@data-fair/lib-vue 0.1.0 → 1.0.1
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/concept-filters.js +20 -22
- package/format/bytes.js +13 -13
- package/format/field.js +14 -21
- package/locale-dayjs-global.js +3 -3
- package/locale-dayjs-types.js +1 -1
- package/locale-dayjs.js +25 -26
- package/package.json +12 -7
- package/reactive-search-params-global.js +3 -3
- package/reactive-search-params.js +124 -140
- package/session.d.ts +1 -0
- package/session.js +244 -276
- package/ui-notif-global.js +3 -3
- package/ui-notif.d.ts +2 -2
- package/ui-notif.js +30 -33
- package/ws.js +58 -62
package/concept-filters.js
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
// filter reactiveSearchParams to conceptFilters (params prefixed by _c_)
|
|
2
|
-
import { reactive, watch } from 'vue'
|
|
3
|
-
export function useConceptFilters(reactiveSearchParams, datasetId) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}, { immediate: true });
|
|
22
|
-
return conceptFilters;
|
|
2
|
+
import { reactive, watch } from 'vue'
|
|
3
|
+
export function useConceptFilters (reactiveSearchParams, datasetId) {
|
|
4
|
+
const conceptFilters = reactive({})
|
|
5
|
+
const datasetFiltersPrefix = datasetId && `_d_${datasetId}_`
|
|
6
|
+
watch(reactiveSearchParams, () => {
|
|
7
|
+
for (const key of Object.keys(reactiveSearchParams)) {
|
|
8
|
+
if (key.startsWith('_c_')) { conceptFilters[key] = reactiveSearchParams[key] }
|
|
9
|
+
if (datasetFiltersPrefix && key.startsWith(datasetFiltersPrefix)) {
|
|
10
|
+
conceptFilters[key.replace(datasetFiltersPrefix, '')] = reactiveSearchParams[key]
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
for (const key of Object.keys(conceptFilters)) {
|
|
14
|
+
if (key.startsWith('_c_') && reactiveSearchParams[key] === undefined) { delete conceptFilters[key] }
|
|
15
|
+
if (datasetFiltersPrefix && !key.startsWith('_c_') && reactiveSearchParams[datasetFiltersPrefix + key] === undefined) {
|
|
16
|
+
delete conceptFilters[key]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}, { immediate: true })
|
|
20
|
+
return conceptFilters
|
|
23
21
|
}
|
|
24
|
-
export default useConceptFilters
|
|
22
|
+
export default useConceptFilters
|
package/format/bytes.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
const locales = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
export function formatBytes(bytes, locale = 'fr') {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
2
|
+
fr: [[0, 'octet'], [1, 'octets'], [1000, 'ko'], [1000 * 1000, 'Mo'], [1000 * 1000 * 1000, 'Go'], [1000 * 1000 * 1000 * 1000, 'To'], [1000 * 1000 * 1000 * 1000 * 1000, 'Po']],
|
|
3
|
+
en: [[0, 'byte'], [1, 'bytes'], [1000, 'kb'], [1000 * 1000, 'Mb'], [1000 * 1000 * 1000, 'Gb'], [1000 * 1000 * 1000 * 1000, 'Tb'], [1000 * 1000 * 1000 * 1000 * 1000, 'Pb']]
|
|
4
|
+
}
|
|
5
|
+
export function formatBytes (bytes, locale = 'fr') {
|
|
6
|
+
const bytesInt = Math.abs(typeof bytes === 'string' ? parseInt(bytes, 10) : bytes)
|
|
7
|
+
const def = locales[locale] ?? locales.en
|
|
8
|
+
for (let i = 0; i < def.length; i++) {
|
|
9
|
+
const step = def[i][0]
|
|
10
|
+
if (bytesInt < step || i === def.length - 1) {
|
|
11
|
+
return (bytesInt / (def[i - 1][0] || 1)).toLocaleString(locale, { maximumFractionDigits: 0 }) + ' ' + def[i - 1][1]
|
|
13
12
|
}
|
|
14
|
-
|
|
13
|
+
}
|
|
14
|
+
return '' // this is only for strict typing, but the code cannot go there, the return in the loop is always called
|
|
15
15
|
}
|
|
16
|
-
export default formatBytes
|
|
16
|
+
export default formatBytes
|
package/format/field.js
CHANGED
|
@@ -1,28 +1,21 @@
|
|
|
1
1
|
// TODO: use locale-dayjs for localization of date formats
|
|
2
|
-
import dayjs from 'dayjs'
|
|
3
|
-
export function formatField(item, field) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (typeof value === 'boolean')
|
|
12
|
-
return value ? 'Oui' : 'Non';
|
|
13
|
-
if (typeof value === 'string') {
|
|
14
|
-
if (field['x-refersTo'] === 'http://schema.org/Date' ||
|
|
2
|
+
import dayjs from 'dayjs'
|
|
3
|
+
export function formatField (item, field) {
|
|
4
|
+
const value = item[field.key]
|
|
5
|
+
if (value === undefined || value === null || value === '') { return '' }
|
|
6
|
+
if (field['x-labels']?.['' + item[field.key]]) { return field['x-labels']['' + item[field.key]] }
|
|
7
|
+
if (field.type === 'number' || field.type === 'integer') { return value.toLocaleString('fr') }
|
|
8
|
+
if (typeof value === 'boolean') { return value ? 'Oui' : 'Non' }
|
|
9
|
+
if (typeof value === 'string') {
|
|
10
|
+
if (field['x-refersTo'] === 'http://schema.org/Date' ||
|
|
15
11
|
field['x-refersTo'] === 'https://schema.org/startDate' ||
|
|
16
12
|
field['x-refersTo'] === 'https://schema.org/endDate' ||
|
|
17
13
|
field['x-refersTo'] === 'http://schema.org/dateCreated') {
|
|
18
|
-
|
|
19
|
-
return dayjs(value).format('DD/MM/YYYY, HH[h]mm');
|
|
20
|
-
else
|
|
21
|
-
return dayjs(value).format('DD/MM/YYYY');
|
|
22
|
-
}
|
|
14
|
+
if (field.format === 'date-time') { return dayjs(value).format('DD/MM/YYYY, HH[h]mm') } else { return dayjs(value).format('DD/MM/YYYY') }
|
|
23
15
|
}
|
|
24
|
-
|
|
16
|
+
}
|
|
17
|
+
return '' + value
|
|
25
18
|
}
|
|
26
|
-
export function getFieldLabel(field) {
|
|
27
|
-
|
|
19
|
+
export function getFieldLabel (field) {
|
|
20
|
+
return field.title || field['x-originalName'] || field.key
|
|
28
21
|
}
|
package/locale-dayjs-global.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// same as locale-dayjs but in a module level singleton for convenience when not using SSR
|
|
2
|
-
import { getLocaleDayjs } from './locale-dayjs.js'
|
|
2
|
+
import { getLocaleDayjs } from './locale-dayjs.js'
|
|
3
3
|
// @ts-ignore
|
|
4
4
|
if (import.meta.env?.SSR) {
|
|
5
|
-
|
|
5
|
+
throw new Error('this module uses a module level singleton, it cannot be used in SSR mode')
|
|
6
6
|
}
|
|
7
|
-
export const { locale, dayjs } = getLocaleDayjs()
|
|
7
|
+
export const { locale, dayjs } = getLocaleDayjs()
|
package/locale-dayjs-types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {}
|
|
1
|
+
export {}
|
package/locale-dayjs.js
CHANGED
|
@@ -1,32 +1,31 @@
|
|
|
1
|
-
import { inject, ref } from 'vue'
|
|
2
|
-
import dayjs from 'dayjs'
|
|
3
|
-
import 'dayjs/locale/fr'
|
|
4
|
-
import 'dayjs/locale/en'
|
|
5
|
-
import localizedFormat from 'dayjs/plugin/localizedFormat.js'
|
|
6
|
-
import relativeTime from 'dayjs/plugin/relativeTime.js'
|
|
7
|
-
dayjs.extend(localizedFormat)
|
|
8
|
-
dayjs.extend(relativeTime)
|
|
1
|
+
import { inject, ref } from 'vue'
|
|
2
|
+
import dayjs from 'dayjs'
|
|
3
|
+
import 'dayjs/locale/fr'
|
|
4
|
+
import 'dayjs/locale/en'
|
|
5
|
+
import localizedFormat from 'dayjs/plugin/localizedFormat.js'
|
|
6
|
+
import relativeTime from 'dayjs/plugin/relativeTime.js'
|
|
7
|
+
dayjs.extend(localizedFormat)
|
|
8
|
+
dayjs.extend(relativeTime)
|
|
9
9
|
// main functionality, use through the createLocaleDayjs plugin and useLocaleDayjs composable
|
|
10
10
|
// or as a global singleton through ./locale-dayjs-global.js
|
|
11
|
-
export function getLocaleDayjs(_locale) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
export function getLocaleDayjs (_locale) {
|
|
12
|
+
const locale = _locale ?? ref('fr')
|
|
13
|
+
return {
|
|
14
|
+
locale,
|
|
15
|
+
dayjs: (date) => {
|
|
16
|
+
return dayjs(date).locale(locale.value)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
19
|
}
|
|
20
20
|
// uses pattern for SSR friendly plugin/composable, cf https://antfu.me/posts/composable-vue-vueday-2021#shared-state-ssr-friendly
|
|
21
|
-
export const localeDayjsKey = Symbol('localeDayjs')
|
|
22
|
-
export function createLocaleDayjs(locale) {
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
export const localeDayjsKey = Symbol('localeDayjs')
|
|
22
|
+
export function createLocaleDayjs (locale) {
|
|
23
|
+
const localeDayjs = getLocaleDayjs(locale)
|
|
24
|
+
return { install (app) { app.provide(localeDayjsKey, localeDayjs) } }
|
|
25
25
|
}
|
|
26
|
-
export function useLocaleDayjs() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return localeDayjs;
|
|
26
|
+
export function useLocaleDayjs () {
|
|
27
|
+
const localeDayjs = inject(localeDayjsKey)
|
|
28
|
+
if (!localeDayjs) { throw new Error('useLocaleDayjs requires using the plugin createLocaleDayjs') }
|
|
29
|
+
return localeDayjs
|
|
31
30
|
}
|
|
32
|
-
export default useLocaleDayjs
|
|
31
|
+
export default useLocaleDayjs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@data-fair/lib-vue",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Composables and other utilities for Vue applications in the data-fair stack.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -9,11 +9,15 @@
|
|
|
9
9
|
],
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "MIT",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"prepublishOnly": "cd .. && npm run prepublishOnly",
|
|
14
|
+
"build": "cd .. && npm run build"
|
|
15
|
+
},
|
|
12
16
|
"peerDependencies": {
|
|
13
|
-
"dayjs": "
|
|
14
|
-
"ofetch": "
|
|
15
|
-
"reconnecting-websocket": "
|
|
16
|
-
"vue": "
|
|
17
|
+
"dayjs": "1",
|
|
18
|
+
"ofetch": "1",
|
|
19
|
+
"reconnecting-websocket": "4",
|
|
20
|
+
"vue": "3"
|
|
17
21
|
},
|
|
18
22
|
"peerDependenciesMeta": {
|
|
19
23
|
"reconnecting-websocket": {
|
|
@@ -24,12 +28,13 @@
|
|
|
24
28
|
}
|
|
25
29
|
},
|
|
26
30
|
"dependencies": {
|
|
27
|
-
"@data-fair/lib-common-types": "^
|
|
28
|
-
"@data-fair/lib-utils": "^0.
|
|
31
|
+
"@data-fair/lib-common-types": "^1.1.0",
|
|
32
|
+
"@data-fair/lib-utils": "^1.0.0",
|
|
29
33
|
"jwt-decode": "^4.0.0",
|
|
30
34
|
"universal-cookie": "^7.2.0"
|
|
31
35
|
},
|
|
32
36
|
"devDependencies": {
|
|
37
|
+
"reconnecting-websocket": "^4.4.0",
|
|
33
38
|
"vue-router": "^4.4.5"
|
|
34
39
|
},
|
|
35
40
|
"type": "module"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// same as use-reactive-search-params.js but in a module level singleton for convenience when not using SSR
|
|
2
|
-
import { getReactiveSearchParams } from './reactive-search-params.js'
|
|
2
|
+
import { getReactiveSearchParams } from './reactive-search-params.js'
|
|
3
3
|
// @ts-ignore
|
|
4
4
|
if (import.meta.env?.SSR) {
|
|
5
|
-
|
|
5
|
+
throw new Error('this module uses a module level singleton, it cannot be used in SSR mode')
|
|
6
6
|
}
|
|
7
|
-
export default getReactiveSearchParams()
|
|
7
|
+
export default getReactiveSearchParams()
|
|
@@ -1,155 +1,139 @@
|
|
|
1
1
|
// inspired by useUrlSearchParams (https://github.com/vueuse/vueuse/blob/main/packages/core/useUrlSearchParams/index.ts)
|
|
2
2
|
// but even simpler, without array values, always in history mode, and shared in a app plugin
|
|
3
|
-
import { reactive, watch, inject, computed } from 'vue'
|
|
4
|
-
import Debug from 'debug'
|
|
5
|
-
const debug = Debug('reactive-search-params')
|
|
6
|
-
debug.log = console.log.bind(console)
|
|
3
|
+
import { reactive, watch, inject, computed } from 'vue'
|
|
4
|
+
import Debug from 'debug'
|
|
5
|
+
const debug = Debug('reactive-search-params')
|
|
6
|
+
debug.log = console.log.bind(console)
|
|
7
7
|
const applySearchParams = (state, queryParams) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
if (Array.isArray(value)) {
|
|
16
|
-
const lastValue = value[value.length - 1];
|
|
17
|
-
if (typeof lastValue === 'string') {
|
|
18
|
-
state[key] = lastValue;
|
|
19
|
-
unusedKeys.delete(key);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
for (const unusedKey of unusedKeys) {
|
|
24
|
-
delete state[unusedKey];
|
|
8
|
+
const unusedKeys = new Set(Object.keys(state))
|
|
9
|
+
for (const key of Object.keys(queryParams)) {
|
|
10
|
+
const value = queryParams[key]
|
|
11
|
+
if (typeof value === 'string') {
|
|
12
|
+
state[key] = value
|
|
13
|
+
unusedKeys.delete(key)
|
|
25
14
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
router = __unctx__.get('nuxt-app').use().$router;
|
|
34
|
-
debug('using nuxt 3 router implicitly');
|
|
35
|
-
}
|
|
36
|
-
catch (e) {
|
|
37
|
-
// nothing to do
|
|
38
|
-
}
|
|
15
|
+
if (Array.isArray(value)) {
|
|
16
|
+
const lastValue = value[value.length - 1]
|
|
17
|
+
if (typeof lastValue === 'string') {
|
|
18
|
+
state[key] = lastValue
|
|
19
|
+
unusedKeys.delete(key)
|
|
20
|
+
}
|
|
39
21
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
22
|
+
}
|
|
23
|
+
for (const unusedKey of unusedKeys) {
|
|
24
|
+
delete state[unusedKey]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function getReactiveSearchParams (router) {
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
if (!import.meta.env?.SSR && !router) {
|
|
30
|
+
try {
|
|
31
|
+
// nuxt 3 way of reading router
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
router = __unctx__.get('nuxt-app').use().$router
|
|
34
|
+
debug('using nuxt 3 router implicitly')
|
|
35
|
+
} catch (e) {
|
|
36
|
+
// nothing to do
|
|
52
37
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
38
|
+
}
|
|
39
|
+
const state = reactive({})
|
|
40
|
+
// 2 modes, 1 based on vue router, 1 based on window.location.search
|
|
41
|
+
if (router) {
|
|
42
|
+
debug('initialize reactive search params based on vue router')
|
|
43
|
+
watch(router.currentRoute, (route) => {
|
|
44
|
+
debug('route.query changed', route.query)
|
|
45
|
+
applySearchParams(state, route.query)
|
|
46
|
+
}, { immediate: true })
|
|
47
|
+
watch(state, () => {
|
|
48
|
+
debug('state changed', state)
|
|
49
|
+
router?.replace({ query: state })
|
|
50
|
+
})
|
|
51
|
+
} else {
|
|
52
|
+
debug('initialize reactive search params based on window.location.search')
|
|
53
|
+
window.addEventListener('popstate', () => {
|
|
54
|
+
debug('update state based on window.location.search', window.location.search)
|
|
55
|
+
applySearchParams(state, Object.fromEntries(new URLSearchParams(window.location.search)))
|
|
56
|
+
})
|
|
57
|
+
applySearchParams(state, Object.fromEntries(new URLSearchParams(window.location.search)))
|
|
58
|
+
const updateUrl = () => {
|
|
59
|
+
debug('update url based on state', state)
|
|
60
|
+
const params = new URLSearchParams('')
|
|
61
|
+
for (const key of Object.keys(state)) {
|
|
62
|
+
const value = state[key]
|
|
63
|
+
if (value !== null && value !== undefined && value !== '') {
|
|
64
|
+
params.set(key, value)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const newQuery = params.toString()
|
|
68
|
+
const newSearch = newQuery.length > 0 ? '?' + newQuery : ''
|
|
69
|
+
if (newSearch !== window.location.search) {
|
|
70
|
+
window.history.replaceState(window.history.state, window.document.title, window.location.pathname + newSearch)
|
|
71
|
+
}
|
|
78
72
|
}
|
|
79
|
-
|
|
73
|
+
watch(state, () => {
|
|
74
|
+
updateUrl()
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
return state
|
|
80
78
|
}
|
|
81
79
|
// uses pattern for SSR friendly plugin/composable, cf https://antfu.me/posts/composable-vue-vueday-2021#shared-state-ssr-friendly
|
|
82
|
-
export const reactiveSearchParamsKey = Symbol('reactiveSearchParams')
|
|
83
|
-
export function createReactiveSearchParams(router) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
export const reactiveSearchParamsKey = Symbol('reactiveSearchParams')
|
|
81
|
+
export function createReactiveSearchParams (router) {
|
|
82
|
+
const reactiveSearchParams = getReactiveSearchParams(router)
|
|
83
|
+
return {
|
|
84
|
+
install (app) { app.provide(reactiveSearchParamsKey, reactiveSearchParams) },
|
|
85
|
+
value: reactiveSearchParams
|
|
86
|
+
}
|
|
89
87
|
}
|
|
90
|
-
export function useReactiveSearchParams() {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return reactiveSearchParams;
|
|
88
|
+
export function useReactiveSearchParams () {
|
|
89
|
+
const reactiveSearchParams = inject(reactiveSearchParamsKey)
|
|
90
|
+
if (!reactiveSearchParams) { throw new Error('useReactiveSearchParams requires using the plugin createReactiveSearchParams') }
|
|
91
|
+
return reactiveSearchParams
|
|
95
92
|
}
|
|
96
93
|
export const useStringSearchParam = (key, options = {}) => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
};
|
|
94
|
+
const reactiveSearchParams = useReactiveSearchParams()
|
|
95
|
+
const defaultValue = typeof options === 'string' ? options : (options.default ?? '')
|
|
96
|
+
return computed({
|
|
97
|
+
get: () => reactiveSearchParams[key] ?? defaultValue,
|
|
98
|
+
set: (value) => {
|
|
99
|
+
if (value === defaultValue) { delete reactiveSearchParams[key] } else { reactiveSearchParams[key] = value }
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
}
|
|
109
103
|
export const useBooleanSearchParam = (key, options = {}) => {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
};
|
|
104
|
+
const reactiveSearchParams = useReactiveSearchParams()
|
|
105
|
+
const defaultValue = typeof options === 'boolean' ? options : (options.default ?? false)
|
|
106
|
+
const strings = (typeof options !== 'boolean' && options.strings) || ['1', '0']
|
|
107
|
+
return computed({
|
|
108
|
+
get: () => key in reactiveSearchParams ? reactiveSearchParams[key] === strings[0] : defaultValue,
|
|
109
|
+
set: (value) => {
|
|
110
|
+
if (value === defaultValue) { delete reactiveSearchParams[key] } else { reactiveSearchParams[key] = value ? strings[0] : strings[1] }
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
}
|
|
123
114
|
export const useNumberSearchParam = (key) => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
reactiveSearchParams[key] = '' + value;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
};
|
|
115
|
+
const reactiveSearchParams = useReactiveSearchParams()
|
|
116
|
+
return computed({
|
|
117
|
+
get: () => {
|
|
118
|
+
if (key in reactiveSearchParams) {
|
|
119
|
+
const value = Number(reactiveSearchParams[key])
|
|
120
|
+
if (!isNaN(value)) { return value }
|
|
121
|
+
}
|
|
122
|
+
return null
|
|
123
|
+
},
|
|
124
|
+
set: (value) => {
|
|
125
|
+
if (value === null) { delete reactiveSearchParams[key] } else { reactiveSearchParams[key] = '' + value }
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
}
|
|
142
129
|
export const useStringsArraySearchParam = (key, options = {}) => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
};
|
|
155
|
-
export default useReactiveSearchParams;
|
|
130
|
+
const reactiveSearchParams = useReactiveSearchParams()
|
|
131
|
+
// const style = typeof options === 'string' ? options : (options.style ?? 'csv')
|
|
132
|
+
return computed({
|
|
133
|
+
get: () => reactiveSearchParams[key] ? reactiveSearchParams[key]?.split(',') : [],
|
|
134
|
+
set: (value) => {
|
|
135
|
+
if (value.length === 0) { delete reactiveSearchParams[key] } else { reactiveSearchParams[key] = value.join(',') }
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
export default useReactiveSearchParams
|
package/session.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { type Ref, App } from 'vue';
|
|
|
3
3
|
import { type RouteLocation } from 'vue-router';
|
|
4
4
|
import { type fetch } from 'ofetch';
|
|
5
5
|
import { type SessionState, type SessionStateAuthenticated } from '@data-fair/lib-common-types/session/index.js';
|
|
6
|
+
export type { SessionState, SessionStateAuthenticated, User, Account } from '@data-fair/lib-common-types/session/index.js';
|
|
6
7
|
interface GenericCookies {
|
|
7
8
|
get: (key: string) => string | undefined;
|
|
8
9
|
set: (key: string, value: string, options?: Record<string, any>) => void;
|