@devtable/dashboard 1.8.0 → 1.11.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.
@@ -29,13 +29,17 @@ var __objRest = (source, exclude) => {
29
29
  }
30
30
  return target;
31
31
  };
32
+ var __publicField = (obj, key, value) => {
33
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
34
+ return value;
35
+ };
32
36
  import React from "react";
33
37
  import _ from "lodash";
34
38
  import { WidthProvider, Responsive } from "react-grid-layout";
35
- import { Popover, Tooltip, Group, Text, ActionIcon, TextInput, Box, LoadingOverlay, Table, Select, Button, useMantineTheme, ColorSwatch, JsonInput, Anchor, Switch, Slider, 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, JsonInput, Anchor, Slider, ColorInput, Accordion, Switch, Modal, AppShell, Tabs, Menu, Divider, Container, SegmentedControl, Textarea } from "@mantine/core";
36
40
  import { useRequest } from "ahooks";
37
41
  import axios from "axios";
38
- import { InfoCircle, DeviceFloppy, Refresh, Trash, Settings, Resize, Paint, PlayerPlay, PlaylistAdd, ClipboardText, Database, Recycle, Share } from "tabler-icons-react";
42
+ import { InfoCircle, DeviceFloppy, Refresh, Trash, PlaylistAdd, Settings, Resize, Paint, PlayerPlay, ClipboardText, Database, Recycle, Share } from "tabler-icons-react";
39
43
  import RichTextEditor, { RichTextEditor as RichTextEditor$1 } from "@mantine/rte";
40
44
  import { useInputState, useElementSize, randomId } from "@mantine/hooks";
41
45
  import ReactEChartsCore from "echarts-for-react/lib/core";
@@ -678,7 +682,7 @@ const defaultOption$1 = {
678
682
  containLabel: true
679
683
  }
680
684
  };
681
- function VizLineBarChart({
685
+ function VizCartesianChart({
682
686
  conf,
683
687
  data,
684
688
  width,
@@ -710,7 +714,7 @@ function VizLineBarChart({
710
714
  y_axis_data_key,
711
715
  y_axis_data_formatter,
712
716
  name,
713
- label_position = "top"
717
+ label_position
714
718
  } = _b, rest = __objRest(_b, [
715
719
  "y_axis_data_key",
716
720
  "y_axis_data_formatter",
@@ -720,7 +724,7 @@ function VizLineBarChart({
720
724
  const ret = __spreadValues({
721
725
  data: data.map((d) => d[y_axis_data_key]),
722
726
  label: {
723
- show: true,
727
+ show: !!label_position,
724
728
  position: label_position
725
729
  },
726
730
  name
@@ -923,7 +927,7 @@ function VizTable({
923
927
  })]
924
928
  }));
925
929
  }
926
- function interpolateString(template, params = {}) {
930
+ function interpolateString$1(template, params = {}) {
927
931
  const extendedParams = __spreadProps(__spreadValues({}, params), {
928
932
  numbro
929
933
  });
@@ -954,7 +958,7 @@ function VizText({
954
958
  sx: {
955
959
  fontSize: size
956
960
  },
957
- children: interpolateString(template, data[0])
961
+ children: interpolateString$1(template, data[0])
958
962
  }), `${template}---${index2}`);
959
963
  })
960
964
  });
@@ -1113,6 +1117,420 @@ function VizPie({
1113
1117
  }
1114
1118
  });
1115
1119
  }
1120
+ var invariant = function() {
1121
+ };
1122
+ const clamp$1 = (min, max, v) => Math.min(Math.max(v, min), max);
1123
+ const progress = (from, to, value) => {
1124
+ const toFromDifference = to - from;
1125
+ return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
1126
+ };
1127
+ const mix = (from, to, progress2) => -progress2 * from + progress2 * to + from;
1128
+ const clamp = (min, max) => (v) => Math.max(Math.min(v, max), min);
1129
+ const sanitize = (v) => v % 1 ? Number(v.toFixed(5)) : v;
1130
+ const floatRegex = /(-)?([\d]*\.?[\d])+/g;
1131
+ const colorRegex = /(#[0-9a-f]{6}|#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2,3}\s*\/*\s*[\d\.]+%?\))/gi;
1132
+ const singleColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2,3}\s*\/*\s*[\d\.]+%?\))$/i;
1133
+ function isString(v) {
1134
+ return typeof v === "string";
1135
+ }
1136
+ const number = {
1137
+ test: (v) => typeof v === "number",
1138
+ parse: parseFloat,
1139
+ transform: (v) => v
1140
+ };
1141
+ const alpha = Object.assign(Object.assign({}, number), { transform: clamp(0, 1) });
1142
+ Object.assign(Object.assign({}, number), { default: 1 });
1143
+ const createUnitType = (unit) => ({
1144
+ test: (v) => isString(v) && v.endsWith(unit) && v.split(" ").length === 1,
1145
+ parse: parseFloat,
1146
+ transform: (v) => `${v}${unit}`
1147
+ });
1148
+ const percent = createUnitType("%");
1149
+ Object.assign(Object.assign({}, percent), { parse: (v) => percent.parse(v) / 100, transform: (v) => percent.transform(v * 100) });
1150
+ const isColorString = (type, testProp) => (v) => {
1151
+ return Boolean(isString(v) && singleColorRegex.test(v) && v.startsWith(type) || testProp && Object.prototype.hasOwnProperty.call(v, testProp));
1152
+ };
1153
+ const splitColor = (aName, bName, cName) => (v) => {
1154
+ if (!isString(v))
1155
+ return v;
1156
+ const [a, b, c, alpha2] = v.match(floatRegex);
1157
+ return {
1158
+ [aName]: parseFloat(a),
1159
+ [bName]: parseFloat(b),
1160
+ [cName]: parseFloat(c),
1161
+ alpha: alpha2 !== void 0 ? parseFloat(alpha2) : 1
1162
+ };
1163
+ };
1164
+ const hsla = {
1165
+ test: isColorString("hsl", "hue"),
1166
+ parse: splitColor("hue", "saturation", "lightness"),
1167
+ transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
1168
+ return "hsla(" + Math.round(hue) + ", " + percent.transform(sanitize(saturation)) + ", " + percent.transform(sanitize(lightness)) + ", " + sanitize(alpha.transform(alpha$1)) + ")";
1169
+ }
1170
+ };
1171
+ const clampRgbUnit = clamp(0, 255);
1172
+ const rgbUnit = Object.assign(Object.assign({}, number), { transform: (v) => Math.round(clampRgbUnit(v)) });
1173
+ const rgba = {
1174
+ test: isColorString("rgb", "red"),
1175
+ parse: splitColor("red", "green", "blue"),
1176
+ transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" + rgbUnit.transform(red) + ", " + rgbUnit.transform(green) + ", " + rgbUnit.transform(blue) + ", " + sanitize(alpha.transform(alpha$1)) + ")"
1177
+ };
1178
+ function parseHex(v) {
1179
+ let r = "";
1180
+ let g = "";
1181
+ let b = "";
1182
+ let a = "";
1183
+ if (v.length > 5) {
1184
+ r = v.substr(1, 2);
1185
+ g = v.substr(3, 2);
1186
+ b = v.substr(5, 2);
1187
+ a = v.substr(7, 2);
1188
+ } else {
1189
+ r = v.substr(1, 1);
1190
+ g = v.substr(2, 1);
1191
+ b = v.substr(3, 1);
1192
+ a = v.substr(4, 1);
1193
+ r += r;
1194
+ g += g;
1195
+ b += b;
1196
+ a += a;
1197
+ }
1198
+ return {
1199
+ red: parseInt(r, 16),
1200
+ green: parseInt(g, 16),
1201
+ blue: parseInt(b, 16),
1202
+ alpha: a ? parseInt(a, 16) / 255 : 1
1203
+ };
1204
+ }
1205
+ const hex = {
1206
+ test: isColorString("#"),
1207
+ parse: parseHex,
1208
+ transform: rgba.transform
1209
+ };
1210
+ const color = {
1211
+ test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
1212
+ parse: (v) => {
1213
+ if (rgba.test(v)) {
1214
+ return rgba.parse(v);
1215
+ } else if (hsla.test(v)) {
1216
+ return hsla.parse(v);
1217
+ } else {
1218
+ return hex.parse(v);
1219
+ }
1220
+ },
1221
+ transform: (v) => {
1222
+ return isString(v) ? v : v.hasOwnProperty("red") ? rgba.transform(v) : hsla.transform(v);
1223
+ }
1224
+ };
1225
+ const colorToken = "${c}";
1226
+ const numberToken = "${n}";
1227
+ function test(v) {
1228
+ var _a, _b, _c, _d;
1229
+ return isNaN(v) && isString(v) && ((_b = (_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = v.match(colorRegex)) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) > 0;
1230
+ }
1231
+ function analyse$1(v) {
1232
+ if (typeof v === "number")
1233
+ v = `${v}`;
1234
+ const values = [];
1235
+ let numColors = 0;
1236
+ const colors = v.match(colorRegex);
1237
+ if (colors) {
1238
+ numColors = colors.length;
1239
+ v = v.replace(colorRegex, colorToken);
1240
+ values.push(...colors.map(color.parse));
1241
+ }
1242
+ const numbers = v.match(floatRegex);
1243
+ if (numbers) {
1244
+ v = v.replace(floatRegex, numberToken);
1245
+ values.push(...numbers.map(number.parse));
1246
+ }
1247
+ return { values, numColors, tokenised: v };
1248
+ }
1249
+ function parse(v) {
1250
+ return analyse$1(v).values;
1251
+ }
1252
+ function createTransformer(v) {
1253
+ const { values, numColors, tokenised } = analyse$1(v);
1254
+ const numValues = values.length;
1255
+ return (v2) => {
1256
+ let output = tokenised;
1257
+ for (let i = 0; i < numValues; i++) {
1258
+ output = output.replace(i < numColors ? colorToken : numberToken, i < numColors ? color.transform(v2[i]) : sanitize(v2[i]));
1259
+ }
1260
+ return output;
1261
+ };
1262
+ }
1263
+ const convertNumbersToZero = (v) => typeof v === "number" ? 0 : v;
1264
+ function getAnimatableNone(v) {
1265
+ const parsed = parse(v);
1266
+ const transformer = createTransformer(v);
1267
+ return transformer(parsed.map(convertNumbersToZero));
1268
+ }
1269
+ const complex = { test, parse, createTransformer, getAnimatableNone };
1270
+ function hueToRgb(p2, q2, t) {
1271
+ if (t < 0)
1272
+ t += 1;
1273
+ if (t > 1)
1274
+ t -= 1;
1275
+ if (t < 1 / 6)
1276
+ return p2 + (q2 - p2) * 6 * t;
1277
+ if (t < 1 / 2)
1278
+ return q2;
1279
+ if (t < 2 / 3)
1280
+ return p2 + (q2 - p2) * (2 / 3 - t) * 6;
1281
+ return p2;
1282
+ }
1283
+ function hslaToRgba({ hue, saturation, lightness, alpha: alpha2 }) {
1284
+ hue /= 360;
1285
+ saturation /= 100;
1286
+ lightness /= 100;
1287
+ let red = 0;
1288
+ let green = 0;
1289
+ let blue = 0;
1290
+ if (!saturation) {
1291
+ red = green = blue = lightness;
1292
+ } else {
1293
+ const q2 = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
1294
+ const p2 = 2 * lightness - q2;
1295
+ red = hueToRgb(p2, q2, hue + 1 / 3);
1296
+ green = hueToRgb(p2, q2, hue);
1297
+ blue = hueToRgb(p2, q2, hue - 1 / 3);
1298
+ }
1299
+ return {
1300
+ red: Math.round(red * 255),
1301
+ green: Math.round(green * 255),
1302
+ blue: Math.round(blue * 255),
1303
+ alpha: alpha2
1304
+ };
1305
+ }
1306
+ const mixLinearColor = (from, to, v) => {
1307
+ const fromExpo = from * from;
1308
+ const toExpo = to * to;
1309
+ return Math.sqrt(Math.max(0, v * (toExpo - fromExpo) + fromExpo));
1310
+ };
1311
+ const colorTypes = [hex, rgba, hsla];
1312
+ const getColorType = (v) => colorTypes.find((type) => type.test(v));
1313
+ const mixColor = (from, to) => {
1314
+ let fromColorType = getColorType(from);
1315
+ let toColorType = getColorType(to);
1316
+ let fromColor = fromColorType.parse(from);
1317
+ let toColor = toColorType.parse(to);
1318
+ if (fromColorType === hsla) {
1319
+ fromColor = hslaToRgba(fromColor);
1320
+ fromColorType = rgba;
1321
+ }
1322
+ if (toColorType === hsla) {
1323
+ toColor = hslaToRgba(toColor);
1324
+ toColorType = rgba;
1325
+ }
1326
+ const blended = Object.assign({}, fromColor);
1327
+ return (v) => {
1328
+ for (const key in blended) {
1329
+ if (key !== "alpha") {
1330
+ blended[key] = mixLinearColor(fromColor[key], toColor[key], v);
1331
+ }
1332
+ }
1333
+ blended.alpha = mix(fromColor.alpha, toColor.alpha, v);
1334
+ return fromColorType.transform(blended);
1335
+ };
1336
+ };
1337
+ const isNum = (v) => typeof v === "number";
1338
+ const combineFunctions = (a, b) => (v) => b(a(v));
1339
+ const pipe = (...transformers) => transformers.reduce(combineFunctions);
1340
+ function getMixer(origin, target) {
1341
+ if (isNum(origin)) {
1342
+ return (v) => mix(origin, target, v);
1343
+ } else if (color.test(origin)) {
1344
+ return mixColor(origin, target);
1345
+ } else {
1346
+ return mixComplex(origin, target);
1347
+ }
1348
+ }
1349
+ const mixArray = (from, to) => {
1350
+ const output = [...from];
1351
+ const numValues = output.length;
1352
+ const blendValue = from.map((fromThis, i) => getMixer(fromThis, to[i]));
1353
+ return (v) => {
1354
+ for (let i = 0; i < numValues; i++) {
1355
+ output[i] = blendValue[i](v);
1356
+ }
1357
+ return output;
1358
+ };
1359
+ };
1360
+ const mixObject = (origin, target) => {
1361
+ const output = Object.assign(Object.assign({}, origin), target);
1362
+ const blendValue = {};
1363
+ for (const key in output) {
1364
+ if (origin[key] !== void 0 && target[key] !== void 0) {
1365
+ blendValue[key] = getMixer(origin[key], target[key]);
1366
+ }
1367
+ }
1368
+ return (v) => {
1369
+ for (const key in blendValue) {
1370
+ output[key] = blendValue[key](v);
1371
+ }
1372
+ return output;
1373
+ };
1374
+ };
1375
+ function analyse(value) {
1376
+ const parsed = complex.parse(value);
1377
+ const numValues = parsed.length;
1378
+ let numNumbers = 0;
1379
+ let numRGB = 0;
1380
+ let numHSL = 0;
1381
+ for (let i = 0; i < numValues; i++) {
1382
+ if (numNumbers || typeof parsed[i] === "number") {
1383
+ numNumbers++;
1384
+ } else {
1385
+ if (parsed[i].hue !== void 0) {
1386
+ numHSL++;
1387
+ } else {
1388
+ numRGB++;
1389
+ }
1390
+ }
1391
+ }
1392
+ return { parsed, numNumbers, numRGB, numHSL };
1393
+ }
1394
+ const mixComplex = (origin, target) => {
1395
+ const template = complex.createTransformer(target);
1396
+ const originStats = analyse(origin);
1397
+ const targetStats = analyse(target);
1398
+ const canInterpolate = originStats.numHSL === targetStats.numHSL && originStats.numRGB === targetStats.numRGB && originStats.numNumbers >= targetStats.numNumbers;
1399
+ if (canInterpolate) {
1400
+ return pipe(mixArray(originStats.parsed, targetStats.parsed), template);
1401
+ } else {
1402
+ return (p2) => `${p2 > 0 ? target : origin}`;
1403
+ }
1404
+ };
1405
+ const mixNumber = (from, to) => (p2) => mix(from, to, p2);
1406
+ function detectMixerFactory(v) {
1407
+ if (typeof v === "number") {
1408
+ return mixNumber;
1409
+ } else if (typeof v === "string") {
1410
+ if (color.test(v)) {
1411
+ return mixColor;
1412
+ } else {
1413
+ return mixComplex;
1414
+ }
1415
+ } else if (Array.isArray(v)) {
1416
+ return mixArray;
1417
+ } else if (typeof v === "object") {
1418
+ return mixObject;
1419
+ }
1420
+ }
1421
+ function createMixers(output, ease, customMixer) {
1422
+ const mixers = [];
1423
+ const mixerFactory = customMixer || detectMixerFactory(output[0]);
1424
+ const numMixers = output.length - 1;
1425
+ for (let i = 0; i < numMixers; i++) {
1426
+ let mixer = mixerFactory(output[i], output[i + 1]);
1427
+ if (ease) {
1428
+ const easingFunction = Array.isArray(ease) ? ease[i] : ease;
1429
+ mixer = pipe(easingFunction, mixer);
1430
+ }
1431
+ mixers.push(mixer);
1432
+ }
1433
+ return mixers;
1434
+ }
1435
+ function fastInterpolate([from, to], [mixer]) {
1436
+ return (v) => mixer(progress(from, to, v));
1437
+ }
1438
+ function slowInterpolate(input, mixers) {
1439
+ const inputLength = input.length;
1440
+ const lastInputIndex = inputLength - 1;
1441
+ return (v) => {
1442
+ let mixerIndex = 0;
1443
+ let foundMixerIndex = false;
1444
+ if (v <= input[0]) {
1445
+ foundMixerIndex = true;
1446
+ } else if (v >= input[lastInputIndex]) {
1447
+ mixerIndex = lastInputIndex - 1;
1448
+ foundMixerIndex = true;
1449
+ }
1450
+ if (!foundMixerIndex) {
1451
+ let i = 1;
1452
+ for (; i < inputLength; i++) {
1453
+ if (input[i] > v || i === lastInputIndex) {
1454
+ break;
1455
+ }
1456
+ }
1457
+ mixerIndex = i - 1;
1458
+ }
1459
+ const progressInRange = progress(input[mixerIndex], input[mixerIndex + 1], v);
1460
+ return mixers[mixerIndex](progressInRange);
1461
+ };
1462
+ }
1463
+ function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {}) {
1464
+ const inputLength = input.length;
1465
+ invariant(inputLength === output.length);
1466
+ invariant(!ease || !Array.isArray(ease) || ease.length === inputLength - 1);
1467
+ if (input[0] > input[inputLength - 1]) {
1468
+ input = [].concat(input);
1469
+ output = [].concat(output);
1470
+ input.reverse();
1471
+ output.reverse();
1472
+ }
1473
+ const mixers = createMixers(output, ease, mixer);
1474
+ const interpolator = inputLength === 2 ? fastInterpolate(input, mixers) : slowInterpolate(input, mixers);
1475
+ return isClamp ? (v) => interpolator(clamp$1(input[0], input[inputLength - 1], v)) : interpolator;
1476
+ }
1477
+ class InterpolateColor {
1478
+ constructor({ valueRange, colorRange }) {
1479
+ __publicField(this, "mapper");
1480
+ this.mapper = interpolate(valueRange, colorRange);
1481
+ }
1482
+ getColor(value) {
1483
+ return this.mapper(value);
1484
+ }
1485
+ }
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
+ function getColorByColorConf(conf, dataRow) {
1499
+ if (conf.type === "static") {
1500
+ return conf.staticColor;
1501
+ }
1502
+ if (conf.type === "continuous") {
1503
+ const mapper = new InterpolateColor(conf);
1504
+ const value = dataRow[conf.valueField];
1505
+ return mapper.getColor(value);
1506
+ }
1507
+ return "black";
1508
+ }
1509
+ function VizStats(_a) {
1510
+ var _b = _a, {
1511
+ conf: _c
1512
+ } = _b, _d = _c, {
1513
+ template,
1514
+ size,
1515
+ color: color2
1516
+ } = _d, rest = __objRest(_d, [
1517
+ "template",
1518
+ "size",
1519
+ "color"
1520
+ ]), {
1521
+ data
1522
+ } = _b;
1523
+ const finalColor = React.useMemo(() => {
1524
+ return getColorByColorConf(color2, data[0]);
1525
+ }, [color2, data]);
1526
+ return /* @__PURE__ */ jsx(Text, __spreadProps(__spreadValues({}, rest), {
1527
+ color: finalColor,
1528
+ sx: {
1529
+ fontSize: size
1530
+ },
1531
+ children: interpolateString(template, data[0])
1532
+ }));
1533
+ }
1116
1534
  function renderViz(width, height, data, viz) {
1117
1535
  const props = {
1118
1536
  width,
@@ -1124,11 +1542,14 @@ function renderViz(width, height, data, viz) {
1124
1542
  case "sunburst":
1125
1543
  return /* @__PURE__ */ jsx(Sunbrust, __spreadValues({}, props));
1126
1544
  case "line-bar":
1127
- return /* @__PURE__ */ jsx(VizLineBarChart, __spreadValues({}, props));
1545
+ case "cartesian":
1546
+ return /* @__PURE__ */ jsx(VizCartesianChart, __spreadValues({}, props));
1128
1547
  case "table":
1129
1548
  return /* @__PURE__ */ jsx(VizTable, __spreadValues({}, props));
1130
1549
  case "text":
1131
1550
  return /* @__PURE__ */ jsx(VizText, __spreadValues({}, props));
1551
+ case "stats":
1552
+ return /* @__PURE__ */ jsx(VizStats, __spreadValues({}, props));
1132
1553
  case "bar-3d":
1133
1554
  return /* @__PURE__ */ jsx(VizBar3D, __spreadValues({}, props));
1134
1555
  case "pie":
@@ -1352,8 +1773,8 @@ function MantineColorSelector({
1352
1773
  }) {
1353
1774
  const theme = useMantineTheme();
1354
1775
  const themeColors = React.useMemo(() => {
1355
- return Object.entries(theme.colors).map(([color, profile]) => ({
1356
- label: color,
1776
+ return Object.entries(theme.colors).map(([color2, profile]) => ({
1777
+ label: color2,
1357
1778
  value: profile[6]
1358
1779
  }));
1359
1780
  }, [theme]);
@@ -1403,6 +1824,9 @@ const numbroFormatExample = JSON.stringify({
1403
1824
  mantissa: 2
1404
1825
  }, null, 2);
1405
1826
  const labelPositions = [{
1827
+ label: "off",
1828
+ value: ""
1829
+ }, {
1406
1830
  label: "top",
1407
1831
  value: "top"
1408
1832
  }, {
@@ -1442,6 +1866,106 @@ const labelPositions = [{
1442
1866
  label: "insideBottomRight",
1443
1867
  value: "insideBottomRight"
1444
1868
  }];
1869
+ function SeriesItemField({
1870
+ form,
1871
+ index: index2
1872
+ }) {
1873
+ const value = form.values.series[index2];
1874
+ const {
1875
+ type
1876
+ } = value;
1877
+ return /* @__PURE__ */ jsxs(Group, {
1878
+ direction: "column",
1879
+ grow: true,
1880
+ my: 0,
1881
+ p: "md",
1882
+ pr: 40,
1883
+ sx: {
1884
+ border: "1px solid #eee",
1885
+ position: "relative"
1886
+ },
1887
+ children: [/* @__PURE__ */ jsxs(Group, {
1888
+ direction: "row",
1889
+ grow: true,
1890
+ 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({
1905
+ label: "Name",
1906
+ required: true,
1907
+ sx: {
1908
+ flex: 1
1909
+ }
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")))]
1914
+ }), /* @__PURE__ */ jsxs(Group, {
1915
+ direction: "row",
1916
+ grow: true,
1917
+ noWrap: true,
1918
+ align: "top",
1919
+ children: [type === "bar" && /* @__PURE__ */ jsx(Fragment, {
1920
+ children: /* @__PURE__ */ jsx(TextInput, __spreadValues({
1921
+ label: "Stack",
1922
+ placeholder: "Stack bars by this ID"
1923
+ }, form.getListInputProps("series", index2, "stack")))
1924
+ }), /* @__PURE__ */ jsx(Select, __spreadValues({
1925
+ label: "Label Position",
1926
+ 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")))]
1948
+ }), /* @__PURE__ */ jsxs(Group, {
1949
+ direction: "column",
1950
+ grow: true,
1951
+ children: [/* @__PURE__ */ jsx(Text, {
1952
+ children: "Color"
1953
+ }), /* @__PURE__ */ jsx(MantineColorSelector, __spreadValues({}, form.getListInputProps("series", index2, "color")))]
1954
+ }), /* @__PURE__ */ jsx(ActionIcon, {
1955
+ color: "red",
1956
+ variant: "hover",
1957
+ onClick: () => form.removeListItem("series", index2),
1958
+ sx: {
1959
+ position: "absolute",
1960
+ top: 15,
1961
+ right: 5
1962
+ },
1963
+ children: /* @__PURE__ */ jsx(Trash, {
1964
+ size: 16
1965
+ })
1966
+ })]
1967
+ }, index2);
1968
+ }
1445
1969
  function withDefaults(series) {
1446
1970
  function setDefaults({
1447
1971
  type,
@@ -1451,7 +1975,7 @@ function withDefaults(series) {
1451
1975
  y_axis_data_formatter = "",
1452
1976
  label_position = "top",
1453
1977
  stack = "1",
1454
- color = "black"
1978
+ color: color2 = "black"
1455
1979
  }) {
1456
1980
  return {
1457
1981
  type,
@@ -1461,12 +1985,12 @@ function withDefaults(series) {
1461
1985
  y_axis_data_formatter,
1462
1986
  label_position,
1463
1987
  stack,
1464
- color
1988
+ color: color2
1465
1989
  };
1466
1990
  }
1467
1991
  return series.map(setDefaults);
1468
1992
  }
1469
- function VizLineBarChartPanel({
1993
+ function VizCartesianChartPanel({
1470
1994
  conf,
1471
1995
  setConf
1472
1996
  }) {
@@ -1551,82 +2075,10 @@ function VizLineBarChartPanel({
1551
2075
  mt: "xl",
1552
2076
  mb: 0,
1553
2077
  children: "Series"
1554
- }), form.values.series.map((item, index2) => /* @__PURE__ */ jsxs(Group, {
1555
- direction: "column",
1556
- grow: true,
1557
- my: 0,
1558
- p: "md",
1559
- pr: 40,
1560
- sx: {
1561
- border: "1px solid #eee",
1562
- position: "relative"
1563
- },
1564
- children: [/* @__PURE__ */ jsxs(Group, {
1565
- direction: "row",
1566
- grow: true,
1567
- noWrap: true,
1568
- children: [/* @__PURE__ */ jsx(TextInput, __spreadValues({
1569
- label: "Name",
1570
- required: true,
1571
- sx: {
1572
- flex: 1
1573
- }
1574
- }, form.getListInputProps("series", index2, "name"))), /* @__PURE__ */ jsx(TextInput, __spreadValues({
1575
- label: "Stack",
1576
- placeholder: "Stack bars by this ID"
1577
- }, form.getListInputProps("series", index2, "stack"))), /* @__PURE__ */ jsx(TextInput, __spreadValues({
1578
- label: "Value key",
1579
- required: true
1580
- }, form.getListInputProps("series", index2, "y_axis_data_key")))]
1581
- }), /* @__PURE__ */ jsxs(Group, {
1582
- direction: "row",
1583
- grow: true,
1584
- noWrap: true,
1585
- align: "top",
1586
- children: [/* @__PURE__ */ jsx(Select, __spreadValues({
1587
- label: "Label Position",
1588
- data: labelPositions
1589
- }, form.getListInputProps("series", index2, "label_position"))), /* @__PURE__ */ jsx(JsonInput, __spreadValues({
1590
- sx: {
1591
- label: {
1592
- width: "100%"
1593
- }
1594
- },
1595
- label: /* @__PURE__ */ jsxs(Group, {
1596
- position: "apart",
1597
- children: [/* @__PURE__ */ jsx(Text, {
1598
- children: "Value Formatter"
1599
- }), /* @__PURE__ */ jsx(Anchor, {
1600
- href: "https://numbrojs.com/format.html",
1601
- target: "_blank",
1602
- children: "Formats"
1603
- })]
1604
- }),
1605
- placeholder: numbroFormatExample,
1606
- minRows: 4,
1607
- maxRows: 12,
1608
- autosize: true
1609
- }, form.getListInputProps("series", index2, "y_axis_data_formatter")))]
1610
- }), /* @__PURE__ */ jsxs(Group, {
1611
- direction: "column",
1612
- grow: true,
1613
- children: [/* @__PURE__ */ jsx(Text, {
1614
- children: "Color"
1615
- }), /* @__PURE__ */ jsx(MantineColorSelector, __spreadValues({}, form.getListInputProps("series", index2, "color")))]
1616
- }), /* @__PURE__ */ jsx(ActionIcon, {
1617
- color: "red",
1618
- variant: "hover",
1619
- onClick: () => form.removeListItem("series", index2),
1620
- sx: {
1621
- position: "absolute",
1622
- top: 15,
1623
- right: 5
1624
- },
1625
- children: /* @__PURE__ */ jsx(Trash, {
1626
- size: 16
1627
- })
1628
- })]
1629
- }, index2)), /* @__PURE__ */ jsx(Group, {
2078
+ }), form.values.series.map((_item, index2) => /* @__PURE__ */ jsx(SeriesItemField, {
2079
+ form,
2080
+ index: index2
2081
+ })), /* @__PURE__ */ jsx(Group, {
1630
2082
  position: "center",
1631
2083
  mt: "xs",
1632
2084
  children: /* @__PURE__ */ jsx(Button, {
@@ -1704,6 +2156,374 @@ function VizPiePanel({
1704
2156
  })
1705
2157
  });
1706
2158
  }
2159
+ const marks = [{
2160
+ label: "initial",
2161
+ value: 0
2162
+ }, {
2163
+ label: "500",
2164
+ value: 25
2165
+ }, {
2166
+ label: "700",
2167
+ value: 50
2168
+ }, {
2169
+ label: "semibold",
2170
+ value: 75
2171
+ }, {
2172
+ label: "bold",
2173
+ value: 100
2174
+ }];
2175
+ function MantineFontWeightSlider({
2176
+ label,
2177
+ value,
2178
+ onChange
2179
+ }) {
2180
+ var _a, _b;
2181
+ const [mark, setMark] = React.useState((_b = (_a = marks.find((m2) => m2.label === value)) == null ? void 0 : _a.value) != null ? _b : marks[0].value);
2182
+ React.useEffect(() => {
2183
+ const match = marks.find((s) => s.value === mark);
2184
+ if (match) {
2185
+ onChange(match.label);
2186
+ }
2187
+ }, [mark]);
2188
+ return /* @__PURE__ */ jsxs(Group, {
2189
+ direction: "column",
2190
+ grow: true,
2191
+ spacing: "xs",
2192
+ mb: "lg",
2193
+ children: [/* @__PURE__ */ jsx(Text, {
2194
+ children: label
2195
+ }), /* @__PURE__ */ jsx(Slider, {
2196
+ label: null,
2197
+ marks,
2198
+ value: mark,
2199
+ onChange: setMark,
2200
+ step: 25,
2201
+ placeholder: "Pick a font size"
2202
+ })]
2203
+ });
2204
+ }
2205
+ function TextArrayInput({
2206
+ label,
2207
+ value,
2208
+ onChange
2209
+ }) {
2210
+ const [values, setValues] = React.useState(Array.isArray(value) ? [...value] : []);
2211
+ const add = React.useCallback(() => {
2212
+ setValues((s) => [...s, ""]);
2213
+ }, [setValues]);
2214
+ const del = React.useCallback((index2) => {
2215
+ setValues((s) => {
2216
+ s.splice(index2, 1);
2217
+ return [...s];
2218
+ });
2219
+ }, [setValues]);
2220
+ const changed = React.useMemo(() => {
2221
+ return !_.isEqual(values, value);
2222
+ }, [values, value]);
2223
+ const submit = () => {
2224
+ onChange(values.map((s) => s.toString()));
2225
+ };
2226
+ return /* @__PURE__ */ jsxs(Fragment, {
2227
+ children: [/* @__PURE__ */ jsxs(Group, {
2228
+ position: "left",
2229
+ children: [/* @__PURE__ */ jsx(Text, {
2230
+ children: label
2231
+ }), /* @__PURE__ */ jsx(ActionIcon, {
2232
+ mr: 5,
2233
+ variant: "filled",
2234
+ color: "blue",
2235
+ disabled: !changed,
2236
+ onClick: submit,
2237
+ children: /* @__PURE__ */ jsx(DeviceFloppy, {
2238
+ size: 20
2239
+ })
2240
+ })]
2241
+ }), /* @__PURE__ */ jsxs(Group, {
2242
+ children: [values.map((v, i) => /* @__PURE__ */ jsx(TextInput, {
2243
+ value: v,
2244
+ onChange: (event) => {
2245
+ const newValue = event.currentTarget.value;
2246
+ setValues((s) => {
2247
+ s.splice(i, 1, newValue);
2248
+ return [...s];
2249
+ });
2250
+ },
2251
+ rightSection: /* @__PURE__ */ jsx(ActionIcon, {
2252
+ onClick: () => del(i),
2253
+ color: "red",
2254
+ children: /* @__PURE__ */ jsx(Trash, {
2255
+ size: 14
2256
+ })
2257
+ }),
2258
+ sx: {
2259
+ width: "45%"
2260
+ }
2261
+ })), /* @__PURE__ */ jsx(ActionIcon, {
2262
+ onClick: add,
2263
+ color: "blue",
2264
+ variant: "outline",
2265
+ children: /* @__PURE__ */ jsx(PlaylistAdd, {
2266
+ size: 20
2267
+ })
2268
+ })]
2269
+ })]
2270
+ });
2271
+ }
2272
+ function ColorArrayInput({
2273
+ label,
2274
+ value,
2275
+ onChange
2276
+ }) {
2277
+ const [values, setValues] = React.useState(Array.isArray(value) ? [...value] : []);
2278
+ const add = React.useCallback(() => {
2279
+ setValues((s) => [...s, ""]);
2280
+ }, [setValues]);
2281
+ const del = React.useCallback((index2) => {
2282
+ setValues((s) => {
2283
+ s.splice(index2, 1);
2284
+ return [...s];
2285
+ });
2286
+ }, [setValues]);
2287
+ const changed = React.useMemo(() => {
2288
+ return !_.isEqual(values, value);
2289
+ }, [values, value]);
2290
+ const submit = () => {
2291
+ onChange(values.map((s) => s.toString()));
2292
+ };
2293
+ const theme = useMantineTheme();
2294
+ const swatches = React.useMemo(() => {
2295
+ return Object.entries(theme.colors).map(([_color, profile]) => profile[6]);
2296
+ }, [theme]);
2297
+ return /* @__PURE__ */ jsxs(Fragment, {
2298
+ children: [/* @__PURE__ */ jsxs(Group, {
2299
+ position: "left",
2300
+ children: [/* @__PURE__ */ jsx(Text, {
2301
+ children: label
2302
+ }), /* @__PURE__ */ jsx(ActionIcon, {
2303
+ mr: 5,
2304
+ variant: "filled",
2305
+ color: "blue",
2306
+ disabled: !changed,
2307
+ onClick: submit,
2308
+ children: /* @__PURE__ */ jsx(DeviceFloppy, {
2309
+ size: 20
2310
+ })
2311
+ })]
2312
+ }), /* @__PURE__ */ jsxs(Group, {
2313
+ children: [values.map((v, i) => /* @__PURE__ */ jsx(ColorInput, {
2314
+ value: v,
2315
+ onChange: (color2) => {
2316
+ setValues((s) => {
2317
+ s.splice(i, 1, color2);
2318
+ return [...s];
2319
+ });
2320
+ },
2321
+ swatches,
2322
+ rightSection: /* @__PURE__ */ jsx(ActionIcon, {
2323
+ onClick: () => del(i),
2324
+ color: "red",
2325
+ children: /* @__PURE__ */ jsx(Trash, {
2326
+ size: 14
2327
+ })
2328
+ }),
2329
+ sx: {
2330
+ width: "45%"
2331
+ }
2332
+ })), /* @__PURE__ */ jsx(ActionIcon, {
2333
+ onClick: add,
2334
+ color: "blue",
2335
+ variant: "outline",
2336
+ children: /* @__PURE__ */ jsx(PlaylistAdd, {
2337
+ size: 20
2338
+ })
2339
+ })]
2340
+ })]
2341
+ });
2342
+ }
2343
+ function VizStatsPanel({
2344
+ conf,
2345
+ setConf
2346
+ }) {
2347
+ const defaultValues = _.merge({}, {
2348
+ align: "center",
2349
+ size: "100px",
2350
+ template: "",
2351
+ weight: "bold",
2352
+ color: {
2353
+ type: "static",
2354
+ staticColor: "red"
2355
+ }
2356
+ }, conf);
2357
+ const {
2358
+ control,
2359
+ handleSubmit,
2360
+ watch,
2361
+ formState: {
2362
+ isDirty
2363
+ }
2364
+ } = useForm({
2365
+ defaultValues
2366
+ });
2367
+ const colorType = watch("color.type");
2368
+ watch("color.valueField");
2369
+ return /* @__PURE__ */ jsx(Group, {
2370
+ direction: "column",
2371
+ mt: "md",
2372
+ spacing: "xs",
2373
+ grow: true,
2374
+ noWrap: true,
2375
+ children: /* @__PURE__ */ jsxs("form", {
2376
+ onSubmit: handleSubmit(setConf),
2377
+ children: [/* @__PURE__ */ jsxs(Group, {
2378
+ position: "left",
2379
+ py: "md",
2380
+ pl: "md",
2381
+ sx: {
2382
+ borderBottom: "1px solid #eee",
2383
+ background: "#efefef"
2384
+ },
2385
+ children: [/* @__PURE__ */ jsx(Text, {
2386
+ weight: 500,
2387
+ children: "Stats Configurations"
2388
+ }), /* @__PURE__ */ jsx(ActionIcon, {
2389
+ type: "submit",
2390
+ mr: 5,
2391
+ variant: "filled",
2392
+ color: "blue",
2393
+ disabled: !isDirty,
2394
+ children: /* @__PURE__ */ jsx(DeviceFloppy, {
2395
+ size: 20
2396
+ })
2397
+ })]
2398
+ }), /* @__PURE__ */ jsxs(Accordion, {
2399
+ offsetIcon: false,
2400
+ multiple: true,
2401
+ initialState: {
2402
+ 0: true,
2403
+ 2: true
2404
+ },
2405
+ children: [/* @__PURE__ */ jsx(Accordion.Item, {
2406
+ label: "Content",
2407
+ children: /* @__PURE__ */ jsx(Group, {
2408
+ direction: "column",
2409
+ grow: true,
2410
+ children: /* @__PURE__ */ jsx(Controller, {
2411
+ name: "template",
2412
+ control,
2413
+ render: ({
2414
+ 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
+ })
2424
+ })
2425
+ }), /* @__PURE__ */ jsxs(Accordion.Item, {
2426
+ label: "Font",
2427
+ children: [/* @__PURE__ */ jsx(Group, {
2428
+ direction: "column",
2429
+ grow: true,
2430
+ children: /* @__PURE__ */ jsx(Controller, {
2431
+ name: "size",
2432
+ control,
2433
+ render: ({
2434
+ field
2435
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2436
+ label: "Font Size",
2437
+ placeholder: "10px, 1em, 1rem, 100%...",
2438
+ sx: {
2439
+ flex: 1
2440
+ }
2441
+ }, field))
2442
+ })
2443
+ }), /* @__PURE__ */ jsx(Group, {
2444
+ position: "apart",
2445
+ grow: true,
2446
+ sx: {
2447
+ "> *": {
2448
+ flexGrow: 1,
2449
+ maxWidth: "100%"
2450
+ }
2451
+ },
2452
+ children: /* @__PURE__ */ jsx(Controller, {
2453
+ name: "weight",
2454
+ control,
2455
+ render: ({
2456
+ field
2457
+ }) => /* @__PURE__ */ jsx(MantineFontWeightSlider, __spreadValues({
2458
+ label: "Font Weight"
2459
+ }, field))
2460
+ })
2461
+ })]
2462
+ }), /* @__PURE__ */ jsx(Accordion.Item, {
2463
+ label: "Color",
2464
+ children: /* @__PURE__ */ jsxs(Group, {
2465
+ direction: "column",
2466
+ grow: true,
2467
+ children: [/* @__PURE__ */ jsx(Controller, {
2468
+ name: "color.type",
2469
+ control,
2470
+ render: ({
2471
+ field
2472
+ }) => /* @__PURE__ */ jsx(Select, __spreadValues({
2473
+ label: "Color Type",
2474
+ data: [{
2475
+ label: "Static Color",
2476
+ value: "static"
2477
+ }, {
2478
+ label: "Continuous Color",
2479
+ value: "continuous"
2480
+ }]
2481
+ }, field))
2482
+ }), colorType === "static" && /* @__PURE__ */ jsx(Controller, {
2483
+ name: "color.staticColor",
2484
+ control,
2485
+ render: ({
2486
+ field
2487
+ }) => /* @__PURE__ */ jsx(MantineColorSelector, __spreadValues({}, field))
2488
+ }), colorType === "continuous" && /* @__PURE__ */ jsxs(Fragment, {
2489
+ children: [/* @__PURE__ */ jsx(Controller, {
2490
+ name: "color.valueField",
2491
+ control,
2492
+ defaultValue: "",
2493
+ render: ({
2494
+ field
2495
+ }) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
2496
+ placeholder: "Calculate color with this field",
2497
+ label: "Value Field",
2498
+ required: true,
2499
+ sx: {
2500
+ flex: 1
2501
+ }
2502
+ }, field))
2503
+ }), /* @__PURE__ */ jsx(Controller, {
2504
+ name: "color.valueRange",
2505
+ control,
2506
+ render: ({
2507
+ field
2508
+ }) => /* @__PURE__ */ jsx(TextArrayInput, __spreadValues({
2509
+ label: "Value Range"
2510
+ }, field))
2511
+ }), /* @__PURE__ */ jsx(Controller, {
2512
+ name: "color.colorRange",
2513
+ control,
2514
+ render: ({
2515
+ field
2516
+ }) => /* @__PURE__ */ jsx(ColorArrayInput, __spreadValues({
2517
+ label: "Color Range"
2518
+ }, field))
2519
+ })]
2520
+ })]
2521
+ })
2522
+ })]
2523
+ })]
2524
+ })
2525
+ });
2526
+ }
1707
2527
  function SunburstPanel({
1708
2528
  conf: {
1709
2529
  label_field,
@@ -1788,16 +2608,16 @@ function ValueTypeSelector({
1788
2608
  sx
1789
2609
  });
1790
2610
  }
1791
- function VizTablePanel(_a) {
1792
- var _b = _a, {
1793
- conf: _c
1794
- } = _b, _d = _c, {
2611
+ function VizTablePanel(_e) {
2612
+ var _f = _e, {
2613
+ conf: _g
2614
+ } = _f, _h = _g, {
1795
2615
  columns
1796
- } = _d, restConf = __objRest(_d, [
2616
+ } = _h, restConf = __objRest(_h, [
1797
2617
  "columns"
1798
2618
  ]), {
1799
2619
  setConf
1800
- } = _b;
2620
+ } = _f;
1801
2621
  const form = useForm$1({
1802
2622
  initialValues: __spreadValues({
1803
2623
  id_field: "id",
@@ -2009,52 +2829,6 @@ function VizTablePanel(_a) {
2009
2829
  })
2010
2830
  });
2011
2831
  }
2012
- const marks = [{
2013
- label: "initial",
2014
- value: 0
2015
- }, {
2016
- label: "500",
2017
- value: 25
2018
- }, {
2019
- label: "700",
2020
- value: 50
2021
- }, {
2022
- label: "semibold",
2023
- value: 75
2024
- }, {
2025
- label: "bold",
2026
- value: 100
2027
- }];
2028
- function MantineFontWeightSlider({
2029
- label,
2030
- value,
2031
- onChange
2032
- }) {
2033
- var _a, _b;
2034
- const [mark, setMark] = React.useState((_b = (_a = marks.find((m2) => m2.label === value)) == null ? void 0 : _a.value) != null ? _b : marks[0].value);
2035
- React.useEffect(() => {
2036
- const match = marks.find((s) => s.value === mark);
2037
- if (match) {
2038
- onChange(match.label);
2039
- }
2040
- }, [mark]);
2041
- return /* @__PURE__ */ jsxs(Group, {
2042
- direction: "column",
2043
- grow: true,
2044
- spacing: "xs",
2045
- mb: "lg",
2046
- children: [/* @__PURE__ */ jsx(Text, {
2047
- children: label
2048
- }), /* @__PURE__ */ jsx(Slider, {
2049
- label: null,
2050
- marks,
2051
- value: mark,
2052
- onChange: setMark,
2053
- step: 25,
2054
- placeholder: "Pick a font size"
2055
- })]
2056
- });
2057
- }
2058
2832
  const sampleParagraphs = [{
2059
2833
  align: "center",
2060
2834
  size: "xl",
@@ -2194,6 +2968,10 @@ const types = [{
2194
2968
  value: "text",
2195
2969
  label: "Text",
2196
2970
  Panel: VizTextPanel
2971
+ }, {
2972
+ value: "stats",
2973
+ label: "Stats",
2974
+ Panel: VizStatsPanel
2197
2975
  }, {
2198
2976
  value: "table",
2199
2977
  label: "Table",
@@ -2207,9 +2985,9 @@ const types = [{
2207
2985
  label: "Bar Chart (3D)",
2208
2986
  Panel: VizBar3DPanel
2209
2987
  }, {
2210
- value: "line-bar",
2211
- label: "Line-Bar Chart",
2212
- Panel: VizLineBarChartPanel
2988
+ value: "cartesian",
2989
+ label: "Cartesian Chart",
2990
+ Panel: VizCartesianChartPanel
2213
2991
  }, {
2214
2992
  value: "pie",
2215
2993
  label: "Pie Chart",
@@ -2799,7 +3577,8 @@ function DataSourceForm({
2799
3577
  });
2800
3578
  }
2801
3579
  function DataSourceEditor({
2802
- id
3580
+ id,
3581
+ setID
2803
3582
  }) {
2804
3583
  const {
2805
3584
  dataSources,
@@ -2819,7 +3598,8 @@ function DataSourceEditor({
2819
3598
  prevs.splice(index22, 1, value);
2820
3599
  return [...prevs];
2821
3600
  });
2822
- }, [id, dataSources, setDataSources]);
3601
+ setID(value.id);
3602
+ }, [id, dataSources, setDataSources, setID]);
2823
3603
  if (!id) {
2824
3604
  return null;
2825
3605
  }
@@ -2951,7 +3731,8 @@ function EditDataSourcesModal({
2951
3731
  setID
2952
3732
  }),
2953
3733
  children: [/* @__PURE__ */ jsx(DataSourceEditor, {
2954
- id
3734
+ id,
3735
+ setID
2955
3736
  }), /* @__PURE__ */ jsx(DataPreview, {
2956
3737
  id
2957
3738
  })]
@@ -3044,46 +3825,48 @@ WHERE \${author_time_condition}`;
3044
3825
  }) => {
3045
3826
  setSQLSnippets(snippets);
3046
3827
  };
3047
- return /* @__PURE__ */ jsxs(Group, {
3828
+ return /* @__PURE__ */ jsx(Group, {
3048
3829
  direction: "column",
3049
3830
  grow: true,
3050
3831
  sx: {
3051
3832
  border: "1px solid #eee"
3052
3833
  },
3053
- children: [/* @__PURE__ */ jsxs(Group, {
3054
- position: "left",
3055
- pl: "md",
3056
- py: "md",
3057
- sx: {
3058
- borderBottom: "1px solid #eee",
3059
- background: "#efefef",
3060
- flexGrow: 0
3061
- },
3062
- children: [/* @__PURE__ */ jsx(Text, {
3063
- weight: 500,
3064
- children: "SQL Snippets"
3065
- }), /* @__PURE__ */ jsx(ActionIcon, {
3066
- type: "submit",
3067
- mr: 5,
3068
- variant: "filled",
3069
- color: "blue",
3070
- disabled: !changed,
3071
- children: /* @__PURE__ */ jsx(DeviceFloppy, {
3072
- size: 20
3073
- })
3074
- })]
3075
- }), /* @__PURE__ */ jsxs(Group, {
3076
- px: "md",
3077
- pb: "md",
3078
- children: [/* @__PURE__ */ jsx(Prism, {
3079
- language: "sql",
3834
+ children: /* @__PURE__ */ jsxs("form", {
3835
+ onSubmit: form.onSubmit(submit),
3836
+ children: [/* @__PURE__ */ jsxs(Group, {
3837
+ position: "left",
3838
+ pl: "md",
3839
+ py: "md",
3080
3840
  sx: {
3081
- width: "100%"
3841
+ borderBottom: "1px solid #eee",
3842
+ background: "#efefef",
3843
+ flexGrow: 0
3082
3844
  },
3083
- noCopy: true,
3084
- trim: false,
3085
- colorScheme: "dark",
3086
- children: `-- You may refer context data *by name*
3845
+ children: [/* @__PURE__ */ jsx(Text, {
3846
+ weight: 500,
3847
+ children: "SQL Snippets"
3848
+ }), /* @__PURE__ */ jsx(ActionIcon, {
3849
+ type: "submit",
3850
+ mr: 5,
3851
+ variant: "filled",
3852
+ color: "blue",
3853
+ disabled: !changed,
3854
+ children: /* @__PURE__ */ jsx(DeviceFloppy, {
3855
+ size: 20
3856
+ })
3857
+ })]
3858
+ }), /* @__PURE__ */ jsxs(Group, {
3859
+ px: "md",
3860
+ pb: "md",
3861
+ children: [/* @__PURE__ */ jsx(Prism, {
3862
+ language: "sql",
3863
+ sx: {
3864
+ width: "100%"
3865
+ },
3866
+ noCopy: true,
3867
+ trim: false,
3868
+ colorScheme: "dark",
3869
+ children: `-- You may refer context data *by name*
3087
3870
  -- in SQL or VizConfig.
3088
3871
 
3089
3872
  ${sampleSQL}
@@ -3091,15 +3874,13 @@ ${sampleSQL}
3091
3874
  -- where author_time_condition is:
3092
3875
  author_time BETWEEN '\${timeRange?.[0].toISOString()}' AND '\${timeRange?.[1].toISOString()}'
3093
3876
  `
3094
- }), /* @__PURE__ */ jsx(Group, {
3095
- direction: "column",
3096
- sx: {
3097
- width: "100%",
3098
- position: "relative"
3099
- },
3100
- grow: true,
3101
- children: /* @__PURE__ */ jsxs("form", {
3102
- onSubmit: form.onSubmit(submit),
3877
+ }), /* @__PURE__ */ jsxs(Group, {
3878
+ direction: "column",
3879
+ sx: {
3880
+ width: "100%",
3881
+ position: "relative"
3882
+ },
3883
+ grow: true,
3103
3884
  children: [form.values.snippets.map((_item, index2) => /* @__PURE__ */ jsxs(Group, {
3104
3885
  direction: "column",
3105
3886
  grow: true,
@@ -3144,9 +3925,9 @@ author_time BETWEEN '\${timeRange?.[0].toISOString()}' AND '\${timeRange?.[1].to
3144
3925
  children: "Add a snippet"
3145
3926
  })
3146
3927
  })]
3147
- })
3928
+ })]
3148
3929
  })]
3149
- })]
3930
+ })
3150
3931
  });
3151
3932
  }
3152
3933
  function EditSQLSnippetsModal({