bfg-common 1.1.37 → 1.1.39

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 (66) hide show
  1. package/assets/localization/local_be.json +2 -1
  2. package/assets/localization/local_en.json +2 -1
  3. package/assets/localization/local_hy.json +2 -1
  4. package/assets/localization/local_kk.json +2 -1
  5. package/assets/localization/local_ru.json +2 -1
  6. package/assets/localization/local_zh.json +2 -1
  7. package/components/atoms/alert/Notification.vue +167 -167
  8. package/components/atoms/autocomplete/Autocomplete.vue +236 -236
  9. package/components/atoms/datepicker/Datepicker.vue +612 -612
  10. package/components/atoms/list/SelectList.vue +62 -62
  11. package/components/atoms/nav/NavBar.vue +116 -116
  12. package/components/atoms/nav/VerticalNavBar.vue +89 -89
  13. package/components/atoms/notificationBar/NotificationBar.vue +174 -174
  14. package/components/atoms/perPage/PerPage.vue +52 -52
  15. package/components/atoms/popup/SimplePopup.vue +90 -90
  16. package/components/atoms/step/VerticalStep.vue +104 -104
  17. package/components/atoms/switch/Switch.vue +107 -107
  18. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +204 -204
  19. package/components/atoms/table/dataGrid/DataGridPage.vue +189 -189
  20. package/components/atoms/tabs/Tabs.vue +189 -189
  21. package/components/atoms/tooltip/Signpost.vue +224 -224
  22. package/components/common/adapterManager/AddAdapterWarningModal.vue +82 -82
  23. package/components/common/adapterManager/NoActiveAdaptersModal.vue +62 -62
  24. package/components/common/adapterManager/NoConnectedActiveAdaptersModal.vue +62 -62
  25. package/components/common/browse/Browse.vue +182 -182
  26. package/components/common/browse/blocks/Title.vue +66 -66
  27. package/components/common/diagramMain/Diagram.vue +186 -186
  28. package/components/common/diagramMain/DiagramMain.vue +986 -979
  29. package/components/common/diagramMain/adapter/AdapterItem.vue +227 -227
  30. package/components/common/diagramMain/adapter/AdapterItems.vue +57 -57
  31. package/components/common/diagramMain/modals/editSettings/tabs/port/IpvFourSettings.vue +339 -339
  32. package/components/common/diagramMain/modals/editSettings/tabs/port/PortProperties.vue +202 -202
  33. package/components/common/diagramMain/modals/remove/RemoveModal.vue +226 -226
  34. package/components/common/diagramMain/network/Contents.vue +238 -238
  35. package/components/common/feedback/Buttons.vue +232 -232
  36. package/components/common/feedback/Message.vue +468 -468
  37. package/components/common/feedback/VisitPortal.vue +54 -54
  38. package/components/common/help/navbar/left/Left.vue +159 -159
  39. package/components/common/help/navbar/left/utils/constructAccordion.ts +27 -27
  40. package/components/common/mainNavigationPanel/MainNavigationPanel.vue +359 -359
  41. package/components/common/modals/Rename.vue +165 -165
  42. package/components/common/perPage/PerPage.vue +51 -51
  43. package/components/common/recursionTree/RecursionTree.vue +201 -201
  44. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +445 -445
  45. package/components/common/vm/actions/add/select/storage/config/config.ts +154 -154
  46. package/components/common/wizards/datastore/add/nfs/configuration/Configuration.vue +373 -373
  47. package/components/common/wizards/datastore/add/nfs/configuration/serversList/ServersList.vue +123 -123
  48. package/components/common/wizards/datastore/add/nfs/kerberosAuthentication/KerberosAuthentication.vue +54 -54
  49. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/HostTable.vue +131 -131
  50. package/components/common/wizards/datastore/add/sharedStorm/partitionConfiguration/PartitionConfiguration.vue +230 -230
  51. package/models/store/interfaces.ts +37 -37
  52. package/models/store/storage/interfaces.ts +32 -32
  53. package/models/store/types.ts +32 -32
  54. package/modules/fixContentBuild/index.ts +92 -92
  55. package/modules/fixContentBuild/utils/methods.ts +114 -114
  56. package/package.json +1 -1
  57. package/public/spice-console/application/codec.js +257 -257
  58. package/public/spice-console/lib/rasterEngine.js +907 -907
  59. package/public/spice-console/network/spicechannel.js +369 -369
  60. package/public/spice-console-minify/lib/decoder/dixie.min.js +4 -4
  61. package/public/spice-console-minify/lib/jgestures.min.js +24 -24
  62. package/public/spice-console-minify/lib/jquery-2.0.3.min.js +24 -24
  63. package/public/spice-console-minify/lib/jquery-mousewheel.min.js +11 -11
  64. package/public/spice-console-minify/lib/jquery-visibility.min.js +1 -1
  65. package/public/spice-console-minify/lib/lodash.4.0.0.min.js +5 -5
  66. package/utils/contentBuild.ts +34 -34
@@ -1,468 +1,468 @@
1
- <template>
2
- <div class="message">
3
- <div class="main-block">
4
- <span class="text">{{ localization.description }}</span>
5
- <textarea
6
- id="feedback-message-textarea"
7
- v-model="descriptionTextMain"
8
- :disabled="!props.selectedTab"
9
- class="clr-textarea ng-pristine ng-invalid ng-touched textarea"
10
- :placeholder="descriptionTextPlaceholder"
11
- ></textarea>
12
- </div>
13
- <div class="main-block">
14
- <span class="text">{{ localization.emailAddress }} </span>
15
- <input
16
- id="feedback-email-input"
17
- type="email"
18
- class="email"
19
- :placeholder="localization.optionalInCaseWeNeed"
20
- />
21
- </div>
22
- <div class="main-block">
23
- <span class="text">{{ localization.additionalDetails }} </span>
24
- <button
25
- v-if="!hasTakeScreenshot"
26
- id="feedback-take-screenshot-button"
27
- class="btn btn-sm ng-star-inserted"
28
- @click="takeScreenshot"
29
- >
30
- {{ localization.takeScreenshot }}
31
- </button>
32
-
33
- <button
34
- v-else
35
- id="feedback-remove-button"
36
- class="btn btn-sm btn-warning-outline ng-star-inserted"
37
- @click="removeScreenshot"
38
- >
39
- {{ localization.remove }}
40
- </button>
41
- </div>
42
- <template v-if="hasTakeScreenshot">
43
- <div class="main-block main-block__last">
44
- <span class="text"></span>
45
- {{ localization.clickAndDragTheMouseToAnnotate }}
46
- <!-- <a
47
- v-for="tab in drawingPanel"
48
- :key="tab.function"
49
- href="javascript:void(0)"
50
- role="button"
51
- class="content-padding"
52
- @click="tab.function"
53
- >
54
- {{ tab.text }}</a
55
- > -->
56
- <a
57
- id="feedback-use-red-marker-button"
58
- href="javascript:void(0)"
59
- role="button"
60
- class="content-padding"
61
- @click="useRedMarker"
62
- >
63
- {{ localization.useRedMarker }}</a
64
- >
65
- <a
66
- id="feedback-use-grey-marker-button"
67
- href="javascript:void(0)"
68
- role="button"
69
- class="content-padding"
70
- @click="useGrayEraser"
71
- >
72
- {{ localization.useGrayEraser }}</a
73
- >
74
- <a
75
- id="feedback-undo-button"
76
- href="javascript:void(0)"
77
- role="button"
78
- class="content-padding"
79
- @click="undoLast"
80
- >
81
- {{ localization.undo }}</a
82
- >
83
- <a
84
- id="feedback-clear-all-button"
85
- href="javascript:void(0)"
86
- role="button"
87
- class="content-padding"
88
- @click="clearAll"
89
- >
90
- {{ localization.clearAll }}</a
91
- >
92
- </div>
93
- <div class="main-block main-block__last">
94
- <span class="text"></span>
95
- <atoms-alert
96
- v-show="true"
97
- test-id="feedback-message"
98
- status="alert-info"
99
- :items="[localization.screenshotQualityMayVary]"
100
- />
101
- </div>
102
- </template>
103
- <div v-else class="main-block main-block__last">
104
- <span class="text"></span>
105
- <div>
106
- <div class="btn btn-sm loadFile">
107
- <label id="labelFileLoad" for="fileLoad">{{
108
- localization.uploadImage
109
- }}</label>
110
- <input
111
- id="fileLoad"
112
- ref="isFileLoad"
113
- type="file"
114
- accept=".png, .jpeg"
115
- @change="onChangeImgLoad"
116
- />
117
- </div>
118
- <span>{{ localization.pngJpegFilesSupported }}</span>
119
- </div>
120
- </div>
121
-
122
- <div id="feedbackImgWrap" ref="feedbackImgWrap">
123
- <canvas
124
- id="feedbackImg"
125
- ref="feedbackImg"
126
- :class="{ feedbackImg: !hasTakeScreenshot }"
127
- ></canvas>
128
- </div>
129
- </div>
130
- </template>
131
-
132
- <script setup lang="ts">
133
- import html2canvas from 'html2canvas'
134
- import { UI_I_Localization } from '~/models/interfaces'
135
- import { UI_I_MessageImg } from '~/components/common/feedback/models/interfaces'
136
-
137
- const props = defineProps<{
138
- selectedTab: number | null
139
- descriptionTyped: string
140
- }>()
141
- const emits = defineEmits<{
142
- (event: 'screen-shot', value: UI_I_MessageImg): void
143
- (event: 'update:description-typed', value: string): void
144
- }>()
145
-
146
- const descriptionTextMain = computed<string>({
147
- get() {
148
- return props.descriptionTyped
149
- },
150
- set(value) {
151
- emits('update:description-typed', value)
152
- },
153
- })
154
- const localization = computed<UI_I_Localization>(() => useLocal())
155
- // const drawingPanel = computed(() => drawingPanelFunc(localization.value))
156
-
157
- const descriptionTextPlaceholder = computed<string>(() => {
158
- if (props.selectedTab === 1) return localization.value.whatIsTheProblemHowCan
159
- if (props.selectedTab === 2) return localization.value.tellUsWhatYouEnjoyedSo
160
- return localization.value.selectFeedbackType
161
- })
162
- const hasTakeScreenshot = ref<boolean>(false)
163
- const feedbackImgWrap = ref()
164
- const feedbackImg = ref()
165
- const isFileLoad = ref(null)
166
- const memoryParentMain = ref<string>('')
167
- const memoryParentModalDialog = ref<string>('')
168
-
169
- const takeScreenshot = () => {
170
- hasTakeScreenshot.value = true
171
- const value = {
172
- hasTakeScreenshot: true,
173
- width: window.outerWidth + 'px',
174
- }
175
-
176
- emits('screen-shot', value)
177
- const parentMain = document.getElementById('feedbackId')
178
- const parentModalDialog = document.getElementById('feedback-modal-dialog-Id')
179
- if (!parentMain || !parentModalDialog) return
180
-
181
- const display = parentMain.style.display
182
- memoryParentMain.value = parentMain.style.display
183
- parentMain.style.display = 'none'
184
- html2canvas(document.body).then(function (thisCanvas) {
185
- parentMain.style.display = display
186
- memoryParentMain.value = parentMain.style.width
187
- memoryParentModalDialog.value = parentModalDialog.style.width
188
- parentMain.style.width = window.outerWidth + 'px'
189
- parentModalDialog.style.width = window.outerWidth + 'px'
190
- parentModalDialog.style.margin = '20px'
191
- const context = feedbackImg.value.getContext('2d')
192
- feedbackImg.value.width = thisCanvas.width
193
- feedbackImg.value.height = thisCanvas.height
194
- context.drawImage(
195
- thisCanvas,
196
- 0,
197
- 0,
198
- feedbackImg.value.width,
199
- feedbackImg.value.height
200
- )
201
- drawingArray.length = 0
202
- indexArray = 0
203
- drawingArray.push(
204
- context.getImageData(
205
- 0,
206
- 0,
207
- feedbackImg.value.width,
208
- feedbackImg.value.height
209
- )
210
- )
211
- })
212
- }
213
- const removeScreenshot = () => {
214
- hasTakeScreenshot.value = false
215
- const parentMain = document.getElementById('feedbackId')
216
- const parentModalDialog = document.getElementById('feedback-modal-dialog-Id')
217
- if (!parentMain || !parentModalDialog) return
218
-
219
- parentMain.style.width = memoryParentMain.value
220
- parentModalDialog.style.width = memoryParentModalDialog.value
221
- const context = feedbackImg.value.getContext('2d')
222
- context.fillStyle = 'green'
223
- context.fillRect(0, 0, feedbackImg.value.width, feedbackImg.value.height)
224
- feedbackImg.value.width = 0
225
- feedbackImg.value.height = 0
226
- feedbackImgWrap.value.style.width = 0 + 'px'
227
- feedbackImgWrap.value.style.height = 0 + 'px'
228
- const value = {
229
- hasTakeScreenshot: false,
230
- width: memoryParentModalDialog.value,
231
- }
232
- emits('screen-shot', value)
233
- clearAll()
234
- }
235
-
236
- const onChangeImgLoad = () => {
237
- hasTakeScreenshot.value = true
238
- if (!isFileLoad.value) return
239
-
240
- const isFileRead = new FileReader()
241
- if (!isFileRead) return
242
-
243
- isFileRead.readAsDataURL(isFileLoad.value.files[0])
244
- isFileRead.onload = () => {
245
- const img = new Image()
246
- if (!feedbackImg.value) return
247
-
248
- const context = feedbackImg.value.getContext('2d')
249
- img.onload = () => {
250
- feedbackImg.value.width = img.width
251
- feedbackImg.value.height = img.height
252
- context.drawImage(img, 0, 0, img.width, img.height)
253
- drawingArray.length = 0
254
- indexArray = 0
255
- drawingArray.push(
256
- context.getImageData(
257
- 0,
258
- 0,
259
- feedbackImg.value.width,
260
- feedbackImg.value.height
261
- )
262
- )
263
- const value = {
264
- hasTakeScreenshot: true,
265
- width: window.outerWidth + 'px',
266
- }
267
- emits('screen-shot', value)
268
- const parentMain = document.getElementById('feedbackId')
269
- const parentModalDialog = document.getElementById(
270
- 'feedback-modal-dialog-Id'
271
- )
272
- if (!parentMain || !parentModalDialog) return
273
-
274
- parentMain.style.width = window.outerWidth + 'px'
275
- parentModalDialog.style.width = window.outerWidth + 'px'
276
- parentModalDialog.style.margin = '20px'
277
- }
278
- img.src = isFileRead.result
279
- }
280
- }
281
- const drawingArray: any = []
282
- let indexArray = 0 // index of feedbackImg itself
283
- let isDrawing = false
284
- let startDrawingX: number | null = null
285
- let startDrawingY: number | null = null
286
- let drawColor = ''
287
- let drawWidth = ''
288
-
289
- const useRedMarker = () => {
290
- drawColor = '#f76945'
291
- drawWidth = '5'
292
- }
293
- const useGrayEraser = () => {
294
- drawColor = 'lightgray'
295
- drawWidth = '14'
296
- }
297
- const undoLast = () => {
298
- drawColor = ''
299
- drawWidth = ''
300
- const context = feedbackImg.value.getContext('2d')
301
- if (indexArray > 0) {
302
- indexArray -= 1
303
- drawingArray.pop()
304
- context.putImageData(drawingArray[indexArray], 0, 0)
305
- }
306
- }
307
- const clearAll = () => {
308
- const context = feedbackImg.value.getContext('2d')
309
- drawColor = ''
310
- drawWidth = ''
311
- if (indexArray <= 0) return
312
- while (indexArray > 0) {
313
- drawingArray.pop()
314
- indexArray -= 1
315
- context.putImageData(drawingArray[indexArray], 0, 0)
316
- }
317
- }
318
- const start = (event: MouseEvent) => {
319
- if (!drawColor) return
320
- const context = feedbackImg.value.getContext('2d')
321
- const canvasCoordinates = feedbackImg.value.getBoundingClientRect()
322
- startDrawingX = event.pageX - canvasCoordinates.left
323
- startDrawingY = event.pageY - canvasCoordinates.top
324
- isDrawing = true
325
- context.beginPath()
326
- context.moveTo(
327
- event.pageX - canvasCoordinates.left,
328
- event.pageY - canvasCoordinates.top
329
- )
330
- event.preventDefault()
331
- }
332
- const draw = (event: MouseEvent) => {
333
- if (!drawColor) return
334
- const context = feedbackImg.value.getContext('2d')
335
- const canvasCoordinates = feedbackImg.value.getBoundingClientRect()
336
- if (!isDrawing) return
337
- context.lineTo(
338
- event.pageX - canvasCoordinates.left,
339
- event.pageY - canvasCoordinates.top
340
- )
341
- context.strokeStyle = drawColor
342
- context.lineWidth = drawWidth
343
- context.lineCap = 'round'
344
- context.lineJoin = 'round'
345
- context.stroke()
346
- event.preventDefault()
347
- }
348
-
349
- const stop = (event: MouseEvent) => {
350
- if (!drawColor) return
351
-
352
- const context = feedbackImg.value.getContext('2d')
353
- const canvasCoordinates = feedbackImg.value.getBoundingClientRect()
354
- if (!isDrawing) return
355
-
356
- context.stroke()
357
- context.closePath()
358
- isDrawing = false
359
- event.preventDefault()
360
- if (
361
- startDrawingX !== event.pageX - canvasCoordinates.left &&
362
- startDrawingY !== event.pageY - canvasCoordinates.top
363
- ) {
364
- drawingArray.push(
365
- context.getImageData(
366
- 0,
367
- 0,
368
- feedbackImg.value.width,
369
- feedbackImg.value.height
370
- )
371
- )
372
- indexArray += 1
373
- }
374
- }
375
- onMounted(() => {
376
- feedbackImg.value.addEventListener('touchstart', start, false)
377
- feedbackImg.value.addEventListener('touchmove', draw, false)
378
- feedbackImg.value.addEventListener('mousedown', start, false)
379
- feedbackImg.value.addEventListener('mousemove', draw, false)
380
- feedbackImg.value.addEventListener('touchend', stop, false)
381
- feedbackImg.value.addEventListener('mouseup', stop, false)
382
- feedbackImg.value.addEventListener('mouseout', stop, false)
383
- })
384
-
385
- onBeforeUnmount(() => {
386
- removeScreenshot()
387
- feedbackImg.value.removeEventListener('touchstart', start, false)
388
- feedbackImg.value.removeEventListener('touchmove', draw, false)
389
- feedbackImg.value.removeEventListener('mousedown', start, false)
390
- feedbackImg.value.removeEventListener('mousemove', draw, false)
391
- feedbackImg.value.removeEventListener('touchend', stop, false)
392
- feedbackImg.value.removeEventListener('mouseup', stop, false)
393
- feedbackImg.value.removeEventListener('mouseout', stop, false)
394
- })
395
- </script>
396
-
397
- <style scoped lang="scss">
398
- .message {
399
- overflow-x: auto;
400
- .main-block {
401
- display: flex;
402
- flex-direction: row;
403
- align-items: flex-start;
404
- margin-bottom: 20px;
405
- .text {
406
- padding-top: 0px;
407
- min-width: 140px;
408
- margin-right: 10px;
409
- }
410
- .textarea {
411
- height: 150px;
412
- width: 100%;
413
- vertical-align: start;
414
- background-color: var(--modal-bg-color);
415
- }
416
- .email {
417
- width: 100%;
418
- }
419
-
420
- &__last {
421
- margin-top: -20px;
422
- width: 100%;
423
- .content-padding {
424
- padding-left: 4px;
425
- color: var(--a-link-color);
426
- }
427
- }
428
- :deep(.alert.alert-info) {
429
- width: 100%;
430
- }
431
- }
432
- }
433
- .loadFile {
434
- width: fit-content;
435
- margin-right: 10px;
436
- padding: 0;
437
- z-index: 11;
438
- label {
439
- color: inherit;
440
- cursor: pointer;
441
- padding: 0 10px;
442
- line-height: calc(1rem - 1px);
443
- letter-spacing: 0.073em;
444
- font-size: 0.458333rem;
445
- font-weight: 500;
446
- height: 1rem;
447
- padding: 0 0.5rem;
448
- }
449
- input {
450
- width: 0.01px;
451
- height: 0.01px;
452
- opacity: 0;
453
- overflow: hidden;
454
- z-index: -1;
455
- }
456
- }
457
- .feedbackImg {
458
- display: none;
459
- }
460
- </style>
461
- <style>
462
- :root {
463
- --a-link-color: #0072a3;
464
- }
465
- :root.dark-theme {
466
- --a-link-color: #4aaed9;
467
- }
468
- </style>
1
+ <template>
2
+ <div class="message">
3
+ <div class="main-block">
4
+ <span class="text">{{ localization.description }}</span>
5
+ <textarea
6
+ id="feedback-message-textarea"
7
+ v-model="descriptionTextMain"
8
+ :disabled="!props.selectedTab"
9
+ class="clr-textarea ng-pristine ng-invalid ng-touched textarea"
10
+ :placeholder="descriptionTextPlaceholder"
11
+ ></textarea>
12
+ </div>
13
+ <div class="main-block">
14
+ <span class="text">{{ localization.emailAddress }} </span>
15
+ <input
16
+ id="feedback-email-input"
17
+ type="email"
18
+ class="email"
19
+ :placeholder="localization.optionalInCaseWeNeed"
20
+ />
21
+ </div>
22
+ <div class="main-block">
23
+ <span class="text">{{ localization.additionalDetails }} </span>
24
+ <button
25
+ v-if="!hasTakeScreenshot"
26
+ id="feedback-take-screenshot-button"
27
+ class="btn btn-sm ng-star-inserted"
28
+ @click="takeScreenshot"
29
+ >
30
+ {{ localization.takeScreenshot }}
31
+ </button>
32
+
33
+ <button
34
+ v-else
35
+ id="feedback-remove-button"
36
+ class="btn btn-sm btn-warning-outline ng-star-inserted"
37
+ @click="removeScreenshot"
38
+ >
39
+ {{ localization.remove }}
40
+ </button>
41
+ </div>
42
+ <template v-if="hasTakeScreenshot">
43
+ <div class="main-block main-block__last">
44
+ <span class="text"></span>
45
+ {{ localization.clickAndDragTheMouseToAnnotate }}
46
+ <!-- <a
47
+ v-for="tab in drawingPanel"
48
+ :key="tab.function"
49
+ href="javascript:void(0)"
50
+ role="button"
51
+ class="content-padding"
52
+ @click="tab.function"
53
+ >
54
+ {{ tab.text }}</a
55
+ > -->
56
+ <a
57
+ id="feedback-use-red-marker-button"
58
+ href="javascript:void(0)"
59
+ role="button"
60
+ class="content-padding"
61
+ @click="useRedMarker"
62
+ >
63
+ {{ localization.useRedMarker }}</a
64
+ >
65
+ <a
66
+ id="feedback-use-grey-marker-button"
67
+ href="javascript:void(0)"
68
+ role="button"
69
+ class="content-padding"
70
+ @click="useGrayEraser"
71
+ >
72
+ {{ localization.useGrayEraser }}</a
73
+ >
74
+ <a
75
+ id="feedback-undo-button"
76
+ href="javascript:void(0)"
77
+ role="button"
78
+ class="content-padding"
79
+ @click="undoLast"
80
+ >
81
+ {{ localization.undo }}</a
82
+ >
83
+ <a
84
+ id="feedback-clear-all-button"
85
+ href="javascript:void(0)"
86
+ role="button"
87
+ class="content-padding"
88
+ @click="clearAll"
89
+ >
90
+ {{ localization.clearAll }}</a
91
+ >
92
+ </div>
93
+ <div class="main-block main-block__last">
94
+ <span class="text"></span>
95
+ <atoms-alert
96
+ v-show="true"
97
+ test-id="feedback-message"
98
+ status="alert-info"
99
+ :items="[localization.screenshotQualityMayVary]"
100
+ />
101
+ </div>
102
+ </template>
103
+ <div v-else class="main-block main-block__last">
104
+ <span class="text"></span>
105
+ <div>
106
+ <div class="btn btn-sm loadFile">
107
+ <label id="labelFileLoad" for="fileLoad">{{
108
+ localization.uploadImage
109
+ }}</label>
110
+ <input
111
+ id="fileLoad"
112
+ ref="isFileLoad"
113
+ type="file"
114
+ accept=".png, .jpeg"
115
+ @change="onChangeImgLoad"
116
+ />
117
+ </div>
118
+ <span>{{ localization.pngJpegFilesSupported }}</span>
119
+ </div>
120
+ </div>
121
+
122
+ <div id="feedbackImgWrap" ref="feedbackImgWrap">
123
+ <canvas
124
+ id="feedbackImg"
125
+ ref="feedbackImg"
126
+ :class="{ feedbackImg: !hasTakeScreenshot }"
127
+ ></canvas>
128
+ </div>
129
+ </div>
130
+ </template>
131
+
132
+ <script setup lang="ts">
133
+ import html2canvas from 'html2canvas'
134
+ import { UI_I_Localization } from '~/models/interfaces'
135
+ import { UI_I_MessageImg } from '~/components/common/feedback/models/interfaces'
136
+
137
+ const props = defineProps<{
138
+ selectedTab: number | null
139
+ descriptionTyped: string
140
+ }>()
141
+ const emits = defineEmits<{
142
+ (event: 'screen-shot', value: UI_I_MessageImg): void
143
+ (event: 'update:description-typed', value: string): void
144
+ }>()
145
+
146
+ const descriptionTextMain = computed<string>({
147
+ get() {
148
+ return props.descriptionTyped
149
+ },
150
+ set(value) {
151
+ emits('update:description-typed', value)
152
+ },
153
+ })
154
+ const localization = computed<UI_I_Localization>(() => useLocal())
155
+ // const drawingPanel = computed(() => drawingPanelFunc(localization.value))
156
+
157
+ const descriptionTextPlaceholder = computed<string>(() => {
158
+ if (props.selectedTab === 1) return localization.value.whatIsTheProblemHowCan
159
+ if (props.selectedTab === 2) return localization.value.tellUsWhatYouEnjoyedSo
160
+ return localization.value.selectFeedbackType
161
+ })
162
+ const hasTakeScreenshot = ref<boolean>(false)
163
+ const feedbackImgWrap = ref()
164
+ const feedbackImg = ref()
165
+ const isFileLoad = ref(null)
166
+ const memoryParentMain = ref<string>('')
167
+ const memoryParentModalDialog = ref<string>('')
168
+
169
+ const takeScreenshot = () => {
170
+ hasTakeScreenshot.value = true
171
+ const value = {
172
+ hasTakeScreenshot: true,
173
+ width: window.outerWidth + 'px',
174
+ }
175
+
176
+ emits('screen-shot', value)
177
+ const parentMain = document.getElementById('feedbackId')
178
+ const parentModalDialog = document.getElementById('feedback-modal-dialog-Id')
179
+ if (!parentMain || !parentModalDialog) return
180
+
181
+ const display = parentMain.style.display
182
+ memoryParentMain.value = parentMain.style.display
183
+ parentMain.style.display = 'none'
184
+ html2canvas(document.body).then(function (thisCanvas) {
185
+ parentMain.style.display = display
186
+ memoryParentMain.value = parentMain.style.width
187
+ memoryParentModalDialog.value = parentModalDialog.style.width
188
+ parentMain.style.width = window.outerWidth + 'px'
189
+ parentModalDialog.style.width = window.outerWidth + 'px'
190
+ parentModalDialog.style.margin = '20px'
191
+ const context = feedbackImg.value.getContext('2d')
192
+ feedbackImg.value.width = thisCanvas.width
193
+ feedbackImg.value.height = thisCanvas.height
194
+ context.drawImage(
195
+ thisCanvas,
196
+ 0,
197
+ 0,
198
+ feedbackImg.value.width,
199
+ feedbackImg.value.height
200
+ )
201
+ drawingArray.length = 0
202
+ indexArray = 0
203
+ drawingArray.push(
204
+ context.getImageData(
205
+ 0,
206
+ 0,
207
+ feedbackImg.value.width,
208
+ feedbackImg.value.height
209
+ )
210
+ )
211
+ })
212
+ }
213
+ const removeScreenshot = () => {
214
+ hasTakeScreenshot.value = false
215
+ const parentMain = document.getElementById('feedbackId')
216
+ const parentModalDialog = document.getElementById('feedback-modal-dialog-Id')
217
+ if (!parentMain || !parentModalDialog) return
218
+
219
+ parentMain.style.width = memoryParentMain.value
220
+ parentModalDialog.style.width = memoryParentModalDialog.value
221
+ const context = feedbackImg.value.getContext('2d')
222
+ context.fillStyle = 'green'
223
+ context.fillRect(0, 0, feedbackImg.value.width, feedbackImg.value.height)
224
+ feedbackImg.value.width = 0
225
+ feedbackImg.value.height = 0
226
+ feedbackImgWrap.value.style.width = 0 + 'px'
227
+ feedbackImgWrap.value.style.height = 0 + 'px'
228
+ const value = {
229
+ hasTakeScreenshot: false,
230
+ width: memoryParentModalDialog.value,
231
+ }
232
+ emits('screen-shot', value)
233
+ clearAll()
234
+ }
235
+
236
+ const onChangeImgLoad = () => {
237
+ hasTakeScreenshot.value = true
238
+ if (!isFileLoad.value) return
239
+
240
+ const isFileRead = new FileReader()
241
+ if (!isFileRead) return
242
+
243
+ isFileRead.readAsDataURL(isFileLoad.value.files[0])
244
+ isFileRead.onload = () => {
245
+ const img = new Image()
246
+ if (!feedbackImg.value) return
247
+
248
+ const context = feedbackImg.value.getContext('2d')
249
+ img.onload = () => {
250
+ feedbackImg.value.width = img.width
251
+ feedbackImg.value.height = img.height
252
+ context.drawImage(img, 0, 0, img.width, img.height)
253
+ drawingArray.length = 0
254
+ indexArray = 0
255
+ drawingArray.push(
256
+ context.getImageData(
257
+ 0,
258
+ 0,
259
+ feedbackImg.value.width,
260
+ feedbackImg.value.height
261
+ )
262
+ )
263
+ const value = {
264
+ hasTakeScreenshot: true,
265
+ width: window.outerWidth + 'px',
266
+ }
267
+ emits('screen-shot', value)
268
+ const parentMain = document.getElementById('feedbackId')
269
+ const parentModalDialog = document.getElementById(
270
+ 'feedback-modal-dialog-Id'
271
+ )
272
+ if (!parentMain || !parentModalDialog) return
273
+
274
+ parentMain.style.width = window.outerWidth + 'px'
275
+ parentModalDialog.style.width = window.outerWidth + 'px'
276
+ parentModalDialog.style.margin = '20px'
277
+ }
278
+ img.src = isFileRead.result
279
+ }
280
+ }
281
+ const drawingArray: any = []
282
+ let indexArray = 0 // index of feedbackImg itself
283
+ let isDrawing = false
284
+ let startDrawingX: number | null = null
285
+ let startDrawingY: number | null = null
286
+ let drawColor = ''
287
+ let drawWidth = ''
288
+
289
+ const useRedMarker = () => {
290
+ drawColor = '#f76945'
291
+ drawWidth = '5'
292
+ }
293
+ const useGrayEraser = () => {
294
+ drawColor = 'lightgray'
295
+ drawWidth = '14'
296
+ }
297
+ const undoLast = () => {
298
+ drawColor = ''
299
+ drawWidth = ''
300
+ const context = feedbackImg.value.getContext('2d')
301
+ if (indexArray > 0) {
302
+ indexArray -= 1
303
+ drawingArray.pop()
304
+ context.putImageData(drawingArray[indexArray], 0, 0)
305
+ }
306
+ }
307
+ const clearAll = () => {
308
+ const context = feedbackImg.value.getContext('2d')
309
+ drawColor = ''
310
+ drawWidth = ''
311
+ if (indexArray <= 0) return
312
+ while (indexArray > 0) {
313
+ drawingArray.pop()
314
+ indexArray -= 1
315
+ context.putImageData(drawingArray[indexArray], 0, 0)
316
+ }
317
+ }
318
+ const start = (event: MouseEvent) => {
319
+ if (!drawColor) return
320
+ const context = feedbackImg.value.getContext('2d')
321
+ const canvasCoordinates = feedbackImg.value.getBoundingClientRect()
322
+ startDrawingX = event.pageX - canvasCoordinates.left
323
+ startDrawingY = event.pageY - canvasCoordinates.top
324
+ isDrawing = true
325
+ context.beginPath()
326
+ context.moveTo(
327
+ event.pageX - canvasCoordinates.left,
328
+ event.pageY - canvasCoordinates.top
329
+ )
330
+ event.preventDefault()
331
+ }
332
+ const draw = (event: MouseEvent) => {
333
+ if (!drawColor) return
334
+ const context = feedbackImg.value.getContext('2d')
335
+ const canvasCoordinates = feedbackImg.value.getBoundingClientRect()
336
+ if (!isDrawing) return
337
+ context.lineTo(
338
+ event.pageX - canvasCoordinates.left,
339
+ event.pageY - canvasCoordinates.top
340
+ )
341
+ context.strokeStyle = drawColor
342
+ context.lineWidth = drawWidth
343
+ context.lineCap = 'round'
344
+ context.lineJoin = 'round'
345
+ context.stroke()
346
+ event.preventDefault()
347
+ }
348
+
349
+ const stop = (event: MouseEvent) => {
350
+ if (!drawColor) return
351
+
352
+ const context = feedbackImg.value.getContext('2d')
353
+ const canvasCoordinates = feedbackImg.value.getBoundingClientRect()
354
+ if (!isDrawing) return
355
+
356
+ context.stroke()
357
+ context.closePath()
358
+ isDrawing = false
359
+ event.preventDefault()
360
+ if (
361
+ startDrawingX !== event.pageX - canvasCoordinates.left &&
362
+ startDrawingY !== event.pageY - canvasCoordinates.top
363
+ ) {
364
+ drawingArray.push(
365
+ context.getImageData(
366
+ 0,
367
+ 0,
368
+ feedbackImg.value.width,
369
+ feedbackImg.value.height
370
+ )
371
+ )
372
+ indexArray += 1
373
+ }
374
+ }
375
+ onMounted(() => {
376
+ feedbackImg.value.addEventListener('touchstart', start, false)
377
+ feedbackImg.value.addEventListener('touchmove', draw, false)
378
+ feedbackImg.value.addEventListener('mousedown', start, false)
379
+ feedbackImg.value.addEventListener('mousemove', draw, false)
380
+ feedbackImg.value.addEventListener('touchend', stop, false)
381
+ feedbackImg.value.addEventListener('mouseup', stop, false)
382
+ feedbackImg.value.addEventListener('mouseout', stop, false)
383
+ })
384
+
385
+ onBeforeUnmount(() => {
386
+ removeScreenshot()
387
+ feedbackImg.value.removeEventListener('touchstart', start, false)
388
+ feedbackImg.value.removeEventListener('touchmove', draw, false)
389
+ feedbackImg.value.removeEventListener('mousedown', start, false)
390
+ feedbackImg.value.removeEventListener('mousemove', draw, false)
391
+ feedbackImg.value.removeEventListener('touchend', stop, false)
392
+ feedbackImg.value.removeEventListener('mouseup', stop, false)
393
+ feedbackImg.value.removeEventListener('mouseout', stop, false)
394
+ })
395
+ </script>
396
+
397
+ <style scoped lang="scss">
398
+ .message {
399
+ overflow-x: auto;
400
+ .main-block {
401
+ display: flex;
402
+ flex-direction: row;
403
+ align-items: flex-start;
404
+ margin-bottom: 20px;
405
+ .text {
406
+ padding-top: 0px;
407
+ min-width: 140px;
408
+ margin-right: 10px;
409
+ }
410
+ .textarea {
411
+ height: 150px;
412
+ width: 100%;
413
+ vertical-align: start;
414
+ background-color: var(--modal-bg-color);
415
+ }
416
+ .email {
417
+ width: 100%;
418
+ }
419
+
420
+ &__last {
421
+ margin-top: -20px;
422
+ width: 100%;
423
+ .content-padding {
424
+ padding-left: 4px;
425
+ color: var(--a-link-color);
426
+ }
427
+ }
428
+ :deep(.alert.alert-info) {
429
+ width: 100%;
430
+ }
431
+ }
432
+ }
433
+ .loadFile {
434
+ width: fit-content;
435
+ margin-right: 10px;
436
+ padding: 0;
437
+ z-index: 11;
438
+ label {
439
+ color: inherit;
440
+ cursor: pointer;
441
+ padding: 0 10px;
442
+ line-height: calc(1rem - 1px);
443
+ letter-spacing: 0.073em;
444
+ font-size: 0.458333rem;
445
+ font-weight: 500;
446
+ height: 1rem;
447
+ padding: 0 0.5rem;
448
+ }
449
+ input {
450
+ width: 0.01px;
451
+ height: 0.01px;
452
+ opacity: 0;
453
+ overflow: hidden;
454
+ z-index: -1;
455
+ }
456
+ }
457
+ .feedbackImg {
458
+ display: none;
459
+ }
460
+ </style>
461
+ <style>
462
+ :root {
463
+ --a-link-color: #0072a3;
464
+ }
465
+ :root.dark-theme {
466
+ --a-link-color: #4aaed9;
467
+ }
468
+ </style>