bfg-common 1.5.92 → 1.5.94

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.
Files changed (112) hide show
  1. package/assets/scss/common/normalize.scss +347 -347
  2. package/components/atoms/alert/Notification.vue +169 -169
  3. package/components/atoms/autocomplete/Autocomplete.vue +361 -362
  4. package/components/atoms/collapse/CollapseNav.vue +169 -169
  5. package/components/atoms/comboDropdownMenu/ComboDropdownMenu.vue +357 -357
  6. package/components/atoms/combobox/Combobox.vue +154 -154
  7. package/components/atoms/datepicker/Datepicker.vue +639 -639
  8. package/components/atoms/dropdown/Portlet.vue +113 -113
  9. package/components/atoms/dropdown/dropdown/Dropdown.vue +168 -168
  10. package/components/atoms/dropdown/tree/Tree.vue +137 -137
  11. package/components/atoms/list/SelectList.vue +63 -63
  12. package/components/atoms/list/dragDropList/DragDropList.vue +148 -148
  13. package/components/atoms/modal/Modal.vue +250 -250
  14. package/components/atoms/modal/bySteps/BySteps.vue +253 -253
  15. package/components/atoms/notificationBar/NotificationBar.vue +178 -178
  16. package/components/atoms/popover/Popover.vue +58 -58
  17. package/components/atoms/popover/lib/models/interfaces.ts +4 -4
  18. package/components/atoms/select/TheSelect.vue +187 -187
  19. package/components/atoms/stack/StackBlock.vue +185 -185
  20. package/components/atoms/stack/StackContent.vue +63 -63
  21. package/components/atoms/step/lib/models/verticalStepItem.ts +5 -5
  22. package/components/atoms/switch/Switch.vue +111 -111
  23. package/components/atoms/table/compact/Compact.vue +529 -529
  24. package/components/atoms/table/dataGrid/DataGrid.vue +1716 -1713
  25. package/components/atoms/table/dataGrid/DataGridPage.vue +195 -195
  26. package/components/atoms/table/info/Info.vue +2 -2
  27. package/components/atoms/table/simpleEvent/SimpleEvent.vue +98 -98
  28. package/components/atoms/table/simpleInfo/SimpleInfo.vue +73 -73
  29. package/components/atoms/tabs/Tabs.vue +217 -217
  30. package/components/atoms/wizard/Wizard.vue +341 -341
  31. package/components/common/accordion/Recursion.vue +222 -222
  32. package/components/common/adapterManager/AddAdapterModal.vue +561 -561
  33. package/components/common/adapterManager/ui/actions/AddAdapterButton.vue +30 -30
  34. package/components/common/adapterManager/ui/table/Table.vue +162 -162
  35. package/components/common/browse/BrowseNew.vue +237 -237
  36. package/components/common/browse/BrowseOld.vue +217 -217
  37. package/components/common/browse/blocks/TitleNew.vue +145 -145
  38. package/components/common/browse/blocks/TitleOld.vue +91 -91
  39. package/components/common/browse/blocks/contents/FilesOld.vue +72 -72
  40. package/components/common/chartOptionsModal/counters/timespan/form/FormNew.vue +262 -262
  41. package/components/common/context/Context.vue +111 -111
  42. package/components/common/context/recursion/RecursionOld.vue +228 -228
  43. package/components/common/details/DetailsItem.vue +109 -109
  44. package/components/common/feedback/Buttons.vue +229 -229
  45. package/components/common/feedback/Feedback.vue +270 -270
  46. package/components/common/feedback/Message.vue +519 -519
  47. package/components/common/graph/graphNew/GraphNew.vue +194 -194
  48. package/components/common/graph/lib/utils/renderGraph.ts +389 -389
  49. package/components/common/layout/theHeader/feedback/new/New.vue +227 -227
  50. package/components/common/layout/theHeader/feedback/new/additionalDetails/AdditionalDetails.vue +606 -606
  51. package/components/common/layout/theHeader/feedback/new/additionalDetails/Headline.vue +98 -98
  52. package/components/common/layout/theHeader/feedback/new/description/Description.vue +59 -59
  53. package/components/common/layout/theHeader/feedback/new/email/Email.vue +43 -43
  54. package/components/common/layout/theHeader/feedback/new/subtitle/Subtitle.vue +103 -103
  55. package/components/common/layout/theHeader/helpMenu/aboutNew/AboutNew.vue +112 -112
  56. package/components/common/layout/theHeader/helpMenu/aboutOld/AboutOld.vue +80 -80
  57. package/components/common/layout/theHeader/helpMenu/helpMenuOld/HelpMenuOld.vue +1 -1
  58. package/components/common/layout/theHeader/modals/Reconnect.vue +2 -2
  59. package/components/common/layout/theHeader/modals/RedirectLogin.vue +3 -3
  60. package/components/common/layout/theHeader/userMenu/modals/changePassword/ChangePassword.vue +1 -1
  61. package/components/common/layout/theHeader/userMenu/modals/changePassword/ChangePasswordNew.vue +8 -8
  62. package/components/common/layout/theHeader/userMenu/modals/changePassword/ChangePasswordOld.vue +3 -3
  63. package/components/common/layout/theHeader/userMenu/modals/preferences/PreferencesNew.vue +1 -1
  64. package/components/common/layout/theHeader/userMenu/modals/preferences/PreferencesOld.vue +1 -1
  65. package/components/common/layout/theHeader/userMenu/modals/preferences/changeLanguage/ChangeLanguage.vue +1 -1
  66. package/components/common/layout/theHeader/userMenu/modals/preferences/changeLanguage/ChangeLanguageNew.vue +1 -1
  67. package/components/common/layout/theHeader/userMenu/modals/preferences/changeLanguage/ChangeLanguageOld.vue +2 -5
  68. package/components/common/layout/theHeader/userMenu/modals/preferences/defaultConsole/DefaultConsoleOld.vue +1 -1
  69. package/components/common/layout/theHeader/userMenu/modals/preferences/inventory/InventoryNew.vue +1 -1
  70. package/components/common/layout/theHeader/userMenu/userMenuNew/UserMenuNew.vue +2 -2
  71. package/components/common/layout/theHeader/userMenu/userMenuNew/lib/config/dropMenu.ts +1 -1
  72. package/components/common/layout/theHeader/userMenu/userMenuOld/UserMenuOld.vue +1 -1
  73. package/components/common/mainNavigationPanel/MainNavigationPanelOld.vue +2 -2
  74. package/components/common/modals/Rename.vue +2 -2
  75. package/components/common/modals/confirmByInput/ConfirmByInput.vue +2 -3
  76. package/components/common/modals/confirmByInput/ConfirmByInputOld.vue +3 -3
  77. package/components/common/modals/confirmation/ConfirmationOld.vue +1 -1
  78. package/components/common/modals/unsavedChanges/UnsavedChanges.vue +1 -1
  79. package/components/common/monitor/advanced/Advanced.vue +1 -1
  80. package/components/common/monitor/advanced/AdvancedNew.vue +1 -1
  81. package/components/common/monitor/advanced/AdvancedOld.vue +1 -1
  82. package/components/common/monitor/advanced/graphView/GraphViewNew.vue +1 -1
  83. package/components/common/monitor/advanced/graphView/GraphViewOld.vue +1 -1
  84. package/components/common/monitor/advanced/table/Table.vue +1 -1
  85. package/components/common/monitor/advanced/table/tableNew/TableNew.vue +2 -2
  86. package/components/common/monitor/advanced/table/tableOld/lib/config/performanceDatatable.ts +2 -2
  87. package/components/common/monitor/advanced/tools/ToolsOld.vue +2 -2
  88. package/components/common/monitor/advanced/tools/chartOptionsModal/ChartOptionsModalOld.vue +1 -1
  89. package/components/common/monitor/advanced/tools/chartOptionsModal/NotificationOld.vue +1 -1
  90. package/components/common/monitor/advanced/tools/chartOptionsModal/actions/ActionsOld.vue +1 -1
  91. package/components/common/monitor/advanced/tools/chartOptionsModal/actions/saveOptionsModal/SaveOptionsModal.vue +1 -1
  92. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/CountersNew.vue +1 -1
  93. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/table/tableOld/lib/config/tableConfig.ts +2 -2
  94. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/object/lib/config/objectTable.ts +10 -3
  95. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/object/objectNew/ObjectNew.vue +1 -1
  96. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/object/objectOld/ObjectOld.vue +2 -2
  97. package/components/common/monitor/advanced/tools/lib/utils/countCores.ts +1 -1
  98. package/components/common/monitor/lib/models/interfaces.ts +1 -1
  99. package/components/common/monitor/overview/filters/customIntervalModal/CustomIntervalModalOld.vue +3 -3
  100. package/components/common/monitor/overview/filters/customIntervalModal/customIntervalModalNew/CustomIntervalModalNew.vue +4 -3
  101. package/components/common/monitor/resourceAllocation/lib/models/interfaces.ts +8 -8
  102. package/components/common/monitor/resourceAllocation/resourceAllocation.vue +2 -2
  103. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/ChartOptionsModal.vue +1 -1
  104. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/Notification.vue +1 -1
  105. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/actions/SaveOptionsModal.vue +1 -1
  106. package/components/common/pages/hardwareHealth/tableView/lib/config/alertWarningTable.ts +1 -1
  107. package/components/common/pages/hardwareHealth/tableView/lib/config/historyTestimonyTable.ts +5 -5
  108. package/components/common/wizards/vm/migrate/Migrate.vue +39 -2
  109. package/components/common/wizards/vm/migrate/vmOrigin/VmOrigin.vue +92 -0
  110. package/components/common/wizards/vm/migrate/vmOrigin/lib/models/interfaces.ts +19 -0
  111. package/components/common/wizards/vm/migrate/vmOrigin/lib/utils/constructItems.ts +62 -0
  112. package/package.json +1 -1
@@ -1,362 +1,361 @@
1
- <template>
2
- <div class="autocomplete" @click.stop>
3
- <div class="content-search">
4
- <div v-show="props.loading" class="loader">
5
- <atoms-loader-pre-loader
6
- :show="true"
7
- :test-id="`${props.testId}-pre-loader`"
8
- id="loader"
9
- class="content-area__loading"
10
- />
11
- </div>
12
- <div class="search-icon">
13
- <atoms-the-icon
14
- stroke-width="10"
15
- class="alert-icon search-icon"
16
- name="search"
17
- />
18
- </div>
19
-
20
- <div class="clr-error">
21
- <div class="form-group__input">
22
- <input
23
- v-model.trim="searchLocal"
24
- :id="`${props.testId}-search-input`"
25
- :data-id="`${props.testId}-search-input`"
26
- :class="fieldErrorText && 'clr-input'"
27
- :placeholder="props.placeholder"
28
- type="text"
29
- class="search-input"
30
- autocomplete="off"
31
- @blur="onInitValidation"
32
- @input="onSearch"
33
- />
34
- <div v-show="fieldErrorText" class="form-validate">
35
- <atoms-the-icon class="is-error tooltip-trigger" name="info" />
36
- </div>
37
- </div>
38
- <div
39
- v-show="fieldErrorText"
40
- class="form-group__input-error clr-subtext"
41
- >
42
- {{ fieldErrorText }}
43
- </div>
44
- </div>
45
- </div>
46
- <div
47
- v-show="isShow"
48
- :class="['content-filtered', { active: items.length }]"
49
- >
50
- <ul class="dropdown-menu filtered-items">
51
- <li
52
- v-for="(item, key) in itemsLocal"
53
- :key="`${item}_${key}`"
54
- :class="['item', { active: key === selectedTabIndex }]"
55
- :data-id="item.testId"
56
- @mouseenter="selectedTabIndex = key"
57
- @click="onSelect(key)"
58
- >
59
- <template v-for="(part, i) in item.parts" :key="i">
60
- <span v-if="part.highlight" class="highlight">{{ part.text }}</span>
61
- <span v-else>{{ part.text }}</span>
62
- </template>
63
- <!-- {{ item.firstText }}<b>{{ item.secondText }}</b-->
64
- <!-- >{{ item.thirdText }}-->
65
- </li>
66
- </ul>
67
- </div>
68
- </div>
69
- </template>
70
-
71
- <script setup lang="ts">
72
- // import type { UI_I_Localization } from '~/lib/models/interfaces'
73
-
74
- const props = withDefaults(
75
- defineProps<{
76
- placeholder: string
77
- items: string[]
78
- loading?: boolean
79
- testId?: string
80
- ms?: number
81
- showValidation?: boolean
82
- errorText?: string
83
- }>(),
84
- {
85
- testId: 'ui-autocomplete',
86
- ms: 500,
87
- loading: false,
88
- showValidation: false,
89
- errorText: '',
90
- }
91
- )
92
- const emits = defineEmits<{
93
- // (event: 'search', value: string): void
94
- (event: 'select', value: string): void
95
- }>()
96
-
97
- // const localization = computed<UI_I_Localization>(() => useLocal())
98
-
99
- const searchLocal = defineModel<string>()
100
-
101
- // let timer: NodeJS.Timeout
102
- const onSearch = (): void => {
103
- // onInitValidation()
104
- // clearTimeout(timer)
105
- // timer = setTimeout(
106
- // (value) => {
107
- // emits('search', value)
108
- // },
109
- // props.ms,
110
- // )
111
- selectedTabIndex.value = 0
112
- }
113
- const isInitFieldValidation = ref<boolean>(false)
114
- const onInitValidation = (): void => {
115
- isInitFieldValidation.value = true
116
- }
117
- const fieldErrorText = computed<string>(() => {
118
- if (!isInitFieldValidation.value) return ''
119
- // if (!searchLocal.value) return localization.value.common.fieldRequired
120
- else if (props.showValidation) return props.errorText
121
- })
122
- const itemsLocal = computed<any[]>(() => {
123
- const search = searchLocal.value
124
- const regex = new RegExp(search, 'gi')
125
-
126
- return [...props.items].map((text) => {
127
- const parts: { text: string; highlight: boolean }[] = []
128
-
129
- let lastIndex = 0
130
- for (const match of text.matchAll(regex)) {
131
- const index = match.index!
132
- if (index > lastIndex) {
133
- parts.push({ text: text.slice(lastIndex, index), highlight: false })
134
- }
135
- parts.push({ text: match[0], highlight: true })
136
- lastIndex = index + match[0].length
137
- }
138
-
139
- // Остаток строки
140
- if (lastIndex < text.length) {
141
- parts.push({ text: text.slice(lastIndex), highlight: false })
142
- }
143
-
144
- return {
145
- parts,
146
- testId: `${search}-filtered-item`,
147
- }
148
- })
149
- })
150
-
151
- // const itemsLocal = computed<any[]>(() => {
152
- // return [...props.items].map((text) => {
153
- // const termMatch = text.match(new RegExp(searchLocal.value, 'i'))
154
- // const term = termMatch?.[0]
155
- //
156
- // // const term = text.match(new RegExp(searchLocal.value, 'i'))?.[0]
157
- // // const texts = term ? text.split(term) : text
158
- //
159
- // const index = text.toLowerCase().indexOf(term.toLowerCase())
160
- // const firstText = text.slice(0, index)
161
- // const secondText = text.slice(index, index + term.length)
162
- // const thirdText = text.slice(index + term.length)
163
- //
164
- // // console.log(texts, 'Mаrilyne.Sipes87@locаl')
165
- //
166
- // return {
167
- // firstText,
168
- // secondText,
169
- // thirdText,
170
- // testId: `${term}-filtered-item`,
171
- // }
172
- // })
173
- // })
174
-
175
- const selectedTabIndex = ref<number>(0)
176
- const onSelect = (key: number): void => {
177
- // searchLocal.value = props.items[key]
178
- emits('select', props.items[key])
179
- isHide.value = true
180
- }
181
-
182
- const isHide = ref<boolean>(false)
183
- const isShow = computed<boolean>(() => !isHide.value)
184
-
185
- const onKeyDown = (event: KeyboardEvent): void => {
186
- switch (event.code) {
187
- case 'ArrowUp':
188
- prevTabItem()
189
- break
190
- case 'ArrowDown':
191
- nextTabItem()
192
- break
193
- case 'Enter':
194
- event.preventDefault()
195
- onSelect(selectedTabIndex.value)
196
- break
197
- case 'Tab':
198
- isHide.value = true
199
- break
200
- }
201
- }
202
-
203
- const nextTabItem = (): void => {
204
- if (selectedTabIndex.value === itemsLocal.value.length - 1)
205
- selectedTabIndex.value = 0
206
- else selectedTabIndex.value++
207
- }
208
-
209
- const prevTabItem = (): void => {
210
- if (selectedTabIndex.value === 0)
211
- selectedTabIndex.value = itemsLocal.value.length - 1
212
- else selectedTabIndex.value--
213
- }
214
-
215
- watch(
216
- () => props.items,
217
- (newValue) => {
218
- if (newValue.length > 1) {
219
- isHide.value = false
220
- }
221
- }
222
- )
223
- window.addEventListener('keydown', onKeyDown, true)
224
- watch(isHide, (newValue) => {
225
- if (!newValue) {
226
- window.addEventListener('keydown', onKeyDown, true)
227
- } else {
228
- window.removeEventListener('keydown', onKeyDown, true)
229
- }
230
- })
231
- watch(
232
- () => props.showValidation,
233
- (newValue: boolean) => {
234
- isInitFieldValidation.value = newValue
235
- },
236
- { immediate: true }
237
- )
238
- </script>
239
-
240
- <style scoped lang="scss">
241
- .autocomplete {
242
- max-width: 180px;
243
- position: relative;
244
-
245
- .content-search {
246
- .loader {
247
- position: absolute;
248
- top: 3px;
249
- left: -6px;
250
- z-index: var(--z-dropdown);
251
- height: 16px;
252
- width: 16px;
253
-
254
- #loader {
255
- height: 100%;
256
- width: 100%;
257
-
258
- :deep(.spinner-inverse) {
259
- min-width: auto;
260
- min-height: auto;
261
- width: 100%;
262
- height: 100%;
263
- }
264
- }
265
- }
266
- .search-icon {
267
- position: absolute;
268
- width: 17px;
269
- height: 17px;
270
- top: 5px;
271
- bottom: 0;
272
-
273
- .alert-icon.search-icon {
274
- fill: #666;
275
- }
276
- }
277
- .search-input {
278
- background-color: var(--modal-bg-color);
279
- padding: 0 6px 0 20px;
280
- }
281
- }
282
-
283
- .content-filtered {
284
- position: absolute;
285
- display: block;
286
- overflow-y: visible;
287
- height: auto;
288
- visibility: visible;
289
- will-change: transform;
290
- top: 0;
291
- left: 0;
292
- transform: translate3d(0px, 25px, 0px);
293
- width: 250px;
294
- z-index: var(--z-dropdown);
295
-
296
- &.active .filtered-items {
297
- max-height: 110px;
298
- visibility: visible;
299
- position: absolute;
300
- top: 100%;
301
- left: 0;
302
- min-width: 96px;
303
- max-width: 288px;
304
- border: 0.8px solid #ccc;
305
- padding: 9.6px 0;
306
- z-index: calc(var(--z-dropdown) + 1);
307
- overflow: auto;
308
- width: 100%;
309
- margin: 1px 0 0;
310
- background: var(--modal-bg-color);
311
-
312
- .item {
313
- line-height: 20px;
314
- padding: 5px 0 0 5px;
315
- color: #333;
316
- cursor: pointer;
317
- outline: unset;
318
-
319
- &.active,
320
- &:focus,
321
- &:hover {
322
- background-color: #2b5480;
323
- color: #fff;
324
- }
325
-
326
- .highlight {
327
- font-weight: bold;
328
- }
329
- }
330
- }
331
- }
332
- .form-group {
333
- &__input {
334
- display: flex;
335
- .form-validate {
336
- svg {
337
- width: 24px;
338
- height: 24px;
339
- }
340
- }
341
- input {
342
- width: 100%;
343
- }
344
- &-error {
345
- margin-top: 0;
346
- }
347
- }
348
- }
349
- }
350
- :root.dark-theme {
351
- .autocomplete .content-search .search-icon .alert-icon.search-icon {
352
- fill: #adbbc4;
353
- }
354
-
355
- .autocomplete .content-filtered.active .filtered-items {
356
- border: 0.8px solid #666;
357
- .item {
358
- color: #aaa;
359
- }
360
- }
361
- }
362
- </style>
1
+ <template>
2
+ <div class="autocomplete" @click.stop>
3
+ <div class="content-search">
4
+ <div v-show="props.loading" class="loader">
5
+ <atoms-loader-pre-loader
6
+ id="loader"
7
+ :test-id="`${props.testId}-pre-loader`"
8
+ :show="true"
9
+ class="content-area__loading"
10
+ />
11
+ </div>
12
+ <div class="search-icon">
13
+ <atoms-the-icon
14
+ stroke-width="10"
15
+ class="alert-icon search-icon"
16
+ name="search"
17
+ />
18
+ </div>
19
+
20
+ <div class="clr-error">
21
+ <div class="form-group__input">
22
+ <input
23
+ :id="`${props.testId}-search-input`"
24
+ v-model.trim="searchLocal"
25
+ :data-id="`${props.testId}-search-input`"
26
+ :class="['search-input', fieldErrorText && 'clr-input']"
27
+ :placeholder="props.placeholder"
28
+ type="text"
29
+ autocomplete="off"
30
+ @blur="onInitValidation"
31
+ @input="onSearch"
32
+ />
33
+ <div v-show="fieldErrorText" class="form-validate">
34
+ <atoms-the-icon class="is-error tooltip-trigger" name="info" />
35
+ </div>
36
+ </div>
37
+ <div
38
+ v-show="fieldErrorText"
39
+ class="form-group__input-error clr-subtext"
40
+ >
41
+ {{ fieldErrorText }}
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <div
46
+ v-show="isShow"
47
+ :class="['content-filtered', { active: items.length }]"
48
+ >
49
+ <ul class="dropdown-menu filtered-items">
50
+ <li
51
+ v-for="(item, key) in itemsLocal"
52
+ :key="`${item}_${key}`"
53
+ :class="['item', { active: key === selectedTabIndex }]"
54
+ :data-id="item.testId"
55
+ @mouseenter="selectedTabIndex = key"
56
+ @click="onSelect(key)"
57
+ >
58
+ <template v-for="(part, i) in item.parts" :key="i">
59
+ <span v-if="part.highlight" class="highlight">{{ part.text }}</span>
60
+ <span v-else>{{ part.text }}</span>
61
+ </template>
62
+ <!-- {{ item.firstText }}<b>{{ item.secondText }}</b-->
63
+ <!-- >{{ item.thirdText }}-->
64
+ </li>
65
+ </ul>
66
+ </div>
67
+ </div>
68
+ </template>
69
+
70
+ <script setup lang="ts">
71
+ // import type { UI_I_Localization } from '~/lib/models/interfaces'
72
+
73
+ const props = withDefaults(
74
+ defineProps<{
75
+ placeholder: string
76
+ items: string[]
77
+ loading?: boolean
78
+ testId?: string
79
+ ms?: number
80
+ showValidation?: boolean
81
+ errorText?: string
82
+ }>(),
83
+ {
84
+ testId: 'ui-autocomplete',
85
+ ms: 500,
86
+ loading: false,
87
+ showValidation: false,
88
+ errorText: '',
89
+ }
90
+ )
91
+ const emits = defineEmits<{
92
+ // (event: 'search', value: string): void
93
+ (event: 'select', value: string): void
94
+ }>()
95
+
96
+ // const localization = computed<UI_I_Localization>(() => useLocal())
97
+
98
+ const searchLocal = defineModel<string>()
99
+
100
+ // let timer: NodeJS.Timeout
101
+ const onSearch = (): void => {
102
+ // onInitValidation()
103
+ // clearTimeout(timer)
104
+ // timer = setTimeout(
105
+ // (value) => {
106
+ // emits('search', value)
107
+ // },
108
+ // props.ms,
109
+ // )
110
+ selectedTabIndex.value = 0
111
+ }
112
+ const isInitFieldValidation = ref<boolean>(false)
113
+ const onInitValidation = (): void => {
114
+ isInitFieldValidation.value = true
115
+ }
116
+ const fieldErrorText = computed<string>(() => {
117
+ if (!isInitFieldValidation.value) return ''
118
+ // if (!searchLocal.value) return localization.value.common.fieldRequired
119
+ else if (props.showValidation) return props.errorText
120
+ })
121
+ const itemsLocal = computed<any[]>(() => {
122
+ const search = searchLocal.value
123
+ const regex = new RegExp(search, 'gi')
124
+
125
+ return [...props.items].map((text) => {
126
+ const parts: { text: string; highlight: boolean }[] = []
127
+
128
+ let lastIndex = 0
129
+ for (const match of text.matchAll(regex)) {
130
+ const index = match.index!
131
+ if (index > lastIndex) {
132
+ parts.push({ text: text.slice(lastIndex, index), highlight: false })
133
+ }
134
+ parts.push({ text: match[0], highlight: true })
135
+ lastIndex = index + match[0].length
136
+ }
137
+
138
+ // Остаток строки
139
+ if (lastIndex < text.length) {
140
+ parts.push({ text: text.slice(lastIndex), highlight: false })
141
+ }
142
+
143
+ return {
144
+ parts,
145
+ testId: `${search}-filtered-item`,
146
+ }
147
+ })
148
+ })
149
+
150
+ // const itemsLocal = computed<any[]>(() => {
151
+ // return [...props.items].map((text) => {
152
+ // const termMatch = text.match(new RegExp(searchLocal.value, 'i'))
153
+ // const term = termMatch?.[0]
154
+ //
155
+ // // const term = text.match(new RegExp(searchLocal.value, 'i'))?.[0]
156
+ // // const texts = term ? text.split(term) : text
157
+ //
158
+ // const index = text.toLowerCase().indexOf(term.toLowerCase())
159
+ // const firstText = text.slice(0, index)
160
+ // const secondText = text.slice(index, index + term.length)
161
+ // const thirdText = text.slice(index + term.length)
162
+ //
163
+ // // console.log(texts, 'Mаrilyne.Sipes87@locаl')
164
+ //
165
+ // return {
166
+ // firstText,
167
+ // secondText,
168
+ // thirdText,
169
+ // testId: `${term}-filtered-item`,
170
+ // }
171
+ // })
172
+ // })
173
+
174
+ const selectedTabIndex = ref<number>(0)
175
+ const onSelect = (key: number): void => {
176
+ // searchLocal.value = props.items[key]
177
+ emits('select', props.items[key])
178
+ isHide.value = true
179
+ }
180
+
181
+ const isHide = ref<boolean>(false)
182
+ const isShow = computed<boolean>(() => !isHide.value)
183
+
184
+ const onKeyDown = (event: KeyboardEvent): void => {
185
+ switch (event.code) {
186
+ case 'ArrowUp':
187
+ prevTabItem()
188
+ break
189
+ case 'ArrowDown':
190
+ nextTabItem()
191
+ break
192
+ case 'Enter':
193
+ event.preventDefault()
194
+ onSelect(selectedTabIndex.value)
195
+ break
196
+ case 'Tab':
197
+ isHide.value = true
198
+ break
199
+ }
200
+ }
201
+
202
+ const nextTabItem = (): void => {
203
+ if (selectedTabIndex.value === itemsLocal.value.length - 1)
204
+ selectedTabIndex.value = 0
205
+ else selectedTabIndex.value++
206
+ }
207
+
208
+ const prevTabItem = (): void => {
209
+ if (selectedTabIndex.value === 0)
210
+ selectedTabIndex.value = itemsLocal.value.length - 1
211
+ else selectedTabIndex.value--
212
+ }
213
+
214
+ watch(
215
+ () => props.items,
216
+ (newValue) => {
217
+ if (newValue.length > 1) {
218
+ isHide.value = false
219
+ }
220
+ }
221
+ )
222
+ window.addEventListener('keydown', onKeyDown, true)
223
+ watch(isHide, (newValue) => {
224
+ if (!newValue) {
225
+ window.addEventListener('keydown', onKeyDown, true)
226
+ } else {
227
+ window.removeEventListener('keydown', onKeyDown, true)
228
+ }
229
+ })
230
+ watch(
231
+ () => props.showValidation,
232
+ (newValue: boolean) => {
233
+ isInitFieldValidation.value = newValue
234
+ },
235
+ { immediate: true }
236
+ )
237
+ </script>
238
+
239
+ <style scoped lang="scss">
240
+ .autocomplete {
241
+ max-width: 180px;
242
+ position: relative;
243
+
244
+ .content-search {
245
+ .loader {
246
+ position: absolute;
247
+ top: 3px;
248
+ left: -6px;
249
+ z-index: var(--z-dropdown);
250
+ height: 16px;
251
+ width: 16px;
252
+
253
+ #loader {
254
+ height: 100%;
255
+ width: 100%;
256
+
257
+ :deep(.spinner-inverse) {
258
+ min-width: auto;
259
+ min-height: auto;
260
+ width: 100%;
261
+ height: 100%;
262
+ }
263
+ }
264
+ }
265
+ .search-icon {
266
+ position: absolute;
267
+ width: 17px;
268
+ height: 17px;
269
+ top: 5px;
270
+ bottom: 0;
271
+
272
+ .alert-icon.search-icon {
273
+ fill: #666;
274
+ }
275
+ }
276
+ .search-input {
277
+ background-color: var(--modal-bg-color);
278
+ padding: 0 6px 0 20px;
279
+ }
280
+ }
281
+
282
+ .content-filtered {
283
+ position: absolute;
284
+ display: block;
285
+ overflow-y: visible;
286
+ height: auto;
287
+ visibility: visible;
288
+ will-change: transform;
289
+ top: 0;
290
+ left: 0;
291
+ transform: translate3d(0px, 25px, 0px);
292
+ width: 250px;
293
+ z-index: var(--z-dropdown);
294
+
295
+ &.active .filtered-items {
296
+ max-height: 110px;
297
+ visibility: visible;
298
+ position: absolute;
299
+ top: 100%;
300
+ left: 0;
301
+ min-width: 96px;
302
+ max-width: 288px;
303
+ border: 0.8px solid #ccc;
304
+ padding: 9.6px 0;
305
+ z-index: calc(var(--z-dropdown) + 1);
306
+ overflow: auto;
307
+ width: 100%;
308
+ margin: 1px 0 0;
309
+ background: var(--modal-bg-color);
310
+
311
+ .item {
312
+ line-height: 20px;
313
+ padding: 5px 0 0 5px;
314
+ color: #333;
315
+ cursor: pointer;
316
+ outline: unset;
317
+
318
+ &.active,
319
+ &:focus,
320
+ &:hover {
321
+ background-color: #2b5480;
322
+ color: #fff;
323
+ }
324
+
325
+ .highlight {
326
+ font-weight: bold;
327
+ }
328
+ }
329
+ }
330
+ }
331
+ .form-group {
332
+ &__input {
333
+ display: flex;
334
+ .form-validate {
335
+ svg {
336
+ width: 24px;
337
+ height: 24px;
338
+ }
339
+ }
340
+ input {
341
+ width: 100%;
342
+ }
343
+ &-error {
344
+ margin-top: 0;
345
+ }
346
+ }
347
+ }
348
+ }
349
+ :root.dark-theme {
350
+ .autocomplete .content-search .search-icon .alert-icon.search-icon {
351
+ fill: #adbbc4;
352
+ }
353
+
354
+ .autocomplete .content-filtered.active .filtered-items {
355
+ border: 0.8px solid #666;
356
+ .item {
357
+ color: #aaa;
358
+ }
359
+ }
360
+ }
361
+ </style>