fix: modify with new blocksuite version about subpage (#2060)

This commit is contained in:
Qi
2023-04-21 16:34:32 +08:00
committed by GitHub
parent 5a124831b8
commit 9ec6768272
18 changed files with 175 additions and 405 deletions
@@ -1,235 +0,0 @@
/**
* @vitest-environment happy-dom
*/
import 'fake-indexeddb/auto';
import { rootCurrentWorkspaceIdAtom } from '@affine/workspace/atom';
import matchers from '@testing-library/jest-dom/matchers';
import type { RenderResult } from '@testing-library/react';
import { render, renderHook } from '@testing-library/react';
import { createStore, getDefaultStore, Provider } from 'jotai';
import type { FC, PropsWithChildren } from 'react';
import { beforeEach, describe, expect, test } from 'vitest';
import { workspacesAtom } from '../../atoms';
import { rootCurrentWorkspaceAtom } from '../../atoms/root';
import { useCurrentWorkspace } from '../../hooks/current/use-current-workspace';
import { useAppHelper } from '../../hooks/use-workspaces';
import { ThemeProvider } from '../../providers/ThemeProvider';
import type { BlockSuiteWorkspace } from '../../shared';
import type { PinboardProps } from '../pure/workspace-slider-bar/Pinboard';
import Pinboard from '../pure/workspace-slider-bar/Pinboard';
expect.extend(matchers);
let store = getDefaultStore();
beforeEach(async () => {
store = createStore();
await store.get(workspacesAtom);
});
const ProviderWrapper: FC<PropsWithChildren> = ({ children }) => {
return <Provider store={store}>{children}</Provider>;
};
const initPinBoard = async () => {
// create one workspace with 2 root pages and 2 pinboard pages
// - hasPinboardPage
// - hasPinboardPage
// - pinboard1
// - pinboard2
// - noPinboardPage
const mutationHook = renderHook(() => useAppHelper(), {
wrapper: ProviderWrapper,
});
const rootPageIds = ['hasPinboardPage', 'noPinboardPage'];
const pinboardPageIds = ['pinboard1', 'pinboard2'];
const id = await mutationHook.result.current.createLocalWorkspace('test0');
store.set(rootCurrentWorkspaceIdAtom, id);
await store.get(workspacesAtom);
await store.get(rootCurrentWorkspaceAtom);
const currentWorkspaceHook = renderHook(() => useCurrentWorkspace(), {
wrapper: ProviderWrapper,
});
currentWorkspaceHook.result.current[1](id);
const currentWorkspace = await store.get(rootCurrentWorkspaceAtom);
const blockSuiteWorkspace =
currentWorkspace?.blockSuiteWorkspace as BlockSuiteWorkspace;
mutationHook.rerender();
// create root pinboard
mutationHook.result.current.createWorkspacePage(id, 'rootPinboard');
blockSuiteWorkspace.meta.setPageMeta('rootPinboard', {
isRootPinboard: true,
subpageIds: rootPageIds,
});
// create parent
rootPageIds.forEach(rootPageId => {
mutationHook.result.current.createWorkspacePage(id, rootPageId);
blockSuiteWorkspace.meta.setPageMeta(rootPageId, {
subpageIds: rootPageId === rootPageIds[0] ? pinboardPageIds : [],
});
});
// create children to first parent
pinboardPageIds.forEach(pinboardId => {
mutationHook.result.current.createWorkspacePage(id, pinboardId);
blockSuiteWorkspace.meta.setPageMeta(pinboardId, {
title: pinboardId,
});
});
const App = (props: PinboardProps) => {
return (
<ThemeProvider>
<ProviderWrapper>
<Pinboard {...props} />
</ProviderWrapper>
</ThemeProvider>
);
};
const app = render(
<App
blockSuiteWorkspace={blockSuiteWorkspace as BlockSuiteWorkspace}
openPage={() => {}}
/>
);
return {
rootPageIds,
pinboardPageIds,
app,
blockSuiteWorkspace,
};
};
const openOperationMenu = async (app: RenderResult, pageId: string) => {
const rootPinboard = await app.findByTestId(`pinboard-${pageId}`);
const operationBtn = (await rootPinboard.querySelector(
'[data-testid="pinboard-operation-button"]'
)) as HTMLElement;
await operationBtn.click();
const menu = await app.findByTestId('pinboard-operation-menu');
expect(menu).toBeInTheDocument();
};
describe('PinBoard', () => {
test('add pinboard', async () => {
const { app, blockSuiteWorkspace, rootPageIds } = await initPinBoard();
const [hasChildrenPageId] = rootPageIds;
await openOperationMenu(app, hasChildrenPageId);
const addBtn = await app.findByTestId('pinboard-operation-add');
await addBtn.click();
const hasChildrenPageMeta =
blockSuiteWorkspace.meta.getPageMeta(hasChildrenPageId);
// Page meta have been added
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(6);
// New page meta is added in initial page meta
expect(hasChildrenPageMeta?.subpageIds.length).toBe(3);
app.unmount();
});
test('delete pinboard', async () => {
const {
app,
blockSuiteWorkspace,
rootPageIds: [hasChildrenPageId],
} = await initPinBoard();
await openOperationMenu(app, hasChildrenPageId);
const deleteBtn = await app.findByTestId(
'pinboard-operation-move-to-trash'
);
await deleteBtn.click();
const confirmBtn = await app.findByTestId('move-to-trash-confirm');
expect(confirmBtn).toBeInTheDocument();
await confirmBtn.click();
// Every page should be tagged as trash
expect(blockSuiteWorkspace.meta.pageMetas.filter(m => m.trash).length).toBe(
3
);
app.unmount();
});
test('rename pinboard', async () => {
const {
app,
rootPageIds: [hasChildrenPageId],
} = await initPinBoard();
await openOperationMenu(app, hasChildrenPageId);
const renameBtn = await app.findByTestId('pinboard-operation-rename');
await renameBtn.click();
const input = await app.findByTestId(`pinboard-input-${hasChildrenPageId}`);
expect(input).toBeInTheDocument();
// TODO: Fix this test
// fireEvent.change(input, { target: { value: 'tteesstt' } });
// expect(
// blockSuiteWorkspace.meta.getPageMeta(hasChildrenPageId)?.name
// ).toBe('tteesstt');
app.unmount();
});
test('move pinboard', async () => {
const {
app,
blockSuiteWorkspace,
rootPageIds: [hasChildrenPageId],
pinboardPageIds: [pinboardId1, pinboardId2],
} = await initPinBoard();
await openOperationMenu(app, pinboardId1);
const moveToBtn = await app.findByTestId('pinboard-operation-move-to');
await moveToBtn.click();
const pinboardMenu = await app.findByTestId('pinboard-menu');
expect(pinboardMenu).toBeInTheDocument();
await (
pinboardMenu.querySelector(
`[data-testid="pinboard-${pinboardId2}"]`
) as HTMLElement
).click();
const hasChildrenPageMeta =
blockSuiteWorkspace.meta.getPageMeta(hasChildrenPageId);
expect(hasChildrenPageMeta?.subpageIds.includes(pinboardId1)).toBe(false);
expect(hasChildrenPageMeta?.subpageIds.includes(pinboardId2)).toBe(true);
app.unmount();
});
test('remove from pinboard', async () => {
const {
app,
blockSuiteWorkspace,
rootPageIds: [hasChildrenPageId],
pinboardPageIds: [pinboardId1],
} = await initPinBoard();
await openOperationMenu(app, pinboardId1);
const moveToBtn = await app.findByTestId('pinboard-operation-move-to');
await moveToBtn.click();
const removeFromPinboardBtn = await app.findByTestId(
'remove-from-pinboard-button'
);
removeFromPinboardBtn.click();
const hasPinboardPageMeta =
blockSuiteWorkspace.meta.getPageMeta(hasChildrenPageId);
expect(hasPinboardPageMeta?.subpageIds.length).toBe(1);
expect(hasPinboardPageMeta?.subpageIds.includes(pinboardId1)).toBe(false);
app.unmount();
});
});
@@ -3,9 +3,9 @@ import { Input, PureMenu, TreeView } from '@affine/component';
import { useTranslation } from '@affine/i18n';
import { RemoveIcon, SearchIcon } from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store';
import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta';
import React, { useCallback, useMemo, useState } from 'react';
import { useReferenceLinkHelper } from '../../../../hooks/affine/use-reference-link-helper';
import { usePinboardData } from '../../../../hooks/use-pinboard-data';
import { usePinboardHandler } from '../../../../hooks/use-pinboard-handler';
import type { BlockSuiteWorkspace } from '../../../../shared';
@@ -41,13 +41,13 @@ export const PinboardMenu = ({
[currentMeta.id, propsMetas]
);
const { t } = useTranslation();
const { setPageMeta } = usePageMetaHelper(blockSuiteWorkspace);
const [query, setQuery] = useState('');
const isSearching = query.length > 0;
const searchResult = metas.filter(
meta => !meta.trash && meta.title.includes(query)
);
const { removeReferenceLink } = useReferenceLinkHelper(blockSuiteWorkspace);
const { dropPin } = usePinboardHandler({
blockSuiteWorkspace,
@@ -117,16 +117,7 @@ export const PinboardMenu = ({
<StyledPinboard
data-testid={'remove-from-pinboard-button'}
onClick={() => {
const parentMeta = metas.find(m =>
m.subpageIds.includes(currentMeta.id)
);
if (!parentMeta) return;
const newSubpageIds = [...parentMeta.subpageIds];
const deleteIndex = newSubpageIds.findIndex(
id => id === currentMeta.id
);
newSubpageIds.splice(deleteIndex, 1);
setPageMeta(parentMeta.id, { subpageIds: newSubpageIds });
removeReferenceLink(currentMeta.id);
}}
>
<RemoveIcon />
@@ -0,0 +1,22 @@
import { PlusIcon } from '@blocksuite/icons';
import { StyledOperationButton } from '../styles';
import type { OperationButtonProps } from './OperationButton';
export const AddButton = ({
onAdd,
visible,
}: Pick<OperationButtonProps, 'onAdd' | 'visible'>) => {
return (
<StyledOperationButton
visible={visible}
size="small"
onClick={e => {
e.stopPropagation();
onAdd();
}}
>
<PlusIcon />
</StyledOperationButton>
);
};
@@ -28,7 +28,7 @@ export type OperationButtonProps = {
metas: PageMeta[];
currentMeta: PageMeta;
blockSuiteWorkspace: BlockSuiteWorkspace;
isHover: boolean;
visible: boolean;
onRename?: () => void;
onMenuClose?: () => void;
};
@@ -39,7 +39,7 @@ export const OperationButton = ({
metas,
currentMeta,
blockSuiteWorkspace,
isHover,
visible,
onMenuClose,
onRename,
}: OperationButtonProps) => {
@@ -61,6 +61,7 @@ export const OperationButton = ({
}}
>
<div
style={{ display: 'flex' }}
onClick={e => {
e.stopPropagation();
}}
@@ -81,7 +82,7 @@ export const OperationButton = ({
onClick={() => {
setOperationMenuOpen(!operationMenuOpen);
}}
visible={isHover}
visible={visible}
>
<MoreVerticalIcon />
</StyledOperationButton>
@@ -14,6 +14,7 @@ import { useMemo, useState } from 'react';
import { workspacePreferredModeAtom } from '../../../../atoms';
import type { PinboardNode } from '../../../../hooks/use-pinboard-data';
import { StyledCollapsedButton, StyledPinboard } from '../styles';
import { AddButton } from './AddButton';
import EmptyItem from './EmptyItem';
import { OperationButton } from './OperationButton';
@@ -84,10 +85,8 @@ export const PinboardRender: PinboardNode['render'] = (
<ArrowDownSmallIcon />
</StyledCollapsedButton>
)}
{asPath && !isRoot ? <LevelIcon className="path-icon" /> : null}
{getIcon(isRoot ? 'root' : record[node.id])}
{showRename ? (
<Input
data-testid={`pinboard-input-${node.id}`}
@@ -106,6 +105,7 @@ export const PinboardRender: PinboardNode['render'] = (
) : (
<span>{isRoot ? 'Pinboard' : currentMeta.title || 'Untitled'}</span>
)}
{showOperationButton && <AddButton onAdd={onAdd} visible={isHover} />}
{showOperationButton && (
<OperationButton
@@ -115,7 +115,7 @@ export const PinboardRender: PinboardNode['render'] = (
metas={metas}
currentMeta={currentMeta!}
blockSuiteWorkspace={blockSuiteWorkspace!}
isHover={isHover}
visible={isHover}
onMenuClose={() => setIsHover(false)}
onRename={() => {
setShowRename(true);