From 60b9cbe2e5c8098bdb190d4e627bc0d63ff57bee Mon Sep 17 00:00:00 2001 From: henrikmv Date: Sat, 4 Jan 2025 17:39:21 +0100 Subject: [PATCH 1/4] fix: remove type check when comparing values --- src/core_modules/capture-core/metaData/OptionSet/OptionSet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core_modules/capture-core/metaData/OptionSet/OptionSet.js b/src/core_modules/capture-core/metaData/OptionSet/OptionSet.js index edf727abce..5924c954d3 100644 --- a/src/core_modules/capture-core/metaData/OptionSet/OptionSet.js +++ b/src/core_modules/capture-core/metaData/OptionSet/OptionSet.js @@ -142,7 +142,7 @@ export class OptionSet { } getOption(value: Value): ?Option { - const option = this.options.find(o => o.value === value); + const option = this.options.find(o => o.value == value); if (!option) { log.warn( errorCreator(OptionSet.errorMessages.OPTION_NOT_FOUND)({ OptionSet: this, value }), From f7136327dc1a15032d18d57a4776e174498cf3f5 Mon Sep 17 00:00:00 2001 From: henrikmv Date: Wed, 15 Jan 2025 16:28:47 +0100 Subject: [PATCH 2/4] fix: convert options to client values --- .../StageDetail/StageDetail.component.js | 7 ++-- .../Stages/Stage/StageDetail/hooks/helpers.js | 4 +-- .../hooks/useClientDataElements.js | 29 +++++++++++++++++ .../Stage/StageDetail/hooks/useEventList.js | 32 +++++++++---------- .../types/common.types.js | 10 ++++++ .../metaData/OptionSet/OptionSet.js | 2 +- 6 files changed, 61 insertions(+), 23 deletions(-) create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useClientDataElements.js diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js index e36d5f4b16..5bbd959f5c 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js @@ -27,6 +27,7 @@ import { getProgramAndStageForProgram } from '../../../../../metaData/helpers'; import type { Props } from './stageDetail.types'; import { EventRow } from './EventRow'; import { errorCreator } from '../../../../../../capture-core-utils'; +import { useClientDataElements } from './hooks/useClientDataElements'; const styles = { @@ -113,8 +114,8 @@ const StageDetailPlain = (props: Props) => { }; const { stage } = getProgramAndStageForProgram(programId, stageId); const headerColumns = useComputeHeaderColumn(dataElements, hideDueDate, enableUserAssignment, stage?.stageForm); - const { loading, value: dataSource, error } = useComputeDataFromEvent(dataElements, events); - + const dataElementsClient = useClientDataElements(dataElements); + const { loading, value: dataSource, error } = useComputeDataFromEvent(dataElementsClient, events); const [{ columnName, sortDirection }, setSortInstructions] = useState(defaultSortState); const [displayedRowNumber, setDisplayedRowNumber] = useState(DEFAULT_NUMBER_OF_ROW); @@ -178,7 +179,7 @@ const StageDetailPlain = (props: Props) => { return sortDataFromEvent({ dataA, dataB, type, columnName, direction: sortDirection }); }) .slice(0, displayedRowNumber) - .map(row => formatRowForView(row, dataElements)) + .map(row => formatRowForView(row, dataElementsClient)) .map((row: Object) => { const cells = headerColumns.map(({ id }) => ( , - dataElements: Array, + dataElements: Array, querySingleResource: QuerySingleResource, absoluteApiPath: string, ) => { diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useClientDataElements.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useClientDataElements.js new file mode 100644 index 0000000000..62d68a8d3b --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useClientDataElements.js @@ -0,0 +1,29 @@ +// @flow +import { useMemo } from 'react'; +import { convertValue } from 'capture-core/converters/serverToClient'; +import type { StageDataElement, StageDataElementClient } from '../../../../types/common.types'; + +const convertToClientDataElement = (dataElement: StageDataElement): StageDataElementClient => { + const { options, type, ...rest } = dataElement; + + const convertedOptions = options + ? Object.entries(options).map(([key, value]) => ({ + value: convertValue(key, type), + text: value, + })) + : []; + + return { + ...rest, + type, + options: convertedOptions, + }; +}; + +export const useClientDataElements = (dataElements: Array) => + useMemo < Array>(() => { + if (!dataElements) { + return []; + } + return dataElements.map(convertToClientDataElement); + }, [dataElements]); diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js index f160eb00e3..3f5a0e76e0 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js @@ -6,7 +6,7 @@ import { useDataEngine, useConfig } from '@dhis2/app-runtime'; import { makeQuerySingleResource } from 'capture-core/utils/api'; import { errorCreator, buildUrl } from 'capture-core-utils'; import { dataElementTypes, DataElement, OptionSet, Option } from '../../../../../../metaData'; -import type { StageDataElement } from '../../../../types/common.types'; +import type { StageDataElement, StageDataElementClient } from '../../../../types/common.types'; import { convertValue as convertClientToList } from '../../../../../../converters/clientToList'; import { convertValue as convertServerToClient } from '../../../../../../converters/serverToClient'; import { @@ -46,8 +46,8 @@ const getBaseColumns = props => baseFields.map((key, index) => ({ ...key, ...get const getAllFieldsWithValue = ( eventId: string, - dataElements: Array, - dataElementsByType: Array<{type: string, eventId: string, ids: Object}>, + dataElements: Array, + dataElementsByType: Array<{ type: string, eventId: string, ids: Object }>, ) => dataElements .reduce((acc, { id, type }) => { const value = dataElementsByType @@ -60,7 +60,7 @@ const getAllFieldsWithValue = ( return acc; }, {}); -const useComputeDataFromEvent = (dataElements: Array, events: Array) => { +const useComputeDataFromEvent = (dataElements: Array, events: Array) => { const [value, setValue] = useState(null); const [error, setError] = useState(null); const [loading, setLoading] = useState(true); @@ -133,42 +133,40 @@ const useComputeHeaderColumn = (dataElements: Array, hideDueDa return headerColumns; }; -const getDataElement = (stageDataElement, type) => { +function getDataElement(stageDataElement: StageDataElementClient, type) { if (!stageDataElement) { return null; } - const dataElement = new DataElement((o) => { o.id = stageDataElement.id; o.type = type; }); if (stageDataElement.options) { - const options = Object.keys(stageDataElement.options).map( - (code: string) => - new Option((o) => { - // $FlowFixMe - o.text = stageDataElement.options[code]; - o.value = code; - }), - ); + const options = stageDataElement.options.map(({ value, text }) => + new Option((o) => { + // $FlowFixMe + o.text = text; + o.value = value; + })); const optionSet = new OptionSet(stageDataElement.id, options); dataElement.optionSet = optionSet; } return dataElement; -}; +} -const formatRowForView = (row: Object, dataElements: Array) => Object.keys(row).reduce((acc, id) => { +const formatRowForView = (row: Object, dataElements: Array) => Object.keys(row).reduce((acc, id) => { const { type: predefinedType } = baseFields.find(f => f.id === id) || {}; const stageDataElement = dataElements.find(el => el.id === id); const { type } = stageDataElement || {}; const value = row[id]; if (predefinedType) { acc[id] = convertClientToList(value, predefinedType); - } else if (!type) { + } else if (!type || !stageDataElement) { acc[id] = value; } else { const dataElement = getDataElement(stageDataElement, type); + console.log('dataElement', dataElement); acc[id] = convertClientToList(value, type, dataElement); } return acc; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/types/common.types.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/types/common.types.js index cff6ac9938..24873d1721 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/types/common.types.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/types/common.types.js @@ -6,6 +6,7 @@ import { dataElementTypes, Option } from '../../../metaData'; type StageOptions = { [code: string]: string; } + export type StageDataElement = { id: string, name: string, @@ -15,6 +16,15 @@ export type StageDataElement = { optionSet?: { options: Array