orc-shared 1.6.0-dev.1 → 1.6.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.
- package/dist/actions/globalErrorMessages.js +67 -0
- package/dist/actions/makeApiAction.js +1 -1
- package/dist/buildStore.js +3 -1
- package/dist/components/MaterialUI/DataDisplay/PredefinedElements/GlobalErrorMessages.js +134 -0
- package/dist/components/MaterialUI/DataDisplay/PredefinedElements/LookupDisplayValue.js +84 -0
- package/dist/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.js +2 -1
- package/dist/components/MaterialUI/DataDisplay/Table.js +2 -2
- package/dist/components/MaterialUI/Inputs/InputBase.js +97 -15
- package/dist/components/MaterialUI/Inputs/InputBaseProps.js +3 -1
- package/dist/components/MaterialUI/hocs/withDeferredPopper.js +1 -1
- package/dist/components/Routing/Page.js +4 -1
- package/dist/components/Routing/SegmentPage.js +4 -1
- package/dist/components/Routing/SubPage.js +11 -13
- package/dist/components/Scope/useScopeConfirmationModalState.js +1 -1
- package/dist/hooks/useDispatchWithErrorHandling.js +106 -0
- package/dist/hooks/useNotificationRequestState.js +2 -2
- package/dist/reducers/globalErrorMessages.js +79 -0
- package/dist/reducers/request.js +2 -1
- package/dist/reducers/scopes.js +3 -0
- package/dist/selectors/authentication.js +2 -2
- package/dist/selectors/globalErrorMessages.js +58 -0
- package/dist/selectors/metadata.js +2 -2
- package/dist/utils/buildUrl.js +1 -1
- package/dist/utils/responseProcessingHelper.js +87 -0
- package/package.json +7 -4
- package/src/actions/globalErrorMessages.js +12 -0
- package/src/actions/globalErrorMessages.test.js +21 -0
- package/src/buildStore.js +2 -0
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/GlobalErrorMessages.js +93 -0
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/GlobalErrorMessages.test.js +472 -0
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/LookupDisplayValue.js +18 -0
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/LookupDisplayValue.test.js +121 -0
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.js +2 -1
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.test.js +20 -0
- package/src/components/MaterialUI/Inputs/InputBase.js +97 -15
- package/src/components/MaterialUI/Inputs/InputBase.test.js +339 -3
- package/src/components/MaterialUI/Inputs/InputBaseProps.js +2 -0
- package/src/components/MaterialUI/Inputs/InputBaseProps.test.js +2 -0
- package/src/components/Routing/Page.js +12 -1
- package/src/components/Routing/SegmentPage.js +12 -1
- package/src/components/Routing/SubPage.js +4 -8
- package/src/components/Routing/SubPage.test.js +46 -0
- package/src/hooks/useDispatchWithErrorHandling.js +57 -0
- package/src/hooks/useDispatchWithErrorHandling.test.js +230 -0
- package/src/reducers/globalErrorMessages.js +25 -0
- package/src/reducers/globalErrorMessages.test.js +66 -0
- package/src/reducers/request.js +2 -1
- package/src/reducers/request.test.js +23 -0
- package/src/reducers/scopes.js +3 -0
- package/src/reducers/scopes.test.js +47 -0
- package/src/selectors/globalErrorMessages.js +11 -0
- package/src/selectors/globalErrorMessages.test.js +25 -0
- package/src/selectors/metadata.js +1 -1
- package/src/selectors/metadata.test.js +12 -0
- package/src/utils/buildUrl.js +1 -1
- package/src/utils/responseProcessingHelper.js +42 -0
- package/src/utils/responseProcessingHelper.test.js +218 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useDispatchWithErrorHandling } from "./useDispatchWithErrorHandling";
|
|
3
|
+
import sinon from "sinon";
|
|
4
|
+
import { mount } from "enzyme";
|
|
5
|
+
import { Provider } from "react-redux";
|
|
6
|
+
import Immutable from "immutable";
|
|
7
|
+
import { pushGlobalErrorMessage } from "../actions/globalErrorMessages";
|
|
8
|
+
|
|
9
|
+
const delay = () => new Promise(resolve => setTimeout(resolve, 10));
|
|
10
|
+
|
|
11
|
+
describe("useDispatchWithErrorHandling", () => {
|
|
12
|
+
let store, state, dispatchSpy;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
state = Immutable.fromJS({});
|
|
16
|
+
dispatchSpy = sinon.stub().named("dispatch");
|
|
17
|
+
|
|
18
|
+
store = {
|
|
19
|
+
subscribe: () => {},
|
|
20
|
+
dispatch: dispatchSpy,
|
|
21
|
+
getState: () => state,
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("Dispatches action just with specified parameters", () => {
|
|
26
|
+
dispatchSpy.resolves({});
|
|
27
|
+
|
|
28
|
+
const TestComp = () => {
|
|
29
|
+
const dispatch = useDispatchWithErrorHandling();
|
|
30
|
+
dispatch({
|
|
31
|
+
action: { type: "testing" },
|
|
32
|
+
errorTitle: "title",
|
|
33
|
+
errorDescription: "desc",
|
|
34
|
+
validationLookupModule: "order",
|
|
35
|
+
validationLookupName: "ValidationsOrderReturns",
|
|
36
|
+
});
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const component = (
|
|
41
|
+
<Provider store={store}>
|
|
42
|
+
<TestComp />
|
|
43
|
+
</Provider>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
mount(component);
|
|
47
|
+
|
|
48
|
+
expect(dispatchSpy.callCount, "to be", 1);
|
|
49
|
+
expect(dispatchSpy, "to have a call satisfying", { args: [{ type: "testing" }] });
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("does not push messages because data is null", () => {
|
|
53
|
+
dispatchSpy.resolves(null);
|
|
54
|
+
|
|
55
|
+
const TestComp = () => {
|
|
56
|
+
const dispatch = useDispatchWithErrorHandling();
|
|
57
|
+
dispatch({
|
|
58
|
+
action: { type: "testing" },
|
|
59
|
+
errorTitle: "title",
|
|
60
|
+
errorDescription: "desc",
|
|
61
|
+
validationLookupModule: "order",
|
|
62
|
+
validationLookupName: "ValidationsOrderReturns",
|
|
63
|
+
});
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const component = (
|
|
68
|
+
<Provider store={store}>
|
|
69
|
+
<TestComp />
|
|
70
|
+
</Provider>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
mount(component);
|
|
74
|
+
|
|
75
|
+
expect(dispatchSpy.callCount, "to be", 1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("does not push messages because data is an empty object", () => {
|
|
79
|
+
dispatchSpy.resolves({});
|
|
80
|
+
|
|
81
|
+
const TestComp = () => {
|
|
82
|
+
const dispatch = useDispatchWithErrorHandling();
|
|
83
|
+
dispatch({
|
|
84
|
+
action: { type: "testing" },
|
|
85
|
+
errorTitle: "title",
|
|
86
|
+
errorDescription: "desc",
|
|
87
|
+
validationLookupModule: "order",
|
|
88
|
+
validationLookupName: "ValidationsOrderReturns",
|
|
89
|
+
});
|
|
90
|
+
return null;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const component = (
|
|
94
|
+
<Provider store={store}>
|
|
95
|
+
<TestComp />
|
|
96
|
+
</Provider>
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
mount(component);
|
|
100
|
+
|
|
101
|
+
expect(dispatchSpy.callCount, "to be", 1);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("does not push messages because data is a response with error=false", () => {
|
|
105
|
+
dispatchSpy.resolves({ error: false });
|
|
106
|
+
|
|
107
|
+
const TestComp = () => {
|
|
108
|
+
const dispatch = useDispatchWithErrorHandling();
|
|
109
|
+
dispatch({
|
|
110
|
+
action: { type: "testing" },
|
|
111
|
+
errorTitle: "title",
|
|
112
|
+
errorDescription: "desc",
|
|
113
|
+
validationLookupModule: "order",
|
|
114
|
+
validationLookupName: "ValidationsOrderReturns",
|
|
115
|
+
});
|
|
116
|
+
return null;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const component = (
|
|
120
|
+
<Provider store={store}>
|
|
121
|
+
<TestComp />
|
|
122
|
+
</Provider>
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
mount(component);
|
|
126
|
+
|
|
127
|
+
expect(dispatchSpy.callCount, "to be", 1);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("dispatch new message with title and description because of empty msg list", () => {
|
|
131
|
+
dispatchSpy.resolves({
|
|
132
|
+
error: true,
|
|
133
|
+
payload: {
|
|
134
|
+
status: 500,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const TestComp = () => {
|
|
139
|
+
const dispatch = useDispatchWithErrorHandling();
|
|
140
|
+
dispatch({
|
|
141
|
+
action: { type: "testing" },
|
|
142
|
+
errorTitle: "title",
|
|
143
|
+
errorDescription: "desc",
|
|
144
|
+
validationLookupModule: "order",
|
|
145
|
+
validationLookupName: "ValidationsOrderReturns",
|
|
146
|
+
});
|
|
147
|
+
return null;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const component = (
|
|
151
|
+
<Provider store={store}>
|
|
152
|
+
<TestComp />
|
|
153
|
+
</Provider>
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
mount(component);
|
|
157
|
+
|
|
158
|
+
delay().then(() => {
|
|
159
|
+
expect(dispatchSpy.callCount, "to be", 2);
|
|
160
|
+
expect(dispatchSpy, "to have a call satisfying", {
|
|
161
|
+
args: [
|
|
162
|
+
pushGlobalErrorMessage({
|
|
163
|
+
title: "title",
|
|
164
|
+
description: "desc",
|
|
165
|
+
messages: [],
|
|
166
|
+
}),
|
|
167
|
+
],
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("dispatch new message with only title because msg list is filled", () => {
|
|
173
|
+
dispatchSpy.resolves({
|
|
174
|
+
error: true,
|
|
175
|
+
payload: {
|
|
176
|
+
status: 500,
|
|
177
|
+
response: {
|
|
178
|
+
errors: [
|
|
179
|
+
{
|
|
180
|
+
message: "msg",
|
|
181
|
+
lookupModule: "mod",
|
|
182
|
+
lookupName: "name",
|
|
183
|
+
lookupKey: "key",
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const TestComp = () => {
|
|
191
|
+
const dispatch = useDispatchWithErrorHandling();
|
|
192
|
+
dispatch({
|
|
193
|
+
action: { type: "testing" },
|
|
194
|
+
errorTitle: "title",
|
|
195
|
+
errorDescription: "desc",
|
|
196
|
+
validationLookupModule: "order",
|
|
197
|
+
validationLookupName: "ValidationsOrderReturns",
|
|
198
|
+
});
|
|
199
|
+
return null;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const component = (
|
|
203
|
+
<Provider store={store}>
|
|
204
|
+
<TestComp />
|
|
205
|
+
</Provider>
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
mount(component);
|
|
209
|
+
|
|
210
|
+
delay().then(() => {
|
|
211
|
+
expect(dispatchSpy.callCount, "to be", 2);
|
|
212
|
+
expect(dispatchSpy, "to have a call satisfying", {
|
|
213
|
+
args: [
|
|
214
|
+
pushGlobalErrorMessage({
|
|
215
|
+
title: "title",
|
|
216
|
+
description: null,
|
|
217
|
+
messages: [
|
|
218
|
+
{
|
|
219
|
+
message: "msg",
|
|
220
|
+
lookupModule: "mod",
|
|
221
|
+
lookupName: "name",
|
|
222
|
+
lookupKey: "key",
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
}),
|
|
226
|
+
],
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Immutable from "immutable";
|
|
2
|
+
import { POP_GLOBAL_ERROR_MESSAGE, PUSH_GLOBAL_ERROR_MESSAGE } from "../actions/globalErrorMessages";
|
|
3
|
+
|
|
4
|
+
const initialState = Immutable.fromJS({
|
|
5
|
+
dialog: {
|
|
6
|
+
errorMessages: [],
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const globalErrorMessages = (state = initialState, action) => {
|
|
11
|
+
switch (action.type) {
|
|
12
|
+
case PUSH_GLOBAL_ERROR_MESSAGE: {
|
|
13
|
+
const newMsgs = state.getIn(["dialog", "errorMessages"]).push(Immutable.fromJS(action.payload));
|
|
14
|
+
return state.setIn(["dialog", "errorMessages"], newMsgs);
|
|
15
|
+
}
|
|
16
|
+
case POP_GLOBAL_ERROR_MESSAGE: {
|
|
17
|
+
const newMsgs = state.getIn(["dialog", "errorMessages"]).shift();
|
|
18
|
+
return state.setIn(["dialog", "errorMessages"], newMsgs);
|
|
19
|
+
}
|
|
20
|
+
default:
|
|
21
|
+
return state;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default globalErrorMessages;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import Immutable from "immutable";
|
|
2
|
+
import reducer from "./globalErrorMessages";
|
|
3
|
+
import { popGlobalErrorMessage, pushGlobalErrorMessage } from "../actions/globalErrorMessages";
|
|
4
|
+
|
|
5
|
+
describe("Global error messages reducer", () => {
|
|
6
|
+
it("behaves as a reducer should", () =>
|
|
7
|
+
expect(reducer, "to be a reducer with initial state", {
|
|
8
|
+
dialog: {
|
|
9
|
+
errorMessages: [],
|
|
10
|
+
},
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
it("save new message to end of the list", () => {
|
|
14
|
+
const oldState = Immutable.fromJS({
|
|
15
|
+
dialog: {
|
|
16
|
+
errorMessages: [{ msg: "123" }],
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
const action = pushGlobalErrorMessage({ msg: "456" });
|
|
20
|
+
const newState = reducer(oldState, action);
|
|
21
|
+
expect(newState, "not to be", oldState).and(
|
|
22
|
+
"to equal",
|
|
23
|
+
Immutable.fromJS({
|
|
24
|
+
dialog: {
|
|
25
|
+
errorMessages: [{ msg: "123" }, { msg: "456" }],
|
|
26
|
+
},
|
|
27
|
+
}),
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("remove oldest message", () => {
|
|
32
|
+
const oldState = Immutable.fromJS({
|
|
33
|
+
dialog: {
|
|
34
|
+
errorMessages: [{ msg: "123" }, { msg: "456" }],
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
const action = popGlobalErrorMessage();
|
|
38
|
+
const newState = reducer(oldState, action);
|
|
39
|
+
expect(newState, "not to be", oldState).and(
|
|
40
|
+
"to equal",
|
|
41
|
+
Immutable.fromJS({
|
|
42
|
+
dialog: {
|
|
43
|
+
errorMessages: [{ msg: "456" }],
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("remove oldest message on an empty list", () => {
|
|
50
|
+
const oldState = Immutable.fromJS({
|
|
51
|
+
dialog: {
|
|
52
|
+
errorMessages: [],
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
const action = popGlobalErrorMessage();
|
|
56
|
+
const newState = reducer(oldState, action);
|
|
57
|
+
expect(newState, "to be", oldState).and(
|
|
58
|
+
"to equal",
|
|
59
|
+
Immutable.fromJS({
|
|
60
|
+
dialog: {
|
|
61
|
+
errorMessages: [],
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
});
|
package/src/reducers/request.js
CHANGED
|
@@ -24,7 +24,8 @@ const requestReducer = (state = initialState, action) => {
|
|
|
24
24
|
}
|
|
25
25
|
if (action.type.endsWith("_FAILURE")) {
|
|
26
26
|
const requestName = action.type.replace(/_FAILURE$/, "");
|
|
27
|
-
|
|
27
|
+
const status = safeGet(action, "payload", "status");
|
|
28
|
+
if (status === 403 || status === 401) {
|
|
28
29
|
return state.deleteIn(["actives", requestName]).set("logout", true);
|
|
29
30
|
} else {
|
|
30
31
|
return state.deleteIn(["actives", requestName]).set("error", Immutable.fromJS(action));
|
|
@@ -125,4 +125,27 @@ describe("Request reducer", () => {
|
|
|
125
125
|
}),
|
|
126
126
|
);
|
|
127
127
|
});
|
|
128
|
+
|
|
129
|
+
it("clears activity flag and sets login flag when a request fails with status 401", () => {
|
|
130
|
+
const oldState = Immutable.fromJS({
|
|
131
|
+
actives: {
|
|
132
|
+
SOME_FLAG: true,
|
|
133
|
+
TEST_THIS: true,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
const action = {
|
|
137
|
+
type: "TEST_THIS_FAILURE",
|
|
138
|
+
payload: { status: 401, message: "UnauthorizedAccessException" },
|
|
139
|
+
};
|
|
140
|
+
const newState = reducer(oldState, action);
|
|
141
|
+
expect(newState, "not to be", oldState).and(
|
|
142
|
+
"to equal",
|
|
143
|
+
Immutable.fromJS({
|
|
144
|
+
actives: {
|
|
145
|
+
SOME_FLAG: true,
|
|
146
|
+
},
|
|
147
|
+
[LOGOUT]: true,
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
});
|
|
128
151
|
});
|
package/src/reducers/scopes.js
CHANGED
|
@@ -10,6 +10,9 @@ const scopeReducer = (state = initialState, action) => {
|
|
|
10
10
|
case GET_SCOPES_SUCCESS: {
|
|
11
11
|
const loadedScopes = state.toJS();
|
|
12
12
|
const normalizedScopes = normalize(action.payload, scopeSchema);
|
|
13
|
+
if (action.meta && action.meta.reset) {
|
|
14
|
+
return Immutable.fromJS(normalizedScopes.entities.scopes);
|
|
15
|
+
}
|
|
13
16
|
|
|
14
17
|
if (Object.keys(loadedScopes).length > 0) {
|
|
15
18
|
const addedScope = {};
|
|
@@ -91,4 +91,51 @@ describe("scopes", () => {
|
|
|
91
91
|
}),
|
|
92
92
|
);
|
|
93
93
|
});
|
|
94
|
+
|
|
95
|
+
it("reset option should override previous state", () => {
|
|
96
|
+
const oldState = Immutable.Map({
|
|
97
|
+
Global: {
|
|
98
|
+
id: "Global",
|
|
99
|
+
isAuthorizedScope: true,
|
|
100
|
+
children: ["Child1", "Child2", "Child3"],
|
|
101
|
+
scopePath: ["Global"],
|
|
102
|
+
},
|
|
103
|
+
Child1: { id: "Child1", isAuthorizedScope: true, scopePath: ["Global", "Child1"], children: [] },
|
|
104
|
+
Child2: { id: "Child2", isAuthorizedScope: false, scopePath: ["Global", "Child2"], children: [] },
|
|
105
|
+
ChildOld: { id: "ChildOld", isAuthorizedScope: false, scopePath: ["Global", "ChildOld"], children: [] },
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const action = {
|
|
109
|
+
type: GET_SCOPES_SUCCESS,
|
|
110
|
+
payload: {
|
|
111
|
+
id: "Global",
|
|
112
|
+
isAuthorizedScope: true,
|
|
113
|
+
children: [
|
|
114
|
+
{ id: "Child1", isAuthorizedScope: false, children: [], parentScopeId: "Global" },
|
|
115
|
+
{ id: "Child2", isAuthorizedScope: true, children: [], parentScopeId: "Global" },
|
|
116
|
+
{ id: "Child3", isAuthorizedScope: false, children: [], parentScopeId: "Global" },
|
|
117
|
+
{ id: "Child4", isAuthorizedScope: true, children: [], parentScopeId: "Global" },
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
meta: {
|
|
121
|
+
reset: true,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
const newState = reducer(oldState, action);
|
|
125
|
+
return expect(newState, "not to be", oldState).and(
|
|
126
|
+
"to satisfy",
|
|
127
|
+
Immutable.fromJS({
|
|
128
|
+
Global: {
|
|
129
|
+
id: "Global",
|
|
130
|
+
isAuthorizedScope: true,
|
|
131
|
+
children: ["Child1", "Child2", "Child3", "Child4"],
|
|
132
|
+
scopePath: ["Global"],
|
|
133
|
+
},
|
|
134
|
+
Child1: { id: "Child1", isAuthorizedScope: false, scopePath: ["Global", "Child1"], children: [] },
|
|
135
|
+
Child2: { id: "Child2", isAuthorizedScope: true, scopePath: ["Global", "Child2"], children: [] },
|
|
136
|
+
Child3: { id: "Child3", isAuthorizedScope: false, scopePath: ["Global", "Child3"], children: [] },
|
|
137
|
+
Child4: { id: "Child4", isAuthorizedScope: true, scopePath: ["Global", "Child4"], children: [] },
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
});
|
|
94
141
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createSelector } from "reselect";
|
|
2
|
+
|
|
3
|
+
const globalMsgData = state => state.get("globalErrorMessages");
|
|
4
|
+
|
|
5
|
+
export const firstDialogErrorMessageSelector = createSelector(globalMsgData, data => {
|
|
6
|
+
const msgs = data.getIn(["dialog", "errorMessages"]);
|
|
7
|
+
if (msgs.size === 0) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return msgs.first().toJS();
|
|
11
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Immutable from "immutable";
|
|
2
|
+
import { firstDialogErrorMessageSelector } from "./globalErrorMessages";
|
|
3
|
+
|
|
4
|
+
describe("firstDialogErrorMessageSelector", () => {
|
|
5
|
+
let state;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
state = Immutable.fromJS({
|
|
8
|
+
globalErrorMessages: {
|
|
9
|
+
dialog: {
|
|
10
|
+
errorMessages: [{ msg: "123" }, { msg: "456" }],
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
view: {},
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("gets the first message", () => {
|
|
18
|
+
expect(firstDialogErrorMessageSelector, "called with", [state], "to satisfy", { msg: "123" });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("gets the first message on an empty list", () => {
|
|
22
|
+
state = state.setIn(["globalErrorMessages", "dialog", "errorMessages"], Immutable.fromJS([]));
|
|
23
|
+
expect(firstDialogErrorMessageSelector, "called with", [state], "to satisfy", null);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -30,7 +30,7 @@ export const mappedLookupsListSelector = memoize(moduleName =>
|
|
|
30
30
|
);
|
|
31
31
|
|
|
32
32
|
const lookupValuesSelector = memoize((moduleName, lookupName) =>
|
|
33
|
-
createSelector(lookups, lookups => lookups.getIn([moduleName, "index", lookupName]) || Immutable.Map()),
|
|
33
|
+
createSelector(lookups, lookups => lookups.getIn([moduleName.toLowerCase(), "index", lookupName]) || Immutable.Map()),
|
|
34
34
|
);
|
|
35
35
|
|
|
36
36
|
export const lookupByNameSelector = memoize((moduleName, lookupName) =>
|
|
@@ -394,6 +394,18 @@ describe("namedLookupValuesSelector", () => {
|
|
|
394
394
|
"Annulla per motivo 1",
|
|
395
395
|
);
|
|
396
396
|
});
|
|
397
|
+
|
|
398
|
+
it("retrieves localized values with an uppercase module", () => {
|
|
399
|
+
expect(
|
|
400
|
+
namedLookupLocalizedSelector,
|
|
401
|
+
"when called with",
|
|
402
|
+
["ORDER", "CanceledStatusReasons", "CanceledReason1"],
|
|
403
|
+
"when called with",
|
|
404
|
+
[state],
|
|
405
|
+
"to satisfy",
|
|
406
|
+
"Annulla per motivo 1",
|
|
407
|
+
);
|
|
408
|
+
});
|
|
397
409
|
});
|
|
398
410
|
|
|
399
411
|
describe("selectCurrentLookupDetails", () => {
|
package/src/utils/buildUrl.js
CHANGED
|
@@ -21,7 +21,7 @@ export const loadConfig = () =>
|
|
|
21
21
|
.catch(() => {
|
|
22
22
|
console.warn("Failed to load config.json, falling back to dev defaults");
|
|
23
23
|
return {
|
|
24
|
-
serviceApiUrl: "https://
|
|
24
|
+
serviceApiUrl: "https://occ-dev-ocs-cm.develop.orckestra.cloud:443/api",
|
|
25
25
|
};
|
|
26
26
|
})
|
|
27
27
|
.then(config => {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const extractStandardErrorMessagesFromResponse = (response, validationLookupModule, validationLookupName) => {
|
|
2
|
+
let hasErrors = false;
|
|
3
|
+
const messages = [];
|
|
4
|
+
|
|
5
|
+
if (response?.error) {
|
|
6
|
+
hasErrors = true;
|
|
7
|
+
|
|
8
|
+
if (response.payload?.status === 422) {
|
|
9
|
+
if (response.payload?.response?.failures) {
|
|
10
|
+
// uses structure from our .Net ValidationFailuresExceptionHandler
|
|
11
|
+
response.payload.response.failures.forEach(failure => {
|
|
12
|
+
if (failure.errorCode) {
|
|
13
|
+
messages.push({
|
|
14
|
+
message: failure.errorMessage,
|
|
15
|
+
lookupModule: validationLookupModule,
|
|
16
|
+
lookupName: validationLookupName,
|
|
17
|
+
lookupKey: failure.errorCode,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
} else if (response.payload?.status === 500) {
|
|
23
|
+
if (response.payload?.response?.errors) {
|
|
24
|
+
// uses structure from our .Net OrckestraExceptionErrorHandler
|
|
25
|
+
response.payload.response.errors.forEach(err => {
|
|
26
|
+
messages.push({
|
|
27
|
+
message: err.message,
|
|
28
|
+
lookupModule: err.lookupModule,
|
|
29
|
+
lookupName: err.lookupName,
|
|
30
|
+
lookupKey: err.lookupKey,
|
|
31
|
+
lookupReplacementValues: err.lookupReplacementValues,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
hasErrors,
|
|
40
|
+
messages,
|
|
41
|
+
};
|
|
42
|
+
};
|