bfg-common 1.5.474 → 1.5.475

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 (149) 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/perPage/PerPage.vue +58 -58
  9. package/components/atoms/table/dataGrid/DataGrid.vue +1709 -1709
  10. package/components/atoms/table/dataGrid/DataGridPagination.vue +97 -97
  11. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  12. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  13. package/components/atoms/window/Window.vue +458 -458
  14. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  15. package/components/common/context/lib/models/interfaces.ts +33 -33
  16. package/components/common/diagramMain/modals/lib/config/networkModal.ts +398 -398
  17. package/components/common/diagramMain/modals/lib/config/portModal.ts +251 -251
  18. package/components/common/diagramMain/modals/lib/config/vCenterModal.ts +48 -48
  19. package/components/common/diagramMain/port/Port.vue +580 -580
  20. package/components/common/layout/theHeader/helpMenu/About.vue +79 -79
  21. package/components/common/layout/theHeader/helpMenu/aboutNew/AboutNew.vue +95 -95
  22. package/components/common/layout/theHeader/helpMenu/aboutOld/AboutOld.vue +79 -79
  23. package/components/common/pages/backups/DetailView.vue +52 -52
  24. package/components/common/pages/backups/lib/models/interfaces.ts +36 -36
  25. package/components/common/pages/backups/modals/createBackup/configuration/Configuration.vue +29 -29
  26. package/components/common/pages/backups/modals/createBackup/configuration/backupWindow/BackupWindow.vue +26 -26
  27. package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/MaxBandwidth.vue +66 -66
  28. package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/lib/config/options.ts +6 -6
  29. package/components/common/pages/backups/modals/createBackup/configuration/strategy/Strategy.vue +35 -35
  30. package/components/common/pages/backups/modals/createBackup/datastores/tableView/TableView.vue +95 -95
  31. package/components/common/pages/backups/modals/createBackup/general/General.vue +141 -141
  32. package/components/common/pages/backups/modals/createBackup/lib/config/strategyOptions.ts +12 -12
  33. package/components/common/pages/backups/modals/lib/config/restore.ts +115 -115
  34. package/components/common/pages/backups/modals/lib/models/interfaces.ts +186 -186
  35. package/components/common/pages/backups/modals/restore/disks/Disks.vue +27 -27
  36. package/components/common/pages/backups/modals/restore/disks/tableView/lib/config/table.ts +117 -117
  37. package/components/common/pages/backups/modals/restore/name/Name.vue +166 -166
  38. package/components/common/pages/backups/modals/restore/name/lib/models/interfaces.ts +6 -6
  39. package/components/common/pages/backups/modals/restore/networks/Networks.vue +67 -67
  40. package/components/common/pages/backups/modals/restore/networks/table/Table.vue +214 -214
  41. package/components/common/pages/backups/modals/restore/types/lib/config/typeOptions.ts +25 -25
  42. package/components/common/pages/backups/tools/Tools.vue +75 -75
  43. package/components/common/pages/backups/tools/lib/config/tabs.ts +36 -36
  44. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  45. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  46. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  47. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  48. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  49. package/components/common/pages/scheduledTasks/lib/utils/utils.ts +84 -84
  50. package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
  51. package/components/common/select/radio/RadioGroup.vue +137 -137
  52. package/components/common/spiceConsole/Drawer.vue +392 -392
  53. package/components/common/spiceConsole/SpiceConsole.vue +184 -184
  54. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  55. package/components/common/tools/Actions.vue +207 -207
  56. package/components/common/treeView/TreeView.vue +52 -52
  57. package/components/common/vm/actions/add/folderTreeView/FolderTreeView.vue +72 -72
  58. package/components/common/vm/actions/add/folderTreeView/New.vue +40 -40
  59. package/components/common/vm/actions/common/customizeHardware/virtualHardware/bus/BusNew.vue +1 -4
  60. package/components/common/vm/actions/common/customizeHardware/virtualHardware/bus/BusOld.vue +1 -1
  61. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveNew.vue +0 -1
  62. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveOld.vue +0 -1
  63. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/Media.vue +0 -1
  64. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaNew.vue +78 -84
  65. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +368 -368
  66. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/coresPerSocket/CoresPerSocketNew.vue +1 -4
  67. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/hotPlug/HotPlugNew.vue +1 -4
  68. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/maxCpu/MaxCpuNew.vue +1 -4
  69. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/model/ModelNew.vue +1 -4
  70. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/Shares.vue +140 -140
  71. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/SharesNew.vue +1 -4
  72. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  73. package/components/common/vm/actions/common/customizeHardware/virtualHardware/limit/LimitNew.vue +1 -4
  74. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/hotPlug/HotPlugNew.vue +1 -4
  75. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskNew.vue +0 -2
  76. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/cache/CacheNew.vue +1 -4
  77. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/file/File.vue +0 -1
  78. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/file/FileNew.vue +1 -5
  79. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/limitIops/LimitIopsNew.vue +1 -4
  80. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/location/Location.vue +154 -154
  81. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/location/LocationNew.vue +1 -4
  82. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/maximumSize/MaximumSize.vue +0 -1
  83. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/maximumSize/MaximumSizeNew.vue +1 -5
  84. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/mode/ModeNew.vue +1 -4
  85. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/provisioning/ProvisioningNew.vue +1 -4
  86. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/sharing/SharingNew.vue +1 -4
  87. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/adapterType/AdapterTypeNew.vue +1 -4
  88. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/new/table/Table.vue +99 -99
  89. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddress.vue +119 -119
  90. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddressNew.vue +1 -4
  91. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoNew.vue +66 -69
  92. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIo.vue +31 -31
  93. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIoNew.vue +1 -4
  94. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/Note.vue +0 -1
  95. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteNew.vue +42 -49
  96. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGridNew.vue +1 -4
  97. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/typeSelection/TypeSelectionNew.vue +1 -4
  98. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/Other.vue +16 -16
  99. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/inputDevices/InputDevicesNew.vue +1 -4
  100. package/components/common/vm/actions/common/customizeHardware/virtualHardware/reservation/ReservationNew.vue +1 -4
  101. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/model/ModelNew.vue +1 -4
  102. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/numberDisplays/NumberDisplays.vue +53 -53
  103. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/numberDisplays/NumberDisplaysNew.vue +1 -4
  104. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/totalVideoMemory/TotalVideoMemoryNew.vue +1 -4
  105. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/Delay.vue +32 -32
  106. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/DelayNew.vue +1 -4
  107. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/Firmware.vue +60 -60
  108. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/FirmwareNew.vue +1 -4
  109. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/menu/MenuNew.vue +1 -4
  110. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +174 -174
  111. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/OrderNew.vue +1 -4
  112. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsNew.vue +4 -16
  113. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/copyPaste/CopyPasteNew.vue +1 -4
  114. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/fileTransfer/FileTransferNew.vue +1 -4
  115. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/folderSharing/FolderSharingNew.vue +1 -4
  116. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +32 -32
  117. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/KeymapNew.vue +1 -4
  118. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/Password.vue +103 -103
  119. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/PasswordNew.vue +1 -4
  120. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirection.vue +28 -28
  121. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirectionNew.vue +1 -4
  122. package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
  123. package/components/common/vm/actions/common/select/computeResource/ComputeResource.vue +143 -143
  124. package/components/common/vm/actions/common/select/computeResource/New.vue +184 -184
  125. package/components/common/vm/actions/common/select/computeResource/treeView/TreeView.vue +131 -131
  126. package/components/common/vm/actions/common/select/createType/CreateType.vue +38 -38
  127. package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
  128. package/components/common/vm/actions/common/select/name/Name.vue +197 -197
  129. package/components/common/vm/actions/common/select/os/Old.vue +152 -152
  130. package/components/common/vm/actions/common/select/os/Os.vue +139 -139
  131. package/components/common/vm/actions/common/select/storage/new/New.vue +320 -320
  132. package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
  133. package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
  134. package/components/common/vm/actions/common/select/template/old/Old.vue +50 -50
  135. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  136. package/components/common/vm/actions/register/Register.vue +267 -267
  137. package/components/common/vm/actions/register/lib/config/steps.ts +86 -86
  138. package/components/common/wizards/datastore/add/steps/typeMode/lib/config/typeOptions.ts +43 -43
  139. package/components/common/wizards/vm/migrate/select/network/Network.vue +103 -103
  140. package/composables/productNameLocal.ts +30 -30
  141. package/composables/useAppVersion.ts +21 -21
  142. package/package.json +1 -1
  143. package/plugins/date.ts +233 -233
  144. package/plugins/panelStates.ts +70 -70
  145. package/plugins/text.ts +59 -59
  146. package/public/spice-console/lib/images/bitmap.js +203 -203
  147. package/public/spice-console/network/spicechannel.js +440 -440
  148. package/store/main/mutations.ts +7 -7
  149. package/store/main/state.ts +7 -7
@@ -1,458 +1,458 @@
1
- <template>
2
- <div
3
- :class="['window-container', { loading: props.loading }]"
4
- :style="{
5
- left: leftLocal + 'px',
6
- top: topLocal + 'px',
7
- width: widthLocal + 'px',
8
- height: heightLocal + 'px',
9
- }"
10
- >
11
- <div
12
- ref="headerEl"
13
- class="window-header"
14
- :style="{ height: headerHeight + 'px' }"
15
- >
16
- <slot name="header">
17
- <div class="window-title text-ellipsis">{{ props.title }}</div>
18
- </slot>
19
-
20
- <div class="flex-align-center gap-2">
21
- <button class="window-btn window-hide" @click="onCollapse">
22
- <ui-icon
23
- :name="collapseData.isCollapsed ? 'arrow' : 'check-line'"
24
- class="hide-icon"
25
- width="16"
26
- height="16"
27
- />
28
- </button>
29
- <button class="window-btn window-view-full-screen" @click="toggle">
30
- <ui-icon
31
- name="view-full-screen"
32
- class="view-full-screen-icon"
33
- width="14"
34
- height="14"
35
- />
36
- </button>
37
- <button class="window-btn window-close" @click="onHide">
38
- <ui-icon name="close" class="close-icon" width="16" height="16" />
39
- </button>
40
- </div>
41
- </div>
42
-
43
- <div ref="windowContent" class="window-content">
44
- <div v-show="props.loading" class="absolute-center">
45
- <ui-icon name="spinner" />
46
- </div>
47
- <slot></slot>
48
- <div v-show="isShowContentBlocker" class="content-blocker"></div>
49
- </div>
50
-
51
- <!-- Ручки для ресайза -->
52
- <div
53
- class="resize-handle resize-top"
54
- @mousedown="startResize($event, 'top')"
55
- ></div>
56
- <div
57
- class="resize-handle resize-right"
58
- @mousedown="startResize($event, 'right')"
59
- ></div>
60
- <div
61
- class="resize-handle resize-bottom"
62
- @mousedown="startResize($event, 'bottom')"
63
- ></div>
64
- <div
65
- class="resize-handle resize-left"
66
- @mousedown="startResize($event, 'left')"
67
- ></div>
68
- <div
69
- class="resize-handle resize-top-left"
70
- @mousedown="startResize($event, 'top-left')"
71
- ></div>
72
- <div
73
- class="resize-handle resize-top-right"
74
- @mousedown="startResize($event, 'top-right')"
75
- ></div>
76
- <div
77
- class="resize-handle resize-bottom-left"
78
- @mousedown="startResize($event, 'bottom-left')"
79
- ></div>
80
- <div
81
- class="resize-handle resize-bottom-right"
82
- @mousedown="startResize($event, 'bottom-right')"
83
- ></div>
84
- </div>
85
- </template>
86
-
87
- <script setup lang="ts">
88
- import { useDraggable, useFullscreen } from '@vueuse/core'
89
- import type { UI_I_WindowCollapsedData } from '~/components/atoms/window/lib/models/interfaces'
90
- import {
91
- minWidth,
92
- minHeight,
93
- headerHeight,
94
- windowPadding,
95
- } from '~/components/atoms/window/lib/config/config'
96
-
97
- const props = withDefaults(
98
- defineProps<{
99
- top: number
100
- left: number
101
- width: number
102
- height: number
103
- title: string
104
- loading?: boolean
105
- }>(),
106
- {
107
- loading: false,
108
- }
109
- )
110
- const emits = defineEmits<{
111
- (event: 'hide'): void
112
- }>()
113
-
114
- const windowContent = ref<any>(null)
115
- const { toggle } = useFullscreen(windowContent)
116
-
117
- const headerEl = ref(null)
118
- const isShowContentBlocker = ref<boolean>(false)
119
-
120
- const leftLocal = ref<number>(props.left)
121
- const topLocal = ref<number>(props.top - headerHeight)
122
- const widthLocal = ref<number>(Math.max(minWidth, props.width))
123
- const heightLocal = ref<number>(
124
- Math.max(minHeight, props.height + headerHeight)
125
- )
126
-
127
- const collapseData = ref<UI_I_WindowCollapsedData>({
128
- isCollapsed: false,
129
- cashTop: -1,
130
- cashLeft: -1,
131
- cashWidth: -1,
132
- cashHeight: -1,
133
- })
134
-
135
- // Используем vueuse для перетаскивания
136
- useDraggable(headerEl, {
137
- initialValue: { x: leftLocal.value, y: topLocal.value },
138
- onMove({ x: newX, y: newY }) {
139
- leftLocal.value = newX
140
- topLocal.value = newY
141
- },
142
- onStart() {
143
- isShowContentBlocker.value = true
144
- if (!collapseData.value.isCollapsed) {
145
- collapseData.value.cashTop = topLocal.value
146
- collapseData.value.cashLeft = leftLocal.value
147
- collapseData.value.cashWidth = widthLocal.value
148
- collapseData.value.cashHeight = heightLocal.value
149
- }
150
- },
151
- onEnd() {
152
- isShowContentBlocker.value = false
153
- fixPosition()
154
- },
155
- })
156
-
157
- const fixSize = (): void => {
158
- const globalWindowWidth = window.innerWidth
159
- const globalWindowHeight = window.innerHeight
160
-
161
- widthLocal.value = Math.min(
162
- globalWindowWidth - windowPadding * 2,
163
- widthLocal.value
164
- )
165
- heightLocal.value = Math.min(
166
- globalWindowHeight - windowPadding * 2,
167
- heightLocal.value
168
- )
169
- }
170
- const fixPosition = (): void => {
171
- const globalWindowWidth = window.innerWidth
172
- const globalWindowHeight = window.innerHeight
173
- let newX = leftLocal.value
174
- let newY = topLocal.value
175
-
176
- if (leftLocal.value + widthLocal.value > globalWindowWidth - windowPadding) {
177
- newX = globalWindowWidth - widthLocal.value - windowPadding
178
- } else if (leftLocal.value < windowPadding) {
179
- newX = windowPadding
180
- }
181
-
182
- if (topLocal.value + heightLocal.value / 2 > globalWindowHeight) {
183
- newY = globalWindowHeight - headerHeight
184
- collapseData.value.isCollapsed = true
185
- } else if (
186
- topLocal.value + heightLocal.value >
187
- globalWindowHeight - windowPadding
188
- ) {
189
- newY = globalWindowHeight - heightLocal.value - windowPadding
190
- collapseData.value.isCollapsed = false
191
- } else if (topLocal.value < windowPadding) {
192
- newY = windowPadding
193
- collapseData.value.isCollapsed = false
194
- } else {
195
- collapseData.value.isCollapsed = false
196
- }
197
-
198
- smoothMove(newX, newY)
199
- }
200
- const smoothMove = (newX: number, newY: number, duration = 100): void => {
201
- const startX = leftLocal.value
202
- const startY = topLocal.value
203
-
204
- // Время начала анимации
205
- const startTime = performance.now()
206
-
207
- // Функция анимации
208
- const animate = (currentTime: number): void => {
209
- // Прошедшее время с начала анимации
210
- const elapsedTime = currentTime - startTime
211
-
212
- // Прогресс анимации (от 0 до 1)
213
- const progress = Math.min(elapsedTime / duration, 1)
214
-
215
- // Вычисляем новые координаты с помощью линейной интерполяции
216
- leftLocal.value = startX + (newX - startX) * progress
217
- topLocal.value = startY + (newY - startY) * progress
218
-
219
- // Если анимация не завершена, продолжаем
220
- if (progress < 1) {
221
- requestAnimationFrame(animate)
222
- }
223
- }
224
-
225
- // Запускаем анимацию
226
- requestAnimationFrame(animate)
227
- }
228
-
229
- const onCollapse = (): void => {
230
- collapseData.value.isCollapsed = !collapseData.value.isCollapsed
231
-
232
- if (collapseData.value.isCollapsed) {
233
- collapseData.value.cashTop = topLocal.value
234
- collapseData.value.cashLeft = leftLocal.value
235
- collapseData.value.cashWidth = widthLocal.value
236
- collapseData.value.cashHeight = heightLocal.value
237
-
238
- const globalWindowWidth = window.innerWidth
239
- const globalWindowHeight = window.innerHeight
240
-
241
- widthLocal.value = minWidth
242
- // heightLocal.value = minHeight
243
- leftLocal.value = globalWindowWidth - widthLocal.value - windowPadding
244
- topLocal.value = globalWindowHeight - headerHeight
245
- fixPosition()
246
- } else {
247
- leftLocal.value = collapseData.value.cashLeft
248
- topLocal.value = collapseData.value.cashTop
249
- widthLocal.value = collapseData.value.cashWidth
250
- heightLocal.value = collapseData.value.cashHeight
251
- fixPosition()
252
- }
253
- }
254
-
255
- // Функция для ресайза
256
- const startResize = (e: any, direction: any): void => {
257
- e.preventDefault()
258
-
259
- const startX = e.clientX
260
- const startY = e.clientY
261
- const startWidth = widthLocal.value
262
- const startHeight = heightLocal.value
263
- const startLeft = leftLocal.value
264
- const startTop = topLocal.value
265
-
266
- const onMouseMove = (e: any): void => {
267
- const deltaX = e.clientX - startX
268
- const deltaY = e.clientY - startY
269
-
270
- if (direction.includes('right')) {
271
- widthLocal.value = Math.max(minWidth, startWidth + deltaX)
272
- }
273
- if (direction.includes('bottom')) {
274
- heightLocal.value = Math.max(minHeight, startHeight + deltaY)
275
- }
276
- if (direction.includes('left')) {
277
- const newWidth = Math.max(minWidth, startWidth - deltaX)
278
- if (newWidth !== widthLocal.value) {
279
- leftLocal.value = startLeft + deltaX
280
- widthLocal.value = newWidth
281
- }
282
- }
283
- if (direction.includes('top')) {
284
- const newHeight = Math.max(minHeight, startHeight - deltaY)
285
- if (newHeight !== heightLocal.value) {
286
- topLocal.value = startTop + deltaY
287
- heightLocal.value = newHeight
288
- }
289
- }
290
- fixSize()
291
- }
292
-
293
- const onMouseUp = (): void => {
294
- document.removeEventListener('mousemove', onMouseMove)
295
- document.removeEventListener('mouseup', onMouseUp)
296
- isShowContentBlocker.value = false
297
- fixPosition()
298
- }
299
-
300
- document.addEventListener('mousemove', onMouseMove)
301
- document.addEventListener('mouseup', onMouseUp)
302
- isShowContentBlocker.value = true
303
- }
304
-
305
- let resizeTimer: any = null
306
- const globalWindowResize = (): void => {
307
- clearTimeout(resizeTimer)
308
-
309
- resizeTimer = setTimeout(() => {
310
- fixSize()
311
- fixPosition()
312
- }, 250)
313
- }
314
- onMounted(() => {
315
- window.addEventListener('resize', globalWindowResize)
316
- })
317
- onUnmounted(() => {
318
- window.removeEventListener('resize', globalWindowResize)
319
- })
320
-
321
- const onHide = (): void => {
322
- emits('hide')
323
- }
324
- </script>
325
-
326
- <style lang="scss">
327
- .window-container {
328
- position: absolute;
329
- border-radius: 6px;
330
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
331
- overflow: hidden;
332
- background-color: #fff;
333
- display: flex;
334
- flex-direction: column;
335
- //min-width: 300px;
336
- //min-height: 200px;
337
- z-index: var(--z-toast);
338
-
339
- &.loading {
340
- opacity: 0.5;
341
- }
342
-
343
- .window-header {
344
- background-color: #314351;
345
- color: white;
346
- padding: 6px 12px;
347
- cursor: move;
348
- user-select: none;
349
- display: flex;
350
- justify-content: space-between;
351
- align-items: center;
352
-
353
- .window-title {
354
- font-size: 13px;
355
- }
356
-
357
- .window-btn {
358
- background: none;
359
- border: none;
360
- color: #e4e4e4;
361
- cursor: pointer;
362
- width: 20px;
363
- height: 20px;
364
- display: flex;
365
- justify-content: center;
366
- align-items: center;
367
-
368
- &:hover {
369
- color: #ffffff;
370
- }
371
- }
372
- }
373
-
374
- .window-content {
375
- position: relative;
376
- flex-grow: 1;
377
-
378
- .content-blocker {
379
- position: absolute;
380
- top: 0;
381
- left: 0;
382
- width: 100%;
383
- height: 100%;
384
- z-index: 1;
385
- }
386
- }
387
-
388
- .resize-handle {
389
- position: absolute;
390
- background: transparent;
391
- z-index: 10;
392
-
393
- &.resize-top {
394
- top: -3px;
395
- left: 0;
396
- right: 0;
397
- height: 6px;
398
- cursor: n-resize;
399
- }
400
-
401
- &.resize-right {
402
- top: 0;
403
- right: -3px;
404
- bottom: 0;
405
- width: 6px;
406
- cursor: e-resize;
407
- }
408
-
409
- &.resize-bottom {
410
- bottom: -3px;
411
- left: 0;
412
- right: 0;
413
- height: 6px;
414
- cursor: s-resize;
415
- }
416
-
417
- &.resize-left {
418
- top: 0;
419
- left: -3px;
420
- bottom: 0;
421
- width: 6px;
422
- cursor: w-resize;
423
- }
424
-
425
- &.resize-top-left {
426
- top: -6px;
427
- left: -6px;
428
- width: 12px;
429
- height: 12px;
430
- cursor: nw-resize;
431
- }
432
-
433
- &.resize-top-right {
434
- top: -6px;
435
- right: -6px;
436
- width: 12px;
437
- height: 12px;
438
- cursor: ne-resize;
439
- }
440
-
441
- &.resize-bottom-left {
442
- bottom: -6px;
443
- left: -6px;
444
- width: 12px;
445
- height: 12px;
446
- cursor: sw-resize;
447
- }
448
-
449
- &.resize-bottom-right {
450
- bottom: -6px;
451
- right: -6px;
452
- width: 12px;
453
- height: 12px;
454
- cursor: se-resize;
455
- }
456
- }
457
- }
458
- </style>
1
+ <template>
2
+ <div
3
+ :class="['window-container', { loading: props.loading }]"
4
+ :style="{
5
+ left: leftLocal + 'px',
6
+ top: topLocal + 'px',
7
+ width: widthLocal + 'px',
8
+ height: heightLocal + 'px',
9
+ }"
10
+ >
11
+ <div
12
+ ref="headerEl"
13
+ class="window-header"
14
+ :style="{ height: headerHeight + 'px' }"
15
+ >
16
+ <slot name="header">
17
+ <div class="window-title text-ellipsis">{{ props.title }}</div>
18
+ </slot>
19
+
20
+ <div class="flex-align-center gap-2">
21
+ <button class="window-btn window-hide" @click="onCollapse">
22
+ <ui-icon
23
+ :name="collapseData.isCollapsed ? 'arrow' : 'check-line'"
24
+ class="hide-icon"
25
+ width="16"
26
+ height="16"
27
+ />
28
+ </button>
29
+ <button class="window-btn window-view-full-screen" @click="toggle">
30
+ <ui-icon
31
+ name="view-full-screen"
32
+ class="view-full-screen-icon"
33
+ width="14"
34
+ height="14"
35
+ />
36
+ </button>
37
+ <button class="window-btn window-close" @click="onHide">
38
+ <ui-icon name="close" class="close-icon" width="16" height="16" />
39
+ </button>
40
+ </div>
41
+ </div>
42
+
43
+ <div ref="windowContent" class="window-content">
44
+ <div v-show="props.loading" class="absolute-center">
45
+ <ui-icon name="spinner" />
46
+ </div>
47
+ <slot></slot>
48
+ <div v-show="isShowContentBlocker" class="content-blocker"></div>
49
+ </div>
50
+
51
+ <!-- Ручки для ресайза -->
52
+ <div
53
+ class="resize-handle resize-top"
54
+ @mousedown="startResize($event, 'top')"
55
+ ></div>
56
+ <div
57
+ class="resize-handle resize-right"
58
+ @mousedown="startResize($event, 'right')"
59
+ ></div>
60
+ <div
61
+ class="resize-handle resize-bottom"
62
+ @mousedown="startResize($event, 'bottom')"
63
+ ></div>
64
+ <div
65
+ class="resize-handle resize-left"
66
+ @mousedown="startResize($event, 'left')"
67
+ ></div>
68
+ <div
69
+ class="resize-handle resize-top-left"
70
+ @mousedown="startResize($event, 'top-left')"
71
+ ></div>
72
+ <div
73
+ class="resize-handle resize-top-right"
74
+ @mousedown="startResize($event, 'top-right')"
75
+ ></div>
76
+ <div
77
+ class="resize-handle resize-bottom-left"
78
+ @mousedown="startResize($event, 'bottom-left')"
79
+ ></div>
80
+ <div
81
+ class="resize-handle resize-bottom-right"
82
+ @mousedown="startResize($event, 'bottom-right')"
83
+ ></div>
84
+ </div>
85
+ </template>
86
+
87
+ <script setup lang="ts">
88
+ import { useDraggable, useFullscreen } from '@vueuse/core'
89
+ import type { UI_I_WindowCollapsedData } from '~/components/atoms/window/lib/models/interfaces'
90
+ import {
91
+ minWidth,
92
+ minHeight,
93
+ headerHeight,
94
+ windowPadding,
95
+ } from '~/components/atoms/window/lib/config/config'
96
+
97
+ const props = withDefaults(
98
+ defineProps<{
99
+ top: number
100
+ left: number
101
+ width: number
102
+ height: number
103
+ title: string
104
+ loading?: boolean
105
+ }>(),
106
+ {
107
+ loading: false,
108
+ }
109
+ )
110
+ const emits = defineEmits<{
111
+ (event: 'hide'): void
112
+ }>()
113
+
114
+ const windowContent = ref<any>(null)
115
+ const { toggle } = useFullscreen(windowContent)
116
+
117
+ const headerEl = ref(null)
118
+ const isShowContentBlocker = ref<boolean>(false)
119
+
120
+ const leftLocal = ref<number>(props.left)
121
+ const topLocal = ref<number>(props.top - headerHeight)
122
+ const widthLocal = ref<number>(Math.max(minWidth, props.width))
123
+ const heightLocal = ref<number>(
124
+ Math.max(minHeight, props.height + headerHeight)
125
+ )
126
+
127
+ const collapseData = ref<UI_I_WindowCollapsedData>({
128
+ isCollapsed: false,
129
+ cashTop: -1,
130
+ cashLeft: -1,
131
+ cashWidth: -1,
132
+ cashHeight: -1,
133
+ })
134
+
135
+ // Используем vueuse для перетаскивания
136
+ useDraggable(headerEl, {
137
+ initialValue: { x: leftLocal.value, y: topLocal.value },
138
+ onMove({ x: newX, y: newY }) {
139
+ leftLocal.value = newX
140
+ topLocal.value = newY
141
+ },
142
+ onStart() {
143
+ isShowContentBlocker.value = true
144
+ if (!collapseData.value.isCollapsed) {
145
+ collapseData.value.cashTop = topLocal.value
146
+ collapseData.value.cashLeft = leftLocal.value
147
+ collapseData.value.cashWidth = widthLocal.value
148
+ collapseData.value.cashHeight = heightLocal.value
149
+ }
150
+ },
151
+ onEnd() {
152
+ isShowContentBlocker.value = false
153
+ fixPosition()
154
+ },
155
+ })
156
+
157
+ const fixSize = (): void => {
158
+ const globalWindowWidth = window.innerWidth
159
+ const globalWindowHeight = window.innerHeight
160
+
161
+ widthLocal.value = Math.min(
162
+ globalWindowWidth - windowPadding * 2,
163
+ widthLocal.value
164
+ )
165
+ heightLocal.value = Math.min(
166
+ globalWindowHeight - windowPadding * 2,
167
+ heightLocal.value
168
+ )
169
+ }
170
+ const fixPosition = (): void => {
171
+ const globalWindowWidth = window.innerWidth
172
+ const globalWindowHeight = window.innerHeight
173
+ let newX = leftLocal.value
174
+ let newY = topLocal.value
175
+
176
+ if (leftLocal.value + widthLocal.value > globalWindowWidth - windowPadding) {
177
+ newX = globalWindowWidth - widthLocal.value - windowPadding
178
+ } else if (leftLocal.value < windowPadding) {
179
+ newX = windowPadding
180
+ }
181
+
182
+ if (topLocal.value + heightLocal.value / 2 > globalWindowHeight) {
183
+ newY = globalWindowHeight - headerHeight
184
+ collapseData.value.isCollapsed = true
185
+ } else if (
186
+ topLocal.value + heightLocal.value >
187
+ globalWindowHeight - windowPadding
188
+ ) {
189
+ newY = globalWindowHeight - heightLocal.value - windowPadding
190
+ collapseData.value.isCollapsed = false
191
+ } else if (topLocal.value < windowPadding) {
192
+ newY = windowPadding
193
+ collapseData.value.isCollapsed = false
194
+ } else {
195
+ collapseData.value.isCollapsed = false
196
+ }
197
+
198
+ smoothMove(newX, newY)
199
+ }
200
+ const smoothMove = (newX: number, newY: number, duration = 100): void => {
201
+ const startX = leftLocal.value
202
+ const startY = topLocal.value
203
+
204
+ // Время начала анимации
205
+ const startTime = performance.now()
206
+
207
+ // Функция анимации
208
+ const animate = (currentTime: number): void => {
209
+ // Прошедшее время с начала анимации
210
+ const elapsedTime = currentTime - startTime
211
+
212
+ // Прогресс анимации (от 0 до 1)
213
+ const progress = Math.min(elapsedTime / duration, 1)
214
+
215
+ // Вычисляем новые координаты с помощью линейной интерполяции
216
+ leftLocal.value = startX + (newX - startX) * progress
217
+ topLocal.value = startY + (newY - startY) * progress
218
+
219
+ // Если анимация не завершена, продолжаем
220
+ if (progress < 1) {
221
+ requestAnimationFrame(animate)
222
+ }
223
+ }
224
+
225
+ // Запускаем анимацию
226
+ requestAnimationFrame(animate)
227
+ }
228
+
229
+ const onCollapse = (): void => {
230
+ collapseData.value.isCollapsed = !collapseData.value.isCollapsed
231
+
232
+ if (collapseData.value.isCollapsed) {
233
+ collapseData.value.cashTop = topLocal.value
234
+ collapseData.value.cashLeft = leftLocal.value
235
+ collapseData.value.cashWidth = widthLocal.value
236
+ collapseData.value.cashHeight = heightLocal.value
237
+
238
+ const globalWindowWidth = window.innerWidth
239
+ const globalWindowHeight = window.innerHeight
240
+
241
+ widthLocal.value = minWidth
242
+ // heightLocal.value = minHeight
243
+ leftLocal.value = globalWindowWidth - widthLocal.value - windowPadding
244
+ topLocal.value = globalWindowHeight - headerHeight
245
+ fixPosition()
246
+ } else {
247
+ leftLocal.value = collapseData.value.cashLeft
248
+ topLocal.value = collapseData.value.cashTop
249
+ widthLocal.value = collapseData.value.cashWidth
250
+ heightLocal.value = collapseData.value.cashHeight
251
+ fixPosition()
252
+ }
253
+ }
254
+
255
+ // Функция для ресайза
256
+ const startResize = (e: any, direction: any): void => {
257
+ e.preventDefault()
258
+
259
+ const startX = e.clientX
260
+ const startY = e.clientY
261
+ const startWidth = widthLocal.value
262
+ const startHeight = heightLocal.value
263
+ const startLeft = leftLocal.value
264
+ const startTop = topLocal.value
265
+
266
+ const onMouseMove = (e: any): void => {
267
+ const deltaX = e.clientX - startX
268
+ const deltaY = e.clientY - startY
269
+
270
+ if (direction.includes('right')) {
271
+ widthLocal.value = Math.max(minWidth, startWidth + deltaX)
272
+ }
273
+ if (direction.includes('bottom')) {
274
+ heightLocal.value = Math.max(minHeight, startHeight + deltaY)
275
+ }
276
+ if (direction.includes('left')) {
277
+ const newWidth = Math.max(minWidth, startWidth - deltaX)
278
+ if (newWidth !== widthLocal.value) {
279
+ leftLocal.value = startLeft + deltaX
280
+ widthLocal.value = newWidth
281
+ }
282
+ }
283
+ if (direction.includes('top')) {
284
+ const newHeight = Math.max(minHeight, startHeight - deltaY)
285
+ if (newHeight !== heightLocal.value) {
286
+ topLocal.value = startTop + deltaY
287
+ heightLocal.value = newHeight
288
+ }
289
+ }
290
+ fixSize()
291
+ }
292
+
293
+ const onMouseUp = (): void => {
294
+ document.removeEventListener('mousemove', onMouseMove)
295
+ document.removeEventListener('mouseup', onMouseUp)
296
+ isShowContentBlocker.value = false
297
+ fixPosition()
298
+ }
299
+
300
+ document.addEventListener('mousemove', onMouseMove)
301
+ document.addEventListener('mouseup', onMouseUp)
302
+ isShowContentBlocker.value = true
303
+ }
304
+
305
+ let resizeTimer: any = null
306
+ const globalWindowResize = (): void => {
307
+ clearTimeout(resizeTimer)
308
+
309
+ resizeTimer = setTimeout(() => {
310
+ fixSize()
311
+ fixPosition()
312
+ }, 250)
313
+ }
314
+ onMounted(() => {
315
+ window.addEventListener('resize', globalWindowResize)
316
+ })
317
+ onUnmounted(() => {
318
+ window.removeEventListener('resize', globalWindowResize)
319
+ })
320
+
321
+ const onHide = (): void => {
322
+ emits('hide')
323
+ }
324
+ </script>
325
+
326
+ <style lang="scss">
327
+ .window-container {
328
+ position: absolute;
329
+ border-radius: 6px;
330
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
331
+ overflow: hidden;
332
+ background-color: #fff;
333
+ display: flex;
334
+ flex-direction: column;
335
+ //min-width: 300px;
336
+ //min-height: 200px;
337
+ z-index: var(--z-toast);
338
+
339
+ &.loading {
340
+ opacity: 0.5;
341
+ }
342
+
343
+ .window-header {
344
+ background-color: #314351;
345
+ color: white;
346
+ padding: 6px 12px;
347
+ cursor: move;
348
+ user-select: none;
349
+ display: flex;
350
+ justify-content: space-between;
351
+ align-items: center;
352
+
353
+ .window-title {
354
+ font-size: 13px;
355
+ }
356
+
357
+ .window-btn {
358
+ background: none;
359
+ border: none;
360
+ color: #e4e4e4;
361
+ cursor: pointer;
362
+ width: 20px;
363
+ height: 20px;
364
+ display: flex;
365
+ justify-content: center;
366
+ align-items: center;
367
+
368
+ &:hover {
369
+ color: #ffffff;
370
+ }
371
+ }
372
+ }
373
+
374
+ .window-content {
375
+ position: relative;
376
+ flex-grow: 1;
377
+
378
+ .content-blocker {
379
+ position: absolute;
380
+ top: 0;
381
+ left: 0;
382
+ width: 100%;
383
+ height: 100%;
384
+ z-index: 1;
385
+ }
386
+ }
387
+
388
+ .resize-handle {
389
+ position: absolute;
390
+ background: transparent;
391
+ z-index: 10;
392
+
393
+ &.resize-top {
394
+ top: -3px;
395
+ left: 0;
396
+ right: 0;
397
+ height: 6px;
398
+ cursor: n-resize;
399
+ }
400
+
401
+ &.resize-right {
402
+ top: 0;
403
+ right: -3px;
404
+ bottom: 0;
405
+ width: 6px;
406
+ cursor: e-resize;
407
+ }
408
+
409
+ &.resize-bottom {
410
+ bottom: -3px;
411
+ left: 0;
412
+ right: 0;
413
+ height: 6px;
414
+ cursor: s-resize;
415
+ }
416
+
417
+ &.resize-left {
418
+ top: 0;
419
+ left: -3px;
420
+ bottom: 0;
421
+ width: 6px;
422
+ cursor: w-resize;
423
+ }
424
+
425
+ &.resize-top-left {
426
+ top: -6px;
427
+ left: -6px;
428
+ width: 12px;
429
+ height: 12px;
430
+ cursor: nw-resize;
431
+ }
432
+
433
+ &.resize-top-right {
434
+ top: -6px;
435
+ right: -6px;
436
+ width: 12px;
437
+ height: 12px;
438
+ cursor: ne-resize;
439
+ }
440
+
441
+ &.resize-bottom-left {
442
+ bottom: -6px;
443
+ left: -6px;
444
+ width: 12px;
445
+ height: 12px;
446
+ cursor: sw-resize;
447
+ }
448
+
449
+ &.resize-bottom-right {
450
+ bottom: -6px;
451
+ right: -6px;
452
+ width: 12px;
453
+ height: 12px;
454
+ cursor: se-resize;
455
+ }
456
+ }
457
+ }
458
+ </style>