feat: add Select field preview and form (#2655)

Closes #2432
This commit is contained in:
Thaïs
2023-11-28 23:44:21 +01:00
committed by GitHub
parent 0fa55b0634
commit bc787f72ba
18 changed files with 317 additions and 87 deletions

View File

@ -2,6 +2,7 @@ import { useState } from 'react';
import { DeepPartial } from 'react-hook-form';
import { z } from 'zod';
import { mainColors, ThemeColor } from '@/ui/theme/constants/colors';
import {
FieldMetadataType,
RelationMetadataType,
@ -16,6 +17,7 @@ type FormValues = {
label: string;
type: FieldMetadataType;
relation: SettingsObjectFieldTypeSelectSectionFormValues['relation'];
select: SettingsObjectFieldTypeSelectSectionFormValues['select'];
};
const defaultValues: FormValues = {
@ -25,6 +27,7 @@ const defaultValues: FormValues = {
relation: {
type: RelationMetadataType.OneToMany,
},
select: [{ color: 'green', text: 'Option 1' }],
};
const fieldSchema = z.object({
@ -48,7 +51,27 @@ const relationSchema = fieldSchema.merge(
}),
);
const { Relation: _, ...otherFieldTypes } = FieldMetadataType;
const selectSchema = fieldSchema.merge(
z.object({
type: z.literal(FieldMetadataType.Enum),
select: z
.array(
z.object({
color: z.enum(
Object.keys(mainColors) as [ThemeColor, ...ThemeColor[]],
),
text: z.string().min(1),
}),
)
.nonempty(),
}),
);
const {
Enum: _Enum,
Relation: _Relation,
...otherFieldTypes
} = FieldMetadataType;
const otherFieldTypesSchema = fieldSchema.merge(
z.object({
@ -63,9 +86,13 @@ const otherFieldTypesSchema = fieldSchema.merge(
const schema = z.discriminatedUnion('type', [
relationSchema,
selectSchema,
otherFieldTypesSchema,
]);
type PartialFormValues = Partial<FormValues> &
DeepPartial<Pick<FormValues, 'relation'>>;
export const useFieldMetadataForm = () => {
const [isInitialized, setIsInitialized] = useState(false);
const [initialFormValues, setInitialFormValues] =
@ -73,14 +100,15 @@ export const useFieldMetadataForm = () => {
const [formValues, setFormValues] = useState<FormValues>(defaultValues);
const [hasFieldFormChanged, setHasFieldFormChanged] = useState(false);
const [hasRelationFormChanged, setHasRelationFormChanged] = useState(false);
const [hasSelectFormChanged, setHasSelectFormChanged] = useState(false);
const [validationResult, setValidationResult] = useState(
schema.safeParse(formValues),
);
const mergePartialValues = (
previousValues: FormValues,
nextValues: DeepPartial<FormValues>,
) => ({
nextValues: PartialFormValues,
): FormValues => ({
...previousValues,
...nextValues,
relation: {
@ -93,7 +121,7 @@ export const useFieldMetadataForm = () => {
},
});
const initForm = (lazyInitialFormValues: DeepPartial<FormValues>) => {
const initForm = (lazyInitialFormValues: PartialFormValues) => {
if (isInitialized) return;
const mergedFormValues = mergePartialValues(
@ -107,16 +135,22 @@ export const useFieldMetadataForm = () => {
setIsInitialized(true);
};
const handleFormChange = (values: DeepPartial<FormValues>) => {
const handleFormChange = (values: PartialFormValues) => {
const nextFormValues = mergePartialValues(formValues, values);
setFormValues(nextFormValues);
setValidationResult(schema.safeParse(nextFormValues));
const { relation: initialRelationFormValues, ...initialFieldFormValues } =
initialFormValues;
const { relation: nextRelationFormValues, ...nextFieldFormValues } =
nextFormValues;
const {
relation: initialRelationFormValues,
select: initialSelectFormValues,
...initialFieldFormValues
} = initialFormValues;
const {
relation: nextRelationFormValues,
select: nextSelectFormValues,
...nextFieldFormValues
} = nextFormValues;
setHasFieldFormChanged(
!isDeeplyEqual(initialFieldFormValues, nextFieldFormValues),
@ -125,13 +159,18 @@ export const useFieldMetadataForm = () => {
nextFieldFormValues.type === FieldMetadataType.Relation &&
!isDeeplyEqual(initialRelationFormValues, nextRelationFormValues),
);
setHasSelectFormChanged(
nextFieldFormValues.type === FieldMetadataType.Enum &&
!isDeeplyEqual(initialSelectFormValues, nextSelectFormValues),
);
};
return {
formValues,
handleFormChange,
hasFieldFormChanged,
hasFormChanged: hasFieldFormChanged || hasRelationFormChanged,
hasFormChanged:
hasFieldFormChanged || hasRelationFormChanged || hasSelectFormChanged,
hasRelationFormChanged,
initForm,
isInitialized,