bfg-common 1.5.693 → 1.5.695

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 (113) hide show
  1. package/CODE_STYLE.md +109 -109
  2. package/assets/img/icons/icons-sprite-dark-1.svg +2 -3
  3. package/assets/img/icons/icons-sprite-dark-3.svg +227 -227
  4. package/assets/img/icons/icons-sprite-dark-5.svg +488 -488
  5. package/assets/img/icons/icons-sprite-light-1.svg +3 -4
  6. package/assets/img/icons/icons-sprite-light-3.svg +227 -227
  7. package/assets/img/icons/icons-sprite-light-5.svg +488 -488
  8. package/assets/localization/local_be.json +6 -1
  9. package/assets/localization/local_en.json +6 -1
  10. package/assets/localization/local_hy.json +6 -1
  11. package/assets/localization/local_kk.json +6 -1
  12. package/assets/localization/local_ru.json +6 -1
  13. package/assets/localization/local_zh.json +6 -1
  14. package/assets/scss/common/icons/icons-1.scss +1 -1
  15. package/assets/scss/components/auth.scss +17 -0
  16. package/components/atoms/TheIcon3.vue +50 -50
  17. package/components/atoms/collapse/CollapseNav.vue +170 -170
  18. package/components/atoms/perPage/PerPage.vue +58 -58
  19. package/components/atoms/switch/Switch.vue +103 -103
  20. package/components/atoms/table/dataGrid/DataGrid.vue +1718 -1718
  21. package/components/atoms/table/dataGrid/DataGridPagination.vue +97 -97
  22. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  23. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  24. package/components/common/backup/storage/actions/add/lib/utils.ts +51 -51
  25. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  26. package/components/common/diagramMain/modals/lib/config/vCenterModal.ts +48 -48
  27. package/components/common/diagramMain/port/Port.vue +580 -580
  28. package/components/common/help/navbar/left/lib/utils/constructAccordion.ts +2 -1
  29. package/components/common/help/navbar/right/Right.vue +1 -1
  30. package/components/common/layout/theHeader/TheHeaderNew.vue +315 -315
  31. package/components/common/layout/theHeader/TheHeaderOld.vue +262 -262
  32. package/components/common/layout/theHeader/helpMenu/About.vue +79 -79
  33. package/components/common/layout/theHeader/helpMenu/aboutOld/AboutOld.vue +79 -79
  34. package/components/common/layout/theHeader/userMenu/modals/preferences/PreferencesOld.vue +144 -144
  35. package/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types.ts +7 -7
  36. package/components/common/pages/backups/DetailView.vue +52 -52
  37. package/components/common/pages/backups/lib/models/interfaces.ts +36 -36
  38. package/components/common/pages/backups/modals/Modals.vue +243 -243
  39. package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/lib/config/options.ts +6 -6
  40. package/components/common/pages/backups/modals/createBackup/lib/config/readyToCompleteOptions.ts +69 -69
  41. package/components/common/pages/backups/modals/lib/config/restore.ts +115 -115
  42. package/components/common/pages/backups/modals/lib/models/interfaces.ts +186 -186
  43. package/components/common/pages/backups/modals/restore/name/lib/models/interfaces.ts +6 -6
  44. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  45. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  46. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  47. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  48. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  49. package/components/common/pages/scheduledTasks/lib/utils/utils.ts +84 -84
  50. package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
  51. package/components/common/select/radio/RadioGroup.vue +137 -137
  52. package/components/common/spiceConsole/Drawer.vue +420 -420
  53. package/components/common/spiceConsole/SpiceConsole.vue +184 -184
  54. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  55. package/components/common/tools/Actions.vue +207 -207
  56. package/components/common/treeView/TreeView.vue +52 -52
  57. package/components/common/vm/actions/clone/lib/config/steps.ts +295 -295
  58. package/components/common/vm/actions/clone/new/New.vue +438 -438
  59. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardware.vue +706 -706
  60. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  61. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Memory.vue +283 -283
  62. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +489 -489
  63. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/NewPciDevice.vue +253 -253
  64. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +156 -156
  65. package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
  66. package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
  67. package/components/common/vm/actions/common/select/options/New.vue +264 -264
  68. package/components/common/vm/actions/common/select/options/Old.vue +109 -109
  69. package/components/common/vm/actions/common/select/options/Options.vue +58 -58
  70. package/components/common/vm/actions/common/select/storage/Old.vue +125 -125
  71. package/components/common/vm/actions/common/select/storage/new/New.vue +311 -311
  72. package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
  73. package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
  74. package/components/common/vm/actions/common/select/template/old/Old.vue +50 -50
  75. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  76. package/components/common/wizards/common/compatibility/Compatibility.vue +35 -35
  77. package/components/common/wizards/common/steps/computeResource/New.vue +93 -93
  78. package/components/common/wizards/common/steps/name/Name.vue +178 -178
  79. package/components/common/wizards/common/steps/name/New.vue +221 -221
  80. package/components/common/wizards/common/steps/name/Old.vue +121 -121
  81. package/components/common/wizards/common/steps/name/lib/models/interfaces.ts +4 -4
  82. package/components/common/wizards/common/steps/name/location/New.vue +40 -40
  83. package/components/common/wizards/datastore/add/Add.vue +228 -228
  84. package/components/common/wizards/datastore/add/lib/utils.ts +85 -85
  85. package/components/common/wizards/datastore/add/steps/nameAndDevice/NameAndDeviceNew.vue +232 -232
  86. package/components/common/wizards/datastore/add/steps/nameAndDevice/NameAndDeviceOld.vue +231 -231
  87. package/components/common/wizards/datastore/add/steps/nameAndDevice/advancedOptions/AdvancedOptions.vue +43 -43
  88. package/components/common/wizards/datastore/add/steps/nameAndDevice/advancedOptions/New.vue +101 -101
  89. package/components/common/wizards/datastore/add/steps/nameAndDevice/advancedOptions/Old.vue +101 -101
  90. package/components/common/wizards/datastore/add/steps/typeMode/lib/config/typeOptions.ts +43 -43
  91. package/composables/useAppVersion.ts +21 -21
  92. package/composables/useEnvLanguage.ts +22 -22
  93. package/composables/useLocal.ts +6 -6
  94. package/composables/useLocalCommon.ts +39 -39
  95. package/package.json +1 -1
  96. package/plugins/console.ts +21 -21
  97. package/plugins/date.ts +375 -398
  98. package/plugins/mouse.ts +21 -21
  99. package/plugins/panelStates.ts +70 -70
  100. package/plugins/text.ts +59 -59
  101. package/public/spice-console/application/clientgui.js +854 -854
  102. package/public/spice-console/application/packetfactory.js +211 -211
  103. package/public/spice-console/application/virtualmouse.js +147 -147
  104. package/public/spice-console/lib/images/bitmap.js +203 -203
  105. package/public/spice-console/network/spicechannel.js +440 -440
  106. package/public/spice-console/process/cursorprocess.js +128 -128
  107. package/public/spice-console/process/inputprocess.js +227 -227
  108. package/public/spice-console/process/mainprocess.js +212 -212
  109. package/public/spice-console/run.js +210 -210
  110. package/store/main/mutations.ts +7 -7
  111. package/store/main/state.ts +7 -7
  112. package/store/tasks/mappers/recentTasks.ts +123 -123
  113. package/store/tasks/mutations.ts +82 -82
package/plugins/date.ts CHANGED
@@ -1,398 +1,375 @@
1
- import { defineNuxtPlugin } from '#app'
2
- import type { UI_T_DateFormat } from '~/lib/models/plugins/date/types'
3
- import type {
4
- UI_I_Dateformat,
5
- UI_I_TimeLocalization,
6
- UI_I_FormattedDatetimeOptions,
7
- } from '~/lib/models/plugins/date/interfaces'
8
- import type { UI_I_ArbitraryObject } from '~/lib/models/interfaces'
9
-
10
- const LocalMethods: {
11
- formatTimeNumber: Function
12
- formattedTimeReplace: Function
13
- formattedDateReplace: Function
14
- } = {
15
- formatTimeNumber:
16
- (value: number, unit: string, is12H = false): Function =>
17
- (
18
- match: string,
19
- ...args: (string | number | undefined)[]
20
- ): string | number => {
21
- const matchUnit: string | undefined = match
22
- .match(/[A-Za-z]*/gi)
23
- ?.filter?.((value: string) => value)[0]
24
-
25
- const isSingleNumber: boolean =
26
- matchUnit === unit || matchUnit === unit.toUpperCase()
27
-
28
- let filteredArgs: (string | number | undefined)[] = args.filter(
29
- (value: string | number | undefined): boolean => value !== undefined
30
- )
31
-
32
- if (typeof filteredArgs[0] === 'number') {
33
- filteredArgs = [undefined, undefined, ...filteredArgs]
34
- }
35
-
36
- if (typeof filteredArgs[1] === 'number') {
37
- filteredArgs = [undefined, ...filteredArgs]
38
- }
39
-
40
- let left = ''
41
- let right = ''
42
-
43
- if (filteredArgs[0] || filteredArgs[1]) {
44
- filteredArgs[0] !== undefined && (left = filteredArgs[0] as string)
45
- filteredArgs[1] !== undefined && (right = filteredArgs[1] as string)
46
- }
47
-
48
- const isHours: boolean = unit[0] === 'h'
49
-
50
- if (is12H && isHours) {
51
- value = value === 12 ? 12 : value % 12
52
- }
53
-
54
- return `${left}${
55
- value < 10 && !isSingleNumber ? '0' + value : value
56
- }${right}`
57
- },
58
-
59
- formattedTimeReplace: (
60
- result: string,
61
- value: number,
62
- unit: string,
63
- ampmLocal: [string, string],
64
- isMinutes = false
65
- ): string => {
66
- const uppercasedUnit: string = unit.toUpperCase()
67
-
68
- const isHours: boolean = unit[0] === 'h'
69
- let ampm: 'am' | 'pm' | '' = ''
70
- const is12H: boolean = !!result.match('aa')?.[0]
71
-
72
- if (is12H && isHours) {
73
- ampm = value >= 12 ? 'pm' : 'am'
74
-
75
- result = result.replace('aa', ampm === 'am' ? ampmLocal[0] : ampmLocal[1])
76
- }
77
-
78
- return result.replace(
79
- new RegExp(
80
- isMinutes
81
- ? `${unit}${unit}|(:)${unit}(\\b)|(:)${unit}(:)|(\\b)${unit}(:)|^${unit}(:)`
82
- : `${unit}${unit}|${uppercasedUnit}${uppercasedUnit}|(:)${unit}(\\b)|:${uppercasedUnit}(\\b)|:${unit}:|:${uppercasedUnit}:|(\\b)${unit}(:)|(\\b)${uppercasedUnit}(:)|^${unit}(:)|^${uppercasedUnit}(:)`
83
- ),
84
- LocalMethods.formatTimeNumber(value, unit, is12H)
85
- )
86
- },
87
-
88
- formattedDateReplace: (
89
- result: string,
90
- value: number,
91
- unit: string
92
- ): string => {
93
- const localUnit: string =
94
- result
95
- .match(new RegExp(`${unit}*`, 'gm'))
96
- ?.filter?.((value) => value)[0] || unit
97
-
98
- let localValue: string | number = value
99
-
100
- if (unit === 'M' && localUnit.length === 2) {
101
- localValue = value < 10 ? '0' + value : value
102
- }
103
- if (unit === 'd' && localUnit.length === 2) {
104
- localValue = value < 10 ? '0' + value : value
105
- }
106
- if (unit === 'y' && localUnit.length) {
107
- localValue = value.toString().slice(-localUnit.length)
108
- }
109
-
110
- return result.replace(localUnit, localValue.toString())
111
- },
112
- }
113
-
114
- export default defineNuxtPlugin(() => {
115
- // Проверяем переданое является датой
116
- const isDate = (date: string | number) => {
117
- return new Date(date).toString() !== 'Invalid Date'
118
- }
119
-
120
- // Проверяем формат времени браузера равно 24h
121
- const isBrowserLocale24h = () =>
122
- !new Intl.DateTimeFormat(undefined, { hour: 'numeric' })
123
- .format(0)
124
- .match(/AM/)
125
-
126
- // Получаем формат даты
127
- const getDateFormat = (lang?: string): UI_T_DateFormat => {
128
- const currentLanguage = lang || useLocalStorage('lang') || 'en_US'
129
- const dateFormats: UI_I_Dateformat = {
130
- be_BY: 'yyyy-MM-dd',
131
- en_US: 'MM-dd-yyyy',
132
- hy_AM: 'yyyy-MM-dd',
133
- kk_KZ: 'dd/MM/yyyy',
134
- ru_RU: 'dd/MM/yyyy',
135
- zh_CHS: 'yyyy-MM-dd',
136
- }
137
-
138
- const dateFormat = ref(dateFormats[currentLanguage])
139
-
140
- window.addEventListener('timeFormatStorageChanged', function handler() {
141
- dateFormat.value = dateFormats[lang || useLocalStorage('lang') || 'en_US'] // TODO нужно проверить когда будем работать без useLocalStorage
142
-
143
- window.removeEventListener('timeFormatStorageChanged', handler)
144
- })
145
-
146
- return dateFormat.value
147
- }
148
-
149
- // Получаем формат времени
150
- const getTimeFormat = (hasSeconds: boolean, timeFormat?: string) => {
151
- let appTimeFormat = timeFormat || useLocalStorage('timeFormat') || 'DEFAULT'
152
- let timeFormatLocal = ''
153
-
154
- if (appTimeFormat === 'DEFAULT') {
155
- const isBrowserTimeFormat24 = isBrowserLocale24h()
156
-
157
- appTimeFormat = isBrowserTimeFormat24 ? '24H' : appTimeFormat
158
- }
159
-
160
- if (appTimeFormat === '24H') {
161
- timeFormatLocal = 'HH:mm'
162
- } else {
163
- timeFormatLocal = 'h:mm aa'
164
- }
165
-
166
- hasSeconds && (timeFormatLocal = timeFormatLocal.replace(':mm', ':mm:ss'))
167
-
168
- return timeFormatLocal
169
- }
170
-
171
- // Форматирование даты из английского в стандартный
172
- const enFormatToStandardFormat = (date: string): string => {
173
- const splitDate = date.split('-')
174
- return [splitDate[2], splitDate[0], splitDate[1]].join('/')
175
- }
176
- const getUnixByDate = (dateTime: string, lang?: string): number => {
177
- const currentFormat: UI_T_DateFormat = getDateFormat(lang)
178
-
179
- const [date, time] = dateTime.split(' ')
180
-
181
- let standardDate = ''
182
- switch (currentFormat) {
183
- case 'dd/MM/yyyy':
184
- standardDate = date.split('/').reverse().join('/')
185
- break
186
- case 'yyyy-MM-dd':
187
- standardDate = date.replaceAll('-', '/')
188
- break
189
- case 'MM-dd-yyyy':
190
- standardDate = enFormatToStandardFormat(date)
191
- break
192
- }
193
-
194
- const standard = time ? standardDate + ' ' + time : standardDate
195
- return new Date(standard).getTime()
196
- }
197
-
198
- // Форматирование даты без временим
199
- const formattedDate = (
200
- date: number | string | Date,
201
- formatDate = '',
202
- lang?: string
203
- ) => {
204
- const dateObj: Date = new Date(date)
205
- const formatDateLocal = formatDate || getDateFormat(lang)
206
-
207
- const day: number = dateObj.getDate()
208
- const month: number = dateObj.getMonth() + 1
209
- const fullYear: number = dateObj.getFullYear()
210
-
211
- return LocalMethods.formattedDateReplace(
212
- LocalMethods.formattedDateReplace(
213
- LocalMethods.formattedDateReplace(formatDateLocal, day, 'd'),
214
- month,
215
- 'M'
216
- ),
217
- fullYear,
218
- 'y'
219
- )
220
- }
221
-
222
- // Форматирование времени
223
- const formattedTime = (
224
- date: number | string | Date,
225
- formatDate = '',
226
- hasSeconds = false,
227
- timeFormat?: string,
228
- lang?: string
229
- ) => {
230
- const dateObj: Date = new Date(date)
231
-
232
- const currentLanguage = lang || useLocalStorage('lang') || 'en_US'
233
- const formatTimeLocal = formatDate || getTimeFormat(hasSeconds, timeFormat)
234
-
235
- const localization: UI_I_TimeLocalization = {
236
- en_US: ['AM', 'PM'],
237
- ru_RU: ['ДП', 'ПП'],
238
- hy_AM: ['AM', 'PM'],
239
- be_BY: ['ДП', 'ПП'],
240
- kk_KZ: ['ТД', 'ТК'],
241
- zh_CHS: ['上午', '下午'],
242
- }
243
-
244
- const hours: number = dateObj.getHours()
245
- const minutes: number = dateObj.getMinutes()
246
- const seconds: number = dateObj.getSeconds()
247
-
248
- return LocalMethods.formattedTimeReplace(
249
- LocalMethods.formattedTimeReplace(
250
- LocalMethods.formattedTimeReplace(
251
- formatTimeLocal,
252
- seconds,
253
- 's',
254
- localization[currentLanguage],
255
- false
256
- ),
257
- minutes,
258
- 'm',
259
- localization[currentLanguage],
260
- true
261
- ),
262
- hours,
263
- 'h',
264
- localization[currentLanguage],
265
- false
266
- )
267
- }
268
-
269
- // Форматирование даты с временим
270
- const formattedDatetime = (
271
- date: number | string | Date,
272
- options?: Partial<UI_I_FormattedDatetimeOptions>
273
- ) => {
274
- const localOptions: UI_I_FormattedDatetimeOptions = {
275
- formatDate: '',
276
- hasSeconds: false,
277
- lang: '',
278
- formatTime: '',
279
- timeFormat: '',
280
- separator: '',
281
- onlyDate: false,
282
- onlyTime: false,
283
- ...(options || {}),
284
- }
285
-
286
- const dateObj: Date = new Date(date)
287
-
288
- const formatDateLocal = ref(
289
- localOptions.formatDate || getDateFormat(localOptions.lang)
290
- )
291
-
292
- const formatTimeLocal = ref(
293
- localOptions.formatTime ||
294
- getTimeFormat(localOptions.hasSeconds, localOptions.formatTime)
295
- )
296
-
297
- const formatDatetime = ref('')
298
-
299
- if (localOptions.onlyDate) {
300
- formatDatetime.value = formatDateLocal.value
301
- }
302
-
303
- if (localOptions.onlyTime) {
304
- formatDatetime.value = formatTimeLocal.value
305
- }
306
-
307
- if (!localOptions.onlyDate && !localOptions.onlyTime) {
308
- formatDatetime.value =
309
- formatDateLocal.value +
310
- (localOptions.separator ? localOptions.separator : ' ') +
311
- formatTimeLocal.value
312
- }
313
-
314
- window.addEventListener('timeFormatStorageChanged', function handler() {
315
- formatDatetime.value =
316
- formatDateLocal.value +
317
- ' ' +
318
- getTimeFormat(localOptions.hasSeconds, localOptions.formatTime)
319
-
320
- window.removeEventListener('timeFormatStorageChanged', handler)
321
- })
322
-
323
- if (!localOptions.onlyTime) {
324
- formatDatetime.value = formattedDate(
325
- dateObj,
326
- formatDatetime.value,
327
- localOptions.lang
328
- )
329
- }
330
-
331
- if (!localOptions.onlyDate) {
332
- formatDatetime.value = formattedTime(
333
- dateObj,
334
- formatDatetime.value,
335
- localOptions.hasSeconds,
336
- localOptions.formatTime,
337
- localOptions.lang
338
- )
339
- }
340
-
341
- return formatDatetime.value
342
- }
343
-
344
- const correctRuUnit = (value: number, type: string): string => {
345
- let result = ''
346
-
347
- const forms: UI_I_ArbitraryObject<string[]> = {
348
- second: ['Секунда', 'Секунды', 'Секунд'],
349
- minute: ['Минута', 'Минуты', 'Минут'],
350
- hour: ['Час', 'Часа', 'Часов'],
351
- day: ['День', 'Дня', 'Дней'],
352
- week: ['Неделя', 'Недели', 'Недель'],
353
- month: ['Месяц', 'Месяца', 'Месяцев'],
354
- year: ['Год', 'Года', 'Лет'],
355
- }
356
-
357
- const isFirstType = value % 10 === 1 && value % 100 !== 11
358
- const isSecondType =
359
- [2, 3, 4].includes(value % 10) && ![12, 13, 14].includes(value % 100)
360
-
361
- if (isFirstType) {
362
- result = forms[type][0]
363
- } else if (isSecondType) {
364
- result = forms[type][1]
365
- } else {
366
- result = forms[type][2]
367
- }
368
-
369
- return result
370
- }
371
-
372
- // Определяем сколько времени осталось
373
- // time = seconds
374
- const timeToTimeLeft = (time: number): number[] => {
375
- const seconds = Math.floor(time % 60)
376
- const minutes = Math.floor((time / 60) % 60)
377
- const hours = Math.floor((time / 60 / 60) % 24)
378
- const days = Math.floor((time / 60 / 60 / 24) % 30)
379
- const months = Math.floor((time / 60 / 60 / 24 / 30) % 12)
380
- const years = Math.floor(time / 60 / 60 / 24 / 30 / 12)
381
-
382
- return [years, months, days, hours, minutes, seconds]
383
- }
384
-
385
- return {
386
- provide: {
387
- isDate,
388
- getTimeFormat,
389
- getDateFormat,
390
- formattedTime,
391
- formattedDate,
392
- formattedDatetime,
393
- getUnixByDate,
394
- correctRuUnit,
395
- timeToTimeLeft,
396
- },
397
- }
398
- })
1
+ import { defineNuxtPlugin } from '#app'
2
+ import type { UI_T_DateFormat } from '~/lib/models/plugins/date/types'
3
+ import type {
4
+ UI_I_Dateformat,
5
+ UI_I_TimeLocalization,
6
+ UI_I_FormattedDatetimeOptions,
7
+ } from '~/lib/models/plugins/date/interfaces'
8
+ import type { UI_I_ArbitraryObject } from '~/lib/models/interfaces'
9
+
10
+ const LocalMethods: {
11
+ formatTimeNumber: Function
12
+ formattedTimeReplace: Function
13
+ formattedDateReplace: Function
14
+ } = {
15
+ formatTimeNumber:
16
+ (value: number, unit: string, is12H = false): Function =>
17
+ (
18
+ match: string,
19
+ ...args: (string | number | undefined)[]
20
+ ): string | number => {
21
+ const matchUnit: string | undefined = match
22
+ .match(/[A-Za-z]*/gi)
23
+ ?.filter?.((value: string) => value)[0]
24
+
25
+ const isSingleNumber: boolean =
26
+ matchUnit === unit || matchUnit === unit.toUpperCase()
27
+
28
+ let filteredArgs: (string | number | undefined)[] = args.filter(
29
+ (value: string | number | undefined): boolean => value !== undefined
30
+ )
31
+
32
+ if (typeof filteredArgs[0] === 'number') {
33
+ filteredArgs = [undefined, undefined, ...filteredArgs]
34
+ }
35
+
36
+ if (typeof filteredArgs[1] === 'number') {
37
+ filteredArgs = [undefined, ...filteredArgs]
38
+ }
39
+
40
+ let left = ''
41
+ let right = ''
42
+
43
+ if (filteredArgs[0] || filteredArgs[1]) {
44
+ filteredArgs[0] !== undefined && (left = filteredArgs[0] as string)
45
+ filteredArgs[1] !== undefined && (right = filteredArgs[1] as string)
46
+ }
47
+
48
+ const isHours: boolean = unit[0] === 'h'
49
+
50
+ if (is12H && isHours) {
51
+ value = value === 12 ? 12 : value % 12
52
+ }
53
+
54
+ return `${left}${
55
+ value < 10 && !isSingleNumber ? '0' + value : value
56
+ }${right}`
57
+ },
58
+
59
+ formattedTimeReplace: (
60
+ result: string,
61
+ value: number,
62
+ unit: string,
63
+ ampmLocal: [string, string],
64
+ isMinutes = false
65
+ ): string => {
66
+ const uppercasedUnit: string = unit.toUpperCase()
67
+
68
+ const isHours: boolean = unit[0] === 'h'
69
+ let ampm: 'am' | 'pm' | '' = ''
70
+ const is12H: boolean = !!result.match('aa')?.[0]
71
+
72
+ if (is12H && isHours) {
73
+ ampm = value >= 12 ? 'pm' : 'am'
74
+
75
+ result = result.replace('aa', ampm === 'am' ? ampmLocal[0] : ampmLocal[1])
76
+ }
77
+
78
+ return result.replace(
79
+ new RegExp(
80
+ isMinutes
81
+ ? `${unit}${unit}|(:)${unit}(\\b)|(:)${unit}(:)|(\\b)${unit}(:)|^${unit}(:)`
82
+ : `${unit}${unit}|${uppercasedUnit}${uppercasedUnit}|(:)${unit}(\\b)|:${uppercasedUnit}(\\b)|:${unit}:|:${uppercasedUnit}:|(\\b)${unit}(:)|(\\b)${uppercasedUnit}(:)|^${unit}(:)|^${uppercasedUnit}(:)`
83
+ ),
84
+ LocalMethods.formatTimeNumber(value, unit, is12H)
85
+ )
86
+ },
87
+
88
+ formattedDateReplace: (
89
+ result: string,
90
+ value: number,
91
+ unit: string
92
+ ): string => {
93
+ const localUnit: string =
94
+ result
95
+ .match(new RegExp(`${unit}*`, 'gm'))
96
+ ?.filter?.((value) => value)[0] || unit
97
+
98
+ let localValue: string | number = value
99
+
100
+ if (unit === 'M' && localUnit.length === 2) {
101
+ localValue = value < 10 ? '0' + value : value
102
+ }
103
+ if (unit === 'd' && localUnit.length === 2) {
104
+ localValue = value < 10 ? '0' + value : value
105
+ }
106
+ if (unit === 'y' && localUnit.length) {
107
+ localValue = value.toString().slice(-localUnit.length)
108
+ }
109
+
110
+ return result.replace(localUnit, localValue.toString())
111
+ },
112
+ }
113
+
114
+ export default defineNuxtPlugin(() => {
115
+ // Проверяем переданое является датой
116
+ const isDate = (date: string | number) => {
117
+ return new Date(date).toString() !== 'Invalid Date'
118
+ }
119
+
120
+ // Проверяем формат времени браузера равно 24h
121
+ const isBrowserLocale24h = () =>
122
+ !new Intl.DateTimeFormat(undefined, { hour: 'numeric' })
123
+ .format(0)
124
+ .match(/AM/)
125
+
126
+ // Получаем формат даты
127
+ const getDateFormat = (lang?: string): UI_T_DateFormat => {
128
+ const currentLanguage = lang || useLocalStorage('lang') || 'en_US'
129
+ const dateFormats: UI_I_Dateformat = {
130
+ be_BY: 'yyyy-MM-dd',
131
+ en_US: 'MM-dd-yyyy',
132
+ hy_AM: 'yyyy-MM-dd',
133
+ kk_KZ: 'dd/MM/yyyy',
134
+ ru_RU: 'dd/MM/yyyy',
135
+ zh_CHS: 'yyyy-MM-dd',
136
+ }
137
+
138
+ return dateFormats[currentLanguage]
139
+ }
140
+
141
+ // Получаем формат времени
142
+ const getTimeFormat = (hasSeconds: boolean, timeFormat?: string) => {
143
+ let appTimeFormat = timeFormat || useLocalStorage('timeFormat') || 'DEFAULT'
144
+ let timeFormatLocal = ''
145
+
146
+ if (appTimeFormat === 'DEFAULT') {
147
+ const isBrowserTimeFormat24 = isBrowserLocale24h()
148
+
149
+ appTimeFormat = isBrowserTimeFormat24 ? '24H' : appTimeFormat
150
+ }
151
+
152
+ if (appTimeFormat === '24H') {
153
+ timeFormatLocal = 'HH:mm'
154
+ } else {
155
+ timeFormatLocal = 'h:mm aa'
156
+ }
157
+
158
+ hasSeconds && (timeFormatLocal = timeFormatLocal.replace(':mm', ':mm:ss'))
159
+
160
+ return timeFormatLocal
161
+ }
162
+
163
+ // Форматирование даты из английского в стандартный
164
+ const enFormatToStandardFormat = (date: string): string => {
165
+ const splitDate = date.split('-')
166
+ return [splitDate[2], splitDate[0], splitDate[1]].join('/')
167
+ }
168
+ const getUnixByDate = (dateTime: string, lang?: string): number => {
169
+ const currentFormat: UI_T_DateFormat = getDateFormat(lang)
170
+
171
+ const [date, time] = dateTime.split(' ')
172
+
173
+ let standardDate = ''
174
+ switch (currentFormat) {
175
+ case 'dd/MM/yyyy':
176
+ standardDate = date.split('/').reverse().join('/')
177
+ break
178
+ case 'yyyy-MM-dd':
179
+ standardDate = date.replaceAll('-', '/')
180
+ break
181
+ case 'MM-dd-yyyy':
182
+ standardDate = enFormatToStandardFormat(date)
183
+ break
184
+ }
185
+
186
+ const standard = time ? standardDate + ' ' + time : standardDate
187
+ return new Date(standard).getTime()
188
+ }
189
+
190
+ // Форматирование даты без временим
191
+ const formattedDate = (
192
+ date: number | string | Date,
193
+ formatDate = '',
194
+ lang?: string
195
+ ) => {
196
+ const dateObj: Date = new Date(date)
197
+ const formatDateLocal = formatDate || getDateFormat(lang)
198
+
199
+ const day: number = dateObj.getDate()
200
+ const month: number = dateObj.getMonth() + 1
201
+ const fullYear: number = dateObj.getFullYear()
202
+
203
+ return LocalMethods.formattedDateReplace(
204
+ LocalMethods.formattedDateReplace(
205
+ LocalMethods.formattedDateReplace(formatDateLocal, day, 'd'),
206
+ month,
207
+ 'M'
208
+ ),
209
+ fullYear,
210
+ 'y'
211
+ )
212
+ }
213
+
214
+ // Форматирование времени
215
+ const formattedTime = (
216
+ date: number | string | Date,
217
+ formatDate = '',
218
+ hasSeconds = false,
219
+ timeFormat?: string,
220
+ lang?: string
221
+ ) => {
222
+ const dateObj: Date = new Date(date)
223
+
224
+ const currentLanguage = lang || useLocalStorage('lang') || 'en_US'
225
+ const formatTimeLocal = formatDate || getTimeFormat(hasSeconds, timeFormat)
226
+
227
+ const localization: UI_I_TimeLocalization = {
228
+ en_US: ['AM', 'PM'],
229
+ ru_RU: ['ДП', 'ПП'],
230
+ hy_AM: ['AM', 'PM'],
231
+ be_BY: ['ДП', 'ПП'],
232
+ kk_KZ: ['ТД', 'ТК'],
233
+ zh_CHS: ['上午', '下午'],
234
+ }
235
+
236
+ const hours: number = dateObj.getHours()
237
+ const minutes: number = dateObj.getMinutes()
238
+ const seconds: number = dateObj.getSeconds()
239
+
240
+ return LocalMethods.formattedTimeReplace(
241
+ LocalMethods.formattedTimeReplace(
242
+ LocalMethods.formattedTimeReplace(
243
+ formatTimeLocal,
244
+ seconds,
245
+ 's',
246
+ localization[currentLanguage],
247
+ false
248
+ ),
249
+ minutes,
250
+ 'm',
251
+ localization[currentLanguage],
252
+ true
253
+ ),
254
+ hours,
255
+ 'h',
256
+ localization[currentLanguage],
257
+ false
258
+ )
259
+ }
260
+
261
+ // Форматирование даты с временим
262
+ const formattedDatetime = (
263
+ date: number | string | Date,
264
+ options?: Partial<UI_I_FormattedDatetimeOptions>
265
+ ) => {
266
+ const localOptions: UI_I_FormattedDatetimeOptions = {
267
+ formatDate: '',
268
+ hasSeconds: false,
269
+ lang: '',
270
+ formatTime: '',
271
+ timeFormat: '',
272
+ separator: '',
273
+ onlyDate: false,
274
+ onlyTime: false,
275
+ ...(options || {}),
276
+ }
277
+
278
+ const dateObj: Date = new Date(date)
279
+
280
+ const formatDateLocal =
281
+ localOptions.formatDate || getDateFormat(localOptions.lang)
282
+
283
+ const formatTimeLocal =
284
+ localOptions.formatTime ||
285
+ getTimeFormat(localOptions.hasSeconds, localOptions.formatTime)
286
+
287
+ let formatDatetime = ''
288
+
289
+ if (localOptions.onlyDate) {
290
+ formatDatetime = formatDateLocal
291
+ }
292
+
293
+ if (localOptions.onlyTime) {
294
+ formatDatetime = formatTimeLocal
295
+ }
296
+
297
+ if (!localOptions.onlyDate && !localOptions.onlyTime) {
298
+ formatDatetime =
299
+ formatDateLocal +
300
+ (localOptions.separator ? localOptions.separator : ' ') +
301
+ formatTimeLocal
302
+ }
303
+
304
+ if (!localOptions.onlyTime) {
305
+ formatDatetime = formattedDate(dateObj, formatDatetime, localOptions.lang)
306
+ }
307
+
308
+ if (!localOptions.onlyDate) {
309
+ formatDatetime = formattedTime(
310
+ dateObj,
311
+ formatDatetime,
312
+ localOptions.hasSeconds,
313
+ localOptions.formatTime,
314
+ localOptions.lang
315
+ )
316
+ }
317
+
318
+ return formatDatetime
319
+ }
320
+
321
+ const correctRuUnit = (value: number, type: string): string => {
322
+ let result = ''
323
+
324
+ const forms: UI_I_ArbitraryObject<string[]> = {
325
+ second: ['Секунда', 'Секунды', 'Секунд'],
326
+ minute: ['Минута', 'Минуты', 'Минут'],
327
+ hour: ['Час', 'Часа', 'Часов'],
328
+ day: ['День', 'Дня', 'Дней'],
329
+ week: ['Неделя', 'Недели', 'Недель'],
330
+ month: ['Месяц', 'Месяца', 'Месяцев'],
331
+ year: ['Год', 'Года', 'Лет'],
332
+ }
333
+
334
+ const isFirstType = value % 10 === 1 && value % 100 !== 11
335
+ const isSecondType =
336
+ [2, 3, 4].includes(value % 10) && ![12, 13, 14].includes(value % 100)
337
+
338
+ if (isFirstType) {
339
+ result = forms[type][0]
340
+ } else if (isSecondType) {
341
+ result = forms[type][1]
342
+ } else {
343
+ result = forms[type][2]
344
+ }
345
+
346
+ return result
347
+ }
348
+
349
+ // Определяем сколько времени осталось
350
+ // time = seconds
351
+ const timeToTimeLeft = (time: number): number[] => {
352
+ const seconds = Math.floor(time % 60)
353
+ const minutes = Math.floor((time / 60) % 60)
354
+ const hours = Math.floor((time / 60 / 60) % 24)
355
+ const days = Math.floor((time / 60 / 60 / 24) % 30)
356
+ const months = Math.floor((time / 60 / 60 / 24 / 30) % 12)
357
+ const years = Math.floor(time / 60 / 60 / 24 / 30 / 12)
358
+
359
+ return [years, months, days, hours, minutes, seconds]
360
+ }
361
+
362
+ return {
363
+ provide: {
364
+ isDate,
365
+ getTimeFormat,
366
+ getDateFormat,
367
+ formattedTime,
368
+ formattedDate,
369
+ formattedDatetime,
370
+ getUnixByDate,
371
+ correctRuUnit,
372
+ timeToTimeLeft,
373
+ },
374
+ }
375
+ })