@bluemarble/bi 0.3.1 → 0.4.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-C4E9afPT.js → DashboardDevtools-7L93aV1-.js} +617 -230
- package/dist/DashboardDevtools-7L93aV1-.js.map +1 -0
- package/dist/{ModelDictionary-kUKcdbc8.js → ModelDictionary-Y7W9oK1J.js} +3 -3
- package/dist/{ModelDictionary-kUKcdbc8.js.map → ModelDictionary-Y7W9oK1J.js.map} +1 -1
- package/dist/client/index.d.ts +54 -17
- package/dist/client/index.js +121 -57
- package/dist/client/index.js.map +1 -1
- package/dist/{layout-DTR4vI-I.js → layout-676sEvvb.js} +84 -32
- package/dist/layout-676sEvvb.js.map +1 -0
- package/dist/server/index.d.ts +1 -5
- package/dist/server/index.js +1 -1
- package/dist/{types-DUJS2Zmx.d.ts → types-HXAn-3I1.d.ts} +47 -13
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/dist/DashboardDevtools-C4E9afPT.js.map +0 -1
- package/dist/layout-DTR4vI-I.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as modelEdges, C as VALUE_FORMATS, D as validateModel, N as referencedTables, S as AGGREGATION_LABEL, T as isAggregate, _ as canonicalJson, a as FILTER_FIELDS, b as toModelCode, c as chartOfType, d as filterReferences, g as validateLayout, i as CARD_FIELDS, j as parseColumnRef, k as measureHome, l as chartReferences, m as layoutModelWarnings, n as CANVAS_PRESETS, p as layoutFileContent, r as CARDS_FIELDS, s as chartColumns, t as BUILTIN_CHART_TYPES, x as AGGREGATIONS } from "./layout-
|
|
1
|
+
import { A as modelEdges, C as VALUE_FORMATS, D as validateModel, N as referencedTables, S as AGGREGATION_LABEL, T as isAggregate, _ as canonicalJson, a as FILTER_FIELDS, b as toModelCode, c as chartOfType, d as filterReferences, g as validateLayout, i as CARD_FIELDS, j as parseColumnRef, k as measureHome, l as chartReferences, m as layoutModelWarnings, n as CANVAS_PRESETS, p as layoutFileContent, r as CARDS_FIELDS, s as chartColumns, t as BUILTIN_CHART_TYPES, x as AGGREGATIONS } from "./layout-676sEvvb.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-Y7W9oK1J.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, TableSortLabel, 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";
|
|
@@ -1656,6 +1656,7 @@ function ChartForm({ chart, cards, types, model, formatters, columns, onChange }
|
|
|
1656
1656
|
columns: chartColumns(chart, types),
|
|
1657
1657
|
formColumns: columns,
|
|
1658
1658
|
chosenDimensions: chartReferences(chart, types).dimensions,
|
|
1659
|
+
chosenMeasures: chartReferences(chart, types).measures,
|
|
1659
1660
|
header: /* @__PURE__ */ jsxs(Fragment, { children: [field("Tipo", /* @__PURE__ */ jsxs(TextField, {
|
|
1660
1661
|
select: true,
|
|
1661
1662
|
size: "small",
|
|
@@ -1703,7 +1704,7 @@ function FilterForm({ filter, model, formatters, columns, onChange }) {
|
|
|
1703
1704
|
});
|
|
1704
1705
|
}
|
|
1705
1706
|
/** Formulário gerado dos `FieldSpec` (campos do tipo de gráfico ou do filtro). */
|
|
1706
|
-
function FieldsForm({ fields, values, onSet: set, model, formatters, columns, formColumns, chosenDimensions, header }) {
|
|
1707
|
+
function FieldsForm({ fields, values, onSet: set, model, formatters, columns, formColumns, chosenDimensions, chosenMeasures = [], header }) {
|
|
1707
1708
|
const dimensions = Object.entries(model.dimensions).map(([name, dim]) => ({
|
|
1708
1709
|
name,
|
|
1709
1710
|
label: dim.label
|
|
@@ -1742,37 +1743,11 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, fo
|
|
|
1742
1743
|
onChange: (e) => set(key, e.target.value),
|
|
1743
1744
|
sx: inputSx$1
|
|
1744
1745
|
});
|
|
1745
|
-
case "color": {
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
gap: .5,
|
|
1751
|
-
alignItems: "center"
|
|
1752
|
-
},
|
|
1753
|
-
children: [/* @__PURE__ */ jsx(Box, {
|
|
1754
|
-
component: "input",
|
|
1755
|
-
type: "color",
|
|
1756
|
-
value: value ?? fallback,
|
|
1757
|
-
onChange: (e) => set(key, e.target.value),
|
|
1758
|
-
sx: {
|
|
1759
|
-
width: 32,
|
|
1760
|
-
height: 30,
|
|
1761
|
-
p: 0,
|
|
1762
|
-
border: 0,
|
|
1763
|
-
bgcolor: "transparent",
|
|
1764
|
-
cursor: "pointer"
|
|
1765
|
-
}
|
|
1766
|
-
}), /* @__PURE__ */ jsx(TextField, {
|
|
1767
|
-
size: "small",
|
|
1768
|
-
fullWidth: true,
|
|
1769
|
-
value: value ?? "",
|
|
1770
|
-
placeholder: fallback,
|
|
1771
|
-
onChange: (e) => set(key, e.target.value),
|
|
1772
|
-
sx: inputSx$1
|
|
1773
|
-
})]
|
|
1774
|
-
});
|
|
1775
|
-
}
|
|
1746
|
+
case "color": return /* @__PURE__ */ jsx(ColorInput, {
|
|
1747
|
+
value,
|
|
1748
|
+
fallback: spec.default,
|
|
1749
|
+
onCommit: (color) => set(key, color)
|
|
1750
|
+
});
|
|
1776
1751
|
case "boolean": {
|
|
1777
1752
|
const fallback = spec.default;
|
|
1778
1753
|
return /* @__PURE__ */ jsx(FormControlLabel, {
|
|
@@ -1863,6 +1838,34 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, fo
|
|
|
1863
1838
|
}, dimension))
|
|
1864
1839
|
});
|
|
1865
1840
|
}
|
|
1841
|
+
case "labels":
|
|
1842
|
+
if (!columns.length) return /* @__PURE__ */ jsx(Typography, {
|
|
1843
|
+
sx: {
|
|
1844
|
+
fontSize: 12,
|
|
1845
|
+
color: "text.disabled"
|
|
1846
|
+
},
|
|
1847
|
+
children: "sem colunas"
|
|
1848
|
+
});
|
|
1849
|
+
return /* @__PURE__ */ jsx(LabelsEditor, {
|
|
1850
|
+
value: value ?? {},
|
|
1851
|
+
columns,
|
|
1852
|
+
model,
|
|
1853
|
+
onChange: (next) => set(key, next)
|
|
1854
|
+
});
|
|
1855
|
+
case "formats":
|
|
1856
|
+
if (!chosenMeasures.length) return /* @__PURE__ */ jsx(Typography, {
|
|
1857
|
+
sx: {
|
|
1858
|
+
fontSize: 12,
|
|
1859
|
+
color: "text.disabled"
|
|
1860
|
+
},
|
|
1861
|
+
children: "sem medidas"
|
|
1862
|
+
});
|
|
1863
|
+
return /* @__PURE__ */ jsx(FormatsEditor, {
|
|
1864
|
+
value: value ?? {},
|
|
1865
|
+
measures: chosenMeasures,
|
|
1866
|
+
model,
|
|
1867
|
+
onChange: (next) => set(key, next)
|
|
1868
|
+
});
|
|
1866
1869
|
default: return /* @__PURE__ */ jsx(NameSelect, {
|
|
1867
1870
|
value: value ?? "",
|
|
1868
1871
|
options: options(spec),
|
|
@@ -1873,7 +1876,7 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, fo
|
|
|
1873
1876
|
}
|
|
1874
1877
|
};
|
|
1875
1878
|
const sections = [...new Set(entries.map(([, spec]) => spec.section))];
|
|
1876
|
-
const wide = (spec, key) => key === "title" || spec.kind === "dimensions" || spec.kind === "measures" || spec.kind === "formatters";
|
|
1879
|
+
const wide = (spec, key) => key === "title" || spec.kind === "dimensions" || spec.kind === "measures" || spec.kind === "formatters" || spec.kind === "labels" || spec.kind === "formats";
|
|
1877
1880
|
return /* @__PURE__ */ jsx(Fragment, { children: sections.map((section) => {
|
|
1878
1881
|
const inSection = entries.filter(([, spec]) => spec.section === section);
|
|
1879
1882
|
return /* @__PURE__ */ jsx(Section, {
|
|
@@ -1892,17 +1895,246 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, fo
|
|
|
1892
1895
|
}, section);
|
|
1893
1896
|
}) });
|
|
1894
1897
|
}
|
|
1898
|
+
/**
|
|
1899
|
+
* Cor com o seletor nativo. Mexer no seletor só muda a amostra: o rascunho (e a página) muda quando
|
|
1900
|
+
* ele fecha — o `change` nativo; o `onChange` do React dispara a cada movimento. O texto aplica no
|
|
1901
|
+
* Enter ou ao sair do campo.
|
|
1902
|
+
*/
|
|
1903
|
+
function ColorInput({ value, fallback, onCommit }) {
|
|
1904
|
+
const [picking, setPicking] = useState(null);
|
|
1905
|
+
const [typing, setTyping] = useState(null);
|
|
1906
|
+
const picker = useRef(null);
|
|
1907
|
+
const commit = useRef(onCommit);
|
|
1908
|
+
useEffect(() => {
|
|
1909
|
+
commit.current = onCommit;
|
|
1910
|
+
});
|
|
1911
|
+
useEffect(() => {
|
|
1912
|
+
const input = picker.current;
|
|
1913
|
+
if (!input) return;
|
|
1914
|
+
const listener = () => {
|
|
1915
|
+
commit.current(input.value);
|
|
1916
|
+
setPicking(null);
|
|
1917
|
+
};
|
|
1918
|
+
input.addEventListener("change", listener);
|
|
1919
|
+
return () => input.removeEventListener("change", listener);
|
|
1920
|
+
}, []);
|
|
1921
|
+
const commitText = () => {
|
|
1922
|
+
if (typing === null) return;
|
|
1923
|
+
const text = typing.trim();
|
|
1924
|
+
setTyping(null);
|
|
1925
|
+
if (text !== (value ?? "")) onCommit(text || void 0);
|
|
1926
|
+
};
|
|
1927
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
1928
|
+
sx: {
|
|
1929
|
+
display: "flex",
|
|
1930
|
+
gap: .5,
|
|
1931
|
+
alignItems: "center"
|
|
1932
|
+
},
|
|
1933
|
+
children: [/* @__PURE__ */ jsx(Box, {
|
|
1934
|
+
component: "input",
|
|
1935
|
+
type: "color",
|
|
1936
|
+
ref: picker,
|
|
1937
|
+
value: picking ?? value ?? fallback,
|
|
1938
|
+
onChange: (e) => setPicking(e.target.value),
|
|
1939
|
+
sx: {
|
|
1940
|
+
width: 32,
|
|
1941
|
+
height: 30,
|
|
1942
|
+
p: 0,
|
|
1943
|
+
border: 0,
|
|
1944
|
+
bgcolor: "transparent",
|
|
1945
|
+
cursor: "pointer"
|
|
1946
|
+
}
|
|
1947
|
+
}), /* @__PURE__ */ jsx(TextField, {
|
|
1948
|
+
size: "small",
|
|
1949
|
+
fullWidth: true,
|
|
1950
|
+
value: typing ?? picking ?? value ?? "",
|
|
1951
|
+
placeholder: fallback,
|
|
1952
|
+
onChange: (e) => setTyping(e.target.value),
|
|
1953
|
+
onBlur: commitText,
|
|
1954
|
+
onKeyDown: (e) => {
|
|
1955
|
+
if (e.key === "Enter") commitText();
|
|
1956
|
+
if (e.key === "Escape") setTyping(null);
|
|
1957
|
+
},
|
|
1958
|
+
sx: inputSx$1
|
|
1959
|
+
})]
|
|
1960
|
+
});
|
|
1961
|
+
}
|
|
1962
|
+
/** Sem as chaves de colunas que saíram do gráfico; vazio = `undefined` (sai do JSON). */
|
|
1963
|
+
function pruned(map, keep) {
|
|
1964
|
+
const next = Object.fromEntries(Object.entries(map).filter(([key]) => keep.includes(key)));
|
|
1965
|
+
return Object.keys(next).length ? next : void 0;
|
|
1966
|
+
}
|
|
1967
|
+
const columnNameSx = {
|
|
1968
|
+
fontFamily: MONO,
|
|
1969
|
+
fontSize: 12,
|
|
1970
|
+
minWidth: 90,
|
|
1971
|
+
maxWidth: 140,
|
|
1972
|
+
overflow: "hidden",
|
|
1973
|
+
textOverflow: "ellipsis",
|
|
1974
|
+
whiteSpace: "nowrap"
|
|
1975
|
+
};
|
|
1976
|
+
/** Rótulo de cada coluna do gráfico; o placeholder é o rótulo do dicionário. */
|
|
1977
|
+
function LabelsEditor({ value, columns, model, onChange }) {
|
|
1978
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
1979
|
+
sx: {
|
|
1980
|
+
display: "flex",
|
|
1981
|
+
flexDirection: "column",
|
|
1982
|
+
gap: .5
|
|
1983
|
+
},
|
|
1984
|
+
children: columns.map((column) => /* @__PURE__ */ jsxs(Box, {
|
|
1985
|
+
sx: {
|
|
1986
|
+
display: "flex",
|
|
1987
|
+
gap: .5,
|
|
1988
|
+
alignItems: "center"
|
|
1989
|
+
},
|
|
1990
|
+
children: [/* @__PURE__ */ jsx(Tooltip, {
|
|
1991
|
+
title: model.dimensions[column] ? "dimensão" : "medida",
|
|
1992
|
+
placement: "left",
|
|
1993
|
+
children: /* @__PURE__ */ jsx(Typography, {
|
|
1994
|
+
sx: columnNameSx,
|
|
1995
|
+
children: column
|
|
1996
|
+
})
|
|
1997
|
+
}), /* @__PURE__ */ jsx(TextField, {
|
|
1998
|
+
size: "small",
|
|
1999
|
+
fullWidth: true,
|
|
2000
|
+
value: value[column] ?? "",
|
|
2001
|
+
placeholder: model.dimensions[column]?.label ?? model.measures[column]?.label ?? column,
|
|
2002
|
+
onChange: (e) => onChange(pruned(withField(value, column, e.target.value), columns)),
|
|
2003
|
+
sx: inputSx$1
|
|
2004
|
+
})]
|
|
2005
|
+
}, column))
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
const FORMAT_LABEL = {
|
|
2009
|
+
number: "número",
|
|
2010
|
+
integer: "inteiro",
|
|
2011
|
+
currency: "R$",
|
|
2012
|
+
percent: "%"
|
|
2013
|
+
};
|
|
2014
|
+
/** Formato de cada medida do gráfico; vazio = o do dicionário (que aparece como placeholder). */
|
|
2015
|
+
function FormatsEditor({ value, measures, model, onChange }) {
|
|
2016
|
+
const setFormat = (measure, key, next) => {
|
|
2017
|
+
const format = withField(value[measure] ?? {}, key, next);
|
|
2018
|
+
const map = { ...value };
|
|
2019
|
+
if (Object.keys(format).length) map[measure] = format;
|
|
2020
|
+
else delete map[measure];
|
|
2021
|
+
onChange(pruned(map, measures));
|
|
2022
|
+
};
|
|
2023
|
+
const small = {
|
|
2024
|
+
...inputSx$1,
|
|
2025
|
+
"& .MuiInputBase-input": {
|
|
2026
|
+
fontFamily: MONO,
|
|
2027
|
+
fontSize: 12,
|
|
2028
|
+
px: 1
|
|
2029
|
+
}
|
|
2030
|
+
};
|
|
2031
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
2032
|
+
sx: {
|
|
2033
|
+
display: "flex",
|
|
2034
|
+
flexDirection: "column",
|
|
2035
|
+
gap: .75
|
|
2036
|
+
},
|
|
2037
|
+
children: measures.map((measure) => {
|
|
2038
|
+
const format = value[measure] ?? {};
|
|
2039
|
+
const fromModel = model.measures[measure];
|
|
2040
|
+
const decimals = format.decimals;
|
|
2041
|
+
return /* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsxs(Typography, {
|
|
2042
|
+
sx: {
|
|
2043
|
+
...columnNameSx,
|
|
2044
|
+
maxWidth: "none",
|
|
2045
|
+
mb: .25
|
|
2046
|
+
},
|
|
2047
|
+
children: [measure, fromModel?.label && /* @__PURE__ */ jsx(Box, {
|
|
2048
|
+
component: "span",
|
|
2049
|
+
sx: {
|
|
2050
|
+
color: "text.secondary",
|
|
2051
|
+
ml: 1,
|
|
2052
|
+
fontFamily: "inherit"
|
|
2053
|
+
},
|
|
2054
|
+
children: fromModel.label
|
|
2055
|
+
})]
|
|
2056
|
+
}), /* @__PURE__ */ jsxs(Box, {
|
|
2057
|
+
sx: {
|
|
2058
|
+
display: "grid",
|
|
2059
|
+
gap: .5,
|
|
2060
|
+
alignItems: "center",
|
|
2061
|
+
gridTemplateColumns: "minmax(88px, 1.4fr) minmax(52px, .8fr) 1fr 1fr auto"
|
|
2062
|
+
},
|
|
2063
|
+
children: [
|
|
2064
|
+
/* @__PURE__ */ jsxs(TextField, {
|
|
2065
|
+
select: true,
|
|
2066
|
+
size: "small",
|
|
2067
|
+
value: format.format ?? "",
|
|
2068
|
+
onChange: (e) => setFormat(measure, "format", e.target.value || void 0),
|
|
2069
|
+
slotProps: { select: { displayEmpty: true } },
|
|
2070
|
+
sx: small,
|
|
2071
|
+
children: [/* @__PURE__ */ jsx(MenuItem, {
|
|
2072
|
+
value: "",
|
|
2073
|
+
children: /* @__PURE__ */ jsxs("em", { children: ["padrão", fromModel?.format ? ` (${FORMAT_LABEL[fromModel.format]})` : ""] })
|
|
2074
|
+
}), VALUE_FORMATS.map((name) => /* @__PURE__ */ jsx(MenuItem, {
|
|
2075
|
+
value: name,
|
|
2076
|
+
children: FORMAT_LABEL[name]
|
|
2077
|
+
}, name))]
|
|
2078
|
+
}),
|
|
2079
|
+
/* @__PURE__ */ jsx(Tooltip, {
|
|
2080
|
+
title: "Casas decimais (0 a 10)",
|
|
2081
|
+
children: /* @__PURE__ */ jsx(TextField, {
|
|
2082
|
+
size: "small",
|
|
2083
|
+
type: "number",
|
|
2084
|
+
value: decimals ?? "",
|
|
2085
|
+
placeholder: fromModel?.decimals === void 0 ? ",00" : String(fromModel.decimals),
|
|
2086
|
+
error: decimals !== void 0 && (!Number.isInteger(decimals) || decimals < 0 || decimals > 10),
|
|
2087
|
+
onChange: (e) => setFormat(measure, "decimals", e.target.value.trim() === "" ? void 0 : Number(e.target.value)),
|
|
2088
|
+
slotProps: { htmlInput: {
|
|
2089
|
+
min: 0,
|
|
2090
|
+
max: 10
|
|
2091
|
+
} },
|
|
2092
|
+
sx: small
|
|
2093
|
+
})
|
|
2094
|
+
}),
|
|
2095
|
+
/* @__PURE__ */ jsx(TextField, {
|
|
2096
|
+
size: "small",
|
|
2097
|
+
value: format.prefix ?? "",
|
|
2098
|
+
placeholder: "prefixo",
|
|
2099
|
+
onChange: (e) => setFormat(measure, "prefix", e.target.value),
|
|
2100
|
+
sx: small
|
|
2101
|
+
}),
|
|
2102
|
+
/* @__PURE__ */ jsx(TextField, {
|
|
2103
|
+
size: "small",
|
|
2104
|
+
value: format.suffix ?? "",
|
|
2105
|
+
placeholder: "sufixo",
|
|
2106
|
+
onChange: (e) => setFormat(measure, "suffix", e.target.value),
|
|
2107
|
+
sx: small
|
|
2108
|
+
}),
|
|
2109
|
+
/* @__PURE__ */ jsx(Tooltip, {
|
|
2110
|
+
title: "Notação curta: 1,2 mil / 3,4 mi",
|
|
2111
|
+
children: /* @__PURE__ */ jsx(FormControlLabel, {
|
|
2112
|
+
sx: { m: 0 },
|
|
2113
|
+
control: /* @__PURE__ */ jsx(Checkbox, {
|
|
2114
|
+
size: "small",
|
|
2115
|
+
sx: { p: .25 },
|
|
2116
|
+
checked: format.compact ?? false,
|
|
2117
|
+
onChange: (e) => setFormat(measure, "compact", e.target.checked || void 0)
|
|
2118
|
+
}),
|
|
2119
|
+
label: /* @__PURE__ */ jsx(Typography, {
|
|
2120
|
+
sx: { fontSize: 11 },
|
|
2121
|
+
children: "curto"
|
|
2122
|
+
})
|
|
2123
|
+
})
|
|
2124
|
+
})
|
|
2125
|
+
]
|
|
2126
|
+
})] }, measure);
|
|
2127
|
+
})
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
1895
2130
|
const formGrid = (columns) => ({
|
|
1896
2131
|
display: "grid",
|
|
1897
2132
|
gap: 1.5,
|
|
1898
2133
|
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
|
|
1899
2134
|
});
|
|
1900
|
-
/** Rótulo padrão (do dicionário) como placeholder
|
|
2135
|
+
/** Rótulo padrão (do dicionário) como placeholder do `label` do filtro. */
|
|
1901
2136
|
function labelPlaceholder(key, values, model) {
|
|
1902
2137
|
if (key === "label" && typeof values.dimension === "string") return model.dimensions[values.dimension]?.label ?? values.dimension;
|
|
1903
|
-
const measureKey = key.endsWith("Label") ? key.slice(0, -5) : null;
|
|
1904
|
-
const measure = measureKey && values[measureKey];
|
|
1905
|
-
return typeof measure === "string" ? model.measures[measure]?.label ?? measure : void 0;
|
|
1906
2138
|
}
|
|
1907
2139
|
function field(label, input, hint) {
|
|
1908
2140
|
return /* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsxs(Typography, {
|
|
@@ -2034,10 +2266,7 @@ function toEditor(model) {
|
|
|
2034
2266
|
const uidOf = (name) => tables.find((table) => table.name === name)?.uid ?? "";
|
|
2035
2267
|
const positions = Object.fromEntries(Object.entries(model.diagram ?? {}).flatMap(([name, point]) => {
|
|
2036
2268
|
const uid = uidOf(name);
|
|
2037
|
-
return uid ? [[uid, {
|
|
2038
|
-
x: point.x,
|
|
2039
|
-
y: point.y
|
|
2040
|
-
}]] : [];
|
|
2269
|
+
return uid ? [[uid, { ...point }]] : [];
|
|
2041
2270
|
}));
|
|
2042
2271
|
return {
|
|
2043
2272
|
name: model.name,
|
|
@@ -2132,14 +2361,18 @@ function fromEditor(editor) {
|
|
|
2132
2361
|
...Object.keys(diagram).length && { diagram }
|
|
2133
2362
|
};
|
|
2134
2363
|
}
|
|
2135
|
-
/** Posições pelo nome, na ordem dos cards; arredonda (o arquivo não precisa de frações). */
|
|
2364
|
+
/** Posições (e tamanhos) pelo nome, na ordem dos cards; arredonda (o arquivo não precisa de frações). */
|
|
2136
2365
|
function diagramOf(editor) {
|
|
2137
2366
|
return Object.fromEntries(editor.tables.flatMap(({ uid, name }) => {
|
|
2138
2367
|
const point = editor.positions[uid];
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2368
|
+
if (!point || !name) return [];
|
|
2369
|
+
const { x, y, width, height } = point;
|
|
2370
|
+
return [[name, {
|
|
2371
|
+
x: Math.round(x),
|
|
2372
|
+
y: Math.round(y),
|
|
2373
|
+
...width !== void 0 && { width: Math.round(width) },
|
|
2374
|
+
...height !== void 0 && { height: Math.round(height) }
|
|
2375
|
+
}]];
|
|
2143
2376
|
}));
|
|
2144
2377
|
}
|
|
2145
2378
|
/** O modelo sem as posições do diagrama: o que muda as consultas. */
|
|
@@ -2918,6 +3151,11 @@ const HEADER = 34;
|
|
|
2918
3151
|
const ROW = 22;
|
|
2919
3152
|
const MAX_BODY = 264;
|
|
2920
3153
|
const PADDING = 4;
|
|
3154
|
+
/** Limites do redimensionamento do card. */
|
|
3155
|
+
const MIN_WIDTH = 160;
|
|
3156
|
+
const MAX_WIDTH = 800;
|
|
3157
|
+
const MIN_HEIGHT$1 = 64;
|
|
3158
|
+
const MAX_HEIGHT = 1600;
|
|
2921
3159
|
const ROLE_STYLE = {
|
|
2922
3160
|
one: {
|
|
2923
3161
|
color: "#4dabf7",
|
|
@@ -3034,25 +3272,27 @@ function buildNodes(editor, columns, errors) {
|
|
|
3034
3272
|
};
|
|
3035
3273
|
});
|
|
3036
3274
|
}
|
|
3037
|
-
|
|
3275
|
+
/** Altura do conteúdo (sem tamanho salvo): até `MAX_BODY` de linhas, o resto rola. */
|
|
3276
|
+
const contentHeight = (node) => HEADER + Math.min(node.items.length * ROW, MAX_BODY) + 8;
|
|
3277
|
+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
3038
3278
|
/** Quem só filtra (lado 1) em cima, o resto embaixo (como costuma ficar no Power BI). */
|
|
3039
|
-
function autoLayout(nodes,
|
|
3279
|
+
function autoLayout(nodes, sizes) {
|
|
3040
3280
|
const top = nodes.filter((node) => node.role === "one");
|
|
3041
3281
|
const bottom = nodes.filter((node) => node.role !== "one");
|
|
3042
3282
|
const positions = {};
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3283
|
+
const gap = 60;
|
|
3284
|
+
const row = (list, y) => {
|
|
3285
|
+
let x = 40;
|
|
3286
|
+
for (const node of list) {
|
|
3287
|
+
positions[node.id] = {
|
|
3288
|
+
x,
|
|
3289
|
+
y
|
|
3290
|
+
};
|
|
3291
|
+
x += (sizes.get(node.id)?.width ?? CARD_WIDTH) + gap;
|
|
3292
|
+
}
|
|
3293
|
+
};
|
|
3294
|
+
row(top, 40);
|
|
3295
|
+
row(bottom, 40 + Math.max(0, ...top.map((node) => sizes.get(node.id)?.height ?? HEADER)) + 140);
|
|
3056
3296
|
return positions;
|
|
3057
3297
|
}
|
|
3058
3298
|
function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingColumns, onLoadColumns, onTry, usage }) {
|
|
@@ -3062,6 +3302,7 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3062
3302
|
errors
|
|
3063
3303
|
]);
|
|
3064
3304
|
const [moving, setMoving] = useState(null);
|
|
3305
|
+
const [resizing, setResizing] = useState(null);
|
|
3065
3306
|
const [collapsed, setCollapsed] = useState({});
|
|
3066
3307
|
const [scrolls, setScrolls] = useState({});
|
|
3067
3308
|
const [view, setView] = useState({
|
|
@@ -3099,9 +3340,39 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3099
3340
|
requested.current = true;
|
|
3100
3341
|
onLoadColumns();
|
|
3101
3342
|
}, [columns, onLoadColumns]);
|
|
3102
|
-
const
|
|
3103
|
-
|
|
3104
|
-
|
|
3343
|
+
const sizes = useMemo(() => new Map(nodes.map((node) => {
|
|
3344
|
+
const saved = resizing?.id === node.id ? resizing : editor.positions[node.id];
|
|
3345
|
+
const width = saved?.width ?? CARD_WIDTH;
|
|
3346
|
+
if (collapsed[node.id]) return [node.id, {
|
|
3347
|
+
width,
|
|
3348
|
+
height: HEADER
|
|
3349
|
+
}];
|
|
3350
|
+
return [node.id, {
|
|
3351
|
+
width,
|
|
3352
|
+
height: saved?.height ?? contentHeight(node)
|
|
3353
|
+
}];
|
|
3354
|
+
})), [
|
|
3355
|
+
nodes,
|
|
3356
|
+
collapsed,
|
|
3357
|
+
editor.positions,
|
|
3358
|
+
resizing
|
|
3359
|
+
]);
|
|
3360
|
+
const sizeOf = (node) => sizes.get(node.id) ?? {
|
|
3361
|
+
width: CARD_WIDTH,
|
|
3362
|
+
height: HEADER
|
|
3363
|
+
};
|
|
3364
|
+
const fallback = useMemo(() => autoLayout(nodes, sizes), [nodes, sizes]);
|
|
3365
|
+
const placed = (node) => {
|
|
3366
|
+
if (moving?.id === node.id) return moving.point;
|
|
3367
|
+
const saved = editor.positions[node.id];
|
|
3368
|
+
return saved ? {
|
|
3369
|
+
x: saved.x,
|
|
3370
|
+
y: saved.y
|
|
3371
|
+
} : fallback[node.id] ?? {
|
|
3372
|
+
x: 0,
|
|
3373
|
+
y: 0
|
|
3374
|
+
};
|
|
3375
|
+
};
|
|
3105
3376
|
const setPositions = (update) => setEditor((current) => ({
|
|
3106
3377
|
...current,
|
|
3107
3378
|
positions: update(current.positions)
|
|
@@ -3110,7 +3381,7 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3110
3381
|
/** Ponto da linha na coluna do card (lado esquerdo ou direito). */
|
|
3111
3382
|
const anchor = (node, column, side) => {
|
|
3112
3383
|
const { x, y } = placed(node);
|
|
3113
|
-
const height =
|
|
3384
|
+
const { width, height } = sizeOf(node);
|
|
3114
3385
|
const index = node.items.findIndex((item) => item.kind === "column" && item.name === column);
|
|
3115
3386
|
let rowY = y + HEADER / 2;
|
|
3116
3387
|
if (!collapsed[node.id] && index >= 0) {
|
|
@@ -3118,7 +3389,7 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3118
3389
|
rowY = Math.min(Math.max(raw, y + HEADER + 2), y + height - 2);
|
|
3119
3390
|
}
|
|
3120
3391
|
return {
|
|
3121
|
-
x: side === "left" ? x : x +
|
|
3392
|
+
x: side === "left" ? x : x + width,
|
|
3122
3393
|
y: rowY
|
|
3123
3394
|
};
|
|
3124
3395
|
};
|
|
@@ -3298,11 +3569,56 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3298
3569
|
setMoving(null);
|
|
3299
3570
|
if (moved) setPositions((current) => ({
|
|
3300
3571
|
...current,
|
|
3301
|
-
[node.id]:
|
|
3572
|
+
[node.id]: {
|
|
3573
|
+
...current[node.id],
|
|
3574
|
+
...point
|
|
3575
|
+
}
|
|
3302
3576
|
}));
|
|
3303
3577
|
else selectNode(node);
|
|
3304
3578
|
});
|
|
3305
3579
|
};
|
|
3580
|
+
/** Arrasta a borda direita (`width`), a de baixo (`height`) ou o canto (as duas). */
|
|
3581
|
+
const startResize = (event, node, edges) => {
|
|
3582
|
+
if (event.button !== 0) return;
|
|
3583
|
+
const start = sizeOf(node);
|
|
3584
|
+
const { zoom } = view;
|
|
3585
|
+
let size = start;
|
|
3586
|
+
track(event, (dx, dy) => {
|
|
3587
|
+
size = {
|
|
3588
|
+
width: edges.width ? clamp(start.width + dx / zoom, MIN_WIDTH, MAX_WIDTH) : start.width,
|
|
3589
|
+
height: edges.height ? clamp(start.height + dy / zoom, MIN_HEIGHT$1, MAX_HEIGHT) : start.height
|
|
3590
|
+
};
|
|
3591
|
+
setResizing({
|
|
3592
|
+
id: node.id,
|
|
3593
|
+
...size
|
|
3594
|
+
});
|
|
3595
|
+
}, (_, moved) => {
|
|
3596
|
+
setResizing(null);
|
|
3597
|
+
if (!moved) return;
|
|
3598
|
+
const point = placed(node);
|
|
3599
|
+
setPositions((current) => ({
|
|
3600
|
+
...current,
|
|
3601
|
+
[node.id]: {
|
|
3602
|
+
...point,
|
|
3603
|
+
...current[node.id],
|
|
3604
|
+
...edges.width && { width: size.width },
|
|
3605
|
+
...edges.height && { height: size.height }
|
|
3606
|
+
}
|
|
3607
|
+
}));
|
|
3608
|
+
});
|
|
3609
|
+
};
|
|
3610
|
+
/** Duplo clique na alça: volta ao tamanho automático (largura padrão, altura do conteúdo). */
|
|
3611
|
+
const resetSize = (node) => setPositions((current) => {
|
|
3612
|
+
const saved = current[node.id];
|
|
3613
|
+
if (!saved) return current;
|
|
3614
|
+
return {
|
|
3615
|
+
...current,
|
|
3616
|
+
[node.id]: {
|
|
3617
|
+
x: saved.x,
|
|
3618
|
+
y: saved.y
|
|
3619
|
+
}
|
|
3620
|
+
};
|
|
3621
|
+
});
|
|
3306
3622
|
const startLink = (event, node, column) => {
|
|
3307
3623
|
if (event.button !== 0) return;
|
|
3308
3624
|
track(event, (_, __, moveEvent) => setLinking({
|
|
@@ -3355,11 +3671,12 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3355
3671
|
if (!rect || !nodes.length) return;
|
|
3356
3672
|
const boxes = nodes.map((node) => ({
|
|
3357
3673
|
...layout?.[node.id] ?? placed(node),
|
|
3358
|
-
|
|
3674
|
+
w: sizeOf(node).width,
|
|
3675
|
+
h: sizeOf(node).height
|
|
3359
3676
|
}));
|
|
3360
3677
|
const minX = Math.min(...boxes.map((box) => box.x));
|
|
3361
3678
|
const minY = Math.min(...boxes.map((box) => box.y));
|
|
3362
|
-
const maxX = Math.max(...boxes.map((box) => box.x +
|
|
3679
|
+
const maxX = Math.max(...boxes.map((box) => box.x + box.w));
|
|
3363
3680
|
const maxY = Math.max(...boxes.map((box) => box.y + box.h));
|
|
3364
3681
|
const zoom = Math.min(1.2, Math.max(.3, Math.min((rect.width - 60) / (maxX - minX), (rect.height - 60) / (maxY - minY))));
|
|
3365
3682
|
setView({
|
|
@@ -3375,7 +3692,7 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3375
3692
|
const isSelected = (node) => selection?.kind === "table" && selection.uid === node.uid;
|
|
3376
3693
|
const lines = [];
|
|
3377
3694
|
const pushLine = (id, many, manyColumn, one, oneColumn, extra) => {
|
|
3378
|
-
const rightward = placed(many).x +
|
|
3695
|
+
const rightward = placed(many).x + sizeOf(many).width / 2 <= placed(one).x + sizeOf(one).width / 2;
|
|
3379
3696
|
lines.push({
|
|
3380
3697
|
id,
|
|
3381
3698
|
from: anchor(many, manyColumn, rightward ? "right" : "left"),
|
|
@@ -3462,7 +3779,7 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3462
3779
|
}), nodes.map((node) => /* @__PURE__ */ jsx(TableCard, {
|
|
3463
3780
|
node,
|
|
3464
3781
|
position: placed(node),
|
|
3465
|
-
|
|
3782
|
+
size: sizeOf(node),
|
|
3466
3783
|
collapsed: !!collapsed[node.id],
|
|
3467
3784
|
selected: !!isSelected(node),
|
|
3468
3785
|
linking: !!linking && linking.node.id !== node.id,
|
|
@@ -3476,6 +3793,8 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3476
3793
|
[node.id]: top
|
|
3477
3794
|
})),
|
|
3478
3795
|
onHeaderDown: (event) => startMove(event, node),
|
|
3796
|
+
onResizeDown: (event, edges) => startResize(event, node, edges),
|
|
3797
|
+
onResizeReset: () => resetSize(node),
|
|
3479
3798
|
onColumnDown: (event, column) => startLink(event, node, column),
|
|
3480
3799
|
onFieldClick: (item) => setSelection({
|
|
3481
3800
|
kind: item.kind,
|
|
@@ -3532,8 +3851,11 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3532
3851
|
/* @__PURE__ */ jsx(Button, {
|
|
3533
3852
|
size: "small",
|
|
3534
3853
|
onClick: () => {
|
|
3535
|
-
const layout = autoLayout(nodes,
|
|
3536
|
-
setPositions(() => layout)
|
|
3854
|
+
const layout = autoLayout(nodes, sizes);
|
|
3855
|
+
setPositions((current) => Object.fromEntries(Object.entries(layout).map(([id, point]) => [id, {
|
|
3856
|
+
...current[id],
|
|
3857
|
+
...point
|
|
3858
|
+
}])));
|
|
3537
3859
|
fitToScreen(layout);
|
|
3538
3860
|
},
|
|
3539
3861
|
title: "Dimensões em cima, fatos embaixo (troca as posições salvas)",
|
|
@@ -3842,7 +4164,7 @@ function RelationshipLine({ line, hovered, onHover }) {
|
|
|
3842
4164
|
]
|
|
3843
4165
|
});
|
|
3844
4166
|
}
|
|
3845
|
-
function TableCard({ node, position,
|
|
4167
|
+
function TableCard({ node, position, size, collapsed, selected, linking, selectedField, onToggle, onScroll, onHeaderDown, onResizeDown, onResizeReset, onColumnDown, onFieldClick, onAddField }) {
|
|
3846
4168
|
const style = ROLE_STYLE[node.role];
|
|
3847
4169
|
const columnActions = ["dimension", "measure"];
|
|
3848
4170
|
return /* @__PURE__ */ jsxs(Box, {
|
|
@@ -3851,8 +4173,8 @@ function TableCard({ node, position, height, collapsed, selected, linking, selec
|
|
|
3851
4173
|
position: "absolute",
|
|
3852
4174
|
left: position.x,
|
|
3853
4175
|
top: position.y,
|
|
3854
|
-
width:
|
|
3855
|
-
height,
|
|
4176
|
+
width: size.width,
|
|
4177
|
+
height: size.height,
|
|
3856
4178
|
bgcolor: "#23272e",
|
|
3857
4179
|
border: "1px solid",
|
|
3858
4180
|
borderColor: node.error ? "error.main" : selected ? style.color : "#3a3f47",
|
|
@@ -3864,187 +4186,252 @@ function TableCard({ node, position, height, collapsed, selected, linking, selec
|
|
|
3864
4186
|
userSelect: "none",
|
|
3865
4187
|
cursor: "default"
|
|
3866
4188
|
},
|
|
3867
|
-
children: [
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
height: 31,
|
|
3872
|
-
display: "flex",
|
|
3873
|
-
alignItems: "center",
|
|
3874
|
-
gap: .75,
|
|
3875
|
-
px: 1,
|
|
3876
|
-
cursor: "move",
|
|
3877
|
-
borderBottom: collapsed ? 0 : "1px solid #3a3f47",
|
|
3878
|
-
flexShrink: 0
|
|
3879
|
-
},
|
|
3880
|
-
children: [
|
|
3881
|
-
/* @__PURE__ */ jsx(Box, {
|
|
3882
|
-
component: "span",
|
|
3883
|
-
sx: {
|
|
3884
|
-
color: style.color,
|
|
3885
|
-
fontSize: 13
|
|
3886
|
-
},
|
|
3887
|
-
children: "▦"
|
|
3888
|
-
}),
|
|
3889
|
-
/* @__PURE__ */ jsx(Typography, {
|
|
3890
|
-
sx: {
|
|
3891
|
-
fontWeight: 700,
|
|
3892
|
-
fontSize: 13,
|
|
3893
|
-
overflow: "hidden",
|
|
3894
|
-
textOverflow: "ellipsis",
|
|
3895
|
-
whiteSpace: "nowrap",
|
|
3896
|
-
flex: 1
|
|
3897
|
-
},
|
|
3898
|
-
children: node.name || /* @__PURE__ */ jsx("em", { children: "sem nome" })
|
|
3899
|
-
}),
|
|
3900
|
-
/* @__PURE__ */ jsx(Box, {
|
|
3901
|
-
component: "span",
|
|
3902
|
-
title: style.title,
|
|
3903
|
-
sx: {
|
|
3904
|
-
fontSize: 10,
|
|
3905
|
-
color: style.color
|
|
3906
|
-
},
|
|
3907
|
-
children: style.label
|
|
3908
|
-
}),
|
|
3909
|
-
node.error && /* @__PURE__ */ jsx(Box, {
|
|
3910
|
-
component: "span",
|
|
3911
|
-
sx: {
|
|
3912
|
-
color: "error.main",
|
|
3913
|
-
fontSize: 12
|
|
3914
|
-
},
|
|
3915
|
-
children: "⚠"
|
|
3916
|
-
}),
|
|
3917
|
-
/* @__PURE__ */ jsx(Box, {
|
|
3918
|
-
component: "button",
|
|
3919
|
-
type: "button",
|
|
3920
|
-
"aria-label": collapsed ? "Expandir" : "Recolher",
|
|
3921
|
-
onMouseDown: (event) => event.stopPropagation(),
|
|
3922
|
-
onClick: onToggle,
|
|
3923
|
-
sx: {
|
|
3924
|
-
border: 0,
|
|
3925
|
-
bgcolor: "transparent",
|
|
3926
|
-
color: "text.secondary",
|
|
3927
|
-
cursor: "pointer",
|
|
3928
|
-
p: 0,
|
|
3929
|
-
fontSize: 11
|
|
3930
|
-
},
|
|
3931
|
-
children: collapsed ? "▾" : "▴"
|
|
3932
|
-
})
|
|
3933
|
-
]
|
|
3934
|
-
}), !collapsed && /* @__PURE__ */ jsxs(Box, {
|
|
3935
|
-
onScroll: (event) => onScroll(event.currentTarget.scrollTop),
|
|
3936
|
-
sx: {
|
|
3937
|
-
overflow: "auto",
|
|
3938
|
-
flex: 1,
|
|
3939
|
-
py: `${PADDING}px`
|
|
3940
|
-
},
|
|
3941
|
-
children: [!node.items.length && /* @__PURE__ */ jsx(Typography, {
|
|
3942
|
-
sx: {
|
|
3943
|
-
fontSize: 11,
|
|
3944
|
-
color: "text.disabled",
|
|
3945
|
-
px: 1,
|
|
3946
|
-
lineHeight: `${ROW}px`
|
|
3947
|
-
},
|
|
3948
|
-
children: "sem colunas lidas"
|
|
3949
|
-
}), node.items.map((item) => item.kind === "column" ? /* @__PURE__ */ jsxs(Box, {
|
|
3950
|
-
"data-diagram-node": node.id,
|
|
3951
|
-
"data-diagram-column": item.name,
|
|
3952
|
-
onMouseDown: (event) => onColumnDown(event, item.name),
|
|
3953
|
-
title: item.missing ? "Citada no modelo, mas a tabela não devolve essa coluna" : "Arraste até a coluna de outra tabela para relacionar",
|
|
4189
|
+
children: [
|
|
4190
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
4191
|
+
onMouseDown: onHeaderDown,
|
|
4192
|
+
title: node.error,
|
|
3954
4193
|
sx: {
|
|
3955
|
-
height:
|
|
4194
|
+
height: 31,
|
|
3956
4195
|
display: "flex",
|
|
3957
4196
|
alignItems: "center",
|
|
3958
4197
|
gap: .75,
|
|
3959
4198
|
px: 1,
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
"&:hover .column-actions": { display: linking ? "none" : "flex" },
|
|
3964
|
-
color: item.missing ? "error.main" : item.linked ? "text.primary" : "#adb5bd",
|
|
3965
|
-
fontWeight: item.linked ? 700 : 400,
|
|
3966
|
-
"&:hover": { bgcolor: linking ? "rgba(245,130,32,.25)" : "rgba(255,255,255,.06)" }
|
|
4199
|
+
cursor: "move",
|
|
4200
|
+
borderBottom: collapsed ? 0 : "1px solid #3a3f47",
|
|
4201
|
+
flexShrink: 0
|
|
3967
4202
|
},
|
|
3968
4203
|
children: [
|
|
3969
4204
|
/* @__PURE__ */ jsx(Box, {
|
|
3970
4205
|
component: "span",
|
|
3971
4206
|
sx: {
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
color: "text.secondary"
|
|
4207
|
+
color: style.color,
|
|
4208
|
+
fontSize: 13
|
|
3975
4209
|
},
|
|
3976
|
-
children:
|
|
4210
|
+
children: "▦"
|
|
3977
4211
|
}),
|
|
3978
|
-
/* @__PURE__ */ jsx(
|
|
3979
|
-
component: "span",
|
|
4212
|
+
/* @__PURE__ */ jsx(Typography, {
|
|
3980
4213
|
sx: {
|
|
4214
|
+
fontWeight: 700,
|
|
4215
|
+
fontSize: 13,
|
|
3981
4216
|
overflow: "hidden",
|
|
3982
4217
|
textOverflow: "ellipsis",
|
|
3983
|
-
whiteSpace: "nowrap"
|
|
4218
|
+
whiteSpace: "nowrap",
|
|
4219
|
+
flex: 1
|
|
3984
4220
|
},
|
|
3985
|
-
children:
|
|
4221
|
+
children: node.name || /* @__PURE__ */ jsx("em", { children: "sem nome" })
|
|
3986
4222
|
}),
|
|
3987
4223
|
/* @__PURE__ */ jsx(Box, {
|
|
3988
|
-
|
|
4224
|
+
component: "span",
|
|
4225
|
+
title: style.title,
|
|
3989
4226
|
sx: {
|
|
3990
|
-
|
|
3991
|
-
|
|
4227
|
+
fontSize: 10,
|
|
4228
|
+
color: style.color
|
|
3992
4229
|
},
|
|
3993
|
-
children:
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4230
|
+
children: style.label
|
|
4231
|
+
}),
|
|
4232
|
+
node.error && /* @__PURE__ */ jsx(Box, {
|
|
4233
|
+
component: "span",
|
|
4234
|
+
sx: {
|
|
4235
|
+
color: "error.main",
|
|
4236
|
+
fontSize: 12
|
|
4237
|
+
},
|
|
4238
|
+
children: "⚠"
|
|
4239
|
+
}),
|
|
4240
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4241
|
+
component: "button",
|
|
4242
|
+
type: "button",
|
|
4243
|
+
"aria-label": collapsed ? "Expandir" : "Recolher",
|
|
4244
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
4245
|
+
onClick: onToggle,
|
|
4246
|
+
sx: {
|
|
4247
|
+
border: 0,
|
|
4248
|
+
bgcolor: "transparent",
|
|
4249
|
+
color: "text.secondary",
|
|
4250
|
+
cursor: "pointer",
|
|
4251
|
+
p: 0,
|
|
4252
|
+
fontSize: 11
|
|
4253
|
+
},
|
|
4254
|
+
children: collapsed ? "▾" : "▴"
|
|
4011
4255
|
})
|
|
4012
4256
|
]
|
|
4013
|
-
}
|
|
4014
|
-
|
|
4015
|
-
|
|
4257
|
+
}),
|
|
4258
|
+
!collapsed && /* @__PURE__ */ jsxs(Box, {
|
|
4259
|
+
onScroll: (event) => onScroll(event.currentTarget.scrollTop),
|
|
4016
4260
|
sx: {
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
gap: .75,
|
|
4021
|
-
px: 1,
|
|
4022
|
-
fontSize: 12,
|
|
4023
|
-
cursor: "pointer",
|
|
4024
|
-
color: item.kind === "measure" ? "#ffd8a8" : "#a5d8ff",
|
|
4025
|
-
bgcolor: selectedField === item.uid ? "rgba(245,130,32,.2)" : void 0,
|
|
4026
|
-
"&:hover": { bgcolor: "rgba(255,255,255,.06)" }
|
|
4261
|
+
overflow: "auto",
|
|
4262
|
+
flex: 1,
|
|
4263
|
+
py: `${PADDING}px`
|
|
4027
4264
|
},
|
|
4028
|
-
children: [/* @__PURE__ */ jsx(
|
|
4029
|
-
component: "span",
|
|
4265
|
+
children: [!node.items.length && /* @__PURE__ */ jsx(Typography, {
|
|
4030
4266
|
sx: {
|
|
4031
|
-
|
|
4032
|
-
|
|
4267
|
+
fontSize: 11,
|
|
4268
|
+
color: "text.disabled",
|
|
4269
|
+
px: 1,
|
|
4270
|
+
lineHeight: `${ROW}px`
|
|
4033
4271
|
},
|
|
4034
|
-
children:
|
|
4035
|
-
}), /* @__PURE__ */
|
|
4036
|
-
|
|
4272
|
+
children: "sem colunas lidas"
|
|
4273
|
+
}), node.items.map((item) => item.kind === "column" ? /* @__PURE__ */ jsxs(Box, {
|
|
4274
|
+
"data-diagram-node": node.id,
|
|
4275
|
+
"data-diagram-column": item.name,
|
|
4276
|
+
onMouseDown: (event) => onColumnDown(event, item.name),
|
|
4277
|
+
title: item.missing ? "Citada no modelo, mas a tabela não devolve essa coluna" : "Arraste até a coluna de outra tabela para relacionar",
|
|
4037
4278
|
sx: {
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4279
|
+
height: ROW,
|
|
4280
|
+
display: "flex",
|
|
4281
|
+
alignItems: "center",
|
|
4282
|
+
gap: .75,
|
|
4283
|
+
px: 1,
|
|
4284
|
+
fontSize: 12,
|
|
4285
|
+
cursor: "crosshair",
|
|
4286
|
+
"& .column-actions": { display: "none" },
|
|
4287
|
+
"&:hover .column-actions": { display: linking ? "none" : "flex" },
|
|
4288
|
+
color: item.missing ? "error.main" : item.linked ? "text.primary" : "#adb5bd",
|
|
4289
|
+
fontWeight: item.linked ? 700 : 400,
|
|
4290
|
+
"&:hover": { bgcolor: linking ? "rgba(245,130,32,.25)" : "rgba(255,255,255,.06)" }
|
|
4041
4291
|
},
|
|
4042
|
-
children:
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4292
|
+
children: [
|
|
4293
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4294
|
+
component: "span",
|
|
4295
|
+
sx: {
|
|
4296
|
+
width: 14,
|
|
4297
|
+
textAlign: "center",
|
|
4298
|
+
color: "text.secondary"
|
|
4299
|
+
},
|
|
4300
|
+
children: item.isKey ? "🔑" : item.numeric ? "Σ" : ""
|
|
4301
|
+
}),
|
|
4302
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4303
|
+
component: "span",
|
|
4304
|
+
sx: {
|
|
4305
|
+
overflow: "hidden",
|
|
4306
|
+
textOverflow: "ellipsis",
|
|
4307
|
+
whiteSpace: "nowrap"
|
|
4308
|
+
},
|
|
4309
|
+
children: item.name
|
|
4310
|
+
}),
|
|
4311
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4312
|
+
className: "column-actions",
|
|
4313
|
+
sx: {
|
|
4314
|
+
ml: "auto",
|
|
4315
|
+
gap: .25
|
|
4316
|
+
},
|
|
4317
|
+
children: columnActions.map((kind) => /* @__PURE__ */ jsx(Box, {
|
|
4318
|
+
component: "button",
|
|
4319
|
+
type: "button",
|
|
4320
|
+
title: kind === "dimension" ? `Nova dimensão com ${node.name}.${item.name}` : `Nova medida: ${item.numeric ? "soma" : "contagem"} de ${node.name}.${item.name}`,
|
|
4321
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
4322
|
+
onClick: () => onAddField(kind, item),
|
|
4323
|
+
sx: {
|
|
4324
|
+
border: "1px solid #3a3f47",
|
|
4325
|
+
borderRadius: .5,
|
|
4326
|
+
bgcolor: "#1b1e23",
|
|
4327
|
+
color: kind === "measure" ? "#ffd8a8" : "#a5d8ff",
|
|
4328
|
+
cursor: "pointer",
|
|
4329
|
+
fontSize: 10,
|
|
4330
|
+
lineHeight: "14px",
|
|
4331
|
+
px: .5
|
|
4332
|
+
},
|
|
4333
|
+
children: kind === "dimension" ? "+◇" : "+Σ"
|
|
4334
|
+
}, kind))
|
|
4335
|
+
})
|
|
4336
|
+
]
|
|
4337
|
+
}, `c:${item.name}`) : /* @__PURE__ */ jsxs(Box, {
|
|
4338
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
4339
|
+
onClick: () => onFieldClick(item),
|
|
4340
|
+
sx: {
|
|
4341
|
+
height: ROW,
|
|
4342
|
+
display: "flex",
|
|
4343
|
+
alignItems: "center",
|
|
4344
|
+
gap: .75,
|
|
4345
|
+
px: 1,
|
|
4346
|
+
fontSize: 12,
|
|
4347
|
+
cursor: "pointer",
|
|
4348
|
+
color: item.kind === "measure" ? "#ffd8a8" : "#a5d8ff",
|
|
4349
|
+
bgcolor: selectedField === item.uid ? "rgba(245,130,32,.2)" : void 0,
|
|
4350
|
+
"&:hover": { bgcolor: "rgba(255,255,255,.06)" }
|
|
4351
|
+
},
|
|
4352
|
+
children: [/* @__PURE__ */ jsx(Box, {
|
|
4353
|
+
component: "span",
|
|
4354
|
+
sx: {
|
|
4355
|
+
width: 14,
|
|
4356
|
+
textAlign: "center"
|
|
4357
|
+
},
|
|
4358
|
+
children: item.icon
|
|
4359
|
+
}), /* @__PURE__ */ jsx(Box, {
|
|
4360
|
+
component: "span",
|
|
4361
|
+
sx: {
|
|
4362
|
+
overflow: "hidden",
|
|
4363
|
+
textOverflow: "ellipsis",
|
|
4364
|
+
whiteSpace: "nowrap"
|
|
4365
|
+
},
|
|
4366
|
+
children: item.name || /* @__PURE__ */ jsx("em", { children: "sem nome" })
|
|
4367
|
+
})]
|
|
4368
|
+
}, `f:${item.uid}`))]
|
|
4369
|
+
}),
|
|
4370
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4371
|
+
onMouseDown: (event) => onResizeDown(event, {
|
|
4372
|
+
width: true,
|
|
4373
|
+
height: false
|
|
4374
|
+
}),
|
|
4375
|
+
onDoubleClick: onResizeReset,
|
|
4376
|
+
title: "Arraste para mudar a largura (duplo clique: tamanho automático)",
|
|
4377
|
+
sx: {
|
|
4378
|
+
...resizeHandleSx,
|
|
4379
|
+
top: 0,
|
|
4380
|
+
right: -4,
|
|
4381
|
+
bottom: 8,
|
|
4382
|
+
width: 8,
|
|
4383
|
+
cursor: "ew-resize"
|
|
4384
|
+
}
|
|
4385
|
+
}),
|
|
4386
|
+
!collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Box, {
|
|
4387
|
+
onMouseDown: (event) => onResizeDown(event, {
|
|
4388
|
+
width: false,
|
|
4389
|
+
height: true
|
|
4390
|
+
}),
|
|
4391
|
+
onDoubleClick: onResizeReset,
|
|
4392
|
+
title: "Arraste para mudar a altura (duplo clique: tamanho automático)",
|
|
4393
|
+
sx: {
|
|
4394
|
+
...resizeHandleSx,
|
|
4395
|
+
left: 0,
|
|
4396
|
+
right: 8,
|
|
4397
|
+
bottom: -4,
|
|
4398
|
+
height: 8,
|
|
4399
|
+
cursor: "ns-resize"
|
|
4400
|
+
}
|
|
4401
|
+
}), /* @__PURE__ */ jsx(Box, {
|
|
4402
|
+
onMouseDown: (event) => onResizeDown(event, {
|
|
4403
|
+
width: true,
|
|
4404
|
+
height: true
|
|
4405
|
+
}),
|
|
4406
|
+
onDoubleClick: onResizeReset,
|
|
4407
|
+
title: "Arraste para redimensionar (duplo clique: tamanho automático)",
|
|
4408
|
+
sx: {
|
|
4409
|
+
...resizeHandleSx,
|
|
4410
|
+
right: -4,
|
|
4411
|
+
bottom: -4,
|
|
4412
|
+
width: 14,
|
|
4413
|
+
height: 14,
|
|
4414
|
+
cursor: "nwse-resize",
|
|
4415
|
+
"&::after": {
|
|
4416
|
+
content: "\"\"",
|
|
4417
|
+
position: "absolute",
|
|
4418
|
+
right: 6,
|
|
4419
|
+
bottom: 6,
|
|
4420
|
+
width: 6,
|
|
4421
|
+
height: 6,
|
|
4422
|
+
borderRight: "2px solid #5c636e",
|
|
4423
|
+
borderBottom: "2px solid #5c636e"
|
|
4424
|
+
},
|
|
4425
|
+
"&:hover::after": { borderColor: ROLE_STYLE[node.role].color }
|
|
4426
|
+
}
|
|
4427
|
+
})] })
|
|
4428
|
+
]
|
|
4046
4429
|
});
|
|
4047
4430
|
}
|
|
4431
|
+
const resizeHandleSx = {
|
|
4432
|
+
position: "absolute",
|
|
4433
|
+
zIndex: 1
|
|
4434
|
+
};
|
|
4048
4435
|
function PropertyBlock({ title, children }) {
|
|
4049
4436
|
return /* @__PURE__ */ jsxs(Box, {
|
|
4050
4437
|
sx: {
|
|
@@ -6883,4 +7270,4 @@ function ToggleButton$1({ draft, loading, problems, inspecting, onOpen }) {
|
|
|
6883
7270
|
//#endregion
|
|
6884
7271
|
export { DashboardDevtools as default };
|
|
6885
7272
|
|
|
6886
|
-
//# sourceMappingURL=DashboardDevtools-
|
|
7273
|
+
//# sourceMappingURL=DashboardDevtools-7L93aV1-.js.map
|