@bluemarble/bi 0.1.0 → 0.2.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/{DashboardDevtools-ByrFb6HT.js → DashboardDevtools-5wh3brAT.js} +344 -208
- package/dist/DashboardDevtools-5wh3brAT.js.map +1 -0
- package/dist/{ModelDictionary-AjNbffwG.js → ModelDictionary-DN77UDVM.js} +10 -4
- package/dist/ModelDictionary-DN77UDVM.js.map +1 -0
- package/dist/client/index.d.ts +60 -4
- package/dist/client/index.js +26 -9
- package/dist/client/index.js.map +1 -1
- package/dist/{layout-iPByu6V0.js → layout-DvHS8XFz.js} +111 -14
- package/dist/layout-DvHS8XFz.js.map +1 -0
- package/dist/server/index.d.ts +7 -2
- package/dist/server/index.js +7 -5
- package/dist/server/index.js.map +1 -1
- package/dist/{types-CB4sK4jP.d.ts → types-BO_AQNxv.d.ts} +87 -5
- package/dist/types.d.ts +2 -2
- package/package.json +2 -2
- package/dist/DashboardDevtools-ByrFb6HT.js.map +0 -1
- package/dist/ModelDictionary-AjNbffwG.js.map +0 -1
- package/dist/layout-iPByu6V0.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as referencedTables, D as modelEdges, E as measureHome, O as parseColumnRef, S as isAggregate, _ as toModelCode, a as chartOfType, b as VALUE_FORMATS, c as filterReferences, d as layoutModelWarnings, i as chartColumns, m as canonicalJson, n as CANVAS_PRESETS, o as chartReferences, p as validateLayout, r as FILTER_FIELDS, t as BUILTIN_CHART_TYPES, u as layoutFileContent, v as AGGREGATIONS, w as validateModel, y as AGGREGATION_LABEL } from "./layout-DvHS8XFz.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-DN77UDVM.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;
|
|
@@ -701,15 +730,19 @@ const NEW_CHART = {
|
|
|
701
730
|
span: 12
|
|
702
731
|
}
|
|
703
732
|
};
|
|
704
|
-
const newChart = (type, model, charts) => {
|
|
705
|
-
const { id, ...rest } = NEW_CHART[type]
|
|
733
|
+
const newChart = (type, model, charts, types) => {
|
|
734
|
+
const { id, ...rest } = NEW_CHART[type] ?? {
|
|
735
|
+
id: type,
|
|
736
|
+
title: `Novo ${types[type]?.label ?? type}`,
|
|
737
|
+
span: 6
|
|
738
|
+
};
|
|
706
739
|
return chartOfType(type, model, {
|
|
707
740
|
id: uniqueId(charts, id),
|
|
708
741
|
...rest
|
|
709
|
-
});
|
|
742
|
+
}, types);
|
|
710
743
|
};
|
|
711
|
-
const chartSummary = (chart) => {
|
|
712
|
-
const { dimensions, measures } = chartReferences(chart);
|
|
744
|
+
const chartSummary = (chart, types) => {
|
|
745
|
+
const { dimensions, measures } = chartReferences(chart, types);
|
|
713
746
|
return `${chart.type} · ${dimensions.join(", ") || "—"} · ${measures.join(", ")}`;
|
|
714
747
|
};
|
|
715
748
|
/**
|
|
@@ -719,13 +752,17 @@ const chartSummary = (chart) => {
|
|
|
719
752
|
*/
|
|
720
753
|
function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
721
754
|
const { layouts } = devtools;
|
|
722
|
-
const { fetcher, model: modelName } = useDashboard();
|
|
755
|
+
const { fetcher, model: modelName, chartTypes } = useDashboard();
|
|
723
756
|
const entries = useSyncExternalStore(layouts.subscribe, layouts.getSnapshot, layouts.getSnapshot);
|
|
724
757
|
const [layoutId, setLayoutId] = useState(null);
|
|
725
758
|
const entry = entries.find((item) => item.registered.id === layoutId) ?? entries[0] ?? null;
|
|
726
759
|
const reference = entry ? entry.draft ?? entry.registered : null;
|
|
727
760
|
const [editing, setEditing] = useState(reference);
|
|
728
761
|
const [selection, setSelection] = useState(null);
|
|
762
|
+
const [sidebar, setSidebar] = useState(loadSidebar);
|
|
763
|
+
const [drag, setDrag] = useState(null);
|
|
764
|
+
const [rootRef, rootWidth] = useWidth();
|
|
765
|
+
const [editorRef, editorWidth] = useWidth();
|
|
729
766
|
const [busy, setBusy] = useState(false);
|
|
730
767
|
const [actionError, setActionError] = useState(null);
|
|
731
768
|
const [save, setSave] = useState(null);
|
|
@@ -738,12 +775,14 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
738
775
|
setLayoutId(parsed.layoutId);
|
|
739
776
|
setSelection(parsed.item);
|
|
740
777
|
}, [picked]);
|
|
741
|
-
const errors = useMemo(() => editing ? validateLayout(editing) : [], [editing]);
|
|
778
|
+
const errors = useMemo(() => editing ? validateLayout(editing, chartTypes) : [], [editing, chartTypes]);
|
|
742
779
|
const warnings = useMemo(() => {
|
|
743
780
|
if (!editing || errors.length) return [];
|
|
744
|
-
const list = layoutModelWarnings(editing, model);
|
|
781
|
+
const list = layoutModelWarnings(editing, model, chartTypes);
|
|
745
782
|
const { charts: chartFormatters = [], filters: filterFormatters } = entry?.parts ?? {};
|
|
746
|
-
|
|
783
|
+
const serverTypes = new Set(capabilities?.chartTypes ?? []);
|
|
784
|
+
for (const type of new Set(editing.charts.map((chart) => chart.type))) if (capabilities?.saveLayout && !BUILTIN_CHART_TYPES[type] && !serverTypes.has(type)) list.push(`Tipo "${type}" não foi passado ao \`devtools.chartTypes\` do endpoint: "Salvar no arquivo" vai recusar.`);
|
|
785
|
+
for (const chart of editing.charts) for (const name of chartReferences(chart, chartTypes).formatters) if (!chartFormatters.includes(name)) list.push(`"${chart.title || chart.id}": formatter "${name}" não foi passado ao <DashboardCharts formatters>`);
|
|
747
786
|
if (editing.canvas && !entry?.parts.canvas) list.push("A página não usa <DashboardCanvas layout={...}>: o tamanho fixo da tela não é aplicado.");
|
|
748
787
|
if (editing.filters?.length && !filterFormatters) list.push("A página não usa <DashboardFilters layout={...}>: os filtros do layout não aparecem.");
|
|
749
788
|
for (const filter of editing.filters ?? []) for (const name of filterReferences(filter).formatters) if (filterFormatters && !filterFormatters.includes(name)) list.push(`filtro "${filter.dimension}": formatter "${name}" não foi passado ao <DashboardFilters formatters>`);
|
|
@@ -752,7 +791,9 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
752
791
|
editing,
|
|
753
792
|
errors,
|
|
754
793
|
model,
|
|
755
|
-
entry
|
|
794
|
+
entry,
|
|
795
|
+
chartTypes,
|
|
796
|
+
capabilities
|
|
756
797
|
]);
|
|
757
798
|
if (!entry || !editing) return /* @__PURE__ */ jsxs(Empty, { children: [
|
|
758
799
|
"Nenhum ",
|
|
@@ -768,13 +809,13 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
768
809
|
const charts = editing.charts;
|
|
769
810
|
const filters = editing.filters ?? [];
|
|
770
811
|
const selectedFilter = selection?.kind === "filter" ? filters.find((filter) => filter.dimension === selection.key) ?? null : null;
|
|
771
|
-
const selected =
|
|
812
|
+
const selected = selection?.kind === "filter" || selection?.kind === "canvas" ? null : charts.find((chart) => chart.id === selection?.key) ?? charts[0] ?? null;
|
|
772
813
|
const layoutKey = entry.registered.id;
|
|
773
814
|
const differsFromFile = canonicalJson(editing) !== canonicalJson(entry.registered);
|
|
774
815
|
const update = (next) => {
|
|
775
816
|
setEditing(next);
|
|
776
817
|
setSave(null);
|
|
777
|
-
if (!validateLayout(next).length) {
|
|
818
|
+
if (!validateLayout(next, chartTypes).length) {
|
|
778
819
|
devtools.store.expectRefetch();
|
|
779
820
|
layouts.setDraft(entry.registered.id, next);
|
|
780
821
|
}
|
|
@@ -790,21 +831,39 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
790
831
|
filters: next
|
|
791
832
|
});
|
|
792
833
|
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);
|
|
834
|
+
const toggleSidebar = () => {
|
|
835
|
+
const next = !sidebar;
|
|
836
|
+
setSidebar(next);
|
|
837
|
+
try {
|
|
838
|
+
localStorage.setItem(SIDEBAR_KEY, next ? "open" : "closed");
|
|
839
|
+
} catch {}
|
|
807
840
|
};
|
|
841
|
+
const dragProps = (kind, index, length) => ({
|
|
842
|
+
dropBefore: drag?.kind === kind && drag.from !== index && drag.to === index,
|
|
843
|
+
dropAfter: drag?.kind === kind && index === length - 1 && drag.to === length,
|
|
844
|
+
onDragStart: () => setDrag({
|
|
845
|
+
kind,
|
|
846
|
+
from: index,
|
|
847
|
+
to: index
|
|
848
|
+
}),
|
|
849
|
+
onDragOver: (e) => {
|
|
850
|
+
if (drag?.kind !== kind) return;
|
|
851
|
+
e.preventDefault();
|
|
852
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
853
|
+
const to = e.clientY < rect.top + rect.height / 2 ? index : index + 1;
|
|
854
|
+
if (to !== drag.to) setDrag({
|
|
855
|
+
...drag,
|
|
856
|
+
to
|
|
857
|
+
});
|
|
858
|
+
},
|
|
859
|
+
onDrop: () => {
|
|
860
|
+
if (drag?.kind !== kind) return;
|
|
861
|
+
if (drag.to !== drag.from && drag.to !== drag.from + 1) if (kind === "chart") setCharts(moveTo(charts, drag.from, drag.to));
|
|
862
|
+
else setFilters(moveTo(filters, drag.from, drag.to));
|
|
863
|
+
setDrag(null);
|
|
864
|
+
},
|
|
865
|
+
onDragEnd: () => setDrag(null)
|
|
866
|
+
});
|
|
808
867
|
const addFilter = () => {
|
|
809
868
|
const used = new Set(filters.map((filter) => filter.dimension));
|
|
810
869
|
const dimension = Object.keys(model.dimensions).find((name) => !used.has(name));
|
|
@@ -817,11 +876,15 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
817
876
|
};
|
|
818
877
|
const focus = (item) => {
|
|
819
878
|
setSelection(item);
|
|
879
|
+
if (stacked) setSidebar(false);
|
|
820
880
|
itemElement(layoutKey, item)?.scrollIntoView({
|
|
821
881
|
behavior: "smooth",
|
|
822
882
|
block: "center"
|
|
823
883
|
});
|
|
824
884
|
};
|
|
885
|
+
const stacked = rootWidth < STACK_WIDTH;
|
|
886
|
+
const formColumns = editorWidth < 420 ? 1 : editorWidth < 720 ? 2 : 4;
|
|
887
|
+
const selectedTitle = selection?.kind === "canvas" ? "Tela" : selectedFilter ? selectedFilter.label || model.dimensions[selectedFilter.dimension]?.label || selectedFilter.dimension : selected ? selected.title || selected.id : "";
|
|
825
888
|
const hover = (item) => onHover(item && itemQueryId(layoutKey, item));
|
|
826
889
|
const add = (type, base) => {
|
|
827
890
|
setAddMenu(null);
|
|
@@ -829,7 +892,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
829
892
|
...base,
|
|
830
893
|
id: uniqueId(charts, base.id),
|
|
831
894
|
title: `${base.title} (cópia)`
|
|
832
|
-
} : newChart(type, model, charts);
|
|
895
|
+
} : newChart(type, model, charts, chartTypes);
|
|
833
896
|
const index = base ? charts.findIndex((item) => item.id === base.id) + 1 : charts.length;
|
|
834
897
|
setCharts([
|
|
835
898
|
...charts.slice(0, index),
|
|
@@ -864,6 +927,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
864
927
|
}
|
|
865
928
|
};
|
|
866
929
|
return /* @__PURE__ */ jsxs(Box, {
|
|
930
|
+
ref: rootRef,
|
|
867
931
|
sx: {
|
|
868
932
|
display: "flex",
|
|
869
933
|
flexDirection: "column",
|
|
@@ -871,19 +935,45 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
871
935
|
minHeight: 0
|
|
872
936
|
},
|
|
873
937
|
children: [
|
|
938
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
939
|
+
sx: {
|
|
940
|
+
display: "flex",
|
|
941
|
+
alignItems: "center",
|
|
942
|
+
gap: 1,
|
|
943
|
+
px: 1,
|
|
944
|
+
py: .5,
|
|
945
|
+
borderBottom: 1,
|
|
946
|
+
borderColor: "divider"
|
|
947
|
+
},
|
|
948
|
+
children: [/* @__PURE__ */ jsx(SmallButton, {
|
|
949
|
+
title: sidebar ? "Recolher a lista" : "Mostrar a lista",
|
|
950
|
+
onClick: toggleSidebar,
|
|
951
|
+
children: sidebar ? "«" : "☰"
|
|
952
|
+
}), /* @__PURE__ */ jsx(Typography, {
|
|
953
|
+
noWrap: true,
|
|
954
|
+
sx: {
|
|
955
|
+
fontSize: 12,
|
|
956
|
+
fontWeight: 700
|
|
957
|
+
},
|
|
958
|
+
children: stacked && sidebar ? `Layout ${layoutKey}` : selectedTitle
|
|
959
|
+
})]
|
|
960
|
+
}),
|
|
874
961
|
/* @__PURE__ */ jsxs(Box, {
|
|
875
962
|
sx: {
|
|
876
963
|
flex: 1,
|
|
877
964
|
minHeight: 0,
|
|
878
|
-
display: "
|
|
879
|
-
gridTemplateColumns: "280px 1fr"
|
|
965
|
+
display: "flex"
|
|
880
966
|
},
|
|
881
|
-
children: [/* @__PURE__ */ jsxs(Box, {
|
|
967
|
+
children: [sidebar && /* @__PURE__ */ jsxs(Box, {
|
|
882
968
|
sx: {
|
|
883
|
-
borderRight: 1,
|
|
884
|
-
borderColor: "divider",
|
|
885
969
|
overflow: "auto",
|
|
886
|
-
p: 1.5
|
|
970
|
+
p: 1.5,
|
|
971
|
+
...stacked ? { flex: 1 } : {
|
|
972
|
+
width: 280,
|
|
973
|
+
flexShrink: 0,
|
|
974
|
+
borderRight: 1,
|
|
975
|
+
borderColor: "divider"
|
|
976
|
+
}
|
|
887
977
|
},
|
|
888
978
|
children: [
|
|
889
979
|
entries.length > 1 && /* @__PURE__ */ jsx(TextField, {
|
|
@@ -902,9 +992,17 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
902
992
|
children: [item.registered.id, item.draft ? " · rascunho" : ""]
|
|
903
993
|
}, item.registered.id))
|
|
904
994
|
}),
|
|
905
|
-
/* @__PURE__ */ jsx(
|
|
906
|
-
|
|
907
|
-
|
|
995
|
+
/* @__PURE__ */ jsx(Section, {
|
|
996
|
+
title: "Tela",
|
|
997
|
+
children: /* @__PURE__ */ jsx(ItemRow, {
|
|
998
|
+
title: editing.canvas ? "Tamanho fixo" : "Responsiva",
|
|
999
|
+
subtitle: editing.canvas ? presetLabel(editing.canvas) : "reorganiza conforme a largura",
|
|
1000
|
+
selected: selection?.kind === "canvas",
|
|
1001
|
+
onSelect: () => {
|
|
1002
|
+
setSelection({ kind: "canvas" });
|
|
1003
|
+
if (stacked) setSidebar(false);
|
|
1004
|
+
}
|
|
1005
|
+
})
|
|
908
1006
|
}),
|
|
909
1007
|
/* @__PURE__ */ jsxs(Section, {
|
|
910
1008
|
title: `Filtros (${filters.length})`,
|
|
@@ -932,8 +1030,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
932
1030
|
selected: selectedFilter?.dimension === filter.dimension,
|
|
933
1031
|
onSelect: () => focus(item),
|
|
934
1032
|
onHover: (on) => hover(on ? item : null),
|
|
935
|
-
|
|
936
|
-
onDown: index < filters.length - 1 ? () => moveFilter(index, 1) : void 0,
|
|
1033
|
+
...dragProps("filter", index, filters.length),
|
|
937
1034
|
onRemove: () => setFilters(filters.filter((other) => other.dimension !== filter.dimension))
|
|
938
1035
|
}, filter.dimension);
|
|
939
1036
|
})]
|
|
@@ -948,10 +1045,10 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
948
1045
|
anchorEl: addMenu,
|
|
949
1046
|
open: !!addMenu,
|
|
950
1047
|
onClose: () => setAddMenu(null),
|
|
951
|
-
children:
|
|
1048
|
+
children: Object.entries(chartTypes).map(([type, { label }]) => /* @__PURE__ */ jsx(MenuItem, {
|
|
952
1049
|
dense: true,
|
|
953
1050
|
onClick: () => add(type),
|
|
954
|
-
children:
|
|
1051
|
+
children: label
|
|
955
1052
|
}, type))
|
|
956
1053
|
})] }),
|
|
957
1054
|
children: charts.map((chart, index) => {
|
|
@@ -961,83 +1058,95 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
961
1058
|
};
|
|
962
1059
|
return /* @__PURE__ */ jsx(ItemRow, {
|
|
963
1060
|
title: chart.title || "(sem título)",
|
|
964
|
-
subtitle: `${chartSummary(chart)} · ${chart.span ?? 12}/12`,
|
|
1061
|
+
subtitle: `${chartSummary(chart, chartTypes)} · ${chart.span ?? 12}/12`,
|
|
965
1062
|
selected: chart.id === selected?.id,
|
|
966
1063
|
onSelect: () => focus(item),
|
|
967
1064
|
onHover: (on) => hover(on ? item : null),
|
|
968
|
-
|
|
969
|
-
onDown: index < charts.length - 1 ? () => move(index, 1) : void 0,
|
|
1065
|
+
...dragProps("chart", index, charts.length),
|
|
970
1066
|
onDuplicate: () => add(chart.type, chart),
|
|
971
1067
|
onRemove: () => setCharts(charts.filter((other) => other.id !== chart.id))
|
|
972
1068
|
}, chart.id);
|
|
973
1069
|
})
|
|
974
1070
|
})
|
|
975
1071
|
]
|
|
976
|
-
}), /* @__PURE__ */
|
|
1072
|
+
}), !(stacked && sidebar) && /* @__PURE__ */ jsx(Box, {
|
|
1073
|
+
ref: editorRef,
|
|
977
1074
|
sx: {
|
|
978
|
-
|
|
979
|
-
|
|
1075
|
+
flex: 1,
|
|
1076
|
+
minWidth: 0,
|
|
1077
|
+
overflow: "auto"
|
|
980
1078
|
},
|
|
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
|
-
|
|
1079
|
+
children: /* @__PURE__ */ jsxs(Box, {
|
|
1080
|
+
sx: { p: 1.5 },
|
|
1081
|
+
children: [
|
|
1082
|
+
entry.draft && /* @__PURE__ */ jsxs(Alert, {
|
|
1083
|
+
severity: "warning",
|
|
1084
|
+
sx: { mb: 1.5 },
|
|
1085
|
+
children: [
|
|
1086
|
+
"Rascunho aplicado: a página mostra o layout editado, não o arquivo",
|
|
1087
|
+
" ",
|
|
1088
|
+
/* @__PURE__ */ jsxs("code", { children: [entry.registered.id, ".json"] }),
|
|
1089
|
+
".",
|
|
1090
|
+
capabilities?.saveLayout ? " Use \"Salvar no arquivo\" quando terminar." : " Copie o JSON para o arquivo quando terminar."
|
|
1091
|
+
]
|
|
1092
|
+
}),
|
|
1093
|
+
!!errors.length && /* @__PURE__ */ jsxs(Alert, {
|
|
1094
|
+
severity: "error",
|
|
1095
|
+
sx: { mb: 1.5 },
|
|
1096
|
+
children: ["Layout inválido — as edições não foram aplicadas na página:", errors.map((error) => /* @__PURE__ */ jsx("div", { children: error }, error))]
|
|
1097
|
+
}),
|
|
1098
|
+
!!warnings.length && /* @__PURE__ */ jsx(Alert, {
|
|
1099
|
+
severity: "warning",
|
|
1100
|
+
sx: { mb: 1.5 },
|
|
1101
|
+
children: warnings.map((warning) => /* @__PURE__ */ jsx("div", { children: warning }, warning))
|
|
1102
|
+
}),
|
|
1103
|
+
actionError && /* @__PURE__ */ jsx(Alert, {
|
|
1104
|
+
severity: "error",
|
|
1105
|
+
sx: {
|
|
1106
|
+
mb: 1.5,
|
|
1107
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
1108
|
+
fontSize: 12
|
|
1109
|
+
},
|
|
1110
|
+
children: actionError
|
|
1111
|
+
}),
|
|
1112
|
+
selection?.kind === "canvas" ? /* @__PURE__ */ jsx(CanvasForm, {
|
|
1113
|
+
canvas: editing.canvas,
|
|
1114
|
+
columns: formColumns,
|
|
1115
|
+
onChange: setCanvas
|
|
1116
|
+
}) : selectedFilter ? /* @__PURE__ */ jsx(FilterForm, {
|
|
1117
|
+
filter: selectedFilter,
|
|
1118
|
+
model,
|
|
1119
|
+
formatters: entry.parts.filters ?? [],
|
|
1120
|
+
columns: formColumns,
|
|
1121
|
+
onChange: (change) => {
|
|
1122
|
+
patchFilter(selectedFilter.dimension, change);
|
|
1123
|
+
setSelection({
|
|
1124
|
+
kind: "filter",
|
|
1125
|
+
key: change(selectedFilter).dimension
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
1128
|
+
}, `filter:${selectedFilter.dimension}`) : selected ? /* @__PURE__ */ jsx(ChartForm, {
|
|
1129
|
+
chart: selected,
|
|
1130
|
+
types: chartTypes,
|
|
1131
|
+
model,
|
|
1132
|
+
formatters: entry.parts.charts ?? [],
|
|
1133
|
+
columns: formColumns,
|
|
1134
|
+
onChange: (change) => {
|
|
1135
|
+
patchChart(selected.id, change);
|
|
1136
|
+
setSelection({
|
|
1137
|
+
kind: "chart",
|
|
1138
|
+
key: change(selected).id
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
}, `chart:${selected.id}`) : /* @__PURE__ */ jsx(Empty, { children: "Escolha a tela, um filtro ou um gráfico, ou use \"+ Novo\"." })
|
|
1142
|
+
]
|
|
1143
|
+
})
|
|
1036
1144
|
})]
|
|
1037
1145
|
}),
|
|
1038
1146
|
/* @__PURE__ */ jsxs(Box, {
|
|
1039
1147
|
sx: {
|
|
1040
1148
|
display: "flex",
|
|
1149
|
+
flexWrap: "wrap",
|
|
1041
1150
|
gap: 1,
|
|
1042
1151
|
justifyContent: "flex-end",
|
|
1043
1152
|
alignItems: "center",
|
|
@@ -1120,74 +1229,88 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
1120
1229
|
}
|
|
1121
1230
|
const presetLabel = ({ width, height }) => `${width}×${height ?? "auto"}`;
|
|
1122
1231
|
/** Tamanho fixo da tela (`layout.canvas`): desligado = responsivo. */
|
|
1123
|
-
function
|
|
1232
|
+
function CanvasForm({ canvas, columns, onChange }) {
|
|
1124
1233
|
const preset = canvas && CANVAS_PRESETS.find((item) => presetLabel(item) === presetLabel(canvas));
|
|
1125
1234
|
const number = (value) => value === "" ? void 0 : Number(value);
|
|
1126
|
-
return /* @__PURE__ */
|
|
1235
|
+
return /* @__PURE__ */ jsx(Section, {
|
|
1127
1236
|
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, {
|
|
1237
|
+
children: /* @__PURE__ */ jsxs(Box, {
|
|
1238
|
+
sx: formGrid(columns),
|
|
1239
|
+
children: [/* @__PURE__ */ jsx(Box, {
|
|
1240
|
+
sx: { gridColumn: "1 / -1" },
|
|
1241
|
+
children: withHint(/* @__PURE__ */ jsx(FormControlLabel, {
|
|
1242
|
+
control: /* @__PURE__ */ jsx(Checkbox, {
|
|
1243
|
+
size: "small",
|
|
1244
|
+
checked: !!canvas,
|
|
1245
|
+
onChange: (e) => onChange(e.target.checked ? CANVAS_PRESETS[0] : void 0)
|
|
1246
|
+
}),
|
|
1247
|
+
label: /* @__PURE__ */ jsx(Typography, {
|
|
1248
|
+
sx: { fontSize: 12 },
|
|
1249
|
+
children: "Tamanho fixo"
|
|
1250
|
+
})
|
|
1251
|
+
}), "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>.")
|
|
1252
|
+
}), canvas && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1253
|
+
field("Predefinido", /* @__PURE__ */ jsx(TextField, {
|
|
1151
1254
|
select: true,
|
|
1152
1255
|
size: "small",
|
|
1153
|
-
|
|
1256
|
+
fullWidth: true,
|
|
1154
1257
|
value: preset ? presetLabel(preset) : "",
|
|
1155
1258
|
onChange: (e) => onChange(CANVAS_PRESETS.find((item) => presetLabel(item) === e.target.value)),
|
|
1156
|
-
sx:
|
|
1157
|
-
...inputSx$1,
|
|
1158
|
-
gridColumn: "1 / -1"
|
|
1159
|
-
},
|
|
1259
|
+
sx: inputSx$1,
|
|
1160
1260
|
children: CANVAS_PRESETS.map((item) => /* @__PURE__ */ jsx(MenuItem, {
|
|
1161
1261
|
value: presetLabel(item),
|
|
1162
1262
|
children: presetLabel(item)
|
|
1163
1263
|
}, presetLabel(item)))
|
|
1164
|
-
}),
|
|
1165
|
-
/* @__PURE__ */ jsx(TextField, {
|
|
1264
|
+
})),
|
|
1265
|
+
field("Largura", /* @__PURE__ */ jsx(TextField, {
|
|
1166
1266
|
size: "small",
|
|
1267
|
+
fullWidth: true,
|
|
1167
1268
|
type: "number",
|
|
1168
|
-
label: "Largura",
|
|
1169
1269
|
value: canvas.width ?? "",
|
|
1170
1270
|
onChange: (e) => onChange(withField(canvas, "width", number(e.target.value))),
|
|
1171
1271
|
sx: inputSx$1
|
|
1172
|
-
}),
|
|
1173
|
-
/* @__PURE__ */ jsx(TextField, {
|
|
1272
|
+
})),
|
|
1273
|
+
field("Altura mín.", /* @__PURE__ */ jsx(TextField, {
|
|
1174
1274
|
size: "small",
|
|
1275
|
+
fullWidth: true,
|
|
1175
1276
|
type: "number",
|
|
1176
|
-
label: "Altura mín.",
|
|
1177
1277
|
value: canvas.height ?? "",
|
|
1278
|
+
placeholder: "auto",
|
|
1178
1279
|
onChange: (e) => onChange(withField(canvas, "height", number(e.target.value))),
|
|
1179
1280
|
sx: inputSx$1
|
|
1180
|
-
})
|
|
1181
|
-
]
|
|
1182
|
-
})
|
|
1281
|
+
}))
|
|
1282
|
+
] })]
|
|
1283
|
+
})
|
|
1183
1284
|
});
|
|
1184
1285
|
}
|
|
1185
|
-
function ItemRow({ title, subtitle, selected, onSelect, onHover,
|
|
1286
|
+
function ItemRow({ title, subtitle, selected, onSelect, onHover, onDuplicate, onRemove, dropBefore, dropAfter, onDragStart, onDragOver, onDrop, onDragEnd }) {
|
|
1287
|
+
const marker = {
|
|
1288
|
+
content: "\"\"",
|
|
1289
|
+
position: "absolute",
|
|
1290
|
+
left: 0,
|
|
1291
|
+
right: 0,
|
|
1292
|
+
height: 2,
|
|
1293
|
+
bgcolor: "primary.main"
|
|
1294
|
+
};
|
|
1186
1295
|
return /* @__PURE__ */ jsxs(Box, {
|
|
1187
1296
|
onClick: onSelect,
|
|
1188
|
-
onMouseEnter: () => onHover(true),
|
|
1189
|
-
onMouseLeave: () => onHover(false),
|
|
1297
|
+
onMouseEnter: () => onHover?.(true),
|
|
1298
|
+
onMouseLeave: () => onHover?.(false),
|
|
1299
|
+
draggable: !!onDragStart,
|
|
1300
|
+
onDragStart: (e) => {
|
|
1301
|
+
if (!onDragStart) return;
|
|
1302
|
+
e.dataTransfer.effectAllowed = "move";
|
|
1303
|
+
e.dataTransfer.setData("text/plain", title);
|
|
1304
|
+
onDragStart();
|
|
1305
|
+
},
|
|
1306
|
+
onDragOver,
|
|
1307
|
+
onDrop: (e) => {
|
|
1308
|
+
e.preventDefault();
|
|
1309
|
+
onDrop?.();
|
|
1310
|
+
},
|
|
1311
|
+
onDragEnd,
|
|
1190
1312
|
sx: {
|
|
1313
|
+
position: "relative",
|
|
1191
1314
|
display: "flex",
|
|
1192
1315
|
alignItems: "center",
|
|
1193
1316
|
gap: .5,
|
|
@@ -1195,64 +1318,71 @@ function ItemRow({ title, subtitle, selected, onSelect, onHover, onUp, onDown, o
|
|
|
1195
1318
|
py: .5,
|
|
1196
1319
|
mb: .5,
|
|
1197
1320
|
borderRadius: 1,
|
|
1198
|
-
cursor: "pointer",
|
|
1321
|
+
cursor: onDragStart ? "grab" : "pointer",
|
|
1199
1322
|
border: 1,
|
|
1200
1323
|
borderColor: selected ? "primary.main" : "divider",
|
|
1201
|
-
"&:hover .item-actions": { visibility: "visible" }
|
|
1324
|
+
"&:hover .item-actions": { visibility: "visible" },
|
|
1325
|
+
"&::before": dropBefore ? {
|
|
1326
|
+
...marker,
|
|
1327
|
+
top: -4
|
|
1328
|
+
} : void 0,
|
|
1329
|
+
"&::after": dropAfter ? {
|
|
1330
|
+
...marker,
|
|
1331
|
+
bottom: -4
|
|
1332
|
+
} : void 0
|
|
1202
1333
|
},
|
|
1203
|
-
children: [
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
},
|
|
1208
|
-
children: [/* @__PURE__ */ jsx(Typography, {
|
|
1209
|
-
noWrap: true,
|
|
1334
|
+
children: [
|
|
1335
|
+
onDragStart && /* @__PURE__ */ jsx(Box, {
|
|
1336
|
+
component: "span",
|
|
1337
|
+
"aria-hidden": true,
|
|
1210
1338
|
sx: {
|
|
1339
|
+
color: "text.disabled",
|
|
1211
1340
|
fontSize: 12,
|
|
1212
|
-
|
|
1341
|
+
lineHeight: 1,
|
|
1342
|
+
userSelect: "none"
|
|
1213
1343
|
},
|
|
1214
|
-
children:
|
|
1215
|
-
}),
|
|
1216
|
-
|
|
1344
|
+
children: "⋮⋮"
|
|
1345
|
+
}),
|
|
1346
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
1217
1347
|
sx: {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
fontFamily: MONO
|
|
1348
|
+
minWidth: 0,
|
|
1349
|
+
flex: 1
|
|
1221
1350
|
},
|
|
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
|
-
|
|
1351
|
+
children: [/* @__PURE__ */ jsx(Typography, {
|
|
1352
|
+
noWrap: true,
|
|
1353
|
+
sx: {
|
|
1354
|
+
fontSize: 12,
|
|
1355
|
+
fontWeight: 700
|
|
1356
|
+
},
|
|
1357
|
+
children: title
|
|
1358
|
+
}), /* @__PURE__ */ jsx(Typography, {
|
|
1359
|
+
noWrap: true,
|
|
1360
|
+
sx: {
|
|
1361
|
+
fontSize: 11,
|
|
1362
|
+
color: "text.secondary",
|
|
1363
|
+
fontFamily: MONO
|
|
1364
|
+
},
|
|
1365
|
+
children: subtitle
|
|
1366
|
+
})]
|
|
1367
|
+
}),
|
|
1368
|
+
(onDuplicate || onRemove) && /* @__PURE__ */ jsxs(Box, {
|
|
1369
|
+
className: "item-actions",
|
|
1370
|
+
onClick: (e) => e.stopPropagation(),
|
|
1371
|
+
sx: {
|
|
1372
|
+
display: "flex",
|
|
1373
|
+
visibility: selected ? "visible" : "hidden"
|
|
1374
|
+
},
|
|
1375
|
+
children: [onDuplicate && /* @__PURE__ */ jsx(SmallButton, {
|
|
1245
1376
|
title: "Duplicar",
|
|
1246
1377
|
onClick: onDuplicate,
|
|
1247
1378
|
children: "⧉"
|
|
1248
|
-
}),
|
|
1249
|
-
/* @__PURE__ */ jsx(SmallButton, {
|
|
1379
|
+
}), onRemove && /* @__PURE__ */ jsx(SmallButton, {
|
|
1250
1380
|
title: "Remover",
|
|
1251
1381
|
onClick: onRemove,
|
|
1252
1382
|
children: "×"
|
|
1253
|
-
})
|
|
1254
|
-
|
|
1255
|
-
|
|
1383
|
+
})]
|
|
1384
|
+
})
|
|
1385
|
+
]
|
|
1256
1386
|
});
|
|
1257
1387
|
}
|
|
1258
1388
|
function SmallButton({ title, disabled, onClick, children }) {
|
|
@@ -1271,27 +1401,32 @@ function SmallButton({ title, disabled, onClick, children }) {
|
|
|
1271
1401
|
}) })
|
|
1272
1402
|
});
|
|
1273
1403
|
}
|
|
1274
|
-
function ChartForm({ chart, model, formatters, onChange }) {
|
|
1404
|
+
function ChartForm({ chart, types, model, formatters, columns, onChange }) {
|
|
1275
1405
|
const set = (key, value) => onChange((current) => withField(current, key, value));
|
|
1276
1406
|
return /* @__PURE__ */ jsx(FieldsForm, {
|
|
1277
|
-
fields:
|
|
1407
|
+
fields: types[chart.type]?.fields ?? {},
|
|
1278
1408
|
values: chart,
|
|
1279
1409
|
onSet: set,
|
|
1280
1410
|
model,
|
|
1281
1411
|
formatters,
|
|
1282
|
-
columns: chartColumns(chart),
|
|
1283
|
-
|
|
1284
|
-
|
|
1412
|
+
columns: chartColumns(chart, types),
|
|
1413
|
+
formColumns: columns,
|
|
1414
|
+
chosenDimensions: chartReferences(chart, types).dimensions,
|
|
1415
|
+
header: /* @__PURE__ */ jsxs(Fragment, { children: [field("Tipo", /* @__PURE__ */ jsxs(TextField, {
|
|
1285
1416
|
select: true,
|
|
1286
1417
|
size: "small",
|
|
1287
1418
|
fullWidth: true,
|
|
1288
1419
|
value: chart.type,
|
|
1289
|
-
onChange: (e) => onChange((current) => chartOfType(e.target.value, model, current)),
|
|
1420
|
+
onChange: (e) => onChange((current) => chartOfType(e.target.value, model, current, types)),
|
|
1290
1421
|
sx: inputSx$1,
|
|
1291
|
-
children:
|
|
1422
|
+
children: [Object.entries(types).map(([type, { label }]) => /* @__PURE__ */ jsx(MenuItem, {
|
|
1292
1423
|
value: type,
|
|
1293
|
-
children:
|
|
1294
|
-
}, type))
|
|
1424
|
+
children: label
|
|
1425
|
+
}, type)), !types[chart.type] && /* @__PURE__ */ jsxs(MenuItem, {
|
|
1426
|
+
value: chart.type,
|
|
1427
|
+
disabled: true,
|
|
1428
|
+
children: [chart.type, " (não registrado)"]
|
|
1429
|
+
})]
|
|
1295
1430
|
})), field("id", /* @__PURE__ */ jsx(TextField, {
|
|
1296
1431
|
size: "small",
|
|
1297
1432
|
fullWidth: true,
|
|
@@ -1302,7 +1437,7 @@ function ChartForm({ chart, model, formatters, onChange }) {
|
|
|
1302
1437
|
}), "Identificador no JSON (letras, números, \"-\" e \"_\")")] })
|
|
1303
1438
|
});
|
|
1304
1439
|
}
|
|
1305
|
-
function FilterForm({ filter, model, formatters, onChange }) {
|
|
1440
|
+
function FilterForm({ filter, model, formatters, columns, onChange }) {
|
|
1306
1441
|
return /* @__PURE__ */ jsx(FieldsForm, {
|
|
1307
1442
|
fields: FILTER_FIELDS,
|
|
1308
1443
|
values: filter,
|
|
@@ -1310,11 +1445,12 @@ function FilterForm({ filter, model, formatters, onChange }) {
|
|
|
1310
1445
|
model,
|
|
1311
1446
|
formatters,
|
|
1312
1447
|
columns: [],
|
|
1448
|
+
formColumns: columns,
|
|
1313
1449
|
chosenDimensions: [filter.dimension]
|
|
1314
1450
|
});
|
|
1315
1451
|
}
|
|
1316
1452
|
/** 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 }) {
|
|
1453
|
+
function FieldsForm({ fields, values, onSet: set, model, formatters, columns, formColumns, chosenDimensions, header }) {
|
|
1318
1454
|
const dimensions = Object.entries(model.dimensions).map(([name, dim]) => ({
|
|
1319
1455
|
name,
|
|
1320
1456
|
label: dim.label
|
|
@@ -1484,21 +1620,16 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, ch
|
|
|
1484
1620
|
}
|
|
1485
1621
|
};
|
|
1486
1622
|
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
1623
|
const wide = (spec, key) => key === "title" || spec.kind === "dimensions" || spec.kind === "measures" || spec.kind === "formatters";
|
|
1493
1624
|
return /* @__PURE__ */ jsx(Fragment, { children: sections.map((section) => {
|
|
1494
1625
|
const inSection = entries.filter(([, spec]) => spec.section === section);
|
|
1495
1626
|
return /* @__PURE__ */ jsx(Section, {
|
|
1496
1627
|
title: section,
|
|
1497
1628
|
children: /* @__PURE__ */ jsxs(Box, {
|
|
1498
|
-
sx:
|
|
1629
|
+
sx: formGrid(formColumns),
|
|
1499
1630
|
children: [section === sections[0] && header, inSection.map(([key, spec]) => /* @__PURE__ */ jsx(Box, {
|
|
1500
1631
|
sx: {
|
|
1501
|
-
gridColumn: wide(spec, key) ? "span 2" : void 0,
|
|
1632
|
+
gridColumn: wide(spec, key) && formColumns > 1 ? "span 2" : void 0,
|
|
1502
1633
|
alignSelf: spec.kind === "boolean" ? "end" : void 0
|
|
1503
1634
|
},
|
|
1504
1635
|
children: spec.kind === "boolean" ? withHint(input(key, spec), spec.hint) : field(spec.label, input(key, spec), spec.hint)
|
|
@@ -1507,6 +1638,11 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, ch
|
|
|
1507
1638
|
}, section);
|
|
1508
1639
|
}) });
|
|
1509
1640
|
}
|
|
1641
|
+
const formGrid = (columns) => ({
|
|
1642
|
+
display: "grid",
|
|
1643
|
+
gap: 1.5,
|
|
1644
|
+
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
|
|
1645
|
+
});
|
|
1510
1646
|
/** Rótulo padrão (do dicionário) como placeholder dos campos `*Label` do combo. */
|
|
1511
1647
|
function labelPlaceholder(key, values, model) {
|
|
1512
1648
|
if (key === "label" && typeof values.dimension === "string") return model.dimensions[values.dimension]?.label ?? values.dimension;
|
|
@@ -6258,4 +6394,4 @@ function ToggleButton$1({ draft, loading, problems, inspecting, onOpen }) {
|
|
|
6258
6394
|
//#endregion
|
|
6259
6395
|
export { DashboardDevtools as default };
|
|
6260
6396
|
|
|
6261
|
-
//# sourceMappingURL=DashboardDevtools-
|
|
6397
|
+
//# sourceMappingURL=DashboardDevtools-5wh3brAT.js.map
|