mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-23 13:29:02 +08:00
feat(core): new all docs header (#12182)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a new grouped document explorer with a masonry layout, advanced filtering, and multi-select capabilities. - Added a floating toolbar for batch actions, such as deleting multiple documents. - Implemented a feature flag to enable the new "All Docs" page, allowing gradual rollout. - Added a new navigation component with links for Docs, Collections, and Tags. - Introduced a display menu button supporting additional menu properties. - **Enhancements** - Redesigned navigation headers across document, collection, and tag pages for improved consistency and usability. - Added new display and view toggling options for document lists. - Improved styling and responsiveness for explorer and header components. - Updated context to support dynamic view switching in the document explorer. - **Bug Fixes** - Updated context and prop types to enhance state management and user interactions. - **Refactor** - Replaced legacy page list views with a modern, grouped explorer interface. - Simplified and modularized header components and styles for better maintainability. - Removed workspace-specific controls from document headers to focus on explorer functionality. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import { createContext, type Dispatch, type SetStateAction } from 'react';
|
||||
|
||||
import type { DocListItemView } from './docs-view/doc-list-item';
|
||||
import type { ExplorerPreference } from './types';
|
||||
|
||||
export type DocExplorerContextType = ExplorerPreference & {
|
||||
view: 'list' | 'grid' | 'masonry';
|
||||
view: DocListItemView;
|
||||
setView: Dispatch<SetStateAction<DocListItemView>>;
|
||||
groups: Array<{ key: string; items: string[] }>;
|
||||
collapsed: string[];
|
||||
selectMode?: boolean;
|
||||
@@ -17,6 +19,7 @@ export type DocExplorerContextType = ExplorerPreference & {
|
||||
|
||||
export const DocExplorerContext = createContext<DocExplorerContextType>({
|
||||
view: 'list',
|
||||
setView: () => {},
|
||||
groups: [],
|
||||
collapsed: [],
|
||||
selectedDocIds: [],
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { Button, Divider, Menu, MenuSub } from '@affine/component';
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Menu,
|
||||
type MenuProps,
|
||||
MenuSub,
|
||||
} from '@affine/component';
|
||||
import type {
|
||||
GroupByParams,
|
||||
OrderByParams,
|
||||
@@ -92,12 +98,14 @@ export const ExplorerDisplayMenuButton = ({
|
||||
style,
|
||||
className,
|
||||
preference,
|
||||
menuProps,
|
||||
onChange,
|
||||
}: {
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
preference: ExplorerPreference;
|
||||
onChange?: (preference: ExplorerPreference) => void;
|
||||
menuProps?: Omit<MenuProps, 'items' | 'children'>;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
return (
|
||||
@@ -105,6 +113,7 @@ export const ExplorerDisplayMenuButton = ({
|
||||
items={
|
||||
<ExplorerDisplayMenu preference={preference} onChange={onChange} />
|
||||
}
|
||||
{...menuProps}
|
||||
>
|
||||
<Button
|
||||
className={className}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const container = style({
|
||||
display: 'flex',
|
||||
gap: 12,
|
||||
alignItems: 'center',
|
||||
fontSize: 18,
|
||||
lineHeight: '26px',
|
||||
fontWeight: 600,
|
||||
});
|
||||
|
||||
export const item = style({
|
||||
color: cssVarV2.text.secondary,
|
||||
selectors: {
|
||||
'&[data-active="true"]': {
|
||||
color: cssVarV2.text.primary,
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
import { WorkbenchLink } from '@affine/core/modules/workbench';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
|
||||
import * as styles from './navigation.css';
|
||||
|
||||
const items = [
|
||||
{
|
||||
value: 'docs',
|
||||
label: 'com.affine.docs.header',
|
||||
testId: 'workspace-docs-button',
|
||||
to: '/all',
|
||||
},
|
||||
{
|
||||
value: 'collections',
|
||||
label: 'com.affine.collections.header',
|
||||
testId: 'workspace-collections-button',
|
||||
to: '/collection',
|
||||
},
|
||||
{
|
||||
value: 'tags',
|
||||
label: 'Tags',
|
||||
testId: 'workspace-tags-button',
|
||||
to: '/tag',
|
||||
},
|
||||
] as const;
|
||||
|
||||
type NavigationKey = (typeof items)[number]['value'];
|
||||
|
||||
export const ExplorerNavigation = ({ active }: { active: NavigationKey }) => {
|
||||
const t = useI18n();
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{items.map(item => (
|
||||
<WorkbenchLink
|
||||
key={item.value}
|
||||
data-testid={item.testId}
|
||||
data-active={active === item.value}
|
||||
to={item.to}
|
||||
className={styles.item}
|
||||
>
|
||||
{t[item.label]()}
|
||||
</WorkbenchLink>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user