bfg-common 1.5.695 → 1.5.697
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.
- package/CODE_STYLE.md +109 -109
- package/assets/img/icons/icons-sprite-dark-3.svg +227 -227
- package/assets/img/icons/icons-sprite-dark-5.svg +488 -488
- package/assets/img/icons/icons-sprite-light-3.svg +227 -227
- package/assets/img/icons/icons-sprite-light-5.svg +488 -488
- package/assets/scss/common/icons/icons-2.scss +282 -264
- package/components/atoms/TheIcon3.vue +50 -50
- package/components/atoms/collapse/CollapseNav.vue +170 -170
- package/components/atoms/perPage/PerPage.vue +58 -58
- package/components/atoms/switch/Switch.vue +103 -103
- package/components/atoms/table/dataGrid/DataGrid.vue +1718 -1718
- package/components/atoms/table/dataGrid/DataGridPagination.vue +97 -97
- package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
- package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
- package/components/common/backup/storage/actions/add/lib/utils.ts +51 -51
- package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
- package/components/common/diagramMain/modals/lib/config/vCenterModal.ts +48 -48
- package/components/common/diagramMain/port/Port.vue +580 -580
- package/components/common/layout/theHeader/TheHeaderNew.vue +315 -315
- package/components/common/layout/theHeader/TheHeaderOld.vue +262 -262
- package/components/common/layout/theHeader/helpMenu/About.vue +79 -79
- package/components/common/layout/theHeader/helpMenu/aboutOld/AboutOld.vue +79 -79
- package/components/common/layout/theHeader/userMenu/modals/preferences/PreferencesOld.vue +144 -144
- package/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types.ts +7 -7
- package/components/common/pages/backups/DetailView.vue +52 -52
- package/components/common/pages/backups/lib/models/interfaces.ts +36 -36
- package/components/common/pages/backups/modals/Modals.vue +243 -243
- package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/lib/config/options.ts +6 -6
- package/components/common/pages/backups/modals/createBackup/lib/config/readyToCompleteOptions.ts +69 -69
- package/components/common/pages/backups/modals/lib/config/restore.ts +115 -115
- package/components/common/pages/backups/modals/lib/models/interfaces.ts +186 -186
- package/components/common/pages/backups/modals/restore/name/lib/models/interfaces.ts +6 -6
- package/components/common/pages/home/lib/models/interfaces.ts +48 -48
- package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
- package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
- package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
- package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
- package/components/common/pages/scheduledTasks/lib/utils/utils.ts +84 -84
- package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
- package/components/common/select/radio/RadioGroup.vue +137 -137
- package/components/common/spiceConsole/Drawer.vue +420 -420
- package/components/common/spiceConsole/SpiceConsole.vue +184 -184
- package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
- package/components/common/tools/Actions.vue +207 -207
- package/components/common/treeView/TreeView.vue +52 -52
- package/components/common/vm/actions/clone/lib/config/steps.ts +295 -295
- package/components/common/vm/actions/clone/new/New.vue +438 -438
- package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardware.vue +706 -706
- package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
- package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Memory.vue +283 -283
- package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +489 -489
- package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/NewPciDevice.vue +253 -253
- package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +156 -156
- package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
- package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
- package/components/common/vm/actions/common/select/options/New.vue +264 -264
- package/components/common/vm/actions/common/select/options/Old.vue +109 -109
- package/components/common/vm/actions/common/select/options/Options.vue +58 -58
- package/components/common/vm/actions/common/select/storage/Old.vue +125 -125
- package/components/common/vm/actions/common/select/storage/new/New.vue +311 -311
- package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
- package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
- package/components/common/vm/actions/common/select/template/old/Old.vue +50 -50
- package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
- package/components/common/wizards/common/compatibility/Compatibility.vue +35 -35
- package/components/common/wizards/common/steps/computeResource/New.vue +93 -93
- package/components/common/wizards/common/steps/name/Name.vue +178 -178
- package/components/common/wizards/common/steps/name/New.vue +221 -221
- package/components/common/wizards/common/steps/name/Old.vue +121 -121
- package/components/common/wizards/common/steps/name/lib/models/interfaces.ts +4 -4
- package/components/common/wizards/common/steps/name/location/New.vue +40 -40
- package/components/common/wizards/datastore/add/Add.vue +228 -228
- package/components/common/wizards/datastore/add/lib/utils.ts +85 -85
- package/components/common/wizards/datastore/add/steps/nameAndDevice/NameAndDeviceNew.vue +232 -232
- package/components/common/wizards/datastore/add/steps/nameAndDevice/NameAndDeviceOld.vue +231 -231
- package/components/common/wizards/datastore/add/steps/nameAndDevice/advancedOptions/AdvancedOptions.vue +43 -43
- package/components/common/wizards/datastore/add/steps/nameAndDevice/advancedOptions/New.vue +101 -101
- package/components/common/wizards/datastore/add/steps/nameAndDevice/advancedOptions/Old.vue +101 -101
- package/components/common/wizards/datastore/add/steps/typeMode/lib/config/typeOptions.ts +43 -43
- package/composables/useAppVersion.ts +21 -21
- package/composables/useEnvLanguage.ts +22 -22
- package/composables/useLocal.ts +6 -6
- package/composables/useLocalCommon.ts +39 -39
- package/package.json +1 -1
- package/plugins/console.ts +21 -21
- package/plugins/date.ts +375 -375
- package/plugins/mouse.ts +21 -21
- package/plugins/panelStates.ts +70 -70
- package/plugins/text.ts +59 -59
- package/public/spice-console/application/clientgui.js +854 -854
- package/public/spice-console/application/packetfactory.js +211 -211
- package/public/spice-console/application/virtualmouse.js +147 -147
- package/public/spice-console/lib/images/bitmap.js +203 -203
- package/public/spice-console/network/spicechannel.js +440 -440
- package/public/spice-console/process/cursorprocess.js +128 -128
- package/public/spice-console/process/inputprocess.js +227 -227
- package/public/spice-console/process/mainprocess.js +212 -212
- package/public/spice-console/run.js +210 -210
- package/store/main/mutations.ts +7 -7
- package/store/main/state.ts +7 -7
- package/store/tasks/mappers/recentTasks.ts +123 -123
- package/store/tasks/mutations.ts +82 -82
package/plugins/date.ts
CHANGED
|
@@ -1,375 +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
|
-
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
|
-
})
|
|
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
|
+
})
|