bfg-common 1.0.44 → 1.0.45

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 (54) hide show
  1. package/components/atoms/alert/Notification.vue +167 -167
  2. package/components/atoms/autocomplete/Autocomplete.vue +236 -236
  3. package/components/atoms/datepicker/Datepicker.vue +612 -612
  4. package/components/atoms/list/SelectList.vue +62 -62
  5. package/components/atoms/modal/bySteps/BySteps.vue +234 -234
  6. package/components/atoms/nav/NavBar.vue +116 -116
  7. package/components/atoms/nav/VerticalNavBar.vue +89 -89
  8. package/components/atoms/notificationBar/NotificationBar.vue +174 -175
  9. package/components/atoms/perPage/PerPage.vue +52 -52
  10. package/components/atoms/popup/SimplePopup.vue +90 -90
  11. package/components/atoms/step/VerticalStep.vue +104 -104
  12. package/components/atoms/switch/Switch.vue +107 -107
  13. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +204 -204
  14. package/components/atoms/table/dataGrid/DataGridPage.vue +189 -189
  15. package/components/atoms/table/dataGrid/DataGridPagination.vue +83 -83
  16. package/components/atoms/tabs/Tabs.vue +189 -189
  17. package/components/atoms/tooltip/Signpost.vue +224 -224
  18. package/components/common/accordion/Accordion.vue +176 -176
  19. package/components/common/accordion/Recursion.vue +195 -195
  20. package/components/common/adapterManager/AddAdapterWarningModal.vue +82 -82
  21. package/components/common/adapterManager/NoActiveAdaptersModal.vue +62 -62
  22. package/components/common/adapterManager/NoConnectedActiveAdaptersModal.vue +62 -62
  23. package/components/common/browse/Browse.vue +182 -182
  24. package/components/common/browse/blocks/Title.vue +66 -66
  25. package/components/common/diagramMain/adapter/AdapterItem.vue +227 -227
  26. package/components/common/diagramMain/adapter/AdapterItems.vue +57 -57
  27. package/components/common/diagramMain/modals/editSettings/tabs/port/IpvFourSettings.vue +339 -339
  28. package/components/common/diagramMain/modals/editSettings/tabs/port/PortProperties.vue +202 -202
  29. package/components/common/diagramMain/modals/remove/RemoveModal.vue +226 -226
  30. package/components/common/diagramMain/modals/viewSettings/Info.vue +94 -94
  31. package/components/common/diagramMain/network/Contents.vue +238 -238
  32. package/components/common/feedback/Buttons.vue +232 -232
  33. package/components/common/feedback/Message.vue +468 -468
  34. package/components/common/feedback/VisitPortal.vue +54 -54
  35. package/components/common/modals/Rename.vue +165 -165
  36. package/components/common/perPage/PerPage.vue +51 -51
  37. package/components/common/recursionTree/RecursionTree.vue +201 -201
  38. package/components/common/tools/Actions.vue +141 -144
  39. package/components/common/wizards/datastore/add/nfs/configuration/Configuration.vue +373 -373
  40. package/components/common/wizards/datastore/add/nfs/configuration/serversList/ServersList.vue +123 -123
  41. package/components/common/wizards/datastore/add/nfs/kerberosAuthentication/KerberosAuthentication.vue +54 -54
  42. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/HostTable.vue +131 -131
  43. package/components/common/wizards/datastore/add/sharedStorm/partitionConfiguration/PartitionConfiguration.vue +230 -230
  44. package/models/store/storage/interfaces.ts +32 -32
  45. package/package.json +1 -1
  46. package/public/spice-console/application/codec.js +257 -257
  47. package/public/spice-console/lib/rasterEngine.js +907 -907
  48. package/public/spice-console/network/spicechannel.js +369 -369
  49. package/public/spice-console-minify/lib/decoder/dixie.min.js +4 -4
  50. package/public/spice-console-minify/lib/jgestures.min.js +24 -24
  51. package/public/spice-console-minify/lib/jquery-2.0.3.min.js +24 -24
  52. package/public/spice-console-minify/lib/jquery-mousewheel.min.js +11 -11
  53. package/public/spice-console-minify/lib/jquery-visibility.min.js +1 -1
  54. package/public/spice-console-minify/lib/lodash.4.0.0.min.js +5 -5
@@ -1,201 +1,201 @@
1
- <template>
2
- <div class="recursion-tree">
3
- <div v-for="node in nodes" :key="`${node.type}_${node.id}`">
4
- <div
5
- :id="`tree-node-${node.type}-${node.id}`"
6
- class="clr-tree-node"
7
- @click="selectNode(node)"
8
- >
9
- <button
10
- v-if="node.hasNodes"
11
- :id="`tree-node-${node.type}-${node.id}-toggle-button`"
12
- class="clr-treenode-caret"
13
- @click.stop="getNodes({ node })"
14
- >
15
- <i
16
- v-if="loading[`${node.id}_${node.type}`]"
17
- class="fa clr-tree-node-caret-icon spinner spinner-sm"
18
- />
19
- <atoms-the-icon
20
- v-else
21
- :class="['clr-tree-node-caret-icon', { down: node.nodesShow }]"
22
- name="angle"
23
- />
24
- </button>
25
- <div
26
- :class="[
27
- 'tree-node-text-drag',
28
- { 'no-child': !node.hasNodes, 'dark-mode': hasDarkMode },
29
- ]"
30
- @contextmenu="showContextMenuAndSelectNode($event, node)"
31
- >
32
- <div
33
- :class="[
34
- 'clr-treenode-link tree-node-text',
35
- { active: node.isActive },
36
- ]"
37
- >
38
- <span :class="node.iconClassName" />
39
- {{ node.name }}
40
- </div>
41
- </div>
42
- </div>
43
-
44
- <common-recursion-tree
45
- v-if="node.nodesShow && node.nodes.length"
46
- :nodes="node.nodes"
47
- :style="{ 'padding-left': node.nodesShow ? '20px' : '' }"
48
- @get-nodes="getNodes($event)"
49
- @select-node="selectNode($event)"
50
- @contextmenu.prevent
51
- @show-context-menu="showContextMenu"
52
- />
53
- </div>
54
- </div>
55
- </template>
56
-
57
- <script setup lang="ts">
58
- import { UI_I_TreeNode } from '~/components/common/recursionTree/models/interfaces'
59
-
60
- const { $store } = useNuxtApp()
61
-
62
- interface UI_I_Loading {
63
- [key: string]: boolean
64
- }
65
-
66
- const props = defineProps<{
67
- nodes: UI_I_TreeNode[]
68
- }>()
69
- const emits = defineEmits<{
70
- (event: 'get-nodes', value: any): void
71
- (event: 'select-node', value: UI_I_TreeNode): void
72
- (event: 'show-context-menu', value: any): void
73
- }>()
74
-
75
- const loading = ref<UI_I_Loading>({})
76
- watch(props.nodes, (nodes) => {
77
- nodes.forEach((node) => {
78
- loading.value[`${node.id}_${node.type}`] = false
79
- })
80
- })
81
-
82
- const hasDarkMode = computed<boolean>(
83
- () => $store.getters['main/getInterfaceThemeMode'] === 'DARK'
84
- )
85
-
86
- const getNodes = (data: any): void => {
87
- const node: UI_I_TreeNode = data.node
88
- const cb: Function | undefined = data.cb
89
-
90
- loading.value[`${node.id}_${node.type}`] = true
91
- const collBack = () => {
92
- loading.value[`${node.id}_${node.type}`] = false
93
- }
94
- emits('get-nodes', {
95
- node,
96
- cb: cb || collBack,
97
- })
98
- }
99
- const selectNode = (node: UI_I_TreeNode): void => {
100
- emits('select-node', node)
101
- }
102
- const showContextMenu = (event: any, node: UI_I_TreeNode): void => {
103
- // Если данные приходят от потомка, то нужно так обработать, из-за рекурсии
104
- if (event.node && event.event) {
105
- emits('show-context-menu', { ...event })
106
- return
107
- }
108
- emits('show-context-menu', { event, node })
109
- }
110
- const showContextMenuAndSelectNode = (
111
- event: any,
112
- node: UI_I_TreeNode
113
- ): void => {
114
- selectNode(node)
115
-
116
- showContextMenu(event, node)
117
- }
118
- </script>
119
-
120
- <style scoped lang="scss">
121
- .recursion-tree {
122
- .clr-tree-node {
123
- width: 100%;
124
- overflow: hidden;
125
- display: flex;
126
- flex: 1 1 0;
127
- align-items: center;
128
- margin-bottom: 1px;
129
-
130
- .clr-treenode-caret {
131
- outline: none;
132
-
133
- .clr-tree-node-caret-icon {
134
- position: static;
135
- transform: rotate(90deg);
136
- width: 11px;
137
- height: 11px;
138
- fill: var(--tree-node-caret-icon);
139
-
140
- &.down {
141
- transform: rotate(180deg);
142
- }
143
- }
144
- }
145
- .tree-node-text-drag {
146
- width: 100%;
147
- overflow: hidden;
148
- display: flex;
149
- cursor: grab;
150
-
151
- &.no-child {
152
- margin-left: 30px;
153
- }
154
- .tree-node-text {
155
- width: 100%;
156
- box-sizing: border-box;
157
- text-overflow: ellipsis;
158
- overflow: hidden;
159
- white-space: nowrap;
160
- padding: 0;
161
- border-radius: 0;
162
- border-bottom: 1px solid transparent;
163
-
164
- &.active {
165
- background: var(--vertical-nav-active-bg-color);
166
- color: var(--vertical-nav-active-item-color);
167
- border-bottom: 1px solid transparent;
168
- }
169
- &:hover {
170
- border-color: var(--vertical-nav-hover-border-color);
171
- &:not(.active) {
172
- background: var(--vertical-nav-hover-bg-color);
173
- }
174
- }
175
- span {
176
- display: inline-block;
177
- vertical-align: text-bottom;
178
- margin: 1px 4px 0;
179
- }
180
- }
181
- }
182
- }
183
- }
184
- </style>
185
-
186
- <style>
187
- :root {
188
- --vertical-nav-active-item-color: #fff;
189
- --vertical-nav-active-bg-color: #29414e;
190
- --vertical-nav-hover-bg-color: #e8e8e8;
191
- --vertical-nav-hover-border-color: #666;
192
- --tree-node-caret-icon: #666;
193
- }
194
- :root.dark-theme {
195
- --vertical-nav-active-item-color: #000;
196
- --vertical-nav-active-bg-color: #d8e3e9;
197
- --vertical-nav-hover-bg-color: #324f61;
198
- --vertical-nav-hover-border-color: #fff;
199
- --tree-node-caret-icon: #acbac3;
200
- }
201
- </style>
1
+ <template>
2
+ <div class="recursion-tree">
3
+ <div v-for="node in nodes" :key="`${node.type}_${node.id}`">
4
+ <div
5
+ :id="`tree-node-${node.type}-${node.id}`"
6
+ class="clr-tree-node"
7
+ @click="selectNode(node)"
8
+ >
9
+ <button
10
+ v-if="node.hasNodes"
11
+ :id="`tree-node-${node.type}-${node.id}-toggle-button`"
12
+ class="clr-treenode-caret"
13
+ @click.stop="getNodes({ node })"
14
+ >
15
+ <i
16
+ v-if="loading[`${node.id}_${node.type}`]"
17
+ class="fa clr-tree-node-caret-icon spinner spinner-sm"
18
+ />
19
+ <atoms-the-icon
20
+ v-else
21
+ :class="['clr-tree-node-caret-icon', { down: node.nodesShow }]"
22
+ name="angle"
23
+ />
24
+ </button>
25
+ <div
26
+ :class="[
27
+ 'tree-node-text-drag',
28
+ { 'no-child': !node.hasNodes, 'dark-mode': hasDarkMode },
29
+ ]"
30
+ @contextmenu="showContextMenuAndSelectNode($event, node)"
31
+ >
32
+ <div
33
+ :class="[
34
+ 'clr-treenode-link tree-node-text',
35
+ { active: node.isActive },
36
+ ]"
37
+ >
38
+ <span :class="node.iconClassName" />
39
+ {{ node.name }}
40
+ </div>
41
+ </div>
42
+ </div>
43
+
44
+ <common-recursion-tree
45
+ v-if="node.nodesShow && node.nodes.length"
46
+ :nodes="node.nodes"
47
+ :style="{ 'padding-left': node.nodesShow ? '20px' : '' }"
48
+ @get-nodes="getNodes($event)"
49
+ @select-node="selectNode($event)"
50
+ @contextmenu.prevent
51
+ @show-context-menu="showContextMenu"
52
+ />
53
+ </div>
54
+ </div>
55
+ </template>
56
+
57
+ <script setup lang="ts">
58
+ import { UI_I_TreeNode } from '~/components/common/recursionTree/models/interfaces'
59
+
60
+ const { $store } = useNuxtApp()
61
+
62
+ interface UI_I_Loading {
63
+ [key: string]: boolean
64
+ }
65
+
66
+ const props = defineProps<{
67
+ nodes: UI_I_TreeNode[]
68
+ }>()
69
+ const emits = defineEmits<{
70
+ (event: 'get-nodes', value: any): void
71
+ (event: 'select-node', value: UI_I_TreeNode): void
72
+ (event: 'show-context-menu', value: any): void
73
+ }>()
74
+
75
+ const loading = ref<UI_I_Loading>({})
76
+ watch(props.nodes, (nodes) => {
77
+ nodes.forEach((node) => {
78
+ loading.value[`${node.id}_${node.type}`] = false
79
+ })
80
+ })
81
+
82
+ const hasDarkMode = computed<boolean>(
83
+ () => $store.getters['main/getInterfaceThemeMode'] === 'DARK'
84
+ )
85
+
86
+ const getNodes = (data: any): void => {
87
+ const node: UI_I_TreeNode = data.node
88
+ const cb: Function | undefined = data.cb
89
+
90
+ loading.value[`${node.id}_${node.type}`] = true
91
+ const collBack = () => {
92
+ loading.value[`${node.id}_${node.type}`] = false
93
+ }
94
+ emits('get-nodes', {
95
+ node,
96
+ cb: cb || collBack,
97
+ })
98
+ }
99
+ const selectNode = (node: UI_I_TreeNode): void => {
100
+ emits('select-node', node)
101
+ }
102
+ const showContextMenu = (event: any, node: UI_I_TreeNode): void => {
103
+ // Если данные приходят от потомка, то нужно так обработать, из-за рекурсии
104
+ if (event.node && event.event) {
105
+ emits('show-context-menu', { ...event })
106
+ return
107
+ }
108
+ emits('show-context-menu', { event, node })
109
+ }
110
+ const showContextMenuAndSelectNode = (
111
+ event: any,
112
+ node: UI_I_TreeNode
113
+ ): void => {
114
+ selectNode(node)
115
+
116
+ showContextMenu(event, node)
117
+ }
118
+ </script>
119
+
120
+ <style scoped lang="scss">
121
+ .recursion-tree {
122
+ .clr-tree-node {
123
+ width: 100%;
124
+ overflow: hidden;
125
+ display: flex;
126
+ flex: 1 1 0;
127
+ align-items: center;
128
+ margin-bottom: 1px;
129
+
130
+ .clr-treenode-caret {
131
+ outline: none;
132
+
133
+ .clr-tree-node-caret-icon {
134
+ position: static;
135
+ transform: rotate(90deg);
136
+ width: 11px;
137
+ height: 11px;
138
+ fill: var(--tree-node-caret-icon);
139
+
140
+ &.down {
141
+ transform: rotate(180deg);
142
+ }
143
+ }
144
+ }
145
+ .tree-node-text-drag {
146
+ width: 100%;
147
+ overflow: hidden;
148
+ display: flex;
149
+ cursor: grab;
150
+
151
+ &.no-child {
152
+ margin-left: 30px;
153
+ }
154
+ .tree-node-text {
155
+ width: 100%;
156
+ box-sizing: border-box;
157
+ text-overflow: ellipsis;
158
+ overflow: hidden;
159
+ white-space: nowrap;
160
+ padding: 0;
161
+ border-radius: 0;
162
+ border-bottom: 1px solid transparent;
163
+
164
+ &.active {
165
+ background: var(--vertical-nav-active-bg-color);
166
+ color: var(--vertical-nav-active-item-color);
167
+ border-bottom: 1px solid transparent;
168
+ }
169
+ &:hover {
170
+ border-color: var(--vertical-nav-hover-border-color);
171
+ &:not(.active) {
172
+ background: var(--vertical-nav-hover-bg-color);
173
+ }
174
+ }
175
+ span {
176
+ display: inline-block;
177
+ vertical-align: text-bottom;
178
+ margin: 1px 4px 0;
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+ </style>
185
+
186
+ <style>
187
+ :root {
188
+ --vertical-nav-active-item-color: #fff;
189
+ --vertical-nav-active-bg-color: #29414e;
190
+ --vertical-nav-hover-bg-color: #e8e8e8;
191
+ --vertical-nav-hover-border-color: #666;
192
+ --tree-node-caret-icon: #666;
193
+ }
194
+ :root.dark-theme {
195
+ --vertical-nav-active-item-color: #000;
196
+ --vertical-nav-active-bg-color: #d8e3e9;
197
+ --vertical-nav-hover-bg-color: #324f61;
198
+ --vertical-nav-hover-border-color: #fff;
199
+ --tree-node-caret-icon: #acbac3;
200
+ }
201
+ </style>
@@ -1,144 +1,141 @@
1
- <template>
2
- <div :id="id" :class="['btn-group', { 'with-space': collapsedItems.length }]">
3
- <div v-for="(button, key) in props.actions" :key="button.type">
4
- <label v-if="button.uploaded">
5
- <span :class="[`btn btn-link ${props.size}`]">
6
- {{ button.text }}
7
- </span>
8
- <input
9
- :id="`select-file-button-${key}`"
10
- type="file"
11
- :disabled="button.disabled"
12
- :multiple="false"
13
- class="btn-group__file"
14
- @change="(event) => onSelectFiles(event, button.type)"
15
- />
16
- </label>
17
-
18
- <button
19
- v-else
20
- :id="`actions-button-${key}`"
21
- :class="[`btn btn-link ${props.size}`]"
22
- :disabled="button.disabled"
23
- @click="onClickButton(button.type)"
24
- >
25
- {{ button.text }}
26
- </button>
27
- </div>
28
- <atoms-collapse-nav
29
- v-show="collapsedItems.length"
30
- :test-id="`${props.testId}-item`"
31
- :items="collapsedItems"
32
- @change="onClickButton"
33
- @select-file="onSelectFiles"
34
- />
35
- </div>
36
- </template>
37
-
38
- <script lang="ts" setup>
39
- import { UI_I_Button } from '~/components/common/tools/models/interfaces'
40
- import { UI_I_CollapseNavItem } from '~/components/atoms/collapse/models/interfaces'
41
-
42
- const props = withDefaults(
43
- defineProps<{
44
- actions: UI_I_Button[]
45
- testId: string
46
- size?: 'btn-sm' | ''
47
- }>(),
48
- {
49
- size: 'btn-sm',
50
- }
51
- )
52
- const emits = defineEmits<{
53
- (event: 'click', value1: string, value2?: Event | null): void
54
- }>()
55
-
56
- const onClickButton = (type: string): void => {
57
- emits('click', type)
58
- }
59
-
60
- const onSelectFiles = (event: Event, type: string): void => {
61
- emits('click', type, event)
62
- }
63
-
64
- const visibleCount = ref(props.actions.length)
65
- const collapsedItems = computed<UI_I_CollapseNavItem[]>(() => {
66
- return props.actions
67
- .filter((_, index) => {
68
- return index >= visibleCount.value
69
- })
70
- .map((item) => {
71
- return {
72
- text: item.text,
73
- value: item.type,
74
- disabled: item.disabled,
75
- uploaded: item.uploaded,
76
- }
77
- })
78
- })
79
-
80
- const outputSize = (): void => {
81
- const el = document.getElementById(id.value)
82
- if (!el) return
83
-
84
- const elWidth = el.clientWidth
85
- const elItems = el.children
86
- const elItemsMarginLeft = parseInt(getComputedStyle(elItems[0]).marginLeft)
87
- const elItemsMarginRight = parseInt(getComputedStyle(elItems[0]).marginRight)
88
- const childrenMarginY = elItemsMarginLeft + elItemsMarginRight
89
-
90
- let childrenWidth = 0
91
- let count = 0
92
- for (let i = 0; i < elItems.length; i++) {
93
- childrenWidth += elItems[i].clientWidth + childrenMarginY
94
- const isWrap = elWidth - 66 < childrenWidth
95
-
96
- if (isWrap) break
97
- count++
98
- }
99
-
100
- visibleCount.value = count
101
- }
102
-
103
- const setResizeObserve = (): void => {
104
- const el = document.getElementById(id.value)
105
-
106
- if (!el) {
107
- setTimeout(setResizeObserve, 0)
108
- return
109
- }
110
-
111
- new ResizeObserver(outputSize).observe(el)
112
- }
113
- const id = ref<string>('')
114
- onMounted(() => {
115
- id.value = `tool-actions-${useUniqueId()}`
116
- setResizeObserve()
117
- })
118
- </script>
119
-
120
- <style lang="scss" scoped>
121
- .btn {
122
- &:disabled {
123
- color: var(--btn-link-disabled);
124
- }
125
- &-group {
126
- margin-top: 10px;
127
- box-shadow: none;
128
- position: relative;
129
- overflow: hidden;
130
- display: flex;
131
- flex-wrap: wrap;
132
- min-height: 25px;
133
- height: 25px;
134
- box-sizing: content-box;
135
-
136
- &__file {
137
- display: none;
138
- }
139
- &.with-space {
140
- padding-right: 66px;
141
- }
142
- }
143
- }
144
- </style>
1
+ <template>
2
+ <div :id="id" class="btn-group">
3
+ <div v-for="(button, key) in props.actions" :key="button.type">
4
+ <label v-if="button.uploaded">
5
+ <span :class="[`btn btn-link ${props.size}`]">
6
+ {{ button.text }}
7
+ </span>
8
+ <input
9
+ :id="`select-file-button-${key}`"
10
+ type="file"
11
+ :disabled="button.disabled"
12
+ :multiple="false"
13
+ class="btn-group__file"
14
+ @change="(event) => onSelectFiles(event, button.type)"
15
+ />
16
+ </label>
17
+
18
+ <button
19
+ v-else
20
+ :id="`actions-button-${key}`"
21
+ :class="[`btn btn-link ${props.size}`]"
22
+ :disabled="button.disabled"
23
+ @click="onClickButton(button.type)"
24
+ >
25
+ {{ button.text }}
26
+ </button>
27
+ </div>
28
+ <atoms-collapse-nav
29
+ v-show="collapsedItems.length"
30
+ :test-id="`${props.testId}-item`"
31
+ :items="collapsedItems"
32
+ @change="onClickButton"
33
+ @select-file="onSelectFiles"
34
+ />
35
+ </div>
36
+ </template>
37
+
38
+ <script lang="ts" setup>
39
+ import { UI_I_Button } from '~/components/common/tools/models/interfaces'
40
+ import { UI_I_CollapseNavItem } from '~/components/atoms/collapse/models/interfaces'
41
+
42
+ const props = withDefaults(
43
+ defineProps<{
44
+ actions: UI_I_Button[]
45
+ testId: string
46
+ size?: 'btn-sm' | ''
47
+ }>(),
48
+ {
49
+ size: 'btn-sm',
50
+ }
51
+ )
52
+ const emits = defineEmits<{
53
+ (event: 'click', value1: string, value2?: Event | null): void
54
+ }>()
55
+
56
+ const onClickButton = (type: string): void => {
57
+ emits('click', type)
58
+ }
59
+
60
+ const onSelectFiles = (event: Event, type: string): void => {
61
+ emits('click', type, event)
62
+ }
63
+
64
+ const visibleCount = ref(props.actions.length)
65
+ const collapsedItems = computed<UI_I_CollapseNavItem[]>(() => {
66
+ return props.actions
67
+ .filter((_, index) => {
68
+ return index >= visibleCount.value
69
+ })
70
+ .map((item) => {
71
+ return {
72
+ text: item.text,
73
+ value: item.type,
74
+ disabled: item.disabled,
75
+ uploaded: item.uploaded,
76
+ }
77
+ })
78
+ })
79
+
80
+ const outputSize = (): void => {
81
+ const el = document.getElementById(id.value)
82
+ if (!el) return
83
+
84
+ const elWidth = el.clientWidth
85
+ const elItems = el.children
86
+ const elItemsMarginLeft = parseInt(getComputedStyle(elItems[0]).marginLeft)
87
+ const elItemsMarginRight = parseInt(getComputedStyle(elItems[0]).marginRight)
88
+ const childrenMarginY = elItemsMarginLeft + elItemsMarginRight
89
+
90
+ let childrenWidth = 0
91
+ let count = 0
92
+ for (let i = 0; i < elItems.length; i++) {
93
+ childrenWidth += elItems[i].clientWidth + childrenMarginY
94
+ const isWrap = elWidth < childrenWidth
95
+
96
+ if (isWrap) break
97
+ count++
98
+ }
99
+
100
+ visibleCount.value = count
101
+ }
102
+
103
+ const setResizeObserve = (): void => {
104
+ const el = document.getElementById(id.value)
105
+
106
+ if (!el) {
107
+ setTimeout(setResizeObserve, 0)
108
+ return
109
+ }
110
+
111
+ new ResizeObserver(outputSize).observe(el)
112
+ }
113
+ const id = ref<string>('')
114
+ onMounted(() => {
115
+ id.value = `tool-actions-${useUniqueId()}`
116
+ setResizeObserve()
117
+ })
118
+ </script>
119
+
120
+ <style lang="scss" scoped>
121
+ .btn {
122
+ &:disabled {
123
+ color: var(--btn-link-disabled);
124
+ }
125
+ &-group {
126
+ margin-top: 10px;
127
+ box-shadow: none;
128
+ position: relative;
129
+ overflow: hidden;
130
+ display: flex;
131
+ flex-wrap: wrap;
132
+ min-height: 25px;
133
+ height: 25px;
134
+ box-sizing: content-box;
135
+
136
+ &__file {
137
+ display: none;
138
+ }
139
+ }
140
+ }
141
+ </style>