From 8c133cea75ae3eed0ff2e83c0a13892b00656a2f Mon Sep 17 00:00:00 2001 From: Saifullah-dev Date: Mon, 11 Nov 2024 11:58:09 +0500 Subject: [PATCH] fix(Callback Props): Update error message to instruct user to pass missing required callback props --- .../Actions/CreateFolder/CreateFolder.action.jsx | 3 ++- .../FileManager/Actions/Rename/Rename.action.jsx | 3 ++- frontend/src/FileManager/FileManager.jsx | 10 +++++----- frontend/src/FileManager/Toolbar/Toolbar.jsx | 3 ++- frontend/src/contexts/ClipboardContext.jsx | 3 ++- frontend/src/contexts/SelectionContext.jsx | 3 ++- frontend/src/hooks/useShortcutHandler.js | 3 ++- frontend/src/utils/validateApiCallback.js | 13 +++++++++++++ 8 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 frontend/src/utils/validateApiCallback.js diff --git a/frontend/src/FileManager/Actions/CreateFolder/CreateFolder.action.jsx b/frontend/src/FileManager/Actions/CreateFolder/CreateFolder.action.jsx index e2b9e21..17f0357 100644 --- a/frontend/src/FileManager/Actions/CreateFolder/CreateFolder.action.jsx +++ b/frontend/src/FileManager/Actions/CreateFolder/CreateFolder.action.jsx @@ -5,6 +5,7 @@ import NameInput from "../../../components/NameInput/NameInput"; import ErrorTooltip from "../../../components/ErrorTooltip/ErrorTooltip"; import { useFileNavigation } from "../../../contexts/FileNavigationContext"; import { useLayout } from "../../../contexts/LayoutContext"; +import { validateApiCallback } from "../../../utils/validateApiCallback"; const maxNameLength = 220; @@ -84,7 +85,7 @@ const CreateFolderAction = ({ filesViewRef, file, onCreateFolder, triggerAction newFolderName = duplicateNameHandler("New Folder", true, syncedCurrPathFiles); } - onCreateFolder(newFolderName, currentFolder); + validateApiCallback(onCreateFolder, "onCreateFolder", newFolderName, currentFolder); setCurrentPathFiles((prev) => prev.filter((f) => f.key !== file.key)); triggerAction.close(); } diff --git a/frontend/src/FileManager/Actions/Rename/Rename.action.jsx b/frontend/src/FileManager/Actions/Rename/Rename.action.jsx index 3f9ff2a..9961b29 100644 --- a/frontend/src/FileManager/Actions/Rename/Rename.action.jsx +++ b/frontend/src/FileManager/Actions/Rename/Rename.action.jsx @@ -8,6 +8,7 @@ import NameInput from "../../../components/NameInput/NameInput"; import ErrorTooltip from "../../../components/ErrorTooltip/ErrorTooltip"; import { useFileNavigation } from "../../../contexts/FileNavigationContext"; import { useLayout } from "../../../contexts/LayoutContext"; +import { validateApiCallback } from "../../../utils/validateApiCallback"; const maxNameLength = 220; @@ -88,7 +89,7 @@ const RenameAction = ({ filesViewRef, file, onRename, triggerAction }) => { } } setFileRenameError(false); - onRename(file, renameFile); + validateApiCallback(onRename, "onRename", file, renameFile); setCurrentPathFiles((prev) => prev.filter((f) => f.key !== file.key)); // Todo: Should only filter on success API call triggerAction.close(); } diff --git a/frontend/src/FileManager/FileManager.jsx b/frontend/src/FileManager/FileManager.jsx index ab3c60a..41eac05 100644 --- a/frontend/src/FileManager/FileManager.jsx +++ b/frontend/src/FileManager/FileManager.jsx @@ -20,16 +20,16 @@ const FileManager = ({ fileUploadConfig, isLoading, onCreateFolder, - onFileUploading, - onFileUploaded, + onFileUploading = () => {}, + onFileUploaded = () => {}, onPaste, onRename, onDownload, onDelete = () => null, - onLayoutChange, + onLayoutChange = () => {}, onRefresh, - onFileOpen, - onError, + onFileOpen = () => {}, + onError = () => {}, layout = "grid", enableFilePreview = true, maxFileSize, diff --git a/frontend/src/FileManager/Toolbar/Toolbar.jsx b/frontend/src/FileManager/Toolbar/Toolbar.jsx index 14e0457..07d3efe 100644 --- a/frontend/src/FileManager/Toolbar/Toolbar.jsx +++ b/frontend/src/FileManager/Toolbar/Toolbar.jsx @@ -14,6 +14,7 @@ import { useFileNavigation } from "../../contexts/FileNavigationContext"; import { useSelection } from "../../contexts/SelectionContext"; import { useClipBoard } from "../../contexts/ClipboardContext"; import { useLayout } from "../../contexts/LayoutContext"; +import { validateApiCallback } from "../../utils/validateApiCallback"; import "./Toolbar.scss"; const Toolbar = ({ @@ -61,7 +62,7 @@ const Toolbar = ({ icon: , title: "Refresh", onClick: () => { - onRefresh(); + validateApiCallback(onRefresh, "onRefresh"); setClipBoard(null); }, }, diff --git a/frontend/src/contexts/ClipboardContext.jsx b/frontend/src/contexts/ClipboardContext.jsx index 47605e3..1188a70 100644 --- a/frontend/src/contexts/ClipboardContext.jsx +++ b/frontend/src/contexts/ClipboardContext.jsx @@ -1,5 +1,6 @@ import { createContext, useContext, useState } from "react"; import { useSelection } from "./SelectionContext"; +import { validateApiCallback } from "../utils/validateApiCallback"; const ClipBoardContext = createContext(); @@ -21,7 +22,7 @@ export const ClipBoardProvider = ({ children, onPaste }) => { const copiedFiles = clipBoard.files; const operationType = clipBoard.isMoving ? "move" : "copy"; - onPaste(copiedFiles, destinationFolder, operationType); + validateApiCallback(onPaste, "onPaste", copiedFiles, destinationFolder, operationType); clipBoard.isMoving && setClipBoard(null); setSelectedFiles([]); diff --git a/frontend/src/contexts/SelectionContext.jsx b/frontend/src/contexts/SelectionContext.jsx index 2b64e36..de3c6b9 100644 --- a/frontend/src/contexts/SelectionContext.jsx +++ b/frontend/src/contexts/SelectionContext.jsx @@ -1,4 +1,5 @@ import { createContext, useContext, useState } from "react"; +import { validateApiCallback } from "../utils/validateApiCallback"; const SelectionContext = createContext(); @@ -6,7 +7,7 @@ export const SelectionProvider = ({ children, onDownload }) => { const [selectedFiles, setSelectedFiles] = useState([]); const handleDownload = () => { - onDownload(selectedFiles); + validateApiCallback(onDownload, "onDownload", selectedFiles); }; return ( diff --git a/frontend/src/hooks/useShortcutHandler.js b/frontend/src/hooks/useShortcutHandler.js index 2dc455b..7704484 100644 --- a/frontend/src/hooks/useShortcutHandler.js +++ b/frontend/src/hooks/useShortcutHandler.js @@ -4,6 +4,7 @@ import { useClipBoard } from "../contexts/ClipboardContext"; import { useFileNavigation } from "../contexts/FileNavigationContext"; import { useSelection } from "../contexts/SelectionContext"; import { useLayout } from "../contexts/LayoutContext"; +import { validateApiCallback } from "../utils/validateApiCallback"; export const useShortcutHandler = (triggerAction, onRefresh) => { const { setClipBoard, handleCutCopy, handlePasting } = useClipBoard(); @@ -64,7 +65,7 @@ export const useShortcutHandler = (triggerAction, onRefresh) => { }; const triggerRefresh = () => { - onRefresh(); + validateApiCallback(onRefresh, "onRefresh"); setClipBoard(null); }; diff --git a/frontend/src/utils/validateApiCallback.js b/frontend/src/utils/validateApiCallback.js new file mode 100644 index 0000000..7519a67 --- /dev/null +++ b/frontend/src/utils/validateApiCallback.js @@ -0,0 +1,13 @@ +export const validateApiCallback = (callback, callbackName, ...args) => { + try { + if (typeof callback === "function") { + callback(...args); + } else { + throw new Error( + ` Missing prop: Callback function "${callbackName}" is required.` + ); + } + } catch (error) { + console.error(error.message); + } +};