|
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