feat(FileExplorer): support moving and copying multiple entries in context menu and modals

This commit is contained in:
shiyu
2025-09-22 19:32:45 +08:00
parent 81095f11df
commit 9d6c63aff4
4 changed files with 109 additions and 64 deletions

View File

@@ -28,8 +28,8 @@ interface ContextMenuProps {
onCreateDir: () => void;
onShare: (entries: VfsEntry[]) => void;
onGetDirectLink: (entry: VfsEntry) => void;
onMove: (entry: VfsEntry) => void;
onCopy: (entry: VfsEntry) => void;
onMove: (entries: VfsEntry[]) => void;
onCopy: (entries: VfsEntry[]) => void;
}
export const ContextMenu: React.FC<ContextMenuProps> = (props) => {
@@ -117,15 +117,15 @@ export const ContextMenu: React.FC<ContextMenuProps> = (props) => {
key: 'move',
label: t('Move'),
icon: <SwapOutlined />,
disabled: targetEntries.length !== 1 || targetEntries[0].type === 'mount',
onClick: () => actions.onMove(targetEntries[0]),
disabled: targetEntries.length === 0 || targetEntries.some(t => t.type === 'mount'),
onClick: () => actions.onMove(targetEntries),
},
{
key: 'copy',
label: t('Copy'),
icon: <CopyOutlined />,
disabled: targetEntries.length !== 1 || targetEntries[0].type === 'mount',
onClick: () => actions.onCopy(targetEntries[0]),
disabled: targetEntries.length === 0 || targetEntries.some(t => t.type === 'mount'),
onClick: () => actions.onCopy(targetEntries),
},
{
key: 'delete',

View File

@@ -6,20 +6,20 @@ import PathSelectorModal from '../../../../components/PathSelectorModal';
interface MoveCopyModalProps {
mode: 'move' | 'copy';
entry: VfsEntry | null;
entries: VfsEntry[];
open: boolean;
defaultPath: string;
onOk: (destination: string) => Promise<void> | void;
onCancel: () => void;
}
export function MoveCopyModal({ mode, entry, open, defaultPath, onOk, onCancel }: MoveCopyModalProps) {
export function MoveCopyModal({ mode, entries, open, defaultPath, onOk, onCancel }: MoveCopyModalProps) {
const { t } = useI18n();
const [value, setValue] = useState(defaultPath);
const [loading, setLoading] = useState(false);
const [selectorOpen, setSelectorOpen] = useState(false);
const entryName = useMemo(() => entry?.name ?? '', [entry]);
const entryName = useMemo(() => entries.length === 1 ? entries[0]?.name ?? '' : '', [entries]);
useEffect(() => {
if (open) {
@@ -91,7 +91,7 @@ export function MoveCopyModal({ mode, entry, open, defaultPath, onOk, onCancel }
return (
<Modal
title={title}
open={open && !!entry}
open={open && entries.length > 0}
onOk={handleOk}
onCancel={onCancel}
confirmLoading={loading}