Skip to content

Commit e9a5cc8

Browse files
committed
Reworked Tables
1 parent 15a439b commit e9a5cc8

File tree

14 files changed

+390
-838
lines changed

14 files changed

+390
-838
lines changed
Lines changed: 2 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,12 @@
11
import type { StackStatus } from '$features/stacks/models';
2-
import type { FetchClientResponse } from '@exceptionless/fetchclient';
32

43
import NumberFormatter from '$comp/formatters/number.svelte';
54
import TimeAgo from '$comp/formatters/time-ago.svelte';
65
import { Checkbox } from '$comp/ui/checkbox';
76
import { nameof } from '$lib/utils';
8-
import { DEFAULT_LIMIT } from '$shared/api/api.svelte';
9-
import {
10-
type ColumnDef,
11-
type ColumnSort,
12-
getCoreRowModel,
13-
type PaginationState,
14-
renderComponent,
15-
type RowSelectionState,
16-
type TableOptions,
17-
type Updater,
18-
type VisibilityState
19-
} from '@tanstack/svelte-table';
20-
import { PersistedState } from 'runed';
21-
import { untrack } from 'svelte';
7+
import { type ColumnDef, renderComponent } from '@tanstack/svelte-table';
228

23-
import type { GetEventsMode, GetEventsParams } from '../../api.svelte';
9+
import type { GetEventsMode } from '../../api.svelte';
2410
import type { EventSummaryModel, StackSummaryModel, SummaryModel, SummaryTemplateKeys } from '../summary/index';
2511

2612
import Summary from '../summary/summary.svelte';
@@ -138,170 +124,3 @@ export function getColumns<TSummaryModel extends SummaryModel<SummaryTemplateKey
138124

139125
return columns;
140126
}
141-
142-
export function getTableContext<TSummaryModel extends SummaryModel<SummaryTemplateKeys>>(
143-
params: GetEventsParams,
144-
configureOptions: (options: TableOptions<TSummaryModel>) => TableOptions<TSummaryModel> = (options) => options
145-
) {
146-
let _parameters = $state(params);
147-
let _pageCount = $state(0);
148-
let _columns = $state(getColumns<TSummaryModel>(untrack(() => _parameters.mode)));
149-
let _data = $state([] as TSummaryModel[]);
150-
let _loading = $state(false);
151-
let _meta = $state({} as FetchClientResponse<unknown>['meta']);
152-
153-
const [columnVisibility, setColumnVisibility] = createPersistedTableState('events-column-visibility', <VisibilityState>{});
154-
const [pagination, setPagination] = createTableState<PaginationState>({
155-
pageIndex: 0,
156-
pageSize: untrack(() => _parameters.limit) ?? DEFAULT_LIMIT
157-
});
158-
const [sorting, setSorting] = createTableState<ColumnSort[]>([
159-
{
160-
desc: true,
161-
id: 'date'
162-
}
163-
]);
164-
const [rowSelection, setRowSelection] = createTableState<RowSelectionState>({});
165-
const onPaginationChange = (updaterOrValue: Updater<PaginationState>) => {
166-
if (_loading) {
167-
return;
168-
}
169-
170-
_loading = true;
171-
const previousPageIndex = pagination().pageIndex;
172-
setPagination(updaterOrValue);
173-
174-
const currentPageInfo = pagination();
175-
const nextLink = _meta.links?.next?.after as string;
176-
const previousLink = _meta.links?.previous?.before as string;
177-
178-
_parameters = {
179-
..._parameters,
180-
after: currentPageInfo.pageIndex > previousPageIndex ? nextLink : undefined,
181-
before: currentPageInfo.pageIndex < previousPageIndex && currentPageInfo.pageIndex > 0 ? previousLink : undefined,
182-
limit: currentPageInfo.pageSize,
183-
page: !nextLink && !previousLink && currentPageInfo.pageIndex !== 0 ? currentPageInfo.pageIndex + 1 : undefined
184-
};
185-
};
186-
187-
const onSortingChange = (updaterOrValue: Updater<ColumnSort[]>) => {
188-
setSorting(updaterOrValue);
189-
190-
_parameters = {
191-
..._parameters,
192-
after: undefined,
193-
before: undefined,
194-
page: undefined,
195-
sort:
196-
sorting().length > 0
197-
? sorting()
198-
.map((sort) => `${sort.desc ? '-' : ''}${sort.id}`)
199-
.join(',')
200-
: undefined
201-
};
202-
};
203-
204-
const options = configureOptions({
205-
get columns() {
206-
return _columns;
207-
},
208-
set columns(value) {
209-
_columns = value;
210-
},
211-
get data() {
212-
return _data;
213-
},
214-
set data(value) {
215-
_data = value;
216-
},
217-
enableMultiRowSelection: true,
218-
enableRowSelection: true,
219-
enableSortingRemoval: false,
220-
getCoreRowModel: getCoreRowModel(),
221-
getRowId: (originalRow) => originalRow.id,
222-
manualPagination: true,
223-
manualSorting: true,
224-
onColumnVisibilityChange: setColumnVisibility,
225-
onPaginationChange,
226-
onRowSelectionChange: setRowSelection,
227-
onSortingChange,
228-
get pageCount() {
229-
return _pageCount;
230-
},
231-
state: {
232-
get columnVisibility() {
233-
return columnVisibility();
234-
},
235-
get pagination() {
236-
return pagination();
237-
},
238-
get rowSelection() {
239-
return rowSelection();
240-
},
241-
get sorting() {
242-
return sorting();
243-
}
244-
}
245-
});
246-
247-
return {
248-
get data() {
249-
return _data;
250-
},
251-
set data(value) {
252-
_data = value;
253-
},
254-
get loading() {
255-
return _loading;
256-
},
257-
get meta() {
258-
return _meta;
259-
},
260-
set meta(value) {
261-
_meta = value;
262-
263-
const limit = _parameters.limit ?? DEFAULT_LIMIT;
264-
const total = (_meta?.total as number) ?? 0;
265-
_pageCount = Math.ceil(total / limit);
266-
267-
_loading = false;
268-
},
269-
options,
270-
get pageCount() {
271-
return _pageCount;
272-
},
273-
get parameters() {
274-
return _parameters;
275-
}
276-
};
277-
}
278-
279-
function createPersistedTableState<T>(key: string, initialValue: T): [() => T, (updater: Updater<T>) => void] {
280-
const persistedValue = new PersistedState<T>(key, initialValue);
281-
282-
return [
283-
() => persistedValue.current,
284-
(updater: Updater<T>) => {
285-
if (updater instanceof Function) {
286-
persistedValue.current = updater(persistedValue.current);
287-
} else {
288-
persistedValue.current = updater;
289-
}
290-
}
291-
];
292-
}
293-
294-
function createTableState<T>(initialValue: T): [() => T, (updater: Updater<T>) => void] {
295-
let value = $state(initialValue);
296-
297-
return [
298-
() => value,
299-
(updater: Updater<T>) => {
300-
if (updater instanceof Function) {
301-
value = updater(value);
302-
} else {
303-
value = updater;
304-
}
305-
}
306-
];
307-
}
Lines changed: 30 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
1-
import type { ClientConfigurationSetting } from '$features/projects/models';
1+
import type { ProblemDetails } from '@exceptionless/fetchclient';
2+
import type { CreateQueryResult } from '@tanstack/svelte-query';
23

34
import ProjectConfigActionsCell from '$features/projects/components/table/project-config-actions-cell.svelte';
4-
import {
5-
type ColumnDef,
6-
getCoreRowModel,
7-
getPaginationRowModel,
8-
renderComponent,
9-
type TableOptions,
10-
type Updater,
11-
type VisibilityState
12-
} from '@tanstack/svelte-table';
13-
import { PersistedState } from 'runed';
5+
import { type ClientConfiguration, ClientConfigurationSetting } from '$features/projects/models';
6+
import { getSharedTableOptions, type TableMemoryPagingParameters } from '$features/shared/table.svelte';
7+
import { type ColumnDef, renderComponent } from '@tanstack/svelte-table';
148

15-
export type ProjectClientConfigurationSettingsParameters = {
16-
limit: number;
9+
export type ConfigurationSettingsColumnParameters = {
1710
projectId: string;
1811
};
1912

2013
export function getColumns<TClientConfigurationSetting extends ClientConfigurationSetting>(
21-
params: ProjectClientConfigurationSettingsParameters
14+
params: ConfigurationSettingsColumnParameters
2215
): ColumnDef<TClientConfigurationSetting>[] {
2316
const columns: ColumnDef<TClientConfigurationSetting>[] = [
2417
{
@@ -54,63 +47,34 @@ export function getColumns<TClientConfigurationSetting extends ClientConfigurati
5447
return columns;
5548
}
5649

57-
export function getTableContext<TClientConfigurationSetting extends ClientConfigurationSetting>(
58-
params: ProjectClientConfigurationSettingsParameters,
59-
configureOptions: (options: TableOptions<TClientConfigurationSetting>) => TableOptions<TClientConfigurationSetting> = (options) => options
50+
export function getTableOptions<TClientConfigurationSetting extends ClientConfigurationSetting>(
51+
columnParameters: ConfigurationSettingsColumnParameters,
52+
queryParameters: TableMemoryPagingParameters,
53+
queryResponse: CreateQueryResult<ClientConfiguration, ProblemDetails>
6054
) {
61-
let _columns = $state(getColumns<TClientConfigurationSetting>(params));
62-
let _data = $state([] as TClientConfigurationSetting[]);
55+
const knownSettingsToHide = ['@@log:*', '@@DataExclusions', '@@IncludePrivateInformation', '@@UserAgentBotPatterns', 'UserNamespaces', 'CommonMethods'];
56+
const queryData = $derived(
57+
Object.entries(queryResponse.data?.settings ?? {})
58+
.map(([key, value]) => {
59+
const config = new ClientConfigurationSetting() as TClientConfigurationSetting;
60+
config.key = key;
61+
config.value = value;
62+
return config;
63+
})
64+
.filter((setting) => !knownSettingsToHide.includes(setting.key))
65+
);
6366

64-
const [columnVisibility, setColumnVisibility] = createPersistedTableState('project-config-column-visibility', <VisibilityState>{});
65-
const options = configureOptions({
67+
return getSharedTableOptions<TClientConfigurationSetting>({
68+
columnPersistenceKey: 'projects-configuration-values-column-visibility',
6669
get columns() {
67-
return _columns;
70+
return getColumns<TClientConfigurationSetting>(columnParameters);
6871
},
69-
set columns(value) {
70-
_columns = value;
72+
paginationStrategy: 'memory',
73+
get queryData() {
74+
return queryData;
7175
},
72-
get data() {
73-
return _data;
74-
},
75-
set data(value) {
76-
_data = value;
77-
},
78-
enableMultiRowSelection: true,
79-
enableRowSelection: true,
80-
enableSortingRemoval: false,
81-
getCoreRowModel: getCoreRowModel(),
82-
getPaginationRowModel: getPaginationRowModel(),
83-
getRowId: (originalRow) => originalRow.key,
84-
onColumnVisibilityChange: setColumnVisibility,
85-
state: {
86-
get columnVisibility() {
87-
return columnVisibility();
88-
}
76+
get queryParameters() {
77+
return queryParameters;
8978
}
9079
});
91-
92-
return {
93-
get data() {
94-
return _data;
95-
},
96-
set data(value) {
97-
_data = value;
98-
},
99-
options
100-
};
101-
}
102-
103-
function createPersistedTableState<T>(key: string, initialValue: T): [() => T, (updater: Updater<T>) => void] {
104-
const persistedValue = new PersistedState<T>(key, initialValue);
105-
106-
return [
107-
() => persistedValue.current,
108-
(updater: Updater<T>) => {
109-
if (updater instanceof Function) {
110-
persistedValue.current = updater(persistedValue.current);
111-
} else {
112-
persistedValue.current = updater;
113-
}
114-
}
115-
];
11680
}

src/Exceptionless.Web/ClientApp/src/lib/features/projects/components/table/options.svelte.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import NumberFormatter from '$comp/formatters/number.svelte';
55
import ProjectActionsCell from '$features/projects/components/table/project-actions-cell.svelte';
66
import { ViewProject } from '$features/projects/models';
77
import { getSharedTableOptions } from '$features/shared/table.svelte';
8-
import { type ColumnDef, renderComponent, type TableOptions } from '@tanstack/svelte-table';
8+
import { type ColumnDef, renderComponent } from '@tanstack/svelte-table';
99

1010
import type { GetOrganizationProjectsParams, GetProjectsMode } from '../../api.svelte';
1111

@@ -60,23 +60,22 @@ export function getColumns<TProject extends ViewProject>(mode: GetProjectsMode =
6060

6161
export function getTableOptions<TProject extends ViewProject>(
6262
queryParameters: GetOrganizationProjectsParams,
63-
queryResponse: CreateQueryResult<FetchClientResponse<TProject[]>, ProblemDetails>,
64-
configureOptions: (options: TableOptions<TProject>) => TableOptions<TProject> = (options) => options
63+
queryResponse: CreateQueryResult<FetchClientResponse<TProject[]>, ProblemDetails>
6564
) {
66-
return getSharedTableOptions<TProject>(
67-
{
68-
columnPersistenceKey: 'project',
69-
get columns() {
70-
return getColumns<TProject>(queryParameters.mode);
71-
},
72-
paginationStrategy: 'offset',
73-
get queryParameters() {
74-
return queryParameters;
75-
},
76-
get queryResponse() {
77-
return queryResponse.data;
78-
}
65+
return getSharedTableOptions<TProject>({
66+
columnPersistenceKey: 'projects-column-visibility',
67+
get columns() {
68+
return getColumns<TProject>(queryParameters.mode);
7969
},
80-
configureOptions
81-
);
70+
paginationStrategy: 'offset',
71+
get queryData() {
72+
return queryResponse.data?.data ?? [];
73+
},
74+
get queryMeta() {
75+
return queryResponse.data?.meta;
76+
},
77+
get queryParameters() {
78+
return queryParameters;
79+
}
80+
});
8281
}

0 commit comments

Comments
 (0)