case-editor-tools 1.0.0-beta.15 → 1.0.0-beta.16

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 (113) hide show
  1. package/.editorconfig +13 -0
  2. package/{index.d.ts → CHANGELOG.md} +0 -0
  3. package/LICENSE +202 -0
  4. package/package.json +3 -3
  5. package/publish.sh +9 -0
  6. package/readme.md +18 -0
  7. package/rollup.config.js +49 -0
  8. package/src/constants/key-definitions.ts +14 -0
  9. package/src/exporter/index.ts +101 -0
  10. package/{expression-utils/expressionGen.js → src/expression-utils/expressionGen.ts} +26 -29
  11. package/src/expression-utils/studyEngineExpressions.ts +359 -0
  12. package/src/index.ts +1 -0
  13. package/{logger/index.d.ts → src/logger/index.ts} +1 -1
  14. package/src/logger/logger.ts +31 -0
  15. package/{surveys/index.d.ts → src/surveys/index.ts} +3 -3
  16. package/src/surveys/survey-editor/component-editor.ts +133 -0
  17. package/{surveys/survey-editor/data-types.d.ts → src/surveys/survey-editor/data-types.ts} +18 -13
  18. package/src/surveys/survey-editor/item-editor.ts +529 -0
  19. package/src/surveys/survey-editor/survey-editor.ts +261 -0
  20. package/src/surveys/survey-engine-expressions.ts +483 -0
  21. package/src/surveys/survey-items.ts +1490 -0
  22. package/src/surveys/types/group.ts +73 -0
  23. package/{surveys/types/index.d.ts → src/surveys/types/index.ts} +4 -4
  24. package/src/surveys/types/item-properties.ts +204 -0
  25. package/{surveys/types/item.d.ts → src/surveys/types/item.ts} +42 -22
  26. package/src/surveys/types/survey-definition.ts +83 -0
  27. package/src/surveys/utils/componentGenerators.ts +76 -0
  28. package/src/surveys/utils/optionDefGenerators.ts +195 -0
  29. package/{surveys/utils/randomKeyGenerator.js → src/surveys/utils/randomKeyGenerator.ts} +9 -14
  30. package/src/surveys/utils/simple-generators.ts +106 -0
  31. package/src/surveys/utils/simple-question-editor.ts +52 -0
  32. package/{types/duration.js → src/types/duration.ts} +30 -27
  33. package/src/types/expression.ts +22 -0
  34. package/src/types/study.ts +17 -0
  35. package/src/types/studyRules.ts +39 -0
  36. package/tsconfig.json +100 -0
  37. package/constants/key-definitions.d.ts +0 -13
  38. package/constants/key-definitions.js +0 -32
  39. package/constants/key-definitions.js.map +0 -1
  40. package/exporter/index.d.ts +0 -2
  41. package/exporter/index.js +0 -99
  42. package/exporter/index.js.map +0 -1
  43. package/expression-utils/expressionGen.d.ts +0 -2
  44. package/expression-utils/expressionGen.js.map +0 -1
  45. package/expression-utils/studyEngineExpressions.d.ts +0 -114
  46. package/expression-utils/studyEngineExpressions.js +0 -283
  47. package/expression-utils/studyEngineExpressions.js.map +0 -1
  48. package/index.js +0 -3
  49. package/index.js.map +0 -1
  50. package/item-editor-7f825952.js +0 -522
  51. package/item-editor-7f825952.js.map +0 -1
  52. package/logger/index.js +0 -10
  53. package/logger/index.js.map +0 -1
  54. package/logger/logger.d.ts +0 -9
  55. package/logger/logger.js +0 -31
  56. package/logger/logger.js.map +0 -1
  57. package/surveys/index.js +0 -26
  58. package/surveys/index.js.map +0 -1
  59. package/surveys/survey-editor/component-editor.d.ts +0 -84
  60. package/surveys/survey-editor/component-editor.js +0 -112
  61. package/surveys/survey-editor/component-editor.js.map +0 -1
  62. package/surveys/survey-editor/data-types.js +0 -3
  63. package/surveys/survey-editor/data-types.js.map +0 -1
  64. package/surveys/survey-editor/item-editor.d.ts +0 -65
  65. package/surveys/survey-editor/item-editor.js +0 -13
  66. package/surveys/survey-editor/item-editor.js.map +0 -1
  67. package/surveys/survey-editor/survey-editor.d.ts +0 -43
  68. package/surveys/survey-editor/survey-editor.js +0 -231
  69. package/surveys/survey-editor/survey-editor.js.map +0 -1
  70. package/surveys/survey-engine-expressions.d.ts +0 -120
  71. package/surveys/survey-engine-expressions.js +0 -407
  72. package/surveys/survey-engine-expressions.js.map +0 -1
  73. package/surveys/survey-items.d.ts +0 -132
  74. package/surveys/survey-items.js +0 -1018
  75. package/surveys/survey-items.js.map +0 -1
  76. package/surveys/types/group.d.ts +0 -23
  77. package/surveys/types/group.js +0 -71
  78. package/surveys/types/group.js.map +0 -1
  79. package/surveys/types/index.js +0 -20
  80. package/surveys/types/index.js.map +0 -1
  81. package/surveys/types/item-properties.d.ts +0 -189
  82. package/surveys/types/item-properties.js +0 -3
  83. package/surveys/types/item-properties.js.map +0 -1
  84. package/surveys/types/item.js +0 -34
  85. package/surveys/types/item.js.map +0 -1
  86. package/surveys/types/survey-definition.d.ts +0 -19
  87. package/surveys/types/survey-definition.js +0 -60
  88. package/surveys/types/survey-definition.js.map +0 -1
  89. package/surveys/utils/componentGenerators.d.ts +0 -24
  90. package/surveys/utils/componentGenerators.js +0 -58
  91. package/surveys/utils/componentGenerators.js.map +0 -1
  92. package/surveys/utils/optionDefGenerators.d.ts +0 -68
  93. package/surveys/utils/optionDefGenerators.js +0 -162
  94. package/surveys/utils/optionDefGenerators.js.map +0 -1
  95. package/surveys/utils/randomKeyGenerator.d.ts +0 -1
  96. package/surveys/utils/randomKeyGenerator.js.map +0 -1
  97. package/surveys/utils/simple-generators.d.ts +0 -13
  98. package/surveys/utils/simple-generators.js +0 -102
  99. package/surveys/utils/simple-generators.js.map +0 -1
  100. package/surveys/utils/simple-question-editor.d.ts +0 -14
  101. package/surveys/utils/simple-question-editor.js +0 -45
  102. package/surveys/utils/simple-question-editor.js.map +0 -1
  103. package/types/duration.d.ts +0 -9
  104. package/types/duration.js.map +0 -1
  105. package/types/expression.d.ts +0 -4
  106. package/types/expression.js +0 -23
  107. package/types/expression.js.map +0 -1
  108. package/types/study.d.ts +0 -13
  109. package/types/study.js +0 -3
  110. package/types/study.js.map +0 -1
  111. package/types/studyRules.d.ts +0 -8
  112. package/types/studyRules.js +0 -32
  113. package/types/studyRules.js.map +0 -1
@@ -0,0 +1,529 @@
1
+ import { SurveyItem, SurveyGroupItem, SurveyItemTypes, Expression, Validation, ItemComponent, SurveySingleItem, ItemGroupComponent, ExpressionName, ResponseComponent, isItemGroupComponent } from "survey-engine/lib/data_types";
2
+ import { NewItemProps, NewComponentProps } from "./data-types";
3
+ import { ComponentEditor } from "./component-editor";
4
+ import { generateRandomKey } from "../utils/randomKeyGenerator";
5
+ import { Logger } from "../../logger/logger";
6
+
7
+
8
+ interface ItemEditorInt {
9
+ getItem: () => SurveyItem;
10
+ getItemJSON: (pretty?: boolean) => string;
11
+
12
+ setKey: (newKey: string) => void;
13
+
14
+ addToFollows: (key: string) => void;
15
+ removeFromFollows: (key: string) => void;
16
+ clearFollows: () => void;
17
+
18
+ setCondition: (exp: Expression | undefined) => void;
19
+ setPriority: (prio: number | undefined) => void;
20
+
21
+ setVersion: (version: number) => void;
22
+ setVersionTags: (tags: string[]) => void;
23
+
24
+ // methods for survey group items:
25
+ addSurveyItem: (item: SurveyItem, atPosition?: number) => void;
26
+ updateSurveyItem: (item: SurveyItem) => void;
27
+ removeItem: (key: string) => void;
28
+ changeItemPosition: (key: string, newPosition: number) => void;
29
+
30
+ setSelectionMethod: (exp: Expression | undefined) => void;
31
+
32
+ // methods for survey single items:
33
+ setItemType: (type: SurveyItemTypes) => void;
34
+
35
+ // fixed components:
36
+ setTitleComponent: (title: ItemComponent) => void;
37
+ setHelpGroupComponent: (helpGroup: ItemGroupComponent) => void;
38
+ // for warning, error, texts:
39
+ addDisplayComponent: (comp: ItemComponent, atPosition?: number) => void;
40
+ updateDisplayComponent: (at: number, comp: ItemComponent) => void;
41
+ removeDisplayComponent: (at: number) => void;
42
+ // response components:
43
+ addNewResponseComponent: (props: NewComponentProps, parentKey?: string, atPosition?: number) => ItemComponent | undefined;
44
+ addExistingResponseComponent: (newComp: ItemComponent, parentKey?: string, atPosition?: number) => ItemComponent | undefined;
45
+ updateResponseComponent: (path: string, item: ItemComponent) => void;
46
+ removeResponseComponent: (key: string) => void;
47
+ findResponseComponent: (key: string) => ItemComponent | undefined;
48
+
49
+ addValidation: (v: Validation) => void;
50
+ removeValidation: (vKey: string) => void;
51
+ }
52
+
53
+ const initialRootComp = () => {
54
+ return {
55
+ role: 'root',
56
+ order: { name: 'sequential' as ExpressionName },
57
+ items: []
58
+ }
59
+ };
60
+
61
+ export class ItemEditor implements ItemEditorInt {
62
+ private surveyItem: SurveyItem;
63
+
64
+ constructor(existingItem?: SurveyItem, newItem?: NewItemProps) {
65
+ this.surveyItem = { key: '', version: 0 };
66
+ if (existingItem) {
67
+ this.surveyItem = { ...existingItem };
68
+ // console.log(this.surveyItem);
69
+ } else {
70
+ const key = newItem?.itemKey ? newItem.itemKey : 'no key';
71
+ if (newItem?.isGroup) {
72
+ const currentItem: SurveyGroupItem = {
73
+ key,
74
+ version: 1,
75
+ items: [],
76
+ }
77
+ this.surveyItem = currentItem;
78
+ } else {
79
+ const currentItem: SurveyItem = {
80
+ key,
81
+ version: 1,
82
+ }
83
+ if (newItem?.type) {
84
+ currentItem.type = newItem.type;
85
+ }
86
+ this.surveyItem = currentItem;
87
+ }
88
+ }
89
+ }
90
+
91
+ getItem(): SurveyItem {
92
+ return { ...this.surveyItem };
93
+ }
94
+
95
+ getItemJSON(pretty?: boolean): string {
96
+ return JSON.stringify(this.surveyItem, undefined, pretty ? ' ' : undefined);
97
+ }
98
+
99
+ setKey(newKey: string) {
100
+ this.surveyItem.key = newKey;
101
+ }
102
+
103
+ addToFollows(key: string) {
104
+ if (!this.surveyItem.follows) {
105
+ this.surveyItem.follows = [];
106
+ }
107
+ if (this.surveyItem.follows.includes(key)) {
108
+ console.warn('follows array already includes key: ', key);
109
+ return;
110
+ }
111
+ this.surveyItem.follows.push(key);
112
+ }
113
+
114
+ removeFromFollows(key: string) {
115
+ if (!this.surveyItem.follows) {
116
+ console.warn('follows array already empty');
117
+ return
118
+ }
119
+ if (!this.surveyItem.follows.includes(key)) {
120
+ console.warn('follows array does not include key: ', key);
121
+ return
122
+ }
123
+ this.surveyItem.follows = this.surveyItem.follows.filter(k => k !== key);
124
+ };
125
+
126
+ clearFollows() {
127
+ if (!this.surveyItem.follows) {
128
+ console.warn('follows array already empty');
129
+ return
130
+ }
131
+ this.surveyItem.follows = undefined;
132
+ };
133
+
134
+ setCondition(exp: Expression | undefined) {
135
+ this.surveyItem.condition = exp;
136
+ };
137
+
138
+ setPriority(prio: number | undefined) {
139
+ this.surveyItem.priority = prio;
140
+ };
141
+
142
+ setVersion(version: number) {
143
+ this.surveyItem.version = version;
144
+ };
145
+
146
+ setVersionTags(tags: string[]) {
147
+ this.surveyItem.versionTags = [...tags];
148
+ };
149
+
150
+ // methods for survey group items:
151
+ addSurveyItem(item: SurveyItem, atPosition?: number) {
152
+ if (atPosition !== undefined) {
153
+ (this.surveyItem as SurveyGroupItem).items.splice(atPosition, 0, { ...item });
154
+ } else {
155
+ (this.surveyItem as SurveyGroupItem).items.push({ ...item });
156
+ }
157
+ };
158
+
159
+ updateSurveyItem(item: SurveyItem) {
160
+ const ind = (this.surveyItem as SurveyGroupItem).items.findIndex(it => item.key === it.key);
161
+ if (ind < 0) {
162
+ console.warn('item not found in the items array');
163
+ return;
164
+ }
165
+ (this.surveyItem as SurveyGroupItem).items[ind] = { ...item };
166
+ };
167
+
168
+ removeItem(key: string) {
169
+ if (!(this.surveyItem as SurveyGroupItem).items.find(it => it.key === key)) {
170
+ console.warn('group items does not contain item with key: ', key);
171
+ return;
172
+ }
173
+ (this.surveyItem as SurveyGroupItem).items = (this.surveyItem as SurveyGroupItem).items.filter(it => it.key !== key);
174
+ };
175
+
176
+ changeItemPosition(key: string, newPosition: number) {
177
+ console.warn('unimplemented');
178
+ };
179
+
180
+ setSelectionMethod(exp: Expression | undefined) {
181
+ (this.surveyItem as SurveyGroupItem).selectionMethod = exp;
182
+ };
183
+
184
+
185
+ // methods for survey single items:
186
+ setItemType(type: SurveyItemTypes) {
187
+ (this.surveyItem as SurveySingleItem).type = type;
188
+ };
189
+
190
+ setTitleComponent(title: ItemComponent) {
191
+ const currentItem = (this.surveyItem as SurveySingleItem);
192
+ if (!currentItem.components) {
193
+ currentItem.components = { ...initialRootComp() }
194
+ }
195
+ title.role = 'title';
196
+ const ind = currentItem.components.items.findIndex(comp => comp.role === 'title');
197
+ if (ind < 0) {
198
+ currentItem.components.items.push({ ...title });
199
+ return;
200
+ }
201
+ currentItem.components.items[ind] = { ...title };
202
+ }
203
+
204
+ setHelpGroupComponent(helpGroup: ItemGroupComponent) {
205
+ const currentItem = (this.surveyItem as SurveySingleItem);
206
+ if (!currentItem.components) {
207
+ currentItem.components = { ...initialRootComp() }
208
+ }
209
+ helpGroup.role = 'helpGroup';
210
+ const ind = currentItem.components.items.findIndex(comp => comp.role === 'helpGroup');
211
+ if (ind < 0) {
212
+ currentItem.components.items.push({ ...helpGroup });
213
+ return;
214
+ }
215
+ currentItem.components.items[ind] = { ...helpGroup };
216
+ };
217
+
218
+ // for warning, error, texts:
219
+ addDisplayComponent(comp: ItemComponent, atPosition?: number) {
220
+ const currentItem = (this.surveyItem as SurveySingleItem);
221
+ if (!currentItem.components) {
222
+ currentItem.components = { ...initialRootComp() }
223
+ }
224
+ if (atPosition !== undefined) {
225
+ currentItem.components.items.splice(atPosition, 0, { ...comp });
226
+ } else {
227
+ currentItem.components.items.push({ ...comp });
228
+ }
229
+ };
230
+
231
+ updateDisplayComponent(at: number, comp: ItemComponent) {
232
+ const currentItem = (this.surveyItem as SurveySingleItem);
233
+ if (!currentItem.components || !currentItem.components.items || currentItem.components.items.length <= at + 1 || at < 0) {
234
+ console.warn('component not found at ', at);
235
+ return;
236
+ }
237
+ currentItem.components.items[at] = { ...comp };
238
+ };
239
+
240
+ removeDisplayComponent(at: number) {
241
+ const currentItem = (this.surveyItem as SurveySingleItem);
242
+ if (!currentItem.components || !currentItem.components.items || currentItem.components.items.length <= at + 1 || at < 0) {
243
+ console.warn('component not found at ', at);
244
+ return;
245
+ }
246
+ currentItem.components.items.splice(at, 1);
247
+ };
248
+
249
+ addNewResponseComponent(props: NewComponentProps, parentKey?: string, atPosition?: number): ItemComponent | undefined {
250
+ const currentItem = (this.surveyItem as SurveySingleItem);
251
+ if (!currentItem.components) {
252
+ currentItem.components = { ...initialRootComp() }
253
+ }
254
+
255
+ if (!parentKey) {
256
+ props.role = 'responseGroup';
257
+ if (!props.key) {
258
+ props.key = 'rg';
259
+ }
260
+ props.isGroup = true;
261
+ const newComponent = (new ComponentEditor(undefined, props)).getComponent() as ItemGroupComponent;
262
+ const ind = currentItem.components.items.findIndex(comp => comp.role === 'responseGroup');
263
+ if (ind < 0) {
264
+ currentItem.components.items.push(newComponent);
265
+ return { ...newComponent };
266
+ }
267
+ currentItem.components.items[ind] = newComponent;
268
+ return { ...newComponent };
269
+ }
270
+
271
+ const ids = parentKey.split('.');
272
+
273
+ let obj: ItemComponent | undefined = undefined;
274
+ for (const currentKey of ids) {
275
+ if (!obj) {
276
+ const ind = currentItem.components.items.findIndex(c => c.key === currentKey);
277
+ if (ind < 0) {
278
+ console.warn('response component not found: ', currentKey);
279
+ return;
280
+ }
281
+ obj = currentItem.components.items[ind] as ResponseComponent;
282
+ continue;
283
+ }
284
+ if (!isItemGroupComponent(obj)) {
285
+ (obj as ItemGroupComponent).items = [];
286
+ // leaf found
287
+ break;
288
+ }
289
+ const index = obj.items.findIndex(it => it.key === currentKey);
290
+ if (index < 0) {
291
+ console.warn('item component cannot be found: ', currentKey);
292
+ return;
293
+ }
294
+ obj = (obj.items[index] as ItemGroupComponent);
295
+ }
296
+ if (!obj) {
297
+ console.warn('survey item cannot be found: ', parentKey);
298
+ return
299
+ }
300
+
301
+ if ((obj as ItemGroupComponent).items.find(it => props.key === it.key)) {
302
+ Logger.criticalError('Duplicate key: ' + props.key);
303
+ return undefined;
304
+ }
305
+
306
+ const newComponent = (new ComponentEditor(undefined, props)).getComponent() as ResponseComponent;
307
+ if (atPosition !== undefined) {
308
+ (obj as ItemGroupComponent).items.splice(atPosition, 0, newComponent);
309
+ } else {
310
+ (obj as ItemGroupComponent).items.push(newComponent);
311
+ }
312
+ return newComponent;
313
+ };
314
+
315
+ addExistingResponseComponent(newComp: ItemComponent, parentKey?: string, atPosition?: number): ItemComponent | undefined {
316
+ const currentItem = (this.surveyItem as SurveySingleItem);
317
+ if (!currentItem.components) {
318
+ currentItem.components = { ...initialRootComp() }
319
+ }
320
+
321
+ if (newComp.key === undefined) {
322
+ newComp.key = generateRandomKey(4);
323
+ }
324
+
325
+ if (!parentKey) {
326
+ const ind = currentItem.components.items.findIndex(comp => comp.role === 'responseGroup');
327
+ if (ind < 0) {
328
+ currentItem.components.items.push(newComp);
329
+ return { ...newComp };
330
+ }
331
+ currentItem.components.items[ind] = newComp;
332
+ return { ...newComp };
333
+ }
334
+
335
+ const ids = parentKey.split('.');
336
+
337
+ let obj: ItemComponent | undefined = undefined;
338
+ for (const currentKey of ids) {
339
+ if (!obj) {
340
+ const ind = currentItem.components.items.findIndex(c => c.key === currentKey);
341
+ if (ind < 0) {
342
+ console.warn('response component not found: ', currentKey);
343
+ return;
344
+ }
345
+ obj = currentItem.components.items[ind] as ResponseComponent;
346
+ continue;
347
+ }
348
+ if (!isItemGroupComponent(obj)) {
349
+ (obj as ItemGroupComponent).items = [];
350
+ // leaf found
351
+ break;
352
+ }
353
+ const index = obj.items.findIndex(it => it.key === currentKey);
354
+ if (index < 0) {
355
+ console.warn('item component cannot be found: ', currentKey);
356
+ return;
357
+ }
358
+ obj = (obj.items[index] as ItemGroupComponent);
359
+ }
360
+ if (!obj) {
361
+ console.warn('item component cannot be found: ', parentKey);
362
+ return
363
+ }
364
+
365
+ if ((obj as ItemGroupComponent).items.find(it => newComp.key === it.key)) {
366
+ Logger.criticalError('Duplicate key: ' + newComp.key);
367
+ return undefined;
368
+ }
369
+
370
+ if (atPosition !== undefined) {
371
+ (obj as ItemGroupComponent).items.splice(atPosition, 0, newComp);
372
+ } else {
373
+ (obj as ItemGroupComponent).items.push(newComp);
374
+ }
375
+ return newComp;
376
+ };
377
+
378
+ updateResponseComponent(path: string, item: ItemComponent) {
379
+
380
+ const currentItem = (this.surveyItem as SurveySingleItem);
381
+ if (!currentItem.components) { return; }
382
+
383
+ const responseGroup = currentItem.components.items.find(comp => comp.role === 'responseGroup');
384
+ if (!responseGroup) {
385
+ console.warn('no responseGroup found');
386
+ return;
387
+ }
388
+
389
+ if (responseGroup.key === path) {
390
+ const ind = currentItem.components.items.findIndex(it => it.key === path)
391
+ if (ind < 0) {
392
+ console.warn('item component cannot be found: ', path);
393
+ return;
394
+ }
395
+ currentItem.components.items[ind] = { ...item };
396
+ return;
397
+ }
398
+
399
+ const ids = path.split('.');
400
+ const parentIds = ids.slice(1, ids.length - 1);
401
+
402
+ let obj: ItemComponent | undefined = responseGroup;
403
+ for (const currentKey of parentIds) {
404
+ if (!isItemGroupComponent(obj)) {
405
+ // leaf found
406
+ break;
407
+ }
408
+ const index = obj.items.findIndex(it => it.key === currentKey);
409
+ if (index < 0) {
410
+ console.warn('item component cannot be found: ', currentKey);
411
+ return;
412
+ }
413
+ obj = (obj.items[index] as ItemGroupComponent);
414
+ }
415
+ if (!obj) {
416
+ console.warn('survey item cannot be found: ', path);
417
+ return
418
+ }
419
+
420
+ const ind = (obj as ItemGroupComponent).items.findIndex(it => it.key === ids[ids.length - 1])
421
+ if (ind < 0) {
422
+ console.warn('item component cannot be found: ', path);
423
+ return;
424
+ }
425
+ (obj as ItemGroupComponent).items[ind] = { ...item };
426
+ };
427
+
428
+ removeResponseComponent(keyPath: string) {
429
+ const currentItem = (this.surveyItem as SurveySingleItem);
430
+ if (!currentItem.components) { return; }
431
+
432
+ const responseGroup = currentItem.components.items.find(comp => comp.role === 'responseGroup');
433
+ if (!responseGroup) {
434
+ console.warn('no responseGroup found');
435
+ return;
436
+ }
437
+
438
+ if (responseGroup.key === keyPath) {
439
+ currentItem.components.items = currentItem.components.items.filter(it => it.role !== 'responseGroup');
440
+ return;
441
+ }
442
+
443
+ const ids = keyPath.split('.');
444
+ const parentIds = ids.slice(1, ids.length - 1);
445
+
446
+ let obj: ItemComponent | undefined = responseGroup;
447
+ for (const currentKey of parentIds) {
448
+ if (!isItemGroupComponent(obj)) {
449
+ // leaf found
450
+ break;
451
+ }
452
+ const index = obj.items.findIndex(it => it.key === currentKey);
453
+ if (index < 0) {
454
+ console.warn('item component cannot be found: ', currentKey);
455
+ return;
456
+ }
457
+ obj = (obj.items[index] as ItemGroupComponent);
458
+ }
459
+ if (!obj) {
460
+ console.warn('survey item cannot be found: ', keyPath);
461
+ return
462
+ }
463
+
464
+ (obj as ItemGroupComponent).items = (obj as ItemGroupComponent).items.filter(comp => comp.key !== ids[ids.length - 1]);
465
+ };
466
+
467
+ findResponseComponent(key: string): ItemComponent | undefined {
468
+ const currentItem = (this.surveyItem as SurveySingleItem);
469
+ if (!currentItem.components) { return; }
470
+
471
+ const ids = key.split('.');
472
+
473
+ let obj: ItemComponent | undefined = undefined;
474
+ for (const currentKey of ids) {
475
+ if (!obj) {
476
+ const ind = currentItem.components.items.findIndex(c => c.key === currentKey);
477
+ if (ind < 0) {
478
+ console.warn('item component not found: ', currentKey);
479
+ return;
480
+ }
481
+ obj = currentItem.components.items[ind] as ResponseComponent;
482
+ continue;
483
+ }
484
+ if (!isItemGroupComponent(obj)) {
485
+ (obj as ItemGroupComponent).items = [];
486
+ // leaf found
487
+ break;
488
+ }
489
+ const index = obj.items.findIndex(it => it.key === currentKey);
490
+ if (index < 0) {
491
+ console.warn('item component cannot be found: ', currentKey);
492
+ return;
493
+ }
494
+ obj = (obj.items[index] as ItemGroupComponent);
495
+ }
496
+ if (!obj) {
497
+ console.warn('item component cannot be found: ', key);
498
+ return
499
+ }
500
+ return obj;
501
+ };
502
+
503
+ addValidation(v: Validation) {
504
+ const currentItem = (this.surveyItem as SurveySingleItem);
505
+ if (!currentItem.validations) {
506
+ currentItem.validations = []
507
+ }
508
+ if (currentItem.validations.find(valid => v.key === valid.key)) {
509
+ console.warn('validation key already used: ', v.key);
510
+ return
511
+ }
512
+ currentItem.validations.push({ ...v });
513
+ this.surveyItem = { ...currentItem };
514
+ };
515
+
516
+ removeValidation(vKey: string) {
517
+ const currentItem = (this.surveyItem as SurveySingleItem);
518
+ if (!currentItem.validations) {
519
+ console.warn('validation key not found used: ', vKey);
520
+ return
521
+ }
522
+ if (currentItem.validations.find(valid => vKey === valid.key)) {
523
+ console.warn('validation key not found used: ', vKey);
524
+ return
525
+ }
526
+ currentItem.validations = currentItem.validations.filter(v => v.key !== vKey);
527
+ this.surveyItem = { ...currentItem };
528
+ };
529
+ }