@dudousxd/nestjs-telescope-ui 2.0.0 → 2.0.1
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/CHANGELOG.md +748 -0
- package/README.md +31 -0
- package/dist/client/console-url.d.ts +11 -0
- package/dist/client/console-url.d.ts.map +1 -0
- package/dist/client/console-url.js +21 -0
- package/dist/client/console-url.js.map +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/telescope-client.d.ts +64 -11
- package/dist/client/telescope-client.d.ts.map +1 -1
- package/dist/client/telescope-client.js +59 -54
- package/dist/client/telescope-client.js.map +1 -1
- package/dist/client/types.d.ts +431 -30
- package/dist/client/types.d.ts.map +1 -1
- package/dist/react/components/batch-timeline.js +2 -2
- package/dist/react/components/batch-timeline.js.map +1 -1
- package/dist/react/components/cache-badge.d.ts +14 -6
- package/dist/react/components/cache-badge.d.ts.map +1 -1
- package/dist/react/components/cache-badge.js +26 -12
- package/dist/react/components/cache-badge.js.map +1 -1
- package/dist/react/components/charts/area-chart-card.d.ts +11 -3
- package/dist/react/components/charts/area-chart-card.d.ts.map +1 -1
- package/dist/react/components/charts/area-chart-card.js +33 -6
- package/dist/react/components/charts/area-chart-card.js.map +1 -1
- package/dist/react/components/charts/bar-chart-card.d.ts +18 -7
- package/dist/react/components/charts/bar-chart-card.d.ts.map +1 -1
- package/dist/react/components/charts/bar-chart-card.js +18 -9
- package/dist/react/components/charts/bar-chart-card.js.map +1 -1
- package/dist/react/components/charts/breakdown-card.d.ts +17 -0
- package/dist/react/components/charts/breakdown-card.d.ts.map +1 -0
- package/dist/react/components/charts/breakdown-card.js +43 -0
- package/dist/react/components/charts/breakdown-card.js.map +1 -0
- package/dist/react/components/charts/chart-card.d.ts +7 -0
- package/dist/react/components/charts/chart-card.d.ts.map +1 -1
- package/dist/react/components/charts/chart-card.js +10 -3
- package/dist/react/components/charts/chart-card.js.map +1 -1
- package/dist/react/components/charts/chart-selection.d.ts +44 -0
- package/dist/react/components/charts/chart-selection.d.ts.map +1 -0
- package/dist/react/components/charts/chart-selection.js +36 -0
- package/dist/react/components/charts/chart-selection.js.map +1 -0
- package/dist/react/components/charts/chart-theme.d.ts +62 -19
- package/dist/react/components/charts/chart-theme.d.ts.map +1 -1
- package/dist/react/components/charts/chart-theme.js +72 -13
- package/dist/react/components/charts/chart-theme.js.map +1 -1
- package/dist/react/components/charts/distribution-chart-card.d.ts +17 -0
- package/dist/react/components/charts/distribution-chart-card.d.ts.map +1 -0
- package/dist/react/components/charts/distribution-chart-card.js +46 -0
- package/dist/react/components/charts/distribution-chart-card.js.map +1 -0
- package/dist/react/components/charts/gauge-card.d.ts +12 -0
- package/dist/react/components/charts/gauge-card.d.ts.map +1 -0
- package/dist/react/components/charts/gauge-card.js +17 -0
- package/dist/react/components/charts/gauge-card.js.map +1 -0
- package/dist/react/components/charts/index.d.ts +1 -0
- package/dist/react/components/charts/index.d.ts.map +1 -1
- package/dist/react/components/charts/index.js +1 -0
- package/dist/react/components/charts/index.js.map +1 -1
- package/dist/react/components/charts/stacked-area-chart-card.d.ts +17 -3
- package/dist/react/components/charts/stacked-area-chart-card.d.ts.map +1 -1
- package/dist/react/components/charts/stacked-area-chart-card.js +31 -8
- package/dist/react/components/charts/stacked-area-chart-card.js.map +1 -1
- package/dist/react/components/entries-table.d.ts.map +1 -1
- package/dist/react/components/entries-table.js +17 -3
- package/dist/react/components/entries-table.js.map +1 -1
- package/dist/react/components/entry-detail.d.ts +2 -0
- package/dist/react/components/entry-detail.d.ts.map +1 -1
- package/dist/react/components/entry-detail.js +186 -20
- package/dist/react/components/entry-detail.js.map +1 -1
- package/dist/react/components/entry-insights.d.ts.map +1 -1
- package/dist/react/components/entry-insights.js +28 -17
- package/dist/react/components/entry-insights.js.map +1 -1
- package/dist/react/components/entry-types.d.ts +29 -0
- package/dist/react/components/entry-types.d.ts.map +1 -1
- package/dist/react/components/entry-types.js +60 -0
- package/dist/react/components/entry-types.js.map +1 -1
- package/dist/react/components/export-json-toolbar.js +2 -2
- package/dist/react/components/export-json-toolbar.js.map +1 -1
- package/dist/react/components/extensions/panel-column-menu.d.ts +19 -0
- package/dist/react/components/extensions/panel-column-menu.d.ts.map +1 -0
- package/dist/react/components/extensions/panel-column-menu.js +47 -0
- package/dist/react/components/extensions/panel-column-menu.js.map +1 -0
- package/dist/react/components/extensions/panel-renderer.d.ts +46 -0
- package/dist/react/components/extensions/panel-renderer.d.ts.map +1 -0
- package/dist/react/components/extensions/panel-renderer.js +122 -0
- package/dist/react/components/extensions/panel-renderer.js.map +1 -0
- package/dist/react/components/extensions/panel-table-header.d.ts +18 -0
- package/dist/react/components/extensions/panel-table-header.d.ts.map +1 -0
- package/dist/react/components/extensions/panel-table-header.js +82 -0
- package/dist/react/components/extensions/panel-table-header.js.map +1 -0
- package/dist/react/components/extensions/panel-table.d.ts +27 -0
- package/dist/react/components/extensions/panel-table.d.ts.map +1 -0
- package/dist/react/components/extensions/panel-table.js +87 -0
- package/dist/react/components/extensions/panel-table.js.map +1 -0
- package/dist/react/components/extensions/stat-card.d.ts +18 -0
- package/dist/react/components/extensions/stat-card.d.ts.map +1 -0
- package/dist/react/components/extensions/stat-card.js +44 -0
- package/dist/react/components/extensions/stat-card.js.map +1 -0
- package/dist/react/components/extensions/table-columns.d.ts +32 -0
- package/dist/react/components/extensions/table-columns.d.ts.map +1 -0
- package/dist/react/components/extensions/table-columns.js +51 -0
- package/dist/react/components/extensions/table-columns.js.map +1 -0
- package/dist/react/components/extensions/table-features.d.ts +47 -0
- package/dist/react/components/extensions/table-features.d.ts.map +1 -0
- package/dist/react/components/extensions/table-features.js +45 -0
- package/dist/react/components/extensions/table-features.js.map +1 -0
- package/dist/react/components/extensions/table-query.d.ts +53 -0
- package/dist/react/components/extensions/table-query.d.ts.map +1 -0
- package/dist/react/components/extensions/table-query.js +51 -0
- package/dist/react/components/extensions/table-query.js.map +1 -0
- package/dist/react/components/flamegraph-view.d.ts +18 -0
- package/dist/react/components/flamegraph-view.d.ts.map +1 -0
- package/dist/react/components/flamegraph-view.js +48 -0
- package/dist/react/components/flamegraph-view.js.map +1 -0
- package/dist/react/components/flamegraph.d.ts +34 -0
- package/dist/react/components/flamegraph.d.ts.map +1 -0
- package/dist/react/components/flamegraph.js +54 -0
- package/dist/react/components/flamegraph.js.map +1 -0
- package/dist/react/components/inertia-badge.d.ts +33 -0
- package/dist/react/components/inertia-badge.d.ts.map +1 -0
- package/dist/react/components/inertia-badge.js +72 -0
- package/dist/react/components/inertia-badge.js.map +1 -0
- package/dist/react/components/inertia-body.d.ts +11 -0
- package/dist/react/components/inertia-body.d.ts.map +1 -0
- package/dist/react/components/inertia-body.js +127 -0
- package/dist/react/components/inertia-body.js.map +1 -0
- package/dist/react/components/official-event.d.ts +16 -0
- package/dist/react/components/official-event.d.ts.map +1 -0
- package/dist/react/components/official-event.js +88 -0
- package/dist/react/components/official-event.js.map +1 -0
- package/dist/react/components/pulse-panel.d.ts.map +1 -1
- package/dist/react/components/pulse-panel.js +6 -6
- package/dist/react/components/pulse-panel.js.map +1 -1
- package/dist/react/components/queues/EnqueueJobForm.d.ts.map +1 -1
- package/dist/react/components/queues/EnqueueJobForm.js +2 -1
- package/dist/react/components/queues/EnqueueJobForm.js.map +1 -1
- package/dist/react/components/queues/JobActions.d.ts.map +1 -1
- package/dist/react/components/queues/JobActions.js +11 -9
- package/dist/react/components/queues/JobActions.js.map +1 -1
- package/dist/react/components/queues/JobDetailDrawer.d.ts.map +1 -1
- package/dist/react/components/queues/JobDetailDrawer.js +8 -13
- package/dist/react/components/queues/JobDetailDrawer.js.map +1 -1
- package/dist/react/components/queues/JobTable.d.ts.map +1 -1
- package/dist/react/components/queues/JobTable.js +0 -0
- package/dist/react/components/queues/JobTable.js.map +1 -1
- package/dist/react/components/queues/QueueList.d.ts.map +1 -1
- package/dist/react/components/queues/QueueList.js +6 -6
- package/dist/react/components/queues/QueueList.js.map +1 -1
- package/dist/react/components/queues/QueueStateTabs.d.ts.map +1 -1
- package/dist/react/components/queues/QueueStateTabs.js +9 -7
- package/dist/react/components/queues/QueueStateTabs.js.map +1 -1
- package/dist/react/components/queues/queue-format.d.ts +5 -1
- package/dist/react/components/queues/queue-format.d.ts.map +1 -1
- package/dist/react/components/queues/queue-format.js +11 -7
- package/dist/react/components/queues/queue-format.js.map +1 -1
- package/dist/react/components/queues-panel.js +1 -1
- package/dist/react/components/queues-panel.js.map +1 -1
- package/dist/react/components/request-timeline.d.ts.map +1 -1
- package/dist/react/components/request-timeline.js +2 -2
- package/dist/react/components/request-timeline.js.map +1 -1
- package/dist/react/components/retention-indicator.d.ts.map +1 -1
- package/dist/react/components/retention-indicator.js +1 -1
- package/dist/react/components/retention-indicator.js.map +1 -1
- package/dist/react/components/sparkline.d.ts.map +1 -1
- package/dist/react/components/sparkline.js +1 -1
- package/dist/react/components/sparkline.js.map +1 -1
- package/dist/react/components/tag-autocomplete.d.ts +21 -4
- package/dist/react/components/tag-autocomplete.d.ts.map +1 -1
- package/dist/react/components/tag-autocomplete.js +57 -29
- package/dist/react/components/tag-autocomplete.js.map +1 -1
- package/dist/react/components/to-csv.d.ts +25 -0
- package/dist/react/components/to-csv.d.ts.map +1 -0
- package/dist/react/components/to-csv.js +78 -0
- package/dist/react/components/to-csv.js.map +1 -0
- package/dist/react/components/user-tag.d.ts +15 -0
- package/dist/react/components/user-tag.d.ts.map +1 -1
- package/dist/react/components/user-tag.js +19 -0
- package/dist/react/components/user-tag.js.map +1 -1
- package/dist/react/components/waterfall-view.d.ts +13 -0
- package/dist/react/components/waterfall-view.d.ts.map +1 -0
- package/dist/react/components/waterfall-view.js +58 -0
- package/dist/react/components/waterfall-view.js.map +1 -0
- package/dist/react/components/window-select.d.ts.map +1 -1
- package/dist/react/components/window-select.js +6 -2
- package/dist/react/components/window-select.js.map +1 -1
- package/dist/react/index.d.ts +7 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +11 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/ui/badge.d.ts +16 -0
- package/dist/react/ui/badge.d.ts.map +1 -0
- package/dist/react/ui/badge.js +28 -0
- package/dist/react/ui/badge.js.map +1 -0
- package/dist/react/ui/button.d.ts +17 -0
- package/dist/react/ui/button.d.ts.map +1 -0
- package/dist/react/ui/button.js +35 -0
- package/dist/react/ui/button.js.map +1 -0
- package/dist/react/ui/chart.d.ts +116 -0
- package/dist/react/ui/chart.d.ts.map +1 -0
- package/dist/react/ui/chart.js +191 -0
- package/dist/react/ui/chart.js.map +1 -0
- package/dist/react/ui/cn.d.ts +8 -0
- package/dist/react/ui/cn.d.ts.map +1 -0
- package/dist/react/ui/cn.js +11 -0
- package/dist/react/ui/cn.js.map +1 -0
- package/dist/react/ui/dialog.d.ts +26 -0
- package/dist/react/ui/dialog.d.ts.map +1 -0
- package/dist/react/ui/dialog.js +40 -0
- package/dist/react/ui/dialog.js.map +1 -0
- package/dist/react/ui/index.d.ts +24 -0
- package/dist/react/ui/index.d.ts.map +1 -0
- package/dist/react/ui/index.js +24 -0
- package/dist/react/ui/index.js.map +1 -0
- package/dist/react/ui/input.d.ts +3 -0
- package/dist/react/ui/input.d.ts.map +1 -0
- package/dist/react/ui/input.js +8 -0
- package/dist/react/ui/input.js.map +1 -0
- package/dist/react/ui/select.d.ts +20 -0
- package/dist/react/ui/select.d.ts.map +1 -0
- package/dist/react/ui/select.js +27 -0
- package/dist/react/ui/select.js.map +1 -0
- package/dist/react/ui/table.d.ts +27 -0
- package/dist/react/ui/table.d.ts.map +1 -0
- package/dist/react/ui/table.js +22 -0
- package/dist/react/ui/table.js.map +1 -0
- package/dist/react/ui/tabs.d.ts +12 -0
- package/dist/react/ui/tabs.d.ts.map +1 -0
- package/dist/react/ui/tabs.js +20 -0
- package/dist/react/ui/tabs.js.map +1 -0
- package/dist/react/ui/tooltip.d.ts +10 -0
- package/dist/react/ui/tooltip.d.ts.map +1 -0
- package/dist/react/ui/tooltip.js +12 -0
- package/dist/react/ui/tooltip.js.map +1 -0
- package/dist/react/use-telescope-queries.d.ts +129 -130
- package/dist/react/use-telescope-queries.d.ts.map +1 -1
- package/dist/react/use-telescope-queries.js +146 -1
- package/dist/react/use-telescope-queries.js.map +1 -1
- package/dist/react/use-telescope-stream.d.ts +10 -0
- package/dist/react/use-telescope-stream.d.ts.map +1 -0
- package/dist/react/use-telescope-stream.js +40 -0
- package/dist/react/use-telescope-stream.js.map +1 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/telescope-ui.module.d.ts +28 -1
- package/dist/server/telescope-ui.module.d.ts.map +1 -1
- package/dist/server/telescope-ui.module.js +42 -4
- package/dist/server/telescope-ui.module.js.map +1 -1
- package/dist/server/telescope-ui.options.d.ts +47 -0
- package/dist/server/telescope-ui.options.d.ts.map +1 -1
- package/dist/server/telescope-ui.options.js.map +1 -1
- package/dist/spa/assets/index-BPSlup7m.js +159 -0
- package/dist/spa/assets/index-DmsmJrlA.css +1 -0
- package/dist/spa/index.html +2 -2
- package/package.json +75 -36
- package/skills/telescope-ui-dashboard/SKILL.md +198 -0
- package/dist/react/components/type-tabs.d.ts +0 -5
- package/dist/react/components/type-tabs.d.ts.map +0 -1
- package/dist/react/components/type-tabs.js +0 -8
- package/dist/react/components/type-tabs.js.map +0 -1
- package/dist/spa/assets/index-CCzTpxj3.css +0 -1
- package/dist/spa/assets/index-w0XTI5OM.js +0 -135
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Cache entries carry `content: { operation, hit, key, tier?, stale?, ... }`. This
|
|
4
|
+
* module derives a small status pill: `HIT` reads `--good`, `MISS` reads `--warn`,
|
|
5
|
+
* and `SET`/`DEL`/`CLEAR` are neutral. A grace-served (`stale`) hit reads warn to
|
|
6
|
+
* stand out from a fresh hit; a `tier` (e.g. l1/l2) is appended when present.
|
|
7
|
+
*/
|
|
8
|
+
import { Badge, badgeVariants } from '../ui/index.js';
|
|
9
|
+
const OPERATIONS = new Set(['get', 'set', 'delete', 'clear']);
|
|
2
10
|
/** Narrow unknown entry content to the cache shape without casts. */
|
|
3
11
|
function isCacheContent(content) {
|
|
4
12
|
if (typeof content !== 'object' || content === null)
|
|
@@ -6,30 +14,36 @@ function isCacheContent(content) {
|
|
|
6
14
|
if (!('operation' in content) || !('hit' in content) || !('key' in content))
|
|
7
15
|
return false;
|
|
8
16
|
const { operation, hit, key } = content;
|
|
9
|
-
if (operation !== '
|
|
17
|
+
if (typeof operation !== 'string' || !OPERATIONS.has(operation))
|
|
10
18
|
return false;
|
|
11
19
|
if (hit !== null && typeof hit !== 'boolean')
|
|
12
20
|
return false;
|
|
13
21
|
return typeof key === 'string';
|
|
14
22
|
}
|
|
15
|
-
|
|
23
|
+
function info(label, variant) {
|
|
24
|
+
return { label, variant, className: badgeVariants({ variant }) };
|
|
25
|
+
}
|
|
16
26
|
/**
|
|
17
27
|
* Pure mapping from entry content to a cache pill descriptor; `null` for any
|
|
18
|
-
* non-cache or unrecognized content.
|
|
19
|
-
* by the queue action buttons.
|
|
28
|
+
* non-cache or unrecognized content.
|
|
20
29
|
*/
|
|
21
30
|
export function cacheBadge(content) {
|
|
22
31
|
if (!isCacheContent(content))
|
|
23
32
|
return null;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
const tierSuffix = typeof content.tier === 'string' ? ` ${content.tier.toUpperCase()}` : '';
|
|
34
|
+
if (content.operation === 'set')
|
|
35
|
+
return info(`SET${tierSuffix}`, 'muted');
|
|
36
|
+
if (content.operation === 'delete')
|
|
37
|
+
return info('DEL', 'muted');
|
|
38
|
+
if (content.operation === 'clear')
|
|
39
|
+
return info('CLEAR', 'muted');
|
|
27
40
|
if (content.hit === true) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return { label: 'MISS', className: `${PILL_BASE} border-amber-500/40 text-amber-300` };
|
|
41
|
+
// A grace-period (stale) hit warns so it's distinguishable from a fresh hit.
|
|
42
|
+
const stale = content.stale === true;
|
|
43
|
+
return info(`${stale ? 'HIT·STALE' : 'HIT'}${tierSuffix}`, stale ? 'warn' : 'good');
|
|
32
44
|
}
|
|
45
|
+
if (content.hit === false)
|
|
46
|
+
return info(`MISS${tierSuffix}`, 'warn');
|
|
33
47
|
return null;
|
|
34
48
|
}
|
|
35
49
|
/** Small cache hit/miss/set status pill; renders nothing for non-cache content. */
|
|
@@ -37,6 +51,6 @@ export function CacheBadge({ content }) {
|
|
|
37
51
|
const badge = cacheBadge(content);
|
|
38
52
|
if (badge === null)
|
|
39
53
|
return null;
|
|
40
|
-
return _jsx(
|
|
54
|
+
return _jsx(Badge, { variant: badge.variant, children: badge.label });
|
|
41
55
|
}
|
|
42
56
|
//# sourceMappingURL=cache-badge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-badge.js","sourceRoot":"","sources":["../../../src/react/components/cache-badge.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cache-badge.js","sourceRoot":"","sources":["../../../src/react/components/cache-badge.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,EAAmB,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAUvE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9D,qEAAqE;AACrE,SAAS,cAAc,CAAC,OAAgB;IACtC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAClE,IAAI,CAAC,CAAC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1F,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACxC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9E,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC3D,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC;AACjC,CAAC;AAcD,SAAS,IAAI,CAAC,KAAa,EAAE,OAA2C;IACtE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,UAAU,GAAG,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC,MAAM,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1E,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjE,IAAI,OAAO,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACzB,6EAA6E;QAC7E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC;QACrC,OAAO,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,GAAG,UAAU,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC,OAAO,UAAU,EAAE,EAAE,MAAM,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAwB;IAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,KAAC,KAAK,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,YAAG,KAAK,CAAC,KAAK,GAAS,CAAC;AAC9D,CAAC"}
|
|
@@ -1,16 +1,24 @@
|
|
|
1
|
+
import type { JSX, ReactNode } from 'react';
|
|
2
|
+
import { type ChartSelection } from './chart-selection.js';
|
|
1
3
|
export interface AreaChartPoint {
|
|
2
4
|
/** X-axis label (e.g. formatted time). */
|
|
3
5
|
label: string;
|
|
4
6
|
/** Series value. */
|
|
5
7
|
value: number;
|
|
6
8
|
}
|
|
7
|
-
/** Single-series time area chart with a
|
|
8
|
-
export declare function AreaChartCard({ title, data, right, color, valueLabel, height, }: {
|
|
9
|
+
/** Single-series time area chart with a gradient fill, a hover card and an optional brush. */
|
|
10
|
+
export declare function AreaChartCard({ title, data, right, color, valueLabel, height, brush, valueFormatter, onSelect, }: {
|
|
9
11
|
title: string;
|
|
10
12
|
data: AreaChartPoint[];
|
|
11
|
-
right?:
|
|
13
|
+
right?: ReactNode;
|
|
12
14
|
color?: string;
|
|
13
15
|
valueLabel?: string;
|
|
14
16
|
height?: number;
|
|
17
|
+
/** Force the range brush on or off. Defaults to on once the series is long. */
|
|
18
|
+
brush?: boolean;
|
|
19
|
+
/** Format the value in the hover card (the axis is left alone). */
|
|
20
|
+
valueFormatter?: (value: number) => ReactNode;
|
|
21
|
+
/** Drill-down: called with the point under a click. Omit and the chart is inert. */
|
|
22
|
+
onSelect?: (selection: ChartSelection) => void;
|
|
15
23
|
}): JSX.Element;
|
|
16
24
|
//# sourceMappingURL=area-chart-card.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-chart-card.d.ts","sourceRoot":"","sources":["../../../../src/react/components/charts/area-chart-card.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"area-chart-card.d.ts","sourceRoot":"","sources":["../../../../src/react/components/charts/area-chart-card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAW5C,OAAO,EAAE,KAAK,cAAc,EAAoC,MAAM,sBAAsB,CAAC;AAG7F,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAWD,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,IAAI,EACJ,KAAK,EACL,KAAkB,EAClB,UAAoB,EACpB,MAAY,EACZ,KAAK,EACL,cAAc,EACd,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAC9C,oFAAoF;IACpF,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CAChD,GAAG,GAAG,CAAC,OAAO,CA0Ed"}
|
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useId } from 'react';
|
|
3
|
-
import { Area, AreaChart,
|
|
2
|
+
import { useId, useMemo } from 'react';
|
|
3
|
+
import { Area, AreaChart, Brush, CartesianGrid, XAxis, YAxis } from 'recharts';
|
|
4
|
+
import { ChartContainer, ChartTooltip, ChartTooltipContent, chartBrushProps, chartColorVar, } from '../../ui/chart.js';
|
|
4
5
|
import { ChartCard, ChartEmptyState } from './chart-card.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { activeChartLabel, chartSelection } from './chart-selection.js';
|
|
7
|
+
import { ACCENT_HEX, chartConfig } from './chart-theme.js';
|
|
8
|
+
/**
|
|
9
|
+
* Number of points past which the chart gets a range brush.
|
|
10
|
+
*
|
|
11
|
+
* A brush costs ~20px of an already short body and only earns it when the window
|
|
12
|
+
* is long enough that the interesting part is a slice of it; over a dozen buckets
|
|
13
|
+
* it is a scrollbar for a page that already fits.
|
|
14
|
+
*/
|
|
15
|
+
const BRUSH_MIN_POINTS = 24;
|
|
16
|
+
/** Single-series time area chart with a gradient fill, a hover card and an optional brush. */
|
|
17
|
+
export function AreaChartCard({ title, data, right, color = ACCENT_HEX, valueLabel = 'value', height = 220, brush, valueFormatter, onSelect, }) {
|
|
8
18
|
const gradientId = useId();
|
|
9
19
|
const bodyHeight = height - 64;
|
|
10
|
-
|
|
20
|
+
const config = useMemo(() => chartConfig(['value'], () => color, () => valueLabel), [color, valueLabel]);
|
|
21
|
+
const showBrush = brush ?? data.length >= BRUSH_MIN_POINTS;
|
|
22
|
+
// Interaction props are built conditionally: under `exactOptionalPropertyTypes`
|
|
23
|
+
// an explicit `undefined` is not assignable to Recharts' optional handlers, and
|
|
24
|
+
// a chart with no drill-down target must not advertise a pointer cursor.
|
|
25
|
+
const clickProps = onSelect
|
|
26
|
+
? {
|
|
27
|
+
onClick: (state) => {
|
|
28
|
+
const label = activeChartLabel(state);
|
|
29
|
+
if (label === undefined)
|
|
30
|
+
return;
|
|
31
|
+
const point = data.find((p) => p.label === label);
|
|
32
|
+
onSelect(chartSelection({ label, series: 'value', value: point?.value }));
|
|
33
|
+
},
|
|
34
|
+
className: 'cursor-pointer',
|
|
35
|
+
}
|
|
36
|
+
: {};
|
|
37
|
+
return (_jsx(ChartCard, { title: title, right: right, height: bodyHeight, children: data.length === 0 ? (_jsx(ChartEmptyState, { height: bodyHeight })) : (_jsx(ChartContainer, { config: config, children: _jsxs(AreaChart, { data: data, margin: { top: 4, right: 8, bottom: 0, left: -16 }, ...clickProps, children: [_jsx("defs", { children: _jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: chartColorVar('value'), stopOpacity: 0.35 }), _jsx("stop", { offset: "100%", stopColor: chartColorVar('value'), stopOpacity: 0 })] }) }), _jsx(CartesianGrid, { vertical: false }), _jsx(XAxis, { dataKey: "label", tickLine: false, minTickGap: 24 }), _jsx(YAxis, { tickLine: false, width: 40, allowDecimals: false }), _jsx(ChartTooltip, { cursor: { stroke: 'var(--line)' }, content: _jsx(ChartTooltipContent, { ...(valueFormatter ? { valueFormatter: (v) => valueFormatter(v) } : {}) }) }), _jsx(Area, { type: "monotone", dataKey: "value", name: valueLabel, stroke: chartColorVar('value'), strokeWidth: 2, fill: `url(#${gradientId})`, isAnimationActive: false, dot: false, activeDot: { r: 3 } }), showBrush && _jsx(Brush, { ...chartBrushProps, dataKey: "label" })] }) })) }));
|
|
11
38
|
}
|
|
12
39
|
//# sourceMappingURL=area-chart-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-chart-card.js","sourceRoot":"","sources":["../../../../src/react/components/charts/area-chart-card.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"area-chart-card.js","sourceRoot":"","sources":["../../../../src/react/components/charts/area-chart-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { JSX, ReactNode } from 'react';
|
|
2
|
+
import { type ChartSelection } from './chart-selection.js';
|
|
1
3
|
export interface BarChartDatum {
|
|
2
4
|
/** Category label on the x-axis (or y-axis when horizontal). */
|
|
3
5
|
label: string;
|
|
@@ -5,22 +7,31 @@ export interface BarChartDatum {
|
|
|
5
7
|
value: number;
|
|
6
8
|
/** Optional per-bar color override. */
|
|
7
9
|
color?: string;
|
|
8
|
-
/** Optional stable identifier carried through to {@link
|
|
10
|
+
/** Optional stable identifier carried through to {@link BarChartCardProps.onSelect}. */
|
|
9
11
|
id?: string;
|
|
10
12
|
}
|
|
11
|
-
|
|
12
|
-
export declare function BarChartCard({ title, data, right, color, valueLabel, height, horizontal, truncateLabel, onBarClick, }: {
|
|
13
|
+
export interface BarChartCardProps {
|
|
13
14
|
title: string;
|
|
14
15
|
data: BarChartDatum[];
|
|
15
|
-
right?:
|
|
16
|
+
right?: ReactNode;
|
|
16
17
|
color?: string;
|
|
17
18
|
valueLabel?: string;
|
|
18
19
|
height?: number;
|
|
19
20
|
/** Render category labels down the Y axis so long labels read left-to-right. */
|
|
20
21
|
horizontal?: boolean;
|
|
21
|
-
/** Truncate tick labels to this many chars (full label stays in the
|
|
22
|
+
/** Truncate tick labels to this many chars (full label stays in the hover card). */
|
|
22
23
|
truncateLabel?: number;
|
|
23
|
-
/**
|
|
24
|
+
/** Format the value in the hover card (the axis is left alone). */
|
|
25
|
+
valueFormatter?: (value: number) => ReactNode;
|
|
26
|
+
/** Drill-down: called with the bar under a click. Omit and the chart is inert. */
|
|
27
|
+
onSelect?: (selection: ChartSelection) => void;
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated Use {@link BarChartCardProps.onSelect}, which reports the same
|
|
30
|
+
* click in the shape every chart card uses. Still called, so existing callers
|
|
31
|
+
* keep working.
|
|
32
|
+
*/
|
|
24
33
|
onBarClick?: (datum: BarChartDatum) => void;
|
|
25
|
-
}
|
|
34
|
+
}
|
|
35
|
+
/** Categorical bar chart (e.g. per-queue failure rate) with a hover card. */
|
|
36
|
+
export declare function BarChartCard({ title, data, right, color, valueLabel, height, horizontal, truncateLabel, valueFormatter, onSelect, onBarClick, }: BarChartCardProps): JSX.Element;
|
|
26
37
|
//# sourceMappingURL=bar-chart-card.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bar-chart-card.d.ts","sourceRoot":"","sources":["../../../../src/react/components/charts/bar-chart-card.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bar-chart-card.d.ts","sourceRoot":"","sources":["../../../../src/react/components/charts/bar-chart-card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAU5C,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,sBAAsB,CAAC;AAG3E,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAQD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAC9C,kFAAkF;IAClF,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC7C;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAI,EACJ,KAAK,EACL,KAAkB,EAClB,UAAoB,EACpB,MAAY,EACZ,UAAkB,EAClB,aAAa,EACb,cAAc,EACd,QAAQ,EACR,UAAU,GACX,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CAsFjC"}
|
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { Bar, BarChart, CartesianGrid, Cell, XAxis, YAxis } from 'recharts';
|
|
4
|
+
import { ChartContainer, ChartTooltip, ChartTooltipContent, chartColorVar, } from '../../ui/chart.js';
|
|
3
5
|
import { ChartCard, ChartEmptyState } from './chart-card.js';
|
|
4
|
-
import {
|
|
6
|
+
import { chartSelection } from './chart-selection.js';
|
|
7
|
+
import { ACCENT_HEX, chartConfig } from './chart-theme.js';
|
|
5
8
|
/** Truncate a long category label to `max` chars with a trailing ellipsis. */
|
|
6
9
|
function truncate(label, max) {
|
|
7
10
|
if (label.length <= max)
|
|
8
11
|
return label;
|
|
9
12
|
return `${label.slice(0, Math.max(0, max - 1))}…`;
|
|
10
13
|
}
|
|
11
|
-
/** Categorical bar chart (e.g. per-queue failure rate) with a hover
|
|
12
|
-
export function BarChartCard({ title, data, right, color = ACCENT_HEX, valueLabel = 'value', height = 220, horizontal = false, truncateLabel, onBarClick, }) {
|
|
14
|
+
/** Categorical bar chart (e.g. per-queue failure rate) with a hover card. */
|
|
15
|
+
export function BarChartCard({ title, data, right, color = ACCENT_HEX, valueLabel = 'value', height = 220, horizontal = false, truncateLabel, valueFormatter, onSelect, onBarClick, }) {
|
|
13
16
|
const bodyHeight = height - 64;
|
|
17
|
+
const config = useMemo(() => chartConfig(['value'], () => color, () => valueLabel), [color, valueLabel]);
|
|
14
18
|
function handleBarClick(_value, index) {
|
|
15
19
|
const datum = data[index];
|
|
16
|
-
if (datum
|
|
17
|
-
|
|
20
|
+
if (!datum)
|
|
21
|
+
return;
|
|
22
|
+
onBarClick?.(datum);
|
|
23
|
+
onSelect?.(chartSelection({ label: datum.label, id: datum.id, value: datum.value }));
|
|
18
24
|
}
|
|
19
|
-
//
|
|
25
|
+
// Optional props are built conditionally: under `exactOptionalPropertyTypes` an
|
|
20
26
|
// explicit `undefined` is not assignable to Recharts' optional handlers.
|
|
21
27
|
const tickFormatterProps = truncateLabel !== undefined
|
|
22
28
|
? { tickFormatter: (value) => truncate(value, truncateLabel) }
|
|
23
29
|
: {};
|
|
24
|
-
const
|
|
25
|
-
|
|
30
|
+
const interactive = onSelect !== undefined || onBarClick !== undefined;
|
|
31
|
+
const barInteractionProps = interactive
|
|
32
|
+
? { onClick: handleBarClick, cursor: 'pointer' }
|
|
33
|
+
: {};
|
|
34
|
+
return (_jsx(ChartCard, { title: title, right: right, height: bodyHeight, children: data.length === 0 ? (_jsx(ChartEmptyState, { height: bodyHeight })) : (_jsx(ChartContainer, { config: config, children: _jsxs(BarChart, { data: data, layout: horizontal ? 'vertical' : 'horizontal', margin: { top: 4, right: 8, bottom: 0, left: horizontal ? 8 : -16 }, children: [_jsx(CartesianGrid, { horizontal: !horizontal, vertical: horizontal }), horizontal ? (_jsx(XAxis, { type: "number", tickLine: false, allowDecimals: false })) : (_jsx(XAxis, { dataKey: "label", tickLine: false, interval: 0, ...tickFormatterProps })), horizontal ? (_jsx(YAxis, { type: "category", dataKey: "label", tickLine: false, width: 160, interval: 0, ...tickFormatterProps })) : (_jsx(YAxis, { tickLine: false, width: 40, allowDecimals: false })), _jsx(ChartTooltip, { cursor: { fill: 'color-mix(in srgb, var(--text) 5%, transparent)' }, content: _jsx(ChartTooltipContent, { ...(valueFormatter ? { valueFormatter: (v) => valueFormatter(v) } : {}) }) }), _jsx(Bar, { dataKey: "value", name: valueLabel, fill: chartColorVar('value'), radius: horizontal ? [0, 3, 3, 0] : [3, 3, 0, 0], isAnimationActive: false, ...barInteractionProps, children: data.map((datum) => (_jsx(Cell, { fill: datum.color ?? chartColorVar('value') }, datum.id ?? datum.label))) })] }) })) }));
|
|
26
35
|
}
|
|
27
36
|
//# sourceMappingURL=bar-chart-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bar-chart-card.js","sourceRoot":"","sources":["../../../../src/react/components/charts/bar-chart-card.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"bar-chart-card.js","sourceRoot":"","sources":["../../../../src/react/components/charts/bar-chart-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
import { type ChartSelection } from './chart-selection.js';
|
|
3
|
+
export interface BreakdownSegment {
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
color?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Donut (default) or single stacked bar showing how a total splits by category. */
|
|
9
|
+
export declare function BreakdownCard({ title, segments, style, height, onSelect, }: {
|
|
10
|
+
title: string;
|
|
11
|
+
segments: BreakdownSegment[];
|
|
12
|
+
style?: 'donut' | 'bar';
|
|
13
|
+
height?: number;
|
|
14
|
+
/** Drill-down: called with the segment under a click. Omit and the chart is inert. */
|
|
15
|
+
onSelect?: (selection: ChartSelection) => void;
|
|
16
|
+
}): JSX.Element;
|
|
17
|
+
//# sourceMappingURL=breakdown-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakdown-card.d.ts","sourceRoot":"","sources":["../../../../src/react/components/charts/breakdown-card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAWjC,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,sBAAsB,CAAC;AAG3E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,QAAQ,EACR,KAAe,EACf,MAAY,EACZ,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CAChD,GAAG,GAAG,CAAC,OAAO,CA2Fd"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { Bar, BarChart, Cell, Pie, PieChart } from 'recharts';
|
|
4
|
+
import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, } from '../../ui/chart.js';
|
|
5
|
+
import { ChartCard, ChartEmptyState } from './chart-card.js';
|
|
6
|
+
import { chartSelection } from './chart-selection.js';
|
|
7
|
+
import { chartConfig, hexForSegment } from './chart-theme.js';
|
|
8
|
+
/** Donut (default) or single stacked bar showing how a total splits by category. */
|
|
9
|
+
export function BreakdownCard({ title, segments, style = 'donut', height = 220, onSelect, }) {
|
|
10
|
+
const bodyHeight = height - 64;
|
|
11
|
+
const config = useMemo(() => chartConfig(segments.map((s) => s.label), (label, index) => hexForSegment(label, index, segments[index]?.color)), [segments]);
|
|
12
|
+
function select(index) {
|
|
13
|
+
const segment = segments[index];
|
|
14
|
+
if (segment && onSelect) {
|
|
15
|
+
onSelect(chartSelection({ label: segment.label, value: segment.value }));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// Recharts hands a click handler its own datum first; the index is what we
|
|
19
|
+
// actually key off, so the datum is deliberately ignored.
|
|
20
|
+
const clickProps = onSelect
|
|
21
|
+
? { onClick: (_datum, index) => select(index), cursor: 'pointer' }
|
|
22
|
+
: {};
|
|
23
|
+
if (segments.length === 0) {
|
|
24
|
+
return (_jsx(ChartCard, { title: title, height: bodyHeight, children: _jsx(ChartEmptyState, { height: bodyHeight }) }));
|
|
25
|
+
}
|
|
26
|
+
if (style === 'bar') {
|
|
27
|
+
// One row, one stacked bar per segment: the chart is a single 100% bar, so
|
|
28
|
+
// every segment is its own series rather than a row in a shared one.
|
|
29
|
+
const row = [
|
|
30
|
+
{ name: 'breakdown', ...Object.fromEntries(segments.map((s) => [s.label, s.value])) },
|
|
31
|
+
];
|
|
32
|
+
return (_jsx(ChartCard, { title: title, height: bodyHeight, children: _jsx(ChartContainer, { config: config, children: _jsxs(BarChart, { data: row, layout: "vertical", children: [_jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { hideLabel: true }) }), _jsx(ChartLegend, { content: _jsx(ChartLegendContent, {}) }), segments.map((segment, index) => (_jsx(Bar, { dataKey: segment.label, stackId: "a", fill: hexForSegment(segment.label, index, segment.color), isAnimationActive: false, ...(onSelect ? { onClick: () => select(index), cursor: 'pointer' } : {}) }, segment.label)))] }) }) }));
|
|
33
|
+
}
|
|
34
|
+
const pieData = segments.map((segment, index) => ({
|
|
35
|
+
name: segment.label,
|
|
36
|
+
value: segment.value,
|
|
37
|
+
// `color` (not `fill`) so the hover card and the legend resolve the segment's
|
|
38
|
+
// own hue — see `seriesColor` in the vendored chart layer.
|
|
39
|
+
color: hexForSegment(segment.label, index, segment.color),
|
|
40
|
+
}));
|
|
41
|
+
return (_jsx(ChartCard, { title: title, height: bodyHeight, children: _jsx(ChartContainer, { config: config, children: _jsxs(PieChart, { children: [_jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { hideLabel: true }) }), _jsx(ChartLegend, { content: _jsx(ChartLegendContent, {}) }), _jsx(Pie, { data: pieData, dataKey: "value", nameKey: "name", innerRadius: "55%", outerRadius: "80%", isAnimationActive: false, ...clickProps, children: pieData.map((entry) => (_jsx(Cell, { fill: entry.color }, entry.name))) })] }) }) }));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=breakdown-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakdown-card.js","sourceRoot":"","sources":["../../../../src/react/components/charts/breakdown-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,13 @@ export declare function ChartCard({ title, right, height, children, }: {
|
|
|
5
5
|
height?: number;
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
}): JSX.Element;
|
|
8
|
+
/**
|
|
9
|
+
* "Nothing in this window" body. `height` is optional: given one it reserves
|
|
10
|
+
* exactly the space the chart would have taken, and without one it fills its
|
|
11
|
+
* parent — which is what a card that puts something else (percentile chips) above
|
|
12
|
+
* the chart needs, since there the chart's share of the body is not the card's
|
|
13
|
+
* height.
|
|
14
|
+
*/
|
|
8
15
|
export declare function ChartEmptyState({ height }: {
|
|
9
16
|
height?: number;
|
|
10
17
|
}): JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-card.d.ts","sourceRoot":"","sources":["../../../../src/react/components/charts/chart-card.tsx"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,MAAY,EACZ,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"chart-card.d.ts","sourceRoot":"","sources":["../../../../src/react/components/charts/chart-card.tsx"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,MAAY,EACZ,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,GAAG,GAAG,CAAC,OAAO,CAYd;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAS5E"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/** Shared card chrome (title, optional right slot, framed body) for every chart card. */
|
|
3
3
|
export function ChartCard({ title, right, height = 220, children, }) {
|
|
4
|
-
return (_jsxs("section", { className: "rounded-lg border border-
|
|
4
|
+
return (_jsxs("section", { className: "rounded-lg border border-line bg-panel/40 p-4", children: [_jsxs("header", { className: "mb-3 flex items-center justify-between", children: [_jsx("h3", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: title }), right] }), _jsx("div", { style: { height }, children: children })] }));
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* "Nothing in this window" body. `height` is optional: given one it reserves
|
|
8
|
+
* exactly the space the chart would have taken, and without one it fills its
|
|
9
|
+
* parent — which is what a card that puts something else (percentile chips) above
|
|
10
|
+
* the chart needs, since there the chart's share of the body is not the card's
|
|
11
|
+
* height.
|
|
12
|
+
*/
|
|
13
|
+
export function ChartEmptyState({ height }) {
|
|
14
|
+
return (_jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", style: height === undefined ? undefined : { height }, children: "No data in window." }));
|
|
8
15
|
}
|
|
9
16
|
//# sourceMappingURL=chart-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-card.js","sourceRoot":"","sources":["../../../../src/react/components/charts/chart-card.tsx"],"names":[],"mappings":";AAAA,yFAAyF;AACzF,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,MAAM,GAAG,GAAG,EACZ,QAAQ,GAMT;IACC,OAAO,CACL,mBAAS,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"chart-card.js","sourceRoot":"","sources":["../../../../src/react/components/charts/chart-card.tsx"],"names":[],"mappings":";AAAA,yFAAyF;AACzF,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,MAAM,GAAG,GAAG,EACZ,QAAQ,GAMT;IACC,OAAO,CACL,mBAAS,SAAS,EAAC,+CAA+C,aAChE,kBAAQ,SAAS,EAAC,wCAAwC,aACxD,aAAI,SAAS,EAAC,mEAAmE,YAC9E,KAAK,GACH,EACJ,KAAK,IACC,EACT,cAAK,KAAK,EAAE,EAAE,MAAM,EAAE,YAAG,QAAQ,GAAO,IAChC,CACX,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,EAAE,MAAM,EAAuB;IAC7D,OAAO,CACL,cACE,SAAS,EAAC,uEAAuE,EACjF,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,mCAGhD,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a user clicked inside a chart, in the one shape every card reports it.
|
|
3
|
+
*
|
|
4
|
+
* This is the drill-down intent and nothing more: a card knows what was clicked,
|
|
5
|
+
* it does not know what that should filter. The caller decides — `PanelView`
|
|
6
|
+
* forwards the selection, the extension dashboard turns it into provider query
|
|
7
|
+
* state. Keeping the card ignorant is what lets the same `AreaChartCard` sit on
|
|
8
|
+
* the Overview page (where clicking means nothing and no callback is passed) and
|
|
9
|
+
* on an extension dashboard (where it filters the page).
|
|
10
|
+
*/
|
|
11
|
+
export interface ChartSelection {
|
|
12
|
+
/** The category, bucket or x-axis label under the click. */
|
|
13
|
+
label: string;
|
|
14
|
+
/** Series key when the chart draws more than one; absent for single-series charts. */
|
|
15
|
+
series?: string;
|
|
16
|
+
/** Provider-supplied stable id, when the datum carried one (topN items do). */
|
|
17
|
+
id?: string;
|
|
18
|
+
/** The value at the click, when the click resolved to a single datum. */
|
|
19
|
+
value?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build a {@link ChartSelection} without tripping `exactOptionalPropertyTypes`,
|
|
23
|
+
* which rejects an explicit `undefined` for an optional field. Every card builds
|
|
24
|
+
* its selection here so "no id" is consistently an absent key rather than a
|
|
25
|
+
* present `undefined` — the difference shows up the moment a selection is spread
|
|
26
|
+
* into a query object.
|
|
27
|
+
*/
|
|
28
|
+
export declare function chartSelection(input: {
|
|
29
|
+
label: string;
|
|
30
|
+
series?: string | undefined;
|
|
31
|
+
id?: string | undefined;
|
|
32
|
+
value?: number | undefined;
|
|
33
|
+
}): ChartSelection;
|
|
34
|
+
/**
|
|
35
|
+
* The x-axis label under a click on a cartesian chart.
|
|
36
|
+
*
|
|
37
|
+
* A click on an area or a line has no single datum — Recharts reports the whole
|
|
38
|
+
* hovered category in its chart-level event state instead, and types that state
|
|
39
|
+
* loosely enough that reading it is a runtime question, not a compile-time one.
|
|
40
|
+
* Returns undefined when the click landed on chrome (axis, legend, padding),
|
|
41
|
+
* which is the case a drill-down must ignore rather than fire an empty filter.
|
|
42
|
+
*/
|
|
43
|
+
export declare function activeChartLabel(state: unknown): string | undefined;
|
|
44
|
+
//# sourceMappingURL=chart-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-selection.d.ts","sourceRoot":"","sources":["../../../../src/react/components/charts/chart-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,GAAG,cAAc,CAOjB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAKnE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a {@link ChartSelection} without tripping `exactOptionalPropertyTypes`,
|
|
3
|
+
* which rejects an explicit `undefined` for an optional field. Every card builds
|
|
4
|
+
* its selection here so "no id" is consistently an absent key rather than a
|
|
5
|
+
* present `undefined` — the difference shows up the moment a selection is spread
|
|
6
|
+
* into a query object.
|
|
7
|
+
*/
|
|
8
|
+
export function chartSelection(input) {
|
|
9
|
+
return {
|
|
10
|
+
label: input.label,
|
|
11
|
+
...(input.series !== undefined ? { series: input.series } : {}),
|
|
12
|
+
...(input.id !== undefined ? { id: input.id } : {}),
|
|
13
|
+
...(input.value !== undefined ? { value: input.value } : {}),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return typeof value === 'object' && value !== null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The x-axis label under a click on a cartesian chart.
|
|
21
|
+
*
|
|
22
|
+
* A click on an area or a line has no single datum — Recharts reports the whole
|
|
23
|
+
* hovered category in its chart-level event state instead, and types that state
|
|
24
|
+
* loosely enough that reading it is a runtime question, not a compile-time one.
|
|
25
|
+
* Returns undefined when the click landed on chrome (axis, legend, padding),
|
|
26
|
+
* which is the case a drill-down must ignore rather than fire an empty filter.
|
|
27
|
+
*/
|
|
28
|
+
export function activeChartLabel(state) {
|
|
29
|
+
if (!isRecord(state))
|
|
30
|
+
return undefined;
|
|
31
|
+
const label = state.activeLabel;
|
|
32
|
+
if (typeof label === 'string' && label.length > 0)
|
|
33
|
+
return label;
|
|
34
|
+
return typeof label === 'number' ? String(label) : undefined;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=chart-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-selection.js","sourceRoot":"","sources":["../../../../src/react/components/charts/chart-selection.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,KAK9B;IACC,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC"}
|