@devtable/dashboard 1.11.0 → 1.14.0

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.
@@ -36,7 +36,7 @@ var __publicField = (obj, key, value) => {
36
36
  import React from "react";
37
37
  import _ from "lodash";
38
38
  import { WidthProvider, Responsive } from "react-grid-layout";
39
- import { Popover, Tooltip, Group, Text, ActionIcon, TextInput, Box, LoadingOverlay, Table, Select, Button, useMantineTheme, ColorSwatch, JsonInput, Anchor, Slider, ColorInput, Accordion, Switch, Modal, AppShell, Tabs, Menu, Divider, Container, SegmentedControl, Textarea } from "@mantine/core";
39
+ import { Popover, Tooltip, Group, Text, ActionIcon, TextInput, Box, LoadingOverlay, Table, Select, Button, useMantineTheme, ColorSwatch, SegmentedControl, NumberInput, Switch, Slider, ColorInput, Accordion, JsonInput, Modal, AppShell, Tabs, Menu, Divider, Container, Textarea } from "@mantine/core";
40
40
  import { useRequest } from "ahooks";
41
41
  import axios from "axios";
42
42
  import { InfoCircle, DeviceFloppy, Refresh, Trash, PlaylistAdd, Settings, Resize, Paint, PlayerPlay, ClipboardText, Database, Recycle, Share } from "tabler-icons-react";
@@ -49,8 +49,8 @@ import { CanvasRenderer } from "echarts/renderers";
49
49
  import { GridComponent, LegendComponent, TooltipComponent, VisualMapComponent } from "echarts/components";
50
50
  import numbro from "numbro";
51
51
  import "echarts-gl";
52
- import { useForm, Controller } from "react-hook-form";
53
- import { formList, useForm as useForm$1 } from "@mantine/form";
52
+ import { useForm, Controller, useFieldArray } from "react-hook-form";
53
+ import { useForm as useForm$1, formList } from "@mantine/form";
54
54
  import { Prism } from "@mantine/prism";
55
55
  var DashboardMode = /* @__PURE__ */ ((DashboardMode2) => {
56
56
  DashboardMode2["Use"] = "use";
@@ -668,12 +668,6 @@ const defaultOption$1 = {
668
668
  fontWeight: "bold"
669
669
  }
670
670
  },
671
- yAxis: {
672
- nameTextStyle: {
673
- fontWeight: "bolder",
674
- align: "left"
675
- }
676
- },
677
671
  grid: {
678
672
  top: 30,
679
673
  left: 15,
@@ -689,49 +683,57 @@ function VizCartesianChart({
689
683
  height
690
684
  }) {
691
685
  const option = React.useMemo(() => {
692
- var _c, _d;
693
- const valueFormatters = conf.series.reduce((ret, {
694
- name,
695
- y_axis_data_formatter
696
- }) => {
697
- ret[name] = function formatter({
698
- value
699
- }) {
700
- if (!y_axis_data_formatter) {
686
+ var _c;
687
+ const labelFormatters = conf.y_axes.reduce((ret, {
688
+ label_formatter
689
+ }, index2) => {
690
+ ret[index2] = function formatter(payload) {
691
+ const value = typeof payload === "object" ? payload.value : payload;
692
+ if (!label_formatter) {
701
693
  return value;
702
694
  }
703
695
  try {
704
- return numbro(value).format(JSON.parse(y_axis_data_formatter));
696
+ return numbro(value).format(label_formatter);
705
697
  } catch (error) {
706
698
  console.error(error);
707
699
  return value;
708
700
  }
709
701
  };
710
702
  return ret;
703
+ }, {
704
+ default: ({
705
+ value
706
+ }) => value
707
+ });
708
+ const yAxisIndexMap = conf.series.reduce((ret, {
709
+ yAxisIndex,
710
+ name
711
+ }) => {
712
+ ret[name] = yAxisIndex;
713
+ return ret;
711
714
  }, {});
712
715
  const series = conf.series.map((_a) => {
713
716
  var _b = _a, {
714
717
  y_axis_data_key,
715
- y_axis_data_formatter,
716
- name,
717
- label_position
718
+ yAxisIndex,
719
+ label_position,
720
+ name
718
721
  } = _b, rest = __objRest(_b, [
719
722
  "y_axis_data_key",
720
- "y_axis_data_formatter",
721
- "name",
722
- "label_position"
723
+ "yAxisIndex",
724
+ "label_position",
725
+ "name"
723
726
  ]);
724
727
  const ret = __spreadValues({
725
728
  data: data.map((d) => d[y_axis_data_key]),
726
729
  label: {
727
730
  show: !!label_position,
728
- position: label_position
731
+ position: label_position,
732
+ formatter: labelFormatters[yAxisIndex != null ? yAxisIndex : "default"]
729
733
  },
730
- name
734
+ name,
735
+ yAxisIndex
731
736
  }, rest);
732
- if (y_axis_data_formatter) {
733
- ret.label.formatter = valueFormatters[name];
734
- }
735
737
  return ret;
736
738
  });
737
739
  const customOptions = {
@@ -739,9 +741,20 @@ function VizCartesianChart({
739
741
  data: data.map((d) => d[conf.x_axis_data_key]),
740
742
  name: (_c = conf.x_axis_name) != null ? _c : ""
741
743
  },
742
- yAxis: {
743
- name: (_d = conf.y_axis_name) != null ? _d : ""
744
- },
744
+ yAxis: conf.y_axes.map((_d, index2) => {
745
+ var _e = _d, {
746
+ label_formatter
747
+ } = _e, rest = __objRest(_e, [
748
+ "label_formatter"
749
+ ]);
750
+ var _a;
751
+ return __spreadProps(__spreadValues({}, rest), {
752
+ axisLabel: {
753
+ show: true,
754
+ formatter: (_a = labelFormatters[index2]) != null ? _a : labelFormatters.default
755
+ }
756
+ });
757
+ }),
745
758
  dataset: {
746
759
  source: data
747
760
  },
@@ -756,10 +769,13 @@ function VizCartesianChart({
756
769
  seriesName,
757
770
  value
758
771
  }) => {
772
+ var _a;
759
773
  if (!seriesName) {
760
774
  return value;
761
775
  }
762
- return `${seriesName}: ${valueFormatters[seriesName]({
776
+ const yAxisIndex = yAxisIndexMap[seriesName];
777
+ const formatter = (_a = labelFormatters[yAxisIndex]) != null ? _a : labelFormatters.default;
778
+ return `${seriesName}: ${formatter({
763
779
  value
764
780
  })}`;
765
781
  });
@@ -911,7 +927,7 @@ function VizTable({
911
927
  type: value_type
912
928
  })
913
929
  })
914
- }, row[value_field]))
930
+ }, `${value_field}--${row[value_field]}`))
915
931
  }, id_field ? row[id_field] : `row-${index2}`))
916
932
  }), data.length > 100 && /* @__PURE__ */ jsx("tfoot", {
917
933
  children: /* @__PURE__ */ jsx("tr", {
@@ -927,7 +943,7 @@ function VizTable({
927
943
  })]
928
944
  }));
929
945
  }
930
- function interpolateString$1(template, params = {}) {
946
+ function interpolateString(template, params = {}) {
931
947
  const extendedParams = __spreadProps(__spreadValues({}, params), {
932
948
  numbro
933
949
  });
@@ -958,7 +974,7 @@ function VizText({
958
974
  sx: {
959
975
  fontSize: size
960
976
  },
961
- children: interpolateString$1(template, data[0])
977
+ children: interpolateString(template, data[0])
962
978
  }), `${template}---${index2}`);
963
979
  })
964
980
  });
@@ -1483,18 +1499,6 @@ class InterpolateColor {
1483
1499
  return this.mapper(value);
1484
1500
  }
1485
1501
  }
1486
- function interpolateString(template, params = {}) {
1487
- const extendedParams = __spreadProps(__spreadValues({}, params), {
1488
- numbro
1489
- });
1490
- const names = Object.keys(extendedParams);
1491
- const vals = Object.values(extendedParams);
1492
- try {
1493
- return new Function(...names, `return \`${template}\`;`)(...vals);
1494
- } catch (error) {
1495
- return error.message;
1496
- }
1497
- }
1498
1502
  function getColorByColorConf(conf, dataRow) {
1499
1503
  if (conf.type === "static") {
1500
1504
  return conf.staticColor;
@@ -1510,11 +1514,11 @@ function VizStats(_a) {
1510
1514
  var _b = _a, {
1511
1515
  conf: _c
1512
1516
  } = _b, _d = _c, {
1513
- template,
1517
+ content,
1514
1518
  size,
1515
1519
  color: color2
1516
1520
  } = _d, rest = __objRest(_d, [
1517
- "template",
1521
+ "content",
1518
1522
  "size",
1519
1523
  "color"
1520
1524
  ]), {
@@ -1523,12 +1527,24 @@ function VizStats(_a) {
1523
1527
  const finalColor = React.useMemo(() => {
1524
1528
  return getColorByColorConf(color2, data[0]);
1525
1529
  }, [color2, data]);
1530
+ const finalContent = React.useMemo(() => {
1531
+ var _a2;
1532
+ const {
1533
+ prefix,
1534
+ postfix,
1535
+ data_field,
1536
+ formatter
1537
+ } = content;
1538
+ const contentData = (_a2 = data == null ? void 0 : data[0]) == null ? void 0 : _a2[data_field];
1539
+ const contents = [prefix, numbro(contentData).format(formatter), postfix];
1540
+ return contents.join(" ");
1541
+ }, [content, data]);
1526
1542
  return /* @__PURE__ */ jsx(Text, __spreadProps(__spreadValues({}, rest), {
1527
1543
  color: finalColor,
1528
1544
  sx: {
1529
1545
  fontSize: size
1530
1546
  },
1531
- children: interpolateString(template, data[0])
1547
+ children: finalContent
1532
1548
  }));
1533
1549
  }
1534
1550
  function renderViz(width, height, data, viz) {
@@ -1819,10 +1835,6 @@ function MantineColorSelector({
1819
1835
  })]
1820
1836
  });
1821
1837
  }
1822
- const numbroFormatExample = JSON.stringify({
1823
- output: "percent",
1824
- mantissa: 2
1825
- }, null, 2);
1826
1838
  const labelPositions = [{
1827
1839
  label: "off",
1828
1840
  value: ""
@@ -1867,13 +1879,13 @@ const labelPositions = [{
1867
1879
  value: "insideBottomRight"
1868
1880
  }];
1869
1881
  function SeriesItemField({
1870
- form,
1871
- index: index2
1882
+ control,
1883
+ index: index2,
1884
+ remove,
1885
+ seriesItem,
1886
+ yAxisOptions
1872
1887
  }) {
1873
- const value = form.values.series[index2];
1874
- const {
1875
- type
1876
- } = value;
1888
+ const type = seriesItem.type;
1877
1889
  return /* @__PURE__ */ jsxs(Group, {
1878
1890
  direction: "column",
1879
1891
  grow: true,
@@ -1884,108 +1896,400 @@ function SeriesItemField({
1884
1896
  border: "1px solid #eee",
1885
1897
  position: "relative"
1886
1898
  },
1887
- children: [/* @__PURE__ */ jsxs(Group, {
1888
- direction: "row",
1899
+ children: [/* @__PURE__ */ jsx(Group, {
1900
+ direction: "column",
1889
1901
  grow: true,
1890
1902
  noWrap: true,
1891
- children: [/* @__PURE__ */ jsx(Select, __spreadValues({
1892
- label: "Type",
1893
- data: [{
1894
- label: "Line",
1895
- value: "line"
1896
- }, {
1897
- label: "Bar",
1898
- value: "bar"
1899
- }, {
1900
- label: "Scatter",
1901
- value: "scatter",
1902
- disabled: true
1903
- }]
1904
- }, form.getListInputProps("series", index2, "type"))), /* @__PURE__ */ jsx(TextInput, __spreadValues({
1903
+ children: /* @__PURE__ */ jsx(Controller, {
1904
+ name: `series.${index2}.type`,
1905
+ control,
1906
+ render: ({
1907
+ field
1908
+ }) => /* @__PURE__ */ jsx(SegmentedControl, __spreadValues({
1909
+ data: [{
1910
+ label: "Line",
1911
+ value: "line"
1912
+ }, {
1913
+ label: "Bar",
1914
+ value: "bar"
1915
+ }, {
1916
+ label: "Scatter",
1917
+ value: "scatter",
1918
+ disabled: true
1919
+ }, {
1920
+ label: "Boxplot",
1921
+ value: "boxplot",
1922
+ disabled: true
1923
+ }]
1924
+ }, field))
1925
+ })
1926
+ }), /* @__PURE__ */ jsx(Controller, {
1927
+ name: `series.${index2}.name`,
1928
+ control,
1929
+ render: ({
1930
+ field
1931
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
1905
1932
  label: "Name",
1906
1933
  required: true,
1907
1934
  sx: {
1908
1935
  flex: 1
1909
1936
  }
1910
- }, form.getListInputProps("series", index2, "name"))), /* @__PURE__ */ jsx(TextInput, __spreadValues({
1911
- label: "Value key",
1912
- required: true
1913
- }, form.getListInputProps("series", index2, "y_axis_data_key")))]
1937
+ }, field))
1914
1938
  }), /* @__PURE__ */ jsxs(Group, {
1915
1939
  direction: "row",
1916
1940
  grow: true,
1917
1941
  noWrap: true,
1942
+ children: [/* @__PURE__ */ jsx(Controller, {
1943
+ name: `series.${index2}.y_axis_data_key`,
1944
+ control,
1945
+ render: ({
1946
+ field
1947
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
1948
+ label: "Value key",
1949
+ required: true,
1950
+ sx: {
1951
+ flex: 1
1952
+ }
1953
+ }, field))
1954
+ }), /* @__PURE__ */ jsx(Controller, {
1955
+ name: `series.${index2}.yAxisIndex`,
1956
+ control,
1957
+ render: (_a) => {
1958
+ var {
1959
+ field: _b
1960
+ } = _a, _c = _b, {
1961
+ value,
1962
+ onChange
1963
+ } = _c, rest = __objRest(_c, [
1964
+ "value",
1965
+ "onChange"
1966
+ ]);
1967
+ var _a2;
1968
+ return /* @__PURE__ */ jsx(Select, __spreadProps(__spreadValues({
1969
+ label: "Y Axis",
1970
+ data: yAxisOptions,
1971
+ disabled: yAxisOptions.length === 0
1972
+ }, rest), {
1973
+ value: (_a2 = value == null ? void 0 : value.toString()) != null ? _a2 : "",
1974
+ onChange: (value2) => {
1975
+ if (!value2) {
1976
+ onChange(0);
1977
+ return;
1978
+ }
1979
+ onChange(Number(value2));
1980
+ },
1981
+ sx: {
1982
+ flex: 1
1983
+ }
1984
+ }));
1985
+ }
1986
+ })]
1987
+ }), type === "bar" && /* @__PURE__ */ jsxs(Group, {
1988
+ direction: "row",
1989
+ grow: true,
1918
1990
  align: "top",
1919
- children: [type === "bar" && /* @__PURE__ */ jsx(Fragment, {
1920
- children: /* @__PURE__ */ jsx(TextInput, __spreadValues({
1991
+ children: [/* @__PURE__ */ jsx(Controller, {
1992
+ name: `series.${index2}.stack`,
1993
+ control,
1994
+ render: ({
1995
+ field
1996
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
1921
1997
  label: "Stack",
1922
- placeholder: "Stack bars by this ID"
1923
- }, form.getListInputProps("series", index2, "stack")))
1924
- }), /* @__PURE__ */ jsx(Select, __spreadValues({
1998
+ placeholder: "Stack bars by this ID",
1999
+ sx: {
2000
+ flexGrow: 1
2001
+ }
2002
+ }, field))
2003
+ }), /* @__PURE__ */ jsx(Controller, {
2004
+ name: `series.${index2}.barWidth`,
2005
+ control,
2006
+ render: ({
2007
+ field
2008
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2009
+ label: "Bar Width",
2010
+ sx: {
2011
+ flexGrow: 1
2012
+ }
2013
+ }, field))
2014
+ })]
2015
+ }), /* @__PURE__ */ jsx(Controller, {
2016
+ name: `series.${index2}.label_position`,
2017
+ control,
2018
+ render: ({
2019
+ field
2020
+ }) => /* @__PURE__ */ jsx(Select, __spreadValues({
1925
2021
  label: "Label Position",
1926
2022
  data: labelPositions
1927
- }, form.getListInputProps("series", index2, "label_position"))), /* @__PURE__ */ jsx(JsonInput, __spreadValues({
1928
- sx: {
1929
- label: {
1930
- width: "100%"
1931
- }
1932
- },
1933
- label: /* @__PURE__ */ jsxs(Group, {
1934
- position: "apart",
1935
- children: [/* @__PURE__ */ jsx(Text, {
1936
- children: "Value Formatter"
1937
- }), /* @__PURE__ */ jsx(Anchor, {
1938
- href: "https://numbrojs.com/format.html",
1939
- target: "_blank",
1940
- children: "Formats"
1941
- })]
1942
- }),
1943
- placeholder: numbroFormatExample,
1944
- minRows: 4,
1945
- maxRows: 12,
1946
- autosize: true
1947
- }, form.getListInputProps("series", index2, "y_axis_data_formatter")))]
2023
+ }, field))
1948
2024
  }), /* @__PURE__ */ jsxs(Group, {
1949
2025
  direction: "column",
1950
2026
  grow: true,
2027
+ spacing: 4,
1951
2028
  children: [/* @__PURE__ */ jsx(Text, {
2029
+ size: "sm",
1952
2030
  children: "Color"
1953
- }), /* @__PURE__ */ jsx(MantineColorSelector, __spreadValues({}, form.getListInputProps("series", index2, "color")))]
2031
+ }), /* @__PURE__ */ jsx(Controller, {
2032
+ name: `series.${index2}.color`,
2033
+ control,
2034
+ render: ({
2035
+ field
2036
+ }) => /* @__PURE__ */ jsx(MantineColorSelector, __spreadValues({}, field))
2037
+ })]
2038
+ }), /* @__PURE__ */ jsx(ActionIcon, {
2039
+ color: "red",
2040
+ variant: "hover",
2041
+ onClick: () => remove(index2),
2042
+ sx: {
2043
+ position: "absolute",
2044
+ top: 15,
2045
+ right: 5
2046
+ },
2047
+ children: /* @__PURE__ */ jsx(Trash, {
2048
+ size: 16
2049
+ })
2050
+ })]
2051
+ }, index2);
2052
+ }
2053
+ function SeriesField({
2054
+ control,
2055
+ watch,
2056
+ getValues
2057
+ }) {
2058
+ const {
2059
+ fields,
2060
+ append,
2061
+ remove
2062
+ } = useFieldArray({
2063
+ control,
2064
+ name: "series"
2065
+ });
2066
+ const watchFieldArray = watch("y_axes");
2067
+ const controlledFields = fields.map((field, index2) => {
2068
+ return __spreadValues(__spreadValues({}, field), watchFieldArray[index2]);
2069
+ });
2070
+ const addSeries = () => append({
2071
+ type: "bar",
2072
+ name: randomId(),
2073
+ showSymbol: false,
2074
+ y_axis_data_key: "value",
2075
+ yAxisIndex: 0,
2076
+ label_position: "top",
2077
+ stack: "",
2078
+ color: "#000"
2079
+ });
2080
+ const yAxisOptions = React.useMemo(() => {
2081
+ return getValues().y_axes.map(({
2082
+ name
2083
+ }, index2) => ({
2084
+ label: name,
2085
+ value: index2.toString()
2086
+ }));
2087
+ }, [getValues]);
2088
+ return /* @__PURE__ */ jsxs(Group, {
2089
+ direction: "column",
2090
+ grow: true,
2091
+ children: [/* @__PURE__ */ jsx(Text, {
2092
+ mt: "xl",
2093
+ mb: 0,
2094
+ children: "Series"
2095
+ }), controlledFields.map((seriesItem, index2) => /* @__PURE__ */ jsx(SeriesItemField, {
2096
+ control,
2097
+ index: index2,
2098
+ remove,
2099
+ seriesItem,
2100
+ yAxisOptions
2101
+ })), /* @__PURE__ */ jsx(Group, {
2102
+ position: "center",
2103
+ mt: "xs",
2104
+ children: /* @__PURE__ */ jsx(Button, {
2105
+ onClick: addSeries,
2106
+ children: "Add a Series"
2107
+ })
2108
+ })]
2109
+ });
2110
+ }
2111
+ const defaultNumbroFormat = {
2112
+ mantissa: 0,
2113
+ output: "number"
2114
+ };
2115
+ function NumbroFormatSelector({
2116
+ value,
2117
+ onChange
2118
+ }) {
2119
+ const changeOutput = (output) => {
2120
+ onChange(__spreadProps(__spreadValues({}, value), {
2121
+ output
2122
+ }));
2123
+ };
2124
+ const changeMantissa = (mantissa) => {
2125
+ const trimMantissa = mantissa === 0 ? false : value.trimMantissa;
2126
+ onChange(__spreadProps(__spreadValues({}, value), {
2127
+ mantissa,
2128
+ trimMantissa
2129
+ }));
2130
+ };
2131
+ const changeTrimMantissa = (event) => {
2132
+ onChange(__spreadProps(__spreadValues({}, value), {
2133
+ trimMantissa: event.currentTarget.checked
2134
+ }));
2135
+ };
2136
+ return /* @__PURE__ */ jsx(Group, {
2137
+ direction: "column",
2138
+ grow: true,
2139
+ noWrap: true,
2140
+ children: /* @__PURE__ */ jsxs(Group, {
2141
+ direction: "row",
2142
+ grow: true,
2143
+ children: [/* @__PURE__ */ jsx(Select, {
2144
+ label: "Format",
2145
+ data: [{
2146
+ label: "1234",
2147
+ value: "number"
2148
+ }, {
2149
+ label: "99%",
2150
+ value: "percent"
2151
+ }],
2152
+ value: value.output,
2153
+ onChange: changeOutput
2154
+ }), /* @__PURE__ */ jsx(NumberInput, {
2155
+ label: "Mantissa",
2156
+ defaultValue: 0,
2157
+ min: 0,
2158
+ step: 1,
2159
+ max: 4,
2160
+ value: value.mantissa,
2161
+ onChange: changeMantissa
2162
+ }), /* @__PURE__ */ jsx(Switch, {
2163
+ label: "Trim mantissa",
2164
+ checked: value.trimMantissa,
2165
+ onChange: changeTrimMantissa,
2166
+ disabled: value.mantissa === 0
2167
+ })]
2168
+ })
2169
+ });
2170
+ }
2171
+ function YAxisField({
2172
+ control,
2173
+ index: index2,
2174
+ remove
2175
+ }) {
2176
+ return /* @__PURE__ */ jsxs(Group, {
2177
+ direction: "column",
2178
+ grow: true,
2179
+ my: 0,
2180
+ p: "md",
2181
+ pr: 40,
2182
+ sx: {
2183
+ border: "1px solid #eee",
2184
+ position: "relative"
2185
+ },
2186
+ children: [/* @__PURE__ */ jsx(Group, {
2187
+ direction: "row",
2188
+ grow: true,
2189
+ noWrap: true,
2190
+ children: /* @__PURE__ */ jsx(Controller, {
2191
+ name: `y_axes.${index2}.name`,
2192
+ control,
2193
+ render: ({
2194
+ field
2195
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2196
+ label: "Name",
2197
+ required: true,
2198
+ sx: {
2199
+ flex: 1
2200
+ }
2201
+ }, field))
2202
+ })
2203
+ }), /* @__PURE__ */ jsx(Group, {
2204
+ direction: "column",
2205
+ grow: true,
2206
+ noWrap: true,
2207
+ children: /* @__PURE__ */ jsx(Controller, {
2208
+ name: `y_axes.${index2}.label_formatter`,
2209
+ control,
2210
+ render: ({
2211
+ field
2212
+ }) => /* @__PURE__ */ jsx(NumbroFormatSelector, __spreadValues({}, field))
2213
+ })
1954
2214
  }), /* @__PURE__ */ jsx(ActionIcon, {
1955
2215
  color: "red",
1956
2216
  variant: "hover",
1957
- onClick: () => form.removeListItem("series", index2),
2217
+ onClick: () => remove(index2),
1958
2218
  sx: {
1959
2219
  position: "absolute",
1960
2220
  top: 15,
1961
2221
  right: 5
1962
2222
  },
2223
+ disabled: index2 === 0,
1963
2224
  children: /* @__PURE__ */ jsx(Trash, {
1964
2225
  size: 16
1965
2226
  })
1966
2227
  })]
1967
2228
  }, index2);
1968
2229
  }
2230
+ function YAxesField({
2231
+ control,
2232
+ watch
2233
+ }) {
2234
+ const {
2235
+ fields,
2236
+ append,
2237
+ remove
2238
+ } = useFieldArray({
2239
+ control,
2240
+ name: "y_axes"
2241
+ });
2242
+ const watchFieldArray = watch("y_axes");
2243
+ const controlledFields = fields.map((field, index2) => {
2244
+ return __spreadValues(__spreadValues({}, field), watchFieldArray[index2]);
2245
+ });
2246
+ const addYAxis = () => append({
2247
+ name: "",
2248
+ label_formatter: defaultNumbroFormat
2249
+ });
2250
+ return /* @__PURE__ */ jsxs(Group, {
2251
+ direction: "column",
2252
+ grow: true,
2253
+ children: [/* @__PURE__ */ jsx(Text, {
2254
+ mt: "xl",
2255
+ mb: 0,
2256
+ children: "Y Axes"
2257
+ }), controlledFields.map((field, index2) => /* @__PURE__ */ jsx(YAxisField, {
2258
+ control,
2259
+ index: index2,
2260
+ remove
2261
+ })), /* @__PURE__ */ jsx(Group, {
2262
+ position: "center",
2263
+ mt: "xs",
2264
+ children: /* @__PURE__ */ jsx(Button, {
2265
+ onClick: addYAxis,
2266
+ children: "Add a Y Axis"
2267
+ })
2268
+ })]
2269
+ });
2270
+ }
1969
2271
  function withDefaults(series) {
1970
2272
  function setDefaults({
1971
2273
  type,
1972
2274
  name,
1973
2275
  showSymbol,
1974
2276
  y_axis_data_key = "value",
1975
- y_axis_data_formatter = "",
2277
+ yAxisIndex = 0,
1976
2278
  label_position = "top",
1977
2279
  stack = "1",
1978
- color: color2 = "black"
2280
+ color: color2 = "black",
2281
+ barWidth = "30"
1979
2282
  }) {
1980
2283
  return {
1981
2284
  type,
1982
2285
  name,
1983
2286
  showSymbol,
1984
2287
  y_axis_data_key,
1985
- y_axis_data_formatter,
2288
+ yAxisIndex,
1986
2289
  label_position,
1987
2290
  stack,
1988
- color: color2
2291
+ color: color2,
2292
+ barWidth
1989
2293
  };
1990
2294
  }
1991
2295
  return series.map(setDefaults);
@@ -1995,45 +2299,51 @@ function VizCartesianChartPanel({
1995
2299
  setConf
1996
2300
  }) {
1997
2301
  const _a = conf, {
1998
- series
2302
+ series,
2303
+ y_axes
1999
2304
  } = _a, restConf = __objRest(_a, [
2000
- "series"
2305
+ "series",
2306
+ "y_axes"
2001
2307
  ]);
2002
- const initialValues = React.useMemo(() => {
2308
+ const defaultValues = React.useMemo(() => {
2003
2309
  const _a2 = restConf, {
2004
- x_axis_name = "",
2005
- y_axis_name = ""
2310
+ x_axis_name = ""
2006
2311
  } = _a2, rest = __objRest(_a2, [
2007
- "x_axis_name",
2008
- "y_axis_name"
2312
+ "x_axis_name"
2009
2313
  ]);
2010
2314
  return __spreadValues({
2011
- series: formList(withDefaults(series != null ? series : [])),
2315
+ series: withDefaults(series != null ? series : []),
2012
2316
  x_axis_name,
2013
- y_axis_name
2317
+ y_axes: y_axes != null ? y_axes : [{
2318
+ name: "Y Axis",
2319
+ label_formatter: defaultNumbroFormat
2320
+ }]
2014
2321
  }, rest);
2015
2322
  }, [series, restConf]);
2016
- const form = useForm$1({
2017
- initialValues
2018
- });
2019
- const addSeries = () => form.addListItem("series", {
2020
- type: "bar",
2021
- name: randomId(),
2022
- showSymbol: false,
2023
- y_axis_data_key: "value",
2024
- y_axis_data_formatter: "",
2025
- label_position: "top",
2026
- stack: "",
2027
- color: "#000"
2323
+ React.useEffect(() => {
2324
+ const configMalformed = !_.isEqual(conf, defaultValues);
2325
+ if (configMalformed) {
2326
+ setConf(defaultValues);
2327
+ }
2328
+ }, [conf, defaultValues]);
2329
+ const {
2330
+ control,
2331
+ handleSubmit,
2332
+ watch,
2333
+ formState: {
2334
+ isDirty
2335
+ },
2336
+ getValues
2337
+ } = useForm({
2338
+ defaultValues
2028
2339
  });
2029
- const changed = React.useMemo(() => !_.isEqual(form.values, initialValues), [form.values, initialValues]);
2030
2340
  return /* @__PURE__ */ jsx(Group, {
2031
2341
  direction: "column",
2032
2342
  mt: "md",
2033
2343
  spacing: "xs",
2034
2344
  grow: true,
2035
2345
  children: /* @__PURE__ */ jsxs("form", {
2036
- onSubmit: form.onSubmit(setConf),
2346
+ onSubmit: handleSubmit(setConf),
2037
2347
  children: [/* @__PURE__ */ jsxs(Group, {
2038
2348
  position: "apart",
2039
2349
  mb: "lg",
@@ -2047,45 +2357,43 @@ function VizCartesianChartPanel({
2047
2357
  mr: 5,
2048
2358
  variant: "filled",
2049
2359
  color: "blue",
2050
- disabled: !changed,
2360
+ disabled: !isDirty,
2051
2361
  children: /* @__PURE__ */ jsx(DeviceFloppy, {
2052
2362
  size: 20
2053
2363
  })
2054
2364
  })]
2055
- }), /* @__PURE__ */ jsx(TextInput, __spreadValues({
2056
- size: "md",
2057
- mb: "lg",
2058
- label: "X Axis Data Key"
2059
- }, form.getInputProps("x_axis_data_key"))), /* @__PURE__ */ jsxs(Group, {
2365
+ }), /* @__PURE__ */ jsx(Controller, {
2366
+ name: "x_axis_data_key",
2367
+ control,
2368
+ render: ({
2369
+ field
2370
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2371
+ size: "md",
2372
+ mb: "lg",
2373
+ label: "X Axis Data Key"
2374
+ }, field))
2375
+ }), /* @__PURE__ */ jsx(Group, {
2060
2376
  direction: "column",
2061
2377
  grow: true,
2062
2378
  noWrap: true,
2063
2379
  mb: "lg",
2064
- children: [/* @__PURE__ */ jsx(TextInput, __spreadValues({
2065
- size: "md",
2066
- label: "X Axis Name"
2067
- }, form.getInputProps("x_axis_name"))), /* @__PURE__ */ jsx(TextInput, __spreadValues({
2068
- size: "md",
2069
- label: "Y Axis Name"
2070
- }, form.getInputProps("y_axis_name")))]
2071
- }), /* @__PURE__ */ jsxs(Group, {
2072
- direction: "column",
2073
- grow: true,
2074
- children: [/* @__PURE__ */ jsx(Text, {
2075
- mt: "xl",
2076
- mb: 0,
2077
- children: "Series"
2078
- }), form.values.series.map((_item, index2) => /* @__PURE__ */ jsx(SeriesItemField, {
2079
- form,
2080
- index: index2
2081
- })), /* @__PURE__ */ jsx(Group, {
2082
- position: "center",
2083
- mt: "xs",
2084
- children: /* @__PURE__ */ jsx(Button, {
2085
- onClick: addSeries,
2086
- children: "Add a Series"
2087
- })
2088
- })]
2380
+ children: /* @__PURE__ */ jsx(Controller, {
2381
+ name: "x_axis_name",
2382
+ control,
2383
+ render: ({
2384
+ field
2385
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2386
+ size: "md",
2387
+ label: "X Axis Name"
2388
+ }, field))
2389
+ })
2390
+ }), /* @__PURE__ */ jsx(YAxesField, {
2391
+ control,
2392
+ watch
2393
+ }), /* @__PURE__ */ jsx(SeriesField, {
2394
+ control,
2395
+ watch,
2396
+ getValues
2089
2397
  })]
2090
2398
  })
2091
2399
  });
@@ -2347,11 +2655,19 @@ function VizStatsPanel({
2347
2655
  const defaultValues = _.merge({}, {
2348
2656
  align: "center",
2349
2657
  size: "100px",
2350
- template: "",
2351
2658
  weight: "bold",
2352
2659
  color: {
2353
2660
  type: "static",
2354
2661
  staticColor: "red"
2662
+ },
2663
+ content: {
2664
+ prefix: "",
2665
+ data_field: "",
2666
+ formatter: {
2667
+ output: "number",
2668
+ mantissa: 0
2669
+ },
2670
+ postfix: ""
2355
2671
  }
2356
2672
  }, conf);
2357
2673
  const {
@@ -2404,23 +2720,54 @@ function VizStatsPanel({
2404
2720
  },
2405
2721
  children: [/* @__PURE__ */ jsx(Accordion.Item, {
2406
2722
  label: "Content",
2407
- children: /* @__PURE__ */ jsx(Group, {
2723
+ children: /* @__PURE__ */ jsxs(Group, {
2408
2724
  direction: "column",
2409
2725
  grow: true,
2410
- children: /* @__PURE__ */ jsx(Controller, {
2411
- name: "template",
2726
+ children: [/* @__PURE__ */ jsxs(Group, {
2727
+ direction: "row",
2728
+ grow: true,
2729
+ children: [/* @__PURE__ */ jsx(Controller, {
2730
+ name: "content.prefix",
2731
+ control,
2732
+ render: ({
2733
+ field
2734
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2735
+ label: "Prefix",
2736
+ sx: {
2737
+ flexGrow: 1
2738
+ }
2739
+ }, field))
2740
+ }), /* @__PURE__ */ jsx(Controller, {
2741
+ name: "content.data_field",
2742
+ control,
2743
+ render: ({
2744
+ field
2745
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2746
+ label: "Data Field",
2747
+ required: true,
2748
+ sx: {
2749
+ flexGrow: 1
2750
+ }
2751
+ }, field))
2752
+ }), /* @__PURE__ */ jsx(Controller, {
2753
+ name: "content.postfix",
2754
+ control,
2755
+ render: ({
2756
+ field
2757
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2758
+ label: "Postfix",
2759
+ sx: {
2760
+ flexGrow: 1
2761
+ }
2762
+ }, field))
2763
+ })]
2764
+ }), /* @__PURE__ */ jsx(Controller, {
2765
+ name: "content.formatter",
2412
2766
  control,
2413
2767
  render: ({
2414
2768
  field
2415
- }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2416
- placeholder: "Time: ${new Date().toISOString()}",
2417
- label: "Content Template",
2418
- required: true,
2419
- sx: {
2420
- flex: 1
2421
- }
2422
- }, field))
2423
- })
2769
+ }) => /* @__PURE__ */ jsx(NumbroFormatSelector, __spreadValues({}, field))
2770
+ })]
2424
2771
  })
2425
2772
  }), /* @__PURE__ */ jsxs(Accordion.Item, {
2426
2773
  label: "Font",
@@ -4006,7 +4353,7 @@ function DashboardActions({
4006
4353
  })
4007
4354
  }), /* @__PURE__ */ jsxs(Group, {
4008
4355
  position: "right",
4009
- children: [inLayoutMode && /* @__PURE__ */ jsx(Button, {
4356
+ children: [!inUseMode && /* @__PURE__ */ jsx(Button, {
4010
4357
  variant: "default",
4011
4358
  size: "sm",
4012
4359
  onClick: addPanel,
@@ -4090,9 +4437,8 @@ function Dashboard({
4090
4437
  return !_.isEqual(dataSources, dashboard.definition.dataSources);
4091
4438
  }, [dashboard, panels, sqlSnippets, dataSources]);
4092
4439
  const saveDashboardChanges = async () => {
4093
- const d = _.merge({}, dashboard, {
4094
- panels
4095
- }, {
4440
+ const d = __spreadProps(__spreadValues({}, dashboard), {
4441
+ panels,
4096
4442
  definition: {
4097
4443
  sqlSnippets,
4098
4444
  dataSources
@@ -4108,13 +4454,13 @@ function Dashboard({
4108
4454
  x: 0,
4109
4455
  y: Infinity,
4110
4456
  w: 3,
4111
- h: 4
4457
+ h: 15
4112
4458
  },
4113
4459
  title: `New Panel - ${id}`,
4114
- description: "description goes here",
4460
+ description: "",
4115
4461
  dataSourceID: "",
4116
4462
  viz: {
4117
- type: "table",
4463
+ type: "text",
4118
4464
  conf: {}
4119
4465
  }
4120
4466
  };