@@ -8,9 +8,10 @@ import {
8
8
onMount ,
9
9
} from "solid-js" ;
10
10
import { useSearchParams } from "@solidjs/router" ;
11
+ import { createWritableMemo } from "@solid-primitives/memo" ;
11
12
import { createColumnHelper } from "@tanstack/solid-table" ;
12
13
import type { ColumnDef , PaginationState } from "@tanstack/solid-table" ;
13
- import { useInfiniteQuery , useQueryClient } from "@tanstack/solid-query" ;
14
+ import { useQuery , useQueryClient } from "@tanstack/solid-query" ;
14
15
import { Chart } from "chart.js/auto" ;
15
16
import type {
16
17
ChartData ,
@@ -41,7 +42,6 @@ import { DataTable, safeParseInt } from "@/components/Table";
41
42
import { FilterBar } from "@/components/FilterBar" ;
42
43
43
44
import { getLogs } from "@/lib/logs" ;
44
- import type { ListLogsResponse } from "@bindings/ListLogsResponse" ;
45
45
46
46
import countriesGeoJSON from "@/assets/countries-110m.json" ;
47
47
@@ -119,13 +119,22 @@ const columns: ColumnDef<LogJson>[] = [
119
119
120
120
// Value is the previous value in case this isn't the first fetch.
121
121
export function LogsPage ( ) {
122
- // NOTE: pageIndex is not controlled via the search params since we cannot
123
- // just jump to page N, we need to cursor from the beginning.
124
- const [ pageIndex , setPageIndex ] = createSignal ( 0 ) ;
125
122
const [ searchParams , setSearchParams ] = useSearchParams < {
126
123
filter ?: string ;
127
124
pageSize ?: string ;
128
125
} > ( ) ;
126
+ // Reset when search params change
127
+ const reset = ( ) => {
128
+ return [ searchParams . pageSize , searchParams . filter ] ;
129
+ } ;
130
+ const [ pageIndex , setPageIndex ] = createWritableMemo < number > ( ( ) => {
131
+ reset ( ) ;
132
+ return 0 ;
133
+ } ) ;
134
+ const [ cursors , setCursors ] = createWritableMemo < string [ ] > ( ( ) => {
135
+ reset ( ) ;
136
+ return [ ] ;
137
+ } ) ;
129
138
130
139
const pagination = ( ) : PaginationState => {
131
140
return {
@@ -134,24 +143,39 @@ export function LogsPage() {
134
143
} ;
135
144
} ;
136
145
137
- const setFilter = ( filter : string | undefined ) =>
146
+ const setFilter = ( filter : string | undefined ) => {
147
+ setPageIndex ( 0 ) ;
138
148
setSearchParams ( {
139
149
...searchParams ,
140
150
filter,
141
151
} ) ;
152
+ } ;
142
153
143
154
// NOTE: admin user endpoint doesn't support offset, we have to cursor through
144
155
// and cannot just jump to page N.
145
- const logsFetch = useInfiniteQuery ( ( ) => ( {
146
- queryKey : [ "logs" , searchParams ] ,
147
- initialPageParam : null ,
148
- getNextPageParam : ( lastPage : ListLogsResponse , _pages ) : string | null => {
149
- return lastPage . cursor ;
150
- } ,
151
- queryFn : async ( { pageParam } : { pageParam : string | null } ) => {
152
- const cursor : string | null = pageParam ;
153
- console . debug ( "logs cursor" , cursor ) ;
154
- return await getLogs ( pagination ( ) . pageSize , searchParams . filter , cursor ) ;
156
+ const logsFetch = useQuery ( ( ) => ( {
157
+ queryKey : [
158
+ "logs" ,
159
+ searchParams . filter ,
160
+ pagination ( ) . pageSize ,
161
+ pagination ( ) . pageIndex ,
162
+ ] ,
163
+ queryFn : async ( ) => {
164
+ const p = pagination ( ) ;
165
+ const c = cursors ( ) ;
166
+
167
+ const response = await getLogs (
168
+ p . pageSize ,
169
+ searchParams . filter ,
170
+ c [ p . pageIndex - 1 ] ,
171
+ ) ;
172
+
173
+ const cursor = response . cursor ;
174
+ if ( cursor && p . pageIndex >= c . length ) {
175
+ setCursors ( [ ...c , cursor ] ) ;
176
+ }
177
+
178
+ return response ;
155
179
} ,
156
180
} ) ) ;
157
181
const client = useQueryClient ( ) ;
@@ -161,9 +185,6 @@ export function LogsPage() {
161
185
} ) ;
162
186
} ;
163
187
164
- const currentPage = ( ) : ListLogsResponse | undefined =>
165
- ( logsFetch . data ?. pages ?? [ ] ) [ pagination ( ) . pageIndex ] ;
166
-
167
188
const [ showMap , setShowMap ] = createSignal ( true ) ;
168
189
const [ showGeoipDialog , setShowGeoipDialog ] = createSignal ( false ) ;
169
190
@@ -200,9 +221,9 @@ export function LogsPage() {
200
221
</ DialogContent >
201
222
202
223
< IconButton
203
- disabled = { logsFetch . isSuccess }
224
+ disabled = { ! logsFetch . isSuccess }
204
225
onClick = { ( ) => {
205
- if ( logsFetch . data ?. pages [ 0 ] ?. stats ?. country_codes ) {
226
+ if ( logsFetch . data ?. stats ?. country_codes ) {
206
227
setShowMap ( ( v ) => ! v ) ;
207
228
} else {
208
229
setShowGeoipDialog ( ( v ) => ! v ) ;
@@ -225,26 +246,22 @@ export function LogsPage() {
225
246
< span > Loading</ span >
226
247
</ Match >
227
248
228
- < Match when = { logsFetch . isSuccess } >
229
- { pagination ( ) . pageIndex === 0 &&
230
- logsFetch . data ?. pages [ 0 ] ?. stats && (
231
- < div class = "mb-4 flex h-[300px] w-full gap-4" >
232
- < div class = { showMap ( ) ? "w-1/2 grow" : "w-full" } >
233
- < LogsChart stats = { logsFetch . data ! . pages [ 0 ] ! . stats ! } />
234
- </ div >
235
-
236
- { showMap ( ) &&
237
- logsFetch . data ! . pages [ 0 ] . stats ! . country_codes && (
238
- < div class = "flex w-1/2 max-w-[500px] items-center" >
239
- < WorldMap
240
- country_codes = {
241
- logsFetch . data ! . pages [ 0 ] . stats ! . country_codes !
242
- }
243
- />
244
- </ div >
245
- ) }
249
+ < Match when = { logsFetch . data } >
250
+ { pagination ( ) . pageIndex === 0 && logsFetch . data ! . stats && (
251
+ < div class = "mb-4 flex h-[300px] w-full gap-4" >
252
+ < div class = { showMap ( ) ? "w-1/2 grow" : "w-full" } >
253
+ < LogsChart stats = { logsFetch . data ! . stats ! } />
246
254
</ div >
247
- ) }
255
+
256
+ { showMap ( ) && logsFetch . data ! . stats ! . country_codes && (
257
+ < div class = "flex w-1/2 max-w-[500px] items-center" >
258
+ < WorldMap
259
+ country_codes = { logsFetch . data ! . stats ! . country_codes ! }
260
+ />
261
+ </ div >
262
+ ) }
263
+ </ div >
264
+ ) }
248
265
249
266
< FilterBar
250
267
initial = { searchParams . filter }
@@ -267,8 +284,8 @@ export function LogsPage() {
267
284
268
285
< DataTable
269
286
columns = { ( ) => columns }
270
- data = { ( ) => currentPage ( ) ? .entries }
271
- rowCount = { Number ( logsFetch . data ?. pages [ 0 ] ? .total_row_count ?? - 1 ) }
287
+ data = { ( ) => logsFetch . data ! . entries }
288
+ rowCount = { Number ( logsFetch . data ! . total_row_count ?? - 1 ) }
272
289
pagination = { pagination ( ) }
273
290
onPaginationChange = { (
274
291
p :
@@ -279,13 +296,18 @@ export function LogsPage() {
279
296
pageSize,
280
297
pageIndex,
281
298
} : PaginationState ) {
282
- setPageIndex ( pageIndex ) ;
283
- logsFetch . fetchNextPage ( ) ;
299
+ const current = pagination ( ) ;
300
+ if ( current . pageSize !== pageSize ) {
301
+ setSearchParams ( {
302
+ ...searchParams ,
303
+ pageSize,
304
+ } ) ;
305
+ return ;
306
+ }
284
307
285
- setSearchParams ( {
286
- ...searchParams ,
287
- pageSize,
288
- } ) ;
308
+ if ( current . pageIndex != pageIndex ) {
309
+ setPageIndex ( pageIndex ) ;
310
+ }
289
311
}
290
312
291
313
if ( typeof p === "function" ) {
0 commit comments