|
15 | 15 | import { useFetchClientStatus } from '$shared/api/api.svelte';
|
16 | 16 | import { persisted } from '$shared/persisted.svelte';
|
17 | 17 | import { type FetchClientResponse, useFetchClient } from '@exceptionless/fetchclient';
|
18 |
| - import { createTable } from '@tanstack/svelte-table'; |
| 18 | + import { createTable, type RowSelectionState } from '@tanstack/svelte-table'; |
19 | 19 | import { useEventListener } from 'runed';
|
20 | 20 | import { debounce } from 'throttle-debounce';
|
21 | 21 | import IconOpenInNew from '~icons/mdi/open-in-new';
|
|
25 | 25 | selectedEventId = row.id;
|
26 | 26 | }
|
27 | 27 |
|
| 28 | + let showRefreshStaleDataRow = $state(false); |
28 | 29 | const limit = persisted<number>('events.limit', 10);
|
29 | 30 | const defaultFilters = getDefaultFilters();
|
30 | 31 | const persistedFilters = persisted<IFilter[]>('events.filters', defaultFilters, new FilterSerializer());
|
|
77 | 78 | const debouncedLoadData = debounce(10000, loadData);
|
78 | 79 |
|
79 | 80 | async function onPersistentEvent(message: WebSocketMessageValue<'PersistentEventChanged'>) {
|
80 |
| - const shouldRefresh = () => |
81 |
| - shouldRefreshPersistentEventChanged(persistedFilters.value, filter, message.organization_id, message.project_id, message.stack_id, message.id); |
82 |
| -
|
83 |
| - switch (message.change_type) { |
84 |
| - case ChangeType.Added: |
85 |
| - case ChangeType.Saved: |
86 |
| - if (shouldRefresh()) { |
87 |
| - await debouncedLoadData(); |
| 81 | + if (message.id && message.change_type === ChangeType.Removed) { |
| 82 | + // Remove the event from the selection if it was selected |
| 83 | + if (table.getIsSomeRowsSelected()) { |
| 84 | + const { rowSelection } = table.getState(); |
| 85 | + if (message.id && rowSelection[message.id]) { |
| 86 | + table.setRowSelection((old) => { |
| 87 | + const filtered = Object.entries(old).filter(([id]) => id !== message.id); |
| 88 | + return Object.fromEntries(filtered); |
| 89 | + }); |
88 | 90 | }
|
| 91 | + } |
89 | 92 |
|
90 |
| - break; |
91 |
| - case ChangeType.Removed: |
92 |
| - if (shouldRefresh()) { |
93 |
| - if (message.id) { |
94 |
| - table.options.data = table.options.data.filter((doc) => doc.id !== message.id); |
95 |
| - } |
| 93 | + // Remove deleted event from the grid data |
| 94 | + if (table.options.data.find((doc) => doc.id === message.id)) { |
| 95 | + table.options.data = table.options.data.filter((doc) => doc.id !== message.id); |
96 | 96 |
|
| 97 | + // If the grid data is empty from all events being removed, we should refresh the data. |
| 98 | + if (table.options.data.length === 0) { |
97 | 99 | await debouncedLoadData();
|
| 100 | + return; |
98 | 101 | }
|
| 102 | + } |
| 103 | + } |
99 | 104 |
|
100 |
| - break; |
| 105 | + // Do not refresh if the filter criteria doesn't match the web socket message. |
| 106 | + if (!shouldRefreshPersistentEventChanged(persistedFilters.value, filter, message.organization_id, message.project_id, message.stack_id, message.id)) { |
| 107 | + return; |
101 | 108 | }
|
| 109 | +
|
| 110 | + // Do not refresh if the grid has selections. |
| 111 | + if (table.getIsSomeRowsSelected()) { |
| 112 | + showRefreshStaleDataRow = true; |
| 113 | + return; |
| 114 | + } |
| 115 | +
|
| 116 | + // Do not refresh if the grid is currently paged. |
| 117 | + if (table.getPageCount() > 1) { |
| 118 | + showRefreshStaleDataRow = true; |
| 119 | + return; |
| 120 | + } |
| 121 | +
|
| 122 | + await debouncedLoadData(); |
102 | 123 | }
|
103 | 124 |
|
104 | 125 | useEventListener(document, 'refresh', async () => await loadData());
|
|
0 commit comments