bfg-common 1.2.36 → 1.2.37

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 (89) hide show
  1. package/assets/localization/local_be.json +2 -2
  2. package/assets/localization/local_en.json +2 -2
  3. package/assets/localization/local_hy.json +2 -2
  4. package/assets/localization/local_kk.json +2 -2
  5. package/assets/localization/local_ru.json +9 -9
  6. package/assets/localization/local_zh.json +2 -2
  7. package/components/atoms/TheIcon2.vue +1 -0
  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/BadBrowser.vue +5 -24
  24. package/components/common/adapterManager/AddAdapterWarningModal.vue +82 -82
  25. package/components/common/adapterManager/NoActiveAdaptersModal.vue +62 -62
  26. package/components/common/adapterManager/NoConnectedActiveAdaptersModal.vue +62 -62
  27. package/components/common/addNetworking/AddNetworking.vue +4 -0
  28. package/components/common/addNetworking/config/portPropertiesStep.ts +27 -15
  29. package/components/common/addNetworking/models/interfaces.ts +2 -2
  30. package/components/common/addNetworking/models/types.ts +11 -3
  31. package/components/common/addNetworking/steps/PortProperties.vue +14 -3
  32. package/components/common/browse/Browse.vue +182 -182
  33. package/components/common/browse/blocks/Title.vue +66 -66
  34. package/components/common/diagramMain/Diagram.vue +186 -186
  35. package/components/common/diagramMain/DiagramMain.vue +986 -986
  36. package/components/common/diagramMain/adapter/AdapterItem.vue +227 -227
  37. package/components/common/diagramMain/adapter/AdapterItems.vue +57 -57
  38. package/components/common/diagramMain/modals/editSettings/tabs/port/IpvFourSettings.vue +339 -339
  39. package/components/common/diagramMain/modals/editSettings/tabs/port/PortProperties.vue +202 -202
  40. package/components/common/diagramMain/modals/remove/RemoveModal.vue +226 -226
  41. package/components/common/diagramMain/network/Contents.vue +238 -238
  42. package/components/common/feedback/Buttons.vue +232 -232
  43. package/components/common/feedback/Message.vue +468 -468
  44. package/components/common/feedback/VisitPortal.vue +54 -54
  45. package/components/common/help/navbar/left/Left.vue +159 -159
  46. package/components/common/help/navbar/left/utils/constructAccordion.ts +27 -27
  47. package/components/common/mainNavigationPanel/MainNavigationPanel.vue +359 -359
  48. package/components/common/modals/Rename.vue +165 -165
  49. package/components/common/perPage/PerPage.vue +51 -51
  50. package/components/common/recursionTree/RecursionTree.vue +201 -201
  51. package/components/common/vm/actions/add/config/capabilities.ts +338 -338
  52. package/components/common/vm/actions/add/customizeHardware/virtualHardware/VirtualHardware.vue +657 -657
  53. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/CoresPerSocket.vue +109 -109
  54. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/Cpu.vue +383 -383
  55. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/Limit.vue +234 -234
  56. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/config/options.ts +28 -28
  57. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/Memory.vue +316 -316
  58. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/config/memoryOptions.ts +35 -35
  59. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +445 -445
  60. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +288 -288
  61. package/components/common/vm/actions/add/customizeHardware/virtualHardware/reservation/Reservation.vue +235 -235
  62. package/components/common/vm/actions/add/customizeHardware/virtualHardware/videoCard/VideoCard.vue +177 -177
  63. package/components/common/vm/actions/add/customizeHardware/vmoptions/bootOptions/order/Order.vue +197 -197
  64. package/components/common/vm/actions/add/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +181 -181
  65. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/CopyPaste.vue +51 -51
  66. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/RemoteConsoleOptions.vue +253 -253
  67. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +55 -55
  68. package/components/common/vm/actions/add/select/storage/config/config.ts +154 -154
  69. package/components/common/vm/actions/clone/Clone.vue +544 -544
  70. package/components/common/vm/actions/clone/select/options/Options.vue +65 -65
  71. package/components/common/vm/actions/clone/utils.ts +43 -43
  72. package/components/common/wizards/datastore/add/Add.vue +1 -0
  73. package/components/common/wizards/datastore/add/nfs/Nfs.vue +94 -91
  74. package/components/common/wizards/datastore/add/nfs/configuration/Configuration.vue +377 -373
  75. package/components/common/wizards/datastore/add/nfs/configuration/serversList/ServersList.vue +123 -123
  76. package/components/common/wizards/datastore/add/nfs/kerberosAuthentication/KerberosAuthentication.vue +54 -54
  77. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/HostTable.vue +131 -131
  78. package/components/common/wizards/datastore/add/sharedStorm/partitionConfiguration/PartitionConfiguration.vue +230 -230
  79. package/composables/useLocal.ts +38 -38
  80. package/minify.js +146 -146
  81. package/models/store/interfaces.ts +37 -37
  82. package/models/store/storage/interfaces.ts +32 -32
  83. package/models/store/types.ts +32 -32
  84. package/modules/fixContentBuild/utils/methods.ts +114 -114
  85. package/package.json +1 -1
  86. package/public/spice-console/application/codec.js +257 -257
  87. package/public/spice-console/lib/rasterEngine.js +907 -907
  88. package/public/spice-console/network/spicechannel.js +369 -369
  89. package/utils/contentBuild.ts +34 -34
@@ -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>