refactor layout

* ui polishing
* frontend and backend fixes
This commit is contained in:
Philipinho
2024-05-31 21:51:44 +01:00
parent 046dd6d150
commit 06d854a7d2
95 changed files with 1548 additions and 821 deletions

View File

@ -9,7 +9,7 @@ export async function up(db: Kysely<any>): Promise<void> {
)
.addColumn('name', 'varchar', (col) => col)
.addColumn('description', 'text', (col) => col)
.addColumn('slug', 'varchar', (col) => col)
.addColumn('slug', 'varchar', (col) => col.notNull())
.addColumn('logo', 'varchar', (col) => col)
.addColumn('visibility', 'varchar', (col) =>
col.defaultTo(SpaceVisibility.OPEN).notNull(),

View File

@ -10,10 +10,17 @@ import {
import { PaginationOptions } from '@docmost/db/pagination/pagination-options';
import { executeWithPagination } from '@docmost/db/pagination/pagination';
import { validate as isValidUUID } from 'uuid';
import { ExpressionBuilder } from 'kysely';
import { DB } from '@docmost/db/types/db';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { SpaceMemberRepo } from '@docmost/db/repos/space/space-member.repo';
@Injectable()
export class PageRepo {
constructor(@InjectKysely() private readonly db: KyselyDB) {}
constructor(
@InjectKysely() private readonly db: KyselyDB,
private spaceMemberRepo: SpaceMemberRepo,
) {}
private baseFields: Array<keyof Page> = [
'id',
@ -38,6 +45,7 @@ export class PageRepo {
opts?: {
includeContent?: boolean;
includeYdoc?: boolean;
includeSpace?: boolean;
},
): Promise<Page> {
let query = this.db
@ -46,6 +54,10 @@ export class PageRepo {
.$if(opts?.includeContent, (qb) => qb.select('content'))
.$if(opts?.includeYdoc, (qb) => qb.select('ydoc'));
if (opts?.includeSpace) {
query = query.select((eb) => this.withSpace(eb));
}
if (isValidUUID(pageId)) {
query = query.where('id', '=', pageId);
} else {
@ -96,12 +108,11 @@ export class PageRepo {
await query.execute();
}
async getRecentPageUpdates(spaceId: string, pagination: PaginationOptions) {
//TODO: should fetch pages from all spaces the user is member of
// for now, fetch from default space
async getRecentPagesInSpace(spaceId: string, pagination: PaginationOptions) {
const query = this.db
.selectFrom('pages')
.select(this.baseFields)
.select((eb) => this.withSpace(eb))
.where('spaceId', '=', spaceId)
.orderBy('updatedAt', 'desc');
@ -112,4 +123,31 @@ export class PageRepo {
return result;
}
async getRecentPages(userId: string, pagination: PaginationOptions) {
const userSpaceIds = await this.spaceMemberRepo.getUserSpaceIds(userId);
const query = this.db
.selectFrom('pages')
.select(this.baseFields)
.select((eb) => this.withSpace(eb))
.where('spaceId', 'in', userSpaceIds)
.orderBy('updatedAt', 'desc');
const result = executeWithPagination(query, {
page: pagination.page,
perPage: pagination.limit,
});
return result;
}
withSpace(eb: ExpressionBuilder<DB, 'pages'>) {
return jsonObjectFrom(
eb
.selectFrom('spaces')
.select(['spaces.id', 'spaces.name', 'spaces.slug'])
.whereRef('spaces.id', '=', 'pages.spaceId'),
).as('space');
}
}

View File

@ -11,12 +11,14 @@ import { PaginationOptions } from '../../pagination/pagination-options';
import { MemberInfo, UserSpaceRole } from './types';
import { executeWithPagination } from '@docmost/db/pagination/pagination';
import { GroupRepo } from '@docmost/db/repos/group/group.repo';
import { SpaceRepo } from '@docmost/db/repos/space/space.repo';
@Injectable()
export class SpaceMemberRepo {
constructor(
@InjectKysely() private readonly db: KyselyDB,
private readonly groupRepo: GroupRepo,
private readonly spaceRepo: SpaceRepo,
) {}
async insertSpaceMember(
@ -184,4 +186,52 @@ export class SpaceMemberRepo {
}
return roles;
}
async getUserSpaceIds(userId: string): Promise<string[]> {
const membership = await this.db
.selectFrom('spaceMembers')
.innerJoin('spaces', 'spaces.id', 'spaceMembers.spaceId')
.select(['spaces.id'])
.where('userId', '=', userId)
.union(
this.db
.selectFrom('spaceMembers')
.innerJoin('groupUsers', 'groupUsers.groupId', 'spaceMembers.groupId')
.innerJoin('spaces', 'spaces.id', 'spaceMembers.spaceId')
.select(['spaces.id'])
.where('groupUsers.userId', '=', userId),
)
.execute();
return membership.map((space) => space.id);
}
async getUserSpaces(userId: string, pagination: PaginationOptions) {
const userSpaceIds = await this.getUserSpaceIds(userId);
let query = this.db
.selectFrom('spaces')
.selectAll('spaces')
.select((eb) => [this.spaceRepo.withMemberCount(eb)])
//.where('workspaceId', '=', workspaceId)
.where('id', 'in', userSpaceIds)
.orderBy('createdAt', 'asc');
if (pagination.query) {
query = query.where((eb) =>
eb('name', 'ilike', `%${pagination.query}%`).or(
'description',
'ilike',
`%${pagination.query}%`,
),
);
}
const result = executeWithPagination(query, {
page: pagination.page,
perPage: pagination.limit,
});
return result;
}
}

View File

@ -11,6 +11,7 @@ import { ExpressionBuilder, sql } from 'kysely';
import { PaginationOptions } from '../../pagination/pagination-options';
import { executeWithPagination } from '@docmost/db/pagination/pagination';
import { DB } from '@docmost/db/types/db';
import { validate as isValidUUID } from 'uuid';
@Injectable()
export class SpaceRepo {
@ -22,13 +23,19 @@ export class SpaceRepo {
opts?: { includeMemberCount?: boolean; trx?: KyselyTransaction },
): Promise<Space> {
const db = dbOrTx(this.db, opts?.trx);
return db
let query = db
.selectFrom('spaces')
.selectAll('spaces')
.$if(opts?.includeMemberCount, (qb) => qb.select(this.withMemberCount))
.where('id', '=', spaceId)
.where('workspaceId', '=', workspaceId)
.executeTakeFirst();
.where('workspaceId', '=', workspaceId);
if (isValidUUID(spaceId)) {
query = query.where('id', '=', spaceId);
} else {
query = query.where('slug', '=', spaceId);
}
return query.executeTakeFirst();
}
async findBySlug(

View File

@ -6,11 +6,15 @@ import { hashPassword } from '../../../helpers';
import { dbOrTx } from '@docmost/db/utils';
import {
InsertableUser,
Space,
UpdatableUser,
User,
} from '@docmost/db/types/entity.types';
import { PaginationOptions } from '../../pagination/pagination-options';
import { executeWithPagination } from '@docmost/db/pagination/pagination';
import {
executeWithPagination,
PaginationResult,
} from '@docmost/db/pagination/pagination';
@Injectable()
export class UserRepo {
@ -152,4 +156,31 @@ export class UserRepo {
return result;
}
/*
async getSpaceIds(
workspaceId: string,
pagination: PaginationOptions,
): Promise<PaginationResult<Space>> {
const spaces = await this.spaceRepo.getSpacesInWorkspace(
workspaceId,
pagination,
);
return spaces;
}
async getUserSpaces(
workspaceId: string,
pagination: PaginationOptions,
): Promise<PaginationResult<Space>> {
const spaces = await this.spaceRepo.getSpacesInWorkspace(
workspaceId,
pagination,
);
return spaces;
}
*/
}