Adopt semantic dashboard action states

This commit is contained in:
2026-08-19 14:26:26 +02:00
parent d0df0b146f
commit c8a7a155aa
2 changed files with 40 additions and 43 deletions
+4 -1
View File
@@ -156,7 +156,10 @@ manifest = ModuleManifest(
body=( body=(
"A Dashboard layout belongs to the active tenant, account, and focused View. " "A Dashboard layout belongs to the active tenant, account, and focused View. "
"Configuring changes only a local draft until Save layout is selected; Cancel or " "Configuring changes only a local draft until Save layout is selected; Cancel or "
"Discard restores the last saved arrangement. Widget removal removes only the placement, " "Discard restores the last saved arrangement. The page action bar always reports whether "
"the draft is saved, unsaved, or currently saving; Save and Cancel remain visible in stable "
"positions and are disabled with an explanation when no draft change exists. Leaving while "
"dirty invokes the shared save-or-discard guard. Widget removal removes only the placement, "
"not the module data represented by the widget. Reset restores the defaults announced by " "not the module data represented by the widget. Reset restores the defaults announced by "
"currently active modules and remains reversible until save. A widget is offered only when " "currently active modules and remains reversible until save. A widget is offered only when "
"its module, focused View surface, and permission contract are available. Widgets never grant " "its module, focused View surface, and permission contract are available. Widgets never grant "
+20 -26
View File
@@ -16,6 +16,7 @@ import {
DocumentationHelpLink, DocumentationHelpLink,
LoadingFrame, LoadingFrame,
MetricCard, MetricCard,
PageActionBar,
PageLayout, PageLayout,
dashboardWidgetsForModules, dashboardWidgetsForModules,
hasAnyScope, hasAnyScope,
@@ -443,16 +444,26 @@ export default function DashboardPage({
return ( return (
<PageLayout <PageLayout
archetype={configuring ? "editor" : "overview"}
className="dashboard-page" className="dashboard-page"
title="i18n:govoplan-dashboard.dashboard.3f8b4df2" title="i18n:govoplan-dashboard.dashboard.3f8b4df2"
description="Personal workspace assembled from installed module widgets." description="Personal workspace assembled from installed module widgets."
error={error} error={error}
success={error ? "" : notice} success={error ? "" : notice}
actions={ actions={configuring ? (
<> <PageActionBar
<DocumentationHelpLink reference={DASHBOARD_DOCUMENTATION} /> variant="editor"
{!configuring && ( dirty={dirty}
<> saving={saving}
helpAction={<DocumentationHelpLink reference={DASHBOARD_DOCUMENTATION} />}
discardAction={{ label: <><X size={16} /> Cancel</>, onClick: discardChanges }}
saveAction={{ label: <><Save size={16} /> Save layout</>, onClick: () => void persistLayout() }}
/>
) : (
<PageActionBar
variant="overview"
refreshable
reloadAction={(
<Button <Button
onClick={() => setRefreshKey((value) => value + 1)} onClick={() => setRefreshKey((value) => value + 1)}
disabled={loading} disabled={loading}
@@ -460,6 +471,9 @@ export default function DashboardPage({
> >
<RefreshCw size={16} /> Refresh <RefreshCw size={16} /> Refresh
</Button> </Button>
)}
helpAction={<DocumentationHelpLink reference={DASHBOARD_DOCUMENTATION} />}
primaryActions={(
<Button <Button
onClick={beginConfiguration} onClick={beginConfiguration}
disabled={loading} disabled={loading}
@@ -467,29 +481,9 @@ export default function DashboardPage({
> >
<SlidersHorizontal size={16} /> Configure <SlidersHorizontal size={16} /> Configure
</Button> </Button>
</>
)} )}
{configuring && ( />
<>
<Button
onClick={discardChanges}
disabled={saving}
disabledReason={saving ? DASHBOARD_I18N.saving : undefined}
>
<X size={16} /> Cancel
</Button>
<Button
variant="primary"
onClick={() => void persistLayout()}
disabled={saving || !dirty}
disabledReason={saving ? DASHBOARD_I18N.saving : !dirty ? DASHBOARD_I18N.noChanges : undefined}
>
<Save size={16} /> {saving ? "Saving..." : "Save layout"}
</Button>
</>
)} )}
</>
}
> >
<MetricGrid className="dashboard-summary-metrics"> <MetricGrid className="dashboard-summary-metrics">