Skip to content

Commit 5eefcbb

Browse files
Refine workbench status indicators and queue filters
1 parent b2250f0 commit 5eefcbb

2 files changed

Lines changed: 93 additions & 29 deletions

File tree

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Changelog
22

3+
## 2026-05-28 — Salt-Aligned Status Indicators Milestone
4+
5+
### Changed
6+
7+
- Refined workbench status badges with dot-based risk indicators.
8+
- Refined priority labels to read as explicit workbench priority states.
9+
- Refined queue filter chips for a more consistent enterprise workbench feel.
10+
- Preserved existing queue filtering, break selection, action preview, and candidate decision interactions.
11+
12+
### Design Notes
13+
14+
- This milestone improves visual consistency without changing reconciliation logic.
15+
- Status color continues to carry operational meaning:
16+
- Red for breached / difference states
17+
- Amber for due-today / missing states
18+
- Green for within-SLA / matched states
19+
- Slate for neutral states
20+
- The UI is moving toward a Salt-inspired institutional operations style while keeping reconciliation-specific workflow logic custom.
21+
322
## 2026-05-28 — Salt Button Replacement Milestone
423

524
### Changed

frontend/components/BreakResolutionWorkbench.tsx

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,42 @@ const fallbackWorkbenchData: WorkbenchData = {
7979
candidatesByExceptionId: fallbackCandidatesByExceptionId,
8080
};
8181

82+
function statusPillClass(value: string) {
83+
if (value === "BREACHED" || value === "difference") {
84+
return {
85+
chip: "bg-red-50 text-red-800 ring-red-200",
86+
dot: "bg-red-600",
87+
};
88+
}
89+
90+
if (value === "DUE_TODAY" || value === "missing") {
91+
return {
92+
chip: "bg-amber-50 text-amber-800 ring-amber-200",
93+
dot: "bg-amber-500",
94+
};
95+
}
96+
97+
if (value === "WITHIN_SLA" || value === "match") {
98+
return {
99+
chip: "bg-emerald-50 text-emerald-800 ring-emerald-200",
100+
dot: "bg-emerald-600",
101+
};
102+
}
103+
104+
return {
105+
chip: "bg-slate-100 text-slate-700 ring-slate-200",
106+
dot: "bg-slate-500",
107+
};
108+
}
109+
82110
function StatusBadge({ value }: { value: string }) {
83-
const style =
84-
value === "BREACHED"
85-
? "bg-red-50 text-red-700 ring-red-200"
86-
: value === "DUE_TODAY"
87-
? "bg-amber-50 text-amber-700 ring-amber-200"
88-
: "bg-emerald-50 text-emerald-700 ring-emerald-200";
111+
const style = statusPillClass(value);
89112

90113
return (
91-
<span className={`rounded-full px-2.5 py-1 text-xs font-semibold ring-1 ${style}`}>
114+
<span
115+
className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-bold ring-1 ${style.chip}`}
116+
>
117+
<span className={`h-1.5 w-1.5 rounded-full ${style.dot}`} />
92118
{value}
93119
</span>
94120
);
@@ -97,33 +123,58 @@ function StatusBadge({ value }: { value: string }) {
97123
function PriorityPill({ value }: { value: string }) {
98124
const style =
99125
value === "High"
100-
? "bg-slate-950 text-white"
126+
? "bg-slate-950 text-white ring-slate-950"
101127
: value === "Medium"
102-
? "bg-slate-200 text-slate-900"
103-
: "bg-slate-100 text-slate-600";
128+
? "bg-slate-100 text-slate-800 ring-slate-300"
129+
: "bg-white text-slate-600 ring-slate-200";
104130

105131
return (
106-
<span className={`rounded-full px-2.5 py-1 text-xs font-semibold ${style}`}>
107-
{value}
132+
<span
133+
className={`inline-flex items-center rounded-full px-2.5 py-1 text-xs font-bold ring-1 ${style}`}
134+
>
135+
Priority: {value}
108136
</span>
109137
);
110138
}
111139

112140
function EvidenceStatus({ value }: { value: string }) {
113-
const style =
114-
value === "difference"
115-
? "bg-red-50 text-red-700"
116-
: value === "missing"
117-
? "bg-amber-50 text-amber-700"
118-
: "bg-emerald-50 text-emerald-700";
141+
const style = statusPillClass(value);
119142

120143
return (
121-
<span className={`rounded-full px-2.5 py-1 text-xs font-semibold ${style}`}>
144+
<span
145+
className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-bold ring-1 ${style.chip}`}
146+
>
147+
<span className={`h-1.5 w-1.5 rounded-full ${style.dot}`} />
122148
{value}
123149
</span>
124150
);
125151
}
126152

153+
function QueueFilterChip({
154+
filter,
155+
active,
156+
onClick,
157+
}: {
158+
filter: QueueFilter;
159+
active: boolean;
160+
onClick: () => void;
161+
}) {
162+
return (
163+
<button
164+
type="button"
165+
onClick={onClick}
166+
className={`rounded-full px-3 py-1.5 text-xs font-bold ring-1 transition ${
167+
active
168+
? "bg-slate-950 text-white ring-slate-950"
169+
: "bg-white text-slate-600 ring-slate-200 hover:bg-slate-50 hover:text-slate-950"
170+
}`}
171+
>
172+
{filter}
173+
</button>
174+
);
175+
}
176+
177+
127178
function QueueCard({
128179
item,
129180
active,
@@ -479,18 +530,12 @@ export default function BreakResolutionWorkbench() {
479530

480531
<div className="mb-4 flex flex-wrap gap-2">
481532
{QUEUE_FILTERS.map((filter) => (
482-
<button
533+
<QueueFilterChip
483534
key={filter}
484-
type="button"
535+
filter={filter}
536+
active={queueFilter === filter}
485537
onClick={() => setQueueFilter(filter)}
486-
className={`rounded-full px-3 py-1.5 text-xs font-bold transition ${
487-
queueFilter === filter
488-
? "bg-slate-950 text-white"
489-
: "bg-slate-100 text-slate-600 hover:bg-slate-200"
490-
}`}
491-
>
492-
{filter}
493-
</button>
538+
/>
494539
))}
495540
</div>
496541

0 commit comments

Comments
 (0)