bfg-common 1.4.742 → 1.4.744

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 (128) hide show
  1. package/assets/img/icons/icons-sprite-dark-3.svg +227 -227
  2. package/assets/img/icons/icons-sprite-dark-5.svg +488 -488
  3. package/assets/img/icons/icons-sprite-light-3.svg +227 -227
  4. package/assets/img/icons/icons-sprite-light-5.svg +488 -488
  5. package/assets/scss/common/normalize.scss +361 -361
  6. package/components/atoms/TheIcon3.vue +50 -50
  7. package/components/atoms/modal/bySteps/BySteps.vue +253 -253
  8. package/components/atoms/stack/StackBlock.vue +185 -185
  9. package/components/atoms/table/dataGrid/DataGrid.vue +1696 -1696
  10. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +222 -222
  11. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +91 -91
  12. package/components/common/browse/BrowseNew.vue +237 -237
  13. package/components/common/browse/BrowseOld.vue +217 -217
  14. package/components/common/browse/blocks/contents/Files.vue +37 -37
  15. package/components/common/browse/blocks/contents/FilesOld.vue +72 -72
  16. package/components/common/browse/blocks/contents/filesNew/FilesNew.vue +96 -96
  17. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  18. package/components/common/context/lib/models/interfaces.ts +30 -30
  19. package/components/common/context/recursion/Recursion.vue +86 -86
  20. package/components/common/context/recursion/RecursionNew.vue +226 -211
  21. package/components/common/context/recursion/RecursionOld.vue +227 -213
  22. package/components/common/layout/theHeader/helpMenu/About.vue +82 -82
  23. package/components/common/layout/theHeader/helpMenu/aboutNew/AboutNew.vue +103 -103
  24. package/components/common/mainNavigationPanel/MainNavigationPanel.vue +150 -150
  25. package/components/common/mainNavigationPanel/MainNavigationPanelOld.vue +300 -300
  26. package/components/common/modals/confirmByInput/ConfirmByInput.vue +206 -206
  27. package/components/common/modals/unsavedChanges/UnsavedChanges.vue +56 -56
  28. package/components/common/pages/home/StatusContent.vue +49 -49
  29. package/components/common/pages/home/headline/Headline.vue +44 -44
  30. package/components/common/pages/home/headline/HeadlineNew.vue +71 -71
  31. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  32. package/components/common/pages/home/widgets/Widgets.vue +49 -49
  33. package/components/common/pages/home/widgets/WidgetsNew.vue +86 -86
  34. package/components/common/pages/home/widgets/WidgetsOld.vue +34 -34
  35. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  36. package/components/common/pages/home/widgets/hosts/HostsNew.vue +100 -100
  37. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  38. package/components/common/pages/home/widgets/services/lib/config/config.ts +108 -108
  39. package/components/common/pages/home/widgets/vms/Vms.vue +26 -26
  40. package/components/common/pages/home/widgets/vms/VmsNew.vue +101 -101
  41. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  42. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  43. package/components/common/recursionTree/RecursionTree.vue +223 -223
  44. package/components/common/select/button/ButtonDropdown.vue +108 -108
  45. package/components/common/selectLanguage/lib/config/config.ts +1 -0
  46. package/components/common/spiceConsole/Drawer.vue +370 -370
  47. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  48. package/components/common/split/horizontal/HorizontalNew.vue +384 -358
  49. package/components/common/split/horizontal/HorizontalOld.vue +345 -307
  50. package/components/common/split/vertical/Vertical.vue +160 -160
  51. package/components/common/vm/actions/add/Add.vue +621 -621
  52. package/components/common/vm/actions/clone/Clone.vue +639 -639
  53. package/components/common/vm/actions/clone/lib/config/steps.ts +129 -129
  54. package/components/common/vm/actions/common/customizeHardware/CustomizeHardware.vue +271 -271
  55. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareNew.vue +271 -271
  56. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareOld.vue +174 -174
  57. package/components/common/vm/actions/common/customizeHardware/virtualHardware/browseView/BrowseView.vue +219 -219
  58. package/components/common/vm/actions/common/customizeHardware/virtualHardware/bus/BusNew.vue +117 -117
  59. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveNew.vue +161 -161
  60. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveOld.vue +165 -165
  61. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/Media.vue +25 -25
  62. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaNew.vue +70 -70
  63. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaOld.vue +50 -50
  64. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +338 -338
  65. package/components/common/vm/actions/common/customizeHardware/virtualHardware/limit/Limit.vue +220 -220
  66. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/mode/ModeOld.vue +56 -56
  67. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/sharing/SharingNew.vue +44 -44
  68. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +281 -281
  69. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetworkNew.vue +124 -124
  70. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/LocationOld.vue +134 -134
  71. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/new/New.vue +63 -63
  72. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/new/table/lib/config/config.ts +95 -95
  73. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddress.vue +119 -119
  74. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddressNew.vue +69 -69
  75. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddressOld.vue +83 -83
  76. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoNew.vue +66 -66
  77. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoOld.vue +62 -62
  78. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIo.vue +31 -31
  79. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIoNew.vue +84 -84
  80. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIoOld.vue +76 -76
  81. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/Note.vue +15 -15
  82. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteNew.vue +42 -42
  83. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteOld.vue +30 -30
  84. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGrid.vue +41 -41
  85. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGridNew.vue +81 -81
  86. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGridOld.vue +84 -84
  87. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbControllerNew.vue +56 -56
  88. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/Other.vue +16 -16
  89. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/OtherNew.vue +30 -30
  90. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardNew.vue +104 -104
  91. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardOld.vue +112 -112
  92. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/totalVideoMemory/TotalVideoMemoryNew.vue +54 -54
  93. package/components/common/vm/actions/common/customizeHardware/vmoptions/Vmoptions.vue +145 -145
  94. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsNew.vue +102 -102
  95. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptionsNew.vue +75 -75
  96. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/Delay.vue +26 -26
  97. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/Firmware.vue +57 -57
  98. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/FirmwareNew.vue +42 -42
  99. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/menu/MenuNew.vue +25 -25
  100. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +171 -171
  101. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/OrderNew.vue +50 -50
  102. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsNew.vue +141 -141
  103. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/New.vue +140 -140
  104. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/copyPaste/CopyPasteNew.vue +30 -30
  105. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/fileTransfer/FileTransferNew.vue +30 -30
  106. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/folderSharing/FolderSharingNew.vue +30 -30
  107. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +32 -32
  108. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/KeymapNew.vue +39 -39
  109. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/Password.vue +103 -103
  110. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/PasswordNew.vue +102 -102
  111. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/PasswordOld.vue +94 -94
  112. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirection.vue +28 -28
  113. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirectionNew.vue +38 -38
  114. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirectionOld.vue +44 -44
  115. package/components/common/vm/actions/common/select/storage/Storage.vue +130 -130
  116. package/components/common/vm/actions/common/select/storage/StorageOld.vue +129 -129
  117. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  118. package/composables/productNameLocal.ts +30 -30
  119. package/composables/useAppVersion.ts +21 -21
  120. package/package.json +1 -1
  121. package/plugins/date.ts +233 -233
  122. package/plugins/recursion.ts +311 -311
  123. package/public/spice-console/lib/images/bitmap.js +203 -203
  124. package/public/spice-console/network/spicechannel.js +383 -383
  125. package/public/spice-console-minify/run.min.js +4 -4
  126. package/store/main/mutations.ts +7 -7
  127. package/store/main/state.ts +7 -7
  128. package/store/tasks/mappers/recentTasks.ts +64 -64
@@ -1,307 +1,345 @@
1
- <template>
2
- <div
3
- :id="elementId"
4
- :class="['fill-parent horizontal', { dragging: isDrag }]"
5
- >
6
- <div class="firstPanel" :style="leftPanelStyle">
7
- <div class="left-panel">
8
- <div
9
- v-if="showToggleButton"
10
- :class="['panel-toggle', { collapsed: leftPanelCollapsed }]"
11
- >
12
- <button
13
- id="collapse-left-panel-button"
14
- data-id="collapse-left-panel-button"
15
- class="btn-trigger"
16
- @click="collapseLeftPanel"
17
- >
18
- <atoms-the-icon class="trigger-icon" name="angle" />
19
- </button>
20
- </div>
21
-
22
- <div v-show="!leftPanelCollapsed" class="navigator">
23
- <slot name="firstPanel" />
24
- </div>
25
- </div>
26
- </div>
27
- <div
28
- v-show="!leftPanelCollapsed"
29
- :id="`gutter-${elementId}`"
30
- class="gutter gutter-horizontal"
31
- tabindex="0"
32
- @mousedown="isGrab = true"
33
- @focus="isFocus = true"
34
- @blur="isFocus = false"
35
- >
36
- <div class="gutter-horizontal-handler"></div>
37
- </div>
38
-
39
- <div class="secondPanel right" :style="rightPanelStyle">
40
- <slot name="secondPanel" />
41
- </div>
42
- </div>
43
- </template>
44
-
45
- <script setup lang="ts">
46
- const props = withDefaults(
47
- defineProps<{
48
- parentElementSelector: string
49
- leftPanelW?: number
50
- leftPanelMinWidth?: number
51
- rightPanelMinWidth?: number
52
- showToggleButton?: boolean
53
- hideLeftPanel?: boolean
54
- }>(),
55
- {
56
- leftPanelMinWidth: 200, // 200px
57
- rightPanelMinWidth: 200, // 200px
58
- leftPanelW: undefined,
59
- showToggleButton: true,
60
- hideLeftPanel: false,
61
- }
62
- )
63
- const emits = defineEmits<{
64
- (event: 'dragend', value: number): void
65
- }>()
66
-
67
- const leftPanelStyle = computed(() => {
68
- let width = `calc(${leftPanelW.value}% - 1.5px)`
69
- if (props.showToggleButton && leftPanelCollapsed.value) {
70
- width = '20px'
71
- }
72
- if (props.hideLeftPanel && leftPanelCollapsed.value) width = '0px'
73
-
74
- return { width }
75
- })
76
- const rightPanelStyle = computed(() => {
77
- let width = `calc(${100 - leftPanelW.value}% - 1.5px)`
78
- if (props.showToggleButton && leftPanelCollapsed.value) {
79
- width = 'calc(100% - 20px)'
80
- }
81
-
82
- if (props.hideLeftPanel && leftPanelCollapsed.value)
83
- width = 'calc(100% - 0px)'
84
-
85
- return { width }
86
- })
87
- const leftPanelCollapsed = ref<boolean>(false)
88
- const collapseLeftPanel = (): void => {
89
- leftPanelCollapsed.value = !leftPanelCollapsed.value
90
- }
91
-
92
- const isGrab = ref<boolean>(false)
93
- const isFocus = ref<boolean>(false)
94
- const isDrag = ref<boolean>(false)
95
- const leftPanelW = ref<number>(20) // 0%
96
- watch(
97
- () => props.leftPanelW,
98
- (newValue) => {
99
- if (newValue === undefined) return
100
- leftPanelW.value = newValue
101
- },
102
- { immediate: true }
103
- )
104
-
105
- watch(
106
- () => props.hideLeftPanel,
107
- () => {
108
- collapseLeftPanel()
109
- }
110
- )
111
-
112
- let parentElem: HTMLElement | null
113
- const mouseup = (): void => {
114
- if (!isGrab.value) {
115
- return
116
- }
117
-
118
- isGrab.value = false
119
- isDrag.value = false
120
-
121
- emits('dragend', leftPanelW.value)
122
- }
123
-
124
- let mousemove = (e: MouseEvent): void => {
125
- if (!isGrab.value) return
126
-
127
- e.preventDefault()
128
- isDrag.value = true
129
- doDrag(e.clientX)
130
- }
131
- mousemove = useThrottle(mousemove)
132
-
133
- const doDrag = (clientX: number): void => {
134
- const parentElemRect = parentElem?.getBoundingClientRect()
135
- const parentElemWidth = parentElemRect?.width || 0
136
- const parentElemLeft = parentElemRect?.left || 0
137
- const onePercent = parentElemWidth / 100
138
- const layerX = clientX - parentElemLeft
139
-
140
- const leftLimit = layerX <= props.leftPanelMinWidth
141
- const rightLimit = parentElemWidth - layerX <= props.rightPanelMinWidth
142
- if (leftLimit || rightLimit) return
143
-
144
- leftPanelW.value = layerX / onePercent
145
- }
146
-
147
- const elementId = `horizontal${useUniqueId()}`
148
-
149
- const keydown = (e: KeyboardEvent): void => {
150
- if (!isFocus.value) return
151
-
152
- const gutter = document.getElementById(`gutter-${elementId}`)
153
-
154
- if (!gutter) return
155
-
156
- const gutterLeft = ~~(gutter.getBoundingClientRect().left + 1.5)
157
-
158
- if (e.keyCode === 39) {
159
- doDrag(gutterLeft + 10)
160
- }
161
- if (e.keyCode === 37) {
162
- doDrag(gutterLeft - 10)
163
- }
164
- }
165
- onMounted(() => {
166
- parentElem = document.querySelector(props.parentElementSelector)
167
-
168
- window.addEventListener('mousemove', mousemove)
169
- window.addEventListener('mouseup', mouseup)
170
- window.addEventListener('keydown', keydown)
171
- })
172
- onUnmounted(() => {
173
- window.removeEventListener('mouseup', mouseup)
174
- window.removeEventListener('mousemove', mousemove)
175
- window.removeEventListener('keydown', keydown)
176
- })
177
- </script>
178
-
179
- <style scoped lang="scss">
180
- @import '@/assets/scss/common/mixins';
181
- .horizontal {
182
- &.dragging {
183
- .gutter-horizontal.gutter {
184
- background-color: var(--gutter-active-bg-color);
185
- }
186
- }
187
- .firstPanel {
188
- width: calc(50% - 1.5px);
189
-
190
- .left-panel {
191
- @include flex($dir: column);
192
- width: 100%;
193
- height: 100%;
194
-
195
- .panel-toggle {
196
- border-bottom: 1px solid var(--global-border-color);
197
-
198
- &.collapsed {
199
- border-right: 1px solid var(--global-border-color);
200
-
201
- .btn-trigger {
202
- .trigger-icon {
203
- transform: rotate(90deg);
204
- }
205
- }
206
- }
207
-
208
- .btn-trigger {
209
- @include flex($align: center);
210
- width: 100%;
211
- height: 36px;
212
- flex: 0 0 36px;
213
- border: 0;
214
- padding: 0;
215
- background-color: transparent;
216
- outline: none;
217
- cursor: pointer;
218
-
219
- .trigger-icon {
220
- width: 16px;
221
- height: 16px;
222
- transform: rotate(-90deg);
223
- margin-left: auto;
224
- fill: var(--triger-icon-color);
225
- }
226
- }
227
- }
228
- .navigator {
229
- overflow: hidden;
230
- height: 100%;
231
-
232
- .panel-inner {
233
- position: relative;
234
- height: 100%;
235
- background: var(--horizontal-panel-bg-color);
236
- border-radius: 0;
237
- border: 0;
238
-
239
- &.inventory-tree {
240
- padding-left: 4px;
241
- padding-top: 6px;
242
- }
243
- }
244
- }
245
- }
246
- }
247
- .gutter-horizontal {
248
- position: relative;
249
- width: 3px;
250
- background-color: var(--gutter-bg-color);
251
- transition-delay: 0.25s;
252
- transition-duration: 0.25s;
253
-
254
- &-handler {
255
- position: absolute;
256
- height: 100%;
257
- width: 10px;
258
- background: transparent;
259
- top: 0;
260
- left: -3.5px;
261
- z-index: 2;
262
- }
263
-
264
- &:focus {
265
- background-color: var(--gutter-active-bg-color);
266
- outline: none;
267
- }
268
-
269
- &:hover {
270
- background-color: var(--gutter-hover-bg-color);
271
- cursor: col-resize;
272
- &:before {
273
- background-color: hsla(0, 0%, 100%, 0.5);
274
- box-shadow: inset 0 0 0 1px rgb(0 0 0 / 10%);
275
- }
276
- }
277
-
278
- &:before {
279
- content: '';
280
- position: relative;
281
- display: block;
282
- background: rgba(0, 0, 0, 0.1);
283
- transition-delay: 0.25s;
284
- transition-duration: 0.25s;
285
- width: 100%;
286
- height: 25px;
287
- top: calc(50% - 12.5px);
288
- }
289
- }
290
- .secondPanel {
291
- width: calc(50% - 1.5px);
292
- &.right {
293
- overflow: hidden;
294
- height: 100%;
295
- }
296
- }
297
- }
298
- </style>
299
-
300
- <style>
301
- :root:not(.is-new-view) {
302
- --horizontal-panel-bg-color: #fff;
303
- }
304
- :root:not(.is-new-view).dark-theme {
305
- --horizontal-panel-bg-color: #1b2a32;
306
- }
307
- </style>
1
+ <template>
2
+ <div
3
+ :id="elementId"
4
+ :class="['fill-parent horizontal', { dragging: isDrag }]"
5
+ >
6
+ <div class="firstPanel" :style="leftPanelStyle">
7
+ <div class="left-panel">
8
+ <div
9
+ v-if="showToggleButton"
10
+ :class="['panel-toggle', { collapsed: leftPanelCollapsed }]"
11
+ >
12
+ <button
13
+ id="collapse-left-panel-button"
14
+ data-id="collapse-left-panel-button"
15
+ class="btn-trigger"
16
+ @click="collapseLeftPanel"
17
+ >
18
+ <atoms-the-icon class="trigger-icon" name="angle" />
19
+ </button>
20
+ </div>
21
+
22
+ <div v-show="!leftPanelCollapsed" class="navigator">
23
+ <slot name="firstPanel" />
24
+ </div>
25
+ </div>
26
+ </div>
27
+ <div
28
+ v-show="!leftPanelCollapsed"
29
+ :id="`gutter-${elementId}`"
30
+ class="gutter gutter-horizontal"
31
+ tabindex="0"
32
+ @mousedown="isGrab = true"
33
+ @focus="isFocus = true"
34
+ @blur="isFocus = false"
35
+ >
36
+ <div class="gutter-horizontal-handler"></div>
37
+ </div>
38
+
39
+ <div class="secondPanel right" :style="rightPanelStyle">
40
+ <slot name="secondPanel" />
41
+ </div>
42
+ </div>
43
+ </template>
44
+
45
+ <script setup lang="ts">
46
+ const props = withDefaults(
47
+ defineProps<{
48
+ parentElementSelector: string
49
+ leftPanelW?: number
50
+ leftPanelMinWidth?: number
51
+ rightPanelMinWidth?: number
52
+ showToggleButton?: boolean
53
+ hideLeftPanel?: boolean
54
+ }>(),
55
+ {
56
+ leftPanelMinWidth: 200, // 200px
57
+ rightPanelMinWidth: 200, // 200px
58
+ leftPanelW: undefined,
59
+ showToggleButton: true,
60
+ hideLeftPanel: false,
61
+ }
62
+ )
63
+ const emits = defineEmits<{
64
+ (event: 'dragend', value: number): void
65
+ }>()
66
+
67
+ // TODO remove
68
+ const isRtl = ref<boolean>(useLocalStorage('rtl').value)
69
+ window.addEventListener('storage', () => {
70
+ isRtl.value = useLocalStorage('rtl')
71
+ })
72
+ //
73
+ const leftPanelStyle = computed(() => {
74
+ let width = `calc(${leftPanelW.value}% - 1.5px)`
75
+ // TODO remove
76
+ if (isRtl.value) {
77
+ width = `calc(${100 - leftPanelW.value}% - 1.5px)`
78
+ }
79
+ //
80
+ if (props.showToggleButton && leftPanelCollapsed.value) {
81
+ width = '20px'
82
+ }
83
+ if (props.hideLeftPanel && leftPanelCollapsed.value) width = '0px'
84
+
85
+ return { width }
86
+ })
87
+ const rightPanelStyle = computed(() => {
88
+ let width = `calc(${100 - leftPanelW.value}% - 1.5px)`
89
+ // TODO remove
90
+ if (isRtl.value) {
91
+ width = `calc(${leftPanelW.value}% - 1.5px)`
92
+ }
93
+ //
94
+ if (props.showToggleButton && leftPanelCollapsed.value) {
95
+ width = 'calc(100% - 20px)'
96
+ }
97
+
98
+ if (props.hideLeftPanel && leftPanelCollapsed.value)
99
+ width = 'calc(100% - 0px)'
100
+
101
+ return { width }
102
+ })
103
+ const leftPanelCollapsed = ref<boolean>(false)
104
+ const collapseLeftPanel = (): void => {
105
+ leftPanelCollapsed.value = !leftPanelCollapsed.value
106
+ }
107
+
108
+ const isGrab = ref<boolean>(false)
109
+ const isFocus = ref<boolean>(false)
110
+ const isDrag = ref<boolean>(false)
111
+ const leftPanelW = ref<number>(20) // 0%
112
+ watch(
113
+ () => props.leftPanelW,
114
+ (newValue) => {
115
+ if (newValue === undefined) return
116
+ leftPanelW.value = newValue
117
+ },
118
+ { immediate: true }
119
+ )
120
+
121
+ watch(
122
+ () => props.hideLeftPanel,
123
+ () => {
124
+ collapseLeftPanel()
125
+ }
126
+ )
127
+
128
+ let parentElem: HTMLElement | null
129
+ const mouseup = (): void => {
130
+ if (!isGrab.value) {
131
+ return
132
+ }
133
+
134
+ isGrab.value = false
135
+ isDrag.value = false
136
+
137
+ emits('dragend', leftPanelW.value)
138
+ }
139
+
140
+ let mousemove = (e: MouseEvent): void => {
141
+ if (!isGrab.value) return
142
+
143
+ e.preventDefault()
144
+ isDrag.value = true
145
+ doDrag(e.clientX)
146
+ }
147
+ mousemove = useThrottle(mousemove)
148
+
149
+ const doDrag = (clientX: number): void => {
150
+ const parentElemRect = parentElem?.getBoundingClientRect()
151
+ const parentElemWidth = parentElemRect?.width || 0
152
+ const parentElemLeft = parentElemRect?.left || 0
153
+ const onePercent = parentElemWidth / 100
154
+ const layerX = clientX - parentElemLeft
155
+
156
+ const leftLimit = layerX <= props.leftPanelMinWidth
157
+ const rightLimit = parentElemWidth - layerX <= props.rightPanelMinWidth
158
+ if (leftLimit || rightLimit) return
159
+
160
+ leftPanelW.value = layerX / onePercent
161
+ }
162
+
163
+ const elementId = `horizontal${useUniqueId()}`
164
+
165
+ const keydown = (e: KeyboardEvent): void => {
166
+ if (!isFocus.value) return
167
+
168
+ const gutter = document.getElementById(`gutter-${elementId}`)
169
+
170
+ if (!gutter) return
171
+
172
+ const gutterLeft = ~~(gutter.getBoundingClientRect().left + 1.5)
173
+
174
+ if (e.keyCode === 39) {
175
+ doDrag(gutterLeft + 10)
176
+ }
177
+ if (e.keyCode === 37) {
178
+ doDrag(gutterLeft - 10)
179
+ }
180
+ }
181
+ onMounted(() => {
182
+ parentElem = document.querySelector(props.parentElementSelector)
183
+
184
+ window.addEventListener('mousemove', mousemove)
185
+ window.addEventListener('mouseup', mouseup)
186
+ window.addEventListener('keydown', keydown)
187
+ })
188
+ onUnmounted(() => {
189
+ window.removeEventListener('mouseup', mouseup)
190
+ window.removeEventListener('mousemove', mousemove)
191
+ window.removeEventListener('keydown', keydown)
192
+ })
193
+ </script>
194
+
195
+ <style>
196
+ :root:not(.is-new-view) {
197
+ --horizontal-panel-bg-color: #fff;
198
+ }
199
+ :root:not(.is-new-view).dark-theme {
200
+ --horizontal-panel-bg-color: #1b2a32;
201
+ }
202
+
203
+ :root {
204
+ --horizontal-split-button-border-right: 1px solid var(--global-border-color);
205
+ --horizontal-split-button-border-left: none;
206
+ --horizontal-split-button-icon-margin-left: auto;
207
+ --horizontal-split-button-icon-margin-right: 0;
208
+ --horizontal-split-button-icon-rotate: -90deg;
209
+ --horizontal-split-button-icon-rotate-collapsed: 90deg;
210
+ }
211
+ :root[dir='rtl'] {
212
+ --horizontal-split-button-border-right: none;
213
+ --horizontal-split-button-border-left: 1px solid var(--global-border-color);
214
+ --horizontal-split-button-icon-margin-left: 0;
215
+ --horizontal-split-button-icon-margin-right: auto;
216
+ --horizontal-split-button-icon-rotate: 90deg;
217
+ --horizontal-split-button-icon-rotate-collapsed: -90deg;
218
+ }
219
+ </style>
220
+
221
+ <style scoped lang="scss">
222
+ @import '@/assets/scss/common/mixins';
223
+ .horizontal {
224
+ &.dragging {
225
+ .gutter-horizontal.gutter {
226
+ background-color: var(--gutter-active-bg-color);
227
+ }
228
+ }
229
+ .firstPanel {
230
+ width: calc(50% - 1.5px);
231
+
232
+ .left-panel {
233
+ @include flex($dir: column);
234
+ width: 100%;
235
+ height: 100%;
236
+
237
+ .panel-toggle {
238
+ border-bottom: 1px solid var(--global-border-color);
239
+
240
+ &.collapsed {
241
+ border-right: var(--horizontal-split-button-border-right);
242
+ border-left: var(--horizontal-split-button-border-left);
243
+
244
+ .btn-trigger {
245
+ .trigger-icon {
246
+ transform: rotate(
247
+ var(--horizontal-split-button-icon-rotate-collapsed)
248
+ );
249
+ }
250
+ }
251
+ }
252
+
253
+ .btn-trigger {
254
+ @include flex($align: center);
255
+ width: 100%;
256
+ height: 36px;
257
+ flex: 0 0 36px;
258
+ border: 0;
259
+ padding: 0;
260
+ margin-right: 0;
261
+ background-color: transparent;
262
+ outline: none;
263
+ cursor: pointer;
264
+
265
+ .trigger-icon {
266
+ width: 16px;
267
+ height: 16px;
268
+ transform: rotate(var(--horizontal-split-button-icon-rotate));
269
+ margin-left: var(--horizontal-split-button-icon-margin-left);
270
+ margin-right: var(--horizontal-split-button-icon-margin-right);
271
+ fill: var(--triger-icon-color);
272
+ }
273
+ }
274
+ }
275
+ .navigator {
276
+ overflow: hidden;
277
+ height: 100%;
278
+
279
+ .panel-inner {
280
+ position: relative;
281
+ height: 100%;
282
+ background: var(--horizontal-panel-bg-color);
283
+ border-radius: 0;
284
+ border: 0;
285
+
286
+ &.inventory-tree {
287
+ padding-left: 4px;
288
+ padding-top: 6px;
289
+ }
290
+ }
291
+ }
292
+ }
293
+ }
294
+ .gutter-horizontal {
295
+ position: relative;
296
+ width: 3px;
297
+ background-color: var(--gutter-bg-color);
298
+ transition-delay: 0.25s;
299
+ transition-duration: 0.25s;
300
+
301
+ &-handler {
302
+ position: absolute;
303
+ height: 100%;
304
+ width: 10px;
305
+ background: transparent;
306
+ top: 0;
307
+ left: -3.5px;
308
+ z-index: 2;
309
+ }
310
+
311
+ &:focus {
312
+ background-color: var(--gutter-active-bg-color);
313
+ outline: none;
314
+ }
315
+
316
+ &:hover {
317
+ background-color: var(--gutter-hover-bg-color);
318
+ cursor: col-resize;
319
+ &:before {
320
+ background-color: hsla(0, 0%, 100%, 0.5);
321
+ box-shadow: inset 0 0 0 1px rgb(0 0 0 / 10%);
322
+ }
323
+ }
324
+
325
+ &:before {
326
+ content: '';
327
+ position: relative;
328
+ display: block;
329
+ background: rgba(0, 0, 0, 0.1);
330
+ transition-delay: 0.25s;
331
+ transition-duration: 0.25s;
332
+ width: 100%;
333
+ height: 25px;
334
+ top: calc(50% - 12.5px);
335
+ }
336
+ }
337
+ .secondPanel {
338
+ width: calc(50% - 1.5px);
339
+ &.right {
340
+ overflow: hidden;
341
+ height: 100%;
342
+ }
343
+ }
344
+ }
345
+ </style>