bfg-common 1.2.25 → 1.2.26

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 (84) hide show
  1. package/assets/localization/local_be.json +2077 -2081
  2. package/assets/localization/local_en.json +2080 -2084
  3. package/assets/localization/local_hy.json +2080 -2084
  4. package/assets/localization/local_kk.json +2080 -2084
  5. package/assets/localization/local_ru.json +2080 -2084
  6. package/assets/localization/local_zh.json +2080 -2084
  7. package/components/atoms/TheIcon2.vue +355 -1137
  8. package/components/atoms/alert/Notification.vue +167 -167
  9. package/components/atoms/autocomplete/Autocomplete.vue +236 -236
  10. package/components/atoms/datepicker/Datepicker.vue +612 -612
  11. package/components/atoms/list/SelectList.vue +62 -62
  12. package/components/atoms/nav/NavBar.vue +116 -116
  13. package/components/atoms/nav/VerticalNavBar.vue +89 -89
  14. package/components/atoms/notificationBar/NotificationBar.vue +175 -175
  15. package/components/atoms/perPage/PerPage.vue +52 -52
  16. package/components/atoms/popup/SimplePopup.vue +90 -90
  17. package/components/atoms/step/VerticalStep.vue +104 -104
  18. package/components/atoms/switch/Switch.vue +107 -107
  19. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +206 -206
  20. package/components/atoms/table/dataGrid/DataGridPage.vue +189 -189
  21. package/components/atoms/tabs/Tabs.vue +189 -189
  22. package/components/atoms/tooltip/Signpost.vue +224 -224
  23. package/components/common/adapterManager/AddAdapterWarningModal.vue +82 -82
  24. package/components/common/adapterManager/NoActiveAdaptersModal.vue +62 -62
  25. package/components/common/adapterManager/NoConnectedActiveAdaptersModal.vue +62 -62
  26. package/components/common/browse/Browse.vue +182 -182
  27. package/components/common/browse/blocks/Title.vue +66 -66
  28. package/components/common/diagramMain/Diagram.vue +186 -186
  29. package/components/common/diagramMain/DiagramMain.vue +986 -986
  30. package/components/common/diagramMain/adapter/AdapterItem.vue +227 -227
  31. package/components/common/diagramMain/adapter/AdapterItems.vue +57 -57
  32. package/components/common/diagramMain/modals/editSettings/tabs/port/IpvFourSettings.vue +339 -339
  33. package/components/common/diagramMain/modals/editSettings/tabs/port/PortProperties.vue +202 -202
  34. package/components/common/diagramMain/modals/remove/RemoveModal.vue +226 -226
  35. package/components/common/diagramMain/network/Contents.vue +238 -238
  36. package/components/common/feedback/Buttons.vue +232 -232
  37. package/components/common/feedback/Message.vue +468 -468
  38. package/components/common/feedback/VisitPortal.vue +54 -54
  39. package/components/common/help/navbar/left/Left.vue +159 -159
  40. package/components/common/help/navbar/left/utils/constructAccordion.ts +27 -27
  41. package/components/common/mainNavigationPanel/MainNavigationPanel.vue +359 -359
  42. package/components/common/modals/Rename.vue +165 -165
  43. package/components/common/perPage/PerPage.vue +51 -51
  44. package/components/common/recursionTree/RecursionTree.vue +201 -201
  45. package/components/common/vm/actions/add/config/capabilities.ts +338 -338
  46. package/components/common/vm/actions/add/customizeHardware/virtualHardware/VirtualHardware.vue +657 -657
  47. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/CoresPerSocket.vue +109 -109
  48. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/Cpu.vue +383 -383
  49. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/Limit.vue +234 -234
  50. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/config/options.ts +28 -28
  51. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/Memory.vue +316 -316
  52. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/config/memoryOptions.ts +35 -35
  53. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +445 -445
  54. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +288 -288
  55. package/components/common/vm/actions/add/customizeHardware/virtualHardware/reservation/Reservation.vue +235 -235
  56. package/components/common/vm/actions/add/customizeHardware/virtualHardware/videoCard/VideoCard.vue +177 -177
  57. package/components/common/vm/actions/add/customizeHardware/vmoptions/bootOptions/order/Order.vue +197 -197
  58. package/components/common/vm/actions/add/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +181 -181
  59. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/CopyPaste.vue +51 -51
  60. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/RemoteConsoleOptions.vue +253 -253
  61. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +55 -55
  62. package/components/common/vm/actions/add/select/storage/config/config.ts +154 -154
  63. package/components/common/vm/actions/clone/Clone.vue +544 -544
  64. package/components/common/vm/actions/clone/select/options/Options.vue +65 -65
  65. package/components/common/vm/actions/clone/utils.ts +43 -43
  66. package/components/common/wizards/datastore/add/nfs/configuration/Configuration.vue +373 -373
  67. package/components/common/wizards/datastore/add/nfs/configuration/serversList/ServersList.vue +123 -123
  68. package/components/common/wizards/datastore/add/nfs/kerberosAuthentication/KerberosAuthentication.vue +54 -54
  69. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/HostTable.vue +131 -131
  70. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/config/tableKeys.ts +2 -2
  71. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/models/types.ts +2 -2
  72. package/components/common/wizards/datastore/add/sharedStorm/partitionConfiguration/PartitionConfiguration.vue +230 -230
  73. package/composables/useLocal.ts +38 -38
  74. package/minify.js +146 -146
  75. package/models/store/interfaces.ts +37 -37
  76. package/models/store/storage/interfaces.ts +32 -32
  77. package/models/store/types.ts +32 -32
  78. package/modules/fixContentBuild/utils/methods.ts +114 -114
  79. package/package.json +1 -1
  80. package/public/spice-console/application/codec.js +257 -257
  81. package/public/spice-console/lib/rasterEngine.js +907 -907
  82. package/public/spice-console/network/spicechannel.js +369 -369
  83. package/utils/contentBuild.ts +34 -34
  84. package/components/common/BadBrowser.vue +0 -95
@@ -1,612 +1,612 @@
1
- <template>
2
- <div class="container-datepicker">
3
- <atoms-the-icon
4
- name="calendar"
5
- :class="[`btn-show-calendar calendar-id-${uniqueId}`]"
6
- @click.stop="showHideCalendar"
7
- />
8
- <div
9
- v-show="isShowCalendar"
10
- class="the-datepicer"
11
- :style="[{ top: calendarTop + 'px' }, { left: calendarLeft + 'px' }]"
12
- @click.stop
13
- >
14
- <div v-show="showAllMonths" class="content-month">
15
- <div class="all-months">
16
- <div
17
- v-for="(item, key) in allMonths"
18
- :key="key"
19
- :class="['calendar-btn', item.class]"
20
- @click="selectMonth(key)"
21
- >
22
- {{ item.text }}
23
- </div>
24
- </div>
25
- </div>
26
- <div v-show="showAllYears" class="content-years">
27
- <div class="content-buttons-arrow">
28
- <button
29
- :id="`${props.testId}-prev-button`"
30
- class="calendar-btn"
31
- title="Previous decade"
32
- @click="prevYear"
33
- >
34
- <atoms-the-icon
35
- name="arrow"
36
- fill="#0095d3"
37
- class="arrow-btn prev"
38
- />
39
- </button>
40
- <button
41
- :id="`${props.testId}-current-year-button`"
42
- class="calendar-btn set-current-data"
43
- title="Current decade"
44
- @click="setCurrentYear"
45
- >
46
- <atoms-the-icon name="calendar-current-date" class="current-btn" />
47
- </button>
48
- <button
49
- :id="`${props.testId}-next-button`"
50
- class="calendar-btn"
51
- title="Next decade"
52
- @click="nextYear"
53
- >
54
- <atoms-the-icon
55
- name="arrow"
56
- fill="#0095d3"
57
- class="arrow-btn next"
58
- />
59
- </button>
60
- </div>
61
- <div class="all-years">
62
- <div
63
- v-for="(item, key) in allYears"
64
- :key="key"
65
- :class="['calendar-btn', item.class]"
66
- @click="selectYear(item.text)"
67
- >
68
- {{ item.text }}
69
- </div>
70
- </div>
71
- </div>
72
- <div v-if="!showAllMonths && !showAllYears" class="main-content">
73
- <div class="the-month">
74
- <div class="date top-menu">
75
- <button
76
- :id="`${props.testId}-current-month-button`"
77
- class="calendar-btn show-all-months"
78
- title="Select Month"
79
- @click="showAllMonths = true"
80
- >
81
- {{ currentMonth }}
82
- </button>
83
- <button
84
- :id="`${props.testId}-current-year-button`"
85
- class="calendar-btn current-year"
86
- title="Select Year"
87
- @click="showAllYears = true"
88
- >
89
- {{ currentYear }}
90
- </button>
91
- </div>
92
- <div class="content-buttons-arrow">
93
- <button
94
- :id="`${props.testId}-prev-month-button`"
95
- class="calendar-btn"
96
- title="Previous Month"
97
- @click="prevMonth"
98
- >
99
- <atoms-the-icon
100
- name="arrow"
101
- fill="#0095d3"
102
- class="arrow-btn prev"
103
- />
104
- </button>
105
- <button
106
- :id="`${props.testId}-current-date-button`"
107
- class="calendar-btn set-current-data"
108
- title="Current Month"
109
- @click="setCurrentDate"
110
- >
111
- <atoms-the-icon
112
- name="calendar-current-date"
113
- class="current-btn"
114
- />
115
- </button>
116
- <button
117
- :id="`${props.testId}-next-month-icon`"
118
- class="calendar-btn"
119
- title="Next Month"
120
- @click="nextMonth"
121
- >
122
- <atoms-the-icon
123
- name="arrow"
124
- fill="#0095d3"
125
- class="arrow-btn next"
126
- />
127
- </button>
128
- </div>
129
- </div>
130
- <div class="bottom-panel">
131
- <div class="weekdays">
132
- <div v-for="(item, key) in weekdays" :key="key">{{ item }}</div>
133
- </div>
134
- <div class="days">
135
- <div
136
- v-for="(item, key) in days"
137
- :key="key"
138
- :class="['item-day', item.class]"
139
- @click="selectDay(item.text, item.class)"
140
- >
141
- {{ item.text }}
142
- </div>
143
- </div>
144
- </div>
145
- </div>
146
- </div>
147
- </div>
148
- </template>
149
-
150
- <script setup lang="ts">
151
- import { UI_I_Localization } from '~/models/interfaces'
152
- import { UI_I_Items } from '~/components/atoms/datepicker/models/interfaces'
153
- import {
154
- getMonthsFunc,
155
- getWeekdaysFunc,
156
- } from '~/components/atoms/datepicker/config/datapicker'
157
- import { getShortMonths } from '~/components/atoms/datepicker/config/allShortMonths'
158
-
159
- const { $isDate } = useNuxtApp()
160
-
161
- const localization = computed<UI_I_Localization>(() => useLocal())
162
-
163
- const props = withDefaults(
164
- defineProps<{
165
- testId?: string
166
- modelValue: number
167
- lang: string
168
- }>(),
169
- { testId: 'ui-datepicker' }
170
- )
171
- const emits = defineEmits<{
172
- (event: 'update:model-value', num: number): void
173
- (event: 'update', num: number): void
174
- }>()
175
-
176
- const interfaceLang = computed<string>(() => props.lang)
177
-
178
- let isEnabledEmit = false
179
- const checkingDate = computed<Date>({
180
- get() {
181
- return new Date(props.modelValue)
182
- },
183
- set(newValue) {
184
- if (isEnabledEmit) {
185
- const newDate = new Date(newValue).getTime()
186
- emits('update:model-value', newDate)
187
- emits('update', newDate)
188
- isEnabledEmit = false
189
- if ($isDate(newValue.toString())) {
190
- renderCalendar()
191
- }
192
- }
193
- },
194
- })
195
-
196
- const currentYear = ref<number>()
197
- const currentMonth = ref<string>()
198
- const showAllYears = ref<boolean>(false)
199
- const showAllMonths = ref<boolean>(false)
200
- const selectedMonth = ref<number>(new Date().getMonth())
201
-
202
- const days = ref<UI_I_Items[]>([])
203
- const months = computed<string[]>(() => getMonthsFunc(localization.value))
204
- const weekdays = computed<string[]>(() => {
205
- const language = interfaceLang.value
206
- return getWeekdaysFunc(localization.value, language)
207
- })
208
-
209
- const renderCalendar = () => {
210
- checkingDate.value.setDate(1)
211
- days.value = []
212
-
213
- const lastDay = new Date(
214
- checkingDate.value.getFullYear(),
215
- checkingDate.value.getMonth() + 1,
216
- 0
217
- ).getDate()
218
-
219
- const prevLastDay = new Date(
220
- checkingDate.value.getFullYear(),
221
- checkingDate.value.getMonth(),
222
- 0
223
- ).getDate()
224
-
225
- const firstDayIndex = checkingDate.value.getDay()
226
- const language = interfaceLang.value
227
- const firstDayIndexByLanguage =
228
- language === 'en_US' ? firstDayIndex : firstDayIndex - 1
229
-
230
- const shortMonths = getShortMonths(language)
231
-
232
- currentMonth.value = shortMonths[checkingDate.value.getMonth()]
233
-
234
- currentYear.value = checkingDate.value.getFullYear()
235
-
236
- for (let x = firstDayIndexByLanguage; x > 0; x--) {
237
- const result = prevLastDay - x + 1
238
- days.value.push({
239
- text: result,
240
- class: 'prev-date',
241
- })
242
- }
243
- const indexCurrentMonth = shortMonths.findIndex(
244
- (x) => x === currentMonth.value
245
- )
246
-
247
- for (let i = 1; i <= lastDay; i++) {
248
- if (
249
- i === new Date(props.modelValue).getDate() &&
250
- new Date(props.modelValue).getMonth() === indexCurrentMonth &&
251
- new Date(props.modelValue).getFullYear() === currentYear.value
252
- ) {
253
- days.value.push({
254
- text: i,
255
- class: 'active',
256
- })
257
- } else if (
258
- i === new Date().getDate() &&
259
- indexCurrentMonth === new Date().getMonth() &&
260
- currentYear.value === new Date().getFullYear()
261
- ) {
262
- days.value.push({
263
- text: i,
264
- class: 'today',
265
- })
266
- } else {
267
- days.value.push({ text: i, class: '' })
268
- }
269
- }
270
-
271
- const x = 42 - days.value.length
272
- for (let j = 1; j <= x; j++) {
273
- days.value.push({
274
- text: j,
275
- class: 'next-date',
276
- })
277
- }
278
- }
279
-
280
- const allMonths = computed<UI_I_Items[]>(() => {
281
- const result = []
282
- for (let i = 0; i < months.value.length; i++) {
283
- const active = i + 1 === selectedMonth.value + 1 ? 'active' : ''
284
- result.push({
285
- text: months.value[i],
286
- class: active,
287
- })
288
- }
289
- return result
290
- })
291
-
292
- const firstYear = ref<number>(
293
- Number(checkingDate.value.getFullYear().toString().slice(0, 3) + 0)
294
- )
295
- const allYears = computed<UI_I_Items[]>(() => {
296
- const result = []
297
- for (let i = firstYear.value; i < firstYear.value + 10; i++) {
298
- const active = i === currentYear.value ? 'active' : ''
299
- result.push({
300
- text: i,
301
- class: active,
302
- })
303
- }
304
- return result
305
- })
306
- const prevYear = (): void => {
307
- firstYear.value = firstYear.value - 10
308
- }
309
- const nextYear = (): void => {
310
- firstYear.value = firstYear.value + 10
311
- }
312
- const setCurrentYear = (): void => {
313
- firstYear.value = Number(
314
- checkingDate.value.getFullYear().toString().slice(0, 3) + 0
315
- )
316
- }
317
- const selectYear = (value: number): void => {
318
- checkingDate.value = new Date(checkingDate.value.setFullYear(value))
319
- renderCalendar()
320
- showAllYears.value = false
321
- }
322
-
323
- const prevMonth = (): void => {
324
- checkingDate.value.setMonth(checkingDate.value.getMonth() - 1)
325
-
326
- renderCalendar()
327
- }
328
- const nextMonth = (): void => {
329
- checkingDate.value.setMonth(checkingDate.value.getMonth() + 1)
330
-
331
- renderCalendar()
332
- }
333
- const setCurrentDate = (): void => {
334
- isEnabledEmit = true
335
- checkingDate.value = new Date()
336
-
337
- setTimeout(() => {
338
- renderCalendar()
339
- }, 0)
340
- }
341
-
342
- const selectMonth = (value: number): void => {
343
- checkingDate.value = new Date(checkingDate.value.setMonth(value))
344
- selectedMonth.value = value
345
- showAllMonths.value = false
346
-
347
- renderCalendar()
348
- }
349
- const selectDay = (value: number | string, type: string): void => {
350
- isEnabledEmit = true
351
- if (type === 'prev-date') {
352
- checkingDate.value = new Date(
353
- checkingDate.value.setMonth(checkingDate.value.getMonth() - 1)
354
- )
355
- } else if (type === 'next-date') {
356
- checkingDate.value = new Date(
357
- checkingDate.value.setMonth(checkingDate.value.getMonth() + 1)
358
- )
359
- }
360
- checkingDate.value = new Date(checkingDate.value.setDate(+value))
361
-
362
- isShowCalendar.value = false
363
- }
364
-
365
- const isShowCalendar = ref<boolean>(false)
366
-
367
- const uniqueId = ref<number>(0)
368
- const calendarTop = ref<number>()
369
- const calendarLeft = ref<number>()
370
- const showHideCalendar = (): void => {
371
- const allDatePickers = document.querySelectorAll('.the-datepicer')
372
- allDatePickers.forEach((element: any) => (element.style.display = 'none'))
373
- const element = document.querySelector(
374
- `.calendar-id-${uniqueId.value}`
375
- ) as HTMLElement
376
-
377
- calendarTop.value = element.getBoundingClientRect().y - 314 + 2
378
- calendarLeft.value = element.getBoundingClientRect().x - 278 / 2
379
-
380
- isShowCalendar.value = !isShowCalendar.value
381
- }
382
-
383
- const windowClick = (): void => {
384
- isShowCalendar.value = false
385
- }
386
-
387
- const bodyScroll = (): void => {
388
- isShowCalendar.value = false
389
- }
390
-
391
- onMounted(() => {
392
- renderCalendar()
393
- window.addEventListener('click', windowClick)
394
- uniqueId.value = useUniqueId()
395
- })
396
- onUnmounted(() => {
397
- window.removeEventListener('scroll', windowClick)
398
- })
399
-
400
- watch(isShowCalendar, (value) => {
401
- if (value) {
402
- checkingDate.value.setMonth(new Date(props.modelValue).getMonth())
403
- checkingDate.value.setFullYear(new Date(props.modelValue).getFullYear())
404
- renderCalendar()
405
- window.addEventListener('scroll', bodyScroll, true)
406
- } else window.removeEventListener('scroll', bodyScroll, true)
407
- })
408
- </script>
409
-
410
- <style scoped lang="scss">
411
- .item-day {
412
- font-size: 13px;
413
- width: 36px;
414
- height: 36px;
415
- display: flex;
416
- justify-content: center;
417
- align-items: center;
418
- transition: background-color 0.2s;
419
- cursor: pointer;
420
- border-radius: 0.15rem;
421
- }
422
- .container-datepicker {
423
- background: unset;
424
-
425
- .the-datepicer {
426
- width: 278px;
427
- height: 314px;
428
- border: 1px solid var(--vertical-nav-hover-bg-color);
429
- border-radius: 0.15rem;
430
- box-shadow: 0 1px 2.4px hsl(0deg 0% 45% / 25%);
431
- padding: 12px;
432
- position: fixed;
433
- z-index: 1050;
434
- background-color: var(--modal-other-bg-color);
435
-
436
- .content-month {
437
- .all-months {
438
- display: grid;
439
- grid-template-columns: 1fr 1fr;
440
-
441
- .calendar-btn {
442
- width: 100%;
443
- height: 48px;
444
- display: flex;
445
- justify-content: center;
446
- align-items: center;
447
- color: var(--checkbox-label-color);
448
- }
449
- .active {
450
- background: var(--vertical-nav-hover-bg-color);
451
- color: var(--form-input-color);
452
- }
453
- }
454
- }
455
- .content-years {
456
- .content-buttons-arrow {
457
- max-width: 108px;
458
- margin: 0 auto;
459
- }
460
- .all-years {
461
- display: grid;
462
- grid-template-columns: 1fr 1fr;
463
-
464
- .calendar-btn {
465
- width: 100%;
466
- height: 48px;
467
- color: var(--checkbox-label-color);
468
- display: flex;
469
- justify-content: center;
470
- align-items: center;
471
- }
472
- .active {
473
- background: var(--vertical-nav-hover-bg-color);
474
- color: var(--form-input-color);
475
- }
476
- }
477
- }
478
- .main-content {
479
- .the-month {
480
- height: 36px;
481
- display: flex;
482
- justify-content: space-between;
483
- align-items: center;
484
- text-align: center;
485
-
486
- i {
487
- font-size: 29px;
488
- cursor: pointer;
489
- }
490
- h1 {
491
- font-size: 3rem;
492
- font-weight: 400;
493
- text-transform: uppercase;
494
- letter-spacing: 0.2rem;
495
- margin-bottom: 1rem;
496
- }
497
- p {
498
- font-size: 1.6rem;
499
- }
500
-
501
- .top-menu {
502
- display: flex;
503
- align-items: center;
504
- }
505
- }
506
-
507
- .bottom-panel {
508
- .weekdays {
509
- display: flex;
510
- align-items: center;
511
-
512
- div {
513
- font-size: 12px;
514
- font-weight: bold;
515
- letter-spacing: 0.1rem;
516
- width: 36px;
517
- height: 36px;
518
- display: flex;
519
- justify-content: center;
520
- align-items: center;
521
- color: var(--checkbox-label-color);
522
- }
523
- }
524
- .days {
525
- width: 100%;
526
- display: flex;
527
- flex-wrap: wrap;
528
-
529
- .item-day {
530
- font-size: 13px;
531
- width: 36px;
532
- height: 36px;
533
- display: flex;
534
- justify-content: center;
535
- align-items: center;
536
- transition: background-color 0.2s;
537
- cursor: pointer;
538
- border-radius: 0.15rem;
539
- color: var(--checkbox-label-color);
540
-
541
- &:not(.prev-date):not(.today):hover {
542
- background: #eee;
543
- }
544
- &.active {
545
- background: #d9e4ea;
546
- color: #000;
547
- font-weight: bold;
548
- }
549
- &.today {
550
- color: var(--blue-950);
551
- font-weight: bold;
552
- }
553
- &.prev-date,
554
- &.next-date {
555
- opacity: 0.5;
556
- }
557
- }
558
- }
559
- }
560
- }
561
- }
562
-
563
- .calendar-btn {
564
- width: 48px;
565
- height: 36px;
566
- color: #0095d3;
567
- text-align: center;
568
- white-space: nowrap;
569
- overflow: hidden;
570
- text-overflow: ellipsis;
571
- background: unset;
572
- border: none;
573
- cursor: pointer;
574
- font-size: 18px;
575
- border-radius: 3px;
576
-
577
- &:hover {
578
- background: #eee;
579
- }
580
- }
581
-
582
- .content-buttons-arrow {
583
- display: flex;
584
- align-items: center;
585
- justify-content: space-between;
586
-
587
- .icons {
588
- color: #0095d3;
589
- }
590
-
591
- .calendar-btn {
592
- width: 40px;
593
- height: 40px;
594
- display: flex;
595
- align-items: center;
596
- justify-content: center;
597
- }
598
- }
599
-
600
- .arrow-btn {
601
- width: 18px;
602
- height: 18px;
603
-
604
- &.prev {
605
- transform: rotate(-90deg);
606
- }
607
- &.next {
608
- transform: rotate(90deg);
609
- }
610
- }
611
- }
612
- </style>
1
+ <template>
2
+ <div class="container-datepicker">
3
+ <atoms-the-icon
4
+ name="calendar"
5
+ :class="[`btn-show-calendar calendar-id-${uniqueId}`]"
6
+ @click.stop="showHideCalendar"
7
+ />
8
+ <div
9
+ v-show="isShowCalendar"
10
+ class="the-datepicer"
11
+ :style="[{ top: calendarTop + 'px' }, { left: calendarLeft + 'px' }]"
12
+ @click.stop
13
+ >
14
+ <div v-show="showAllMonths" class="content-month">
15
+ <div class="all-months">
16
+ <div
17
+ v-for="(item, key) in allMonths"
18
+ :key="key"
19
+ :class="['calendar-btn', item.class]"
20
+ @click="selectMonth(key)"
21
+ >
22
+ {{ item.text }}
23
+ </div>
24
+ </div>
25
+ </div>
26
+ <div v-show="showAllYears" class="content-years">
27
+ <div class="content-buttons-arrow">
28
+ <button
29
+ :id="`${props.testId}-prev-button`"
30
+ class="calendar-btn"
31
+ title="Previous decade"
32
+ @click="prevYear"
33
+ >
34
+ <atoms-the-icon
35
+ name="arrow"
36
+ fill="#0095d3"
37
+ class="arrow-btn prev"
38
+ />
39
+ </button>
40
+ <button
41
+ :id="`${props.testId}-current-year-button`"
42
+ class="calendar-btn set-current-data"
43
+ title="Current decade"
44
+ @click="setCurrentYear"
45
+ >
46
+ <atoms-the-icon name="calendar-current-date" class="current-btn" />
47
+ </button>
48
+ <button
49
+ :id="`${props.testId}-next-button`"
50
+ class="calendar-btn"
51
+ title="Next decade"
52
+ @click="nextYear"
53
+ >
54
+ <atoms-the-icon
55
+ name="arrow"
56
+ fill="#0095d3"
57
+ class="arrow-btn next"
58
+ />
59
+ </button>
60
+ </div>
61
+ <div class="all-years">
62
+ <div
63
+ v-for="(item, key) in allYears"
64
+ :key="key"
65
+ :class="['calendar-btn', item.class]"
66
+ @click="selectYear(item.text)"
67
+ >
68
+ {{ item.text }}
69
+ </div>
70
+ </div>
71
+ </div>
72
+ <div v-if="!showAllMonths && !showAllYears" class="main-content">
73
+ <div class="the-month">
74
+ <div class="date top-menu">
75
+ <button
76
+ :id="`${props.testId}-current-month-button`"
77
+ class="calendar-btn show-all-months"
78
+ title="Select Month"
79
+ @click="showAllMonths = true"
80
+ >
81
+ {{ currentMonth }}
82
+ </button>
83
+ <button
84
+ :id="`${props.testId}-current-year-button`"
85
+ class="calendar-btn current-year"
86
+ title="Select Year"
87
+ @click="showAllYears = true"
88
+ >
89
+ {{ currentYear }}
90
+ </button>
91
+ </div>
92
+ <div class="content-buttons-arrow">
93
+ <button
94
+ :id="`${props.testId}-prev-month-button`"
95
+ class="calendar-btn"
96
+ title="Previous Month"
97
+ @click="prevMonth"
98
+ >
99
+ <atoms-the-icon
100
+ name="arrow"
101
+ fill="#0095d3"
102
+ class="arrow-btn prev"
103
+ />
104
+ </button>
105
+ <button
106
+ :id="`${props.testId}-current-date-button`"
107
+ class="calendar-btn set-current-data"
108
+ title="Current Month"
109
+ @click="setCurrentDate"
110
+ >
111
+ <atoms-the-icon
112
+ name="calendar-current-date"
113
+ class="current-btn"
114
+ />
115
+ </button>
116
+ <button
117
+ :id="`${props.testId}-next-month-icon`"
118
+ class="calendar-btn"
119
+ title="Next Month"
120
+ @click="nextMonth"
121
+ >
122
+ <atoms-the-icon
123
+ name="arrow"
124
+ fill="#0095d3"
125
+ class="arrow-btn next"
126
+ />
127
+ </button>
128
+ </div>
129
+ </div>
130
+ <div class="bottom-panel">
131
+ <div class="weekdays">
132
+ <div v-for="(item, key) in weekdays" :key="key">{{ item }}</div>
133
+ </div>
134
+ <div class="days">
135
+ <div
136
+ v-for="(item, key) in days"
137
+ :key="key"
138
+ :class="['item-day', item.class]"
139
+ @click="selectDay(item.text, item.class)"
140
+ >
141
+ {{ item.text }}
142
+ </div>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </template>
149
+
150
+ <script setup lang="ts">
151
+ import { UI_I_Localization } from '~/models/interfaces'
152
+ import { UI_I_Items } from '~/components/atoms/datepicker/models/interfaces'
153
+ import {
154
+ getMonthsFunc,
155
+ getWeekdaysFunc,
156
+ } from '~/components/atoms/datepicker/config/datapicker'
157
+ import { getShortMonths } from '~/components/atoms/datepicker/config/allShortMonths'
158
+
159
+ const { $isDate } = useNuxtApp()
160
+
161
+ const localization = computed<UI_I_Localization>(() => useLocal())
162
+
163
+ const props = withDefaults(
164
+ defineProps<{
165
+ testId?: string
166
+ modelValue: number
167
+ lang: string
168
+ }>(),
169
+ { testId: 'ui-datepicker' }
170
+ )
171
+ const emits = defineEmits<{
172
+ (event: 'update:model-value', num: number): void
173
+ (event: 'update', num: number): void
174
+ }>()
175
+
176
+ const interfaceLang = computed<string>(() => props.lang)
177
+
178
+ let isEnabledEmit = false
179
+ const checkingDate = computed<Date>({
180
+ get() {
181
+ return new Date(props.modelValue)
182
+ },
183
+ set(newValue) {
184
+ if (isEnabledEmit) {
185
+ const newDate = new Date(newValue).getTime()
186
+ emits('update:model-value', newDate)
187
+ emits('update', newDate)
188
+ isEnabledEmit = false
189
+ if ($isDate(newValue.toString())) {
190
+ renderCalendar()
191
+ }
192
+ }
193
+ },
194
+ })
195
+
196
+ const currentYear = ref<number>()
197
+ const currentMonth = ref<string>()
198
+ const showAllYears = ref<boolean>(false)
199
+ const showAllMonths = ref<boolean>(false)
200
+ const selectedMonth = ref<number>(new Date().getMonth())
201
+
202
+ const days = ref<UI_I_Items[]>([])
203
+ const months = computed<string[]>(() => getMonthsFunc(localization.value))
204
+ const weekdays = computed<string[]>(() => {
205
+ const language = interfaceLang.value
206
+ return getWeekdaysFunc(localization.value, language)
207
+ })
208
+
209
+ const renderCalendar = () => {
210
+ checkingDate.value.setDate(1)
211
+ days.value = []
212
+
213
+ const lastDay = new Date(
214
+ checkingDate.value.getFullYear(),
215
+ checkingDate.value.getMonth() + 1,
216
+ 0
217
+ ).getDate()
218
+
219
+ const prevLastDay = new Date(
220
+ checkingDate.value.getFullYear(),
221
+ checkingDate.value.getMonth(),
222
+ 0
223
+ ).getDate()
224
+
225
+ const firstDayIndex = checkingDate.value.getDay()
226
+ const language = interfaceLang.value
227
+ const firstDayIndexByLanguage =
228
+ language === 'en_US' ? firstDayIndex : firstDayIndex - 1
229
+
230
+ const shortMonths = getShortMonths(language)
231
+
232
+ currentMonth.value = shortMonths[checkingDate.value.getMonth()]
233
+
234
+ currentYear.value = checkingDate.value.getFullYear()
235
+
236
+ for (let x = firstDayIndexByLanguage; x > 0; x--) {
237
+ const result = prevLastDay - x + 1
238
+ days.value.push({
239
+ text: result,
240
+ class: 'prev-date',
241
+ })
242
+ }
243
+ const indexCurrentMonth = shortMonths.findIndex(
244
+ (x) => x === currentMonth.value
245
+ )
246
+
247
+ for (let i = 1; i <= lastDay; i++) {
248
+ if (
249
+ i === new Date(props.modelValue).getDate() &&
250
+ new Date(props.modelValue).getMonth() === indexCurrentMonth &&
251
+ new Date(props.modelValue).getFullYear() === currentYear.value
252
+ ) {
253
+ days.value.push({
254
+ text: i,
255
+ class: 'active',
256
+ })
257
+ } else if (
258
+ i === new Date().getDate() &&
259
+ indexCurrentMonth === new Date().getMonth() &&
260
+ currentYear.value === new Date().getFullYear()
261
+ ) {
262
+ days.value.push({
263
+ text: i,
264
+ class: 'today',
265
+ })
266
+ } else {
267
+ days.value.push({ text: i, class: '' })
268
+ }
269
+ }
270
+
271
+ const x = 42 - days.value.length
272
+ for (let j = 1; j <= x; j++) {
273
+ days.value.push({
274
+ text: j,
275
+ class: 'next-date',
276
+ })
277
+ }
278
+ }
279
+
280
+ const allMonths = computed<UI_I_Items[]>(() => {
281
+ const result = []
282
+ for (let i = 0; i < months.value.length; i++) {
283
+ const active = i + 1 === selectedMonth.value + 1 ? 'active' : ''
284
+ result.push({
285
+ text: months.value[i],
286
+ class: active,
287
+ })
288
+ }
289
+ return result
290
+ })
291
+
292
+ const firstYear = ref<number>(
293
+ Number(checkingDate.value.getFullYear().toString().slice(0, 3) + 0)
294
+ )
295
+ const allYears = computed<UI_I_Items[]>(() => {
296
+ const result = []
297
+ for (let i = firstYear.value; i < firstYear.value + 10; i++) {
298
+ const active = i === currentYear.value ? 'active' : ''
299
+ result.push({
300
+ text: i,
301
+ class: active,
302
+ })
303
+ }
304
+ return result
305
+ })
306
+ const prevYear = (): void => {
307
+ firstYear.value = firstYear.value - 10
308
+ }
309
+ const nextYear = (): void => {
310
+ firstYear.value = firstYear.value + 10
311
+ }
312
+ const setCurrentYear = (): void => {
313
+ firstYear.value = Number(
314
+ checkingDate.value.getFullYear().toString().slice(0, 3) + 0
315
+ )
316
+ }
317
+ const selectYear = (value: number): void => {
318
+ checkingDate.value = new Date(checkingDate.value.setFullYear(value))
319
+ renderCalendar()
320
+ showAllYears.value = false
321
+ }
322
+
323
+ const prevMonth = (): void => {
324
+ checkingDate.value.setMonth(checkingDate.value.getMonth() - 1)
325
+
326
+ renderCalendar()
327
+ }
328
+ const nextMonth = (): void => {
329
+ checkingDate.value.setMonth(checkingDate.value.getMonth() + 1)
330
+
331
+ renderCalendar()
332
+ }
333
+ const setCurrentDate = (): void => {
334
+ isEnabledEmit = true
335
+ checkingDate.value = new Date()
336
+
337
+ setTimeout(() => {
338
+ renderCalendar()
339
+ }, 0)
340
+ }
341
+
342
+ const selectMonth = (value: number): void => {
343
+ checkingDate.value = new Date(checkingDate.value.setMonth(value))
344
+ selectedMonth.value = value
345
+ showAllMonths.value = false
346
+
347
+ renderCalendar()
348
+ }
349
+ const selectDay = (value: number | string, type: string): void => {
350
+ isEnabledEmit = true
351
+ if (type === 'prev-date') {
352
+ checkingDate.value = new Date(
353
+ checkingDate.value.setMonth(checkingDate.value.getMonth() - 1)
354
+ )
355
+ } else if (type === 'next-date') {
356
+ checkingDate.value = new Date(
357
+ checkingDate.value.setMonth(checkingDate.value.getMonth() + 1)
358
+ )
359
+ }
360
+ checkingDate.value = new Date(checkingDate.value.setDate(+value))
361
+
362
+ isShowCalendar.value = false
363
+ }
364
+
365
+ const isShowCalendar = ref<boolean>(false)
366
+
367
+ const uniqueId = ref<number>(0)
368
+ const calendarTop = ref<number>()
369
+ const calendarLeft = ref<number>()
370
+ const showHideCalendar = (): void => {
371
+ const allDatePickers = document.querySelectorAll('.the-datepicer')
372
+ allDatePickers.forEach((element: any) => (element.style.display = 'none'))
373
+ const element = document.querySelector(
374
+ `.calendar-id-${uniqueId.value}`
375
+ ) as HTMLElement
376
+
377
+ calendarTop.value = element.getBoundingClientRect().y - 314 + 2
378
+ calendarLeft.value = element.getBoundingClientRect().x - 278 / 2
379
+
380
+ isShowCalendar.value = !isShowCalendar.value
381
+ }
382
+
383
+ const windowClick = (): void => {
384
+ isShowCalendar.value = false
385
+ }
386
+
387
+ const bodyScroll = (): void => {
388
+ isShowCalendar.value = false
389
+ }
390
+
391
+ onMounted(() => {
392
+ renderCalendar()
393
+ window.addEventListener('click', windowClick)
394
+ uniqueId.value = useUniqueId()
395
+ })
396
+ onUnmounted(() => {
397
+ window.removeEventListener('scroll', windowClick)
398
+ })
399
+
400
+ watch(isShowCalendar, (value) => {
401
+ if (value) {
402
+ checkingDate.value.setMonth(new Date(props.modelValue).getMonth())
403
+ checkingDate.value.setFullYear(new Date(props.modelValue).getFullYear())
404
+ renderCalendar()
405
+ window.addEventListener('scroll', bodyScroll, true)
406
+ } else window.removeEventListener('scroll', bodyScroll, true)
407
+ })
408
+ </script>
409
+
410
+ <style scoped lang="scss">
411
+ .item-day {
412
+ font-size: 13px;
413
+ width: 36px;
414
+ height: 36px;
415
+ display: flex;
416
+ justify-content: center;
417
+ align-items: center;
418
+ transition: background-color 0.2s;
419
+ cursor: pointer;
420
+ border-radius: 0.15rem;
421
+ }
422
+ .container-datepicker {
423
+ background: unset;
424
+
425
+ .the-datepicer {
426
+ width: 278px;
427
+ height: 314px;
428
+ border: 1px solid var(--vertical-nav-hover-bg-color);
429
+ border-radius: 0.15rem;
430
+ box-shadow: 0 1px 2.4px hsl(0deg 0% 45% / 25%);
431
+ padding: 12px;
432
+ position: fixed;
433
+ z-index: 1050;
434
+ background-color: var(--modal-other-bg-color);
435
+
436
+ .content-month {
437
+ .all-months {
438
+ display: grid;
439
+ grid-template-columns: 1fr 1fr;
440
+
441
+ .calendar-btn {
442
+ width: 100%;
443
+ height: 48px;
444
+ display: flex;
445
+ justify-content: center;
446
+ align-items: center;
447
+ color: var(--checkbox-label-color);
448
+ }
449
+ .active {
450
+ background: var(--vertical-nav-hover-bg-color);
451
+ color: var(--form-input-color);
452
+ }
453
+ }
454
+ }
455
+ .content-years {
456
+ .content-buttons-arrow {
457
+ max-width: 108px;
458
+ margin: 0 auto;
459
+ }
460
+ .all-years {
461
+ display: grid;
462
+ grid-template-columns: 1fr 1fr;
463
+
464
+ .calendar-btn {
465
+ width: 100%;
466
+ height: 48px;
467
+ color: var(--checkbox-label-color);
468
+ display: flex;
469
+ justify-content: center;
470
+ align-items: center;
471
+ }
472
+ .active {
473
+ background: var(--vertical-nav-hover-bg-color);
474
+ color: var(--form-input-color);
475
+ }
476
+ }
477
+ }
478
+ .main-content {
479
+ .the-month {
480
+ height: 36px;
481
+ display: flex;
482
+ justify-content: space-between;
483
+ align-items: center;
484
+ text-align: center;
485
+
486
+ i {
487
+ font-size: 29px;
488
+ cursor: pointer;
489
+ }
490
+ h1 {
491
+ font-size: 3rem;
492
+ font-weight: 400;
493
+ text-transform: uppercase;
494
+ letter-spacing: 0.2rem;
495
+ margin-bottom: 1rem;
496
+ }
497
+ p {
498
+ font-size: 1.6rem;
499
+ }
500
+
501
+ .top-menu {
502
+ display: flex;
503
+ align-items: center;
504
+ }
505
+ }
506
+
507
+ .bottom-panel {
508
+ .weekdays {
509
+ display: flex;
510
+ align-items: center;
511
+
512
+ div {
513
+ font-size: 12px;
514
+ font-weight: bold;
515
+ letter-spacing: 0.1rem;
516
+ width: 36px;
517
+ height: 36px;
518
+ display: flex;
519
+ justify-content: center;
520
+ align-items: center;
521
+ color: var(--checkbox-label-color);
522
+ }
523
+ }
524
+ .days {
525
+ width: 100%;
526
+ display: flex;
527
+ flex-wrap: wrap;
528
+
529
+ .item-day {
530
+ font-size: 13px;
531
+ width: 36px;
532
+ height: 36px;
533
+ display: flex;
534
+ justify-content: center;
535
+ align-items: center;
536
+ transition: background-color 0.2s;
537
+ cursor: pointer;
538
+ border-radius: 0.15rem;
539
+ color: var(--checkbox-label-color);
540
+
541
+ &:not(.prev-date):not(.today):hover {
542
+ background: #eee;
543
+ }
544
+ &.active {
545
+ background: #d9e4ea;
546
+ color: #000;
547
+ font-weight: bold;
548
+ }
549
+ &.today {
550
+ color: var(--blue-950);
551
+ font-weight: bold;
552
+ }
553
+ &.prev-date,
554
+ &.next-date {
555
+ opacity: 0.5;
556
+ }
557
+ }
558
+ }
559
+ }
560
+ }
561
+ }
562
+
563
+ .calendar-btn {
564
+ width: 48px;
565
+ height: 36px;
566
+ color: #0095d3;
567
+ text-align: center;
568
+ white-space: nowrap;
569
+ overflow: hidden;
570
+ text-overflow: ellipsis;
571
+ background: unset;
572
+ border: none;
573
+ cursor: pointer;
574
+ font-size: 18px;
575
+ border-radius: 3px;
576
+
577
+ &:hover {
578
+ background: #eee;
579
+ }
580
+ }
581
+
582
+ .content-buttons-arrow {
583
+ display: flex;
584
+ align-items: center;
585
+ justify-content: space-between;
586
+
587
+ .icons {
588
+ color: #0095d3;
589
+ }
590
+
591
+ .calendar-btn {
592
+ width: 40px;
593
+ height: 40px;
594
+ display: flex;
595
+ align-items: center;
596
+ justify-content: center;
597
+ }
598
+ }
599
+
600
+ .arrow-btn {
601
+ width: 18px;
602
+ height: 18px;
603
+
604
+ &.prev {
605
+ transform: rotate(-90deg);
606
+ }
607
+ &.next {
608
+ transform: rotate(90deg);
609
+ }
610
+ }
611
+ }
612
+ </style>