@beinformed/ui 1.9.0-beta.6 → 1.9.1

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.
Files changed (160) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/esm/constants/Settings.js +10 -8
  3. package/esm/constants/Settings.js.map +1 -1
  4. package/esm/hooks/useForm.js.map +1 -1
  5. package/esm/hooks/useNotification.js.map +1 -1
  6. package/esm/hooks/useRouter.js.map +1 -1
  7. package/esm/models/attributes/AttributeContent.js +126 -58
  8. package/esm/models/attributes/AttributeContent.js.map +1 -1
  9. package/esm/models/attributes/AttributeDataHelper.js +1 -1
  10. package/esm/models/attributes/AttributeDataHelper.js.map +1 -1
  11. package/esm/models/attributes/AttributeModel.js +3 -3
  12. package/esm/models/attributes/AttributeModel.js.map +1 -1
  13. package/esm/models/attributes/ChoiceAttributeOptionModel.js +4 -4
  14. package/esm/models/attributes/ChoiceAttributeOptionModel.js.map +1 -1
  15. package/esm/models/attributes/HelptextAttributeModel.js +17 -1
  16. package/esm/models/attributes/HelptextAttributeModel.js.map +1 -1
  17. package/esm/models/caseview/CaseViewModel.js +26 -12
  18. package/esm/models/caseview/CaseViewModel.js.map +1 -1
  19. package/esm/models/content/SectionModel.js +2 -1
  20. package/esm/models/content/SectionModel.js.map +1 -1
  21. package/esm/models/content/SubSectionModel.js +3 -1
  22. package/esm/models/content/SubSectionModel.js.map +1 -1
  23. package/esm/models/contentconfiguration/ContentConfigurationResults.js +2 -2
  24. package/esm/models/contentconfiguration/ContentConfigurationResults.js.map +1 -1
  25. package/esm/models/form/FormObjectModel.js +8 -2
  26. package/esm/models/form/FormObjectModel.js.map +1 -1
  27. package/esm/models/layouthint/LayoutHintCollection.js +3 -2
  28. package/esm/models/layouthint/LayoutHintCollection.js.map +1 -1
  29. package/esm/models/list/ListDetailModel.js +25 -0
  30. package/esm/models/list/ListDetailModel.js.map +1 -1
  31. package/esm/models/list/ListModel.js +22 -16
  32. package/esm/models/list/ListModel.js.map +1 -1
  33. package/esm/models/panels/GroupingPanelModel.js +19 -17
  34. package/esm/models/panels/GroupingPanelModel.js.map +1 -1
  35. package/esm/modularui/ModularUIRequest.js +2 -1
  36. package/esm/modularui/ModularUIRequest.js.map +1 -1
  37. package/esm/utils/helpers/text.js +19 -0
  38. package/esm/utils/helpers/text.js.map +1 -0
  39. package/esm/utils/index.js +2 -1
  40. package/esm/utils/index.js.map +1 -1
  41. package/lib/constants/Settings.js +12 -1
  42. package/lib/constants/Settings.js.flow +9 -5
  43. package/lib/constants/Settings.js.map +1 -1
  44. package/lib/hooks/useForm.js.flow +10 -5
  45. package/lib/hooks/useForm.js.map +1 -1
  46. package/lib/hooks/useNotification.js.flow +5 -2
  47. package/lib/hooks/useNotification.js.map +1 -1
  48. package/lib/hooks/useRouter.js.flow +12 -5
  49. package/lib/hooks/useRouter.js.map +1 -1
  50. package/lib/models/attributes/AttributeContent.js +136 -59
  51. package/lib/models/attributes/AttributeContent.js.flow +91 -39
  52. package/lib/models/attributes/AttributeContent.js.map +1 -1
  53. package/lib/models/attributes/AttributeDataHelper.js +1 -1
  54. package/lib/models/attributes/AttributeDataHelper.js.flow +2 -1
  55. package/lib/models/attributes/AttributeDataHelper.js.map +1 -1
  56. package/lib/models/attributes/AttributeModel.js +1 -1
  57. package/lib/models/attributes/AttributeModel.js.flow +2 -3
  58. package/lib/models/attributes/AttributeModel.js.map +1 -1
  59. package/lib/models/attributes/ChoiceAttributeOptionModel.js +3 -3
  60. package/lib/models/attributes/ChoiceAttributeOptionModel.js.flow +4 -7
  61. package/lib/models/attributes/ChoiceAttributeOptionModel.js.map +1 -1
  62. package/lib/models/attributes/HelptextAttributeModel.js +17 -1
  63. package/lib/models/attributes/HelptextAttributeModel.js.flow +11 -1
  64. package/lib/models/attributes/HelptextAttributeModel.js.map +1 -1
  65. package/lib/models/attributes/__tests__/AttributeContent.spec.js.flow +10 -2
  66. package/lib/models/attributes/__tests__/AttributeDataHelper.spec.js.flow +9 -3
  67. package/lib/models/attributes/__tests__/HelptextAttributeModel.spec.js.flow +39 -1
  68. package/lib/models/caseview/CaseViewModel.js +27 -13
  69. package/lib/models/caseview/CaseViewModel.js.flow +17 -7
  70. package/lib/models/caseview/CaseViewModel.js.map +1 -1
  71. package/lib/models/caseview/__tests__/CaseViewModel.spec.js.flow +68 -184
  72. package/lib/models/concepts/__mock__/business_scenario.js.flow +14 -1
  73. package/lib/models/concepts/__mock__/conceptdetail.js.flow +15 -6
  74. package/lib/models/concepts/__tests__/BusinessScenarioModel.spec.js.flow +5 -6
  75. package/lib/models/concepts/__tests__/ConceptDetailModel.spec.js.flow +58 -3
  76. package/lib/models/content/SectionModel.js +3 -1
  77. package/lib/models/content/SectionModel.js.flow +2 -1
  78. package/lib/models/content/SectionModel.js.map +1 -1
  79. package/lib/models/content/SubSectionModel.js +4 -1
  80. package/lib/models/content/SubSectionModel.js.flow +3 -1
  81. package/lib/models/content/SubSectionModel.js.map +1 -1
  82. package/lib/models/contentconfiguration/ContentConfigurationResults.js +2 -2
  83. package/lib/models/contentconfiguration/ContentConfigurationResults.js.flow +2 -2
  84. package/lib/models/contentconfiguration/ContentConfigurationResults.js.map +1 -1
  85. package/lib/models/contentconfiguration/__tests__/ContentConfigurationResults.spec.js.flow +6 -6
  86. package/lib/models/form/FormObjectModel.js +8 -2
  87. package/lib/models/form/FormObjectModel.js.flow +5 -1
  88. package/lib/models/form/FormObjectModel.js.map +1 -1
  89. package/lib/models/form/__tests__/FormObjectModel.spec.js.flow +2 -2
  90. package/lib/models/layouthint/LayoutHintCollection.js +4 -2
  91. package/lib/models/layouthint/LayoutHintCollection.js.flow +8 -7
  92. package/lib/models/layouthint/LayoutHintCollection.js.map +1 -1
  93. package/lib/models/list/ListDetailModel.js +25 -0
  94. package/lib/models/list/ListDetailModel.js.flow +19 -0
  95. package/lib/models/list/ListDetailModel.js.map +1 -1
  96. package/lib/models/list/ListModel.js +23 -16
  97. package/lib/models/list/ListModel.js.flow +9 -5
  98. package/lib/models/list/ListModel.js.map +1 -1
  99. package/lib/models/list/__tests__/ListDetailModel.spec.js.flow +64 -0
  100. package/lib/models/list/__tests__/ListModel.spec.js.flow +64 -2
  101. package/lib/models/panels/GroupingPanelModel.js +21 -18
  102. package/lib/models/panels/GroupingPanelModel.js.flow +10 -9
  103. package/lib/models/panels/GroupingPanelModel.js.map +1 -1
  104. package/lib/models/panels/__tests__/GroupingPanelModel.spec.js.flow +90 -0
  105. package/lib/models/types.js.flow +38 -11
  106. package/lib/modularui/ModularUIRequest.js +2 -1
  107. package/lib/modularui/ModularUIRequest.js.flow +1 -0
  108. package/lib/modularui/ModularUIRequest.js.map +1 -1
  109. package/lib/utils/helpers/text.js +28 -0
  110. package/lib/utils/helpers/text.js.flow +23 -0
  111. package/lib/utils/helpers/text.js.map +1 -0
  112. package/lib/utils/index.js +14 -0
  113. package/lib/utils/index.js.flow +1 -0
  114. package/lib/utils/index.js.map +1 -1
  115. package/package.json +13 -13
  116. package/src/constants/Settings.js +9 -5
  117. package/src/hooks/useForm.js +10 -5
  118. package/src/hooks/useNotification.js +5 -2
  119. package/src/hooks/useRouter.js +12 -5
  120. package/src/models/attributes/AttributeContent.js +91 -39
  121. package/src/models/attributes/AttributeDataHelper.js +2 -1
  122. package/src/models/attributes/AttributeModel.js +2 -3
  123. package/src/models/attributes/ChoiceAttributeOptionModel.js +4 -7
  124. package/src/models/attributes/HelptextAttributeModel.js +11 -1
  125. package/src/models/attributes/__tests__/AttributeContent.spec.js +10 -2
  126. package/src/models/attributes/__tests__/AttributeDataHelper.spec.js +9 -3
  127. package/src/models/attributes/__tests__/HelptextAttributeModel.spec.js +39 -1
  128. package/src/models/caseview/CaseViewModel.js +17 -7
  129. package/src/models/caseview/__tests__/CaseViewModel.spec.js +68 -184
  130. package/src/models/caseview/__tests__/caseview.json +38 -0
  131. package/src/models/caseview/__tests__/caseviewContributions.json +147 -0
  132. package/src/models/concepts/__mock__/business_scenario.js +14 -1
  133. package/src/models/concepts/__mock__/business_scenario_step.json +64 -0
  134. package/src/models/concepts/__mock__/conceptdetail.js +15 -6
  135. package/src/models/concepts/__mock__/conceptdetail_data.json +117 -17
  136. package/src/models/concepts/__mock__/concepttype_Calculation.json +75 -0
  137. package/src/models/concepts/__tests__/BusinessScenarioModel.spec.js +5 -6
  138. package/src/models/concepts/__tests__/ConceptDetailModel.spec.js +58 -3
  139. package/src/models/content/SectionModel.js +2 -1
  140. package/src/models/content/SubSectionModel.js +3 -1
  141. package/src/models/contentconfiguration/ContentConfigurationResults.js +2 -2
  142. package/src/models/contentconfiguration/__tests__/ContentConfigurationResults.spec.js +6 -6
  143. package/src/models/form/FormObjectModel.js +5 -1
  144. package/src/models/form/__tests__/FormObjectModel.spec.js +2 -2
  145. package/src/models/form/__tests__/FormWithContentData.json +1 -0
  146. package/src/models/layouthint/LayoutHintCollection.js +8 -7
  147. package/src/models/list/ListDetailModel.js +19 -0
  148. package/src/models/list/ListModel.js +9 -5
  149. package/src/models/list/__tests__/ListDetailModel.spec.js +64 -0
  150. package/src/models/list/__tests__/ListModel.spec.js +64 -2
  151. package/src/models/list/__tests__/caselist-34.contributions.json +1 -1
  152. package/src/models/list/__tests__/listContributions.json +1 -1
  153. package/src/models/panels/GroupingPanelModel.js +10 -9
  154. package/src/models/panels/__tests__/GroupingPanelModel.spec.js +90 -0
  155. package/src/models/panels/__tests__/groupingPanel.json +30 -0
  156. package/src/models/panels/__tests__/groupingPanelContributions.json +46 -0
  157. package/src/models/types.js +38 -11
  158. package/src/modularui/ModularUIRequest.js +1 -0
  159. package/src/utils/helpers/text.js +23 -0
  160. package/src/utils/index.js +1 -0
@@ -33,14 +33,14 @@ describe("ContentConfigurationResults", () => {
33
33
  });
34
34
 
35
35
  it("can handle configuration with description object", () => {
36
- const rawText =
36
+ const message =
37
37
  "<p>The property value is ${EstimatedPropertyValue} and my personal deposit is ${MortgageDeposit}. The mortgage is a repayment mortgage for a term of ${MortgageTermInYears} years. The rate type is ${InterestRateType} for a period of ${PeriodOfInterestRate}.</p>";
38
38
 
39
39
  const contributions = {
40
40
  label: "Total cost of mortgage",
41
41
  description: {
42
42
  id: "CalculatorResults.TotalCostOfMortgage.introText",
43
- rawText,
43
+ message,
44
44
  },
45
45
  layouthint: ["render-description:TotalCostOfMortgage"],
46
46
  attributes: ["TotalCostOfMortgage"],
@@ -59,7 +59,7 @@ describe("ContentConfigurationResults", () => {
59
59
  );
60
60
 
61
61
  expect(contentConfigurationResults.label).toBe("Total cost of mortgage");
62
- expect(contentConfigurationResults.description).toBe(rawText);
62
+ expect(contentConfigurationResults.description).toBe(message);
63
63
  expect(contentConfigurationResults.attributes).toStrictEqual([
64
64
  "TotalCostOfMortgage",
65
65
  ]);
@@ -87,15 +87,15 @@ describe("ContentConfigurationResults", () => {
87
87
  });
88
88
 
89
89
  it("can handle configuration with description string", () => {
90
- const rawText =
90
+ const message =
91
91
  "<p>The property value is ${EstimatedPropertyValue} and my personal deposit is ${MortgageDeposit}. The mortgage is a repayment mortgage for a term of ${MortgageTermInYears} years. The rate type is ${InterestRateType} for a period of ${PeriodOfInterestRate}.</p>";
92
92
 
93
93
  const contentConfigurationResults = new ContentConfigurationResults({
94
94
  label: "Total cost of mortgage",
95
- description: rawText,
95
+ description: message,
96
96
  });
97
97
 
98
98
  expect(contentConfigurationResults.label).toBe("Total cost of mortgage");
99
- expect(contentConfigurationResults.description).toBe(rawText);
99
+ expect(contentConfigurationResults.description).toBe(message);
100
100
  });
101
101
  });
@@ -295,8 +295,12 @@ export default class FormObjectModel extends BaseModel {
295
295
  * Get introText of form object
296
296
  */
297
297
  get introText(): string {
298
+ if (this.data.content?.text) {
299
+ return this.data.content.text.message ?? this.data.content.text;
300
+ }
301
+
298
302
  return (
299
- this.contributions.introText?.rawText ?? this.contributions.introText
303
+ this.contributions.introText?.message ?? this.contributions.introText
300
304
  );
301
305
  }
302
306
 
@@ -19,7 +19,7 @@ const data = {
19
19
  const contributions = {
20
20
  repeatable: false,
21
21
  label: "Create person",
22
- introText: { id: "IntroTextID", rawText: "This is introtext" },
22
+ introText: { id: "IntroTextID", message: "This is introtext" },
23
23
  attributes: [
24
24
  {
25
25
  Name: {
@@ -122,7 +122,7 @@ describe("formObjectModel", () => {
122
122
  const contributions2 = {
123
123
  repeatable: false,
124
124
  label: "Create person",
125
- introText: { id: "IntroTextID", rawText: "This is new introtext" },
125
+ introText: { id: "IntroTextID", message: "This is new introtext" },
126
126
  attributes: [],
127
127
  };
128
128
 
@@ -19,6 +19,7 @@
19
19
  {
20
20
  "elementid": "UitslagBlaastestType",
21
21
  "content": {
22
+ "header": { "label": "Header label" },
22
23
  "label": "Uitslag blaastest label",
23
24
  "elements": [
24
25
  {
@@ -35,11 +35,13 @@ export default class LayoutHintCollection extends BaseCollection<string> {
35
35
  has(...hints: Array<string>): boolean {
36
36
  const hintArray = hints.length > 0 ? [...hints] : [];
37
37
 
38
- return hintArray.some(
39
- (hint) =>
40
- this.layouthint.includes(hint) ||
41
- this.layouthint.some((hint2) => hint2.startsWith(hint))
42
- );
38
+ return hintArray
39
+ .flat()
40
+ .some(
41
+ (hint) =>
42
+ this.layouthint.includes(hint) ||
43
+ this.layouthint.some((hint2) => hint2.startsWith(hint))
44
+ );
43
45
  }
44
46
 
45
47
  /**
@@ -51,8 +53,7 @@ export default class LayoutHintCollection extends BaseCollection<string> {
51
53
  */
52
54
  hasExact(...hints: Array<string>): boolean {
53
55
  const hintArray = hints.length > 0 ? [...hints] : [];
54
-
55
- return hintArray.some((hint) => this.layouthint.includes(hint));
56
+ return hintArray.flat().some((hint) => this.layouthint.includes(hint));
56
57
  }
57
58
 
58
59
  /**
@@ -133,6 +133,25 @@ export default class ListDetailModel extends DetailModel {
133
133
  this._contentConfiguration = configuration;
134
134
  }
135
135
 
136
+ /**
137
+ * Getting the introduction text configured on the case view
138
+ */
139
+ get introtext(): string {
140
+ if (this.data._text) {
141
+ return this.data._text.message ?? this.data._text;
142
+ }
143
+
144
+ if (this.contributions.text) {
145
+ return this.contributions.text.message ?? this.contributions.text;
146
+ }
147
+
148
+ if (Array.isArray(this.contributions.texts)) {
149
+ return this.contributions.texts[0].text;
150
+ }
151
+
152
+ return "";
153
+ }
154
+
136
155
  /**
137
156
  */
138
157
  setResultSection() {
@@ -98,12 +98,16 @@ export default class ListModel extends ResourceModel {
98
98
  * Getting the introduction text
99
99
  */
100
100
  get introtext(): string {
101
- if (this.contributions.texts) {
102
- const text = this.contributions.texts.find(
103
- (item) => item.type === "master"
104
- );
101
+ if (this.data.text) {
102
+ return this.data.text.message ?? this.data.text;
103
+ }
104
+
105
+ if (this.contributions.text) {
106
+ return this.contributions.text.message ?? this.contributions.text;
107
+ }
105
108
 
106
- return text ? text.text : "";
109
+ if (Array.isArray(this.contributions.texts)) {
110
+ return this.contributions.texts[0].text;
107
111
  }
108
112
 
109
113
  return "";
@@ -27,4 +27,68 @@ describe("listDetailModel", () => {
27
27
  "Highly Inappropriate Tales for Young People"
28
28
  );
29
29
  });
30
+
31
+ it("should be able to handle different kind of introtext", () => {
32
+ const listdetailOldStructure = new ListDetailModel({
33
+ key: "Book",
34
+ data: data.Book,
35
+ contributions: contributions.Book,
36
+ });
37
+
38
+ expect(listdetailOldStructure.introtext).toBe("<p>This is introtext</p>");
39
+
40
+ const listdetailFromDataPlain = new ListDetailModel({
41
+ key: "Book",
42
+ data: {
43
+ _text: "<p>This is introtext</p>",
44
+ ...data.Book,
45
+ },
46
+ contributions: contributions.Book,
47
+ });
48
+
49
+ expect(listdetailFromDataPlain.introtext).toBe("<p>This is introtext</p>");
50
+
51
+ const listdetailFromDataApplicationMessage = new ListDetailModel({
52
+ key: "Book",
53
+ data: {
54
+ ...data.Book,
55
+ _text: {
56
+ message: "<p>This is introtext</p>",
57
+ },
58
+ },
59
+ contributions: contributions.Book,
60
+ });
61
+
62
+ expect(listdetailFromDataApplicationMessage.introtext).toBe(
63
+ "<p>This is introtext</p>"
64
+ );
65
+
66
+ const listdetailFromNewContributionsRawTextMessage = new ListDetailModel({
67
+ key: "Book",
68
+ data: data.Book,
69
+ contributions: {
70
+ ...contributions.Book,
71
+ text: {
72
+ message: "<p>This is introtext</p>",
73
+ },
74
+ },
75
+ });
76
+
77
+ expect(listdetailFromNewContributionsRawTextMessage.introtext).toBe(
78
+ "<p>This is introtext</p>"
79
+ );
80
+
81
+ const listdetailFromNewContributionsSimpleMessage = new ListDetailModel({
82
+ key: "Book",
83
+ data: data.Book,
84
+ contributions: {
85
+ ...contributions.Book,
86
+ text: "<p>This is introtext</p>",
87
+ },
88
+ });
89
+
90
+ expect(listdetailFromNewContributionsSimpleMessage.introtext).toBe(
91
+ "<p>This is introtext</p>"
92
+ );
93
+ });
30
94
  });
@@ -54,8 +54,70 @@ describe("listModel spec", () => {
54
54
 
55
55
  expect(list.headers).toHaveLength(6);
56
56
 
57
- expect(list.introtext).toStrictEqual(
58
- "<p>This is a list of <em>books</em><br />For each book the <strong>contributers</strong> and the <strong>publishers</strong> are added as <u>additional details</u>.<br />For more information see amazon</p>"
57
+ expect(list.introtext).toStrictEqual("<p>This is introtext</p>");
58
+ });
59
+
60
+ it("should be able to handle different kind of introtext", () => {
61
+ const listOldStructure = new ListModel({
62
+ key: "Books",
63
+ data: mockList.Books,
64
+ contributions: mockListContributions.Books,
65
+ });
66
+
67
+ expect(listOldStructure.introtext).toBe("<p>This is introtext</p>");
68
+
69
+ const listFromDataPlain = new ListModel({
70
+ key: "Books",
71
+ data: {
72
+ text: "<p>This is introtext</p>",
73
+ ...mockList.Books,
74
+ },
75
+ contributions: mockListContributions.Books,
76
+ });
77
+
78
+ expect(listFromDataPlain.introtext).toBe("<p>This is introtext</p>");
79
+
80
+ const listFromDataApplicationMessage = new ListModel({
81
+ key: "Books",
82
+ data: {
83
+ ...mockList.Books,
84
+ text: {
85
+ message: "<p>This is introtext</p>",
86
+ },
87
+ },
88
+ contributions: mockListContributions.Books,
89
+ });
90
+
91
+ expect(listFromDataApplicationMessage.introtext).toBe(
92
+ "<p>This is introtext</p>"
93
+ );
94
+
95
+ const listFromNewContributionsRawTextMessage = new ListModel({
96
+ key: "Books",
97
+ data: mockList.Books,
98
+ contributions: {
99
+ ...mockListContributions.Books,
100
+ text: {
101
+ message: "<p>This is introtext</p>",
102
+ },
103
+ },
104
+ });
105
+
106
+ expect(listFromNewContributionsRawTextMessage.introtext).toBe(
107
+ "<p>This is introtext</p>"
108
+ );
109
+
110
+ const listFromNewContributionsSimpleMessage = new ListModel({
111
+ key: "Books",
112
+ data: mockList.Books,
113
+ contributions: {
114
+ ...mockListContributions.Books,
115
+ text: "<p>This is introtext</p>",
116
+ },
117
+ });
118
+
119
+ expect(listFromNewContributionsSimpleMessage.introtext).toBe(
120
+ "<p>This is introtext</p>"
59
121
  );
60
122
  });
61
123
  });
@@ -5,7 +5,7 @@
5
5
  "texts": [
6
6
  {
7
7
  "type": "master",
8
- "text": "<p>This view contains all the data about this book. It contains a list of the creators and editions. A person can be an author(1) or an illustrator(2)<br /><br />This is a list of books that is ordered by the role (author (1), co-author, illustrator(2)) of the person that contributed to the book.<br /><br />1) An author is broadly defined as &quot;the person who originated or gave existence to anything&quot; and whose authorship determines responsibility for what was created. Narrowly defined, an author is the originator of any written work and can also be described as a writer.<br /><br />2) An illustrator is an artist who specializes in enhancing writing or elucidating concepts by providing a visual representation that corresponds to the content of the associated text or idea. The illustration may be intended to clarify complicated concepts or objects that are difficult to describe textually, which is the reason illustrations are often found in children&#39;s books.<br /></p>"
8
+ "text": "<p>This is introtext</p>"
9
9
  }
10
10
  ],
11
11
  "_links": {
@@ -6,7 +6,7 @@
6
6
  "texts": [
7
7
  {
8
8
  "type": "master",
9
- "text": "<p>This is a list of <em>books</em><br />For each book the <strong>contributers</strong> and the <strong>publishers</strong> are added as <u>additional details</u>.<br />For more information see amazon</p>"
9
+ "text": "<p>This is introtext</p>"
10
10
  }
11
11
  ],
12
12
  "actions": [
@@ -78,22 +78,23 @@ export default class GroupingPanelModel extends ResourceModel {
78
78
  * Check if an introtext exists for this caseview
79
79
  */
80
80
  hasIntroText(): boolean {
81
- return (
82
- this.contributions.texts &&
83
- this.contributions.texts.find((item) => item.type === "master")
84
- );
81
+ return this.introtext !== "";
85
82
  }
86
83
 
87
84
  /**
88
85
  * Getting the introduction text configured on the grouping panel
89
86
  */
90
87
  get introtext(): string {
91
- if (this.contributions.texts) {
92
- const text = this.contributions.texts.find(
93
- (item) => item.type === "master"
94
- );
88
+ if (this.data._text) {
89
+ return this.data._text.message ?? this.data._text;
90
+ }
91
+
92
+ if (this.contributions.text) {
93
+ return this.contributions.text.message ?? this.contributions.text;
94
+ }
95
95
 
96
- return text ? text.text : "";
96
+ if (Array.isArray(this.contributions.texts)) {
97
+ return this.contributions.texts[0].text;
97
98
  }
98
99
 
99
100
  return "";
@@ -1,5 +1,9 @@
1
1
  import GroupingPanelModel from "../GroupingPanelModel";
2
2
 
3
+ import panelJson from "./groupingPanel.json";
4
+ import panelContributionsJson from "./groupingPanelContributions.json";
5
+ import CaseViewModel from "../../caseview/CaseViewModel";
6
+
3
7
  describe("groupingPanelModel", () => {
4
8
  it("should be able to create an empty GroupingPanelModel object", () => {
5
9
  const groupingPanel = new GroupingPanelModel();
@@ -30,4 +34,90 @@ describe("groupingPanelModel", () => {
30
34
  })
31
35
  ).toBe(true);
32
36
  });
37
+
38
+ it("should be able to create a grouping panel from a typical modular UI json structure", () => {
39
+ const groupingPanel = new GroupingPanelModel({
40
+ key: "AskingQuestions",
41
+ data: panelJson,
42
+ contributions: panelContributionsJson,
43
+ });
44
+
45
+ expect(groupingPanel).toBeInstanceOf(GroupingPanelModel);
46
+
47
+ expect(groupingPanel.key).toBe("AskingQuestions");
48
+ expect(groupingPanel.label).toBe("Asking questions");
49
+
50
+ expect(groupingPanel.links).toHaveLength(8);
51
+ expect(groupingPanel.panelLinks).toHaveLength(1);
52
+
53
+ expect(groupingPanel.hasIntroText()).toBe(true);
54
+ });
55
+
56
+ it("should be able to handle different kind of introtext", () => {
57
+ const groupingPanelOldStructure = new CaseViewModel({
58
+ key: "Book",
59
+ data: panelJson,
60
+ contributions: panelContributionsJson,
61
+ });
62
+
63
+ expect(groupingPanelOldStructure.introtext).toBe(
64
+ "<p>This is introtext</p>"
65
+ );
66
+
67
+ const groupingPanelFromDataPlain = new CaseViewModel({
68
+ key: "Book",
69
+ data: {
70
+ _text: "<p>This is introtext</p>",
71
+ ...panelJson,
72
+ },
73
+ contributions: panelContributionsJson,
74
+ });
75
+
76
+ expect(groupingPanelFromDataPlain.introtext).toBe(
77
+ "<p>This is introtext</p>"
78
+ );
79
+
80
+ const groupingPanelFromDataApplicationMessage = new CaseViewModel({
81
+ key: "Book",
82
+ data: {
83
+ ...panelJson,
84
+ _text: {
85
+ message: "<p>This is introtext</p>",
86
+ },
87
+ },
88
+ contributions: panelContributionsJson,
89
+ });
90
+
91
+ expect(groupingPanelFromDataApplicationMessage.introtext).toBe(
92
+ "<p>This is introtext</p>"
93
+ );
94
+
95
+ const groupingPanelFromNewContributionsRawTextMessage = new CaseViewModel({
96
+ key: "Book",
97
+ data: panelJson,
98
+ contributions: {
99
+ ...panelContributionsJson,
100
+ text: {
101
+ message: "<p>This is introtext</p>",
102
+ },
103
+ },
104
+ });
105
+
106
+ expect(groupingPanelFromNewContributionsRawTextMessage.introtext).toBe(
107
+ "<p>This is introtext</p>"
108
+ );
109
+
110
+ const groupingPanelFromNewContributionsSimpleMessage = new CaseViewModel({
111
+ key: "Book",
112
+ data: panelJson,
113
+ contributions: {
114
+ ...panelContributionsJson,
115
+ text: "<p>This is introtext</p>",
116
+ },
117
+ });
118
+
119
+ expect(groupingPanelFromNewContributionsSimpleMessage.introtext).toBe(
120
+ "<p>This is introtext</p>"
121
+ );
122
+ });
33
123
  });
@@ -0,0 +1,30 @@
1
+ {
2
+ "_links": {
3
+ "self": { "href": "/iq-content/case/1/asking-questions" },
4
+ "api_doc": {
5
+ "href": "/api-docs/v3/iq-content/case/(case-id)/asking-questions"
6
+ },
7
+ "contributions": {
8
+ "href": "/contributions/iq-content/case/(case-id)/asking-questions"
9
+ },
10
+ "Decisions": { "href": "/iq-content/case/1/asking-questions/decisions" },
11
+ "taskgroup": [
12
+ {
13
+ "href": "/iq-content/case/1/asking-questions/labels",
14
+ "name": "Labels"
15
+ },
16
+ {
17
+ "href": "/iq-content/case/1/asking-questions/properties",
18
+ "name": "Properties"
19
+ },
20
+ {
21
+ "href": "/iq-content/case/1/asking-questions/sources",
22
+ "name": "Sources"
23
+ },
24
+ {
25
+ "href": "/iq-content/case/1/asking-questions/text-fragments",
26
+ "name": "TextFragments"
27
+ }
28
+ ]
29
+ }
30
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "label": "Asking questions",
3
+ "resourcetype": "GroupingPanel",
4
+ "layouthint": ["hint"],
5
+ "texts": [
6
+ {
7
+ "type": "master",
8
+ "text": "<p>This is introtext</p>"
9
+ }
10
+ ],
11
+ "_links": {
12
+ "panel": [
13
+ {
14
+ "name": "Decisions",
15
+ "label": "Decisions",
16
+ "resourcetype": "InstrumentResultListPanel"
17
+ }
18
+ ],
19
+ "taskgroup": [
20
+ {
21
+ "name": "Labels",
22
+ "label": "Labels",
23
+ "layouthint": ["not-in-dropdown"],
24
+ "resourcetype": "TaskGroup"
25
+ },
26
+ {
27
+ "name": "Properties",
28
+ "label": "Properties",
29
+ "layouthint": ["not-in-dropdown"],
30
+ "resourcetype": "TaskGroup"
31
+ },
32
+ {
33
+ "name": "Sources",
34
+ "label": "Sources",
35
+ "layouthint": ["not-in-dropdown"],
36
+ "resourcetype": "TaskGroup"
37
+ },
38
+ {
39
+ "name": "TextFragments",
40
+ "label": "Text fragments",
41
+ "layouthint": ["not-in-dropdown"],
42
+ "resourcetype": "TaskGroup"
43
+ }
44
+ ]
45
+ }
46
+ }
@@ -44,6 +44,7 @@ import type LookupOptionsModel from "./lookup/LookupOptionsModel";
44
44
  import type BaseFilterModel from "./filters/BaseFilterModel";
45
45
  import type AttributeCollection from "./attributes/AttributeCollection";
46
46
  import type AttributeModel from "./attributes/AttributeModel";
47
+ import type LayoutHintCollection from "./layouthint/LayoutHintCollection";
47
48
 
48
49
  export type ModularUIModel =
49
50
  | ApplicationModel
@@ -176,49 +177,75 @@ export type FilesizeConstraintsType = {
176
177
  };
177
178
 
178
179
  export type PropertyData = { type: string, label: string, value: string };
179
- export type TextFragmentData = { type: string, label: string, text: string };
180
+ export type TextFragmentData = {
181
+ type: string,
182
+ label: string,
183
+ text: string | { id?: string, message: string, properties?: Object },
184
+ };
180
185
  export type SectionData = {
181
186
  id: string,
182
187
  type: string,
183
188
  label?: string,
184
189
  number?: string,
185
- body: string,
190
+ body: string | { id?: string, message: string, properties?: Object },
186
191
  _links: { self: { href: string } },
187
192
  childSections: Array<SectionData>,
188
193
  subSections: Array<SectionData>,
189
194
  };
190
195
 
191
- export type PropertiesElement = {
192
- propertiesElement: {
196
+ export type PropertyElement = {
197
+ propertyElement: {
193
198
  label: string,
194
- id: string,
199
+ layouthint: Array<string>,
195
200
  properties: Array<PropertyData>,
196
201
  },
197
202
  };
198
203
  export type TextFragmentElement = {
199
204
  textFragmentElement: {
200
205
  label: string,
201
- id: string,
206
+ layouthint: Array<string>,
202
207
  textfragments: Array<TextFragmentData>,
203
208
  },
204
209
  };
205
210
  export type ContentElement = {
206
211
  contentElement: {
207
212
  label: string,
213
+ layouthint: Array<string>,
208
214
  sections: Array<SectionData>,
209
215
  },
210
216
  };
211
- export type ContentData = {
212
- label: string | null,
213
- elements: Array<PropertiesElement | TextFragmentElement | ContentElement>,
214
- };
215
217
 
218
+ type PropertyElementMapped = {
219
+ propertyElement: {
220
+ label: string,
221
+ layouthint: LayoutHintCollection,
222
+ properties: Array<PropertyData>,
223
+ },
224
+ };
225
+ type TextFragmentElementMapped = {
226
+ textFragmentElement: {
227
+ label: string,
228
+ layouthint: LayoutHintCollection,
229
+ textfragments: Array<TextFragmentData>,
230
+ },
231
+ };
216
232
  type ContentElementMapped = {
217
233
  contentElement: {
218
234
  label: string,
235
+ layouthint: LayoutHintCollection,
219
236
  sections: Array<SectionModel>,
220
237
  },
221
238
  };
239
+
222
240
  export type ContentAll = Array<
223
- PropertiesElement | TextFragmentElement | ContentElementMapped
241
+ PropertyElementMapped | TextFragmentElementMapped | ContentElementMapped
224
242
  >;
243
+
244
+ export type ContentData = {
245
+ header: {
246
+ label?: string,
247
+ description?: { id?: string, message: string, properties?: Object },
248
+ },
249
+ label?: string,
250
+ elements: Array<PropertyElement | TextFragmentElement | ContentElement>,
251
+ };
@@ -475,6 +475,7 @@ class ModularUIRequest {
475
475
 
476
476
  if (model instanceof FormModel) {
477
477
  const newData = JSON.parse(model.validationData);
478
+ // $FlowFixMe incompatible-call
478
479
  return JSON.stringify(deepmerge(prevData || {}, newData));
479
480
  }
480
481
 
@@ -0,0 +1,23 @@
1
+ // @flow
2
+ import { isPlainObject } from "./objects";
3
+
4
+ /**
5
+ * Handles text that is in the ApplicationMessage form ({ id: string, message: string, properties: object })
6
+ * @param text
7
+ * @returns {string}
8
+ */
9
+ export const retrieveText = (
10
+ text:
11
+ | string
12
+ | { id?: string, message: string, properties?: { [key: string]: any } }
13
+ ): string => {
14
+ if (typeof text === "string") {
15
+ return text;
16
+ }
17
+
18
+ if (isPlainObject(text) && "message" in text) {
19
+ return text.message;
20
+ }
21
+
22
+ return "";
23
+ };
@@ -18,6 +18,7 @@ export * from "./helpers/createHash";
18
18
  export { default as createUUID } from "./helpers/createUUID";
19
19
  export * from "./helpers/sanitizeHtml";
20
20
  export * from "./helpers/objects";
21
+ export * from "./helpers/text";
21
22
 
22
23
  // number
23
24
  export { default as DecimalFormat } from "./number/DecimalFormat";