started getting move file and folder API working

This commit is contained in:
subnub
2024-08-04 18:36:59 -04:00
parent f0c2bbd42d
commit 34323fe4fb
13 changed files with 191 additions and 50 deletions
+4 -4
View File
@@ -727,11 +727,11 @@ class FileController {
}
try {
const fileID = req.body.id;
const userID = req.user._id;
const folderID = req.body.parentID;
const fileID = req.body.id as string;
const userID = req.user._id as string;
const parentID = (req.body.parentID as string) || "/";
await fileService.moveFile(userID, fileID, folderID);
await fileService.moveFile(userID, fileID, parentID);
res.send();
} catch (e: unknown) {
+2 -2
View File
@@ -177,9 +177,9 @@ class FolderController {
try {
const userID = req.user._id;
const folderID = req.body.id;
const parent = req.body.parent;
const parentID = req.body.parentID;
await folderService.moveFolder(userID, folderID, parent);
await folderService.moveFolder(userID, folderID, parentID);
res.send();
} catch (e: unknown) {
+17 -2
View File
@@ -129,7 +129,7 @@ class DbUtil {
) => {
const folder = (await Folder.findOneAndUpdate(
{ _id: new ObjectId(folderID), owner: userID },
{ $set: { parent: parent, parentList: parentList } }
{ $set: { parent: parent, parentList: parentList }, new: true }
)) as FolderInterface;
return folder;
@@ -194,7 +194,11 @@ class DbUtil {
owner: userID,
};
const idQuery = [currentParent];
const idQuery = [];
if (currentParent && currentParent !== "/") {
idQuery.push(currentParent);
}
if (folderID) {
query.parentList = { $ne: folderID };
@@ -217,6 +221,17 @@ class DbUtil {
return result;
};
getFolderListByIncludedParent = async (userID: string, parent: string) => {
const folderList = await Folder.find({
owner: userID,
parentList: {
$in: parent,
},
});
return folderList;
};
}
export default DbUtil;
+2 -2
View File
@@ -4,7 +4,7 @@ import env from "../enviroment/env";
import FileSystemService from "../services/ChunkService/FileSystemService";
import S3Service from "../services/ChunkService/S3Service";
import FolderController from "../controllers/folder";
import { moveFolderValidationRules } from "../middleware/Folders/FolderMiddleware";
import { moveFolderListValidationRules } from "../middleware/Folders/FolderMiddleware";
let folderController: FolderController;
@@ -51,7 +51,7 @@ router.get(
router.get(
"/folder-service/move-folder-list",
auth,
moveFolderValidationRules,
moveFolderListValidationRules,
folderController.getMoveFolderList
);
@@ -0,0 +1,9 @@
import { query, validationResult } from "express-validator";
import { Request, Response, NextFunction } from "express";
import { middlewareValidationFunction } from "../Utils/MiddlewareUtils";
export const moveFileValidationRules = [
query("fileID").isString().withMessage("Parent must be a string"),
query("parentID").isString().withMessage("Parent must be a string"),
middlewareValidationFunction,
];
+3 -12
View File
@@ -1,18 +1,9 @@
import { query, validationResult } from "express-validator";
import { Request, Response, NextFunction } from "express";
import { middlewareValidationFunction } from "../Utils/MiddlewareUtils";
export const moveFolderValidationRules = [
export const moveFolderListValidationRules = [
query("parent").optional().isString().withMessage("Parent must be a string"),
query("search").optional().isString().withMessage("Search must be a string"),
query("folderID")
.optional()
.isString()
.withMessage("FolderID must be a string"),
(req: Request, res: Response, next: NextFunction) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
next();
},
middlewareValidationFunction,
];
@@ -0,0 +1,15 @@
import { NextFunction } from "express";
import { validationResult } from "express-validator";
import { Request, Response } from "express";
export const middlewareValidationFunction = (
req: Request,
res: Response,
next: NextFunction
) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
next();
};
+13 -5
View File
@@ -315,21 +315,29 @@ class MongoFileService {
return file;
};
moveFile = async (userID: string, fileID: string, folderID: string) => {
moveFile = async (userID: string, fileID: string, parentID: string) => {
const file = await dbUtilsFile.getFileInfo(fileID, userID);
if (!file) throw new NotFoundError("Move File Not Found Error");
const folder = await dbUtilsFolder.getFolderInfo(folderID, userID);
const newParentList = [];
if (!folder) throw new NotFoundError("Move Folder Not Found Error");
if (parentID !== "/") {
const folder = await dbUtilsFolder.getFolderInfo(parentID, userID);
const newParentList = [...folder.parentList, folder._id];
if (!folder) throw new NotFoundError("Move Folder Not Found Error");
newParentList.push(...folder.parentList, folder._id);
} else {
newParentList.push("/");
}
console.log("new parent list", newParentList, parentID);
const updatedFile = await dbUtilsFile.moveFile(
fileID,
userID,
folderID,
parentID,
newParentList.toString()
);
+46 -6
View File
@@ -248,16 +248,56 @@ class FolderService {
};
moveFolder = async (userID: string, folderID: string, parentID: string) => {
console.log("parentID", parentID);
const foldersByIncludedParent =
await utilsFolder.getFolderListByIncludedParent(userID, folderID);
//const newParentList = [];
if (parentID !== "/") {
const folderToMoveTo = await utilsFolder.getFolderInfo(parentID, userID);
if (!folderToMoveTo) {
throw new NotFoundError("Move Folder Not Found Error");
}
for (let i = 0; i < foldersByIncludedParent.length; i++) {
const currentFolder = foldersByIncludedParent[i];
const currentParentIndex = currentFolder.parentList.indexOf(folderID);
const newParentList = [
...folderToMoveTo.parentList,
folderToMoveTo._id.toString(),
...currentFolder.parentList.slice(currentParentIndex + 1),
];
console.log("new parent list", newParentList);
await utilsFolder.moveFolder(
folderID,
userID,
folderToMoveTo._id.toString(),
newParentList
);
}
} else {
// newParentList.push("/");
}
console.log("foldersByIncludedParent", foldersByIncludedParent);
return;
let parentList = ["/"];
if (parentID.length !== 1) {
const parentFile = await utilsFolder.getFolderInfo(parentID, userID);
// if (parentID.length !== 1) {
// const parentFile = await utilsFolder.getFolderInfo(parentID, userID);
if (!parentFile) throw new NotFoundError("Parent Folder Info Not Found");
// if (!parentFile) throw new NotFoundError("Parent Folder Info Not Found");
parentList = parentFile.parentList;
parentList.push(parentID);
}
// parentList = parentFile.parentList;
// parentList.push(parentID);
// }
const folder = await utilsFolder.moveFolder(
folderID,
+8
View File
@@ -206,6 +206,14 @@ export const removeLinkAPI = async (fileID: string) => {
return response.data;
};
export const moveFileAPI = async (fileID: string, parentID: string) => {
const response = await axios.patch(`/file-service/move`, {
id: fileID,
parentID,
});
return response.data;
};
// DELETE
export const deleteFileAPI = async (fileID: string) => {
+8
View File
@@ -90,6 +90,14 @@ export const restoreFolderAPI = async (folderID: string) => {
return response.data;
};
export const moveFolderAPI = async (folderID: string, parentID: string) => {
const response = await axios.patch(`/folder-service/move`, {
id: folderID,
parentID,
});
return response.data;
};
// DELETE
export const deleteFolderAPI = async (folderID: string) => {
+60 -13
View File
@@ -1,6 +1,6 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { useMoveFolders } from "../../hooks/folders";
import { useFoldersClient, useMoveFolders } from "../../hooks/folders";
import { FolderInterface } from "../../types/folders";
import CloseIcon from "../../icons/CloseIcon";
import { resetMoveModal } from "../../reducers/selected";
@@ -10,6 +10,10 @@ import HomeIconOutline from "../../icons/HomeIconOutline";
import ArrowBackIcon from "../../icons/ArrowBackIcon";
import classNames from "classnames";
import FolderIcon from "../../icons/FolderIcon";
import { toast } from "react-toastify";
import { moveFileAPI } from "../../api/filesAPI";
import { useFilesClient } from "../../hooks/files";
import { moveFolderAPI } from "../../api/foldersAPI";
const MoverPopup = () => {
const [search, setSearch] = useState("");
@@ -22,9 +26,12 @@ const MoverPopup = () => {
const multiSelectMode = useAppSelector(
(state) => state.selected.multiSelectMode
);
const [isLoadingMove, setIsLoadingMove] = useState(false);
const file = useAppSelector((state) => state.selected.moveModal.file);
const folder = useAppSelector((state) => state.selected.moveModal.folder);
const dispatch = useAppDispatch();
const { invalidateFilesCache } = useFilesClient();
const { invalidateFoldersCache } = useFoldersClient();
const lastSelected = useRef({
timestamp: 0,
folderID: "",
@@ -59,7 +66,7 @@ const MoverPopup = () => {
setDebouncedSearch("");
setParentList([...parentList, folder]);
setParent(folder);
setSelectedFolder(folder);
setSelectedFolder(null);
} else {
setSelectedFolder(folder);
}
@@ -83,14 +90,21 @@ const MoverPopup = () => {
};
const moveText = useMemo(() => {
if (selectedFolder?._id) {
return "Move to selected folder";
if (selectedFolder?._id && selectedFolder?.name) {
let reducedLengthFileName = selectedFolder.name;
if (reducedLengthFileName.length > 10)
reducedLengthFileName = reducedLengthFileName.substring(0, 10) + "...";
return `Move to ${reducedLengthFileName}`;
} else if (!parent) {
return "Move home";
return "Move to home";
} else {
return "Move here";
const lastParent = parentList[parentList.length - 1];
let reducedLengthFileName = lastParent.name;
if (reducedLengthFileName.length > 10)
reducedLengthFileName = reducedLengthFileName.substring(0, 10) + "...";
return `Move to ${reducedLengthFileName}`;
}
}, [selectedFolder?._id, parent?._id]);
}, [selectedFolder?._id, selectedFolder?.name, parent?._id]);
const headerText = useMemo(() => {
if (parent) {
@@ -108,14 +122,40 @@ const MoverPopup = () => {
setSelectedFolder(null);
};
const onMoveClick = () => {
const onMoveClick = async () => {
setIsLoadingMove(true);
const moveTo = selectedFolder?._id
? selectedFolder?._id
: parent?._id || "/";
if (file) {
} else if (folder) {
try {
if (multiSelectMode) {
} else if (file) {
await toast.promise(moveFileAPI(file._id, moveTo), {
pending: "Moving File...",
success: "File Moved",
error: "Error Moving File",
});
invalidateFilesCache();
dispatch(resetMoveModal());
} else if (folder) {
await toast.promise(moveFolderAPI(folder._id, moveTo), {
pending: "Moving Folder...",
success: "Folder Moved",
error: "Error Moving Folder",
});
invalidateFoldersCache();
dispatch(resetMoveModal());
}
console.log("move to", moveTo);
} catch (e) {
console.log("move error", e);
} finally {
setIsLoadingMove(false);
}
console.log("move to", moveTo);
};
const onTitleClick = () => {
setSelectedFolder(parentList[parentList.length - 1]);
};
const closeMoverModal = (e: any) => {
@@ -163,7 +203,10 @@ const MoverPopup = () => {
/>
</div>
<div>
<p className="text-lg mt-2 mb-2 max-w-[75%] text-ellipsis overflow-hidden">
<p
className="text-lg mt-2 mb-2 max-w-[75%] text-ellipsis overflow-hidden select-none cursor-pointer"
onClick={onTitleClick}
>
{headerText}
</p>
</div>
@@ -206,9 +249,13 @@ const MoverPopup = () => {
<div className="flex justify-end mt-4">
<button
className={classNames(
"bg-primary hover:bg-primary-hover text-white px-4 py-2 rounded-md"
"bg-primary hover:bg-primary-hover text-white px-4 py-2 rounded-md",
{
"opacity-50": isLoadingMove,
}
)}
onClick={onMoveClick}
disabled={isLoadingMove}
>
{moveText}
</button>
+4 -4
View File
@@ -264,14 +264,14 @@ const PhotoViewerPopup: React.FC<PhotoViewerPopupProps> = memo((props) => {
<div className="flex mr-4">
<div onClick={onContextMenu} id="action-context-wrapper">
<ActionsIcon
className="pointer text-white w-[20px] h-[25px] mr-4 cursor-pointer"
className="pointer text-white w-[20px] h-[25px] mr-4 cursor-pointer hover:text-white-hover"
id="action-context-icon"
/>
</div>
<div onClick={closePhotoViewer} id="action-close-wrapper">
<CloseIcon
className="pointer text-white w-[25px] h-[25px] cursor-pointer"
className="pointer text-white w-[25px] h-[25px] cursor-pointer hover:text-white-hover"
id="action-close-icon"
/>
</div>
@@ -280,11 +280,11 @@ const PhotoViewerPopup: React.FC<PhotoViewerPopupProps> = memo((props) => {
<div className="flex absolute pb-[70px] desktopMode:pb-0 top-[50px] bottom-0 w-full h-full justify-between items-end desktopMode:items-center p-4">
<CircleLeftIcon
onClick={goToPreviousItem}
className="pointer text-white w-[45px] h-[45px] desktopMode:w-[30px] desktopMode:h-[30px] select-none cursor-pointer"
className="pointer text-white w-[45px] h-[45px] desktopMode:w-[30px] desktopMode:h-[30px] select-none cursor-pointer hover:text-white-hover"
/>
<CircleRightIcon
onClick={goToNextItem}
className="pointer text-white w-[45px] h-[45px] desktopMode:w-[30px] desktopMode:h-[30px] select-none cursor-pointer"
className="pointer text-white w-[45px] h-[45px] desktopMode:w-[30px] desktopMode:h-[30px] select-none cursor-pointer hover:text-white-hover"
/>
</div>
<div className="max-w-[80vw] max-h-[80vh] flex justify-center items-center">