@gravitee/gamma-lib-observability 3.1.1-feat-obs-86-datatable-widget.8efffa8 → 3.1.1-feat-obs-86-datatable-widget.3a15154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QUERYING.md +53 -7
- package/USAGE_GUIDE.md +39 -6
- package/dist/dashboards/DashboardView.d.ts +8 -1
- package/dist/dashboards/DashboardView.d.ts.map +1 -1
- package/dist/dashboards/WidgetGroup.d.ts +7 -1
- package/dist/dashboards/WidgetGroup.d.ts.map +1 -1
- package/dist/dashboards/WidgetInteractionContext.d.ts +31 -0
- package/dist/dashboards/WidgetInteractionContext.d.ts.map +1 -0
- package/dist/dashboards/WidgetItem.d.ts +7 -3
- package/dist/dashboards/WidgetItem.d.ts.map +1 -1
- package/dist/dashboards/analytics-table/AnalyticsTable.d.ts +50 -0
- package/dist/dashboards/analytics-table/AnalyticsTable.d.ts.map +1 -0
- package/dist/dashboards/analytics-table/analytics-table-model.d.ts +73 -0
- package/dist/dashboards/analytics-table/analytics-table-model.d.ts.map +1 -0
- package/dist/dashboards/analytics-table/format-table-value.d.ts +28 -0
- package/dist/dashboards/analytics-table/format-table-value.d.ts.map +1 -0
- package/dist/dashboards/analytics-table/index.d.ts +6 -0
- package/dist/dashboards/analytics-table/index.d.ts.map +1 -0
- package/dist/dashboards/analytics-table/plan-columns.d.ts +80 -0
- package/dist/dashboards/analytics-table/plan-columns.d.ts.map +1 -0
- package/dist/dashboards/analytics-table/use-analytics-table-query.d.ts +46 -0
- package/dist/dashboards/analytics-table/use-analytics-table-query.d.ts.map +1 -0
- package/dist/dashboards/editor/TableColumnsEditor.d.ts +16 -0
- package/dist/dashboards/editor/TableColumnsEditor.d.ts.map +1 -0
- package/dist/dashboards/editor/TableDisplayFields.d.ts +13 -0
- package/dist/dashboards/editor/TableDisplayFields.d.ts.map +1 -0
- package/dist/dashboards/editor/TableQueryFields.d.ts +15 -0
- package/dist/dashboards/editor/TableQueryFields.d.ts.map +1 -0
- package/dist/dashboards/editor/VisualizationTypePicker.d.ts.map +1 -1
- package/dist/dashboards/editor/WidgetConfigForm.d.ts.map +1 -1
- package/dist/dashboards/editor/WidgetPreview.d.ts +8 -0
- package/dist/dashboards/editor/WidgetPreview.d.ts.map +1 -1
- package/dist/dashboards/editor/convert-widget-type.d.ts.map +1 -1
- package/dist/dashboards/editor/dashboard-editor-state.d.ts +8 -0
- package/dist/dashboards/editor/dashboard-editor-state.d.ts.map +1 -1
- package/dist/dashboards/editor/suggest-widget-title.d.ts.map +1 -1
- package/dist/dashboards/editor/widget-auto-scope.d.ts.map +1 -1
- package/dist/dashboards/index.d.ts +4 -1
- package/dist/dashboards/index.d.ts.map +1 -1
- package/dist/dashboards/register-default-renderers.d.ts +1 -1
- package/dist/dashboards/register-default-renderers.d.ts.map +1 -1
- package/dist/dashboards/renderers/TablePresentation.d.ts +20 -0
- package/dist/dashboards/renderers/TablePresentation.d.ts.map +1 -0
- package/dist/dashboards/renderers/TableWidgetRenderer.d.ts +4 -0
- package/dist/dashboards/renderers/TableWidgetRenderer.d.ts.map +1 -0
- package/dist/dashboards/renderers/index.d.ts +1 -0
- package/dist/dashboards/renderers/index.d.ts.map +1 -1
- package/dist/dashboards/widget-data.d.ts +26 -2
- package/dist/dashboards/widget-data.d.ts.map +1 -1
- package/dist/dashboards/widget-renderer-registry.d.ts +8 -0
- package/dist/dashboards/widget-renderer-registry.d.ts.map +1 -1
- package/dist/data-sources/http-data-source.d.ts.map +1 -1
- package/dist/hooks/use-facets-query.d.ts +7 -0
- package/dist/hooks/use-facets-query.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4143 -3017
- package/dist/lib/use-element-size.d.ts +21 -0
- package/dist/lib/use-element-size.d.ts.map +1 -0
- package/dist/routing/ObservabilityDashboardPage.d.ts +6 -0
- package/dist/routing/ObservabilityDashboardPage.d.ts.map +1 -1
- package/dist/routing/detail-filter.d.ts +9 -4
- package/dist/routing/detail-filter.d.ts.map +1 -1
- package/dist/shared/ExplorerTable.d.ts +34 -2
- package/dist/shared/ExplorerTable.d.ts.map +1 -1
- package/dist/styles/observability.css +1 -1
- package/dist/testing/graphene-core-icons-mock.d.ts +7 -0
- package/dist/testing/graphene-core-icons-mock.d.ts.map +1 -1
- package/dist/testing/graphene-core-mock.d.ts +24 -6
- package/dist/testing/graphene-core-mock.d.ts.map +1 -1
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/mock-metrics-data-source.d.ts.map +1 -1
- package/dist/testing.js +16 -1
- package/dist/types/domain.d.ts +92 -1
- package/dist/types/domain.d.ts.map +1 -1
- package/dist/types/guards.d.ts +2 -1
- package/dist/types/guards.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/responses.d.ts +18 -0
- package/dist/types/responses.d.ts.map +1 -1
- package/package.json +1 -1
package/QUERYING.md
CHANGED
|
@@ -74,13 +74,14 @@ the same metric/range) dedupe.
|
|
|
74
74
|
|
|
75
75
|
## 4. Widget → request mapping
|
|
76
76
|
|
|
77
|
-
| Widget | Endpoint | Mapping
|
|
78
|
-
| -------------- | ----------- |
|
|
79
|
-
| `metric` | measures | `{ metric, measure }` → one `MetricRequest`. Widget `filters` → top-level filters.
|
|
80
|
-
| `metric-group` | measures | each `items[]` → one `MetricRequest` (`metric`, `measure`, per-item `filters`). Identical (metric+filters) items are deduped.
|
|
81
|
-
| `cartesian` | time-series | each `series[]` → one query. `metric`/`measure` → `metrics[0]`; `by` → `by[]`; `filters`/`sorts`/`ranges`/`limit` forwarded. Results are merged on the shared time bucket (`category`) before rendering.
|
|
82
|
-
| `doughnut` | facets | `by` → `by[]`; `metric`/`measure`/`sorts` → `metrics[0]`; `ranges`/`limit` forwarded.
|
|
83
|
-
| `bar` | facets | same as `doughnut`, plus `barLayout`.
|
|
77
|
+
| Widget | Endpoint | Mapping |
|
|
78
|
+
| -------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `metric` | measures | `{ metric, measure }` → one `MetricRequest`. Widget `filters` → top-level filters. |
|
|
80
|
+
| `metric-group` | measures | each `items[]` → one `MetricRequest` (`metric`, `measure`, per-item `filters`). Identical (metric+filters) items are deduped. |
|
|
81
|
+
| `cartesian` | time-series | each `series[]` → one query. `metric`/`measure` → `metrics[0]`; `by` → `by[]`; `filters`/`sorts`/`ranges`/`limit` forwarded. Results are merged on the shared time bucket (`category`) before rendering. |
|
|
82
|
+
| `doughnut` | facets | `by` → `by[]`; `metric`/`measure`/`sorts` → `metrics[0]`; `ranges`/`limit` forwarded. |
|
|
83
|
+
| `bar` | facets | same as `doughnut`, plus `barLayout`. |
|
|
84
|
+
| `table` | facets | `by` → `by[]`; `columns[]` grouped by distinct `metric` → one `metrics[]` entry each, measures de-duplicated; `sorts` goes on **exactly one** metric, the one owning the sort column; `ranges`/`limit` forwarded. With `showTotals` or a `share` column, one extra measures request with the same filters and range. |
|
|
84
85
|
|
|
85
86
|
**Presentation-only fields** (not sent to analytics; consumed by `CartesianPresentation` / graphene-charts):
|
|
86
87
|
|
|
@@ -109,6 +110,11 @@ chart total.
|
|
|
109
110
|
sent to the backend but flattened onto the first level.
|
|
110
111
|
- Distinct visual series for several measures of one metric are best expressed as one `series[]` entry
|
|
111
112
|
per measure (e.g. P90/P95/P99), which the renderer keys apart by measure.
|
|
113
|
+
- `table` rows come from the metric carrying `sorts`; the other metrics are joined on the bucket key.
|
|
114
|
+
The backend aggregates each metric separately, so a sort on anything but a count can leave a row
|
|
115
|
+
without a value for another column: the cell renders `—` and the widget reports how many rows are
|
|
116
|
+
incomplete. A single-column table issues exactly the request a top list on the same query issues, and
|
|
117
|
+
shares its cache entry.
|
|
112
118
|
|
|
113
119
|
---
|
|
114
120
|
|
|
@@ -224,6 +230,46 @@ series to keep a single left axis (backward compatible).
|
|
|
224
230
|
|
|
225
231
|
---
|
|
226
232
|
|
|
233
|
+
### 5.7 Multi-metric table (one facets request, sort on one metric)
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"type": "table",
|
|
238
|
+
"by": ["API"],
|
|
239
|
+
"columns": [
|
|
240
|
+
{ "metric": "HTTP_REQUESTS", "measure": "COUNT", "share": true },
|
|
241
|
+
{
|
|
242
|
+
"metric": "HTTP_ERROR_RATE",
|
|
243
|
+
"measure": "PERCENTAGE",
|
|
244
|
+
"thresholds": [{ "op": "gte", "value": 5, "level": "critical" }]
|
|
245
|
+
},
|
|
246
|
+
{ "metric": "HTTP_GATEWAY_RESPONSE_TIME", "measure": "P95", "pinned": true }
|
|
247
|
+
],
|
|
248
|
+
"sort": { "columnId": "HTTP_GATEWAY_RESPONSE_TIME:P95", "order": "DESC" },
|
|
249
|
+
"limit": 10,
|
|
250
|
+
"showTotals": true
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Facets request (`sorts` on the P95 metric only, the others unordered):
|
|
255
|
+
|
|
256
|
+
```json
|
|
257
|
+
{
|
|
258
|
+
"by": ["API"],
|
|
259
|
+
"limit": 10,
|
|
260
|
+
"metrics": [
|
|
261
|
+
{ "name": "HTTP_REQUESTS", "measures": ["COUNT"] },
|
|
262
|
+
{ "name": "HTTP_ERROR_RATE", "measures": ["PERCENTAGE"] },
|
|
263
|
+
{ "name": "HTTP_GATEWAY_RESPONSE_TIME", "measures": ["P95"], "sorts": [{ "measure": "P95", "order": "DESC" }] }
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Plus, because `showTotals` is on, one measures request for the same three metrics under the same
|
|
269
|
+
filters and range. A column's id is `metric:measure` unless it declares an `id`; the sort refers to it.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
227
273
|
## 6. Filter semantics
|
|
228
274
|
|
|
229
275
|
Filters merge in this order, later layers win on a field conflict:
|
package/USAGE_GUIDE.md
CHANGED
|
@@ -492,6 +492,8 @@ import { MetricPresentation, BarPresentation } from '@gravitee/gamma-lib-observa
|
|
|
492
492
|
| Manual | `CartesianWidget` | `CartesianWidgetData` |
|
|
493
493
|
| Manual | `BarWidget` | `BarWidgetData` |
|
|
494
494
|
| Manual | `DoughnutWidget` | `DoughnutWidgetData` |
|
|
495
|
+
| Manual | `BreakdownWidget` | `BreakdownWidgetData` |
|
|
496
|
+
| Manual | `TableWidget` | `TableWidgetData` |
|
|
495
497
|
|
|
496
498
|
Shared props (available in all modes):
|
|
497
499
|
|
|
@@ -504,12 +506,43 @@ Shared props (available in all modes):
|
|
|
504
506
|
|
|
505
507
|
#### `WidgetGroupProps`
|
|
506
508
|
|
|
507
|
-
| Prop
|
|
508
|
-
|
|
|
509
|
-
| `timeRange`
|
|
510
|
-
| `filters`
|
|
511
|
-
| `align`
|
|
512
|
-
| `
|
|
509
|
+
| Prop | Type | Required | Default | Description |
|
|
510
|
+
| ------------- | ------------------------------- | -------- | ----------- | ---------------------------------------------------------- |
|
|
511
|
+
| `timeRange` | `TimeRange` | Yes | | Time range propagated to all nested `WidgetItem`s |
|
|
512
|
+
| `filters` | `readonly FilterCondition[]` | No | `[]` | Filters propagated to all nested `WidgetItem`s |
|
|
513
|
+
| `align` | `WidgetGroupAlign` | No | `'stretch'` | Cross-axis alignment: `stretch`, `center`, `start`, `end` |
|
|
514
|
+
| `interaction` | `WidgetInteractionContextValue` | No | | Receives what a reader acts on inside a widget (see below) |
|
|
515
|
+
| `children` | `ReactNode` | Yes | | `WidgetItem` children |
|
|
516
|
+
|
|
517
|
+
#### Widget interactions (row drill-down)
|
|
518
|
+
|
|
519
|
+
A widget can send a value the reader acted on back to the page — a table row, today — through a
|
|
520
|
+
`WidgetInteraction { kind, field, value, label? }`. `DashboardView` and `WidgetGroup` both take an
|
|
521
|
+
`interaction` prop; `ObservabilityDashboardPage` wires it for you (a row click adds a filter chip on
|
|
522
|
+
the widget's dimension, clicking the same row again clears it, a locked dashboard filter is never
|
|
523
|
+
overridden). When embedding widgets yourself:
|
|
524
|
+
|
|
525
|
+
```tsx
|
|
526
|
+
<WidgetGroup
|
|
527
|
+
timeRange={timeRange}
|
|
528
|
+
filters={filters}
|
|
529
|
+
interaction={{
|
|
530
|
+
onInteract: ({ kind, field, value }) => {
|
|
531
|
+
if (kind === 'filter') setFilters(upsertFilterCondition(filters, field, value));
|
|
532
|
+
},
|
|
533
|
+
// Optional: which kinds the page can act on, per field. Only `filter` is
|
|
534
|
+
// offered when omitted; `exclude` needs the field's provider to advertise
|
|
535
|
+
// `not_in`, `view-logs` / `view-traces` / `open-entity` need a route.
|
|
536
|
+
supports: (kind) => kind === 'filter',
|
|
537
|
+
}}
|
|
538
|
+
>
|
|
539
|
+
<WidgetItem widget={topApisTable} />
|
|
540
|
+
</WidgetGroup>
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
Widgets rendered without an `interaction` upstream show no row affordance at all rather than a dead
|
|
544
|
+
one. The table widget also declares `layout.minCols` / `minRows`, which `DashboardView` forwards to
|
|
545
|
+
the grid so a reader cannot shrink it below what it can render.
|
|
513
546
|
|
|
514
547
|
---
|
|
515
548
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BreakpointCols } from '@gravitee/graphene-charts/dashboard-grid';
|
|
2
2
|
import { Dashboard, FilterCondition, TimeRange, Widget, WidgetLayout } from '../types/domain';
|
|
3
|
+
import { WidgetInteractionContextValue } from './WidgetInteractionContext';
|
|
3
4
|
export interface DashboardViewProps {
|
|
4
5
|
readonly dashboard: Dashboard;
|
|
5
6
|
readonly timeRange: TimeRange;
|
|
@@ -28,6 +29,12 @@ export interface DashboardViewProps {
|
|
|
28
29
|
* user knows the grid copy will be replaced on save.
|
|
29
30
|
*/
|
|
30
31
|
readonly highlightedWidgetId?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Receives what a reader acted on inside a widget — a table row, say — so the
|
|
34
|
+
* page can turn it into a dashboard filter or a navigation. Left out, widgets
|
|
35
|
+
* render without the affordance rather than with a dead one.
|
|
36
|
+
*/
|
|
37
|
+
readonly interaction?: WidgetInteractionContextValue;
|
|
31
38
|
}
|
|
32
|
-
export declare function DashboardView({ dashboard, timeRange, filters, editable, rowHeight, breakpointCols, onLayoutChange, widgetActions, highlightedWidgetId, }: DashboardViewProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export declare function DashboardView({ dashboard, timeRange, filters, editable, rowHeight, breakpointCols, onLayoutChange, widgetActions, highlightedWidgetId, interaction, }: DashboardViewProps): import("react/jsx-runtime").JSX.Element;
|
|
33
40
|
//# sourceMappingURL=DashboardView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardView.d.ts","sourceRoot":"","sources":["../../src/dashboards/DashboardView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAwB,MAAM,0CAA0C,CAAC;AAIrG,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"DashboardView.d.ts","sourceRoot":"","sources":["../../src/dashboards/DashboardView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAwB,MAAM,0CAA0C,CAAC;AAIrG,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEnG,OAAO,EAA6B,KAAK,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AA+B3G,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,iIAAiI;IACjI,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,2DAA2D;IAC3D,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,IAAI,CAAC;IAC/E;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,6BAA6B,CAAC;CACtD;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,SAAS,EACT,OAAuB,EACvB,QAAgB,EAChB,SAAS,EACT,cAAwC,EACxC,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,WAAW,GACZ,EAAE,kBAAkB,2CAmFpB"}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { FilterCondition, TimeRange } from '../types/domain';
|
|
3
|
+
import { WidgetInteractionContextValue } from './WidgetInteractionContext';
|
|
3
4
|
export type WidgetGroupAlign = 'stretch' | 'center' | 'start' | 'end';
|
|
4
5
|
export interface WidgetGroupProps {
|
|
5
6
|
readonly timeRange: TimeRange;
|
|
6
7
|
readonly filters?: readonly FilterCondition[];
|
|
7
8
|
readonly align?: WidgetGroupAlign;
|
|
9
|
+
/**
|
|
10
|
+
* Receives what a reader acted on inside a widget. Same contract as on
|
|
11
|
+
* `DashboardView`, so an embedded group behaves like a dashboard does.
|
|
12
|
+
*/
|
|
13
|
+
readonly interaction?: WidgetInteractionContextValue;
|
|
8
14
|
readonly children: ReactNode;
|
|
9
15
|
}
|
|
10
16
|
/**
|
|
@@ -12,5 +18,5 @@ export interface WidgetGroupProps {
|
|
|
12
18
|
* `filters` context. Renders children in a responsive flex layout where
|
|
13
19
|
* each child takes equal width.
|
|
14
20
|
*/
|
|
15
|
-
export declare function WidgetGroup({ timeRange, filters, align, children }: WidgetGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export declare function WidgetGroup({ timeRange, filters, align, interaction, children, }: WidgetGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
16
22
|
//# sourceMappingURL=WidgetGroup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetGroup.d.ts","sourceRoot":"","sources":["../../src/dashboards/WidgetGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"WidgetGroup.d.ts","sourceRoot":"","sources":["../../src/dashboards/WidgetGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,EAA6B,KAAK,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAE3G,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;AAEtE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,6BAA6B,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B;AASD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,OAAuB,EACvB,KAAiB,EACjB,WAAW,EACX,QAAQ,GACT,EAAE,gBAAgB,2CAYlB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a widget can ask the page to do with one of its values.
|
|
3
|
+
*
|
|
4
|
+
* `filter` and `exclude` are the drill-down proper. The three navigation kinds
|
|
5
|
+
* exist because the widget cannot build those links itself: the library
|
|
6
|
+
* contributes routes but never owns them, so only the page knows its base path
|
|
7
|
+
* and, for `open-entity`, what a value even points at. The widget offers the
|
|
8
|
+
* affordance; the page decides what it means.
|
|
9
|
+
*/
|
|
10
|
+
export type WidgetInteractionKind = 'filter' | 'exclude' | 'view-logs' | 'view-traces' | 'open-entity';
|
|
11
|
+
export interface WidgetInteraction {
|
|
12
|
+
readonly kind: WidgetInteractionKind;
|
|
13
|
+
/** Dimension the value belongs to, which is also its filter field. */
|
|
14
|
+
readonly field: string;
|
|
15
|
+
readonly value: string;
|
|
16
|
+
/** Human-readable form of `value`, when the data source resolved one. */
|
|
17
|
+
readonly label?: string;
|
|
18
|
+
}
|
|
19
|
+
export type WidgetInteractionHandler = (interaction: WidgetInteraction) => void;
|
|
20
|
+
export interface WidgetInteractionContextValue {
|
|
21
|
+
readonly onInteract: WidgetInteractionHandler;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the page can act on a kind for a given field. A widget offers only
|
|
24
|
+
* what the page answers for: an entry that silently does nothing is worse
|
|
25
|
+
* than no entry at all. Everything is offered when this is omitted.
|
|
26
|
+
*/
|
|
27
|
+
readonly supports?: (kind: WidgetInteractionKind, field: string) => boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare const WidgetInteractionProvider: import('react').Provider<WidgetInteractionContextValue | null>;
|
|
30
|
+
export declare function useWidgetInteractionContext(): WidgetInteractionContextValue | null;
|
|
31
|
+
//# sourceMappingURL=WidgetInteractionContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WidgetInteractionContext.d.ts","sourceRoot":"","sources":["../../src/dashboards/WidgetInteractionContext.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC;AAEvG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,wBAAwB,GAAG,CAAC,WAAW,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAEhF,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,UAAU,EAAE,wBAAwB,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAC7E;AAUD,eAAO,MAAM,yBAAyB,gEAAoC,CAAC;AAE3E,wBAAgB,2BAA2B,IAAI,6BAA6B,GAAG,IAAI,CAElF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BarWidget, BreakdownWidget, CartesianWidget, DoughnutWidget, FilterCondition, MetricGroupWidget, MetricWidget, TimeRange, Widget } from '../types/domain';
|
|
2
|
-
import { BarWidgetData, BreakdownWidgetData, CartesianWidgetData, DoughnutWidgetData, MetricGroupWidgetData, MetricWidgetData } from './widget-data';
|
|
1
|
+
import { BarWidget, BreakdownWidget, CartesianWidget, DoughnutWidget, FilterCondition, MetricGroupWidget, MetricWidget, TableWidget, TimeRange, Widget } from '../types/domain';
|
|
2
|
+
import { BarWidgetData, BreakdownWidgetData, CartesianWidgetData, DoughnutWidgetData, MetricGroupWidgetData, MetricWidgetData, TableWidgetData } from './widget-data';
|
|
3
3
|
interface WidgetItemBaseProps {
|
|
4
4
|
readonly timeRange?: TimeRange;
|
|
5
5
|
readonly filters?: readonly FilterCondition[];
|
|
@@ -32,11 +32,15 @@ interface WidgetItemManualBreakdownProps extends WidgetItemBaseProps {
|
|
|
32
32
|
readonly widget: BreakdownWidget;
|
|
33
33
|
readonly data: BreakdownWidgetData;
|
|
34
34
|
}
|
|
35
|
+
interface WidgetItemManualTableProps extends WidgetItemBaseProps {
|
|
36
|
+
readonly widget: TableWidget;
|
|
37
|
+
readonly data: TableWidgetData;
|
|
38
|
+
}
|
|
35
39
|
/**
|
|
36
40
|
* Props for `WidgetItem`. The union ensures that when `data` is provided,
|
|
37
41
|
* `data.type` is paired with the correct `widget` subtype at compile time.
|
|
38
42
|
*/
|
|
39
|
-
export type WidgetItemProps = WidgetItemAutoProps | WidgetItemManualMetricProps | WidgetItemManualMetricGroupProps | WidgetItemManualCartesianProps | WidgetItemManualBarProps | WidgetItemManualDoughnutProps | WidgetItemManualBreakdownProps;
|
|
43
|
+
export type WidgetItemProps = WidgetItemAutoProps | WidgetItemManualMetricProps | WidgetItemManualMetricGroupProps | WidgetItemManualCartesianProps | WidgetItemManualBarProps | WidgetItemManualDoughnutProps | WidgetItemManualBreakdownProps | WidgetItemManualTableProps;
|
|
40
44
|
/**
|
|
41
45
|
* Standalone widget that resolves a renderer from the widget registry.
|
|
42
46
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetItem.d.ts","sourceRoot":"","sources":["../../src/dashboards/WidgetItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,MAAM,EACP,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"WidgetItem.d.ts","sourceRoot":"","sources":["../../src/dashboards/WidgetItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,SAAS,EACT,MAAM,EACP,MAAM,iBAAiB,CAAC;AAYzB,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EAEhB,MAAM,eAAe,CAAC;AAKvB,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;CAC/C;AAED,UAAU,mBAAoB,SAAQ,mBAAmB;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,UAAU,2BAA4B,SAAQ,mBAAmB;IAC/D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;CACjC;AAED,UAAU,gCAAiC,SAAQ,mBAAmB;IACpE,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;CACtC;AAED,UAAU,8BAA+B,SAAQ,mBAAmB;IAClE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;CACpC;AAED,UAAU,wBAAyB,SAAQ,mBAAmB;IAC5D,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC9B;AAED,UAAU,6BAA8B,SAAQ,mBAAmB;IACjE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;CACnC;AAED,UAAU,8BAA+B,SAAQ,mBAAmB;IAClE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;CACpC;AAED,UAAU,0BAA2B,SAAQ,mBAAmB;IAC9D,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,2BAA2B,GAC3B,gCAAgC,GAChC,8BAA8B,GAC9B,wBAAwB,GACxB,6BAA6B,GAC7B,8BAA8B,GAC9B,0BAA0B,CAAC;AAE/B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,2CAMhD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ChartState } from '@gravitee/graphene-charts';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { TableSort } from '../../types/domain';
|
|
4
|
+
import { AnalyticsTableRow, ResolvedTableColumn } from './analytics-table-model';
|
|
5
|
+
/** Key of the synthetic totals row. Never a real dimension value. */
|
|
6
|
+
export declare const TOTALS_ROW_KEY = "__totals__";
|
|
7
|
+
export declare function isTotalsRow(row: AnalyticsTableRow): boolean;
|
|
8
|
+
export interface AnalyticsTableProps {
|
|
9
|
+
readonly columns: readonly ResolvedTableColumn[];
|
|
10
|
+
readonly rows: readonly AnalyticsTableRow[];
|
|
11
|
+
/** Header of the label column, e.g. `API`. */
|
|
12
|
+
readonly dimensionLabel: string;
|
|
13
|
+
readonly state: ChartState;
|
|
14
|
+
/** Active sort when controlled; the initial sort otherwise. */
|
|
15
|
+
readonly sort: TableSort | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Makes the sort controlled. Left out — in manual mode, or in a story — the
|
|
18
|
+
* table sorts itself over the rows it was handed, which is the only thing it
|
|
19
|
+
* can do without a query to re-issue.
|
|
20
|
+
*/
|
|
21
|
+
readonly onSortChange?: (sort: TableSort) => void;
|
|
22
|
+
/** Overall metric totals, keyed by column id. Also the share denominator. */
|
|
23
|
+
readonly totals?: Readonly<Record<string, number>>;
|
|
24
|
+
readonly showTotals?: boolean;
|
|
25
|
+
/** How many rows the response could not fill completely. */
|
|
26
|
+
readonly partialRows?: number;
|
|
27
|
+
/** Ceiling on the rows shown per page; the height decides the rest. */
|
|
28
|
+
readonly pageSize?: number;
|
|
29
|
+
readonly onRowSelect?: (row: AnalyticsTableRow) => void;
|
|
30
|
+
/** Extra entries for the per-row menu. The menu only exists when this is set. */
|
|
31
|
+
readonly renderRowMenuItems?: (row: AnalyticsTableRow) => ReactNode;
|
|
32
|
+
/**
|
|
33
|
+
* Ranked-list rendering used when the widget is too narrow for even one value
|
|
34
|
+
* column. Supplied by the caller so the fallback is the real top-list
|
|
35
|
+
* presentation rather than a second implementation of it.
|
|
36
|
+
*/
|
|
37
|
+
readonly renderTopList?: (sortColumn: ResolvedTableColumn) => ReactNode;
|
|
38
|
+
readonly emptyMessage?: ReactNode;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The table itself: sorting, paging, totals and degradation, over data someone
|
|
42
|
+
* else fetched.
|
|
43
|
+
*
|
|
44
|
+
* It measures its own body and adapts in discrete steps — compact numbers, then
|
|
45
|
+
* collapsed columns, then a top list, then an explicit "too small" state. It
|
|
46
|
+
* never scales and never scrolls: the widget lives in a box the grid clips, so
|
|
47
|
+
* anything that does not fit has to be decided about, not pushed out of view.
|
|
48
|
+
*/
|
|
49
|
+
export declare function AnalyticsTable({ columns, rows, dimensionLabel, state, sort, onSortChange, totals, showTotals, partialRows, pageSize, onRowSelect, renderRowMenuItems, renderTopList, emptyMessage, }: AnalyticsTableProps): import("react/jsx-runtime").JSX.Element;
|
|
50
|
+
//# sourceMappingURL=AnalyticsTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsTable.d.ts","sourceRoot":"","sources":["../../../src/dashboards/analytics-table/AnalyticsTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAe5D,OAAO,EAAkC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAIjC,qEAAqE;AACrE,eAAO,MAAM,cAAc,eAAe,CAAC;AAI3C,wBAAgB,WAAW,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAE3D;AA+DD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5C,8CAA8C;IAC9C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IAClD,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxD,iFAAiF;IACjF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,SAAS,CAAC;IACpE;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,mBAAmB,KAAK,SAAS,CAAC;IACxE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,cAAc,EACd,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,UAAkB,EAClB,WAAe,EACf,QAAQ,EACR,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,YAAyC,GAC1C,EAAE,mBAAmB,2CAiLrB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { SortOrder, TableColumn, TableColumnFormat, TableSort, TableThreshold } from '../../types/domain';
|
|
2
|
+
import { FacetBucket } from '../../types/responses';
|
|
3
|
+
/**
|
|
4
|
+
* A column with every default resolved: the identity used for sorting and for
|
|
5
|
+
* the collapse plan, the label and unit taken from the metric catalog when the
|
|
6
|
+
* author did not override them, and the flags turned into plain booleans.
|
|
7
|
+
*
|
|
8
|
+
* Resolution happens at render time, never at save time, so a table follows the
|
|
9
|
+
* catalog as it is corrected or extended instead of freezing a copy of it into
|
|
10
|
+
* the dashboard (see OBS-73 / OBS-81).
|
|
11
|
+
*/
|
|
12
|
+
export interface ResolvedTableColumn {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly metric: string;
|
|
15
|
+
readonly measure: string;
|
|
16
|
+
readonly label: string;
|
|
17
|
+
readonly unit?: string;
|
|
18
|
+
readonly format: TableColumnFormat;
|
|
19
|
+
readonly thresholds: readonly TableThreshold[];
|
|
20
|
+
readonly share: boolean;
|
|
21
|
+
readonly pinned: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface AnalyticsTableRow {
|
|
24
|
+
/** Bucket key — the value a row click filters on. */
|
|
25
|
+
readonly key: string;
|
|
26
|
+
readonly label: string;
|
|
27
|
+
/**
|
|
28
|
+
* Column id to value. A missing entry is a cell the response did not carry,
|
|
29
|
+
* which renders as "—" rather than as a zero: the two mean different things
|
|
30
|
+
* and reading "0 errors" where the backend said nothing is a lie.
|
|
31
|
+
*/
|
|
32
|
+
readonly values: Readonly<Record<string, number>>;
|
|
33
|
+
}
|
|
34
|
+
export interface AnalyticsTableModel {
|
|
35
|
+
readonly rows: readonly AnalyticsTableRow[];
|
|
36
|
+
/** Rows missing at least one column's value. */
|
|
37
|
+
readonly partialRows: number;
|
|
38
|
+
}
|
|
39
|
+
/** A column's identity is its metric/measure pair unless the author named it. */
|
|
40
|
+
export declare function tableColumnId(column: TableColumn): string;
|
|
41
|
+
export declare function resolveTableColumn(column: TableColumn): ResolvedTableColumn;
|
|
42
|
+
export declare function resolveTableColumns(columns: readonly TableColumn[]): ResolvedTableColumn[];
|
|
43
|
+
/**
|
|
44
|
+
* The sort the widget actually applies: the author's when it still names a
|
|
45
|
+
* column, otherwise the first column descending. A saved sort pointing at a
|
|
46
|
+
* column that has since been removed must not leave the table unordered.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveTableSort(columns: readonly ResolvedTableColumn[], sort: TableSort | undefined): TableSort | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Joins the buckets of several metrics into one row per dimension value.
|
|
51
|
+
*
|
|
52
|
+
* The row list — and its order — comes from the metric that carries the sort,
|
|
53
|
+
* because that is the only aggregation the backend ordered. Every other metric
|
|
54
|
+
* is looked up by key, and a key it does not carry leaves a hole: with one
|
|
55
|
+
* `terms` aggregation per metric, a sort on something other than a count lets
|
|
56
|
+
* the other aggregations return a different top-N. Holes are counted so the
|
|
57
|
+
* widget can say how much of the table is incomplete rather than passing off a
|
|
58
|
+
* partial join as a full one.
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildTableModel(buckets: readonly FacetBucket[], columns: readonly ResolvedTableColumn[], sortMetric: string): AnalyticsTableModel;
|
|
61
|
+
/**
|
|
62
|
+
* Denominator for a share column: the metric's overall total when totals were
|
|
63
|
+
* fetched, otherwise the sum of what is on screen. The two answer different
|
|
64
|
+
* questions ("share of all traffic" vs "share of the top N"), so which one is
|
|
65
|
+
* in play has to reach the cell — hence the flag rather than a bare number.
|
|
66
|
+
*/
|
|
67
|
+
export declare function resolveShareBase(column: ResolvedTableColumn, rows: readonly AnalyticsTableRow[], totals: Readonly<Record<string, number>> | undefined): {
|
|
68
|
+
readonly base: number;
|
|
69
|
+
readonly ofTotal: boolean;
|
|
70
|
+
};
|
|
71
|
+
/** Client-side ordering over the top-N the backend returned. */
|
|
72
|
+
export declare function sortTableRows(rows: readonly AnalyticsTableRow[], columnId: string, order: SortOrder): AnalyticsTableRow[];
|
|
73
|
+
//# sourceMappingURL=analytics-table-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-table-model.d.ts","sourceRoot":"","sources":["../../../src/dashboards/analytics-table/analytics-table-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/G,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIzD;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5C,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEzD;AAaD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,CAc3E;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,mBAAmB,EAAE,CAE1F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,SAAS,GAAG,SAAS,CAKvB;AAYD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,UAAU,EAAE,MAAM,GACjB,mBAAmB,CAmCrB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE,SAAS,iBAAiB,EAAE,EAClC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAKtD;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,iBAAiB,EAAE,EAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,GACf,iBAAiB,EAAE,CAWrB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { TableColumnFormat, TableThreshold, TableThresholdLevel } from '../../types/domain';
|
|
2
|
+
import { ResolvedTableColumn } from './analytics-table-model';
|
|
3
|
+
import { TableDensity } from './plan-columns';
|
|
4
|
+
/** What an absent cell reads as. Never a zero — see `AnalyticsTableRow.values`. */
|
|
5
|
+
export declare const MISSING_CELL = "\u2014";
|
|
6
|
+
export interface FormatTableValueOptions {
|
|
7
|
+
readonly format: TableColumnFormat;
|
|
8
|
+
readonly unit?: string;
|
|
9
|
+
/** Compact density switches plain numbers to `1.28M`. @default 'comfortable' */
|
|
10
|
+
readonly density?: TableDensity;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Formats one cell. The unit suffix is only appended to plain numbers: a
|
|
14
|
+
* percentage, a duration and a byte size all carry their own, and repeating it
|
|
15
|
+
* gives "2.3% %".
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatTableValue(value: number, options: FormatTableValueOptions): string;
|
|
18
|
+
/** Formats a cell of a resolved column, or the placeholder when it has no value. */
|
|
19
|
+
export declare function formatColumnValue(value: number | undefined, column: ResolvedTableColumn, density: TableDensity): string;
|
|
20
|
+
/**
|
|
21
|
+
* The worst level the value crosses. `critical` wins over `warning`, so a value
|
|
22
|
+
* past both bounds reads as the more serious one rather than as whichever
|
|
23
|
+
* threshold the author happened to list first.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveThresholdLevel(value: number | undefined, thresholds: readonly TableThreshold[]): TableThresholdLevel | undefined;
|
|
26
|
+
/** Design-system tokens, so both themes are covered without a theme branch. */
|
|
27
|
+
export declare const THRESHOLD_TEXT_CLASS: Record<TableThresholdLevel, string>;
|
|
28
|
+
//# sourceMappingURL=format-table-value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-table-value.d.ts","sourceRoot":"","sources":["../../../src/dashboards/analytics-table/format-table-value.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACjG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAKnD,mFAAmF;AACnF,eAAO,MAAM,YAAY,WAAM,CAAC;AAuBhC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAkBxF;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,YAAY,GACpB,MAAM,CAOR;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,UAAU,EAAE,SAAS,cAAc,EAAE,GACpC,mBAAmB,GAAG,SAAS,CAWjC;AAED,+EAA+E;AAC/E,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAGpE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AnalyticsTable, TOTALS_ROW_KEY, isTotalsRow, type AnalyticsTableProps } from './AnalyticsTable';
|
|
2
|
+
export { buildTableModel, resolveShareBase, resolveTableColumn, resolveTableColumns, resolveTableSort, sortTableRows, tableColumnId, type AnalyticsTableModel, type AnalyticsTableRow, type ResolvedTableColumn, } from './analytics-table-model';
|
|
3
|
+
export { MISSING_CELL, formatColumnValue, formatTableValue, resolveThresholdLevel, type FormatTableValueOptions, } from './format-table-value';
|
|
4
|
+
export { planColumns, resolveRowsPerPage, type ColumnPlan, type PageSizePlan, type PlanColumnsOptions, type TableDensity, type TableLayoutMode, } from './plan-columns';
|
|
5
|
+
export { buildTableMetrics, useAnalyticsTableQuery, type AnalyticsTableQueryResult, type UseAnalyticsTableQueryParams, } from './use-analytics-table-query';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dashboards/analytics-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzG,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,GAClC,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ResolvedTableColumn } from './analytics-table-model';
|
|
2
|
+
/**
|
|
3
|
+
* Intrinsic minimum widths, in pixels, for each kind of cell. They are what the
|
|
4
|
+
* content needs to stay readable, not a share of the widget: an API name needs
|
|
5
|
+
* room for more than an ellipsis, and a number needs room for its unit.
|
|
6
|
+
*/
|
|
7
|
+
export declare const LABEL_COLUMN_MIN_WIDTH = 140;
|
|
8
|
+
export declare const VALUE_COLUMN_MIN_WIDTH = 88;
|
|
9
|
+
/** A value column drawing a share bar next to its number. */
|
|
10
|
+
export declare const SHARE_COLUMN_MIN_WIDTH = 120;
|
|
11
|
+
export declare const ROW_MENU_WIDTH = 28;
|
|
12
|
+
/** Below this the cells switch to compact numbers and lose their share bars. */
|
|
13
|
+
export declare const COMPACT_DENSITY_WIDTH = 480;
|
|
14
|
+
/**
|
|
15
|
+
* Below either of these nothing legible fits at all, so the widget says so
|
|
16
|
+
* instead of drawing a table nobody can read — the same call `MetricGroup`
|
|
17
|
+
* makes with its own emergency threshold.
|
|
18
|
+
*/
|
|
19
|
+
export declare const EMERGENCY_WIDTH = 180;
|
|
20
|
+
export declare const EMERGENCY_HEIGHT = 90;
|
|
21
|
+
export declare const TABLE_ROW_HEIGHT = 36;
|
|
22
|
+
export declare const TABLE_HEADER_HEIGHT = 40;
|
|
23
|
+
export declare const TABLE_PAGINATION_HEIGHT = 36;
|
|
24
|
+
export type TableDensity = 'comfortable' | 'compact';
|
|
25
|
+
/**
|
|
26
|
+
* - `table` — the visualization the author asked for, possibly with columns
|
|
27
|
+
* collapsed away.
|
|
28
|
+
* - `top-list` — not even one value column fits next to the labels, so the
|
|
29
|
+
* widget falls back to the ranked-list presentation on the sort column.
|
|
30
|
+
* - `emergency` — too small for either.
|
|
31
|
+
*/
|
|
32
|
+
export type TableLayoutMode = 'table' | 'top-list' | 'emergency';
|
|
33
|
+
export interface ColumnPlan {
|
|
34
|
+
readonly mode: TableLayoutMode;
|
|
35
|
+
readonly density: TableDensity;
|
|
36
|
+
/** Column ids to render, in author order. */
|
|
37
|
+
readonly visible: readonly string[];
|
|
38
|
+
/** Column ids collapsed away, in author order. */
|
|
39
|
+
readonly hidden: readonly string[];
|
|
40
|
+
}
|
|
41
|
+
export interface PlanColumnsOptions {
|
|
42
|
+
readonly width: number;
|
|
43
|
+
readonly height: number;
|
|
44
|
+
readonly columns: readonly ResolvedTableColumn[];
|
|
45
|
+
/** The column ordering the rows. Never collapsed while a table is rendered. */
|
|
46
|
+
readonly sortColumnId: string | undefined;
|
|
47
|
+
/** Reserves room for the per-row actions button. @default false */
|
|
48
|
+
readonly hasRowMenu?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Decides which columns fit the measured width, and how tightly they draw.
|
|
52
|
+
*
|
|
53
|
+
* Pure, and separate from the component, because it is the whole of the
|
|
54
|
+
* degradation contract: hide in reverse author order, keep the label, the sort
|
|
55
|
+
* column and the pinned ones, fall back to a top list rather than clip. A
|
|
56
|
+
* pinned column is dropped only when the alternative is losing the table
|
|
57
|
+
* altogether — pinning asks for priority, and priority cannot conjure pixels.
|
|
58
|
+
*/
|
|
59
|
+
export declare function planColumns({ width, height, columns, sortColumnId, hasRowMenu, }: PlanColumnsOptions): ColumnPlan;
|
|
60
|
+
export interface PageSizePlan {
|
|
61
|
+
readonly rowsPerPage: number;
|
|
62
|
+
readonly paginated: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Rows per page derived from the height that is actually available, capped by
|
|
66
|
+
* the author's `pageSize`.
|
|
67
|
+
*
|
|
68
|
+
* Derived rather than fixed because the widget must never clip: a table asked
|
|
69
|
+
* for ten rows in a box that holds four has to show four and page, not four and
|
|
70
|
+
* a half. The author's number is therefore a ceiling — it can ask for fewer
|
|
71
|
+
* rows than fit, never for more.
|
|
72
|
+
*
|
|
73
|
+
* Two passes, because the pagination bar only exists if there is something to
|
|
74
|
+
* page through, and it costs a row's worth of height when it does.
|
|
75
|
+
*/
|
|
76
|
+
export declare function resolveRowsPerPage(height: number, totalRows: number, options?: {
|
|
77
|
+
readonly showTotals?: boolean;
|
|
78
|
+
readonly pageSize?: number;
|
|
79
|
+
}): PageSizePlan;
|
|
80
|
+
//# sourceMappingURL=plan-columns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-columns.d.ts","sourceRoot":"","sources":["../../../src/dashboards/analytics-table/plan-columns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,6DAA6D;AAC7D,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC;;;;GAIG;AACH,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,SAAS,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,+EAA+E;IAC/E,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,mEAAmE;IACnE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAMD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,OAAO,EACP,YAAY,EACZ,UAAkB,GACnB,EAAE,kBAAkB,GAAG,UAAU,CA2CjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1E,YAAY,CASd"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FilterCondition, NumericRange, TableSort, TimeRange } from '../../types/domain';
|
|
2
|
+
import { FacetMetricRequest } from '../../types/requests';
|
|
3
|
+
import { AnalyticsTableRow, ResolvedTableColumn } from './analytics-table-model';
|
|
4
|
+
/**
|
|
5
|
+
* Groups the columns by metric, de-duplicating measures, and attaches the sort
|
|
6
|
+
* directive to **exactly one** metric: the one owning the sort column.
|
|
7
|
+
*
|
|
8
|
+
* That single-carrier rule is the contract shared with the backend's bucket
|
|
9
|
+
* alignment work — the metric carrying `sorts` is the governing order once the
|
|
10
|
+
* aggregations are merged server-side. Putting `sorts` on two metrics would
|
|
11
|
+
* make "which order governs" ambiguous, so the request never does, and this
|
|
12
|
+
* side needs no change when the backend catches up.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildTableMetrics(columns: readonly ResolvedTableColumn[], sort: TableSort | undefined): FacetMetricRequest[];
|
|
15
|
+
export interface UseAnalyticsTableQueryParams {
|
|
16
|
+
readonly by: readonly string[];
|
|
17
|
+
readonly columns: readonly ResolvedTableColumn[];
|
|
18
|
+
readonly sort: TableSort | undefined;
|
|
19
|
+
readonly timeRange: TimeRange;
|
|
20
|
+
readonly filters?: FilterCondition[];
|
|
21
|
+
readonly limit?: number;
|
|
22
|
+
readonly ranges?: readonly NumericRange[];
|
|
23
|
+
/**
|
|
24
|
+
* Fires the extra measures request. Wanted by the totals row *and* by any
|
|
25
|
+
* share column, which needs a denominator that is not just the visible rows.
|
|
26
|
+
*/
|
|
27
|
+
readonly withTotals?: boolean;
|
|
28
|
+
readonly enabled?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface AnalyticsTableQueryResult {
|
|
31
|
+
readonly rows: readonly AnalyticsTableRow[];
|
|
32
|
+
readonly partialRows: number;
|
|
33
|
+
readonly totals: Readonly<Record<string, number>> | undefined;
|
|
34
|
+
readonly isLoading: boolean;
|
|
35
|
+
readonly isError: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* One facets request for the whole table, however many columns it has, plus one
|
|
39
|
+
* measures request when totals or a share column need a denominator.
|
|
40
|
+
*
|
|
41
|
+
* A single-column table produces exactly the request a top list on the same
|
|
42
|
+
* query produces, down to the cache key, so the two share a cache entry. A
|
|
43
|
+
* multi-metric table cannot: the key hashes the whole metric list.
|
|
44
|
+
*/
|
|
45
|
+
export declare function useAnalyticsTableQuery({ by, columns, sort, timeRange, filters, limit, ranges, withTotals, enabled, }: UseAnalyticsTableQueryParams): AnalyticsTableQueryResult;
|
|
46
|
+
//# sourceMappingURL=use-analytics-table-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-analytics-table-query.d.ts","sourceRoot":"","sources":["../../../src/dashboards/analytics-table/use-analytics-table-query.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAAmB,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE5G;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,kBAAkB,EAAE,CAiBtB;AAoBD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,EAAE,EACF,OAAO,EACP,IAAI,EACJ,SAAS,EACT,OAAO,EACP,KAAK,EACL,MAAM,EACN,UAAkB,EAClB,OAAO,GACR,EAAE,4BAA4B,GAAG,yBAAyB,CAwC1D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TableColumn } from '../../types/domain';
|
|
2
|
+
export interface TableColumnsEditorProps {
|
|
3
|
+
readonly columns: readonly TableColumn[];
|
|
4
|
+
readonly onChange: (columns: TableColumn[]) => void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Editor for a table's columns: what each one measures, how it reads, when it
|
|
8
|
+
* turns amber or red, and whether it survives a narrow widget.
|
|
9
|
+
*
|
|
10
|
+
* Reordering is up/down buttons rather than drag-and-drop, and not only to
|
|
11
|
+
* avoid a dependency: the order is the collapse order — the last column is the
|
|
12
|
+
* first to go — so it is a value the author sets deliberately, not a
|
|
13
|
+
* presentation detail they nudge.
|
|
14
|
+
*/
|
|
15
|
+
export declare function TableColumnsEditor({ columns, onChange }: TableColumnsEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=TableColumnsEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableColumnsEditor.d.ts","sourceRoot":"","sources":["../../../src/dashboards/editor/TableColumnsEditor.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,WAAW,EAAqC,MAAM,oBAAoB,CAAC;AAoBzF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;CACrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,uBAAuB,2CAiJhF"}
|