@media-quest/builder 0.0.25 → 0.0.27

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 (55) hide show
  1. package/dist/public-api.d.ts +819 -0
  2. package/dist/public-api.js +2696 -0
  3. package/dist/public-api.js.map +1 -0
  4. package/package.json +20 -6
  5. package/src/Builder-option.ts +64 -64
  6. package/src/Builder-question.spec.ts +68 -68
  7. package/src/Builder-question.ts +98 -102
  8. package/src/Builder-schema.spec.ts +135 -144
  9. package/src/Builder-schema.ts +70 -69
  10. package/src/Builder-text.spec.ts +24 -24
  11. package/src/Builder-text.ts +57 -57
  12. package/src/BuilderObject.ts +30 -29
  13. package/src/builder-compiler.ts +1 -1
  14. package/src/code-book/codebook-variable.ts +27 -0
  15. package/src/code-book/codebook.ts +81 -0
  16. package/src/page/Builder-page-collection.spec.ts +209 -0
  17. package/src/page/Builder-page-collection.ts +113 -0
  18. package/src/page/Builder-page.spec.ts +163 -0
  19. package/src/{Builder-page.ts → page/Builder-page.ts} +74 -95
  20. package/src/primitives/ID.spec.ts +39 -39
  21. package/src/primitives/ID.ts +26 -10
  22. package/src/primitives/page-prefix.ts +59 -59
  23. package/src/primitives/varID.ts +12 -12
  24. package/src/public-api.ts +8 -6
  25. package/src/rulebuilder/Builder-rule.spec.ts +323 -323
  26. package/src/rulebuilder/Builder-rule.ts +191 -191
  27. package/src/rulebuilder/RuleAction.ts +105 -106
  28. package/src/rulebuilder/RuleBuilder-test-utils.ts +320 -320
  29. package/src/rulebuilder/RuleInput.ts +30 -30
  30. package/src/rulebuilder/RuleVariable.ts +34 -48
  31. package/src/rulebuilder/SingleSelectItem.ts +9 -8
  32. package/src/rulebuilder/condition/Builder-condition-group.ts +14 -6
  33. package/src/rulebuilder/condition/Builder-condition.spec.ts +12 -12
  34. package/src/rulebuilder/condition/Builder-condition.ts +17 -13
  35. package/src/rulebuilder/index.ts +16 -3
  36. package/src/rulebuilder/page-action-manager.ts +33 -33
  37. package/src/rulebuilder/rule2/Rule2.ts +211 -215
  38. package/src/schema-config.ts +25 -25
  39. package/src/sum-score/sum-score-answer.ts +6 -0
  40. package/src/sum-score/sum-score-variable-collection.spec.ts +68 -0
  41. package/src/sum-score/sum-score-variable-collection.ts +101 -0
  42. package/src/sum-score/sum-score-variable.spec.ts +253 -0
  43. package/src/sum-score/sum-score-variable.ts +98 -0
  44. package/src/{variable → sum-score}/sum-score.ts +57 -26
  45. package/src/tag/BuilderTag.ts +45 -0
  46. package/src/tag/Tag-Collection.ts +53 -0
  47. package/src/theme/default-theme-compiler.ts +358 -358
  48. package/tsconfig.json +19 -15
  49. package/src/Builder-page.spec.ts +0 -320
  50. package/src/BuilderTag.ts +0 -96
  51. package/src/codebook.ts +0 -72
  52. package/src/variable/b-variable.ts +0 -68
  53. package/src/variable/mq-variable.spec.ts +0 -147
  54. package/src/variable/sum-score-variable.ts +0 -50
  55. package/tsconfig.tsbuildinfo +0 -1
@@ -1,13 +1,13 @@
1
1
  import type { BuilderSchemaDto } from "./Builder-schema";
2
2
  import { BuilderSchema } from "./Builder-schema";
3
- import { BuilderPage } from "./Builder-page";
4
- import type { BuilderTagDto } from "./BuilderTag";
5
- import { BuilderTag } from "./BuilderTag";
3
+ import { BuilderPage } from "./page/Builder-page";
4
+ import type { BuilderTagDto } from "./tag/BuilderTag";
5
+ import { BuilderTag } from "./tag/BuilderTag";
6
6
  import { PagePrefix } from "./primitives/page-prefix";
7
7
  import { SchemaPrefix } from "./primitives/schema-prefix";
8
8
 
9
- import { SumScoreVariableDto } from "./variable/sum-score-variable";
10
- import { OptionID, PageID, QuestionID, SchemaID } from "./primitives/ID";
9
+ import { SumScoreVariableDto } from "./sum-score/sum-score-variable";
10
+ import { OptionID, PageID, QuestionID, SchemaID, SumScoreVariableID } from "./primitives/ID";
11
11
 
12
12
  const tag1: BuilderTagDto = BuilderTag.create("tag1", "This tag is defined in schemaDto1").toJson();
13
13
 
@@ -24,18 +24,18 @@ const schemaDto1: BuilderSchemaDto = {
24
24
  tags: [tag1, tag2, tag3],
25
25
  sumScoreVariables: [
26
26
  {
27
- kind: "numeric-variable",
28
- origin: "sum-score",
29
- label: "label for dummy variable",
30
- initialValue: 0,
31
- varId: "testId",
32
- basedOn: [],
27
+ id: SumScoreVariableID.dummy.a,
28
+ name: "label for dummy sum-score",
29
+ description: "testId",
30
+ useAvg: false,
31
+ // basedOn: [],
33
32
  },
34
33
  ],
35
34
  pages: [
36
35
  {
37
36
  id: PageID.validateOrCreate("a".repeat(24)),
38
37
  _type: "info-page",
38
+ includedInSumScores: [],
39
39
  prefix: PagePrefix.fromStringOrThrow("p1"),
40
40
  mainText: {
41
41
  text: "hello from test",
@@ -78,14 +78,14 @@ const schemaDto1: BuilderSchemaDto = {
78
78
  // { tag: 'can_read', description: 'The patient can read' },
79
79
  // { tag: 'is grown up', description: 'Is grownUp.' }
80
80
  ],
81
- questions: [],
82
81
  autoplaySequence: [],
83
82
  },
84
83
  {
85
- id: PageID.validateOrCreate("b".repeat(24)),
86
- _type: "multi-select",
84
+ id: PageID.dummy.b,
85
+ _type: "question",
87
86
  prefix: PagePrefix.fromStringOrThrow("page2-prefix"),
88
87
  tags: [tag3.tag],
88
+ includedInSumScores: [],
89
89
  mainText: {
90
90
  text: "hello from test",
91
91
  autoplay: false,
@@ -104,31 +104,6 @@ const schemaDto1: BuilderSchemaDto = {
104
104
  text: "q1",
105
105
  options: [],
106
106
  },
107
- questions: [
108
- {
109
- id: QuestionID.create(),
110
- prefix: "one-prefix",
111
- _type: "select-one",
112
- text: "q1-text",
113
- options: [
114
- {
115
- id: "opt-nei" as OptionID,
116
- value: 0,
117
- label: "Nei",
118
- },
119
- {
120
- id: "opt-ja" as OptionID,
121
- value: 1,
122
- label: "Ja",
123
- },
124
- {
125
- id: "opt-vet-ikke" as OptionID,
126
- value: 9,
127
- label: "Vet ikke",
128
- },
129
- ],
130
- },
131
- ],
132
107
  autoplaySequence: [],
133
108
  },
134
109
  ],
@@ -138,41 +113,41 @@ const schemaDto1: BuilderSchemaDto = {
138
113
  };
139
114
 
140
115
  const SCHEMA_ID = SchemaID.create();
141
- const schemaPrefixA = SchemaPrefix.castOrCreateRandom("a").value;
142
- let builderSchema = BuilderSchema.create(SCHEMA_ID, "test", schemaPrefixA);
116
+ const SCHEMA_PREFIX_A = SchemaPrefix.castOrCreateRandom("a").value;
117
+ let s1 = BuilderSchema.create(SCHEMA_ID, "test-name", SCHEMA_PREFIX_A);
143
118
 
144
119
  beforeEach(() => {
145
- builderSchema = BuilderSchema.create(SCHEMA_ID, "test-name", schemaPrefixA);
120
+ s1 = BuilderSchema.create(SCHEMA_ID, "test-name", SCHEMA_PREFIX_A);
146
121
  });
147
122
 
148
123
  describe("Builder schema", () => {
149
124
  test("Can add pages.", () => {
150
- builderSchema.addPage("question");
151
- builderSchema.addPage("info-page");
152
- expect(builderSchema.pages.length).toBe(2);
153
- const dto = builderSchema.compile().schema;
125
+ s1.addPage("question");
126
+ s1.addPage("info-page");
127
+ expect(s1.pages.length).toBe(2);
128
+ const dto = s1.compile().schema;
154
129
  expect(dto.pages.length).toBe(2);
155
- expect(dto.id).toBe(builderSchema.id);
156
- expect(dto.baseHeight).toBe(builderSchema.baseHeight);
157
- expect(dto.baseWidth).toBe(builderSchema.baseWidth);
158
- expect(dto.backgroundColor).toBe(builderSchema.backgroundColor);
130
+ expect(dto.id).toBe(s1.id);
131
+ expect(dto.baseHeight).toBe(s1.baseHeight);
132
+ expect(dto.baseWidth).toBe(s1.baseWidth);
133
+ expect(dto.backgroundColor).toBe(s1.backgroundColor);
159
134
  });
160
135
 
161
136
  test("Can delete page by passing reference", () => {
162
- const p1 = builderSchema.addPage("question");
163
- const p2 = builderSchema.addPage("question");
164
- const p3 = builderSchema.addPage("info-page");
165
- expect(builderSchema.pages.length).toBe(3);
166
- const result = builderSchema.deletePage(p1);
167
- expect(builderSchema.pages.length).toBe(2);
137
+ const p1 = s1.addPage("question");
138
+ const p2 = s1.addPage("question");
139
+ const p3 = s1.addPage("info-page");
140
+ expect(s1.pages.length).toBe(3);
141
+ const result = s1.deletePage(p1);
142
+ expect(s1.pages.length).toBe(2);
168
143
  expect(result).toBe(true);
169
- const result2 = builderSchema.deletePage(p2);
144
+ const result2 = s1.deletePage(p2);
170
145
  expect(result2).toBe(true);
171
- expect(builderSchema.pages.length).toBe(1);
172
- expect(builderSchema.pages[0]).toBe(p3);
173
- const result3 = builderSchema.deletePage(p2);
146
+ expect(s1.pages.length).toBe(1);
147
+ expect(s1.pages[0]).toBe(p3);
148
+ const result3 = s1.deletePage(p2);
174
149
  expect(result3).toBe(false);
175
- const result4 = builderSchema.deletePage(p3);
150
+ const result4 = s1.deletePage(p3);
176
151
  expect(result4).toBe(true);
177
152
  });
178
153
 
@@ -205,73 +180,76 @@ describe("Builder schema", () => {
205
180
  const json = s.toJson();
206
181
  expect(schemaDto1).toStrictEqual(json);
207
182
  });
183
+
208
184
  test("Can add page at concrete index", () => {
209
- const p1 = builderSchema.addPage("form");
210
- expect(p1.pageType).toBe("form");
211
- const p2 = builderSchema.addPage("multi-select", 0);
212
- expect(p2.pageType).toBe("multi-select");
213
- const pages = builderSchema.pages;
214
- expect(pages[0].id).toBe(p2.id);
215
- builderSchema.addPage("form");
216
- builderSchema.addPage("form");
217
- const last = builderSchema.addPage("form");
218
- expect(builderSchema.pages[builderSchema.pages.length - 1]).toBe(last);
219
- const p3 = builderSchema.addPage("info-page", 4);
220
- expect(pages[4].id).toBe(p3.id);
185
+ const p1 = s1.addPage("question");
186
+ expect(p1.pageType).toBe("question");
187
+ const p2 = s1.addPage("info-page", 0);
188
+ expect(p2.pageType).toBe("info-page");
189
+ // const pages = s1.pages;
190
+ expect(s1.pages[0].id).toBe(p2.id);
191
+ s1.addPage("question");
192
+ s1.addPage("question");
193
+ const last = s1.addPage("question");
194
+ expect(s1.pages[s1.pages.length - 1]).toBe(last);
195
+ const p3 = s1.addPage("info-page", 4);
196
+ expect(s1.pages[4].id).toBe(p3.id);
221
197
  });
198
+
222
199
  test("Can move page up and down", () => {
223
- const p1 = builderSchema.addPage("form");
224
- const p2 = builderSchema.addPage("form");
225
- const p3 = builderSchema.addPage("form");
226
- const p4 = builderSchema.addPage("multi-select");
227
- const last = builderSchema.addPage("form");
228
- const pages = builderSchema.pages;
229
- builderSchema.movePage(p2, 0);
230
- expect(pages[0]).toBe(p2);
231
- expect(pages[1]).toBe(p1);
232
- expect(builderSchema.movePage(p4, 4)).toBeTruthy();
233
- expect(builderSchema.movePage(p4, 5)).toBeFalsy();
234
- expect(builderSchema.movePage(p4, 10)).toBeFalsy();
200
+ const p1 = s1.addPage("question");
201
+ const p2 = s1.addPage("question");
202
+ const p3 = s1.addPage("question");
203
+ const p4 = s1.addPage("info-page");
204
+ const last = s1.addPage("question");
205
+ s1.movePage(p2, 0);
206
+ expect(s1.pages[0]).toBe(p2);
207
+ expect(s1.pages[1]).toBe(p1);
208
+ expect(s1.movePage(p4, 4)).toBeTruthy();
209
+ expect(s1.movePage(p4, 5)).toBeFalsy();
210
+ expect(s1.movePage(p4, 10)).toBeFalsy();
235
211
 
236
212
  // expect(pages[0].id).toBe(p4.id);
237
213
  });
214
+
238
215
  test("Can clone a page and insert at index", () => {
239
- const p1 = builderSchema.addPage("form");
240
- const p2 = builderSchema.addPage("form");
241
- const p3 = builderSchema.addPage("form");
216
+ const p1 = s1.addPage("question");
217
+ const p2 = s1.addPage("question");
218
+ const p3 = s1.addPage("question");
242
219
  const mainTextContent = "Hello from test";
243
- const p4 = builderSchema.addPage("multi-select");
220
+ const p4 = s1.addPage("info-page");
244
221
  p3.mainText.text = mainTextContent;
245
222
  const p1Clone = BuilderPage.fromJson(p1.clone());
246
- const beforeLen = builderSchema.pages.length;
247
- builderSchema.insertPage(p1Clone, 2);
248
- const pages = builderSchema.pages;
223
+ const beforeLen = s1.pages.length;
224
+ s1.insertPage(p1Clone, 2);
225
+ const pages = s1.pages;
249
226
  expect(beforeLen + 1).toBe(pages.length);
250
227
  expect(pages[2]).toBe(p1Clone);
251
228
  });
229
+
252
230
  test("Will not insert a page that is already in array.", () => {
253
- const p1 = builderSchema.addPage("form");
254
- const p2 = builderSchema.addPage("form");
255
- const p3 = builderSchema.addPage("form");
256
- const beforeLen = builderSchema.pages.length;
257
- const result = builderSchema.insertPage(p1, 0);
258
- const pages = builderSchema.pages;
231
+ const p1 = s1.addPage("question");
232
+ const p2 = s1.addPage("question");
233
+ const p3 = s1.addPage("question");
234
+ const beforeLen = s1.pages.length;
235
+ const result = s1.insertPage(p1, 0);
236
+ const pages = s1.pages;
259
237
  expect(beforeLen).toBe(pages.length);
260
238
  expect(result).toBe(false);
261
239
  });
262
240
 
263
241
  test("Can generate a info-page", () => {
264
- const p1 = builderSchema.addPage("info-page");
265
- const p2 = builderSchema.addPage("question");
242
+ const p1 = s1.addPage("info-page");
243
+ const p2 = s1.addPage("question");
266
244
  p2.defaultQuestion.addOption("Ja", 1, 0);
267
245
  p2.defaultQuestion.addOption("Nei", 0);
268
246
  p1.nextButton.label = "Neste";
269
- builderSchema.backgroundColor = "red";
270
- builderSchema.baseHeight = 600;
271
- builderSchema.baseWidth = 500;
247
+ s1.backgroundColor = "red";
248
+ s1.baseHeight = 600;
249
+ s1.baseWidth = 500;
272
250
  // builderSchema.prefix = "as";
273
- builderSchema.name = "depressed";
274
- const schema = builderSchema.compile().schema;
251
+ s1.name = "depressed";
252
+ const schema = s1.compile().schema;
275
253
  expect(schema.backgroundColor).toBe("red");
276
254
  expect(schema.baseHeight).toBe(600);
277
255
  expect(schema.baseWidth).toBe(500);
@@ -287,17 +265,17 @@ describe("Builder schema", () => {
287
265
  // expect(schemaP2.elements.length).toBe(options.length + 1);
288
266
  });
289
267
  test("Can get ruleInput!", () => {
290
- const p0 = builderSchema.addPage("info-page");
268
+ const p0 = s1.addPage("info-page");
291
269
  // p0.prefix = "info_page_prefix_";
292
- const p1 = builderSchema.addPage("question");
270
+ const p1 = s1.addPage("question");
293
271
  // p1.prefix = "p1_prefix_";
294
- const p2 = builderSchema.addPage("question");
272
+ const p2 = s1.addPage("question");
295
273
  // p2.prefix = "p2_prefix_";
296
274
  p1.defaultQuestion.addOption("Ja", 1, 0);
297
275
  p1.defaultQuestion.addOption("Nei", 0, 0);
298
276
  p2.defaultQuestion.addOption("Ja", 1, 0);
299
277
  p2.defaultQuestion.addOption("Nei", 0);
300
- const ruleInput = builderSchema.getRuleInput();
278
+ const ruleInput = s1.getRuleInput();
301
279
  expect(ruleInput.questionVars.length).toBe(2);
302
280
  expect(ruleInput.jumpToPageActions.length).toBe(3);
303
281
  // TODO add TAGS!!
@@ -314,44 +292,57 @@ describe("Builder schema", () => {
314
292
  expect(allPageIds.has(v.pageId)).toBe(true);
315
293
  });
316
294
  });
317
- test.skip("Can add sum-variables - and save as json", () => {
318
- // p0.prefix = "info_page_prefix_";
319
- const p1 = builderSchema.addPage("question");
320
- const p2 = builderSchema.addPage("question");
321
- p1.prefix = PagePrefix.fromStringOrThrow("p1_prefix");
322
- p2.prefix = PagePrefix.fromStringOrThrow("p2_prefix");
323
- p1.defaultQuestion.addOption("Ja", 1, 0);
324
- p1.defaultQuestion.addOption("Nei", 0, 0);
325
- p2.defaultQuestion.addOption("Ja", 1, 0);
326
- p2.defaultQuestion.addOption("Nei", 0);
327
295
 
328
- const ruleInput = builderSchema.getRuleInput();
329
- const ss1: SumScoreVariableDto = {
330
- label: "ss1",
331
- varId: "ss1_var_id",
332
- initialValue: 0,
333
- kind: "numeric-variable",
334
- origin: "sum-score",
335
- basedOn: [],
336
- };
296
+ test("Can add, update and delete sum-variable", () => {
297
+ const ssv = (name: string) =>
298
+ s1.sumScoreVariableCreate({ name, useAvg: true, description: "description for " + name });
337
299
 
338
- builderSchema.addSumScoreVariable(ss1);
300
+ const v1 = ssv("v1");
301
+ const v2 = ssv("v2");
302
+ const v3 = ssv("v3");
303
+ expect(s1.sumScoreVariables.length).toBe(3);
304
+ s1.sumScoreVariableUpdate(v1.id, { name: "updatedName" });
305
+ expect(s1.sumScoreVariables[0].name).toBe("updatedName");
306
+ const success = s1.sumScoreVariableDelete(v2.id);
307
+ expect(success).toBeTruthy();
308
+ expect(s1.sumScoreVariables.length).toBe(2);
309
+ const failure = s1.sumScoreVariableDelete(SumScoreVariableID.create());
310
+ expect(failure).toBeFalsy();
311
+ // s1.sumScoreVariableDelete(v2.id);
312
+ });
339
313
 
340
- expect(ruleInput.questionVars.length).toBe(2);
341
- expect(ruleInput.jumpToPageActions.length).toBe(3);
314
+ test("When a sum-score updates, then the pages update as well", () => {
315
+ const p1 = s1.addPage("question");
316
+ const v1 = s1.sumScoreVariableCreate({
317
+ name: "v1",
318
+ useAvg: true,
319
+ description: "description for v1",
320
+ });
321
+ expect(s1.sumScoreVariables.length).toBe(1);
322
+ expect(s1.pages.length).toBe(1);
323
+ const success = s1.sumScoreVariableAddToPage(v1, p1, 1);
324
+ expect(success).toBe(true);
325
+ expect(p1.includedInSumScores.length).toBe(1);
326
+ const updateSuccess = s1.sumScoreVariableUpdate(v1.id, {
327
+ name: "updated_name",
328
+ description: "updated_description",
329
+ useAvg: !v1.useAvg,
330
+ });
331
+ expect(updateSuccess).toBe(true);
332
+ expect(p1.includedInSumScores[0].name).toBe("updated_name");
333
+ expect(p1.includedInSumScores[0].description).toBe("updated_description");
334
+ });
342
335
 
343
- // TODO add TAGS!!
344
- // expect(ruleInput.excludeByTagActions.length).toBe(0);
345
- // expect(ruleInput.excludeByPageIdActions.length).toBe(3);
346
- // const allPageIds = new Set(ruleInput.jumpToPageActions.map((a) => a.pageId));
347
- // expect(allPageIds.has(p0.id)).toBe(true);
348
- // expect(allPageIds.has(p1.id)).toBe(true);
349
- // expect(allPageIds.has(p2.id)).toBe(true);
350
- // ruleInput.questionVars.forEach((v) => {
351
- // expect(allPageIds.has(v.varId)).toBe(true);
352
- // });
353
- // ruleInput.jumpToPageActions.forEach((v) => {
354
- // expect(allPageIds.has(v.pageId)).toBe(true);
355
- // });
336
+ test("When a sum-score is deleted, then pages will delete from included in sum-scores.", () => {
337
+ const p1 = s1.addPage("question");
338
+ const v1 = s1.sumScoreVariableCreate({
339
+ name: "v1",
340
+ useAvg: true,
341
+ description: "description for v1",
342
+ });
343
+ const success = s1.sumScoreVariableAddToPage(v1, p1, 1);
344
+ expect(success).toBe(true);
345
+ s1.sumScoreVariableDelete(v1.id);
346
+ expect(p1.includedInSumScores.length).toBe(0);
356
347
  });
357
348
  });
@@ -1,28 +1,31 @@
1
- import type { BuilderPageDto, BuilderPageType } from "./Builder-page";
2
- import { BuilderPage } from "./Builder-page";
1
+ import type { BuilderPageDto, BuilderPageType } from "./page/Builder-page";
2
+ import { BuilderPage } from "./page/Builder-page";
3
3
  import type {
4
4
  BuilderRuleDto,
5
- CustomVariable,
6
5
  ExcludeByPageAction,
7
6
  ExcludeByTagAction,
8
7
  JumpToPageAction,
8
+ RuleCustomVariable,
9
9
  } from "./rulebuilder";
10
10
  import { BuilderRule, RuleInput } from "./rulebuilder";
11
- import type { QuestionVariable } from "./rulebuilder/RuleVariable";
12
- import type { BuilderTagDto } from "./BuilderTag";
13
- import { BuilderTag, TagCollection } from "./BuilderTag";
11
+ import type { RuleQuestionVariable } from "./rulebuilder/RuleVariable";
12
+ import type { BuilderTagDto } from "./tag/BuilderTag";
13
+ import { BuilderTag } from "./tag/BuilderTag";
14
14
  import { DefaultThemeCompiler } from "./theme/default-theme-compiler";
15
15
  import { ImageFile } from "./media-files";
16
16
  import { DUtil } from "@media-quest/engine";
17
17
  import { PagePrefix } from "./primitives/page-prefix";
18
18
  import { SchemaPrefix, SchemaPrefixValue } from "./primitives/schema-prefix";
19
- import { CodeBook } from "./codebook";
20
- import { PredefinedVariable } from "./variable/b-variable";
19
+ import { CodeBook } from "./code-book/codebook";
20
+ import { CodebookPredefinedVariable } from "./code-book/codebook-variable";
21
21
  import { SchemaConfig } from "./schema-config";
22
22
  import { CompilerOption, CompilerOutput } from "./builder-compiler";
23
23
 
24
- import { SumScoreVariableDto } from "./variable/sum-score-variable";
25
- import { SchemaID } from "./primitives/ID";
24
+ import { SumScoreVariable, SumScoreVariableDto } from "./sum-score/sum-score-variable";
25
+ import { PageID, SchemaID, SumScoreVariableID } from "./primitives/ID";
26
+ import { SumScoreVariableCollection } from "./sum-score/sum-score-variable-collection";
27
+ import { TagCollection } from "./tag/Tag-Collection";
28
+ import { BuilderPageCollection } from "./page/Builder-page-collection";
26
29
 
27
30
  const U = DUtil;
28
31
 
@@ -32,34 +35,34 @@ export interface BuilderSchemaDto {
32
35
  readonly mainImage: ImageFile | false;
33
36
  readonly backgroundColor: string;
34
37
  readonly name: string;
35
- readonly pages: BuilderPageDto[];
38
+ readonly pages: ReadonlyArray<BuilderPageDto>;
36
39
  readonly baseHeight: number;
37
40
  readonly baseWidth: number;
38
- readonly predefinedVariables?: Array<PredefinedVariable>;
41
+ readonly predefinedVariables?: Array<CodebookPredefinedVariable>;
39
42
  readonly sumScoreVariables?: ReadonlyArray<SumScoreVariableDto>;
40
43
  readonly rules: ReadonlyArray<BuilderRuleDto>;
41
44
  readonly tags: ReadonlyArray<BuilderTagDto>;
42
45
  }
43
46
 
44
- class SumScoreVariableCollection {
45
- private _all: Array<SumScoreVariableDto> = [];
46
- }
47
-
48
47
  export class BuilderSchema {
49
48
  readonly prefix: SchemaPrefix;
50
49
  baseHeight = 1300;
51
50
  baseWidth = 1024;
52
51
  backgroundColor = "#000000";
53
- pages: BuilderPage[] = [];
52
+ private readonly _pageCollection: BuilderPageCollection;
54
53
  mainImage: ImageFile | false = false;
55
- predefinedVariables: PredefinedVariable[] = [];
54
+ predefinedVariables: CodebookPredefinedVariable[] = [];
56
55
  private _rules: BuilderRule[] = [];
57
- private _sumVariables: SumScoreVariableDto[] = [];
56
+ private readonly _sumScoreCollection;
58
57
  get rules(): ReadonlyArray<BuilderRule> {
59
58
  return [...this._rules];
60
59
  }
61
- get sumScoreVariables(): ReadonlyArray<SumScoreVariableDto> {
62
- return [...this._sumVariables];
60
+ get pages(): ReadonlyArray<BuilderPage> {
61
+ return [...this._pageCollection];
62
+ }
63
+
64
+ get sumScoreVariables(): ReadonlyArray<SumScoreVariable> {
65
+ return [...this._sumScoreCollection];
63
66
  }
64
67
 
65
68
  // get prefix(): SchemaPrefixValue {
@@ -78,29 +81,31 @@ export class BuilderSchema {
78
81
  public static fromJson(dto: BuilderSchemaDto): BuilderSchema {
79
82
  const schemaPrefix = SchemaPrefix.castOrCreateRandom(dto.prefix);
80
83
  const schema = new BuilderSchema(dto.id, dto.name, schemaPrefix);
81
- const pages = dto.pages.map(BuilderPage.fromJson);
84
+ const sumScoreVariables = dto.sumScoreVariables ? [...dto.sumScoreVariables] : [];
85
+ const pagesDto = Array.isArray(dto.pages) ? dto.pages : [];
82
86
 
87
+ // Init collections.
83
88
  schema._tagCollection.init(dto.tags);
89
+ schema._sumScoreCollection.init(sumScoreVariables);
90
+
84
91
  schema.backgroundColor = dto.backgroundColor;
85
92
  schema.baseHeight = dto.baseHeight;
86
93
  schema.baseWidth = dto.baseWidth;
87
- schema.pages = pages;
94
+ schema._pageCollection._init(pagesDto);
88
95
  schema.predefinedVariables = dto.predefinedVariables ?? [];
89
96
  schema.backgroundColor = dto.backgroundColor;
90
97
  schema.mainImage = dto.mainImage ?? false;
91
98
  const rulesDto = dto.rules ?? [];
92
99
  const ruleInput = schema.getRuleInput();
93
-
94
- schema._sumVariables = Array.isArray(dto.sumScoreVariables) ? [...dto.sumScoreVariables] : [];
95
100
  schema._rules = rulesDto.map((r) => BuilderRule.fromDto(r, ruleInput));
96
101
  return schema;
97
102
  }
98
103
 
99
104
  toJson(): BuilderSchemaDto {
100
- const pages = this.pages.map((p) => p.toJson());
105
+ const pages = this._pageCollection.toJson();
101
106
  const tags = this._tagCollection.toJson();
102
107
  const rules = this._rules.map((rule) => rule.toJson());
103
-
108
+ const sumScoreVariables = this._sumScoreCollection.toJson();
104
109
  const dto: BuilderSchemaDto = {
105
110
  backgroundColor: this.backgroundColor,
106
111
  baseHeight: this.baseHeight,
@@ -111,7 +116,7 @@ export class BuilderSchema {
111
116
  rules,
112
117
  tags,
113
118
  predefinedVariables: this.predefinedVariables,
114
- sumScoreVariables: [...this.sumScoreVariables],
119
+ sumScoreVariables,
115
120
  mainImage: this.mainImage,
116
121
  prefix: this.prefix.value,
117
122
  };
@@ -123,22 +128,31 @@ export class BuilderSchema {
123
128
  prefix: SchemaPrefix,
124
129
  ) {
125
130
  this.prefix = prefix;
131
+ this._sumScoreCollection = SumScoreVariableCollection.create([]);
132
+ this._pageCollection = BuilderPageCollection.create([]);
133
+ // this
126
134
  }
127
135
 
128
136
  addPage(type: BuilderPageType, atIndex = -1): BuilderPage {
129
- const pagePrefix = PagePrefix.create();
130
- const newPage = BuilderPage.create(type, pagePrefix.value);
131
- if (atIndex >= 0 && atIndex < this.pages.length) {
132
- this.pages.splice(atIndex, 0, newPage);
133
- } else {
134
- this.pages.push(newPage);
135
- }
136
- return newPage;
137
+ return this._pageCollection.add(type, atIndex);
137
138
  }
138
139
 
139
- addSumScoreVariable(variable: SumScoreVariableDto) {
140
+ sumScoreVariableCreate(options: { name: string; description: string; useAvg: boolean }) {
140
141
  // TODO VALIDATE.
141
- this._sumVariables.push({ ...variable });
142
+ // this._sumVariables.push({ ...variable });
143
+ const variable = this._sumScoreCollection.addNew(options);
144
+
145
+ return variable;
146
+ }
147
+ sumScoreVariableAddToPage(sumScoreVariable: SumScoreVariable, page: BuilderPage, weight: number) {
148
+ // this._pages.
149
+ return this._pageCollection.addSumScoreVariable(sumScoreVariable, page.id, weight);
150
+ }
151
+
152
+ sumScoreVariableUpdate(id: SumScoreVariableID, data: Partial<SumScoreVariableDto>) {
153
+ const didUpdate = this._sumScoreCollection._updateOne(id, data);
154
+ this._pageCollection.updateAllData({ sumScoreVariables: this._sumScoreCollection.asArray() });
155
+ return didUpdate;
142
156
  }
143
157
 
144
158
  insertPage(page: BuilderPage, atIndex: number): boolean {
@@ -146,16 +160,7 @@ export class BuilderSchema {
146
160
  }
147
161
 
148
162
  private insertPageAtIndex(page: BuilderPage, atIndex: number) {
149
- const isValidIndex = U.isInRange(0, this.pages.length - 1);
150
- if (!isValidIndex(atIndex)) {
151
- return false;
152
- }
153
- const exists = !!this.pages.find((p) => p.id === page.id);
154
- if (exists) {
155
- return false;
156
- }
157
- this.pages.splice(atIndex, 0, page);
158
- return true;
163
+ return this._pageCollection.insertPage(page, atIndex);
159
164
  }
160
165
 
161
166
  addRule() {
@@ -181,25 +186,11 @@ export class BuilderSchema {
181
186
  }
182
187
 
183
188
  movePage(page: BuilderPage, toIndex: number): boolean {
184
- const index = this.pages.indexOf(page);
185
- if (index < 0) {
186
- return false;
187
- }
188
- const isValidIndex = U.isInRange(0, this.pages.length - 1);
189
- if (!isValidIndex(toIndex)) {
190
- return false;
191
- }
192
- // console.log('Moving from :' + index + ' to: ' + toIndex);
193
- this.pages.splice(index, 1);
194
- this.pages.splice(toIndex, 0, page);
195
- return true;
189
+ return this._pageCollection.movePage(page, toIndex);
196
190
  }
197
191
 
198
192
  deletePage(page: BuilderPage): boolean {
199
- const filtered = this.pages.filter((p) => p !== page);
200
- const didDelete = filtered.length === this.pages.length - 1;
201
- this.pages = filtered;
202
- return didDelete;
193
+ return this._pageCollection.deleteById(page.id);
203
194
  }
204
195
 
205
196
  reevaluateRules() {
@@ -210,12 +201,12 @@ export class BuilderSchema {
210
201
  }
211
202
 
212
203
  getRuleInput(): RuleInput {
213
- const qVars: QuestionVariable[] = [];
214
- const cVars: CustomVariable[] = [];
204
+ const qVars: RuleQuestionVariable[] = [];
205
+ const cVars: RuleCustomVariable[] = [];
215
206
  const pageIdActions: ExcludeByPageAction[] = [];
216
207
  const tagActions: ExcludeByTagAction[] = this.tags.map((t) => {
217
208
  const tag = t.tagText;
218
- const pageCount = this.pages.reduce((count, curr) => {
209
+ const pageCount = this._pageCollection.pages.reduce((count, curr) => {
219
210
  return curr.tags.includes(tag) ? count + 1 : count;
220
211
  }, 0);
221
212
  const excludeByTagDto: ExcludeByTagAction = {
@@ -226,8 +217,10 @@ export class BuilderSchema {
226
217
  };
227
218
  return excludeByTagDto;
228
219
  });
220
+
229
221
  const jumpActions: JumpToPageAction[] = [];
230
- this.pages.forEach((page, index) => {
222
+
223
+ this._pageCollection.pages.forEach((page, index) => {
231
224
  const pageVariables = page.getQuestionVariables(this.prefix, index);
232
225
  qVars.push(...pageVariables);
233
226
  const mainText = page.mainText.text;
@@ -269,7 +262,7 @@ export class BuilderSchema {
269
262
  const builderSchema = BuilderSchema.fromJson(this.toJson());
270
263
 
271
264
  // Overriding the
272
- builderSchema.pages.forEach((p) => {
265
+ builderSchema._pageCollection.pages.forEach((p) => {
273
266
  if (options.blockAutoplayQuestion) {
274
267
  p.mainText.autoplay = false;
275
268
  }
@@ -289,4 +282,12 @@ export class BuilderSchema {
289
282
  const output: CompilerOutput = { codebook, schema, schemaConfig };
290
283
  return output;
291
284
  }
285
+
286
+ sumScoreVariableDelete(id: SumScoreVariableID) {
287
+ const didDelete = this._sumScoreCollection._deleteVariable(id);
288
+ const sumScoreVariables = [...this._sumScoreCollection];
289
+ this._pageCollection.updateAllData({ sumScoreVariables });
290
+ this._pageCollection.sumScoreVariableDelete(id);
291
+ return didDelete;
292
+ }
292
293
  }