bfg-common 1.5.812 → 1.5.813

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 (105) 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/DataGridPagination.vue +97 -97
  10. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  11. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  12. package/components/common/backup/storage/actions/add/lib/utils.ts +51 -51
  13. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  14. package/components/common/configure/advancedSystemSettings/AdvancedSystemSettings.vue +47 -47
  15. package/components/common/configure/advancedSystemSettings/modals/edit/Edit.vue +78 -78
  16. package/components/common/configure/advancedSystemSettings/modals/edit/New.vue +56 -56
  17. package/components/common/configure/advancedSystemSettings/modals/edit/Old.vue +66 -66
  18. package/components/common/configure/advancedSystemSettings/tableView/TableView.vue +40 -40
  19. package/components/common/configure/advancedSystemSettings/tableView/old/Old.vue +122 -122
  20. package/components/common/configure/advancedSystemSettings/tableView/old/field/Field.vue +139 -139
  21. package/components/common/configure/advancedSystemSettings/tableView/old/field/lib/models/enums.ts +13 -13
  22. package/components/common/configure/advancedSystemSettings/tableView/old/lib/config/table.ts +131 -131
  23. package/components/common/diagramMain/modals/lib/config/vCenterModal.ts +48 -48
  24. package/components/common/diagramMain/port/Port.vue +580 -580
  25. package/components/common/layout/theHeader/userMenu/UserMenu.vue +116 -116
  26. package/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types.ts +7 -7
  27. package/components/common/layout/topNotification/TopNotification.vue +37 -37
  28. package/components/common/layout/topNotification/lib/models/enums.ts +3 -3
  29. package/components/common/pages/backups/DetailView.vue +52 -52
  30. package/components/common/pages/backups/lib/models/interfaces.ts +36 -36
  31. package/components/common/pages/backups/modals/Modals.vue +243 -243
  32. package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/lib/config/options.ts +6 -6
  33. package/components/common/pages/backups/modals/restore/disks/tableView/old/Table.vue +117 -117
  34. package/components/common/pages/backups/modals/restore/lib/config/readyToCompleteOptions.ts +96 -96
  35. package/components/common/pages/backups/modals/restore/lib/config/steps.ts +134 -134
  36. package/components/common/pages/backups/modals/restore/name/lib/models/interfaces.ts +6 -6
  37. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  38. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  39. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  40. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  41. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  42. package/components/common/pages/scheduledTasks/lib/utils/utils.ts +84 -84
  43. package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
  44. package/components/common/select/radio/RadioGroup.vue +137 -137
  45. package/components/common/spiceConsole/Drawer.vue +420 -420
  46. package/components/common/spiceConsole/SpiceConsole.vue +184 -184
  47. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  48. package/components/common/tools/Actions.vue +207 -207
  49. package/components/common/treeView/TreeView.vue +52 -52
  50. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  51. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Memory.vue +283 -283
  52. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/New.vue +340 -340
  53. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +511 -502
  54. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/Old.vue +279 -279
  55. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/vmStoragePolicy/New.vue +53 -53
  56. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/vmStoragePolicy/Old.vue +45 -45
  57. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/vmStoragePolicy/VmStoragePolicy.vue +31 -31
  58. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/vmStoragePolicy/lib/config/options.ts +12 -12
  59. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +156 -156
  60. package/components/common/vm/actions/common/lib/models/interfaces.ts +192 -192
  61. package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
  62. package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
  63. package/components/common/vm/actions/common/select/options/Options.vue +58 -58
  64. package/components/common/vm/actions/common/select/storage/Old.vue +125 -125
  65. package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
  66. package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
  67. package/components/common/vm/actions/common/select/template/old/Old.vue +50 -50
  68. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  69. package/components/common/wizards/common/compatibility/Compatibility.vue +35 -35
  70. package/components/common/wizards/common/steps/name/Old.vue +121 -121
  71. package/components/common/wizards/common/steps/name/lib/models/interfaces.ts +4 -4
  72. package/components/common/wizards/common/steps/name/location/New.vue +40 -40
  73. package/components/common/wizards/datastore/add/steps/typeMode/lib/config/typeOptions.ts +43 -43
  74. package/components/common/wizards/network/add/steps/portProperties/PortProperties.vue +192 -192
  75. package/composables/useAppVersion.ts +21 -21
  76. package/composables/useLocal.ts +6 -6
  77. package/composables/useLocalCommon.ts +39 -39
  78. package/lib/config/regExp.ts +53 -53
  79. package/package.json +1 -1
  80. package/plugins/console.ts +21 -21
  81. package/plugins/helpers.ts +34 -34
  82. package/plugins/mouse.ts +21 -21
  83. package/plugins/panelStates.ts +70 -70
  84. package/plugins/text.ts +59 -59
  85. package/public/spice-console/application/clientgui.js +854 -854
  86. package/public/spice-console/application/packetfactory.js +211 -211
  87. package/public/spice-console/application/virtualmouse.js +147 -147
  88. package/public/spice-console/lib/images/bitmap.js +203 -203
  89. package/public/spice-console/network/spicechannel.js +440 -440
  90. package/public/spice-console/process/cursorprocess.js +128 -128
  91. package/public/spice-console/process/inputprocess.js +227 -227
  92. package/public/spice-console/process/mainprocess.js +212 -212
  93. package/public/spice-console/run.js +210 -210
  94. package/store/inventory/modules/configure/advancedSystemSettings/actions.ts +92 -92
  95. package/store/inventory/modules/configure/advancedSystemSettings/getters.ts +17 -17
  96. package/store/inventory/modules/configure/advancedSystemSettings/lib/models/interfaces.ts +45 -45
  97. package/store/inventory/modules/configure/advancedSystemSettings/lib/models/types.ts +30 -30
  98. package/store/inventory/modules/configure/advancedSystemSettings/mappers/mapSettings.ts +50 -50
  99. package/store/main/actions.ts +28 -28
  100. package/store/main/getters.ts +14 -14
  101. package/store/main/lib/interfaces.ts +18 -18
  102. package/store/main/mutations.ts +28 -28
  103. package/store/main/state.ts +9 -9
  104. package/store/tasks/mappers/recentTasks.ts +123 -123
  105. package/store/tasks/mutations.ts +82 -82
@@ -1,502 +1,511 @@
1
- <template>
2
- <!--TODO 111-->
3
- <!-- v-model:vm-storage-policy="vmStoragePolicy"-->
4
- <component
5
- :is="currentComponent"
6
- v-model:delete-files-from-datastore="deleteFilesFromDatastore"
7
- v-model:size="sizeLocal"
8
- v-model:hard-disk-type="hardDiskType"
9
- v-model:disk-provisioning="provisionType"
10
- v-model:sharing="sharingLocal"
11
- v-model:limit-iops="limitIops"
12
- v-model:limit-iops-type="limitIopsType"
13
- v-model:limit-iops-invalid="limitIopsInvalid"
14
- v-model:disk-mode="diskMode"
15
- v-model:cache="cache"
16
- v-model:bus="bus"
17
- v-model:source="source"
18
- :is-removable="isRemovable"
19
- :label="label"
20
- :hard-disk-invalid="hardDiskInvalid"
21
- :error-text="hardDiskLocalAndApiErrorsTexts"
22
- :hard-disk-type-error-local-text="hardDiskTypeErrorLocalText"
23
- :is-disabled-size="isDisabledSize"
24
- :is-disabled-provisioning="isDisabledProvisioning"
25
- :is-disabled-sharing="isDisabledSharing"
26
- :is-disabled-limit-iops="isDisabledLimitIops"
27
- :is-disabled-mode="isDisabledMode"
28
- :is-disabled-cache="isDisabledCache"
29
- :is-disabled-bus="isDisabledBus"
30
- :hard-disk-type-options="hardDiskTypeOptions"
31
- :max-hard-disk="maxHardDisk"
32
- :location="location"
33
- :is-running="isRunning"
34
- :is-new-hard-disk="isNewHardDisk"
35
- :is-edit="props.isEdit"
36
- :datastore="props.datastore"
37
- :is-datastore-loading="props.isDatastoreLoading"
38
- :get-datastore-table-func="props.getDatastoreTableFunc"
39
- :error-validation-fields="props.errorValidationFields"
40
- :index="props.index"
41
- :type="props.type"
42
- :guest-machine-type="props.guestMachineType"
43
- :compute-resource="props.computeResource"
44
- @remove="emits('remove')"
45
- @roll-back="emits('roll-back')"
46
- @validate-size="onValidateSize"
47
- @change-storage="onChangeStorage"
48
- @remove-error-by-title="emits('remove-error-by-title', $event)"
49
- />
50
- </template>
51
-
52
- <script setup lang="ts">
53
- import type { UI_I_DatastoreTableItem } from '~/lib/models/store/storage/interfaces'
54
- // import type {
55
- // UI_I_SendDataNewHardDisk,
56
- // UI_I_SendDataNewHardDiskStorage,
57
- // } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
58
- import type { UI_T_HardDiskType } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/types'
59
- import type { UI_I_Localization } from '~/lib/models/interfaces'
60
- import type { UI_I_ErrorValidationField } from '~/lib/models/store/interfaces'
61
- import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
62
- import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
63
- import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
64
- import type {
65
- UI_T_LimitIopsType
66
- } from "~/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/limitIops/lib/types";
67
- import { binaryOptionsFunc } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/config/binaryOptions'
68
- import {
69
- minLimitIops
70
- } from "~/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/limitIops/lib/config/options";
71
-
72
- const size = defineModel<number>('size', { required: true })
73
- const initialSize = size.value
74
- // TODO 111
75
- // const vmStoragePolicy = defineModel<string>('vmStoragePolicy', { required: true })
76
- // const provisionType = ref<string>('thick')
77
- const provisionType = defineModel<string>('provisionType', { required: true })
78
- // const sharing = ref<string>('')
79
- const sharing = defineModel<boolean>('sharing', { required: true })
80
- // const sharingLocal = ref<string>(sharing.value ? 'yes' : '')
81
- const sharingLocal = computed<string>({
82
- set(newValue) {
83
- sharing.value = newValue === 'yes'
84
- },
85
- get() {
86
- return sharing.value ? 'yes' : ''
87
- },
88
- })
89
- // const shares = ref<number>(0)
90
- const shares = defineModel<number>('shares', { required: true })
91
-
92
- // const limitIops = ref<number>(16)
93
- const limitIops = defineModel<number>('limitIops', { required: true })
94
- const limitIopsType = ref<UI_T_LimitIopsType>(limitIops.value === 0 ? 'unlimited' : 'custom')
95
- watch(limitIopsType, newValue => {
96
- if (newValue === 'unlimited') limitIops.value = minLimitIops
97
- })
98
- const limitIopsInvalid = ref<boolean>(false) // ??
99
-
100
- // const diskMode = ref<string>('dependent')
101
- const diskMode = defineModel<string>('diskMode', { required: true })
102
-
103
- // const cache = ref<string>('none')
104
- const cache = defineModel<string>('cache', { required: true })
105
-
106
- // const bus = ref<string>('ide')
107
- const bus = defineModel<string>('bus', { required: true })
108
-
109
- // const readOnly = ref<boolean>(false)
110
- const readOnly = defineModel<boolean>('readOnly', { required: true })
111
-
112
- // const discard = ref<string>('')
113
- const discard = defineModel<string>('discard', { required: true })
114
-
115
- // const io = ref<string>('')
116
- const io = defineModel<string>('io', { required: true })
117
-
118
- // const target = ref<string>('')
119
- const target = defineModel<string>('target', { required: true })
120
-
121
- const source = defineModel<string>('source', { required: true })
122
-
123
- const storage = defineModel<any>('storage', { required: true })
124
-
125
- const remove = defineModel<boolean>('remove', { required: true })
126
- const detach = defineModel<boolean>('detach', { required: true })
127
-
128
- const props = withDefaults(
129
- defineProps<{
130
- mainStorage: UI_I_DatastoreTableItem | null
131
- mainStorageFree: number
132
- // hardDisk: UI_I_SendDataNewHardDisk
133
- type: UI_T_HardDiskType
134
- index: number
135
- errorValidationFields: UI_I_ErrorValidationField[]
136
- getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
137
- datastore: UI_I_DatastoreTableItem[]
138
- isDatastoreLoading: boolean
139
- isEdit: boolean
140
- state?: string | number
141
- guestMachineType?: UI_I_OptionItem | null
142
- computeResource?: UI_I_TreeNode | null
143
- }>(),
144
- {
145
- state: undefined,
146
- guestMachineType: undefined,
147
- computeResource: undefined,
148
- }
149
- )
150
- const emits = defineEmits<{
151
- // (event: 'send-data', value: UI_I_SendDataNewHardDisk): void
152
- (event: 'invalid', value: boolean): void
153
- (event: 'remove'): void
154
- (event: 'roll-back'): void
155
- (event: 'remove-error-by-title', value: string): void
156
- }>()
157
-
158
- watch(
159
- () => props.type,
160
- (newValue) => {
161
- detach.value = newValue === 'removed'
162
- }
163
- )
164
-
165
- const { $store, $binary }: any = useNuxtApp()
166
- const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
167
- const currentComponent = computed(() =>
168
- isNewView.value
169
- ? defineAsyncComponent(() => import('./New.vue'))
170
- : defineAsyncComponent(() => import('./Old.vue'))
171
- )
172
-
173
- const localization = computed<UI_I_Localization>(() => useLocal())
174
-
175
- const isRunning = computed<boolean>(() => {
176
- return props.state === 2
177
- })
178
-
179
- const isRemovable = computed<boolean>(() => {
180
- return (
181
- !props.isEdit ||
182
- !isRunning.value ||
183
- (isRunning.value && bus.value === 'virtio')
184
- )
185
- })
186
-
187
- const typeError = computed<string>(() => `disk_devices[${props.index}].size`)
188
-
189
- const apiErrorLocal = computed<string>(() => {
190
- return (
191
- props.errorValidationFields?.find(
192
- (message) => message.field === typeError.value
193
- )?.error_message || ''
194
- )
195
- })
196
-
197
- // PC-1796
198
- // const isNotNewHardDisk = computed<boolean>(
199
- // () => props.type === 'edit' || props.type === 'removed'
200
- // )
201
- const isNewHardDisk = computed<boolean>(
202
- () => props.type !== 'edit' && props.type !== 'removed'
203
- )
204
- const label = computed<string>(() => {
205
- // if (props.type === 'edit' || props.type === 'removed')
206
- if (!isNewHardDisk.value)
207
- return `${localization.value.common.hardDisk} ${props.index + 1}`
208
-
209
- return `${localization.value.common.newHardDisk} *`
210
- })
211
-
212
- const maxHardDisk = computed<number>(() => {
213
- // // const hardDiskSizeMb = $binary.gbToMb(props.hardDisk.size)
214
- //
215
- // if (props.type === 'exist') return initialSize
216
- //
217
- // if (!storageLocal.value) return 0
218
- // const free = (storageLocal.value.capacity.free_mb ||
219
- // storageLocal.value.free) as number // TODO fix
220
- //
221
- // if (props.type === 'edit') return free + initialSize
222
- //
223
- // return free
224
- if (props.type === 'exist') return initialSize
225
-
226
- if (!storageLocal.value) return 0
227
-
228
- return props.mainStorageFree + size.value
229
- })
230
- const hardDiskTypeErrorLocalText = computed<string>(() => {
231
- if (size.value > maxHardDisk.value) {
232
- return localization.value.common.diskCapacitySpecifiedGreater
233
- }
234
-
235
- if (size.value <= 0) {
236
- return localization.value.common.diskCapacityCannotZero
237
- }
238
-
239
- return ''
240
- })
241
-
242
- const hardDiskLocalAndApiErrorsTexts = computed<string>(() => {
243
- const localError = hardDiskTypeErrorLocalText.value
244
- const apiError = apiErrorLocal.value
245
-
246
- let result = ''
247
- if (localError && !apiError) result = localError
248
- if (!localError && apiError) result = apiError
249
- if (localError && apiError) result = localError + ', ' + apiError
250
- if (!localError && apiError) result = apiError
251
-
252
- return result
253
- })
254
-
255
- const deleteFilesFromDatastore = ref<boolean>(false)
256
- watch(deleteFilesFromDatastore, (newValue) => {
257
- remove.value = props.type === 'removed' && newValue
258
- })
259
-
260
- const hardDiskType = ref<string>(size.value < 1024 ? 'mb' : 'gb')
261
- watch(hardDiskType, (newValue) => {
262
- size.value = $binary.universalFromTo(sizeLocal.value, newValue, 'mb')
263
- })
264
- const hardDiskTypeOptions = ref<UI_I_OptionItem[]>(
265
- binaryOptionsFunc(localization.value)
266
- )
267
-
268
- const sizeLocal = ref<number>(
269
- size.value < 1024 ? size.value : $binary.mbToGb(size.value)
270
- )
271
- watch(sizeLocal, (newValue) => {
272
- if (hardDiskType.value === 'mb') {
273
- size.value = newValue
274
- }
275
-
276
- size.value = $binary.universalFromTo(newValue, hardDiskType.value, 'mb')
277
- })
278
- // const sizeInMb = computed<number>(() => {
279
- // if (hardDiskType.value === 'mb') {
280
- // return size.value
281
- // }
282
- //
283
- // return $binary.universalFromTo(size.value, hardDiskType.value, 'mb')
284
- // })
285
- const onValidateSize = (): void => {
286
- if (props.type !== 'edit') return
287
- if (size.value < initialSize) {
288
- sizeLocal.value = $binary.universalFromTo(
289
- initialSize,
290
- 'mb',
291
- hardDiskType.value
292
- )
293
- }
294
- }
295
-
296
- const isDisabledSize = computed<boolean>(() => {
297
- if (isNewHardDisk.value) return false
298
- return (
299
- props.type === 'exist' ||
300
- (props.type === 'edit' && readOnly.value)
301
- // (isRunning.value && provisionType.value === 'thick')
302
- )
303
- })
304
- const isDisabledProvisioning = computed<boolean>(() => {
305
- if (isNewHardDisk.value) return false
306
- return props.isEdit || isRunning.value
307
- })
308
- const isDisabledSharing = computed<boolean>(() => {
309
- return isRunning.value && !isNewHardDisk.value
310
- })
311
- const isDisabledLimitIops = computed<boolean>(() => {
312
- return isRunning.value && !isNewHardDisk.value
313
- })
314
- const isDisabledMode = computed<boolean>(() => {
315
- return isRunning.value && !isNewHardDisk.value
316
- })
317
- const isDisabledCache = computed<boolean>(() => {
318
- if (isNewHardDisk.value) return false
319
- return props.isEdit || isRunning.value
320
- })
321
- const isDisabledBus = computed<boolean>(() => {
322
- return !isNewHardDisk.value && isRunning.value
323
- })
324
-
325
- const location = ref<UI_I_DatastoreTableItem | null>(props.mainStorage || null)
326
- const storageLocal = ref<UI_I_DatastoreTableItem | null>(props.mainStorage)
327
- watch(
328
- () => props.mainStorage,
329
- (newValue) => {
330
- location.value = newValue
331
- storageLocal.value = newValue
332
-
333
- storage.value = {
334
- id: newValue?.id || '',
335
- name: newValue?.name || '',
336
- type: newValue?.type_text || '',
337
- pool: newValue?.pool_name || '',
338
- user: '',
339
- endpoint: '',
340
- password: '',
341
- protocol: '',
342
- options: '',
343
- }
344
- },
345
- {
346
- immediate: true,
347
- deep: true,
348
- }
349
- )
350
- const onChangeStorage = (item: UI_I_DatastoreTableItem): void => {
351
- storageLocal.value = item
352
-
353
- storage.value = {
354
- id: item?.id || '',
355
- name: item?.name || '',
356
- type: item?.type_text || '',
357
- pool: item?.pool_name || '',
358
- user: '',
359
- endpoint: '',
360
- password: '',
361
- protocol: '',
362
- options: '',
363
- }
364
- }
365
-
366
- // const diskProvisioning = ref<string>('thick')
367
- // const sharing = ref<string>('')
368
- // const shares = ref<number>(0)
369
- //
370
- // const limitIops = ref<number>(16)
371
- // const limitIopsType = ref<string>('unlimited')
372
- // const limitIopsInvalid = ref<boolean>(false)
373
- //
374
- // const diskMode = ref<string>('dependent')
375
- //
376
- // const cache = ref<string>('none')
377
- //
378
- // const bus = ref<string>('ide')
379
- //
380
- // const readOnly = ref<boolean>(false)
381
- //
382
- // const discard = ref<string>('')
383
- //
384
- // const io = ref<string>('')
385
- //
386
- // const target = ref<string>('')
387
-
388
- // watch(
389
- // [
390
- // sizeInMb,
391
- // storage,
392
- // diskProvisioning,
393
- // sharing,
394
- // limitIops,
395
- // limitIopsType,
396
- // diskMode,
397
- // cache,
398
- // bus,
399
- // deleteFilesFromDatastore,
400
- // (): void => props.type,
401
- // ],
402
- // () => {
403
- // const limitIopsLocal =
404
- // limitIopsType.value === 'unlimited' ? 0 : limitIops.value
405
- // const storageLocal: UI_I_SendDataNewHardDiskStorage = {
406
- // id: storage.value?.id || '',
407
- // name: storage.value?.name || '',
408
- // type: storage.value?.type_text || '',
409
- // pool: storage.value?.pool_name || '',
410
- // user: '',
411
- // endpoint: '',
412
- // password: '',
413
- // protocol: '',
414
- // options: '',
415
- // }
416
- //
417
- // emits('send-data', {
418
- // create: props.hardDisk.create,
419
- // attach: props.hardDisk.attach,
420
- // source: props.hardDisk.source,
421
- // size: Math.ceil(sizeInMb.value),
422
- // bus: bus.value,
423
- // target: target.value,
424
- // storage: storageLocal,
425
- // device_type: 'disk',
426
- // provision_type: diskProvisioning.value,
427
- // disk_mode: diskMode.value,
428
- // sharing: sharing.value === 'yes',
429
- // read_only: readOnly.value,
430
- // shares: shares.value,
431
- // cache: cache.value,
432
- // io: io.value,
433
- // limit_iops: limitIopsLocal,
434
- // discard: discard.value,
435
- // capacity: Math.ceil(sizeInMb.value),
436
- // boot_order: props.hardDisk.boot_order,
437
- // detach: props.type === 'removed',
438
- // remove: props.type === 'removed' && deleteFilesFromDatastore.value, // Проверяем если удалили диск и указали Delete files from datastore
439
- // })
440
- // },
441
- // { immediate: true }
442
- // )
443
-
444
- // Добавляем данные для редактирования
445
- // watch(
446
- // () => props.hardDisk,
447
- // (newValue) => {
448
- // // TODO refactoring
449
- // if (props.type === 'exist') {
450
- // diskProvisioning.value = newValue.provision_type || 'thick'
451
- // return
452
- // }
453
- // // if (props.type !== 'edit') return
454
- // if (props.type !== 'edit' && props.type !== 'clone') return
455
- //
456
- // const sizeInGb = $binary.mbToGb(newValue.size)
457
- // if (sizeInGb < 1) {
458
- // size.value = newValue.size
459
- // hardDiskType.value = 'mb'
460
- // } else {
461
- // size.value = sizeInGb
462
- // hardDiskType.value = 'gb'
463
- // }
464
- // diskProvisioning.value = newValue.provision_type || 'thick'
465
- // sharing.value = newValue.sharing ? 'yes' : ''
466
- // shares.value = newValue.shares || 0
467
- // // limitIopsType.value = newValue.io === 'native' ? 'unlimited' : 'custom'
468
- // limitIopsType.value = newValue.limit_iops === 0 ? 'unlimited' : 'custom'
469
- // limitIops.value = newValue.limit_iops || 16
470
- // diskMode.value = newValue.disk_mode || 'dependent'
471
- // cache.value = newValue.cache || 'none'
472
- // bus.value = newValue.bus || 'ide'
473
- // readOnly.value = newValue.read_only || false
474
- // discard.value = newValue.discard || ''
475
- // io.value = newValue.io || ''
476
- // target.value = newValue.target || ''
477
- // },
478
- // { immediate: true }
479
- // )
480
- watch(
481
- isRunning,
482
- (newValue) => {
483
- if (newValue && props.type === 'new') {
484
- bus.value = 'virtio'
485
- }
486
- },
487
- { immediate: true }
488
- )
489
-
490
- const hardDiskInvalid = computed<boolean>(() => {
491
- return !!hardDiskTypeErrorLocalText.value || limitIopsInvalid.value
492
- })
493
- watch(
494
- hardDiskInvalid,
495
- (newValue) => {
496
- emits('invalid', newValue)
497
- },
498
- { immediate: true }
499
- )
500
- </script>
501
-
502
- <style scoped lang="scss"></style>
1
+ <template>
2
+ <!--TODO 111-->
3
+ <!-- v-model:vm-storage-policy="vmStoragePolicy"-->
4
+ <component
5
+ :is="currentComponent"
6
+ v-model:delete-files-from-datastore="deleteFilesFromDatastore"
7
+ v-model:size="sizeLocal"
8
+ v-model:hard-disk-type="hardDiskType"
9
+ v-model:disk-provisioning="provisionType"
10
+ v-model:sharing="sharingLocal"
11
+ v-model:limit-iops="limitIops"
12
+ v-model:limit-iops-type="limitIopsType"
13
+ v-model:limit-iops-invalid="limitIopsInvalid"
14
+ v-model:disk-mode="diskMode"
15
+ v-model:cache="cache"
16
+ v-model:bus="bus"
17
+ v-model:source="source"
18
+ :is-removable="isRemovable"
19
+ :label="label"
20
+ :hard-disk-invalid="hardDiskInvalid"
21
+ :error-text="hardDiskLocalAndApiErrorsTexts"
22
+ :hard-disk-type-error-local-text="hardDiskTypeErrorLocalText"
23
+ :is-disabled-size="isDisabledSize"
24
+ :is-disabled-provisioning="isDisabledProvisioning"
25
+ :is-disabled-sharing="isDisabledSharing"
26
+ :is-disabled-limit-iops="isDisabledLimitIops"
27
+ :is-disabled-mode="isDisabledMode"
28
+ :is-disabled-cache="isDisabledCache"
29
+ :is-disabled-bus="isDisabledBus"
30
+ :hard-disk-type-options="hardDiskTypeOptions"
31
+ :max-hard-disk="maxHardDisk"
32
+ :location="location"
33
+ :is-running="isRunning"
34
+ :is-new-hard-disk="isNewHardDisk"
35
+ :is-edit="props.isEdit"
36
+ :datastore="props.datastore"
37
+ :is-datastore-loading="props.isDatastoreLoading"
38
+ :get-datastore-table-func="props.getDatastoreTableFunc"
39
+ :error-validation-fields="props.errorValidationFields"
40
+ :index="props.index"
41
+ :type="props.type"
42
+ :guest-machine-type="props.guestMachineType"
43
+ :compute-resource="props.computeResource"
44
+ @remove="emits('remove')"
45
+ @roll-back="emits('roll-back')"
46
+ @validate-size="onValidateSize"
47
+ @change-storage="onChangeStorage"
48
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
49
+ />
50
+ </template>
51
+
52
+ <script setup lang="ts">
53
+ import type { UI_I_DatastoreTableItem } from '~/lib/models/store/storage/interfaces'
54
+ // import type {
55
+ // UI_I_SendDataNewHardDisk,
56
+ // UI_I_SendDataNewHardDiskStorage,
57
+ // } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
58
+ import type { UI_T_HardDiskType } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/types'
59
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
60
+ import type { UI_I_ErrorValidationField } from '~/lib/models/store/interfaces'
61
+ import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
62
+ import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
63
+ import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
64
+ import type { UI_T_LimitIopsType } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/limitIops/lib/types'
65
+ import { binaryOptionsFunc } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/config/binaryOptions'
66
+ import { minLimitIops } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/limitIops/lib/config/options'
67
+
68
+ const size = defineModel<number>('size', { required: true })
69
+ const initialSize = size.value
70
+ // TODO 111
71
+ // const vmStoragePolicy = defineModel<string>('vmStoragePolicy', { required: true })
72
+ // const provisionType = ref<string>('thick')
73
+ const provisionType = defineModel<string>('provisionType', { required: true })
74
+ // const sharing = ref<string>('')
75
+ const sharing = defineModel<boolean>('sharing', { required: true })
76
+ // const sharingLocal = ref<string>(sharing.value ? 'yes' : '')
77
+ const sharingLocal = computed<string>({
78
+ set(newValue) {
79
+ sharing.value = newValue === 'yes'
80
+ },
81
+ get() {
82
+ return sharing.value ? 'yes' : ''
83
+ },
84
+ })
85
+ // const shares = ref<number>(0)
86
+ const shares = defineModel<number>('shares', { required: true })
87
+
88
+ // const limitIops = ref<number>(16)
89
+ const limitIops = defineModel<number>('limitIops', { required: true })
90
+ const limitIopsType = ref<UI_T_LimitIopsType>(
91
+ !limitIops.value ? 'unlimited' : 'custom'
92
+ )
93
+ watch(limitIopsType, (newValue) => {
94
+ if (newValue === 'custom') limitIops.value = minLimitIops
95
+ else limitIops.value = 0
96
+ })
97
+ watch(
98
+ limitIops,
99
+ (newValue) => {
100
+ if (typeof newValue !== 'number') {
101
+ if (limitIopsType.value === 'custom') limitIops.value = minLimitIops
102
+ else limitIops.value = 0
103
+ }
104
+ },
105
+ { immediate: true }
106
+ )
107
+
108
+ const limitIopsInvalid = ref<boolean>(false) // ??
109
+
110
+ // const diskMode = ref<string>('dependent')
111
+ const diskMode = defineModel<string>('diskMode', { required: true })
112
+
113
+ // const cache = ref<string>('none')
114
+ const cache = defineModel<string>('cache', { required: true })
115
+
116
+ // const bus = ref<string>('ide')
117
+ const bus = defineModel<string>('bus', { required: true })
118
+
119
+ // const readOnly = ref<boolean>(false)
120
+ const readOnly = defineModel<boolean>('readOnly', { required: true })
121
+
122
+ // const discard = ref<string>('')
123
+ const discard = defineModel<string>('discard', { required: true })
124
+
125
+ // const io = ref<string>('')
126
+ const io = defineModel<string>('io', { required: true })
127
+
128
+ // const target = ref<string>('')
129
+ const target = defineModel<string>('target', { required: true })
130
+
131
+ const source = defineModel<string>('source', { required: true })
132
+
133
+ const storage = defineModel<any>('storage', { required: true })
134
+
135
+ const remove = defineModel<boolean>('remove', { required: true })
136
+ const detach = defineModel<boolean>('detach', { required: true })
137
+
138
+ const props = withDefaults(
139
+ defineProps<{
140
+ mainStorage: UI_I_DatastoreTableItem | null
141
+ mainStorageFree: number
142
+ // hardDisk: UI_I_SendDataNewHardDisk
143
+ type: UI_T_HardDiskType
144
+ index: number
145
+ errorValidationFields: UI_I_ErrorValidationField[]
146
+ getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
147
+ datastore: UI_I_DatastoreTableItem[]
148
+ isDatastoreLoading: boolean
149
+ isEdit: boolean
150
+ state?: string | number
151
+ guestMachineType?: UI_I_OptionItem | null
152
+ computeResource?: UI_I_TreeNode | null
153
+ }>(),
154
+ {
155
+ state: undefined,
156
+ guestMachineType: undefined,
157
+ computeResource: undefined,
158
+ }
159
+ )
160
+ const emits = defineEmits<{
161
+ // (event: 'send-data', value: UI_I_SendDataNewHardDisk): void
162
+ (event: 'invalid', value: boolean): void
163
+ (event: 'remove'): void
164
+ (event: 'roll-back'): void
165
+ (event: 'remove-error-by-title', value: string): void
166
+ }>()
167
+
168
+ watch(
169
+ () => props.type,
170
+ (newValue) => {
171
+ detach.value = newValue === 'removed'
172
+ }
173
+ )
174
+
175
+ const { $store, $binary }: any = useNuxtApp()
176
+ const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
177
+ const currentComponent = computed(() =>
178
+ isNewView.value
179
+ ? defineAsyncComponent(() => import('./New.vue'))
180
+ : defineAsyncComponent(() => import('./Old.vue'))
181
+ )
182
+
183
+ const localization = computed<UI_I_Localization>(() => useLocal())
184
+
185
+ const isRunning = computed<boolean>(() => {
186
+ return props.state === 2
187
+ })
188
+
189
+ const isRemovable = computed<boolean>(() => {
190
+ return (
191
+ !props.isEdit ||
192
+ !isRunning.value ||
193
+ (isRunning.value && bus.value === 'virtio')
194
+ )
195
+ })
196
+
197
+ const typeError = computed<string>(() => `disk_devices[${props.index}].size`)
198
+
199
+ const apiErrorLocal = computed<string>(() => {
200
+ return (
201
+ props.errorValidationFields?.find(
202
+ (message) => message.field === typeError.value
203
+ )?.error_message || ''
204
+ )
205
+ })
206
+
207
+ // PC-1796
208
+ // const isNotNewHardDisk = computed<boolean>(
209
+ // () => props.type === 'edit' || props.type === 'removed'
210
+ // )
211
+ const isNewHardDisk = computed<boolean>(
212
+ () => props.type !== 'edit' && props.type !== 'removed'
213
+ )
214
+ const label = computed<string>(() => {
215
+ // if (props.type === 'edit' || props.type === 'removed')
216
+ if (!isNewHardDisk.value)
217
+ return `${localization.value.common.hardDisk} ${props.index + 1}`
218
+
219
+ return `${localization.value.common.newHardDisk} *`
220
+ })
221
+
222
+ const maxHardDisk = computed<number>(() => {
223
+ // // const hardDiskSizeMb = $binary.gbToMb(props.hardDisk.size)
224
+ //
225
+ // if (props.type === 'exist') return initialSize
226
+ //
227
+ // if (!storageLocal.value) return 0
228
+ // const free = (storageLocal.value.capacity.free_mb ||
229
+ // storageLocal.value.free) as number // TODO fix
230
+ //
231
+ // if (props.type === 'edit') return free + initialSize
232
+ //
233
+ // return free
234
+ if (props.type === 'exist') return initialSize
235
+
236
+ if (!storageLocal.value) return 0
237
+
238
+ return props.mainStorageFree + size.value
239
+ })
240
+ const hardDiskTypeErrorLocalText = computed<string>(() => {
241
+ if (size.value > maxHardDisk.value) {
242
+ return localization.value.common.diskCapacitySpecifiedGreater
243
+ }
244
+
245
+ if (size.value <= 0) {
246
+ return localization.value.common.diskCapacityCannotZero
247
+ }
248
+
249
+ return ''
250
+ })
251
+
252
+ const hardDiskLocalAndApiErrorsTexts = computed<string>(() => {
253
+ const localError = hardDiskTypeErrorLocalText.value
254
+ const apiError = apiErrorLocal.value
255
+
256
+ let result = ''
257
+ if (localError && !apiError) result = localError
258
+ if (!localError && apiError) result = apiError
259
+ if (localError && apiError) result = localError + ', ' + apiError
260
+ if (!localError && apiError) result = apiError
261
+
262
+ return result
263
+ })
264
+
265
+ const deleteFilesFromDatastore = ref<boolean>(false)
266
+ watch(deleteFilesFromDatastore, (newValue) => {
267
+ remove.value = props.type === 'removed' && newValue
268
+ })
269
+
270
+ const hardDiskType = ref<string>(size.value < 1024 ? 'mb' : 'gb')
271
+ watch(hardDiskType, (newValue) => {
272
+ size.value = $binary.universalFromTo(sizeLocal.value, newValue, 'mb')
273
+ })
274
+ const hardDiskTypeOptions = ref<UI_I_OptionItem[]>(
275
+ binaryOptionsFunc(localization.value)
276
+ )
277
+
278
+ const sizeLocal = ref<number>(
279
+ size.value < 1024 ? size.value : $binary.mbToGb(size.value)
280
+ )
281
+ watch(sizeLocal, (newValue) => {
282
+ if (hardDiskType.value === 'mb') {
283
+ size.value = newValue
284
+ }
285
+
286
+ size.value = $binary.universalFromTo(newValue, hardDiskType.value, 'mb')
287
+ })
288
+ // const sizeInMb = computed<number>(() => {
289
+ // if (hardDiskType.value === 'mb') {
290
+ // return size.value
291
+ // }
292
+ //
293
+ // return $binary.universalFromTo(size.value, hardDiskType.value, 'mb')
294
+ // })
295
+ const onValidateSize = (): void => {
296
+ if (props.type !== 'edit') return
297
+ if (size.value < initialSize) {
298
+ sizeLocal.value = $binary.universalFromTo(
299
+ initialSize,
300
+ 'mb',
301
+ hardDiskType.value
302
+ )
303
+ }
304
+ }
305
+
306
+ const isDisabledSize = computed<boolean>(() => {
307
+ if (isNewHardDisk.value) return false
308
+ return (
309
+ props.type === 'exist' || (props.type === 'edit' && readOnly.value)
310
+ // (isRunning.value && provisionType.value === 'thick')
311
+ )
312
+ })
313
+ const isDisabledProvisioning = computed<boolean>(() => {
314
+ if (isNewHardDisk.value) return false
315
+ return props.isEdit || isRunning.value
316
+ })
317
+ const isDisabledSharing = computed<boolean>(() => {
318
+ return isRunning.value && !isNewHardDisk.value
319
+ })
320
+ const isDisabledLimitIops = computed<boolean>(() => {
321
+ return isRunning.value && !isNewHardDisk.value
322
+ })
323
+ const isDisabledMode = computed<boolean>(() => {
324
+ return isRunning.value && !isNewHardDisk.value
325
+ })
326
+ const isDisabledCache = computed<boolean>(() => {
327
+ if (isNewHardDisk.value) return false
328
+ return props.isEdit || isRunning.value
329
+ })
330
+ const isDisabledBus = computed<boolean>(() => {
331
+ return !isNewHardDisk.value && isRunning.value
332
+ })
333
+
334
+ const location = ref<UI_I_DatastoreTableItem | null>(props.mainStorage || null)
335
+ const storageLocal = ref<UI_I_DatastoreTableItem | null>(props.mainStorage)
336
+ watch(
337
+ () => props.mainStorage,
338
+ (newValue) => {
339
+ location.value = newValue
340
+ storageLocal.value = newValue
341
+
342
+ storage.value = {
343
+ id: newValue?.id || '',
344
+ name: newValue?.name || '',
345
+ type: newValue?.type_text || '',
346
+ pool: newValue?.pool_name || '',
347
+ user: '',
348
+ endpoint: '',
349
+ password: '',
350
+ protocol: '',
351
+ options: '',
352
+ }
353
+ },
354
+ {
355
+ immediate: true,
356
+ deep: true,
357
+ }
358
+ )
359
+ const onChangeStorage = (item: UI_I_DatastoreTableItem): void => {
360
+ storageLocal.value = item
361
+
362
+ storage.value = {
363
+ id: item?.id || '',
364
+ name: item?.name || '',
365
+ type: item?.type_text || '',
366
+ pool: item?.pool_name || '',
367
+ user: '',
368
+ endpoint: '',
369
+ password: '',
370
+ protocol: '',
371
+ options: '',
372
+ }
373
+ }
374
+
375
+ // const diskProvisioning = ref<string>('thick')
376
+ // const sharing = ref<string>('')
377
+ // const shares = ref<number>(0)
378
+ //
379
+ // const limitIops = ref<number>(16)
380
+ // const limitIopsType = ref<string>('unlimited')
381
+ // const limitIopsInvalid = ref<boolean>(false)
382
+ //
383
+ // const diskMode = ref<string>('dependent')
384
+ //
385
+ // const cache = ref<string>('none')
386
+ //
387
+ // const bus = ref<string>('ide')
388
+ //
389
+ // const readOnly = ref<boolean>(false)
390
+ //
391
+ // const discard = ref<string>('')
392
+ //
393
+ // const io = ref<string>('')
394
+ //
395
+ // const target = ref<string>('')
396
+
397
+ // watch(
398
+ // [
399
+ // sizeInMb,
400
+ // storage,
401
+ // diskProvisioning,
402
+ // sharing,
403
+ // limitIops,
404
+ // limitIopsType,
405
+ // diskMode,
406
+ // cache,
407
+ // bus,
408
+ // deleteFilesFromDatastore,
409
+ // (): void => props.type,
410
+ // ],
411
+ // () => {
412
+ // const limitIopsLocal =
413
+ // limitIopsType.value === 'unlimited' ? 0 : limitIops.value
414
+ // const storageLocal: UI_I_SendDataNewHardDiskStorage = {
415
+ // id: storage.value?.id || '',
416
+ // name: storage.value?.name || '',
417
+ // type: storage.value?.type_text || '',
418
+ // pool: storage.value?.pool_name || '',
419
+ // user: '',
420
+ // endpoint: '',
421
+ // password: '',
422
+ // protocol: '',
423
+ // options: '',
424
+ // }
425
+ //
426
+ // emits('send-data', {
427
+ // create: props.hardDisk.create,
428
+ // attach: props.hardDisk.attach,
429
+ // source: props.hardDisk.source,
430
+ // size: Math.ceil(sizeInMb.value),
431
+ // bus: bus.value,
432
+ // target: target.value,
433
+ // storage: storageLocal,
434
+ // device_type: 'disk',
435
+ // provision_type: diskProvisioning.value,
436
+ // disk_mode: diskMode.value,
437
+ // sharing: sharing.value === 'yes',
438
+ // read_only: readOnly.value,
439
+ // shares: shares.value,
440
+ // cache: cache.value,
441
+ // io: io.value,
442
+ // limit_iops: limitIopsLocal,
443
+ // discard: discard.value,
444
+ // capacity: Math.ceil(sizeInMb.value),
445
+ // boot_order: props.hardDisk.boot_order,
446
+ // detach: props.type === 'removed',
447
+ // remove: props.type === 'removed' && deleteFilesFromDatastore.value, // Проверяем если удалили диск и указали Delete files from datastore
448
+ // })
449
+ // },
450
+ // { immediate: true }
451
+ // )
452
+
453
+ // Добавляем данные для редактирования
454
+ // watch(
455
+ // () => props.hardDisk,
456
+ // (newValue) => {
457
+ // // TODO refactoring
458
+ // if (props.type === 'exist') {
459
+ // diskProvisioning.value = newValue.provision_type || 'thick'
460
+ // return
461
+ // }
462
+ // // if (props.type !== 'edit') return
463
+ // if (props.type !== 'edit' && props.type !== 'clone') return
464
+ //
465
+ // const sizeInGb = $binary.mbToGb(newValue.size)
466
+ // if (sizeInGb < 1) {
467
+ // size.value = newValue.size
468
+ // hardDiskType.value = 'mb'
469
+ // } else {
470
+ // size.value = sizeInGb
471
+ // hardDiskType.value = 'gb'
472
+ // }
473
+ // diskProvisioning.value = newValue.provision_type || 'thick'
474
+ // sharing.value = newValue.sharing ? 'yes' : ''
475
+ // shares.value = newValue.shares || 0
476
+ // // limitIopsType.value = newValue.io === 'native' ? 'unlimited' : 'custom'
477
+ // limitIopsType.value = newValue.limit_iops === 0 ? 'unlimited' : 'custom'
478
+ // limitIops.value = newValue.limit_iops || 16
479
+ // diskMode.value = newValue.disk_mode || 'dependent'
480
+ // cache.value = newValue.cache || 'none'
481
+ // bus.value = newValue.bus || 'ide'
482
+ // readOnly.value = newValue.read_only || false
483
+ // discard.value = newValue.discard || ''
484
+ // io.value = newValue.io || ''
485
+ // target.value = newValue.target || ''
486
+ // },
487
+ // { immediate: true }
488
+ // )
489
+ watch(
490
+ isRunning,
491
+ (newValue) => {
492
+ if (newValue && props.type === 'new') {
493
+ bus.value = 'virtio'
494
+ }
495
+ },
496
+ { immediate: true }
497
+ )
498
+
499
+ const hardDiskInvalid = computed<boolean>(() => {
500
+ return !!hardDiskTypeErrorLocalText.value || limitIopsInvalid.value
501
+ })
502
+ watch(
503
+ hardDiskInvalid,
504
+ (newValue) => {
505
+ emits('invalid', newValue)
506
+ },
507
+ { immediate: true }
508
+ )
509
+ </script>
510
+
511
+ <style scoped lang="scss"></style>