@wg-npm/survey-response 0.5.1 → 0.5.123

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": "@wg-npm/survey-response",
3
- "version": "0.5.1",
3
+ "version": "0.5.123",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -12,8 +12,8 @@
12
12
  "lint-fix": "eslint \"**/*.ts\" \"**/*.vue\" --fix --no-error-on-unmatched-pattern"
13
13
  },
14
14
  "peerDependencies": {
15
- "@wg-npm/survey-core": "0.5.1",
16
- "@wg-npm/survey-service-api": "0.5.1",
15
+ "@wg-npm/survey-core": "0.5.123",
16
+ "@wg-npm/survey-service-api": "0.5.123",
17
17
  "axios": "^0.19.2",
18
18
  "deepmerge": "^4.2.2",
19
19
  "lodash": "^4.17.15",
@@ -34,8 +34,8 @@
34
34
  "@typescript-eslint/parser": "^3.6.0",
35
35
  "@vue/eslint-config-prettier": "^6.0.0",
36
36
  "@vue/eslint-config-typescript": "^5.0.2",
37
- "@wg-npm/survey-core": "0.5.1",
38
- "@wg-npm/survey-service-api": "0.5.1",
37
+ "@wg-npm/survey-core": "0.5.123",
38
+ "@wg-npm/survey-service-api": "0.5.123",
39
39
  "acorn": "^7.3.1",
40
40
  "axios": "^0.19.2",
41
41
  "babelrc-rollup": "^3.0.0",
@@ -46,7 +46,7 @@
46
46
  "eslint-plugin-prettier": "^3.1.4",
47
47
  "eslint-plugin-vue": "^6.2.2",
48
48
  "lodash": "^4.17.15",
49
- "rollup": "^2.20.0",
49
+ "rollup": "2.20.0",
50
50
  "rollup-plugin-babel": "^4.4.0",
51
51
  "rollup-plugin-img": "^1.1.0",
52
52
  "rollup-plugin-terser": "^6.1.0",
@@ -72,7 +72,7 @@
72
72
  "publishConfig": {
73
73
  "access": "public"
74
74
  },
75
- "gitHead": "ecd5a545a11f95650a95c087dbee5281e65d5dbd",
75
+ "gitHead": "a3ea2c0de00a2487db9d0254ff0b85c897fe2837",
76
76
  "rollup": {
77
77
  "external": [
78
78
  "vue",
@@ -86,5 +86,8 @@
86
86
  "output": {
87
87
  "name": "SurveyResponsePlugin"
88
88
  }
89
+ },
90
+ "dependencies": {
91
+ "quill": "^2.0.2"
89
92
  }
90
93
  }
@@ -0,0 +1,232 @@
1
+ <template>
2
+ <div v-if="!emptyQuestions" class="survey-response-wrapper">
3
+ <Form
4
+ ref="responseForm"
5
+ :model="responseSurveyAnswers"
6
+ :disabled="readonly"
7
+ >
8
+ <div :key="surveyIndex" v-for="(survey, surveyIndex) in surveys">
9
+ <div
10
+ :key="index"
11
+ v-for="(question, index) in getFilterSortQuestions(survey.id)"
12
+ class="question"
13
+ >
14
+ <question-title
15
+ :question="question"
16
+ :custom-question="getCustomQuestion(question.id)"
17
+ :index="index"
18
+ >
19
+ </question-title>
20
+ <question-body
21
+ :question="calculateQuestion(question, question.originalIndex)"
22
+ :answer="
23
+ responseSurveyAnswers.moreSurveyAnswers[surveyIndex].answers[
24
+ question.originalIndex
25
+ ]
26
+ "
27
+ :index="question.originalIndex"
28
+ :survey-index="surveyIndex"
29
+ :is-more-survey="true"
30
+ :options="options"
31
+ :readonly="readonly"
32
+ @singleQuestion="handleSelected"
33
+ >
34
+ </question-body>
35
+ </div>
36
+ </div>
37
+ </Form>
38
+ </div>
39
+ <empty-question v-else></empty-question>
40
+ </template>
41
+ <script lang="ts">
42
+ import Vue from "vue";
43
+ import _ from "lodash";
44
+ import EmptyQuestion from "./empty-question.vue";
45
+ import QuestionTitle from "./question/question-title.vue";
46
+ import QuestionBody from "./question/question-body.vue";
47
+ import { Form } from "view-design";
48
+ import SurveyResponseMixin from "../mixins/survey-response-mixin";
49
+ import { QuestionType } from "@wg-npm/survey-core";
50
+ import { EventBus } from "../event-bus.js";
51
+
52
+
53
+ export default Vue.extend({
54
+ name: "MoreSurveyResponse",
55
+ mixins: [SurveyResponseMixin],
56
+ components: {
57
+ QuestionTitle,
58
+ QuestionBody,
59
+ EmptyQuestion,
60
+ Form,
61
+ },
62
+ provide() {
63
+ return {
64
+ responseStar:
65
+ this.response.status != this.$consts.STATUS_DRAFT
66
+ ? this.response.star
67
+ : null,
68
+ responseStatus: this.response.status,
69
+ $rootComponent: this,
70
+ };
71
+ },
72
+ props: {
73
+ surveys: {
74
+ type: Array,
75
+ required: true,
76
+ },
77
+ options: {
78
+ type: Object,
79
+ },
80
+ response: {
81
+ type: Object,
82
+ required: true,
83
+ },
84
+ responseSurveyAnswers: {
85
+ type: Object,
86
+ required: true,
87
+ },
88
+ customQuestions: {
89
+ type: Object,
90
+ required: false,
91
+ },
92
+ },
93
+ data() {
94
+ return {
95
+ answers: {},
96
+ sortQuestions: null,
97
+ recordQuestionId: "",
98
+ screenshotData: {
99
+ type: Object,
100
+ required: false,
101
+ },
102
+ };
103
+ },
104
+ created() {
105
+ let number = 1;
106
+ this.surveys.forEach((survey) => {
107
+ survey.questions.forEach((item, index) => {
108
+ item.originalIndex = index;
109
+ item.surveyId = survey.id;
110
+ if (QuestionType.TEXT_TITLE !== item.type) {
111
+ item.header.number = number++;
112
+ }
113
+ });
114
+ });
115
+ this.sortQuestions = _.flatMap(this.surveys, "questions");
116
+ this.parseQuestionAnswers();
117
+ this.initDraftSortQuestions();
118
+ },
119
+ computed: {
120
+ emptyQuestions: function () {
121
+ return _.size(this.sortQuestions) == 0;
122
+ },
123
+ },
124
+ watch: {
125
+ screenshotData: {
126
+ deep: true,
127
+ handler(newValue) {
128
+ if (Array.isArray(newValue.urls) && newValue.urls.length > 0) {
129
+ EventBus.$emit("screen-shot-urls", newValue);
130
+ }
131
+ },
132
+ },
133
+ },
134
+ methods: {
135
+ getScreenShot(message) {
136
+ this.$emit("getScreenShot", message);
137
+ },
138
+ updateAnswerByQuestion(question, resetData) {
139
+ // @ts-ignore
140
+ let surveyId = _.find(
141
+ this.sortQuestions,
142
+ (q) => q.id === question.id
143
+ )?.surveyId;
144
+ let surveyIndex = _.findIndex(
145
+ this.surveys,
146
+ (s: any) => s.id === surveyId
147
+ );
148
+ this.$set(
149
+ this.responseSurveyAnswers.moreSurveyAnswers[surveyIndex].answers,
150
+ question.originalIndex,
151
+ resetData
152
+ );
153
+ },
154
+ getCustomQuestion(questionId) {
155
+ return _.find(
156
+ // @ts-ignore
157
+ _.get(this.customQuestions, "chosenQuestions", []),
158
+ (q) => q.id === questionId
159
+ );
160
+ },
161
+ getFilterSortQuestions(surveyId) {
162
+ return _.filter(this.sortQuestions, (s) => s.surveyId === surveyId);
163
+ },
164
+ parseQuestionAnswers() {
165
+ if (
166
+ _.isEmpty(
167
+ // @ts-ignore
168
+ _.get(this.responseSurveyAnswers, "moreSurveyAnswers", []))
169
+ ) {
170
+ _.each(this.surveys, (s) => {
171
+ let surveyAnswer = {
172
+ surveyId: s.id,
173
+ answers: [],
174
+ };
175
+ this.responseSurveyAnswers.moreSurveyAnswers.push(surveyAnswer);
176
+ });
177
+ }
178
+ _.each(this.responseSurveyAnswers.moreSurveyAnswers, (surveyAnswers) => {
179
+ _.each(surveyAnswers.answers, (data) => {
180
+ // @ts-ignore
181
+ _.set(this.answers, data.questionId, data);
182
+ });
183
+ });
184
+
185
+ // @ts-ignore
186
+ _.set(this.responseSurveyAnswers, "moreSurveyAnswers", []);
187
+
188
+ _.forEach(
189
+ _.groupBy(this.sortQuestions, (o) => {
190
+ return o.surveyId;
191
+ }),
192
+ (questions, surveyId) => {
193
+ let surveyAnswers: any = [];
194
+ _.each(questions, (question) => {
195
+ let input_answers: any = [];
196
+ let questionInputtedEnabled = question.options.inputtedEnabled;
197
+
198
+ // @ts-ignore
199
+ let answer: any = _.get(this.answers, question.id);
200
+ if (!answer) {
201
+ _.forEach(question.choices, (choice) => {
202
+ let choiceInputEnabled = choice.options.inputEnabled;
203
+ if (questionInputtedEnabled && choiceInputEnabled) {
204
+ input_answers.push({
205
+ choiceId: choice.id,
206
+ inputText: null,
207
+ });
208
+ }
209
+ });
210
+ }
211
+ answer = answer
212
+ ? answer
213
+ : {
214
+ answer: question.type == "MULTI_SELECTION" ? [] : null,
215
+ question_id: question.id,
216
+ question_type: question.type,
217
+ score: null,
218
+ star: null,
219
+ inputAnswers: input_answers,
220
+ };
221
+ surveyAnswers.push(answer);
222
+ });
223
+ this.responseSurveyAnswers.moreSurveyAnswers.push({
224
+ surveyId: surveyId,
225
+ answers: surveyAnswers,
226
+ });
227
+ }
228
+ );
229
+ },
230
+ },
231
+ });
232
+ </script>
@@ -4,6 +4,8 @@
4
4
  :is="question.type"
5
5
  :answer="answer"
6
6
  :index="index"
7
+ :survey-index="surveyIndex"
8
+ :is-more-survey="isMoreSurvey"
7
9
  :options="options"
8
10
  :question="question"
9
11
  :readonly="readonly"
@@ -39,6 +41,7 @@ export default Vue.extend({
39
41
  required: true,
40
42
  },
41
43
  index: Number,
44
+ surveyIndex: Number,
42
45
  answer: {
43
46
  type: Object,
44
47
  required: true,
@@ -49,6 +52,9 @@ export default Vue.extend({
49
52
  readonly: {
50
53
  type: Boolean,
51
54
  },
55
+ isMoreSurvey: {
56
+ type: Boolean,
57
+ },
52
58
  },
53
59
  methods: {
54
60
  getJumpRules(val) {
@@ -0,0 +1,61 @@
1
+ <script lang="ts">
2
+ import Vue, { CreateElement } from "vue";
3
+ import { Input } from "view-design";
4
+ import _ from "lodash";
5
+ import { CUSTOM_INPUT_REG } from "@wg-npm/survey-core";
6
+ import {Component} from "vue/types/options";
7
+
8
+ export default Vue.component("question-title-dynamic", {
9
+ components: { Input },
10
+ props: {
11
+ splitedTitles: {
12
+ type: Array,
13
+ required: true,
14
+ },
15
+ customFilledTitle: {
16
+ type: Array,
17
+ required: false,
18
+ },
19
+ },
20
+ render(createElement: CreateElement) {
21
+
22
+ let childArr: Array<any> = [];
23
+ const self = this;
24
+
25
+ _.forEach(this.splitedTitles, (title: string, index: number) => {
26
+
27
+ if(CUSTOM_INPUT_REG.test(title)) {
28
+ let corespondTitle = _.find(self.customFilledTitle, (title) => {
29
+ return title.index === index;
30
+ });
31
+ if(corespondTitle!==undefined){
32
+ childArr.push(createElement("input" as Component, {
33
+ attrs:{
34
+ class:"ivu-input ivu-input-default",
35
+ style:"width:172px"
36
+ },
37
+ domProps: {
38
+ // @ts-ignore
39
+ value: corespondTitle.title
40
+ },
41
+ on: {
42
+ input: function (value) {
43
+ // @ts-ignore
44
+ corespondTitle.title = value;
45
+ }
46
+ }
47
+ }));}
48
+ } else {
49
+ childArr.push(title);
50
+ }
51
+ });
52
+ return createElement("div", { class: "content pl-sm"}, childArr);
53
+ }
54
+ });
55
+ </script>
56
+
57
+ <style scoped lang="less">
58
+ /deep/ .ivu-input-wrapper {
59
+ width: auto;
60
+ }
61
+ </style>
@@ -1,13 +1,13 @@
1
1
  <template>
2
2
  <div class="question-title">
3
- <span v-if="question.type !== 'text_title'">
3
+ <span v-if="question.type !== 'text_title'" class="pr-sm">
4
4
  <label v-if="question.options.required" class="require-label">*</label>
5
5
  <label v-if="question.header.number" class="number"
6
6
  >{{ question.header.number }}.</label
7
7
  >
8
8
  </span>
9
- <span class="content">{{ i18nText(question.header.text) }}</span>
10
- <span class="options-explain" v-if="haveStar">
9
+ <question-title-dynamic v-if="question" :splitedTitles="getTitle(question)" :customFilledTitle="customFilledTitle"></question-title-dynamic>
10
+ <span class="options-explain" v-if="haveStar" :style="{'display':(isMobile()?'block':'')}">
11
11
  <span v-if="isSingleSelection">
12
12
  ({{
13
13
  t(
@@ -47,11 +47,18 @@
47
47
  <script lang="ts">
48
48
  import Vue from "vue";
49
49
  import { Icon } from "view-design";
50
- import { BaseQuestionModel, QuestionType } from "@wg-npm/survey-core";
50
+ import {
51
+ formatTitle,
52
+ QuestionType,
53
+ } from "@wg-npm/survey-core";
54
+ import OptionLayoutMixin from "../../mixins/option-layout-mixin";
55
+ import QuestionTitleDynamic from "./question-title-dynamic.vue";
56
+ import QuestionMixin from "../../mixins/question-mixin";
51
57
 
52
58
  export default Vue.extend({
53
59
  name: "question-title",
54
- components: { Icon },
60
+ components: { Icon, QuestionTitleDynamic },
61
+ mixins: [OptionLayoutMixin, QuestionMixin],
55
62
  inject: ["$rootComponent"],
56
63
  props: {
57
64
  index: {
@@ -65,8 +72,15 @@ export default Vue.extend({
65
72
  language: {
66
73
  type: String,
67
74
  },
75
+ customQuestion: {
76
+ type: Object,
77
+ required: false,
78
+ },
68
79
  },
69
80
  computed: {
81
+ customFilledTitle() {
82
+ return this.customQuestion?.filledTitle;
83
+ },
70
84
  haveStar() {
71
85
  return this.question?.options?.starEnabled ?? false;
72
86
  },
@@ -74,5 +88,21 @@ export default Vue.extend({
74
88
  return this.question.type == QuestionType.SINGLE_SELECTION;
75
89
  },
76
90
  },
91
+ methods: {
92
+ getTitle(question) {
93
+ return formatTitle(question, this.$rootComponent.currentLanguage);
94
+ },
95
+ },
77
96
  });
78
97
  </script>
98
+
99
+ <style lang="less" scoped>
100
+ .flex {
101
+ display: flex;
102
+ align-items: center;
103
+ white-space: nowrap;
104
+ }
105
+ .pr-sm {
106
+ padding-right: 4px;
107
+ }
108
+ </style>
@@ -1,43 +1,41 @@
1
1
  <template>
2
2
  <div>
3
- <div
4
- v-if="readonly || question.options.disabled"
5
- class="processed-answer"
6
- v-html="decodeHTML(value)"
7
- />
8
3
  <FormItem
9
- v-else
10
- :prop="`answers[${index}].answer`"
4
+ :prop="answerProp"
11
5
  :rules="{
12
6
  required: question.options.required,
13
7
  message: t('survey_response.question.question_required'),
14
8
  }"
15
9
  >
16
- <Input
10
+ <quill-rich-text
17
11
  v-model.trim="value.answer"
18
12
  :placeholder="placeholder"
19
- :disabled="question.options.readonly"
20
- />
13
+ :disabled="readonly || question.options.readonly"
14
+ ></quill-rich-text>
21
15
  </FormItem>
22
16
  </div>
23
17
  </template>
24
18
 
25
19
  <script lang="ts">
26
20
  import Vue from "vue";
27
- import { FormItem, Input } from "view-design";
21
+ import { FormItem } from "view-design";
22
+ import QuestionMixin from "../../../mixins/question-mixin";
23
+ import LocalMixin from "../../../mixins/locale-mixin";
24
+ import QuillRichText from "./quill-rich-text.vue";
28
25
 
29
26
  export default Vue.extend({
30
27
  name: "fill-blank",
31
28
  components: {
32
29
  FormItem,
33
- Input,
30
+ QuillRichText,
34
31
  },
32
+ inject: ["$rootComponent"],
33
+ mixins: [QuestionMixin, LocalMixin],
35
34
  props: {
36
35
  question: {
37
36
  type: Object,
38
37
  required: true,
39
38
  },
40
- index: Number,
41
39
  answer: {
42
40
  type: Object,
43
41
  required: true,
@@ -86,7 +84,7 @@ export default Vue.extend({
86
84
  cursor: not-allowed;
87
85
  color: #ccc;
88
86
  width: 100%;
89
- height: 32px;
87
+ min-height: 32px;
90
88
  border: 1px solid #dcdee2;
91
89
  border-radius: 4px;
92
90
  padding: 4px 8px;
@@ -10,7 +10,7 @@
10
10
  >
11
11
  <span class="title"> {{ i18nText(subQuestion.text) }} </span>
12
12
  <FormItem
13
- :prop="`answers[${index}].answer[${subIndex}].answer`"
13
+ :prop="answerProp(subIndex)"
14
14
  :rules="{
15
15
  required: question.options.required && !question.options.disabled,
16
16
  message: t('survey_response.question.question_required'),
@@ -29,7 +29,13 @@
29
29
  <Radio
30
30
  :label="choice.id"
31
31
  :key="choice.id"
32
- @click.native="toggleAnswer(choice.id, subIndex)"
32
+ @click.native="
33
+ toggleAnswer(
34
+ choice.id,
35
+ subIndex,
36
+ subQuestion.options.readonly || question.options.disabled
37
+ )
38
+ "
33
39
  :disabled="
34
40
  subQuestion.options.readonly || question.options.disabled
35
41
  "
@@ -68,6 +74,12 @@ export default Vue.extend({
68
74
  required: true,
69
75
  },
70
76
  index: Number,
77
+ surveyIndex: Number,
78
+ isMoreSurvey: {
79
+ type: Boolean,
80
+ required: false,
81
+ default: false,
82
+ },
71
83
  answer: {
72
84
  type: Object,
73
85
  required: true,
@@ -86,6 +98,11 @@ export default Vue.extend({
86
98
  },
87
99
  },
88
100
  methods: {
101
+ answerProp(subIndex) {
102
+ return this.isMoreSurvey
103
+ ? `moreSurveyAnswers[${this.surveyIndex}].answers[${this.index}].answer[${subIndex}].answer`
104
+ : `answers[${this.index}].answer[${subIndex}].answer`;
105
+ },
89
106
  initData() {
90
107
  let subAnswers = {};
91
108
  // @ts-ignore
@@ -127,8 +144,8 @@ export default Vue.extend({
127
144
  // @ts-ignore
128
145
  this.value.score = score;
129
146
  },
130
- toggleAnswer(subValue, subIndex) {
131
- if (this.responseStatus == this.$consts.STATUS_DRAFT) {
147
+ toggleAnswer(subValue, subIndex, disabled) {
148
+ if (this.responseStatus == this.$consts.STATUS_DRAFT && !disabled) {
132
149
  let subAnswer = this.value.answer[subIndex].answer;
133
150
  this.value.answer[subIndex].answer = _.isEmpty(subAnswer)
134
151
  ? subValue