@sentio/ui-dashboard 0.3.1 → 0.3.5

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
@@ -41,13 +41,17 @@ __export(index_exports, {
41
41
  ChartLegend: () => ChartLegend,
42
42
  ChartTooltip: () => ChartTooltip,
43
43
  ChartTypeButtonGroup: () => ChartTypeButtonGroup,
44
+ DEFAULT_HIGHLIGHT_KEY: () => DEFAULT_HIGHLIGHT_KEY,
44
45
  DataControls: () => DataControls,
46
+ EditDashboardDialog: () => EditDashboardDialog,
47
+ EditGroupDialog: () => EditGroupDialog,
45
48
  EventsFunctionCategories: () => EventsFunctionCategories,
46
49
  EventsFunctionMap: () => EventsFunctionMap,
47
50
  FunctionInput: () => FunctionInput,
48
51
  FunctionMap: () => FunctionMap,
49
52
  FunctionsCategories: () => FunctionsCategories,
50
53
  FunctionsPanel: () => FunctionsPanel,
54
+ HIGHLIGHT_COLORS: () => HIGHLIGHT_COLORS,
51
55
  LabelControls: () => LabelControls,
52
56
  LabelSearchProvider: () => LabelSearchProvider,
53
57
  LabelsInput: () => LabelsInput,
@@ -66,6 +70,7 @@ __export(index_exports, {
66
70
  ScatterControls: () => ScatterControls,
67
71
  ScatterIcon: () => ScatterIcon_default,
68
72
  SystemLabels: () => SystemLabels,
73
+ TableControls: () => TableControls,
69
74
  TableIcon: () => TableIcon_default,
70
75
  TimeSeriesChart: () => TimeSeriesChart,
71
76
  ValueControls: () => ValueControls,
@@ -78,9 +83,14 @@ __export(index_exports, {
78
83
  defaultDataConfig: () => defaultConfig5,
79
84
  defaultPieConfig: () => defaultConfig,
80
85
  defaultScatterConfig: () => defaultConfig6,
86
+ defaultTableConfig: () => defaultConfig7,
81
87
  defaultValueConfig: () => defaultConfig3,
82
88
  defaultValueControlsConfig: () => defaultConfig4,
89
+ getDefaultValueConfig: () => getDefaultValueConfig,
90
+ getHighlightHex: () => getHighlightHex,
83
91
  isAggrOrRollupFunction: () => isAggrOrRollupFunction,
92
+ resolveHeaderStyle: () => resolveHeaderStyle,
93
+ resolveHighlight: () => resolveHighlight,
84
94
  sentioColors: () => sentioColors,
85
95
  sentioTheme: () => sentioTheme,
86
96
  sentioThemeDark: () => sentioThemeDark,
@@ -5831,7 +5841,7 @@ var operators = {
5831
5841
  "<=": "less or equal"
5832
5842
  };
5833
5843
  var renderTreeLine = (index, isLast) => {
5834
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mr-2 flex h-12 w-3 flex-col items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex h-full w-full items-center", children: [
5844
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mr-2 flex w-3 flex-col items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex h-full w-full items-center", children: [
5835
5845
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5836
5846
  "div",
5837
5847
  {
@@ -5872,16 +5882,16 @@ function ValueStringMapping({ rules, onChange }) {
5872
5882
  })
5873
5883
  );
5874
5884
  }
5875
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex w-full flex-col rounded-md py-2", children: [
5885
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex w-full flex-col gap-2 rounded-md", children: [
5876
5886
  (rules || []).map((rule, index) => {
5877
5887
  const isLast = index === (rules || []).length - 1;
5878
5888
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
5879
5889
  "div",
5880
5890
  {
5881
- className: "text-text-foreground flex h-10 items-center py-1",
5891
+ className: "text-text-foreground flex h-8 items-center",
5882
5892
  children: [
5883
5893
  renderTreeLine(index, isLast),
5884
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "sm:text-ilabel inline-flex h-full items-center pr-3 font-medium", children: "If value is" }),
5894
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "sm:text-ilabel inline-flex h-full items-center pr-2 font-medium", children: "If value is" }),
5885
5895
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5886
5896
  "select",
5887
5897
  {
@@ -5910,7 +5920,7 @@ function ValueStringMapping({ rules, onChange }) {
5910
5920
  }
5911
5921
  }
5912
5922
  ),
5913
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "sm:text-ilabel inline-flex h-full items-center rounded-none px-3 font-medium", children: ", then show" }),
5923
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "sm:text-ilabel inline-flex h-full items-center rounded-none px-2 font-medium", children: ", then show" }),
5914
5924
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5915
5925
  "input",
5916
5926
  {
@@ -5929,16 +5939,10 @@ function ValueStringMapping({ rules, onChange }) {
5929
5939
  "button",
5930
5940
  {
5931
5941
  type: "button",
5932
- className: "mx-2",
5942
+ className: "text-text-foreground-disabled hover:text-primary-600 mx-2 cursor-pointer",
5933
5943
  "aria-label": "remove",
5934
5944
  onClick: () => removeRule(index),
5935
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5936
- import_lu7.LuTrash2,
5937
- {
5938
- className: "icon text-text-foreground-disabled",
5939
- "aria-hidden": "true"
5940
- }
5941
- )
5945
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lu7.LuTrash2, { className: "icon", "aria-hidden": "true" })
5942
5946
  }
5943
5947
  )
5944
5948
  ]
@@ -5946,18 +5950,16 @@ function ValueStringMapping({ rules, onChange }) {
5946
5950
  index
5947
5951
  );
5948
5952
  }),
5949
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
5953
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5950
5954
  import_ui_core21.Button,
5951
5955
  {
5952
5956
  type: "button",
5953
5957
  role: "secondary",
5954
- className: "mt-1 w-fit flex-none",
5958
+ className: "py-1.5! w-fit flex-none",
5955
5959
  "aria-label": "remove",
5956
5960
  onClick: addRule,
5957
- children: [
5958
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lu7.LuPlus, { className: (0, import_ui_core21.classNames)("h-4 w-4"), "aria-hidden": "true" }),
5959
- "Add Formatting Rule"
5960
- ]
5961
+ icon: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lu7.LuPlus, {}),
5962
+ children: "Add Formatting Rule"
5961
5963
  }
5962
5964
  )
5963
5965
  ] });
@@ -6607,6 +6609,558 @@ function ScatterControls({
6607
6609
  }
6608
6610
  );
6609
6611
  }
6612
+
6613
+ // src/charts/options/TableControls.tsx
6614
+ var import_react24 = require("react");
6615
+ var import_immer14 = require("immer");
6616
+ var import_lodash13 = require("lodash");
6617
+ var import_ui_core27 = require("@sentio/ui-core");
6618
+
6619
+ // src/charts/table-utils.ts
6620
+ var import_lodash12 = require("lodash");
6621
+ var TEMPLATE_TOKEN = /{{([\s\S]+?)}}/g;
6622
+ function sanitizeLabels(labels) {
6623
+ const result = {};
6624
+ for (const k in labels) {
6625
+ switch (k) {
6626
+ case "contract_name":
6627
+ result["contract"] = labels[k];
6628
+ break;
6629
+ case "contract_address":
6630
+ result["address"] = labels[k];
6631
+ break;
6632
+ }
6633
+ result[k] = labels[k];
6634
+ }
6635
+ return result;
6636
+ }
6637
+ function aliasTemplate(alias, labels) {
6638
+ if (alias) {
6639
+ try {
6640
+ const safe = sanitizeLabels(labels);
6641
+ return alias.replace(TEMPLATE_TOKEN, (_, m1) => {
6642
+ const value = safe[m1.trim()];
6643
+ return value == null ? `` : value;
6644
+ });
6645
+ } catch (e) {
6646
+ return alias;
6647
+ }
6648
+ }
6649
+ }
6650
+ function escapeColumnId(id) {
6651
+ return id.replace(/[\W_.]+/g, "_");
6652
+ }
6653
+ function getColumnNameId(labels, alias, displayName) {
6654
+ const s = aliasTemplate(alias, labels) || (0, import_lodash12.startCase)(displayName);
6655
+ return { columnName: s, columnId: escapeColumnId(s) };
6656
+ }
6657
+
6658
+ // src/charts/options/TableControls.tsx
6659
+ var import_jsx_runtime39 = require("react/jsx-runtime");
6660
+ var defaultConfig7 = {
6661
+ calculation: "LAST",
6662
+ sortColumns: [],
6663
+ showColumns: void 0,
6664
+ columnWidths: {},
6665
+ columnOrders: [],
6666
+ showPlainData: false,
6667
+ calculations: {},
6668
+ valueConfigs: {}
6669
+ };
6670
+ function getDefaultValueConfig(type) {
6671
+ switch (type) {
6672
+ case "NUMBER":
6673
+ return {
6674
+ ...defaultConfig4,
6675
+ valueFormatter: "NumberFormatter"
6676
+ };
6677
+ case "TIME":
6678
+ return {
6679
+ ...defaultConfig4,
6680
+ valueFormatter: "DateFormatter"
6681
+ };
6682
+ default:
6683
+ return {
6684
+ ...defaultConfig4,
6685
+ valueFormatter: "StringFormatter"
6686
+ };
6687
+ }
6688
+ }
6689
+ var CalculationItems3 = [
6690
+ { label: "All", value: "ALL" },
6691
+ { label: "Last", value: "LAST" },
6692
+ { label: "First", value: "FIRST" },
6693
+ { label: "Total", value: "TOTAL" },
6694
+ { label: "Mean", value: "MEAN" },
6695
+ { label: "Max", value: "MAX" },
6696
+ { label: "Min", value: "MIN" }
6697
+ ];
6698
+ function TableControls({ config, defaultOpen, onChange, data }) {
6699
+ config = (0, import_lodash13.defaults)({}, config, defaultConfig7);
6700
+ function onCalculationChange(col, cal) {
6701
+ config && onChange(
6702
+ (0, import_immer14.produce)(config, (draft) => {
6703
+ if (col === "") {
6704
+ delete draft.calculations;
6705
+ draft.calculation = cal;
6706
+ } else {
6707
+ draft.calculations = draft.calculations || {};
6708
+ draft.calculations[col] = cal;
6709
+ }
6710
+ })
6711
+ );
6712
+ }
6713
+ function onValueConfigChange(col, valueConfig) {
6714
+ config && onChange(
6715
+ (0, import_immer14.produce)(config, (draft) => {
6716
+ draft.valueConfigs = draft.valueConfigs || {};
6717
+ draft.valueConfigs[col] = valueConfig;
6718
+ })
6719
+ );
6720
+ }
6721
+ function onMapSeriesAsColumnsChange(checked) {
6722
+ config && onChange((0, import_immer14.produce)(config, (draft) => void (draft.showPlainData = checked)));
6723
+ }
6724
+ const calculations = (0, import_react24.useMemo)(() => {
6725
+ if (!config?.showPlainData) {
6726
+ return CalculationItems3.filter((item) => item.value !== "ALL");
6727
+ }
6728
+ return CalculationItems3;
6729
+ }, [config?.showPlainData]);
6730
+ const isSql = data?.result !== void 0;
6731
+ const columns = (0, import_react24.useMemo)(() => {
6732
+ if (config?.showPlainData) {
6733
+ return [];
6734
+ }
6735
+ const map = {};
6736
+ if (isSql) {
6737
+ const results = data?.result;
6738
+ if (results) {
6739
+ for (const [name, type] of Object.entries(results?.columnTypes || {})) {
6740
+ map[name] = {
6741
+ name,
6742
+ type
6743
+ };
6744
+ }
6745
+ }
6746
+ } else {
6747
+ const results = data?.results;
6748
+ for (const r of results || []) {
6749
+ for (const s of r?.matrix?.samples || []) {
6750
+ const { columnId, columnName } = getColumnNameId(
6751
+ s?.metric?.labels || {},
6752
+ r.alias,
6753
+ s.metric?.displayName
6754
+ );
6755
+ map[columnId] = {
6756
+ name: columnName
6757
+ };
6758
+ }
6759
+ }
6760
+ }
6761
+ return Object.keys(map).sort().map((k) => ({ columnId: k, column: map[k] }));
6762
+ }, [data, config]);
6763
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
6764
+ import_ui_core27.DisclosurePanel,
6765
+ {
6766
+ title: "Table Options",
6767
+ defaultOpen,
6768
+ containerClassName: "w-full bg-default-bg",
6769
+ children: [
6770
+ !isSql && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "min-h-8 flex items-center", children: [
6771
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "w-48 px-2", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6772
+ import_ui_core27.Checkbox,
6773
+ {
6774
+ checked: config?.showPlainData,
6775
+ onChange: onMapSeriesAsColumnsChange,
6776
+ label: "Show plain data"
6777
+ }
6778
+ ) }),
6779
+ config?.showPlainData && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex", children: [
6780
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "border-main sm:text-icontent inline-flex items-center rounded-l-md border border-r-0 bg-gray-50 px-3", children: "Calculation" }),
6781
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6782
+ "select",
6783
+ {
6784
+ value: config.calculation,
6785
+ className: "border-main text-text-foreground sm:text-icontent focus:border-primary-600 hover:border-primary-600 inline-flex items-center rounded-r-md border pl-4 pr-7 focus:ring-0",
6786
+ onChange: (e) => {
6787
+ onCalculationChange("", e.target.value);
6788
+ },
6789
+ children: calculations.map((d) => {
6790
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: d.value, children: d.label }, d.value);
6791
+ })
6792
+ }
6793
+ )
6794
+ ] }),
6795
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", {})
6796
+ ] }),
6797
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "divide-border-color flex flex-col gap-2 divide-y", children: columns.map(({ columnId, column }) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-start pb-2", children: [
6798
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("h4", { className: "text-text-foreground text-icontent leading-7.5 w-48 px-2 font-medium", children: column.name }),
6799
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-1 flex-wrap items-start gap-2 rounded-md", children: [
6800
+ !isSql && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex", children: [
6801
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "sm:text-ilabel border-main inline-flex items-center rounded-l-md border border-r-0 bg-gray-50 px-3", children: "Calculation" }),
6802
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6803
+ "select",
6804
+ {
6805
+ value: config?.calculations && config?.calculations[columnId] || "LAST",
6806
+ className: "border-main text-text-foreground sm:text-icontent focus:border-primary-600 hover:border-primary-600 inline-flex items-center rounded-r-md border pl-4 pr-7 focus:ring-0",
6807
+ onChange: (e) => onCalculationChange(
6808
+ columnId,
6809
+ e.target.value
6810
+ ),
6811
+ children: calculations.map((d) => {
6812
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: d.value, children: d.label }, d.value);
6813
+ })
6814
+ }
6815
+ )
6816
+ ] }),
6817
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6818
+ ValueOptions,
6819
+ {
6820
+ onChange: (cfg) => onValueConfigChange(columnId, cfg),
6821
+ config: config?.valueConfigs && config.valueConfigs[columnId] || getDefaultValueConfig(column.type)
6822
+ }
6823
+ )
6824
+ ] })
6825
+ ] }, columnId)) })
6826
+ ]
6827
+ }
6828
+ );
6829
+ }
6830
+
6831
+ // src/dashboard/EditDashboardDialog.tsx
6832
+ var import_react25 = require("react");
6833
+ var import_ui_core28 = require("@sentio/ui-core");
6834
+ var import_jsx_runtime40 = require("react/jsx-runtime");
6835
+ var EditDashboardDialog = ({
6836
+ dashboard,
6837
+ open,
6838
+ onClose,
6839
+ onUpdate
6840
+ }) => {
6841
+ const [processing, setProcessing] = (0, import_react25.useState)(false);
6842
+ const [updateDisabled, setUpdateDisabled] = (0, import_react25.useState)(true);
6843
+ const inputElementRef = (0, import_react25.useRef)(null);
6844
+ const onCloseAndReset = (0, import_react25.useCallback)(() => {
6845
+ onClose?.();
6846
+ if (dashboard?.name && inputElementRef.current) {
6847
+ inputElementRef.current.value = dashboard.name;
6848
+ }
6849
+ }, [onClose, dashboard?.name]);
6850
+ const onOk = (0, import_react25.useCallback)(() => {
6851
+ if (!inputElementRef.current?.value) {
6852
+ return;
6853
+ }
6854
+ setProcessing(true);
6855
+ onUpdate({ ...dashboard, name: inputElementRef.current?.value }).then(() => {
6856
+ onCloseAndReset();
6857
+ }).finally(() => {
6858
+ setProcessing(false);
6859
+ });
6860
+ }, [onCloseAndReset, onUpdate, dashboard]);
6861
+ (0, import_react25.useEffect)(() => {
6862
+ if (open && dashboard?.name && inputElementRef.current) {
6863
+ inputElementRef.current.value = dashboard.name;
6864
+ }
6865
+ }, [open, dashboard?.name]);
6866
+ const onInputChange = (0, import_react25.useCallback)(
6867
+ (evt) => {
6868
+ const value = evt.target.value;
6869
+ if (!value || value === dashboard?.name) {
6870
+ setUpdateDisabled(true);
6871
+ } else {
6872
+ setUpdateDisabled(false);
6873
+ }
6874
+ },
6875
+ [dashboard?.name]
6876
+ );
6877
+ const okProps = (0, import_react25.useMemo)(
6878
+ () => ({
6879
+ processing,
6880
+ disabled: updateDisabled
6881
+ }),
6882
+ [updateDisabled, processing]
6883
+ );
6884
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6885
+ import_ui_core28.BaseDialog,
6886
+ {
6887
+ title: "Edit Dashboard",
6888
+ open,
6889
+ onClose: onCloseAndReset,
6890
+ cancelText: "Close",
6891
+ onCancel: onCloseAndReset,
6892
+ onOk,
6893
+ okProps,
6894
+ okText: "Update",
6895
+ footerBorder: false,
6896
+ initialFocus: inputElementRef,
6897
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6898
+ "form",
6899
+ {
6900
+ method: "dialog",
6901
+ className: "text-text-foreground relative mb-4 mt-2 px-4",
6902
+ onSubmit: onOk,
6903
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "grid py-2 text-sm", children: [
6904
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "sm:text-ilabel text-text-foreground-secondary mb-2 mt-1", children: "Dashboard Name" }),
6905
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6906
+ "input",
6907
+ {
6908
+ defaultValue: dashboard?.name,
6909
+ placeholder: "Provide a new name for your dashboard",
6910
+ type: "text",
6911
+ required: true,
6912
+ name: "dashboard-name",
6913
+ id: "new-dashboard-name",
6914
+ className: "focus:border-primary-600 focus:ring-primary-600/30 focus:ring-3 hover:border-primary-600 sm:text-ilabel border-main block w-full rounded-md",
6915
+ ref: inputElementRef,
6916
+ onChange: onInputChange
6917
+ }
6918
+ )
6919
+ ] })
6920
+ }
6921
+ )
6922
+ }
6923
+ );
6924
+ };
6925
+
6926
+ // src/dashboard/EditGroupDialog.tsx
6927
+ var import_react26 = require("react");
6928
+ var import_ui_core29 = require("@sentio/ui-core");
6929
+ var import_lu9 = require("react-icons/lu");
6930
+
6931
+ // src/dashboard/group-styles.ts
6932
+ var CLASSIC_INDEX = {
6933
+ blue: 0,
6934
+ cyan: 1,
6935
+ pink: 2,
6936
+ yellow: 3,
6937
+ green: 4,
6938
+ lightblue: 5,
6939
+ purple: 6,
6940
+ red: 7,
6941
+ orange: 8
6942
+ };
6943
+ var HIGHLIGHT_COLORS = [
6944
+ { key: "green", name: "Sentio Green" },
6945
+ { key: "blue", name: "Sentio Blue" },
6946
+ { key: "cyan", name: "Sentio Cyan" },
6947
+ { key: "lightblue", name: "Sentio Light Blue" },
6948
+ { key: "purple", name: "Sentio Purple" },
6949
+ { key: "pink", name: "Sentio Pink" },
6950
+ { key: "red", name: "Sentio Red" },
6951
+ { key: "orange", name: "Sentio Orange" },
6952
+ { key: "yellow", name: "Sentio Yellow" }
6953
+ ];
6954
+ var DEFAULT_HIGHLIGHT_KEY = "green";
6955
+ function getHighlightHex(key, isDark) {
6956
+ if (!key) return void 0;
6957
+ const idx = CLASSIC_INDEX[key];
6958
+ if (idx === void 0) return void 0;
6959
+ return sentioColors[isDark ? "dark" : "light"].classic[idx];
6960
+ }
6961
+ function readableForeground(hex) {
6962
+ const m = hex.replace("#", "");
6963
+ const r = parseInt(m.slice(0, 2), 16) / 255;
6964
+ const g = parseInt(m.slice(2, 4), 16) / 255;
6965
+ const b = parseInt(m.slice(4, 6), 16) / 255;
6966
+ const lin = (v) => v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
6967
+ const L = 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
6968
+ return L > 0.5 ? "#1f2937" : "#ffffff";
6969
+ }
6970
+ function resolveHighlight(colorKey, isDark) {
6971
+ const hex = getHighlightHex(colorKey, isDark) ?? getHighlightHex(DEFAULT_HIGHLIGHT_KEY, isDark);
6972
+ return { solid: hex, foreground: readableForeground(hex) };
6973
+ }
6974
+ function resolveHeaderStyle(style, colorKey, isDark) {
6975
+ if (!style || style === "DEFAULT") return {};
6976
+ const color = resolveHighlight(colorKey, isDark);
6977
+ return { backgroundColor: color.solid, color: color.foreground };
6978
+ }
6979
+
6980
+ // src/dashboard/EditGroupDialog.tsx
6981
+ var import_jsx_runtime41 = require("react/jsx-runtime");
6982
+ function StyleCard({ selected, label, onClick, preview }) {
6983
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
6984
+ "button",
6985
+ {
6986
+ type: "button",
6987
+ onClick,
6988
+ className: (0, import_ui_core29.classNames)(
6989
+ "flex flex-col items-stretch overflow-hidden rounded-lg border bg-white text-left transition-colors",
6990
+ "dark:bg-default-bg",
6991
+ selected ? "border-primary-600 ring-primary-600/30 ring-3 shadow-sm" : "border-main hover:border-primary-400"
6992
+ ),
6993
+ children: [
6994
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "bg-hover/40 flex h-28 items-center justify-center", children: preview }),
6995
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
6996
+ "div",
6997
+ {
6998
+ className: (0, import_ui_core29.classNames)(
6999
+ "border-main flex items-center justify-center gap-1.5 border-t px-2 py-2 text-sm",
7000
+ selected ? "text-primary-600 font-semibold" : "text-text-foreground font-medium"
7001
+ ),
7002
+ children: [
7003
+ selected && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lu9.LuCheck, { className: "h-3.5 w-3.5" }),
7004
+ label
7005
+ ]
7006
+ }
7007
+ )
7008
+ ]
7009
+ }
7010
+ );
7011
+ }
7012
+ function DefaultPreview() {
7013
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "border-main bg-default-bg text-text-foreground flex h-16 w-32 items-center rounded border px-2 text-base", children: "Title" });
7014
+ }
7015
+ function EmphasisPreview({
7016
+ color
7017
+ }) {
7018
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "border-main bg-default-bg flex h-16 w-32 flex-col rounded border", children: [
7019
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7020
+ "div",
7021
+ {
7022
+ className: "flex h-9 items-center justify-center text-sm font-semibold",
7023
+ style: { backgroundColor: color.solid, color: color.foreground },
7024
+ children: "Title"
7025
+ }
7026
+ ),
7027
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex-1" })
7028
+ ] });
7029
+ }
7030
+ function EditGroupDialog({
7031
+ open,
7032
+ onClose,
7033
+ title,
7034
+ style,
7035
+ highlightColor,
7036
+ onSave
7037
+ }) {
7038
+ const [draftTitle, setDraftTitle] = (0, import_react26.useState)(title);
7039
+ const [draftStyle, setDraftStyle] = (0, import_react26.useState)(style);
7040
+ const [draftColor, setDraftColor] = (0, import_react26.useState)(highlightColor);
7041
+ const titleRef = (0, import_react26.useRef)(null);
7042
+ const isDark = useDarkMode();
7043
+ (0, import_react26.useEffect)(() => {
7044
+ if (!open) return;
7045
+ setDraftTitle(title);
7046
+ setDraftStyle(style || "DEFAULT");
7047
+ setDraftColor(
7048
+ highlightColor || (style && style !== "DEFAULT" ? DEFAULT_HIGHLIGHT_KEY : "")
7049
+ );
7050
+ }, [open, title, style, highlightColor]);
7051
+ const previewColor = (0, import_react26.useMemo)(
7052
+ () => resolveHighlight(draftColor, isDark),
7053
+ [draftColor, isDark]
7054
+ );
7055
+ const onPickStyle = (next) => {
7056
+ setDraftStyle(next);
7057
+ if (next !== "DEFAULT" && !draftColor) {
7058
+ setDraftColor(DEFAULT_HIGHLIGHT_KEY);
7059
+ }
7060
+ };
7061
+ const onOk = () => {
7062
+ onSave({
7063
+ title: draftTitle.trim() || "Group",
7064
+ style: draftStyle,
7065
+ // Persist '' for DEFAULT so we don't pollute the model with an unused
7066
+ // color when the user reverts.
7067
+ highlightColor: draftStyle === "DEFAULT" ? "" : draftColor || DEFAULT_HIGHLIGHT_KEY
7068
+ });
7069
+ onClose();
7070
+ };
7071
+ const colorOptions = (0, import_react26.useMemo)(
7072
+ () => HIGHLIGHT_COLORS.map((c) => {
7073
+ const resolved = resolveHighlight(c.key, isDark);
7074
+ return {
7075
+ value: c.key,
7076
+ title: c.name,
7077
+ label: ({ selected }) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex w-full items-center gap-2.5 pr-2", children: [
7078
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7079
+ "div",
7080
+ {
7081
+ className: "flex h-5 w-5 items-center justify-center rounded text-xs font-bold",
7082
+ style: {
7083
+ backgroundColor: resolved.solid,
7084
+ color: resolved.foreground
7085
+ },
7086
+ children: "T"
7087
+ }
7088
+ ),
7089
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "flex-1 text-sm", children: c.name }),
7090
+ selected && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lu9.LuCheck, { className: "text-primary-600 h-4 w-4" })
7091
+ ] })
7092
+ };
7093
+ }),
7094
+ [isDark]
7095
+ );
7096
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7097
+ import_ui_core29.BaseDialog,
7098
+ {
7099
+ title: "Edit Group",
7100
+ open,
7101
+ onClose,
7102
+ cancelText: "Cancel",
7103
+ onCancel: onClose,
7104
+ onOk,
7105
+ okText: "Save",
7106
+ panelClassName: "sm:max-w-xl",
7107
+ initialFocus: titleRef,
7108
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "text-text-foreground px-4 pb-2 pt-4", children: [
7109
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("h4", { className: "text-text-foreground mb-3 text-sm font-semibold", children: "Display options" }),
7110
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { className: "text-text-foreground-secondary text-ilabel mb-1 block", children: "Title" }),
7111
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7112
+ "input",
7113
+ {
7114
+ ref: titleRef,
7115
+ type: "text",
7116
+ value: draftTitle,
7117
+ onChange: (e) => setDraftTitle(e.target.value),
7118
+ onKeyDown: (e) => {
7119
+ if (e.key === "Enter") {
7120
+ e.preventDefault();
7121
+ onOk();
7122
+ }
7123
+ },
7124
+ className: "focus:border-primary-600 focus:ring-primary-600/30 focus:ring-3 hover:border-primary-600 sm:text-ilabel border-main mb-4 block w-full rounded-md"
7125
+ }
7126
+ ),
7127
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "mb-4 grid grid-cols-2 gap-3", children: [
7128
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7129
+ StyleCard,
7130
+ {
7131
+ selected: draftStyle === "DEFAULT",
7132
+ label: "Default",
7133
+ onClick: () => onPickStyle("DEFAULT"),
7134
+ preview: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DefaultPreview, {})
7135
+ }
7136
+ ),
7137
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7138
+ StyleCard,
7139
+ {
7140
+ selected: draftStyle === "EMPHASIS",
7141
+ label: "Emphasis",
7142
+ onClick: () => onPickStyle("EMPHASIS"),
7143
+ preview: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(EmphasisPreview, { color: previewColor })
7144
+ }
7145
+ )
7146
+ ] }),
7147
+ draftStyle !== "DEFAULT" && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
7148
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { className: "text-text-foreground-secondary text-ilabel mb-1 block", children: "Highlight Color" }),
7149
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
7150
+ import_ui_core29.Select,
7151
+ {
7152
+ value: draftColor || DEFAULT_HIGHLIGHT_KEY,
7153
+ onChange: (v) => setDraftColor(v),
7154
+ options: colorOptions,
7155
+ size: "md",
7156
+ asLayer: true
7157
+ }
7158
+ )
7159
+ ] })
7160
+ ] })
7161
+ }
7162
+ );
7163
+ }
6610
7164
  // Annotate the CommonJS export names for ESM import in node:
6611
7165
  0 && (module.exports = {
6612
7166
  AggregateInput,
@@ -6620,13 +7174,17 @@ function ScatterControls({
6620
7174
  ChartLegend,
6621
7175
  ChartTooltip,
6622
7176
  ChartTypeButtonGroup,
7177
+ DEFAULT_HIGHLIGHT_KEY,
6623
7178
  DataControls,
7179
+ EditDashboardDialog,
7180
+ EditGroupDialog,
6624
7181
  EventsFunctionCategories,
6625
7182
  EventsFunctionMap,
6626
7183
  FunctionInput,
6627
7184
  FunctionMap,
6628
7185
  FunctionsCategories,
6629
7186
  FunctionsPanel,
7187
+ HIGHLIGHT_COLORS,
6630
7188
  LabelControls,
6631
7189
  LabelSearchProvider,
6632
7190
  LabelsInput,
@@ -6645,6 +7203,7 @@ function ScatterControls({
6645
7203
  ScatterControls,
6646
7204
  ScatterIcon,
6647
7205
  SystemLabels,
7206
+ TableControls,
6648
7207
  TableIcon,
6649
7208
  TimeSeriesChart,
6650
7209
  ValueControls,
@@ -6657,9 +7216,14 @@ function ScatterControls({
6657
7216
  defaultDataConfig,
6658
7217
  defaultPieConfig,
6659
7218
  defaultScatterConfig,
7219
+ defaultTableConfig,
6660
7220
  defaultValueConfig,
6661
7221
  defaultValueControlsConfig,
7222
+ getDefaultValueConfig,
7223
+ getHighlightHex,
6662
7224
  isAggrOrRollupFunction,
7225
+ resolveHeaderStyle,
7226
+ resolveHighlight,
6663
7227
  sentioColors,
6664
7228
  sentioTheme,
6665
7229
  sentioThemeDark,