mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
feat(editor): affine to blocksuite doc dnd with prefered card view (#11748)
Close [BS-3070](https://linear.app/affine-design/issue/BS-3070/文档拖动进入edgeless,形成引用时,默认形成embeded的引用,但是记录上次选择)
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
ActionPlacement,
|
ActionPlacement,
|
||||||
DocDisplayMetaProvider,
|
DocDisplayMetaProvider,
|
||||||
|
EditorSettingProvider,
|
||||||
type LinkEventType,
|
type LinkEventType,
|
||||||
type OpenDocMode,
|
type OpenDocMode,
|
||||||
type ToolbarAction,
|
type ToolbarAction,
|
||||||
@@ -33,7 +34,7 @@ import {
|
|||||||
ExpandFullIcon,
|
ExpandFullIcon,
|
||||||
OpenInNewIcon,
|
OpenInNewIcon,
|
||||||
} from '@blocksuite/icons/lit';
|
} from '@blocksuite/icons/lit';
|
||||||
import { BlockFlavourIdentifier } from '@blocksuite/std';
|
import { BlockFlavourIdentifier, isGfxBlockComponent } from '@blocksuite/std';
|
||||||
import { type ExtensionType, Slice } from '@blocksuite/store';
|
import { type ExtensionType, Slice } from '@blocksuite/store';
|
||||||
import { computed, signal } from '@preact/signals-core';
|
import { computed, signal } from '@preact/signals-core';
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
@@ -213,6 +214,15 @@ const conversionsActionGroup = {
|
|||||||
},
|
},
|
||||||
run(ctx) {
|
run(ctx) {
|
||||||
const block = ctx.getCurrentBlockByType(EmbedLinkedDocBlockComponent);
|
const block = ctx.getCurrentBlockByType(EmbedLinkedDocBlockComponent);
|
||||||
|
|
||||||
|
if (isGfxBlockComponent(block)) {
|
||||||
|
const editorSetting = ctx.std.getOptional(EditorSettingProvider);
|
||||||
|
editorSetting?.set?.(
|
||||||
|
'docDropCanvasPreferView',
|
||||||
|
'affine:embed-synced-doc'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
block?.convertToEmbed();
|
block?.convertToEmbed();
|
||||||
|
|
||||||
ctx.track('SelectedView', {
|
ctx.track('SelectedView', {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { EditorChevronDown } from '@blocksuite/affine-components/toolbar';
|
|||||||
import { EmbedSyncedDocModel } from '@blocksuite/affine-model';
|
import { EmbedSyncedDocModel } from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
ActionPlacement,
|
ActionPlacement,
|
||||||
|
EditorSettingProvider,
|
||||||
type LinkEventType,
|
type LinkEventType,
|
||||||
type OpenDocMode,
|
type OpenDocMode,
|
||||||
type ToolbarAction,
|
type ToolbarAction,
|
||||||
@@ -21,7 +22,7 @@ import {
|
|||||||
ExpandFullIcon,
|
ExpandFullIcon,
|
||||||
OpenInNewIcon,
|
OpenInNewIcon,
|
||||||
} from '@blocksuite/icons/lit';
|
} from '@blocksuite/icons/lit';
|
||||||
import { BlockFlavourIdentifier } from '@blocksuite/std';
|
import { BlockFlavourIdentifier, isGfxBlockComponent } from '@blocksuite/std';
|
||||||
import { type ExtensionType, Slice } from '@blocksuite/store';
|
import { type ExtensionType, Slice } from '@blocksuite/store';
|
||||||
import { computed, signal } from '@preact/signals-core';
|
import { computed, signal } from '@preact/signals-core';
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
@@ -30,7 +31,6 @@ import { keyed } from 'lit/directives/keyed.js';
|
|||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
|
|
||||||
import { EmbedSyncedDocBlockComponent } from '../embed-synced-doc-block';
|
import { EmbedSyncedDocBlockComponent } from '../embed-synced-doc-block';
|
||||||
|
|
||||||
const trackBaseProps = {
|
const trackBaseProps = {
|
||||||
category: 'linked doc',
|
category: 'linked doc',
|
||||||
type: 'embed view',
|
type: 'embed view',
|
||||||
@@ -142,6 +142,14 @@ const conversionsActionGroup = {
|
|||||||
label: 'Card view',
|
label: 'Card view',
|
||||||
run(ctx) {
|
run(ctx) {
|
||||||
const block = ctx.getCurrentBlockByType(EmbedSyncedDocBlockComponent);
|
const block = ctx.getCurrentBlockByType(EmbedSyncedDocBlockComponent);
|
||||||
|
if (isGfxBlockComponent(block)) {
|
||||||
|
const editorSetting = ctx.std.getOptional(EditorSettingProvider);
|
||||||
|
editorSetting?.set?.(
|
||||||
|
'docDropCanvasPreferView',
|
||||||
|
'affine:embed-linked-doc'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
block?.convertToCard();
|
block?.convertToCard();
|
||||||
|
|
||||||
ctx.track('SelectedView', {
|
ctx.track('SelectedView', {
|
||||||
|
|||||||
@@ -117,9 +117,9 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
|
|||||||
const nextDepth = this.depth + 1;
|
const nextDepth = this.depth + 1;
|
||||||
const previewSpecBuilder = SpecProvider._.getSpec(name);
|
const previewSpecBuilder = SpecProvider._.getSpec(name);
|
||||||
const currentDisposables = this.disposables;
|
const currentDisposables = this.disposables;
|
||||||
const editorSetting =
|
const editorSetting = this.std.getOptional(EditorSettingProvider) ?? {
|
||||||
this.std.getOptional(EditorSettingProvider) ??
|
setting$: signal(GeneralSettingSchema.parse({})),
|
||||||
signal(GeneralSettingSchema.parse({}));
|
};
|
||||||
|
|
||||||
class EmbedSyncedDocWatcher extends LifeCycleWatcher {
|
class EmbedSyncedDocWatcher extends LifeCycleWatcher {
|
||||||
static override key = 'embed-synced-doc-watcher';
|
static override key = 'embed-synced-doc-watcher';
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ export class EdgelessRootBlockComponent extends BlockComponent<
|
|||||||
private _initWheelEvent() {
|
private _initWheelEvent() {
|
||||||
this._disposables.add(
|
this._disposables.add(
|
||||||
this.dispatcher.add('wheel', ctx => {
|
this.dispatcher.add('wheel', ctx => {
|
||||||
const config = this.std.getOptional(EditorSettingProvider);
|
const config = this.std.getOptional(EditorSettingProvider)?.setting$;
|
||||||
const state = ctx.get('defaultState');
|
const state = ctx.get('defaultState');
|
||||||
const e = state.event as WheelEvent;
|
const e = state.event as WheelEvent;
|
||||||
const edgelessScrollZoom = config?.peek().edgelessScrollZoom ?? false;
|
const edgelessScrollZoom = config?.peek().edgelessScrollZoom ?? false;
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _disableScheduleUpdate() {
|
private get _disableScheduleUpdate() {
|
||||||
const editorSetting = this.std.getOptional(EditorSettingProvider);
|
const editorSetting = this.std.getOptional(EditorSettingProvider)?.setting$;
|
||||||
|
|
||||||
return editorSetting?.peek().edgelessDisableScheduleUpdate ?? false;
|
return editorSetting?.peek().edgelessDisableScheduleUpdate ?? false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,9 @@ export class EditPropsStore extends LifeCycleWatcher {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.lastProps$ = computed(() => {
|
this.lastProps$ = computed(() => {
|
||||||
const editorSetting$ = this.std.getOptional(EditorSettingProvider);
|
const editorSetting$ = this.std.getOptional(
|
||||||
|
EditorSettingProvider
|
||||||
|
)?.setting$;
|
||||||
const nextProps = mergeWith(
|
const nextProps = mergeWith(
|
||||||
clonedeep(initProps),
|
clonedeep(initProps),
|
||||||
editorSetting$?.value,
|
editorSetting$?.value,
|
||||||
|
|||||||
@@ -10,21 +10,32 @@ export const GeneralSettingSchema = z
|
|||||||
.object({
|
.object({
|
||||||
edgelessScrollZoom: z.boolean().default(false),
|
edgelessScrollZoom: z.boolean().default(false),
|
||||||
edgelessDisableScheduleUpdate: z.boolean().default(false),
|
edgelessDisableScheduleUpdate: z.boolean().default(false),
|
||||||
|
docDropCanvasPreferView: z
|
||||||
|
.enum(['affine:embed-linked-doc', 'affine:embed-synced-doc'])
|
||||||
|
.default('affine:embed-synced-doc'),
|
||||||
})
|
})
|
||||||
.merge(NodePropsSchema);
|
.merge(NodePropsSchema);
|
||||||
|
|
||||||
export type EditorSetting = z.infer<typeof GeneralSettingSchema>;
|
export type EditorSetting = z.infer<typeof GeneralSettingSchema>;
|
||||||
|
|
||||||
export const EditorSettingProvider = createIdentifier<
|
export interface EditorSettingService {
|
||||||
Signal<DeepPartial<EditorSetting>>
|
setting$: Signal<DeepPartial<EditorSetting>>;
|
||||||
>('AffineEditorSettingProvider');
|
set?: (
|
||||||
|
key: keyof EditorSetting,
|
||||||
|
value: EditorSetting[keyof EditorSetting]
|
||||||
|
) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EditorSettingProvider = createIdentifier<EditorSettingService>(
|
||||||
|
'AffineEditorSettingProvider'
|
||||||
|
);
|
||||||
|
|
||||||
export function EditorSettingExtension(
|
export function EditorSettingExtension(
|
||||||
signal: Signal<DeepPartial<EditorSetting>>
|
service: EditorSettingService
|
||||||
): ExtensionType {
|
): ExtensionType {
|
||||||
return {
|
return {
|
||||||
setup: di => {
|
setup: di => {
|
||||||
di.addImpl(EditorSettingProvider, () => signal);
|
di.addImpl(EditorSettingProvider, () => service);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,14 +66,14 @@ export class PreviewHelper {
|
|||||||
blockIds = blockIds.slice();
|
blockIds = blockIds.slice();
|
||||||
|
|
||||||
const docModeService = std.get(DocModeProvider);
|
const docModeService = std.get(DocModeProvider);
|
||||||
const editorSetting = std.get(EditorSettingProvider).peek();
|
const editorSetting = std.get(EditorSettingProvider);
|
||||||
const query = this._calculateQuery(blockIds as string[]);
|
const query = this._calculateQuery(blockIds as string[]);
|
||||||
const store = widget.doc.doc.getStore({ query });
|
const store = widget.doc.doc.getStore({ query });
|
||||||
const previewSpec = SpecProvider._.getSpec('preview:page');
|
const previewSpec = SpecProvider._.getSpec('preview:page');
|
||||||
const settingSignal = signal({ ...editorSetting });
|
const settingSignal = signal({ ...editorSetting.setting$.peek() });
|
||||||
const extensions = [
|
const extensions = [
|
||||||
DocModeExtension(docModeService),
|
DocModeExtension(docModeService),
|
||||||
EditorSettingExtension(settingSignal),
|
EditorSettingExtension({ setting$: settingSignal }),
|
||||||
{
|
{
|
||||||
setup(di) {
|
setup(di) {
|
||||||
di.override(
|
di.override(
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ export function getTestCommonExtensions(
|
|||||||
): ExtensionType[] {
|
): ExtensionType[] {
|
||||||
return [
|
return [
|
||||||
FontConfigExtension(CommunityCanvasTextFonts),
|
FontConfigExtension(CommunityCanvasTextFonts),
|
||||||
EditorSettingExtension(mockEditorSetting()),
|
EditorSettingExtension({
|
||||||
|
setting$: mockEditorSetting(),
|
||||||
|
}),
|
||||||
ParseDocUrlExtension(mockParseDocUrlService(editor.doc.workspace)),
|
ParseDocUrlExtension(mockParseDocUrlService(editor.doc.workspace)),
|
||||||
{
|
{
|
||||||
setup: di => {
|
setup: di => {
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ export function getEditorConfigExtension(
|
|||||||
const baseUrl = workspaceServerService.server?.baseUrl ?? location.origin;
|
const baseUrl = workspaceServerService.server?.baseUrl ?? location.origin;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
EditorSettingExtension(editorSettingService.editorSetting.settingSignal),
|
EditorSettingExtension({
|
||||||
|
// eslint-disable-next-line rxjs/finnish
|
||||||
|
setting$: editorSettingService.editorSetting.settingSignal,
|
||||||
|
set: (k, v) => editorSettingService.editorSetting.set(k, v),
|
||||||
|
}),
|
||||||
DatabaseConfigExtension(createDatabaseOptionsConfig(framework)),
|
DatabaseConfigExtension(createDatabaseOptionsConfig(framework)),
|
||||||
LinkedWidgetConfigExtension(createLinkedWidgetConfig(framework)),
|
LinkedWidgetConfigExtension(createLinkedWidgetConfig(framework)),
|
||||||
ToolbarMoreMenuConfigExtension(createToolbarMoreMenuConfig(framework)),
|
ToolbarMoreMenuConfigExtension(createToolbarMoreMenuConfig(framework)),
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { type Framework } from '@toeverything/infra';
|
import { type Framework } from '@toeverything/infra';
|
||||||
|
|
||||||
import { DocsService } from '../doc';
|
import { DocsService } from '../doc';
|
||||||
|
import { EditorSettingService } from '../editor-setting';
|
||||||
import { WorkspaceScope, WorkspaceService } from '../workspace';
|
import { WorkspaceScope, WorkspaceService } from '../workspace';
|
||||||
import { DndService } from './services';
|
import { DndService } from './services';
|
||||||
|
|
||||||
export function configureDndModule(framework: Framework) {
|
export function configureDndModule(framework: Framework) {
|
||||||
framework
|
framework
|
||||||
.scope(WorkspaceScope)
|
.scope(WorkspaceScope)
|
||||||
.service(DndService, [DocsService, WorkspaceService]);
|
.service(DndService, [DocsService, WorkspaceService, EditorSettingService]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
type ExternalGetDataFeedbackArgs,
|
type ExternalGetDataFeedbackArgs,
|
||||||
type fromExternalData,
|
type fromExternalData,
|
||||||
|
type MonitorDragEvent,
|
||||||
monitorForElements,
|
monitorForElements,
|
||||||
type MonitorGetFeedback,
|
type MonitorGetFeedback,
|
||||||
type toExternalData,
|
type toExternalData,
|
||||||
@@ -16,6 +17,7 @@ import type { DragBlockPayload } from '@blocksuite/affine/widgets/drag-handle';
|
|||||||
import { Service } from '@toeverything/infra';
|
import { Service } from '@toeverything/infra';
|
||||||
|
|
||||||
import type { DocsService } from '../../doc';
|
import type { DocsService } from '../../doc';
|
||||||
|
import type { EditorSettingService } from '../../editor-setting';
|
||||||
import { resolveLinkToDoc } from '../../navigation';
|
import { resolveLinkToDoc } from '../../navigation';
|
||||||
import type { WorkspaceService } from '../../workspace';
|
import type { WorkspaceService } from '../../workspace';
|
||||||
|
|
||||||
@@ -31,7 +33,8 @@ type MixedDNDData = AffineDNDData & {
|
|||||||
export class DndService extends Service {
|
export class DndService extends Service {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly docsService: DocsService,
|
private readonly docsService: DocsService,
|
||||||
private readonly workspaceService: WorkspaceService
|
private readonly workspaceService: WorkspaceService,
|
||||||
|
private readonly editorSettingService: EditorSettingService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@@ -130,6 +133,43 @@ export class DndService extends Service {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBSDropTarget(args: MonitorDragEvent<MixedDNDData>) {
|
||||||
|
for (const target of args.location.current.dropTargets) {
|
||||||
|
const { tagName } = target.element;
|
||||||
|
if (['AFFINE-EDGELESS-NOTE', 'AFFINE-NOTE'].includes(tagName))
|
||||||
|
return 'note';
|
||||||
|
if (tagName === 'AFFINE-EDGELESS-ROOT') return 'canvas';
|
||||||
|
}
|
||||||
|
return 'other';
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeDocCardView = (args: MonitorDragEvent<MixedDNDData>) => {
|
||||||
|
if (args.source.data.from?.at === 'blocksuite-editor') return;
|
||||||
|
|
||||||
|
const dropTarget = getBSDropTarget(args);
|
||||||
|
if (dropTarget === 'other') return;
|
||||||
|
|
||||||
|
const flavour =
|
||||||
|
dropTarget === 'canvas'
|
||||||
|
? this.editorSettingService.editorSetting.docDropCanvasPreferView
|
||||||
|
.value
|
||||||
|
: 'affine:embed-linked-doc';
|
||||||
|
|
||||||
|
const { entity, bsEntity } = args.source.data;
|
||||||
|
if (!entity || !bsEntity) return;
|
||||||
|
|
||||||
|
const dndAPI = this.getBlocksuiteDndAPI();
|
||||||
|
if (!dndAPI) return;
|
||||||
|
|
||||||
|
const snapshotSlice = dndAPI.fromEntity({
|
||||||
|
docId: entity.id,
|
||||||
|
flavour,
|
||||||
|
});
|
||||||
|
if (!snapshotSlice) return;
|
||||||
|
|
||||||
|
bsEntity.snapshot = snapshotSlice;
|
||||||
|
};
|
||||||
|
|
||||||
this.disposables.push(
|
this.disposables.push(
|
||||||
monitorForElements({
|
monitorForElements({
|
||||||
canMonitor: (args: MonitorGetFeedback<MixedDNDData>) => {
|
canMonitor: (args: MonitorGetFeedback<MixedDNDData>) => {
|
||||||
@@ -144,6 +184,9 @@ export class DndService extends Service {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
onDropTargetChange: (args: MonitorDragEvent<MixedDNDData>) => {
|
||||||
|
changeDocCardView(args);
|
||||||
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
import { test } from '@affine-test/kit/playwright';
|
import { test } from '@affine-test/kit/playwright';
|
||||||
|
import {
|
||||||
|
clickEdgelessModeButton,
|
||||||
|
locateToolbar,
|
||||||
|
} from '@affine-test/kit/utils/editor';
|
||||||
|
import { pressBackspace, pressEnter } from '@affine-test/kit/utils/keyboard';
|
||||||
import { openHomePage } from '@affine-test/kit/utils/load-page';
|
import { openHomePage } from '@affine-test/kit/utils/load-page';
|
||||||
import {
|
import {
|
||||||
clickNewPageButton,
|
clickNewPageButton,
|
||||||
createLinkedPage,
|
createLinkedPage,
|
||||||
dragTo,
|
dragTo,
|
||||||
|
type,
|
||||||
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 { clickSideBarAllPageButton } from '@affine-test/kit/utils/sidebar';
|
||||||
@@ -293,7 +299,7 @@ test('drag a page card block to another page', async ({ page }) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('drag a favourite page into blocksuite', async ({ page }) => {
|
test('drag a favourite page into note on page mode', async ({ page }) => {
|
||||||
await clickNewPageButton(page, 'hi from page');
|
await clickNewPageButton(page, 'hi from page');
|
||||||
await page.getByTestId('pin-button').click();
|
await page.getByTestId('pin-button').click();
|
||||||
const pageId = getCurrentDocIdFromUrl(page);
|
const pageId = getCurrentDocIdFromUrl(page);
|
||||||
@@ -313,3 +319,93 @@ test('drag a favourite page into blocksuite', async ({ page }) => {
|
|||||||
'hi from page'
|
'hi from page'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('drag a favourite page into canvas on edgeless mode', async ({ page }) => {
|
||||||
|
await clickNewPageButton(page, 'hi from page');
|
||||||
|
await pressEnter(page);
|
||||||
|
await type(page, 'Hello world');
|
||||||
|
await page.getByTestId('pin-button').click();
|
||||||
|
const pageId = getCurrentDocIdFromUrl(page);
|
||||||
|
const item = page
|
||||||
|
.getByTestId(`explorer-favorites`)
|
||||||
|
.locator(`[data-testid="explorer-doc-${pageId}"]`);
|
||||||
|
await expect(item).toBeVisible();
|
||||||
|
|
||||||
|
await clickNewPageButton(page, 'edgeless page');
|
||||||
|
await clickEdgelessModeButton(page);
|
||||||
|
|
||||||
|
// drag item into blocksuite editor
|
||||||
|
await dragTo(page, item, page.locator('affine-edgeless-root').first());
|
||||||
|
|
||||||
|
const embedDoc = page.locator('affine-embed-edgeless-synced-doc-block');
|
||||||
|
await expect(embedDoc).toContainText('Hello world');
|
||||||
|
await embedDoc.click();
|
||||||
|
|
||||||
|
const toolbar = locateToolbar(page);
|
||||||
|
const switchViewButton = toolbar.getByLabel('Switch view');
|
||||||
|
await switchViewButton.click();
|
||||||
|
await toolbar.getByLabel('Card view').click(); // this will record the view as preferred view
|
||||||
|
const cardDoc = page.locator('affine-embed-edgeless-linked-doc-block');
|
||||||
|
await expect(embedDoc).toBeHidden();
|
||||||
|
await expect(cardDoc).toBeVisible();
|
||||||
|
|
||||||
|
await pressBackspace(page);
|
||||||
|
await expect(embedDoc).toBeHidden();
|
||||||
|
await expect(cardDoc).toBeHidden();
|
||||||
|
|
||||||
|
await dragTo(page, item, page.locator('affine-edgeless-root').first());
|
||||||
|
await expect(cardDoc).toBeVisible();
|
||||||
|
await expect(embedDoc).toBeHidden();
|
||||||
|
|
||||||
|
await page.reload();
|
||||||
|
await cardDoc.click();
|
||||||
|
await pressBackspace(page);
|
||||||
|
|
||||||
|
await dragTo(page, item, page.locator('affine-edgeless-root').first());
|
||||||
|
await expect(cardDoc, 'prefer view should be persistence').toBeVisible();
|
||||||
|
await expect(embedDoc).toBeHidden();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('drag a favourite page into note on edgeless mode', async ({ page }) => {
|
||||||
|
await clickNewPageButton(page, 'hi from page');
|
||||||
|
await pressEnter(page);
|
||||||
|
await type(page, 'Hello world');
|
||||||
|
await page.getByTestId('pin-button').click();
|
||||||
|
const pageId = getCurrentDocIdFromUrl(page);
|
||||||
|
const item = page
|
||||||
|
.getByTestId(`explorer-favorites`)
|
||||||
|
.locator(`[data-testid="explorer-doc-${pageId}"]`);
|
||||||
|
await expect(item).toBeVisible();
|
||||||
|
|
||||||
|
await clickNewPageButton(page, 'edgeless page');
|
||||||
|
await clickEdgelessModeButton(page);
|
||||||
|
|
||||||
|
const edgelessNote = page.locator('affine-edgeless-note');
|
||||||
|
await dragTo(page, item, edgelessNote);
|
||||||
|
|
||||||
|
const embedDocInNote = edgelessNote.locator('affine-embed-synced-doc-block');
|
||||||
|
const cardDocInNote = edgelessNote.locator('affine-embed-linked-doc-block');
|
||||||
|
|
||||||
|
await expect(embedDocInNote).toBeHidden();
|
||||||
|
await expect(cardDocInNote).toBeVisible();
|
||||||
|
|
||||||
|
await edgelessNote.click({ delay: 100 });
|
||||||
|
await edgelessNote.click({ delay: 100 });
|
||||||
|
await cardDocInNote.click();
|
||||||
|
|
||||||
|
const toolbar = locateToolbar(page);
|
||||||
|
const switchViewButton = toolbar.getByLabel('Switch view');
|
||||||
|
await switchViewButton.click();
|
||||||
|
await toolbar.getByLabel('Embed view').click(); // this should not record the view as preferred view
|
||||||
|
await expect(embedDocInNote).toBeVisible();
|
||||||
|
await expect(cardDocInNote).toBeHidden();
|
||||||
|
|
||||||
|
await pressBackspace(page);
|
||||||
|
|
||||||
|
await dragTo(page, item, edgelessNote);
|
||||||
|
await expect(
|
||||||
|
embedDocInNote,
|
||||||
|
'prefer view should only be available in canvas'
|
||||||
|
).toBeHidden();
|
||||||
|
await expect(cardDocInNote).toBeVisible();
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user