Docker images / prepare-release (push) Successful in 10s
Docker images / backend-test (push) Successful in 2m23s
Docker images / frontend-image (push) Successful in 3m30s
Docker images / updater-image (push) Successful in 52s
Docker images / backend-image (push) Successful in 3m8s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 14s
Сопоставить клиентов с ifIndex как на карте трафика, чтобы KPI пользователей не обнулялся. На экране — разрез остальных измерений и сводная матрица. Co-authored-by: Cursor <[email protected]>
74 lines
2.2 KiB
TypeScript
74 lines
2.2 KiB
TypeScript
"use client"
|
|
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/components/ui/select"
|
|
import { STATISTICS_DIMS } from "@/lib/statistics-dims"
|
|
import type { StatisticsPivotDim } from "@mmapp/contracts/statistics"
|
|
import type { StatisticsSliceKind } from "@/components/data-grids/statistics-breakdown-data-grid"
|
|
|
|
export function DimensionSelect({
|
|
value,
|
|
onChange,
|
|
label,
|
|
}: {
|
|
value: StatisticsSliceKind
|
|
onChange: (value: StatisticsSliceKind) => void
|
|
label?: string
|
|
}) {
|
|
const current = STATISTICS_DIMS.find((d) => d.id === value)
|
|
return (
|
|
<label className="flex items-center gap-2">
|
|
{label ? <span className="text-muted-foreground text-xs whitespace-nowrap">{label}</span> : null}
|
|
<Select value={value} onValueChange={(v) => onChange(String(v ?? value) as StatisticsSliceKind)}>
|
|
<SelectTrigger size="sm" className="min-w-40">
|
|
<SelectValue>{current?.label ?? "Измерение"}</SelectValue>
|
|
</SelectTrigger>
|
|
<SelectContent align="start">
|
|
{STATISTICS_DIMS.map((d) => (
|
|
<SelectItem key={d.id} value={d.id}>
|
|
{d.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</label>
|
|
)
|
|
}
|
|
|
|
export function PivotDimSelect({
|
|
value,
|
|
onChange,
|
|
exclude,
|
|
label,
|
|
}: {
|
|
value: StatisticsPivotDim
|
|
onChange: (value: StatisticsPivotDim) => void
|
|
exclude?: StatisticsPivotDim
|
|
label: string
|
|
}) {
|
|
const options = STATISTICS_DIMS.filter((d) => d.pivot !== exclude)
|
|
const current = STATISTICS_DIMS.find((d) => d.pivot === value)
|
|
return (
|
|
<label className="flex items-center gap-2">
|
|
<span className="text-muted-foreground text-xs whitespace-nowrap">{label}</span>
|
|
<Select value={value} onValueChange={(v) => onChange(String(v ?? value) as StatisticsPivotDim)}>
|
|
<SelectTrigger size="sm" className="min-w-40">
|
|
<SelectValue>{current?.label ?? label}</SelectValue>
|
|
</SelectTrigger>
|
|
<SelectContent align="start">
|
|
{options.map((d) => (
|
|
<SelectItem key={d.pivot} value={d.pivot}>
|
|
{d.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</label>
|
|
)
|
|
}
|