facett-demo/src/demo_zoneui.rs
//! **Demo wiring for the two shared zone/jera framework widgets** (`facett-zoneui`).
//!
//! This module builds the two drop-in widgets with fake-but-realistic data so the
//! showcase deck exercises them like every other facet:
//!
//! * [`zone_pane`] — the [`ZonePane`] a Tools-menu entry opens, with a demo
//! [`ZoneGenerator`] wired in place of a real jera `submit_container_job`: pressing
//! **Generate** brings the 2 default containers (FalkorDB + Spark) up to their
//! health-check step in the selected zone, so the live inline status paints.
//! * [`jera_central`] — the [`JeraCentral`] panel seeded with a couple of zoned jera
//! jobs (a demo-zone populate + its two container jobs, and a test-zone populate),
//! so the central panel lists jobs WITH their zone column.
//!
//! Both are returned as boxed [`Facet`](facett::Facet)s the deck mounts. Nothing
//! korp-specific: the generator here is the demo stand-in an app replaces with its
//! own jera submit.
use facett_zoneui::{
ContainerStatus, JeraCentral, JobEntry, JobStatus, Step, Zone, ZonePane, ZonedJob, FALKORDB_IMAGE,
SPARK_IMAGE,
};
/// Build the demo **zone-populate pane**. The wired generator is the demo stand-in
/// for an app's jera `submit_container_job`: it brings the 2 default containers up to
/// health-check in the selected zone and returns their live status.
pub fn zone_pane() -> ZonePane {
ZonePane::new("zone").with_generator(|zone: Zone| {
vec![
ContainerStatus::new("FalkorDB", FALKORDB_IMAGE, 6379 + zone.port_offset())
.step(Step::HealthCheck)
.detail("waiting for PONG"),
ContainerStatus::new("Spark", SPARK_IMAGE, 15002 + zone.port_offset())
.step(Step::Starting)
.detail("podman run…"),
]
})
}
/// Build the demo **jera-central panel**: a demo-zone populate (parent) with its two
/// container child jobs, plus a test-zone populate — so the panel lists jobs WITH
/// their zone column (demo · test).
pub fn jera_central() -> JeraCentral {
let pid = "pop-demo";
// User-facing pane/tab title is "Jobs" (the jera edda job-engine surface reads
// as one thing to the user); `jera`/`JeraCentral` stays the engine name in code.
JeraCentral::from_jobs(
"Jobs",
vec![
ZonedJob::new(
JobEntry {
target: "korp".into(),
started_micros: 2_000_000,
detail: "populate demo — FalkorDB + Spark".into(),
..JobEntry::new(pid, "zone_populate", JobStatus::Running)
},
Zone::Demo,
),
ZonedJob::new(
JobEntry {
target: "FalkorDB :6379".into(),
started_micros: 2_000_100,
elapsed_ms: Some(1800),
detail: "healthy ✓".into(),
parent_id: Some(pid.to_string()),
..JobEntry::new("falkordb-demo", "container", JobStatus::Done)
},
Zone::Demo,
),
ZonedJob::new(
JobEntry {
target: "Spark :15002".into(),
started_micros: 2_000_200,
detail: "starting…".into(),
parent_id: Some(pid.to_string()),
..JobEntry::new("spark-demo", "container", JobStatus::Running)
},
Zone::Demo,
),
ZonedJob::new(
JobEntry {
target: "dwarves".into(),
started_micros: 1_900_000,
detail: "populate test — isolated ports/namespace".into(),
..JobEntry::new("pop-test", "zone_populate", JobStatus::Queued)
},
Zone::Test,
),
],
)
}
#[cfg(test)]
mod tests {
use super::*;
use facett::Facet;
#[test]
fn zone_pane_generate_is_wired_and_lists_the_two_containers() {
let mut p = zone_pane();
// The wired demo generator drives on Generate (the state_json proves it).
p.update_json("\"generate\"");
let j = p.state_json();
assert_eq!(j["zone"], "demo", "default zone");
assert_eq!(j["containers"].as_array().unwrap().len(), 2);
assert_eq!(j["overall"], "running", "generate seeded live bring-up");
assert_eq!(j["has_demo_button"], false);
}
#[test]
fn jera_central_lists_zoned_jobs() {
let jc = jera_central();
let j = jc.state_json();
assert_eq!(j["zones"]["pop-demo"], "demo");
assert_eq!(j["zones"]["pop-test"], "test");
assert_eq!(j["zone_summary"]["demo"], 3, "demo populate + its two containers");
assert_eq!(j["zone_summary"]["test"], 1);
}
}