diff --git a/apps/decodex/src/orchestrator/operator_dashboard.html b/apps/decodex/src/orchestrator/operator_dashboard.html
index 920071e6..3e06191f 100644
--- a/apps/decodex/src/orchestrator/operator_dashboard.html
+++ b/apps/decodex/src/orchestrator/operator_dashboard.html
@@ -3575,11 +3575,7 @@
Run History
}
function compactStateToken(value) {
- if (!value) {
- return "none";
- }
-
- return String(value).trim().toLowerCase().replace(/_/g, " ");
+ return formatDetailToken(value);
}
function formatTimestamp(value) {
@@ -4229,7 +4225,7 @@ Run History
function formatDetailToken(value) {
const token = String(value || "").trim();
- return token ? token.toUpperCase() : "NONE";
+ return token || "NONE";
}
function formatPriority(priority) {
@@ -4530,6 +4526,9 @@ Run History
function titleCaseLabel(label) {
return String(label || "").replace(/\b[A-Za-z][A-Za-z0-9]*\b/g, (word) => {
+ if (/^[A-Z0-9]+$/.test(word) && /[A-Z]/.test(word)) {
+ return word;
+ }
const lower = word.toLowerCase();
const acronym = FIELD_LABEL_ACRONYMS.get(lower);
return acronym || `${lower.charAt(0).toUpperCase()}${lower.slice(1)}`;
@@ -4599,6 +4598,22 @@ Run History
return renderField(label, value, valueClass, titleCaseLabel, "card-field");
}
+ function cardFactValueClass(value, explicitClass = "") {
+ return [explicitClass, String(value || "").trim() === "NONE" ? "is-muted" : ""]
+ .filter(Boolean)
+ .join(" ");
+ }
+
+ function optionalCardToken(value) {
+ const token = String(value || "").trim();
+ return token || "NONE";
+ }
+
+ function reviewThreadToken(count) {
+ const numericCount = Number(count);
+ return Number.isFinite(numericCount) && numericCount > 0 ? String(numericCount) : "NONE";
+ }
+
function renderAttentionFacts(candidate) {
const attention = candidate.attention;
if (!attention) {
@@ -7274,9 +7289,9 @@ Run History
["Run", activeRun.run_id],
["Operation", humanizeToken(activeRun.current_operation || activeRun.phase)],
["Checks", compactStateToken(lane.check_state)],
- ["Threads", lane.unresolved_review_threads == null ? "none" : String(lane.unresolved_review_threads)],
- ["PR", lane.pr_url || "none"],
- ["Branch", lane.branch_name],
+ ["Threads", reviewThreadToken(lane.unresolved_review_threads)],
+ ["PR", optionalCardToken(lane.pr_url)],
+ ["Branch", optionalCardToken(lane.branch_name)],
],
});
continue;
@@ -7293,9 +7308,9 @@ Run History
status: postReviewBlockerStatus(lane, blockerScope),
facts: [
["Checks", compactStateToken(lane.check_state)],
- ["Threads", lane.unresolved_review_threads == null ? "none" : String(lane.unresolved_review_threads)],
- ["PR", lane.pr_url || "none"],
- ["Branch", lane.branch_name],
+ ["Threads", reviewThreadToken(lane.unresolved_review_threads)],
+ ["PR", optionalCardToken(lane.pr_url)],
+ ["Branch", optionalCardToken(lane.branch_name)],
],
});
continue;
@@ -7311,9 +7326,9 @@ Run History
status: lane.check_state ? `checks ${compactStateToken(lane.check_state)}` : "waiting",
facts: [
["Review decision", compactStateToken(lane.review_decision)],
- ["Threads", lane.unresolved_review_threads == null ? "none" : String(lane.unresolved_review_threads)],
- ["PR", lane.pr_url || "none"],
- ["Branch", lane.branch_name],
+ ["Threads", reviewThreadToken(lane.unresolved_review_threads)],
+ ["PR", optionalCardToken(lane.pr_url)],
+ ["Branch", optionalCardToken(lane.branch_name)],
],
});
continue;
@@ -7330,8 +7345,9 @@ Run History
facts: [
["Review decision", compactStateToken(lane.review_decision)],
["Checks", compactStateToken(lane.check_state)],
- ["PR", lane.pr_url || "none"],
- ["Branch", lane.branch_name],
+ ["Threads", reviewThreadToken(lane.unresolved_review_threads)],
+ ["PR", optionalCardToken(lane.pr_url)],
+ ["Branch", optionalCardToken(lane.branch_name)],
],
});
}
@@ -8021,7 +8037,7 @@ ${escapeHtml(item.title)}
${statusLabel(item.status, item.tone)}
- ${item.facts.map(([label, value]) => cardField(label, value)).join("")}
+ ${item.facts.map(([label, value, valueClass]) => cardField(label, value, cardFactValueClass(value, valueClass))).join("")}
`,
diff --git a/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs b/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs
index f806d453..ab9e9e23 100644
--- a/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs
+++ b/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs
@@ -944,7 +944,8 @@ fn operator_dashboard_projects_keep_status_summary_compact() {
assert!(response.contains("Appears after /state publishes a snapshot."));
assert!(response.contains("renderQueuedCandidates("));
assert!(response.contains("function formatDetailToken(value)"));
- assert!(response.contains("return token ? token.toUpperCase() : \"NONE\";"));
+ assert!(response.contains("return token || \"NONE\";"));
+ assert!(!response.contains("return token ? token.toUpperCase() : \"NONE\";"));
assert!(response.contains("return priority == null ? \"NONE\" : `P${priority}`;"));
assert!(response.contains("function queuedCandidateSummaryIsNoise(summary)"));
assert!(response.contains("normalized.includes(\"systemerror\")"));
@@ -970,7 +971,9 @@ fn operator_dashboard_projects_keep_status_summary_compact() {
assert!(!response.contains("metadata "));
assert!(!response.contains("telemetry "));
assert!(response.contains("renderActionCards("));
- assert!(response.contains("${item.facts.map(([label, value]) => cardField(label, value)).join(\"\")}"));
+ assert!(response.contains("function cardFactValueClass(value, explicitClass = \"\")"));
+ assert!(response.contains("String(value || \"\").trim() === \"NONE\" ? \"is-muted\" : \"\""));
+ assert!(response.contains("${item.facts.map(([label, value, valueClass]) => cardField(label, value, cardFactValueClass(value, valueClass))).join(\"\")}"));
assert!(!response.contains("${item.facts.map(([label, value]) => field(label, value)).join(\"\")}"));
assert!(!response.contains("No running lanes"));
assert!(!response.contains("No queued issues"));
@@ -1091,7 +1094,16 @@ fn operator_dashboard_normalizes_review_state_tokens() {
let response = dashboard_response();
assert!(response.contains("function compactStateToken(value)"));
- assert!(response.contains("return String(value).trim().toLowerCase().replace(/_/g, \" \");"));
+ assert!(response.contains("return formatDetailToken(value);"));
+ assert!(response.contains("function reviewThreadToken(count)"));
+ assert!(
+ response.contains(
+ "return Number.isFinite(numericCount) && numericCount > 0 ? String(numericCount) : \"NONE\";",
+ )
+ );
+ assert!(response.contains("function optionalCardToken(value)"));
+ assert!(response.contains("return token || \"NONE\";"));
+ assert!(response.contains("if (/^[A-Z0-9]+$/.test(word) && /[A-Z]/.test(word))"));
assert!(response.contains(
"status: lane.mergeable ? `merge ${compactStateToken(lane.mergeable)}` : \"ready\","
));
@@ -1100,10 +1112,14 @@ fn operator_dashboard_normalizes_review_state_tokens() {
));
assert!(response.contains("`review ${compactStateToken(lane.review_decision)}`"));
assert!(response.contains("[\"Checks\", compactStateToken(lane.check_state)]"));
+ assert!(response.contains("[\"Threads\", reviewThreadToken(lane.unresolved_review_threads)]"));
assert!(response.contains("[\"Review decision\", compactStateToken(lane.review_decision)]"));
+ assert!(response.contains("[\"PR\", optionalCardToken(lane.pr_url)]"));
assert!(!response.contains("`merge ${humanizeToken(lane.mergeable)}`"));
assert!(!response.contains("`checks ${humanizeToken(lane.check_state)}`"));
assert!(!response.contains("[\"Checks\", lane.check_state || \"none\"]"));
+ assert!(!response.contains("lane.unresolved_review_threads == null ? \"none\""));
+ assert!(!response.contains("lane.pr_url || \"none\""));
}
#[test]