diff --git a/.prettierignore b/.prettierignore
index c2c8d3e54..32f77635c 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,5 +1,9 @@
lib
dist
coverage
+build
*.md
-*.stories.*
\ No newline at end of file
+*.stories.*
+*.cjs
+*.js
+*.config.*
diff --git a/apps/smart-forms-app/package.json b/apps/smart-forms-app/package.json
index 2824fe60f..8b2699b80 100644
--- a/apps/smart-forms-app/package.json
+++ b/apps/smart-forms-app/package.json
@@ -27,7 +27,7 @@
"dependencies": {
"@aehrc/sdc-assemble": "^1.2.0",
"@aehrc/sdc-populate": "^2.2.0",
- "@aehrc/smart-forms-renderer": "^0.34.0",
+ "@aehrc/smart-forms-renderer": "^0.34.2",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fontsource/material-icons": "^5.0.16",
diff --git a/documentation/package.json b/documentation/package.json
index 693249281..6c1ccded6 100644
--- a/documentation/package.json
+++ b/documentation/package.json
@@ -15,7 +15,7 @@
"typecheck": "tsc"
},
"dependencies": {
- "@aehrc/smart-forms-renderer": "^0.34.0",
+ "@aehrc/smart-forms-renderer": "^0.34.2",
"@docusaurus/core": "3.3.2",
"@docusaurus/preset-classic": "3.3.2",
"@docusaurus/theme-live-codeblock": "^3.3.2",
diff --git a/documentation/src/css/custom.css b/documentation/src/css/custom.css
index ca4d1a7fc..82e624c00 100644
--- a/documentation/src/css/custom.css
+++ b/documentation/src/css/custom.css
@@ -30,7 +30,7 @@
}
/* Custom CSS for code blocks */
-code, pre {
+code,
+pre {
font-size: 0.875em; /* Adjust the font size as needed */
}
-
diff --git a/package-lock.json b/package-lock.json
index ff1645b1b..f78b43fbe 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -51,7 +51,7 @@
"dependencies": {
"@aehrc/sdc-assemble": "^1.2.0",
"@aehrc/sdc-populate": "^2.2.0",
- "@aehrc/smart-forms-renderer": "^0.34.0",
+ "@aehrc/smart-forms-renderer": "^0.34.2",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fontsource/material-icons": "^5.0.16",
@@ -465,7 +465,7 @@
"name": "@aehrc/smart-forms-documentation",
"version": "0.0.0",
"dependencies": {
- "@aehrc/smart-forms-renderer": "^0.34.0",
+ "@aehrc/smart-forms-renderer": "^0.34.2",
"@docusaurus/core": "3.3.2",
"@docusaurus/preset-classic": "3.3.2",
"@docusaurus/theme-live-codeblock": "^3.3.2",
@@ -43947,7 +43947,7 @@
},
"packages/smart-forms-renderer": {
"name": "@aehrc/smart-forms-renderer",
- "version": "0.34.0",
+ "version": "0.34.2",
"license": "Apache-2.0",
"dependencies": {
"@aehrc/sdc-populate": "^2.2.0",
diff --git a/packages/sdc-populate/src/SDCPopulateQuestionnaireOperation/utils/createFhirPathContext.ts b/packages/sdc-populate/src/SDCPopulateQuestionnaireOperation/utils/createFhirPathContext.ts
index dfdda5434..3ef2b21d6 100644
--- a/packages/sdc-populate/src/SDCPopulateQuestionnaireOperation/utils/createFhirPathContext.ts
+++ b/packages/sdc-populate/src/SDCPopulateQuestionnaireOperation/utils/createFhirPathContext.ts
@@ -235,7 +235,9 @@ function createReferenceContextTuple(
referenceContext,
Promise.resolve(
createWarningIssue(
- `Reference Context ${referenceContext.part[0]?.valueString ?? ''} does not contain a reference`
+ `Reference Context ${
+ referenceContext.part[0]?.valueString ?? ''
+ } does not contain a reference`
)
),
null
@@ -259,7 +261,9 @@ function createResourceContextTuple(
resourceContext,
Promise.resolve(
createWarningIssue(
- `${resourceContextName} bundle entry ${bundleEntry.fullUrl ?? ''} does not contain a request`
+ `${resourceContextName} bundle entry ${
+ bundleEntry.fullUrl ?? ''
+ } does not contain a request`
)
),
null
diff --git a/packages/smart-forms-renderer/package.json b/packages/smart-forms-renderer/package.json
index 18fa3908a..ef6304260 100644
--- a/packages/smart-forms-renderer/package.json
+++ b/packages/smart-forms-renderer/package.json
@@ -1,6 +1,6 @@
{
"name": "@aehrc/smart-forms-renderer",
- "version": "0.34.0",
+ "version": "0.34.2",
"description": "FHIR Structured Data Captured (SDC) rendering engine for Smart Forms",
"main": "lib/index.js",
"scripts": {
diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionItem.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionItem.tsx
index db39eaf60..22b0f0c0e 100644
--- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionItem.tsx
+++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionItem.tsx
@@ -16,7 +16,11 @@
*/
import React from 'react';
-import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
+import type {
+ QuestionnaireItem,
+ QuestionnaireItemAnswerOption,
+ QuestionnaireResponseItem
+} from 'fhir/r4';
import { findInAnswerOptions, getChoiceControlType, getQrChoiceValue } from '../../../utils/choice';
import { createEmptyQrItem } from '../../../utils/qrItem';
import type {
@@ -68,15 +72,25 @@ function ChoiceRadioAnswerOptionItem(props: ChoiceRadioAnswerOptionItemProps) {
});
// Event handlers
- function handleChange(newValue: string) {
- if (options.length === 0) {
+ function handleChange(newValue: QuestionnaireItemAnswerOption | string | null) {
+ // No options present or newValue is type null
+ if (options.length === 0 || newValue === null) {
onQrItemChange(createEmptyQrItem(qItem));
return;
}
- const qrAnswer = findInAnswerOptions(options, newValue);
+ // newValue is type string
+ if (typeof newValue === 'string') {
+ const qrAnswer = findInAnswerOptions(options, newValue);
+ onQrItemChange(
+ qrAnswer ? { ...createEmptyQrItem(qItem), answer: [qrAnswer] } : createEmptyQrItem(qItem)
+ );
+ return;
+ }
+
+ // newValue is type QuestionnaireItemAnswerOption
onQrItemChange(
- qrAnswer ? { ...createEmptyQrItem(qItem), answer: [qrAnswer] } : createEmptyQrItem(qItem)
+ newValue ? { ...createEmptyQrItem(qItem), answer: [newValue] } : createEmptyQrItem(qItem)
);
}
@@ -117,7 +131,6 @@ function ChoiceRadioAnswerOptionItem(props: ChoiceRadioAnswerOptionItemProps) {
calcExpUpdated={calcExpUpdated}
onFocusLinkId={() => onFocusLinkId(qItem.linkId)}
onSelectChange={handleChange}
- onClear={handleClear}
/>
);
}
diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx
index 59601d1ec..01db9051a 100644
--- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx
+++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx
@@ -16,21 +16,22 @@
*/
import React, { Fragment } from 'react';
-import InputAdornment from '@mui/material/InputAdornment';
-import MenuItem from '@mui/material/MenuItem';
-import Select from '@mui/material/Select';
import type { QuestionnaireItem, QuestionnaireItemAnswerOption } from 'fhir/r4';
import useRenderingExtensions from '../../../hooks/useRenderingExtensions';
import type { PropsWithIsTabledAttribute } from '../../../interfaces/renderProps.interface';
-import { TEXT_FIELD_WIDTH } from '../Textfield.styles';
+import { StandardTextField, TEXT_FIELD_WIDTH } from '../Textfield.styles';
+import FadingCheckIcon from '../ItemParts/FadingCheckIcon';
+import Autocomplete from '@mui/material/Autocomplete';
+import { getAnswerOptionLabel } from '../../../utils/openChoice';
+import { compareAnswerOptionValue } from '../../../utils/choice';
interface ChoiceSelectAnswerOptionFieldsProps extends PropsWithIsTabledAttribute {
qItem: QuestionnaireItem;
options: QuestionnaireItemAnswerOption[];
- valueSelect: string;
+ valueSelect: QuestionnaireItemAnswerOption | null;
readOnly: boolean;
calcExpUpdated: boolean;
- onSelectChange: (newValue: string) => void;
+ onSelectChange: (newValue: QuestionnaireItemAnswerOption | null) => void;
}
function ChoiceSelectAnswerOptionFields(props: ChoiceSelectAnswerOptionFieldsProps) {
@@ -38,49 +39,39 @@ function ChoiceSelectAnswerOptionFields(props: ChoiceSelectAnswerOptionFieldsPro
const { displayUnit, displayPrompt, entryFormat } = useRenderingExtensions(qItem);
- // TODO use calcExpUpdated as updated feedback
-
return (
-
+ disabled={readOnly}
+ renderInput={(params) => (
+
+ {params.InputProps.endAdornment}
+
+ {displayUnit}
+ >
+ )
+ }}
+ data-test="q-item-choice-dropdown-answer-value-set-field"
+ />
+ )}
+ />
);
}
diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionItem.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionItem.tsx
index 4f9ea0275..1fd6ff42f 100644
--- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionItem.tsx
+++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionItem.tsx
@@ -17,7 +17,11 @@
import React from 'react';
-import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
+import type {
+ QuestionnaireItem,
+ QuestionnaireItemAnswerOption,
+ QuestionnaireResponseItem
+} from 'fhir/r4';
import { findInAnswerOptions, getQrChoiceValue } from '../../../utils/choice';
import { createEmptyQrItem } from '../../../utils/qrItem';
import type {
@@ -66,23 +70,28 @@ function ChoiceSelectAnswerOptionItem(props: ChoiceSelectAnswerOptionItemProps)
}
});
- // Event handlers
- function handleChange(newValue: string) {
- if (options.length === 0) {
+ function handleChange(newValue: QuestionnaireItemAnswerOption | string | null) {
+ // No options present or newValue is type null
+ if (options.length === 0 || newValue === null) {
onQrItemChange(createEmptyQrItem(qItem));
return;
}
- const qrAnswer = findInAnswerOptions(options, newValue);
+ // newValue is type string
+ if (typeof newValue === 'string') {
+ const qrAnswer = findInAnswerOptions(options, newValue);
+ onQrItemChange(
+ qrAnswer ? { ...createEmptyQrItem(qItem), answer: [qrAnswer] } : createEmptyQrItem(qItem)
+ );
+ return;
+ }
+
+ // newValue is type QuestionnaireItemAnswerOption
onQrItemChange(
- qrAnswer ? { ...createEmptyQrItem(qItem), answer: [qrAnswer] } : createEmptyQrItem(qItem)
+ newValue ? { ...createEmptyQrItem(qItem), answer: [newValue] } : createEmptyQrItem(qItem)
);
}
- function handleClear() {
- onQrItemChange(createEmptyQrItem(qItem));
- }
-
return (
onFocusLinkId(qItem.linkId)}
onSelectChange={handleChange}
- onClear={handleClear}
/>
);
}
diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionView.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionView.tsx
index 38b86332d..f5dea9ad1 100644
--- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionView.tsx
+++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionView.tsx
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import React from 'react';
+import React, { useMemo } from 'react';
import { FullWidthFormComponentBox } from '../../Box.styles';
import ItemFieldGrid from '../ItemParts/ItemFieldGrid';
import type {
@@ -23,6 +23,7 @@ import type {
PropsWithIsTabledAttribute
} from '../../../interfaces/renderProps.interface';
import type { QuestionnaireItem, QuestionnaireItemAnswerOption } from 'fhir/r4';
+import { findInAnswerOptions } from '../../../utils/choice';
import ChoiceSelectAnswerOptionFields from './ChoiceSelectAnswerOptionFields';
interface ChoiceSelectAnswerOptionViewProps
@@ -33,9 +34,8 @@ interface ChoiceSelectAnswerOptionViewProps
valueChoice: string | null;
readOnly: boolean;
calcExpUpdated: boolean;
- onSelectChange: (linkId: string) => void;
+ onSelectChange: (newValue: QuestionnaireItemAnswerOption | null) => void;
onFocusLinkId: () => void;
- onClear: () => void;
}
function ChoiceSelectAnswerOptionView(props: ChoiceSelectAnswerOptionViewProps) {
@@ -48,16 +48,20 @@ function ChoiceSelectAnswerOptionView(props: ChoiceSelectAnswerOptionViewProps)
readOnly,
calcExpUpdated,
onFocusLinkId,
- onSelectChange,
- onClear
+ onSelectChange
} = props;
+ const valueSelect: QuestionnaireItemAnswerOption | null = useMemo(
+ () => findInAnswerOptions(options, valueChoice ?? '') ?? null,
+ [options, valueChoice]
+ );
+
if (isRepeated) {
return (
diff --git a/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormButtonForStorybook.tsx b/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormButtonForStorybook.tsx
index d6c2bfe87..dfbd67a12 100644
--- a/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormButtonForStorybook.tsx
+++ b/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormButtonForStorybook.tsx
@@ -21,6 +21,7 @@ import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
import { Box, IconButton, Tooltip } from '@mui/material';
import Iconify from '../../components/Iconify/Iconify';
import { buildForm } from '../../utils';
+import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
interface BuildFormButtonProps {
questionnaire: Questionnaire;
@@ -31,7 +32,12 @@ function BuildFormButtonForStorybook(props: BuildFormButtonProps) {
const { questionnaire, questionnaireResponse } = props;
async function handleBuildForm() {
- await buildForm(questionnaire, questionnaireResponse);
+ await buildForm(
+ questionnaire,
+ questionnaireResponse,
+ undefined,
+ STORYBOOK_TERMINOLOGY_SERVER_URL
+ );
}
return (
diff --git a/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx b/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx
index c0761448d..10214dee8 100644
--- a/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx
+++ b/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx
@@ -23,6 +23,7 @@ import { QueryClientProvider } from '@tanstack/react-query';
import { RendererThemeProvider } from '../../theme';
import { useBuildForm, useRendererQueryClient } from '../../hooks';
import BuildFormButtonForStorybook from './BuildFormButtonForStorybook';
+import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
interface BuildFormButtonTesterWrapperForStorybookProps {
questionnaire: Questionnaire;
@@ -46,7 +47,12 @@ function BuildFormButtonTesterWrapperForStorybook(
const queryClient = useRendererQueryClient();
- const isBuilding = useBuildForm(questionnaire);
+ const isBuilding = useBuildForm(
+ questionnaire,
+ undefined,
+ undefined,
+ STORYBOOK_TERMINOLOGY_SERVER_URL
+ );
if (isBuilding) {
return Loading...
;
diff --git a/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormWrapperForStorybook.tsx b/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormWrapperForStorybook.tsx
index ddc6ea243..3ac62e3f2 100644
--- a/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormWrapperForStorybook.tsx
+++ b/packages/smart-forms-renderer/src/stories/storybookWrappers/BuildFormWrapperForStorybook.tsx
@@ -23,6 +23,7 @@ import { QueryClientProvider } from '@tanstack/react-query';
import RendererThemeProvider from '../../theme/Theme';
import { useBuildForm } from '../../hooks';
import useRendererQueryClient from '../../hooks/useRendererQueryClient';
+import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
interface BuildFormWrapperForStorybookProps {
questionnaire: Questionnaire;
@@ -33,7 +34,12 @@ function BuildFormWrapperForStorybook(props: BuildFormWrapperForStorybookProps)
const { questionnaire, questionnaireResponse } = props;
const queryClient = useRendererQueryClient();
- const isBuilding = useBuildForm(questionnaire, questionnaireResponse);
+ const isBuilding = useBuildForm(
+ questionnaire,
+ questionnaireResponse,
+ undefined,
+ STORYBOOK_TERMINOLOGY_SERVER_URL
+ );
if (isBuilding) {
return Loading...
;
diff --git a/packages/smart-forms-renderer/src/stories/storybookWrappers/FormValidationTesterWrapperForStorybook.tsx b/packages/smart-forms-renderer/src/stories/storybookWrappers/FormValidationTesterWrapperForStorybook.tsx
index 39f869e30..d987842e0 100644
--- a/packages/smart-forms-renderer/src/stories/storybookWrappers/FormValidationTesterWrapperForStorybook.tsx
+++ b/packages/smart-forms-renderer/src/stories/storybookWrappers/FormValidationTesterWrapperForStorybook.tsx
@@ -24,6 +24,7 @@ import { RendererThemeProvider } from '../../theme';
import { useBuildForm, useRendererQueryClient } from '../../hooks';
import { Grid } from '@mui/material';
import FormValidationViewerForStorybook from './FormValidationViewerForStorybook';
+import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
interface FormValidationTesterWrapperForStorybookProps {
questionnaire: Questionnaire;
@@ -35,7 +36,12 @@ function FormValidationTesterWrapperForStorybook(
) {
const { questionnaire, questionnaireResponse } = props;
- const isBuilding = useBuildForm(questionnaire, questionnaireResponse);
+ const isBuilding = useBuildForm(
+ questionnaire,
+ questionnaireResponse,
+ undefined,
+ STORYBOOK_TERMINOLOGY_SERVER_URL
+ );
const queryClient = useRendererQueryClient();
diff --git a/packages/smart-forms-renderer/src/stories/storybookWrappers/PrePopWrapperForStorybook.tsx b/packages/smart-forms-renderer/src/stories/storybookWrappers/PrePopWrapperForStorybook.tsx
index 9e645cfd7..5ee3538be 100644
--- a/packages/smart-forms-renderer/src/stories/storybookWrappers/PrePopWrapperForStorybook.tsx
+++ b/packages/smart-forms-renderer/src/stories/storybookWrappers/PrePopWrapperForStorybook.tsx
@@ -27,6 +27,7 @@ import PrePopButtonForStorybook from './PrePopButtonForStorybook';
import { populateQuestionnaire } from '@aehrc/sdc-populate';
import { fetchResourceCallback } from './populateCallbackForStorybook';
import { buildForm } from '../../utils';
+import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
interface PrePopWrapperForStorybookProps {
questionnaire: Questionnaire;
@@ -75,7 +76,12 @@ function PrePopWrapperForStorybook(props: PrePopWrapperForStorybookProps) {
const { populatedResponse } = populateResult;
// Call to buildForm to pre-populate the QR which repaints the entire BaseRenderer view
- await buildForm(questionnaire, populatedResponse);
+ await buildForm(
+ questionnaire,
+ populatedResponse,
+ undefined,
+ STORYBOOK_TERMINOLOGY_SERVER_URL
+ );
setIsPopulating(false);
});
diff --git a/packages/smart-forms-renderer/src/stories/storybookWrappers/globals.ts b/packages/smart-forms-renderer/src/stories/storybookWrappers/globals.ts
new file mode 100644
index 000000000..b0ae048e4
--- /dev/null
+++ b/packages/smart-forms-renderer/src/stories/storybookWrappers/globals.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2024 Commonwealth Scientific and Industrial Research
+ * Organisation (CSIRO) ABN 41 687 119 230.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const STORYBOOK_TERMINOLOGY_SERVER_URL = 'https://r4.ontoserver.csiro.au/fhir';
diff --git a/packages/smart-forms-renderer/src/utils/choice.ts b/packages/smart-forms-renderer/src/utils/choice.ts
index 9a643a544..323c8fa2f 100644
--- a/packages/smart-forms-renderer/src/utils/choice.ts
+++ b/packages/smart-forms-renderer/src/utils/choice.ts
@@ -80,6 +80,34 @@ export function findInAnswerOptions(
return;
}
+/**
+ * Compare answer option value with selected value via valueString, valueInteger, or valueCoding.code
+ *
+ * @author Sean Fong
+ */
+export function compareAnswerOptionValue(
+ option: QuestionnaireItemAnswerOption,
+ value: QuestionnaireItemAnswerOption
+): boolean {
+ if (!value) {
+ return false;
+ }
+
+ if (value.valueString) {
+ return option.valueString === value.valueString;
+ }
+
+ if (value.valueInteger) {
+ return option.valueInteger === value.valueInteger;
+ }
+
+ if (value.valueCoding && value.valueCoding.code) {
+ return option.valueCoding?.code === value.valueCoding.code;
+ }
+
+ return false;
+}
+
/**
* Get choice control type based on certain criteria in choice items
*
@@ -105,22 +133,6 @@ export function getChoiceControlType(qItem: QuestionnaireItem) {
return ChoiceItemControl.Select;
}
-/**
- * Find and return corresponding coding from AnswerValueSet based on selected answer in form
- *
- * @author Sean Fong
- */
-export function findInAnswerValueSetCodings(
- codings: Coding[],
- selected: string
-): QuestionnaireResponseItemAnswer | undefined {
- for (const coding of codings) {
- if (selected === coding.code) {
- return coding;
- }
- }
-}
-
/**
* Find and return string value from selected answer
*
diff --git a/packages/smart-forms-renderer/src/utils/itemControl.ts b/packages/smart-forms-renderer/src/utils/itemControl.ts
index 47c9fc802..7b338373c 100644
--- a/packages/smart-forms-renderer/src/utils/itemControl.ts
+++ b/packages/smart-forms-renderer/src/utils/itemControl.ts
@@ -26,10 +26,18 @@ function hasDisplayCategory(qItem: QuestionnaireItem): boolean {
);
}
+function hasItemControl(qItem: QuestionnaireItem): boolean {
+ return !!qItem.extension?.some(
+ (extension: Extension) =>
+ extension.url === 'http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl'
+ );
+}
+
// If all nested items are of type display and have itemControl, then they should not be rendered
export function shouldRenderNestedItems(qItem: QuestionnaireItem): boolean {
return !qItem.item?.every(
- (childItem) => childItem.type === 'display' && hasDisplayCategory(childItem)
+ (childItem) =>
+ childItem.type === 'display' && (hasDisplayCategory(childItem) || hasItemControl(childItem))
);
}