mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-24 04:27:27 +08:00
feat(core): add a two-step confirm page to create new journal (#13240)
close AF-2750; <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced a new workspace journals page with date-based navigation, placeholder UI, and the ability to create daily journals directly from the page. * Added a "Today" button for quick navigation to the current day's journal when viewing other dates. * **Improvements** * Enhanced the journal document title display with improved date formatting and flexible styling. * Expanded the active state for the journal sidebar button to cover all journal-related routes. * Updated journal navigation to open existing entries directly or navigate to filtered journal listings. * **Bug Fixes** * Improved date handling and navigation logic for journal entries to ensure accurate redirection and creation flows. * **Style** * Added new styles for the workspace journals page, including headers, placeholders, and buttons. * **Localization** * Added English translations for journal placeholder text and create journal prompts. * **Tests** * Added confirmation steps in journal creation flows to improve test reliability. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -9,20 +9,40 @@ import * as styles from './styles.css';
|
|||||||
export const BlocksuiteEditorJournalDocTitle = ({ page }: { page: Store }) => {
|
export const BlocksuiteEditorJournalDocTitle = ({ page }: { page: Store }) => {
|
||||||
const journalService = useService(JournalService);
|
const journalService = useService(JournalService);
|
||||||
const journalDateStr = useLiveData(journalService.journalDate$(page.id));
|
const journalDateStr = useLiveData(journalService.journalDate$(page.id));
|
||||||
const journalDate = journalDateStr ? dayjs(journalDateStr) : null;
|
|
||||||
const isTodayJournal = useLiveData(journalService.journalToday$(page.id));
|
return <BlocksuiteEditorJournalDocTitleUI date={journalDateStr} />;
|
||||||
const localizedJournalDate = i18nTime(journalDateStr, {
|
};
|
||||||
|
|
||||||
|
export const BlocksuiteEditorJournalDocTitleUI = ({
|
||||||
|
date: dateStr,
|
||||||
|
overrideClassName,
|
||||||
|
}: {
|
||||||
|
date?: string;
|
||||||
|
/**
|
||||||
|
* The `doc-title-container` class style is defined in editor,
|
||||||
|
* which means if we use this component outside editor, the style will not work,
|
||||||
|
* so we provide a className to override
|
||||||
|
*/
|
||||||
|
overrideClassName?: string;
|
||||||
|
}) => {
|
||||||
|
const localizedJournalDate = i18nTime(dateStr, {
|
||||||
absolute: { accuracy: 'day' },
|
absolute: { accuracy: 'day' },
|
||||||
});
|
});
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
// TODO(catsjuice): i18n
|
// TODO(catsjuice): i18n
|
||||||
const day = journalDate?.format('dddd') ?? null;
|
const today = dayjs();
|
||||||
|
const date = dayjs(dateStr);
|
||||||
|
const day = dayjs(date).format('dddd') ?? null;
|
||||||
|
const isToday = date.isSame(today, 'day');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="doc-title-container" data-testid="journal-title">
|
<div
|
||||||
|
className={overrideClassName ?? 'doc-title-container'}
|
||||||
|
data-testid="journal-title"
|
||||||
|
>
|
||||||
<span data-testid="date">{localizedJournalDate}</span>
|
<span data-testid="date">{localizedJournalDate}</span>
|
||||||
{isTodayJournal ? (
|
{isToday ? (
|
||||||
<span className={styles.titleTodayTag} data-testid="date-today-label">
|
<span className={styles.titleTodayTag} data-testid="date-today-label">
|
||||||
{t['com.affine.today']()}
|
{t['com.affine.today']()}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import type { WeekDatePickerHandle } from '@affine/component';
|
import type { WeekDatePickerHandle } from '@affine/component';
|
||||||
import { WeekDatePicker } from '@affine/component';
|
import { WeekDatePicker } from '@affine/component';
|
||||||
import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal';
|
import {
|
||||||
import { JournalService } from '@affine/core/modules/journal';
|
JOURNAL_DATE_FORMAT,
|
||||||
|
JournalService,
|
||||||
|
} from '@affine/core/modules/journal';
|
||||||
|
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||||
import type { Store } from '@blocksuite/affine/store';
|
import type { Store } from '@blocksuite/affine/store';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
export interface JournalWeekDatePickerProps {
|
export interface JournalWeekDatePickerProps {
|
||||||
page: Store;
|
page: Store;
|
||||||
@@ -17,17 +20,29 @@ export const JournalWeekDatePicker = ({ page }: JournalWeekDatePickerProps) => {
|
|||||||
const journalService = useService(JournalService);
|
const journalService = useService(JournalService);
|
||||||
const journalDateStr = useLiveData(journalService.journalDate$(page.id));
|
const journalDateStr = useLiveData(journalService.journalDate$(page.id));
|
||||||
const journalDate = journalDateStr ? dayjs(journalDateStr) : null;
|
const journalDate = journalDateStr ? dayjs(journalDateStr) : null;
|
||||||
const { openJournal } = useJournalRouteHelper();
|
|
||||||
const [date, setDate] = useState(
|
const [date, setDate] = useState(
|
||||||
(journalDate ?? dayjs()).format('YYYY-MM-DD')
|
(journalDate ?? dayjs()).format(JOURNAL_DATE_FORMAT)
|
||||||
);
|
);
|
||||||
|
const workbench = useService(WorkbenchService).workbench;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!journalDate) return;
|
if (!journalDate) return;
|
||||||
setDate(journalDate.format('YYYY-MM-DD'));
|
setDate(journalDate.format(JOURNAL_DATE_FORMAT));
|
||||||
handleRef.current?.setCursor?.(journalDate);
|
handleRef.current?.setCursor?.(journalDate);
|
||||||
}, [journalDate]);
|
}, [journalDate]);
|
||||||
|
|
||||||
|
const openJournal = useCallback(
|
||||||
|
(date: string) => {
|
||||||
|
const docs = journalService.journalsByDate$(date).value;
|
||||||
|
if (docs.length > 0) {
|
||||||
|
workbench.openDoc(docs[0].id, { at: 'active' });
|
||||||
|
} else {
|
||||||
|
workbench.open(`/journals?date=${date}`, { at: 'active' });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[journalService, workbench]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WeekDatePicker
|
<WeekDatePicker
|
||||||
data-testid="journal-week-picker"
|
data-testid="journal-week-picker"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const AppSidebarJournalButton = () => {
|
|||||||
return (
|
return (
|
||||||
<MenuLinkItem
|
<MenuLinkItem
|
||||||
data-testid="slider-bar-journals-button"
|
data-testid="slider-bar-journals-button"
|
||||||
active={isJournal}
|
active={isJournal || location.pathname.startsWith('/journals')}
|
||||||
to={'/journals'}
|
to={'/journals'}
|
||||||
icon={<Icon />}
|
icon={<Icon />}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
// this route page acts as a redirector to today's journal
|
|
||||||
export const Component = () => {
|
|
||||||
const { openToday } = useJournalRouteHelper();
|
|
||||||
useEffect(() => {
|
|
||||||
openToday({ replaceHistory: true });
|
|
||||||
}, [openToday]);
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
+17
-3
@@ -9,7 +9,6 @@ import {
|
|||||||
useConfirmModal,
|
useConfirmModal,
|
||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import { Guard } from '@affine/core/components/guard';
|
import { Guard } from '@affine/core/components/guard';
|
||||||
import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal';
|
|
||||||
import { MoveToTrash } from '@affine/core/components/page-list';
|
import { MoveToTrash } from '@affine/core/components/page-list';
|
||||||
import {
|
import {
|
||||||
type DocRecord,
|
type DocRecord,
|
||||||
@@ -18,7 +17,10 @@ import {
|
|||||||
} from '@affine/core/modules/doc';
|
} from '@affine/core/modules/doc';
|
||||||
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
||||||
import { JournalService } from '@affine/core/modules/journal';
|
import { JournalService } from '@affine/core/modules/journal';
|
||||||
import { WorkbenchLink } from '@affine/core/modules/workbench';
|
import {
|
||||||
|
WorkbenchLink,
|
||||||
|
WorkbenchService,
|
||||||
|
} from '@affine/core/modules/workbench';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { CalendarXmarkIcon, EditIcon } from '@blocksuite/icons/rc';
|
import { CalendarXmarkIcon, EditIcon } from '@blocksuite/icons/rc';
|
||||||
import {
|
import {
|
||||||
@@ -103,13 +105,25 @@ const mobile = environment.isMobile;
|
|||||||
export const EditorJournalPanel = () => {
|
export const EditorJournalPanel = () => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const doc = useServiceOptional(DocService)?.doc;
|
const doc = useServiceOptional(DocService)?.doc;
|
||||||
|
const workbench = useService(WorkbenchService).workbench;
|
||||||
const journalService = useService(JournalService);
|
const journalService = useService(JournalService);
|
||||||
const journalDateStr = useLiveData(
|
const journalDateStr = useLiveData(
|
||||||
doc ? journalService.journalDate$(doc.id) : null
|
doc ? journalService.journalDate$(doc.id) : null
|
||||||
);
|
);
|
||||||
const journalDate = journalDateStr ? dayjs(journalDateStr) : null;
|
const journalDate = journalDateStr ? dayjs(journalDateStr) : null;
|
||||||
const isJournal = !!journalDate;
|
const isJournal = !!journalDate;
|
||||||
const { openJournal } = useJournalRouteHelper();
|
|
||||||
|
const openJournal = useCallback(
|
||||||
|
(date: string) => {
|
||||||
|
const docs = journalService.journalsByDate$(date).value;
|
||||||
|
if (docs.length > 0) {
|
||||||
|
workbench.openDoc(docs[0].id, { at: 'active' });
|
||||||
|
} else {
|
||||||
|
workbench.open(`/journals?date=${date}`, { at: 'active' });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[journalService, workbench]
|
||||||
|
);
|
||||||
|
|
||||||
const onDateSelect = useCallback(
|
const onDateSelect = useCallback(
|
||||||
(date: string) => {
|
(date: string) => {
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
export const header = style({
|
||||||
|
display: 'flex',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
position: 'relative',
|
||||||
|
padding: '0 36px',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const todayButton = style({
|
||||||
|
position: 'absolute',
|
||||||
|
right: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const body = style({
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
borderTop: `0.5px solid ${cssVarV2.layer.insideBorder.border}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const content = style({
|
||||||
|
maxWidth: 944,
|
||||||
|
padding: '0px 50px',
|
||||||
|
margin: '0 auto',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const docTitleContainer = style({
|
||||||
|
color: cssVarV2.text.primary,
|
||||||
|
fontSize: 40,
|
||||||
|
lineHeight: '50px',
|
||||||
|
fontWeight: 700,
|
||||||
|
padding: '38px 0',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const placeholder = style({
|
||||||
|
height: 200,
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
border: `1px dashed ${cssVarV2.layer.insideBorder.border}`,
|
||||||
|
borderRadius: 8,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const placeholderIcon = style({
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
borderRadius: 36,
|
||||||
|
backgroundColor: cssVarV2.button.emptyIconBackground,
|
||||||
|
color: cssVarV2.icon.primary,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: 20,
|
||||||
|
marginBottom: 4,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const placeholderText = style({
|
||||||
|
fontSize: 14,
|
||||||
|
lineHeight: '22px',
|
||||||
|
marginBottom: 16,
|
||||||
|
color: cssVarV2.text.tertiary,
|
||||||
|
});
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
WeekDatePicker,
|
||||||
|
type WeekDatePickerHandle,
|
||||||
|
} from '@affine/component';
|
||||||
|
import { BlocksuiteEditorJournalDocTitleUI } from '@affine/core/blocksuite/block-suite-editor/journal-doc-title';
|
||||||
|
import {
|
||||||
|
JOURNAL_DATE_FORMAT,
|
||||||
|
JournalService,
|
||||||
|
} from '@affine/core/modules/journal';
|
||||||
|
import {
|
||||||
|
ViewBody,
|
||||||
|
ViewHeader,
|
||||||
|
ViewIcon,
|
||||||
|
ViewService,
|
||||||
|
ViewTitle,
|
||||||
|
WorkbenchService,
|
||||||
|
} from '@affine/core/modules/workbench';
|
||||||
|
import { useI18n } from '@affine/i18n';
|
||||||
|
import { TodayIcon } from '@blocksuite/icons/rc';
|
||||||
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import type { Location } from 'history';
|
||||||
|
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import { AllDocSidebarTabs } from '../layouts/all-doc-sidebar-tabs';
|
||||||
|
import * as styles from './index.css';
|
||||||
|
|
||||||
|
function getDateFromUrl(location: Location) {
|
||||||
|
const searchParams = new URLSearchParams(location.search);
|
||||||
|
const date = searchParams.get('date')
|
||||||
|
? dayjs(searchParams.get('date'))
|
||||||
|
: dayjs();
|
||||||
|
return date.format(JOURNAL_DATE_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
const weekStyle = { maxWidth: 800, width: '100%' };
|
||||||
|
// this route page acts as a redirector to today's journal
|
||||||
|
export const Component = () => {
|
||||||
|
const handleRef = useRef<WeekDatePickerHandle>(null);
|
||||||
|
|
||||||
|
const t = useI18n();
|
||||||
|
const journalService = useService(JournalService);
|
||||||
|
const workbench = useService(WorkbenchService).workbench;
|
||||||
|
const view = useService(ViewService).view;
|
||||||
|
const location = useLiveData(view.location$);
|
||||||
|
const dateString = getDateFromUrl(location);
|
||||||
|
const todayString = dayjs().format(JOURNAL_DATE_FORMAT);
|
||||||
|
const isToday = dateString === todayString;
|
||||||
|
|
||||||
|
const [redirecting, setRedirecting] = useState(false);
|
||||||
|
const [ready, setReady] = useState(false);
|
||||||
|
|
||||||
|
const createJournal = useCallback(() => {
|
||||||
|
if (redirecting) return;
|
||||||
|
setRedirecting(true);
|
||||||
|
const doc = journalService.ensureJournalByDate(dateString);
|
||||||
|
workbench.openDoc(doc.id, {
|
||||||
|
replaceHistory: true,
|
||||||
|
at: 'active',
|
||||||
|
});
|
||||||
|
}, [dateString, journalService, redirecting, workbench]);
|
||||||
|
|
||||||
|
const openJournal = useCallback(
|
||||||
|
(date: string) => {
|
||||||
|
workbench.open(`/journals?date=${date}`, { at: 'active' });
|
||||||
|
},
|
||||||
|
[workbench]
|
||||||
|
);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
// only handle current route
|
||||||
|
if (!location.pathname.startsWith('/journals')) return;
|
||||||
|
|
||||||
|
// check if the journal is created
|
||||||
|
const docs = journalService.journalsByDate$(dateString).value;
|
||||||
|
if (docs.length === 0) {
|
||||||
|
setReady(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if created, redirect to the journal
|
||||||
|
const journal = docs[0];
|
||||||
|
workbench.openDoc(journal.id, { replaceHistory: true, at: 'active' });
|
||||||
|
}, [dateString, journalService, location.pathname, view, workbench]);
|
||||||
|
|
||||||
|
if (!ready) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewTitle title="" />
|
||||||
|
<ViewIcon icon="journal" />
|
||||||
|
<ViewHeader>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<WeekDatePicker
|
||||||
|
data-testid="journal-week-picker"
|
||||||
|
handleRef={handleRef}
|
||||||
|
style={weekStyle}
|
||||||
|
value={dateString}
|
||||||
|
onChange={openJournal}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{!isToday ? (
|
||||||
|
<Button
|
||||||
|
className={styles.todayButton}
|
||||||
|
onClick={() => openJournal(todayString)}
|
||||||
|
>
|
||||||
|
{t['com.affine.today']()}
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</ViewHeader>
|
||||||
|
<ViewBody>
|
||||||
|
<div className={styles.body}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<BlocksuiteEditorJournalDocTitleUI
|
||||||
|
date={dateString}
|
||||||
|
overrideClassName={styles.docTitleContainer}
|
||||||
|
/>
|
||||||
|
<div className={styles.placeholder}>
|
||||||
|
<div className={styles.placeholderIcon}>
|
||||||
|
<TodayIcon />
|
||||||
|
</div>
|
||||||
|
<div className={styles.placeholderText}>
|
||||||
|
{t['com.affine.journal.placeholder.title']()}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
onClick={createJournal}
|
||||||
|
data-testid="confirm-create-journal-button"
|
||||||
|
>
|
||||||
|
{t['com.affine.journal.placeholder.create']()}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ViewBody>
|
||||||
|
<AllDocSidebarTabs />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -39,7 +39,7 @@ export const workbenchRoutes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/journals',
|
path: '/journals',
|
||||||
lazy: () => import('./pages/journals'),
|
lazy: () => import('./pages/workspace/journals'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
|
|||||||
@@ -2493,6 +2493,14 @@ export function useAFFiNEI18N(): {
|
|||||||
* `Updated`
|
* `Updated`
|
||||||
*/
|
*/
|
||||||
["com.affine.journal.updated-today"](): string;
|
["com.affine.journal.updated-today"](): string;
|
||||||
|
/**
|
||||||
|
* `No Journal`
|
||||||
|
*/
|
||||||
|
["com.affine.journal.placeholder.title"](): string;
|
||||||
|
/**
|
||||||
|
* `Create Daily Journal`
|
||||||
|
*/
|
||||||
|
["com.affine.journal.placeholder.create"](): string;
|
||||||
/**
|
/**
|
||||||
* `Just now`
|
* `Just now`
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -622,6 +622,8 @@
|
|||||||
"com.affine.journal.daily-count-created-empty-tips": "You haven't created anything yet",
|
"com.affine.journal.daily-count-created-empty-tips": "You haven't created anything yet",
|
||||||
"com.affine.journal.daily-count-updated-empty-tips": "You haven't updated anything yet",
|
"com.affine.journal.daily-count-updated-empty-tips": "You haven't updated anything yet",
|
||||||
"com.affine.journal.updated-today": "Updated",
|
"com.affine.journal.updated-today": "Updated",
|
||||||
|
"com.affine.journal.placeholder.title": "No Journal",
|
||||||
|
"com.affine.journal.placeholder.create": "Create Daily Journal",
|
||||||
"com.affine.just-now": "Just now",
|
"com.affine.just-now": "Just now",
|
||||||
"com.affine.keyboardShortcuts.appendDailyNote": "Append to daily note",
|
"com.affine.keyboardShortcuts.appendDailyNote": "Append to daily note",
|
||||||
"com.affine.keyboardShortcuts.bodyText": "Body text",
|
"com.affine.keyboardShortcuts.bodyText": "Body text",
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ test('tab title will change when navigating', async ({ page }) => {
|
|||||||
|
|
||||||
// go to today's journal
|
// go to today's journal
|
||||||
await page.getByTestId('slider-bar-journals-button').click();
|
await page.getByTestId('slider-bar-journals-button').click();
|
||||||
|
await page.getByTestId('confirm-create-journal-button').click();
|
||||||
await expect(page.locator('.doc-title-container')).toContainText('Today');
|
await expect(page.locator('.doc-title-container')).toContainText('Today');
|
||||||
const dateString = await page
|
const dateString = await page
|
||||||
.locator('.doc-title-container > span:first-of-type')
|
.locator('.doc-title-container > span:first-of-type')
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { test } from '@affine-test/kit/playwright';
|
import { test } from '@affine-test/kit/playwright';
|
||||||
import { openHomePage } from '@affine-test/kit/utils/load-page';
|
import {
|
||||||
|
confirmCreateJournal,
|
||||||
|
openHomePage,
|
||||||
|
} from '@affine-test/kit/utils/load-page';
|
||||||
import { waitForEditorLoad } from '@affine-test/kit/utils/page-logic';
|
import { waitForEditorLoad } from '@affine-test/kit/utils/page-logic';
|
||||||
import { expect, type Locator, type Page } from '@playwright/test';
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
|
|
||||||
@@ -84,6 +87,7 @@ async function createPageAndTurnIntoJournal(page: Page) {
|
|||||||
test('Create a journal from sidebar', async ({ page }) => {
|
test('Create a journal from sidebar', async ({ page }) => {
|
||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
await page.getByTestId('slider-bar-journals-button').click();
|
await page.getByTestId('slider-bar-journals-button').click();
|
||||||
|
await confirmCreateJournal(page);
|
||||||
await waitForEditorLoad(page);
|
await waitForEditorLoad(page);
|
||||||
await isJournalEditor(page);
|
await isJournalEditor(page);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { test } from '@affine-test/kit/playwright';
|
import { test } from '@affine-test/kit/playwright';
|
||||||
import { openHomePage } from '@affine-test/kit/utils/load-page';
|
import {
|
||||||
|
confirmCreateJournal,
|
||||||
|
openHomePage,
|
||||||
|
} from '@affine-test/kit/utils/load-page';
|
||||||
import { waitForEditorLoad } from '@affine-test/kit/utils/page-logic';
|
import { waitForEditorLoad } from '@affine-test/kit/utils/page-logic';
|
||||||
import { expect, type Locator, type Page } from '@playwright/test';
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
|
|
||||||
@@ -183,6 +186,7 @@ test('set default template for journal', async ({ page }) => {
|
|||||||
|
|
||||||
// by default create a journal, should not use template
|
// by default create a journal, should not use template
|
||||||
await page.getByTestId('slider-bar-journals-button').click();
|
await page.getByTestId('slider-bar-journals-button').click();
|
||||||
|
await confirmCreateJournal(page);
|
||||||
await waitForEditorLoad(page);
|
await waitForEditorLoad(page);
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('This is a journal template doc')
|
page.getByText('This is a journal template doc')
|
||||||
@@ -200,6 +204,7 @@ test('set default template for journal', async ({ page }) => {
|
|||||||
const prevWeekButton = page.getByTestId('week-picker-prev');
|
const prevWeekButton = page.getByTestId('week-picker-prev');
|
||||||
await prevWeekButton.click();
|
await prevWeekButton.click();
|
||||||
await page.getByTestId('week-picker-day').first().click();
|
await page.getByTestId('week-picker-day').first().click();
|
||||||
|
await confirmCreateJournal(page);
|
||||||
await waitForEditorLoad(page);
|
await waitForEditorLoad(page);
|
||||||
await expect(page.getByText('This is a page template doc')).toBeVisible();
|
await expect(page.getByText('This is a page template doc')).toBeVisible();
|
||||||
|
|
||||||
@@ -212,6 +217,7 @@ test('set default template for journal', async ({ page }) => {
|
|||||||
// create a new journal
|
// create a new journal
|
||||||
await prevWeekButton.click();
|
await prevWeekButton.click();
|
||||||
await page.getByTestId('week-picker-day').first().click();
|
await page.getByTestId('week-picker-day').first().click();
|
||||||
|
await confirmCreateJournal(page);
|
||||||
await waitForEditorLoad(page);
|
await waitForEditorLoad(page);
|
||||||
await expect(page.getByText('This is a journal template doc')).toBeVisible();
|
await expect(page.getByText('This is a journal template doc')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,8 +15,14 @@ export async function open404Page(page: Page) {
|
|||||||
await page.goto(`${coreUrl}/404`);
|
await page.goto(`${coreUrl}/404`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function confirmCreateJournal(page: Page) {
|
||||||
|
const confirmButton = page.getByTestId('confirm-create-journal-button');
|
||||||
|
await confirmButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
export async function openJournalsPage(page: Page) {
|
export async function openJournalsPage(page: Page) {
|
||||||
await page.getByTestId('slider-bar-journals-button').click();
|
await page.getByTestId('slider-bar-journals-button').click();
|
||||||
|
await confirmCreateJournal(page);
|
||||||
await expect(
|
await expect(
|
||||||
page.locator('.doc-title-container:has-text("Today")')
|
page.locator('.doc-title-container:has-text("Today")')
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
|||||||
Reference in New Issue
Block a user