[REFACTOR] Split in two distinct forms Settings Object Model page (#10653)
# Introduction This PR contains around ~+300 tests + snapshot additions Please check both object model creation and edition Closes https://github.com/twentyhq/core-team-issues/issues/355 Refactored into two agnostic forms the Object Model settings page for instance `/settings/objects/notes#settings`. ## `SettingsDataModelObjectAboutForm` Added a new abstraction `SettingsUpdateDataModelObjectAboutForm` to wrap `SettingsDataModelObjectAboutForm` in an `update` context  Schema: ```ts const requiredFormFields = objectMetadataItemSchema.pick({ description: true, icon: true, labelPlural: true, labelSingular: true, }); const optionalFormFields = objectMetadataItemSchema .pick({ nameSingular: true, namePlural: true, isLabelSyncedWithName: true, }) .partial(); export const settingsDataModelObjectAboutFormSchema = requiredFormFields.merge(optionalFormFields); ``` ## `SettingsDataModelObjectSettingsFormCard` Update on change  Schema: ```ts export const settingsDataModelObjectIdentifiersFormSchema = objectMetadataItemSchema.pick({ labelIdentifierFieldMetadataId: true, imageIdentifierFieldMetadataId: true, }); ``` ## Error management and validation schema Improved the frontend validation form in order to attest that: - Names are in camelCase - Names are differents - Names are not empty string ***SHOULD BE DONE SERVER SIDE TOO*** ( will in a next PR, atm it literally breaks any workspace ) - Labels are differents - Labels aren't empty strings Hide the error messages as we need to decide what kind of styling we want for our errors with forms ( Example with error labels ) 
This commit is contained in:
@ -1,16 +1,16 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { H2Title, Section } from 'twenty-ui';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { useCreateOneObjectMetadataItem } from '@/object-metadata/hooks/useCreateOneObjectMetadataItem';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SETTINGS_OBJECT_MODEL_IS_LABEL_SYNCED_WITH_NAME_LABEL_DEFAULT_VALUE } from '@/settings/constants/SettingsObjectModel';
|
||||
import { SettingsDataModelObjectAboutForm } from '@/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm';
|
||||
import {
|
||||
SettingsDataModelObjectAboutForm,
|
||||
SettingsDataModelObjectAboutFormValues,
|
||||
settingsDataModelObjectAboutFormSchema,
|
||||
} from '@/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm';
|
||||
import { settingsCreateObjectInputSchema } from '@/settings/data-model/validation-schemas/settingsCreateObjectInputSchema';
|
||||
} from '@/settings/data-model/validation-schemas/settingsDataModelObjectAboutFormSchema';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
@ -19,10 +19,6 @@ import { useLingui } from '@lingui/react/macro';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
|
||||
const newObjectFormSchema = settingsDataModelObjectAboutFormSchema;
|
||||
|
||||
type SettingsDataModelNewObjectFormValues = z.infer<typeof newObjectFormSchema>;
|
||||
|
||||
export const SettingsNewObject = () => {
|
||||
const { t } = useLingui();
|
||||
const navigate = useNavigateSettings();
|
||||
@ -30,21 +26,23 @@ export const SettingsNewObject = () => {
|
||||
|
||||
const { createOneObjectMetadataItem } = useCreateOneObjectMetadataItem();
|
||||
|
||||
const formConfig = useForm<SettingsDataModelNewObjectFormValues>({
|
||||
mode: 'onTouched',
|
||||
resolver: zodResolver(newObjectFormSchema),
|
||||
const formConfig = useForm<SettingsDataModelObjectAboutFormValues>({
|
||||
mode: 'onSubmit',
|
||||
resolver: zodResolver(settingsDataModelObjectAboutFormSchema),
|
||||
defaultValues: {
|
||||
isLabelSyncedWithName:
|
||||
SETTINGS_OBJECT_MODEL_IS_LABEL_SYNCED_WITH_NAME_LABEL_DEFAULT_VALUE,
|
||||
},
|
||||
});
|
||||
|
||||
const { isValid, isSubmitting } = formConfig.formState;
|
||||
const canSave = isValid && !isSubmitting;
|
||||
|
||||
const handleSave = async (
|
||||
formValues: SettingsDataModelNewObjectFormValues,
|
||||
formValues: SettingsDataModelObjectAboutFormValues,
|
||||
) => {
|
||||
try {
|
||||
const { data: response } = await createOneObjectMetadataItem(
|
||||
settingsCreateObjectInputSchema.parse(formValues),
|
||||
);
|
||||
const { data: response } = await createOneObjectMetadataItem(formValues);
|
||||
|
||||
navigate(
|
||||
response ? SettingsPath.ObjectDetail : SettingsPath.Objects,
|
||||
@ -53,6 +51,8 @@ export const SettingsNewObject = () => {
|
||||
: undefined,
|
||||
);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
enqueueSnackBar((error as Error).message, {
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
@ -90,7 +90,9 @@ export const SettingsNewObject = () => {
|
||||
title={t`About`}
|
||||
description={t`Define the name and description of your object`}
|
||||
/>
|
||||
<SettingsDataModelObjectAboutForm />
|
||||
<SettingsDataModelObjectAboutForm
|
||||
onNewDirtyField={() => formConfig.trigger()}
|
||||
/>
|
||||
</Section>
|
||||
</SettingsPageContainer>
|
||||
</SubMenuTopBarContainer>
|
||||
|
||||
Reference in New Issue
Block a user