fix(ui): antd nested form bugs

This commit is contained in:
Fu Diwei
2025-01-06 19:10:29 +08:00
parent 4ba7237326
commit 87e1749553
60 changed files with 1694 additions and 1358 deletions

View File

@@ -64,16 +64,23 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
initialValues: initialValues,
});
const configProvider = Form.useWatch("provider", formInst);
const [configFormInst] = Form.useForm();
const configFormName = useAntdFormName({ form: configFormInst, name: "accessEditConfigForm" });
const configFormEl = useMemo(() => {
const fieldProvider = Form.useWatch("provider", formInst);
const [nestedFormInst] = Form.useForm();
const nestedFormName = useAntdFormName({ form: nestedFormInst, name: "accessEditFormConfigForm" });
const nestedFormEl = useMemo(() => {
const configFormProps = {
form: nestedFormInst,
formName: nestedFormName,
disabled: disabled,
initialValues: initialValues?.config,
};
/*
注意:如果追加新的子组件,请保持以 ASCII 排序。
NOTICE: If you add new child component, please keep ASCII order.
*/
const configFormProps = { form: configFormInst, formName: configFormName, disabled: disabled, initialValues: initialValues?.config };
switch (configProvider) {
switch (fieldProvider) {
case ACCESS_PROVIDERS.ACMEHTTPREQ:
return <AccessEditFormACMEHttpReqConfig {...configFormProps} />;
case ACCESS_PROVIDERS.ALIYUN:
@@ -113,17 +120,17 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
case ACCESS_PROVIDERS.WEBHOOK:
return <AccessEditFormWebhookConfig {...configFormProps} />;
}
}, [disabled, initialValues, configProvider, configFormInst, configFormName]);
}, [disabled, initialValues, fieldProvider, nestedFormInst, nestedFormName]);
const handleFormProviderChange = (name: string) => {
if (name === configFormName) {
formInst.setFieldValue("config", configFormInst.getFieldsValue());
if (name === nestedFormName) {
formInst.setFieldValue("config", nestedFormInst.getFieldsValue());
onValuesChange?.(formInst.getFieldsValue(true));
}
};
const handleFormChange = (_: unknown, values: AccessEditFormFieldValues) => {
if (values.provider !== configProvider) {
if (values.provider !== fieldProvider) {
formInst.setFieldValue("provider", values.provider);
}
@@ -140,7 +147,7 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
},
validateFields: (nameList, config) => {
const t1 = formInst.validateFields(nameList, config);
const t2 = configFormInst.validateFields(undefined, config);
const t2 = nestedFormInst.validateFields(undefined, config);
return Promise.all([t1, t2]).then(() => t1);
},
} as AccessEditFormInstance;
@@ -164,7 +171,7 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
</Form.Item>
</Form>
{configFormEl}
{nestedFormEl}
</div>
</Form.Provider>
);

View File

@@ -18,10 +18,10 @@ export type AccessEditModalProps = {
preset: AccessEditFormProps["preset"];
trigger?: React.ReactNode;
onOpenChange?: (open: boolean) => void;
onSubmit?: (record: AccessModel) => void;
afterSubmit?: (record: AccessModel) => void;
};
const AccessEditModal = ({ data, loading, trigger, preset, onSubmit, ...props }: AccessEditModalProps) => {
const AccessEditModal = ({ data, loading, trigger, preset, afterSubmit, ...props }: AccessEditModalProps) => {
const { t } = useTranslation();
const [notificationApi, NotificationContextHolder] = notification.useNotification();
@@ -39,45 +39,48 @@ const AccessEditModal = ({ data, loading, trigger, preset, onSubmit, ...props }:
const formRef = useRef<AccessEditFormInstance>(null);
const [formPending, setFormPending] = useState(false);
const handleClickOk = async () => {
const handleOkClick = async () => {
setFormPending(true);
try {
await formRef.current!.validateFields();
} catch (err) {
setFormPending(false);
return Promise.reject(err);
throw err;
}
try {
let temp: AccessModel = formRef.current!.getFieldsValue();
temp.usage = accessProvidersMap.get(temp.provider)!.usage;
let values: AccessModel = formRef.current!.getFieldsValue();
values.usage = accessProvidersMap.get(values.provider)!.usage;
if (preset === "add") {
if (data?.id) {
throw "Invalid props: `data`";
}
temp = await createAccess(temp);
values = await createAccess(values);
} else if (preset === "edit") {
if (!data?.id) {
throw "Invalid props: `data`";
}
temp = await updateAccess({ ...data, ...temp });
values = await updateAccess({ ...data, ...values });
} else {
throw "Invalid props: `preset`";
}
onSubmit?.(temp);
afterSubmit?.(values);
setOpen(false);
} catch (err) {
notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
throw err;
} finally {
setFormPending(false);
}
};
const handleClickCancel = () => {
if (formPending) return Promise.reject();
const handleCancelClick = () => {
if (formPending) return;
setOpen(false);
};
@@ -99,8 +102,8 @@ const AccessEditModal = ({ data, loading, trigger, preset, onSubmit, ...props }:
open={open}
title={t(`access.action.${preset}`)}
width={480}
onOk={handleClickOk}
onCancel={handleClickCancel}
onOk={handleOkClick}
onCancel={handleCancelClick}
>
<div className="pb-2 pt-4">
<AccessEditForm ref={formRef} initialValues={data} preset={preset === "add" ? "add" : "edit"} />

View File

@@ -17,7 +17,7 @@ const AccessSelect = ({ filter, ...props }: AccessTypeSelectProps) => {
const { accesses, loadedAtOnce, fetchAccesses } = useAccessesStore(useZustandShallowSelector(["accesses", "loadedAtOnce", "fetchAccesses"]));
useEffect(() => {
fetchAccesses();
}, [fetchAccesses]);
}, []);
const [options, setOptions] = useState<Array<{ key: string; value: string; label: string; data: AccessModel }>>([]);
useEffect(() => {