orc-shared 5.7.0-dev.0 → 5.7.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/components/MaterialUI/DataDisplay/Modal.js +3 -3
- package/dist/components/MaterialUI/DataDisplay/TransferList.js +2 -3
- package/dist/components/MaterialUI/Inputs/Checkbox.js +3 -4
- package/dist/components/MaterialUI/Inputs/CheckboxGroup.js +5 -6
- package/dist/components/MaterialUI/Inputs/InputBase.js +11 -0
- package/dist/components/MaterialUI/Inputs/Select.js +1 -2
- package/dist/components/MaterialUI/Inputs/StandaloneRadio.js +2 -3
- package/dist/components/MaterialUI/Inputs/createInput.js +3 -4
- package/dist/components/MaterialUI/muiThemes.js +10 -11
- package/dist/components/Routing/SubPage.js +5 -4
- package/dist/constants.js +53 -1
- package/dist/hocs/withToggle.js +1 -2
- package/dist/hooks/useDispatchWithErrorHandling.js +24 -9
- package/dist/reducers/authentication.js +3 -0
- package/dist/sharedMessages.js +8 -0
- package/dist/utils/modelValidationHelper.js +5 -6
- package/dist/utils/propertyBagHelper.js +265 -0
- package/dist/utils/responseProcessingHelper.js +17 -3
- package/package.json +1 -1
- package/src/components/MaterialUI/Inputs/InputBase.js +18 -0
- package/src/components/MaterialUI/Inputs/InputBase.test.js +156 -0
- package/src/components/Routing/SubPage.js +6 -5
- package/src/constants.js +48 -0
- package/src/hooks/useDispatchWithErrorHandling.js +16 -2
- package/src/hooks/useDispatchWithErrorHandling.test.js +15 -13
- package/src/reducers/authentication.js +5 -0
- package/src/reducers/authentication.test.js +81 -0
- package/src/sharedMessages.js +8 -0
- package/src/translations/en-US.json +2 -0
- package/src/translations/fr-CA.json +2 -0
- package/src/utils/propertyBagHelper.js +239 -0
- package/src/utils/propertyBagHelper.test.js +709 -0
- package/src/utils/responseProcessingHelper.js +28 -3
- package/src/utils/responseProcessingHelper.test.js +256 -12
|
@@ -2,11 +2,13 @@ import React from "react";
|
|
|
2
2
|
import { useDispatchWithErrorHandling } from "./useDispatchWithErrorHandling";
|
|
3
3
|
import sinon from "sinon";
|
|
4
4
|
import { mount } from "enzyme";
|
|
5
|
-
import { Provider } from "react-redux";
|
|
6
5
|
import Immutable from "immutable";
|
|
7
6
|
import { pushGlobalErrorMessage } from "../actions/globalErrorMessages";
|
|
7
|
+
import { extractMessages, TestWrapper } from "../utils/testUtils";
|
|
8
|
+
import sharedMessages from "../sharedMessages";
|
|
8
9
|
|
|
9
10
|
const delay = () => new Promise(resolve => setTimeout(resolve, 10));
|
|
11
|
+
const messages = extractMessages(sharedMessages);
|
|
10
12
|
|
|
11
13
|
describe("useDispatchWithErrorHandling", () => {
|
|
12
14
|
let store, state, dispatchSpy;
|
|
@@ -38,9 +40,9 @@ describe("useDispatchWithErrorHandling", () => {
|
|
|
38
40
|
};
|
|
39
41
|
|
|
40
42
|
const component = (
|
|
41
|
-
<
|
|
43
|
+
<TestWrapper provider={{ store }} intlProvider={{ messages }}>
|
|
42
44
|
<TestComp />
|
|
43
|
-
</
|
|
45
|
+
</TestWrapper>
|
|
44
46
|
);
|
|
45
47
|
|
|
46
48
|
mount(component);
|
|
@@ -65,9 +67,9 @@ describe("useDispatchWithErrorHandling", () => {
|
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
const component = (
|
|
68
|
-
<
|
|
70
|
+
<TestWrapper provider={{ store }} intlProvider={{ messages }}>
|
|
69
71
|
<TestComp />
|
|
70
|
-
</
|
|
72
|
+
</TestWrapper>
|
|
71
73
|
);
|
|
72
74
|
|
|
73
75
|
mount(component);
|
|
@@ -91,9 +93,9 @@ describe("useDispatchWithErrorHandling", () => {
|
|
|
91
93
|
};
|
|
92
94
|
|
|
93
95
|
const component = (
|
|
94
|
-
<
|
|
96
|
+
<TestWrapper provider={{ store }} intlProvider={{ messages }}>
|
|
95
97
|
<TestComp />
|
|
96
|
-
</
|
|
98
|
+
</TestWrapper>
|
|
97
99
|
);
|
|
98
100
|
|
|
99
101
|
mount(component);
|
|
@@ -117,9 +119,9 @@ describe("useDispatchWithErrorHandling", () => {
|
|
|
117
119
|
};
|
|
118
120
|
|
|
119
121
|
const component = (
|
|
120
|
-
<
|
|
122
|
+
<TestWrapper provider={{ store }} intlProvider={{ messages }}>
|
|
121
123
|
<TestComp />
|
|
122
|
-
</
|
|
124
|
+
</TestWrapper>
|
|
123
125
|
);
|
|
124
126
|
|
|
125
127
|
mount(component);
|
|
@@ -148,9 +150,9 @@ describe("useDispatchWithErrorHandling", () => {
|
|
|
148
150
|
};
|
|
149
151
|
|
|
150
152
|
const component = (
|
|
151
|
-
<
|
|
153
|
+
<TestWrapper provider={{ store }} intlProvider={{ messages }}>
|
|
152
154
|
<TestComp />
|
|
153
|
-
</
|
|
155
|
+
</TestWrapper>
|
|
154
156
|
);
|
|
155
157
|
|
|
156
158
|
mount(component);
|
|
@@ -200,9 +202,9 @@ describe("useDispatchWithErrorHandling", () => {
|
|
|
200
202
|
};
|
|
201
203
|
|
|
202
204
|
const component = (
|
|
203
|
-
<
|
|
205
|
+
<TestWrapper provider={{ store }} intlProvider={{ messages }}>
|
|
204
206
|
<TestComp />
|
|
205
|
-
</
|
|
207
|
+
</TestWrapper>
|
|
206
208
|
);
|
|
207
209
|
|
|
208
210
|
mount(component);
|
|
@@ -14,6 +14,11 @@ const authenticationReducer = (state = initialState, action) => {
|
|
|
14
14
|
s.set("upn", action.payload.upn);
|
|
15
15
|
s.set("name", action.payload.name);
|
|
16
16
|
const claims = action.payload.rolesClaimsValues;
|
|
17
|
+
|
|
18
|
+
if (action.meta && action.meta.overrideClaims) {
|
|
19
|
+
s.set("rolesClaimsValues", Immutable.fromJS({}));
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
claims.forEach(claim => {
|
|
18
23
|
const [app, scope, role] = claim.split("/");
|
|
19
24
|
s.setIn(["rolesClaimsValues", app, scope, role], true);
|
|
@@ -81,6 +81,87 @@ describe("authentication", () => {
|
|
|
81
81
|
});
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
+
describe("storing authentication with override", () => {
|
|
85
|
+
it("clears existing roles and claims if override is true", () => {
|
|
86
|
+
const oldState = Immutable.fromJS({
|
|
87
|
+
upn: "oldupn",
|
|
88
|
+
name: "oldname",
|
|
89
|
+
rolesClaimsValues: {
|
|
90
|
+
Customer: { "*": { Reader: true } },
|
|
91
|
+
Generic: { "*": { Reader: true } },
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
const action = {
|
|
95
|
+
type: GET_AUTHENTICATION_PROFILE_SUCCESS,
|
|
96
|
+
payload: {
|
|
97
|
+
upn: "newupn",
|
|
98
|
+
name: "newname",
|
|
99
|
+
rolesClaimsValues: ["Setting/*/Reader", "Tenant/*/Reader"],
|
|
100
|
+
},
|
|
101
|
+
meta: { overrideClaims: true },
|
|
102
|
+
};
|
|
103
|
+
const newState = reducer(oldState, action);
|
|
104
|
+
return expect(newState, "to have value at", ["rolesClaimsValues"], Immutable.fromJS({
|
|
105
|
+
Setting: { "*": { Reader: true } },
|
|
106
|
+
Tenant: { "*": { Reader: true } },
|
|
107
|
+
}));
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("does not clear existing roles and claims if override is false", () => {
|
|
111
|
+
const oldState = Immutable.fromJS({
|
|
112
|
+
upn: "oldupn",
|
|
113
|
+
name: "oldname",
|
|
114
|
+
rolesClaimsValues: {
|
|
115
|
+
Customer: { "*": { Reader: true } },
|
|
116
|
+
Generic: { "*": { Reader: true } },
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const action = {
|
|
120
|
+
type: GET_AUTHENTICATION_PROFILE_SUCCESS,
|
|
121
|
+
payload: {
|
|
122
|
+
upn: "newupn",
|
|
123
|
+
name: "newname",
|
|
124
|
+
rolesClaimsValues: ["Setting/*/Reader", "Tenant/*/Reader"],
|
|
125
|
+
},
|
|
126
|
+
meta: { overrideClaims: false },
|
|
127
|
+
};
|
|
128
|
+
const newState = reducer(oldState, action);
|
|
129
|
+
return expect(newState, "to have value at", ["rolesClaimsValues"], Immutable.fromJS({
|
|
130
|
+
Customer: { "*": { Reader: true } },
|
|
131
|
+
Generic: { "*": { Reader: true } },
|
|
132
|
+
Setting: { "*": { Reader: true } },
|
|
133
|
+
Tenant: { "*": { Reader: true } },
|
|
134
|
+
}));
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("does not clear existing roles and claims if override is not provided", () => {
|
|
138
|
+
const oldState = Immutable.fromJS({
|
|
139
|
+
upn: "oldupn",
|
|
140
|
+
name: "oldname",
|
|
141
|
+
rolesClaimsValues: {
|
|
142
|
+
Customer: { "*": { Reader: true } },
|
|
143
|
+
Generic: { "*": { Reader: true } },
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
const action = {
|
|
147
|
+
type: GET_AUTHENTICATION_PROFILE_SUCCESS,
|
|
148
|
+
payload: {
|
|
149
|
+
upn: "newupn",
|
|
150
|
+
name: "newname",
|
|
151
|
+
rolesClaimsValues: ["Setting/*/Reader", "Tenant/*/Reader"],
|
|
152
|
+
},
|
|
153
|
+
// meta: { overrideClaims: false }, // Intentionally omitted
|
|
154
|
+
};
|
|
155
|
+
const newState = reducer(oldState, action);
|
|
156
|
+
return expect(newState, "to have value at", ["rolesClaimsValues"], Immutable.fromJS({
|
|
157
|
+
Customer: { "*": { Reader: true } },
|
|
158
|
+
Generic: { "*": { Reader: true } },
|
|
159
|
+
Setting: { "*": { Reader: true } },
|
|
160
|
+
Tenant: { "*": { Reader: true } },
|
|
161
|
+
}));
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
84
165
|
describe("sign out", () => {
|
|
85
166
|
const { location } = window;
|
|
86
167
|
beforeAll(() => {
|
package/src/sharedMessages.js
CHANGED
|
@@ -271,6 +271,14 @@ const sharedMessages = defineMessages({
|
|
|
271
271
|
id: "orc-shared.taskLogs",
|
|
272
272
|
defaultMessage: "Logs",
|
|
273
273
|
},
|
|
274
|
+
valueTypeWrapperTrue: {
|
|
275
|
+
id: "orc-shared.valueTypeWrapperTrue",
|
|
276
|
+
defaultMessage: "True",
|
|
277
|
+
},
|
|
278
|
+
valueTypeWrapperFalse: {
|
|
279
|
+
id: "orc-shared.valueTypeWrapperFalse",
|
|
280
|
+
defaultMessage: "False",
|
|
281
|
+
},
|
|
274
282
|
});
|
|
275
283
|
|
|
276
284
|
export default sharedMessages;
|
|
@@ -65,5 +65,7 @@
|
|
|
65
65
|
"orc-shared.taskStatus": "Status",
|
|
66
66
|
"orc-shared.unsavedChanges": "This entity has unsaved changes. All changes will be lost.\n\nAre you sure you want to close it?",
|
|
67
67
|
"orc-shared.valueName": "Value Name",
|
|
68
|
+
"orc-shared.valueTypeWrapperFalse": "False",
|
|
69
|
+
"orc-shared.valueTypeWrapperTrue": "True",
|
|
68
70
|
"orc-shared.yes": "Yes"
|
|
69
71
|
}
|
|
@@ -65,5 +65,7 @@
|
|
|
65
65
|
"orc-shared.taskStatus": "Statut",
|
|
66
66
|
"orc-shared.unsavedChanges": "Ce dossier contient des modifications qui ne sont sauvegardées. Si vous quittez, les modifications seront perdues.\n\nVoulez vous vraiment quitter?",
|
|
67
67
|
"orc-shared.valueName": "Nom de la valeur",
|
|
68
|
+
"orc-shared.valueTypeWrapperFalse": "Faux",
|
|
69
|
+
"orc-shared.valueTypeWrapperTrue": "Vrai",
|
|
68
70
|
"orc-shared.yes": "Oui"
|
|
69
71
|
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import {
|
|
2
|
+
attributeDataType,
|
|
3
|
+
dotNetDataTypes,
|
|
4
|
+
jsonCargoType,
|
|
5
|
+
propertyBagPrimitiveDataType,
|
|
6
|
+
serializationTypeKey,
|
|
7
|
+
} from "../constants";
|
|
8
|
+
import { isObject } from "./propertyValidator";
|
|
9
|
+
import sharedMessages from "../sharedMessages";
|
|
10
|
+
import { parseGuid } from "./parseHelper";
|
|
11
|
+
|
|
12
|
+
export const customDataType = {
|
|
13
|
+
money: "Money",
|
|
14
|
+
priceTieredRateTable: "PriceTieredRateTable",
|
|
15
|
+
quantityTieredRateTable: "QuantityTieredRateTable",
|
|
16
|
+
password: "Password",
|
|
17
|
+
carrierProviderSelector: "CarrierProviderSelector",
|
|
18
|
+
routingProviderSelector: "RoutingProviderSelector",
|
|
19
|
+
multipleCarrierProvidersSelector: "MultipleCarrierProvidersSelector",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const tieredAttributeTypes = [customDataType.priceTieredRateTable, customDataType.quantityTieredRateTable];
|
|
23
|
+
|
|
24
|
+
export const isTieredAttribute = attribute => tieredAttributeTypes.includes(attribute.customDataType);
|
|
25
|
+
|
|
26
|
+
const buildValueOfType = cargoType => {
|
|
27
|
+
return `ValueOf${cargoType}`;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const buildValueContainerOfType = dotNetType => {
|
|
31
|
+
return `Orckestra.Overture.Entities.ValueContainer\`1[[${dotNetType}, mscorlib]], Orckestra.Overture.Entities`;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const createJsonCargo = (cargoType, value) => {
|
|
35
|
+
return {
|
|
36
|
+
__type: buildValueOfType(cargoType),
|
|
37
|
+
value: value,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const createTieredTableJsonCargo = tiers => {
|
|
42
|
+
return {
|
|
43
|
+
__type: "Orckestra.Overture.Entities.Orders.TieredRateTable, Orckestra.Overture.Entities",
|
|
44
|
+
tiers: tiers.filter(tier => (tier?.min ?? "") !== ""),
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const toJsonCargo = (attribute, value) => {
|
|
49
|
+
switch (attribute.dataType) {
|
|
50
|
+
case attributeDataType.text:
|
|
51
|
+
case attributeDataType.lookup:
|
|
52
|
+
return value;
|
|
53
|
+
|
|
54
|
+
case attributeDataType.boolean:
|
|
55
|
+
return createJsonCargo(jsonCargoType.boolean, value);
|
|
56
|
+
|
|
57
|
+
case attributeDataType.integer:
|
|
58
|
+
return createJsonCargo(jsonCargoType.integer, Number(formatNumber(value, 0)));
|
|
59
|
+
|
|
60
|
+
case attributeDataType.decimal:
|
|
61
|
+
return createJsonCargo(jsonCargoType.double, Number(value));
|
|
62
|
+
|
|
63
|
+
case attributeDataType.dateTime:
|
|
64
|
+
return createJsonCargo(jsonCargoType.dateTime, value);
|
|
65
|
+
|
|
66
|
+
case attributeDataType.customType:
|
|
67
|
+
switch (attribute.customDataType) {
|
|
68
|
+
case customDataType.money:
|
|
69
|
+
return createJsonCargo(jsonCargoType.double, Number(formatNumber(value, 2)));
|
|
70
|
+
case customDataType.priceTieredRateTable:
|
|
71
|
+
case customDataType.quantityTieredRateTable:
|
|
72
|
+
return createTieredTableJsonCargo(value);
|
|
73
|
+
case customDataType.password:
|
|
74
|
+
case customDataType.carrierProviderSelector: // To be properly handled when user story 61801 will be addressed
|
|
75
|
+
case customDataType.routingProviderSelector: // To be properly handled when user story 61801 will be addressed
|
|
76
|
+
case customDataType.multipleCarrierProvidersSelector: // To be properly handled when user story 61801 will be addressed
|
|
77
|
+
return value;
|
|
78
|
+
default:
|
|
79
|
+
throw new Error(`toJsonCargo: attribute.customDataType ${attribute.customDataType} is not implemented`);
|
|
80
|
+
}
|
|
81
|
+
case attributeDataType.entityReference:
|
|
82
|
+
return createJsonCargo(jsonCargoType.entityReferences, value);
|
|
83
|
+
default:
|
|
84
|
+
throw new Error(`toJsonCargo: attribute.dataType ${attribute.dataType} is not implemented`);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const dataTypesChecker = {
|
|
89
|
+
booleanDataTypes: [
|
|
90
|
+
buildValueOfType(propertyBagPrimitiveDataType.boolean),
|
|
91
|
+
buildValueContainerOfType(dotNetDataTypes.boolean),
|
|
92
|
+
],
|
|
93
|
+
integerDataTypes: [
|
|
94
|
+
buildValueOfType(propertyBagPrimitiveDataType.byte),
|
|
95
|
+
buildValueContainerOfType(dotNetDataTypes.byte),
|
|
96
|
+
buildValueOfType(propertyBagPrimitiveDataType.sbyte),
|
|
97
|
+
buildValueContainerOfType(dotNetDataTypes.sbyte),
|
|
98
|
+
buildValueOfType(propertyBagPrimitiveDataType.int16),
|
|
99
|
+
buildValueContainerOfType(dotNetDataTypes.int16),
|
|
100
|
+
buildValueOfType(propertyBagPrimitiveDataType.uint16),
|
|
101
|
+
buildValueContainerOfType(dotNetDataTypes.uint16),
|
|
102
|
+
buildValueOfType(propertyBagPrimitiveDataType.int32),
|
|
103
|
+
buildValueContainerOfType(dotNetDataTypes.int32),
|
|
104
|
+
buildValueOfType(propertyBagPrimitiveDataType.uint32),
|
|
105
|
+
buildValueContainerOfType(dotNetDataTypes.uint32),
|
|
106
|
+
buildValueOfType(propertyBagPrimitiveDataType.int64),
|
|
107
|
+
buildValueContainerOfType(dotNetDataTypes.int64),
|
|
108
|
+
buildValueOfType(propertyBagPrimitiveDataType.uint64),
|
|
109
|
+
buildValueContainerOfType(dotNetDataTypes.uint64),
|
|
110
|
+
],
|
|
111
|
+
textDataTypes: [
|
|
112
|
+
buildValueOfType(propertyBagPrimitiveDataType.char),
|
|
113
|
+
buildValueContainerOfType(dotNetDataTypes.char),
|
|
114
|
+
buildValueOfType(propertyBagPrimitiveDataType.string),
|
|
115
|
+
buildValueContainerOfType(dotNetDataTypes.string),
|
|
116
|
+
],
|
|
117
|
+
decimalDataTypes: [
|
|
118
|
+
buildValueOfType(propertyBagPrimitiveDataType.single),
|
|
119
|
+
buildValueContainerOfType(dotNetDataTypes.single),
|
|
120
|
+
buildValueOfType(propertyBagPrimitiveDataType.double),
|
|
121
|
+
buildValueContainerOfType(dotNetDataTypes.double),
|
|
122
|
+
buildValueOfType(propertyBagPrimitiveDataType.decimal),
|
|
123
|
+
buildValueContainerOfType(dotNetDataTypes.decimal),
|
|
124
|
+
],
|
|
125
|
+
dateTimeDataTypes: [
|
|
126
|
+
buildValueOfType(propertyBagPrimitiveDataType.dateTime),
|
|
127
|
+
buildValueContainerOfType(dotNetDataTypes.dateTime),
|
|
128
|
+
],
|
|
129
|
+
guidDataTypes: [buildValueOfType(propertyBagPrimitiveDataType.guid), buildValueContainerOfType(dotNetDataTypes.guid)],
|
|
130
|
+
|
|
131
|
+
isBoolean: type => dataTypesChecker.booleanDataTypes.includes(type),
|
|
132
|
+
isInteger: type => dataTypesChecker.integerDataTypes.includes(type),
|
|
133
|
+
isText: type => dataTypesChecker.textDataTypes.includes(type),
|
|
134
|
+
isDecimal: type => dataTypesChecker.decimalDataTypes.includes(type),
|
|
135
|
+
isDateTime: type => dataTypesChecker.dateTimeDataTypes.includes(type),
|
|
136
|
+
isGuid: type => dataTypesChecker.guidDataTypes.includes(type),
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export const getPropertyBagFormattedPrimitiveValue = (propertyBagValue, formatMessage, formatDate, formatTime) => {
|
|
140
|
+
if (propertyBagValue === null || propertyBagValue === undefined || !isObject(propertyBagValue)) {
|
|
141
|
+
return propertyBagValue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (propertyBagValue.value === null || propertyBagValue.value === undefined) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (dataTypesChecker.isBoolean(propertyBagValue[serializationTypeKey])) {
|
|
149
|
+
return Boolean(propertyBagValue.value)
|
|
150
|
+
? formatMessage(sharedMessages.valueTypeWrapperTrue)
|
|
151
|
+
: formatMessage(sharedMessages.valueTypeWrapperFalse);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (dataTypesChecker.isInteger(propertyBagValue[serializationTypeKey])) {
|
|
155
|
+
return formatNumber(propertyBagValue.value, 0);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (dataTypesChecker.isText(propertyBagValue[serializationTypeKey])) {
|
|
159
|
+
return propertyBagValue.value.toString();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (dataTypesChecker.isDecimal(propertyBagValue[serializationTypeKey])) {
|
|
163
|
+
return formatNumber(propertyBagValue.value, 2);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (dataTypesChecker.isDateTime(propertyBagValue[serializationTypeKey])) {
|
|
167
|
+
return `${formatDate(propertyBagValue.value)} ${formatTime(propertyBagValue.value)}`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (dataTypesChecker.isGuid(propertyBagValue[serializationTypeKey])) {
|
|
171
|
+
return parseGuid(propertyBagValue.value);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// we ignore other data types since we have no way to format them
|
|
175
|
+
return null;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export const formatNumber = (value, precision) => Number(value).toFixed(precision);
|
|
179
|
+
|
|
180
|
+
export const fixPropertyBagModifiedModel = (model, ...fields) => {
|
|
181
|
+
const fixProfileOperations = model => {
|
|
182
|
+
if (model.hasOwnProperty("profileOperations")) {
|
|
183
|
+
let { profilesToAdd, profilesToUpdate } = model.profileOperations;
|
|
184
|
+
if (profilesToAdd) {
|
|
185
|
+
const items = Array.isArray(profilesToAdd) ? profilesToAdd : Object.values(profilesToAdd);
|
|
186
|
+
items.forEach(pr => {
|
|
187
|
+
fixPropertyBagEmptyValues(pr.propertyBag);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (profilesToUpdate) {
|
|
191
|
+
const items = Array.isArray(profilesToUpdate) ? profilesToUpdate : Object.values(profilesToUpdate);
|
|
192
|
+
items.forEach(pr => {
|
|
193
|
+
fixPropertyBagEmptyValues(pr.propertyBag);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
fixPropertyBagEmptyValues(model.propertyBag);
|
|
200
|
+
fixProfileOperations(model);
|
|
201
|
+
|
|
202
|
+
fields.forEach(field => {
|
|
203
|
+
let fieldValue = model[field]?.value;
|
|
204
|
+
if (!fieldValue) return;
|
|
205
|
+
if (Array.isArray(fieldValue)) {
|
|
206
|
+
fieldValue.forEach(fieldItem => {
|
|
207
|
+
fixPropertyBagEmptyValues(fieldItem.propertyBag);
|
|
208
|
+
fixProfileOperations(fieldItem);
|
|
209
|
+
});
|
|
210
|
+
} else {
|
|
211
|
+
fixPropertyBagEmptyValues(fieldValue.propertyBag);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export const fixPropertyBagEmptyValues = propertyBag => {
|
|
217
|
+
if (!propertyBag) return;
|
|
218
|
+
//we need to pass null to backend to remove attribute instead of empty string
|
|
219
|
+
//in case if attribute has validation for min length and when we will pass empty string, then we will get error from platform
|
|
220
|
+
//in case if DateTime attribute has empty value Backend will transform it to some '01/01/1900' date, so we need to pass null
|
|
221
|
+
const modifiedFields = Object.keys(propertyBag);
|
|
222
|
+
modifiedFields.forEach(propertyName => {
|
|
223
|
+
let property = propertyBag[propertyName];
|
|
224
|
+
let propertyValue = property && isObject(property) && property.hasOwnProperty("value") ? property.value : property;
|
|
225
|
+
if (propertyValue === "") {
|
|
226
|
+
propertyBag[propertyName] = null;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
export const setRequiredBooleansDefault = (attributes, propertyBag) => {
|
|
232
|
+
const requiredBools = attributes.filter(a => a.isRequired && a.dataType === attributeDataType.boolean);
|
|
233
|
+
|
|
234
|
+
requiredBools.forEach(attr => {
|
|
235
|
+
if (!propertyBag[attr.name]) {
|
|
236
|
+
propertyBag[attr.name] = toJsonCargo(attr, false);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
};
|