@bluemarble/bi 0.2.0 → 0.3.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-5wh3brAT.js → DashboardDevtools-C8AXaFgw.js} +1155 -303
- package/dist/DashboardDevtools-C8AXaFgw.js.map +1 -0
- package/dist/{ModelDictionary-DN77UDVM.js → ModelDictionary-CBILYbZ1.js} +3 -3
- package/dist/{ModelDictionary-DN77UDVM.js.map → ModelDictionary-CBILYbZ1.js.map} +1 -1
- package/dist/client/index.d.ts +10 -2
- package/dist/client/index.js +55 -28
- package/dist/client/index.js.map +1 -1
- package/dist/{layout-DvHS8XFz.js → layout-DTR4vI-I.js} +120 -5
- package/dist/layout-DTR4vI-I.js.map +1 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +38 -8
- package/dist/server/index.js.map +1 -1
- package/dist/{types-BO_AQNxv.d.ts → types-DUJS2Zmx.d.ts} +39 -3
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/dist/DashboardDevtools-5wh3brAT.js.map +0 -1
- package/dist/layout-DvHS8XFz.js.map +0 -1
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { A as
|
|
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-DTR4vI-I.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-
|
|
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";
|
|
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-CBILYbZ1.js";
|
|
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";
|
|
7
|
+
//#region \0rolldown/runtime.js
|
|
8
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
9
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
7
14
|
//#region src/devtools/sqlHighlight.tsx
|
|
8
15
|
const KEYWORDS$1 = new Set(`SELECT FROM WHERE AND OR NOT IN IS NULL JOIN LEFT RIGHT INNER OUTER CROSS ON AS GROUP BY ORDER
|
|
9
16
|
HAVING LIMIT OFFSET UNION ALL DISTINCT CASE WHEN THEN ELSE END WITH ASC DESC BETWEEN LIKE EXISTS
|
|
@@ -91,9 +98,13 @@ function StatusDot({ status }) {
|
|
|
91
98
|
}
|
|
92
99
|
});
|
|
93
100
|
}
|
|
94
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Copia para a área de transferência. Com o devtools em janela separada, o clipboard tem que ser o
|
|
103
|
+
* dela (o da página não está em foco e recusa): passe o elemento clicado.
|
|
104
|
+
*/
|
|
105
|
+
async function copyText(text, from) {
|
|
95
106
|
try {
|
|
96
|
-
await navigator.clipboard.writeText(text);
|
|
107
|
+
await (from?.ownerDocument.defaultView ?? window).navigator.clipboard.writeText(text);
|
|
97
108
|
return true;
|
|
98
109
|
} catch {
|
|
99
110
|
return false;
|
|
@@ -103,8 +114,8 @@ function CopyButton({ text, label = "Copiar" }) {
|
|
|
103
114
|
const [copied, setCopied] = useState(false);
|
|
104
115
|
return /* @__PURE__ */ jsx(Button, {
|
|
105
116
|
size: "small",
|
|
106
|
-
onClick: async () => {
|
|
107
|
-
if (await copyText(text)) {
|
|
117
|
+
onClick: async (event) => {
|
|
118
|
+
if (await copyText(text, event.currentTarget)) {
|
|
108
119
|
setCopied(true);
|
|
109
120
|
setTimeout(() => setCopied(false), 1200);
|
|
110
121
|
}
|
|
@@ -112,9 +123,33 @@ function CopyButton({ text, label = "Copiar" }) {
|
|
|
112
123
|
children: copied ? "Copiado!" : label
|
|
113
124
|
});
|
|
114
125
|
}
|
|
115
|
-
|
|
126
|
+
const COLLAPSED_KEY = "bm-dashboard-devtools:collapsed";
|
|
127
|
+
function loadCollapsed() {
|
|
128
|
+
try {
|
|
129
|
+
const saved = JSON.parse(localStorage.getItem(COLLAPSED_KEY) ?? "[]");
|
|
130
|
+
return Array.isArray(saved) ? saved : [];
|
|
131
|
+
} catch {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** Seção recolhida (lembrada entre recargas, pela chave). */
|
|
136
|
+
function useCollapsed(key) {
|
|
137
|
+
const [collapsed, setCollapsed] = useState(() => !!key && loadCollapsed().includes(key));
|
|
138
|
+
const toggle = () => {
|
|
139
|
+
if (!key) return;
|
|
140
|
+
const next = !collapsed;
|
|
141
|
+
setCollapsed(next);
|
|
142
|
+
try {
|
|
143
|
+
const others = loadCollapsed().filter((item) => item !== key);
|
|
144
|
+
localStorage.setItem(COLLAPSED_KEY, JSON.stringify(next ? [...others, key] : others));
|
|
145
|
+
} catch {}
|
|
146
|
+
};
|
|
147
|
+
return [collapsed, toggle];
|
|
148
|
+
}
|
|
149
|
+
function Section({ title, actions, collapseKey, children }) {
|
|
150
|
+
const [collapsed, toggle] = useCollapsed(collapseKey);
|
|
116
151
|
return /* @__PURE__ */ jsxs(Box, {
|
|
117
|
-
sx: { mb: 2 },
|
|
152
|
+
sx: { mb: collapsed ? .5 : 2 },
|
|
118
153
|
children: [/* @__PURE__ */ jsxs(Box, {
|
|
119
154
|
sx: {
|
|
120
155
|
display: "flex",
|
|
@@ -123,15 +158,43 @@ function Section({ title, actions, children }) {
|
|
|
123
158
|
mb: .5,
|
|
124
159
|
minHeight: 30
|
|
125
160
|
},
|
|
126
|
-
children: [/* @__PURE__ */
|
|
161
|
+
children: [/* @__PURE__ */ jsxs(Typography, {
|
|
127
162
|
variant: "overline",
|
|
163
|
+
component: collapseKey ? "button" : "span",
|
|
164
|
+
...collapseKey && {
|
|
165
|
+
type: "button",
|
|
166
|
+
onClick: toggle,
|
|
167
|
+
"aria-expanded": !collapsed,
|
|
168
|
+
title: collapsed ? "Expandir" : "Recolher"
|
|
169
|
+
},
|
|
128
170
|
sx: {
|
|
129
171
|
color: "text.secondary",
|
|
130
172
|
lineHeight: 1.5,
|
|
131
|
-
fontWeight: 700
|
|
173
|
+
fontWeight: 700,
|
|
174
|
+
...collapseKey && {
|
|
175
|
+
display: "flex",
|
|
176
|
+
alignItems: "center",
|
|
177
|
+
gap: .5,
|
|
178
|
+
p: 0,
|
|
179
|
+
border: 0,
|
|
180
|
+
bgcolor: "transparent",
|
|
181
|
+
cursor: "pointer",
|
|
182
|
+
textAlign: "left",
|
|
183
|
+
"&:hover": { color: "text.primary" }
|
|
184
|
+
}
|
|
132
185
|
},
|
|
133
|
-
children:
|
|
134
|
-
|
|
186
|
+
children: [collapseKey && /* @__PURE__ */ jsx(Box, {
|
|
187
|
+
component: "span",
|
|
188
|
+
"aria-hidden": true,
|
|
189
|
+
sx: {
|
|
190
|
+
display: "inline-block",
|
|
191
|
+
fontSize: 9,
|
|
192
|
+
transition: "transform .15s",
|
|
193
|
+
transform: collapsed ? "rotate(-90deg)" : "none"
|
|
194
|
+
},
|
|
195
|
+
children: "▼"
|
|
196
|
+
}), title]
|
|
197
|
+
}), !collapsed && /* @__PURE__ */ jsx(Box, {
|
|
135
198
|
sx: {
|
|
136
199
|
ml: "auto",
|
|
137
200
|
display: "flex",
|
|
@@ -139,7 +202,7 @@ function Section({ title, actions, children }) {
|
|
|
139
202
|
},
|
|
140
203
|
children: actions
|
|
141
204
|
})]
|
|
142
|
-
}), children]
|
|
205
|
+
}), !collapsed && children]
|
|
143
206
|
});
|
|
144
207
|
}
|
|
145
208
|
function CodeBlock({ code, maxHeight = 260, sql = false }) {
|
|
@@ -181,7 +244,16 @@ function inlineParams(sql, params) {
|
|
|
181
244
|
});
|
|
182
245
|
}
|
|
183
246
|
const MAX_ROWS = 500;
|
|
247
|
+
/** Ordena linhas de resultado por uma coluna; `null` sempre no fim. */
|
|
248
|
+
function compareCells(a, b, { column, direction }) {
|
|
249
|
+
const [x, y] = [a[column], b[column]];
|
|
250
|
+
if (x === null || x === void 0) return y === null || y === void 0 ? 0 : 1;
|
|
251
|
+
if (y === null || y === void 0) return -1;
|
|
252
|
+
const order = typeof x === "number" && typeof y === "number" ? x - y : String(x).localeCompare(String(y), "pt-BR", { numeric: true });
|
|
253
|
+
return direction === "asc" ? order : -order;
|
|
254
|
+
}
|
|
184
255
|
function ResultTable({ rows, maxHeight = 320 }) {
|
|
256
|
+
const [sort, setSort] = useState(null);
|
|
185
257
|
if (!rows.length) return /* @__PURE__ */ jsx(Typography, {
|
|
186
258
|
sx: {
|
|
187
259
|
color: "text.secondary",
|
|
@@ -190,6 +262,14 @@ function ResultTable({ rows, maxHeight = 320 }) {
|
|
|
190
262
|
children: "Nenhuma linha."
|
|
191
263
|
});
|
|
192
264
|
const columns = Object.keys(rows[0]);
|
|
265
|
+
const sorted = sort ? [...rows].sort((a, b) => compareCells(a, b, sort)) : rows;
|
|
266
|
+
const toggleSort = (column) => setSort((current) => current?.column !== column ? {
|
|
267
|
+
column,
|
|
268
|
+
direction: "asc"
|
|
269
|
+
} : current.direction === "asc" ? {
|
|
270
|
+
column,
|
|
271
|
+
direction: "desc"
|
|
272
|
+
} : null);
|
|
193
273
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(TableContainer, {
|
|
194
274
|
sx: {
|
|
195
275
|
maxHeight,
|
|
@@ -201,12 +281,19 @@ function ResultTable({ rows, maxHeight = 320 }) {
|
|
|
201
281
|
size: "small",
|
|
202
282
|
stickyHeader: true,
|
|
203
283
|
children: [/* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(TableRow, { children: columns.map((column) => /* @__PURE__ */ jsx(TableCell, {
|
|
284
|
+
sortDirection: sort?.column === column ? sort.direction : false,
|
|
204
285
|
sx: {
|
|
205
286
|
fontFamily: MONO,
|
|
206
|
-
fontWeight: 700
|
|
287
|
+
fontWeight: 700,
|
|
288
|
+
whiteSpace: "nowrap"
|
|
207
289
|
},
|
|
208
|
-
children:
|
|
209
|
-
|
|
290
|
+
children: /* @__PURE__ */ jsx(TableSortLabel, {
|
|
291
|
+
active: sort?.column === column,
|
|
292
|
+
direction: sort?.column === column ? sort.direction : "asc",
|
|
293
|
+
onClick: () => toggleSort(column),
|
|
294
|
+
children: column
|
|
295
|
+
})
|
|
296
|
+
}, column)) }) }), /* @__PURE__ */ jsx(TableBody, { children: sorted.slice(0, MAX_ROWS).map((row, index) => /* @__PURE__ */ jsx(TableRow, {
|
|
210
297
|
hover: true,
|
|
211
298
|
children: columns.map((column) => /* @__PURE__ */ jsx(TableCell, {
|
|
212
299
|
align: typeof row[column] === "number" ? "right" : "left",
|
|
@@ -508,6 +595,483 @@ function FiltersPanel({ devtools }) {
|
|
|
508
595
|
});
|
|
509
596
|
}
|
|
510
597
|
//#endregion
|
|
598
|
+
//#region node_modules/react-dom/cjs/react-dom.production.js
|
|
599
|
+
/**
|
|
600
|
+
* @license React
|
|
601
|
+
* react-dom.production.js
|
|
602
|
+
*
|
|
603
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
604
|
+
*
|
|
605
|
+
* This source code is licensed under the MIT license found in the
|
|
606
|
+
* LICENSE file in the root directory of this source tree.
|
|
607
|
+
*/
|
|
608
|
+
var require_react_dom_production = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
609
|
+
var React = __require("react");
|
|
610
|
+
function formatProdErrorMessage(code) {
|
|
611
|
+
var url = "https://react.dev/errors/" + code;
|
|
612
|
+
if (1 < arguments.length) {
|
|
613
|
+
url += "?args[]=" + encodeURIComponent(arguments[1]);
|
|
614
|
+
for (var i = 2; i < arguments.length; i++) url += "&args[]=" + encodeURIComponent(arguments[i]);
|
|
615
|
+
}
|
|
616
|
+
return "Minified React error #" + code + "; visit " + url + " for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";
|
|
617
|
+
}
|
|
618
|
+
function noop() {}
|
|
619
|
+
var Internals = {
|
|
620
|
+
d: {
|
|
621
|
+
f: noop,
|
|
622
|
+
r: function() {
|
|
623
|
+
throw Error(formatProdErrorMessage(522));
|
|
624
|
+
},
|
|
625
|
+
D: noop,
|
|
626
|
+
C: noop,
|
|
627
|
+
L: noop,
|
|
628
|
+
m: noop,
|
|
629
|
+
X: noop,
|
|
630
|
+
S: noop,
|
|
631
|
+
M: noop
|
|
632
|
+
},
|
|
633
|
+
p: 0,
|
|
634
|
+
findDOMNode: null
|
|
635
|
+
};
|
|
636
|
+
var REACT_PORTAL_TYPE = Symbol.for("react.portal");
|
|
637
|
+
var REACT_RECOVERABLE_TYPE = Symbol.for("react.recoverable");
|
|
638
|
+
var REACT_OPTIMISTIC_KEY = Symbol.for("react.optimistic_key");
|
|
639
|
+
function createPortal$1(children, containerInfo, implementation) {
|
|
640
|
+
var key = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;
|
|
641
|
+
return {
|
|
642
|
+
$$typeof: REACT_PORTAL_TYPE,
|
|
643
|
+
key: null == key ? null : key === REACT_OPTIMISTIC_KEY ? REACT_OPTIMISTIC_KEY : "" + key,
|
|
644
|
+
children,
|
|
645
|
+
containerInfo,
|
|
646
|
+
implementation
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
650
|
+
function getCrossOriginStringAs(as, input) {
|
|
651
|
+
if ("font" === as) return "";
|
|
652
|
+
if ("string" === typeof input) return "use-credentials" === input ? input : "";
|
|
653
|
+
}
|
|
654
|
+
exports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = Internals;
|
|
655
|
+
exports.browser = function(reason) {
|
|
656
|
+
return {
|
|
657
|
+
$$typeof: REACT_RECOVERABLE_TYPE,
|
|
658
|
+
_reason: reason
|
|
659
|
+
};
|
|
660
|
+
};
|
|
661
|
+
exports.createPortal = function(children, container) {
|
|
662
|
+
var key = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;
|
|
663
|
+
if (!container || 1 !== container.nodeType && 9 !== container.nodeType && 11 !== container.nodeType) throw Error(formatProdErrorMessage(299));
|
|
664
|
+
return createPortal$1(children, container, null, key);
|
|
665
|
+
};
|
|
666
|
+
exports.flushSync = function(fn) {
|
|
667
|
+
var previousTransition = ReactSharedInternals.T, previousUpdatePriority = Internals.p;
|
|
668
|
+
try {
|
|
669
|
+
if (ReactSharedInternals.T = null, Internals.p = 2, fn) return fn();
|
|
670
|
+
} finally {
|
|
671
|
+
ReactSharedInternals.T = previousTransition, Internals.p = previousUpdatePriority, Internals.d.f();
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
exports.preconnect = function(href, options) {
|
|
675
|
+
"string" === typeof href && (options ? (options = options.crossOrigin, options = "string" === typeof options ? "use-credentials" === options ? options : "" : void 0) : options = null, Internals.d.C(href, options));
|
|
676
|
+
};
|
|
677
|
+
exports.prefetchDNS = function(href) {
|
|
678
|
+
"string" === typeof href && Internals.d.D(href);
|
|
679
|
+
};
|
|
680
|
+
exports.preinit = function(href, options) {
|
|
681
|
+
if ("string" === typeof href && options && "string" === typeof options.as) {
|
|
682
|
+
var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin), integrity = "string" === typeof options.integrity ? options.integrity : void 0, fetchPriority = "string" === typeof options.fetchPriority ? options.fetchPriority : void 0;
|
|
683
|
+
"style" === as ? Internals.d.S(href, "string" === typeof options.precedence ? options.precedence : void 0, {
|
|
684
|
+
crossOrigin,
|
|
685
|
+
integrity,
|
|
686
|
+
fetchPriority
|
|
687
|
+
}) : "script" === as && Internals.d.X(href, {
|
|
688
|
+
crossOrigin,
|
|
689
|
+
integrity,
|
|
690
|
+
fetchPriority,
|
|
691
|
+
nonce: "string" === typeof options.nonce ? options.nonce : void 0
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
exports.preinitModule = function(href, options) {
|
|
696
|
+
if ("string" === typeof href) if ("object" === typeof options && null !== options) {
|
|
697
|
+
if (null == options.as || "script" === options.as) {
|
|
698
|
+
var crossOrigin = getCrossOriginStringAs(options.as, options.crossOrigin);
|
|
699
|
+
Internals.d.M(href, {
|
|
700
|
+
crossOrigin,
|
|
701
|
+
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
|
|
702
|
+
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
|
|
703
|
+
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
} else options ?? Internals.d.M(href);
|
|
707
|
+
};
|
|
708
|
+
exports.preload = function(href, options) {
|
|
709
|
+
if ("string" === typeof href && "object" === typeof options && null !== options && "string" === typeof options.as) {
|
|
710
|
+
var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin);
|
|
711
|
+
Internals.d.L(href, as, {
|
|
712
|
+
crossOrigin,
|
|
713
|
+
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
|
|
714
|
+
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
|
|
715
|
+
type: "string" === typeof options.type ? options.type : void 0,
|
|
716
|
+
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0,
|
|
717
|
+
referrerPolicy: "string" === typeof options.referrerPolicy ? options.referrerPolicy : void 0,
|
|
718
|
+
imageSrcSet: "string" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,
|
|
719
|
+
imageSizes: "string" === typeof options.imageSizes ? options.imageSizes : void 0,
|
|
720
|
+
media: "string" === typeof options.media ? options.media : void 0
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
exports.preloadModule = function(href, options) {
|
|
725
|
+
if ("string" === typeof href) if (options) {
|
|
726
|
+
var crossOrigin = getCrossOriginStringAs(options.as, options.crossOrigin);
|
|
727
|
+
Internals.d.m(href, {
|
|
728
|
+
as: "string" === typeof options.as && "script" !== options.as ? options.as : void 0,
|
|
729
|
+
crossOrigin,
|
|
730
|
+
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
|
|
731
|
+
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
|
|
732
|
+
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0
|
|
733
|
+
});
|
|
734
|
+
} else Internals.d.m(href);
|
|
735
|
+
};
|
|
736
|
+
exports.requestFormReset = function(form) {
|
|
737
|
+
Internals.d.r(form);
|
|
738
|
+
};
|
|
739
|
+
exports.unstable_batchedUpdates = function(fn, a) {
|
|
740
|
+
return fn(a);
|
|
741
|
+
};
|
|
742
|
+
exports.useFormState = function(action, initialState, permalink) {
|
|
743
|
+
return ReactSharedInternals.H.useFormState(action, initialState, permalink);
|
|
744
|
+
};
|
|
745
|
+
exports.useFormStatus = function() {
|
|
746
|
+
return ReactSharedInternals.H.useHostTransitionStatus();
|
|
747
|
+
};
|
|
748
|
+
exports.version = "19.3.0";
|
|
749
|
+
}));
|
|
750
|
+
//#endregion
|
|
751
|
+
//#region node_modules/react-dom/cjs/react-dom.development.js
|
|
752
|
+
/**
|
|
753
|
+
* @license React
|
|
754
|
+
* react-dom.development.js
|
|
755
|
+
*
|
|
756
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
757
|
+
*
|
|
758
|
+
* This source code is licensed under the MIT license found in the
|
|
759
|
+
* LICENSE file in the root directory of this source tree.
|
|
760
|
+
*/
|
|
761
|
+
var require_react_dom_development = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
762
|
+
"production" !== process.env.NODE_ENV && (function() {
|
|
763
|
+
function noop() {}
|
|
764
|
+
function testStringCoercion(value) {
|
|
765
|
+
return "" + value;
|
|
766
|
+
}
|
|
767
|
+
function createPortal$1(children, containerInfo, implementation) {
|
|
768
|
+
var key = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;
|
|
769
|
+
if (null == key) key = null;
|
|
770
|
+
else if (key === REACT_OPTIMISTIC_KEY) key = REACT_OPTIMISTIC_KEY;
|
|
771
|
+
else {
|
|
772
|
+
try {
|
|
773
|
+
testStringCoercion(key);
|
|
774
|
+
var JSCompiler_inline_result = !1;
|
|
775
|
+
} catch (e) {
|
|
776
|
+
JSCompiler_inline_result = !0;
|
|
777
|
+
}
|
|
778
|
+
JSCompiler_inline_result && (console.error("The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", "function" === typeof Symbol && Symbol.toStringTag && key[Symbol.toStringTag] || key.constructor.name || "Object"), testStringCoercion(key));
|
|
779
|
+
key = "" + key;
|
|
780
|
+
}
|
|
781
|
+
return {
|
|
782
|
+
$$typeof: REACT_PORTAL_TYPE,
|
|
783
|
+
key,
|
|
784
|
+
children,
|
|
785
|
+
containerInfo,
|
|
786
|
+
implementation
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
function getCrossOriginStringAs(as, input) {
|
|
790
|
+
if ("font" === as) return "";
|
|
791
|
+
if ("string" === typeof input) return "use-credentials" === input ? input : "";
|
|
792
|
+
}
|
|
793
|
+
function getValueDescriptorExpectingObjectForWarning(thing) {
|
|
794
|
+
return null === thing ? "`null`" : void 0 === thing ? "`undefined`" : "" === thing ? "an empty string" : "something with type \"" + typeof thing + "\"";
|
|
795
|
+
}
|
|
796
|
+
function getValueDescriptorExpectingEnumForWarning(thing) {
|
|
797
|
+
return null === thing ? "`null`" : void 0 === thing ? "`undefined`" : "" === thing ? "an empty string" : "string" === typeof thing ? JSON.stringify(thing) : "number" === typeof thing ? "`" + thing + "`" : "something with type \"" + typeof thing + "\"";
|
|
798
|
+
}
|
|
799
|
+
function resolveDispatcher() {
|
|
800
|
+
var dispatcher = ReactSharedInternals.H;
|
|
801
|
+
null === dispatcher && console.error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.");
|
|
802
|
+
return dispatcher;
|
|
803
|
+
}
|
|
804
|
+
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
805
|
+
var React = __require("react"), Internals = {
|
|
806
|
+
d: {
|
|
807
|
+
f: noop,
|
|
808
|
+
r: function() {
|
|
809
|
+
throw Error("Invalid form element. requestFormReset must be passed a form that was rendered by React.");
|
|
810
|
+
},
|
|
811
|
+
D: noop,
|
|
812
|
+
C: noop,
|
|
813
|
+
L: noop,
|
|
814
|
+
m: noop,
|
|
815
|
+
X: noop,
|
|
816
|
+
S: noop,
|
|
817
|
+
M: noop
|
|
818
|
+
},
|
|
819
|
+
p: 0,
|
|
820
|
+
findDOMNode: null
|
|
821
|
+
}, REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_RECOVERABLE_TYPE = Symbol.for("react.recoverable"), REACT_OPTIMISTIC_KEY = Symbol.for("react.optimistic_key"), ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
822
|
+
"function" === typeof Map && null != Map.prototype && "function" === typeof Map.prototype.forEach && "function" === typeof Set && null != Set.prototype && "function" === typeof Set.prototype.clear && "function" === typeof Set.prototype.forEach || console.error("React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills");
|
|
823
|
+
exports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = Internals;
|
|
824
|
+
exports.browser = function(reason) {
|
|
825
|
+
return {
|
|
826
|
+
$$typeof: REACT_RECOVERABLE_TYPE,
|
|
827
|
+
_reason: reason
|
|
828
|
+
};
|
|
829
|
+
};
|
|
830
|
+
exports.createPortal = function(children, container) {
|
|
831
|
+
var key = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;
|
|
832
|
+
if (!container || 1 !== container.nodeType && 9 !== container.nodeType && 11 !== container.nodeType) throw Error("Target container is not a DOM element.");
|
|
833
|
+
return createPortal$1(children, container, null, key);
|
|
834
|
+
};
|
|
835
|
+
exports.flushSync = function(fn) {
|
|
836
|
+
var previousTransition = ReactSharedInternals.T, previousUpdatePriority = Internals.p;
|
|
837
|
+
try {
|
|
838
|
+
if (ReactSharedInternals.T = null, Internals.p = 2, fn) return fn();
|
|
839
|
+
} finally {
|
|
840
|
+
ReactSharedInternals.T = previousTransition, Internals.p = previousUpdatePriority, Internals.d.f() && console.error("flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.");
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
exports.preconnect = function(href, options) {
|
|
844
|
+
"string" === typeof href && href ? null != options && "object" !== typeof options ? console.error("ReactDOM.preconnect(): Expected the `options` argument (second) to be an object but encountered %s instead. The only supported option at this time is `crossOrigin` which accepts a string.", getValueDescriptorExpectingEnumForWarning(options)) : null != options && "string" !== typeof options.crossOrigin && console.error("ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered %s instead. Try removing this option or passing a string value instead.", getValueDescriptorExpectingObjectForWarning(options.crossOrigin)) : console.error("ReactDOM.preconnect(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.", getValueDescriptorExpectingObjectForWarning(href));
|
|
845
|
+
"string" === typeof href && (options ? (options = options.crossOrigin, options = "string" === typeof options ? "use-credentials" === options ? options : "" : void 0) : options = null, Internals.d.C(href, options));
|
|
846
|
+
};
|
|
847
|
+
exports.prefetchDNS = function(href) {
|
|
848
|
+
if ("string" !== typeof href || !href) console.error("ReactDOM.prefetchDNS(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.", getValueDescriptorExpectingObjectForWarning(href));
|
|
849
|
+
else if (1 < arguments.length) {
|
|
850
|
+
var options = arguments[1];
|
|
851
|
+
"object" === typeof options && options.hasOwnProperty("crossOrigin") ? console.error("ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.", getValueDescriptorExpectingEnumForWarning(options)) : console.error("ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.", getValueDescriptorExpectingEnumForWarning(options));
|
|
852
|
+
}
|
|
853
|
+
"string" === typeof href && Internals.d.D(href);
|
|
854
|
+
};
|
|
855
|
+
exports.preinit = function(href, options) {
|
|
856
|
+
"string" === typeof href && href ? null == options || "object" !== typeof options ? console.error("ReactDOM.preinit(): Expected the `options` argument (second) to be an object with an `as` property describing the type of resource to be preinitialized but encountered %s instead.", getValueDescriptorExpectingEnumForWarning(options)) : "style" !== options.as && "script" !== options.as && console.error("ReactDOM.preinit(): Expected the `as` property in the `options` argument (second) to contain a valid value describing the type of resource to be preinitialized but encountered %s instead. Valid values for `as` are \"style\" and \"script\".", getValueDescriptorExpectingEnumForWarning(options.as)) : console.error("ReactDOM.preinit(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.", getValueDescriptorExpectingObjectForWarning(href));
|
|
857
|
+
if ("string" === typeof href && options && "string" === typeof options.as) {
|
|
858
|
+
var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin), integrity = "string" === typeof options.integrity ? options.integrity : void 0, fetchPriority = "string" === typeof options.fetchPriority ? options.fetchPriority : void 0;
|
|
859
|
+
"style" === as ? Internals.d.S(href, "string" === typeof options.precedence ? options.precedence : void 0, {
|
|
860
|
+
crossOrigin,
|
|
861
|
+
integrity,
|
|
862
|
+
fetchPriority
|
|
863
|
+
}) : "script" === as && Internals.d.X(href, {
|
|
864
|
+
crossOrigin,
|
|
865
|
+
integrity,
|
|
866
|
+
fetchPriority,
|
|
867
|
+
nonce: "string" === typeof options.nonce ? options.nonce : void 0
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
exports.preinitModule = function(href, options) {
|
|
872
|
+
var encountered = "";
|
|
873
|
+
"string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
|
|
874
|
+
void 0 !== options && "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : options && "as" in options && "script" !== options.as && (encountered += " The `as` option encountered was " + getValueDescriptorExpectingEnumForWarning(options.as) + ".");
|
|
875
|
+
if (encountered) console.error("ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property.%s", encountered);
|
|
876
|
+
else switch (encountered = options && "string" === typeof options.as ? options.as : "script", encountered) {
|
|
877
|
+
case "script": break;
|
|
878
|
+
default: encountered = getValueDescriptorExpectingEnumForWarning(encountered), console.error("ReactDOM.preinitModule(): Currently the only supported \"as\" type for this function is \"script\" but received \"%s\" instead. This warning was generated for `href` \"%s\". In the future other module types will be supported, aligning with the import-attributes proposal. Learn more here: (https://github.com/tc39/proposal-import-attributes)", encountered, href);
|
|
879
|
+
}
|
|
880
|
+
if ("string" === typeof href) if ("object" === typeof options && null !== options) {
|
|
881
|
+
if (null == options.as || "script" === options.as) encountered = getCrossOriginStringAs(options.as, options.crossOrigin), Internals.d.M(href, {
|
|
882
|
+
crossOrigin: encountered,
|
|
883
|
+
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
|
|
884
|
+
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
|
|
885
|
+
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0
|
|
886
|
+
});
|
|
887
|
+
} else options ?? Internals.d.M(href);
|
|
888
|
+
};
|
|
889
|
+
exports.preload = function(href, options) {
|
|
890
|
+
var encountered = "";
|
|
891
|
+
"string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
|
|
892
|
+
null == options || "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : "string" === typeof options.as && options.as || (encountered += " The `as` option encountered was " + getValueDescriptorExpectingObjectForWarning(options.as) + ".");
|
|
893
|
+
encountered && console.error("ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an `options` object with an `as` property valid for a `<link rel=\"preload\" as=\"...\" />` tag.%s", encountered);
|
|
894
|
+
if ("string" === typeof href && "object" === typeof options && null !== options && "string" === typeof options.as) {
|
|
895
|
+
encountered = options.as;
|
|
896
|
+
var crossOrigin = getCrossOriginStringAs(encountered, options.crossOrigin);
|
|
897
|
+
Internals.d.L(href, encountered, {
|
|
898
|
+
crossOrigin,
|
|
899
|
+
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
|
|
900
|
+
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
|
|
901
|
+
type: "string" === typeof options.type ? options.type : void 0,
|
|
902
|
+
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0,
|
|
903
|
+
referrerPolicy: "string" === typeof options.referrerPolicy ? options.referrerPolicy : void 0,
|
|
904
|
+
imageSrcSet: "string" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,
|
|
905
|
+
imageSizes: "string" === typeof options.imageSizes ? options.imageSizes : void 0,
|
|
906
|
+
media: "string" === typeof options.media ? options.media : void 0
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
exports.preloadModule = function(href, options) {
|
|
911
|
+
var encountered = "";
|
|
912
|
+
"string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
|
|
913
|
+
void 0 !== options && "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : options && "as" in options && "string" !== typeof options.as && (encountered += " The `as` option encountered was " + getValueDescriptorExpectingObjectForWarning(options.as) + ".");
|
|
914
|
+
encountered && console.error("ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel=\"modulepreload\" as=\"...\" />` tag.%s", encountered);
|
|
915
|
+
"string" === typeof href && (options ? (encountered = getCrossOriginStringAs(options.as, options.crossOrigin), Internals.d.m(href, {
|
|
916
|
+
as: "string" === typeof options.as && "script" !== options.as ? options.as : void 0,
|
|
917
|
+
crossOrigin: encountered,
|
|
918
|
+
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
|
|
919
|
+
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
|
|
920
|
+
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0
|
|
921
|
+
})) : Internals.d.m(href));
|
|
922
|
+
};
|
|
923
|
+
exports.requestFormReset = function(form) {
|
|
924
|
+
Internals.d.r(form);
|
|
925
|
+
};
|
|
926
|
+
exports.unstable_batchedUpdates = function(fn, a) {
|
|
927
|
+
return fn(a);
|
|
928
|
+
};
|
|
929
|
+
exports.useFormState = function(action, initialState, permalink) {
|
|
930
|
+
return resolveDispatcher().useFormState(action, initialState, permalink);
|
|
931
|
+
};
|
|
932
|
+
exports.useFormStatus = function() {
|
|
933
|
+
return resolveDispatcher().useHostTransitionStatus();
|
|
934
|
+
};
|
|
935
|
+
exports.version = "19.3.0";
|
|
936
|
+
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
937
|
+
})();
|
|
938
|
+
}));
|
|
939
|
+
//#endregion
|
|
940
|
+
//#region src/devtools/DevtoolsWindow.tsx
|
|
941
|
+
var import_react_dom = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
942
|
+
function checkDCE() {
|
|
943
|
+
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined" || typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== "function") return;
|
|
944
|
+
if (process.env.NODE_ENV !== "production") throw new Error("^_^");
|
|
945
|
+
try {
|
|
946
|
+
__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);
|
|
947
|
+
} catch (err) {
|
|
948
|
+
console.error(err);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
if (process.env.NODE_ENV === "production") {
|
|
952
|
+
checkDCE();
|
|
953
|
+
module.exports = require_react_dom_production();
|
|
954
|
+
} else module.exports = require_react_dom_development();
|
|
955
|
+
})))();
|
|
956
|
+
/**
|
|
957
|
+
* Devtools numa janela separada do navegador (popup), para usar com a página em tela cheia ou em
|
|
958
|
+
* outro monitor. O painel continua sendo renderizado pela árvore React da página (mesmo contexto,
|
|
959
|
+
* mesmo store), só que via portal no `document` do popup:
|
|
960
|
+
*
|
|
961
|
+
* - os estilos do emotion/MUI vão para o `<head>` da página; aqui eles são espelhados no popup;
|
|
962
|
+
* - menus, tooltips e diálogos do MUI montam no `body` da página por padrão: o tema da janela
|
|
963
|
+
* aponta o `container` deles para o popup.
|
|
964
|
+
*
|
|
965
|
+
* Recarregar a página derruba o vínculo (o popup é de outra árvore): o popup avisa e o botão do
|
|
966
|
+
* devtools na página reconecta (abrir popup exige um clique, o navegador bloqueia sem gesto).
|
|
967
|
+
*/
|
|
968
|
+
const WINDOW_NAME = "bm-bi-devtools";
|
|
969
|
+
/** Abre (ou reaproveita, se ainda estiver aberta) a janela do devtools. `null` = bloqueada. */
|
|
970
|
+
function openDevtoolsWindow() {
|
|
971
|
+
const width = Math.min(1100, window.screen.availWidth);
|
|
972
|
+
const height = Math.min(720, window.screen.availHeight);
|
|
973
|
+
return window.open("", WINDOW_NAME, `popup,width=${width},height=${height}`);
|
|
974
|
+
}
|
|
975
|
+
const isStyleNode = (node) => node instanceof HTMLStyleElement || node instanceof HTMLLinkElement && node.rel === "stylesheet";
|
|
976
|
+
/** Cópia de um `<style>`/`<link>`; estilo inserido por `insertRule` (sem texto) vai pelas regras. */
|
|
977
|
+
function cloneStyle(node, target) {
|
|
978
|
+
const clone = target.importNode(node, true);
|
|
979
|
+
if (node instanceof HTMLStyleElement && !node.textContent && node.sheet?.cssRules.length) clone.textContent = [...node.sheet.cssRules].map((rule) => rule.cssText).join("\n");
|
|
980
|
+
return clone;
|
|
981
|
+
}
|
|
982
|
+
/** Copia os estilos da página para o popup e acompanha os que entrarem/saírem depois. */
|
|
983
|
+
function mirrorStyles(source, target) {
|
|
984
|
+
const clones = /* @__PURE__ */ new Map();
|
|
985
|
+
const add = (node) => {
|
|
986
|
+
if (!isStyleNode(node) || clones.has(node)) return;
|
|
987
|
+
const clone = cloneStyle(node, target);
|
|
988
|
+
clones.set(node, clone);
|
|
989
|
+
target.head.appendChild(clone);
|
|
990
|
+
};
|
|
991
|
+
for (const node of source.head.querySelectorAll("style, link[rel=\"stylesheet\"]")) add(node);
|
|
992
|
+
const observer = new MutationObserver((mutations) => {
|
|
993
|
+
for (const mutation of mutations) {
|
|
994
|
+
if (mutation.type === "characterData" || mutation.target !== source.head) {
|
|
995
|
+
const style = (mutation.target instanceof Element ? mutation.target : mutation.target.parentElement)?.closest("style");
|
|
996
|
+
const clone = style && clones.get(style);
|
|
997
|
+
if (style && clone) {
|
|
998
|
+
const next = cloneStyle(style, target);
|
|
999
|
+
target.head.replaceChild(next, clone);
|
|
1000
|
+
clones.set(style, next);
|
|
1001
|
+
}
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
for (const node of mutation.addedNodes) add(node);
|
|
1005
|
+
for (const node of mutation.removedNodes) {
|
|
1006
|
+
clones.get(node)?.parentNode?.removeChild(clones.get(node));
|
|
1007
|
+
clones.delete(node);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
});
|
|
1011
|
+
observer.observe(source.head, {
|
|
1012
|
+
childList: true,
|
|
1013
|
+
subtree: true,
|
|
1014
|
+
characterData: true
|
|
1015
|
+
});
|
|
1016
|
+
return () => observer.disconnect();
|
|
1017
|
+
}
|
|
1018
|
+
/** Tema com os portais do MUI (menus, tooltips, diálogos) dentro do popup. */
|
|
1019
|
+
function windowTheme(base, container) {
|
|
1020
|
+
return createTheme(base, { components: {
|
|
1021
|
+
MuiModal: { defaultProps: { container } },
|
|
1022
|
+
MuiPopover: { defaultProps: { container } },
|
|
1023
|
+
MuiPopper: { defaultProps: { container } },
|
|
1024
|
+
MuiDialog: { defaultProps: { container } },
|
|
1025
|
+
MuiMenu: { defaultProps: { container } }
|
|
1026
|
+
} });
|
|
1027
|
+
}
|
|
1028
|
+
function DevtoolsWindow({ popup, title, theme, onClosed, children }) {
|
|
1029
|
+
const [root, setRoot] = useState(null);
|
|
1030
|
+
const onClosedRef = useRef(onClosed);
|
|
1031
|
+
onClosedRef.current = onClosed;
|
|
1032
|
+
useEffect(() => {
|
|
1033
|
+
const doc = popup.document;
|
|
1034
|
+
doc.title = title;
|
|
1035
|
+
doc.head.replaceChildren();
|
|
1036
|
+
doc.body.replaceChildren();
|
|
1037
|
+
const meta = doc.createElement("meta");
|
|
1038
|
+
meta.setAttribute("charset", "utf-8");
|
|
1039
|
+
doc.head.appendChild(meta);
|
|
1040
|
+
const base = doc.createElement("style");
|
|
1041
|
+
base.textContent = `html, body { height: 100%; margin: 0; background: ${theme.palette.background.paper}; color-scheme: dark; } body { font-family: ${theme.typography.fontFamily}; } #${WINDOW_NAME} { height: 100%; display: flex; flex-direction: column; }`;
|
|
1042
|
+
doc.head.appendChild(base);
|
|
1043
|
+
const container = doc.createElement("div");
|
|
1044
|
+
container.id = WINDOW_NAME;
|
|
1045
|
+
doc.body.appendChild(container);
|
|
1046
|
+
const stopMirror = mirrorStyles(document, doc);
|
|
1047
|
+
setRoot(container);
|
|
1048
|
+
const poll = setInterval(() => {
|
|
1049
|
+
if (popup.closed) onClosedRef.current();
|
|
1050
|
+
}, 400);
|
|
1051
|
+
const onPageHide = () => {
|
|
1052
|
+
stopMirror();
|
|
1053
|
+
doc.body.innerHTML = `<p style="font: 14px sans-serif; color: #ccc; padding: 24px">A página do dashboard recarregou. Clique no botão <b style="color: #F58220">◆ BI</b> da página para reconectar o devtools a esta janela.</p>`;
|
|
1054
|
+
};
|
|
1055
|
+
window.addEventListener("pagehide", onPageHide);
|
|
1056
|
+
return () => {
|
|
1057
|
+
clearInterval(poll);
|
|
1058
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
1059
|
+
stopMirror();
|
|
1060
|
+
setRoot(null);
|
|
1061
|
+
};
|
|
1062
|
+
}, [
|
|
1063
|
+
popup,
|
|
1064
|
+
title,
|
|
1065
|
+
theme
|
|
1066
|
+
]);
|
|
1067
|
+
const localTheme = useMemo(() => root && windowTheme(theme, root), [theme, root]);
|
|
1068
|
+
if (!root || !localTheme) return null;
|
|
1069
|
+
return (0, import_react_dom.createPortal)(/* @__PURE__ */ jsx(ThemeProvider, {
|
|
1070
|
+
theme: localTheme,
|
|
1071
|
+
children
|
|
1072
|
+
}), root);
|
|
1073
|
+
}
|
|
1074
|
+
//#endregion
|
|
511
1075
|
//#region src/devtools/Inspector.tsx
|
|
512
1076
|
/**
|
|
513
1077
|
* Liga componente da página <-> consulta do devtools. Os componentes marcam o elemento raiz com
|
|
@@ -676,7 +1240,7 @@ function useWidth() {
|
|
|
676
1240
|
const [width, setWidth] = useState(Number.POSITIVE_INFINITY);
|
|
677
1241
|
useEffect(() => {
|
|
678
1242
|
if (!element) return;
|
|
679
|
-
const observer = new ResizeObserver(([entry]) => entry && setWidth(entry.contentRect.width));
|
|
1243
|
+
const observer = new ((element.ownerDocument.defaultView?.ResizeObserver) ?? ResizeObserver)(([entry]) => entry && setWidth(entry.contentRect.width));
|
|
680
1244
|
observer.observe(element);
|
|
681
1245
|
return () => observer.disconnect();
|
|
682
1246
|
}, [element]);
|
|
@@ -696,6 +1260,18 @@ const uniqueId = (charts, base) => {
|
|
|
696
1260
|
while (ids.has(`${base}-${n}`)) n++;
|
|
697
1261
|
return `${base}-${n}`;
|
|
698
1262
|
};
|
|
1263
|
+
/** Objeto sem nenhum campo sai do JSON. */
|
|
1264
|
+
const nonEmpty = (object) => Object.keys(object).length ? object : void 0;
|
|
1265
|
+
/** Campos do card de um gráfico, com o padrão do layout (`cards`) no lugar do padrão da lib. */
|
|
1266
|
+
const chartCardFields = (cards) => Object.fromEntries(Object.entries(CARD_FIELDS).map(([key, spec]) => [key, {
|
|
1267
|
+
...spec,
|
|
1268
|
+
default: cards?.[key] ?? spec.default
|
|
1269
|
+
}]));
|
|
1270
|
+
const cardsSummary = (cards) => {
|
|
1271
|
+
const { gap, ...style } = cards ?? {};
|
|
1272
|
+
const custom = Object.keys(style).length;
|
|
1273
|
+
return `espaço ${String(gap ?? CARDS_FIELDS.gap?.default)}px · ${custom ? `${custom} ajuste(s) de estilo` : "estilo padrão"}`;
|
|
1274
|
+
};
|
|
699
1275
|
/** Campo opcional vazio sai do objeto, para o JSON ficar só com o que foi definido. */
|
|
700
1276
|
function withField(object, key, value) {
|
|
701
1277
|
const next = { ...object };
|
|
@@ -809,7 +1385,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
809
1385
|
const charts = editing.charts;
|
|
810
1386
|
const filters = editing.filters ?? [];
|
|
811
1387
|
const selectedFilter = selection?.kind === "filter" ? filters.find((filter) => filter.dimension === selection.key) ?? null : null;
|
|
812
|
-
const selected = selection?.kind === "filter" || selection?.kind === "canvas" ? null : charts.find((chart) => chart.id === selection?.key) ?? charts[0] ?? null;
|
|
1388
|
+
const selected = selection?.kind === "filter" || selection?.kind === "canvas" || selection?.kind === "cards" ? null : charts.find((chart) => chart.id === selection?.key) ?? charts[0] ?? null;
|
|
813
1389
|
const layoutKey = entry.registered.id;
|
|
814
1390
|
const differsFromFile = canonicalJson(editing) !== canonicalJson(entry.registered);
|
|
815
1391
|
const update = (next) => {
|
|
@@ -826,6 +1402,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
826
1402
|
});
|
|
827
1403
|
const patchChart = (id, change) => setCharts(charts.map((chart) => chart.id === id ? change(chart) : chart));
|
|
828
1404
|
const setCanvas = (next) => update(withField(editing, "canvas", next));
|
|
1405
|
+
const setCards = (key, value) => update(withField(editing, "cards", nonEmpty(withField(editing.cards ?? {}, key, value))));
|
|
829
1406
|
const setFilters = (next) => update({
|
|
830
1407
|
...editing,
|
|
831
1408
|
filters: next
|
|
@@ -884,7 +1461,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
884
1461
|
};
|
|
885
1462
|
const stacked = rootWidth < STACK_WIDTH;
|
|
886
1463
|
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 : "";
|
|
1464
|
+
const selectedTitle = selection?.kind === "canvas" ? "Tela" : selection?.kind === "cards" ? "Cards" : selectedFilter ? selectedFilter.label || model.dimensions[selectedFilter.dimension]?.label || selectedFilter.dimension : selected ? selected.title || selected.id : "";
|
|
888
1465
|
const hover = (item) => onHover(item && itemQueryId(layoutKey, item));
|
|
889
1466
|
const add = (type, base) => {
|
|
890
1467
|
setAddMenu(null);
|
|
@@ -992,9 +1569,10 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
992
1569
|
children: [item.registered.id, item.draft ? " · rascunho" : ""]
|
|
993
1570
|
}, item.registered.id))
|
|
994
1571
|
}),
|
|
995
|
-
/* @__PURE__ */
|
|
1572
|
+
/* @__PURE__ */ jsxs(Section, {
|
|
996
1573
|
title: "Tela",
|
|
997
|
-
|
|
1574
|
+
collapseKey: "layout:lista:tela",
|
|
1575
|
+
children: [/* @__PURE__ */ jsx(ItemRow, {
|
|
998
1576
|
title: editing.canvas ? "Tamanho fixo" : "Responsiva",
|
|
999
1577
|
subtitle: editing.canvas ? presetLabel(editing.canvas) : "reorganiza conforme a largura",
|
|
1000
1578
|
selected: selection?.kind === "canvas",
|
|
@@ -1002,10 +1580,19 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
1002
1580
|
setSelection({ kind: "canvas" });
|
|
1003
1581
|
if (stacked) setSidebar(false);
|
|
1004
1582
|
}
|
|
1005
|
-
})
|
|
1583
|
+
}), /* @__PURE__ */ jsx(ItemRow, {
|
|
1584
|
+
title: "Cards",
|
|
1585
|
+
subtitle: cardsSummary(editing.cards),
|
|
1586
|
+
selected: selection?.kind === "cards",
|
|
1587
|
+
onSelect: () => {
|
|
1588
|
+
setSelection({ kind: "cards" });
|
|
1589
|
+
if (stacked) setSidebar(false);
|
|
1590
|
+
}
|
|
1591
|
+
})]
|
|
1006
1592
|
}),
|
|
1007
1593
|
/* @__PURE__ */ jsxs(Section, {
|
|
1008
1594
|
title: `Filtros (${filters.length})`,
|
|
1595
|
+
collapseKey: "layout:lista:filtros",
|
|
1009
1596
|
actions: /* @__PURE__ */ jsx(Button, {
|
|
1010
1597
|
size: "small",
|
|
1011
1598
|
onClick: addFilter,
|
|
@@ -1037,6 +1624,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
1037
1624
|
}),
|
|
1038
1625
|
/* @__PURE__ */ jsx(Section, {
|
|
1039
1626
|
title: `Gráficos (${charts.length})`,
|
|
1627
|
+
collapseKey: "layout:lista:graficos",
|
|
1040
1628
|
actions: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
|
|
1041
1629
|
size: "small",
|
|
1042
1630
|
onClick: (e) => setAddMenu(e.currentTarget),
|
|
@@ -1113,7 +1701,23 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
1113
1701
|
canvas: editing.canvas,
|
|
1114
1702
|
columns: formColumns,
|
|
1115
1703
|
onChange: setCanvas
|
|
1116
|
-
}) :
|
|
1704
|
+
}) : selection?.kind === "cards" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Typography, {
|
|
1705
|
+
sx: {
|
|
1706
|
+
fontSize: 12,
|
|
1707
|
+
color: "text.secondary",
|
|
1708
|
+
mb: 1
|
|
1709
|
+
},
|
|
1710
|
+
children: "Estilo padrão dos cards de todos os gráficos; cada gráfico pode sobrepor na seção Card dele. Vazio = padrão do componente."
|
|
1711
|
+
}), /* @__PURE__ */ jsx(FieldsForm, {
|
|
1712
|
+
fields: CARDS_FIELDS,
|
|
1713
|
+
values: editing.cards ?? {},
|
|
1714
|
+
onSet: setCards,
|
|
1715
|
+
model,
|
|
1716
|
+
formatters: [],
|
|
1717
|
+
columns: [],
|
|
1718
|
+
formColumns,
|
|
1719
|
+
chosenDimensions: []
|
|
1720
|
+
})] }) : selectedFilter ? /* @__PURE__ */ jsx(FilterForm, {
|
|
1117
1721
|
filter: selectedFilter,
|
|
1118
1722
|
model,
|
|
1119
1723
|
formatters: entry.parts.filters ?? [],
|
|
@@ -1127,6 +1731,7 @@ function LayoutPanel({ devtools, model, capabilities, picked, onHover }) {
|
|
|
1127
1731
|
}
|
|
1128
1732
|
}, `filter:${selectedFilter.dimension}`) : selected ? /* @__PURE__ */ jsx(ChartForm, {
|
|
1129
1733
|
chart: selected,
|
|
1734
|
+
cards: editing.cards,
|
|
1130
1735
|
types: chartTypes,
|
|
1131
1736
|
model,
|
|
1132
1737
|
formatters: entry.parts.charts ?? [],
|
|
@@ -1234,6 +1839,7 @@ function CanvasForm({ canvas, columns, onChange }) {
|
|
|
1234
1839
|
const number = (value) => value === "" ? void 0 : Number(value);
|
|
1235
1840
|
return /* @__PURE__ */ jsx(Section, {
|
|
1236
1841
|
title: "Tela",
|
|
1842
|
+
collapseKey: "layout:form:Tela",
|
|
1237
1843
|
children: /* @__PURE__ */ jsxs(Box, {
|
|
1238
1844
|
sx: formGrid(columns),
|
|
1239
1845
|
children: [/* @__PURE__ */ jsx(Box, {
|
|
@@ -1401,9 +2007,10 @@ function SmallButton({ title, disabled, onClick, children }) {
|
|
|
1401
2007
|
}) })
|
|
1402
2008
|
});
|
|
1403
2009
|
}
|
|
1404
|
-
function ChartForm({ chart, types, model, formatters, columns, onChange }) {
|
|
2010
|
+
function ChartForm({ chart, cards, types, model, formatters, columns, onChange }) {
|
|
1405
2011
|
const set = (key, value) => onChange((current) => withField(current, key, value));
|
|
1406
|
-
|
|
2012
|
+
const setCard = (key, value) => onChange((current) => withField(current, "card", nonEmpty(withField(current.card ?? {}, key, value))));
|
|
2013
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(FieldsForm, {
|
|
1407
2014
|
fields: types[chart.type]?.fields ?? {},
|
|
1408
2015
|
values: chart,
|
|
1409
2016
|
onSet: set,
|
|
@@ -1435,7 +2042,16 @@ function ChartForm({ chart, types, model, formatters, columns, onChange }) {
|
|
|
1435
2042
|
onChange: (e) => set("id", e.target.value),
|
|
1436
2043
|
sx: inputSx$1
|
|
1437
2044
|
}), "Identificador no JSON (letras, números, \"-\" e \"_\")")] })
|
|
1438
|
-
})
|
|
2045
|
+
}), /* @__PURE__ */ jsx(FieldsForm, {
|
|
2046
|
+
fields: chartCardFields(cards),
|
|
2047
|
+
values: chart.card ?? {},
|
|
2048
|
+
onSet: setCard,
|
|
2049
|
+
model,
|
|
2050
|
+
formatters: [],
|
|
2051
|
+
columns: [],
|
|
2052
|
+
formColumns: columns,
|
|
2053
|
+
chosenDimensions: []
|
|
2054
|
+
})] });
|
|
1439
2055
|
}
|
|
1440
2056
|
function FilterForm({ filter, model, formatters, columns, onChange }) {
|
|
1441
2057
|
return /* @__PURE__ */ jsx(FieldsForm, {
|
|
@@ -1625,6 +2241,7 @@ function FieldsForm({ fields, values, onSet: set, model, formatters, columns, fo
|
|
|
1625
2241
|
const inSection = entries.filter(([, spec]) => spec.section === section);
|
|
1626
2242
|
return /* @__PURE__ */ jsx(Section, {
|
|
1627
2243
|
title: section,
|
|
2244
|
+
collapseKey: `layout:form:${section}`,
|
|
1628
2245
|
children: /* @__PURE__ */ jsxs(Box, {
|
|
1629
2246
|
sx: formGrid(formColumns),
|
|
1630
2247
|
children: [section === sections[0] && header, inSection.map(([key, spec]) => /* @__PURE__ */ jsx(Box, {
|
|
@@ -2705,6 +3322,7 @@ function track(event, onMove, onUp) {
|
|
|
2705
3322
|
x: event.clientX,
|
|
2706
3323
|
y: event.clientY
|
|
2707
3324
|
};
|
|
3325
|
+
const win = event.currentTarget.ownerDocument.defaultView ?? window;
|
|
2708
3326
|
let moved = false;
|
|
2709
3327
|
const move = (moveEvent) => {
|
|
2710
3328
|
const dx = moveEvent.clientX - start.x;
|
|
@@ -2713,12 +3331,12 @@ function track(event, onMove, onUp) {
|
|
|
2713
3331
|
if (moved) onMove(dx, dy, moveEvent);
|
|
2714
3332
|
};
|
|
2715
3333
|
const up = (upEvent) => {
|
|
2716
|
-
|
|
2717
|
-
|
|
3334
|
+
win.removeEventListener("mousemove", move);
|
|
3335
|
+
win.removeEventListener("mouseup", up);
|
|
2718
3336
|
onUp?.(upEvent, moved);
|
|
2719
3337
|
};
|
|
2720
|
-
|
|
2721
|
-
|
|
3338
|
+
win.addEventListener("mousemove", move);
|
|
3339
|
+
win.addEventListener("mouseup", up);
|
|
2722
3340
|
}
|
|
2723
3341
|
/** Colunas citadas como `tabela.coluna` no SQL das dimensões/medidas. */
|
|
2724
3342
|
function citedColumns(sql, table) {
|
|
@@ -3060,7 +3678,7 @@ function ModelDiagram({ editor, setEditor, columns, errors, warnings, loadingCol
|
|
|
3060
3678
|
selectNode(node);
|
|
3061
3679
|
return;
|
|
3062
3680
|
}
|
|
3063
|
-
const target = document.elementFromPoint(upEvent.clientX, upEvent.clientY)?.closest("[data-diagram-column]");
|
|
3681
|
+
const target = (canvas.current?.ownerDocument ?? document).elementFromPoint(upEvent.clientX, upEvent.clientY)?.closest("[data-diagram-column]");
|
|
3064
3682
|
const targetNode = nodes.find((item) => item.id === target?.dataset.diagramNode);
|
|
3065
3683
|
const targetColumn = target?.dataset.diagramColumn;
|
|
3066
3684
|
if (targetNode && targetColumn) connect(node, column, targetNode, targetColumn);
|
|
@@ -4587,7 +5205,7 @@ function ModelPanel({ devtools, original, capabilities, tables, onTry, onSaved }
|
|
|
4587
5205
|
}),
|
|
4588
5206
|
/* @__PURE__ */ jsx(Button, {
|
|
4589
5207
|
size: "small",
|
|
4590
|
-
onClick: () => copyText(toModelCode(edited)),
|
|
5208
|
+
onClick: (e) => copyText(toModelCode(edited), e.currentTarget),
|
|
4591
5209
|
children: "Copiar TS"
|
|
4592
5210
|
}),
|
|
4593
5211
|
/* @__PURE__ */ jsx(Button, {
|
|
@@ -4850,12 +5468,55 @@ function PlaygroundPanel({ model, selection, onSelectionChange }) {
|
|
|
4850
5468
|
//#endregion
|
|
4851
5469
|
//#region src/devtools/QueriesPanel.tsx
|
|
4852
5470
|
const queryKey = (run) => JSON.stringify(run.query);
|
|
5471
|
+
const SORT_LABEL = {
|
|
5472
|
+
default: "ordem da página",
|
|
5473
|
+
label: "nome",
|
|
5474
|
+
duration: "mais lentas",
|
|
5475
|
+
rows: "mais linhas",
|
|
5476
|
+
status: "erros primeiro"
|
|
5477
|
+
};
|
|
5478
|
+
const SORT_KEY = "bm-dashboard-devtools:queries-sort";
|
|
5479
|
+
/** Problemas primeiro: erro, em andamento, cancelada, ok. */
|
|
5480
|
+
const STATUS_ORDER = {
|
|
5481
|
+
error: 0,
|
|
5482
|
+
loading: 1,
|
|
5483
|
+
cancelled: 2,
|
|
5484
|
+
success: 3
|
|
5485
|
+
};
|
|
5486
|
+
function loadSort() {
|
|
5487
|
+
try {
|
|
5488
|
+
const saved = localStorage.getItem(SORT_KEY);
|
|
5489
|
+
return saved && saved in SORT_LABEL ? saved : "default";
|
|
5490
|
+
} catch {
|
|
5491
|
+
return "default";
|
|
5492
|
+
}
|
|
5493
|
+
}
|
|
5494
|
+
/** Ordena a lista; empate mantém a ordem original (página ou mais recente primeiro). */
|
|
5495
|
+
function sortRuns(runs, key) {
|
|
5496
|
+
if (key === "default") return runs;
|
|
5497
|
+
const compare = (a, b) => {
|
|
5498
|
+
switch (key) {
|
|
5499
|
+
case "label": return a.label.localeCompare(b.label, "pt-BR", { numeric: true });
|
|
5500
|
+
case "duration": return (b.durationMs ?? Date.now() - b.startedAt) - (a.durationMs ?? Date.now() - a.startedAt);
|
|
5501
|
+
case "rows": return (b.rows?.length ?? -1) - (a.rows?.length ?? -1);
|
|
5502
|
+
case "status": return STATUS_ORDER[a.status] - STATUS_ORDER[b.status];
|
|
5503
|
+
}
|
|
5504
|
+
};
|
|
5505
|
+
return [...runs].sort(compare);
|
|
5506
|
+
}
|
|
4853
5507
|
/** Consultas ativas na página (uma por componente) e o histórico de execuções. */
|
|
4854
5508
|
function QueriesPanel({ devtools, capabilities, selected, onSelect, onHover, onClearServerCache }) {
|
|
4855
5509
|
const { store, refresh } = devtools;
|
|
4856
5510
|
const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
4857
5511
|
const [view, setView] = useState("active");
|
|
4858
|
-
const
|
|
5512
|
+
const [sort, setSort] = useState(loadSort);
|
|
5513
|
+
const changeSort = (next) => {
|
|
5514
|
+
setSort(next);
|
|
5515
|
+
try {
|
|
5516
|
+
localStorage.setItem(SORT_KEY, next);
|
|
5517
|
+
} catch {}
|
|
5518
|
+
};
|
|
5519
|
+
const runs = sortRuns(view === "active" ? snapshot.instances.map((instance) => instance.last) : snapshot.history, sort);
|
|
4859
5520
|
const instanceById = new Map(snapshot.instances.map((item) => [item.instanceId, item]));
|
|
4860
5521
|
const sameQuery = /* @__PURE__ */ new Map();
|
|
4861
5522
|
for (const { last } of snapshot.instances) sameQuery.set(queryKey(last), (sameQuery.get(queryKey(last)) ?? 0) + 1);
|
|
@@ -4886,31 +5547,54 @@ function QueriesPanel({ devtools, capabilities, selected, onSelect, onHover, onC
|
|
|
4886
5547
|
borderBottom: 1,
|
|
4887
5548
|
borderColor: "divider"
|
|
4888
5549
|
},
|
|
4889
|
-
children: [
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
5550
|
+
children: [
|
|
5551
|
+
/* @__PURE__ */ jsxs(ToggleButtonGroup, {
|
|
5552
|
+
size: "small",
|
|
5553
|
+
exclusive: true,
|
|
5554
|
+
value: view,
|
|
5555
|
+
onChange: (_, value) => value && setView(value),
|
|
5556
|
+
children: [/* @__PURE__ */ jsxs(ToggleButton, {
|
|
5557
|
+
value: "active",
|
|
5558
|
+
children: [
|
|
5559
|
+
"Ativas (",
|
|
5560
|
+
snapshot.instances.length,
|
|
5561
|
+
")"
|
|
5562
|
+
]
|
|
5563
|
+
}), /* @__PURE__ */ jsxs(ToggleButton, {
|
|
5564
|
+
value: "history",
|
|
5565
|
+
children: [
|
|
5566
|
+
"Histórico (",
|
|
5567
|
+
snapshot.history.length,
|
|
5568
|
+
")"
|
|
5569
|
+
]
|
|
5570
|
+
})]
|
|
5571
|
+
}),
|
|
5572
|
+
view === "history" && /* @__PURE__ */ jsx(Button, {
|
|
5573
|
+
size: "small",
|
|
5574
|
+
onClick: store.clearHistory,
|
|
5575
|
+
children: "Limpar"
|
|
5576
|
+
}),
|
|
5577
|
+
/* @__PURE__ */ jsx(TextField, {
|
|
5578
|
+
select: true,
|
|
5579
|
+
size: "small",
|
|
5580
|
+
value: sort,
|
|
5581
|
+
onChange: (e) => changeSort(e.target.value),
|
|
5582
|
+
title: "Ordenar a lista",
|
|
5583
|
+
sx: {
|
|
5584
|
+
ml: "auto",
|
|
5585
|
+
minWidth: 0,
|
|
5586
|
+
"& .MuiSelect-select": {
|
|
5587
|
+
fontSize: 12,
|
|
5588
|
+
py: .5
|
|
5589
|
+
}
|
|
5590
|
+
},
|
|
5591
|
+
children: Object.keys(SORT_LABEL).map((key) => /* @__PURE__ */ jsx(MenuItem, {
|
|
5592
|
+
value: key,
|
|
5593
|
+
dense: true,
|
|
5594
|
+
children: key === "default" && view === "history" ? "mais recentes" : SORT_LABEL[key]
|
|
5595
|
+
}, key))
|
|
5596
|
+
})
|
|
5597
|
+
]
|
|
4914
5598
|
}),
|
|
4915
5599
|
/* @__PURE__ */ jsxs(Box, {
|
|
4916
5600
|
sx: {
|
|
@@ -5102,6 +5786,7 @@ function RunDetail({ run, devtools, capabilities, mounted }) {
|
|
|
5102
5786
|
},
|
|
5103
5787
|
children: run.error
|
|
5104
5788
|
}),
|
|
5789
|
+
run.status === "error" && !debug && /* @__PURE__ */ jsx(FailedSql, { run }),
|
|
5105
5790
|
/* @__PURE__ */ jsx(Section, {
|
|
5106
5791
|
title: "Consulta",
|
|
5107
5792
|
children: /* @__PURE__ */ jsx(CodeBlock, {
|
|
@@ -5149,6 +5834,67 @@ function RunDetail({ run, devtools, capabilities, mounted }) {
|
|
|
5149
5834
|
})
|
|
5150
5835
|
] });
|
|
5151
5836
|
}
|
|
5837
|
+
/**
|
|
5838
|
+
* SQL de uma consulta que deu erro: o servidor não devolve debug junto com o erro, então pede só a
|
|
5839
|
+
* compilação (`devtools.compile`), sem executar. Se nem compilar, mostra por quê.
|
|
5840
|
+
*/
|
|
5841
|
+
function FailedSql({ run }) {
|
|
5842
|
+
const { fetcher } = useDashboard();
|
|
5843
|
+
const [state, setState] = useState(null);
|
|
5844
|
+
useEffect(() => {
|
|
5845
|
+
let active = true;
|
|
5846
|
+
setState({ loading: true });
|
|
5847
|
+
fetcher({
|
|
5848
|
+
...run.query,
|
|
5849
|
+
devtools: { compile: true }
|
|
5850
|
+
}).then((result) => {
|
|
5851
|
+
const debug = result.devtools?.debug;
|
|
5852
|
+
if (active) setState(debug ? {
|
|
5853
|
+
loading: false,
|
|
5854
|
+
data: debug
|
|
5855
|
+
} : {
|
|
5856
|
+
loading: false,
|
|
5857
|
+
error: "O endpoint não devolveu o SQL (precisa de runQuery(..., { devtools: true }) numa versão que aceite devtools.compile)."
|
|
5858
|
+
});
|
|
5859
|
+
}).catch((error) => active && setState({
|
|
5860
|
+
loading: false,
|
|
5861
|
+
error: errorMessage(error)
|
|
5862
|
+
}));
|
|
5863
|
+
return () => {
|
|
5864
|
+
active = false;
|
|
5865
|
+
};
|
|
5866
|
+
}, [fetcher, run.query]);
|
|
5867
|
+
return /* @__PURE__ */ jsx(Section, {
|
|
5868
|
+
title: "SQL gerado (não executou)",
|
|
5869
|
+
children: /* @__PURE__ */ jsx(ToolResult, {
|
|
5870
|
+
state,
|
|
5871
|
+
children: (debug) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(CodeBlock, {
|
|
5872
|
+
sql: true,
|
|
5873
|
+
code: inlineParams(debug.sql, debug.params)
|
|
5874
|
+
}), /* @__PURE__ */ jsxs(Typography, {
|
|
5875
|
+
sx: {
|
|
5876
|
+
fontSize: 11,
|
|
5877
|
+
color: "text.secondary",
|
|
5878
|
+
mt: .5
|
|
5879
|
+
},
|
|
5880
|
+
children: [
|
|
5881
|
+
"Compilado de novo agora",
|
|
5882
|
+
debug.draft ? ", com o rascunho atual" : "",
|
|
5883
|
+
", para depurar o erro acima.",
|
|
5884
|
+
!!debug.params.length && /* @__PURE__ */ jsxs(Box, {
|
|
5885
|
+
component: "span",
|
|
5886
|
+
sx: { fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" },
|
|
5887
|
+
children: [
|
|
5888
|
+
" ",
|
|
5889
|
+
"params: ",
|
|
5890
|
+
JSON.stringify(debug.params)
|
|
5891
|
+
]
|
|
5892
|
+
})
|
|
5893
|
+
]
|
|
5894
|
+
})] })
|
|
5895
|
+
})
|
|
5896
|
+
});
|
|
5897
|
+
}
|
|
5152
5898
|
function useTool() {
|
|
5153
5899
|
const [state, setState] = useState(null);
|
|
5154
5900
|
const run = async (load) => {
|
|
@@ -5632,9 +6378,10 @@ function CheckList({ checks, expectedLabel, actualLabel }) {
|
|
|
5632
6378
|
* painel com as consultas da página, o modelo editável, um playground, regressão, dicionário e
|
|
5633
6379
|
* filtros. Montado pelo próprio `DashboardProvider` em desenvolvimento.
|
|
5634
6380
|
*
|
|
5635
|
-
*
|
|
5636
|
-
* redimensiona pelo canto)
|
|
5637
|
-
* página encolhe para não ficar escondida atrás dele; só o modo flutuante
|
|
6381
|
+
* Modos: fixado (embaixo, à esquerda ou à direita), flutuante (janela que se arrasta pelo cabeçalho
|
|
6382
|
+
* e redimensiona pelo canto) ou numa janela separada do navegador (`DevtoolsWindow`). Fixado, o
|
|
6383
|
+
* painel ocupa espaço: a página encolhe para não ficar escondida atrás dele; só o modo flutuante
|
|
6384
|
+
* sobrepõe a página.
|
|
5638
6385
|
* Atalhos: Alt+Shift+B abre/fecha o painel, Alt+Shift+F alterna entre fixado e flutuante,
|
|
5639
6386
|
* Alt+Shift+I liga o inspetor, Esc sai do inspetor.
|
|
5640
6387
|
*/
|
|
@@ -5723,13 +6470,15 @@ function loadUi() {
|
|
|
5723
6470
|
"bottom",
|
|
5724
6471
|
"left",
|
|
5725
6472
|
"right",
|
|
5726
|
-
"floating"
|
|
6473
|
+
"floating",
|
|
6474
|
+
"window"
|
|
5727
6475
|
].includes(saved.mode)) saved.mode = "bottom";
|
|
5728
6476
|
if (![
|
|
5729
6477
|
"bottom",
|
|
5730
6478
|
"left",
|
|
5731
6479
|
"right"
|
|
5732
6480
|
].includes(saved.dock)) saved.dock = "bottom";
|
|
6481
|
+
if (saved.mode === "window") saved.open = false;
|
|
5733
6482
|
return {
|
|
5734
6483
|
...saved,
|
|
5735
6484
|
float: clampFloat({
|
|
@@ -5828,6 +6577,7 @@ function DashboardDevtools() {
|
|
|
5828
6577
|
const [pickedItem, setPickedItem] = useState(null);
|
|
5829
6578
|
const [hovered, setHovered] = useState(null);
|
|
5830
6579
|
const [inspecting, setInspecting] = useState(false);
|
|
6580
|
+
const [popup, setPopup] = useState(null);
|
|
5831
6581
|
const store = devtools?.store;
|
|
5832
6582
|
const instances = useSyncExternalStore(store?.subscribe ?? (() => () => {}), () => store?.getSnapshot(), () => store?.getSnapshot())?.instances ?? [];
|
|
5833
6583
|
useEffect(() => {
|
|
@@ -5886,18 +6636,85 @@ function DashboardDevtools() {
|
|
|
5886
6636
|
}));
|
|
5887
6637
|
}, [layoutTab])
|
|
5888
6638
|
});
|
|
6639
|
+
const closePopup = useCallback(() => {
|
|
6640
|
+
setPopup((current) => {
|
|
6641
|
+
if (current && !current.closed) current.close();
|
|
6642
|
+
return null;
|
|
6643
|
+
});
|
|
6644
|
+
}, []);
|
|
6645
|
+
const openPanel = useCallback(() => {
|
|
6646
|
+
if (ui.mode !== "window") {
|
|
6647
|
+
setUi((current) => ({
|
|
6648
|
+
...current,
|
|
6649
|
+
open: true
|
|
6650
|
+
}));
|
|
6651
|
+
return;
|
|
6652
|
+
}
|
|
6653
|
+
const opened = popup && !popup.closed ? popup : openDevtoolsWindow();
|
|
6654
|
+
if (opened) {
|
|
6655
|
+
opened.focus();
|
|
6656
|
+
setPopup(opened);
|
|
6657
|
+
setUi((current) => ({
|
|
6658
|
+
...current,
|
|
6659
|
+
open: true
|
|
6660
|
+
}));
|
|
6661
|
+
} else setUi((current) => ({
|
|
6662
|
+
...current,
|
|
6663
|
+
open: true,
|
|
6664
|
+
mode: current.dock
|
|
6665
|
+
}));
|
|
6666
|
+
}, [ui.mode, popup]);
|
|
6667
|
+
const closePanel = useCallback(() => {
|
|
6668
|
+
closePopup();
|
|
6669
|
+
setUi((current) => ({
|
|
6670
|
+
...current,
|
|
6671
|
+
open: false
|
|
6672
|
+
}));
|
|
6673
|
+
}, [closePopup]);
|
|
6674
|
+
const toWindow = () => {
|
|
6675
|
+
const opened = openDevtoolsWindow();
|
|
6676
|
+
if (!opened) return;
|
|
6677
|
+
opened.focus();
|
|
6678
|
+
setPopup(opened);
|
|
6679
|
+
setUi((current) => ({
|
|
6680
|
+
...current,
|
|
6681
|
+
open: true,
|
|
6682
|
+
mode: "window"
|
|
6683
|
+
}));
|
|
6684
|
+
};
|
|
6685
|
+
const onPopupClosed = useCallback(() => {
|
|
6686
|
+
setPopup(null);
|
|
6687
|
+
setUi((current) => ({
|
|
6688
|
+
...current,
|
|
6689
|
+
open: false
|
|
6690
|
+
}));
|
|
6691
|
+
}, []);
|
|
6692
|
+
const keyActions = useRef({
|
|
6693
|
+
openPanel,
|
|
6694
|
+
closePanel,
|
|
6695
|
+
closePopup,
|
|
6696
|
+
open: ui.open,
|
|
6697
|
+
inspecting
|
|
6698
|
+
});
|
|
6699
|
+
keyActions.current = {
|
|
6700
|
+
openPanel,
|
|
6701
|
+
closePanel,
|
|
6702
|
+
closePopup,
|
|
6703
|
+
open: ui.open,
|
|
6704
|
+
inspecting
|
|
6705
|
+
};
|
|
5889
6706
|
useEffect(() => {
|
|
5890
6707
|
const onKey = (event) => {
|
|
5891
|
-
|
|
6708
|
+
const actions = keyActions.current;
|
|
6709
|
+
if (event.key === "Escape" && actions.inspecting) setInspecting(false);
|
|
5892
6710
|
if (!event.altKey || !event.shiftKey) return;
|
|
5893
6711
|
if (event.code === "KeyB") {
|
|
5894
6712
|
event.preventDefault();
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
open: !current.open
|
|
5898
|
-
}));
|
|
6713
|
+
if (actions.open) actions.closePanel();
|
|
6714
|
+
else actions.openPanel();
|
|
5899
6715
|
} else if (event.code === "KeyF") {
|
|
5900
6716
|
event.preventDefault();
|
|
6717
|
+
actions.closePopup();
|
|
5901
6718
|
setUi((current) => ({
|
|
5902
6719
|
...current,
|
|
5903
6720
|
open: true,
|
|
@@ -5908,10 +6725,13 @@ function DashboardDevtools() {
|
|
|
5908
6725
|
setInspecting((value) => !value);
|
|
5909
6726
|
}
|
|
5910
6727
|
};
|
|
5911
|
-
window
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
6728
|
+
const targets = popup && !popup.closed ? [window, popup] : [window];
|
|
6729
|
+
for (const target of targets) target.addEventListener("keydown", onKey);
|
|
6730
|
+
return () => {
|
|
6731
|
+
for (const target of targets) target.removeEventListener("keydown", onKey);
|
|
6732
|
+
};
|
|
6733
|
+
}, [popup]);
|
|
6734
|
+
const reserved = ui.open && ui.mode !== "floating" && ui.mode !== "window" ? ui.mode : null;
|
|
5915
6735
|
const reservedSize = reserved === "bottom" ? ui.height : ui.width;
|
|
5916
6736
|
const reservation = useRef(null);
|
|
5917
6737
|
const reservedSizeRef = useRef(reservedSize);
|
|
@@ -5935,6 +6755,7 @@ function DashboardDevtools() {
|
|
|
5935
6755
|
return () => window.removeEventListener("resize", onResize);
|
|
5936
6756
|
}, []);
|
|
5937
6757
|
if (!devtools || !store) return null;
|
|
6758
|
+
const inWindow = ui.mode === "window" && !!popup;
|
|
5938
6759
|
const floating = ui.mode === "floating";
|
|
5939
6760
|
const side = ui.mode === "left" || ui.mode === "right" ? ui.mode : null;
|
|
5940
6761
|
const startDockResize = (event) => {
|
|
@@ -5971,15 +6792,21 @@ function DashboardDevtools() {
|
|
|
5971
6792
|
})
|
|
5972
6793
|
})));
|
|
5973
6794
|
};
|
|
5974
|
-
const toggleMode = () =>
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
6795
|
+
const toggleMode = () => {
|
|
6796
|
+
closePopup();
|
|
6797
|
+
setUi((current) => ({
|
|
6798
|
+
...current,
|
|
6799
|
+
mode: current.mode === "floating" ? current.dock : "floating"
|
|
6800
|
+
}));
|
|
6801
|
+
};
|
|
6802
|
+
const dockTo = (dock) => {
|
|
6803
|
+
closePopup();
|
|
6804
|
+
setUi((current) => ({
|
|
6805
|
+
...current,
|
|
6806
|
+
mode: dock,
|
|
6807
|
+
dock
|
|
6808
|
+
}));
|
|
6809
|
+
};
|
|
5983
6810
|
const clearServerCache = () => loadModel(true).then(devtools.refresh);
|
|
5984
6811
|
const loading = instances.filter((item) => item.last.status === "loading").length;
|
|
5985
6812
|
const errors = instances.filter((item) => item.last.status === "error").length;
|
|
@@ -6008,6 +6835,229 @@ function DashboardDevtools() {
|
|
|
6008
6835
|
},
|
|
6009
6836
|
children: /* @__PURE__ */ jsx(CircularProgress, { size: 20 })
|
|
6010
6837
|
}) : content(original);
|
|
6838
|
+
const header = /* @__PURE__ */ jsxs(Box, {
|
|
6839
|
+
onMouseDown: startDrag,
|
|
6840
|
+
onDoubleClick: (event) => {
|
|
6841
|
+
if (floating && !event.target.closest("button, [role=\"tab\"]")) toggleMode();
|
|
6842
|
+
},
|
|
6843
|
+
sx: {
|
|
6844
|
+
display: "flex",
|
|
6845
|
+
alignItems: "center",
|
|
6846
|
+
gap: 1.5,
|
|
6847
|
+
px: 1.5,
|
|
6848
|
+
borderBottom: 1,
|
|
6849
|
+
borderColor: "divider",
|
|
6850
|
+
cursor: floating ? "move" : void 0,
|
|
6851
|
+
...side && {
|
|
6852
|
+
flexWrap: "wrap",
|
|
6853
|
+
columnGap: 1,
|
|
6854
|
+
pt: .5
|
|
6855
|
+
}
|
|
6856
|
+
},
|
|
6857
|
+
children: [
|
|
6858
|
+
/* @__PURE__ */ jsx(Typography, {
|
|
6859
|
+
sx: {
|
|
6860
|
+
fontWeight: 800,
|
|
6861
|
+
color: "primary.main",
|
|
6862
|
+
whiteSpace: "nowrap"
|
|
6863
|
+
},
|
|
6864
|
+
children: "◆ BI Devtools"
|
|
6865
|
+
}),
|
|
6866
|
+
/* @__PURE__ */ jsx(Chip, {
|
|
6867
|
+
size: "small",
|
|
6868
|
+
label: model,
|
|
6869
|
+
sx: { fontFamily: MONO }
|
|
6870
|
+
}),
|
|
6871
|
+
/* @__PURE__ */ jsxs(Tabs, {
|
|
6872
|
+
value: ui.tab,
|
|
6873
|
+
onChange: (_, tab) => setTab(tab),
|
|
6874
|
+
variant: "scrollable",
|
|
6875
|
+
scrollButtons: "auto",
|
|
6876
|
+
sx: {
|
|
6877
|
+
minHeight: 40,
|
|
6878
|
+
...side && {
|
|
6879
|
+
order: 1,
|
|
6880
|
+
width: "100%"
|
|
6881
|
+
}
|
|
6882
|
+
},
|
|
6883
|
+
children: [
|
|
6884
|
+
/* @__PURE__ */ jsx(Tab, {
|
|
6885
|
+
value: "queries",
|
|
6886
|
+
label: /* @__PURE__ */ jsxs(Box, {
|
|
6887
|
+
sx: {
|
|
6888
|
+
display: "flex",
|
|
6889
|
+
alignItems: "center",
|
|
6890
|
+
gap: .75
|
|
6891
|
+
},
|
|
6892
|
+
children: [
|
|
6893
|
+
"Consultas (",
|
|
6894
|
+
instances.length,
|
|
6895
|
+
")",
|
|
6896
|
+
!!loading && /* @__PURE__ */ jsx(CircularProgress, { size: 10 }),
|
|
6897
|
+
!!(errors || storms) && /* @__PURE__ */ jsx(Chip, {
|
|
6898
|
+
size: "small",
|
|
6899
|
+
color: "error",
|
|
6900
|
+
label: errors + storms,
|
|
6901
|
+
sx: { height: 16 }
|
|
6902
|
+
})
|
|
6903
|
+
]
|
|
6904
|
+
})
|
|
6905
|
+
}),
|
|
6906
|
+
/* @__PURE__ */ jsx(Tab, {
|
|
6907
|
+
value: "model",
|
|
6908
|
+
label: "Modelo"
|
|
6909
|
+
}),
|
|
6910
|
+
/* @__PURE__ */ jsx(Tab, {
|
|
6911
|
+
value: "layout",
|
|
6912
|
+
label: "Layout"
|
|
6913
|
+
}),
|
|
6914
|
+
/* @__PURE__ */ jsx(Tab, {
|
|
6915
|
+
value: "playground",
|
|
6916
|
+
label: "Playground"
|
|
6917
|
+
}),
|
|
6918
|
+
/* @__PURE__ */ jsx(Tab, {
|
|
6919
|
+
value: "regression",
|
|
6920
|
+
label: "Regressão"
|
|
6921
|
+
}),
|
|
6922
|
+
/* @__PURE__ */ jsx(Tab, {
|
|
6923
|
+
value: "dictionary",
|
|
6924
|
+
label: "Dicionário"
|
|
6925
|
+
}),
|
|
6926
|
+
/* @__PURE__ */ jsx(Tab, {
|
|
6927
|
+
value: "filters",
|
|
6928
|
+
label: "Filtros"
|
|
6929
|
+
})
|
|
6930
|
+
]
|
|
6931
|
+
}),
|
|
6932
|
+
devtools.draft && /* @__PURE__ */ jsx(Chip, {
|
|
6933
|
+
size: "small",
|
|
6934
|
+
color: "warning",
|
|
6935
|
+
label: "rascunho aplicado"
|
|
6936
|
+
}),
|
|
6937
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
6938
|
+
sx: {
|
|
6939
|
+
ml: "auto",
|
|
6940
|
+
display: "flex",
|
|
6941
|
+
alignItems: "center",
|
|
6942
|
+
gap: .5
|
|
6943
|
+
},
|
|
6944
|
+
children: [
|
|
6945
|
+
/* @__PURE__ */ jsx(Tooltip, {
|
|
6946
|
+
title: "Inspecionar componente (Alt+Shift+I)",
|
|
6947
|
+
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6948
|
+
size: "small",
|
|
6949
|
+
color: inspecting ? "primary" : "default",
|
|
6950
|
+
onClick: () => setInspecting((value) => !value),
|
|
6951
|
+
"aria-label": "Inspecionar componente",
|
|
6952
|
+
children: "⌖"
|
|
6953
|
+
})
|
|
6954
|
+
}),
|
|
6955
|
+
DOCK_SIDES.map(({ side: dock, icon, label }) => /* @__PURE__ */ jsx(Tooltip, {
|
|
6956
|
+
title: `${label} (ocupa espaço na página)`,
|
|
6957
|
+
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6958
|
+
size: "small",
|
|
6959
|
+
color: ui.mode === dock ? "primary" : "default",
|
|
6960
|
+
onClick: () => dockTo(dock),
|
|
6961
|
+
"aria-label": label,
|
|
6962
|
+
children: icon
|
|
6963
|
+
})
|
|
6964
|
+
}, dock)),
|
|
6965
|
+
/* @__PURE__ */ jsx(Tooltip, {
|
|
6966
|
+
title: "Janela flutuante, por cima da página (Alt+Shift+F) · arraste pelo cabeçalho",
|
|
6967
|
+
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6968
|
+
size: "small",
|
|
6969
|
+
color: floating ? "primary" : "default",
|
|
6970
|
+
onClick: toggleMode,
|
|
6971
|
+
"aria-label": "Devtools flutuante",
|
|
6972
|
+
children: "⧉"
|
|
6973
|
+
})
|
|
6974
|
+
}),
|
|
6975
|
+
/* @__PURE__ */ jsx(Tooltip, {
|
|
6976
|
+
title: "Abrir numa janela separada do navegador (ex.: em outro monitor)",
|
|
6977
|
+
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6978
|
+
size: "small",
|
|
6979
|
+
color: inWindow ? "primary" : "default",
|
|
6980
|
+
onClick: inWindow ? () => popup?.focus() : toWindow,
|
|
6981
|
+
"aria-label": "Devtools em janela separada",
|
|
6982
|
+
children: "↗"
|
|
6983
|
+
})
|
|
6984
|
+
}),
|
|
6985
|
+
/* @__PURE__ */ jsx(Tooltip, {
|
|
6986
|
+
title: "Fechar (Alt+Shift+B)",
|
|
6987
|
+
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6988
|
+
size: "small",
|
|
6989
|
+
onClick: closePanel,
|
|
6990
|
+
"aria-label": "Fechar devtools",
|
|
6991
|
+
children: "✕"
|
|
6992
|
+
})
|
|
6993
|
+
})
|
|
6994
|
+
]
|
|
6995
|
+
})
|
|
6996
|
+
]
|
|
6997
|
+
});
|
|
6998
|
+
const body = /* @__PURE__ */ jsxs(Box, {
|
|
6999
|
+
sx: {
|
|
7000
|
+
flex: 1,
|
|
7001
|
+
minHeight: 0
|
|
7002
|
+
},
|
|
7003
|
+
children: [
|
|
7004
|
+
ui.tab === "queries" && /* @__PURE__ */ jsx(QueriesPanel, {
|
|
7005
|
+
devtools,
|
|
7006
|
+
capabilities,
|
|
7007
|
+
selected,
|
|
7008
|
+
onSelect: setSelected,
|
|
7009
|
+
onHover: setHovered,
|
|
7010
|
+
onClearServerCache: clearServerCache
|
|
7011
|
+
}),
|
|
7012
|
+
ui.tab === "model" && needsModel((registered) => /* @__PURE__ */ jsx(ModelPanel, {
|
|
7013
|
+
devtools,
|
|
7014
|
+
original: registered,
|
|
7015
|
+
capabilities,
|
|
7016
|
+
tables: tables ?? [],
|
|
7017
|
+
onTry: (selection) => {
|
|
7018
|
+
setPlayground(selection);
|
|
7019
|
+
setTab("playground");
|
|
7020
|
+
},
|
|
7021
|
+
onSaved: () => setTimeout(() => loadModel(), 1e3)
|
|
7022
|
+
})),
|
|
7023
|
+
ui.tab === "layout" && needsModel((registered) => /* @__PURE__ */ jsx(LayoutPanel, {
|
|
7024
|
+
devtools,
|
|
7025
|
+
model: devtools.draft ?? registered,
|
|
7026
|
+
capabilities,
|
|
7027
|
+
picked: pickedItem,
|
|
7028
|
+
onHover: setHovered
|
|
7029
|
+
})),
|
|
7030
|
+
ui.tab === "playground" && needsModel((registered) => /* @__PURE__ */ jsx(PlaygroundPanel, {
|
|
7031
|
+
model: devtools.draft ?? registered,
|
|
7032
|
+
selection: playground,
|
|
7033
|
+
onSelectionChange: setPlayground
|
|
7034
|
+
})),
|
|
7035
|
+
ui.tab === "regression" && /* @__PURE__ */ jsx(RegressionPanel, {
|
|
7036
|
+
devtools,
|
|
7037
|
+
capabilities
|
|
7038
|
+
}),
|
|
7039
|
+
ui.tab === "dictionary" && /* @__PURE__ */ jsxs(Box, {
|
|
7040
|
+
sx: {
|
|
7041
|
+
p: 1.5,
|
|
7042
|
+
overflow: "auto",
|
|
7043
|
+
height: "100%"
|
|
7044
|
+
},
|
|
7045
|
+
children: [/* @__PURE__ */ jsxs(Typography, {
|
|
7046
|
+
sx: {
|
|
7047
|
+
fontSize: 12,
|
|
7048
|
+
color: "text.secondary",
|
|
7049
|
+
mb: 1.5
|
|
7050
|
+
},
|
|
7051
|
+
children: [
|
|
7052
|
+
"O mesmo ",
|
|
7053
|
+
/* @__PURE__ */ jsx("code", { children: "<ModelDictionary />" }),
|
|
7054
|
+
" pode ir numa página do dashboard como documentação para quem usa. Edite rótulos e descrições na aba Modelo."
|
|
7055
|
+
]
|
|
7056
|
+
}), /* @__PURE__ */ jsx(ModelDictionary, {})]
|
|
7057
|
+
}),
|
|
7058
|
+
ui.tab === "filters" && /* @__PURE__ */ jsx(FiltersPanel, { devtools })
|
|
7059
|
+
]
|
|
7060
|
+
});
|
|
6011
7061
|
return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(ThemeProvider, {
|
|
6012
7062
|
theme,
|
|
6013
7063
|
children: [
|
|
@@ -6016,7 +7066,26 @@ function DashboardDevtools() {
|
|
|
6016
7066
|
label: hoveredLabel,
|
|
6017
7067
|
zIndex: 1251
|
|
6018
7068
|
}),
|
|
6019
|
-
ui.open
|
|
7069
|
+
ui.open && inWindow && popup && /* @__PURE__ */ jsx(DevtoolsWindow, {
|
|
7070
|
+
popup,
|
|
7071
|
+
title: `BI Devtools · ${model}`,
|
|
7072
|
+
theme,
|
|
7073
|
+
onClosed: onPopupClosed,
|
|
7074
|
+
children: /* @__PURE__ */ jsxs(Paper, {
|
|
7075
|
+
...devtoolsMarker,
|
|
7076
|
+
square: true,
|
|
7077
|
+
elevation: 0,
|
|
7078
|
+
sx: {
|
|
7079
|
+
height: "100%",
|
|
7080
|
+
display: "flex",
|
|
7081
|
+
flexDirection: "column",
|
|
7082
|
+
color: "text.primary",
|
|
7083
|
+
overflow: "hidden"
|
|
7084
|
+
},
|
|
7085
|
+
children: [header, body]
|
|
7086
|
+
})
|
|
7087
|
+
}),
|
|
7088
|
+
ui.open && !inWindow ? /* @__PURE__ */ jsxs(Paper, {
|
|
6020
7089
|
...devtoolsMarker,
|
|
6021
7090
|
square: !floating,
|
|
6022
7091
|
elevation: floating ? 16 : 12,
|
|
@@ -6081,232 +7150,15 @@ function DashboardDevtools() {
|
|
|
6081
7150
|
cursor: "ns-resize"
|
|
6082
7151
|
}
|
|
6083
7152
|
}),
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
onDoubleClick: (event) => {
|
|
6087
|
-
if (floating && !event.target.closest("button, [role=\"tab\"]")) toggleMode();
|
|
6088
|
-
},
|
|
6089
|
-
sx: {
|
|
6090
|
-
display: "flex",
|
|
6091
|
-
alignItems: "center",
|
|
6092
|
-
gap: 1.5,
|
|
6093
|
-
px: 1.5,
|
|
6094
|
-
borderBottom: 1,
|
|
6095
|
-
borderColor: "divider",
|
|
6096
|
-
cursor: floating ? "move" : void 0,
|
|
6097
|
-
...side && {
|
|
6098
|
-
flexWrap: "wrap",
|
|
6099
|
-
columnGap: 1,
|
|
6100
|
-
pt: .5
|
|
6101
|
-
}
|
|
6102
|
-
},
|
|
6103
|
-
children: [
|
|
6104
|
-
/* @__PURE__ */ jsx(Typography, {
|
|
6105
|
-
sx: {
|
|
6106
|
-
fontWeight: 800,
|
|
6107
|
-
color: "primary.main",
|
|
6108
|
-
whiteSpace: "nowrap"
|
|
6109
|
-
},
|
|
6110
|
-
children: "◆ BI Devtools"
|
|
6111
|
-
}),
|
|
6112
|
-
/* @__PURE__ */ jsx(Chip, {
|
|
6113
|
-
size: "small",
|
|
6114
|
-
label: model,
|
|
6115
|
-
sx: { fontFamily: MONO }
|
|
6116
|
-
}),
|
|
6117
|
-
/* @__PURE__ */ jsxs(Tabs, {
|
|
6118
|
-
value: ui.tab,
|
|
6119
|
-
onChange: (_, tab) => setTab(tab),
|
|
6120
|
-
variant: "scrollable",
|
|
6121
|
-
scrollButtons: "auto",
|
|
6122
|
-
sx: {
|
|
6123
|
-
minHeight: 40,
|
|
6124
|
-
...side && {
|
|
6125
|
-
order: 1,
|
|
6126
|
-
width: "100%"
|
|
6127
|
-
}
|
|
6128
|
-
},
|
|
6129
|
-
children: [
|
|
6130
|
-
/* @__PURE__ */ jsx(Tab, {
|
|
6131
|
-
value: "queries",
|
|
6132
|
-
label: /* @__PURE__ */ jsxs(Box, {
|
|
6133
|
-
sx: {
|
|
6134
|
-
display: "flex",
|
|
6135
|
-
alignItems: "center",
|
|
6136
|
-
gap: .75
|
|
6137
|
-
},
|
|
6138
|
-
children: [
|
|
6139
|
-
"Consultas (",
|
|
6140
|
-
instances.length,
|
|
6141
|
-
")",
|
|
6142
|
-
!!loading && /* @__PURE__ */ jsx(CircularProgress, { size: 10 }),
|
|
6143
|
-
!!(errors || storms) && /* @__PURE__ */ jsx(Chip, {
|
|
6144
|
-
size: "small",
|
|
6145
|
-
color: "error",
|
|
6146
|
-
label: errors + storms,
|
|
6147
|
-
sx: { height: 16 }
|
|
6148
|
-
})
|
|
6149
|
-
]
|
|
6150
|
-
})
|
|
6151
|
-
}),
|
|
6152
|
-
/* @__PURE__ */ jsx(Tab, {
|
|
6153
|
-
value: "model",
|
|
6154
|
-
label: "Modelo"
|
|
6155
|
-
}),
|
|
6156
|
-
/* @__PURE__ */ jsx(Tab, {
|
|
6157
|
-
value: "layout",
|
|
6158
|
-
label: "Layout"
|
|
6159
|
-
}),
|
|
6160
|
-
/* @__PURE__ */ jsx(Tab, {
|
|
6161
|
-
value: "playground",
|
|
6162
|
-
label: "Playground"
|
|
6163
|
-
}),
|
|
6164
|
-
/* @__PURE__ */ jsx(Tab, {
|
|
6165
|
-
value: "regression",
|
|
6166
|
-
label: "Regressão"
|
|
6167
|
-
}),
|
|
6168
|
-
/* @__PURE__ */ jsx(Tab, {
|
|
6169
|
-
value: "dictionary",
|
|
6170
|
-
label: "Dicionário"
|
|
6171
|
-
}),
|
|
6172
|
-
/* @__PURE__ */ jsx(Tab, {
|
|
6173
|
-
value: "filters",
|
|
6174
|
-
label: "Filtros"
|
|
6175
|
-
})
|
|
6176
|
-
]
|
|
6177
|
-
}),
|
|
6178
|
-
devtools.draft && /* @__PURE__ */ jsx(Chip, {
|
|
6179
|
-
size: "small",
|
|
6180
|
-
color: "warning",
|
|
6181
|
-
label: "rascunho aplicado"
|
|
6182
|
-
}),
|
|
6183
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
6184
|
-
sx: {
|
|
6185
|
-
ml: "auto",
|
|
6186
|
-
display: "flex",
|
|
6187
|
-
alignItems: "center",
|
|
6188
|
-
gap: .5
|
|
6189
|
-
},
|
|
6190
|
-
children: [
|
|
6191
|
-
/* @__PURE__ */ jsx(Tooltip, {
|
|
6192
|
-
title: "Inspecionar componente (Alt+Shift+I)",
|
|
6193
|
-
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6194
|
-
size: "small",
|
|
6195
|
-
color: inspecting ? "primary" : "default",
|
|
6196
|
-
onClick: () => setInspecting((value) => !value),
|
|
6197
|
-
"aria-label": "Inspecionar componente",
|
|
6198
|
-
children: "⌖"
|
|
6199
|
-
})
|
|
6200
|
-
}),
|
|
6201
|
-
DOCK_SIDES.map(({ side: dock, icon, label }) => /* @__PURE__ */ jsx(Tooltip, {
|
|
6202
|
-
title: `${label} (ocupa espaço na página)`,
|
|
6203
|
-
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6204
|
-
size: "small",
|
|
6205
|
-
color: ui.mode === dock ? "primary" : "default",
|
|
6206
|
-
onClick: () => dockTo(dock),
|
|
6207
|
-
"aria-label": label,
|
|
6208
|
-
children: icon
|
|
6209
|
-
})
|
|
6210
|
-
}, dock)),
|
|
6211
|
-
/* @__PURE__ */ jsx(Tooltip, {
|
|
6212
|
-
title: "Janela flutuante, por cima da página (Alt+Shift+F) · arraste pelo cabeçalho",
|
|
6213
|
-
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6214
|
-
size: "small",
|
|
6215
|
-
color: floating ? "primary" : "default",
|
|
6216
|
-
onClick: toggleMode,
|
|
6217
|
-
"aria-label": "Devtools flutuante",
|
|
6218
|
-
children: "⧉"
|
|
6219
|
-
})
|
|
6220
|
-
}),
|
|
6221
|
-
/* @__PURE__ */ jsx(Tooltip, {
|
|
6222
|
-
title: "Fechar (Alt+Shift+B)",
|
|
6223
|
-
children: /* @__PURE__ */ jsx(IconButton, {
|
|
6224
|
-
size: "small",
|
|
6225
|
-
onClick: () => setUi((current) => ({
|
|
6226
|
-
...current,
|
|
6227
|
-
open: false
|
|
6228
|
-
})),
|
|
6229
|
-
"aria-label": "Fechar devtools",
|
|
6230
|
-
children: "✕"
|
|
6231
|
-
})
|
|
6232
|
-
})
|
|
6233
|
-
]
|
|
6234
|
-
})
|
|
6235
|
-
]
|
|
6236
|
-
}),
|
|
6237
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
6238
|
-
sx: {
|
|
6239
|
-
flex: 1,
|
|
6240
|
-
minHeight: 0
|
|
6241
|
-
},
|
|
6242
|
-
children: [
|
|
6243
|
-
ui.tab === "queries" && /* @__PURE__ */ jsx(QueriesPanel, {
|
|
6244
|
-
devtools,
|
|
6245
|
-
capabilities,
|
|
6246
|
-
selected,
|
|
6247
|
-
onSelect: setSelected,
|
|
6248
|
-
onHover: setHovered,
|
|
6249
|
-
onClearServerCache: clearServerCache
|
|
6250
|
-
}),
|
|
6251
|
-
ui.tab === "model" && needsModel((registered) => /* @__PURE__ */ jsx(ModelPanel, {
|
|
6252
|
-
devtools,
|
|
6253
|
-
original: registered,
|
|
6254
|
-
capabilities,
|
|
6255
|
-
tables: tables ?? [],
|
|
6256
|
-
onTry: (selection) => {
|
|
6257
|
-
setPlayground(selection);
|
|
6258
|
-
setTab("playground");
|
|
6259
|
-
},
|
|
6260
|
-
onSaved: () => setTimeout(() => loadModel(), 1e3)
|
|
6261
|
-
})),
|
|
6262
|
-
ui.tab === "layout" && needsModel((registered) => /* @__PURE__ */ jsx(LayoutPanel, {
|
|
6263
|
-
devtools,
|
|
6264
|
-
model: devtools.draft ?? registered,
|
|
6265
|
-
capabilities,
|
|
6266
|
-
picked: pickedItem,
|
|
6267
|
-
onHover: setHovered
|
|
6268
|
-
})),
|
|
6269
|
-
ui.tab === "playground" && needsModel((registered) => /* @__PURE__ */ jsx(PlaygroundPanel, {
|
|
6270
|
-
model: devtools.draft ?? registered,
|
|
6271
|
-
selection: playground,
|
|
6272
|
-
onSelectionChange: setPlayground
|
|
6273
|
-
})),
|
|
6274
|
-
ui.tab === "regression" && /* @__PURE__ */ jsx(RegressionPanel, {
|
|
6275
|
-
devtools,
|
|
6276
|
-
capabilities
|
|
6277
|
-
}),
|
|
6278
|
-
ui.tab === "dictionary" && /* @__PURE__ */ jsxs(Box, {
|
|
6279
|
-
sx: {
|
|
6280
|
-
p: 1.5,
|
|
6281
|
-
overflow: "auto",
|
|
6282
|
-
height: "100%"
|
|
6283
|
-
},
|
|
6284
|
-
children: [/* @__PURE__ */ jsxs(Typography, {
|
|
6285
|
-
sx: {
|
|
6286
|
-
fontSize: 12,
|
|
6287
|
-
color: "text.secondary",
|
|
6288
|
-
mb: 1.5
|
|
6289
|
-
},
|
|
6290
|
-
children: [
|
|
6291
|
-
"O mesmo ",
|
|
6292
|
-
/* @__PURE__ */ jsx("code", { children: "<ModelDictionary />" }),
|
|
6293
|
-
" pode ir numa página do dashboard como documentação para quem usa. Edite rótulos e descrições na aba Modelo."
|
|
6294
|
-
]
|
|
6295
|
-
}), /* @__PURE__ */ jsx(ModelDictionary, {})]
|
|
6296
|
-
}),
|
|
6297
|
-
ui.tab === "filters" && /* @__PURE__ */ jsx(FiltersPanel, { devtools })
|
|
6298
|
-
]
|
|
6299
|
-
})
|
|
7153
|
+
header,
|
|
7154
|
+
body
|
|
6300
7155
|
]
|
|
6301
7156
|
}) : /* @__PURE__ */ jsx(ToggleButton$1, {
|
|
6302
7157
|
draft: !!devtools.draft,
|
|
6303
7158
|
loading,
|
|
6304
7159
|
problems: errors + storms,
|
|
6305
7160
|
inspecting,
|
|
6306
|
-
onOpen: () =>
|
|
6307
|
-
...current,
|
|
6308
|
-
open: true
|
|
6309
|
-
}))
|
|
7161
|
+
onOpen: inWindow ? () => popup?.focus() : openPanel
|
|
6310
7162
|
}),
|
|
6311
7163
|
inspecting && /* @__PURE__ */ jsx(Box, {
|
|
6312
7164
|
...devtoolsMarker,
|
|
@@ -6394,4 +7246,4 @@ function ToggleButton$1({ draft, loading, problems, inspecting, onOpen }) {
|
|
|
6394
7246
|
//#endregion
|
|
6395
7247
|
export { DashboardDevtools as default };
|
|
6396
7248
|
|
|
6397
|
-
//# sourceMappingURL=DashboardDevtools-
|
|
7249
|
+
//# sourceMappingURL=DashboardDevtools-C8AXaFgw.js.map
|