mirror of
https://github.com/docmost/docmost.git
synced 2025-11-23 03:01:11 +10:00
Rework sidebar pages
* Move sidebar pages from workspace to space level * Replace array sorting with lexicographical fractional indexing * Fixes and updates
This commit is contained in:
@ -12,7 +12,6 @@ import { SpaceMemberRepo } from '@docmost/db/repos/space/space-member.repo';
|
||||
import { PageRepo } from './repos/page/page.repo';
|
||||
import { CommentRepo } from './repos/comment/comment.repo';
|
||||
import { PageHistoryRepo } from './repos/page/page-history.repo';
|
||||
import { PageOrderingRepo } from './repos/page/page-ordering.repo';
|
||||
import { AttachmentRepo } from './repos/attachment/attachment.repo';
|
||||
|
||||
// https://github.com/brianc/node-postgres/issues/811
|
||||
@ -35,9 +34,9 @@ types.setTypeParser(types.builtins.INT8, (val) => Number(val));
|
||||
if (environmentService.getEnv() !== 'development') return;
|
||||
if (event.level === 'query') {
|
||||
console.log(event.query.sql);
|
||||
if (event.query.parameters.length > 0) {
|
||||
console.log('parameters: ' + event.query.parameters);
|
||||
}
|
||||
//if (event.query.parameters.length > 0) {
|
||||
//console.log('parameters: ' + event.query.parameters);
|
||||
//}
|
||||
console.log('time: ' + event.queryDurationMillis);
|
||||
}
|
||||
},
|
||||
@ -53,7 +52,6 @@ types.setTypeParser(types.builtins.INT8, (val) => Number(val));
|
||||
SpaceMemberRepo,
|
||||
PageRepo,
|
||||
PageHistoryRepo,
|
||||
PageOrderingRepo,
|
||||
CommentRepo,
|
||||
AttachmentRepo,
|
||||
],
|
||||
@ -66,7 +64,6 @@ types.setTypeParser(types.builtins.INT8, (val) => Number(val));
|
||||
SpaceMemberRepo,
|
||||
PageRepo,
|
||||
PageHistoryRepo,
|
||||
PageOrderingRepo,
|
||||
CommentRepo,
|
||||
AttachmentRepo,
|
||||
],
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
import { type Kysely } from 'kysely';
|
||||
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await db.schema
|
||||
.alterTable('pages')
|
||||
.addColumn('position', 'varchar', (col) => col)
|
||||
.execute();
|
||||
}
|
||||
|
||||
export async function down(db: Kysely<any>): Promise<void> {
|
||||
await db.schema.alterTable('pages').dropColumn('position').execute();
|
||||
}
|
||||
@ -23,13 +23,4 @@ export class PaginationOptions {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
query: string;
|
||||
|
||||
get offset(): number {
|
||||
return (this.page - 1) * this.limit;
|
||||
}
|
||||
}
|
||||
|
||||
export enum PaginationSort {
|
||||
ASC = 'asc',
|
||||
DESC = 'desc',
|
||||
}
|
||||
|
||||
@ -20,6 +20,10 @@ export async function executeWithPagination<O, DB, TB extends keyof DB>(
|
||||
experimental_deferredJoinPrimaryKey?: StringReference<DB, TB>;
|
||||
},
|
||||
): Promise<PaginationResult<O>> {
|
||||
if (opts.page < 1) {
|
||||
opts.page = 1;
|
||||
}
|
||||
console.log('perpage', opts.perPage);
|
||||
qb = qb.limit(opts.perPage + 1).offset((opts.page - 1) * opts.perPage);
|
||||
|
||||
const deferredJoinPrimaryKey = opts.experimental_deferredJoinPrimaryKey;
|
||||
|
||||
@ -72,7 +72,7 @@ export class PageHistoryRepo {
|
||||
.orderBy('createdAt', 'desc');
|
||||
|
||||
const result = executeWithPagination(query, {
|
||||
page: pagination.offset,
|
||||
page: pagination.page,
|
||||
perPage: pagination.limit,
|
||||
});
|
||||
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectKysely } from 'nestjs-kysely';
|
||||
import { KyselyDB } from '../../types/kysely.types';
|
||||
|
||||
@Injectable()
|
||||
export class PageOrderingRepo {
|
||||
constructor(@InjectKysely() private readonly db: KyselyDB) {}
|
||||
}
|
||||
@ -23,6 +23,7 @@ export class PageRepo {
|
||||
'icon',
|
||||
'coverPhoto',
|
||||
'key',
|
||||
'position',
|
||||
'parentPageId',
|
||||
'creatorId',
|
||||
'lastUpdatedById',
|
||||
@ -38,15 +39,17 @@ export class PageRepo {
|
||||
|
||||
async findById(
|
||||
pageId: string,
|
||||
withJsonContent?: boolean,
|
||||
withYdoc?: boolean,
|
||||
opts?: {
|
||||
includeContent?: boolean;
|
||||
includeYdoc?: boolean;
|
||||
},
|
||||
): Promise<Page> {
|
||||
return await this.db
|
||||
.selectFrom('pages')
|
||||
.select(this.baseFields)
|
||||
.where('id', '=', pageId)
|
||||
.$if(withJsonContent, (qb) => qb.select('content'))
|
||||
.$if(withYdoc, (qb) => qb.select('ydoc'))
|
||||
.$if(opts?.includeContent, (qb) => qb.select('content'))
|
||||
.$if(opts?.includeYdoc, (qb) => qb.select('ydoc'))
|
||||
.executeTakeFirst();
|
||||
}
|
||||
|
||||
@ -79,7 +82,7 @@ export class PageRepo {
|
||||
return db
|
||||
.insertInto('pages')
|
||||
.values(insertablePage)
|
||||
.returningAll()
|
||||
.returning(this.baseFields)
|
||||
.executeTakeFirst();
|
||||
}
|
||||
|
||||
@ -101,26 +104,4 @@ export class PageRepo {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async getSpaceSidebarPages(spaceId: string, limit: number) {
|
||||
const pages = await this.db
|
||||
.selectFrom('pages as page')
|
||||
.leftJoin('pageOrdering as ordering', 'ordering.entityId', 'page.id')
|
||||
.where('page.spaceId', '=', spaceId)
|
||||
.select([
|
||||
'page.id',
|
||||
'page.title',
|
||||
'page.icon',
|
||||
'page.parentPageId',
|
||||
'page.spaceId',
|
||||
'ordering.childrenIds',
|
||||
'page.creatorId',
|
||||
'page.createdAt',
|
||||
])
|
||||
.orderBy('page.updatedAt', 'desc')
|
||||
.limit(limit)
|
||||
.execute();
|
||||
|
||||
return pages;
|
||||
}
|
||||
}
|
||||
|
||||
14
apps/server/src/kysely/types/db.d.ts
vendored
14
apps/server/src/kysely/types/db.d.ts
vendored
@ -91,18 +91,6 @@ export interface PageHistory {
|
||||
workspaceId: string;
|
||||
}
|
||||
|
||||
export interface PageOrdering {
|
||||
childrenIds: string[];
|
||||
createdAt: Generated<Timestamp>;
|
||||
deletedAt: Timestamp | null;
|
||||
entityId: string;
|
||||
entityType: string;
|
||||
id: Generated<string>;
|
||||
spaceId: string;
|
||||
updatedAt: Generated<Timestamp>;
|
||||
workspaceId: string;
|
||||
}
|
||||
|
||||
export interface Pages {
|
||||
content: Json | null;
|
||||
coverPhoto: string | null;
|
||||
@ -118,6 +106,7 @@ export interface Pages {
|
||||
key: string | null;
|
||||
lastUpdatedById: string | null;
|
||||
parentPageId: string | null;
|
||||
position: string | null;
|
||||
publishedAt: Timestamp | null;
|
||||
slug: string | null;
|
||||
spaceId: string;
|
||||
@ -209,7 +198,6 @@ export interface DB {
|
||||
groups: Groups;
|
||||
groupUsers: GroupUsers;
|
||||
pageHistory: PageHistory;
|
||||
pageOrdering: PageOrdering;
|
||||
pages: Pages;
|
||||
spaceMembers: SpaceMembers;
|
||||
spaces: Spaces;
|
||||
|
||||
@ -8,7 +8,6 @@ import {
|
||||
Users,
|
||||
Workspaces,
|
||||
PageHistory as History,
|
||||
PageOrdering as Ordering,
|
||||
GroupUsers,
|
||||
SpaceMembers,
|
||||
WorkspaceInvitations,
|
||||
@ -63,11 +62,6 @@ export type PageHistory = Selectable<History>;
|
||||
export type InsertablePageHistory = Insertable<History>;
|
||||
export type UpdatablePageHistory = Updateable<Omit<History, 'id'>>;
|
||||
|
||||
// PageOrdering
|
||||
export type PageOrdering = Selectable<Ordering>;
|
||||
export type InsertablePageOrdering = Insertable<Ordering>;
|
||||
export type UpdatablePageOrdering = Updateable<Omit<Ordering, 'id'>>;
|
||||
|
||||
// Comment
|
||||
export type Comment = Selectable<Comments>;
|
||||
export type InsertableComment = Insertable<Comments>;
|
||||
|
||||
Reference in New Issue
Block a user