feat(docs-ui): shared FileIcon + signed-state pill on EntityFolderView rows
- Extract FileIcon mapping to `src/components/files/file-icon.tsx` (single source of truth for mime→icon+colour palette; was previously inline in FileGrid only). - EntityFolderView file rows now render the type-specific icon (PDF/red, Image/blue, Sheet/green, Video/purple) instead of a generic FileText — multi-deal clients become scannable at a glance. - Add an inline "Signed" pill on rows where signedFromDocumentId is set so reps can distinguish a signed-from-workflow copy from a vanilla upload without hovering for "View signing details". - Tighter hover treatment (row picks up a subtle bg on hover) for affordance. - FileGrid refactored to consume the shared FileIcon so both surfaces stay in lockstep on future mime additions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import { ClipboardSignature, FileText, Eye, Download } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { AggregatedSection } from './aggregated-section';
|
||||
import { SigningDetailsDialog } from './signing-details-dialog';
|
||||
import { FileIcon } from '@/components/files/file-icon';
|
||||
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';
|
||||
@@ -95,15 +96,23 @@ export function EntityFolderView({ portSlug, entityType, entityId }: Props) {
|
||||
renderRow={(f: AggregatedFile, _group: AggregatedGroup<AggregatedFile>) => {
|
||||
const signedFromDocumentId = f.signedFromDocumentId;
|
||||
return (
|
||||
<div className="group flex items-center justify-between gap-3 text-sm">
|
||||
<div className="group flex items-center justify-between gap-3 rounded-sm px-1 py-0.5 text-sm hover:bg-accent/30">
|
||||
<button
|
||||
type="button"
|
||||
className="flex min-w-0 flex-1 items-center gap-2 text-left hover:text-brand focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand/40 rounded-sm"
|
||||
onClick={() => setPreviewFile({ id: f.id, name: f.filename, mimeType: f.mimeType })}
|
||||
aria-label={`Preview ${f.filename}`}
|
||||
>
|
||||
<FileText className="h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden />
|
||||
<FileIcon mimeType={f.mimeType} />
|
||||
<span className="truncate group-hover:underline">{f.filename}</span>
|
||||
{signedFromDocumentId ? (
|
||||
<span
|
||||
className="ml-1 inline-flex shrink-0 items-center rounded-full bg-emerald-50 px-1.5 py-px text-[10px] font-medium text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-300"
|
||||
title="This file is a signed copy of a Documenso/uploaded workflow"
|
||||
>
|
||||
Signed
|
||||
</span>
|
||||
) : null}
|
||||
{f.interestBerthLabel && f.interestId ? (
|
||||
<Link
|
||||
href={`/${portSlug}/interests/${f.interestId}`}
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
Download,
|
||||
FileText,
|
||||
Film,
|
||||
Image,
|
||||
MoreHorizontal,
|
||||
Pencil,
|
||||
Sheet,
|
||||
Trash2,
|
||||
} from 'lucide-react';
|
||||
import { Download, FileText, MoreHorizontal, Pencil, Trash2 } from 'lucide-react';
|
||||
import { format } from 'date-fns';
|
||||
|
||||
import { FileIcon as SharedFileIcon } from './file-icon';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -56,19 +49,7 @@ function formatBytes(bytes: string | null): string {
|
||||
}
|
||||
|
||||
function FileIcon({ mimeType }: { mimeType: string | null }) {
|
||||
if (!mimeType) return <FileText className="h-8 w-8 text-muted-foreground" />;
|
||||
// eslint-disable-next-line jsx-a11y/alt-text
|
||||
if (mimeType.startsWith('image/')) return <Image className="h-8 w-8 text-blue-500" />;
|
||||
if (mimeType === 'application/pdf') return <FileText className="h-8 w-8 text-red-500" />;
|
||||
if (
|
||||
mimeType === 'application/vnd.ms-excel' ||
|
||||
mimeType === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
|
||||
mimeType === 'text/csv'
|
||||
) {
|
||||
return <Sheet className="h-8 w-8 text-green-600" />;
|
||||
}
|
||||
if (mimeType.startsWith('video/')) return <Film className="h-8 w-8 text-purple-500" />;
|
||||
return <FileText className="h-8 w-8 text-muted-foreground" />;
|
||||
return <SharedFileIcon mimeType={mimeType} className="h-8 w-8" />;
|
||||
}
|
||||
|
||||
export function FileGrid({
|
||||
|
||||
Reference in New Issue
Block a user