@wg-npm/survey-core 0.1.272 → 0.2.0

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.
@@ -1,27 +1,295 @@
1
- var TemplateModel = /** @class */ (function () {
2
- function TemplateModel() {
3
- }
4
- return TemplateModel;
5
- }());
6
- var SurveyModel = /** @class */ (function () {
7
- function SurveyModel() {
8
- }
9
- return SurveyModel;
10
- }());
11
- var ResponseModel = /** @class */ (function () {
12
- function ResponseModel() {
13
- }
14
- return ResponseModel;
15
- }());
16
- var QuestionModel = /** @class */ (function () {
17
- function QuestionModel() {
18
- }
19
- return QuestionModel;
20
- }());
21
- var PlanModel = /** @class */ (function () {
22
- function PlanModel() {
23
- }
24
- return PlanModel;
25
- }());
1
+ import _ from 'lodash';
26
2
 
27
- export { PlanModel, QuestionModel, ResponseModel, SurveyModel, TemplateModel };
3
+ class QuestionFactory {
4
+ constructor(locale) {
5
+ this.creatorHash = {};
6
+ this.locale = locale;
7
+ this.registerQuestion("FILL_BLANK", (locale) => {
8
+ return new BaseQuestionModel("FILL_BLANK", locale);
9
+ });
10
+ this.registerQuestion("SHORT_ANSWER", (locale) => {
11
+ return new BaseQuestionModel("SHORT_ANSWER", locale);
12
+ });
13
+ this.registerQuestion("MATRIX", (locale) => {
14
+ return new QuestionMatrixModel("MATRIX", locale);
15
+ });
16
+ this.registerQuestion("TEXT_TITLE", (locale) => {
17
+ return new QuestionTextTitleModel("TEXT_TITLE", locale);
18
+ });
19
+ this.registerQuestion("SINGLE_SELECTION", (locale) => {
20
+ return new QuestionCheckBoxModel("SINGLE_SELECTION", locale);
21
+ });
22
+ this.registerQuestion("MULTI_SELECTION", (locale) => {
23
+ return new QuestionCheckBoxModel("MULTI_SELECTION", locale);
24
+ });
25
+ this.registerQuestion("EVALUATION", (locale) => {
26
+ return new QuestionEvaluationModel("EVALUATION", locale);
27
+ });
28
+ }
29
+ static getInstance(locale) {
30
+ if (!QuestionFactory.instance) {
31
+ QuestionFactory.instance = new QuestionFactory(locale);
32
+ }
33
+ return QuestionFactory.instance;
34
+ }
35
+ static createDefault(locale) {
36
+ return new ChoiceModel(locale);
37
+ }
38
+ static createSubQuestion(locale) {
39
+ return new SubQuestionModel(locale);
40
+ }
41
+ static createEvaluationItem(locale) {
42
+ return new StarEvaluationItemModel(locale);
43
+ }
44
+ static createSelectionQuestionChoices(locale) {
45
+ return _.range(4).map(() => this.createDefault(locale));
46
+ }
47
+ static createMatrixQuestionChoices(locale) {
48
+ return _.range(5).map(() => this.createDefault(locale));
49
+ }
50
+ static createEvaluationItems(locale) {
51
+ return _.range(5).map(() => this.createEvaluationItem(locale));
52
+ }
53
+ registerQuestion(questionType, questionCreator) {
54
+ this.creatorHash[questionType] = questionCreator;
55
+ }
56
+ createQuestion(questionType) {
57
+ let creator = this.creatorHash[questionType];
58
+ return creator(this.locale);
59
+ }
60
+ }
61
+
62
+ const defaultText = function getText(locale) {
63
+ return _.set({}, locale, "");
64
+ };
65
+ class ChoiceModel {
66
+ constructor(locale) {
67
+ this.id = ChoiceModel.createChoiceId();
68
+ this.text = defaultText(locale);
69
+ this.options = {
70
+ score: null,
71
+ star: false,
72
+ starCount: null,
73
+ };
74
+ }
75
+ static createChoiceId() {
76
+ return `Choice-${_.now()}-${_.random(0, 9999999)}`;
77
+ }
78
+ }
79
+ class EvaluationItemModel {
80
+ constructor(locale) {
81
+ this.id = EvaluationItemModel.createChoiceId();
82
+ this.text = defaultText(locale);
83
+ }
84
+ static createChoiceId() {
85
+ return `Evaluation-Item-${_.now()}-${_.random(0, 9999999)}`;
86
+ }
87
+ }
88
+ class StarEvaluationItemModel extends EvaluationItemModel {
89
+ constructor(locale) {
90
+ super(locale);
91
+ }
92
+ }
93
+ class ExprEvaluationItemModel extends EvaluationItemModel {
94
+ constructor(locale, type) {
95
+ super(locale);
96
+ this.type = type;
97
+ }
98
+ }
99
+ class ExprConditionModel {
100
+ constructor(type) {
101
+ this.type = type;
102
+ }
103
+ }
104
+ class QuestionOptionsModel {
105
+ constructor(required) {
106
+ this.required = required;
107
+ this.visible = true;
108
+ }
109
+ }
110
+ class QuestionHeaderModel {
111
+ constructor(locale) {
112
+ this.text = defaultText(locale);
113
+ this.number = null;
114
+ }
115
+ }
116
+ class SubQuestionModel {
117
+ constructor(locale) {
118
+ this.id = `SubQ-${_.now()}-${_.random(0, 9999999)}`;
119
+ this.text = defaultText(locale);
120
+ this.number = null;
121
+ }
122
+ }
123
+ class BaseQuestionModel {
124
+ constructor(type, locale) {
125
+ this.id = BaseQuestionModel.createQuestionId();
126
+ this.type = type;
127
+ this.header = new QuestionHeaderModel(locale);
128
+ this.options = new QuestionOptionsModel(false);
129
+ }
130
+ static getMaxScore(question) {
131
+ if (question.type == "SINGLE_SELECTION") {
132
+ return _.max(_.map(question.choices, (choice) => parseFloat(_.get(choice, "options.score", 0) || 0)));
133
+ }
134
+ else if (question.type == "MULTI_SELECTION") {
135
+ return _.sumBy(question.choices, (item) => parseFloat(_.get(item, "options.score") || 0));
136
+ }
137
+ else if (question.type == "MATRIX") {
138
+ let score = _.max(_.map(question.choices, (choice) => parseFloat(_.get(choice, "options.score", 0) || 0)));
139
+ return score * question.subQuestions.length;
140
+ }
141
+ return 0;
142
+ }
143
+ static createQuestionId() {
144
+ return `Q-${_.now()}-${_.random(0, 9999999)}`;
145
+ }
146
+ static getNumber(preNumber, question) {
147
+ return preNumber + 1;
148
+ }
149
+ static refreshSurvey(survey) {
150
+ this.rebuildQuestionNumber(survey.questions);
151
+ survey.statistics.maxScore = this.calculationAllQuestionMaxScore(survey.questions);
152
+ survey.statistics.questionCount = this.calculationAllQuestionCount(survey.questions);
153
+ }
154
+ static calculationAllQuestionCount(questions) {
155
+ let count = 0;
156
+ let exclude = ["TEXT_TITLE"];
157
+ _.forEach(questions, (question) => {
158
+ if (!_.includes(exclude, question.type)) {
159
+ count++;
160
+ }
161
+ });
162
+ return count;
163
+ }
164
+ static calculationAllQuestionMaxScore(questions) {
165
+ let maxScore = 0;
166
+ _.forEach(questions, (question) => {
167
+ maxScore += this.getMaxScore(question);
168
+ });
169
+ return maxScore;
170
+ }
171
+ static setActiveQuestion(currentQuestion, questions) {
172
+ _.forEach(questions, (question) => {
173
+ if (question.id == currentQuestion.id) {
174
+ question.active = true;
175
+ }
176
+ else {
177
+ question.active = false;
178
+ }
179
+ });
180
+ }
181
+ static rebuildQuestionNumber(questions) {
182
+ let preNumber = 0;
183
+ _.forEach(questions, function (question) {
184
+ let number;
185
+ if (question.type === "TEXT_TITLE") {
186
+ number = QuestionTextTitleModel.getNumber(preNumber, question);
187
+ }
188
+ else if (question.type === "MATRIX") {
189
+ number = QuestionMatrixModel.getNumber(preNumber, question);
190
+ }
191
+ else {
192
+ number = BaseQuestionModel.getNumber(preNumber, question);
193
+ }
194
+ question.header.number = number;
195
+ if (number) {
196
+ preNumber = number;
197
+ }
198
+ });
199
+ }
200
+ }
201
+ class QuestionCheckBoxModel extends BaseQuestionModel {
202
+ constructor(type, locale) {
203
+ super(type, locale);
204
+ this.choices = QuestionFactory.createSelectionQuestionChoices(locale);
205
+ }
206
+ }
207
+ class QuestionEvaluationModel extends BaseQuestionModel {
208
+ constructor(type, locale) {
209
+ super(type, locale);
210
+ this.evaluationItems = QuestionFactory.createEvaluationItems(locale);
211
+ }
212
+ }
213
+ class QuestionTextTitleModel extends BaseQuestionModel {
214
+ constructor(type, locale) {
215
+ super(type, locale);
216
+ }
217
+ static getNumber(preNumber, question) {
218
+ return null;
219
+ }
220
+ }
221
+ class QuestionFillBlankModel extends BaseQuestionModel {
222
+ constructor(type, locale) {
223
+ super(type, locale);
224
+ }
225
+ static getNumber(preNumber, question) {
226
+ return null;
227
+ }
228
+ }
229
+ class QuestionShortAnswerModel extends BaseQuestionModel {
230
+ constructor(type, locale) {
231
+ super(type, locale);
232
+ }
233
+ getNumber(preNumber) {
234
+ return null;
235
+ }
236
+ }
237
+ class QuestionSingleSelectionModel extends QuestionCheckBoxModel {
238
+ constructor(type, locale) {
239
+ super(type, locale);
240
+ }
241
+ }
242
+ class QuestionMulitSelectionModel extends QuestionCheckBoxModel {
243
+ constructor(type, locale) {
244
+ super(type, locale);
245
+ }
246
+ }
247
+ class QuestionMatrixModel extends BaseQuestionModel {
248
+ constructor(type, locale) {
249
+ super(type, locale);
250
+ this.choices = QuestionFactory.createMatrixQuestionChoices(locale);
251
+ this.subQuestions = [QuestionFactory.createSubQuestion(locale)];
252
+ }
253
+ static getNumber(preNumber, question) {
254
+ let number = preNumber + 1;
255
+ _.forEach(question.subQuestions, (sq, index) => {
256
+ sq.number = index + 1;
257
+ });
258
+ return number;
259
+ }
260
+ }
261
+ class ResponseModel {
262
+ }
263
+ class PlanModel {
264
+ }
265
+ class PlanStatisticsModel {
266
+ }
267
+ class ResponseStatisticsModel {
268
+ }
269
+
270
+ const ZH_CN = _.camelCase("zh-CN");
271
+ const EN_US = _.camelCase("en-US");
272
+ const ZH_TW = _.camelCase("zh-TW");
273
+ function getValue(obj, locale) {
274
+ let value = _.get(obj, _.camelCase(locale), '');
275
+ if (!_.isEmpty(value)) {
276
+ return value;
277
+ }
278
+ return _.get(obj, locale, '');
279
+ }
280
+ function translate(obj, locale, prettyMath = false) {
281
+ let value = getValue(obj, locale);
282
+ if (!_.isEmpty(value) || !prettyMath) {
283
+ return value;
284
+ }
285
+ return obj[ZH_CN] || obj["zh-CN"] || obj[EN_US] || obj["en-US"]
286
+ || obj[ZH_TW] || obj["zh-TW"];
287
+ }
288
+
289
+ function move(array, fromIndex, toIndex) {
290
+ let moveValue = array[fromIndex];
291
+ array[fromIndex] = array[toIndex];
292
+ array[toIndex] = moveValue;
293
+ }
294
+
295
+ export { BaseQuestionModel, ChoiceModel, EvaluationItemModel, ExprConditionModel, ExprEvaluationItemModel, PlanModel, PlanStatisticsModel, QuestionCheckBoxModel, QuestionEvaluationModel, QuestionFactory, QuestionFillBlankModel, QuestionHeaderModel, QuestionMatrixModel, QuestionMulitSelectionModel, QuestionOptionsModel, QuestionShortAnswerModel, QuestionSingleSelectionModel, QuestionTextTitleModel, ResponseModel, ResponseStatisticsModel, StarEvaluationItemModel, SubQuestionModel, move, translate };
package/package.json CHANGED
@@ -1,38 +1,57 @@
1
1
  {
2
2
  "name": "@wg-npm/survey-core",
3
- "version": "0.1.272",
3
+ "version": "0.2.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "scripts": {
7
7
  "dts": "rollup -c rollup.dts.js --environment INCLUDE_DEPS,BUILD:production",
8
- "build": "rollup -c --environment INCLUDE_DEPS,BUILD:production"
8
+ "build": "rollup -c --environment INCLUDE_DEPS,BUILD:production",
9
+ "watch": "rollup -c --watch.include \"src/**\" --environment INCLUDE_DEPS,BUILD:production",
10
+ "lint": "eslint \"**/*.ts\" \"**/*.vue\" --no-error-on-unmatched-pattern",
11
+ "lint-fix": "eslint \"**/*.ts\" \"**/*.vue\" --fix --no-error-on-unmatched-pattern"
12
+ },
13
+ "peerDependencies": {
14
+ "lodash": "^4.17.15"
9
15
  },
10
16
  "devDependencies": {
17
+ "@rollup/plugin-buble": "^0.21.3",
18
+ "@rollup/plugin-commonjs": "^13.0.0",
19
+ "@rollup/plugin-node-resolve": "^8.1.0",
20
+ "@rollup/plugin-replace": "^2.3.3",
21
+ "@typescript-eslint/eslint-plugin": "^3.6.0",
22
+ "@typescript-eslint/parser": "^3.6.0",
23
+ "@vue/eslint-config-prettier": "^6.0.0",
24
+ "@vue/eslint-config-typescript": "^5.0.2",
25
+ "acorn": "^7.3.1",
26
+ "eslint": "^7.4.0",
27
+ "eslint-plugin-prettier": "^3.1.4",
28
+ "eslint-plugin-vue": "^6.2.2",
11
29
  "lodash": "^4.17.15",
12
- "rollup": "^1.19.4",
13
- "rollup-plugin-buble": "^0.19.8",
14
- "rollup-plugin-commonjs": "^10.0.2",
15
- "rollup-plugin-dts": "^1.1.6",
16
- "rollup-plugin-node-resolve": "^5.2.0",
17
- "rollup-plugin-replace": "^2.2.0",
18
- "rollup-plugin-terser": "^5.1.1",
19
- "rollup-plugin-typescript": "^1.0.1",
20
- "tslib": "^1.10.0",
21
- "typescript": "^3.5.3"
30
+ "prettier": "^2.0.5",
31
+ "rollup": "^2.20.0",
32
+ "rollup-plugin-dts": "^1.4.7",
33
+ "rollup-plugin-terser": "^6.1.0",
34
+ "rollup-plugin-typescript2": "^0.27.1",
35
+ "tslib": "^2.0.0",
36
+ "typescript": "^3.9.6"
22
37
  },
23
- "main": "dist/survey-core.common.js",
24
- "module": "dist/survey-core.esm.js",
25
- "unpkg": "dist/survey-core.js",
26
- "jsdelivr": "dist/survey-core.js",
38
+ "main": "dist/survey-core.esm.js",
27
39
  "sideEffects": false,
28
- "typings": "types/index.d.ts",
40
+ "typings": "src/index.ts",
29
41
  "files": [
30
42
  "src",
31
- "types",
32
43
  "dist"
33
44
  ],
34
45
  "publishConfig": {
35
46
  "access": "public"
36
47
  },
37
- "gitHead": "c61e91cd95628e67ba9f8813b7bf0761f506e29c"
48
+ "gitHead": "577c7fabd6df149e573991c6dddbe7ac1fd7eedd",
49
+ "rollup": {
50
+ "external": [
51
+ "lodash"
52
+ ],
53
+ "output": {
54
+ "name": "SurveyCore"
55
+ }
56
+ }
38
57
  }
@@ -0,0 +1,5 @@
1
+ export function move(array: Array<any>, fromIndex: number, toIndex: number): void {
2
+ let moveValue: any = array[fromIndex];
3
+ array[fromIndex] = array[toIndex];
4
+ array[toIndex] = moveValue;
5
+ }
@@ -0,0 +1,110 @@
1
+ import _ from "lodash";
2
+
3
+ export class ExprEvaluationQuestion {
4
+ questions;
5
+ scope;
6
+ questionMap;
7
+
8
+ constructor(questions, scope) {
9
+ this.questions = questions;
10
+ this.scope = _.sortBy(scope);
11
+
12
+ this.questionMap = this.buildQuestionMap();
13
+ }
14
+
15
+ calculateNumbers() {
16
+ const checkedQuestions = this.checkedQuestion();
17
+ const checkedNumberElements = new Array();
18
+ this.recurs(checkedQuestions, checkedNumberElements);
19
+
20
+ return checkedNumberElements;
21
+ }
22
+
23
+ buildQuestionMap() {
24
+ const questionMap = {};
25
+ _.forEach(this.questions, (question) => {
26
+ questionMap[question.id] = question;
27
+ if (question.type == "MATRIX") {
28
+ _.forEach(_.get(question, "subQuestions", []), (subQuestion) => {
29
+ questionMap[subQuestion.id] = subQuestion;
30
+ });
31
+ }
32
+ });
33
+ return questionMap;
34
+ }
35
+
36
+ checkedQuestion() {
37
+ const questions = new Array();
38
+ _.forEach(this.questions, (question) => {
39
+ if (_.get(question, "type") == "MATRIX") {
40
+ const markedQuestions = new Array();
41
+ _.forEach(_.get(question, "subQuestions", []), (subQuestion) => {
42
+ if (_.includes(this.scope, subQuestion.id)) {
43
+ const newSubQuestion = _.cloneDeep(subQuestion);
44
+ _.set(newSubQuestion, "type", "MATRIX");
45
+ _.set(newSubQuestion, "parentId", _.get(question, "id"));
46
+ markedQuestions.push(newSubQuestion);
47
+ }
48
+ });
49
+ if (!_.isEmpty(markedQuestions)) {
50
+ questions.push(markedQuestions);
51
+ }
52
+ } else if (_.includes(this.scope, question.id)) {
53
+ questions.push(question);
54
+ }
55
+ });
56
+ return questions;
57
+ }
58
+
59
+ recurs(elements, numbers) {
60
+ for (let i = 0; i < elements.length; i++) {
61
+ const element = elements[i];
62
+ if (_.isArray(element)) {
63
+ numbers.push(new Array());
64
+ this.recurs(element, numbers[numbers.length - 1]);
65
+ } else {
66
+ const temp = new Array();
67
+ temp.push(this.getFullNumber(element));
68
+ if (i == elements.length - 1) {
69
+ numbers.push(temp);
70
+ continue;
71
+ }
72
+ for (let j = i + 1; ; j++) {
73
+ if (
74
+ j == elements.length ||
75
+ !this.isContinuous(elements[j - 1], elements[j])
76
+ ) {
77
+ numbers.push(temp);
78
+ i = j - 1;
79
+ break;
80
+ }
81
+ if (_.size(temp) > 1) {
82
+ temp.pop();
83
+ }
84
+ temp.push(this.getFullNumber(elements[j]));
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ isContinuous(front, hind) {
91
+ return (
92
+ !_.isArray(hind) && this.getNumber(hind) - this.getNumber(front) == 1
93
+ );
94
+ }
95
+
96
+ getFullNumber(question) {
97
+ if (question.type == "MATRIX") {
98
+ return (
99
+ this.questionMap[question.parentId].header.number +
100
+ "." +
101
+ this.getNumber(question)
102
+ );
103
+ }
104
+ return this.getNumber(question).toString();
105
+ }
106
+
107
+ getNumber(question) {
108
+ return question.type == "MATRIX" ? question.number : question.header.number;
109
+ }
110
+ }
package/src/index.ts CHANGED
@@ -1 +1,35 @@
1
- export * from './models'
1
+ export {
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
+ } from "./models";
31
+ export {
32
+ QuestionFactory
33
+ } from "./quetion-factory"
34
+ export { translate } from "./locale-utils";
35
+ export { move } from "./array-utils";
@@ -0,0 +1,23 @@
1
+ import _ from 'lodash';
2
+ import { SurveyLocales } from './models';
3
+
4
+ const ZH_CN: string = _.camelCase(SurveyLocales.ZH_CN);
5
+ const EN_US: string = _.camelCase(SurveyLocales.EN_US);
6
+ const ZH_TW: string = _.camelCase(SurveyLocales.ZH_TW);
7
+
8
+ function getValue(obj: any, locale: string) {
9
+ let value: any = _.get(obj, _.camelCase(locale), '');
10
+ if (!_.isEmpty(value)) {
11
+ return value;
12
+ }
13
+ return _.get(obj, locale, '');
14
+ }
15
+
16
+ export function translate(obj: any, locale: string, prettyMath: boolean = false): any {
17
+ let value: any = getValue(obj, locale);
18
+ if (!_.isEmpty(value) || !prettyMath) {
19
+ return value;
20
+ }
21
+ return obj[ZH_CN] || obj[SurveyLocales.ZH_CN] || obj[EN_US] || obj[SurveyLocales.EN_US]
22
+ || obj[ZH_TW] || obj[SurveyLocales.ZH_TW];
23
+ }
package/src/models.ts CHANGED
@@ -1,19 +1,388 @@
1
- export class TemplateModel {
2
- id?: string;
1
+ import _ from "lodash";
2
+ import { QuestionFactory } from "./quetion-factory";
3
+
4
+ const defaultText = function getText(locale: string): object {
5
+ return _.set({}, locale, "");
6
+ };
7
+
8
+ export const enum SurveyLocales {
9
+ ZH_CN = "zh-CN",
10
+ ZH_TW = "zh-TW",
11
+ EN_US = "en-US",
3
12
  }
4
- export class SurveyModel {
5
- id?: string
6
13
 
14
+ export const enum SurveyLayout {
15
+ HORIZONTAL = "HORIZONTAL",
16
+ VERTICAL = "VERTICAL",
7
17
  }
8
18
 
9
- export class ResponseModel {
10
- id?: string
19
+ export const enum QuestionType {
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
+ }
28
+
29
+ export const enum EvaluationType {
30
+ STAR = "STAR",
31
+ EXPR = "EXPR",
32
+ }
33
+
34
+ export const enum ExprConditionType {
35
+ ASSIGN = "ASSIGN",
36
+ AUTO = "AUTO",
37
+ SCORE = "SCORE",
38
+ }
39
+
40
+ export const enum ExprEvaluationItemType {
41
+ IF = "IF",
42
+ ELSE = "ELSE",
43
+ }
44
+
45
+ export class ChoiceModel {
46
+ id: string;
47
+ options?: Object;
48
+ text: object;
49
+
50
+ constructor(locale: string) {
51
+ this.id = ChoiceModel.createChoiceId();
52
+ this.text = defaultText(locale);
53
+ this.options = {
54
+ score: null,
55
+ star: false,
56
+ starCount: null,
57
+ };
58
+ }
59
+
60
+ static createChoiceId(): string {
61
+ return `Choice-${_.now()}-${_.random(0, 9999999)}`;
62
+ }
63
+ }
64
+
65
+ export class LevelRange {
66
+ min?: Number;
67
+ max?: Number;
68
+ }
69
+
70
+ export class EvaluationItemModel {
71
+ id: string;
72
+ options?: Object;
73
+ text: object;
74
+
75
+ constructor(locale: string) {
76
+ this.id = EvaluationItemModel.createChoiceId();
77
+ this.text = defaultText(locale);
78
+ }
79
+
80
+ static createChoiceId(): string {
81
+ return `Evaluation-Item-${_.now()}-${_.random(0, 9999999)}`;
82
+ }
83
+ }
84
+
85
+ export class StarEvaluationItemModel extends EvaluationItemModel {
86
+ level?: Number;
87
+ range?: LevelRange;
88
+
89
+ constructor(locale: string) {
90
+ super(locale);
91
+ }
92
+ }
93
+
94
+ export class ExprEvaluationItemModel extends EvaluationItemModel {
95
+ type: ExprEvaluationItemType;
96
+ conditions?: Array<ExprConditionModel>;
97
+
98
+ constructor(locale: string, type: ExprEvaluationItemType) {
99
+ super(locale);
100
+ this.type = type;
101
+ }
102
+ }
103
+
104
+ export class ExprConditionModel {
105
+ type: ExprConditionType;
106
+ expr?: string;
107
+ desc?: string;
108
+ payload?: any;
109
+
110
+ constructor(type: ExprConditionType) {
111
+ this.type = type;
112
+ }
113
+ }
114
+
115
+ export class QuestionOptionsModel {
116
+ required: Boolean;
117
+ visible: Boolean;
118
+ layout?: SurveyLayout;
119
+ wordLimit?: Number;
120
+ scoringEnabled?: Boolean;
121
+ starEnabled?: Boolean;
122
+ starMinCount?: Number;
123
+
124
+ constructor(required: Boolean) {
125
+ this.required = required;
126
+ this.visible = true;
127
+ }
128
+ }
129
+
130
+ export class QuestionHeaderModel {
131
+ number?: Number | null;
132
+ text: Object;
133
+
134
+ constructor(locale: string) {
135
+ this.text = defaultText(locale);
136
+ this.number = null;
137
+ }
138
+ }
139
+
140
+ export class SubQuestionModel {
141
+ id: string;
142
+ number?: Number | null;
143
+ text?: Object;
144
+
145
+ constructor(locale: string) {
146
+ this.id = `SubQ-${_.now()}-${_.random(0, 9999999)}`;
147
+ this.text = defaultText(locale);
148
+ this.number = null;
149
+ }
150
+ }
151
+
152
+ export class QuestionExprModel {
153
+ id: string;
154
+ answer: any;
155
+
156
+ constructor(id: string, answer: any) {
157
+ this.id = id;
158
+ this.answer = answer;
159
+ }
160
+ }
161
+
162
+ export class BaseQuestionModel {
163
+ id: string;
164
+ type: string;
165
+ options: QuestionOptionsModel;
166
+ header: QuestionHeaderModel;
167
+
168
+ constructor(type: string, locale: string) {
169
+ this.id = BaseQuestionModel.createQuestionId();
170
+ this.type = type;
171
+ this.header = new QuestionHeaderModel(locale);
172
+ this.options = new QuestionOptionsModel(false);
173
+ }
174
+
175
+ static getMaxScore(question): number {
176
+ if (question.type == QuestionType.SINGLE_SELECTION) {
177
+ return _.max(
178
+ _.map(question.choices, (choice) =>
179
+ parseFloat(_.get(choice, "options.score", 0) || 0)
180
+ )
181
+ );
182
+ } else if (question.type == QuestionType.MULTI_SELECTION) {
183
+ return _.sumBy(question.choices, (item) =>
184
+ parseFloat(_.get(item, "options.score") || 0)
185
+ );
186
+ } else if (question.type == QuestionType.MATRIX) {
187
+ let score = _.max(
188
+ _.map(question.choices, (choice) =>
189
+ parseFloat(_.get(choice, "options.score", 0) || 0)
190
+ )
191
+ );
192
+ return score * question.subQuestions.length;
193
+ }
194
+ return 0;
195
+ }
196
+
197
+ static createQuestionId(): string {
198
+ return `Q-${_.now()}-${_.random(0, 9999999)}`;
199
+ }
200
+
201
+ static getNumber(
202
+ preNumber: number,
203
+ question: BaseQuestionModel
204
+ ): null | number {
205
+ return preNumber + 1;
206
+ }
207
+
208
+ static refreshSurvey(survey): void {
209
+ this.rebuildQuestionNumber(survey.questions);
210
+ survey.statistics.maxScore = this.calculationAllQuestionMaxScore(
211
+ survey.questions
212
+ );
213
+ survey.statistics.questionCount = this.calculationAllQuestionCount(
214
+ survey.questions
215
+ );
216
+ }
217
+
218
+ static calculationAllQuestionCount(questions): number {
219
+ let count = 0;
220
+ let exclude = [QuestionType.TEXT_TITLE];
221
+ _.forEach(questions, (question) => {
222
+ if (!_.includes(exclude, question.type)) {
223
+ count++;
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
+ }
267
+ }
268
+
269
+ export class QuestionCheckBoxModel extends BaseQuestionModel {
270
+ choices: Array<any>;
271
+
272
+ constructor(type: QuestionType, locale: string) {
273
+ super(type, locale);
274
+ this.choices = QuestionFactory.createSelectionQuestionChoices(locale);
275
+ }
276
+ }
277
+
278
+ export class QuestionEvaluationModel extends BaseQuestionModel {
279
+ evaluationItems: Array<EvaluationItemModel>;
280
+
281
+ constructor(type: QuestionType, locale: string) {
282
+ super(type, locale);
283
+ this.evaluationItems = QuestionFactory.createEvaluationItems(locale);
284
+ }
285
+ }
286
+
287
+ export class QuestionTextTitleModel extends BaseQuestionModel {
288
+ constructor(type: QuestionType, locale: string) {
289
+ super(type, locale);
290
+ }
291
+
292
+ static getNumber(
293
+ preNumber: number,
294
+ question: BaseQuestionModel
295
+ ): null | number {
296
+ return null;
297
+ }
298
+ }
299
+
300
+ export class QuestionFillBlankModel extends BaseQuestionModel {
301
+ constructor(type: QuestionType, locale: string) {
302
+ super(type, locale);
303
+ }
304
+
305
+ static getNumber(
306
+ preNumber: number,
307
+ question: BaseQuestionModel
308
+ ): null | number {
309
+ return null;
310
+ }
11
311
  }
12
312
 
13
- export class QuestionModel {
14
- id?: string
313
+ export class QuestionShortAnswerModel extends BaseQuestionModel {
314
+ constructor(type: QuestionType, locale: string) {
315
+ super(type, locale);
316
+ }
317
+
318
+ getNumber(preNumber: number): null | number {
319
+ return null;
320
+ }
321
+ }
322
+
323
+ export class QuestionSingleSelectionModel extends QuestionCheckBoxModel {
324
+ constructor(type: QuestionType, locale: string) {
325
+ super(type, locale);
326
+ }
327
+ }
328
+
329
+ export class QuestionMulitSelectionModel extends QuestionCheckBoxModel {
330
+ constructor(type: QuestionType, locale: string) {
331
+ super(type, locale);
332
+ }
333
+ }
334
+
335
+ export class QuestionMatrixModel extends BaseQuestionModel {
336
+ choices: Array<any>;
337
+ subQuestions: Array<SubQuestionModel>;
338
+
339
+ constructor(type: QuestionType, locale: string) {
340
+ super(type, locale);
341
+ this.choices = QuestionFactory.createMatrixQuestionChoices(locale);
342
+ this.subQuestions = [QuestionFactory.createSubQuestion(locale)];
343
+ }
344
+
345
+ static getNumber(
346
+ preNumber: number,
347
+ question: QuestionMatrixModel
348
+ ): null | number {
349
+ let number = preNumber + 1;
350
+ _.forEach(question.subQuestions, (sq, index) => {
351
+ sq.number = index + 1;
352
+ });
353
+ return number;
354
+ }
355
+ }
356
+
357
+ export interface SurveyOptionsModel {
358
+ primaryLanguage: SurveyLocales;
359
+ languages: SurveyLocales[];
360
+ layout: SurveyLayout;
361
+ }
362
+
363
+ export interface SurveyStatisticsModel {
364
+ maxScore: Number;
365
+ questionCount: Number;
366
+ }
367
+
368
+ export interface SurveyModel {
369
+ id: string;
370
+ name: any;
371
+ options: SurveyOptionsModel;
372
+ statistics: SurveyStatisticsModel;
373
+ questions: BaseQuestionModel[];
374
+ }
375
+
376
+ export class ResponseModel {
377
+ id?: string;
15
378
  }
16
379
 
17
380
  export class PlanModel {
18
- id?: string
19
- }
381
+ id?: string;
382
+ }
383
+
384
+ //todo remove
385
+ export class PlanStatisticsModel {}
386
+
387
+ //todo remove
388
+ export class ResponseStatisticsModel {}
@@ -0,0 +1,90 @@
1
+ import {
2
+ BaseQuestionModel,
3
+ ChoiceModel,
4
+ QuestionType,
5
+ QuestionMatrixModel,
6
+ QuestionTextTitleModel,
7
+ QuestionCheckBoxModel,
8
+ SubQuestionModel,
9
+ QuestionEvaluationModel,
10
+ StarEvaluationItemModel
11
+ } from "./models";
12
+ import _ from "lodash";
13
+
14
+ interface HashTable<T> {
15
+ [key: string]: T;
16
+ }
17
+
18
+ export class QuestionFactory {
19
+ private creatorHash: HashTable<(locale: string) => BaseQuestionModel> = {};
20
+ private static instance: QuestionFactory;
21
+ private locale: string;
22
+
23
+ public static getInstance(locale: string): QuestionFactory {
24
+ if (!QuestionFactory.instance) {
25
+ QuestionFactory.instance = new QuestionFactory(locale);
26
+ }
27
+ return QuestionFactory.instance;
28
+ }
29
+
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
+
55
+ public static createDefault(locale: string): ChoiceModel {
56
+ return new ChoiceModel(locale);
57
+ }
58
+
59
+ public static createSubQuestion(locale: string): SubQuestionModel {
60
+ return new SubQuestionModel(locale);
61
+ }
62
+
63
+ public static createEvaluationItem(locale: string): ChoiceModel {
64
+ return new StarEvaluationItemModel(locale);
65
+ }
66
+
67
+ public static createSelectionQuestionChoices(locale: string) {
68
+ return _.range(4).map(() => this.createDefault(locale));
69
+ }
70
+
71
+ public static createMatrixQuestionChoices(locale: string) {
72
+ return _.range(5).map(() => this.createDefault(locale));
73
+ }
74
+
75
+ public static createEvaluationItems(locale: string) {
76
+ return _.range(5).map(() => this.createEvaluationItem(locale));
77
+ }
78
+
79
+ public registerQuestion(
80
+ questionType: string,
81
+ questionCreator: (locale: string) => BaseQuestionModel
82
+ ) {
83
+ this.creatorHash[questionType] = questionCreator;
84
+ }
85
+
86
+ public createQuestion(questionType: string): BaseQuestionModel {
87
+ let creator = this.creatorHash[questionType];
88
+ return creator(this.locale);
89
+ }
90
+ }
@@ -1,35 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var TemplateModel = /** @class */ (function () {
6
- function TemplateModel() {
7
- }
8
- return TemplateModel;
9
- }());
10
- var SurveyModel = /** @class */ (function () {
11
- function SurveyModel() {
12
- }
13
- return SurveyModel;
14
- }());
15
- var ResponseModel = /** @class */ (function () {
16
- function ResponseModel() {
17
- }
18
- return ResponseModel;
19
- }());
20
- var QuestionModel = /** @class */ (function () {
21
- function QuestionModel() {
22
- }
23
- return QuestionModel;
24
- }());
25
- var PlanModel = /** @class */ (function () {
26
- function PlanModel() {
27
- }
28
- return PlanModel;
29
- }());
30
-
31
- exports.PlanModel = PlanModel;
32
- exports.QuestionModel = QuestionModel;
33
- exports.ResponseModel = ResponseModel;
34
- exports.SurveyModel = SurveyModel;
35
- exports.TemplateModel = TemplateModel;
@@ -1,38 +0,0 @@
1
- var SurveyCore = (function (exports) {
2
- 'use strict';
3
-
4
- var TemplateModel = /** @class */ (function () {
5
- function TemplateModel() {
6
- }
7
- return TemplateModel;
8
- }());
9
- var SurveyModel = /** @class */ (function () {
10
- function SurveyModel() {
11
- }
12
- return SurveyModel;
13
- }());
14
- var ResponseModel = /** @class */ (function () {
15
- function ResponseModel() {
16
- }
17
- return ResponseModel;
18
- }());
19
- var QuestionModel = /** @class */ (function () {
20
- function QuestionModel() {
21
- }
22
- return QuestionModel;
23
- }());
24
- var PlanModel = /** @class */ (function () {
25
- function PlanModel() {
26
- }
27
- return PlanModel;
28
- }());
29
-
30
- exports.PlanModel = PlanModel;
31
- exports.QuestionModel = QuestionModel;
32
- exports.ResponseModel = ResponseModel;
33
- exports.SurveyModel = SurveyModel;
34
- exports.TemplateModel = TemplateModel;
35
-
36
- return exports;
37
-
38
- }({}));
@@ -1 +0,0 @@
1
- var SurveyCore=function(n){"use strict";var e=function(){},o=function(){},t=function(){},u=function(){},i=function(){};return n.PlanModel=i,n.QuestionModel=u,n.ResponseModel=t,n.SurveyModel=o,n.TemplateModel=e,n}({});
@@ -1,41 +0,0 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
- (global = global || self, factory(global.SurveyCore = {}));
5
- }(this, (function (exports) { 'use strict';
6
-
7
- var TemplateModel = /** @class */ (function () {
8
- function TemplateModel() {
9
- }
10
- return TemplateModel;
11
- }());
12
- var SurveyModel = /** @class */ (function () {
13
- function SurveyModel() {
14
- }
15
- return SurveyModel;
16
- }());
17
- var ResponseModel = /** @class */ (function () {
18
- function ResponseModel() {
19
- }
20
- return ResponseModel;
21
- }());
22
- var QuestionModel = /** @class */ (function () {
23
- function QuestionModel() {
24
- }
25
- return QuestionModel;
26
- }());
27
- var PlanModel = /** @class */ (function () {
28
- function PlanModel() {
29
- }
30
- return PlanModel;
31
- }());
32
-
33
- exports.PlanModel = PlanModel;
34
- exports.QuestionModel = QuestionModel;
35
- exports.ResponseModel = ResponseModel;
36
- exports.SurveyModel = SurveyModel;
37
- exports.TemplateModel = TemplateModel;
38
-
39
- Object.defineProperty(exports, '__esModule', { value: true });
40
-
41
- })));
@@ -1 +0,0 @@
1
- !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports):"function"==typeof define&&define.amd?define(["exports"],o):o((e=e||self).SurveyCore={})}(this,(function(e){"use strict";var o=function(){},n=function(){},t=function(){},f=function(){},i=function(){};e.PlanModel=i,e.QuestionModel=f,e.ResponseModel=t,e.SurveyModel=n,e.TemplateModel=o,Object.defineProperty(e,"__esModule",{value:!0})}));
package/src/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from './models';
package/src/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA"}
package/types/index.d.ts DELETED
@@ -1,65 +0,0 @@
1
- declare class TemplateModel {
2
- id?: string;
3
- }
4
-
5
- declare class PlanModel {
6
- id?: string;
7
- }
8
-
9
- declare class SurveyModel {
10
- id?: string;
11
- }
12
-
13
- declare class ResponseModel {
14
- id?: string;
15
- }
16
-
17
- declare class QuestionModel {
18
- id?: string;
19
- }
20
-
21
- declare enum RespondStatusEnum {
22
- Saved = 'SAVED',
23
- Submitted = 'SUBMITTED',
24
- All = 'ALL'
25
- }
26
-
27
- declare enum MongodbComparisonOperatorsEnum {
28
- EQ = 'EQ', // =
29
- GT = 'GT', // >
30
- GTE = 'GTE', // >=
31
- IN = 'IN',
32
- LT = 'LT', // <
33
- LTE = 'LTE', // <=
34
- NE = 'NE', // !=
35
- NIN = 'NIN', // not in
36
- }
37
-
38
- declare class OptionsFiltersModel {
39
- operator: MongodbComparisonOperatorsEnum;
40
- column: string;
41
- value: any;
42
- }
43
-
44
- declare class StatisticsModel {
45
- respondentOptionsFilters?: Array<OptionsFiltersModel>;
46
- targetOptionsFilters?: Array<OptionsFiltersModel>;
47
- }
48
-
49
- declare class PlanStatisticsModel extends StatisticsModel {
50
- }
51
-
52
- declare class ResponseStatisticsModel extends StatisticsModel {
53
- targetId?: string;
54
- status?: RespondStatusEnum;
55
- }
56
-
57
- export {
58
- QuestionModel,
59
- ResponseModel,
60
- SurveyModel,
61
- TemplateModel,
62
- PlanModel,
63
- PlanStatisticsModel,
64
- ResponseStatisticsModel
65
- };