@aehrc/smart-forms-renderer 0.9.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/.swcrc +11 -0
  2. package/lib/components/FormComponents/GroupItem/NextTabButtonWrapper.js +5 -5
  3. package/lib/components/FormComponents/GroupItem/NextTabButtonWrapper.js.map +1 -1
  4. package/lib/components/FormComponents/RepeatGroup/DeleteItemButton.js +1 -1
  5. package/lib/components/FormComponents/RepeatItem/RemoveItemButton.d.ts +10 -0
  6. package/lib/components/FormComponents/RepeatItem/RemoveItemButton.js +30 -0
  7. package/lib/components/FormComponents/RepeatItem/RemoveItemButton.js.map +1 -0
  8. package/lib/components/FormComponents/RepeatItem/RepeatField.js +2 -2
  9. package/lib/components/FormComponents/SingleItem/SingleItem.js +2 -2
  10. package/lib/components/FormComponents/SingleItem/SingleItem.js.map +1 -1
  11. package/lib/components/FormComponents/Tables/GroupTable.d.ts +1 -2
  12. package/lib/components/FormComponents/Tables/GroupTable.js +44 -59
  13. package/lib/components/FormComponents/Tables/GroupTable.js.map +1 -1
  14. package/lib/components/FormComponents/Tables/GroupTableBody.d.ts +17 -0
  15. package/lib/components/FormComponents/Tables/GroupTableBody.js +48 -0
  16. package/lib/components/FormComponents/Tables/GroupTableBody.js.map +1 -0
  17. package/lib/components/FormComponents/Tables/GroupTableRow.d.ts +18 -5
  18. package/lib/components/FormComponents/Tables/GroupTableRow.js +17 -25
  19. package/lib/components/FormComponents/Tables/GroupTableRow.js.map +1 -1
  20. package/lib/components/FormComponents/Tables/GroupTableRowCells.d.ts +11 -0
  21. package/lib/components/FormComponents/Tables/GroupTableRowCells.js +57 -0
  22. package/lib/components/FormComponents/Tables/GroupTableRowCells.js.map +1 -0
  23. package/lib/components/FormComponents/Tables/GroupTableRows.d.ts +17 -0
  24. package/lib/components/FormComponents/Tables/GroupTableRows.js +45 -0
  25. package/lib/components/FormComponents/Tables/GroupTableRows.js.map +1 -0
  26. package/lib/components/FormComponents/Tables/GroupTableTestRow.d.ts +22 -0
  27. package/lib/components/FormComponents/Tables/GroupTableTestRow.js +43 -0
  28. package/lib/components/FormComponents/Tables/GroupTableTestRow.js.map +1 -0
  29. package/lib/components/FormComponents/Tables/GroupTableView.d.ts +21 -0
  30. package/lib/components/FormComponents/Tables/GroupTableView.js +65 -0
  31. package/lib/components/FormComponents/Tables/GroupTableView.js.map +1 -0
  32. package/lib/components/FormComponents/Tables/RemoveRowButton.d.ts +10 -0
  33. package/lib/components/FormComponents/Tables/RemoveRowButton.js +32 -0
  34. package/lib/components/FormComponents/Tables/RemoveRowButton.js.map +1 -0
  35. package/lib/components/FormComponents/Tables/SelectRowButton.d.ts +7 -0
  36. package/lib/components/FormComponents/Tables/SelectRowButton.js +26 -0
  37. package/lib/components/FormComponents/Tables/SelectRowButton.js.map +1 -0
  38. package/lib/components/FormComponents/Tables/Table.styles.d.ts +8 -0
  39. package/lib/components/FormComponents/Tables/Table.styles.js +17 -0
  40. package/lib/components/FormComponents/Tables/Table.styles.js.map +1 -1
  41. package/lib/components/Renderer/BaseRenderer.js +5 -6
  42. package/lib/components/Renderer/BaseRenderer.js.map +1 -1
  43. package/lib/components/Renderer/FormBodyCollapsible.js +4 -4
  44. package/lib/components/Renderer/FormBodyCollapsible.js.map +1 -1
  45. package/lib/components/Renderer/FormBodyTabbed.js +3 -3
  46. package/lib/components/Renderer/FormBodyTabbed.js.map +1 -1
  47. package/lib/components/Tabs/CompleteTabButton.js +2 -2
  48. package/lib/components/Tabs/CompleteTabButton.js.map +1 -1
  49. package/lib/components/Tabs/FormBodySingleTab.js +2 -2
  50. package/lib/components/Tabs/FormBodySingleTab.js.map +1 -1
  51. package/lib/components/Tabs/FormBodyTabList.js +4 -4
  52. package/lib/components/Tabs/FormBodyTabList.js.map +1 -1
  53. package/lib/hooks/useDecimalCalculatedExpression.js +2 -2
  54. package/lib/hooks/useDecimalCalculatedExpression.js.map +1 -1
  55. package/lib/hooks/useHidden.js +4 -4
  56. package/lib/hooks/useHidden.js.map +1 -1
  57. package/lib/hooks/useInitialiseGroupTable.d.ts +2 -2
  58. package/lib/hooks/useInitialiseGroupTable.js.map +1 -1
  59. package/lib/hooks/useInitialiseRenderer.js +11 -14
  60. package/lib/hooks/useInitialiseRenderer.js.map +1 -1
  61. package/lib/hooks/useIntegerCalculatedExpression.js +2 -2
  62. package/lib/hooks/useIntegerCalculatedExpression.js.map +1 -1
  63. package/lib/hooks/useMinimalStringCalculatedExpression.js +25 -13
  64. package/lib/hooks/useStringCalculatedExpression.js +2 -2
  65. package/lib/hooks/useStringCalculatedExpression.js.map +1 -1
  66. package/lib/hooks/useTerminologyServerQuery.js +3 -4
  67. package/lib/hooks/useTerminologyServerQuery.js.map +1 -1
  68. package/lib/hooks/useValueSetCodings.js +10 -12
  69. package/lib/hooks/useValueSetCodings.js.map +1 -1
  70. package/lib/index.js +19 -20
  71. package/lib/index.js.map +1 -1
  72. package/lib/interfaces/groupTable.interface.d.ts +1 -1
  73. package/lib/setup-jest.js +1 -0
  74. package/lib/setup-jest.js.map +1 -0
  75. package/lib/stores/index.d.ts +4 -3
  76. package/lib/stores/index.js +4 -3
  77. package/lib/stores/index.js.map +1 -1
  78. package/lib/stores/questionnaireResponseStore.d.ts +28 -0
  79. package/lib/stores/questionnaireResponseStore.js +64 -0
  80. package/lib/stores/questionnaireResponseStore.js.map +1 -0
  81. package/lib/stores/questionnaireStore.d.ts +65 -0
  82. package/lib/stores/questionnaireStore.js +172 -0
  83. package/lib/stores/questionnaireStore.js.map +1 -0
  84. package/lib/stores/smartConfigStore.d.ts +25 -0
  85. package/lib/stores/smartConfigStore.js +30 -0
  86. package/lib/stores/smartConfigStore.js.map +1 -0
  87. package/lib/stores/terminologyServerStore.d.ts +14 -0
  88. package/lib/stores/terminologyServerStore.js +26 -0
  89. package/lib/stores/terminologyServerStore.js.map +1 -0
  90. package/lib/stores/useQuestionnaireResponseStore.d.ts +14 -2
  91. package/lib/stores/useQuestionnaireResponseStore.js +4 -2
  92. package/lib/stores/useQuestionnaireResponseStore.js.map +1 -1
  93. package/lib/stores/useQuestionnaireStore.d.ts +30 -2
  94. package/lib/stores/useQuestionnaireStore.js +4 -2
  95. package/lib/stores/useQuestionnaireStore.js.map +1 -1
  96. package/lib/stories/MedicalHistoryTable.stories.js +49 -0
  97. package/lib/stories/MedicalHistoryTable.stories.js.map +1 -0
  98. package/lib/stories/SmartFormsRenderer.stories.js +103 -0
  99. package/lib/stories/SmartFormsRenderer.stories.js.map +1 -0
  100. package/lib/theme/overrides/Table.d.ts +1 -0
  101. package/lib/theme/overrides/Table.js +2 -1
  102. package/lib/theme/overrides/Table.js.map +1 -1
  103. package/lib/utils/calculatedExpression.js +1 -2
  104. package/lib/utils/calculatedExpression.js.map +1 -1
  105. package/lib/utils/groupTable.d.ts +3 -0
  106. package/lib/utils/groupTable.js +29 -0
  107. package/lib/utils/groupTable.js.map +1 -0
  108. package/package.json +10 -5
  109. package/src/components/FormComponents/GroupItem/NextTabButtonWrapper.tsx +5 -5
  110. package/src/components/FormComponents/RepeatGroup/DeleteItemButton.tsx +1 -1
  111. package/src/components/FormComponents/RepeatItem/{DeleteItemButton.tsx → RemoveItemButton.tsx} +4 -4
  112. package/src/components/FormComponents/RepeatItem/RepeatField.tsx +2 -2
  113. package/src/components/FormComponents/SingleItem/SingleItem.tsx +2 -2
  114. package/src/components/FormComponents/Tables/GroupTable.tsx +71 -120
  115. package/src/components/FormComponents/Tables/GroupTableBody.tsx +116 -0
  116. package/src/components/FormComponents/Tables/GroupTableRow.tsx +89 -49
  117. package/src/components/FormComponents/Tables/GroupTableRowCells.tsx +87 -0
  118. package/src/components/FormComponents/Tables/GroupTableView.tsx +169 -0
  119. package/src/components/FormComponents/Tables/{DeleteRowButton.tsx → RemoveRowButton.tsx} +7 -7
  120. package/src/components/FormComponents/Tables/SelectRowButton.tsx +37 -0
  121. package/src/components/FormComponents/Tables/Table.styles.tsx +25 -0
  122. package/src/components/Renderer/BaseRenderer.tsx +5 -6
  123. package/src/components/Renderer/FormBodyCollapsible.tsx +4 -5
  124. package/src/components/Renderer/FormBodyTabbed.tsx +3 -3
  125. package/src/components/Tabs/CompleteTabButton.tsx +2 -2
  126. package/src/components/Tabs/FormBodySingleTab.tsx +2 -3
  127. package/src/components/Tabs/FormBodyTabList.tsx +4 -4
  128. package/src/hooks/useDecimalCalculatedExpression.ts +2 -2
  129. package/src/hooks/useHidden.ts +4 -4
  130. package/src/hooks/useInitialiseGroupTable.ts +3 -3
  131. package/src/hooks/useInitialiseRenderer.ts +17 -18
  132. package/src/hooks/useIntegerCalculatedExpression.ts +2 -2
  133. package/src/hooks/useStringCalculatedExpression.ts +2 -2
  134. package/src/hooks/useTerminologyServerQuery.ts +3 -4
  135. package/src/hooks/useValueSetCodings.ts +10 -12
  136. package/src/index.ts +19 -20
  137. package/src/interfaces/groupTable.interface.ts +1 -1
  138. package/src/stores/index.ts +7 -3
  139. package/src/stores/questionnaireResponseStore.ts +83 -0
  140. package/src/stores/{useQuestionnaireStore.ts → questionnaireStore.ts} +7 -6
  141. package/src/stores/smartConfigStore.ts +45 -0
  142. package/src/stores/{useTerminologyServerStore.ts → terminologyServerStore.ts} +5 -4
  143. package/src/stories/MedicalHistoryTable.stories.tsx +61 -0
  144. package/src/stories/SmartFormsRenderer.stories.ts +15 -5
  145. package/src/stories/assets/QItems-and-QRItems/QR_GTableMedicalHistory.json +80 -0
  146. package/src/stories/assets/QItems-and-QRItems/Q_GTableMedicalHistory.json +109 -0
  147. package/src/stories/assets/Qs-and-QRs/QDev715.json +16081 -0
  148. package/src/theme/overrides/Table.ts +2 -1
  149. package/src/utils/calculatedExpression.ts +1 -2
  150. package/src/utils/groupTable.ts +37 -0
  151. package/src/stores/useQuestionnaireResponseStore.ts +0 -63
  152. package/src/stores/useSmartConfigStore.ts +0 -27
  153. /package/src/stories/assets/{Q715.json → Qs-and-QRs/Q715.json} +0 -0
  154. /package/src/stories/assets/{QTestGrid.json → Qs-and-QRs/QTestGrid.json} +0 -0
  155. /package/src/stories/assets/{R715.json → Qs-and-QRs/R715.json} +0 -0
  156. /package/src/stories/assets/{RTestGrid.json → Qs-and-QRs/RTestGrid.json} +0 -0
@@ -17,65 +17,105 @@
17
17
 
18
18
  import React from 'react';
19
19
  import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
20
- import { createEmptyQrGroup, updateQrItemsInGroup } from '../../../utils/qrItem';
21
- import SingleItem from '../SingleItem/SingleItem';
22
- import { getQrItemsIndex } from '../../../utils/mapItem';
23
- import { StandardTableCell } from './Table.styles';
24
20
  import type {
25
21
  PropsWithParentIsReadOnlyAttribute,
26
- PropsWithQrItemChangeHandler
22
+ PropsWithShowMinimalViewAttribute
27
23
  } from '../../../interfaces/renderProps.interface';
24
+ import { TableRowProps } from '@mui/material/TableRow';
25
+ import SelectRowButton from './SelectRowButton';
26
+ import GroupTableRowCells from './GroupTableRowCells';
27
+ import RemoveRowButton from './RemoveRowButton';
28
+ import { GroupTableRowModel } from '../../../interfaces/groupTable.interface';
29
+ import DragIndicator from '@mui/icons-material/DragIndicator';
30
+ import TableCell from '@mui/material/TableCell';
31
+ import Box from '@mui/material/Box';
32
+ import { Draggable } from 'react-beautiful-dnd';
33
+ import { StyledGroupTableRow } from './Table.styles';
28
34
 
29
- interface Props extends PropsWithQrItemChangeHandler, PropsWithParentIsReadOnlyAttribute {
30
- qItem: QuestionnaireItem;
31
- qrItem: QuestionnaireResponseItem | null;
35
+ interface GroupTableRowProps
36
+ extends PropsWithShowMinimalViewAttribute,
37
+ PropsWithParentIsReadOnlyAttribute,
38
+ TableRowProps {
39
+ nanoId: string;
40
+ index: number;
41
+ tableQItem: QuestionnaireItem;
42
+ answeredQrItem: QuestionnaireResponseItem;
43
+ nullableQrItem: QuestionnaireResponseItem | null;
44
+ readOnly: boolean;
45
+ hoverDisabled: boolean;
46
+ tableRows: GroupTableRowModel[];
47
+ itemIsSelected: boolean;
48
+ selectedIds: string[];
32
49
  qItemsIndexMap: Record<string, number>;
50
+ onRowChange: (newQrRow: QuestionnaireResponseItem, index: number) => void;
51
+ onRemoveRow: (index: number) => void;
52
+ onSelectRow: (nanoId: string) => void;
33
53
  }
34
54
 
35
- function GroupTableRow(props: Props) {
36
- const { qItem, qrItem, qItemsIndexMap, parentIsReadOnly, onQrItemChange } = props;
37
-
38
- const rowItems = qItem.item;
39
- const row = qrItem && qrItem.item ? qrItem : createEmptyQrGroup(qItem);
40
- const rowQrItems = row.item;
41
-
42
- if (!rowItems || !rowQrItems) {
43
- return null;
44
- }
45
-
46
- function handleQrRowItemChange(newQrRowItem: QuestionnaireResponseItem) {
47
- const qrRow: QuestionnaireResponseItem = { ...row };
48
- updateQrItemsInGroup(newQrRowItem, null, qrRow, qItemsIndexMap);
49
- onQrItemChange(qrRow);
50
- }
51
-
52
- const qrItemsByIndex = getQrItemsIndex(rowItems, rowQrItems, qItemsIndexMap);
55
+ function GroupTableRow(props: GroupTableRowProps) {
56
+ const {
57
+ nanoId,
58
+ index,
59
+ tableQItem,
60
+ answeredQrItem,
61
+ nullableQrItem,
62
+ readOnly,
63
+ hoverDisabled,
64
+ tableRows,
65
+ itemIsSelected,
66
+ qItemsIndexMap,
67
+ showMinimalView,
68
+ parentIsReadOnly,
69
+ onRowChange,
70
+ onRemoveRow,
71
+ onSelectRow
72
+ } = props;
53
73
 
54
74
  return (
55
- <>
56
- {rowItems.map((rowItem, index) => {
57
- const qrItem = qrItemsByIndex[index];
58
-
59
- if (Array.isArray(qrItem)) {
60
- return null;
61
- }
62
-
63
- return (
64
- <StandardTableCell key={index} numOfColumns={rowItems.length} isFirst={index === 0}>
65
- <SingleItem
66
- key={qItem.linkId}
67
- qItem={rowItem}
68
- qrItem={qrItem ?? null}
69
- isRepeated={true}
70
- isTabled={true}
71
- showMinimalView={true}
72
- parentIsReadOnly={parentIsReadOnly}
73
- onQrItemChange={handleQrRowItemChange}
75
+ <Draggable draggableId={nanoId} index={index}>
76
+ {(draggableProvided, snapshot) => (
77
+ <StyledGroupTableRow
78
+ itemIsDragged={snapshot.isDragging}
79
+ itemIsSelected={itemIsSelected}
80
+ hoverDisabled={hoverDisabled}
81
+ hover={!hoverDisabled}
82
+ ref={draggableProvided.innerRef}
83
+ {...draggableProvided.draggableProps}>
84
+ {showMinimalView ? null : (
85
+ <>
86
+ <TableCell padding="checkbox">
87
+ <Box
88
+ display="flex"
89
+ alignItems="center"
90
+ justifyContent="center"
91
+ {...draggableProvided.dragHandleProps}>
92
+ <DragIndicator fontSize="small" />
93
+ </Box>
94
+ </TableCell>
95
+ <SelectRowButton
96
+ isSelected={itemIsSelected}
97
+ onSelectItem={() => onSelectRow(nanoId)}
98
+ />
99
+ </>
100
+ )}
101
+ <GroupTableRowCells
102
+ qItem={tableQItem}
103
+ qrItem={answeredQrItem}
104
+ qItemsIndexMap={qItemsIndexMap}
105
+ parentIsReadOnly={parentIsReadOnly}
106
+ onQrItemChange={(newQrGroup) => onRowChange(newQrGroup, index)}
107
+ />
108
+ {showMinimalView ? null : (
109
+ <RemoveRowButton
110
+ nullableQrItem={nullableQrItem}
111
+ numOfRows={tableRows.length}
112
+ readOnly={readOnly}
113
+ onRemoveItem={() => onRemoveRow(index)}
74
114
  />
75
- </StandardTableCell>
76
- );
77
- })}
78
- </>
115
+ )}
116
+ </StyledGroupTableRow>
117
+ )}
118
+ </Draggable>
79
119
  );
80
120
  }
81
121
 
@@ -0,0 +1,87 @@
1
+ /*
2
+ * Copyright 2023 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import React from 'react';
19
+ import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
20
+ import { createEmptyQrGroup, updateQrItemsInGroup } from '../../../utils/qrItem';
21
+ import SingleItem from '../SingleItem/SingleItem';
22
+ import { getQrItemsIndex } from '../../../utils/mapItem';
23
+ import { StandardTableCell } from './Table.styles';
24
+ import type {
25
+ PropsWithParentIsReadOnlyAttribute,
26
+ PropsWithQrItemChangeHandler
27
+ } from '../../../interfaces/renderProps.interface';
28
+ import { TableRowProps } from '@mui/material/TableRow';
29
+
30
+ interface GroupTableRowCellsProps
31
+ extends PropsWithQrItemChangeHandler,
32
+ PropsWithParentIsReadOnlyAttribute,
33
+ TableRowProps {
34
+ qItem: QuestionnaireItem;
35
+ qrItem: QuestionnaireResponseItem | null;
36
+ qItemsIndexMap: Record<string, number>;
37
+ }
38
+
39
+ function GroupTableRowCells(props: GroupTableRowCellsProps) {
40
+ const { qItem, qrItem, qItemsIndexMap, parentIsReadOnly, onQrItemChange, ...tableRowProps } =
41
+ props;
42
+
43
+ const rowItems = qItem.item;
44
+ const row = qrItem && qrItem.item ? qrItem : createEmptyQrGroup(qItem);
45
+ const rowQrItems = row.item;
46
+
47
+ if (!rowItems || !rowQrItems) {
48
+ return null;
49
+ }
50
+
51
+ function handleQrRowItemChange(newQrRowItem: QuestionnaireResponseItem) {
52
+ const qrRow: QuestionnaireResponseItem = { ...row };
53
+ updateQrItemsInGroup(newQrRowItem, null, qrRow, qItemsIndexMap);
54
+ onQrItemChange(qrRow);
55
+ }
56
+
57
+ const qrItemsByIndex = getQrItemsIndex(rowItems, rowQrItems, qItemsIndexMap);
58
+
59
+ return (
60
+ <>
61
+ {rowItems.map((rowItem, index) => {
62
+ const qrItem = qrItemsByIndex[index];
63
+
64
+ if (Array.isArray(qrItem)) {
65
+ return null;
66
+ }
67
+
68
+ return (
69
+ <StandardTableCell key={index} numOfColumns={rowItems.length} isFirst={index === 0}>
70
+ <SingleItem
71
+ key={qItem.linkId}
72
+ qItem={rowItem}
73
+ qrItem={qrItem ?? null}
74
+ isRepeated={true}
75
+ isTabled={true}
76
+ showMinimalView={true}
77
+ parentIsReadOnly={parentIsReadOnly}
78
+ onQrItemChange={handleQrRowItemChange}
79
+ />
80
+ </StandardTableCell>
81
+ );
82
+ })}
83
+ </>
84
+ );
85
+ }
86
+
87
+ export default GroupTableRowCells;
@@ -0,0 +1,169 @@
1
+ /*
2
+ * Copyright 2023 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import React from 'react';
19
+ import { QGroupContainerBox } from '../../Box.styles';
20
+ import TableContainer from '@mui/material/TableContainer';
21
+ import Paper from '@mui/material/Paper';
22
+ import Table from '@mui/material/Table';
23
+ import TableHead from '@mui/material/TableHead';
24
+ import TableRow from '@mui/material/TableRow';
25
+ import { HeaderTableCell } from './Table.styles';
26
+ import TableCell from '@mui/material/TableCell';
27
+ import TableBody from '@mui/material/TableBody';
28
+ import Typography from '@mui/material/Typography';
29
+ import LabelWrapper from '../ItemParts/ItemLabelWrapper';
30
+ import Divider from '@mui/material/Divider';
31
+ import AddRowButton from './AddRowButton';
32
+ import { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
33
+ import {
34
+ PropsWithParentIsReadOnlyAttribute,
35
+ PropsWithShowMinimalViewAttribute
36
+ } from '../../../interfaces/renderProps.interface';
37
+ import { GroupTableRowModel } from '../../../interfaces/groupTable.interface';
38
+ import GroupTableBody from './GroupTableBody';
39
+ import Checkbox from '@mui/material/Checkbox';
40
+
41
+ interface GroupTableViewProps
42
+ extends PropsWithShowMinimalViewAttribute,
43
+ PropsWithParentIsReadOnlyAttribute {
44
+ qItem: QuestionnaireItem;
45
+ qItemsIndexMap: Record<string, number>;
46
+ groupCardElevation: number;
47
+ readOnly: boolean;
48
+ tableRows: GroupTableRowModel[];
49
+ selectedIds: string[];
50
+ itemLabels: string[];
51
+ onAddRow: () => void;
52
+ onRowChange: (newQrRow: QuestionnaireResponseItem, index: number) => void;
53
+ onRemoveRow: (index: number) => void;
54
+ onSelectRow: (nanoId: string) => void;
55
+ onSelectAll: () => void;
56
+ onReorderRows: (newTableRows: GroupTableRowModel[]) => void;
57
+ }
58
+
59
+ function GroupTableView(props: GroupTableViewProps) {
60
+ const {
61
+ qItem,
62
+ qItemsIndexMap,
63
+ groupCardElevation,
64
+ readOnly,
65
+ tableRows,
66
+ selectedIds,
67
+ itemLabels,
68
+ showMinimalView,
69
+ parentIsReadOnly,
70
+ onAddRow,
71
+ onRowChange,
72
+ onRemoveRow,
73
+ onSelectRow,
74
+ onSelectAll,
75
+ onReorderRows
76
+ } = props;
77
+
78
+ if (showMinimalView) {
79
+ return (
80
+ <QGroupContainerBox cardElevation={groupCardElevation} isRepeated={false} py={1}>
81
+ <TableContainer component={Paper} elevation={groupCardElevation}>
82
+ <Table size="small">
83
+ <TableHead>
84
+ <TableRow>
85
+ {itemLabels.map((itemLabel) => (
86
+ <HeaderTableCell key={itemLabel} size="medium">
87
+ {itemLabel}
88
+ </HeaderTableCell>
89
+ ))}
90
+ <TableCell />
91
+ </TableRow>
92
+ </TableHead>
93
+ <TableBody>
94
+ <GroupTableBody
95
+ tableQItem={qItem}
96
+ readOnly={readOnly}
97
+ tableRows={tableRows}
98
+ selectedIds={selectedIds}
99
+ qItemsIndexMap={qItemsIndexMap}
100
+ showMinimalView={showMinimalView}
101
+ parentIsReadOnly={parentIsReadOnly}
102
+ onRowChange={onRowChange}
103
+ onRemoveRow={onRemoveRow}
104
+ onSelectRow={onSelectRow}
105
+ onReorderRows={onReorderRows}
106
+ />
107
+ </TableBody>
108
+ </Table>
109
+ </TableContainer>
110
+ </QGroupContainerBox>
111
+ );
112
+ }
113
+
114
+ return (
115
+ <QGroupContainerBox cardElevation={groupCardElevation} isRepeated={false} py={3}>
116
+ {groupCardElevation !== 1 ? (
117
+ <>
118
+ <Typography
119
+ fontSize={13}
120
+ variant="h6"
121
+ color={readOnly ? 'text.secondary' : 'text.primary'}>
122
+ <LabelWrapper qItem={qItem} readOnly={readOnly} />
123
+ </Typography>
124
+ <Divider sx={{ my: 1 }} light />
125
+ </>
126
+ ) : null}
127
+ <TableContainer component={Paper} elevation={groupCardElevation}>
128
+ <Table>
129
+ <caption>
130
+ <AddRowButton repeatGroups={tableRows} readOnly={readOnly} onAddItem={onAddRow} />
131
+ </caption>
132
+ <TableHead>
133
+ <TableRow>
134
+ <HeaderTableCell padding="checkbox" />
135
+ <HeaderTableCell padding="checkbox">
136
+ <Checkbox
137
+ color="primary"
138
+ size="small"
139
+ indeterminate={selectedIds.length > 0 && selectedIds.length < tableRows.length}
140
+ checked={tableRows.length > 0 && selectedIds.length === tableRows.length}
141
+ onChange={onSelectAll}
142
+ />
143
+ </HeaderTableCell>
144
+ {itemLabels.map((itemLabel) => (
145
+ <HeaderTableCell key={itemLabel}>{itemLabel}</HeaderTableCell>
146
+ ))}
147
+ <TableCell />
148
+ </TableRow>
149
+ </TableHead>
150
+ <GroupTableBody
151
+ tableQItem={qItem}
152
+ readOnly={readOnly}
153
+ tableRows={tableRows}
154
+ selectedIds={selectedIds}
155
+ qItemsIndexMap={qItemsIndexMap}
156
+ showMinimalView={showMinimalView}
157
+ parentIsReadOnly={parentIsReadOnly}
158
+ onRowChange={onRowChange}
159
+ onRemoveRow={onRemoveRow}
160
+ onSelectRow={onSelectRow}
161
+ onReorderRows={onReorderRows}
162
+ />
163
+ </Table>
164
+ </TableContainer>
165
+ </QGroupContainerBox>
166
+ );
167
+ }
168
+
169
+ export default GroupTableView;
@@ -23,22 +23,22 @@ import Tooltip from '@mui/material/Tooltip';
23
23
  import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
24
24
  import type { QuestionnaireResponseItem } from 'fhir/r4';
25
25
 
26
- interface DeleteRowButtonProps {
26
+ interface RemoveRowButtonProps {
27
27
  nullableQrItem: QuestionnaireResponseItem | null;
28
28
  numOfRows: number;
29
29
  readOnly: boolean;
30
- onDeleteItem: () => void;
30
+ onRemoveItem: () => void;
31
31
  }
32
32
 
33
- function DeleteRowButton(props: DeleteRowButtonProps) {
34
- const { nullableQrItem, numOfRows, readOnly, onDeleteItem } = props;
33
+ function RemoveRowButton(props: RemoveRowButtonProps) {
34
+ const { nullableQrItem, numOfRows, readOnly, onRemoveItem } = props;
35
35
 
36
36
  const isDisabled = nullableQrItem === null || numOfRows === 1 || readOnly;
37
37
  return (
38
38
  <DeleteButtonTableCell>
39
- <Tooltip title="Delete item">
39
+ <Tooltip title="Remove item">
40
40
  <span>
41
- <IconButton size="small" color="error" disabled={isDisabled} onClick={onDeleteItem}>
41
+ <IconButton size="small" color="error" disabled={isDisabled} onClick={onRemoveItem}>
42
42
  <RemoveCircleOutlineIcon fontSize="small" />
43
43
  </IconButton>
44
44
  </span>
@@ -47,4 +47,4 @@ function DeleteRowButton(props: DeleteRowButtonProps) {
47
47
  );
48
48
  }
49
49
 
50
- export default DeleteRowButton;
50
+ export default RemoveRowButton;
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Copyright 2023 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import React from 'react';
19
+ import Checkbox from '@mui/material/Checkbox';
20
+ import TableCell from '@mui/material/TableCell';
21
+
22
+ interface SelectRowButtonProps {
23
+ isSelected: boolean;
24
+ onSelectItem: () => void;
25
+ }
26
+
27
+ function SelectRowButton(props: SelectRowButtonProps) {
28
+ const { isSelected, onSelectItem } = props;
29
+
30
+ return (
31
+ <TableCell padding="checkbox">
32
+ <Checkbox color="primary" size="small" checked={isSelected} onChange={onSelectItem} />
33
+ </TableCell>
34
+ );
35
+ }
36
+
37
+ export default SelectRowButton;
@@ -17,6 +17,8 @@
17
17
 
18
18
  import { styled } from '@mui/material/styles';
19
19
  import TableCell from '@mui/material/TableCell';
20
+ import TableRow from '@mui/material/TableRow';
21
+ import { grey } from '@mui/material/colors';
20
22
 
21
23
  export const HeaderTableCell = styled(TableCell)(() => ({
22
24
  fontSize: 13,
@@ -50,3 +52,26 @@ export const GridAnswerTableCell = styled(TableCell, {
50
52
  paddingLeft: 5,
51
53
  paddingRight: 5
52
54
  }));
55
+
56
+ export const StyledGroupTableRow = styled(TableRow, {
57
+ shouldForwardProp: (prop) =>
58
+ prop !== 'itemIsDragged' && prop !== 'itemIsSelected' && prop !== 'hoverDisabled'
59
+ })<{ itemIsDragged: boolean; itemIsSelected: boolean; hoverDisabled: boolean }>(
60
+ ({ theme, itemIsDragged, itemIsSelected, hoverDisabled }) => ({
61
+ backgroundColor: itemIsSelected ? '#f4f8ff' : '#fff',
62
+ ...(hoverDisabled
63
+ ? {}
64
+ : {
65
+ '&.MuiTableRow-root:hover': {
66
+ backgroundColor: itemIsSelected ? '#e9f1ff' : grey['50']
67
+ }
68
+ }),
69
+ ...(itemIsDragged
70
+ ? {
71
+ boxShadow: theme.customShadows.z8,
72
+ opacity: 1,
73
+ backgroundColor: itemIsSelected ? '#edf4ff' : '#fafafa'
74
+ }
75
+ : {})
76
+ })
77
+ );
@@ -20,18 +20,17 @@ import Container from '@mui/material/Container';
20
20
  import Fade from '@mui/material/Fade';
21
21
  import FormTopLevelItem from './FormTopLevelItem';
22
22
  import type { QuestionnaireResponse, QuestionnaireResponseItem } from 'fhir/r4';
23
- import useQuestionnaireStore from '../../stores/useQuestionnaireStore';
24
- import useQuestionnaireResponseStore from '../../stores/useQuestionnaireResponseStore';
23
+ import { useQuestionnaireResponseStore, useQuestionnaireStore } from '../../stores';
25
24
  import cloneDeep from 'lodash.clonedeep';
26
25
  import { getQrItemsIndex, mapQItemsIndex } from '../../utils/mapItem';
27
26
  import { updateQrItemsInGroup } from '../../utils/qrItem';
28
27
  import type { QrRepeatGroup } from '../../interfaces/repeatGroup.interface';
29
28
 
30
29
  function BaseRenderer() {
31
- const sourceQuestionnaire = useQuestionnaireStore((state) => state.sourceQuestionnaire);
32
- const updateExpressions = useQuestionnaireStore((state) => state.updateExpressions);
33
- const updatableResponse = useQuestionnaireResponseStore((state) => state.updatableResponse);
34
- const updateResponse = useQuestionnaireResponseStore((state) => state.updateResponse);
30
+ const sourceQuestionnaire = useQuestionnaireStore.use.sourceQuestionnaire();
31
+ const updateExpressions = useQuestionnaireStore.use.updateExpressions();
32
+ const updatableResponse = useQuestionnaireResponseStore.use.updatableResponse();
33
+ const updateResponse = useQuestionnaireResponseStore.use.updateResponse();
35
34
 
36
35
  const qItemsIndexMap = useMemo(() => mapQItemsIndex(sourceQuestionnaire), [sourceQuestionnaire]);
37
36
 
@@ -21,7 +21,7 @@ import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
21
21
  import { getQrItemsIndex, mapQItemsIndex } from '../../utils/mapItem';
22
22
  import { createEmptyQrGroup, updateQrItemsInGroup } from '../../utils/qrItem';
23
23
  import type { PropsWithQrItemChangeHandler } from '../../interfaces/renderProps.interface';
24
- import useQuestionnaireStore from '../../stores/useQuestionnaireStore';
24
+ import { useQuestionnaireStore } from '../../stores';
25
25
  import FormBodySingleCollapsibleWrapper from './FormBodySingleCollapsibleWrapper';
26
26
 
27
27
  interface FormBodyCollapsibleProps extends PropsWithQrItemChangeHandler {
@@ -32,10 +32,9 @@ interface FormBodyCollapsibleProps extends PropsWithQrItemChangeHandler {
32
32
  function FormBodyCollapsibleWrapper(props: FormBodyCollapsibleProps) {
33
33
  const { topLevelQItem, topLevelQRItem, onQrItemChange } = props;
34
34
 
35
- const currentTab = useQuestionnaireStore((state) => state.currentTabIndex);
36
- const tabs = useQuestionnaireStore((state) => state.tabs);
37
-
38
- const switchTab = useQuestionnaireStore((state) => state.switchTab);
35
+ const tabs = useQuestionnaireStore.use.tabs();
36
+ const currentTab = useQuestionnaireStore.use.currentTabIndex();
37
+ const switchTab = useQuestionnaireStore.use.switchTab();
39
38
 
40
39
  const indexMap: Record<string, number> = useMemo(
41
40
  () => mapQItemsIndex(topLevelQItem),
@@ -25,7 +25,7 @@ import GroupItem from '../FormComponents/GroupItem/GroupItem';
25
25
  import { createEmptyQrGroup, updateQrItemsInGroup } from '../../utils/qrItem';
26
26
  import FormBodyTabListWrapper from '../Tabs/FormBodyTabListWrapper';
27
27
  import type { PropsWithQrItemChangeHandler } from '../../interfaces/renderProps.interface';
28
- import useQuestionnaireStore from '../../stores/useQuestionnaireStore';
28
+ import { useQuestionnaireStore } from '../../stores';
29
29
 
30
30
  interface FormBodyTabbedProps extends PropsWithQrItemChangeHandler {
31
31
  topLevelQItem: QuestionnaireItem;
@@ -35,8 +35,8 @@ interface FormBodyTabbedProps extends PropsWithQrItemChangeHandler {
35
35
  function FormBodyTabbed(props: FormBodyTabbedProps) {
36
36
  const { topLevelQItem, topLevelQRItem, onQrItemChange } = props;
37
37
 
38
- const tabs = useQuestionnaireStore((state) => state.tabs);
39
- const currentTab = useQuestionnaireStore((state) => state.currentTabIndex);
38
+ const tabs = useQuestionnaireStore.use.tabs();
39
+ const currentTab = useQuestionnaireStore.use.currentTabIndex();
40
40
 
41
41
  const indexMap: Record<string, number> = useMemo(
42
42
  () => mapQItemsIndex(topLevelQItem),
@@ -19,7 +19,7 @@ import React, { memo } from 'react';
19
19
  import IconButton from '@mui/material/IconButton';
20
20
  import Tooltip from '@mui/material/Tooltip';
21
21
  import CheckCircleIcon from '@mui/icons-material/CheckCircle';
22
- import useQuestionnaireStore from '../../stores/useQuestionnaireStore';
22
+ import { useQuestionnaireStore } from '../../stores';
23
23
 
24
24
  interface CompleteTabButtonProps {
25
25
  tabLinkId: string;
@@ -29,7 +29,7 @@ interface CompleteTabButtonProps {
29
29
  const CompleteTabButton = memo(function CompleteTabButton(props: CompleteTabButtonProps) {
30
30
  const { tabLinkId, tabIsMarkedAsComplete } = props;
31
31
 
32
- const markTabAsComplete = useQuestionnaireStore((state) => state.markTabAsComplete);
32
+ const markTabAsComplete = useQuestionnaireStore.use.markTabAsComplete();
33
33
 
34
34
  return (
35
35
  <Tooltip title={tabIsMarkedAsComplete ? 'Mark as incomplete' : 'Complete tab'}>
@@ -20,8 +20,7 @@ import Box from '@mui/material/Box';
20
20
  import ListItemButton from '@mui/material/ListItemButton';
21
21
  import ListItemText from '@mui/material/ListItemText';
22
22
  import Typography from '@mui/material/Typography';
23
-
24
- import useQuestionnaireStore from '../../stores/useQuestionnaireStore';
23
+ import { useQuestionnaireStore } from '../../stores';
25
24
  import type { QuestionnaireItem } from 'fhir/r4';
26
25
  import ContextDisplayItem from '../FormComponents/ItemParts/ContextDisplayItem';
27
26
 
@@ -35,7 +34,7 @@ interface FormBodySingleTabProps {
35
34
  const FormBodySingleTab = memo(function FormBodySingleTab(props: FormBodySingleTabProps) {
36
35
  const { contextDisplayItems, selected, tabLabel, listIndex } = props;
37
36
 
38
- const switchTab = useQuestionnaireStore((state) => state.switchTab);
37
+ const switchTab = useQuestionnaireStore.use.switchTab();
39
38
 
40
39
  function handleTabClick() {
41
40
  switchTab(listIndex);
@@ -22,7 +22,7 @@ import { getShortText } from '../../utils/itemControl';
22
22
  import type { QuestionnaireItem } from 'fhir/r4';
23
23
  import FormBodySingleTab from './FormBodySingleTab';
24
24
  import type { Tabs } from '../../interfaces/tab.interface';
25
- import useQuestionnaireStore from '../../stores/useQuestionnaireStore';
25
+ import { useQuestionnaireStore } from '../../stores';
26
26
  import { isTabHidden } from '../../utils/tabs';
27
27
 
28
28
  interface FormBodyTabListProps {
@@ -37,9 +37,9 @@ const FormBodyTabList = memo(function FormBodyTabList(props: FormBodyTabListProp
37
37
  const { topLevelItems, currentTabIndex, tabs, completedTabsCollapsed, allContextDisplayItems } =
38
38
  props;
39
39
 
40
- const enableWhenIsActivated = useQuestionnaireStore((state) => state.enableWhenIsActivated);
41
- const enableWhenItems = useQuestionnaireStore((state) => state.enableWhenItems);
42
- const enableWhenExpressions = useQuestionnaireStore((state) => state.enableWhenExpressions);
40
+ const enableWhenIsActivated = useQuestionnaireStore.use.enableWhenIsActivated();
41
+ const enableWhenItems = useQuestionnaireStore.use.enableWhenItems();
42
+ const enableWhenExpressions = useQuestionnaireStore.use.enableWhenExpressions();
43
43
 
44
44
  return (
45
45
  <TransitionGroup>