fix(core): improve doc title and icon display (#9755)
Closes: [AF-2132](https://linear.app/affine-design/issue/AF-2132/优化-emoji-title-和-icon-显示)
This commit is contained in:
@@ -229,10 +229,9 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
|
|||||||
title$ = computed(() => {
|
title$ = computed(() => {
|
||||||
const { pageId, params, title } = this.referenceInfo$.value;
|
const { pageId, params, title } = this.referenceInfo$.value;
|
||||||
return (
|
return (
|
||||||
title ||
|
|
||||||
this.std
|
this.std
|
||||||
.get(DocDisplayMetaProvider)
|
.get(DocDisplayMetaProvider)
|
||||||
.title(pageId, { params, title, referenced: true })
|
.title(pageId, { params, title, referenced: true }) || title
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -145,10 +145,9 @@ export class AffineReference extends WithDisposable(ShadowlessElement) {
|
|||||||
get _title() {
|
get _title() {
|
||||||
const { pageId, params, title } = this.referenceInfo;
|
const { pageId, params, title } = this.referenceInfo;
|
||||||
return (
|
return (
|
||||||
title ||
|
|
||||||
this.block?.std
|
this.block?.std
|
||||||
?.get(DocDisplayMetaProvider)
|
?.get(DocDisplayMetaProvider)
|
||||||
.title(pageId, { params, title, referenced: true }).value
|
.title(pageId, { params, title, referenced: true }).value || title
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ function AffinePageReferenceInner({
|
|||||||
mode: referenceWithMode ?? undefined,
|
mode: referenceWithMode ?? undefined,
|
||||||
reference: true,
|
reference: true,
|
||||||
referenceToNode,
|
referenceToNode,
|
||||||
hasTitleAlias: Boolean(title),
|
title,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -186,8 +186,8 @@ export function buildDocDisplayMetaExtension(framework: FrameworkProvider) {
|
|||||||
const icon$ = docDisplayMetaService
|
const icon$ = docDisplayMetaService
|
||||||
.icon$(docId, {
|
.icon$(docId, {
|
||||||
type: 'lit',
|
type: 'lit',
|
||||||
|
title,
|
||||||
reference: referenced,
|
reference: referenced,
|
||||||
hasTitleAlias: Boolean(title),
|
|
||||||
referenceToNode: referenceToNode({ pageId: docId, params }),
|
referenceToNode: referenceToNode({ pageId: docId, params }),
|
||||||
})
|
})
|
||||||
.map(iconBuilder);
|
.map(iconBuilder);
|
||||||
@@ -204,7 +204,7 @@ export function buildDocDisplayMetaExtension(framework: FrameworkProvider) {
|
|||||||
|
|
||||||
title(
|
title(
|
||||||
docId: string,
|
docId: string,
|
||||||
{ title = '', referenced }: DocDisplayMetaParams = {}
|
{ title, referenced }: DocDisplayMetaParams = {}
|
||||||
): Signal<string> {
|
): Signal<string> {
|
||||||
const title$ = docDisplayMetaService.title$(docId, {
|
const title$ = docDisplayMetaService.title$(docId, {
|
||||||
title,
|
title,
|
||||||
@@ -212,7 +212,7 @@ export function buildDocDisplayMetaExtension(framework: FrameworkProvider) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { signal: titleSignal, cleanup } =
|
const { signal: titleSignal, cleanup } =
|
||||||
createSignalFromObservable<string>(title$, title);
|
createSignalFromObservable<string>(title$, title ?? '');
|
||||||
|
|
||||||
this.disposables.push(cleanup);
|
this.disposables.push(cleanup);
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ const PageItem = ({
|
|||||||
const Icon = useLiveData(
|
const Icon = useLiveData(
|
||||||
docDisplayMetaService.icon$(docId, { compareDate: new Date() })
|
docDisplayMetaService.icon$(docId, { compareDate: new Date() })
|
||||||
);
|
);
|
||||||
const titleMeta = useLiveData(docDisplayMetaService.title$(docId));
|
const title = useLiveData(docDisplayMetaService.title$(docId));
|
||||||
const title = i18n.t(titleMeta);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WorkbenchLink
|
<WorkbenchLink
|
||||||
|
|||||||
@@ -55,8 +55,7 @@ const ConflictItem = ({ docRecord }: { docRecord: DocRecord }) => {
|
|||||||
const docId = docRecord.id;
|
const docId = docRecord.id;
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const docDisplayMetaService = useService(DocDisplayMetaService);
|
const docDisplayMetaService = useService(DocDisplayMetaService);
|
||||||
const titleMeta = useLiveData(docDisplayMetaService.title$(docId));
|
const title = useLiveData(docDisplayMetaService.title$(docId));
|
||||||
const title = i18n.t(titleMeta);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WorkbenchLink className={styles.docItem} to={`/${docId}`}>
|
<WorkbenchLink className={styles.docItem} to={`/${docId}`}>
|
||||||
|
|||||||
@@ -84,8 +84,7 @@ const DocItem = ({ docRecord }: { docRecord: DocRecord }) => {
|
|||||||
const Icon = useLiveData(
|
const Icon = useLiveData(
|
||||||
docDisplayMetaService.icon$(docId, { compareDate: new Date() })
|
docDisplayMetaService.icon$(docId, { compareDate: new Date() })
|
||||||
);
|
);
|
||||||
const titleMeta = useLiveData(docDisplayMetaService.title$(docId));
|
const title = useLiveData(docDisplayMetaService.title$(docId));
|
||||||
const title = i18n.t(titleMeta);
|
|
||||||
return (
|
return (
|
||||||
<WorkbenchLink aria-label={title} to={`/${docId}`}>
|
<WorkbenchLink aria-label={title} to={`/${docId}`}>
|
||||||
<MobileMenuItem
|
<MobileMenuItem
|
||||||
|
|||||||
@@ -23,13 +23,11 @@ interface JournalTodayActivityMenuItemProps {
|
|||||||
type Category = 'created' | 'updated';
|
type Category = 'created' | 'updated';
|
||||||
|
|
||||||
const DocItem = ({ docId }: { docId: string }) => {
|
const DocItem = ({ docId }: { docId: string }) => {
|
||||||
const i18n = useI18n();
|
|
||||||
const docDisplayMetaService = useService(DocDisplayMetaService);
|
const docDisplayMetaService = useService(DocDisplayMetaService);
|
||||||
const Icon = useLiveData(
|
const Icon = useLiveData(
|
||||||
docDisplayMetaService.icon$(docId, { compareDate: new Date() })
|
docDisplayMetaService.icon$(docId, { compareDate: new Date() })
|
||||||
);
|
);
|
||||||
const titleMeta = useLiveData(docDisplayMetaService.title$(docId));
|
const title = useLiveData(docDisplayMetaService.title$(docId));
|
||||||
const title = i18n.t(titleMeta);
|
|
||||||
return (
|
return (
|
||||||
<WorkbenchLink aria-label={title} to={`/${docId}`}>
|
<WorkbenchLink aria-label={title} to={`/${docId}`}>
|
||||||
<MenuItem prefixIcon={<Icon />}>{title}</MenuItem>
|
<MenuItem prefixIcon={<Icon />}>{title}</MenuItem>
|
||||||
|
|||||||
@@ -91,14 +91,10 @@ export class AtMenuConfigService extends Service {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let title = docDisplayMetaService.title$(meta.id, {
|
const title = docDisplayMetaService.title$(meta.id, {
|
||||||
reference: true,
|
reference: true,
|
||||||
}).value;
|
}).value;
|
||||||
|
|
||||||
if (typeof title === 'object' && 'i18nKey' in title) {
|
|
||||||
title = I18n.t(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fuzzyMatch(title, query)) {
|
if (!fuzzyMatch(title, query)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,16 +40,15 @@ interface DocDisplayIconOptions<T extends IconType> {
|
|||||||
* by default, it will use the `primaryMode$` of the doc.
|
* by default, it will use the `primaryMode$` of the doc.
|
||||||
*/
|
*/
|
||||||
mode?: 'edgeless' | 'page';
|
mode?: 'edgeless' | 'page';
|
||||||
|
title?: string; // title alias
|
||||||
reference?: boolean;
|
reference?: boolean;
|
||||||
referenceToNode?: boolean;
|
referenceToNode?: boolean;
|
||||||
hasTitleAlias?: boolean;
|
|
||||||
/**
|
/**
|
||||||
* @default true
|
* @default true
|
||||||
*/
|
*/
|
||||||
enableEmojiIcon?: boolean;
|
enableEmojiIcon?: boolean;
|
||||||
}
|
}
|
||||||
interface DocDisplayTitleOptions {
|
interface DocDisplayTitleOptions {
|
||||||
originalTitle?: string;
|
|
||||||
title?: string; // title alias
|
title?: string; // title alias
|
||||||
reference?: boolean;
|
reference?: boolean;
|
||||||
/**
|
/**
|
||||||
@@ -130,24 +129,31 @@ export class DocDisplayMetaService extends Service {
|
|||||||
const iconSet = icons[options?.type ?? 'rc'];
|
const iconSet = icons[options?.type ?? 'rc'];
|
||||||
|
|
||||||
return LiveData.computed(get => {
|
return LiveData.computed(get => {
|
||||||
|
const enableEmojiIcon =
|
||||||
|
get(this.featureFlagService.flags.enable_emoji_doc_icon.$) &&
|
||||||
|
options?.enableEmojiIcon !== false;
|
||||||
const doc = get(this.docsService.list.doc$(docId));
|
const doc = get(this.docsService.list.doc$(docId));
|
||||||
const title = doc ? get(doc.title$) : '';
|
const referenced = !!options?.reference;
|
||||||
|
const titleAlias = referenced ? options?.title : undefined;
|
||||||
|
const originalTitle = doc ? get(doc.title$) : '';
|
||||||
|
const title = titleAlias ?? originalTitle;
|
||||||
const mode = doc ? get(doc.primaryMode$) : undefined;
|
const mode = doc ? get(doc.primaryMode$) : undefined;
|
||||||
const finalMode = options?.mode ?? mode ?? 'page';
|
const finalMode = options?.mode ?? mode ?? 'page';
|
||||||
const referenceToNode = !!(options?.reference && options.referenceToNode);
|
const referenceToNode = !!(referenced && options.referenceToNode);
|
||||||
const hasTitleAlias = !!(options?.reference && options?.hasTitleAlias);
|
|
||||||
|
|
||||||
// increases block link priority with title alias
|
// emoji title
|
||||||
if (hasTitleAlias) {
|
if (enableEmojiIcon && title) {
|
||||||
return iconSet.AliasIcon;
|
const { emoji } = extractEmojiIcon(title);
|
||||||
|
if (emoji) return () => emoji;
|
||||||
}
|
}
|
||||||
|
|
||||||
// increases block link priority
|
// title alias
|
||||||
if (referenceToNode) {
|
if (titleAlias) return iconSet.AliasIcon;
|
||||||
return iconSet.BlockLinkIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
// journal icon
|
// link to specified block
|
||||||
|
if (referenceToNode) return iconSet.BlockLinkIcon;
|
||||||
|
|
||||||
|
// link to journal doc
|
||||||
const journalDate = this._toDayjs(
|
const journalDate = this._toDayjs(
|
||||||
get(this.journalService.journalDate$(docId))
|
get(this.journalService.journalDate$(docId))
|
||||||
);
|
);
|
||||||
@@ -155,22 +161,13 @@ export class DocDisplayMetaService extends Service {
|
|||||||
return this.getJournalIcon(journalDate, options);
|
return this.getJournalIcon(journalDate, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reference icon
|
// link to regular doc (reference)
|
||||||
if (options?.reference) {
|
if (options?.reference) {
|
||||||
return finalMode === 'edgeless'
|
return finalMode === 'edgeless'
|
||||||
? iconSet.LinkedEdgelessIcon
|
? iconSet.LinkedEdgelessIcon
|
||||||
: iconSet.LinkedPageIcon;
|
: iconSet.LinkedPageIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// emoji icon
|
|
||||||
const enableEmojiIcon =
|
|
||||||
get(this.featureFlagService.flags.enable_emoji_doc_icon.$) &&
|
|
||||||
options?.enableEmojiIcon !== false;
|
|
||||||
if (enableEmojiIcon) {
|
|
||||||
const { emoji } = extractEmojiIcon(title);
|
|
||||||
if (emoji) return () => emoji;
|
|
||||||
}
|
|
||||||
|
|
||||||
// default icon
|
// default icon
|
||||||
return finalMode === 'edgeless' ? iconSet.EdgelessIcon : iconSet.PageIcon;
|
return finalMode === 'edgeless' ? iconSet.EdgelessIcon : iconSet.PageIcon;
|
||||||
});
|
});
|
||||||
@@ -183,14 +180,28 @@ export class DocDisplayMetaService extends Service {
|
|||||||
options?.enableEmojiIcon !== false;
|
options?.enableEmojiIcon !== false;
|
||||||
const lng = get(this.i18nService.i18n.currentLanguageKey$);
|
const lng = get(this.i18nService.i18n.currentLanguageKey$);
|
||||||
const doc = get(this.docsService.list.doc$(docId));
|
const doc = get(this.docsService.list.doc$(docId));
|
||||||
|
const referenced = !!options?.reference;
|
||||||
|
const titleAlias = referenced ? options?.title : undefined;
|
||||||
|
const originalTitle = doc ? get(doc.title$) : '';
|
||||||
|
const title = titleAlias ?? originalTitle;
|
||||||
|
|
||||||
// title alias
|
// emoji title
|
||||||
if (options?.title) {
|
if (enableEmojiIcon && title) {
|
||||||
return enableEmojiIcon
|
const { rest } = extractEmojiIcon(title);
|
||||||
? extractEmojiIcon(options.title).rest
|
if (rest) return rest;
|
||||||
: options.title;
|
|
||||||
|
// When the title has only one emoji character,
|
||||||
|
// if it's a journal document, the date should be displayed.
|
||||||
|
const journalDateString = get(this.journalService.journalDate$(docId));
|
||||||
|
if (journalDateString) {
|
||||||
|
return i18nTime(journalDateString, { absolute: { accuracy: 'day' } });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// title alias
|
||||||
|
if (titleAlias) return titleAlias;
|
||||||
|
|
||||||
|
// doc not found
|
||||||
if (!doc) {
|
if (!doc) {
|
||||||
return this.i18nService.i18n.i18next.t(
|
return this.i18nService.i18n.i18next.t(
|
||||||
'com.affine.notFoundPage.title',
|
'com.affine.notFoundPage.title',
|
||||||
@@ -205,31 +216,16 @@ export class DocDisplayMetaService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// original title
|
// original title
|
||||||
if (options?.originalTitle) return options.originalTitle;
|
if (originalTitle) return originalTitle;
|
||||||
|
|
||||||
const docTitle = get(doc.title$);
|
|
||||||
|
|
||||||
// empty title
|
// empty title
|
||||||
if (!docTitle) {
|
|
||||||
return this.i18nService.i18n.i18next.t('Untitled', { lng });
|
return this.i18nService.i18n.i18next.t('Untitled', { lng });
|
||||||
}
|
|
||||||
|
|
||||||
// reference
|
|
||||||
if (options?.reference) return docTitle;
|
|
||||||
|
|
||||||
// emoji icon
|
|
||||||
if (enableEmojiIcon) {
|
|
||||||
return extractEmojiIcon(docTitle).rest;
|
|
||||||
}
|
|
||||||
|
|
||||||
// default
|
|
||||||
return docTitle;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getDocDisplayMeta(docRecord: DocRecord, originalTitle?: string) {
|
getDocDisplayMeta(docRecord: DocRecord) {
|
||||||
return {
|
return {
|
||||||
title: this.title$(docRecord.id, { originalTitle }).value,
|
title: this.title$(docRecord.id).value,
|
||||||
icon: this.icon$(docRecord.id).value,
|
icon: this.icon$(docRecord.id).value,
|
||||||
updatedDate: docRecord.meta$.value.updatedDate,
|
updatedDate: docRecord.meta$.value.updatedDate,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -66,10 +66,7 @@ export class DocsQuickSearchSession
|
|||||||
)
|
)
|
||||||
.map(([doc, docRecord]) => {
|
.map(([doc, docRecord]) => {
|
||||||
const { title, icon, updatedDate } =
|
const { title, icon, updatedDate } =
|
||||||
this.docDisplayMetaService.getDocDisplayMeta(
|
this.docDisplayMetaService.getDocDisplayMeta(docRecord);
|
||||||
docRecord,
|
|
||||||
'title' in doc ? doc.title : undefined
|
|
||||||
);
|
|
||||||
return {
|
return {
|
||||||
id: 'doc:' + docRecord.id,
|
id: 'doc:' + docRecord.id,
|
||||||
source: 'docs',
|
source: 'docs',
|
||||||
|
|||||||
@@ -8,10 +8,17 @@ import { coreUrl, openHomePage } from '@affine-test/kit/utils/load-page';
|
|||||||
import {
|
import {
|
||||||
clickNewPageButton,
|
clickNewPageButton,
|
||||||
createLinkedPage,
|
createLinkedPage,
|
||||||
|
createTodayPage,
|
||||||
getBlockSuiteEditorTitle,
|
getBlockSuiteEditorTitle,
|
||||||
|
waitForEditorLoad,
|
||||||
waitForEmptyEditor,
|
waitForEmptyEditor,
|
||||||
} from '@affine-test/kit/utils/page-logic';
|
} from '@affine-test/kit/utils/page-logic';
|
||||||
import { expect, type Locator } from '@playwright/test';
|
import {
|
||||||
|
confirmExperimentalPrompt,
|
||||||
|
openEditorSetting,
|
||||||
|
openExperimentalFeaturesPanel,
|
||||||
|
} from '@affine-test/kit/utils/setting';
|
||||||
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
@@ -19,6 +26,26 @@ test.beforeEach(async ({ page }) => {
|
|||||||
await waitForEmptyEditor(page);
|
await waitForEmptyEditor(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function enableEmojiDocIcon(page: Page) {
|
||||||
|
// Opens settings panel
|
||||||
|
await openEditorSetting(page);
|
||||||
|
await openExperimentalFeaturesPanel(page);
|
||||||
|
await confirmExperimentalPrompt(page);
|
||||||
|
|
||||||
|
const settingModal = page.locator('[data-testid=setting-modal-content]');
|
||||||
|
const item = settingModal.locator('div').getByText('Emoji Doc Icon');
|
||||||
|
await item.waitFor({ state: 'attached' });
|
||||||
|
await expect(item).toBeVisible();
|
||||||
|
const button = item.locator('label');
|
||||||
|
const isChecked = await button.locator('input').isChecked();
|
||||||
|
if (!isChecked) {
|
||||||
|
await button.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Closes settings panel
|
||||||
|
await page.keyboard.press('Escape');
|
||||||
|
}
|
||||||
|
|
||||||
async function notClickable(locator: Locator) {
|
async function notClickable(locator: Locator) {
|
||||||
await expect(locator).toHaveAttribute('disabled', '');
|
await expect(locator).toHaveAttribute('disabled', '');
|
||||||
}
|
}
|
||||||
@@ -908,4 +935,65 @@ test.describe('Customize linked doc title and description', () => {
|
|||||||
embedToolbar.getByRole('button', { name: 'Doc title' })
|
embedToolbar.getByRole('button', { name: 'Doc title' })
|
||||||
).toBeHidden();
|
).toBeHidden();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should show emoji doc icon in normal document', async ({ page }) => {
|
||||||
|
await waitForEditorLoad(page);
|
||||||
|
await enableEmojiDocIcon(page);
|
||||||
|
|
||||||
|
await clickNewPageButton(page);
|
||||||
|
const title = getBlockSuiteEditorTitle(page);
|
||||||
|
await title.click();
|
||||||
|
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
|
await createLinkedPage(page, 'Test Page');
|
||||||
|
|
||||||
|
const inlineLink = page.locator('affine-reference');
|
||||||
|
const inlineToolbar = page.locator('reference-popup');
|
||||||
|
|
||||||
|
await inlineLink.hover();
|
||||||
|
|
||||||
|
// Edits title
|
||||||
|
await inlineToolbar.getByRole('button', { name: 'Edit' }).click();
|
||||||
|
|
||||||
|
// Title alias
|
||||||
|
await page.keyboard.type('🦀hello');
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
|
|
||||||
|
const a = inlineLink.locator('a');
|
||||||
|
|
||||||
|
await expect(a).toHaveText('🦀hello');
|
||||||
|
await expect(a.locator('svg')).toBeHidden();
|
||||||
|
await expect(a.locator('.affine-reference-title')).toHaveText('hello');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should show emoji doc icon in journal document', async ({ page }) => {
|
||||||
|
await waitForEditorLoad(page);
|
||||||
|
await enableEmojiDocIcon(page);
|
||||||
|
|
||||||
|
await clickNewPageButton(page);
|
||||||
|
const title = getBlockSuiteEditorTitle(page);
|
||||||
|
await title.click();
|
||||||
|
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
|
await createTodayPage(page);
|
||||||
|
|
||||||
|
const inlineLink = page.locator('affine-reference');
|
||||||
|
const inlineToolbar = page.locator('reference-popup');
|
||||||
|
|
||||||
|
await inlineLink.hover();
|
||||||
|
|
||||||
|
// Edits title
|
||||||
|
await inlineToolbar.getByRole('button', { name: 'Edit' }).click();
|
||||||
|
|
||||||
|
// Title alias
|
||||||
|
await page.keyboard.type('🦀');
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
|
|
||||||
|
const a = inlineLink.locator('a');
|
||||||
|
|
||||||
|
const year = String(new Date().getFullYear());
|
||||||
|
await expect(a).toContainText('🦀');
|
||||||
|
await expect(a.locator('svg')).toBeHidden();
|
||||||
|
await expect(a.locator('.affine-reference-title')).toContainText(year);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -76,6 +76,21 @@ export const createLinkedPage = async (page: Page, pageName?: string) => {
|
|||||||
.click();
|
.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createTodayPage = async (page: Page) => {
|
||||||
|
// fixme: workaround for @ popover not showing up when editor is not ready
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
await page.keyboard.type('@', { delay: 50 });
|
||||||
|
const linkedPagePopover = page.locator('.linked-doc-popover');
|
||||||
|
await expect(linkedPagePopover).toBeVisible();
|
||||||
|
await type(page, 'Today');
|
||||||
|
|
||||||
|
await linkedPagePopover
|
||||||
|
.locator(`icon-button`)
|
||||||
|
.filter({ hasText: 'Today' })
|
||||||
|
.nth(0)
|
||||||
|
.click();
|
||||||
|
};
|
||||||
|
|
||||||
export async function clickPageMoreActions(page: Page) {
|
export async function clickPageMoreActions(page: Page) {
|
||||||
return page
|
return page
|
||||||
.getByTestId('header')
|
.getByTestId('header')
|
||||||
|
|||||||
Reference in New Issue
Block a user