Skip to content

Commit f0dc410

Browse files
author
sheepzh
committed
Support memory function of the filter items (#168)
1 parent 3d80d6c commit f0dc410

File tree

7 files changed

+148
-28
lines changed

7 files changed

+148
-28
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Copyright (c) 2022-present Hengyang Zhang
3+
*
4+
* This software is released under the MIT License.
5+
* https://opensource.org/licenses/MIT
6+
*/
7+
8+
/**
9+
* The wrapper of filter item history
10+
*
11+
* @param path path of route
12+
* @param paramName the name of param
13+
*/
14+
class FilterItemHistoryWrapper {
15+
private key: string
16+
17+
constructor(path: string, paramName: string) {
18+
if (!path || !paramName) {
19+
this.key = undefined
20+
} else {
21+
this.key = `__filter_item_history_value_${path}_${paramName}`
22+
}
23+
}
24+
25+
/**
26+
* get the value
27+
*
28+
* @returns val of undefined
29+
*/
30+
getValue(): string {
31+
if (!this.key) {
32+
return undefined
33+
}
34+
return localStorage.getItem(this.key)
35+
}
36+
37+
/**
38+
* Set new value
39+
*
40+
* @param newVal
41+
*/
42+
setValue(newVal: string) {
43+
newVal && this.key && localStorage.setItem(this.key, newVal)
44+
}
45+
46+
/**
47+
* Do something if the value exists
48+
*
49+
* @param callback
50+
*/
51+
ifPresent(callback: (historyVal: string) => void) {
52+
const val = this.getValue()
53+
val && callback?.(val)
54+
}
55+
}
56+
57+
export default FilterItemHistoryWrapper

src/app/components/common/select-filter-item.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,49 @@
11

2-
import { PropType, Ref, watch } from "vue"
2+
import type { PropType, Ref } from "vue"
3+
import type { RouteLocation } from "vue-router"
34

5+
import { watch } from "vue"
46
import { ElOption, ElSelect } from "element-plus"
5-
import { defineComponent, h, ref } from "vue"
7+
import { defineComponent, h, ref, nextTick } from "vue"
8+
import { useRoute } from "vue-router"
9+
import FilterItemHistoryWrapper from "./filter-item-history-wrapper"
10+
11+
const PREFIX = "__filter_select_history_value_"
12+
13+
function calcHistoryKey(route: RouteLocation, historyName: string): string {
14+
if (!historyName) {
15+
return undefined
16+
} else {
17+
return PREFIX + route.path + '_' + historyName
18+
}
19+
}
620

721
const _default = defineComponent({
822
name: "SelectFilterItem",
923
props: {
1024
defaultValue: String,
25+
/**
26+
* Whether to save the value in the localstorage with {@param historyName}
27+
*/
28+
historyName: {
29+
type: String,
30+
required: false
31+
},
1132
options: Object as PropType<Record<string | number, string>>
1233
},
1334
emits: ['select'],
1435
setup(props, ctx) {
1536
const modelValue: Ref<string> = ref(props.defaultValue)
16-
watch(modelValue, () => ctx.emit('select', modelValue.value))
37+
const historyWrapper = new FilterItemHistoryWrapper(useRoute().path, props.historyName)
38+
// Initiliaze value
39+
historyWrapper.ifPresent(
40+
historyVal => nextTick(() => ctx.emit('select', (modelValue.value = historyVal)))
41+
)
42+
43+
watch(modelValue, () => {
44+
ctx.emit('select', modelValue.value)
45+
historyWrapper.setValue(modelValue.value)
46+
})
1747
return () => h(ElSelect, {
1848
class: 'filter-item',
1949
modelValue: modelValue.value,

src/app/components/common/switch-filter-item.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,23 @@
44
* This software is released under the MIT License.
55
* https://opensource.org/licenses/MIT
66
*/
7-
import type { Ref } from "vue"
7+
import { nextTick, Ref } from "vue"
8+
import type { RouteLocation } from "vue-router"
89

910
import { ElSwitch } from "element-plus"
1011
import { defineComponent, h, ref } from "vue"
12+
import { useRoute } from "vue-router"
13+
import FilterItemHistoryWrapper from "./filter-item-history-wrapper"
14+
15+
const PREFIX = "__filter_select_history_value_"
16+
17+
function calcHistoryKey(route: RouteLocation, historyName: string): string {
18+
if (!historyName) {
19+
return undefined
20+
} else {
21+
return PREFIX + route.path + '_' + historyName
22+
}
23+
}
1124

1225
const _default = defineComponent({
1326
name: "SwitchFilterItem",
@@ -16,17 +29,32 @@ const _default = defineComponent({
1629
type: Boolean,
1730
default: false
1831
},
32+
/**
33+
* Whether to save the value in the localstorage with {@param historyName}
34+
*/
35+
historyName: {
36+
type: String,
37+
required: false
38+
},
1939
label: String
2040
},
2141
emits: ["change"],
2242
setup(props, ctx) {
2343
const modelValue: Ref<boolean> = ref(props.defaultValue)
44+
const historyWrapper = new FilterItemHistoryWrapper(useRoute().path, props.historyName)
45+
// Initiliaze value
46+
historyWrapper.ifPresent(
47+
historyVal => nextTick(() => ctx.emit('change', (modelValue.value = historyVal === 'true')))
48+
)
2449
return () => h("span", { class: "filter-switch" }, [
2550
h('a', { class: 'filter-name' }, props.label),
2651
h(ElSwitch, {
2752
class: 'filter-item',
2853
modelValue: modelValue.value,
29-
onChange: (val: boolean) => ctx.emit("change", modelValue.value = val)
54+
onChange(val: boolean) {
55+
ctx.emit("change", modelValue.value = val)
56+
historyWrapper.setValue(modelValue.value?.toString?.())
57+
}
3058
})
3159
])
3260
}

src/app/components/habit/component/filter.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
* https://opensource.org/licenses/MIT
66
*/
77

8-
import { ElOption, ElSelect } from "element-plus"
9-
import { ref, Ref, h, defineComponent, PropType } from "vue"
8+
import type { PropType } from "vue"
9+
import type { HabitMessage } from "@app/locale/components/habit"
10+
11+
import { ref, Ref, h, defineComponent } from "vue"
1012
import { daysAgo } from "@util/time"
1113
import { t } from "@app/locale"
12-
import { HabitMessage } from "@app/locale/components/habit"
1314
import SwitchFilterItem from "@app/components/common/switch-filter-item"
1415
import { ElementDatePickerShortcut } from "@src/element-ui/date"
1516
import DateRangeFilterItem from "@app/components/common/date-range-filter-item"
17+
import SelectFilterItem from "@app/components/common/select-filter-item"
1618

1719
export type HabitFilterOption = {
1820
periodSize: number
@@ -46,17 +48,17 @@ const DATE_RANGE_END_PLACEHOLDER = t(msg => msg.trend.endDate)
4648
// [value, label]
4749
type _SizeOption = [number, keyof HabitMessage['sizes']]
4850

49-
const SIZE_OPTIONS: _SizeOption[] = [
50-
[1, 'fifteen'],
51-
[2, 'halfHour'],
52-
[4, 'hour'],
53-
[8, 'twoHour']
54-
]
55-
56-
const renderSizeOption = ([size, msg]: _SizeOption) => h(ElOption, {
57-
label: t(root => root.habit.sizes[msg]),
58-
value: size
59-
})
51+
function allOptions(): Record<number, string> {
52+
const allOptions = {}
53+
const allSizes: _SizeOption[] = [
54+
[1, 'fifteen'],
55+
[2, 'halfHour'],
56+
[4, 'hour'],
57+
[8, 'twoHour'],
58+
]
59+
allSizes.forEach(([size, msg]) => allOptions[size] = t(root => root.habit.sizes[msg]))
60+
return allOptions
61+
}
6062

6163
const _default = defineComponent({
6264
name: "HabitFilter",
@@ -67,7 +69,6 @@ const _default = defineComponent({
6769
},
6870
emits: ["change"],
6971
setup(props, ctx) {
70-
const trendSearching: Ref<boolean> = ref(false)
7172
const periodSize: Ref<number> = ref(props.periodSize || 1)
7273
// @ts-ignore
7374
const dateRange: Ref<Date[]> = ref(props.dateRange || [])
@@ -81,21 +82,19 @@ const _default = defineComponent({
8182
}
8283
return () => [
8384
// Size select
84-
h(ElSelect, {
85-
placeholder: t(msg => msg.trend.hostPlaceholder),
86-
class: 'filter-item',
87-
modelValue: periodSize.value,
88-
filterable: true,
89-
loading: trendSearching.value,
90-
onChange: (val: string) => {
85+
h(SelectFilterItem, {
86+
historyName: 'periodSize',
87+
defaultValue: periodSize.value?.toString?.(),
88+
options: allOptions(),
89+
onSelect(val: string) {
9190
const newPeriodSize = parseInt(val)
9291
if (isNaN(newPeriodSize)) {
9392
return
9493
}
9594
periodSize.value = newPeriodSize
9695
handleChange()
9796
},
98-
}, () => SIZE_OPTIONS.map(renderSizeOption)),
97+
}),
9998
// Date range picker
10099
h(DateRangeFilterItem, {
101100
startPlaceholder: DATE_RANGE_START_PLACEHOLDER,
@@ -111,6 +110,7 @@ const _default = defineComponent({
111110
}),
112111
// Average by date
113112
h(SwitchFilterItem, {
113+
historyName: 'average',
114114
label: AVERAGE_LABEL,
115115
defaultValue: averageByDate.value,
116116
onChange: (newVal: boolean) => {

src/app/components/limit/filter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const _default = defineComponent({
4444
},
4545
}),
4646
h(SwitchFilterItem, {
47+
historyName: 'onlyEnabled',
4748
label: onlyEnabledLabel,
4849
defaultValue: onlyEnabled.value,
4950
onChange(newVal: boolean) {

src/app/components/report/filter/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ const _default = defineComponent({
100100
}
101101
}),
102102
h(SelectFilterItem, {
103+
historyName: 'timeFormat',
103104
defaultValue: timeFormat.value,
104105
options: timeFormatLabels,
105106
onSelect(newVal: timer.app.TimeFormat) {
@@ -108,6 +109,7 @@ const _default = defineComponent({
108109
}
109110
}),
110111
h(SwitchFilterItem, {
112+
historyName: 'mergeDate',
111113
label: mergeDateLabel,
112114
defaultValue: mergeDate.value,
113115
onChange(newVal: boolean) {
@@ -116,6 +118,7 @@ const _default = defineComponent({
116118
}
117119
}),
118120
h(SwitchFilterItem, {
121+
historyName: 'mergeHost',
119122
label: mergeHostLabel,
120123
defaultValue: mergeHost.value,
121124
onChange(newVal: boolean) {

src/app/components/trend/components/filter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ const _default = defineComponent({
131131
disabledDate: (date: Date) => date.getTime() > new Date().getTime(),
132132
}),
133133
h(SelectFilterItem, {
134+
historyName: 'timeFormat',
134135
defaultValue: timeFormat.value,
135136
options: TIME_FORMAT_LABELS,
136137
onSelect(newVal: timer.app.TimeFormat) {

0 commit comments

Comments
 (0)