feat: improve file uploader size validation - custom hook (#3952)
* 📝 (inputFileComponent/index.tsx): add useFileSizeValidator hook to validate file size before upload to improve code readability and maintainability * 📝 (chatInput/index.tsx): remove unused imports and refactor file size validation to use a custom hook for better code organization and readability * 📝 (FileInput/index.tsx): refactor file input component to use a custom hook for file size validation instead of utility store 🔧 (FileInput/index.tsx): remove dependency on utility store for max file size upload and use a custom hook for file size validation instead * ✨ (use-file-size-validator.tsx): introduce a new custom hook useFileSizeValidator to validate file size before uploading it
This commit is contained in:
parent
29404c79ba
commit
6db15255a5
4 changed files with 36 additions and 23 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
|
import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
|
||||||
import { createFileUpload } from "@/helpers/create-file-upload";
|
import { createFileUpload } from "@/helpers/create-file-upload";
|
||||||
|
import useFileSizeValidator from "@/shared/hooks/use-file-size-validator";
|
||||||
import { useUtilityStore } from "@/stores/utilityStore";
|
import { useUtilityStore } from "@/stores/utilityStore";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import {
|
import {
|
||||||
|
|
@ -23,7 +24,8 @@ export default function InputFileComponent({
|
||||||
}: FileComponentType): JSX.Element {
|
}: FileComponentType): JSX.Element {
|
||||||
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const maxFileSizeUpload = useUtilityStore((state) => state.maxFileSizeUpload);
|
const { validateFileSize } = useFileSizeValidator(setErrorData);
|
||||||
|
|
||||||
// Clear component state
|
// Clear component state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (disabled && value !== "") {
|
if (disabled && value !== "") {
|
||||||
|
|
@ -47,13 +49,11 @@ export default function InputFileComponent({
|
||||||
createFileUpload({ multiple: false, accept: fileTypes?.join(",") }).then(
|
createFileUpload({ multiple: false, accept: fileTypes?.join(",") }).then(
|
||||||
(files) => {
|
(files) => {
|
||||||
const file = files[0];
|
const file = files[0];
|
||||||
if (file.size > maxFileSizeUpload) {
|
if (file) {
|
||||||
setErrorData({
|
if (!validateFileSize(file)) {
|
||||||
title: INVALID_FILE_SIZE_ALERT(maxFileSizeUpload / 1024 / 1024),
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (file) {
|
|
||||||
if (checkFileType(file.name)) {
|
if (checkFileType(file.name)) {
|
||||||
// Upload the file
|
// Upload the file
|
||||||
mutate(
|
mutate(
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { Button } from "../../../../../../components/ui/button";
|
import { Button } from "../../../../../../components/ui/button";
|
||||||
|
|
||||||
import { INVALID_FILE_SIZE_ALERT } from "@/constants/alerts_constants";
|
|
||||||
import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
|
import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
|
||||||
import { createFileUpload } from "@/helpers/create-file-upload";
|
import { createFileUpload } from "@/helpers/create-file-upload";
|
||||||
|
import useFileSizeValidator from "@/shared/hooks/use-file-size-validator";
|
||||||
import useAlertStore from "@/stores/alertStore";
|
import useAlertStore from "@/stores/alertStore";
|
||||||
import { useUtilityStore } from "@/stores/utilityStore";
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import IconComponent from "../../../../../../components/genericIconComponent";
|
import IconComponent from "../../../../../../components/genericIconComponent";
|
||||||
import {
|
import {
|
||||||
|
|
@ -22,7 +21,7 @@ export default function IOFileInput({ field, updateValue }: IOFileInputProps) {
|
||||||
const [filePath, setFilePath] = useState("");
|
const [filePath, setFilePath] = useState("");
|
||||||
const [image, setImage] = useState<string | null>(null);
|
const [image, setImage] = useState<string | null>(null);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const maxFileSizeUpload = useUtilityStore((state) => state.maxFileSizeUpload);
|
const { validateFileSize } = useFileSizeValidator(setErrorData);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
|
|
@ -79,13 +78,9 @@ export default function IOFileInput({ field, updateValue }: IOFileInputProps) {
|
||||||
|
|
||||||
const upload = async (file) => {
|
const upload = async (file) => {
|
||||||
if (file) {
|
if (file) {
|
||||||
if (file.size > maxFileSizeUpload) {
|
if (!validateFileSize(file)) {
|
||||||
setErrorData({
|
|
||||||
title: INVALID_FILE_SIZE_ALERT(maxFileSizeUpload / 1024 / 1024),
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a file was selected
|
// Check if a file was selected
|
||||||
const fileReader = new FileReader();
|
const fileReader = new FileReader();
|
||||||
fileReader.onload = (event) => {
|
fileReader.onload = (event) => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { INVALID_FILE_SIZE_ALERT } from "@/constants/alerts_constants";
|
|
||||||
import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
|
import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
|
||||||
|
import useFileSizeValidator from "@/shared/hooks/use-file-size-validator";
|
||||||
import useAlertStore from "@/stores/alertStore";
|
import useAlertStore from "@/stores/alertStore";
|
||||||
import { useUtilityStore } from "@/stores/utilityStore";
|
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import ShortUniqueId from "short-unique-id";
|
import ShortUniqueId from "short-unique-id";
|
||||||
import {
|
import {
|
||||||
|
|
@ -38,12 +37,12 @@ export default function ChatInput({
|
||||||
const [inputFocus, setInputFocus] = useState<boolean>(false);
|
const [inputFocus, setInputFocus] = useState<boolean>(false);
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const maxFileSizeUpload = useUtilityStore((state) => state.maxFileSizeUpload);
|
const { validateFileSize } = useFileSizeValidator(setErrorData);
|
||||||
|
|
||||||
useFocusOnUnlock(lockChat, inputRef);
|
useFocusOnUnlock(lockChat, inputRef);
|
||||||
useAutoResizeTextArea(chatValue, inputRef);
|
useAutoResizeTextArea(chatValue, inputRef);
|
||||||
|
|
||||||
const { mutate, isPending } = usePostUploadFile();
|
const { mutate } = usePostUploadFile();
|
||||||
|
|
||||||
const handleFileChange = async (
|
const handleFileChange = async (
|
||||||
event: React.ChangeEvent<HTMLInputElement> | ClipboardEvent,
|
event: React.ChangeEvent<HTMLInputElement> | ClipboardEvent,
|
||||||
|
|
@ -68,10 +67,7 @@ export default function ChatInput({
|
||||||
if (file) {
|
if (file) {
|
||||||
const fileExtension = file.name.split(".").pop()?.toLowerCase();
|
const fileExtension = file.name.split(".").pop()?.toLowerCase();
|
||||||
|
|
||||||
if (file.size > maxFileSizeUpload) {
|
if (!validateFileSize(file)) {
|
||||||
setErrorData({
|
|
||||||
title: INVALID_FILE_SIZE_ALERT(maxFileSizeUpload / 1024 / 1024),
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
22
src/frontend/src/shared/hooks/use-file-size-validator.tsx
Normal file
22
src/frontend/src/shared/hooks/use-file-size-validator.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { INVALID_FILE_SIZE_ALERT } from "@/constants/alerts_constants";
|
||||||
|
import { useUtilityStore } from "@/stores/utilityStore";
|
||||||
|
|
||||||
|
const useFileSizeValidator = (
|
||||||
|
setErrorData: (newState: { title: string; list?: Array<string> }) => void,
|
||||||
|
) => {
|
||||||
|
const maxFileSizeUpload = useUtilityStore((state) => state.maxFileSizeUpload);
|
||||||
|
|
||||||
|
const validateFileSize = (file) => {
|
||||||
|
if (file.size > maxFileSizeUpload) {
|
||||||
|
setErrorData({
|
||||||
|
title: INVALID_FILE_SIZE_ALERT(maxFileSizeUpload / 1024 / 1024),
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return { validateFileSize };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useFileSizeValidator;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue