Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for new file types: .xls, .xlsx, .ods, .csv #443

Merged
merged 13 commits into from
May 28, 2024
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ node_modules/
.next/
.react-email/
.vercel/
.github/
.github/
*.min.js
*.min.css
4 changes: 3 additions & 1 deletion components/NotionPage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { useEffect, useRef, useState } from "react";
import React from "react";

import { Brand, DataroomBrand } from "@prisma/client";
import { ExtendedRecordMap } from "notion-types";
import { NotionRenderer } from "react-notion-x";
// core styles shared by all of react-notion-x (required)
import "react-notion-x/src/styles.css";

import { TDocumentData } from "./view/dataroom/dataroom-view";
import Nav from "./view/nav";

export const NotionPage = ({
Expand All @@ -29,7 +31,7 @@ export const NotionPage = ({
documentName?: string;
brand?: Partial<Brand> | Partial<DataroomBrand> | null;
dataroomId?: string;
setDocumentData?: (data: any) => void;
setDocumentData?: React.Dispatch<React.SetStateAction<TDocumentData | null>>;
}) => {
const [pageNumber, setPageNumber] = useState<number>(1); // start on first page
const [maxScrollPercentage, setMaxScrollPercentage] = useState<number>(0);
Expand Down
32 changes: 31 additions & 1 deletion components/document-upload.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useMemo, useState } from "react";

import { useTeam } from "@/context/team-context";
import {
Upload as ArrowUpTrayIcon,
File as DocumentIcon,
FileText as DocumentTextIcon,
FileSpreadsheetIcon,
Image as PhotoIcon,
Presentation as PresentationChartBarIcon,
} from "lucide-react";
Expand All @@ -15,6 +15,13 @@ import { usePlan } from "@/lib/swr/use-billing";
import { bytesToSize } from "@/lib/utils";
import { getPagesCount } from "@/lib/utils/get-page-number-count";

const fileSizeLimits: { [key: string]: number } = {
"application/vnd.ms-excel": 100, // 30 MB
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": 30, // 30 MB
"text/csv": 30, // 30 MB
"application/vnd.oasis.opendocument.spreadsheet": 30, // 30 MB
};

function fileIcon(fileType: string) {
switch (fileType) {
case "application/pdf":
Expand All @@ -29,6 +36,11 @@ function fileIcon(fileType: string) {
case "application/vnd.ms-powerpoint":
case "application/msword":
return <PresentationChartBarIcon className="mx-auto h-6 w-6" />;
case "application/vnd.ms-excel":
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
case "text/csv":
case "application/vnd.oasis.opendocument.spreadsheet":
return <FileSpreadsheetIcon className="mx-auto h-6 w-6" />;
default:
return <DocumentIcon className="mx-auto h-6 w-6" />;
}
Expand All @@ -46,11 +58,29 @@ export default function DocumentUpload({
const { getRootProps, getInputProps } = useDropzone({
accept: {
"application/pdf": [], // ".pdf"
"application/vnd.ms-excel": [], // ".xls"
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [], // ".xlsx"
"text/csv": [], // ".csv"
"application/vnd.oasis.opendocument.spreadsheet": [], // ".ods"
},
multiple: false,
maxSize: maxSize * 1024 * 1024, // 30 MB
onDropAccepted: (acceptedFiles) => {
const file = acceptedFiles[0];
const fileType = file.type;
const fileSizeLimit = fileSizeLimits[fileType] * 1024 * 1024;

if (file.size > fileSizeLimit) {
toast.error(
`File size too big for ${fileType} (max. ${fileSizeLimits[fileType]} MB)`,
);
return;
}

if (file.type !== "application/pdf") {
setCurrentFile(file);
return;
}
file
.arrayBuffer()
.then((buffer) => {
Expand Down
18 changes: 15 additions & 3 deletions components/documents/add-document-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from "@/lib/documents/create-document";
import { putFile } from "@/lib/files/put-file";
import { copyToClipboard } from "@/lib/utils";
import { getSupportedContentType } from "@/lib/utils/get-content-type";

export function AddDocumentModal({
newVersion,
Expand Down Expand Up @@ -69,6 +70,16 @@ export function AddDocumentModal({
try {
setUploading(true);

const contentType = getSupportedContentType(currentFile.type);

if (!contentType) {
setUploading(false);
toast.error(
"Unsupported file format. Please upload a PDF or Excel file.",
);
return;
}

const { type, data, numPages } = await putFile({
file: currentFile,
teamId,
Expand All @@ -78,6 +89,7 @@ export function AddDocumentModal({
name: currentFile.name,
key: data!,
storageType: type!,
contentType: contentType,
};
let response: Response | undefined;
// create a document or new version in the database
Expand Down Expand Up @@ -115,7 +127,7 @@ export function AddDocumentModal({
name: document.name,
numPages: document.numPages,
path: router.asPath,
type: "pdf",
type: document.type,
teamId: teamId,
dataroomId: dataroomId,
});
Expand All @@ -137,7 +149,7 @@ export function AddDocumentModal({
name: document.name,
numPages: document.numPages,
path: router.asPath,
type: "pdf",
type: document.type,
teamId: teamId,
});
analytics.capture("Link Added", {
Expand All @@ -157,7 +169,7 @@ export function AddDocumentModal({
name: document.name,
numPages: document.numPages,
path: router.asPath,
type: "pdf",
type: document.type,
newVersion: true,
teamId: teamId,
});
Expand Down
2 changes: 1 addition & 1 deletion components/links/links-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export default function LinksTable({
>
{/* Progress bar */}
{primaryVersion &&
primaryVersion.type !== "notion" &&
primaryVersion.type === "pdf" &&
!primaryVersion.hasPages ? (
<ProcessStatusBar
documentVersionId={primaryVersion.id}
Expand Down
48 changes: 11 additions & 37 deletions components/view/DataroomViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,35 @@
import Link from "next/link";
import { useRouter } from "next/router";

import { useEffect, useState } from "react";
import React from "react";

import { Brand, Dataroom, DataroomBrand, DataroomFolder } from "@prisma/client";
import { DataroomBrand, DataroomFolder } from "@prisma/client";
import * as SheetPrimitive from "@radix-ui/react-dialog";
import { MenuIcon, PanelLeftIcon, XIcon } from "lucide-react";
import { PanelLeftIcon, XIcon } from "lucide-react";

import { cn } from "@/lib/utils";

import { ViewFolderTree } from "../datarooms/folders";
import { ViewFolderTree } from "@/components/datarooms/folders";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "../ui/breadcrumb";
import { Button } from "../ui/button";
import { FileTree } from "../ui/nextra-filetree";
import { ScrollArea } from "../ui/scroll-area";
} from "@/components/ui/breadcrumb";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
Sheet,
SheetContent,
SheetOverlay,
SheetPortal,
SheetTrigger,
} from "../ui/sheet";
} from "@/components/ui/sheet";

import { cn } from "@/lib/utils";

import { TDocumentData } from "./dataroom/dataroom-view";
import DocumentCard from "./dataroom/document-card";
import FolderCard from "./dataroom/folder-card";
import DataroomNav from "./dataroom/nav-dataroom";
import Nav from "./nav";

type DataroomDocument = {
dataroomDocumentId: string;
Expand Down Expand Up @@ -64,17 +61,7 @@ export default function DataroomViewer({
setViewType: React.Dispatch<
React.SetStateAction<"DOCUMENT_VIEW" | "DATAROOM_VIEW">
>;
setDocumentData: React.Dispatch<
React.SetStateAction<{
id: string;
name: string;
hasPages: boolean;
documentType: "pdf" | "notion";
documentVersionId: string;
documentVersionNumber: number;
isVertical: boolean;
} | null>
>;
setDocumentData: React.Dispatch<React.SetStateAction<TDocumentData | null>>;
setDataroomVerified: React.Dispatch<React.SetStateAction<boolean>>;
}) {
const router = useRouter();
Expand Down Expand Up @@ -161,19 +148,6 @@ export default function DataroomViewer({
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
{/* <SheetContent
side="left"
className="w-[280px] sm:w-[300px] lg:hidden p-0 m-0 top-56"
>
<div className="h-full overflow-auto md:mx-5 lg:mx-7 xl:mx-10 mt-4 md:mt-5 lg:mt-8 mb-10 space-y-8 py-3 px-2">
<ViewFolderTree
folders={folders}
documents={documents}
setFolderId={setFolderId}
folderId={folderId}
/>
</div>
</SheetContent> */}
</Sheet>
</div>

Expand Down
4 changes: 3 additions & 1 deletion components/view/PagesViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Image from "next/image";
import { useRouter } from "next/router";

import { useEffect, useRef, useState } from "react";
import React from "react";

import BlankImg from "@/public/_static/blank.gif";
import { Brand, DataroomBrand } from "@prisma/client";
Expand All @@ -13,6 +14,7 @@ import LoadingSpinner from "@/components/ui/loading-spinner";
import { cn } from "@/lib/utils";

import { ScreenProtector } from "./ScreenProtection";
import { TDocumentData } from "./dataroom/dataroom-view";
import Nav from "./nav";
import { PoweredBy } from "./powered-by";
import Question from "./question";
Expand Down Expand Up @@ -50,7 +52,7 @@ export default function PagesViewer({
brand?: Partial<Brand> | Partial<DataroomBrand> | null;
documentName?: string;
dataroomId?: string;
setDocumentData?: (data: any) => void;
setDocumentData?: React.Dispatch<React.SetStateAction<TDocumentData | null>>;
showPoweredByBanner?: boolean;
enableQuestion?: boolean | null;
feedback?: {
Expand Down
4 changes: 3 additions & 1 deletion components/view/PagesViewerNew.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useRouter } from "next/router";

import { useEffect, useRef, useState } from "react";
import React from "react";

import { Brand, DataroomBrand } from "@prisma/client";
import {
Expand All @@ -19,6 +20,7 @@ import { toast } from "sonner";
import { cn } from "@/lib/utils";

import { ScreenProtector } from "./ScreenProtection";
import { TDocumentData } from "./dataroom/dataroom-view";
import Nav from "./nav";
import { PoweredBy } from "./powered-by";
import Question from "./question";
Expand Down Expand Up @@ -75,7 +77,7 @@ export default function PagesViewer({
brand?: Partial<Brand> | Partial<DataroomBrand> | null;
documentName?: string;
dataroomId?: string;
setDocumentData?: (data: any) => void;
setDocumentData?: React.Dispatch<React.SetStateAction<TDocumentData | null>>;
showPoweredByBanner?: boolean;
enableQuestion?: boolean | null;
feedback?: {
Expand Down
Loading