) => {
return (
@@ -115,6 +116,7 @@ const TreeNodeItem = ({
collapsed,
setCollapsed,
isSelected: selectedId === node.id,
+ disableCollapse,
})}
);
diff --git a/packages/component/src/ui/tree-view/TreeView.tsx b/packages/component/src/ui/tree-view/TreeView.tsx
index 61c87c780e..3db4bc4254 100644
--- a/packages/component/src/ui/tree-view/TreeView.tsx
+++ b/packages/component/src/ui/tree-view/TreeView.tsx
@@ -12,6 +12,7 @@ export const TreeView = ({
onSelect,
enableDnd = true,
initialCollapsedIds = [],
+ disableCollapse,
...otherProps
}: TreeViewProps) => {
const [selectedId, setSelectedId] = useState();
@@ -62,6 +63,9 @@ export const TreeView = ({
}, [data, selectedId]);
const setCollapsed: TreeNodeProps['setCollapsed'] = (id, collapsed) => {
+ if (disableCollapse) {
+ return;
+ }
if (collapsed) {
setCollapsedIds(ids => [...ids, id]);
} else {
@@ -81,6 +85,7 @@ export const TreeView = ({
node={node}
selectedId={selectedId}
enableDnd={enableDnd}
+ disableCollapse={disableCollapse}
{...otherProps}
/>
))}
@@ -99,6 +104,7 @@ export const TreeView = ({
node={node}
selectedId={selectedId}
enableDnd={enableDnd}
+ disableCollapse={disableCollapse}
{...otherProps}
/>
))}
diff --git a/packages/component/src/ui/tree-view/types.ts b/packages/component/src/ui/tree-view/types.ts
index 1b2be07962..4801ecb39c 100644
--- a/packages/component/src/ui/tree-view/types.ts
+++ b/packages/component/src/ui/tree-view/types.ts
@@ -23,6 +23,7 @@ export type Node = {
collapsed: boolean;
setCollapsed: (id: string, collapsed: boolean) => void;
isSelected: boolean;
+ disableCollapse?: ReactNode;
},
renderProps?: RenderProps
) => ReactNode;
@@ -39,6 +40,7 @@ type CommonProps = {
onDrop?: OnDrop;
// Only trigger when the enableKeyboardSelection is true
onSelect?: (id: string) => void;
+ disableCollapse?: ReactNode;
};
export type TreeNodeProps = {
@@ -65,6 +67,7 @@ export type TreeNodeItemProps = {
export type TreeViewProps = {
data: Node[];
initialCollapsedIds?: string[];
+ disableCollapse?: boolean;
} & CommonProps;
export type NodeLIneProps = {
diff --git a/packages/i18n/src/resources/en.json b/packages/i18n/src/resources/en.json
index 31b0fd7811..a63ccb5726 100644
--- a/packages/i18n/src/resources/en.json
+++ b/packages/i18n/src/resources/en.json
@@ -201,5 +201,8 @@
"Move page to...": "Move page to...",
"Remove from Pivots": "Remove from Pivots",
"RFP": "Pages can be freely added/removed from pivots, remaining accessible from \"All Pages\".",
- "Discover what's new!": "Discover what's new!"
+ "Discover what's new!": "Discover what's new!",
+ "Navigation Path": "Navigation Path",
+ "View Navigation Path": "View Navigation Path",
+ "Back to Quick Search": "Back to Quick Search"
}
diff --git a/tests/libs/load-page.ts b/tests/libs/load-page.ts
index b999d80156..cd066c33c4 100644
--- a/tests/libs/load-page.ts
+++ b/tests/libs/load-page.ts
@@ -1,6 +1,14 @@
import type { Page } from '@playwright/test';
+import { getMetas } from './utils';
+
export async function openHomePage(page: Page) {
await page.goto('http://localhost:8080');
await page.waitForSelector('#__next');
}
+
+export async function initHomePageWithPinboard(page: Page) {
+ await openHomePage(page);
+ await page.waitForSelector('[data-testid="sidebar-pinboard-container"]');
+ return (await getMetas(page)).find(m => m.isRootPinboard);
+}
diff --git a/tests/libs/page-logic.ts b/tests/libs/page-logic.ts
index 902151ad59..877e65169f 100644
--- a/tests/libs/page-logic.ts
+++ b/tests/libs/page-logic.ts
@@ -27,3 +27,21 @@ export async function clickPageMoreActions(page: Page) {
.getByTestId('editor-option-menu')
.click();
}
+
+export async function createPinboardPage(
+ page: Page,
+ parentId: string,
+ title: string
+) {
+ await newPage(page);
+ await page.focus('.affine-default-page-block-title');
+ await page.type('.affine-default-page-block-title', title, {
+ delay: 100,
+ });
+ await clickPageMoreActions(page);
+ await page.getByTestId('move-to-menu-item').click();
+ await page
+ .getByTestId('pinboard-menu')
+ .getByTestId(`pinboard-${parentId}`)
+ .click();
+}
diff --git a/tests/parallels/pin-board.spec.ts b/tests/parallels/pin-board.spec.ts
index 6558f326e8..0dc2c5f12a 100644
--- a/tests/parallels/pin-board.spec.ts
+++ b/tests/parallels/pin-board.spec.ts
@@ -1,31 +1,11 @@
import type { Page } from '@playwright/test';
import { expect } from '@playwright/test';
-import { openHomePage } from '../libs/load-page';
-import { clickPageMoreActions, newPage } from '../libs/page-logic';
+import { initHomePageWithPinboard } from '../libs/load-page';
+import { createPinboardPage } from '../libs/page-logic';
import { test } from '../libs/playwright';
import { getMetas } from '../libs/utils';
-async function createPinboardPage(page: Page, parentId: string, title: string) {
- await newPage(page);
- await page.focus('.affine-default-page-block-title');
- await page.type('.affine-default-page-block-title', title, {
- delay: 100,
- });
- await clickPageMoreActions(page);
- await page.getByTestId('move-to-menu-item').click();
- await page
- .getByTestId('pinboard-menu')
- .getByTestId(`pinboard-${parentId}`)
- .click();
-}
-
-async function initHomePageWithPinboard(page: Page) {
- await openHomePage(page);
- await page.waitForSelector('[data-testid="sidebar-pinboard-container"]');
- return (await getMetas(page)).find(m => m.isRootPinboard);
-}
-
async function openPinboardPageOperationMenu(page: Page, id: string) {
const node = await page
.getByTestId('sidebar-pinboard-container')
diff --git a/tests/parallels/quick-search.spec.ts b/tests/parallels/quick-search.spec.ts
index 41a77ccfa8..c3881d093e 100644
--- a/tests/parallels/quick-search.spec.ts
+++ b/tests/parallels/quick-search.spec.ts
@@ -1,8 +1,12 @@
import { expect, type Page } from '@playwright/test';
import { withCtrlOrMeta } from '../libs/keyboard';
-import { openHomePage } from '../libs/load-page';
-import { newPage, waitMarkdownImported } from '../libs/page-logic';
+import { initHomePageWithPinboard, openHomePage } from '../libs/load-page';
+import {
+ createPinboardPage,
+ newPage,
+ waitMarkdownImported,
+} from '../libs/page-logic';
import { test } from '../libs/playwright';
const openQuickSearchByShortcut = async (page: Page) =>
@@ -204,4 +208,54 @@ test.describe('Novice guidance for quick search', () => {
await page.getByTestId('sliderBar-arrowButton-collapse').click();
await expect(quickSearchTips).not.toBeVisible();
});
+
+ test('Show navigation path if page is a subpage', async ({ page }) => {
+ const rootPinboardMeta = await initHomePageWithPinboard(page);
+ await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1');
+ await openQuickSearchByShortcut(page);
+ expect(await page.getByTestId('navigation-path').count()).toBe(1);
+ });
+ test('Not show navigation path if page is not a subpage or current page is not in editor', async ({
+ page,
+ }) => {
+ await openHomePage(page);
+ await waitMarkdownImported(page);
+ await openQuickSearchByShortcut(page);
+ expect(await page.getByTestId('navigation-path').count()).toBe(0);
+ });
+ test('Navigation path item click will jump to page, but not current active item', async ({
+ page,
+ }) => {
+ const rootPinboardMeta = await initHomePageWithPinboard(page);
+ await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1');
+ await openQuickSearchByShortcut(page);
+ const oldUrl = page.url();
+ expect(
+ await page.locator('[data-testid="navigation-path-link"]').count()
+ ).toBe(2);
+ await page.locator('[data-testid="navigation-path-link"]').nth(1).click();
+ expect(page.url()).toBe(oldUrl);
+ await page.locator('[data-testid="navigation-path-link"]').nth(0).click();
+ expect(page.url()).not.toBe(oldUrl);
+ });
+ test('Navigation path expand', async ({ page }) => {
+ //
+ const rootPinboardMeta = await initHomePageWithPinboard(page);
+ await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1');
+ await openQuickSearchByShortcut(page);
+ const top = await page
+ .getByTestId('navigation-path-expand-panel')
+ .evaluate(el => {
+ return window.getComputedStyle(el).getPropertyValue('top');
+ });
+ expect(parseInt(top)).toBeLessThan(0);
+ await page.getByTestId('navigation-path-expand-btn').click();
+ await page.waitForTimeout(500);
+ const expandTop = await page
+ .getByTestId('navigation-path-expand-panel')
+ .evaluate(el => {
+ return window.getComputedStyle(el).getPropertyValue('top');
+ });
+ expect(expandTop).toBe('0px');
+ });
});