mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
fix: public sharing performance improvements (#1841)
This commit is contained in:
@@ -269,12 +269,15 @@ function Node({ node, style, dragHandle, tree }: NodeRendererProps<any>) {
|
||||
const toggleMobileSidebar = useToggleSidebar(mobileSidebarAtom);
|
||||
|
||||
const prefetchPage = () => {
|
||||
timerRef.current = setTimeout(() => {
|
||||
queryClient.prefetchQuery({
|
||||
queryKey: ["pages", node.data.slugId],
|
||||
queryFn: () => getPageById({ pageId: node.data.slugId }),
|
||||
timerRef.current = setTimeout(async () => {
|
||||
const page = await queryClient.fetchQuery({
|
||||
queryKey: ["pages", node.data.id],
|
||||
queryFn: () => getPageById({ pageId: node.data.id }),
|
||||
staleTime: 5 * 60 * 1000,
|
||||
});
|
||||
if (page?.slugId) {
|
||||
queryClient.setQueryData(["pages", page.slugId], page);
|
||||
}
|
||||
}, 150);
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
Switch,
|
||||
Text,
|
||||
TextInput,
|
||||
Tooltip,
|
||||
} from "@mantine/core";
|
||||
import { IconExternalLink, IconWorld, IconLock } from "@tabler/icons-react";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
@@ -21,12 +20,12 @@ import {
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import { extractPageSlugId, getPageIcon } from "@/lib";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { usePageQuery } from "@/features/page/queries/page-query.ts";
|
||||
import CopyTextButton from "@/components/common/copy.tsx";
|
||||
import { getAppUrl, isCloud } from "@/lib/config.ts";
|
||||
import { buildPageUrl } from "@/features/page/page.utils.ts";
|
||||
import classes from "@/features/share/components/share.module.css";
|
||||
import useTrial from "@/ee/hooks/use-trial.tsx";
|
||||
import { getCheckoutLink } from "@/ee/billing/services/billing-service.ts";
|
||||
|
||||
interface ShareModalProps {
|
||||
readOnly: boolean;
|
||||
@@ -35,7 +34,9 @@ export default function ShareModal({ readOnly }: ShareModalProps) {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { pageSlug } = useParams();
|
||||
const pageId = extractPageSlugId(pageSlug);
|
||||
const pageSlugId = extractPageSlugId(pageSlug);
|
||||
const { data: page } = usePageQuery({ pageId: pageSlugId });
|
||||
const pageId = page?.id;
|
||||
const { data: share } = useShareForPageQuery(pageId);
|
||||
const { spaceSlug } = useParams();
|
||||
const { isTrial } = useTrial();
|
||||
|
||||
@@ -27,9 +27,7 @@ import {
|
||||
getShares,
|
||||
updateShare,
|
||||
} from "@/features/share/services/share-service.ts";
|
||||
import { IPage } from "@/features/page/types/page.types.ts";
|
||||
import { IPagination, QueryParams } from "@/lib/types.ts";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export function useGetSharesQuery(
|
||||
params?: QueryParams,
|
||||
@@ -72,7 +70,7 @@ export function useShareForPageQuery(
|
||||
queryKey: ["share-for-page", pageId],
|
||||
queryFn: () => getShareForPage(pageId),
|
||||
enabled: !!pageId,
|
||||
staleTime: 0,
|
||||
staleTime: 60 * 1000,
|
||||
retry: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -123,80 +123,82 @@ export class ShareService {
|
||||
.withRecursive('page_hierarchy', (cte) =>
|
||||
cte
|
||||
.selectFrom('pages')
|
||||
.leftJoin('shares', 'shares.pageId', 'pages.id')
|
||||
.select([
|
||||
'id',
|
||||
'slugId',
|
||||
'pages.id',
|
||||
'pages.slugId',
|
||||
'pages.title',
|
||||
'pages.icon',
|
||||
'parentPageId',
|
||||
'pages.parentPageId',
|
||||
sql`0`.as('level'),
|
||||
'shares.id as shareId',
|
||||
'shares.key as shareKey',
|
||||
'shares.includeSubPages',
|
||||
'shares.searchIndexing',
|
||||
'shares.creatorId',
|
||||
'shares.spaceId',
|
||||
'shares.workspaceId',
|
||||
'shares.createdAt',
|
||||
])
|
||||
.where(isValidUUID(pageId) ? 'id' : 'slugId', '=', pageId)
|
||||
.where('deletedAt', 'is', null)
|
||||
.unionAll((union) =>
|
||||
union
|
||||
.selectFrom('pages as p')
|
||||
.select([
|
||||
'p.id',
|
||||
'p.slugId',
|
||||
'p.title',
|
||||
'p.icon',
|
||||
'p.parentPageId',
|
||||
// Increase the level by 1 for each ancestor.
|
||||
sql`ph.level + 1`.as('level'),
|
||||
])
|
||||
.innerJoin('page_hierarchy as ph', 'ph.parentPageId', 'p.id')
|
||||
.where('p.deletedAt', 'is', null),
|
||||
.where(isValidUUID(pageId) ? 'pages.id' : 'pages.slugId', '=', pageId)
|
||||
.where('pages.deletedAt', 'is', null)
|
||||
.unionAll(
|
||||
(union) =>
|
||||
union
|
||||
.selectFrom('pages as p')
|
||||
.innerJoin('page_hierarchy as ph', 'ph.parentPageId', 'p.id')
|
||||
.leftJoin('shares as s', 's.pageId', 'p.id')
|
||||
.select([
|
||||
'p.id',
|
||||
'p.slugId',
|
||||
'p.title',
|
||||
'p.icon',
|
||||
'p.parentPageId',
|
||||
sql`ph.level + 1`.as('level'),
|
||||
's.id as shareId',
|
||||
's.key as shareKey',
|
||||
's.includeSubPages',
|
||||
's.searchIndexing',
|
||||
's.creatorId',
|
||||
's.spaceId',
|
||||
's.workspaceId',
|
||||
's.createdAt',
|
||||
])
|
||||
.where('p.deletedAt', 'is', null)
|
||||
.where(sql`ph.share_id`, 'is', null) // stop if share found
|
||||
.where(sql`ph.level`, '<', sql`25`), // prevent loop
|
||||
),
|
||||
)
|
||||
.selectFrom('page_hierarchy')
|
||||
.leftJoin('shares', 'shares.pageId', 'page_hierarchy.id')
|
||||
.select([
|
||||
'page_hierarchy.id as sharedPageId',
|
||||
'page_hierarchy.slugId as sharedPageSlugId',
|
||||
'page_hierarchy.title as sharedPageTitle',
|
||||
'page_hierarchy.icon as sharedPageIcon',
|
||||
'page_hierarchy.level as level',
|
||||
'shares.id',
|
||||
'shares.key',
|
||||
'shares.pageId',
|
||||
'shares.includeSubPages',
|
||||
'shares.searchIndexing',
|
||||
'shares.creatorId',
|
||||
'shares.spaceId',
|
||||
'shares.workspaceId',
|
||||
'shares.createdAt',
|
||||
'shares.updatedAt',
|
||||
])
|
||||
.where('shares.id', 'is not', null)
|
||||
.orderBy('page_hierarchy.level', 'asc')
|
||||
.selectAll()
|
||||
.where('shareId', 'is not', null)
|
||||
.limit(1)
|
||||
.executeTakeFirst();
|
||||
|
||||
if (!share || share.workspaceId != workspaceId) {
|
||||
if (!share || share.workspaceId !== workspaceId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (share.level === 1 && !share.includeSubPages) {
|
||||
// we can only show a page if its shared ancestor permits it
|
||||
if ((share.level as number) > 0 && !share.includeSubPages) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
id: share.id,
|
||||
key: share.key,
|
||||
id: share.shareId,
|
||||
key: share.shareKey,
|
||||
includeSubPages: share.includeSubPages,
|
||||
searchIndexing: share.searchIndexing,
|
||||
pageId: share.pageId,
|
||||
pageId: share.id,
|
||||
creatorId: share.creatorId,
|
||||
spaceId: share.spaceId,
|
||||
workspaceId: share.workspaceId,
|
||||
createdAt: share.createdAt,
|
||||
level: share.level,
|
||||
sharedPage: {
|
||||
id: share.sharedPageId,
|
||||
slugId: share.sharedPageSlugId,
|
||||
title: share.sharedPageTitle,
|
||||
icon: share.sharedPageIcon,
|
||||
id: share.id,
|
||||
slugId: share.slugId,
|
||||
title: share.title,
|
||||
icon: share.icon,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user