diff --git a/ui/src/components/IssueDocumentsSection.tsx b/ui/src/components/IssueDocumentsSection.tsx index 851518b8..d6aa356f 100644 --- a/ui/src/components/IssueDocumentsSection.tsx +++ b/ui/src/components/IssueDocumentsSection.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { Issue } from "@paperclipai/shared"; import { issuesApi } from "../api/issues"; @@ -46,11 +46,13 @@ export function IssueDocumentsSection({ canDeleteDocuments, mentions, imageUploadHandler, + extraActions, }: { issue: Issue; canDeleteDocuments: boolean; mentions?: MentionOption[]; imageUploadHandler?: (file: File) => Promise; + extraActions?: ReactNode; }) { const queryClient = useQueryClient(); const [confirmDeleteKey, setConfirmDeleteKey] = useState(null); @@ -106,6 +108,7 @@ export function IssueDocumentsSection({ }, [documents]); const hasRealPlan = sortedDocuments.some((doc) => doc.key === "plan"); + const isEmpty = sortedDocuments.length === 0 && !issue.legacyPlanDocument; const newDocumentKeyError = draft?.isNew && draft.key.trim().length > 0 && !DOCUMENT_KEY_PATTERN.test(draft.key.trim()) ? "Use lowercase letters, numbers, -, or _, and start with a letter or number." @@ -302,13 +305,26 @@ export function IssueDocumentsSection({ return (
-
-

Documents

- -
+ {isEmpty && !draft?.isNew ? ( +
+ {extraActions} + +
+ ) : ( +
+

Documents

+
+ {extraActions} + +
+
+ )} {error &&

{error}

} @@ -367,10 +383,6 @@ export function IssueDocumentsSection({
)} - {sortedDocuments.length === 0 && !issue.legacyPlanDocument ? ( -

No documents yet.

- ) : null} - {!hasRealPlan && issue.legacyPlanDocument ? (
diff --git a/ui/src/pages/IssueDetail.tsx b/ui/src/pages/IssueDetail.tsx index e076d383..5087bb73 100644 --- a/ui/src/pages/IssueDetail.tsx +++ b/ui/src/pages/IssueDetail.tsx @@ -606,6 +606,38 @@ export function IssueDetail() { }; const isImageAttachment = (attachment: IssueAttachment) => attachment.contentType.startsWith("image/"); + const attachmentList = attachments ?? []; + const hasAttachments = attachmentList.length > 0; + const attachmentUploadButton = ( +
+ + +
+ ); return (
@@ -774,9 +806,11 @@ export function IssueDetail() { const attachment = await uploadAttachment.mutateAsync(file); return attachment.contentPath; }} + extraActions={!hasAttachments ? attachmentUploadButton : undefined} /> -

Attachments

-
- - -
+ {attachmentUploadButton}
{attachmentError && (

{attachmentError}

)} - {(!attachments || attachments.length === 0) ? ( -

No attachments yet.

- ) : ( -
- {attachments.map((attachment) => ( -
-
- - {attachment.originalFilename ?? attachment.id} - - -
-

- {attachment.contentType} · {(attachment.byteSize / 1024).toFixed(1)} KB -

- {isImageAttachment(attachment) && ( - - {attachment.originalFilename - - )} +
+ {attachmentList.map((attachment) => ( +
+
+ + {attachment.originalFilename ?? attachment.id} + +
- ))} -
- )} -
+

+ {attachment.contentType} · {(attachment.byteSize / 1024).toFixed(1)} KB +

+ {isImageAttachment(attachment) && ( + + {attachment.originalFilename + + )} +
+ ))} +
+
+ ) : null}