Compare commits

...

7 Commits

22 changed files with 411 additions and 197 deletions

19
.github/renovate.json vendored
View File

@@ -69,6 +69,11 @@
"matchPackagePatterns": ["*"],
"rangeStrategy": "replace",
"excludePackagePatterns": ["^@blocksuite/"]
},
{
"groupName": "rust toolchain",
"matchManagers": ["custom.regex"],
"matchPackageNames": ["rustc"]
}
],
"commitMessagePrefix": "chore: ",
@@ -79,5 +84,17 @@
"lockFileMaintenance": {
"enabled": true,
"extends": ["schedule:weekly"]
}
},
"customManagers": [
{
"customType": "regex",
"fileMatch": ["^rust-toolchain\\.toml?$"],
"matchStrings": [
"channel\\s*=\\s*\"(?<currentValue>\\d+\\.\\d+(\\.\\d+)?)\""
],
"depNameTemplate": "rustc",
"packageNameTemplate": "rust-lang/rust",
"datasourceTemplate": "github-releases"
}
]
}

View File

@@ -204,7 +204,7 @@ export class SubscriptionService {
tax_id_collection: {
enabled: true,
},
discounts,
...(discounts ? { discounts } : { allow_promotion_codes: true }),
mode: 'subscription',
success_url: redirectUrl,
customer: customer.stripeCustomerId,

View File

@@ -3,8 +3,8 @@
"private": true,
"type": "module",
"devDependencies": {
"@blocksuite/global": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/store": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/global": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/store": "0.14.0-canary-202405070525-ad1cc9f",
"react": "18.2.0",
"react-dom": "18.2.0",
"vitest": "1.4.0"

View File

@@ -11,9 +11,9 @@
"@affine/debug": "workspace:*",
"@affine/env": "workspace:*",
"@affine/templates": "workspace:*",
"@blocksuite/blocks": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/global": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/store": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/blocks": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/global": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/store": "0.14.0-canary-202405070525-ad1cc9f",
"@datastructures-js/binary-search-tree": "^5.3.2",
"foxact": "^0.2.33",
"jotai": "^2.8.0",
@@ -28,8 +28,8 @@
"devDependencies": {
"@affine-test/fixtures": "workspace:*",
"@affine/templates": "workspace:*",
"@blocksuite/block-std": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/presets": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/block-std": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/presets": "0.14.0-canary-202405070525-ad1cc9f",
"@testing-library/react": "^15.0.0",
"async-call-rpc": "^6.4.0",
"react": "^18.2.0",

View File

@@ -75,12 +75,12 @@
"zod": "^3.22.4"
},
"devDependencies": {
"@blocksuite/block-std": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/blocks": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/global": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/block-std": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/blocks": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/global": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/icons": "2.1.46",
"@blocksuite/presets": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/store": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/presets": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/store": "0.14.0-canary-202405070525-ad1cc9f",
"@storybook/addon-actions": "^7.6.17",
"@storybook/addon-essentials": "^7.6.17",
"@storybook/addon-interactions": "^7.6.17",

View File

@@ -18,13 +18,13 @@
"@affine/graphql": "workspace:*",
"@affine/i18n": "workspace:*",
"@affine/templates": "workspace:*",
"@blocksuite/block-std": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/blocks": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/global": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/block-std": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/blocks": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/global": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/icons": "2.1.46",
"@blocksuite/inline": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/presets": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/store": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/inline": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/presets": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/store": "0.14.0-canary-202405070525-ad1cc9f",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/modifiers": "^7.0.0",
"@dnd-kit/sortable": "^8.0.0",

View File

@@ -25,11 +25,17 @@ export const AISubscribe = ({ ...btnProps }: AISubscribeProps) => {
useEffect(() => {
if (isOpenedExternalWindow) {
// when the external window is opened, revalidate the subscription status every 3 seconds
const timer = setInterval(() => {
subscriptionService.subscription.revalidate();
}, 3000);
return () => clearInterval(timer);
// when the external window is opened, revalidate the subscription when window get focus
window.addEventListener(
'focus',
subscriptionService.subscription.revalidate
);
return () => {
window.removeEventListener(
'focus',
subscriptionService.subscription.revalidate
);
};
}
return;
}, [isOpenedExternalWindow, subscriptionService]);

View File

@@ -159,13 +159,17 @@ export const PlanLayout = ({ cloud, ai, aiTip }: PlanLayoutProps) => {
height={24}
color={cssVar('iconColor')}
/>
<div className={styles.aiScrollTipText}>Meet AFFiNE AI</div>
<div className={styles.aiScrollTipText}>
{t['com.affine.ai-scroll-tip.title']()}
</div>
<div className={styles.aiScrollTipTag}>
<div className={styles.aiScrollTipTagInner}>NEW</div>
<div className={styles.aiScrollTipTagInner}>
{t['com.affine.ai-scroll-tip.tag']()}
</div>
</div>
</div>
<Button onClick={scrollAiIntoView} type="primary">
View
{t['com.affine.ai-scroll-tip.view']()}
</Button>
</div>,
settingModalScrollContainer,

View File

@@ -235,11 +235,17 @@ const Upgrade = ({ recurring }: { recurring: SubscriptionRecurring }) => {
useEffect(() => {
if (isOpenedExternalWindow) {
// when the external window is opened, revalidate the subscription status every 3 seconds
const timer = setInterval(() => {
subscriptionService.subscription.revalidate();
}, 1000);
return () => clearInterval(timer);
// when the external window is opened, revalidate the subscription when window get focus
window.addEventListener(
'focus',
subscriptionService.subscription.revalidate
);
return () => {
window.removeEventListener(
'focus',
subscriptionService.subscription.revalidate
);
};
}
return;
}, [isOpenedExternalWindow, subscriptionService]);

View File

@@ -1,4 +1,9 @@
import { CloseIcon, DeleteIcon } from '@blocksuite/icons';
import {
CloseIcon,
DeleteIcon,
DeletePermanentlyIcon,
ResetIcon,
} from '@blocksuite/icons';
import type { ReactNode } from 'react';
import { FloatingToolbar } from './floating-toolbar';
@@ -9,23 +14,34 @@ export const ListFloatingToolbar = ({
onClose,
open,
onDelete,
onRestore,
}: {
open: boolean;
content: ReactNode;
onClose: () => void;
onDelete: () => void;
onDelete?: () => void;
onRestore?: () => void;
}) => {
return (
<FloatingToolbar className={styles.floatingToolbar} open={open}>
<FloatingToolbar.Item>{content}</FloatingToolbar.Item>
<FloatingToolbar.Button onClick={onClose} icon={<CloseIcon />} />
<FloatingToolbar.Separator />
<FloatingToolbar.Button
onClick={onDelete}
icon={<DeleteIcon />}
type="danger"
data-testid="list-toolbar-delete"
/>
{!!onRestore && (
<FloatingToolbar.Button
onClick={onRestore}
icon={<ResetIcon />}
data-testid="list-toolbar-restore"
/>
)}
{!!onDelete && (
<FloatingToolbar.Button
onClick={onDelete}
icon={onRestore ? <DeletePermanentlyIcon /> : <DeleteIcon />}
type="danger"
data-testid="list-toolbar-delete"
/>
)}
</FloatingToolbar>
);
};

View File

@@ -22,3 +22,4 @@ export * from './use-filtered-page-metas';
export * from './utils';
export * from './view';
export * from './virtualized-list';
export * from './virtualized-trash-list';

View File

@@ -82,3 +82,13 @@ export const editTagWrapper = style({
},
},
});
export const deleteIcon = style({
color: cssVar('iconColor'),
selectors: {
'&:not(.without-hover):hover': {
color: cssVar('errorColor'),
background: cssVar('backgroundErrorColor'),
},
},
});

View File

@@ -1,5 +1,4 @@
import {
ConfirmModal,
IconButton,
Menu,
MenuIcon,
@@ -227,7 +226,21 @@ export const TrashOperationCell = ({
onRestorePage,
}: TrashOperationCellProps) => {
const t = useAFFiNEI18N();
const [open, setOpen] = useState(false);
const { openConfirmModal } = useConfirmModal();
const onConfirmPermanentlyDelete = useCallback(() => {
openConfirmModal({
title: `${t['com.affine.trashOperation.deletePermanently']()}?`,
description: t['com.affine.trashOperation.deleteDescription'](),
cancelText: t['Cancel'](),
confirmButtonOptions: {
type: 'error',
children: t['com.affine.trashOperation.delete'](),
},
onConfirm: onPermanentlyDeletePage,
});
}, [onPermanentlyDeletePage, openConfirmModal, t]);
return (
<ColWrapper flex={1}>
<Tooltip content={t['com.affine.trashOperation.restoreIt']()} side="top">
@@ -248,28 +261,12 @@ export const TrashOperationCell = ({
>
<IconButton
data-testid="delete-page-button"
onClick={() => {
setOpen(true);
}}
onClick={onConfirmPermanentlyDelete}
className={styles.deleteIcon}
>
<DeletePermanentlyIcon />
</IconButton>
</Tooltip>
<ConfirmModal
title={`${t['com.affine.trashOperation.deletePermanently']()}?`}
description={t['com.affine.trashOperation.deleteDescription']()}
cancelText={t['com.affine.confirmModal.button.cancel']()}
confirmButtonOptions={{
type: 'error',
children: t['com.affine.trashOperation.delete'](),
}}
open={open}
onOpenChange={setOpen}
onConfirm={() => {
onPermanentlyDeletePage();
setOpen(false);
}}
/>
</ColWrapper>
);
};

View File

@@ -0,0 +1,150 @@
import { toast, useConfirmModal } from '@affine/component';
import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper';
import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { DocMeta } from '@blocksuite/store';
import { useService, WorkspaceService } from '@toeverything/infra';
import { useCallback, useMemo, useRef, useState } from 'react';
import { usePageHelper } from '../blocksuite/block-suite-page-list/utils';
import { ListFloatingToolbar } from './components/list-floating-toolbar';
import { usePageHeaderColsDef } from './header-col-def';
import { TrashOperationCell } from './operation-cell';
import { PageListItemRenderer } from './page-group';
import { ListTableHeader } from './page-header';
import type { ItemListHandle, ListItem } from './types';
import { useFilteredPageMetas } from './use-filtered-page-metas';
import { VirtualizedList } from './virtualized-list';
export const VirtualizedTrashList = () => {
const currentWorkspace = useService(WorkspaceService).workspace;
const docCollection = currentWorkspace.docCollection;
const { restoreFromTrash, permanentlyDeletePage } =
useBlockSuiteMetaHelper(docCollection);
const pageMetas = useBlockSuiteDocMeta(docCollection);
const filteredPageMetas = useFilteredPageMetas(pageMetas, {
trash: true,
});
const { isPreferredEdgeless } = usePageHelper(docCollection);
const listRef = useRef<ItemListHandle>(null);
const [showFloatingToolbar, setShowFloatingToolbar] = useState(false);
const [selectedPageIds, setSelectedPageIds] = useState<string[]>([]);
const { openConfirmModal } = useConfirmModal();
const t = useAFFiNEI18N();
const pageHeaderColsDef = usePageHeaderColsDef();
const filteredSelectedPageIds = useMemo(() => {
const ids = filteredPageMetas.map(page => page.id);
return selectedPageIds.filter(id => ids.includes(id));
}, [filteredPageMetas, selectedPageIds]);
const hideFloatingToolbar = useCallback(() => {
listRef.current?.toggleSelectable();
}, []);
const handleMultiDelete = useCallback(() => {
filteredSelectedPageIds.forEach(pageId => {
permanentlyDeletePage(pageId);
});
hideFloatingToolbar();
toast(t['com.affine.toastMessage.permanentlyDeleted']());
}, [filteredSelectedPageIds, hideFloatingToolbar, permanentlyDeletePage, t]);
const handleMultiRestore = useCallback(() => {
filteredSelectedPageIds.forEach(pageId => {
restoreFromTrash(pageId);
});
hideFloatingToolbar();
toast(
t['com.affine.toastMessage.restored']({
title: filteredSelectedPageIds.length > 1 ? 'docs' : 'doc',
})
);
}, [filteredSelectedPageIds, hideFloatingToolbar, restoreFromTrash, t]);
const onConfirmPermanentlyDelete = useCallback(() => {
openConfirmModal({
title: `${t['com.affine.trashOperation.deletePermanently']()}?`,
description: t['com.affine.trashOperation.deleteDescription'](),
cancelText: t['Cancel'](),
confirmButtonOptions: {
type: 'error',
children: t['com.affine.trashOperation.delete'](),
},
onConfirm: handleMultiDelete,
});
}, [handleMultiDelete, openConfirmModal, t]);
const pageOperationsRenderer = useCallback(
(item: ListItem) => {
const page = item as DocMeta;
const onRestorePage = () => {
restoreFromTrash(page.id);
toast(
t['com.affine.toastMessage.restored']({
title: page.title || 'Untitled',
})
);
};
const onPermanentlyDeletePage = () => {
permanentlyDeletePage(page.id);
toast(t['com.affine.toastMessage.permanentlyDeleted']());
};
return (
<TrashOperationCell
onPermanentlyDeletePage={onPermanentlyDeletePage}
onRestorePage={onRestorePage}
/>
);
},
[permanentlyDeletePage, restoreFromTrash, t]
);
const pageItemRenderer = useCallback((item: ListItem) => {
return <PageListItemRenderer {...item} />;
}, []);
const pageHeaderRenderer = useCallback(() => {
return <ListTableHeader headerCols={pageHeaderColsDef} />;
}, [pageHeaderColsDef]);
return (
<>
<VirtualizedList
ref={listRef}
selectable="toggle"
items={filteredPageMetas}
rowAsLink
isPreferredEdgeless={isPreferredEdgeless}
onSelectionActiveChange={setShowFloatingToolbar}
docCollection={currentWorkspace.docCollection}
operationsRenderer={pageOperationsRenderer}
itemRenderer={pageItemRenderer}
headerRenderer={pageHeaderRenderer}
selectedIds={filteredSelectedPageIds}
onSelectedIdsChange={setSelectedPageIds}
/>
<ListFloatingToolbar
open={showFloatingToolbar && filteredSelectedPageIds.length > 0}
onDelete={onConfirmPermanentlyDelete}
onClose={hideFloatingToolbar}
onRestore={handleMultiRestore}
content={
<Trans
i18nKey="com.affine.page.toolbar.selected"
count={filteredSelectedPageIds.length}
>
<div style={{ color: 'var(--affine-text-secondary-color)' }}>
{{ count: filteredSelectedPageIds.length } as any}
</div>
selected
</Trans>
}
/>
</>
);
};

View File

@@ -6,6 +6,7 @@ export const trashTitle = style({
gap: 8,
padding: '0 8px',
fontWeight: 600,
userSelect: 'none',
});
export const body = style({
display: 'flex',

View File

@@ -1,23 +1,13 @@
import { toast } from '@affine/component';
import { usePageHelper } from '@affine/core/components/blocksuite/block-suite-page-list/utils';
import type { ListItem } from '@affine/core/components/page-list';
import {
ListTableHeader,
PageListItemRenderer,
TrashOperationCell,
useFilteredPageMetas,
VirtualizedList,
VirtualizedTrashList,
} from '@affine/core/components/page-list';
import { usePageHeaderColsDef } from '@affine/core/components/page-list/header-col-def';
import { Header } from '@affine/core/components/pure/header';
import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper';
import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils';
import { DeleteIcon } from '@blocksuite/icons';
import type { DocMeta } from '@blocksuite/store';
import { useService, WorkspaceService } from '@toeverything/infra';
import { useCallback } from 'react';
import { ViewBodyIsland, ViewHeaderIsland } from '../../modules/workbench';
import { EmptyPageList } from './page-list-empty';
@@ -47,44 +37,6 @@ export const TrashPage = () => {
trash: true,
});
const { restoreFromTrash, permanentlyDeletePage } =
useBlockSuiteMetaHelper(docCollection);
const { isPreferredEdgeless } = usePageHelper(docCollection);
const t = useAFFiNEI18N();
const pageHeaderColsDef = usePageHeaderColsDef();
const pageOperationsRenderer = useCallback(
(item: ListItem) => {
const page = item as DocMeta;
const onRestorePage = () => {
restoreFromTrash(page.id);
toast(
t['com.affine.toastMessage.restored']({
title: page.title || 'Untitled',
})
);
};
const onPermanentlyDeletePage = () => {
permanentlyDeletePage(page.id);
toast(t['com.affine.toastMessage.permanentlyDeleted']());
};
return (
<TrashOperationCell
onPermanentlyDeletePage={onPermanentlyDeletePage}
onRestorePage={onRestorePage}
/>
);
},
[permanentlyDeletePage, restoreFromTrash, t]
);
const pageItemRenderer = useCallback((item: ListItem) => {
return <PageListItemRenderer {...item} />;
}, []);
const pageHeaderRenderer = useCallback(() => {
return <ListTableHeader headerCols={pageHeaderColsDef} />;
}, [pageHeaderColsDef]);
return (
<>
<ViewHeaderIsland>
@@ -93,15 +45,7 @@ export const TrashPage = () => {
<ViewBodyIsland>
<div className={styles.body}>
{filteredPageMetas.length > 0 ? (
<VirtualizedList
items={filteredPageMetas}
rowAsLink
isPreferredEdgeless={isPreferredEdgeless}
docCollection={currentWorkspace.docCollection}
operationsRenderer={pageOperationsRenderer}
itemRenderer={pageItemRenderer}
headerRenderer={pageHeaderRenderer}
/>
<VirtualizedTrashList />
) : (
<EmptyPageList
type="trash"

View File

@@ -29,10 +29,10 @@
"@affine/env": "workspace:*",
"@affine/i18n": "workspace:*",
"@affine/native": "workspace:*",
"@blocksuite/block-std": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/blocks": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/presets": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/store": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/block-std": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/blocks": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/presets": "0.14.0-canary-202405070525-ad1cc9f",
"@blocksuite/store": "0.14.0-canary-202405070525-ad1cc9f",
"@electron-forge/cli": "^7.3.0",
"@electron-forge/core": "^7.3.0",
"@electron-forge/core-utils": "^7.3.0",

View File

@@ -894,7 +894,7 @@
"com.affine.payment.ai.benefit.g3-3": "Open source & Privacy ensured",
"com.affine.payment.ai.billing-tip.end-at": "You have purchased AFFiNE AI. The expiration date is {{end}}.",
"com.affine.payment.ai.billing-tip.next-bill-at": "You have purchased AFFiNE AI. The next payment date is {{due}}.",
"com.affine.payment.ai.pricing-plan.caption-free": "You are current on the Basic plan.",
"com.affine.payment.ai.pricing-plan.caption-free": "You are currently on the Basic plan.",
"com.affine.payment.ai.pricing-plan.caption-purchased": "You have purchased AFFiNE AI",
"com.affine.payment.ai.pricing-plan.learn": "Learn About AFFiNE AI",
"com.affine.payment.ai.pricing-plan.title": "AFFiNE AI",
@@ -914,7 +914,7 @@
"com.affine.payment.benefit-6": "Number of members per Workspace ≤ {{capacity}}",
"com.affine.payment.benefit-7": "{{capacity}}-days version history",
"com.affine.payment.billing-setting.ai-plan": "AFFiNE AI",
"com.affine.payment.billing-setting.ai.free-desc": "You are current on the <a>Free plan</a>.",
"com.affine.payment.billing-setting.ai.free-desc": "You are currently on the <a>Free plan</a>.",
"com.affine.payment.billing-setting.ai.purchase": "Purchase",
"com.affine.payment.billing-setting.cancel-subscription": "Cancel Subscription",
"com.affine.payment.billing-setting.cancel-subscription.description": "Once you canceled subscription you will no longer enjoy the plan benefits.",
@@ -1052,6 +1052,9 @@
"com.affine.payment.upgrade-success-page.support": "If you have any questions, please contact our <1> customer support</1>.",
"com.affine.payment.upgrade-success-page.text": "Congratulations! Your AFFiNE account has been successfully upgraded to a Pro account.",
"com.affine.payment.upgrade-success-page.title": "Upgrade Successful!",
"com.affine.ai-scroll-tip.title": "Meet AFFiNE AI",
"com.affine.ai-scroll-tip.tag": "New",
"com.affine.ai-scroll-tip.view": "View",
"com.affine.publicLinkDisableModal.button.cancel": "Cancel",
"com.affine.publicLinkDisableModal.button.disable": "Disable",
"com.affine.publicLinkDisableModal.description": "Disabling this public link will prevent anyone with the link from accessing this doc.",

View File

@@ -228,6 +228,65 @@ test('select two pages and delete', async ({ page }) => {
expect(await getPagesCount(page)).toBe(pageCount - 2);
});
test('select two pages and permanently delete', async ({ page }) => {
await openHomePage(page);
await waitForEditorLoad(page);
await clickNewPageButton(page);
await clickSideBarAllPageButton(page);
await waitForAllPagesLoad(page);
const pageCount = await getPagesCount(page);
await page.keyboard.down('Shift');
await page.locator('[data-testid="page-list-item"]').nth(0).click();
await page.locator('[data-testid="page-list-item"]').nth(1).click();
await page.keyboard.up('Shift');
// the floating popover should appear
await expect(page.locator('[data-testid="floating-toolbar"]')).toBeVisible();
await expect(page.locator('[data-testid="floating-toolbar"]')).toHaveText(
'2 doc(s) selected'
);
// click delete button
await page.locator('[data-testid="list-toolbar-delete"]').click();
// the confirm dialog should appear
await expect(page.getByText('Delete 2 docs?')).toBeVisible();
await page.getByRole('button', { name: 'Delete' }).click();
// check the page count again
await page.waitForTimeout(300);
expect(await getPagesCount(page)).toBe(pageCount - 2);
await page.getByTestId('trash-page').click();
await page.waitForTimeout(300);
const trashPageCount = await getPagesCount(page);
expect(trashPageCount).toBe(2);
await page.keyboard.down('Shift');
await page.locator('[data-testid="page-list-item"]').nth(0).click();
await page.locator('[data-testid="page-list-item"]').nth(1).click();
await page.keyboard.up('Shift');
await expect(page.locator('[data-testid="floating-toolbar"]')).toBeVisible();
await expect(page.locator('[data-testid="floating-toolbar"]')).toHaveText(
'2 doc(s) selected'
);
await page.locator('[data-testid="list-toolbar-delete"]').click();
await page.getByRole('button', { name: 'Delete' }).click();
await page.waitForTimeout(300);
expect(await getPagesCount(page)).toBe(trashPageCount - 2);
});
test('select a group of items by clicking "Select All" in group header', async ({
page,

View File

@@ -95,6 +95,9 @@ for (const oid of repo
.revWalk()
.push(latest.id())
.setSorting(Sort.Time & Sort.Topological)) {
if (oid.startsWith(oldHash)) {
break;
}
const commit = repo.findCommit(oid);
const summary = commit.summary();
if (summary.startsWith('feat')) {
@@ -106,9 +109,6 @@ for (const oid of repo
} else {
commits.Misc.push(commit);
}
if (oid.startsWith(oldHash)) {
break;
}
}
clipboard.setText(await formatCommits(commits));

View File

@@ -6,7 +6,7 @@
"@affine/env": "workspace:*",
"@affine/templates": "workspace:*",
"@aws-sdk/client-s3": "3.537.0",
"@blocksuite/presets": "0.14.0-canary-202405070334-778ff10",
"@blocksuite/presets": "0.14.0-canary-202405070525-ad1cc9f",
"@clack/core": "^0.3.4",
"@clack/prompts": "^0.7.0",
"@magic-works/i18n-codegen": "^0.5.0",

136
yarn.lock
View File

@@ -173,7 +173,7 @@ __metadata:
"@affine/env": "workspace:*"
"@affine/templates": "workspace:*"
"@aws-sdk/client-s3": "npm:3.537.0"
"@blocksuite/presets": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/presets": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@clack/core": "npm:^0.3.4"
"@clack/prompts": "npm:^0.7.0"
"@magic-works/i18n-codegen": "npm:^0.5.0"
@@ -226,12 +226,12 @@ __metadata:
"@affine/electron-api": "workspace:*"
"@affine/graphql": "workspace:*"
"@affine/i18n": "workspace:*"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/icons": "npm:2.1.46"
"@blocksuite/presets": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/store": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/presets": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/store": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@dnd-kit/core": "npm:^6.1.0"
"@dnd-kit/modifiers": "npm:^7.0.0"
"@dnd-kit/sortable": "npm:^8.0.0"
@@ -327,13 +327,13 @@ __metadata:
"@affine/graphql": "workspace:*"
"@affine/i18n": "workspace:*"
"@affine/templates": "workspace:*"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/icons": "npm:2.1.46"
"@blocksuite/inline": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/presets": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/store": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/inline": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/presets": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/store": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@dnd-kit/core": "npm:^6.1.0"
"@dnd-kit/modifiers": "npm:^7.0.0"
"@dnd-kit/sortable": "npm:^8.0.0"
@@ -455,10 +455,10 @@ __metadata:
"@affine/env": "workspace:*"
"@affine/i18n": "workspace:*"
"@affine/native": "workspace:*"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/presets": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/store": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/presets": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/store": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@electron-forge/cli": "npm:^7.3.0"
"@electron-forge/core": "npm:^7.3.0"
"@electron-forge/core-utils": "npm:^7.3.0"
@@ -516,8 +516,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "@affine/env@workspace:packages/common/env"
dependencies:
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/store": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/store": "npm:0.14.0-canary-202405070525-ad1cc9f"
lit: "npm:^3.1.2"
react: "npm:18.2.0"
react-dom: "npm:18.2.0"
@@ -3731,30 +3731,30 @@ __metadata:
languageName: node
linkType: hard
"@blocksuite/block-std@npm:0.14.0-canary-202405070334-778ff10":
version: 0.14.0-canary-202405070334-778ff10
resolution: "@blocksuite/block-std@npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/block-std@npm:0.14.0-canary-202405070525-ad1cc9f":
version: 0.14.0-canary-202405070525-ad1cc9f
resolution: "@blocksuite/block-std@npm:0.14.0-canary-202405070525-ad1cc9f"
dependencies:
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
lit: "npm:^3.1.3"
lz-string: "npm:^1.5.0"
w3c-keyname: "npm:^2.2.8"
zod: "npm:^3.22.4"
peerDependencies:
"@blocksuite/inline": 0.14.0-canary-202405070334-778ff10
"@blocksuite/store": 0.14.0-canary-202405070334-778ff10
checksum: 10/68c8bf3828ad09c88992060bad4c871e6ec55b873e0a399da053b1587c5e93bd91ea25a5d009418473a9733b86c60494834912293c68676cfbc6ad0374e5eadb
"@blocksuite/inline": 0.14.0-canary-202405070525-ad1cc9f
"@blocksuite/store": 0.14.0-canary-202405070525-ad1cc9f
checksum: 10/bf4586379600587f12b20b08afec12537313f03c9b9318e2da484f634eae4762b656f43a9da05d3574899cd3d498e34b3856c8469e4f4acd9444f045c9550120
languageName: node
linkType: hard
"@blocksuite/blocks@npm:0.14.0-canary-202405070334-778ff10":
version: 0.14.0-canary-202405070334-778ff10
resolution: "@blocksuite/blocks@npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/blocks@npm:0.14.0-canary-202405070525-ad1cc9f":
version: 0.14.0-canary-202405070525-ad1cc9f
resolution: "@blocksuite/blocks@npm:0.14.0-canary-202405070525-ad1cc9f"
dependencies:
"@blocksuite/block-std": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/inline": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/store": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/inline": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/store": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@dotlottie/player-component": "npm:^2.7.12"
"@fal-ai/serverless-client": "npm:^0.9.3"
"@floating-ui/dom": "npm:^1.6.3"
@@ -3793,16 +3793,16 @@ __metadata:
unified: "npm:^11.0.4"
webfontloader: "npm:^1.6.28"
zod: "npm:^3.22.4"
checksum: 10/a1db64bb34641603479eb95625fabd2beca7c4c0caadad7dc6dfb89c96532eab441d571ccdb5cfdc933d9457d52b1dca5138d6b96fcde603adbc16844c364041
checksum: 10/7b4809efc0656aed6b256342c1af61e64662de534c7cbdb371ca7479a25270041058f8167e93204c24d699bfcf6a7f18ac20473b352af2dad37dde8f8bf77193
languageName: node
linkType: hard
"@blocksuite/global@npm:0.14.0-canary-202405070334-778ff10":
version: 0.14.0-canary-202405070334-778ff10
resolution: "@blocksuite/global@npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global@npm:0.14.0-canary-202405070525-ad1cc9f":
version: 0.14.0-canary-202405070525-ad1cc9f
resolution: "@blocksuite/global@npm:0.14.0-canary-202405070525-ad1cc9f"
dependencies:
zod: "npm:^3.22.4"
checksum: 10/abd50f775577789427733fd711324e2d46ed88581dcb9a465a63504e6a2f3ce3ca3950302d066c19be95a42b39e83aa3a0aba20ed88bd6003757344c00316fe0
checksum: 10/07e3ca0d5ff1a12000c84b4f34ba6364237666e616245aedae331cf76369de4c43692a2930aaf7bf6945d64f91853090f04b13c51c23539dc326c420047feacc
languageName: node
linkType: hard
@@ -3816,45 +3816,45 @@ __metadata:
languageName: node
linkType: hard
"@blocksuite/inline@npm:0.14.0-canary-202405070334-778ff10":
version: 0.14.0-canary-202405070334-778ff10
resolution: "@blocksuite/inline@npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/inline@npm:0.14.0-canary-202405070525-ad1cc9f":
version: 0.14.0-canary-202405070525-ad1cc9f
resolution: "@blocksuite/inline@npm:0.14.0-canary-202405070525-ad1cc9f"
dependencies:
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
zod: "npm:^3.22.4"
peerDependencies:
lit: ^3.1.1
yjs: ^13
checksum: 10/05c48f82cbd7db5382b6c094778b4934965afd0839c80094db9d61f92de2aa57ff78515144e6f9edf65376659bf88576776bc3daa1699dda19346ec5840ad462
checksum: 10/1904602706a39ee78a1c2534f57f2d75700bbeab45af7c6cd781311cdc26aa45897b2a5c405fd9488aa2cfb229cf3564df6c2c3c7191aacb1101e037982ace50
languageName: node
linkType: hard
"@blocksuite/presets@npm:0.14.0-canary-202405070334-778ff10":
version: 0.14.0-canary-202405070334-778ff10
resolution: "@blocksuite/presets@npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/presets@npm:0.14.0-canary-202405070525-ad1cc9f":
version: 0.14.0-canary-202405070525-ad1cc9f
resolution: "@blocksuite/presets@npm:0.14.0-canary-202405070525-ad1cc9f"
dependencies:
"@blocksuite/block-std": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/inline": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/store": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/inline": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/store": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@dotlottie/player-component": "npm:^2.7.12"
"@fal-ai/serverless-client": "npm:^0.9.3"
"@floating-ui/dom": "npm:^1.6.3"
"@toeverything/theme": "npm:^0.7.29"
lit: "npm:^3.1.3"
openai: "npm:^4.37.1"
checksum: 10/1bb86139f425ad39272433453ebf22ca56cb83fae580f4882f3450bb204ba5155190c4ad95907f01cbbfa907bf60472146868512503c94c5068339cd16ae616b
checksum: 10/c4a759df22a9386d787026ba3da4296a69038a84d1b914a23c95d3f2659100c827e77e477b18939966c1ac223d510b2f214248dfabbc51eba949eb50962f979a
languageName: node
linkType: hard
"@blocksuite/store@npm:0.14.0-canary-202405070334-778ff10":
version: 0.14.0-canary-202405070334-778ff10
resolution: "@blocksuite/store@npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/store@npm:0.14.0-canary-202405070525-ad1cc9f":
version: 0.14.0-canary-202405070525-ad1cc9f
resolution: "@blocksuite/store@npm:0.14.0-canary-202405070525-ad1cc9f"
dependencies:
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/inline": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/sync": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/inline": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/sync": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@types/flexsearch": "npm:^0.7.6"
flexsearch: "npm:0.7.43"
idb-keyval: "npm:^6.2.1"
@@ -3866,20 +3866,20 @@ __metadata:
zod: "npm:^3.22.4"
peerDependencies:
yjs: ^13
checksum: 10/a6fbd6449034890b08c73a2a16dc2e0ef426148a9a67dc254976fcd9e7174e9f1e52f676002913d4f71eac9b40d96c79584201d444f884250b07ac1f6472eb56
checksum: 10/92718b5d6768ea9eaa2ac060e07af4b705212c6db4abeaeec6961c9191ba62e0a122fd337721e4cafbdc91af99d7628b5210a9390db7c775534a3c43d815e233
languageName: node
linkType: hard
"@blocksuite/sync@npm:0.14.0-canary-202405070334-778ff10":
version: 0.14.0-canary-202405070334-778ff10
resolution: "@blocksuite/sync@npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/sync@npm:0.14.0-canary-202405070525-ad1cc9f":
version: 0.14.0-canary-202405070525-ad1cc9f
resolution: "@blocksuite/sync@npm:0.14.0-canary-202405070525-ad1cc9f"
dependencies:
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
idb: "npm:^8.0.0"
y-protocols: "npm:^1.0.6"
peerDependencies:
yjs: ^13
checksum: 10/7154091297a713bbb50a6513e25645b59a734c77bdcb42295bfb3bc0ddbf1720b6841e343c619c0cf3afd4afa934704499fa7fa684fc146758000da418a526b0
checksum: 10/9101de5161c8be3383fc9a9c3c152829cacb4b628b4027b42dd4070d0968e97867fbc2fb874c45fed5a9773c2ec51b6246dd0cddf633ee295e9294c137db2fc6
languageName: node
linkType: hard
@@ -14251,11 +14251,11 @@ __metadata:
"@affine/debug": "workspace:*"
"@affine/env": "workspace:*"
"@affine/templates": "workspace:*"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/global": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/presets": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/store": "npm:0.14.0-canary-202405070334-778ff10"
"@blocksuite/block-std": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/blocks": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/global": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/presets": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@blocksuite/store": "npm:0.14.0-canary-202405070525-ad1cc9f"
"@datastructures-js/binary-search-tree": "npm:^5.3.2"
"@testing-library/react": "npm:^15.0.0"
async-call-rpc: "npm:^6.4.0"