import React, { useEffect, useState } from "react"; import clsx from "clsx"; import "./styles.css"; import type { Resource } from "@/libs/store"; import { fetchRegistryData } from "@/libs/store"; import TagFormItem from "./Items/Tag"; import type { Tag as TagType } from "@/types/tag"; export type FormItemData = { type: string; name: string; labelText: string; }; export type FormItemGroup = { name: string; items: FormItemData[]; }; export type Props = { children?: React.ReactNode; type: Resource["resourceType"]; formItems: FormItemGroup[]; handleSubmit: (result: Record) => void; }; export function Form({ type, children, formItems, handleSubmit, }: Props): React.ReactNode { const [currentStep, setCurrentStep] = useState(0); const [result, setResult] = useState>({}); const [allowTags, setAllowTags] = useState([]); // load tags asynchronously useEffect(() => { fetchRegistryData(type) .then((data) => setAllowTags( data .filter((item) => item.tags.length > 0) .map((ele) => ele.tags) .flat() ) ) .catch((e) => { console.error(e); }); }, [type]); const setFormValue = (key: string, value: string) => { setResult({ ...result, [key]: value }); }; const handleNextStep = () => { const currentStepNames = formItems[currentStep].items.map( (item) => item.name ); if (currentStepNames.every((name) => result[name])) { setCurrentStep(currentStep + 1); } else { } }; const onPrev = () => currentStep > 0 && setCurrentStep(currentStep - 1); const onNext = () => currentStep < formItems.length - 1 ? handleNextStep() : handleSubmit(result); return ( <>
    {formItems.map((item, index) => (
  • {item.name}
  • ))}
{children || formItems[currentStep].items.map((item) => ( ))}
); } export function FormItem({ type, name, labelText, allowTags, result, setResult, }: FormItemData & { allowTags: TagType[]; result: Record; setResult: (key: string, value: string) => void; }): React.ReactNode { return ( <> {type === "text" && ( setResult(name, e.target.value)} placeholder="请输入" className={clsx("form-input", { "form-input-error": !result[name], })} /> )} {type === "text" && !result[name] && ( )} {type === "tag" && ( setResult(name, JSON.stringify(tags))} /> )} ); }