From 82bb4bd7ff2480c2337547a69a2a2c897ad7a9a5 Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Fri, 23 Aug 2024 14:20:43 +1000 Subject: [PATCH] Add support for non-repeating group table --- apps/demo-renderer-app/package.json | 2 +- apps/smart-forms-app/package.json | 2 +- documentation/package.json | 2 +- package-lock.json | 39 +-- packages/smart-forms-renderer/package.json | 2 +- .../GroupItem/GroupItemSwitcher.tsx | 16 ++ .../FormComponents/Tables/GroupTable.tsx | 4 + .../FormComponents/Tables/GroupTableBody.tsx | 6 +- .../FormComponents/Tables/GroupTableRow.tsx | 144 +++++++---- .../FormComponents/Tables/GroupTableView.tsx | 56 +++-- .../components/Renderer/FormTopLevelItem.tsx | 17 ++ .../questionnaires/QItemControlGroup.ts | 234 +++++++++++++++++- .../stories/sdc/ItemControlGroup.stories.tsx | 13 +- 13 files changed, 414 insertions(+), 123 deletions(-) diff --git a/apps/demo-renderer-app/package.json b/apps/demo-renderer-app/package.json index 85ed5bf83..b0dfd17b9 100644 --- a/apps/demo-renderer-app/package.json +++ b/apps/demo-renderer-app/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@aehrc/sdc-populate": "^2.3.1", - "@aehrc/smart-forms-renderer": "^0.37.2", + "@aehrc/smart-forms-renderer": "^0.38.3", "@tanstack/react-query": "^4.36.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/apps/smart-forms-app/package.json b/apps/smart-forms-app/package.json index 428c39d07..50d0645fd 100644 --- a/apps/smart-forms-app/package.json +++ b/apps/smart-forms-app/package.json @@ -28,7 +28,7 @@ "dependencies": { "@aehrc/sdc-assemble": "^1.3.1", "@aehrc/sdc-populate": "^2.3.1", - "@aehrc/smart-forms-renderer": "^0.37.2", + "@aehrc/smart-forms-renderer": "^0.38.3", "@emotion/react": "^11.13.0", "@emotion/styled": "^11.11.5", "@fontsource/material-icons": "^5.0.18", diff --git a/documentation/package.json b/documentation/package.json index 4fc6a7d07..f3d7710d5 100644 --- a/documentation/package.json +++ b/documentation/package.json @@ -15,7 +15,7 @@ "typecheck": "tsc" }, "dependencies": { - "@aehrc/smart-forms-renderer": "^0.37.2", + "@aehrc/smart-forms-renderer": "^0.38.3", "@docusaurus/core": "^3.4.0", "@docusaurus/preset-classic": "^3.4.0", "@docusaurus/theme-live-codeblock": "^3.4.0", diff --git a/package-lock.json b/package-lock.json index eeb3d5946..5b258d4a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "dependencies": { "@aehrc/sdc-assemble": "^1.3.1", "@aehrc/sdc-populate": "^2.3.1", - "@aehrc/smart-forms-renderer": "^0.37.2", + "@aehrc/smart-forms-renderer": "^0.38.2", "@emotion/react": "^11.13.0", "@emotion/styled": "^11.11.5", "@fontsource/material-icons": "^5.0.18", @@ -117,43 +117,6 @@ "yui-lint": "^0.2.0" } }, - "apps/smart-forms-app/node_modules/@aehrc/smart-forms-renderer": { - "version": "0.37.2", - "resolved": "https://registry.npmjs.org/@aehrc/smart-forms-renderer/-/smart-forms-renderer-0.37.2.tgz", - "integrity": "sha512-d0OSM951JhsTbHVsabzHgEcNTk0PLmI+GSNqYtkI/02vWDYNjjz5XtWM/29mA+FajdvYPRAfQbc7R7/buJ8lAg==", - "dependencies": { - "@aehrc/sdc-populate": "^2.3.1", - "@iconify/react": "^4.1.1", - "dayjs": "^1.11.10", - "deep-diff": "^1.0.2", - "fhirclient": "^2.5.2", - "fhirpath": "3.11.0", - "html-react-parser": "4.2.10", - "js-base64": "^3.7.7", - "lodash.clonedeep": "^4.5.0", - "lodash.debounce": "^4.0.8", - "lodash.difference": "^4.5.0", - "lodash.intersection": "^4.4.0", - "nanoid": "^5.0.7", - "react-beautiful-dnd": "^13.1.1", - "react-dnd": "^16.0.1", - "react-dnd-html5-backend": "^16.0.1", - "react-markdown": "^8.0.7", - "style-to-object": "^1.0.6", - "zustand": "^4.5.4" - }, - "peerDependencies": { - "@emotion/react": "^11.11.3", - "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.10", - "@mui/lab": "^5.0.0-alpha.165", - "@mui/material": "^5.15.10", - "@mui/x-date-pickers": "^6.19.4", - "@tanstack/react-query": "^4.36.0", - "react": ">=17.0.0", - "react-dom": ">=17.0.0" - } - }, "apps/smart-forms-app/node_modules/@typescript-eslint/parser": { "version": "6.21.0", "dev": true, diff --git a/packages/smart-forms-renderer/package.json b/packages/smart-forms-renderer/package.json index 96b95e747..35b88306e 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.38.2", + "version": "0.38.3", "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/GroupItem/GroupItemSwitcher.tsx b/packages/smart-forms-renderer/src/components/FormComponents/GroupItem/GroupItemSwitcher.tsx index 12ddab2cf..3244c0efd 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/GroupItem/GroupItemSwitcher.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/GroupItem/GroupItemSwitcher.tsx @@ -76,6 +76,7 @@ function GroupItemSwitcher(props: GroupItemSwitcherProps) { qItem={qItem} qrItems={qrItems} groupCardElevation={groupCardElevation + 1} + isRepeated={true} parentIsReadOnly={parentIsReadOnly} onQrRepeatGroupChange={onQrRepeatGroupChange} /> @@ -119,6 +120,7 @@ function GroupItemSwitcher(props: GroupItemSwitcherProps) { qItem={qItem} qrItems={[]} groupCardElevation={groupCardElevation + 1} + isRepeated={true} parentIsReadOnly={parentIsReadOnly} onQrRepeatGroupChange={onQrRepeatGroupChange} /> @@ -149,6 +151,20 @@ function GroupItemSwitcher(props: GroupItemSwitcherProps) { // if qItem is not a repeating question or is a checkbox if (qItem.type === 'group') { + // GroupTable "gtable" can be rendered with either repeats:true or false + if (isSpecificItemControl(qItem, 'gtable')) { + return ( + + ); + } + return ( - {(draggableProvided, snapshot) => ( - - {showMinimalView ? null : ( - <> - - - - - - + {(draggableProvided, snapshot) => ( + + {showMinimalView || !isRepeated ? ( + + ) : ( + <> + + + + + + onSelectRow(nanoId)} + /> + + )} + onRowChange(newQrGroup, index)} + /> + {showMinimalView || !isRepeated ? ( + + ) : ( + onSelectRow(nanoId)} + onRemoveItem={() => onRemoveRow(index)} /> - - )} - onRowChange(newQrGroup, index)} + )} + + )} + + ); + } + + return ( + + {showMinimalView || !isRepeated ? ( + + ) : ( + <> + + + + + + onSelectRow(nanoId)} /> - {showMinimalView ? null : ( - onRemoveRow(index)} - /> - )} - + + )} + onRowChange(newQrGroup, index)} + /> + {showMinimalView || !isRepeated ? ( + + ) : ( + onRemoveRow(index)} + /> )} - + ); } diff --git a/packages/smart-forms-renderer/src/components/FormComponents/Tables/GroupTableView.tsx b/packages/smart-forms-renderer/src/components/FormComponents/Tables/GroupTableView.tsx index b865f824b..632b7d582 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/Tables/GroupTableView.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/Tables/GroupTableView.tsx @@ -31,6 +31,7 @@ import Divider from '@mui/material/Divider'; import AddRowButton from './AddRowButton'; import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4'; import type { + PropsWithIsRepeatedAttribute, PropsWithParentIsReadOnlyAttribute, PropsWithShowMinimalViewAttribute } from '../../../interfaces/renderProps.interface'; @@ -40,7 +41,8 @@ import Checkbox from '@mui/material/Checkbox'; import { useQuestionnaireStore } from '../../../stores'; interface GroupTableViewProps - extends PropsWithShowMinimalViewAttribute, + extends PropsWithIsRepeatedAttribute, + PropsWithShowMinimalViewAttribute, PropsWithParentIsReadOnlyAttribute { qItem: QuestionnaireItem; qItemsIndexMap: Record; @@ -62,6 +64,7 @@ function GroupTableView(props: GroupTableViewProps) { qItem, qItemsIndexMap, groupCardElevation, + isRepeated, readOnly, tableRows, selectedIds, @@ -100,6 +103,7 @@ function GroupTableView(props: GroupTableViewProps) { tableRows={tableRows} selectedIds={selectedIds} qItemsIndexMap={qItemsIndexMap} + isRepeated={isRepeated} showMinimalView={showMinimalView} parentIsReadOnly={parentIsReadOnly} onRowChange={onRowChange} @@ -121,39 +125,38 @@ function GroupTableView(props: GroupTableViewProps) { py={3} data-linkid={qItem.linkId} onClick={() => onFocusLinkId(qItem.linkId)}> - {groupCardElevation !== 1 ? ( - <> - - - - - - ) : null} + <> + + + + + - + {isRepeated ? ( + + ) : null} - - 0 && selectedIds.length < tableRows.length} - checked={tableRows.length > 0 && selectedIds.length === tableRows.length} - disabled={readOnly} - onChange={onSelectAll} - /> - + {isRepeated ? ( + + 0 && selectedIds.length < tableRows.length} + checked={tableRows.length > 0 && selectedIds.length === tableRows.length} + disabled={readOnly} + onChange={onSelectAll} + /> + + ) : null} {itemLabels.map((itemLabel) => ( {itemLabel} ))} - + + ); + } + return ( ; // More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args -export const Gtable: Story = { +export const GTableRepeats: Story = { args: { - questionnaire: qItemControlGroupGTable + questionnaire: qItemControlGroupGTableRepeats + } +}; + +export const GTableSingle: Story = { + args: { + questionnaire: qItemControlGroupGTableSingle } };
- - + +