bfg-common 1.2.37 → 1.2.39

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