mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +00:00
fix: modify with new blocksuite version about subpage (#2060)
This commit is contained in:
@@ -18,11 +18,11 @@
|
||||
"@affine/jotai": "workspace:*",
|
||||
"@affine/templates": "workspace:*",
|
||||
"@affine/workspace": "workspace:*",
|
||||
"@blocksuite/blocks": "0.0.0-20230420160324-857b396c-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230420160324-857b396c-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230420160324-857b396c-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230420210727-85b7de79-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230420210727-85b7de79-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230420210727-85b7de79-nightly",
|
||||
"@blocksuite/icons": "^2.1.10",
|
||||
"@blocksuite/store": "0.0.0-20230420160324-857b396c-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230420210727-85b7de79-nightly",
|
||||
"@dnd-kit/core": "^6.0.8",
|
||||
"@dnd-kit/sortable": "^7.0.2",
|
||||
"@emotion/cache": "^11.10.7",
|
||||
|
||||
@@ -25,7 +25,7 @@ function createPublicWorkspace(
|
||||
);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_block_hub', false);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_set_remote_flag', false);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_database', true);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_database', false);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_edgeless_toolbar', false);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_slash_menu', false);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_drag_handle', false);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -5,11 +5,14 @@ import {
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import type { BlockSuiteWorkspace } from '../../shared';
|
||||
import { useReferenceLinkHelper } from './use-reference-link-helper';
|
||||
|
||||
export function useBlockSuiteMetaHelper(
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace
|
||||
) {
|
||||
const { setPageMeta, getPageMeta } = usePageMetaHelper(blockSuiteWorkspace);
|
||||
const { addReferenceLink, removeReferenceLink } =
|
||||
useReferenceLinkHelper(blockSuiteWorkspace);
|
||||
const metas = useBlockSuitePageMeta(blockSuiteWorkspace);
|
||||
|
||||
const removeToTrash = useCallback(
|
||||
@@ -29,17 +32,10 @@ export function useBlockSuiteMetaHelper(
|
||||
|
||||
// Just the trash root need delete its id from parent
|
||||
if (parentMeta && isRoot) {
|
||||
const deleteIndex = parentMeta.subpageIds.findIndex(
|
||||
id => id === pageId
|
||||
);
|
||||
const newSubpageIds = [...parentMeta.subpageIds];
|
||||
newSubpageIds.splice(deleteIndex, 1);
|
||||
setPageMeta(parentMeta.id, {
|
||||
subpageIds: newSubpageIds,
|
||||
});
|
||||
removeReferenceLink(pageId);
|
||||
}
|
||||
},
|
||||
[getPageMeta, metas, setPageMeta]
|
||||
[getPageMeta, metas, removeReferenceLink, setPageMeta]
|
||||
);
|
||||
|
||||
const restoreFromTrash = useCallback(
|
||||
@@ -47,11 +43,7 @@ export function useBlockSuiteMetaHelper(
|
||||
const { subpageIds = [], trashRelate } = getPageMeta(pageId) ?? {};
|
||||
|
||||
if (trashRelate) {
|
||||
const parentMeta = metas.find(m => m.id === trashRelate);
|
||||
parentMeta &&
|
||||
setPageMeta(parentMeta.id, {
|
||||
subpageIds: [...parentMeta.subpageIds, pageId],
|
||||
});
|
||||
addReferenceLink(trashRelate, pageId);
|
||||
}
|
||||
|
||||
setPageMeta(pageId, {
|
||||
@@ -63,7 +55,7 @@ export function useBlockSuiteMetaHelper(
|
||||
restoreFromTrash(id);
|
||||
});
|
||||
},
|
||||
[getPageMeta, metas, setPageMeta]
|
||||
[addReferenceLink, getPageMeta, setPageMeta]
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
45
apps/web/src/hooks/affine/use-reference-link-helper.ts
Normal file
45
apps/web/src/hooks/affine/use-reference-link-helper.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import type { BlockSuiteWorkspace } from '../../shared';
|
||||
|
||||
export function useReferenceLinkHelper(
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace
|
||||
) {
|
||||
const addReferenceLink = useCallback(
|
||||
(pageId: string, referenceId: string) => {
|
||||
const page = blockSuiteWorkspace?.getPage(pageId);
|
||||
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);
|
||||
},
|
||||
[blockSuiteWorkspace]
|
||||
);
|
||||
const removeReferenceLink = useCallback(
|
||||
(deleteId: string) => {
|
||||
blockSuiteWorkspace.indexer.backlink.removeSubpageNode(
|
||||
blockSuiteWorkspace,
|
||||
deleteId
|
||||
);
|
||||
},
|
||||
[blockSuiteWorkspace]
|
||||
);
|
||||
|
||||
return {
|
||||
addReferenceLink,
|
||||
removeReferenceLink,
|
||||
};
|
||||
}
|
||||
@@ -4,10 +4,11 @@ import type { PageMeta } from '@blocksuite/store';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import type { BlockSuiteWorkspace } from '../shared';
|
||||
import { useBlockSuiteMetaHelper } from './affine/use-block-suite-meta-helper';
|
||||
import { useReferenceLinkHelper } from './affine/use-reference-link-helper';
|
||||
import type { NodeRenderProps } from './use-pinboard-data';
|
||||
|
||||
const logger = new DebugLogger('pinboard');
|
||||
@@ -21,50 +22,32 @@ function findRootIds(metas: PageMeta[], id: string): string[] {
|
||||
}
|
||||
export function usePinboardHandler({
|
||||
blockSuiteWorkspace,
|
||||
metas,
|
||||
metas: propsMetas,
|
||||
onAdd,
|
||||
onDelete,
|
||||
onDrop,
|
||||
}: {
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||
metas: PageMeta[];
|
||||
metas?: PageMeta[];
|
||||
onAdd?: (addedId: string, parentId: string) => void;
|
||||
onDelete?: TreeViewProps<NodeRenderProps>['onDelete'];
|
||||
onDrop?: TreeViewProps<NodeRenderProps>['onDrop'];
|
||||
}) {
|
||||
const metas = useMemo(
|
||||
() => propsMetas || blockSuiteWorkspace.meta.pageMetas || [],
|
||||
[blockSuiteWorkspace.meta.pageMetas, propsMetas]
|
||||
);
|
||||
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
|
||||
const { setPageMeta } = usePageMetaHelper(blockSuiteWorkspace);
|
||||
const { removeToTrash: removeToTrashHelper } =
|
||||
useBlockSuiteMetaHelper(blockSuiteWorkspace);
|
||||
// Just need handle add operation, delete check is handled in blockSuite's reference link
|
||||
const addReferenceLink = useCallback(
|
||||
(pageId: string, referenceId: string) => {
|
||||
const page = blockSuiteWorkspace?.getPage(pageId);
|
||||
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);
|
||||
},
|
||||
[blockSuiteWorkspace]
|
||||
);
|
||||
const { addReferenceLink, removeReferenceLink } =
|
||||
useReferenceLinkHelper(blockSuiteWorkspace);
|
||||
|
||||
const addPin = useCallback(
|
||||
(parentId: string) => {
|
||||
const id = nanoid();
|
||||
createPage(id, parentId);
|
||||
createPage(id);
|
||||
onAdd?.(id, parentId);
|
||||
addReferenceLink(parentId, id);
|
||||
},
|
||||
@@ -127,24 +110,7 @@ export function usePinboardHandler({
|
||||
return onDrop?.(dragId, dropId, position);
|
||||
}
|
||||
// Old parent will delete drag node, new parent will be added
|
||||
const newDragParentSubpageIds = [...(dragParentMeta?.subpageIds ?? [])];
|
||||
const deleteIndex = newDragParentSubpageIds.findIndex(
|
||||
id => id === dragId
|
||||
);
|
||||
newDragParentSubpageIds.splice(deleteIndex, 1);
|
||||
|
||||
const newDropParentSubpageIds = [...(dropParentMeta?.subpageIds ?? [])];
|
||||
const insertIndex =
|
||||
newDropParentSubpageIds.findIndex(id => id === dropId) + insertOffset;
|
||||
newDropParentSubpageIds.splice(insertIndex, 0, dragId);
|
||||
dragParentMeta &&
|
||||
setPageMeta(dragParentMeta.id, {
|
||||
subpageIds: newDragParentSubpageIds,
|
||||
});
|
||||
dropParentMeta &&
|
||||
setPageMeta(dropParentMeta.id, {
|
||||
subpageIds: newDropParentSubpageIds,
|
||||
});
|
||||
removeReferenceLink(dragId);
|
||||
dropParentMeta && addReferenceLink(dropParentMeta.id, dragId);
|
||||
return onDrop?.(dragId, dropId, position);
|
||||
}
|
||||
@@ -154,23 +120,12 @@ export function usePinboardHandler({
|
||||
return;
|
||||
}
|
||||
if (dragParentMeta) {
|
||||
const metaIndex = dragParentMeta.subpageIds.findIndex(
|
||||
id => id === dragId
|
||||
);
|
||||
const newSubpageIds = [...dragParentMeta.subpageIds];
|
||||
newSubpageIds.splice(metaIndex, 1);
|
||||
setPageMeta(dragParentMeta.id, {
|
||||
subpageIds: newSubpageIds,
|
||||
});
|
||||
removeReferenceLink(dragId);
|
||||
}
|
||||
const dropMeta = metas.find(meta => meta.id === dropId)!;
|
||||
const newSubpageIds = [dragId, ...(dropMeta.subpageIds ?? [])];
|
||||
setPageMeta(dropMeta.id, {
|
||||
subpageIds: newSubpageIds,
|
||||
});
|
||||
addReferenceLink(dropMeta.id, dragId);
|
||||
},
|
||||
[addReferenceLink, metas, onDrop, setPageMeta]
|
||||
[addReferenceLink, metas, onDrop, removeReferenceLink, setPageMeta]
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -27,7 +27,7 @@ import type { BlockSuiteWorkspace, NextPageWithLayout } from '../../../shared';
|
||||
|
||||
function enableFullFlags(blockSuiteWorkspace: BlockSuiteWorkspace) {
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_set_remote_flag', false);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_database', true);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_database', false);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_slash_menu', true);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_edgeless_toolbar', true);
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_block_hub', true);
|
||||
|
||||
Reference in New Issue
Block a user