Skip to content

Commit 81bbb85

Browse files
feature: implemented moving file from one folder to another.
1 parent 738ccab commit 81bbb85

6 files changed

Lines changed: 374 additions & 9 deletions

File tree

app/components/FileItem.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface FileItemProps {
2424
onRename?: (file: FileItemData) => void;
2525
onPreview?: (file: FileItemData) => void;
2626
onCopy?: (file: FileItemData) => void;
27+
onMove?: (file: FileItemData) => void;
2728
isSelected?: boolean;
2829
}
2930

@@ -35,6 +36,7 @@ export default function FileItem({
3536
onRename,
3637
onPreview,
3738
onCopy,
39+
onMove,
3840
isSelected = false,
3941
}: FileItemProps) {
4042
const [isHovered, setIsHovered] = useState(false);
@@ -131,7 +133,7 @@ export default function FileItem({
131133
onPreview={onPreview}
132134
onDownload={(f) => console.log("Download:", f.name)}
133135
onCopy={onCopy}
134-
onMove={(f) => console.log("Move:", f.name)}
136+
onMove={onMove}
135137
onDelete={(f) => console.log("Delete:", f.name)}
136138
/>
137139
)}
@@ -179,7 +181,7 @@ export default function FileItem({
179181
onPreview={onPreview}
180182
onDownload={(f) => console.log("Download:", f.name)}
181183
onCopy={onCopy}
182-
onMove={(f) => console.log("Move:", f.name)}
184+
onMove={onMove}
183185
onDelete={(f) => console.log("Delete:", f.name)}
184186
/>
185187
)}

app/components/FileItemMenu.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,18 @@ export default function FileItemMenu({
104104
className: "text-gray-700 hover:bg-gray-100 border-b border-gray-100",
105105
iconClassName: "text-gray-500",
106106
},
107-
{
108-
label: "Move",
109-
icon: ArrowRightCircleIcon,
110-
action: onMove,
111-
className: "text-gray-700 hover:bg-gray-100 border-b border-gray-100",
112-
iconClassName: "text-gray-500",
113-
},
107+
// Only show Move for files, not folders
108+
...(file.type === "file"
109+
? [
110+
{
111+
label: "Move",
112+
icon: ArrowRightCircleIcon,
113+
action: onMove,
114+
className: "text-gray-700 hover:bg-gray-100 border-b border-gray-100",
115+
iconClassName: "text-gray-500",
116+
},
117+
]
118+
: []),
114119
{
115120
label: "Delete",
116121
icon: TrashIcon,

app/components/FileList.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface FileListProps {
1313
onFileRename?: (file: FileItemData) => void;
1414
onFilePreview?: (file: FileItemData) => void;
1515
onFileCopy?: (file: FileItemData) => void;
16+
onFileMove?: (file: FileItemData) => void;
1617
selectedFileIds: string[];
1718
}
1819

@@ -26,6 +27,7 @@ export default function FileList({
2627
onFileRename,
2728
onFilePreview,
2829
onFileCopy,
30+
onFileMove,
2931
selectedFileIds,
3032
}: FileListProps) {
3133
const [view, setView] = useState<"grid" | "list">(() => {
@@ -62,6 +64,7 @@ export default function FileList({
6264
onRename={onFileRename}
6365
onPreview={onFilePreview}
6466
onCopy={onFileCopy}
67+
onMove={onFileMove}
6568
isSelected={selectedFileIds.includes(file.id)}
6669
/>
6770
))}
@@ -78,6 +81,7 @@ export default function FileList({
7881
onRename={onFileRename}
7982
onPreview={onFilePreview}
8083
onCopy={onFileCopy}
84+
onMove={onFileMove}
8185
isSelected={selectedFileIds.includes(file.id)}
8286
/>
8387
))}

app/components/FileManager.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import PermissionsDialog, { Permission } from "./PermissionsDialog";
1212
import NewFolderDialog from "./NewFolderDialog";
1313
import RenameDialog from "./RenameDialog";
1414
import PreviewModal from "./PreviewModal";
15+
import MoveDialog from "./MoveDialog";
1516
import FileUploadHandler from "./FileUploadHandler";
1617
import { FileItemData } from "./FileItem";
1718
import LoadingSpinner from "./shared/LoadingSpinner";
@@ -46,6 +47,8 @@ export default function FileManager() {
4647
const [fileToRename, setFileToRename] = useState<FileItemData | null>(null);
4748
const [showPreviewModal, setShowPreviewModal] = useState(false);
4849
const [fileToPreview, setFileToPreview] = useState<FileItemData | null>(null);
50+
const [showMoveDialog, setShowMoveDialog] = useState(false);
51+
const [fileToMove, setFileToMove] = useState<FileItemData | null>(null);
4952

5053
const [savedUrl, setSavedUrl] = useState<string | null>(() => {
5154
if (typeof window === "undefined") return null;
@@ -250,6 +253,15 @@ export default function FileManager() {
250253
setShowPreviewModal(true);
251254
};
252255

256+
const handleMove = (file: FileItemData) => {
257+
setFileToMove(file);
258+
setShowMoveDialog(true);
259+
};
260+
261+
const handleMoved = () => {
262+
setRefreshKey((prev) => prev + 1);
263+
};
264+
253265
const storageFiles: FileItemData[] = storages.map((storage) => ({
254266
id: storage.id,
255267
name: storage.name,
@@ -259,6 +271,24 @@ export default function FileManager() {
259271

260272
const displayFiles = selectedStorageId ? browsedFiles : storageFiles;
261273

274+
// Get all available folders for move dialog (storages + browsed folders)
275+
const availableFolders: FileItemData[] = [
276+
...storageFiles,
277+
...(selectedStorageId ? browsedFiles.filter((f) => f.type === "folder") : []),
278+
];
279+
280+
// Get current location URL for move dialog
281+
const getCurrentLocationUrl = (): string => {
282+
if (!selectedStorageId) {
283+
return "";
284+
}
285+
if (currentPath === "/") {
286+
const storage = storages.find((s) => s.id === selectedStorageId);
287+
return storage?.url || "";
288+
}
289+
return currentPath;
290+
};
291+
262292
const selectedStorage = storages.find((s) => s.id === selectedStorageId);
263293
const breadcrumbItems = buildBreadcrumbItems(
264294
selectedStorageId,
@@ -436,6 +466,7 @@ export default function FileManager() {
436466
onFileRename={handleRename}
437467
onFilePreview={handlePreview}
438468
onFileCopy={handleCopy}
469+
onFileMove={handleMove}
439470
selectedFileIds={selectedFileIds}
440471
/>
441472
</div>
@@ -479,6 +510,17 @@ export default function FileManager() {
479510
}}
480511
file={fileToPreview}
481512
/>
513+
<MoveDialog
514+
isOpen={showMoveDialog}
515+
onClose={() => {
516+
setShowMoveDialog(false);
517+
setFileToMove(null);
518+
}}
519+
file={fileToMove}
520+
availableFolders={availableFolders}
521+
currentLocationUrl={getCurrentLocationUrl()}
522+
onMoved={handleMoved}
523+
/>
482524
<FileUploadHandler
483525
currentContainerUrl={containerUrlToBrowse}
484526
onUploadComplete={handleFileUploaded}

0 commit comments

Comments
 (0)