bfg-common 1.5.506 → 1.5.508

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 (25) hide show
  1. package/assets/localization/local_be.json +12 -2
  2. package/assets/localization/local_en.json +12 -2
  3. package/assets/localization/local_hy.json +12 -2
  4. package/assets/localization/local_kk.json +12 -2
  5. package/assets/localization/local_ru.json +12 -2
  6. package/assets/localization/local_zh.json +12 -2
  7. package/components/common/pages/backups/Backups.vue +54 -61
  8. package/components/common/pages/backups/BackupsOld.vue +80 -0
  9. package/components/common/pages/backups/backupsNew/BackupsNew.vue +356 -0
  10. package/components/common/pages/backups/backupsNew/contextMenuView/ContextMenuView.vue +101 -0
  11. package/components/common/pages/backups/backupsNew/contextMenuView/lib/config/contextMenuItems.ts +29 -0
  12. package/components/common/pages/backups/backupsNew/lib/models/interfaces.ts +12 -0
  13. package/components/common/pages/backups/backupsNew/lib/utils/contextMenu.ts +29 -0
  14. package/components/common/pages/backups/backupsNew/lib/utils/details.ts +30 -0
  15. package/components/common/pages/backups/modals/deleteBackup/DeleteBackup.vue +17 -4
  16. package/components/common/pages/backups/tools/Tools.vue +75 -75
  17. package/components/common/pages/backups/tools/lib/config/tabs.ts +37 -36
  18. package/components/common/spiceConsole/Drawer.vue +29 -2
  19. package/components/common/spiceConsole/lib/models/types.ts +1 -0
  20. package/package.json +1 -1
  21. package/plugins/console.ts +21 -22
  22. package/plugins/mouse.ts +21 -0
  23. package/public/spice-console/process/inputprocess.js +227 -203
  24. package/public/spice-console/process/mainprocess.js +82 -78
  25. package/public/spice-console-minify/run.min.js +1 -1
@@ -0,0 +1,356 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ 'backups-page grid h-inherit p-4 overflow-hidden ',
5
+ { 'selected gap-3': props.detailData },
6
+ ]"
7
+ >
8
+ <div class="left-content grid p-4">
9
+ <div class="flex justify-between">
10
+ <h3 class="title-block font-[500] text-[16px]">
11
+ {{ localization.inventoryTabs.backups }} ({{
12
+ props.backupsTree.length
13
+ }})
14
+ </h3>
15
+ <ui-button
16
+ v-if="props.typeFromRoute === 'vm'"
17
+ v-permission="props.createBackupPermission"
18
+ test-id="take-backup-btn"
19
+ size="md"
20
+ @click="emits('set-action', 'createBackup')"
21
+ >
22
+ <ui-icon name="plus" width="20" height="20" class="mr-2" />
23
+ {{ localization.common.createBackup }}...
24
+ </ui-button>
25
+ </div>
26
+ <div
27
+ v-if="props.backupsTree.length"
28
+ class="backups-tree-content overflow-y-auto my-4 px-2 pb-2"
29
+ >
30
+ <ui-tree
31
+ :is-loading="props.backupsLoading"
32
+ :nodes="props.backupsTree"
33
+ @select-node="emits('select-node', $event)"
34
+ @toggle-node="emits('show-nodes', $event.id)"
35
+ @show-context-menu="showContextMenu"
36
+ >
37
+ <template #content="{ node }">
38
+ <div class="flex-align-center">
39
+ <span :class="['node-icon', node.iconClassName]"></span>
40
+ <span class="node-name text-ellipsis">{{ node.name }}</span>
41
+ </div>
42
+ </template>
43
+ </ui-tree>
44
+ </div>
45
+ <div v-else class="empty-block grid justify-items-center content-center">
46
+ <ui-icon
47
+ name="not-found-magnifier"
48
+ width="28"
49
+ height="28"
50
+ color="#9da6ad"
51
+ />
52
+ <p class="title-block font-[400] text-[16px] mt-2">
53
+ {{ localization.common.noBackupsAvailable }}
54
+ </p>
55
+ <p class="description-block mt-[6px] text-[13px]">
56
+ {{ localization.common.noBackupsAvailableDesc }}
57
+ </p>
58
+ </div>
59
+ <ui-button
60
+ v-permission="props.deleteAllPermission"
61
+ :disabled="!props.backupsTree.length"
62
+ :class="[
63
+ 'delete-all w-max ml-auto',
64
+ { disabled: !props.backupsTree.length },
65
+ ]"
66
+ test-id="delete-all-backups-btn"
67
+ size="md"
68
+ variant="text"
69
+ is-without-sizes
70
+ is-without-height
71
+ @click="emits('set-action', 'deleteBackupAll')"
72
+ >
73
+ <ui-icon name="delete" width="20" height="20" class="mr-2" />
74
+ {{ localization.common.deleteAll }}
75
+ </ui-button>
76
+ </div>
77
+ <div
78
+ v-if="props.detailData"
79
+ class="backups-details overflow-hidden flex-direction-column p-4"
80
+ >
81
+ <div class="flex justify-between mb-6">
82
+ <h3 class="title-block font-[500] text-[16px]">
83
+ {{ localization.common.backupDetails }}
84
+ </h3>
85
+ <div class="details-actions-block flex column-gap-4">
86
+ <ui-tooltip
87
+ id="restore-backups-btn"
88
+ test-id="restore-backups-btn-tooltip"
89
+ size="md"
90
+ position="bottom"
91
+ position-by-tooltip="center"
92
+ show-type="variant-1"
93
+ >
94
+ <template #target>
95
+ <div id="restore-backups-btn" class="popped tooltip">
96
+ <ui-button
97
+ v-permission="props.restoreBackupPermission"
98
+ test-id="restore-backups-btn"
99
+ size="md"
100
+ variant="text"
101
+ class="restore-backups-btn"
102
+ is-without-sizes
103
+ is-without-height
104
+ @click="emits('set-action', 'restoreBackup')"
105
+ >
106
+ <ui-icon name="update" width="20" height="20" />
107
+ </ui-button>
108
+ </div>
109
+ </template>
110
+ <template #content>
111
+ {{ localization.common.restore }}
112
+ </template>
113
+ </ui-tooltip>
114
+ <div class="border-line"></div>
115
+ <ui-tooltip
116
+ id="delete-backups-btn"
117
+ test-id="delete-backups-btn-tooltip"
118
+ size="md"
119
+ position="bottom"
120
+ position-by-tooltip="center"
121
+ show-type="variant-1"
122
+ >
123
+ <template #target>
124
+ <div id="delete-backups-btn" class="popped tooltip">
125
+ <ui-button
126
+ v-permission="props.deleteBackupPermission"
127
+ test-id="delete-backups-btn"
128
+ size="md"
129
+ variant="text"
130
+ class="delete-backups-btn"
131
+ is-without-sizes
132
+ is-without-height
133
+ @click="emits('set-action', 'deleteBackup')"
134
+ >
135
+ <ui-icon name="delete" width="20" height="20" />
136
+ </ui-button>
137
+ </div>
138
+ </template>
139
+ <template #content>
140
+ {{ localization.common.delete }}
141
+ </template>
142
+ </ui-tooltip>
143
+ </div>
144
+ </div>
145
+ <div class="grid row-gap-3 overflow-y-auto">
146
+ <ui-info-block
147
+ v-for="(item, index) in currentDetailsData"
148
+ :key="index"
149
+ :data="item"
150
+ >
151
+ <template v-if="item.labelIcon" #labelBlock>
152
+ <div class="info-block-label-content flex items-start">
153
+ <ui-icon
154
+ v-if="item.labelIcon"
155
+ :name="item.labelIcon"
156
+ width="20"
157
+ height="20"
158
+ class="info-label-icon mr-[10px]"
159
+ />
160
+ <span class="info-label">{{ item.label }}</span>
161
+ </div>
162
+ </template>
163
+ <template #valueBlock>
164
+ <span
165
+ v-if="item.value === 'empty-description'"
166
+ class="empty-description"
167
+ >
168
+ {{ localization.common.backupHasNoDescriptionYet }}
169
+ </span>
170
+ </template>
171
+ </ui-info-block>
172
+ </div>
173
+ </div>
174
+ </div>
175
+
176
+ <common-pages-backups-backups-new-context-menu-view
177
+ :show="contextMenuShow"
178
+ :context-data="contextMenu"
179
+ :restore-backup-permission="props.restoreBackupPermission"
180
+ :delete-backup-permission="props.deleteBackupPermission"
181
+ @select-action="onSelectContextMenuItem"
182
+ />
183
+ </template>
184
+
185
+ <script setup lang="ts">
186
+ import type { UI_I_InfoBlock } from '~/node_modules/bfg-uikit/components/ui/infoBlock/models/interfaces'
187
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
188
+ import type { UI_I_BackupsTreeNode } from '~/components/common/pages/backups/lib/models/interfaces'
189
+ import type {
190
+ UI_T_TargetType,
191
+ UI_T_BackupActionType,
192
+ } from '~/components/common/pages/backups/lib/models/types'
193
+ import * as utils from '~/components/common/pages/backups/backupsNew/lib/utils/contextMenu'
194
+ import { constructDetails } from '~/components/common/pages/backups/backupsNew/lib/utils/details'
195
+
196
+ const props = defineProps<{
197
+ backupsTree: UI_I_BackupsTreeNode[]
198
+ backupsLoading: boolean
199
+ typeFromRoute: UI_T_TargetType
200
+ detailData: UI_I_BackupsTreeNode | null
201
+ createBackupPermission: string
202
+ restoreBackupPermission: string
203
+ deleteBackupPermission: string
204
+ deleteAllPermission: string
205
+ }>()
206
+
207
+ const emits = defineEmits<{
208
+ (event: 'show-nodes', value: string | number): void
209
+ (event: 'set-action', value: UI_T_BackupActionType): void
210
+ (event: 'select-node', value: UI_I_BackupsTreeNode): void
211
+ }>()
212
+
213
+ const localization = computed<UI_I_Localization>(() => useLocal())
214
+
215
+ const { showContextMenu, contextMenuShow, contextMenu } = utils.getContextMenu()
216
+
217
+ const onSelectContextMenuItem = (actionType: UI_T_BackupActionType): void => {
218
+ emits('set-action', actionType)
219
+ }
220
+
221
+ const currentDetailsData = computed<UI_I_InfoBlock[]>(() =>
222
+ constructDetails(localization.value, props.detailData)
223
+ )
224
+ </script>
225
+
226
+ <style>
227
+ :root {
228
+ --backups-page-inner-block-bg: #ffffff;
229
+ --backups-page-title-color: #4d5d69;
230
+ --backups-page-tree-border-color: #e9ebed;
231
+ --backups-page-details-action-color: #4d5d69;
232
+ --backups-page-details-action-hover-color: #213444;
233
+ --backups-page-info-block-label-color: #4d5d69;
234
+ --backups-page-info-block-value-color: #182531;
235
+ }
236
+ :root.dark-theme {
237
+ --backups-page-inner-block-bg: #334453;
238
+ --backups-page-title-color: #e9eaec;
239
+ --backups-page-tree-border-color: #e9ebed1f;
240
+ --backups-page-details-action-color: #e9eaec;
241
+ --backups-page-details-action-hover-color: #ffffff;
242
+ --backups-page-info-block-label-color: #e9eaec;
243
+ --backups-page-info-block-value-color: #e9eaec;
244
+ }
245
+ </style>
246
+
247
+ <style scoped lang="scss">
248
+ .backups-page {
249
+ &.selected {
250
+ grid-template-columns: repeat(2, calc(50% - 6px));
251
+ }
252
+
253
+ .title-block {
254
+ color: var(--backups-page-title-color);
255
+ }
256
+
257
+ .left-content {
258
+ background-color: var(--backups-page-inner-block-bg);
259
+ box-shadow: 0 1px 4px 0 #00000014;
260
+ border-radius: 8px;
261
+ grid-template-rows: max-content 1fr max-content;
262
+
263
+ .backups-tree-content {
264
+ border: 1px solid var(--backups-page-tree-border-color);
265
+ border-radius: 8px;
266
+
267
+ :deep(.tree-content) {
268
+ padding-right: 8px;
269
+
270
+ .node-wrapper {
271
+ border-radius: 4px;
272
+
273
+ .node-element {
274
+ line-height: 20px;
275
+ }
276
+ }
277
+ }
278
+ }
279
+
280
+ .empty-block {
281
+ .description-block {
282
+ color: #9da6ad;
283
+ }
284
+ }
285
+ .delete-all {
286
+ &:not(.disabled) {
287
+ color: #ea3223;
288
+ }
289
+ }
290
+ }
291
+ .backups-details {
292
+ background-color: var(--backups-page-inner-block-bg);
293
+ box-shadow: 0 1px 4px 0 #00000014;
294
+ border-radius: 8px;
295
+
296
+ .details-actions-block {
297
+ .border-line {
298
+ width: 1px;
299
+ height: 20px;
300
+ background-color: #e9ebeda3;
301
+ }
302
+ .restore-backups-btn,
303
+ .edit-backups-btn {
304
+ color: var(--backups-page-details-action-color);
305
+
306
+ &:hover {
307
+ color: var(--backups-page-details-action-hover-color);
308
+ }
309
+ }
310
+ .delete-backups-btn {
311
+ color: #ea3223;
312
+ }
313
+ }
314
+ .info-block-label-content {
315
+ .info-label-icon {
316
+ color: #9da6ad;
317
+ min-width: 20px;
318
+ }
319
+ .info-label {
320
+ margin-top: 2.5px;
321
+ color: var(--backups-page-info-block-label-color);
322
+ }
323
+ }
324
+ .empty-description {
325
+ color: #9da6ad;
326
+ }
327
+ :deep(.ui-main-info-block-item-right) {
328
+ white-space: unset !important;
329
+ max-width: 50%;
330
+ }
331
+ :deep(.ui-main-info-block-item-right-value-parent) {
332
+ white-space: unset !important;
333
+ }
334
+ :deep(.ui-main-info-block-item-right-value) {
335
+ color: var(--backups-page-info-block-value-color);
336
+ }
337
+ :deep(.ui-main-info-block-item-right-open) {
338
+ display: none;
339
+ }
340
+ }
341
+ }
342
+
343
+ @media (max-width: 1200px) {
344
+ .backups-page {
345
+ overflow-y: auto;
346
+
347
+ &.selected {
348
+ grid-template-columns: 1fr;
349
+ }
350
+
351
+ .backups-details {
352
+ height: max-content;
353
+ }
354
+ }
355
+ }
356
+ </style>
@@ -0,0 +1,101 @@
1
+ <template>
2
+ <div class="backups-context-menu-view">
3
+ <common-context
4
+ :action-loading="null"
5
+ :context-menu="contextMenu"
6
+ @select-item="onSelectContextMenuItem"
7
+ @hide="onHideContextMenu"
8
+ />
9
+ </div>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
14
+ import type {
15
+ UI_I_ContextMenu,
16
+ UI_I_ContextMenuItem,
17
+ } from '~/components/common/context/lib/models/interfaces'
18
+ import type { I_ContextData } from '~/components/common/pages/backups/backupsNew/lib/models/interfaces'
19
+ import { contextMenuItemsFunc } from '~/components/common/pages/backups/backupsNew/contextMenuView/lib/config/contextMenuItems'
20
+
21
+ const props = defineProps<{
22
+ contextData: I_ContextData
23
+ show: number
24
+ restoreBackupPermission: string
25
+ deleteBackupPermission: string
26
+ }>()
27
+
28
+ const emits = defineEmits<{
29
+ (event: 'select-action', value: string): void
30
+ }>()
31
+
32
+ const localization = computed<UI_I_Localization>(() => useLocal())
33
+
34
+ const contextMenu = ref<UI_I_ContextMenu<'backup'>>({
35
+ x: -9999,
36
+ y: -9999,
37
+ id: '',
38
+ type: 'backup',
39
+ titleText: '',
40
+ titleIconClassName: '',
41
+ items: contextMenuItemsFunc(
42
+ localization.value,
43
+ props.restoreBackupPermission,
44
+ props.deleteBackupPermission
45
+ ),
46
+ })
47
+
48
+ const showContextMenu = (data: I_ContextData): void => {
49
+ const event = data.event
50
+ const node = data.node
51
+
52
+ if (!event || !node) return
53
+
54
+ event.preventDefault()
55
+
56
+ contextMenu.value.x = event.clientX
57
+ contextMenu.value.y = event.clientY
58
+ contextMenu.value.id = '' + node.id
59
+ contextMenu.value.type = node.type
60
+ contextMenu.value.titleText = node.name
61
+ contextMenu.value.titleIconClassName = node.iconClassName
62
+ }
63
+
64
+ watch(
65
+ () => props.show,
66
+ () => {
67
+ showContextMenu(props.contextData)
68
+ }
69
+ )
70
+
71
+ const onHideContextMenu = (): void => {
72
+ contextMenu.value.x = -9999
73
+ contextMenu.value.y = -9999
74
+ }
75
+
76
+ const onSelectContextMenuItem = (item: UI_I_ContextMenuItem): void => {
77
+ emits('select-action', item.actionType)
78
+ }
79
+ </script>
80
+
81
+ <style scoped lang="scss">
82
+ .backups-context-menu-view {
83
+ :deep(.menu-item) {
84
+ .context-icon {
85
+ display: none;
86
+ }
87
+
88
+ .item-ui-icon {
89
+ margin-right: 8px;
90
+ }
91
+
92
+ &:last-child {
93
+ color: #ea3223;
94
+
95
+ .context-link:hover {
96
+ color: #ea3223;
97
+ }
98
+ }
99
+ }
100
+ }
101
+ </style>
@@ -0,0 +1,29 @@
1
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
2
+ import type { UI_I_ContextMenuItem } from '~/components/common/context/lib/models/interfaces'
3
+
4
+ export const contextMenuItemsFunc = (
5
+ localization: UI_I_Localization,
6
+ restoreBackupPermission: string,
7
+ deleteBackupPermission: string
8
+ ): UI_I_ContextMenuItem[] => [
9
+ {
10
+ key: useUniqueId(),
11
+ name: localization.common.restore,
12
+ actionType: 'restoreBackup',
13
+ iconClassName: '',
14
+ iconName: 'update',
15
+ testId: 'restore-backup-vm',
16
+ items: [],
17
+ permission: restoreBackupPermission,
18
+ },
19
+ {
20
+ key: useUniqueId(),
21
+ name: localization.common.delete,
22
+ actionType: 'deleteBackup',
23
+ iconClassName: '',
24
+ iconName: 'delete',
25
+ testId: 'delete-backup-vm',
26
+ items: [],
27
+ permission: deleteBackupPermission,
28
+ },
29
+ ]
@@ -0,0 +1,12 @@
1
+ import type { UI_I_BackupsTreeNode } from '~/components/common/pages/backups/lib/models/interfaces'
2
+
3
+ export interface I_ContextData {
4
+ event: null | MouseEvent
5
+ node: null | UI_I_BackupsTreeNode
6
+ }
7
+
8
+ export interface I_Context {
9
+ contextMenuShow: Ref<number>
10
+ contextMenu: Ref<I_ContextData>
11
+ showContextMenu: any
12
+ }
@@ -0,0 +1,29 @@
1
+ import type {
2
+ I_ContextData,
3
+ I_Context,
4
+ } from '~/components/common/pages/backups/backupsNew/lib/models/interfaces'
5
+
6
+ const contextMenuShow = ref<number>(0)
7
+
8
+ const contextMenu = ref<I_ContextData>({
9
+ event: null,
10
+ node: null,
11
+ })
12
+
13
+ export function getContextMenu(): I_Context {
14
+ const showContextMenu = (data: I_ContextData | null): void => {
15
+ if (!data) return
16
+
17
+ data.event?.preventDefault()
18
+
19
+ contextMenu.value.event = data.event
20
+ contextMenu.value.node = data.node
21
+ contextMenuShow.value++
22
+ }
23
+
24
+ return {
25
+ contextMenuShow,
26
+ contextMenu,
27
+ showContextMenu,
28
+ }
29
+ }
@@ -0,0 +1,30 @@
1
+ import type { UI_I_InfoBlock } from '~/node_modules/bfg-uikit/components/ui/infoBlock/models/interfaces'
2
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
3
+ import type { UI_I_BackupsTreeNode } from '~/components/common/pages/backups/lib/models/interfaces'
4
+
5
+ export const constructDetails = (
6
+ localization: UI_I_Localization,
7
+ detailData: UI_I_BackupsTreeNode | null
8
+ ): UI_I_InfoBlock[] =>
9
+ !detailData
10
+ ? []
11
+ : [
12
+ {
13
+ label: localization.common.name,
14
+ value: detailData.name || '--',
15
+ items: [],
16
+ labelIcon: 'vsphere-icon-storage-system-refresh',
17
+ },
18
+ {
19
+ label: localization.common.description,
20
+ value: detailData.description || 'empty-description',
21
+ items: [],
22
+ labelIcon: 'file',
23
+ },
24
+ {
25
+ label: localization.common.timestamp,
26
+ value: detailData.timestamp || '--',
27
+ items: [],
28
+ labelIcon: 'clock',
29
+ },
30
+ ]
@@ -3,12 +3,14 @@
3
3
  :headline="headline"
4
4
  :description="description"
5
5
  :loading="props.isLoading"
6
+ :modal-texts="modalTexts"
6
7
  @confirm="onRemove"
7
8
  @hide-modal="onHide"
8
9
  />
9
10
  </template>
10
11
 
11
12
  <script setup lang="ts">
13
+ import type { UI_I_ModalTexts } from '~/node_modules/bfg-uikit/components/ui/modal/models/interfaces'
12
14
  import type { UI_I_Localization } from '~/lib/models/interfaces'
13
15
 
14
16
  const props = withDefaults(
@@ -32,13 +34,24 @@ const localization = computed<UI_I_Localization>(() => useLocal())
32
34
 
33
35
  const headline = computed<string>(() => {
34
36
  return props.isAll
35
- ? localization.value.common.deleteAllBackups
36
- : `${props.name} - ${localization.value.common.deleteBackup}`
37
+ ? localization.value.backup.deleteAllBackupsConfirmation
38
+ : localization.value.backup.deleteBackupConfirmation
37
39
  })
38
40
  const description = computed<string>(() => {
39
41
  return props.isAll
40
- ? localization.value.common.deleteAllBackupDescription
41
- : localization.value.common.deleteBackupDescription
42
+ ? localization.value.backup.deleteAllBackupsConfirmationDesc
43
+ : localization.value.backup.deleteBackupConfirmationDesc.replace(
44
+ '{0}',
45
+ props.name
46
+ )
47
+ })
48
+
49
+ const modalTexts = computed<UI_I_ModalTexts>(() => {
50
+ return {
51
+ button2: props.isAll
52
+ ? localization.value.common.deleteAll
53
+ : localization.value.common.delete,
54
+ }
42
55
  })
43
56
 
44
57
  const onRemove = (): void => {