mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 05:14:54 +00:00
feat(core): add no access to share menu (#10927)
This commit is contained in:
@@ -6,8 +6,10 @@ import { EmptyNodeChildren } from '../../layouts/empty-node-children';
|
||||
|
||||
export const Empty = ({
|
||||
onDrop,
|
||||
noAccessible = false,
|
||||
}: {
|
||||
onDrop: (data: DropTargetDropEvent<AffineDNDData>) => void;
|
||||
noAccessible?: boolean;
|
||||
}) => {
|
||||
const { dropTargetRef } = useDropTarget<AffineDNDData>(
|
||||
() => ({
|
||||
@@ -19,7 +21,9 @@ export const Empty = ({
|
||||
|
||||
return (
|
||||
<EmptyNodeChildren ref={dropTargetRef}>
|
||||
{t['com.affine.rootAppSidebar.docs.no-subdoc']()}
|
||||
{noAccessible
|
||||
? t['com.affine.share-menu.option.permission.no-access']()
|
||||
: t['com.affine.rootAppSidebar.docs.no-subdoc']()}
|
||||
</EmptyNodeChildren>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
toast,
|
||||
Tooltip,
|
||||
} from '@affine/component';
|
||||
import { DocPermissionGuard } from '@affine/core/components/guard/doc-guard';
|
||||
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks';
|
||||
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
||||
import { DocsService } from '@affine/core/modules/doc';
|
||||
@@ -43,6 +44,7 @@ export const ExplorerDocNode = ({
|
||||
}: {
|
||||
docId: string;
|
||||
isLinked?: boolean;
|
||||
forwardKey?: string;
|
||||
} & GenericExplorerNode) => {
|
||||
const t = useI18n();
|
||||
const {
|
||||
@@ -261,24 +263,35 @@ export const ExplorerDocNode = ({
|
||||
}}
|
||||
onRename={handleRename}
|
||||
childrenPlaceholder={
|
||||
searching ? null : <Empty onDrop={handleDropOnPlaceholder} />
|
||||
searching ? null : (
|
||||
<Empty
|
||||
onDrop={handleDropOnPlaceholder}
|
||||
noAccessible={!!children && children.length > 0}
|
||||
/>
|
||||
)
|
||||
}
|
||||
operations={finalOperations}
|
||||
dropEffect={handleDropEffectOnDoc}
|
||||
data-testid={`explorer-doc-${docId}`}
|
||||
>
|
||||
{children?.map(child => (
|
||||
<ExplorerDocNode
|
||||
key={child.docId}
|
||||
docId={child.docId}
|
||||
reorderable={false}
|
||||
location={{
|
||||
at: 'explorer:doc:linked-docs',
|
||||
docId,
|
||||
}}
|
||||
isLinked
|
||||
/>
|
||||
))}
|
||||
<DocPermissionGuard docId={docId} permission="Doc_Read">
|
||||
{canRead =>
|
||||
canRead
|
||||
? children?.map((child, index) => (
|
||||
<ExplorerDocNode
|
||||
key={`${child.docId}-${index}`}
|
||||
docId={child.docId}
|
||||
reorderable={false}
|
||||
location={{
|
||||
at: 'explorer:doc:linked-docs',
|
||||
docId,
|
||||
}}
|
||||
isLinked
|
||||
/>
|
||||
))
|
||||
: null
|
||||
}
|
||||
</DocPermissionGuard>
|
||||
</ExplorerTreeNode>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -73,6 +73,7 @@ export interface BaseExplorerTreeNodeProps {
|
||||
operations?: NodeOperation[];
|
||||
childrenOperations?: NodeOperation[];
|
||||
childrenPlaceholder?: React.ReactNode;
|
||||
|
||||
linkComponent?: React.ComponentType<
|
||||
React.PropsWithChildren<{ to: To; className?: string }> &
|
||||
RefAttributes<any> & { draggable?: boolean }
|
||||
@@ -492,7 +493,7 @@ export const ExplorerTreeNode = ({
|
||||
<Collapsible.Content style={{ display: dragging ? 'none' : undefined }}>
|
||||
{/* For lastInGroup check, the placeholder must be placed above all children in the dom */}
|
||||
<div className={styles.collapseContentPlaceholder}>
|
||||
{childCount === 0 && !collapsed && childrenPlaceholder}
|
||||
{childCount === 0 && !collapsed ? childrenPlaceholder : null}
|
||||
</div>
|
||||
<ExplorerTreeContext.Provider value={contextValue}>
|
||||
{collapsed ? null : children}
|
||||
|
||||
@@ -220,9 +220,12 @@ export function DocPeekPreview({
|
||||
!animating
|
||||
);
|
||||
|
||||
const guardService = useService(GuardService);
|
||||
const canAccess = useLiveData(guardService.can$('Doc_Read', docId));
|
||||
|
||||
// if sync engine has been synced and the page is null, show 404 page.
|
||||
if (!doc || !editor) {
|
||||
return loading ? (
|
||||
if (!doc || !editor || !canAccess) {
|
||||
return loading || canAccess === undefined ? (
|
||||
<PageDetailSkeleton key="current-page-is-null" />
|
||||
) : (
|
||||
<PageNotFound noPermission />
|
||||
|
||||
@@ -28,6 +28,8 @@ const getRoleName = (t: ReturnType<typeof useI18n>, role?: DocRole) => {
|
||||
return t['com.affine.share-menu.option.permission.can-edit']();
|
||||
case DocRole.Reader:
|
||||
return t['com.affine.share-menu.option.permission.can-read']();
|
||||
case DocRole.None:
|
||||
return t['com.affine.share-menu.option.permission.no-access']();
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -53,7 +55,9 @@ export const MembersPermission = ({
|
||||
[docDefaultRole, t]
|
||||
);
|
||||
const showTips =
|
||||
docDefaultRole === DocRole.Reader || docDefaultRole === DocRole.Editor;
|
||||
docDefaultRole === DocRole.Reader ||
|
||||
docDefaultRole === DocRole.Editor ||
|
||||
docDefaultRole === DocRole.None;
|
||||
const changePermission = useAsyncCallback(
|
||||
async (docRole: DocRole) => {
|
||||
try {
|
||||
@@ -93,6 +97,14 @@ export const MembersPermission = ({
|
||||
changePermission(DocRole.Reader);
|
||||
}, [changePermission, hittingPaywall, openPaywallModal]);
|
||||
|
||||
const selectNone = useCallback(() => {
|
||||
if (hittingPaywall) {
|
||||
openPaywallModal?.();
|
||||
return;
|
||||
}
|
||||
changePermission(DocRole.None);
|
||||
}, [changePermission, hittingPaywall, openPaywallModal]);
|
||||
|
||||
return (
|
||||
<div className={styles.rowContainerStyle}>
|
||||
<div className={styles.labelStyle}>
|
||||
@@ -141,6 +153,17 @@ export const MembersPermission = ({
|
||||
</div>
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onSelect={selectNone}
|
||||
selected={docDefaultRole === DocRole.None}
|
||||
>
|
||||
<div className={styles.publicItemRowStyle}>
|
||||
<div className={styles.tagContainerStyle}>
|
||||
{t['com.affine.share-menu.option.permission.no-access']()}
|
||||
{hittingPaywall ? <PlanTag /> : null}
|
||||
</div>
|
||||
</div>
|
||||
</MenuItem>
|
||||
</>
|
||||
}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user