orc-shared 5.10.0-dev.2 → 5.10.0-dev.21

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 (186) hide show
  1. package/dist/actions/metadata.js +30 -11
  2. package/dist/actions/requestsApi.js +10 -1
  3. package/dist/components/AppFrame/About.js +136 -100
  4. package/dist/components/AppFrame/Anchor.js +45 -21
  5. package/dist/components/AppFrame/AppFrame.js +53 -31
  6. package/dist/components/AppFrame/Help.js +35 -15
  7. package/dist/components/AppFrame/MenuItem.js +148 -114
  8. package/dist/components/AppFrame/Preferences.js +136 -97
  9. package/dist/components/AppFrame/Sidebar.js +51 -28
  10. package/dist/components/AppFrame/Topbar.js +61 -36
  11. package/dist/components/ColumnWrapper.js +28 -5
  12. package/dist/components/Culture.js +33 -14
  13. package/dist/components/DropMenu/Menu.js +79 -45
  14. package/dist/components/DropMenu/index.js +34 -29
  15. package/dist/components/Form/Combination.js +45 -16
  16. package/dist/components/Form/Field.js +57 -38
  17. package/dist/components/Form/FieldElements.js +0 -11
  18. package/dist/components/Form/Fieldset.js +47 -19
  19. package/dist/components/Form/Form.js +22 -9
  20. package/dist/components/Form/FormElement.js +40 -7
  21. package/dist/components/Form/Inputs/Button.js +63 -18
  22. package/dist/components/Form/Inputs/ReadOnly.js +50 -27
  23. package/dist/components/{AppFrame/ApplicationSelector/Header.js → Form/Inputs/Selector.js} +30 -31
  24. package/dist/components/Form/Inputs/Text.js +20 -37
  25. package/dist/components/Form/Inputs/Toggles.js +39 -40
  26. package/dist/components/Form/Inputs/index.js +2 -13
  27. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +31 -11
  28. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/SectionToolbar.js +89 -0
  29. package/dist/components/MaterialUI/DataDisplay/Table.js +109 -18
  30. package/dist/components/MaterialUI/DataDisplay/TableProps.js +5 -1
  31. package/dist/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.js +198 -0
  32. package/dist/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +4 -1
  33. package/dist/components/MaterialUI/Inputs/DatePicker.js +14 -14
  34. package/dist/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -0
  35. package/dist/components/MaterialUI/Inputs/Select.js +2 -0
  36. package/dist/components/MaterialUI/Inputs/SelectProps.js +2 -0
  37. package/dist/components/MaterialUI/Inputs/Switch.js +17 -1
  38. package/dist/components/MaterialUI/Inputs/SwitchProps.js +2 -0
  39. package/dist/components/MaterialUI/Inputs/TimePicker.js +14 -21
  40. package/dist/components/MaterialUI/hocs/withDeferredTooltip.js +3 -1
  41. package/dist/components/MaterialUI/muiThemes.js +2 -1
  42. package/dist/components/Provision.js +1 -1
  43. package/dist/constants.js +2 -1
  44. package/dist/content/iconsSheet.svg +740 -116
  45. package/dist/hocs/withScrollBox.js +27 -12
  46. package/dist/hooks/useDaysAndMonthsLocalization.js +77 -0
  47. package/dist/hooks/useInMemoryPaging.js +135 -0
  48. package/dist/hooks/useMultipleFieldEditState.js +12 -3
  49. package/dist/reducers/metadata.js +6 -0
  50. package/dist/schemas/metadata.js +9 -1
  51. package/dist/selectors/locale.js +1 -0
  52. package/dist/selectors/metadata.js +14 -11
  53. package/dist/sharedMessages.js +184 -0
  54. package/dist/utils/ListHelper.js +271 -0
  55. package/dist/utils/comparisonHelper.js +185 -0
  56. package/dist/utils/propertyBagHelper.js +3 -1
  57. package/dist/utils/timezoneHelper.js +18 -31
  58. package/package.json +4 -3
  59. package/src/actions/metadata.js +11 -0
  60. package/src/actions/metadata.test.js +27 -0
  61. package/src/actions/requestsApi.js +6 -0
  62. package/src/components/AppFrame/About.js +97 -117
  63. package/src/components/AppFrame/About.test.js +128 -90
  64. package/src/components/AppFrame/Anchor.js +34 -36
  65. package/src/components/AppFrame/Anchor.test.js +5 -68
  66. package/src/components/AppFrame/AppFrame.js +31 -40
  67. package/src/components/AppFrame/AppFrame.test.js +424 -445
  68. package/src/components/AppFrame/Help.js +23 -20
  69. package/src/components/AppFrame/Help.test.js +3 -3
  70. package/src/components/AppFrame/MenuItem.js +106 -126
  71. package/src/components/AppFrame/MenuItem.test.js +78 -169
  72. package/src/components/AppFrame/Preferences.js +110 -98
  73. package/src/components/AppFrame/Preferences.test.js +115 -219
  74. package/src/components/AppFrame/Sidebar.js +39 -41
  75. package/src/components/AppFrame/Sidebar.test.js +88 -168
  76. package/src/components/AppFrame/Topbar.js +59 -52
  77. package/src/components/AppFrame/Topbar.test.js +31 -39
  78. package/src/components/ColumnWrapper.js +18 -9
  79. package/src/components/Culture.js +20 -10
  80. package/src/components/Culture.test.js +27 -16
  81. package/src/components/DropMenu/DropMenu.test.js +185 -224
  82. package/src/components/DropMenu/Menu.js +73 -80
  83. package/src/components/DropMenu/Menu.test.js +35 -86
  84. package/src/components/DropMenu/index.js +19 -15
  85. package/src/components/Form/Combination.js +35 -28
  86. package/src/components/Form/Combination.test.js +6 -19
  87. package/src/components/Form/Field.js +53 -66
  88. package/src/components/Form/Field.test.js +29 -51
  89. package/src/components/Form/FieldElements.js +0 -14
  90. package/src/components/Form/FieldElements.test.js +104 -111
  91. package/src/components/Form/Fieldset.js +42 -37
  92. package/src/components/Form/Fieldset.test.js +14 -7
  93. package/src/components/Form/Form.js +11 -7
  94. package/src/components/Form/Form.test.js +75 -56
  95. package/src/components/Form/FormElement.js +24 -16
  96. package/src/components/Form/InputField.test.js +24 -30
  97. package/src/components/Form/Inputs/Button.js +58 -14
  98. package/src/components/Form/Inputs/Button.test.js +32 -7
  99. package/src/components/Form/Inputs/Inputs.test.js +0 -7
  100. package/src/components/Form/Inputs/ReadOnly.js +34 -28
  101. package/src/components/Form/Inputs/ReadOnly.test.js +45 -7
  102. package/src/components/Form/Inputs/Selector.js +22 -0
  103. package/src/components/Form/Inputs/Selector.test.js +105 -0
  104. package/src/components/Form/Inputs/Text.js +15 -44
  105. package/src/components/Form/Inputs/Text.test.js +20 -29
  106. package/src/components/Form/Inputs/Toggles.js +27 -26
  107. package/src/components/Form/Inputs/Toggles.test.js +22 -28
  108. package/src/components/Form/Inputs/index.js +4 -15
  109. package/src/components/MaterialUI/DataDisplay/PredefinedElements/InformationItem.test.js +1 -4
  110. package/src/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +32 -6
  111. package/src/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.test.js +3 -1
  112. package/src/components/MaterialUI/DataDisplay/PredefinedElements/SectionToolbar.js +39 -0
  113. package/src/components/MaterialUI/DataDisplay/Table.js +190 -114
  114. package/src/components/MaterialUI/DataDisplay/Table.test.js +246 -1
  115. package/src/components/MaterialUI/DataDisplay/TableProps.js +4 -0
  116. package/src/components/MaterialUI/DataDisplay/TableProps.test.js +2 -0
  117. package/src/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.js +145 -0
  118. package/src/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.test.js +457 -0
  119. package/src/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +5 -1
  120. package/src/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.test.js +7 -1
  121. package/src/components/MaterialUI/Inputs/DatePicker.js +19 -20
  122. package/src/components/MaterialUI/Inputs/DatePicker.test.js +11 -6
  123. package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -0
  124. package/src/components/MaterialUI/Inputs/Select.js +2 -0
  125. package/src/components/MaterialUI/Inputs/SelectProps.js +2 -0
  126. package/src/components/MaterialUI/Inputs/SelectProps.test.js +2 -0
  127. package/src/components/MaterialUI/Inputs/Switch.js +22 -1
  128. package/src/components/MaterialUI/Inputs/Switch.test.js +23 -0
  129. package/src/components/MaterialUI/Inputs/SwitchProps.js +2 -0
  130. package/src/components/MaterialUI/Inputs/SwitchProps.test.js +2 -0
  131. package/src/components/MaterialUI/Inputs/TimePicker.js +10 -19
  132. package/src/components/MaterialUI/Inputs/TimePicker.test.js +278 -117
  133. package/src/components/MaterialUI/hocs/withDeferredTooltip.js +4 -1
  134. package/src/components/MaterialUI/hocs/withDeferredTooltip.test.js +27 -0
  135. package/src/components/MaterialUI/muiThemes.js +1 -0
  136. package/src/components/Navigation/Bar.test.js +92 -87
  137. package/src/components/Provision.js +1 -1
  138. package/src/components/TaskDetailsModal.test.js +1 -3
  139. package/src/constants.js +1 -0
  140. package/src/content/iconsSheet.svg +740 -116
  141. package/src/hocs/withScrollBox.js +32 -19
  142. package/src/hocs/withScrollBox.test.js +15 -3
  143. package/src/hooks/useDaysAndMonthsLocalization.js +79 -0
  144. package/src/hooks/useDaysAndMonthsLocalization.test.js +107 -0
  145. package/src/hooks/useInMemoryPaging.js +78 -0
  146. package/src/hooks/useInMemoryPaging.test.js +515 -0
  147. package/src/hooks/useMultipleFieldEditState.js +11 -4
  148. package/src/hooks/useMultipleFieldEditState.test.js +49 -1
  149. package/src/reducers/metadata.js +6 -1
  150. package/src/reducers/metadata.test.js +31 -0
  151. package/src/requests +1 -0
  152. package/src/schemas/metadata.js +3 -0
  153. package/src/selectors/locale.js +1 -1
  154. package/src/selectors/metadata.js +12 -9
  155. package/src/selectors/metadata.test.js +92 -11
  156. package/src/sharedMessages.js +184 -0
  157. package/src/timezones.json +883 -0
  158. package/src/translations/en-US.json +46 -0
  159. package/src/translations/fr-CA.json +46 -0
  160. package/src/utils/ListHelper.js +203 -0
  161. package/src/utils/ListHelper.test.js +710 -0
  162. package/src/utils/comparisonHelper.js +135 -0
  163. package/src/utils/comparisonHelper.test.js +334 -0
  164. package/src/utils/propertyBagHelper.js +2 -0
  165. package/src/utils/propertyBagHelper.test.js +6 -0
  166. package/src/utils/timezoneHelper.js +10 -135
  167. package/src/utils/timezoneHelper.test.js +7 -7
  168. package/dist/components/Form/FieldList.js +0 -270
  169. package/dist/components/Form/Inputs/FieldButtons.js +0 -66
  170. package/dist/components/Form/Inputs/Number.js +0 -117
  171. package/dist/components/Form/Inputs/SmallButton.js +0 -91
  172. package/dist/components/Form/Inputs/Time.js +0 -86
  173. package/dist/components/Form/Inputs/Translation.js +0 -169
  174. package/src/components/AppFrame/ApplicationSelector/Header.js +0 -34
  175. package/src/components/AppFrame/ApplicationSelector/Header.test.js +0 -23
  176. package/src/components/Form/FieldList.js +0 -210
  177. package/src/components/Form/FieldList.test.js +0 -558
  178. package/src/components/Form/Inputs/FieldButtons.js +0 -90
  179. package/src/components/Form/Inputs/Number.js +0 -60
  180. package/src/components/Form/Inputs/Number.test.js +0 -435
  181. package/src/components/Form/Inputs/SmallButton.js +0 -37
  182. package/src/components/Form/Inputs/SmallButton.test.js +0 -65
  183. package/src/components/Form/Inputs/Time.js +0 -32
  184. package/src/components/Form/Inputs/Time.test.js +0 -41
  185. package/src/components/Form/Inputs/Translation.js +0 -93
  186. package/src/components/Form/Inputs/Translation.test.js +0 -204
@@ -0,0 +1,145 @@
1
+ import React, { useCallback, useRef } from "react";
2
+ import TableProps from "./TableProps";
3
+ import buildHeaderAndRowFromConfig from "./tableHelpers";
4
+ import useInMemoryPaging from "../../../hooks/useInMemoryPaging";
5
+ import Placeholder from "./PredefinedElements/Placeholder";
6
+ import { doesObjectContainsTextCaseInsensitive } from "../../../utils/comparisonHelper";
7
+ import { useIntl } from "react-intl";
8
+ import sharedMessages from "../../../sharedMessages";
9
+ import SearchControl from "../Inputs/PredefinedElements/SearchControl";
10
+ import Table from "./Table";
11
+ import SectionToolbar from "./PredefinedElements/SectionToolbar";
12
+ import TableInfoBar from "./PredefinedElements/TableInfoBar";
13
+
14
+ const listFilter = (list, searchTerm, searchProperties) => {
15
+ if (!searchTerm) {
16
+ return list;
17
+ }
18
+
19
+ return list.filter(item => doesObjectContainsTextCaseInsensitive(item, searchTerm, searchProperties));
20
+ };
21
+
22
+ function getTableInfo(totalCountLabelId, noRowsTotalCountLabelId, formatMessage, totalCount) {
23
+ if (totalCountLabelId && noRowsTotalCountLabelId) {
24
+ if (totalCount) {
25
+ return (
26
+ <TableInfoBar
27
+ tableLabel={formatMessage(totalCountLabelId, {
28
+ quantity: totalCount,
29
+ })}
30
+ />
31
+ );
32
+ }
33
+ return <TableInfoBar tableLabel={formatMessage(noRowsTotalCountLabelId)} />;
34
+ }
35
+
36
+ return null;
37
+ }
38
+
39
+ const TableWithInMemoryPaging = ({
40
+ sortedRows,
41
+ tableName,
42
+ searchProperties = [],
43
+ columnDefs,
44
+ toolbarRightContent,
45
+ pageSize = 20,
46
+ onItemClick = null,
47
+ isReadMode = true,
48
+ totalCountLabelId = null,
49
+ noRowsTotalCountLabelId = null,
50
+ placeholderIcon = null,
51
+ placeholderTitle = null,
52
+ placeholderSubtitle = null,
53
+ rowKeyField = "id",
54
+ }) => {
55
+ const { formatMessage } = useIntl();
56
+ const tableRef = useRef(null);
57
+ const initialSearchProperties = useRef(searchProperties);
58
+ const searchPlaceholder = formatMessage(sharedMessages.search);
59
+ const sortAndFilter = useCallback(
60
+ ({ list, filters }) => {
61
+ const { searchTerm } = filters;
62
+
63
+ return listFilter(list, searchTerm, initialSearchProperties.current);
64
+ },
65
+ [initialSearchProperties],
66
+ );
67
+
68
+ const {
69
+ rows: rowsSlice,
70
+ scrollLoader,
71
+ currentPage,
72
+ filters,
73
+ setFilter,
74
+ totalCount,
75
+ } = useInMemoryPaging({
76
+ viewStateName: tableName,
77
+ tableRef,
78
+ records: sortedRows,
79
+ pageSize: pageSize,
80
+ sortAndFilterFn: sortAndFilter,
81
+ });
82
+
83
+ const { headers, rows } = buildHeaderAndRowFromConfig(columnDefs, rowsSlice, isReadMode, rowKeyField);
84
+ const placeholder = (
85
+ <Placeholder
86
+ icon={placeholderIcon}
87
+ title={placeholderTitle}
88
+ subtitle={placeholderSubtitle}
89
+ cellList={columnDefs.map(col => col.placeholder)}
90
+ />
91
+ );
92
+
93
+ const onSearch = (searchOption, searchText) => {
94
+ setFilter({
95
+ ...filters,
96
+ searchTerm: searchText,
97
+ });
98
+ };
99
+
100
+ const tableProps = new TableProps();
101
+ tableProps.set(TableProps.propNames.stickyHeader, true);
102
+ tableProps.set(TableProps.propNames.withoutTopBorder, true);
103
+ tableProps.set(TableProps.propNames.deepPropsComparation, true);
104
+ tableProps.set(TableProps.propNames.saveScrollbarPosition, true);
105
+ tableProps.set(TableProps.propNames.tableName, tableName);
106
+ if (onItemClick) {
107
+ tableProps.set(TableProps.propNames.onRowClick, onItemClick);
108
+ }
109
+
110
+ const hasToolbar = toolbarRightContent || searchProperties.length > 0;
111
+ const toolbar = hasToolbar ? (
112
+ <SectionToolbar rightContent={toolbarRightContent}>
113
+ {searchProperties.length > 0 && (
114
+ <SearchControl
115
+ placeholder={searchPlaceholder}
116
+ defaultValue={filters.searchTerm}
117
+ onSearch={onSearch}
118
+ focusAndSelectSearchFieldOnLoad={false}
119
+ />
120
+ )}
121
+ </SectionToolbar>
122
+ ) : null;
123
+
124
+ const tableInfo = getTableInfo(totalCountLabelId, noRowsTotalCountLabelId, formatMessage, totalCount);
125
+
126
+ return (
127
+ <>
128
+ {toolbar}
129
+
130
+ <Table
131
+ ref={tableRef}
132
+ headers={headers}
133
+ tableInfo={tableInfo}
134
+ rows={rows}
135
+ tableProps={tableProps}
136
+ placeholder={placeholder}
137
+ scrollLoader={scrollLoader}
138
+ latestPage={currentPage}
139
+ pageLength={pageSize}
140
+ />
141
+ </>
142
+ );
143
+ };
144
+
145
+ export default TableWithInMemoryPaging;
@@ -0,0 +1,457 @@
1
+ import React from "react";
2
+ import sinon from "sinon";
3
+ import { mount } from "enzyme";
4
+ import Table from "./Table";
5
+ import { buildHeaderAndRowFromConfig } from "./tableHelpers";
6
+ import TableInfoBar from "./PredefinedElements/TableInfoBar";
7
+ import { extractMessages, spyOnConsole } from "../../../utils/testUtils";
8
+ import TableProps from "./TableProps";
9
+ import { createMuiTheme } from "./../../../utils/testUtils";
10
+ import { TestWrapper } from "../../../utils/testUtils";
11
+ import TableWithInMemoryPaging from "./TableWithInMemoryPaging";
12
+ import sharedMessages from "../../../sharedMessages";
13
+ import SearchControl from "../Inputs/PredefinedElements/SearchControl";
14
+ import SectionToolbar from "./PredefinedElements/SectionToolbar";
15
+ import buildStore from "../../../buildStore";
16
+ import { fireEvent, render, getByPlaceholderText, getByTestId, queryAllByRole } from "@testing-library/react";
17
+ import Placeholder from "./PredefinedElements/Placeholder";
18
+ import { cloneDeep } from "lodash";
19
+
20
+ const messages = extractMessages(sharedMessages);
21
+
22
+ const getColumnDefs = () => [
23
+ {
24
+ fieldName: "name",
25
+ label: "name",
26
+ placeholder: "t",
27
+ },
28
+ ];
29
+
30
+ const standardListRecords = Array.from(Array(50).keys()).map(k => ({ name: "n" + k, id: k }));
31
+
32
+ describe("TableWithInMemoryPaging", () => {
33
+ const theme = createMuiTheme();
34
+
35
+ let store;
36
+
37
+ spyOnConsole(["error"]);
38
+
39
+ beforeEach(() => {
40
+ global.SUPPORTED_LOCALES = undefined;
41
+ store = buildStore([]); // use the real reducers
42
+ });
43
+
44
+ afterEach(() => {
45
+ delete process.env.SUPPORTED_LOCALES;
46
+ });
47
+
48
+ it("Renders TableWithInMemoryPaging", () => {
49
+ const configDefs = getColumnDefs();
50
+ const { headers, rows } = buildHeaderAndRowFromConfig(configDefs, standardListRecords.slice(0, 20));
51
+
52
+ const component = (
53
+ <TestWrapper
54
+ provider={{ store }}
55
+ memoryRouter
56
+ intlProvider={{ messages }}
57
+ stylesProvider
58
+ muiThemeProvider={{ theme }}
59
+ >
60
+ <TableWithInMemoryPaging
61
+ sortedRows={standardListRecords}
62
+ tableName={"StateName"}
63
+ columnDefs={configDefs}
64
+ pageSize={20}
65
+ />
66
+ </TestWrapper>
67
+ );
68
+
69
+ const tableProps = new TableProps();
70
+
71
+ tableProps.set(TableProps.propNames.stickyHeader, true);
72
+ tableProps.set(TableProps.propNames.withoutTopBorder, true);
73
+ tableProps.set(TableProps.propNames.deepPropsComparation, true);
74
+ tableProps.set(TableProps.propNames.saveScrollbarPosition, true);
75
+ tableProps.set(TableProps.propNames.tableName, "StateName");
76
+
77
+ const expected = (
78
+ <TestWrapper provider={{ store }} memoryRouter intlProvider stylesProvider>
79
+ <Table rows={rows} headers={headers} tableProps={tableProps} />
80
+ </TestWrapper>
81
+ );
82
+
83
+ expect(component, "when mounted", "to satisfy", expected);
84
+ });
85
+
86
+ it("Renders TableWithInMemoryPaging with onItemClick", () => {
87
+ const configDefs = getColumnDefs();
88
+ const onItemClick = sinon.spy().named("onItemClick");
89
+
90
+ const component = (
91
+ <TestWrapper
92
+ provider={{ store }}
93
+ memoryRouter
94
+ intlProvider={{ messages }}
95
+ stylesProvider
96
+ muiThemeProvider={{ theme }}
97
+ >
98
+ <TableWithInMemoryPaging
99
+ sortedRows={standardListRecords}
100
+ tableName={"StateName"}
101
+ columnDefs={configDefs}
102
+ pageSize={20}
103
+ onItemClick={onItemClick}
104
+ />
105
+ </TestWrapper>
106
+ );
107
+
108
+ const mountedComponent = mount(component);
109
+ const row = mountedComponent.find("td").first();
110
+
111
+ row.simulate("click");
112
+ expect(onItemClick, "was called once");
113
+ });
114
+
115
+ it("Renders TableWithInMemoryPaging with right toolbar", () => {
116
+ const configDefs = getColumnDefs();
117
+ const { headers, rows } = buildHeaderAndRowFromConfig(configDefs, standardListRecords.slice(0, 20));
118
+
119
+ const toolbarRightContent = <div>hello</div>;
120
+
121
+ const component = (
122
+ <TestWrapper
123
+ provider={{ store }}
124
+ memoryRouter
125
+ intlProvider={{ messages }}
126
+ stylesProvider
127
+ muiThemeProvider={{ theme }}
128
+ >
129
+ <div>
130
+ <TableWithInMemoryPaging
131
+ sortedRows={standardListRecords}
132
+ tableName={"StateName"}
133
+ columnDefs={configDefs}
134
+ toolbarRightContent={toolbarRightContent}
135
+ pageSize={20}
136
+ />
137
+ </div>
138
+ </TestWrapper>
139
+ );
140
+
141
+ const tableProps = new TableProps();
142
+
143
+ tableProps.set(TableProps.propNames.stickyHeader, true);
144
+ tableProps.set(TableProps.propNames.withoutTopBorder, true);
145
+ tableProps.set(TableProps.propNames.deepPropsComparation, true);
146
+ tableProps.set(TableProps.propNames.saveScrollbarPosition, true);
147
+ tableProps.set(TableProps.propNames.tableName, "StateName");
148
+
149
+ const expected = (
150
+ <TestWrapper
151
+ provider={{ store }}
152
+ memoryRouter
153
+ intlProvider={{ messages }}
154
+ stylesProvider
155
+ muiThemeProvider={{ theme }}
156
+ >
157
+ <div>
158
+ <SectionToolbar rightContent={toolbarRightContent}></SectionToolbar>
159
+ <Table rows={rows} headers={headers} tableProps={tableProps} />
160
+ </div>
161
+ </TestWrapper>
162
+ );
163
+
164
+ expect(component, "when mounted", "to satisfy", expected);
165
+ });
166
+
167
+ it("Renders TableWithInMemoryPaging with search", () => {
168
+ const configDefs = getColumnDefs();
169
+ const { headers, rows } = buildHeaderAndRowFromConfig(configDefs, standardListRecords.slice(0, 20));
170
+
171
+ const component = (
172
+ <TestWrapper
173
+ provider={{ store }}
174
+ memoryRouter
175
+ intlProvider={{ messages }}
176
+ stylesProvider
177
+ muiThemeProvider={{ theme }}
178
+ >
179
+ <div>
180
+ <TableWithInMemoryPaging
181
+ sortedRows={standardListRecords}
182
+ tableName={"StateName"}
183
+ columnDefs={configDefs}
184
+ pageSize={20}
185
+ searchProperties={["name"]}
186
+ />
187
+ </div>
188
+ </TestWrapper>
189
+ );
190
+
191
+ const tableProps = new TableProps();
192
+
193
+ tableProps.set(TableProps.propNames.stickyHeader, true);
194
+ tableProps.set(TableProps.propNames.withoutTopBorder, true);
195
+ tableProps.set(TableProps.propNames.deepPropsComparation, true);
196
+ tableProps.set(TableProps.propNames.saveScrollbarPosition, true);
197
+ tableProps.set(TableProps.propNames.tableName, "StateName");
198
+
199
+ const expected = (
200
+ <TestWrapper
201
+ provider={{ store }}
202
+ memoryRouter
203
+ intlProvider={{ messages }}
204
+ stylesProvider
205
+ muiThemeProvider={{ theme }}
206
+ >
207
+ <div>
208
+ <SectionToolbar>
209
+ <SearchControl placeholder="Search" />
210
+ </SectionToolbar>
211
+ <Table rows={rows} headers={headers} tableProps={tableProps} />
212
+ </div>
213
+ </TestWrapper>
214
+ );
215
+
216
+ expect(component, "when mounted", "to satisfy", expected);
217
+ });
218
+
219
+ it("Renders TableWithInMemoryPaging with search and right toolbar", () => {
220
+ const configDefs = getColumnDefs();
221
+ const { headers, rows } = buildHeaderAndRowFromConfig(configDefs, standardListRecords.slice(0, 20));
222
+ const toolbarRightContent = <div>hello</div>;
223
+
224
+ const component = (
225
+ <TestWrapper
226
+ provider={{ store }}
227
+ memoryRouter
228
+ intlProvider={{ messages }}
229
+ stylesProvider
230
+ muiThemeProvider={{ theme }}
231
+ >
232
+ <div>
233
+ <TableWithInMemoryPaging
234
+ sortedRows={standardListRecords}
235
+ tableName={"StateName"}
236
+ columnDefs={configDefs}
237
+ searchProperties={["name"]}
238
+ toolbarRightContent={toolbarRightContent}
239
+ />
240
+ </div>
241
+ </TestWrapper>
242
+ );
243
+
244
+ const tableProps = new TableProps();
245
+
246
+ tableProps.set(TableProps.propNames.stickyHeader, true);
247
+ tableProps.set(TableProps.propNames.withoutTopBorder, true);
248
+ tableProps.set(TableProps.propNames.deepPropsComparation, true);
249
+ tableProps.set(TableProps.propNames.saveScrollbarPosition, true);
250
+ tableProps.set(TableProps.propNames.tableName, "StateName");
251
+
252
+ const expected = (
253
+ <TestWrapper
254
+ provider={{ store }}
255
+ memoryRouter
256
+ intlProvider={{ messages }}
257
+ stylesProvider
258
+ muiThemeProvider={{ theme }}
259
+ >
260
+ <div>
261
+ <SectionToolbar rightContent={toolbarRightContent}>
262
+ <SearchControl placeholder="Search" />
263
+ </SectionToolbar>
264
+ <Table rows={rows} headers={headers} tableProps={tableProps} />
265
+ </div>
266
+ </TestWrapper>
267
+ );
268
+
269
+ expect(component, "when mounted", "to satisfy", expected);
270
+ });
271
+
272
+ it("Renders TableWithInMemoryPaging search for something", () => {
273
+ const configDefs = getColumnDefs();
274
+
275
+ const component = (
276
+ <TestWrapper
277
+ provider={{ store }}
278
+ memoryRouter
279
+ intlProvider={{ messages }}
280
+ stylesProvider
281
+ muiThemeProvider={{ theme }}
282
+ >
283
+ <div>
284
+ <TableWithInMemoryPaging
285
+ sortedRows={standardListRecords}
286
+ tableName={"StateName"}
287
+ columnDefs={configDefs}
288
+ searchProperties={["name"]}
289
+ />
290
+ </div>
291
+ </TestWrapper>
292
+ );
293
+
294
+ const { container } = render(component);
295
+
296
+ const searchInput = getByPlaceholderText(container, "Search");
297
+ const searchButton = getByTestId(container, "searchButton");
298
+
299
+ const beforeTableRowCount = queryAllByRole(container, "cell").length;
300
+ expect(beforeTableRowCount, "not to be", 0);
301
+
302
+ fireEvent.change(searchInput, {
303
+ target: {
304
+ value: "invalid text",
305
+ },
306
+ });
307
+ fireEvent.click(searchButton);
308
+
309
+ const afterTableRowCount = queryAllByRole(container, "getAllByRole").length;
310
+
311
+ expect(beforeTableRowCount, "not to be", afterTableRowCount);
312
+ expect(afterTableRowCount, "to be", 0);
313
+ });
314
+
315
+ it("Renders TableWithInMemoryPaging with filled count bar", () => {
316
+ const configDefs = getColumnDefs();
317
+ const { headers, rows } = buildHeaderAndRowFromConfig(configDefs, standardListRecords.slice(0, 20));
318
+
319
+ const component = (
320
+ <TestWrapper
321
+ provider={{ store }}
322
+ memoryRouter
323
+ intlProvider={{ messages }}
324
+ stylesProvider
325
+ muiThemeProvider={{ theme }}
326
+ >
327
+ <div>
328
+ <TableWithInMemoryPaging
329
+ sortedRows={standardListRecords}
330
+ tableName={"StateName"}
331
+ columnDefs={configDefs}
332
+ totalCountLabelId={sharedMessages.about}
333
+ noRowsTotalCountLabelId={sharedMessages.help}
334
+ />
335
+ </div>
336
+ </TestWrapper>
337
+ );
338
+
339
+ const tableProps = new TableProps();
340
+
341
+ tableProps.set(TableProps.propNames.stickyHeader, true);
342
+ tableProps.set(TableProps.propNames.withoutTopBorder, true);
343
+ tableProps.set(TableProps.propNames.deepPropsComparation, true);
344
+ tableProps.set(TableProps.propNames.saveScrollbarPosition, true);
345
+ tableProps.set(TableProps.propNames.tableName, "StateName");
346
+
347
+ const tableInfo = <TableInfoBar tableLabel={"About"} />;
348
+
349
+ const expected = (
350
+ <TestWrapper
351
+ provider={{ store }}
352
+ memoryRouter
353
+ intlProvider={{ messages }}
354
+ stylesProvider
355
+ muiThemeProvider={{ theme }}
356
+ >
357
+ <div>
358
+ <Table rows={rows} headers={headers} tableProps={tableProps} tableInfo={tableInfo} />
359
+ </div>
360
+ </TestWrapper>
361
+ );
362
+
363
+ expect(component, "when mounted", "to satisfy", expected);
364
+ });
365
+
366
+ it("Renders TableWithInMemoryPaging with empty count bar and with placeholder", () => {
367
+ const configDefs = getColumnDefs();
368
+ const { headers, rows } = buildHeaderAndRowFromConfig(configDefs, []);
369
+
370
+ const component = (
371
+ <TestWrapper
372
+ provider={{ store }}
373
+ memoryRouter
374
+ intlProvider={{ messages }}
375
+ stylesProvider
376
+ muiThemeProvider={{ theme }}
377
+ >
378
+ <div>
379
+ <TableWithInMemoryPaging
380
+ sortedRows={[]}
381
+ tableName={"StateName"}
382
+ columnDefs={configDefs}
383
+ totalCountLabelId={sharedMessages.about}
384
+ noRowsTotalCountLabelId={sharedMessages.help}
385
+ />
386
+ </div>
387
+ </TestWrapper>
388
+ );
389
+
390
+ const tableProps = new TableProps();
391
+
392
+ tableProps.set(TableProps.propNames.stickyHeader, true);
393
+ tableProps.set(TableProps.propNames.withoutTopBorder, true);
394
+ tableProps.set(TableProps.propNames.deepPropsComparation, true);
395
+ tableProps.set(TableProps.propNames.saveScrollbarPosition, true);
396
+ tableProps.set(TableProps.propNames.tableName, "StateName");
397
+
398
+ const tableInfo = <TableInfoBar tableLabel={"Help"} />;
399
+
400
+ const placeholder = <Placeholder cellList={configDefs.map(col => col.placeholder)} />;
401
+
402
+ const expected = (
403
+ <TestWrapper
404
+ provider={{ store }}
405
+ memoryRouter
406
+ intlProvider={{ messages }}
407
+ stylesProvider
408
+ muiThemeProvider={{ theme }}
409
+ >
410
+ <div>
411
+ <Table
412
+ rows={rows}
413
+ headers={headers}
414
+ tableProps={tableProps}
415
+ tableInfo={tableInfo}
416
+ placeholder={placeholder}
417
+ />
418
+ </div>
419
+ </TestWrapper>
420
+ );
421
+
422
+ expect(component, "when mounted", "to satisfy", expected);
423
+ });
424
+
425
+ it("Renders TableWithInMemoryPaging with a different key", () => {
426
+ const configDefs = getColumnDefs();
427
+ const records = cloneDeep(standardListRecords);
428
+ records.forEach(record => {
429
+ record.anotherId = record.id;
430
+ delete record.id;
431
+ });
432
+
433
+ const component = (
434
+ <TestWrapper
435
+ provider={{ store }}
436
+ memoryRouter
437
+ intlProvider={{ messages }}
438
+ stylesProvider
439
+ muiThemeProvider={{ theme }}
440
+ >
441
+ <div>
442
+ <TableWithInMemoryPaging
443
+ sortedRows={records}
444
+ tableName={"StateName"}
445
+ columnDefs={configDefs}
446
+ searchProperties={["name"]}
447
+ rowKeyField="anotherId"
448
+ />
449
+ </div>
450
+ </TestWrapper>
451
+ );
452
+
453
+ render(component);
454
+
455
+ expect(console.error, "was not called");
456
+ });
457
+ });
@@ -39,9 +39,13 @@ const MultipleLinesText = ({ children, titleValue, textProps, tooltipClasses })
39
39
  [isClamped, setIsClamped],
40
40
  );
41
41
 
42
+ if (!children) {
43
+ return null;
44
+ }
45
+
42
46
  return (
43
47
  <TooltippedTextClamp
44
- disableCssClamp={true}
48
+ disableCssClamp={false}
45
49
  clamp={lineCount}
46
50
  className={classNames(classes.clampedText, customStyles)}
47
51
  children={children.toString()}
@@ -17,7 +17,7 @@ describe("MultipleLinesText", () => {
17
17
 
18
18
  const mountedComponent = mount(component);
19
19
  const expected = (
20
- <TextClamp disableCssClamp={true} clamp={lineCount}>
20
+ <TextClamp disableCssClamp={false} clamp={lineCount}>
21
21
  {text}
22
22
  </TextClamp>
23
23
  );
@@ -89,4 +89,10 @@ describe("MultipleLinesText", () => {
89
89
  expect(() => mount(component), "to throw a", TypeError);
90
90
  });
91
91
  });
92
+
93
+ it("Returns null if children is null", () => {
94
+ const component = <MultipleLinesText>{null}</MultipleLinesText>;
95
+ const mountedComponent = shallow(component);
96
+ expect(mountedComponent.isEmptyRender(), "to be true");
97
+ });
92
98
  });
@@ -6,12 +6,10 @@ import "react-datepicker/dist/react-datepicker.css";
6
6
  import TimePicker from "./TimePicker";
7
7
  import { makeStyles } from "@material-ui/core/styles";
8
8
  import {
9
- getTimeZoneByName,
10
- convertTimeToOtherTimeZone,
9
+ getIanaTimeZoneFromWindowsName,
11
10
  convertTimeToLocalTimeZone,
11
+ getWindowsTimeZone,
12
12
  } from "../../../utils/timezoneHelper";
13
- import { namedLookupLocalizedSelector } from "../../../selectors/metadata";
14
- import { useSelector } from "react-redux";
15
13
 
16
14
  const useStyles = makeStyles(theme => ({
17
15
  container: {
@@ -139,24 +137,31 @@ const WrappedDatePicker = ({
139
137
  readOnly,
140
138
  showTimeSelectOnly,
141
139
  metadata,
142
- timePickerTimeZone,
140
+ timePickerWindowsTimeZone,
143
141
  error,
144
142
  timeOption,
145
143
  ...props
146
144
  }) => {
147
145
  const classes = useStyles({ readOnly });
148
- const timeZoneName = getTimeZoneByName(timePickerTimeZone);
149
- const startDate = value
150
- ? timePickerTimeZone && useTimeZone
151
- ? convertTimeToLocalTimeZone(new Date(value), timeZoneName)
152
- : new Date(value)
153
- : null;
146
+
147
+ const ianaTimeZone =
148
+ useTimeZone && timePickerWindowsTimeZone ? getIanaTimeZoneFromWindowsName(timePickerWindowsTimeZone) : null;
149
+
150
+ const computeDateWithTimezone = React.useCallback(
151
+ date => {
152
+ return date ? (ianaTimeZone ? convertTimeToLocalTimeZone(new Date(date), ianaTimeZone) : new Date(date)) : null;
153
+ },
154
+ [ianaTimeZone],
155
+ );
156
+
157
+ const startDate = computeDateWithTimezone(value);
154
158
  const disabledCls = classNames({ [classes.disabled]: props.disabled });
155
- const localizedTimeZoneName = useSelector(namedLookupLocalizedSelector("customer", "TimeZone", timePickerTimeZone));
159
+
160
+ const windowsTimeZoneName = useTime && showTimeZone ? (timePickerWindowsTimeZone ?? getWindowsTimeZone()) : null;
156
161
 
157
162
  const updateDate = (date, metadata) => {
158
163
  if (onChange) {
159
- onChange(useTimeZone && timePickerTimeZone ? convertTimeToOtherTimeZone(date, timeZoneName) : date, metadata);
164
+ onChange(computeDateWithTimezone(date), metadata);
160
165
  }
161
166
  };
162
167
 
@@ -179,13 +184,7 @@ const WrappedDatePicker = ({
179
184
  showTimeInput={useTime ?? false}
180
185
  useTime={useTime ?? false}
181
186
  customTimeInput={
182
- useTime ? (
183
- <TimePicker
184
- showTimeZone={showTimeZone}
185
- requestedTimeZone={localizedTimeZoneName}
186
- timeOption={timeOption}
187
- />
188
- ) : null
187
+ useTime ? <TimePicker windowsTimeZone={windowsTimeZoneName} timeOption={timeOption} /> : null
189
188
  }
190
189
  timeInputLabel={timeInputLabel ?? ""}
191
190
  readOnly={readOnly}