@devtable/dashboard 1.6.0 → 1.9.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.
- package/dist/contexts/layout-state-context.d.ts +2 -0
- package/dist/dashboard.es.js +964 -178
- package/dist/dashboard.umd.js +8 -8
- package/dist/definition-editor/data-source-editor/editor.d.ts +3 -2
- package/dist/panel/settings/common/color-array-input.d.ts +8 -0
- package/dist/panel/settings/common/text-array-input.d.ts +8 -0
- package/dist/panel/viz/line-bar/type.d.ts +4 -0
- package/dist/panel/viz/stats/index.d.ts +9 -0
- package/dist/panel/viz/stats/panel.d.ts +3 -0
- package/dist/panel/viz/stats/types.d.ts +17 -0
- package/dist/panel/viz/table/type.d.ts +1 -1
- package/dist/types/dashboard.d.ts +1 -0
- package/dist/utils/color-mapping.d.ts +10 -0
- package/package.json +4 -2
package/dist/dashboard.es.js
CHANGED
|
@@ -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,
|
|
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, Paint, PlayerPlay,
|
|
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";
|
|
@@ -50,6 +54,7 @@ import { formList, useForm as useForm$1 } from "@mantine/form";
|
|
|
50
54
|
import { Prism } from "@mantine/prism";
|
|
51
55
|
var DashboardMode = /* @__PURE__ */ ((DashboardMode2) => {
|
|
52
56
|
DashboardMode2["Use"] = "use";
|
|
57
|
+
DashboardMode2["Layout"] = "layout";
|
|
53
58
|
DashboardMode2["Edit"] = "edit";
|
|
54
59
|
return DashboardMode2;
|
|
55
60
|
})(DashboardMode || {});
|
|
@@ -58,7 +63,9 @@ const initialContext$3 = {
|
|
|
58
63
|
freezeLayout: () => {
|
|
59
64
|
},
|
|
60
65
|
mode: DashboardMode.Edit,
|
|
61
|
-
inEditMode: false
|
|
66
|
+
inEditMode: false,
|
|
67
|
+
inLayoutMode: false,
|
|
68
|
+
inUseMode: true
|
|
62
69
|
};
|
|
63
70
|
const LayoutStateContext = React.createContext(initialContext$3);
|
|
64
71
|
const getRequest = (method) => {
|
|
@@ -216,7 +223,7 @@ function DescriptionPopover({
|
|
|
216
223
|
React.useEffect(() => {
|
|
217
224
|
freezeLayout(opened);
|
|
218
225
|
}, [opened]);
|
|
219
|
-
if (!description) {
|
|
226
|
+
if (!description || description === "<p><br></p>") {
|
|
220
227
|
return null;
|
|
221
228
|
}
|
|
222
229
|
const target = trigger === "click" ? /* @__PURE__ */ jsx(Tooltip, {
|
|
@@ -463,7 +470,8 @@ function DataPreview({
|
|
|
463
470
|
});
|
|
464
471
|
if (loading) {
|
|
465
472
|
return /* @__PURE__ */ jsx(LoadingOverlay, {
|
|
466
|
-
visible: loading
|
|
473
|
+
visible: loading,
|
|
474
|
+
exitTransitionDuration: 0
|
|
467
475
|
});
|
|
468
476
|
}
|
|
469
477
|
if (data.length === 0) {
|
|
@@ -845,7 +853,7 @@ function CellValue({
|
|
|
845
853
|
}
|
|
846
854
|
function VizTable({
|
|
847
855
|
conf,
|
|
848
|
-
data,
|
|
856
|
+
data = [],
|
|
849
857
|
width,
|
|
850
858
|
height
|
|
851
859
|
}) {
|
|
@@ -886,7 +894,7 @@ function VizTable({
|
|
|
886
894
|
}, label))
|
|
887
895
|
})
|
|
888
896
|
}), /* @__PURE__ */ jsx("tbody", {
|
|
889
|
-
children: data.map((row, index2) => /* @__PURE__ */ jsx("tr", {
|
|
897
|
+
children: data.slice(0, 30).map((row, index2) => /* @__PURE__ */ jsx("tr", {
|
|
890
898
|
children: finalColumns.map(({
|
|
891
899
|
value_field,
|
|
892
900
|
value_type
|
|
@@ -894,7 +902,8 @@ function VizTable({
|
|
|
894
902
|
children: /* @__PURE__ */ jsx(Group, {
|
|
895
903
|
sx: {
|
|
896
904
|
"&, .mantine-Text-root": {
|
|
897
|
-
fontFamily: "monospace"
|
|
905
|
+
fontFamily: "monospace",
|
|
906
|
+
fontSize: rest.fontSize
|
|
898
907
|
}
|
|
899
908
|
},
|
|
900
909
|
children: /* @__PURE__ */ jsx(CellValue, {
|
|
@@ -904,12 +913,26 @@ function VizTable({
|
|
|
904
913
|
})
|
|
905
914
|
}, row[value_field]))
|
|
906
915
|
}, id_field ? row[id_field] : `row-${index2}`))
|
|
916
|
+
}), data.length > 100 && /* @__PURE__ */ jsx("tfoot", {
|
|
917
|
+
children: /* @__PURE__ */ jsx("tr", {
|
|
918
|
+
children: /* @__PURE__ */ jsx("td", {
|
|
919
|
+
colSpan: labels.length,
|
|
920
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
921
|
+
color: "red",
|
|
922
|
+
size: "sm",
|
|
923
|
+
children: "Showing only the first 30 rows to avoid causing slow performance"
|
|
924
|
+
})
|
|
925
|
+
})
|
|
926
|
+
})
|
|
907
927
|
})]
|
|
908
928
|
}));
|
|
909
929
|
}
|
|
910
|
-
function interpolateString(template, params = {}) {
|
|
911
|
-
const
|
|
912
|
-
|
|
930
|
+
function interpolateString$1(template, params = {}) {
|
|
931
|
+
const extendedParams = __spreadProps(__spreadValues({}, params), {
|
|
932
|
+
numbro
|
|
933
|
+
});
|
|
934
|
+
const names = Object.keys(extendedParams);
|
|
935
|
+
const vals = Object.values(extendedParams);
|
|
913
936
|
try {
|
|
914
937
|
return new Function(...names, `return \`${template}\`;`)(...vals);
|
|
915
938
|
} catch (error) {
|
|
@@ -935,7 +958,7 @@ function VizText({
|
|
|
935
958
|
sx: {
|
|
936
959
|
fontSize: size
|
|
937
960
|
},
|
|
938
|
-
children: interpolateString(template, data[0])
|
|
961
|
+
children: interpolateString$1(template, data[0])
|
|
939
962
|
}), `${template}---${index2}`);
|
|
940
963
|
})
|
|
941
964
|
});
|
|
@@ -1094,6 +1117,420 @@ function VizPie({
|
|
|
1094
1117
|
}
|
|
1095
1118
|
});
|
|
1096
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
|
+
}
|
|
1097
1534
|
function renderViz(width, height, data, viz) {
|
|
1098
1535
|
const props = {
|
|
1099
1536
|
width,
|
|
@@ -1110,6 +1547,8 @@ function renderViz(width, height, data, viz) {
|
|
|
1110
1547
|
return /* @__PURE__ */ jsx(VizTable, __spreadValues({}, props));
|
|
1111
1548
|
case "text":
|
|
1112
1549
|
return /* @__PURE__ */ jsx(VizText, __spreadValues({}, props));
|
|
1550
|
+
case "stats":
|
|
1551
|
+
return /* @__PURE__ */ jsx(VizStats, __spreadValues({}, props));
|
|
1113
1552
|
case "bar-3d":
|
|
1114
1553
|
return /* @__PURE__ */ jsx(VizBar3D, __spreadValues({}, props));
|
|
1115
1554
|
case "pie":
|
|
@@ -1134,7 +1573,8 @@ function Viz({
|
|
|
1134
1573
|
className: "viz-root",
|
|
1135
1574
|
ref,
|
|
1136
1575
|
children: /* @__PURE__ */ jsx(LoadingOverlay, {
|
|
1137
|
-
visible: loading
|
|
1576
|
+
visible: loading,
|
|
1577
|
+
exitTransitionDuration: 0
|
|
1138
1578
|
})
|
|
1139
1579
|
});
|
|
1140
1580
|
}
|
|
@@ -1332,8 +1772,8 @@ function MantineColorSelector({
|
|
|
1332
1772
|
}) {
|
|
1333
1773
|
const theme = useMantineTheme();
|
|
1334
1774
|
const themeColors = React.useMemo(() => {
|
|
1335
|
-
return Object.entries(theme.colors).map(([
|
|
1336
|
-
label:
|
|
1775
|
+
return Object.entries(theme.colors).map(([color2, profile]) => ({
|
|
1776
|
+
label: color2,
|
|
1337
1777
|
value: profile[6]
|
|
1338
1778
|
}));
|
|
1339
1779
|
}, [theme]);
|
|
@@ -1431,7 +1871,7 @@ function withDefaults(series) {
|
|
|
1431
1871
|
y_axis_data_formatter = "",
|
|
1432
1872
|
label_position = "top",
|
|
1433
1873
|
stack = "1",
|
|
1434
|
-
color = "black"
|
|
1874
|
+
color: color2 = "black"
|
|
1435
1875
|
}) {
|
|
1436
1876
|
return {
|
|
1437
1877
|
type,
|
|
@@ -1441,7 +1881,7 @@ function withDefaults(series) {
|
|
|
1441
1881
|
y_axis_data_formatter,
|
|
1442
1882
|
label_position,
|
|
1443
1883
|
stack,
|
|
1444
|
-
color
|
|
1884
|
+
color: color2
|
|
1445
1885
|
};
|
|
1446
1886
|
}
|
|
1447
1887
|
return series.map(setDefaults);
|
|
@@ -1684,6 +2124,374 @@ function VizPiePanel({
|
|
|
1684
2124
|
})
|
|
1685
2125
|
});
|
|
1686
2126
|
}
|
|
2127
|
+
const marks = [{
|
|
2128
|
+
label: "initial",
|
|
2129
|
+
value: 0
|
|
2130
|
+
}, {
|
|
2131
|
+
label: "500",
|
|
2132
|
+
value: 25
|
|
2133
|
+
}, {
|
|
2134
|
+
label: "700",
|
|
2135
|
+
value: 50
|
|
2136
|
+
}, {
|
|
2137
|
+
label: "semibold",
|
|
2138
|
+
value: 75
|
|
2139
|
+
}, {
|
|
2140
|
+
label: "bold",
|
|
2141
|
+
value: 100
|
|
2142
|
+
}];
|
|
2143
|
+
function MantineFontWeightSlider({
|
|
2144
|
+
label,
|
|
2145
|
+
value,
|
|
2146
|
+
onChange
|
|
2147
|
+
}) {
|
|
2148
|
+
var _a, _b;
|
|
2149
|
+
const [mark, setMark] = React.useState((_b = (_a = marks.find((m2) => m2.label === value)) == null ? void 0 : _a.value) != null ? _b : marks[0].value);
|
|
2150
|
+
React.useEffect(() => {
|
|
2151
|
+
const match = marks.find((s) => s.value === mark);
|
|
2152
|
+
if (match) {
|
|
2153
|
+
onChange(match.label);
|
|
2154
|
+
}
|
|
2155
|
+
}, [mark]);
|
|
2156
|
+
return /* @__PURE__ */ jsxs(Group, {
|
|
2157
|
+
direction: "column",
|
|
2158
|
+
grow: true,
|
|
2159
|
+
spacing: "xs",
|
|
2160
|
+
mb: "lg",
|
|
2161
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2162
|
+
children: label
|
|
2163
|
+
}), /* @__PURE__ */ jsx(Slider, {
|
|
2164
|
+
label: null,
|
|
2165
|
+
marks,
|
|
2166
|
+
value: mark,
|
|
2167
|
+
onChange: setMark,
|
|
2168
|
+
step: 25,
|
|
2169
|
+
placeholder: "Pick a font size"
|
|
2170
|
+
})]
|
|
2171
|
+
});
|
|
2172
|
+
}
|
|
2173
|
+
function TextArrayInput({
|
|
2174
|
+
label,
|
|
2175
|
+
value,
|
|
2176
|
+
onChange
|
|
2177
|
+
}) {
|
|
2178
|
+
const [values, setValues] = React.useState(Array.isArray(value) ? [...value] : []);
|
|
2179
|
+
const add = React.useCallback(() => {
|
|
2180
|
+
setValues((s) => [...s, ""]);
|
|
2181
|
+
}, [setValues]);
|
|
2182
|
+
const del = React.useCallback((index2) => {
|
|
2183
|
+
setValues((s) => {
|
|
2184
|
+
s.splice(index2, 1);
|
|
2185
|
+
return [...s];
|
|
2186
|
+
});
|
|
2187
|
+
}, [setValues]);
|
|
2188
|
+
const changed = React.useMemo(() => {
|
|
2189
|
+
return !_.isEqual(values, value);
|
|
2190
|
+
}, [values, value]);
|
|
2191
|
+
const submit = () => {
|
|
2192
|
+
onChange(values.map((s) => s.toString()));
|
|
2193
|
+
};
|
|
2194
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
2195
|
+
children: [/* @__PURE__ */ jsxs(Group, {
|
|
2196
|
+
position: "left",
|
|
2197
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2198
|
+
children: label
|
|
2199
|
+
}), /* @__PURE__ */ jsx(ActionIcon, {
|
|
2200
|
+
mr: 5,
|
|
2201
|
+
variant: "filled",
|
|
2202
|
+
color: "blue",
|
|
2203
|
+
disabled: !changed,
|
|
2204
|
+
onClick: submit,
|
|
2205
|
+
children: /* @__PURE__ */ jsx(DeviceFloppy, {
|
|
2206
|
+
size: 20
|
|
2207
|
+
})
|
|
2208
|
+
})]
|
|
2209
|
+
}), /* @__PURE__ */ jsxs(Group, {
|
|
2210
|
+
children: [values.map((v, i) => /* @__PURE__ */ jsx(TextInput, {
|
|
2211
|
+
value: v,
|
|
2212
|
+
onChange: (event) => {
|
|
2213
|
+
const newValue = event.currentTarget.value;
|
|
2214
|
+
setValues((s) => {
|
|
2215
|
+
s.splice(i, 1, newValue);
|
|
2216
|
+
return [...s];
|
|
2217
|
+
});
|
|
2218
|
+
},
|
|
2219
|
+
rightSection: /* @__PURE__ */ jsx(ActionIcon, {
|
|
2220
|
+
onClick: () => del(i),
|
|
2221
|
+
color: "red",
|
|
2222
|
+
children: /* @__PURE__ */ jsx(Trash, {
|
|
2223
|
+
size: 14
|
|
2224
|
+
})
|
|
2225
|
+
}),
|
|
2226
|
+
sx: {
|
|
2227
|
+
width: "45%"
|
|
2228
|
+
}
|
|
2229
|
+
})), /* @__PURE__ */ jsx(ActionIcon, {
|
|
2230
|
+
onClick: add,
|
|
2231
|
+
color: "blue",
|
|
2232
|
+
variant: "outline",
|
|
2233
|
+
children: /* @__PURE__ */ jsx(PlaylistAdd, {
|
|
2234
|
+
size: 20
|
|
2235
|
+
})
|
|
2236
|
+
})]
|
|
2237
|
+
})]
|
|
2238
|
+
});
|
|
2239
|
+
}
|
|
2240
|
+
function ColorArrayInput({
|
|
2241
|
+
label,
|
|
2242
|
+
value,
|
|
2243
|
+
onChange
|
|
2244
|
+
}) {
|
|
2245
|
+
const [values, setValues] = React.useState(Array.isArray(value) ? [...value] : []);
|
|
2246
|
+
const add = React.useCallback(() => {
|
|
2247
|
+
setValues((s) => [...s, ""]);
|
|
2248
|
+
}, [setValues]);
|
|
2249
|
+
const del = React.useCallback((index2) => {
|
|
2250
|
+
setValues((s) => {
|
|
2251
|
+
s.splice(index2, 1);
|
|
2252
|
+
return [...s];
|
|
2253
|
+
});
|
|
2254
|
+
}, [setValues]);
|
|
2255
|
+
const changed = React.useMemo(() => {
|
|
2256
|
+
return !_.isEqual(values, value);
|
|
2257
|
+
}, [values, value]);
|
|
2258
|
+
const submit = () => {
|
|
2259
|
+
onChange(values.map((s) => s.toString()));
|
|
2260
|
+
};
|
|
2261
|
+
const theme = useMantineTheme();
|
|
2262
|
+
const swatches = React.useMemo(() => {
|
|
2263
|
+
return Object.entries(theme.colors).map(([_color, profile]) => profile[6]);
|
|
2264
|
+
}, [theme]);
|
|
2265
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
2266
|
+
children: [/* @__PURE__ */ jsxs(Group, {
|
|
2267
|
+
position: "left",
|
|
2268
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2269
|
+
children: label
|
|
2270
|
+
}), /* @__PURE__ */ jsx(ActionIcon, {
|
|
2271
|
+
mr: 5,
|
|
2272
|
+
variant: "filled",
|
|
2273
|
+
color: "blue",
|
|
2274
|
+
disabled: !changed,
|
|
2275
|
+
onClick: submit,
|
|
2276
|
+
children: /* @__PURE__ */ jsx(DeviceFloppy, {
|
|
2277
|
+
size: 20
|
|
2278
|
+
})
|
|
2279
|
+
})]
|
|
2280
|
+
}), /* @__PURE__ */ jsxs(Group, {
|
|
2281
|
+
children: [values.map((v, i) => /* @__PURE__ */ jsx(ColorInput, {
|
|
2282
|
+
value: v,
|
|
2283
|
+
onChange: (color2) => {
|
|
2284
|
+
setValues((s) => {
|
|
2285
|
+
s.splice(i, 1, color2);
|
|
2286
|
+
return [...s];
|
|
2287
|
+
});
|
|
2288
|
+
},
|
|
2289
|
+
swatches,
|
|
2290
|
+
rightSection: /* @__PURE__ */ jsx(ActionIcon, {
|
|
2291
|
+
onClick: () => del(i),
|
|
2292
|
+
color: "red",
|
|
2293
|
+
children: /* @__PURE__ */ jsx(Trash, {
|
|
2294
|
+
size: 14
|
|
2295
|
+
})
|
|
2296
|
+
}),
|
|
2297
|
+
sx: {
|
|
2298
|
+
width: "45%"
|
|
2299
|
+
}
|
|
2300
|
+
})), /* @__PURE__ */ jsx(ActionIcon, {
|
|
2301
|
+
onClick: add,
|
|
2302
|
+
color: "blue",
|
|
2303
|
+
variant: "outline",
|
|
2304
|
+
children: /* @__PURE__ */ jsx(PlaylistAdd, {
|
|
2305
|
+
size: 20
|
|
2306
|
+
})
|
|
2307
|
+
})]
|
|
2308
|
+
})]
|
|
2309
|
+
});
|
|
2310
|
+
}
|
|
2311
|
+
function VizStatsPanel({
|
|
2312
|
+
conf,
|
|
2313
|
+
setConf
|
|
2314
|
+
}) {
|
|
2315
|
+
const defaultValues = _.merge({}, {
|
|
2316
|
+
align: "center",
|
|
2317
|
+
size: "100px",
|
|
2318
|
+
template: "",
|
|
2319
|
+
weight: "bold",
|
|
2320
|
+
color: {
|
|
2321
|
+
type: "static",
|
|
2322
|
+
staticColor: "red"
|
|
2323
|
+
}
|
|
2324
|
+
}, conf);
|
|
2325
|
+
const {
|
|
2326
|
+
control,
|
|
2327
|
+
handleSubmit,
|
|
2328
|
+
watch,
|
|
2329
|
+
formState: {
|
|
2330
|
+
isDirty
|
|
2331
|
+
}
|
|
2332
|
+
} = useForm({
|
|
2333
|
+
defaultValues
|
|
2334
|
+
});
|
|
2335
|
+
const colorType = watch("color.type");
|
|
2336
|
+
watch("color.valueField");
|
|
2337
|
+
return /* @__PURE__ */ jsx(Group, {
|
|
2338
|
+
direction: "column",
|
|
2339
|
+
mt: "md",
|
|
2340
|
+
spacing: "xs",
|
|
2341
|
+
grow: true,
|
|
2342
|
+
noWrap: true,
|
|
2343
|
+
children: /* @__PURE__ */ jsxs("form", {
|
|
2344
|
+
onSubmit: handleSubmit(setConf),
|
|
2345
|
+
children: [/* @__PURE__ */ jsxs(Group, {
|
|
2346
|
+
position: "left",
|
|
2347
|
+
py: "md",
|
|
2348
|
+
pl: "md",
|
|
2349
|
+
sx: {
|
|
2350
|
+
borderBottom: "1px solid #eee",
|
|
2351
|
+
background: "#efefef"
|
|
2352
|
+
},
|
|
2353
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2354
|
+
weight: 500,
|
|
2355
|
+
children: "Stats Configurations"
|
|
2356
|
+
}), /* @__PURE__ */ jsx(ActionIcon, {
|
|
2357
|
+
type: "submit",
|
|
2358
|
+
mr: 5,
|
|
2359
|
+
variant: "filled",
|
|
2360
|
+
color: "blue",
|
|
2361
|
+
disabled: !isDirty,
|
|
2362
|
+
children: /* @__PURE__ */ jsx(DeviceFloppy, {
|
|
2363
|
+
size: 20
|
|
2364
|
+
})
|
|
2365
|
+
})]
|
|
2366
|
+
}), /* @__PURE__ */ jsxs(Accordion, {
|
|
2367
|
+
offsetIcon: false,
|
|
2368
|
+
multiple: true,
|
|
2369
|
+
initialState: {
|
|
2370
|
+
0: true,
|
|
2371
|
+
2: true
|
|
2372
|
+
},
|
|
2373
|
+
children: [/* @__PURE__ */ jsx(Accordion.Item, {
|
|
2374
|
+
label: "Content",
|
|
2375
|
+
children: /* @__PURE__ */ jsx(Group, {
|
|
2376
|
+
direction: "column",
|
|
2377
|
+
grow: true,
|
|
2378
|
+
children: /* @__PURE__ */ jsx(Controller, {
|
|
2379
|
+
name: "template",
|
|
2380
|
+
control,
|
|
2381
|
+
render: ({
|
|
2382
|
+
field
|
|
2383
|
+
}) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
|
|
2384
|
+
placeholder: "Time: ${new Date().toISOString()}",
|
|
2385
|
+
label: "Content Template",
|
|
2386
|
+
required: true,
|
|
2387
|
+
sx: {
|
|
2388
|
+
flex: 1
|
|
2389
|
+
}
|
|
2390
|
+
}, field))
|
|
2391
|
+
})
|
|
2392
|
+
})
|
|
2393
|
+
}), /* @__PURE__ */ jsxs(Accordion.Item, {
|
|
2394
|
+
label: "Font",
|
|
2395
|
+
children: [/* @__PURE__ */ jsx(Group, {
|
|
2396
|
+
direction: "column",
|
|
2397
|
+
grow: true,
|
|
2398
|
+
children: /* @__PURE__ */ jsx(Controller, {
|
|
2399
|
+
name: "size",
|
|
2400
|
+
control,
|
|
2401
|
+
render: ({
|
|
2402
|
+
field
|
|
2403
|
+
}) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
|
|
2404
|
+
label: "Font Size",
|
|
2405
|
+
placeholder: "10px, 1em, 1rem, 100%...",
|
|
2406
|
+
sx: {
|
|
2407
|
+
flex: 1
|
|
2408
|
+
}
|
|
2409
|
+
}, field))
|
|
2410
|
+
})
|
|
2411
|
+
}), /* @__PURE__ */ jsx(Group, {
|
|
2412
|
+
position: "apart",
|
|
2413
|
+
grow: true,
|
|
2414
|
+
sx: {
|
|
2415
|
+
"> *": {
|
|
2416
|
+
flexGrow: 1,
|
|
2417
|
+
maxWidth: "100%"
|
|
2418
|
+
}
|
|
2419
|
+
},
|
|
2420
|
+
children: /* @__PURE__ */ jsx(Controller, {
|
|
2421
|
+
name: "weight",
|
|
2422
|
+
control,
|
|
2423
|
+
render: ({
|
|
2424
|
+
field
|
|
2425
|
+
}) => /* @__PURE__ */ jsx(MantineFontWeightSlider, __spreadValues({
|
|
2426
|
+
label: "Font Weight"
|
|
2427
|
+
}, field))
|
|
2428
|
+
})
|
|
2429
|
+
})]
|
|
2430
|
+
}), /* @__PURE__ */ jsx(Accordion.Item, {
|
|
2431
|
+
label: "Color",
|
|
2432
|
+
children: /* @__PURE__ */ jsxs(Group, {
|
|
2433
|
+
direction: "column",
|
|
2434
|
+
grow: true,
|
|
2435
|
+
children: [/* @__PURE__ */ jsx(Controller, {
|
|
2436
|
+
name: "color.type",
|
|
2437
|
+
control,
|
|
2438
|
+
render: ({
|
|
2439
|
+
field
|
|
2440
|
+
}) => /* @__PURE__ */ jsx(Select, __spreadValues({
|
|
2441
|
+
label: "Color Type",
|
|
2442
|
+
data: [{
|
|
2443
|
+
label: "Static Color",
|
|
2444
|
+
value: "static"
|
|
2445
|
+
}, {
|
|
2446
|
+
label: "Continuous Color",
|
|
2447
|
+
value: "continuous"
|
|
2448
|
+
}]
|
|
2449
|
+
}, field))
|
|
2450
|
+
}), colorType === "static" && /* @__PURE__ */ jsx(Controller, {
|
|
2451
|
+
name: "color.staticColor",
|
|
2452
|
+
control,
|
|
2453
|
+
render: ({
|
|
2454
|
+
field
|
|
2455
|
+
}) => /* @__PURE__ */ jsx(MantineColorSelector, __spreadValues({}, field))
|
|
2456
|
+
}), colorType === "continuous" && /* @__PURE__ */ jsxs(Fragment, {
|
|
2457
|
+
children: [/* @__PURE__ */ jsx(Controller, {
|
|
2458
|
+
name: "color.valueField",
|
|
2459
|
+
control,
|
|
2460
|
+
defaultValue: "",
|
|
2461
|
+
render: ({
|
|
2462
|
+
field
|
|
2463
|
+
}) => /* @__PURE__ */ jsx(TextInput, __spreadValues({
|
|
2464
|
+
placeholder: "Calculate color with this field",
|
|
2465
|
+
label: "Value Field",
|
|
2466
|
+
required: true,
|
|
2467
|
+
sx: {
|
|
2468
|
+
flex: 1
|
|
2469
|
+
}
|
|
2470
|
+
}, field))
|
|
2471
|
+
}), /* @__PURE__ */ jsx(Controller, {
|
|
2472
|
+
name: "color.valueRange",
|
|
2473
|
+
control,
|
|
2474
|
+
render: ({
|
|
2475
|
+
field
|
|
2476
|
+
}) => /* @__PURE__ */ jsx(TextArrayInput, __spreadValues({
|
|
2477
|
+
label: "Value Range"
|
|
2478
|
+
}, field))
|
|
2479
|
+
}), /* @__PURE__ */ jsx(Controller, {
|
|
2480
|
+
name: "color.colorRange",
|
|
2481
|
+
control,
|
|
2482
|
+
render: ({
|
|
2483
|
+
field
|
|
2484
|
+
}) => /* @__PURE__ */ jsx(ColorArrayInput, __spreadValues({
|
|
2485
|
+
label: "Color Range"
|
|
2486
|
+
}, field))
|
|
2487
|
+
})]
|
|
2488
|
+
})]
|
|
2489
|
+
})
|
|
2490
|
+
})]
|
|
2491
|
+
})]
|
|
2492
|
+
})
|
|
2493
|
+
});
|
|
2494
|
+
}
|
|
1687
2495
|
function SunburstPanel({
|
|
1688
2496
|
conf: {
|
|
1689
2497
|
label_field,
|
|
@@ -1768,22 +2576,22 @@ function ValueTypeSelector({
|
|
|
1768
2576
|
sx
|
|
1769
2577
|
});
|
|
1770
2578
|
}
|
|
1771
|
-
function VizTablePanel(
|
|
1772
|
-
var
|
|
1773
|
-
conf:
|
|
1774
|
-
} =
|
|
2579
|
+
function VizTablePanel(_e) {
|
|
2580
|
+
var _f = _e, {
|
|
2581
|
+
conf: _g
|
|
2582
|
+
} = _f, _h = _g, {
|
|
1775
2583
|
columns
|
|
1776
|
-
} =
|
|
2584
|
+
} = _h, restConf = __objRest(_h, [
|
|
1777
2585
|
"columns"
|
|
1778
2586
|
]), {
|
|
1779
2587
|
setConf
|
|
1780
|
-
} =
|
|
2588
|
+
} = _f;
|
|
1781
2589
|
const form = useForm$1({
|
|
1782
2590
|
initialValues: __spreadValues({
|
|
1783
2591
|
id_field: "id",
|
|
1784
2592
|
use_raw_columns: true,
|
|
1785
2593
|
columns: formList(columns != null ? columns : []),
|
|
1786
|
-
|
|
2594
|
+
fontSize: "sm",
|
|
1787
2595
|
horizontalSpacing: "sm",
|
|
1788
2596
|
verticalSpacing: "sm",
|
|
1789
2597
|
striped: false,
|
|
@@ -1874,7 +2682,7 @@ function VizTablePanel(_a) {
|
|
|
1874
2682
|
sx: {
|
|
1875
2683
|
flex: 1
|
|
1876
2684
|
}
|
|
1877
|
-
}, form.getInputProps("
|
|
2685
|
+
}, form.getInputProps("fontSize")))
|
|
1878
2686
|
}), /* @__PURE__ */ jsxs(Group, {
|
|
1879
2687
|
direction: "column",
|
|
1880
2688
|
grow: true,
|
|
@@ -1989,52 +2797,6 @@ function VizTablePanel(_a) {
|
|
|
1989
2797
|
})
|
|
1990
2798
|
});
|
|
1991
2799
|
}
|
|
1992
|
-
const marks = [{
|
|
1993
|
-
label: "initial",
|
|
1994
|
-
value: 0
|
|
1995
|
-
}, {
|
|
1996
|
-
label: "500",
|
|
1997
|
-
value: 25
|
|
1998
|
-
}, {
|
|
1999
|
-
label: "700",
|
|
2000
|
-
value: 50
|
|
2001
|
-
}, {
|
|
2002
|
-
label: "semibold",
|
|
2003
|
-
value: 75
|
|
2004
|
-
}, {
|
|
2005
|
-
label: "bold",
|
|
2006
|
-
value: 100
|
|
2007
|
-
}];
|
|
2008
|
-
function MantineFontWeightSlider({
|
|
2009
|
-
label,
|
|
2010
|
-
value,
|
|
2011
|
-
onChange
|
|
2012
|
-
}) {
|
|
2013
|
-
var _a, _b;
|
|
2014
|
-
const [mark, setMark] = React.useState((_b = (_a = marks.find((m2) => m2.label === value)) == null ? void 0 : _a.value) != null ? _b : marks[0].value);
|
|
2015
|
-
React.useEffect(() => {
|
|
2016
|
-
const match = marks.find((s) => s.value === mark);
|
|
2017
|
-
if (match) {
|
|
2018
|
-
onChange(match.label);
|
|
2019
|
-
}
|
|
2020
|
-
}, [mark]);
|
|
2021
|
-
return /* @__PURE__ */ jsxs(Group, {
|
|
2022
|
-
direction: "column",
|
|
2023
|
-
grow: true,
|
|
2024
|
-
spacing: "xs",
|
|
2025
|
-
mb: "lg",
|
|
2026
|
-
children: [/* @__PURE__ */ jsx(Text, {
|
|
2027
|
-
children: label
|
|
2028
|
-
}), /* @__PURE__ */ jsx(Slider, {
|
|
2029
|
-
label: null,
|
|
2030
|
-
marks,
|
|
2031
|
-
value: mark,
|
|
2032
|
-
onChange: setMark,
|
|
2033
|
-
step: 25,
|
|
2034
|
-
placeholder: "Pick a font size"
|
|
2035
|
-
})]
|
|
2036
|
-
});
|
|
2037
|
-
}
|
|
2038
2800
|
const sampleParagraphs = [{
|
|
2039
2801
|
align: "center",
|
|
2040
2802
|
size: "xl",
|
|
@@ -2174,6 +2936,10 @@ const types = [{
|
|
|
2174
2936
|
value: "text",
|
|
2175
2937
|
label: "Text",
|
|
2176
2938
|
Panel: VizTextPanel
|
|
2939
|
+
}, {
|
|
2940
|
+
value: "stats",
|
|
2941
|
+
label: "Stats",
|
|
2942
|
+
Panel: VizStatsPanel
|
|
2177
2943
|
}, {
|
|
2178
2944
|
value: "table",
|
|
2179
2945
|
label: "Table",
|
|
@@ -2323,7 +3089,8 @@ function PanelSettingsModal({
|
|
|
2323
3089
|
children: [/* @__PURE__ */ jsxs(Tabs.Tab, {
|
|
2324
3090
|
label: "Data Source",
|
|
2325
3091
|
children: [/* @__PURE__ */ jsx(LoadingOverlay, {
|
|
2326
|
-
visible: loading
|
|
3092
|
+
visible: loading,
|
|
3093
|
+
exitTransitionDuration: 0
|
|
2327
3094
|
}), /* @__PURE__ */ jsx(PickDataSource, {})]
|
|
2328
3095
|
}), /* @__PURE__ */ jsx(Tabs.Tab, {
|
|
2329
3096
|
label: "Panel",
|
|
@@ -2561,10 +3328,15 @@ function ModeToggler({
|
|
|
2561
3328
|
size: 20
|
|
2562
3329
|
}), "Use"),
|
|
2563
3330
|
value: DashboardMode.Use
|
|
3331
|
+
}, {
|
|
3332
|
+
label: renderLabel(/* @__PURE__ */ jsx(Resize, {
|
|
3333
|
+
size: 20
|
|
3334
|
+
}), "Layout"),
|
|
3335
|
+
value: DashboardMode.Layout
|
|
2564
3336
|
}, {
|
|
2565
3337
|
label: renderLabel(/* @__PURE__ */ jsx(Paint, {
|
|
2566
3338
|
size: 20
|
|
2567
|
-
}), "
|
|
3339
|
+
}), "Content"),
|
|
2568
3340
|
value: DashboardMode.Edit
|
|
2569
3341
|
}]
|
|
2570
3342
|
});
|
|
@@ -2773,7 +3545,8 @@ function DataSourceForm({
|
|
|
2773
3545
|
});
|
|
2774
3546
|
}
|
|
2775
3547
|
function DataSourceEditor({
|
|
2776
|
-
id
|
|
3548
|
+
id,
|
|
3549
|
+
setID
|
|
2777
3550
|
}) {
|
|
2778
3551
|
const {
|
|
2779
3552
|
dataSources,
|
|
@@ -2784,7 +3557,7 @@ function DataSourceEditor({
|
|
|
2784
3557
|
}, [dataSources, id]);
|
|
2785
3558
|
const update = React.useCallback((value) => {
|
|
2786
3559
|
const index2 = dataSources.findIndex((d) => d.id === id);
|
|
2787
|
-
if (
|
|
3560
|
+
if (index2 === -1) {
|
|
2788
3561
|
console.error(new Error("Invalid data source id when updating by id"));
|
|
2789
3562
|
return;
|
|
2790
3563
|
}
|
|
@@ -2793,7 +3566,11 @@ function DataSourceEditor({
|
|
|
2793
3566
|
prevs.splice(index22, 1, value);
|
|
2794
3567
|
return [...prevs];
|
|
2795
3568
|
});
|
|
2796
|
-
|
|
3569
|
+
setID(value.id);
|
|
3570
|
+
}, [id, dataSources, setDataSources, setID]);
|
|
3571
|
+
if (!id) {
|
|
3572
|
+
return null;
|
|
3573
|
+
}
|
|
2797
3574
|
if (!dataSource) {
|
|
2798
3575
|
return /* @__PURE__ */ jsx("span", {
|
|
2799
3576
|
children: "Invalid Data Source ID"
|
|
@@ -2922,7 +3699,8 @@ function EditDataSourcesModal({
|
|
|
2922
3699
|
setID
|
|
2923
3700
|
}),
|
|
2924
3701
|
children: [/* @__PURE__ */ jsx(DataSourceEditor, {
|
|
2925
|
-
id
|
|
3702
|
+
id,
|
|
3703
|
+
setID
|
|
2926
3704
|
}), /* @__PURE__ */ jsx(DataPreview, {
|
|
2927
3705
|
id
|
|
2928
3706
|
})]
|
|
@@ -3015,46 +3793,48 @@ WHERE \${author_time_condition}`;
|
|
|
3015
3793
|
}) => {
|
|
3016
3794
|
setSQLSnippets(snippets);
|
|
3017
3795
|
};
|
|
3018
|
-
return /* @__PURE__ */
|
|
3796
|
+
return /* @__PURE__ */ jsx(Group, {
|
|
3019
3797
|
direction: "column",
|
|
3020
3798
|
grow: true,
|
|
3021
3799
|
sx: {
|
|
3022
3800
|
border: "1px solid #eee"
|
|
3023
3801
|
},
|
|
3024
|
-
children:
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
background: "#efefef",
|
|
3031
|
-
flexGrow: 0
|
|
3032
|
-
},
|
|
3033
|
-
children: [/* @__PURE__ */ jsx(Text, {
|
|
3034
|
-
weight: 500,
|
|
3035
|
-
children: "SQL Snippets"
|
|
3036
|
-
}), /* @__PURE__ */ jsx(ActionIcon, {
|
|
3037
|
-
type: "submit",
|
|
3038
|
-
mr: 5,
|
|
3039
|
-
variant: "filled",
|
|
3040
|
-
color: "blue",
|
|
3041
|
-
disabled: !changed,
|
|
3042
|
-
children: /* @__PURE__ */ jsx(DeviceFloppy, {
|
|
3043
|
-
size: 20
|
|
3044
|
-
})
|
|
3045
|
-
})]
|
|
3046
|
-
}), /* @__PURE__ */ jsxs(Group, {
|
|
3047
|
-
px: "md",
|
|
3048
|
-
pb: "md",
|
|
3049
|
-
children: [/* @__PURE__ */ jsx(Prism, {
|
|
3050
|
-
language: "sql",
|
|
3802
|
+
children: /* @__PURE__ */ jsxs("form", {
|
|
3803
|
+
onSubmit: form.onSubmit(submit),
|
|
3804
|
+
children: [/* @__PURE__ */ jsxs(Group, {
|
|
3805
|
+
position: "left",
|
|
3806
|
+
pl: "md",
|
|
3807
|
+
py: "md",
|
|
3051
3808
|
sx: {
|
|
3052
|
-
|
|
3809
|
+
borderBottom: "1px solid #eee",
|
|
3810
|
+
background: "#efefef",
|
|
3811
|
+
flexGrow: 0
|
|
3053
3812
|
},
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3813
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
3814
|
+
weight: 500,
|
|
3815
|
+
children: "SQL Snippets"
|
|
3816
|
+
}), /* @__PURE__ */ jsx(ActionIcon, {
|
|
3817
|
+
type: "submit",
|
|
3818
|
+
mr: 5,
|
|
3819
|
+
variant: "filled",
|
|
3820
|
+
color: "blue",
|
|
3821
|
+
disabled: !changed,
|
|
3822
|
+
children: /* @__PURE__ */ jsx(DeviceFloppy, {
|
|
3823
|
+
size: 20
|
|
3824
|
+
})
|
|
3825
|
+
})]
|
|
3826
|
+
}), /* @__PURE__ */ jsxs(Group, {
|
|
3827
|
+
px: "md",
|
|
3828
|
+
pb: "md",
|
|
3829
|
+
children: [/* @__PURE__ */ jsx(Prism, {
|
|
3830
|
+
language: "sql",
|
|
3831
|
+
sx: {
|
|
3832
|
+
width: "100%"
|
|
3833
|
+
},
|
|
3834
|
+
noCopy: true,
|
|
3835
|
+
trim: false,
|
|
3836
|
+
colorScheme: "dark",
|
|
3837
|
+
children: `-- You may refer context data *by name*
|
|
3058
3838
|
-- in SQL or VizConfig.
|
|
3059
3839
|
|
|
3060
3840
|
${sampleSQL}
|
|
@@ -3062,15 +3842,13 @@ ${sampleSQL}
|
|
|
3062
3842
|
-- where author_time_condition is:
|
|
3063
3843
|
author_time BETWEEN '\${timeRange?.[0].toISOString()}' AND '\${timeRange?.[1].toISOString()}'
|
|
3064
3844
|
`
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
children: /* @__PURE__ */ jsxs("form", {
|
|
3073
|
-
onSubmit: form.onSubmit(submit),
|
|
3845
|
+
}), /* @__PURE__ */ jsxs(Group, {
|
|
3846
|
+
direction: "column",
|
|
3847
|
+
sx: {
|
|
3848
|
+
width: "100%",
|
|
3849
|
+
position: "relative"
|
|
3850
|
+
},
|
|
3851
|
+
grow: true,
|
|
3074
3852
|
children: [form.values.snippets.map((_item, index2) => /* @__PURE__ */ jsxs(Group, {
|
|
3075
3853
|
direction: "column",
|
|
3076
3854
|
grow: true,
|
|
@@ -3115,9 +3893,9 @@ author_time BETWEEN '\${timeRange?.[0].toISOString()}' AND '\${timeRange?.[1].to
|
|
|
3115
3893
|
children: "Add a snippet"
|
|
3116
3894
|
})
|
|
3117
3895
|
})]
|
|
3118
|
-
})
|
|
3896
|
+
})]
|
|
3119
3897
|
})]
|
|
3120
|
-
})
|
|
3898
|
+
})
|
|
3121
3899
|
});
|
|
3122
3900
|
}
|
|
3123
3901
|
function EditSQLSnippetsModal({
|
|
@@ -3173,13 +3951,17 @@ function DashboardActions({
|
|
|
3173
3951
|
addPanel,
|
|
3174
3952
|
saveChanges
|
|
3175
3953
|
}) {
|
|
3954
|
+
const {
|
|
3955
|
+
inLayoutMode,
|
|
3956
|
+
inEditMode,
|
|
3957
|
+
inUseMode
|
|
3958
|
+
} = React.useContext(LayoutStateContext);
|
|
3176
3959
|
const [dataSourcesOpened, setDataSourcesOpened] = React.useState(false);
|
|
3177
3960
|
const openDataSources = () => setDataSourcesOpened(true);
|
|
3178
3961
|
const closeDataSources = () => setDataSourcesOpened(false);
|
|
3179
3962
|
const [sqlSnippetsOpened, setSQLSnippetsOpened] = React.useState(false);
|
|
3180
3963
|
const openSQLSnippets = () => setSQLSnippetsOpened(true);
|
|
3181
3964
|
const closeSQLSnippets = () => setSQLSnippetsOpened(false);
|
|
3182
|
-
const inEditMode = mode === DashboardMode.Edit;
|
|
3183
3965
|
return /* @__PURE__ */ jsxs(Group, {
|
|
3184
3966
|
position: "apart",
|
|
3185
3967
|
pt: "sm",
|
|
@@ -3190,59 +3972,57 @@ function DashboardActions({
|
|
|
3190
3972
|
mode,
|
|
3191
3973
|
setMode
|
|
3192
3974
|
})
|
|
3193
|
-
}),
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
children: "Revert Changes"
|
|
3237
|
-
})]
|
|
3238
|
-
}), /* @__PURE__ */ jsx(EditDataSourcesModal, {
|
|
3239
|
-
opened: dataSourcesOpened,
|
|
3240
|
-
close: closeDataSources
|
|
3241
|
-
}), /* @__PURE__ */ jsx(EditSQLSnippetsModal, {
|
|
3242
|
-
opened: sqlSnippetsOpened,
|
|
3243
|
-
close: closeSQLSnippets
|
|
3975
|
+
}), /* @__PURE__ */ jsxs(Group, {
|
|
3976
|
+
position: "right",
|
|
3977
|
+
children: [inLayoutMode && /* @__PURE__ */ jsx(Button, {
|
|
3978
|
+
variant: "default",
|
|
3979
|
+
size: "sm",
|
|
3980
|
+
onClick: addPanel,
|
|
3981
|
+
leftIcon: /* @__PURE__ */ jsx(PlaylistAdd, {
|
|
3982
|
+
size: 20
|
|
3983
|
+
}),
|
|
3984
|
+
children: "Add a Panel"
|
|
3985
|
+
}), inEditMode && /* @__PURE__ */ jsx(Button, {
|
|
3986
|
+
variant: "default",
|
|
3987
|
+
size: "sm",
|
|
3988
|
+
onClick: openSQLSnippets,
|
|
3989
|
+
leftIcon: /* @__PURE__ */ jsx(ClipboardText, {
|
|
3990
|
+
size: 20
|
|
3991
|
+
}),
|
|
3992
|
+
children: "SQL Snippets"
|
|
3993
|
+
}), inEditMode && /* @__PURE__ */ jsx(Button, {
|
|
3994
|
+
variant: "default",
|
|
3995
|
+
size: "sm",
|
|
3996
|
+
onClick: openDataSources,
|
|
3997
|
+
leftIcon: /* @__PURE__ */ jsx(Database, {
|
|
3998
|
+
size: 20
|
|
3999
|
+
}),
|
|
4000
|
+
children: "Data Sources"
|
|
4001
|
+
}), !inUseMode && /* @__PURE__ */ jsx(Button, {
|
|
4002
|
+
variant: "default",
|
|
4003
|
+
size: "sm",
|
|
4004
|
+
onClick: saveChanges,
|
|
4005
|
+
disabled: !hasChanges,
|
|
4006
|
+
leftIcon: /* @__PURE__ */ jsx(DeviceFloppy, {
|
|
4007
|
+
size: 20
|
|
4008
|
+
}),
|
|
4009
|
+
children: "Save Changes"
|
|
4010
|
+
}), !inUseMode && /* @__PURE__ */ jsx(Button, {
|
|
4011
|
+
color: "red",
|
|
4012
|
+
size: "sm",
|
|
4013
|
+
disabled: !hasChanges,
|
|
4014
|
+
leftIcon: /* @__PURE__ */ jsx(Recycle, {
|
|
4015
|
+
size: 20
|
|
4016
|
+
}),
|
|
4017
|
+
children: "Revert Changes"
|
|
3244
4018
|
})]
|
|
3245
|
-
}),
|
|
4019
|
+
}), /* @__PURE__ */ jsx(EditDataSourcesModal, {
|
|
4020
|
+
opened: dataSourcesOpened,
|
|
4021
|
+
close: closeDataSources
|
|
4022
|
+
}), /* @__PURE__ */ jsx(EditSQLSnippetsModal, {
|
|
4023
|
+
opened: sqlSnippetsOpened,
|
|
4024
|
+
close: closeSQLSnippets
|
|
4025
|
+
}), inUseMode && /* @__PURE__ */ jsx(Button, {
|
|
3246
4026
|
variant: "default",
|
|
3247
4027
|
size: "sm",
|
|
3248
4028
|
disabled: true,
|
|
@@ -3316,6 +4096,8 @@ function Dashboard({
|
|
|
3316
4096
|
});
|
|
3317
4097
|
};
|
|
3318
4098
|
const inEditMode = mode === DashboardMode.Edit;
|
|
4099
|
+
const inLayoutMode = mode === DashboardMode.Layout;
|
|
4100
|
+
const inUseMode = mode === DashboardMode.Use;
|
|
3319
4101
|
const definitions = React.useMemo(() => ({
|
|
3320
4102
|
sqlSnippets,
|
|
3321
4103
|
setSQLSnippets,
|
|
@@ -3333,7 +4115,9 @@ function Dashboard({
|
|
|
3333
4115
|
layoutFrozen,
|
|
3334
4116
|
freezeLayout,
|
|
3335
4117
|
mode,
|
|
3336
|
-
inEditMode
|
|
4118
|
+
inEditMode,
|
|
4119
|
+
inLayoutMode,
|
|
4120
|
+
inUseMode
|
|
3337
4121
|
},
|
|
3338
4122
|
children: [/* @__PURE__ */ jsx(DashboardActions, {
|
|
3339
4123
|
mode,
|
|
@@ -3344,8 +4128,8 @@ function Dashboard({
|
|
|
3344
4128
|
}), /* @__PURE__ */ jsx(DashboardLayout, {
|
|
3345
4129
|
panels,
|
|
3346
4130
|
setPanels,
|
|
3347
|
-
isDraggable:
|
|
3348
|
-
isResizable:
|
|
4131
|
+
isDraggable: inLayoutMode,
|
|
4132
|
+
isResizable: inLayoutMode,
|
|
3349
4133
|
onRemoveItem: removePanelByID,
|
|
3350
4134
|
setLocalCols,
|
|
3351
4135
|
setBreakpoint
|
|
@@ -3412,7 +4196,9 @@ function ReadOnlyDashboard({
|
|
|
3412
4196
|
freezeLayout: () => {
|
|
3413
4197
|
},
|
|
3414
4198
|
mode: DashboardMode.Use,
|
|
3415
|
-
inEditMode: false
|
|
4199
|
+
inEditMode: false,
|
|
4200
|
+
inLayoutMode: false,
|
|
4201
|
+
inUseMode: true
|
|
3416
4202
|
},
|
|
3417
4203
|
children: /* @__PURE__ */ jsx(ReadOnlyDashboardLayout, {
|
|
3418
4204
|
panels: dashboard.panels
|