Skip to content

Commit

Permalink
feat: add org unit edit form
Browse files Browse the repository at this point in the history
  • Loading branch information
flaminic committed Oct 28, 2024
1 parent 9fa40dc commit e63b5b8
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 71 deletions.
77 changes: 42 additions & 35 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-10-23T11:07:53.225Z\n"
"PO-Revision-Date: 2024-10-23T11:07:53.225Z\n"
"POT-Creation-Date: 2024-10-28T13:53:29.437Z\n"
"PO-Revision-Date: 2024-10-28T13:53:29.437Z\n"

msgid "schemas"
msgstr "schemas"
Expand Down Expand Up @@ -123,21 +123,6 @@ msgstr "Failed to load {{label}}"
msgid "Failed to load"
msgstr "Failed to load"

msgid "Download"
msgstr "Download"

msgid "Merge"
msgstr "Merge"

msgid "Delete source data element values"
msgstr "Delete source data element values"

msgid "Last updated"
msgstr "Last updated"

msgid "Discard"
msgstr "Discard"

msgid "Aggregation level(s)"
msgstr "Aggregation level(s)"

Expand Down Expand Up @@ -237,6 +222,9 @@ msgstr "Created"
msgid "Last updated by"
msgstr "Last updated by"

msgid "Last updated"
msgstr "Last updated"

msgid "Id"
msgstr "Id"

Expand All @@ -258,6 +246,9 @@ msgstr "Details"
msgid "Failed to load details"
msgstr "Failed to load details"

msgid "Download"
msgstr "Download"

msgid "Download {{section}}"
msgstr "Download {{section}}"

Expand Down Expand Up @@ -858,6 +849,9 @@ msgstr "Data dimension type"
msgid "This field requires a unique value, please choose another one"
msgstr "This field requires a unique value, please choose another one"

msgid "{{label}} (required)"
msgstr "{{label}} (required)"

msgid "No changes to be saved"
msgstr "No changes to be saved"

Expand All @@ -879,23 +873,27 @@ msgstr "Basic information"
msgid "Set up the basic information for this category."
msgstr "Set up the basic information for this category."

msgid "Explain the purpose of this category."
msgstr "Explain the purpose of this category."
msgid "Explain the purpose of this category option group."
msgstr "Explain the purpose of this category option group."

msgid "Data configuration"
msgstr "Data configuration"

msgid "Choose how this category will be used to capture and analyze"
msgstr "Choose how this category will be used to capture and analyze"
msgid "Choose how this category option group will be used to capture and analyze"
msgstr "Choose how this category option group will be used to capture and analyze"

msgid "Use as data dimension"
msgstr "Use as data dimension"

msgid "Category will be available to the analytics as another dimension"
msgstr "Category will be available to the analytics as another dimension"
msgid ""
"Category option group will be available to the analytics as another "
"dimension"
msgstr ""
"Category option group will be available to the analytics as another "
"dimension"

msgid "Choose the category options to include in this category."
msgstr "Choose the category options to include in this category."
msgid "Choose the category options to include in this category option group."
msgstr "Choose the category options to include in this category option group."

msgid "Available category options"
msgstr "Available category options"
Expand Down Expand Up @@ -933,6 +931,15 @@ msgstr "Filter selected categories"
msgid "At least one category is required"
msgstr "At least one category is required"

msgid "Set up the basic information for this category option group."
msgstr "Set up the basic information for this category option group."

msgid "Choose how this category option will be used to capture and analyze"
msgstr "Choose how this category option will be used to capture and analyze"

msgid "Choose the category options to include in this category."
msgstr "Choose the category options to include in this category."

msgid "Set up the basic information for this category option."
msgstr "Set up the basic information for this category option."

Expand Down Expand Up @@ -1081,6 +1088,12 @@ msgstr ""
"included. PHU will still be available for the PHU level, but not included "
"in the aggregations to the levels above."

msgid "Longitude"
msgstr "Longitude"

msgid "{{type}} coordinates are not editable"
msgstr "{{type}} coordinates are not editable"

msgid "Upload an image"
msgstr "Upload an image"

Expand Down Expand Up @@ -1130,17 +1143,11 @@ msgstr "Location"
msgid "Set up the organisation unit location."
msgstr "Set up the organisation unit location."

msgid "Latitude"
msgstr "Latitude"

msgid "Longitude"
msgstr "Longitude"

msgid "Reference assignments"
msgstr "Reference assignments"
msgid "Reference assignment"
msgstr "Reference assignment"

msgid "Assign the organisation unit to related models."
msgstr "Assign the organisation unit to related models."
msgid "Assign the organisation unit to related objects."
msgstr "Assign the organisation unit to related objects."

msgid "Available data sets"
msgstr "Available data sets"
Expand Down
84 changes: 84 additions & 0 deletions src/pages/organisationUnits/Edit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react'
import { useQuery } from 'react-query'
import { useParams } from 'react-router-dom'
import { DefaultEditFormContents, FormBase } from '../../components'
import {
ATTRIBUTE_VALUES_FIELD_FILTERS,
DEFAULT_FIELD_FILTERS,
SECTIONS_MAP,
useOnSubmitEdit,
validate,
} from '../../lib'
import { useBoundResourceQueryFn } from '../../lib/query/useBoundQueryFn'
import { OrganisationUnit, PickWithFieldFilters } from '../../types/generated'
import {
FormValues,
OrganisationUnitFormField,
organisationUnitSchema,
} from './form'

const fieldFilters = [
...DEFAULT_FIELD_FILTERS,
...ATTRIBUTE_VALUES_FIELD_FILTERS,
'name',
'code',
'shortName',
'openingDate',
'closedDate',
'comment',
'image',
'description',
'contactPerson',
'address',
'email',
'phoneNumber',
'url',
'geometry',
'dataSets',
'programs',
'level',
'path',
'parent[id,path, displayName]',
] as const

export type OrgUnitFormValues = PickWithFieldFilters<
OrganisationUnit,
typeof fieldFilters
>

const section = SECTIONS_MAP.organisationUnit

export const Component = () => {
const queryFn = useBoundResourceQueryFn()
const modelId = useParams().id as string

const query = {
resource: 'organisationUnits',
id: modelId,
params: {
fields: fieldFilters.concat(),
},
}
const orgUnit = useQuery({
queryKey: [query],
queryFn: queryFn<OrgUnitFormValues>,
})

return (
<FormBase
onSubmit={useOnSubmitEdit({
section,
modelId,
})}
section={section}
initialValues={orgUnit.data as FormValues}
validate={(values: FormValues) => {
return validate(organisationUnitSchema, values)
}}
>
<DefaultEditFormContents section={section}>
<OrganisationUnitFormField />
</DefaultEditFormContents>
</FormBase>
)
}
16 changes: 3 additions & 13 deletions src/pages/organisationUnits/New.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,11 @@ import {
organisationUnitSchema,
} from './form'

const formatFormValues: (values: FormValues) => Record<string, unknown> = (
values
) => {
export const formatFormValues: (
values: FormValues
) => Record<string, unknown> = (values) => {
return {
...values,
geometry:
values.geometry?.longitude && values.geometry?.latitude
? {
type: 'Point',
coordinates: [
values.geometry?.longitude,
values.geometry?.latitude,
],
}
: undefined,
attributeValues: values.attributeValues.filter(({ value }) => !!value),
}
}
Expand Down
75 changes: 75 additions & 0 deletions src/pages/organisationUnits/form/GeometryFields.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import i18n from '@dhis2/d2-i18n'
import { Field, InputField } from '@dhis2/ui'
import React from 'react'
import { useField } from 'react-final-form'

export function GeometryFields() {
const fieldName = 'geometry'
const { input, meta } = useField(fieldName)

const handleChange = ({
longitude,
latitude,
}: {
longitude?: string
latitude?: string
}) => {
const geometry = {
type: 'Point',
coordinates: [longitude || undefined, latitude || undefined],
}

input.onChange(geometry)
}

return !input.value || input.value?.type === 'Point' ? (
<>
<Field
name={fieldName}
error={meta.touched && meta.error}
validationText={meta.touched ? meta.error : undefined}
>
<InputField
onChange={(e) =>
handleChange({
longitude: e.value,
latitude: input.value.coordinates?.[1],
})
}
label={i18n.t('Longitude')}
inputWidth="400px"
name="longitude"
type="number"
value={input.value.coordinates?.[0].toString()}
min="-90"
max="90"
step="any"
/>
<InputField
onChange={(e) =>
handleChange({
longitude: input.value.coordinates?.[0],
latitude: e.value,
})
}
inputWidth="400px"
label={i18n.t('Longitude')}
name="latitude"
type="number"
value={input.value.coordinates?.[1].toString()}
min="-180"
max="180"
step="any"
/>
</Field>
</>
) : (
<InputField
value={i18n.t('{{type}} coordinates are not editable', {
type: input.value?.type,
})}
inputWidth="400px"
disabled
/>
)
}
22 changes: 2 additions & 20 deletions src/pages/organisationUnits/form/OrganisationUnitFormFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { DateField } from '../../../components/form/fields/DateField'
import { SCHEMA_SECTIONS, useSystemSetting } from '../../../lib'
import { ImageField } from './ImageField'
import { OrganisationUnitSelector } from './OrganisationUnitSelector'
import { GeometryFields } from './GeometryFields'

Check failure on line 21 in src/pages/organisationUnits/form/OrganisationUnitFormFields.tsx

View workflow job for this annotation

GitHub Actions / lint

`./GeometryFields` import should occur before import of `./ImageField`

const schemaSection = SCHEMA_SECTIONS.organisationUnit

Expand Down Expand Up @@ -126,26 +127,7 @@ export function OrganisationUnitFormField() {
<StandardFormSectionDescription>
{i18n.t('Set up the organisation unit location.')}
</StandardFormSectionDescription>

<FieldRFF<string | undefined>
component={InputFieldFF}
inputWidth="400px"
label={i18n.t('Latitude')}
name="geometry.latitude"
type="number"
min="-90"
max="90"
/>

<FieldRFF<string | undefined>
component={InputFieldFF}
inputWidth="400px"
label={i18n.t('Longitude')}
name="geometry.longitude"
type="number"
min="-180"
max="180"
/>
<GeometryFields />
</StandardFormSection>
{allowReferenceAssignments && (
<StandardFormSection>
Expand Down
Loading

0 comments on commit e63b5b8

Please sign in to comment.