From b2801480aac74800b9310ca9b4361aa1fe1cf96b Mon Sep 17 00:00:00 2001 From: amel Date: Sun, 5 Jan 2025 17:15:53 +0800 Subject: [PATCH] rev: file upload ekstensi Deskripsi: - tambah type ekstensi file upload pada project, task divisi dan dokumen divisi No Issues --- .../ui/drawer_menu_document_division.tsx | 2 +- .../document/ui/navbar_document_division.tsx | 76 +++++++++++-------- .../project/ui/add_file_detail_project.tsx | 3 +- src/module/project/ui/create_project.tsx | 2 +- .../project/ui/list_file_detail_project.tsx | 60 +++++++++++---- src/module/project/ui/results_file.tsx | 47 ++++++++++-- src/module/task/ui/add_file_detail_task.tsx | 2 +- src/module/task/ui/create_task.tsx | 2 +- src/module/task/ui/detail_list_file_task.tsx | 59 ++++++++++---- src/module/task/ui/results_file.tsx | 50 +++++++++--- 10 files changed, 219 insertions(+), 84 deletions(-) diff --git a/src/module/document/ui/drawer_menu_document_division.tsx b/src/module/document/ui/drawer_menu_document_division.tsx index 7fefc09..cc99b97 100644 --- a/src/module/document/ui/drawer_menu_document_division.tsx +++ b/src/module/document/ui/drawer_menu_document_division.tsx @@ -149,7 +149,7 @@ export default function DrawerMenuDocumentDivision() { }} activateOnClick={false} maxSize={3 * 1024 ** 2} - accept={['text/csv', 'image/png', 'image/jpeg', 'image/heic', 'application/pdf']} + accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']} onReject={(files) => { refresh.set(true) setOpenModal(false) diff --git a/src/module/document/ui/navbar_document_division.tsx b/src/module/document/ui/navbar_document_division.tsx index 80af889..a513250 100644 --- a/src/module/document/ui/navbar_document_division.tsx +++ b/src/module/document/ui/navbar_document_division.tsx @@ -34,6 +34,7 @@ export default function NavbarDocumentDivision() { const [isOpenModalView, setOpenModalView] = useState(false); const [isExtension, setExtension] = useState(""); const [idStorage, setIdStorage] = useState(""); + const [nameFileFull, setNameFileFull] = useState(""); const [name, setName] = useState(""); const [isOpen, setOpen] = useState(false); const [isDelete, setIsDelete] = useState(false); @@ -253,9 +254,18 @@ export default function NavbarDocumentDivision() { setRename(true); } - const onDownload = async () => { + const onDownload = async (kategori: string, file?: { idFile: string, nameFile: string }) => { try { - const fileUrl = `https://wibu-storage.wibudev.com/api/files/${selectedFiles[0].idStorage}`; + let idStorageDownload, nameFileDownload = "" + if (kategori == "selected") { + idStorageDownload = selectedFiles[0].idStorage + nameFileDownload = `${selectedFiles[0].name}.${selectedFiles[0].extension}` + } else if (kategori == "klik") { + idStorageDownload = file?.idFile + nameFileDownload = String(file?.nameFile) + } + + const fileUrl = `https://wibu-storage.wibudev.com/api/files/${idStorageDownload}`; const response = await fetch(fileUrl); const blob = await response.blob(); @@ -263,7 +273,7 @@ export default function NavbarDocumentDivision() { const link = document.createElement("a"); const url = window.URL.createObjectURL(blob); link.href = url; - link.download = `${selectedFiles[0].name}.${selectedFiles[0].extension}`; // Nama file yang akan diunduh + link.download = nameFileDownload; // Nama file yang akan diunduh document.body.appendChild(link); link.click(); @@ -341,7 +351,7 @@ export default function NavbarDocumentDivision() { direction={"column"} onClick={() => { if (selectedFiles.length > 0 && copyAllowed) { - onDownload(); + onDownload("selected"); } }} > @@ -663,9 +673,7 @@ export default function NavbarDocumentDivision() { ) : ( dataDocument.map((v, i) => { - const isSelected = selectedFiles.some( - (i: any) => i?.id == v.id - ); + const isSelected = selectedFiles.some((i: any) => i?.id == v.id); return ( @@ -680,20 +688,17 @@ export default function NavbarDocumentDivision() { xl: 1, }} onClick={() => { - if ( - v.category == "FOLDER" && - selectedFiles.length == 0 && - !dariSelectAll - ) { + if (v.category == "FOLDER" && selectedFiles.length == 0 && !dariSelectAll) { router.push("?path=" + v.id); - } else if ( - v.category == "FILE" && - selectedFiles.length == 0 && - !dariSelectAll - ) { + } else if (v.category == "FILE" && selectedFiles.length == 0 && !dariSelectAll) { setExtension(v.extension); setIdStorage(v.idStorage); - setOpenModalView(true); + setNameFileFull(v.name + "." + v.extension) + if (v.extension != "doc" && v.extension != "docx" && v.extension != "xls" && v.extension != "xlsx" && v.extension != "ppt" && v.extension != "pptx") { + setOpenModalView(true); + } else { + onDownload("klik", { idFile: v.idStorage, nameFile: v.name + "." + v.extension }) + } } }} > @@ -712,7 +717,13 @@ export default function NavbarDocumentDivision() { {v.category == "FOLDER" ? ( ) : v.extension == "pdf" || - v.extension == "csv" ? ( + v.extension == "csv" || + v.extension == "doc" || + v.extension == "docx" || + v.extension == "xls" || + v.extension == "xlsx" || + v.extension == "ppt" || + v.extension == "pptx" ? ( ) : ( @@ -723,7 +734,13 @@ export default function NavbarDocumentDivision() { {v.category == "FOLDER" ? ( ) : v.extension == "pdf" || - v.extension == "csv" ? ( + v.extension == "csv" || + v.extension == "doc" || + v.extension == "docx" || + v.extension == "xls" || + v.extension == "xlsx" || + v.extension == "ppt" || + v.extension == "pptx" ? ( ) : ( @@ -747,20 +764,17 @@ export default function NavbarDocumentDivision() { { - if ( - v.category == "FOLDER" && - selectedFiles.length == 0 && - !dariSelectAll - ) { + if (v.category == "FOLDER" && selectedFiles.length == 0 && !dariSelectAll) { router.push("?path=" + v.id); - } else if ( - v.category == "FILE" && - selectedFiles.length == 0 && - !dariSelectAll - ) { + } else if (v.category == "FILE" && selectedFiles.length == 0 && !dariSelectAll) { setExtension(v.extension); setIdStorage(v.idStorage); - setOpenModalView(true); + setNameFileFull(v.name + "." + v.extension) + if (v.extension != "doc" && v.extension != "docx" && v.extension != "xls" && v.extension != "xlsx" && v.extension != "ppt" && v.extension != "pptx") { + setOpenModalView(true); + } else { + onDownload("klik", { idFile: v.idStorage, nameFile: v.name + "." + v.extension }) + } } }} > diff --git a/src/module/project/ui/add_file_detail_project.tsx b/src/module/project/ui/add_file_detail_project.tsx index c6ca3dd..d1efa2c 100644 --- a/src/module/project/ui/add_file_detail_project.tsx +++ b/src/module/project/ui/add_file_detail_project.tsx @@ -69,7 +69,6 @@ export default function AddFileDetailProject() { } const response = await funAddFileProject(param.id, fd) - console.group(response) if (response.success) { setDataRealtime([{ category: "project-detail-file", @@ -107,7 +106,7 @@ export default function AddFileDetailProject() { }} activateOnClick={false} maxSize={3 * 1024 ** 2} - accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf']} + accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']} onReject={(files) => { return toast.error('File yang diizinkan: .png, .jpg, .heic, .pdf dengan ukuran maksimal 3 MB') }} diff --git a/src/module/project/ui/create_project.tsx b/src/module/project/ui/create_project.tsx index 57793c6..31232ff 100644 --- a/src/module/project/ui/create_project.tsx +++ b/src/module/project/ui/create_project.tsx @@ -413,7 +413,7 @@ export default function CreateProject() { }} activateOnClick={false} maxSize={3 * 1024 ** 2} - accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf']} + accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']} onReject={(files) => { return toast.error('File yang diizinkan: .png, .jpg, .heic, .pdf dengan ukuran maksimal 3 MB') }} diff --git a/src/module/project/ui/list_file_detail_project.tsx b/src/module/project/ui/list_file_detail_project.tsx index 9a65f43..c9fe0ad 100644 --- a/src/module/project/ui/list_file_detail_project.tsx +++ b/src/module/project/ui/list_file_detail_project.tsx @@ -7,8 +7,9 @@ import { useMediaQuery, useShallowEffect } from '@mantine/hooks'; import { useParams } from 'next/navigation'; import { useState } from 'react'; import toast from 'react-hot-toast'; -import { BsFileTextFill, BsFiletypeCsv, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng } from 'react-icons/bs'; +import { BsFileTextFill, BsFiletypeCsv, BsFiletypeDocx, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng, BsFiletypePptx, BsFiletypeXlsx } from 'react-icons/bs'; import { FaTrash } from 'react-icons/fa6'; +import { ImDownload3 } from "react-icons/im"; import { useWibuRealtime } from 'wibu-realtime'; import { funDeleteFileProject, funGetOneProjectById } from '../lib/api_project'; import { IDataFileProject } from '../lib/type_project'; @@ -113,6 +114,28 @@ export default function ListFileDetailProject() { } }, [dataRealTime]) + const onDownload = async () => { + try { + const fileUrl = `https://wibu-storage.wibudev.com/api/files/${idStorage}`; + const response = await fetch(fileUrl); + const blob = await response.blob(); + + // Create a link element, use Blob URL + const link = document.createElement("a"); + const url = window.URL.createObjectURL(blob); + link.href = url; + link.download = `${nameData}`; // Nama file yang akan diunduh + document.body.appendChild(link); + link.click(); + + // Cleanup + window.URL.revokeObjectURL(url); + document.body.removeChild(link); + } catch (error) { + alert(error); + } + }; + return ( <> @@ -167,13 +190,12 @@ export default function ListFileDetailProject() { }}> {item.extension == "pdf" && } {item.extension == "csv" && } - {item.extension == "png" && } - {item.extension == "jpg" && } - {item.extension == "jpeg" && } - {item.extension == "PNG" && } - {item.extension == "JPG" && } - {item.extension == "JPEG" && } + {(item.extension == "png" || item.extension == "PNG") && } + {(item.extension == "jpg" || item.extension == "jpeg" || item.extension == "JPG" || item.extension == "JPEG") && } {item.extension == "heic" && } + {(item.extension == "doc" || item.extension == "docx") && } + {(item.extension == "xls" || item.extension == "xlsx") && } + {(item.extension == "ppt" || item.extension == "pptx") && } {nameData}} onClose={() => setOpenDrawer(false)}> - - { setOpenModalView(true) }} justify={'center'} align={'center'} direction={'column'} > + + { + (isExtension != "doc" && isExtension != "docx" && isExtension != "xls" && isExtension != "xlsx" && isExtension != "ppt" && isExtension != "pptx") && + { setOpenModalView(true) }} justify={'center'} align={'center'} direction={'column'} > + + + + + Lihat file + + + } + + { onDownload() }} justify={'center'} align={'center'} direction={'column'} > - + - Lihat file + Download @@ -227,7 +259,7 @@ export default function ListFileDetailProject() { - Hapus file + Hapus } diff --git a/src/module/project/ui/results_file.tsx b/src/module/project/ui/results_file.tsx index 86c1f4d..4709110 100644 --- a/src/module/project/ui/results_file.tsx +++ b/src/module/project/ui/results_file.tsx @@ -1,10 +1,38 @@ - import { Box, Center, Grid, Group, Text } from '@mantine/core'; -import React from 'react'; -import { BsFiletypeCsv, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng } from 'react-icons/bs'; +import { useShallowEffect } from '@mantine/hooks'; +import { useState } from 'react'; +import { BsFiletypeCsv, BsFiletypeDocx, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng, BsFiletypePptx, BsFiletypeXlsx } from 'react-icons/bs'; import { IListFileTaskProject } from '../lib/type_project'; export default function ResultsFile({ name, extension }: IListFileTaskProject) { + const [fixed, setFixed] = useState(extension) + + function cekExtension() { + let jadi = extension + if (extension == "msword") { + jadi = "doc" + } else if (extension == "vnd.openxmlformats-officedocument.wordprocessingml.document") { + jadi = "docx" + } else if (extension == "vnd.ms-excel") { + jadi = "xls" + } else if (extension == "vnd.openxmlformats-officedocument.spreadsheetml.sheet") { + jadi = "xlsx" + } else if (extension == "vnd.ms-powerpoint") { + jadi = "ppt" + } else if (extension == "vnd.openxmlformats-officedocument.presentationml.presentation") { + jadi = "pptx" + } else { + jadi = extension + } + + setFixed(jadi) + } + + + useShallowEffect(() => { + cekExtension() + }, []); + return (
- {extension == "pdf" && } - {extension == "csv" && } - {extension == "png" && } - {extension == "jpg" || extension == "jpeg" && } - {extension == "heic" && } + {fixed == "pdf" && } + {fixed == "csv" && } + {fixed == "png" && } + {fixed == "jpg" || fixed == "jpeg" && } + {fixed == "heic" && } + {fixed == "doc" || fixed == "docx" && } + {fixed == "xls" || fixed == "xlsx" && } + {fixed == "ppt" || fixed == "pptx" && }
diff --git a/src/module/task/ui/add_file_detail_task.tsx b/src/module/task/ui/add_file_detail_task.tsx index 7bc6884..a9d2150 100644 --- a/src/module/task/ui/add_file_detail_task.tsx +++ b/src/module/task/ui/add_file_detail_task.tsx @@ -107,7 +107,7 @@ export default function AddFileDetailTask() { }} activateOnClick={false} maxSize={3 * 1024 ** 2} - accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf']} + accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']} onReject={(files) => { return toast.error('File yang diizinkan: .png, .jpg, .heic, .pdf dengan ukuran maksimal 3 MB') }} diff --git a/src/module/task/ui/create_task.tsx b/src/module/task/ui/create_task.tsx index dc4a033..bda6323 100644 --- a/src/module/task/ui/create_task.tsx +++ b/src/module/task/ui/create_task.tsx @@ -336,7 +336,7 @@ export default function CreateTask() { }} activateOnClick={false} maxSize={3 * 1024 ** 2} - accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf']} + accept={['image/png', 'image/jpeg', 'image/heic', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']} onReject={(files) => { return toast.error('File yang diizinkan: .png, .jpg, .heic, .pdf dengan ukuran maksimal 3 MB') }} diff --git a/src/module/task/ui/detail_list_file_task.tsx b/src/module/task/ui/detail_list_file_task.tsx index 50364d4..198bddc 100644 --- a/src/module/task/ui/detail_list_file_task.tsx +++ b/src/module/task/ui/detail_list_file_task.tsx @@ -1,18 +1,19 @@ 'use client' import { globalRole, keyWibu, LayoutDrawer, LayoutModalViewFile, TEMA } from "@/module/_global"; import LayoutModal from "@/module/_global/layout/layout_modal"; +import { globalIsMemberDivision } from "@/module/division_new"; import { useHookstate } from "@hookstate/core"; import { Box, Center, Flex, Grid, Group, SimpleGrid, Skeleton, Stack, Text } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; import { useParams } from "next/navigation"; import { useState } from "react"; import toast from "react-hot-toast"; -import { BsFileTextFill, BsFiletypeCsv, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng } from "react-icons/bs"; +import { BsFileTextFill, BsFiletypeCsv, BsFiletypeDocx, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng, BsFiletypePptx, BsFiletypeXlsx } from "react-icons/bs"; import { FaTrash } from "react-icons/fa6"; +import { ImDownload3 } from "react-icons/im"; import { useWibuRealtime } from "wibu-realtime"; import { funDeleteFileTask, funGetTaskDivisionById } from "../lib/api_task"; import { IDataFileTaskDivision } from "../lib/type_task"; -import { globalIsMemberDivision } from "@/module/division_new"; export default function ListFileDetailTask() { const roleLogin = useHookstate(globalRole) @@ -111,6 +112,28 @@ export default function ListFileDetailTask() { } }, [dataRealTime]) + const onDownload = async () => { + try { + const fileUrl = `https://wibu-storage.wibudev.com/api/files/${idDataStorage}`; + const response = await fetch(fileUrl); + const blob = await response.blob(); + + // Create a link element, use Blob URL + const link = document.createElement("a"); + const url = window.URL.createObjectURL(blob); + link.href = url; + link.download = `${nameData}`; // Nama file yang akan diunduh + document.body.appendChild(link); + link.click(); + + // Cleanup + window.URL.revokeObjectURL(url); + document.body.removeChild(link); + } catch (error) { + alert(error); + } + }; + return ( File @@ -159,13 +182,12 @@ export default function ListFileDetailTask() {
{item.extension == "pdf" && } {item.extension == "csv" && } - {item.extension == "png" && } - {item.extension == "jpg" && } - {item.extension == "jpeg" && } - {item.extension == "PNG" && } - {item.extension == "JPG" && } - {item.extension == "JPEG" && } + {(item.extension == "png" || item.extension == "PNG") && } + {(item.extension == "jpg" || item.extension == "jpeg" || item.extension == "JPG" || item.extension == "JPEG") && } {item.extension == "heic" && } + {(item.extension == "doc" || item.extension == "docx") && } + {(item.extension == "xls" || item.extension == "xlsx") && } + {(item.extension == "ppt" || item.extension == "pptx") && }
@@ -185,15 +207,24 @@ export default function ListFileDetailTask() { {nameData}} onClose={() => setOpenDrawer(false)}> - - { setOpenModalView(true) }} justify={'center'} align={'center'} direction={'column'} > + + { + (isExtension != "doc" && isExtension != "docx" && isExtension != "xls" && isExtension != "xlsx" && isExtension != "ppt" && isExtension != "pptx") && + { setOpenModalView(true) }} justify={'center'} align={'center'} direction={'column'} > + + + + + Lihat file + + + } + { onDownload() }} justify={'center'} align={'center'} direction={'column'} > - + - Lihat file + Download { diff --git a/src/module/task/ui/results_file.tsx b/src/module/task/ui/results_file.tsx index 4bc6f5c..ebfbc62 100644 --- a/src/module/task/ui/results_file.tsx +++ b/src/module/task/ui/results_file.tsx @@ -1,9 +1,38 @@ import { Box, Center, Grid, Group, Text } from '@mantine/core'; -import React from 'react'; -import { BsFiletypeCsv, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng } from 'react-icons/bs'; +import React, { useState } from 'react'; +import { BsFiletypeCsv, BsFiletypeDocx, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng, BsFiletypePptx, BsFiletypeXlsx } from 'react-icons/bs'; import { IListFileTask } from '../lib/type_task'; +import { useShallowEffect } from '@mantine/hooks'; export default function ResultsFile({ name, extension }: IListFileTask) { + const [fixed, setFixed] = useState(extension) + + function cekExtension() { + let jadi = extension + if (extension == "msword") { + jadi = "doc" + } else if (extension == "vnd.openxmlformats-officedocument.wordprocessingml.document") { + jadi = "docx" + } else if (extension == "vnd.ms-excel") { + jadi = "xls" + } else if (extension == "vnd.openxmlformats-officedocument.spreadsheetml.sheet") { + jadi = "xlsx" + } else if (extension == "vnd.ms-powerpoint") { + jadi = "ppt" + } else if (extension == "vnd.openxmlformats-officedocument.presentationml.presentation") { + jadi = "pptx" + } else { + jadi = extension + } + + setFixed(jadi) + } + + + useShallowEffect(() => { + cekExtension() + }, []); + return (
- {extension == "pdf" && } - {extension == "csv" && } - {extension == "png" && } - {extension == "jpg" && } - {extension == "jpeg" && } - {extension == "PNG" && } - {extension == "JPG" && } - {extension == "JPEG" && } - {extension == "heic" && } + {fixed == "pdf" && } + {fixed == "csv" && } + {fixed == "png" && } + {fixed == "jpg" || fixed == "jpeg" && } + {fixed == "heic" && } + {fixed == "doc" || fixed == "docx" && } + {fixed == "xls" || fixed == "xlsx" && } + {fixed == "ppt" || fixed == "pptx" && }