feat: adapt the quick search to the public page
This commit is contained in:
@@ -8,17 +8,17 @@ import React, {
|
|||||||
import { SearchIcon } from '@blocksuite/icons';
|
import { SearchIcon } from '@blocksuite/icons';
|
||||||
import { StyledInputContent, StyledLabel } from './style';
|
import { StyledInputContent, StyledLabel } from './style';
|
||||||
import { Command } from 'cmdk';
|
import { Command } from 'cmdk';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
export const Input = (props: {
|
export const Input = (props: {
|
||||||
query: string;
|
query: string;
|
||||||
setQuery: Dispatch<SetStateAction<string>>;
|
setQuery: Dispatch<SetStateAction<string>>;
|
||||||
setLoading: Dispatch<SetStateAction<boolean>>;
|
setLoading: Dispatch<SetStateAction<boolean>>;
|
||||||
|
isPublic: boolean;
|
||||||
|
publishWorkspaceName: string | undefined;
|
||||||
}) => {
|
}) => {
|
||||||
const [isComposition, setIsComposition] = useState(false);
|
const [isComposition, setIsComposition] = useState(false);
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const { currentWorkspace } = useAppState();
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
inputRef.current?.addEventListener(
|
inputRef.current?.addEventListener(
|
||||||
@@ -78,9 +78,9 @@ export const Input = (props: {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
placeholder={
|
placeholder={
|
||||||
currentWorkspace?.isPublish
|
props.isPublic
|
||||||
? t('Quick search placeholder2', {
|
? t('Quick search placeholder2', {
|
||||||
workspace: currentWorkspace?.blocksuiteWorkspace?.meta.name,
|
workspace: props.publishWorkspaceName,
|
||||||
})
|
})
|
||||||
: t('Quick search placeholder')
|
: t('Quick search placeholder')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import { Command } from 'cmdk';
|
||||||
|
import { StyledListItem, StyledNotFound } from './style';
|
||||||
|
import { PaperIcon, EdgelessIcon } from '@blocksuite/icons';
|
||||||
|
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
||||||
|
import { useAppState, PageMeta } from '@/providers/app-state-provider';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { NoResultSVG } from './NoResultSVG';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import usePageHelper from '@/hooks/use-page-helper';
|
||||||
|
import { Workspace } from '@blocksuite/store';
|
||||||
|
|
||||||
|
export const PublishedResults = (props: {
|
||||||
|
query: string;
|
||||||
|
loading: boolean;
|
||||||
|
setLoading: Dispatch<SetStateAction<boolean>>;
|
||||||
|
setPublishWorkspaceName: Dispatch<SetStateAction<string>>;
|
||||||
|
onClose: () => void;
|
||||||
|
}) => {
|
||||||
|
const [workspace, setWorkspace] = useState<Workspace>();
|
||||||
|
const { query, loading, setLoading, onClose, setPublishWorkspaceName } =
|
||||||
|
props;
|
||||||
|
const { search } = usePageHelper();
|
||||||
|
const [results, setResults] = useState(new Map<string, string | undefined>());
|
||||||
|
const { dataCenter } = useAppState();
|
||||||
|
const router = useRouter();
|
||||||
|
const [pageList, setPageList] = useState<PageMeta[]>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
dataCenter
|
||||||
|
.loadPublicWorkspace(router.query.workspaceId as string)
|
||||||
|
.then(data => {
|
||||||
|
setPageList(data.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]);
|
||||||
|
if (data && data.blocksuiteWorkspace) {
|
||||||
|
setWorkspace(data.blocksuiteWorkspace);
|
||||||
|
setPublishWorkspaceName(data.blocksuiteWorkspace.meta.name);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
router.push('/404');
|
||||||
|
});
|
||||||
|
}, [router, dataCenter, setPublishWorkspaceName]);
|
||||||
|
const { t } = useTranslation();
|
||||||
|
useEffect(() => {
|
||||||
|
setResults(search(query, workspace));
|
||||||
|
setLoading(false);
|
||||||
|
//Save the Map<BlockId, PageId> obtained from the search as state
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [query, setResults, setLoading]);
|
||||||
|
const pageIds = [...results.values()];
|
||||||
|
const resultsPageMeta = pageList.filter(
|
||||||
|
page => pageIds.indexOf(page.id) > -1 && !page.trash
|
||||||
|
);
|
||||||
|
|
||||||
|
return loading ? null : (
|
||||||
|
<>
|
||||||
|
{query ? (
|
||||||
|
resultsPageMeta.length ? (
|
||||||
|
<Command.Group
|
||||||
|
heading={t('Find results', { number: resultsPageMeta.length })}
|
||||||
|
>
|
||||||
|
{resultsPageMeta.map(result => {
|
||||||
|
return (
|
||||||
|
<Command.Item
|
||||||
|
key={result.id}
|
||||||
|
onSelect={() => {
|
||||||
|
router.push(
|
||||||
|
`/public-workspace/${router.query.workspaceId}/${result.id}`
|
||||||
|
);
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
value={result.id}
|
||||||
|
>
|
||||||
|
<StyledListItem>
|
||||||
|
{result.mode === 'edgeless' ? (
|
||||||
|
<EdgelessIcon />
|
||||||
|
) : (
|
||||||
|
<PaperIcon />
|
||||||
|
)}
|
||||||
|
<span>{result.title}</span>
|
||||||
|
</StyledListItem>
|
||||||
|
</Command.Item>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Command.Group>
|
||||||
|
) : (
|
||||||
|
<StyledNotFound>
|
||||||
|
<span>{t('Find 0 result')}</span>
|
||||||
|
<NoResultSVG />
|
||||||
|
</StyledNotFound>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -13,7 +13,8 @@ import { Command } from 'cmdk';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useModal } from '@/providers/GlobalModalProvider';
|
import { useModal } from '@/providers/GlobalModalProvider';
|
||||||
import { getUaHelper } from '@/utils';
|
import { getUaHelper } from '@/utils';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
import { useRouter } from 'next/router';
|
||||||
|
import { PublishedResults } from './PublishedResults';
|
||||||
type TransitionsModalProps = {
|
type TransitionsModalProps = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -22,10 +23,11 @@ const isMac = () => {
|
|||||||
return getUaHelper().isMacOs;
|
return getUaHelper().isMacOs;
|
||||||
};
|
};
|
||||||
export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||||
const { currentWorkspace } = useAppState();
|
const router = useRouter();
|
||||||
|
|
||||||
const [query, setQuery] = useState('');
|
const [query, setQuery] = useState('');
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [isPublic, setIsPublic] = useState(false);
|
||||||
|
const [publishWorkspaceName, setPublishWorkspaceName] = useState('');
|
||||||
const [showCreatePage, setShowCreatePage] = useState(true);
|
const [showCreatePage, setShowCreatePage] = useState(true);
|
||||||
const { triggerQuickSearchModal } = useModal();
|
const { triggerQuickSearchModal } = useModal();
|
||||||
|
|
||||||
@@ -51,6 +53,17 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
|||||||
document.removeEventListener('keydown', down, { capture: true });
|
document.removeEventListener('keydown', down, { capture: true });
|
||||||
}, [open, triggerQuickSearchModal]);
|
}, [open, triggerQuickSearchModal]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
router.pathname === '/public-workspace/[workspaceId]/[pageId]' ||
|
||||||
|
router.pathname === '/public-workspace/[workspaceId]'
|
||||||
|
) {
|
||||||
|
return setIsPublic(true);
|
||||||
|
} else {
|
||||||
|
return setIsPublic(false);
|
||||||
|
}
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={open}
|
open={open}
|
||||||
@@ -81,28 +94,44 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StyledModalHeader>
|
<StyledModalHeader>
|
||||||
<Input query={query} setQuery={setQuery} setLoading={setLoading} />
|
<Input
|
||||||
|
query={query}
|
||||||
|
setQuery={setQuery}
|
||||||
|
setLoading={setLoading}
|
||||||
|
isPublic={isPublic}
|
||||||
|
publishWorkspaceName={publishWorkspaceName}
|
||||||
|
/>
|
||||||
<StyledShortcut>{isMac() ? '⌘ + K' : 'Ctrl + K'}</StyledShortcut>
|
<StyledShortcut>{isMac() ? '⌘ + K' : 'Ctrl + K'}</StyledShortcut>
|
||||||
</StyledModalHeader>
|
</StyledModalHeader>
|
||||||
<StyledModalDivider />
|
<StyledModalDivider />
|
||||||
<Command.List>
|
<Command.List>
|
||||||
<StyledContent>
|
<StyledContent>
|
||||||
<Results
|
{!isPublic ? (
|
||||||
query={query}
|
<Results
|
||||||
loading={loading}
|
query={query}
|
||||||
setLoading={setLoading}
|
loading={loading}
|
||||||
setShowCreatePage={setShowCreatePage}
|
setLoading={setLoading}
|
||||||
/>
|
setShowCreatePage={setShowCreatePage}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<PublishedResults
|
||||||
|
query={query}
|
||||||
|
loading={loading}
|
||||||
|
setLoading={setLoading}
|
||||||
|
onClose={onClose}
|
||||||
|
setPublishWorkspaceName={setPublishWorkspaceName}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</StyledContent>
|
</StyledContent>
|
||||||
{currentWorkspace?.published ? (
|
{!isPublic ? (
|
||||||
<></>
|
showCreatePage ? (
|
||||||
) : showCreatePage ? (
|
<>
|
||||||
<>
|
<StyledModalDivider />
|
||||||
<StyledModalDivider />
|
<StyledModalFooter>
|
||||||
<StyledModalFooter>
|
<Footer query={query} />
|
||||||
<Footer query={query} />
|
</StyledModalFooter>
|
||||||
</StyledModalFooter>
|
</>
|
||||||
</>
|
) : null
|
||||||
) : null}
|
) : null}
|
||||||
</Command.List>
|
</Command.List>
|
||||||
</Command>
|
</Command>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { uuidv4 } from '@blocksuite/store';
|
import { uuidv4, Workspace } from '@blocksuite/store';
|
||||||
import { QueryContent } from '@blocksuite/store/dist/workspace/search';
|
import { QueryContent } from '@blocksuite/store/dist/workspace/search';
|
||||||
import { PageMeta, useAppState } from '@/providers/app-state-provider';
|
import { PageMeta, useAppState } from '@/providers/app-state-provider';
|
||||||
import { EditorContainer } from '@blocksuite/editor';
|
import { EditorContainer } from '@blocksuite/editor';
|
||||||
@@ -20,7 +20,10 @@ export type EditorHandlers = {
|
|||||||
toggleDeletePage: (pageId: string) => Promise<boolean>;
|
toggleDeletePage: (pageId: string) => Promise<boolean>;
|
||||||
toggleFavoritePage: (pageId: string) => Promise<boolean>;
|
toggleFavoritePage: (pageId: string) => Promise<boolean>;
|
||||||
permanentlyDeletePage: (pageId: string) => void;
|
permanentlyDeletePage: (pageId: string) => void;
|
||||||
search: (query: QueryContent) => Map<string, string | undefined>;
|
search: (
|
||||||
|
query: QueryContent,
|
||||||
|
workspace?: Workspace
|
||||||
|
) => Map<string, string | undefined>;
|
||||||
// changeEditorMode: (pageId: string) => void;
|
// changeEditorMode: (pageId: string) => void;
|
||||||
changePageMode: (
|
changePageMode: (
|
||||||
pageId: string,
|
pageId: string,
|
||||||
@@ -83,9 +86,16 @@ export const usePageHelper = (): EditorHandlers => {
|
|||||||
});
|
});
|
||||||
return trash;
|
return trash;
|
||||||
},
|
},
|
||||||
search: (query: QueryContent) => {
|
search: (query: QueryContent, workspace?: Workspace) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
if (workspace) {
|
||||||
return currentWorkspace!.blocksuiteWorkspace!.search(query);
|
return workspace.search(query);
|
||||||
|
}
|
||||||
|
if (currentWorkspace) {
|
||||||
|
if (currentWorkspace.blocksuiteWorkspace) {
|
||||||
|
return currentWorkspace.blocksuiteWorkspace.search(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Map();
|
||||||
},
|
},
|
||||||
changePageMode: async (pageId, mode) => {
|
changePageMode: async (pageId, mode) => {
|
||||||
const pageMeta = getPageMeta(currentWorkspace, pageId);
|
const pageMeta = getPageMeta(currentWorkspace, pageId);
|
||||||
|
|||||||
Reference in New Issue
Block a user