build: no 'back' alternatives; portal's way down the tree replaces them

The page after sending and every public list ended with a Back/Tilbake
alternative. Portal now puts a way down the tree on every page (an
arrow at the left edge and a link at the foot, uhhm/portal PR 1), to
the nearest page below that the visitor may open: the front door after
a public form, the group's desk after an internal one. Sites built from
here need a portal that carries it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
This commit is contained in:
Bendik Aagaard Lynghaug
2026-09-29 07:05:48 +02:00
co-authored by Claude Opus 5.5
parent cda3b0685a
commit c2658ae2c4
+10 -11
View File
@@ -861,17 +861,15 @@ pub fn fallback_words(plan: &Plan) -> BTreeMap<String, Value> {
);
}
for need in &plan.needs {
let (path, back) = match &need.enters_as {
None => (format!("questions/received/{}.yaml", need.id), "/".to_string()),
Some(group) => (format!("questions/{group}/{}-sent.yaml", need.id), format!("/{group}")),
let path = match &need.enters_as {
None => format!("questions/received/{}.yaml", need.id),
Some(group) => format!("questions/{group}/{}-sent.yaml", need.id),
};
let _ = back;
let mut page = json!({
"question": "What happens now?",
"description": format!("It has reached our {}.", humanize(&need.handled_by).to_lowercase()),
"next_heading": "We read it and come back to you",
"next_description": format!("Questions in the meantime go to {} at {}.", plan.contact.name, plan.contact.email),
"back": "Back",
});
if need.watched_by.iter().any(|g| g == PUBLIC) {
page["see_all"] = json!({ "heading": format!("See all {}", humanize(&need.lands_in).to_lowercase()), "description": "", "button": "Open" });
@@ -959,7 +957,6 @@ pub fn fallback_words(plan: &Plan) -> BTreeMap<String, Value> {
"list_title": humanize(bucket),
"list_note": loc(lang, "Each row is one case and the stage it has reached. Names and contact details are not shown here.", "Hver rad er én sak og hvor langt den har kommet. Navn og kontaktopplysninger vises ikke her."),
"empty": loc(lang, "Nothing here yet.", "Ingenting her ennå."),
"back": "Back",
}),
);
}
@@ -1613,9 +1610,13 @@ pub fn render(plan: &Plan, words: &BTreeMap<String, Value>) -> anyhow::Result<BT
}
for need in &plan.needs {
let (path, back) = match &need.enters_as {
None => (format!("questions/received/{}.yaml", need.id), "/".to_string()),
Some(group) => (format!("questions/{group}/{}-sent.yaml", need.id), format!("/{group}")),
// No "back" alternative: portal's way down the tree (the arrow at
// the left and the link at the foot) takes a visitor
// one level down from any page, here to the front door or, after
// an internal form, to the group's desk.
let path = match &need.enters_as {
None => format!("questions/received/{}.yaml", need.id),
Some(group) => format!("questions/{group}/{}-sent.yaml", need.id),
};
let w = &words[&path];
let mut alternatives = vec![
@@ -1627,7 +1628,6 @@ pub fn render(plan: &Plan, words: &BTreeMap<String, Value>) -> anyhow::Result<BT
"action": format!("/status/{}", need.lands_in), "consequence": [s(&w["see_all"]["button"])],
}));
}
alternatives.push(json!({ "name": s(&w["back"]), "description": "", "action": back, "consequence": [s(&w["back"])] }));
// Nested and not an index: portal infers a followup page.
files.insert(path, json!({ "name": s(&w["question"]), "description": s(&w["description"]), "alternatives": alternatives }));
if let Some(group) = &need.enters_as {
@@ -1740,7 +1740,6 @@ pub fn render(plan: &Plan, words: &BTreeMap<String, Value>) -> anyhow::Result<BT
"description": s(&w["list_description"]),
"features": [{ "name": s(&w["list_title"]), "description": s(&w["list_note"]), "resource": public_resource(bucket, &needs, s(&w["empty"]), None) }],
},
{ "name": s(&w["back"]), "description": "", "action": "/", "consequence": [s(&w["back"])] },
],
}),
);