Files
app/frontend/src/components/Common/RangePicker.tsx
T
stroblme 9d11e01a48 Point the range picker at the shared segmented control
RangePicker carried a byte-for-byte copy of ui/segmented.tsx's markup; it
now renders that component instead.

The dashboard's own segmented widget stays where it is: it is not a copy
but a look-aware control, drawn per look in
Dashboard/ui/{fluksio,glass,material}/Controls.tsx over the shared
useSegmented behaviour. Note that in segmented.tsx in place of the stale
size-prop plan.
2026-08-28 18:49:29 +02:00

63 lines
1.8 KiB
TypeScript

import { Segmented } from "@/components/ui/segmented"
/**
* A window of history, and everything a query needs to ask for it.
*
* `bucketS` keeps the number of points a chart draws roughly constant: a week
* of minute buckets is ten thousand readings nobody can see and a megabyte of
* JSON every refresh, so the longer windows are folded coarser server-side.
*/
export type Range = { label: string; hours: number; bucketS: number }
/**
* The windows on offer.
*
* Bounded by what the collector keeps: it prunes buckets, failures and runs at
* `OBS_RETENTION_DAYS` (30 by default), so a week is behind the last preset
* rather than an empty chart.
*/
export const RANGES: Range[] = [
{ label: "1h", hours: 1, bucketS: 60 },
{ label: "6h", hours: 6, bucketS: 60 },
{ label: "24h", hours: 24, bucketS: 60 },
{ label: "7d", hours: 168, bucketS: 900 },
]
/** A day: long enough to hold a night's worth of trouble, short enough to read. */
export const DEFAULT_RANGE = RANGES[2]
/**
* Where the window starts, as the stamp the history endpoints take.
*
* Read at fetch time rather than when the options are built, so the window
* slides with the clock instead of freezing where the screen opened.
*/
export const rangeStart = (range: Range) =>
new Date(Date.now() - range.hours * 3600_000).toISOString()
/** The window a screen is showing, as presets. */
export function RangePicker({
value,
onChange,
}: {
value: Range
onChange: (range: Range) => void
}) {
return (
<Segmented
testId="range-picker"
label="Time range"
value={String(value.hours)}
options={RANGES.map(
(range) => [String(range.hours), range.label] as const,
)}
onChange={(hours) =>
onChange(
RANGES.find((range) => String(range.hours) === hours) ??
DEFAULT_RANGE,
)
}
/>
)
}