Align inbox non-issue selection styling
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
facf994694
commit
1871a602df
2 changed files with 108 additions and 3 deletions
93
ui/src/pages/Inbox.test.tsx
Normal file
93
ui/src/pages/Inbox.test.tsx
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
// @vitest-environment jsdom
|
||||
|
||||
import { act } from "react";
|
||||
import type { ComponentProps } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { FailedRunInboxRow } from "./Inbox";
|
||||
|
||||
vi.mock("@/lib/router", () => ({
|
||||
Link: ({ children, className, ...props }: ComponentProps<"a">) => (
|
||||
<a className={className} {...props}>{children}</a>
|
||||
),
|
||||
useLocation: () => ({ pathname: "/", search: "", hash: "" }),
|
||||
useNavigate: () => () => {},
|
||||
}));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;
|
||||
|
||||
describe("FailedRunInboxRow", () => {
|
||||
let container: HTMLDivElement;
|
||||
|
||||
beforeEach(() => {
|
||||
container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
container.remove();
|
||||
});
|
||||
|
||||
it("suppresses accent hover styling when selected", () => {
|
||||
const root = createRoot(container);
|
||||
const run = {
|
||||
id: "run-1",
|
||||
companyId: "company-1",
|
||||
agentId: "agent-1",
|
||||
invocationSource: "assignment",
|
||||
triggerDetail: null,
|
||||
status: "failed",
|
||||
error: "boom",
|
||||
wakeupRequestId: null,
|
||||
exitCode: null,
|
||||
signal: null,
|
||||
usageJson: null,
|
||||
resultJson: null,
|
||||
sessionIdBefore: null,
|
||||
sessionIdAfter: null,
|
||||
logStore: null,
|
||||
logRef: null,
|
||||
logBytes: null,
|
||||
logSha256: null,
|
||||
logCompressed: false,
|
||||
errorCode: null,
|
||||
externalRunId: null,
|
||||
processPid: null,
|
||||
processStartedAt: null,
|
||||
retryOfRunId: null,
|
||||
processLossRetryCount: 0,
|
||||
stdoutExcerpt: null,
|
||||
stderrExcerpt: null,
|
||||
contextSnapshot: null,
|
||||
startedAt: new Date("2026-03-11T00:00:00.000Z"),
|
||||
finishedAt: null,
|
||||
createdAt: new Date("2026-03-11T00:00:00.000Z"),
|
||||
updatedAt: new Date("2026-03-11T00:00:00.000Z"),
|
||||
} as const;
|
||||
|
||||
act(() => {
|
||||
root.render(
|
||||
<FailedRunInboxRow
|
||||
run={run}
|
||||
issueById={new Map()}
|
||||
agentName="Agent"
|
||||
issueLinkState={null}
|
||||
onDismiss={() => {}}
|
||||
onRetry={() => {}}
|
||||
isRetrying={false}
|
||||
selected
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
const link = container.querySelector("a");
|
||||
expect(link).not.toBeNull();
|
||||
expect(link?.className).toContain("hover:bg-transparent");
|
||||
expect(link?.className).not.toContain("hover:bg-accent/50");
|
||||
|
||||
act(() => {
|
||||
root.unmount();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -101,7 +101,7 @@ function readIssueIdFromRun(run: HeartbeatRun): string | null {
|
|||
|
||||
type NonIssueUnreadState = "visible" | "fading" | "hidden" | null;
|
||||
|
||||
function FailedRunInboxRow({
|
||||
export function FailedRunInboxRow({
|
||||
run,
|
||||
issueById,
|
||||
agentName: linkedAgentName,
|
||||
|
|
@ -113,6 +113,7 @@ function FailedRunInboxRow({
|
|||
onMarkRead,
|
||||
onArchive,
|
||||
archiveDisabled,
|
||||
selected = false,
|
||||
className,
|
||||
}: {
|
||||
run: HeartbeatRun;
|
||||
|
|
@ -126,6 +127,7 @@ function FailedRunInboxRow({
|
|||
onMarkRead?: () => void;
|
||||
onArchive?: () => void;
|
||||
archiveDisabled?: boolean;
|
||||
selected?: boolean;
|
||||
className?: string;
|
||||
}) {
|
||||
const issueId = readIssueIdFromRun(run);
|
||||
|
|
@ -171,7 +173,10 @@ function FailedRunInboxRow({
|
|||
) : null}
|
||||
<Link
|
||||
to={`/agents/${run.agentId}/runs/${run.id}`}
|
||||
className="flex min-w-0 flex-1 items-start gap-2 no-underline text-inherit transition-colors hover:bg-accent/50"
|
||||
className={cn(
|
||||
"flex min-w-0 flex-1 items-start gap-2 no-underline text-inherit transition-colors",
|
||||
selected ? "hover:bg-transparent" : "hover:bg-accent/50",
|
||||
)}
|
||||
>
|
||||
{!showUnreadSlot && <span className="hidden h-2 w-2 shrink-0 sm:inline-flex" aria-hidden="true" />}
|
||||
<span className="hidden h-3.5 w-3.5 shrink-0 sm:inline-flex" aria-hidden="true" />
|
||||
|
|
@ -260,6 +265,7 @@ function ApprovalInboxRow({
|
|||
onMarkRead,
|
||||
onArchive,
|
||||
archiveDisabled,
|
||||
selected = false,
|
||||
className,
|
||||
}: {
|
||||
approval: Approval;
|
||||
|
|
@ -271,6 +277,7 @@ function ApprovalInboxRow({
|
|||
onMarkRead?: () => void;
|
||||
onArchive?: () => void;
|
||||
archiveDisabled?: boolean;
|
||||
selected?: boolean;
|
||||
className?: string;
|
||||
}) {
|
||||
const Icon = typeIcon[approval.type] ?? defaultTypeIcon;
|
||||
|
|
@ -318,7 +325,10 @@ function ApprovalInboxRow({
|
|||
) : null}
|
||||
<Link
|
||||
to={`/approvals/${approval.id}`}
|
||||
className="flex min-w-0 flex-1 items-start gap-2 no-underline text-inherit transition-colors hover:bg-accent/50"
|
||||
className={cn(
|
||||
"flex min-w-0 flex-1 items-start gap-2 no-underline text-inherit transition-colors",
|
||||
selected ? "hover:bg-transparent" : "hover:bg-accent/50",
|
||||
)}
|
||||
>
|
||||
{!showUnreadSlot && <span className="hidden h-2 w-2 shrink-0 sm:inline-flex" aria-hidden="true" />}
|
||||
<span className="hidden h-3.5 w-3.5 shrink-0 sm:inline-flex" aria-hidden="true" />
|
||||
|
|
@ -1267,6 +1277,7 @@ export function Inbox() {
|
|||
<ApprovalInboxRow
|
||||
key={approvalKey}
|
||||
approval={item.approval}
|
||||
selected={isSelected}
|
||||
requesterName={agentName(item.approval.requestedByAgentId)}
|
||||
onApprove={() => approveMutation.mutate(item.approval.id)}
|
||||
onReject={() => rejectMutation.mutate(item.approval.id)}
|
||||
|
|
@ -1302,6 +1313,7 @@ export function Inbox() {
|
|||
<FailedRunInboxRow
|
||||
key={runKey}
|
||||
run={item.run}
|
||||
selected={isSelected}
|
||||
issueById={issueById}
|
||||
agentName={agentName(item.run.agentId)}
|
||||
issueLinkState={issueLinkState}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue