From ded16f4a5b13a626e36f3d06e056c1400329399d Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 21 May 2026 19:21:11 +0200 Subject: [PATCH] feat(uat-batch-24): click-to-preview on EntityFolderView + HubRootView Files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completes the click-to-preview sweep across all file-row surfaces. The filename cells in entity-folder-view.tsx (entity-scoped Files panel) and hub-root-view.tsx (Documents Hub root "Recent files") were the last two non-clickable surfaces — both now wrap the filename in a button that opens FilePreviewDialog directly, matching the FileGrid and DocumentList pattern shipped in 52342ee. HubRootFile shape extended to include mimeType (already returned by the /api/v1/files endpoint via the buildListQuery passthrough) so the preview dialog can branch on image vs PDF without a second request. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../documents/entity-folder-view.tsx | 25 +++++++++++++++- src/components/documents/hub-root-view.tsx | 30 ++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/components/documents/entity-folder-view.tsx b/src/components/documents/entity-folder-view.tsx index 06ceea24..81600f60 100644 --- a/src/components/documents/entity-folder-view.tsx +++ b/src/components/documents/entity-folder-view.tsx @@ -7,6 +7,7 @@ import { ClipboardSignature, FileText, Eye } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { AggregatedSection } from './aggregated-section'; import { SigningDetailsDialog } from './signing-details-dialog'; +import { FilePreviewDialog } from '@/components/files/file-preview-dialog'; import { useAggregatedFiles, useAggregatedWorkflows } from '@/hooks/use-aggregated-listing'; import { StatusPill, type StatusPillStatus } from '@/components/ui/status-pill'; import type { @@ -35,6 +36,11 @@ function mapWorkflowStatus(status: string): StatusPillStatus { export function EntityFolderView({ portSlug, entityType, entityId }: Props) { const [detailsId, setDetailsId] = useState(null); + const [previewFile, setPreviewFile] = useState<{ + id: string; + name: string; + mimeType: string | null; + } | null>(null); // Hook data is the bare AggregatedGroup[] array (hooks unwrap the API envelope). const { data: workflowGroups = [], isLoading: workflowsLoading } = useAggregatedWorkflows( @@ -76,7 +82,14 @@ export function EntityFolderView({ portSlug, entityType, entityId }: Props) { const signedFromDocumentId = f.signedFromDocumentId; return (
- {f.filename} +
{new Date(f.createdAt).toLocaleDateString('en-GB')} {signedFromDocumentId ? ( @@ -101,6 +114,16 @@ export function EntityFolderView({ portSlug, entityType, entityId }: Props) { open={Boolean(detailsId)} onOpenChange={(open) => !open && setDetailsId(null)} /> + + { + if (!open) setPreviewFile(null); + }} + fileId={previewFile?.id} + fileName={previewFile?.name} + mimeType={previewFile?.mimeType ?? undefined} + />
); } diff --git a/src/components/documents/hub-root-view.tsx b/src/components/documents/hub-root-view.tsx index 9bb3c473..85837e70 100644 --- a/src/components/documents/hub-root-view.tsx +++ b/src/components/documents/hub-root-view.tsx @@ -1,10 +1,12 @@ 'use client'; +import { useState } from 'react'; import Link from 'next/link'; import { FileText, ClipboardSignature } from 'lucide-react'; import { usePaginatedQuery } from '@/hooks/use-paginated-query'; import { StatusPill, type StatusPillStatus } from '@/components/ui/status-pill'; +import { FilePreviewDialog } from '@/components/files/file-preview-dialog'; interface HubRootDoc { id: string; @@ -17,6 +19,7 @@ interface HubRootDoc { interface HubRootFile { id: string; filename: string; + mimeType: string | null; createdAt: string; } @@ -36,6 +39,12 @@ const STATUS_PILL_MAP: Record = { }; export function HubRootView({ portSlug }: Props) { + const [previewFile, setPreviewFile] = useState<{ + id: string; + name: string; + mimeType: string | null; + } | null>(null); + const { data: workflows, isLoading: workflowsLoading } = usePaginatedQuery({ queryKey: ['documents', 'hub-root', 'workflows'], endpoint: '/api/v1/documents?tab=in_progress', @@ -87,7 +96,16 @@ export function HubRootView({ portSlug }: Props) {
    {filesData.map((f) => (
  • - {f.filename} + {new Date(f.createdAt).toLocaleDateString('en-GB')} @@ -96,6 +114,16 @@ export function HubRootView({ portSlug }: Props) {
)} + + { + if (!open) setPreviewFile(null); + }} + fileId={previewFile?.id} + fileName={previewFile?.name} + mimeType={previewFile?.mimeType ?? undefined} + />
); }