mirror of
https://github.com/docmost/docmost.git
synced 2026-05-15 05:04:06 +08:00
support beforeCursor/prevCursor
This commit is contained in:
@@ -206,7 +206,8 @@ export class PageService {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: 250,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [
|
||||
{ expression: 'position', direction: 'asc', orderModifier: (ob) => ob.collate('C').asc() },
|
||||
{ expression: 'id', direction: 'asc' },
|
||||
|
||||
@@ -66,7 +66,8 @@ export class WorkspaceInvitationService {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [{ expression: 'id', direction: 'asc' }],
|
||||
parseCursor: (cursor) => ({ id: cursor.id }),
|
||||
});
|
||||
|
||||
@@ -110,9 +110,10 @@ type CursorPaginationResultRow<
|
||||
|
||||
type CursorPaginationMeta = {
|
||||
limit: number;
|
||||
hasNextPage?: boolean;
|
||||
hasPrevPage?: boolean;
|
||||
hasNextPage: boolean;
|
||||
hasPrevPage: boolean;
|
||||
nextCursor: string | null;
|
||||
prevCursor: string | null;
|
||||
};
|
||||
|
||||
export type CursorPaginationResult<
|
||||
@@ -133,8 +134,8 @@ export async function executeWithCursorPagination<
|
||||
qb: SelectQueryBuilder<DB, TB, O>,
|
||||
opts: {
|
||||
perPage: number;
|
||||
after?: string;
|
||||
before?: string;
|
||||
cursor?: string;
|
||||
beforeCursor?: string;
|
||||
cursorPerRow?: TCursorKey;
|
||||
fields: TFields;
|
||||
encodeCursor?: CursorEncoder<DB, TB, O, TFields>;
|
||||
@@ -219,10 +220,10 @@ export async function executeWithCursorPagination<
|
||||
});
|
||||
}
|
||||
|
||||
if (opts.after) qb = applyCursor(qb, opts.after, 'asc');
|
||||
if (opts.before) qb = applyCursor(qb, opts.before, 'desc');
|
||||
if (opts.cursor) qb = applyCursor(qb, opts.cursor, 'asc');
|
||||
if (opts.beforeCursor) qb = applyCursor(qb, opts.beforeCursor, 'desc');
|
||||
|
||||
const reversed = !!opts.before && !opts.after;
|
||||
const reversed = !!opts.beforeCursor && !opts.cursor;
|
||||
|
||||
for (const { expression, direction, orderModifier } of fields) {
|
||||
qb = qb.orderBy(
|
||||
@@ -234,8 +235,7 @@ export async function executeWithCursorPagination<
|
||||
|
||||
const rows = await qb.limit(opts.perPage + 1).execute();
|
||||
|
||||
const hasNextPage = reversed ? true : rows.length > opts.perPage;
|
||||
const hasPrevPage = !reversed ? undefined : rows.length > opts.perPage;
|
||||
const hasNextPage = rows.length > opts.perPage;
|
||||
|
||||
// If we fetched an extra row to determine if we have a next page, that
|
||||
// shouldn't be in the returned results
|
||||
@@ -243,10 +243,11 @@ export async function executeWithCursorPagination<
|
||||
|
||||
if (reversed) rows.reverse();
|
||||
|
||||
//const startRow = rows[0];
|
||||
const startRow = rows[0];
|
||||
const endRow = rows[rows.length - 1];
|
||||
|
||||
//const startCursor = startRow ? generateCursor(startRow) : null;
|
||||
const hasPrevPage = !!opts.cursor;
|
||||
const prevCursor = hasPrevPage && startRow ? generateCursor(startRow) : null;
|
||||
const nextCursor = hasNextPage && endRow ? generateCursor(endRow) : null;
|
||||
|
||||
return {
|
||||
@@ -263,8 +264,9 @@ export async function executeWithCursorPagination<
|
||||
meta: {
|
||||
limit: opts.perPage,
|
||||
hasNextPage,
|
||||
hasPrevPage: hasPrevPage ?? !!opts.after,
|
||||
hasPrevPage,
|
||||
nextCursor,
|
||||
prevCursor,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,11 +9,6 @@ import {
|
||||
} from 'class-validator';
|
||||
|
||||
export class PaginationOptions {
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
page = 1;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@IsPositive()
|
||||
@@ -25,6 +20,10 @@ export class PaginationOptions {
|
||||
@IsString()
|
||||
cursor?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
beforeCursor?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
query: string;
|
||||
|
||||
@@ -41,7 +41,8 @@ export class CommentRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [{ expression: 'id', direction: 'asc' }],
|
||||
parseCursor: (cursor) => ({ id: cursor.id }),
|
||||
});
|
||||
|
||||
@@ -62,7 +62,8 @@ export class GroupUserRepo {
|
||||
|
||||
const result = await executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [{ expression: 'users.id', direction: 'asc', key: 'id' }],
|
||||
parseCursor: (cursor) => ({ id: cursor.id }),
|
||||
});
|
||||
|
||||
@@ -127,7 +127,8 @@ export class GroupRepo {
|
||||
const query = this.db.selectFrom(baseQuery.as('sub')).selectAll('sub');
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [
|
||||
{
|
||||
expression: 'sub.memberCount',
|
||||
|
||||
@@ -69,7 +69,8 @@ export class PageHistoryRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [{ expression: 'id', direction: 'desc' }],
|
||||
parseCursor: (cursor) => ({ id: cursor.id }),
|
||||
});
|
||||
|
||||
@@ -285,7 +285,8 @@ export class PageRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [
|
||||
{ expression: 'updatedAt', direction: 'desc' },
|
||||
{ expression: 'id', direction: 'desc' },
|
||||
@@ -307,7 +308,8 @@ export class PageRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [
|
||||
{ expression: 'updatedAt', direction: 'desc' },
|
||||
{ expression: 'id', direction: 'desc' },
|
||||
@@ -347,7 +349,8 @@ export class PageRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [
|
||||
{ expression: 'deletedAt', direction: 'desc' },
|
||||
{ expression: 'id', direction: 'desc' },
|
||||
|
||||
@@ -147,7 +147,8 @@ export class ShareRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [
|
||||
{ expression: 'updatedAt', direction: 'desc' },
|
||||
{ expression: 'id', direction: 'desc' },
|
||||
|
||||
@@ -141,7 +141,8 @@ export class SpaceMemberRepo {
|
||||
|
||||
const result = await executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [
|
||||
{ expression: 'sub.isGroup', direction: 'desc', key: 'isGroup' },
|
||||
{ expression: 'sub.createdAt', direction: 'asc', key: 'createdAt' },
|
||||
@@ -262,7 +263,8 @@ export class SpaceMemberRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [{ expression: 'id', direction: 'asc' }],
|
||||
parseCursor: (cursor) => ({ id: cursor.id }),
|
||||
});
|
||||
|
||||
@@ -128,7 +128,8 @@ export class SpaceRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [{ expression: 'id', direction: 'asc' }],
|
||||
parseCursor: (cursor) => ({ id: cursor.id }),
|
||||
});
|
||||
|
||||
@@ -163,7 +163,8 @@ export class UserRepo {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [{ expression: 'id', direction: 'asc' }],
|
||||
parseCursor: (cursor) => ({ id: cursor.id }),
|
||||
});
|
||||
|
||||
+1
-1
Submodule apps/server/src/ee updated: fb7257cb4c...9888832270
@@ -60,7 +60,8 @@ export class FileTaskController {
|
||||
|
||||
return executeWithCursorPagination(query, {
|
||||
perPage: pagination.limit,
|
||||
after: pagination.cursor,
|
||||
cursor: pagination.cursor,
|
||||
beforeCursor: pagination.beforeCursor,
|
||||
fields: [{ expression: 'id', direction: 'desc' }],
|
||||
parseCursor: (cursor) => ({ id: cursor.id }),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user