mirror of
https://github.com/docmost/docmost.git
synced 2025-11-18 16:51:09 +10:00
added recycle bin modal, updated api routes
This commit is contained in:
7
apps/server/src/core/page/dto/deleted-page.dto.ts
Normal file
7
apps/server/src/core/page/dto/deleted-page.dto.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class DeletedPageDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
spaceId: string;
|
||||
}
|
||||
@ -27,6 +27,7 @@ import {
|
||||
import SpaceAbilityFactory from '../casl/abilities/space-ability.factory';
|
||||
import { PageRepo } from '@docmost/db/repos/page/page.repo';
|
||||
import { RecentPageDto } from './dto/recent-page.dto';
|
||||
import { DeletedPageDto } from './dto/deleted-page.dto';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('pages')
|
||||
@ -112,6 +113,23 @@ export class PageController {
|
||||
await this.pageService.forceDelete(pageIdDto.pageId);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('remove')
|
||||
async remove(@Body() pageIdDto: PageIdDto, @AuthUser() user: User) {
|
||||
const page = await this.pageRepo.findById(pageIdDto.pageId);
|
||||
|
||||
if (!page) {
|
||||
throw new NotFoundException('Page not found');
|
||||
}
|
||||
|
||||
const ability = await this.spaceAbility.createForUser(user, page.spaceId);
|
||||
if (ability.cannot(SpaceCaslAction.Manage, SpaceCaslSubject.Page)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
await this.pageService.remove(pageIdDto.pageId);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('restore')
|
||||
async restore(@Body() pageIdDto: PageIdDto) {
|
||||
@ -144,6 +162,30 @@ export class PageController {
|
||||
return this.pageService.getRecentPages(user.id, pagination);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('deleted')
|
||||
async getDeletedPages(
|
||||
@Body() deletedPageDto: DeletedPageDto,
|
||||
@Body() pagination: PaginationOptions,
|
||||
@AuthUser() user: User,
|
||||
) {
|
||||
if (deletedPageDto.spaceId) {
|
||||
const ability = await this.spaceAbility.createForUser(
|
||||
user,
|
||||
deletedPageDto.spaceId,
|
||||
);
|
||||
|
||||
if (ability.cannot(SpaceCaslAction.Read, SpaceCaslSubject.Page)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
return this.pageService.getDeletedSpacePages(
|
||||
deletedPageDto.spaceId,
|
||||
pagination,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: scope to workspaces
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('/history')
|
||||
|
||||
@ -228,6 +228,7 @@ export class PageService {
|
||||
])
|
||||
.select((eb) => this.withHasChildren(eb))
|
||||
.where('id', '=', childPageId)
|
||||
.where('deletedAt', 'is not', null)
|
||||
.unionAll((exp) =>
|
||||
exp
|
||||
.selectFrom('pages as p')
|
||||
@ -281,10 +282,21 @@ export class PageService {
|
||||
return await this.pageRepo.getRecentPages(userId, pagination);
|
||||
}
|
||||
|
||||
async getDeletedSpacePages(
|
||||
spaceId: string,
|
||||
pagination: PaginationOptions,
|
||||
): Promise<PaginationResult<Page>> {
|
||||
return await this.pageRepo.getDeletedPagesInSpace(spaceId, pagination);
|
||||
}
|
||||
|
||||
async forceDelete(pageId: string): Promise<void> {
|
||||
await this.pageRepo.deletePage(pageId);
|
||||
}
|
||||
|
||||
async remove(pageId: string): Promise<void> {
|
||||
await this.pageRepo.removePage(pageId);
|
||||
}
|
||||
|
||||
async restore(pageId: string): Promise<void> {
|
||||
await this.pageRepo.restorePage(pageId);
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ export class PageRepo {
|
||||
.executeTakeFirst();
|
||||
}
|
||||
|
||||
async deletePage(pageId: string): Promise<void> {
|
||||
async removePage(pageId: string): Promise<void> {
|
||||
let query = this.db.updateTable('pages').set({ deletedAt: new Date() });
|
||||
|
||||
if (isValidUUID(pageId)) {
|
||||
@ -118,6 +118,18 @@ export class PageRepo {
|
||||
await query.execute();
|
||||
}
|
||||
|
||||
async deletePage(pageId: string): Promise<void> {
|
||||
let query = this.db.deleteFrom('pages');
|
||||
|
||||
if (isValidUUID(pageId)) {
|
||||
query = query.where('id', '=', pageId);
|
||||
} else {
|
||||
query = query.where('slugId', '=', pageId);
|
||||
}
|
||||
|
||||
await query.execute();
|
||||
}
|
||||
|
||||
async restorePage(pageId: string): Promise<void> {
|
||||
let query = this.db.updateTable('pages').set({ deletedAt: null });
|
||||
|
||||
@ -164,6 +176,23 @@ export class PageRepo {
|
||||
return result;
|
||||
}
|
||||
|
||||
async getDeletedPagesInSpace(spaceId: string, pagination: PaginationOptions) {
|
||||
const query = this.db
|
||||
.selectFrom('pages')
|
||||
.select(this.baseFields)
|
||||
.select((eb) => this.withSpace(eb))
|
||||
.where('spaceId', '=', spaceId)
|
||||
.where('deletedAt', 'is not', null)
|
||||
.orderBy('updatedAt', 'desc');
|
||||
|
||||
const result = executeWithPagination(query, {
|
||||
page: pagination.page,
|
||||
perPage: pagination.limit,
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
withSpace(eb: ExpressionBuilder<DB, 'pages'>) {
|
||||
return jsonObjectFrom(
|
||||
eb
|
||||
|
||||
Reference in New Issue
Block a user