diff --git a/src/renderer/components/inbox/Inbox.tsx b/src/renderer/components/inbox/Inbox.tsx
index dc9c6cd3..cfe7c30c 100644
--- a/src/renderer/components/inbox/Inbox.tsx
+++ b/src/renderer/components/inbox/Inbox.tsx
@@ -8,7 +8,7 @@ import {
import type { InboxItem, InboxItemType, SectionId } from "@shared/types";
import { timeAgo } from "../../lib/formatters";
import { useT } from "../../i18n";
-import { typeConfig, severityBorderClass } from "./inbox-helpers";
+import { typeConfig } from "./inbox-helpers";
import { AttentionRow } from "../ui";
interface InboxProps {
@@ -104,12 +104,15 @@ export function Inbox({ items, onNavigate }: InboxProps) {
{t("inbox.noItemsNow")}
) : (
-
+
{filteredItems.map((item, i) => {
const config = typeConfig[item.type];
const Icon = config.icon;
- const title = {item.title};
+ const isUrgent = item.severity === "critical" || item.severity === "high";
+ const title = (
+ {item.title}
+ );
const subtitle = (
{item.agentName ? (
@@ -119,6 +122,9 @@ export function Inbox({ items, onNavigate }: InboxProps) {
) : null}
{item.subtitle.slice(0, 80)}
+ {isUrgent ? (
+
+ ) : null}
{timeAgo(item.createdAt)}
);
@@ -127,11 +133,9 @@ export function Inbox({ items, onNavigate }: InboxProps) {
key={item.id}
index={i}
icon={Icon}
- iconColor={config.color}
- iconTileBg={config.bg}
- iconWeight="fill"
- rowBgClass="bg-card"
- borderAccentClass={`border-l-[3px] border-border hover:shadow-md hover:-translate-y-px ${severityBorderClass(item.severity)}`}
+ tone="info"
+ iconWeight={isUrgent ? "bold" : "regular"}
+ variant="line"
title={title}
subtitle={subtitle}
onClick={() => handleItemClick(item)}
diff --git a/src/renderer/components/inbox/inbox-helpers.tsx b/src/renderer/components/inbox/inbox-helpers.tsx
index 275f7a46..a39346be 100644
--- a/src/renderer/components/inbox/inbox-helpers.tsx
+++ b/src/renderer/components/inbox/inbox-helpers.tsx
@@ -10,27 +10,15 @@ import {
import type { InboxItemType } from "@shared/types";
import { Card } from "../ui";
-export const typeConfig: Record = {
- pending_approval: { icon: ShieldCheck, color: "var(--destructive)", bg: "var(--muted-foreground)", label: "Approval" },
- failed_run: { icon: XCircle, color: "var(--destructive)", bg: "var(--destructive)", label: "Failed Run" },
- budget_warning: { icon: CurrencyCircleDollar, color: "var(--destructive)", bg: "var(--muted-foreground)", label: "Budget" },
- blocked_task: { icon: Warning, color: "var(--destructive)", bg: "var(--destructive)", label: "Blocked" },
- review_needed: { icon: Eye, color: "var(--primary)", bg: "var(--primary)", label: "Review" },
- agent_message: { icon: ChatCircle, color: "var(--primary)", bg: "var(--primary)", label: "Message" },
+export const typeConfig: Record = {
+ pending_approval: { icon: ShieldCheck, label: "Approval" },
+ failed_run: { icon: XCircle, label: "Failed Run" },
+ budget_warning: { icon: CurrencyCircleDollar, label: "Budget" },
+ blocked_task: { icon: Warning, label: "Blocked" },
+ review_needed: { icon: Eye, label: "Review" },
+ agent_message: { icon: ChatCircle, label: "Message" },
};
-export const severityColors: Record = {
- critical: "border-l-[color:var(--destructive)]",
- high: "border-l-[color:var(--destructive)]",
- medium: "border-l-[color:var(--primary)]",
- low: "border-l-[color:var(--border)]",
-};
-
-export function severityBorderClass(severity: string | null | undefined): string {
- if (!severity) return "border-l-[color:var(--border)]";
- return severityColors[severity] ?? "border-l-[color:var(--border)]";
-}
-
export function CompactMetric({ label, value, tone = "default", subtitle }: {
label: string;
value: string | number;
diff --git a/src/renderer/components/ui/AttentionRow.tsx b/src/renderer/components/ui/AttentionRow.tsx
index 8f203568..2a9bf31e 100644
--- a/src/renderer/components/ui/AttentionRow.tsx
+++ b/src/renderer/components/ui/AttentionRow.tsx
@@ -6,6 +6,7 @@ const ATTENTION_STAGGER_MAX = 8;
const ATTENTION_STAGGER_STEP = 0.04;
export type AttentionTone = "warn" | "danger" | "info" | "neutral";
+export type AttentionVariant = "card" | "line";
export interface AttentionRowProps {
icon: ElementType;
@@ -21,6 +22,7 @@ export interface AttentionRowProps {
borderAccentClass?: string;
showArrow?: boolean;
iconWeight?: "fill" | "bold" | "regular";
+ variant?: AttentionVariant;
}
const toneIconClass: Record = {
@@ -51,30 +53,53 @@ export function AttentionRow({
borderAccentClass,
showArrow = true,
iconWeight,
+ variant = "card",
}: AttentionRowProps) {
const iconClass = iconColor ? "" : toneIconClass[tone];
- const bgClass = rowBgClass ?? toneBgClass[tone];
const delay = Math.min(index, ATTENTION_STAGGER_MAX) * ATTENTION_STAGGER_STEP;
- const borderClass = borderAccentClass ?? "border-[color:var(--destructive)] border-opacity-20 hover:border-opacity-40";
const isButton = typeof onClick === "function";
- const commonClass = `focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 flex w-full items-center gap-3 rounded-lg border ${borderClass} ${bgClass} px-4 py-3 text-left transition`;
- const iconElement = iconTileBg ? (
-
-
-
- ) : (
-
- );
+ const chromeClass =
+ variant === "line"
+ ? "border-b border-border/60 hover:bg-muted/40 px-2 py-3"
+ : (() => {
+ const bgClass = rowBgClass ?? toneBgClass[tone];
+ const borderClass =
+ borderAccentClass ??
+ "border-[color:var(--destructive)] border-opacity-20 hover:border-opacity-40";
+ return `rounded-lg border ${borderClass} ${bgClass} px-4 py-3`;
+ })();
+ const commonClass = `focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 flex w-full items-center gap-3 text-left transition ${chromeClass}`;
+
+ const iconElement =
+ variant === "card" && iconTileBg ? (
+
+
+
+ ) : (
+
+ );
+
+ const titleWeightClass = variant === "line" ? "" : "font-medium";
const inner = (
<>
{iconElement}
-
{title}
+
{title}
{subtitle ?
{subtitle}
: null}
{rightMeta}