mirror of
https://github.com/docmost/docmost.git
synced 2025-11-12 16:02:35 +10:00
updated page service & controller, recycle bin modal
This commit is contained in:
@ -13,6 +13,7 @@ import { IMovePage, IPage } from "@/features/page/types/page.types.ts";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import {
|
||||
useCreatePageMutation,
|
||||
// useDeletePageMutation,
|
||||
useRemovePageMutation,
|
||||
useMovePageMutation,
|
||||
useUpdatePageMutation,
|
||||
@ -27,7 +28,8 @@ export function useTreeMutation<T>(spaceId: string) {
|
||||
const tree = useMemo(() => new SimpleTree<SpaceTreeNode>(data), [data]);
|
||||
const createPageMutation = useCreatePageMutation();
|
||||
const updatePageMutation = useUpdatePageMutation();
|
||||
const deletePageMutation = useRemovePageMutation();
|
||||
// const deletePageMutation = useDeletePageMutation();
|
||||
const removePageMutation = useRemovePageMutation();
|
||||
const movePageMutation = useMovePageMutation();
|
||||
const navigate = useNavigate();
|
||||
const { spaceSlug } = useParams();
|
||||
@ -180,7 +182,7 @@ export function useTreeMutation<T>(spaceId: string) {
|
||||
|
||||
const onDelete: DeleteHandler<T> = async (args: { ids: string[] }) => {
|
||||
try {
|
||||
await deletePageMutation.mutateAsync(args.ids[0]);
|
||||
await removePageMutation.mutateAsync(args.ids[0]);
|
||||
|
||||
if (tree.find(args.ids[0])) {
|
||||
tree.drop({ id: args.ids[0] });
|
||||
|
||||
@ -3,6 +3,10 @@ import React, { useMemo } from "react";
|
||||
import { useSpaceQuery } from "@/features/space/queries/space-query.ts";
|
||||
import { useSpaceAbility } from "@/features/space/permissions/use-space-ability.ts";
|
||||
import RecycledPagesList from "@/features/space/components/recycled-pages.tsx"
|
||||
import {
|
||||
SpaceCaslAction,
|
||||
SpaceCaslSubject,
|
||||
} from "@/features/space/permissions/permissions.type.ts";
|
||||
|
||||
interface RecycleBinModalProps {
|
||||
spaceId: string;
|
||||
@ -40,7 +44,13 @@ export default function RecycleBinModal({
|
||||
<Modal.Body>
|
||||
<div style={{ height: rem("600px") }}>
|
||||
<ScrollArea h="600" w="100%" scrollbarSize={5}>
|
||||
<RecycledPagesList spaceId={space.id} />
|
||||
<RecycledPagesList
|
||||
spaceId={space?.id}
|
||||
readOnly={spaceAbility.cannot(
|
||||
SpaceCaslAction.Manage,
|
||||
SpaceCaslSubject.Page
|
||||
)}
|
||||
/>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
</Modal.Body>
|
||||
|
||||
@ -10,6 +10,7 @@ interface RecycledPagesProps {
|
||||
|
||||
export default function RecycledPagesList({
|
||||
spaceId,
|
||||
readOnly,
|
||||
}: RecycledPagesProps) {
|
||||
const { data, isLoading } = useDeletedPagesQuery(spaceId);
|
||||
const restorePageMutation = useRestorePageMutation();
|
||||
@ -65,13 +66,13 @@ export default function RecycledPagesList({
|
||||
<Table.Td>
|
||||
<div>
|
||||
<Text fz="sm" fw={500}>
|
||||
{page?.title}
|
||||
{page?.title || "Untitled"}
|
||||
</Text>
|
||||
</div>
|
||||
</Table.Td>
|
||||
|
||||
<Table.Td>
|
||||
{(
|
||||
{!readOnly && (
|
||||
<Menu>
|
||||
<Menu.Target>
|
||||
<ActionIcon variant="subtle" c="gray">
|
||||
@ -88,7 +89,7 @@ export default function RecycledPagesList({
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
onClick={() =>
|
||||
openRemovePageModal
|
||||
openRemovePageModal(page.id)
|
||||
}>
|
||||
Delete Page permanently
|
||||
</Menu.Item>
|
||||
|
||||
@ -12,6 +12,7 @@ import { PageService } from './services/page.service';
|
||||
import { CreatePageDto } from './dto/create-page.dto';
|
||||
import { UpdatePageDto } from './dto/update-page.dto';
|
||||
import { MovePageDto } from './dto/move-page.dto';
|
||||
// import { RestorePageDto } from './dto/restore-page.dto';
|
||||
import { PageHistoryIdDto, PageIdDto, PageInfoDto } from './dto/page.dto';
|
||||
import { PageHistoryService } from './services/page-history.service';
|
||||
import { AuthUser } from '../../common/decorators/auth-user.decorator';
|
||||
@ -132,8 +133,19 @@ export class PageController {
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('restore')
|
||||
async restore(@Body() pageIdDto: PageIdDto) {
|
||||
await this.pageService.restore(pageIdDto.pageId);
|
||||
async restore(@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.restore(pageIdDto.pageId);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
|
||||
@ -162,9 +162,11 @@ export class PageService {
|
||||
'parentPageId',
|
||||
'spaceId',
|
||||
'creatorId',
|
||||
'deletedAt',
|
||||
])
|
||||
.select((eb) => this.withHasChildren(eb))
|
||||
.orderBy('position', 'asc')
|
||||
.where('deletedAt', 'is', null)
|
||||
.where('spaceId', '=', spaceId);
|
||||
|
||||
if (pageId) {
|
||||
|
||||
@ -148,6 +148,7 @@ export class PageRepo {
|
||||
.select(this.baseFields)
|
||||
.select((eb) => this.withSpace(eb))
|
||||
.where('spaceId', '=', spaceId)
|
||||
.where('deletedAt', 'is not', null)
|
||||
.orderBy('updatedAt', 'desc');
|
||||
|
||||
const result = executeWithPagination(query, {
|
||||
@ -166,6 +167,7 @@ export class PageRepo {
|
||||
.select(this.baseFields)
|
||||
.select((eb) => this.withSpace(eb))
|
||||
.where('spaceId', 'in', userSpaceIds)
|
||||
.where('deletedAt', 'is not', null)
|
||||
.orderBy('updatedAt', 'desc');
|
||||
|
||||
const result = executeWithPagination(query, {
|
||||
|
||||
Reference in New Issue
Block a user