Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove FinalForm dependency in main form [DHIS2-18373] #425

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
167 changes: 133 additions & 34 deletions cypress/fixtures/network/41/a_data_set_can_be_selected.json

Large diffs are not rendered by default.

183 changes: 42 additions & 141 deletions cypress/fixtures/network/41/a_period_can_be_selected.json

Large diffs are not rendered by default.

226 changes: 195 additions & 31 deletions cypress/fixtures/network/41/a_section_filter_can_be_selected.json

Large diffs are not rendered by default.

78 changes: 39 additions & 39 deletions cypress/fixtures/network/41/an_org_unit_can_be_selected.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

271 changes: 119 additions & 152 deletions cypress/fixtures/network/41/static_resources.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions cypress/fixtures/network/41/summary.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"count": 1420,
"totalResponseSize": 5850276,
"duplicates": 1316,
"count": 1475,
"totalResponseSize": 5423540,
"duplicates": 1366,
"nonDeterministicResponses": 103,
"apiVersion": "41",
"fixtureFiles": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import React from 'react'
import { useMetadata } from '../../shared/metadata/use-metadata.js'
import { useDataSetId } from '../../shared/use-context-selection/use-context-selection.js'
import { render } from '../../test-utils/index.js'
import { FinalFormWrapper } from '../final-form-wrapper.js'
import { CategoryComboTableBody } from './category-combo-table-body.js'

jest.mock(
Expand All @@ -21,6 +20,33 @@ jest.mock('../../shared/metadata/use-metadata.js', () => ({
useMetadata: jest.fn(),
}))

const MOCK_VALUES = {
FTRrcoaog83: {
HllvX50cXC0: {
value: '5',
},
},
}

jest.mock('../../shared/stores/data-value-store.js', () => ({
useValueStore: jest.fn().mockImplementation((func) => {
const state = {
getInitialDataValue: ({ dataElementId, categoryOptionComboId }) => {
return MOCK_VALUES?.[dataElementId]?.[categoryOptionComboId]
?.value
},
hasComment: () => false,
getMinMaxValues: () => [],
getDataValue: () => '',
getDataValues: () => {
return MOCK_VALUES
},
}

return func(state)
}),
}))

const categories = {
fMZEcRHuamy: {
allItems: false,
Expand Down Expand Up @@ -493,11 +519,7 @@ describe('<CategoryComboTableBody />', () => {
/>
</Table>,
{
wrapper: ({ children }) => (
<FinalFormWrapper dataValueSet={{}}>
{children}
</FinalFormWrapper>
),
wrapper: ({ children }) => <>{children}</>,
}
)

Expand Down Expand Up @@ -547,11 +569,7 @@ describe('<CategoryComboTableBody />', () => {
/>
</Table>,
{
wrapper: ({ children }) => (
<FinalFormWrapper dataValueSet={{}}>
{children}
</FinalFormWrapper>
),
wrapper: ({ children }) => <>{children}</>,
}
)

Expand Down Expand Up @@ -599,11 +617,7 @@ describe('<CategoryComboTableBody />', () => {
/>
</Table>,
{
wrapper: ({ children }) => (
<FinalFormWrapper dataValueSet={{}}>
{children}
</FinalFormWrapper>
),
wrapper: ({ children }) => <>{children}</>,
}
)

Expand Down Expand Up @@ -662,11 +676,7 @@ describe('<CategoryComboTableBody />', () => {
/>
</Table>,
{
wrapper: ({ children }) => (
<FinalFormWrapper dataValueSet={{}}>
{children}
</FinalFormWrapper>
),
wrapper: ({ children }) => <>{children}</>,
}
)

Expand All @@ -689,11 +699,7 @@ describe('<CategoryComboTableBody />', () => {
/>
</Table>,
{
wrapper: ({ children }) => (
<FinalFormWrapper dataValueSet={{}}>
{children}
</FinalFormWrapper>
),
wrapper: ({ children }) => <>{children}</>,
}
)

Expand All @@ -715,19 +721,7 @@ describe('<CategoryComboTableBody />', () => {
/>
</Table>,
{
wrapper: ({ children }) => (
<FinalFormWrapper
dataValueSet={{
FTRrcoaog83: {
HllvX50cXC0: {
value: 5,
},
},
}}
>
{children}
</FinalFormWrapper>
),
wrapper: ({ children }) => <>{children}</>,
}
)

Expand All @@ -754,19 +748,7 @@ describe('<CategoryComboTableBody />', () => {
/>
</Table>,
{
wrapper: ({ children }) => (
<FinalFormWrapper
dataValueSet={{
FTRrcoaog83: {
HllvX50cXC0: {
value: 5,
},
},
}}
>
{children}
</FinalFormWrapper>
),
wrapper: ({ children }) => <>{children}</>,
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export const RowTotal = ({ dataElements, categoryOptionCombos, row }) => {
() => calculateRowTotal(matrix, row),
[matrix, row]
)

return <TotalCell>{rowTotal}</TotalCell>
}

Expand Down
24 changes: 14 additions & 10 deletions src/data-workspace/category-combo-table-body/use-value-matrix.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { getIn } from 'final-form'
import { useMemo, useRef } from 'react'
import { useForm } from 'react-final-form'
import { useBlurredField } from '../../shared/index.js'
import { useBlurredField, useValueStore } from '../../shared/index.js'
import { getFieldId } from '../get-field-id.js'
const createValueMatrix = (dataElements, sortedCOCs, formState) =>

const createValueMatrix = (dataElements, sortedCOCs, dataValues) =>
dataElements.map((de) =>
sortedCOCs.map((coc) =>
getIn(formState.values, getFieldId(de.id, coc.id))
)
sortedCOCs.map((coc) => dataValues?.[de?.id]?.[coc?.id]?.value)
)

/**
Expand All @@ -18,8 +15,9 @@ const createValueMatrix = (dataElements, sortedCOCs, formState) =>
*/
export const useValueMatrix = (dataElements = [], sortedCOCs = []) => {
const valueMatrixRef = useRef(null)
const form = useForm()
const blurredField = useBlurredField()
const dataValues = useValueStore((state) => state.getDataValues())

const affectedFieldsLookup = useMemo(
() =>
new Set(
Expand All @@ -38,9 +36,15 @@ export const useValueMatrix = (dataElements = [], sortedCOCs = []) => {
valueMatrixRef.current = createValueMatrix(
dataElements,
sortedCOCs,
form.getState()
dataValues
)
}
return valueMatrixRef.current
}, [blurredField, affectedFieldsLookup, dataElements, form, sortedCOCs])
}, [
blurredField,
affectedFieldsLookup,
dataElements,
dataValues,
sortedCOCs,
])
}
44 changes: 26 additions & 18 deletions src/data-workspace/custom-form/custom-form-total-cell.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,53 @@
import PropTypes from 'prop-types'
import React, { useState, useEffect } from 'react'
import { useForm } from 'react-final-form'
import { useBlurredField } from '../../shared/use-blurred-field.js'
import {
useBlurredField,
useValueStore,
useEntryFormStore,
} from '../../shared/index.js'
import { TotalCell } from '../category-combo-table-body/total-cells.js'
import { getFieldId, parseFieldId } from '../get-field-id.js'
import { parseFieldId } from '../get-field-id.js'

const computeTotal = (dataElementId, formState) => {
const { values, hasValidationErrors, errors } = formState
const dataElementValues = values[dataElementId]
const computeTotal = (dataElementId, dataValues, formErrors) => {
const dataElementValues = dataValues?.[dataElementId] || {}

if (!dataElementValues) {
return null
}

// Initialise sum as null and only start counting when numerical values
// are encountered to avoid rendering zeros when the sum isn't actually zero
return Object.entries(dataElementValues).reduce((sum, [cocId, value]) => {
const fieldHasError =
hasValidationErrors && errors[getFieldId(dataElementId, cocId)]
return Object.entries(dataElementValues).reduce(
(sum, [cocId, valueDetails]) => {
const fieldHasError = formErrors?.[dataElementId]?.[cocId]

if (!fieldHasError && !isNaN(value)) {
sum = isNaN(sum) ? value : sum + Number(value)
}
return sum
}, null)
const value = valueDetails?.value

if (!fieldHasError && !isNaN(value)) {
sum = isNaN(sum) ? value : sum + Number(value)
}
return sum
},
null
)
}

export const CustomFormTotalCell = ({ dataElementId }) => {
const form = useForm()
const dataValues = useValueStore((state) => state.getDataValues())
const formErrors = useEntryFormStore((state) => state.getErrors())

const blurredField = useBlurredField()
const [total, setTotal] = useState(() =>
computeTotal(dataElementId, form.getState())
computeTotal(dataElementId, dataValues, formErrors)
)

useEffect(() => {
const { dataElementId: blurredFieldDataElementId } =
parseFieldId(blurredField)
if (blurredFieldDataElementId === dataElementId) {
setTotal(computeTotal(dataElementId, form.getState()))
setTotal(computeTotal(dataElementId, dataValues, formErrors))
}
}, [blurredField, dataElementId, form])
}, [blurredField, dataElementId, dataValues, formErrors])

return <TotalCell>{total}</TotalCell>
}
Expand Down
9 changes: 8 additions & 1 deletion src/data-workspace/data-entry-cell/data-entry-field.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types'
import React from 'react'
import React, { useState } from 'react'
import {
useLockedContext,
useHighlightedFieldStore,
Expand All @@ -25,6 +25,9 @@ export const DataEntryField = React.memo(function DataEntryField({

const { locked } = useLockedContext()

const [active, setActive] = useState(false)
const [valueSynced, setValueSynced] = useState(false)

return (
<InnerWrapper
fieldname={fieldname}
Expand All @@ -33,6 +36,8 @@ export const DataEntryField = React.memo(function DataEntryField({
disabled={disabled}
locked={locked}
highlighted={highlighted}
valueSynced={valueSynced}
active={active}
>
<EntryFieldInput
fieldname={fieldname}
Expand All @@ -41,6 +46,8 @@ export const DataEntryField = React.memo(function DataEntryField({
disabled={disabled}
locked={locked}
highlighted={highlighted}
setActive={setActive}
setValueSynced={setValueSynced}
/>
</InnerWrapper>
)
Expand Down
Loading
Loading