bfg-common 1.2.39 → 1.2.41

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 (78) hide show
  1. package/components/atoms/alert/Notification.vue +167 -167
  2. package/components/atoms/autocomplete/Autocomplete.vue +236 -236
  3. package/components/atoms/datepicker/Datepicker.vue +612 -612
  4. package/components/atoms/list/SelectList.vue +62 -62
  5. package/components/atoms/nav/NavBar.vue +116 -116
  6. package/components/atoms/nav/VerticalNavBar.vue +89 -89
  7. package/components/atoms/notificationBar/NotificationBar.vue +175 -175
  8. package/components/atoms/perPage/PerPage.vue +52 -52
  9. package/components/atoms/popup/SimplePopup.vue +90 -90
  10. package/components/atoms/step/VerticalStep.vue +104 -104
  11. package/components/atoms/switch/Switch.vue +107 -107
  12. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +206 -206
  13. package/components/atoms/table/dataGrid/DataGridPage.vue +189 -189
  14. package/components/atoms/tabs/Tabs.vue +189 -189
  15. package/components/atoms/tooltip/Signpost.vue +224 -224
  16. package/components/common/BadBrowser.vue +114 -114
  17. package/components/common/adapterManager/AddAdapterWarningModal.vue +82 -82
  18. package/components/common/adapterManager/NoActiveAdaptersModal.vue +62 -62
  19. package/components/common/adapterManager/NoConnectedActiveAdaptersModal.vue +62 -62
  20. package/components/common/browse/Browse.vue +182 -182
  21. package/components/common/browse/blocks/Title.vue +66 -66
  22. package/components/common/diagramMain/Diagram.vue +186 -186
  23. package/components/common/diagramMain/DiagramMain.vue +986 -986
  24. package/components/common/diagramMain/adapter/AdapterItem.vue +227 -227
  25. package/components/common/diagramMain/adapter/AdapterItems.vue +57 -57
  26. package/components/common/diagramMain/modals/editSettings/tabs/port/IpvFourSettings.vue +339 -339
  27. package/components/common/diagramMain/modals/editSettings/tabs/port/PortProperties.vue +202 -202
  28. package/components/common/diagramMain/modals/remove/RemoveModal.vue +226 -226
  29. package/components/common/diagramMain/network/Contents.vue +238 -238
  30. package/components/common/feedback/Buttons.vue +232 -232
  31. package/components/common/feedback/Message.vue +468 -468
  32. package/components/common/feedback/VisitPortal.vue +54 -54
  33. package/components/common/help/navbar/left/Left.vue +159 -159
  34. package/components/common/help/navbar/left/utils/constructAccordion.ts +27 -27
  35. package/components/common/mainNavigationPanel/MainNavigationPanel.vue +359 -359
  36. package/components/common/modals/Rename.vue +165 -165
  37. package/components/common/monitor/advanced/Advanced.vue +235 -235
  38. package/components/common/monitor/advanced/tools/chartOptionsModal/models/interfaces.ts +19 -19
  39. package/components/common/perPage/PerPage.vue +51 -51
  40. package/components/common/recursionTree/RecursionTree.vue +201 -201
  41. package/components/common/vm/actions/add/config/capabilities.ts +338 -338
  42. package/components/common/vm/actions/add/customizeHardware/virtualHardware/VirtualHardware.vue +657 -657
  43. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/CoresPerSocket.vue +109 -109
  44. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/Cpu.vue +383 -383
  45. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/Limit.vue +234 -234
  46. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/config/options.ts +28 -28
  47. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/Memory.vue +316 -316
  48. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/config/memoryOptions.ts +35 -35
  49. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +445 -445
  50. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +288 -288
  51. package/components/common/vm/actions/add/customizeHardware/virtualHardware/reservation/Reservation.vue +235 -235
  52. package/components/common/vm/actions/add/customizeHardware/virtualHardware/videoCard/VideoCard.vue +177 -177
  53. package/components/common/vm/actions/add/customizeHardware/vmoptions/bootOptions/order/Order.vue +197 -197
  54. package/components/common/vm/actions/add/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +181 -181
  55. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/CopyPaste.vue +51 -51
  56. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/RemoteConsoleOptions.vue +253 -253
  57. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +55 -55
  58. package/components/common/vm/actions/add/select/storage/config/config.ts +154 -154
  59. package/components/common/vm/actions/clone/Clone.vue +544 -544
  60. package/components/common/vm/actions/clone/select/options/Options.vue +65 -65
  61. package/components/common/vm/actions/clone/utils.ts +43 -43
  62. package/components/common/wizards/datastore/add/nfs/Nfs.vue +94 -94
  63. package/components/common/wizards/datastore/add/nfs/configuration/Configuration.vue +377 -377
  64. package/components/common/wizards/datastore/add/nfs/configuration/serversList/ServersList.vue +123 -123
  65. package/components/common/wizards/datastore/add/nfs/kerberosAuthentication/KerberosAuthentication.vue +54 -54
  66. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/HostTable.vue +131 -131
  67. package/components/common/wizards/datastore/add/sharedStorm/partitionConfiguration/PartitionConfiguration.vue +230 -230
  68. package/composables/useLocal.ts +38 -38
  69. package/minify.js +146 -146
  70. package/models/store/interfaces.ts +37 -37
  71. package/models/store/storage/interfaces.ts +32 -32
  72. package/models/store/types.ts +32 -32
  73. package/modules/fixContentBuild/utils/methods.ts +114 -114
  74. package/package.json +1 -1
  75. package/public/spice-console/application/codec.js +257 -257
  76. package/public/spice-console/lib/rasterEngine.js +907 -907
  77. package/public/spice-console/network/spicechannel.js +369 -369
  78. 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>