orc-shared 1.1.0-dev.9 → 1.2.0-dev.10

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 (309) 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/locale.js +1 -1
  5. package/dist/actions/makeApiAction.js +73 -3
  6. package/dist/actions/makeOrcApiAction.js +2 -2
  7. package/dist/actions/metadata.js +295 -31
  8. package/dist/actions/modules.js +63 -1
  9. package/dist/actions/navigation.js +3 -3
  10. package/dist/actions/requestState.js +78 -0
  11. package/dist/actions/requestsApi.js +58 -7
  12. package/dist/actions/scopes.js +59 -22
  13. package/dist/actions/timezones.js +1 -1
  14. package/dist/actions/toasts.js +1 -1
  15. package/dist/actions/versionInfo.js +1 -1
  16. package/dist/actions/view.js +1 -1
  17. package/dist/buildStore.js +7 -4
  18. package/dist/components/AppFrame/About.js +6 -5
  19. package/dist/components/AppFrame/ApplicationSelector/ApplicationDialog.js +115 -62
  20. package/dist/components/AppFrame/ApplicationSelector/index.js +45 -47
  21. package/dist/components/AppFrame/MenuItem.js +6 -15
  22. package/dist/components/AppFrame/Preferences.js +3 -3
  23. package/dist/components/AppFrame/Sidebar.js +20 -9
  24. package/dist/components/AppFrame/Topbar.js +1 -1
  25. package/dist/components/ApplicationModuleLoader.js +143 -0
  26. package/dist/components/Authenticate.js +13 -13
  27. package/dist/components/CategoryList.js +1 -1
  28. package/dist/components/Checkbox.js +1 -1
  29. package/dist/components/DropMenu/Menu.js +1 -1
  30. package/dist/components/DropMenu/index.js +1 -1
  31. package/dist/components/Form/FieldList.js +3 -3
  32. package/dist/components/Form/Form.js +1 -1
  33. package/dist/components/Form/Inputs/Button.js +1 -1
  34. package/dist/components/Form/Inputs/FieldButtons.js +1 -1
  35. package/dist/components/Form/Inputs/Number.js +1 -1
  36. package/dist/components/Form/Inputs/ReadOnly.js +1 -1
  37. package/dist/components/Form/Inputs/SmallButton.js +1 -1
  38. package/dist/components/Form/Inputs/Text.js +1 -1
  39. package/dist/components/Form/Inputs/Time.js +1 -1
  40. package/dist/components/Form/Inputs/Toggles.js +1 -1
  41. package/dist/components/Form/Inputs/Translation.js +3 -3
  42. package/dist/components/List/HeadCell.js +1 -1
  43. package/dist/components/List/List.js +1 -1
  44. package/dist/components/List/Row.js +1 -1
  45. package/dist/components/List/enhanceColumnDefs.js +2 -2
  46. package/dist/components/MaterialUI/DataDisplay/List.js +1 -1
  47. package/dist/components/MaterialUI/DataDisplay/Notification.js +2 -2
  48. package/dist/components/MaterialUI/DataDisplay/NotificationProps.js +1 -1
  49. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/Translations.js +3 -3
  50. package/dist/components/MaterialUI/DataDisplay/SelectionList.js +19 -6
  51. package/dist/components/MaterialUI/DataDisplay/Table.js +28 -10
  52. package/dist/components/MaterialUI/DataDisplay/TableProps.js +5 -2
  53. package/dist/components/MaterialUI/DataDisplay/TransferList.js +5 -2
  54. package/dist/components/MaterialUI/DataDisplay/chipProps.js +1 -1
  55. package/dist/components/MaterialUI/DataDisplay/collapsableListProps.js +1 -1
  56. package/dist/components/MaterialUI/DataDisplay/dividerProps.js +1 -1
  57. package/dist/components/MaterialUI/DataDisplay/index.js +1 -1
  58. package/dist/components/MaterialUI/DataDisplay/modalProps.js +1 -1
  59. package/dist/components/MaterialUI/DataDisplay/useTableSelection.js +3 -3
  60. package/dist/components/MaterialUI/Feedback/useNotification.js +1 -1
  61. package/dist/components/MaterialUI/Inputs/Autocomplete.js +2 -2
  62. package/dist/components/MaterialUI/Inputs/AutocompleteProps.js +1 -1
  63. package/dist/components/MaterialUI/Inputs/CheckboxGroupProps.js +1 -1
  64. package/dist/components/MaterialUI/Inputs/CheckboxProps.js +1 -1
  65. package/dist/components/MaterialUI/Inputs/DatePicker.js +11 -0
  66. package/dist/components/MaterialUI/Inputs/InputBase.js +3 -2
  67. package/dist/components/MaterialUI/Inputs/InputBaseProps.js +1 -1
  68. package/dist/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -1
  69. package/dist/components/MaterialUI/Inputs/RadioProps.js +1 -1
  70. package/dist/components/MaterialUI/Inputs/Select.js +2 -2
  71. package/dist/components/MaterialUI/Inputs/SelectProps.js +1 -1
  72. package/dist/components/MaterialUI/Inputs/Switch.js +3 -3
  73. package/dist/components/MaterialUI/Inputs/SwitchProps.js +1 -1
  74. package/dist/components/MaterialUI/Inputs/TimePicker.js +19 -8
  75. package/dist/components/MaterialUI/Inputs/createInput.js +3 -3
  76. package/dist/components/MaterialUI/Inputs/index.js +1 -1
  77. package/dist/components/MaterialUI/Inputs/standaloneRadioProps.js +1 -1
  78. package/dist/components/MaterialUI/Navigation/DropDownMenuProps.js +1 -1
  79. package/dist/components/MaterialUI/Navigation/ExternalLink.js +113 -0
  80. package/dist/components/MaterialUI/Navigation/TabBar.js +38 -33
  81. package/dist/components/MaterialUI/ScopeSelector/ScopeSelector.js +6 -4
  82. package/dist/components/MaterialUI/ScopeSelector/ScopeTreeView.js +8 -4
  83. package/dist/components/MaterialUI/ScopeSelector/TreeItem.js +9 -6
  84. package/dist/components/MaterialUI/Surfaces/ExpansionPanel.js +11 -2
  85. package/dist/components/MaterialUI/Surfaces/SectionExpansionPanel.js +10 -2
  86. package/dist/components/MaterialUI/Surfaces/expansionPanelProps.js +5 -2
  87. package/dist/components/MaterialUI/Surfaces/paperProps.js +1 -1
  88. package/dist/components/MaterialUI/muiThemes.js +26 -6
  89. package/dist/components/MaterialUI/textProps.js +1 -1
  90. package/dist/components/Modules.js +132 -25
  91. package/dist/components/MultiSelector.js +1 -1
  92. package/dist/components/Navigation/Bar.js +3 -3
  93. package/dist/components/Navigation/Tab.js +1 -1
  94. package/dist/components/Navigation/useNavigationState.js +30 -4
  95. package/dist/components/Placeholder.js +1 -1
  96. package/dist/components/Routing/FullPage.js +5 -1
  97. package/dist/components/Routing/Page.js +5 -3
  98. package/dist/components/Routing/Segment.js +4 -3
  99. package/dist/components/Routing/SegmentPage.js +8 -6
  100. package/dist/components/Routing/withWaypointing.js +14 -4
  101. package/dist/components/Scope/ScopeNode.js +1 -1
  102. package/dist/components/Scope/Selector.js +1 -1
  103. package/dist/components/Scope/index.js +11 -3
  104. package/dist/components/Scope/useScopeConfirmationModalState.js +7 -16
  105. package/dist/components/Scope/useScopeData.js +4 -13
  106. package/dist/components/Scope/useScopeSelect.js +1 -1
  107. package/dist/components/Selector.js +1 -1
  108. package/dist/components/Sidepanel.js +1 -2
  109. package/dist/components/Spritesheet.js +1 -1
  110. package/dist/components/Switch.js +1 -1
  111. package/dist/components/Text.js +1 -1
  112. package/dist/components/ToastList.js +1 -1
  113. package/dist/components/Toolbar.js +1 -1
  114. package/dist/components/Treeview/Label.js +1 -1
  115. package/dist/components/Treeview/Leaf.js +1 -1
  116. package/dist/components/Treeview/Node.js +3 -3
  117. package/dist/components/Treeview/index.js +2 -2
  118. package/dist/components/Treeview/settings.js +1 -1
  119. package/dist/constants.js +44 -2
  120. package/dist/content/icons/html-templates.svg +3 -0
  121. package/dist/content/icons/lock.svg +3 -0
  122. package/dist/content/icons/orckestra-icon.svg +5 -0
  123. package/dist/content/icons/unlock.svg +3 -0
  124. package/dist/content/iconsSheet.svg +14 -0
  125. package/dist/content/orckestra-logo-white.png +0 -0
  126. package/dist/getThemeOverrides.js +2 -2
  127. package/dist/hocs/withInfiniteScroll.js +1 -1
  128. package/dist/hocs/withUpdateHandler.js +2 -2
  129. package/dist/hooks/useDispatchWithModulesData.js +1 -1
  130. package/dist/hooks/useEditState.js +3 -3
  131. package/dist/hooks/useEntityLoader.js +182 -0
  132. package/dist/hooks/useFullEntityEditState.js +3 -3
  133. package/dist/hooks/useInfiniteScroll.js +104 -0
  134. package/dist/hooks/useLabelMessage.js +3 -3
  135. package/dist/hooks/useLoader.js +1 -0
  136. package/dist/hooks/useMultipleFieldEditState.js +2 -2
  137. package/dist/hooks/useNavigationHandler.js +1 -1
  138. package/dist/hooks/useNotificationRequestState.js +159 -0
  139. package/dist/hooks/useRequestState.js +146 -0
  140. package/dist/hooks/useSelectorAndUnwrap.js +1 -1
  141. package/dist/reducers/metadata.js +52 -26
  142. package/dist/reducers/modules.js +39 -1
  143. package/dist/reducers/requestStates.js +181 -0
  144. package/dist/reducers/scopes.js +27 -0
  145. package/dist/reducers/settings.js +31 -2
  146. package/dist/schemas/countries.js +1 -1
  147. package/dist/schemas/definitions.js +1 -1
  148. package/dist/schemas/metadata.js +1 -1
  149. package/dist/schemas/productDefinitions.js +1 -1
  150. package/dist/schemas/timezones.js +1 -1
  151. package/dist/selectors/applications.js +1 -1
  152. package/dist/selectors/authentication.js +57 -19
  153. package/dist/selectors/countries.js +1 -1
  154. package/dist/selectors/locale.js +1 -1
  155. package/dist/selectors/metadata.js +104 -14
  156. package/dist/selectors/modules.js +15 -1
  157. package/dist/selectors/navigation.js +1 -1
  158. package/dist/selectors/requestStates.js +82 -0
  159. package/dist/selectors/requests.js +1 -1
  160. package/dist/selectors/scope.js +7 -1
  161. package/dist/selectors/settings.js +13 -1
  162. package/dist/selectors/versionInfo.js +1 -1
  163. package/dist/selectors/view.js +1 -1
  164. package/dist/sharedMessages.js +44 -0
  165. package/dist/spawnerMiddleware.js +1 -1
  166. package/dist/utils/displayModeHelper.js +1 -1
  167. package/dist/utils/flatten.js +2 -2
  168. package/dist/utils/localizationHelper.js +1 -1
  169. package/dist/utils/mapHelper.js +1 -1
  170. package/dist/utils/modelValidationHelper.js +2 -2
  171. package/dist/utils/parseHelper.js +1 -1
  172. package/dist/utils/propertyHelper.js +2 -2
  173. package/dist/utils/propertyValidator.js +1 -1
  174. package/dist/utils/setTranslationWithFallback.js +3 -2
  175. package/dist/utils/testUtils.js +6 -2
  176. package/dist/utils/timezoneHelper.js +111 -0
  177. package/dist/utils/unwrapImmutable.js +1 -1
  178. package/dist/utils/urlHelper.js +11 -1
  179. package/package.json +6 -9
  180. package/src/actions/makeApiAction.js +24 -1
  181. package/src/actions/makeApiAction.test.js +76 -3
  182. package/src/actions/metadata.js +130 -0
  183. package/src/actions/metadata.test.js +337 -5
  184. package/src/actions/modules.js +30 -0
  185. package/src/actions/modules.test.js +50 -1
  186. package/src/actions/requestState.js +8 -0
  187. package/src/actions/requestState.test.js +14 -0
  188. package/src/actions/requestsApi.js +30 -0
  189. package/src/actions/scopes.js +33 -7
  190. package/src/actions/scopes.test.js +84 -14
  191. package/src/buildStore.js +2 -0
  192. package/src/components/AppFrame/About.js +2 -2
  193. package/src/components/AppFrame/AppFrame.test.js +15 -16
  194. package/src/components/AppFrame/ApplicationSelector/ApplicationDialog.js +105 -82
  195. package/src/components/AppFrame/ApplicationSelector/ApplicationDialog.test.js +60 -23
  196. package/src/components/AppFrame/ApplicationSelector/ApplicationSelector.test.js +22 -89
  197. package/src/components/AppFrame/ApplicationSelector/index.js +34 -15
  198. package/src/components/AppFrame/MenuItem.js +3 -5
  199. package/src/components/AppFrame/MenuItem.test.js +2 -24
  200. package/src/components/AppFrame/Sidebar.js +11 -12
  201. package/src/components/AppFrame/Sidebar.test.js +18 -0
  202. package/src/components/AppFrame/Topbar.test.js +2 -4
  203. package/src/components/ApplicationModuleLoader.js +52 -0
  204. package/src/components/ApplicationModuleLoader.test.js +149 -0
  205. package/src/components/Authenticate.js +5 -4
  206. package/src/components/Authenticate.test.js +23 -4
  207. package/src/components/MaterialUI/DataDisplay/SelectionList.js +14 -6
  208. package/src/components/MaterialUI/DataDisplay/SelectionList.test.js +21 -11
  209. package/src/components/MaterialUI/DataDisplay/Table.js +29 -5
  210. package/src/components/MaterialUI/DataDisplay/Table.test.js +23 -0
  211. package/src/components/MaterialUI/DataDisplay/TableProps.js +2 -0
  212. package/src/components/MaterialUI/DataDisplay/TableProps.test.js +2 -0
  213. package/src/components/MaterialUI/DataDisplay/TransferList.js +3 -0
  214. package/src/components/MaterialUI/Inputs/DatePicker.js +11 -0
  215. package/src/components/MaterialUI/Inputs/InputBase.js +3 -1
  216. package/src/components/MaterialUI/Inputs/InputBase.test.js +38 -0
  217. package/src/components/MaterialUI/Inputs/TimePicker.js +9 -3
  218. package/src/components/MaterialUI/Inputs/TimePicker.test.js +263 -118
  219. package/src/components/MaterialUI/Navigation/ExternalLink.js +25 -0
  220. package/src/components/MaterialUI/Navigation/ExternalLink.test.js +26 -0
  221. package/src/components/MaterialUI/Navigation/TabBar.js +82 -78
  222. package/src/components/MaterialUI/Navigation/TabBar.test.js +129 -3
  223. package/src/components/MaterialUI/ScopeSelector/ScopeSelector.js +4 -2
  224. package/src/components/MaterialUI/ScopeSelector/ScopeSelector.test.js +29 -0
  225. package/src/components/MaterialUI/ScopeSelector/ScopeTreeView.js +4 -1
  226. package/src/components/MaterialUI/ScopeSelector/ScopeTreeView.test.js +52 -0
  227. package/src/components/MaterialUI/ScopeSelector/TreeItem.js +9 -6
  228. package/src/components/MaterialUI/ScopeSelector/TreeItem.test.js +63 -2
  229. package/src/components/MaterialUI/Surfaces/ExpansionPanel.js +14 -1
  230. package/src/components/MaterialUI/Surfaces/ExpansionPanel.test.js +16 -0
  231. package/src/components/MaterialUI/Surfaces/SectionExpansionPanel.js +11 -2
  232. package/src/components/MaterialUI/Surfaces/SectionExpansionPanel.test.js +36 -0
  233. package/src/components/MaterialUI/Surfaces/expansionPanelProps.js +2 -0
  234. package/src/components/MaterialUI/Surfaces/expansionPanelProps.test.js +2 -2
  235. package/src/components/MaterialUI/muiThemes.js +23 -3
  236. package/src/components/Modules.js +108 -13
  237. package/src/components/Modules.test.js +431 -12
  238. package/src/components/Navigation/Navigation.test.js +2 -0
  239. package/src/components/Navigation/useNavigationState.js +21 -1
  240. package/src/components/Navigation/useNavigationState.test.js +10 -0
  241. package/src/components/Provision.test.js +34 -0
  242. package/src/components/Routing/FullPage.js +4 -2
  243. package/src/components/Routing/FullPage.test.js +75 -0
  244. package/src/components/Routing/Page.js +2 -2
  245. package/src/components/Routing/Page.test.js +20 -0
  246. package/src/components/Routing/Segment.js +5 -2
  247. package/src/components/Routing/Segment.test.js +22 -1
  248. package/src/components/Routing/SegmentPage.js +12 -4
  249. package/src/components/Routing/SubPage.test.js +1 -1
  250. package/src/components/Routing/withWaypointing.js +19 -17
  251. package/src/components/Routing/withWaypointing.test.js +81 -3
  252. package/src/components/Scope/Scope.test.js +117 -0
  253. package/src/components/Scope/index.js +6 -10
  254. package/src/components/Scope/useScopeConfirmationModalState.js +5 -16
  255. package/src/components/Scope/useScopeConfirmationModalState.test.js +39 -13
  256. package/src/components/Scope/useScopeData.js +0 -3
  257. package/src/components/Scope/useScopeData.test.js +0 -27
  258. package/src/components/Sidepanel.js +0 -1
  259. package/src/components/Sidepanel.test.js +0 -3
  260. package/src/constants.js +33 -0
  261. package/src/content/icons/html-templates.svg +3 -0
  262. package/src/content/icons/lock.svg +3 -0
  263. package/src/content/icons/orckestra-icon.svg +5 -0
  264. package/src/content/icons/unlock.svg +3 -0
  265. package/src/content/iconsSheet.svg +14 -0
  266. package/src/content/orckestra-logo-white.png +0 -0
  267. package/src/hocs/withScopeData.test.js +0 -31
  268. package/src/hooks/useEntityLoader.js +68 -0
  269. package/src/hooks/useEntityLoader.test.js +266 -0
  270. package/src/hooks/useInfiniteScroll.js +25 -0
  271. package/src/hooks/useInfiniteScroll.test.js +87 -0
  272. package/src/hooks/useLoader.js +1 -0
  273. package/src/hooks/useNotificationRequestState.js +78 -0
  274. package/src/hooks/useNotificationRequestState.test.js +264 -0
  275. package/src/hooks/useRequestState.js +57 -0
  276. package/src/hooks/useRequestState.test.js +217 -0
  277. package/src/reducers/metadata.js +76 -16
  278. package/src/reducers/metadata.test.js +458 -4
  279. package/src/reducers/modules.js +48 -2
  280. package/src/reducers/modules.test.js +117 -2
  281. package/src/reducers/requestStates.js +98 -0
  282. package/src/reducers/requestStates.test.js +399 -0
  283. package/src/reducers/scopes.js +30 -0
  284. package/src/reducers/scopes.test.js +45 -1
  285. package/src/reducers/settings.js +26 -2
  286. package/src/reducers/settings.test.js +74 -6
  287. package/src/selectors/authentication.js +53 -28
  288. package/src/selectors/authentication.test.js +600 -12
  289. package/src/selectors/locale.test.js +0 -2
  290. package/src/selectors/metadata.js +73 -13
  291. package/src/selectors/metadata.test.js +479 -8
  292. package/src/selectors/modules.js +7 -0
  293. package/src/selectors/modules.test.js +16 -1
  294. package/src/selectors/requestStates.js +12 -0
  295. package/src/selectors/requestStates.test.js +83 -0
  296. package/src/selectors/scope.js +2 -0
  297. package/src/selectors/scope.test.js +5 -0
  298. package/src/selectors/settings.js +6 -0
  299. package/src/sharedMessages.js +44 -0
  300. package/src/translations/en-US.json +12 -1
  301. package/src/translations/fr-CA.json +13 -2
  302. package/src/utils/modelValidationHelper.js +1 -1
  303. package/src/utils/setTranslationWithFallback.js +1 -1
  304. package/src/utils/setTranslationWithFallback.test.js +4 -14
  305. package/src/utils/testUtils.js +3 -1
  306. package/src/utils/timezoneHelper.js +140 -0
  307. package/src/utils/timezoneHelper.test.js +33 -0
  308. package/src/utils/urlHelper.js +6 -0
  309. package/src/translations/it-IT.json +0 -54
@@ -12,6 +12,7 @@ import { mount } from "enzyme";
12
12
 
13
13
  describe("TreeItem", () => {
14
14
  let store, state;
15
+ const closeSelectorSpy = sinon.spy();
15
16
 
16
17
  beforeEach(() => {
17
18
  state = Immutable.fromJS({
@@ -32,6 +33,10 @@ describe("TreeItem", () => {
32
33
  };
33
34
  });
34
35
 
36
+ afterEach(() => {
37
+ closeSelectorSpy.resetHistory();
38
+ });
39
+
35
40
  const globalScope = {
36
41
  id: "Global",
37
42
  name: "Global",
@@ -59,8 +64,6 @@ describe("TreeItem", () => {
59
64
 
60
65
  const theme = createMuiTheme();
61
66
 
62
- const closeSelectorSpy = sinon.spy();
63
-
64
67
  it("Renders Tree Item correctly for global scope", () => {
65
68
  const expectedGlobalLabel = (
66
69
  <ScopeLabel name={globalScope.name} type={globalScope.type} isRootScope={true} isVirtualScope={false} />
@@ -151,6 +154,64 @@ describe("TreeItem", () => {
151
154
  expect(preventDefaultSpy, "was called once");
152
155
  expect(closeSelectorSpy, "to have no calls satisfying", { args: [event] });
153
156
  });
157
+
158
+ it("Does not calls scope select handler on label click if isScopeSelectable is defined and returns false", () => {
159
+ const isScopeSelectableSpy = sinon.spy(() => false).named("isScopeSelectable");
160
+ const component = (
161
+ <TestWrapper provider={{ store }} memoryRouter stylesProvider muiThemeProvider={{ theme }}>
162
+ <TreeItem
163
+ scope={saleScope}
164
+ rootId={rootId}
165
+ onScopeSelect={closeSelectorSpy}
166
+ isScopeSelectable={isScopeSelectableSpy}
167
+ />
168
+ </TestWrapper>
169
+ );
170
+
171
+ const preventDefaultSpy = sinon.spy();
172
+
173
+ const mountedComponent = mount(component);
174
+
175
+ const saleScopeLabel = mountedComponent.find(TreeItemMui);
176
+
177
+ const event = {
178
+ preventDefault: preventDefaultSpy,
179
+ };
180
+
181
+ saleScopeLabel.invoke("onLabelClick")(event);
182
+
183
+ expect(preventDefaultSpy, "was called");
184
+ expect(closeSelectorSpy, "was not called");
185
+ });
186
+
187
+ it("Calls scope select handler on label click if isScopeSelectable is defined and returns true", () => {
188
+ const isScopeSelectableSpy = sinon.spy(() => true).named("isScopeSelectable");
189
+ const component = (
190
+ <TestWrapper provider={{ store }} memoryRouter stylesProvider muiThemeProvider={{ theme }}>
191
+ <TreeItem
192
+ scope={saleScope}
193
+ rootId={rootId}
194
+ onScopeSelect={closeSelectorSpy}
195
+ isScopeSelectable={isScopeSelectableSpy}
196
+ />
197
+ </TestWrapper>
198
+ );
199
+
200
+ const preventDefaultSpy = sinon.spy();
201
+
202
+ const mountedComponent = mount(component);
203
+
204
+ const saleScopeLabel = mountedComponent.find(TreeItemMui);
205
+
206
+ const event = {
207
+ preventDefault: preventDefaultSpy,
208
+ };
209
+
210
+ saleScopeLabel.invoke("onLabelClick")(event);
211
+
212
+ expect(preventDefaultSpy, "was called");
213
+ expect(closeSelectorSpy, "to have no calls satisfying", { args: [event] });
214
+ });
154
215
  });
155
216
 
156
217
  describe("ScopeLabel", () => {
@@ -29,6 +29,13 @@ const useStyles = makeStyles(theme => ({
29
29
  width: theme.spacing(1),
30
30
  },
31
31
  headerPanelExpanded: {},
32
+ constrainedSummaryRoot: {
33
+ overflowX: "auto",
34
+ overflowY: "hidden",
35
+ },
36
+ constrainedSummaryContent: {
37
+ minWidth: theme.spacing(83),
38
+ },
32
39
  }));
33
40
 
34
41
  const ExpansionPanel = ({ header, content, actions, expansionPanelProps, expansionPanelActionsProps }) => {
@@ -45,6 +52,7 @@ const ExpansionPanel = ({ header, content, actions, expansionPanelProps, expansi
45
52
  // Expansion panel props
46
53
  const disabled = expansionPanelProps?.get(ExpansionPanelProps.propNames.disabled);
47
54
  const defaultExpanded = expansionPanelProps?.get(ExpansionPanelProps.propNames.defaultExpanded) ?? true;
55
+ const constrained = expansionPanelProps?.get(ExpansionPanelProps.propNames.constrained) || false;
48
56
 
49
57
  const [expanded, setExpanded] = React.useState(defaultExpanded);
50
58
 
@@ -76,7 +84,12 @@ const ExpansionPanel = ({ header, content, actions, expansionPanelProps, expansi
76
84
  <AccordionSummary
77
85
  expandIcon={<Icon id="chevron-down" className={classes.expandIcon} />}
78
86
  classes={{
79
- root: classNames(classes.expansionPanelHeader, panelSummaryRootStyle),
87
+ root: classNames(
88
+ classes.expansionPanelHeader,
89
+ panelSummaryRootStyle,
90
+ constrained ? classes.constrainedSummaryRoot : "",
91
+ ),
92
+ content: classNames(constrained ? classes.constrainedSummaryContent : ""),
80
93
  expanded: classNames(classes.headerPanelExpanded, panelSummaryExpandedStyle),
81
94
  }}
82
95
  >
@@ -178,6 +178,22 @@ describe("Expansion Panel", () => {
178
178
  expect(mountedComponent.exists(".MuiAccordionActions-spacing"), "to be truthy");
179
179
  });
180
180
 
181
+ it("Classes are added properly when constrained property of expansionPanelProps is true", () => {
182
+ const expansionPanelProps = new ExpansionPanelProps();
183
+ expansionPanelProps.set(ExpansionPanelProps.propNames.constrained, true);
184
+
185
+ const component = (
186
+ <MuiThemeProvider theme={createMuiTheme()}>
187
+ <ExpansionPanel expansionPanelProps={expansionPanelProps} />
188
+ </MuiThemeProvider>
189
+ );
190
+
191
+ const mountedComponent = mount(component);
192
+
193
+ expect(mountedComponent.exists(".makeStyles-constrainedSummaryRoot-49"), "to be truthy");
194
+ expect(mountedComponent.exists(".makeStyles-constrainedSummaryContent-50"), "to be truthy");
195
+ });
196
+
181
197
  it("DisableSpacing value for disabled property is correct if expansionPanelActionsProps was passed without setting that", () => {
182
198
  const actions = <p>Actions</p>;
183
199
  const expansionPanelActionsProps = new ExpansionPanelActionsProps();
@@ -52,6 +52,13 @@ const useStyles = makeStyles(theme => ({
52
52
  color: theme.palette.grey.darker,
53
53
  minWidth: "auto",
54
54
  },
55
+ constrainedSummaryRoot: {
56
+ overflowX: "auto",
57
+ overflowY: "hidden",
58
+ },
59
+ constrainedSummaryContent: {
60
+ minWidth: theme.spacing(83),
61
+ },
55
62
  }));
56
63
 
57
64
  const SectionExpansionPanel = ({
@@ -97,6 +104,8 @@ const SectionExpansionPanel = ({
97
104
  // Expansion panel actions props
98
105
  const disableSpacing = expansionPanelActionsProps?.get(ExpansionPanelActionsProps.propNames.disableSpacing);
99
106
 
107
+ const constrained = expansionPanelProps?.get(ExpansionPanelProps.propNames.constrained) || false;
108
+
100
109
  return (
101
110
  <Accordion
102
111
  defaultExpanded={defaultExpanded}
@@ -112,9 +121,9 @@ const SectionExpansionPanel = ({
112
121
  expandIcon={<Icon id="dropdown-chevron-down" />}
113
122
  IconButtonProps={defaultSummaryStyles}
114
123
  classes={{
115
- root: classNames(classes.summaryRoot),
124
+ root: classNames(classes.summaryRoot, constrained ? classes.constrainedSummaryRoot : ""),
116
125
  expanded: classNames(classes.panelExpanded),
117
- content: classNames(classes.summaryContent),
126
+ content: classNames(classes.summaryContent, constrained ? classes.constrainedSummaryContent : ""),
118
127
  expandIcon: classNames(classes.summaryExpandIconRoot),
119
128
  }}
120
129
  >
@@ -231,6 +231,42 @@ describe("Section Expansion Panel", () => {
231
231
  expect(mountedComponent.exists(".MuiAccordionActions-spacing"), "to be truthy");
232
232
  });
233
233
 
234
+ it("Uses expansionPanelProps.constrained correctly", () => {
235
+ const expansionPanelProps = new ExpansionPanelProps();
236
+
237
+ expansionPanelProps.set(ExpansionPanelProps.propNames.constrained, true);
238
+
239
+ const component = (
240
+ <Provider store={store(state)}>
241
+ <MuiThemeProvider theme={createMuiTheme()}>
242
+ <SectionExpansionPanel expansionPanelProps={expansionPanelProps} />
243
+ </MuiThemeProvider>
244
+ </Provider>
245
+ );
246
+
247
+ const mountedComponent = mount(component);
248
+
249
+ expect(mountedComponent.exists(".makeStyles-constrainedSummaryRoot-87"), "to be truthy");
250
+ expect(mountedComponent.exists(".makeStyles-constrainedSummaryContent-88"), "to be truthy");
251
+ });
252
+
253
+ it("Default value for constrained property is correct if expansionPanelProps was passed without setting that", () => {
254
+ const expansionPanelProps = new ExpansionPanelProps();
255
+
256
+ const component = (
257
+ <Provider store={store(state)}>
258
+ <MuiThemeProvider theme={createMuiTheme()}>
259
+ <SectionExpansionPanel expansionPanelProps={expansionPanelProps} />
260
+ </MuiThemeProvider>
261
+ </Provider>
262
+ );
263
+
264
+ const mountedComponent = mount(component);
265
+
266
+ expect(mountedComponent.exists(".makeStyles-constrainedSummaryRoot-96"), "to be falsy");
267
+ expect(mountedComponent.exists(".makeStyles-constrainedSummaryContent-97"), "to be falsy");
268
+ });
269
+
234
270
  it("handles internal on change function", () => {
235
271
  const header = <p>Header</p>;
236
272
  const content = <p>Content</p>;
@@ -6,6 +6,7 @@ class ExpansionPanelProps extends ComponentProps {
6
6
  disabled: "disabled",
7
7
  expanded: "expanded",
8
8
  onChange: "onChange",
9
+ constrained: "constrained",
9
10
  };
10
11
 
11
12
  static ruleNames = {
@@ -22,6 +23,7 @@ class ExpansionPanelProps extends ComponentProps {
22
23
  this.componentProps.set(this.constructor.propNames.disabled, null);
23
24
  this.componentProps.set(this.constructor.propNames.expanded, null);
24
25
  this.componentProps.set(this.constructor.propNames.onChange, null);
26
+ this.componentProps.set(this.constructor.propNames.constrained, false);
25
27
 
26
28
  this.componentClasses.set(this.constructor.ruleNames.root, null);
27
29
  this.componentClasses.set(this.constructor.ruleNames.summaryRoot, null);
@@ -7,7 +7,7 @@ import {
7
7
 
8
8
  describe("Expansion Panel Props", () => {
9
9
  it("Contains necessary prop and rule keys", () => {
10
- const propNames = ["defaultExpanded", "disabled", "expanded", "onChange"];
10
+ const propNames = ["defaultExpanded", "disabled", "expanded", "onChange", "constrained"];
11
11
  const rulesNames = ["root", "summaryRoot", "summaryExpanded", "details", "actions"];
12
12
 
13
13
  expect(ExpansionPanelProps.propNames, "to have keys", propNames);
@@ -15,7 +15,7 @@ describe("Expansion Panel Props", () => {
15
15
  });
16
16
 
17
17
  it("Puts keys in component prop and rule maps", () => {
18
- const propNames = ["defaultExpanded", "disabled", "expanded", "onChange"];
18
+ const propNames = ["defaultExpanded", "disabled", "expanded", "onChange", "constrained"];
19
19
  const rulesNames = ["root", "summaryRoot", "summaryExpanded", "details", "actions"];
20
20
 
21
21
  const expansionPanelProps = new ExpansionPanelProps();
@@ -94,6 +94,7 @@ const commonPalette = {
94
94
  default: "#FFF",
95
95
  tabs: "#EFEFEF",
96
96
  app: "#333",
97
+ selectedDate: "#216BA5",
97
98
  },
98
99
  action: {
99
100
  disabledBackground: "#EFEFEF",
@@ -157,6 +158,11 @@ const setThemeOverrides = theme => ({
157
158
  },
158
159
  },
159
160
  },
161
+ MuiLink: {
162
+ root: {
163
+ fontSize: theme.spacing(1.3),
164
+ },
165
+ },
160
166
  MuiButton: {
161
167
  ...theme.MuiButton,
162
168
  root: {
@@ -979,9 +985,6 @@ const setThemeOverrides = theme => ({
979
985
  left: theme.spacing(-2.1),
980
986
  width: theme.spacing(2),
981
987
  },
982
- "&.Mui-expanded:before": {
983
- width: theme.spacing(1.5),
984
- },
985
988
  },
986
989
  label: {
987
990
  ...theme.label,
@@ -1027,6 +1030,23 @@ const setThemeOverrides = theme => ({
1027
1030
  "& svg": {
1028
1031
  fontSize: "10px",
1029
1032
  },
1033
+ "&:before": {
1034
+ content: `" "`,
1035
+ position: "absolute",
1036
+ height: theme.spacing(0.1),
1037
+ width: theme.spacing(0.5),
1038
+ left: theme.spacing(-0.5),
1039
+ backgroundColor: theme.palette.grey.light,
1040
+ top: theme.spacing(1.1),
1041
+ },
1042
+ "&:empty": {
1043
+ width: theme.spacing(1),
1044
+ "&:before": {
1045
+ backgroundColor: "transparent",
1046
+ borderTop: `1px solid ${theme.palette.grey.icon}`,
1047
+ width: theme.spacing(1.5),
1048
+ },
1049
+ },
1030
1050
  },
1031
1051
  },
1032
1052
  MuiTimeline: {
@@ -3,37 +3,122 @@ import { useHistory, useLocation } from "react-router-dom";
3
3
  import { useSelector, useDispatch } from "react-redux";
4
4
  import { Route, Switch, Redirect } from "react-router-dom";
5
5
  import withErrorBoundary from "../hocs/withErrorBoundary";
6
- import { getCurrentScope } from "../selectors/navigation";
6
+ import { getCurrentScope, getCurrentScopeFromRoute, selectRouteHref } from "../selectors/navigation";
7
7
  import { isCurrentScopeAuthorizedSelector } from "../selectors/scope";
8
8
  import Navigation from "./Navigation";
9
9
  import FullPage from "./Routing/FullPage";
10
10
  import { setHrefConfig } from "../actions/navigation";
11
- import { setModulesStructure } from "../actions/modules";
12
- import { defaultScopeSelector } from "../selectors/settings";
11
+ import {
12
+ setRoutingPerformed,
13
+ setModuleAsVisible,
14
+ setModulesStructure,
15
+ initializeFirstModuleScope,
16
+ } from "../actions/modules";
17
+ import { defaultScopeSelector, getApplicationModulesSelector } from "../selectors/settings";
18
+ import { getScopeModuleInformationSelector } from "../selectors/modules";
19
+ import UrlPattern from "url-pattern";
20
+ import { overtureModule } from "../constants";
21
+
22
+ const rerouteOnScopeAndModule = (history, currentRoute, scope, module) => {
23
+ const params = {
24
+ scope: scope,
25
+ };
26
+
27
+ const pattern = new UrlPattern(`/:scope/${module}`);
28
+ const href = pattern.stringify(params);
29
+
30
+ if (currentRoute !== href) {
31
+ history.push(href);
32
+ }
33
+ };
34
+
35
+ export const Module = withErrorBoundary("Module")(({ id, config, path, error, location, match, modulePrependPath }) => {
36
+ const history = useHistory();
37
+ const scope = useSelector(getCurrentScopeFromRoute);
38
+ const currentRoute = useSelector(selectRouteHref);
39
+ const moduleInfo = useSelector(getScopeModuleInformationSelector);
40
+
41
+ const isVisible =
42
+ moduleInfo.scope != null && moduleInfo.visibleModules.length > 0 && moduleInfo.visibleModules.includes(id);
43
+
44
+ React.useEffect(() => {
45
+ if (moduleInfo.scope != null && scope === moduleInfo.scope && moduleInfo.visibleModules.length > 0 && !isVisible) {
46
+ rerouteOnScopeAndModule(history, currentRoute, moduleInfo.scope, moduleInfo.visibleModules[0]);
47
+ }
48
+ }, [history, scope, isVisible, currentRoute, moduleInfo.scope, moduleInfo.visibleModules]);
13
49
 
14
- export const Module = withErrorBoundary("Module")(({ config, path, error, location, match, modulePrependPath }) => {
15
50
  return (
16
- <FullPage path={path} config={config} location={location} match={match} modulePrependPath={modulePrependPath} />
51
+ <FullPage
52
+ path={path}
53
+ config={config}
54
+ location={location}
55
+ match={match}
56
+ modulePrependPath={modulePrependPath}
57
+ isVisible={isVisible}
58
+ />
17
59
  );
18
60
  });
19
61
 
20
62
  const getHrefFromPath = (path, scope) => path.replace(":scope", scope);
21
63
 
64
+ const CheckModuleVisibility = ({ id, config, moduleInfo }) => {
65
+ const dispatch = useDispatch();
66
+ const applicationModules = useSelector(getApplicationModulesSelector);
67
+ const scopeFromRoute = useSelector(getCurrentScopeFromRoute);
68
+
69
+ const hideSelector = state => (typeof config.hide === "function" ? config.hide(state) : () => config.hide ?? false);
70
+
71
+ const isHidden = useSelector(hideSelector(moduleInfo.scope ?? scopeFromRoute));
72
+
73
+ const moduleScope = moduleInfo.scope;
74
+ const moduleIsVisible = isHidden === false && !moduleInfo.visibleModules.includes(id);
75
+
76
+ React.useEffect(() => {
77
+ // We need to wait for the ROUTE to be set the first time in the Redux/Store before to set module's visibility
78
+ if (scopeFromRoute !== null || applicationModules.includes(overtureModule.System)) {
79
+ if (moduleScope == null) {
80
+ dispatch(initializeFirstModuleScope(scopeFromRoute));
81
+ }
82
+
83
+ if (moduleIsVisible) {
84
+ dispatch(setModuleAsVisible(id));
85
+ }
86
+ }
87
+ }, [moduleScope, moduleIsVisible, dispatch, id, scopeFromRoute, applicationModules]);
88
+
89
+ return <React.Fragment />;
90
+ };
91
+
22
92
  export const Modules = ({ modules, pathConfig: { customPath, ...otherConfigs } = {} }) => {
23
93
  const dispatch = useDispatch();
24
- const scope = useSelector(getCurrentScope);
94
+ const currentScope = useSelector(getCurrentScope);
25
95
  const isAuthorizedScope = useSelector(isCurrentScopeAuthorizedSelector);
26
96
  const defaultScope = useSelector(defaultScopeSelector);
27
97
  const history = useHistory();
28
98
  const location = useLocation();
99
+ const currentRoute = useSelector(selectRouteHref);
100
+
101
+ const moduleInfo = useSelector(getScopeModuleInformationSelector);
102
+
103
+ const firstModuleName = Object.keys(modules)[0];
104
+
105
+ const destinationModule =
106
+ moduleInfo.routingPerformed === false &&
107
+ moduleInfo.scope != null &&
108
+ moduleInfo.visibleModules.length > 0 &&
109
+ moduleInfo.moduleName != null
110
+ ? moduleInfo.visibleModules.includes(moduleInfo.moduleName)
111
+ ? moduleInfo.moduleName
112
+ : moduleInfo.visibleModules[0]
113
+ : null;
29
114
 
30
115
  const scopePath = "/:scope/";
31
116
  const prependPath = customPath || scopePath;
32
- const prependHref = getHrefFromPath(prependPath, scope);
117
+ const prependHref = getHrefFromPath(prependPath, currentScope);
33
118
 
34
119
  Object.keys(otherConfigs).forEach(key => {
35
120
  const moduleConfig = otherConfigs[key];
36
- moduleConfig.prependHref = getHrefFromPath(moduleConfig.prependPath, scope);
121
+ moduleConfig.prependHref = getHrefFromPath(moduleConfig.prependPath, currentScope);
37
122
  });
38
123
 
39
124
  useEffect(() => {
@@ -41,23 +126,33 @@ export const Modules = ({ modules, pathConfig: { customPath, ...otherConfigs } =
41
126
  }, [dispatch, prependPath, prependHref, otherConfigs]);
42
127
 
43
128
  const getModuleConfig = name => (otherConfigs && otherConfigs[name]) || { prependPath, prependHref };
44
- const firstModuleName = Object.keys(modules)[0];
45
129
 
46
130
  useEffect(() => {
47
131
  const { pathname, search } = location;
48
- if (!isAuthorizedScope && pathname.includes(scope) && defaultScope) {
49
- history.push(pathname.replace(scope, defaultScope) + search);
132
+ if (!isAuthorizedScope && pathname.includes(currentScope) && defaultScope) {
133
+ history.push(pathname.replace(currentScope, defaultScope) + search);
50
134
  }
51
135
  // eslint-disable-next-line react-hooks/exhaustive-deps
52
- }, [isAuthorizedScope, defaultScope, history, scope]);
136
+ }, [isAuthorizedScope, defaultScope, history, currentScope]);
53
137
 
54
138
  React.useEffect(() => {
55
139
  dispatch(setModulesStructure(modules));
56
140
  }, [dispatch, modules]);
57
141
 
142
+ useEffect(() => {
143
+ if (destinationModule != null) {
144
+ rerouteOnScopeAndModule(history, currentRoute, moduleInfo.scope, destinationModule);
145
+
146
+ dispatch(setRoutingPerformed());
147
+ }
148
+ }, [dispatch, history, moduleInfo.scope, destinationModule, currentRoute]);
149
+
58
150
  return (
59
151
  <React.Fragment>
60
152
  <Navigation modules={modules} />
153
+ {Object.entries(modules).map(([name, module]) => (
154
+ <CheckModuleVisibility key={name} id={name} config={module} moduleInfo={moduleInfo} />
155
+ ))}
61
156
  <Switch>
62
157
  {Object.entries(modules).map(([name, module]) => {
63
158
  const moduleConfig = getModuleConfig(name);
@@ -67,7 +162,7 @@ export const Modules = ({ modules, pathConfig: { customPath, ...otherConfigs } =
67
162
  key={name}
68
163
  path={path}
69
164
  render={route => (
70
- <Module modulePrependPath={moduleConfig.prependPath} config={module} path={path} {...route} />
165
+ <Module id={name} modulePrependPath={moduleConfig.prependPath} config={module} path={path} {...route} />
71
166
  )}
72
167
  />
73
168
  );