refactor(webui): adopt semantic page actions

This commit is contained in:
2026-08-19 18:47:46 +02:00
parent 89a142ead1
commit ed0357b146
2 changed files with 33 additions and 24 deletions
+23 -15
View File
@@ -6,8 +6,7 @@ import {
useState,
type FormEvent
} from "react";
import { ActionToolbar,
ActionBlockerHint,
import { ActionBlockerHint,
CountBadge,
DismissibleAlert,
Button,
@@ -19,6 +18,7 @@ import { ActionToolbar,
StatusBadge,
ToggleSwitch,
useGuardedNavigate,
WorkspaceActionBar,
WorkspaceFrame,
type PlatformRouteContext
} from "@govoplan/core-webui";
@@ -41,6 +41,7 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
const [launchingId, setLaunchingId] = useState("");
const [reloadKey, setReloadKey] = useState(0);
const launchAttempts = useRef(new Map<string, {
idempotencyKey: string;
requestedAt: string;
@@ -67,7 +68,7 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
}).
finally(() => setLoading(false));
return () => controller.abort();
}, [includeUnavailable, settings, submittedQuery]);
}, [includeUnavailable, reloadKey, settings, submittedQuery]);
useEffect(() => {
const controller = new AbortController();
@@ -79,7 +80,7 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
}
});
return () => controller.abort();
}, [settings]);
}, [reloadKey, settings]);
const counts = useMemo(() => ({
available: services.filter((entry) => entry.state === "available").length,
@@ -131,8 +132,14 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
return (
<main className="portal-page">
<WorkspaceFrame className="portal-shell" label="Service directory" interfaceId="portal.service-directory" helpContextId="portal.page.directory" helpModuleId="portal">
<ActionToolbar surface="panel-header" className="portal-toolbar">
<FilterBar as="form" surface="control" wrap="never" width="wide" className="portal-search" onSubmit={submit}>
<WorkspaceActionBar
scope="workspace"
variant="collection"
refreshable
reloadAction={{ onReload: () => setReloadKey((value) => value + 1), loading }}
className="portal-toolbar"
contextActions={<>
<FilterBar as="form" surface="control" wrap="never" width="wide" className="portal-search" onSubmit={submit}>
<Search size={17} aria-hidden="true" />
<input
value={query}
@@ -141,17 +148,18 @@ export default function PortalPage({ settings }: PlatformRouteContext) {
placeholder="Search services"
/>
<Button type="submit" variant="primary">Search</Button>
</FilterBar>
<DocumentationHelpLink
</FilterBar>
<ToggleSwitch
label="Show unavailable services"
checked={includeUnavailable}
onChange={setIncludeUnavailable}
/>
</>}
helpAction={<DocumentationHelpLink
reference={{ topicId: "portal.service-directory", documentationType: "user" }}
label="Open service directory documentation"
/>
<ToggleSwitch
label="Show unavailable services"
checked={includeUnavailable}
onChange={setIncludeUnavailable}
/>
</ActionToolbar>
/>}
/>
<div className="portal-result-summary" aria-live="polite">
<strong>{counts.available}</strong> available
+10 -9
View File
@@ -1,8 +1,7 @@
import { Clock3, LogIn, RefreshCw, Send } from "lucide-react";
import { Clock3, LogIn, Send } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { useParams, useSearchParams } from "react-router";
import {
ActionToolbar,
Button,
Card,
DescriptionItem,
@@ -12,6 +11,7 @@ import {
LoadingIndicator,
PageScrollViewport,
StatusBadge,
WorkspaceActionBar,
WorkspaceFrame,
type PlatformRouteContext
} from "@govoplan/core-webui";
@@ -101,13 +101,14 @@ export default function PortalStatusPage({ settings }: PlatformRouteContext) {
helpModuleId="portal"
helpTopicId="portal.application-status"
helpContextId="portal.application-status">
<ActionToolbar surface="workspace" className="portal-status-toolbar">
<strong>Application status</strong>
<Button onClick={() => void load()} disabled={loading}>
<RefreshCw size={16} aria-hidden="true" />
Reload
</Button>
</ActionToolbar>
<WorkspaceActionBar
scope="workspace"
variant="detail"
refreshable
reloadAction={{ onReload: () => void load(), loading }}
className="portal-status-toolbar"
contextActions={<strong>Application status</strong>}
/>
<PageScrollViewport className="portal-status-viewport">
{error && <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert>}
{notice && <DismissibleAlert tone="info" resetKey={notice}>{notice}</DismissibleAlert>}