mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 13:25:12 +00:00
refactor: abstract header adapter (#2580)
This commit is contained in:
@@ -5,7 +5,7 @@ import type {
|
||||
AffineLegacyCloudWorkspace,
|
||||
LocalWorkspace,
|
||||
} from '@affine/workspace/type';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { WorkspaceFlavour, WorkspaceSubPath } from '@affine/workspace/type';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { assertEquals } from '@blocksuite/store';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -15,7 +15,6 @@ import { useCallback, useState } from 'react';
|
||||
import { useToggleWorkspacePublish } from '../../../../hooks/affine/use-toggle-workspace-publish';
|
||||
import { useOnTransformWorkspace } from '../../../../hooks/root/use-on-transform-workspace';
|
||||
import { useRouterHelper } from '../../../../hooks/use-router-helper';
|
||||
import { WorkspaceSubPath } from '../../../../shared';
|
||||
import { TransformWorkspaceToAffineModal } from '../../../affine/transform-workspace-to-affine-modal';
|
||||
import type { BaseHeaderProps } from '../header';
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ export type BaseHeaderProps<
|
||||
workspace: Workspace;
|
||||
currentPage: Page | null;
|
||||
isPublic: boolean;
|
||||
isPreview: boolean;
|
||||
leftSlot?: ReactNode;
|
||||
};
|
||||
|
||||
@@ -67,7 +66,6 @@ type HeaderItem = {
|
||||
currentPage: Page | null,
|
||||
status: {
|
||||
isPublic: boolean;
|
||||
isPreview: boolean;
|
||||
}
|
||||
) => boolean;
|
||||
};
|
||||
@@ -81,8 +79,8 @@ const HeaderRightItems: Record<HeaderRightItemName, HeaderItem> = {
|
||||
},
|
||||
[HeaderRightItemName.SyncUser]: {
|
||||
Component: SyncUser,
|
||||
availableWhen: (_, currentPage, { isPublic, isPreview }) => {
|
||||
return !isPublic && !isPreview;
|
||||
availableWhen: (_, currentPage, { isPublic }) => {
|
||||
return !isPublic;
|
||||
},
|
||||
},
|
||||
[HeaderRightItemName.ShareMenu]: {
|
||||
@@ -105,8 +103,8 @@ const HeaderRightItems: Record<HeaderRightItemName, HeaderItem> = {
|
||||
},
|
||||
[HeaderRightItemName.EditorOptionMenu]: {
|
||||
Component: EditorOptionMenu,
|
||||
availableWhen: (_, currentPage, { isPublic, isPreview }) => {
|
||||
return !isPublic && !isPreview;
|
||||
availableWhen: (_, currentPage, { isPublic }) => {
|
||||
return !isPublic;
|
||||
},
|
||||
},
|
||||
[HeaderRightItemName.WindowsAppControls]: {
|
||||
@@ -216,7 +214,6 @@ export const Header = forwardRef<
|
||||
([name, { availableWhen, Component }]) => {
|
||||
if (
|
||||
availableWhen(props.workspace, props.currentPage, {
|
||||
isPreview: props.isPreview,
|
||||
isPublic: props.isPublic,
|
||||
})
|
||||
) {
|
||||
@@ -224,7 +221,6 @@ export const Header = forwardRef<
|
||||
<Component
|
||||
workspace={props.workspace}
|
||||
currentPage={props.currentPage}
|
||||
isPreview={props.isPreview}
|
||||
isPublic={props.isPublic}
|
||||
key={name}
|
||||
/>
|
||||
|
||||
@@ -18,7 +18,7 @@ import * as styles from './styles.css';
|
||||
|
||||
export type WorkspaceHeaderProps = BaseHeaderProps;
|
||||
|
||||
export const WorkspaceHeader: FC<
|
||||
export const BlockSuiteEditorHeader: FC<
|
||||
PropsWithChildren<WorkspaceHeaderProps> & HTMLAttributes<HTMLDivElement>
|
||||
> = (props): ReactElement => {
|
||||
const { workspace, currentPage, children, isPublic } = props;
|
||||
@@ -62,4 +62,4 @@ export const WorkspaceHeader: FC<
|
||||
);
|
||||
};
|
||||
|
||||
WorkspaceHeader.displayName = 'BlockSuiteEditorHeader';
|
||||
BlockSuiteEditorHeader.displayName = 'BlockSuiteEditorHeader';
|
||||
|
||||
@@ -13,16 +13,13 @@ import { startTransition, useCallback } from 'react';
|
||||
import { currentEditorAtom, workspacePreferredModeAtom } from '../atoms';
|
||||
import type { AffineOfficialWorkspace } from '../shared';
|
||||
import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor';
|
||||
import { WorkspaceHeader } from './blocksuite/workspace-header';
|
||||
|
||||
export type PageDetailEditorProps = {
|
||||
isPublic?: boolean;
|
||||
isPreview?: boolean;
|
||||
workspace: AffineOfficialWorkspace;
|
||||
pageId: string;
|
||||
onInit: (page: Page, editor: Readonly<EditorContainer>) => void;
|
||||
onLoad?: (page: Page, editor: EditorContainer) => () => void;
|
||||
header?: React.ReactNode;
|
||||
};
|
||||
|
||||
export const PageDetailEditor: React.FC<PageDetailEditorProps> = ({
|
||||
@@ -30,9 +27,7 @@ export const PageDetailEditor: React.FC<PageDetailEditorProps> = ({
|
||||
pageId,
|
||||
onInit,
|
||||
onLoad,
|
||||
header,
|
||||
isPublic,
|
||||
isPreview,
|
||||
}) => {
|
||||
const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
|
||||
const page = useBlockSuiteWorkspacePage(blockSuiteWorkspace, pageId);
|
||||
@@ -52,14 +47,6 @@ export const PageDetailEditor: React.FC<PageDetailEditorProps> = ({
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
</Head>
|
||||
<WorkspaceHeader
|
||||
isPublic={isPublic ?? false}
|
||||
isPreview={isPreview ?? false}
|
||||
workspace={workspace}
|
||||
currentPage={page}
|
||||
>
|
||||
{header}
|
||||
</WorkspaceHeader>
|
||||
<Editor
|
||||
style={{
|
||||
height: 'calc(100% - 52px)',
|
||||
|
||||
127
apps/web/src/components/workspace-header.tsx
Normal file
127
apps/web/src/components/workspace-header.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
import { Button } from '@affine/component';
|
||||
import {
|
||||
FilterList,
|
||||
SaveViewButton,
|
||||
useAllPageSetting,
|
||||
ViewList,
|
||||
} from '@affine/component/page-list';
|
||||
import { config } from '@affine/env';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import type { WorkspaceHeaderProps } from '@affine/workspace/type';
|
||||
import { WorkspaceFlavour, WorkspaceSubPath } from '@affine/workspace/type';
|
||||
import {
|
||||
DeleteTemporarilyIcon,
|
||||
FolderIcon,
|
||||
SettingsIcon,
|
||||
ShareIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import type { ReactElement } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import { BlockSuiteEditorHeader } from './blocksuite/workspace-header';
|
||||
import { WorkspaceTitle } from './pure/workspace-title';
|
||||
|
||||
export function WorkspaceHeader({
|
||||
currentWorkspace,
|
||||
currentEntry,
|
||||
}: WorkspaceHeaderProps<WorkspaceFlavour>): ReactElement {
|
||||
const setting = useAllPageSetting();
|
||||
const t = useAFFiNEI18N();
|
||||
if ('subPath' in currentEntry) {
|
||||
if (currentEntry.subPath === WorkspaceSubPath.ALL) {
|
||||
const leftSlot = config.enableAllPageFilter && (
|
||||
<ViewList setting={setting}></ViewList>
|
||||
);
|
||||
const filterContainer = config.enableAllPageFilter &&
|
||||
setting.currentView.filterList.length > 0 && (
|
||||
<div style={{ padding: 12, display: 'flex' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<FilterList
|
||||
value={setting.currentView.filterList}
|
||||
onChange={filterList =>
|
||||
setting.changeView(
|
||||
{
|
||||
...setting.currentView,
|
||||
filterList,
|
||||
},
|
||||
setting.currentViewIndex
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{setting.currentViewIndex == null ? (
|
||||
<SaveViewButton
|
||||
init={setting.currentView.filterList}
|
||||
onConfirm={setting.createView}
|
||||
></SaveViewButton>
|
||||
) : (
|
||||
<Button onClick={() => setting.selectView()}>
|
||||
Back to all
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WorkspaceTitle
|
||||
workspace={currentWorkspace}
|
||||
currentPage={null}
|
||||
isPublic={false}
|
||||
icon={<FolderIcon />}
|
||||
leftSlot={leftSlot}
|
||||
>
|
||||
{t['All pages']()}
|
||||
</WorkspaceTitle>
|
||||
{filterContainer}
|
||||
</>
|
||||
);
|
||||
} else if (currentEntry.subPath === WorkspaceSubPath.SETTING) {
|
||||
return (
|
||||
<WorkspaceTitle
|
||||
workspace={currentWorkspace}
|
||||
currentPage={null}
|
||||
isPublic={false}
|
||||
icon={<SettingsIcon />}
|
||||
>
|
||||
{t['Workspace Settings']()}
|
||||
</WorkspaceTitle>
|
||||
);
|
||||
} else if (currentEntry.subPath === WorkspaceSubPath.SHARED) {
|
||||
return (
|
||||
<WorkspaceTitle
|
||||
workspace={currentWorkspace}
|
||||
currentPage={null}
|
||||
isPublic={false}
|
||||
icon={<ShareIcon />}
|
||||
>
|
||||
{t['Shared Pages']()}
|
||||
</WorkspaceTitle>
|
||||
);
|
||||
} else if (currentEntry.subPath === WorkspaceSubPath.TRASH) {
|
||||
return (
|
||||
<WorkspaceTitle
|
||||
workspace={currentWorkspace}
|
||||
currentPage={null}
|
||||
isPublic={false}
|
||||
icon={<DeleteTemporarilyIcon />}
|
||||
>
|
||||
{t['Trash']()}
|
||||
</WorkspaceTitle>
|
||||
);
|
||||
}
|
||||
} else if ('pageId' in currentEntry) {
|
||||
const pageId = currentEntry.pageId;
|
||||
const isPublic = currentWorkspace.flavour === WorkspaceFlavour.PUBLIC;
|
||||
return (
|
||||
<BlockSuiteEditorHeader
|
||||
isPublic={isPublic}
|
||||
workspace={currentWorkspace}
|
||||
currentPage={currentWorkspace.blockSuiteWorkspace.getPage(pageId)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <></>;
|
||||
}
|
||||
Reference in New Issue
Block a user