Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion __mocks__/forms/rfe-forms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export { default as multiSelectFormSchema } from './multi-select-form.json';
export { default as nestedForm1Body } from './nested-form1.json';
export { default as nestedForm2Body } from './nested-form2.json';
export { default as nextVisitForm } from './next-visit-test-form.json';
export { default as obsGroupHideTestForm } from './obs-group-hide-test-form.json';
export { default as obsGroupHideDirectTestForm } from './obs-group-hide-direct-test-form.json';
export { default as obsGroupTestForm } from './obs-group-test-form.json';
export { default as postSubmissionTestForm } from './post-submission-test-form.json';
export { default as preclinicReviewComponentBody } from './component-preclinic-review.json';
Expand All @@ -48,4 +50,6 @@ export {
htsRetrospectiveResultingSchemaV2,
htsWildcardResultingSchemaV2,
testSchemaV2,
} from './forms-loader.test.schema';
} from './forms-loader.test.schema';


116 changes: 116 additions & 0 deletions __mocks__/forms/rfe-forms/obs-group-hide-direct-test-form.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
"name": "ObsGroup HideWhen Direct Test Form",
"version": "1",
"published": true,
"retired": false,
"pages": [
{
"label": "Test Page",
"sections": [
{
"label": "Test Section",
"isExpanded": "true",
"questions": [
{
"label": "Show Group?",
"type": "obs",
"questionOptions": {
"rendering": "radio",
"concept": "1587AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"answers": [
{
"concept": "1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"label": "Yes"
},
{
"concept": "1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"label": "No"
}
]
},
"id": "showGroupDirect",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "false"
}
},
{
"id": "testGroupDirect",
"label": "Test Group Direct (Should hide when 'No' is selected)",
"type": "obsGroup",
"questionOptions": {
"rendering": "group",
"concept": "1c70c490-cafa-4c95-9fdd-a30b62bb78b8"
},
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "showGroupDirect === '1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'"
},
"questions": [
{
"label": "Child Question 1 - Text Direct",
"type": "obs",
"questionOptions": {
"rendering": "text",
"concept": "163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
},
"id": "childTextDirect",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "false"
}
},
{
"label": "Child Question 2 - Number Direct",
"type": "obs",
"questionOptions": {
"rendering": "number",
"concept": "5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
},
"id": "childNumberDirect",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "false"
}
},
{
"label": "Child Question 3 - Radio Direct",
"type": "obs",
"questionOptions": {
"rendering": "radio",
"concept": "1587AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"answers": [
{
"concept": "1535AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"label": "Option A"
},
{
"concept": "1534AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"label": "Option B"
}
]
},
"id": "childRadioDirect",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "false"
}
}
]
}
]
}
]
}
],
"availableIntents": [],
"processor": "EncounterFormProcessor",
"uuid": "da24c540-cc83-43bc-978f-c1ef180a497f",
"referencedForms": [],
"encounterType": "79c1f50f-f77d-42e2-ad2a-d29304dde2fe"
}
146 changes: 146 additions & 0 deletions __mocks__/forms/rfe-forms/obs-group-hide-test-form.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
{
"name": "ObsGroup HideWhen Test Form",
"version": "1",
"published": true,
"retired": false,
"pages": [
{
"label": "Test Page",
"sections": [
{
"label": "Test Section",
"isExpanded": "true",
"questions": [
{
"label": "Show Group?",
"type": "obs",
"questionOptions": {
"rendering": "radio",
"concept": "1587AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"answers": [
{
"concept": "1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"label": "Yes"
},
{
"concept": "1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"label": "No"
}
]
},
"id": "showGroup",
"behaviours": [
{
"intent": "*",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "false"
},
"validators": []
}
]
},
{
"id": "testGroup",
"label": "Test Group (Should hide when 'No' is selected)",
"type": "obsGroup",
"questionOptions": {
"rendering": "group",
"concept": "1c70c490-cafa-4c95-9fdd-a30b62bb78b8"
},
"behaviours": [
{
"intent": "*",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "showGroup === '1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'"
},
"validators": []
}
],
"questions": [
{
"label": "Child Question 1 - Text",
"type": "obs",
"questionOptions": {
"rendering": "text",
"concept": "163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
},
"id": "childText",
"behaviours": [
{
"intent": "*",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "false"
},
"validators": []
}
]
},
{
"label": "Child Question 2 - Number",
"type": "obs",
"questionOptions": {
"rendering": "number",
"concept": "5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
},
"id": "childNumber",
"behaviours": [
{
"intent": "*",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "false"
},
"validators": []
}
]
},
{
"label": "Child Question 3 - Radio",
"type": "obs",
"questionOptions": {
"rendering": "radio",
"concept": "1587AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"answers": [
{
"concept": "1535AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"label": "Option A"
},
{
"concept": "1534AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"label": "Option B"
}
]
},
"id": "childRadio",
"behaviours": [
{
"intent": "*",
"required": "false",
"unspecified": "false",
"hide": {
"hideWhenExpression": "false"
},
"validators": []
}
]
}
]
}
]
}
]
}
],
"availableIntents": [],
"processor": "EncounterFormProcessor",
"uuid": "da24c540-cc83-43bc-978f-c1ef180a497f",
"referencedForms": [],
"encounterType": "79c1f50f-f77d-42e2-ad2a-d29304dde2fe"
}
68 changes: 37 additions & 31 deletions src/components/group/obs-group.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,48 @@ export const ObsGroup: React.FC<FormFieldInputProps> = ({ field, ...restProps })
const { t } = useTranslation();
const { formFieldAdapters, formFields } = useFormProviderContext();

const content = useMemo(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming the issue is related to how form intents are handled in the src/utils/forms-loader.ts, is it necessary to make changes in this file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming the issue is related to how form intents are handled in the src/utils/forms-loader.ts, is it necessary to make changes in this file?

I tested the fix by reverting obs-group.component.tsx to its original state (before commit eb663d8), and the tests FAILED without those changes. This proves that both fixes are necessary:

The forms-loader.ts fix ensures children inherit the parent's hide property at form load time.

The obs-group.component.tsx changes provide runtime filtering by checking isHidden and isParentHidden to properly hide the children.

The two layers work together one at form loading, one at rendering.

The testing demonstrated that:

Without obs-group.component.tsx changes: Tests FAIL (groups and children still render when they should be hidden)

() =>
field.questions
.map((child) => formFields.find((field) => field.id === child.id))
.filter((child) => !child.isHidden)
.map((child, index) => {
const key = `${child.id}_${index}`;
if (child.id === field.id) {
return (
<ErrorFallback error={new Error('ObsGroup child has same id as parent question')}/>
);
}
// Get the actual field from formFields to ensure we have the latest evaluated state
const evaluatedField = formFields.find((f) => f.id === field.id) || field;

// If the obsGroup itself is hidden, don't render it at all
const isGroupHidden = evaluatedField.isHidden || evaluatedField.isParentHidden || false;

if (isGroupHidden) {
return null;
}

if (child.type === 'obsGroup' && isGroupField(child.questionOptions.rendering)) {
return (
<div key={key} className={styles.nestedGroupContainer}>
<ObsGroup field={child} {...restProps} />
</div>
);
} else if (formFieldAdapters[child.type]) {
return (
<div className={classNames(styles.flexColumn)} key={key}>
<div className={styles.groupContainer}>
<FormFieldRenderer fieldId={child.id} valueAdapter={formFieldAdapters[child.type]} />
</div>
</div>
);
}
}),
[field, formFields],
);
const content = evaluatedField.questions
.map((child) => formFields.find((field) => field.id === child.id))
.filter((child) => !child.isHidden && !child.isParentHidden)
.map((child, index) => {
const key = `${child.id}_${index}`;
if (child.id === field.id) {
return (
<ErrorFallback error={new Error('ObsGroup child has same id as parent question')}/>
);
}

if (child.type === 'obsGroup' && isGroupField(child.questionOptions.rendering)) {
return (
<div key={key} className={styles.nestedGroupContainer}>
<ObsGroup field={child} {...restProps} />
</div>
);
} else if (formFieldAdapters[child.type]) {
return (
<div className={classNames(styles.flexColumn)} key={key}>
<div className={styles.groupContainer}>
<FormFieldRenderer fieldId={child.id} valueAdapter={formFieldAdapters[child.type]} />
</div>
</div>
);
}
});

return (
<div className={styles.groupContainer}>
{content.length > 1 ? (
<FormGroup legendText={t(field.label)} className={styles.boldLegend}>
<FormGroup legendText={t(evaluatedField.label)} className={styles.boldLegend}>
{content}
</FormGroup>
) : (
Expand Down
Loading