Refactor default value for select (#5343)
In this PR, we are refactoring two things: - leverage field.defaultValue for Select and MultiSelect settings form (instead of option.isDefault) - use quoted string (ex: "'USD'") for string default values to embrace backend format --------- Co-authored-by: Thaïs Guigon <guigon.thais@gmail.com>
This commit is contained in:
@ -1,5 +1,4 @@
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SettingsDataModelFieldSelectFormValues } from '@/settings/data-model/components/SettingsObjectFieldSelectForm';
|
||||
import {
|
||||
mockedCompanyObjectMetadataItem,
|
||||
mockedOpportunityObjectMetadataItem,
|
||||
@ -10,35 +9,21 @@ import { getFieldDefaultPreviewValue } from '../getFieldDefaultPreviewValue';
|
||||
|
||||
describe('getFieldDefaultPreviewValue', () => {
|
||||
describe('SELECT field', () => {
|
||||
it('returns the default select option', () => {
|
||||
it('returns the default select option value', () => {
|
||||
// Given
|
||||
const objectMetadataItem = mockedOpportunityObjectMetadataItem;
|
||||
const fieldMetadataItem = mockedOpportunityObjectMetadataItem.fields.find(
|
||||
({ name }) => name === 'stage',
|
||||
)!;
|
||||
const selectOptions: SettingsDataModelFieldSelectFormValues['options'] = [
|
||||
{
|
||||
color: 'purple',
|
||||
label: '🏭 Industry',
|
||||
value: 'INDUSTRY',
|
||||
},
|
||||
{
|
||||
color: 'pink',
|
||||
isDefault: true,
|
||||
label: '💊 Health',
|
||||
value: 'HEALTH',
|
||||
},
|
||||
];
|
||||
|
||||
// When
|
||||
const result = getFieldDefaultPreviewValue({
|
||||
objectMetadataItem,
|
||||
fieldMetadataItem,
|
||||
selectOptions,
|
||||
fieldMetadataItem: { ...fieldMetadataItem, defaultValue: "'MEETING'" },
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(result).toEqual(selectOptions[1].value);
|
||||
expect(result).toEqual('MEETING');
|
||||
});
|
||||
|
||||
it('returns the first select option if no default option was found', () => {
|
||||
@ -47,28 +32,15 @@ describe('getFieldDefaultPreviewValue', () => {
|
||||
const fieldMetadataItem = mockedOpportunityObjectMetadataItem.fields.find(
|
||||
({ name }) => name === 'stage',
|
||||
)!;
|
||||
const selectOptions: SettingsDataModelFieldSelectFormValues['options'] = [
|
||||
{
|
||||
color: 'purple' as const,
|
||||
label: '🏭 Industry',
|
||||
value: 'INDUSTRY',
|
||||
},
|
||||
{
|
||||
color: 'pink' as const,
|
||||
label: '💊 Health',
|
||||
value: 'HEALTH',
|
||||
},
|
||||
];
|
||||
|
||||
// When
|
||||
const result = getFieldDefaultPreviewValue({
|
||||
objectMetadataItem,
|
||||
fieldMetadataItem,
|
||||
selectOptions,
|
||||
fieldMetadataItem: { ...fieldMetadataItem, defaultValue: null },
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(result).toEqual(selectOptions[0].value);
|
||||
expect(result).toEqual(fieldMetadataItem.options![0].value);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,106 +1,12 @@
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { SettingsDataModelFieldSelectFormValues } from '@/settings/data-model/components/SettingsObjectFieldSelectForm';
|
||||
import {
|
||||
mockedCompanyObjectMetadataItem,
|
||||
mockedOpportunityObjectMetadataItem,
|
||||
mockedPersonObjectMetadataItem,
|
||||
} from '~/testing/mock-data/metadata';
|
||||
|
||||
import { getFieldPreviewValueFromRecord } from '../getFieldPreviewValueFromRecord';
|
||||
|
||||
describe('getFieldPreviewValueFromRecord', () => {
|
||||
describe('SELECT field', () => {
|
||||
it('returns the select option corresponding to the record field value', () => {
|
||||
// Given
|
||||
const record: ObjectRecord = {
|
||||
id: '',
|
||||
stage: 'MEETING',
|
||||
__typename: 'Opportunity',
|
||||
};
|
||||
const fieldMetadataItem = mockedOpportunityObjectMetadataItem.fields.find(
|
||||
({ name }) => name === 'stage',
|
||||
)!;
|
||||
const selectOptions: SettingsDataModelFieldSelectFormValues['options'] = [
|
||||
{
|
||||
color: 'red',
|
||||
label: 'New',
|
||||
value: 'NEW',
|
||||
},
|
||||
{
|
||||
color: 'purple',
|
||||
label: 'Screening',
|
||||
value: 'SCREENING',
|
||||
},
|
||||
{
|
||||
color: 'sky',
|
||||
label: 'Meeting',
|
||||
value: 'MEETING',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
color: 'turquoise',
|
||||
label: 'Proposal',
|
||||
value: 'PROPOSAL',
|
||||
},
|
||||
{
|
||||
color: 'yellow',
|
||||
label: 'Customer',
|
||||
value: 'CUSTOMER',
|
||||
},
|
||||
];
|
||||
|
||||
// When
|
||||
const result = getFieldPreviewValueFromRecord({
|
||||
record,
|
||||
fieldMetadataItem,
|
||||
selectOptions,
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(result).toEqual(selectOptions[2].value);
|
||||
});
|
||||
|
||||
it('returns undefined if the select option was not found', () => {
|
||||
// Given
|
||||
const record: ObjectRecord = {
|
||||
id: '',
|
||||
industry: 'DOES_NOT_EXIST',
|
||||
__typename: 'Opportunity',
|
||||
};
|
||||
const fieldMetadataItem = mockedOpportunityObjectMetadataItem.fields.find(
|
||||
({ name }) => name === 'stage',
|
||||
)!;
|
||||
const selectOptions: SettingsDataModelFieldSelectFormValues['options'] = [
|
||||
{
|
||||
color: 'purple',
|
||||
label: '🏭 Industry',
|
||||
value: 'INDUSTRY',
|
||||
},
|
||||
{
|
||||
color: 'pink',
|
||||
isDefault: true,
|
||||
label: '💊 Health',
|
||||
value: 'HEALTH',
|
||||
},
|
||||
{
|
||||
color: 'turquoise',
|
||||
label: '🌿 Green tech',
|
||||
value: 'GREEN_TECH',
|
||||
},
|
||||
];
|
||||
|
||||
// When
|
||||
const result = getFieldPreviewValueFromRecord({
|
||||
record,
|
||||
fieldMetadataItem,
|
||||
selectOptions,
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('RELATION field', () => {
|
||||
it('returns the first relation record from a list of edges ("to many" relation)', () => {
|
||||
// Given
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
import { FieldMetadataType } from '~/generated/graphql';
|
||||
|
||||
import { isSelectOptionDefaultValue } from '../isSelectOptionDefaultValue';
|
||||
|
||||
describe('isSelectOptionDefaultValue', () => {
|
||||
describe('SELECT field', () => {
|
||||
it('returns true if the option value matches the default value', () => {
|
||||
// Given
|
||||
const optionValue = 'OPTION_1';
|
||||
const fieldMetadataItem = {
|
||||
defaultValue: `'${optionValue}'`,
|
||||
type: FieldMetadataType.Select,
|
||||
};
|
||||
|
||||
// When
|
||||
const result = isSelectOptionDefaultValue(optionValue, fieldMetadataItem);
|
||||
|
||||
// Then
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false if the option value does not match the default value', () => {
|
||||
// Given
|
||||
const optionValue = 'OPTION_1';
|
||||
const fieldMetadataItem = {
|
||||
defaultValue: "'OPTION_2'",
|
||||
type: FieldMetadataType.Select,
|
||||
};
|
||||
|
||||
// When
|
||||
const result = isSelectOptionDefaultValue(optionValue, fieldMetadataItem);
|
||||
|
||||
// Then
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('MULTI_SELECT field', () => {
|
||||
it('returns true if the option value is included in the default value array', () => {
|
||||
// Given
|
||||
const optionValue = 'OPTION_1';
|
||||
const fieldMetadataItem = {
|
||||
defaultValue: ["'OPTION_1'", "'OPTION_2'"],
|
||||
type: FieldMetadataType.MultiSelect,
|
||||
};
|
||||
|
||||
// When
|
||||
const result = isSelectOptionDefaultValue(optionValue, fieldMetadataItem);
|
||||
|
||||
// Then
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false if the option value is not included in the default value array', () => {
|
||||
// Given
|
||||
const optionValue = 'OPTION_1';
|
||||
const fieldMetadataItem = {
|
||||
defaultValue: ["'OPTION_2'", "'OPTION_3'"],
|
||||
type: FieldMetadataType.MultiSelect,
|
||||
};
|
||||
|
||||
// When
|
||||
const result = isSelectOptionDefaultValue(optionValue, fieldMetadataItem);
|
||||
|
||||
// Then
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -2,39 +2,41 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||
import { SettingsDataModelFieldSelectFormValues } from '@/settings/data-model/components/SettingsObjectFieldSelectForm';
|
||||
import { getSettingsFieldTypeConfig } from '@/settings/data-model/utils/getSettingsFieldTypeConfig';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString';
|
||||
|
||||
export const getFieldDefaultPreviewValue = ({
|
||||
fieldMetadataItem,
|
||||
objectMetadataItem,
|
||||
relationObjectMetadataItem,
|
||||
selectOptions,
|
||||
}: {
|
||||
fieldMetadataItem: Pick<FieldMetadataItem, 'type'> & {
|
||||
fieldMetadataItem: Pick<
|
||||
FieldMetadataItem,
|
||||
'type' | 'defaultValue' | 'options'
|
||||
> & {
|
||||
id?: string;
|
||||
name?: string;
|
||||
};
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
relationObjectMetadataItem?: ObjectMetadataItem;
|
||||
selectOptions?: SettingsDataModelFieldSelectFormValues['options'];
|
||||
}) => {
|
||||
if (
|
||||
fieldMetadataItem.type === FieldMetadataType.Select &&
|
||||
isDefined(selectOptions)
|
||||
) {
|
||||
const defaultSelectOption =
|
||||
selectOptions.find(({ isDefault }) => isDefault) || selectOptions[0];
|
||||
return defaultSelectOption.value;
|
||||
if (fieldMetadataItem.type === FieldMetadataType.Select) {
|
||||
const defaultValue = fieldMetadataItem.defaultValue
|
||||
? stripSimpleQuotesFromString(fieldMetadataItem.defaultValue)
|
||||
: null;
|
||||
return defaultValue ?? fieldMetadataItem.options?.[0]?.value ?? null;
|
||||
}
|
||||
|
||||
if (
|
||||
fieldMetadataItem.type === FieldMetadataType.MultiSelect &&
|
||||
isDefined(selectOptions)
|
||||
) {
|
||||
return selectOptions.map((selectOption) => selectOption.value);
|
||||
if (fieldMetadataItem.type === FieldMetadataType.MultiSelect) {
|
||||
const defaultValues = fieldMetadataItem.defaultValue?.map(
|
||||
(defaultValue: `'${string}'`) =>
|
||||
stripSimpleQuotesFromString(defaultValue),
|
||||
);
|
||||
return defaultValues?.length
|
||||
? defaultValues
|
||||
: fieldMetadataItem.options?.map(({ value }) => value) ?? null;
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@ -1,26 +1,16 @@
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { SettingsDataModelFieldSelectFormValues } from '@/settings/data-model/components/SettingsObjectFieldSelectForm';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
export const getFieldPreviewValueFromRecord = ({
|
||||
record,
|
||||
fieldMetadataItem,
|
||||
selectOptions,
|
||||
}: {
|
||||
record: ObjectRecord;
|
||||
fieldMetadataItem: Pick<FieldMetadataItem, 'name' | 'type'>;
|
||||
selectOptions?: SettingsDataModelFieldSelectFormValues['options'];
|
||||
}) => {
|
||||
const recordFieldValue = record[fieldMetadataItem.name];
|
||||
|
||||
// Select field
|
||||
if (fieldMetadataItem.type === FieldMetadataType.Select) {
|
||||
return selectOptions?.find(
|
||||
(selectOption) => selectOption.value === recordFieldValue,
|
||||
)?.value;
|
||||
}
|
||||
|
||||
// Relation fields (to many)
|
||||
if (
|
||||
fieldMetadataItem.type === FieldMetadataType.Relation &&
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
||||
|
||||
export const isSelectOptionDefaultValue = (
|
||||
optionValue: string,
|
||||
fieldMetadataItem: Pick<FieldMetadataItem, 'defaultValue' | 'type'>,
|
||||
): boolean => {
|
||||
if (fieldMetadataItem.type === FieldMetadataType.Select) {
|
||||
return (
|
||||
applySimpleQuotesToString(optionValue) === fieldMetadataItem.defaultValue
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
fieldMetadataItem.type === FieldMetadataType.MultiSelect &&
|
||||
Array.isArray(fieldMetadataItem.defaultValue)
|
||||
) {
|
||||
return fieldMetadataItem.defaultValue.includes(
|
||||
applySimpleQuotesToString(optionValue),
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
Reference in New Issue
Block a user