diff --git a/.eslintrc.js b/.eslintrc.js index 69b2f4fe90..53da9ed66a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -22,10 +22,15 @@ const createPattern = packageName => [ allowTypeImports: false, }, { - group: ['@blocksuite/store'], + group: ['@blocksuite /store'], message: "Import from '@blocksuite/global/utils'", importNames: ['assertExists', 'assertEquals'], }, + { + group: ['react-router-dom'], + message: 'Use `useNavigateHelper` instead', + importNames: ['useNavigate'], + }, ]; const allPackages = [ @@ -144,6 +149,11 @@ const config = { message: "Import from '@blocksuite/global/utils'", importNames: ['assertExists', 'assertEquals'], }, + { + group: ['react-router-dom'], + message: 'Use `useNavigateHelper` instead', + importNames: ['useNavigate'], + }, ], }, ], diff --git a/apps/core/src/atoms/history.ts b/apps/core/src/atoms/history.ts index 9d38c8fcf4..69364f8a2c 100644 --- a/apps/core/src/atoms/history.ts +++ b/apps/core/src/atoms/history.ts @@ -1,6 +1,7 @@ import { useAtom } from 'jotai'; import { atomWithStorage, createJSONStorage } from 'jotai/utils'; import { useCallback } from 'react'; +// eslint-disable-next-line @typescript-eslint/no-restricted-imports import { useNavigate } from 'react-router-dom'; import { router } from '../router'; diff --git a/apps/core/src/components/pure/quick-search-modal/config.ts b/apps/core/src/components/pure/quick-search-modal/config.ts index 3d665dc089..a1fd22ee9f 100644 --- a/apps/core/src/components/pure/quick-search-modal/config.ts +++ b/apps/core/src/components/pure/quick-search-modal/config.ts @@ -1,3 +1,4 @@ +import { WorkspaceSubPath } from '@affine/env/workspace'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { DeleteTemporarilyIcon, @@ -9,23 +10,27 @@ import type { FC, SVGProps } from 'react'; import { useMemo } from 'react'; import { openSettingModalAtom } from '../../../atoms'; -import { pathGenerator } from '../../../shared'; -export const useSwitchToConfig = ( - workspaceId: string -): { - title: string; - href?: string; - onClick?: () => void; - icon: FC>; -}[] => { +export type Config = + | { + title: string; + icon: FC>; + subPath: WorkspaceSubPath; + } + | { + title: string; + icon: FC>; + onClick: () => void; + }; + +export const useSwitchToConfig = (workspaceId: string): Config[] => { const t = useAFFiNEI18N(); const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom); return useMemo( () => [ { title: t['All pages'](), - href: pathGenerator.all(workspaceId), + subPath: WorkspaceSubPath.ALL, icon: FolderIcon, }, { @@ -41,7 +46,7 @@ export const useSwitchToConfig = ( }, { title: t['Trash'](), - href: pathGenerator.trash(workspaceId), + subPath: WorkspaceSubPath.TRASH, icon: DeleteTemporarilyIcon, }, ], diff --git a/apps/core/src/components/pure/quick-search-modal/index.tsx b/apps/core/src/components/pure/quick-search-modal/index.tsx index e5b2775fd2..81d641de1e 100644 --- a/apps/core/src/components/pure/quick-search-modal/index.tsx +++ b/apps/core/src/components/pure/quick-search-modal/index.tsx @@ -2,8 +2,7 @@ import { Modal, ModalWrapper } from '@affine/component'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { Command } from 'cmdk'; import { startTransition } from 'react'; -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { useLocation } from 'react-router-dom'; +import { useCallback, useEffect, useRef, useState } from 'react'; import type { AllWorkspace } from '../../../shared'; import { Footer } from './footer'; @@ -37,15 +36,7 @@ export const QuickSearchModal: React.FC = ({ _setQuery(query); }); }, []); - const location = useLocation(); - const isPublicWorkspace = useMemo( - () => location.pathname.startsWith('/public-workspace'), - [location] - ); const [showCreatePage, setShowCreatePage] = useState(true); - const isPublicAndNoQuery = useCallback(() => { - return isPublicWorkspace && query.length === 0; - }, [isPublicWorkspace, query.length]); const handleClose = useCallback(() => { setOpen(false); }, [setOpen]); @@ -88,7 +79,7 @@ export const QuickSearchModal: React.FC = ({ width={608} style={{ maxHeight: '80vh', - minHeight: isPublicAndNoQuery() ? '72px' : '412px', + minHeight: '412px', top: '80px', overflow: 'hidden', }} @@ -134,13 +125,9 @@ export const QuickSearchModal: React.FC = ({ : 'Ctrl + K'} - + - + = ({ setShowCreatePage={setShowCreatePage} /> - {isPublicWorkspace ? null : showCreatePage ? ( + {showCreatePage ? ( <> diff --git a/apps/core/src/components/pure/quick-search-modal/results.tsx b/apps/core/src/components/pure/quick-search-modal/results.tsx index 3ac21890d9..5771858910 100644 --- a/apps/core/src/components/pure/quick-search-modal/results.tsx +++ b/apps/core/src/components/pure/quick-search-modal/results.tsx @@ -7,8 +7,6 @@ import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suit import { Command } from 'cmdk'; import { useAtomValue } from 'jotai'; import type { Dispatch, FC, SetStateAction } from 'react'; -import { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; import { recentPageSettingsAtom } from '../../../atoms'; import { useNavigateHelper } from '../../../hooks/use-navigate-helper'; @@ -32,12 +30,11 @@ export const Results: FC = ({ useBlockSuiteWorkspaceHelper(blockSuiteWorkspace); const pageList = useBlockSuitePageMeta(blockSuiteWorkspace); assertExists(blockSuiteWorkspace.id); - const List = useSwitchToConfig(workspace.id); + const list = useSwitchToConfig(workspace.id); const recentPageSetting = useAtomValue(recentPageSettingsAtom); const t = useAFFiNEI18N(); - const navigate = useNavigate(); - const { jumpToPage } = useNavigateHelper(); + const { jumpToPage, jumpToSubPath } = useNavigateHelper(); const results = blockSuiteWorkspace.search({ query }); // remove `space:` prefix @@ -55,10 +52,7 @@ export const Results: FC = ({ return page.trash !== true; } }); - useEffect(() => { - setShowCreatePage(!resultsPageMeta.length); - //Determine whether to display the ‘+ New page’ - }, [resultsPageMeta.length, setShowCreatePage]); + setShowCreatePage(resultsPageMeta.length === 0); if (!query) { return ( <> @@ -90,15 +84,20 @@ export const Results: FC = ({ )} - {List.map(link => { + {list.map(link => { return ( { onClose(); - link.href && navigate(link.href); - link.onClick?.(); + if ('subPath' in link) { + jumpToSubPath(blockSuiteWorkspace.id, link.subPath); + } else if ('onClick' in link) { + link.onClick(); + } else { + throw new Error('Invalid link'); + } }} > diff --git a/apps/core/src/hooks/use-navigate-helper.ts b/apps/core/src/hooks/use-navigate-helper.ts index 49e7c944bc..525f15d7c1 100644 --- a/apps/core/src/hooks/use-navigate-helper.ts +++ b/apps/core/src/hooks/use-navigate-helper.ts @@ -1,5 +1,6 @@ import type { WorkspaceSubPath } from '@affine/env/workspace'; import { useCallback } from 'react'; +// eslint-disable-next-line @typescript-eslint/no-restricted-imports import { useLocation, useNavigate } from 'react-router-dom'; export enum RouteLogic { diff --git a/apps/core/src/pages/workspace/detail-page.tsx b/apps/core/src/pages/workspace/detail-page.tsx index 62f803666b..e536b08fe1 100644 --- a/apps/core/src/pages/workspace/detail-page.tsx +++ b/apps/core/src/pages/workspace/detail-page.tsx @@ -12,7 +12,7 @@ import { useAtomValue } from 'jotai'; import { useAtom } from 'jotai/react'; import { type ReactElement, useCallback, useEffect } from 'react'; import type { LoaderFunction } from 'react-router-dom'; -import { useLocation, useNavigate, useParams } from 'react-router-dom'; +import { useLocation, useParams } from 'react-router-dom'; import { getUIAdapter } from '../../adapters/workspace'; import { useCurrentWorkspace } from '../../hooks/current/use-current-workspace'; @@ -71,7 +71,7 @@ const DetailPageImpl = (): ReactElement => { export const DetailPage = (): ReactElement => { const { workspaceId, pageId } = useParams(); const location = useLocation(); - const navigate = useNavigate(); + const { jumpTo404 } = useNavigateHelper(); const [currentWorkspace] = useCurrentWorkspace(); const [currentPageId, setCurrentPageId] = useAtom(currentPageIdAtom); const page = currentPageId @@ -91,7 +91,7 @@ export const DetailPage = (): ReactElement => { const page = currentWorkspace.blockSuiteWorkspace.getPage(currentPageId); if (!page) { - navigate('/404'); + jumpTo404(); } else { // fixme: cleanup jumpOnce in the right time if (page.meta.jumpOnce) { @@ -106,8 +106,8 @@ export const DetailPage = (): ReactElement => { currentPageId, currentWorkspace.blockSuiteWorkspace, currentWorkspace.id, + jumpTo404, location.pathname, - navigate, pageId, setCurrentPageId, workspaceId,