Skip to content

Commit

Permalink
feat: be able to download multiple minio files
Browse files Browse the repository at this point in the history
  • Loading branch information
prosfus committed Jan 4, 2025
1 parent dca2d95 commit 95268f1
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 11 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"clsx": "^2.1.1",
"file-type": "^19.6.0",
"framer-motion": "^11.3.31",
"jszip": "^3.10.1",
"lucide-react": "^0.411.0",
"next-themes": "^0.3.0",
"react": "^18.3.1",
Expand Down
114 changes: 103 additions & 11 deletions src/pages/ui/minio/components/BucketContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@ import { _Object, CommonPrefix } from "@aws-sdk/client-s3";
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import GenericTable from "@/components/Table"; // Importar GenericTable
import { AlertCircle, Eye, Folder, Trash } from "lucide-react";
import {
AlertCircle,
Eye,
Folder,
Trash,
Download,
DownloadIcon,
} from "lucide-react";
import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
import OscarColors from "@/styles";
import { motion, AnimatePresence } from "framer-motion";
import useSelectedBucket from "../../hooks/useSelectedBucket";
import { Button } from "@/components/ui/button";
import DeleteDialog from "@/components/DeleteDialog";
import FilePreviewModal from "./FilePreview";
import JSZip from "jszip";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";

export type BucketItem =
| {
Expand All @@ -29,7 +42,8 @@ export type BucketItem =
export default function BucketContent() {
const { name: bucketName, path } = useSelectedBucket();

const { getBucketItems, buckets, uploadFile, deleteFile } = useMinio();
const { getBucketItems, buckets, uploadFile, deleteFile, getFileUrl } =
useMinio();

const [items, setItems] = useState<BucketItem[]>([]);

Expand Down Expand Up @@ -87,6 +101,48 @@ export default function BucketContent() {

const [itemsToDelete, setItemsToDelete] = useState<BucketItem[]>([]);

const handleDownloadFile = async (item: BucketItem) => {
if (item.Type === "file") {
try {
const url = await getFileUrl(item.BucketName, item.Key.Key!);
if (url) {
const a = document.createElement("a");
a.href = url;
a.download = item.Name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
} catch (error) {
console.error("Error al descargar el archivo:", error);
}
}
};

const handleBulkDownload = async (items: BucketItem[]) => {
const zip = new JSZip();

for (const item of items) {
if (item.Type === "file") {
const url = await getFileUrl(item.BucketName, item.Key.Key!);
if (url) {
const response = await fetch(url);
const blob = await response.blob();
zip.file(item.Name, blob);
}
}
}

zip.generateAsync({ type: "blob" }).then((content) => {
const a = document.createElement("a");
a.href = URL.createObjectURL(content);
a.download = `${bucketName}_files.zip`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
};

return (
<>
{previewFile && (
Expand Down Expand Up @@ -202,15 +258,24 @@ export default function BucketContent() {
return (
<>
{item.Type === "file" && (
<Button
variant="link"
size="icon"
onClick={() => {
setPreviewFile(item);
}}
>
<Eye color={OscarColors.Blue} />
</Button>
<>
<Button
variant="link"
size="icon"
onClick={() => {
setPreviewFile(item);
}}
>
<Eye color={OscarColors.Blue} />
</Button>
<Button
variant="link"
size="icon"
onClick={() => handleDownloadFile(item)}
>
<Download />
</Button>
</>
)}
<Button
variant={"ghost"}
Expand All @@ -224,6 +289,33 @@ export default function BucketContent() {
},
},
]}
bulkActions={[
{
button: (items) => {
return (
<Tooltip>
<TooltipTrigger asChild>
<div>
<Button
className="mt-[2px]"
onClick={() => handleBulkDownload(items)}
disabled={items.some(
(item) => item.Type === "folder"
)}
>
<DownloadIcon className="w-4 h-4 mr-2" />
Download
</Button>
</div>
</TooltipTrigger>
{items.some((item) => item.Type === "folder") && (
<TooltipContent>Cannot download folders</TooltipContent>
)}
</Tooltip>
);
},
},
]}
/>
</motion.div>
</>
Expand Down

0 comments on commit 95268f1

Please sign in to comment.