fix(core): improve tag list performance (#11353)
This commit is contained in:
@@ -407,7 +407,6 @@ function tagMetaToListItemProp(
|
|||||||
to: props.rowAsLink && !props.selectable ? `/tag/${item.id}` : undefined,
|
to: props.rowAsLink && !props.selectable ? `/tag/${item.id}` : undefined,
|
||||||
onClick: toggleSelection,
|
onClick: toggleSelection,
|
||||||
color: item.color,
|
color: item.color,
|
||||||
pageCount: item.pageCount,
|
|
||||||
operations: props.operationsRenderer?.(item),
|
operations: props.operationsRenderer?.(item),
|
||||||
selectable: props.selectable,
|
selectable: props.selectable,
|
||||||
selected: props.selectedIds?.includes(item.id),
|
selected: props.selectedIds?.includes(item.id),
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ import type { TagListItemProps } from '../types';
|
|||||||
import { ColWrapper } from '../utils';
|
import { ColWrapper } from '../utils';
|
||||||
import * as styles from './tag-list-item.css';
|
import * as styles from './tag-list-item.css';
|
||||||
|
|
||||||
const TagListTitleCell = ({
|
const TagListTitleCell = ({ title }: Pick<TagListItemProps, 'title'>) => {
|
||||||
title,
|
|
||||||
}: Pick<TagListItemProps, 'title' | 'pageCount'>) => {
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
return (
|
return (
|
||||||
<div data-testid="tag-list-item-title" className={styles.titleCell}>
|
<div data-testid="tag-list-item-title" className={styles.titleCell}>
|
||||||
@@ -119,7 +117,7 @@ export const TagListItem = (props: TagListItemProps) => {
|
|||||||
/>
|
/>
|
||||||
<ListIconCell color={props.color} />
|
<ListIconCell color={props.color} />
|
||||||
</div>
|
</div>
|
||||||
<TagListTitleCell title={props.title} pageCount={props.pageCount} />
|
<TagListTitleCell title={props.title} />
|
||||||
</ColWrapper>
|
</ColWrapper>
|
||||||
<ColWrapper
|
<ColWrapper
|
||||||
flex={4}
|
flex={4}
|
||||||
@@ -147,7 +145,7 @@ export const TagListItem = (props: TagListItemProps) => {
|
|||||||
/>
|
/>
|
||||||
<ListIconCell color={props.color} />
|
<ListIconCell color={props.color} />
|
||||||
</div>
|
</div>
|
||||||
<TagListTitleCell title={props.title} pageCount={props.pageCount} />
|
<TagListTitleCell title={props.title} />
|
||||||
</div>
|
</div>
|
||||||
</CustomDragPreview>
|
</CustomDragPreview>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ export type TagListItemProps = {
|
|||||||
tagId: string;
|
tagId: string;
|
||||||
color: string;
|
color: string;
|
||||||
title: ReactNode; // using ReactNode to allow for rich content rendering
|
title: ReactNode; // using ReactNode to allow for rich content rendering
|
||||||
pageCount?: number;
|
|
||||||
createDate?: Date | number;
|
createDate?: Date | number;
|
||||||
updatedDate?: Date | number;
|
updatedDate?: Date | number;
|
||||||
to?: To; // whether or not to render this item as a Link
|
to?: To; // whether or not to render this item as a Link
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ export class TagList extends Entity {
|
|||||||
id: tag.id,
|
id: tag.id,
|
||||||
title: get(tag.value$),
|
title: get(tag.value$),
|
||||||
color: get(tag.color$),
|
color: get(tag.color$),
|
||||||
pageCount: get(tag.pageIds$).length,
|
|
||||||
createDate: get(tag.createDate$),
|
createDate: get(tag.createDate$),
|
||||||
updatedDate: get(tag.updateDate$),
|
updatedDate: get(tag.updateDate$),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,14 +64,5 @@ export class Tag extends Entity<{ id: string }> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
readonly pageIds$ = LiveData.from(this.store.watchTagPageIds(this.id), []);
|
||||||
* @deprecated performance issue here, use with caution until it is fixed
|
|
||||||
* @fixme(EYHN): page.meta$ has performance issue
|
|
||||||
*/
|
|
||||||
readonly pageIds$ = LiveData.computed(get => {
|
|
||||||
const pages = get(this.docs.list.docs$);
|
|
||||||
return pages
|
|
||||||
.filter(page => get(page.meta$).tags?.includes(this.id))
|
|
||||||
.map(page => page.id);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
import type { Tag, Tag as TagSchema } from '@affine/env/filter';
|
import type { Tag, Tag as TagSchema } from '@affine/env/filter';
|
||||||
import type { DocsPropertiesMeta } from '@blocksuite/affine/store';
|
import type { DocsPropertiesMeta } from '@blocksuite/affine/store';
|
||||||
import { LiveData, Store } from '@toeverything/infra';
|
import {
|
||||||
|
LiveData,
|
||||||
|
Store,
|
||||||
|
yjsObserveByPath,
|
||||||
|
yjsObserveDeep,
|
||||||
|
} from '@toeverything/infra';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import { Observable } from 'rxjs';
|
import { map, Observable, switchMap } from 'rxjs';
|
||||||
|
import { Array as YArray } from 'yjs';
|
||||||
|
|
||||||
import type { WorkspaceService } from '../../workspace';
|
import type { WorkspaceService } from '../../workspace';
|
||||||
|
|
||||||
@@ -119,4 +125,32 @@ export class TagStore extends Store {
|
|||||||
...tagInfo,
|
...tagInfo,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchTagPageIds(id: string) {
|
||||||
|
return yjsObserveByPath(
|
||||||
|
this.workspaceService.workspace.rootYDoc.getMap('meta'),
|
||||||
|
'pages'
|
||||||
|
).pipe(
|
||||||
|
switchMap(yjsObserveDeep),
|
||||||
|
map(meta => {
|
||||||
|
if (meta instanceof YArray) {
|
||||||
|
return meta
|
||||||
|
.map(v => {
|
||||||
|
const tags = v.get('tags') as YArray<string> | undefined;
|
||||||
|
if (tags instanceof YArray) {
|
||||||
|
for (const tagId of tags.toArray()) {
|
||||||
|
if (tagId === id) {
|
||||||
|
return v.get('id') as string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.filter(Boolean) as string[];
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user