Adopt shared WebUI layout primitives
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Download, FileJson, Play, ShieldCheck } from "lucide-react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
import { ContentGrid, ActionToolbar,
|
||||
Button,
|
||||
Card,
|
||||
DismissibleAlert,
|
||||
@@ -174,7 +174,7 @@ export function ProviderReportWorkspace({ settings, auth, report }: {
|
||||
</div>
|
||||
{execution ?
|
||||
<>
|
||||
<div className="reporting-output-toolbar">
|
||||
<ActionToolbar className="reporting-output-toolbar">
|
||||
<span>Generated {formatDateTime(execution.generated_at)}</span>
|
||||
{report.export_formats.includes("csv") &&
|
||||
<IconButton label="Download CSV" icon={<Download size={17} />} variant="ghost" onClick={() => void download("csv")} />
|
||||
@@ -182,7 +182,7 @@ export function ProviderReportWorkspace({ settings, auth, report }: {
|
||||
{report.export_formats.includes("json") &&
|
||||
<IconButton label="Download JSON" icon={<FileJson size={17} />} variant="ghost" onClick={() => void download("json")} />
|
||||
}
|
||||
</div>
|
||||
</ActionToolbar>
|
||||
<div className="reporting-provider-output">
|
||||
<ProviderResult execution={execution} />
|
||||
</div>
|
||||
@@ -227,11 +227,11 @@ function ProviderResult({ execution }: { execution: ProviderReportExecution }) {
|
||||
return (
|
||||
<Card title={group} key={group}>
|
||||
{metrics.length > 0 &&
|
||||
<div className="dashboard-grid reporting-provider-metrics">
|
||||
<ContentGrid columns={2} collapseAt="workspace" className="reporting-provider-metrics">
|
||||
{metrics.map((field) =>
|
||||
<MetricCard key={field.path} label={field.label} value={displayValue(pathValue(execution.result, field.path))} />
|
||||
)}
|
||||
</div>
|
||||
</ContentGrid>
|
||||
}
|
||||
{details.length > 0 &&
|
||||
<dl className="detail-list">
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
useState,
|
||||
type FormEvent
|
||||
} from "react";
|
||||
import {
|
||||
import { FormGrid, ActionToolbar,
|
||||
Button,
|
||||
DataGrid,
|
||||
Dialog,
|
||||
@@ -250,7 +250,7 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
||||
return (
|
||||
<main className="reporting-page">
|
||||
<div className="reporting-shell">
|
||||
<div className="reporting-toolbar">
|
||||
<ActionToolbar className="reporting-toolbar">
|
||||
<form className="reporting-search" onSubmit={submitSearch}>
|
||||
<Search size={17} aria-hidden="true" />
|
||||
<input
|
||||
@@ -271,7 +271,7 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
||||
variant="ghost"
|
||||
onClick={() => void reload()}
|
||||
/>
|
||||
</div>
|
||||
</ActionToolbar>
|
||||
{error &&
|
||||
<DismissibleAlert tone="danger" resetKey={error}>
|
||||
{error}
|
||||
@@ -345,7 +345,7 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
||||
onQueryChange={setQuery}
|
||||
onParametersChange={setParameters}
|
||||
/>
|
||||
<div className="reporting-output-toolbar">
|
||||
<ActionToolbar className="reporting-output-toolbar">
|
||||
<SegmentedControl
|
||||
ariaLabel="Report output"
|
||||
value={outputMode}
|
||||
@@ -365,7 +365,7 @@ export default function ReportingPage({ settings, auth }: PlatformRouteContext)
|
||||
}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</ActionToolbar>
|
||||
<div className="reporting-output">
|
||||
{!execution && <div className="reporting-empty">Run the report or select a previous execution.</div>}
|
||||
{execution && outputMode === "visual" && <ReportVisual execution={execution} onDrill={execution.query.mode === "detail" ? undefined : drill} />}
|
||||
@@ -757,7 +757,7 @@ function PublishDialog({ open, targets, onClose, onPublish }: {
|
||||
</Button>
|
||||
</>}>
|
||||
{dialogError && <DismissibleAlert tone="danger" resetKey={dialogError}>{dialogError}</DismissibleAlert>}
|
||||
<div className="reporting-dialog-grid">
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow">
|
||||
<label className="reporting-dialog-field">
|
||||
<span>Target</span>
|
||||
<select value={targetCapability} onChange={(event) => {
|
||||
@@ -784,7 +784,7 @@ function PublishDialog({ open, targets, onClose, onPublish }: {
|
||||
<label className="reporting-dialog-field"><span>Sender address</span><input type="email" value={fromAddress} onChange={(event) => setFromAddress(event.target.value)} /></label>
|
||||
<label className="reporting-dialog-field reporting-dialog-span"><span>Subject</span><input value={subject} onChange={(event) => setSubject(event.target.value)} placeholder="Generated from report name" /></label>
|
||||
</>}
|
||||
</div>
|
||||
</FormGrid>
|
||||
{target?.reason && <DismissibleAlert tone="warning" dismissible={false}>{target.reason}</DismissibleAlert>}
|
||||
</Dialog>
|
||||
);
|
||||
@@ -936,10 +936,10 @@ function ScheduleDialog({ open, onClose, onSave }: { open: boolean; onClose: ()
|
||||
<Button onClick={onClose}>Cancel</Button>
|
||||
<Button variant="primary" disabled={!name.trim() || saving} onClick={() => { setSaving(true); void onSave(name.trim(), Number(interval)).finally(() => setSaving(false)); }}>Schedule</Button>
|
||||
</>}>
|
||||
<div className="reporting-dialog-grid">
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow">
|
||||
<label className="reporting-dialog-field"><span>Name</span><input value={name} onChange={(event) => setName(event.target.value)} autoFocus /></label>
|
||||
<label className="reporting-dialog-field"><span>Interval</span><select value={interval} onChange={(event) => setIntervalValue(event.target.value)}><option value="3600">Hourly</option><option value="86400">Daily</option><option value="604800">Weekly</option><option value="2592000">Every 30 days</option></select></label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user