feat(core): adjust the display settings to be independent for each workspace (#6502)
close TOV-793
This commit is contained in:
@@ -7,12 +7,10 @@ import {
|
|||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||||
import { ArrowDownSmallIcon, DoneIcon } from '@blocksuite/icons';
|
import { ArrowDownSmallIcon, DoneIcon } from '@blocksuite/icons';
|
||||||
import { useAtom } from 'jotai';
|
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { pageGroupByTypeAtom } from '../group-definitions';
|
|
||||||
import type { PageDisplayProperties, PageGroupByType } from '../types';
|
import type { PageDisplayProperties, PageGroupByType } from '../types';
|
||||||
import { usePageDisplayProperties } from '../use-page-display-properties';
|
import { useAllDocDisplayProperties } from '../use-all-doc-display-properties';
|
||||||
import * as styles from './page-display-menu.css';
|
import * as styles from './page-display-menu.css';
|
||||||
|
|
||||||
type GroupOption = {
|
type GroupOption = {
|
||||||
@@ -22,13 +20,21 @@ type GroupOption = {
|
|||||||
|
|
||||||
export const PageDisplayMenu = () => {
|
export const PageDisplayMenu = () => {
|
||||||
const t = useAFFiNEI18N();
|
const t = useAFFiNEI18N();
|
||||||
const [group, setGroup] = useAtom(pageGroupByTypeAtom);
|
const [workspaceProperties, setProperties] = useAllDocDisplayProperties();
|
||||||
const [properties, setProperties] = usePageDisplayProperties();
|
|
||||||
const handleSelect = useCallback(
|
const handleSelect = useCallback(
|
||||||
(value: PageGroupByType) => {
|
(value: PageGroupByType) => {
|
||||||
setGroup(value);
|
setProperties('groupBy', value);
|
||||||
},
|
},
|
||||||
[setGroup]
|
[setProperties]
|
||||||
|
);
|
||||||
|
const handleSetDocDisplayProperties = useCallback(
|
||||||
|
(key: keyof PageDisplayProperties) => {
|
||||||
|
setProperties('displayProperties', {
|
||||||
|
...workspaceProperties.displayProperties,
|
||||||
|
[key]: !workspaceProperties.displayProperties[key],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setProperties, workspaceProperties.displayProperties]
|
||||||
);
|
);
|
||||||
const propertyOptions: Array<{
|
const propertyOptions: Array<{
|
||||||
key: keyof PageDisplayProperties;
|
key: keyof PageDisplayProperties;
|
||||||
@@ -38,26 +44,26 @@ export const PageDisplayMenu = () => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
key: 'bodyNotes',
|
key: 'bodyNotes',
|
||||||
onClick: () => setProperties('bodyNotes', !properties['bodyNotes']),
|
onClick: () => handleSetDocDisplayProperties('bodyNotes'),
|
||||||
label: t['com.affine.page.display.display-properties.body-notes'](),
|
label: t['com.affine.page.display.display-properties.body-notes'](),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'tags',
|
key: 'tags',
|
||||||
onClick: () => setProperties('tags', !properties['tags']),
|
onClick: () => handleSetDocDisplayProperties('tags'),
|
||||||
label: t['Tags'](),
|
label: t['Tags'](),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'createDate',
|
key: 'createDate',
|
||||||
onClick: () => setProperties('createDate', !properties['createDate']),
|
onClick: () => handleSetDocDisplayProperties('createDate'),
|
||||||
label: t['Created'](),
|
label: t['Created'](),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'updatedDate',
|
key: 'updatedDate',
|
||||||
onClick: () => setProperties('updatedDate', !properties['updatedDate']),
|
onClick: () => handleSetDocDisplayProperties('updatedDate'),
|
||||||
label: t['Updated'](),
|
label: t['Updated'](),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [properties, setProperties, t]);
|
}, [handleSetDocDisplayProperties, t]);
|
||||||
|
|
||||||
const items = useMemo(() => {
|
const items = useMemo(() => {
|
||||||
const groupOptions: GroupOption[] = [
|
const groupOptions: GroupOption[] = [
|
||||||
@@ -87,8 +93,12 @@ export const PageDisplayMenu = () => {
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
key={option.value}
|
key={option.value}
|
||||||
onSelect={() => handleSelect(option.value)}
|
onSelect={() => handleSelect(option.value)}
|
||||||
data-active={group === option.value}
|
data-active={workspaceProperties.groupBy === option.value}
|
||||||
endFix={group === option.value ? <DoneIcon fontSize={'20px'} /> : null}
|
endFix={
|
||||||
|
workspaceProperties.groupBy === option.value ? (
|
||||||
|
<DoneIcon fontSize={'20px'} />
|
||||||
|
) : null
|
||||||
|
}
|
||||||
className={styles.subMenuItem}
|
className={styles.subMenuItem}
|
||||||
data-testid={`group-by-${option.value}`}
|
data-testid={`group-by-${option.value}`}
|
||||||
>
|
>
|
||||||
@@ -97,7 +107,7 @@ export const PageDisplayMenu = () => {
|
|||||||
));
|
));
|
||||||
|
|
||||||
const currentGroupType = groupOptions.find(
|
const currentGroupType = groupOptions.find(
|
||||||
option => option.value === group
|
option => option.value === workspaceProperties.groupBy
|
||||||
)?.label;
|
)?.label;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -131,7 +141,7 @@ export const PageDisplayMenu = () => {
|
|||||||
key={option.label}
|
key={option.label}
|
||||||
className={styles.propertyButton}
|
className={styles.propertyButton}
|
||||||
onClick={option.onClick}
|
onClick={option.onClick}
|
||||||
data-active={properties[option.key]}
|
data-active={!!workspaceProperties.displayProperties[option.key]}
|
||||||
data-testid={`property-${option.key}`}
|
data-testid={`property-${option.key}`}
|
||||||
>
|
>
|
||||||
{option.label}
|
{option.label}
|
||||||
@@ -140,7 +150,13 @@ export const PageDisplayMenu = () => {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}, [group, handleSelect, properties, propertyOptions, t]);
|
}, [
|
||||||
|
handleSelect,
|
||||||
|
propertyOptions,
|
||||||
|
t,
|
||||||
|
workspaceProperties.displayProperties,
|
||||||
|
workspaceProperties.groupBy,
|
||||||
|
]);
|
||||||
return (
|
return (
|
||||||
<Menu
|
<Menu
|
||||||
items={items}
|
items={items}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useCallback, useMemo } from 'react';
|
|||||||
import { WorkbenchLink } from '../../../modules/workbench/view/workbench-link';
|
import { WorkbenchLink } from '../../../modules/workbench/view/workbench-link';
|
||||||
import { selectionStateAtom, useAtom } from '../scoped-atoms';
|
import { selectionStateAtom, useAtom } from '../scoped-atoms';
|
||||||
import type { DraggableTitleCellData, PageListItemProps } from '../types';
|
import type { DraggableTitleCellData, PageListItemProps } from '../types';
|
||||||
import { usePageDisplayProperties } from '../use-page-display-properties';
|
import { useAllDocDisplayProperties } from '../use-all-doc-display-properties';
|
||||||
import { ColWrapper, formatDate, stopPropagation } from '../utils';
|
import { ColWrapper, formatDate, stopPropagation } from '../utils';
|
||||||
import * as styles from './page-list-item.css';
|
import * as styles from './page-list-item.css';
|
||||||
import { PageTags } from './page-tags';
|
import { PageTags } from './page-tags';
|
||||||
@@ -18,7 +18,7 @@ const ListTitleCell = ({
|
|||||||
title,
|
title,
|
||||||
preview,
|
preview,
|
||||||
}: Pick<PageListItemProps, 'title' | 'preview'>) => {
|
}: Pick<PageListItemProps, 'title' | 'preview'>) => {
|
||||||
const [displayProperties] = usePageDisplayProperties();
|
const [displayProperties] = useAllDocDisplayProperties();
|
||||||
return (
|
return (
|
||||||
<div data-testid="page-list-item-title" className={styles.titleCell}>
|
<div data-testid="page-list-item-title" className={styles.titleCell}>
|
||||||
<div
|
<div
|
||||||
@@ -27,7 +27,7 @@ const ListTitleCell = ({
|
|||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
{preview && displayProperties['bodyNotes'] ? (
|
{preview && displayProperties.displayProperties.bodyNotes ? (
|
||||||
<div
|
<div
|
||||||
data-testid="page-list-item-preview-text"
|
data-testid="page-list-item-preview-text"
|
||||||
className={styles.titleCellPreview}
|
className={styles.titleCellPreview}
|
||||||
@@ -127,7 +127,7 @@ const PageListOperationsCell = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const PageListItem = (props: PageListItemProps) => {
|
export const PageListItem = (props: PageListItemProps) => {
|
||||||
const [displayProperties] = usePageDisplayProperties();
|
const [displayProperties] = useAllDocDisplayProperties();
|
||||||
const pageTitleElement = useMemo(() => {
|
const pageTitleElement = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.dragPageItemOverlay}>
|
<div className={styles.dragPageItemOverlay}>
|
||||||
@@ -190,7 +190,7 @@ export const PageListItem = (props: PageListItemProps) => {
|
|||||||
flex={4}
|
flex={4}
|
||||||
alignment="end"
|
alignment="end"
|
||||||
style={{ overflow: 'visible' }}
|
style={{ overflow: 'visible' }}
|
||||||
hidden={!displayProperties['tags']}
|
hidden={!displayProperties.displayProperties.tags}
|
||||||
>
|
>
|
||||||
<PageTagsCell pageId={props.pageId} />
|
<PageTagsCell pageId={props.pageId} />
|
||||||
</ColWrapper>
|
</ColWrapper>
|
||||||
@@ -199,7 +199,7 @@ export const PageListItem = (props: PageListItemProps) => {
|
|||||||
flex={1}
|
flex={1}
|
||||||
alignment="end"
|
alignment="end"
|
||||||
hideInSmallContainer
|
hideInSmallContainer
|
||||||
hidden={!displayProperties['createDate']}
|
hidden={!displayProperties.displayProperties.createDate}
|
||||||
>
|
>
|
||||||
<PageCreateDateCell createDate={props.createDate} />
|
<PageCreateDateCell createDate={props.createDate} />
|
||||||
</ColWrapper>
|
</ColWrapper>
|
||||||
@@ -207,7 +207,7 @@ export const PageListItem = (props: PageListItemProps) => {
|
|||||||
flex={1}
|
flex={1}
|
||||||
alignment="end"
|
alignment="end"
|
||||||
hideInSmallContainer
|
hideInSmallContainer
|
||||||
hidden={!displayProperties['updatedDate']}
|
hidden={!displayProperties.displayProperties.updatedDate}
|
||||||
>
|
>
|
||||||
<PageUpdatedDateCell updatedDate={props.updatedDate} />
|
<PageUpdatedDateCell updatedDate={props.updatedDate} />
|
||||||
</ColWrapper>
|
</ColWrapper>
|
||||||
|
|||||||
@@ -5,24 +5,13 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
|||||||
import { FavoritedIcon, FavoriteIcon } from '@blocksuite/icons';
|
import { FavoritedIcon, FavoriteIcon } from '@blocksuite/icons';
|
||||||
import type { DocMeta } from '@blocksuite/store';
|
import type { DocMeta } from '@blocksuite/store';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import { useAtomValue } from 'jotai';
|
|
||||||
import { atomWithStorage } from 'jotai/utils';
|
|
||||||
import { type ReactNode, useMemo } from 'react';
|
import { type ReactNode, useMemo } from 'react';
|
||||||
|
|
||||||
import * as styles from './group-definitions.css';
|
import * as styles from './group-definitions.css';
|
||||||
import type {
|
import type { DateKey, ItemGroupDefinition, ListItem } from './types';
|
||||||
DateKey,
|
import { useAllDocDisplayProperties } from './use-all-doc-display-properties';
|
||||||
ItemGroupDefinition,
|
|
||||||
ListItem,
|
|
||||||
PageGroupByType,
|
|
||||||
} from './types';
|
|
||||||
import { betweenDaysAgo, withinDaysAgo } from './utils';
|
import { betweenDaysAgo, withinDaysAgo } from './utils';
|
||||||
|
|
||||||
export const pageGroupByTypeAtom = atomWithStorage<PageGroupByType>(
|
|
||||||
'pageGroupByType',
|
|
||||||
'updatedDate'
|
|
||||||
);
|
|
||||||
|
|
||||||
const GroupLabel = ({
|
const GroupLabel = ({
|
||||||
label,
|
label,
|
||||||
count,
|
count,
|
||||||
@@ -189,7 +178,7 @@ export const useFavoriteGroupDefinitions = <
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const usePageItemGroupDefinitions = () => {
|
export const usePageItemGroupDefinitions = () => {
|
||||||
const key = useAtomValue(pageGroupByTypeAtom);
|
const [workspaceProperties] = useAllDocDisplayProperties();
|
||||||
const tagGroupDefinitions = useTagGroupDefinitions();
|
const tagGroupDefinitions = useTagGroupDefinitions();
|
||||||
const createDateGroupDefinitions = useDateGroupDefinitions('createDate');
|
const createDateGroupDefinitions = useDateGroupDefinitions('createDate');
|
||||||
const updatedDateGroupDefinitions = useDateGroupDefinitions('updatedDate');
|
const updatedDateGroupDefinitions = useDateGroupDefinitions('updatedDate');
|
||||||
@@ -206,12 +195,12 @@ export const usePageItemGroupDefinitions = () => {
|
|||||||
// add more here later
|
// add more here later
|
||||||
// todo: some page group definitions maybe dynamic
|
// todo: some page group definitions maybe dynamic
|
||||||
};
|
};
|
||||||
return itemGroupDefinitions[key];
|
return itemGroupDefinitions[workspaceProperties.groupBy];
|
||||||
}, [
|
}, [
|
||||||
createDateGroupDefinitions,
|
createDateGroupDefinitions,
|
||||||
favouriteGroupDefinitions,
|
favouriteGroupDefinitions,
|
||||||
key,
|
|
||||||
tagGroupDefinitions,
|
tagGroupDefinitions,
|
||||||
updatedDateGroupDefinitions,
|
updatedDateGroupDefinitions,
|
||||||
|
workspaceProperties.groupBy,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import { useMemo } from 'react';
|
|||||||
|
|
||||||
import { ListHeaderTitleCell } from './page-header';
|
import { ListHeaderTitleCell } from './page-header';
|
||||||
import type { HeaderColDef } from './types';
|
import type { HeaderColDef } from './types';
|
||||||
import { usePageDisplayProperties } from './use-page-display-properties';
|
import { useAllDocDisplayProperties } from './use-all-doc-display-properties';
|
||||||
export const usePageHeaderColsDef = (): HeaderColDef[] => {
|
export const usePageHeaderColsDef = (): HeaderColDef[] => {
|
||||||
const [displayProperties] = usePageDisplayProperties();
|
const [displayProperties] = useAllDocDisplayProperties();
|
||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
@@ -20,7 +21,7 @@ export const usePageHeaderColsDef = (): HeaderColDef[] => {
|
|||||||
content: <Trans i18nKey="Tags" />,
|
content: <Trans i18nKey="Tags" />,
|
||||||
flex: 3,
|
flex: 3,
|
||||||
alignment: 'end',
|
alignment: 'end',
|
||||||
hidden: !displayProperties['tags'],
|
hidden: !displayProperties.displayProperties.tags,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'createDate',
|
key: 'createDate',
|
||||||
@@ -29,7 +30,7 @@ export const usePageHeaderColsDef = (): HeaderColDef[] => {
|
|||||||
sortable: true,
|
sortable: true,
|
||||||
alignment: 'end',
|
alignment: 'end',
|
||||||
hideInSmallContainer: true,
|
hideInSmallContainer: true,
|
||||||
hidden: !displayProperties['createDate'],
|
hidden: !displayProperties.displayProperties.createDate,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'updatedDate',
|
key: 'updatedDate',
|
||||||
@@ -38,7 +39,7 @@ export const usePageHeaderColsDef = (): HeaderColDef[] => {
|
|||||||
sortable: true,
|
sortable: true,
|
||||||
alignment: 'end',
|
alignment: 'end',
|
||||||
hideInSmallContainer: true,
|
hideInSmallContainer: true,
|
||||||
hidden: !displayProperties['updatedDate'],
|
hidden: !displayProperties.displayProperties.updatedDate,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'actions',
|
key: 'actions',
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ export * from './page-group';
|
|||||||
export * from './page-header';
|
export * from './page-header';
|
||||||
export * from './tags';
|
export * from './tags';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
export * from './use-all-doc-display-properties';
|
||||||
export * from './use-collection-manager';
|
export * from './use-collection-manager';
|
||||||
export * from './use-filtered-page-metas';
|
export * from './use-filtered-page-metas';
|
||||||
export * from './use-page-display-properties';
|
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
export * from './view';
|
export * from './view';
|
||||||
export * from './virtualized-list';
|
export * from './virtualized-list';
|
||||||
|
|||||||
@@ -168,3 +168,8 @@ export type PageDisplayProperties = {
|
|||||||
createDate: boolean;
|
createDate: boolean;
|
||||||
updatedDate: boolean;
|
updatedDate: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DisplayProperties = {
|
||||||
|
groupBy: PageGroupByType;
|
||||||
|
displayProperties: PageDisplayProperties;
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { useService, Workspace } from '@toeverything/infra';
|
||||||
|
import { useAtom } from 'jotai';
|
||||||
|
import { atomWithStorage } from 'jotai/utils';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
DisplayProperties,
|
||||||
|
PageDisplayProperties,
|
||||||
|
PageGroupByType,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
export const displayPropertiesAtom = atomWithStorage<{
|
||||||
|
[workspaceId: string]: DisplayProperties;
|
||||||
|
}>('allDocDisplayProperties', {});
|
||||||
|
|
||||||
|
const defaultProps: DisplayProperties = {
|
||||||
|
groupBy: 'updatedDate',
|
||||||
|
displayProperties: {
|
||||||
|
bodyNotes: true,
|
||||||
|
tags: true,
|
||||||
|
createDate: true,
|
||||||
|
updatedDate: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useAllDocDisplayProperties = (): [
|
||||||
|
DisplayProperties,
|
||||||
|
(
|
||||||
|
key: keyof DisplayProperties,
|
||||||
|
value: PageGroupByType | PageDisplayProperties
|
||||||
|
) => void,
|
||||||
|
] => {
|
||||||
|
const workspace = useService(Workspace);
|
||||||
|
const [properties, setProperties] = useAtom(displayPropertiesAtom);
|
||||||
|
|
||||||
|
const workspaceProperties = properties[workspace.id] || defaultProps;
|
||||||
|
|
||||||
|
const onChange = useCallback(
|
||||||
|
(
|
||||||
|
key: keyof DisplayProperties,
|
||||||
|
value: PageGroupByType | PageDisplayProperties
|
||||||
|
) => {
|
||||||
|
setProperties(prev => ({
|
||||||
|
...prev,
|
||||||
|
[workspace.id]: {
|
||||||
|
...(prev[workspace.id] || defaultProps),
|
||||||
|
[key]: value,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
[setProperties, workspace.id]
|
||||||
|
);
|
||||||
|
|
||||||
|
return [workspaceProperties, onChange];
|
||||||
|
};
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import { useAtom } from 'jotai';
|
|
||||||
import { atomWithStorage } from 'jotai/utils';
|
|
||||||
import { useCallback } from 'react';
|
|
||||||
|
|
||||||
import type { PageDisplayProperties } from './types';
|
|
||||||
|
|
||||||
export const pageDisplayPropertiesAtom = atomWithStorage<PageDisplayProperties>(
|
|
||||||
'pageDisplayProperties',
|
|
||||||
{
|
|
||||||
bodyNotes: true,
|
|
||||||
tags: true,
|
|
||||||
createDate: true,
|
|
||||||
updatedDate: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const usePageDisplayProperties = (): [
|
|
||||||
PageDisplayProperties,
|
|
||||||
(key: keyof PageDisplayProperties, value: boolean) => void,
|
|
||||||
] => {
|
|
||||||
const [properties, setProperties] = useAtom(pageDisplayPropertiesAtom);
|
|
||||||
const onChange = useCallback(
|
|
||||||
(key: keyof PageDisplayProperties, value: boolean) => {
|
|
||||||
setProperties(prev => ({ ...prev, [key]: value }));
|
|
||||||
},
|
|
||||||
[setProperties]
|
|
||||||
);
|
|
||||||
return [properties, onChange];
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user