frontend permissions

* rework backend workspace permissions
This commit is contained in:
Philipinho
2024-06-03 02:54:12 +01:00
parent b88e0b605f
commit 886d9591fa
54 changed files with 715 additions and 385 deletions

View File

@ -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>
);

View File

@ -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>

View File

@ -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 });
}
},
});
}

View File

@ -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>
);