refactor(webui): adopt semantic workspace actions

This commit is contained in:
2026-08-19 18:47:45 +02:00
parent 178d08c729
commit 0d7d18c486
+21 -15
View File
@@ -1,7 +1,6 @@
import { Download, Pencil, Plus, RefreshCw, Search, Upload } from "lucide-react";
import { Download, Pencil, Plus, Search, Upload } from "lucide-react";
import { useCallback, useEffect, useRef, useState, type FormEvent } from "react";
import { ActionToolbar,
ActionBlockerHint,
import { ActionBlockerHint,
Button,
Dialog,
DocumentationHelpLink,
@@ -16,6 +15,7 @@ import { ActionToolbar,
hasScope,
useUnsavedChanges,
useUnsavedDraftGuard,
WorkspaceActionBar,
WorkspaceFrame,
type PlatformRouteContext
} from "@govoplan/core-webui";
@@ -148,13 +148,19 @@ export default function FormsPage({ settings, auth }: PlatformRouteContext) {
return (
<main className="forms-page">
<WorkspaceFrame className="forms-shell" label="Form definitions" interfaceId="forms.catalogue" helpContextId="forms.page.catalogue" helpModuleId="forms">
<ActionToolbar surface="panel-header" className="forms-toolbar">
<FilterBar as="form" surface="control" wrap="never" width="default" onSubmit={search} className="forms-search">
<WorkspaceActionBar
scope="workspace"
variant="collection"
refreshable
reloadAction={{ onReload: () => void load(), loading, label: "Refresh definitions" }}
className="forms-toolbar"
contextActions={<>
<FilterBar as="form" surface="control" wrap="never" width="default" onSubmit={search} className="forms-search">
<Search size={17} aria-hidden="true" />
<input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search definitions" aria-label="Search Form definitions" />
<Button type="submit">Search</Button>
</FilterBar>
<label>
</FilterBar>
<label>
<span>State</span>
<select value={state} onChange={(event) => setState(event.target.value)}>
<option value="">All</option>
@@ -162,14 +168,14 @@ export default function FormsPage({ settings, auth }: PlatformRouteContext) {
<option value="published">Published</option>
<option value="retired">Retired</option>
</select>
</label>
<IconButton label="Refresh definitions" icon={<RefreshCw size={16} />} onClick={() => void load()} disabled={loading} disabledReason={loading ? FORMS_I18N.loading : undefined} />
<IconButton label="Import Form package" icon={<Upload size={16} />} onClick={() => importInput.current?.click()} disabled={loading || !canWrite} disabledReason={loading ? FORMS_I18N.loading : !canWrite ? FORMS_I18N.writeReason : undefined} />
<input ref={importInput} className="forms-hidden-input" type="file" accept="application/json,.json" onChange={(event) => void choosePackage(event.target.files?.[0])} />
<Button variant="primary" disabled={!canWrite} disabledReason={!canWrite ? FORMS_I18N.writeReason : undefined} onClick={() => setEditing("new")}><Plus size={16} aria-hidden="true" />New definition</Button>
<span className="forms-count">{total}</span>
<DocumentationHelpLink reference={FORMS_DOCUMENTATION} />
</ActionToolbar>
</label>
<IconButton label="Import Form package" icon={<Upload size={16} />} onClick={() => importInput.current?.click()} disabled={loading || !canWrite} disabledReason={loading ? FORMS_I18N.loading : !canWrite ? FORMS_I18N.writeReason : undefined} />
<input ref={importInput} className="forms-hidden-input" type="file" accept="application/json,.json" onChange={(event) => void choosePackage(event.target.files?.[0])} />
<span className="forms-count">{total}</span>
</>}
createAction={<Button variant="primary" disabled={!canWrite} disabledReason={!canWrite ? FORMS_I18N.writeReason : undefined} onClick={() => setEditing("new")}><Plus size={16} aria-hidden="true" />New definition</Button>}
helpAction={<DocumentationHelpLink reference={FORMS_DOCUMENTATION} />}
/>
<PageScrollViewport className="forms-list-viewport">
{error && <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert>}
{!canWrite && <ActionBlockerHint tone="info" reason={{ summary: "No Form management permission", details: FORMS_I18N.writeReason, requiredAction: FORMS_I18N.permissionAction, actor: FORMS_I18N.permissionActor, target: FORMS_I18N.permissionDestination }} labels={{ requiredAction: FORMS_I18N.requiredAction, actor: FORMS_I18N.actor, target: FORMS_I18N.destination }} documentation={FORMS_DOCUMENTATION} />}