orc-shared 1.2.0-dev.2 → 1.2.0-dev.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/modules.js +63 -1
- package/dist/actions/scopes.js +59 -22
- package/dist/components/AppFrame/MenuItem.js +5 -14
- package/dist/components/AppFrame/Sidebar.js +11 -5
- package/dist/components/ApplicationModuleLoader.js +143 -0
- package/dist/components/Authenticate.js +12 -12
- package/dist/components/MaterialUI/DataDisplay/SelectionList.js +1 -1
- package/dist/components/MaterialUI/Navigation/ExternalLink.js +113 -0
- package/dist/components/MaterialUI/muiThemes.js +5 -0
- package/dist/components/Modules.js +126 -41
- package/dist/components/Routing/FullPage.js +3 -1
- package/dist/components/Routing/Page.js +5 -3
- package/dist/components/Routing/Segment.js +1 -1
- package/dist/components/Routing/withWaypointing.js +6 -2
- package/dist/components/Scope/useScopeConfirmationModalState.js +7 -16
- package/dist/components/Scope/useScopeData.js +4 -13
- package/dist/constants.js +19 -2
- package/dist/content/iconsSheet.svg +3 -0
- package/dist/reducers/modules.js +39 -1
- package/dist/reducers/scopes.js +27 -0
- package/dist/reducers/settings.js +31 -2
- package/dist/selectors/authentication.js +57 -18
- package/dist/selectors/modules.js +15 -1
- package/dist/selectors/scope.js +7 -1
- package/dist/selectors/settings.js +13 -1
- package/package.json +6 -5
- package/src/actions/modules.js +30 -0
- package/src/actions/modules.test.js +50 -1
- package/src/actions/scopes.js +33 -7
- package/src/actions/scopes.test.js +84 -14
- package/src/components/AppFrame/AppFrame.test.js +9 -0
- package/src/components/AppFrame/MenuItem.js +3 -5
- package/src/components/AppFrame/MenuItem.test.js +2 -24
- package/src/components/AppFrame/Sidebar.js +8 -1
- package/src/components/AppFrame/Sidebar.test.js +18 -0
- package/src/components/ApplicationModuleLoader.js +52 -0
- package/src/components/ApplicationModuleLoader.test.js +149 -0
- package/src/components/Authenticate.js +5 -4
- package/src/components/Authenticate.test.js +23 -4
- package/src/components/MaterialUI/DataDisplay/SelectionList.js +1 -1
- package/src/components/MaterialUI/DataDisplay/SelectionList.test.js +2 -2
- package/src/components/MaterialUI/Navigation/ExternalLink.js +25 -0
- package/src/components/MaterialUI/Navigation/ExternalLink.test.js +26 -0
- package/src/components/MaterialUI/muiThemes.js +5 -0
- package/src/components/Modules.js +103 -20
- package/src/components/Modules.test.js +315 -28
- package/src/components/Provision.test.js +34 -0
- package/src/components/Routing/FullPage.js +2 -1
- package/src/components/Routing/FullPage.test.js +23 -0
- package/src/components/Routing/Page.js +2 -2
- package/src/components/Routing/Page.test.js +20 -0
- package/src/components/Routing/Segment.js +1 -1
- package/src/components/Routing/withWaypointing.js +2 -2
- package/src/components/Routing/withWaypointing.test.js +33 -5
- package/src/components/Scope/useScopeConfirmationModalState.js +5 -16
- package/src/components/Scope/useScopeConfirmationModalState.test.js +39 -13
- package/src/components/Scope/useScopeData.js +0 -3
- package/src/components/Scope/useScopeData.test.js +0 -27
- package/src/constants.js +15 -0
- package/src/content/iconsSheet.svg +3 -0
- package/src/hocs/withScopeData.test.js +0 -31
- package/src/reducers/modules.js +48 -2
- package/src/reducers/modules.test.js +117 -2
- package/src/reducers/scopes.js +30 -0
- package/src/reducers/scopes.test.js +45 -1
- package/src/reducers/settings.js +26 -2
- package/src/reducers/settings.test.js +74 -6
- package/src/selectors/authentication.js +53 -27
- package/src/selectors/authentication.test.js +600 -12
- package/src/selectors/modules.js +7 -0
- package/src/selectors/modules.test.js +16 -1
- package/src/selectors/scope.js +2 -0
- package/src/selectors/scope.test.js +5 -0
- package/src/selectors/settings.js +6 -0
|
@@ -6,6 +6,13 @@ import { spyOnConsole } from "../utils/testUtils";
|
|
|
6
6
|
import Provision from "./Provision";
|
|
7
7
|
import { createTheme } from "@material-ui/core/styles";
|
|
8
8
|
|
|
9
|
+
jest.mock("../utils/buildUrl", () => {
|
|
10
|
+
const modExport = {};
|
|
11
|
+
modExport.loadConfig = () => Promise.resolve({});
|
|
12
|
+
modExport.buildUrl = () => "URL";
|
|
13
|
+
return modExport;
|
|
14
|
+
});
|
|
15
|
+
|
|
9
16
|
const fakeStore = {
|
|
10
17
|
subscribe: listener => () => {},
|
|
11
18
|
dispatch: action => action,
|
|
@@ -17,8 +24,35 @@ const fakeStore = {
|
|
|
17
24
|
authentication: {
|
|
18
25
|
name: "foo@bar.com",
|
|
19
26
|
},
|
|
27
|
+
scopes: {
|
|
28
|
+
Global: {
|
|
29
|
+
name: { en: "Global", fr: "Global" },
|
|
30
|
+
id: "Global",
|
|
31
|
+
children: ["MyScope"],
|
|
32
|
+
currency: {
|
|
33
|
+
displayName: {
|
|
34
|
+
en: "Euro",
|
|
35
|
+
fr: "Euro",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
defaultCulture: "en-US",
|
|
39
|
+
},
|
|
40
|
+
MyScope: {
|
|
41
|
+
name: { en: "First child", fr: "Premier fils" },
|
|
42
|
+
id: "FirstChild",
|
|
43
|
+
children: ["ChildScope"],
|
|
44
|
+
parentScopeId: "Global",
|
|
45
|
+
},
|
|
46
|
+
ChildScope: {
|
|
47
|
+
name: { en: "First grandchild", fr: "Premier petit-fils" },
|
|
48
|
+
id: "FirstGrandchild",
|
|
49
|
+
parentScopeId: "MyScope",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
20
52
|
settings: {
|
|
21
53
|
defaultScope: "myScope",
|
|
54
|
+
loadedModulesScope: ["moduleA", "moduleB"],
|
|
55
|
+
modules: ["moduleA", "moduleB"],
|
|
22
56
|
},
|
|
23
57
|
}),
|
|
24
58
|
replaceReducer: () => {},
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
import Page from "./Page";
|
|
3
3
|
import SegmentPage from "./SegmentPage";
|
|
4
4
|
|
|
5
|
-
const FullPage = ({ path, config, location, match, modulePrependPath }) => {
|
|
5
|
+
const FullPage = ({ path, config, location, match, modulePrependPath, isVisible }) => {
|
|
6
6
|
const { component, componentProps, pages = {}, segments, subpages, entityIdResolver } = config;
|
|
7
7
|
if (segments) {
|
|
8
8
|
return (
|
|
@@ -26,6 +26,7 @@ const FullPage = ({ path, config, location, match, modulePrependPath }) => {
|
|
|
26
26
|
subpages={subpages}
|
|
27
27
|
location={location}
|
|
28
28
|
match={match}
|
|
29
|
+
isVisible={isVisible}
|
|
29
30
|
modulePrependPath={modulePrependPath}
|
|
30
31
|
/>
|
|
31
32
|
);
|
|
@@ -86,6 +86,29 @@ describe("Fullpage", () => {
|
|
|
86
86
|
<View2 />,
|
|
87
87
|
));
|
|
88
88
|
|
|
89
|
+
it("does not show a page when not visible", () =>
|
|
90
|
+
expect(
|
|
91
|
+
<TestWrapper
|
|
92
|
+
provider={{ store }}
|
|
93
|
+
memoryRouter={{ initialEntries: ["/meep/snap/stuff"] }}
|
|
94
|
+
stylesProvider
|
|
95
|
+
muiThemeProvider={{ theme }}
|
|
96
|
+
>
|
|
97
|
+
<FullPage
|
|
98
|
+
path="/meep/snap"
|
|
99
|
+
config={{
|
|
100
|
+
component: View1,
|
|
101
|
+
}}
|
|
102
|
+
isVisible={false}
|
|
103
|
+
location={{ location: true }}
|
|
104
|
+
match={{ match: true }}
|
|
105
|
+
/>
|
|
106
|
+
</TestWrapper>,
|
|
107
|
+
"when mounted",
|
|
108
|
+
"to be",
|
|
109
|
+
null,
|
|
110
|
+
));
|
|
111
|
+
|
|
89
112
|
it("shows a segment page if segments", () => {
|
|
90
113
|
const location = {
|
|
91
114
|
pathname: "/meep/snap/stuff",
|
|
@@ -5,8 +5,8 @@ import FullPage from "./FullPage";
|
|
|
5
5
|
import SubPage from "./SubPage";
|
|
6
6
|
import withWaypointing from "./withWaypointing";
|
|
7
7
|
|
|
8
|
-
const Page = ({ component: View, path, pages = {}, subpages = {}, modulePrependPath }) => {
|
|
9
|
-
const WrappedView = useMemo(() => withErrorBoundary(path)(withWaypointing(View)), [path, View]);
|
|
8
|
+
const Page = ({ component: View, path, pages = {}, subpages = {}, modulePrependPath, isVisible = true }) => {
|
|
9
|
+
const WrappedView = useMemo(() => withErrorBoundary(path)(withWaypointing(View, isVisible)), [path, View, isVisible]);
|
|
10
10
|
return (
|
|
11
11
|
<React.Fragment>
|
|
12
12
|
<Switch>
|
|
@@ -70,6 +70,26 @@ describe("Page", () => {
|
|
|
70
70
|
</TestWrapper>,
|
|
71
71
|
));
|
|
72
72
|
|
|
73
|
+
it("Does not show the page view when its path is matched but not visible", () =>
|
|
74
|
+
expect(
|
|
75
|
+
<TestWrapper provider={{ store }} intlProvider={intlProvider} stylesProvider muiThemeProvider={{ theme }}>
|
|
76
|
+
<MemoryRouter initialEntries={["/nabble"]}>
|
|
77
|
+
<Page
|
|
78
|
+
component={View}
|
|
79
|
+
path="/nabble"
|
|
80
|
+
isVisible={false}
|
|
81
|
+
pages={{
|
|
82
|
+
"/foo": { component: Sub1 },
|
|
83
|
+
"/bar": { component: Sub2 },
|
|
84
|
+
}}
|
|
85
|
+
/>
|
|
86
|
+
</MemoryRouter>
|
|
87
|
+
</TestWrapper>,
|
|
88
|
+
"when mounted",
|
|
89
|
+
"to equal",
|
|
90
|
+
null,
|
|
91
|
+
));
|
|
92
|
+
|
|
73
93
|
it("shows nested page when its path is matched", () =>
|
|
74
94
|
expect(
|
|
75
95
|
<TestWrapper provider={{ store }} intlProvider={intlProvider} stylesProvider muiThemeProvider={{ theme }}>
|
|
@@ -6,7 +6,7 @@ const Segment = ({ location, match, config, root, modulePrependPath }) => {
|
|
|
6
6
|
const { component, componentProps } = config;
|
|
7
7
|
const path = location.pathname;
|
|
8
8
|
const View = useMemo(
|
|
9
|
-
() => withErrorBoundary(path)(withWaypointing(component, componentProps)),
|
|
9
|
+
() => withErrorBoundary(path)(withWaypointing(component, true, componentProps)),
|
|
10
10
|
[path, component, componentProps],
|
|
11
11
|
);
|
|
12
12
|
return <View location={location} match={match} mapFrom={root} modulePrependPath={modulePrependPath} />;
|
|
@@ -6,7 +6,7 @@ import { setRoute, mapHref, setCurrentPrependPath } from "../../actions/navigati
|
|
|
6
6
|
import useLoader from "../../hooks/useLoader";
|
|
7
7
|
|
|
8
8
|
const withWaypointing =
|
|
9
|
-
(Comp, componentProps = {}) =>
|
|
9
|
+
(Comp, isVisible = true, componentProps = {}) =>
|
|
10
10
|
props => {
|
|
11
11
|
const { match, mapFrom, modulePrependPath } = props;
|
|
12
12
|
const location = useLocation();
|
|
@@ -24,7 +24,7 @@ const withWaypointing =
|
|
|
24
24
|
}
|
|
25
25
|
const cutout = state => selectRouteHref(state) === location.pathname;
|
|
26
26
|
useLoader(loadActions, cutout);
|
|
27
|
-
return <Comp {...props} {...componentProps}
|
|
27
|
+
return isVisible ? <Comp {...props} {...componentProps} /> : null;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export default withWaypointing;
|
|
@@ -6,7 +6,7 @@ import { Router, Route } from "react-router-dom";
|
|
|
6
6
|
import { mount, act } from "unexpected-reaction";
|
|
7
7
|
import sinon from "sinon";
|
|
8
8
|
import { PropStruct } from "../../utils/testUtils";
|
|
9
|
-
import { setRoute, mapHref } from "../../actions/navigation";
|
|
9
|
+
import { setRoute, mapHref, setCurrentPrependPath } from "../../actions/navigation";
|
|
10
10
|
import withWaypointing from "./withWaypointing";
|
|
11
11
|
|
|
12
12
|
describe("withWaypointing", () => {
|
|
@@ -22,6 +22,7 @@ describe("withWaypointing", () => {
|
|
|
22
22
|
params: { some: "meep" },
|
|
23
23
|
isExact: true,
|
|
24
24
|
},
|
|
25
|
+
modulePrependPath: "foo",
|
|
25
26
|
},
|
|
26
27
|
},
|
|
27
28
|
requests: {
|
|
@@ -94,6 +95,21 @@ describe("withWaypointing", () => {
|
|
|
94
95
|
})
|
|
95
96
|
.then(() => expect(store.dispatch, "to have calls satisfying", [])));
|
|
96
97
|
|
|
98
|
+
it("does not render the component if the component is not visible", () =>
|
|
99
|
+
expect(withWaypointing, "called with", [PropStruct, false])
|
|
100
|
+
.then(EnhancedView => {
|
|
101
|
+
return expect(
|
|
102
|
+
<Provider store={store}>
|
|
103
|
+
<Router history={history}>
|
|
104
|
+
<Route path="/feep/:some" component={EnhancedView} />
|
|
105
|
+
</Router>
|
|
106
|
+
</Provider>,
|
|
107
|
+
"when mounted",
|
|
108
|
+
"to be null",
|
|
109
|
+
);
|
|
110
|
+
})
|
|
111
|
+
.then(() => expect(store.dispatch, "to have calls satisfying", [])));
|
|
112
|
+
|
|
97
113
|
it("does fire action if path parameters different", () =>
|
|
98
114
|
expect(withWaypointing, "called with", [PropStruct])
|
|
99
115
|
.then(EnhancedView => {
|
|
@@ -128,7 +144,7 @@ describe("withWaypointing", () => {
|
|
|
128
144
|
));
|
|
129
145
|
|
|
130
146
|
it("does fire action if path parameters different and with custom props", () =>
|
|
131
|
-
expect(withWaypointing, "called with", [PropStruct, { foo: 123 }])
|
|
147
|
+
expect(withWaypointing, "called with", [PropStruct, true, { foo: 123 }])
|
|
132
148
|
.then(EnhancedView => {
|
|
133
149
|
history.replace("/feep/moof");
|
|
134
150
|
return expect(
|
|
@@ -161,7 +177,7 @@ describe("withWaypointing", () => {
|
|
|
161
177
|
));
|
|
162
178
|
|
|
163
179
|
it("does not fire action if route match is not exact with custom props", () =>
|
|
164
|
-
expect(withWaypointing, "called with", [PropStruct, { foo: 123 }])
|
|
180
|
+
expect(withWaypointing, "called with", [PropStruct, true, { foo: 123 }])
|
|
165
181
|
.then(EnhancedView => {
|
|
166
182
|
history.replace("/feep/meep/mef");
|
|
167
183
|
return expect(
|
|
@@ -201,16 +217,28 @@ describe("withWaypointing", () => {
|
|
|
201
217
|
return expect(
|
|
202
218
|
<Provider store={store}>
|
|
203
219
|
<Router history={history}>
|
|
204
|
-
<Route
|
|
220
|
+
<Route
|
|
221
|
+
path="/foo/bar"
|
|
222
|
+
render={props => <EnhancedView {...props} mapFrom="/foo" modulePrependPath="foo" />}
|
|
223
|
+
/>
|
|
205
224
|
</Router>
|
|
206
225
|
</Provider>,
|
|
207
226
|
"when mounted",
|
|
208
227
|
"to satisfy",
|
|
209
|
-
<PropStruct
|
|
228
|
+
<PropStruct
|
|
229
|
+
history="__ignore"
|
|
230
|
+
location="__ignore"
|
|
231
|
+
match="__ignore"
|
|
232
|
+
mapFrom="/foo"
|
|
233
|
+
modulePrependPath="__ignore"
|
|
234
|
+
/>,
|
|
210
235
|
);
|
|
211
236
|
})
|
|
212
237
|
.then(() =>
|
|
213
238
|
expect(store.dispatch, "to have calls satisfying", [
|
|
239
|
+
{
|
|
240
|
+
args: [setCurrentPrependPath("foo")],
|
|
241
|
+
},
|
|
214
242
|
{
|
|
215
243
|
args: [mapHref("/foo", "/foo/bar")],
|
|
216
244
|
},
|
|
@@ -6,8 +6,7 @@ import { applicationScopeHasChanged } from "../../actions/scopes";
|
|
|
6
6
|
import useScopeData from "./useScopeData";
|
|
7
7
|
import { hasUnsavedDataSelector } from "../../selectors/view";
|
|
8
8
|
import { scopeConfirmationDialogTypes } from "../../constants";
|
|
9
|
-
import {
|
|
10
|
-
import UrlPattern from "url-pattern";
|
|
9
|
+
import { setNewScopeAndModuleName } from "../../actions/modules";
|
|
11
10
|
|
|
12
11
|
const ExecuteClosingTabHandlerActions = async closingTabHandlerActions => {
|
|
13
12
|
if (closingTabHandlerActions.length <= 0) return Promise.resolve();
|
|
@@ -19,23 +18,13 @@ const ExecuteClosingTabHandlerActions = async closingTabHandlerActions => {
|
|
|
19
18
|
|
|
20
19
|
const useApplicationScopeChanger = closingTabHandlerActions => {
|
|
21
20
|
const dispatch = useDispatch();
|
|
22
|
-
const history = useHistory();
|
|
23
21
|
const moduleName = useSelectorAndUnwrap(selectCurrentModuleName);
|
|
24
22
|
|
|
25
23
|
return (previousScope, newScope) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// did not find a more reliable way to get the URL for the first tab of the module
|
|
31
|
-
const pattern = new UrlPattern(`/:scope/${moduleName}`);
|
|
32
|
-
const href = pattern.stringify(params);
|
|
33
|
-
|
|
34
|
-
history.push(href);
|
|
35
|
-
|
|
36
|
-
ExecuteClosingTabHandlerActions(closingTabHandlerActions).then(() =>
|
|
37
|
-
dispatch(applicationScopeHasChanged(previousScope, newScope)),
|
|
38
|
-
);
|
|
24
|
+
ExecuteClosingTabHandlerActions(closingTabHandlerActions).then(() => {
|
|
25
|
+
dispatch(setNewScopeAndModuleName(newScope, moduleName));
|
|
26
|
+
dispatch(applicationScopeHasChanged(previousScope, newScope));
|
|
27
|
+
});
|
|
39
28
|
};
|
|
40
29
|
};
|
|
41
30
|
|
|
@@ -4,8 +4,8 @@ import sinon from "sinon";
|
|
|
4
4
|
import { TestWrapper } from "../../utils/testUtils";
|
|
5
5
|
import useScopeConfirmationModalState from "./useScopeConfirmationModalState";
|
|
6
6
|
import { mount } from "enzyme";
|
|
7
|
-
import { createMemoryHistory } from "history";
|
|
8
7
|
import { APPLICATION_SCOPE_HAS_CHANGED } from "../../actions/scopes";
|
|
8
|
+
import { SET_NEW_SCOPE_AND_MODULE_NAME } from "../../actions/modules";
|
|
9
9
|
|
|
10
10
|
jest.mock("../../utils/buildUrl", () => {
|
|
11
11
|
const modExport = {};
|
|
@@ -35,13 +35,9 @@ const TestComp = () => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
describe("useScopeConfirmationModalState", () => {
|
|
38
|
-
let state, store
|
|
38
|
+
let state, store;
|
|
39
39
|
|
|
40
40
|
beforeEach(() => {
|
|
41
|
-
history = createMemoryHistory({ initialEntries: ["/TestScope/demos?arg=data"] });
|
|
42
|
-
sinon.spy(history, "push");
|
|
43
|
-
history.push.named("history.push");
|
|
44
|
-
|
|
45
41
|
state = Immutable.fromJS({
|
|
46
42
|
input: {},
|
|
47
43
|
locale: {
|
|
@@ -170,7 +166,7 @@ describe("useScopeConfirmationModalState", () => {
|
|
|
170
166
|
|
|
171
167
|
it("selecting a new scope without active tabs changes the scope", async () => {
|
|
172
168
|
const component = (
|
|
173
|
-
<TestWrapper provider={{ store }}
|
|
169
|
+
<TestWrapper provider={{ store }}>
|
|
174
170
|
<TestComp />
|
|
175
171
|
</TestWrapper>
|
|
176
172
|
);
|
|
@@ -183,8 +179,18 @@ describe("useScopeConfirmationModalState", () => {
|
|
|
183
179
|
|
|
184
180
|
await new Promise(resolve => setTimeout(resolve, 10));
|
|
185
181
|
|
|
186
|
-
expect(history.push, "to have calls satisfying", [{ args: ["/newScope/TheModuleName"] }]);
|
|
187
182
|
expect(store.dispatch, "to have calls satisfying", [
|
|
183
|
+
{
|
|
184
|
+
args: [
|
|
185
|
+
{
|
|
186
|
+
type: SET_NEW_SCOPE_AND_MODULE_NAME,
|
|
187
|
+
payload: {
|
|
188
|
+
scope: "newScope",
|
|
189
|
+
moduleName: "TheModuleName",
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
},
|
|
188
194
|
{
|
|
189
195
|
args: [
|
|
190
196
|
{
|
|
@@ -227,7 +233,7 @@ describe("useScopeConfirmationModalState", () => {
|
|
|
227
233
|
openTabs();
|
|
228
234
|
|
|
229
235
|
const component = (
|
|
230
|
-
<TestWrapper provider={{ store }}
|
|
236
|
+
<TestWrapper provider={{ store }}>
|
|
231
237
|
<TestComp />
|
|
232
238
|
</TestWrapper>
|
|
233
239
|
);
|
|
@@ -248,8 +254,18 @@ describe("useScopeConfirmationModalState", () => {
|
|
|
248
254
|
isModalOpened = mountedComponent.find("#isModalOpened").text();
|
|
249
255
|
expect(isModalOpened, "to equal", "false");
|
|
250
256
|
|
|
251
|
-
expect(history.push, "to have calls satisfying", [{ args: ["/newScope/TheModuleName"] }]);
|
|
252
257
|
expect(store.dispatch, "to have calls satisfying", [
|
|
258
|
+
{
|
|
259
|
+
args: [
|
|
260
|
+
{
|
|
261
|
+
type: SET_NEW_SCOPE_AND_MODULE_NAME,
|
|
262
|
+
payload: {
|
|
263
|
+
scope: "newScope",
|
|
264
|
+
moduleName: "TheModuleName",
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
},
|
|
253
269
|
{
|
|
254
270
|
args: [
|
|
255
271
|
{
|
|
@@ -281,7 +297,7 @@ describe("useScopeConfirmationModalState", () => {
|
|
|
281
297
|
openTabs();
|
|
282
298
|
|
|
283
299
|
const component = (
|
|
284
|
-
<TestWrapper provider={{ store }}
|
|
300
|
+
<TestWrapper provider={{ store }}>
|
|
285
301
|
<TestComp />
|
|
286
302
|
</TestWrapper>
|
|
287
303
|
);
|
|
@@ -309,9 +325,19 @@ describe("useScopeConfirmationModalState", () => {
|
|
|
309
325
|
{ args: [null, true] },
|
|
310
326
|
]);
|
|
311
327
|
|
|
312
|
-
expect(
|
|
313
|
-
expect(store.dispatch.callCount, "to be", 1);
|
|
328
|
+
expect(store.dispatch.callCount, "to be", 2);
|
|
314
329
|
expect(store.dispatch, "to have calls satisfying", [
|
|
330
|
+
{
|
|
331
|
+
args: [
|
|
332
|
+
{
|
|
333
|
+
type: SET_NEW_SCOPE_AND_MODULE_NAME,
|
|
334
|
+
payload: {
|
|
335
|
+
scope: "newScope",
|
|
336
|
+
moduleName: "TheModuleName",
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
],
|
|
340
|
+
},
|
|
315
341
|
{
|
|
316
342
|
args: [
|
|
317
343
|
{
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { useSelector } from "react-redux";
|
|
2
|
-
import useLoader from "../../hooks/useLoader";
|
|
3
2
|
import { unwrapImmutable } from "../../utils";
|
|
4
3
|
import { currentScopeSelector, scopeGetter } from "../../selectors/scope";
|
|
5
|
-
import { getScopes } from "../../actions/scopes";
|
|
6
4
|
|
|
7
5
|
const buildDefaultNodeState = (current, getScope) => {
|
|
8
6
|
let node = current;
|
|
@@ -16,7 +14,6 @@ const buildDefaultNodeState = (current, getScope) => {
|
|
|
16
14
|
const useScopeData = () => {
|
|
17
15
|
const currentScope = unwrapImmutable(useSelector(currentScopeSelector));
|
|
18
16
|
const getScope = useSelector(scopeGetter);
|
|
19
|
-
useLoader(getScopes(), () => currentScope.name);
|
|
20
17
|
const defaultNodeState = buildDefaultNodeState(currentScope, getScope);
|
|
21
18
|
return [currentScope, defaultNodeState, getScope];
|
|
22
19
|
};
|
|
@@ -2,7 +2,6 @@ import React from "react";
|
|
|
2
2
|
import { Provider } from "react-redux";
|
|
3
3
|
import { MemoryRouter } from "react-router-dom";
|
|
4
4
|
import Immutable from "immutable";
|
|
5
|
-
import { RSAA } from "redux-api-middleware";
|
|
6
5
|
import sinon from "sinon";
|
|
7
6
|
import { PropStruct } from "../../utils/testUtils";
|
|
8
7
|
import useScopeData from "./useScopeData";
|
|
@@ -122,30 +121,4 @@ describe("useScopeData", () => {
|
|
|
122
121
|
)
|
|
123
122
|
|
|
124
123
|
.then(() => expect(store.dispatch, "was not called")));
|
|
125
|
-
|
|
126
|
-
it("loads scopes if it has none", () => {
|
|
127
|
-
state = state.setIn(["scopes"], Immutable.Map());
|
|
128
|
-
return expect(
|
|
129
|
-
<Provider store={store}>
|
|
130
|
-
<MemoryRouter>
|
|
131
|
-
<TestComp />
|
|
132
|
-
</MemoryRouter>
|
|
133
|
-
</Provider>,
|
|
134
|
-
"when mounted",
|
|
135
|
-
"to be a",
|
|
136
|
-
"DOMElement",
|
|
137
|
-
).then(() =>
|
|
138
|
-
expect(store.dispatch, "to have calls satisfying", [
|
|
139
|
-
{
|
|
140
|
-
args: [
|
|
141
|
-
{
|
|
142
|
-
[RSAA]: {
|
|
143
|
-
types: ["GET_SCOPES_REQUEST", "GET_SCOPES_SUCCESS", "GET_SCOPES_FAILURE"],
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
},
|
|
148
|
-
]),
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
124
|
});
|
package/src/constants.js
CHANGED
|
@@ -23,6 +23,7 @@ export const roleGroups = {
|
|
|
23
23
|
Shopping: "Shopping",
|
|
24
24
|
Search: "Search",
|
|
25
25
|
Profiles: "Profiles",
|
|
26
|
+
Locations: "Locations",
|
|
26
27
|
Orchestrator: "Orchestrator",
|
|
27
28
|
PriceManagement: "PriceManagement",
|
|
28
29
|
UserManagement: "UserManagement",
|
|
@@ -73,6 +74,20 @@ export const attributeDataType = {
|
|
|
73
74
|
customType: "CustomType",
|
|
74
75
|
};
|
|
75
76
|
|
|
77
|
+
// It is intended that some of them have a different value of its keys
|
|
78
|
+
export const overtureModule = {
|
|
79
|
+
System: "System",
|
|
80
|
+
Products: "Product",
|
|
81
|
+
Customers: "Customer",
|
|
82
|
+
Orders: "Order",
|
|
83
|
+
Marketing: "Marketing",
|
|
84
|
+
Report: "Reports",
|
|
85
|
+
Administration: "Administration",
|
|
86
|
+
UserManagement: "UserManagement",
|
|
87
|
+
PriceManagement: "PriceManagement",
|
|
88
|
+
Locations: "Location",
|
|
89
|
+
};
|
|
90
|
+
|
|
76
91
|
export const definitionType = {
|
|
77
92
|
shared: "Shared",
|
|
78
93
|
embedded: "Embedded",
|
|
@@ -122,6 +122,9 @@
|
|
|
122
122
|
<symbol id="icon-dropdown-chevron-down" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
|
|
123
123
|
<polyline fill="none" stroke-linecap="round" stroke-linejoin="round" points="9 3 5 7 1 3"/>
|
|
124
124
|
</symbol>
|
|
125
|
+
<symbol id="icon-open-in-new-tab" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
|
|
126
|
+
<path stroke="none" fill-rule="evenodd" d="M8.4375,6.25 L7.8125,6.25 C7.63991102,6.25 7.5,6.38991102 7.5,6.5625 L7.5,8.75 L1.25,8.75 L1.25,2.5 L4.0625,2.5 C4.23508898,2.5 4.375,2.36008898 4.375,2.1875 L4.375,1.5625 C4.375,1.38991102 4.23508898,1.25 4.0625,1.25 L0.9375,1.25 C0.419733047,1.25 0,1.66973305 0,2.1875 L0,9.0625 C0,9.58026695 0.419733047,10 0.9375,10 L7.8125,10 C8.33026695,10 8.75,9.58026695 8.75,9.0625 L8.75,6.5625 C8.75,6.38991102 8.61008898,6.25 8.4375,6.25 Z M9.53125,0 L7.03125,0 C6.61386719,0 6.40527344,0.506054688 6.69921875,0.80078125 L7.39707031,1.49863281 L2.63671875,6.25722656 C2.54845882,6.34518057 2.49884911,6.46465556 2.49884911,6.58925781 C2.49884911,6.71386007 2.54845882,6.83333506 2.63671875,6.92128906 L3.07949219,7.36328125 C3.16744619,7.45154118 3.28692118,7.50115089 3.41152344,7.50115089 C3.53612569,7.50115089 3.65560068,7.45154118 3.74355469,7.36328125 L8.5015625,2.60390625 L9.19921875,3.30078125 C9.4921875,3.59375 10,3.38867188 10,2.96875 L10,0.46875 C10,0.209866524 9.79013348,0 9.53125,0 Z"/>
|
|
127
|
+
</symbol>
|
|
125
128
|
<symbol id="icon-dropdown-chevron-right" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
|
|
126
129
|
<polyline fill="none" stroke-linecap="round" stroke-linejoin="round" points="9 3 5 7 1 3" transform="rotate(-90 5 5)"/>
|
|
127
130
|
</symbol>
|
|
@@ -2,7 +2,6 @@ import React from "react";
|
|
|
2
2
|
import { Provider } from "react-redux";
|
|
3
3
|
import { MemoryRouter } from "react-router-dom";
|
|
4
4
|
import Immutable from "immutable";
|
|
5
|
-
import { RSAA } from "redux-api-middleware";
|
|
6
5
|
import sinon from "sinon";
|
|
7
6
|
import { PropStruct, spyOnConsole } from "../utils/testUtils";
|
|
8
7
|
import withScopeData from "./withScopeData";
|
|
@@ -142,34 +141,4 @@ describe("withScopeData", () => {
|
|
|
142
141
|
),
|
|
143
142
|
)
|
|
144
143
|
.then(() => expect(store.dispatch, "was not called")));
|
|
145
|
-
|
|
146
|
-
it("loads scopes if it has none", () => {
|
|
147
|
-
state = state.setIn(["scopes"], Immutable.Map());
|
|
148
|
-
return expect(withScopeData, "when called with", [TestComp])
|
|
149
|
-
.then(Comp =>
|
|
150
|
-
expect(
|
|
151
|
-
<Provider store={store}>
|
|
152
|
-
<MemoryRouter>
|
|
153
|
-
<Comp />
|
|
154
|
-
</MemoryRouter>
|
|
155
|
-
</Provider>,
|
|
156
|
-
"when mounted",
|
|
157
|
-
"to be a",
|
|
158
|
-
"DOMElement",
|
|
159
|
-
),
|
|
160
|
-
)
|
|
161
|
-
.then(() =>
|
|
162
|
-
expect(store.dispatch, "to have calls satisfying", [
|
|
163
|
-
{
|
|
164
|
-
args: [
|
|
165
|
-
{
|
|
166
|
-
[RSAA]: {
|
|
167
|
-
types: ["GET_SCOPES_REQUEST", "GET_SCOPES_SUCCESS", "GET_SCOPES_FAILURE"],
|
|
168
|
-
},
|
|
169
|
-
},
|
|
170
|
-
],
|
|
171
|
-
},
|
|
172
|
-
]),
|
|
173
|
-
);
|
|
174
|
-
});
|
|
175
144
|
});
|
package/src/reducers/modules.js
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
import Immutable from "immutable";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
INITIALIZE_FIRST_MODULE_SCOPE,
|
|
4
|
+
SET_MODULE_AS_VISIBLE,
|
|
5
|
+
SET_MODULES_STRUCTURE,
|
|
6
|
+
SET_NEW_SCOPE_AND_MODULE_NAME,
|
|
7
|
+
SET_ROUTING_PERFORMED,
|
|
8
|
+
} from "../actions/modules";
|
|
3
9
|
import { infoBar } from "./../constants";
|
|
4
10
|
|
|
5
|
-
const initialState = Immutable.
|
|
11
|
+
const initialState = Immutable.fromJS({
|
|
12
|
+
tree: {},
|
|
13
|
+
visibleModules: [],
|
|
14
|
+
lastScopeAndModuleSelection: {
|
|
15
|
+
scope: null,
|
|
16
|
+
moduleName: null,
|
|
17
|
+
routingPerformed: true,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
6
20
|
|
|
7
21
|
const viewStateReducer = (state = initialState, action) => {
|
|
8
22
|
switch (action.type) {
|
|
@@ -32,6 +46,38 @@ const viewStateReducer = (state = initialState, action) => {
|
|
|
32
46
|
|
|
33
47
|
return state.set("tree", Immutable.fromJS(modulesTree));
|
|
34
48
|
}
|
|
49
|
+
|
|
50
|
+
case INITIALIZE_FIRST_MODULE_SCOPE: {
|
|
51
|
+
return state.setIn(["lastScopeAndModuleSelection", "scope"], action.payload);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
case SET_MODULE_AS_VISIBLE: {
|
|
55
|
+
const visibleModules = state.get("visibleModules").toJS();
|
|
56
|
+
visibleModules.push(action.payload);
|
|
57
|
+
|
|
58
|
+
return state.set("visibleModules", Immutable.fromJS(visibleModules));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
case SET_NEW_SCOPE_AND_MODULE_NAME: {
|
|
62
|
+
const lastScopeAndModuleSelection = state.get("lastScopeAndModuleSelection").toJS();
|
|
63
|
+
|
|
64
|
+
if (action.payload.scope !== lastScopeAndModuleSelection.scope) {
|
|
65
|
+
state = state.set("visibleModules", Immutable.fromJS([]));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return state.set(
|
|
69
|
+
"lastScopeAndModuleSelection",
|
|
70
|
+
Immutable.fromJS({
|
|
71
|
+
moduleName: action.payload.moduleName,
|
|
72
|
+
scope: action.payload.scope,
|
|
73
|
+
routingPerformed: false,
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
case SET_ROUTING_PERFORMED:
|
|
79
|
+
return state.setIn(["lastScopeAndModuleSelection", "routingPerformed"], true);
|
|
80
|
+
|
|
35
81
|
default:
|
|
36
82
|
return state;
|
|
37
83
|
}
|