Skip to content

Commit

Permalink
feat: implement new and edit forms
Browse files Browse the repository at this point in the history
  • Loading branch information
Chisomchima committed Oct 16, 2024
1 parent 252fb8e commit 6033dfd
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/pages/categoryOptionGroups/Edit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react'
import { useQuery } from 'react-query'
import { useParams } from 'react-router-dom'
import { DefaultEditFormContents, FormBase } from '../../components'
import { DEFAULT_FIELD_FILTERS, SECTIONS_MAP, useOnSubmitEdit } from '../../lib'
import { useBoundResourceQueryFn } from '../../lib/query/useBoundQueryFn'
import { PickWithFieldFilters } from '../../types/generated'
import { Category } from '../../types/models'
import CategoryOptionGroupFormFields from './form/CategoryOptionGroupFormFields'
import { validate } from './form/categoryOptionGroupSchema'

const fieldFilters = [
...DEFAULT_FIELD_FILTERS,
'name',
'shortName',
'code',
'description',
'categoryOptions[id,displayName]',
'dataDimension',
'dataDimensionType',
'attributeValues[value,attribute[id]]',
] as const

export type CategoryFormValues = PickWithFieldFilters<
Category,
typeof fieldFilters
>

export const Component = () => {
const section = SECTIONS_MAP.categoryOptionGroup
const queryFn = useBoundResourceQueryFn()
const modelId = useParams().id as string
const query = {
resource: 'categoryOptionGroups',
id: modelId,
params: {
fields: fieldFilters.concat(),
},
}
const categoryQuery = useQuery({
queryKey: [query],
queryFn: queryFn<CategoryFormValues>,
})

return (
<FormBase
onSubmit={useOnSubmitEdit({ section, modelId })}
section={section}
initialValues={categoryQuery.data}
validate={validate}
>
<DefaultEditFormContents section={section}>
<CategoryOptionGroupFormFields />
</DefaultEditFormContents>
</FormBase>
)
}
23 changes: 23 additions & 0 deletions src/pages/categoryOptionGroups/New.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react'
import { FormBase } from '../../components'
import { DefaultNewFormContents } from '../../components/form/DefaultFormContents'
import { SECTIONS_MAP, useOnSubmitNew } from '../../lib'
import CategoryOptionGroupFormFields from './form/CategoryOptionGroupFormFields'
import { initialValues, validate } from './form/categoryOptionGroupSchema'

const section = SECTIONS_MAP.categoryOptionGroup

export const Component = () => {
return (
<FormBase
section={section}
onSubmit={useOnSubmitNew({ section })}
initialValues={initialValues}
validate={validate}
>
<DefaultNewFormContents section={section}>
<CategoryOptionGroupFormFields />
</DefaultNewFormContents>
</FormBase>
)
}
114 changes: 114 additions & 0 deletions src/pages/categoryOptionGroups/form/CategoryOptionGroupFormFields.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import i18n from '@dhis2/d2-i18n'
import { RadioFieldFF, CheckboxFieldFF } from '@dhis2/ui'
import React from 'react'
import { Field } from 'react-final-form'
import {
DefaultIdentifiableFields,
DescriptionField,
HorizontalFieldGroup,
ModelTransferField,
StandardFormField,
StandardFormSection,
StandardFormSectionDescription,
StandardFormSectionTitle,
} from '../../../components'
import { SECTIONS_MAP } from '../../../lib'

function CategoryOptionGroupFormFields() {
const section = SECTIONS_MAP.categoryOptionGroup
return (
<>
<StandardFormSection>
<StandardFormSectionTitle>
{i18n.t('Basic information')}
</StandardFormSectionTitle>
<StandardFormSectionDescription>
{i18n.t('Set up the basic information for this category.')}
</StandardFormSectionDescription>
<DefaultIdentifiableFields />
<DescriptionField
schemaSection={section}
helpText={i18n.t('Explain the purpose of this category.')}
/>
</StandardFormSection>

<StandardFormSection>
<StandardFormSectionTitle>
{i18n.t('Data configuration')}
</StandardFormSectionTitle>
<StandardFormSectionDescription>
{i18n.t(
'Choose how this category will be used to capture and analyze'
)}
</StandardFormSectionDescription>
<StandardFormField>
<HorizontalFieldGroup
label={'Data dimension type (required)'}
>
<Field<string | undefined>
name="dataDimensionType"
component={RadioFieldFF}
label={i18n.t('Disaggregation')}
type="radio"
value={'DISAGGREGATION'}
/>
<Field<string | undefined>
name="dataDimensionType"
component={RadioFieldFF}
label={i18n.t('Attribute')}
type="radio"
value={'ATTRIBUTE'}
/>
</HorizontalFieldGroup>
</StandardFormField>
<StandardFormField>
<Field
name="dataDimension"
type="checkbox"
component={CheckboxFieldFF}
label={i18n.t('Use as data dimension')}
helpText={i18n.t(
'Category will be available to the analytics as another dimension'
)}
/>
</StandardFormField>
</StandardFormSection>

<StandardFormSection>
<StandardFormSectionTitle>
<label htmlFor={'categoryOptions'}>
{i18n.t('Category options')}
</label>
</StandardFormSectionTitle>
<StandardFormSectionDescription>
{i18n.t(
'Choose the category options to include in this category.'
)}
</StandardFormSectionDescription>
<StandardFormField>
<StandardFormField>
<ModelTransferField
name="categoryOptions"
query={{
resource: 'categoryOptions',
params: {
filter: ['isDefault:eq:false'],
},
}}
leftHeader={i18n.t('Available category options')}
rightHeader={i18n.t('Selected category options')}
filterPlaceholder={i18n.t(
'Filter available category options'
)}
filterPlaceholderPicked={i18n.t(
'Filter selected category options'
)}
/>
</StandardFormField>
</StandardFormField>
</StandardFormSection>
</>
)
}

export default CategoryOptionGroupFormFields
27 changes: 27 additions & 0 deletions src/pages/categoryOptionGroups/form/categoryOptionGroupSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { z } from 'zod'
import { getDefaults, createFormValidate, modelFormSchemas } from '../../../lib'
import { CategoryOptionGroup } from '../../../types/generated'

/* Note that this describes what we send to the server,
and not what is stored in the form. */
const { identifiable, referenceCollection, withAttributeValues } =
modelFormSchemas

export const categoryOptionGroupSchema = identifiable
.merge(withAttributeValues)
.extend({
shortName: z.string().trim(),
code: z.string().trim().optional(),
description: z.string().trim().optional(),
dataDimensionType: z
.nativeEnum(CategoryOptionGroup.dataDimensionType)
.default(CategoryOptionGroup.dataDimensionType.DISAGGREGATION),
dataDimension: z.boolean().default(true),
categoryOptions: referenceCollection
.min(1, 'At least one category option is required')
.default([]),
})

export const initialValues = getDefaults(categoryOptionGroupSchema)

export const validate = createFormValidate(categoryOptionGroupSchema)

0 comments on commit 6033dfd

Please sign in to comment.