From 5e09dec669b31cf37e6cf7786936ad9e7fb3f255 Mon Sep 17 00:00:00 2001 From: "Hugo P.Brito" Date: Thu, 16 Jul 2026 22:16:47 +0100 Subject: [PATCH] fix(ui): address grouped Jira review feedback --- ui/actions/integrations/jira-dispatch.test.ts | 43 ++++++++- ui/actions/integrations/jira-dispatch.ts | 6 +- .../findings/floating-mute-button.test.tsx | 2 +- .../findings/floating-mute-button.tsx | 12 +-- .../findings/send-to-jira-modal-copy.test.ts | 17 ++++ .../findings/send-to-jira-modal-copy.ts | 13 +++ .../findings/send-to-jira-modal.test.tsx | 89 +++++++++++++++++++ ui/components/findings/send-to-jira-modal.tsx | 28 ++++-- .../table/data-table-row-actions.test.tsx | 38 ++++++++ .../findings/table/data-table-row-actions.tsx | 4 +- .../table/findings-group-drill-down.tsx | 2 +- .../table/findings-group-table.test.tsx | 32 +++++++ .../findings/table/findings-group-table.tsx | 22 ++++- .../shadcn/dropdown/action-dropdown.tsx | 18 +++- ui/lib/deployment.test.ts | 4 +- ui/lib/deployment.ts | 4 +- 16 files changed, 303 insertions(+), 31 deletions(-) diff --git a/ui/actions/integrations/jira-dispatch.test.ts b/ui/actions/integrations/jira-dispatch.test.ts index 56c19b8fe6..901d472a43 100644 --- a/ui/actions/integrations/jira-dispatch.test.ts +++ b/ui/actions/integrations/jira-dispatch.test.ts @@ -100,7 +100,27 @@ describe("sendJiraDispatch", () => { // Then expect(result).toEqual({ success: false, - error: "Jira dispatch completed with 1 failed and 2 created issues.", + error: + "Jira dispatch completed with 1 failed and 2 created/updated issues.", + }); + }); + + it("should include updated issues in partial failure summaries", async () => { + // Given + pollTaskUntilSettledMock.mockResolvedValue({ + ok: true, + state: "completed", + result: { created_count: 0, updated_count: 2, failed_count: 1 }, + }); + + // When + const result = await pollJiraDispatchTask("task-1"); + + // Then + expect(result).toEqual({ + success: false, + error: + "Jira dispatch completed with 1 failed and 2 created/updated issues.", }); }); @@ -118,7 +138,8 @@ describe("sendJiraDispatch", () => { // Then expect(result).toEqual({ success: false, - error: "Jira dispatch completed with 1 failed and 1 created issue.", + error: + "Jira dispatch completed with 1 failed and 1 created/updated issue.", }); }); @@ -186,4 +207,22 @@ describe("sendJiraDispatch", () => { error: "Jira dispatch completed but did not create or update any issues.", }); }); + + it("should fail completed task polling when Jira dispatch has no result payload", async () => { + // Given + pollTaskUntilSettledMock.mockResolvedValue({ + ok: true, + state: "completed", + result: null, + }); + + // When + const result = await pollJiraDispatchTask("task-1"); + + // Then + expect(result).toEqual({ + success: false, + error: "Jira dispatch completed but did not create or update any issues.", + }); + }); }); diff --git a/ui/actions/integrations/jira-dispatch.ts b/ui/actions/integrations/jira-dispatch.ts index 41df32e492..a1520588d0 100644 --- a/ui/actions/integrations/jira-dispatch.ts +++ b/ui/actions/integrations/jira-dispatch.ts @@ -63,7 +63,9 @@ const buildJiraDispatchFailureMessage = ( if (result?.error) return result.error; const createdCount = result?.created_count ?? 0; - return `Jira dispatch completed with ${failedCount} failed and ${createdCount} created issue${createdCount === 1 ? "" : "s"}.`; + const updatedCount = result?.updated_count ?? 0; + const successCount = createdCount + updatedCount; + return `Jira dispatch completed with ${failedCount} failed and ${successCount} created/updated issue${successCount === 1 ? "" : "s"}.`; }; export const getJiraIssueTypes = async ( @@ -254,7 +256,7 @@ export const pollJiraDispatchTask = async ( }; } - if (jiraResult && getJiraDispatchSuccessCount(jiraResult) === 0) { + if (!jiraResult || getJiraDispatchSuccessCount(jiraResult) === 0) { return { success: false, error: diff --git a/ui/components/findings/floating-mute-button.test.tsx b/ui/components/findings/floating-mute-button.test.tsx index 56769fc83e..3cc6f36634 100644 --- a/ui/components/findings/floating-mute-button.test.tsx +++ b/ui/components/findings/floating-mute-button.test.tsx @@ -260,7 +260,7 @@ describe("FloatingMuteButton — onBeforeOpen error handling", () => { ).toBeVisible(); expect( screen.getByRole("button", { - name: "Send to Jira", + name: "Send 1 Group and 1 Finding to Jira", }), ).toHaveTextContent("Send 1 Group and 1 Finding to Jira"); }); diff --git a/ui/components/findings/floating-mute-button.tsx b/ui/components/findings/floating-mute-button.tsx index 11ec761484..ac24e3d6ff 100644 --- a/ui/components/findings/floating-mute-button.tsx +++ b/ui/components/findings/floating-mute-button.tsx @@ -14,6 +14,7 @@ import { TooltipContent, TooltipTrigger, } from "@/components/shadcn/tooltip"; +import { cn } from "@/lib/utils"; import { MuteFindingsModal } from "./mute-findings-modal"; @@ -171,12 +172,11 @@ export function FloatingMuteButton({