git-ents.gitmain
⌘K
foforge
commit 2e90008
web: extract shared status/verdict chip and sidebar tree-head components

Pull the pass/fail/error status chip (commits' checks card, agents' derived session state, effects' trigger-parse check), the review verdict chip (commits' per-commit reviews, the reviews aggregate list, its sidebar, and its own detail page), and a sidebar’s "+ New" tree-head (agents, issues) into shared pages::mod helpers, replacing four independently-hand-rolled copies of the same markup each.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Joseph D. Carpinelli · 28 days ago

Reviews

No reviews of this commit yet — record a verdict below.

Start a review

verdict

crates/cli/ents-web/src/pages/agents.rs @@ -94,10 +94,7 @@ /// page, `.active` naming the viewed session's id. fn agents_sidebar(rows: &[(String, AgentSession)], active: Option<&str>) -> Markup { html! { - div.tree-head { - span { "Agents" } - a.btn.btn-sm.btn-ghost[active.is_some()] href="/agents" { "+ New" } - } + (super::tree_head("Agents", "/agents", active.is_some())) @if rows.is_empty() { span.tree-note { "No agent sessions yet." } } @@ -265,9 +262,9 @@ } /// The state badge [`agents_sidebar`] and [`show`] both render: a -/// checkmark/cross `.status` chip for the terminal `done`/`failed` states -/// (matching `crate::pages::commits::checks_section`'s identical result -/// taxonomy -- a session's own finish literally records a +/// checkmark/cross [`super::status_chip_labeled`] for the terminal +/// `done`/`failed` states (matching `crate::pages::commits::checks_section`'s +/// identical result taxonomy -- a session's own finish literally records a /// [`ents_model::Status::Pass`]/`Fail`), or a neutral `.chip.state-in-progress` /// pill labeled with [`session_state`]'s own word for every state still in /// flight -- the four non-terminal states share one color, since the @@ -275,8 +272,8 @@ fn state_badge(session: &AgentSession) -> Markup { let label = session_state(session); match label { - "done" => html! { span.status.status-pass { "done" } }, - "failed" => html! { span.status.status-fail { "failed" } }, + "done" => super::status_chip_labeled("done", "pass"), + "failed" => super::status_chip_labeled("failed", "fail"), _ => html! { span.chip.chip-pill.state-in-progress { span.dot {}
crates/cli/ents-web/src/pages/commits.rs @@ -380,18 +380,6 @@ seconds: Option<i64>, } -/// A [`ents_model::Status`]'s display word, doubling as its -/// `.status-<word>` chip class -- the closed pass/fail/error taxonomy -/// (`model.result-taxonomy`), spelled out here rather than through -/// `Debug`. -fn status_label(status: ents_model::Status) -> &'static str { - match status { - ents_model::Status::Pass => "pass", - ents_model::Status::Fail => "fail", - ents_model::Status::Error => "error", - } -} - /// The "Checks" card on `GET /commit/{oid}`: every recorded result /// (`model.result-identity`) whose stored `target` field names this /// commit -- the canonical `refs/meta/results/<effect>/<short-oid>` @@ -451,9 +439,7 @@ div.card-header { "Checks" } @for row in &rows { div.card-row { - span class={ "status status-" (status_label(row.status)) } { - (status_label(row.status)) - } + (super::status_chip(row.status)) " " a href={ "/effects/" (row.effect) } { (row.effect) } @if let Some(member) = &row.self_run { @@ -504,7 +490,7 @@ @for ((target, member), review) in &reviews { div.card { div.comment-meta { - span class={ "verdict verdict-" (review.verdict) } { (review.verdict) } + (super::verdict_chip(review.verdict)) (super::avatar(member.as_str())) span.author { (member) } @let reviewer = ents_model::namespace::review_ref(target, member)
crates/cli/ents-web/src/pages/effects.rs @@ -181,15 +181,15 @@ })?; let body = match effect { Ok(effect) => { - let (label, status_class) = match effect.trigger.parse::<Query>() { - Ok(_) => ("parses".to_owned(), "status-pass"), - Err(error) => (format!("does not parse: {error}"), "status-fail"), + let (label, class) = match effect.trigger.parse::<Query>() { + Ok(_) => ("parses".to_owned(), "pass"), + Err(error) => (format!("does not parse: {error}"), "fail"), }; html! { (crate::render::view(&effect)) p { "trigger query: " - span class={ "status " (status_class) } { (label) } + (super::status_chip_labeled(&label, class)) } } }
crates/cli/ents-web/src/pages/issues.rs @@ -84,10 +84,7 @@ /// linking to its own page, `.active` naming the viewed issue's id. fn issues_sidebar(rows: &[(String, ents_forge::Issue)], active: Option<&str>) -> Markup { html! { - div.tree-head { - span { "Issues" } - a.btn.btn-sm.btn-ghost[active.is_some()] href="/issues" { "+ New" } - } + (super::tree_head("Issues", "/issues", active.is_some())) @if rows.is_empty() { span.tree-note { "No issues yet." } }
crates/cli/ents-web/src/pages/mod.rs @@ -657,6 +657,37 @@ format!("scope-c{}", hash.checked_rem(6).unwrap_or(0)) } +/// A `.status-<class>` chip: `label` as its text, `class` as its CSS suffix. +pub(crate) fn status_chip_labeled(label: &str, class: &str) -> Markup { + html! { span class={ "status status-" (class) } { (label) } } +} + +/// The `.status-<word>` chip for a closed pass/fail/error [`ents_model::Status`]. +pub(crate) fn status_chip(status: ents_model::Status) -> Markup { + let word = match status { + ents_model::Status::Pass => "pass", + ents_model::Status::Fail => "fail", + ents_model::Status::Error => "error", + }; + status_chip_labeled(word, word) +} + +/// A `.verdict-<word>` chip for a review's own [`ents_forge::review::Verdict`]. +pub(crate) fn verdict_chip(verdict: ents_forge::review::Verdict) -> Markup { + html! { span class={ "verdict verdict-" (verdict) } { (verdict) } } +} + +/// A sidebar `.tree-head`: `name` plus a "+ New" link into `new_href`, +/// ghost-styled while `viewing_one` (a child page is open). +pub(crate) fn tree_head(name: &str, new_href: &str, viewing_one: bool) -> Markup { + html! { + div.tree-head { + span { (name) } + a.btn.btn-sm.btn-ghost[viewing_one] href=(new_href) { "+ New" } + } + } +} + /// The acting session's member id -- the composite review key's /// `<member>` segment -- resolved the same way /// [`account::resolve_member_by_key`] does, falling back to a short hash of
crates/cli/ents-web/src/pages/reviews.rs @@ -94,7 +94,7 @@ html! { div.card { div.comment-meta { - span class={ "verdict verdict-" (review.verdict) } { (review.verdict) } + (super::verdict_chip(review.verdict)) (super::avatar(member.as_str())) span.author { (member) } span.spacer {} @@ -158,7 +158,7 @@ href={ "/reviews/" (target) "/" (member) } { span.side-title { - span class={ "verdict verdict-" (review.verdict) } { (review.verdict) } + (super::verdict_chip(review.verdict)) " " (member.as_str()) } span.side-meta { @@ -219,7 +219,7 @@ div.card { dl.entity-view { dt { "verdict" } - dd { span class={ "verdict verdict-" (review.verdict) } { (review.verdict) } } + dd { (super::verdict_chip(review.verdict)) } dt { "state" } dd { (state_badge(review.state)) } dt { "target" }