Skip to content

Commit 1de66db

Browse files
committed
feat: add utils.ts
1 parent 32ec623 commit 1de66db

File tree

3 files changed

+207
-1
lines changed

3 files changed

+207
-1
lines changed

src/lib/dateTime.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (C) 2024 Nethesis S.r.l.
2+
// SPDX-License-Identifier: AGPL-3.0-or-later
3+
4+
import { enGB, it } from 'date-fns/locale'
5+
import { format, utcToZonedTime } from 'date-fns-tz'
6+
import { formatDistanceToNowStrict, formatDuration, intervalToDuration } from 'date-fns'
7+
8+
/**
9+
* Format a date expressed in milliseconds to current locale
10+
*
11+
*/
12+
export function formatDateLoc(date: any, fmt: string) {
13+
return format(date, fmt, { locale: getDateFnsLocale() })
14+
}
15+
16+
export const formatInTimeZoneLoc = (date: any, fmt: string, tz: any) => {
17+
return format(utcToZonedTime(date, tz), fmt, { timeZone: tz, locale: getDateFnsLocale() })
18+
}
19+
20+
/**
21+
* Get browser locale (english fallback)
22+
*/
23+
export const getDateFnsLocale = () => {
24+
let loc = enGB
25+
26+
if (navigator) {
27+
const lang = navigator.language.substring(0, 2)
28+
switch (lang) {
29+
case 'it':
30+
loc = it
31+
break
32+
// add other supported languages
33+
}
34+
}
35+
return loc
36+
}
37+
38+
/**
39+
* Format a duration expressed in seconds to a human readable value. E.g. 189 -> 3 minutes 9 seconds
40+
*
41+
* @param seconds - duration to format
42+
*
43+
*/
44+
export function formatDurationLoc(durationSeconds: number, options: any = {}) {
45+
if (!durationSeconds) {
46+
return null
47+
}
48+
49+
return formatDuration(
50+
intervalToDuration({
51+
start: 0,
52+
end: durationSeconds * 1000
53+
}),
54+
{ ...options, locale: getDateFnsLocale() }
55+
)
56+
}
57+
58+
/**
59+
* Return the approximate and concise distance from a date to now. Example output: '2 hours'.
60+
* Useful to show how long ago something has happened (e.g. a notification timestamp)
61+
*/
62+
export function humanDistanceToNowLoc(date: Date, options: any = {}) {
63+
if (!date) {
64+
return null
65+
}
66+
return formatDistanceToNowStrict(date, { ...options, locale: getDateFnsLocale() })
67+
}

src/lib/utils.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright (C) 2024 Nethesis S.r.l.
2+
// SPDX-License-Identifier: AGPL-3.0-or-later
3+
4+
import { round } from 'lodash-es'
5+
import { nextTick } from 'vue'
6+
7+
/**
8+
* Sort function to order array elements by a specific property (for array of objects) or by a specific index (for arrays of arrays)
9+
*
10+
*/
11+
export const sortByProperty = (property: string | number) => {
12+
return function (a: any, b: any) {
13+
if (a[property] < b[property]) {
14+
return -1
15+
}
16+
if (a[property] > b[property]) {
17+
return 1
18+
}
19+
return 0
20+
}
21+
}
22+
23+
/**
24+
* Set the focus on an element. To set the focus on a custom component, it needs to expose focus() function (see NeTextInput for an example)
25+
*
26+
*/
27+
export const focusElement = (elementRef: any) => {
28+
nextTick(() => {
29+
if (elementRef && elementRef.value) {
30+
elementRef.value.focus()
31+
}
32+
})
33+
}
34+
35+
/**
36+
* Returns a i18n key for an error returned by Axios
37+
*
38+
*/
39+
export const getAxiosErrorMessage = (error: any) => {
40+
if (error.message === 'Network Error') {
41+
return 'error.network_error'
42+
}
43+
44+
if (/^timeout of .+ exceeded$/.test(error.message)) {
45+
// axios timeout reached
46+
return 'error.network_timeout'
47+
}
48+
49+
if (error.response) {
50+
switch (error.response.status) {
51+
case 401:
52+
return 'error.http_401'
53+
case 403:
54+
return 'error.http_403'
55+
case 404:
56+
return 'error.http_404'
57+
case 500:
58+
return 'error.http_500'
59+
}
60+
}
61+
return 'error.generic_error'
62+
}
63+
64+
/**
65+
* Format a byte size according to the International Electrotechnical Commission (IEC), using 1024 as multiple factor
66+
*
67+
* @param byteSize the number of bytes to format
68+
* @returns a string representing the byte size with the appropriate unit
69+
*/
70+
export const byteFormat1024 = (byteSize: number) => {
71+
switch (true) {
72+
case isNaN(byteSize) || (!byteSize && byteSize !== 0):
73+
return '-'
74+
case byteSize >= 0 && byteSize < 1024:
75+
return byteSize + ' B'
76+
case byteSize >= 1024 && byteSize < Math.pow(1024, 2):
77+
return round(byteSize / 1024, 2) + ' KiB'
78+
case byteSize >= Math.pow(1024, 2) && byteSize < Math.pow(1024, 3):
79+
return round(byteSize / Math.pow(1024, 2), 2) + ' MiB'
80+
case byteSize >= Math.pow(1024, 3) && byteSize < Math.pow(1024, 4):
81+
return round(byteSize / Math.pow(1024, 3), 2) + ' GiB'
82+
default:
83+
return round(byteSize / Math.pow(1024, 4), 2) + ' TiB'
84+
}
85+
}
86+
87+
/**
88+
* Format a byte size according to the International System of Units (SI), using 1000 as multiple factor
89+
*
90+
* @param byteSize the number of bytes to format
91+
* @returns a string representing the byte size with the appropriate unit
92+
*/
93+
export const byteFormat1000 = (byteSize: number) => {
94+
switch (true) {
95+
case isNaN(byteSize) || (!byteSize && byteSize !== 0):
96+
return '-'
97+
case byteSize >= 0 && byteSize < 1000:
98+
return byteSize + ' B'
99+
case byteSize >= 1000 && byteSize < Math.pow(1000, 2):
100+
return round(byteSize / 1000, 2) + ' kB'
101+
case byteSize >= Math.pow(1000, 2) && byteSize < Math.pow(1000, 3):
102+
return round(byteSize / Math.pow(1000, 2), 2) + ' MB'
103+
case byteSize >= Math.pow(1000, 3) && byteSize < Math.pow(1000, 4):
104+
return round(byteSize / Math.pow(1000, 3), 2) + ' GB'
105+
default:
106+
return round(byteSize / Math.pow(1000, 4), 2) + ' TB'
107+
}
108+
}
109+
110+
/**
111+
* Format kilobits per second (kbps, typically a network speed)
112+
*
113+
* @param kbps the number of kilobits to format
114+
* @returns a string representing the input value with the appropriate unit
115+
*/
116+
export const kbpsFormat = (kbps: number) => {
117+
switch (true) {
118+
case isNaN(kbps) || (!kbps && kbps !== 0):
119+
return '-'
120+
case kbps >= 0 && kbps < 1000:
121+
return round(kbps, 2) + ' kbps'
122+
case kbps >= 1000 && kbps < Math.pow(1000, 2):
123+
return round(kbps / 1000, 2) + ' Mbps'
124+
case kbps >= Math.pow(1000, 2) && kbps < Math.pow(1000, 3):
125+
return round(kbps / Math.pow(1000, 2), 2) + ' Gbps'
126+
default:
127+
return round(kbps / Math.pow(1000, 3), 2) + ' Tbps'
128+
}
129+
}

src/main.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ export { default as NeFormItemLabel } from '@/components/NeFormItemLabel.vue'
2929
export { default as NeRadioSelection } from '@/components/NeRadioSelection.vue'
3030
export { default as NePaginator } from '@/components/NePaginator.vue'
3131

32-
// types
32+
// types export
3333
export type { NeComboboxOption } from '@/components/NeCombobox.vue'
3434
export type { NePaginatorProps } from '@/components/NePaginator.vue'
35+
36+
// library functions export
37+
export {
38+
sortByProperty,
39+
focusElement,
40+
getAxiosErrorMessage,
41+
byteFormat1024,
42+
byteFormat1000,
43+
kbpsFormat
44+
} from '@/lib/utils'

0 commit comments

Comments
 (0)