@gravitee/gamma-lib-observability 3.1.1-feat-obs-86-datatable-widget.8efffa8 → 3.1.1-feat-obs-86-datatable-widget.9370a7f

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.
Files changed (83) hide show
  1. package/QUERYING.md +53 -7
  2. package/USAGE_GUIDE.md +39 -6
  3. package/dist/dashboards/DashboardView.d.ts +8 -1
  4. package/dist/dashboards/DashboardView.d.ts.map +1 -1
  5. package/dist/dashboards/WidgetGroup.d.ts +7 -1
  6. package/dist/dashboards/WidgetGroup.d.ts.map +1 -1
  7. package/dist/dashboards/WidgetInteractionContext.d.ts +31 -0
  8. package/dist/dashboards/WidgetInteractionContext.d.ts.map +1 -0
  9. package/dist/dashboards/WidgetItem.d.ts +7 -3
  10. package/dist/dashboards/WidgetItem.d.ts.map +1 -1
  11. package/dist/dashboards/analytics-table/AnalyticsTable.d.ts +50 -0
  12. package/dist/dashboards/analytics-table/AnalyticsTable.d.ts.map +1 -0
  13. package/dist/dashboards/analytics-table/analytics-table-model.d.ts +73 -0
  14. package/dist/dashboards/analytics-table/analytics-table-model.d.ts.map +1 -0
  15. package/dist/dashboards/analytics-table/format-table-value.d.ts +28 -0
  16. package/dist/dashboards/analytics-table/format-table-value.d.ts.map +1 -0
  17. package/dist/dashboards/analytics-table/index.d.ts +6 -0
  18. package/dist/dashboards/analytics-table/index.d.ts.map +1 -0
  19. package/dist/dashboards/analytics-table/plan-columns.d.ts +80 -0
  20. package/dist/dashboards/analytics-table/plan-columns.d.ts.map +1 -0
  21. package/dist/dashboards/analytics-table/use-analytics-table-query.d.ts +46 -0
  22. package/dist/dashboards/analytics-table/use-analytics-table-query.d.ts.map +1 -0
  23. package/dist/dashboards/editor/TableColumnsEditor.d.ts +16 -0
  24. package/dist/dashboards/editor/TableColumnsEditor.d.ts.map +1 -0
  25. package/dist/dashboards/editor/TableDisplayFields.d.ts +13 -0
  26. package/dist/dashboards/editor/TableDisplayFields.d.ts.map +1 -0
  27. package/dist/dashboards/editor/TableQueryFields.d.ts +15 -0
  28. package/dist/dashboards/editor/TableQueryFields.d.ts.map +1 -0
  29. package/dist/dashboards/editor/VisualizationTypePicker.d.ts.map +1 -1
  30. package/dist/dashboards/editor/WidgetConfigForm.d.ts.map +1 -1
  31. package/dist/dashboards/editor/WidgetPreview.d.ts +8 -0
  32. package/dist/dashboards/editor/WidgetPreview.d.ts.map +1 -1
  33. package/dist/dashboards/editor/convert-widget-type.d.ts.map +1 -1
  34. package/dist/dashboards/editor/dashboard-editor-state.d.ts +8 -0
  35. package/dist/dashboards/editor/dashboard-editor-state.d.ts.map +1 -1
  36. package/dist/dashboards/editor/suggest-widget-title.d.ts.map +1 -1
  37. package/dist/dashboards/editor/widget-auto-scope.d.ts.map +1 -1
  38. package/dist/dashboards/index.d.ts +4 -1
  39. package/dist/dashboards/index.d.ts.map +1 -1
  40. package/dist/dashboards/register-default-renderers.d.ts +1 -1
  41. package/dist/dashboards/register-default-renderers.d.ts.map +1 -1
  42. package/dist/dashboards/renderers/TablePresentation.d.ts +20 -0
  43. package/dist/dashboards/renderers/TablePresentation.d.ts.map +1 -0
  44. package/dist/dashboards/renderers/TableWidgetRenderer.d.ts +4 -0
  45. package/dist/dashboards/renderers/TableWidgetRenderer.d.ts.map +1 -0
  46. package/dist/dashboards/renderers/index.d.ts +1 -0
  47. package/dist/dashboards/renderers/index.d.ts.map +1 -1
  48. package/dist/dashboards/widget-data.d.ts +26 -2
  49. package/dist/dashboards/widget-data.d.ts.map +1 -1
  50. package/dist/dashboards/widget-renderer-registry.d.ts +8 -0
  51. package/dist/dashboards/widget-renderer-registry.d.ts.map +1 -1
  52. package/dist/data-sources/http-data-source.d.ts.map +1 -1
  53. package/dist/hooks/use-facets-query.d.ts +7 -0
  54. package/dist/hooks/use-facets-query.d.ts.map +1 -1
  55. package/dist/index.d.ts +4 -4
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +4146 -3017
  58. package/dist/lib/use-element-size.d.ts +21 -0
  59. package/dist/lib/use-element-size.d.ts.map +1 -0
  60. package/dist/routing/ObservabilityDashboardPage.d.ts +6 -0
  61. package/dist/routing/ObservabilityDashboardPage.d.ts.map +1 -1
  62. package/dist/routing/detail-filter.d.ts +9 -4
  63. package/dist/routing/detail-filter.d.ts.map +1 -1
  64. package/dist/shared/ExplorerTable.d.ts +34 -2
  65. package/dist/shared/ExplorerTable.d.ts.map +1 -1
  66. package/dist/styles/observability.css +1 -1
  67. package/dist/testing/graphene-core-icons-mock.d.ts +7 -0
  68. package/dist/testing/graphene-core-icons-mock.d.ts.map +1 -1
  69. package/dist/testing/graphene-core-mock.d.ts +24 -6
  70. package/dist/testing/graphene-core-mock.d.ts.map +1 -1
  71. package/dist/testing/index.d.ts +9 -0
  72. package/dist/testing/index.d.ts.map +1 -1
  73. package/dist/testing/mock-metrics-data-source.d.ts.map +1 -1
  74. package/dist/testing.js +16 -1
  75. package/dist/types/domain.d.ts +92 -1
  76. package/dist/types/domain.d.ts.map +1 -1
  77. package/dist/types/guards.d.ts +2 -1
  78. package/dist/types/guards.d.ts.map +1 -1
  79. package/dist/types/index.d.ts +2 -2
  80. package/dist/types/index.d.ts.map +1 -1
  81. package/dist/types/responses.d.ts +18 -0
  82. package/dist/types/responses.d.ts.map +1 -1
  83. 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 | Type | Required | Default | Description |
508
- | ----------- | ---------------------------- | -------- | ----------- | --------------------------------------------------------- |
509
- | `timeRange` | `TimeRange` | Yes | | Time range propagated to all nested `WidgetItem`s |
510
- | `filters` | `readonly FilterCondition[]` | No | `[]` | Filters propagated to all nested `WidgetItem`s |
511
- | `align` | `WidgetGroupAlign` | No | `'stretch'` | Cross-axis alignment: `stretch`, `center`, `start`, `end` |
512
- | `children` | `ReactNode` | Yes | | `WidgetItem` children |
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;AAgCnG,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;CACvC;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,SAAS,EACT,OAAuB,EACvB,QAAgB,EAChB,SAAS,EACT,cAAwC,EACxC,cAAc,EACd,aAAa,EACb,mBAAmB,GACpB,EAAE,kBAAkB,2CA2EpB"}
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;AAGlE,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,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B;AASD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,OAAuB,EAAE,KAAiB,EAAE,QAAQ,EAAE,EAAE,gBAAgB,2CAQhH"}
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;AAUzB,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAEjB,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;;;GAGG;AACH,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,2BAA2B,GAC3B,gCAAgC,GAChC,8BAA8B,GAC9B,wBAAwB,GACxB,6BAA6B,GAC7B,8BAA8B,CAAC;AAEnC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,2CAMhD"}
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"}