-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
refactor: reorg replacements to reflect form file hierarchy
Showing
18 changed files
with
1,778 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
File renamed without changes.
174 changes: 174 additions & 0 deletions
174
...end/src/features/admin-form/create/builder-and-design/EditFieldDrawer/EditFieldDrawer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
import { memo, useMemo } from 'react' | ||
|
||
import { | ||
BasicField, | ||
FieldCreateDto, | ||
MyInfoAttribute, | ||
} from '~shared/types/field' | ||
|
||
import { | ||
BASICFIELD_TO_DRAWER_META, | ||
MYINFO_FIELD_TO_DRAWER_META, | ||
} from '~features/admin-form/create/constants' | ||
import { isMyInfo } from '~features/myinfo/utils' | ||
import { useUser } from '~features/user/queries' | ||
|
||
import { useBuilderFields } from '../../BuilderAndDesignContent/useBuilderFields' | ||
import { | ||
FieldBuilderState, | ||
stateDataSelector, | ||
useFieldBuilderStore, | ||
} from '../../useFieldBuilderStore' | ||
import { BuilderDrawerContainer } from '../common/BuilderDrawerContainer' | ||
|
||
import { | ||
ChildrenCompoundFieldMyInfo, | ||
EditMyInfoChildren, | ||
} from './edit-fieldtype/EditMyInfoChildren' | ||
import { | ||
EditAttachment, | ||
EditCheckbox, | ||
EditCountryRegion, | ||
EditDate, | ||
EditDecimal, | ||
EditDropdown, | ||
EditEmail, | ||
EditHeader, | ||
EditHomeno, | ||
EditImage, | ||
EditLongText, | ||
EditMobile, | ||
EditMyInfo, | ||
EditNric, | ||
EditNumber, | ||
EditParagraph, | ||
EditRadio, | ||
EditRating, | ||
EditShortText, | ||
EditTable, | ||
EditUen, | ||
EditYesNo, | ||
} from './edit-fieldtype' | ||
|
||
export const EditFieldDrawer = (): JSX.Element | null => { | ||
const stateData = useFieldBuilderStore(stateDataSelector) | ||
|
||
const fieldToEdit: FieldCreateDto | undefined = useMemo(() => { | ||
if ( | ||
stateData.state === FieldBuilderState.EditingField || | ||
stateData.state === FieldBuilderState.CreatingField | ||
) { | ||
return stateData.field | ||
} | ||
}, [stateData]) | ||
|
||
const basicFieldText = useMemo(() => { | ||
if (!fieldToEdit?.fieldType) return '' | ||
if (isMyInfo(fieldToEdit)) { | ||
return MYINFO_FIELD_TO_DRAWER_META[fieldToEdit.myInfo.attr].label | ||
} | ||
return BASICFIELD_TO_DRAWER_META[fieldToEdit?.fieldType].label | ||
}, [fieldToEdit]) | ||
|
||
// Hacky method of determining when to rerender the drawer, | ||
// i.e. when the user clicks into a different field. | ||
// We pass `${fieldIndex}-${numFields}` as the key. If the | ||
// user was creating a new field but clicked into an existing | ||
// field, causing the new field to be discarded, then numFields | ||
// changes. If the user was editing an existing field then clicked | ||
// into another existing field, causing the edits to be discarded, | ||
// then fieldIndex changes. | ||
const { builderFields } = useBuilderFields() | ||
const fieldIndex = useMemo(() => { | ||
if (stateData.state === FieldBuilderState.CreatingField) { | ||
return stateData.insertionIndex | ||
} else if (stateData.state === FieldBuilderState.EditingField) { | ||
return builderFields?.findIndex( | ||
(field) => field._id === stateData.field._id, | ||
) | ||
} | ||
}, [builderFields, stateData]) | ||
const numFields = useMemo(() => builderFields?.length, [builderFields]) | ||
|
||
if (!fieldToEdit) return null | ||
|
||
return ( | ||
<BuilderDrawerContainer title={basicFieldText}> | ||
<MemoFieldDrawerContent | ||
field={fieldToEdit} | ||
key={`${fieldIndex}-${numFields}`} | ||
/> | ||
</BuilderDrawerContainer> | ||
) | ||
} | ||
|
||
interface MemoFieldDrawerContentProps { | ||
field: FieldCreateDto | ||
} | ||
|
||
export const MemoFieldDrawerContent = memo<MemoFieldDrawerContentProps>( | ||
({ field, ...props }) => { | ||
const { user } = useUser() | ||
if (isMyInfo(field)) { | ||
if ( | ||
field?.myInfo?.attr === MyInfoAttribute.ChildrenBirthRecords && | ||
user?.betaFlags?.children | ||
) { | ||
return ( | ||
<EditMyInfoChildren | ||
{...props} | ||
field={field as ChildrenCompoundFieldMyInfo} | ||
/> | ||
) | ||
} | ||
return <EditMyInfo {...props} field={field} /> | ||
} | ||
|
||
switch (field.fieldType) { | ||
case BasicField.Attachment: | ||
return <EditAttachment {...props} field={field} /> | ||
case BasicField.Checkbox: | ||
return <EditCheckbox {...props} field={field} /> | ||
case BasicField.Dropdown: | ||
return <EditDropdown {...props} field={field} /> | ||
case BasicField.CountryRegion: | ||
return <EditCountryRegion {...props} field={field} /> | ||
case BasicField.Mobile: | ||
return <EditMobile {...props} field={field} /> | ||
case BasicField.HomeNo: | ||
return <EditHomeno {...props} field={field} /> | ||
case BasicField.Email: | ||
return <EditEmail {...props} field={field} /> | ||
case BasicField.Nric: | ||
return <EditNric {...props} field={field} /> | ||
case BasicField.Number: | ||
return <EditNumber {...props} field={field} /> | ||
case BasicField.Date: | ||
return <EditDate {...props} field={field} /> | ||
case BasicField.Decimal: | ||
return <EditDecimal {...props} field={field} /> | ||
case BasicField.Section: | ||
return <EditHeader {...props} field={field} /> | ||
case BasicField.Uen: | ||
return <EditUen {...props} field={field} /> | ||
case BasicField.YesNo: | ||
return <EditYesNo {...props} field={field} /> | ||
case BasicField.Radio: | ||
return <EditRadio {...props} field={field} /> | ||
case BasicField.Rating: | ||
return <EditRating {...props} field={field} /> | ||
case BasicField.ShortText: | ||
return <EditShortText {...props} field={field} /> | ||
case BasicField.Table: | ||
return <EditTable {...props} field={field} /> | ||
case BasicField.LongText: | ||
return <EditLongText {...props} field={field} /> | ||
case BasicField.Statement: | ||
return <EditParagraph {...props} field={field} /> | ||
// case BasicField.Image: | ||
// return <EditImage {...props} field={field} /> | ||
default: | ||
return <div>TODO: Insert field options here</div> | ||
} | ||
}, | ||
) |
File renamed without changes.
150 changes: 150 additions & 0 deletions
150
replacements/frontend/src/features/admin-form/create/builder-and-design/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { | ||
BasicField, | ||
ChildrenCompoundFieldBase, | ||
DateFieldBase, | ||
DropdownFieldBase, | ||
MobileFieldBase, | ||
MyInfoAttribute, | ||
MyInfoChildAttributes, | ||
ShortTextFieldBase, | ||
} from '~shared/types/field' | ||
|
||
import { MyInfoFieldMeta } from '~features/myinfo/types' | ||
|
||
import { MYINFO_FIELD_TO_DRAWER_META } from '../constants' | ||
|
||
export const BASIC_FIELDS_ORDERED = [ | ||
BasicField.ShortText, | ||
BasicField.LongText, | ||
BasicField.Radio, | ||
BasicField.Checkbox, | ||
BasicField.Dropdown, | ||
BasicField.CountryRegion, | ||
BasicField.Section, | ||
BasicField.Statement, | ||
BasicField.YesNo, | ||
BasicField.Rating, | ||
BasicField.Email, | ||
BasicField.Mobile, | ||
BasicField.HomeNo, | ||
BasicField.Date, | ||
// BasicField.Image, | ||
BasicField.Table, | ||
BasicField.Attachment, | ||
BasicField.Number, | ||
BasicField.Decimal, | ||
BasicField.Nric, | ||
BasicField.Uen, | ||
] | ||
|
||
export const MYINFO_FIELDS_ORDERED: MyInfoAttribute[] = [ | ||
// Personal section | ||
MyInfoAttribute.Name, | ||
MyInfoAttribute.Sex, | ||
MyInfoAttribute.DateOfBirth, | ||
MyInfoAttribute.Race, | ||
MyInfoAttribute.Nationality, | ||
MyInfoAttribute.BirthCountry, | ||
MyInfoAttribute.ResidentialStatus, | ||
MyInfoAttribute.Dialect, | ||
MyInfoAttribute.HousingType, | ||
MyInfoAttribute.HdbType, | ||
MyInfoAttribute.PassportNumber, | ||
MyInfoAttribute.PassportExpiryDate, | ||
MyInfoAttribute.VehicleNo, | ||
// Contact section | ||
MyInfoAttribute.RegisteredAddress, | ||
MyInfoAttribute.MobileNo, | ||
// Particulars section | ||
MyInfoAttribute.Occupation, | ||
MyInfoAttribute.Employment, | ||
MyInfoAttribute.WorkpassStatus, | ||
MyInfoAttribute.WorkpassExpiryDate, | ||
// Family (Marriage) section | ||
MyInfoAttribute.Marital, | ||
MyInfoAttribute.CountryOfMarriage, | ||
MyInfoAttribute.MarriageCertNo, | ||
MyInfoAttribute.MarriageDate, | ||
MyInfoAttribute.DivorceDate, | ||
// Children section | ||
MyInfoAttribute.ChildrenBirthRecords, | ||
] | ||
|
||
export const MYINFO_TEXTFIELD_META: MyInfoFieldMeta<ShortTextFieldBase> = { | ||
ValidationOptions: { | ||
selectedValidation: null, | ||
customVal: null, | ||
}, | ||
} | ||
|
||
export const MYINFO_DROPDOWNFIELD_META: MyInfoFieldMeta<DropdownFieldBase> = { | ||
fieldOptions: [], | ||
} | ||
export const MYINFO_MOBILEFIELD_META: MyInfoFieldMeta<MobileFieldBase> = { | ||
allowIntlNumbers: false, | ||
isVerifiable: false, | ||
} | ||
|
||
export const MYINFO_DATEFIELD_META: MyInfoFieldMeta<DateFieldBase> = { | ||
dateValidation: { | ||
customMaxDate: null, | ||
customMinDate: null, | ||
selectedDateValidation: null, | ||
}, | ||
} | ||
|
||
export const MYINFO_CHILDRENFIELD_META: MyInfoFieldMeta<ChildrenCompoundFieldBase> = | ||
{ | ||
childrenSubFields: [MyInfoChildAttributes.ChildName], | ||
allowMultiple: false, | ||
} | ||
|
||
export const CREATE_MYINFO_PERSONAL_FIELDS_ORDERED = | ||
MYINFO_FIELDS_ORDERED.slice(0, 13) | ||
|
||
export const CREATE_MYINFO_CONTACT_FIELDS_ORDERED = MYINFO_FIELDS_ORDERED.slice( | ||
13, | ||
15, | ||
) | ||
|
||
export const CREATE_MYINFO_PARTICULARS_FIELDS_ORDERED = | ||
MYINFO_FIELDS_ORDERED.slice(15, 19) | ||
|
||
export const CREATE_MYINFO_MARRIAGE_FIELDS_ORDERED = | ||
MYINFO_FIELDS_ORDERED.slice(19, 24) | ||
|
||
export const CREATE_MYINFO_CHILDREN_FIELDS_ORDERED = | ||
MYINFO_FIELDS_ORDERED.slice(24, 25) | ||
|
||
export const CREATE_FIELD_DROP_ID = 'create-fields-field' | ||
|
||
export const CREATE_MYINFO_PERSONAL_DROP_ID = 'create-myinfo-personal' | ||
|
||
export const CREATE_MYINFO_CONTACT_DROP_ID = 'create-myinfo-drop' | ||
|
||
export const CREATE_MYINFO_PARTICULARS_DROP_ID = 'create-myinfo-particulars' | ||
|
||
export const CREATE_MYINFO_MARRIAGE_DROP_ID = 'create-myinfo-marriage' | ||
|
||
export const CREATE_MYINFO_CHILDREN_DROP_ID = 'create-myinfo-children' | ||
|
||
export const FIELD_LIST_DROP_ID = 'formFieldList' | ||
export const PENDING_CREATE_FIELD_ID = 'FIELD-PENDING-CREATION' | ||
|
||
export enum FieldListTabIndex { | ||
Basic = 0, | ||
MyInfo, | ||
Payments, | ||
} | ||
|
||
export const CREATE_MYINFO_CHILDREN_SUBFIELDS_OPTIONS: { | ||
value: MyInfoChildAttributes | ||
label: string | ||
}[] = Object.values(MyInfoChildAttributes) | ||
.filter((e) => e !== MyInfoChildAttributes.ChildName) | ||
.map((value) => { | ||
return { | ||
value, | ||
label: MYINFO_FIELD_TO_DRAWER_META[value].label, | ||
} | ||
}) |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import { BasicField } from '../../types/field' | ||
|
||
type BasicFieldBlock = { | ||
/** Type of field */ | ||
name: BasicField | ||
/** Default name of field */ | ||
value: string | ||
/** Whether field is to be submittable */ | ||
submitted: boolean | ||
/** Whether field is multi-answer */ | ||
answerArray: boolean | ||
} | ||
|
||
export const types: BasicFieldBlock[] = [ | ||
{ | ||
name: BasicField.Section, | ||
value: 'Header', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Statement, | ||
value: 'Statement', | ||
submitted: false, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Email, | ||
value: 'Email', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Mobile, | ||
value: 'Mobile Number', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.HomeNo, | ||
value: 'Home Number', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Number, | ||
value: 'Number', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Decimal, | ||
value: 'Decimal', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
// { | ||
// name: BasicField.Image, | ||
// value: 'Image', | ||
// submitted: false, | ||
// answerArray: false, | ||
// }, | ||
{ | ||
name: BasicField.ShortText, | ||
value: 'Short Text', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.LongText, | ||
value: 'Long Text', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Dropdown, | ||
value: 'Dropdown', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.CountryRegion, | ||
value: 'Country/Region', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.YesNo, | ||
value: 'Yes/No', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Checkbox, | ||
value: 'Checkbox', | ||
submitted: true, | ||
answerArray: true, | ||
}, | ||
{ | ||
name: BasicField.Radio, | ||
value: 'Radio', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Attachment, | ||
value: 'Attachment', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Date, | ||
value: 'Date', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Rating, | ||
value: 'Rating', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Nric, | ||
value: 'NRIC', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Uen, | ||
value: 'UEN', | ||
submitted: true, | ||
answerArray: false, | ||
}, | ||
{ | ||
name: BasicField.Table, | ||
value: 'Table', | ||
submitted: true, | ||
answerArray: true, | ||
}, | ||
] | ||
|
||
/** | ||
* Array of BasicFields which are not included in the form response (e.g. statement) | ||
*/ | ||
export const FIELDS_TO_REJECT: BasicField[] = types | ||
.filter((f) => !f.submitted) | ||
.map((f) => f.name) |
File renamed without changes.
Large diffs are not rendered by default.
Oops, something went wrong.
File renamed without changes.