Skip to content

Commit

Permalink
refactor(de group sets): align form code with de group form code
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohammer5 committed Mar 5, 2024
1 parent 6122afa commit eb2f878
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 455 deletions.
28 changes: 14 additions & 14 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-03-05T09:22:49.833Z\n"
"PO-Revision-Date: 2024-03-05T09:22:49.833Z\n"
"POT-Creation-Date: 2024-03-05T12:19:26.068Z\n"
"PO-Revision-Date: 2024-03-05T12:19:26.068Z\n"

msgid "schemas"
msgstr "schemas"
Expand Down Expand Up @@ -657,6 +657,9 @@ msgstr "This field requires a unique value, please choose another one"
msgid "Required"
msgstr "Required"

msgid "Custom attributes"
msgstr "Custom attributes"

msgid "Exit without saving"
msgstr "Exit without saving"

Expand All @@ -678,32 +681,29 @@ msgstr "Refresh list"
msgid "Add new"
msgstr "Add new"

msgid "Explain the purpose of this data element and how it's measured."
msgstr "Explain the purpose of this data element and how it's measured."

msgid "A data element name should be concise and easy to recognize."
msgstr "A data element name should be concise and easy to recognize."

msgid "Basic information"
msgstr "Basic information"

msgid "Set up the information for this data element group"
msgstr "Set up the information for this data element group"

msgid "Explain the purpose of this data element group."
msgstr "Explain the purpose of this data element group."

msgid "@TODO"
msgstr "@TODO"

msgid "Custom attributes"
msgstr "Custom attributes"
msgid "Custom fields for your DHIS2 instance"
msgstr "Custom fields for your DHIS2 instance"

msgid "Selected data elements"
msgstr "Selected data elements"

msgid "Explain the purpose of this data element group."
msgstr "Explain the purpose of this data element group."
msgid "Explain the purpose of this data element and how it's measured."
msgstr "Explain the purpose of this data element and how it's measured."

msgid "Custom fields for your DHIS2 instance"
msgstr "Custom fields for your DHIS2 instance"
msgid "A data element name should be concise and easy to recognize."
msgstr "A data element name should be concise and easy to recognize."

msgid "Create data element"
msgstr "Create data element"
Expand Down
252 changes: 110 additions & 142 deletions src/pages/dataElementGroupSets/Edit.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { useDataEngine, useDataQuery } from '@dhis2/app-runtime'
import { useDataQuery } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import { NoticeBox } from '@dhis2/ui'
import { FORM_ERROR, FormApi } from 'final-form'
import React, { useEffect, useRef } from 'react'
import { FormApi } from 'final-form'
import React from 'react'
import { withTypes } from 'react-final-form'
import { useNavigate, useParams } from 'react-router-dom'
import { Loader } from '../../components'
import {
Loader,
StandardFormActions,
StandardFormSection,
} from '../../components'
import { SCHEMA_SECTIONS, getSectionPath, validate } from '../../lib'
import { JsonPatchOperation } from '../../types'
import { DataElementGroupSet } from '../../types/generated'
import { createJsonPatchOperations } from './edit/'
import classes from './Edit.module.css'
DefaultFormContents,
useCustomAttributesQuery,
} from '../../components/form'
import {
SCHEMA_SECTIONS,
getSectionPath,
usePatchModel,
validate,
} from '../../lib'
import { createJsonPatchOperations } from '../../lib/form/createJsonPatchOperations'
import { getAllAttributeValues } from '../../lib/models/attributes'
import { Attribute, DataElementGroupSet } from '../../types/generated'
import {
DataElementGroupSetFormFields,
dataElementGroupSetSchema,
Expand All @@ -29,172 +32,137 @@ type DataElementGroupSetQueryResponse = {
dataElementGroupSet: DataElementGroupSet
}

const listPath = `/${getSectionPath(SCHEMA_SECTIONS.dataElementGroupSet)}`
const section = SCHEMA_SECTIONS.dataElementGroupSet

function useDataElementGroupSetQuery(id: string) {
const DATA_ELEMENT_QUERY = {
dataElementGroupSet: {
resource: `dataElementGroupSets/${id}`,
params: {
fields: ['*', 'attributeValues[*]'],
},
const query = {
dataElementGroupSet: {
resource: `dataElementGroupSets`,
id: ({ id }: Record<string, string>) => id,
params: {
fields: ['*', 'attributeValues[*]'],
},
}
},
}

return useDataQuery<DataElementGroupSetQueryResponse>(DATA_ELEMENT_QUERY, {
function useDataElementGroupSetQuery(id: string) {
return useDataQuery<DataElementGroupSetQueryResponse>(query, {
variables: { id },
})
}

function usePatchDirtyFields() {
const dataEngine = useDataEngine()
function computeInitialValues({
dataElementGroupSet,
customAttributes,
}: {
dataElementGroupSet: DataElementGroupSet
customAttributes: Attribute[]
}) {
if (!dataElementGroupSet) {
return {}
}

return async ({
values,
dirtyFields,
// We want to have an array in the state with all attributes, not just the
// ones that are set
const attributeValues = getAllAttributeValues(
dataElementGroupSet,
}: {
values: FormValues
dirtyFields: { [name: string]: boolean }
dataElementGroupSet: DataElementGroupSet
}) => {
const jsonPatchPayload = createJsonPatchOperations({
values,
dirtyFields,
originalValue: dataElementGroupSet,
})
customAttributes
)

// We want the promise so we know when submitting is done. The promise
// returned by the mutation function of useDataMutation will never
// resolve
const ADD_NEW_DATA_ELEMENT_MUTATION = {
resource: 'dataElementGroupSets',
id: values.id,
type: 'json-patch',
data: ({ operations }: { operations: JsonPatchOperation[] }) =>
operations,
} as const

try {
await dataEngine.mutate(ADD_NEW_DATA_ELEMENT_MUTATION, {
variables: { operations: jsonPatchPayload },
})
} catch (e) {
return { [FORM_ERROR]: (e as Error | string).toString() }
}
return {
id: dataElementGroupSet.id,
name: dataElementGroupSet.name,
shortName: dataElementGroupSet.shortName,
code: dataElementGroupSet.code,
description: dataElementGroupSet.description,
compulsory: dataElementGroupSet.compulsory,
dataDimension: dataElementGroupSet.dataDimension,
dataElementGroups: dataElementGroupSet.dataElementGroups || [],
attributeValues,
}
}

export const Component = () => {
const navigate = useNavigate()
const params = useParams()
const dataElementGroupSetId = params.id as string
const dataElementGroupSetQuery = useDataElementGroupSetQuery(
dataElementGroupSetId
)
const patchDirtyFields = usePatchDirtyFields()

async function onSubmit(values: FormValues, form: FinalFormFormApi) {
const errors = await patchDirtyFields({
values,
dirtyFields: form.getState().dirtyFields,
dataElementGroupSet: dataElementGroupSetQuery.data
?.dataElementGroupSet as DataElementGroupSet,
})
const attributesQuery = useCustomAttributesQuery()

if (errors) {
return errors
}

navigate(listPath)
}

const dataElementGroupSet = dataElementGroupSetQuery.data
?.dataElementGroupSet as DataElementGroupSet
const initialValues = dataElementGroupSet
? {
id: dataElementGroupSetId,
name: dataElementGroupSet.name,
shortName: dataElementGroupSet.shortName,
code: dataElementGroupSet.code,
description: dataElementGroupSet.description,
compulsory: dataElementGroupSet.compulsory,
dataDimension: dataElementGroupSet.dataDimension,
dataElementGroups: dataElementGroupSet.dataElementGroups || [],
}
: {}
const dataElementGroupSet =
dataElementGroupSetQuery.data?.dataElementGroupSet

return (
<Loader
queryResponse={dataElementGroupSetQuery}
label={i18n.t('Data element group')}
label={i18n.t('Data element group set')}
>
<Form
validateOnBlur
onSubmit={onSubmit}
validate={(values: FormValues) => {
return validate(dataElementGroupSetSchema, values)
}}
initialValues={initialValues}
<Loader
queryResponse={attributesQuery}
label={i18n.t('Attributes')}
>
{({ handleSubmit, submitting, submitError }) => (
<form onSubmit={handleSubmit}>
<FormContents
submitError={submitError}
submitting={submitting}
/>
</form>
)}
</Form>
<DataElementGroupSetForm
dataElementGroupSet={
dataElementGroupSet as DataElementGroupSet
}
attributes={attributesQuery.data}
></DataElementGroupSetForm>
</Loader>
</Loader>
)
}

function FormContents({
submitError,
submitting,
function DataElementGroupSetForm({
dataElementGroupSet,
attributes,
}: {
submitting: boolean
submitError?: string
dataElementGroupSet: DataElementGroupSet
attributes: Attribute[]
}) {
const formErrorRef = useRef<HTMLDivElement | null>(null)
const navigate = useNavigate()
const patchDirtyFields = usePatchModel(
dataElementGroupSet.id,
section.namePlural
)

async function onSubmit(values: FormValues, form: FinalFormFormApi) {
const jsonPatchOperations = createJsonPatchOperations({
values,
dirtyFields: form.getState().dirtyFields,
originalValue: dataElementGroupSet,
})
const errors = await patchDirtyFields(jsonPatchOperations)

useEffect(() => {
if (submitError) {
formErrorRef.current?.scrollIntoView({ behavior: 'smooth' })
if (errors) {
return errors
}
}, [submitError])

navigate(getSectionPath(section))
}

return (
<>
{submitError && (
<StandardFormSection>
<div ref={formErrorRef}>
<NoticeBox
error
title={i18n.t(
'Something went wrong when submitting the form'
)}
>
{submitError}
</NoticeBox>
</div>
</StandardFormSection>
<Form
validateOnBlur
onSubmit={onSubmit}
validate={(values: FormValues) => {
return validate(dataElementGroupSetSchema, values)
}}
initialValues={computeInitialValues({
dataElementGroupSet,
customAttributes: attributes,
})}
>
{({ handleSubmit, submitting, submitError }) => (
<form onSubmit={handleSubmit}>
<DefaultFormContents
section={section}
submitting={submitting}
submitError={submitError}
>
<DataElementGroupSetFormFields />
</DefaultFormContents>
</form>
)}

<div className={classes.form}>
<DataElementGroupSetFormFields />
</div>

<div className={classes.formActions}>
<StandardFormActions
cancelLabel={i18n.t('Cancel')}
submitLabel={i18n.t('Save and close')}
submitting={submitting}
onCancelClick={() => navigate(listPath)}
/>
</div>
</>
</Form>
)
}
Loading

0 comments on commit eb2f878

Please sign in to comment.