From 9f695bff3b415c5a9e106b14a5b734421835479f Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Sun, 14 Apr 2024 22:27:30 +0300 Subject: [PATCH 01/11] Initial commit(will remove the date bug fix) --- src/components/inputs/date/date.component.tsx | 2 +- src/components/section/form-section.component.tsx | 3 ++- src/types.ts | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/inputs/date/date.component.tsx b/src/components/inputs/date/date.component.tsx index 3e59392d2..a8e0fdd7d 100644 --- a/src/components/inputs/date/date.component.tsx +++ b/src/components/inputs/date/date.component.tsx @@ -110,7 +110,7 @@ const DateField: React.FC = ({ question, onChange, handler, prev }, []); useEffect(() => { - if (encounterContext?.previousEncounter && !isTrue(question.questionOptions.usePreviousValueDisabled)) { + if (encounterContext?.previousEncounter && !isTrue(question.questionOptions.enablePreviousValue)) { let prevValue = handler?.getPreviousValue(question, encounterContext?.previousEncounter, fields); if (!isEmpty(prevValue?.value)) { diff --git a/src/components/section/form-section.component.tsx b/src/components/section/form-section.component.tsx index ca5f6de2f..d7c53eec3 100644 --- a/src/components/section/form-section.component.tsx +++ b/src/components/section/form-section.component.tsx @@ -95,7 +95,8 @@ const FormSection = ({ fields, onFieldChange }) => { {encounterContext?.previousEncounter && previousFieldValue && - !isTrue(fieldDescriptor.questionOptions.usePreviousValueDisabled) && ( + (isTrue(fieldDescriptor.questionOptions.enablePreviousValue) || + fieldDescriptor.historicalExpression) && (
>; behaviours?: Array>; questionInfo?: string; + historicalExpression?: string; constrainMaxWidth?: boolean; meta?: { concept?: OpenmrsResource; @@ -199,7 +200,7 @@ export interface FormQuestionOptions { calculateExpression: string; }; isDateTime?: { labelTrue: boolean; labelFalse: boolean }; - usePreviousValueDisabled?: boolean; + enablePreviousValue?: boolean; allowedFileTypes?: Array; allowMultiple?: boolean; datasource?: { name: string; config?: Record }; From 0ddccb88f928732c3e2e51b800cf550f909b42d5 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Mon, 15 Apr 2024 15:32:07 +0300 Subject: [PATCH 02/11] cleanup --- src/components/inputs/date/date.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/inputs/date/date.component.tsx b/src/components/inputs/date/date.component.tsx index a8e0fdd7d..ea0fdcb87 100644 --- a/src/components/inputs/date/date.component.tsx +++ b/src/components/inputs/date/date.component.tsx @@ -110,7 +110,7 @@ const DateField: React.FC = ({ question, onChange, handler, prev }, []); useEffect(() => { - if (encounterContext?.previousEncounter && !isTrue(question.questionOptions.enablePreviousValue)) { + if (encounterContext?.previousEncounter && isTrue(question.questionOptions.enablePreviousValue)) { let prevValue = handler?.getPreviousValue(question, encounterContext?.previousEncounter, fields); if (!isEmpty(prevValue?.value)) { From 7ba63f5468b7dfbadeadd8d1d3a586f64c34ef69 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Wed, 24 Apr 2024 01:18:52 +0300 Subject: [PATCH 03/11] Getting the HD object to evaluate tt t --- .../section/form-section.component.tsx | 24 ++++++++++++ src/utils/common-expression-helpers.ts | 16 ++++++++ src/utils/expression-runner.ts | 38 +++++++++++++++++-- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/components/section/form-section.component.tsx b/src/components/section/form-section.component.tsx index d7c53eec3..e21d2c180 100644 --- a/src/components/section/form-section.component.tsx +++ b/src/components/section/form-section.component.tsx @@ -8,11 +8,15 @@ import { getRegisteredFieldSubmissionHandler } from '../../registry/registry'; import { formatPreviousValueDisplayText, getFieldControlWithFallback, isUnspecifiedSupported } from './helpers'; import { PreviousValueReview } from '../previous-value-review/previous-value-review.component'; import { isTrue } from '../../utils/boolean-utils'; +<<<<<<< HEAD:src/components/section/form-section.component.tsx import { UnspecifiedField } from '../inputs/unspecified/unspecified.component'; import { FormField, FormFieldProps, previousValue, SubmissionHandler } from '../../types'; import { FormContext } from '../../form-context'; import { Tooltip } from '../inputs/tooltip/tooltip.component'; import styles from './form-section.scss'; +======= +import { evaluateExpression, HD } from '../../utils/expression-runner'; +>>>>>>> e1fe9dd (Getting the HD object to evaluate):src/components/section/ohri-form-section.component.tsx interface FieldComponentMap { fieldComponent: React.ComponentType; @@ -44,7 +48,27 @@ const FormSection = ({ fields, onFieldChange }) => { .filter((entry) => entry?.fieldComponent) .map((entry, index) => { const { fieldComponent: FieldComponent, fieldDescriptor, handler } = entry; +<<<<<<< HEAD:src/components/section/form-section.component.tsx const rendering = fieldDescriptor.questionOptions.rendering; +======= + + if (fieldDescriptor.historicalExpression) { + const historicalValue = evaluateExpression( + fieldDescriptor.historicalExpression, + { value: fieldDescriptor, type: 'field' }, + fieldsFromEncounter, + encounterContext.initValues, + { + mode: encounterContext.sessionMode, + patient: encounterContext.patient, + previousEncounter: encounterContext.previousEncounter, + }, + ); + + console.log(historicalValue); + } + +>>>>>>> e1fe9dd (Getting the HD object to evaluate):src/components/section/ohri-form-section.component.tsx const previousFieldValue = encounterContext.previousEncounter ? handler?.getPreviousValue(fieldDescriptor, encounterContext.previousEncounter, fieldsFromEncounter) : null; diff --git a/src/utils/common-expression-helpers.ts b/src/utils/common-expression-helpers.ts index 8f4a9e81d..02ac1b408 100644 --- a/src/utils/common-expression-helpers.ts +++ b/src/utils/common-expression-helpers.ts @@ -445,7 +445,23 @@ export class CommonExpressionHelpers { }; } +<<<<<<< HEAD export function registerDependency(node: FormNode, determinant: FormField) { +======= +export class HistoricalDataSourceService { + dataSourceMap: Record = {}; + + putObject(key: string, value: any) { + this.dataSourceMap[key] = value; + } + + getObject(key: string) { + return this.dataSourceMap[key]; + } +} + +export function registerDependency(node: FormNode, determinant: OHRIFormField) { +>>>>>>> e1fe9dd (Getting the HD object to evaluate) if (!node || !determinant) { return; } diff --git a/src/utils/expression-runner.ts b/src/utils/expression-runner.ts index bfb43acf9..3a9dfc61f 100644 --- a/src/utils/expression-runner.ts +++ b/src/utils/expression-runner.ts @@ -1,7 +1,14 @@ +<<<<<<< HEAD import { getRegisteredExpressionHelpers } from '../registry/registry'; import { FormField, FormPage, FormSection } from '../types'; import { CommonExpressionHelpers } from './common-expression-helpers'; +======= +import { OHRIFormField, OHRIFormPage, OHRIFormSection, OpenmrsEncounter } from '../api/types'; +import { getRegisteredExpressionHelpers } from '../registry/registry'; +import { CommonExpressionHelpers, HistoricalDataSourceService } from './common-expression-helpers'; +>>>>>>> e1fe9dd (Getting the HD object to evaluate) import { findAndRegisterReferencedFields, linkReferencedFieldValues, parseExpression } from './expression-parser'; +import { EncounterContext } from '../ohri-form-context'; export interface FormNode { value: FormPage | FormSection | FormField; @@ -12,8 +19,11 @@ export interface ExpressionContext { mode: 'enter' | 'edit' | 'view' | 'embedded-view'; myValue?: any; patient: any; + previousEncounter?: OpenmrsEncounter; } +export const HD = new HistoricalDataSourceService(); + export function evaluateExpression( expression: string, node: FormNode, @@ -24,6 +34,9 @@ export function evaluateExpression( if (!expression?.trim()) { return null; } + + console.log(context.previousEncounter); + const allFieldsKeys = fields.map((f) => f.id); const parts = parseExpression(expression.trim()); // register dependencies @@ -32,10 +45,19 @@ export function evaluateExpression( let { myValue, patient } = context; const { sex, age } = patient && 'sex' in patient && 'age' in patient ? patient : { sex: undefined, age: undefined }; - if (node.type === 'field' && myValue === undefined) { + if (node.type === 'field' && myValue === undefined && node.value) { myValue = fieldValues[node.value['id']]; } + const HD = new HistoricalDataSourceService(); + + HD.putObject('prevEnc', { + value: context.previousEncounter, + getValue(concept) { + return this.value.obs.find((obs) => obs.concept.uuid == concept)?.value; + }, + }); + const expressionContext = { ...new CommonExpressionHelpers(node, patient, fields, fieldValues, allFieldsKeys), ...getRegisteredExpressionHelpers(), @@ -45,6 +67,7 @@ export function evaluateExpression( myValue, sex, age, + HD, }; expression = linkReferencedFieldValues(fields, fieldValues, parts); @@ -67,10 +90,15 @@ export async function evaluateAsyncExpression( if (!expression?.trim()) { return null; } - const allFieldsKeys = fields.map((f) => f.id); - let parts = parseExpression(expression.trim()); + + const allFieldsKeys = fields.map((f) => f.id); //extract ids from the fields + let parts = parseExpression(expression.trim()); //takes the trimmed expression and returns "tokens", whatever that means + // tokens are kinda like broken down pieces of the expression... + // console.log(parts); + // register dependencies - findAndRegisterReferencedFields(node, parts, fields); + findAndRegisterReferencedFields(node, parts, fields); //what does this do???? + //adds values to the determinants // setup function scope let { myValue, patient } = context; @@ -91,6 +119,8 @@ export async function evaluateAsyncExpression( temporaryObjectsMap: {}, }; + // console.log(new CommonExpressionHelpers(node, patient, fields, fieldValues, allFieldsKeys)); + expression = linkReferencedFieldValues(fields, fieldValues, parts); // parts with resolve-able field references From 057eeb6413f44f396d399886ce5313a62d89295c Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:42:43 +0300 Subject: [PATCH 04/11] aligning Hxp with previous value --- .../section/form-section.component.tsx | 80 +++++++++++++------ src/components/section/helpers.ts | 2 +- src/utils/common-expression-helpers.ts | 7 +- src/utils/expression-runner.ts | 21 +---- 4 files changed, 61 insertions(+), 49 deletions(-) diff --git a/src/components/section/form-section.component.tsx b/src/components/section/form-section.component.tsx index e21d2c180..b2bcdcfd1 100644 --- a/src/components/section/form-section.component.tsx +++ b/src/components/section/form-section.component.tsx @@ -8,15 +8,14 @@ import { getRegisteredFieldSubmissionHandler } from '../../registry/registry'; import { formatPreviousValueDisplayText, getFieldControlWithFallback, isUnspecifiedSupported } from './helpers'; import { PreviousValueReview } from '../previous-value-review/previous-value-review.component'; import { isTrue } from '../../utils/boolean-utils'; -<<<<<<< HEAD:src/components/section/form-section.component.tsx import { UnspecifiedField } from '../inputs/unspecified/unspecified.component'; import { FormField, FormFieldProps, previousValue, SubmissionHandler } from '../../types'; import { FormContext } from '../../form-context'; import { Tooltip } from '../inputs/tooltip/tooltip.component'; import styles from './form-section.scss'; -======= -import { evaluateExpression, HD } from '../../utils/expression-runner'; ->>>>>>> e1fe9dd (Getting the HD object to evaluate):src/components/section/ohri-form-section.component.tsx +import { evaluateExpression } from '../../utils/expression-runner'; +import dayjs from 'dayjs'; +import { parseToLocalDateTime } from '../../utils/form-helper'; interface FieldComponentMap { fieldComponent: React.ComponentType; @@ -24,6 +23,35 @@ interface FieldComponentMap { handler: SubmissionHandler; } +const historicalValueTransformer = (field, obs) => { + const rendering = field.questionOptions.rendering; + if (typeof obs.value == 'string' || typeof obs.value == 'number') { + if (rendering == 'date' || rendering == 'datetime') { + const dateObj = parseToLocalDateTime(`${obs.value}`); + return { value: dateObj, display: dayjs(dateObj).format('YYYY-MM-DD HH:mm') }; + } + return { value: obs.value, display: obs.value }; + } + if (rendering == 'checkbox') { + return obs.map((each) => { + return { + value: each.value?.uuid, + display: each.value?.name?.name, + }; + }); + } + if (rendering == 'toggle') { + return { + value: obs.value?.uuid, + display: obs.value?.name?.name, + }; + } + return { + value: obs.value?.uuid, + display: field.questionOptions.answers?.find((option) => option.concept == obs.value?.uuid)?.label, + }; +}; + const FormSection = ({ fields, onFieldChange }) => { const [previousValues, setPreviousValues] = useState>({}); const [fieldComponentMapEntries, setFieldComponentMapEntries] = useState([]); @@ -48,31 +76,30 @@ const FormSection = ({ fields, onFieldChange }) => { .filter((entry) => entry?.fieldComponent) .map((entry, index) => { const { fieldComponent: FieldComponent, fieldDescriptor, handler } = entry; -<<<<<<< HEAD:src/components/section/form-section.component.tsx const rendering = fieldDescriptor.questionOptions.rendering; -======= - - if (fieldDescriptor.historicalExpression) { - const historicalValue = evaluateExpression( - fieldDescriptor.historicalExpression, - { value: fieldDescriptor, type: 'field' }, - fieldsFromEncounter, - encounterContext.initValues, - { - mode: encounterContext.sessionMode, - patient: encounterContext.patient, - previousEncounter: encounterContext.previousEncounter, - }, - ); - console.log(historicalValue); - } + const historicalValue = fieldDescriptor.historicalExpression + ? evaluateExpression( + fieldDescriptor.historicalExpression, + { value: fieldDescriptor, type: 'field' }, + fieldsFromEncounter, + encounterContext.initValues, + { + mode: encounterContext.sessionMode, + patient: encounterContext.patient, + previousEncounter: encounterContext.previousEncounter, + }, + ) + : null; ->>>>>>> e1fe9dd (Getting the HD object to evaluate):src/components/section/ohri-form-section.component.tsx const previousFieldValue = encounterContext.previousEncounter ? handler?.getPreviousValue(fieldDescriptor, encounterContext.previousEncounter, fieldsFromEncounter) : null; + const transformedHistoricalValue = historicalValue + ? historicalValueTransformer(fieldDescriptor, historicalValue) + : null; + if (FieldComponent) { const qnFragment = ( { )}
{encounterContext?.previousEncounter && - previousFieldValue && + (previousFieldValue || historicalValue) && (isTrue(fieldDescriptor.questionOptions.enablePreviousValue) || fieldDescriptor.historicalExpression) && (
diff --git a/src/components/section/helpers.ts b/src/components/section/helpers.ts index 06bace81f..39bb44e22 100644 --- a/src/components/section/helpers.ts +++ b/src/components/section/helpers.ts @@ -46,7 +46,7 @@ function previousValueDisplayForCheckbox(previosValueItems: Object[]): String { export const formatPreviousValueDisplayText = (question: FormField, value: any) => { switch (question.questionOptions.rendering) { case 'date': - return formatDate(new Date(value?.display)); + return formatDate(new Date(value?.value)); case 'checkbox': return Array.isArray(value) ? previousValueDisplayForCheckbox(value) : null; default: diff --git a/src/utils/common-expression-helpers.ts b/src/utils/common-expression-helpers.ts index 02ac1b408..e8706ff5e 100644 --- a/src/utils/common-expression-helpers.ts +++ b/src/utils/common-expression-helpers.ts @@ -444,10 +444,6 @@ export class CommonExpressionHelpers { return Promise.resolve(lazy); }; } - -<<<<<<< HEAD -export function registerDependency(node: FormNode, determinant: FormField) { -======= export class HistoricalDataSourceService { dataSourceMap: Record = {}; @@ -460,8 +456,7 @@ export class HistoricalDataSourceService { } } -export function registerDependency(node: FormNode, determinant: OHRIFormField) { ->>>>>>> e1fe9dd (Getting the HD object to evaluate) +export function registerDependency(node: FormNode, determinant: FormField) { if (!node || !determinant) { return; } diff --git a/src/utils/expression-runner.ts b/src/utils/expression-runner.ts index 3a9dfc61f..da2d28f24 100644 --- a/src/utils/expression-runner.ts +++ b/src/utils/expression-runner.ts @@ -1,14 +1,7 @@ -<<<<<<< HEAD -import { getRegisteredExpressionHelpers } from '../registry/registry'; -import { FormField, FormPage, FormSection } from '../types'; -import { CommonExpressionHelpers } from './common-expression-helpers'; -======= -import { OHRIFormField, OHRIFormPage, OHRIFormSection, OpenmrsEncounter } from '../api/types'; import { getRegisteredExpressionHelpers } from '../registry/registry'; +import { FormField, FormPage, FormSection, OpenmrsEncounter } from '../types'; import { CommonExpressionHelpers, HistoricalDataSourceService } from './common-expression-helpers'; ->>>>>>> e1fe9dd (Getting the HD object to evaluate) import { findAndRegisterReferencedFields, linkReferencedFieldValues, parseExpression } from './expression-parser'; -import { EncounterContext } from '../ohri-form-context'; export interface FormNode { value: FormPage | FormSection | FormField; @@ -35,8 +28,6 @@ export function evaluateExpression( return null; } - console.log(context.previousEncounter); - const allFieldsKeys = fields.map((f) => f.id); const parts = parseExpression(expression.trim()); // register dependencies @@ -54,7 +45,7 @@ export function evaluateExpression( HD.putObject('prevEnc', { value: context.previousEncounter, getValue(concept) { - return this.value.obs.find((obs) => obs.concept.uuid == concept)?.value; + return this.value.obs.find((obs) => obs.concept.uuid == concept); }, }); @@ -91,10 +82,8 @@ export async function evaluateAsyncExpression( return null; } - const allFieldsKeys = fields.map((f) => f.id); //extract ids from the fields - let parts = parseExpression(expression.trim()); //takes the trimmed expression and returns "tokens", whatever that means - // tokens are kinda like broken down pieces of the expression... - // console.log(parts); + const allFieldsKeys = fields.map((f) => f.id); + let parts = parseExpression(expression.trim()); // register dependencies findAndRegisterReferencedFields(node, parts, fields); //what does this do???? @@ -119,8 +108,6 @@ export async function evaluateAsyncExpression( temporaryObjectsMap: {}, }; - // console.log(new CommonExpressionHelpers(node, patient, fields, fieldValues, allFieldsKeys)); - expression = linkReferencedFieldValues(fields, fieldValues, parts); // parts with resolve-able field references From fefff75a454aafc901e06b8ec52459386628b7be Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Wed, 24 Apr 2024 19:10:41 +0300 Subject: [PATCH 05/11] more cleanup --- src/utils/expression-runner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/expression-runner.ts b/src/utils/expression-runner.ts index da2d28f24..7ba632442 100644 --- a/src/utils/expression-runner.ts +++ b/src/utils/expression-runner.ts @@ -86,7 +86,7 @@ export async function evaluateAsyncExpression( let parts = parseExpression(expression.trim()); // register dependencies - findAndRegisterReferencedFields(node, parts, fields); //what does this do???? + findAndRegisterReferencedFields(node, parts, fields); //adds values to the determinants // setup function scope From 275d38bb7872d54971b66356fd23b60021441ea1 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:32:41 +0300 Subject: [PATCH 06/11] resolving logic --- src/form-engine.component.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/form-engine.component.tsx b/src/form-engine.component.tsx index 5bf932b87..4cc9831fa 100644 --- a/src/form-engine.component.tsx +++ b/src/form-engine.component.tsx @@ -117,9 +117,7 @@ const FormEngine: React.FC = ({ }, [patient?.id, sessionMode, workspaceLayout]); const showButtonSet = useMemo(() => { - return ( - workspaceLayout === 'minimized' || ('maximized' && sessionMode != 'embedded-view' && scrollablePages.size <= 1) - ); + return sessionMode !== 'embedded-view' && workspaceLayout === 'minimized' && scrollablePages.size <= 1; }, [sessionMode, workspaceLayout, scrollablePages]); useEffect(() => { From 3002ee9f26e0463c55a13974351a592474c5b2d2 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:29:25 +0300 Subject: [PATCH 07/11] revamped transformer, migrated historical data source class --- .../section/form-section.component.tsx | 39 +++--------------- src/components/section/helpers.ts | 41 ++++++++++++++++++- src/utils/common-expression-helpers.ts | 20 ++------- src/utils/expression-runner.ts | 4 +- src/utils/historical-data-source.ts | 11 +++++ 5 files changed, 62 insertions(+), 53 deletions(-) create mode 100644 src/utils/historical-data-source.ts diff --git a/src/components/section/form-section.component.tsx b/src/components/section/form-section.component.tsx index 3b4dbdeb1..6745a493e 100644 --- a/src/components/section/form-section.component.tsx +++ b/src/components/section/form-section.component.tsx @@ -5,7 +5,12 @@ import { useField } from 'formik'; import type { FormField, FormFieldProps, previousValue, SubmissionHandler } from '../../types'; import { ErrorBoundary } from 'react-error-boundary'; import { ToastNotification } from '@carbon/react'; -import { formatPreviousValueDisplayText, getFieldControlWithFallback, isUnspecifiedSupported } from './helpers'; +import { + formatPreviousValueDisplayText, + getFieldControlWithFallback, + isUnspecifiedSupported, + historicalValueTransformer, +} from './helpers'; import { getRegisteredFieldSubmissionHandler } from '../../registry/registry'; import { isTrue } from '../../utils/boolean-utils'; import { FormContext } from '../../form-context'; @@ -14,44 +19,12 @@ import Tooltip from '../inputs/tooltip/tooltip.component'; import UnspecifiedField from '../inputs/unspecified/unspecified.component'; import styles from './form-section.scss'; import { evaluateExpression } from '../../utils/expression-runner'; -import dayjs from 'dayjs'; -import { parseToLocalDateTime } from '../../utils/form-helper'; - interface FieldComponentMap { fieldComponent: React.ComponentType; fieldDescriptor: FormField; handler: SubmissionHandler; } -const historicalValueTransformer = (field, obs) => { - const rendering = field.questionOptions.rendering; - if (typeof obs.value == 'string' || typeof obs.value == 'number') { - if (rendering == 'date' || rendering == 'datetime') { - const dateObj = parseToLocalDateTime(`${obs.value}`); - return { value: dateObj, display: dayjs(dateObj).format('YYYY-MM-DD HH:mm') }; - } - return { value: obs.value, display: obs.value }; - } - if (rendering == 'checkbox') { - return obs.map((each) => { - return { - value: each.value?.uuid, - display: each.value?.name?.name, - }; - }); - } - if (rendering == 'toggle') { - return { - value: obs.value?.uuid, - display: obs.value?.name?.name, - }; - } - return { - value: obs.value?.uuid, - display: field.questionOptions.answers?.find((option) => option.concept == obs.value?.uuid)?.label, - }; -}; - const FormSection = ({ fields, onFieldChange }) => { const [previousValues, setPreviousValues] = useState>({}); const [fieldComponentMapEntries, setFieldComponentMapEntries] = useState([]); diff --git a/src/components/section/helpers.ts b/src/components/section/helpers.ts index 93e1d55d0..3dbf505ab 100644 --- a/src/components/section/helpers.ts +++ b/src/components/section/helpers.ts @@ -1,7 +1,9 @@ import { formatDate } from '@openmrs/esm-framework'; import { getRegisteredControl } from '../../registry/registry'; import { isTrue } from '../../utils/boolean-utils'; -import { type FormField } from '../../types'; +import { type OpenmrsObs, type FormField } from '../../types'; +import { parseToLocalDateTime } from '../../utils/form-helper'; +import dayjs from 'dayjs'; /** * Retrieves the appropriate field control for a question, considering missing concepts. @@ -53,3 +55,40 @@ export const formatPreviousValueDisplayText = (question: FormField, value: any) return value?.display; } }; + +export const historicalValueTransformer = (field: FormField, obs: OpenmrsObs | OpenmrsObs[]) => { + const rendering = field.questionOptions.rendering; + + const transformObservation = (obs: OpenmrsObs, rendering: string) => { + if (typeof obs.value === 'string' || typeof obs.value === 'number') { + if (rendering === 'date' || rendering === 'datetime') { + const dateObj = parseToLocalDateTime(`${obs.value}`); + return { value: dateObj, display: dayjs(dateObj).format('YYYY-MM-DD HH:mm') }; + } + return { value: obs.value, display: obs.value }; + } else if (rendering === 'checkbox') { + return { + value: obs.value?.uuid, + display: obs.value?.name?.name, + }; + } else if (rendering === 'toggle') { + return { + value: obs.value?.uuid, + display: obs.value?.name?.name, + }; + } else { + return { + value: obs.value?.uuid, + display: field.questionOptions.answers?.find((option) => option.concept === obs.value?.uuid)?.label, + }; + } + }; + + if (Array.isArray(obs)) { + return obs.map((eachObs) => { + return transformObservation(eachObs, rendering); + }); + } else { + return transformObservation(obs, rendering); + } +}; diff --git a/src/utils/common-expression-helpers.ts b/src/utils/common-expression-helpers.ts index a5c48cc52..b6809d0f2 100644 --- a/src/utils/common-expression-helpers.ts +++ b/src/utils/common-expression-helpers.ts @@ -94,16 +94,13 @@ export class CommonExpressionHelpers { return null; }; - doesNotMatchExpression = ( - regexString: string, - val: string | null | undefined - ): boolean => { + doesNotMatchExpression = (regexString: string, val: string | null | undefined): boolean => { if (!val || ['undefined', 'null', ''].includes(val.toString())) { return true; } const pattern = new RegExp(regexString); - - return !pattern.test(val) + + return !pattern.test(val); }; calcBMI = (height: number, weight: number) => { @@ -456,17 +453,6 @@ export class CommonExpressionHelpers { return Promise.resolve(lazy); }; } -export class HistoricalDataSourceService { - dataSourceMap: Record = {}; - - putObject(key: string, value: any) { - this.dataSourceMap[key] = value; - } - - getObject(key: string) { - return this.dataSourceMap[key]; - } -} export function registerDependency(node: FormNode, determinant: FormField) { if (!node || !determinant) { diff --git a/src/utils/expression-runner.ts b/src/utils/expression-runner.ts index 7969e3278..8037ad3ee 100644 --- a/src/utils/expression-runner.ts +++ b/src/utils/expression-runner.ts @@ -1,7 +1,8 @@ import { getRegisteredExpressionHelpers } from '../registry/registry'; import { type OpenmrsEncounter, type FormField, type FormPage, type FormSection } from '../types'; -import { CommonExpressionHelpers, HistoricalDataSourceService } from './common-expression-helpers'; +import { CommonExpressionHelpers } from './common-expression-helpers'; import { findAndRegisterReferencedFields, linkReferencedFieldValues, parseExpression } from './expression-parser'; +import { HistoricalDataSourceService } from './historical-data-source'; export interface FormNode { value: FormPage | FormSection | FormField; @@ -87,7 +88,6 @@ export async function evaluateAsyncExpression( // register dependencies findAndRegisterReferencedFields(node, parts, fields); - //adds values to the determinants // setup function scope let { myValue, patient } = context; diff --git a/src/utils/historical-data-source.ts b/src/utils/historical-data-source.ts new file mode 100644 index 000000000..e0fd1d424 --- /dev/null +++ b/src/utils/historical-data-source.ts @@ -0,0 +1,11 @@ +export class HistoricalDataSourceService { + dataSourceMap: Record = {}; + + putObject(key: string, value: any) { + this.dataSourceMap[key] = value; + } + + getObject(key: string) { + return this.dataSourceMap[key]; + } +} From 34775a0c0be443a27721bc96deffa4b2043cd3ba Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Tue, 7 May 2024 22:44:49 +0300 Subject: [PATCH 08/11] combine hxp and previous value logic --- .../multi-select/multi-select.component.tsx | 17 ++++-- .../section/form-section.component.tsx | 15 ++---- src/components/section/helpers.ts | 52 ++++++++----------- 3 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/components/inputs/multi-select/multi-select.component.tsx b/src/components/inputs/multi-select/multi-select.component.tsx index ba3be01a3..5e489b1a3 100644 --- a/src/components/inputs/multi-select/multi-select.component.tsx +++ b/src/components/inputs/multi-select/multi-select.component.tsx @@ -58,11 +58,18 @@ const MultiSelect: React.FC = ({ question, onChange, handler, pr }; useEffect(() => { - if (!isEmpty(previousValue) && Array.isArray(previousValue)) { - const valuesToSet = previousValue.map((eachItem) => eachItem.value); - setFieldValue(question.id, valuesToSet); - onChange(question.id, valuesToSet, setErrors, setWarnings); - question.value = handler?.handleFieldSubmission(question, valuesToSet, encounterContext); + if (!isEmpty(previousValue)) { + if (Array.isArray(previousValue)) { + const valuesToSet = previousValue.map((eachItem) => eachItem.value); + setFieldValue(question.id, valuesToSet); + onChange(question.id, valuesToSet, setErrors, setWarnings); + question.value = handler?.handleFieldSubmission(question, valuesToSet, encounterContext); + } else { + const valueToSet = [previousValue.value]; + setFieldValue(question.id, valueToSet); + onChange(question.id, valueToSet, setErrors, setWarnings); + question.value = handler?.handleFieldSubmission(question, valueToSet, encounterContext); + } } }, [previousValue]); diff --git a/src/components/section/form-section.component.tsx b/src/components/section/form-section.component.tsx index 6a26f53be..2998fb801 100644 --- a/src/components/section/form-section.component.tsx +++ b/src/components/section/form-section.component.tsx @@ -67,12 +67,10 @@ const FormSection = ({ fields, onFieldChange }) => { ) : null; - const previousFieldValue = encounterContext.previousEncounter - ? handler?.getPreviousValue(fieldDescriptor, encounterContext.previousEncounter, fieldsFromEncounter) - : null; - - const transformedHistoricalValue = historicalValue + const previousFieldValue = historicalValue ? historicalValueTransformer(fieldDescriptor, historicalValue) + : encounterContext.previousEncounter + ? handler?.getPreviousValue(fieldDescriptor, encounterContext.previousEncounter, fieldsFromEncounter) : null; if (FieldComponent) { @@ -125,11 +123,8 @@ const FormSection = ({ fields, onFieldChange }) => { fieldDescriptor.historicalExpression) && (
diff --git a/src/components/section/helpers.ts b/src/components/section/helpers.ts index 9cbd14acf..5bc0a82ba 100644 --- a/src/components/section/helpers.ts +++ b/src/components/section/helpers.ts @@ -4,6 +4,8 @@ import { isTrue } from '../../utils/boolean-utils'; import { type OpenmrsObs, type FormField } from '../../types'; import { parseToLocalDateTime } from '../../utils/form-helper'; import dayjs from 'dayjs'; +import { format } from 'path'; +import { render } from '@testing-library/react'; /** * Retrieves the appropriate field control for a question, considering missing concepts. @@ -48,47 +50,35 @@ function previousValueDisplayForCheckbox(previosValueItems: Object[]): String { export const formatPreviousValueDisplayText = (question: FormField, value: any) => { switch (question.questionOptions.rendering) { case 'date': + if (value instanceof Date) { + return formatDate(value); + } return formatDate(new Date(value?.display)) || formatDate(value?.value); case 'checkbox': - return Array.isArray(value) ? previousValueDisplayForCheckbox(value) : null; + return Array.isArray(value) ? previousValueDisplayForCheckbox(value) : value.display; default: return value?.display; } }; -export const historicalValueTransformer = (field: FormField, obs: OpenmrsObs | OpenmrsObs[]) => { +export const historicalValueTransformer = (field: FormField, obs: OpenmrsObs) => { const rendering = field.questionOptions.rendering; - const transformObservation = (obs: OpenmrsObs, rendering: string) => { - if (typeof obs.value === 'string' || typeof obs.value === 'number') { - if (rendering === 'date' || rendering === 'datetime') { - const dateObj = parseToLocalDateTime(`${obs.value}`); - return { value: dateObj, display: dayjs(dateObj).format('YYYY-MM-DD HH:mm') }; - } - return { value: obs.value, display: obs.value }; - } else if (rendering === 'checkbox') { - return { - value: obs.value?.uuid, - display: obs.value?.name?.name, - }; - } else if (rendering === 'toggle') { - return { - value: obs.value?.uuid, - display: obs.value?.name?.name, - }; - } else { - return { - value: obs.value?.uuid, - display: field.questionOptions.answers?.find((option) => option.concept === obs.value?.uuid)?.label, - }; + if (typeof obs.value === 'string' || typeof obs.value === 'number') { + if (rendering === 'date' || rendering === 'datetime') { + const dateObj = parseToLocalDateTime(`${obs.value}`); + return { value: dateObj, display: dayjs(dateObj).format('YYYY-MM-DD HH:mm') }; } - }; - - if (Array.isArray(obs)) { - return obs.map((eachObs) => { - return transformObservation(eachObs, rendering); - }); + return { value: obs.value, display: obs.value }; + } else if (['toggle', 'checkbox'].includes(rendering)) { + return { + value: obs.value?.uuid, + display: obs.value?.name?.name, + }; } else { - return transformObservation(obs, rendering); + return { + value: obs.value?.uuid, + display: field.questionOptions.answers?.find((option) => option.concept === obs.value?.uuid)?.label, + }; } }; From a9ca72592e42b94926d52d331d4b083852958311 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Wed, 8 May 2024 22:06:32 +0300 Subject: [PATCH 09/11] Added tests --- .../historical-expressions-form.json | 170 ++++++++++++++++++ .../mockHistoricalvisitsEncounter.json | 89 +++++++++ src/form-engine.test.tsx | 25 ++- 3 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 __mocks__/forms/rfe-forms/historical-expressions-form.json create mode 100644 __mocks__/forms/rfe-forms/mockHistoricalvisitsEncounter.json diff --git a/__mocks__/forms/rfe-forms/historical-expressions-form.json b/__mocks__/forms/rfe-forms/historical-expressions-form.json new file mode 100644 index 000000000..dd78c3d92 --- /dev/null +++ b/__mocks__/forms/rfe-forms/historical-expressions-form.json @@ -0,0 +1,170 @@ +{ + "name": "COVID Assessment Form", + "version": "1", + "published": true, + "retired": false, + "pages": [ + { + "label": "COVID Assessment", + "sections": [ + { + "label": "Assessment Details", + "isExpanded": "true", + "questions": [ + { + "label": "Reasons for assessment", + "type": "obs", + "historicalExpression": "HD.getObject('prevEnc').getValue('ae46f4b1-c15d-4bba-ab41-b9157b82b0ce')", + "questionOptions": { + "rendering": "checkbox", + "concept": "ae46f4b1-c15d-4bba-ab41-b9157b82b0ce", + "answers": [ + { + "concept": "1068AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "label": "Symptomatic", + "conceptMappings": [ + { + "type": "AMPATH", + "value": "1068" + }, + { + "type": "SNOMED-CT", + "value": "264931009" + } + ] + }, + { + "concept": "0ed2e3ca-b9a6-4ff6-ac74-4d4cd9520acc", + "label": "RDT confirmatory", + "conceptMappings": [] + }, + { + "concept": "f974e267-feeb-42be-9d37-61554dad16b1", + "label": "Voluntary", + "conceptMappings": [] + }, + { + "concept": "1cee0ab3-bf06-49e9-a49c-baf261620c67", + "label": "Post-mortem", + "conceptMappings": [] + }, + { + "concept": "e0f1584a-cc8b-48e9-980f-64d9f724caf8", + "label": "Quarantine", + "conceptMappings": [] + }, + { + "concept": "ad8be6bf-ced7-4390-a6af-c5acebeac216", + "label": "Follow-up", + "conceptMappings": [] + }, + { + "concept": "30320fb8-b29b-443f-98cf-f3ef491f8947", + "label": "Health worker", + "conceptMappings": [] + }, + { + "concept": "38769c82-a3d3-4714-97b7-015726cdb209", + "label": "Other frontline worker", + "conceptMappings": [] + }, + { + "concept": "f8c9c2cc-3070-444e-8818-26fb8100bb78", + "label": "Travel out of country", + "conceptMappings": [] + }, + { + "concept": "677f4d21-7293-4810-abe6-57a192acde57", + "label": "Entry into a country", + "conceptMappings": [] + }, + { + "concept": "8a6ab892-1b1d-4ad9-82da-c6c38ee8fcfb", + "label": "Surveillance", + "conceptMappings": [] + }, + { + "concept": "5340f478-ec5d-41e6-bc62-961c52014d4d", + "label": "Contact of a case", + "conceptMappings": [] + }, + { + "concept": "5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "label": "Other", + "conceptMappings": [ + { + "type": "PIH-Malawi", + "value": "6408" + }, + { + "type": "org.openmrs.module.mdrtb", + "value": "OTHER" + }, + { + "type": "CIEL", + "value": "5622" + }, + { + "type": "SNOMED-MVP", + "value": "56221000105001" + }, + { + "type": "PIH", + "value": "5622" + }, + { + "type": "AMPATH", + "value": "5622" + }, + { + "type": "SNOMED-CT", + "value": "74964007" + } + ] + } + ] + }, + "id": "reasonsForTesting", + "behaviours": [ + { + "intent": "*", + "required": "true", + "unspecified": "true", + "hide": { + "hideWhenExpression": "false" + }, + "validators": [] + }, + { + "intent": "COVID_LAB_ASSESSMENT_EMBED", + "required": "true", + "unspecified": "true", + "hide": { + "hideWhenExpression": "false" + }, + "validators": [] + } + ] + } + ] + } + ] + } + ], + "availableIntents": [ + { + "intent": "*", + "display": "COVID Assessment" + }, + { + "intent": "COVID_LAB_ASSESSMENT_EMBED", + "display": "Covid Case Form" + } + ], + "processor": "EncounterFormProcessor", + "uuid": "f5fb6bc4-6fc3-3462-a191-2fff0896bab3", + "referencedForms": [], + "encounterType": "253a43d3-c99e-415c-8b78-ee7d4d3c1d54", + "encounter": "COVID Case Assessment", + "allowUnspecifiedAll": true +} diff --git a/__mocks__/forms/rfe-forms/mockHistoricalvisitsEncounter.json b/__mocks__/forms/rfe-forms/mockHistoricalvisitsEncounter.json new file mode 100644 index 000000000..9294d935a --- /dev/null +++ b/__mocks__/forms/rfe-forms/mockHistoricalvisitsEncounter.json @@ -0,0 +1,89 @@ +{ + "uuid": "82649039-540d-45e8-b935-2edf3ac68449", + "encounterDatetime": "2024-05-01T09:34:18.000+0000", + "encounterType": { + "uuid": "253a43d3-c99e-415c-8b78-ee7d4d3c1d54", + "display": "COVID Case Assessment", + "name": "COVID Case Assessment", + "description": "This encounter type is shared across the COVID Assessment Form/COVID Outcome Form and COVID Lab Result Form", + "retired": false, + "links": [ + { + "rel": "self", + "uri": "https://ohri-dev.globalhealthapp.net/openmrs/ws/rest/v1/encountertype/253a43d3-c99e-415c-8b78-ee7d4d3c1d54", + "resourceAlias": "encountertype" + }, + { + "rel": "full", + "uri": "https://ohri-dev.globalhealthapp.net/openmrs/ws/rest/v1/encountertype/253a43d3-c99e-415c-8b78-ee7d4d3c1d54?v=full", + "resourceAlias": "encountertype" + } + ], + "resourceVersion": "1.8" + }, + "location": { + "uuid": "28066518-a0e5-4331-b23e-7b40f96d733a", + "name": "MCH Clinic" + }, + "patient": { + "uuid": "b280078a-c0ce-443b-9997-3c66c63ec2f8", + "display": "100000Y - John Doe" + }, + "encounterProviders": [ + { + "uuid": "72d1879e-f949-48ba-bdbe-9ea157ab5c20", + "provider": { + "uuid": "bc450226-4138-40b7-ad88-9c98df687738", + "name": "Super User" + } + } + ], + "orders": [], + "obs": [ + { + "uuid": "810d08df-9e14-494c-9c02-eada18af90ed", + "obsDatetime": "2024-05-01T09:34:18.000+0000", + "voided": false, + "groupMembers": null, + "formFieldNamespace": "rfe-forms", + "formFieldPath": "rfe-forms-dateOfAssessment", + "concept": { + "uuid": "160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "name": { + "uuid": "f415bf25-2008-3ac2-8f0e-46e75648e30d", + "name": "Date of event" + } + }, + "value": "2024-01-08T00:00:00.000+0000" + }, + { + "uuid": "f03bc18e-b4bc-432c-bffc-47daff58892b", + "obsDatetime": "2024-05-01T09:34:18.000+0000", + "voided": false, + "groupMembers": null, + "formFieldNamespace": "rfe-forms", + "formFieldPath": "rfe-forms-reasonsForTesting", + "concept": { + "uuid": "ae46f4b1-c15d-4bba-ab41-b9157b82b0ce", + "name": { + "uuid": "8b31f49b-04cf-3c31-b9da-149f262aa7b6", + "name": "What is the reason for COVID-19 testing?" + } + }, + "value": { + "uuid": "677f4d21-7293-4810-abe6-57a192acde57", + "name": { + "uuid": "3f3b2df5-fe22-3833-b2e9-22368c88f6de", + "name": "Entry into a country" + }, + "names": [ + { + "uuid": "3f3b2df5-fe22-3833-b2e9-22368c88f6de", + "conceptNameType": "FULLY_SPECIFIED", + "name": "Entry into a country" + } + ] + } + } + ] +} diff --git a/src/form-engine.test.tsx b/src/form-engine.test.tsx index 2e172f522..326616722 100644 --- a/src/form-engine.test.tsx +++ b/src/form-engine.test.tsx @@ -29,6 +29,8 @@ import referenceByMappingForm from '__mocks__/forms/rfe-forms/reference-by-mappi import sampleFieldsForm from '__mocks__/forms/rfe-forms/sample_fields.json'; import testEnrolmentForm from '__mocks__/forms/rfe-forms/test-enrolment-form.json'; import viralLoadStatusForm from '__mocks__/forms/rfe-forms/viral-load-status-form.json'; +import historicalExpressionsForm from '__mocks__/forms/rfe-forms/historical-expressions-form.json'; +import mockHxpEncounter from '__mocks__/forms/rfe-forms/mockHistoricalvisitsEncounter.json'; import FormEngine from './form-engine.component'; const mockShowToast = showToast as jest.Mock; @@ -65,7 +67,7 @@ jest.mock('../src/api/api', () => { return { ...originalModule, - getPreviousEncounter: jest.fn().mockImplementation(() => Promise.resolve(null)), + getPreviousEncounter: jest.fn().mockImplementation(() => Promise.resolve(mockHxpEncounter)), getConcept: jest.fn().mockImplementation(() => Promise.resolve(null)), getLatestObs: jest.fn().mockImplementation(() => Promise.resolve({ valueNumeric: 60 })), saveEncounter: jest.fn(), @@ -152,6 +154,27 @@ describe('Form engine component', () => { }); }); + describe('historical expressions', () => { + it('should ascertain getPreviousEncounter() returns an encounter and the historical expression displays on the UI', async () => { + const user = userEvent.setup(); + + renderForm(null, historicalExpressionsForm, 'COVID Assessment'); + + //ascertain form has rendered + await screen.findByRole('combobox', { name: /Reasons for assessment/i }); + + //ascertain function fetching the encounter has been called + expect(api.getPreviousEncounter).toHaveBeenCalled(); + expect(api.getPreviousEncounter).toHaveReturnedWith(Promise.resolve(mockHxpEncounter)); + + const reuseValueButton = screen.getByRole('button', { name: /reuse value/i }); + const evaluatedHistoricalValue = screen.getByText(/Entry into a country/i); + + expect(reuseValueButton).toBeInTheDocument; + expect(evaluatedHistoricalValue).toBeInTheDocument; + }); + }); + describe('Form submission', () => { it('should validate form submission', async () => { const saveEncounterMock = jest.spyOn(api, 'saveEncounter'); From adc92b7796e0d85dfe2563392e9b45de8cf3ad20 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Thu, 9 May 2024 21:10:37 +0300 Subject: [PATCH 10/11] PR resolutions --- .../multi-select/multi-select.component.tsx | 17 ++++++----------- .../section/form-section.component.tsx | 5 +++-- src/components/section/helpers.ts | 4 +--- .../historical-data-source.ts | 0 src/utils/expression-runner.ts | 2 +- 5 files changed, 11 insertions(+), 17 deletions(-) rename src/{utils => datasources}/historical-data-source.ts (100%) diff --git a/src/components/inputs/multi-select/multi-select.component.tsx b/src/components/inputs/multi-select/multi-select.component.tsx index 20a6d9164..54e2c56fa 100644 --- a/src/components/inputs/multi-select/multi-select.component.tsx +++ b/src/components/inputs/multi-select/multi-select.component.tsx @@ -58,17 +58,12 @@ const MultiSelect: React.FC = ({ question, onChange, handler, pr useEffect(() => { if (!isEmpty(previousValue)) { - if (Array.isArray(previousValue)) { - const valuesToSet = previousValue.map((eachItem) => eachItem.value); - setFieldValue(question.id, valuesToSet); - onChange(question.id, valuesToSet, setErrors, setWarnings); - question.value = handler?.handleFieldSubmission(question, valuesToSet, encounterContext); - } else { - const valueToSet = [previousValue.value]; - setFieldValue(question.id, valueToSet); - onChange(question.id, valueToSet, setErrors, setWarnings); - question.value = handler?.handleFieldSubmission(question, valueToSet, encounterContext); - } + const previousValues = Array.isArray(previousValue) + ? previousValue.map((item) => item.value) + : [previousValue.value]; + setFieldValue(question.id, previousValues); + onChange(question.id, previousValues, setErrors, setWarnings); + question.value = handler?.handleFieldSubmission(question, previousValues, encounterContext); } }, [previousValue]); diff --git a/src/components/section/form-section.component.tsx b/src/components/section/form-section.component.tsx index 2998fb801..ac2bf5af7 100644 --- a/src/components/section/form-section.component.tsx +++ b/src/components/section/form-section.component.tsx @@ -9,7 +9,7 @@ import { formatPreviousValueDisplayText, getFieldControlWithFallback, isUnspecifiedSupported, - historicalValueTransformer, + extractObsValueAndDisplay, } from './helpers'; import { getRegisteredFieldSubmissionHandler } from '../../registry/registry'; import { isTrue } from '../../utils/boolean-utils'; @@ -19,6 +19,7 @@ import Tooltip from '../inputs/tooltip/tooltip.component'; import UnspecifiedField from '../inputs/unspecified/unspecified.component'; import styles from './form-section.scss'; import { evaluateExpression } from '../../utils/expression-runner'; + interface FieldComponentMap { fieldComponent: React.ComponentType; fieldDescriptor: FormField; @@ -68,7 +69,7 @@ const FormSection = ({ fields, onFieldChange }) => { : null; const previousFieldValue = historicalValue - ? historicalValueTransformer(fieldDescriptor, historicalValue) + ? extractObsValueAndDisplay(fieldDescriptor, historicalValue) : encounterContext.previousEncounter ? handler?.getPreviousValue(fieldDescriptor, encounterContext.previousEncounter, fieldsFromEncounter) : null; diff --git a/src/components/section/helpers.ts b/src/components/section/helpers.ts index 5bc0a82ba..6cf56b8dc 100644 --- a/src/components/section/helpers.ts +++ b/src/components/section/helpers.ts @@ -4,8 +4,6 @@ import { isTrue } from '../../utils/boolean-utils'; import { type OpenmrsObs, type FormField } from '../../types'; import { parseToLocalDateTime } from '../../utils/form-helper'; import dayjs from 'dayjs'; -import { format } from 'path'; -import { render } from '@testing-library/react'; /** * Retrieves the appropriate field control for a question, considering missing concepts. @@ -61,7 +59,7 @@ export const formatPreviousValueDisplayText = (question: FormField, value: any) } }; -export const historicalValueTransformer = (field: FormField, obs: OpenmrsObs) => { +export const extractObsValueAndDisplay = (field: FormField, obs: OpenmrsObs) => { const rendering = field.questionOptions.rendering; if (typeof obs.value === 'string' || typeof obs.value === 'number') { diff --git a/src/utils/historical-data-source.ts b/src/datasources/historical-data-source.ts similarity index 100% rename from src/utils/historical-data-source.ts rename to src/datasources/historical-data-source.ts diff --git a/src/utils/expression-runner.ts b/src/utils/expression-runner.ts index 8037ad3ee..80a27cfdd 100644 --- a/src/utils/expression-runner.ts +++ b/src/utils/expression-runner.ts @@ -2,7 +2,7 @@ import { getRegisteredExpressionHelpers } from '../registry/registry'; import { type OpenmrsEncounter, type FormField, type FormPage, type FormSection } from '../types'; import { CommonExpressionHelpers } from './common-expression-helpers'; import { findAndRegisterReferencedFields, linkReferencedFieldValues, parseExpression } from './expression-parser'; -import { HistoricalDataSourceService } from './historical-data-source'; +import { HistoricalDataSourceService } from '../datasources/historical-data-source'; export interface FormNode { value: FormPage | FormSection | FormField; From acee9396da1e38d1e5683cc57688a3ac35d888d1 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Thu, 9 May 2024 21:15:36 +0300 Subject: [PATCH 11/11] Fix CI build failure --- src/form-engine.test.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/form-engine.test.tsx b/src/form-engine.test.tsx index bfb899ed5..326616722 100644 --- a/src/form-engine.test.tsx +++ b/src/form-engine.test.tsx @@ -31,8 +31,6 @@ import testEnrolmentForm from '__mocks__/forms/rfe-forms/test-enrolment-form.jso import viralLoadStatusForm from '__mocks__/forms/rfe-forms/viral-load-status-form.json'; import historicalExpressionsForm from '__mocks__/forms/rfe-forms/historical-expressions-form.json'; import mockHxpEncounter from '__mocks__/forms/rfe-forms/mockHistoricalvisitsEncounter.json'; -import requiredTestForm from '__mocks__/forms/rfe-forms/required-form.json'; -import conditionalRequiredTestForm from '__mocks__/forms/rfe-forms/conditional-required-form.json'; import FormEngine from './form-engine.component'; const mockShowToast = showToast as jest.Mock;