mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-21 08:17:10 +08:00
feat(core): new all docs list ui (#12102)
### New all docs list ui close AF-2531, AF-2585, AF-2586, AF-2580 ### What changed - a new `display-menu` component - properties visibility - quick actions visibility - extend DocPropertyType definition - `showInDocList`: configure whether to show in doc and how to show (stack | inline) - `docListProperty`: define how to render property in doc - `groupHeader`: define how to render group header when grouped - implement all properties's `docListProperty` renderer and `groupHeader` renderer - new `docs-view` component - render doc in `card` | `list` view - split doc card into minimal components for reuse in list and card views, as well as visibility control - implement docs-list with `<Masonry />` and multi-view support - for list view, make masonry column count always `1` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Redesigned document explorer with multiple view modes (list, grid, masonry), grouping, selection, and multi-delete. - Added customizable display properties and quick actions (favorite, trash, split view, new tab, select) for documents. - Introduced new group header and document item components with improved styling and interaction. - Enabled dynamic rendering of document properties including tags, dates, users, templates, and themes. - Added filtering support for trash status and enhanced localization for UI elements. - Introduced drag handle size customization and expanded masonry layout configurability. - Added contextual "More" menu with document operations like favorite, info, duplicate, and trash. - Implemented shared context for explorer state management and multi-selection logic. - **Enhancements** - Improved virtual scrolling with active item tracking and configurable preload and debounce settings. - Responsive, theme-aware styling applied across explorer and property components. - Configurable UI elements and quick actions via user preferences. - Enhanced error messages for unsupported property types in filters. - Refined padding and layout calculations in masonry component for better visual consistency. - Avatar and date components refactored for explicit prop-driven rendering and customization. - **Bug Fixes** - Improved error messages for unsupported property types in filters. - **Documentation** - Added new localization keys and updated language completeness for new features. - **Chores** - Modularized workspace property types with list and group header display components. - Consolidated imports and enhanced code maintainability. - Added new CSS styling modules for explorer components and workspace property types. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -38,8 +38,6 @@ export type { ServerConfig } from './types';
|
||||
// eslint-disable-next-line simple-import-sort/imports
|
||||
import { type Framework } from '@toeverything/infra';
|
||||
|
||||
import { DocScope } from '../doc/scopes/doc';
|
||||
import { DocService } from '../doc/services/doc';
|
||||
import { GlobalCache, GlobalState } from '../storage/providers/global';
|
||||
import { GlobalStateService } from '../storage/services/global';
|
||||
import { UrlService } from '../url';
|
||||
@@ -101,7 +99,7 @@ import { DocCreatedByService } from './services/doc-created-by';
|
||||
import { DocUpdatedByService } from './services/doc-updated-by';
|
||||
import { DocCreatedByUpdatedBySyncService } from './services/doc-created-by-updated-by-sync';
|
||||
import { WorkspacePermissionService } from '../permissions';
|
||||
import { DocsService } from '../doc';
|
||||
import { DocScope, DocService, DocsService } from '../doc';
|
||||
import { DocCreatedByUpdatedBySyncStore } from './stores/doc-created-by-updated-by-sync';
|
||||
|
||||
export function configureCloudModule(framework: Framework) {
|
||||
|
||||
@@ -7,7 +7,15 @@ import { useLayoutEffect, useMemo } from 'react';
|
||||
import { PublicUserService } from '../services/public-user';
|
||||
import * as styles from './public-user.css';
|
||||
|
||||
export const PublicUserLabel = ({ id }: { id: string }) => {
|
||||
export const PublicUserLabel = ({
|
||||
id,
|
||||
size = 20,
|
||||
showName = true,
|
||||
}: {
|
||||
id: string;
|
||||
size?: number;
|
||||
showName?: boolean;
|
||||
}) => {
|
||||
const serverService = useCurrentServerService();
|
||||
const publicUser = useMemo(() => {
|
||||
return serverService?.scope.get(PublicUserService);
|
||||
@@ -28,10 +36,16 @@ export const PublicUserLabel = ({ id }: { id: string }) => {
|
||||
}
|
||||
|
||||
if (user?.removed) {
|
||||
return (
|
||||
return showName ? (
|
||||
<span className={styles.publicUserLabelRemoved}>
|
||||
{t['Unknown User']()}
|
||||
</span>
|
||||
) : (
|
||||
<Avatar
|
||||
size={size}
|
||||
name={t['Unknown User']()}
|
||||
className={styles.publicUserLabelAvatar}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,10 +54,10 @@ export const PublicUserLabel = ({ id }: { id: string }) => {
|
||||
<Avatar
|
||||
url={user?.avatar}
|
||||
name={user?.name ?? ''}
|
||||
size={20}
|
||||
size={size}
|
||||
className={styles.publicUserLabelAvatar}
|
||||
/>
|
||||
{user?.name}
|
||||
{showName && user?.name}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ export class PropertyFilterProvider extends Service implements FilterProvider {
|
||||
FilterProvider('property:' + type)
|
||||
);
|
||||
if (!provider) {
|
||||
throw new Error('Unsupported property type');
|
||||
throw new Error(`Unsupported property type: ${type}`);
|
||||
}
|
||||
return provider.filter$(params);
|
||||
})
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { DocsService } from '@affine/core/modules/doc';
|
||||
import { Service } from '@toeverything/infra';
|
||||
import { map, type Observable } from 'rxjs';
|
||||
|
||||
import type { FilterProvider } from '../../provider';
|
||||
import type { FilterParams } from '../../types';
|
||||
|
||||
export class TrashFilterProvider extends Service implements FilterProvider {
|
||||
constructor(private readonly docsService: DocsService) {
|
||||
super();
|
||||
}
|
||||
filter$(params: FilterParams): Observable<Set<string>> {
|
||||
if (params.value === 'true') {
|
||||
return this.docsService.allTrashDocIds$().pipe(map(ids => new Set(ids)));
|
||||
} else {
|
||||
return this.docsService
|
||||
.allNonTrashDocIds$()
|
||||
.pipe(map(ids => new Set(ids)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import { PropertyFilterProvider } from './impls/filters/property';
|
||||
import { SystemFilterProvider } from './impls/filters/system';
|
||||
import { TagsFilterProvider } from './impls/filters/tags';
|
||||
import { TextPropertyFilterProvider } from './impls/filters/text';
|
||||
import { TrashFilterProvider } from './impls/filters/trash';
|
||||
import { UpdatedAtFilterProvider } from './impls/filters/updated-at';
|
||||
import { UpdatedByFilterProvider } from './impls/filters/updated-by';
|
||||
import { CheckboxPropertyGroupByProvider } from './impls/group-by/checkbox';
|
||||
@@ -79,6 +80,7 @@ export function configureCollectionRulesModule(framework: Framework) {
|
||||
DocPrimaryModeFilterProvider,
|
||||
[DocsService]
|
||||
)
|
||||
.impl(FilterProvider('system:trash'), TrashFilterProvider, [DocsService])
|
||||
.impl(FilterProvider('property:date'), DatePropertyFilterProvider, [
|
||||
DocsService,
|
||||
])
|
||||
|
||||
@@ -69,6 +69,14 @@ export class DocsService extends Service {
|
||||
return this.store.watchAllDocTagIds();
|
||||
}
|
||||
|
||||
allNonTrashDocIds$() {
|
||||
return this.store.watchNonTrashDocIds();
|
||||
}
|
||||
|
||||
allTrashDocIds$() {
|
||||
return this.store.watchTrashDocIds();
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly store: DocsStore,
|
||||
private readonly docPropertiesStore: DocPropertiesStore,
|
||||
|
||||
Reference in New Issue
Block a user