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;
onRestore?: (ids: string[]) => void;
/** 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 contextValue = useContext(DocExplorerContext);
@@ -163,8 +170,11 @@ export const DocsExplorer = ({
return;
}
if (onDelete) {
onDelete(contextValue.selectedDocIds$.value);
handleCloseFloatingToolbar();
onDelete(contextValue.selectedDocIds$.value, {
onFinished: () => {
handleCloseFloatingToolbar();
},
});
return;
}

View File

@@ -1,4 +1,4 @@
import { toast } from '@affine/component';
import { toast, useConfirmModal } from '@affine/component';
import {
createDocExplorerContext,
DocExplorerContext,
@@ -44,8 +44,9 @@ export const TrashPage = () => {
const globalContextService = useService(GlobalContextService);
const permissionService = useService(WorkspacePermissionService);
const { restoreFromTrash } = useBlockSuiteMetaHelper();
const { restoreFromTrash, permanentlyDeletePage } = useBlockSuiteMetaHelper();
const isActiveView = useIsActiveView();
const { openConfirmModal } = useConfirmModal();
const [explorerContextValue] = useState(() =>
createDocExplorerContext({
@@ -87,6 +88,47 @@ export const TrashPage = () => {
[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(() => {
const subscription = collectionRulesService
.watch({
@@ -139,6 +181,9 @@ export const TrashPage = () => {
<DocsExplorer
disableMultiDelete={!isAdmin && !isOwner}
onRestore={isAdmin || isOwner ? handleMultiRestore : undefined}
onDelete={
isAdmin || isOwner ? onConfirmPermanentlyDelete : undefined
}
/>
)}
</div>