Adopt shared WebUI structural primitives

This commit is contained in:
2026-08-18 13:17:32 +02:00
parent ca30928380
commit df1a7d3bb1
2 changed files with 14 additions and 62 deletions
+12 -8
View File
@@ -8,14 +8,18 @@ import {
} from "react"; } from "react";
import { ActionToolbar, import { ActionToolbar,
ActionBlockerHint, ActionBlockerHint,
CountBadge,
DismissibleAlert, DismissibleAlert,
Button, Button,
DocumentationHelpLink, DocumentationHelpLink,
FilterBar,
LoadingIndicator, LoadingIndicator,
PageScrollViewport, PageScrollViewport,
StatePanel,
StatusBadge, StatusBadge,
ToggleSwitch, ToggleSwitch,
useGuardedNavigate, useGuardedNavigate,
WorkspaceFrame,
type PlatformRouteContext type PlatformRouteContext
} from "@govoplan/core-webui"; } from "@govoplan/core-webui";
import { import {
@@ -126,9 +130,9 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
return ( return (
<main className="portal-page"> <main className="portal-page">
<div className="portal-shell"> <WorkspaceFrame className="portal-shell" label="Service directory" interfaceId="portal.service-directory" helpContextId="portal.page.directory" helpModuleId="portal">
<ActionToolbar className="portal-toolbar"> <ActionToolbar surface="panel-header" className="portal-toolbar">
<form className="portal-search" onSubmit={submit}> <FilterBar as="form" surface="control" wrap="never" width="wide" className="portal-search" onSubmit={submit}>
<Search size={17} aria-hidden="true" /> <Search size={17} aria-hidden="true" />
<input <input
value={query} value={query}
@@ -137,7 +141,7 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
placeholder="Search services" placeholder="Search services"
/> />
<Button type="submit" variant="primary">Search</Button> <Button type="submit" variant="primary">Search</Button>
</form> </FilterBar>
<DocumentationHelpLink <DocumentationHelpLink
reference={{ topicId: "portal.service-directory", documentationType: "user" }} reference={{ topicId: "portal.service-directory", documentationType: "user" }}
label="Open service directory documentation" label="Open service directory documentation"
@@ -183,9 +187,9 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
.join(" / ") || entry.postbox.address} .join(" / ") || entry.postbox.address}
</small> </small>
</span> </span>
<span className="portal-postbox-count" aria-label={`${entry.unread_count} unread messages`}> <CountBadge className="portal-postbox-count" aria-label={`${entry.unread_count} unread messages`}>
{entry.unread_count > 99 ? "99+" : entry.unread_count} {entry.unread_count > 99 ? "99+" : entry.unread_count}
</span> </CountBadge>
<ArrowUpRight size={15} aria-hidden="true" /> <ArrowUpRight size={15} aria-hidden="true" />
</button> </button>
))} ))}
@@ -193,7 +197,7 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
</section> </section>
)} )}
{!loading && !error && services.length === 0 && {!loading && !error && services.length === 0 &&
<div className="portal-empty">No matching services.</div> <StatePanel size="compact" description="No matching services." />
} }
{!loading && services.length > 0 && {!loading && services.length > 0 &&
<div className="portal-service-list"> <div className="portal-service-list">
@@ -208,7 +212,7 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
</div> </div>
} }
</PageScrollViewport> </PageScrollViewport>
</div> </WorkspaceFrame>
</main> </main>
); );
} }
+2 -54
View File
@@ -4,36 +4,7 @@
overflow: hidden; overflow: hidden;
} }
.portal-shell { .portal-search { flex: 1 1 620px; }
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
background: var(--surface);
}
.portal-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
min-height: 58px;
padding: 10px 18px;
border-bottom: 1px solid var(--border);
background: var(--surface-raised);
}
.portal-search {
display: flex;
align-items: center;
gap: 8px;
width: min(620px, 100%);
}
.portal-search input {
min-width: 120px;
flex: 1;
}
.portal-result-summary { .portal-result-summary {
display: flex; display: flex;
@@ -114,13 +85,7 @@
} }
.portal-postbox-count { .portal-postbox-count {
min-width: 24px; flex: 0 0 auto;
padding: 2px 5px;
border-radius: 10px;
background: var(--accent);
color: var(--on-accent);
font-size: 0.75rem;
text-align: center;
} }
.portal-service-entry { .portal-service-entry {
@@ -198,20 +163,3 @@
align-items: center; align-items: center;
gap: 6px; gap: 6px;
} }
.portal-empty {
padding: 36px 0;
color: var(--text-soft);
text-align: center;
}
@media (max-width: 720px) {
.portal-toolbar {
align-items: stretch;
flex-direction: column;
}
.portal-search {
width: 100%;
}
}