feat(core): add use guard hook (#11180)

Previously, we used `useLiveData(guardService.can$())` to get the guard result, but `guardService.can$()` will request the server to revalidate the permission when calling it, will cause additional network requests when re-render.

This pr make a new hook `useGuard` to fix this problem.

And the side effect in `can$` is moved to `revalidateCan()` to make that the subscribe method is pure
This commit is contained in:
EYHN
2025-03-25 14:15:29 +00:00
parent a10acf304b
commit 3df51a217d
28 changed files with 154 additions and 163 deletions
@@ -6,13 +6,13 @@ import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-
import { EditorOutlineViewer } from '@affine/core/blocksuite/outline-viewer';
import { PageAIOnboarding } from '@affine/core/components/affine/ai-onboarding';
import { DocPropertySidebar } from '@affine/core/components/doc-properties/sidebar';
import { useGuard } from '@affine/core/components/guard';
import { useAppSettingHelper } from '@affine/core/components/hooks/affine/use-app-setting-helper';
import { useEnableAI } from '@affine/core/components/hooks/affine/use-enable-ai';
import { DocService } from '@affine/core/modules/doc';
import { EditorService } from '@affine/core/modules/editor';
import { GlobalContextService } from '@affine/core/modules/global-context';
import { PeekViewService } from '@affine/core/modules/peek-view';
import { GuardService } from '@affine/core/modules/permissions';
import { RecentDocsService } from '@affine/core/modules/quicksearch';
import { ViewService } from '@affine/core/modules/workbench';
import { WorkspaceService } from '@affine/core/modules/workspace';
@@ -69,7 +69,6 @@ const DetailPageImpl = memo(function DetailPageImpl() {
docService,
workspaceService,
globalContextService,
guardService,
} = useServices({
WorkbenchService,
ViewService,
@@ -77,7 +76,6 @@ const DetailPageImpl = memo(function DetailPageImpl() {
DocService,
WorkspaceService,
GlobalContextService,
GuardService,
});
const workbench = workbenchService.workbench;
const editor = editorService.editor;
@@ -262,7 +260,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
const [dragging, setDragging] = useState(false);
const canEdit = useLiveData(guardService.can$('Doc_Update', doc.id));
const canEdit = useGuard('Doc_Update', doc.id);
const readonly = !canEdit || isInTrash;
@@ -368,7 +366,6 @@ const DetailPageImpl = memo(function DetailPageImpl() {
export const Component = () => {
const params = useParams();
const recentPages = useService(RecentDocsService);
const guardService = useService(GuardService);
useEffect(() => {
if (params.pageId) {
@@ -380,9 +377,7 @@ export const Component = () => {
}, [params, recentPages]);
const pageId = params.pageId;
const canAccess = useLiveData(
pageId ? guardService.can$('Doc_Read', pageId) : undefined
);
const canAccess = useGuard('Doc_Read', pageId ?? '');
return pageId ? (
<DetailPageWrapper
@@ -8,7 +8,7 @@ import {
Scrollable,
useConfirmModal,
} from '@affine/component';
import { DocPermissionGuard } from '@affine/core/components/guard/doc-guard';
import { Guard } from '@affine/core/components/guard';
import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal';
import { MoveToTrash } from '@affine/core/components/page-list';
import {
@@ -367,10 +367,7 @@ const ConflictList = ({
}}
items={
<>
<DocPermissionGuard
docId={docRecord.id}
permission="Doc_Update"
>
<Guard docId={docRecord.id} permission="Doc_Update">
{canEdit => (
<MenuItem
prefixIcon={<CalendarXmarkIcon />}
@@ -386,19 +383,16 @@ const ConflictList = ({
]()}
</MenuItem>
)}
</DocPermissionGuard>
</Guard>
<MenuSeparator />
<DocPermissionGuard
docId={docRecord.id}
permission="Doc_Trash"
>
<Guard docId={docRecord.id} permission="Doc_Trash">
{canTrash => (
<MoveToTrash
onSelect={() => handleOpenTrashModal(docRecord)}
disabled={!canTrash}
/>
)}
</DocPermissionGuard>
</Guard>
</>
}
>