forked from sheepzh/time-tracker-4-browser
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontext.ts
More file actions
95 lines (77 loc) · 3.4 KB
/
context.ts
File metadata and controls
95 lines (77 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { useLocalStorage, useProvide, useProvider } from "@hooks"
import { reactive, type Reactive, ref, type Ref, toRaw, watch } from "vue"
import { type RouteLocation, type Router, useRoute, useRouter } from "vue-router"
import type { DisplayComponent, ReportFilterOption, ReportQueryParam, ReportSort } from "./types"
type Context = {
filter: Reactive<ReportFilterOption>
sort: Ref<ReportSort>
comp: Ref<DisplayComponent | undefined>
}
const NAMESPACE = 'report'
type QueryPartial = PartialPick<ReportFilterOption, 'query' | 'dateRange' | 'mergeDate' | 'siteMerge'>
/**
* Init the query parameters
*/
function parseQuery(route: RouteLocation, router: Router): [QueryPartial, ReportSort['prop'] | undefined] {
const routeQuery = route.query as unknown as ReportQueryParam
const { q, mm, md, ds, de, sc } = routeQuery
const dateStart = ds ? new Date(Number.parseInt(ds)) : undefined
const dateEnd = de ? new Date(Number.parseInt(de)) : undefined
// Remove queries
router.replace({ query: {} })
const now = new Date()
const partial: QueryPartial = {
...(q && { query: q }),
...((md === 'true' || md === '1') && { mergeDate: true }),
...((dateStart ?? dateEnd) && { dateRange: [dateStart ?? now, dateEnd ?? now] }),
...(mm && { siteMerge: mm })
}
return [partial, sc ? sc satisfies ReportSort['prop'] : undefined]
}
type FilterStorageValue = Omit<ReportFilterOption, 'dateRange' | 'readRemote'> & {
dateStart?: number
dateEnd?: number
}
const cvtStorage2Filter = (storage: FilterStorageValue | undefined): ReportFilterOption => {
const { query, dateStart, dateEnd, mergeDate, siteMerge, cateIds, timeFormat } = storage || {}
const now = new Date()
return {
query,
dateRange: [dateStart ? new Date(dateStart) : now, dateEnd ? new Date(dateEnd) : now],
mergeDate: mergeDate ?? false,
siteMerge,
cateIds,
timeFormat: timeFormat ?? 'default',
readRemote: false,
}
}
const cvtFilter2Storage = (filter: ReportFilterOption): FilterStorageValue => {
const { query, dateRange, mergeDate, siteMerge, cateIds, timeFormat } = filter
return {
query,
mergeDate, siteMerge,
dateStart: dateRange?.[0]?.getTime?.(),
dateEnd: dateRange?.[1]?.getTime?.(),
cateIds, timeFormat,
}
}
export const initReportContext = () => {
const route = useRoute()
const router = useRouter()
const [queryFilter, querySort] = parseQuery(route, router)
const [cachedFilter, setCachedFilter] = useLocalStorage<FilterStorageValue>('report_filter')
const initialFilter: ReportFilterOption = { ...cvtStorage2Filter(cachedFilter), ...queryFilter }
const filter = reactive(initialFilter)
watch(() => filter, v => setCachedFilter(cvtFilter2Storage(toRaw(v))), { deep: true })
const sort = ref<ReportSort>({
order: 'descending',
prop: querySort || 'focus'
})
const comp = ref<DisplayComponent>()
const context: Context = { filter, sort, comp }
useProvide<Context>(NAMESPACE, context)
return context
}
export const useReportFilter = (): Reactive<ReportFilterOption> => useProvider<Context, 'filter'>(NAMESPACE, "filter").filter
export const useReportSort = (): Ref<ReportSort> => useProvider<Context, 'sort'>(NAMESPACE, 'sort').sort
export const useReportComponent = () => useProvider<Context, 'comp'>(NAMESPACE, 'comp').comp