@webitel/ui-sdk 3.2.142 → 3.2.144

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": "3.2.142",
3
+ "version": "3.2.144",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve-lib": "vue-cli-service serve",
@@ -2,10 +2,18 @@
2
2
  <div
3
3
  :class="{
4
4
  'wt-search-bar--outline': outline,
5
+ 'wt-search-bar--invalid': invalid,
5
6
  }"
6
7
  class="wt-search-bar"
7
8
  >
8
9
  <div class="wt-search-bar__wrapper">
10
+ <div class="wt-search-bar__search-icon">
11
+ <slot name="search-icon">
12
+ <wt-icon
13
+ icon="search"
14
+ ></wt-icon>
15
+ </slot>
16
+ </div>
9
17
  <input
10
18
  :placeholder="placeholder || $t('webitelUI.searchBar.placeholder')"
11
19
  :value="value"
@@ -14,27 +22,36 @@
14
22
  @input="handleInput($event.target.value)"
15
23
  @keyup="handleKeyup"
16
24
  >
17
- <div class="wt-search-bar__search-icon">
18
- <slot name="search-icon">
19
- <wt-icon
20
- icon="search"
21
- ></wt-icon>
22
- </slot>
25
+ <div class="wt-search-bar__icon-controls">
26
+ <wt-icon-btn
27
+ :class="{ 'hidden': !value }"
28
+ class="wt-search-bar__reset-icon-btn"
29
+ icon="close"
30
+ @click="handleInput('')"
31
+ ></wt-icon-btn>
32
+ <wt-hint
33
+ v-if="hint"
34
+ >{{ hint }}
35
+ </wt-hint>
36
+ <slot name="additional-actions"></slot>
23
37
  </div>
24
- <wt-icon-btn
25
- :class="{ 'hidden': !value }"
26
- class="wt-search-bar__reset-icon-btn"
27
- icon="close"
28
- @click="handleInput('')"
29
- ></wt-icon-btn>
30
38
  </div>
31
39
  </div>
32
40
  </template>
33
41
 
34
42
  <script setup>
43
+ import { reactive } from 'vue';
35
44
  import debounce from '../../scripts/debounce';
45
+ import { useValidation } from '../../mixins/validationMixin/useValidation';
36
46
 
37
47
  const props = defineProps({
48
+ v: {
49
+ type: Object,
50
+ },
51
+ customValidators: {
52
+ type: Array,
53
+ default: () => [],
54
+ },
38
55
  /**
39
56
  * Current search-bar value (`v-model`)
40
57
  */
@@ -52,6 +69,10 @@ const props = defineProps({
52
69
  type: Boolean,
53
70
  default: false,
54
71
  },
72
+ hint: {
73
+ type: String,
74
+ description: 'Adds hint icon + tooltip with text, passed as "hint" prop',
75
+ },
55
76
  });
56
77
 
57
78
  const emit = defineEmits([
@@ -60,6 +81,10 @@ const emit = defineEmits([
60
81
  'enter',
61
82
  ]);
62
83
 
84
+ const { v, customValidators } = reactive(props);
85
+
86
+ const { invalid } = useValidation({ v, customValidators });
87
+
63
88
  const search = debounce((value) => {
64
89
  emit('search', value);
65
90
  }, 1000);
@@ -89,25 +114,35 @@ function handleKeyup(event) {
89
114
  .wt-search-bar {
90
115
  cursor: text;
91
116
 
117
+ &.wt-search-bar--invalid {
118
+ .wt-search-bar__wrapper {
119
+ border-color: var(--false-color);
120
+ outline: none; // prevent outline overlapping false color
121
+ }
122
+ //deep needed to change color for icons in slot
123
+ :deep .wt-icon__icon {
124
+ fill: var(--false-color);
125
+ }
126
+ .wt-search-bar__input {
127
+ color: var(--false-color);
128
+ }
129
+ }
130
+
92
131
  .wt-search-bar__wrapper {
93
- position: relative;
132
+ border: var(--input-border);
133
+ border-color: var(--form-border-color);
134
+ border-radius: var(--border-radius);
135
+ display: flex;
136
+ padding: calc(var(--spacing-xs) - 1px) var(--spacing-xs);
137
+ align-items: center;
138
+ gap: var(--spacing-xs);
94
139
  }
95
140
 
96
141
  .wt-search-bar__search-icon {
97
- position: absolute;
98
- top: 50%;
99
- left: var(--input-icon-margin);
100
- transform: translateY(-50%);
101
- line-height: 0;
102
- pointer-events: none;
142
+ display: flex;
103
143
  }
104
144
 
105
145
  .wt-search-bar__reset-icon-btn {
106
- position: absolute;
107
- top: 50%;
108
- right: var(--input-icon-margin);
109
- transform: translateY(-50%);
110
-
111
146
  .wt-search-bar:not(:focus-within) & {
112
147
  pointer-events: none;
113
148
  opacity: 0;
@@ -121,12 +156,11 @@ function handleKeyup(event) {
121
156
  display: block;
122
157
  box-sizing: border-box;
123
158
  width: 100%;
124
- padding: var(--search-bar-padding);
159
+ padding: 0;
125
160
  transition: var(--transition);
126
161
  color: var(--form-input-color);
127
- border: var(--input-border);
128
- border-color: var(--form-border-color);
129
- border-radius: var(--border-radius);
162
+ border: none;
163
+ outline: none;
130
164
 
131
165
  &:focus {
132
166
  @include wt-placeholder('focus');
@@ -169,5 +203,11 @@ function handleKeyup(event) {
169
203
  .wt-search-bar__input::-webkit-search-results-decoration {
170
204
  display: none;
171
205
  }
206
+
207
+ .wt-search-bar__icon-controls {
208
+ display: flex;
209
+ align-items: center;
210
+ gap: var(--spacing-xs);
211
+ }
172
212
  }
173
213
  </style>
@@ -348,7 +348,7 @@ export default {
348
348
  },
349
349
  statusSelectErrorPopup: {
350
350
  title: 'Attention',
351
- message: 'he limit for agents to take a pause has been exceeded. The pause is unavailable right now.',
351
+ message: 'The limit for agents to take a pause has been exceeded. The pause is unavailable right now.',
352
352
  },
353
353
  },
354
354
  },
@@ -15,6 +15,7 @@ const messages = {
15
15
  export default new createI18n({
16
16
  // legacy: false,
17
17
  locale: 'en',
18
+ allowComposition: true,
18
19
  fallbackLocale: 'en',
19
20
  messages,
20
21
  });
@@ -346,7 +346,7 @@ export default {
346
346
  },
347
347
  statusSelectErrorPopup: {
348
348
  title: 'Внимание',
349
- message: 'Лимит операторов в паузе превишен. Перерыв сейчас недоступен.',
349
+ message: 'Лимит операторов в паузе превышен. Перерыв сейчас недоступен.',
350
350
  },
351
351
  },
352
352
  },
@@ -0,0 +1,39 @@
1
+ import { computed } from 'vue';
2
+ import { useI18n } from 'vue-i18n';
3
+
4
+ export function useValidation({ v, customValidators }) {
5
+ const { t } = useI18n();
6
+ const isValidation = computed(() => !!v && !!Object.keys(v).length);
7
+ const invalid = computed(() => isValidation.value && v.$error);
8
+
9
+ const validationText = computed(() => {
10
+ let validationText = '';
11
+ if (isValidation && invalid) {
12
+ if (v.required?.$invalid) validationText = t('validation.required');
13
+ else if (v.numeric?.$invalid) validationText = t('validation.numeric');
14
+ else if (v.email?.$invalid) validationText = t('validation.email');
15
+ else if (v.gatewayHostValidator?.$invalid) validationText = t('validation.gatewayHostValidator');
16
+ else if (v.ipValidator?.$invalid) validationText = t('validation.ipValidator');
17
+ else if (v.macValidator?.$invalid) validationText = t('validation.macValidator');
18
+ else if (v.minValue?.$invalid) validationText = `${t('validation.minValue')} ${v.minValue.$params.min}`;
19
+ else if (v.maxValue?.$invalid) validationText = `${t('validation.maxValue')} ${v.maxValue.$params.max}`;
20
+ else if (v.sipAccountValidator?.$invalid) validationText = t('validation.sipAccountValidator');
21
+ else if (v.minLength?.$invalid) validationText = `${t('validation.minLength')} ${v.minLength.$params.min}`;
22
+ else if (v.url?.$invalid) validationText = `${t('validation.url')}`;
23
+ else if (v.regExpValidator?.$invalid) validationText = `${t('validation.regExpValidator')}`;
24
+ else if (v.sameAs?.$invalid) validationText = `${t('validation.sameAs')}`;
25
+ else if (v.domainValidator?.$invalid) validationText = `${t('validation.domainValidator')}`;
26
+ }
27
+ // eslint-disable-next-line no-restricted-syntax
28
+ for (const { name, text } of customValidators) {
29
+ if (v[name]?.$invalid) validationText = text;
30
+ }
31
+ return validationText;
32
+ });
33
+
34
+ return {
35
+ isValidation,
36
+ invalid,
37
+ validationText,
38
+ };
39
+ }