orc-shared 5.7.0-dev.9 → 5.8.0-dev.2
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/requestsApi.js +743 -140
- package/dist/actions/scopes.js +25 -1
- package/dist/buildStore.js +2 -0
- package/dist/components/MaterialUI/DataDisplay/PredefinedElements/InformationItem.js +7 -3
- package/dist/components/MaterialUI/Inputs/CheckboxGroup.js +10 -4
- package/dist/components/MaterialUI/Inputs/CheckboxGroupProps.js +3 -1
- package/dist/components/MaterialUI/Inputs/InputBase.js +6 -1
- package/dist/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +15 -8
- package/dist/components/Provision.js +2 -1
- package/dist/components/ScopeExtendedConfigurationLoader.js +83 -0
- package/dist/constants.js +11 -2
- package/dist/content/icons/orckestra-icon.svg +11 -5
- package/dist/reducers/scopesExtendedConfiguration.js +68 -0
- package/dist/selectors/metadata.js +11 -1
- package/dist/selectors/scopeExtendedConfiguration.js +56 -0
- package/dist/utils/propertyBagHelper.js +3 -0
- package/package.json +1 -1
- package/src/actions/requestsApi.js +511 -89
- package/src/actions/scopes.js +25 -1
- package/src/actions/scopes.test.js +34 -0
- package/src/buildStore.js +2 -0
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/InformationItem.js +9 -3
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/InformationItem.test.js +29 -0
- package/src/components/MaterialUI/Inputs/CheckboxGroup.js +5 -4
- package/src/components/MaterialUI/Inputs/CheckboxGroup.test.js +22 -0
- package/src/components/MaterialUI/Inputs/CheckboxGroupProps.js +2 -0
- package/src/components/MaterialUI/Inputs/CheckboxGroupProps.test.js +2 -2
- package/src/components/MaterialUI/Inputs/InputBase.js +8 -5
- package/src/components/MaterialUI/Inputs/InputBase.test.js +160 -110
- package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +13 -6
- package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.test.js +57 -0
- package/src/components/Provision.js +2 -0
- package/src/components/Provision.test.js +7 -0
- package/src/components/ScopeExtendedConfigurationLoader.js +22 -0
- package/src/components/ScopeExtendedConfigurationLoader.test.js +71 -0
- package/src/constants.js +8 -0
- package/src/content/icons/orckestra-icon.svg +11 -5
- package/src/reducers/scopesExtendedConfiguration.js +16 -0
- package/src/reducers/scopesExtendedConfiguration.test.js +31 -0
- package/src/selectors/metadata.js +9 -0
- package/src/selectors/metadata.test.js +90 -0
- package/src/selectors/scopeExtendedConfiguration.js +9 -0
- package/src/selectors/scopeExtendedConfiguration.test.js +45 -0
- package/src/utils/propertyBagHelper.js +3 -0
- package/src/utils/propertyBagHelper.test.js +7 -0
|
@@ -238,6 +238,63 @@ describe("SearchControl Component", () => {
|
|
|
238
238
|
expect(onSearchEvent, "to have calls satisfying", [{ args: ["aValue", "abc"] }]);
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
+
it("Search value should be trimmed after a search", () => {
|
|
242
|
+
const options = [
|
|
243
|
+
{ value: "aValue", label: "aLabel" },
|
|
244
|
+
{ value: "anotherValue", label: "anotherLabel" },
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
const onSearchEvent = sinon.spy().named("search");
|
|
248
|
+
|
|
249
|
+
const component = (
|
|
250
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
251
|
+
<SearchControl placeholder="placeHolderTest" searchOptions={options} onSearch={onSearchEvent} />
|
|
252
|
+
</TestWrapper>
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const mountedComponent = mount(component);
|
|
256
|
+
|
|
257
|
+
const allInputs = mountedComponent.find("input");
|
|
258
|
+
const searchInput = allInputs.find("[placeholder='placeHolderTest']");
|
|
259
|
+
expect(searchInput.length, "to be", 1);
|
|
260
|
+
|
|
261
|
+
searchInput.instance().value = "abc ";
|
|
262
|
+
mountedComponent.find("form").simulate("submit", { preventDefault: () => {} });
|
|
263
|
+
|
|
264
|
+
expect(onSearchEvent, "to have calls satisfying", [{ args: ["aValue", "abc"] }]);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it("Search value should not be trimmed after a search", () => {
|
|
268
|
+
const options = [
|
|
269
|
+
{ value: "aValue", label: "aLabel" },
|
|
270
|
+
{ value: "anotherValue", label: "anotherLabel" },
|
|
271
|
+
];
|
|
272
|
+
|
|
273
|
+
const onSearchEvent = sinon.spy().named("search");
|
|
274
|
+
|
|
275
|
+
const component = (
|
|
276
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
277
|
+
<SearchControl
|
|
278
|
+
placeholder="placeHolderTest"
|
|
279
|
+
searchOptions={options}
|
|
280
|
+
onSearch={onSearchEvent}
|
|
281
|
+
trimSearchvalue={false}
|
|
282
|
+
/>
|
|
283
|
+
</TestWrapper>
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const mountedComponent = mount(component);
|
|
287
|
+
|
|
288
|
+
const allInputs = mountedComponent.find("input");
|
|
289
|
+
const searchInput = allInputs.find("[placeholder='placeHolderTest']");
|
|
290
|
+
expect(searchInput.length, "to be", 1);
|
|
291
|
+
|
|
292
|
+
searchInput.instance().value = "abc ";
|
|
293
|
+
mountedComponent.find("form").simulate("submit", { preventDefault: () => {} });
|
|
294
|
+
|
|
295
|
+
expect(onSearchEvent, "to have calls satisfying", [{ args: ["aValue", "abc "] }]);
|
|
296
|
+
});
|
|
297
|
+
|
|
241
298
|
it("Search Control should trigger the event when clicking on the search button", () => {
|
|
242
299
|
const options = [
|
|
243
300
|
{ value: "aValue", label: "aLabel" },
|
|
@@ -11,6 +11,7 @@ import Head from "./Head";
|
|
|
11
11
|
import I18n from "./I18n";
|
|
12
12
|
import InternetExplorerWarningMessage from "./InternetExplorerWarningMessage";
|
|
13
13
|
import Culture from "./Culture";
|
|
14
|
+
import ScopeExtendedConfigurationLoader from "./ScopeExtendedConfigurationLoader";
|
|
14
15
|
|
|
15
16
|
const GlobalStyle = createGlobalStyle`
|
|
16
17
|
html {
|
|
@@ -53,6 +54,7 @@ const Provision = ({ store, theme = {}, muiTheme, children }) => {
|
|
|
53
54
|
<InternetExplorerWarningMessage />
|
|
54
55
|
</I18n>
|
|
55
56
|
</DevPages>
|
|
57
|
+
<ScopeExtendedConfigurationLoader />
|
|
56
58
|
</React.Fragment>
|
|
57
59
|
</Authenticate>
|
|
58
60
|
</React.Fragment>
|
|
@@ -54,6 +54,13 @@ const fakeStore = {
|
|
|
54
54
|
loadedModulesScope: ["moduleA", "moduleB"],
|
|
55
55
|
modules: ["moduleA", "moduleB"],
|
|
56
56
|
},
|
|
57
|
+
navigation: {
|
|
58
|
+
route: {
|
|
59
|
+
match: { path: "/:scope/TheModuleName/:entityId", params: { scope: "TheOldScope", entityId: "loaderId" } },
|
|
60
|
+
},
|
|
61
|
+
moduleTabs: {},
|
|
62
|
+
config: { prependPath: "/:scope/", prependHref: "/Scope1/" },
|
|
63
|
+
},
|
|
57
64
|
}),
|
|
58
65
|
replaceReducer: () => {},
|
|
59
66
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import useScopeData from "./Scope/useScopeData";
|
|
3
|
+
import { useDispatch } from "react-redux";
|
|
4
|
+
import { getScopeExtendedConfiguration } from "../actions/scopes";
|
|
5
|
+
|
|
6
|
+
const ScopeExtendedConfigurationLoader = () => {
|
|
7
|
+
const [currentScope] = useScopeData();
|
|
8
|
+
const dispatch = useDispatch();
|
|
9
|
+
|
|
10
|
+
const [localScopeValue, setLocalScopeValue] = useState();
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (currentScope.id !== localScopeValue) {
|
|
14
|
+
setLocalScopeValue(currentScope.id);
|
|
15
|
+
dispatch(getScopeExtendedConfiguration(currentScope.id));
|
|
16
|
+
}
|
|
17
|
+
}, [currentScope.id, dispatch, localScopeValue]);
|
|
18
|
+
|
|
19
|
+
return null;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default ScopeExtendedConfigurationLoader;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Immutable from "immutable";
|
|
3
|
+
import { Provider } from "react-redux";
|
|
4
|
+
import { ThemeProvider } from "styled-components";
|
|
5
|
+
import ScopeExtendedConfigurationLoader from "./ScopeExtendedConfigurationLoader";
|
|
6
|
+
import { mount } from "enzyme";
|
|
7
|
+
import { getScopeExtendedConfiguration } from "../actions/scopes";
|
|
8
|
+
import sinon from "sinon";
|
|
9
|
+
|
|
10
|
+
jest.mock("../utils/buildUrl", () => {
|
|
11
|
+
const modExport = {};
|
|
12
|
+
modExport.loadConfig = () => Promise.resolve({});
|
|
13
|
+
modExport.buildUrl = (path = [], params = "") => "URL: " + path.join("/") + " " + JSON.stringify(params);
|
|
14
|
+
return modExport;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe("ScopeExtendedConfigurationLoader", () => {
|
|
18
|
+
let state, store;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
state = Immutable.fromJS({
|
|
22
|
+
locale: {
|
|
23
|
+
locale: "en-US",
|
|
24
|
+
},
|
|
25
|
+
authentication: {
|
|
26
|
+
name: "foo@bar.com",
|
|
27
|
+
},
|
|
28
|
+
requests: {},
|
|
29
|
+
scopes: {
|
|
30
|
+
TheOldScope: {
|
|
31
|
+
id: "TheOldScope",
|
|
32
|
+
name: { "en-CA": "Test 1", "en-US": "TheOldScope" },
|
|
33
|
+
children: ["test2"],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
settings: {
|
|
37
|
+
defaultScope: "aDefaultScope",
|
|
38
|
+
loadedModulesScope: ["moduleA", "moduleB"],
|
|
39
|
+
modules: ["moduleA", "moduleB"],
|
|
40
|
+
},
|
|
41
|
+
navigation: {
|
|
42
|
+
route: {
|
|
43
|
+
match: { path: "/:scope/TheModuleName/:entityId", params: { scope: "TheOldScope", entityId: "loaderId" } },
|
|
44
|
+
},
|
|
45
|
+
moduleTabs: {},
|
|
46
|
+
config: { prependPath: "/:scope/", prependHref: "/Scope1/" },
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
store = state => ({
|
|
50
|
+
subscribe: () => {},
|
|
51
|
+
getState: () => state,
|
|
52
|
+
dispatch: sinon.spy().named("dispatch"),
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("dispatch request to get extended configuration", () => {
|
|
57
|
+
const theStore = store(state);
|
|
58
|
+
|
|
59
|
+
const component = (
|
|
60
|
+
<Provider store={theStore}>
|
|
61
|
+
<ThemeProvider theme={{}}>
|
|
62
|
+
<ScopeExtendedConfigurationLoader />
|
|
63
|
+
</ThemeProvider>
|
|
64
|
+
</Provider>
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
mount(component);
|
|
68
|
+
|
|
69
|
+
expect(theStore.dispatch, "to have calls satisfying", [{ args: [getScopeExtendedConfiguration("TheOldScope")] }]);
|
|
70
|
+
});
|
|
71
|
+
});
|
package/src/constants.js
CHANGED
|
@@ -74,6 +74,8 @@ export const attributeDataType = {
|
|
|
74
74
|
lookup: "Lookup",
|
|
75
75
|
entityReference: "EntityReference",
|
|
76
76
|
customType: "CustomType",
|
|
77
|
+
singleChoice: "SingleChoice",
|
|
78
|
+
multipleChoice: "MultipleChoice",
|
|
77
79
|
};
|
|
78
80
|
|
|
79
81
|
// It is intended that some of them have a different value of its keys
|
|
@@ -166,7 +168,13 @@ export const jsonCargoType = {
|
|
|
166
168
|
double: "Double",
|
|
167
169
|
dateTime: "DateTime",
|
|
168
170
|
integer: "Int32",
|
|
171
|
+
stringArray: "String[]",
|
|
169
172
|
entityReferences: "Guid[]",
|
|
170
173
|
};
|
|
171
174
|
|
|
172
175
|
export const allValue = "#All#";
|
|
176
|
+
|
|
177
|
+
export const choiceControlOrientation = {
|
|
178
|
+
horizontal: "Horizontal",
|
|
179
|
+
vertical: "Vertical",
|
|
180
|
+
};
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
<svg
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
</
|
|
1
|
+
<svg width="354" height="354" viewBox="0 0 354 354" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<g clip-path="url(#clip0_2_1387)">
|
|
3
|
+
<path d="M0 241.41C0 175.92 50.53 129.43 119.66 129.43C188.79 129.43 238.91 175.92 238.91 241.41C238.91 306.9 188.78 353.38 119.66 353.38C50.54 353.38 0 306.9 0 241.41ZM175.04 241.41C175.04 203.81 151.19 181.18 119.66 181.18C88.13 181.18 63.87 203.82 63.87 241.41C63.87 279 88.13 301.64 119.66 301.64C151.19 301.64 175.04 279 175.04 241.41Z" fill="black"/>
|
|
4
|
+
<path d="M353.14 165.06H275.66C275.66 116.77 236.37 77.48 188.08 77.48V0C279.1 0 353.15 74.05 353.15 165.06H353.14Z" fill="#E00600"/>
|
|
5
|
+
</g>
|
|
6
|
+
<defs>
|
|
7
|
+
<clipPath id="clip0_2_1387">
|
|
8
|
+
<rect width="353.14" height="353.38" fill="white"/>
|
|
9
|
+
</clipPath>
|
|
10
|
+
</defs>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Immutable from "immutable";
|
|
2
|
+
import { GET_SCOPE_EXTENDED_CONFIGURATION_SUCCESS } from "../actions/scopes";
|
|
3
|
+
|
|
4
|
+
const initialState = Immutable.fromJS({});
|
|
5
|
+
|
|
6
|
+
const scopesExtendedConfigurationReducer = (state = initialState, action) => {
|
|
7
|
+
switch (action.type) {
|
|
8
|
+
case GET_SCOPE_EXTENDED_CONFIGURATION_SUCCESS: {
|
|
9
|
+
return state.set(action.meta.scope, Immutable.fromJS(action.payload));
|
|
10
|
+
}
|
|
11
|
+
default:
|
|
12
|
+
return state;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default scopesExtendedConfigurationReducer;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import Immutable from "immutable";
|
|
2
|
+
import { GET_SCOPE_EXTENDED_CONFIGURATION_SUCCESS } from "../actions/scopes";
|
|
3
|
+
import reducer from "./scopesExtendedConfiguration";
|
|
4
|
+
|
|
5
|
+
describe("scopesExtendedConfiguration", () => {
|
|
6
|
+
it("behaves as a reducer should", () => expect(reducer, "to be a reducer with initial state", {}));
|
|
7
|
+
|
|
8
|
+
it("save scope info to store", () => {
|
|
9
|
+
const oldState = Immutable.Map({
|
|
10
|
+
TheScope: { extConfig: 789 },
|
|
11
|
+
anotherScope: { extConfig: 456 },
|
|
12
|
+
});
|
|
13
|
+
const action = {
|
|
14
|
+
type: GET_SCOPE_EXTENDED_CONFIGURATION_SUCCESS,
|
|
15
|
+
meta: {
|
|
16
|
+
scope: "TheScope",
|
|
17
|
+
},
|
|
18
|
+
payload: {
|
|
19
|
+
extConfig: 123,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const newState = reducer(oldState, action);
|
|
23
|
+
return expect(newState, "not to be", oldState).and(
|
|
24
|
+
"to satisfy",
|
|
25
|
+
Immutable.fromJS({
|
|
26
|
+
TheScope: { extConfig: 123 },
|
|
27
|
+
anotherScope: { extConfig: 456 },
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -66,6 +66,15 @@ export const namedLookupLocalizedSelector = memoize((moduleName, lookupName, key
|
|
|
66
66
|
}),
|
|
67
67
|
);
|
|
68
68
|
|
|
69
|
+
export const lookupExistAndIsActiveSelector = memoize((moduleName, lookupName, key) =>
|
|
70
|
+
createSelector(lookupValuesSelector(moduleName, lookupName), lookups => {
|
|
71
|
+
const values = lookups.get("values");
|
|
72
|
+
if (values == null || key == null) return false;
|
|
73
|
+
const value = values.get(key);
|
|
74
|
+
return value?.get("isActive") === true;
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
|
|
69
78
|
export const namedLookupLocalizedValuesSelector = memoize((moduleName, lookupName) =>
|
|
70
79
|
createSelector(lookupValuesSelector(moduleName, lookupName), currentLocaleOrDefault, (lookup, locale) =>
|
|
71
80
|
(lookup.get("values") || Immutable.Map()).map(lookupValue =>
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
definitionEntityCustomAttributesSelector,
|
|
31
31
|
lookupByNameSelector,
|
|
32
32
|
mappedLookupsListSelector,
|
|
33
|
+
lookupExistAndIsActiveSelector,
|
|
33
34
|
} from "./metadata";
|
|
34
35
|
|
|
35
36
|
const lookups = {
|
|
@@ -1899,3 +1900,92 @@ describe("definitions", () => {
|
|
|
1899
1900
|
);
|
|
1900
1901
|
});
|
|
1901
1902
|
});
|
|
1903
|
+
|
|
1904
|
+
describe("lookupExistAndIsActiveSelector", () => {
|
|
1905
|
+
let state;
|
|
1906
|
+
beforeEach(() => {
|
|
1907
|
+
state = Immutable.fromJS({
|
|
1908
|
+
locale: { locale: "it-IT" },
|
|
1909
|
+
metadata: {
|
|
1910
|
+
lookups: {
|
|
1911
|
+
order: {
|
|
1912
|
+
index: {
|
|
1913
|
+
...lookups,
|
|
1914
|
+
DistanceUOM: {
|
|
1915
|
+
lookupName: "DistanceUOM",
|
|
1916
|
+
values: {
|
|
1917
|
+
Inches: {
|
|
1918
|
+
value: "Inches",
|
|
1919
|
+
displayName: {
|
|
1920
|
+
"en-CA": "inEnCa",
|
|
1921
|
+
"en-US": "inEnUS",
|
|
1922
|
+
"fr-CA": "inFrCa",
|
|
1923
|
+
"it-IT": "inItIt",
|
|
1924
|
+
},
|
|
1925
|
+
isActive: true,
|
|
1926
|
+
},
|
|
1927
|
+
},
|
|
1928
|
+
},
|
|
1929
|
+
},
|
|
1930
|
+
list: [],
|
|
1931
|
+
},
|
|
1932
|
+
},
|
|
1933
|
+
},
|
|
1934
|
+
});
|
|
1935
|
+
});
|
|
1936
|
+
|
|
1937
|
+
it("retrieves true when lookup exist and value is active", () => {
|
|
1938
|
+
expect(
|
|
1939
|
+
lookupExistAndIsActiveSelector,
|
|
1940
|
+
"when called with",
|
|
1941
|
+
["order", "DistanceUOM", "Inches"],
|
|
1942
|
+
"when called with",
|
|
1943
|
+
[state],
|
|
1944
|
+
"to be",
|
|
1945
|
+
true,
|
|
1946
|
+
);
|
|
1947
|
+
});
|
|
1948
|
+
|
|
1949
|
+
it("retrieves false when lookup exist and value is inactive", () => {
|
|
1950
|
+
state = state.setIn(
|
|
1951
|
+
["metadata", "lookups", "order", "index", "DistanceUOM", "values", "Inches", "isActive"],
|
|
1952
|
+
false,
|
|
1953
|
+
);
|
|
1954
|
+
|
|
1955
|
+
expect(
|
|
1956
|
+
lookupExistAndIsActiveSelector,
|
|
1957
|
+
"when called with",
|
|
1958
|
+
["order", "DistanceUOM", "Inches"],
|
|
1959
|
+
"when called with",
|
|
1960
|
+
[state],
|
|
1961
|
+
"to be",
|
|
1962
|
+
false,
|
|
1963
|
+
);
|
|
1964
|
+
});
|
|
1965
|
+
|
|
1966
|
+
it("retrieves false when lookup exist and its values property is null", () => {
|
|
1967
|
+
state = state.setIn(["metadata", "lookups", "order", "index", "DistanceUOM", "values"], null);
|
|
1968
|
+
|
|
1969
|
+
expect(
|
|
1970
|
+
lookupExistAndIsActiveSelector,
|
|
1971
|
+
"when called with",
|
|
1972
|
+
["order", "DistanceUOM", "Inches"],
|
|
1973
|
+
"when called with",
|
|
1974
|
+
[state],
|
|
1975
|
+
"to be",
|
|
1976
|
+
false,
|
|
1977
|
+
);
|
|
1978
|
+
});
|
|
1979
|
+
|
|
1980
|
+
it("retrieves false when lookup exist and lookup value name does not exist", () => {
|
|
1981
|
+
expect(
|
|
1982
|
+
lookupExistAndIsActiveSelector,
|
|
1983
|
+
"when called with",
|
|
1984
|
+
["order", "DistanceUOM", "unknown"],
|
|
1985
|
+
"when called with",
|
|
1986
|
+
[state],
|
|
1987
|
+
"to be",
|
|
1988
|
+
false,
|
|
1989
|
+
);
|
|
1990
|
+
});
|
|
1991
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createSelector } from "reselect";
|
|
2
|
+
|
|
3
|
+
const scopesExtendedConfigurationData = state => state.get("scopesExtendedConfiguration");
|
|
4
|
+
|
|
5
|
+
export const doesScopeHaveGeolocationProviderSelector = scopeId => {
|
|
6
|
+
return createSelector(scopesExtendedConfigurationData, scopesCfg => {
|
|
7
|
+
return scopesCfg?.get(scopeId)?.get("hasGeolocationProvider") ?? false;
|
|
8
|
+
});
|
|
9
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Immutable from "immutable";
|
|
2
|
+
import { doesScopeHaveGeolocationProviderSelector } from "./scopeExtendedConfiguration";
|
|
3
|
+
|
|
4
|
+
let state;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
state = Immutable.fromJS({
|
|
7
|
+
navigation: {
|
|
8
|
+
route: { location: {}, match: { params: { scope: "SecondChild" } } },
|
|
9
|
+
},
|
|
10
|
+
locale: {
|
|
11
|
+
locale: "fr",
|
|
12
|
+
supportedLocales: ["en", "fr"],
|
|
13
|
+
},
|
|
14
|
+
scopesExtendedConfiguration: {
|
|
15
|
+
theScope: { hasGeolocationProvider: true },
|
|
16
|
+
},
|
|
17
|
+
settings: {
|
|
18
|
+
defaultScope: "FirstChild",
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("doesScopeHaveGeolocationProviderSelector", () => {
|
|
24
|
+
it("gets an unknown scope", () =>
|
|
25
|
+
expect(
|
|
26
|
+
doesScopeHaveGeolocationProviderSelector,
|
|
27
|
+
"when called with",
|
|
28
|
+
["Unknown"],
|
|
29
|
+
"called with",
|
|
30
|
+
[state],
|
|
31
|
+
"to be",
|
|
32
|
+
false,
|
|
33
|
+
));
|
|
34
|
+
|
|
35
|
+
it("gets a known scope", () =>
|
|
36
|
+
expect(
|
|
37
|
+
doesScopeHaveGeolocationProviderSelector,
|
|
38
|
+
"when called with",
|
|
39
|
+
["theScope"],
|
|
40
|
+
"called with",
|
|
41
|
+
[state],
|
|
42
|
+
"to be",
|
|
43
|
+
true,
|
|
44
|
+
));
|
|
45
|
+
});
|
|
@@ -49,7 +49,10 @@ export const toJsonCargo = (attribute, value) => {
|
|
|
49
49
|
switch (attribute.dataType) {
|
|
50
50
|
case attributeDataType.text:
|
|
51
51
|
case attributeDataType.lookup:
|
|
52
|
+
case attributeDataType.singleChoice:
|
|
52
53
|
return value;
|
|
54
|
+
case attributeDataType.multipleChoice:
|
|
55
|
+
return createJsonCargo(jsonCargoType.stringArray, value);
|
|
53
56
|
|
|
54
57
|
case attributeDataType.boolean:
|
|
55
58
|
return createJsonCargo(jsonCargoType.boolean, value);
|
|
@@ -123,6 +123,13 @@ describe("toJsonCargo function", () => {
|
|
|
123
123
|
tiers: [{ min: "2", rate: "2" }],
|
|
124
124
|
},
|
|
125
125
|
],
|
|
126
|
+
["aRadioValue", attributeDataType.singleChoice, null, "aRadioValue"],
|
|
127
|
+
[
|
|
128
|
+
["aCheckboxValue1", "aCheckboxValue1"],
|
|
129
|
+
attributeDataType.multipleChoice,
|
|
130
|
+
null,
|
|
131
|
+
{ __type: "ValueOfString[]", value: ["aCheckboxValue1", "aCheckboxValue1"] },
|
|
132
|
+
],
|
|
126
133
|
])("should return the proper json cargo with %s of type %s", (value, dataType, customType, expectedCargo) => {
|
|
127
134
|
const attribute = {
|
|
128
135
|
dataType: dataType,
|