Skip to main content

max / makenotwork

2.7 KB · 71 lines History Blame Raw
1 //! The Askama entry point for the described "remove this link" button.
2 //!
3 //! Shape 8 (`b279b9eb`), through the glue-module ruling `27d5e5b8`. One of the
4 //! two sites the shape recorded as unsayable: the template reached its row with
5 //! `hx-target="closest .link-row"`, and naming a region cannot say a relative
6 //! selector.
7 //!
8 //! [`Action::replacing_enclosing`] is that sentence in a spelling every
9 //! renderer reads, and it takes no parameter because the act is inside the row
10 //! it removes. The row says `data-row` in Askama, which is the attribute a
11 //! described row already carries and the one the target selects on. Nothing is
12 //! invented: the class stays where the page's own scripts still read it.
13 //!
14 //! `DELETE /api/links/{id}` is a plain API route the description layer does not
15 //! serve, which is why the control names what it replaces at all. See
16 //! [`Action::replaces`].
17 //!
18 //! # Why the caller wraps this in a span
19 //!
20 //! `link_remove_btn` was never styling. `static/tab-user-profile.js` hides the
21 //! Remove while a row is being edited and finds it by that class, and a
22 //! described act carries the class every described act carries. The class moves
23 //! to the element around the control, which is where a fact about that page
24 //! belongs and what `export_act` already does with its layout classes. It goes
25 //! when the profile tab is described and the edit flow with it.
26 //!
27 //! Ids arrive as `impl Display` rather than `&str`: the caller is Askama and
28 //! the server's ids are typed newtypes over `Uuid`, so asking for a string
29 //! would push a `to_string()` into every call site to say what `format!`
30 //! already says here.
31
32 use std::fmt;
33
34 use makeover_layout::Tone;
35 use quasi_router::screen::Act;
36 use quasi_router::{Action, Node};
37
38 /// The remove button for one link row.
39 #[must_use]
40 pub fn html(link_id: impl fmt::Display) -> String {
41 use quasi_axum::Serves as _;
42
43 let act = Act::new(
44 "Remove",
45 Action::delete(format!("/api/links/{link_id}")).replacing_enclosing(),
46 )
47 .tone(Tone::Danger)
48 .confirm("Remove this link?");
49
50 quasi_webview::Webview::new().fragment(&Node::Act(act))
51 }
52
53 #[cfg(test)]
54 mod tests {
55 /// The row it sits in, said without a selector the description cannot hold.
56 #[test]
57 fn a_removal_names_its_route_its_row_and_its_prompt() {
58 let html = super::html("l3");
59
60 assert!(html.contains(r#"hx-delete="/api/links/l3""#), "{html}");
61 assert!(html.contains(r#"hx-target="closest [data-row]""#), "{html}");
62 assert!(html.contains(r#"hx-confirm="Remove this link?""#), "{html}");
63 assert!(!html.contains(".link-row"), "{html}");
64 }
65
66 #[test]
67 fn a_removal_says_it_is_dangerous() {
68 assert!(super::html("l3").contains(r#"data-tone="danger""#));
69 }
70 }
71