Skip to content

Commit d491967

Browse files
janadhJanardhan Vignarajan
andauthored
- Fixing Missing calculatedExpression animations Fixes aehrc#1643 (aehrc#1776)
* - Fixing Missing calculatedExpression animations Fixes aehrc#1643 Test with below Questionnaire { "resourceType": "Questionnaire", "id": "AssemblyInstructions", "meta": { "profile": [] }, "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/variable", "valueExpression": { "name": "heightValue", "language": "text/fhirpath", "expression": "%resource.descendants().where(linkId='heightValue').answer.valueDecimal" } }, { "url": "http://hl7.org/fhir/StructureDefinition/variable", "valueExpression": { "name": "mxValueDisplay", "language": "text/fhirpath", "expression": "%resource.descendants().where(linkId='medical-history-condition1').answer.valueCoding.display" } }, { "url": "http://hl7.org/fhir/StructureDefinition/variable", "valueExpression": { "name": "mxValue", "language": "text/fhirpath", "expression": "%resource.descendants().where(linkId='medical-history-condition1').answer.valueCoding" } }, { "url": "http://hl7.org/fhir/StructureDefinition/variable", "valueExpression": { "name": "dob", "language": "text/fhirpath", "expression": "%resource.descendants().where(linkId='dob1').answer.value" } } ], "contained": [ { "resourceType": "ValueSet", "id": "MedicalHistory", "url": "https://smartforms.csiro.au/ig/ValueSet/MedicalHistory", "name": "MedicalHistory", "title": "Medical History", "status": "draft", "experimental": false, "description": "The Medical History value set includes values that may be used to represent medical history, operations and hospital admissions.", "compose": { "include": [ { "system": "http://snomed.info/sct", "filter": [ { "property": "constraint", "op": "=", "value": "^32570581000036105|Problem/Diagnosis reference set| OR ^32570141000036105|Procedure foundation reference set|" } ] } ] } }, { "resourceType": "ValueSet", "id": "MedicalHistory2", "url": "https://smartforms.csiro.au/ig/ValueSet/MedicalHistory", "name": "MedicalHistory", "title": "Medical History", "status": "draft", "experimental": false, "description": "The Medical History value set includes values that may be used to represent medical history, operations and hospital admissions.", "compose": { "include": [ { "system": "http://snomed.info/sct", "filter": [ { "property": "constraint", "op": "=", "value": "^32570581000036105|Problem/Diagnosis reference set| OR ^32570141000036105|Procedure foundation reference set|" } ] } ] } } ], "url": "http://www.health.gov.au/assessments/mbs/715", "version": "0.3.0-assembled", "name": "AboriginalTorresStraitIslanderHealthCheck", "title": "Aboriginal and Torres Strait Islander Health Check", "status": "draft", "experimental": false, "subjectType": [ "Patient" ], "date": "2025-03-14", "publisher": "AEHRC CSIRO", "contact": [ { "name": "AEHRC CSIRO", "telecom": [ { "system": "url", "value": "https://confluence.csiro.au/display/PCDQFPhase2/Primary+Care+Data+Quality+Foundations+-+Phase+2" } ] } ], "jurisdiction": [ { "coding": [ { "system": "urn:iso:std:iso:3166", "code": "AU", "display": "Australia" } ] } ], "copyright": "Copyright © 2022+ Australian Government Department of Health and Aged Care - All rights reserved.\nThis content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.\nSee https://creativecommons.org/licenses/by-sa/4.0/.\n", "item": [ { "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/entryFormat", "valueString": "Height" } ], "linkId": "heightValue", "text": "Height (Change Here)", "type": "decimal", "required": true, "item": [ { "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl", "valueCodeableConcept": { "coding": [ { "system": "http://hl7.org/fhir/questionnaire-item-control", "code": "unit" } ] } } ], "linkId": "bmi-height-unit1", "text": "m", "type": "display" } ] }, { "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/entryFormat", "valueString": "Height" }, { "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression", "valueExpression": { "language": "text/fhirpath", "expression": "iif(exists(%heightValue), %heightValue, 0.0)" } } ], "linkId": "bmi-height-decimal", "text": "Height Calc Expr Animation", "type": "decimal", "required": true, "item": [ { "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl", "valueCodeableConcept": { "coding": [ { "system": "http://hl7.org/fhir/questionnaire-item-control", "code": "unit" } ] } } ], "linkId": "bmi-height-unit", "text": "m", "type": "display" } ] }, { "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl", "valueCodeableConcept": { "coding": [ { "system": "http://hl7.org/fhir/questionnaire-item-control", "code": "autocomplete" } ] } } ], "linkId": "medical-history-condition1", "text": "Medical History Condition (Change Here)", "type": "open-choice", "answerValueSet": "#MedicalHistory" }, { "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl", "valueCodeableConcept": { "coding": [ { "system": "http://hl7.org/fhir/questionnaire-item-control", "code": "autocomplete" } ] } }, { "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression", "valueExpression": { "language": "text/fhirpath", "expression": "%resource.descendants().where(linkId='medical-history-condition1').answer.valueCoding" } } ], "linkId": "medical-history-condition2", "text": "Medical History Condition Open Choice CalcExp Animation", "type": "open-choice", "answerValueSet": "#MedicalHistory2" }, { "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl", "valueCodeableConcept": { "coding": [ { "system": "http://hl7.org/fhir/questionnaire-item-control", "code": "autocomplete" } ] } }, { "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression", "valueExpression": { "language": "text/fhirpath", "expression": "%mxValue" } } ], "linkId": "medical-history-condition3", "text": "Medical History Condition Choice CalcExp Animation", "type": "choice", "answerValueSet": "#MedicalHistory2" }, { "extension": [ { "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression", "valueExpression": { "language": "text/fhirpath", "expression": "iif(%mxValue.exists(), %mxValue.code, {})" } } ], "linkId": "medical-health-condition-text", "text": "Medical History Condition Text", "type": "text" }, { "linkId": "dob1", "type": "dateTime", "repeats": false, "text": "Datetime of birth change here" }, { "extension": [ { "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression", "valueExpression": { "language": "text/fhirpath", "expression": "iif(%dob.exists(), %dob, {} )" } } ], "linkId": "dob2", "type": "dateTime", "repeats": false, "text": "Datetime of birth CalcExpr Animation" } ] } * Refactor QR Item ID handling across form components - Introduced `getQRItemId` utility function to manage QR Item IDs, ensuring that IDs generated from calculated expressions are unique. - Updated multiple form components (AttachmentItem, BooleanItem, ChoiceAutocompleteItem, etc.) to utilize `getQRItemId` for initializing answer keys. - This change enhances the reliability of ID handling in components that rely on QR Item answers, particularly in scenarios involving calculated expressions. * - Reverting SingleItemSwitcher based on code review. * - fix lint --------- Co-authored-by: Janardhan Vignarajan <itzjana@gmail.com>
1 parent 0c09791 commit d491967

33 files changed

Lines changed: 125 additions & 71 deletions

packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import React, { useCallback, useState } from 'react';
1919
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2020
import debounce from 'lodash.debounce';
21-
import { createEmptyQrItem } from '../../../utils/qrItem';
21+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
2222
import { DEBOUNCE_DURATION } from '../../../utils/debounce';
2323
import useReadOnly from '../../../hooks/useReadOnly';
2424
import AttachmentFieldWrapper from './AttachmentFieldWrapper';
@@ -45,7 +45,7 @@ function AttachmentItem(props: BaseItemProps) {
4545
} = props;
4646

4747
// Init input value
48-
const answerKey = qrItem?.answer?.[0]?.id;
48+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
4949
let valueString = '';
5050
if (qrItem?.answer && qrItem?.answer[0].valueString) {
5151
valueString = qrItem.answer[0].valueString;

packages/smart-forms-renderer/src/components/FormComponents/BooleanItem/BooleanItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import useReadOnly from '../../../hooks/useReadOnly';
2020
import useValidationFeedback from '../../../hooks/useValidationFeedback';
2121
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2222
import { useQuestionnaireStore } from '../../../stores';
23-
import { createEmptyQrItem } from '../../../utils/qrItem';
23+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
2424
import { FullWidthFormComponentBox } from '../../Box.styles';
2525
import ItemFieldGrid from '../ItemParts/ItemFieldGrid';
2626
import ItemLabel from '../ItemParts/ItemLabel';
@@ -46,7 +46,7 @@ function BooleanItem(props: BaseItemProps) {
4646
const feedback = useValidationFeedback(qItem, feedbackFromParent);
4747

4848
// Init input value
49-
const answerKey = qrItem?.answer?.[0]?.id;
49+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
5050
let valueBoolean: boolean | undefined = undefined;
5151
if (qrItem?.answer?.[0]?.valueBoolean !== undefined) {
5252
valueBoolean = qrItem.answer[0].valueBoolean;

packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import type {
3636
import type { AlertColor } from '@mui/material/Alert';
3737
import { useRendererConfigStore } from '../../../stores';
3838
import DisplayUnitText from '../ItemParts/DisplayUnitText';
39+
import ExpressionUpdateFadingIcon from '../ItemParts/ExpressionUpdateFadingIcon';
3940

4041
interface ChoiceAutocompleteFieldsProps
4142
extends PropsWithIsTabledAttribute,
@@ -47,6 +48,8 @@ interface ChoiceAutocompleteFieldsProps
4748
loading: boolean;
4849
feedback: { message: string; color: AlertColor } | null;
4950
readOnly: boolean;
51+
calcExpUpdated: boolean;
52+
5053
onInputChange: (newInput: string) => void;
5154
onValueChange: (newValue: Coding | null) => void;
5255
}
@@ -59,6 +62,7 @@ function ChoiceAutocompleteField(props: ChoiceAutocompleteFieldsProps) {
5962
loading,
6063
feedback,
6164
readOnly,
65+
calcExpUpdated,
6266
isTabled,
6367
renderingExtensions,
6468
onInputChange,
@@ -123,6 +127,7 @@ function ChoiceAutocompleteField(props: ChoiceAutocompleteFieldsProps) {
123127
</Tooltip>
124128
</Fade>
125129
) : null}
130+
<ExpressionUpdateFadingIcon fadeIn={calcExpUpdated} disabled={readOnly} />
126131
{params.InputProps.endAdornment}
127132
<DisplayUnitText readOnly={readOnly}>{displayUnit}</DisplayUnitText>
128133
</>

packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceAutocompleteItem.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import useValidationFeedback from '../../../hooks/useValidationFeedback';
2626
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2727
import { useQuestionnaireStore } from '../../../stores';
2828
import { AUTOCOMPLETE_DEBOUNCE_DURATION } from '../../../utils/debounce';
29-
import { createEmptyQrItem } from '../../../utils/qrItem';
29+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
3030
import { FullWidthFormComponentBox } from '../../Box.styles';
3131
import ItemFieldGrid from '../ItemParts/ItemFieldGrid';
3232
import ItemLabel from '../ItemParts/ItemLabel';
@@ -41,14 +41,14 @@ function ChoiceAutocompleteItem(props: BaseItemProps) {
4141
renderingExtensions,
4242
parentIsReadOnly,
4343
feedbackFromParent,
44-
onQrItemChange
44+
onQrItemChange,
45+
calcExpUpdated
4546
} = props;
46-
// TODO no calcExpUpdated
4747

4848
const onFocusLinkId = useQuestionnaireStore.use.onFocusLinkId();
4949

5050
// Init input value
51-
const answerKey = qrItem?.answer?.[0]?.id;
51+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
5252
const qrChoice = qrItem ?? createEmptyQrItem(qItem, answerKey);
5353

5454
let valueCoding: Coding | undefined;
@@ -108,6 +108,7 @@ function ChoiceAutocompleteItem(props: BaseItemProps) {
108108
loading={loading}
109109
feedback={feedback}
110110
readOnly={readOnly}
111+
calcExpUpdated={calcExpUpdated}
111112
isTabled={isTabled}
112113
renderingExtensions={renderingExtensions}
113114
onInputChange={setInput}
@@ -134,6 +135,7 @@ function ChoiceAutocompleteItem(props: BaseItemProps) {
134135
loading={loading}
135136
feedback={feedback}
136137
readOnly={readOnly}
138+
calcExpUpdated={calcExpUpdated}
137139
isTabled={isTabled}
138140
renderingExtensions={renderingExtensions}
139141
onInputChange={setInput}

packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerOptionItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import useValidationFeedback from '../../../hooks/useValidationFeedback';
2121
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2222
import { useQuestionnaireStore } from '../../../stores';
2323
import { updateChoiceCheckboxAnswers } from '../../../utils/choice';
24-
import { createEmptyQrItem } from '../../../utils/qrItem';
24+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
2525
import { FullWidthFormComponentBox } from '../../Box.styles';
2626
import DisplayInstructions from '../DisplayItem/DisplayInstructions';
2727
import ItemFieldGrid from '../ItemParts/ItemFieldGrid';
@@ -44,7 +44,7 @@ function ChoiceCheckboxAnswerOptionItem(props: BaseItemProps) {
4444
const onFocusLinkId = useQuestionnaireStore.use.onFocusLinkId();
4545

4646
// Init input value
47-
const answerKey = qrItem?.answer?.[0]?.id;
47+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
4848
const qrChoiceCheckbox = qrItem ?? createEmptyQrItem(qItem, answerKey);
4949
const answers = qrChoiceCheckbox.answer ?? [];
5050

packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerValueSetItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import useValueSetCodings from '../../../hooks/useValueSetCodings';
2323
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2424
import { useQuestionnaireStore } from '../../../stores';
2525
import { convertCodingsToAnswerOptions, updateChoiceCheckboxAnswers } from '../../../utils/choice';
26-
import { createEmptyQrItem } from '../../../utils/qrItem';
26+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
2727
import { FullWidthFormComponentBox } from '../../Box.styles';
2828
import DisplayInstructions from '../DisplayItem/DisplayInstructions';
2929
import ItemFieldGrid from '../ItemParts/ItemFieldGrid';
@@ -46,7 +46,7 @@ function ChoiceCheckboxAnswerValueSetItem(props: BaseItemProps) {
4646
const onFocusLinkId = useQuestionnaireStore.use.onFocusLinkId();
4747

4848
// Init input value
49-
const answerKey = qrItem?.answer?.[0]?.id;
49+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
5050
const qrChoiceCheckbox = qrItem ?? createEmptyQrItem(qItem, answerKey);
5151
const answers = qrChoiceCheckbox.answer ?? [];
5252

packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { ChoiceItemControl } from '../../../interfaces/choice.enum';
2424
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2525
import { useQuestionnaireStore } from '../../../stores';
2626
import { findInAnswerOptions, getChoiceControlType, getQrChoiceValue } from '../../../utils/choice';
27-
import { createEmptyQrItem } from '../../../utils/qrItem';
27+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
2828
import ChoiceRadioAnswerOptionView from './ChoiceRadioAnswerOptionView';
2929
import ChoiceSelectAnswerOptionView from './ChoiceSelectAnswerOptionView';
3030

@@ -44,7 +44,7 @@ function ChoiceRadioAnswerOptionItem(props: BaseItemProps) {
4444
const onFocusLinkId = useQuestionnaireStore.use.onFocusLinkId();
4545

4646
// Init input value
47-
const answerKey = qrItem?.answer?.[0]?.id;
47+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
4848
const qrChoice = qrItem ?? createEmptyQrItem(qItem, answerKey);
4949
const valueChoice = getQrChoiceValue(qrChoice);
5050

packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import useValueSetCodings from '../../../hooks/useValueSetCodings';
2323
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2424
import { useQuestionnaireStore } from '../../../stores';
2525
import { convertCodingsToAnswerOptions, findInAnswerOptions } from '../../../utils/choice';
26-
import { createEmptyQrItem } from '../../../utils/qrItem';
26+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
2727
import { FullWidthFormComponentBox } from '../../Box.styles';
2828
import ItemFieldGrid from '../ItemParts/ItemFieldGrid';
2929
import ItemLabel from '../ItemParts/ItemLabel';
@@ -44,7 +44,7 @@ function ChoiceRadioAnswerValueSetItem(props: BaseItemProps) {
4444
const onFocusLinkId = useQuestionnaireStore.use.onFocusLinkId();
4545

4646
// Init input value
47-
const answerKey = qrItem?.answer?.[0]?.id;
47+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
4848
const qrChoiceRadio = qrItem ?? createEmptyQrItem(qItem, answerKey);
4949

5050
let valueRadio: string | null = null;

packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import useValidationFeedback from '../../../hooks/useValidationFeedback';
2222
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2323
import { useQuestionnaireStore } from '../../../stores';
2424
import { findInAnswerOptions, getQrChoiceValue } from '../../../utils/choice';
25-
import { createEmptyQrItem } from '../../../utils/qrItem';
25+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
2626
import ChoiceSelectAnswerOptionView from './ChoiceSelectAnswerOptionView';
2727

2828
function ChoiceSelectAnswerOptionItem(props: BaseItemProps) {
@@ -46,7 +46,7 @@ function ChoiceSelectAnswerOptionItem(props: BaseItemProps) {
4646
const feedback = useValidationFeedback(qItem, feedbackFromParent);
4747

4848
// Init input value
49-
const answerKey = qrItem?.answer?.[0]?.id;
49+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
5050
const qrChoice = qrItem ?? createEmptyQrItem(qItem, answerKey);
5151
const valueChoice = getQrChoiceValue(qrChoice);
5252

packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import useValidationFeedback from '../../../hooks/useValidationFeedback';
2424
import useValueSetCodings from '../../../hooks/useValueSetCodings';
2525
import type { BaseItemProps } from '../../../interfaces/renderProps.interface';
2626
import { useQuestionnaireStore } from '../../../stores';
27-
import { createEmptyQrItem } from '../../../utils/qrItem';
27+
import { createEmptyQrItem, getQRItemId } from '../../../utils/qrItem';
2828
import { FullWidthFormComponentBox } from '../../Box.styles';
2929
import ItemFieldGrid from '../ItemParts/ItemFieldGrid';
3030
import ItemLabel from '../ItemParts/ItemLabel';
@@ -46,7 +46,7 @@ function ChoiceSelectAnswerValueSetItem(props: BaseItemProps) {
4646
const onFocusLinkId = useQuestionnaireStore.use.onFocusLinkId();
4747

4848
// Init input value
49-
const answerKey = qrItem?.answer?.[0]?.id;
49+
const answerKey = getQRItemId(qrItem?.answer?.[0]?.id);
5050
const qrChoiceSelect = qrItem ?? createEmptyQrItem(qItem, answerKey);
5151

5252
let valueCoding: Coding | null = null;

0 commit comments

Comments
 (0)