@bluemarble/bi 0.1.0 → 0.1.2
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/{DashboardDevtools-ByrFb6HT.js → DashboardDevtools-DLhEr3fN.js} +307 -184
- package/dist/DashboardDevtools-DLhEr3fN.js.map +1 -0
- package/dist/{ModelDictionary-AjNbffwG.js → ModelDictionary-DU6i_QSn.js} +2 -2
- package/dist/{ModelDictionary-AjNbffwG.js.map → ModelDictionary-DU6i_QSn.js.map} +1 -1
- package/dist/client/index.js +1 -1
- package/package.json +2 -2
- package/dist/DashboardDevtools-ByrFb6HT.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as validateModel, D as parseColumnRef, E as modelEdges, T as measureHome, _ as AGGREGATIONS, a as FILTER_FIELDS, c as chartReferences, d as layoutModelWarnings, f as validateLayout, g as toModelCode, i as CHART_TYPE_LABEL, k as referencedTables, l as filterReferences, n as CHART_FIELDS, o as chartColumns, p as canonicalJson, r as CHART_TYPES, s as chartOfType, t as CANVAS_PRESETS, u as layoutFileContent, v as AGGREGATION_LABEL, x as isAggregate, y as VALUE_FORMATS } from "./layout-iPByu6V0.js";
|
|
2
2
|
import { n as diffRows } from "./compare-DloZhg1T.js";
|
|
3
|
-
import { a as useDashboard, c as layoutItemKey, l as parseLayoutItemKey, n as INSPECT_ATTRIBUTE, o as errorMessage, s as LAYOUT_ITEM_ATTRIBUTE, t as ModelDictionary } from "./ModelDictionary-
|
|
3
|
+
import { a as useDashboard, c as layoutItemKey, l as parseLayoutItemKey, n as INSPECT_ATTRIBUTE, o as errorMessage, s as LAYOUT_ITEM_ATTRIBUTE, t as ModelDictionary } from "./ModelDictionary-DU6i_QSn.js";
|
|
4
4
|
import { Alert, Autocomplete, Box, Button, Checkbox, Chip, CircularProgress, Collapse, Dialog, DialogActions, DialogContent, DialogTitle, Divider, FormControlLabel, IconButton, List, ListItemButton, Menu, MenuItem, MenuList, Paper, Popper, Portal, Tab, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tabs, TextField, ThemeProvider, ToggleButton, ToggleButtonGroup, Tooltip, Typography, createTheme } from "@mui/material";
|
|
5
5
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -660,6 +660,35 @@ const inputSx$1 = { "& .MuiInputBase-input": {
|
|
|
660
660
|
} };
|
|
661
661
|
const itemElement = (layoutId, item) => document.querySelector(`[${LAYOUT_ITEM_ATTRIBUTE}="${CSS.escape(layoutItemKey(layoutId, item))}"]`);
|
|
662
662
|
const itemQueryId = (layoutId, item) => itemElement(layoutId, item)?.querySelector(`[data-bm-dashboard-query]`)?.getAttribute("data-bm-dashboard-query") ?? null;
|
|
663
|
+
const SIDEBAR_KEY = "bm-dashboard-devtools:layout-sidebar";
|
|
664
|
+
/** Abaixo disso a lista vai para cima do formulário, em vez de ficar ao lado. */
|
|
665
|
+
const STACK_WIDTH = 640;
|
|
666
|
+
function loadSidebar() {
|
|
667
|
+
try {
|
|
668
|
+
return localStorage.getItem(SIDEBAR_KEY) !== "closed";
|
|
669
|
+
} catch {
|
|
670
|
+
return true;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
/** Largura do elemento, acompanhando o redimensionamento do devtools. */
|
|
674
|
+
function useWidth() {
|
|
675
|
+
const [element, setElement] = useState(null);
|
|
676
|
+
const [width, setWidth] = useState(Number.POSITIVE_INFINITY);
|
|
677
|
+
useEffect(() => {
|
|
678
|
+
if (!element) return;
|
|
679
|
+
const observer = new ResizeObserver(([entry]) => entry && setWidth(entry.contentRect.width));
|
|
680
|
+
observer.observe(element);
|
|
681
|
+
return () => observer.disconnect();
|
|
682
|
+
}, [element]);
|
|
683
|
+
return [setElement, width];
|
|
684
|
+
}
|
|
685
|
+
/** Move o item `from` para antes da posição `to` (`to === list.length` = fim). */
|
|
686
|
+
function moveTo(list, from, to) {
|
|
687
|
+
const next = [...list];
|
|
688
|
+
const [item] = next.splice(from, 1);
|
|
689
|
+
next.splice(to > from ? to - 1 : to, 0, item);
|
|
690
|
+
return next;
|
|
691
|
+
}
|
|
663
692
|
const uniqueId = (charts, base) => {
|
|
664
693
|
const ids = new Set(charts.map((chart) => chart.id));
|
|
665
694
|
if (!ids.has(base)) return base;
|
|
@@ -726,6 +755,10 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
726
755
|
const reference = entry ? entry.draft ?? entry.registered : null;
|
|
727
756
|
const [editing, setEditing] = useState(reference);
|
|
728
757
|
const [selection, setSelection] = useState(null);
|
|
758
|
+
const [sidebar, setSidebar] = useState(loadSidebar);
|
|
759
|
+
const [drag, setDrag] = useState(null);
|
|
760
|
+
const [rootRef, rootWidth] = useWidth();
|
|
761
|
+
const [editorRef, editorWidth] = useWidth();
|
|
729
762
|
const [busy, setBusy] = useState(false);
|
|
730
763
|
const [actionError, setActionError] = useState(null);
|
|
731
764
|
const [save, setSave] = useState(null);
|
|
@@ -768,7 +801,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
768
801
|
const charts = editing.charts;
|
|
769
802
|
const filters = editing.filters ?? [];
|
|
770
803
|
const selectedFilter = selection?.kind === "filter" ? filters.find((filter) => filter.dimension === selection.key) ?? null : null;
|
|
771
|
-
const selected =
|
|
804
|
+
const selected = selection?.kind === "filter" || selection?.kind === "canvas" ? null : charts.find((chart) => chart.id === selection?.key) ?? charts[0] ?? null;
|
|
772
805
|
const layoutKey = entry.registered.id;
|
|
773
806
|
const differsFromFile = canonicalJson(editing) !== canonicalJson(entry.registered);
|
|
774
807
|
const update = (next) => {
|
|
@@ -790,21 +823,39 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
790
823
|
filters: next
|
|
791
824
|
});
|
|
792
825
|
const patchFilter = (dimension, change) => setFilters(filters.map((filter) => filter.dimension === dimension ? change(filter) : filter));
|
|
793
|
-
const
|
|
794
|
-
const
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
};
|
|
800
|
-
const move = (index, delta) => {
|
|
801
|
-
const next = swap(charts, index, delta);
|
|
802
|
-
if (next) setCharts(next);
|
|
803
|
-
};
|
|
804
|
-
const moveFilter = (index, delta) => {
|
|
805
|
-
const next = swap(filters, index, delta);
|
|
806
|
-
if (next) setFilters(next);
|
|
826
|
+
const toggleSidebar = () => {
|
|
827
|
+
const next = !sidebar;
|
|
828
|
+
setSidebar(next);
|
|
829
|
+
try {
|
|
830
|
+
localStorage.setItem(SIDEBAR_KEY, next ? "open" : "closed");
|
|
831
|
+
} catch {}
|
|
807
832
|
};
|
|
833
|
+
const dragProps = (kind, index, length) => ({
|
|
834
|
+
dropBefore: drag?.kind === kind && drag.from !== index && drag.to === index,
|
|
835
|
+
dropAfter: drag?.kind === kind && index === length - 1 && drag.to === length,
|
|
836
|
+
onDragStart: () => setDrag({
|
|
837
|
+
kind,
|
|
838
|
+
from: index,
|
|
839
|
+
to: index
|
|
840
|
+
}),
|
|
841
|
+
onDragOver: (e) => {
|
|
842
|
+
if (drag?.kind !== kind) return;
|
|
843
|
+
e.preventDefault();
|
|
844
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
845
|
+
const to = e.clientY < rect.top + rect.height / 2 ? index : index + 1;
|
|
846
|
+
if (to !== drag.to) setDrag({
|
|
847
|
+
...drag,
|
|
848
|
+
to
|
|
849
|
+
});
|
|
850
|
+
},
|
|
851
|
+
onDrop: () => {
|
|
852
|
+
if (drag?.kind !== kind) return;
|
|
853
|
+
if (drag.to !== drag.from && drag.to !== drag.from + 1) if (kind === "chart") setCharts(moveTo(charts, drag.from, drag.to));
|
|
854
|
+
else setFilters(moveTo(filters, drag.from, drag.to));
|
|
855
|
+
setDrag(null);
|
|
856
|
+
},
|
|
857
|
+
onDragEnd: () => setDrag(null)
|
|
858
|
+
});
|
|
808
859
|
const addFilter = () => {
|
|
809
860
|
const used = new Set(filters.map((filter) => filter.dimension));
|
|
810
861
|
const dimension = Object.keys(model.dimensions).find((name) => !used.has(name));
|
|
@@ -817,11 +868,15 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
817
868
|
};
|
|
818
869
|
const focus = (item) => {
|
|
819
870
|
setSelection(item);
|
|
871
|
+
if (stacked) setSidebar(false);
|
|
820
872
|
itemElement(layoutKey, item)?.scrollIntoView({
|
|
821
873
|
behavior: "smooth",
|
|
822
874
|
block: "center"
|
|
823
875
|
});
|
|
824
876
|
};
|
|
877
|
+
const stacked = rootWidth < STACK_WIDTH;
|
|
878
|
+
const formColumns = editorWidth < 420 ? 1 : editorWidth < 720 ? 2 : 4;
|
|
879
|
+
const selectedTitle = selection?.kind === "canvas" ? "Tela" : selectedFilter ? selectedFilter.label || model.dimensions[selectedFilter.dimension]?.label || selectedFilter.dimension : selected ? selected.title || selected.id : "";
|
|
825
880
|
const hover = (item) => onHover(item && itemQueryId(layoutKey, item));
|
|
826
881
|
const add = (type, base) => {
|
|
827
882
|
setAddMenu(null);
|
|
@@ -864,6 +919,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
864
919
|
}
|
|
865
920
|
};
|
|
866
921
|
return /* @__PURE__ */ jsxs(Box, {
|
|
922
|
+
ref: rootRef,
|
|
867
923
|
sx: {
|
|
868
924
|
display: "flex",
|
|
869
925
|
flexDirection: "column",
|
|
@@ -871,19 +927,45 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
871
927
|
minHeight: 0
|
|
872
928
|
},
|
|
873
929
|
children: [
|
|
930
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
931
|
+
sx: {
|
|
932
|
+
display: "flex",
|
|
933
|
+
alignItems: "center",
|
|
934
|
+
gap: 1,
|
|
935
|
+
px: 1,
|
|
936
|
+
py: .5,
|
|
937
|
+
borderBottom: 1,
|
|
938
|
+
borderColor: "divider"
|
|
939
|
+
},
|
|
940
|
+
children: [/* @__PURE__ */ jsx(SmallButton, {
|
|
941
|
+
title: sidebar ? "Recolher a lista" : "Mostrar a lista",
|
|
942
|
+
onClick: toggleSidebar,
|
|
943
|
+
children: sidebar ? "«" : "☰"
|
|
944
|
+
}), /* @__PURE__ */ jsx(Typography, {
|
|
945
|
+
noWrap: true,
|
|
946
|
+
sx: {
|
|
947
|
+
fontSize: 12,
|
|
948
|
+
fontWeight: 700
|
|
949
|
+
},
|
|
950
|
+
children: stacked && sidebar ? `Layout ${layoutKey}` : selectedTitle
|
|
951
|
+
})]
|
|
952
|
+
}),
|
|
874
953
|
/* @__PURE__ */ jsxs(Box, {
|
|
875
954
|
sx: {
|
|
876
955
|
flex: 1,
|
|
877
956
|
minHeight: 0,
|
|
878
|
-
display: "
|
|
879
|
-
gridTemplateColumns: "280px 1fr"
|
|
957
|
+
display: "flex"
|
|
880
958
|
},
|
|
881
|
-
children: [/* @__PURE__ */ jsxs(Box, {
|
|
959
|
+
children: [sidebar && /* @__PURE__ */ jsxs(Box, {
|
|
882
960
|
sx: {
|
|
883
|
-
borderRight: 1,
|
|
884
|
-
borderColor: "divider",
|
|
885
961
|
overflow: "auto",
|
|
886
|
-
p: 1.5
|
|
962
|
+
p: 1.5,
|
|
963
|
+
...stacked ? { flex: 1 } : {
|
|
964
|
+
width: 280,
|
|
965
|
+
flexShrink: 0,
|
|
966
|
+
borderRight: 1,
|
|
967
|
+
borderColor: "divider"
|
|
968
|
+
}
|
|
887
969
|
},
|
|
888
970
|
children: [
|
|
889
971
|
entries.length > 1 && /* @__PURE__ */ jsx(TextField, {
|
|
@@ -902,9 +984,17 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
902
984
|
children: [item.registered.id, item.draft ? " · rascunho" : ""]
|
|
903
985
|
}, item.registered.id))
|
|
904
986
|
}),
|
|
905
|
-
/* @__PURE__ */ jsx(
|
|
906
|
-
|
|
907
|
-
|
|
987
|
+
/* @__PURE__ */ jsx(Section, {
|
|
988
|
+
title: "Tela",
|
|
989
|
+
children: /* @__PURE__ */ jsx(ItemRow, {
|
|
990
|
+
title: editing.canvas ? "Tamanho fixo" : "Responsiva",
|
|
991
|
+
subtitle: editing.canvas ? presetLabel(editing.canvas) : "reorganiza conforme a largura",
|
|
992
|
+
selected: selection?.kind === "canvas",
|
|
993
|
+
onSelect: () => {
|
|
994
|
+
setSelection({ kind: "canvas" });
|
|
995
|
+
if (stacked) setSidebar(false);
|
|
996
|
+
}
|
|
997
|
+
})
|
|
908
998
|
}),
|
|
909
999
|
/* @__PURE__ */ jsxs(Section, {
|
|
910
1000
|
title: `Filtros (${filters.length})`,
|
|
@@ -932,8 +1022,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
932
1022
|
selected: selectedFilter?.dimension === filter.dimension,
|
|
933
1023
|
onSelect: () => focus(item),
|
|
934
1024
|
onHover: (on) => hover(on ? item : null),
|
|
935
|
-
|
|
936
|
-
onDown: index < filters.length - 1 ? () => moveFilter(index, 1) : void 0,
|
|
1025
|
+
...dragProps("filter", index, filters.length),
|
|
937
1026
|
onRemove: () => setFilters(filters.filter((other) => other.dimension !== filter.dimension))
|
|
938
1027
|
}, filter.dimension);
|
|
939
1028
|
})]
|
|
@@ -965,79 +1054,90 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
965
1054
|
selected: chart.id === selected?.id,
|
|
966
1055
|
onSelect: () => focus(item),
|
|
967
1056
|
onHover: (on) => hover(on ? item : null),
|
|
968
|
-
|
|
969
|
-
onDown: index < charts.length - 1 ? () => move(index, 1) : void 0,
|
|
1057
|
+
...dragProps("chart", index, charts.length),
|
|
970
1058
|
onDuplicate: () => add(chart.type, chart),
|
|
971
1059
|
onRemove: () => setCharts(charts.filter((other) => other.id !== chart.id))
|
|
972
1060
|
}, chart.id);
|
|
973
1061
|
})
|
|
974
1062
|
})
|
|
975
1063
|
]
|
|
976
|
-
}), /* @__PURE__ */
|
|
1064
|
+
}), !(stacked && sidebar) && /* @__PURE__ */ jsx(Box, {
|
|
1065
|
+
ref: editorRef,
|
|
977
1066
|
sx: {
|
|
978
|
-
|
|
979
|
-
|
|
1067
|
+
flex: 1,
|
|
1068
|
+
minWidth: 0,
|
|
1069
|
+
overflow: "auto"
|
|
980
1070
|
},
|
|
981
|
-
children:
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1071
|
+
children: /* @__PURE__ */ jsxs(Box, {
|
|
1072
|
+
sx: { p: 1.5 },
|
|
1073
|
+
children: [
|
|
1074
|
+
entry.draft && /* @__PURE__ */ jsxs(Alert, {
|
|
1075
|
+
severity: "warning",
|
|
1076
|
+
sx: { mb: 1.5 },
|
|
1077
|
+
children: [
|
|
1078
|
+
"Rascunho aplicado: a página mostra o layout editado, não o arquivo",
|
|
1079
|
+
" ",
|
|
1080
|
+
/* @__PURE__ */ jsxs("code", { children: [entry.registered.id, ".json"] }),
|
|
1081
|
+
".",
|
|
1082
|
+
capabilities?.saveLayout ? " Use \"Salvar no arquivo\" quando terminar." : " Copie o JSON para o arquivo quando terminar."
|
|
1083
|
+
]
|
|
1084
|
+
}),
|
|
1085
|
+
!!errors.length && /* @__PURE__ */ jsxs(Alert, {
|
|
1086
|
+
severity: "error",
|
|
1087
|
+
sx: { mb: 1.5 },
|
|
1088
|
+
children: ["Layout inválido — as edições não foram aplicadas na página:", errors.map((error) => /* @__PURE__ */ jsx("div", { children: error }, error))]
|
|
1089
|
+
}),
|
|
1090
|
+
!!warnings.length && /* @__PURE__ */ jsx(Alert, {
|
|
1091
|
+
severity: "warning",
|
|
1092
|
+
sx: { mb: 1.5 },
|
|
1093
|
+
children: warnings.map((warning) => /* @__PURE__ */ jsx("div", { children: warning }, warning))
|
|
1094
|
+
}),
|
|
1095
|
+
actionError && /* @__PURE__ */ jsx(Alert, {
|
|
1096
|
+
severity: "error",
|
|
1097
|
+
sx: {
|
|
1098
|
+
mb: 1.5,
|
|
1099
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
1100
|
+
fontSize: 12
|
|
1101
|
+
},
|
|
1102
|
+
children: actionError
|
|
1103
|
+
}),
|
|
1104
|
+
selection?.kind === "canvas" ? /* @__PURE__ */ jsx(CanvasForm, {
|
|
1105
|
+
canvas: editing.canvas,
|
|
1106
|
+
columns: formColumns,
|
|
1107
|
+
onChange: setCanvas
|
|
1108
|
+
}) : selectedFilter ? /* @__PURE__ */ jsx(FilterForm, {
|
|
1109
|
+
filter: selectedFilter,
|
|
1110
|
+
model,
|
|
1111
|
+
formatters: entry.parts.filters ?? [],
|
|
1112
|
+
columns: formColumns,
|
|
1113
|
+
onChange: (change) => {
|
|
1114
|
+
patchFilter(selectedFilter.dimension, change);
|
|
1115
|
+
setSelection({
|
|
1116
|
+
kind: "filter",
|
|
1117
|
+
key: change(selectedFilter).dimension
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
}, `filter:${selectedFilter.dimension}`) : selected ? /* @__PURE__ */ jsx(ChartForm, {
|
|
1121
|
+
chart: selected,
|
|
1122
|
+
model,
|
|
1123
|
+
formatters: entry.parts.charts ?? [],
|
|
1124
|
+
columns: formColumns,
|
|
1125
|
+
onChange: (change) => {
|
|
1126
|
+
patchChart(selected.id, change);
|
|
1127
|
+
setSelection({
|
|
1128
|
+
kind: "chart",
|
|
1129
|
+
key: change(selected).id
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
}, `chart:${selected.id}`) : /* @__PURE__ */ jsx(Empty, { children: "Escolha a tela, um filtro ou um gráfico, ou use \"+ Novo\"." })
|
|
1133
|
+
]
|
|
1134
|
+
})
|
|
1036
1135
|
})]
|
|
1037
1136
|
}),
|
|
1038
1137
|
/* @__PURE__ */ jsxs(Box, {
|
|
1039
1138
|
sx: {
|
|
1040
1139
|
display: "flex",
|
|
1140
|
+
flexWrap: "wrap",
|
|
1041
1141
|
gap: 1,
|
|
1042
1142
|
justifyContent: "flex-end",
|
|
1043
1143
|
alignItems: "center",
|
|
@@ -1120,74 +1220,88 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
1120
1220
|
}
|
|
1121
1221
|
const presetLabel = ({ width, height }) => `${width}×${height ?? "auto"}`;
|
|
1122
1222
|
/** Tamanho fixo da tela (`layout.canvas`): desligado = responsivo. */
|
|
1123
|
-
function
|
|
1223
|
+
function CanvasForm({ canvas, columns, onChange }) {
|
|
1124
1224
|
const preset = canvas && CANVAS_PRESETS.find((item) => presetLabel(item) === presetLabel(canvas));
|
|
1125
1225
|
const number = (value) => value === "" ? void 0 : Number(value);
|
|
1126
|
-
return /* @__PURE__ */
|
|
1226
|
+
return /* @__PURE__ */ jsx(Section, {
|
|
1127
1227
|
title: "Tela",
|
|
1128
|
-
children:
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
gridTemplateColumns: "1fr 1fr",
|
|
1146
|
-
gap: 1,
|
|
1147
|
-
mt: .5
|
|
1148
|
-
},
|
|
1149
|
-
children: [
|
|
1150
|
-
/* @__PURE__ */ jsx(TextField, {
|
|
1228
|
+
children: /* @__PURE__ */ jsxs(Box, {
|
|
1229
|
+
sx: formGrid(columns),
|
|
1230
|
+
children: [/* @__PURE__ */ jsx(Box, {
|
|
1231
|
+
sx: { gridColumn: "1 / -1" },
|
|
1232
|
+
children: withHint(/* @__PURE__ */ jsx(FormControlLabel, {
|
|
1233
|
+
control: /* @__PURE__ */ jsx(Checkbox, {
|
|
1234
|
+
size: "small",
|
|
1235
|
+
checked: !!canvas,
|
|
1236
|
+
onChange: (e) => onChange(e.target.checked ? CANVAS_PRESETS[0] : void 0)
|
|
1237
|
+
}),
|
|
1238
|
+
label: /* @__PURE__ */ jsx(Typography, {
|
|
1239
|
+
sx: { fontSize: 12 },
|
|
1240
|
+
children: "Tamanho fixo"
|
|
1241
|
+
})
|
|
1242
|
+
}), "Desenha o dashboard nesse tamanho e escala para caber na tela, mantendo a proporção, em vez de reorganizar os gráficos. A página precisa do <DashboardCanvas>.")
|
|
1243
|
+
}), canvas && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1244
|
+
field("Predefinido", /* @__PURE__ */ jsx(TextField, {
|
|
1151
1245
|
select: true,
|
|
1152
1246
|
size: "small",
|
|
1153
|
-
|
|
1247
|
+
fullWidth: true,
|
|
1154
1248
|
value: preset ? presetLabel(preset) : "",
|
|
1155
1249
|
onChange: (e) => onChange(CANVAS_PRESETS.find((item) => presetLabel(item) === e.target.value)),
|
|
1156
|
-
sx:
|
|
1157
|
-
...inputSx$1,
|
|
1158
|
-
gridColumn: "1 / -1"
|
|
1159
|
-
},
|
|
1250
|
+
sx: inputSx$1,
|
|
1160
1251
|
children: CANVAS_PRESETS.map((item) => /* @__PURE__ */ jsx(MenuItem, {
|
|
1161
1252
|
value: presetLabel(item),
|
|
1162
1253
|
children: presetLabel(item)
|
|
1163
1254
|
}, presetLabel(item)))
|
|
1164
|
-
}),
|
|
1165
|
-
/* @__PURE__ */ jsx(TextField, {
|
|
1255
|
+
})),
|
|
1256
|
+
field("Largura", /* @__PURE__ */ jsx(TextField, {
|
|
1166
1257
|
size: "small",
|
|
1258
|
+
fullWidth: true,
|
|
1167
1259
|
type: "number",
|
|
1168
|
-
label: "Largura",
|
|
1169
1260
|
value: canvas.width ?? "",
|
|
1170
1261
|
onChange: (e) => onChange(withField(canvas, "width", number(e.target.value))),
|
|
1171
1262
|
sx: inputSx$1
|
|
1172
|
-
}),
|
|
1173
|
-
/* @__PURE__ */ jsx(TextField, {
|
|
1263
|
+
})),
|
|
1264
|
+
field("Altura mín.", /* @__PURE__ */ jsx(TextField, {
|
|
1174
1265
|
size: "small",
|
|
1266
|
+
fullWidth: true,
|
|
1175
1267
|
type: "number",
|
|
1176
|
-
label: "Altura mín.",
|
|
1177
1268
|
value: canvas.height ?? "",
|
|
1269
|
+
placeholder: "auto",
|
|
1178
1270
|
onChange: (e) => onChange(withField(canvas, "height", number(e.target.value))),
|
|
1179
1271
|
sx: inputSx$1
|
|
1180
|
-
})
|
|
1181
|
-
]
|
|
1182
|
-
})
|
|
1272
|
+
}))
|
|
1273
|
+
] })]
|
|
1274
|
+
})
|
|
1183
1275
|
});
|
|
1184
1276
|
}
|
|
1185
|
-
function ItemRow({ title, subtitle, selected, onSelect, onHover,
|
|
1277
|
+
function ItemRow({ title, subtitle, selected, onSelect, onHover, onDuplicate, onRemove, dropBefore, dropAfter, onDragStart, onDragOver, onDrop, onDragEnd }) {
|
|
1278
|
+
const marker = {
|
|
1279
|
+
content: "\"\"",
|
|
1280
|
+
position: "absolute",
|
|
1281
|
+
left: 0,
|
|
1282
|
+
right: 0,
|
|
1283
|
+
height: 2,
|
|
1284
|
+
bgcolor: "primary.main"
|
|
1285
|
+
};
|
|
1186
1286
|
return /* @__PURE__ */ jsxs(Box, {
|
|
1187
1287
|
onClick: onSelect,
|
|
1188
|
-
onMouseEnter: () => onHover(true),
|
|
1189
|
-
onMouseLeave: () => onHover(false),
|
|
1288
|
+
onMouseEnter: () => onHover?.(true),
|
|
1289
|
+
onMouseLeave: () => onHover?.(false),
|
|
1290
|
+
draggable: !!onDragStart,
|
|
1291
|
+
onDragStart: (e) => {
|
|
1292
|
+
if (!onDragStart) return;
|
|
1293
|
+
e.dataTransfer.effectAllowed = "move";
|
|
1294
|
+
e.dataTransfer.setData("text/plain", title);
|
|
1295
|
+
onDragStart();
|
|
1296
|
+
},
|
|
1297
|
+
onDragOver,
|
|
1298
|
+
onDrop: (e) => {
|
|
1299
|
+
e.preventDefault();
|
|
1300
|
+
onDrop?.();
|
|
1301
|
+
},
|
|
1302
|
+
onDragEnd,
|
|
1190
1303
|
sx: {
|
|
1304
|
+
position: "relative",
|
|
1191
1305
|
display: "flex",
|
|
1192
1306
|
alignItems: "center",
|
|
1193
1307
|
gap: .5,
|
|
@@ -1195,64 +1309,71 @@ function ItemRow({ title, subtitle, selected, onSelect, onHover, onUp, onDown, o
|
|
|
1195
1309
|
py: .5,
|
|
1196
1310
|
mb: .5,
|
|
1197
1311
|
borderRadius: 1,
|
|
1198
|
-
cursor: "pointer",
|
|
1312
|
+
cursor: onDragStart ? "grab" : "pointer",
|
|
1199
1313
|
border: 1,
|
|
1200
1314
|
borderColor: selected ? "primary.main" : "divider",
|
|
1201
|
-
"&:hover .item-actions": { visibility: "visible" }
|
|
1315
|
+
"&:hover .item-actions": { visibility: "visible" },
|
|
1316
|
+
"&::before": dropBefore ? {
|
|
1317
|
+
...marker,
|
|
1318
|
+
top: -4
|
|
1319
|
+
} : void 0,
|
|
1320
|
+
"&::after": dropAfter ? {
|
|
1321
|
+
...marker,
|
|
1322
|
+
bottom: -4
|
|
1323
|
+
} : void 0
|
|
1202
1324
|
},
|
|
1203
|
-
children: [
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
},
|
|
1208
|
-
children: [/* @__PURE__ */ jsx(Typography, {
|
|
1209
|
-
noWrap: true,
|
|
1325
|
+
children: [
|
|
1326
|
+
onDragStart && /* @__PURE__ */ jsx(Box, {
|
|
1327
|
+
component: "span",
|
|
1328
|
+
"aria-hidden": true,
|
|
1210
1329
|
sx: {
|
|
1330
|
+
color: "text.disabled",
|
|
1211
1331
|
fontSize: 12,
|
|
1212
|
-
|
|
1332
|
+
lineHeight: 1,
|
|
1333
|
+
userSelect: "none"
|
|
1213
1334
|
},
|
|
1214
|
-
children:
|
|
1215
|
-
}),
|
|
1216
|
-
|
|
1335
|
+
children: "⋮⋮"
|
|
1336
|
+
}),
|
|
1337
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
1217
1338
|
sx: {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
fontFamily: MONO
|
|
1339
|
+
minWidth: 0,
|
|
1340
|
+
flex: 1
|
|
1221
1341
|
},
|
|
1222
|
-
children:
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
children:
|
|
1237
|
-
})
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1342
|
+
children: [/* @__PURE__ */ jsx(Typography, {
|
|
1343
|
+
noWrap: true,
|
|
1344
|
+
sx: {
|
|
1345
|
+
fontSize: 12,
|
|
1346
|
+
fontWeight: 700
|
|
1347
|
+
},
|
|
1348
|
+
children: title
|
|
1349
|
+
}), /* @__PURE__ */ jsx(Typography, {
|
|
1350
|
+
noWrap: true,
|
|
1351
|
+
sx: {
|
|
1352
|
+
fontSize: 11,
|
|
1353
|
+
color: "text.secondary",
|
|
1354
|
+
fontFamily: MONO
|
|
1355
|
+
},
|
|
1356
|
+
children: subtitle
|
|
1357
|
+
})]
|
|
1358
|
+
}),
|
|
1359
|
+
(onDuplicate || onRemove) && /* @__PURE__ */ jsxs(Box, {
|
|
1360
|
+
className: "item-actions",
|
|
1361
|
+
onClick: (e) => e.stopPropagation(),
|
|
1362
|
+
sx: {
|
|
1363
|
+
display: "flex",
|
|
1364
|
+
visibility: selected ? "visible" : "hidden"
|
|
1365
|
+
},
|
|
1366
|
+
children: [onDuplicate && /* @__PURE__ */ jsx(SmallButton, {
|
|
1245
1367
|
title: "Duplicar",
|
|
1246
1368
|
onClick: onDuplicate,
|
|
1247
1369
|
children: "⧉"
|
|
1248
|
-
}),
|
|
1249
|
-
/* @__PURE__ */ jsx(SmallButton, {
|
|
1370
|
+
}), onRemove && /* @__PURE__ */ jsx(SmallButton, {
|
|
1250
1371
|
title: "Remover",
|
|
1251
1372
|
onClick: onRemove,
|
|
1252
1373
|
children: "×"
|
|
1253
|
-
})
|
|
1254
|
-
|
|
1255
|
-
|
|
1374
|
+
})]
|
|
1375
|
+
})
|
|
1376
|
+
]
|
|
1256
1377
|
});
|
|
1257
1378
|
}
|
|
1258
1379
|
function SmallButton({ title, disabled, onClick, children }) {
|
|
@@ -1271,7 +1392,7 @@ function SmallButton({ title, disabled, onClick, children }) {
|
|
|
1271
1392
|
}) })
|
|
1272
1393
|
});
|
|
1273
1394
|
}
|
|
1274
|
-
function ChartForm({ chart, model, formatters, onChange }) {
|
|
1395
|
+
function ChartForm({ chart, model, formatters, columns, onChange }) {
|
|
1275
1396
|
const set = (key, value) => onChange((current) => withField(current, key, value));
|
|
1276
1397
|
return /* @__PURE__ */ jsx(FieldsForm, {
|
|
1277
1398
|
fields: CHART_FIELDS[chart.type],
|
|
@@ -1280,6 +1401,7 @@ function ChartForm({ chart, model, formatters, onChange }) {
|
|
|
1280
1401
|
model,
|
|
1281
1402
|
formatters,
|
|
1282
1403
|
columns: chartColumns(chart),
|
|
1404
|
+
formColumns: columns,
|
|
1283
1405
|
chosenDimensions: chartReferences(chart).dimensions,
|
|
1284
1406
|
header: /* @__PURE__ */ jsxs(Fragment, { children: [field("Tipo", /* @__PURE__ */ jsx(TextField, {
|
|
1285
1407
|
select: true,
|
|
@@ -1302,7 +1424,7 @@ function ChartForm({ chart, model, formatters, onChange }) {
|
|
|
1302
1424
|
}), "Identificador no JSON (letras, números, \"-\" e \"_\")")] })
|
|
1303
1425
|
});
|
|
1304
1426
|
}
|
|
1305
|
-
function FilterForm({ filter, model, formatters, onChange }) {
|
|
1427
|
+
function FilterForm({ filter, model, formatters, columns, onChange }) {
|
|
1306
1428
|
return /* @__PURE__ */ jsx(FieldsForm, {
|
|
1307
1429
|
fields: FILTER_FIELDS,
|
|
1308
1430
|
values: filter,
|
|
@@ -1310,11 +1432,12 @@ function FilterForm({ filter, model, formatters, onChange }) {
|
|
|
1310
1432
|
model,
|
|
1311
1433
|
formatters,
|
|
1312
1434
|
columns: [],
|
|
1435
|
+
formColumns: columns,
|
|
1313
1436
|
chosenDimensions: [filter.dimension]
|
|
1314
1437
|
});
|
|
1315
1438
|
}
|
|
1316
1439
|
/** Formulário gerado dos `FieldSpec` (campos do tipo de gráfico ou do filtro). */
|
|
1317
|
-
function FieldsForm({ fields, values, onSet: set, model, formatters, columns, chosenDimensions, header }) {
|
|
1440
|
+
function FieldsForm({ fields, values, onSet: set, model, formatters, columns, formColumns, chosenDimensions, header }) {
|
|
1318
1441
|
const dimensions = Object.entries(model.dimensions).map(([name, dim]) => ({
|
|
1319
1442
|
name,
|
|
1320
1443
|
label: dim.label
|
|
@@ -1484,21 +1607,16 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, ch
|
|
|
1484
1607
|
}
|
|
1485
1608
|
};
|
|
1486
1609
|
const sections = [...new Set(entries.map(([, spec]) => spec.section))];
|
|
1487
|
-
const grid = {
|
|
1488
|
-
display: "grid",
|
|
1489
|
-
gap: 1.5,
|
|
1490
|
-
gridTemplateColumns: "repeat(4, minmax(0, 1fr))"
|
|
1491
|
-
};
|
|
1492
1610
|
const wide = (spec, key) => key === "title" || spec.kind === "dimensions" || spec.kind === "measures" || spec.kind === "formatters";
|
|
1493
1611
|
return /* @__PURE__ */ jsx(Fragment, { children: sections.map((section) => {
|
|
1494
1612
|
const inSection = entries.filter(([, spec]) => spec.section === section);
|
|
1495
1613
|
return /* @__PURE__ */ jsx(Section, {
|
|
1496
1614
|
title: section,
|
|
1497
1615
|
children: /* @__PURE__ */ jsxs(Box, {
|
|
1498
|
-
sx:
|
|
1616
|
+
sx: formGrid(formColumns),
|
|
1499
1617
|
children: [section === sections[0] && header, inSection.map(([key, spec]) => /* @__PURE__ */ jsx(Box, {
|
|
1500
1618
|
sx: {
|
|
1501
|
-
gridColumn: wide(spec, key) ? "span 2" : void 0,
|
|
1619
|
+
gridColumn: wide(spec, key) && formColumns > 1 ? "span 2" : void 0,
|
|
1502
1620
|
alignSelf: spec.kind === "boolean" ? "end" : void 0
|
|
1503
1621
|
},
|
|
1504
1622
|
children: spec.kind === "boolean" ? withHint(input(key, spec), spec.hint) : field(spec.label, input(key, spec), spec.hint)
|
|
@@ -1507,6 +1625,11 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, ch
|
|
|
1507
1625
|
}, section);
|
|
1508
1626
|
}) });
|
|
1509
1627
|
}
|
|
1628
|
+
const formGrid = (columns) => ({
|
|
1629
|
+
display: "grid",
|
|
1630
|
+
gap: 1.5,
|
|
1631
|
+
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
|
|
1632
|
+
});
|
|
1510
1633
|
/** Rótulo padrão (do dicionário) como placeholder dos campos `*Label` do combo. */
|
|
1511
1634
|
function labelPlaceholder(key, values, model) {
|
|
1512
1635
|
if (key === "label" && typeof values.dimension === "string") return model.dimensions[values.dimension]?.label ?? values.dimension;
|
|
@@ -6258,4 +6381,4 @@ function ToggleButton$1({ draft, loading, problems, inspecting, onOpen }) {
|
|
|
6258
6381
|
//#endregion
|
|
6259
6382
|
export { DashboardDevtools as default };
|
|
6260
6383
|
|
|
6261
|
-
//# sourceMappingURL=DashboardDevtools-
|
|
6384
|
+
//# sourceMappingURL=DashboardDevtools-DLhEr3fN.js.map
|