From dc9fdc9143485dfbaa6ea816e1cbae781766ed6b Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Tue, 18 Aug 2026 13:17:32 +0200 Subject: [PATCH] Adopt shared WebUI structural primitives --- webui/src/features/voting/VotingPage.tsx | 74 ++++++++++++++--------- webui/src/styles/voting.css | 77 ------------------------ 2 files changed, 44 insertions(+), 107 deletions(-) diff --git a/webui/src/features/voting/VotingPage.tsx b/webui/src/features/voting/VotingPage.tsx index 68586c5..d412d61 100644 --- a/webui/src/features/voting/VotingPage.tsx +++ b/webui/src/features/voting/VotingPage.tsx @@ -10,8 +10,15 @@ import { ActionToolbar, FormField, IconButton, LoadingIndicator, + MetricCard, + MetricGrid, PageScrollViewport, + SelectionList, + SelectionListItem, + SelectionListItemContent, + StatePanel, StatusBadge, + WorkspaceLayout, hasScope, i18nMessage, usePlatformLanguage, @@ -144,28 +151,40 @@ export default function VotingPage({ settings, auth }: PlatformRouteContext) { return (
-
- -
+ } + > {error && {error}} {notice && {notice}} - {!selected && !loading &&
Select a ballot.
} + {!selected && !loading && } {selected &&

{selected.title}

Revision {selected.revision}
@@ -179,12 +198,12 @@ export default function VotingPage({ settings, auth }: PlatformRouteContext) { {selected.state !== "annulled" && }
-
- - total + item.weight, 0)} /> - - -
+ + + total + item.weight, 0)} /> + + + {selected.description &&

{selected.description}

} {selected.state === "open" && selected.assurance_profile === "recorded" && canCast && eligible &&

Cast vote

@@ -215,12 +234,12 @@ export default function VotingPage({ settings, auth }: PlatformRouteContext) {
{selected.result &&

Result

-
- - - - -
+ + + + + +
}
@@ -235,8 +254,7 @@ export default function VotingPage({ settings, auth }: PlatformRouteContext) {
} - - + {editing && {label}{value}; -} - function Hash({ label, value }: { label: string; value?: string | null }) { return
{label}{value || "Not frozen"}
; } diff --git a/webui/src/styles/voting.css b/webui/src/styles/voting.css index 2409b6f..9357d90 100644 --- a/webui/src/styles/voting.css +++ b/webui/src/styles/voting.css @@ -4,22 +4,12 @@ overflow: hidden; } -.voting-shell { - display: grid; - grid-template-columns: minmax(250px, 320px) minmax(0, 1fr); - min-height: 0; - height: 100%; - background: var(--surface, #fff); -} - .voting-catalogue { display: flex; min-height: 0; flex-direction: column; - border-right: 1px solid var(--border-color, #d8dde3); } -.voting-toolbar, .voting-detail-heading, .voting-actions, .voting-editor-heading { @@ -28,52 +18,18 @@ gap: 8px; } -.voting-toolbar { - min-height: 50px; - padding: 8px 12px; - border-bottom: 1px solid var(--border-color, #d8dde3); -} - .voting-list-viewport, .voting-detail-viewport { min-height: 0; flex: 1; } -.voting-list { - display: flex; - flex-direction: column; - padding: 6px; -} - -.voting-list-row { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - align-items: center; - gap: 8px; - width: 100%; - min-height: 52px; - padding: 7px 8px; - border: 0; - background: transparent; - color: inherit; - text-align: left; - cursor: pointer; -} - -.voting-list-row:hover, -.voting-list-row.is-selected { - background: var(--hover-bg, rgba(54, 99, 135, 0.1)); -} - -.voting-list-row > span:first-child, .voting-option-results > div > span:first-child { display: flex; min-width: 0; flex-direction: column; } -.voting-list-row small, .voting-option-results small { color: var(--text-muted, #65717e); } @@ -118,23 +74,6 @@ justify-content: flex-end; } -.voting-metrics { - display: grid; - grid-template-columns: repeat(4, minmax(110px, 1fr)); - gap: 10px; - margin: 16px 0; -} - -.voting-metrics > div { - display: flex; - min-width: 0; - flex-direction: column; - padding: 10px 12px; - border: 1px solid var(--border-color, #d8dde3); - border-radius: 4px; -} - -.voting-metrics span, .voting-hash span { color: var(--text-muted, #65717e); font-size: 0.75rem; @@ -200,11 +139,6 @@ text-overflow: ellipsis; } -.voting-empty { - padding: 24px; - color: var(--text-muted, #65717e); -} - .voting-ballot-dialog { height: min(820px, calc(100vh - 32px)); } @@ -256,17 +190,6 @@ } @media (max-width: 800px) { - .voting-shell { - grid-template-columns: 1fr; - grid-template-rows: minmax(160px, 34%) minmax(0, 1fr); - } - - .voting-catalogue { - border-right: 0; - border-bottom: 1px solid var(--border-color, #d8dde3); - } - - .voting-metrics, .voting-option-row, .voting-elector-row { grid-template-columns: 1fr;