Skip to content

Commit 3fa012f

Browse files
authored
Merge pull request #1615 from Kobzol/ui-store-preferences
Store filter and aggregations state in LocalStorage
2 parents 2dd3ea2 + ff182a2 commit 3fa012f

File tree

7 files changed

+116
-26
lines changed

7 files changed

+116
-26
lines changed

site/frontend/src/pages/compare/header/data-selector.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ function submitSettings() {
3737
const params = {start, end, stat};
3838
emit("change", params);
3939
}
40+
41+
const opened = ref(false);
4042
</script>
4143

4244
<template>
4345
<fieldset class="settings">
44-
<Toggle>
46+
<Toggle :opened="opened" @change="(value) => (opened = value)">
4547
<template #label>Do another comparison</template>
4648
<template #content>
4749
<div class="commits section">

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

Lines changed: 15 additions & 14 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
@@ -29,11 +31,13 @@ watch(
2931
},
3032
{deep: true}
3133
);
34+
35+
const opened = createPersistedRef(PREF_FILTERS_OPENED);
3236
</script>
3337

3438
<template>
3539
<fieldset class="collapsible-section">
36-
<Toggle :defaultOpened="false">
40+
<Toggle :opened="opened" @change="(value) => (opened = value)">
3741
<template #label>Filters</template>
3842
<template #content>
3943
<div>
@@ -46,9 +50,8 @@ watch(
4650
<div style="width: 160px">
4751
<span>Profiles</span>
4852
<Tooltip
49-
>The different compilation profiles (check, debug, opt,
50-
doc).</Tooltip
51-
>
53+
>The different compilation profiles (check, debug, opt, doc).
54+
</Tooltip>
5255
</div>
5356
</div>
5457
<ul class="states-list">
@@ -84,9 +87,8 @@ watch(
8487
<span class="cache-label">opt</span>
8588
</label>
8689
<Tooltip
87-
>Release build that produces as optimized code as
88-
possible.</Tooltip
89-
>
90+
>Release build that produces as optimized code as possible.
91+
</Tooltip>
9092
</li>
9193
<li>
9294
<label>
@@ -125,9 +127,8 @@ watch(
125127
<span class="cache-label">full</span>
126128
</label>
127129
<Tooltip
128-
>A non-incremental full build starting with empty
129-
cache.</Tooltip
130-
>
130+
>A non-incremental full build starting with empty cache.
131+
</Tooltip>
131132
</li>
132133
<li>
133134
<label>
@@ -139,8 +140,8 @@ watch(
139140
<span class="cache-label">incr-full</span>
140141
</label>
141142
<Tooltip
142-
>An incremental build starting with empty cache.</Tooltip
143-
>
143+
>An incremental build starting with empty cache.
144+
</Tooltip>
144145
</li>
145146
<li>
146147
<label>
@@ -181,8 +182,8 @@ watch(
181182
<span>Categories</span>
182183
<Tooltip
183184
>Select benchmarks based on their category (primary or
184-
secondary).</Tooltip
185-
>
185+
secondary).
186+
</Tooltip>
186187
</div>
187188
</div>
188189
<ul class="states-list">

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: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import {computeSummary, SummaryGroup, TestCase} from "../data";
33
import Toggle from "../toggle.vue";
44
import SummaryTable from "./summary-table.vue";
5+
import {createPersistedRef} from "../../../storage";
6+
import {PREF_AGGREGATIONS_OPENED} from "../prefs";
57
68
const props = defineProps<{
79
cases: TestCase[];
@@ -19,11 +21,13 @@ function calculateSummary(
1921
}
2022
return computeSummary(benchmarks);
2123
}
24+
25+
const opened = createPersistedRef(PREF_AGGREGATIONS_OPENED);
2226
</script>
2327

2428
<template>
2529
<fieldset class="collapsible-section">
26-
<Toggle>
30+
<Toggle :opened="opened" @change="(value) => (opened = value)">
2731
<template #label>Aggregations</template>
2832
<template #content>
2933
<div>

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
<script setup lang="ts">
2-
import {ref} from "vue";
3-
42
const props = withDefaults(
53
defineProps<{
6-
defaultOpened?: boolean;
4+
opened?: boolean;
75
}>(),
86
{
9-
defaultOpened: false,
7+
opened: false,
108
}
119
);
1210
13-
const opened = ref(props.defaultOpened);
11+
const emit = defineEmits<{
12+
(e: "change", opened: boolean): void;
13+
}>();
1414
</script>
1515

1616
<template>
17-
<legend class="toggle section-heading" @click="opened = !opened">
17+
<legend class="toggle section-heading" @click="emit('change', !props.opened)">
1818
<slot name="label"></slot>
19-
<span>{{ opened ? " ▼" : " ▶" }}</span>
19+
<span>{{ props.opened ? " ▼" : " ▶" }}</span>
2020
</legend>
21-
<div v-show="opened">
21+
<div v-show="props.opened">
2222
<slot name="content"></slot>
2323
</div>
2424
</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)