Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 27 additions & 15 deletions components/datarooms/dataroom-document-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ import { useTheme } from "next-themes";
import { toast } from "sonner";
import { mutate } from "swr";

import { MoveToFolderModal } from "@/components/documents/move-folder-modal";
import BarChart from "@/components/shared/icons/bar-chart";
import Check from "@/components/shared/icons/check";
import Copy from "@/components/shared/icons/copy";
import NotionIcon from "@/components/shared/icons/notion";
import { Button } from "@/components/ui/button";
import {
Expand All @@ -27,20 +24,21 @@ import {

import { type DataroomFolderDocument } from "@/lib/swr/use-dataroom";
import { type DocumentWithLinksAndLinkCountAndViewCount } from "@/lib/types";
import { nFormatter, timeAgo } from "@/lib/utils";
import { useCopyToClipboard } from "@/lib/utils/use-copy-to-clipboard";
import { cn, nFormatter, timeAgo } from "@/lib/utils";

import { MoveToDataroomFolderModal } from "./move-dataroom-folder-modal";

type DocumentsCardProps = {
document: DataroomFolderDocument;
teamInfo: TeamContextType | null;
dataroomId: string;
isDragging?: boolean;
};
export default function DataroomDocumentCard({
document: dataroomDocument,
teamInfo,
dataroomId,
isDragging,
}: DocumentsCardProps) {
const { theme, systemTheme } = useTheme();
const isLight =
Expand Down Expand Up @@ -147,9 +145,24 @@ export default function DataroomDocumentCard({
}
};

const handleCardClick = (e: React.MouseEvent) => {
if (isDragging) {
e.preventDefault();
e.stopPropagation();
return;
}
router.push(`/documents/${dataroomDocument.document.id}`);
};

return (
<>
<li className="group/row relative flex items-center justify-between rounded-lg border-0 p-3 ring-1 ring-gray-200 transition-all hover:bg-secondary hover:ring-gray-300 dark:bg-secondary dark:ring-gray-700 hover:dark:ring-gray-500 sm:p-4">
<div
onClick={handleCardClick}
className={cn(
"group/row relative flex items-center justify-between rounded-lg border-0 bg-white p-3 ring-1 ring-gray-200 transition-all hover:bg-secondary hover:ring-gray-300 dark:bg-secondary dark:ring-gray-700 hover:dark:ring-gray-500 sm:p-4",
isDragging ? "cursor-grabbing" : "cursor-pointer",
)}
>
<div className="flex min-w-0 shrink items-center space-x-2 sm:space-x-4">
<div className="mx-0.5 flex w-8 items-center justify-center text-center sm:mx-1">
{dataroomDocument.document.type === "notion" ? (
Expand All @@ -167,13 +180,7 @@ export default function DataroomDocumentCard({
<div className="flex-col">
<div className="flex items-center">
<h2 className="min-w-0 max-w-[150px] truncate text-sm font-semibold leading-6 text-foreground sm:max-w-md">
<Link
href={`/documents/${dataroomDocument.document.id}`}
className="w-full truncate"
>
<span>{dataroomDocument.document.name}</span>
<span className="absolute inset-0" />
</Link>
{dataroomDocument.document.name}
</h2>
</div>
<div className="mt-1 flex items-center space-x-1 text-xs leading-5 text-muted-foreground">
Expand Down Expand Up @@ -216,7 +223,12 @@ export default function DataroomDocumentCard({
</DropdownMenuTrigger>
<DropdownMenuContent align="end" ref={dropdownRef}>
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem onClick={() => setMoveFolderOpen(true)}>
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
setMoveFolderOpen(true);
}}
>
<FolderInputIcon className="mr-2 h-4 w-4" />
Move to folder
</DropdownMenuItem>
Expand All @@ -239,7 +251,7 @@ export default function DataroomDocumentCard({
</DropdownMenuContent>
</DropdownMenu>
</div>
</li>
</div>
{moveFolderOpen ? (
<MoveToDataroomFolderModal
open={moveFolderOpen}
Expand Down
111 changes: 111 additions & 0 deletions components/datarooms/dataroom-items-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { useState } from "react";

import { TeamContextType } from "@/context/team-context";

import { EmptyDocuments } from "@/components/documents/empty-document";
import FolderCard from "@/components/documents/folder-card";
import { UploadNotificationDrawer } from "@/components/upload-notification";
import UploadZone from "@/components/upload-zone";

import {
DataroomFolderDocument,
DataroomFolderWithCount,
} from "@/lib/swr/use-dataroom";

import DataroomDocumentCard from "./dataroom-document-card";

type FolderOrDocument =
| (DataroomFolderWithCount & { itemType: "folder" })
| (DataroomFolderDocument & { itemType: "document" });

export function DataroomItemsList({
mixedItems,
teamInfo,
folderPathName,
dataroomId,
}: {
mixedItems: FolderOrDocument[] | [];
teamInfo: TeamContextType | null;
folderPathName?: string[];
dataroomId: string;
}) {
const [uploads, setUploads] = useState<
{ fileName: string; progress: number; documentId?: string }[]
>([]);
const [rejectedFiles, setRejectedFiles] = useState<
{ fileName: string; message: string }[]
>([]);

const [showDrawer, setShowDrawer] = useState(false);

const renderItem = (item: FolderOrDocument) => {
const itemId = `${item.itemType}-${item.id}`;

return (
<>
{item.itemType === "folder" ? (
<FolderCard
key={itemId}
folder={item}
teamInfo={teamInfo}
isDataroom={!!dataroomId}
dataroomId={dataroomId}
/>
) : (
<DataroomDocumentCard
key={itemId}
document={item as DataroomFolderDocument}
teamInfo={teamInfo}
dataroomId={dataroomId}
/>
)}
</>
);
};

return (
<>
<UploadZone
folderPathName={folderPathName?.join("/")}
onUploadStart={(newUploads) => {
setUploads(newUploads);
setShowDrawer(true);
}}
onUploadProgress={(index, progress, documentId) => {
setUploads((prevUploads) =>
prevUploads.map((upload, i) =>
i === index ? { ...upload, progress, documentId } : upload,
),
);
}}
onUploadRejected={(rejected) => {
setRejectedFiles(rejected);
setShowDrawer(true);
}}
setUploads={setUploads}
setRejectedFiles={setRejectedFiles}
dataroomId={dataroomId}
>
<ul role="list" className="space-y-4">
{mixedItems.map(renderItem)}
</ul>

{mixedItems.length === 0 && (
<div className="flex h-full justify-center">
<EmptyDocuments />
</div>
)}
</UploadZone>
{showDrawer ? (
<UploadNotificationDrawer
open={showDrawer}
onOpenChange={setShowDrawer}
uploads={uploads}
setUploads={setUploads}
rejectedFiles={rejectedFiles}
setRejectedFiles={setRejectedFiles}
/>
) : null}
</>
);
}
48 changes: 48 additions & 0 deletions components/datarooms/sortable/sortable-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react";

import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

export type ItemCategory = "folder" | "document";

interface SortableItemProps {
id: string;
category: ItemCategory;
children: React.ReactElement;
}

export const SortableItem: React.FC<SortableItemProps> = ({
id,
category,
children,
}) => {
const { attributes, listeners, setNodeRef, transform, isDragging } =
useSortable({
id: id,
data: {
category: category,
id: id.replace(category, ""),
},
});

const style = {
transform: CSS.Transform.toString(transform),
opacity: isDragging ? 0.5 : 1,
};

const childWithProps = React.cloneElement(children, {
isDragging,
});

return (
<li
ref={setNodeRef}
style={style}
{...attributes}
{...listeners}
className="cursor-move *:pointer-events-none"
>
{childWithProps}
</li>
);
};
Loading