fix(SchemaForm): Make SchemaForm correctly support ui:widget of PluginForm and have the correct default values.

This commit is contained in:
haitaoo
2023-03-15 10:54:36 +08:00
parent 89ed70f5a8
commit bfc0bb5ac2
2 changed files with 44 additions and 17 deletions
+38 -9
View File
@@ -148,6 +148,35 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
}
const keys = Object.keys(properties);
/**
* Prevent components such as `select` from having default values,
* which are not generated on `formData`
*/
const setDefaultValueAsDomBehaviour = () => {
keys.forEach((k) => {
const formVal = formData[k]?.value;
const metaProp = properties[k];
const uiCtrl = uiSchema[k]?.['ui:widget'];
if (
!metaProp ||
!uiCtrl ||
formVal ||
formVal === 0 ||
formVal === false
) {
return;
}
if (uiCtrl === 'select' && metaProp.enum?.[0] !== undefined) {
formData[k] = {
errorMsg: '',
isInvalid: false,
value: metaProp.enum?.[0],
};
console.log('formData[k]: ', k, formData[k]);
}
});
};
setDefaultValueAsDomBehaviour();
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
@@ -297,16 +326,17 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
}
};
const handleCheckboxChange = (
const handleInputCheck = (
e: React.ChangeEvent<HTMLInputElement>,
index: number,
) => {
const { name } = e.target;
const { name, checked } = e.currentTarget;
const freshVal = checked ? schema.properties[name]?.enum?.[index] : '';
const data = {
...formData,
[name]: {
...formData[name],
value: schema.properties[name]?.enum?.[index],
value: freshVal,
isInvalid: false,
},
};
@@ -324,6 +354,7 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
{keys.map((key) => {
const { title, description, label } = properties[key];
const { 'ui:widget': widget = 'input' } = uiSchema[key] || {};
if (widget === 'select') {
return (
<Form.Group
@@ -354,6 +385,7 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
</Form.Group>
);
}
if (widget === 'checkbox' || widget === 'radio') {
return (
<Form.Group
@@ -376,7 +408,7 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
feedback={formData[key]?.errorMsg}
feedbackType="invalid"
isInvalid={formData[key].isInvalid}
onChange={(e) => handleCheckboxChange(e, index)}
onChange={(e) => handleInputCheck(e, index)}
/>
);
})}
@@ -544,11 +576,8 @@ export const initFormData = (schema: JSONSchema): Type.FormDataType => {
const formData: Type.FormDataType = {};
Object.keys(schema.properties).forEach((key) => {
const prop = schema.properties[key];
let defaultVal = prop?.default;
if (typeof defaultVal === 'undefined' && Array.isArray(prop?.enum)) {
// eslint-disable-next-line prefer-destructuring
defaultVal = prop.enum[0];
}
const defaultVal = prop?.default;
formData[key] = {
value: defaultVal,
isInvalid: false,
+6 -8
View File
@@ -16,8 +16,7 @@ const Config = () => {
const { data } = useQueryPluginConfig({ plugin_slug_name: slug_name });
const Toast = useToast();
const [schema, setSchema] = useState<JSONSchema | null>(null);
const uiSchema: UISchema = {};
const [uiSchema, setUISchema] = useState<UISchema>();
const required: string[] = [];
const [formData, setFormData] = useState<Types.FormDataType | null>(null);
@@ -27,7 +26,7 @@ const Config = () => {
return;
}
const properties: JSONSchema['properties'] = {};
const uiConf: UISchema = {};
data.config_fields?.forEach((item) => {
properties[item.name] = {
type: 'string',
@@ -42,28 +41,27 @@ const Config = () => {
(option) => option.label,
);
}
uiConf[item.name] = {};
uiConf[item.name]['ui:widget'] = item.type;
if (item.ui_options) {
if ((item.ui_options as InputOptions & { input_type })?.input_type) {
(item.ui_options as InputOptions).inputType = (
item.ui_options as InputOptions & { input_type }
).input_type;
}
uiSchema[item.name] = {
'ui:options': item.ui_options,
};
uiConf[item.name]['ui:options'] = item.ui_options;
}
if (item.required) {
required.push(item.name);
}
});
const result = {
title: data?.name || '',
required,
properties,
};
setSchema(result);
setUISchema(uiConf);
setFormData(initFormData(result));
}, [data?.config_fields]);