mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-23 21:38:44 +08:00
feat(core): add default filter rules for all docs (#12197)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a filter to exclude empty journals from document collections. - Added a live-updating list of non-trashed document IDs for improved document management. - **Improvements** - Default filters in the document explorer have been updated to show all items, including trashed ones, unless filters are applied. - Enhanced filtering in workspace views to automatically exclude empty journals and trashed documents. - Increased the responsiveness of grouped document updates for a smoother user experience. - **Bug Fixes** - Removed unnecessary debug output from the document synchronization, member search, session management, and member selector components. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -27,14 +27,7 @@ export const createDocExplorerContext = () =>
|
||||
selectMode$: new LiveData<boolean>(false),
|
||||
selectedDocIds$: new LiveData<string[]>([]),
|
||||
prevCheckAnchorId$: new LiveData<string | null>(null),
|
||||
filters$: new LiveData<ExplorerPreference['filters']>([
|
||||
{
|
||||
type: 'system',
|
||||
key: 'trash',
|
||||
value: 'false',
|
||||
method: 'is',
|
||||
},
|
||||
]),
|
||||
filters$: new LiveData<ExplorerPreference['filters']>([]),
|
||||
groupBy$: new LiveData<ExplorerPreference['groupBy']>(undefined),
|
||||
orderBy$: new LiveData<ExplorerPreference['orderBy']>(undefined),
|
||||
displayProperties$: new LiveData<ExplorerPreference['displayProperties']>(
|
||||
|
||||
@@ -90,7 +90,6 @@ export const MemberSelector = ({
|
||||
if (value.length > 0) {
|
||||
setFocusedInlineIndex(selected.length);
|
||||
}
|
||||
console.log('onInputChange', value);
|
||||
debouncedSearch(value.trim());
|
||||
},
|
||||
[debouncedSearch, selected.length]
|
||||
|
||||
@@ -143,7 +143,25 @@ export const AllPage = () => {
|
||||
const collectionRulesService = useService(CollectionRulesService);
|
||||
useEffect(() => {
|
||||
const subscription = collectionRulesService
|
||||
.watch(filters ?? [], groupBy, orderBy)
|
||||
.watch(
|
||||
[
|
||||
...(filters ?? []),
|
||||
{
|
||||
type: 'system',
|
||||
key: 'empty-journal',
|
||||
method: 'is',
|
||||
value: 'false',
|
||||
},
|
||||
{
|
||||
type: 'system',
|
||||
key: 'trash',
|
||||
method: 'is',
|
||||
value: 'false',
|
||||
},
|
||||
],
|
||||
groupBy,
|
||||
orderBy
|
||||
)
|
||||
.subscribe({
|
||||
next: result => {
|
||||
explorerContextValue.groups$.next(result.groups);
|
||||
|
||||
@@ -141,7 +141,6 @@ export class AuthSession extends Entity {
|
||||
|
||||
async updateLabel(label: string) {
|
||||
await this.store.updateLabel(label);
|
||||
console.log('updateLabel');
|
||||
await this.waitForRevalidation();
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,6 @@ export class DocCreatedByUpdatedBySyncService extends Service {
|
||||
.pipe(
|
||||
map(allDocsCreatedBy => {
|
||||
let missingCreatedBy = false;
|
||||
console.log(allDocsCreatedBy);
|
||||
for (const createdBy of allDocsCreatedBy.values()) {
|
||||
if (!createdBy) {
|
||||
missingCreatedBy = true;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { DocsService } from '@affine/core/modules/doc';
|
||||
import { Service } from '@toeverything/infra';
|
||||
import { combineLatest, map, type Observable } from 'rxjs';
|
||||
|
||||
import type { FilterProvider } from '../../provider';
|
||||
import type { FilterParams } from '../../types';
|
||||
|
||||
export class EmptyJournalFilterProvider
|
||||
extends Service
|
||||
implements FilterProvider
|
||||
{
|
||||
constructor(private readonly docsService: DocsService) {
|
||||
super();
|
||||
}
|
||||
|
||||
filter$(params: FilterParams): Observable<Set<string>> {
|
||||
return combineLatest([
|
||||
this.docsService.allDocsUpdatedDate$(),
|
||||
this.docsService.propertyValues$('journal'),
|
||||
]).pipe(
|
||||
map(([updatedAts, journalValues]) => {
|
||||
const match = new Set<string>();
|
||||
|
||||
for (const { id, updatedDate } of updatedAts) {
|
||||
const isJournal = journalValues.get(id);
|
||||
const isEmptyJournal = updatedDate === undefined && isJournal;
|
||||
if (
|
||||
(params.value === 'false' && !isEmptyJournal) ||
|
||||
(params.value === 'true' && isEmptyJournal)
|
||||
) {
|
||||
match.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import { CreatedAtFilterProvider } from './impls/filters/created-at';
|
||||
import { CreatedByFilterProvider } from './impls/filters/created-by';
|
||||
import { DatePropertyFilterProvider } from './impls/filters/date';
|
||||
import { DocPrimaryModeFilterProvider } from './impls/filters/doc-primary-mode';
|
||||
import { EmptyJournalFilterProvider } from './impls/filters/empty-journal';
|
||||
import { JournalFilterProvider } from './impls/filters/journal';
|
||||
import { PropertyFilterProvider } from './impls/filters/property';
|
||||
import { SystemFilterProvider } from './impls/filters/system';
|
||||
@@ -114,6 +115,9 @@ export function configureCollectionRulesModule(framework: Framework) {
|
||||
.impl(FilterProvider('system:updatedBy'), UpdatedByFilterProvider, [
|
||||
DocsService,
|
||||
])
|
||||
.impl(FilterProvider('system:empty-journal'), EmptyJournalFilterProvider, [
|
||||
DocsService,
|
||||
])
|
||||
// --------------- Group By ---------------
|
||||
.impl(GroupByProvider('system'), SystemGroupByProvider)
|
||||
.impl(GroupByProvider('property'), PropertyGroupByProvider, [
|
||||
|
||||
@@ -159,7 +159,7 @@ export class CollectionRulesService extends Service {
|
||||
}[];
|
||||
filterErrors: any[];
|
||||
}> = grouped$.pipe(
|
||||
throttleTime(500), // throttle the results to avoid too many re-renders
|
||||
throttleTime(300, undefined, { leading: false, trailing: true }), // throttle the results to avoid too many re-renders
|
||||
map(({ grouped, ordered, filtered, filterErrors }) => {
|
||||
const result: { key: string; items: string[] }[] = [];
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ export class DocRecordList extends Entity {
|
||||
[]
|
||||
);
|
||||
|
||||
public readonly nonTrashDocsIds$ = LiveData.from<string[]>(
|
||||
this.store.watchNonTrashDocIds(),
|
||||
[]
|
||||
);
|
||||
|
||||
public readonly isReady$ = LiveData.from(
|
||||
this.store.watchDocListReady(),
|
||||
false
|
||||
|
||||
@@ -147,7 +147,7 @@ export class DocsStore extends Store {
|
||||
this.workspaceService.workspace.rootYDoc.getMap('meta'),
|
||||
'pages'
|
||||
).pipe(
|
||||
switchMap(yjsObserveDeep),
|
||||
switchMap(pages => yjsObservePath(pages, '*.trash')),
|
||||
map(meta => {
|
||||
if (meta instanceof YArray) {
|
||||
return meta
|
||||
@@ -165,7 +165,7 @@ export class DocsStore extends Store {
|
||||
this.workspaceService.workspace.rootYDoc.getMap('meta'),
|
||||
'pages'
|
||||
).pipe(
|
||||
switchMap(yjsObserveDeep),
|
||||
switchMap(pages => yjsObservePath(pages, '*.trash')),
|
||||
map(meta => {
|
||||
if (meta instanceof YArray) {
|
||||
return meta
|
||||
|
||||
@@ -66,7 +66,6 @@ export class MemberSearchService extends Service {
|
||||
}
|
||||
|
||||
search(searchText?: string) {
|
||||
console.log('search', searchText);
|
||||
this.reset();
|
||||
this.searchText$.setValue(searchText ?? '');
|
||||
this.loadMore();
|
||||
|
||||
Reference in New Issue
Block a user