mirror of
https://github.com/docmost/docmost.git
synced 2025-11-17 05:51:10 +10:00
frontend permissions
* rework backend workspace permissions
This commit is contained in:
@ -19,8 +19,12 @@ import { getAppUrl } from "@/lib/config.ts";
|
||||
import { extractPageSlugId } from "@/lib";
|
||||
import { treeApiAtom } from "@/features/page/tree/atoms/tree-api-atom.ts";
|
||||
import { useDeletePageModal } from "@/features/page/hooks/use-delete-page-modal.tsx";
|
||||
import { boolean } from "zod";
|
||||
|
||||
export default function PageHeaderMenu() {
|
||||
interface PageHeaderMenuProps {
|
||||
readOnly?: boolean;
|
||||
}
|
||||
export default function PageHeaderMenu({ readOnly }: PageHeaderMenuProps) {
|
||||
const toggleAside = useToggleAside();
|
||||
|
||||
return (
|
||||
@ -35,12 +39,15 @@ export default function PageHeaderMenu() {
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
|
||||
<PageActionMenu />
|
||||
<PageActionMenu readOnly={readOnly} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function PageActionMenu() {
|
||||
interface PageActionMenuProps {
|
||||
readOnly?: boolean;
|
||||
}
|
||||
function PageActionMenu({ readOnly }: PageActionMenuProps) {
|
||||
const [, setHistoryModalOpen] = useAtom(historyAtoms);
|
||||
const clipboard = useClipboard({ timeout: 500 });
|
||||
const { pageSlug, spaceSlug } = useParams();
|
||||
@ -96,14 +103,18 @@ function PageActionMenu() {
|
||||
Page history
|
||||
</Menu.Item>
|
||||
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
color={"red"}
|
||||
leftSection={<IconTrash size={16} stroke={2} />}
|
||||
onClick={handleDeletePage}
|
||||
>
|
||||
Delete
|
||||
</Menu.Item>
|
||||
{!readOnly && (
|
||||
<>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
color={"red"}
|
||||
leftSection={<IconTrash size={16} stroke={2} />}
|
||||
onClick={handleDeletePage}
|
||||
>
|
||||
Delete
|
||||
</Menu.Item>
|
||||
</>
|
||||
)}
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
@ -3,14 +3,17 @@ import PageHeaderMenu from "@/features/page/components/header/page-header-menu.t
|
||||
import { Group } from "@mantine/core";
|
||||
import Breadcrumb from "@/features/page/components/breadcrumbs/breadcrumb.tsx";
|
||||
|
||||
export default function PageHeader() {
|
||||
interface Props {
|
||||
readOnly?: boolean;
|
||||
}
|
||||
export default function PageHeader({ readOnly }: Props) {
|
||||
return (
|
||||
<div className={classes.header}>
|
||||
<Group justify="space-between" h="100%" px="md" wrap="nowrap">
|
||||
<Breadcrumb />
|
||||
|
||||
<Group justify="flex-end" h="100%" px="md" wrap="nowrap">
|
||||
<PageHeaderMenu />
|
||||
<PageHeaderMenu readOnly={readOnly} />
|
||||
</Group>
|
||||
</Group>
|
||||
</div>
|
||||
|
||||
@ -49,11 +49,26 @@ export function useCreatePageMutation() {
|
||||
|
||||
export function useUpdatePageMutation() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<IPage, Error, Partial<IPageInput>>({
|
||||
mutationFn: (data) => updatePage(data),
|
||||
onSuccess: (data) => {
|
||||
// update page in cache
|
||||
queryClient.setQueryData(["pages", data.slugId], data);
|
||||
const pageBySlug = queryClient.getQueryData<IPage>([
|
||||
"pages",
|
||||
data.slugId,
|
||||
]);
|
||||
const pageById = queryClient.getQueryData<IPage>(["pages", data.id]);
|
||||
|
||||
if (pageBySlug) {
|
||||
queryClient.setQueryData(["pages", data.slugId], {
|
||||
...pageBySlug,
|
||||
...data,
|
||||
});
|
||||
}
|
||||
|
||||
if (pageById) {
|
||||
queryClient.setQueryData(["pages", data.id], { ...pageById, ...data });
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -50,11 +50,12 @@ import { useDeletePageModal } from "@/features/page/hooks/use-delete-page-modal.
|
||||
|
||||
interface SpaceTreeProps {
|
||||
spaceId: string;
|
||||
readOnly: boolean;
|
||||
}
|
||||
|
||||
const openTreeNodesAtom = atom<OpenMap>({});
|
||||
|
||||
export default function SpaceTree({ spaceId }: SpaceTreeProps) {
|
||||
export default function SpaceTree({ spaceId, readOnly }: SpaceTreeProps) {
|
||||
const { pageSlug } = useParams();
|
||||
const { data, setData, controllers } =
|
||||
useTreeMutation<TreeApi<SpaceTreeNode>>(spaceId);
|
||||
@ -190,6 +191,9 @@ export default function SpaceTree({ spaceId }: SpaceTreeProps) {
|
||||
{rootElement.current && (
|
||||
<Tree
|
||||
data={data}
|
||||
disableDrag={readOnly}
|
||||
disableDrop={readOnly}
|
||||
disableEdit={readOnly}
|
||||
{...controllers}
|
||||
width={width}
|
||||
height={height}
|
||||
@ -328,6 +332,7 @@ function Node({ node, style, dragHandle, tree }: NodeRendererProps<any>) {
|
||||
<IconFileDescription size="18" />
|
||||
)
|
||||
}
|
||||
readOnly={tree.props.disableEdit as boolean}
|
||||
removeEmojiAction={handleRemoveEmoji}
|
||||
/>
|
||||
</div>
|
||||
@ -336,11 +341,14 @@ function Node({ node, style, dragHandle, tree }: NodeRendererProps<any>) {
|
||||
|
||||
<div className={classes.actions}>
|
||||
<NodeMenu node={node} treeApi={tree} />
|
||||
<CreateNode
|
||||
node={node}
|
||||
treeApi={tree}
|
||||
onExpandTree={() => handleLoadChildren(node)}
|
||||
/>
|
||||
|
||||
{!tree.props.disableEdit && (
|
||||
<CreateNode
|
||||
node={node}
|
||||
treeApi={tree}
|
||||
onExpandTree={() => handleLoadChildren(node)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
@ -429,18 +437,23 @@ function NodeMenu({ node, treeApi }: NodeMenuProps) {
|
||||
Copy link
|
||||
</Menu.Item>
|
||||
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
c="red"
|
||||
leftSection={
|
||||
<IconTrash style={{ width: rem(14), height: rem(14) }} />
|
||||
}
|
||||
onClick={() =>
|
||||
openDeleteModal({ onConfirm: () => treeApi?.delete(node) })
|
||||
}
|
||||
>
|
||||
Delete
|
||||
</Menu.Item>
|
||||
{!(treeApi.props.disableEdit as boolean) && (
|
||||
<>
|
||||
<Menu.Divider />
|
||||
|
||||
<Menu.Item
|
||||
c="red"
|
||||
leftSection={
|
||||
<IconTrash style={{ width: rem(14), height: rem(14) }} />
|
||||
}
|
||||
onClick={() =>
|
||||
openDeleteModal({ onConfirm: () => treeApi?.delete(node) })
|
||||
}
|
||||
>
|
||||
Delete
|
||||
</Menu.Item>
|
||||
</>
|
||||
)}
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user