mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-18 23:07:02 +08:00
feat(core): set doc mode and primary doc mode separately (#8359)
https://github.com/user-attachments/assets/98c282f2-4c53-475f-bf10-936a626c2630
This commit is contained in:
@@ -11,4 +11,9 @@ export const BUILT_IN_CUSTOM_PROPERTY_TYPE = [
|
|||||||
type: 'tags',
|
type: 'tags',
|
||||||
index: 'a0000001',
|
index: 'a0000001',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'docPrimaryMode',
|
||||||
|
type: 'docPrimaryMode',
|
||||||
|
show: 'always-hide',
|
||||||
|
},
|
||||||
] as DocCustomPropertyInfo[];
|
] as DocCustomPropertyInfo[];
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ export const hide = style({
|
|||||||
export const propertyNameContainer = style({
|
export const propertyNameContainer = style({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
fontSize: cssVar('fontSm'),
|
fontSize: cssVar('fontSm'),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { toast } from '@affine/component';
|
import { notify } from '@affine/component';
|
||||||
import {
|
import {
|
||||||
Menu,
|
Menu,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
@@ -74,6 +74,7 @@ export const PageHeaderMenuButton = ({
|
|||||||
editorService.editor.doc.meta$.map(meta => meta.trash)
|
editorService.editor.doc.meta$.map(meta => meta.trash)
|
||||||
);
|
);
|
||||||
const currentMode = useLiveData(editorService.editor.mode$);
|
const currentMode = useLiveData(editorService.editor.mode$);
|
||||||
|
const primaryMode = useLiveData(editorService.editor.doc.primaryMode$);
|
||||||
|
|
||||||
const workbench = useService(WorkbenchService).workbench;
|
const workbench = useService(WorkbenchService).workbench;
|
||||||
|
|
||||||
@@ -148,16 +149,22 @@ export const PageHeaderMenuButton = ({
|
|||||||
}, [rename]);
|
}, [rename]);
|
||||||
|
|
||||||
const handleSwitchMode = useCallback(() => {
|
const handleSwitchMode = useCallback(() => {
|
||||||
editorService.editor.toggleMode();
|
const mode = primaryMode === 'page' ? 'edgeless' : 'page';
|
||||||
|
editorService.editor.doc.setPrimaryMode(mode);
|
||||||
track.$.header.docOptions.switchPageMode({
|
track.$.header.docOptions.switchPageMode({
|
||||||
mode: currentMode === 'page' ? 'edgeless' : 'page',
|
mode,
|
||||||
});
|
});
|
||||||
toast(
|
notify.success({
|
||||||
currentMode === 'page'
|
title:
|
||||||
? t['com.affine.toastMessage.edgelessMode']()
|
primaryMode === 'page'
|
||||||
: t['com.affine.toastMessage.pageMode']()
|
? t['com.affine.toastMessage.defaultMode.edgeless.title']()
|
||||||
);
|
: t['com.affine.toastMessage.defaultMode.page.title'](),
|
||||||
}, [currentMode, editorService, t]);
|
message:
|
||||||
|
primaryMode === 'page'
|
||||||
|
? t['com.affine.toastMessage.defaultMode.edgeless.message']()
|
||||||
|
: t['com.affine.toastMessage.defaultMode.page.message'](),
|
||||||
|
});
|
||||||
|
}, [primaryMode, editorService, t]);
|
||||||
|
|
||||||
const handleMenuOpenChange = useCallback((open: boolean) => {
|
const handleMenuOpenChange = useCallback((open: boolean) => {
|
||||||
if (open) {
|
if (open) {
|
||||||
@@ -264,14 +271,13 @@ export const PageHeaderMenuButton = ({
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
prefixIcon={currentMode === 'page' ? <EdgelessIcon /> : <PageIcon />}
|
prefixIcon={primaryMode === 'page' ? <EdgelessIcon /> : <PageIcon />}
|
||||||
data-testid="editor-option-menu-edgeless"
|
data-testid="editor-option-menu-edgeless"
|
||||||
onSelect={handleSwitchMode}
|
onSelect={handleSwitchMode}
|
||||||
>
|
>
|
||||||
{t['Convert to ']()}
|
{primaryMode === 'page'
|
||||||
{currentMode === 'page'
|
? t['com.affine.editorDefaultMode.edgeless']()
|
||||||
? t['com.affine.pageMode.edgeless']()
|
: t['com.affine.editorDefaultMode.page']()}
|
||||||
: t['com.affine.pageMode.page']()}
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
data-testid="editor-option-menu-favorite"
|
data-testid="editor-option-menu-favorite"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { RadioGroup, type RadioItem, toast, Tooltip } from '@affine/component';
|
import { RadioGroup, type RadioItem, Tooltip } from '@affine/component';
|
||||||
import { registerAffineCommand } from '@affine/core/commands';
|
import { registerAffineCommand } from '@affine/core/commands';
|
||||||
import { EditorService } from '@affine/core/modules/editor';
|
import { EditorService } from '@affine/core/modules/editor';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
@@ -41,19 +41,15 @@ export const EditorModeSwitch = () => {
|
|||||||
if (currentMode === 'page' || isSharedMode || trash) return;
|
if (currentMode === 'page' || isSharedMode || trash) return;
|
||||||
editor.setMode('page');
|
editor.setMode('page');
|
||||||
editor.setSelector(undefined);
|
editor.setSelector(undefined);
|
||||||
editor.doc.setPrimaryMode('page');
|
|
||||||
toast(t['com.affine.toastMessage.pageMode']());
|
|
||||||
track.$.header.actions.switchPageMode({ mode: 'page' });
|
track.$.header.actions.switchPageMode({ mode: 'page' });
|
||||||
}, [currentMode, editor, isSharedMode, t, trash]);
|
}, [currentMode, editor, isSharedMode, trash]);
|
||||||
|
|
||||||
const toggleEdgeless = useCallback(() => {
|
const toggleEdgeless = useCallback(() => {
|
||||||
if (currentMode === 'edgeless' || isSharedMode || trash) return;
|
if (currentMode === 'edgeless' || isSharedMode || trash) return;
|
||||||
editor.setMode('edgeless');
|
editor.setMode('edgeless');
|
||||||
editor.setSelector(undefined);
|
editor.setSelector(undefined);
|
||||||
editor.doc.setPrimaryMode('edgeless');
|
|
||||||
toast(t['com.affine.toastMessage.edgelessMode']());
|
|
||||||
track.$.header.actions.switchPageMode({ mode: 'edgeless' });
|
track.$.header.actions.switchPageMode({ mode: 'edgeless' });
|
||||||
}, [currentMode, editor, isSharedMode, t, trash]);
|
}, [currentMode, editor, isSharedMode, trash]);
|
||||||
|
|
||||||
const onModeChange = useCallback(
|
const onModeChange = useCallback(
|
||||||
(mode: DocMode) => {
|
(mode: DocMode) => {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
CheckBoxCheckLinearIcon,
|
CheckBoxCheckLinearIcon,
|
||||||
CreatedEditedIcon,
|
CreatedEditedIcon,
|
||||||
DateTimeIcon,
|
DateTimeIcon,
|
||||||
|
FileIcon,
|
||||||
NumberIcon,
|
NumberIcon,
|
||||||
TagIcon,
|
TagIcon,
|
||||||
TextIcon,
|
TextIcon,
|
||||||
@@ -11,6 +12,7 @@ import {
|
|||||||
import { CheckboxValue } from './checkbox';
|
import { CheckboxValue } from './checkbox';
|
||||||
import { CreatedByValue, UpdatedByValue } from './created-updated-by';
|
import { CreatedByValue, UpdatedByValue } from './created-updated-by';
|
||||||
import { DateValue } from './date';
|
import { DateValue } from './date';
|
||||||
|
import { DocPrimaryModeValue } from './doc-primary-mode';
|
||||||
import { NumberValue } from './number';
|
import { NumberValue } from './number';
|
||||||
import { TagsValue } from './tags';
|
import { TagsValue } from './tags';
|
||||||
import { TextValue } from './text';
|
import { TextValue } from './text';
|
||||||
@@ -54,6 +56,11 @@ export const DocPropertyTypes = {
|
|||||||
uniqueId: 'tags',
|
uniqueId: 'tags',
|
||||||
renameable: false,
|
renameable: false,
|
||||||
},
|
},
|
||||||
|
docPrimaryMode: {
|
||||||
|
icon: FileIcon,
|
||||||
|
value: DocPrimaryModeValue,
|
||||||
|
name: 'com.affine.page-properties.property.docPrimaryMode',
|
||||||
|
},
|
||||||
} as Record<
|
} as Record<
|
||||||
string,
|
string,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
notify,
|
||||||
|
PropertyValue,
|
||||||
|
RadioGroup,
|
||||||
|
type RadioItem,
|
||||||
|
} from '@affine/component';
|
||||||
|
import { useI18n } from '@affine/i18n';
|
||||||
|
import type { DocMode } from '@blocksuite/affine/blocks';
|
||||||
|
import { DocService, useLiveData, useService } from '@toeverything/infra';
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
|
export const DocPrimaryModeValue = () => {
|
||||||
|
const t = useI18n();
|
||||||
|
const doc = useService(DocService).doc;
|
||||||
|
|
||||||
|
const primaryMode = useLiveData(doc.primaryMode$);
|
||||||
|
|
||||||
|
const DocModeItems = useMemo<RadioItem[]>(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
value: 'page' as DocMode,
|
||||||
|
label: t['Page'](),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'edgeless' as DocMode,
|
||||||
|
label: t['Edgeless'](),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[t]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleChange = useCallback(
|
||||||
|
(mode: DocMode) => {
|
||||||
|
doc.setPrimaryMode(mode);
|
||||||
|
notify.success({
|
||||||
|
title:
|
||||||
|
mode === 'page'
|
||||||
|
? t['com.affine.toastMessage.defaultMode.page.title']()
|
||||||
|
: t['com.affine.toastMessage.defaultMode.edgeless.title'](),
|
||||||
|
message:
|
||||||
|
mode === 'page'
|
||||||
|
? t['com.affine.toastMessage.defaultMode.page.message']()
|
||||||
|
: t['com.affine.toastMessage.defaultMode.edgeless.message'](),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[doc, t]
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<PropertyValue>
|
||||||
|
<RadioGroup
|
||||||
|
width={194}
|
||||||
|
value={primaryMode}
|
||||||
|
onChange={handleChange}
|
||||||
|
items={DocModeItems}
|
||||||
|
/>
|
||||||
|
</PropertyValue>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IconButton, toast } from '@affine/component';
|
import { IconButton, notify } from '@affine/component';
|
||||||
import {
|
import {
|
||||||
MenuSeparator,
|
MenuSeparator,
|
||||||
MobileMenu,
|
MobileMenu,
|
||||||
@@ -39,21 +39,29 @@ export const PageHeaderMenuButton = () => {
|
|||||||
const isInTrash = useLiveData(
|
const isInTrash = useLiveData(
|
||||||
editorService.editor.doc.meta$.map(meta => meta.trash)
|
editorService.editor.doc.meta$.map(meta => meta.trash)
|
||||||
);
|
);
|
||||||
const currentMode = useLiveData(editorService.editor.mode$);
|
const primaryMode = useLiveData(editorService.editor.doc.primaryMode$);
|
||||||
|
|
||||||
const { favorite, toggleFavorite } = useFavorite(docId);
|
const { favorite, toggleFavorite } = useFavorite(docId);
|
||||||
|
|
||||||
const handleSwitchMode = useCallback(() => {
|
const handleSwitchMode = useCallback(() => {
|
||||||
editorService.editor.toggleMode();
|
const mode = primaryMode === 'page' ? 'edgeless' : 'page';
|
||||||
|
// TODO(@JimmFly): remove setMode when there has view mode switch
|
||||||
|
editorService.editor.setMode(mode);
|
||||||
|
editorService.editor.doc.setPrimaryMode(mode);
|
||||||
track.$.header.docOptions.switchPageMode({
|
track.$.header.docOptions.switchPageMode({
|
||||||
mode: currentMode === 'page' ? 'edgeless' : 'page',
|
mode,
|
||||||
});
|
});
|
||||||
toast(
|
notify.success({
|
||||||
currentMode === 'page'
|
title:
|
||||||
? t['com.affine.toastMessage.edgelessMode']()
|
primaryMode === 'page'
|
||||||
: t['com.affine.toastMessage.pageMode']()
|
? t['com.affine.toastMessage.defaultMode.edgeless.title']()
|
||||||
);
|
: t['com.affine.toastMessage.defaultMode.page.title'](),
|
||||||
}, [currentMode, editorService, t]);
|
message:
|
||||||
|
primaryMode === 'page'
|
||||||
|
? t['com.affine.toastMessage.defaultMode.edgeless.message']()
|
||||||
|
: t['com.affine.toastMessage.defaultMode.page.message'](),
|
||||||
|
});
|
||||||
|
}, [primaryMode, editorService, t]);
|
||||||
|
|
||||||
const handleMenuOpenChange = useCallback((open: boolean) => {
|
const handleMenuOpenChange = useCallback((open: boolean) => {
|
||||||
if (open) {
|
if (open) {
|
||||||
@@ -75,14 +83,13 @@ export const PageHeaderMenuButton = () => {
|
|||||||
const EditMenu = (
|
const EditMenu = (
|
||||||
<>
|
<>
|
||||||
<MobileMenuItem
|
<MobileMenuItem
|
||||||
prefixIcon={currentMode === 'page' ? <EdgelessIcon /> : <PageIcon />}
|
prefixIcon={primaryMode === 'page' ? <EdgelessIcon /> : <PageIcon />}
|
||||||
data-testid="editor-option-menu-mode-switch"
|
data-testid="editor-option-menu-mode-switch"
|
||||||
onSelect={handleSwitchMode}
|
onSelect={handleSwitchMode}
|
||||||
>
|
>
|
||||||
{t['Convert to ']()}
|
{primaryMode === 'page'
|
||||||
{currentMode === 'page'
|
? t['com.affine.editorDefaultMode.edgeless']()
|
||||||
? t['com.affine.pageMode.edgeless']()
|
: t['com.affine.editorDefaultMode.page']()}
|
||||||
: t['com.affine.pageMode.page']()}
|
|
||||||
</MobileMenuItem>
|
</MobileMenuItem>
|
||||||
<MobileMenuItem
|
<MobileMenuItem
|
||||||
data-testid="editor-option-menu-favorite"
|
data-testid="editor-option-menu-favorite"
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"ar": 87,
|
"ar": 86,
|
||||||
"ca": 6,
|
"ca": 6,
|
||||||
"da": 7,
|
"da": 7,
|
||||||
"de": 32,
|
"de": 32,
|
||||||
"en": 100,
|
"en": 100,
|
||||||
"es-AR": 16,
|
"es-AR": 15,
|
||||||
"es-CL": 18,
|
"es-CL": 18,
|
||||||
"es": 16,
|
"es": 15,
|
||||||
"fr": 77,
|
"fr": 77,
|
||||||
"hi": 2,
|
"hi": 2,
|
||||||
"it": 1,
|
"it": 1,
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
"ko": 92,
|
"ko": 92,
|
||||||
"pl": 0,
|
"pl": 0,
|
||||||
"pt-BR": 99,
|
"pt-BR": 99,
|
||||||
"ru": 85,
|
"ru": 84,
|
||||||
"sv-SE": 5,
|
"sv-SE": 5,
|
||||||
"ur": 3,
|
"ur": 3,
|
||||||
"zh-Hans": 100,
|
"zh-Hans": 100,
|
||||||
"zh-Hant": 100
|
"zh-Hant": 99
|
||||||
}
|
}
|
||||||
@@ -92,6 +92,7 @@
|
|||||||
"Successfully deleted": "Successfully deleted",
|
"Successfully deleted": "Successfully deleted",
|
||||||
"Successfully joined!": "Successfully joined!",
|
"Successfully joined!": "Successfully joined!",
|
||||||
"Switch": "Switch",
|
"Switch": "Switch",
|
||||||
|
"switchView": "Switch view",
|
||||||
"Sync": "Sync",
|
"Sync": "Sync",
|
||||||
"Synced with AFFiNE Cloud": "Synced with AFFiNE Cloud",
|
"Synced with AFFiNE Cloud": "Synced with AFFiNE Cloud",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
@@ -425,6 +426,8 @@
|
|||||||
"com.affine.editCollectionName.createTips": "Collection is a smart folder where you can manually add docs or automatically add docs through rules.",
|
"com.affine.editCollectionName.createTips": "Collection is a smart folder where you can manually add docs or automatically add docs through rules.",
|
||||||
"com.affine.editCollectionName.name": "Name",
|
"com.affine.editCollectionName.name": "Name",
|
||||||
"com.affine.editCollectionName.name.placeholder": "Collection name",
|
"com.affine.editCollectionName.name.placeholder": "Collection name",
|
||||||
|
"com.affine.editorDefaultMode.edgeless": "Default to Edgeless mode",
|
||||||
|
"com.affine.editorDefaultMode.page": "Default to Page mode",
|
||||||
"com.affine.empty.collection-detail.action.add-doc": "Add docs",
|
"com.affine.empty.collection-detail.action.add-doc": "Add docs",
|
||||||
"com.affine.empty.collection-detail.action.add-rule": "Add rules",
|
"com.affine.empty.collection-detail.action.add-rule": "Add rules",
|
||||||
"com.affine.empty.collection-detail.description": "Collection is a smart folder where you can manually add docs or automatically add docs through rules.",
|
"com.affine.empty.collection-detail.description": "Collection is a smart folder where you can manually add docs or automatically add docs through rules.",
|
||||||
@@ -527,7 +530,7 @@
|
|||||||
"com.affine.keyboardShortcuts.elbowedConnector": "Elbowed connector",
|
"com.affine.keyboardShortcuts.elbowedConnector": "Elbowed connector",
|
||||||
"com.affine.keyboardShortcuts.expandOrCollapseSidebar": "Expand/collapse sidebar",
|
"com.affine.keyboardShortcuts.expandOrCollapseSidebar": "Expand/collapse sidebar",
|
||||||
"com.affine.keyboardShortcuts.goBack": "Go back",
|
"com.affine.keyboardShortcuts.goBack": "Go back",
|
||||||
"com.affine.keyboardShortcuts.goForward": "Go Forward",
|
"com.affine.keyboardShortcuts.goForward": "Go forward",
|
||||||
"com.affine.keyboardShortcuts.group": "Group",
|
"com.affine.keyboardShortcuts.group": "Group",
|
||||||
"com.affine.keyboardShortcuts.groupDatabase": "Group as database",
|
"com.affine.keyboardShortcuts.groupDatabase": "Group as database",
|
||||||
"com.affine.keyboardShortcuts.hand": "Hand",
|
"com.affine.keyboardShortcuts.hand": "Hand",
|
||||||
@@ -551,7 +554,7 @@
|
|||||||
"com.affine.keyboardShortcuts.straightConnector": "Straight connector",
|
"com.affine.keyboardShortcuts.straightConnector": "Straight connector",
|
||||||
"com.affine.keyboardShortcuts.strikethrough": "Strikethrough",
|
"com.affine.keyboardShortcuts.strikethrough": "Strikethrough",
|
||||||
"com.affine.keyboardShortcuts.subtitle": "Check keyboard shortcuts quickly",
|
"com.affine.keyboardShortcuts.subtitle": "Check keyboard shortcuts quickly",
|
||||||
"com.affine.keyboardShortcuts.switch": "Switch",
|
"com.affine.keyboardShortcuts.switch": "Switch view",
|
||||||
"com.affine.keyboardShortcuts.text": "Text",
|
"com.affine.keyboardShortcuts.text": "Text",
|
||||||
"com.affine.keyboardShortcuts.title": "Keyboard shortcuts",
|
"com.affine.keyboardShortcuts.title": "Keyboard shortcuts",
|
||||||
"com.affine.keyboardShortcuts.unGroup": "Ungroup",
|
"com.affine.keyboardShortcuts.unGroup": "Ungroup",
|
||||||
@@ -647,6 +650,7 @@
|
|||||||
"com.affine.page-properties.property.required": "Required",
|
"com.affine.page-properties.property.required": "Required",
|
||||||
"com.affine.page-properties.property.show-in-view": "Show in view",
|
"com.affine.page-properties.property.show-in-view": "Show in view",
|
||||||
"com.affine.page-properties.property.tags": "Tags",
|
"com.affine.page-properties.property.tags": "Tags",
|
||||||
|
"com.affine.page-properties.property.docPrimaryMode": "Doc mode",
|
||||||
"com.affine.page-properties.property.text": "Text",
|
"com.affine.page-properties.property.text": "Text",
|
||||||
"com.affine.page-properties.property.updatedBy": "Last edited by",
|
"com.affine.page-properties.property.updatedBy": "Last edited by",
|
||||||
"com.affine.propertySidebar.property-list.section": "Properties",
|
"com.affine.propertySidebar.property-list.section": "Properties",
|
||||||
@@ -1213,6 +1217,10 @@
|
|||||||
"com.affine.toastMessage.edgelessMode": "Edgeless mode",
|
"com.affine.toastMessage.edgelessMode": "Edgeless mode",
|
||||||
"com.affine.toastMessage.movedTrash": "Moved to trash",
|
"com.affine.toastMessage.movedTrash": "Moved to trash",
|
||||||
"com.affine.toastMessage.pageMode": "Page Mode",
|
"com.affine.toastMessage.pageMode": "Page Mode",
|
||||||
|
"com.affine.toastMessage.defaultMode.page.title": "Default mode has changed",
|
||||||
|
"com.affine.toastMessage.defaultMode.page.message": "The default mode for this document has been changed to Page mode",
|
||||||
|
"com.affine.toastMessage.defaultMode.edgeless.title": "Default mode has changed",
|
||||||
|
"com.affine.toastMessage.defaultMode.edgeless.message": "The default mode for this document has been changed to Edgeless mode",
|
||||||
"com.affine.toastMessage.permanentlyDeleted": "Permanently deleted",
|
"com.affine.toastMessage.permanentlyDeleted": "Permanently deleted",
|
||||||
"com.affine.toastMessage.removedFavorites": "Removed from favourites",
|
"com.affine.toastMessage.removedFavorites": "Removed from favourites",
|
||||||
"com.affine.toastMessage.rename": "Successfully renamed",
|
"com.affine.toastMessage.rename": "Successfully renamed",
|
||||||
|
|||||||
@@ -682,7 +682,6 @@
|
|||||||
"com.affine.editCollectionName.name": "이름",
|
"com.affine.editCollectionName.name": "이름",
|
||||||
"com.affine.editCollectionName.name.placeholder": "컬렉션 이름",
|
"com.affine.editCollectionName.name.placeholder": "컬렉션 이름",
|
||||||
"com.affine.editor.reference-not-found": "연결된 페이지를 찾을 수 없음",
|
"com.affine.editor.reference-not-found": "연결된 페이지를 찾을 수 없음",
|
||||||
"com.affine.editorModeSwitch.tooltip": "전환",
|
|
||||||
"com.affine.empty.collection-detail.action.add-doc": "문서 추가",
|
"com.affine.empty.collection-detail.action.add-doc": "문서 추가",
|
||||||
"com.affine.empty.collection-detail.action.add-rule": "규칙 추가",
|
"com.affine.empty.collection-detail.action.add-rule": "규칙 추가",
|
||||||
"com.affine.empty.collection-detail.description": "컬렉션은 페이지를 수동으로 추가하거나 규칙을 통해 자동으로 페이지를 추가할 수 있는 스마트 폴더입니다.",
|
"com.affine.empty.collection-detail.description": "컬렉션은 페이지를 수동으로 추가하거나 규칙을 통해 자동으로 페이지를 추가할 수 있는 스마트 폴더입니다.",
|
||||||
|
|||||||
@@ -92,6 +92,7 @@
|
|||||||
"Successfully deleted": "成功删除。",
|
"Successfully deleted": "成功删除。",
|
||||||
"Successfully joined!": "加入成功!",
|
"Successfully joined!": "加入成功!",
|
||||||
"Switch": "切换",
|
"Switch": "切换",
|
||||||
|
"switchView": "切换视图",
|
||||||
"Sync": "同步",
|
"Sync": "同步",
|
||||||
"Synced with AFFiNE Cloud": "AFFiNE Cloud 同步完成",
|
"Synced with AFFiNE Cloud": "AFFiNE Cloud 同步完成",
|
||||||
"Tags": "标签",
|
"Tags": "标签",
|
||||||
@@ -438,6 +439,9 @@
|
|||||||
"com.affine.empty.docs.trash-description": "已删除的文档将显示在此处。",
|
"com.affine.empty.docs.trash-description": "已删除的文档将显示在此处。",
|
||||||
"com.affine.empty.tags.description": "为您的文档创建一个新标签。",
|
"com.affine.empty.tags.description": "为您的文档创建一个新标签。",
|
||||||
"com.affine.empty.tags.title": "标签管理",
|
"com.affine.empty.tags.title": "标签管理",
|
||||||
|
"com.affine.editorDefaultMode.edgeless": "默认为无界模式",
|
||||||
|
"com.affine.editorDefaultMode.page": "默认为文档模式",
|
||||||
|
"com.affine.editor.reference-not-found": "未找到已链接的文档",
|
||||||
"com.affine.emptyDesc": "这里还没有文档",
|
"com.affine.emptyDesc": "这里还没有文档",
|
||||||
"com.affine.enableAffineCloudModal.button.cancel": "取消",
|
"com.affine.enableAffineCloudModal.button.cancel": "取消",
|
||||||
"com.affine.error.hide-error": "隐藏错误详情",
|
"com.affine.error.hide-error": "隐藏错误详情",
|
||||||
@@ -551,7 +555,7 @@
|
|||||||
"com.affine.keyboardShortcuts.straightConnector": "直线连接器快捷键",
|
"com.affine.keyboardShortcuts.straightConnector": "直线连接器快捷键",
|
||||||
"com.affine.keyboardShortcuts.strikethrough": "删除线",
|
"com.affine.keyboardShortcuts.strikethrough": "删除线",
|
||||||
"com.affine.keyboardShortcuts.subtitle": "快速查看快捷键",
|
"com.affine.keyboardShortcuts.subtitle": "快速查看快捷键",
|
||||||
"com.affine.keyboardShortcuts.switch": "切换快捷键",
|
"com.affine.keyboardShortcuts.switch": "切换视图快捷键",
|
||||||
"com.affine.keyboardShortcuts.text": "文本",
|
"com.affine.keyboardShortcuts.text": "文本",
|
||||||
"com.affine.keyboardShortcuts.title": "键盘快捷键",
|
"com.affine.keyboardShortcuts.title": "键盘快捷键",
|
||||||
"com.affine.keyboardShortcuts.unGroup": "取消分组",
|
"com.affine.keyboardShortcuts.unGroup": "取消分组",
|
||||||
@@ -642,6 +646,7 @@
|
|||||||
"com.affine.page-properties.property.required": "必选",
|
"com.affine.page-properties.property.required": "必选",
|
||||||
"com.affine.page-properties.property.show-in-view": "在视图中显示",
|
"com.affine.page-properties.property.show-in-view": "在视图中显示",
|
||||||
"com.affine.page-properties.property.tags": "标签",
|
"com.affine.page-properties.property.tags": "标签",
|
||||||
|
"com.affine.page-properties.property.docPrimaryMode": "文档模式",
|
||||||
"com.affine.page-properties.property.text": "文本",
|
"com.affine.page-properties.property.text": "文本",
|
||||||
"com.affine.page-properties.property.updatedBy": "最后编辑者",
|
"com.affine.page-properties.property.updatedBy": "最后编辑者",
|
||||||
"com.affine.page-properties.settings.title": "自定义属性",
|
"com.affine.page-properties.settings.title": "自定义属性",
|
||||||
@@ -1206,6 +1211,10 @@
|
|||||||
"com.affine.toastMessage.rename": "更名成功",
|
"com.affine.toastMessage.rename": "更名成功",
|
||||||
"com.affine.toastMessage.restored": "{{title}} 已恢复",
|
"com.affine.toastMessage.restored": "{{title}} 已恢复",
|
||||||
"com.affine.toastMessage.successfullyDeleted": "删除成功",
|
"com.affine.toastMessage.successfullyDeleted": "删除成功",
|
||||||
|
"com.affine.toastMessage.defaultMode.page.title": "默认模式已更改",
|
||||||
|
"com.affine.toastMessage.defaultMode.page.message": "该文档的默认模式已更改为页面模式",
|
||||||
|
"com.affine.toastMessage.defaultMode.edgeless.title": "默认模式已更改",
|
||||||
|
"com.affine.toastMessage.defaultMode.edgeless.message": "该文档的默认模式已更改为无界模式",
|
||||||
"com.affine.today": "今天",
|
"com.affine.today": "今天",
|
||||||
"com.affine.tomorrow": "明日",
|
"com.affine.tomorrow": "明日",
|
||||||
"com.affine.top-tip.mobile": "在移动设备上仅限于查看。",
|
"com.affine.top-tip.mobile": "在移动设备上仅限于查看。",
|
||||||
|
|||||||
@@ -8,56 +8,20 @@ import { openHomePage } from '@affine-test/kit/utils/load-page';
|
|||||||
import {
|
import {
|
||||||
clickNewPageButton,
|
clickNewPageButton,
|
||||||
clickPageMoreActions,
|
clickPageMoreActions,
|
||||||
|
getBlockSuiteEditorTitle,
|
||||||
|
waitForAllPagesLoad,
|
||||||
waitForEditorLoad,
|
waitForEditorLoad,
|
||||||
} from '@affine-test/kit/utils/page-logic';
|
} from '@affine-test/kit/utils/page-logic';
|
||||||
|
import { clickSideBarAllPageButton } from '@affine-test/kit/utils/sidebar';
|
||||||
import { expect } from '@playwright/test';
|
import { expect } from '@playwright/test';
|
||||||
|
|
||||||
test('Switch to edgeless by switch edgeless item', async ({ page }) => {
|
test('Switch to edgeless by switch edgeless item', async ({ page }) => {
|
||||||
async function getCount(): Promise<number> {
|
|
||||||
return page.evaluate(() => {
|
|
||||||
// @ts-expect-error
|
|
||||||
return globalThis.__toastCount;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
await waitForEditorLoad(page);
|
await waitForEditorLoad(page);
|
||||||
await clickNewPageButton(page);
|
await clickNewPageButton(page);
|
||||||
const btn = page.getByTestId('switch-edgeless-mode-button');
|
const btn = page.getByTestId('switch-edgeless-mode-button');
|
||||||
await page.evaluate(() => {
|
await btn.click({ delay: 100 });
|
||||||
// @ts-expect-error
|
await ensureInEdgelessMode(page);
|
||||||
globalThis.__toastCount = 0;
|
|
||||||
window.addEventListener('affine-toast:emit', () => {
|
|
||||||
// @ts-expect-error
|
|
||||||
globalThis.__toastCount++;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
await btn.click();
|
|
||||||
await page.waitForTimeout(100);
|
|
||||||
{
|
|
||||||
const count = await getCount();
|
|
||||||
expect(count).toBe(1);
|
|
||||||
}
|
|
||||||
const edgeless = page.locator('affine-edgeless-root');
|
|
||||||
await expect(edgeless).toBeVisible();
|
|
||||||
|
|
||||||
const editorWrapperPadding = await page
|
|
||||||
.locator('.editor-wrapper.edgeless-mode')
|
|
||||||
.evaluate(element => {
|
|
||||||
return window.getComputedStyle(element).getPropertyValue('padding');
|
|
||||||
});
|
|
||||||
expect(editorWrapperPadding).toBe('0px');
|
|
||||||
{
|
|
||||||
const count = await getCount();
|
|
||||||
expect(count).toBe(1);
|
|
||||||
}
|
|
||||||
await btn.click();
|
|
||||||
await btn.click();
|
|
||||||
await btn.click();
|
|
||||||
await page.waitForTimeout(100);
|
|
||||||
{
|
|
||||||
const count = await getCount();
|
|
||||||
expect(count).toBe(1);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Quick Switch Doc Mode, Doc Mode should stable', async ({ page }) => {
|
test('Quick Switch Doc Mode, Doc Mode should stable', async ({ page }) => {
|
||||||
@@ -94,13 +58,26 @@ test('Quick Switch Doc Mode, Doc Mode should stable', async ({ page }) => {
|
|||||||
expect(await getPageMode(page)).toBe('page');
|
expect(await getPageMode(page)).toBe('page');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Convert to edgeless by editor header items', async ({ page }) => {
|
test('default to edgeless by editor header items', async ({ page }) => {
|
||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
await waitForEditorLoad(page);
|
await waitForEditorLoad(page);
|
||||||
await clickNewPageButton(page);
|
await clickNewPageButton(page, 'this is a new page');
|
||||||
|
const title = getBlockSuiteEditorTitle(page);
|
||||||
|
expect(await title.textContent()).toBe('this is a new page');
|
||||||
|
|
||||||
await clickPageMoreActions(page);
|
await clickPageMoreActions(page);
|
||||||
const menusEdgelessItem = page.getByTestId('editor-option-menu-edgeless');
|
const menusEdgelessItem = page.getByTestId('editor-option-menu-edgeless');
|
||||||
await menusEdgelessItem.click({ delay: 100 });
|
await menusEdgelessItem.click({ delay: 100 });
|
||||||
|
|
||||||
|
await clickSideBarAllPageButton(page);
|
||||||
|
await waitForAllPagesLoad(page);
|
||||||
|
const docItem = page.locator(
|
||||||
|
`[data-testid="page-list-item"]:has-text("this is a new page")`
|
||||||
|
);
|
||||||
|
expect(docItem).not.toBeUndefined();
|
||||||
|
await docItem.click();
|
||||||
|
|
||||||
|
await waitForEditorLoad(page);
|
||||||
const edgeless = page.locator('affine-edgeless-root');
|
const edgeless = page.locator('affine-edgeless-root');
|
||||||
await expect(edgeless).toBeVisible();
|
await expect(edgeless).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
openWorkspaceProperties,
|
openWorkspaceProperties,
|
||||||
removeSelectedTag,
|
removeSelectedTag,
|
||||||
searchAndCreateTag,
|
searchAndCreateTag,
|
||||||
|
togglePropertyListVisibility,
|
||||||
} from '@affine-test/kit/utils/properties';
|
} from '@affine-test/kit/utils/properties';
|
||||||
import { expect } from '@playwright/test';
|
import { expect } from '@playwright/test';
|
||||||
|
|
||||||
@@ -117,8 +118,9 @@ test('property table reordering', async ({ page }) => {
|
|||||||
'bottom'
|
'bottom'
|
||||||
);
|
);
|
||||||
|
|
||||||
// new order should be (Tags), Number, Date, Checkbox, Text
|
// new order should be Doc mode, (Tags), Number, Date, Checkbox, Text
|
||||||
for (const [index, property] of [
|
for (const [index, property] of [
|
||||||
|
'Doc mode',
|
||||||
'Tags',
|
'Tags',
|
||||||
'Number',
|
'Number',
|
||||||
'Date',
|
'Date',
|
||||||
@@ -157,6 +159,7 @@ test('page info show more will show all properties', async ({ page }) => {
|
|||||||
await page.click('[data-testid="property-collapsible-button"]');
|
await page.click('[data-testid="property-collapsible-button"]');
|
||||||
|
|
||||||
for (const [index, property] of [
|
for (const [index, property] of [
|
||||||
|
'Doc mode',
|
||||||
'Tags',
|
'Tags',
|
||||||
'Text',
|
'Text',
|
||||||
'Number',
|
'Number',
|
||||||
@@ -179,6 +182,7 @@ test('change page properties visibility', async ({ page }) => {
|
|||||||
await addCustomProperty(page, page, 'number');
|
await addCustomProperty(page, page, 'number');
|
||||||
await addCustomProperty(page, page, 'date');
|
await addCustomProperty(page, page, 'date');
|
||||||
await addCustomProperty(page, page, 'checkbox');
|
await addCustomProperty(page, page, 'checkbox');
|
||||||
|
await togglePropertyListVisibility(page);
|
||||||
|
|
||||||
// add some number to number property
|
// add some number to number property
|
||||||
await clickPropertyValue(page, 'Number');
|
await clickPropertyValue(page, 'Number');
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ test('switch to page mode', async ({ page }) => {
|
|||||||
await page.click('[data-testid="detail-page-header-more-button"]');
|
await page.click('[data-testid="detail-page-header-more-button"]');
|
||||||
await expect(page.getByRole('dialog')).toBeVisible();
|
await expect(page.getByRole('dialog')).toBeVisible();
|
||||||
|
|
||||||
await page.getByRole('menuitem', { name: 'convert to page' }).click();
|
await page.getByRole('menuitem', { name: 'Default to Page mode' }).click();
|
||||||
await expect(page.locator('.doc-title-container')).toBeVisible();
|
await expect(page.locator('.doc-title-container')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -93,11 +93,36 @@ export const clickAddPropertyButton = async (root: Locator | Page) => {
|
|||||||
.click();
|
.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ensureAddPropertyButtonVisible = async (
|
||||||
|
page: Page,
|
||||||
|
root: Locator | Page
|
||||||
|
) => {
|
||||||
|
if (
|
||||||
|
await root
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'Add property',
|
||||||
|
})
|
||||||
|
.isVisible()
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await togglePropertyListVisibility(page);
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
await expect(
|
||||||
|
root.getByRole('button', { name: 'Add property' })
|
||||||
|
).toBeVisible();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const togglePropertyListVisibility = async (page: Page) => {
|
||||||
|
await page.getByTestId('property-collapsible-button').click();
|
||||||
|
};
|
||||||
|
|
||||||
export const addCustomProperty = async (
|
export const addCustomProperty = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
root: Locator | Page,
|
root: Locator | Page,
|
||||||
type: string
|
type: string
|
||||||
) => {
|
) => {
|
||||||
|
ensureAddPropertyButtonVisible(page, root);
|
||||||
await clickAddPropertyButton(root);
|
await clickAddPropertyButton(root);
|
||||||
await page
|
await page
|
||||||
.locator(
|
.locator(
|
||||||
|
|||||||
Reference in New Issue
Block a user