Skip to content

Commit 2941718

Browse files
committed
Reworked grid refresh behavior
1 parent dc851b1 commit 2941718

File tree

3 files changed

+51
-34
lines changed

3 files changed

+51
-34
lines changed

src/Exceptionless.Web/ClientApp/src/routes/(app)/+page.svelte

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
import EventsBulkActionsDropdownMenu from '$features/events/components/table/EventsBulkActionsDropdownMenu.svelte';
1414
import EventsDataTable from '$features/events/components/table/EventsDataTable.svelte';
1515
import { getTableContext } from '$features/events/components/table/options.svelte';
16-
import { isTableEmpty, removeTableData, removeTableSelection } from '$features/shared/table';
1716
import { ChangeType, type WebSocketMessageValue } from '$features/websockets/models';
1817
import { useFetchClientStatus } from '$shared/api/api.svelte';
1918
import { persisted } from '$shared/persisted.svelte';
19+
import { isTableEmpty, removeTableData, removeTableSelection } from '$shared/table';
2020
import { type FetchClientResponse, useFetchClient } from '@exceptionless/fetchclient';
2121
import { createTable } from '@tanstack/svelte-table';
2222
import { useEventListener } from 'runed';
23-
import { debounce } from 'throttle-debounce';
23+
import { throttle } from 'throttle-debounce';
2424
import IconOpenInNew from '~icons/mdi/open-in-new';
2525
2626
let selectedEventId: null | string = $state(null);
@@ -76,16 +76,16 @@
7676
context.meta = clientResponse.meta;
7777
}
7878
}
79-
const debouncedLoadData = debounce(10000, loadData);
79+
const throttledLoadData = throttle(10000, loadData);
8080
81-
async function onPersistentEvent(message: WebSocketMessageValue<'PersistentEventChanged'>) {
81+
async function onPersistentEventChanged(message: WebSocketMessageValue<'PersistentEventChanged'>) {
8282
if (message.id && message.change_type === ChangeType.Removed) {
8383
removeTableSelection(table, message.id);
8484
8585
if (removeTableData(table, (doc) => doc.id === message.id)) {
8686
// If the grid data is empty from all events being removed, we should refresh the data.
8787
if (isTableEmpty(table)) {
88-
await debouncedLoadData();
88+
await throttledLoadData();
8989
return;
9090
}
9191
}
@@ -101,11 +101,11 @@
101101
return;
102102
}
103103
104-
await debouncedLoadData();
104+
await throttledLoadData();
105105
}
106106
107107
useEventListener(document, 'refresh', () => loadData());
108-
useEventListener(document, 'PersistentEventChanged', async (event) => await onPersistentEvent((event as CustomEvent).detail));
108+
useEventListener(document, 'PersistentEventChanged', async (event) => await onPersistentEventChanged((event as CustomEvent).detail));
109109
110110
$effect(() => {
111111
loadData();

src/Exceptionless.Web/ClientApp/src/routes/(app)/issues/+page.svelte

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@
1414
import EventsDataTable from '$features/events/components/table/EventsDataTable.svelte';
1515
import { getTableContext } from '$features/events/components/table/options.svelte';
1616
import TableStacksBulkActionsDropdownMenu from '$features/stacks/components/StacksBulkActionsDropdownMenu.svelte';
17-
import { type WebSocketMessageValue } from '$features/websockets/models';
17+
import { ChangeType, type WebSocketMessageValue } from '$features/websockets/models';
1818
import { useFetchClientStatus } from '$shared/api/api.svelte';
1919
import { persisted } from '$shared/persisted.svelte';
20+
import { isTableEmpty, removeTableData, removeTableSelection } from '$shared/table';
2021
import { type FetchClientResponse, useFetchClient } from '@exceptionless/fetchclient';
2122
import { createTable } from '@tanstack/svelte-table';
2223
import { useEventListener } from 'runed';
23-
import { debounce } from 'throttle-debounce';
24+
import { throttle } from 'throttle-debounce';
2425
import IconOpenInNew from '~icons/mdi/open-in-new';
2526
27+
// TODO: Update this page to use StackSummaryModel instead of EventSummaryModel.
2628
let selectedStackId = $state<string>();
2729
function rowclick(row: EventSummaryModel<SummaryTemplateKeys>) {
2830
selectedStackId = row.id;
@@ -94,16 +96,36 @@
9496
context.meta = clientResponse.meta;
9597
}
9698
}
97-
const debouncedLoadData = debounce(10000, loadData);
99+
const throttledLoadData = throttle(10000, loadData);
100+
101+
async function onStackChanged(message: WebSocketMessageValue<'StackChanged'>) {
102+
if (message.id && message.change_type === ChangeType.Removed) {
103+
removeTableSelection(table, message.id);
104+
105+
if (removeTableData(table, (doc) => doc.id === message.id)) {
106+
// If the grid data is empty from all events being removed, we should refresh the data.
107+
if (isTableEmpty(table)) {
108+
await throttledLoadData();
109+
return;
110+
}
111+
}
112+
}
98113
99-
async function onPersistentEvent(message: WebSocketMessageValue<'PersistentEventChanged'>) {
100-
if (shouldRefreshPersistentEventChanged(persistedFilters.value, filter, message.organization_id, message.project_id, message.stack_id, message.id)) {
101-
await debouncedLoadData();
114+
// Do not refresh if the filter criteria doesn't match the web socket message.
115+
if (!shouldRefreshPersistentEventChanged(persistedFilters.value, filter, message.organization_id, message.project_id, message.id)) {
116+
return;
102117
}
118+
119+
// Do not refresh if the grid has selections or grid is currently paged.
120+
if (canRefresh) {
121+
return;
122+
}
123+
124+
await throttledLoadData();
103125
}
104126
105127
useEventListener(document, 'refresh', async () => await loadData());
106-
useEventListener(document, 'PersistentEventChanged', async (event) => await onPersistentEvent((event as CustomEvent).detail));
128+
useEventListener(document, 'StackChanged', async (event) => await onStackChanged((event as CustomEvent).detail));
107129
108130
$effect(() => {
109131
loadData();

src/Exceptionless.Web/ClientApp/src/routes/(app)/stream/+page.svelte

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import { ChangeType, type WebSocketMessageValue } from '$features/websockets/models';
1818
import { useFetchClientStatus } from '$shared/api/api.svelte';
1919
import { persisted } from '$shared/persisted.svelte';
20+
import { isTableEmpty, removeTableData } from '$shared/table';
2021
import { type FetchClientResponse, useFetchClient } from '@exceptionless/fetchclient';
2122
import { createTable } from '@tanstack/svelte-table';
2223
import { useEventListener } from 'runed';
@@ -100,33 +101,27 @@
100101
}
101102
102103
const debouncedLoadData = debounce(5000, loadData);
103-
async function onPersistentEvent(message: WebSocketMessageValue<'PersistentEventChanged'>) {
104-
const shouldRefresh = () =>
105-
shouldRefreshPersistentEventChanged(persistedFilters.value, filter, message.organization_id, message.project_id, message.stack_id, message.id);
106-
107-
switch (message.change_type) {
108-
case ChangeType.Added:
109-
case ChangeType.Saved:
110-
if (shouldRefresh()) {
111-
await debouncedLoadData();
112-
}
113-
114-
break;
115-
case ChangeType.Removed:
116-
if (shouldRefresh()) {
117-
if (message.id) {
118-
table.options.data = table.options.data.filter((doc) => doc.id !== message.id);
119-
}
120-
104+
async function onPersistentEventChanged(message: WebSocketMessageValue<'PersistentEventChanged'>) {
105+
if (message.id && message.change_type === ChangeType.Removed) {
106+
if (removeTableData(table, (doc) => doc.id === message.id)) {
107+
// If the grid data is empty from all events being removed, we should refresh the data.
108+
if (isTableEmpty(table)) {
121109
await debouncedLoadData();
110+
return;
122111
}
112+
}
113+
}
123114
124-
break;
115+
// Do not refresh if the filter criteria doesn't match the web socket message.
116+
if (!shouldRefreshPersistentEventChanged(persistedFilters.value, filter, message.organization_id, message.project_id, message.stack_id, message.id)) {
117+
return;
125118
}
119+
120+
await debouncedLoadData();
126121
}
127122
128123
useEventListener(document, 'refresh', async () => await loadData());
129-
useEventListener(document, 'PersistentEventChanged', (event) => onPersistentEvent((event as CustomEvent).detail));
124+
useEventListener(document, 'PersistentEventChanged', (event) => onPersistentEventChanged((event as CustomEvent).detail));
130125
131126
$effect(() => {
132127
loadData();

0 commit comments

Comments
 (0)