Skip to content

Commit

Permalink
Merge pull request #8578 from opencrvs/ocrvs-8397-b
Browse files Browse the repository at this point in the history
Clean up Field types
  • Loading branch information
makelicious authored Feb 7, 2025
2 parents 9e4fec5 + 0f16abe commit f6786bf
Show file tree
Hide file tree
Showing 48 changed files with 929 additions and 722 deletions.
170 changes: 97 additions & 73 deletions packages/client/src/v2-events/components/forms/FormFieldGenerator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@

/* eslint-disable */
import { InputField } from '@client/components/form/InputField'
import { DATE, IFormFieldValue, PARAGRAPH, TEXT } from '@client/forms'
import { DateField } from '@opencrvs/components/lib/DateField'
import { Text } from '@opencrvs/components/lib/Text'
import { TextInput } from '@opencrvs/components/lib/TextInput'
import { TEXT } from '@client/forms'
import { Text as TextComponent } from '@opencrvs/components/lib/Text'
import * as React from 'react'

import styled, { keyframes } from 'styled-components'
Expand All @@ -29,14 +27,22 @@ import { Errors, getValidationErrorsForForm } from './validation'

import {
ActionFormData,
CheckboxFieldValue,
FieldConfig,
FieldType,
FieldValue,
FileFieldValue,
LocationFieldValue,
RadioGroupFieldValue,
SelectFieldValue
isBulletListFieldType,
isCheckboxFieldType,
isCountryFieldType,
isDateFieldType,
isDividerFieldType,
isFileFieldType,
isLocationFieldType,
isPageHeaderFieldType,
isParagraphFieldType,
isRadioGroupFieldType,
isSelectFieldType,
isTextFieldType
} from '@opencrvs/commons/client'
import {
Field,
Expand All @@ -52,15 +58,20 @@ import {
MessageDescriptor,
useIntl
} from 'react-intl'
import { FileInput } from './inputs/FileInput/FileInput'

import { RadioGroup } from '@client/v2-events/features/events/registered-fields'
import { BulletList } from '@client/v2-events/features/events/registered-fields/BulletList'
import { Checkbox } from '@client/v2-events/features/events/registered-fields/Checkbox'
import { Location } from '@client/v2-events/features/events/registered-fields/Location'
import { LocationSearch } from '@client/v2-events/features/events/registered-fields/LocationSearch'
import { Select } from '@client/v2-events/features/events/registered-fields/Select'
import { SelectCountry } from '@client/v2-events/features/events/registered-fields/SelectCountry'
import { File } from './inputs/FileInput/FileInput'

import {
BulletList,
Checkbox,
Date as DateField,
RadioGroup,
Location,
LocationSearch,
Select,
SelectCountry,
Text
} from '@client/v2-events/features/events/registered-fields'

import { SubHeader } from '@opencrvs/components'
import { formatISO } from 'date-fns'
import { Divider } from '@opencrvs/components'
Expand All @@ -78,16 +89,16 @@ const FormItem = styled.div<{
ignoreBottomMargin ? '0px' : '22px'};
`

interface GeneratedInputFieldProps<FieldType extends FieldConfig> {
fieldDefinition: FieldType
interface GeneratedInputFieldProps<T extends FieldConfig> {
fieldDefinition: T
fields: FieldConfig[]
values: ActionFormData
setFieldValue: (name: string, value: FieldValue | undefined) => void
onClick?: () => void
onChange: (e: React.ChangeEvent) => void
onBlur: (e: React.FocusEvent) => void
resetDependentSelectValues: (name: string) => void
value: IFormFieldValue
value: FieldValue
touched: boolean
error: string
formData: ActionFormData
Expand All @@ -98,7 +109,7 @@ interface GeneratedInputFieldProps<FieldType extends FieldConfig> {
}

const GeneratedInputField = React.memo(
<FieldType extends FieldConfig>({
<T extends FieldConfig>({
fieldDefinition,
onChange,
onBlur,
Expand All @@ -113,7 +124,7 @@ const GeneratedInputField = React.memo(
requiredErrorMessage,
fields,
values
}: GeneratedInputFieldProps<FieldType>) => {
}: GeneratedInputFieldProps<T>) => {
const intl = useIntl()

const inputFieldProps = {
Expand Down Expand Up @@ -155,157 +166,170 @@ const GeneratedInputField = React.memo(
[fieldDefinition.id, setFieldValue]
)

if (fieldDefinition.type === DATE) {
/**
* Combines the field definition with the current value and input field props
* USED FOR: rendering the correct input field based on the FieldConfig guards
*/
const field = {
inputFieldProps,
config: fieldDefinition,
value
}

if (isDateFieldType(field)) {
return (
<InputField {...inputFieldProps}>
<DateField
<InputField {...field.inputFieldProps}>
<DateField.Input
{...inputProps}
value={value as string}
value={field.value}
onChange={(val: string) => setFieldValue(fieldDefinition.id, val)}
/>
</InputField>
)
}
if (fieldDefinition.type === 'PAGE_HEADER') {
if (isPageHeaderFieldType(field)) {
return <SubHeader>{intl.formatMessage(fieldDefinition.label)}</SubHeader>
}
if (fieldDefinition.type === PARAGRAPH) {

if (isParagraphFieldType(field)) {
const label = fieldDefinition.label as unknown as MessageDescriptor & {
values: Record<string, string>
}
const values = label.values || {}

const message = intl.formatMessage(label, {
...values,
[fieldDefinition.id]: value as any
[fieldDefinition.id]: field.value
})

return (
<Text
<TextComponent
element="p"
variant={fieldDefinition.options.fontVariant ?? 'reg16'}
variant={field.config.configuration?.styles?.fontVariant ?? 'reg16'}
>
<span dangerouslySetInnerHTML={{ __html: message }} />
</Text>
</TextComponent>
)
}

if (fieldDefinition.type === TEXT) {
if (isTextFieldType(field)) {
return (
<InputField
{...inputFieldProps}
prefix={
fieldDefinition.options?.prefix &&
intl.formatMessage(fieldDefinition.options?.prefix)
field.config.configuration?.prefix &&
intl.formatMessage(field.config.configuration?.prefix)
}
postfix={
fieldDefinition.options?.postfix &&
intl.formatMessage(fieldDefinition.options?.postfix)
field.config.configuration?.postfix &&
intl.formatMessage(field.config.configuration?.postfix)
}
>
<TextInput
type={fieldDefinition.options?.type ?? 'text'}
<Text.Input
type={field.config.configuration?.type ?? 'text'}
{...inputProps}
isDisabled={disabled}
maxLength={fieldDefinition.options?.maxLength}
value={inputProps.value as string}
maxLength={field.config.configuration?.maxLength}
value={field.value}
/>
</InputField>
)
}
if (fieldDefinition.type === 'FILE') {

if (isFileFieldType(field)) {
const value = formData[fieldDefinition.id] as FileFieldValue
return (
<InputField {...inputFieldProps}>
<FileInput
<File.Input
{...inputProps}
value={value}
onChange={handleFileChange}
/>
</InputField>
)
}
if (fieldDefinition.type === 'BULLET_LIST') {
if (isBulletListFieldType(field)) {
return (
<InputField {...inputFieldProps}>
<BulletList {...fieldDefinition} />
<BulletList {...field.config} />
</InputField>
)
}
if (fieldDefinition.type === 'SELECT') {
if (isSelectFieldType(field)) {
return (
<InputField {...inputFieldProps}>
<Select
{...fieldDefinition}
value={inputProps.value as SelectFieldValue}
<Select.Input
{...field.config}
value={field.value}
onChange={(val: string) => setFieldValue(fieldDefinition.id, val)}
/>
</InputField>
)
}
if (fieldDefinition.type === 'COUNTRY') {
if (isCountryFieldType(field)) {
return (
<InputField {...inputFieldProps}>
<SelectCountry
{...fieldDefinition}
value={inputProps.value as SelectFieldValue}
<SelectCountry.Input
{...field.config}
value={field.value}
setFieldValue={setFieldValue}
/>
</InputField>
)
}
if (fieldDefinition.type === 'CHECKBOX') {
if (isCheckboxFieldType(field)) {
return (
<Checkbox
{...fieldDefinition}
value={value as CheckboxFieldValue}
<Checkbox.Input
{...field.config}
value={field.value}
setFieldValue={setFieldValue}
/>
)
}
if (fieldDefinition.type === 'RADIO_GROUP') {
if (isRadioGroupFieldType(field)) {
return (
<InputField {...inputFieldProps}>
<RadioGroup
{...fieldDefinition}
value={value as RadioGroupFieldValue}
<RadioGroup.Input
{...field.config}
value={field.value}
setFieldValue={setFieldValue}
/>
</InputField>
)
}
if (fieldDefinition.type === 'LOCATION') {
if (fieldDefinition.options.type === 'HEALTH_FACILITY')
if (isLocationFieldType(field)) {
if (field.config.options.type === 'HEALTH_FACILITY')
return (
<InputField {...inputFieldProps}>
<LocationSearch
{...fieldDefinition}
value={value as LocationFieldValue}
<LocationSearch.Input
{...field.config}
value={field.value}
setFieldValue={setFieldValue}
/>
</InputField>
)
return (
<InputField {...inputFieldProps}>
<Location
{...fieldDefinition}
value={value as LocationFieldValue}
<Location.Input
{...field.config}
value={field.value}
setFieldValue={setFieldValue}
partOf={
(fieldDefinition.options?.partOf?.$data &&
(field.config.options?.partOf?.$data &&
(makeFormikFieldIdsOpenCRVSCompatible(formData)[
fieldDefinition.options?.partOf.$data
field.config.options?.partOf.$data
] as string | undefined | null)) ??
null
}
/>
</InputField>
)
}
if (fieldDefinition.type === 'DIVIDER') {
if (isDividerFieldType(field)) {
return <Divider />
}
throw new Error(`Unsupported field ${fieldDefinition}`)

throw new Error(`Unsupported field ${JSON.stringify(fieldDefinition)}`)
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { FileFieldValue } from '@opencrvs/commons/client'
import { useFileUpload } from '@client/v2-events/features/files/useFileUpload'
import { SimpleDocumentUploader } from './SimpleDocumentUploader'

export function FileInput(
function FileInput(
props: Omit<
ComponentProps<typeof SimpleDocumentUploader>,
'onComplete' | 'label' | 'error'
Expand Down Expand Up @@ -71,4 +71,9 @@ export function FileInput(
)
}

export const FileOutput = null
const FileOutput = null

export const File = {
Input: FileInput,
Output: FileOutput
}
Loading

0 comments on commit f6786bf

Please sign in to comment.