feat(ui): triage issues and send them to Jira (#13151)

Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com>
This commit is contained in:
Rubén De la Torre Vicoandalejandrobailo authored and GitHub committed 2026-10-26 15:09:05 +01:00
1 parent 3bbd551f0f
commit 83152ae1a6
32 files changed
+1244 -188

No files matched your search

@@ -0,0 +1,31 @@
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { FINDING_TRIAGE_STATUS } from "@/types/findings-triage";
import { TriageStatusBadge } from "./triage-status-badge";
describe("TriageStatusBadge", () => {
it("renders the labeled read-only status used in the finding drawer", () => {
// Given / When
render(<TriageStatusBadge status={FINDING_TRIAGE_STATUS.REMEDIATING} />);
// Then
expect(screen.getByText("Triage:")).toBeInTheDocument();
expect(screen.getByText("Remediating")).toHaveClass("text-bg-data-info");
});
it("omits the label when the surrounding table already names the field", () => {
// Given / When
render(
<TriageStatusBadge
status={FINDING_TRIAGE_STATUS.RISK_ACCEPTED}
showLabel={false}
/>,
);
// Then
expect(screen.queryByText("Triage:")).not.toBeInTheDocument();
expect(screen.getByText("Risk Accepted")).toBeInTheDocument();
});
});
@@ -0,0 +1,23 @@
import { TRIAGE_STATUS_TEXT_CLASS } from "@/lib/triage";
import { cn } from "@/lib/utils";
import { FINDING_TRIAGE_STATUS_LABELS } from "@/types/findings-triage";
import type { TriageStatusBadgeProps } from "./types";
export function TriageStatusBadge({
status,
showLabel = true,
}: TriageStatusBadgeProps) {
return (
<div className="flex items-center gap-1">
{showLabel && (
<span className="text-text-neutral-tertiary text-xs">Triage:</span>
)}
<span
className={cn("text-xs font-medium", TRIAGE_STATUS_TEXT_CLASS[status])}
>
{FINDING_TRIAGE_STATUS_LABELS[status]}
</span>
</div>
);
}
@@ -0,0 +1,77 @@
"use client";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
} from "@/components/shadcn/select/select";
import { TRIAGE_STATUS_TEXT_CLASS } from "@/lib/triage";
import { cn } from "@/lib/utils";
import {
FINDING_TRIAGE_STATUS,
FINDING_TRIAGE_STATUS_LABELS,
MANUAL_PASS_NOTE_REQUIRED_COPY,
type FindingTriageModalStatus,
} from "@/types/findings-triage";
import type { TriageStatusPickerProps } from "./types";
export function TriageStatusPicker({
disabled,
size = "sm",
value,
statusValues,
showManualPassTooltip = false,
onValueChange,
}: TriageStatusPickerProps) {
return (
<Select
value={value}
disabled={disabled}
onValueChange={(nextStatus) => {
if (statusValues.includes(nextStatus as FindingTriageModalStatus)) {
onValueChange(nextStatus as FindingTriageModalStatus);
}
}}
>
<SelectTrigger
aria-label="Triage status"
disabled={disabled}
size={size}
iconSize="sm"
>
<span className={cn("truncate", TRIAGE_STATUS_TEXT_CLASS[value])}>
{FINDING_TRIAGE_STATUS_LABELS[value]}
</span>
</SelectTrigger>
<SelectContent>
{statusValues.map((status) => {
const shouldExplainManualPass =
showManualPassTooltip && status === FINDING_TRIAGE_STATUS.RESOLVED;
return (
<SelectItem
key={status}
value={status}
aria-label={FINDING_TRIAGE_STATUS_LABELS[status]}
>
<span
className={cn("truncate", TRIAGE_STATUS_TEXT_CLASS[status])}
>
{FINDING_TRIAGE_STATUS_LABELS[status]}
</span>
{shouldExplainManualPass && (
<span
className="text-text-neutral-secondary text-xs font-normal normal-case"
aria-hidden="true"
>
{MANUAL_PASS_NOTE_REQUIRED_COPY}
</span>
)}
</SelectItem>
);
})}
</SelectContent>
</Select>
);
}
+25
View File
@@ -0,0 +1,25 @@
import type { ComponentProps } from "react";
import type { SelectTrigger } from "@/components/shadcn/select/select";
import type {
FindingTriageModalStatus,
FindingTriageStatus,
} from "@/types/findings-triage";
export type TriageStatusPickerSize = NonNullable<
ComponentProps<typeof SelectTrigger>["size"]
>;
export interface TriageStatusPickerProps {
disabled: boolean;
size?: TriageStatusPickerSize;
value: FindingTriageStatus;
statusValues: readonly FindingTriageModalStatus[];
showManualPassTooltip?: boolean;
onValueChange: (status: FindingTriageModalStatus) => void;
}
export interface TriageStatusBadgeProps {
status: FindingTriageStatus;
showLabel?: boolean;
}