refactor(techdemo): scope card handles to partials

Move board card and lane actions onto their reusable partial templates, register the scoped generated handles directly, and remove hidden shell-level handle anchors and manual handle fields from the rendered view data.

req: component/003

req: view/001

req: examples/001
This commit is contained in:
slhx agent
2026-06-01 21:58:40 +02:00
parent c69eb9932c
commit 4319dea171
7 changed files with 22 additions and 33 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ mod tests {
fn techdemo_exports_form_and_interaction_handles() {
assert_ne!(
ui::control_center::handles::launch_work.id(),
ui::control_center::handles::advance_work.id()
ui::issue_card::handles::advance_work.id()
);
assert_eq!(
ui::control_center::forms::launch_work.field("title").resource,
+8 -15
View File
@@ -4,7 +4,7 @@ use axum::routing::get;
use axum::Router;
use futures_util::{stream, StreamExt};
use hemplate::Hemplate;
use slhx::{CssClass, CssClasses, Handle, IntoEffect, RenderSlotExt, SafeHtml};
use slhx::{CssClass, CssClasses, IntoEffect, RenderSlotExt, SafeHtml};
use slhx_axum::{
runtime_js, sse, DispatchRejection, EffectResponse, HandlerRegistry, InteractionForm,
PageRequest,
@@ -102,7 +102,6 @@ struct Shared {
struct IssueLane {
class: CssClass,
lane_id: &'static str,
move_handle: Handle<()>,
title: &'static str,
description: &'static str,
cards: Vec<IssueCard>,
@@ -116,9 +115,6 @@ struct IssueCard {
title: String,
stage: &'static str,
impact_style: String,
spotlight_handle: Handle<()>,
advance_handle: Handle<()>,
delete_handle: Handle<()>,
}
#[derive(Hemplate)]
@@ -304,7 +300,7 @@ fn registry(shared: Arc<Shared>) -> HandlerRegistry {
demo_effects(&demo, "Launch accepted · 4 targets updated")
}
})
.register_handle(ui::control_center::handles::advance_work, {
.register_handle(ui::issue_card::handles::advance_work, {
let shared = shared.clone();
move |form| {
// req: list/003 req: examples/001
@@ -322,7 +318,7 @@ fn registry(shared: Arc<Shared>) -> HandlerRegistry {
demo_effects(&demo, "Pipeline advanced")
}
})
.register_handle(ui::control_center::handles::move_to_lane, {
.register_handle(ui::issue_lane::handles::move_to_lane, {
let shared = shared.clone();
move |form| {
// req: list/003 req: examples/001
@@ -344,7 +340,7 @@ fn registry(shared: Arc<Shared>) -> HandlerRegistry {
demo_effects(&demo, "Drag-and-drop move persisted")
}
})
.register_handle(ui::control_center::handles::delete_work, {
.register_handle(ui::issue_card::handles::delete_work, {
let shared = shared.clone();
move |form| {
// req: list/003 req: examples/001
@@ -363,7 +359,7 @@ fn registry(shared: Arc<Shared>) -> HandlerRegistry {
demo_effects(&demo, "Card removed")
}
})
.register_handle(ui::control_center::handles::spotlight_work, {
.register_handle(ui::issue_card::handles::spotlight_work, {
let shared = shared.clone();
move |form| {
// req: examples/001
@@ -416,7 +412,7 @@ fn update_work(demo: &mut DemoState, id: Option<&str>, update: impl FnOnce(&mut
fn demo_effects(demo: &DemoState, notice: &'static str) -> impl IntoEffect {
(
ui::control_center::slots::hero_metrics.render(&hero_view(demo)),
ui::control_center::slots::board.render(&board_view(demo)),
ui::control_center::slots::board.html(render_board(demo)),
ui::control_center::slots::activity.render(&activity_view(demo)),
ui::control_center::slots::inspector.render(&inspector_view(demo)),
ui::control_center::slots::notice.text(notice),
@@ -491,7 +487,6 @@ fn board_view(demo: &DemoState) -> BoardLanes {
.map(|(idx, (lane_id, title, description))| IssueLane {
class: ui::control_center::classes::lane,
lane_id,
move_handle: ui::control_center::handles::move_to_lane,
title,
description,
cards: demo
@@ -508,7 +503,8 @@ fn board_view(demo: &DemoState) -> BoardLanes {
fn render_board(demo: &DemoState) -> SafeHtml {
// req: html_safety/002 req: view/001
slhx::render_html(&board_view(demo))
let html = render_template(&board_view(demo));
SafeHtml::trusted(ui::issue_lane::lower_html(ui::issue_card::lower_html(html)))
}
fn issue_card(item: &WorkItem, selected: bool) -> IssueCard {
@@ -525,9 +521,6 @@ fn issue_card(item: &WorkItem, selected: bool) -> IssueCard {
title: item.title.clone(),
stage: item.stage.label(),
impact_style: format!("width:{}%", item.impact as usize * 11),
spotlight_handle: ui::control_center::handles::spotlight_work,
advance_handle: ui::control_center::handles::advance_work,
delete_handle: ui::control_center::handles::delete_work,
}
}