refactor(webui): adopt semantic workspace actions
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { DescriptionList } from "@govoplan/core-webui";
|
import { DescriptionList } from "@govoplan/core-webui";
|
||||||
import { Download, FileJson, Play, ShieldCheck } from "lucide-react";
|
import { Download, FileJson, Play, ShieldCheck } from "lucide-react";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { ContentGrid, ActionToolbar,
|
import { ContentGrid,
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
DismissibleAlert,
|
DismissibleAlert,
|
||||||
@@ -9,6 +9,7 @@ import { ContentGrid, ActionToolbar,
|
|||||||
MetricCard,
|
MetricCard,
|
||||||
StatePanel,
|
StatePanel,
|
||||||
StatusBadge,
|
StatusBadge,
|
||||||
|
WorkspaceActionBar,
|
||||||
hasScope,
|
hasScope,
|
||||||
type ApiSettings,
|
type ApiSettings,
|
||||||
type AuthInfo
|
type AuthInfo
|
||||||
@@ -176,15 +177,20 @@ export function ProviderReportWorkspace({ settings, auth, report }: {
|
|||||||
</div>
|
</div>
|
||||||
{execution ?
|
{execution ?
|
||||||
<>
|
<>
|
||||||
<ActionToolbar surface="panel-header" className="reporting-output-toolbar">
|
<WorkspaceActionBar
|
||||||
<span>Generated {formatDateTime(execution.generated_at)}</span>
|
scope="detail-pane"
|
||||||
|
variant="detail"
|
||||||
|
className="reporting-output-toolbar"
|
||||||
|
contextActions={<span>Generated {formatDateTime(execution.generated_at)}</span>}
|
||||||
|
primaryActions={<>
|
||||||
{report.export_formats.includes("csv") &&
|
{report.export_formats.includes("csv") &&
|
||||||
<IconButton label="Download CSV" icon={<Download size={17} />} variant="ghost" onClick={() => void download("csv")} />
|
<IconButton label="Download CSV" icon={<Download size={17} />} variant="ghost" onClick={() => void download("csv")} />
|
||||||
}
|
}
|
||||||
{report.export_formats.includes("json") &&
|
{report.export_formats.includes("json") &&
|
||||||
<IconButton label="Download JSON" icon={<FileJson size={17} />} variant="ghost" onClick={() => void download("json")} />
|
<IconButton label="Download JSON" icon={<FileJson size={17} />} variant="ghost" onClick={() => void download("json")} />
|
||||||
}
|
}
|
||||||
</ActionToolbar>
|
</>}
|
||||||
|
/>
|
||||||
<div className="reporting-provider-output">
|
<div className="reporting-provider-output">
|
||||||
<ProviderResult execution={execution} />
|
<ProviderResult execution={execution} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {
|
|||||||
FolderOutput,
|
FolderOutput,
|
||||||
History,
|
History,
|
||||||
Play,
|
Play,
|
||||||
RefreshCw,
|
|
||||||
Save,
|
Save,
|
||||||
Search,
|
Search,
|
||||||
SlidersHorizontal,
|
SlidersHorizontal,
|
||||||
@@ -19,7 +18,7 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
type FormEvent
|
type FormEvent
|
||||||
} from "react";
|
} from "react";
|
||||||
import { FormGrid, ActionToolbar,
|
import { FormGrid,
|
||||||
Button,
|
Button,
|
||||||
DataGrid,
|
DataGrid,
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -37,6 +36,7 @@ import { FormGrid, ActionToolbar,
|
|||||||
StatusBadge,
|
StatusBadge,
|
||||||
ToggleSwitch,
|
ToggleSwitch,
|
||||||
hasScope,
|
hasScope,
|
||||||
|
WorkspaceActionBar,
|
||||||
WorkspaceFrame,
|
WorkspaceFrame,
|
||||||
type DataGridColumn,
|
type DataGridColumn,
|
||||||
type PlatformRouteContext
|
type PlatformRouteContext
|
||||||
@@ -256,7 +256,13 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
|||||||
return (
|
return (
|
||||||
<main className="reporting-page">
|
<main className="reporting-page">
|
||||||
<WorkspaceFrame className="reporting-shell" label="Reporting workspace" interfaceId="reporting.workspace" helpContextId="reporting.page.workspace" helpModuleId="reporting">
|
<WorkspaceFrame className="reporting-shell" label="Reporting workspace" interfaceId="reporting.workspace" helpContextId="reporting.page.workspace" helpModuleId="reporting">
|
||||||
<ActionToolbar surface="panel-header" className="reporting-toolbar">
|
<WorkspaceActionBar
|
||||||
|
scope="workspace"
|
||||||
|
variant="collection"
|
||||||
|
refreshable
|
||||||
|
reloadAction={{ onReload: () => void reload(), loading, label: "Reload reports" }}
|
||||||
|
className="reporting-toolbar"
|
||||||
|
contextActions={<>
|
||||||
<FilterBar as="form" surface="control" wrap="never" width="compact" className="reporting-search" onSubmit={submitSearch}>
|
<FilterBar as="form" surface="control" wrap="never" width="compact" className="reporting-search" onSubmit={submitSearch}>
|
||||||
<Search size={17} aria-hidden="true" />
|
<Search size={17} aria-hidden="true" />
|
||||||
<input
|
<input
|
||||||
@@ -267,17 +273,12 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
|||||||
/>
|
/>
|
||||||
</FilterBar>
|
</FilterBar>
|
||||||
<span className="reporting-count">{reports.length + providerReports.length} reports</span>
|
<span className="reporting-count">{reports.length + providerReports.length} reports</span>
|
||||||
<DocumentationHelpLink
|
</>}
|
||||||
|
helpAction={<DocumentationHelpLink
|
||||||
reference={{ topicId: "reporting.governed-bi", documentationType: "user" }}
|
reference={{ topicId: "reporting.governed-bi", documentationType: "user" }}
|
||||||
label="Open reporting documentation"
|
label="Open reporting documentation"
|
||||||
|
/>}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
|
||||||
label="Reload reports"
|
|
||||||
icon={<RefreshCw size={17} />}
|
|
||||||
variant="ghost"
|
|
||||||
onClick={() => void reload()}
|
|
||||||
/>
|
|
||||||
</ActionToolbar>
|
|
||||||
{error &&
|
{error &&
|
||||||
<DismissibleAlert tone="danger" resetKey={error}>
|
<DismissibleAlert tone="danger" resetKey={error}>
|
||||||
{error}
|
{error}
|
||||||
@@ -345,8 +346,11 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
|||||||
onQueryChange={setQuery}
|
onQueryChange={setQuery}
|
||||||
onParametersChange={setParameters}
|
onParametersChange={setParameters}
|
||||||
/>
|
/>
|
||||||
<ActionToolbar surface="panel-header" className="reporting-output-toolbar">
|
<WorkspaceActionBar
|
||||||
<SegmentedControl
|
scope="detail-pane"
|
||||||
|
variant="detail"
|
||||||
|
className="reporting-output-toolbar"
|
||||||
|
contextActions={<SegmentedControl
|
||||||
ariaLabel="Report output"
|
ariaLabel="Report output"
|
||||||
value={outputMode}
|
value={outputMode}
|
||||||
onChange={setOutputMode}
|
onChange={setOutputMode}
|
||||||
@@ -354,8 +358,8 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
|||||||
{ id: "visual", label: <><BarChart3 size={15} /> Visual</> },
|
{ id: "visual", label: <><BarChart3 size={15} /> Visual</> },
|
||||||
{ id: "table", label: <><Table2 size={15} /> Table</> }
|
{ id: "table", label: <><Table2 size={15} /> Table</> }
|
||||||
]}
|
]}
|
||||||
/>
|
/>}
|
||||||
{execution &&
|
primaryActions={execution ?
|
||||||
<>
|
<>
|
||||||
<span>{execution.total_rows} rows{execution.truncated ? " (truncated)" : ""}</span>
|
<span>{execution.total_rows} rows{execution.truncated ? " (truncated)" : ""}</span>
|
||||||
<IconButton label="Download CSV" icon={<Download size={17} />} variant="ghost" onClick={() => void downloadExecution(settings, execution.execution_id, "csv").catch((reason) => setError(message(reason)))} />
|
<IconButton label="Download CSV" icon={<Download size={17} />} variant="ghost" onClick={() => void downloadExecution(settings, execution.execution_id, "csv").catch((reason) => setError(message(reason)))} />
|
||||||
@@ -364,8 +368,8 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
|||||||
<IconButton label="Publish report" icon={<FolderOutput size={17} />} variant="ghost" onClick={() => setPublishDialogOpen(true)} />
|
<IconButton label="Publish report" icon={<FolderOutput size={17} />} variant="ghost" onClick={() => setPublishDialogOpen(true)} />
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
}
|
: undefined}
|
||||||
</ActionToolbar>
|
/>
|
||||||
<div className="reporting-output">
|
<div className="reporting-output">
|
||||||
{!execution && <StatePanel size="fill" description="Run the report or select a previous execution." />}
|
{!execution && <StatePanel size="fill" description="Run the report or select a previous execution." />}
|
||||||
{execution && outputMode === "visual" && <ReportVisual execution={execution} onDrill={execution.query.mode === "detail" ? undefined : drill} />}
|
{execution && outputMode === "visual" && <ReportVisual execution={execution} onDrill={execution.query.mode === "detail" ? undefined : drill} />}
|
||||||
|
|||||||
Reference in New Issue
Block a user