mirror of
https://github.com/hanzo-apps/dataroom.git
synced 2026-10-30 14:47:36 +00:00
Drop the dual-licensed `ee/` tree entirely. All features previously
locked behind the Hanzo Dataroom Commercial License are now part of the
AGPL-3.0 core and freely available — custom domains, branded viewing,
advanced analytics, watermarks, access controls, Q&A, AI vector stores,
workflows, SAML SSO, dataroom invitations, conversations, templates.
Layout changes:
* `ee/features/{ai,conversations,workflows,permissions,storage,templates,
dataroom-invitations,access-notifications,security,conversions}/` →
`features/<name>/` (AGPL).
* `ee/limits/` → `lib/billing/limits/` with every plan resolving to an
unlimited profile (no users/links/documents/domains/datarooms cap,
conversations and watermarks always on).
* `ee/stripe/` → `lib/billing/legacy/` (already a compat shim over
`@hanzoai/commerce`; renewal-reminder webhook is now a no-op).
* `ee/features/billing/cancellation/` deleted. Pause/unpause/cancel/
retention routes now compile against `lib/billing/cancellation.ts`
stubs that return 410 Gone; `isTeamPaused`/`isTeamPausedById` in
`lib/billing/paused.ts` always report active. `CancellationModal` is
a no-op shim in `components/billing/`.
* `app/(ee)/api/*` route group folded into `app/api/*` (SAML auth,
SCIM, AI chat, workflows, FAQ, link-upload).
Build: `npm run build` green.
248 lines
8.3 KiB
TypeScript
248 lines
8.3 KiB
TypeScript
import dynamic from "next/dynamic";
|
|
|
|
import { ViewerChatPanel } from "@/features/ai/components/viewer-chat-panel";
|
|
import {
|
|
ViewerChatLayout,
|
|
ViewerChatProvider,
|
|
} from "@/features/ai/components/viewer-chat-provider";
|
|
import { ViewerChatToggle } from "@/features/ai/components/viewer-chat-toggle";
|
|
import {
|
|
Brand,
|
|
DataroomBrand,
|
|
Document,
|
|
DocumentVersion,
|
|
} from "@prisma/client";
|
|
import { ExtendedRecordMap } from "notion-types";
|
|
|
|
import {
|
|
LinkWithDataroomDocument,
|
|
LinkWithDocument,
|
|
NotionTheme,
|
|
WatermarkConfig,
|
|
} from "@/lib/types";
|
|
import { useMediaQuery } from "@/lib/utils/use-media-query";
|
|
|
|
import { DEFAULT_DOCUMENT_VIEW_TYPE } from "@/components/view/document-view";
|
|
import { NotionPage } from "@/components/view/viewer/notion-page";
|
|
import PDFViewer from "@/components/view/viewer/pdf-default-viewer";
|
|
|
|
import { DEFAULT_DATAROOM_DOCUMENT_VIEW_TYPE } from "./dataroom/dataroom-document-view";
|
|
import LinkPreview from "./link-preview";
|
|
import { TNavData } from "./nav";
|
|
import AdvancedExcelViewer from "./viewer/advanced-excel-viewer";
|
|
import DownloadOnlyViewer from "./viewer/download-only-viewer";
|
|
import ImageViewer from "./viewer/image-viewer";
|
|
import PagesHorizontalViewer from "./viewer/pages-horizontal-viewer";
|
|
import PagesVerticalViewer from "./viewer/pages-vertical-viewer";
|
|
import VideoViewer from "./viewer/video-viewer";
|
|
|
|
const ExcelViewer = dynamic(
|
|
() => import("@/components/view/viewer/excel-viewer"),
|
|
{ ssr: false },
|
|
);
|
|
|
|
export type TViewDocumentData = Document & {
|
|
versions: DocumentVersion[];
|
|
};
|
|
|
|
const isDownloadAllowed = (
|
|
canDownload: boolean | undefined,
|
|
linkAllowDownload: boolean | undefined,
|
|
): boolean => {
|
|
if (canDownload === false) return false;
|
|
return !!linkAllowDownload;
|
|
};
|
|
|
|
export default function ViewData({
|
|
viewData,
|
|
link,
|
|
document,
|
|
notionData,
|
|
brand,
|
|
showPoweredByBanner,
|
|
showAccountCreationSlide,
|
|
useAdvancedExcelViewer,
|
|
viewerEmail,
|
|
dataroomId,
|
|
canDownload,
|
|
annotationsEnabled,
|
|
textSelectionEnabled,
|
|
}: {
|
|
viewData: DEFAULT_DOCUMENT_VIEW_TYPE | DEFAULT_DATAROOM_DOCUMENT_VIEW_TYPE;
|
|
link: LinkWithDocument | LinkWithDataroomDocument;
|
|
document: TViewDocumentData;
|
|
notionData?: {
|
|
rootNotionPageId: string | null;
|
|
recordMap: ExtendedRecordMap | null;
|
|
theme: NotionTheme | null;
|
|
};
|
|
brand?: Partial<Brand> | Partial<DataroomBrand> | null;
|
|
showPoweredByBanner?: boolean;
|
|
showAccountCreationSlide?: boolean;
|
|
useAdvancedExcelViewer?: boolean;
|
|
viewerEmail?: string;
|
|
dataroomId?: string;
|
|
canDownload?: boolean;
|
|
annotationsEnabled?: boolean;
|
|
textSelectionEnabled?: boolean;
|
|
}) {
|
|
const { isMobile } = useMediaQuery();
|
|
|
|
const navData: TNavData = {
|
|
viewId: viewData.viewId,
|
|
isPreview: viewData.isPreview,
|
|
linkId: link.id,
|
|
brand: brand,
|
|
viewerId: "viewerId" in viewData ? viewData.viewerId : undefined,
|
|
isMobile: isMobile,
|
|
isDataroom: !!dataroomId,
|
|
documentId: document.id,
|
|
dataroomId: dataroomId,
|
|
conversationsEnabled:
|
|
!!dataroomId &&
|
|
("conversationsEnabled" in viewData
|
|
? viewData.conversationsEnabled
|
|
: false),
|
|
allowDownload:
|
|
document.downloadOnly ||
|
|
isDownloadAllowed(canDownload, link.allowDownload ?? false),
|
|
isTeamMember: viewData.isTeamMember,
|
|
annotationsFeatureEnabled: annotationsEnabled,
|
|
};
|
|
|
|
// Check if agents are enabled (returned from views API after access is granted)
|
|
const agentsEnabled =
|
|
"agentsEnabled" in viewData ? viewData.agentsEnabled : false;
|
|
|
|
// Determine dataroom name if applicable
|
|
const dataroomName =
|
|
dataroomId && "dataroomName" in viewData
|
|
? viewData.dataroomName
|
|
: undefined;
|
|
|
|
return (
|
|
<ViewerChatProvider
|
|
enabled={agentsEnabled}
|
|
documentId={document.id}
|
|
documentName={document.name}
|
|
dataroomId={dataroomId}
|
|
dataroomName={dataroomName}
|
|
linkId={link.id}
|
|
viewId={viewData.viewId}
|
|
viewerId={"viewerId" in viewData ? viewData.viewerId : undefined}
|
|
>
|
|
<ViewerChatLayout>
|
|
{notionData?.recordMap ? (
|
|
<NotionPage
|
|
recordMap={notionData.recordMap}
|
|
versionNumber={document.versions[0].versionNumber}
|
|
theme={notionData.theme}
|
|
screenshotProtectionEnabled={link.enableScreenshotProtection!}
|
|
textSelectionEnabled={textSelectionEnabled ?? false}
|
|
navData={navData}
|
|
/>
|
|
) : viewData.fileType === "link" ? (
|
|
<LinkPreview
|
|
linkUrl={viewData.file || document.versions[0]?.file || ""}
|
|
linkName={document.name}
|
|
versionNumber={document.versions[0]?.versionNumber || 1}
|
|
navData={navData}
|
|
/>
|
|
) : document.downloadOnly ? (
|
|
<DownloadOnlyViewer
|
|
versionNumber={document.versions[0].versionNumber}
|
|
documentName={document.name}
|
|
navData={navData}
|
|
/>
|
|
) : viewData.fileType === "sheet" && viewData.sheetData ? (
|
|
<ExcelViewer
|
|
versionNumber={document.versions[0].versionNumber}
|
|
sheetData={viewData.sheetData}
|
|
screenshotProtectionEnabled={link.enableScreenshotProtection!}
|
|
navData={navData}
|
|
/>
|
|
) : viewData.fileType === "sheet" && useAdvancedExcelViewer ? (
|
|
<AdvancedExcelViewer
|
|
file={viewData.file!}
|
|
versionNumber={document.versions[0].versionNumber}
|
|
navData={navData}
|
|
/>
|
|
) : viewData.fileType === "image" ? (
|
|
<ImageViewer
|
|
file={viewData.file!}
|
|
screenshotProtectionEnabled={link.enableScreenshotProtection!}
|
|
versionNumber={document.versions[0].versionNumber}
|
|
showPoweredByBanner={showPoweredByBanner}
|
|
viewerEmail={viewerEmail}
|
|
watermarkConfig={
|
|
link.enableWatermark
|
|
? (link.watermarkConfig as WatermarkConfig)
|
|
: null
|
|
}
|
|
ipAddress={viewData.ipAddress}
|
|
linkName={link.name ?? `Link #${link.id.slice(-5)}`}
|
|
navData={navData}
|
|
/>
|
|
) : viewData.pages && !document.versions[0].isVertical ? (
|
|
<PagesHorizontalViewer
|
|
pages={viewData.pages}
|
|
feedbackEnabled={link.enableFeedback!}
|
|
screenshotProtectionEnabled={link.enableScreenshotProtection!}
|
|
versionNumber={document.versions[0].versionNumber}
|
|
showPoweredByBanner={showPoweredByBanner}
|
|
showAccountCreationSlide={showAccountCreationSlide}
|
|
enableQuestion={link.enableQuestion}
|
|
feedback={link.feedback}
|
|
viewerEmail={viewerEmail}
|
|
watermarkConfig={
|
|
link.enableWatermark
|
|
? (link.watermarkConfig as WatermarkConfig)
|
|
: null
|
|
}
|
|
ipAddress={viewData.ipAddress}
|
|
linkName={link.name ?? `Link #${link.id.slice(-5)}`}
|
|
navData={navData}
|
|
/>
|
|
) : viewData.pages && document.versions[0].isVertical ? (
|
|
<PagesVerticalViewer
|
|
pages={viewData.pages}
|
|
feedbackEnabled={link.enableFeedback!}
|
|
screenshotProtectionEnabled={link.enableScreenshotProtection!}
|
|
versionNumber={document.versions[0].versionNumber}
|
|
showPoweredByBanner={showPoweredByBanner}
|
|
enableQuestion={link.enableQuestion}
|
|
feedback={link.feedback}
|
|
viewerEmail={viewerEmail}
|
|
watermarkConfig={
|
|
link.enableWatermark
|
|
? (link.watermarkConfig as WatermarkConfig)
|
|
: null
|
|
}
|
|
ipAddress={viewData.ipAddress}
|
|
linkName={link.name ?? `Link #${link.id.slice(-5)}`}
|
|
navData={navData}
|
|
/>
|
|
) : viewData.fileType === "video" ? (
|
|
<VideoViewer
|
|
file={viewData.file!}
|
|
screenshotProtectionEnabled={link.enableScreenshotProtection!}
|
|
versionNumber={document.versions[0].versionNumber}
|
|
navData={navData}
|
|
/>
|
|
) : (
|
|
<PDFViewer
|
|
file={viewData.file}
|
|
name={document.name}
|
|
versionNumber={document.versions[0].versionNumber}
|
|
navData={navData}
|
|
/>
|
|
)}
|
|
</ViewerChatLayout>
|
|
|
|
{/* AI Chat Components */}
|
|
<ViewerChatPanel />
|
|
<ViewerChatToggle />
|
|
</ViewerChatProvider>
|
|
);
|
|
}
|