|
1 |
| -import type { FetchClientResponse } from '@exceptionless/fetchclient'; |
| 1 | +import type { FetchClientResponse, ProblemDetails } from '@exceptionless/fetchclient'; |
| 2 | +import type { CreateQueryResult } from '@tanstack/svelte-query'; |
2 | 3 |
|
3 | 4 | import NumberFormatter from '$comp/formatters/number.svelte';
|
4 | 5 | import ProjectActionsCell from '$features/projects/components/table/project-actions-cell.svelte';
|
5 | 6 | import { ViewProject } from '$features/projects/models';
|
6 |
| -import { DEFAULT_LIMIT } from '$shared/api/api.svelte'; |
7 |
| -import { |
8 |
| - type ColumnDef, |
9 |
| - type ColumnSort, |
10 |
| - getCoreRowModel, |
11 |
| - type PaginationState, |
12 |
| - renderComponent, |
13 |
| - type RowSelectionState, |
14 |
| - type TableOptions, |
15 |
| - type Updater, |
16 |
| - type VisibilityState |
17 |
| -} from '@tanstack/svelte-table'; |
18 |
| -import { PersistedState } from 'runed'; |
19 |
| -import { untrack } from 'svelte'; |
| 7 | +import { getSharedTableOptions } from '$features/shared/table.svelte'; |
| 8 | +import { type ColumnDef, renderComponent, type TableOptions } from '@tanstack/svelte-table'; |
20 | 9 |
|
21 | 10 | import type { GetOrganizationProjectsParams, GetProjectsMode } from '../../api.svelte';
|
22 | 11 |
|
@@ -69,164 +58,25 @@ export function getColumns<TProject extends ViewProject>(mode: GetProjectsMode =
|
69 | 58 | return columns;
|
70 | 59 | }
|
71 | 60 |
|
72 |
| -export function getTableContext<TProject extends ViewProject>( |
73 |
| - params: GetOrganizationProjectsParams, |
| 61 | +export function getTableOptions<TProject extends ViewProject>( |
| 62 | + queryParameters: GetOrganizationProjectsParams, |
| 63 | + queryResponse: CreateQueryResult<FetchClientResponse<TProject[]>, ProblemDetails>, |
74 | 64 | configureOptions: (options: TableOptions<TProject>) => TableOptions<TProject> = (options) => options
|
75 | 65 | ) {
|
76 |
| - let _parameters = $state(params); |
77 |
| - let _pageCount = $state(0); |
78 |
| - let _columns = $state(getColumns<TProject>(untrack(() => _parameters.mode))); |
79 |
| - let _data = $state([] as TProject[]); |
80 |
| - let _loading = $state(false); |
81 |
| - let _meta = $state({} as FetchClientResponse<unknown>['meta']); |
82 |
| - |
83 |
| - const [columnVisibility, setColumnVisibility] = createPersistedTableState('project-column-visibility', <VisibilityState>{}); |
84 |
| - const [pagination, setPagination] = createTableState<PaginationState>({ |
85 |
| - pageIndex: 0, |
86 |
| - pageSize: untrack(() => _parameters.limit) ?? DEFAULT_LIMIT |
87 |
| - }); |
88 |
| - const [sorting, setSorting] = createTableState<ColumnSort[]>([ |
| 66 | + return getSharedTableOptions<TProject>( |
89 | 67 | {
|
90 |
| - desc: true, |
91 |
| - id: 'name' |
92 |
| - } |
93 |
| - ]); |
94 |
| - const [rowSelection, setRowSelection] = createTableState<RowSelectionState>({}); |
95 |
| - const onPaginationChange = (updaterOrValue: Updater<PaginationState>) => { |
96 |
| - if (_loading) { |
97 |
| - return; |
98 |
| - } |
99 |
| - |
100 |
| - _loading = true; |
101 |
| - setPagination(updaterOrValue); |
102 |
| - |
103 |
| - const currentPageInfo = pagination(); |
104 |
| - const nextLink = _meta.links?.next?.after as string; |
105 |
| - const previousLink = _meta.links?.previous?.before as string; |
106 |
| - |
107 |
| - _parameters = { |
108 |
| - ..._parameters, |
109 |
| - limit: currentPageInfo.pageSize, |
110 |
| - page: !nextLink && !previousLink && currentPageInfo.pageIndex !== 0 ? currentPageInfo.pageIndex + 1 : undefined |
111 |
| - }; |
112 |
| - }; |
113 |
| - |
114 |
| - const onSortingChange = (updaterOrValue: Updater<ColumnSort[]>) => { |
115 |
| - setSorting(updaterOrValue); |
116 |
| - |
117 |
| - _parameters = { |
118 |
| - ..._parameters, |
119 |
| - page: undefined, |
120 |
| - sort: |
121 |
| - sorting().length > 0 |
122 |
| - ? sorting() |
123 |
| - .map((sort) => `${sort.desc ? '-' : ''}${sort.id}`) |
124 |
| - .join(',') |
125 |
| - : undefined |
126 |
| - }; |
127 |
| - }; |
128 |
| - |
129 |
| - const options = configureOptions({ |
130 |
| - get columns() { |
131 |
| - return _columns; |
132 |
| - }, |
133 |
| - set columns(value) { |
134 |
| - _columns = value; |
135 |
| - }, |
136 |
| - get data() { |
137 |
| - return _data; |
138 |
| - }, |
139 |
| - set data(value) { |
140 |
| - _data = value; |
141 |
| - }, |
142 |
| - enableMultiRowSelection: true, |
143 |
| - enableRowSelection: true, |
144 |
| - enableSortingRemoval: false, |
145 |
| - getCoreRowModel: getCoreRowModel(), |
146 |
| - getRowId: (originalRow) => originalRow.id, |
147 |
| - manualPagination: true, |
148 |
| - manualSorting: true, |
149 |
| - onColumnVisibilityChange: setColumnVisibility, |
150 |
| - onPaginationChange, |
151 |
| - onRowSelectionChange: setRowSelection, |
152 |
| - onSortingChange, |
153 |
| - get pageCount() { |
154 |
| - return _pageCount; |
155 |
| - }, |
156 |
| - state: { |
157 |
| - get columnVisibility() { |
158 |
| - return columnVisibility(); |
| 68 | + columnPersistenceKey: 'project', |
| 69 | + get columns() { |
| 70 | + return getColumns<TProject>(queryParameters.mode); |
159 | 71 | },
|
160 |
| - get pagination() { |
161 |
| - return pagination(); |
| 72 | + paginationStrategy: 'offset', |
| 73 | + get queryParameters() { |
| 74 | + return queryParameters; |
162 | 75 | },
|
163 |
| - get rowSelection() { |
164 |
| - return rowSelection(); |
165 |
| - }, |
166 |
| - get sorting() { |
167 |
| - return sorting(); |
| 76 | + get queryResponse() { |
| 77 | + return queryResponse.data; |
168 | 78 | }
|
169 |
| - } |
170 |
| - }); |
171 |
| - |
172 |
| - return { |
173 |
| - get data() { |
174 |
| - return _data; |
175 |
| - }, |
176 |
| - set data(value) { |
177 |
| - _data = value; |
178 | 79 | },
|
179 |
| - get loading() { |
180 |
| - return _loading; |
181 |
| - }, |
182 |
| - get meta() { |
183 |
| - return _meta; |
184 |
| - }, |
185 |
| - set meta(value) { |
186 |
| - _meta = value; |
187 |
| - |
188 |
| - const limit = _parameters.limit ?? DEFAULT_LIMIT; |
189 |
| - const total = (_meta?.total as number) ?? 0; |
190 |
| - _pageCount = Math.ceil(total / limit); |
191 |
| - |
192 |
| - _loading = false; |
193 |
| - }, |
194 |
| - options, |
195 |
| - get pageCount() { |
196 |
| - return _pageCount; |
197 |
| - }, |
198 |
| - get parameters() { |
199 |
| - return _parameters; |
200 |
| - } |
201 |
| - }; |
202 |
| -} |
203 |
| - |
204 |
| -function createPersistedTableState<T>(key: string, initialValue: T): [() => T, (updater: Updater<T>) => void] { |
205 |
| - const persistedValue = new PersistedState<T>(key, initialValue); |
206 |
| - |
207 |
| - return [ |
208 |
| - () => persistedValue.current, |
209 |
| - (updater: Updater<T>) => { |
210 |
| - if (updater instanceof Function) { |
211 |
| - persistedValue.current = updater(persistedValue.current); |
212 |
| - } else { |
213 |
| - persistedValue.current = updater; |
214 |
| - } |
215 |
| - } |
216 |
| - ]; |
217 |
| -} |
218 |
| - |
219 |
| -function createTableState<T>(initialValue: T): [() => T, (updater: Updater<T>) => void] { |
220 |
| - let value = $state(initialValue); |
221 |
| - |
222 |
| - return [ |
223 |
| - () => value, |
224 |
| - (updater: Updater<T>) => { |
225 |
| - if (updater instanceof Function) { |
226 |
| - value = updater(value); |
227 |
| - } else { |
228 |
| - value = updater; |
229 |
| - } |
230 |
| - } |
231 |
| - ]; |
| 80 | + configureOptions |
| 81 | + ); |
232 | 82 | }
|
0 commit comments