From ac4954f7adfcca3054def3c3ce654529c4f9ccd6 Mon Sep 17 00:00:00 2001 From: EYHN Date: Fri, 23 May 2025 16:46:02 +0900 Subject: [PATCH] feat(core): add more collection rules (#12458) --- .../system-property-types/edgeless-theme.tsx | 5 + .../components/system-property-types/index.ts | 84 +++++++++++++ .../integration-type.tsx | 98 +++++++++++++++ .../system-property-types/page-width.tsx | 5 + .../system-property-types/template.tsx | 5 + .../workspace-property-types/checkbox.tsx | 6 +- .../edgeless-theme.tsx | 114 +++++++++++++++++- .../workspace-property-types/index.ts | 43 ++++++- .../workspace-property-types/journal.tsx | 6 +- .../workspace-property-types/page-width.tsx | 111 ++++++++++++++++- .../workspace-property-types/template.tsx | 94 ++++++++++++++- .../impls/filters/edgeless-theme.ts | 46 +++++++ .../impls/filters/integration-type.ts | 45 +++++++ .../impls/filters/page-width.ts | 43 +++++++ .../impls/filters/template.ts | 43 +++++++ .../impls/group-by/edgeless-theme.ts | 35 ++++++ .../impls/group-by/integration-type.ts | 38 ++++++ .../impls/group-by/page-width.ts | 35 ++++++ .../impls/group-by/template.ts | 35 ++++++ .../impls/order-by/edgeless-theme.ts | 39 ++++++ .../impls/order-by/integration-type.ts | 41 +++++++ .../impls/order-by/page-width.ts | 39 ++++++ .../impls/order-by/template.ts | 39 ++++++ .../src/modules/collection-rules/index.ts | 91 ++++++++++++++ .../src/modules/workspace-property/types.ts | 6 +- .../i18n/src/i18n-completenesses.json | 32 ++--- packages/frontend/i18n/src/i18n.gen.ts | 24 ++++ packages/frontend/i18n/src/resources/en.json | 6 + 28 files changed, 1170 insertions(+), 38 deletions(-) create mode 100644 packages/frontend/core/src/components/system-property-types/edgeless-theme.tsx create mode 100644 packages/frontend/core/src/components/system-property-types/integration-type.tsx create mode 100644 packages/frontend/core/src/components/system-property-types/page-width.tsx create mode 100644 packages/frontend/core/src/components/system-property-types/template.tsx create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/filters/edgeless-theme.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/filters/integration-type.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/filters/page-width.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/filters/template.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/group-by/edgeless-theme.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/group-by/integration-type.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/group-by/page-width.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/group-by/template.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/order-by/edgeless-theme.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/order-by/integration-type.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/order-by/page-width.ts create mode 100644 packages/frontend/core/src/modules/collection-rules/impls/order-by/template.ts diff --git a/packages/frontend/core/src/components/system-property-types/edgeless-theme.tsx b/packages/frontend/core/src/components/system-property-types/edgeless-theme.tsx new file mode 100644 index 000000000..e3e288470 --- /dev/null +++ b/packages/frontend/core/src/components/system-property-types/edgeless-theme.tsx @@ -0,0 +1,5 @@ +export { + EdgelessThemeDocListProperty, + EdgelessThemeFilterValue, + EdgelessThemeGroupHeader, +} from '../workspace-property-types/edgeless-theme'; diff --git a/packages/frontend/core/src/components/system-property-types/index.ts b/packages/frontend/core/src/components/system-property-types/index.ts index ba5a09ae8..9c652aae4 100644 --- a/packages/frontend/core/src/components/system-property-types/index.ts +++ b/packages/frontend/core/src/components/system-property-types/index.ts @@ -3,11 +3,15 @@ import type { DocRecord } from '@affine/core/modules/doc'; import type { I18nString } from '@affine/i18n'; import { DateTimeIcon, + EdgelessIcon, FavoriteIcon, HistoryIcon, + IntegrationsIcon, + LongerIcon, MemberIcon, ShareIcon, TagIcon, + TemplateIcon, } from '@blocksuite/icons/rc'; import type { GroupHeaderProps } from '../explorer/types'; @@ -26,9 +30,29 @@ import { ModifiedByGroupHeader, UpdatedByDocListInlineProperty, } from './created-updated-by'; +import { + EdgelessThemeDocListProperty, + EdgelessThemeFilterValue, + EdgelessThemeGroupHeader, +} from './edgeless-theme'; import { FavoriteFilterValue } from './favorite'; +import { + IntegrationTypeDocListProperty, + IntegrationTypeFilterValue, + IntegrationTypeGroupHeader, +} from './integration-type'; +import { + PageWidthDocListProperty, + PageWidthFilterValue, + PageWidthGroupHeader, +} from './page-width'; import { SharedFilterValue } from './shared'; import { TagsDocListProperty, TagsFilterValue, TagsGroupHeader } from './tags'; +import { + TemplateDocListProperty, + TemplateFilterValue, + TemplateGroupHeader, +} from './template'; export const SystemPropertyTypes = { tags: { @@ -122,6 +146,66 @@ export const SystemPropertyTypes = { }, filterValue: SharedFilterValue, }, + edgelessTheme: { + icon: EdgelessIcon, + name: 'com.affine.page-properties.property.edgelessTheme', + showInDocList: 'stack', + allowInGroupBy: true, + allowInOrderBy: true, + docListProperty: EdgelessThemeDocListProperty, + groupHeader: EdgelessThemeGroupHeader, + filterMethod: { + is: 'com.affine.editCollection.rules.include.is', + 'is-not': 'com.affine.editCollection.rules.include.is-not', + }, + filterValue: EdgelessThemeFilterValue, + defaultFilter: { method: 'is', value: 'system' }, + }, + pageWidth: { + icon: LongerIcon, + name: 'com.affine.page-properties.property.pageWidth', + showInDocList: 'stack', + allowInGroupBy: true, + allowInOrderBy: true, + docListProperty: PageWidthDocListProperty, + groupHeader: PageWidthGroupHeader, + filterMethod: { + is: 'com.affine.editCollection.rules.include.is', + 'is-not': 'com.affine.editCollection.rules.include.is-not', + }, + filterValue: PageWidthFilterValue, + defaultFilter: { method: 'is', value: 'fullWidth' }, + }, + template: { + icon: TemplateIcon, + name: 'com.affine.page-properties.property.template', + showInDocList: 'stack', + allowInGroupBy: true, + allowInOrderBy: true, + docListProperty: TemplateDocListProperty, + groupHeader: TemplateGroupHeader, + filterMethod: { + is: 'com.affine.editCollection.rules.include.is', + 'is-not': 'com.affine.editCollection.rules.include.is-not', + }, + filterValue: TemplateFilterValue, + defaultFilter: { method: 'is', value: 'true' }, + }, + integrationType: { + icon: IntegrationsIcon, + name: 'com.affine.integration.integrations', + showInDocList: 'stack', + allowInGroupBy: true, + allowInOrderBy: true, + docListProperty: IntegrationTypeDocListProperty, + groupHeader: IntegrationTypeGroupHeader, + filterMethod: { + is: 'com.affine.editCollection.rules.include.is', + 'is-not': 'com.affine.editCollection.rules.include.is-not', + }, + filterValue: IntegrationTypeFilterValue, + defaultFilter: { method: 'is', value: 'readwise' }, + }, } as { [type: string]: { icon: React.FC>; diff --git a/packages/frontend/core/src/components/system-property-types/integration-type.tsx b/packages/frontend/core/src/components/system-property-types/integration-type.tsx new file mode 100644 index 000000000..9a719c5fc --- /dev/null +++ b/packages/frontend/core/src/components/system-property-types/integration-type.tsx @@ -0,0 +1,98 @@ +import { Menu, MenuItem, type MenuRef } from '@affine/component'; +import type { FilterParams } from '@affine/core/modules/collection-rules'; +import type { DocRecord } from '@affine/core/modules/doc'; +import { useI18n } from '@affine/i18n'; +import { IntegrationsIcon, ReadwiseIcon } from '@blocksuite/icons/rc'; +import { useLiveData } from '@toeverything/infra'; +import { useEffect, useRef } from 'react'; + +import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header'; +import { StackProperty } from '../explorer/docs-view/stack-property'; +import type { GroupHeaderProps } from '../explorer/types'; + +export const IntegrationTypeFilterValue = ({ + filter, + isDraft, + onDraftCompleted, + onChange, +}: { + filter: FilterParams; + isDraft?: boolean; + onDraftCompleted?: () => void; + onChange?: (filter: FilterParams) => void; +}) => { + const t = useI18n(); + const menuRef = useRef(null); + + useEffect(() => { + if (isDraft) { + menuRef.current?.changeOpen(true); + } + }, [isDraft]); + + return ( + { + onChange?.({ + ...filter, + value: 'readwise', + }); + }} + prefixIcon={} + selected={filter.value === 'readwise'} + > + {t['com.affine.integration.readwise.name']()} + + } + > + + {filter.value === 'readwise' + ? t['com.affine.integration.readwise.name']() + : filter.value} + + + ); +}; + +export const IntegrationTypeDocListProperty = ({ doc }: { doc: DocRecord }) => { + const integrationType = useLiveData(doc.property$('integrationType')); + + if (!integrationType) { + return null; + } + + return ( + : + } + > + {integrationType} + + ); +}; + +export const IntegrationTypeGroupHeader = ({ + groupId, + docCount, +}: GroupHeaderProps) => { + const t = useI18n(); + const text = + groupId === 'readwise' + ? t['com.affine.integration.readwise.name']() + : groupId + ? groupId + : 'No integrations'; + + return ( + + {text} + + ); +}; diff --git a/packages/frontend/core/src/components/system-property-types/page-width.tsx b/packages/frontend/core/src/components/system-property-types/page-width.tsx new file mode 100644 index 000000000..f0ceb960d --- /dev/null +++ b/packages/frontend/core/src/components/system-property-types/page-width.tsx @@ -0,0 +1,5 @@ +export { + PageWidthDocListProperty, + PageWidthFilterValue, + PageWidthGroupHeader, +} from '../workspace-property-types/page-width'; diff --git a/packages/frontend/core/src/components/system-property-types/template.tsx b/packages/frontend/core/src/components/system-property-types/template.tsx new file mode 100644 index 000000000..7b3c0c0c1 --- /dev/null +++ b/packages/frontend/core/src/components/system-property-types/template.tsx @@ -0,0 +1,5 @@ +export { + TemplateDocListProperty, + TemplateFilterValue, + TemplateGroupHeader, +} from '../workspace-property-types/template'; diff --git a/packages/frontend/core/src/components/workspace-property-types/checkbox.tsx b/packages/frontend/core/src/components/workspace-property-types/checkbox.tsx index 9195e58ae..c5883609b 100644 --- a/packages/frontend/core/src/components/workspace-property-types/checkbox.tsx +++ b/packages/frontend/core/src/components/workspace-property-types/checkbox.tsx @@ -123,7 +123,11 @@ export const CheckboxGroupHeader = ({ groupId, docCount, }: GroupHeaderProps) => { - const text = groupId === 'true' ? 'Checked' : 'Unchecked'; + const t = useI18n(); + const text = + groupId === 'true' + ? t['com.affine.all-docs.group.is-checked']() + : t['com.affine.all-docs.group.is-not-checked'](); return ( {text} diff --git a/packages/frontend/core/src/components/workspace-property-types/edgeless-theme.tsx b/packages/frontend/core/src/components/workspace-property-types/edgeless-theme.tsx index 21e5e635e..5dcd328b8 100644 --- a/packages/frontend/core/src/components/workspace-property-types/edgeless-theme.tsx +++ b/packages/frontend/core/src/components/workspace-property-types/edgeless-theme.tsx @@ -1,12 +1,20 @@ -import { PropertyValue, type RadioItem } from '@affine/component'; -import { DocService } from '@affine/core/modules/doc'; +import { + Menu, + MenuItem, + type MenuRef, + PropertyValue, + type RadioItem, +} from '@affine/component'; +import type { FilterParams } from '@affine/core/modules/collection-rules'; +import { type DocRecord, DocService } from '@affine/core/modules/doc'; import { useI18n } from '@affine/i18n'; import { EdgelessIcon } from '@blocksuite/icons/rc'; import { useLiveData, useService } from '@toeverything/infra'; -import { useCallback, useMemo } from 'react'; +import { useCallback, useEffect, useMemo, useRef } from 'react'; +import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header'; import { StackProperty } from '../explorer/docs-view/stack-property'; -import type { DocListPropertyProps } from '../explorer/types'; +import type { GroupHeaderProps } from '../explorer/types'; import type { PropertyValueProps } from '../properties/types'; import { PropertyRadioGroup } from '../properties/widgets/radio-group'; import * as styles from './edgeless-theme.css'; @@ -60,7 +68,7 @@ export const EdgelessThemeValue = ({ ); }; -export const EdgelessThemeDocListProperty = ({ doc }: DocListPropertyProps) => { +export const EdgelessThemeDocListProperty = ({ doc }: { doc: DocRecord }) => { const t = useI18n(); const edgelessTheme = useLiveData( doc.properties$.selector(p => p.edgelessColorTheme) @@ -76,3 +84,99 @@ export const EdgelessThemeDocListProperty = ({ doc }: DocListPropertyProps) => { ); }; + +export const EdgelessThemeFilterValue = ({ + filter, + isDraft, + onDraftCompleted, + onChange, +}: { + filter: FilterParams; + isDraft?: boolean; + onDraftCompleted?: () => void; + onChange?: (filter: FilterParams) => void; +}) => { + const t = useI18n(); + const menuRef = useRef(null); + + useEffect(() => { + if (isDraft) { + menuRef.current?.changeOpen(true); + } + }, [isDraft]); + + return ( + + { + onChange?.({ + ...filter, + value: 'system', + }); + }} + selected={filter.value === 'system'} + > + {t['com.affine.themeSettings.auto']()} + + { + onChange?.({ + ...filter, + value: 'light', + }); + }} + selected={filter.value === 'light'} + > + {t['com.affine.themeSettings.light']()} + + { + onChange?.({ + ...filter, + value: 'dark', + }); + }} + selected={filter.value === 'dark'} + > + {t['com.affine.themeSettings.dark']()} + + + } + > + + {filter.value === 'system' + ? t['com.affine.themeSettings.auto']() + : filter.value === 'light' + ? t['com.affine.themeSettings.light']() + : t['com.affine.themeSettings.dark']()} + + + ); +}; + +export const EdgelessThemeGroupHeader = ({ + groupId, + docCount, +}: GroupHeaderProps) => { + const t = useI18n(); + const text = + groupId === 'light' + ? t['com.affine.themeSettings.light']() + : groupId === 'dark' + ? t['com.affine.themeSettings.dark']() + : groupId === 'system' + ? t['com.affine.themeSettings.auto']() + : 'Default'; + + return ( + + {text} + + ); +}; diff --git a/packages/frontend/core/src/components/workspace-property-types/index.ts b/packages/frontend/core/src/components/workspace-property-types/index.ts index 1dc0f3ded..c807c72f0 100644 --- a/packages/frontend/core/src/components/workspace-property-types/index.ts +++ b/packages/frontend/core/src/components/workspace-property-types/index.ts @@ -60,6 +60,8 @@ import { } from './doc-primary-mode'; import { EdgelessThemeDocListProperty, + EdgelessThemeFilterValue, + EdgelessThemeGroupHeader, EdgelessThemeValue, } from './edgeless-theme'; import { @@ -69,14 +71,24 @@ import { JournalValue, } from './journal'; import { NumberDocListProperty, NumberValue } from './number'; -import { PageWidthDocListProperty, PageWidthValue } from './page-width'; +import { + PageWidthDocListProperty, + PageWidthFilterValue, + PageWidthGroupHeader, + PageWidthValue, +} from './page-width'; import { TagsDocListProperty, TagsFilterValue, TagsGroupHeader, TagsValue, } from './tags'; -import { TemplateDocListProperty, TemplateValue } from './template'; +import { + TemplateDocListProperty, + TemplateFilterValue, + TemplateGroupHeader, + TemplateValue, +} from './template'; import { TextDocListProperty, TextFilterValue, @@ -290,7 +302,16 @@ export const WorkspacePropertyTypes = { name: 'com.affine.page-properties.property.edgelessTheme', description: 'com.affine.page-properties.property.edgelessTheme.tooltips', showInDocList: 'stack', + allowInGroupBy: true, + allowInOrderBy: true, docListProperty: EdgelessThemeDocListProperty, + groupHeader: EdgelessThemeGroupHeader, + filterMethod: { + is: 'com.affine.editCollection.rules.include.is', + 'is-not': 'com.affine.editCollection.rules.include.is-not', + }, + filterValue: EdgelessThemeFilterValue, + defaultFilter: { method: 'is', value: 'system' }, }, pageWidth: { icon: LongerIcon, @@ -298,7 +319,16 @@ export const WorkspacePropertyTypes = { name: 'com.affine.page-properties.property.pageWidth', description: 'com.affine.page-properties.property.pageWidth.tooltips', showInDocList: 'stack', + allowInGroupBy: true, + allowInOrderBy: true, docListProperty: PageWidthDocListProperty, + groupHeader: PageWidthGroupHeader, + filterMethod: { + is: 'com.affine.editCollection.rules.include.is', + 'is-not': 'com.affine.editCollection.rules.include.is-not', + }, + filterValue: PageWidthFilterValue, + defaultFilter: { method: 'is', value: 'fullWidth' }, }, template: { icon: TemplateIcon, @@ -307,7 +337,16 @@ export const WorkspacePropertyTypes = { renameable: true, description: 'com.affine.page-properties.property.template.tooltips', showInDocList: 'stack', + allowInGroupBy: true, + allowInOrderBy: true, docListProperty: TemplateDocListProperty, + groupHeader: TemplateGroupHeader, + filterMethod: { + is: 'com.affine.editCollection.rules.include.is', + 'is-not': 'com.affine.editCollection.rules.include.is-not', + }, + filterValue: TemplateFilterValue, + defaultFilter: { method: 'is', value: 'true' }, }, unknown: { icon: PropertyIcon, diff --git a/packages/frontend/core/src/components/workspace-property-types/journal.tsx b/packages/frontend/core/src/components/workspace-property-types/journal.tsx index 5a5a4fb03..565d1af4c 100644 --- a/packages/frontend/core/src/components/workspace-property-types/journal.tsx +++ b/packages/frontend/core/src/components/workspace-property-types/journal.tsx @@ -254,7 +254,11 @@ export const JournalDocListProperty = ({ doc }: DocListPropertyProps) => { }; export const JournalGroupHeader = ({ groupId, docCount }: GroupHeaderProps) => { - const text = groupId === 'true' ? 'Journal' : 'Not Journal'; + const t = useI18n(); + const text = + groupId === 'true' + ? t['com.affine.all-docs.group.is-journal']() + : t['com.affine.all-docs.group.is-not-journal'](); return ( {text} diff --git a/packages/frontend/core/src/components/workspace-property-types/page-width.tsx b/packages/frontend/core/src/components/workspace-property-types/page-width.tsx index a92b8da01..4ffa24939 100644 --- a/packages/frontend/core/src/components/workspace-property-types/page-width.tsx +++ b/packages/frontend/core/src/components/workspace-property-types/page-width.tsx @@ -1,13 +1,21 @@ -import { PropertyValue, type RadioItem } from '@affine/component'; -import { DocService } from '@affine/core/modules/doc'; +import { + Menu, + MenuItem, + type MenuRef, + PropertyValue, + type RadioItem, +} from '@affine/component'; +import type { FilterParams } from '@affine/core/modules/collection-rules'; +import { type DocRecord, DocService } from '@affine/core/modules/doc'; import { EditorSettingService } from '@affine/core/modules/editor-setting'; import { useI18n } from '@affine/i18n'; import { LongerIcon } from '@blocksuite/icons/rc'; import { useLiveData, useService } from '@toeverything/infra'; -import { useCallback, useMemo } from 'react'; +import { useCallback, useEffect, useMemo, useRef } from 'react'; +import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header'; import { StackProperty } from '../explorer/docs-view/stack-property'; -import type { DocListPropertyProps } from '../explorer/types'; +import type { GroupHeaderProps } from '../explorer/types'; import type { PropertyValueProps } from '../properties/types'; import { PropertyRadioGroup } from '../properties/widgets/radio-group'; import { container } from './page-width.css'; @@ -62,7 +70,7 @@ export const PageWidthValue = ({ readonly }: PropertyValueProps) => { ); }; -export const PageWidthDocListProperty = ({ doc }: DocListPropertyProps) => { +export const PageWidthDocListProperty = ({ doc }: { doc: DocRecord }) => { const t = useI18n(); const pageWidth = useLiveData(doc.properties$.selector(p => p.pageWidth)); @@ -78,3 +86,96 @@ export const PageWidthDocListProperty = ({ doc }: DocListPropertyProps) => { ); }; + +export const PageWidthFilterValue = ({ + filter, + isDraft, + onDraftCompleted, + onChange, +}: { + filter: FilterParams; + isDraft?: boolean; + onDraftCompleted?: () => void; + onChange?: (filter: FilterParams) => void; +}) => { + const t = useI18n(); + const menuRef = useRef(null); + + useEffect(() => { + if (isDraft) { + menuRef.current?.changeOpen(true); + } + }, [isDraft]); + + return ( + + { + onChange?.({ + ...filter, + value: 'fullWidth', + }); + }} + selected={filter.value === 'fullWidth'} + > + {t[ + 'com.affine.settings.editorSettings.page.default-page-width.full-width' + ]()} + + { + onChange?.({ + ...filter, + value: 'standard', + }); + }} + selected={filter.value !== 'fullWidth'} + > + {t[ + 'com.affine.settings.editorSettings.page.default-page-width.standard' + ]()} + + + } + > + + {filter.value === 'fullWidth' + ? t[ + 'com.affine.settings.editorSettings.page.default-page-width.full-width' + ]() + : t[ + 'com.affine.settings.editorSettings.page.default-page-width.standard' + ]()} + + + ); +}; + +export const PageWidthGroupHeader = ({ + groupId, + docCount, +}: GroupHeaderProps) => { + const t = useI18n(); + const text = + groupId === 'fullWidth' + ? t[ + 'com.affine.settings.editorSettings.page.default-page-width.full-width' + ]() + : groupId === 'standard' + ? t[ + 'com.affine.settings.editorSettings.page.default-page-width.standard' + ]() + : 'Default'; + + return ( + + {text} + + ); +}; diff --git a/packages/frontend/core/src/components/workspace-property-types/template.tsx b/packages/frontend/core/src/components/workspace-property-types/template.tsx index 75ed3d16b..0b4ca6324 100644 --- a/packages/frontend/core/src/components/workspace-property-types/template.tsx +++ b/packages/frontend/core/src/components/workspace-property-types/template.tsx @@ -1,12 +1,20 @@ -import { Checkbox, PropertyValue } from '@affine/component'; -import { DocService } from '@affine/core/modules/doc'; +import { + Checkbox, + Menu, + MenuItem, + type MenuRef, + PropertyValue, +} from '@affine/component'; +import type { FilterParams } from '@affine/core/modules/collection-rules'; +import { type DocRecord, DocService } from '@affine/core/modules/doc'; import { useI18n } from '@affine/i18n'; import { TemplateIcon } from '@blocksuite/icons/rc'; import { useLiveData, useService } from '@toeverything/infra'; -import { type ChangeEvent, useCallback } from 'react'; +import { type ChangeEvent, useCallback, useEffect, useRef } from 'react'; +import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header'; import { StackProperty } from '../explorer/docs-view/stack-property'; -import type { DocListPropertyProps } from '../explorer/types'; +import type { GroupHeaderProps } from '../explorer/types'; import type { PropertyValueProps } from '../properties/types'; import * as styles from './template.css'; @@ -44,7 +52,7 @@ export const TemplateValue = ({ readonly }: PropertyValueProps) => { ); }; -export const TemplateDocListProperty = ({ doc }: DocListPropertyProps) => { +export const TemplateDocListProperty = ({ doc }: { doc: DocRecord }) => { const t = useI18n(); const isTemplate = useLiveData(doc.properties$.selector(p => p.isTemplate)); @@ -56,3 +64,79 @@ export const TemplateDocListProperty = ({ doc }: DocListPropertyProps) => { }>{t['Template']()} ); }; + +export const TemplateGroupHeader = ({ + groupId, + docCount, +}: GroupHeaderProps) => { + const t = useI18n(); + const text = + groupId === 'true' + ? t['com.affine.all-docs.group.is-template']() + : groupId === 'false' + ? t['com.affine.all-docs.group.is-not-template']() + : 'Default'; + + return ( + + {text} + + ); +}; + +export const TemplateFilterValue = ({ + filter, + isDraft, + onDraftCompleted, + onChange, +}: { + filter: FilterParams; + isDraft?: boolean; + onDraftCompleted?: () => void; + onChange?: (filter: FilterParams) => void; +}) => { + const menuRef = useRef(null); + + useEffect(() => { + if (isDraft) { + menuRef.current?.changeOpen(true); + } + }, [isDraft]); + + return ( + + { + onChange?.({ + ...filter, + value: 'true', + }); + }} + selected={filter.value === 'true'} + > + {'True'} + + { + onChange?.({ + ...filter, + value: 'false', + }); + }} + selected={filter.value !== 'true'} + > + {'False'} + + + } + > + {filter.value === 'true' ? 'True' : 'False'} + + ); +}; diff --git a/packages/frontend/core/src/modules/collection-rules/impls/filters/edgeless-theme.ts b/packages/frontend/core/src/modules/collection-rules/impls/filters/edgeless-theme.ts new file mode 100644 index 000000000..ec69bb597 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/filters/edgeless-theme.ts @@ -0,0 +1,46 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import type { WorkspacePropertyFilter } from '@affine/core/modules/workspace-property'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { FilterProvider } from '../../provider'; +import type { FilterParams } from '../../types'; + +export class EdgelessThemeFilterProvider + extends Service + implements FilterProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + filter$(params: FilterParams): Observable> { + const method = params.method as WorkspacePropertyFilter<'edgelessTheme'>; + if (method === 'is') { + return this.docsService.propertyValues$('edgelessColorTheme').pipe( + map(values => { + const match = new Set(); + for (const [id, value] of values) { + if ((value ?? 'system') === params.value) { + match.add(id); + } + } + return match; + }) + ); + } else if (method === 'is-not') { + return this.docsService.propertyValues$('edgelessColorTheme').pipe( + map(values => { + const match = new Set(); + for (const [id, value] of values) { + if ((value ?? 'system') !== params.value) { + match.add(id); + } + } + return match; + }) + ); + } + throw new Error(`Unsupported method: ${params.method}`); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/filters/integration-type.ts b/packages/frontend/core/src/modules/collection-rules/impls/filters/integration-type.ts new file mode 100644 index 000000000..0e6116092 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/filters/integration-type.ts @@ -0,0 +1,45 @@ +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 IntegrationTypeFilterProvider + extends Service + implements FilterProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + filter$(params: FilterParams): Observable> { + const method = params.method as 'is' | 'is-not'; + if (method === 'is') { + return this.docsService.propertyValues$('integrationType').pipe( + map(values => { + const match = new Set(); + for (const [id, value] of values) { + if (value === params.value) { + match.add(id); + } + } + return match; + }) + ); + } else if (method === 'is-not') { + return this.docsService.propertyValues$('integrationType').pipe( + map(values => { + const match = new Set(); + for (const [id, value] of values) { + if (value !== params.value) { + match.add(id); + } + } + return match; + }) + ); + } + throw new Error(`Unsupported method: ${params.method}`); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/filters/page-width.ts b/packages/frontend/core/src/modules/collection-rules/impls/filters/page-width.ts new file mode 100644 index 000000000..ac8a39b6e --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/filters/page-width.ts @@ -0,0 +1,43 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import type { WorkspacePropertyFilter } from '@affine/core/modules/workspace-property'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { FilterProvider } from '../../provider'; +import type { FilterParams } from '../../types'; + +export class PageWidthFilterProvider extends Service implements FilterProvider { + constructor(private readonly docsService: DocsService) { + super(); + } + + filter$(params: FilterParams): Observable> { + const method = params.method as WorkspacePropertyFilter<'pageWidth'>; + if (method === 'is') { + return this.docsService.propertyValues$('pageWidth').pipe( + map(values => { + const match = new Set(); + for (const [id, value] of values) { + if ((value ?? 'standard') === params.value) { + match.add(id); + } + } + return match; + }) + ); + } else if (method === 'is-not') { + return this.docsService.propertyValues$('pageWidth').pipe( + map(values => { + const match = new Set(); + for (const [id, value] of values) { + if ((value ?? 'standard') !== params.value) { + match.add(id); + } + } + return match; + }) + ); + } + throw new Error(`Unsupported method: ${params.method}`); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/filters/template.ts b/packages/frontend/core/src/modules/collection-rules/impls/filters/template.ts new file mode 100644 index 000000000..33a19161c --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/filters/template.ts @@ -0,0 +1,43 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import type { WorkspacePropertyFilter } from '@affine/core/modules/workspace-property'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { FilterProvider } from '../../provider'; +import type { FilterParams } from '../../types'; + +export class TemplateFilterProvider extends Service implements FilterProvider { + constructor(private readonly docsService: DocsService) { + super(); + } + + filter$(params: FilterParams): Observable> { + const method = params.method as WorkspacePropertyFilter<'template'>; + if (method === 'is') { + return this.docsService.propertyValues$('isTemplate').pipe( + map(values => { + const match = new Set(); + for (const [id, value] of values) { + if ((value ? 'true' : 'false') === params.value) { + match.add(id); + } + } + return match; + }) + ); + } else if (method === 'is-not') { + return this.docsService.propertyValues$('isTemplate').pipe( + map(values => { + const match = new Set(); + for (const [id, value] of values) { + if ((value ? 'true' : 'false') !== params.value) { + match.add(id); + } + } + return match; + }) + ); + } + throw new Error(`Unsupported method: ${params.method}`); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/group-by/edgeless-theme.ts b/packages/frontend/core/src/modules/collection-rules/impls/group-by/edgeless-theme.ts new file mode 100644 index 000000000..d34c94a2b --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/group-by/edgeless-theme.ts @@ -0,0 +1,35 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { GroupByProvider } from '../../provider'; +import type { GroupByParams } from '../../types'; + +export class EdgelessThemeGroupByProvider + extends Service + implements GroupByProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + groupBy$( + _items$: Observable>, + _params: GroupByParams + ): Observable>> { + return this.docsService.propertyValues$('edgelessColorTheme').pipe( + map(values => { + const result = new Map>(); + for (const [id, value] of values) { + const theme = value ?? 'system'; + if (!result.has(theme)) { + result.set(theme, new Set([id])); + } else { + result.get(theme)?.add(id); + } + } + return result; + }) + ); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/group-by/integration-type.ts b/packages/frontend/core/src/modules/collection-rules/impls/group-by/integration-type.ts new file mode 100644 index 000000000..79ec621d6 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/group-by/integration-type.ts @@ -0,0 +1,38 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { GroupByProvider } from '../../provider'; +import type { GroupByParams } from '../../types'; + +export class IntegrationTypeGroupByProvider + extends Service + implements GroupByProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + groupBy$( + _items$: Observable>, + _params: GroupByParams + ): Observable>> { + return this.docsService.propertyValues$('integrationType').pipe( + map(values => { + const result = new Map>(); + for (const [id, value] of values) { + const integrationType = value; + if (!integrationType) { + continue; + } + if (!result.has(integrationType)) { + result.set(integrationType, new Set([id])); + } else { + result.get(integrationType)?.add(id); + } + } + return result; + }) + ); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/group-by/page-width.ts b/packages/frontend/core/src/modules/collection-rules/impls/group-by/page-width.ts new file mode 100644 index 000000000..7c99ef511 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/group-by/page-width.ts @@ -0,0 +1,35 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { GroupByProvider } from '../../provider'; +import type { GroupByParams } from '../../types'; + +export class PageWidthGroupByProvider + extends Service + implements GroupByProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + groupBy$( + _items$: Observable>, + _params: GroupByParams + ): Observable>> { + return this.docsService.propertyValues$('pageWidth').pipe( + map(values => { + const result = new Map>(); + for (const [id, value] of values) { + const pageWidth = value ?? 'standard'; + if (!result.has(pageWidth)) { + result.set(pageWidth, new Set([id])); + } else { + result.get(pageWidth)?.add(id); + } + } + return result; + }) + ); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/group-by/template.ts b/packages/frontend/core/src/modules/collection-rules/impls/group-by/template.ts new file mode 100644 index 000000000..8f8299274 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/group-by/template.ts @@ -0,0 +1,35 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { GroupByProvider } from '../../provider'; +import type { GroupByParams } from '../../types'; + +export class TemplateGroupByProvider + extends Service + implements GroupByProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + groupBy$( + _items$: Observable>, + _params: GroupByParams + ): Observable>> { + return this.docsService.propertyValues$('isTemplate').pipe( + map(values => { + const result = new Map>(); + for (const [id, value] of values) { + const isTemplate = value ? 'true' : 'false'; + if (!result.has(isTemplate)) { + result.set(isTemplate, new Set([id])); + } else { + result.get(isTemplate)?.add(id); + } + } + return result; + }) + ); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/order-by/edgeless-theme.ts b/packages/frontend/core/src/modules/collection-rules/impls/order-by/edgeless-theme.ts new file mode 100644 index 000000000..43a3e8d69 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/order-by/edgeless-theme.ts @@ -0,0 +1,39 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { OrderByProvider } from '../../provider'; +import type { OrderByParams } from '../../types'; + +export class EdgelessThemeOrderByProvider + extends Service + implements OrderByProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + orderBy$( + _items$: Observable>, + params: OrderByParams + ): Observable { + return this.docsService.propertyValues$('edgelessColorTheme').pipe( + map(values => { + const docs = Array.from(values).map(([id, value]) => ({ + id, + theme: value ?? 'system', + })); + + if (params.desc) { + return docs + .sort((a, b) => b.theme.localeCompare(a.theme)) + .map(doc => doc.id); + } else { + return docs + .sort((a, b) => a.theme.localeCompare(b.theme)) + .map(doc => doc.id); + } + }) + ); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/order-by/integration-type.ts b/packages/frontend/core/src/modules/collection-rules/impls/order-by/integration-type.ts new file mode 100644 index 000000000..9dbcc38d1 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/order-by/integration-type.ts @@ -0,0 +1,41 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { OrderByProvider } from '../../provider'; +import type { OrderByParams } from '../../types'; + +export class IntegrationTypeOrderByProvider + extends Service + implements OrderByProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + orderBy$( + _items$: Observable>, + params: OrderByParams + ): Observable { + return this.docsService.propertyValues$('integrationType').pipe( + map(values => { + const docs = Array.from(values) + .filter(([, value]) => value !== undefined) + .map(([id, value]) => ({ + id, + type: value as string, + })); + + if (params.desc) { + return docs + .sort((a, b) => b.type.localeCompare(a.type)) + .map(doc => doc.id); + } else { + return docs + .sort((a, b) => a.type.localeCompare(b.type)) + .map(doc => doc.id); + } + }) + ); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/order-by/page-width.ts b/packages/frontend/core/src/modules/collection-rules/impls/order-by/page-width.ts new file mode 100644 index 000000000..0b93e6498 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/order-by/page-width.ts @@ -0,0 +1,39 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { OrderByProvider } from '../../provider'; +import type { OrderByParams } from '../../types'; + +export class PageWidthOrderByProvider + extends Service + implements OrderByProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + orderBy$( + _items$: Observable>, + params: OrderByParams + ): Observable { + return this.docsService.propertyValues$('pageWidth').pipe( + map(values => { + const docs = Array.from(values).map(([id, value]) => ({ + id, + width: value ?? 'standard', + })); + + if (params.desc) { + return docs + .sort((a, b) => b.width.localeCompare(a.width)) + .map(doc => doc.id); + } else { + return docs + .sort((a, b) => a.width.localeCompare(b.width)) + .map(doc => doc.id); + } + }) + ); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/impls/order-by/template.ts b/packages/frontend/core/src/modules/collection-rules/impls/order-by/template.ts new file mode 100644 index 000000000..7b4d56128 --- /dev/null +++ b/packages/frontend/core/src/modules/collection-rules/impls/order-by/template.ts @@ -0,0 +1,39 @@ +import type { DocsService } from '@affine/core/modules/doc'; +import { Service } from '@toeverything/infra'; +import { map, type Observable } from 'rxjs'; + +import type { OrderByProvider } from '../../provider'; +import type { OrderByParams } from '../../types'; + +export class TemplateOrderByProvider + extends Service + implements OrderByProvider +{ + constructor(private readonly docsService: DocsService) { + super(); + } + + orderBy$( + _items$: Observable>, + params: OrderByParams + ): Observable { + return this.docsService.propertyValues$('isTemplate').pipe( + map(values => { + const docs = Array.from(values).map(([id, value]) => ({ + id, + isTemplate: value ? 'true' : 'false', + })); + + if (params.desc) { + return docs + .sort((a, b) => b.isTemplate.localeCompare(a.isTemplate)) + .map(doc => doc.id); + } else { + return docs + .sort((a, b) => a.isTemplate.localeCompare(b.isTemplate)) + .map(doc => doc.id); + } + }) + ); + } +} diff --git a/packages/frontend/core/src/modules/collection-rules/index.ts b/packages/frontend/core/src/modules/collection-rules/index.ts index 4ba7b5b5e..ceab21983 100644 --- a/packages/frontend/core/src/modules/collection-rules/index.ts +++ b/packages/frontend/core/src/modules/collection-rules/index.ts @@ -12,13 +12,17 @@ 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 { EdgelessThemeFilterProvider } from './impls/filters/edgeless-theme'; import { EmptyJournalFilterProvider } from './impls/filters/empty-journal'; import { FavoriteFilterProvider } from './impls/filters/favorite'; +import { IntegrationTypeFilterProvider } from './impls/filters/integration-type'; import { JournalFilterProvider } from './impls/filters/journal'; +import { PageWidthFilterProvider } from './impls/filters/page-width'; import { PropertyFilterProvider } from './impls/filters/property'; import { SharedFilterProvider } from './impls/filters/shared'; import { SystemFilterProvider } from './impls/filters/system'; import { TagsFilterProvider } from './impls/filters/tags'; +import { TemplateFilterProvider } from './impls/filters/template'; import { TextPropertyFilterProvider } from './impls/filters/text'; import { TitleFilterProvider } from './impls/filters/title'; import { TrashFilterProvider } from './impls/filters/trash'; @@ -29,10 +33,14 @@ import { CreatedAtGroupByProvider } from './impls/group-by/created-at'; import { CreatedByGroupByProvider } from './impls/group-by/created-by'; import { DatePropertyGroupByProvider } from './impls/group-by/date'; import { DocPrimaryModeGroupByProvider } from './impls/group-by/doc-primary-mode'; +import { EdgelessThemeGroupByProvider } from './impls/group-by/edgeless-theme'; +import { IntegrationTypeGroupByProvider } from './impls/group-by/integration-type'; import { JournalGroupByProvider } from './impls/group-by/journal'; +import { PageWidthGroupByProvider } from './impls/group-by/page-width'; import { PropertyGroupByProvider } from './impls/group-by/property'; import { SystemGroupByProvider } from './impls/group-by/system'; import { TagsGroupByProvider } from './impls/group-by/tags'; +import { TemplateGroupByProvider } from './impls/group-by/template'; import { TextPropertyGroupByProvider } from './impls/group-by/text'; import { UpdatedAtGroupByProvider } from './impls/group-by/updated-at'; import { UpdatedByGroupByProvider } from './impls/group-by/updated-by'; @@ -41,10 +49,14 @@ import { CreatedAtOrderByProvider } from './impls/order-by/created-at'; import { CreatedByOrderByProvider } from './impls/order-by/created-by'; import { DatePropertyOrderByProvider } from './impls/order-by/date'; import { DocPrimaryModeOrderByProvider } from './impls/order-by/doc-primary-mode'; +import { EdgelessThemeOrderByProvider } from './impls/order-by/edgeless-theme'; +import { IntegrationTypeOrderByProvider } from './impls/order-by/integration-type'; import { JournalOrderByProvider } from './impls/order-by/journal'; +import { PageWidthOrderByProvider } from './impls/order-by/page-width'; import { PropertyOrderByProvider } from './impls/order-by/property'; import { SystemOrderByProvider } from './impls/order-by/system'; import { TagsOrderByProvider } from './impls/order-by/tags'; +import { TemplateOrderByProvider } from './impls/order-by/template'; import { TextPropertyOrderByProvider } from './impls/order-by/text'; import { UpdatedAtOrderByProvider } from './impls/order-by/updated-at'; import { UpdatedByOrderByProvider } from './impls/order-by/updated-by'; @@ -135,6 +147,31 @@ export function configureCollectionRulesModule(framework: Framework) { .impl(FilterProvider('system:title'), TitleFilterProvider, [ DocsSearchService, ]) + .impl( + FilterProvider('system:integrationType'), + IntegrationTypeFilterProvider, + [DocsService] + ) + .impl( + FilterProvider('property:edgelessTheme'), + EdgelessThemeFilterProvider, + [DocsService] + ) + .impl(FilterProvider('system:edgelessTheme'), EdgelessThemeFilterProvider, [ + DocsService, + ]) + .impl(FilterProvider('property:template'), TemplateFilterProvider, [ + DocsService, + ]) + .impl(FilterProvider('system:template'), TemplateFilterProvider, [ + DocsService, + ]) + .impl(FilterProvider('property:pageWidth'), PageWidthFilterProvider, [ + DocsService, + ]) + .impl(FilterProvider('system:pageWidth'), PageWidthFilterProvider, [ + DocsService, + ]) // --------------- Group By --------------- .impl(GroupByProvider('system'), SystemGroupByProvider) .impl(GroupByProvider('property'), PropertyGroupByProvider, [ @@ -199,6 +236,33 @@ export function configureCollectionRulesModule(framework: Framework) { .impl(GroupByProvider('system:updatedBy'), UpdatedByGroupByProvider, [ DocsService, ]) + .impl( + GroupByProvider('system:integrationType'), + IntegrationTypeGroupByProvider, + [DocsService] + ) + .impl( + GroupByProvider('property:edgelessTheme'), + EdgelessThemeGroupByProvider, + [DocsService] + ) + .impl( + GroupByProvider('system:edgelessTheme'), + EdgelessThemeGroupByProvider, + [DocsService] + ) + .impl(GroupByProvider('property:pageWidth'), PageWidthGroupByProvider, [ + DocsService, + ]) + .impl(GroupByProvider('system:pageWidth'), PageWidthGroupByProvider, [ + DocsService, + ]) + .impl(GroupByProvider('property:template'), TemplateGroupByProvider, [ + DocsService, + ]) + .impl(GroupByProvider('system:template'), TemplateGroupByProvider, [ + DocsService, + ]) // --------------- Order By --------------- .impl(OrderByProvider('system'), SystemOrderByProvider) .impl(OrderByProvider('property'), PropertyOrderByProvider, [ @@ -262,5 +326,32 @@ export function configureCollectionRulesModule(framework: Framework) { ]) .impl(OrderByProvider('system:updatedBy'), UpdatedByOrderByProvider, [ DocsService, + ]) + .impl( + OrderByProvider('system:integrationType'), + IntegrationTypeOrderByProvider, + [DocsService] + ) + .impl( + OrderByProvider('property:edgelessTheme'), + EdgelessThemeOrderByProvider, + [DocsService] + ) + .impl( + OrderByProvider('system:edgelessTheme'), + EdgelessThemeOrderByProvider, + [DocsService] + ) + .impl(OrderByProvider('property:pageWidth'), PageWidthOrderByProvider, [ + DocsService, + ]) + .impl(OrderByProvider('system:pageWidth'), PageWidthOrderByProvider, [ + DocsService, + ]) + .impl(OrderByProvider('property:template'), TemplateOrderByProvider, [ + DocsService, + ]) + .impl(OrderByProvider('system:template'), TemplateOrderByProvider, [ + DocsService, ]); } diff --git a/packages/frontend/core/src/modules/workspace-property/types.ts b/packages/frontend/core/src/modules/workspace-property/types.ts index d7e87bafc..1e7425464 100644 --- a/packages/frontend/core/src/modules/workspace-property/types.ts +++ b/packages/frontend/core/src/modules/workspace-property/types.ts @@ -39,9 +39,9 @@ export type WorkspacePropertyTypes = { createdAt: { filter: DateFilters }; docPrimaryMode: { filter: 'is' | 'is-not' }; journal: { filter: 'is' | 'is-not' }; - edgelessTheme: { filter: never }; - pageWidth: { filter: never }; - template: { filter: never }; + edgelessTheme: { filter: 'is' | 'is-not' }; + pageWidth: { filter: 'is' | 'is-not' }; + template: { filter: 'is' | 'is-not' }; unknown: { filter: never }; }; export type WorkspacePropertyType = keyof WorkspacePropertyTypes; diff --git a/packages/frontend/i18n/src/i18n-completenesses.json b/packages/frontend/i18n/src/i18n-completenesses.json index 2fb2beb2f..9e0aa95b4 100644 --- a/packages/frontend/i18n/src/i18n-completenesses.json +++ b/packages/frontend/i18n/src/i18n-completenesses.json @@ -1,26 +1,26 @@ { - "ar": 95, + "ar": 94, "ca": 4, "da": 4, - "de": 95, - "el-GR": 95, + "de": 94, + "el-GR": 94, "en": 100, "es-AR": 95, "es-CL": 96, - "es": 95, - "fa": 95, - "fr": 95, + "es": 94, + "fa": 94, + "fr": 94, "hi": 2, - "it-IT": 95, + "it-IT": 94, "it": 1, - "ja": 95, - "ko": 55, - "pl": 95, - "pt-BR": 95, - "ru": 95, - "sv-SE": 95, - "uk": 95, + "ja": 94, + "ko": 54, + "pl": 94, + "pt-BR": 94, + "ru": 94, + "sv-SE": 94, + "uk": 94, "ur": 2, - "zh-Hans": 95, - "zh-Hant": 95 + "zh-Hans": 94, + "zh-Hant": 94 } diff --git a/packages/frontend/i18n/src/i18n.gen.ts b/packages/frontend/i18n/src/i18n.gen.ts index 1877ff9d2..646d79d50 100644 --- a/packages/frontend/i18n/src/i18n.gen.ts +++ b/packages/frontend/i18n/src/i18n.gen.ts @@ -7080,6 +7080,30 @@ export function useAFFiNEI18N(): { * `All` */ ["com.affine.all-docs.pinned-collection.all"](): string; + /** + * `Template` + */ + ["com.affine.all-docs.group.is-template"](): string; + /** + * `Not Template` + */ + ["com.affine.all-docs.group.is-not-template"](): string; + /** + * `Journal` + */ + ["com.affine.all-docs.group.is-journal"](): string; + /** + * `Not Journal` + */ + ["com.affine.all-docs.group.is-not-journal"](): string; + /** + * `Checked` + */ + ["com.affine.all-docs.group.is-checked"](): string; + /** + * `Unchecked` + */ + ["com.affine.all-docs.group.is-not-checked"](): string; /** * `core` */ diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 656d77f36..e2e83719b 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -1767,6 +1767,12 @@ "com.affine.all-docs.quick-action.tab": "Open in new tab", "com.affine.all-docs.quick-action.select": "Select checkbox", "com.affine.all-docs.pinned-collection.all": "All", + "com.affine.all-docs.group.is-template": "Template", + "com.affine.all-docs.group.is-not-template": "Not Template", + "com.affine.all-docs.group.is-journal": "Journal", + "com.affine.all-docs.group.is-not-journal": "Not Journal", + "com.affine.all-docs.group.is-checked": "Checked", + "com.affine.all-docs.group.is-not-checked": "Unchecked", "core": "core", "dark": "Dark", "invited you to join": "invited you to join",