@webitel/ui-sdk 3.1.80 → 3.1.82
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 +1 -1
- package/src/modules/AuditForm/components/__tests__/audit-form.spec.js +20 -15
- package/src/modules/AuditForm/components/audit-form-question-read-wrapper.vue +5 -1
- package/src/modules/AuditForm/components/audit-form-question.vue +3 -2
- package/src/modules/AuditForm/components/audit-form.vue +30 -3
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { ref } from 'vue';
|
|
2
3
|
import AuditForm from '../audit-form.vue';
|
|
3
4
|
import { generateQuestionSchema } from '../../schemas/AuditFormQuestionSchema';
|
|
4
5
|
|
|
@@ -8,11 +9,11 @@ import {
|
|
|
8
9
|
|
|
9
10
|
jest.mock('../../composables/useDestroyableSortable');
|
|
10
11
|
|
|
11
|
-
useDestroyableSortable.mockImplementation(() => ({}));
|
|
12
|
+
useDestroyableSortable.mockImplementation(() => ({ reloadSortable: ref(false) }));
|
|
12
13
|
|
|
13
14
|
describe('AuditForm', () => {
|
|
14
|
-
it('renders a component', () => {
|
|
15
|
-
const wrapper =
|
|
15
|
+
it('renders a component', async () => {
|
|
16
|
+
const wrapper = mount(AuditForm, {
|
|
16
17
|
props: {
|
|
17
18
|
mode: '',
|
|
18
19
|
questions: [],
|
|
@@ -20,42 +21,46 @@ describe('AuditForm', () => {
|
|
|
20
21
|
});
|
|
21
22
|
expect(wrapper.isVisible()).toBe(true);
|
|
22
23
|
});
|
|
23
|
-
it('add question button triggers update question event', () => {
|
|
24
|
-
const wrapper =
|
|
24
|
+
it('add question button triggers update question event', async () => {
|
|
25
|
+
const wrapper = mount(AuditForm, {
|
|
25
26
|
props: {
|
|
26
27
|
mode: 'create',
|
|
27
28
|
questions: [],
|
|
28
29
|
},
|
|
29
30
|
});
|
|
30
|
-
wrapper.findComponent('.audit-form__add-button').vm.$emit('click');
|
|
31
|
+
await wrapper.findComponent('.audit-form__add-button').vm.$emit('click');
|
|
32
|
+
await wrapper.vm.$nextTick();
|
|
33
|
+
await wrapper.vm.$nextTick();
|
|
34
|
+
await wrapper.vm.$nextTick();
|
|
35
|
+
console.info(wrapper.html());
|
|
31
36
|
expect(wrapper.emitted()['update:questions'][0][0])
|
|
32
37
|
.toEqual([generateQuestionSchema({ required: true })]);
|
|
33
38
|
});
|
|
34
|
-
it('delete event from child question emits update without passed question', () => {
|
|
35
|
-
const wrapper =
|
|
39
|
+
it('delete event from child question emits update without passed question', async () => {
|
|
40
|
+
const wrapper = mount(AuditForm, {
|
|
36
41
|
props: {
|
|
37
42
|
mode: 'create',
|
|
38
43
|
questions: [generateQuestionSchema()],
|
|
39
44
|
},
|
|
40
45
|
});
|
|
41
|
-
wrapper.findComponent({ name: 'audit-form-question' }).vm.$emit('delete', { key: 0 });
|
|
46
|
+
await wrapper.findComponent({ name: 'audit-form-question' }).vm.$emit('delete', { key: 0 });
|
|
42
47
|
expect(wrapper.emitted()['update:questions'][0][0])
|
|
43
48
|
.toEqual([]);
|
|
44
49
|
});
|
|
45
|
-
it('copy event from child question emits update with duplicated questions', () => {
|
|
50
|
+
it('copy event from child question emits update with duplicated questions', async () => {
|
|
46
51
|
const question = generateQuestionSchema();
|
|
47
|
-
const wrapper =
|
|
52
|
+
const wrapper = mount(AuditForm, {
|
|
48
53
|
props: {
|
|
49
54
|
mode: 'create',
|
|
50
55
|
questions: [question],
|
|
51
56
|
},
|
|
52
57
|
});
|
|
53
|
-
wrapper.findComponent({ name: 'audit-form-question' }).vm.$emit('copy', { question, key: 0 });
|
|
58
|
+
await wrapper.findComponent({ name: 'audit-form-question' }).vm.$emit('copy', { question, key: 0 });
|
|
54
59
|
expect(wrapper.emitted()['update:questions'][0][0])
|
|
55
60
|
.toEqual([question, question]);
|
|
56
61
|
});
|
|
57
|
-
it('initializes result depending on passed questions',
|
|
58
|
-
const wrapper =
|
|
62
|
+
it('initializes result depending on passed questions',() => {
|
|
63
|
+
const wrapper = mount(AuditForm, {
|
|
59
64
|
props: {
|
|
60
65
|
mode: 'fill',
|
|
61
66
|
questions: [generateQuestionSchema(), generateQuestionSchema(), generateQuestionSchema()],
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
>{{ question.question }}</p>
|
|
18
18
|
<wt-icon
|
|
19
19
|
class="audit-form-question-read__drag-icon"
|
|
20
|
-
v-if="!disableDragging"
|
|
20
|
+
v-if="!disableDragging && !first"
|
|
21
21
|
icon="move"
|
|
22
22
|
color="secondary"
|
|
23
23
|
></wt-icon>
|
|
@@ -59,6 +59,10 @@ const props = defineProps({
|
|
|
59
59
|
type: Boolean,
|
|
60
60
|
default: false,
|
|
61
61
|
},
|
|
62
|
+
first: {
|
|
63
|
+
type: Boolean,
|
|
64
|
+
default: false,
|
|
65
|
+
},
|
|
62
66
|
});
|
|
63
67
|
|
|
64
68
|
const emit = defineEmits([
|
|
@@ -78,7 +78,7 @@ const v$ = useVuelidate(computed(() => (
|
|
|
78
78
|
},
|
|
79
79
|
} : {
|
|
80
80
|
result: {
|
|
81
|
-
required: (value) => (question.value.required ?
|
|
81
|
+
required: (value) => (question.value.required ? !isEmpty(value) : true),
|
|
82
82
|
},
|
|
83
83
|
})), { question, result }, { $autoDirty: true });
|
|
84
84
|
|
|
@@ -102,10 +102,11 @@ function activateQuestion() {
|
|
|
102
102
|
state.value = QuestionState.EDIT;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
defineExpose({ activateQuestion });
|
|
106
|
+
|
|
105
107
|
// initialize validations
|
|
106
108
|
onMounted(() => {
|
|
107
109
|
v$.value.$touch();
|
|
108
|
-
if (props.first) activateQuestion();
|
|
109
110
|
});
|
|
110
111
|
</script>
|
|
111
112
|
|
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
>
|
|
8
8
|
<audit-form-question
|
|
9
9
|
v-for="(question, key) of questions"
|
|
10
|
+
ref="auditQuestions"
|
|
10
11
|
:key="key"
|
|
11
12
|
:question="question"
|
|
12
13
|
:result="(result && result[key]) ? result[key] : null"
|
|
13
14
|
:mode="mode"
|
|
14
15
|
:first="key === 0"
|
|
15
16
|
:readonly="readonly"
|
|
17
|
+
:class="{'audit-form-question--sort-ignore': key === 0}"
|
|
16
18
|
@copy="copyQuestion({ question, key })"
|
|
17
19
|
@delete="deleteQuestion({ question, key})"
|
|
18
20
|
@update:question="handleQuestionUpdate({ key, value: $event })"
|
|
@@ -33,6 +35,7 @@
|
|
|
33
35
|
import cloneDeep from 'lodash/cloneDeep';
|
|
34
36
|
import {
|
|
35
37
|
watch, watchEffect, ref, computed, onMounted,
|
|
38
|
+
reactive, nextTick,
|
|
36
39
|
} from 'vue';
|
|
37
40
|
import { useVuelidate } from '@vuelidate/core';
|
|
38
41
|
import { useDestroyableSortable } from '../composables/useDestroyableSortable';
|
|
@@ -70,13 +73,17 @@ const emit = defineEmits([
|
|
|
70
73
|
const v$ = useVuelidate();
|
|
71
74
|
|
|
72
75
|
const isInvalidForm = computed(() => !!v$.value.$errors.length);
|
|
76
|
+
const auditQuestions = ref(null);
|
|
77
|
+
const isQuestionAdded = reactive({ value: false, index: null });
|
|
73
78
|
|
|
74
|
-
function addQuestion({ index, question } = {}) {
|
|
79
|
+
async function addQuestion({ index, question } = {}) {
|
|
75
80
|
const questions = [...props.questions];
|
|
76
81
|
const newQuestion = question || generateQuestionSchema();
|
|
77
82
|
if (index != null) questions.splice(index, 0, newQuestion);
|
|
78
83
|
else questions.push(newQuestion);
|
|
79
|
-
emit('update:questions', questions);
|
|
84
|
+
await emit('update:questions', questions);
|
|
85
|
+
isQuestionAdded.value = true;
|
|
86
|
+
isQuestionAdded.index = index || 'last';
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
function handleQuestionUpdate({ key, value }) {
|
|
@@ -98,6 +105,7 @@ function deleteQuestion({ key }) {
|
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
function changeQuestionsOrder({ oldIndex, newIndex }) {
|
|
108
|
+
if (newIndex === 0) return;
|
|
101
109
|
const questions = [...props.questions];
|
|
102
110
|
const [el] = questions.splice(oldIndex, 1);
|
|
103
111
|
questions.splice(newIndex, 0, el);
|
|
@@ -118,7 +126,21 @@ function initResult() {
|
|
|
118
126
|
function initQuestions() {
|
|
119
127
|
if (props.mode === 'create' && !props.questions.length) {
|
|
120
128
|
addQuestion({ question: generateQuestionSchema({ required: true }) });
|
|
121
|
-
}
|
|
129
|
+
} else if (props.questions.length) auditQuestions.value.at(0).activateQuestion();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// https://my.webitel.com/browse/WTEL-3451, https://my.webitel.com/browse/WTEL-3436
|
|
133
|
+
// at new question added, activate this question
|
|
134
|
+
async function atQuestionAdded() {
|
|
135
|
+
// wait for new question to render
|
|
136
|
+
await nextTick();
|
|
137
|
+
const index = isQuestionAdded.index && isQuestionAdded.index === 'last'
|
|
138
|
+
? -1
|
|
139
|
+
: isQuestionAdded.index;
|
|
140
|
+
auditQuestions.value.at(index).activateQuestion();
|
|
141
|
+
|
|
142
|
+
isQuestionAdded.value = false;
|
|
143
|
+
isQuestionAdded.index = null;
|
|
122
144
|
}
|
|
123
145
|
|
|
124
146
|
const sortableWrapper = ref(null);
|
|
@@ -126,6 +148,7 @@ const sortableWrapper = ref(null);
|
|
|
126
148
|
const { reloadSortable } = useDestroyableSortable(sortableWrapper, {
|
|
127
149
|
handle: '.audit-form-question-read__drag-icon',
|
|
128
150
|
disabled: props.mode !== 'create',
|
|
151
|
+
filter: '.audit-form-question--sort-ignore',
|
|
129
152
|
onEnd: ({ newIndex, oldIndex }) => {
|
|
130
153
|
if (newIndex === oldIndex) return;
|
|
131
154
|
changeQuestionsOrder({ oldIndex, newIndex });
|
|
@@ -134,6 +157,10 @@ const { reloadSortable } = useDestroyableSortable(sortableWrapper, {
|
|
|
134
157
|
|
|
135
158
|
watch(v$, () => emit('update:validation', { invalid: isInvalidForm.value, v$: v$.value }));
|
|
136
159
|
watchEffect(initResult);
|
|
160
|
+
watch(() => props.questions, () => {
|
|
161
|
+
if (!isQuestionAdded.value) return;
|
|
162
|
+
atQuestionAdded();
|
|
163
|
+
});
|
|
137
164
|
|
|
138
165
|
onMounted(() => {
|
|
139
166
|
initQuestions();
|