orc-shared 1.2.0-dev.10 → 1.2.0-dev.14
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/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/components/AppFrame/About.js +5 -1
- package/dist/components/AppFrame/AppFrame.js +14 -4
- package/dist/components/AppFrame/MenuItem.js +1 -4
- package/dist/components/MaterialUI/Inputs/InputBase.js +41 -4
- package/dist/components/MaterialUI/ScopeSelector/ScopeSelector.js +8 -2
- package/dist/components/Routing/FullPage.js +6 -3
- package/dist/selectors/metadata.js +13 -3
- package/dist/selectors/scope.js +2 -1
- package/dist/utils/setTranslation.js +27 -1
- package/dist/utils/setTranslationWithFallback.js +30 -1
- package/package.json +1 -1
- package/src/components/AppFrame/About.js +8 -1
- package/src/components/AppFrame/AppFrame.js +13 -2
- package/src/components/AppFrame/AppFrame.test.js +53 -0
- package/src/components/AppFrame/MenuItem.js +1 -12
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/Translations.test.js +7 -1
- package/src/components/MaterialUI/Inputs/InputBase.js +19 -2
- package/src/components/MaterialUI/Inputs/InputBase.test.js +68 -0
- package/src/components/MaterialUI/ScopeSelector/ScopeSelector.js +5 -1
- package/src/components/Routing/FullPage.js +12 -4
- package/src/components/Routing/FullPage.test.js +24 -0
- package/src/components/Scope/Scope.test.js +4 -0
- package/src/selectors/metadata.js +18 -7
- package/src/selectors/metadata.test.js +221 -283
- package/src/selectors/scope.js +1 -1
- package/src/translations/en-US.json +1 -1
- package/src/translations/fr-CA.json +1 -1
- package/src/utils/setTranslation.js +16 -1
- package/src/utils/setTranslation.test.js +24 -0
- package/src/utils/setTranslationWithFallback.js +18 -1
- package/src/utils/setTranslationWithFallback.test.js +108 -0
|
@@ -5,15 +5,19 @@ import InputBaseMUI from "@material-ui/core/InputBase";
|
|
|
5
5
|
import sinon from "sinon";
|
|
6
6
|
import { ignoreConsoleError } from "../../../utils/testUtils";
|
|
7
7
|
import InputBaseProps from "./InputBaseProps";
|
|
8
|
+
import { act } from "unexpected-reaction";
|
|
8
9
|
|
|
9
10
|
describe("InputBase Component", () => {
|
|
10
11
|
let update, container;
|
|
11
12
|
beforeEach(() => {
|
|
13
|
+
window.bypassDebounce = true;
|
|
14
|
+
|
|
12
15
|
container = document.createElement("div");
|
|
13
16
|
document.body.appendChild(container);
|
|
14
17
|
update = sinon.spy().named("update");
|
|
15
18
|
});
|
|
16
19
|
afterEach(() => {
|
|
20
|
+
delete window.bypassDebounce;
|
|
17
21
|
document.body.removeChild(container);
|
|
18
22
|
container = null;
|
|
19
23
|
});
|
|
@@ -243,3 +247,67 @@ describe("InputBase Component", () => {
|
|
|
243
247
|
expect(mountedComponent.containsMatchingElement(expected), "to be truthy");
|
|
244
248
|
});
|
|
245
249
|
});
|
|
250
|
+
|
|
251
|
+
describe("InputBase component debouce", () => {
|
|
252
|
+
const clock = sinon.useFakeTimers();
|
|
253
|
+
let update, container;
|
|
254
|
+
|
|
255
|
+
beforeEach(() => {
|
|
256
|
+
container = document.createElement("div");
|
|
257
|
+
document.body.appendChild(container);
|
|
258
|
+
update = sinon.spy().named("update");
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
afterEach(() => {
|
|
262
|
+
clock.restore();
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it("InputBase component updates when debounced update", async () => {
|
|
266
|
+
const inputProps = new InputBaseProps();
|
|
267
|
+
const aLabel = "aLabel";
|
|
268
|
+
const aValue = "value";
|
|
269
|
+
|
|
270
|
+
const metadata = {
|
|
271
|
+
test: "value",
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
inputProps.set(InputBaseProps.propNames.value, "");
|
|
275
|
+
inputProps.set(InputBaseProps.propNames.update, update);
|
|
276
|
+
inputProps.set(InputBaseProps.propNames.label, aLabel);
|
|
277
|
+
inputProps.set(InputBaseProps.propNames.metadata, metadata);
|
|
278
|
+
|
|
279
|
+
const component = <InputBase inputProps={inputProps} />;
|
|
280
|
+
const mountedComponent = mount(component);
|
|
281
|
+
|
|
282
|
+
const input = mountedComponent.find("input");
|
|
283
|
+
input.simulate("change", { target: { value: aValue } });
|
|
284
|
+
|
|
285
|
+
act(() => {
|
|
286
|
+
clock.tick(200);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
input.simulate("change", { target: { value: "differentValue" } });
|
|
290
|
+
expect(update, "to have calls satisfying", [{ args: [aValue, metadata] }]);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it("InputBase component update to empty when text to display is null", async () => {
|
|
294
|
+
const inputProps = new InputBaseProps();
|
|
295
|
+
const aLabel = "aLabel";
|
|
296
|
+
|
|
297
|
+
const metadata = {
|
|
298
|
+
test: "value",
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
inputProps.set(InputBaseProps.propNames.value, null);
|
|
302
|
+
inputProps.set(InputBaseProps.propNames.update, update);
|
|
303
|
+
inputProps.set(InputBaseProps.propNames.label, aLabel);
|
|
304
|
+
inputProps.set(InputBaseProps.propNames.metadata, metadata);
|
|
305
|
+
|
|
306
|
+
const component = <InputBase inputProps={inputProps} />;
|
|
307
|
+
const mountedComponent = mount(component);
|
|
308
|
+
|
|
309
|
+
const input = mountedComponent.find("input");
|
|
310
|
+
input.simulate("change", { target: { value: null } });
|
|
311
|
+
expect(input.get(0).props.value, "to equal", "");
|
|
312
|
+
});
|
|
313
|
+
});
|
|
@@ -16,6 +16,10 @@ const useStyles = makeStyles(theme => ({
|
|
|
16
16
|
border: `1px solid ${theme.palette.grey.borders}`,
|
|
17
17
|
boxShadow: "0 2px 4px rgba(0,0,0,0.5)",
|
|
18
18
|
width: theme.spacing(50),
|
|
19
|
+
display: "flex",
|
|
20
|
+
},
|
|
21
|
+
scopeContainer: {
|
|
22
|
+
width: "100%",
|
|
19
23
|
},
|
|
20
24
|
scopeSelector: {
|
|
21
25
|
display: "flex",
|
|
@@ -64,7 +68,7 @@ const ScopeSelector = ({ show, getScope, selectedScope, closeSelector, filter, u
|
|
|
64
68
|
<Sidepanel className={classes.container} in={show} timeout={300}>
|
|
65
69
|
<ClickAwayListener onClickAway={e => closeSelector(e)}>
|
|
66
70
|
{/* this div is required since ClickAwayListener child element should be able to hold ref */}
|
|
67
|
-
<div>{show ? scopeSelectorContent : null}</div>
|
|
71
|
+
<div className={classes.scopeContainer}>{show ? scopeSelectorContent : null}</div>
|
|
68
72
|
</ClickAwayListener>
|
|
69
73
|
</Sidepanel>
|
|
70
74
|
);
|
|
@@ -2,8 +2,16 @@ 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, isVisible }) => {
|
|
6
|
-
const {
|
|
5
|
+
const FullPage = ({ path, config, location, match, modulePrependPath, isVisible = true }) => {
|
|
6
|
+
const {
|
|
7
|
+
component,
|
|
8
|
+
routerComponent = null,
|
|
9
|
+
componentProps,
|
|
10
|
+
pages = {},
|
|
11
|
+
segments,
|
|
12
|
+
subpages,
|
|
13
|
+
entityIdResolver,
|
|
14
|
+
} = config;
|
|
7
15
|
if (segments) {
|
|
8
16
|
return (
|
|
9
17
|
<SegmentPage
|
|
@@ -21,12 +29,12 @@ const FullPage = ({ path, config, location, match, modulePrependPath, isVisible
|
|
|
21
29
|
return (
|
|
22
30
|
<Page
|
|
23
31
|
path={path}
|
|
24
|
-
component={component}
|
|
32
|
+
component={component ?? routerComponent}
|
|
25
33
|
pages={pages}
|
|
26
34
|
subpages={subpages}
|
|
27
35
|
location={location}
|
|
28
36
|
match={match}
|
|
29
|
-
isVisible={isVisible}
|
|
37
|
+
isVisible={isVisible === true || routerComponent != null}
|
|
30
38
|
modulePrependPath={modulePrependPath}
|
|
31
39
|
/>
|
|
32
40
|
);
|
|
@@ -86,6 +86,30 @@ describe("Fullpage", () => {
|
|
|
86
86
|
<View2 />,
|
|
87
87
|
));
|
|
88
88
|
|
|
89
|
+
it("shows a page when there is a router component no matter how visible is set", () =>
|
|
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
|
+
routerComponent: View1,
|
|
101
|
+
pages: { "/stuff": { component: View2 } },
|
|
102
|
+
}}
|
|
103
|
+
location={{ location: true }}
|
|
104
|
+
match={{ match: true }}
|
|
105
|
+
isVisible={false}
|
|
106
|
+
/>
|
|
107
|
+
</TestWrapper>,
|
|
108
|
+
"when mounted",
|
|
109
|
+
"to satisfy",
|
|
110
|
+
<View2 />,
|
|
111
|
+
));
|
|
112
|
+
|
|
89
113
|
it("does not show a page when not visible", () =>
|
|
90
114
|
expect(
|
|
91
115
|
<TestWrapper
|
|
@@ -204,10 +204,14 @@ describe("ScopeBar", () => {
|
|
|
204
204
|
describe("Scope", () => {
|
|
205
205
|
let nodeState;
|
|
206
206
|
beforeEach(() => {
|
|
207
|
+
window.bypassDebounce = true;
|
|
208
|
+
|
|
207
209
|
nodeState = { foo: true, bar: false };
|
|
208
210
|
state = state.setIn(["view", "scopeSelector", "nodeState"], Immutable.fromJS(nodeState));
|
|
209
211
|
});
|
|
210
212
|
|
|
213
|
+
afterEach(() => delete window.bypassDebounce);
|
|
214
|
+
|
|
211
215
|
it("renders a scope bar, selector panel with handlers, and viewport", () => {
|
|
212
216
|
const scopes = [
|
|
213
217
|
{
|
|
@@ -46,8 +46,10 @@ export const namedLookupSelector = memoize((moduleName, lookupName) =>
|
|
|
46
46
|
);
|
|
47
47
|
|
|
48
48
|
export const namedLookupValuesSelector = memoize((moduleName, lookupName) =>
|
|
49
|
-
createSelector(namedLookupSelector(moduleName, lookupName), currentLocaleOrDefault, (
|
|
50
|
-
(
|
|
49
|
+
createSelector(namedLookupSelector(moduleName, lookupName), currentLocaleOrDefault, (lookup, locale) =>
|
|
50
|
+
(lookup.get("values") || Immutable.Map()).map(lookupValue =>
|
|
51
|
+
setTranslationWithFallbackField(locale, lookupValue, "name", "displayName"),
|
|
52
|
+
),
|
|
51
53
|
),
|
|
52
54
|
);
|
|
53
55
|
|
|
@@ -157,7 +159,8 @@ const definitionEntityAttributes = memoize((moduleName, entityName) =>
|
|
|
157
159
|
),
|
|
158
160
|
);
|
|
159
161
|
|
|
160
|
-
const filterIsBuiltInAttributes = isBuiltIn => attributes =>
|
|
162
|
+
const filterIsBuiltInAttributes = isBuiltIn => attributes =>
|
|
163
|
+
attributes.filter(a => a.get("isBuiltIn") === isBuiltIn).sortBy(x => x.get("displayOrder"));
|
|
161
164
|
|
|
162
165
|
export const definitionEntityCustomAttributesSelector = memoize((moduleName, entityName) =>
|
|
163
166
|
createSelector(definitionEntityAttributes(moduleName, entityName), filterIsBuiltInAttributes(false)),
|
|
@@ -204,11 +207,15 @@ export const groupedCustomAttributesDefinitionSelector = memoize((moduleName, en
|
|
|
204
207
|
})
|
|
205
208
|
.set(
|
|
206
209
|
"baseAttributes",
|
|
207
|
-
group
|
|
210
|
+
group
|
|
211
|
+
.filter(i => i.get("dataType") !== attributeDataType.entityReference)
|
|
212
|
+
.sortBy(x => x.get("displayOrder")),
|
|
208
213
|
)
|
|
209
214
|
.set(
|
|
210
215
|
"profileAttributes",
|
|
211
|
-
group
|
|
216
|
+
group
|
|
217
|
+
.filter(i => i.get("dataType") === attributeDataType.entityReference)
|
|
218
|
+
.sortBy(x => x.get("displayOrder")),
|
|
212
219
|
);
|
|
213
220
|
})
|
|
214
221
|
.sortBy(x => x.get("displayOrder")),
|
|
@@ -220,8 +227,12 @@ export const customAttributesDefinitionSelector = memoize((moduleName, profileEn
|
|
|
220
227
|
mappedDefinitionEntity(moduleName, profileEntityName),
|
|
221
228
|
customAttributesSelector(moduleName, profileEntityName),
|
|
222
229
|
(definition, attributes) => {
|
|
223
|
-
const profileAttributes = attributes
|
|
224
|
-
|
|
230
|
+
const profileAttributes = attributes
|
|
231
|
+
?.filter(a => a.get("dataType") === attributeDataType.entityReference)
|
|
232
|
+
.sortBy(x => x.get("displayOrder"));
|
|
233
|
+
const baseAttributes = attributes
|
|
234
|
+
?.filter(a => a.get("dataType") !== attributeDataType.entityReference)
|
|
235
|
+
.sortBy(x => x.get("displayOrder"));
|
|
225
236
|
return definition.set("baseAttributes", baseAttributes).set("profileAttributes", profileAttributes);
|
|
226
237
|
},
|
|
227
238
|
),
|