Skip to content

Commit 52a1639

Browse files
authored
Merge pull request #2356 from Particular/john/simpler_refresh
Removed auto-refresh from store
2 parents 5b1c6b0 + 00dc42c commit 52a1639

File tree

5 files changed

+112
-63
lines changed

5 files changed

+112
-63
lines changed

src/Frontend/package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"diff": "^7.0.0",
3232
"hex-to-css-filter": "^6.0.0",
3333
"lodash.debounce": "^4.0.8",
34+
"lodash.throttle": "^4.0.8",
3435
"lossless-json": "^4.0.2",
3536
"memoize-one": "^6.0.0",
3637
"moment": "^2.30.1",
Lines changed: 74 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,107 @@
11
<script setup lang="ts">
2-
import { ref } from "vue";
3-
import OnOffSwitch from "./OnOffSwitch.vue";
2+
import { ref, watch } from "vue";
3+
import ListFilterSelector from "@/components/audit/ListFilterSelector.vue";
44
5-
const props = defineProps<{
6-
id: string;
7-
initialTimeout?: number;
8-
onManualRefresh: () => void;
9-
}>();
5+
const props = defineProps<{ isLoading: boolean }>();
6+
const model = defineModel<number | null>({ required: true });
7+
const emit = defineEmits<{ (e: "manualRefresh"): Promise<void> }>();
8+
const autoRefreshOptionsText: [number, string][] = [
9+
[0, "Off"],
10+
[5000, "Every 5 seconds"],
11+
[15000, "Every 15 seconds"],
12+
[30000, "Every 30 seconds"],
13+
[60000, "Every 1 minute"],
14+
[600000, "Every 10 minute"],
15+
[1800000, "Every 30 minute"],
16+
[3600000, "Every 1 hour"],
17+
];
1018
11-
const emit = defineEmits<{ change: [newValue: number | null]; manualRefresh: [] }>();
19+
function extracted() {
20+
const item = autoRefreshOptionsText.find((item) => item[0] === model.value);
1221
13-
const autoRefresh = ref(props.initialTimeout != null);
14-
const refreshTimeout = ref(props.initialTimeout ?? 5);
22+
if (item) {
23+
return item[1];
24+
}
1525
16-
function toggleRefresh() {
17-
autoRefresh.value = !autoRefresh.value;
18-
updateTimeout();
26+
return "Off";
1927
}
2028
21-
function updateTimeout() {
22-
validateTimeout();
23-
emit("change", autoRefresh.value ? refreshTimeout.value * 1000 : null);
24-
}
29+
const selectValue = extracted();
30+
31+
const selectedRefresh = ref<string>(selectValue);
32+
33+
watch(selectedRefresh, (newValue) => {
34+
const item = autoRefreshOptionsText.find((item) => item[1] === newValue);
2535
26-
function validateTimeout() {
27-
refreshTimeout.value = Math.max(1, Math.min(600, refreshTimeout.value));
36+
if (item) {
37+
if (item[0] === 0) {
38+
model.value = null;
39+
} else {
40+
model.value = item[0];
41+
}
42+
}
43+
});
44+
const showSpinning = ref(false);
45+
watch(
46+
() => props.isLoading,
47+
(newValue) => {
48+
if (newValue) {
49+
showSpinning.value = true;
50+
window.setTimeout(() => {
51+
showSpinning.value = false;
52+
}, 1000);
53+
}
54+
}
55+
);
56+
async function refresh() {
57+
await emit("manualRefresh");
2858
}
2959
</script>
3060

3161
<template>
3262
<div class="refresh-config">
33-
<button class="fa" title="refresh" @click="() => emit('manualRefresh')">
34-
<i class="fa fa-lg fa-refresh" />
35-
</button>
36-
<span>|</span>
37-
<label>Auto-Refresh:</label>
38-
<div>
39-
<OnOffSwitch :id="id" @toggle="toggleRefresh" :value="autoRefresh" />
63+
<button class="btn btn-sm" title="refresh" @click="refresh"><i class="fa fa-refresh" :class="{ spinning: showSpinning }" /> Refresh List</button>
64+
<div class="filter">
65+
<div class="filter-label">Auto-Refresh:</div>
66+
<div class="filter-component">
67+
<ListFilterSelector :items="autoRefreshOptionsText.map((i) => i[1])" v-model="selectedRefresh" item-name="result" :can-clear="false" :show-clear="false" :show-filter="false" />
68+
</div>
4069
</div>
41-
<input type="number" v-model="refreshTimeout" min="1" max="600" v-on:change="updateTimeout" />
42-
<span class="unit">s</span>
4370
</div>
4471
</template>
4572

4673
<style scoped>
4774
.refresh-config {
4875
display: flex;
4976
align-items: center;
50-
gap: 0.5em;
51-
}
52-
53-
.refresh-config .unit {
54-
margin-left: -0.45em;
77+
gap: 1em;
78+
margin-bottom: 0.5em;
5579
}
5680
57-
.refresh-config label {
58-
margin: 0;
59-
}
60-
61-
.refresh-config input {
62-
width: 3.5em;
81+
.filter {
82+
display: flex;
83+
align-items: center;
6384
}
6485
65-
.refresh-config button {
66-
background: none;
67-
border: none;
68-
width: 2em;
86+
.filter-label {
87+
font-weight: bold;
6988
}
7089
71-
.refresh-config button .fa {
72-
transition: all 0.15s ease-in-out;
73-
transition: rotate 0.05s ease-in-out;
74-
transform-origin: center;
90+
@keyframes spin {
91+
from {
92+
transform: rotate(0deg);
93+
}
94+
to {
95+
transform: rotate(360deg);
96+
}
7597
}
7698
77-
.refresh-config button:hover .fa {
78-
color: #00a3c4;
79-
transform: scale(1.1);
99+
.fa-refresh {
100+
display: inline-block;
80101
}
81102
82-
.refresh-config button:active .fa {
83-
transform: rotate(25deg);
84-
text-shadow: #929e9e 0.25px 0.25px;
103+
/* You can add this class dynamically when needed */
104+
.fa-refresh.spinning {
105+
animation: spin 1s linear infinite;
85106
}
86107
</style>

src/Frontend/src/components/audit/AuditList.vue

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,33 @@ import { useRoute, useRouter } from "vue-router";
77
import ResultsCount from "@/components/ResultsCount.vue";
88
import { dotNetTimespanToMilliseconds, formatDotNetTimespan } from "@/composables/formatUtils.ts";
99
import FiltersPanel from "@/components/audit/FiltersPanel.vue";
10-
import { onBeforeMount, watch } from "vue";
10+
import { onBeforeMount, onUnmounted, ref, watch } from "vue";
1111
import RefreshConfig from "../RefreshConfig.vue";
12+
import useAutoRefresh from "@/composables/autoRefresh.ts";
13+
import throttle from "lodash/throttle";
1214
1315
const store = useAuditStore();
1416
const { messages, totalCount, sortBy, messageFilterString, selectedEndpointName, itemsPerPage, dateRange } = storeToRefs(store);
1517
const route = useRoute();
1618
const router = useRouter();
19+
const autoRefreshValue = ref<number | null>(null);
20+
const isLoading = ref(false);
21+
22+
const dataRetriever = useAutoRefresh(
23+
throttle(async () => {
24+
isLoading.value = true;
25+
try {
26+
await store.refresh();
27+
} finally {
28+
isLoading.value = false;
29+
}
30+
}, 2000),
31+
null
32+
);
33+
34+
onUnmounted(() => {
35+
dataRetriever.updateTimeout(null);
36+
});
1737
1838
function statusToName(messageStatus: MessageStatus) {
1939
switch (messageStatus) {
@@ -74,7 +94,7 @@ onBeforeMount(() => {
7494
7595
//without setTimeout, this happens before the store is properly initialised, and therefore the query route values aren't applied to the refresh
7696
//TODO: is there a better way to achieve this?
77-
setTimeout(async () => await Promise.all([store.refresh(), store.loadEndpoints()]), 0);
97+
setTimeout(async () => await Promise.all([dataRetriever.executeAndResetTimer(), store.loadEndpoints()]), 0);
7898
7999
firstLoad = false;
80100
});
@@ -83,7 +103,7 @@ watch(
83103
() => router.currentRoute.value.query,
84104
async () => {
85105
setQuery();
86-
await store.refresh();
106+
await dataRetriever.executeAndResetTimer();
87107
},
88108
{ deep: true }
89109
);
@@ -109,7 +129,7 @@ const watchHandle = watch([() => route.query, itemsPerPage, sortBy, messageFilte
109129
},
110130
});
111131
112-
await store.refresh();
132+
await dataRetriever.executeAndResetTimer();
113133
});
114134
115135
function setQuery() {
@@ -128,12 +148,14 @@ function setQuery() {
128148
129149
watchHandle.resume();
130150
}
151+
152+
watch(autoRefreshValue, (newValue) => dataRetriever.updateTimeout(newValue));
131153
</script>
132154

133155
<template>
134156
<div>
135157
<div class="header">
136-
<RefreshConfig id="auditListRefresh" @change="store.updateRefreshTimer" @manual-refresh="store.refresh" />
158+
<RefreshConfig v-model="autoRefreshValue" :isLoading="isLoading" @manual-refresh="dataRetriever.executeAndResetTimer()" />
137159
<div class="row">
138160
<FiltersPanel />
139161
</div>

src/Frontend/src/stores/AuditStore.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { ref } from "vue";
44
import type { SortInfo } from "@/components/SortInfo";
55
import Message from "@/resources/Message";
66
import { EndpointsView } from "@/resources/EndpointView.ts";
7-
import useAutoRefresh from "@/composables/autoRefresh";
87

98
export type DateRange = [fromDate: Date, toDate: Date] | [];
109

@@ -39,7 +38,7 @@ export const useAuditStore = defineStore("AuditStore", () => {
3938
}
4039
}
4140

42-
const dataRetriever = useAutoRefresh(async () => {
41+
async function refresh() {
4342
try {
4443
const [fromDate, toDate] = dateRange.value;
4544
const from = fromDate?.toISOString() ?? "";
@@ -53,11 +52,10 @@ export const useAuditStore = defineStore("AuditStore", () => {
5352
messages.value = [];
5453
throw e;
5554
}
56-
}, null);
55+
}
5756

5857
return {
59-
refresh: dataRetriever.executeAndResetTimer,
60-
updateRefreshTimer: dataRetriever.updateTimeout,
58+
refresh,
6159
loadEndpoints,
6260
sortBy: sortByInstances,
6361
messages,

0 commit comments

Comments
 (0)