@bluemarble/bi 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"DashboardDevtools-DLhEr3fN.js","names":["KEYWORDS","inputSx","ToggleButton"],"sources":["../src/devtools/sqlHighlight.tsx","../src/devtools/ui.tsx","../src/devtools/FiltersPanel.tsx","../src/devtools/Inspector.tsx","../src/devtools/lineDiff.ts","../src/devtools/LayoutPanel.tsx","../src/devtools/modelCode.ts","../src/devtools/SqlEditor.tsx","../src/devtools/modelFields.tsx","../src/devtools/DimensionPicker.tsx","../src/devtools/ModelDiagram.tsx","../src/devtools/ModelPanel.tsx","../src/devtools/PlaygroundPanel.tsx","../src/devtools/QueriesPanel.tsx","../src/devtools/RegressionPanel.tsx","../src/devtools/DashboardDevtools.tsx"],"sourcesContent":["import { type CSSProperties, type ReactNode, useMemo } from 'react'\n\n/**\n * Destaque de sintaxe do SQL do modelo (sem dependência de editor): um tokenizador pequeno que\n * reconhece o que aparece nos modelos — palavras-chave, funções, textos, números, comentários,\n * `tabela.coluna` e os marcadores `{keys}` / `{medida}`.\n */\n\nexport type TokenKind =\n | 'keyword'\n | 'function'\n | 'string'\n | 'number'\n | 'comment'\n | 'placeholder'\n | 'qualifier'\n | 'quoted'\n | 'plain'\n\nexport type Token = { kind: TokenKind; text: string }\n\nconst KEYWORDS = new Set(\n `SELECT FROM WHERE AND OR NOT IN IS NULL JOIN LEFT RIGHT INNER OUTER CROSS ON AS GROUP BY ORDER\n HAVING LIMIT OFFSET UNION ALL DISTINCT CASE WHEN THEN ELSE END WITH ASC DESC BETWEEN LIKE EXISTS\n INTERVAL TRUE FALSE USING OVER PARTITION ROLLUP`.split(/\\s+/)\n)\n\nconst PATTERN =\n /(--[^\\n]*|\\/\\*[\\s\\S]*?(?:\\*\\/|$))|('(?:[^'\\\\]|\\\\.)*'?|\"(?:[^\"\\\\]|\\\\.)*\"?)|(`[^`]*`?)|(\\{[A-Za-z_]\\w*\\})|(\\b\\d+(?:\\.\\d+)?\\b)|([A-Za-z_]\\w*)/g\n\nexport function tokenizeSql(sql: string): Token[] {\n const tokens: Token[] = []\n let last = 0\n for (const match of sql.matchAll(PATTERN)) {\n const index = match.index ?? 0\n if (index > last) tokens.push({ kind: 'plain', text: sql.slice(last, index) })\n const [text, comment, string, quoted, placeholder, number, word] = match\n let kind: TokenKind = 'plain'\n if (comment) kind = 'comment'\n else if (string) kind = 'string'\n else if (quoted) kind = 'quoted'\n else if (placeholder) kind = 'placeholder'\n else if (number) kind = 'number'\n else if (word) {\n const after = sql.slice(index + text.length)\n // Palavra-chave antes de função: `IN (`, `EXISTS (`, `OVER (`\n if (after.startsWith('.')) kind = 'qualifier'\n else if (KEYWORDS.has(word.toUpperCase())) kind = 'keyword'\n else if (/^\\s*\\(/.test(after)) kind = 'function'\n }\n tokens.push({ kind, text })\n last = index + text.length\n }\n if (last < sql.length) tokens.push({ kind: 'plain', text: sql.slice(last) })\n return tokens\n}\n\n// `style` em vez de `sx` (um span por token). Sem negrito nem itálico: no editor o texto colorido fica por\n// baixo do campo e precisa ter exatamente a mesma largura\nconst COLORS: Record<TokenKind, CSSProperties> = {\n keyword: { color: '#c792ea' },\n function: { color: '#82aaff' },\n string: { color: '#c3e88d' },\n number: { color: '#f78c6c' },\n comment: { color: '#697098' },\n placeholder: { color: '#ffcb6b' },\n qualifier: { color: '#89ddff' },\n quoted: { color: '#eeffff' },\n plain: {}\n}\n\n/** Os tokens como `<span>` coloridos (para dentro de um `<pre>`). */\nexport function HighlightedSql({ code }: { code: string }) {\n const parts = useMemo(() => tokenizeSql(code), [code])\n return (\n <>\n {parts.map((token, index): ReactNode =>\n token.kind === 'plain' ? (\n token.text\n ) : (\n // biome-ignore lint/suspicious/noArrayIndexKey: tokens recalculados a cada texto\n <span key={index} style={COLORS[token.kind]}>\n {token.text}\n </span>\n )\n )}\n </>\n )\n}\n","import {\n Box,\n Button,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Typography\n} from '@mui/material'\nimport { type ReactNode, useState } from 'react'\nimport type { RowDiff } from '../compare'\nimport type { DashboardRow } from '../types'\nimport type { DiffLine } from './lineDiff'\nimport { HighlightedSql } from './sqlHighlight'\nimport type { RunStatus } from './store'\n\nexport const MONO = 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace'\n\nexport const STATUS_COLOR: Record<RunStatus, string> = {\n loading: '#4dabf7',\n success: '#51cf66',\n error: '#ff6b6b',\n cancelled: '#868e96'\n}\n\nexport const STATUS_LABEL: Record<RunStatus, string> = {\n loading: 'carregando',\n success: 'ok',\n error: 'erro',\n cancelled: 'cancelada'\n}\n\nexport function StatusDot({ status }: { status: RunStatus }) {\n return (\n <Box\n component=\"span\"\n title={STATUS_LABEL[status]}\n sx={{\n width: 8,\n height: 8,\n flexShrink: 0,\n borderRadius: '50%',\n display: 'inline-block',\n bgcolor: STATUS_COLOR[status]\n }}\n />\n )\n}\n\nexport async function copyText(text: string) {\n try {\n await navigator.clipboard.writeText(text)\n return true\n } catch {\n return false\n }\n}\n\nexport function CopyButton({ text, label = 'Copiar' }: { text: string; label?: string }) {\n const [copied, setCopied] = useState(false)\n return (\n <Button\n size=\"small\"\n onClick={async () => {\n if (await copyText(text)) {\n setCopied(true)\n setTimeout(() => setCopied(false), 1200)\n }\n }}\n >\n {copied ? 'Copiado!' : label}\n </Button>\n )\n}\n\nexport function Section({\n title,\n actions,\n children\n}: {\n title: ReactNode\n actions?: ReactNode\n children: ReactNode\n}) {\n return (\n <Box sx={{ mb: 2 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5, minHeight: 30 }}>\n <Typography\n variant=\"overline\"\n sx={{ color: 'text.secondary', lineHeight: 1.5, fontWeight: 700 }}\n >\n {title}\n </Typography>\n <Box sx={{ ml: 'auto', display: 'flex', gap: 0.5 }}>{actions}</Box>\n </Box>\n {children}\n </Box>\n )\n}\n\nexport function CodeBlock({\n code,\n maxHeight = 260,\n sql = false\n}: {\n code: string\n maxHeight?: number\n /** Colore como SQL. */\n sql?: boolean\n}) {\n return (\n <Box sx={{ position: 'relative' }}>\n <Box\n component=\"pre\"\n sx={{\n m: 0,\n p: 1.25,\n pr: 9,\n maxHeight,\n overflow: 'auto',\n fontFamily: MONO,\n fontSize: 12,\n lineHeight: 1.5,\n bgcolor: 'rgba(0,0,0,.35)',\n borderRadius: 1,\n whiteSpace: 'pre'\n }}\n >\n {sql ? <HighlightedSql code={code} /> : code}\n </Box>\n <Box sx={{ position: 'absolute', top: 4, right: 4 }}>\n <CopyButton text={code} />\n </Box>\n </Box>\n )\n}\n\n/** Substitui os `?` pelos parâmetros, para colar o SQL direto num cliente de banco. */\nexport function inlineParams(sql: string, params: (string | number)[]) {\n let index = 0\n return sql.replace(/\\?/g, () => {\n const value = params[index++]\n if (value === undefined) return '?'\n return typeof value === 'number' ? String(value) : `'${value.replaceAll(\"'\", \"''\")}'`\n })\n}\n\nconst MAX_ROWS = 500\n\nexport function ResultTable({\n rows,\n maxHeight = 320\n}: {\n rows: DashboardRow[]\n maxHeight?: number\n}) {\n if (!rows.length)\n return <Typography sx={{ color: 'text.secondary', fontSize: 12 }}>Nenhuma linha.</Typography>\n const columns = Object.keys(rows[0])\n return (\n <>\n <TableContainer sx={{ maxHeight, border: 1, borderColor: 'divider', borderRadius: 1 }}>\n <Table size=\"small\" stickyHeader>\n <TableHead>\n <TableRow>\n {columns.map((column) => (\n <TableCell key={column} sx={{ fontFamily: MONO, fontWeight: 700 }}>\n {column}\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n <TableBody>\n {rows.slice(0, MAX_ROWS).map((row, index) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: linhas de resultado não têm id\n <TableRow key={index} hover>\n {columns.map((column) => (\n <TableCell\n key={column}\n align={typeof row[column] === 'number' ? 'right' : 'left'}\n sx={{ fontFamily: MONO, whiteSpace: 'nowrap' }}\n >\n {row[column] === null ? (\n <Box component=\"span\" sx={{ color: 'text.disabled' }}>\n null\n </Box>\n ) : (\n String(row[column])\n )}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n {rows.length > MAX_ROWS && (\n <Typography sx={{ color: 'text.secondary', fontSize: 12, mt: 0.5 }}>\n Mostrando {MAX_ROWS} de {rows.length} linhas.\n </Typography>\n )}\n </>\n )\n}\n\nexport function Empty({ children }: { children: ReactNode }) {\n return (\n <Box\n sx={{\n height: '100%',\n minHeight: 120,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: 'text.secondary',\n fontSize: 13,\n textAlign: 'center',\n p: 2\n }}\n >\n {children}\n </Box>\n )\n}\n\nconst DIFF_LINE_COLOR = {\n same: 'transparent',\n added: 'rgba(81, 207, 102, .18)',\n removed: 'rgba(255, 107, 107, .18)'\n} as const\n\n/** Diff de arquivo; linhas iguais longe de mudanças ficam recolhidas. */\nexport function FileDiff({ lines, context = 3 }: { lines: DiffLine[]; context?: number }) {\n const near = lines.map((_, index) =>\n lines\n .slice(Math.max(0, index - context), index + context + 1)\n .some((line) => line.kind !== 'same')\n )\n const output: ReactNode[] = []\n let skipped = 0\n lines.forEach((line, index) => {\n if (!near[index]) {\n skipped++\n return\n }\n if (skipped) {\n output.push(\n // biome-ignore lint/suspicious/noArrayIndexKey: posição do trecho recolhido no diff\n <Box key={`skip-${index}`} sx={{ color: 'text.disabled', px: 1 }}>\n ⋯ {skipped} linhas iguais\n </Box>\n )\n skipped = 0\n }\n output.push(\n // biome-ignore lint/suspicious/noArrayIndexKey: linhas de um diff fixo, sem id próprio\n <Box key={index} sx={{ bgcolor: DIFF_LINE_COLOR[line.kind], px: 1, whiteSpace: 'pre' }}>\n {line.kind === 'added' ? '+ ' : line.kind === 'removed' ? '- ' : ' '}\n {line.text}\n </Box>\n )\n })\n if (skipped)\n output.push(\n <Box key=\"skip-end\" sx={{ color: 'text.disabled', px: 1 }}>\n ⋯ {skipped} linhas iguais\n </Box>\n )\n return (\n <Box\n sx={{\n fontFamily: MONO,\n fontSize: 12,\n lineHeight: 1.5,\n bgcolor: 'rgba(0,0,0,.35)',\n borderRadius: 1,\n py: 1,\n overflow: 'auto',\n maxHeight: 420\n }}\n >\n {lines.some((line) => line.kind !== 'same') ? (\n output\n ) : (\n <Box sx={{ px: 1 }}>Sem mudanças.</Box>\n )}\n </Box>\n )\n}\n\nconst DIFF_KIND_LABEL: Record<RowDiff['kind'], string> = {\n missing: 'sumiu',\n extra: 'nova',\n changed: 'mudou'\n}\n\n/** Linhas que diferem entre dois resultados (esperado x atual). */\nexport function RowDiffTable({\n diffs,\n expectedLabel = 'esperado',\n actualLabel = 'atual'\n}: {\n diffs: RowDiff[]\n expectedLabel?: string\n actualLabel?: string\n}) {\n if (!diffs.length)\n return <Typography sx={{ color: 'success.main', fontSize: 12 }}>Resultados iguais.</Typography>\n return (\n <TableContainer sx={{ maxHeight: 320, border: 1, borderColor: 'divider', borderRadius: 1 }}>\n <Table size=\"small\" stickyHeader>\n <TableHead>\n <TableRow>\n <TableCell>linha</TableCell>\n <TableCell>dimensões</TableCell>\n <TableCell>medida</TableCell>\n <TableCell align=\"right\">{expectedLabel}</TableCell>\n <TableCell align=\"right\">{actualLabel}</TableCell>\n <TableCell align=\"right\">diferença</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {diffs.flatMap((diff) => {\n const where = JSON.stringify(diff.dimensions)\n if (diff.kind !== 'changed')\n return (\n <TableRow key={where}>\n <TableCell sx={{ color: diff.kind === 'missing' ? 'error.main' : 'info.main' }}>\n {DIFF_KIND_LABEL[diff.kind]}\n </TableCell>\n <TableCell sx={{ fontFamily: MONO }} colSpan={5}>\n {where}\n </TableCell>\n </TableRow>\n )\n return diff.changes.map((change) => (\n <TableRow key={`${where}-${change.measure}`}>\n <TableCell sx={{ color: 'warning.main' }}>{DIFF_KIND_LABEL.changed}</TableCell>\n <TableCell sx={{ fontFamily: MONO }}>{where}</TableCell>\n <TableCell sx={{ fontFamily: MONO }}>{change.measure}</TableCell>\n <TableCell align=\"right\" sx={{ fontFamily: MONO }}>\n {String(change.expected)}\n </TableCell>\n <TableCell align=\"right\" sx={{ fontFamily: MONO }}>\n {String(change.actual)}\n </TableCell>\n <TableCell align=\"right\" sx={{ fontFamily: MONO }}>\n {typeof change.expected === 'number' && typeof change.actual === 'number'\n ? (change.actual - change.expected).toFixed(4)\n : ''}\n </TableCell>\n </TableRow>\n ))\n })}\n </TableBody>\n </Table>\n </TableContainer>\n )\n}\n","import { Alert, Box, Button, Chip, TextField, Typography } from '@mui/material'\nimport { useEffect, useState } from 'react'\nimport type { DashboardDevtoolsContext } from '../client/DashboardProvider'\nimport { useDashboard } from '../client/DashboardProvider'\nimport type { DashboardFilters } from '../types'\nimport { MONO, Section } from './ui'\n\nfunction parseFilters(text: string): DashboardFilters {\n const parsed: unknown = JSON.parse(text)\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))\n throw new Error('Esperado um objeto { dimensão: [valores] }')\n for (const [name, values] of Object.entries(parsed)) {\n const valid =\n Array.isArray(values) &&\n values.every((value) => typeof value === 'string' || typeof value === 'number')\n if (!valid) throw new Error(`\"${name}\" precisa ser uma lista de textos/números`)\n }\n return parsed as DashboardFilters\n}\n\n/** Estado dos filtros do `DashboardProvider`, editável como JSON. */\nexport function FiltersPanel({ devtools }: { devtools: DashboardDevtoolsContext }) {\n const { filters, setFilter } = useDashboard()\n const current = JSON.stringify(filters, null, 2)\n const [text, setText] = useState(current)\n const [error, setError] = useState<string | null>(null)\n\n // Filtro alterado na página: o texto acompanha (descarta edição não aplicada)\n useEffect(() => {\n setText(current)\n setError(null)\n }, [current])\n\n const active = Object.entries(filters).filter(([, values]) => values.length)\n\n const apply = () => {\n try {\n devtools.setFilters(parseFilters(text))\n setError(null)\n } catch (err) {\n setError((err as Error).message)\n }\n }\n\n return (\n <Box sx={{ p: 1.5, overflow: 'auto', height: '100%' }}>\n <Section\n title=\"Filtros ativos\"\n actions={\n <>\n <Button size=\"small\" onClick={() => devtools.setFilters(devtools.defaultFilters)}>\n Restaurar padrão\n </Button>\n <Button size=\"small\" onClick={() => devtools.setFilters({})}>\n Limpar tudo\n </Button>\n </>\n }\n >\n <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>\n {active.map(([name, values]) => (\n <Chip\n key={name}\n size=\"small\"\n label={`${name}: ${values.join(', ')}`}\n onDelete={() => setFilter(name, [])}\n sx={{ fontFamily: MONO }}\n />\n ))}\n {!active.length && (\n <Typography sx={{ fontSize: 12, color: 'text.secondary' }}>\n Nenhum filtro: tudo aparece como \"Todos\".\n </Typography>\n )}\n </Box>\n </Section>\n\n <Section\n title=\"Editar como JSON\"\n actions={\n <Button size=\"small\" variant=\"contained\" disabled={text === current} onClick={apply}>\n Aplicar\n </Button>\n }\n >\n <TextField\n fullWidth\n multiline\n minRows={6}\n maxRows={18}\n value={text}\n onChange={(e) => setText(e.target.value)}\n error={!!error}\n sx={{ '& .MuiInputBase-input': { fontFamily: MONO, fontSize: 12 } }}\n />\n {error && (\n <Alert severity=\"error\" sx={{ mt: 1 }}>\n {error}\n </Alert>\n )}\n </Section>\n\n <Section title=\"Padrão do provider (defaultFilters)\">\n <Typography sx={{ fontFamily: MONO, fontSize: 12 }}>\n {JSON.stringify(devtools.defaultFilters)}\n </Typography>\n </Section>\n </Box>\n )\n}\n","import { Box } from '@mui/material'\nimport { useEffect, useState } from 'react'\nimport { INSPECT_ATTRIBUTE } from '../client/useModelQuery'\n\n/**\n * Liga componente da página <-> consulta do devtools. Os componentes marcam o elemento raiz com\n * `inspectProps` do `useModelQuery` (`data-bm-dashboard-query=\"<instanceId>\"`).\n */\n\n/** Marca os elementos do próprio painel, que o modo de inspeção ignora. */\nexport const DEVTOOLS_ATTRIBUTE = 'data-bm-devtools'\n\nexport const findQueryElement = (instanceId: string) =>\n document.querySelector<HTMLElement>(`[${INSPECT_ATTRIBUTE}=\"${CSS.escape(instanceId)}\"]`)\n\nexport function scrollToQuery(instanceId: string) {\n findQueryElement(instanceId)?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n}\n\n/** Retângulo do elemento, acompanhando scroll/resize. */\nfunction useElementRect(instanceId: string | null) {\n const [rect, setRect] = useState<DOMRect | null>(null)\n useEffect(() => {\n if (!instanceId) {\n setRect(null)\n return\n }\n let frame = 0\n const update = () => {\n setRect(findQueryElement(instanceId)?.getBoundingClientRect() ?? null)\n frame = requestAnimationFrame(update)\n }\n update()\n return () => cancelAnimationFrame(frame)\n }, [instanceId])\n return rect\n}\n\nexport function HighlightOverlay({\n instanceId,\n label,\n zIndex\n}: {\n instanceId: string | null\n label?: string\n zIndex: number\n}) {\n const rect = useElementRect(instanceId)\n if (!rect) return null\n return (\n <Box\n sx={{\n position: 'fixed',\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n zIndex,\n pointerEvents: 'none',\n outline: '2px solid #F58220',\n bgcolor: 'rgba(245, 130, 32, .12)',\n borderRadius: 0.5\n }}\n >\n {label && (\n <Box\n sx={{\n position: 'absolute',\n left: -2,\n bottom: '100%',\n px: 0.75,\n py: 0.25,\n bgcolor: '#F58220',\n color: '#111',\n fontSize: 11,\n fontWeight: 700,\n whiteSpace: 'nowrap',\n fontFamily: 'ui-monospace, monospace'\n }}\n >\n {label}\n </Box>\n )}\n </Box>\n )\n}\n\n/**\n * Modo de inspeção: passar o mouse num componente do dashboard destaca a consulta dele; clicar\n * seleciona no painel. O clique é engolido para não acionar o componente.\n */\nexport function useInspectMode({\n active,\n onHover,\n onPick\n}: {\n active: boolean\n onHover: (instanceId: string | null) => void\n onPick: (instanceId: string) => void\n}) {\n useEffect(() => {\n if (!active) return\n const target = (event: Event) => {\n const element = event.target as Element | null\n if (!element?.closest || element.closest(`[${DEVTOOLS_ATTRIBUTE}]`)) return null\n return element.closest(`[${INSPECT_ATTRIBUTE}]`)?.getAttribute(INSPECT_ATTRIBUTE) ?? null\n }\n const move = (event: MouseEvent) => onHover(target(event))\n const click = (event: MouseEvent) => {\n const instanceId = target(event)\n if (!instanceId) return\n event.preventDefault()\n event.stopPropagation()\n onPick(instanceId)\n }\n // O Select do MUI abre no mousedown, antes do click\n const press = (event: MouseEvent) => {\n if (!target(event)) return\n event.preventDefault()\n event.stopPropagation()\n }\n const previousCursor = document.body.style.cursor\n document.body.style.cursor = 'crosshair'\n document.addEventListener('mousemove', move, true)\n document.addEventListener('mousedown', press, true)\n document.addEventListener('click', click, true)\n return () => {\n document.body.style.cursor = previousCursor\n document.removeEventListener('mousemove', move, true)\n document.removeEventListener('mousedown', press, true)\n document.removeEventListener('click', click, true)\n onHover(null)\n }\n }, [active, onHover, onPick])\n}\n","export type DiffLine = { kind: 'same' | 'added' | 'removed'; text: string }\n\n/** Diff de linhas por LCS. Suficiente para arquivos de modelo (centenas de linhas). */\nexport function lineDiff(before: string, after: string): DiffLine[] {\n const a = before.split('\\n')\n const b = after.split('\\n')\n const lcs: number[][] = Array.from({ length: a.length + 1 }, () =>\n new Array(b.length + 1).fill(0)\n )\n for (let i = a.length - 1; i >= 0; i--)\n for (let j = b.length - 1; j >= 0; j--)\n lcs[i][j] = a[i] === b[j] ? lcs[i + 1][j + 1] + 1 : Math.max(lcs[i + 1][j], lcs[i][j + 1])\n\n const lines: DiffLine[] = []\n let i = 0\n let j = 0\n while (i < a.length && j < b.length) {\n if (a[i] === b[j]) {\n lines.push({ kind: 'same', text: a[i++] })\n j++\n } else if (lcs[i + 1][j] >= lcs[i][j + 1]) lines.push({ kind: 'removed', text: a[i++] })\n else lines.push({ kind: 'added', text: b[j++] })\n }\n while (i < a.length) lines.push({ kind: 'removed', text: a[i++] })\n while (j < b.length) lines.push({ kind: 'added', text: b[j++] })\n return lines\n}\n","import {\n Alert,\n Box,\n Button,\n Checkbox,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n IconButton,\n Menu,\n MenuItem,\n TextField,\n Tooltip,\n Typography\n} from '@mui/material'\nimport {\n type ChangeEvent,\n type DragEvent,\n type ReactNode,\n useEffect,\n useMemo,\n useState,\n useSyncExternalStore\n} from 'react'\nimport type { DashboardDevtoolsContext } from '../client/DashboardProvider'\nimport { useDashboard } from '../client/DashboardProvider'\nimport { INSPECT_ATTRIBUTE } from '../client/useModelQuery'\nimport { canonicalJson } from '../codegen'\nimport {\n CANVAS_PRESETS,\n type CanvasDef,\n CHART_FIELDS,\n CHART_TYPE_LABEL,\n CHART_TYPES,\n type ChartDef,\n type ChartsLayout,\n type ChartType,\n chartColumns,\n chartOfType,\n chartReferences,\n FILTER_FIELDS,\n type FieldSpec,\n type FilterDef,\n filterReferences,\n LAYOUT_COLUMNS,\n layoutFileContent,\n layoutModelWarnings,\n validateLayout\n} from '../layout'\nimport type { ModelDef } from '../model'\nimport type { DevtoolsCapabilities, SaveModelResult } from '../types'\nimport {\n LAYOUT_ITEM_ATTRIBUTE,\n type LayoutItem,\n layoutItemKey,\n parseLayoutItemKey\n} from './layoutStore'\nimport { lineDiff } from './lineDiff'\nimport { errorMessage } from './store'\nimport { CopyButton, Empty, FileDiff, MONO, Section } from './ui'\n\ntype Props = {\n devtools: DashboardDevtoolsContext\n /** Modelo em vigor (rascunho, se houver), para listar dimensões e medidas. */\n model: ModelDef\n capabilities: DevtoolsCapabilities | null\n /** Item escolhido pelo inspetor (`layoutItemKey`); objeto novo a cada clique. */\n picked: { item: string } | null\n /** Destaca a consulta do gráfico na página. */\n onHover: (instanceId: string | null) => void\n}\n\nconst inputSx = { '& .MuiInputBase-input': { fontFamily: MONO, fontSize: 12 } }\n\nconst itemElement = (layoutId: string, item: LayoutItem) =>\n document.querySelector<HTMLElement>(\n `[${LAYOUT_ITEM_ATTRIBUTE}=\"${CSS.escape(layoutItemKey(layoutId, item))}\"]`\n )\n\nconst itemQueryId = (layoutId: string, item: LayoutItem) =>\n itemElement(layoutId, item)\n ?.querySelector(`[${INSPECT_ATTRIBUTE}]`)\n ?.getAttribute(INSPECT_ATTRIBUTE) ?? null\n\n/** Item escolhido na lista: a tela (`layout.canvas`), um filtro ou um gráfico. */\ntype Selection = LayoutItem | { kind: 'canvas' }\n\ntype DragState = { kind: LayoutItem['kind']; from: number; to: number }\n\nconst SIDEBAR_KEY = 'bm-dashboard-devtools:layout-sidebar'\n\n/** Abaixo disso a lista vai para cima do formulário, em vez de ficar ao lado. */\nconst STACK_WIDTH = 640\n\nfunction loadSidebar() {\n try {\n return localStorage.getItem(SIDEBAR_KEY) !== 'closed'\n } catch {\n return true\n }\n}\n\n/** Largura do elemento, acompanhando o redimensionamento do devtools. */\nfunction useWidth() {\n const [element, setElement] = useState<HTMLElement | null>(null)\n const [width, setWidth] = useState(Number.POSITIVE_INFINITY)\n useEffect(() => {\n if (!element) return\n const observer = new ResizeObserver(([entry]) => entry && setWidth(entry.contentRect.width))\n observer.observe(element)\n return () => observer.disconnect()\n }, [element])\n return [setElement, width] as const\n}\n\n/** Move o item `from` para antes da posição `to` (`to === list.length` = fim). */\nfunction moveTo<T>(list: T[], from: number, to: number) {\n const next = [...list]\n const [item] = next.splice(from, 1)\n next.splice(to > from ? to - 1 : to, 0, item as T)\n return next\n}\n\nconst uniqueId = (charts: ChartDef[], base: string) => {\n const ids = new Set(charts.map((chart) => chart.id))\n if (!ids.has(base)) return base\n let n = 2\n while (ids.has(`${base}-${n}`)) n++\n return `${base}-${n}`\n}\n\n/** Campo opcional vazio sai do objeto, para o JSON ficar só com o que foi definido. */\nfunction withField<T extends object>(object: T, key: keyof T, value: unknown): T {\n const next = { ...object }\n if (value === undefined || value === '') delete next[key]\n else (next as Record<keyof T, unknown>)[key] = value\n return next\n}\n\nconst NEW_CHART: Record<ChartType, { id: string; title: string; span: number }> = {\n kpi: { id: 'kpi', title: 'Novo KPI', span: 3 },\n combo: { id: 'grafico', title: 'Novo gráfico', span: 6 },\n bar: { id: 'grafico', title: 'Novo gráfico', span: 6 },\n donut: { id: 'grafico', title: 'Novo gráfico', span: 6 },\n table: { id: 'tabela', title: 'Nova tabela', span: 12 }\n}\n\nconst newChart = (type: ChartType, model: ModelDef, charts: ChartDef[]) => {\n const { id, ...rest } = NEW_CHART[type]\n return chartOfType(type, model, { id: uniqueId(charts, id), ...rest })\n}\n\nconst chartSummary = (chart: ChartDef) => {\n const { dimensions, measures } = chartReferences(chart)\n return `${chart.type} · ${dimensions.join(', ') || '—'} · ${measures.join(', ')}`\n}\n\n/**\n * Editor dos layouts da página (filtros do `<DashboardFilters>` e gráficos do `<DashboardCharts>`).\n * Cada edição válida vira rascunho na hora — a página re-renderiza com ele — e \"Salvar no arquivo\"\n * grava o JSON do layout.\n */\nexport function LayoutPanel({ devtools, model, capabilities, picked, onHover }: Props) {\n const { layouts } = devtools\n const { fetcher, model: modelName } = useDashboard()\n const entries = useSyncExternalStore(layouts.subscribe, layouts.getSnapshot, layouts.getSnapshot)\n const [layoutId, setLayoutId] = useState<string | null>(null)\n const entry = entries.find((item) => item.registered.id === layoutId) ?? entries[0] ?? null\n const reference = entry ? (entry.draft ?? entry.registered) : null\n\n const [editing, setEditing] = useState<ChartsLayout | null>(reference)\n const [selection, setSelection] = useState<Selection | null>(null)\n const [sidebar, setSidebar] = useState(loadSidebar)\n const [drag, setDrag] = useState<DragState | null>(null)\n const [rootRef, rootWidth] = useWidth()\n const [editorRef, editorWidth] = useWidth()\n const [busy, setBusy] = useState(false)\n const [actionError, setActionError] = useState<string | null>(null)\n const [save, setSave] = useState<SaveModelResult | null>(null)\n const [addMenu, setAddMenu] = useState<HTMLElement | null>(null)\n\n // Rascunho descartado, arquivo recarregado ou outro layout: o editor acompanha\n const referenceKey = canonicalJson(reference)\n useEffect(() => setEditing(reference), [referenceKey])\n\n // Inspetor clicou num gráfico\n useEffect(() => {\n const parsed = picked && parseLayoutItemKey(picked.item)\n if (!parsed) return\n setLayoutId(parsed.layoutId)\n setSelection(parsed.item)\n }, [picked])\n\n const errors = useMemo(() => (editing ? validateLayout(editing) : []), [editing])\n const warnings = useMemo(() => {\n if (!editing || errors.length) return []\n const list = layoutModelWarnings(editing, model)\n const { charts: chartFormatters = [], filters: filterFormatters } = entry?.parts ?? {}\n for (const chart of editing.charts)\n for (const name of chartReferences(chart).formatters)\n if (!chartFormatters.includes(name))\n list.push(\n `\"${chart.title || chart.id}\": formatter \"${name}\" não foi passado ao <DashboardCharts formatters>`\n )\n if (editing.canvas && !entry?.parts.canvas)\n list.push(\n 'A página não usa <DashboardCanvas layout={...}>: o tamanho fixo da tela não é aplicado.'\n )\n if (editing.filters?.length && !filterFormatters)\n list.push(\n 'A página não usa <DashboardFilters layout={...}>: os filtros do layout não aparecem.'\n )\n for (const filter of editing.filters ?? [])\n for (const name of filterReferences(filter).formatters)\n if (filterFormatters && !filterFormatters.includes(name))\n list.push(\n `filtro \"${filter.dimension}\": formatter \"${name}\" não foi passado ao <DashboardFilters formatters>`\n )\n return list\n }, [editing, errors, model, entry])\n\n if (!entry || !editing)\n return (\n <Empty>\n Nenhum <code>{'<DashboardCharts layout={...} />'}</code> ou{' '}\n <code>{'<DashboardFilters layout={...} />'}</code> nesta página. Os gráficos e filtros\n editáveis pelo devtools vêm de um layout em JSON (ex.:{' '}\n <code>src/dashboard/layouts/&lt;id&gt;.json</code>\n ).\n </Empty>\n )\n\n const charts = editing.charts\n const filters = editing.filters ?? []\n const selectedFilter =\n selection?.kind === 'filter'\n ? (filters.find((filter) => filter.dimension === selection.key) ?? null)\n : null\n const selected =\n selection?.kind === 'filter' || selection?.kind === 'canvas'\n ? null\n : (charts.find((chart) => chart.id === selection?.key) ?? charts[0] ?? null)\n const layoutKey = entry.registered.id\n const differsFromFile = canonicalJson(editing) !== canonicalJson(entry.registered)\n\n // Toda edição válida vai direto pra página\n const update = (next: ChartsLayout) => {\n setEditing(next)\n setSave(null)\n if (!validateLayout(next).length) {\n devtools.store.expectRefetch()\n layouts.setDraft(entry.registered.id, next)\n }\n }\n const setCharts = (next: ChartDef[]) => update({ ...editing, charts: next })\n const patchChart = (id: string, change: (chart: ChartDef) => ChartDef) =>\n setCharts(charts.map((chart) => (chart.id === id ? change(chart) : chart)))\n\n const setCanvas = (next: CanvasDef | undefined) => update(withField(editing, 'canvas', next))\n\n const setFilters = (next: FilterDef[]) => update({ ...editing, filters: next })\n const patchFilter = (dimension: string, change: (filter: FilterDef) => FilterDef) =>\n setFilters(filters.map((filter) => (filter.dimension === dimension ? change(filter) : filter)))\n\n const toggleSidebar = () => {\n const next = !sidebar\n setSidebar(next)\n try {\n localStorage.setItem(SIDEBAR_KEY, next ? 'open' : 'closed')\n } catch {}\n }\n\n // Arrastar para reordenar: só dentro da mesma lista (filtros ou gráficos)\n const dragProps = (kind: LayoutItem['kind'], index: number, length: number) => ({\n dropBefore: drag?.kind === kind && drag.from !== index && drag.to === index,\n dropAfter: drag?.kind === kind && index === length - 1 && drag.to === length,\n onDragStart: () => setDrag({ kind, from: index, to: index }),\n onDragOver: (e: DragEvent<HTMLElement>) => {\n if (drag?.kind !== kind) return\n e.preventDefault()\n const rect = e.currentTarget.getBoundingClientRect()\n const to = e.clientY < rect.top + rect.height / 2 ? index : index + 1\n if (to !== drag.to) setDrag({ ...drag, to })\n },\n onDrop: () => {\n if (drag?.kind !== kind) return\n if (drag.to !== drag.from && drag.to !== drag.from + 1)\n if (kind === 'chart') setCharts(moveTo(charts, drag.from, drag.to))\n else setFilters(moveTo(filters, drag.from, drag.to))\n setDrag(null)\n },\n onDragEnd: () => setDrag(null)\n })\n\n const addFilter = () => {\n // Primeira dimensão que ainda não tem filtro\n const used = new Set(filters.map((filter) => filter.dimension))\n const dimension = Object.keys(model.dimensions).find((name) => !used.has(name))\n if (!dimension) return\n setFilters([...filters, { dimension }])\n setSelection({ kind: 'filter', key: dimension })\n }\n\n const focus = (item: LayoutItem) => {\n setSelection(item)\n // Lista empilhada sobre o formulário: fecha para o formulário ter espaço\n if (stacked) setSidebar(false)\n itemElement(layoutKey, item)?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n const stacked = rootWidth < STACK_WIDTH\n const formColumns = editorWidth < 420 ? 1 : editorWidth < 720 ? 2 : 4\n const selectedTitle =\n selection?.kind === 'canvas'\n ? 'Tela'\n : selectedFilter\n ? selectedFilter.label ||\n model.dimensions[selectedFilter.dimension]?.label ||\n selectedFilter.dimension\n : selected\n ? selected.title || selected.id\n : ''\n const hover = (item: LayoutItem | null) => onHover(item && itemQueryId(layoutKey, item))\n\n const add = (type: ChartType, base?: ChartDef) => {\n setAddMenu(null)\n const chart = base\n ? { ...base, id: uniqueId(charts, base.id), title: `${base.title} (cópia)` }\n : newChart(type, model, charts)\n const index = base ? charts.findIndex((item) => item.id === base.id) + 1 : charts.length\n setCharts([...charts.slice(0, index), chart, ...charts.slice(index)])\n setSelection({ kind: 'chart', key: chart.id })\n setTimeout(() =>\n itemElement(layoutKey, { kind: 'chart', key: chart.id })?.scrollIntoView({ block: 'center' })\n )\n }\n\n const saveFile = async (mode: 'preview' | 'write') => {\n setBusy(true)\n setActionError(null)\n try {\n const result = await fetcher({\n model: modelName,\n devtools: { saveLayout: { layout: editing, mode } }\n })\n // Gravado: o Next recarrega o JSON e o rascunho some sozinho quando bater com o arquivo\n setSave(mode === 'write' ? null : (result.devtools?.save ?? null))\n } catch (error) {\n setActionError(errorMessage(error))\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <Box\n ref={rootRef}\n sx={{ display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0 }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n px: 1,\n py: 0.5,\n borderBottom: 1,\n borderColor: 'divider'\n }}\n >\n <SmallButton\n title={sidebar ? 'Recolher a lista' : 'Mostrar a lista'}\n onClick={toggleSidebar}\n >\n {sidebar ? '«' : '☰'}\n </SmallButton>\n <Typography noWrap sx={{ fontSize: 12, fontWeight: 700 }}>\n {stacked && sidebar ? `Layout ${layoutKey}` : selectedTitle}\n </Typography>\n </Box>\n <Box sx={{ flex: 1, minHeight: 0, display: 'flex' }}>\n {sidebar && (\n <Box\n sx={{\n overflow: 'auto',\n p: 1.5,\n ...(stacked\n ? { flex: 1 }\n : { width: 280, flexShrink: 0, borderRight: 1, borderColor: 'divider' })\n }}\n >\n {entries.length > 1 && (\n <TextField\n select\n size=\"small\"\n fullWidth\n label=\"Layout\"\n value={entry.registered.id}\n onChange={(e) => setLayoutId(e.target.value)}\n sx={{ ...inputSx, mb: 1.5 }}\n >\n {entries.map((item) => (\n <MenuItem key={item.registered.id} value={item.registered.id}>\n {item.registered.id}\n {item.draft ? ' · rascunho' : ''}\n </MenuItem>\n ))}\n </TextField>\n )}\n <Section title=\"Tela\">\n <ItemRow\n title={editing.canvas ? 'Tamanho fixo' : 'Responsiva'}\n subtitle={\n editing.canvas ? presetLabel(editing.canvas) : 'reorganiza conforme a largura'\n }\n selected={selection?.kind === 'canvas'}\n onSelect={() => {\n setSelection({ kind: 'canvas' })\n if (stacked) setSidebar(false)\n }}\n />\n </Section>\n <Section\n title={`Filtros (${filters.length})`}\n actions={\n <Button\n size=\"small\"\n onClick={addFilter}\n disabled={filters.length >= Object.keys(model.dimensions).length}\n >\n + Novo\n </Button>\n }\n >\n {!filters.length && (\n <Typography sx={{ fontSize: 12, color: 'text.disabled', mb: 1 }}>\n Nenhum filtro no layout.\n </Typography>\n )}\n {filters.map((filter, index) => {\n const item: LayoutItem = { kind: 'filter', key: filter.dimension }\n return (\n <ItemRow\n key={filter.dimension}\n title={\n filter.label || model.dimensions[filter.dimension]?.label || filter.dimension\n }\n subtitle={`${filter.dimension}${filter.formatLabel ? ` · ${filter.formatLabel}` : ''}`}\n selected={selectedFilter?.dimension === filter.dimension}\n onSelect={() => focus(item)}\n onHover={(on) => hover(on ? item : null)}\n {...dragProps('filter', index, filters.length)}\n onRemove={() =>\n setFilters(filters.filter((other) => other.dimension !== filter.dimension))\n }\n />\n )\n })}\n </Section>\n <Section\n title={`Gráficos (${charts.length})`}\n actions={\n <>\n <Button size=\"small\" onClick={(e) => setAddMenu(e.currentTarget)}>\n + Novo\n </Button>\n <Menu anchorEl={addMenu} open={!!addMenu} onClose={() => setAddMenu(null)}>\n {CHART_TYPES.map((type) => (\n <MenuItem key={type} dense onClick={() => add(type)}>\n {CHART_TYPE_LABEL[type]}\n </MenuItem>\n ))}\n </Menu>\n </>\n }\n >\n {charts.map((chart, index) => {\n const item: LayoutItem = { kind: 'chart', key: chart.id }\n return (\n <ItemRow\n key={chart.id}\n title={chart.title || '(sem título)'}\n subtitle={`${chartSummary(chart)} · ${chart.span ?? LAYOUT_COLUMNS}/${LAYOUT_COLUMNS}`}\n selected={chart.id === selected?.id}\n onSelect={() => focus(item)}\n onHover={(on) => hover(on ? item : null)}\n {...dragProps('chart', index, charts.length)}\n onDuplicate={() => add(chart.type, chart)}\n onRemove={() => setCharts(charts.filter((other) => other.id !== chart.id))}\n />\n )\n })}\n </Section>\n </Box>\n )}\n\n {!(stacked && sidebar) && (\n <Box ref={editorRef} sx={{ flex: 1, minWidth: 0, overflow: 'auto' }}>\n <Box sx={{ p: 1.5 }}>\n {entry.draft && (\n <Alert severity=\"warning\" sx={{ mb: 1.5 }}>\n Rascunho aplicado: a página mostra o layout editado, não o arquivo{' '}\n <code>{entry.registered.id}.json</code>.\n {capabilities?.saveLayout\n ? ' Use \"Salvar no arquivo\" quando terminar.'\n : ' Copie o JSON para o arquivo quando terminar.'}\n </Alert>\n )}\n {!!errors.length && (\n <Alert severity=\"error\" sx={{ mb: 1.5 }}>\n Layout inválido — as edições não foram aplicadas na página:\n {errors.map((error) => (\n <div key={error}>{error}</div>\n ))}\n </Alert>\n )}\n {!!warnings.length && (\n <Alert severity=\"warning\" sx={{ mb: 1.5 }}>\n {warnings.map((warning) => (\n <div key={warning}>{warning}</div>\n ))}\n </Alert>\n )}\n {actionError && (\n <Alert severity=\"error\" sx={{ mb: 1.5, fontFamily: MONO, fontSize: 12 }}>\n {actionError}\n </Alert>\n )}\n {selection?.kind === 'canvas' ? (\n <CanvasForm canvas={editing.canvas} columns={formColumns} onChange={setCanvas} />\n ) : selectedFilter ? (\n <FilterForm\n key={`filter:${selectedFilter.dimension}`}\n filter={selectedFilter}\n model={model}\n formatters={entry.parts.filters ?? []}\n columns={formColumns}\n onChange={(change) => {\n patchFilter(selectedFilter.dimension, change)\n setSelection({ kind: 'filter', key: change(selectedFilter).dimension })\n }}\n />\n ) : selected ? (\n <ChartForm\n key={`chart:${selected.id}`}\n chart={selected}\n model={model}\n formatters={entry.parts.charts ?? []}\n columns={formColumns}\n onChange={(change) => {\n patchChart(selected.id, change)\n setSelection({ kind: 'chart', key: change(selected).id })\n }}\n />\n ) : (\n <Empty>Escolha a tela, um filtro ou um gráfico, ou use \"+ Novo\".</Empty>\n )}\n </Box>\n </Box>\n )}\n </Box>\n\n <Box\n sx={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 1,\n justifyContent: 'flex-end',\n alignItems: 'center',\n px: 1.5,\n py: 1,\n borderTop: 1,\n borderColor: 'divider'\n }}\n >\n <CopyButton text={layoutFileContent(editing)} label=\"Copiar JSON\" />\n <Button\n size=\"small\"\n color=\"warning\"\n disabled={!entry.draft && !differsFromFile}\n onClick={() => {\n devtools.store.expectRefetch()\n layouts.setDraft(entry.registered.id, null)\n setEditing(entry.registered)\n }}\n title=\"Volta ao layout do arquivo\"\n >\n Descartar rascunho\n </Button>\n {capabilities?.saveLayout && (\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={!differsFromFile || !!errors.length || busy}\n onClick={() => saveFile('preview')}\n title={`Reescreve ${entry.registered.id}.json`}\n >\n {busy ? 'Gerando…' : 'Salvar no arquivo'}\n </Button>\n )}\n </Box>\n\n <Dialog open={!!save} onClose={() => setSave(null)} maxWidth=\"lg\" fullWidth>\n <DialogTitle>Salvar layout no arquivo</DialogTitle>\n <DialogContent>\n <Typography sx={{ fontFamily: MONO, fontSize: 12, mb: 1 }}>{save?.path}</Typography>\n {save?.warnings.map((warning) => (\n <Alert key={warning} severity=\"warning\" sx={{ mb: 1 }}>\n {warning}\n </Alert>\n ))}\n {save && <FileDiff lines={lineDiff(save.previous, save.content)} />}\n <Typography sx={{ fontSize: 12, color: 'text.secondary', mt: 1 }}>\n O Next recarrega o JSON sozinho; o rascunho some quando a página receber o arquivo novo.\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setSave(null)}>Cancelar</Button>\n <Button\n variant=\"contained\"\n disabled={!save || save.previous === save.content || busy}\n onClick={() => saveFile('write')}\n >\n Gravar\n </Button>\n </DialogActions>\n </Dialog>\n </Box>\n )\n}\n\nconst presetLabel = ({ width, height }: CanvasDef) => `${width}×${height ?? 'auto'}`\n\n/** Tamanho fixo da tela (`layout.canvas`): desligado = responsivo. */\nfunction CanvasForm({\n canvas,\n columns,\n onChange\n}: {\n canvas: CanvasDef | undefined\n columns: number\n onChange: (next: CanvasDef | undefined) => void\n}) {\n const preset = canvas && CANVAS_PRESETS.find((item) => presetLabel(item) === presetLabel(canvas))\n const number = (value: string) => (value === '' ? undefined : Number(value))\n return (\n <Section title=\"Tela\">\n <Box sx={formGrid(columns)}>\n <Box sx={{ gridColumn: '1 / -1' }}>\n {withHint(\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n checked={!!canvas}\n onChange={(e) =>\n onChange(e.target.checked ? (CANVAS_PRESETS[0] as CanvasDef) : undefined)\n }\n />\n }\n label={<Typography sx={{ fontSize: 12 }}>Tamanho fixo</Typography>}\n />,\n 'Desenha o dashboard nesse tamanho e escala para caber na tela, mantendo a proporção, em vez de reorganizar os gráficos. A página precisa do <DashboardCanvas>.'\n )}\n </Box>\n {canvas && (\n <>\n {field(\n 'Predefinido',\n <TextField\n select\n size=\"small\"\n fullWidth\n value={preset ? presetLabel(preset) : ''}\n onChange={(e) =>\n onChange(CANVAS_PRESETS.find((item) => presetLabel(item) === e.target.value))\n }\n sx={inputSx}\n >\n {CANVAS_PRESETS.map((item) => (\n <MenuItem key={presetLabel(item)} value={presetLabel(item)}>\n {presetLabel(item)}\n </MenuItem>\n ))}\n </TextField>\n )}\n {field(\n 'Largura',\n <TextField\n size=\"small\"\n fullWidth\n type=\"number\"\n value={canvas.width ?? ''}\n onChange={(e) => onChange(withField(canvas, 'width', number(e.target.value)))}\n sx={inputSx}\n />\n )}\n {field(\n 'Altura mín.',\n <TextField\n size=\"small\"\n fullWidth\n type=\"number\"\n value={canvas.height ?? ''}\n placeholder=\"auto\"\n onChange={(e) => onChange(withField(canvas, 'height', number(e.target.value)))}\n sx={inputSx}\n />\n )}\n </>\n )}\n </Box>\n </Section>\n )\n}\n\nfunction ItemRow({\n title,\n subtitle,\n selected,\n onSelect,\n onHover,\n onDuplicate,\n onRemove,\n dropBefore,\n dropAfter,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd\n}: {\n title: string\n subtitle: string\n selected: boolean\n onSelect: () => void\n onHover?: (hovering: boolean) => void\n onDuplicate?: () => void\n /** Ausente = item fixo (a tela). */\n onRemove?: () => void\n /** Marca onde o item arrastado vai cair. */\n dropBefore?: boolean\n dropAfter?: boolean\n /** Presente = item arrastável. */\n onDragStart?: () => void\n onDragOver?: (e: DragEvent<HTMLElement>) => void\n onDrop?: () => void\n onDragEnd?: () => void\n}) {\n const marker = {\n content: '\"\"',\n position: 'absolute',\n left: 0,\n right: 0,\n height: 2,\n bgcolor: 'primary.main'\n }\n return (\n <Box\n onClick={onSelect}\n onMouseEnter={() => onHover?.(true)}\n onMouseLeave={() => onHover?.(false)}\n draggable={!!onDragStart}\n onDragStart={(e) => {\n if (!onDragStart) return\n e.dataTransfer.effectAllowed = 'move'\n // Firefox só arrasta com algum dado\n e.dataTransfer.setData('text/plain', title)\n onDragStart()\n }}\n onDragOver={onDragOver}\n onDrop={(e) => {\n e.preventDefault()\n onDrop?.()\n }}\n onDragEnd={onDragEnd}\n sx={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n gap: 0.5,\n px: 1,\n py: 0.5,\n mb: 0.5,\n borderRadius: 1,\n cursor: onDragStart ? 'grab' : 'pointer',\n border: 1,\n borderColor: selected ? 'primary.main' : 'divider',\n '&:hover .item-actions': { visibility: 'visible' },\n '&::before': dropBefore ? { ...marker, top: -4 } : undefined,\n '&::after': dropAfter ? { ...marker, bottom: -4 } : undefined\n }}\n >\n {onDragStart && (\n <Box\n component=\"span\"\n aria-hidden\n sx={{ color: 'text.disabled', fontSize: 12, lineHeight: 1, userSelect: 'none' }}\n >\n ⋮⋮\n </Box>\n )}\n <Box sx={{ minWidth: 0, flex: 1 }}>\n <Typography noWrap sx={{ fontSize: 12, fontWeight: 700 }}>\n {title}\n </Typography>\n <Typography noWrap sx={{ fontSize: 11, color: 'text.secondary', fontFamily: MONO }}>\n {subtitle}\n </Typography>\n </Box>\n {(onDuplicate || onRemove) && (\n <Box\n className=\"item-actions\"\n onClick={(e) => e.stopPropagation()}\n sx={{ display: 'flex', visibility: selected ? 'visible' : 'hidden' }}\n >\n {onDuplicate && (\n <SmallButton title=\"Duplicar\" onClick={onDuplicate}>\n ⧉\n </SmallButton>\n )}\n {onRemove && (\n <SmallButton title=\"Remover\" onClick={onRemove}>\n ×\n </SmallButton>\n )}\n </Box>\n )}\n </Box>\n )\n}\n\nfunction SmallButton({\n title,\n disabled,\n onClick,\n children\n}: {\n title: string\n disabled?: boolean\n onClick: () => void\n children: ReactNode\n}) {\n return (\n <Tooltip title={title}>\n <span>\n <IconButton\n size=\"small\"\n disabled={disabled}\n onClick={onClick}\n aria-label={title}\n sx={{ p: 0.25, fontSize: 13 }}\n >\n {children}\n </IconButton>\n </span>\n </Tooltip>\n )\n}\n\nfunction ChartForm({\n chart,\n model,\n formatters,\n columns,\n onChange\n}: {\n chart: ChartDef\n model: ModelDef\n formatters: string[]\n /** Colunas do formulário (encolhe com a largura do devtools). */\n columns: number\n onChange: (change: (chart: ChartDef) => ChartDef) => void\n}) {\n const set = (key: string, value: unknown) =>\n onChange((current) => withField(current as Record<string, unknown>, key, value) as ChartDef)\n return (\n <FieldsForm\n fields={CHART_FIELDS[chart.type]}\n values={chart as unknown as Record<string, unknown>}\n onSet={set}\n model={model}\n formatters={formatters}\n columns={chartColumns(chart)}\n formColumns={columns}\n chosenDimensions={chartReferences(chart).dimensions}\n header={\n <>\n {field(\n 'Tipo',\n <TextField\n select\n size=\"small\"\n fullWidth\n value={chart.type}\n // Troca de tipo: mantém id, título, largura e o que der de dimensões/medidas\n onChange={(e) =>\n onChange((current) => chartOfType(e.target.value as ChartType, model, current))\n }\n sx={inputSx}\n >\n {CHART_TYPES.map((type) => (\n <MenuItem key={type} value={type}>\n {CHART_TYPE_LABEL[type]}\n </MenuItem>\n ))}\n </TextField>\n )}\n {field(\n 'id',\n <TextField\n size=\"small\"\n fullWidth\n value={chart.id}\n error={!/^[A-Za-z0-9_-]{1,80}$/.test(chart.id)}\n onChange={(e) => set('id', e.target.value)}\n sx={inputSx}\n />,\n 'Identificador no JSON (letras, números, \"-\" e \"_\")'\n )}\n </>\n }\n />\n )\n}\n\nfunction FilterForm({\n filter,\n model,\n formatters,\n columns,\n onChange\n}: {\n filter: FilterDef\n model: ModelDef\n formatters: string[]\n columns: number\n onChange: (change: (filter: FilterDef) => FilterDef) => void\n}) {\n return (\n <FieldsForm\n fields={FILTER_FIELDS}\n values={filter as unknown as Record<string, unknown>}\n onSet={(key, value) =>\n onChange(\n (current) => withField(current as Record<string, unknown>, key, value) as FilterDef\n )\n }\n model={model}\n formatters={formatters}\n columns={[]}\n formColumns={columns}\n chosenDimensions={[filter.dimension]}\n />\n )\n}\n\n/** Formulário gerado dos `FieldSpec` (campos do tipo de gráfico ou do filtro). */\nfunction FieldsForm({\n fields,\n values,\n onSet: set,\n model,\n formatters,\n columns,\n formColumns,\n chosenDimensions,\n header\n}: {\n fields: Record<string, FieldSpec>\n values: Record<string, unknown>\n onSet: (key: string, value: unknown) => void\n model: ModelDef\n formatters: string[]\n /** Opções dos campos `column` (ex.: `sortBy`). */\n columns: string[]\n formColumns: number\n /** Dimensões já escolhidas (campos `formatters`). */\n chosenDimensions: string[]\n /** Campos fixos no começo da primeira seção (tipo, id). */\n header?: ReactNode\n}) {\n const dimensions = Object.entries(model.dimensions).map(([name, dim]) => ({\n name,\n label: dim.label\n }))\n const measures = Object.entries(model.measures).map(([name, measure]) => ({\n name,\n label: measure.label\n }))\n const entries = Object.entries(fields)\n\n const options = (spec: FieldSpec): Option[] => {\n switch (spec.kind) {\n case 'dimension':\n case 'dimensions':\n return dimensions\n case 'measure':\n case 'measures':\n return measures\n case 'formatter':\n return formatters.map((name) => ({ name }))\n case 'column':\n return columns.map((name) => ({\n name,\n label: model.dimensions[name]?.label ?? model.measures[name]?.label\n }))\n case 'enum':\n return spec.values.map((name) => ({ name, label: spec.labels?.[name] }))\n default:\n return []\n }\n }\n\n const input = (key: string, spec: FieldSpec): ReactNode => {\n const value = values[key]\n switch (spec.kind) {\n case 'text':\n return (\n <TextField\n size=\"small\"\n fullWidth\n value={(value as string | undefined) ?? ''}\n placeholder={labelPlaceholder(key, values, model)}\n onChange={(e) => set(key, e.target.value)}\n sx={inputSx}\n />\n )\n case 'color': {\n const fallback = spec.default as string\n return (\n <Box sx={{ display: 'flex', gap: 0.5, alignItems: 'center' }}>\n <Box\n component=\"input\"\n type=\"color\"\n value={(value as string | undefined) ?? fallback}\n onChange={(e: ChangeEvent<HTMLInputElement>) => set(key, e.target.value)}\n sx={{\n width: 32,\n height: 30,\n p: 0,\n border: 0,\n bgcolor: 'transparent',\n cursor: 'pointer'\n }}\n />\n <TextField\n size=\"small\"\n fullWidth\n value={(value as string | undefined) ?? ''}\n placeholder={fallback}\n onChange={(e) => set(key, e.target.value)}\n sx={inputSx}\n />\n </Box>\n )\n }\n case 'boolean': {\n const fallback = spec.default as boolean\n return (\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n checked={(value as boolean | undefined) ?? fallback}\n // Igual ao padrão do componente: sai do JSON\n onChange={(e) =>\n set(key, e.target.checked === fallback ? undefined : e.target.checked)\n }\n />\n }\n label={<Typography sx={{ fontSize: 12 }}>{spec.label}</Typography>}\n />\n )\n }\n case 'integer':\n // Largura: lista fechada, mais rápida que digitar\n if (key === 'span')\n return (\n <TextField\n select\n size=\"small\"\n fullWidth\n value={(value as number | undefined) ?? spec.default}\n onChange={(e) => {\n const span = Number(e.target.value)\n set(key, span === spec.default ? undefined : span)\n }}\n sx={inputSx}\n >\n {Array.from({ length: spec.max }, (_, i) => i + 1).map((span) => (\n <MenuItem key={span} value={span}>\n {span}/{spec.max}\n </MenuItem>\n ))}\n </TextField>\n )\n return (\n <TextField\n size=\"small\"\n fullWidth\n type=\"number\"\n value={(value as number | undefined) ?? ''}\n placeholder={spec.default === undefined ? '' : String(spec.default)}\n error={\n typeof value === 'number' &&\n (!Number.isInteger(value) || value < spec.min || value > spec.max)\n }\n onChange={(e) =>\n set(key, e.target.value.trim() === '' ? undefined : Number(e.target.value))\n }\n sx={inputSx}\n />\n )\n case 'dimensions':\n case 'measures':\n return (\n <MultiNameSelect\n value={(value as string[] | undefined) ?? []}\n options={options(spec)}\n required={!!spec.required}\n onChange={(next) => set(key, next.length || spec.required ? next : undefined)}\n />\n )\n case 'formatters': {\n const map = (value as Record<string, string> | undefined) ?? {}\n if (!chosenDimensions.length)\n return (\n <Typography sx={{ fontSize: 12, color: 'text.disabled' }}>sem dimensões</Typography>\n )\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>\n {chosenDimensions.map((dimension) => (\n <Box key={dimension} sx={{ display: 'flex', gap: 0.5, alignItems: 'center' }}>\n <Typography sx={{ fontFamily: MONO, fontSize: 12, minWidth: 90 }}>\n {dimension}\n </Typography>\n <NameSelect\n value={map[dimension] ?? ''}\n options={formatters.map((name) => ({ name }))}\n onChange={(name) => {\n const next = withField(map, dimension, name)\n set(key, Object.keys(next).length ? next : undefined)\n }}\n />\n </Box>\n ))}\n </Box>\n )\n }\n default:\n return (\n <NameSelect\n value={(value as string | undefined) ?? ''}\n options={options(spec)}\n required={spec.required}\n emptyLabel={\n spec.kind === 'enum' && spec.default\n ? `padrão (${spec.labels?.[spec.default as string] ?? spec.default})`\n : undefined\n }\n onChange={(name) => set(key, name === spec.default ? undefined : name)}\n />\n )\n }\n }\n\n // Seções na ordem em que aparecem nos campos\n const sections = [...new Set(entries.map(([, spec]) => spec.section))]\n const wide = (spec: FieldSpec, key: string) =>\n key === 'title' ||\n spec.kind === 'dimensions' ||\n spec.kind === 'measures' ||\n spec.kind === 'formatters'\n\n return (\n <>\n {sections.map((section) => {\n const inSection = entries.filter(([, spec]) => spec.section === section)\n return (\n <Section key={section} title={section}>\n <Box sx={formGrid(formColumns)}>\n {section === sections[0] && header}\n {inSection.map(([key, spec]) => (\n <Box\n key={key}\n sx={{\n gridColumn: wide(spec, key) && formColumns > 1 ? 'span 2' : undefined,\n alignSelf: spec.kind === 'boolean' ? 'end' : undefined\n }}\n >\n {spec.kind === 'boolean'\n ? withHint(input(key, spec), spec.hint)\n : field(spec.label, input(key, spec), spec.hint)}\n </Box>\n ))}\n </Box>\n </Section>\n )\n })}\n </>\n )\n}\n\ntype Option = { name: string; label?: string }\n\nconst formGrid = (columns: number) => ({\n display: 'grid',\n gap: 1.5,\n gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`\n})\n\n/** Rótulo padrão (do dicionário) como placeholder dos campos `*Label` do combo. */\nfunction labelPlaceholder(key: string, values: Record<string, unknown>, model: ModelDef) {\n if (key === 'label' && typeof values.dimension === 'string')\n return model.dimensions[values.dimension]?.label ?? values.dimension\n const measureKey = key.endsWith('Label') ? key.slice(0, -'Label'.length) : null\n const measure = measureKey && values[measureKey]\n return typeof measure === 'string' ? (model.measures[measure]?.label ?? measure) : undefined\n}\n\nfunction field(label: string, input: ReactNode, hint?: string) {\n return (\n <Box>\n <Typography sx={{ fontSize: 11, color: 'text.secondary', mb: 0.25 }}>\n {label}\n {hint && (\n <Tooltip title={hint}>\n <Box component=\"span\" sx={{ ml: 0.5, cursor: 'help' }}>\n ⓘ\n </Box>\n </Tooltip>\n )}\n </Typography>\n {input}\n </Box>\n )\n}\n\nfunction withHint(input: ReactNode, hint?: string) {\n return hint ? (\n <Tooltip title={hint} placement=\"top-start\">\n <Box>{input}</Box>\n </Tooltip>\n ) : (\n input\n )\n}\n\nfunction OptionText({ option }: { option: Option }) {\n return (\n <>\n {option.name}\n {option.label && option.label !== option.name && (\n <Box component=\"span\" sx={{ color: 'text.secondary', ml: 1 }}>\n {option.label}\n </Box>\n )}\n </>\n )\n}\n\nfunction NameSelect({\n value,\n options,\n required,\n emptyLabel,\n onChange\n}: {\n value: string\n options: Option[]\n required?: boolean\n /** Texto da opção vazia (padrão: \"(nenhum)\"). */\n emptyLabel?: string\n onChange: (value: string) => void\n}) {\n const known = !value || options.some((option) => option.name === value)\n return (\n <TextField\n select\n size=\"small\"\n fullWidth\n value={value}\n error={!known || (!!required && !value)}\n onChange={(e) => onChange(e.target.value)}\n sx={inputSx}\n >\n {!required && (\n <MenuItem value=\"\">\n <em>{emptyLabel ?? '(nenhum)'}</em>\n </MenuItem>\n )}\n {!known && <MenuItem value={value}>{value} (não existe)</MenuItem>}\n {options.map((option) => (\n <MenuItem key={option.name} value={option.name}>\n <OptionText option={option} />\n </MenuItem>\n ))}\n </TextField>\n )\n}\n\n/** Lista ordenada de nomes: a ordem de escolha é a ordem das séries/colunas. */\nfunction MultiNameSelect({\n value,\n options,\n required,\n onChange\n}: {\n value: string[]\n options: Option[]\n required: boolean\n onChange: (value: string[]) => void\n}) {\n const unknown = value.filter((name) => !options.some((option) => option.name === name))\n return (\n <TextField\n select\n size=\"small\"\n fullWidth\n value={value}\n error={!!unknown.length || (required && !value.length)}\n onChange={(e) => {\n const next = e.target.value as unknown as string[]\n // O Select devolve na ordem dos cliques: novos vão pro fim\n onChange(next)\n }}\n slotProps={{\n select: {\n multiple: true,\n renderValue: (selected) => (selected as string[]).join(', ') || '(nenhum)',\n displayEmpty: true\n }\n }}\n sx={inputSx}\n >\n {unknown.map((name) => (\n <MenuItem key={name} value={name}>\n {name} (não existe)\n </MenuItem>\n ))}\n {options.map((option) => (\n <MenuItem key={option.name} value={option.name} dense>\n <Checkbox size=\"small\" checked={value.includes(option.name)} sx={{ p: 0.25, mr: 1 }} />\n {value.includes(option.name) && (\n <Box component=\"span\" sx={{ color: 'primary.main', mr: 0.75, fontFamily: MONO }}>\n {value.indexOf(option.name) + 1}\n </Box>\n )}\n <OptionText option={option} />\n </MenuItem>\n ))}\n </TextField>\n )\n}\n","import {\n type Aggregation,\n type DiagramPosition,\n type DimensionDef,\n type FieldMeta,\n isAggregate,\n type MeasureDef,\n type MeasureMeta,\n type ModelDef,\n type TableDef,\n type ValueFormat,\n validateModel\n} from '../model'\nimport { parseColumnRef } from '../star'\n\n/**\n * Conversão entre o modelo (objetos indexados por nome) e as linhas da tabela do editor. As linhas\n * têm `uid` próprio para que renomear uma dimensão/medida não perca o foco nem a posição. Os\n * metadados ficam como texto (vazio = ausente) e só viram o formato do modelo em `fromEditor`.\n */\n\ntype MetaFields = { label: string; description: string }\n\nexport type DimensionRow = MetaFields & {\n uid: string\n name: string\n type: 'number' | 'string'\n sql: string\n}\nexport type MeasureRow = MetaFields & {\n uid: string\n name: string\n type: Aggregation | 'ratio' | 'formula'\n /** Expressão agregada (`sum`, `count`, `avg`...). */\n sql: string\n /** Fórmula (`{medida}`). */\n expression: string\n numerator: string\n denominator: string\n format: ValueFormat | ''\n decimals: string\n}\nexport type TableRow = MetaFields & {\n uid: string\n name: string\n key: string\n sql: string\n}\n/** Lado N (`from`) e lado 1 (`to`); a tabela vai pelo `uid`, para renomear sem quebrar. */\nexport type RelationshipRow = {\n uid: string\n fromTable: string\n fromColumn: string\n toTable: string\n toColumn: string\n inner: boolean\n}\n\nexport type EditorModel = {\n name: string\n dimensions: DimensionRow[]\n measures: MeasureRow[]\n tables: TableRow[]\n relationships: RelationshipRow[]\n /**\n * Posições do diagrama pelo `uid` da tabela: renomear não perde a posição, e o que foi removido\n * some do arquivo sozinho.\n */\n positions: Record<string, DiagramPosition>\n}\n\nlet uidCounter = 0\nexport const newUid = () => `row-${++uidCounter}`\n\nconst metaFields = (field: FieldMeta): MetaFields => ({\n label: field.label ?? '',\n description: field.description ?? ''\n})\n\nexport function toEditor(model: ModelDef): EditorModel {\n const tables: TableRow[] = Object.entries(model.tables).map(([name, table]) => ({\n uid: newUid(),\n name,\n key: table.key ?? '',\n sql: table.sql,\n ...metaFields(table)\n }))\n const uidOf = (name: string) => tables.find((table) => table.name === name)?.uid ?? ''\n const positions = Object.fromEntries(\n Object.entries(model.diagram ?? {}).flatMap(([name, point]) => {\n const uid = uidOf(name)\n return uid ? [[uid, { x: point.x, y: point.y }]] : []\n })\n )\n return {\n name: model.name,\n tables,\n relationships: (model.relationships ?? []).map((relationship) => {\n const from = parseColumnRef(relationship.from)\n const to = parseColumnRef(relationship.to)\n return {\n uid: newUid(),\n fromTable: uidOf(from?.table ?? ''),\n fromColumn: from?.column ?? '',\n toTable: uidOf(to?.table ?? ''),\n toColumn: to?.column ?? '',\n inner: relationship.inner === true\n }\n }),\n dimensions: Object.entries(model.dimensions).map(([name, dimension]) => ({\n uid: newUid(),\n name,\n type: dimension.type,\n sql: dimension.sql,\n ...metaFields(dimension)\n })),\n measures: Object.entries(model.measures).map(([name, measure]) => ({\n uid: newUid(),\n name,\n type: measure.type,\n sql: isAggregate(measure) ? measure.sql : '',\n expression: measure.type === 'formula' ? measure.expression : '',\n numerator: measure.type === 'ratio' ? measure.numerator : '',\n denominator: measure.type === 'ratio' ? measure.denominator : '',\n format: measure.format ?? '',\n decimals: measure.decimals === undefined ? '' : String(measure.decimals),\n ...metaFields(measure)\n })),\n positions\n }\n}\n\nconst fieldMeta = (row: MetaFields): FieldMeta => ({\n ...(row.label.trim() && { label: row.label.trim() }),\n ...(row.description.trim() && { description: row.description.trim() })\n})\n\nexport const dimensionOf = (row: DimensionRow): DimensionDef => ({\n sql: row.sql,\n type: row.type,\n ...fieldMeta(row)\n})\n\nexport function measureOf(row: MeasureRow): MeasureDef {\n const meta: MeasureMeta = {\n ...fieldMeta(row),\n ...(row.format && { format: row.format }),\n // Texto inválido vira NaN e a validação do modelo acusa\n ...(row.decimals.trim() && { decimals: Number(row.decimals) })\n }\n if (isAggregate(row)) return { type: row.type, sql: row.sql, ...meta }\n if (row.type === 'formula') return { type: 'formula', expression: row.expression, ...meta }\n return { type: 'ratio', numerator: row.numerator, denominator: row.denominator, ...meta }\n}\n\nexport const tableOf = (row: TableRow): TableDef => ({\n ...(row.key.trim() && { key: row.key.trim() }),\n sql: row.sql,\n ...fieldMeta(row)\n})\n\nexport function relationshipOf(editor: EditorModel, row: RelationshipRow) {\n const name = (uid: string) => editor.tables.find((table) => table.uid === uid)?.name ?? '?'\n return {\n from: `${name(row.fromTable)}.${row.fromColumn}`,\n to: `${name(row.toTable)}.${row.toColumn}`,\n ...(row.inner && { inner: true })\n }\n}\n\nexport function fromEditor(editor: EditorModel): ModelDef {\n const diagram = diagramOf(editor)\n return {\n name: editor.name,\n tables: Object.fromEntries(editor.tables.map((row) => [row.name, tableOf(row)])),\n ...(editor.relationships.length && {\n relationships: editor.relationships.map((row) => relationshipOf(editor, row))\n }),\n dimensions: Object.fromEntries(editor.dimensions.map((row) => [row.name, dimensionOf(row)])),\n measures: Object.fromEntries(editor.measures.map((row) => [row.name, measureOf(row)])),\n ...(Object.keys(diagram).length && { diagram })\n }\n}\n\n/** Posições pelo nome, na ordem dos cards; arredonda (o arquivo não precisa de frações). */\nfunction diagramOf(editor: EditorModel): Record<string, DiagramPosition> {\n return Object.fromEntries(\n editor.tables.flatMap(({ uid, name }) => {\n const point = editor.positions[uid]\n return point && name ? [[name, { x: Math.round(point.x), y: Math.round(point.y) }]] : []\n })\n )\n}\n\n/** O modelo sem as posições do diagrama: o que muda as consultas. */\nexport const withoutDiagram = ({ diagram: _, ...model }: ModelDef): ModelDef => model\n\n/** Erros do editor: nomes repetidos (que o objeto do modelo esconderia) + validação do modelo. */\nexport function validateEditor(editor: EditorModel): string[] {\n const repeated = (names: string[]) => [\n ...new Set(names.filter((name, index) => names.indexOf(name) !== index))\n ]\n const names = [...editor.dimensions, ...editor.measures].map((row) => row.name)\n const tables = editor.tables.map((row) => row.name)\n return [\n ...repeated(names).map((name) => `nome repetido: \"${name}\"`),\n ...repeated(tables).map((name) => `tabela repetida: \"${name}\"`),\n ...validateModel(fromEditor(editor)).filter((error) => !error.startsWith('nome repetido'))\n ]\n}\n\nconst escapeRegex = (text: string) => text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\n/**\n * Renomeia uma tabela e as referências `antigo.coluna` nas dimensões e medidas (os\n * relacionamentos e as posições do diagrama apontam pelo `uid` e acompanham sozinhos).\n */\nexport function renameTable(editor: EditorModel, uid: string, name: string): EditorModel {\n const previous = editor.tables.find((row) => row.uid === uid)?.name\n if (!previous || previous === name) return editor\n const pattern = new RegExp(`(?<![\\\\w.\\`])${escapeRegex(previous)}\\\\.`, 'g')\n const replace = (sql: string) => sql.replace(pattern, `${name}.`)\n return {\n ...editor,\n tables: editor.tables.map((table) => (table.uid === uid ? { ...table, name } : table)),\n dimensions: editor.dimensions.map((row) => ({ ...row, sql: replace(row.sql) })),\n measures: editor.measures.map((row) => ({ ...row, sql: replace(row.sql) }))\n }\n}\n\nexport const emptyMeasure = (changes: Partial<MeasureRow> = {}): MeasureRow => ({\n uid: newUid(),\n name: '',\n type: 'sum',\n sql: '',\n expression: '',\n numerator: '',\n denominator: '',\n format: '',\n decimals: '',\n label: '',\n description: '',\n ...changes\n})\n\nexport const emptyDimension = (changes: Partial<DimensionRow> = {}): DimensionRow => ({\n uid: newUid(),\n name: '',\n type: 'string',\n sql: '',\n label: '',\n description: '',\n ...changes\n})\n\n/** Nome livre a partir de `prefixo`, `prefixo2`, `prefixo3`... */\nexport function freeName(prefix: string, taken: string[]) {\n if (!taken.includes(prefix)) return prefix\n for (let index = 2; ; index++)\n if (!taken.includes(`${prefix}${index}`)) return `${prefix}${index}`\n}\n","import {\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n MenuItem,\n MenuList,\n Paper,\n Popper,\n TextField\n} from '@mui/material'\nimport { createContext, useContext, useRef, useState } from 'react'\nimport type { SchemaTable } from '../types'\nimport { HighlightedSql } from './sqlHighlight'\nimport { MONO } from './ui'\n\n/**\n * Campo de SQL com destaque de sintaxe e autocomplete de tabelas e colunas. As colunas vêm do\n * `information_schema` (tabelas/views do banco) e das colunas de cada tabela do modelo (lidas do banco).\n * O ⤢ abre o mesmo SQL num editor grande.\n *\n * O destaque é um `<pre>` colorido por baixo do `<textarea>` de texto transparente: mesma fonte,\n * mesmo recuo e mesma quebra de linha, com a rolagem sincronizada. O cursor, a seleção e o\n * autocomplete continuam sendo do textarea.\n */\n\n// Recuo do texto dentro do campo (o lado direito abre espaço para o ⤢)\nconst PAD = { top: 8.5, right: 30, bottom: 8.5, left: 12 }\nconst LINE_HEIGHT = '18px'\n\nexport type SqlCompletions = {\n tables: SchemaTable[]\n /** Colunas de cada tabela do modelo (`tabela.` completa com elas). */\n modelColumns: Record<string, string[]>\n}\n\nexport const SqlCompletionsContext = createContext<SqlCompletions>({\n tables: [],\n modelColumns: {}\n})\n\ntype Suggestion = { text: string; detail: string }\n\nconst KEYWORDS = new Set(\n 'WHERE ON LEFT RIGHT INNER OUTER JOIN GROUP ORDER LIMIT USING AND OR AS SET HAVING UNION'.split(\n ' '\n )\n)\n\n/** `alias -> tabela` a partir dos `FROM x a` / `JOIN x AS a` do texto. */\nfunction aliases(sql: string) {\n const map = new Map<string, string>()\n for (const match of sql.matchAll(/\\b(?:FROM|JOIN)\\s+`?(\\w+)`?(?:\\s+(?:AS\\s+)?`?(\\w+)`?)?/gi)) {\n const [, table, alias] = match\n map.set(table.toLowerCase(), table)\n if (alias && !KEYWORDS.has(alias.toUpperCase())) map.set(alias.toLowerCase(), table)\n }\n return map\n}\n\nfunction suggest(sql: string, caret: number, completions: SqlCompletions) {\n const before = sql.slice(0, caret)\n const tables = new Map(completions.tables.map((table) => [table.name.toLowerCase(), table]))\n const columnsOf = (table: string): Suggestion[] =>\n tables.get(table.toLowerCase())?.columns.map((column) => ({\n text: column.name,\n detail: column.type\n })) ?? []\n\n let prefix: string\n let candidates: Suggestion[]\n const qualified = /([A-Za-z_]\\w*)\\.(\\w*)$/.exec(before)\n if (qualified) {\n const [, qualifier, typed] = qualified\n prefix = typed\n if (completions.modelColumns[qualifier])\n candidates = completions.modelColumns[qualifier].map((text) => ({ text, detail: qualifier }))\n else candidates = columnsOf(aliases(sql).get(qualifier.toLowerCase()) ?? qualifier)\n } else {\n const word = /[A-Za-z_]\\w*$/.exec(before)\n if (!word || word[0].length < 2) return null\n prefix = word[0]\n const referenced = [...new Set(aliases(sql).values())]\n candidates = [\n ...Object.keys(completions.modelColumns).map((text) => ({\n text,\n detail: 'tabela do modelo'\n })),\n ...completions.tables.map((table) => ({ text: table.name, detail: table.type })),\n ...referenced.flatMap(columnsOf)\n ]\n }\n\n const lower = prefix.toLowerCase()\n const seen = new Set<string>()\n const items = candidates\n .filter((item) => {\n const text = item.text.toLowerCase()\n if (seen.has(text) || text === lower || !text.includes(lower)) return false\n seen.add(text)\n return true\n })\n .sort(\n (a, b) =>\n Number(!a.text.toLowerCase().startsWith(lower)) -\n Number(!b.text.toLowerCase().startsWith(lower)) || a.text.localeCompare(b.text)\n )\n .slice(0, 8)\n return items.length ? { from: caret - prefix.length, items } : null\n}\n\ntype Props = {\n value: string\n onChange: (value: string) => void\n label?: string\n placeholder?: string\n minRows?: number\n maxRows?: number\n /** Erro do banco (validação). */\n error?: string\n warning?: string\n /** Mostra o ⤢ que abre o editor grande (desligado dentro do próprio editor grande). */\n expandable?: boolean\n}\n\nexport function SqlEditor({\n value,\n onChange,\n label,\n placeholder = 'SQL',\n minRows,\n maxRows = 6,\n error,\n warning,\n expandable = true\n}: Props) {\n const completions = useContext(SqlCompletionsContext)\n const anchor = useRef<HTMLDivElement>(null)\n const input = useRef<HTMLTextAreaElement>(null)\n const highlight = useRef<HTMLPreElement>(null)\n const [expanded, setExpanded] = useState(false)\n const [state, setState] = useState<{ from: number; items: Suggestion[]; index: number } | null>(\n null\n )\n\n const accept = (item: Suggestion) => {\n const element = input.current\n if (!element || !state) return\n const caret = element.selectionStart\n const next = value.slice(0, state.from) + item.text + value.slice(caret)\n onChange(next)\n setState(null)\n const position = state.from + item.text.length\n requestAnimationFrame(() => {\n element.focus()\n element.setSelectionRange(position, position)\n })\n }\n\n return (\n <>\n <TextField\n ref={anchor}\n inputRef={input}\n size=\"small\"\n fullWidth\n multiline\n label={label}\n minRows={minRows}\n maxRows={maxRows}\n value={value}\n placeholder={placeholder}\n error={!value.trim() || !!error}\n helperText={error ?? warning}\n onChange={(event) => {\n onChange(event.target.value)\n const found = suggest(event.target.value, event.target.selectionStart ?? 0, completions)\n setState(found && { ...found, index: 0 })\n }}\n onKeyDown={(event) => {\n if (!state) return\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n const step = event.key === 'ArrowDown' ? 1 : -1\n setState({\n ...state,\n index: (state.index + step + state.items.length) % state.items.length\n })\n } else if (event.key === 'Enter' || event.key === 'Tab') {\n event.preventDefault()\n accept(state.items[state.index])\n } else if (event.key === 'Escape') {\n event.stopPropagation()\n setState(null)\n }\n }}\n onBlur={() => setState(null)}\n slotProps={{\n htmlInput: {\n spellCheck: false,\n onScroll: (event: React.UIEvent<HTMLTextAreaElement>) => {\n if (highlight.current) highlight.current.scrollTop = event.currentTarget.scrollTop\n }\n },\n input: {\n endAdornment: (\n <>\n <Box\n component=\"pre\"\n ref={highlight}\n aria-hidden\n sx={{\n ...textSx,\n // Exatamente sobre a caixa do textarea: recorta a rolagem no mesmo lugar\n m: 0,\n p: 0,\n position: 'absolute',\n top: PAD.top,\n right: PAD.right,\n bottom: PAD.bottom,\n left: PAD.left,\n overflow: 'hidden',\n pointerEvents: 'none',\n color: 'text.primary'\n }}\n >\n <HighlightedSql code={value} />\n {/* Linha final vazia: o textarea mostra, o <pre> sem isso esconderia */}\n {'\\n'}\n </Box>\n {expandable && (\n <Box\n component=\"button\"\n type=\"button\"\n title=\"Expandir o SQL\"\n aria-label=\"Expandir o SQL\"\n onClick={() => setExpanded(true)}\n sx={{\n position: 'absolute',\n top: 4,\n right: 4,\n zIndex: 2,\n border: 0,\n borderRadius: 0.5,\n bgcolor: 'transparent',\n color: 'text.secondary',\n cursor: 'pointer',\n fontSize: 14,\n lineHeight: 1,\n p: 0.25,\n '&:hover': { color: 'primary.main', bgcolor: 'rgba(255,255,255,.08)' }\n }}\n >\n ⤢\n </Box>\n )}\n </>\n )\n }\n }}\n sx={{\n '& .MuiInputBase-root': { ...padSx, position: 'relative', alignItems: 'flex-start' },\n '& textarea': {\n ...textSx,\n position: 'relative',\n zIndex: 1,\n color: 'transparent',\n caretColor: (theme) => theme.palette.text.primary,\n '&::placeholder': { color: 'text.disabled', opacity: 1 },\n '&::selection': { bgcolor: 'rgba(245,130,32,.35)' }\n },\n '& .MuiFormHelperText-root': {\n fontFamily: MONO,\n color: error ? 'error.main' : 'warning.main'\n }\n }}\n />\n {expandable && (\n <Dialog open={expanded} onClose={() => setExpanded(false)} maxWidth=\"lg\" fullWidth>\n <DialogTitle sx={{ fontSize: 14 }}>{label ?? 'SQL'}</DialogTitle>\n <DialogContent>\n <Box sx={{ pt: 1 }}>\n <SqlEditor\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n minRows={20}\n maxRows={36}\n error={error}\n warning={warning}\n expandable={false}\n />\n </Box>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setExpanded(false)}>Fechar</Button>\n </DialogActions>\n </Dialog>\n )}\n <Popper\n open={!!state}\n anchorEl={anchor.current}\n placement=\"bottom-start\"\n sx={{ zIndex: 1400 }}\n >\n <Paper elevation={8}>\n <MenuList dense>\n {state?.items.map((item, index) => (\n <MenuItem\n key={item.text}\n selected={index === state.index}\n // mousedown: antes do blur do campo fechar a lista\n onMouseDown={(event) => {\n event.preventDefault()\n accept(item)\n }}\n sx={{ gap: 2, fontFamily: MONO, fontSize: 12 }}\n >\n {item.text}\n <Box component=\"span\" sx={{ ml: 'auto', color: 'text.secondary', fontSize: 11 }}>\n {item.detail}\n </Box>\n </MenuItem>\n ))}\n </MenuList>\n </Paper>\n </Popper>\n </>\n )\n}\n\n/** Tudo que muda a posição dos caracteres: igual no textarea e no <pre> colorido. */\nconst textSx = {\n fontFamily: MONO,\n fontSize: 12,\n lineHeight: LINE_HEIGHT,\n letterSpacing: 0,\n whiteSpace: 'pre-wrap',\n overflowWrap: 'break-word',\n wordBreak: 'normal',\n tabSize: 2,\n // Mesma largura útil com ou sem barra de rolagem\n scrollbarGutter: 'stable'\n} as const\n\nconst padSx = {\n padding: `${PAD.top}px ${PAD.right}px ${PAD.bottom}px ${PAD.left}px`\n}\n","import { Box, MenuItem, TextField, Typography } from '@mui/material'\nimport { AGGREGATION_LABEL, AGGREGATIONS, isAggregate, VALUE_FORMATS } from '../model'\nimport type { MeasureRow } from './modelCode'\nimport { SqlEditor } from './SqlEditor'\nimport { MONO } from './ui'\n\n/** Campos do editor do modelo, usados pela tabela e pelo painel de propriedades do diagrama. */\n\nexport const inputSx = { '& .MuiInputBase-input': { fontFamily: MONO, fontSize: 12 } }\n\nexport const MEASURE_TYPES: { value: MeasureRow['type']; label: string }[] = [\n ...AGGREGATIONS.map((value) => ({ value, label: `${value} · ${AGGREGATION_LABEL[value]}` })),\n { value: 'ratio', label: 'ratio · Razão' },\n { value: 'formula', label: 'formula · Fórmula' }\n]\n\nexport function NameField({\n value,\n onChange,\n onBlur,\n label\n}: {\n value: string\n onChange: (value: string) => void\n onBlur?: () => void\n label?: string\n}) {\n return (\n <TextField\n size=\"small\"\n fullWidth\n label={label}\n value={value}\n placeholder=\"nome\"\n error={!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n onKeyDown={(e) => {\n if (e.key === 'Enter') (e.target as HTMLInputElement).blur()\n }}\n sx={inputSx}\n />\n )\n}\n\nexport function MeasureSelect({\n value,\n options,\n onChange\n}: {\n value: string\n options: string[]\n onChange: (value: string) => void\n}) {\n return (\n <TextField\n select\n size=\"small\"\n value={options.includes(value) ? value : ''}\n error={!options.includes(value)}\n onChange={(e) => onChange(e.target.value)}\n sx={{ ...inputSx, minWidth: 140, flex: 1 }}\n >\n {options.map((name) => (\n <MenuItem key={name} value={name}>\n {name}\n </MenuItem>\n ))}\n </TextField>\n )\n}\n\nexport function MeasureTypeSelect({\n value,\n onChange\n}: {\n value: MeasureRow['type']\n onChange: (value: MeasureRow['type']) => void\n}) {\n return (\n <TextField\n select\n size=\"small\"\n fullWidth\n value={value}\n onChange={(e) => onChange(e.target.value as MeasureRow['type'])}\n sx={inputSx}\n >\n {MEASURE_TYPES.map((type) => (\n <MenuItem key={type.value} value={type.value}>\n {type.label}\n </MenuItem>\n ))}\n </TextField>\n )\n}\n\n/** Definição da medida conforme o tipo: SQL da soma, as duas medidas da razão ou a fórmula. */\nexport function MeasureDefinition({\n row,\n measureNames,\n error,\n onPatch\n}: {\n row: MeasureRow\n measureNames: string[]\n error?: string\n onPatch: (changes: Partial<MeasureRow>) => void\n}) {\n const others = measureNames.filter((name) => name !== row.name)\n if (isAggregate(row))\n return (\n <SqlEditor\n value={row.sql}\n placeholder={\n row.type === 'count' || row.type === 'countDistinct'\n ? 'tabela.coluna (conta os valores não nulos)'\n : 'tabela.coluna'\n }\n error={error}\n onChange={(sql) => onPatch({ sql })}\n />\n )\n if (row.type === 'formula')\n return (\n <SqlEditor\n value={row.expression}\n placeholder=\"COALESCE({medidaA}, 0) + COALESCE({medidaB}, 0)\"\n error={error}\n warning={others.length ? `medidas: ${others.map((name) => `{${name}}`).join(' ')}` : ''}\n onChange={(expression) => onPatch({ expression })}\n />\n )\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <MeasureSelect\n value={row.numerator}\n options={others}\n onChange={(numerator) => onPatch({ numerator })}\n />\n <Typography sx={{ fontFamily: MONO }}>/</Typography>\n <MeasureSelect\n value={row.denominator}\n options={others}\n onChange={(denominator) => onPatch({ denominator })}\n />\n </Box>\n )\n}\n\nexport function FormatFields({\n row,\n onPatch\n}: {\n row: MeasureRow\n onPatch: (changes: Partial<MeasureRow>) => void\n}) {\n return (\n <Box sx={{ display: 'flex', gap: 0.5 }}>\n <TextField\n select\n size=\"small\"\n value={row.format}\n onChange={(e) => onPatch({ format: e.target.value as MeasureRow['format'] })}\n sx={{ ...inputSx, flex: 1 }}\n slotProps={{ select: { displayEmpty: true } }}\n >\n <MenuItem value=\"\">\n <em>padrão</em>\n </MenuItem>\n {VALUE_FORMATS.map((format) => (\n <MenuItem key={format} value={format}>\n {format}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n size=\"small\"\n placeholder=\"casas\"\n value={row.decimals}\n error={!!row.decimals.trim() && !/^\\d+$/.test(row.decimals.trim())}\n onChange={(e) => onPatch({ decimals: e.target.value })}\n sx={{ ...inputSx, width: 64 }}\n />\n </Box>\n )\n}\n\nexport function DictionaryFields({\n row,\n onPatch\n}: {\n row: { label: string; description: string }\n onPatch: (changes: { label?: string; description?: string }) => void\n}) {\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>\n <TextField\n size=\"small\"\n placeholder=\"rótulo\"\n value={row.label}\n onChange={(e) => onPatch({ label: e.target.value })}\n sx={inputSx}\n />\n <TextField\n size=\"small\"\n placeholder=\"descrição\"\n multiline\n maxRows={4}\n value={row.description}\n onChange={(e) => onPatch({ description: e.target.value })}\n sx={inputSx}\n />\n </Box>\n )\n}\n","import {\n Box,\n Checkbox,\n MenuItem,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Typography\n} from '@mui/material'\nimport { useState } from 'react'\nimport type { ModelColumns } from '../types'\nimport { type DimensionRow, type EditorModel, emptyDimension, freeName } from './modelCode'\nimport { inputSx } from './modelFields'\nimport { SqlEditor } from './SqlEditor'\nimport { MONO } from './ui'\n\n/**\n * Modo simples das dimensões: marcar as colunas da tabela que viram dimensão. Marcar cria\n * `tabela.coluna` (tipo pelo valor lido do banco); desmarcar remove a dimensão que é exatamente\n * essa coluna. Dimensão com SQL próprio (`YEAR(tabela.data)`) não aparece marcada aqui — essa se\n * edita no painel dela.\n */\n\n/** `tabela.coluna` puro (o que o modo simples sabe editar). */\nexport const SIMPLE_DIMENSION = /^\\s*([A-Za-z_][A-Za-z0-9_]*)\\.([A-Za-z_][A-Za-z0-9_]*)\\s*$/\n\ntype Props = {\n editor: EditorModel\n setEditor: (update: (current: EditorModel) => EditorModel) => void\n columns: ModelColumns | null\n table: string\n /** Abre a dimensão no painel. */\n onOpen: (uid: string) => void\n}\n\nexport function DimensionPicker({ editor, setEditor, columns, table, onOpen }: Props) {\n const [search, setSearch] = useState('')\n const loaded = columns?.tables[table]\n if (!loaded)\n return (\n <Typography sx={{ fontSize: 12, color: 'text.disabled' }}>\n Colunas ainda não lidas: use \"Recarregar colunas\".\n </Typography>\n )\n\n const numeric = new Set(columns?.numeric ?? [])\n const dimensionsOf = (column: string) =>\n editor.dimensions.filter((row) => {\n const match = SIMPLE_DIMENSION.exec(row.sql)\n return match?.[1] === table && match[2] === column\n })\n\n const toggle = (column: string, checked: boolean) =>\n setEditor((current) => {\n if (!checked) {\n const removed = new Set(dimensionsOf(column).map((row) => row.uid))\n return { ...current, dimensions: current.dimensions.filter((row) => !removed.has(row.uid)) }\n }\n const taken = [...current.dimensions, ...current.measures].map((row) => row.name)\n // Nome da coluna; se já existir, com a tabela na frente\n const name = taken.includes(column) ? freeName(`${table}_${column}`, taken) : column\n const dimension = emptyDimension({\n name,\n type: numeric.has(`${table}.${column}`) ? 'number' : 'string',\n sql: `${table}.${column}`\n })\n return { ...current, dimensions: [...current.dimensions, dimension] }\n })\n\n const visible = loaded.filter((column) => column.toLowerCase().includes(search.toLowerCase()))\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column' }}>\n {loaded.length > 10 && (\n <TextField\n size=\"small\"\n placeholder=\"filtrar colunas\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n sx={{ ...inputSx, mb: 0.5 }}\n />\n )}\n {visible.map((column) => {\n const existing = dimensionsOf(column)\n return (\n <Box\n key={column}\n component=\"label\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 0.5,\n fontSize: 12,\n fontFamily: MONO,\n cursor: 'pointer',\n borderRadius: 0.5,\n '&:hover': { bgcolor: 'rgba(255,255,255,.05)' }\n }}\n >\n <Checkbox\n size=\"small\"\n sx={{ p: 0.25 }}\n checked={!!existing.length}\n onChange={(e) => toggle(column, e.target.checked)}\n />\n <Box component=\"span\" sx={{ flex: 1 }}>\n {column}\n {numeric.has(`${table}.${column}`) && (\n <Box component=\"span\" sx={{ color: 'text.disabled', ml: 0.5 }}>\n Σ\n </Box>\n )}\n </Box>\n {existing.map((row) => (\n <Box\n key={row.uid}\n component=\"button\"\n type=\"button\"\n title=\"Abrir a dimensão\"\n onClick={(event) => {\n event.preventDefault()\n onOpen(row.uid)\n }}\n sx={{\n border: 0,\n bgcolor: 'transparent',\n color: '#a5d8ff',\n cursor: 'pointer',\n fontFamily: MONO,\n fontSize: 11,\n p: 0\n }}\n >\n ◇ {row.name || 'sem nome'}\n </Box>\n ))}\n </Box>\n )\n })}\n </Box>\n )\n}\n\nconst PARTIAL = /^\\s*([A-Za-z_][A-Za-z0-9_]*)\\.([A-Za-z0-9_]*)\\s*$/\n\n/**\n * Origem de uma dimensão: no modo simples, tabela + coluna (vira `tabela.coluna`); no modo SQL, a\n * expressão livre (`YEAR(tabela.data)`, `CONCAT(...)`). Abre no simples quando o SQL é só a coluna.\n */\nexport function DimensionSource({\n row,\n editor,\n columns,\n error,\n warning,\n onPatch\n}: {\n row: DimensionRow\n editor: EditorModel\n columns: ModelColumns | null\n error?: string\n warning?: string\n onPatch: (changes: Partial<DimensionRow>) => void\n}) {\n const [mode, setMode] = useState<'simple' | 'sql'>(() =>\n !row.sql.trim() || PARTIAL.test(row.sql) ? 'simple' : 'sql'\n )\n const parsed = PARTIAL.exec(row.sql)\n const table = parsed?.[1] ?? ''\n const column = parsed?.[2] ?? ''\n const tableColumns = columns?.tables[table] ?? []\n const numeric = new Set(columns?.numeric ?? [])\n\n const choose = (nextTable: string, nextColumn: string) => {\n const changes: Partial<DimensionRow> = { sql: `${nextTable}.${nextColumn}` }\n if (nextColumn) {\n changes.type = numeric.has(`${nextTable}.${nextColumn}`) ? 'number' : 'string'\n // Nome ainda automático: acompanha a coluna\n if (!row.name || /^novaDimensao\\d*$/.test(row.name)) {\n const taken = [...editor.dimensions, ...editor.measures]\n .filter((item) => item.uid !== row.uid)\n .map((item) => item.name)\n changes.name = freeName(nextColumn, taken)\n }\n }\n onPatch(changes)\n }\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={mode}\n onChange={(_, next: 'simple' | 'sql' | null) => next && setMode(next)}\n >\n <ToggleButton value=\"simple\" sx={{ textTransform: 'none', py: 0.25, flex: 1 }}>\n Tabela e coluna\n </ToggleButton>\n <ToggleButton value=\"sql\" sx={{ textTransform: 'none', py: 0.25, flex: 1 }}>\n SQL\n </ToggleButton>\n </ToggleButtonGroup>\n {mode === 'simple' ? (\n <>\n {!parsed && row.sql.trim() && (\n <Typography sx={{ fontSize: 11, color: 'warning.main' }}>\n O SQL atual ({row.sql.trim()}) não é uma coluna só; escolher aqui substitui ele.\n </Typography>\n )}\n <Box sx={{ display: 'flex', gap: 1 }}>\n <TextField\n select\n size=\"small\"\n label=\"tabela\"\n value={editor.tables.some((item) => item.name === table) ? table : ''}\n onChange={(e) =>\n choose(\n e.target.value,\n columns?.tables[e.target.value]?.includes(column) ? column : ''\n )\n }\n sx={{ ...inputSx, flex: 1 }}\n >\n {editor.tables.map((item) => (\n <MenuItem key={item.uid} value={item.name}>\n {item.name}\n </MenuItem>\n ))}\n </TextField>\n {tableColumns.length ? (\n <TextField\n select\n size=\"small\"\n label=\"coluna\"\n value={tableColumns.includes(column) ? column : ''}\n error={!!error}\n onChange={(e) => choose(table, e.target.value)}\n sx={{ ...inputSx, flex: 1 }}\n >\n {tableColumns.map((name) => (\n <MenuItem key={name} value={name}>\n {name}\n </MenuItem>\n ))}\n </TextField>\n ) : (\n // Colunas ainda não lidas: digita\n <TextField\n size=\"small\"\n label=\"coluna\"\n value={column}\n disabled={!table}\n onChange={(e) => choose(table, e.target.value)}\n sx={{ ...inputSx, flex: 1 }}\n />\n )}\n </Box>\n {(error || warning) && (\n <Typography\n sx={{ fontSize: 11, fontFamily: MONO, color: error ? 'error.main' : 'warning.main' }}\n >\n {error ?? warning}\n </Typography>\n )}\n </>\n ) : (\n <SqlEditor\n label=\"sql\"\n value={row.sql}\n error={error}\n warning={warning}\n onChange={(sql) => onPatch({ sql })}\n />\n )}\n </Box>\n )\n}\n","import {\n Alert,\n Box,\n Button,\n Checkbox,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n FormControlLabel,\n IconButton,\n MenuItem,\n TextField,\n Tooltip,\n Typography\n} from '@mui/material'\nimport {\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n type WheelEvent\n} from 'react'\nimport { isAggregate } from '../model'\nimport { measureHome, modelEdges, referencedTables } from '../star'\nimport type { ModelColumns } from '../types'\nimport { DimensionPicker, DimensionSource } from './DimensionPicker'\nimport {\n type DimensionRow,\n type EditorModel,\n emptyDimension,\n emptyMeasure,\n freeName,\n fromEditor,\n type MeasureRow,\n newUid,\n type RelationshipRow,\n renameTable,\n type TableRow\n} from './modelCode'\nimport {\n DictionaryFields,\n FormatFields,\n inputSx,\n MeasureDefinition,\n MeasureTypeSelect,\n NameField\n} from './modelFields'\nimport { SqlEditor } from './SqlEditor'\nimport { MONO } from './ui'\n\n/**\n * Diagrama do modelo, no estilo da \"Exibição de modelo\" do Power BI: um card por tabela (colunas,\n * dimensões e medidas que saem dela) e uma linha por relacionamento, com `*` no lado N e `1` no\n * lado 1. Edita o mesmo rascunho da tabela do editor.\n *\n * - arrastar o cabeçalho move o card; arrastar o fundo move a tela; Ctrl+roda dá zoom;\n * - arrastar uma coluna até a coluna de outra tabela cria o relacionamento (quem foi arrastado é o\n * lado N; de dimensão para fato, inverte sozinho);\n * - clicar num card, linha, dimensão ou medida abre as propriedades à direita; Delete remove;\n * - os botões `+◇`/`+Σ` de uma coluna criam a dimensão/medida dela.\n *\n * As posições dos cards fazem parte do modelo (`diagram`) e vão para o arquivo ao salvar.\n */\n\ntype Props = {\n editor: EditorModel\n setEditor: (update: (current: EditorModel) => EditorModel) => void\n columns: ModelColumns | null\n /** Pedaços que o banco recusou (`table:<nome>`, `relationship:<i>`, `dimension:<nome>`...). */\n errors: Record<string, string>\n warnings: Record<string, string>\n loadingColumns: boolean\n onLoadColumns: () => void\n onTry: (selection: { dimensions: string[]; measures: string[] }) => void\n /** Consultas ativas que usam cada nome. */\n usage: Map<string, number>\n}\n\n/**\n * Papel da tabela, tirado dos relacionamentos (não é configurado): `one` só aparece no lado 1\n * (cadastro que filtra), `many` tem relacionamento saindo (lançamentos), `alone` não tem nenhum.\n */\ntype NodeRole = 'one' | 'many' | 'alone'\n\ntype ColumnItem = {\n kind: 'column'\n name: string\n numeric: boolean\n isKey: boolean\n linked: boolean\n /** Citada no modelo, mas a tabela (já lida do banco) não tem. */\n missing: boolean\n}\ntype FieldItem = { kind: 'dimension' | 'measure'; uid: string; name: string; icon: string }\ntype Item = ColumnItem | FieldItem\n\ntype DiagramNode = {\n /** Chave das posições: `uid` da tabela. */\n id: string\n uid: string\n name: string\n role: NodeRole\n /** Coluna única da tabela (`key`). */\n key: string\n items: Item[]\n error?: string\n}\n\ntype Selection =\n | { kind: 'table'; uid: string }\n | { kind: 'relationship'; uid: string }\n | { kind: 'dimension'; uid: string }\n | { kind: 'measure'; uid: string }\n | null\n\ntype Point = { x: number; y: number }\ntype View = { x: number; y: number; zoom: number }\n\nconst CARD_WIDTH = 230\nconst HEADER = 34\nconst ROW = 22\nconst MAX_BODY = 264\nconst PADDING = 4\n\nconst ROLE_STYLE: Record<NodeRole, { color: string; label: string; title: string }> = {\n one: { color: '#4dabf7', label: 'lado 1', title: 'Só aparece no lado 1: filtra outras tabelas' },\n many: { color: '#F58220', label: 'lado N', title: 'Tem relacionamento saindo (lado N)' },\n alone: { color: '#868e96', label: 'solta', title: 'Sem relacionamentos' }\n}\n\nconst PANEL_KEY = 'bm-dashboard-devtools:diagram-panel'\nconst PANEL_MIN = 260\nconst PANEL_MAX = 720\n\ntype PanelState = { open: boolean; width: number }\n\nfunction loadPanel(): PanelState {\n try {\n const saved = JSON.parse(localStorage.getItem(PANEL_KEY) ?? 'null')\n if (typeof saved?.width === 'number')\n return {\n open: saved.open !== false,\n width: Math.min(PANEL_MAX, Math.max(PANEL_MIN, saved.width))\n }\n } catch {}\n return { open: true, width: 340 }\n}\n\n/** Acompanha o mouse até soltar o botão. */\nfunction track(\n event: ReactMouseEvent,\n onMove: (dx: number, dy: number, event: MouseEvent) => void,\n onUp?: (event: MouseEvent, moved: boolean) => void\n) {\n event.preventDefault()\n event.stopPropagation()\n const start = { x: event.clientX, y: event.clientY }\n let moved = false\n const move = (moveEvent: MouseEvent) => {\n const dx = moveEvent.clientX - start.x\n const dy = moveEvent.clientY - start.y\n if (Math.abs(dx) + Math.abs(dy) > 3) moved = true\n if (moved) onMove(dx, dy, moveEvent)\n }\n const up = (upEvent: MouseEvent) => {\n window.removeEventListener('mousemove', move)\n window.removeEventListener('mouseup', up)\n onUp?.(upEvent, moved)\n }\n window.addEventListener('mousemove', move)\n window.addEventListener('mouseup', up)\n}\n\n/** Colunas citadas como `tabela.coluna` no SQL das dimensões/medidas. */\nfunction citedColumns(sql: string, table: string) {\n const code = sql.replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"''\")\n const pattern = new RegExp(`(?<![\\\\w.\\`])${table}\\\\.([A-Za-z_][A-Za-z0-9_]*)`, 'g')\n return [...code.matchAll(pattern)].map((match) => match[1])\n}\n\n/** Ícone de cada agregação no card (a soma fica com o Σ). */\nconst MEASURE_ICON: Partial<Record<MeasureRow['type'], string>> = {\n count: '#',\n countDistinct: '#',\n avg: 'x̄',\n min: '↓',\n max: '↑'\n}\n\nconst fieldItems = (\n dimensions: DimensionRow[],\n measures: MeasureRow[],\n belongs: (sql: string) => boolean\n): FieldItem[] => [\n ...dimensions\n .filter((row) => belongs(row.sql))\n .map((row) => ({ kind: 'dimension' as const, uid: row.uid, name: row.name, icon: '◇' })),\n ...measures\n .filter((row) => isAggregate(row) && belongs(row.sql))\n .map((row) => ({\n kind: 'measure' as const,\n uid: row.uid,\n name: row.name,\n icon: MEASURE_ICON[row.type] ?? 'Σ'\n }))\n]\n\nfunction buildNodes(\n editor: EditorModel,\n columns: ModelColumns | null,\n errors: Record<string, string>\n): DiagramNode[] {\n const numeric = new Set(columns?.numeric ?? [])\n const columnItems = (\n node: string,\n loaded: string[] | undefined,\n extra: string[],\n key: string,\n linked: Set<string>\n ): ColumnItem[] => {\n const names = [...(loaded ?? []), ...extra.filter((name) => !loaded?.includes(name))]\n return [...new Set(names)].map((name) => ({\n kind: 'column',\n name,\n numeric: numeric.has(`${node}.${name}`),\n isKey: name === key,\n linked: linked.has(name),\n missing: !!loaded?.length && !loaded.includes(name)\n }))\n }\n\n const tableNames = editor.tables.map((table) => table.name)\n const edges = modelEdges(fromEditor(editor))\n // Tabela onde a medida/dimensão agrega (a que alcança as outras que ela cita)\n const homeOf = (sql: string) => measureHome(referencedTables(sql, tableNames), edges)\n return editor.tables.map((table) => {\n const linked = new Set(\n editor.relationships.flatMap((row) => [\n ...(row.fromTable === table.uid ? [row.fromColumn] : []),\n ...(row.toTable === table.uid ? [row.toColumn] : [])\n ])\n )\n const cited = [...editor.dimensions, ...editor.measures].flatMap((row) =>\n citedColumns(row.sql, table.name)\n )\n return {\n id: table.uid,\n uid: table.uid,\n name: table.name,\n role: editor.relationships.some((row) => row.fromTable === table.uid)\n ? ('many' as const)\n : editor.relationships.some((row) => row.toTable === table.uid)\n ? ('one' as const)\n : ('alone' as const),\n key: table.key,\n error: errors[`table:${table.name}`],\n items: [\n ...columnItems(\n table.name,\n columns?.tables[table.name],\n [...(table.key ? [table.key] : []), ...linked, ...cited],\n table.key,\n linked\n ),\n ...fieldItems(editor.dimensions, editor.measures, (sql) => homeOf(sql) === table.name)\n ]\n }\n })\n}\n\nconst cardHeight = (node: DiagramNode, collapsed: boolean) =>\n collapsed ? HEADER : HEADER + Math.min(node.items.length * ROW, MAX_BODY) + PADDING * 2\n\n/** Quem só filtra (lado 1) em cima, o resto embaixo (como costuma ficar no Power BI). */\nfunction autoLayout(nodes: DiagramNode[], heights: Map<string, number>) {\n const top = nodes.filter((node) => node.role === 'one')\n const bottom = nodes.filter((node) => node.role !== 'one')\n const positions: Record<string, Point> = {}\n const gap = 60\n top.forEach((node, index) => {\n positions[node.id] = { x: 40 + index * (CARD_WIDTH + gap), y: 40 }\n })\n const topHeight = Math.max(0, ...top.map((node) => heights.get(node.id) ?? HEADER))\n bottom.forEach((node, index) => {\n positions[node.id] = { x: 40 + index * (CARD_WIDTH + gap), y: 40 + topHeight + 140 }\n })\n return positions\n}\n\nexport function ModelDiagram({\n editor,\n setEditor,\n columns,\n errors,\n warnings,\n loadingColumns,\n onLoadColumns,\n onTry,\n usage\n}: Props) {\n const nodes = useMemo(() => buildNodes(editor, columns, errors), [editor, columns, errors])\n // Card sendo arrastado: a posição só vai para o modelo ao soltar\n const [moving, setMoving] = useState<{ id: string; point: Point } | null>(null)\n const [collapsed, setCollapsed] = useState<Record<string, boolean>>({})\n const [scrolls, setScrolls] = useState<Record<string, number>>({})\n const [view, setView] = useState<View>({ x: 0, y: 0, zoom: 1 })\n const [selection, setSelection] = useState<Selection>(null)\n const [panel, setPanel] = useState<PanelState>(loadPanel)\n const [picking, setPicking] = useState<string | null>(null)\n\n useEffect(() => {\n try {\n localStorage.setItem(PANEL_KEY, JSON.stringify(panel))\n } catch {}\n }, [panel])\n\n // Selecionou algo com o painel recolhido: abre para mostrar as propriedades\n useEffect(() => {\n if (selection) setPanel((current) => (current.open ? current : { ...current, open: true }))\n }, [selection])\n\n const startPanelResize = (event: ReactMouseEvent) => {\n const start = panel.width\n track(event, (dx) =>\n setPanel((current) => ({\n ...current,\n width: Math.min(PANEL_MAX, Math.max(PANEL_MIN, start - dx))\n }))\n )\n }\n const [linking, setLinking] = useState<{ node: DiagramNode; column: string; to: Point } | null>(\n null\n )\n const [hoveredEdge, setHoveredEdge] = useState<string | null>(null)\n const canvas = useRef<HTMLDivElement>(null)\n\n // Colunas do banco: carrega uma vez ao abrir o diagrama\n const requested = useRef(false)\n useEffect(() => {\n if (requested.current || columns) return\n requested.current = true\n onLoadColumns()\n }, [columns, onLoadColumns])\n\n const heights = useMemo(\n () => new Map(nodes.map((node) => [node.id, cardHeight(node, !!collapsed[node.id])])),\n [nodes, collapsed]\n )\n // Card sem posição salva entra no layout automático (sem mexer nos que já foram arrumados)\n const fallback = useMemo(() => autoLayout(nodes, heights), [nodes, heights])\n const placed = (node: DiagramNode): Point =>\n (moving?.id === node.id ? moving.point : editor.positions[node.id]) ?? fallback[node.id]\n const setPositions = (update: (current: Record<string, Point>) => Record<string, Point>) =>\n setEditor((current) => ({ ...current, positions: update(current.positions) }))\n\n const nodeOf = (uid: string) => nodes.find((node) => node.uid === uid)\n\n /** Ponto da linha na coluna do card (lado esquerdo ou direito). */\n const anchor = (node: DiagramNode, column: string, side: 'left' | 'right'): Point => {\n const { x, y } = placed(node)\n const height = heights.get(node.id) ?? HEADER\n const index = node.items.findIndex((item) => item.kind === 'column' && item.name === column)\n let rowY = y + HEADER / 2\n if (!collapsed[node.id] && index >= 0) {\n const raw = y + HEADER + PADDING + index * ROW + ROW / 2 - (scrolls[node.id] ?? 0)\n rowY = Math.min(Math.max(raw, y + HEADER + 2), y + height - 2)\n }\n return { x: side === 'left' ? x : x + CARD_WIDTH, y: rowY }\n }\n\n const toWorld = (clientX: number, clientY: number): Point => {\n const rect = canvas.current?.getBoundingClientRect()\n return {\n x: (clientX - (rect?.left ?? 0) - view.x) / view.zoom,\n y: (clientY - (rect?.top ?? 0) - view.y) / view.zoom\n }\n }\n\n // --- edição ---\n\n const patchTable = (uid: string, changes: Partial<TableRow>) =>\n setEditor((current) => ({\n ...current,\n tables: current.tables.map((row) => (row.uid === uid ? { ...row, ...changes } : row))\n }))\n const patchRelationship = (uid: string, changes: Partial<RelationshipRow>) =>\n setEditor((current) => ({\n ...current,\n relationships: current.relationships.map((row) =>\n row.uid === uid ? { ...row, ...changes } : row\n )\n }))\n const patchDimension = (uid: string, changes: Partial<DimensionRow>) =>\n setEditor((current) => ({\n ...current,\n dimensions: current.dimensions.map((row) => (row.uid === uid ? { ...row, ...changes } : row))\n }))\n const patchMeasure = (uid: string, changes: Partial<MeasureRow>) =>\n setEditor((current) => ({\n ...current,\n measures: current.measures.map((row) => (row.uid === uid ? { ...row, ...changes } : row))\n }))\n\n /** Perto do centro da área visível (onde entra um card novo). */\n const visibleCenter = () => {\n const rect = canvas.current?.getBoundingClientRect()\n return toWorld(\n (rect?.left ?? 0) + (rect?.width ?? 600) / 2 - CARD_WIDTH / 2,\n (rect?.top ?? 0) + (rect?.height ?? 400) / 3\n )\n }\n\n const addTable = () => {\n const uid = newUid()\n const name = freeName(\n 'novaTabela',\n editor.tables.map((table) => table.name)\n )\n const center = visibleCenter()\n setEditor((current) => ({\n ...current,\n positions: { ...current.positions, [uid]: center },\n tables: [\n ...current.tables,\n {\n uid,\n name,\n key: '',\n sql: 'SELECT * FROM tabela',\n label: '',\n description: ''\n }\n ]\n }))\n setSelection({ kind: 'table', uid })\n }\n\n const removeTable = (uid: string) => {\n setEditor((current) => ({\n ...current,\n tables: current.tables.filter((row) => row.uid !== uid),\n relationships: current.relationships.filter(\n (row) => row.fromTable !== uid && row.toTable !== uid\n )\n }))\n setSelection(null)\n }\n\n // Corrige as referências `tabela.coluna` (a posição vai pelo uid)\n const commitRename = (uid: string, name: string) =>\n setEditor((current) => renameTable(current, uid, name))\n\n const connect = (from: DiagramNode, fromColumn: string, to: DiagramNode, toColumn: string) => {\n if (from.uid === to.uid) return\n // O lado 1 é quem entra pela própria chave: arrastou da chave para uma coluna comum, inverte\n const swap = fromColumn === from.key && toColumn !== to.key\n const [many, manyColumn, one, oneColumn] = swap\n ? [to, toColumn, from, fromColumn]\n : [from, fromColumn, to, toColumn]\n const uid = newUid()\n setEditor((current) => ({\n ...current,\n relationships: [\n ...current.relationships,\n {\n uid,\n fromTable: many.uid,\n fromColumn: manyColumn,\n toTable: one.uid,\n toColumn: oneColumn,\n inner: false\n }\n ]\n }))\n setSelection({ kind: 'relationship', uid })\n }\n\n /** Dimensão/medida nova a partir da tabela (ou de uma coluna dela, já preenchida). */\n const addField = (\n kind: 'dimension' | 'measure',\n table: string,\n column?: { name: string; numeric: boolean }\n ) => {\n const uid = newUid()\n const taken = [...editor.dimensions, ...editor.measures].map((row) => row.name)\n const sql = `${table}.${column?.name ?? ''}`\n if (kind === 'dimension')\n setEditor((current) => ({\n ...current,\n dimensions: [\n ...current.dimensions,\n emptyDimension({\n uid,\n name: freeName(column?.name ?? 'novaDimensao', taken),\n type: column?.numeric ? 'number' : 'string',\n sql\n })\n ]\n }))\n else\n setEditor((current) => ({\n ...current,\n measures: [\n ...current.measures,\n // Coluna de texto/data não soma: vira contagem\n emptyMeasure({\n uid,\n name: freeName(\n column ? `${column.numeric ? 'total' : 'qtd'}_${column.name}` : 'novaMedida',\n taken\n ),\n type: column && !column.numeric ? 'count' : 'sum',\n sql\n })\n ]\n }))\n setSelection({ kind, uid })\n }\n\n const removeSelection = () => {\n if (!selection) return\n if (selection.kind === 'table') removeTable(selection.uid)\n else {\n const list = (\n { relationship: 'relationships', dimension: 'dimensions', measure: 'measures' } as const\n )[selection.kind]\n setEditor((current) => ({\n ...current,\n [list]: (current[list] as { uid: string }[]).filter((row) => row.uid !== selection.uid)\n }))\n setSelection(null)\n }\n }\n\n // --- mouse ---\n\n const startPan = (event: ReactMouseEvent) => {\n if (event.button !== 0) return\n const start = view\n track(\n event,\n (dx, dy) => setView((current) => ({ ...current, x: start.x + dx, y: start.y + dy })),\n (_, moved) => {\n if (!moved) setSelection(null)\n }\n )\n }\n\n const startMove = (event: ReactMouseEvent, node: DiagramNode) => {\n if (event.button !== 0) return\n const start = placed(node)\n const { zoom } = view\n let point = start\n track(\n event,\n (dx, dy) => {\n point = { x: start.x + dx / zoom, y: start.y + dy / zoom }\n setMoving({ id: node.id, point })\n },\n (_, moved) => {\n setMoving(null)\n if (moved) setPositions((current) => ({ ...current, [node.id]: point }))\n else selectNode(node)\n }\n )\n }\n\n const startLink = (event: ReactMouseEvent, node: DiagramNode, column: string) => {\n if (event.button !== 0) return\n track(\n event,\n (_, __, moveEvent) =>\n setLinking({ node, column, to: toWorld(moveEvent.clientX, moveEvent.clientY) }),\n (upEvent, moved) => {\n setLinking(null)\n if (!moved) {\n selectNode(node)\n return\n }\n const target = document\n .elementFromPoint(upEvent.clientX, upEvent.clientY)\n ?.closest<HTMLElement>('[data-diagram-column]')\n const targetNode = nodes.find((item) => item.id === target?.dataset.diagramNode)\n const targetColumn = target?.dataset.diagramColumn\n if (targetNode && targetColumn) connect(node, column, targetNode, targetColumn)\n }\n )\n }\n\n const onWheel = (event: WheelEvent) => {\n if (!event.ctrlKey && !event.metaKey) {\n setView((current) => ({\n ...current,\n x: current.x - event.deltaX,\n y: current.y - event.deltaY\n }))\n return\n }\n const rect = canvas.current?.getBoundingClientRect()\n const px = event.clientX - (rect?.left ?? 0)\n const py = event.clientY - (rect?.top ?? 0)\n setView((current) => {\n const zoom = Math.min(2, Math.max(0.3, current.zoom * (event.deltaY > 0 ? 0.9 : 1.1)))\n const ratio = zoom / current.zoom\n return { zoom, x: px - (px - current.x) * ratio, y: py - (py - current.y) * ratio }\n })\n }\n\n // Ctrl+roda não pode dar zoom na página inteira\n useEffect(() => {\n const element = canvas.current\n if (!element) return\n const prevent = (event: globalThis.WheelEvent) => event.preventDefault()\n element.addEventListener('wheel', prevent, { passive: false })\n return () => element.removeEventListener('wheel', prevent)\n }, [])\n\n const fitToScreen = (layout?: Record<string, Point>) => {\n const rect = canvas.current?.getBoundingClientRect()\n if (!rect || !nodes.length) return\n const boxes = nodes.map((node) => ({\n ...(layout?.[node.id] ?? placed(node)),\n h: heights.get(node.id) ?? HEADER\n }))\n const minX = Math.min(...boxes.map((box) => box.x))\n const minY = Math.min(...boxes.map((box) => box.y))\n const maxX = Math.max(...boxes.map((box) => box.x + CARD_WIDTH))\n const maxY = Math.max(...boxes.map((box) => box.y + box.h))\n const zoom = Math.min(\n 1.2,\n Math.max(0.3, Math.min((rect.width - 60) / (maxX - minX), (rect.height - 60) / (maxY - minY)))\n )\n setView({ zoom, x: 30 - minX * zoom, y: 30 - minY * zoom })\n }\n\n const selectNode = (node: DiagramNode) => setSelection({ kind: 'table', uid: node.uid })\n\n const isSelected = (node: DiagramNode) =>\n selection?.kind === 'table' && selection.uid === node.uid\n\n // --- linhas ---\n\n type Line = {\n id: string\n from: Point\n to: Point\n selected: boolean\n inner?: boolean\n error?: string\n onClick?: () => void\n }\n const lines: Line[] = []\n const pushLine = (\n id: string,\n many: DiagramNode,\n manyColumn: string,\n one: DiagramNode,\n oneColumn: string,\n extra: Partial<Line>\n ) => {\n const manyX = placed(many).x + CARD_WIDTH / 2\n const oneX = placed(one).x + CARD_WIDTH / 2\n const rightward = manyX <= oneX\n lines.push({\n id,\n from: anchor(many, manyColumn, rightward ? 'right' : 'left'),\n to: anchor(one, oneColumn, rightward ? 'left' : 'right'),\n selected: false,\n ...extra\n })\n }\n editor.relationships.forEach((row, index) => {\n const many = nodeOf(row.fromTable)\n const one = nodeOf(row.toTable)\n if (!many || !one) return\n pushLine(row.uid, many, row.fromColumn, one, row.toColumn, {\n inner: row.inner,\n selected: selection?.kind === 'relationship' && selection.uid === row.uid,\n error: errors[`relationship:${index}`],\n onClick: () => setSelection({ kind: 'relationship', uid: row.uid })\n })\n })\n\n // Dimensões/medidas que não caem em nenhum card (SQL sem `tabela.coluna` conhecido)\n const shown = new Set(\n nodes.flatMap((node) => node.items.map((item) => 'uid' in item && item.uid))\n )\n const unplaced = fieldItems(editor.dimensions, editor.measures, () => true).filter(\n (item) => !shown.has(item.uid)\n )\n\n const linkPreview =\n linking &&\n (() => {\n const start = anchor(\n linking.node,\n linking.column,\n linking.to.x < placed(linking.node).x ? 'left' : 'right'\n )\n return curve(start, linking.to)\n })()\n\n return (\n <Box sx={{ display: 'flex', height: '100%', minHeight: 0 }}>\n <Box\n ref={canvas}\n tabIndex={-1}\n onMouseDown={startPan}\n // O arrastar cancela o mouse down; o foco é o que faz o Delete chegar aqui\n onMouseDownCapture={() => canvas.current?.focus({ preventScroll: true })}\n onKeyDown={(event) => {\n if (\n (event.key === 'Delete' || event.key === 'Backspace') &&\n event.target === canvas.current\n )\n removeSelection()\n }}\n onWheel={onWheel}\n sx={{\n outline: 'none',\n flex: 1,\n position: 'relative',\n overflow: 'hidden',\n cursor: 'grab',\n bgcolor: '#15171b',\n backgroundImage: 'radial-gradient(rgba(255,255,255,.07) 1px, transparent 1px)',\n backgroundSize: `${20 * view.zoom}px ${20 * view.zoom}px`,\n backgroundPosition: `${view.x}px ${view.y}px`\n }}\n >\n <Box\n sx={{\n position: 'absolute',\n left: 0,\n top: 0,\n transformOrigin: '0 0',\n transform: `translate(${view.x}px, ${view.y}px) scale(${view.zoom})`\n }}\n >\n <svg\n width={1}\n height={1}\n style={{ position: 'absolute', overflow: 'visible', pointerEvents: 'none' }}\n aria-hidden\n >\n {lines.map((line) => (\n <RelationshipLine\n key={line.id}\n line={line}\n hovered={hoveredEdge === line.id}\n onHover={(hovered) => setHoveredEdge(hovered ? line.id : null)}\n />\n ))}\n {linkPreview && (\n <path\n d={linkPreview}\n fill=\"none\"\n stroke=\"#F58220\"\n strokeWidth={2}\n strokeDasharray=\"5 4\"\n />\n )}\n </svg>\n\n {nodes.map((node) => (\n <TableCard\n key={node.id}\n node={node}\n position={placed(node)}\n height={heights.get(node.id) ?? HEADER}\n collapsed={!!collapsed[node.id]}\n selected={!!isSelected(node)}\n linking={!!linking && linking.node.id !== node.id}\n selectedField={\n selection?.kind === 'dimension' || selection?.kind === 'measure'\n ? selection.uid\n : null\n }\n onToggle={() =>\n setCollapsed((current) => ({ ...current, [node.id]: !current[node.id] }))\n }\n onScroll={(top) => setScrolls((current) => ({ ...current, [node.id]: top }))}\n onHeaderDown={(event) => startMove(event, node)}\n onColumnDown={(event, column) => startLink(event, node, column)}\n onFieldClick={(item) => setSelection({ kind: item.kind, uid: item.uid })}\n onAddField={(kind, column) => addField(kind, node.name, column)}\n />\n ))}\n </Box>\n\n <Box\n onMouseDown={(event) => event.stopPropagation()}\n sx={{\n position: 'absolute',\n top: 8,\n left: 8,\n right: 8,\n display: 'flex',\n gap: 0.75,\n flexWrap: 'wrap',\n alignItems: 'center',\n pointerEvents: 'none',\n '& > *': { pointerEvents: 'auto' }\n }}\n >\n <Button size=\"small\" variant=\"outlined\" onClick={addTable}>\n + Tabela\n </Button>\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={!editor.tables.length}\n onClick={() => setPicking(editor.tables[0]?.name ?? null)}\n title=\"Escolher a tabela e marcar as colunas que viram dimensão\"\n >\n + Dimensões\n </Button>\n <Button\n size=\"small\"\n onClick={onLoadColumns}\n disabled={loadingColumns}\n title=\"Lê uma linha de cada tabela para listar as colunas\"\n sx={{ bgcolor: '#1b1e23' }}\n >\n {loadingColumns ? 'Lendo colunas…' : 'Recarregar colunas'}\n </Button>\n <Box sx={{ ml: 'auto', display: 'flex', gap: 0.5, alignItems: 'center' }}>\n <Button\n size=\"small\"\n onClick={() => {\n const layout = autoLayout(nodes, heights)\n setPositions(() => layout)\n fitToScreen(layout)\n }}\n title=\"Dimensões em cima, fatos embaixo (troca as posições salvas)\"\n sx={{ bgcolor: '#1b1e23' }}\n >\n Organizar\n </Button>\n <Button size=\"small\" onClick={() => fitToScreen()} sx={{ bgcolor: '#1b1e23' }}>\n Ajustar à tela\n </Button>\n <IconButton\n size=\"small\"\n aria-label=\"Diminuir zoom\"\n onClick={() =>\n setView((current) => ({ ...current, zoom: Math.max(0.3, current.zoom - 0.1) }))\n }\n >\n −\n </IconButton>\n <Typography sx={{ fontSize: 11, fontFamily: MONO, width: 36, textAlign: 'center' }}>\n {Math.round(view.zoom * 100)}%\n </Typography>\n <IconButton\n size=\"small\"\n aria-label=\"Aumentar zoom\"\n onClick={() =>\n setView((current) => ({ ...current, zoom: Math.min(2, current.zoom + 0.1) }))\n }\n >\n +\n </IconButton>\n </Box>\n </Box>\n\n {!nodes.length && (\n <Box\n sx={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n pointerEvents: 'none',\n color: 'text.secondary',\n fontSize: 13,\n textAlign: 'center',\n px: 4\n }}\n >\n Modelo vazio. Adicione as tabelas dimensão (cadastros: navio, calendário…) e fato\n (lançamentos: pesagens, custos…) e arraste a coluna da fato até a chave da dimensão para\n relacioná-las.\n </Box>\n )}\n {!!nodes.length && (\n <Typography\n sx={{\n position: 'absolute',\n left: 10,\n bottom: 6,\n fontSize: 11,\n color: 'text.disabled',\n pointerEvents: 'none'\n }}\n >\n Arraste uma coluna até a coluna de outra tabela para relacionar · +◇/+Σ na coluna cria\n dimensão/medida · Delete remove · Ctrl+roda: zoom\n </Typography>\n )}\n </Box>\n\n {panel.open ? (\n <Box\n sx={{\n width: panel.width,\n flexShrink: 0,\n borderLeft: 1,\n borderColor: 'divider',\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0\n }}\n >\n {/* Borda arrastável: redimensiona o painel */}\n <Box\n onMouseDown={startPanelResize}\n title=\"Arraste para redimensionar\"\n sx={{\n position: 'absolute',\n left: -3,\n top: 0,\n bottom: 0,\n width: 6,\n cursor: 'ew-resize',\n zIndex: 2,\n '&:hover': { bgcolor: 'primary.main', opacity: 0.4 }\n }}\n />\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 1.5,\n py: 0.5,\n borderBottom: 1,\n borderColor: 'divider'\n }}\n >\n <Typography sx={{ fontSize: 12, fontWeight: 700, color: 'text.secondary', flex: 1 }}>\n Propriedades\n </Typography>\n <IconButton\n size=\"small\"\n aria-label=\"Recolher propriedades\"\n title=\"Recolher\"\n onClick={() => setPanel((current) => ({ ...current, open: false }))}\n >\n ⟩\n </IconButton>\n </Box>\n <Box sx={{ overflow: 'auto', flex: 1, p: 1.5 }}>\n <Properties\n editor={editor}\n selection={selection}\n columns={columns}\n errors={errors}\n warnings={warnings}\n usage={usage}\n onSelect={setSelection}\n onTry={onTry}\n setEditor={setEditor}\n patchTable={patchTable}\n patchRelationship={patchRelationship}\n patchDimension={patchDimension}\n patchMeasure={patchMeasure}\n removeTable={removeTable}\n commitRename={commitRename}\n addField={addField}\n unplaced={unplaced}\n />\n </Box>\n </Box>\n ) : (\n <Box\n component=\"button\"\n type=\"button\"\n title=\"Mostrar as propriedades\"\n onClick={() => setPanel((current) => ({ ...current, open: true }))}\n sx={{\n width: 28,\n flexShrink: 0,\n border: 0,\n borderLeft: 1,\n borderColor: 'divider',\n bgcolor: 'background.paper',\n color: 'text.secondary',\n cursor: 'pointer',\n writingMode: 'vertical-rl',\n fontSize: 12,\n py: 1,\n '&:hover': { color: 'primary.main' }\n }}\n >\n ⟨ Propriedades\n </Box>\n )}\n\n <Dialog open={picking !== null} onClose={() => setPicking(null)} maxWidth=\"xs\" fullWidth>\n <DialogTitle sx={{ fontSize: 14 }}>Dimensões</DialogTitle>\n <DialogContent>\n <Typography sx={{ fontSize: 12, color: 'text.secondary', mb: 1 }}>\n Marque as colunas que viram dimensão (filtro e eixo dos gráficos). Para expressões como{' '}\n <code>YEAR(tabela.data)</code>, use o modo SQL da dimensão.\n </Typography>\n <TextField\n select\n size=\"small\"\n fullWidth\n label=\"tabela\"\n value={picking ?? ''}\n onChange={(e) => setPicking(e.target.value)}\n sx={{ ...inputSx, mb: 1 }}\n >\n {editor.tables.map((table) => (\n <MenuItem key={table.uid} value={table.name}>\n {table.name}\n </MenuItem>\n ))}\n </TextField>\n {picking && (\n <DimensionPicker\n editor={editor}\n setEditor={setEditor}\n columns={columns}\n table={picking}\n onOpen={(uid) => {\n setPicking(null)\n setSelection({ kind: 'dimension', uid })\n }}\n />\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setPicking(null)}>Fechar</Button>\n </DialogActions>\n </Dialog>\n </Box>\n )\n}\n\n/** Curva com tangentes horizontais (saída e chegada pelas laterais dos cards). */\nfunction curve(from: Point, to: Point) {\n const bend = Math.max(40, Math.abs(to.x - from.x) / 2)\n const out = to.x >= from.x ? 1 : -1\n return `M ${from.x} ${from.y} C ${from.x + bend * out} ${from.y}, ${to.x - bend * out} ${to.y}, ${to.x} ${to.y}`\n}\n\nfunction RelationshipLine({\n line,\n hovered,\n onHover\n}: {\n line: {\n from: Point\n to: Point\n selected: boolean\n inner?: boolean\n error?: string\n onClick?: () => void\n }\n hovered: boolean\n onHover: (hovered: boolean) => void\n}) {\n const { from, to } = line\n const d = curve(from, to)\n const color = line.error ? '#ff6b6b' : line.selected ? '#F58220' : hovered ? '#ced4da' : '#868e96'\n const out = to.x >= from.x ? 1 : -1\n // Ponto do meio da curva e a direção do filtro (do lado 1 para o lado N)\n const mid = { x: (from.x + to.x) / 2, y: (from.y + to.y) / 2 }\n const angle = (Math.atan2(from.y - to.y, from.x - to.x) * 180) / Math.PI\n return (\n <g style={{ pointerEvents: line.onClick ? 'auto' : 'none' }}>\n {line.error && <title>{line.error}</title>}\n {/* biome-ignore lint/a11y/noStaticElementInteractions: área de clique da linha; os relacionamentos também abrem pela lista do painel */}\n <path\n d={d}\n fill=\"none\"\n stroke=\"transparent\"\n strokeWidth={12}\n style={{ cursor: line.onClick ? 'pointer' : undefined, pointerEvents: 'stroke' }}\n onMouseDown={(event) => event.stopPropagation()}\n onClick={line.onClick}\n onMouseEnter={() => onHover(true)}\n onMouseLeave={() => onHover(false)}\n />\n <path\n d={d}\n fill=\"none\"\n stroke={color}\n strokeWidth={line.selected || line.inner ? 2.4 : 1.4}\n />\n <polygon\n points=\"-5,-4 5,0 -5,4\"\n fill={color}\n transform={`translate(${mid.x} ${mid.y}) rotate(${angle})`}\n />\n <text\n x={from.x + 8 * out}\n y={from.y - 5}\n fill={color}\n fontSize={14}\n fontWeight={700}\n textAnchor=\"middle\"\n >\n *\n </text>\n <text\n x={to.x - 8 * out}\n y={to.y - 5}\n fill={color}\n fontSize={12}\n fontWeight={700}\n textAnchor=\"middle\"\n >\n 1\n </text>\n </g>\n )\n}\n\nfunction TableCard({\n node,\n position,\n height,\n collapsed,\n selected,\n linking,\n selectedField,\n onToggle,\n onScroll,\n onHeaderDown,\n onColumnDown,\n onFieldClick,\n onAddField\n}: {\n node: DiagramNode\n position: Point\n height: number\n collapsed: boolean\n selected: boolean\n linking: boolean\n selectedField: string | null\n onToggle: () => void\n onScroll: (top: number) => void\n onHeaderDown: (event: ReactMouseEvent) => void\n onColumnDown: (event: ReactMouseEvent, column: string) => void\n onFieldClick: (item: FieldItem) => void\n onAddField: (kind: 'dimension' | 'measure', column: { name: string; numeric: boolean }) => void\n}) {\n const style = ROLE_STYLE[node.role]\n const columnActions = ['dimension', 'measure'] as const\n return (\n <Box\n onMouseDown={(event) => event.stopPropagation()}\n sx={{\n position: 'absolute',\n left: position.x,\n top: position.y,\n width: CARD_WIDTH,\n height,\n bgcolor: '#23272e',\n border: '1px solid',\n borderColor: node.error ? 'error.main' : selected ? style.color : '#3a3f47',\n borderTop: `3px solid ${style.color}`,\n borderRadius: 1,\n boxShadow: selected ? `0 0 0 2px ${style.color}55, 0 6px 18px rgba(0,0,0,.4)` : 3,\n display: 'flex',\n flexDirection: 'column',\n userSelect: 'none',\n cursor: 'default'\n }}\n >\n <Box\n onMouseDown={onHeaderDown}\n title={node.error}\n sx={{\n height: HEADER - 3,\n display: 'flex',\n alignItems: 'center',\n gap: 0.75,\n px: 1,\n cursor: 'move',\n borderBottom: collapsed ? 0 : '1px solid #3a3f47',\n flexShrink: 0\n }}\n >\n <Box component=\"span\" sx={{ color: style.color, fontSize: 13 }}>\n ▦\n </Box>\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: 13,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1\n }}\n >\n {node.name || <em>sem nome</em>}\n </Typography>\n <Box component=\"span\" title={style.title} sx={{ fontSize: 10, color: style.color }}>\n {style.label}\n </Box>\n {node.error && (\n <Box component=\"span\" sx={{ color: 'error.main', fontSize: 12 }}>\n ⚠\n </Box>\n )}\n <Box\n component=\"button\"\n type=\"button\"\n aria-label={collapsed ? 'Expandir' : 'Recolher'}\n onMouseDown={(event) => event.stopPropagation()}\n onClick={onToggle}\n sx={{\n border: 0,\n bgcolor: 'transparent',\n color: 'text.secondary',\n cursor: 'pointer',\n p: 0,\n fontSize: 11\n }}\n >\n {collapsed ? '▾' : '▴'}\n </Box>\n </Box>\n {!collapsed && (\n <Box\n onScroll={(event) => onScroll(event.currentTarget.scrollTop)}\n sx={{ overflow: 'auto', flex: 1, py: `${PADDING}px` }}\n >\n {!node.items.length && (\n <Typography\n sx={{ fontSize: 11, color: 'text.disabled', px: 1, lineHeight: `${ROW}px` }}\n >\n sem colunas lidas\n </Typography>\n )}\n {node.items.map((item) =>\n item.kind === 'column' ? (\n <Box\n key={`c:${item.name}`}\n data-diagram-node={node.id}\n data-diagram-column={item.name}\n onMouseDown={(event) => onColumnDown(event, item.name)}\n title={\n item.missing\n ? 'Citada no modelo, mas a tabela não devolve essa coluna'\n : 'Arraste até a coluna de outra tabela para relacionar'\n }\n sx={{\n height: ROW,\n display: 'flex',\n alignItems: 'center',\n gap: 0.75,\n px: 1,\n fontSize: 12,\n cursor: 'crosshair',\n '& .column-actions': { display: 'none' },\n '&:hover .column-actions': { display: linking ? 'none' : 'flex' },\n color: item.missing ? 'error.main' : item.linked ? 'text.primary' : '#adb5bd',\n fontWeight: item.linked ? 700 : 400,\n '&:hover': { bgcolor: linking ? 'rgba(245,130,32,.25)' : 'rgba(255,255,255,.06)' }\n }}\n >\n <Box\n component=\"span\"\n sx={{ width: 14, textAlign: 'center', color: 'text.secondary' }}\n >\n {item.isKey ? '🔑' : item.numeric ? 'Σ' : ''}\n </Box>\n <Box\n component=\"span\"\n sx={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}\n >\n {item.name}\n </Box>\n <Box className=\"column-actions\" sx={{ ml: 'auto', gap: 0.25 }}>\n {columnActions.map((kind) => (\n <Box\n key={kind}\n component=\"button\"\n type=\"button\"\n title={\n kind === 'dimension'\n ? `Nova dimensão com ${node.name}.${item.name}`\n : `Nova medida: ${item.numeric ? 'soma' : 'contagem'} de ${node.name}.${item.name}`\n }\n onMouseDown={(event) => event.stopPropagation()}\n onClick={() => onAddField(kind, item)}\n sx={{\n border: '1px solid #3a3f47',\n borderRadius: 0.5,\n bgcolor: '#1b1e23',\n color: kind === 'measure' ? '#ffd8a8' : '#a5d8ff',\n cursor: 'pointer',\n fontSize: 10,\n lineHeight: '14px',\n px: 0.5\n }}\n >\n {kind === 'dimension' ? '+◇' : '+Σ'}\n </Box>\n ))}\n </Box>\n </Box>\n ) : (\n <Box\n key={`f:${item.uid}`}\n onMouseDown={(event) => event.stopPropagation()}\n onClick={() => onFieldClick(item)}\n sx={{\n height: ROW,\n display: 'flex',\n alignItems: 'center',\n gap: 0.75,\n px: 1,\n fontSize: 12,\n cursor: 'pointer',\n color: item.kind === 'measure' ? '#ffd8a8' : '#a5d8ff',\n bgcolor: selectedField === item.uid ? 'rgba(245,130,32,.2)' : undefined,\n '&:hover': { bgcolor: 'rgba(255,255,255,.06)' }\n }}\n >\n <Box component=\"span\" sx={{ width: 14, textAlign: 'center' }}>\n {item.icon}\n </Box>\n <Box\n component=\"span\"\n sx={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}\n >\n {item.name || <em>sem nome</em>}\n </Box>\n </Box>\n )\n )}\n </Box>\n )}\n </Box>\n )\n}\n\nfunction PropertyBlock({ title, children }: { title: string; children: ReactNode }) {\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1, mb: 2 }}>\n <Typography\n variant=\"overline\"\n sx={{ color: 'text.secondary', fontWeight: 700, lineHeight: 1.5 }}\n >\n {title}\n </Typography>\n {children}\n </Box>\n )\n}\n\nfunction ColumnSelect({\n label,\n value,\n options,\n onChange\n}: {\n label: string\n value: string\n options: string[]\n onChange: (value: string) => void\n}) {\n // Sem colunas lidas, digita livre\n if (!options.length)\n return (\n <TextField\n size=\"small\"\n label={label}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n sx={{ ...inputSx, flex: 1 }}\n />\n )\n return (\n <TextField\n select\n size=\"small\"\n label={label}\n value={options.includes(value) ? value : ''}\n error={!options.includes(value)}\n onChange={(e) => onChange(e.target.value)}\n sx={{ ...inputSx, flex: 1 }}\n >\n {options.map((name) => (\n <MenuItem key={name} value={name}>\n {name}\n </MenuItem>\n ))}\n </TextField>\n )\n}\n\nfunction TableSelect({\n label,\n value,\n tables,\n onChange\n}: {\n label: string\n value: string\n tables: TableRow[]\n onChange: (uid: string) => void\n}) {\n return (\n <TextField\n select\n size=\"small\"\n label={label}\n value={tables.some((table) => table.uid === value) ? value : ''}\n onChange={(e) => onChange(e.target.value)}\n sx={{ ...inputSx, flex: 1 }}\n >\n {tables.map((table) => (\n <MenuItem key={table.uid} value={table.uid}>\n {table.name}\n </MenuItem>\n ))}\n </TextField>\n )\n}\n\nfunction Properties({\n editor,\n selection,\n columns,\n errors,\n warnings,\n usage,\n onSelect,\n onTry,\n setEditor,\n patchTable,\n patchRelationship,\n patchDimension,\n patchMeasure,\n removeTable,\n commitRename,\n addField,\n unplaced\n}: {\n editor: EditorModel\n selection: Selection\n columns: ModelColumns | null\n errors: Record<string, string>\n warnings: Record<string, string>\n usage: Map<string, number>\n onSelect: (selection: Selection) => void\n onTry: Props['onTry']\n setEditor: Props['setEditor']\n patchTable: (uid: string, changes: Partial<TableRow>) => void\n patchRelationship: (uid: string, changes: Partial<RelationshipRow>) => void\n patchDimension: (uid: string, changes: Partial<DimensionRow>) => void\n patchMeasure: (uid: string, changes: Partial<MeasureRow>) => void\n removeTable: (uid: string) => void\n commitRename: (uid: string, name: string) => void\n addField: (kind: 'dimension' | 'measure', table: string) => void\n unplaced: FieldItem[]\n}) {\n const tableName = (uid: string) => editor.tables.find((table) => table.uid === uid)?.name ?? '?'\n const columnsOf = (uid: string) => columns?.tables[tableName(uid)] ?? []\n const measureNames = editor.measures.map((row) => row.name).filter(Boolean)\n const inUse = (name: string) => usage.get(name) ?? 0\n const addButtons = (table: string, kinds: ('dimension' | 'measure')[]) =>\n kinds.map((kind) => (\n <Button key={kind} size=\"small\" onClick={() => addField(kind, table)}>\n {kind === 'dimension' ? '+ Dimensão daqui' : '+ Medida daqui'}\n </Button>\n ))\n\n if (selection?.kind === 'table') {\n const table = editor.tables.find((row) => row.uid === selection.uid)\n if (!table) return null\n return (\n <>\n <PropertyBlock title=\"Tabela\">\n <RenameField\n key={table.uid}\n value={table.name}\n onCommit={(name) => commitRename(table.uid, name)}\n />\n <ColumnSelect\n label=\"chave (key)\"\n value={table.key}\n options={columnsOf(table.uid).length ? ['', ...columnsOf(table.uid)] : []}\n onChange={(key) => patchTable(table.uid, { key })}\n />\n <SqlEditor\n label=\"sql\"\n minRows={3}\n maxRows={12}\n value={table.sql}\n error={errors[`table:${table.name}`]}\n onChange={(sql) => patchTable(table.uid, { sql })}\n />\n </PropertyBlock>\n <PropertyBlock title=\"Dimensões (marque as colunas)\">\n <DimensionPicker\n editor={editor}\n setEditor={setEditor}\n columns={columns}\n table={table.name}\n onOpen={(uid) => onSelect({ kind: 'dimension', uid })}\n />\n </PropertyBlock>\n <PropertyBlock title=\"Dicionário\">\n <DictionaryFields row={table} onPatch={(changes) => patchTable(table.uid, changes)} />\n </PropertyBlock>\n <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>\n {addButtons(table.name, ['dimension', 'measure'])}\n <Button size=\"small\" color=\"error\" onClick={() => removeTable(table.uid)}>\n Remover tabela\n </Button>\n </Box>\n </>\n )\n }\n\n if (selection?.kind === 'relationship') {\n const index = editor.relationships.findIndex((row) => row.uid === selection.uid)\n const row = editor.relationships[index]\n if (!row) return null\n return (\n <>\n <PropertyBlock title=\"Relacionamento\">\n <Typography sx={{ fontSize: 12, color: 'text.secondary' }}>\n Muitos para um (*:1). O filtro vai do lado 1 para o lado N: filtrar{' '}\n <b>{tableName(row.toTable)}</b> filtra as linhas de <b>{tableName(row.fromTable)}</b>.\n </Typography>\n {errors[`relationship:${index}`] && (\n <Alert severity=\"error\" sx={{ fontSize: 12 }}>\n {errors[`relationship:${index}`]}\n </Alert>\n )}\n <Typography sx={{ fontSize: 12, fontWeight: 700 }}>Lado N (*)</Typography>\n <Box sx={{ display: 'flex', gap: 1 }}>\n <TableSelect\n label=\"tabela\"\n value={row.fromTable}\n tables={editor.tables}\n onChange={(fromTable) => patchRelationship(row.uid, { fromTable })}\n />\n <ColumnSelect\n label=\"coluna\"\n value={row.fromColumn}\n options={columnsOf(row.fromTable)}\n onChange={(fromColumn) => patchRelationship(row.uid, { fromColumn })}\n />\n </Box>\n <Typography sx={{ fontSize: 12, fontWeight: 700 }}>Lado 1</Typography>\n <Box sx={{ display: 'flex', gap: 1 }}>\n <TableSelect\n label=\"tabela\"\n value={row.toTable}\n tables={editor.tables}\n onChange={(toTable) => patchRelationship(row.uid, { toTable })}\n />\n <ColumnSelect\n label=\"coluna\"\n value={row.toColumn}\n options={columnsOf(row.toTable)}\n onChange={(toColumn) => patchRelationship(row.uid, { toColumn })}\n />\n </Box>\n </PropertyBlock>\n <PropertyBlock title=\"Opções\">\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n checked={row.inner}\n onChange={(e) => patchRelationship(row.uid, { inner: e.target.checked })}\n />\n }\n label={\n <Typography sx={{ fontSize: 12 }}>\n Pressupor integridade referencial (INNER JOIN): linhas de {tableName(row.fromTable)}{' '}\n sem par em {tableName(row.toTable)} ficam de fora, em vez de virar um grupo em\n branco. A tabela do lado 1 entra sempre na consulta.\n </Typography>\n }\n />\n </PropertyBlock>\n <Box sx={{ display: 'flex', gap: 1 }}>\n <Button\n size=\"small\"\n onClick={() =>\n patchRelationship(row.uid, {\n fromTable: row.toTable,\n fromColumn: row.toColumn,\n toTable: row.fromTable,\n toColumn: row.fromColumn\n })\n }\n >\n Inverter lados\n </Button>\n <Button\n size=\"small\"\n color=\"error\"\n onClick={() => {\n setEditor((current) => ({\n ...current,\n relationships: current.relationships.filter((item) => item.uid !== row.uid)\n }))\n onSelect(null)\n }}\n >\n Remover\n </Button>\n </Box>\n </>\n )\n }\n\n if (selection?.kind === 'dimension') {\n const row = editor.dimensions.find((item) => item.uid === selection.uid)\n if (!row) return null\n return (\n <>\n <PropertyBlock title=\"Dimensão\">\n <NameField\n label=\"nome\"\n value={row.name}\n onChange={(name) => patchDimension(row.uid, { name })}\n />\n <TextField\n select\n size=\"small\"\n label=\"tipo\"\n value={row.type}\n onChange={(e) =>\n patchDimension(row.uid, { type: e.target.value as DimensionRow['type'] })\n }\n sx={inputSx}\n >\n <MenuItem value=\"string\">string</MenuItem>\n <MenuItem value=\"number\">number</MenuItem>\n </TextField>\n <DimensionSource\n key={row.uid}\n row={row}\n editor={editor}\n columns={columns}\n error={errors[`dimension:${row.name}`]}\n warning={warnings[`dimension:${row.name}`]}\n onPatch={(changes) => patchDimension(row.uid, changes)}\n />\n </PropertyBlock>\n <PropertyBlock title=\"Dicionário\">\n <DictionaryFields row={row} onPatch={(changes) => patchDimension(row.uid, changes)} />\n </PropertyBlock>\n <FieldActions\n name={row.name}\n uses={inUse(row.name)}\n onTry={() => onTry({ dimensions: [row.name], measures: [] })}\n onRemove={() => {\n setEditor((current) => ({\n ...current,\n dimensions: current.dimensions.filter((item) => item.uid !== row.uid)\n }))\n onSelect(null)\n }}\n />\n </>\n )\n }\n\n if (selection?.kind === 'measure') {\n const row = editor.measures.find((item) => item.uid === selection.uid)\n if (!row) return null\n return (\n <>\n <PropertyBlock title=\"Medida\">\n <NameField\n label=\"nome\"\n value={row.name}\n onChange={(name) => patchMeasure(row.uid, { name })}\n />\n <MeasureTypeSelect\n value={row.type}\n onChange={(type) => patchMeasure(row.uid, { type })}\n />\n <MeasureDefinition\n row={row}\n measureNames={measureNames}\n error={errors[`measure:${row.name}`]}\n onPatch={(changes) => patchMeasure(row.uid, changes)}\n />\n <FormatFields row={row} onPatch={(changes) => patchMeasure(row.uid, changes)} />\n </PropertyBlock>\n <PropertyBlock title=\"Dicionário\">\n <DictionaryFields row={row} onPatch={(changes) => patchMeasure(row.uid, changes)} />\n </PropertyBlock>\n <FieldActions\n name={row.name}\n uses={inUse(row.name)}\n onTry={() => onTry({ dimensions: [], measures: [row.name] })}\n onRemove={() => {\n setEditor((current) => ({\n ...current,\n measures: current.measures.filter((item) => item.uid !== row.uid)\n }))\n onSelect(null)\n }}\n />\n </>\n )\n }\n\n // Nada selecionado: resumo e a lista de relacionamentos (\"Gerenciar relações\")\n const formulas = editor.measures.filter((row) => !isAggregate(row))\n return (\n <>\n <PropertyBlock title=\"Modelo\">\n <Typography sx={{ fontSize: 12, color: 'text.secondary' }}>\n {`${editor.tables.length} tabela(s), ${editor.relationships.length} relacionamento(s), ${editor.dimensions.length} dimensão(ões), ${editor.measures.length} medida(s). Clique num card, linha ou campo para editar.`}\n </Typography>\n </PropertyBlock>\n <PropertyBlock title=\"Relacionamentos\">\n {!editor.relationships.length && (\n <Typography sx={{ fontSize: 12, color: 'text.disabled' }}>\n Nenhum. Arraste a coluna da fato até a chave da dimensão.\n </Typography>\n )}\n {editor.relationships.map((row, index) => (\n <Box\n key={row.uid}\n component=\"button\"\n type=\"button\"\n onClick={() => onSelect({ kind: 'relationship', uid: row.uid })}\n sx={{\n textAlign: 'left',\n border: 1,\n borderColor: errors[`relationship:${index}`] ? 'error.main' : 'divider',\n borderRadius: 1,\n bgcolor: 'transparent',\n color: 'text.primary',\n fontFamily: MONO,\n fontSize: 11,\n p: 0.75,\n cursor: 'pointer',\n '&:hover': { bgcolor: 'rgba(255,255,255,.05)' }\n }}\n >\n {tableName(row.fromTable)}.{row.fromColumn} * → 1 {tableName(row.toTable)}.\n {row.toColumn}\n </Box>\n ))}\n </PropertyBlock>\n {!!unplaced.length && (\n <PropertyBlock title=\"Fora dos cards\">\n <Typography sx={{ fontSize: 11, color: 'text.disabled' }}>\n O SQL não cita uma tabela do modelo (<code>tabela.coluna</code>).\n </Typography>\n {unplaced.map((item) => (\n <Button\n key={item.uid}\n size=\"small\"\n onClick={() => onSelect({ kind: item.kind, uid: item.uid })}\n sx={{ justifyContent: 'flex-start', fontFamily: MONO }}\n >\n {item.icon} {item.name || 'sem nome'}\n </Button>\n ))}\n </PropertyBlock>\n )}\n <PropertyBlock title=\"Medidas calculadas\">\n {formulas.map((row) => (\n <Button\n key={row.uid}\n size=\"small\"\n onClick={() => onSelect({ kind: 'measure', uid: row.uid })}\n sx={{ justifyContent: 'flex-start', fontFamily: MONO }}\n >\n {row.type === 'ratio' ? '÷' : 'ƒ'} {row.name}\n </Button>\n ))}\n <Button\n size=\"small\"\n onClick={() => {\n const uid = newUid()\n const taken = [...editor.dimensions, ...editor.measures].map((item) => item.name)\n setEditor((current) => ({\n ...current,\n measures: [\n ...current.measures,\n emptyMeasure({ uid, type: 'formula', name: freeName('novaMedida', taken) })\n ]\n }))\n onSelect({ kind: 'measure', uid })\n }}\n >\n + Medida calculada\n </Button>\n </PropertyBlock>\n <Divider sx={{ my: 1 }} />\n <Typography sx={{ fontSize: 11, color: 'text.disabled' }}>\n Razões e fórmulas não pertencem a uma tabela: aparecem em \"Medidas calculadas\".\n </Typography>\n </>\n )\n}\n\n/** Nome da tabela: renomeia (e corrige as referências `tabela.coluna`) ao sair do campo. */\nfunction RenameField({ value, onCommit }: { value: string; onCommit: (name: string) => void }) {\n const [text, setText] = useState(value)\n useEffect(() => setText(value), [value])\n return (\n <NameField\n label=\"nome (renomeia as referências ao sair do campo)\"\n value={text}\n onChange={setText}\n onBlur={() => {\n if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(text)) onCommit(text)\n else setText(value)\n }}\n />\n )\n}\n\nfunction FieldActions({\n name,\n uses,\n onTry,\n onRemove\n}: {\n name: string\n uses: number\n onTry: () => void\n onRemove: () => void\n}) {\n return (\n <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>\n <Button size=\"small\" onClick={onTry} disabled={!name}>\n ▶ Testar no playground\n </Button>\n <Tooltip title={uses ? 'Em uso na página: as consultas que usam vão falhar' : ''}>\n <span>\n <Button size=\"small\" color=\"error\" onClick={onRemove}>\n Remover\n </Button>\n </span>\n </Tooltip>\n {!!uses && (\n <Typography sx={{ fontSize: 11, color: 'text.secondary' }}>\n {uses} consulta(s) usando\n </Typography>\n )}\n </Box>\n )\n}\n","import {\n Alert,\n Box,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Tooltip,\n Typography\n} from '@mui/material'\nimport { useEffect, useMemo, useState, useSyncExternalStore } from 'react'\nimport type { DashboardDevtoolsContext } from '../client/DashboardProvider'\nimport { useDashboard } from '../client/DashboardProvider'\nimport { canonicalJson, toModelCode } from '../codegen'\nimport type { ModelDef } from '../model'\nimport type {\n DevtoolsCapabilities,\n ModelColumns,\n ModelValidation,\n SaveModelResult,\n SchemaTable\n} from '../types'\nimport { lineDiff } from './lineDiff'\nimport { ModelDiagram } from './ModelDiagram'\nimport { type EditorModel, fromEditor, toEditor, validateEditor, withoutDiagram } from './modelCode'\nimport { SqlCompletionsContext } from './SqlEditor'\nimport { errorMessage } from './store'\nimport { CodeBlock, copyText, FileDiff, MONO } from './ui'\n\ntype Props = {\n devtools: DashboardDevtoolsContext\n /** Modelo registrado no servidor. */\n original: ModelDef\n capabilities: DevtoolsCapabilities | null\n /** Tabelas do banco, para o autocomplete (vazio enquanto carrega). */\n tables: SchemaTable[]\n /** Abre o playground com essa combinação. */\n onTry: (selection: { dimensions: string[]; measures: string[] }) => void\n /** O arquivo do modelo foi reescrito: recarregar o modelo registrado. */\n onSaved: () => void\n}\n\nconst same = (a: unknown, b: unknown) => canonicalJson(a) === canonicalJson(b)\n\n/**\n * Editor do modelo: o diagrama (cards e relacionamentos, como a exibição de modelo do Power BI) e o\n * painel de propriedades ao lado. As edições ficam locais até \"Aplicar\": aí o SQL de cada pedaço é\n * validado no banco e o rascunho vai junto de todas as consultas da página (o servidor usa ele no\n * lugar do modelo registrado). \"Salvar no arquivo\" reescreve `src/dashboard/models/<nome>.ts`.\n */\nexport function ModelPanel({ devtools, original, capabilities, tables, onTry, onSaved }: Props) {\n const { store, draft, setDraft } = devtools\n const { fetcher, model: modelName } = useDashboard()\n const [editor, setEditor] = useState<EditorModel>(() => toEditor(draft ?? original))\n const [showCode, setShowCode] = useState(false)\n const [checked, setChecked] = useState<{ structure: string; result: ModelValidation } | null>(\n null\n )\n const [columns, setColumns] = useState<ModelColumns | null>(null)\n const [columnErrors, setColumnErrors] = useState<Record<string, string>>({})\n const [busy, setBusy] = useState<string | null>(null)\n const [actionError, setActionError] = useState<string | null>(null)\n const [save, setSave] = useState<SaveModelResult | null>(null)\n\n // Rascunho descartado/aplicado ou modelo recarregado: o editor acompanha\n useEffect(() => setEditor(toEditor(draft ?? original)), [draft, original])\n const errors = useMemo(() => validateEditor(editor), [editor])\n const edited = useMemo(() => fromEditor(editor), [editor])\n // Erro de validação é do SQL validado; editou, deixa de valer (mover card no diagrama não conta)\n const structure = useMemo(() => canonicalJson(withoutDiagram(edited)), [edited])\n const validation = checked?.structure === structure ? checked.result : null\n const reference = draft ?? original\n const dirty = !same(edited, reference)\n const differsFromOriginal = !same(edited, original)\n\n // Quantas consultas ativas usam cada nome (dimensão, filtro ou medida)\n const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot)\n const usage = useMemo(() => {\n const count = new Map<string, number>()\n for (const { last } of snapshot.instances) {\n const { dimensions = [], measures = [], filters = {} } = last.query\n for (const name of new Set([...dimensions, ...measures, ...Object.keys(filters)]))\n count.set(name, (count.get(name) ?? 0) + 1)\n }\n return count\n }, [snapshot])\n\n const removed = [\n ...Object.keys(original.dimensions).filter((name) => !edited.dimensions[name]),\n ...Object.keys(original.measures).filter((name) => !edited.measures[name]),\n ...Object.keys(original.tables).filter((name) => !edited.tables[name])\n ]\n\n // --- ações que vão ao servidor ---\n\n const validateSql = async () => {\n const result = await fetcher({ model: modelName, devtools: { validate: true, model: edited } })\n const next = result.devtools?.validation ?? null\n setChecked(next && { structure, result: next })\n if (next) setColumns(next.columns)\n return next\n }\n\n // Só as colunas (uma linha de cada tabela): o diagrama precisa delas para listar e relacionar\n const loadColumns = async () => {\n if (validateEditor(editor).length) {\n setActionError('Corrija os erros do modelo antes de ler as colunas.')\n return\n }\n await act('columns', async () => {\n const result = await fetcher({ model: modelName, devtools: { columns: true, model: edited } })\n setColumns(result.devtools?.columns ?? null)\n setColumnErrors(result.devtools?.columnErrors ?? {})\n })\n }\n\n const act = async (name: string, action: () => Promise<void>) => {\n setBusy(name)\n setActionError(null)\n try {\n await action()\n } catch (error) {\n setActionError(errorMessage(error))\n } finally {\n setBusy(null)\n }\n }\n\n const apply = () =>\n act('apply', async () => {\n // Só moveu cards: não há SQL novo para validar\n const onlyLayout = canonicalJson(withoutDiagram(reference)) === structure\n const result = onlyLayout ? null : await validateSql()\n if (result && Object.keys(result.errors).length) return\n setDraft(differsFromOriginal ? edited : null)\n })\n\n const previewSave = () =>\n act('save', async () => {\n const result = await fetcher({\n model: modelName,\n devtools: { save: 'preview', model: edited }\n })\n setSave(result.devtools?.save ?? null)\n })\n\n const writeSave = () =>\n act('save', async () => {\n await fetcher({ model: modelName, devtools: { save: 'write', model: edited } })\n setSave(null)\n setDraft(null)\n onSaved()\n })\n\n const completions = useMemo(\n () => ({\n tables,\n // `tabela.` completa as colunas da tabela do modelo\n modelColumns: Object.fromEntries(\n editor.tables.map((row) => [row.name, columns?.tables[row.name] ?? []])\n )\n }),\n [tables, columns, editor.tables]\n )\n\n const validationErrors = validation ? Object.entries(validation.errors) : []\n\n return (\n <SqlCompletionsContext.Provider value={completions}>\n <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0 }}>\n <Box sx={{ px: 1.5, '& .MuiAlert-root': { my: 0.5, py: 0 } }}>\n {draft && (\n <Alert severity=\"warning\">\n Rascunho aplicado: as consultas desta página estão usando o modelo editado, não o\n registrado em <code>src/dashboard/models</code>.\n {capabilities?.saveModel\n ? ' Use \"Salvar no arquivo\" quando terminar.'\n : ' Copie o código para o arquivo quando terminar.'}\n </Alert>\n )}\n {actionError && (\n <Alert severity=\"error\" sx={{ fontFamily: MONO, fontSize: 12 }}>\n {actionError}\n </Alert>\n )}\n {!!validationErrors.length && (\n <Alert severity=\"error\">\n O banco recusou {validationErrors.length} pedaço(s) do modelo — veja os campos\n marcados. O rascunho não foi aplicado.\n {validation?.errors.model && <div>{validation.errors.model}</div>}\n </Alert>\n )}\n </Box>\n\n <Box sx={{ flex: 1, minHeight: 0, borderTop: 1, borderColor: 'divider' }}>\n <ModelDiagram\n editor={editor}\n setEditor={setEditor}\n columns={columns}\n errors={{ ...columnErrors, ...validation?.errors }}\n warnings={validation?.warnings ?? {}}\n loadingColumns={busy === 'columns'}\n onLoadColumns={loadColumns}\n onTry={onTry}\n usage={usage}\n />\n </Box>\n\n <Box\n sx={{\n borderTop: 1,\n borderColor: 'divider',\n p: 1,\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n flexWrap: 'wrap'\n }}\n >\n {errors.length ? (\n <Tooltip title={<Box sx={{ whiteSpace: 'pre-line' }}>{errors.join('\\n')}</Box>}>\n <Chip color=\"error\" size=\"small\" label={`${errors.length} erro(s): ${errors[0]}`} />\n </Tooltip>\n ) : validation && !validationErrors.length ? (\n <Chip color=\"success\" size=\"small\" label=\"SQL validado no banco\" />\n ) : (\n <Chip color=\"success\" size=\"small\" variant=\"outlined\" label=\"modelo válido\" />\n )}\n {!!removed.length && (\n <Chip size=\"small\" color=\"warning\" label={`removidos: ${removed.join(', ')}`} />\n )}\n <Box sx={{ ml: 'auto', display: 'flex', gap: 1, flexWrap: 'wrap' }}>\n <Button size=\"small\" onClick={() => setShowCode(true)}>\n Ver código\n </Button>\n <Button size=\"small\" onClick={() => copyText(toModelCode(edited))}>\n Copiar TS\n </Button>\n <Button\n size=\"small\"\n disabled={!!errors.length || !!busy}\n onClick={() =>\n act('validate', async () => {\n await validateSql()\n })\n }\n title=\"Executa cada pedaço do modelo no banco com poucas chaves\"\n >\n {busy === 'validate' ? 'Validando…' : 'Validar SQL'}\n </Button>\n <Button\n size=\"small\"\n disabled={!dirty}\n onClick={() => setEditor(toEditor(reference))}\n title=\"Desfaz as edições ainda não aplicadas\"\n >\n Desfazer\n </Button>\n <Button\n size=\"small\"\n color=\"warning\"\n disabled={!draft}\n onClick={() => setDraft(null)}\n title=\"Volta a usar o modelo registrado no servidor\"\n >\n Descartar rascunho\n </Button>\n {capabilities?.saveModel && (\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={!differsFromOriginal || !!errors.length || !!busy}\n onClick={previewSave}\n title={`Reescreve src/dashboard/models/${original.name}.ts`}\n >\n {busy === 'save' ? 'Gerando…' : 'Salvar no arquivo'}\n </Button>\n )}\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={!dirty || !!errors.length || !!busy}\n onClick={apply}\n >\n {busy === 'apply' ? 'Validando…' : 'Aplicar na página'}\n </Button>\n </Box>\n </Box>\n </Box>\n\n <Dialog open={showCode} onClose={() => setShowCode(false)} maxWidth=\"lg\" fullWidth>\n <DialogTitle>Código do modelo</DialogTitle>\n <DialogContent>\n <CodeBlock code={toModelCode(edited)} maxHeight={600} />\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setShowCode(false)}>Fechar</Button>\n </DialogActions>\n </Dialog>\n\n <Dialog open={!!save} onClose={() => setSave(null)} maxWidth=\"lg\" fullWidth>\n <DialogTitle>Salvar no arquivo</DialogTitle>\n <DialogContent>\n <Typography sx={{ fontFamily: MONO, fontSize: 12, mb: 1 }}>{save?.path}</Typography>\n {save?.warnings.map((warning) => (\n <Alert key={warning} severity=\"warning\" sx={{ mb: 1 }}>\n {warning}\n </Alert>\n ))}\n {save && <FileDiff lines={lineDiff(save.previous, save.content)} />}\n <Typography sx={{ fontSize: 12, color: 'text.secondary', mt: 1 }}>\n O Next recarrega o modelo sozinho; o rascunho é descartado. O lint-staged formata o\n arquivo no commit.\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setSave(null)}>Cancelar</Button>\n <Button\n variant=\"contained\"\n disabled={!save || save.previous === save.content || !!busy}\n onClick={writeSave}\n >\n Gravar\n </Button>\n </DialogActions>\n </Dialog>\n </SqlCompletionsContext.Provider>\n )\n}\n","import {\n Alert,\n Autocomplete,\n Box,\n Button,\n Checkbox,\n Chip,\n FormControlLabel,\n TextField\n} from '@mui/material'\nimport { useEffect, useState } from 'react'\nimport { useDashboard } from '../client/DashboardProvider'\nimport type { ModelDef } from '../model'\nimport type { DashboardQueryDebug, DashboardRow } from '../types'\nimport { errorMessage } from './store'\nimport { CodeBlock, Empty, inlineParams, MONO, ResultTable, Section } from './ui'\n\nexport type PlaygroundSelection = { dimensions: string[]; measures: string[] }\n\ntype Props = {\n /** Modelo em vigor na página (rascunho aplicado ou o registrado). */\n model: ModelDef\n selection: PlaygroundSelection\n onSelectionChange: (selection: PlaygroundSelection) => void\n}\n\ntype Outcome = { rows: DashboardRow[]; debug?: DashboardQueryDebug; ms: number } | { error: string }\n\n/** Consulta avulsa ao modelo: qualquer combinação de dimensões e medidas, com ou sem os filtros. */\nexport function PlaygroundPanel({ model, selection, onSelectionChange }: Props) {\n const { model: modelName, filters, fetcher } = useDashboard()\n const [useFilters, setUseFilters] = useState(true)\n const [running, setRunning] = useState(false)\n const [outcome, setOutcome] = useState<Outcome | null>(null)\n\n const run = async () => {\n setRunning(true)\n const startedAt = Date.now()\n try {\n const result = await fetcher({\n model: modelName,\n dimensions: selection.dimensions,\n measures: selection.measures,\n filters: useFilters ? filters : {}\n })\n setOutcome({ rows: result.rows, debug: result.devtools?.debug, ms: Date.now() - startedAt })\n } catch (error) {\n setOutcome({ error: errorMessage(error) })\n } finally {\n setRunning(false)\n }\n }\n\n // \"Testar\" no editor chega aqui com a seleção pronta: já executa\n const key = JSON.stringify(selection)\n useEffect(() => {\n if (selection.dimensions.length || selection.measures.length) run()\n }, [key])\n\n const empty = !selection.dimensions.length && !selection.measures.length\n\n return (\n <Box sx={{ p: 1.5, overflow: 'auto', height: '100%' }}>\n <Box sx={{ display: 'flex', gap: 1, alignItems: 'flex-start', flexWrap: 'wrap', mb: 2 }}>\n <Autocomplete\n multiple\n size=\"small\"\n options={Object.keys(model.dimensions)}\n value={selection.dimensions}\n onChange={(_, dimensions) => onSelectionChange({ ...selection, dimensions })}\n renderInput={(params) => <TextField {...params} label=\"Dimensões\" />}\n sx={{ minWidth: 280, flex: 1 }}\n />\n <Autocomplete\n multiple\n size=\"small\"\n options={Object.keys(model.measures)}\n value={selection.measures}\n onChange={(_, measures) => onSelectionChange({ ...selection, measures })}\n renderInput={(params) => <TextField {...params} label=\"Medidas\" />}\n sx={{ minWidth: 280, flex: 1 }}\n />\n <FormControlLabel\n control={\n <Checkbox checked={useFilters} onChange={(e) => setUseFilters(e.target.checked)} />\n }\n label=\"Usar filtros da página\"\n />\n <Button variant=\"contained\" disabled={empty || running} onClick={run}>\n {running ? 'Executando…' : 'Executar'}\n </Button>\n </Box>\n\n {!outcome ? (\n <Empty>Escolha dimensões e/ou medidas e execute.</Empty>\n ) : 'error' in outcome ? (\n <Alert severity=\"error\" sx={{ fontFamily: MONO, fontSize: 12 }}>\n {outcome.error}\n </Alert>\n ) : (\n <>\n <Box sx={{ display: 'flex', gap: 1, mb: 1.5 }}>\n <Chip size=\"small\" label={`${outcome.rows.length} linhas`} />\n <Chip size=\"small\" label={`total ${outcome.ms} ms`} />\n {outcome.debug && (\n <Chip\n size=\"small\"\n label={outcome.debug.cached ? 'cache' : `banco ${outcome.debug.durationMs} ms`}\n />\n )}\n {outcome.debug?.draft && <Chip size=\"small\" color=\"warning\" label=\"rascunho\" />}\n </Box>\n <Section title=\"Resultado\">\n <ResultTable rows={outcome.rows} maxHeight={420} />\n </Section>\n {outcome.debug && (\n <Section title=\"SQL gerado\">\n <CodeBlock sql code={inlineParams(outcome.debug.sql, outcome.debug.params)} />\n </Section>\n )}\n </>\n )}\n </Box>\n )\n}\n","import {\n Alert,\n Box,\n Button,\n Checkbox,\n Chip,\n FormControlLabel,\n List,\n ListItemButton,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Tooltip,\n Typography\n} from '@mui/material'\nimport { type ReactNode, useState, useSyncExternalStore } from 'react'\nimport type { DashboardDevtoolsContext } from '../client/DashboardProvider'\nimport { useDashboard } from '../client/DashboardProvider'\nimport { diffRows, type RowDiff } from '../compare'\nimport type { DashboardRow, DevtoolsCapabilities, ProfileStep } from '../types'\nimport { scrollToQuery } from './Inspector'\nimport { errorMessage, type QueryRun } from './store'\nimport {\n CodeBlock,\n Empty,\n inlineParams,\n MONO,\n ResultTable,\n RowDiffTable,\n Section,\n STATUS_LABEL,\n StatusDot\n} from './ui'\n\nexport type QuerySelection = { instanceId: string; runId?: number }\n\ntype Props = {\n devtools: DashboardDevtoolsContext\n capabilities: DevtoolsCapabilities | null\n selected: QuerySelection | null\n onSelect: (selection: QuerySelection) => void\n /** Destaca o componente da consulta na página. */\n onHover: (instanceId: string | null) => void\n onClearServerCache: () => void\n}\n\nconst queryKey = (run: QueryRun) => JSON.stringify(run.query)\n\n/** Consultas ativas na página (uma por componente) e o histórico de execuções. */\nexport function QueriesPanel({\n devtools,\n capabilities,\n selected,\n onSelect,\n onHover,\n onClearServerCache\n}: Props) {\n const { store, refresh } = devtools\n const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot)\n const [view, setView] = useState<'active' | 'history'>('active')\n\n const runs: QueryRun[] =\n view === 'active' ? snapshot.instances.map((instance) => instance.last) : snapshot.history\n const instanceById = new Map(snapshot.instances.map((item) => [item.instanceId, item]))\n\n // Mesma consulta pedida por mais de um componente: o cache do endpoint segura, mas vale saber\n const sameQuery = new Map<string, number>()\n for (const { last } of snapshot.instances)\n sameQuery.set(queryKey(last), (sameQuery.get(queryKey(last)) ?? 0) + 1)\n\n const storms = snapshot.instances.filter((item) => item.storm)\n\n // Na aba \"ativas\" a seleção acompanha a instância (cada nova execução substitui a anterior)\n const current =\n (view === 'history' && selected?.runId\n ? snapshot.history.find((run) => run.runId === selected.runId)\n : selected && instanceById.get(selected.instanceId)?.last) ?? runs[0]\n\n return (\n <Box sx={{ display: 'grid', gridTemplateColumns: '360px 1fr', height: '100%', minHeight: 0 }}>\n <Box\n sx={{\n borderRight: 1,\n borderColor: 'divider',\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0\n }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n p: 1,\n borderBottom: 1,\n borderColor: 'divider'\n }}\n >\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={view}\n onChange={(_, value) => value && setView(value)}\n >\n <ToggleButton value=\"active\">Ativas ({snapshot.instances.length})</ToggleButton>\n <ToggleButton value=\"history\">Histórico ({snapshot.history.length})</ToggleButton>\n </ToggleButtonGroup>\n {view === 'history' && (\n <Button size=\"small\" onClick={store.clearHistory}>\n Limpar\n </Button>\n )}\n </Box>\n <Box sx={{ display: 'flex', gap: 0.5, p: 1, borderBottom: 1, borderColor: 'divider' }}>\n <Button size=\"small\" variant=\"outlined\" onClick={refresh}>\n Re-executar tudo\n </Button>\n <Button\n size=\"small\"\n onClick={onClearServerCache}\n title=\"Esvazia o cache em memória do endpoint e refaz as consultas\"\n >\n Limpar cache\n </Button>\n </Box>\n {!!storms.length && (\n <Alert\n severity=\"warning\"\n sx={{ m: 1, py: 0 }}\n action={\n <Button size=\"small\" color=\"inherit\" onClick={store.resetStorms}>\n OK\n </Button>\n }\n >\n Consulta em loop: {storms.map((item) => item.label).join(', ')}. Algum componente está\n recriando dimensions/measures/filtros a cada render.\n </Alert>\n )}\n <List\n dense\n disablePadding\n sx={{ overflow: 'auto', flex: 1 }}\n onMouseLeave={() => onHover(null)}\n >\n {runs.map((run) => {\n const instance = instanceById.get(run.instanceId)\n const duplicated = view === 'active' && (sameQuery.get(queryKey(run)) ?? 0) > 1\n return (\n <ListItemButton\n key={run.runId}\n selected={current?.runId === run.runId}\n onClick={() => onSelect({ instanceId: run.instanceId, runId: run.runId })}\n onMouseEnter={() => onHover(instance ? run.instanceId : null)}\n sx={{ gap: 1, alignItems: 'center' }}\n >\n <StatusDot status={run.status} />\n <Box sx={{ minWidth: 0, flex: 1 }}>\n <Typography noWrap sx={{ fontSize: 12, fontFamily: MONO }}>\n {run.label}\n </Typography>\n <Typography noWrap sx={{ fontSize: 11, color: 'text.secondary' }}>\n {run.status === 'loading' ? 'carregando…' : `${run.durationMs} ms`}\n {run.rows && ` · ${run.rows.length} linhas`}\n {run.debug?.cached && ' · cache'}\n {view === 'active' && ` · ${instance?.runs ?? 1}×`}\n </Typography>\n </Box>\n {instance?.storm && view === 'active' && (\n <Chip label=\"loop\" size=\"small\" color=\"error\" />\n )}\n {duplicated && (\n <Tooltip title=\"Outro componente faz exatamente a mesma consulta\">\n <Chip label=\"duplicada\" size=\"small\" variant=\"outlined\" />\n </Tooltip>\n )}\n {run.debug?.draft && <Chip label=\"rascunho\" size=\"small\" color=\"warning\" />}\n </ListItemButton>\n )\n })}\n {!runs.length && <Empty>Nenhuma consulta.</Empty>}\n </List>\n </Box>\n\n <Box sx={{ overflow: 'auto', p: 1.5, minWidth: 0 }}>\n {current ? (\n <RunDetail\n key={current.runId}\n run={current}\n devtools={devtools}\n capabilities={capabilities}\n mounted={instanceById.has(current.instanceId)}\n />\n ) : (\n <Empty>Selecione uma consulta.</Empty>\n )}\n </Box>\n </Box>\n )\n}\n\nfunction RunDetail({\n run,\n devtools,\n capabilities,\n mounted\n}: {\n run: QueryRun\n devtools: DashboardDevtoolsContext\n capabilities: DevtoolsCapabilities | null\n mounted: boolean\n}) {\n const { debug } = run\n const { devtools: _, ...query } = run.query\n return (\n <>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.5, flexWrap: 'wrap' }}>\n <StatusDot status={run.status} />\n <Typography sx={{ fontFamily: MONO, fontWeight: 700 }}>{run.label}</Typography>\n <Chip size=\"small\" label={STATUS_LABEL[run.status]} />\n {run.durationMs !== undefined && (\n <Chip size=\"small\" label={`total ${run.durationMs} ms`} title=\"Ida e volta no browser\" />\n )}\n {debug && (\n <Chip\n size=\"small\"\n color={debug.cached ? 'info' : 'default'}\n label={\n debug.cached\n ? `cache (banco: ${debug.durationMs} ms)`\n : `banco ${debug.durationMs} ms`\n }\n />\n )}\n {debug?.draft && <Chip size=\"small\" color=\"warning\" label=\"rodou no rascunho\" />}\n {mounted && (\n <Button size=\"small\" onClick={() => scrollToQuery(run.instanceId)}>\n Localizar na página\n </Button>\n )}\n <Typography sx={{ ml: 'auto', fontSize: 11, color: 'text.secondary' }}>\n {new Date(run.startedAt).toLocaleTimeString('pt-BR')}\n </Typography>\n </Box>\n\n {run.error && (\n <Alert severity=\"error\" sx={{ mb: 2, fontFamily: MONO, fontSize: 12 }}>\n {run.error}\n </Alert>\n )}\n\n <Section title=\"Consulta\">\n <CodeBlock code={JSON.stringify(query, null, 2)} maxHeight={180} />\n </Section>\n\n {debug && (\n <Section title=\"SQL gerado\">\n <CodeBlock sql code={inlineParams(debug.sql, debug.params)} />\n {!!debug.params.length && (\n <Typography sx={{ fontSize: 11, color: 'text.secondary', mt: 0.5, fontFamily: MONO }}>\n params: {JSON.stringify(debug.params)}\n </Typography>\n )}\n </Section>\n )}\n {!debug && run.status === 'success' && (\n <Alert severity=\"info\" sx={{ mb: 2 }}>\n O servidor não devolveu debug. Confira se o endpoint chama{' '}\n <code>runQuery(..., {'{ devtools: true }'})</code> em desenvolvimento.\n </Alert>\n )}\n\n {debug && <RunTools run={run} devtools={devtools} capabilities={capabilities} />}\n\n {run.rows && (\n <Section title={`Resultado (${run.rows.length} linhas)`}>\n <ResultTable rows={run.rows} />\n </Section>\n )}\n </>\n )\n}\n\ntype ToolState<T> = { loading: boolean; error?: string; data?: T }\n\nfunction useTool<T>() {\n const [state, setState] = useState<ToolState<T> | null>(null)\n const run = async (load: () => Promise<T>) => {\n setState({ loading: true })\n try {\n setState({ loading: false, data: await load() })\n } catch (error) {\n setState({ loading: false, error: errorMessage(error) })\n }\n }\n return [state, run] as const\n}\n\nfunction ToolResult<T>({\n state,\n children\n}: {\n state: ToolState<T> | null\n children: (data: T) => ReactNode\n}) {\n if (!state) return null\n if (state.loading) return <Typography sx={{ fontSize: 12 }}>Executando…</Typography>\n if (state.error)\n return (\n <Alert severity=\"error\" sx={{ fontFamily: MONO, fontSize: 12 }}>\n {state.error}\n </Alert>\n )\n return state.data === undefined ? null : children(state.data)\n}\n\n/** EXPLAIN, perfil por join, comparação com o modelo registrado e snapshot da consulta. */\nfunction RunTools({\n run,\n devtools,\n capabilities\n}: {\n run: QueryRun\n devtools: DashboardDevtoolsContext\n capabilities: DevtoolsCapabilities | null\n}) {\n const { fetcher } = useDashboard()\n const query = run.query\n const [explain, runExplain] = useTool<DashboardRow[]>()\n const [profile, runProfile] = useTool<ProfileStep[]>()\n const [compare, runCompare] = useTool<RowDiff[]>()\n const [snapshot, runSnapshot] = useTool<string>()\n const [snapshotName, setSnapshotName] = useState('')\n const [overwrite, setOverwrite] = useState(false)\n\n const explainQuery = () =>\n runExplain(async () => {\n const result = await fetcher({ ...query, devtools: { explain: true } })\n return result.devtools?.explain ?? []\n })\n const profileQuery = () =>\n runProfile(async () => {\n const result = await fetcher({ ...query, devtools: { profile: true } })\n return result.devtools?.profile ?? []\n })\n const compareQuery = () =>\n runCompare(async () => {\n const registered = await devtools.rawFetcher(query)\n return diffRows(registered.rows, run.rows ?? [], query)\n })\n const saveSnapshot = () =>\n runSnapshot(async () => {\n const result = await devtools.rawFetcher({\n ...query,\n devtools: { snapshot: { name: snapshotName, overwrite } }\n })\n return result.devtools?.snapshot?.path ?? ''\n })\n\n const maxProfile = Math.max(1, ...(profile?.data ?? []).map((step) => step.durationMs))\n\n return (\n <Section\n title=\"Ferramentas\"\n actions={\n <>\n <Button size=\"small\" variant=\"outlined\" onClick={explainQuery}>\n EXPLAIN\n </Button>\n <Button\n size=\"small\"\n variant=\"outlined\"\n onClick={profileQuery}\n title=\"Mede a agregação de cada fato isoladamente (sem cache)\"\n >\n Perfil por join\n </Button>\n {devtools.draft && run.rows && (\n <Button size=\"small\" variant=\"outlined\" color=\"warning\" onClick={compareQuery}>\n Comparar com o registrado\n </Button>\n )}\n </>\n }\n >\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <ToolResult state={explain}>\n {(rows) => <ResultTable rows={rows} maxHeight={240} />}\n </ToolResult>\n\n <ToolResult state={profile}>\n {(steps) => (\n <Box sx={{ display: 'grid', gridTemplateColumns: '160px 1fr 90px 90px', gap: 0.5 }}>\n {steps.map((step) => (\n <Box key={step.name} sx={{ display: 'contents', fontFamily: MONO, fontSize: 12 }}>\n <Box sx={{ fontFamily: MONO }}>{step.name}</Box>\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <Box\n sx={{\n height: 10,\n borderRadius: 1,\n width: `${(step.durationMs / maxProfile) * 100}%`,\n minWidth: 2,\n bgcolor: step.name === 'consulta' ? 'primary.main' : 'info.main'\n }}\n />\n </Box>\n <Box sx={{ textAlign: 'right', fontFamily: MONO }}>{step.durationMs} ms</Box>\n <Box sx={{ textAlign: 'right', fontFamily: MONO, color: 'text.secondary' }}>\n {step.rows ?? ''} {step.name === 'consulta' ? 'linhas' : 'chaves'}\n </Box>\n </Box>\n ))}\n </Box>\n )}\n </ToolResult>\n\n <ToolResult state={compare}>\n {(diffs) => (\n <RowDiffTable diffs={diffs} expectedLabel=\"registrado\" actualLabel=\"rascunho\" />\n )}\n </ToolResult>\n\n {capabilities?.snapshots && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>\n <TextField\n size=\"small\"\n label=\"Nome do snapshot\"\n placeholder=\"custo-mes-2024\"\n value={snapshotName}\n onChange={(e) => setSnapshotName(e.target.value)}\n sx={{ width: 240, '& input': { fontFamily: MONO, fontSize: 12 } }}\n />\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n checked={overwrite}\n onChange={(e) => setOverwrite(e.target.checked)}\n />\n }\n label=\"Sobrescrever\"\n />\n <Tooltip title=\"Grava o resultado do modelo REGISTRADO (não o rascunho) como referência para os testes de regressão. Prefira períodos fechados: dado que ainda muda quebra o teste.\">\n <span>\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={!snapshotName}\n onClick={saveSnapshot}\n >\n Salvar snapshot\n </Button>\n </span>\n </Tooltip>\n <ToolResult state={snapshot}>\n {(path) => (\n <Typography sx={{ fontSize: 12, color: 'success.main', fontFamily: MONO }}>\n Salvo em {path}\n </Typography>\n )}\n </ToolResult>\n </Box>\n )}\n </Box>\n </Section>\n )\n}\n","import { Alert, Box, Button, Chip, Collapse, Typography } from '@mui/material'\nimport { useEffect, useState } from 'react'\nimport type { DashboardDevtoolsContext } from '../client/DashboardProvider'\nimport { useDashboard } from '../client/DashboardProvider'\nimport { diffRows, type RowDiff } from '../compare'\nimport type { DashboardQuery, DashboardSnapshot, DevtoolsCapabilities } from '../types'\nimport { errorMessage } from './store'\nimport { Empty, MONO, RowDiffTable, Section } from './ui'\n\ntype CheckItem = { id: string; label: string; query: DashboardQuery }\n\ntype Check = {\n id: string\n label: string\n query: DashboardQuery\n status: 'loading' | 'done' | 'error'\n diffs?: RowDiff[]\n rows?: number\n error?: string\n}\n\ntype Props = {\n devtools: DashboardDevtoolsContext\n capabilities: DevtoolsCapabilities | null\n}\n\nconst stripQuery = ({ model, dimensions, measures, filters }: DashboardQuery): DashboardQuery => ({\n model,\n dimensions,\n measures,\n filters\n})\n\n/** Executa as conferências uma a uma, atualizando a lista conforme terminam. */\nfunction useChecks() {\n const [checks, setChecks] = useState<Check[]>([])\n const run = async (\n items: CheckItem[],\n compare: (item: CheckItem) => Promise<{ diffs: RowDiff[]; rows: number }>\n ) => {\n setChecks(items.map((item) => ({ ...item, status: 'loading' })))\n for (const item of items) {\n let patch: Partial<Check>\n try {\n patch = { status: 'done', ...(await compare(item)) }\n } catch (error) {\n patch = { status: 'error', error: errorMessage(error) }\n }\n setChecks((current) =>\n current.map((check) => (check.id === item.id ? { ...check, ...patch } : check))\n )\n }\n }\n return [checks, run] as const\n}\n\n/**\n * Proteção dos números: (1) rascunho x modelo registrado em todas as consultas da página e\n * (2) snapshots salvos x modelo em vigor (o mesmo que o teste `tests/dashboard` faz no CI).\n */\nexport function RegressionPanel({ devtools, capabilities }: Props) {\n const { fetcher, model } = useDashboard()\n const [pageChecks, runPageChecks] = useChecks()\n const [snapshotChecks, runSnapshotChecks] = useChecks()\n const [snapshots, setSnapshots] = useState<DashboardSnapshot[] | null>(null)\n const [snapshotsError, setSnapshotsError] = useState<string | null>(null)\n\n const loadSnapshots = () =>\n devtools\n .rawFetcher({ model, devtools: { snapshots: true } })\n .then((result) => {\n setSnapshots(result.devtools?.snapshots ?? [])\n setSnapshotsError(null)\n })\n .catch((error) => setSnapshotsError(errorMessage(error)))\n\n useEffect(() => {\n if (capabilities?.snapshots) loadSnapshots()\n }, [capabilities?.snapshots])\n\n const comparePage = () => {\n // Uma conferência por consulta distinta (componentes com a mesma consulta contam uma vez)\n const unique = new Map<string, CheckItem>()\n for (const { last, label } of devtools.store.getSnapshot().instances) {\n const query = stripQuery(last.query)\n const id = JSON.stringify(query)\n if (!unique.has(id)) unique.set(id, { id, label, query })\n }\n runPageChecks([...unique.values()], async ({ query }) => {\n const [registered, draft] = await Promise.all([devtools.rawFetcher(query), fetcher(query)])\n return { diffs: diffRows(registered.rows, draft.rows, query), rows: draft.rows.length }\n })\n }\n\n const verifySnapshots = () => {\n const byName = new Map((snapshots ?? []).map((snapshot) => [snapshot.name, snapshot]))\n runSnapshotChecks(\n [...byName.values()].map((snapshot) => ({\n id: snapshot.name,\n label: snapshot.name,\n query: snapshot.query as DashboardQuery\n })),\n async ({ id, query }) => {\n const result = await fetcher(query)\n const expected = byName.get(id)?.rows ?? []\n return { diffs: diffRows(expected, result.rows, query), rows: result.rows.length }\n }\n )\n }\n\n return (\n <Box sx={{ p: 1.5, overflow: 'auto', height: '100%' }}>\n <Section\n title=\"Rascunho × modelo registrado\"\n actions={\n <Button size=\"small\" variant=\"contained\" disabled={!devtools.draft} onClick={comparePage}>\n Comparar consultas da página\n </Button>\n }\n >\n {!devtools.draft ? (\n <Typography sx={{ fontSize: 12, color: 'text.secondary' }}>\n Aplique um rascunho na aba Modelo para comparar: cada consulta da página roda nos dois\n modelos e as linhas são casadas pelas dimensões.\n </Typography>\n ) : (\n <CheckList checks={pageChecks} expectedLabel=\"registrado\" actualLabel=\"rascunho\" />\n )}\n </Section>\n\n <Section\n title=\"Snapshots de regressão\"\n actions={\n capabilities?.snapshots && (\n <>\n <Button size=\"small\" onClick={loadSnapshots}>\n Recarregar\n </Button>\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={!snapshots?.length}\n onClick={verifySnapshots}\n >\n Verificar todos {devtools.draft ? '(no rascunho)' : ''}\n </Button>\n </>\n )\n }\n >\n {!capabilities?.snapshots ? (\n <Alert severity=\"info\">\n O endpoint não configurou <code>snapshotsDir</code> no <code>runQuery</code>.\n </Alert>\n ) : snapshotsError ? (\n <Alert severity=\"error\">{snapshotsError}</Alert>\n ) : !snapshots ? (\n <Typography sx={{ fontSize: 12 }}>Carregando…</Typography>\n ) : !snapshots.length ? (\n <Empty>\n Nenhum snapshot. Salve um pela aba Consultas → Ferramentas → \"Salvar snapshot\".\n </Empty>\n ) : (\n <>\n <Typography sx={{ fontSize: 12, color: 'text.secondary', mb: 1 }}>\n {snapshots.length} snapshot(s). Os mesmos rodam nos testes do app (\n <code>tests/dashboard</code>).\n </Typography>\n {snapshotChecks.length ? (\n <CheckList checks={snapshotChecks} expectedLabel=\"snapshot\" actualLabel=\"agora\" />\n ) : (\n <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>\n {snapshots.map((snapshot) => (\n <Chip\n key={snapshot.name}\n size=\"small\"\n label={`${snapshot.name} · ${snapshot.rows.length} linhas`}\n title={`${JSON.stringify(snapshot.query)}\\n${snapshot.createdAt}`}\n sx={{ fontFamily: MONO }}\n />\n ))}\n </Box>\n )}\n </>\n )}\n </Section>\n </Box>\n )\n}\n\nfunction CheckList({\n checks,\n expectedLabel,\n actualLabel\n}: {\n checks: Check[]\n expectedLabel: string\n actualLabel: string\n}) {\n const [open, setOpen] = useState<string | null>(null)\n if (!checks.length) return null\n const failed = checks.filter((check) => check.status === 'error' || check.diffs?.length).length\n const done = checks.every((check) => check.status !== 'loading')\n return (\n <Box>\n {done && (\n <Alert severity={failed ? 'warning' : 'success'} sx={{ mb: 1 }}>\n {failed ? `${failed} de ${checks.length} com diferença ou erro.` : 'Tudo igual.'}\n </Alert>\n )}\n {checks.map((check) => {\n const differs = !!check.diffs?.length\n return (\n <Box key={check.id} sx={{ borderBottom: 1, borderColor: 'divider', py: 0.5 }}>\n <Box\n sx={{ display: 'flex', alignItems: 'center', gap: 1, cursor: 'pointer' }}\n onClick={() => setOpen(open === check.id ? null : check.id)}\n >\n <Typography sx={{ fontFamily: MONO, fontSize: 12, flex: 1 }} noWrap>\n {check.label}\n </Typography>\n {check.status === 'loading' && <Chip size=\"small\" label=\"executando…\" />}\n {check.status === 'error' && <Chip size=\"small\" color=\"error\" label=\"erro\" />}\n {check.status === 'done' && (\n <Chip\n size=\"small\"\n color={differs ? 'warning' : 'success'}\n label={\n differs\n ? `${check.diffs?.length} linha(s) diferente(s)`\n : `igual · ${check.rows} linhas`\n }\n />\n )}\n </Box>\n <Collapse in={open === check.id}>\n <Box sx={{ pt: 1 }}>\n {check.error && (\n <Alert severity=\"error\" sx={{ fontFamily: MONO, fontSize: 12 }}>\n {check.error}\n </Alert>\n )}\n {check.diffs && (\n <RowDiffTable\n diffs={check.diffs}\n expectedLabel={expectedLabel}\n actualLabel={actualLabel}\n />\n )}\n </Box>\n </Collapse>\n </Box>\n )\n })}\n </Box>\n )\n}\n","import {\n Alert,\n Box,\n Chip,\n CircularProgress,\n createTheme,\n IconButton,\n Paper,\n Portal,\n Tab,\n Tabs,\n ThemeProvider,\n Tooltip,\n Typography\n} from '@mui/material'\nimport {\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore\n} from 'react'\nimport { useDashboard } from '../client/DashboardProvider'\nimport { ModelDictionary } from '../client/ModelDictionary'\nimport type { ModelDef } from '../model'\nimport type { DevtoolsCapabilities, SchemaTable } from '../types'\nimport { FiltersPanel } from './FiltersPanel'\nimport { DEVTOOLS_ATTRIBUTE, findQueryElement, HighlightOverlay, useInspectMode } from './Inspector'\nimport { LayoutPanel } from './LayoutPanel'\nimport { LAYOUT_ITEM_ATTRIBUTE } from './layoutStore'\nimport { ModelPanel } from './ModelPanel'\nimport { PlaygroundPanel, type PlaygroundSelection } from './PlaygroundPanel'\nimport { QueriesPanel, type QuerySelection } from './QueriesPanel'\nimport { RegressionPanel } from './RegressionPanel'\nimport { errorMessage } from './store'\nimport { MONO } from './ui'\n\n/**\n * Devtools do `@bluemarble/bi` (no estilo do TanStack Query Devtools): um botão flutuante que abre um\n * painel com as consultas da página, o modelo editável, um playground, regressão, dicionário e\n * filtros. Montado pelo próprio `DashboardProvider` em desenvolvimento.\n *\n * Dois modos: fixado na parte de baixo da tela ou flutuante (janela que se arrasta pelo cabeçalho e\n * redimensiona pelo canto). Fixado (embaixo, à esquerda ou à direita), o painel ocupa espaço: a\n * página encolhe para não ficar escondida atrás dele; só o modo flutuante sobrepõe a página.\n * Atalhos: Alt+Shift+B abre/fecha o painel, Alt+Shift+F alterna entre fixado e flutuante,\n * Alt+Shift+I liga o inspetor, Esc sai do inspetor.\n */\n\n// Abaixo do Modal do MUI (1300) para os menus dos Selects do painel abrirem por cima dele\nconst Z_INDEX = 1250\nconst MIN_HEIGHT = 180\nconst MIN_SIDE_WIDTH = 360\nconst MIN_FLOAT_WIDTH = 420\nconst MIN_FLOAT_HEIGHT = 220\nconst FLOAT_MARGIN = 16\n\nconst theme = createTheme({\n palette: { mode: 'dark', primary: { main: '#F58220' }, background: { paper: '#1b1e23' } },\n typography: { fontSize: 12 },\n components: {\n MuiTableCell: { styleOverrides: { root: { fontSize: 12, padding: '4px 8px' } } },\n MuiButton: {\n defaultProps: { disableElevation: true },\n styleOverrides: { root: { textTransform: 'none' } }\n },\n MuiTab: { styleOverrides: { root: { textTransform: 'none', minHeight: 40 } } }\n }\n})\n\ntype TabKey =\n | 'queries'\n | 'model'\n | 'layout'\n | 'playground'\n | 'regression'\n | 'dictionary'\n | 'filters'\n\nconst STORAGE_KEY = 'bm-dashboard-devtools:ui'\n\ntype DockSide = 'bottom' | 'left' | 'right'\n\nconst DOCK_SIDES: { side: DockSide; icon: string; label: string }[] = [\n { side: 'left', icon: '◧', label: 'Fixar à esquerda' },\n { side: 'bottom', icon: '⬓', label: 'Fixar embaixo' },\n { side: 'right', icon: '◨', label: 'Fixar à direita' }\n]\n\ntype FloatRect = { x: number; y: number; width: number; height: number }\n\ntype UiState = {\n open: boolean\n /** Fixado numa borda (ocupa espaço na página) ou `floating` (janela solta, por cima). */\n mode: DockSide | 'floating'\n /** Última borda usada: para onde volta ao sair do flutuante. */\n dock: DockSide\n /** Altura fixado embaixo. */\n height: number\n /** Largura fixado na lateral. */\n width: number\n /** Posição e tamanho no modo flutuante. */\n float: FloatRect\n tab: TabKey\n}\n\n/** Mantém a janela flutuante inteira dentro da tela (encolhe se a tela ficou menor). */\nfunction clampFloat(rect: FloatRect): FloatRect {\n const maxWidth = Math.max(MIN_FLOAT_WIDTH, window.innerWidth - FLOAT_MARGIN * 2)\n const maxHeight = Math.max(MIN_FLOAT_HEIGHT, window.innerHeight - FLOAT_MARGIN * 2)\n const width = Math.min(Math.max(rect.width, MIN_FLOAT_WIDTH), maxWidth)\n const height = Math.min(Math.max(rect.height, MIN_FLOAT_HEIGHT), maxHeight)\n return {\n width,\n height,\n x: Math.min(Math.max(rect.x, 0), Math.max(0, window.innerWidth - width)),\n y: Math.min(Math.max(rect.y, 0), Math.max(0, window.innerHeight - height))\n }\n}\n\nfunction loadUi(): UiState {\n const width = Math.min(960, window.innerWidth - FLOAT_MARGIN * 2)\n const height = Math.min(560, window.innerHeight - FLOAT_MARGIN * 2)\n const fallback: UiState = {\n open: false,\n mode: 'bottom',\n dock: 'bottom',\n width: 520,\n height: 380,\n // Canto inferior direito, longe do botão (que fica à esquerda)\n float: {\n width,\n height,\n x: window.innerWidth - width - FLOAT_MARGIN,\n y: window.innerHeight - height - FLOAT_MARGIN\n },\n tab: 'queries'\n }\n try {\n const saved: UiState = {\n ...fallback,\n ...JSON.parse(localStorage.getItem(STORAGE_KEY) ?? '{}')\n }\n // Versão anterior gravava `docked` (só existia embaixo)\n if (!['bottom', 'left', 'right', 'floating'].includes(saved.mode)) saved.mode = 'bottom'\n if (!['bottom', 'left', 'right'].includes(saved.dock)) saved.dock = 'bottom'\n return { ...saved, float: clampFloat({ ...fallback.float, ...saved.float }) }\n } catch {\n return fallback\n }\n}\n\n/**\n * Encolhe a página para o painel fixado caber ao lado dela. A raiz do Next (`#__next`) vira uma caixa\n * do tamanho da tela menos o painel, com rolagem própria; o `transform` faz os elementos `fixed` do\n * app (sidebar, appbar) ficarem dentro dessa caixa em vez de presos à janela — só um padding no\n * `body` deixaria eles atrás do painel. Sem `#__next` (App Router), cai no padding do `body`.\n */\nfunction reservePageSpace(side: DockSide, initialSize: number) {\n const root = document.getElementById('__next')\n if (!root) {\n const property = (\n { bottom: 'paddingBottom', left: 'paddingLeft', right: 'paddingRight' } as const\n )[side]\n const previous = document.body.style[property]\n const resize = (size: number) => {\n document.body.style[property] = `${size}px`\n }\n resize(initialSize)\n return {\n resize,\n release: () => {\n document.body.style[property] = previous\n }\n }\n }\n const previous = root.getAttribute('style')\n const scroll = { x: window.scrollX, y: window.scrollY }\n Object.assign(root.style, {\n position: 'fixed',\n inset: '0',\n overflow: 'auto',\n transform: 'translateZ(0)'\n })\n const resize = (size: number) => {\n root.style[side] = `${size}px`\n }\n resize(initialSize)\n // A rolagem passa da janela para a caixa: mantém onde a pessoa estava\n root.scrollTo(scroll.x, scroll.y)\n return {\n resize,\n release: () => {\n const inner = { x: root.scrollLeft, y: root.scrollTop }\n if (previous === null) root.removeAttribute('style')\n else root.setAttribute('style', previous)\n window.scrollTo(inner.x, inner.y)\n }\n }\n}\n\n/** Acompanha o mouse até soltar o botão, sem selecionar texto da página no caminho. */\nfunction trackMouse(event: ReactMouseEvent, onMove: (dx: number, dy: number) => void) {\n event.preventDefault()\n const startX = event.clientX\n const startY = event.clientY\n const previousSelect = document.body.style.userSelect\n document.body.style.userSelect = 'none'\n const move = (moveEvent: MouseEvent) =>\n onMove(moveEvent.clientX - startX, moveEvent.clientY - startY)\n const up = () => {\n document.body.style.userSelect = previousSelect\n window.removeEventListener('mousemove', move)\n window.removeEventListener('mouseup', up)\n }\n window.addEventListener('mousemove', move)\n window.addEventListener('mouseup', up)\n}\n\nconst devtoolsMarker = { [DEVTOOLS_ATTRIBUTE]: '' }\n\nexport default function DashboardDevtools() {\n const { model, fetcher, devtools } = useDashboard()\n const [ui, setUi] = useState(loadUi)\n const [original, setOriginal] = useState<ModelDef | null>(null)\n const [capabilities, setCapabilities] = useState<DevtoolsCapabilities | null>(null)\n const [describeError, setDescribeError] = useState<string | null>(null)\n const [tables, setTables] = useState<SchemaTable[] | null>(null)\n const [playground, setPlayground] = useState<PlaygroundSelection>({\n dimensions: [],\n measures: []\n })\n const [selected, setSelected] = useState<QuerySelection | null>(null)\n const [pickedItem, setPickedItem] = useState<{ item: string } | null>(null)\n const [hovered, setHovered] = useState<string | null>(null)\n const [inspecting, setInspecting] = useState(false)\n\n const store = devtools?.store\n const snapshot = useSyncExternalStore(\n store?.subscribe ?? (() => () => {}),\n () => store?.getSnapshot(),\n () => store?.getSnapshot()\n )\n const instances = snapshot?.instances ?? []\n\n useEffect(() => {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(ui))\n } catch {}\n }, [ui])\n\n const loadModel = useCallback(\n (clearCache = false) =>\n fetcher({ model, devtools: { describe: true, clearCache } })\n .then((result) => {\n setOriginal(result.devtools?.model ?? null)\n setCapabilities(result.devtools?.capabilities ?? null)\n setDescribeError(result.devtools?.model ? null : 'O endpoint não devolveu o modelo.')\n })\n .catch((error) => setDescribeError(errorMessage(error))),\n [fetcher, model]\n )\n\n useEffect(() => {\n if (ui.open) loadModel()\n }, [ui.open, loadModel])\n\n // Schema do banco só quando alguém vai editar SQL\n useEffect(() => {\n if (!ui.open || ui.tab !== 'model' || tables) return\n fetcher({ model, devtools: { schema: true } })\n .then((result) => setTables(result.devtools?.schema ?? []))\n .catch(() => setTables([]))\n }, [ui.open, ui.tab, tables, fetcher, model])\n\n const setTab = (tab: TabKey) => setUi((current) => ({ ...current, open: true, tab }))\n\n // Na aba Layout, o inspetor escolhe o gráfico/filtro para editar; nas outras, a consulta\n const layoutTab = ui.tab === 'layout'\n const pick = useCallback(\n (instanceId: string) => {\n setInspecting(false)\n const item = findQueryElement(instanceId)\n ?.closest(`[${LAYOUT_ITEM_ATTRIBUTE}]`)\n ?.getAttribute(LAYOUT_ITEM_ATTRIBUTE)\n if (layoutTab && item) {\n setPickedItem({ item })\n return\n }\n setSelected({ instanceId })\n setUi((current) => ({ ...current, open: true, tab: 'queries' }))\n },\n [layoutTab]\n )\n useInspectMode({ active: inspecting, onHover: setHovered, onPick: pick })\n\n useEffect(() => {\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && inspecting) setInspecting(false)\n if (!event.altKey || !event.shiftKey) return\n if (event.code === 'KeyB') {\n event.preventDefault()\n setUi((current) => ({ ...current, open: !current.open }))\n } else if (event.code === 'KeyF') {\n event.preventDefault()\n setUi((current) => ({\n ...current,\n open: true,\n mode: current.mode === 'floating' ? current.dock : 'floating'\n }))\n } else if (event.code === 'KeyI') {\n event.preventDefault()\n setInspecting((value) => !value)\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [inspecting])\n\n // Fixado, o painel ocupa espaço: a página encolhe em vez de ficar escondida atrás dele.\n // Flutuante (ou fechado), a página volta ao normal.\n const reserved = ui.open && ui.mode !== 'floating' ? ui.mode : null\n const reservedSize = reserved === 'bottom' ? ui.height : ui.width\n const reservation = useRef<ReturnType<typeof reservePageSpace> | null>(null)\n const reservedSizeRef = useRef(reservedSize)\n reservedSizeRef.current = reservedSize\n useEffect(() => {\n if (!reserved) return\n const handle = reservePageSpace(reserved, reservedSizeRef.current)\n reservation.current = handle\n return () => {\n reservation.current = null\n handle.release()\n }\n }, [reserved])\n // Arrastar a borda só ajusta o tamanho, sem desfazer e refazer tudo\n useEffect(() => reservation.current?.resize(reservedSize), [reservedSize])\n\n // Tela redimensionada: a janela flutuante não pode ficar fora dela\n useEffect(() => {\n const onResize = () => setUi((current) => ({ ...current, float: clampFloat(current.float) }))\n window.addEventListener('resize', onResize)\n return () => window.removeEventListener('resize', onResize)\n }, [])\n\n if (!devtools || !store) return null\n\n const floating = ui.mode === 'floating'\n const side = ui.mode === 'left' || ui.mode === 'right' ? ui.mode : null\n\n const startDockResize = (event: ReactMouseEvent) => {\n const { height, width } = ui\n trackMouse(event, (dx, dy) =>\n setUi((current) =>\n current.mode === 'bottom'\n ? {\n ...current,\n height: Math.min(Math.max(height - dy, MIN_HEIGHT), window.innerHeight - 40)\n }\n : {\n ...current,\n width: Math.min(\n Math.max(width + (current.mode === 'left' ? dx : -dx), MIN_SIDE_WIDTH),\n window.innerWidth - 80\n )\n }\n )\n )\n }\n\n const startFloatResize = (event: ReactMouseEvent) => {\n const start = ui.float\n trackMouse(event, (dx, dy) =>\n setUi((current) => ({\n ...current,\n float: clampFloat({ ...start, width: start.width + dx, height: start.height + dy })\n }))\n )\n }\n\n // Arrastar pelo cabeçalho; botões, abas e campos continuam clicáveis\n const startDrag = (event: ReactMouseEvent) => {\n if (!floating || event.button !== 0) return\n if ((event.target as Element).closest('button, [role=\"tab\"], input, a')) return\n const start = ui.float\n trackMouse(event, (dx, dy) =>\n setUi((current) => ({\n ...current,\n float: clampFloat({ ...start, x: start.x + dx, y: start.y + dy })\n }))\n )\n }\n\n const toggleMode = () =>\n setUi((current) => ({\n ...current,\n mode: current.mode === 'floating' ? current.dock : 'floating'\n }))\n const dockTo = (dock: DockSide) => setUi((current) => ({ ...current, mode: dock, dock }))\n\n const clearServerCache = () => loadModel(true).then(devtools.refresh)\n\n const loading = instances.filter((item) => item.last.status === 'loading').length\n const errors = instances.filter((item) => item.last.status === 'error').length\n const storms = instances.filter((item) => item.storm).length\n const hoveredLabel = instances.find((item) => item.instanceId === hovered)?.label\n\n const needsModel = (content: (registered: ModelDef) => ReactNode) =>\n describeError ? (\n <Alert severity=\"error\" sx={{ m: 1.5 }}>\n Não foi possível carregar o modelo: {describeError}. O endpoint precisa chamar{' '}\n <code>runQuery(..., {'{ devtools: true }'})</code> em desenvolvimento.\n </Alert>\n ) : !original ? (\n <Box sx={{ p: 3, display: 'flex', justifyContent: 'center' }}>\n <CircularProgress size={20} />\n </Box>\n ) : (\n content(original)\n )\n\n return (\n <Portal>\n <ThemeProvider theme={theme}>\n <HighlightOverlay instanceId={hovered} label={hoveredLabel} zIndex={Z_INDEX + 1} />\n\n {ui.open ? (\n <Paper\n {...devtoolsMarker}\n square={!floating}\n elevation={floating ? 16 : 12}\n sx={{\n position: 'fixed',\n zIndex: Z_INDEX,\n display: 'flex',\n flexDirection: 'column',\n color: 'text.primary',\n overflow: 'hidden',\n ...(floating\n ? {\n left: ui.float.x,\n top: ui.float.y,\n width: ui.float.width,\n height: ui.float.height,\n border: '1px solid #F58220',\n borderRadius: 1.5\n }\n : side\n ? {\n top: 0,\n bottom: 0,\n [side]: 0,\n width: ui.width,\n [side === 'left' ? 'borderRight' : 'borderLeft']: '2px solid #F58220'\n }\n : {\n left: 0,\n right: 0,\n bottom: 0,\n height: ui.height,\n borderTop: '2px solid #F58220'\n })\n }}\n >\n {floating ? (\n <Box\n onMouseDown={startFloatResize}\n title=\"Redimensionar\"\n sx={{\n position: 'absolute',\n right: 0,\n bottom: 0,\n width: 16,\n height: 16,\n zIndex: 1,\n cursor: 'nwse-resize',\n // Riscos diagonais no canto, como o \"grip\" de janela\n background:\n 'linear-gradient(135deg, transparent 0 55%, #F58220 55% 62%, transparent 62% 72%, #F58220 72% 79%, transparent 79%)'\n }}\n />\n ) : (\n <Box\n onMouseDown={startDockResize}\n sx={\n side\n ? {\n position: 'absolute',\n top: 0,\n bottom: 0,\n [side === 'left' ? 'right' : 'left']: -3,\n width: 8,\n zIndex: 1,\n cursor: 'ew-resize'\n }\n : {\n position: 'absolute',\n top: -5,\n left: 0,\n right: 0,\n height: 8,\n cursor: 'ns-resize'\n }\n }\n />\n )}\n <Box\n onMouseDown={startDrag}\n onDoubleClick={(event) => {\n if (floating && !(event.target as Element).closest('button, [role=\"tab\"]'))\n toggleMode()\n }}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n px: 1.5,\n borderBottom: 1,\n borderColor: 'divider',\n cursor: floating ? 'move' : undefined,\n // Na lateral não cabe tudo numa linha: as abas descem para a linha de baixo\n ...(side && { flexWrap: 'wrap', columnGap: 1, pt: 0.5 })\n }}\n >\n <Typography sx={{ fontWeight: 800, color: 'primary.main', whiteSpace: 'nowrap' }}>\n ◆ BI Devtools\n </Typography>\n <Chip size=\"small\" label={model} sx={{ fontFamily: MONO }} />\n <Tabs\n value={ui.tab}\n onChange={(_, tab: TabKey) => setTab(tab)}\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n sx={{ minHeight: 40, ...(side && { order: 1, width: '100%' }) }}\n >\n <Tab\n value=\"queries\"\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75 }}>\n Consultas ({instances.length}){!!loading && <CircularProgress size={10} />}\n {!!(errors || storms) && (\n <Chip\n size=\"small\"\n color=\"error\"\n label={errors + storms}\n sx={{ height: 16 }}\n />\n )}\n </Box>\n }\n />\n <Tab value=\"model\" label=\"Modelo\" />\n <Tab value=\"layout\" label=\"Layout\" />\n <Tab value=\"playground\" label=\"Playground\" />\n <Tab value=\"regression\" label=\"Regressão\" />\n <Tab value=\"dictionary\" label=\"Dicionário\" />\n <Tab value=\"filters\" label=\"Filtros\" />\n </Tabs>\n {devtools.draft && <Chip size=\"small\" color=\"warning\" label=\"rascunho aplicado\" />}\n <Box sx={{ ml: 'auto', display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <Tooltip title=\"Inspecionar componente (Alt+Shift+I)\">\n <IconButton\n size=\"small\"\n color={inspecting ? 'primary' : 'default'}\n onClick={() => setInspecting((value) => !value)}\n aria-label=\"Inspecionar componente\"\n >\n ⌖\n </IconButton>\n </Tooltip>\n {DOCK_SIDES.map(({ side: dock, icon, label }) => (\n <Tooltip key={dock} title={`${label} (ocupa espaço na página)`}>\n <IconButton\n size=\"small\"\n color={ui.mode === dock ? 'primary' : 'default'}\n onClick={() => dockTo(dock)}\n aria-label={label}\n >\n {icon}\n </IconButton>\n </Tooltip>\n ))}\n <Tooltip title=\"Janela flutuante, por cima da página (Alt+Shift+F) · arraste pelo cabeçalho\">\n <IconButton\n size=\"small\"\n color={floating ? 'primary' : 'default'}\n onClick={toggleMode}\n aria-label=\"Devtools flutuante\"\n >\n ⧉\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Fechar (Alt+Shift+B)\">\n <IconButton\n size=\"small\"\n onClick={() => setUi((current) => ({ ...current, open: false }))}\n aria-label=\"Fechar devtools\"\n >\n ✕\n </IconButton>\n </Tooltip>\n </Box>\n </Box>\n\n <Box sx={{ flex: 1, minHeight: 0 }}>\n {ui.tab === 'queries' && (\n <QueriesPanel\n devtools={devtools}\n capabilities={capabilities}\n selected={selected}\n onSelect={setSelected}\n onHover={setHovered}\n onClearServerCache={clearServerCache}\n />\n )}\n {ui.tab === 'model' &&\n needsModel((registered) => (\n <ModelPanel\n devtools={devtools}\n original={registered}\n capabilities={capabilities}\n tables={tables ?? []}\n onTry={(selection) => {\n setPlayground(selection)\n setTab('playground')\n }}\n // O Next recompila a rota ao ver o arquivo novo; espera um pouco antes de reler\n onSaved={() => setTimeout(() => loadModel(), 1000)}\n />\n ))}\n {ui.tab === 'layout' &&\n needsModel((registered) => (\n <LayoutPanel\n devtools={devtools}\n model={devtools.draft ?? registered}\n capabilities={capabilities}\n picked={pickedItem}\n onHover={setHovered}\n />\n ))}\n {ui.tab === 'playground' &&\n needsModel((registered) => (\n <PlaygroundPanel\n model={devtools.draft ?? registered}\n selection={playground}\n onSelectionChange={setPlayground}\n />\n ))}\n {ui.tab === 'regression' && (\n <RegressionPanel devtools={devtools} capabilities={capabilities} />\n )}\n {ui.tab === 'dictionary' && (\n <Box sx={{ p: 1.5, overflow: 'auto', height: '100%' }}>\n <Typography sx={{ fontSize: 12, color: 'text.secondary', mb: 1.5 }}>\n O mesmo <code>{'<ModelDictionary />'}</code> pode ir numa página do dashboard\n como documentação para quem usa. Edite rótulos e descrições na aba Modelo.\n </Typography>\n <ModelDictionary />\n </Box>\n )}\n {ui.tab === 'filters' && <FiltersPanel devtools={devtools} />}\n </Box>\n </Paper>\n ) : (\n <ToggleButton\n draft={!!devtools.draft}\n loading={loading}\n problems={errors + storms}\n inspecting={inspecting}\n onOpen={() => setUi((current) => ({ ...current, open: true }))}\n />\n )}\n\n {inspecting && (\n <Box\n {...devtoolsMarker}\n sx={{\n position: 'fixed',\n top: 12,\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: Z_INDEX + 2,\n bgcolor: '#1b1e23',\n color: '#fff',\n border: '1px solid #F58220',\n borderRadius: 1,\n px: 1.5,\n py: 0.75,\n fontSize: 12,\n boxShadow: 6\n }}\n >\n {layoutTab\n ? 'Inspetor: clique num gráfico ou filtro para editá-lo · Esc para sair'\n : 'Inspetor: clique num gráfico ou filtro do dashboard · Esc para sair'}\n </Box>\n )}\n </ThemeProvider>\n </Portal>\n )\n}\n\nfunction ToggleButton({\n draft,\n loading,\n problems,\n inspecting,\n onOpen\n}: {\n draft: boolean\n loading: number\n problems: number\n inspecting: boolean\n onOpen: () => void\n}) {\n return (\n <Tooltip title=\"BI Devtools (Alt+Shift+B)\" placement=\"right\">\n <Box\n {...devtoolsMarker}\n component=\"button\"\n type=\"button\"\n onClick={onOpen}\n aria-label=\"Abrir BI Devtools\"\n sx={{\n position: 'fixed',\n left: 12,\n bottom: 12,\n zIndex: Z_INDEX,\n display: 'flex',\n alignItems: 'center',\n gap: 0.75,\n px: 1.25,\n height: 32,\n border: '1px solid',\n borderColor: draft || inspecting ? 'warning.main' : '#F58220',\n borderRadius: 16,\n bgcolor: '#1b1e23',\n color: '#fff',\n fontSize: 12,\n fontWeight: 800,\n cursor: 'pointer',\n boxShadow: 4,\n opacity: 0.85,\n '&:hover': { opacity: 1 }\n }}\n >\n <Box component=\"span\" sx={{ color: '#F58220' }}>\n ◆\n </Box>\n BI\n {!!loading && <CircularProgress size={10} sx={{ color: '#4dabf7' }} />}\n {!!problems && (\n <Box component=\"span\" sx={{ bgcolor: 'error.main', borderRadius: 8, px: 0.75 }}>\n {problems}\n </Box>\n )}\n {draft && (\n <Box component=\"span\" sx={{ color: 'warning.main' }}>\n rascunho\n </Box>\n )}\n </Box>\n </Tooltip>\n )\n}\n"],"mappings":"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"}