Skip to content

Commit

Permalink
refactor: improve Settings supported field types validation
Browse files Browse the repository at this point in the history
Related to: #4084, #4295
  • Loading branch information
thaisguigon committed Mar 15, 2024
1 parent 846da39 commit 9d1ecb5
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,20 @@ import { FieldMetadataType } from '~/generated-metadata/graphql';

DEFAULT_DATE_VALUE.setFullYear(DEFAULT_DATE_VALUE.getFullYear() + 2);

export const SETTINGS_FIELD_METADATA_TYPES: Partial<
Record<
FieldMetadataType,
{ label: string; Icon: IconComponent; defaultValue?: unknown }
>
export type SettingsSupportedFieldTypes = Exclude<
FieldMetadataType,
FieldMetadataType.Position
>;

export type SettingsFieldTypeConfig = {
label: string;
Icon: IconComponent;
defaultValue?: unknown;
};

export const SETTINGS_FIELD_TYPE_CONFIGS: Record<
SettingsSupportedFieldTypes,
SettingsFieldTypeConfig
> = {
[FieldMetadataType.Uuid]: {
label: 'Unique ID',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
import { SETTINGS_FIELD_METADATA_TYPES } from '@/settings/data-model/constants/SettingsFieldMetadataTypes';
import omit from 'lodash.omit';

import {
SETTINGS_FIELD_TYPE_CONFIGS,
SettingsFieldTypeConfig,
} from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
import { SettingsSupportedFieldType } from '@/settings/data-model/types/SettingsSupportedFieldType';
import { Select, SelectOption } from '@/ui/input/components/Select';
import { FieldMetadataType } from '~/generated-metadata/graphql';

type SettingsDataModelFieldTypeSelectProps = {
className?: string;
disabled?: boolean;
excludedFieldTypes?: FieldMetadataType[];
onChange?: ({ type }: { type: FieldMetadataType }) => void;
value?: FieldMetadataType;
excludedFieldTypes?: SettingsSupportedFieldType[];
onChange?: ({ type }: { type: SettingsSupportedFieldType }) => void;
value?: SettingsSupportedFieldType;
};

export const SettingsDataModelFieldTypeSelect = ({
className,
disabled,
excludedFieldTypes,
excludedFieldTypes = [],
onChange,
value,
}: SettingsDataModelFieldTypeSelectProps) => {
const fieldTypeOptions = Object.entries(SETTINGS_FIELD_METADATA_TYPES)
.filter(([key]) => !excludedFieldTypes?.includes(key as FieldMetadataType))
.map<SelectOption<FieldMetadataType>>(([key, dataTypeConfig]) => ({
Icon: dataTypeConfig.Icon,
label: dataTypeConfig.label,
value: key as FieldMetadataType,
}));
const fieldTypeConfigs = omit(
SETTINGS_FIELD_TYPE_CONFIGS,
excludedFieldTypes,
);
const fieldTypeOptions = Object.entries<SettingsFieldTypeConfig>(
fieldTypeConfigs,
).map<SelectOption<SettingsSupportedFieldType>>(([key, dataTypeConfig]) => ({
Icon: dataTypeConfig.Icon,
label: dataTypeConfig.label,
value: key as SettingsSupportedFieldType,
}));

return (
<Select
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { v4 } from 'uuid';
import { z } from 'zod';

import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
import { SettingsSupportedFieldType } from '@/settings/data-model/types/SettingsSupportedFieldType';
import { themeColorSchema } from '@/ui/theme/utils/themeColorSchema';
import {
FieldMetadataType,
Expand All @@ -17,7 +18,7 @@ type FormValues = {
description?: string;
icon: string;
label: string;
type: FieldMetadataType;
type: SettingsSupportedFieldType;
} & SettingsDataModelFieldSettingsFormValues;

export const fieldMetadataFormDefaultValues: FormValues = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';

import { SETTINGS_FIELD_METADATA_TYPES } from '@/settings/data-model/constants/SettingsFieldMetadataTypes';
import { SettingsSupportedFieldType } from '@/settings/data-model/types/SettingsSupportedFieldType';
import { getSettingsFieldTypeConfig } from '@/settings/data-model/utils/getSettingsFieldTypeConfig';
import { IconTwentyStar } from '@/ui/display/icon/components/IconTwentyStar';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { FieldMetadataType } from '~/generated-metadata/graphql';
Expand All @@ -10,10 +11,10 @@ type SettingsObjectFieldDataTypeProps = {
onClick?: () => void;
Icon?: IconComponent;
label?: string;
value: FieldMetadataType;
value: SettingsSupportedFieldType;
};

const StyledDataType = styled.div<{ value: FieldMetadataType }>`
const StyledDataType = styled.div<{ value: SettingsSupportedFieldType }>`
align-items: center;
border: 1px solid transparent;
border-radius: ${({ theme }) => theme.border.radius.sm};
Expand Down Expand Up @@ -49,11 +50,16 @@ const StyledLabelContainer = styled.div`
export const SettingsObjectFieldDataType = ({
onClick,
value,
Icon = SETTINGS_FIELD_METADATA_TYPES[value]?.Icon ?? IconTwentyStar,
label = SETTINGS_FIELD_METADATA_TYPES[value]?.label,
Icon: IconFromProps,
label: labelFromProps,
}: SettingsObjectFieldDataTypeProps) => {
const theme = useTheme();

const fieldTypeConfig = getSettingsFieldTypeConfig(value);
const Icon: IconComponent =
IconFromProps ?? fieldTypeConfig?.Icon ?? IconTwentyStar;
const label = labelFromProps ?? fieldTypeConfig?.label;

const StyledIcon = styled(Icon)`
flex: 1 0 auto;
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import styled from '@emotion/styled';
import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMetadata';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
import { SETTINGS_FIELD_METADATA_TYPES } from '@/settings/data-model/constants/SettingsFieldMetadataTypes';
import { FieldIdentifierType } from '@/settings/data-model/types/FieldIdentifierType';
import { isFieldTypeSupportedInSettings } from '@/settings/data-model/utils/isFieldTypeSupportedInSettings';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
Expand Down Expand Up @@ -49,10 +49,6 @@ export const SettingsObjectFieldItemTableRow = ({
const Icon = getIcon(fieldMetadataItem.icon);
const navigate = useNavigate();

// TODO: parse with zod and merge types with FieldType (create a subset of FieldType for example)
const fieldDataTypeIsSupported =
fieldMetadataItem.type in SETTINGS_FIELD_METADATA_TYPES;

const getRelationMetadata = useGetRelationMetadata();

const { relationObjectMetadataItem, relationType } =
Expand All @@ -61,7 +57,10 @@ export const SettingsObjectFieldItemTableRow = ({
[fieldMetadataItem, getRelationMetadata],
) ?? {};

if (!fieldDataTypeIsSupported) return null;
const fieldType = fieldMetadataItem.type;
const isFieldTypeSupported = isFieldTypeSupportedInSettings(fieldType);

if (!isFieldTypeSupported) return null;

const RelationIcon = relationType
? RELATION_TYPES[relationType].Icon
Expand Down Expand Up @@ -97,7 +96,7 @@ export const SettingsObjectFieldItemTableRow = ({
)
: undefined
}
value={fieldMetadataItem.type}
value={fieldType}
/>
</TableCell>
<StyledIconTableCell>{ActionIcon}</StyledIconTableCell>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { FieldMetadataType } from '~/generated-metadata/graphql';

export type SettingsSupportedFieldType = Exclude<
FieldMetadataType,
FieldMetadataType.Position
>;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
import { SettingsObjectFieldSelectFormValues } from '@/settings/data-model/components/SettingsObjectFieldSelectForm';
import { SETTINGS_FIELD_METADATA_TYPES } from '@/settings/data-model/constants/SettingsFieldMetadataTypes';
import { getSettingsFieldTypeConfig } from '@/settings/data-model/utils/getSettingsFieldTypeConfig';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { isDefined } from '~/utils/isDefined';

Expand Down Expand Up @@ -39,12 +39,16 @@ export const getFieldDefaultPreviewValue = ({

if (!relationLabelIdentifierFieldMetadataItem) return null;

const { type: relationLabelIdentifierFieldType } =
relationLabelIdentifierFieldMetadataItem;
const relationFieldTypeConfig = getSettingsFieldTypeConfig(
relationLabelIdentifierFieldType,
);

const defaultRelationLabelIdentifierFieldValue =
relationLabelIdentifierFieldMetadataItem.type === FieldMetadataType.Text
relationLabelIdentifierFieldType === FieldMetadataType.Text
? relationObjectMetadataItem.labelSingular
: SETTINGS_FIELD_METADATA_TYPES[
relationLabelIdentifierFieldMetadataItem.type
]?.defaultValue;
: relationFieldTypeConfig?.defaultValue;

const defaultRelationRecord = {
[relationLabelIdentifierFieldMetadataItem.name]:
Expand All @@ -54,6 +58,7 @@ export const getFieldDefaultPreviewValue = ({
return defaultRelationRecord;
}

// Other fields
const isLabelIdentifier =
!!fieldMetadataItem.id &&
!!fieldMetadataItem.name &&
Expand All @@ -65,8 +70,9 @@ export const getFieldDefaultPreviewValue = ({
objectMetadataItem,
});

// Other fields
const fieldTypeConfig = getSettingsFieldTypeConfig(fieldMetadataItem.type);

return isLabelIdentifier && fieldMetadataItem.type === FieldMetadataType.Text
? objectMetadataItem.labelSingular
: SETTINGS_FIELD_METADATA_TYPES[fieldMetadataItem.type]?.defaultValue;
: fieldTypeConfig?.defaultValue;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SETTINGS_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
import { isFieldTypeSupportedInSettings } from '@/settings/data-model/utils/isFieldTypeSupportedInSettings';
import { FieldMetadataType } from '~/generated-metadata/graphql';

export const getSettingsFieldTypeConfig = (fieldType: FieldMetadataType) =>
isFieldTypeSupportedInSettings(fieldType)
? SETTINGS_FIELD_TYPE_CONFIGS[fieldType]
: undefined;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {
SETTINGS_FIELD_TYPE_CONFIGS,
SettingsSupportedFieldTypes,
} from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
import { FieldMetadataType } from '~/generated-metadata/graphql';

export const isFieldTypeSupportedInSettings = (
fieldType: FieldMetadataType,
): fieldType is SettingsSupportedFieldTypes =>
fieldType in SETTINGS_FIELD_TYPE_CONFIGS;
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { SettingsObjectFieldFormSection } from '@/settings/data-model/components
import { SettingsDataModelFieldSettingsFormCard } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard';
import { SettingsDataModelFieldTypeSelect } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldTypeSelect';
import { useFieldMetadataForm } from '@/settings/data-model/fields/forms/hooks/useFieldMetadataForm';
import { isFieldTypeSupportedInSettings } from '@/settings/data-model/utils/isFieldTypeSupportedInSettings';
import { AppPath } from '@/types/AppPath';
import { IconArchive, IconSettings } from '@/ui/display/icon';
import { H2Title } from '@/ui/display/typography/components/H2Title';
Expand Down Expand Up @@ -112,11 +113,16 @@ export const SettingsObjectFieldEdit = () => {
(optionA, optionB) => optionA.position - optionB.position,
);

const fieldType = activeMetadataField.type;
const isFieldTypeSupported = isFieldTypeSupportedInSettings(fieldType);

if (!isFieldTypeSupported) return;

initForm({
icon: activeMetadataField.icon ?? undefined,
label: activeMetadataField.label,
description: activeMetadataField.description ?? undefined,
type: activeMetadataField.type,
type: fieldType,
...(currencyDefaultValue ? { currency: currencyDefaultValue } : {}),
relation: {
field: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { SettingsObjectFieldFormSection } from '@/settings/data-model/components
import { SettingsDataModelFieldSettingsFormCard } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard';
import { SettingsDataModelFieldTypeSelect } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldTypeSelect';
import { useFieldMetadataForm } from '@/settings/data-model/fields/forms/hooks/useFieldMetadataForm';
import { SettingsSupportedFieldType } from '@/settings/data-model/types/SettingsSupportedFieldType';
import { AppPath } from '@/types/AppPath';
import { IconSettings } from '@/ui/display/icon';
import { H2Title } from '@/ui/display/typography/components/H2Title';
Expand Down Expand Up @@ -259,7 +260,7 @@ export const SettingsObjectNewFieldStep2 = () => {
}
};

const excludedFieldTypes = [
const excludedFieldTypes: SettingsSupportedFieldType[] = [
FieldMetadataType.Currency,
FieldMetadataType.Email,
FieldMetadataType.FullName,
Expand Down

0 comments on commit 9d1ecb5

Please sign in to comment.