mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
ui permissions
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { useSpaceAbility } from "@/features/space/permissions/use-space-ability";
|
||||
import {
|
||||
SpaceCaslAction,
|
||||
SpaceCaslSubject,
|
||||
} from "@/features/space/permissions/permissions.type";
|
||||
import { usePageRestrictionInfoQuery } from "@/ee/page-permission/queries/page-permission-query";
|
||||
|
||||
export function usePagePermission(pageId: string, spaceRules: any) {
|
||||
const spaceAbility = useSpaceAbility(spaceRules);
|
||||
const { data: restrictionInfo, isLoading } =
|
||||
usePageRestrictionInfoQuery(pageId);
|
||||
|
||||
if (isLoading || !restrictionInfo) {
|
||||
return { canEdit: false, restrictionInfo: undefined };
|
||||
}
|
||||
|
||||
const hasRestriction =
|
||||
restrictionInfo.hasDirectRestriction ||
|
||||
restrictionInfo.hasInheritedRestriction;
|
||||
|
||||
const canEdit = hasRestriction
|
||||
? (restrictionInfo.userAccess?.canEdit ?? false)
|
||||
: spaceAbility.can(SpaceCaslAction.Manage, SpaceCaslSubject.Page);
|
||||
|
||||
return { canEdit, restrictionInfo };
|
||||
}
|
||||
@@ -4,6 +4,7 @@ export * from "./components/publish-tab";
|
||||
export * from "./components/page-permission-list";
|
||||
export * from "./components/page-permission-item";
|
||||
export * from "./components/general-access-select";
|
||||
export * from "./hooks/use-page-permission";
|
||||
export * from "./queries/page-permission-query";
|
||||
export * from "./services/page-permission-service";
|
||||
export * from "./types/page-permission.types";
|
||||
|
||||
@@ -17,11 +17,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { useQueryEmit } from "@/features/websocket/use-query-emit";
|
||||
import { useIsCloudEE } from "@/hooks/use-is-cloud-ee";
|
||||
import { useGetSpaceBySlugQuery } from "@/features/space/queries/space-query.ts";
|
||||
import { useSpaceAbility } from "@/features/space/permissions/use-space-ability.ts";
|
||||
import {
|
||||
SpaceCaslAction,
|
||||
SpaceCaslSubject,
|
||||
} from "@/features/space/permissions/permissions.type.ts";
|
||||
import { usePagePermission } from "@/ee/page-permission";
|
||||
|
||||
function CommentListWithTabs() {
|
||||
const { t } = useTranslation();
|
||||
@@ -38,13 +34,9 @@ function CommentListWithTabs() {
|
||||
const isCloudEE = useIsCloudEE();
|
||||
const { data: space } = useGetSpaceBySlugQuery(page?.space?.slug);
|
||||
|
||||
const spaceRules = space?.membership?.permissions;
|
||||
const spaceAbility = useSpaceAbility(spaceRules);
|
||||
|
||||
|
||||
const canComment: boolean = spaceAbility.can(
|
||||
SpaceCaslAction.Manage,
|
||||
SpaceCaslSubject.Page
|
||||
const { canEdit: canComment } = usePagePermission(
|
||||
page?.id,
|
||||
space?.membership?.permissions,
|
||||
);
|
||||
|
||||
// Separate active and resolved comments
|
||||
@@ -54,14 +46,14 @@ function CommentListWithTabs() {
|
||||
}
|
||||
|
||||
const parentComments = comments.items.filter(
|
||||
(comment: IComment) => comment.parentCommentId === null
|
||||
(comment: IComment) => comment.parentCommentId === null,
|
||||
);
|
||||
|
||||
const active = parentComments.filter(
|
||||
(comment: IComment) => !comment.resolvedAt
|
||||
(comment: IComment) => !comment.resolvedAt,
|
||||
);
|
||||
const resolved = parentComments.filter(
|
||||
(comment: IComment) => comment.resolvedAt
|
||||
(comment: IComment) => comment.resolvedAt,
|
||||
);
|
||||
|
||||
return { activeComments: active, resolvedComments: resolved };
|
||||
@@ -89,7 +81,7 @@ function CommentListWithTabs() {
|
||||
setIsLoading(false);
|
||||
}
|
||||
},
|
||||
[createCommentMutation, page?.id]
|
||||
[createCommentMutation, page?.id],
|
||||
);
|
||||
|
||||
const renderComments = useCallback(
|
||||
@@ -131,7 +123,7 @@ function CommentListWithTabs() {
|
||||
)}
|
||||
</Paper>
|
||||
),
|
||||
[comments, handleAddReply, isLoading, space?.membership?.role]
|
||||
[comments, handleAddReply, isLoading, space?.membership?.role],
|
||||
);
|
||||
|
||||
if (isCommentsLoading) {
|
||||
@@ -199,7 +191,14 @@ function CommentListWithTabs() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ height: "85vh", display: "flex", flexDirection: "column", marginTop: '-15px' }}>
|
||||
<div
|
||||
style={{
|
||||
height: "85vh",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
marginTop: "-15px",
|
||||
}}
|
||||
>
|
||||
<Tabs defaultValue="open" variant="default" style={{ flex: "0 0 auto" }}>
|
||||
<Tabs.List justify="center">
|
||||
<Tabs.Tab
|
||||
@@ -273,9 +272,9 @@ const ChildComments = ({
|
||||
const getChildComments = useCallback(
|
||||
(parentId: string) =>
|
||||
comments.items.filter(
|
||||
(comment: IComment) => comment.parentCommentId === parentId
|
||||
(comment: IComment) => comment.parentCommentId === parentId,
|
||||
),
|
||||
[comments.items]
|
||||
[comments.items],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -171,11 +171,14 @@ export function TitleEditor({
|
||||
}, [pageId]);
|
||||
|
||||
useEffect(() => {
|
||||
// honor user default page edit mode preference
|
||||
if (userPageEditMode && titleEditor && editable) {
|
||||
if (userPageEditMode === PageEditMode.Edit) {
|
||||
titleEditor.setEditable(true);
|
||||
} else if (userPageEditMode === PageEditMode.Read) {
|
||||
if (titleEditor) {
|
||||
if (userPageEditMode && editable) {
|
||||
if (userPageEditMode === PageEditMode.Edit) {
|
||||
titleEditor.setEditable(true);
|
||||
} else if (userPageEditMode === PageEditMode.Read) {
|
||||
titleEditor.setEditable(false);
|
||||
}
|
||||
} else {
|
||||
titleEditor.setEditable(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,9 @@ import { Helmet } from "react-helmet-async";
|
||||
import PageHeader from "@/features/page/components/header/page-header.tsx";
|
||||
import { extractPageSlugId } from "@/lib";
|
||||
import { useGetSpaceBySlugQuery } from "@/features/space/queries/space-query.ts";
|
||||
import { useSpaceAbility } from "@/features/space/permissions/use-space-ability.ts";
|
||||
import {
|
||||
SpaceCaslAction,
|
||||
SpaceCaslSubject,
|
||||
} from "@/features/space/permissions/permissions.type.ts";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import React from "react";
|
||||
import { usePagePermission } from "@/ee/page-permission";
|
||||
|
||||
const MemoizedFullEditor = React.memo(FullEditor);
|
||||
const MemoizedPageHeader = React.memo(PageHeader);
|
||||
@@ -30,8 +26,7 @@ export default function Page() {
|
||||
} = usePageQuery({ pageId: extractPageSlugId(pageSlug) });
|
||||
const { data: space } = useGetSpaceBySlugQuery(page?.space?.slug);
|
||||
|
||||
const spaceRules = space?.membership?.permissions;
|
||||
const spaceAbility = useSpaceAbility(spaceRules);
|
||||
const { canEdit } = usePagePermission(page?.id, space?.membership?.permissions);
|
||||
|
||||
if (isLoading) {
|
||||
return <></>;
|
||||
@@ -55,12 +50,7 @@ export default function Page() {
|
||||
<title>{`${page?.icon || ""} ${page?.title || t("untitled")}`}</title>
|
||||
</Helmet>
|
||||
|
||||
<MemoizedPageHeader
|
||||
readOnly={spaceAbility.cannot(
|
||||
SpaceCaslAction.Manage,
|
||||
SpaceCaslSubject.Page,
|
||||
)}
|
||||
/>
|
||||
<MemoizedPageHeader readOnly={!canEdit} />
|
||||
|
||||
<MemoizedFullEditor
|
||||
key={page.id}
|
||||
@@ -69,10 +59,7 @@ export default function Page() {
|
||||
content={page.content}
|
||||
slugId={page.slugId}
|
||||
spaceSlug={page?.space?.slug}
|
||||
editable={spaceAbility.can(
|
||||
SpaceCaslAction.Manage,
|
||||
SpaceCaslSubject.Page,
|
||||
)}
|
||||
editable={canEdit}
|
||||
/>
|
||||
<MemoizedHistoryModal pageId={page.id} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user