@wg-npm/survey-response 0.3.13 → 0.3.377-8.develop
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-response.esm.js +118 -54
- package/package.json +5 -5
- package/src/components/question/type/evaluation.vue +48 -16
- package/src/components/question/type/matrix.vue +48 -20
- package/src/components/question/type/multi-selection.vue +84 -62
- package/src/components/question/type/single-selection.vue +113 -92
- package/src/components/survey-response.vue +172 -139
- package/src/ellipsis-tooltip.ts +160 -0
- package/src/mixins/option-layout-mixin.ts +22 -15
|
@@ -1,17 +1,42 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<div
|
|
4
|
-
|
|
3
|
+
<div
|
|
4
|
+
v-for="(subQuestion, subIndex) in question.subQuestions"
|
|
5
|
+
:key="subIndex"
|
|
6
|
+
class="sub-question"
|
|
7
|
+
>
|
|
8
|
+
<span class="number">
|
|
9
|
+
{{ question.header.number }}-{{ subQuestion.number }}.</span
|
|
10
|
+
>
|
|
5
11
|
<span class="title"> {{ i18nText(subQuestion.text) }} </span>
|
|
6
12
|
<FormItem
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
:prop="`answers[${index}].answer[${subIndex}].answer`"
|
|
14
|
+
:rules="{
|
|
15
|
+
required: question.options.required,
|
|
16
|
+
message: t('survey_response.question.question_required')
|
|
17
|
+
}"
|
|
9
18
|
>
|
|
10
|
-
<RadioGroup
|
|
19
|
+
<RadioGroup
|
|
20
|
+
v-model="value.answer[subIndex].answer"
|
|
21
|
+
@on-change="selChange"
|
|
22
|
+
>
|
|
11
23
|
<Row type="flex" justify="start" :gutter="60">
|
|
12
|
-
<Col
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
<Col
|
|
25
|
+
:xs="24"
|
|
26
|
+
:sm="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
27
|
+
:xl="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
28
|
+
:md="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
29
|
+
:lg="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
30
|
+
v-for="choice in question.choices"
|
|
31
|
+
:key="choice.id"
|
|
32
|
+
:class="optionLayout"
|
|
33
|
+
>
|
|
34
|
+
<Radio
|
|
35
|
+
:label="choice.id"
|
|
36
|
+
:key="choice.id"
|
|
37
|
+
@click.native="toggleAnswer(choice.id, subIndex)"
|
|
38
|
+
:disabled="subQuestion.options.readonly"
|
|
39
|
+
>
|
|
15
40
|
<span>{{ i18nText(choice.text) }}</span>
|
|
16
41
|
</Radio>
|
|
17
42
|
</Col>
|
|
@@ -23,15 +48,16 @@
|
|
|
23
48
|
</template>
|
|
24
49
|
|
|
25
50
|
<script lang="ts">
|
|
26
|
-
import Vue from
|
|
27
|
-
import _ from
|
|
28
|
-
import OptionLayoutMixin from
|
|
29
|
-
import {FormItem, RadioGroup, Radio, Row, Col} from "view-design";
|
|
51
|
+
import Vue from "vue";
|
|
52
|
+
import _ from "lodash";
|
|
53
|
+
import OptionLayoutMixin from "../../../mixins/option-layout-mixin";
|
|
54
|
+
import { FormItem, RadioGroup, Radio, Row, Col } from "view-design";
|
|
30
55
|
|
|
31
56
|
export default Vue.extend({
|
|
32
|
-
name:
|
|
57
|
+
name: "matrix",
|
|
33
58
|
mixins: [OptionLayoutMixin],
|
|
34
|
-
inject: ["responseStatus"],
|
|
59
|
+
inject: ["responseStatus", "$rootComponent"],
|
|
60
|
+
|
|
35
61
|
components: {
|
|
36
62
|
FormItem,
|
|
37
63
|
RadioGroup,
|
|
@@ -51,7 +77,7 @@ export default Vue.extend({
|
|
|
51
77
|
}
|
|
52
78
|
},
|
|
53
79
|
data() {
|
|
54
|
-
return {value: this.answer};
|
|
80
|
+
return { value: this.answer };
|
|
55
81
|
},
|
|
56
82
|
created() {
|
|
57
83
|
let subAnswers = {};
|
|
@@ -60,17 +86,17 @@ export default Vue.extend({
|
|
|
60
86
|
_.set(subAnswers, data.questionId, data);
|
|
61
87
|
});
|
|
62
88
|
// @ts-ignore
|
|
63
|
-
_.set(this.value,
|
|
89
|
+
_.set(this.value, "answer", []);
|
|
64
90
|
// @ts-ignore
|
|
65
91
|
_.each(this.question.subQuestions, question => {
|
|
66
92
|
let _answer: any = _.get(subAnswers, question.id);
|
|
67
93
|
_answer = _answer
|
|
68
|
-
|
|
69
|
-
|
|
94
|
+
? _answer
|
|
95
|
+
: {
|
|
70
96
|
answer: null,
|
|
71
97
|
question_id: question.id,
|
|
72
98
|
score: 0,
|
|
73
|
-
question_type:
|
|
99
|
+
question_type: "SINGLE_SELECTION"
|
|
74
100
|
};
|
|
75
101
|
// @ts-ignore
|
|
76
102
|
this.value.answer.push(_answer);
|
|
@@ -96,7 +122,9 @@ export default Vue.extend({
|
|
|
96
122
|
toggleAnswer(subValue, subIndex) {
|
|
97
123
|
if (this.responseStatus == this.$consts.STATUS_DRAFT) {
|
|
98
124
|
let subAnswer = this.value.answer[subIndex].answer;
|
|
99
|
-
this.value.answer[subIndex].answer = _.isEmpty(subAnswer)
|
|
125
|
+
this.value.answer[subIndex].answer = _.isEmpty(subAnswer)
|
|
126
|
+
? subValue
|
|
127
|
+
: subAnswer;
|
|
100
128
|
}
|
|
101
129
|
}
|
|
102
130
|
}
|
|
@@ -1,67 +1,89 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
<FormItem
|
|
3
|
+
:prop="`answers[${index}].answer`"
|
|
4
|
+
:rules="{
|
|
5
|
+
required: question.options.required,
|
|
6
|
+
type: 'array',
|
|
7
|
+
min: 1,
|
|
8
|
+
message: t('survey_response.question.question_required')
|
|
9
|
+
}"
|
|
10
|
+
>
|
|
11
|
+
<CheckboxGroup v-model="value.answer" @on-change="selChange">
|
|
12
|
+
<Row type="flex" justify="start" :gutter="60">
|
|
13
|
+
<Col
|
|
14
|
+
:xs="24"
|
|
15
|
+
:sm="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
16
|
+
:xl="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
17
|
+
:md="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
18
|
+
:lg="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
19
|
+
v-for="choice in question.choices"
|
|
20
|
+
:key="choice.id"
|
|
21
|
+
:class="optionLayout"
|
|
22
|
+
>
|
|
23
|
+
<Checkbox
|
|
24
|
+
:label="choice.id"
|
|
25
|
+
:key="choice.id"
|
|
26
|
+
:disabled="question.options.readonly"
|
|
27
|
+
>
|
|
28
|
+
<span>{{ i18nText(choice.text) }}</span>
|
|
29
|
+
</Checkbox>
|
|
30
|
+
</Col>
|
|
31
|
+
</Row>
|
|
32
|
+
</CheckboxGroup>
|
|
33
|
+
</FormItem>
|
|
14
34
|
</template>
|
|
15
35
|
<script lang="ts">
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
36
|
+
import Vue from "vue";
|
|
37
|
+
import _ from "lodash";
|
|
38
|
+
import OptionLayoutMixin from "../../../mixins/option-layout-mixin";
|
|
39
|
+
import { FormItem, CheckboxGroup, Checkbox, Row, Col } from "view-design";
|
|
20
40
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
41
|
+
export default Vue.extend({
|
|
42
|
+
name: "multi-selection",
|
|
43
|
+
inject: ["$rootComponent"],
|
|
44
|
+
mixins: [OptionLayoutMixin],
|
|
45
|
+
components: {
|
|
46
|
+
FormItem,
|
|
47
|
+
CheckboxGroup,
|
|
48
|
+
Checkbox,
|
|
49
|
+
Row,
|
|
50
|
+
Col
|
|
51
|
+
},
|
|
52
|
+
props: {
|
|
53
|
+
question: {
|
|
54
|
+
type: Object,
|
|
55
|
+
required: true
|
|
56
|
+
},
|
|
57
|
+
index: Number,
|
|
58
|
+
answer: {
|
|
59
|
+
type: Object,
|
|
60
|
+
required: true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
data() {
|
|
64
|
+
return { value: this.answer };
|
|
65
|
+
},
|
|
66
|
+
methods: {
|
|
67
|
+
selChange(val) {
|
|
68
|
+
let score = 0;
|
|
69
|
+
let minStarCount = 0;
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
_.each(this.question.choices, choice => {
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
_.each(val, id => {
|
|
74
|
+
if (choice.id == id) {
|
|
75
|
+
score += parseInt(choice?.options?.score ?? 0);
|
|
76
|
+
minStarCount++;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
this.answer.score = score;
|
|
82
|
+
if (this.question.options.starEnabled) {
|
|
83
|
+
this.answer.star =
|
|
84
|
+
minStarCount >= this.question.options.starMinCount ? 1 : 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
67
89
|
</script>
|
|
@@ -1,99 +1,120 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
<FormItem
|
|
3
|
+
:prop="`answers[${index}].answer`"
|
|
4
|
+
:rules="{
|
|
5
|
+
required: question.options.required,
|
|
6
|
+
message: t('survey_response.question.question_required')
|
|
7
|
+
}"
|
|
8
|
+
>
|
|
9
|
+
<RadioGroup
|
|
10
|
+
v-model="value.answer"
|
|
11
|
+
@on-change="selChange"
|
|
12
|
+
class="question-choice"
|
|
13
|
+
>
|
|
14
|
+
<Row type="flex" justify="start" :gutter="60">
|
|
15
|
+
<Col
|
|
16
|
+
:xs="24"
|
|
17
|
+
:sm="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
18
|
+
:xl="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
19
|
+
:md="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
20
|
+
:lg="$rootComponent.layout === 'vertical' ? 24 : 6"
|
|
21
|
+
v-for="choice in question.choices"
|
|
22
|
+
:key="choice.id"
|
|
23
|
+
:class="optionLayout"
|
|
24
|
+
>
|
|
25
|
+
<Radio
|
|
26
|
+
:disabled="question.options.readonly"
|
|
27
|
+
:label="choice.id"
|
|
28
|
+
:key="choice.id"
|
|
29
|
+
@click.native="toggleAnswer(choice.id)"
|
|
30
|
+
>
|
|
31
|
+
<span v-if="haveStar(choice)">
|
|
32
|
+
<Icon type="md-star" color="orange" :size="16" />
|
|
33
|
+
</span>
|
|
34
|
+
<span>{{ i18nText(choice.text) }}</span>
|
|
35
|
+
</Radio>
|
|
36
|
+
</Col>
|
|
37
|
+
</Row>
|
|
38
|
+
</RadioGroup>
|
|
39
|
+
</FormItem>
|
|
19
40
|
</template>
|
|
20
41
|
|
|
21
42
|
<script lang="ts">
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
import Vue from "vue";
|
|
44
|
+
import OptionLayoutMixin from "../../../mixins/option-layout-mixin";
|
|
45
|
+
import { Col, FormItem, Icon, Radio, RadioGroup, Row } from "view-design";
|
|
46
|
+
import _ from "lodash";
|
|
47
|
+
import { SurveyLayout } from "@wg-npm/survey-core";
|
|
27
48
|
|
|
28
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
},
|
|
74
|
-
buildChoiceClasses() {
|
|
75
|
-
return [
|
|
76
|
-
`question-choice`,
|
|
77
|
-
`question-choice-${_.lowerCase(
|
|
78
|
-
this.question.options.layout || SurveyLayout.HORIZONTAL
|
|
79
|
-
)}`
|
|
80
|
-
];
|
|
81
|
-
},
|
|
82
|
-
haveStar(choice) {
|
|
83
|
-
return choice.options?.star ?? false;
|
|
84
|
-
},
|
|
85
|
-
toggleAnswer(value) {
|
|
86
|
-
if(this.question.options.readonly){
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
if (this.responseStatus == this.$consts.STATUS_DRAFT) {
|
|
90
|
-
if (this.value.answer) {
|
|
91
|
-
this.value.answer = null;
|
|
92
|
-
} else {
|
|
93
|
-
this.value.answer = value
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
49
|
+
export default Vue.extend({
|
|
50
|
+
name: "single-selection",
|
|
51
|
+
components: {
|
|
52
|
+
FormItem,
|
|
53
|
+
RadioGroup,
|
|
54
|
+
Radio,
|
|
55
|
+
Row,
|
|
56
|
+
Col,
|
|
57
|
+
Icon
|
|
58
|
+
},
|
|
59
|
+
mixins: [OptionLayoutMixin],
|
|
60
|
+
inject: ["responseStatus", "$rootComponent"],
|
|
61
|
+
props: {
|
|
62
|
+
question: {
|
|
63
|
+
type: Object,
|
|
64
|
+
required: true
|
|
65
|
+
},
|
|
66
|
+
index: Number,
|
|
67
|
+
answer: {
|
|
68
|
+
type: Object,
|
|
69
|
+
required: true
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
data() {
|
|
73
|
+
return {
|
|
74
|
+
value: this.answer,
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
choiceClasses: this.buildChoiceClasses()
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
watch: {
|
|
80
|
+
"question.options.layout"() {
|
|
81
|
+
this.choiceClasses = this.buildChoiceClasses();
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
methods: {
|
|
85
|
+
selChange(id) {
|
|
86
|
+
// @ts-ignore
|
|
87
|
+
_.each(this.question.choices, choice => {
|
|
88
|
+
if (choice.id == id) {
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
this.answer.score = parseInt(choice?.options?.score ?? 0);
|
|
91
|
+
this.answer.star = parseInt(choice?.options?.starCount ?? 0);
|
|
97
92
|
}
|
|
98
|
-
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
buildChoiceClasses() {
|
|
96
|
+
return [
|
|
97
|
+
`question-choice`,
|
|
98
|
+
`question-choice-${_.lowerCase(
|
|
99
|
+
this.question.options.layout || SurveyLayout.HORIZONTAL
|
|
100
|
+
)}`
|
|
101
|
+
];
|
|
102
|
+
},
|
|
103
|
+
haveStar(choice) {
|
|
104
|
+
return choice.options?.star ?? false;
|
|
105
|
+
},
|
|
106
|
+
toggleAnswer(value) {
|
|
107
|
+
if (this.question.options.readonly) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (this.responseStatus == this.$consts.STATUS_DRAFT) {
|
|
111
|
+
if (this.value.answer) {
|
|
112
|
+
this.value.answer = null;
|
|
113
|
+
} else {
|
|
114
|
+
this.value.answer = value;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
99
120
|
</script>
|