Skip to content

Instantly share code, notes, and snippets.

@danphilibin
Last active January 20, 2023 18:56
Show Gist options
  • Save danphilibin/466459428d387c485587e7242ad894fa to your computer and use it in GitHub Desktop.
Save danphilibin/466459428d387c485587e7242ad894fa to your computer and use it in GitHub Desktop.
import { T_IO_STATE } from '@interval/sdk/dist/ioSchema'
export default class CursorPagination {
cursors: string[] = []
lastOffset: number = 0
lastQueryTerm: string | undefined
lastSortColumn: string | undefined
lastSortDirection: string | undefined
update(newState: T_IO_STATE<'DISPLAY_TABLE'>) {
let direction = newState.offset >= this.lastOffset ? 'forward' : 'backward'
// interval resets to page 0 when any of these change
if (
newState.queryTerm !== this.lastQueryTerm ||
newState.sortColumn !== this.lastSortColumn ||
newState.sortDirection !== this.lastSortDirection
) {
this.cursors.length = 0
this.lastOffset = 0
direction = 'forward'
}
if (direction === 'backward') {
this.cursors.pop()
this.cursors.pop()
}
this.lastOffset = newState.offset
this.lastQueryTerm = newState.queryTerm
this.lastSortColumn = newState.sortColumn
this.lastSortDirection = newState.sortDirection
}
get lastCursor() {
return this.cursors[this.cursors.length - 1] ?? null
}
add(id?: string | null) {
if (id) {
this.cursors.push(id)
}
}
}
import { io, Layout, Page } from '@interval/sdk'
import prisma from '~/prisma.server'
import CursorPagination from './cursor-pagination'
export default new Page({
name: 'Tags',
handler: async () => {
// 1️⃣ initialize the CursorPagination class
const cursor = new CursorPagination()
return new Layout({
title: 'Tags',
children: [
io.display.table('', {
defaultPageSize: 30,
columns: ['name', 'slug'],
getData: async newState => {
const { sortColumn, sortDirection, pageSize, queryTerm } = newState
// 2️⃣ update with the new state
cursor.update(newState)
const where = queryTerm
? {
name: { contains: queryTerm },
}
: undefined
let orderBy
if (sortColumn && sortDirection) {
orderBy = {
[sortColumn]: sortDirection,
}
}
// 3️⃣ use the previous cursor in your query
const lastResultId = cursor.lastCursor
const data = await prisma.tag.findMany({
where,
cursor: lastResultId ? { id: lastResultId } : undefined,
skip: lastResultId ? 1 : 0, // skip the cursor
take: pageSize,
orderBy,
})
const totalRecords = await prisma.tag.count({
where,
})
// 4️⃣ store the cursor for the data you're returning
cursor.add(data[data.length - 1]?.id)
return {
data,
totalRecords,
}
},
}),
],
})
},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment