@sentio/ui-dashboard 0.3.7 → 0.3.8

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/dist/index.js CHANGED
@@ -63,6 +63,7 @@ __export(index_exports, {
63
63
  PieChartControls: () => PieChartControls,
64
64
  PieIcon: () => PieIcon_default,
65
65
  QueryValueChart: () => QueryValueChart,
66
+ QueryValueControls: () => QueryValueControls,
66
67
  QueryValueIcon: () => QueryValueIcon_default,
67
68
  ReactEChartsBase: () => ReactEChartsBase,
68
69
  RefreshButton: () => RefreshButton,
@@ -70,10 +71,12 @@ __export(index_exports, {
70
71
  ScatterChartTooltip: () => ScatterChartTooltip,
71
72
  ScatterControls: () => ScatterControls,
72
73
  ScatterIcon: () => ScatterIcon_default,
74
+ SeriesControls: () => SeriesControls,
73
75
  ShareDashboardDialog: () => ShareDashboardDialog,
74
76
  SystemLabels: () => SystemLabels,
75
77
  TableControls: () => TableControls,
76
78
  TableIcon: () => TableIcon_default,
79
+ TimeRangeOverride: () => TimeRangeOverride,
77
80
  TimeSeriesChart: () => TimeSeriesChart,
78
81
  ValueControls: () => ValueControls,
79
82
  ValueFormatters: () => ValueFormatters,
@@ -84,8 +87,10 @@ __export(index_exports, {
84
87
  defaultBarGaugeConfig: () => defaultConfig2,
85
88
  defaultDataConfig: () => defaultConfig5,
86
89
  defaultPieConfig: () => defaultConfig,
90
+ defaultQueryValueConfig: () => defaultConfig9,
87
91
  defaultScatterConfig: () => defaultConfig6,
88
92
  defaultTableConfig: () => defaultConfig7,
93
+ defaultTimeRangeOverrideConfig: () => defaultConfig8,
89
94
  defaultValueConfig: () => defaultConfig3,
90
95
  defaultValueControlsConfig: () => defaultConfig4,
91
96
  getDefaultValueConfig: () => getDefaultValueConfig,
@@ -4127,6 +4132,29 @@ function timeBefore(time, duration2, asStart = true) {
4127
4132
  return t.subtract(durationValue, import_ui_core11.TimeUnitShortNames[duration2.unit]);
4128
4133
  }
4129
4134
  }
4135
+ function fromTimeLike(tl) {
4136
+ if (!tl) {
4137
+ return void 0;
4138
+ }
4139
+ if (tl.relativeTime) {
4140
+ const value = tl.relativeTime.value || 0;
4141
+ return {
4142
+ value: Math.abs(value),
4143
+ unit: tl.relativeTime.unit,
4144
+ sign: value < 0 ? -1 : 1
4145
+ };
4146
+ }
4147
+ return import_dayjs4.default.unix(parseInt(tl.absoluteTime || ""));
4148
+ }
4149
+ function toTimeLike(t) {
4150
+ if (import_dayjs4.default.isDayjs(t)) {
4151
+ return { absoluteTime: `${t.unix()}` };
4152
+ }
4153
+ const rt = t;
4154
+ return {
4155
+ relativeTime: { unit: rt.unit, value: rt.sign * rt.value, align: rt.align }
4156
+ };
4157
+ }
4130
4158
 
4131
4159
  // src/charts/TimeSeriesChart.tsx
4132
4160
  var import_ui_core15 = require("@sentio/ui-core");
@@ -7378,6 +7406,375 @@ var ShareDashboardDialog = ({
7378
7406
  }
7379
7407
  );
7380
7408
  };
7409
+
7410
+ // src/dashboard/TimeRangeOverride.tsx
7411
+ var import_lodash14 = require("lodash");
7412
+ var import_immer15 = require("immer");
7413
+ var import_ui_core32 = require("@sentio/ui-core");
7414
+ var import_jsx_runtime44 = require("react/jsx-runtime");
7415
+ var defaultConfig8 = {
7416
+ enabled: false
7417
+ };
7418
+ function TimeRangeOverride({
7419
+ config,
7420
+ onChange,
7421
+ globalStartTime,
7422
+ globalEndTime,
7423
+ globalTz,
7424
+ onSetGlobalTimeRange
7425
+ }) {
7426
+ config = (0, import_lodash14.defaults)(config || {}, defaultConfig8);
7427
+ const setEnabled = (enabled) => {
7428
+ config && onChange(
7429
+ (0, import_immer15.produce)(config, (draft) => {
7430
+ draft.enabled = enabled;
7431
+ if (enabled) {
7432
+ draft.timeRange = {
7433
+ start: toTimeLike(globalStartTime),
7434
+ end: toTimeLike(globalEndTime),
7435
+ step: draft.timeRange?.step,
7436
+ interval: draft.timeRange?.interval,
7437
+ timezone: draft.timeRange?.timezone
7438
+ };
7439
+ }
7440
+ })
7441
+ );
7442
+ };
7443
+ function onTimeRangeChange(start, end, tz) {
7444
+ if (config?.enabled) {
7445
+ onChange(
7446
+ (0, import_immer15.produce)(config, (draft) => {
7447
+ draft.timeRange = {
7448
+ start: toTimeLike(start),
7449
+ end: toTimeLike(end),
7450
+ timezone: tz,
7451
+ step: draft.timeRange?.step,
7452
+ interval: draft.timeRange?.interval
7453
+ };
7454
+ })
7455
+ );
7456
+ } else {
7457
+ onSetGlobalTimeRange(start, end, tz);
7458
+ }
7459
+ }
7460
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-wrap items-center gap-4 p-2", children: [
7461
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
7462
+ import_ui_core32.Switch,
7463
+ {
7464
+ checked: config.enabled || false,
7465
+ onChange: setEnabled,
7466
+ label: "Override Global Time"
7467
+ }
7468
+ ) }),
7469
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
7470
+ import_ui_core32.TimeRangePicker,
7471
+ {
7472
+ startTime: config.enabled ? fromTimeLike(config.timeRange?.start) : globalStartTime,
7473
+ endTime: config.enabled ? fromTimeLike(config.timeRange?.end) : globalEndTime,
7474
+ tz: config.enabled ? config.timeRange?.timezone || globalTz : globalTz,
7475
+ onChange: onTimeRangeChange
7476
+ }
7477
+ )
7478
+ ] });
7479
+ }
7480
+
7481
+ // src/dashboard/SeriesControls.tsx
7482
+ var import_react29 = require("react");
7483
+ var import_ui_core33 = require("@sentio/ui-core");
7484
+ var import_react_virtual = require("@tanstack/react-virtual");
7485
+ var import_lu10 = require("react-icons/lu");
7486
+ var import_lodash15 = require("lodash");
7487
+ var import_react30 = require("@headlessui/react");
7488
+ var import_jsx_runtime45 = require("react/jsx-runtime");
7489
+ var seriesChartTypes = [
7490
+ {
7491
+ value: "default",
7492
+ label: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center", children: [
7493
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lu10.LuMountainSnow, { className: "mr-2 h-4 w-4" }),
7494
+ "Default"
7495
+ ] })
7496
+ },
7497
+ {
7498
+ value: "LINE",
7499
+ label: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center", children: [
7500
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(LineIcon_default, { className: "mr-2 h-4 w-4" }),
7501
+ "Line"
7502
+ ] })
7503
+ },
7504
+ {
7505
+ value: "BAR",
7506
+ label: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center", children: [
7507
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(BarIcon_default, { className: "mr-2 h-4 w-4" }),
7508
+ "Bar"
7509
+ ] })
7510
+ },
7511
+ {
7512
+ value: "AREA",
7513
+ label: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center", children: [
7514
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(AreaIcon_default, { className: "mr-2 h-4 w-4" }),
7515
+ "Area"
7516
+ ] })
7517
+ }
7518
+ ];
7519
+ var SeriesControls = ({
7520
+ config,
7521
+ setSeriesConfig,
7522
+ series,
7523
+ enabled
7524
+ }) => {
7525
+ const parentRef = (0, import_react29.useRef)(null);
7526
+ const [isDisclosureOpen, setIsDisclosureOpen] = (0, import_react29.useState)(true);
7527
+ const shouldVirtualize = series.length > 10;
7528
+ const virtualizer = (0, import_react_virtual.useVirtualizer)({
7529
+ count: shouldVirtualize && isDisclosureOpen ? series.length : 0,
7530
+ getScrollElement: () => parentRef.current,
7531
+ estimateSize: () => 40,
7532
+ overscan: 5
7533
+ // Render 5 extra items outside viewport for smooth scrolling
7534
+ });
7535
+ (0, import_react29.useLayoutEffect)(() => {
7536
+ if (isDisclosureOpen && shouldVirtualize && parentRef.current) {
7537
+ const timeoutId = setTimeout(() => {
7538
+ virtualizer.measure();
7539
+ }, 10);
7540
+ return () => clearTimeout(timeoutId);
7541
+ }
7542
+ }, [isDisclosureOpen, shouldVirtualize, virtualizer]);
7543
+ const handleSeriesTypeChange = (seriesName, selectedType) => {
7544
+ const currentSeriesConfig = config?.seriesConfig || { series: {} };
7545
+ if (selectedType === "default") {
7546
+ const newSeriesConfig2 = (0, import_lodash15.cloneDeep)(currentSeriesConfig);
7547
+ if (newSeriesConfig2.series && newSeriesConfig2.series[seriesName]) {
7548
+ delete newSeriesConfig2.series[seriesName];
7549
+ }
7550
+ setSeriesConfig(newSeriesConfig2);
7551
+ return;
7552
+ }
7553
+ const newSeriesConfig = {
7554
+ ...currentSeriesConfig,
7555
+ series: {
7556
+ ...currentSeriesConfig.series,
7557
+ [seriesName]: { type: selectedType }
7558
+ }
7559
+ };
7560
+ setSeriesConfig(newSeriesConfig);
7561
+ };
7562
+ const handleReset = () => {
7563
+ setSeriesConfig({ series: {} });
7564
+ };
7565
+ const renderSeriesItem = (seriesName) => {
7566
+ const currentType = config?.seriesConfig?.series?.[seriesName]?.type || "default";
7567
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
7568
+ "div",
7569
+ {
7570
+ className: "text-icontent inline-flex h-8 w-full basis-0 px-2",
7571
+ children: [
7572
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "sm:text-icontent bg-sentio-gray-100 dark:bg-sentio-gray-200 border-main inline-flex shrink items-center rounded-l-md border border-r-0 px-2 font-medium sm:min-w-[160px]", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "truncate", title: seriesName, children: seriesName }) }),
7573
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "sm:text-icontent bg-sentio-gray-100 dark:bg-sentio-gray-200 border-main inline-flex items-center whitespace-nowrap border border-r-0 px-2", children: "Show as" }),
7574
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "w-40", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7575
+ import_ui_core33.Select,
7576
+ {
7577
+ options: seriesChartTypes,
7578
+ value: currentType,
7579
+ onChange: (selectedType) => handleSeriesTypeChange(seriesName, selectedType),
7580
+ className: "focus:border-primary-500 sm:text-icontent border-main h-full rounded-r-md border",
7581
+ buttonClassName: "border-none! h-full!",
7582
+ placeholder: "Select chart type",
7583
+ asLayer: true
7584
+ }
7585
+ ) })
7586
+ ]
7587
+ },
7588
+ seriesName
7589
+ );
7590
+ };
7591
+ if (!enabled) {
7592
+ return null;
7593
+ }
7594
+ const titleWithReset = /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex w-full items-center justify-between pr-2", children: [
7595
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: `Series (${series.length})` }),
7596
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7597
+ "button",
7598
+ {
7599
+ type: "button",
7600
+ onClick: (e) => {
7601
+ e.stopPropagation();
7602
+ handleReset();
7603
+ },
7604
+ className: "rounded-sm bg-gray-200 px-2 py-1 text-xs transition-colors hover:bg-gray-300",
7605
+ title: "Reset all series to default",
7606
+ children: "Reset"
7607
+ }
7608
+ )
7609
+ ] });
7610
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react30.Disclosure, { defaultOpen: true, children: ({ open }) => {
7611
+ (0, import_react29.useEffect)(() => {
7612
+ setIsDisclosureOpen(open);
7613
+ }, [open]);
7614
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-default-bg w-full rounded-sm", children: [
7615
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
7616
+ import_react30.Disclosure.Button,
7617
+ {
7618
+ className: (0, import_ui_core33.classNames)(
7619
+ open ? "rounded-t" : "rounded-sm",
7620
+ "focus-visible:ring-primary-500/75 text-ilabel font-ilabel text-text-foreground hover:bg-sentio-gray-100 dark:hover:bg-sentio-gray-400 focus:outline-hidden focus-visible:ring-3 flex w-full px-2 py-1.5 text-left"
7621
+ ),
7622
+ children: [
7623
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7624
+ import_lu10.LuChevronRight,
7625
+ {
7626
+ className: (0, import_ui_core33.classNames)(
7627
+ open ? "rotate-90 transform" : "",
7628
+ "mr-1 h-5 w-5 self-center transition-all"
7629
+ )
7630
+ }
7631
+ ),
7632
+ titleWithReset
7633
+ ]
7634
+ }
7635
+ ),
7636
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react30.Disclosure.Panel, { className: "p-2", children: shouldVirtualize && open ? (
7637
+ // Virtualized rendering for large lists - only render when open
7638
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7639
+ "div",
7640
+ {
7641
+ ref: parentRef,
7642
+ className: "text-icontent h-[200px] overflow-auto",
7643
+ style: {
7644
+ contain: "strict"
7645
+ },
7646
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7647
+ "div",
7648
+ {
7649
+ style: {
7650
+ height: `${virtualizer?.getTotalSize() ?? 0}px`,
7651
+ width: "100%",
7652
+ position: "relative"
7653
+ },
7654
+ children: virtualizer?.getVirtualItems().map((virtualItem) => {
7655
+ const seriesName = series[virtualItem.index];
7656
+ if (!seriesName) return null;
7657
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
7658
+ "div",
7659
+ {
7660
+ style: {
7661
+ position: "absolute",
7662
+ top: 0,
7663
+ left: 0,
7664
+ width: "100%",
7665
+ height: `${virtualItem.size}px`,
7666
+ transform: `translateY(${virtualItem.start}px)`
7667
+ },
7668
+ children: renderSeriesItem(seriesName)
7669
+ },
7670
+ virtualItem.key
7671
+ );
7672
+ })
7673
+ }
7674
+ )
7675
+ }
7676
+ )
7677
+ ) : (
7678
+ // Normal rendering for small lists
7679
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "text-icontent flex max-h-[200px] flex-col gap-2 overflow-y-auto", children: series.map((seriesName) => renderSeriesItem(seriesName)) })
7680
+ ) })
7681
+ ] });
7682
+ } });
7683
+ };
7684
+
7685
+ // src/dashboard/QueryValueControls.tsx
7686
+ var import_immer16 = require("immer");
7687
+ var import_lodash16 = require("lodash");
7688
+ var import_ui_core34 = require("@sentio/ui-core");
7689
+ var import_jsx_runtime46 = require("react/jsx-runtime");
7690
+ var defaultConfig9 = {
7691
+ calculation: "LAST",
7692
+ colorTheme: {
7693
+ themeType: "Gray"
7694
+ },
7695
+ showBackgroundChart: false
7696
+ };
7697
+ var CalculationItems4 = [
7698
+ { label: "Last", value: "LAST" },
7699
+ { label: "First", value: "FIRST" },
7700
+ { label: "Total", value: "TOTAL" },
7701
+ { label: "Mean", value: "MEAN" },
7702
+ { label: "Max", value: "MAX" },
7703
+ { label: "Min", value: "MIN" }
7704
+ ];
7705
+ function QueryValueControls({
7706
+ config,
7707
+ defaultOpen,
7708
+ onChange,
7709
+ renderColorSelect
7710
+ }) {
7711
+ config = (0, import_lodash16.defaults)(config, defaultConfig9);
7712
+ function onCalculationChange(cal) {
7713
+ config && onChange((0, import_immer16.produce)(config, (draft) => void (draft.calculation = cal)));
7714
+ }
7715
+ function onSeriesCalculationChange(cal) {
7716
+ config && onChange((0, import_immer16.produce)(config, (draft) => void (draft.seriesCalculation = cal)));
7717
+ }
7718
+ function onSelectColor(c) {
7719
+ config && onChange(
7720
+ (0, import_immer16.produce)(config, (draft) => {
7721
+ draft.colorTheme = c.value;
7722
+ })
7723
+ );
7724
+ }
7725
+ function toggleShowBackgroundChart() {
7726
+ config && onChange(
7727
+ (0, import_immer16.produce)(config, (draft) => {
7728
+ draft.showBackgroundChart = !draft.showBackgroundChart;
7729
+ })
7730
+ );
7731
+ }
7732
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7733
+ import_ui_core34.DisclosurePanel,
7734
+ {
7735
+ title: "Query Value Options",
7736
+ defaultOpen,
7737
+ containerClassName: "w-full bg-default-bg",
7738
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-wrap items-center gap-4", children: [
7739
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "shadow-xs flex h-8 rounded-md", children: [
7740
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "sm:text-ilabel border-main text-text-foreground inline-flex items-center whitespace-nowrap rounded-l-md border bg-gray-50 px-3", children: "For each series, calculate the" }),
7741
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7742
+ "select",
7743
+ {
7744
+ value: config?.calculation,
7745
+ className: "sm:text-ilabel border-main text-text-foreground inline-flex items-center border border-x-0 py-0.5 pl-4 pr-7",
7746
+ onChange: (e) => onCalculationChange(e.target.value),
7747
+ children: CalculationItems4.map((d) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: d.value, children: d.label }, d.value))
7748
+ }
7749
+ ),
7750
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "sm:text-ilabel border-main text-text-foreground inline-flex items-center whitespace-nowrap border bg-gray-50 px-3", children: "value, then show the" }),
7751
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7752
+ "select",
7753
+ {
7754
+ value: config?.seriesCalculation,
7755
+ className: "sm:text-ilabel border-main text-text-foreground inline-flex items-center border border-x-0 py-0.5 pl-4 pr-7",
7756
+ onChange: (e) => onSeriesCalculationChange(e.target.value),
7757
+ children: CalculationItems4.map((d) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: d.value, children: d.label }, d.value))
7758
+ }
7759
+ ),
7760
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "sm:text-ilabel border-main text-text-foreground inline-flex items-center whitespace-nowrap rounded-r-md border bg-gray-50 px-3", children: "value of multiple series" })
7761
+ ] }),
7762
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "focus-within:ring-primary-500 shadow-xs border-main flex h-8 divide-x divide-gray-300 rounded-md border focus-within:border-transparent focus-within:ring-2", children: [
7763
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "sm:text-ilabel text-text-foreground inline-flex items-center whitespace-nowrap rounded-l-md bg-gray-50 px-3", children: "Color Theme" }),
7764
+ renderColorSelect(config?.colorTheme, onSelectColor)
7765
+ ] }),
7766
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
7767
+ import_ui_core34.Checkbox,
7768
+ {
7769
+ checked: config?.showBackgroundChart,
7770
+ onChange: toggleShowBackgroundChart,
7771
+ label: "Show Background Chart"
7772
+ }
7773
+ )
7774
+ ] })
7775
+ }
7776
+ );
7777
+ }
7381
7778
  // Annotate the CommonJS export names for ESM import in node:
7382
7779
  0 && (module.exports = {
7383
7780
  AggregateInput,
@@ -7413,6 +7810,7 @@ var ShareDashboardDialog = ({
7413
7810
  PieChartControls,
7414
7811
  PieIcon,
7415
7812
  QueryValueChart,
7813
+ QueryValueControls,
7416
7814
  QueryValueIcon,
7417
7815
  ReactEChartsBase,
7418
7816
  RefreshButton,
@@ -7420,10 +7818,12 @@ var ShareDashboardDialog = ({
7420
7818
  ScatterChartTooltip,
7421
7819
  ScatterControls,
7422
7820
  ScatterIcon,
7821
+ SeriesControls,
7423
7822
  ShareDashboardDialog,
7424
7823
  SystemLabels,
7425
7824
  TableControls,
7426
7825
  TableIcon,
7826
+ TimeRangeOverride,
7427
7827
  TimeSeriesChart,
7428
7828
  ValueControls,
7429
7829
  ValueFormatters,
@@ -7434,8 +7834,10 @@ var ShareDashboardDialog = ({
7434
7834
  defaultBarGaugeConfig,
7435
7835
  defaultDataConfig,
7436
7836
  defaultPieConfig,
7837
+ defaultQueryValueConfig,
7437
7838
  defaultScatterConfig,
7438
7839
  defaultTableConfig,
7840
+ defaultTimeRangeOverrideConfig,
7439
7841
  defaultValueConfig,
7440
7842
  defaultValueControlsConfig,
7441
7843
  getDefaultValueConfig,