diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/FolderItem.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/FolderItem.hooks.ts
deleted file mode 100644
index c08e4d3691..0000000000
--- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/FolderItem.hooks.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-import { foldersActions, IFolder } from '$app_reducers/folders/slice';
-import { useEffect, useState } from 'react';
-import { useAppDispatch, useAppSelector } from '$app/stores/store';
-import { IPage, pagesActions } from '$app_reducers/pages/slice';
-import { ViewLayoutPB } from '@/services/backend';
-import { AppBackendService } from '$app/stores/effects/folder/app/app_bd_svc';
-import { WorkspaceBackendService } from '$app/stores/effects/folder/workspace/workspace_bd_svc';
-
-import { AppObserver } from '$app/stores/effects/folder/app/app_observer';
-import { useNavigate } from 'react-router-dom';
-import { INITIAL_FOLDER_HEIGHT, PAGE_ITEM_HEIGHT } from '../../_shared/constants';
-
-export const useFolderEvents = (folder: IFolder, pages: IPage[]) => {
- const appDispatch = useAppDispatch();
- const workspace = useAppSelector((state) => state.workspace);
-
- const navigate = useNavigate();
-
- // Actions
- const [showPages, setShowPages] = useState(false);
- const [showFolderOptions, setShowFolderOptions] = useState(false);
- const [showNewPageOptions, setShowNewPageOptions] = useState(false);
- const [showRenamePopup, setShowRenamePopup] = useState(false);
-
- // UI configurations
- const [folderHeight, setFolderHeight] = useState(`${INITIAL_FOLDER_HEIGHT}px`);
-
- // Observers
- const appObserver = new AppObserver(folder.id);
-
- // Backend services
- const appBackendService = new AppBackendService(folder.id);
-
- useEffect(() => {
- void appObserver.subscribe({
- onViewsChanged: async () => {
- const result = await appBackendService.getAllViews();
- if (!result.ok) return;
- const views = result.val;
- const updatedPages: IPage[] = views.map((view) => ({
- id: view.id,
- folderId: view.parent_view_id,
- pageType: view.layout,
- title: view.name,
- }));
- appDispatch(pagesActions.didReceivePages({ pages: updatedPages, folderId: folder.id }));
- },
- });
- return () => {
- // Unsubscribe when the component is unmounted.
- void appObserver.unsubscribe();
- };
- }, []);
-
- useEffect(() => {
- if (showPages) {
- setFolderHeight(`${INITIAL_FOLDER_HEIGHT + pages.length * PAGE_ITEM_HEIGHT}px`);
- }
- }, [pages]);
-
- const onFolderNameClick = () => {
- if (showPages) {
- setFolderHeight(`${INITIAL_FOLDER_HEIGHT}px`);
- } else {
- setFolderHeight(`${INITIAL_FOLDER_HEIGHT + pages.length * PAGE_ITEM_HEIGHT}px`);
- }
- setShowPages(!showPages);
- };
-
- const onFolderOptionsClick = () => {
- setShowFolderOptions(!showFolderOptions);
- };
-
- const onNewPageClick = () => {
- setShowNewPageOptions(!showNewPageOptions);
- };
-
- const startFolderRename = () => {
- closePopup();
- setShowRenamePopup(true);
- };
-
- const changeFolderTitle = async (newTitle: string) => {
- await appBackendService.update({ name: newTitle });
- appDispatch(foldersActions.renameFolder({ id: folder.id, newTitle }));
- };
-
- const closeRenamePopup = () => {
- setShowRenamePopup(false);
- };
-
- const deleteFolder = async () => {
- closePopup();
- await appBackendService.delete();
- appDispatch(foldersActions.deleteFolder({ id: folder.id }));
- };
-
- const duplicateFolder = async () => {
- closePopup();
- const workspaceBackendService = new WorkspaceBackendService(workspace.id ?? '');
- const newApp = await workspaceBackendService.createApp({
- name: folder.title,
- });
- appDispatch(foldersActions.addFolder({ id: newApp.id, title: folder.title }));
- };
-
- const closePopup = () => {
- setShowFolderOptions(false);
- setShowNewPageOptions(false);
- };
-
- const onAddNewDocumentPage = async () => {
- closePopup();
- const newView = await appBackendService.createView({
- name: 'New Document 1',
- layoutType: ViewLayoutPB.Document,
- });
- try {
- appDispatch(
- pagesActions.addPage({
- folderId: folder.id,
- pageType: ViewLayoutPB.Document,
- title: newView.name,
- id: newView.id,
- })
- );
-
- setShowPages(true);
-
- navigate(`/page/document/${newView.id}`);
- } catch (e) {
- console.error(e);
- }
- };
-
- const onAddNewBoardPage = async () => {
- closePopup();
- const newView = await appBackendService.createView({
- name: 'New Board 1',
- layoutType: ViewLayoutPB.Board,
- });
-
- setShowPages(true);
-
- appDispatch(
- pagesActions.addPage({
- folderId: folder.id,
- pageType: ViewLayoutPB.Board,
- title: newView.name,
- id: newView.id,
- })
- );
-
- navigate(`/page/board/${newView.id}`);
- };
-
- const onAddNewGridPage = async () => {
- closePopup();
- const newView = await appBackendService.createView({
- name: 'New Grid 1',
- layoutType: ViewLayoutPB.Grid,
- });
-
- setShowPages(true);
-
- appDispatch(
- pagesActions.addPage({
- folderId: folder.id,
- pageType: ViewLayoutPB.Grid,
- title: newView.name,
- id: newView.id,
- })
- );
-
- navigate(`/page/grid/${newView.id}`);
- };
-
- useEffect(() => {
- appDispatch(foldersActions.setShowPages({ id: folder.id, showPages: showPages }));
- }, [showPages]);
-
- return {
- showPages,
- onFolderNameClick,
- showFolderOptions,
- onFolderOptionsClick,
- showNewPageOptions,
- onNewPageClick,
-
- showRenamePopup,
- startFolderRename,
- changeFolderTitle,
- closeRenamePopup,
- deleteFolder,
- duplicateFolder,
-
- onAddNewDocumentPage,
- onAddNewBoardPage,
- onAddNewGridPage,
-
- closePopup,
- folderHeight,
- };
-};
diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/FolderItem.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/FolderItem.tsx
deleted file mode 100644
index 4ebdcad8a8..0000000000
--- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/FolderItem.tsx
+++ /dev/null
@@ -1,118 +0,0 @@
-import { Details2Svg } from '../../_shared/svg/Details2Svg';
-import AddSvg from '../../_shared/svg/AddSvg';
-import { NavItemOptionsPopup } from './NavItemOptionsPopup';
-import { NewPagePopup } from './NewPagePopup';
-import { IFolder } from '$app_reducers/folders/slice';
-import { useFolderEvents } from './FolderItem.hooks';
-import { IPage } from '$app_reducers/pages/slice';
-import { PageItem } from './PageItem';
-import { Button } from '../../_shared/Button';
-import { RenamePopup } from './RenamePopup';
-import { useEffect, useRef, useState } from 'react';
-import { DropDownShowSvg } from '../../_shared/svg/DropDownShowSvg';
-import { ANIMATION_DURATION } from '../../_shared/constants';
-
-export const FolderItem = ({
- folder,
- pages,
- onPageClick,
-}: {
- folder: IFolder;
- pages: IPage[];
- onPageClick: (page: IPage) => void;
-}) => {
- const {
- showPages,
- onFolderNameClick,
- showFolderOptions,
- onFolderOptionsClick,
- showNewPageOptions,
- onNewPageClick,
-
- showRenamePopup,
- startFolderRename,
- changeFolderTitle,
- closeRenamePopup,
- deleteFolder,
- duplicateFolder,
-
- onAddNewDocumentPage,
- onAddNewBoardPage,
- onAddNewGridPage,
-
- closePopup,
- folderHeight,
- } = useFolderEvents(folder, pages);
-
- const [popupY, setPopupY] = useState(0);
-
- const el = useRef
(null);
-
- useEffect(() => {
- if (el.current) {
- const { top } = el.current.getBoundingClientRect();
- setPopupY(top);
- }
- }, [showFolderOptions, showNewPageOptions, showRenamePopup]);
-
- return (
-
-
-
onFolderNameClick()}
- className={'flex cursor-pointer items-center justify-between rounded-lg px-4 py-2 hover:bg-surface-2'}
- >
-
-
-
-
-
-
-
- {pages.map((page, index) => (
-
onPageClick(page)}>
- ))}
-
- {showFolderOptions && (
-
startFolderRename()}
- onDeleteClick={() => deleteFolder()}
- onDuplicateClick={() => duplicateFolder()}
- onClose={() => closePopup()}
- top={popupY - 124 + 40}
- >
- )}
- {showNewPageOptions && (
-
onAddNewDocumentPage()}
- onBoardClick={() => onAddNewBoardPage()}
- onGridClick={() => onAddNewGridPage()}
- onClose={() => closePopup()}
- top={popupY - 124 + 40}
- >
- )}
- {showRenamePopup && (
-
changeFolderTitle(newTitle)}
- onClose={closeRenamePopup}
- top={popupY - 124 + 40}
- >
- )}
-
- );
-};
diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavItem.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavItem.hooks.ts
new file mode 100644
index 0000000000..29fddfdee4
--- /dev/null
+++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavItem.hooks.ts
@@ -0,0 +1,226 @@
+import { useEffect, useState } from 'react';
+import { useAppDispatch, useAppSelector } from '$app/stores/store';
+import { IPage, pagesActions } from '$app_reducers/pages/slice';
+import { ViewLayoutPB } from '@/services/backend';
+import { WorkspaceBackendService } from '$app/stores/effects/folder/workspace/workspace_bd_svc';
+
+import { useLocation, useNavigate } from 'react-router-dom';
+import { INITIAL_FOLDER_HEIGHT, PAGE_ITEM_HEIGHT } from '../../_shared/constants';
+
+import { ViewBackendService } from '$app/stores/effects/folder/view/view_bd_svc';
+import { ViewObserver } from '$app/stores/effects/folder/view/view_observer';
+
+export const useNavItem = (page: IPage) => {
+ const appDispatch = useAppDispatch();
+ const workspace = useAppSelector((state) => state.workspace);
+ const currentLocation = useLocation();
+ const [activePageId, setActivePageId] = useState('');
+ const pages = useAppSelector((state) => state.pages);
+
+ const navigate = useNavigate();
+
+ // Actions
+ const [showPageOptions, setShowPageOptions] = useState(false);
+ const [showNewPageOptions, setShowNewPageOptions] = useState(false);
+ const [showRenamePopup, setShowRenamePopup] = useState(false);
+
+ // UI configurations
+ const [folderHeight, setFolderHeight] = useState(`${INITIAL_FOLDER_HEIGHT}px`);
+
+ // backend
+ const service = new ViewBackendService(page.id);
+ const observer = new ViewObserver(page.id);
+
+ const loadInsidePages = async () => {
+ const result = await service.getChildViews();
+ if (!result.ok) return;
+ const views = result.val;
+ const updatedPages: IPage[] = views.map((view) => ({
+ parentPageId: page.id,
+ id: view.id,
+ pageType: view.layout,
+ title: view.name,
+ showPagesInside: false,
+ }));
+ appDispatch(pagesActions.addInsidePages({ currentPageId: page.id, insidePages: updatedPages }));
+ };
+
+ useEffect(() => {
+ void loadInsidePages();
+ void observer.subscribe({
+ onChildViewsChanged: () => {
+ void loadInsidePages();
+ },
+ });
+ return () => {
+ // Unsubscribe when the component is unmounted.
+ void observer.unsubscribe();
+ };
+ }, []);
+
+ useEffect(() => {
+ const { pathname } = currentLocation;
+ const parts = pathname.split('/');
+ const pageId = parts[parts.length - 1];
+ setActivePageId(pageId);
+ }, [currentLocation]);
+
+ useEffect(() => {
+ if (page.showPagesInside) {
+ setFolderHeight(`${PAGE_ITEM_HEIGHT + getChildCount(page) * PAGE_ITEM_HEIGHT}px`);
+ } else {
+ setFolderHeight(`${PAGE_ITEM_HEIGHT}px`);
+ }
+ }, [page, pages]);
+
+ // recursively get all unfolded child pages
+ const getChildCount: (startPage: IPage) => number = (startPage: IPage) => {
+ let count = 0;
+ count = pages.filter((p) => p.parentPageId === startPage.id).length;
+ pages
+ .filter((p) => p.parentPageId === startPage.id)
+ .forEach((p) => {
+ if (p.showPagesInside) {
+ count += getChildCount(p);
+ }
+ });
+ return count;
+ };
+
+ const onUnfoldClick = () => {
+ appDispatch(pagesActions.toggleShowPages({ id: page.id }));
+ };
+
+ const onPageOptionsClick = () => {
+ setShowPageOptions(!showPageOptions);
+ };
+
+ const startPageRename = () => {
+ setShowRenamePopup(true);
+ closePopup();
+ };
+
+ const onNewPageClick = () => {
+ setShowNewPageOptions(!showNewPageOptions);
+ };
+
+ const changePageTitle = async (newTitle: string) => {
+ await service.update({ name: newTitle });
+ appDispatch(pagesActions.renamePage({ id: page.id, newTitle }));
+ };
+
+ const closeRenamePopup = () => {
+ setShowRenamePopup(false);
+ };
+
+ const deletePage = async () => {
+ closePopup();
+ await service.delete();
+ appDispatch(pagesActions.deletePage({ id: page.id }));
+ };
+
+ const duplicatePage = async () => {
+ closePopup();
+ await service.duplicate();
+ };
+
+ const closePopup = () => {
+ setShowPageOptions(false);
+ setShowNewPageOptions(false);
+ };
+
+ const onPageClick = (eventPage: IPage) => {
+ const pageTypeRoute = (() => {
+ switch (eventPage.pageType) {
+ case ViewLayoutPB.Document:
+ return 'document';
+ case ViewLayoutPB.Grid:
+ return 'grid';
+ case ViewLayoutPB.Board:
+ return 'board';
+ default:
+ return 'document';
+ }
+ })();
+
+ navigate(`/page/${pageTypeRoute}/${eventPage.id}`);
+ };
+
+ const onAddNewPage = async (pageType: ViewLayoutPB) => {
+ closePopup();
+ if (!workspace?.id) return;
+
+ let newPageName = '';
+ let pageTypeRoute = '';
+
+ switch (pageType) {
+ case ViewLayoutPB.Document:
+ newPageName = 'Document Page 1';
+ pageTypeRoute = 'document';
+ break;
+ case ViewLayoutPB.Grid:
+ newPageName = 'Grid Page 1';
+ pageTypeRoute = 'grid';
+ break;
+ case ViewLayoutPB.Board:
+ newPageName = 'Board Page 1';
+ pageTypeRoute = 'board';
+ break;
+ default:
+ newPageName = 'Document Page 1';
+ pageTypeRoute = 'document';
+ break;
+ }
+
+ const workspaceService = new WorkspaceBackendService(workspace.id);
+ const newViewResult = await workspaceService.createView({
+ name: newPageName,
+ layoutType: pageType,
+ parentViewId: page.id,
+ });
+
+ if (newViewResult.ok) {
+ const newView = newViewResult.val;
+ if (!page.showPagesInside) {
+ appDispatch(pagesActions.toggleShowPages({ id: page.id }));
+ }
+
+ appDispatch(
+ pagesActions.addPage({
+ parentPageId: page.id,
+ pageType,
+ title: newView.name,
+ id: newView.id,
+ showPagesInside: false,
+ })
+ );
+
+ navigate(`/page/${pageTypeRoute}/${newView.id}`);
+ }
+ };
+
+ return {
+ onUnfoldClick,
+ onNewPageClick,
+ onPageOptionsClick,
+ startPageRename,
+
+ changePageTitle,
+ closeRenamePopup,
+ closePopup,
+
+ showNewPageOptions,
+ showPageOptions,
+ showRenamePopup,
+
+ deletePage,
+ duplicatePage,
+
+ onPageClick,
+
+ onAddNewPage,
+
+ folderHeight,
+ activePageId,
+ };
+};
diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavItem.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavItem.tsx
new file mode 100644
index 0000000000..de37ef8b64
--- /dev/null
+++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavItem.tsx
@@ -0,0 +1,126 @@
+import { Details2Svg } from '../../_shared/svg/Details2Svg';
+import AddSvg from '../../_shared/svg/AddSvg';
+import { NavItemOptionsPopup } from './NavItemOptionsPopup';
+import { NewPagePopup } from './NewPagePopup';
+import { IPage } from '$app_reducers/pages/slice';
+import { Button } from '../../_shared/Button';
+import { RenamePopup } from './RenamePopup';
+import { useEffect, useMemo, useRef, useState } from 'react';
+import { DropDownShowSvg } from '../../_shared/svg/DropDownShowSvg';
+import { ANIMATION_DURATION, PAGE_ITEM_HEIGHT } from '../../_shared/constants';
+import { useNavItem } from '$app/components/layout/NavigationPanel/NavItem.hooks';
+import { useAppSelector } from '$app/stores/store';
+import { ViewLayoutPB } from '@/services/backend';
+
+export const NavItem = ({ page }: { page: IPage }) => {
+ const pages = useAppSelector((state) => state.pages);
+ const {
+ onUnfoldClick,
+ onNewPageClick,
+ onPageOptionsClick,
+ startPageRename,
+
+ changePageTitle,
+ closeRenamePopup,
+ closePopup,
+
+ showNewPageOptions,
+ showPageOptions,
+ showRenamePopup,
+
+ deletePage,
+ duplicatePage,
+
+ onAddNewPage,
+
+ folderHeight,
+ activePageId,
+
+ onPageClick,
+ } = useNavItem(page);
+
+ const [popupY, setPopupY] = useState(0);
+
+ const el = useRef(null);
+
+ useEffect(() => {
+ if (el.current) {
+ const { top } = el.current.getBoundingClientRect();
+ setPopupY(top);
+ }
+ }, [showPageOptions, showNewPageOptions, showRenamePopup]);
+
+ return (
+
+
+
+
+
+
onPageClick(page)}
+ className={
+ 'flex h-full min-w-0 flex-1 items-center overflow-hidden overflow-ellipsis whitespace-nowrap text-left'
+ }
+ >
+ {page.title}
+
+
+
+
+
+
+
+
+ {useMemo(() => pages.filter((insidePage) => insidePage.parentPageId === page.id), [pages, page]).map(
+ (insidePage, insideIndex) => (
+
+ )
+ )}
+
+
+ {showPageOptions && (
+
startPageRename()}
+ onDeleteClick={() => deletePage()}
+ onDuplicateClick={() => duplicatePage()}
+ onClose={() => closePopup()}
+ top={popupY - 124 + 40}
+ >
+ )}
+ {showNewPageOptions && (
+
onAddNewPage(ViewLayoutPB.Document)}
+ onBoardClick={() => onAddNewPage(ViewLayoutPB.Board)}
+ onGridClick={() => onAddNewPage(ViewLayoutPB.Grid)}
+ onClose={() => closePopup()}
+ top={popupY - 124 + 40}
+ >
+ )}
+ {showRenamePopup && (
+
changePageTitle(newTitle)}
+ onClose={closeRenamePopup}
+ top={popupY - 124 + 40}
+ >
+ )}
+
+ );
+};
diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavigationPanel.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavigationPanel.hooks.ts
index 60543ddea7..e5df126fff 100644
--- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavigationPanel.hooks.ts
+++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavigationPanel.hooks.ts
@@ -1,17 +1,10 @@
import { useAppSelector } from '$app/stores/store';
-import { useNavigate } from 'react-router-dom';
-import { IPage } from '$app_reducers/pages/slice';
-import { ViewLayoutPB } from '@/services/backend';
import { useState } from 'react';
export const useNavigationPanelHooks = function () {
- const folders = useAppSelector((state) => state.folders);
- const pages = useAppSelector((state) => state.pages);
const width = useAppSelector((state) => state.navigationWidth);
const [menuHidden, setMenuHidden] = useState(false);
- const navigate = useNavigate();
-
const onHideMenuClick = () => {
setMenuHidden(true);
};
@@ -20,28 +13,8 @@ export const useNavigationPanelHooks = function () {
setMenuHidden(false);
};
- const onPageClick = (page: IPage) => {
- const pageTypeRoute = (() => {
- switch (page.pageType) {
- case ViewLayoutPB.Document:
- return 'document';
- case ViewLayoutPB.Grid:
- return 'grid';
- case ViewLayoutPB.Board:
- return 'board';
- default:
- return 'document';
- }
- })();
-
- navigate(`/page/${pageTypeRoute}/${page.id}`);
- };
-
return {
width,
- folders,
- pages,
- onPageClick,
menuHidden,
onHideMenuClick,
onShowMenuClick,
diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavigationPanel.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavigationPanel.tsx
index 2808cef8b7..bd3c7b9cdb 100644
--- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavigationPanel.tsx
+++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/NavigationPanel.tsx
@@ -1,40 +1,27 @@
import { WorkspaceUser } from '../WorkspaceUser';
import { AppLogo } from '../AppLogo';
-import { FolderItem } from './FolderItem';
import { TrashButton } from './TrashButton';
-import { NewFolderButton } from './NewFolderButton';
+import { NewViewButton } from './NewViewButton';
import { NavigationResizer } from './NavigationResizer';
-import { IFolder } from '$app_reducers/folders/slice';
import { IPage } from '$app_reducers/pages/slice';
import { useLocation, useNavigate } from 'react-router-dom';
import React, { useEffect, useRef, useState } from 'react';
import { useAppSelector } from '$app/stores/store';
-import {
- ANIMATION_DURATION,
- FOLDER_MARGIN,
- INITIAL_FOLDER_HEIGHT,
- NAV_PANEL_MINIMUM_WIDTH,
- PAGE_ITEM_HEIGHT,
-} from '../../_shared/constants';
+import { NavItem } from '$app/components/layout/NavigationPanel/NavItem';
+import { ANIMATION_DURATION, NAV_PANEL_MINIMUM_WIDTH, PAGE_ITEM_HEIGHT } from '../../_shared/constants';
export const NavigationPanel = ({
onHideMenuClick,
menuHidden,
width,
- folders,
- pages,
- onPageClick,
}: {
onHideMenuClick: () => void;
menuHidden: boolean;
width: number;
- folders: IFolder[];
- pages: IPage[];
- onPageClick: (page: IPage) => void;
}) => {
const el = useRef(null);
- const foldersStore = useAppSelector((state) => state.folders);
- const pagesStore = useAppSelector((state) => state.pages);
+ const pages = useAppSelector((state) => state.pages);
+ const workspace = useAppSelector((state) => state.workspace);
const [activePageId, setActivePageId] = useState('');
const currentLocation = useLocation();
const [maxHeight, setMaxHeight] = useState(0);
@@ -47,44 +34,8 @@ export const NavigationPanel = ({
}, [currentLocation]);
useEffect(() => {
- setTimeout(() => {
- if (!el.current) return;
- if (!activePageId?.length) return;
- const activePage = pagesStore.find((page) => page.id === activePageId);
- if (!activePage) return;
-
- const folderIndex = foldersStore.findIndex((folder) => folder.id === activePage.folderId);
- if (folderIndex === -1) return;
-
- let height = 0;
- for (let i = 0; i < folderIndex; i++) {
- height += INITIAL_FOLDER_HEIGHT + FOLDER_MARGIN;
- if (foldersStore[i].showPages) {
- height += pagesStore.filter((p) => p.folderId === foldersStore[i].id).length * PAGE_ITEM_HEIGHT;
- }
- }
-
- height += INITIAL_FOLDER_HEIGHT + FOLDER_MARGIN / 2;
-
- const pageIndex = pagesStore
- .filter((p) => p.folderId === foldersStore[folderIndex].id)
- .findIndex((p) => p.id === activePageId);
- for (let i = 0; i <= pageIndex; i++) {
- height += PAGE_ITEM_HEIGHT;
- }
-
- const elHeight = el.current.getBoundingClientRect().height;
- const scrollTop = el.current.scrollTop;
-
- if (scrollTop + elHeight < height || scrollTop > height) {
- el.current.scrollTo({ top: height - elHeight, behavior: 'smooth' });
- }
- }, ANIMATION_DURATION);
- }, [activePageId]);
-
- useEffect(() => {
- setMaxHeight(foldersStore.length * (INITIAL_FOLDER_HEIGHT + FOLDER_MARGIN) + pagesStore.length * PAGE_ITEM_HEIGHT);
- }, [foldersStore, pagesStore]);
+ setMaxHeight(pages.length * PAGE_ITEM_HEIGHT);
+ }, [pages]);
const scrollDown = () => {
setTimeout(() => {
@@ -113,7 +64,7 @@ export const NavigationPanel = ({
}}
ref={el}
>
-
+ p.parentPageId === workspace.id)} />