Skip to content

Commit ff182a2

Browse files
committed
Persist filter and aggregations opened state in LocalStorage
1 parent 11e8197 commit ff182a2

File tree

5 files changed

+92
-10
lines changed

5 files changed

+92
-10
lines changed

site/frontend/src/pages/compare/header/filters.vue

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {DataFilter} from "../types";
44
import Tooltip from "../tooltip.vue";
55
import {ref, toRaw, watch} from "vue";
66
import {deepCopy} from "../../../utils/copy";
7+
import {PREF_FILTERS_OPENED} from "../prefs";
8+
import {createPersistedRef} from "../../../storage";
79
810
const props = defineProps<{
911
// When reset, set filter to this value
@@ -30,16 +32,12 @@ watch(
3032
{deep: true}
3133
);
3234
33-
function updateOpened(opened: boolean) {
34-
filterOpened.value = opened;
35-
}
36-
37-
const filterOpened = ref(false);
35+
const opened = createPersistedRef(PREF_FILTERS_OPENED);
3836
</script>
3937

4038
<template>
4139
<fieldset class="collapsible-section">
42-
<Toggle :opened="filterOpened" @change="updateOpened">
40+
<Toggle :opened="opened" @change="(value) => (opened = value)">
4341
<template #label>Filters</template>
4442
<template #content>
4543
<div>

site/frontend/src/pages/compare/page.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,14 @@ async function loadCompareData(
163163
selector: CompareSelector,
164164
loading: Ref<boolean>
165165
) {
166-
const response: CompareResponse = await withLoading(loading, async () => {
166+
data.value = await withLoading(loading, async () => {
167167
const params = {
168168
start: selector.start,
169169
end: selector.end,
170170
stat: selector.stat,
171171
};
172172
return await postMsgpack<CompareResponse>(COMPARE_DATA_URL, params);
173173
});
174-
data.value = response;
175174
totalSummary.value = computeSummary(
176175
filterNonRelevant(
177176
defaultFilter,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {createStoredValue} from "../../storage";
2+
3+
export const PREF_FILTERS_OPENED = createStoredValue(
4+
"compare.filters-opened",
5+
false
6+
);
7+
export const PREF_AGGREGATIONS_OPENED = createStoredValue(
8+
"compare.aggregations-opened",
9+
false
10+
);

site/frontend/src/pages/compare/summary/aggregations.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import {computeSummary, SummaryGroup, TestCase} from "../data";
33
import Toggle from "../toggle.vue";
44
import SummaryTable from "./summary-table.vue";
5-
import {ref} from "vue";
5+
import {createPersistedRef} from "../../../storage";
6+
import {PREF_AGGREGATIONS_OPENED} from "../prefs";
67
78
const props = defineProps<{
89
cases: TestCase[];
@@ -21,7 +22,7 @@ function calculateSummary(
2122
return computeSummary(benchmarks);
2223
}
2324
24-
const opened = ref(false);
25+
const opened = createPersistedRef(PREF_AGGREGATIONS_OPENED);
2526
</script>
2627

2728
<template>

site/frontend/src/storage.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import {ref, Ref, watch} from "vue";
2+
3+
/**
4+
* Value that is persisted in LocalStorage.
5+
*/
6+
class StoredValue<T> {
7+
private _value: T;
8+
9+
constructor(private key: string, defaultValue: T) {
10+
this._value = getFromStorage<T>(key) ?? defaultValue;
11+
}
12+
13+
get value(): T {
14+
return this._value;
15+
}
16+
17+
store(value: T) {
18+
this._value = value;
19+
console.debug(`Changing local preference ${this.key} to ${value}`);
20+
setToStorage(this.key, value);
21+
}
22+
}
23+
24+
function getFromStorage<T>(key: string): T | null {
25+
try {
26+
if (window.localStorage) {
27+
const found = window.localStorage.getItem(key);
28+
if (found !== null) {
29+
try {
30+
return JSON.parse(found) as T;
31+
} catch (e) {
32+
// Something weird is stored inside the storage key.
33+
// We should better remove it.
34+
window.localStorage.removeItem(key);
35+
throw e;
36+
}
37+
}
38+
}
39+
} catch (e) {
40+
console.error(`Error while loading \`${key}\` from local storage: ${e}`);
41+
}
42+
return null;
43+
}
44+
45+
function setToStorage<T>(key: string, value: T) {
46+
try {
47+
if (window.localStorage) {
48+
window.localStorage.setItem(key, JSON.stringify(value));
49+
}
50+
} catch (e) {
51+
console.error(`Error while storing \`${key}\` to local storage: ${e}`);
52+
}
53+
}
54+
55+
const prefix = "rustc-perf.ui";
56+
57+
export function createStoredValue<T>(
58+
key: string,
59+
defaultValue: T
60+
): StoredValue<T> {
61+
return new StoredValue(`${prefix}.${key}`, defaultValue);
62+
}
63+
64+
/**
65+
* Creates a reactive variable whose state will be persisted to the passed
66+
* `storedValue`.
67+
*/
68+
export function createPersistedRef<T>(storedValue: StoredValue<T>): Ref<T> {
69+
const value = ref(storedValue.value) as Ref<T>;
70+
watch(value, (newValue) => {
71+
storedValue.store(newValue);
72+
});
73+
return value;
74+
}

0 commit comments

Comments
 (0)