fix(ui): align contextual documentation with headings

Verified with the coordinated workspace changes by devkit full run
2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed).
This shared UI pass does not mark the individual module reviews complete.
This commit is contained in:
2026-09-09 02:04:26 +02:00
parent f8ab0f0e8d
commit 914121f4d7
4 changed files with 15 additions and 5 deletions
+8 -2
View File
@@ -327,7 +327,10 @@ manifest = ModuleManifest(
id="voting.workspace-layout", id="voting.workspace-layout",
title="Voting workspace layout", title="Voting workspace layout",
summary="Find workspace actions and read consistently arranged content.", summary="Find workspace actions and read consistently arranged content.",
body="Reload and New ballot remain in the workspace-wide top bar, even when a ballot is selected or the catalogue is empty. Reload sits immediately before New. Ballot actions such as opening, casting, certification, challenge, and annulment stay with the selected ballot. New ballot stays visible but disabled without management permission. The shared layout changes no electorate or assurance policy; administrators retain the existing separate management, casting, certification, and administrative grants.", body="Documentation books sit immediately beside the visible heading or contextual label for "
"Voting and ballot dialogs, not among operational action buttons. Field help remains beside "
"its label. "
"Reload and New ballot remain in the workspace-wide top bar, even when a ballot is selected or the catalogue is empty. Reload sits immediately before New. Ballot actions such as opening, casting, certification, challenge, and annulment stay with the selected ballot. New ballot stays visible but disabled without management permission. The shared layout changes no electorate or assurance policy; administrators retain the existing separate management, casting, certification, and administrative grants.",
layer="static", layer="static",
documentation_types=("user", "admin"), documentation_types=("user", "admin"),
audience=("user", "module_admin", "operator"), audience=("user", "module_admin", "operator"),
@@ -335,7 +338,10 @@ manifest = ModuleManifest(
translations={"de": { translations={"de": {
"title": "Abstimmungen: Aufbau des Arbeitsbereichs", "title": "Abstimmungen: Aufbau des Arbeitsbereichs",
"summary": "Arbeitsbereichsaktionen finden und einheitlich angeordnete Inhalte lesen.", "summary": "Arbeitsbereichsaktionen finden und einheitlich angeordnete Inhalte lesen.",
"body": "Neu laden und Neue Abstimmung bleiben in der arbeitsbereichsweiten oberen Leiste, auch bei ausgewählter Abstimmung oder leerem Katalog. Neu laden steht unmittelbar vor Neu. Öffnen, Stimmabgabe, Zertifizierung, Anfechtung und Annullierung bleiben bei der ausgewählten Abstimmung. Neue Abstimmung bleibt ohne Verwaltungsrecht sichtbar, aber deaktiviert. Das gemeinsame Layout verändert weder Wählerschaft noch Zusicherung; die getrennten Verwaltungs-, Stimmabgabe-, Zertifizierungs- und Administrationsrechte bleiben bestehen.", "body": "Dokumentationsbücher stehen unmittelbar neben der sichtbaren Überschrift oder "
"Kontextbezeichnung für Abstimmungen und Abstimmungsdialoge, nicht zwischen ausführbaren "
"Aktionsschaltflächen. Feldhilfe bleibt neben der Feldbezeichnung. "
"Neu laden und Neue Abstimmung bleiben in der arbeitsbereichsweiten oberen Leiste, auch bei ausgewählter Abstimmung oder leerem Katalog. Neu laden steht unmittelbar vor Neu. Öffnen, Stimmabgabe, Zertifizierung, Anfechtung und Annullierung bleiben bei der ausgewählten Abstimmung. Neue Abstimmung bleibt ohne Verwaltungsrecht sichtbar, aber deaktiviert. Das gemeinsame Layout verändert weder Wählerschaft noch Zusicherung; die getrennten Verwaltungs-, Stimmabgabe-, Zertifizierungs- und Administrationsrechte bleiben bestehen.",
}}, }},
), ),
DocumentationTopic( DocumentationTopic(
@@ -114,7 +114,7 @@ export default function VotingBallotDialog({
return ( return (
<Dialog <Dialog
open={open} open={open}
title={ballot ? `Edit ${ballot.title}` : "New ballot"} title={ballot ? `Edit ${ballot.title}` : "New ballot"} titleHelp={<DocumentationHelpLink reference={VOTING_FIELD_DOCUMENTATION} />}
onClose={requestClose} onClose={requestClose}
closeDisabled={busy} closeDisabled={busy}
portal portal
@@ -127,7 +127,7 @@ export default function VotingBallotDialog({
</> </>
}> }>
<div className="voting-ballot-editor"> <div className="voting-ballot-editor">
<div className="voting-editor-help"><DocumentationHelpLink reference={VOTING_FIELD_DOCUMENTATION} /></div>
{error && <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert>} {error && <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert>}
<FormGrid columns={2} gap="compact" collapseAt="workspace"> <FormGrid columns={2} gap="compact" collapseAt="workspace">
<FormField label="Title"><input value={draft.title} disabled={busy} onChange={(event) => setDraft({ ...draft, title: event.target.value })} /></FormField> <FormField label="Title"><input value={draft.title} disabled={busy} onChange={(event) => setDraft({ ...draft, title: event.target.value })} /></FormField>
+3 -1
View File
@@ -158,7 +158,9 @@ export default function VotingPage({ settings, auth }: PlatformRouteContext) {
refreshable refreshable
reloadAction={{ onReload: () => void loadList().catch((reason) => setError(message(reason, "Ballots could not be loaded."))), loading: loading || busy, label: "Refresh ballots" }} reloadAction={{ onReload: () => void loadList().catch((reason) => setError(message(reason, "Ballots could not be loaded."))), loading: loading || busy, label: "Refresh ballots" }}
createAction={<Button variant="primary" disabled={!canManage || busy} disabledReason={busy ? VOTING_I18N.busy : !canManage ? VOTING_I18N.manageReason : undefined} onClick={() => setEditing("new")}><Plus size={16} aria-hidden="true" />New ballot</Button>} createAction={<Button variant="primary" disabled={!canManage || busy} disabledReason={busy ? VOTING_I18N.busy : !canManage ? VOTING_I18N.manageReason : undefined} onClick={() => setEditing("new")}><Plus size={16} aria-hidden="true" />New ballot</Button>}
helpAction={<DocumentationHelpLink reference={VOTING_DOCUMENTATION} />} title="Ballots"
titleLevel={1}
titleHelp={<DocumentationHelpLink reference={VOTING_DOCUMENTATION} />}
/> />
<WorkspaceLayout <WorkspaceLayout
variant="split" variant="split"
+2
View File
@@ -1,6 +1,7 @@
import type { PlatformTranslations } from "@govoplan/core-webui"; import type { PlatformTranslations } from "@govoplan/core-webui";
const en = { const en = {
"Ballots": "Ballots",
"i18n:govoplan-voting.voting": "Voting", "i18n:govoplan-voting.voting": "Voting",
"i18n:govoplan-voting.loading_reason": "Ballot data is still loading.", "i18n:govoplan-voting.loading_reason": "Ballot data is still loading.",
"i18n:govoplan-voting.busy_reason": "Another ballot action is still running.", "i18n:govoplan-voting.busy_reason": "Another ballot action is still running.",
@@ -76,6 +77,7 @@ const en = {
} as const; } as const;
const de: Record<keyof typeof en, string> = { const de: Record<keyof typeof en, string> = {
"Ballots": "Abstimmungen",
"i18n:govoplan-voting.voting": "Abstimmungen", "i18n:govoplan-voting.voting": "Abstimmungen",
"i18n:govoplan-voting.loading_reason": "Abstimmungsdaten werden noch geladen.", "i18n:govoplan-voting.loading_reason": "Abstimmungsdaten werden noch geladen.",
"i18n:govoplan-voting.busy_reason": "Eine andere Abstimmungsaktion läuft noch.", "i18n:govoplan-voting.busy_reason": "Eine andere Abstimmungsaktion läuft noch.",