@beinformed/ui 1.60.5 → 1.61.0
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/CHANGELOG.md +19 -0
- package/esm/hooks/__tests__/useForm.spec.js.flow +1 -1
- package/esm/hooks/useForm.js +15 -20
- package/esm/hooks/useForm.js.flow +5 -14
- package/esm/hooks/useForm.js.map +1 -1
- package/esm/hooks/useModularUI.d.ts +0 -1
- package/esm/hooks/useModularUI.js +3 -11
- package/esm/hooks/useModularUI.js.flow +4 -23
- package/esm/hooks/useModularUI.js.map +1 -1
- package/esm/models/attributes/AttributeCollection.js +2 -2
- package/esm/models/attributes/AttributeCollection.js.map +1 -1
- package/esm/models/attributes/AttributeContent.js +1 -1
- package/esm/models/attributes/AttributeContent.js.flow +1 -1
- package/esm/models/attributes/AttributeContent.js.map +1 -1
- package/esm/models/attributes/CompositeAttributeChildCollection.js +4 -4
- package/esm/models/attributes/CompositeAttributeChildCollection.js.map +1 -1
- package/esm/models/concepts/ConceptDetailModel.js +9 -9
- package/esm/models/concepts/ConceptDetailModel.js.map +1 -1
- package/esm/models/content/ContentTOCModel.d.ts +7 -0
- package/esm/models/content/ContentTOCModel.js +35 -8
- package/esm/models/content/ContentTOCModel.js.flow +36 -9
- package/esm/models/content/ContentTOCModel.js.map +1 -1
- package/esm/models/content/SectionModel.d.ts +3 -0
- package/esm/models/content/SectionModel.js +11 -2
- package/esm/models/content/SectionModel.js.flow +11 -0
- package/esm/models/content/SectionModel.js.map +1 -1
- package/esm/models/content/SubSectionModel.d.ts +1 -1
- package/esm/models/content/SubSectionModel.js.flow +1 -1
- package/esm/models/content/SubSectionModel.js.map +1 -1
- package/esm/models/content/__tests__/Formalsource.spec.js.flow +91 -0
- package/esm/models/form/FormModel.js +33 -33
- package/esm/models/form/FormModel.js.map +1 -1
- package/esm/models/form/FormObjectModel.d.ts +13 -12
- package/esm/models/form/FormObjectModel.js +10 -9
- package/esm/models/form/FormObjectModel.js.flow +41 -27
- package/esm/models/form/FormObjectModel.js.map +1 -1
- package/esm/models/form/__tests__/FormValidation.spec.js.flow +79 -0
- package/esm/models/href/Href.js +6 -6
- package/esm/models/href/Href.js.map +1 -1
- package/esm/models/links/LinkCollection.js +4 -4
- package/esm/models/links/LinkCollection.js.map +1 -1
- package/esm/redux/_modularui/ModularUIActions.d.ts +2 -2
- package/esm/redux/_modularui/ModularUIActions.js +27 -10
- package/esm/redux/_modularui/ModularUIActions.js.flow +24 -5
- package/esm/redux/_modularui/ModularUIActions.js.map +1 -1
- package/esm/redux/_modularui/ModularUIMiddleware.js +1 -1
- package/esm/redux/_modularui/ModularUIMiddleware.js.flow +1 -1
- package/esm/redux/_modularui/ModularUIMiddleware.js.map +1 -1
- package/esm/redux/_modularui/ModularUIReducer.js +4 -2
- package/esm/redux/_modularui/ModularUIReducer.js.flow +10 -1
- package/esm/redux/_modularui/ModularUIReducer.js.map +1 -1
- package/esm/redux/_modularui/ModularUISelectors.js +2 -2
- package/esm/redux/_modularui/ModularUISelectors.js.map +1 -1
- package/esm/redux/_modularui/__tests__/actions.spec.js.flow +5 -1
- package/esm/redux/_modularui/types.d.ts +1 -0
- package/esm/redux/_modularui/types.js.flow +2 -0
- package/esm/redux/_modularui/types.js.map +1 -1
- package/esm/utils/helpers/text.d.ts +1 -1
- package/esm/utils/helpers/text.js +1 -1
- package/esm/utils/helpers/text.js.flow +2 -2
- package/esm/utils/helpers/text.js.map +1 -1
- package/lib/hooks/useDeepCompareEffect.js +1 -2
- package/lib/hooks/useDeepCompareEffect.js.map +1 -1
- package/lib/hooks/useForm.js +14 -19
- package/lib/hooks/useForm.js.map +1 -1
- package/lib/hooks/useModularUI.d.ts +0 -1
- package/lib/hooks/useModularUI.js +4 -13
- package/lib/hooks/useModularUI.js.map +1 -1
- package/lib/i18n/index.js +1 -2
- package/lib/i18n/index.js.map +1 -1
- package/lib/models/attributes/AttributeCollection.js +2 -2
- package/lib/models/attributes/AttributeCollection.js.map +1 -1
- package/lib/models/attributes/AttributeContent.js +1 -1
- package/lib/models/attributes/AttributeContent.js.map +1 -1
- package/lib/models/attributes/CompositeAttributeChildCollection.js +4 -4
- package/lib/models/attributes/CompositeAttributeChildCollection.js.map +1 -1
- package/lib/models/concepts/ConceptDetailModel.js +9 -9
- package/lib/models/concepts/ConceptDetailModel.js.map +1 -1
- package/lib/models/content/ContentTOCModel.d.ts +7 -0
- package/lib/models/content/ContentTOCModel.js +35 -8
- package/lib/models/content/ContentTOCModel.js.map +1 -1
- package/lib/models/content/SectionModel.d.ts +3 -0
- package/lib/models/content/SectionModel.js +11 -2
- package/lib/models/content/SectionModel.js.map +1 -1
- package/lib/models/content/SubSectionModel.d.ts +1 -1
- package/lib/models/content/SubSectionModel.js.map +1 -1
- package/lib/models/form/FormModel.js +33 -33
- package/lib/models/form/FormModel.js.map +1 -1
- package/lib/models/form/FormObjectModel.d.ts +13 -12
- package/lib/models/form/FormObjectModel.js +10 -9
- package/lib/models/form/FormObjectModel.js.map +1 -1
- package/lib/models/href/Href.js +6 -6
- package/lib/models/href/Href.js.map +1 -1
- package/lib/models/index.js +1 -2
- package/lib/models/index.js.map +1 -1
- package/lib/models/links/LinkCollection.js +4 -4
- package/lib/models/links/LinkCollection.js.map +1 -1
- package/lib/react-server/serverUtil.js +1 -2
- package/lib/react-server/serverUtil.js.map +1 -1
- package/lib/redux/_modularui/ModularUIActions.d.ts +2 -2
- package/lib/redux/_modularui/ModularUIActions.js +27 -10
- package/lib/redux/_modularui/ModularUIActions.js.map +1 -1
- package/lib/redux/_modularui/ModularUIMiddleware.js +1 -1
- package/lib/redux/_modularui/ModularUIMiddleware.js.map +1 -1
- package/lib/redux/_modularui/ModularUIReducer.js +4 -2
- package/lib/redux/_modularui/ModularUIReducer.js.map +1 -1
- package/lib/redux/_modularui/ModularUISelectors.js +2 -2
- package/lib/redux/_modularui/ModularUISelectors.js.map +1 -1
- package/lib/redux/_modularui/types.d.ts +1 -0
- package/lib/redux/_modularui/types.js.map +1 -1
- package/lib/utils/helpers/text.d.ts +1 -1
- package/lib/utils/helpers/text.js +1 -1
- package/lib/utils/helpers/text.js.map +1 -1
- package/package.json +17 -17
- package/src/hooks/__tests__/useForm.spec.js +1 -1
- package/src/hooks/useForm.js +5 -14
- package/src/hooks/useModularUI.js +4 -23
- package/src/models/attributes/AttributeContent.js +1 -1
- package/src/models/content/ContentTOCModel.js +36 -9
- package/src/models/content/SectionModel.js +11 -0
- package/src/models/content/SubSectionModel.js +1 -1
- package/src/models/content/__tests__/Formalsource.spec.js +91 -0
- package/src/models/content/__tests__/formalsource-complete.json +234 -0
- package/src/models/content/__tests__/formalsource-contributions.json +110 -0
- package/src/models/content/__tests__/formalsource-section-contributions.json +84 -0
- package/src/models/content/__tests__/formalsource-section.json +60 -0
- package/src/models/content/__tests__/formalsource-toc.json +119 -0
- package/src/models/form/FormObjectModel.js +41 -27
- package/src/models/form/__tests__/FormValidation.spec.js +79 -0
- package/src/models/form/__tests__/FormValidationContributions.json +45 -0
- package/src/models/form/__tests__/FormValidationDataInitial.json +33 -0
- package/src/models/form/__tests__/FormValidationDataUpdate1.json +25 -0
- package/src/models/form/__tests__/FormValidationDataUpdate2.json +33 -0
- package/src/redux/_modularui/ModularUIActions.js +24 -5
- package/src/redux/_modularui/ModularUIMiddleware.js +1 -1
- package/src/redux/_modularui/ModularUIReducer.js +10 -1
- package/src/redux/_modularui/__tests__/actions.spec.js +5 -1
- package/src/redux/_modularui/types.js +2 -0
- package/src/utils/helpers/text.js +2 -2
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"content": {
|
|
3
|
+
"filter": {
|
|
4
|
+
"booleanfilter": {
|
|
5
|
+
"param": "complete",
|
|
6
|
+
"name": "complete",
|
|
7
|
+
"value": "false"
|
|
8
|
+
},
|
|
9
|
+
"stringfilter": {
|
|
10
|
+
"param": "searchTerm",
|
|
11
|
+
"name": "searchTerm"
|
|
12
|
+
},
|
|
13
|
+
"entryDate": {
|
|
14
|
+
"param": "entryDate",
|
|
15
|
+
"name": "entryDate",
|
|
16
|
+
"value": "2025-05-28"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"_links": {
|
|
20
|
+
"self": {
|
|
21
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource"
|
|
22
|
+
},
|
|
23
|
+
"api_doc": {
|
|
24
|
+
"href": "/api-docs/v3/content/(content-identifier)"
|
|
25
|
+
},
|
|
26
|
+
"contributions": {
|
|
27
|
+
"href": "/contributions/content/(content-identifier)"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"label": "Grant Funding Agreement - Terms and Conditions",
|
|
31
|
+
"sections": [
|
|
32
|
+
{
|
|
33
|
+
"_links": {
|
|
34
|
+
"self": {
|
|
35
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/Chapter1"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"_id": "Chapter1",
|
|
39
|
+
"label": "1. Introduction"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"_links": {
|
|
43
|
+
"self": {
|
|
44
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/Chapter2"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"_id": "Chapter2",
|
|
48
|
+
"label": "2. Grant Offer",
|
|
49
|
+
"sections": [
|
|
50
|
+
{
|
|
51
|
+
"_links": {
|
|
52
|
+
"self": {
|
|
53
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/Chapter2_1"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"_id": "Chapter2_1",
|
|
57
|
+
"label": "2.1 Payment of Grant"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"_links": {
|
|
61
|
+
"self": {
|
|
62
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/Chapter2_2"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"_id": "Chapter2_2",
|
|
66
|
+
"label": "2.2 Purpose of Funding"
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"_links": {
|
|
72
|
+
"self": {
|
|
73
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/Chapter3"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"_id": "Chapter3",
|
|
77
|
+
"label": "3. Amount of Grant"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"_links": {
|
|
81
|
+
"self": {
|
|
82
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/Chapter4"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"_id": "Chapter4",
|
|
86
|
+
"label": "4. Purpose of Grant"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"_links": {
|
|
90
|
+
"self": {
|
|
91
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/Chapter5"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"_id": "Chapter5",
|
|
95
|
+
"label": "5. Eligibility of Grant",
|
|
96
|
+
"sections": [
|
|
97
|
+
{
|
|
98
|
+
"_links": {
|
|
99
|
+
"self": {
|
|
100
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/Chapter5_1"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"_id": "Chapter5_1",
|
|
104
|
+
"label": "5.1 Eligibility Criteria"
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"_links": {
|
|
110
|
+
"self": {
|
|
111
|
+
"href": "/content/bundle-com.beinformed.source.GrantFundingAgreementTermsandConditions/Grant%20Funding%20Agreement.formalsource/AnnexA"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"_id": "AnnexA",
|
|
115
|
+
"label": "Annex A. Innovation levels research grant projects"
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -18,8 +18,19 @@ import type {
|
|
|
18
18
|
import LayoutHintCollection from "../layouthint/LayoutHintCollection";
|
|
19
19
|
|
|
20
20
|
import type LinkModel from "../links/LinkModel";
|
|
21
|
-
import type { MessageParameters } from "../../i18n";
|
|
22
21
|
import type ErrorResponse from "../error/ErrorResponse";
|
|
22
|
+
import type { MessageParameters } from "../../i18n";
|
|
23
|
+
|
|
24
|
+
type ErrorObject = {
|
|
25
|
+
anchor: {
|
|
26
|
+
objectid: string,
|
|
27
|
+
elementid?: string,
|
|
28
|
+
},
|
|
29
|
+
id: string,
|
|
30
|
+
message: string,
|
|
31
|
+
properties: MessageParameters,
|
|
32
|
+
layouthint: Array<string>,
|
|
33
|
+
};
|
|
23
34
|
|
|
24
35
|
/**
|
|
25
36
|
* Form Object
|
|
@@ -474,22 +485,12 @@ export default class FormObjectModel extends BaseModel {
|
|
|
474
485
|
/**
|
|
475
486
|
* Convert error json from a form service to validation messages on the form object and attributes
|
|
476
487
|
*/
|
|
477
|
-
handleErrorValidations(
|
|
478
|
-
errors: Array<{
|
|
479
|
-
anchor: {
|
|
480
|
-
objectid: string,
|
|
481
|
-
elementid?: string,
|
|
482
|
-
},
|
|
483
|
-
id: string,
|
|
484
|
-
message: string,
|
|
485
|
-
properties: MessageParameters,
|
|
486
|
-
layouthint: Array<string>,
|
|
487
|
-
}>,
|
|
488
|
-
) {
|
|
488
|
+
handleErrorValidations(errors: Array<ErrorObject>) {
|
|
489
489
|
const attributeErrors = [];
|
|
490
490
|
|
|
491
|
-
errors
|
|
492
|
-
|
|
491
|
+
errors
|
|
492
|
+
.filter((error) => error.anchor?.objectid === this.key)
|
|
493
|
+
.forEach((error) => {
|
|
493
494
|
if (has(error.anchor, "elementid")) {
|
|
494
495
|
attributeErrors.push(error);
|
|
495
496
|
} else {
|
|
@@ -500,8 +501,7 @@ export default class FormObjectModel extends BaseModel {
|
|
|
500
501
|
new LayoutHintCollection(error.layouthint),
|
|
501
502
|
);
|
|
502
503
|
}
|
|
503
|
-
}
|
|
504
|
-
});
|
|
504
|
+
});
|
|
505
505
|
|
|
506
506
|
this.attributeCollection.updateValidations(attributeErrors);
|
|
507
507
|
}
|
|
@@ -509,15 +509,18 @@ export default class FormObjectModel extends BaseModel {
|
|
|
509
509
|
/**
|
|
510
510
|
* Convert missing json from a form service to mandatory validation constraints and messages
|
|
511
511
|
*/
|
|
512
|
-
handleMissingValidations(
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
512
|
+
handleMissingValidations(
|
|
513
|
+
missing: {
|
|
514
|
+
anchors: Array<
|
|
515
|
+
| {
|
|
516
|
+
elements: Array<{ elementid: string }>,
|
|
517
|
+
objectid?: string,
|
|
518
|
+
}
|
|
519
|
+
| { anchor: { elementid: string, objectid?: string } },
|
|
520
|
+
>,
|
|
521
|
+
},
|
|
522
|
+
errors: Array<ErrorObject>,
|
|
523
|
+
) {
|
|
521
524
|
const attributeErrors = [];
|
|
522
525
|
|
|
523
526
|
for (const anchor of missing.anchors) {
|
|
@@ -538,6 +541,17 @@ export default class FormObjectModel extends BaseModel {
|
|
|
538
541
|
}
|
|
539
542
|
}
|
|
540
543
|
|
|
544
|
+
errors
|
|
545
|
+
.filter(
|
|
546
|
+
(error) =>
|
|
547
|
+
error.id === "Constraint.Mandatory" &&
|
|
548
|
+
error.anchor?.objectid === this.key &&
|
|
549
|
+
has(error.anchor, "elementid"),
|
|
550
|
+
)
|
|
551
|
+
.forEach((error) => {
|
|
552
|
+
attributeErrors.push(error);
|
|
553
|
+
});
|
|
554
|
+
|
|
541
555
|
this.attributeCollection.updateValidations(attributeErrors);
|
|
542
556
|
}
|
|
543
557
|
|
|
@@ -552,7 +566,7 @@ export default class FormObjectModel extends BaseModel {
|
|
|
552
566
|
|
|
553
567
|
// missing attribute errors
|
|
554
568
|
if (Array.isArray(data.missing?.anchors)) {
|
|
555
|
-
this.handleMissingValidations(data.missing);
|
|
569
|
+
this.handleMissingValidations(data.missing, data.errors);
|
|
556
570
|
}
|
|
557
571
|
|
|
558
572
|
this.dynamicValidationsLoaded = true;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ModularUIResponse } from "../../../modularui";
|
|
2
|
+
|
|
3
|
+
import initialData from "./FormValidationDataInitial.json";
|
|
4
|
+
import contributions from "./FormValidationContributions.json";
|
|
5
|
+
import updateData from "./FormValidationDataUpdate1.json";
|
|
6
|
+
import updateData2 from "./FormValidationDataUpdate2.json";
|
|
7
|
+
|
|
8
|
+
import FormModel from "../FormModel";
|
|
9
|
+
|
|
10
|
+
describe("Form validation update", () => {
|
|
11
|
+
it("should be able to update the validations of a form", () => {
|
|
12
|
+
const response = ModularUIResponse.create({
|
|
13
|
+
key: "Form",
|
|
14
|
+
data: initialData,
|
|
15
|
+
contributions: contributions,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const form = new FormModel(response);
|
|
19
|
+
const formModel = form.currentFormObject;
|
|
20
|
+
|
|
21
|
+
const validation = formModel.getAttributeByKey("Validation");
|
|
22
|
+
const compareWith = formModel.getAttributeByKey("CompareWith");
|
|
23
|
+
const optional = formModel.getAttributeByKey("ThisOneIsOptional");
|
|
24
|
+
|
|
25
|
+
expect(validation.mandatory).toBe(true);
|
|
26
|
+
expect(compareWith.mandatory).toBe(true);
|
|
27
|
+
expect(optional.mandatory).toBe(false);
|
|
28
|
+
|
|
29
|
+
const newForm = form.clone();
|
|
30
|
+
newForm.currentFormObject.updateAttribute(validation, "test");
|
|
31
|
+
|
|
32
|
+
expect(validation.mandatory).toBe(true);
|
|
33
|
+
expect(compareWith.mandatory).toBe(true);
|
|
34
|
+
expect(optional.mandatory).toBe(false);
|
|
35
|
+
|
|
36
|
+
const updateResponse = ModularUIResponse.create({
|
|
37
|
+
key: "Form",
|
|
38
|
+
data: updateData,
|
|
39
|
+
contributions: contributions,
|
|
40
|
+
});
|
|
41
|
+
const updateForm = new FormModel(updateResponse);
|
|
42
|
+
|
|
43
|
+
newForm.updateValidations(updateForm.data);
|
|
44
|
+
|
|
45
|
+
expect(
|
|
46
|
+
newForm.currentFormObject.getAttributeByKey("Validation").mandatory,
|
|
47
|
+
).toBe(true);
|
|
48
|
+
expect(
|
|
49
|
+
newForm.currentFormObject.getAttributeByKey("CompareWith").mandatory,
|
|
50
|
+
).toBe(true);
|
|
51
|
+
expect(
|
|
52
|
+
newForm.currentFormObject.getAttributeByKey("ThisOneIsOptional")
|
|
53
|
+
.mandatory,
|
|
54
|
+
).toBe(false);
|
|
55
|
+
|
|
56
|
+
const newForm2 = form.clone();
|
|
57
|
+
newForm2.currentFormObject.updateAttribute(validation, "");
|
|
58
|
+
|
|
59
|
+
const update2Response = ModularUIResponse.create({
|
|
60
|
+
key: "Form",
|
|
61
|
+
data: updateData2,
|
|
62
|
+
contributions: contributions,
|
|
63
|
+
});
|
|
64
|
+
const update2Form = new FormModel(update2Response);
|
|
65
|
+
|
|
66
|
+
newForm.updateValidations(update2Form.data);
|
|
67
|
+
|
|
68
|
+
expect(
|
|
69
|
+
newForm.currentFormObject.getAttributeByKey("Validation").mandatory,
|
|
70
|
+
).toBe(true);
|
|
71
|
+
expect(
|
|
72
|
+
newForm.currentFormObject.getAttributeByKey("CompareWith").mandatory,
|
|
73
|
+
).toBe(true);
|
|
74
|
+
expect(
|
|
75
|
+
newForm.currentFormObject.getAttributeByKey("ThisOneIsOptional")
|
|
76
|
+
.mandatory,
|
|
77
|
+
).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ValidationMakesItOptional": {
|
|
3
|
+
"label": "Validation makes it optional",
|
|
4
|
+
"resourcetype": "Form",
|
|
5
|
+
"actiontype": "form",
|
|
6
|
+
"objects": {
|
|
7
|
+
"ValidationMakesItOptional": {
|
|
8
|
+
"dynamicObject": false,
|
|
9
|
+
"repeatable": false,
|
|
10
|
+
"dynamicValidations": true,
|
|
11
|
+
"label": "Validation makes it optional",
|
|
12
|
+
"mandatory": true,
|
|
13
|
+
"attributes": [
|
|
14
|
+
{
|
|
15
|
+
"Validation": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"label": "Validation",
|
|
18
|
+
"mandatory": true,
|
|
19
|
+
"displaysize": 50,
|
|
20
|
+
"maxLength": 255
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"CompareWith": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"label": "Compare with",
|
|
27
|
+
"mandatory": true,
|
|
28
|
+
"displaysize": 50,
|
|
29
|
+
"maxLength": 255
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"ThisOneIsOptional": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"label": "This one is optional",
|
|
36
|
+
"mandatory": false,
|
|
37
|
+
"displaysize": 50,
|
|
38
|
+
"maxLength": 255
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"formresponse": {
|
|
3
|
+
"_links": {
|
|
4
|
+
"self": {
|
|
5
|
+
"href": "/all-cases/validation-makes/validation-makes-it-optional"
|
|
6
|
+
},
|
|
7
|
+
"api_doc": {
|
|
8
|
+
"href": "/api-docs/v3/all-cases/validation-makes/validation-makes-it-optional"
|
|
9
|
+
},
|
|
10
|
+
"contributions": {
|
|
11
|
+
"href": "/contributions/all-cases/validation-makes/validation-makes-it-optional"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"missing": {
|
|
15
|
+
"anchors": [
|
|
16
|
+
{
|
|
17
|
+
"objectid": "ValidationMakesItOptional",
|
|
18
|
+
"elements": [
|
|
19
|
+
{
|
|
20
|
+
"elementid": "Validation"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"elementid": "CompareWith"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"elementid": "ThisOneIsOptional"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"formresponse": {
|
|
3
|
+
"_links": {
|
|
4
|
+
"self": {
|
|
5
|
+
"href": "/all-cases/validation-makes/validation-makes-it-optional"
|
|
6
|
+
},
|
|
7
|
+
"api_doc": {
|
|
8
|
+
"href": "/api-docs/v3/all-cases/validation-makes/validation-makes-it-optional"
|
|
9
|
+
},
|
|
10
|
+
"contributions": {
|
|
11
|
+
"href": "/contributions/all-cases/validation-makes/validation-makes-it-optional"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"errors": [
|
|
15
|
+
{
|
|
16
|
+
"anchor": {
|
|
17
|
+
"objectid": "ValidationMakesItOptional",
|
|
18
|
+
"elementid": "CompareWith"
|
|
19
|
+
},
|
|
20
|
+
"id": "Constraint.Mandatory",
|
|
21
|
+
"message": "Field is mandatory"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"formresponse": {
|
|
3
|
+
"_links": {
|
|
4
|
+
"self": {
|
|
5
|
+
"href": "/all-cases/validation-makes/validation-makes-it-optional"
|
|
6
|
+
},
|
|
7
|
+
"api_doc": {
|
|
8
|
+
"href": "/api-docs/v3/all-cases/validation-makes/validation-makes-it-optional"
|
|
9
|
+
},
|
|
10
|
+
"contributions": {
|
|
11
|
+
"href": "/contributions/all-cases/validation-makes/validation-makes-it-optional"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"missing": {
|
|
15
|
+
"anchors": [
|
|
16
|
+
{
|
|
17
|
+
"objectid": "ValidationMakesItOptional",
|
|
18
|
+
"elementid": "Validation"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"errors": [
|
|
23
|
+
{
|
|
24
|
+
"anchor": {
|
|
25
|
+
"objectid": "ValidationMakesItOptional",
|
|
26
|
+
"elementid": "CompareWith"
|
|
27
|
+
},
|
|
28
|
+
"id": "Constraint.Mandatory",
|
|
29
|
+
"message": "Field is mandatory"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -81,9 +81,10 @@ export const resetModularUI = (): ResetModularUIAction => ({
|
|
|
81
81
|
export const updateStatus = (
|
|
82
82
|
key: string,
|
|
83
83
|
status: $Keys<typeof MODULARUI_STATUS>,
|
|
84
|
+
requestOptions: any,
|
|
84
85
|
): UpdateStatusAction => ({
|
|
85
86
|
type: "MODULARUI/STATUS",
|
|
86
|
-
payload: { key, status },
|
|
87
|
+
payload: { key, status, requestOptions },
|
|
87
88
|
});
|
|
88
89
|
|
|
89
90
|
/**
|
|
@@ -177,13 +178,31 @@ export const loadModularUI =
|
|
|
177
178
|
key: string,
|
|
178
179
|
href: Href | string,
|
|
179
180
|
options?: RequestModularUIOptions,
|
|
181
|
+
retryCount: number = 3,
|
|
182
|
+
retryDelay: number = 200,
|
|
180
183
|
): ThunkAction =>
|
|
181
184
|
(dispatch: Dispatch, getState) => {
|
|
182
185
|
const modularuiStore = getState()?.modularui;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
const currentRequest = modularuiStore?.[key];
|
|
187
|
+
|
|
188
|
+
const isLoading = currentRequest?.status === MODULARUI_STATUS.LOADING;
|
|
189
|
+
|
|
190
|
+
if (isLoading) {
|
|
191
|
+
const isDifferentRequest =
|
|
192
|
+
currentRequest.requestOptions?.href?.toString() !== href.toString();
|
|
193
|
+
if (isDifferentRequest && retryCount > 0) {
|
|
194
|
+
return new Promise((resolve) => {
|
|
195
|
+
setTimeout(() => {
|
|
196
|
+
resolve(
|
|
197
|
+
dispatch(
|
|
198
|
+
loadModularUI(key, href, options, retryCount - 1, retryDelay),
|
|
199
|
+
),
|
|
200
|
+
);
|
|
201
|
+
}, retryDelay);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Same request is already loading — do nothing
|
|
187
206
|
return Promise.resolve();
|
|
188
207
|
}
|
|
189
208
|
|
|
@@ -150,7 +150,7 @@ const handleFetch = (
|
|
|
150
150
|
|
|
151
151
|
const modularuiRequest = createRequest(requestOptions);
|
|
152
152
|
|
|
153
|
-
dispatch(updateStatus(key, MODULARUI_STATUS.LOADING));
|
|
153
|
+
dispatch(updateStatus(key, MODULARUI_STATUS.LOADING, requestOptions));
|
|
154
154
|
|
|
155
155
|
return modularuiRequest
|
|
156
156
|
.fetch()
|
|
@@ -11,7 +11,15 @@ import type { ModularUIModel } from "../../models";
|
|
|
11
11
|
*/
|
|
12
12
|
const updateStatus = (
|
|
13
13
|
state: ModularUIState,
|
|
14
|
-
{
|
|
14
|
+
{
|
|
15
|
+
key,
|
|
16
|
+
status,
|
|
17
|
+
requestOptions,
|
|
18
|
+
}: {
|
|
19
|
+
key: string,
|
|
20
|
+
status: $Keys<typeof MODULARUI_STATUS>,
|
|
21
|
+
requestOptions: any,
|
|
22
|
+
},
|
|
15
23
|
) => {
|
|
16
24
|
// model should always be available when status is not loading
|
|
17
25
|
if (status !== MODULARUI_STATUS.LOADING && !state[key]) {
|
|
@@ -24,6 +32,7 @@ const updateStatus = (
|
|
|
24
32
|
...state[key],
|
|
25
33
|
status,
|
|
26
34
|
lastModification: Date.now(),
|
|
35
|
+
requestOptions: requestOptions || state[key]?.requestOptions,
|
|
27
36
|
},
|
|
28
37
|
};
|
|
29
38
|
};
|
|
@@ -72,7 +72,11 @@ describe("modularui actions", () => {
|
|
|
72
72
|
expect(store.getActions()).toStrictEqual([
|
|
73
73
|
{
|
|
74
74
|
type: "MODULARUI/STATUS",
|
|
75
|
-
payload: {
|
|
75
|
+
payload: {
|
|
76
|
+
key: "application",
|
|
77
|
+
status: MODULARUI_STATUS.LOADING,
|
|
78
|
+
requestOptions: undefined,
|
|
79
|
+
},
|
|
76
80
|
},
|
|
77
81
|
]);
|
|
78
82
|
});
|
|
@@ -21,6 +21,7 @@ export type ModelEntry = {
|
|
|
21
21
|
+status: string,
|
|
22
22
|
+model: ModularUIModel,
|
|
23
23
|
+lastModification: number,
|
|
24
|
+
+requestOptions?: any,
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
export type ModularUIState = {
|
|
@@ -111,6 +112,7 @@ export type UpdateStatusAction = {
|
|
|
111
112
|
payload: {
|
|
112
113
|
key: string,
|
|
113
114
|
status: $Keys<MODULARUI_STATUS>,
|
|
115
|
+
requestOptions: any,
|
|
114
116
|
},
|
|
115
117
|
};
|
|
116
118
|
|
|
@@ -10,7 +10,7 @@ export const retrieveText = (
|
|
|
10
10
|
text:
|
|
11
11
|
| string
|
|
12
12
|
| { id?: string, message: string, properties?: { [key: string]: any } },
|
|
13
|
-
): string => {
|
|
13
|
+
): string | null => {
|
|
14
14
|
if (typeof text === "string") {
|
|
15
15
|
return text;
|
|
16
16
|
}
|
|
@@ -19,5 +19,5 @@ export const retrieveText = (
|
|
|
19
19
|
return text.message;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
return
|
|
22
|
+
return null;
|
|
23
23
|
};
|