@webitel/ui-sdk 24.2.7 → 24.2.8

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": "@webitel/ui-sdk",
3
- "version": "24.2.7",
3
+ "version": "24.2.8",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -1,16 +1,16 @@
1
1
 
2
2
  .multiselect :deep {
3
- cursor: pointer;
4
3
  position: relative;
4
+ cursor: pointer;
5
5
 
6
6
  .multiselect__select {
7
7
  position: absolute;
8
8
  top: var(--select-icon-top-pos);
9
9
  right: var(--select-caret-right-pos);
10
- padding: 0; // reset default
11
- transition: var(--transition);
12
10
  width: fit-content; // reset default
13
11
  height: fit-content; // reset default
12
+ padding: 0; // reset default
13
+ transition: var(--transition);
14
14
  background: transparent;
15
15
 
16
16
  &:before {
@@ -45,10 +45,10 @@
45
45
  .multiselect__placeholder {
46
46
  @extend %typo-body-1;
47
47
  @include wt-placeholder;
48
- background: transparent;
49
- color: var(--wt-text-field-text-color);
50
- padding: 0; // reset default
51
48
  margin: 0; // reset default
49
+ padding: 0; // reset default
50
+ color: var(--wt-text-field-text-color);
51
+ background: transparent;
52
52
  }
53
53
 
54
54
  .multiselect__custom-tag,
@@ -58,9 +58,9 @@
58
58
 
59
59
  .multiselect__placeholder {
60
60
  @extend %wt-placeholder;
61
+ display: block;
61
62
  overflow: hidden;
62
63
  max-width: 100%;
63
- display: block;
64
64
 
65
65
  // text overflow 3 dots
66
66
  white-space: nowrap;
@@ -74,8 +74,8 @@
74
74
  border: var(--select-tags-border);
75
75
  border-color: var(--wt-text-field-select-option-wrapper-border-color);
76
76
  border-radius: var(--border-radius);
77
- box-shadow: var(--elevation-10);
78
77
  background: transparent;
78
+ box-shadow: var(--elevation-10);
79
79
  }
80
80
 
81
81
  // select options
@@ -108,6 +108,10 @@
108
108
  .multiselect__select .wt-icon__icon {
109
109
  fill: var(--icon-active-color);
110
110
  }
111
+
112
+ .multiselect__custom-value-arrow {
113
+ transform: none;
114
+ }
111
115
  }
112
116
 
113
117
  .wt-select--loading,
@@ -110,10 +110,12 @@ export default {
110
110
  return option[this.defaultOptionLabel] || option;
111
111
  },
112
112
  handleSearchChange(search) {
113
+ // search can be used in non-api mode too
114
+ this.searchParams.search = search;
115
+
113
116
  if (!this.isApiMode) return;
114
117
  this.isLoading = true;
115
118
  this.searchParams.page = 1;
116
- this.searchParams.search = search;
117
119
  this.fetchOptions();
118
120
  },
119
121
 
@@ -11,21 +11,20 @@
11
11
  >
12
12
  <wt-label
13
13
  v-if="hasLabel"
14
- v-bind="labelProps"
15
14
  :disabled="disabled"
16
15
  :invalid="invalid"
17
16
  class="wt-select__label"
17
+ v-bind="labelProps"
18
18
  >
19
19
  <!-- @slot Custom input label -->
20
20
  <slot
21
- v-bind="{ label }"
22
21
  name="label"
22
+ v-bind="{ label }"
23
23
  >
24
24
  {{ requiredLabel }}
25
25
  </slot>
26
26
  </wt-label>
27
27
  <vue-multiselect
28
- v-bind="$attrs"
29
28
  ref="vue-multiselect"
30
29
  :allow-empty="allowEmpty"
31
30
  :disabled="disabled"
@@ -33,12 +32,13 @@
33
32
  :label="selectOptionLabel"
34
33
  :limit="1"
35
34
  :loading="false"
35
+ :model-value="selectValue"
36
36
  :multiple="multiple"
37
37
  :options="selectOptions"
38
38
  :placeholder="placeholder || label"
39
39
  :track-by="trackBy"
40
- :model-value="selectValue"
41
40
  class="wt-select__select"
41
+ v-bind="$attrs"
42
42
  @close="isOpened = false"
43
43
  @open="isOpened = true"
44
44
  v-on="listeners"
@@ -62,8 +62,8 @@
62
62
  <!-- Slot for custom label template for single select-->
63
63
  <template #singleLabel="{ option }">
64
64
  <slot
65
- v-bind="{ option, optionLabel }"
66
65
  name="singleLabel"
66
+ v-bind="{ option, optionLabel }"
67
67
  >
68
68
  <span class="multiselect__single-label">
69
69
  {{ getOptionLabel({ option, optionLabel }) }}
@@ -74,8 +74,8 @@
74
74
  <!-- Slot for custom option template -->
75
75
  <template #option="{ option }">
76
76
  <slot
77
- v-bind="{ option, optionLabel }"
78
77
  name="option"
78
+ v-bind="{ option, optionLabel }"
79
79
  >
80
80
  {{ getOptionLabel({ option, optionLabel }) }}
81
81
  </slot>
@@ -83,8 +83,19 @@
83
83
 
84
84
  <!-- Element for opening and closing the dropdown -->
85
85
  <template #caret="{ toggle }">
86
+ <!-- In mode allowCustomValues, adding is done by clicking on this icon -->
87
+ <!-- [https://my.webitel.com/browse/WTEL-3181]-->
88
+ <wt-icon-btn
89
+ v-if="allowCustomValues && searchParams.search"
90
+ :disabled="disabled"
91
+ class="multiselect__select multiselect__custom-value-arrow"
92
+ icon="call-merge-filled"
93
+ @mousedown.prevent.stop="handleCustomValue(toggle)"
94
+ />
95
+ <!-- To view a list of possible values, click on this icon -->
86
96
  <!-- @mousedown.native.prevent.stop="toggle": https://github.com/shentao/vue-multiselect/issues/1204#issuecomment-615114727 -->
87
97
  <wt-icon-btn
98
+ v-else
88
99
  :disabled="disabled"
89
100
  class="multiselect__select"
90
101
  icon="arrow-down"
@@ -130,11 +141,16 @@
130
141
  </template>
131
142
 
132
143
  <script>
144
+ import taggableMixin from '../wt-tags-input/mixin/taggableMixin';
133
145
  import multiselectMixin from './mixins/multiselectMixin';
134
146
 
135
147
  export default {
136
148
  name: 'WtSelect',
137
- mixins: [multiselectMixin],
149
+ mixins: [
150
+ multiselectMixin,
151
+ // taggableMixin is used to add custom select values, see [https://my.webitel.com/browse/WTEL-3181]
152
+ taggableMixin,
153
+ ],
138
154
  props: {
139
155
  value: {},
140
156
 
@@ -147,12 +163,45 @@ export default {
147
163
  type: Boolean,
148
164
  default: true,
149
165
  },
166
+ // for taggableMixin functionality
167
+ allowCustomValues: {
168
+ type: Boolean,
169
+ default: false,
170
+ description: 'See wt-tags-input "taggable" prop.',
171
+ },
172
+ // for taggableMixin functionality
173
+ handleCustomValuesAdditionManually: {
174
+ type: Boolean,
175
+ default: false,
176
+ description: 'See wt-tags-input "manualTagging" prop.',
177
+ },
150
178
  },
151
- emits: ['reset', 'search-change', 'input', 'closed'],
179
+ emits: [
180
+ 'reset',
181
+ 'search-change',
182
+ 'input',
183
+ 'closed',
184
+ 'custom-value', // fires when allowCustomValues and new customValue is added
185
+ ],
152
186
  data: () => ({
153
187
  isOpened: false,
154
188
  }),
189
+ computed: {
190
+ // for taggableMixin
191
+ taggable() { return this.allowCustomValues; },
192
+ // for taggableMixin
193
+ manualTagging() { return this.handleCustomValuesAdditionManually; },
194
+ },
155
195
  methods: {
196
+ // for taggableMixin functionality
197
+ handleCustomValue(toggle) {
198
+ toggle();
199
+ this.tag(this.searchParams.search);
200
+ },
201
+ // for taggableMixin functionality
202
+ emitTagEvent(searchQuery, id) {
203
+ this.$emit('custom-value', searchQuery, id);
204
+ },
156
205
  clearValue() {
157
206
  let value = '';
158
207
  if (Array.isArray(this.value)) value = [];
@@ -215,17 +264,19 @@ export default {
215
264
  .wt-select.wt-select--multiple:not(.wt-select--clearable) {
216
265
  .multiselect :deep {
217
266
  $multiselect-limit-right-pos: calc(
218
- var(--select-caret-right-pos) // caret offet from border
219
- + var(--icon-md-size) // caret size
267
+ var(--select-caret-right-pos)// caret offet from border
268
+ + var(--icon-md-size)// caret size
220
269
  + var(--input-padding) // caret-to-chip offset
221
270
  );
271
+
222
272
  .multiselect__tags {
223
273
  padding-right: calc(
224
274
  $multiselect-limit-right-pos
225
- + 50px // chip
275
+ + 50px// chip
226
276
  + var(--input-padding) // chip-to-content offset
227
277
  );
228
278
  }
279
+
229
280
  .multiselect__limit {
230
281
  right: $multiselect-limit-right-pos;
231
282
  }
@@ -236,14 +287,15 @@ export default {
236
287
  .wt-select.wt-select--clearable:not(.wt-select--multiple) {
237
288
  .multiselect :deep {
238
289
  $multiselect-clear-right-pos: calc(
239
- var(--select-caret-right-pos) // caret offset from border
240
- + var(--icon-md-size) // caret size
290
+ var(--select-caret-right-pos)// caret offset from border
291
+ + var(--icon-md-size)// caret size
241
292
  + var(--input-padding) // caret-to-chip offset
242
293
  );
294
+
243
295
  .multiselect__tags {
244
296
  padding-right: calc(
245
297
  $multiselect-clear-right-pos
246
- + var(--icon-md-size) // clear
298
+ + var(--icon-md-size)// clear
247
299
  + var(--input-padding) // clear-to-content offset
248
300
  );
249
301
  }
@@ -25,7 +25,7 @@ describe('WtTagsInput', () => {
25
25
  },
26
26
  });
27
27
  wrapper.findComponent({ name: 'vue-multiselect' }).vm.$emit('tag', tag);
28
- expect(wrapper.emitted().input[0][0]).toEqual([tag]);
28
+ expect(wrapper.emitted().input[0]).toEqual([tag]);
29
29
  });
30
30
 
31
31
  it('in manual mode doesnt emit "input" event at native "tag" event', () => {
@@ -0,0 +1,24 @@
1
+ import { mount, shallowMount } from '@vue/test-utils';
2
+ import taggableMixin from '../taggableMixin';
3
+
4
+ describe('taggableMixin', () => {
5
+ const Component = {
6
+ render() {},
7
+ mixins: [taggableMixin],
8
+ };
9
+
10
+ it('renders a component', () => {
11
+ const wrapper = shallowMount(Component);
12
+ expect(wrapper.exists()).toBe(true);
13
+ });
14
+
15
+ it('Methods are called correctly', () => {
16
+ const searchQuery = '123';
17
+ const wrapper = mount(Component);
18
+
19
+ wrapper.vm.$emit('tag', searchQuery);
20
+
21
+ expect(wrapper.emitted().tag).toBeTruthy()
22
+ expect(wrapper.emitted().input).toBeFalsy();
23
+ });
24
+ })
@@ -0,0 +1,36 @@
1
+ export default {
2
+ methods: {
3
+ // TODO: WHAT IS "ID" PARAM?!
4
+ // this functionality allows you to add custom values to the list of values
5
+ // [https://my.webitel.com/browse/WTEL-3181]
6
+ tag(searchQuery, id) {
7
+ this.emitTagEvent(searchQuery, id);
8
+
9
+ const tag = this.trackBy ? {
10
+ [this.optionLabel || 'name']: searchQuery,
11
+ [this.trackBy]: id || searchQuery,
12
+ } : searchQuery;
13
+
14
+ const isTagExist = (newTag) => {
15
+ if (typeof newTag === 'string') {
16
+ return this.options.some((elem) => elem === newTag);
17
+ }
18
+ return this.options.some((elem) => elem[this.trackBy] ===
19
+ newTag[this.trackBy]);
20
+ };
21
+
22
+ if (isTagExist(tag)) return;
23
+
24
+ this.options.unshift(tag);
25
+ if (!this.manualTagging) {
26
+ const value = this.multiple ? [...this.value, tag] : tag;
27
+ this.input(value);
28
+ }
29
+ },
30
+ // method to override
31
+ emitTagEvent(searchQuery, id) {
32
+ this.$emit('tag', searchQuery, id);
33
+ },
34
+ },
35
+ };
36
+
@@ -9,35 +9,35 @@
9
9
  >
10
10
  <wt-label
11
11
  v-if="hasLabel"
12
- v-bind="labelProps"
13
12
  :disabled="disabled"
14
13
  :invalid="invalid"
15
14
  class="wt-tags-input__label"
15
+ v-bind="labelProps"
16
16
  >
17
17
  <!-- @slot Custom input label -->
18
18
  <slot
19
- v-bind="{ label }"
20
19
  name="label"
20
+ v-bind="{ label }"
21
21
  >
22
22
  {{ requiredLabel }}
23
23
  </slot>
24
24
  </wt-label>
25
25
 
26
26
  <vue-multiselect
27
- v-bind="$attrs"
28
27
  ref="vue-multiselect"
29
28
  :close-on-select="false"
30
29
  :disabled="disabled"
31
30
  :internal-search="!searchMethod"
32
31
  :label="selectOptionLabel"
33
32
  :loading="false"
33
+ :model-value="selectValue"
34
34
  :options="selectOptions"
35
35
  :placeholder="placeholder || label"
36
36
  :taggable="taggable"
37
37
  :track-by="trackBy"
38
- :model-value="selectValue"
39
38
  class="wt-tags-input__select"
40
39
  multiple
40
+ v-bind="$attrs"
41
41
  v-on="listeners"
42
42
  >
43
43
  <!-- Slot that is used for all selected options (tags)-->
@@ -45,9 +45,9 @@
45
45
  <wt-chip class="multiselect__custom-tag">
46
46
  {{ getTagOptionLabel({ option, optionLabel }) }}
47
47
  <wt-icon-btn
48
+ color="on-primary"
48
49
  icon="close--filled"
49
50
  size="sm"
50
- color="on-primary"
51
51
  @click="remove(option)"
52
52
  />
53
53
  </wt-chip>
@@ -56,8 +56,8 @@
56
56
  <!-- Slot for custom option template -->
57
57
  <template #option="{ option }">
58
58
  <slot
59
- v-bind="{ option, optionLabel }"
60
59
  name="option"
60
+ v-bind="{ option, optionLabel }"
61
61
  >
62
62
  {{ getTagOptionLabel({ option, optionLabel }) }}
63
63
  </slot>
@@ -103,10 +103,15 @@
103
103
 
104
104
  <script>
105
105
  import multiselectMixin from '../wt-select/mixins/multiselectMixin';
106
+ import taggableMixin from './mixin/taggableMixin';
106
107
 
107
108
  export default {
108
109
  name: 'WtTagsInput',
109
- mixins: [multiselectMixin],
110
+ mixins: [
111
+ multiselectMixin,
112
+ // taggableMixin is used to add custom select values, see [https://my.webitel.com/browse/WTEL-3181
113
+ taggableMixin,
114
+ ],
110
115
  props: {
111
116
  value: {
112
117
  type: Array,
@@ -135,29 +140,6 @@ export default {
135
140
  defaultOptionLabel: 'label',
136
141
  }),
137
142
  methods: {
138
- tag(searchQuery, id) {
139
- this.$emit('tag', searchQuery, id);
140
-
141
- const tag = this.trackBy ? {
142
- [this.optionLabel || 'name']: searchQuery,
143
- [this.trackBy]: id || searchQuery,
144
- } : searchQuery;
145
-
146
- const isTagExist = (newTag) => {
147
- if (typeof newTag === 'string') {
148
- return this.options.some((elem) => elem === newTag);
149
- }
150
- return this.options.some((elem) => elem[this.trackBy] === newTag[this.trackBy]);
151
- }
152
-
153
- if (isTagExist(tag)) return;
154
-
155
- this.options.unshift(tag);
156
- if (!this.manualTagging) {
157
- const value = [...this.value, tag];
158
- this.input(value);
159
- }
160
- },
161
143
  getTagOptionLabel({ optionLabel, option }) {
162
144
  /*
163
145
  Multiselect creates new tags with "label" property by default, so we need to handle
@@ -187,12 +169,12 @@ export default {
187
169
  // paddings recalc
188
170
  .wt-tags-input .multiselect :deep {
189
171
  .multiselect__tags {
190
- padding-bottom: 0;
191
172
  padding-right: calc(
192
173
  var(--input-padding)
193
174
  + var(--icon-md-size)
194
175
  + var(--select-caret-right-pos)
195
176
  );
177
+ padding-bottom: 0;
196
178
 
197
179
  .multiselect__tags-wrap {
198
180
  display: flex;