fix space favorites view

This commit is contained in:
Philipinho
2026-04-14 02:39:22 +01:00
parent 66c70c0e76
commit 0b32511dff
11 changed files with 103 additions and 39 deletions
@@ -1,8 +1,12 @@
import { IsIn, IsNotEmpty, IsString } from 'class-validator';
import { IsIn, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator';
export class FavoriteIdsDto {
@IsString()
@IsNotEmpty()
@IsIn(['page', 'space', 'template'])
type: 'page' | 'space' | 'template';
@IsOptional()
@IsUUID()
spaceId?: string;
}
@@ -1,8 +1,12 @@
import { IsIn, IsOptional, IsString } from 'class-validator';
import { IsIn, IsOptional, IsString, IsUUID } from 'class-validator';
export class ListFavoritesDto {
@IsOptional()
@IsString()
@IsIn(['page', 'space', 'template'])
type?: 'page' | 'space' | 'template';
@IsOptional()
@IsUUID()
spaceId?: string;
}
@@ -82,6 +82,7 @@ export class FavoriteController {
user.id,
workspace.id,
dto.type as FavoriteType,
dto.spaceId,
);
}
@@ -98,6 +99,7 @@ export class FavoriteController {
workspace.id,
pagination,
dto.type as FavoriteType | undefined,
dto.spaceId,
);
}
@@ -20,11 +20,13 @@ export class FavoriteService {
userId: string,
workspaceId: string,
type: FavoriteType,
spaceId?: string,
) {
const result = await this.favoriteRepo.getFavoriteIds(
userId,
workspaceId,
type,
spaceId,
);
if (result.items.length === 0) {
@@ -95,12 +97,14 @@ export class FavoriteService {
workspaceId: string,
pagination: PaginationOptions,
type?: FavoriteType,
spaceId?: string,
) {
const result = await this.favoriteRepo.findUserFavorites(
userId,
workspaceId,
pagination,
type,
spaceId,
);
if (result.items.length === 0) {
@@ -5,7 +5,7 @@ import { InsertableFavorite, Favorite } from '@docmost/db/types/entity.types';
import { PaginationOptions } from '@docmost/db/pagination/pagination-options';
import { executeWithCursorPagination } from '@docmost/db/pagination/cursor-pagination';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { ExpressionBuilder, sql } from 'kysely';
import { ExpressionBuilder, SelectQueryBuilder, sql } from 'kysely';
import { DB } from '@docmost/db/types/db';
import { dbOrTx } from '@docmost/db/utils';
@@ -66,6 +66,7 @@ export class FavoriteRepo {
userId: string,
workspaceId: string,
type: FavoriteType,
spaceId?: string,
): Promise<{ items: string[]; meta: any }> {
const idColumn =
type === FavoriteType.PAGE
@@ -74,12 +75,16 @@ export class FavoriteRepo {
? 'spaceId'
: 'templateId';
const query = this.db
let query = this.db
.selectFrom('favorites')
.select(['favorites.id', `favorites.${idColumn} as entityId`])
.where('userId', '=', userId)
.where('workspaceId', '=', workspaceId)
.where('type', '=', type);
.where('favorites.userId', '=', userId)
.where('favorites.workspaceId', '=', workspaceId)
.where('favorites.type', '=', type);
if (spaceId) {
query = this.applySpaceFilter(query, type, spaceId);
}
const result = await executeWithCursorPagination(query, {
perPage: 250,
@@ -100,6 +105,7 @@ export class FavoriteRepo {
workspaceId: string,
pagination: PaginationOptions,
type?: FavoriteType,
spaceId?: string,
) {
let query = this.db
.selectFrom('favorites')
@@ -111,6 +117,10 @@ export class FavoriteRepo {
query = query.where('favorites.type', '=', type);
}
if (spaceId) {
query = this.applySpaceFilter(query, type, spaceId);
}
if (type === FavoriteType.PAGE || !type) {
query = query.select((eb) => this.withPage(eb));
}
@@ -184,6 +194,39 @@ export class FavoriteRepo {
.execute();
}
private applySpaceFilter<Q extends SelectQueryBuilder<any, any, any>>(
query: Q,
type: FavoriteType | undefined,
spaceId: string,
): Q {
if (type === FavoriteType.PAGE) {
return query.where((eb: any) =>
eb.exists(
eb
.selectFrom('pages')
.select(sql`1`.as('one'))
.whereRef('pages.id', '=', 'favorites.pageId')
.where('pages.spaceId', '=', spaceId),
),
) as Q;
}
if (type === FavoriteType.SPACE) {
return query.where('favorites.spaceId' as any, '=', spaceId) as Q;
}
if (type === FavoriteType.TEMPLATE) {
return query.where((eb: any) =>
eb.exists(
eb
.selectFrom('templates')
.select(sql`1`.as('one'))
.whereRef('templates.id', '=', 'favorites.templateId')
.where('templates.spaceId', '=', spaceId),
),
) as Q;
}
return query;
}
private withPage(eb: ExpressionBuilder<DB, 'favorites'>) {
return jsonObjectFrom(
eb