Skip to content

Commit

Permalink
feat(de fields): add field rules & move catcombo validation to fields…
Browse files Browse the repository at this point in the history
….tsx
  • Loading branch information
Mohammer5 committed Nov 15, 2023
1 parent 4b47400 commit 23555fc
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 9 deletions.
3 changes: 0 additions & 3 deletions src/pages/dataElements/form/createDataElementSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ export const createDataElementSchema = (schemas: ModelSchemas) =>
z.literal('DEFAULT'),
])
.refine((v) => !!v, { message: requiredMessage }),
categoryCombo: z.object({
id: z.string().min(1, { message: requiredMessage }),
}),
optionSet: z.object({
id: z.string().optional(),
}),
Expand Down
187 changes: 181 additions & 6 deletions src/pages/dataElements/form/fields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ import {
SingleSelectFieldFF,
TextAreaFieldFF,
} from '@dhis2/ui'
import React, { useRef } from 'react'
import { Field as FieldRFF, useField } from 'react-final-form'
import React, { useEffect, useRef, useState } from 'react'
import {
Field as FieldRFF,
useField,
useForm,
useFormState,
} from 'react-final-form'
import { useHref } from 'react-router'
import { useParams } from 'react-router-dom'
import {
Expand All @@ -21,11 +26,16 @@ import {
LegendSetTransfer,
} from '../../../components'
import { AGGREGATION_TYPE, DOMAIN_TYPE, VALUE_TYPE } from '../../../constants'
import { useSchemas } from '../../../lib'
import { useOptionSetQuery, useSchemas } from '../../../lib'
import classes from './customFields.module.css'
import { EditableFieldWrapper } from './EditableFieldWrapper'
import { useIsFieldValueUnique } from './useIsFieldValueUnique'

/**
*
* Name
*
*/
export function NameField() {
const params = useParams()
const dataElementId = params.id as string
Expand Down Expand Up @@ -59,6 +69,11 @@ export function NameField() {
)
}

/**
*
* ShortName
*
*/
export function ShortNameField() {
const params = useParams()
const dataElementId = params.id as string
Expand Down Expand Up @@ -90,6 +105,11 @@ export function ShortNameField() {
)
}

/**
*
* Code
*
*/
export function CodeField() {
return (
<FieldRFF
Expand All @@ -103,6 +123,11 @@ export function CodeField() {
)
}

/**
*
* Description
*
*/
export function DescriptionField() {
return (
<FieldRFF
Expand All @@ -119,6 +144,11 @@ export function DescriptionField() {
)
}

/**
*
* Url
*
*/
export function UrlField() {
return (
<FieldRFF
Expand All @@ -133,6 +163,11 @@ export function UrlField() {
)
}

/**
*
* ColorAndIcon
*
*/
export function ColorAndIconField() {
const { input: colorInput } = useField('style.color', {
validateFields: [],
Expand Down Expand Up @@ -163,6 +198,11 @@ export function ColorAndIconField() {
)
}

/**
*
* FieldMask
*
*/
export function FieldMaskField() {
return (
<FieldRFF
Expand All @@ -180,6 +220,11 @@ export function FieldMaskField() {
)
}

/**
*
* FormName
*
*/
export function FormNameField() {
return (
<FieldRFF
Expand All @@ -196,6 +241,11 @@ export function FormNameField() {
)
}

/**
*
* ZeroIsSignificant
*
*/
export function ZeroIsSignificantField() {
return (
<FieldRFF
Expand All @@ -209,6 +259,11 @@ export function ZeroIsSignificantField() {
)
}

/**
*
* Domain
*
*/
export function DomainField() {
const name = 'domainType'
const validate = (value: string) => (!value ? 'Required' : undefined)
Expand Down Expand Up @@ -270,6 +325,11 @@ export function DomainField() {
)
}

/**
*
* LegendSet
*
*/
export function LegendSetField() {
const name = 'legendSets'
const { input, meta } = useField(name, {
Expand Down Expand Up @@ -328,18 +388,65 @@ export function LegendSetField() {
)
}

/**
*
* ValueType
* * Field rule: Unless valueType or the selected optionSet's valueType is
* MULTI_TEXT, filter out the MULTI_TEXT option
* * Field rule: When the selected optionSet's valueType is MULTI_TEXT, disable
* valueType field
* * Field rule: When the selected optionSet's valueType is MULTI_TEXT, set
* valueTypeField value to optionSet's valueType
*
*/
export function ValueTypeField() {
const { change } = useForm()
const { values } = useFormState({ subscription: { values: true } })
const disabled = !!values.optionSet.id
const [lazy] = useState(!values.optionSet.id)
const { refetch, ...optionSetQuery } = useOptionSetQuery({
lazy,
id: values.optionSet.id,
fields: ['id', 'valueType'],
})

useEffect(() => {
if (values.optionSet.id) {
refetch({ id: values.optionSet.id })
}
}, [refetch, values.optionSet.id])

useEffect(() => {
if (
values.optionSet.id &&
!optionSetQuery.loading &&
!optionSetQuery.fetching &&
!optionSetQuery.error &&
optionSetQuery.data?.optionSets.valueType
) {
change('valueType', optionSetQuery.data?.optionSets.valueType)
}
})

const schemas = useSchemas()
const { dataElement } = schemas
const options = dataElement.properties.valueType.constants?.map(
(constant) => ({
const optionSetHasMultiTextValueType =
values.valueType === 'MULTI_TEXT' ||
(values.optionSet?.id &&
optionSetQuery.data?.optionSets.valueType === 'MULTI_TEXT')
const options = dataElement.properties.valueType.constants
?.map((constant) => ({
value: constant,
label: VALUE_TYPE[constant as keyof typeof VALUE_TYPE],
}))
.filter(({ value }) => {
return optionSetHasMultiTextValueType || value !== 'MULTI_TEXT'
})
)

return (
<FieldRFF
required
disabled={disabled}
component={SingleSelectFieldFF}
dataTest="dataelementsformfields-valuetype"
inputWidth="400px"
Expand All @@ -354,7 +461,37 @@ export function ValueTypeField() {
)
}

/**
*
* AggregationType
* * Field rule: When value type has a certain value, disable aggregationType
* field
* * Field rule: When value type has a certain value, disable aggregationType
* value to ''
*
*/
export function AggregationTypeField() {
const { change } = useForm()
const { values } = useFormState({ subscription: { values: true } })
const disabled = [
'TEXT',
'LONG_TEXT',
'MULTI_TEXT',
'LETTER',
'PHONE_NUMBER',
'EMAIL',
'TRACKER_ASSOCIATE',
'USERNAME',
'FILE_RESOURCE',
'COORDINATE',
].includes(values.valueType)

useEffect(() => {
if (disabled) {
change('aggregationType', '')
}
}, [change, disabled])

const { dataElement } = useSchemas()
const options = dataElement.properties.aggregationType.constants?.map(
(constant) => ({
Expand All @@ -365,6 +502,7 @@ export function AggregationTypeField() {

return (
<FieldRFF
disabled={disabled}
component={SingleSelectFieldFF}
dataTest="dataelementsformfields-aggregationtype"
required
Expand All @@ -382,10 +520,31 @@ export function AggregationTypeField() {
)
}

/**
*
* CategoryCombo
* * Field rule: Disable when domainType is TRACKER
*
*/
const validateCategoryCombo = (value: string) => {
if (!value) {
return i18n.t('Required')
}
}

/*
* @TODO: Verify that the api ignores the category combo when it's disabled.
* If it does not, file a jira issue and "escalate" this so it will be
* implemented
*/
export function CategoryComboField() {
const { values } = useFormState({ subscription: { values: true } })
const disabled = values.domainType === 'TRACKER'
const validate = disabled ? undefined : validateCategoryCombo
const newCategoryComboLink = useHref('/categoryCombos/new')
const { input, meta } = useField('categoryCombo.id', {
validateFields: [],
validate,
})
const categoryComboHandle = useRef({
refetch: () => {
Expand Down Expand Up @@ -415,6 +574,7 @@ export function CategoryComboField() {
>
<CategoryComboSelect
placeholder=""
disabled={disabled}
invalid={meta.touched && !!meta.error}
ref={categoryComboHandle}
selected={input.value}
Expand All @@ -428,6 +588,11 @@ export function CategoryComboField() {
)
}

/**
*
* OptionSet
*
*/
export function OptionSetField() {
const newOptionSetLink = useHref('/optionSets/new')
const { input, meta } = useField('optionSet.id', {
Expand Down Expand Up @@ -471,6 +636,11 @@ export function OptionSetField() {
)
}

/**
*
* OptionSetComment
*
*/
export function OptionSetCommentField() {
const newOptionSetLink = useHref('/optionSets/new')
const { input, meta } = useField('commentOptionSet.id', {
Expand Down Expand Up @@ -514,6 +684,11 @@ export function OptionSetCommentField() {
)
}

/**
*
* AggregationLevels
*
*/
export function AggregationLevelsField() {
const newAggregationLevelLink = useHref('/organisationUnitLevel/new')
const { input, meta } = useField('aggregationLevels', {
Expand Down

0 comments on commit 23555fc

Please sign in to comment.