@wg-npm/survey-core 0.3.480-5.release → 0.3.489-9.release
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/survey-core.esm.js +15 -11
- package/package.json +1 -1
- package/src/array-utils.ts +6 -2
- package/src/index.ts +29 -31
- package/src/locale-utils.ts +18 -8
- package/src/models.ts +275 -278
- package/src/quetion-factory.ts +70 -70
package/dist/survey-core.esm.js
CHANGED
|
@@ -54,7 +54,7 @@ class QuestionFactory {
|
|
|
54
54
|
this.creatorHash[questionType] = questionCreator;
|
|
55
55
|
}
|
|
56
56
|
createQuestion(questionType) {
|
|
57
|
-
|
|
57
|
+
const creator = this.creatorHash[questionType];
|
|
58
58
|
return creator(this.locale);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -69,7 +69,7 @@ class ChoiceModel {
|
|
|
69
69
|
this.options = {
|
|
70
70
|
score: null,
|
|
71
71
|
star: false,
|
|
72
|
-
starCount: null
|
|
72
|
+
starCount: null,
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
static createChoiceId() {
|
|
@@ -135,7 +135,7 @@ class BaseQuestionModel {
|
|
|
135
135
|
return _.sumBy(question.choices, (item) => parseFloat(_.get(item, "options.score") || 0));
|
|
136
136
|
}
|
|
137
137
|
else if (question.type == "MATRIX") {
|
|
138
|
-
|
|
138
|
+
const score = _.max(_.map(question.choices, (choice) => parseFloat(_.get(choice, "options.score", 0) || 0)));
|
|
139
139
|
return score * question.subQuestions.length;
|
|
140
140
|
}
|
|
141
141
|
return 0;
|
|
@@ -153,7 +153,7 @@ class BaseQuestionModel {
|
|
|
153
153
|
}
|
|
154
154
|
static calculationAllQuestionCount(questions) {
|
|
155
155
|
let count = 0;
|
|
156
|
-
|
|
156
|
+
const exclude = ["TEXT_TITLE"];
|
|
157
157
|
_.forEach(questions, (question) => {
|
|
158
158
|
if (!_.includes(exclude, question.type)) {
|
|
159
159
|
count++;
|
|
@@ -251,7 +251,7 @@ class QuestionMatrixModel extends BaseQuestionModel {
|
|
|
251
251
|
this.subQuestions = [QuestionFactory.createSubQuestion(locale)];
|
|
252
252
|
}
|
|
253
253
|
static getNumber(preNumber, question) {
|
|
254
|
-
|
|
254
|
+
const number = preNumber + 1;
|
|
255
255
|
_.forEach(question.subQuestions, (sq, index) => {
|
|
256
256
|
sq.number = index + 1;
|
|
257
257
|
});
|
|
@@ -271,23 +271,27 @@ const ZH_CN = _.camelCase("zh-CN");
|
|
|
271
271
|
const EN_US = _.camelCase("en-US");
|
|
272
272
|
const ZH_TW = _.camelCase("zh-TW");
|
|
273
273
|
function getValue(obj, locale) {
|
|
274
|
-
|
|
274
|
+
const value = _.get(obj, _.camelCase(locale), "");
|
|
275
275
|
if (!_.isEmpty(value)) {
|
|
276
276
|
return value;
|
|
277
277
|
}
|
|
278
|
-
return _.get(obj, locale,
|
|
278
|
+
return _.get(obj, locale, "");
|
|
279
279
|
}
|
|
280
280
|
function translate(obj, locale, prettyMath = false) {
|
|
281
|
-
|
|
281
|
+
const value = getValue(obj, locale);
|
|
282
282
|
if (!_.isEmpty(value) || !prettyMath) {
|
|
283
283
|
return value;
|
|
284
284
|
}
|
|
285
|
-
return obj[ZH_CN] ||
|
|
286
|
-
|
|
285
|
+
return (obj[ZH_CN] ||
|
|
286
|
+
obj["zh-CN"] ||
|
|
287
|
+
obj[EN_US] ||
|
|
288
|
+
obj["en-US"] ||
|
|
289
|
+
obj[ZH_TW] ||
|
|
290
|
+
obj["zh-TW"]);
|
|
287
291
|
}
|
|
288
292
|
|
|
289
293
|
function move(array, fromIndex, toIndex) {
|
|
290
|
-
|
|
294
|
+
const moveValue = array[fromIndex];
|
|
291
295
|
array[fromIndex] = array[toIndex];
|
|
292
296
|
array[toIndex] = moveValue;
|
|
293
297
|
}
|
package/package.json
CHANGED
package/src/array-utils.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export function move(
|
|
2
|
-
|
|
1
|
+
export function move(
|
|
2
|
+
array: Array<any>,
|
|
3
|
+
fromIndex: number,
|
|
4
|
+
toIndex: number
|
|
5
|
+
): void {
|
|
6
|
+
const moveValue: any = array[fromIndex];
|
|
3
7
|
array[fromIndex] = array[toIndex];
|
|
4
8
|
array[toIndex] = moveValue;
|
|
5
9
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,35 +1,33 @@
|
|
|
1
1
|
export {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
2
|
+
SurveyLocales,
|
|
3
|
+
SurveyLayout,
|
|
4
|
+
QuestionType,
|
|
5
|
+
ResponseStatisticsModel,
|
|
6
|
+
PlanStatisticsModel,
|
|
7
|
+
QuestionOptionsModel,
|
|
8
|
+
QuestionHeaderModel,
|
|
9
|
+
BaseQuestionModel,
|
|
10
|
+
QuestionCheckBoxModel,
|
|
11
|
+
QuestionTextTitleModel,
|
|
12
|
+
QuestionMatrixModel,
|
|
13
|
+
QuestionFillBlankModel,
|
|
14
|
+
QuestionMulitSelectionModel,
|
|
15
|
+
QuestionShortAnswerModel,
|
|
16
|
+
QuestionSingleSelectionModel,
|
|
17
|
+
QuestionEvaluationModel,
|
|
18
|
+
SubQuestionModel,
|
|
19
|
+
SurveyOptionsModel,
|
|
20
|
+
SurveyModel,
|
|
21
|
+
ChoiceModel,
|
|
22
|
+
ResponseModel,
|
|
23
|
+
PlanModel,
|
|
24
|
+
EvaluationType,
|
|
25
|
+
EvaluationItemModel,
|
|
26
|
+
StarEvaluationItemModel,
|
|
27
|
+
ExprEvaluationItemModel,
|
|
28
|
+
ExprConditionModel,
|
|
29
|
+
ExprConditionType,
|
|
30
30
|
} from "./models";
|
|
31
|
-
export {
|
|
32
|
-
QuestionFactory
|
|
33
|
-
} from "./quetion-factory"
|
|
31
|
+
export { QuestionFactory } from "./quetion-factory";
|
|
34
32
|
export { translate } from "./locale-utils";
|
|
35
33
|
export { move } from "./array-utils";
|
package/src/locale-utils.ts
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
import _ from
|
|
2
|
-
import { SurveyLocales } from
|
|
1
|
+
import _ from "lodash";
|
|
2
|
+
import { SurveyLocales } from "./models";
|
|
3
3
|
|
|
4
4
|
const ZH_CN: string = _.camelCase(SurveyLocales.ZH_CN);
|
|
5
5
|
const EN_US: string = _.camelCase(SurveyLocales.EN_US);
|
|
6
6
|
const ZH_TW: string = _.camelCase(SurveyLocales.ZH_TW);
|
|
7
7
|
|
|
8
8
|
function getValue(obj: any, locale: string) {
|
|
9
|
-
|
|
9
|
+
const value: any = _.get(obj, _.camelCase(locale), "");
|
|
10
10
|
if (!_.isEmpty(value)) {
|
|
11
11
|
return value;
|
|
12
12
|
}
|
|
13
|
-
return _.get(obj, locale,
|
|
13
|
+
return _.get(obj, locale, "");
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export function translate(
|
|
17
|
-
|
|
16
|
+
export function translate(
|
|
17
|
+
obj: any,
|
|
18
|
+
locale: string,
|
|
19
|
+
prettyMath: boolean = false
|
|
20
|
+
): any {
|
|
21
|
+
const value: any = getValue(obj, locale);
|
|
18
22
|
if (!_.isEmpty(value) || !prettyMath) {
|
|
19
23
|
return value;
|
|
20
24
|
}
|
|
21
|
-
return
|
|
22
|
-
|
|
25
|
+
return (
|
|
26
|
+
obj[ZH_CN] ||
|
|
27
|
+
obj[SurveyLocales.ZH_CN] ||
|
|
28
|
+
obj[EN_US] ||
|
|
29
|
+
obj[SurveyLocales.EN_US] ||
|
|
30
|
+
obj[ZH_TW] ||
|
|
31
|
+
obj[SurveyLocales.ZH_TW]
|
|
32
|
+
);
|
|
23
33
|
}
|
package/src/models.ts
CHANGED
|
@@ -1,390 +1,387 @@
|
|
|
1
1
|
import _ from "lodash";
|
|
2
|
-
import {QuestionFactory} from "./quetion-factory";
|
|
2
|
+
import { QuestionFactory } from "./quetion-factory";
|
|
3
3
|
|
|
4
4
|
const defaultText = function getText(locale: string): object {
|
|
5
|
-
|
|
5
|
+
return _.set({}, locale, "");
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
export const enum SurveyLocales {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
ZH_CN = "zh-CN",
|
|
10
|
+
ZH_TW = "zh-TW",
|
|
11
|
+
EN_US = "en-US",
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export const enum SurveyLayout {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
HORIZONTAL = "HORIZONTAL",
|
|
16
|
+
VERTICAL = "VERTICAL",
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const enum QuestionType {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
SINGLE_SELECTION = "SINGLE_SELECTION",
|
|
21
|
+
MULTI_SELECTION = "MULTI_SELECTION",
|
|
22
|
+
FILL_BLANK = "FILL_BLANK",
|
|
23
|
+
SHORT_ANSWER = "SHORT_ANSWER",
|
|
24
|
+
MATRIX = "MATRIX",
|
|
25
|
+
TEXT_TITLE = "TEXT_TITLE",
|
|
26
|
+
EVALUATION = "EVALUATION",
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export const enum EvaluationType {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
STAR = "STAR",
|
|
31
|
+
EXPR = "EXPR",
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export const enum ExprConditionType {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
ASSIGN = "ASSIGN",
|
|
36
|
+
AUTO = "AUTO",
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export const enum ExprEvaluationItemType {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
IF = "IF",
|
|
41
|
+
ELSE = "ELSE",
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export class ChoiceModel {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
constructor(locale: string) {
|
|
50
|
-
this.id = ChoiceModel.createChoiceId();
|
|
51
|
-
this.text = defaultText(locale);
|
|
52
|
-
this.options = {
|
|
53
|
-
score: null,
|
|
54
|
-
star: false,
|
|
55
|
-
starCount: null
|
|
56
|
-
};
|
|
57
|
-
}
|
|
45
|
+
id: string;
|
|
46
|
+
options?: Object;
|
|
47
|
+
text: object;
|
|
58
48
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
constructor(locale: string) {
|
|
50
|
+
this.id = ChoiceModel.createChoiceId();
|
|
51
|
+
this.text = defaultText(locale);
|
|
52
|
+
this.options = {
|
|
53
|
+
score: null,
|
|
54
|
+
star: false,
|
|
55
|
+
starCount: null,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static createChoiceId(): string {
|
|
60
|
+
return `Choice-${_.now()}-${_.random(0, 9999999)}`;
|
|
61
|
+
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export class LevelRange {
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
min?: Number;
|
|
66
|
+
max?: Number;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export class EvaluationItemModel {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
id: string;
|
|
71
|
+
options?: Object;
|
|
72
|
+
text: object;
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
constructor(locale: string) {
|
|
75
|
+
this.id = EvaluationItemModel.createChoiceId();
|
|
76
|
+
this.text = defaultText(locale);
|
|
77
|
+
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
static createChoiceId(): string {
|
|
80
|
+
return `Evaluation-Item-${_.now()}-${_.random(0, 9999999)}`;
|
|
81
|
+
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
export class StarEvaluationItemModel extends EvaluationItemModel {
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
level?: Number;
|
|
86
|
+
range?: LevelRange;
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
constructor(locale: string) {
|
|
89
|
+
super(locale);
|
|
90
|
+
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export class ExprEvaluationItemModel extends EvaluationItemModel {
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
type: ExprEvaluationItemType;
|
|
95
|
+
conditions?: Array<ExprConditionModel>;
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
constructor(locale: string, type: ExprEvaluationItemType) {
|
|
98
|
+
super(locale);
|
|
99
|
+
this.type = type;
|
|
100
|
+
}
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
export class ExprConditionModel {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
type: ExprConditionType;
|
|
105
|
+
expr?: string;
|
|
106
|
+
desc?: string;
|
|
107
|
+
payload?: any;
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
constructor(type: ExprConditionType) {
|
|
110
|
+
this.type = type;
|
|
111
|
+
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
export class QuestionOptionsModel {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
115
|
+
required: Boolean;
|
|
116
|
+
visible: Boolean;
|
|
117
|
+
layout?: SurveyLayout;
|
|
118
|
+
wordLimit?: Number;
|
|
119
|
+
scoringEnabled?: Boolean;
|
|
120
|
+
starEnabled?: Boolean;
|
|
121
|
+
starMinCount?: Number;
|
|
122
|
+
|
|
123
|
+
constructor(required: Boolean) {
|
|
124
|
+
this.required = required;
|
|
125
|
+
this.visible = true;
|
|
126
|
+
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
export class QuestionHeaderModel {
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
number?: Number | null;
|
|
131
|
+
text: Object;
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
constructor(locale: string) {
|
|
134
|
+
this.text = defaultText(locale);
|
|
135
|
+
this.number = null;
|
|
136
|
+
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
export class SubQuestionModel {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
140
|
+
id: string;
|
|
141
|
+
number?: Number | null;
|
|
142
|
+
text?: Object;
|
|
143
|
+
|
|
144
|
+
constructor(locale: string) {
|
|
145
|
+
this.id = `SubQ-${_.now()}-${_.random(0, 9999999)}`;
|
|
146
|
+
this.text = defaultText(locale);
|
|
147
|
+
this.number = null;
|
|
148
|
+
}
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
export class QuestionExprModel {
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
id: string;
|
|
153
|
+
answer: any;
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
155
|
+
constructor(id: string, answer: any) {
|
|
156
|
+
this.id = id;
|
|
157
|
+
this.answer = answer;
|
|
158
|
+
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
export class BaseQuestionModel {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
162
|
+
id: string;
|
|
163
|
+
type: string;
|
|
164
|
+
options: QuestionOptionsModel;
|
|
165
|
+
header: QuestionHeaderModel;
|
|
166
|
+
|
|
167
|
+
constructor(type: string, locale: string) {
|
|
168
|
+
this.id = BaseQuestionModel.createQuestionId();
|
|
169
|
+
this.type = type;
|
|
170
|
+
this.header = new QuestionHeaderModel(locale);
|
|
171
|
+
this.options = new QuestionOptionsModel(false);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
static getMaxScore(question): number {
|
|
175
|
+
if (question.type == QuestionType.SINGLE_SELECTION) {
|
|
176
|
+
return _.max(
|
|
177
|
+
_.map(question.choices, (choice) =>
|
|
178
|
+
parseFloat(_.get(choice, "options.score", 0) || 0)
|
|
179
|
+
)
|
|
180
|
+
);
|
|
181
|
+
} else if (question.type == QuestionType.MULTI_SELECTION) {
|
|
182
|
+
return _.sumBy(question.choices, (item) =>
|
|
183
|
+
parseFloat(_.get(item, "options.score") || 0)
|
|
184
|
+
);
|
|
185
|
+
} else if (question.type == QuestionType.MATRIX) {
|
|
186
|
+
const score = _.max(
|
|
187
|
+
_.map(question.choices, (choice) =>
|
|
188
|
+
parseFloat(_.get(choice, "options.score", 0) || 0)
|
|
189
|
+
)
|
|
190
|
+
);
|
|
191
|
+
return score * question.subQuestions.length;
|
|
192
|
+
}
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
static createQuestionId(): string {
|
|
197
|
+
return `Q-${_.now()}-${_.random(0, 9999999)}`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static getNumber(
|
|
201
|
+
preNumber: number,
|
|
202
|
+
question: BaseQuestionModel
|
|
203
|
+
): null | number {
|
|
204
|
+
return preNumber + 1;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static refreshSurvey(survey): void {
|
|
208
|
+
this.rebuildQuestionNumber(survey.questions);
|
|
209
|
+
survey.statistics.maxScore = this.calculationAllQuestionMaxScore(
|
|
210
|
+
survey.questions
|
|
211
|
+
);
|
|
212
|
+
survey.statistics.questionCount = this.calculationAllQuestionCount(
|
|
213
|
+
survey.questions
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
static calculationAllQuestionCount(questions): number {
|
|
218
|
+
let count = 0;
|
|
219
|
+
const exclude = [QuestionType.TEXT_TITLE];
|
|
220
|
+
_.forEach(questions, (question) => {
|
|
221
|
+
if (!_.includes(exclude, question.type)) {
|
|
222
|
+
count++;
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
return count;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
static calculationAllQuestionMaxScore(questions): number {
|
|
229
|
+
let maxScore = 0;
|
|
230
|
+
_.forEach(questions, (question) => {
|
|
231
|
+
maxScore += this.getMaxScore(question);
|
|
232
|
+
});
|
|
233
|
+
return maxScore;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static setActiveQuestion(currentQuestion, questions): void {
|
|
237
|
+
_.forEach(questions, (question) => {
|
|
238
|
+
if (question.id == currentQuestion.id) {
|
|
239
|
+
question.active = true;
|
|
240
|
+
} else {
|
|
241
|
+
question.active = false;
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
static rebuildQuestionNumber(questions): void {
|
|
247
|
+
let preNumber = 0;
|
|
248
|
+
_.forEach(questions, function (question: BaseQuestionModel) {
|
|
249
|
+
let number;
|
|
250
|
+
if (question.type === QuestionType.TEXT_TITLE) {
|
|
251
|
+
number = QuestionTextTitleModel.getNumber(preNumber, question);
|
|
252
|
+
} else if (question.type === QuestionType.MATRIX) {
|
|
253
|
+
number = QuestionMatrixModel.getNumber(
|
|
254
|
+
preNumber,
|
|
255
|
+
question as QuestionMatrixModel
|
|
215
256
|
);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
});
|
|
226
|
-
return count;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
static calculationAllQuestionMaxScore(questions): number {
|
|
230
|
-
let maxScore = 0;
|
|
231
|
-
_.forEach(questions, (question) => {
|
|
232
|
-
maxScore += this.getMaxScore(question);
|
|
233
|
-
});
|
|
234
|
-
return maxScore;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
static setActiveQuestion(currentQuestion, questions): void {
|
|
238
|
-
_.forEach(questions, (question) => {
|
|
239
|
-
if (question.id == currentQuestion.id) {
|
|
240
|
-
question.active = true;
|
|
241
|
-
} else {
|
|
242
|
-
question.active = false;
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
static rebuildQuestionNumber(questions): void {
|
|
248
|
-
let preNumber = 0;
|
|
249
|
-
_.forEach(questions, function (question: BaseQuestionModel) {
|
|
250
|
-
let number;
|
|
251
|
-
if (question.type === QuestionType.TEXT_TITLE) {
|
|
252
|
-
number = QuestionTextTitleModel.getNumber(preNumber, question);
|
|
253
|
-
} else if (question.type === QuestionType.MATRIX) {
|
|
254
|
-
number = QuestionMatrixModel.getNumber(
|
|
255
|
-
preNumber,
|
|
256
|
-
question as QuestionMatrixModel
|
|
257
|
-
);
|
|
258
|
-
} else {
|
|
259
|
-
number = BaseQuestionModel.getNumber(preNumber, question);
|
|
260
|
-
}
|
|
261
|
-
question.header.number = number;
|
|
262
|
-
if (number) {
|
|
263
|
-
preNumber = number;
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
}
|
|
257
|
+
} else {
|
|
258
|
+
number = BaseQuestionModel.getNumber(preNumber, question);
|
|
259
|
+
}
|
|
260
|
+
question.header.number = number;
|
|
261
|
+
if (number) {
|
|
262
|
+
preNumber = number;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
267
266
|
}
|
|
268
267
|
|
|
269
268
|
export class QuestionCheckBoxModel extends BaseQuestionModel {
|
|
270
|
-
|
|
269
|
+
choices: Array<any>;
|
|
271
270
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
271
|
+
constructor(type: QuestionType, locale: string) {
|
|
272
|
+
super(type, locale);
|
|
273
|
+
this.choices = QuestionFactory.createSelectionQuestionChoices(locale);
|
|
274
|
+
}
|
|
276
275
|
}
|
|
277
276
|
|
|
278
277
|
export class QuestionEvaluationModel extends BaseQuestionModel {
|
|
279
|
-
|
|
278
|
+
evaluationItems: Array<EvaluationItemModel>;
|
|
280
279
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
280
|
+
constructor(type: QuestionType, locale: string) {
|
|
281
|
+
super(type, locale);
|
|
282
|
+
this.evaluationItems = QuestionFactory.createEvaluationItems(locale);
|
|
283
|
+
}
|
|
285
284
|
}
|
|
286
285
|
|
|
287
286
|
export class QuestionTextTitleModel extends BaseQuestionModel {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
constructor(type: QuestionType, locale: string) {
|
|
288
|
+
super(type, locale);
|
|
289
|
+
}
|
|
291
290
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
291
|
+
static getNumber(
|
|
292
|
+
preNumber: number,
|
|
293
|
+
question: BaseQuestionModel
|
|
294
|
+
): null | number {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
298
297
|
}
|
|
299
298
|
|
|
300
299
|
export class QuestionFillBlankModel extends BaseQuestionModel {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
300
|
+
constructor(type: QuestionType, locale: string) {
|
|
301
|
+
super(type, locale);
|
|
302
|
+
}
|
|
304
303
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
304
|
+
static getNumber(
|
|
305
|
+
preNumber: number,
|
|
306
|
+
question: BaseQuestionModel
|
|
307
|
+
): null | number {
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
311
310
|
}
|
|
312
311
|
|
|
313
312
|
export class QuestionShortAnswerModel extends BaseQuestionModel {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
313
|
+
constructor(type: QuestionType, locale: string) {
|
|
314
|
+
super(type, locale);
|
|
315
|
+
}
|
|
317
316
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
317
|
+
getNumber(preNumber: number): null | number {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
321
320
|
}
|
|
322
321
|
|
|
323
322
|
export class QuestionSingleSelectionModel extends QuestionCheckBoxModel {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
323
|
+
constructor(type: QuestionType, locale: string) {
|
|
324
|
+
super(type, locale);
|
|
325
|
+
}
|
|
327
326
|
}
|
|
328
327
|
|
|
329
328
|
export class QuestionMulitSelectionModel extends QuestionCheckBoxModel {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
329
|
+
constructor(type: QuestionType, locale: string) {
|
|
330
|
+
super(type, locale);
|
|
331
|
+
}
|
|
333
332
|
}
|
|
334
333
|
|
|
335
334
|
export class QuestionMatrixModel extends BaseQuestionModel {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
335
|
+
choices: Array<any>;
|
|
336
|
+
subQuestions: Array<SubQuestionModel>;
|
|
337
|
+
|
|
338
|
+
constructor(type: QuestionType, locale: string) {
|
|
339
|
+
super(type, locale);
|
|
340
|
+
this.choices = QuestionFactory.createMatrixQuestionChoices(locale);
|
|
341
|
+
this.subQuestions = [QuestionFactory.createSubQuestion(locale)];
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
static getNumber(
|
|
345
|
+
preNumber: number,
|
|
346
|
+
question: QuestionMatrixModel
|
|
347
|
+
): null | number {
|
|
348
|
+
const number = preNumber + 1;
|
|
349
|
+
_.forEach(question.subQuestions, (sq, index) => {
|
|
350
|
+
sq.number = index + 1;
|
|
351
|
+
});
|
|
352
|
+
return number;
|
|
353
|
+
}
|
|
355
354
|
}
|
|
356
355
|
|
|
357
356
|
export interface SurveyOptionsModel {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
357
|
+
primaryLanguage: SurveyLocales;
|
|
358
|
+
languages: SurveyLocales[];
|
|
359
|
+
layout: SurveyLayout;
|
|
361
360
|
}
|
|
362
361
|
|
|
363
362
|
export interface SurveyStatisticsModel {
|
|
364
|
-
|
|
365
|
-
|
|
363
|
+
maxScore: Number;
|
|
364
|
+
questionCount: Number;
|
|
366
365
|
}
|
|
367
366
|
|
|
368
367
|
export interface SurveyModel {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
368
|
+
id: string;
|
|
369
|
+
name: any;
|
|
370
|
+
options: SurveyOptionsModel;
|
|
371
|
+
statistics: SurveyStatisticsModel;
|
|
372
|
+
questions: BaseQuestionModel[];
|
|
374
373
|
}
|
|
375
374
|
|
|
376
375
|
export class ResponseModel {
|
|
377
|
-
|
|
376
|
+
id?: string;
|
|
378
377
|
}
|
|
379
378
|
|
|
380
379
|
export class PlanModel {
|
|
381
|
-
|
|
380
|
+
id?: string;
|
|
382
381
|
}
|
|
383
382
|
|
|
384
383
|
//todo remove
|
|
385
|
-
export class PlanStatisticsModel {
|
|
386
|
-
}
|
|
384
|
+
export class PlanStatisticsModel {}
|
|
387
385
|
|
|
388
386
|
//todo remove
|
|
389
|
-
export class ResponseStatisticsModel {
|
|
390
|
-
}
|
|
387
|
+
export class ResponseStatisticsModel {}
|
package/src/quetion-factory.ts
CHANGED
|
@@ -1,90 +1,90 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
BaseQuestionModel,
|
|
3
|
+
ChoiceModel,
|
|
4
|
+
QuestionType,
|
|
5
|
+
QuestionMatrixModel,
|
|
6
|
+
QuestionTextTitleModel,
|
|
7
|
+
QuestionCheckBoxModel,
|
|
8
|
+
SubQuestionModel,
|
|
9
|
+
QuestionEvaluationModel,
|
|
10
|
+
StarEvaluationItemModel,
|
|
11
11
|
} from "./models";
|
|
12
12
|
import _ from "lodash";
|
|
13
13
|
|
|
14
14
|
interface HashTable<T> {
|
|
15
|
-
|
|
15
|
+
[key: string]: T;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export class QuestionFactory {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
private creatorHash: HashTable<(locale: string) => BaseQuestionModel> = {};
|
|
20
|
+
private static instance: QuestionFactory;
|
|
21
|
+
private locale: string;
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
return QuestionFactory.instance;
|
|
23
|
+
public static getInstance(locale: string): QuestionFactory {
|
|
24
|
+
if (!QuestionFactory.instance) {
|
|
25
|
+
QuestionFactory.instance = new QuestionFactory(locale);
|
|
28
26
|
}
|
|
27
|
+
return QuestionFactory.instance;
|
|
28
|
+
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
30
|
+
private constructor(locale: string) {
|
|
31
|
+
this.locale = locale;
|
|
32
|
+
this.registerQuestion(QuestionType.FILL_BLANK, (locale: string) => {
|
|
33
|
+
return new BaseQuestionModel(QuestionType.FILL_BLANK, locale);
|
|
34
|
+
});
|
|
35
|
+
this.registerQuestion(QuestionType.SHORT_ANSWER, (locale: string) => {
|
|
36
|
+
return new BaseQuestionModel(QuestionType.SHORT_ANSWER, locale);
|
|
37
|
+
});
|
|
38
|
+
this.registerQuestion(QuestionType.MATRIX, (locale: string) => {
|
|
39
|
+
return new QuestionMatrixModel(QuestionType.MATRIX, locale);
|
|
40
|
+
});
|
|
41
|
+
this.registerQuestion(QuestionType.TEXT_TITLE, (locale: string) => {
|
|
42
|
+
return new QuestionTextTitleModel(QuestionType.TEXT_TITLE, locale);
|
|
43
|
+
});
|
|
44
|
+
this.registerQuestion(QuestionType.SINGLE_SELECTION, (locale: string) => {
|
|
45
|
+
return new QuestionCheckBoxModel(QuestionType.SINGLE_SELECTION, locale);
|
|
46
|
+
});
|
|
47
|
+
this.registerQuestion(QuestionType.MULTI_SELECTION, (locale: string) => {
|
|
48
|
+
return new QuestionCheckBoxModel(QuestionType.MULTI_SELECTION, locale);
|
|
49
|
+
});
|
|
50
|
+
this.registerQuestion(QuestionType.EVALUATION, (locale: string) => {
|
|
51
|
+
return new QuestionEvaluationModel(QuestionType.EVALUATION, locale);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
public static createDefault(locale: string): ChoiceModel {
|
|
56
|
+
return new ChoiceModel(locale);
|
|
57
|
+
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
public static createSubQuestion(locale: string): SubQuestionModel {
|
|
60
|
+
return new SubQuestionModel(locale);
|
|
61
|
+
}
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
public static createEvaluationItem(locale: string): ChoiceModel {
|
|
64
|
+
return new StarEvaluationItemModel(locale);
|
|
65
|
+
}
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
public static createSelectionQuestionChoices(locale: string) {
|
|
68
|
+
return _.range(4).map(() => this.createDefault(locale));
|
|
69
|
+
}
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
public static createMatrixQuestionChoices(locale: string) {
|
|
72
|
+
return _.range(5).map(() => this.createDefault(locale));
|
|
73
|
+
}
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
public static createEvaluationItems(locale: string) {
|
|
76
|
+
return _.range(5).map(() => this.createEvaluationItem(locale));
|
|
77
|
+
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
public registerQuestion(
|
|
80
|
+
questionType: string,
|
|
81
|
+
questionCreator: (locale: string) => BaseQuestionModel
|
|
82
|
+
) {
|
|
83
|
+
this.creatorHash[questionType] = questionCreator;
|
|
84
|
+
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
public createQuestion(questionType: string): BaseQuestionModel {
|
|
87
|
+
const creator = this.creatorHash[questionType];
|
|
88
|
+
return creator(this.locale);
|
|
89
|
+
}
|
|
90
90
|
}
|