@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.
- package/dist/public-api.d.ts +819 -0
- package/dist/public-api.js +2696 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +20 -6
- package/src/Builder-option.ts +64 -64
- package/src/Builder-question.spec.ts +68 -68
- package/src/Builder-question.ts +98 -102
- package/src/Builder-schema.spec.ts +135 -144
- package/src/Builder-schema.ts +70 -69
- package/src/Builder-text.spec.ts +24 -24
- package/src/Builder-text.ts +57 -57
- package/src/BuilderObject.ts +30 -29
- package/src/builder-compiler.ts +1 -1
- package/src/code-book/codebook-variable.ts +27 -0
- package/src/code-book/codebook.ts +81 -0
- package/src/page/Builder-page-collection.spec.ts +209 -0
- package/src/page/Builder-page-collection.ts +113 -0
- package/src/page/Builder-page.spec.ts +163 -0
- package/src/{Builder-page.ts → page/Builder-page.ts} +74 -95
- package/src/primitives/ID.spec.ts +39 -39
- package/src/primitives/ID.ts +26 -10
- package/src/primitives/page-prefix.ts +59 -59
- package/src/primitives/varID.ts +12 -12
- package/src/public-api.ts +8 -6
- package/src/rulebuilder/Builder-rule.spec.ts +323 -323
- package/src/rulebuilder/Builder-rule.ts +191 -191
- package/src/rulebuilder/RuleAction.ts +105 -106
- package/src/rulebuilder/RuleBuilder-test-utils.ts +320 -320
- package/src/rulebuilder/RuleInput.ts +30 -30
- package/src/rulebuilder/RuleVariable.ts +34 -48
- package/src/rulebuilder/SingleSelectItem.ts +9 -8
- package/src/rulebuilder/condition/Builder-condition-group.ts +14 -6
- package/src/rulebuilder/condition/Builder-condition.spec.ts +12 -12
- package/src/rulebuilder/condition/Builder-condition.ts +17 -13
- package/src/rulebuilder/index.ts +16 -3
- package/src/rulebuilder/page-action-manager.ts +33 -33
- package/src/rulebuilder/rule2/Rule2.ts +211 -215
- package/src/schema-config.ts +25 -25
- package/src/sum-score/sum-score-answer.ts +6 -0
- package/src/sum-score/sum-score-variable-collection.spec.ts +68 -0
- package/src/sum-score/sum-score-variable-collection.ts +101 -0
- package/src/sum-score/sum-score-variable.spec.ts +253 -0
- package/src/sum-score/sum-score-variable.ts +98 -0
- package/src/{variable → sum-score}/sum-score.ts +57 -26
- package/src/tag/BuilderTag.ts +45 -0
- package/src/tag/Tag-Collection.ts +53 -0
- package/src/theme/default-theme-compiler.ts +358 -358
- package/tsconfig.json +19 -15
- package/src/Builder-page.spec.ts +0 -320
- package/src/BuilderTag.ts +0 -96
- package/src/codebook.ts +0 -72
- package/src/variable/b-variable.ts +0 -68
- package/src/variable/mq-variable.spec.ts +0 -147
- package/src/variable/sum-score-variable.ts +0 -50
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { BuilderPage } from "./Builder-page";
|
|
2
|
+
import type { BuilderPageDto } from "./Builder-page";
|
|
3
|
+
import type { BuilderQuestionDto } from "../Builder-question";
|
|
4
|
+
import { DUtil } from "@media-quest/engine";
|
|
5
|
+
import { PagePrefix } from "../primitives/page-prefix";
|
|
6
|
+
import { SchemaPrefix } from "../primitives/schema-prefix";
|
|
7
|
+
import { OptionID, PageID, QuestionID } from "../primitives/ID";
|
|
8
|
+
|
|
9
|
+
const U = DUtil;
|
|
10
|
+
const deleteIdsFromPage = (page: BuilderPageDto) => {
|
|
11
|
+
const deleteIdsFromQuestion = (q: BuilderQuestionDto) => {
|
|
12
|
+
U.deleteProp(q, "id");
|
|
13
|
+
q.options.forEach((o) => {
|
|
14
|
+
U.deleteProp(o, "id");
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
U.deleteProp(page, "id");
|
|
18
|
+
deleteIdsFromQuestion(page.defaultQuestion);
|
|
19
|
+
return page;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const pxx = PagePrefix.fromStringOrThrow("pxx");
|
|
23
|
+
const questionPageDto: BuilderPageDto = {
|
|
24
|
+
_type: "question",
|
|
25
|
+
autoplaySequence: [],
|
|
26
|
+
includedInSumScores: [],
|
|
27
|
+
mainText: {
|
|
28
|
+
text: "Velkommen til denne undersøkelsen.",
|
|
29
|
+
audioFile: false,
|
|
30
|
+
autoplayDelay: 0,
|
|
31
|
+
autoplay: false,
|
|
32
|
+
},
|
|
33
|
+
tags: [],
|
|
34
|
+
|
|
35
|
+
nextButton: {
|
|
36
|
+
id: OptionID.dummy.a,
|
|
37
|
+
label: "Neste",
|
|
38
|
+
value: -1,
|
|
39
|
+
},
|
|
40
|
+
defaultQuestion: {
|
|
41
|
+
id: QuestionID.validateOrThrow("default-question-id"),
|
|
42
|
+
prefix: "q1",
|
|
43
|
+
text: "sadf",
|
|
44
|
+
options: [
|
|
45
|
+
{
|
|
46
|
+
id: "q1-opt1" as OptionID,
|
|
47
|
+
value: 0,
|
|
48
|
+
label: "Nei",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "q1-opt2" as OptionID,
|
|
52
|
+
value: 1,
|
|
53
|
+
label: "Ja",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "q1-opt3" as OptionID,
|
|
57
|
+
value: 9,
|
|
58
|
+
label: "Vet ikke",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
_type: "select-one",
|
|
62
|
+
},
|
|
63
|
+
// id: "p1" as BuilderObjectId.PageID,
|
|
64
|
+
id: PageID.create(),
|
|
65
|
+
prefix: PagePrefix.fromStringOrThrow("pxx"),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const multiQuestionPageDto: BuilderPageDto = {
|
|
69
|
+
_type: "question",
|
|
70
|
+
includedInSumScores: [],
|
|
71
|
+
mainText: {
|
|
72
|
+
text: "Velkommen til denne undersøkelsen.",
|
|
73
|
+
audioFile: false,
|
|
74
|
+
autoplay: false,
|
|
75
|
+
autoplayDelay: 0,
|
|
76
|
+
},
|
|
77
|
+
autoplaySequence: [],
|
|
78
|
+
defaultQuestion: {
|
|
79
|
+
id: QuestionID.create(),
|
|
80
|
+
prefix: "",
|
|
81
|
+
text: "",
|
|
82
|
+
options: [],
|
|
83
|
+
_type: "select-one",
|
|
84
|
+
},
|
|
85
|
+
tags: [],
|
|
86
|
+
nextButton: {
|
|
87
|
+
id: "next-button-id-3" as OptionID,
|
|
88
|
+
label: "Neste",
|
|
89
|
+
value: -1,
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
id: PageID.create(),
|
|
93
|
+
prefix: PagePrefix.fromStringOrThrow("pxx"),
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
let page = BuilderPage.create("info-page", PagePrefix.fromStringOrThrow("a"));
|
|
97
|
+
|
|
98
|
+
beforeEach(() => {
|
|
99
|
+
page = BuilderPage.create("info-page", PagePrefix.fromStringOrThrow("a"));
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe("Builder Page", () => {
|
|
103
|
+
test("Can create page, and convert to json, and back", () => {
|
|
104
|
+
const page1 = BuilderPage.fromJson(questionPageDto);
|
|
105
|
+
const asJson = page1.toJson();
|
|
106
|
+
expect(questionPageDto).toStrictEqual(asJson);
|
|
107
|
+
const page2 = BuilderPage.fromJson(multiQuestionPageDto);
|
|
108
|
+
const asJson2 = page2.toJson();
|
|
109
|
+
expect(multiQuestionPageDto).toStrictEqual(asJson2);
|
|
110
|
+
// expect(page1.prefix).toBe(pageDto.prefix);
|
|
111
|
+
});
|
|
112
|
+
test("Can clone a page and everything except id is equal ", () => {
|
|
113
|
+
const page1 = BuilderPage.create("info-page", PagePrefix.fromStringOrThrow("as"));
|
|
114
|
+
const clone1 = BuilderPage.fromJson(page1.clone());
|
|
115
|
+
const page1Json = deleteIdsFromPage(page1.clone());
|
|
116
|
+
const clone1Json = deleteIdsFromPage(page1.clone());
|
|
117
|
+
expect(page1Json).toStrictEqual(clone1Json);
|
|
118
|
+
|
|
119
|
+
const page2 = BuilderPage.fromJson(questionPageDto);
|
|
120
|
+
const clone2 = BuilderPage.fromJson(page2.clone());
|
|
121
|
+
const page2Json = deleteIdsFromPage(page2.toJson());
|
|
122
|
+
const clone2Json = deleteIdsFromPage(clone2.toJson());
|
|
123
|
+
expect(page2Json).toStrictEqual(clone2Json);
|
|
124
|
+
|
|
125
|
+
const page3 = BuilderPage.fromJson(multiQuestionPageDto);
|
|
126
|
+
const clone3 = BuilderPage.fromJson(page3.clone());
|
|
127
|
+
const page3Json = deleteIdsFromPage(page3.toJson());
|
|
128
|
+
const clone3Json = deleteIdsFromPage(clone3.toJson());
|
|
129
|
+
expect(page3Json).toStrictEqual(clone3Json);
|
|
130
|
+
});
|
|
131
|
+
test("Can clone a page and no id is equal", () => {
|
|
132
|
+
const page1 = BuilderPage.create("info-page", pxx);
|
|
133
|
+
const clone1 = BuilderPage.fromJson(page1.clone());
|
|
134
|
+
expect(page1.id).not.toBe(clone1.id);
|
|
135
|
+
|
|
136
|
+
const testDtoIds = (dto: BuilderPageDto) => {
|
|
137
|
+
const instance = BuilderPage.fromJson(dto);
|
|
138
|
+
const clone = BuilderPage.fromJson(instance.clone());
|
|
139
|
+
|
|
140
|
+
testDtoIds(questionPageDto);
|
|
141
|
+
testDtoIds(multiQuestionPageDto);
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test("Can get all rule-variables.", () => {
|
|
146
|
+
const prefix = PagePrefix.fromStringOrThrow("as1");
|
|
147
|
+
const page = BuilderPage.create("question", prefix);
|
|
148
|
+
page.mainText.text = "Hva heter du?";
|
|
149
|
+
page.defaultQuestion.addOption("Ja", 1);
|
|
150
|
+
page.defaultQuestion.addOption("Nei", 0);
|
|
151
|
+
const shemaPrefix = SchemaPrefix.fromValueOrThrow("ax");
|
|
152
|
+
const variables = page.getQuestionVariables(shemaPrefix, 1);
|
|
153
|
+
const first = variables[0];
|
|
154
|
+
expect(variables.length).toBe(1);
|
|
155
|
+
expect(first.options.length).toBe(2);
|
|
156
|
+
expect(first.options[0].value).toBe(1);
|
|
157
|
+
expect(first.kind === "question-variable").toBe(true);
|
|
158
|
+
// const newQuestion = BuilderQuestion.create('select-one');
|
|
159
|
+
// const m1 = page1.moveQuestion(newQuestion, 0);
|
|
160
|
+
// expect(page1.questions.length).toBe(3);
|
|
161
|
+
// expect(m1).toBe(false);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import type { BuilderQuestionDto, BuilderQuestionType } from "
|
|
2
|
-
import { BuilderQuestion } from "
|
|
3
|
-
import { BuilderObject } from "
|
|
4
|
-
import type { BuilderOptionDto } from "
|
|
5
|
-
import { BuilderOption } from "
|
|
6
|
-
import type { BuilderMainVideoDto } from "
|
|
7
|
-
import type { BuilderMainImageDto } from "
|
|
8
|
-
import type { BuilderMainTextDto } from "
|
|
9
|
-
import { BuilderMainText } from "
|
|
10
|
-
import {
|
|
1
|
+
import type { BuilderQuestionDto, BuilderQuestionType } from "../Builder-question";
|
|
2
|
+
import { BuilderQuestion } from "../Builder-question";
|
|
3
|
+
import { BuilderObject } from "../BuilderObject";
|
|
4
|
+
import type { BuilderOptionDto } from "../Builder-option";
|
|
5
|
+
import { BuilderOption } from "../Builder-option";
|
|
6
|
+
import type { BuilderMainVideoDto } from "../BuilderMainVideoDto";
|
|
7
|
+
import type { BuilderMainImageDto } from "../BuilderMainImageDto";
|
|
8
|
+
import type { BuilderMainTextDto } from "../BuilderMainText";
|
|
9
|
+
import { BuilderMainText } from "../BuilderMainText";
|
|
10
|
+
import { RuleVariableOption, RuleQuestionVariable } from "../rulebuilder";
|
|
11
11
|
import { DUtil } from "@media-quest/engine";
|
|
12
|
-
import { PagePrefix, PagePrefixValue } from "
|
|
13
|
-
import { VarID } from "
|
|
14
|
-
import { SchemaPrefix } from "
|
|
15
|
-
import { PageID } from "
|
|
12
|
+
import { PagePrefix, PagePrefixValue } from "../primitives/page-prefix";
|
|
13
|
+
import { VarID } from "../primitives/varID";
|
|
14
|
+
import { SchemaPrefix } from "../primitives/schema-prefix";
|
|
15
|
+
import { PageID, SumScoreVariableID } from "../primitives/ID";
|
|
16
|
+
import { SumScoreVariable } from "../sum-score/sum-score-variable";
|
|
16
17
|
|
|
17
18
|
const U = DUtil;
|
|
18
|
-
export type BuilderPageType = "info-page" | "question"
|
|
19
|
+
export type BuilderPageType = "info-page" | "question";
|
|
19
20
|
|
|
20
21
|
export interface BuilderPageDto {
|
|
21
22
|
readonly id: PageID;
|
|
@@ -24,11 +25,10 @@ export interface BuilderPageDto {
|
|
|
24
25
|
mainText: BuilderMainTextDto;
|
|
25
26
|
nextButton: BuilderOptionDto;
|
|
26
27
|
defaultQuestion: BuilderQuestionDto;
|
|
27
|
-
questions: Array<BuilderQuestionDto>;
|
|
28
28
|
mainMedia?: BuilderMainImageDto | BuilderMainVideoDto;
|
|
29
|
+
includedInSumScores: Array<{ sumScoreVariableId: SumScoreVariableID; weight: number }>;
|
|
29
30
|
autoplaySequence: Array<string>;
|
|
30
31
|
tags: ReadonlyArray<string>;
|
|
31
|
-
// sumScoreVariables: Array<BuilderObjectId.SumScoreVariableId>
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
@@ -36,9 +36,18 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
36
36
|
readonly id: PageID;
|
|
37
37
|
private _pageType: BuilderPageType;
|
|
38
38
|
private _prefix: PagePrefix;
|
|
39
|
-
private _questions: Array<BuilderQuestion> = [];
|
|
40
39
|
private readonly _tags: Set<string>;
|
|
41
40
|
private _backgroundColor = "#FFFFFF";
|
|
41
|
+
private _includedInSumScores: Map<
|
|
42
|
+
SumScoreVariableID,
|
|
43
|
+
{
|
|
44
|
+
sumScoreVariableId: SumScoreVariableID;
|
|
45
|
+
weight: number;
|
|
46
|
+
name: string;
|
|
47
|
+
description: string;
|
|
48
|
+
}
|
|
49
|
+
> = new Map();
|
|
50
|
+
|
|
42
51
|
mainMedia: BuilderMainVideoDto | BuilderMainImageDto | false = false;
|
|
43
52
|
defaultQuestion: BuilderQuestion;
|
|
44
53
|
mainText: BuilderMainText;
|
|
@@ -63,7 +72,7 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
63
72
|
nextButton: nextButtonDto,
|
|
64
73
|
mainText: mainTextDto,
|
|
65
74
|
prefix: _prefix,
|
|
66
|
-
|
|
75
|
+
includedInSumScores: [],
|
|
67
76
|
tags: [],
|
|
68
77
|
};
|
|
69
78
|
|
|
@@ -84,74 +93,20 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
84
93
|
this.mainText = BuilderMainText.fromJson(dto.mainText);
|
|
85
94
|
this.nextButton = BuilderOption.fromJson(dto.nextButton);
|
|
86
95
|
this.defaultQuestion = BuilderQuestion.fromJson(dto.defaultQuestion);
|
|
87
|
-
this._questions = dto.questions.map((q) => BuilderQuestion.fromJson(q));
|
|
88
96
|
const tagList: string[] = Array.isArray(dto.tags) ? dto.tags : [];
|
|
97
|
+
const sumScores = Array.isArray(dto.includedInSumScores) ? dto.includedInSumScores : [];
|
|
98
|
+
sumScores.forEach((item) => {
|
|
99
|
+
this._includedInSumScores.set(item.sumScoreVariableId, {
|
|
100
|
+
sumScoreVariableId: item.sumScoreVariableId,
|
|
101
|
+
weight: item.weight,
|
|
102
|
+
name: "",
|
|
103
|
+
description: "",
|
|
104
|
+
});
|
|
105
|
+
});
|
|
89
106
|
this._tags = new Set(tagList);
|
|
90
107
|
if (dto.mainMedia) {
|
|
91
108
|
this.mainMedia = dto.mainMedia;
|
|
92
109
|
}
|
|
93
|
-
this.updateRows();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
insertQuestion(question: BuilderQuestion, atIndex: number): boolean {
|
|
97
|
-
const validIndexFn = U.isInRange(0, this._questions.length);
|
|
98
|
-
if (!validIndexFn(atIndex)) {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
const hasQuestion = !!this._questions.find((q) => q.id === question.id);
|
|
102
|
-
if (hasQuestion) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
this._questions.splice(atIndex, 0, question);
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
addQuestion(type: BuilderQuestionType, atIndex = -1): BuilderQuestion {
|
|
110
|
-
const question = BuilderQuestion.create(type);
|
|
111
|
-
if (atIndex < this._questions.length && atIndex >= 0) {
|
|
112
|
-
this._questions.splice(atIndex, 0, question);
|
|
113
|
-
} else {
|
|
114
|
-
this._questions.push(question);
|
|
115
|
-
}
|
|
116
|
-
return question;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Move a question in questions-array
|
|
121
|
-
* @param question (reference)
|
|
122
|
-
* @param toIndex
|
|
123
|
-
*/
|
|
124
|
-
moveQuestion(question: BuilderQuestion, toIndex: number): boolean {
|
|
125
|
-
const validToIndexFn = U.isInRange(0, this._questions.length);
|
|
126
|
-
if (!validToIndexFn(toIndex)) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
const currentIndex = this._questions.indexOf(question);
|
|
130
|
-
if (currentIndex < 0) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
this._questions.splice(currentIndex, 1);
|
|
134
|
-
this._questions.splice(toIndex, 0, question);
|
|
135
|
-
return true;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
deleteQuestion(question: BuilderQuestion) {
|
|
139
|
-
this._questions = this._questions.filter((q) => q !== question);
|
|
140
|
-
// TODO EMIT DELETED QUESTION.
|
|
141
|
-
this.updateRows();
|
|
142
|
-
}
|
|
143
|
-
private updateRows() {
|
|
144
|
-
if (this._pageType === "question" || this._pageType === "info-page") {
|
|
145
|
-
this._questions = [];
|
|
146
|
-
}
|
|
147
|
-
if (this._pageType === "form" && this._questions.length === 0) {
|
|
148
|
-
this._questions = [];
|
|
149
|
-
this.addQuestion("text");
|
|
150
|
-
}
|
|
151
|
-
if (this._pageType === "multi-select" && this._questions.length === 0) {
|
|
152
|
-
this._questions = [];
|
|
153
|
-
this.addQuestion("text");
|
|
154
|
-
}
|
|
155
110
|
}
|
|
156
111
|
|
|
157
112
|
public addTag(tag: string) {
|
|
@@ -163,15 +118,17 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
163
118
|
|
|
164
119
|
set pageType(value: BuilderPageType) {
|
|
165
120
|
this._pageType = value;
|
|
166
|
-
|
|
167
|
-
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
get includedInSumScores() {
|
|
124
|
+
return [...this._includedInSumScores.values()];
|
|
168
125
|
}
|
|
169
126
|
|
|
170
127
|
getQuestionVariables(
|
|
171
128
|
modulePrefix: SchemaPrefix,
|
|
172
129
|
pageNumber: number,
|
|
173
|
-
): ReadonlyArray<
|
|
174
|
-
const variables:
|
|
130
|
+
): ReadonlyArray<RuleQuestionVariable> {
|
|
131
|
+
const variables: RuleQuestionVariable[] = [];
|
|
175
132
|
|
|
176
133
|
if (this._pageType === "question") {
|
|
177
134
|
const pagePrefix = this.prefix;
|
|
@@ -180,9 +137,9 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
180
137
|
const op = this.defaultQuestion.options.map((o) => {
|
|
181
138
|
const label = o.label;
|
|
182
139
|
const value = o.value;
|
|
183
|
-
return new
|
|
140
|
+
return new RuleVariableOption(label, value);
|
|
184
141
|
});
|
|
185
|
-
const singleVar = new
|
|
142
|
+
const singleVar = new RuleQuestionVariable(varId, label, op, pageNumber);
|
|
186
143
|
variables.push(singleVar);
|
|
187
144
|
}
|
|
188
145
|
return variables;
|
|
@@ -203,11 +160,36 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
203
160
|
this._prefix.value = value;
|
|
204
161
|
}
|
|
205
162
|
|
|
163
|
+
sumScoreVariableSet(sumScoreVariable: SumScoreVariable, weight: number) {
|
|
164
|
+
const { id, name, description } = sumScoreVariable;
|
|
165
|
+
|
|
166
|
+
this._includedInSumScores.set(sumScoreVariable.id, {
|
|
167
|
+
sumScoreVariableId: id,
|
|
168
|
+
weight,
|
|
169
|
+
name,
|
|
170
|
+
description,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
sumScoreVariableUpdateData(variables: ReadonlyArray<SumScoreVariable>) {
|
|
177
|
+
variables.forEach((v) => {
|
|
178
|
+
const sumScoreEntry = this._includedInSumScores.get(v.id);
|
|
179
|
+
if (sumScoreEntry) {
|
|
180
|
+
this.sumScoreVariableSet(v, sumScoreEntry.weight);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
206
185
|
toJson(): BuilderPageDto {
|
|
207
|
-
const questions = this._questions.map((q) => q.toJson());
|
|
208
186
|
const mainText = this.mainText.toJson();
|
|
209
187
|
const nextButton = this.nextButton.toJson();
|
|
210
188
|
const mainMedia = this.mainMedia;
|
|
189
|
+
const includedInSumScores = this.includedInSumScores.map(({ sumScoreVariableId, weight }) => ({
|
|
190
|
+
sumScoreVariableId,
|
|
191
|
+
weight,
|
|
192
|
+
}));
|
|
211
193
|
const dto: BuilderPageDto = {
|
|
212
194
|
_type: this.pageType,
|
|
213
195
|
mainText,
|
|
@@ -215,9 +197,9 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
215
197
|
nextButton,
|
|
216
198
|
id: this.id,
|
|
217
199
|
tags: [...this.tags],
|
|
200
|
+
includedInSumScores,
|
|
218
201
|
prefix: this._prefix.value,
|
|
219
202
|
defaultQuestion: this.defaultQuestion.toJson(),
|
|
220
|
-
questions,
|
|
221
203
|
};
|
|
222
204
|
if (mainMedia) {
|
|
223
205
|
dto.mainMedia = mainMedia;
|
|
@@ -229,15 +211,12 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
229
211
|
const dto = this.toJson();
|
|
230
212
|
const defaultQuestionClone = this.defaultQuestion.clone();
|
|
231
213
|
const mainTextClone = JSON.parse(JSON.stringify(this.mainText));
|
|
232
|
-
// const pagesClone = this
|
|
233
|
-
const questionsClone = this.questions.map((q) => q.clone());
|
|
234
214
|
const newId = PageID.create();
|
|
235
215
|
const clone: BuilderPageDto = {
|
|
236
216
|
...dto,
|
|
237
217
|
id: newId,
|
|
238
218
|
defaultQuestion: defaultQuestionClone,
|
|
239
219
|
mainText: mainTextClone,
|
|
240
|
-
questions: questionsClone,
|
|
241
220
|
};
|
|
242
221
|
// const cloneDto
|
|
243
222
|
return clone;
|
|
@@ -253,7 +232,7 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
|
|
|
253
232
|
}
|
|
254
233
|
}
|
|
255
234
|
|
|
256
|
-
|
|
257
|
-
|
|
235
|
+
sumScoreVariableDelete(sumScoreVariableID: SumScoreVariableID) {
|
|
236
|
+
this._includedInSumScores.delete(sumScoreVariableID);
|
|
258
237
|
}
|
|
259
238
|
}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import { PageID, SchemaID } from "./ID";
|
|
2
|
-
|
|
3
|
-
describe("ID Functions work", () => {
|
|
4
|
-
//Generate test for schema prefix
|
|
5
|
-
test("SCHEMA_ID isFunction works", () => {
|
|
6
|
-
const id = SchemaID.create();
|
|
7
|
-
expect(SchemaID.is(id)).toBe(true);
|
|
8
|
-
expect(SchemaID.is("")).toBe(false);
|
|
9
|
-
expect(SchemaID.is("a")).toBe(false);
|
|
10
|
-
expect(SchemaID.is("a".repeat(10))).toBe(true);
|
|
11
|
-
expect(SchemaID.is("a".repeat(9))).toBe(false);
|
|
12
|
-
});
|
|
13
|
-
test("SCHEMA_ID ensure works", () => {
|
|
14
|
-
const id = SchemaID.create();
|
|
15
|
-
expect(SchemaID.validateOrCreate(id)).toBe(id);
|
|
16
|
-
expect(SchemaID.validateOrCreate("")).not.toBe("");
|
|
17
|
-
expect(SchemaID.validateOrCreate("")).not.toBe("a");
|
|
18
|
-
expect(SchemaID.validateOrCreate("a".repeat(10))).toBe("a".repeat(10));
|
|
19
|
-
expect(SchemaID.validateOrCreate("a".repeat(9))).not.toBe("a".repeat(9));
|
|
20
|
-
expect(SchemaID.validateOrCreate("ABcdefghigKLML")).toBe("ABcdefghigKLML");
|
|
21
|
-
});
|
|
22
|
-
test("PageID isFunction works", () => {
|
|
23
|
-
const id = PageID.create();
|
|
24
|
-
expect(PageID.is(id)).toBe(true);
|
|
25
|
-
expect(PageID.is("")).toBe(false);
|
|
26
|
-
expect(PageID.is("a")).toBe(false);
|
|
27
|
-
expect(PageID.is("a".repeat(10))).toBe(true);
|
|
28
|
-
expect(PageID.is("a".repeat(9))).toBe(false);
|
|
29
|
-
});
|
|
30
|
-
test("PageID ensure works", () => {
|
|
31
|
-
const id = PageID.create();
|
|
32
|
-
expect(PageID.validateOrCreate(id)).toBe(id);
|
|
33
|
-
expect(PageID.validateOrCreate("")).not.toBe("");
|
|
34
|
-
expect(PageID.validateOrCreate("")).not.toBe("a");
|
|
35
|
-
expect(PageID.validateOrCreate("a".repeat(10))).toBe("a".repeat(10));
|
|
36
|
-
expect(PageID.validateOrCreate("a".repeat(9))).not.toBe("a".repeat(9));
|
|
37
|
-
expect(PageID.validateOrCreate("ABcdefghigKLML")).toBe("ABcdefghigKLML");
|
|
38
|
-
});
|
|
39
|
-
});
|
|
1
|
+
import { PageID, SchemaID } from "./ID";
|
|
2
|
+
|
|
3
|
+
describe("ID Functions work", () => {
|
|
4
|
+
//Generate test for schema prefix
|
|
5
|
+
test("SCHEMA_ID isFunction works", () => {
|
|
6
|
+
const id = SchemaID.create();
|
|
7
|
+
expect(SchemaID.is(id)).toBe(true);
|
|
8
|
+
expect(SchemaID.is("")).toBe(false);
|
|
9
|
+
expect(SchemaID.is("a")).toBe(false);
|
|
10
|
+
expect(SchemaID.is("a".repeat(10))).toBe(true);
|
|
11
|
+
expect(SchemaID.is("a".repeat(9))).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
test("SCHEMA_ID ensure works", () => {
|
|
14
|
+
const id = SchemaID.create();
|
|
15
|
+
expect(SchemaID.validateOrCreate(id)).toBe(id);
|
|
16
|
+
expect(SchemaID.validateOrCreate("")).not.toBe("");
|
|
17
|
+
expect(SchemaID.validateOrCreate("")).not.toBe("a");
|
|
18
|
+
expect(SchemaID.validateOrCreate("a".repeat(10))).toBe("a".repeat(10));
|
|
19
|
+
expect(SchemaID.validateOrCreate("a".repeat(9))).not.toBe("a".repeat(9));
|
|
20
|
+
expect(SchemaID.validateOrCreate("ABcdefghigKLML")).toBe("ABcdefghigKLML");
|
|
21
|
+
});
|
|
22
|
+
test("PageID isFunction works", () => {
|
|
23
|
+
const id = PageID.create();
|
|
24
|
+
expect(PageID.is(id)).toBe(true);
|
|
25
|
+
expect(PageID.is("")).toBe(false);
|
|
26
|
+
expect(PageID.is("a")).toBe(false);
|
|
27
|
+
expect(PageID.is("a".repeat(10))).toBe(true);
|
|
28
|
+
expect(PageID.is("a".repeat(9))).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
test("PageID ensure works", () => {
|
|
31
|
+
const id = PageID.create();
|
|
32
|
+
expect(PageID.validateOrCreate(id)).toBe(id);
|
|
33
|
+
expect(PageID.validateOrCreate("")).not.toBe("");
|
|
34
|
+
expect(PageID.validateOrCreate("")).not.toBe("a");
|
|
35
|
+
expect(PageID.validateOrCreate("a".repeat(10))).toBe("a".repeat(10));
|
|
36
|
+
expect(PageID.validateOrCreate("a".repeat(9))).not.toBe("a".repeat(9));
|
|
37
|
+
expect(PageID.validateOrCreate("ABcdefghigKLML")).toBe("ABcdefghigKLML");
|
|
38
|
+
});
|
|
39
|
+
});
|
package/src/primitives/ID.ts
CHANGED
|
@@ -86,17 +86,30 @@ export const createTypedIdSingleton = <const B extends string>(idName: B): Id<B>
|
|
|
86
86
|
return is(id) ? id : create();
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
+
const a = createDummyID(idName, "a");
|
|
90
|
+
const b = createDummyID(idName, "b");
|
|
91
|
+
const c = createDummyID(idName, "c");
|
|
92
|
+
const d = createDummyID(idName, "d");
|
|
93
|
+
const e = createDummyID(idName, "e");
|
|
94
|
+
const f = createDummyID(idName, "f");
|
|
95
|
+
const g = createDummyID(idName, "g");
|
|
96
|
+
const h = createDummyID(idName, "h");
|
|
97
|
+
const i = createDummyID(idName, "i");
|
|
98
|
+
const j = createDummyID(idName, "j");
|
|
99
|
+
const list = [a, b, c, d, e, f, g, h, i, j];
|
|
100
|
+
|
|
89
101
|
const dummy = {
|
|
90
|
-
a
|
|
91
|
-
b
|
|
92
|
-
c
|
|
93
|
-
d
|
|
94
|
-
e
|
|
95
|
-
f
|
|
96
|
-
g
|
|
97
|
-
h
|
|
98
|
-
i
|
|
99
|
-
j
|
|
102
|
+
a,
|
|
103
|
+
b,
|
|
104
|
+
c,
|
|
105
|
+
d,
|
|
106
|
+
e,
|
|
107
|
+
f,
|
|
108
|
+
g,
|
|
109
|
+
h,
|
|
110
|
+
i,
|
|
111
|
+
j,
|
|
112
|
+
list,
|
|
100
113
|
};
|
|
101
114
|
|
|
102
115
|
return Object.freeze({ create, is, validateOrCreate, validateOrThrow, name, dummy });
|
|
@@ -117,3 +130,6 @@ export type TextID = ID<"TEXT">;
|
|
|
117
130
|
export const TextID = createTypedIdSingleton("TEXT");
|
|
118
131
|
export type QuestionID = ID<"QUESTION">;
|
|
119
132
|
export const QuestionID = createTypedIdSingleton("QUESTION");
|
|
133
|
+
|
|
134
|
+
export type SumScoreVariableID = ID<"SUM_SCORE_VARIABLE">;
|
|
135
|
+
export const SumScoreVariableID = createTypedIdSingleton("SUM_SCORE_VARIABLE");
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import { SchemaPrefix } from "./schema-prefix";
|
|
2
|
-
|
|
3
|
-
export type PagePrefixValue = string & { __PAGE_PREFIX__: true };
|
|
4
|
-
export const createRandomPrefix = <const P extends string>(length: number): P => {
|
|
5
|
-
const letters = "abcdefghijklmnopqrstuvyz";
|
|
6
|
-
const all = letters + letters.toUpperCase();
|
|
7
|
-
let result = "";
|
|
8
|
-
for (let i = 0; i < length; i++) {
|
|
9
|
-
const char = all.charAt(Math.floor(Math.random() * all.length));
|
|
10
|
-
result += char;
|
|
11
|
-
}
|
|
12
|
-
return result as P;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export class PagePrefix {
|
|
16
|
-
public static readonly MIN_LENGTH = 1;
|
|
17
|
-
private static randomLen = 5;
|
|
18
|
-
public static readonly MAX_LENGTH = 16;
|
|
19
|
-
|
|
20
|
-
public static create = (): PagePrefix => {
|
|
21
|
-
const v = createRandomPrefix<PagePrefixValue>(PagePrefix.randomLen);
|
|
22
|
-
return new PagePrefix(v);
|
|
23
|
-
};
|
|
24
|
-
public static fromString = (value: string): PagePrefix | false => {
|
|
25
|
-
if (!PagePrefix.isValid(value)) return false;
|
|
26
|
-
return new PagePrefix(value);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
public static fromStringOrThrow = (value: string): PagePrefixValue => {
|
|
30
|
-
if (!PagePrefix.isValid(value)) throw new Error("Invalid prefix");
|
|
31
|
-
return value;
|
|
32
|
-
};
|
|
33
|
-
public static castOrCreateRandom = (value: string): PagePrefix => {
|
|
34
|
-
const v = PagePrefix.isValid(value)
|
|
35
|
-
? value
|
|
36
|
-
: createRandomPrefix<PagePrefixValue>(PagePrefix.randomLen);
|
|
37
|
-
return new PagePrefix(v);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
public static isValid = (prefix: string | 999): prefix is PagePrefixValue => {
|
|
41
|
-
if (typeof prefix !== "string") return false;
|
|
42
|
-
if (prefix.length < SchemaPrefix.MIN_LENGTH) return false;
|
|
43
|
-
return prefix.length <= SchemaPrefix.MAX_LENGTH;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
get value(): PagePrefixValue {
|
|
47
|
-
return this._value;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
set value(value: string) {
|
|
51
|
-
if (!PagePrefix.isValid(value)) {
|
|
52
|
-
console.log("INVALID PREFIX", value);
|
|
53
|
-
} else {
|
|
54
|
-
this._value = value;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private constructor(private _value: PagePrefixValue) {}
|
|
59
|
-
}
|
|
1
|
+
import { SchemaPrefix } from "./schema-prefix";
|
|
2
|
+
|
|
3
|
+
export type PagePrefixValue = string & { __PAGE_PREFIX__: true };
|
|
4
|
+
export const createRandomPrefix = <const P extends string>(length: number): P => {
|
|
5
|
+
const letters = "abcdefghijklmnopqrstuvyz";
|
|
6
|
+
const all = letters + letters.toUpperCase();
|
|
7
|
+
let result = "";
|
|
8
|
+
for (let i = 0; i < length; i++) {
|
|
9
|
+
const char = all.charAt(Math.floor(Math.random() * all.length));
|
|
10
|
+
result += char;
|
|
11
|
+
}
|
|
12
|
+
return result as P;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class PagePrefix {
|
|
16
|
+
public static readonly MIN_LENGTH = 1;
|
|
17
|
+
private static randomLen = 5;
|
|
18
|
+
public static readonly MAX_LENGTH = 16;
|
|
19
|
+
|
|
20
|
+
public static create = (): PagePrefix => {
|
|
21
|
+
const v = createRandomPrefix<PagePrefixValue>(PagePrefix.randomLen);
|
|
22
|
+
return new PagePrefix(v);
|
|
23
|
+
};
|
|
24
|
+
public static fromString = (value: string): PagePrefix | false => {
|
|
25
|
+
if (!PagePrefix.isValid(value)) return false;
|
|
26
|
+
return new PagePrefix(value);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
public static fromStringOrThrow = (value: string): PagePrefixValue => {
|
|
30
|
+
if (!PagePrefix.isValid(value)) throw new Error("Invalid prefix");
|
|
31
|
+
return value;
|
|
32
|
+
};
|
|
33
|
+
public static castOrCreateRandom = (value: string): PagePrefix => {
|
|
34
|
+
const v = PagePrefix.isValid(value)
|
|
35
|
+
? value
|
|
36
|
+
: createRandomPrefix<PagePrefixValue>(PagePrefix.randomLen);
|
|
37
|
+
return new PagePrefix(v);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
public static isValid = (prefix: string | 999): prefix is PagePrefixValue => {
|
|
41
|
+
if (typeof prefix !== "string") return false;
|
|
42
|
+
if (prefix.length < SchemaPrefix.MIN_LENGTH) return false;
|
|
43
|
+
return prefix.length <= SchemaPrefix.MAX_LENGTH;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
get value(): PagePrefixValue {
|
|
47
|
+
return this._value;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
set value(value: string) {
|
|
51
|
+
if (!PagePrefix.isValid(value)) {
|
|
52
|
+
console.log("INVALID PREFIX", value);
|
|
53
|
+
} else {
|
|
54
|
+
this._value = value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private constructor(private _value: PagePrefixValue) {}
|
|
59
|
+
}
|