Added ZIP upload support
X-Lovable-Edit-ID: edt-7c9c8e31-2960-4964-a296-a5b115e765bc Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
@@ -78,6 +78,7 @@
|
||||
"input-otp": "^1.4.2",
|
||||
"jspdf": "^4.2.1",
|
||||
"jspdf-autotable": "^5.0.7",
|
||||
"jszip": "^3.10.1",
|
||||
"lucide-react": "^0.575.0",
|
||||
"mailparser": "3.7.1",
|
||||
"papaparse": "^5.5.3",
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { ShareDocumentDialog } from "./share-document-dialog";
|
||||
import JSZip from "jszip";
|
||||
|
||||
const MAX_BYTES = 150 * 1024 * 1024;
|
||||
|
||||
@@ -135,6 +136,37 @@ export function CaseDocumentsTab({ caseId }: { caseId: string }) {
|
||||
const list = Array.from(files);
|
||||
let ok = 0;
|
||||
for (const f of list) {
|
||||
// Auto-expand ZIP files into folders/files
|
||||
if (/\.zip$/i.test(f.name) || f.type === "application/zip" || f.type === "application/x-zip-compressed") {
|
||||
try {
|
||||
const zip = await JSZip.loadAsync(await f.arrayBuffer());
|
||||
const zipRootName = sanitizeName(f.name.replace(/\.zip$/i, ""));
|
||||
const zipRoot = baseFolder ? `${baseFolder}/${zipRootName}` : zipRootName;
|
||||
await ensureFolder(zipRoot);
|
||||
const entries = Object.values(zip.files);
|
||||
for (const entry of entries) {
|
||||
// Skip macOS metadata noise
|
||||
if (/(^|\/)__MACOSX\//.test(entry.name) || /(^|\/)\.DS_Store$/.test(entry.name)) continue;
|
||||
const parts = entry.name.split("/").filter(Boolean);
|
||||
if (entry.dir) {
|
||||
const sub = parts.map(sanitizeName).join("/");
|
||||
if (sub) await ensureFolder(`${zipRoot}/${sub}`);
|
||||
continue;
|
||||
}
|
||||
const fname = parts.pop() || "file";
|
||||
const sub = parts.map(sanitizeName).join("/");
|
||||
const folderForFile = sub ? `${zipRoot}/${sub}` : zipRoot;
|
||||
if (sub) await ensureFolder(folderForFile);
|
||||
const blob = await entry.async("blob");
|
||||
const file = new File([blob], fname, { type: blob.type || "application/octet-stream" });
|
||||
const success = await uploadFile(file, folderForFile);
|
||||
if (success) ok++;
|
||||
}
|
||||
} catch (err: any) {
|
||||
toast.error(`${f.name}: could not unzip`, { description: err?.message });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// webkitRelativePath supports folder uploads when input has webkitdirectory
|
||||
const rel: string = (f as File & { webkitRelativePath?: string }).webkitRelativePath || "";
|
||||
let folderForFile = baseFolder;
|
||||
|
||||
@@ -1314,12 +1314,3 @@ const rootRouteChildren: RootRouteChildren = {
|
||||
export const routeTree = rootRouteImport
|
||||
._addFileChildren(rootRouteChildren)
|
||||
._addFileTypes<FileRouteTypes>()
|
||||
|
||||
import type { getRouter } from './router.tsx'
|
||||
import type { createStart } from '@tanstack/react-start'
|
||||
declare module '@tanstack/react-start' {
|
||||
interface Register {
|
||||
ssr: true
|
||||
router: Awaited<ReturnType<typeof getRouter>>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user