bfg-common 1.5.313 → 1.5.314

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 (129) hide show
  1. package/CODE_STYLE.md +109 -109
  2. package/assets/img/icons/icons-sprite-dark-3.svg +227 -227
  3. package/assets/img/icons/icons-sprite-dark-5.svg +488 -488
  4. package/assets/img/icons/icons-sprite-light-3.svg +227 -227
  5. package/assets/img/icons/icons-sprite-light-5.svg +488 -488
  6. package/components/atoms/TheIcon3.vue +50 -50
  7. package/components/atoms/collapse/CollapseNav.vue +170 -170
  8. package/components/atoms/collapse/CollapseNavItem.vue +226 -226
  9. package/components/atoms/nav/NavBar.vue +147 -147
  10. package/components/atoms/perPage/PerPage.vue +58 -58
  11. package/components/atoms/table/dataGrid/DataGrid.vue +1717 -1717
  12. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  13. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  14. package/components/atoms/tabs/VerticalTabs.vue +105 -105
  15. package/components/common/accordion/Recursion.vue +225 -225
  16. package/components/common/backup/storage/actions/add/lib/config/steps.ts +168 -168
  17. package/components/common/backup/storage/actions/add/steps/hostAccessibility/HostAccessibility.vue +52 -52
  18. package/components/common/backup/storage/actions/add/steps/readyComplete/ReadyComplete.vue +45 -45
  19. package/components/common/backup/storage/actions/delete/Delete.vue +65 -65
  20. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  21. package/components/common/context/lib/models/interfaces.ts +33 -33
  22. package/components/common/diagramMain/DiagramMain.vue +897 -897
  23. package/components/common/diagramMain/modals/lib/config/networkModal.ts +398 -398
  24. package/components/common/diagramMain/network/Network.vue +141 -141
  25. package/components/common/layout/theHeader/helpMenu/About.vue +82 -82
  26. package/components/common/layout/theHeader/userMenu/modals/preferences/view/ViewOld.vue +112 -112
  27. package/components/common/monitor/overview/OverviewOld.vue +139 -139
  28. package/components/common/pages/home/headline/Headline.vue +45 -45
  29. package/components/common/pages/home/headline/HeadlineOld.vue +42 -42
  30. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  31. package/components/common/pages/home/widgets/Widgets.vue +49 -49
  32. package/components/common/pages/home/widgets/WidgetsNew.vue +86 -86
  33. package/components/common/pages/home/widgets/WidgetsOld.vue +34 -34
  34. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  35. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  36. package/components/common/pages/home/widgets/vms/Vms.vue +26 -26
  37. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  38. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  39. package/components/common/pages/packages/Packages.vue +208 -208
  40. package/components/common/pages/shortcuts/block/BlockOld.vue +68 -68
  41. package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
  42. package/components/common/recursionTree/RecursionTree.vue +223 -223
  43. package/components/common/select/button/ButtonDropdown.vue +112 -112
  44. package/components/common/spiceConsole/Drawer.vue +377 -377
  45. package/components/common/spiceConsole/SpiceConsole.vue +127 -127
  46. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  47. package/components/common/tools/Actions.vue +207 -207
  48. package/components/common/vm/actions/add/folderTreeView/FolderTreeView.vue +72 -72
  49. package/components/common/vm/actions/add/folderTreeView/New.vue +40 -40
  50. package/components/common/vm/actions/add/folderTreeView/Old.vue +50 -50
  51. package/components/common/vm/actions/clone/Clone.vue +817 -817
  52. package/components/common/vm/actions/clone/lib/config/steps.ts +291 -291
  53. package/components/common/vm/actions/clone/toTemplate/lib/config/steps.ts +116 -116
  54. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardwareOld.vue +321 -321
  55. package/components/common/vm/actions/common/customizeHardware/virtualHardware/browseView/BrowseView.vue +227 -227
  56. package/components/common/vm/actions/common/customizeHardware/virtualHardware/bus/Bus.vue +100 -100
  57. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDrive.vue +232 -232
  58. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveOld.vue +168 -168
  59. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/Media.vue +25 -25
  60. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaNew.vue +78 -78
  61. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaOld.vue +50 -50
  62. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/Shares.vue +140 -140
  63. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  64. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/tooltip/TooltipNew.vue +154 -154
  65. package/components/common/vm/actions/common/customizeHardware/virtualHardware/limit/Limit.vue +220 -220
  66. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Memory.vue +307 -307
  67. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +385 -385
  68. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/location/Location.vue +154 -154
  69. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/location/LocationOld.vue +85 -85
  70. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +288 -288
  71. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/new/table/lib/config/config.ts +94 -94
  72. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddress.vue +119 -119
  73. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/NewPciDevice.vue +205 -205
  74. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoNew.vue +66 -66
  75. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoOld.vue +62 -62
  76. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIo.vue +31 -31
  77. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIoOld.vue +76 -76
  78. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/Note.vue +15 -15
  79. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteNew.vue +42 -42
  80. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteOld.vue +30 -30
  81. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGridOld.vue +84 -84
  82. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/Other.vue +16 -16
  83. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCard.vue +154 -154
  84. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/numberDisplays/NumberDisplays.vue +53 -53
  85. package/components/common/vm/actions/common/customizeHardware/vmoptions/Vmoptions.vue +152 -152
  86. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsNew.vue +128 -128
  87. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsOld.vue +111 -111
  88. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/Delay.vue +32 -32
  89. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/Firmware.vue +60 -60
  90. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +174 -174
  91. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +83 -83
  92. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsOld.vue +154 -154
  93. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +32 -32
  94. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/KeymapOld.vue +44 -44
  95. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/Password.vue +103 -103
  96. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirection.vue +28 -28
  97. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirectionOld.vue +44 -44
  98. package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
  99. package/components/common/vm/actions/common/select/computeResource/treeView/TreeView.vue +118 -118
  100. package/components/common/vm/actions/common/select/createType/CreateType.vue +38 -38
  101. package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
  102. package/components/common/vm/actions/common/select/name/Name.vue +174 -174
  103. package/components/common/vm/actions/common/select/os/Old.vue +152 -152
  104. package/components/common/vm/actions/common/select/os/Os.vue +139 -139
  105. package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
  106. package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
  107. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  108. package/components/common/vmt/actions/add/Add.vue +641 -641
  109. package/components/common/vmt/actions/add/lib/config/steps.ts +107 -107
  110. package/components/common/vmt/actions/add/lib/models/interfaces.ts +23 -23
  111. package/components/common/wizards/network/add/steps/SelectConnectionType.vue +104 -104
  112. package/components/common/wizards/network/add/steps/SelectedTargetDevice.vue +467 -467
  113. package/components/common/wizards/vm/migrate/Migrate.vue +349 -349
  114. package/components/common/wizards/vm/migrate/lib/config/constructDataReady.ts +220 -220
  115. package/components/common/wizards/vm/migrate/lib/config/steps.ts +157 -157
  116. package/components/common/wizards/vm/migrate/lib/validations.ts +68 -68
  117. package/components/common/wizards/vm/migrate/select/network/Network.vue +103 -103
  118. package/components/common/wizards/vm/migrate/select/network/table/network/lib/config/advancedTable.ts +91 -91
  119. package/composables/productNameLocal.ts +30 -30
  120. package/composables/useAppVersion.ts +21 -21
  121. package/package.json +1 -1
  122. package/plugins/date.ts +233 -233
  123. package/plugins/panelStates.ts +70 -70
  124. package/plugins/text.ts +59 -59
  125. package/public/spice-console/lib/images/bitmap.js +203 -203
  126. package/public/spice-console/network/spicechannel.js +387 -387
  127. package/store/main/mutations.ts +7 -7
  128. package/store/main/state.ts +7 -7
  129. package/store/tasks/mappers/recentTasks.ts +64 -64
@@ -1,127 +1,127 @@
1
- <template>
2
- <div ref="fullScreen" class="spice-console">
3
- <div id="vmw" ref="vmScreen" @scroll="onConsoleScroll"></div>
4
- <common-spice-console-drawer
5
- @toggle-fullscreen="toggle"
6
- @send-alt-command="onSendAltCommand"
7
- />
8
- </div>
9
- </template>
10
- <script setup lang="ts">
11
- import { useFullscreen } from '@vueuse/core'
12
- import RFB from '@novnc/novnc/core/rfb.js'
13
- import SpiceConsole from '~/plugins/spice-console/spice.console'
14
-
15
- const props = defineProps<{
16
- wsUrl: string
17
- vmType: string
18
- vmId: string
19
- host: string
20
- port: number
21
- }>()
22
-
23
- let rfb: any
24
- const vmScreen = ref<any>(null)
25
- const fullScreen = ref<any>(null)
26
- const { toggle } = useFullscreen(fullScreen)
27
-
28
- const connectWS = (): void => {
29
- if (props.vmType === 'VNC') {
30
- connectVNC()
31
- } else if (props.vmType === 'SPICE') {
32
- SpiceConsole.init(props.wsUrl)
33
- }
34
- }
35
-
36
- const connectVNC = (): void => {
37
- rfb = new RFB(vmScreen.value, props.wsUrl, {
38
- protocols: {},
39
- })
40
- }
41
-
42
- const vmDisconnect = (): void => {
43
- if (props.vmType === 'VNC') {
44
- if (rfb) {
45
- rfb.disconnect()
46
- }
47
- }
48
- }
49
-
50
- const onSendAltCommand = (): void => {
51
- // @ts-ignore
52
- window.app.sendCtrlAltDelete()
53
- }
54
-
55
- const onConsoleScroll = (event: any): void => {
56
- app.clientGui.setClientOffset(
57
- app.clientGui.clientOffsetX,
58
- event.target.scrollTop
59
- )
60
- }
61
-
62
- const blockCtrlOrCmdCommands = (e): void => {
63
- const blockedKeys = [
64
- 'e',
65
- 's',
66
- 'p',
67
- 'u',
68
- 'r',
69
- 'o',
70
- 'i',
71
- 'j',
72
- 'k',
73
- 'n',
74
- 't',
75
- 'w',
76
- 'h',
77
- 'd',
78
- ]
79
-
80
- const key = e.key
81
- const ctrlOrCmd = e.ctrlKey || e.metaKey
82
-
83
- // Block Ctrl+key or Cmd+key
84
- if (ctrlOrCmd && blockedKeys.includes(key.toLowerCase())) {
85
- e.preventDefault()
86
- e.stopPropagation()
87
- // console.log(`Blocked key: ${key}`);
88
- return false
89
- }
90
-
91
- // Optionally block right-click menu key (context menu)
92
- // if (e.key === 'ContextMenu') {
93
- // e.preventDefault();
94
- // return false;
95
- // }
96
-
97
- // Optional: block F5/Reload with Ctrl+R as fallback
98
- // if (key === 'F5' || (ctrlOrCmd && key.toLowerCase() === 'r')) {
99
- // e.preventDefault();
100
- // return false;
101
- // }
102
- }
103
- onMounted(() => {
104
- connectWS()
105
- document.addEventListener('keydown', blockCtrlOrCmdCommands)
106
- })
107
-
108
- onBeforeUnmount(() => {
109
- vmDisconnect()
110
- document.removeEventListener('keydown', blockCtrlOrCmdCommands)
111
- })
112
- </script>
113
- <style scoped lang="scss">
114
- .spice-console {
115
- width: 100vw;
116
- height: 100vh;
117
- overflow: hidden;
118
- position: relative;
119
- }
120
- #vmw {
121
- overflow-y: auto;
122
- overflow-x: auto;
123
- position: relative;
124
- height: 100vh;
125
- background-color: #000;
126
- }
127
- </style>
1
+ <template>
2
+ <div ref="fullScreen" class="spice-console">
3
+ <div id="vmw" ref="vmScreen" @scroll="onConsoleScroll"></div>
4
+ <common-spice-console-drawer
5
+ @toggle-fullscreen="toggle"
6
+ @send-alt-command="onSendAltCommand"
7
+ />
8
+ </div>
9
+ </template>
10
+ <script setup lang="ts">
11
+ import { useFullscreen } from '@vueuse/core'
12
+ import RFB from '@novnc/novnc/core/rfb.js'
13
+ import SpiceConsole from '~/plugins/spice-console/spice.console'
14
+
15
+ const props = defineProps<{
16
+ wsUrl: string
17
+ vmType: string
18
+ vmId: string
19
+ host: string
20
+ port: number
21
+ }>()
22
+
23
+ let rfb: any
24
+ const vmScreen = ref<any>(null)
25
+ const fullScreen = ref<any>(null)
26
+ const { toggle } = useFullscreen(fullScreen)
27
+
28
+ const connectWS = (): void => {
29
+ if (props.vmType === 'VNC') {
30
+ connectVNC()
31
+ } else if (props.vmType === 'SPICE') {
32
+ SpiceConsole.init(props.wsUrl)
33
+ }
34
+ }
35
+
36
+ const connectVNC = (): void => {
37
+ rfb = new RFB(vmScreen.value, props.wsUrl, {
38
+ protocols: {},
39
+ })
40
+ }
41
+
42
+ const vmDisconnect = (): void => {
43
+ if (props.vmType === 'VNC') {
44
+ if (rfb) {
45
+ rfb.disconnect()
46
+ }
47
+ }
48
+ }
49
+
50
+ const onSendAltCommand = (): void => {
51
+ // @ts-ignore
52
+ window.app.sendCtrlAltDelete()
53
+ }
54
+
55
+ const onConsoleScroll = (event: any): void => {
56
+ app.clientGui.setClientOffset(
57
+ app.clientGui.clientOffsetX,
58
+ event.target.scrollTop
59
+ )
60
+ }
61
+
62
+ const blockCtrlOrCmdCommands = (e): void => {
63
+ const blockedKeys = [
64
+ 'e',
65
+ 's',
66
+ 'p',
67
+ 'u',
68
+ 'r',
69
+ 'o',
70
+ 'i',
71
+ 'j',
72
+ 'k',
73
+ 'n',
74
+ 't',
75
+ 'w',
76
+ 'h',
77
+ 'd',
78
+ ]
79
+
80
+ const key = e.key
81
+ const ctrlOrCmd = e.ctrlKey || e.metaKey
82
+
83
+ // Block Ctrl+key or Cmd+key
84
+ if (ctrlOrCmd && blockedKeys.includes(key.toLowerCase())) {
85
+ e.preventDefault()
86
+ e.stopPropagation()
87
+ // console.log(`Blocked key: ${key}`);
88
+ return false
89
+ }
90
+
91
+ // Optionally block right-click menu key (context menu)
92
+ // if (e.key === 'ContextMenu') {
93
+ // e.preventDefault();
94
+ // return false;
95
+ // }
96
+
97
+ // Optional: block F5/Reload with Ctrl+R as fallback
98
+ // if (key === 'F5' || (ctrlOrCmd && key.toLowerCase() === 'r')) {
99
+ // e.preventDefault();
100
+ // return false;
101
+ // }
102
+ }
103
+ onMounted(() => {
104
+ connectWS()
105
+ document.addEventListener('keydown', blockCtrlOrCmdCommands)
106
+ })
107
+
108
+ onBeforeUnmount(() => {
109
+ vmDisconnect()
110
+ document.removeEventListener('keydown', blockCtrlOrCmdCommands)
111
+ })
112
+ </script>
113
+ <style scoped lang="scss">
114
+ .spice-console {
115
+ width: 100vw;
116
+ height: 100vh;
117
+ overflow: hidden;
118
+ position: relative;
119
+ }
120
+ #vmw {
121
+ overflow-y: auto;
122
+ overflow-x: auto;
123
+ position: relative;
124
+ height: 100vh;
125
+ background-color: #000;
126
+ }
127
+ </style>
@@ -1,5 +1,5 @@
1
- export interface UI_I_DeviceOption {
2
- label: string
3
- value: any
4
- disabled?: boolean
5
- }
1
+ export interface UI_I_DeviceOption {
2
+ label: string
3
+ value: any
4
+ disabled?: boolean
5
+ }
@@ -1,207 +1,207 @@
1
- <template>
2
- <!-- :style="{ 'padding-right': rightSpace + 'px' }"-->
3
- <div
4
- :id="id"
5
- :style="{ paddingRight: spaceForCollapseBtn + 'px' }"
6
- class="btn-group"
7
- >
8
- <div v-for="(button, key) in props.actions" :key="button.type">
9
- <label
10
- v-if="button.uploaded"
11
- v-development="button.development"
12
- v-permission="button.permission"
13
- >
14
- <span
15
- :class="[`btn btn-link ${props.size}`]"
16
- :data-id="`${button.testId}-text`"
17
- >
18
- <slot name="icon" :data="button" />
19
- {{ button.text }}
20
- </span>
21
- <input
22
- :id="`select-file-button-${key}`"
23
- :data-id="button.testId"
24
- :disabled="button.disabled"
25
- :multiple="button?.multiple || false"
26
- type="file"
27
- class="btn-group__file"
28
- @change="(event) => onSelectFiles(event, button.type, key)"
29
- />
30
- </label>
31
-
32
- <button
33
- v-else
34
- :id="`actions-button-${key}`"
35
- v-development="button.development"
36
- v-permission="button.permission"
37
- :data-id="button.testId"
38
- :class="[`btn btn-link ${props.size}`]"
39
- :disabled="button.disabled"
40
- @click="onClickButton(button.type)"
41
- >
42
- <slot name="icon" :data="button" />
43
- {{ button.text }}
44
- </button>
45
- </div>
46
- <atoms-collapse-nav
47
- v-show="collapsedItems.length"
48
- :test-id="`${props.testId}-item`"
49
- :items="collapsedItems"
50
- class="nav-tabs"
51
- close-after-click
52
- @change="onClickButton"
53
- @select-file="onSelectFiles"
54
- />
55
- </div>
56
- </template>
57
-
58
- <script lang="ts" setup>
59
- import type { UI_I_Button } from '~/components/common/tools/lib/models/interfaces'
60
- import type { UI_I_CollapseNavItem } from '~/components/atoms/collapse/lib/models/interfaces'
61
-
62
- const props = withDefaults(
63
- defineProps<{
64
- actions: UI_I_Button[]
65
- testId: string
66
- size?: 'btn-sm' | ''
67
- }>(),
68
- {
69
- size: 'btn-sm',
70
- }
71
- )
72
- const emits = defineEmits<{
73
- (event: 'click', value1: string, value2?: Event | null): void
74
- }>()
75
-
76
- const onClickButton = (type: string): void => {
77
- emits('click', type)
78
- }
79
-
80
- const onSelectFiles = (event: Event, type: string, key: number): void => {
81
- emits('click', type, event)
82
-
83
- const input = document.getElementById(
84
- `select-file-button-${key}`
85
- ) as HTMLInputElement | null
86
- input && (input.value = '')
87
- }
88
-
89
- const visibleCount = ref<number>(props.actions.length)
90
- const collapsedItems = computed<UI_I_CollapseNavItem[]>(() => {
91
- return props.actions
92
- .filter((_, index) => {
93
- return index >= visibleCount.value
94
- })
95
- .map((item) => {
96
- return {
97
- text: item.text,
98
- value: item.type,
99
- disabled: item.disabled,
100
- development: item.development,
101
- permission: item.permission,
102
- uploaded: item.uploaded,
103
- testId: item.testId,
104
- }
105
- })
106
- })
107
- watch(
108
- () => props.actions,
109
- () => {
110
- // visibleCount.value = newValue.length
111
- outputSize()
112
- },
113
- { deep: true }
114
- )
115
-
116
- // const rightSpace = ref<number>(0)
117
- // watch(
118
- // collapsedItems,
119
- // (newValue) => {
120
- // let space = 0
121
- // const element: any = document.getElementById(id.value)
122
- // if (!element || !newValue.length) space = 0
123
- // else if (element.lastChild?.className?.includes('tabs-overflow')) {
124
- // space =
125
- // element.getBoundingClientRect().right -
126
- // element.lastChild.getBoundingClientRect().left
127
- // }
128
- //
129
- // rightSpace.value = space
130
- // },
131
- // { deep: true }
132
- // )
133
-
134
- const spaceForCollapseBtn = ref<number>(65)
135
- const outputSize = (): void => {
136
- const el = document.getElementById(id.value)
137
- if (!el) return
138
-
139
- const elWidth = el.clientWidth + 1
140
- // const elItems = el.children
141
- const elItems = Array.from(el.children).filter(
142
- (item) => !item.classList.contains('nav-tabs')
143
- )
144
- // const elItemsMarginLeft = parseInt(getComputedStyle(elItems[0]).marginLeft)
145
- // const elItemsMarginRight = parseInt(getComputedStyle(elItems[0]).marginRight)
146
- // const childrenMarginX = elItemsMarginLeft + elItemsMarginRight
147
-
148
- // let childrenWidth = -10 // TODO Найти способ лучше. Не всегда совпадает ширина элементов с шириной родительского элемента
149
- let childrenWidth = spaceForCollapseBtn.value // TODO Найти способ лучше. Не всегда совпадает ширина элементов с шириной родительского элемента
150
- let count = 0
151
- for (let i = 0; i < elItems.length; i++) {
152
- const elItemsMarginLeft = parseInt(getComputedStyle(elItems[i]).marginLeft)
153
- const elItemsMarginRight = parseInt(
154
- getComputedStyle(elItems[i]).marginRight
155
- )
156
- const childrenMarginX = elItemsMarginLeft + elItemsMarginRight
157
-
158
- childrenWidth += elItems[i].clientWidth + childrenMarginX
159
- // const isWrap = elWidth - rightSpace.value < childrenWidth
160
- const isWrap = elWidth < childrenWidth
161
-
162
- if (isWrap) break
163
- count++
164
- }
165
-
166
- visibleCount.value = count
167
- }
168
-
169
- const setResizeObserve = (): void => {
170
- const el = document.getElementById(id.value)
171
-
172
- if (!el) {
173
- setTimeout(setResizeObserve, 0)
174
- return
175
- }
176
-
177
- new ResizeObserver(outputSize).observe(el)
178
- }
179
- const id = ref<string>('')
180
- onMounted(() => {
181
- id.value = `tool-actions-${useUniqueId()}`
182
- setResizeObserve()
183
- })
184
- </script>
185
-
186
- <style lang="scss" scoped>
187
- .btn {
188
- &:disabled {
189
- color: var(--btn-link-disabled);
190
- }
191
- &-group {
192
- margin-top: 10px;
193
- box-shadow: none;
194
- position: relative;
195
- overflow: hidden;
196
- display: flex;
197
- flex-wrap: wrap;
198
- min-height: 25px;
199
- height: 25px;
200
- box-sizing: content-box;
201
-
202
- &__file {
203
- display: none;
204
- }
205
- }
206
- }
207
- </style>
1
+ <template>
2
+ <!-- :style="{ 'padding-right': rightSpace + 'px' }"-->
3
+ <div
4
+ :id="id"
5
+ :style="{ paddingRight: spaceForCollapseBtn + 'px' }"
6
+ class="btn-group"
7
+ >
8
+ <div v-for="(button, key) in props.actions" :key="button.type">
9
+ <label
10
+ v-if="button.uploaded"
11
+ v-development="button.development"
12
+ v-permission="button.permission"
13
+ >
14
+ <span
15
+ :class="[`btn btn-link ${props.size}`]"
16
+ :data-id="`${button.testId}-text`"
17
+ >
18
+ <slot name="icon" :data="button" />
19
+ {{ button.text }}
20
+ </span>
21
+ <input
22
+ :id="`select-file-button-${key}`"
23
+ :data-id="button.testId"
24
+ :disabled="button.disabled"
25
+ :multiple="button?.multiple || false"
26
+ type="file"
27
+ class="btn-group__file"
28
+ @change="(event) => onSelectFiles(event, button.type, key)"
29
+ />
30
+ </label>
31
+
32
+ <button
33
+ v-else
34
+ :id="`actions-button-${key}`"
35
+ v-development="button.development"
36
+ v-permission="button.permission"
37
+ :data-id="button.testId"
38
+ :class="[`btn btn-link ${props.size}`]"
39
+ :disabled="button.disabled"
40
+ @click="onClickButton(button.type)"
41
+ >
42
+ <slot name="icon" :data="button" />
43
+ {{ button.text }}
44
+ </button>
45
+ </div>
46
+ <atoms-collapse-nav
47
+ v-show="collapsedItems.length"
48
+ :test-id="`${props.testId}-item`"
49
+ :items="collapsedItems"
50
+ class="nav-tabs"
51
+ close-after-click
52
+ @change="onClickButton"
53
+ @select-file="onSelectFiles"
54
+ />
55
+ </div>
56
+ </template>
57
+
58
+ <script lang="ts" setup>
59
+ import type { UI_I_Button } from '~/components/common/tools/lib/models/interfaces'
60
+ import type { UI_I_CollapseNavItem } from '~/components/atoms/collapse/lib/models/interfaces'
61
+
62
+ const props = withDefaults(
63
+ defineProps<{
64
+ actions: UI_I_Button[]
65
+ testId: string
66
+ size?: 'btn-sm' | ''
67
+ }>(),
68
+ {
69
+ size: 'btn-sm',
70
+ }
71
+ )
72
+ const emits = defineEmits<{
73
+ (event: 'click', value1: string, value2?: Event | null): void
74
+ }>()
75
+
76
+ const onClickButton = (type: string): void => {
77
+ emits('click', type)
78
+ }
79
+
80
+ const onSelectFiles = (event: Event, type: string, key: number): void => {
81
+ emits('click', type, event)
82
+
83
+ const input = document.getElementById(
84
+ `select-file-button-${key}`
85
+ ) as HTMLInputElement | null
86
+ input && (input.value = '')
87
+ }
88
+
89
+ const visibleCount = ref<number>(props.actions.length)
90
+ const collapsedItems = computed<UI_I_CollapseNavItem[]>(() => {
91
+ return props.actions
92
+ .filter((_, index) => {
93
+ return index >= visibleCount.value
94
+ })
95
+ .map((item) => {
96
+ return {
97
+ text: item.text,
98
+ value: item.type,
99
+ disabled: item.disabled,
100
+ development: item.development,
101
+ permission: item.permission,
102
+ uploaded: item.uploaded,
103
+ testId: item.testId,
104
+ }
105
+ })
106
+ })
107
+ watch(
108
+ () => props.actions,
109
+ () => {
110
+ // visibleCount.value = newValue.length
111
+ outputSize()
112
+ },
113
+ { deep: true }
114
+ )
115
+
116
+ // const rightSpace = ref<number>(0)
117
+ // watch(
118
+ // collapsedItems,
119
+ // (newValue) => {
120
+ // let space = 0
121
+ // const element: any = document.getElementById(id.value)
122
+ // if (!element || !newValue.length) space = 0
123
+ // else if (element.lastChild?.className?.includes('tabs-overflow')) {
124
+ // space =
125
+ // element.getBoundingClientRect().right -
126
+ // element.lastChild.getBoundingClientRect().left
127
+ // }
128
+ //
129
+ // rightSpace.value = space
130
+ // },
131
+ // { deep: true }
132
+ // )
133
+
134
+ const spaceForCollapseBtn = ref<number>(65)
135
+ const outputSize = (): void => {
136
+ const el = document.getElementById(id.value)
137
+ if (!el) return
138
+
139
+ const elWidth = el.clientWidth + 1
140
+ // const elItems = el.children
141
+ const elItems = Array.from(el.children).filter(
142
+ (item) => !item.classList.contains('nav-tabs')
143
+ )
144
+ // const elItemsMarginLeft = parseInt(getComputedStyle(elItems[0]).marginLeft)
145
+ // const elItemsMarginRight = parseInt(getComputedStyle(elItems[0]).marginRight)
146
+ // const childrenMarginX = elItemsMarginLeft + elItemsMarginRight
147
+
148
+ // let childrenWidth = -10 // TODO Найти способ лучше. Не всегда совпадает ширина элементов с шириной родительского элемента
149
+ let childrenWidth = spaceForCollapseBtn.value // TODO Найти способ лучше. Не всегда совпадает ширина элементов с шириной родительского элемента
150
+ let count = 0
151
+ for (let i = 0; i < elItems.length; i++) {
152
+ const elItemsMarginLeft = parseInt(getComputedStyle(elItems[i]).marginLeft)
153
+ const elItemsMarginRight = parseInt(
154
+ getComputedStyle(elItems[i]).marginRight
155
+ )
156
+ const childrenMarginX = elItemsMarginLeft + elItemsMarginRight
157
+
158
+ childrenWidth += elItems[i].clientWidth + childrenMarginX
159
+ // const isWrap = elWidth - rightSpace.value < childrenWidth
160
+ const isWrap = elWidth < childrenWidth
161
+
162
+ if (isWrap) break
163
+ count++
164
+ }
165
+
166
+ visibleCount.value = count
167
+ }
168
+
169
+ const setResizeObserve = (): void => {
170
+ const el = document.getElementById(id.value)
171
+
172
+ if (!el) {
173
+ setTimeout(setResizeObserve, 0)
174
+ return
175
+ }
176
+
177
+ new ResizeObserver(outputSize).observe(el)
178
+ }
179
+ const id = ref<string>('')
180
+ onMounted(() => {
181
+ id.value = `tool-actions-${useUniqueId()}`
182
+ setResizeObserve()
183
+ })
184
+ </script>
185
+
186
+ <style lang="scss" scoped>
187
+ .btn {
188
+ &:disabled {
189
+ color: var(--btn-link-disabled);
190
+ }
191
+ &-group {
192
+ margin-top: 10px;
193
+ box-shadow: none;
194
+ position: relative;
195
+ overflow: hidden;
196
+ display: flex;
197
+ flex-wrap: wrap;
198
+ min-height: 25px;
199
+ height: 25px;
200
+ box-sizing: content-box;
201
+
202
+ &__file {
203
+ display: none;
204
+ }
205
+ }
206
+ }
207
+ </style>