@pega/react-sdk-overrides 0.23.6

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 (220) hide show
  1. package/lib/designSystemExtensions/CaseSummaryFields/CaseSummaryFields.css +19 -0
  2. package/lib/designSystemExtensions/CaseSummaryFields/CaseSummaryFields.tsx +156 -0
  3. package/lib/designSystemExtensions/CaseSummaryFields/index.tsx +1 -0
  4. package/lib/designSystemExtensions/DetailsFields/DetailsFields.tsx +154 -0
  5. package/lib/designSystemExtensions/DetailsFields/index.tsx +1 -0
  6. package/lib/designSystemExtensions/FieldGroup/FieldGroup.tsx +113 -0
  7. package/lib/designSystemExtensions/FieldGroup/index.tsx +1 -0
  8. package/lib/designSystemExtensions/FieldGroupList/FieldGroupList.tsx +53 -0
  9. package/lib/designSystemExtensions/FieldGroupList/index.tsx +1 -0
  10. package/lib/designSystemExtensions/FieldValueList/FieldValueList.tsx +106 -0
  11. package/lib/designSystemExtensions/FieldValueList/index.tsx +1 -0
  12. package/lib/designSystemExtensions/Operator/Operator.tsx +195 -0
  13. package/lib/designSystemExtensions/Operator/index.tsx +1 -0
  14. package/lib/designSystemExtensions/Pulse/Pulse.tsx +31 -0
  15. package/lib/designSystemExtensions/Pulse/index.tsx +1 -0
  16. package/lib/forms/AutoComplete/AutoComplete.tsx +183 -0
  17. package/lib/forms/AutoComplete/index.tsx +1 -0
  18. package/lib/forms/CancelAlert/CancelAlert.css +24 -0
  19. package/lib/forms/CancelAlert/CancelAlert.tsx +126 -0
  20. package/lib/forms/CancelAlert/index.tsx +1 -0
  21. package/lib/forms/Checkbox/Checkbox.tsx +68 -0
  22. package/lib/forms/Checkbox/index.tsx +1 -0
  23. package/lib/forms/Currency/Currency.tsx +89 -0
  24. package/lib/forms/Currency/index.tsx +1 -0
  25. package/lib/forms/Date/Date.tsx +79 -0
  26. package/lib/forms/Date/index.tsx +1 -0
  27. package/lib/forms/DateTime/DateTime.tsx +75 -0
  28. package/lib/forms/DateTime/index.tsx +1 -0
  29. package/lib/forms/Decimal/Decimal.tsx +51 -0
  30. package/lib/forms/Decimal/index.tsx +1 -0
  31. package/lib/forms/Dropdown/Dropdown.tsx +82 -0
  32. package/lib/forms/Dropdown/index.tsx +1 -0
  33. package/lib/forms/Email/Email.tsx +68 -0
  34. package/lib/forms/Email/index.tsx +1 -0
  35. package/lib/forms/Integer/Integer.tsx +77 -0
  36. package/lib/forms/Integer/index.tsx +1 -0
  37. package/lib/forms/Percentage/Percentage.tsx +82 -0
  38. package/lib/forms/Percentage/index.tsx +1 -0
  39. package/lib/forms/Phone/Phone.tsx +90 -0
  40. package/lib/forms/Phone/index.tsx +1 -0
  41. package/lib/forms/RadioButtons/RadioButtons.tsx +73 -0
  42. package/lib/forms/RadioButtons/index.tsx +1 -0
  43. package/lib/forms/SemanticLink/SemanticLink.tsx +69 -0
  44. package/lib/forms/SemanticLink/index.tsx +1 -0
  45. package/lib/forms/SemanticLink/utils.ts +51 -0
  46. package/lib/forms/TextArea/TextArea.tsx +66 -0
  47. package/lib/forms/TextArea/index.tsx +1 -0
  48. package/lib/forms/TextContent/TextContent.tsx +40 -0
  49. package/lib/forms/TextContent/index.tsx +1 -0
  50. package/lib/forms/TextInput/TextInput.tsx +61 -0
  51. package/lib/forms/TextInput/index.tsx +1 -0
  52. package/lib/forms/Time/Time.tsx +71 -0
  53. package/lib/forms/Time/index.tsx +1 -0
  54. package/lib/forms/URL/URL.tsx +53 -0
  55. package/lib/forms/URL/index.tsx +1 -0
  56. package/lib/forms/UserReference/UserReference.tsx +197 -0
  57. package/lib/forms/UserReference/UserReferenceUtils.ts +13 -0
  58. package/lib/forms/UserReference/index.tsx +1 -0
  59. package/lib/helpers/auth.js +483 -0
  60. package/lib/helpers/authManager.js +630 -0
  61. package/lib/helpers/config_access.js +268 -0
  62. package/lib/helpers/data_page.ts +24 -0
  63. package/lib/helpers/event-utils.js +20 -0
  64. package/lib/helpers/field-group-utils.js +61 -0
  65. package/lib/helpers/formatters/Boolean.js +38 -0
  66. package/lib/helpers/formatters/Currency.js +74 -0
  67. package/lib/helpers/formatters/CurrencyMap.js +908 -0
  68. package/lib/helpers/formatters/Date.js +77 -0
  69. package/lib/helpers/formatters/common.js +10 -0
  70. package/lib/helpers/formatters/index.js +120 -0
  71. package/lib/helpers/utils.ts +334 -0
  72. package/lib/helpers/versionHelpers.ts +50 -0
  73. package/lib/infra/ActionButtons/ActionButtons.tsx +70 -0
  74. package/lib/infra/ActionButtons/index.tsx +1 -0
  75. package/lib/infra/Assignment/Assignment.tsx +301 -0
  76. package/lib/infra/Assignment/index.tsx +1 -0
  77. package/lib/infra/AssignmentCard/AssignmentCard.tsx +47 -0
  78. package/lib/infra/AssignmentCard/index.tsx +1 -0
  79. package/lib/infra/Attachment/Attachment.css +18 -0
  80. package/lib/infra/Attachment/Attachment.tsx +404 -0
  81. package/lib/infra/Attachment/AttachmentUtils.js +71 -0
  82. package/lib/infra/Attachment/index.tsx +1 -0
  83. package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +511 -0
  84. package/lib/infra/Containers/FlowContainer/helpers.js +147 -0
  85. package/lib/infra/Containers/FlowContainer/index.tsx +1 -0
  86. package/lib/infra/Containers/ModalViewContainer/ModalViewContainer.tsx +320 -0
  87. package/lib/infra/Containers/ModalViewContainer/index.tsx +1 -0
  88. package/lib/infra/Containers/ViewContainer/ViewContainer.tsx +216 -0
  89. package/lib/infra/Containers/ViewContainer/index.tsx +1 -0
  90. package/lib/infra/DashboardFilter/DashboardFilter.tsx +180 -0
  91. package/lib/infra/DashboardFilter/filterUtils.tsx +188 -0
  92. package/lib/infra/DashboardFilter/index.tsx +1 -0
  93. package/lib/infra/DeferLoad/DeferLoad.tsx +175 -0
  94. package/lib/infra/DeferLoad/index.tsx +1 -0
  95. package/lib/infra/ErrorBoundary/ErrorBoundary.tsx +103 -0
  96. package/lib/infra/ErrorBoundary/index.tsx +1 -0
  97. package/lib/infra/MultiStep/MultiStep.css +261 -0
  98. package/lib/infra/MultiStep/MultiStep.tsx +225 -0
  99. package/lib/infra/MultiStep/index.tsx +1 -0
  100. package/lib/infra/NavBar/NavBar.css +170 -0
  101. package/lib/infra/NavBar/NavBar.tsx +393 -0
  102. package/lib/infra/NavBar/index.tsx +1 -0
  103. package/lib/infra/Reference/Reference.tsx +58 -0
  104. package/lib/infra/Reference/index.tsx +1 -0
  105. package/lib/infra/Region/Region.tsx +17 -0
  106. package/lib/infra/Region/index.tsx +1 -0
  107. package/lib/infra/RootContainer/RootContainer.tsx +336 -0
  108. package/lib/infra/RootContainer/index.tsx +1 -0
  109. package/lib/infra/Stages/Stages.tsx +120 -0
  110. package/lib/infra/Stages/index.tsx +1 -0
  111. package/lib/infra/ToDo/ToDo.css +87 -0
  112. package/lib/infra/ToDo/ToDo.tsx +285 -0
  113. package/lib/infra/ToDo/index.tsx +1 -0
  114. package/lib/infra/VerticalTabs/LeftAlignVerticalTab.tsx +27 -0
  115. package/lib/infra/VerticalTabs/VerticalTabs.tsx +75 -0
  116. package/lib/infra/VerticalTabs/index.tsx +1 -0
  117. package/lib/infra/View/View.css +8 -0
  118. package/lib/infra/View/View.tsx +175 -0
  119. package/lib/infra/View/index.tsx +1 -0
  120. package/lib/templates/AppShell/AppShell.css +40 -0
  121. package/lib/templates/AppShell/AppShell.tsx +439 -0
  122. package/lib/templates/AppShell/index.tsx +1 -0
  123. package/lib/templates/CaseSummary/CaseSummary.tsx +50 -0
  124. package/lib/templates/CaseSummary/index.tsx +1 -0
  125. package/lib/templates/CaseView/CaseView.tsx +261 -0
  126. package/lib/templates/CaseView/CaseViewActionsMenu.tsx +73 -0
  127. package/lib/templates/CaseView/index.tsx +1 -0
  128. package/lib/templates/DataReference/DataReference.tsx +290 -0
  129. package/lib/templates/DataReference/index.tsx +1 -0
  130. package/lib/templates/DefaultForm/DefaultForm.css +25 -0
  131. package/lib/templates/DefaultForm/DefaultForm.tsx +52 -0
  132. package/lib/templates/DefaultForm/index.tsx +1 -0
  133. package/lib/templates/Details/Details/Details.tsx +35 -0
  134. package/lib/templates/Details/Details/index.tsx +1 -0
  135. package/lib/templates/Details/DetailsSubTabs/DetailsSubTabs.tsx +65 -0
  136. package/lib/templates/Details/DetailsSubTabs/index.tsx +1 -0
  137. package/lib/templates/Details/DetailsThreeColumn/DetailsThreeColumn.tsx +45 -0
  138. package/lib/templates/Details/DetailsThreeColumn/index.tsx +1 -0
  139. package/lib/templates/Details/DetailsTwoColumn/DetailsTwoColumn.tsx +43 -0
  140. package/lib/templates/Details/DetailsTwoColumn/index.tsx +1 -0
  141. package/lib/templates/FieldGroupTemplate/FieldGroupTemplate.tsx +94 -0
  142. package/lib/templates/FieldGroupTemplate/index.tsx +1 -0
  143. package/lib/templates/InlineDashboard/InlineDashboard.tsx +72 -0
  144. package/lib/templates/InlineDashboard/index.tsx +1 -0
  145. package/lib/templates/InlineDashboardPage/InlineDashboardPage.tsx +41 -0
  146. package/lib/templates/InlineDashboardPage/index.tsx +1 -0
  147. package/lib/templates/ListPage/ListPage.tsx +20 -0
  148. package/lib/templates/ListPage/index.tsx +1 -0
  149. package/lib/templates/ListView/ListView.css +10 -0
  150. package/lib/templates/ListView/ListView.tsx +1230 -0
  151. package/lib/templates/ListView/index.tsx +1 -0
  152. package/lib/templates/MultiReferenceReadOnly/MultiReferenceReadOnly.tsx +42 -0
  153. package/lib/templates/MultiReferenceReadOnly/index.tsx +1 -0
  154. package/lib/templates/NarrowWide/NarrowWide/NarrowWide.css +21 -0
  155. package/lib/templates/NarrowWide/NarrowWide/NarrowWide.tsx +35 -0
  156. package/lib/templates/NarrowWide/NarrowWide/index.tsx +1 -0
  157. package/lib/templates/NarrowWide/NarrowWideDetails/NarrowWideDetails.tsx +53 -0
  158. package/lib/templates/NarrowWide/NarrowWideDetails/index.tsx +1 -0
  159. package/lib/templates/NarrowWide/NarrowWideForm/NarrowWideForm.css +21 -0
  160. package/lib/templates/NarrowWide/NarrowWideForm/NarrowWideForm.tsx +24 -0
  161. package/lib/templates/NarrowWide/NarrowWideForm/index.tsx +1 -0
  162. package/lib/templates/NarrowWide/NarrowWidePage/NarrowWidePage.tsx +38 -0
  163. package/lib/templates/NarrowWide/NarrowWidePage/index.tsx +1 -0
  164. package/lib/templates/OneColumn/OneColumn/OneColumn.tsx +32 -0
  165. package/lib/templates/OneColumn/OneColumn/index.tsx +1 -0
  166. package/lib/templates/OneColumn/OneColumnPage/OneColumnPage.tsx +24 -0
  167. package/lib/templates/OneColumn/OneColumnPage/index.tsx +1 -0
  168. package/lib/templates/OneColumn/OneColumnTab/OneColumnTab.tsx +17 -0
  169. package/lib/templates/OneColumn/OneColumnTab/index.tsx +1 -0
  170. package/lib/templates/PromotedFilters/PromotedFilters.css +7 -0
  171. package/lib/templates/PromotedFilters/PromotedFilters.tsx +160 -0
  172. package/lib/templates/PromotedFilters/index.tsx +1 -0
  173. package/lib/templates/SimpleTable/SimpleTable/SimpleTable.tsx +28 -0
  174. package/lib/templates/SimpleTable/SimpleTable/index.tsx +1 -0
  175. package/lib/templates/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +719 -0
  176. package/lib/templates/SimpleTable/SimpleTableManual/index.tsx +1 -0
  177. package/lib/templates/SimpleTable/SimpleTableSelect/SimpleTableSelect.tsx +129 -0
  178. package/lib/templates/SimpleTable/SimpleTableSelect/index.tsx +1 -0
  179. package/lib/templates/SimpleTable/helpers.ts +360 -0
  180. package/lib/templates/SingleReferenceReadOnly/SingleReferenceReadOnly.tsx +66 -0
  181. package/lib/templates/SingleReferenceReadOnly/index.tsx +1 -0
  182. package/lib/templates/SubTabs/SubTabs.tsx +65 -0
  183. package/lib/templates/SubTabs/index.tsx +1 -0
  184. package/lib/templates/SubTabs/tabUtils.ts +73 -0
  185. package/lib/templates/TwoColumn/TwoColumn/TwoColumn.css +13 -0
  186. package/lib/templates/TwoColumn/TwoColumn/TwoColumn.tsx +58 -0
  187. package/lib/templates/TwoColumn/TwoColumn/index.tsx +1 -0
  188. package/lib/templates/TwoColumn/TwoColumnPage/TwoColumnPage.tsx +25 -0
  189. package/lib/templates/TwoColumn/TwoColumnPage/index.tsx +1 -0
  190. package/lib/templates/TwoColumn/TwoColumnTab/TwoColumnTab.css +12 -0
  191. package/lib/templates/TwoColumn/TwoColumnTab/TwoColumnTab.tsx +55 -0
  192. package/lib/templates/TwoColumn/TwoColumnTab/index.tsx +1 -0
  193. package/lib/templates/WideNarrow/WideNarrow/WideNarrow.css +21 -0
  194. package/lib/templates/WideNarrow/WideNarrow/WideNarrow.tsx +35 -0
  195. package/lib/templates/WideNarrow/WideNarrow/index.tsx +1 -0
  196. package/lib/templates/WideNarrow/WideNarrowDetails/WideNarrowDetails.tsx +54 -0
  197. package/lib/templates/WideNarrow/WideNarrowDetails/index.tsx +1 -0
  198. package/lib/templates/WideNarrow/WideNarrowForm/WideNarrowForm.css +21 -0
  199. package/lib/templates/WideNarrow/WideNarrowForm/WideNarrowForm.tsx +24 -0
  200. package/lib/templates/WideNarrow/WideNarrowForm/index.tsx +1 -0
  201. package/lib/templates/WideNarrow/WideNarrowPage/WideNarrowPage.tsx +38 -0
  202. package/lib/templates/WideNarrow/WideNarrowPage/index.tsx +1 -0
  203. package/lib/templates/utils.ts +23 -0
  204. package/lib/widgets/AppAnnouncement/AppAnnouncement.tsx +67 -0
  205. package/lib/widgets/AppAnnouncement/index.tsx +1 -0
  206. package/lib/widgets/CaseHistory/CaseHistory.tsx +169 -0
  207. package/lib/widgets/CaseHistory/index.tsx +1 -0
  208. package/lib/widgets/FileUtility/ActionButtonsForFileUtil.css +27 -0
  209. package/lib/widgets/FileUtility/ActionButtonsForFileUtil.tsx +22 -0
  210. package/lib/widgets/FileUtility/FileUtility.css +117 -0
  211. package/lib/widgets/FileUtility/FileUtility.tsx +567 -0
  212. package/lib/widgets/FileUtility/index.tsx +0 -0
  213. package/lib/widgets/Followers/Followers.tsx +43 -0
  214. package/lib/widgets/Followers/index.tsx +1 -0
  215. package/lib/widgets/SummaryItem/SummaryItem.css +78 -0
  216. package/lib/widgets/SummaryItem/SummaryItem.tsx +80 -0
  217. package/lib/widgets/SummaryItem/index.tsx +1 -0
  218. package/lib/widgets/SummaryList/SummaryList.tsx +12 -0
  219. package/lib/widgets/SummaryList/index.tsx +1 -0
  220. package/package.json +14 -0
@@ -0,0 +1,1230 @@
1
+ /* eslint-disable no-plusplus */
2
+ /* eslint-disable guard-for-in */
3
+ /* eslint-disable @typescript-eslint/no-use-before-define */
4
+ import React, { useState, useEffect, useRef } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
7
+ import { Utils } from '@pega/react-sdk-components/lib/components/helpers/utils';
8
+ import Table from '@material-ui/core/Table';
9
+ import TableBody from '@material-ui/core/TableBody';
10
+ import TableCell from '@material-ui/core/TableCell';
11
+ import TableContainer from '@material-ui/core/TableContainer';
12
+ import TableHead from '@material-ui/core/TableHead';
13
+ import TablePagination from '@material-ui/core/TablePagination';
14
+ import TableRow from '@material-ui/core/TableRow';
15
+ import TableSortLabel from '@material-ui/core/TableSortLabel';
16
+ import Paper from '@material-ui/core/Paper';
17
+ import MoreIcon from '@material-ui/icons/MoreVert';
18
+ import FilterListIcon from '@material-ui/icons/FilterList';
19
+ import SubjectIcon from '@material-ui/icons/Subject';
20
+ import SearchIcon from '@material-ui/icons/Search';
21
+ import TextField from '@material-ui/core/TextField';
22
+ import Grid from '@material-ui/core/Grid';
23
+ import Menu from '@material-ui/core/Menu';
24
+ import MenuItem from '@material-ui/core/MenuItem';
25
+ import Dialog from '@material-ui/core/Dialog';
26
+ import DialogActions from '@material-ui/core/DialogActions';
27
+ import DialogContent from '@material-ui/core/DialogContent';
28
+ import DialogTitle from '@material-ui/core/DialogTitle';
29
+ import Select from '@material-ui/core/Select';
30
+ import Button from '@material-ui/core/Button';
31
+ import Link from '@material-ui/core/Link';
32
+ import Typography from '@material-ui/core/Typography';
33
+ import Snackbar from '@material-ui/core/Snackbar';
34
+ import IconButton from '@material-ui/core/IconButton';
35
+ import CloseIcon from '@material-ui/icons/Close';
36
+ import { Radio } from '@material-ui/core';
37
+ import Checkbox from '@material-ui/core/Checkbox';
38
+ import { filterData } from '@pega/react-sdk-components/lib/components/templates/SimpleTable/helpers';
39
+ import './ListView.css';
40
+
41
+ const SELECTION_MODE = { SINGLE: 'single', MULTI: 'multi' };
42
+ declare const PCore: any;
43
+
44
+ let myRows: Array<any>;
45
+ let myDisplayColumnList: Array<any>;
46
+
47
+ let menuColumnId = '';
48
+ let menuColumnType = '';
49
+ let menuColumnLabel = '';
50
+
51
+ let sortColumnId: any;
52
+
53
+ // let dialogContainsFilter: string = "contains";
54
+ // let dialogContainsValue: string = "";
55
+ // let dialogDateFilter: string = "notequal";
56
+ // let dialogDateValue: string = "";
57
+
58
+ const filterByColumns: Array<any> = [];
59
+
60
+ export default function ListView(props) {
61
+ const { getPConnect, bInForm } = props;
62
+ const { globalSearch, presets, referenceList, rowClickAction, selectionMode, referenceType, payload, parameters, compositeKeys } = props;
63
+
64
+ const thePConn = getPConnect();
65
+ const componentConfig = thePConn.getComponentConfig();
66
+ const resolvedConfigProps = thePConn.getConfigProps();
67
+
68
+ /** By default, pyGUID is used for Data classes and pyID is for Work classes as row-id/key */
69
+ const defRowID = referenceType === 'Case' ? 'pyID' : 'pyGUID';
70
+
71
+ /** If compositeKeys is defined, use dynamic value, else fallback to pyID or pyGUID. */
72
+ const rowID = compositeKeys && compositeKeys[0] ? compositeKeys[0] : defRowID;
73
+
74
+ const [arRows, setRows] = useState<Array<any>>([]);
75
+ const [arColumns, setColumns] = useState<Array<any>>([]);
76
+
77
+ const [order, setOrder] = useState<Order>('asc');
78
+ const [orderBy, setOrderBy] = useState<keyof any>('');
79
+
80
+ const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
81
+ const [open, setOpen] = useState(false);
82
+
83
+ const [showSnackbar, setShowSnackbar] = useState(false);
84
+ const [snackbarMessage, setSnackbarMessage] = useState('');
85
+
86
+ const [selectedValue, setSelectedValue] = useState('');
87
+
88
+ // This basically will hold the list of all current filters
89
+ const filters = useRef({});
90
+
91
+ // Will contain the list of columns specific for an instance
92
+ let columnList: any = useRef([]);
93
+ let dashboardFilterPayload: any ;
94
+ // Will be sent in the dashboardFilterPayload
95
+ let selectParam: Array<any> = [];
96
+
97
+ // dataview parameters coming from the ListPage
98
+ // This constant will also be used for parameters coming from from other components/utility fnctions in future
99
+ const dataViewParameters = parameters;
100
+
101
+ const useStyles = makeStyles((theme: Theme) =>
102
+ createStyles({
103
+ root: {
104
+ width: '100%'
105
+ },
106
+ paper: {
107
+ width: '100%',
108
+ marginTop: theme.spacing(2),
109
+ marginBottom: theme.spacing(2)
110
+ },
111
+ search: {
112
+ padding: '5px 5px'
113
+ },
114
+ table: {
115
+ minWidth: 750
116
+ },
117
+ tableInForm: {
118
+ minWidth: 750,
119
+ maxHeight: 550,
120
+ overflow: 'auto'
121
+ },
122
+ moreIcon: {
123
+ verticalAlign: 'bottom'
124
+ },
125
+ filteredIcon: {
126
+ verticalAlign: 'bottom'
127
+ },
128
+ cell: {
129
+ whiteSpace: 'nowrap'
130
+ },
131
+ visuallyHidden: {
132
+ border: 0,
133
+ clip: 'rect(0 0 0 0)',
134
+ height: 1,
135
+ margin: -1,
136
+ overflow: 'hidden',
137
+ padding: 0,
138
+ position: 'absolute',
139
+ top: 20,
140
+ width: 1
141
+ },
142
+ title: {
143
+ marginTop: theme.spacing(1),
144
+ marginLeft: theme.spacing(1)
145
+ }
146
+ })
147
+ );
148
+
149
+ const classes = useStyles();
150
+
151
+ const handleRequestSort = (event: React.MouseEvent<unknown>, property: keyof any) => {
152
+ const isAsc = orderBy === property && order === 'asc';
153
+ setOrder(isAsc ? 'desc' : 'asc');
154
+ setOrderBy(property);
155
+ };
156
+
157
+ const createSortHandler = (property: keyof any) => (event: React.MouseEvent<unknown>) => {
158
+ sortColumnId = property;
159
+ handleRequestSort(event, property);
160
+ };
161
+
162
+ function descendingComparator<T>(a: T, b: T, orderedBy: keyof T) {
163
+ if (b[orderedBy] < a[orderedBy]) {
164
+ return -1;
165
+ }
166
+ if (b[orderedBy] > a[orderedBy]) {
167
+ return 1;
168
+ }
169
+ return 0;
170
+ }
171
+
172
+ type Order = 'asc' | 'desc';
173
+
174
+ function getComparator<Key extends keyof any>(
175
+ theOrder: Order,
176
+ orderedBy: Key
177
+ // eslint-disable-next-line no-unused-vars
178
+ ): (a: { [key in Key]: number | string }, b: { [key in Key]: number | string }) => number {
179
+ return theOrder === 'desc'
180
+ ? (a, b) => descendingComparator(a, b, orderedBy)
181
+ : (a, b) => -descendingComparator(a, b, orderedBy);
182
+ }
183
+
184
+ // eslint-disable-next-line no-unused-vars
185
+ function stableSort<T>(array: Array<T>, comparator: (a: T, b: T) => number) {
186
+ const stabilizedThis = array.map((el, index) => [el, index] as [T, number]);
187
+ stabilizedThis.sort((a, b) => {
188
+ // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow
189
+ const order = comparator(a[0], b[0]);
190
+ if (order !== 0) return order;
191
+ return a[1] - b[1];
192
+ });
193
+ return stabilizedThis.map(el => el[0]);
194
+ }
195
+
196
+ const [page, setPage] = useState(0);
197
+ const [rowsPerPage, setRowsPerPage] = useState(10);
198
+
199
+ const handleChangePage = (event: unknown, newPage: number) => {
200
+ setPage(newPage);
201
+ };
202
+
203
+ const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
204
+ setRowsPerPage(+event.target.value);
205
+ setPage(0);
206
+ };
207
+
208
+ // function getDisplayColumns(fields = []) {
209
+ // let arReturn = fields.map(( field: any, colIndex) => {
210
+ // let theField = field.config.value.substring(field.config.value.indexOf(" ")+1);
211
+ // if (theField.indexOf(".") == 0) {
212
+ // theField = theField.substring(1);
213
+ // }
214
+
215
+ // return theField;
216
+ // });
217
+ // return arReturn;
218
+
219
+ // }
220
+
221
+ function getHeaderCells(colFields, fields) {
222
+ const arReturn = colFields.map((field: any, colIndex) => {
223
+ let theField = field.config.value.substring(field.config.value.indexOf(' ') + 1);
224
+ if (theField.indexOf('.') === 0) {
225
+ theField = theField.substring(1);
226
+ }
227
+
228
+ const headerRow: any = {};
229
+ headerRow.id = theField;
230
+ headerRow.type = field.type;
231
+ headerRow.numeric =
232
+ field.type === 'Decimal' ||
233
+ field.type === 'Integer' ||
234
+ field.type === 'Percentage' ||
235
+ field.type === 'Currency' ||
236
+ false;
237
+ headerRow.disablePadding = false;
238
+ headerRow.label = fields[colIndex].config.label;
239
+
240
+ return headerRow;
241
+ });
242
+ return arReturn;
243
+ }
244
+
245
+ function updateFields(arFields, theColumns): Array<any> {
246
+ const arReturn = arFields;
247
+ arFields.forEach((field, index) => {
248
+ arReturn[index].config.name = theColumns[index].id;
249
+ });
250
+
251
+ return arReturn;
252
+ }
253
+
254
+ function getUsingData(arTableData, theColumns): Array<any> {
255
+ if (selectionMode === SELECTION_MODE.SINGLE || selectionMode === SELECTION_MODE.MULTI) {
256
+ const record = arTableData?.length > 0 ? arTableData[0] : '';
257
+ if (typeof record === 'object' && !('pyGUID' in record) && !('pyID' in record)) {
258
+ // eslint-disable-next-line no-console
259
+ console.error('pyGUID or pyID values are mandatory to select the required row from the list');
260
+ }
261
+ }
262
+ const arReturn = arTableData?.map((data: any) => {
263
+ const row: any = {};
264
+
265
+ theColumns.forEach(col => {
266
+ row[col.id] = data[col.id];
267
+ });
268
+ row[rowID] = data[rowID];
269
+ // for (const field of theColumns) {
270
+ // row[field.id] = data[field.id];
271
+ // }
272
+
273
+ // add in pxRefObjectClass and pzInsKey
274
+ if (data['pxRefObjectClass']) {
275
+ row['pxRefObjectClass'] = data['pxRefObjectClass'];
276
+ }
277
+
278
+ if (data['pzInsKey']) {
279
+ row['pzInsKey'] = data['pzInsKey'];
280
+ }
281
+
282
+ return row;
283
+ });
284
+
285
+ return arReturn;
286
+ }
287
+
288
+ function updateData(listData: Array<any>, fieldData: Array<any>): Array<any> {
289
+ const returnList: Array<any> = new Array<any>();
290
+ listData?.forEach(row => {
291
+ // copy
292
+ const rowData = JSON.parse(JSON.stringify(row));
293
+
294
+ fieldData.forEach(field => {
295
+ const config = field.config;
296
+ let fieldName;
297
+ let formattedDate;
298
+ let myFormat;
299
+
300
+ switch (field.type) {
301
+ case 'Date':
302
+ fieldName = config.name;
303
+ myFormat = config.formatter;
304
+ if (!myFormat) {
305
+ myFormat = 'Date';
306
+ }
307
+ formattedDate = Utils.generateDate(rowData[fieldName], myFormat);
308
+
309
+ rowData[fieldName] = formattedDate;
310
+ break;
311
+
312
+ case 'DateTime':
313
+ fieldName = config.name;
314
+ myFormat = config.formatter;
315
+ if (!myFormat) {
316
+ myFormat = 'DateTime-Long';
317
+ }
318
+ formattedDate = Utils.generateDateTime(rowData[fieldName], myFormat);
319
+
320
+ rowData[fieldName] = formattedDate;
321
+ break;
322
+
323
+ default:
324
+ break;
325
+ }
326
+ });
327
+
328
+ returnList.push(rowData);
329
+ });
330
+
331
+ return returnList;
332
+ }
333
+
334
+ function getMyColumnList(arCols: Array<any>): Array<string> {
335
+ const myColList: Array<string> = [];
336
+
337
+ arCols.forEach(col => {
338
+ myColList.push(col.id);
339
+ });
340
+
341
+ // for (const col of arCols) {
342
+ // myColList.push(col.id);
343
+ // }
344
+
345
+ return myColList;
346
+ }
347
+
348
+ /** Will return field from a filter expression */
349
+ function getFieldFromFilter(filter, dateRange = false) {
350
+ let fieldValue;
351
+ if (dateRange) {
352
+ fieldValue = filter?.AND[0]?.condition.lhs.field;
353
+ } else {
354
+ fieldValue = filter?.condition.lhs.field;
355
+ }
356
+ return fieldValue;
357
+ }
358
+
359
+ // Will be triggered when EVENT_DASHBOARD_FILTER_CHANGE fires
360
+ function processFilterChange(data) {
361
+ const { filterId, filterExpression } = data;
362
+ dashboardFilterPayload = {
363
+ query: {
364
+ filter: {},
365
+ select: []
366
+ }
367
+ };
368
+
369
+ filters.current[filterId] = filterExpression;
370
+ // eslint-disable-next-line no-unneeded-ternary
371
+ let isDateRange = data.filterExpression?.AND ? true : false;
372
+ // Will be AND by default but making it dynamic in case we support dynamic relational ops in future
373
+ const relationalOp = 'AND';
374
+
375
+ let field = getFieldFromFilter(filterExpression, isDateRange);
376
+ selectParam = [];
377
+ // Constructing the select parameters list( will be sent in dashboardFilterPayload)
378
+ columnList.forEach(col => {
379
+ selectParam.push({
380
+ field: col
381
+ });
382
+ });
383
+
384
+ // Checking if the triggered filter is applicable for this list
385
+ if (data.filterExpression !== null && !(columnList.length && columnList.includes(field))) {
386
+ return;
387
+ }
388
+ // This is a flag which will be used to reset dashboardFilterPayload in case we don't find any valid filters
389
+ let validFilter = false;
390
+
391
+ let index = 1;
392
+ // Iterating over the current filters list to create filter data which will be POSTed
393
+ for (const filterExp in filters.current) {
394
+ const filter = filters.current[filterExp];
395
+ // If the filter is null then we can skip this iteration
396
+ if (filter === null) {
397
+ // eslint-disable-next-line no-continue
398
+ continue;
399
+ }
400
+
401
+ // Checking if the filter is of type- Date Range
402
+ // eslint-disable-next-line no-unneeded-ternary
403
+ isDateRange = filter?.AND ? true : false;
404
+ field = getFieldFromFilter(filter, isDateRange);
405
+
406
+ if (!(columnList.length && columnList.includes(field))) {
407
+ // eslint-disable-next-line no-continue
408
+ continue;
409
+ }
410
+ // If we reach here that implies we've at least one valid filter, hence setting the flag
411
+ validFilter = true;
412
+ /** Below are the 2 cases for- Text & Date-Range filter types where we'll construct filter data which will be sent in the dashboardFilterPayload
413
+ * In Nebula, through Repeating Structures they might be using several APIs to do it, we're doing it here
414
+ */
415
+ if (isDateRange) {
416
+ const dateRelationalOp = filter?.AND ? 'AND' : 'OR';
417
+ dashboardFilterPayload.query.filter.filterConditions = {
418
+ ...dashboardFilterPayload.query.filter.filterConditions,
419
+ [`T${index++}`]: { ...filter[relationalOp][0].condition },
420
+ [`T${index++}`]: { ...filter[relationalOp][1].condition }
421
+ };
422
+ if (dashboardFilterPayload.query.filter.logic) {
423
+ dashboardFilterPayload.query.filter.logic = `${dashboardFilterPayload.query.filter.logic} ${relationalOp} (T${
424
+ index - 2
425
+ } ${dateRelationalOp} T${index - 1})`;
426
+ } else {
427
+ dashboardFilterPayload.query.filter.logic = `(T${index - 2} ${relationalOp} T${index - 1})`;
428
+ }
429
+
430
+ dashboardFilterPayload.query.select = selectParam;
431
+ } else {
432
+ dashboardFilterPayload.query.filter.filterConditions = {
433
+ ...dashboardFilterPayload.query.filter.filterConditions,
434
+ [`T${index++}`]: { ...filter.condition, ignoreCase: true }
435
+ };
436
+
437
+ if (dashboardFilterPayload.query.filter.logic) {
438
+ dashboardFilterPayload.query.filter.logic = `${dashboardFilterPayload.query.filter.logic} ${relationalOp} T${
439
+ index - 1
440
+ }`;
441
+ } else {
442
+ dashboardFilterPayload.query.filter.logic = `T${index - 1}`;
443
+ }
444
+
445
+ dashboardFilterPayload.query.select = selectParam;
446
+ }
447
+ }
448
+
449
+ // Reset the dashboardFilterPayload if we end up with no valid filters for the list
450
+ if (!validFilter) {
451
+ dashboardFilterPayload = undefined;
452
+ }
453
+
454
+ fetchDataFromServer();
455
+ }
456
+
457
+ // Will be triggered when EVENT_DASHBOARD_FILTER_CLEAR_ALL fires
458
+ function processFilterClear() {
459
+ dashboardFilterPayload = undefined;
460
+ fetchDataFromServer();
461
+ }
462
+
463
+ useEffect(() => {
464
+ setTimeout(() => {
465
+ PCore.getPubSubUtils().subscribe(
466
+ PCore.getConstants().PUB_SUB_EVENTS.EVENT_DASHBOARD_FILTER_CHANGE,
467
+ data => {
468
+ processFilterChange(data);
469
+ },
470
+ `dashboard-component-${'id'}`,
471
+ false,
472
+ getPConnect().getContextName()
473
+ );
474
+ PCore.getPubSubUtils().subscribe(
475
+ PCore.getConstants().PUB_SUB_EVENTS.EVENT_DASHBOARD_FILTER_CLEAR_ALL,
476
+ () => {
477
+ filters.current = {};
478
+ processFilterClear();
479
+ },
480
+ `dashboard-component-${'id'}`,
481
+ false,
482
+ getPConnect().getContextName()
483
+ );
484
+ }, 0);
485
+ }, []);
486
+
487
+ function fetchAllData() {
488
+ const context = getPConnect().getContextName();
489
+ return PCore.getDataPageUtils().getDataAsync(
490
+ referenceList,
491
+ context,
492
+ payload ? payload.dataViewParameters : dataViewParameters,
493
+ null,
494
+ payload ? payload.query : dashboardFilterPayload && dashboardFilterPayload.query
495
+ );
496
+ }
497
+
498
+ async function fetchDataFromServer() {
499
+ let bCallSetRowsColumns = true;
500
+ const workListJSON = await fetchAllData();
501
+
502
+ // don't update these fields until we return from promise
503
+ let fields = presets[0].children[0].children;
504
+
505
+ // this is an unresovled version of this.fields$, need unresolved, so can get the property reference
506
+ const columnFields = componentConfig.presets[0].children[0].children;
507
+
508
+ const tableDataResults = workListJSON['data'];
509
+
510
+ const myColumns = getHeaderCells(columnFields, fields);
511
+
512
+ const selectParams: any = [];
513
+
514
+ myColumns.forEach(column => {
515
+ selectParams.push({
516
+ field: column.id
517
+ });
518
+ });
519
+
520
+ const colList: any = [];
521
+
522
+ selectParams.forEach(col => {
523
+ colList.push(col.field);
524
+ });
525
+
526
+ columnList = colList;
527
+
528
+ fields = updateFields(fields, myColumns);
529
+
530
+ const usingDataResults = getUsingData(tableDataResults, myColumns);
531
+
532
+ // store globally, so can be searched, filtered, etc.
533
+ myRows = updateData(usingDataResults, fields);
534
+ myDisplayColumnList = getMyColumnList(myColumns);
535
+
536
+ // At this point, if we have data ready to render and haven't been asked
537
+ // to NOT call setRows and setColumns, call them
538
+ if (bCallSetRowsColumns) {
539
+ setRows(myRows);
540
+ setColumns(myColumns);
541
+ }
542
+
543
+ return () => {
544
+ // Inspired by https://juliangaramendy.dev/blog/use-promise-subscription
545
+ // The useEffect closure lets us have access to the bCallSetRowsColumns
546
+ // variable inside the useEffect and inside the "then" clause of the
547
+ // workListData promise
548
+ // So, if this cleanup code gets run before the promise .then is called,
549
+ // we can avoid calling the useState setters which would otherwise show a warning
550
+ bCallSetRowsColumns = false;
551
+ };
552
+ }
553
+
554
+ useEffect(() => {
555
+ fetchDataFromServer();
556
+ }, []);
557
+
558
+ function searchFilter(value: string, rows: Array<any>) {
559
+ function filterArray(el: any): boolean {
560
+ const bReturn = false;
561
+ for (const key in el) {
562
+ // only search columsn that are displayed (pzInsKey and pxRefObjectClass are added and may or may not be displayed)
563
+ if (myDisplayColumnList.includes(key)) {
564
+ let myVal = el[key];
565
+ if (myVal !== null) {
566
+ if (typeof myVal !== 'string') {
567
+ myVal = myVal.toString();
568
+ }
569
+ if (myVal.toLowerCase().indexOf(value.toLowerCase()) >= 0) {
570
+ return true;
571
+ }
572
+ }
573
+ }
574
+ }
575
+
576
+ return bReturn;
577
+ }
578
+
579
+ rows = rows.filter(filterArray);
580
+
581
+ return rows;
582
+ }
583
+
584
+ function _onSearch(event: any) {
585
+ const searchValue = event.target.value;
586
+
587
+ const filteredRows = searchFilter(searchValue, myRows.slice());
588
+
589
+ setRows(filteredRows);
590
+ }
591
+
592
+ function showToast(message: string) {
593
+ const theMessage = `Assignment: ${message}`;
594
+ // eslint-disable-next-line no-console
595
+ console.error(theMessage);
596
+ setSnackbarMessage(message);
597
+ setShowSnackbar(true);
598
+ }
599
+
600
+ function openAssignment(row) {
601
+ const { pxRefObjectClass, pzInsKey } = row;
602
+ const sTarget = thePConn.getContainerName();
603
+
604
+ const options = { containerName: sTarget };
605
+
606
+ thePConn
607
+ .getActionsApi()
608
+ .openAssignment(pzInsKey, pxRefObjectClass, options)
609
+ .then(() => {
610
+ // console.log("openAssignment successful");
611
+ })
612
+ .catch(() => {
613
+ showToast(`openAssignment failed!`);
614
+ });
615
+ }
616
+
617
+ function _rowClick(row: any) {
618
+ // eslint-disable-next-line sonarjs/no-small-switch
619
+ switch (rowClickAction) {
620
+ case 'openAssignment':
621
+ openAssignment(row);
622
+ break;
623
+
624
+ default:
625
+ break;
626
+ }
627
+ }
628
+
629
+ function openWork(row) {
630
+ const { pxRefObjectClass, pxRefObjectKey } = row;
631
+
632
+ if (pxRefObjectClass !== '' && pxRefObjectKey !== '') {
633
+ thePConn.getActionsApi().openWorkByHandle(pxRefObjectKey, pxRefObjectClass);
634
+ }
635
+ }
636
+
637
+ function handleSnackbarClose(event: React.SyntheticEvent | React.MouseEvent, reason?: string) {
638
+ if (reason === 'clickaway') {
639
+ return;
640
+ }
641
+ setShowSnackbar(false);
642
+ }
643
+
644
+ function _menuClick(event, columnId: string, columnType: string, label: string) {
645
+ menuColumnId = columnId;
646
+ menuColumnType = columnType;
647
+ menuColumnLabel = label;
648
+
649
+ setAnchorEl(event.currentTarget);
650
+ }
651
+
652
+ function _menuClose() {
653
+ setAnchorEl(null);
654
+ }
655
+
656
+ const [filterBy, setFilterBy] = useState<string>();
657
+ const [containsDateOrTime, setContainsDateOrTime] = useState<boolean>(false);
658
+ const [filterType, setFilterType] = useState<string>('string');
659
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars
660
+ const [displayDialogFilterName, setDisplayDialogFilterName] = useState<string>('');
661
+ const [displayDialogContainsFilter, setDisplayDialogContainsFilter] =
662
+ useState<string>('contains');
663
+ const [displayDialogContainsValue, setDisplayDialogContainsValue] = useState<string>('');
664
+ const [displayDialogDateFilter, setDisplayDialogDateFilter] = useState<string>('notequal');
665
+ const [displayDialogDateValue, setDisplayDialogDateValue] = useState<string>('');
666
+
667
+ function _filterMenu() {
668
+ setAnchorEl(null);
669
+
670
+ let bFound = false;
671
+
672
+ for (const filterObj of filterByColumns) {
673
+ if (filterObj.ref === menuColumnId) {
674
+ setFilterBy(menuColumnLabel);
675
+ if (
676
+ filterObj.type === 'Date' ||
677
+ filterObj.type === 'DateTime' ||
678
+ filterObj.type === 'Time'
679
+ ) {
680
+ setContainsDateOrTime(true);
681
+ setFilterType(filterObj.type);
682
+ setDisplayDialogDateFilter(filterObj.containsFilter);
683
+ setDisplayDialogDateValue(filterObj.containsFilterValue);
684
+ } else {
685
+ setContainsDateOrTime(false);
686
+ setFilterType('string');
687
+ setDisplayDialogContainsFilter(filterObj.containsFilter);
688
+ setDisplayDialogContainsValue(filterObj.containsFilterValue);
689
+ }
690
+ bFound = true;
691
+ break;
692
+ }
693
+ }
694
+
695
+ if (!bFound) {
696
+ setFilterBy(menuColumnLabel);
697
+ setDisplayDialogFilterName(menuColumnId);
698
+ setDisplayDialogContainsValue('');
699
+
700
+ switch (menuColumnType) {
701
+ case 'Date':
702
+ case 'DateTime':
703
+ case 'Time':
704
+ setContainsDateOrTime(true);
705
+ setFilterType(menuColumnType);
706
+ break;
707
+ default:
708
+ setContainsDateOrTime(false);
709
+ setFilterType('string');
710
+ break;
711
+ }
712
+ }
713
+
714
+ // open dialog
715
+ setOpen(true);
716
+ }
717
+
718
+ function _groupMenu() {
719
+ setAnchorEl(null);
720
+ }
721
+
722
+ function _closeDialog() {
723
+ setOpen(false);
724
+ }
725
+
726
+ function _showFilteredIcon(columnId) {
727
+ for (const filterObj of filterByColumns) {
728
+ if (filterObj['ref'] === columnId) {
729
+ // eslint-disable-next-line sonarjs/prefer-single-boolean-return
730
+ if (filterObj['containsFilterValue'] !== '') {
731
+ return true;
732
+ }
733
+ return false;
734
+ }
735
+ }
736
+
737
+ return false;
738
+ }
739
+
740
+ function updateFilterWithInfo() {
741
+ let bFound = false;
742
+ for (const filterObj of filterByColumns) {
743
+ if (filterObj['ref'] === menuColumnId) {
744
+ filterObj['type'] = filterType;
745
+ if (containsDateOrTime) {
746
+ filterObj['containsFilter'] = displayDialogDateFilter;
747
+ filterObj['containsFilterValue'] = displayDialogDateValue;
748
+ } else {
749
+ filterObj['containsFilter'] = displayDialogContainsFilter;
750
+ filterObj['containsFilterValue'] = displayDialogContainsValue;
751
+ }
752
+ bFound = true;
753
+ break;
754
+ }
755
+ }
756
+
757
+ if (!bFound) {
758
+ // add in
759
+ const filterObj: any = {};
760
+ filterObj.ref = menuColumnId;
761
+ filterObj['type'] = filterType;
762
+ if (containsDateOrTime) {
763
+ filterObj['containsFilter'] = displayDialogDateFilter;
764
+ filterObj['containsFilterValue'] = displayDialogDateValue;
765
+ } else {
766
+ filterObj['containsFilter'] = displayDialogContainsFilter;
767
+ filterObj['containsFilterValue'] = displayDialogContainsValue;
768
+ }
769
+
770
+ filterByColumns.push(filterObj);
771
+ }
772
+ }
773
+
774
+ function filterSortGroupBy() {
775
+ // get original data set
776
+ let theData = myRows.slice();
777
+
778
+ // last filter config data is global
779
+ theData = theData.filter(filterData(filterByColumns));
780
+
781
+ // move data to array and then sort
782
+ setRows(theData);
783
+ createSortHandler(sortColumnId);
784
+
785
+ // grouping here
786
+
787
+ // let reGroupData = this.addGroups(theData, this.groupByColumns$);
788
+
789
+ // this.repeatList$.data = [];
790
+ // this.repeatList$.data.push( ...reGroupData);
791
+
792
+ // if (this.searchFilter && this.searchFilter != "") {
793
+ // this.repeatList$.filter = this.searchFilter;
794
+ // }
795
+ // else {
796
+ // this.perfFilter = performance.now().toString();
797
+ // this.repeatList$.filter = this.perfFilter;
798
+ // }
799
+ // this.repeatList$.filter = "";
800
+
801
+ // if (this.repeatList$.paginator) {
802
+ // this.repeatList$.paginator.firstPage();
803
+ // }
804
+ }
805
+
806
+ function _dialogContainsFilter(event) {
807
+ // dialogContainsFilter = event.target.value;
808
+ setDisplayDialogContainsFilter(event.target.value);
809
+ }
810
+
811
+ function _dialogContainsValue(event) {
812
+ // dialogContainsValue = event.target.value;
813
+ setDisplayDialogContainsValue(event.target.value);
814
+ }
815
+
816
+ function _dialogDateFilter(event) {
817
+ // dialogDateFilter = event.target.value;
818
+ setDisplayDialogDateFilter(event.target.value);
819
+ }
820
+
821
+ function _dialogDateValue(event) {
822
+ setDisplayDialogDateValue(event.target.value);
823
+ }
824
+
825
+ function _submitFilter() {
826
+ updateFilterWithInfo();
827
+ filterSortGroupBy();
828
+
829
+ setOpen(false);
830
+ }
831
+
832
+ function _showButton(name, row) {
833
+ let bReturn = false;
834
+ const { pxRefObjectClass, pzInsKey, pxRefObjectKey } = row;
835
+ switch (name) {
836
+ case 'pxTaskLabel':
837
+ if (pxRefObjectClass !== '' && pzInsKey !== '') {
838
+ bReturn = true;
839
+ }
840
+ break;
841
+
842
+ case 'pxRefObjectInsName':
843
+ if (pxRefObjectClass !== '' && pxRefObjectKey !== '') {
844
+ bReturn = true;
845
+ }
846
+ break;
847
+
848
+ default:
849
+ break;
850
+ }
851
+
852
+ return bReturn;
853
+ }
854
+
855
+ function _listViewClick(name, row) {
856
+ switch (name) {
857
+ case 'pxTaskLabel':
858
+ openAssignment(row);
859
+ break;
860
+
861
+ case 'pxRefObjectInsName':
862
+ openWork(row);
863
+ break;
864
+
865
+ default:
866
+ break;
867
+ }
868
+ }
869
+
870
+ function _listTitle() {
871
+ const defaultTitle = 'List';
872
+ let title = resolvedConfigProps.title ? resolvedConfigProps.title : defaultTitle;
873
+ const inheritedProps = resolvedConfigProps?.inheritedProps;
874
+
875
+ // Let any title in resolvedConfigProps that isn't the default take precedence
876
+ // but only look in inheritedProps if they exist
877
+ if (title === defaultTitle && inheritedProps) {
878
+ for (const inheritedProp of inheritedProps) {
879
+ if (inheritedProp?.prop === 'label') {
880
+ title = inheritedProp?.value;
881
+ break;
882
+ }
883
+ }
884
+ }
885
+
886
+ return title;
887
+ }
888
+
889
+ const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
890
+ const value = event.target.value;
891
+ getPConnect()
892
+ ?.getListActions?.()
893
+ ?.setSelectedRows([{ [rowID]: value }]);
894
+ setSelectedValue(value);
895
+ };
896
+
897
+ const onCheckboxClick = event => {
898
+ const value = event?.target?.value;
899
+ const checked = event?.target?.checked;
900
+ getPConnect()
901
+ ?.getListActions()
902
+ ?.setSelectedRows([{ [rowID]: value, $selected: checked }]);
903
+ };
904
+
905
+ return (
906
+ <>
907
+ {arColumns && arColumns.length > 0 && (
908
+ <Paper className={classes.paper}>
909
+ <Typography className={classes.title} variant='h6' color='textPrimary' gutterBottom>
910
+ {_listTitle()}
911
+ </Typography>
912
+ {globalSearch && (
913
+ <Grid container spacing={1} alignItems='flex-end' className={classes.search}>
914
+ <Grid item>
915
+ <SearchIcon />
916
+ </Grid>
917
+ <Grid item>
918
+ <TextField
919
+ label='Search'
920
+ fullWidth
921
+ variant='outlined'
922
+ placeholder=''
923
+ size='small'
924
+ onChange={_onSearch}
925
+ />
926
+ </Grid>
927
+ </Grid>
928
+ )}
929
+ <>
930
+ {bInForm ? (
931
+ <TableContainer className={classes.tableInForm}>
932
+ <Table stickyHeader aria-label='sticky table'>
933
+ <TableHead>
934
+ <TableRow>
935
+ {arColumns.map(column => {
936
+ return (
937
+ <TableCell
938
+ className={classes.cell}
939
+ key={column.id}
940
+ sortDirection={orderBy === column.id ? order : false}
941
+ >
942
+ <TableSortLabel
943
+ active={orderBy === column.id}
944
+ direction={orderBy === column.id ? order : 'asc'}
945
+ onClick={createSortHandler(column.id)}
946
+ >
947
+ {column.label}
948
+ {_showFilteredIcon(column.id) && (
949
+ <FilterListIcon className={classes.filteredIcon} />
950
+ )}
951
+ {orderBy === column.id ? (
952
+ <span className={classes.visuallyHidden}>
953
+ {order === 'desc' ? 'sorted descending' : 'sorted ascending'}
954
+ </span>
955
+ ) : null}
956
+ </TableSortLabel>
957
+ <MoreIcon
958
+ className={classes.moreIcon}
959
+ onClick={event => {
960
+ _menuClick(event, column.id, column.type, column.label);
961
+ }}
962
+ />
963
+ </TableCell>
964
+ );
965
+ })}
966
+ </TableRow>
967
+ </TableHead>
968
+ <TableBody>
969
+ {stableSort(arRows, getComparator(order, orderBy))
970
+ .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
971
+ .map(row => {
972
+ return (
973
+ <TableRow
974
+ key={row.pxRefObjectInsName || row.pyID}
975
+ onClick={() => {
976
+ _rowClick(row);
977
+ }}
978
+ >
979
+ {arColumns.map(column => {
980
+ const value = row[column.id];
981
+ return (
982
+ <TableCell
983
+ key={column.id}
984
+ align={column.align}
985
+ className={classes.cell}
986
+ >
987
+ {_showButton(column.id, row) ? (
988
+ <Link
989
+ component='button'
990
+ onClick={() => {
991
+ _listViewClick(column.id, row);
992
+ }}
993
+ >
994
+ {column.format && typeof value === 'number'
995
+ ? column.format(value)
996
+ : value}
997
+ </Link>
998
+ ) : (
999
+ <>
1000
+ {column.format && typeof value === 'number'
1001
+ ? column.format(value)
1002
+ : value}
1003
+ </>
1004
+ )}
1005
+ </TableCell>
1006
+ );
1007
+ })}
1008
+ </TableRow>
1009
+ );
1010
+ })}
1011
+ </TableBody>
1012
+ </Table>
1013
+ </TableContainer>
1014
+ ) : (
1015
+ <TableContainer>
1016
+ <Table>
1017
+ <TableHead>
1018
+ <TableRow>
1019
+ {(selectionMode === SELECTION_MODE.SINGLE ||
1020
+ selectionMode === SELECTION_MODE.MULTI) && <TableCell></TableCell>}
1021
+ {arColumns.map(column => {
1022
+ return (
1023
+ <TableCell
1024
+ className={classes.cell}
1025
+ key={column.id}
1026
+ sortDirection={orderBy === column.id ? order : false}
1027
+ >
1028
+ <TableSortLabel
1029
+ active={orderBy === column.id}
1030
+ direction={orderBy === column.id ? order : 'asc'}
1031
+ onClick={createSortHandler(column.id)}
1032
+ >
1033
+ {column.label}
1034
+ {orderBy === column.id ? (
1035
+ <span className={classes.visuallyHidden}>
1036
+ {order === 'desc' ? 'sorted descending' : 'sorted ascending'}
1037
+ </span>
1038
+ ) : null}
1039
+ </TableSortLabel>
1040
+ </TableCell>
1041
+ );
1042
+ })}
1043
+ </TableRow>
1044
+ </TableHead>
1045
+ <TableBody>
1046
+ {arRows &&
1047
+ arRows.length > 0 &&
1048
+ stableSort(arRows, getComparator(order, orderBy))
1049
+ .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
1050
+ .map(row => {
1051
+ return (
1052
+ <TableRow
1053
+ key={row[rowID]}
1054
+ onClick={() => {
1055
+ _rowClick(row);
1056
+ }}
1057
+ >
1058
+ {selectionMode === SELECTION_MODE.SINGLE && (
1059
+ <TableCell>
1060
+ <Radio
1061
+ onChange={handleChange}
1062
+ value={row[rowID]}
1063
+ name='radio-buttons'
1064
+ inputProps={{ 'aria-label': 'A' }}
1065
+ checked={selectedValue === row[rowID]}
1066
+ ></Radio>
1067
+ </TableCell>
1068
+ )}
1069
+ {selectionMode === SELECTION_MODE.MULTI && (
1070
+ <TableCell>
1071
+ <Checkbox
1072
+ onChange={onCheckboxClick}
1073
+ value={row[rowID]}
1074
+ ></Checkbox>
1075
+ </TableCell>
1076
+ )}
1077
+ {arColumns.map(column => {
1078
+ const value = row[column.id];
1079
+ return (
1080
+ <TableCell
1081
+ className={classes.cell}
1082
+ key={column.id}
1083
+ align={column.align}
1084
+ >
1085
+ {column.format && typeof value === 'number'
1086
+ ? column.format(value)
1087
+ : value}
1088
+ </TableCell>
1089
+ );
1090
+ })}
1091
+ </TableRow>
1092
+ );
1093
+ })}
1094
+ </TableBody>
1095
+ </Table>
1096
+ {arRows && arRows.length === 0 && (
1097
+ <div className='no-records'>No records found.</div>
1098
+ )}
1099
+ </TableContainer>
1100
+ )}
1101
+ </>
1102
+ {arRows && arRows.length > 0 && (
1103
+ <TablePagination
1104
+ rowsPerPageOptions={[10, 25, 100]}
1105
+ component='div'
1106
+ count={arRows.length}
1107
+ rowsPerPage={rowsPerPage}
1108
+ page={page}
1109
+ onPageChange={handleChangePage}
1110
+ onRowsPerPageChange={handleChangeRowsPerPage}
1111
+ />
1112
+ )}
1113
+ </Paper>
1114
+ )}
1115
+ <Menu
1116
+ id='simple-menu'
1117
+ anchorEl={anchorEl}
1118
+ keepMounted
1119
+ open={Boolean(anchorEl)}
1120
+ onClose={_menuClose}
1121
+ >
1122
+ <MenuItem onClick={_filterMenu}>
1123
+ <FilterListIcon /> Filter
1124
+ </MenuItem>
1125
+ <MenuItem onClick={_groupMenu}>
1126
+ <SubjectIcon /> Group
1127
+ </MenuItem>
1128
+ </Menu>
1129
+ <Dialog open={open} onClose={_closeDialog} aria-labelledby='form-dialog-title'>
1130
+ <DialogTitle id='form-dialog-title'>Filter: {filterBy}</DialogTitle>
1131
+ <DialogContent>
1132
+ {containsDateOrTime ? (
1133
+ <>
1134
+ <Select value={displayDialogDateFilter} onChange={_dialogDateFilter} fullWidth>
1135
+ <MenuItem value='notequal'>is not equal to</MenuItem>
1136
+ <MenuItem value='after'>after</MenuItem>
1137
+ <MenuItem value='before'>before</MenuItem>
1138
+ <MenuItem value='null'>is null</MenuItem>
1139
+ <MenuItem value='notnull'>is not null</MenuItem>
1140
+ </Select>
1141
+ {filterType === 'Date' && (
1142
+ <TextField
1143
+ autoFocus
1144
+ margin='dense'
1145
+ id='containsFilter'
1146
+ type='date'
1147
+ fullWidth
1148
+ value={displayDialogDateValue}
1149
+ onChange={_dialogDateValue}
1150
+ />
1151
+ )}
1152
+ {filterType === 'DateTime' && (
1153
+ <TextField
1154
+ autoFocus
1155
+ margin='dense'
1156
+ id='containsFilter'
1157
+ type='datetime-local'
1158
+ fullWidth
1159
+ value={displayDialogDateValue}
1160
+ onChange={_dialogDateValue}
1161
+ />
1162
+ )}
1163
+ {filterType === 'Time' && (
1164
+ <TextField
1165
+ autoFocus
1166
+ margin='dense'
1167
+ id='containsFilter'
1168
+ type='time'
1169
+ fullWidth
1170
+ value={displayDialogDateValue}
1171
+ onChange={_dialogDateValue}
1172
+ />
1173
+ )}
1174
+ </>
1175
+ ) : (
1176
+ <>
1177
+ <Select
1178
+ fullWidth
1179
+ onChange={_dialogContainsFilter}
1180
+ value={displayDialogContainsFilter}
1181
+ >
1182
+ <MenuItem value='contains'>Contains</MenuItem>
1183
+ <MenuItem value='equals'>Equals</MenuItem>
1184
+ <MenuItem value='startswith'>Starts with</MenuItem>
1185
+ </Select>
1186
+ <TextField
1187
+ autoFocus
1188
+ margin='dense'
1189
+ id='containsFilter'
1190
+ type='text'
1191
+ fullWidth
1192
+ value={displayDialogContainsValue}
1193
+ onChange={_dialogContainsValue}
1194
+ />
1195
+ </>
1196
+ )}
1197
+ </DialogContent>
1198
+ <DialogActions>
1199
+ <Button onClick={_closeDialog} color='secondary'>
1200
+ Cancel
1201
+ </Button>
1202
+ <Button onClick={_submitFilter} color='primary'>
1203
+ Submit
1204
+ </Button>
1205
+ </DialogActions>
1206
+ </Dialog>
1207
+
1208
+ <Snackbar
1209
+ open={showSnackbar}
1210
+ autoHideDuration={3000}
1211
+ onClose={handleSnackbarClose}
1212
+ message={snackbarMessage}
1213
+ action={
1214
+ <IconButton size='small' aria-label='close' color='inherit' onClick={handleSnackbarClose}>
1215
+ <CloseIcon fontSize='small' />
1216
+ </IconButton>
1217
+ }
1218
+ />
1219
+ </>
1220
+ );
1221
+ }
1222
+
1223
+ ListView.defaultProps = {
1224
+ // parameters: undefined
1225
+ };
1226
+
1227
+ ListView.propTypes = {
1228
+ getPConnect: PropTypes.func.isRequired
1229
+ // parameters: PropTypes.objectOf(PropTypes.any)
1230
+ };