| 1 | /** |
| 2 | * Typed view of the Axiom dashboard chart-JSON subset. |
| 3 | * |
| 4 | * Axiom's `CreateDashboardInput` declares |
| 5 | * `dashboard.charts: ReadonlyArray<unknown>` (see |
| 6 | * `@distilled.cloud/axiom/.../v2/createDashboard.ts`); these |
| 7 | * interfaces give callers compile-time safety when building the |
| 8 | * payload by hand. |
| 9 | * |
| 10 | * `chart.id` is a free-form string the author picks — Axiom |
| 11 | * doesn't validate the format. It joins to the matching |
| 12 | * `LayoutCell.i` in `dashboard.layout`. |
| 13 | */ |
| 14 | |
| 15 | /** |
| 16 | * Axiom-validated chart kinds. Discovered by probing |
| 17 | * `POST /v2/dashboards`: anything else returns |
| 18 | * `dashboard validation failed at [charts N type]: Invalid input`. |
| 19 | */ |
| 20 | export type ChartKind = |
| 21 | | "TimeSeries" |
| 22 | | "Table" |
| 23 | | "Pie" |
| 24 | | "Statistic" |
| 25 | | "Heatmap" |
| 26 | | "LogStream" |
| 27 | | "Note" |
| 28 | | "SmartFilter"; |
| 29 | |
| 30 | /** |
| 31 | * Minimum chart payload Axiom's `POST /v2/dashboards` accepts. |
| 32 | * Any unknown keys (e.g. `dataset`, `description`) trigger |
| 33 | * `Unrecognized keys: "<name>"`, so this struct is intentionally |
| 34 | * narrow. The dataset is implicit via the APL query. |
| 35 | */ |
| 36 | export interface BaseChart { |
| 37 | readonly id: string; |
| 38 | readonly name: string; |
| 39 | readonly type: ChartKind; |
| 40 | readonly query: { readonly apl: string }; |
| 41 | } |
| 42 | |
| 43 | export interface TimeSeriesChart extends BaseChart { |
| 44 | readonly type: "TimeSeries"; |
| 45 | } |
| 46 | |
| 47 | export interface TableChart extends BaseChart { |
| 48 | readonly type: "Table"; |
| 49 | } |
| 50 | |
| 51 | export interface PieChart extends BaseChart { |
| 52 | readonly type: "Pie"; |
| 53 | } |
| 54 | |
| 55 | export interface StatisticChart extends BaseChart { |
| 56 | readonly type: "Statistic"; |
| 57 | } |
| 58 | |
| 59 | export interface HeatmapChart extends BaseChart { |
| 60 | readonly type: "Heatmap"; |
| 61 | } |
| 62 | |
| 63 | export interface LogStreamChart extends BaseChart { |
| 64 | readonly type: "LogStream"; |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * A free-form markdown note. Unlike data charts, `Note` has no `query` |
| 69 | * or `name` — Axiom's payload is strictly `{ id, type, text, variant? }`. |
| 70 | */ |
| 71 | export interface NoteChart { |
| 72 | readonly id: string; |
| 73 | readonly type: "Note"; |
| 74 | /** Markdown body rendered in the note cell. */ |
| 75 | readonly text: string; |
| 76 | readonly variant?: "default"; |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * A dashboard filter bar (Axiom calls it `SmartFilter` on the wire, |
| 81 | * `Filter bar` in the UI). Holds one or more filters whose IDs can |
| 82 | * be referenced from other charts' APL via |
| 83 | * `declare query_parameters (<filter-id>:string = "")`. |
| 84 | * |
| 85 | * Unlike data charts, `SmartFilter` has no top-level `query` field — |
| 86 | * each filter inside `filters` may carry its own option-source APL. |
| 87 | */ |
| 88 | export interface SmartFilterChart { |
| 89 | readonly id: string; |
| 90 | readonly type: "SmartFilter"; |
| 91 | /** Optional display name for the filter bar element. */ |
| 92 | readonly name?: string; |
| 93 | readonly filters: readonly SmartFilter[]; |
| 94 | } |
| 95 | |
| 96 | /** |
| 97 | * One filter inside a {@link SmartFilterChart}. Either a free-text |
| 98 | * `search` filter or a dropdown `select` filter. Select filters draw |
| 99 | * their options from either an inline `list` or an APL `query`. |
| 100 | */ |
| 101 | export type SmartFilter = SmartFilterSearch | SmartFilterSelect; |
| 102 | |
| 103 | export interface SmartFilterSearch { |
| 104 | readonly id: string; |
| 105 | readonly type: "search"; |
| 106 | readonly name?: string; |
| 107 | readonly active?: boolean; |
| 108 | } |
| 109 | |
| 110 | export interface SmartFilterSelect { |
| 111 | readonly id: string; |
| 112 | readonly type: "select"; |
| 113 | readonly name?: string; |
| 114 | readonly active?: boolean; |
| 115 | /** `"list"` for inline `options`, `"apl"` for a query-driven dropdown. */ |
| 116 | readonly selectType?: "list" | "apl"; |
| 117 | /** |
| 118 | * APL query that returns rows shaped `{ key, value }`. Axiom shows |
| 119 | * `key` in the dropdown and substitutes `value` into chart queries. |
| 120 | */ |
| 121 | readonly apl?: { readonly apl: string }; |
| 122 | /** Inline key/value options when `selectType === "list"`. */ |
| 123 | readonly options?: readonly { |
| 124 | readonly id?: string; |
| 125 | readonly key: string; |
| 126 | readonly value: string; |
| 127 | readonly default?: boolean; |
| 128 | }[]; |
| 129 | } |
| 130 | |
| 131 | export type Chart = |
| 132 | | TimeSeriesChart |
| 133 | | TableChart |
| 134 | | PieChart |
| 135 | | StatisticChart |
| 136 | | HeatmapChart |
| 137 | | LogStreamChart |
| 138 | | NoteChart |
| 139 | | SmartFilterChart; |
| 140 | |
| 141 | /** |
| 142 | * Mirrors Axiom's `CreateDashboardInput.dashboard.layout` cell schema. |
| 143 | * `i` references a chart by its `id`. |
| 144 | */ |
| 145 | export interface LayoutCell { |
| 146 | readonly i: string; |
| 147 | readonly x: number; |
| 148 | readonly y: number | null; |
| 149 | readonly w: number; |
| 150 | readonly h: number; |
| 151 | readonly minW?: number; |
| 152 | readonly minH?: number; |
| 153 | readonly maxW?: number; |
| 154 | readonly maxH?: number; |
| 155 | readonly static?: boolean; |
| 156 | } |