Skip to content

Commit

Permalink
changes to show name taken on label
Browse files Browse the repository at this point in the history
  • Loading branch information
deval2498 committed Jul 7, 2024
1 parent aa22189 commit 7677b01
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,97 +10,99 @@ import {
} from '~/generated-metadata/graphql';
import { camelCaseStringSchema } from '~/utils/validation-schemas/camelCaseStringSchema';

export const fieldMetadataItemSchema = z.object({
__typename: z.literal('field').optional(),
createdAt: z.string().datetime(),
defaultValue: z.any().optional(),
description: z.string().trim().nullable().optional(),
fromRelationMetadata: z
.object({
__typename: z.literal('relation').optional(),
id: z.string().uuid(),
relationType: z.nativeEnum(RelationMetadataType),
toFieldMetadataId: z.string().uuid(),
toObjectMetadata: z.object({
__typename: z.literal('object').optional(),
dataSourceId: z.string().uuid(),
export const fieldMetadataItemSchema = (existingLabels?: string[]) => {
return z.object({
__typename: z.literal('field').optional(),
createdAt: z.string().datetime(),
defaultValue: z.any().optional(),
description: z.string().trim().nullable().optional(),
fromRelationMetadata: z
.object({
__typename: z.literal('relation').optional(),
id: z.string().uuid(),
isRemote: z.boolean(),
isSystem: z.boolean(),
namePlural: z.string().trim().min(1),
nameSingular: z.string().trim().min(1),
}),
})
.nullable()
.optional(),
icon: z.string().startsWith('Icon').trim().nullable(),
id: z.string().uuid(),
isActive: z.boolean(),
isCustom: z.boolean(),
isNullable: z.boolean(),
isSystem: z.boolean(),
label: metadataLabelSchema,
name: camelCaseStringSchema,
options: z
.array(
z.object({
color: themeColorSchema,
relationType: z.nativeEnum(RelationMetadataType),
toFieldMetadataId: z.string().uuid(),
toObjectMetadata: z.object({
__typename: z.literal('object').optional(),
dataSourceId: z.string().uuid(),
id: z.string().uuid(),
isRemote: z.boolean(),
isSystem: z.boolean(),
namePlural: z.string().trim().min(1),
nameSingular: z.string().trim().min(1),
}),
})
.nullable()
.optional(),
icon: z.string().startsWith('Icon').trim().nullable(),
id: z.string().uuid(),
isActive: z.boolean(),
isCustom: z.boolean(),
isNullable: z.boolean(),
isSystem: z.boolean(),
label: metadataLabelSchema(existingLabels),
name: camelCaseStringSchema,
options: z
.array(
z.object({
color: themeColorSchema,
id: z.string().uuid(),
label: z.string().trim().min(1),
position: z.number(),
value: z.string().trim().min(1),
}),
)
.nullable()
.optional(),
relationDefinition: z
.object({
__typename: z.literal('RelationDefinition').optional(),
relationId: z.string().uuid(),
direction: z.nativeEnum(RelationDefinitionType),
sourceFieldMetadata: z.object({
__typename: z.literal('field').optional(),
id: z.string().uuid(),
name: z.string().trim().min(1),
}),
sourceObjectMetadata: z.object({
__typename: z.literal('object').optional(),
id: z.string().uuid(),
namePlural: z.string().trim().min(1),
nameSingular: z.string().trim().min(1),
}),
targetFieldMetadata: z.object({
__typename: z.literal('field').optional(),
id: z.string().uuid(),
name: z.string().trim().min(1),
}),
targetObjectMetadata: z.object({
__typename: z.literal('object').optional(),
id: z.string().uuid(),
namePlural: z.string().trim().min(1),
nameSingular: z.string().trim().min(1),
}),
})
.nullable()
.optional(),
toRelationMetadata: z
.object({
__typename: z.literal('relation').optional(),
id: z.string().uuid(),
label: z.string().trim().min(1),
position: z.number(),
value: z.string().trim().min(1),
}),
)
.nullable()
.optional(),
relationDefinition: z
.object({
__typename: z.literal('RelationDefinition').optional(),
relationId: z.string().uuid(),
direction: z.nativeEnum(RelationDefinitionType),
sourceFieldMetadata: z.object({
__typename: z.literal('field').optional(),
id: z.string().uuid(),
name: z.string().trim().min(1),
}),
sourceObjectMetadata: z.object({
__typename: z.literal('object').optional(),
id: z.string().uuid(),
namePlural: z.string().trim().min(1),
nameSingular: z.string().trim().min(1),
}),
targetFieldMetadata: z.object({
__typename: z.literal('field').optional(),
id: z.string().uuid(),
name: z.string().trim().min(1),
}),
targetObjectMetadata: z.object({
__typename: z.literal('object').optional(),
id: z.string().uuid(),
namePlural: z.string().trim().min(1),
nameSingular: z.string().trim().min(1),
}),
})
.nullable()
.optional(),
toRelationMetadata: z
.object({
__typename: z.literal('relation').optional(),
id: z.string().uuid(),
relationType: z.nativeEnum(RelationMetadataType),
fromFieldMetadataId: z.string().uuid(),
fromObjectMetadata: z.object({
__typename: z.literal('object').optional(),
id: z.string().uuid(),
dataSourceId: z.string().uuid(),
isRemote: z.boolean(),
isSystem: z.boolean(),
namePlural: z.string().trim().min(1),
nameSingular: z.string().trim().min(1),
}),
})
.nullable()
.optional(),
type: z.nativeEnum(FieldMetadataType),
updatedAt: z.string().datetime(),
}) satisfies z.ZodType<FieldMetadataItem>;
relationType: z.nativeEnum(RelationMetadataType),
fromFieldMetadataId: z.string().uuid(),
fromObjectMetadata: z.object({
__typename: z.literal('object').optional(),
id: z.string().uuid(),
dataSourceId: z.string().uuid(),
isRemote: z.boolean(),
isSystem: z.boolean(),
namePlural: z.string().trim().min(1),
nameSingular: z.string().trim().min(1),
}),
})
.nullable()
.optional(),
type: z.nativeEnum(FieldMetadataType),
updatedAt: z.string().datetime(),
}) satisfies z.ZodType<FieldMetadataItem>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,34 @@ import { z } from 'zod';

import { METADATA_LABEL_VALID_PATTERN } from '~/pages/settings/data-model/constants/MetadataLabelValidPattern';
import { computeMetadataNameFromLabelOrThrow } from '~/pages/settings/data-model/utils/compute-metadata-name-from-label.utils';

export const metadataLabelSchema = z
.string()
.trim()
.min(1)
.regex(METADATA_LABEL_VALID_PATTERN)
.refine(
(label) => {
try {
computeMetadataNameFromLabelOrThrow(label);
return true;
} catch (error) {
return false;
export const metadataLabelSchema = (existingLabels?: string[]) => {
return z
.string()
.trim()
.min(1, "Label cannot be empty")
.regex(METADATA_LABEL_VALID_PATTERN)
.refine(
(label) => {
try {
computeMetadataNameFromLabelOrThrow(label);
return true;
} catch (error) {
return false;
}
},
{
message: 'Label is not formattable',
},
)
.refine((label) => {
try{if(!existingLabels) {
return true
}
return !existingLabels.includes(label);}
catch(error) {
return false
}
},
{
message: 'Label is not formattable',
},
); // allows non-latin char
}, {
message: "Label must be unique",
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const objectMetadataItemSchema = z.object({
createdAt: z.string().datetime(),
dataSourceId: z.string().uuid(),
description: z.string().trim().nullable().optional(),
fields: z.array(fieldMetadataItemSchema),
fields: z.array(fieldMetadataItemSchema()),
icon: z.string().startsWith('Icon').trim(),
id: z.string().uuid(),
imageIdentifierFieldMetadataId: z.string().uuid().nullable(),
Expand All @@ -19,8 +19,8 @@ export const objectMetadataItemSchema = z.object({
isRemote: z.boolean(),
isSystem: z.boolean(),
labelIdentifierFieldMetadataId: z.string().uuid().nullable(),
labelPlural: metadataLabelSchema,
labelSingular: metadataLabelSchema,
labelPlural: metadataLabelSchema(),
labelSingular: metadataLabelSchema(),
namePlural: camelCaseStringSchema,
nameSingular: camelCaseStringSchema,
updatedAt: z.string().datetime(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ import { IconPicker } from '@/ui/input/components/IconPicker';
import { TextArea } from '@/ui/input/components/TextArea';
import { TextInput } from '@/ui/input/components/TextInput';

export const settingsDataModelFieldAboutFormSchema =
fieldMetadataItemSchema.pick({
export const settingsDataModelFieldAboutFormSchema = (existingLabels?: string[]) => {
return fieldMetadataItemSchema(existingLabels || []).pick({
description: true,
icon: true,
label: true,
});
};

// Correctly infer the type from the returned schema
type SettingsDataModelFieldAboutFormValues = z.infer<
typeof settingsDataModelFieldAboutFormSchema
ReturnType<typeof settingsDataModelFieldAboutFormSchema>
>;

type SettingsDataModelFieldAboutFormProps = {
Expand All @@ -37,8 +39,11 @@ export const SettingsDataModelFieldAboutForm = ({
fieldMetadataItem,
maxLength,
}: SettingsDataModelFieldAboutFormProps) => {
const { control } = useFormContext<SettingsDataModelFieldAboutFormValues>();

const { control, trigger, formState: {errors} } = useFormContext<SettingsDataModelFieldAboutFormValues>();
const validateLabel = () => {
trigger('label')
}
console.log(errors.label, "errors near label")
return (
<>
<StyledInputsContainer>
Expand All @@ -63,7 +68,11 @@ export const SettingsDataModelFieldAboutForm = ({
<TextInput
placeholder="Employees"
value={value}
onChange={onChange}
onChange={(e) => {
onChange(e)
validateLabel()
}}
error={errors.label?.message=='Label must be unique' ? "This name is already taken": undefined}
disabled={disabled}
maxLength={maxLength}
fullWidth
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { TextInput } from '@/ui/input/components/TextInput';

export const settingsDataModelFieldRelationFormSchema = z.object({
relation: z.object({
field: fieldMetadataItemSchema.pick({
field: fieldMetadataItemSchema().pick({
icon: true,
label: true,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import { settingsDataModelFieldAboutFormSchema } from '@/settings/data-model/fie
import { settingsDataModelFieldSettingsFormSchema } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard';
import { settingsDataModelFieldTypeFormSchema } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldTypeSelect';

export const settingsFieldFormSchema = z
export const settingsFieldFormSchema = (existingLabels? : string[]) => {
return z
.object({})
.merge(settingsDataModelFieldAboutFormSchema)
.merge(settingsDataModelFieldAboutFormSchema(existingLabels))
.merge(settingsDataModelFieldTypeFormSchema)
.and(settingsDataModelFieldSettingsFormSchema);
.and(settingsDataModelFieldSettingsFormSchema)
}

Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ import { FieldMetadataType } from '~/generated-metadata/graphql';
import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';

type SettingsDataModelNewFieldFormValues = z.infer<
typeof settingsFieldFormSchema
>;
type SettingsDataModelNewFieldFormValues = z.infer<ReturnType<typeof settingsFieldFormSchema>>;

const StyledSettingsObjectFieldTypeSelect = styled(
SettingsDataModelFieldTypeSelect,
Expand All @@ -59,9 +57,9 @@ export const SettingsObjectNewFieldStep2 = () => {

const formConfig = useForm<SettingsDataModelNewFieldFormValues>({
mode: 'onTouched',
resolver: zodResolver(settingsFieldFormSchema),
resolver: zodResolver(settingsFieldFormSchema(activeObjectMetadataItem?.fields.map((value) => value.name))),
});

useEffect(() => {
if (!activeObjectMetadataItem) {
navigate(AppPath.NotFound);
Expand Down Expand Up @@ -111,7 +109,6 @@ export const SettingsObjectNewFieldStep2 = () => {

const canSave =
formConfig.formState.isValid && !formConfig.formState.isSubmitting;

const handleSave = async (
formValues: SettingsDataModelNewFieldFormValues,
) => {
Expand All @@ -121,7 +118,7 @@ export const SettingsObjectNewFieldStep2 = () => {
'relation' in formValues
) {
const { relation: relationFormValues, ...fieldFormValues } = formValues;

await createOneRelationMetadata({
relationType: relationFormValues.type,
field: pick(fieldFormValues, ['icon', 'label', 'description']),
Expand All @@ -145,7 +142,6 @@ export const SettingsObjectNewFieldStep2 = () => {
...formValues,
objectMetadataId: activeObjectMetadataItem.id,
});

// TODO: fix optimistic update logic
// Forcing a refetch for now but it's not ideal
await apolloClient.refetchQueries({
Expand Down

0 comments on commit 7677b01

Please sign in to comment.