mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 02:44:50 +01:00
feat(ui): add download-all attachment action
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
2f302334f7
commit
e250a31982
3 files changed
+43
-1
No files matched your search
@@ -116,6 +116,32 @@ describe("IssueAttachmentsSection", () => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it("renders download-all beside upload with a direct archive link", async () => {
|
||||
const attachment = makeAttachment();
|
||||
|
||||
await act(async () => {
|
||||
root.render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<IssueAttachmentsSection
|
||||
attachments={[attachment]}
|
||||
downloadAllHref="/api/issues/issue-1/attachments/archive"
|
||||
uploadButton={<button type="button" aria-label="Upload attachment">Upload</button>}
|
||||
onImageClick={vi.fn()}
|
||||
/>
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
});
|
||||
await flushReact();
|
||||
|
||||
const downloadAll = container.querySelector<HTMLAnchorElement>(
|
||||
'a[aria-label="Download all attachments"]',
|
||||
);
|
||||
expect(downloadAll?.getAttribute("href")).toBe("/api/issues/issue-1/attachments/archive");
|
||||
expect(downloadAll?.getAttribute("title")).toBe("Download all attachments");
|
||||
expect(downloadAll?.getAttribute("target")).toBeNull();
|
||||
expect(container.querySelector('button[aria-label="Upload attachment"]')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders markdown attachments with the document markdown presentation", async () => {
|
||||
const attachment = makeAttachment({
|
||||
id: "markdown-attachment",
|
||||
|
||||
@@ -22,6 +22,7 @@ import { Card } from "@/components/ui/card";
|
||||
|
||||
interface IssueAttachmentsSectionProps {
|
||||
attachments: IssueAttachment[];
|
||||
downloadAllHref?: string;
|
||||
uploadButton?: ReactNode;
|
||||
error?: string | null;
|
||||
dragActive?: boolean;
|
||||
@@ -212,6 +213,7 @@ function GenericAttachmentRow({
|
||||
|
||||
export function IssueAttachmentsSection({
|
||||
attachments,
|
||||
downloadAllHref,
|
||||
uploadButton,
|
||||
error,
|
||||
dragActive = false,
|
||||
@@ -269,7 +271,20 @@ export function IssueAttachmentsSection({
|
||||
<h3 className="text-sm font-medium text-muted-foreground">Attachments</h3>
|
||||
<span className="text-xs text-muted-foreground">{attachments.length}</span>
|
||||
</div>
|
||||
{uploadButton}
|
||||
<div className="flex items-center gap-1">
|
||||
{downloadAllHref ? (
|
||||
<Button asChild variant="ghost" size="icon-sm">
|
||||
<a
|
||||
href={downloadAllHref}
|
||||
aria-label="Download all attachments"
|
||||
title="Download all attachments"
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
</a>
|
||||
</Button>
|
||||
) : null}
|
||||
{uploadButton}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
|
||||
@@ -5124,6 +5124,7 @@ export function IssueDetail() {
|
||||
) : hasAttachments ? (
|
||||
<IssueAttachmentsSection
|
||||
attachments={attachmentList}
|
||||
downloadAllHref={`/api/issues/${issue.id}/attachments/archive`}
|
||||
uploadButton={attachmentUploadButton}
|
||||
error={attachmentError}
|
||||
dragActive={attachmentDragActive}
|
||||
|
||||
Reference in new issue
Block a user