Fix structured attachment rendering (#69)
* review: harden readonly git checks and lint verification * test: satisfy readonly reviewer sandbox typing * test: fix readonly reviewer sandbox assertions * test: remove impossible readonly sandbox guards * test: relax readonly sandbox assertions * test: cast readonly sandbox expectation shape * test: cast readonly sandbox expectation through unknown * Phase 0 — STEP_DONE/TASK_DONE split + owner-follow-up integration smoke * Add STEP_DONE guards, verdict storage, and stale delivery suppression * style: format paired stepdone telemetry files * Route STEP_DONE through reviewer * Add structured Discord attachments * style: format structured attachment test * Fix room thread bot output parity * Remove duplicate work item attachment migration from owner branch * Remove legacy dashboard rooms renderer * Extract dashboard parsed body renderer * Extract dashboard redaction helpers * Extract dashboard RoomCardV2 component * Include RoomCardV2 test in vitest suite * Extract dashboard RoomBoardV2 component * Extract dashboard EmptyState component * Extract dashboard InboxPanel component * Split dashboard InboxPanel card renderer * Extract dashboard TaskPanel component * Extract dashboard UsagePanel component * Fix dashboard room thread chunk rendering * Extract dashboard ServicePanel component * Render dashboard live progress markdown * Extract dashboard SettingsPanel component * Fix structured attachment rendering
This commit is contained in:
38
apps/dashboard/src/RoomAttachmentGallery.tsx
Normal file
38
apps/dashboard/src/RoomAttachmentGallery.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { RoomThreadEntry } from './roomThread';
|
||||
|
||||
type RoomAttachment = NonNullable<RoomThreadEntry['attachments']>[number];
|
||||
|
||||
function attachmentDisplayName(attachment: RoomAttachment): string {
|
||||
if (attachment.name) return attachment.name;
|
||||
const segments = attachment.path.split(/[\\/]/);
|
||||
return segments.at(-1) || 'attachment';
|
||||
}
|
||||
|
||||
function attachmentUrl(attachment: RoomAttachment): string {
|
||||
return `/api/attachments?path=${encodeURIComponent(attachment.path)}`;
|
||||
}
|
||||
|
||||
export function RoomAttachmentGallery({
|
||||
attachments,
|
||||
}: {
|
||||
attachments?: RoomThreadEntry['attachments'];
|
||||
}) {
|
||||
if (!attachments || attachments.length === 0) return null;
|
||||
|
||||
return (
|
||||
<ul className="room-attachments">
|
||||
{attachments.map((attachment) => {
|
||||
const name = attachmentDisplayName(attachment);
|
||||
const url = attachmentUrl(attachment);
|
||||
return (
|
||||
<li className="room-attachment" key={`${attachment.path}:${name}`}>
|
||||
<a href={url} rel="noreferrer" target="_blank">
|
||||
<img alt={name} loading="lazy" src={url} />
|
||||
<span>{name}</span>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user