Skip to content

Commit

Permalink
feat: add all setup fields plus dummy placeholders to required fields
Browse files Browse the repository at this point in the history
  • Loading branch information
flaminic committed Dec 16, 2024
1 parent 27f8be0 commit 672889f
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 39 deletions.
10 changes: 8 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-12-09T08:26:30.983Z\n"
"PO-Revision-Date: 2024-12-09T08:26:30.983Z\n"
"POT-Creation-Date: 2024-12-11T08:38:02.793Z\n"
"PO-Revision-Date: 2024-12-11T08:38:02.793Z\n"

msgid "schemas"
msgstr "schemas"
Expand Down Expand Up @@ -1234,6 +1234,12 @@ msgstr "Configure data elements"
msgid "Choose what data is collected for this data set."
msgstr "Choose what data is collected for this data set."

msgid "Data set disaggregation"
msgstr "Data set disaggregation"

msgid "Choose an optional category combination to disaggregate the entire data set."
msgstr "Choose an optional category combination to disaggregate the entire data set."

msgid "Configure data entry periods"
msgstr "Configure data entry periods"

Expand Down
4 changes: 3 additions & 1 deletion src/app/routes/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ function createSectionLazyRouteFunction(
return async () => {
try {
return await import(
`../../pages/${section.routeName || section.namePlural}/${componentFileName}`
`../../pages/${
section.routeName || section.namePlural
}/${componentFileName}`
)
} catch (e) {
// means the component is not implemented yet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import i18n from '@dhis2/d2-i18n'
import React, { forwardRef } from 'react'
import { ModelSingleSelect } from '../ModelSingleSelect'
import type { ModelSingleSelectProps } from '../ModelSingleSelect'
import { useInitialOptionQuery } from './useInitialOptionQuery'
import { useOptionsQuery } from './useOptionsQuery'
import { useCategoryCombosQuery } from './useCategoryCombosQuery'
import { useInitialCategoryComboQuery } from './useInitialCategoryComboQuery'

type CategoryComboSelectProps = Omit<
ModelSingleSelectProps,
Expand All @@ -30,8 +30,8 @@ export const CategoryComboSelect = forwardRef(function CategoryComboSelect(
required={required}
invalid={invalid}
disabled={disabled}
useInitialOptionQuery={useInitialOptionQuery}
useOptionsQuery={useOptionsQuery}
useInitialOptionQuery={useInitialCategoryComboQuery}
useOptionsQuery={useCategoryCombosQuery}
placeholder={placeholder}
showAllOption={showAllOption}
onChange={onChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const DEFAULT_CATEGORY_SELECT_OPTION = {
label: DEFAULT_CATEGORY_COMBO.displayName,
}

export function useOptionsQuery() {
export function useCategoryCombosQuery() {
const [loadedOptions, setLoadedOptions] = useState<SelectOption[]>([])
// The gist doesn't include the `isDefault` value, need to use `useDataQuery`
const queryResult = useDataQuery<CategoryComboQueryResult>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type InitialCategoryComboQueryResult = {
categoryCombo: FilteredCategoryCombo
}

const INITIAL_OPTION_QUERY = {
const INITIAL_CATEGORY_COMBO_QUERY = {
categoryCombo: {
resource: 'categoryCombos',
id: (variables: Record<string, string>) => variables.id,
Expand All @@ -18,23 +18,26 @@ const INITIAL_OPTION_QUERY = {
},
}

export function useInitialOptionQuery({
export function useInitialCategoryComboQuery({
selected,
onComplete,
}: {
onComplete: (option: SelectOption) => void
selected?: string
}) {
const initialSelected = useRef(selected)
return useDataQuery<InitialCategoryComboQueryResult>(INITIAL_OPTION_QUERY, {
lazy:
!initialSelected.current ||
initialSelected.current === DEFAULT_CATEGORY_COMBO.id,
variables: { id: selected },
onComplete: (data) => {
const categoryCombo = data.categoryCombo
const { id: value, displayName: label } = categoryCombo
onComplete({ value, label })
},
})
return useDataQuery<InitialCategoryComboQueryResult>(
INITIAL_CATEGORY_COMBO_QUERY,
{
lazy:
!initialSelected.current ||
initialSelected.current === DEFAULT_CATEGORY_COMBO.id,
variables: { id: selected },
onComplete: (data) => {
const categoryCombo = data.categoryCombo
const { id: value, displayName: label } = categoryCombo
onComplete({ value, label })
},
}
)
}
17 changes: 7 additions & 10 deletions src/lib/optionSet/useOptionSetsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type OptionSetQueryResult = {
}
}

const CATEGORY_COMBOS_QUERY = {
const OPTION_SETS_QUERY = {
optionSets: {
resource: 'optionSets',
params: (variables: Record<string, string>) => {
Expand All @@ -35,15 +35,12 @@ const CATEGORY_COMBOS_QUERY = {

export function useOptionSetsQuery() {
const [loadedOptions, setLoadedOptions] = useState<SelectOption[]>([])
const queryResult = useDataQuery<OptionSetQueryResult>(
CATEGORY_COMBOS_QUERY,
{
variables: {
page: 1,
filter: '',
},
}
)
const queryResult = useDataQuery<OptionSetQueryResult>(OPTION_SETS_QUERY, {
variables: {
page: 1,
filter: '',
},
})
const { data } = queryResult

// Must be done in `useEffect` and not in `onComplete`, as `onComplete`
Expand Down
1 change: 0 additions & 1 deletion src/lib/routeUtils/routePaths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export const getSectionPath = (section: Section | string) => {
return section
}
return section.routeName || section.namePlural

}

export const getSectionNewPath = (section: Section | string) => {
Expand Down
24 changes: 24 additions & 0 deletions src/pages/dataSetsWip/form/CategoryComboField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import i18n from '@dhis2/d2-i18n'
import { Field, InputFieldFF } from '@dhis2/ui'
import React from 'react'
import { Field as FieldRFF, useField } from 'react-final-form'

export function CategoryComboField() {
const validate = () => {}
const { input, meta } = useField('categoryCombo', {
validateFields: [],
validate,
format: (categoryCombo) => categoryCombo && categoryCombo.id,
parse: (id) => ({ id }),
})
return (
<FieldRFF<string | undefined>
component={InputFieldFF}
inputWidth="400px"
label={i18n.t('{{fieldLabel}} (required)', {
fieldLabel: i18n.t('Category combination'),
})}
name="categoryCombo.id"
/>
)
}
23 changes: 20 additions & 3 deletions src/pages/dataSetsWip/form/DataSetFormContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ import {
import {
SECTIONS_MAP,
useSectionedFormContext,
useSelectedSection,
useSyncSelectedSectionWithScroll,
} from '../../../lib'
import { ColorAndIconField } from '../../dataElements/fields'
import { CategoryComboField } from './CategoryComboField'
import { DataSetFormDescriptor } from './formDescriptor'
import { PeriodTypeField } from './PeriodTypeField'

const section = SECTIONS_MAP.dataSet

export const DataSetFormContents = () => {
const descriptor = useSectionedFormContext<typeof DataSetFormDescriptor>()
useSyncSelectedSectionWithScroll()
const [selectedSection] = useSelectedSection()
return (
<>
<SectionedFormSections>
Expand All @@ -41,7 +42,12 @@ export const DataSetFormContents = () => {
)}
</StandardFormSectionDescription>
<DefaultIdentifiableFields />
<DescriptionField schemaSection={section} />
<StandardFormField>
<DescriptionField schemaSection={section} />
</StandardFormField>
<StandardFormField>
<ColorAndIconField />
</StandardFormField>
</SectionedFormSection>
<SectionedFormSection name={descriptor.getSection('data').name}>
<StandardFormSectionTitle>
Expand All @@ -60,6 +66,16 @@ export const DataSetFormContents = () => {
}}
/>
</StandardFormField>
<div style={{ height: 24 }} />
<StandardFormSectionTitle>
{i18n.t('Data set disaggregation')}
</StandardFormSectionTitle>
<StandardFormSectionDescription>
{i18n.t(
'Choose an optional category combination to disaggregate the entire data set.'
)}
</StandardFormSectionDescription>
<CategoryComboField />
</SectionedFormSection>
<SectionedFormSection
name={descriptor.getSection('periods').name}
Expand All @@ -72,6 +88,7 @@ export const DataSetFormContents = () => {
'Choose for what time periods data can be entered for this data set'
)}
</StandardFormSectionDescription>
<PeriodTypeField />
</SectionedFormSection>
<SectionedFormSection
name={descriptor.getSection('validation').name}
Expand Down
47 changes: 47 additions & 0 deletions src/pages/dataSetsWip/form/PeriodTypeField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import i18n from '@dhis2/d2-i18n'
import { InputFieldFF } from '@dhis2/ui'
import React from 'react'
import { Field as FieldRFF, useField } from 'react-final-form'

export function PeriodTypeField() {
const validate = () => {}
const { input, meta } = useField('categoryCombo', {
validateFields: [],
validate,
format: (categoryCombo) => categoryCombo && categoryCombo.id,
parse: (id) => ({ id }),
})
return (
<FieldRFF<string | undefined>
component={InputFieldFF}
inputWidth="400px"
label={i18n.t('Period type')}
name="periodType"
/>

// <Field
// required
// name="periodType"
// label={i18n.t('{{fieldLabel}} (required)', {
// fieldLabel: i18n.t('Period type'),
// })}
// error={meta.touched && !!meta.error}
// validationText={meta.touched ? meta.error : undefined}
// >
//
// <ModelSingleSelect
// required
// useInitialOptionQuery={useInitialCategoryComboQuery}
// useOptionsQuery={useCategoryCombosQuery}
// invalid={meta.touched && !!meta.error}
// selected={input.value}
// onChange={({ selected }) => {
// input.onChange(selected)
// input.onBlur()
// }}
// onBlur={input.onBlur}
// onFocus={input.onFocus}
// />
// </Field>
)
}
13 changes: 10 additions & 3 deletions src/pages/dataSetsWip/form/dataSetFormSchema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { z } from 'zod'
import { getDefaults, modelFormSchemas } from '../../../lib'
import {
DEFAULT_CATEGORY_COMBO,
getDefaults,
modelFormSchemas,
} from '../../../lib'
import { createFormValidate } from '../../../lib/form/validate'

const { withAttributeValues, identifiable, style, referenceCollection } =
Expand All @@ -10,10 +14,13 @@ export const dataSetFormSchema = identifiable
.extend({
id: z.string().optional(),
code: z.string().trim().optional(),
description: z.string().trim().optional(),
description: z.string().trim().max(2000).optional(),
style,
dataElements: referenceCollection.default([]),
// categoryCombo: z.object({ id: z.string() }),
categoryCombo: z
.object({ id: z.string() })
.default({ id: DEFAULT_CATEGORY_COMBO.id }),
periodType: z.string().default('Monthly'),
})

export const initialValues = getDefaults(dataSetFormSchema)
Expand Down
2 changes: 1 addition & 1 deletion src/types/section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface SectionBase {
namePlural: string
titlePlural: string
title: string
routeName?: string
}

// SchemaSection is a section that can be mapped directly to a schema by the name
Expand All @@ -22,7 +23,6 @@ export type NonSchemaSection = SectionBase & {

export type OverviewSection = SectionBase & {
componentName: string
routeName?: string
}

export type ModelSection = SchemaSection | NonSchemaSection
Expand Down

0 comments on commit 672889f

Please sign in to comment.