diff --git a/tickets/009-all-dashboards-print-friendly-view.md b/tickets/009-all-dashboards-print-friendly-view.md deleted file mode 100644 index 8215b50..0000000 --- a/tickets/009-all-dashboards-print-friendly-view.md +++ /dev/null @@ -1,9 +0,0 @@ -# Add "All dashboards" option with print-friendly stacked layout - -The dashboards part should keep the click-to-select dashboards, however it should have an "All dashboards" option. In that situation, the dashboards are displayed one after another with named separators. This is important so that it is possible to print the page or print the dashboards section. Printing itself is a browser capability we don't need to implement, but the page should be laid out in a way that's compatible with it. - -## Acceptance criteria -- Existing click-to-select single-dashboard view is preserved. -- New "All dashboards" option stacks all dashboards vertically, one after another, each preceded by a named separator (dashboard name/title). -- The stacked layout uses normal document flow (no fixed-height scroll containers that would clip content) so the browser's native print function can render the full stacked content across pages. -- Verified visually in browser, including a print-preview check. diff --git a/webapp/src/components/Dashboards.tsx b/webapp/src/components/Dashboards.tsx index fbe9bf8..4b5ec57 100644 --- a/webapp/src/components/Dashboards.tsx +++ b/webapp/src/components/Dashboards.tsx @@ -26,6 +26,9 @@ import { HelpIcon } from './HelpIcon' const CHART_TYPES: ChartType[] = ['line', 'bar', 'pie'] +/// Virtual selection id for the "All dashboards" stacked/print view; distinct from any real dashboard id. +const ALL_DASHBOARDS_ID = '__all__' + /// Long enough that rapid typing doesn't spam the save endpoint, short enough that a pause reads as "done" and commits promptly. const AUTOSAVE_DEBOUNCE_MS = 600 @@ -96,6 +99,36 @@ function AutosaveStatus({ status, error }: { status: SaveStatus; error: string | return null } +/// Read-only, print-friendly view of every dashboard stacked one after another, each preceded by a heading naming it. +/// Deliberately uses normal document flow (no scroll containers, no fixed heights) so the browser's native print +/// function can lay the full stack out across as many pages as it needs. +function AllDashboardsView({ dashboards, range }: { dashboards: Dashboard[]; range: TimeRange | null }) { + if (dashboards.length === 0) { + return
No dashboards saved yet.
+ } + return ( +
+ {dashboards.map((d) => ( +
+

{d.name}

+ {d.panels.length === 0 ? ( +
No panels in this dashboard.
+ ) : ( +
+ {d.panels.map((panel) => ( +
+ {panel.title &&
{panel.title}
} + +
+ ))} +
+ )} +
+ ))} +
+ ) +} + export function Dashboards({ range }: { range: TimeRange | null }) { const [activeProfile, setActiveProfile] = useState(null) const [dashboards, setDashboards] = useState([]) @@ -281,6 +314,19 @@ export function Dashboards({ range }: { range: TimeRange | null }) {
+ {dashboards.length > 0 && ( + + )} {dashboards.length === 0 &&
No dashboards saved yet.
} {dashboards.map((d) => (
- {!draft ? ( + {selectedId === ALL_DASHBOARDS_ID ? ( + + ) : !draft ? (
Select or create a dashboard to edit its panels.
) : (