diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/BasicFieldPanel.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/BasicFieldPanel.tsx index fec3eb39bf..2f8443a34d 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/BasicFieldPanel.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/BasicFieldPanel.tsx @@ -1,4 +1,3 @@ -import { useMemo } from 'react' import { Box } from '@chakra-ui/react' import { Droppable } from '@hello-pangea/dnd' @@ -12,16 +11,16 @@ import { useCreateTabForm } from '../../../../builder-and-design/useCreateTabFor import { DraggableBasicFieldListOption } from '../FieldListOption' import { FieldSection } from './FieldSection' +import { filterFieldsBySearchValue } from './utils' export const BasicFieldPanel = ({ searchValue }: { searchValue: string }) => { const { isLoading } = useCreateTabForm() - const filteredCreateBasicFields = useMemo(() => { - return BASIC_FIELDS_ORDERED.filter((fieldType) => { - const meta = BASICFIELD_TO_DRAWER_META[fieldType] - return meta.label.toLowerCase().includes(searchValue.toLowerCase()) - }) - }, [searchValue]) + const filteredCreateBasicFields = filterFieldsBySearchValue( + searchValue, + BASIC_FIELDS_ORDERED, + BASICFIELD_TO_DRAWER_META, + ) return ( diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/MyInfoPanel.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/MyInfoPanel.tsx index 5d160641c7..ec80ac19d1 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/MyInfoPanel.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/MyInfoPanel.tsx @@ -36,6 +36,7 @@ import { useCreateTabForm } from '../../../../builder-and-design/useCreateTabFor import { DraggableMyInfoFieldListOption } from '../FieldListOption' import { FieldSection } from './FieldSection' +import { filterFieldsBySearchValue } from './utils' const SGID_SUPPORTED_V1 = [ MyInfoAttribute.Name, @@ -126,40 +127,35 @@ export const MyInfoFieldPanel = ({ searchValue }: { searchValue: string }) => { [form, isDisabled, sgIDUnSupported], ) - const filteredCreateMyInfoPersonalFields = useMemo(() => { - return CREATE_MYINFO_PERSONAL_FIELDS_ORDERED.filter((fieldType) => { - const meta = MYINFO_FIELD_TO_DRAWER_META[fieldType] - return meta.label.toLowerCase().includes(searchValue.toLowerCase()) - }) - }, [searchValue]) + const filteredCreateMyInfoPersonalFields = filterFieldsBySearchValue( + searchValue, + CREATE_MYINFO_PERSONAL_FIELDS_ORDERED, + MYINFO_FIELD_TO_DRAWER_META, + ) - const filteredCreateMyInfoContactFields = useMemo(() => { - return CREATE_MYINFO_CONTACT_FIELDS_ORDERED.filter((fieldType) => { - const meta = MYINFO_FIELD_TO_DRAWER_META[fieldType] - return meta.label.toLowerCase().includes(searchValue.toLowerCase()) - }) - }, [searchValue]) + const filteredCreateMyInfoContactFields = filterFieldsBySearchValue( + searchValue, + CREATE_MYINFO_CONTACT_FIELDS_ORDERED, + MYINFO_FIELD_TO_DRAWER_META, + ) - const filteredCreateMyInfoParticularsFields = useMemo(() => { - return CREATE_MYINFO_PARTICULARS_FIELDS_ORDERED.filter((fieldType) => { - const meta = MYINFO_FIELD_TO_DRAWER_META[fieldType] - return meta.label.toLowerCase().includes(searchValue.toLowerCase()) - }) - }, [searchValue]) + const filteredCreateMyInfoParticularsFields = filterFieldsBySearchValue( + searchValue, + CREATE_MYINFO_PARTICULARS_FIELDS_ORDERED, + MYINFO_FIELD_TO_DRAWER_META, + ) - const filteredCreateMyInfoMarriageFields = useMemo(() => { - return CREATE_MYINFO_MARRIAGE_FIELDS_ORDERED.filter((fieldType) => { - const meta = MYINFO_FIELD_TO_DRAWER_META[fieldType] - return meta.label.toLowerCase().includes(searchValue.toLowerCase()) - }) - }, [searchValue]) + const filteredCreateMyInfoMarriageFields = filterFieldsBySearchValue( + searchValue, + CREATE_MYINFO_MARRIAGE_FIELDS_ORDERED, + MYINFO_FIELD_TO_DRAWER_META, + ) - const filteredCreateMyInfoChildrenFields = useMemo(() => { - return CREATE_MYINFO_CHILDREN_FIELDS_ORDERED.filter((fieldType) => { - const meta = MYINFO_FIELD_TO_DRAWER_META[fieldType] - return meta.label.toLowerCase().includes(searchValue.toLowerCase()) - }) - }, [searchValue]) + const filteredCreateMyInfoChildrenFields = filterFieldsBySearchValue( + searchValue, + CREATE_MYINFO_CHILDREN_FIELDS_ORDERED, + MYINFO_FIELD_TO_DRAWER_META, + ) return ( <> diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/utils.ts b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/utils.ts new file mode 100644 index 0000000000..cdae03cb2b --- /dev/null +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/utils.ts @@ -0,0 +1,31 @@ +import { BasicField, MyInfoAttribute } from '~shared/types' + +import { BuilderSidebarFieldMeta } from '~features/admin-form/create/constants' + +const checkSearchValueMatchesFieldMeta = ( + searchValue: string, + fieldMeta: BuilderSidebarFieldMeta, +) => { + const lowerCaseSearchValue = searchValue.toLowerCase() + return ( + fieldMeta.label.toLowerCase().includes(lowerCaseSearchValue) || + fieldMeta.alias?.some((alias) => + alias.toLowerCase().includes(lowerCaseSearchValue), + ) + ) +} + +export const filterFieldsBySearchValue = < + T extends BasicField | MyInfoAttribute, +>( + searchValue: string, + fields: T[], + fieldsMeta: { + [key in T]: BuilderSidebarFieldMeta + }, +) => { + return fields.filter((fieldType) => { + const fieldMeta = fieldsMeta[fieldType] + return checkSearchValueMatchesFieldMeta(searchValue, fieldMeta) + }) +} diff --git a/frontend/src/features/admin-form/create/constants.ts b/frontend/src/features/admin-form/create/constants.ts index 8ceca71882..a8e31311b6 100644 --- a/frontend/src/features/admin-form/create/constants.ts +++ b/frontend/src/features/admin-form/create/constants.ts @@ -47,11 +47,12 @@ import { As } from '@chakra-ui/react' import { BasicField, MyInfoAttribute } from '~shared/types/field' -type BuilderSidebarFieldMeta = { +export type BuilderSidebarFieldMeta = { label: string icon: As // Is this fieldType included in submissions? isSubmitted: boolean + alias?: string[] } // !!! Do not use this to reference field titles for MyInfo fields. !!! @@ -63,126 +64,173 @@ export const BASICFIELD_TO_DRAWER_META: { label: 'Image', icon: BiImage, isSubmitted: false, + alias: ['photo', 'picture'], }, [BasicField.Statement]: { label: 'Paragraph', icon: BiText, isSubmitted: false, + alias: ['description'], }, [BasicField.Section]: { label: 'Heading', icon: BiHeading, isSubmitted: false, + alias: ['header', 'title', 'section'], }, [BasicField.Attachment]: { label: 'Attachment', icon: BiCloudUpload, isSubmitted: true, + alias: ['document', 'file', 'upload'], }, [BasicField.Checkbox]: { label: 'Checkbox', icon: BiSelectMultiple, isSubmitted: true, + alias: ['choice', 'options', 'multiple'], }, [BasicField.Date]: { label: 'Date', icon: BiCalendarEvent, isSubmitted: true, + alias: [ + 'birthdate', + 'dob', + 'date of birth', + 'event date', + 'start date', + 'end date', + 'time', + ], }, [BasicField.Decimal]: { label: 'Decimal', icon: BiCalculator, isSubmitted: true, + alias: ['price', 'amount', 'cost'], }, [BasicField.Dropdown]: { label: 'Dropdown', icon: BiCaretDownSquare, isSubmitted: true, + alias: ['choice', 'options', 'category', 'type', 'status'], }, [BasicField.CountryRegion]: { label: 'Country/Region', icon: BiFlag, isSubmitted: true, + alias: ['country', 'region', 'location', 'nationality'], }, [BasicField.Email]: { label: 'Email', icon: BiMailSend, isSubmitted: true, + alias: ['contact'], }, [BasicField.HomeNo]: { label: 'Home number', icon: BiPhone, isSubmitted: true, + alias: ['phone', 'contact', 'telephone'], }, [BasicField.LongText]: { label: 'Long answer', icon: BiAlignLeft, isSubmitted: true, + alias: [ + 'text', + 'description', + 'comments', + 'feedback', + 'notes', + 'details', + 'explanation', + 'paragraph', + ], }, [BasicField.Mobile]: { label: 'Mobile number', icon: BiMobile, isSubmitted: true, + alias: ['phone', 'contact', 'telephone'], }, [BasicField.Nric]: { label: 'NRIC/FIN', icon: BiUser, isSubmitted: true, + alias: ['id', 'identification', 'national', 'singpass', 'ic number'], }, [BasicField.Number]: { label: 'Number', icon: BiHash, isSubmitted: true, + alias: ['age', 'quantity', 'count'], }, [BasicField.Radio]: { label: 'Radio', icon: BiRadioCircleMarked, isSubmitted: true, + alias: ['choice', 'options', 'mcq', 'multiple'], }, [BasicField.Rating]: { label: 'Rating', icon: BiStar, isSubmitted: true, + alias: ['satisfaction', 'quality', 'performance'], }, [BasicField.ShortText]: { label: 'Short answer', icon: BiRename, isSubmitted: true, + alias: ['name', 'text'], }, [BasicField.Table]: { label: 'Table', icon: BiTable, isSubmitted: true, + alias: [ + 'grid', + 'spreadsheet', + 'list', + 'collection', + 'entries', + 'records', + 'items', + 'multiple', + ], }, [BasicField.Uen]: { label: 'UEN', icon: BiBuilding, isSubmitted: true, + alias: ['business id', 'company registration', 'organization number'], }, [BasicField.YesNo]: { label: 'Yes/No', icon: BiToggleLeft, isSubmitted: true, + alias: ['consent', 'agreement', 'confirmation', 'approval', 'accept_terms'], }, [BasicField.Children]: {