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

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 (168) 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/DropMenu/Menu.js +79 -45
  13. package/dist/components/DropMenu/index.js +34 -29
  14. package/dist/components/Form/Combination.js +45 -16
  15. package/dist/components/Form/Field.js +57 -38
  16. package/dist/components/Form/FieldElements.js +0 -11
  17. package/dist/components/Form/Fieldset.js +47 -19
  18. package/dist/components/Form/Form.js +22 -9
  19. package/dist/components/Form/FormElement.js +40 -7
  20. package/dist/components/Form/Inputs/Button.js +63 -18
  21. package/dist/components/Form/Inputs/ReadOnly.js +50 -27
  22. package/dist/components/{AppFrame/ApplicationSelector/Header.js → Form/Inputs/Selector.js} +30 -31
  23. package/dist/components/Form/Inputs/Text.js +20 -37
  24. package/dist/components/Form/Inputs/Toggles.js +39 -40
  25. package/dist/components/Form/Inputs/index.js +2 -13
  26. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +31 -11
  27. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/SectionToolbar.js +89 -0
  28. package/dist/components/MaterialUI/DataDisplay/Table.js +109 -18
  29. package/dist/components/MaterialUI/DataDisplay/TableProps.js +5 -1
  30. package/dist/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.js +198 -0
  31. package/dist/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +4 -1
  32. package/dist/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -0
  33. package/dist/components/MaterialUI/Inputs/Select.js +2 -0
  34. package/dist/components/MaterialUI/Inputs/SelectProps.js +2 -0
  35. package/dist/components/MaterialUI/Inputs/Switch.js +17 -1
  36. package/dist/components/MaterialUI/Inputs/SwitchProps.js +2 -0
  37. package/dist/components/MaterialUI/hocs/withDeferredTooltip.js +3 -1
  38. package/dist/components/MaterialUI/muiThemes.js +2 -1
  39. package/dist/constants.js +2 -1
  40. package/dist/content/iconsSheet.svg +740 -116
  41. package/dist/hocs/withScrollBox.js +27 -12
  42. package/dist/hooks/useInMemoryPaging.js +135 -0
  43. package/dist/hooks/useMultipleFieldEditState.js +12 -3
  44. package/dist/reducers/metadata.js +6 -0
  45. package/dist/schemas/metadata.js +9 -1
  46. package/dist/selectors/locale.js +1 -0
  47. package/dist/selectors/metadata.js +14 -11
  48. package/dist/sharedMessages.js +4 -0
  49. package/dist/utils/ListHelper.js +271 -0
  50. package/dist/utils/comparisonHelper.js +185 -0
  51. package/dist/utils/propertyBagHelper.js +3 -1
  52. package/package.json +1 -1
  53. package/src/actions/metadata.js +11 -0
  54. package/src/actions/metadata.test.js +27 -0
  55. package/src/actions/requestsApi.js +6 -0
  56. package/src/components/AppFrame/About.js +97 -117
  57. package/src/components/AppFrame/About.test.js +128 -90
  58. package/src/components/AppFrame/Anchor.js +34 -36
  59. package/src/components/AppFrame/Anchor.test.js +5 -68
  60. package/src/components/AppFrame/AppFrame.js +31 -40
  61. package/src/components/AppFrame/AppFrame.test.js +424 -445
  62. package/src/components/AppFrame/Help.js +23 -20
  63. package/src/components/AppFrame/Help.test.js +3 -3
  64. package/src/components/AppFrame/MenuItem.js +106 -126
  65. package/src/components/AppFrame/MenuItem.test.js +78 -169
  66. package/src/components/AppFrame/Preferences.js +110 -98
  67. package/src/components/AppFrame/Preferences.test.js +115 -219
  68. package/src/components/AppFrame/Sidebar.js +39 -41
  69. package/src/components/AppFrame/Sidebar.test.js +88 -168
  70. package/src/components/AppFrame/Topbar.js +59 -52
  71. package/src/components/AppFrame/Topbar.test.js +31 -39
  72. package/src/components/ColumnWrapper.js +18 -9
  73. package/src/components/DropMenu/DropMenu.test.js +185 -224
  74. package/src/components/DropMenu/Menu.js +73 -80
  75. package/src/components/DropMenu/Menu.test.js +35 -86
  76. package/src/components/DropMenu/index.js +19 -15
  77. package/src/components/Form/Combination.js +35 -28
  78. package/src/components/Form/Combination.test.js +6 -19
  79. package/src/components/Form/Field.js +53 -66
  80. package/src/components/Form/Field.test.js +29 -51
  81. package/src/components/Form/FieldElements.js +0 -14
  82. package/src/components/Form/FieldElements.test.js +104 -111
  83. package/src/components/Form/Fieldset.js +42 -37
  84. package/src/components/Form/Fieldset.test.js +14 -7
  85. package/src/components/Form/Form.js +11 -7
  86. package/src/components/Form/Form.test.js +75 -56
  87. package/src/components/Form/FormElement.js +24 -16
  88. package/src/components/Form/InputField.test.js +24 -30
  89. package/src/components/Form/Inputs/Button.js +58 -14
  90. package/src/components/Form/Inputs/Button.test.js +32 -7
  91. package/src/components/Form/Inputs/Inputs.test.js +0 -7
  92. package/src/components/Form/Inputs/ReadOnly.js +34 -28
  93. package/src/components/Form/Inputs/ReadOnly.test.js +45 -7
  94. package/src/components/Form/Inputs/Selector.js +22 -0
  95. package/src/components/Form/Inputs/Selector.test.js +105 -0
  96. package/src/components/Form/Inputs/Text.js +15 -44
  97. package/src/components/Form/Inputs/Text.test.js +20 -29
  98. package/src/components/Form/Inputs/Toggles.js +27 -26
  99. package/src/components/Form/Inputs/Toggles.test.js +22 -28
  100. package/src/components/Form/Inputs/index.js +4 -15
  101. package/src/components/MaterialUI/DataDisplay/PredefinedElements/InformationItem.test.js +1 -4
  102. package/src/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +32 -6
  103. package/src/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.test.js +3 -1
  104. package/src/components/MaterialUI/DataDisplay/PredefinedElements/SectionToolbar.js +39 -0
  105. package/src/components/MaterialUI/DataDisplay/Table.js +190 -114
  106. package/src/components/MaterialUI/DataDisplay/Table.test.js +246 -1
  107. package/src/components/MaterialUI/DataDisplay/TableProps.js +4 -0
  108. package/src/components/MaterialUI/DataDisplay/TableProps.test.js +2 -0
  109. package/src/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.js +145 -0
  110. package/src/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.test.js +457 -0
  111. package/src/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +5 -1
  112. package/src/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.test.js +7 -1
  113. package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -0
  114. package/src/components/MaterialUI/Inputs/Select.js +2 -0
  115. package/src/components/MaterialUI/Inputs/SelectProps.js +2 -0
  116. package/src/components/MaterialUI/Inputs/SelectProps.test.js +2 -0
  117. package/src/components/MaterialUI/Inputs/Switch.js +22 -1
  118. package/src/components/MaterialUI/Inputs/Switch.test.js +23 -0
  119. package/src/components/MaterialUI/Inputs/SwitchProps.js +2 -0
  120. package/src/components/MaterialUI/Inputs/SwitchProps.test.js +2 -0
  121. package/src/components/MaterialUI/hocs/withDeferredTooltip.js +4 -1
  122. package/src/components/MaterialUI/hocs/withDeferredTooltip.test.js +27 -0
  123. package/src/components/MaterialUI/muiThemes.js +1 -0
  124. package/src/components/Navigation/Bar.test.js +92 -87
  125. package/src/components/TaskDetailsModal.test.js +1 -3
  126. package/src/constants.js +1 -0
  127. package/src/content/iconsSheet.svg +740 -116
  128. package/src/hocs/withScrollBox.js +32 -19
  129. package/src/hocs/withScrollBox.test.js +15 -3
  130. package/src/hooks/useInMemoryPaging.js +78 -0
  131. package/src/hooks/useInMemoryPaging.test.js +515 -0
  132. package/src/hooks/useMultipleFieldEditState.js +11 -4
  133. package/src/hooks/useMultipleFieldEditState.test.js +49 -1
  134. package/src/reducers/metadata.js +6 -1
  135. package/src/reducers/metadata.test.js +31 -0
  136. package/src/requests +1 -0
  137. package/src/schemas/metadata.js +3 -0
  138. package/src/selectors/locale.js +1 -1
  139. package/src/selectors/metadata.js +12 -9
  140. package/src/selectors/metadata.test.js +92 -11
  141. package/src/sharedMessages.js +4 -0
  142. package/src/translations/en-US.json +1 -0
  143. package/src/translations/fr-CA.json +1 -0
  144. package/src/utils/ListHelper.js +203 -0
  145. package/src/utils/ListHelper.test.js +710 -0
  146. package/src/utils/comparisonHelper.js +135 -0
  147. package/src/utils/comparisonHelper.test.js +334 -0
  148. package/src/utils/propertyBagHelper.js +2 -0
  149. package/src/utils/propertyBagHelper.test.js +6 -0
  150. package/dist/components/Form/FieldList.js +0 -270
  151. package/dist/components/Form/Inputs/FieldButtons.js +0 -66
  152. package/dist/components/Form/Inputs/Number.js +0 -117
  153. package/dist/components/Form/Inputs/SmallButton.js +0 -91
  154. package/dist/components/Form/Inputs/Time.js +0 -86
  155. package/dist/components/Form/Inputs/Translation.js +0 -169
  156. package/src/components/AppFrame/ApplicationSelector/Header.js +0 -34
  157. package/src/components/AppFrame/ApplicationSelector/Header.test.js +0 -23
  158. package/src/components/Form/FieldList.js +0 -210
  159. package/src/components/Form/FieldList.test.js +0 -558
  160. package/src/components/Form/Inputs/FieldButtons.js +0 -90
  161. package/src/components/Form/Inputs/Number.js +0 -60
  162. package/src/components/Form/Inputs/Number.test.js +0 -435
  163. package/src/components/Form/Inputs/SmallButton.js +0 -37
  164. package/src/components/Form/Inputs/SmallButton.test.js +0 -65
  165. package/src/components/Form/Inputs/Time.js +0 -32
  166. package/src/components/Form/Inputs/Time.test.js +0 -41
  167. package/src/components/Form/Inputs/Translation.js +0 -93
  168. package/src/components/Form/Inputs/Translation.test.js +0 -204
@@ -1,7 +1,7 @@
1
1
  import { useSelector } from "react-redux";
2
2
  import { validationRules } from "../utils/modelValidationHelper";
3
3
  import { getModifiedModels } from "../selectors/view";
4
- import { setEditModelField, setEditModelFieldError } from "../actions/view";
4
+ import { setEditModelField, setEditModelFieldError, removeEditModelFieldError } from "../actions/view";
5
5
  import { useDispatchWithModulesData } from "./../hooks/useDispatchWithModulesData";
6
6
 
7
7
  /* This hook is used when a component has a dynamic number of fields that can be edited (e.g.: Orders' Custom Configuration Parameters).
@@ -25,7 +25,7 @@ const useMultipleFieldEditState = (entityId, sectionName, initialValues, extende
25
25
  const mergedValidationRules = { ...validationRules, ...extendedValidationRules };
26
26
  const modifiedStates = useSelector(getModifiedModels(entityId))[sectionName] || {};
27
27
 
28
- const useDynamicFieldState = (id, fieldName, errorTypes = []) => {
28
+ const useDynamicFieldState = (id, fieldName, errorTypes = [], fieldDependencies = {}) => {
29
29
  const keys = [id, fieldName];
30
30
 
31
31
  const initialValue = initialValues[id]?.[fieldName] ?? "";
@@ -42,12 +42,15 @@ const useMultipleFieldEditState = (entityId, sectionName, initialValues, extende
42
42
  dispatch(setEditModelField, [keys, initialValue, initialValue, entityId, sectionName]);
43
43
  };
44
44
 
45
- const isEditStateValid = value => {
45
+ const isEditStateValid = (value, dependencies = {}) => {
46
46
  const valueToValidate = value ?? editState.value;
47
47
 
48
48
  let hasAnyValidationErrors = false;
49
49
  errorTypes.forEach(errorType => {
50
- const isValid = mergedValidationRules[errorType](valueToValidate, id, fieldName);
50
+ const isValid = mergedValidationRules[errorType](valueToValidate, id, fieldName, {
51
+ ...fieldDependencies,
52
+ ...dependencies,
53
+ });
51
54
 
52
55
  if (isValid === false) {
53
56
  dispatch(setEditModelFieldError, [keys, errorType, entityId, sectionName]);
@@ -57,6 +60,10 @@ const useMultipleFieldEditState = (entityId, sectionName, initialValues, extende
57
60
  }
58
61
  });
59
62
 
63
+ if (!hasAnyValidationErrors) {
64
+ dispatch(removeEditModelFieldError, [keys, entityId, sectionName]);
65
+ }
66
+
60
67
  return !hasAnyValidationErrors;
61
68
  };
62
69
 
@@ -5,7 +5,7 @@ import Immutable from "immutable";
5
5
  import sinon from "sinon";
6
6
  import { mount } from "enzyme";
7
7
  import * as useDispatchWithModulesDataMock from "./useDispatchWithModulesData";
8
- import { setEditModelField, setEditModelFieldError } from "./../actions/view";
8
+ import { removeEditModelFieldError, setEditModelField, setEditModelFieldError } from "./../actions/view";
9
9
  import { validationErrorTypes } from "./../constants";
10
10
  import _ from "lodash";
11
11
 
@@ -404,6 +404,54 @@ describe("useMultipleFieldEditState", () => {
404
404
  }
405
405
  });
406
406
 
407
+ it("Updates edit view value and reset error correctly with custom validation rules when validation was passed", () => {
408
+ const useDispatchWithModulesDataSpy = sinon.spy();
409
+ const useDispatchWithModulesDataStub = sinon
410
+ .stub(useDispatchWithModulesDataMock, "useDispatchWithModulesData")
411
+ .returns(useDispatchWithModulesDataSpy);
412
+
413
+ try {
414
+ // TODOJOC
415
+ const mountedComponent = mountComponent();
416
+
417
+ const fieldComponent = mountedComponent.find(`#id1-prop1-update`);
418
+
419
+ const event = {
420
+ target: {
421
+ value: "anotherValue",
422
+ },
423
+ };
424
+
425
+ fieldComponent.invoke("onClick")(event);
426
+
427
+ const resetEvent = {
428
+ target: {
429
+ value: "custom",
430
+ },
431
+ };
432
+
433
+ fieldComponent.invoke("onClick")(resetEvent);
434
+
435
+ const id = "id1";
436
+ const fieldName = "prop1";
437
+ const initialFieldValue = fieldInitialValues[id][fieldName];
438
+
439
+ expect(useDispatchWithModulesDataSpy, "to have a call satisfying", {
440
+ args: [setEditModelField, [[id, fieldName], "anotherValue", initialFieldValue, entityId, sectionName]],
441
+ });
442
+
443
+ expect(useDispatchWithModulesDataSpy, "to have a call satisfying", {
444
+ args: [setEditModelFieldError, [[id, fieldName], "customRule", entityId, sectionName]],
445
+ });
446
+
447
+ expect(useDispatchWithModulesDataSpy, "to have a call satisfying", {
448
+ args: [removeEditModelFieldError, [[id, fieldName], entityId, sectionName]],
449
+ });
450
+ } finally {
451
+ useDispatchWithModulesDataStub.restore();
452
+ }
453
+ });
454
+
407
455
  it.each([
408
456
  ["id1", "prop1"],
409
457
  ["id1", "prop2"],
@@ -1,7 +1,7 @@
1
1
  import Immutable from "immutable";
2
2
  import { normalize } from "normalizr";
3
3
  import { definitionsListSchema } from "../schemas/definitions";
4
- import { profileAttributeGroupsListSchema } from "../schemas/metadata";
4
+ import { orderAttributeGroupsListSchema, profileAttributeGroupsListSchema } from "../schemas/metadata";
5
5
  import { productDefinitionsListSchema } from "../schemas/productDefinitions";
6
6
  import {
7
7
  GET_ORDER_LOOKUPS_SUCCESS,
@@ -26,6 +26,7 @@ import {
26
26
  UPDATE_PROFILE_DEFINITION_SUCCESS,
27
27
  GET_ORDER_LOOKUP_SUCCESS,
28
28
  GET_CUSTOMER_LOOKUP_SUCCESS,
29
+ GET_ORDER_ATTRIBUTE_GROUPS_SUCCESS,
29
30
  } from "../actions/metadata";
30
31
 
31
32
  export const ORDER_MODULE_NAME = "order";
@@ -154,6 +155,10 @@ const metadataReducer = (state = initialState, action) => {
154
155
  const normalizedData = normalize(action.payload?.profileAttributeGroups, profileAttributeGroupsListSchema);
155
156
  return state.set("profileAttributeGroups", Immutable.fromJS(normalizedData.entities.metadata));
156
157
  }
158
+ case GET_ORDER_ATTRIBUTE_GROUPS_SUCCESS: {
159
+ const normalizedData = normalize(action.payload?.orderAttributeGroups, orderAttributeGroupsListSchema);
160
+ return state.set("orderAttributeGroups", Immutable.fromJS(normalizedData.entities.metadata));
161
+ }
157
162
  case SAVE_ORDER_LOOKUP_SUCCESS:
158
163
  case GET_ORDER_LOOKUP_SUCCESS:
159
164
  return lookupReducerHelper.getLookupsQuerySuccess(ORDER_MODULE_NAME, state, {
@@ -22,6 +22,7 @@ import {
22
22
  ADD_CUSTOMER_LOOKUP_SUCCESS,
23
23
  GET_ORDER_LOOKUP_SUCCESS,
24
24
  GET_CUSTOMER_LOOKUP_SUCCESS,
25
+ GET_ORDER_ATTRIBUTE_GROUPS_SUCCESS,
25
26
  } from "../actions/metadata";
26
27
  import reducer from "./metadata";
27
28
 
@@ -1553,3 +1554,33 @@ describe("profileAttributeGroups", () => {
1553
1554
  );
1554
1555
  });
1555
1556
  });
1557
+
1558
+ describe("orderAttributeGroups", () => {
1559
+ it("saves orderAttributeGroups metadata", () => {
1560
+ const orderAttributeGroupsPayload = {
1561
+ displayOrder: 1,
1562
+ name: "Default",
1563
+ displayName: {
1564
+ "en-US": "Default",
1565
+ "fr-CA": "Défaut",
1566
+ },
1567
+ isSystem: false,
1568
+ };
1569
+ const oldState = Immutable.fromJS({
1570
+ orderAttributeGroups: {},
1571
+ });
1572
+ const action = {
1573
+ type: GET_ORDER_ATTRIBUTE_GROUPS_SUCCESS,
1574
+ payload: { orderAttributeGroups: [orderAttributeGroupsPayload] },
1575
+ };
1576
+ const newState = reducer(oldState, action);
1577
+ return expect(newState, "not to be", oldState).and(
1578
+ "to equal",
1579
+ Immutable.fromJS({
1580
+ orderAttributeGroups: {
1581
+ Default: orderAttributeGroupsPayload,
1582
+ },
1583
+ }),
1584
+ );
1585
+ });
1586
+ });
package/src/requests CHANGED
@@ -8,6 +8,7 @@ getCountriesRequest
8
8
  getCustomerDefinitionsRequest
9
9
  getCustomerLookupRequest
10
10
  getCustomerLookupsRequest
11
+ getOrderAttributeGroupsRequest
11
12
  getOrderDefinitionRequest
12
13
  getOrderLookupRequest
13
14
  getOrderLookupsRequest
@@ -3,3 +3,6 @@ import { schema } from "normalizr";
3
3
  export const profileAttributeGroupsSchema = new schema.Entity("metadata", {}, { idAttribute: "name" });
4
4
  export const profileAttributeGroupsListSchema = [profileAttributeGroupsSchema];
5
5
  export default profileAttributeGroupsListSchema;
6
+
7
+ export const orderAttributeGroupsSchema = new schema.Entity("metadata", {}, { idAttribute: "name" });
8
+ export const orderAttributeGroupsListSchema = [orderAttributeGroupsSchema];
@@ -28,7 +28,7 @@ export const defaultCulture = createSelector(localeData, locale => locale.get("d
28
28
  export const orderedCultureList = createSelector(cultureList, defaultCulture, (cultures, defaultCulture) =>
29
29
  cultures.sort((a, b) => {
30
30
  /*istanbul ignore if */ if (a === defaultCulture) return -1;
31
- if (b === defaultCulture) return 1;
31
+ /*istanbul ignore if */ if (b === defaultCulture) return 1;
32
32
  return 0;
33
33
  }),
34
34
  );
@@ -210,26 +210,29 @@ export const baseAttributesSelector = memoize((moduleName, entityName) =>
210
210
  createSelector(mappedDefinitionAttributesSelector(moduleName, entityName), filterIsBuiltInAttributes(true)),
211
211
  );
212
212
 
213
- export const profileAttributeGroupsSelector = createSelector(metadata, currentLocaleOrDefault, (meta, locale) => {
214
- const groups = meta.get("profileAttributeGroups");
215
- return !groups?.size ? null : groups?.map(x => setTranslationWithFallbackField(locale, x, "name", "displayName"));
216
- });
213
+ export const moduleAttributeGroupsSelector = memoize(moduleName =>
214
+ createSelector(metadata, currentLocaleOrDefault, (meta, locale) => {
215
+ const metaDataGroupName = moduleName === "order" ? "orderAttributeGroups" : "profileAttributeGroups";
216
+ const groups = meta.get(metaDataGroupName);
217
+ return !groups?.size ? null : groups?.map(x => setTranslationWithFallbackField(locale, x, "name", "displayName"));
218
+ }),
219
+ );
217
220
 
218
221
  export const groupedCustomAttributesDefinitionSelector = memoize((moduleName, entityName) =>
219
222
  createSelector(
220
- profileAttributeGroupsSelector,
223
+ moduleAttributeGroupsSelector(moduleName),
221
224
  customAttributesSelector(moduleName, entityName),
222
225
  currentLocaleOrDefault,
223
- (allProfileAttributeGroups, attributes) =>
226
+ (allAttributeGroups, attributes) =>
224
227
  attributes
225
228
  .groupBy(item => item.get("groupId"))
226
229
  .map(group => {
227
230
  const groupId = group.first().get("groupId");
228
- const profileAttributeGroup = allProfileAttributeGroups?.get(groupId);
231
+ const attributeGroup = allAttributeGroups?.get(groupId);
229
232
  return Immutable.fromJS({
230
233
  id: groupId,
231
- name: profileAttributeGroup?.get("displayName"),
232
- displayOrder: profileAttributeGroup?.get("displayOrder"),
234
+ name: attributeGroup?.get("displayName"),
235
+ displayOrder: attributeGroup?.get("displayOrder"),
233
236
  })
234
237
  .set(
235
238
  "baseAttributes",
@@ -18,7 +18,6 @@ import {
18
18
  productPropertyValueSelector,
19
19
  productPropertyValuesSelector,
20
20
  variantPropertyKeyValuesSelector,
21
- profileAttributeGroupsSelector,
22
21
  selectCurrentLookupDetails,
23
22
  mappedDefinitionsListSelector,
24
23
  baseAttributesSelector,
@@ -1367,6 +1366,29 @@ describe("definitions", () => {
1367
1366
  allowPriceLists: true,
1368
1367
  },
1369
1368
  },
1369
+ order: {
1370
+ ORDER: {
1371
+ displayName: {
1372
+ "en-CA": "Order",
1373
+ "en-US": "Order",
1374
+ "fr-CA": "ORDER",
1375
+ },
1376
+ entityTypeName: "CUSTOMER",
1377
+ isBuiltIn: true,
1378
+ attributes: [
1379
+ baseBuitInAttribute1,
1380
+ baseBuitInAttribute2,
1381
+ customProfileAttribute1,
1382
+ customProfileAttribute2,
1383
+ baseBuitInAttribute4,
1384
+ baseBuitInAttribute3,
1385
+ baseCustomAttribute1,
1386
+ baseCustomAttribute3,
1387
+ baseCustomAttribute2,
1388
+ ],
1389
+ isSharedEntity: true,
1390
+ },
1391
+ },
1370
1392
  },
1371
1393
  profileAttributeGroups: {
1372
1394
  Default: {
@@ -1388,20 +1410,21 @@ describe("definitions", () => {
1388
1410
  },
1389
1411
  },
1390
1412
  },
1413
+ orderAttributeGroups: {
1414
+ Default: {
1415
+ displayOrder: 1,
1416
+ name: "Default",
1417
+ displayName: {
1418
+ "en-US": "Default en-US",
1419
+ "en-CA": "Default en-CA",
1420
+ "fr-CA": "Default fr-CA",
1421
+ },
1422
+ },
1423
+ },
1391
1424
  },
1392
1425
  });
1393
1426
  });
1394
1427
 
1395
- it("will get null if profileAttributeGroups are not found in metadata", () => {
1396
- const newState = Immutable.fromJS({
1397
- locale: {},
1398
- metadata: {
1399
- profileAttributeGroups: {},
1400
- },
1401
- });
1402
- expect(profileAttributeGroupsSelector, "when called with", [newState], "to satisfy", null);
1403
- });
1404
-
1405
1428
  it("will return correct customer profile definition", () => {
1406
1429
  const expected = Immutable.fromJS({
1407
1430
  CustomProfile1: {
@@ -1591,6 +1614,64 @@ describe("definitions", () => {
1591
1614
  );
1592
1615
  });
1593
1616
 
1617
+ it("will return correct custom order attributes definition in correct order", () => {
1618
+ const expectedGroup1 = customProfileAttribute1.groupId;
1619
+ const expectedItem1 = {
1620
+ ...customProfileAttribute1,
1621
+ ...{ displayName: customProfileAttribute1.displayName["en-US"] },
1622
+ };
1623
+
1624
+ const expectedBaseCustomWithOrder1 = {
1625
+ ...baseCustomAttribute1,
1626
+ ...{ displayName: baseCustomAttribute1.displayName["en-US"] },
1627
+ };
1628
+
1629
+ const expectedBaseCustomWithOrder2 = {
1630
+ ...baseCustomAttribute2,
1631
+ ...{ displayName: baseCustomAttribute2.displayName["en-US"] },
1632
+ };
1633
+
1634
+ const expectedBaseCustomWithOrder3 = {
1635
+ ...baseCustomAttribute3,
1636
+ ...{ displayName: baseCustomAttribute3.displayName["en-US"] },
1637
+ };
1638
+
1639
+ const expected = Immutable.fromJS({
1640
+ [expectedGroup1]: {
1641
+ id: expectedGroup1,
1642
+ name: "Default en-US",
1643
+ baseAttributes: [expectedBaseCustomWithOrder1, expectedBaseCustomWithOrder2, expectedBaseCustomWithOrder3],
1644
+ profileAttributes: [expectedItem1],
1645
+ },
1646
+ });
1647
+
1648
+ expect(
1649
+ groupedCustomAttributesDefinitionSelector,
1650
+ "when called with",
1651
+ ["order", "ORDER"],
1652
+ "when called with",
1653
+ [state],
1654
+ "to satisfy",
1655
+ expected,
1656
+ );
1657
+ });
1658
+
1659
+ it("will return correct custom attributes definition in correct order for unknown module", () => {
1660
+ const expected = Immutable.fromJS({});
1661
+
1662
+ const newState = state.removeIn(["metadata", "profileAttributeGroups"]);
1663
+
1664
+ expect(
1665
+ groupedCustomAttributesDefinitionSelector,
1666
+ "when called with",
1667
+ ["invalid", "invalid"],
1668
+ "when called with",
1669
+ [newState],
1670
+ "to satisfy",
1671
+ expected,
1672
+ );
1673
+ });
1674
+
1594
1675
  it("will return correct full base (built in) customer definition attributes", () => {
1595
1676
  const expected = Immutable.fromJS([
1596
1677
  baseBuitInAttribute1,
@@ -299,6 +299,10 @@ const sharedMessages = defineMessages({
299
299
  id: "orc-shared.lastModifiedBy",
300
300
  defaultMessage: "Last Modified By",
301
301
  },
302
+ search: {
303
+ id: "orc-shared.search",
304
+ defaultMessage: "Search",
305
+ },
302
306
  });
303
307
 
304
308
  export default sharedMessages;
@@ -58,6 +58,7 @@
58
58
  "orc-shared.scopeChangeWithUnsavedDataConfirmation": "One or more entities opened will be closed with unsaved data. Would you like to change scope?",
59
59
  "orc-shared.scopeChangeWithUnsavedDataTitle": "Confirm scope change without saving data",
60
60
  "orc-shared.scopeFilterPlaceholder": "Type a scope name",
61
+ "orc-shared.search": "Search",
61
62
  "orc-shared.shared": "Shared",
62
63
  "orc-shared.showFewerLanguages": "Show fewer languages",
63
64
  "orc-shared.showMoreLanguages": "Show more languages",
@@ -58,6 +58,7 @@
58
58
  "orc-shared.scopeChangeWithUnsavedDataConfirmation": "Une ou plusieurs entités ouvertes seront fermées, entraînant la perte de données non-sauvegardées. Voulez-vous vraiment changer de Scope?",
59
59
  "orc-shared.scopeChangeWithUnsavedDataTitle": "Confirmation du changement de Scope sans sauvegarde",
60
60
  "orc-shared.scopeFilterPlaceholder": "Entrez un nom de Scope",
61
+ "orc-shared.search": "Recherche",
61
62
  "orc-shared.shared": "Partagé",
62
63
  "orc-shared.showFewerLanguages": "Afficher moins de langues",
63
64
  "orc-shared.showMoreLanguages": "Afficher plus de langues",
@@ -0,0 +1,203 @@
1
+ import Immutable from "immutable";
2
+ import { isObject } from "lodash";
3
+
4
+ export const ListInfoPropertyName = "listInfo";
5
+
6
+ const standardInfoKeys = ["scope", "page", "filters", "sorting", "totalCount", "nextPageToLoad", "index", "list"];
7
+
8
+ class ListReducerHelper {
9
+ constructor(groupPropertyName) {
10
+ this.groupPropertyName = groupPropertyName;
11
+ }
12
+
13
+ setNextPageToLoad = (state, nextPageToLoad) => {
14
+ return state.setIn([this.groupPropertyName, "nextPageToLoad"], nextPageToLoad);
15
+ };
16
+
17
+ setResults = (state, listInfo, forceReset = false) => {
18
+ return state.withMutations(s => {
19
+ const page = s.getIn([this.groupPropertyName, "nextPageToLoad"]);
20
+
21
+ const entities = Immutable.fromJS(listInfo.indexEntities || {});
22
+ if (page === 1 || forceReset) {
23
+ s.setIn([this.groupPropertyName, "index"], entities);
24
+ s.setIn([this.groupPropertyName, "list"], Immutable.fromJS(listInfo.listEntities));
25
+ } else {
26
+ s.mergeIn([this.groupPropertyName, "index"], entities);
27
+ s.setIn(
28
+ [this.groupPropertyName, "list"],
29
+ s.getIn([this.groupPropertyName, "list"]).concat(Immutable.fromJS(listInfo.listEntities)),
30
+ );
31
+ }
32
+
33
+ s.setIn([this.groupPropertyName, "totalCount"], listInfo.totalCount);
34
+ });
35
+ };
36
+
37
+ setCurrentInfo = (state, { resetList, scope, filters, sorting, ...others } = {}) => {
38
+ return state.withMutations(s => {
39
+ if (resetList) {
40
+ s.setIn([this.groupPropertyName, "nextPageToLoad"], 1);
41
+ s.setIn([this.groupPropertyName, "page"], null);
42
+ s.setIn([this.groupPropertyName, "index"], Immutable.fromJS({}));
43
+ s.setIn([this.groupPropertyName, "list"], Immutable.fromJS([]));
44
+ s.setIn([this.groupPropertyName, "totalCount"], 0);
45
+ } else {
46
+ const nextPageToLoad = state.getIn([this.groupPropertyName, "nextPageToLoad"]);
47
+ s.setIn([this.groupPropertyName, "nextPageToLoad"], nextPageToLoad);
48
+ s.setIn([this.groupPropertyName, "page"], nextPageToLoad);
49
+ }
50
+
51
+ s.setIn([this.groupPropertyName, "scope"], scope ?? null);
52
+ s.setIn([this.groupPropertyName, "filters"], Immutable.fromJS(filters ?? null));
53
+ s.setIn([this.groupPropertyName, "sorting"], Immutable.fromJS(sorting ?? null));
54
+
55
+ const otherKeys = Object.keys(others);
56
+
57
+ s.get(this.groupPropertyName)
58
+ .keySeq()
59
+ .forEach(key => {
60
+ if (!standardInfoKeys.includes(key) && !otherKeys.includes(key)) {
61
+ s.removeIn([this.groupPropertyName, key]);
62
+ }
63
+ });
64
+
65
+ otherKeys.forEach(key => {
66
+ s.setIn([this.groupPropertyName, key], isObject(others[key]) ? Immutable.fromJS(others[key]) : others[key]);
67
+ });
68
+ });
69
+ };
70
+
71
+ addIndexWithMutations = (mutator, id, value) => {
72
+ mutator.setIn([this.groupPropertyName, "index", id], Immutable.fromJS(value));
73
+ };
74
+
75
+ appendIdToListWithMutations = (mutator, id) => {
76
+ mutator.setIn([this.groupPropertyName, "list"], mutator.getIn([this.groupPropertyName, "list"]).push(id));
77
+ };
78
+
79
+ updateIndexWithMutations = (mutator, id, value) => {
80
+ const key = [this.groupPropertyName, "index", id];
81
+ if (mutator.getIn(key)) {
82
+ mutator.setIn(key, Immutable.fromJS(value));
83
+ }
84
+ };
85
+
86
+ removeFromIndexWithMutations = (mutator, id) => {
87
+ mutator.removeIn([this.groupPropertyName, "index", id]);
88
+ };
89
+
90
+ resetListInfo = (state, propertiesToKeep = {}) => {
91
+ let updatedState = state
92
+ .setIn([this.groupPropertyName, "nextPageToLoad"], 1)
93
+ .setIn([this.groupPropertyName, "index"], Immutable.fromJS({}))
94
+ .setIn([this.groupPropertyName, "list"], Immutable.fromJS([]))
95
+ .setIn([this.groupPropertyName, "totalCount"], 0);
96
+
97
+ if (!propertiesToKeep.filters) {
98
+ updatedState = updatedState.setIn([this.groupPropertyName, "filters"], null);
99
+ }
100
+
101
+ if (!propertiesToKeep.sorting) {
102
+ updatedState = updatedState.setIn([this.groupPropertyName, "sorting"], null);
103
+ }
104
+
105
+ if (!propertiesToKeep.scope) {
106
+ updatedState = updatedState.setIn([this.groupPropertyName, "scope"], null);
107
+ }
108
+
109
+ if (!propertiesToKeep.page) {
110
+ updatedState = updatedState.setIn([this.groupPropertyName, "page"], null);
111
+ }
112
+
113
+ return updatedState;
114
+ };
115
+ }
116
+
117
+ class ListSelectorHelper {
118
+ constructor(groupPropertyName) {
119
+ this.groupPropertyName = groupPropertyName;
120
+ }
121
+
122
+ getCurrentInfo = state => {
123
+ const listInfo = state.get(this.groupPropertyName) || Immutable.Map();
124
+
125
+ const info = {
126
+ currentScope: listInfo.get("scope"),
127
+ currentPage: listInfo.get("page"),
128
+ currentFilters: listInfo.get("filters")?.toJS(),
129
+ currentSorting: listInfo.get("sorting")?.toJS(),
130
+ totalCount: listInfo.get("totalCount"),
131
+ };
132
+
133
+ listInfo.mapKeys((key, value) => {
134
+ if (standardInfoKeys.includes(key)) {
135
+ // standard key, nothing to do
136
+ } else {
137
+ info[key] = value?.toJS ? value.toJS() : value;
138
+ }
139
+ });
140
+
141
+ return info;
142
+ };
143
+
144
+ getIndex = state => {
145
+ return state.getIn([this.groupPropertyName, "index"]);
146
+ };
147
+
148
+ getList = state => {
149
+ return state.getIn([this.groupPropertyName, "list"]);
150
+ };
151
+
152
+ getNextPageToLoad = state => {
153
+ return state.getIn([this.groupPropertyName, "nextPageToLoad"]);
154
+ };
155
+ }
156
+
157
+ class ListHelper {
158
+ constructor(groupPropertyName = ListInfoPropertyName) {
159
+ this.groupPropertyName = groupPropertyName;
160
+ this.reducer = new ListReducerHelper(this.groupPropertyName);
161
+ this.selector = new ListSelectorHelper(this.groupPropertyName);
162
+ }
163
+
164
+ static defaultInstance = new ListHelper();
165
+ static reducer = ListHelper.defaultInstance.reducer;
166
+ static selector = ListHelper.defaultInstance.selector;
167
+ static createInitialListInfo = ListHelper.defaultInstance.createInitialListInfo;
168
+ static createListInfoFrom = ListHelper.defaultInstance.createListInfoFrom;
169
+
170
+ createInitialListInfo = (additionalValues = null) => {
171
+ return this.createListInfoFrom({
172
+ ...additionalValues,
173
+ });
174
+ };
175
+
176
+ createListInfoFrom = ({
177
+ sorting,
178
+ filters,
179
+ scope,
180
+ page,
181
+ nextPageToLoad,
182
+ index,
183
+ list,
184
+ totalCount,
185
+ ...additionalValues
186
+ } = {}) => {
187
+ return {
188
+ [this.groupPropertyName]: {
189
+ sorting: sorting ?? null,
190
+ filters: filters ?? null,
191
+ scope: scope ?? null,
192
+ page: page ?? null,
193
+ nextPageToLoad: nextPageToLoad ?? 1,
194
+ index: index ?? {},
195
+ list: list ?? [],
196
+ totalCount: totalCount ?? 0,
197
+ ...additionalValues,
198
+ },
199
+ };
200
+ };
201
+ }
202
+
203
+ export default ListHelper;