bfg-common 1.5.451 → 1.5.453

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.
@@ -3252,7 +3252,8 @@
3252
3252
  "channels": "Каналы ({0})",
3253
3253
  "metricsNotFound": "Паказчыкі не знойдзены",
3254
3254
  "uploadFolder": "Тэчка загрузкі",
3255
- "uploadFiles": "Запампаваць файлы"
3255
+ "uploadFiles": "Запампаваць файлы",
3256
+ "clickForUse": "Націсніце для выкарыстання"
3256
3257
  },
3257
3258
  "vmWizard": {
3258
3259
  "selectCreationType": "Выберыце тып стварэння",
@@ -3256,7 +3256,8 @@
3256
3256
  "channels": "Channels ({0})",
3257
3257
  "metricsNotFound": "Metrics not found",
3258
3258
  "uploadFolder": "Upload folder",
3259
- "uploadFiles": "Upload files"
3259
+ "uploadFiles": "Upload files",
3260
+ "clickForUse": "Click for use"
3260
3261
  },
3261
3262
  "vmWizard": {
3262
3263
  "selectCreationType": "Select a Creation Type",
@@ -3256,7 +3256,8 @@
3256
3256
  "channels": "Ալիքներ ({0})",
3257
3257
  "metricsNotFound": "Չափանիշները չեն գտնվել",
3258
3258
  "uploadFolder": "Վերբեռնեք թղթապանակը",
3259
- "uploadFiles": "Վերբեռնեք ֆայլեր"
3259
+ "uploadFiles": "Վերբեռնեք ֆայլեր",
3260
+ "clickForUse": "Կտտացրեք օգտագործման համար"
3260
3261
  },
3261
3262
  "vmWizard": {
3262
3263
  "selectCreationType": "Ընտրեք ստեղծման տեսակը",
@@ -3255,7 +3255,8 @@
3255
3255
  "channels": "Арналар ({0})",
3256
3256
  "metricsNotFound": "Көрсеткіштер табылмады",
3257
3257
  "uploadFolder": "Қалтаны жүктеп салу",
3258
- "uploadFiles": "Файлдарды жүктеп салу"
3258
+ "uploadFiles": "Файлдарды жүктеп салу",
3259
+ "clickForUse": "Пайдалану үшін басыңыз"
3259
3260
  },
3260
3261
  "vmWizard": {
3261
3262
  "selectCreationType": "Жасау түрін таңдаңыз",
@@ -3255,7 +3255,8 @@
3255
3255
  "channels": "Каналы ({0})",
3256
3256
  "metricsNotFound": "Метрики не найдены",
3257
3257
  "uploadFolder": "Загрузить папку",
3258
- "uploadFiles": "Загрузить файлы"
3258
+ "uploadFiles": "Загрузить файлы",
3259
+ "clickForUse": "Нажмите для использования"
3259
3260
  },
3260
3261
  "vmWizard": {
3261
3262
  "selectCreationType": "Выбор типа создания",
@@ -3253,7 +3253,8 @@
3253
3253
  "channels": "频道 ({0})",
3254
3254
  "metricsNotFound": "未找到指标",
3255
3255
  "uploadFolder": "上传文件夹",
3256
- "uploadFiles": "上传文件"
3256
+ "uploadFiles": "上传文件",
3257
+ "clickForUse": "点击使用"
3257
3258
  },
3258
3259
  "vmWizard": {
3259
3260
  "selectCreationType": "选择创建类型",
@@ -2906,7 +2906,8 @@
2906
2906
  "channels": "القنوات ({0})",
2907
2907
  "metricsNotFound": "لم يتم العثور على المقاييس",
2908
2908
  "uploadFolder": "تحميل مجلد",
2909
- "uploadFiles": "تحميل ملفات"
2909
+ "uploadFiles": "تحميل ملفات",
2910
+ "clickForUse": "انقر للاستخدام"
2910
2911
  },
2911
2912
  "vmWizard": {
2912
2913
  "devices": "الأجهزة ({0})",
@@ -0,0 +1,440 @@
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 ref="headerEl" class="window-header">
12
+ <slot name="header">
13
+ <div class="window-title">{{ props.title }}</div>
14
+ </slot>
15
+
16
+ <div class="flex-align-center">
17
+ <button class="window-close" @click="onCollapse">
18
+ <ui-icon
19
+ :name="collapseData.isCollapsed ? 'arrow' : 'check-line'"
20
+ class="hide-icon"
21
+ />
22
+ </button>
23
+ <button class="window-close ml-1" @click="onHide">
24
+ <ui-icon name="close" class="close-icon" />
25
+ </button>
26
+ </div>
27
+ </div>
28
+
29
+ <div class="window-content">
30
+ <div v-show="props.loading" class="absolute-center">
31
+ <ui-icon name="spinner" />
32
+ </div>
33
+ <slot></slot>
34
+ <div v-show="isShowContentBlocker" class="content-blocker"></div>
35
+ </div>
36
+
37
+ <!-- Ручки для ресайза -->
38
+ <div
39
+ class="resize-handle resize-top"
40
+ @mousedown="startResize($event, 'top')"
41
+ ></div>
42
+ <div
43
+ class="resize-handle resize-right"
44
+ @mousedown="startResize($event, 'right')"
45
+ ></div>
46
+ <div
47
+ class="resize-handle resize-bottom"
48
+ @mousedown="startResize($event, 'bottom')"
49
+ ></div>
50
+ <div
51
+ class="resize-handle resize-left"
52
+ @mousedown="startResize($event, 'left')"
53
+ ></div>
54
+ <div
55
+ class="resize-handle resize-top-left"
56
+ @mousedown="startResize($event, 'top-left')"
57
+ ></div>
58
+ <div
59
+ class="resize-handle resize-top-right"
60
+ @mousedown="startResize($event, 'top-right')"
61
+ ></div>
62
+ <div
63
+ class="resize-handle resize-bottom-left"
64
+ @mousedown="startResize($event, 'bottom-left')"
65
+ ></div>
66
+ <div
67
+ class="resize-handle resize-bottom-right"
68
+ @mousedown="startResize($event, 'bottom-right')"
69
+ ></div>
70
+ </div>
71
+ </template>
72
+
73
+ <script setup lang="ts">
74
+ import { useDraggable } from '@vueuse/core'
75
+ import type { UI_I_WindowCollapsedData } from '~/components/atoms/window/lib/models/interfaces'
76
+ import {
77
+ minWidth,
78
+ minHeight,
79
+ headerHeight,
80
+ windowPadding,
81
+ } from '~/components/atoms/window/lib/config/config'
82
+
83
+ const props = withDefaults(
84
+ defineProps<{
85
+ top: number
86
+ left: number
87
+ width: number
88
+ height: number
89
+ title: string
90
+ loading?: boolean
91
+ }>(),
92
+ {
93
+ loading: false,
94
+ }
95
+ )
96
+ const emits = defineEmits<{
97
+ (event: 'hide'): void
98
+ }>()
99
+
100
+ const headerEl = ref(null)
101
+ const isShowContentBlocker = ref<boolean>(false)
102
+
103
+ const leftLocal = ref<number>(props.left)
104
+ const topLocal = ref<number>(props.top)
105
+ const widthLocal = ref<number>(Math.max(minWidth, props.width))
106
+ const heightLocal = ref<number>(Math.max(minHeight, props.height))
107
+
108
+ const collapseData = ref<UI_I_WindowCollapsedData>({
109
+ isCollapsed: false,
110
+ cashTop: -1,
111
+ cashLeft: -1,
112
+ cashWidth: -1,
113
+ cashHeight: -1,
114
+ })
115
+
116
+ // Используем vueuse для перетаскивания
117
+ useDraggable(headerEl, {
118
+ initialValue: { x: leftLocal.value, y: topLocal.value },
119
+ onMove({ x: newX, y: newY }) {
120
+ leftLocal.value = newX
121
+ topLocal.value = newY
122
+ },
123
+ onStart() {
124
+ isShowContentBlocker.value = true
125
+ if (!collapseData.value.isCollapsed) {
126
+ collapseData.value.cashTop = topLocal.value
127
+ collapseData.value.cashLeft = leftLocal.value
128
+ collapseData.value.cashWidth = widthLocal.value
129
+ collapseData.value.cashHeight = heightLocal.value
130
+ }
131
+ },
132
+ onEnd() {
133
+ isShowContentBlocker.value = false
134
+ fixPosition()
135
+ },
136
+ })
137
+
138
+ const fixSize = (): void => {
139
+ const globalWindowWidth = window.innerWidth
140
+ const globalWindowHeight = window.innerHeight
141
+
142
+ widthLocal.value = Math.min(
143
+ globalWindowWidth - windowPadding * 2,
144
+ widthLocal.value
145
+ )
146
+ heightLocal.value = Math.min(
147
+ globalWindowHeight - windowPadding * 2,
148
+ heightLocal.value
149
+ )
150
+ }
151
+ const fixPosition = (): void => {
152
+ const globalWindowWidth = window.innerWidth
153
+ const globalWindowHeight = window.innerHeight
154
+ let newX = leftLocal.value
155
+ let newY = topLocal.value
156
+
157
+ if (leftLocal.value + widthLocal.value > globalWindowWidth - windowPadding) {
158
+ newX = globalWindowWidth - widthLocal.value - windowPadding
159
+ } else if (leftLocal.value < windowPadding) {
160
+ newX = windowPadding
161
+ }
162
+
163
+ if (topLocal.value + heightLocal.value / 2 > globalWindowHeight) {
164
+ newY = globalWindowHeight - headerHeight
165
+ collapseData.value.isCollapsed = true
166
+ } else if (
167
+ topLocal.value + heightLocal.value >
168
+ globalWindowHeight - windowPadding
169
+ ) {
170
+ newY = globalWindowHeight - heightLocal.value - windowPadding
171
+ collapseData.value.isCollapsed = false
172
+ } else if (topLocal.value < windowPadding) {
173
+ newY = windowPadding
174
+ collapseData.value.isCollapsed = false
175
+ } else {
176
+ collapseData.value.isCollapsed = false
177
+ }
178
+
179
+ smoothMove(newX, newY)
180
+ }
181
+ const smoothMove = (newX: number, newY: number, duration = 100): void => {
182
+ const startX = leftLocal.value
183
+ const startY = topLocal.value
184
+
185
+ // Время начала анимации
186
+ const startTime = performance.now()
187
+
188
+ // Функция анимации
189
+ const animate = (currentTime: number): void => {
190
+ // Прошедшее время с начала анимации
191
+ const elapsedTime = currentTime - startTime
192
+
193
+ // Прогресс анимации (от 0 до 1)
194
+ const progress = Math.min(elapsedTime / duration, 1)
195
+
196
+ // Вычисляем новые координаты с помощью линейной интерполяции
197
+ leftLocal.value = startX + (newX - startX) * progress
198
+ topLocal.value = startY + (newY - startY) * progress
199
+
200
+ // Если анимация не завершена, продолжаем
201
+ if (progress < 1) {
202
+ requestAnimationFrame(animate)
203
+ }
204
+ }
205
+
206
+ // Запускаем анимацию
207
+ requestAnimationFrame(animate)
208
+ }
209
+
210
+ const onCollapse = (): void => {
211
+ collapseData.value.isCollapsed = !collapseData.value.isCollapsed
212
+
213
+ if (collapseData.value.isCollapsed) {
214
+ collapseData.value.cashTop = topLocal.value
215
+ collapseData.value.cashLeft = leftLocal.value
216
+ collapseData.value.cashWidth = widthLocal.value
217
+ collapseData.value.cashHeight = heightLocal.value
218
+
219
+ const globalWindowWidth = window.innerWidth
220
+ const globalWindowHeight = window.innerHeight
221
+
222
+ widthLocal.value = minWidth
223
+ heightLocal.value = minHeight
224
+ leftLocal.value = globalWindowWidth - widthLocal.value - windowPadding
225
+ topLocal.value = globalWindowHeight - headerHeight
226
+ fixPosition()
227
+ } else {
228
+ leftLocal.value = collapseData.value.cashLeft
229
+ topLocal.value = collapseData.value.cashTop
230
+ widthLocal.value = collapseData.value.cashWidth
231
+ heightLocal.value = collapseData.value.cashHeight
232
+ fixPosition()
233
+ }
234
+ }
235
+
236
+ // Функция для ресайза
237
+ const startResize = (e: any, direction: any): void => {
238
+ e.preventDefault()
239
+
240
+ const startX = e.clientX
241
+ const startY = e.clientY
242
+ const startWidth = widthLocal.value
243
+ const startHeight = heightLocal.value
244
+ const startLeft = leftLocal.value
245
+ const startTop = topLocal.value
246
+
247
+ const onMouseMove = (e: any): void => {
248
+ const deltaX = e.clientX - startX
249
+ const deltaY = e.clientY - startY
250
+
251
+ if (direction.includes('right')) {
252
+ widthLocal.value = Math.max(minWidth, startWidth + deltaX)
253
+ }
254
+ if (direction.includes('bottom')) {
255
+ heightLocal.value = Math.max(minHeight, startHeight + deltaY)
256
+ }
257
+ if (direction.includes('left')) {
258
+ const newWidth = Math.max(minWidth, startWidth - deltaX)
259
+ if (newWidth !== widthLocal.value) {
260
+ leftLocal.value = startLeft + deltaX
261
+ widthLocal.value = newWidth
262
+ }
263
+ }
264
+ if (direction.includes('top')) {
265
+ const newHeight = Math.max(minHeight, startHeight - deltaY)
266
+ if (newHeight !== heightLocal.value) {
267
+ topLocal.value = startTop + deltaY
268
+ heightLocal.value = newHeight
269
+ }
270
+ }
271
+ fixSize()
272
+ }
273
+
274
+ const onMouseUp = (): void => {
275
+ document.removeEventListener('mousemove', onMouseMove)
276
+ document.removeEventListener('mouseup', onMouseUp)
277
+ isShowContentBlocker.value = false
278
+ fixPosition()
279
+ }
280
+
281
+ document.addEventListener('mousemove', onMouseMove)
282
+ document.addEventListener('mouseup', onMouseUp)
283
+ isShowContentBlocker.value = true
284
+ }
285
+
286
+ let resizeTimer: any = null
287
+ const globalWindowResize = (): void => {
288
+ clearTimeout(resizeTimer)
289
+
290
+ resizeTimer = setTimeout(() => {
291
+ fixSize()
292
+ fixPosition()
293
+ }, 250)
294
+ }
295
+ onMounted(() => {
296
+ window.addEventListener('resize', globalWindowResize)
297
+ })
298
+ onUnmounted(() => {
299
+ window.removeEventListener('resize', globalWindowResize)
300
+ })
301
+
302
+ const onHide = (): void => {
303
+ emits('hide')
304
+ }
305
+ </script>
306
+
307
+ <style lang="scss">
308
+ .window-container {
309
+ position: absolute;
310
+ border-radius: 8px;
311
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
312
+ overflow: hidden;
313
+ background-color: #fff;
314
+ display: flex;
315
+ flex-direction: column;
316
+ min-width: 300px;
317
+ min-height: 200px;
318
+ z-index: var(--z-toast);
319
+
320
+ &.loading {
321
+ opacity: 0.5;
322
+ }
323
+
324
+ .window-header {
325
+ background-color: #314351;
326
+ color: white;
327
+ padding: 6px 12px;
328
+ cursor: move;
329
+ user-select: none;
330
+ display: flex;
331
+ justify-content: space-between;
332
+ align-items: center;
333
+
334
+ .window-title {
335
+ font-weight: 500;
336
+ font-size: 16px;
337
+ }
338
+
339
+ .window-close {
340
+ background: none;
341
+ border: none;
342
+ color: #e4e4e4;
343
+ cursor: pointer;
344
+ width: 20px;
345
+ height: 20px;
346
+ display: flex;
347
+ justify-content: center;
348
+ align-items: center;
349
+
350
+ &:hover {
351
+ color: #ffffff;
352
+ }
353
+ }
354
+ }
355
+
356
+ .window-content {
357
+ position: relative;
358
+ flex-grow: 1;
359
+
360
+ .content-blocker {
361
+ position: absolute;
362
+ top: 0;
363
+ left: 0;
364
+ width: 100%;
365
+ height: 100%;
366
+ z-index: 1;
367
+ }
368
+ }
369
+
370
+ .resize-handle {
371
+ position: absolute;
372
+ background: transparent;
373
+ z-index: 10;
374
+
375
+ &.resize-top {
376
+ top: -3px;
377
+ left: 0;
378
+ right: 0;
379
+ height: 6px;
380
+ cursor: n-resize;
381
+ }
382
+
383
+ &.resize-right {
384
+ top: 0;
385
+ right: -3px;
386
+ bottom: 0;
387
+ width: 6px;
388
+ cursor: e-resize;
389
+ }
390
+
391
+ &.resize-bottom {
392
+ bottom: -3px;
393
+ left: 0;
394
+ right: 0;
395
+ height: 6px;
396
+ cursor: s-resize;
397
+ }
398
+
399
+ &.resize-left {
400
+ top: 0;
401
+ left: -3px;
402
+ bottom: 0;
403
+ width: 6px;
404
+ cursor: w-resize;
405
+ }
406
+
407
+ &.resize-top-left {
408
+ top: -6px;
409
+ left: -6px;
410
+ width: 12px;
411
+ height: 12px;
412
+ cursor: nw-resize;
413
+ }
414
+
415
+ &.resize-top-right {
416
+ top: -6px;
417
+ right: -6px;
418
+ width: 12px;
419
+ height: 12px;
420
+ cursor: ne-resize;
421
+ }
422
+
423
+ &.resize-bottom-left {
424
+ bottom: -6px;
425
+ left: -6px;
426
+ width: 12px;
427
+ height: 12px;
428
+ cursor: sw-resize;
429
+ }
430
+
431
+ &.resize-bottom-right {
432
+ bottom: -6px;
433
+ right: -6px;
434
+ width: 12px;
435
+ height: 12px;
436
+ cursor: se-resize;
437
+ }
438
+ }
439
+ }
440
+ </style>
@@ -0,0 +1,4 @@
1
+ export const minWidth = 300
2
+ export const minHeight = 200
3
+ export const windowPadding = 8
4
+ export const headerHeight = 36
@@ -0,0 +1,7 @@
1
+ export interface UI_I_WindowCollapsedData {
2
+ isCollapsed: boolean
3
+ cashTop: number
4
+ cashLeft: number
5
+ cashWidth: number
6
+ cashHeight: number
7
+ }
@@ -53,7 +53,7 @@
53
53
  @submit-options="emits('submit-options', $event)"
54
54
  />
55
55
 
56
- <div v-show="!props.data" class="empty-container">
56
+ <div v-show="!props.data && !props.advancedLoading" class="empty-container">
57
57
  {{
58
58
  localization.inventoryMonitor
59
59
  .noPerformanceCurrentlySelectedMetrics
@@ -16,90 +16,92 @@
16
16
  <atoms-the-icon2 name="drag" class="vmw-drawer__drag-icon" />
17
17
  </div>
18
18
 
19
- <div class="vmw-drawer-header">
20
- <h3>{{ localization.common.consolePanel }}</h3>
21
- <atoms-the-icon
22
- class="vmw-drawer-header__close"
23
- data-id="spice-console-drawer-toggle-icon"
24
- name="close"
25
- @click="toggleDrawer"
26
- />
27
- </div>
19
+ <div class="drawer-content">
20
+ <div class="vmw-drawer-header">
21
+ <h3>{{ localization.common.consolePanel }}</h3>
22
+ <atoms-the-icon
23
+ class="vmw-drawer-header__close"
24
+ data-id="spice-console-drawer-toggle-icon"
25
+ name="close"
26
+ @click="toggleDrawer"
27
+ />
28
+ </div>
28
29
 
29
- <div class="vmw-drawer-body">
30
- <button
31
- class="vmw-drawer-body__btn animation toggle-fullscreen"
32
- data-id="spice-console-drawer-toggle-fullscreen"
33
- @click="emits('toggle-fullscreen')"
34
- >
35
- {{ localization.common.toggleFullscreenMode }}
36
- </button>
37
- <button
38
- class="vmw-drawer-body__btn animation toggle-fullscreen"
39
- @click="emits('send-alt-command')"
40
- >
41
- {{ localization.common.sendAltCommand }}
42
- </button>
43
- <label
44
- v-development="true"
45
- class="vmw-drawer-body__btn animation relative"
46
- >
47
- {{ localization.remoteConsole.uploadFolder }}
48
- <input type="file" webkitdirectory directory multiple />
49
- </label>
50
- <label
51
- v-development="true"
52
- class="vmw-drawer-body__btn animation relative"
53
- >
54
- {{ localization.remoteConsole.uploadFiles }}
55
- <input type="file" multiple />
56
- </label>
57
-
58
- <select
59
- v-model="usbDevice"
60
- v-development="true"
61
- @mouseenter="hover = true"
62
- @mouseleave="hover = false"
63
- @change="onChangeUsbDevice"
64
- >
65
- <option
66
- v-for="item in usbDevices"
67
- :key="item.value"
68
- :value="item.value"
69
- :disabled="item.disabled"
30
+ <div class="vmw-drawer-body">
31
+ <button
32
+ class="vmw-drawer-body__btn animation toggle-fullscreen"
33
+ data-id="spice-console-drawer-toggle-fullscreen"
34
+ @click="emits('toggle-fullscreen')"
70
35
  >
71
- {{ item.label }}
72
- </option>
73
- </select>
74
-
75
- <select
76
- :value="codec"
77
- @mouseenter="hover = true"
78
- @mouseleave="hover = false"
79
- @change="onChangeCodec"
80
- >
81
- <option :value="1">MJPEG</option>
82
- <option :value="2">VP8</option>
83
- <option :value="3">H264</option>
84
- <option :value="4" disabled>VP9</option>
85
- <option :value="5">H265</option>
86
- </select>
87
-
88
- <hr />
89
- <button
90
- class="vmw-drawer-body__btn animation show-keyboard"
91
- @click="onToggleKeyboard"
92
- >
93
- {{ showOrHideKeyboard }}
94
- </button>
95
- </div>
36
+ {{ localization.common.toggleFullscreenMode }}
37
+ </button>
38
+ <button
39
+ class="vmw-drawer-body__btn animation toggle-fullscreen"
40
+ @click="emits('send-alt-command')"
41
+ >
42
+ {{ localization.common.sendAltCommand }}
43
+ </button>
44
+ <label
45
+ v-development="true"
46
+ class="vmw-drawer-body__btn animation relative"
47
+ >
48
+ {{ localization.remoteConsole.uploadFolder }}
49
+ <input type="file" webkitdirectory directory multiple />
50
+ </label>
51
+ <label
52
+ v-development="true"
53
+ class="vmw-drawer-body__btn animation relative"
54
+ >
55
+ {{ localization.remoteConsole.uploadFiles }}
56
+ <input type="file" multiple />
57
+ </label>
58
+
59
+ <select
60
+ v-model="usbDevice"
61
+ v-development="true"
62
+ @mouseenter="hover = true"
63
+ @mouseleave="hover = false"
64
+ @change="onChangeUsbDevice"
65
+ >
66
+ <option
67
+ v-for="item in usbDevices"
68
+ :key="item.value"
69
+ :value="item.value"
70
+ :disabled="item.disabled"
71
+ >
72
+ {{ item.label }}
73
+ </option>
74
+ </select>
75
+
76
+ <select
77
+ :value="codec"
78
+ @mouseenter="hover = true"
79
+ @mouseleave="hover = false"
80
+ @change="onChangeCodec"
81
+ >
82
+ <option :value="1">MJPEG</option>
83
+ <option :value="2">VP8</option>
84
+ <option :value="3">H264</option>
85
+ <option :value="4" disabled>VP9</option>
86
+ <option :value="5">H265</option>
87
+ </select>
88
+
89
+ <hr />
90
+ <button
91
+ class="vmw-drawer-body__btn animation show-keyboard"
92
+ @click="onToggleKeyboard"
93
+ >
94
+ {{ showOrHideKeyboard }}
95
+ </button>
96
+ </div>
96
97
 
97
- <div class="vmw-drawer-footer">
98
- <div class="size-info">
99
- <p class="size-info-text">View size: {{ viewSize }}</p>
100
- <p class="size-info-text">Canvas size: {{ canvasSize }}</p>
98
+ <div class="vmw-drawer-footer">
99
+ <div class="size-info">
100
+ <p class="size-info-text">View size: {{ viewSize }}</p>
101
+ <p class="size-info-text">Canvas size: {{ canvasSize }}</p>
102
+ </div>
103
+ <div id="debug-stream"></div>
101
104
  </div>
102
- <div id="debug-stream"></div>
103
105
  </div>
104
106
  <div v-if="isKeyboardShown">
105
107
  <common-spice-console-keyboard />
@@ -256,7 +258,9 @@ setDefaultDevices()
256
258
  right: -300px;
257
259
  width: 300px;
258
260
  height: 100vh;
259
- padding: 20px;
261
+ display: flex;
262
+ flex-direction: column;
263
+ padding: 20px 0 20px 20px;
260
264
  z-index: var(--z-modal);
261
265
 
262
266
  &.show {
@@ -306,6 +310,10 @@ setDefaultDevices()
306
310
  }
307
311
  }
308
312
 
313
+ .drawer-content {
314
+ overflow: auto;
315
+ padding-right: 20px;
316
+ }
309
317
  .vmw-drawer-header {
310
318
  & h3 {
311
319
  color: #fff;
@@ -1,6 +1,14 @@
1
1
  <template>
2
2
  <div ref="fullScreen" class="spice-console">
3
3
  <div id="vmw" ref="vmScreen" @scroll="onConsoleScroll"></div>
4
+ <div
5
+ v-if="isWindow"
6
+ v-show="isShowBlocker"
7
+ class="blocker"
8
+ @click="onFocus"
9
+ >
10
+ <p class="blocker-text">{{ localization.remoteConsole.clickForUse }}</p>
11
+ </div>
4
12
  <common-spice-console-drawer
5
13
  @toggle-fullscreen="toggle"
6
14
  @send-alt-command="onSendAltCommand"
@@ -11,6 +19,7 @@
11
19
  import { useFullscreen } from '@vueuse/core'
12
20
  import RFB from '@novnc/novnc/core/rfb.js'
13
21
  import SpiceConsole from '~/plugins/spice-console/spice.console'
22
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
14
23
 
15
24
  const props = defineProps<{
16
25
  wsUrl: string
@@ -20,6 +29,8 @@ const props = defineProps<{
20
29
  port: number
21
30
  }>()
22
31
 
32
+ const localization = computed<UI_I_Localization>(() => useLocal())
33
+
23
34
  let rfb: any
24
35
  const vmScreen = ref<any>(null)
25
36
  const fullScreen = ref<any>(null)
@@ -100,14 +111,28 @@ const blockCtrlOrCmdCommands = (e): void => {
100
111
  // return false;
101
112
  // }
102
113
  }
114
+
115
+ const isWindow = computed<boolean>(() => useRoute().query.window === 'true')
116
+ const isShowBlocker = ref<boolean>(true)
117
+ const onFocus = (): void => {
118
+ document.getElementById('inputmanager')?.focus()
119
+ isShowBlocker.value = false
120
+ }
121
+
122
+ const inputManagerBlur = (): void => {
123
+ isShowBlocker.value = true
124
+ }
125
+
103
126
  onMounted(() => {
104
127
  connectWS()
105
128
  document.addEventListener('keydown', blockCtrlOrCmdCommands)
129
+ window.addEventListener('blur', inputManagerBlur)
106
130
  })
107
131
 
108
132
  onBeforeUnmount(() => {
109
133
  vmDisconnect()
110
134
  document.removeEventListener('keydown', blockCtrlOrCmdCommands)
135
+ window.removeEventListener('blur', inputManagerBlur)
111
136
  })
112
137
  </script>
113
138
  <style scoped lang="scss">
@@ -124,4 +149,20 @@ onBeforeUnmount(() => {
124
149
  height: 100vh;
125
150
  background-color: #000;
126
151
  }
152
+ .blocker {
153
+ position: fixed;
154
+ top: 0;
155
+ left: 0;
156
+ width: 100%;
157
+ height: 100%;
158
+ display: flex;
159
+ justify-content: center;
160
+ align-items: center;
161
+ background-color: rgba(0, 0, 0, 0.5);
162
+ z-index: 9999;
163
+
164
+ .blocker-text {
165
+ color: #e4e4e4;
166
+ }
167
+ }
127
168
  </style>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bfg-common",
3
3
  "private": false,
4
- "version": "1.5.451",
4
+ "version": "1.5.453",
5
5
  "scripts": {
6
6
  "build": "nuxt build",
7
7
  "dev": "nuxt dev --port=3002",