bfg-common 1.4.175 → 1.4.177
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.
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="combo-dropdown-content">
|
|
3
|
+
<div class="ng-star-inserted">
|
|
4
|
+
<div class="ng-pristine ng-invalid ng-touched">
|
|
5
|
+
<div
|
|
6
|
+
:class="['alarm-trigger-combo-box dropdown', { open: isShowList }]"
|
|
7
|
+
@mouseenter="isHover = true"
|
|
8
|
+
@mouseleave="isHover = false"
|
|
9
|
+
>
|
|
10
|
+
<div
|
|
11
|
+
class="select dropdown-toggle"
|
|
12
|
+
aria-haspopup="menu"
|
|
13
|
+
aria-expanded="false"
|
|
14
|
+
>
|
|
15
|
+
<input
|
|
16
|
+
v-model="modelValue"
|
|
17
|
+
:placeholder="localization.inventoryConfigure.selectTrigger"
|
|
18
|
+
:data-id="`${props.testId}-selected-field`"
|
|
19
|
+
type="text"
|
|
20
|
+
class="form-control dropdown-host"
|
|
21
|
+
@click="isShowList = !isShowList"
|
|
22
|
+
/>
|
|
23
|
+
</div>
|
|
24
|
+
<div
|
|
25
|
+
v-if="isShowList"
|
|
26
|
+
class="combo-dropdown-menu dropdown-menu ng-star-inserted"
|
|
27
|
+
tabindex="0"
|
|
28
|
+
role="menu"
|
|
29
|
+
>
|
|
30
|
+
<input
|
|
31
|
+
id="search-input"
|
|
32
|
+
v-model="search"
|
|
33
|
+
type="search"
|
|
34
|
+
autocomplete="off"
|
|
35
|
+
maxlength="300"
|
|
36
|
+
class="form-control dropdown-search-box ng-pristine ng-valid ng-touched"
|
|
37
|
+
placeholder="Search"
|
|
38
|
+
/>
|
|
39
|
+
<div class="dropdown-result-holder ng-star-inserted">
|
|
40
|
+
<div
|
|
41
|
+
tabindex="0"
|
|
42
|
+
role="tree"
|
|
43
|
+
aria-multiselectable="false"
|
|
44
|
+
class="ng-star-inserted"
|
|
45
|
+
>
|
|
46
|
+
<div
|
|
47
|
+
v-for="(item, key) in filteredData"
|
|
48
|
+
:key="key"
|
|
49
|
+
:data-id="item.title"
|
|
50
|
+
:class="[
|
|
51
|
+
'clr-tree-node ng-star-inserted item-row dropdown-parent-item',
|
|
52
|
+
{ open: arrowKeys[key] },
|
|
53
|
+
{ searched: isSearched },
|
|
54
|
+
]"
|
|
55
|
+
role="treeitem"
|
|
56
|
+
>
|
|
57
|
+
<div
|
|
58
|
+
v-if="!isSearched"
|
|
59
|
+
role="treeitem"
|
|
60
|
+
tabindex="-1"
|
|
61
|
+
class="clr-tree-node-content-container"
|
|
62
|
+
aria-expanded="true"
|
|
63
|
+
>
|
|
64
|
+
<button
|
|
65
|
+
:data-id="`${item.testId}-toggle-button`"
|
|
66
|
+
aria-hidden="true"
|
|
67
|
+
type="button"
|
|
68
|
+
tabindex="-1"
|
|
69
|
+
class="clr-treenode-caret ng-star-inserted"
|
|
70
|
+
@click="arrowKeys[key] = !arrowKeys[key]"
|
|
71
|
+
>
|
|
72
|
+
<atoms-the-icon
|
|
73
|
+
:class="[
|
|
74
|
+
'trigger-icon clr-icon',
|
|
75
|
+
{ open: arrowKeys[key] },
|
|
76
|
+
]"
|
|
77
|
+
name="angle"
|
|
78
|
+
/>
|
|
79
|
+
</button>
|
|
80
|
+
<div class="clr-treenode-content item-title-content">
|
|
81
|
+
<b
|
|
82
|
+
:title="`${item.title} (${item.itemsCount})`"
|
|
83
|
+
class="dropdown-item-text category-name"
|
|
84
|
+
>
|
|
85
|
+
{{ item.title }} </b
|
|
86
|
+
><b
|
|
87
|
+
:title="`${item.title} (${item.itemsCount})`"
|
|
88
|
+
class="dropdown-item-text category-size"
|
|
89
|
+
>
|
|
90
|
+
({{ item.itemsCount }})</b
|
|
91
|
+
>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
<div
|
|
95
|
+
:class="[
|
|
96
|
+
'clr-treenode-children ng-trigger ng-trigger-toggleChildrenAnim children-content',
|
|
97
|
+
{ open: arrowKeys[key] },
|
|
98
|
+
]"
|
|
99
|
+
role="group"
|
|
100
|
+
>
|
|
101
|
+
<div
|
|
102
|
+
v-for="(item2, key2) in item.childs"
|
|
103
|
+
:key="key2"
|
|
104
|
+
:data-id="item2.testId"
|
|
105
|
+
class="clr-tree-node ng-star-inserted"
|
|
106
|
+
role="treeitem"
|
|
107
|
+
@click="onSelect(item2.title)"
|
|
108
|
+
>
|
|
109
|
+
<div
|
|
110
|
+
role="treeitem"
|
|
111
|
+
tabindex="-1"
|
|
112
|
+
class="clr-tree-node-content-container"
|
|
113
|
+
>
|
|
114
|
+
<div class="clr-treenode-content item-title-content">
|
|
115
|
+
<button
|
|
116
|
+
:title="item2.title"
|
|
117
|
+
:data-id="item2.title"
|
|
118
|
+
type="button"
|
|
119
|
+
class="btn-link dropdown-child-item"
|
|
120
|
+
tabindex="-1"
|
|
121
|
+
role="menuitem"
|
|
122
|
+
aria-disabled="false"
|
|
123
|
+
>
|
|
124
|
+
<span
|
|
125
|
+
:title="item2.title"
|
|
126
|
+
class="dropdown-item-text"
|
|
127
|
+
>{{ item2.firstText }}<b>{{ item2.secondText }}</b
|
|
128
|
+
>{{ item2.thirdText }}</span
|
|
129
|
+
>
|
|
130
|
+
</button>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</template>
|
|
144
|
+
|
|
145
|
+
<script setup lang="ts">
|
|
146
|
+
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
147
|
+
import type {
|
|
148
|
+
UI_I_ComboDropdown,
|
|
149
|
+
UI_I_ComboDropdownSearched,
|
|
150
|
+
UI_I_ComboDropdownSearchedItem,
|
|
151
|
+
} from '~/components/atoms/comboDropdownMenu/lib/models/interfaces'
|
|
152
|
+
|
|
153
|
+
const props = defineProps<{
|
|
154
|
+
exportData: UI_I_ComboDropdown[]
|
|
155
|
+
testId: string
|
|
156
|
+
}>()
|
|
157
|
+
const modelValue = defineModel<string>()
|
|
158
|
+
const emits = defineEmits<{
|
|
159
|
+
(event: 'select', value: string): void
|
|
160
|
+
}>()
|
|
161
|
+
|
|
162
|
+
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
163
|
+
|
|
164
|
+
const search = ref<string>('')
|
|
165
|
+
const isSearched = computed<boolean>(() => modelValue.value !== search.value)
|
|
166
|
+
|
|
167
|
+
const constructChildesBySearch = (
|
|
168
|
+
data: string[]
|
|
169
|
+
): UI_I_ComboDropdownSearchedItem[] => {
|
|
170
|
+
if (!isSearched.value)
|
|
171
|
+
return data.map((item) => {
|
|
172
|
+
return {
|
|
173
|
+
title: item,
|
|
174
|
+
firstText: item,
|
|
175
|
+
secondText: '',
|
|
176
|
+
thirdText: '',
|
|
177
|
+
testId: `${item}-child`,
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
const searchLower = search.value.toLowerCase()
|
|
182
|
+
const searchLength = searchLower.length
|
|
183
|
+
const result: UI_I_ComboDropdownSearchedItem[] = []
|
|
184
|
+
data.forEach((item) => {
|
|
185
|
+
const showTextLower = item.toLowerCase()
|
|
186
|
+
const showText = item
|
|
187
|
+
if (showTextLower.includes(searchLower)) {
|
|
188
|
+
const getIndex = showTextLower.indexOf(searchLower)
|
|
189
|
+
|
|
190
|
+
const newValue = {
|
|
191
|
+
title: item,
|
|
192
|
+
firstText: showText.slice(0, getIndex),
|
|
193
|
+
secondText: showText.slice(getIndex, getIndex + searchLength),
|
|
194
|
+
thirdText: showText.slice(getIndex + searchLength, showText.length),
|
|
195
|
+
testId: `${item}-child`,
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
result.push(newValue)
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
return result
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const filteredData = computed<UI_I_ComboDropdownSearched[]>(() => {
|
|
205
|
+
return [...props.exportData].map((item) => {
|
|
206
|
+
return {
|
|
207
|
+
title: item.title,
|
|
208
|
+
itemsCount: item.itemsCount,
|
|
209
|
+
childs: constructChildesBySearch(item.childs),
|
|
210
|
+
testId: item.testId,
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
const arrowKeys = ref<boolean[]>([])
|
|
216
|
+
watch(
|
|
217
|
+
() => props.exportData,
|
|
218
|
+
(newValue) => {
|
|
219
|
+
if (!newValue.length) return
|
|
220
|
+
|
|
221
|
+
newValue.forEach((_, key) => {
|
|
222
|
+
const currentValue = key === 0
|
|
223
|
+
arrowKeys.value.push(currentValue)
|
|
224
|
+
})
|
|
225
|
+
},
|
|
226
|
+
{ immediate: true, deep: true }
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
const isShowList = ref<boolean>(false)
|
|
230
|
+
watch(isShowList, (newValue) => {
|
|
231
|
+
if (!newValue) return
|
|
232
|
+
|
|
233
|
+
setTimeout(() => {
|
|
234
|
+
document.getElementById('search-input')?.focus()
|
|
235
|
+
}, 0)
|
|
236
|
+
modelValue.value && (search.value = modelValue.value)
|
|
237
|
+
})
|
|
238
|
+
const isHover = ref<boolean>(false)
|
|
239
|
+
|
|
240
|
+
const hideMenu = (force?: boolean): void => {
|
|
241
|
+
if (isHover.value && !force) return
|
|
242
|
+
|
|
243
|
+
isShowList.value = false
|
|
244
|
+
}
|
|
245
|
+
const windowClick = (): void => {
|
|
246
|
+
hideMenu()
|
|
247
|
+
}
|
|
248
|
+
const windowScroll = (): void => {
|
|
249
|
+
hideMenu()
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const onSelect = (value: string): void => {
|
|
253
|
+
modelValue.value = value
|
|
254
|
+
|
|
255
|
+
emits('select', value)
|
|
256
|
+
hideMenu(true)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
onMounted(() => {
|
|
260
|
+
window.addEventListener('click', windowClick)
|
|
261
|
+
window.addEventListener('scroll', windowScroll, true)
|
|
262
|
+
})
|
|
263
|
+
onUnmounted(() => {
|
|
264
|
+
window.removeEventListener('click', windowClick)
|
|
265
|
+
window.removeEventListener('scroll', windowScroll)
|
|
266
|
+
})
|
|
267
|
+
</script>
|
|
268
|
+
|
|
269
|
+
<style scoped lang="scss">
|
|
270
|
+
.combo-dropdown-content {
|
|
271
|
+
.alarm-trigger-combo-box {
|
|
272
|
+
position: static;
|
|
273
|
+
|
|
274
|
+
.combo-dropdown-menu {
|
|
275
|
+
position: absolute;
|
|
276
|
+
inset: 0 auto auto 0;
|
|
277
|
+
transform: translateX(15px) translateY(24px);
|
|
278
|
+
margin-top: -15px;
|
|
279
|
+
width: 30rem;
|
|
280
|
+
|
|
281
|
+
.dropdown-result-holder {
|
|
282
|
+
padding-top: 10px;
|
|
283
|
+
max-height: 18rem;
|
|
284
|
+
overflow-x: hidden;
|
|
285
|
+
overflow-y: auto;
|
|
286
|
+
|
|
287
|
+
.dropdown-parent-item {
|
|
288
|
+
&.open {
|
|
289
|
+
&.searched {
|
|
290
|
+
.children-content {
|
|
291
|
+
.item-title-content {
|
|
292
|
+
.dropdown-child-item {
|
|
293
|
+
padding-left: 14px;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.trigger-icon {
|
|
300
|
+
transform: rotate(180deg);
|
|
301
|
+
}
|
|
302
|
+
.children-content {
|
|
303
|
+
overflow-y: visible;
|
|
304
|
+
height: auto;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.trigger-icon {
|
|
309
|
+
transform: rotate(90deg);
|
|
310
|
+
}
|
|
311
|
+
.children-content {
|
|
312
|
+
overflow-x: hidden;
|
|
313
|
+
margin-left: 0;
|
|
314
|
+
height: 0;
|
|
315
|
+
overflow-y: visible;
|
|
316
|
+
|
|
317
|
+
.item-title-content {
|
|
318
|
+
&:first-child {
|
|
319
|
+
padding-left: 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.dropdown-child-item {
|
|
323
|
+
padding-left: 28px;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface UI_I_ComboDropdown {
|
|
2
|
+
title: string
|
|
3
|
+
itemsCount: number
|
|
4
|
+
childs: string[]
|
|
5
|
+
testId: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface UI_I_ComboDropdownSearchedItem {
|
|
9
|
+
title: string
|
|
10
|
+
firstText: string
|
|
11
|
+
secondText: string
|
|
12
|
+
thirdText: string
|
|
13
|
+
testId: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface UI_I_ComboDropdownSearched {
|
|
17
|
+
title: string
|
|
18
|
+
itemsCount: number
|
|
19
|
+
childs: UI_I_ComboDropdownSearchedItem[]
|
|
20
|
+
testId: string
|
|
21
|
+
}
|
package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue
CHANGED
|
@@ -92,7 +92,7 @@ watch(
|
|
|
92
92
|
iconClassName: 'icon-disk',
|
|
93
93
|
type: 'disk',
|
|
94
94
|
name: item.source + index,
|
|
95
|
-
testId:
|
|
95
|
+
testId: `select-disk-value-${index + 1}`,
|
|
96
96
|
}
|
|
97
97
|
}) || []
|
|
98
98
|
const cdDvdDrives: UI_I_BootItem[] =
|
|
@@ -105,7 +105,7 @@ watch(
|
|
|
105
105
|
iconClassName: 'icon-disk',
|
|
106
106
|
type: 'cdDvd',
|
|
107
107
|
name: item.source + index,
|
|
108
|
-
testId:
|
|
108
|
+
testId: `select-cd-dvd-value-${index + 1}`,
|
|
109
109
|
}
|
|
110
110
|
}) || []
|
|
111
111
|
const networks: UI_I_BootItem[] =
|
|
@@ -118,7 +118,7 @@ watch(
|
|
|
118
118
|
iconClassName: 'vsphere-icon-network',
|
|
119
119
|
type: 'nic',
|
|
120
120
|
name: item.network + index,
|
|
121
|
-
testId:
|
|
121
|
+
testId: `select-nic-value-${index + 1}`,
|
|
122
122
|
}
|
|
123
123
|
}) || []
|
|
124
124
|
|