orc-shared 1.6.0-dev.1 → 1.6.0-dev.11

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 (134) hide show
  1. package/dist/actions/applications.js +1 -1
  2. package/dist/actions/authentication.js +1 -1
  3. package/dist/actions/countries.js +1 -1
  4. package/dist/actions/globalErrorMessages.js +67 -0
  5. package/dist/actions/locale.js +1 -1
  6. package/dist/actions/makeApiAction.js +3 -3
  7. package/dist/actions/makeOrcApiAction.js +2 -2
  8. package/dist/actions/metadata.js +3 -3
  9. package/dist/actions/navigation.js +2 -2
  10. package/dist/actions/scopes.js +1 -1
  11. package/dist/actions/tasks.js +1 -1
  12. package/dist/actions/timezones.js +1 -1
  13. package/dist/actions/versionInfo.js +1 -1
  14. package/dist/buildStore.js +5 -3
  15. package/dist/components/AppFrame/About.js +3 -3
  16. package/dist/components/AppFrame/AppFrame.js +1 -1
  17. package/dist/components/AppFrame/Preferences.js +3 -3
  18. package/dist/components/ApplicationModuleLoader.js +1 -1
  19. package/dist/components/CategoryList.js +1 -1
  20. package/dist/components/DropMenu/index.js +1 -1
  21. package/dist/components/Form/FieldList.js +2 -2
  22. package/dist/components/Form/InputField.js +1 -1
  23. package/dist/components/Form/Inputs/Translation.js +3 -3
  24. package/dist/components/List/List.js +1 -1
  25. package/dist/components/List/enhanceColumnDefs.js +2 -2
  26. package/dist/components/Loader.js +1 -1
  27. package/dist/components/MaterialUI/DataDisplay/CollapsableList.js +1 -1
  28. package/dist/components/MaterialUI/DataDisplay/Notification.js +3 -3
  29. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/GlobalErrorMessages.js +162 -0
  30. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/LookupDisplayValue.js +89 -0
  31. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.js +3 -2
  32. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/Translations.js +2 -2
  33. package/dist/components/MaterialUI/DataDisplay/SelectionList.js +1 -1
  34. package/dist/components/MaterialUI/DataDisplay/Table.js +3 -3
  35. package/dist/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +1 -1
  36. package/dist/components/MaterialUI/DataDisplay/TransferList.js +1 -1
  37. package/dist/components/MaterialUI/DataDisplay/tableHelpers.js +1 -1
  38. package/dist/components/MaterialUI/DataDisplay/useTableSelection.js +3 -3
  39. package/dist/components/MaterialUI/Feedback/NotificationContext.js +1 -1
  40. package/dist/components/MaterialUI/Feedback/loadingScreen.js +1 -1
  41. package/dist/components/MaterialUI/Inputs/Autocomplete.js +2 -2
  42. package/dist/components/MaterialUI/Inputs/InputBase.js +98 -16
  43. package/dist/components/MaterialUI/Inputs/InputBaseProps.js +3 -1
  44. package/dist/components/MaterialUI/Inputs/Select.js +3 -3
  45. package/dist/components/MaterialUI/Inputs/Switch.js +2 -2
  46. package/dist/components/MaterialUI/Inputs/TimePicker.js +1 -1
  47. package/dist/components/MaterialUI/Inputs/createInput.js +2 -2
  48. package/dist/components/MaterialUI/Navigation/DropDownMenu.js +1 -1
  49. package/dist/components/MaterialUI/Navigation/TabBar.js +1 -1
  50. package/dist/components/MaterialUI/Navigation/TabLabel.js +1 -1
  51. package/dist/components/MaterialUI/ScopeSelector/ScopeTreeView.js +1 -1
  52. package/dist/components/MaterialUI/Surfaces/ExpansionPanel.js +1 -1
  53. package/dist/components/MaterialUI/Surfaces/SectionExpansionPanel.js +1 -1
  54. package/dist/components/MaterialUI/hocs/withDeferredPopper.js +2 -2
  55. package/dist/components/MaterialUI/hocs/withDeferredTooltip.js +1 -1
  56. package/dist/components/MaterialUI/muiThemes.js +2 -2
  57. package/dist/components/Modal/index.js +1 -1
  58. package/dist/components/Modules.js +1 -1
  59. package/dist/components/MultiSelector.js +1 -1
  60. package/dist/components/Navigation/Bar.js +3 -3
  61. package/dist/components/Navigation/Tab.js +1 -1
  62. package/dist/components/Navigation/useNavigationState.js +3 -3
  63. package/dist/components/Routing/Page.js +5 -2
  64. package/dist/components/Routing/SegmentPage.js +5 -2
  65. package/dist/components/Routing/SubPage.js +11 -13
  66. package/dist/components/Routing/withWaypointing.js +2 -2
  67. package/dist/components/Scope/ScopeNode.js +1 -1
  68. package/dist/components/Scope/index.js +3 -3
  69. package/dist/components/Scope/useScopeConfirmationModalState.js +2 -2
  70. package/dist/components/Selector.js +1 -1
  71. package/dist/components/Text.js +1 -1
  72. package/dist/components/Treeview/Node.js +2 -2
  73. package/dist/components/Treeview/index.js +3 -3
  74. package/dist/getThemeOverrides.js +2 -2
  75. package/dist/hocs/withNavigationLink.js +1 -1
  76. package/dist/hocs/withScopeData.js +1 -1
  77. package/dist/hocs/withToggle.js +1 -1
  78. package/dist/hocs/withUpdateHandler.js +2 -2
  79. package/dist/hocs/withViewState.js +1 -1
  80. package/dist/hooks/useDispatchWithErrorHandling.js +106 -0
  81. package/dist/hooks/useEditState.js +2 -2
  82. package/dist/hooks/useEntityLoader.js +3 -3
  83. package/dist/hooks/useFullEntityEditState.js +3 -3
  84. package/dist/hooks/useInfiniteScroll.js +1 -1
  85. package/dist/hooks/useLabelMessage.js +2 -2
  86. package/dist/hooks/useMultipleFieldEditState.js +2 -2
  87. package/dist/hooks/useNotificationRequestState.js +4 -4
  88. package/dist/hooks/useToggle.js +1 -1
  89. package/dist/reducers/authentication.js +1 -1
  90. package/dist/reducers/globalErrorMessages.js +79 -0
  91. package/dist/reducers/request.js +2 -1
  92. package/dist/reducers/scopes.js +3 -0
  93. package/dist/selectors/authentication.js +2 -2
  94. package/dist/selectors/globalErrorMessages.js +58 -0
  95. package/dist/selectors/metadata.js +4 -4
  96. package/dist/selectors/modules.js +2 -2
  97. package/dist/utils/buildUrl.js +2 -2
  98. package/dist/utils/flatten.js +3 -3
  99. package/dist/utils/responseProcessingHelper.js +87 -0
  100. package/dist/utils/testUtils.js +1 -1
  101. package/dist/utils/timezoneHelper.js +1 -1
  102. package/package.json +7 -4
  103. package/src/actions/globalErrorMessages.js +12 -0
  104. package/src/actions/globalErrorMessages.test.js +21 -0
  105. package/src/buildStore.js +2 -0
  106. package/src/components/MaterialUI/DataDisplay/PredefinedElements/GlobalErrorMessages.js +108 -0
  107. package/src/components/MaterialUI/DataDisplay/PredefinedElements/GlobalErrorMessages.test.js +468 -0
  108. package/src/components/MaterialUI/DataDisplay/PredefinedElements/LookupDisplayValue.js +29 -0
  109. package/src/components/MaterialUI/DataDisplay/PredefinedElements/LookupDisplayValue.test.js +147 -0
  110. package/src/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.js +2 -1
  111. package/src/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.test.js +20 -0
  112. package/src/components/MaterialUI/Inputs/InputBase.js +97 -15
  113. package/src/components/MaterialUI/Inputs/InputBase.test.js +339 -3
  114. package/src/components/MaterialUI/Inputs/InputBaseProps.js +2 -0
  115. package/src/components/MaterialUI/Inputs/InputBaseProps.test.js +2 -0
  116. package/src/components/Routing/Page.js +12 -1
  117. package/src/components/Routing/SegmentPage.js +12 -1
  118. package/src/components/Routing/SubPage.js +4 -8
  119. package/src/components/Routing/SubPage.test.js +46 -0
  120. package/src/hooks/useDispatchWithErrorHandling.js +57 -0
  121. package/src/hooks/useDispatchWithErrorHandling.test.js +230 -0
  122. package/src/reducers/globalErrorMessages.js +25 -0
  123. package/src/reducers/globalErrorMessages.test.js +66 -0
  124. package/src/reducers/request.js +2 -1
  125. package/src/reducers/request.test.js +23 -0
  126. package/src/reducers/scopes.js +3 -0
  127. package/src/reducers/scopes.test.js +47 -0
  128. package/src/selectors/globalErrorMessages.js +11 -0
  129. package/src/selectors/globalErrorMessages.test.js +25 -0
  130. package/src/selectors/metadata.js +1 -1
  131. package/src/selectors/metadata.test.js +12 -0
  132. package/src/utils/buildUrl.js +1 -1
  133. package/src/utils/responseProcessingHelper.js +42 -0
  134. package/src/utils/responseProcessingHelper.test.js +218 -0
@@ -0,0 +1,21 @@
1
+ import {
2
+ POP_GLOBAL_ERROR_MESSAGE,
3
+ popGlobalErrorMessage,
4
+ PUSH_GLOBAL_ERROR_MESSAGE,
5
+ pushGlobalErrorMessage,
6
+ } from "./globalErrorMessages";
7
+
8
+ describe("pushGlobalErrorMessage", () => {
9
+ it("create action with message", () =>
10
+ expect(pushGlobalErrorMessage, "when called with", [{ custom: "message" }], "to equal", {
11
+ type: PUSH_GLOBAL_ERROR_MESSAGE,
12
+ payload: { custom: "message" },
13
+ }));
14
+ });
15
+
16
+ describe("popGlobalErrorMessage", () => {
17
+ it("create action", () =>
18
+ expect(popGlobalErrorMessage, "when called with", [], "to equal", {
19
+ type: POP_GLOBAL_ERROR_MESSAGE,
20
+ }));
21
+ });
package/src/buildStore.js CHANGED
@@ -21,6 +21,7 @@ import modulesReducer from "./reducers/modules";
21
21
  import metadataReducer from "./reducers/metadata";
22
22
  import requestStatesReducer from "./reducers/requestStates";
23
23
  import tasksReducer from "./reducers/tasks";
24
+ import globalErrorMessagesReducer from "./reducers/globalErrorMessages";
24
25
 
25
26
  window.BUILD_ID = BUILD_ID;
26
27
  window.BUILD_NUMBER = BUILD_NUMBER;
@@ -67,6 +68,7 @@ const buildStore = (reducers, devOptions = {}) => {
67
68
  metadata: metadataReducer,
68
69
  requestStates: requestStatesReducer,
69
70
  tasks: tasksReducer,
71
+ globalErrorMessages: globalErrorMessagesReducer,
70
72
  });
71
73
  const rootReducer = buildReducer(reducers);
72
74
 
@@ -0,0 +1,108 @@
1
+ import React from "react";
2
+ import { useIntl } from "react-intl";
3
+ import { makeStyles } from "@material-ui/core/styles";
4
+ import sharedMessages from "../../../../sharedMessages";
5
+ import Grid from "@material-ui/core/Grid";
6
+ import ListItemText from "@material-ui/core/ListItemText";
7
+ import List from "@material-ui/core/List";
8
+ import ListItem from "@material-ui/core/ListItem";
9
+ import ListItemIcon from "@material-ui/core/ListItemIcon";
10
+ import LookupDisplayValue from "./LookupDisplayValue";
11
+ import ActionModal from "./ActionModal";
12
+ import { useDispatch, useSelector } from "react-redux";
13
+ import { firstDialogErrorMessageSelector } from "../../../../selectors/globalErrorMessages";
14
+ import { popGlobalErrorMessage } from "../../../../actions/globalErrorMessages";
15
+
16
+ const useStyles = makeStyles(theme => ({
17
+ grid: {
18
+ maxHeight: "40vh",
19
+ overflowY: "auto",
20
+ },
21
+ }));
22
+
23
+ const useMessageStyles = makeStyles(theme => ({
24
+ label: {
25
+ fontSize: theme.typography.fontSize,
26
+ color: theme.palette.grey.dark,
27
+ fontFamily: theme.typography.fontFamily,
28
+ },
29
+ }));
30
+
31
+ export const GlobalErrorMessageLabel = ({ children }) => {
32
+ const classes = useMessageStyles();
33
+
34
+ return <span className={classes.label}>{children}</span>;
35
+ };
36
+
37
+ const GlobalErrorMessagesModal = ({ children }) => {
38
+ const classes = useStyles();
39
+ const { formatMessage } = useIntl();
40
+ const dispatch = useDispatch();
41
+
42
+ const msg = useSelector(firstDialogErrorMessageSelector);
43
+
44
+ if (msg === null) {
45
+ return <>{children}</>;
46
+ }
47
+
48
+ const closeCallback = () => {
49
+ dispatch(popGlobalErrorMessage());
50
+ };
51
+ const actions = [{ label: sharedMessages.close, isPrimary: true, handler: closeCallback }];
52
+
53
+ let content = (
54
+ <Grid container spacing={2} className={classes.grid}>
55
+ <Grid container item spacing={0}>
56
+ {msg.description && (
57
+ <Grid item xs={12}>
58
+ {msg.description}
59
+ </Grid>
60
+ )}
61
+
62
+ {msg.messages?.length > 0 && (
63
+ <Grid item xs={12}>
64
+ <List className={classes.root}>
65
+ {msg.messages.map((msg, index) => {
66
+ const hasLookup = msg.lookupModule && msg.lookupName && msg.lookupKey;
67
+
68
+ return (
69
+ <ListItem key={index}>
70
+ <ListItemIcon>●</ListItemIcon>
71
+ <ListItemText>
72
+ {hasLookup && (
73
+ <LookupDisplayValue
74
+ moduleName={msg.lookupModule}
75
+ lookupName={msg.lookupName}
76
+ lookupKey={msg.lookupKey}
77
+ lookupReplacementValues={msg.lookupReplacementValues}
78
+ labelComponent={GlobalErrorMessageLabel}
79
+ />
80
+ )}
81
+ {!hasLookup && <GlobalErrorMessageLabel>{msg.message}</GlobalErrorMessageLabel>}
82
+ </ListItemText>
83
+ </ListItem>
84
+ );
85
+ })}
86
+ </List>
87
+ </Grid>
88
+ )}
89
+ </Grid>
90
+ </Grid>
91
+ );
92
+
93
+ return (
94
+ <>
95
+ {children}
96
+ {
97
+ <ActionModal
98
+ title={msg.title || formatMessage(sharedMessages.error)}
99
+ message={content}
100
+ open={true}
101
+ actions={actions}
102
+ />
103
+ }
104
+ </>
105
+ );
106
+ };
107
+
108
+ export default GlobalErrorMessagesModal;
@@ -0,0 +1,468 @@
1
+ import React from "react";
2
+ import GlobalErrorMessagesModal, { GlobalErrorMessageLabel } from "./GlobalErrorMessages";
3
+ import { createMuiTheme, extractMessages, TestWrapper } from "../../../../utils/testUtils";
4
+ import Immutable from "immutable";
5
+ import ActionModal from "./ActionModal";
6
+ import sharedMessages from "../../../../sharedMessages";
7
+ import Grid from "@material-ui/core/Grid";
8
+ import ListItemText from "@material-ui/core/ListItemText";
9
+ import List from "@material-ui/core/List";
10
+ import ListItem from "@material-ui/core/ListItem";
11
+ import ListItemIcon from "@material-ui/core/ListItemIcon";
12
+ import { popGlobalErrorMessage } from "../../../../actions/globalErrorMessages";
13
+ import sinon from "sinon";
14
+ import { render } from "@testing-library/react";
15
+ import { getByText, fireEvent } from "@testing-library/react";
16
+
17
+ const theme = createMuiTheme();
18
+ const messages = extractMessages(sharedMessages);
19
+
20
+ const metadataPayload = {
21
+ metadata: {
22
+ lookups: {
23
+ order: {
24
+ index: {
25
+ OrderStatus: {
26
+ lookupName: "OrderStatus",
27
+ values: {
28
+ Completed: {
29
+ id: "03caa0ebecd04792a96c2f8df5b9b35a",
30
+ value: "Completed",
31
+ lookupId: "OrderStatus",
32
+ displayName: {
33
+ "en-US": "Completed",
34
+ },
35
+ sortOrder: 0,
36
+ isActive: true,
37
+ isSystem: true,
38
+ },
39
+ InProgress: {
40
+ id: "13caa0ebecd04792a96c2f8df5b9b35a",
41
+ value: "InProgress",
42
+ lookupId: "InProgress",
43
+ displayName: {
44
+ "en-US": "In Progress",
45
+ },
46
+ sortOrder: 1,
47
+ isActive: false,
48
+ isSystem: true,
49
+ },
50
+ MessageWithArguments: {
51
+ id: "23caa0ebecd04792a96c2f8df5b9b35a",
52
+ value: "MessageWithArguments",
53
+ lookupId: "MessageWithArguments",
54
+ displayName: {
55
+ "en-US": "This is the message with arguments {customKey1} {customKey2}",
56
+ },
57
+ sortOrder: 1,
58
+ isActive: false,
59
+ isSystem: true,
60
+ },
61
+ },
62
+ displayName: {
63
+ "en-US": "Order Status",
64
+ },
65
+ isActive: true,
66
+ isSystem: true,
67
+ },
68
+ },
69
+ list: [],
70
+ },
71
+ },
72
+ },
73
+ };
74
+
75
+ describe("GlobalErrorMessagesModal", () => {
76
+ let store, state, dispatch;
77
+ beforeEach(() => {
78
+ state = Immutable.fromJS({
79
+ locale: {
80
+ locale: "en",
81
+ supportedLocales: ["en", "fr"],
82
+ },
83
+ globalErrorMessages: {
84
+ dialog: {
85
+ errorMessages: [],
86
+ },
87
+ },
88
+ ...metadataPayload,
89
+ });
90
+
91
+ dispatch = sinon.spy().named("dispatch");
92
+
93
+ store = {
94
+ subscribe: () => {},
95
+ getState: () => state,
96
+ dispatch: dispatch,
97
+ };
98
+ });
99
+
100
+ const errorMessages = [
101
+ {
102
+ title: "ze title",
103
+ description: "desc",
104
+ messages: [
105
+ { message: "error msg" },
106
+ { lookupModule: "order", lookupName: "OrderStatus", lookupKey: "InProgress" },
107
+ {
108
+ lookupModule: "order",
109
+ lookupName: "OrderStatus",
110
+ lookupKey: "MessageWithArguments",
111
+ lookupReplacementValues: { customKey1: "val1", customKey2: "val2" },
112
+ },
113
+ ],
114
+ },
115
+ ];
116
+ const expectedMessagesContent = (
117
+ <Grid item xs={12}>
118
+ <List>
119
+ <ListItem key={0}>
120
+ <ListItemIcon>●</ListItemIcon>
121
+ <ListItemText>
122
+ <GlobalErrorMessageLabel>error msg</GlobalErrorMessageLabel>
123
+ </ListItemText>
124
+ </ListItem>
125
+ <ListItem key={1}>
126
+ <ListItemIcon>●</ListItemIcon>
127
+ <ListItemText>
128
+ <GlobalErrorMessageLabel>In Progress</GlobalErrorMessageLabel>
129
+ </ListItemText>
130
+ </ListItem>
131
+ <ListItem key={2}>
132
+ <ListItemIcon>●</ListItemIcon>
133
+ <ListItemText>
134
+ <GlobalErrorMessageLabel>This is the message with arguments val1 val2</GlobalErrorMessageLabel>
135
+ </ListItemText>
136
+ </ListItem>
137
+ </List>
138
+ </Grid>
139
+ );
140
+
141
+ it("Renders no dialog because state contains no messages", () => {
142
+ const component = (
143
+ <TestWrapper
144
+ provider={{ store }}
145
+ intlProvider={{ messages }}
146
+ memoryRouter
147
+ stylesProvider
148
+ muiThemeProvider={{ theme }}
149
+ >
150
+ <GlobalErrorMessagesModal>
151
+ <div>children</div>
152
+ </GlobalErrorMessagesModal>
153
+ </TestWrapper>
154
+ );
155
+
156
+ const expected = (
157
+ <TestWrapper
158
+ provider={{ store }}
159
+ intlProvider={{ messages }}
160
+ memoryRouter
161
+ stylesProvider
162
+ muiThemeProvider={{ theme }}
163
+ >
164
+ <div>children</div>
165
+ </TestWrapper>
166
+ );
167
+
168
+ expect(component, "when mounted", "to satisfy", expected);
169
+ });
170
+
171
+ it("Renders dialog with messages", () => {
172
+ state = state.setIn(["globalErrorMessages", "dialog", "errorMessages"], Immutable.fromJS(errorMessages));
173
+
174
+ const component = (
175
+ <TestWrapper
176
+ provider={{ store }}
177
+ intlProvider={{ messages }}
178
+ memoryRouter
179
+ stylesProvider
180
+ muiThemeProvider={{ theme }}
181
+ >
182
+ <div>
183
+ <GlobalErrorMessagesModal>
184
+ <div>children</div>
185
+ </GlobalErrorMessagesModal>
186
+ </div>
187
+ </TestWrapper>
188
+ );
189
+
190
+ const content = (
191
+ <Grid container spacing={2}>
192
+ <Grid container item spacing={0}>
193
+ <Grid item xs={12}>
194
+ desc
195
+ </Grid>
196
+ {expectedMessagesContent}
197
+ </Grid>
198
+ </Grid>
199
+ );
200
+
201
+ const expected = (
202
+ <TestWrapper
203
+ provider={{ store }}
204
+ intlProvider={{ messages }}
205
+ memoryRouter
206
+ stylesProvider
207
+ muiThemeProvider={{ theme }}
208
+ >
209
+ <div>
210
+ <div>children</div>
211
+ <ActionModal
212
+ title={"ze title"}
213
+ message={content}
214
+ open={true}
215
+ actions={[{ label: sharedMessages.close, isPrimary: true }]}
216
+ />
217
+ </div>
218
+ </TestWrapper>
219
+ );
220
+
221
+ expect(component, "when mounted", "to satisfy", expected);
222
+ });
223
+
224
+ it("Renders dialog with messages with default title", () => {
225
+ state = state.setIn(
226
+ ["globalErrorMessages", "dialog", "errorMessages"],
227
+ Immutable.fromJS([{ ...errorMessages[0], title: null }]),
228
+ );
229
+
230
+ const component = (
231
+ <TestWrapper
232
+ provider={{ store }}
233
+ intlProvider={{ messages }}
234
+ memoryRouter
235
+ stylesProvider
236
+ muiThemeProvider={{ theme }}
237
+ >
238
+ <div>
239
+ <GlobalErrorMessagesModal>
240
+ <div>children</div>
241
+ </GlobalErrorMessagesModal>
242
+ </div>
243
+ </TestWrapper>
244
+ );
245
+
246
+ const content = (
247
+ <Grid container spacing={2}>
248
+ <Grid container item spacing={0}>
249
+ <Grid item xs={12}>
250
+ desc
251
+ </Grid>
252
+ {expectedMessagesContent}
253
+ </Grid>
254
+ </Grid>
255
+ );
256
+
257
+ const expected = (
258
+ <TestWrapper
259
+ provider={{ store }}
260
+ intlProvider={{ messages }}
261
+ memoryRouter
262
+ stylesProvider
263
+ muiThemeProvider={{ theme }}
264
+ >
265
+ <div>
266
+ <div>children</div>
267
+ <ActionModal
268
+ title={"Error"}
269
+ message={content}
270
+ open={true}
271
+ actions={[{ label: sharedMessages.close, isPrimary: true }]}
272
+ />
273
+ </div>
274
+ </TestWrapper>
275
+ );
276
+
277
+ expect(component, "when mounted", "to satisfy", expected);
278
+ });
279
+
280
+ it("Renders dialog with messages without description", () => {
281
+ state = state.setIn(
282
+ ["globalErrorMessages", "dialog", "errorMessages"],
283
+ Immutable.fromJS([{ ...errorMessages[0], description: null }]),
284
+ );
285
+
286
+ const component = (
287
+ <TestWrapper
288
+ provider={{ store }}
289
+ intlProvider={{ messages }}
290
+ memoryRouter
291
+ stylesProvider
292
+ muiThemeProvider={{ theme }}
293
+ >
294
+ <div>
295
+ <GlobalErrorMessagesModal>
296
+ <div>children</div>
297
+ </GlobalErrorMessagesModal>
298
+ </div>
299
+ </TestWrapper>
300
+ );
301
+
302
+ const content = (
303
+ <Grid container spacing={2}>
304
+ <Grid container item spacing={0}>
305
+ {expectedMessagesContent}
306
+ </Grid>
307
+ </Grid>
308
+ );
309
+
310
+ const expected = (
311
+ <TestWrapper
312
+ provider={{ store }}
313
+ intlProvider={{ messages }}
314
+ memoryRouter
315
+ stylesProvider
316
+ muiThemeProvider={{ theme }}
317
+ >
318
+ <div>
319
+ <div>children</div>
320
+ <ActionModal
321
+ title={"ze title"}
322
+ message={content}
323
+ open={true}
324
+ actions={[{ label: sharedMessages.close, isPrimary: true }]}
325
+ />
326
+ </div>
327
+ </TestWrapper>
328
+ );
329
+
330
+ expect(component, "when mounted", "to satisfy", expected);
331
+ });
332
+
333
+ it("Renders dialog without messages (empty)", () => {
334
+ state = state.setIn(
335
+ ["globalErrorMessages", "dialog", "errorMessages"],
336
+ Immutable.fromJS([{ ...errorMessages[0], messages: [] }]),
337
+ );
338
+
339
+ const component = (
340
+ <TestWrapper
341
+ provider={{ store }}
342
+ intlProvider={{ messages }}
343
+ memoryRouter
344
+ stylesProvider
345
+ muiThemeProvider={{ theme }}
346
+ >
347
+ <div>
348
+ <GlobalErrorMessagesModal>
349
+ <div>children</div>
350
+ </GlobalErrorMessagesModal>
351
+ </div>
352
+ </TestWrapper>
353
+ );
354
+
355
+ const content = (
356
+ <Grid container spacing={2}>
357
+ <Grid container item spacing={0}>
358
+ <Grid item xs={12}>
359
+ desc
360
+ </Grid>
361
+ </Grid>
362
+ </Grid>
363
+ );
364
+
365
+ const expected = (
366
+ <TestWrapper
367
+ provider={{ store }}
368
+ intlProvider={{ messages }}
369
+ memoryRouter
370
+ stylesProvider
371
+ muiThemeProvider={{ theme }}
372
+ >
373
+ <div>
374
+ <div>children</div>
375
+ <ActionModal
376
+ title={"ze title"}
377
+ message={content}
378
+ open={true}
379
+ actions={[{ label: sharedMessages.close, isPrimary: true }]}
380
+ />
381
+ </div>
382
+ </TestWrapper>
383
+ );
384
+
385
+ expect(component, "when mounted", "to satisfy", expected);
386
+ });
387
+
388
+ it("Renders dialog without messages (null)", () => {
389
+ state = state.setIn(
390
+ ["globalErrorMessages", "dialog", "errorMessages"],
391
+ Immutable.fromJS([{ ...errorMessages[0], messages: null }]),
392
+ );
393
+
394
+ const component = (
395
+ <TestWrapper
396
+ provider={{ store }}
397
+ intlProvider={{ messages }}
398
+ memoryRouter
399
+ stylesProvider
400
+ muiThemeProvider={{ theme }}
401
+ >
402
+ <div>
403
+ <GlobalErrorMessagesModal>
404
+ <div>children</div>
405
+ </GlobalErrorMessagesModal>
406
+ </div>
407
+ </TestWrapper>
408
+ );
409
+
410
+ const content = (
411
+ <Grid container spacing={2}>
412
+ <Grid container item spacing={0}>
413
+ <Grid item xs={12}>
414
+ desc
415
+ </Grid>
416
+ </Grid>
417
+ </Grid>
418
+ );
419
+
420
+ const expected = (
421
+ <TestWrapper
422
+ provider={{ store }}
423
+ intlProvider={{ messages }}
424
+ memoryRouter
425
+ stylesProvider
426
+ muiThemeProvider={{ theme }}
427
+ >
428
+ <div>
429
+ <div>children</div>
430
+ <ActionModal
431
+ title={"ze title"}
432
+ message={content}
433
+ open={true}
434
+ actions={[{ label: sharedMessages.close, isPrimary: true }]}
435
+ />
436
+ </div>
437
+ </TestWrapper>
438
+ );
439
+
440
+ expect(component, "when mounted", "to satisfy", expected);
441
+ });
442
+
443
+ it("The close button pop the message", () => {
444
+ state = state.setIn(["globalErrorMessages", "dialog", "errorMessages"], Immutable.fromJS(errorMessages));
445
+
446
+ const component = (
447
+ <TestWrapper
448
+ provider={{ store }}
449
+ intlProvider={{ messages }}
450
+ memoryRouter
451
+ stylesProvider
452
+ muiThemeProvider={{ theme }}
453
+ >
454
+ <div>
455
+ <GlobalErrorMessagesModal>
456
+ <div>children</div>
457
+ </GlobalErrorMessagesModal>
458
+ </div>
459
+ </TestWrapper>
460
+ );
461
+
462
+ const { container } = render(component);
463
+ const button = getByText(container, "Close");
464
+ fireEvent.click(button);
465
+
466
+ expect(dispatch, "to have calls satisfying", [{ args: [popGlobalErrorMessage()] }]);
467
+ });
468
+ });
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ import TooltippedTypography from "../TooltippedElements/TooltippedTypography";
3
+ import { namedLookupLocalizedSelector } from "../../../../selectors/metadata";
4
+ import { useSelector } from "react-redux";
5
+
6
+ const LookupDisplayValue = ({
7
+ moduleName,
8
+ lookupName,
9
+ lookupKey,
10
+ lookupReplacementValues,
11
+ labelComponent,
12
+ ...otherProps
13
+ }) => {
14
+ let value = useSelector(namedLookupLocalizedSelector(moduleName, lookupName, lookupKey));
15
+
16
+ if (value && lookupReplacementValues) {
17
+ Object.keys(lookupReplacementValues).forEach(key => {
18
+ value = value.replace("{" + key + "}", lookupReplacementValues[key]);
19
+ });
20
+ }
21
+
22
+ const DisplayComponent =
23
+ labelComponent ??
24
+ (({ children }) => <TooltippedTypography noWrap {...otherProps} children={children} titleValue={value} />);
25
+
26
+ return <DisplayComponent>{value}</DisplayComponent>;
27
+ };
28
+
29
+ export default LookupDisplayValue;