fix(core): should show delete permanently for trash page multi-select (#13111)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added a confirmation modal before permanently deleting pages from the
trash, ensuring users must confirm before deletion.
* Permanent deletion now displays a toast notification upon completion.

* **Improvements**
* Enhanced deletion actions with callbacks for handling completion,
cancellation, or errors.
* Permanent delete option is now conditionally available based on user
permissions (admin or owner).

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Cats Juice
2025-07-09 16:45:26 +08:00
committed by GitHub
parent ae74f4ae51
commit dace1d1738
2 changed files with 60 additions and 5 deletions

View File

@@ -108,7 +108,14 @@ export const DocsExplorer = ({
masonryItemWidthMin?: number; masonryItemWidthMin?: number;
onRestore?: (ids: string[]) => void; onRestore?: (ids: string[]) => void;
/** Override the default delete action */ /** Override the default delete action */
onDelete?: (ids: string[]) => void; onDelete?: (
ids: string[],
callbacks?: {
onFinished?: () => void;
onAbort?: () => void;
onError?: (error: Error) => void;
}
) => void;
}) => { }) => {
const t = useI18n(); const t = useI18n();
const contextValue = useContext(DocExplorerContext); const contextValue = useContext(DocExplorerContext);
@@ -163,8 +170,11 @@ export const DocsExplorer = ({
return; return;
} }
if (onDelete) { if (onDelete) {
onDelete(contextValue.selectedDocIds$.value); onDelete(contextValue.selectedDocIds$.value, {
onFinished: () => {
handleCloseFloatingToolbar(); handleCloseFloatingToolbar();
},
});
return; return;
} }

View File

@@ -1,4 +1,4 @@
import { toast } from '@affine/component'; import { toast, useConfirmModal } from '@affine/component';
import { import {
createDocExplorerContext, createDocExplorerContext,
DocExplorerContext, DocExplorerContext,
@@ -44,8 +44,9 @@ export const TrashPage = () => {
const globalContextService = useService(GlobalContextService); const globalContextService = useService(GlobalContextService);
const permissionService = useService(WorkspacePermissionService); const permissionService = useService(WorkspacePermissionService);
const { restoreFromTrash } = useBlockSuiteMetaHelper(); const { restoreFromTrash, permanentlyDeletePage } = useBlockSuiteMetaHelper();
const isActiveView = useIsActiveView(); const isActiveView = useIsActiveView();
const { openConfirmModal } = useConfirmModal();
const [explorerContextValue] = useState(() => const [explorerContextValue] = useState(() =>
createDocExplorerContext({ createDocExplorerContext({
@@ -87,6 +88,47 @@ export const TrashPage = () => {
[restoreFromTrash, t] [restoreFromTrash, t]
); );
const handleMultiDelete = useCallback(
(ids: string[]) => {
ids.forEach(pageId => {
permanentlyDeletePage(pageId);
});
toast(t['com.affine.toastMessage.permanentlyDeleted']());
},
[permanentlyDeletePage, t]
);
const onConfirmPermanentlyDelete = useCallback(
(
ids: string[],
callbacks?: {
onFinished?: () => void;
onAbort?: () => void;
}
) => {
if (ids.length === 0) {
return;
}
openConfirmModal({
title: `${t['com.affine.trashOperation.deletePermanently']()}?`,
description: t['com.affine.trashOperation.deleteDescription'](),
cancelText: t['Cancel'](),
confirmText: t['com.affine.trashOperation.delete'](),
confirmButtonOptions: {
variant: 'error',
},
onConfirm: () => {
handleMultiDelete(ids);
callbacks?.onFinished?.();
},
onCancel: () => {
callbacks?.onAbort?.();
},
});
},
[handleMultiDelete, openConfirmModal, t]
);
useEffect(() => { useEffect(() => {
const subscription = collectionRulesService const subscription = collectionRulesService
.watch({ .watch({
@@ -139,6 +181,9 @@ export const TrashPage = () => {
<DocsExplorer <DocsExplorer
disableMultiDelete={!isAdmin && !isOwner} disableMultiDelete={!isAdmin && !isOwner}
onRestore={isAdmin || isOwner ? handleMultiRestore : undefined} onRestore={isAdmin || isOwner ? handleMultiRestore : undefined}
onDelete={
isAdmin || isOwner ? onConfirmPermanentlyDelete : undefined
}
/> />
)} )}
</div> </div>