refactor(webui): adopt semantic workspace actions

This commit is contained in:
2026-08-19 18:47:45 +02:00
parent 3f1177abbd
commit bcc6bdd2d7
@@ -14,7 +14,7 @@ import {
useRef,
useState
} from "react";
import { DialogSection, ToolbarGroup, FormGrid, ActionToolbar,
import { DialogSection, FormGrid, ActionToolbar,
ApiError,
Button,
ConfirmDialog,
@@ -38,6 +38,7 @@ import { DialogSection, ToolbarGroup, FormGrid, ActionToolbar,
StatePanel,
StatusBadge,
ToggleSwitch,
WorkspaceActionBar,
WorkspaceFrame,
WorkspaceLayout,
formatDateTime,
@@ -549,27 +550,21 @@ export default function DistributionListsPage({ settings, auth }: Props) {
contentLabel="Distribution list workspace"
contentClassName="dist-lists-workspace"
primary={<>
<ActionToolbar surface="panel-header">
<strong>Distribution Lists</strong>
<span>
<IconButton
label="Refresh"
icon={<RefreshCw size={16} />}
variant="ghost"
disabled={loading || busy}
disabledReason={loading ? DIST_LISTS_I18N.loading : busy ? DIST_LISTS_I18N.busy : undefined}
onClick={() => void reload(selectedId)}
/>
<IconButton
label="New distribution list"
icon={<Plus size={17} />}
variant="primary"
disabled={!canWrite}
disabledReason={!canWrite ? DIST_LISTS_I18N.writeReason : undefined}
onClick={() => requestDiscard(() => setCreateOpen(true))}
/>
</span>
</ActionToolbar>
<WorkspaceActionBar
scope="collection-pane"
variant="collection"
refreshable
reloadAction={{ onReload: () => void reload(selectedId), loading: loading || busy }}
contextActions={<strong>Distribution Lists</strong>}
createAction={<IconButton
label="New distribution list"
icon={<Plus size={17} />}
variant="primary"
disabled={!canWrite}
disabledReason={!canWrite ? DIST_LISTS_I18N.writeReason : undefined}
onClick={() => requestDiscard(() => setCreateOpen(true))}
/>}
/>
<FilterBar surface="panel">
<input
type="search"
@@ -596,14 +591,17 @@ export default function DistributionListsPage({ settings, auth }: Props) {
</LoadingFrame>
</>}
>
<ActionToolbar surface="panel-header" className="dist-lists-workspace-toolbar">
<span className="dist-lists-current-title">
<WorkspaceActionBar
scope="editor-pane"
variant="editor"
state={busy ? "saving" : dirty ? "dirty" : "clean"}
className="dist-lists-workspace-toolbar"
contextActions={<span className="dist-lists-current-title">
<strong>{selected?.name ?? "No distribution list selected"}</strong>
{selected ? <small>Revision {selected.current_revision} · {selected.scope_type} scope</small> : null}
</span>
<ToolbarGroup align="end" className="dist-lists-toolbar-actions">
<DocumentationHelpLink reference={DIST_LISTS_DOCUMENTATION} />
<SegmentedControl<WorkspaceView>
</span>}
helpAction={<DocumentationHelpLink reference={DIST_LISTS_DOCUMENTATION} />}
primaryActions={<SegmentedControl<WorkspaceView>
ariaLabel="Distribution-list workspace"
value={view}
onChange={(next) => next === "snapshots" ? void openSnapshots() : setView(next)}
@@ -612,25 +610,27 @@ export default function DistributionListsPage({ settings, auth }: Props) {
{ id: "preview", label: "Preview" },
{ id: "snapshots", label: "Snapshots" }
]}
/>
<Button
variant="primary"
disabled={!selected || !dirty || busy || !canWrite}
disabledReason={busy ? DIST_LISTS_I18N.busy : !canWrite ? DIST_LISTS_I18N.writeReason : !selected ? DIST_LISTS_I18N.noSelection : !dirty ? DIST_LISTS_I18N.noChanges : undefined}
onClick={() => void saveItem()}
>
<Save size={16} /> Save revision
</Button>
<IconButton
/>}
destructiveActions={<IconButton
label="Delete distribution list"
icon={<Trash2 size={16} />}
variant="danger"
disabled={!selected || !canWrite}
disabledReason={!canWrite ? DIST_LISTS_I18N.writeReason : !selected ? DIST_LISTS_I18N.noSelection : undefined}
onClick={() => setDeleteOpen(true)}
/>
</ToolbarGroup>
</ActionToolbar>
/>}
discardAction={{
label: "Discard changes",
onClick: () => requestDiscard(() => void reload(selectedId)),
disabled: !selected
}}
saveAction={{
label: <><Save size={16} /> Save revision</>,
disabled: !selected || busy || !canWrite,
disabledReason: busy ? DIST_LISTS_I18N.busy : !canWrite ? DIST_LISTS_I18N.writeReason : !selected ? DIST_LISTS_I18N.noSelection : undefined,
onClick: () => void saveItem()
}}
/>
<div className="dist-lists-alerts">
{error ? <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert> : null}