@media-quest/builder 0.0.29 → 0.0.31

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@media-quest/builder",
3
- "version": "0.0.29",
3
+ "version": "0.0.31",
4
4
  "description": "Builder library for Media-quest schemas",
5
5
  "main": "dist/public-api.js",
6
6
  "types": "dist/public-api.d.js",
@@ -24,6 +24,6 @@
24
24
  "dts": true
25
25
  },
26
26
  "peerDependencies": {
27
- "@media-quest/engine": "0.0.29"
27
+ "@media-quest/engine": "0.0.31"
28
28
  }
29
29
  }
@@ -1,64 +1,62 @@
1
- import { BuilderObject } from "./BuilderObject";
2
- import type { BuilderOptionTheme } from "./theme/IDefaultTheme";
3
- import { DefaultTheme } from "./theme/IDefaultTheme";
4
- import { AudioFile } from "./media-files";
5
- import { OptionID } from "./primitives/ID";
6
-
7
- export interface BuilderOptionDto {
8
- readonly id: OptionID;
9
- readonly value: number;
10
- readonly label: string;
11
- readonly labelAudio?: AudioFile;
12
- }
13
-
14
- export class BuilderOption extends BuilderObject<"builder-question-option", BuilderOptionDto> {
15
- readonly objectType = "builder-question-option";
16
- id: OptionID;
17
- value: number;
18
- label = "";
19
- private _labelAudioFile: AudioFile | false = false;
20
- get labelAudioFile() {
21
- return this._labelAudioFile;
22
- }
23
- set labelAudioFile(audioFile: AudioFile | false) {
24
- this._labelAudioFile = audioFile;
25
- }
26
-
27
- private constructor(dto: BuilderOptionDto) {
28
- super(dto);
29
- this.id = dto.id;
30
- this.value = dto.value;
31
- this.label = dto.label;
32
- // this.theme = dto.theme;
33
- }
34
- public static create(value: number, label: string) {
35
- const id = OptionID.create();
36
- const dto: BuilderOptionDto = {
37
- id,
38
- value,
39
- label,
40
- };
41
- const instance = new BuilderOption(dto);
42
- return instance;
43
- }
44
-
45
- public static fromJson(dto: BuilderOptionDto) {
46
- const instance = new BuilderOption(dto);
47
- return instance;
48
- }
49
-
50
- toJson(): BuilderOptionDto {
51
- const dto: BuilderOptionDto = {
52
- id: this.id,
53
- value: this.value,
54
- label: this.label,
55
- };
56
- return dto;
57
- }
58
-
59
- clone(): BuilderOptionDto {
60
- const dto = this.toJson();
61
- const cloneDto: BuilderOptionDto = { ...dto, id: OptionID.create() };
62
- return cloneDto;
63
- }
64
- }
1
+ import { BuilderObject } from "./BuilderObject";
2
+ import { AudioFile } from "./media-files";
3
+ import { OptionID } from "./primitives/ID";
4
+
5
+ export interface BuilderOptionDto {
6
+ readonly id: OptionID;
7
+ readonly value: number;
8
+ readonly label: string;
9
+ readonly labelAudio?: AudioFile;
10
+ }
11
+
12
+ export class BuilderOption extends BuilderObject<"builder-question-option", BuilderOptionDto> {
13
+ readonly objectType = "builder-question-option";
14
+ id: OptionID;
15
+ value: number;
16
+ label = "";
17
+ private _labelAudioFile: AudioFile | false = false;
18
+ get labelAudioFile() {
19
+ return this._labelAudioFile;
20
+ }
21
+ set labelAudioFile(audioFile: AudioFile | false) {
22
+ this._labelAudioFile = audioFile;
23
+ }
24
+
25
+ private constructor(dto: BuilderOptionDto) {
26
+ super(dto);
27
+ this.id = dto.id;
28
+ this.value = dto.value;
29
+ this.label = dto.label;
30
+ // this.theme = dto.theme;
31
+ }
32
+ public static create(value: number, label: string) {
33
+ const id = OptionID.create();
34
+ const dto: BuilderOptionDto = {
35
+ id,
36
+ value,
37
+ label,
38
+ };
39
+ const instance = new BuilderOption(dto);
40
+ return instance;
41
+ }
42
+
43
+ public static fromJson(dto: BuilderOptionDto) {
44
+ const instance = new BuilderOption(dto);
45
+ return instance;
46
+ }
47
+
48
+ toJson(): BuilderOptionDto {
49
+ const dto: BuilderOptionDto = {
50
+ id: this.id,
51
+ value: this.value,
52
+ label: this.label,
53
+ };
54
+ return dto;
55
+ }
56
+
57
+ clone(): BuilderOptionDto {
58
+ const dto = this.toJson();
59
+ const cloneDto: BuilderOptionDto = { ...dto, id: OptionID.create() };
60
+ return cloneDto;
61
+ }
62
+ }
@@ -46,6 +46,8 @@ export interface BuilderSchemaDto {
46
46
 
47
47
  export class BuilderSchema {
48
48
  readonly prefix: SchemaPrefix;
49
+ public readonly compiler = new DefaultThemeCompiler();
50
+
49
51
  baseHeight = 1300;
50
52
  baseWidth = 1024;
51
53
  backgroundColor = "#000000";
@@ -287,10 +289,10 @@ export class BuilderSchema {
287
289
  }
288
290
  });
289
291
  const moduleDto = builderSchema.toJson();
290
- const imp = new DefaultThemeCompiler();
292
+ // const imp = new DefaultThemeCompiler();
291
293
 
292
294
  const codebook = CodeBook.fromSchema(moduleDto);
293
- const schema = imp.compile(moduleDto);
295
+ const schema = this.compiler.compile(moduleDto);
294
296
  const schemaConfig = SchemaConfig.fromSchema(moduleDto);
295
297
  const output: CompilerOutput = { codebook, schema, schemaConfig };
296
298
  return output;
@@ -26,8 +26,16 @@ const fromPage = (
26
26
  });
27
27
 
28
28
  const varId = modulePrefix + "_" + page.prefix;
29
+ const pageIncludedInSumScoresArray = page.includedInSumScores ?? [];
29
30
 
30
- const includedInSumScores = page.includedInSumScores.filter((a) => true);
31
+ const includedInSumScores: SumScoreVariableDto[] = [];
32
+ pageIncludedInSumScoresArray.forEach((p) => {
33
+ sumScoreVariables.forEach((ssv) => {
34
+ if (p.sumScoreVariableId === ssv.id) {
35
+ includedInSumScores.push(ssv);
36
+ }
37
+ });
38
+ });
31
39
 
32
40
  const variable: CodeBookQuestionVariable = {
33
41
  kind: "codebook-question-variable",
@@ -38,7 +46,7 @@ const fromPage = (
38
46
  modulePrefix,
39
47
  pagePosition,
40
48
  varId,
41
- includedInSumScores: [],
49
+ includedInSumScores,
42
50
  };
43
51
 
44
52
  variables.push(variable);
package/src/public-api.ts CHANGED
@@ -26,3 +26,4 @@ export * from "./sum-score/sum-score";
26
26
  export { SumScoreVariableDto, SumScoreVariable } from "./sum-score/sum-score-variable";
27
27
  export { SumScoreAnswer } from "./sum-score/sum-score-answer";
28
28
  export { TagCollection } from "./tag/Tag-Collection";
29
+ export * from "./theme/Default-theme";
@@ -0,0 +1,173 @@
1
+ import { DCss, DStyle, PStyle } from "@media-quest/engine";
2
+ import { IconUrls } from "./icon-urls";
3
+ import { BuilderOptionTheme, IDefaultTheme } from "./IDefault-theme";
4
+ import { CssTheme } from "./css-theme";
5
+
6
+ namespace BuilderOptionTheme {
7
+ const GREEN = "#70AD47";
8
+ const YELLOW = "#FFC000";
9
+ const ORANGE = "#F4902C";
10
+ const RED = "#FF0000";
11
+ const LIGHT_BLUE = "#42719C";
12
+ const WHITE = "#ffffff";
13
+ const BLUE = "#2F5597";
14
+ const BTN_BORDER_WIDTH = 3;
15
+ const BTN_BORDER_RADIUS = 10;
16
+ const BTN_BORDER_STYLE: DStyle["borderStyle"] = "solid";
17
+ const FONT_WEIGHT: DStyle["fontWeight"] = 600;
18
+ const FONT_SIZE: DCss.Px["value"] = 50;
19
+ const BTN_PADDING_LEFT = 40;
20
+ const BTN_PADDING_TOP = 40;
21
+
22
+ const buttonBaseCss = (): CssTheme => ({
23
+ css: {
24
+ fontWeight: FONT_WEIGHT,
25
+ fontSize: { _unit: "px", value: FONT_SIZE },
26
+ letterSpacing: { _unit: "px", value: 2 },
27
+ paddingLeft: { _unit: "px", value: BTN_PADDING_LEFT },
28
+ paddingTop: { _unit: "px", value: BTN_PADDING_TOP },
29
+ paddingBottom: { _unit: "px", value: BTN_PADDING_TOP },
30
+ paddingRight: { _unit: "px", value: BTN_PADDING_LEFT },
31
+ borderRadius: { _unit: "px", value: BTN_BORDER_RADIUS },
32
+ borderWidth: { _unit: "px", value: BTN_BORDER_WIDTH },
33
+ borderStyle: BTN_BORDER_STYLE,
34
+ // boxShadow: "3px 3px gray",
35
+ position: "relative",
36
+ display: "block",
37
+ },
38
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
39
+ cssEnabled: { opacity: 1, cursor: "pointer" },
40
+ });
41
+
42
+ export const blueButton = (): BuilderOptionTheme => {
43
+ const base = buttonBaseCss();
44
+ const { css, cssEnabled, cssDisabled } = base;
45
+ const optionTheme: BuilderOptionTheme = {
46
+ name: "blue-button-theme",
47
+ normal: {
48
+ btn: {
49
+ css: {
50
+ ...css,
51
+ backgroundColor: BLUE,
52
+ borderColor: BLUE,
53
+ textColor: WHITE,
54
+ },
55
+ cssDisabled,
56
+ cssEnabled,
57
+ },
58
+ divider: {},
59
+ text1: {},
60
+ text2: {},
61
+ },
62
+
63
+ dontKnow: {
64
+ btn: {
65
+ css: {
66
+ ...css,
67
+ backgroundColor: WHITE,
68
+ borderColor: LIGHT_BLUE,
69
+ textColor: BLUE,
70
+ },
71
+ cssDisabled,
72
+ cssEnabled,
73
+ },
74
+ text1: {},
75
+ text2: {},
76
+ divider: {},
77
+ },
78
+ };
79
+
80
+ return optionTheme;
81
+ };
82
+ }
83
+
84
+ const textHighTop = 25;
85
+ const textLowTop = 55;
86
+ const audioHighTop = 20;
87
+ const audioLowTop = 55;
88
+
89
+ const textBase: PStyle = {
90
+ width: 80,
91
+ top: textHighTop,
92
+ left: 10,
93
+ textAlign: "center",
94
+ textColor: "black",
95
+ fontSize: { _unit: "px", value: 40 },
96
+ };
97
+ const textHigh: PStyle = { ...textBase, top: textHighTop };
98
+ const textLow: PStyle = { ...textHigh, top: textLowTop };
99
+
100
+ const audioBase: PStyle = {
101
+ height: 6,
102
+ width: 6,
103
+ left: 4,
104
+ top: audioHighTop,
105
+ cursor: "pointer",
106
+ opacity: 0.8,
107
+ visibility: "visible",
108
+ };
109
+ const audioHigh: PStyle = { ...audioBase, top: audioHighTop };
110
+ const audioLow: PStyle = { ...audioBase, top: audioLowTop };
111
+
112
+ export const DefaultTheme: IDefaultTheme = {
113
+ name: "default-theme",
114
+ schemaBackgroundColor: "white",
115
+ dimensions: { baseHeight: 1300, baseWidth: 1024 },
116
+ videoPlayer: {
117
+ playButton: {
118
+ iconUrl: IconUrls.playCircleRegular,
119
+ css: { w: 5, h: 5, y: 48, x: 4 },
120
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
121
+ cssEnabled: { opacity: 0.8, cursor: "pointer" },
122
+ },
123
+ pauseButton: {
124
+ iconUrl: IconUrls.pauseSvg,
125
+ css: { w: 5, h: 5, y: 48, x: 4 },
126
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
127
+ cssEnabled: { opacity: 0.8, cursor: "pointer" },
128
+ },
129
+ videoElement: { css: { height: 41, top: 3, x: 0 } },
130
+ },
131
+ image: { style: { h: 50, w: 100, x: 0 } },
132
+ mainText: {
133
+ base: {
134
+ text: { ...textBase },
135
+ audio: {
136
+ iconUrl: IconUrls.volumeUpSvg,
137
+ css: { ...audioBase },
138
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
139
+ cssEnabled: { opacity: 0.8, cursor: "pointer" },
140
+ },
141
+ },
142
+ notMediaHasAudio: {
143
+ text: { ...textHigh },
144
+ audio: { ...audioHigh },
145
+ },
146
+ hasMediaNotAudio: {
147
+ text: { ...textHigh },
148
+ },
149
+ notMediaNotAudio: { text: { ...textHigh } },
150
+ hasMediaHasAudio: { text: { ...textLow }, audio: { ...audioLow } },
151
+ },
152
+
153
+ buttonBar: {
154
+ vibrateMs: false,
155
+ container: {
156
+ base: {
157
+ display: "flex",
158
+ justifyContent: "space-evenly",
159
+ position: "absolute",
160
+ width: 100,
161
+ height: 15,
162
+ bottom: 0,
163
+ left: 0, // h: 10,
164
+ alignItems: "center",
165
+ backgroundColor: "yellow",
166
+ },
167
+ whenSingle: { justifyContent: "space-evenly" },
168
+ whenMany: { justifyContent: "space-evenly" },
169
+ },
170
+ nextButtonTheme: BuilderOptionTheme.blueButton(),
171
+ responseButtons: BuilderOptionTheme.blueButton(),
172
+ },
173
+ };
@@ -0,0 +1,125 @@
1
+ import { DStyle } from "@media-quest/engine";
2
+ import type { CssTheme } from "./css-theme";
3
+
4
+ type PStyle = Partial<DStyle>;
5
+ export interface IDefaultTheme {
6
+ name: string;
7
+ schemaBackgroundColor: string;
8
+ dimensions: {
9
+ baseHeight: number;
10
+ baseWidth: number;
11
+ };
12
+
13
+ pageBackGroundImage?: { url: string; style: PStyle };
14
+
15
+ pageBackGround?: { style: PStyle };
16
+
17
+ backGroundArea1?: { style: PStyle };
18
+
19
+ backGroundArea2?: { style: PStyle };
20
+
21
+ backGroundArea3?: { style: PStyle };
22
+
23
+ progressBar?: {
24
+ width: number;
25
+ height: number;
26
+ bottom: number;
27
+ left: number;
28
+ backgroundStyles: PStyle;
29
+ progressStyles: PStyle;
30
+ text?: {
31
+ style: PStyle;
32
+ textType: "percent" | "page-progress";
33
+ };
34
+ };
35
+
36
+ image: { style: PStyle };
37
+ videoPlayer: {
38
+ playButton: {
39
+ iconUrl: string;
40
+ css: PStyle;
41
+ cssDisabled: PStyle;
42
+ cssEnabled: PStyle;
43
+ text?: { text: string; css: PStyle };
44
+ };
45
+
46
+ buttonBar?: PStyle;
47
+
48
+ pauseButton: {
49
+ iconUrl: string;
50
+ css: PStyle;
51
+ cssDisabled: PStyle;
52
+ cssEnabled: PStyle;
53
+ text?: { text: string; css: PStyle };
54
+ };
55
+
56
+ replayButton?: {
57
+ iconUrl: string;
58
+ css: PStyle;
59
+ cssDisabled: PStyle;
60
+ cssEnabled: PStyle;
61
+ text?: { text: string; css: PStyle };
62
+ };
63
+
64
+ muteButton?: {
65
+ iconUrl: string;
66
+ css: PStyle;
67
+ text?: { text: string; css: PStyle };
68
+ };
69
+
70
+ unMuteButton?: {
71
+ iconUrl: string;
72
+ css: PStyle;
73
+ text?: { text: string; css: PStyle };
74
+ };
75
+
76
+ videoElement: {
77
+ css: PStyle;
78
+ };
79
+ };
80
+ mainText: {
81
+ base: {
82
+ text: PStyle;
83
+ audio: { css: PStyle; cssDisabled: PStyle; cssEnabled: PStyle; iconUrl: string };
84
+ };
85
+
86
+ notMediaNotAudio: {
87
+ text: PStyle;
88
+ };
89
+
90
+ hasMediaNotAudio: {
91
+ text: PStyle;
92
+ };
93
+
94
+ hasMediaHasAudio: {
95
+ text: PStyle;
96
+ audio: PStyle;
97
+ };
98
+
99
+ notMediaHasAudio: {
100
+ text: PStyle;
101
+ audio: PStyle;
102
+ };
103
+ };
104
+
105
+ buttonBar: {
106
+ vibrateMs: number | false;
107
+ container: { base: PStyle; whenSingle: PStyle; whenMany: PStyle };
108
+ responseButtons: BuilderOptionTheme;
109
+ nextButtonTheme: BuilderOptionTheme;
110
+ };
111
+ // buttonThemes?: Array<BuilderOptionTheme>;
112
+ }
113
+
114
+ interface ButtonTheme {
115
+ btn: CssTheme;
116
+ divider: PStyle;
117
+ text1: PStyle;
118
+ text2: PStyle;
119
+ }
120
+
121
+ export interface BuilderOptionTheme {
122
+ name: string;
123
+ normal: ButtonTheme;
124
+ dontKnow: ButtonTheme;
125
+ }
@@ -0,0 +1,10 @@
1
+ import type { BuilderSchemaDto } from "../Builder-schema";
2
+ import { SchemaDto } from "@media-quest/engine";
3
+
4
+ export interface ThemeCompiler<ThemeSchema> {
5
+ currentTheme: ThemeSchema;
6
+ allThemes: ThemeSchema[];
7
+ setTheme(theme: ThemeSchema): void;
8
+ // protected constructor(protected readonly theme: ThemeSchema) {}
9
+ compile(schema: BuilderSchemaDto): SchemaDto;
10
+ }
@@ -0,0 +1,31 @@
1
+ import { DefaultThemeCompiler } from "./default-theme-compiler";
2
+ import { BuilderSchema } from "../Builder-schema";
3
+ import { SchemaID } from "../primitives/ID";
4
+ import { SchemaPrefix } from "../primitives/schema-prefix";
5
+ import { Theme2 } from "./theme2";
6
+
7
+ let builder = BuilderSchema.create(
8
+ SchemaID.create(),
9
+ "test-schema",
10
+ SchemaPrefix.fromValueOrThrow("prefix").value,
11
+ );
12
+
13
+ beforeEach(() => {
14
+ builder = BuilderSchema.create(
15
+ SchemaID.create(),
16
+ "test-schema",
17
+ SchemaPrefix.fromValueOrThrow("prefix").value,
18
+ );
19
+ });
20
+ describe("Default Theme compiler works", () => {
21
+ test("Dimensions from theme is used.", () => {
22
+ const compiler = new DefaultThemeCompiler();
23
+ compiler.setTheme(Theme2);
24
+ builder.baseHeight = 100;
25
+ builder.baseWidth = 100;
26
+
27
+ const compiledSchema = compiler.compile(builder.toJson());
28
+ expect(compiledSchema.baseHeight).toBe(Theme2.dimensions.baseHeight);
29
+ expect(compiledSchema.baseWidth).toBe(Theme2.dimensions.baseWidth);
30
+ });
31
+ });