mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +00:00
feat: new sidebar (app shell) styles (#2303)
This commit is contained in:
@@ -28,7 +28,7 @@ async function createWindow() {
|
||||
y: mainWindowState.y,
|
||||
width: mainWindowState.width,
|
||||
minWidth: 640,
|
||||
transparent: isMacOS(),
|
||||
minHeight: 480,
|
||||
visualEffectState: 'active',
|
||||
vibrancy: 'under-window',
|
||||
height: mainWindowState.height,
|
||||
|
||||
@@ -7,7 +7,7 @@ export const StyledSidebarSwitch = styled(IconButton, {
|
||||
})<{ visible: boolean }>(({ visible }) => {
|
||||
return {
|
||||
opacity: visible ? 1 : 0,
|
||||
WebkitAppRegion: 'no-drag',
|
||||
WebkitAppRegion: visible ? 'no-drag' : 'drag',
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
};
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { CloseIcon, MinusIcon, RoundedRectangleIcon } from '@blocksuite/icons';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { useAtom } from 'jotai';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import type { FC, HTMLAttributes, PropsWithChildren } from 'react';
|
||||
import {
|
||||
forwardRef,
|
||||
@@ -161,7 +161,7 @@ export const Header = forwardRef<
|
||||
setShowWarning(shouldShowWarning());
|
||||
setShowGuideDownloadClientTip(shouldShowGuideDownloadClientTip);
|
||||
}, [shouldShowGuideDownloadClientTip]);
|
||||
const [open] = useAtom(appSidebarOpenAtom);
|
||||
const open = useAtomValue(appSidebarOpenAtom);
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const mode = useCurrentMode();
|
||||
@@ -189,7 +189,6 @@ export const Header = forwardRef<
|
||||
className={styles.header}
|
||||
data-has-warning={showWarning}
|
||||
data-testid="editor-header-items"
|
||||
data-tauri-drag-region
|
||||
data-is-edgeless={mode === 'edgeless'}
|
||||
>
|
||||
<Suspense>
|
||||
|
||||
@@ -6,18 +6,9 @@ export const headerContainer = style({
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
background: 'var(--affine-background-primary-color)',
|
||||
// @ts-ignore
|
||||
WebkitAppRegion: 'drag',
|
||||
zIndex: 'var(--affine-z-index-popover)',
|
||||
'@media': {
|
||||
'(max-width: 768px)': {
|
||||
selectors: {
|
||||
'&[data-open="true"]': {
|
||||
// @ts-ignore
|
||||
WebkitAppRegion: 'no-drag',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
selectors: {
|
||||
'&[data-has-warning="true"]': {
|
||||
height: '96px',
|
||||
|
||||
@@ -6,7 +6,7 @@ export const StyledSelectorContainer = styled('div')(() => {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '0 6px',
|
||||
marginBottom: '16px',
|
||||
margin: '0 -6px',
|
||||
borderRadius: '8px',
|
||||
color: 'var(--affine-text-primary-color)',
|
||||
':hover': {
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { MenuItem } from '@affine/component/app-sidebar';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
|
||||
import { StyledCollapseItem } from '../shared-styles';
|
||||
|
||||
export const EmptyItem = () => {
|
||||
const t = useAFFiNEI18N();
|
||||
return (
|
||||
<StyledCollapseItem disable={true} textWrap={true}>
|
||||
{t['Favorite pages for easy access']()}
|
||||
</StyledCollapseItem>
|
||||
<MenuItem disabled={true}>{t['Favorite pages for easy access']()}</MenuItem>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
import { MuiCollapse } from '@affine/component';
|
||||
import { MenuLinkItem } from '@affine/component/app-sidebar';
|
||||
import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
|
||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { workspacePreferredModeAtom } from '../../../../atoms';
|
||||
import type { FavoriteListProps } from '../index';
|
||||
import { StyledCollapseItem } from '../shared-styles';
|
||||
import EmptyItem from './empty-item';
|
||||
export const FavoriteList = ({
|
||||
pageMeta,
|
||||
openPage,
|
||||
showList,
|
||||
}: FavoriteListProps) => {
|
||||
export const FavoriteList = ({ currentWorkspace }: FavoriteListProps) => {
|
||||
const router = useRouter();
|
||||
const record = useAtomValue(workspacePreferredModeAtom);
|
||||
const pageMeta = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace);
|
||||
const workspaceId = currentWorkspace.id;
|
||||
|
||||
const favoriteList = useMemo(
|
||||
() => pageMeta.filter(p => p.favorite && !p.trash),
|
||||
@@ -22,45 +20,25 @@ export const FavoriteList = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<MuiCollapse
|
||||
in={showList}
|
||||
style={{
|
||||
maxHeight: 300,
|
||||
overflowY: 'auto',
|
||||
marginLeft: '16px',
|
||||
}}
|
||||
>
|
||||
<>
|
||||
{favoriteList.map((pageMeta, index) => {
|
||||
const active = router.query.pageId === pageMeta.id;
|
||||
const icon =
|
||||
record[pageMeta.id] === 'edgeless' ? <EdgelessIcon /> : <PageIcon />;
|
||||
return (
|
||||
<div key={`${pageMeta}-${index}`}>
|
||||
<StyledCollapseItem
|
||||
data-testid={`favorite-list-item-${pageMeta.id}`}
|
||||
active={active}
|
||||
ref={ref => {
|
||||
if (ref && active) {
|
||||
ref.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
}}
|
||||
onClick={() => {
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
openPage(pageMeta.id);
|
||||
}}
|
||||
>
|
||||
{record[pageMeta.id] === 'edgeless' ? (
|
||||
<EdgelessIcon />
|
||||
) : (
|
||||
<PageIcon />
|
||||
)}
|
||||
<span>{pageMeta.title || 'Untitled'}</span>
|
||||
</StyledCollapseItem>
|
||||
</div>
|
||||
<MenuLinkItem
|
||||
key={`${pageMeta}-${index}`}
|
||||
data-testid={`favorite-list-item-${pageMeta.id}`}
|
||||
active={active}
|
||||
href={`/workspace/${workspaceId}/${pageMeta.id}`}
|
||||
icon={icon}
|
||||
>
|
||||
<span>{pageMeta.title || 'Untitled'}</span>
|
||||
</MenuLinkItem>
|
||||
);
|
||||
})}
|
||||
{favoriteList.length === 0 && <EmptyItem />}
|
||||
</MuiCollapse>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,66 +1 @@
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ArrowDownSmallIcon, FavoriteIcon } from '@blocksuite/icons';
|
||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import type { AllWorkspace } from '../../../../shared';
|
||||
import type { WorkSpaceSliderBarProps } from '../index';
|
||||
import { StyledCollapseButton, StyledListItem } from '../shared-styles';
|
||||
import { StyledLink } from '../style';
|
||||
import FavoriteList from './favorite-list';
|
||||
|
||||
export const Favorite = ({
|
||||
currentPath,
|
||||
paths,
|
||||
currentPageId,
|
||||
openPage,
|
||||
currentWorkspace,
|
||||
}: Pick<
|
||||
WorkSpaceSliderBarProps,
|
||||
'currentPath' | 'paths' | 'currentPageId' | 'openPage'
|
||||
> & {
|
||||
currentWorkspace: AllWorkspace;
|
||||
}) => {
|
||||
const currentWorkspaceId = currentWorkspace.id;
|
||||
const pageMeta = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace);
|
||||
|
||||
const [showSubFavorite, setOpenSubFavorite] = useState(true);
|
||||
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledListItem
|
||||
active={
|
||||
currentPath ===
|
||||
(currentWorkspaceId && paths.favorite(currentWorkspaceId))
|
||||
}
|
||||
>
|
||||
<StyledLink
|
||||
href={{
|
||||
pathname: currentWorkspaceId && paths.favorite(currentWorkspaceId),
|
||||
}}
|
||||
>
|
||||
<FavoriteIcon />
|
||||
{t['Favorites']()}
|
||||
</StyledLink>
|
||||
<StyledCollapseButton
|
||||
onClick={useCallback(() => {
|
||||
setOpenSubFavorite(!showSubFavorite);
|
||||
}, [showSubFavorite])}
|
||||
collapse={showSubFavorite}
|
||||
>
|
||||
<ArrowDownSmallIcon />
|
||||
</StyledCollapseButton>
|
||||
</StyledListItem>
|
||||
<FavoriteList
|
||||
currentPageId={currentPageId}
|
||||
showList={showSubFavorite}
|
||||
openPage={openPage}
|
||||
pageMeta={pageMeta}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Favorite;
|
||||
export * from './favorite-list';
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
export const Arrow = () => {
|
||||
return (
|
||||
<svg
|
||||
width="6"
|
||||
height="10"
|
||||
viewBox="0 0 6 10"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M0.354 9.22997C0.201333 9.0773 0.125 8.91764 0.125 8.75097C0.125 8.5843 0.201333 8.42464 0.354 8.27197L3.625 5.00097L0.354 1.72997C0.201333 1.5773 0.125 1.41764 0.125 1.25097C0.125 1.0843 0.201333 0.924636 0.354 0.771969C0.506667 0.619302 0.666333 0.542969 0.833 0.542969C0.999667 0.542969 1.15933 0.619302 1.312 0.771969L4.979 4.43897C5.06233 4.52164 5.125 4.61164 5.167 4.70897C5.20833 4.8063 5.229 4.90364 5.229 5.00097C5.229 5.0983 5.20833 5.19564 5.167 5.29297C5.125 5.3903 5.06233 5.4803 4.979 5.56297L1.312 9.22997C1.15933 9.38264 0.999667 9.45897 0.833 9.45897C0.666333 9.45897 0.506667 9.38264 0.354 9.22997Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -1,12 +1,9 @@
|
||||
import type { Page, PageMeta } from '@blocksuite/store';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
|
||||
import type { AllWorkspace } from '../../../shared';
|
||||
|
||||
export type FavoriteListProps = {
|
||||
currentPageId: string | null;
|
||||
openPage: (pageId: string) => void;
|
||||
showList: boolean;
|
||||
pageMeta: PageMeta[];
|
||||
currentWorkspace: AllWorkspace;
|
||||
};
|
||||
|
||||
export type WorkSpaceSliderBarProps = {
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { IconButton } from '@affine/component';
|
||||
import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons';
|
||||
|
||||
import { StyledRouteNavigationWrapper } from './shared-styles';
|
||||
|
||||
export const RouteNavigation = () => {
|
||||
if (!environment.isDesktop) {
|
||||
return <></>;
|
||||
}
|
||||
return (
|
||||
<StyledRouteNavigationWrapper>
|
||||
<IconButton
|
||||
size="middle"
|
||||
onClick={() => {
|
||||
window.history.back();
|
||||
}}
|
||||
>
|
||||
<ArrowLeftSmallIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
size="middle"
|
||||
onClick={() => {
|
||||
window.history.forward();
|
||||
}}
|
||||
style={{ marginLeft: '32px' }}
|
||||
>
|
||||
<ArrowRightSmallIcon />
|
||||
</IconButton>
|
||||
</StyledRouteNavigationWrapper>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,14 @@
|
||||
import {
|
||||
AddPageButton,
|
||||
AppSidebar,
|
||||
appSidebarOpenAtom,
|
||||
ResizeIndicator,
|
||||
AppUpdaterButton,
|
||||
CategoryDivider,
|
||||
MenuLinkItem,
|
||||
QuickSearchInput,
|
||||
SidebarContainer,
|
||||
SidebarScrollableContainer,
|
||||
updateAvailableAtom,
|
||||
} from '@affine/component/app-sidebar';
|
||||
import { config } from '@affine/env';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
@@ -9,27 +16,18 @@ import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import {
|
||||
DeleteTemporarilyIcon,
|
||||
FolderIcon,
|
||||
PlusIcon,
|
||||
SearchIcon,
|
||||
SettingsIcon,
|
||||
ShareIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { ReactElement, UIEvent } from 'react';
|
||||
import type { ReactElement } from 'react';
|
||||
import type React from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
import type { AllWorkspace } from '../../shared';
|
||||
import ChangeLog from '../pure/workspace-slider-bar/changeLog';
|
||||
import Favorite from '../pure/workspace-slider-bar/favorite';
|
||||
import { StyledListItem } from '../pure/workspace-slider-bar/shared-styles';
|
||||
import {
|
||||
StyledLink,
|
||||
StyledNewPageButton,
|
||||
StyledScrollWrapper,
|
||||
StyledSliderBarInnerWrapper,
|
||||
} from '../pure/workspace-slider-bar/style';
|
||||
import FavoriteList from '../pure/workspace-slider-bar/favorite/favorite-list';
|
||||
import { WorkspaceSelector } from '../pure/workspace-slider-bar/WorkspaceSelector';
|
||||
|
||||
export type RootAppSidebarProps = {
|
||||
@@ -37,7 +35,6 @@ export type RootAppSidebarProps = {
|
||||
onOpenQuickSearchModal: () => void;
|
||||
onOpenWorkspaceListModal: () => void;
|
||||
currentWorkspace: AllWorkspace | null;
|
||||
currentPageId: string | null;
|
||||
openPage: (pageId: string) => void;
|
||||
createPage: () => Page;
|
||||
currentPath: string;
|
||||
@@ -50,6 +47,26 @@ export type RootAppSidebarProps = {
|
||||
};
|
||||
};
|
||||
|
||||
const RouteMenuLinkItem = ({
|
||||
currentPath,
|
||||
path,
|
||||
icon,
|
||||
children,
|
||||
...props
|
||||
}: {
|
||||
currentPath: string; // todo: pass through useRouter?
|
||||
path?: string | null;
|
||||
icon: ReactElement;
|
||||
children?: ReactElement;
|
||||
} & React.HTMLAttributes<HTMLDivElement>) => {
|
||||
const active = currentPath === path;
|
||||
return (
|
||||
<MenuLinkItem {...props} active={active} href={path ?? ''} icon={icon}>
|
||||
{children}
|
||||
</MenuLinkItem>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* This is for the whole affine app sidebar.
|
||||
* This component wraps the app sidebar in `@affine/component` with logic and data.
|
||||
@@ -58,7 +75,6 @@ export type RootAppSidebarProps = {
|
||||
*/
|
||||
export const RootAppSidebar = ({
|
||||
currentWorkspace,
|
||||
currentPageId,
|
||||
openPage,
|
||||
createPage,
|
||||
currentPath,
|
||||
@@ -69,7 +85,6 @@ export const RootAppSidebar = ({
|
||||
const currentWorkspaceId = currentWorkspace?.id || null;
|
||||
const blockSuiteWorkspace = currentWorkspace?.blockSuiteWorkspace;
|
||||
const t = useAFFiNEI18N();
|
||||
const [isScrollAtTop, setIsScrollAtTop] = useState(true);
|
||||
const onClickNewPage = useCallback(async () => {
|
||||
const page = await createPage();
|
||||
openPage(page.id);
|
||||
@@ -80,160 +95,78 @@ export const RootAppSidebar = ({
|
||||
window.apis?.ui.handleSidebarVisibilityChange(sidebarOpen);
|
||||
}
|
||||
}, [sidebarOpen]);
|
||||
const [ref, setRef] = useState<HTMLElement | null>(null);
|
||||
|
||||
const handleQuickSearchButtonKeyDown = useCallback(
|
||||
(e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
onOpenQuickSearchModal();
|
||||
}
|
||||
},
|
||||
[onOpenQuickSearchModal]
|
||||
);
|
||||
const clientUpdateAvailable = useAtomValue(updateAvailableAtom);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AppSidebar
|
||||
ref={setRef}
|
||||
footer={
|
||||
<StyledNewPageButton
|
||||
data-testid="new-page-button"
|
||||
onClick={onClickNewPage}
|
||||
>
|
||||
<PlusIcon /> {t['New Page']()}
|
||||
</StyledNewPageButton>
|
||||
}
|
||||
>
|
||||
<StyledSliderBarInnerWrapper data-testid="sliderBar-inner">
|
||||
<AppSidebar>
|
||||
<SidebarContainer>
|
||||
<WorkspaceSelector
|
||||
currentWorkspace={currentWorkspace}
|
||||
onClick={onOpenWorkspaceListModal}
|
||||
/>
|
||||
<ChangeLog />
|
||||
<StyledListItem
|
||||
<QuickSearchInput
|
||||
data-testid="slider-bar-quick-search-button"
|
||||
onClick={useCallback(() => {
|
||||
onOpenQuickSearchModal();
|
||||
}, [onOpenQuickSearchModal])}
|
||||
onKeyDown={handleQuickSearchButtonKeyDown}
|
||||
onClick={onOpenQuickSearchModal}
|
||||
/>
|
||||
<RouteMenuLinkItem
|
||||
icon={<FolderIcon />}
|
||||
currentPath={currentPath}
|
||||
path={currentWorkspaceId && paths.all(currentWorkspaceId)}
|
||||
>
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
style={{
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
}}
|
||||
>
|
||||
<SearchIcon />
|
||||
{t['Quick search']()}
|
||||
</div>
|
||||
</StyledListItem>
|
||||
<StyledListItem
|
||||
active={
|
||||
currentPath ===
|
||||
(currentWorkspaceId && paths.setting(currentWorkspaceId))
|
||||
}
|
||||
<span data-testid="all-pages">{t['All pages']()}</span>
|
||||
</RouteMenuLinkItem>
|
||||
<RouteMenuLinkItem
|
||||
data-testid="slider-bar-workspace-setting-button"
|
||||
style={{
|
||||
marginBottom: '16px',
|
||||
}}
|
||||
icon={<SettingsIcon />}
|
||||
currentPath={currentPath}
|
||||
path={currentWorkspaceId && paths.setting(currentWorkspaceId)}
|
||||
>
|
||||
<StyledLink
|
||||
href={{
|
||||
pathname:
|
||||
currentWorkspaceId && paths.setting(currentWorkspaceId),
|
||||
}}
|
||||
>
|
||||
<SettingsIcon />
|
||||
<div>{t['Workspace Settings']()}</div>
|
||||
</StyledLink>
|
||||
</StyledListItem>
|
||||
<StyledListItem
|
||||
active={
|
||||
currentPath ===
|
||||
(currentWorkspaceId && paths.all(currentWorkspaceId))
|
||||
}
|
||||
>
|
||||
<StyledLink
|
||||
href={{
|
||||
pathname: currentWorkspaceId && paths.all(currentWorkspaceId),
|
||||
}}
|
||||
>
|
||||
<FolderIcon />
|
||||
<span data-testid="all-pages">{t['All pages']()}</span>
|
||||
</StyledLink>
|
||||
</StyledListItem>
|
||||
<StyledScrollWrapper
|
||||
showTopBorder={!isScrollAtTop}
|
||||
onScroll={(e: UIEvent<HTMLDivElement>) => {
|
||||
(e.target as HTMLDivElement).scrollTop === 0
|
||||
? setIsScrollAtTop(true)
|
||||
: setIsScrollAtTop(false);
|
||||
}}
|
||||
>
|
||||
{blockSuiteWorkspace && (
|
||||
<Favorite
|
||||
currentPath={currentPath}
|
||||
paths={paths}
|
||||
currentPageId={currentPageId}
|
||||
openPage={openPage}
|
||||
currentWorkspace={currentWorkspace}
|
||||
/>
|
||||
)}
|
||||
</StyledScrollWrapper>
|
||||
<div style={{ height: 16 }}></div>
|
||||
<span data-testid="settings">{t['Settings']()}</span>
|
||||
</RouteMenuLinkItem>
|
||||
</SidebarContainer>
|
||||
|
||||
<SidebarScrollableContainer>
|
||||
<CategoryDivider label={t['Favorites']()} />
|
||||
{blockSuiteWorkspace && (
|
||||
<FavoriteList currentWorkspace={currentWorkspace} />
|
||||
)}
|
||||
{config.enableLegacyCloud &&
|
||||
(currentWorkspace?.flavour === WorkspaceFlavour.AFFINE &&
|
||||
currentWorkspace.public ? (
|
||||
<StyledListItem>
|
||||
<StyledLink
|
||||
href={{
|
||||
pathname:
|
||||
currentWorkspaceId && paths.setting(currentWorkspaceId),
|
||||
}}
|
||||
>
|
||||
<ShareIcon />
|
||||
<span data-testid="Published-to-web">Published to web</span>
|
||||
</StyledLink>
|
||||
</StyledListItem>
|
||||
) : (
|
||||
<StyledListItem
|
||||
active={
|
||||
currentPath ===
|
||||
(currentWorkspaceId && paths.shared(currentWorkspaceId))
|
||||
}
|
||||
<RouteMenuLinkItem
|
||||
icon={<ShareIcon />}
|
||||
currentPath={currentPath}
|
||||
path={currentWorkspaceId && paths.setting(currentWorkspaceId)}
|
||||
>
|
||||
<StyledLink
|
||||
href={{
|
||||
pathname:
|
||||
currentWorkspaceId && paths.shared(currentWorkspaceId),
|
||||
}}
|
||||
>
|
||||
<ShareIcon />
|
||||
<span data-testid="shared-pages">{t['Shared Pages']()}</span>
|
||||
</StyledLink>
|
||||
</StyledListItem>
|
||||
<span data-testid="Published-to-web">Published to web</span>
|
||||
</RouteMenuLinkItem>
|
||||
) : (
|
||||
<RouteMenuLinkItem
|
||||
icon={<ShareIcon />}
|
||||
currentPath={currentPath}
|
||||
path={currentWorkspaceId && paths.shared(currentWorkspaceId)}
|
||||
>
|
||||
<span data-testid="shared-pages">{t['Shared Pages']()}</span>
|
||||
</RouteMenuLinkItem>
|
||||
))}
|
||||
<StyledListItem
|
||||
active={
|
||||
currentPath ===
|
||||
(currentWorkspaceId && paths.trash(currentWorkspaceId))
|
||||
}
|
||||
|
||||
<CategoryDivider label={t['others']()} />
|
||||
<RouteMenuLinkItem
|
||||
icon={<DeleteTemporarilyIcon />}
|
||||
currentPath={currentPath}
|
||||
path={currentWorkspaceId && paths.trash(currentWorkspaceId)}
|
||||
>
|
||||
<StyledLink
|
||||
href={{
|
||||
pathname: currentWorkspaceId && paths.trash(currentWorkspaceId),
|
||||
}}
|
||||
>
|
||||
<DeleteTemporarilyIcon /> {t['Trash']()}
|
||||
</StyledLink>
|
||||
</StyledListItem>
|
||||
</StyledSliderBarInnerWrapper>
|
||||
<span data-testid="trash-page">{t['Trash']()}</span>
|
||||
</RouteMenuLinkItem>
|
||||
</SidebarScrollableContainer>
|
||||
<SidebarContainer>
|
||||
{clientUpdateAvailable && <AppUpdaterButton />}
|
||||
<AddPageButton onClick={onClickNewPage} />
|
||||
</SidebarContainer>
|
||||
</AppSidebar>
|
||||
<ResizeIndicator targetElement={ref} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
appSidebarOpenAtom,
|
||||
appSidebarResizingAtom,
|
||||
} from '@affine/component/app-sidebar';
|
||||
import {
|
||||
AppContainer,
|
||||
MainContainer,
|
||||
@@ -330,17 +334,19 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
|
||||
setOpenQuickSearchModalAtom(true);
|
||||
}, [setOpenQuickSearchModalAtom]);
|
||||
|
||||
const resizing = useAtomValue(appSidebarResizingAtom);
|
||||
const sidebarOpen = useAtomValue(appSidebarOpenAtom);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
</Head>
|
||||
<AppContainer>
|
||||
<AppContainer resizing={resizing}>
|
||||
<RootAppSidebar
|
||||
isPublicWorkspace={isPublicWorkspace}
|
||||
onOpenQuickSearchModal={handleOpenQuickSearchModal}
|
||||
currentWorkspace={currentWorkspace}
|
||||
currentPageId={currentPageId}
|
||||
onOpenWorkspaceListModal={handleOpenWorkspaceListModal}
|
||||
openPage={useCallback(
|
||||
(pageId: string) => {
|
||||
@@ -353,7 +359,7 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
|
||||
currentPath={router.asPath.split('?')[0]}
|
||||
paths={isPublicWorkspace ? publicPathGenerator : pathGenerator}
|
||||
/>
|
||||
<MainContainer>
|
||||
<MainContainer sidebarOpen={sidebarOpen}>
|
||||
<Suspense fallback={<WorkspaceFallback />}>{children}</Suspense>
|
||||
<ToolContainer>
|
||||
{/* fixme(himself65): remove this */}
|
||||
|
||||
Reference in New Issue
Block a user