feat: connect pinboard and reference link (#1859)

This commit is contained in:
Qi
2023-04-11 00:49:51 +08:00
committed by GitHub
parent 9acbba7016
commit ea2a146c82
12 changed files with 243 additions and 91 deletions
@@ -45,7 +45,7 @@ export const PinboardMenu = ({
meta => !meta.trash && meta.title.includes(query) meta => !meta.trash && meta.title.includes(query)
); );
const { handleDrop } = usePinboardHandler({ const { dropPin } = usePinboardHandler({
blockSuiteWorkspace, blockSuiteWorkspace,
metas, metas,
}); });
@@ -54,7 +54,7 @@ export const PinboardMenu = ({
(dropId: string) => { (dropId: string) => {
const targetTitle = metas.find(m => m.id === dropId)?.title; const targetTitle = metas.find(m => m.id === dropId)?.title;
handleDrop(currentMeta.id, dropId, { dropPin(currentMeta.id, dropId, {
bottomLine: false, bottomLine: false,
topLine: false, topLine: false,
internal: true, internal: true,
@@ -62,7 +62,7 @@ export const PinboardMenu = ({
onPinboardClick?.({ dragId: currentMeta.id, dropId }); onPinboardClick?.({ dragId: currentMeta.id, dropId });
toast(`Moved "${currentMeta.title}" to "${targetTitle}"`); toast(`Moved "${currentMeta.title}" to "${targetTitle}"`);
}, },
[currentMeta.id, currentMeta.title, handleDrop, metas, onPinboardClick] [currentMeta.id, currentMeta.title, dropPin, metas, onPinboardClick]
); );
const { data } = usePinboardData({ const { data } = usePinboardData({
@@ -80,7 +80,13 @@ export const PageDetailEditor: React.FC<PageDetailEditorProps> = ({
}, },
[onInit, setEditor] [onInit, setEditor]
)} )}
onLoad={onLoad} onLoad={useCallback(
(page: Page, editor: EditorContainer) => {
setEditor(editor);
onLoad?.(page, editor);
},
[onLoad, setEditor]
)}
/> />
</> </>
); );
@@ -41,7 +41,7 @@ export const Pinboard = ({
showOperationButton: true, showOperationButton: true,
}); });
const { handleAdd, handleDelete, handleDrop } = usePinboardHandler({ const { addPin, deletePin, dropPin } = usePinboardHandler({
blockSuiteWorkspace: blockSuiteWorkspace, blockSuiteWorkspace: blockSuiteWorkspace,
metas: allMetas, metas: allMetas,
onAdd, onAdd,
@@ -54,9 +54,9 @@ export const Pinboard = ({
<div data-testid="sidebar-pinboard-container"> <div data-testid="sidebar-pinboard-container">
<TreeView <TreeView
data={data} data={data}
onAdd={handleAdd} onAdd={addPin}
onDelete={handleDelete} onDelete={deletePin}
onDrop={handleDrop} onDrop={dropPin}
indent={16} indent={16}
/> />
</div> </div>
@@ -0,0 +1,42 @@
import { useAtomValue } from 'jotai';
import { useEffect } from 'react';
import { currentEditorAtom } from '../../atoms';
export function useReferenceLink(props?: {
pageLinkClicked?: (params: { pageId: string }) => void;
subpageLinked?: (params: { pageId: string }) => void;
subpageUnlinked?: (params: { pageId: string }) => void;
}) {
const { pageLinkClicked, subpageLinked, subpageUnlinked } = props ?? {};
const editor = useAtomValue(currentEditorAtom);
useEffect(() => {
if (!editor) {
return;
}
const linkClickedDisposable = editor.slots.pageLinkClicked.on(
({ pageId }) => {
pageLinkClicked?.({ pageId });
}
);
const subpageLinkedDisposable = editor.slots.subpageLinked.on(
({ pageId }) => {
subpageLinked?.({ pageId });
}
);
const subpageUnlinkedDisposable = editor.slots.subpageUnlinked.on(
({ pageId }) => {
subpageUnlinked?.({ pageId });
}
);
return () => {
linkClickedDisposable.dispose();
subpageLinkedDisposable.dispose();
subpageUnlinkedDisposable.dispose();
};
}, [editor, pageLinkClicked, subpageLinked, subpageUnlinked]);
}
+49 -20
View File
@@ -7,7 +7,7 @@ import { useCallback } from 'react';
import type { BlockSuiteWorkspace } from '../shared'; import type { BlockSuiteWorkspace } from '../shared';
import { useBlockSuiteWorkspaceHelper } from './use-blocksuite-workspace-helper'; import { useBlockSuiteWorkspaceHelper } from './use-blocksuite-workspace-helper';
import { usePageMetaHelper } from './use-page-meta'; import { usePageMetaHelper } from './use-page-meta';
import type { NodeRenderProps, PinboardNode } from './use-pinboard-data'; import type { NodeRenderProps } from './use-pinboard-data';
const logger = new DebugLogger('pinboard'); const logger = new DebugLogger('pinboard');
@@ -25,7 +25,7 @@ export function usePinboardHandler({
onDelete, onDelete,
onDrop, onDrop,
}: { }: {
blockSuiteWorkspace: BlockSuiteWorkspace; blockSuiteWorkspace: BlockSuiteWorkspace | null;
metas: PageMeta[]; metas: PageMeta[];
onAdd?: (addedId: string, parentId: string) => void; onAdd?: (addedId: string, parentId: string) => void;
onDelete?: TreeViewProps<NodeRenderProps>['onDelete']; onDelete?: TreeViewProps<NodeRenderProps>['onDelete'];
@@ -34,17 +34,43 @@ export function usePinboardHandler({
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace); const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
const { getPageMeta, setPageMeta } = usePageMetaHelper(blockSuiteWorkspace); const { getPageMeta, setPageMeta } = usePageMetaHelper(blockSuiteWorkspace);
const handleAdd = useCallback( // Just need handle add operation, delete check is handled in blockSuite's reference link
(node: PinboardNode) => { const addReferenceLink = useCallback(
const id = nanoid(); (pageId: string, referenceId: string) => {
createPage(id, node.id); const page = blockSuiteWorkspace?.getPage(pageId);
onAdd?.(id, node.id); if (!page) {
return;
}
const text = page.Text.fromDelta([
{
insert: ' ',
attributes: {
reference: {
type: 'Subpage',
pageId: referenceId,
},
},
},
]);
const [frame] = page.getBlockByFlavour('affine:frame');
frame && page.addBlock('affine:paragraph', { text }, frame.id);
}, },
[createPage, onAdd] [blockSuiteWorkspace]
); );
const handleDelete = useCallback( const addPin = useCallback(
(node: PinboardNode) => { (parentId: string) => {
const id = nanoid();
createPage(id, parentId);
onAdd?.(id, parentId);
addReferenceLink(parentId, id);
},
[addReferenceLink, createPage, onAdd]
);
const deletePin = useCallback(
(deleteId: string) => {
const removeToTrash = (currentMeta: PageMeta) => { const removeToTrash = (currentMeta: PageMeta) => {
const { subpageIds = [] } = currentMeta; const { subpageIds = [] } = currentMeta;
setPageMeta(currentMeta.id, { setPageMeta(currentMeta.id, {
@@ -52,17 +78,17 @@ export function usePinboardHandler({
trashDate: +new Date(), trashDate: +new Date(),
}); });
subpageIds.forEach(id => { subpageIds.forEach(id => {
const subcurrentMeta = getPageMeta(id); const subCurrentMeta = getPageMeta(id);
subcurrentMeta && removeToTrash(subcurrentMeta); subCurrentMeta && removeToTrash(subCurrentMeta);
}); });
}; };
removeToTrash(metas.find(m => m.id === node.id)!); removeToTrash(metas.find(m => m.id === deleteId)!);
onDelete?.(node); onDelete?.(deleteId);
}, },
[metas, getPageMeta, onDelete, setPageMeta] [metas, getPageMeta, onDelete, setPageMeta]
); );
const handleDrop = useCallback( const dropPin = useCallback(
( (
dragId: string, dragId: string,
dropId: string, dropId: string,
@@ -96,7 +122,7 @@ export function usePinboardHandler({
const dropParentMeta = metas.find(m => m.subpageIds?.includes(dropId)); const dropParentMeta = metas.find(m => m.subpageIds?.includes(dropId));
if (dropParentMeta?.id === dragParentMeta?.id) { if (dropParentMeta?.id === dragParentMeta?.id) {
// same parent // same parent, resort node
const newSubpageIds = [...(dragParentMeta?.subpageIds ?? [])]; const newSubpageIds = [...(dragParentMeta?.subpageIds ?? [])];
const deleteIndex = newSubpageIds.findIndex(id => id === dragId); const deleteIndex = newSubpageIds.findIndex(id => id === dragId);
newSubpageIds.splice(deleteIndex, 1); newSubpageIds.splice(deleteIndex, 1);
@@ -109,6 +135,7 @@ export function usePinboardHandler({
}); });
return onDrop?.(dragId, dropId, position); return onDrop?.(dragId, dropId, position);
} }
// Old parent will delete drag node, new parent will be added
const newDragParentSubpageIds = [...(dragParentMeta?.subpageIds ?? [])]; const newDragParentSubpageIds = [...(dragParentMeta?.subpageIds ?? [])];
const deleteIndex = newDragParentSubpageIds.findIndex( const deleteIndex = newDragParentSubpageIds.findIndex(
id => id === dragId id => id === dragId
@@ -127,6 +154,7 @@ export function usePinboardHandler({
setPageMeta(dropParentMeta.id, { setPageMeta(dropParentMeta.id, {
subpageIds: newDropParentSubpageIds, subpageIds: newDropParentSubpageIds,
}); });
dropParentMeta && addReferenceLink(dropParentMeta.id, dragId);
return onDrop?.(dragId, dropId, position); return onDrop?.(dragId, dropId, position);
} }
@@ -149,14 +177,15 @@ export function usePinboardHandler({
setPageMeta(dropMeta.id, { setPageMeta(dropMeta.id, {
subpageIds: newSubpageIds, subpageIds: newSubpageIds,
}); });
addReferenceLink(dropMeta.id, dragId);
}, },
[metas, onDrop, setPageMeta] [addReferenceLink, metas, onDrop, setPageMeta]
); );
return { return {
handleDrop, dropPin,
handleAdd, addPin,
handleDelete, deletePin,
}; };
} }
+65 -42
View File
@@ -1,5 +1,5 @@
import type { NextRouter } from 'next/router'; import type { NextRouter } from 'next/router';
import { useMemo } from 'react'; import { useCallback } from 'react';
import type { WorkspaceSubPath } from '../shared'; import type { WorkspaceSubPath } from '../shared';
@@ -9,47 +9,70 @@ export const enum RouteLogic {
} }
export function useRouterHelper(router: NextRouter) { export function useRouterHelper(router: NextRouter) {
return useMemo( const jumpToPage = useCallback(
() => ({ (
jumpToPage: ( workspaceId: string,
workspaceId: string, pageId: string,
pageId: string, logic: RouteLogic = RouteLogic.PUSH
logic: RouteLogic = RouteLogic.PUSH ) => {
) => { return router[logic]({
return router[logic]({ pathname: `/workspace/[workspaceId]/[pageId]`,
pathname: `/workspace/[workspaceId]/[pageId]`, query: {
query: { workspaceId,
workspaceId, pageId,
pageId, },
}, });
}); },
},
jumpToPublicWorkspacePage: (
workspaceId: string,
pageId: string,
logic: RouteLogic = RouteLogic.PUSH
) => {
return router[logic]({
pathname: `/public-workspace/[workspaceId]/[pageId]`,
query: {
workspaceId,
pageId,
},
});
},
jumpToSubPath: (
workspaceId: string,
subPath: WorkspaceSubPath,
logic: RouteLogic = RouteLogic.PUSH
): Promise<boolean> => {
return router[logic]({
pathname: `/workspace/[workspaceId]/${subPath}`,
query: {
workspaceId,
},
});
},
}),
[router] [router]
); );
const jumpToPublicWorkspacePage = useCallback(
(
workspaceId: string,
pageId: string,
logic: RouteLogic = RouteLogic.PUSH
) => {
return router[logic]({
pathname: `/public-workspace/[workspaceId]/[pageId]`,
query: {
workspaceId,
pageId,
},
});
},
[router]
);
const jumpToSubPath = useCallback(
(
workspaceId: string,
subPath: WorkspaceSubPath,
logic: RouteLogic = RouteLogic.PUSH
): Promise<boolean> => {
return router[logic]({
pathname: `/workspace/[workspaceId]/${subPath}`,
query: {
workspaceId,
},
});
},
[router]
);
const openPage = useCallback(
(workspaceId: string, pageId: string) => {
const isPublicWorkspace =
router.pathname.split('/')[1] === 'public-workspace';
if (isPublicWorkspace) {
return jumpToPublicWorkspacePage(workspaceId, pageId);
} else {
return jumpToPage(workspaceId, pageId);
}
},
[jumpToPage, jumpToPublicWorkspacePage, router.pathname]
);
return {
jumpToPage,
jumpToPublicWorkspacePage,
jumpToSubPath,
openPage,
};
} }
+8 -13
View File
@@ -233,7 +233,7 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
} }
}, [currentWorkspace]); }, [currentWorkspace]);
const router = useRouter(); const router = useRouter();
const { jumpToPage, jumpToPublicWorkspacePage } = useRouterHelper(router); const { openPage } = useRouterHelper(router);
const [, setOpenWorkspacesModal] = useAtom(openWorkspacesModalAtom); const [, setOpenWorkspacesModal] = useAtom(openWorkspacesModalAtom);
const helper = useBlockSuiteWorkspaceHelper( const helper = useBlockSuiteWorkspaceHelper(
currentWorkspace?.blockSuiteWorkspace ?? null currentWorkspace?.blockSuiteWorkspace ?? null
@@ -241,17 +241,6 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
const isPublicWorkspace = const isPublicWorkspace =
router.pathname.split('/')[1] === 'public-workspace'; router.pathname.split('/')[1] === 'public-workspace';
const title = useRouterTitle(router); const title = useRouterTitle(router);
const handleOpenPage = useCallback(
(pageId: string) => {
assertExists(currentWorkspace);
if (isPublicWorkspace) {
jumpToPublicWorkspacePage(currentWorkspace.id, pageId);
} else {
jumpToPage(currentWorkspace.id, pageId);
}
},
[currentWorkspace, isPublicWorkspace, jumpToPage, jumpToPublicWorkspacePage]
);
const handleCreatePage = useCallback(() => { const handleCreatePage = useCallback(() => {
return helper.createPage(nanoid()); return helper.createPage(nanoid());
}, [helper]); }, [helper]);
@@ -319,7 +308,13 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
currentWorkspace={currentWorkspace} currentWorkspace={currentWorkspace}
currentPageId={currentPageId} currentPageId={currentPageId}
onOpenWorkspaceListModal={handleOpenWorkspaceListModal} onOpenWorkspaceListModal={handleOpenWorkspaceListModal}
openPage={handleOpenPage} openPage={useCallback(
(pageId: string) => {
assertExists(currentWorkspace);
return openPage(currentWorkspace.id, pageId);
},
[currentWorkspace, openPage]
)}
createPage={handleCreatePage} createPage={handleCreatePage}
currentPath={router.asPath.split('?')[0]} currentPath={router.asPath.split('?')[0]}
paths={isPublicWorkspace ? publicPathGenerator : pathGenerator} paths={isPublicWorkspace ? publicPathGenerator : pathGenerator}
@@ -1,13 +1,14 @@
import { Breadcrumbs, displayFlex, styled } from '@affine/component'; import { Breadcrumbs, displayFlex, styled } from '@affine/component';
import { useTranslation } from '@affine/i18n'; import { useTranslation } from '@affine/i18n';
import { PageIcon } from '@blocksuite/icons'; import { PageIcon } from '@blocksuite/icons';
import { assertExists } from '@blocksuite/store';
import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-blocksuite-workspace-avatar-url'; import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-blocksuite-workspace-avatar-url';
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-blocksuite-workspace-name'; import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-blocksuite-workspace-name';
import { useAtomValue, useSetAtom } from 'jotai'; import { useAtomValue, useSetAtom } from 'jotai';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import type React from 'react'; import type React from 'react';
import { Suspense, useEffect } from 'react'; import { Suspense, useCallback, useEffect } from 'react';
import { import {
publicPageBlockSuiteAtom, publicPageBlockSuiteAtom,
@@ -18,6 +19,8 @@ import { QueryParamError } from '../../../components/affine/affine-error-eoundar
import { PageDetailEditor } from '../../../components/page-detail-editor'; import { PageDetailEditor } from '../../../components/page-detail-editor';
import { WorkspaceAvatar } from '../../../components/pure/footer'; import { WorkspaceAvatar } from '../../../components/pure/footer';
import { PageLoading } from '../../../components/pure/loading'; import { PageLoading } from '../../../components/pure/loading';
import { useReferenceLink } from '../../../hooks/affine/use-reference-link';
import { useRouterHelper } from '../../../hooks/use-router-helper';
import { PublicWorkspaceLayout } from '../../../layouts/public-workspace-layout'; import { PublicWorkspaceLayout } from '../../../layouts/public-workspace-layout';
import type { NextPageWithLayout } from '../../../shared'; import type { NextPageWithLayout } from '../../../shared';
import { initPage } from '../../../utils'; import { initPage } from '../../../utils';
@@ -56,9 +59,21 @@ const PublicWorkspaceDetailPageInner: React.FC<{
if (!blockSuiteWorkspace) { if (!blockSuiteWorkspace) {
throw new Error('cannot find workspace'); throw new Error('cannot find workspace');
} }
const router = useRouter();
const { openPage } = useRouterHelper(router);
useEffect(() => { useEffect(() => {
blockSuiteWorkspace.awarenessStore.setFlag('enable_block_hub', false); blockSuiteWorkspace.awarenessStore.setFlag('enable_block_hub', false);
}, [blockSuiteWorkspace]); }, [blockSuiteWorkspace]);
useReferenceLink({
pageLinkClicked: useCallback(
({ pageId }: { pageId: string }) => {
assertExists(currentWorkspace);
return openPage(blockSuiteWorkspace.id, pageId);
},
[blockSuiteWorkspace.id, openPage]
),
});
const { t } = useTranslation(); const { t } = useTranslation();
const [name] = useBlockSuiteWorkspaceName(blockSuiteWorkspace); const [name] = useBlockSuiteWorkspaceName(blockSuiteWorkspace);
const [avatar] = useBlockSuiteWorkspaceAvatarUrl(blockSuiteWorkspace); const [avatar] = useBlockSuiteWorkspaceAvatarUrl(blockSuiteWorkspace);
@@ -1,13 +1,18 @@
import { WorkspaceFlavour } from '@affine/workspace/type'; import { WorkspaceFlavour } from '@affine/workspace/type';
import { assertExists } from '@blocksuite/store';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import type React from 'react'; import type React from 'react';
import { useEffect } from 'react'; import { useCallback, useEffect } from 'react';
import { Unreachable } from '../../../components/affine/affine-error-eoundary'; import { Unreachable } from '../../../components/affine/affine-error-eoundary';
import { PageLoading } from '../../../components/pure/loading'; import { PageLoading } from '../../../components/pure/loading';
import { useReferenceLink } from '../../../hooks/affine/use-reference-link';
import { useCurrentPageId } from '../../../hooks/current/use-current-page-id'; import { useCurrentPageId } from '../../../hooks/current/use-current-page-id';
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
import { usePageMeta } from '../../../hooks/use-page-meta';
import { usePinboardHandler } from '../../../hooks/use-pinboard-handler';
import { useSyncRecentViewsWithRouter } from '../../../hooks/use-recent-views'; import { useSyncRecentViewsWithRouter } from '../../../hooks/use-recent-views';
import { useRouterHelper } from '../../../hooks/use-router-helper';
import { useSyncRouterWithCurrentWorkspaceAndPage } from '../../../hooks/use-sync-router-with-current-workspace-and-page'; import { useSyncRouterWithCurrentWorkspaceAndPage } from '../../../hooks/use-sync-router-with-current-workspace-and-page';
import { WorkspaceLayout } from '../../../layouts'; import { WorkspaceLayout } from '../../../layouts';
import { WorkspacePlugins } from '../../../plugins'; import { WorkspacePlugins } from '../../../plugins';
@@ -21,12 +26,37 @@ function enableFullFlags(blockSuiteWorkspace: BlockSuiteWorkspace) {
blockSuiteWorkspace.awarenessStore.setFlag('enable_block_hub', true); blockSuiteWorkspace.awarenessStore.setFlag('enable_block_hub', true);
blockSuiteWorkspace.awarenessStore.setFlag('enable_drag_handle', true); blockSuiteWorkspace.awarenessStore.setFlag('enable_drag_handle', true);
blockSuiteWorkspace.awarenessStore.setFlag('enable_surface', true); blockSuiteWorkspace.awarenessStore.setFlag('enable_surface', true);
blockSuiteWorkspace.awarenessStore.setFlag('enable_linked_page', true);
} }
const WorkspaceDetail: React.FC = () => { const WorkspaceDetail: React.FC = () => {
const router = useRouter();
const { openPage } = useRouterHelper(router);
const [pageId] = useCurrentPageId(); const [pageId] = useCurrentPageId();
const [currentWorkspace] = useCurrentWorkspace(); const [currentWorkspace] = useCurrentWorkspace();
useSyncRecentViewsWithRouter(useRouter());
const { deletePin } = usePinboardHandler({
blockSuiteWorkspace: currentWorkspace?.blockSuiteWorkspace ?? null,
metas: usePageMeta(currentWorkspace?.blockSuiteWorkspace ?? null ?? null),
});
useSyncRecentViewsWithRouter(router);
useReferenceLink({
pageLinkClicked: useCallback(
({ pageId }: { pageId: string }) => {
assertExists(currentWorkspace);
return openPage(currentWorkspace.id, pageId);
},
[currentWorkspace, openPage]
),
subpageUnlinked: useCallback(
({ pageId }: { pageId: string }) => {
deletePin(pageId);
},
[deletePin]
),
});
useEffect(() => { useEffect(() => {
if (currentWorkspace) { if (currentWorkspace) {
enableFullFlags(currentWorkspace.blockSuiteWorkspace); enableFullFlags(currentWorkspace.blockSuiteWorkspace);
@@ -110,8 +110,8 @@ const TreeNodeItem = <RenderProps,>({
<div ref={dropRef}> <div ref={dropRef}>
{node.render?.(node, { {node.render?.(node, {
isOver: isOver && canDrop, isOver: isOver && canDrop,
onAdd: () => onAdd?.(node), onAdd: () => onAdd?.(node.id),
onDelete: () => onDelete?.(node), onDelete: () => onDelete?.(node.id),
collapsed, collapsed,
setCollapsed, setCollapsed,
isSelected: selectedId === node.id, isSelected: selectedId === node.id,
+2 -2
View File
@@ -34,8 +34,8 @@ type CommonProps<RenderProps = unknown> = {
enableDnd?: boolean; enableDnd?: boolean;
enableKeyboardSelection?: boolean; enableKeyboardSelection?: boolean;
indent?: CSSProperties['paddingLeft']; indent?: CSSProperties['paddingLeft'];
onAdd?: (node: Node<RenderProps>) => void; onAdd?: (parentId: string) => void;
onDelete?: (node: Node<RenderProps>) => void; onDelete?: (deleteId: string) => void;
onDrop?: OnDrop; onDrop?: OnDrop;
// Only trigger when the enableKeyboardSelection is true // Only trigger when the enableKeyboardSelection is true
onSelect?: (id: string) => void; onSelect?: (id: string) => void;
+13 -1
View File
@@ -34,6 +34,16 @@ async function openPinboardPageOperationMenu(page: Page, id: string) {
await node.getByTestId('pinboard-operation-button').click(); await node.getByTestId('pinboard-operation-button').click();
} }
async function checkIsChildInsertToParentInEditor(page: Page, pageId: string) {
await page
.getByTestId('sidebar-pinboard-container')
.getByTestId(`pinboard-${pageId}`)
.click();
await page.waitForTimeout(200);
const referenceLink = await page.locator('.affine-reference');
expect(referenceLink).not.toBeNull();
}
test.describe('PinBoard interaction', () => { test.describe('PinBoard interaction', () => {
test('Have initial root pinboard page when first in', async ({ page }) => { test('Have initial root pinboard page when first in', async ({ page }) => {
const rootPinboardMeta = await initHomePageWithPinboard(page); const rootPinboardMeta = await initHomePageWithPinboard(page);
@@ -77,6 +87,7 @@ test.describe('PinBoard interaction', () => {
.getByTestId('[data-testid="sidebar-pinboard-container"]') .getByTestId('[data-testid="sidebar-pinboard-container"]')
.getByTestId(`pinboard-${meta?.id}`) .getByTestId(`pinboard-${meta?.id}`)
).not.toBeNull(); ).not.toBeNull();
await checkIsChildInsertToParentInEditor(page, rootPinboardMeta?.id ?? '');
}); });
test('Add pinboard by sidebar operation menu', async ({ page }) => { test('Add pinboard by sidebar operation menu', async ({ page }) => {
@@ -92,6 +103,8 @@ test.describe('PinBoard interaction', () => {
.getByTestId('sidebar-pinboard-container') .getByTestId('sidebar-pinboard-container')
.getByTestId(`pinboard-${newPageMeta?.id}`) .getByTestId(`pinboard-${newPageMeta?.id}`)
).not.toBeNull(); ).not.toBeNull();
console.log('rootPinboardMeta', rootPinboardMeta);
await checkIsChildInsertToParentInEditor(page, rootPinboardMeta?.id ?? '');
}); });
test('Move pinboard to another in sidebar', async ({ page }) => { test('Move pinboard to another in sidebar', async ({ page }) => {
@@ -116,7 +129,6 @@ test.describe('PinBoard interaction', () => {
await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1'); await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1');
await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test2'); await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test2');
const childMeta = (await getMetas(page)).find(m => m.title === 'test1'); const childMeta = (await getMetas(page)).find(m => m.title === 'test1');
const childMeta2 = (await getMetas(page)).find(m => m.title === 'test2');
await page.getByTestId('all-pages').click(); await page.getByTestId('all-pages').click();
await page await page