@actionexec/dashboards 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/SearchableSelect.d.ts +9 -0
- package/dist/{index-CxUAEQYp.js → index-BXIn44vr.js} +250 -166
- package/dist/index-BXIn44vr.js.map +1 -0
- package/dist/index.js +249 -238
- package/dist/index.js.map +1 -1
- package/dist/internals.d.ts +1 -0
- package/dist/internals.js +19 -18
- package/dist/styles.css +1 -1
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
- package/dist/index-CxUAEQYp.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-BXIn44vr.js","sources":["../src/api/fetcher.ts","../src/palettes/index.ts","../src/utils/date.ts","../src/components/DashboardDatePicker.tsx","../src/components/SearchableSelect.tsx","../src/components/ColorPaletteSelector.tsx","../src/types/index.ts"],"sourcesContent":["// Purpose: Client HTTP interno da API Action (endpoints /external/dashboards).\n// Scope: Infraestrutura da lib — nao exportado no index publico. Consumidor\n// externo usa <Dashboard token /> que encapsula tudo.\n// Public API (interno): fetchLayout, fetchRender, ApiError, setApiUrl\n\nimport type { LayoutResponse, RenderResponse } from '../types';\n\nconst DEFAULT_API_URL = 'https://action-data-api-7mbrztperq-rj.a.run.app';\nconst ENDPOINT_PREFIX = '/external/dashboards';\n\n// URL efetiva — pode ser sobrescrita via `setApiUrl` (uso interno em dev).\nlet apiUrl = DEFAULT_API_URL;\n\n/** Sobrescreve a URL base da API. Destinado ao builder da plataforma em dev —\n * consumidores externos nao devem chamar (usam a URL de producao por default). */\nexport function setApiUrl(url: string): void {\n apiUrl = url.replace(/\\/$/, '');\n}\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public status?: number,\n public payload?: unknown,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nasync function get<T>(path: string, token: string, params?: Record<string, string>): Promise<T> {\n const url = new URL(`${apiUrl}${ENDPOINT_PREFIX}${path}`);\n if (params) {\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n }\n\n const res = await fetch(url.toString(), {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n let payload: unknown;\n try { payload = await res.json(); } catch { /* non-json */ }\n throw new ApiError(\n `Requisicao falhou (${res.status}) em ${path}`,\n res.status,\n payload,\n );\n }\n return (await res.json()) as T;\n}\n\nexport const fetchLayout = (token: string) =>\n get<LayoutResponse>('/layout', token);\n\nexport const fetchRender = (token: string, params?: Record<string, string>) =>\n get<RenderResponse>('/render', token, params);\n","// Purpose: Paletas de cores completas para dashboards (series de dados + cores de UI).\n// Scope: Define paletas com 13 slots semanticos (5 series + 8 cores de UI) e helpers\n// para extrair series e gerar CSS variables aplicaveis ao escopo do dashboard.\n// Public API: PALETTES, PaletteKey, Palette, getSeries, getPaletteCssVars,\n// SLOT_INDEX, SLOT_LABELS, DEFAULT_PALETTE_COLORS, ensurePaletteShape\n\nexport interface Palette {\n label: string;\n colors: string[]; // 13 cores ordenadas pelos slots semanticos\n}\n\nexport type PaletteKey = 'action' | 'westCoast' | 'mono' | 'ocean' | 'princess';\n\n// -------Slots semanticos (indices fixos no array de cores)-------\n//\n// Convencao posicional para manter o storage como string[] (compativel com schemas\n// Pydantic e o tipo `PaletteConfig.paletteColors`). Cada paleta deve ter 13 cores.\n\nexport const SLOT_INDEX = {\n series0: 0,\n series1: 1,\n series2: 2,\n series3: 3,\n series4: 4,\n bgDark: 5,\n bgPaper: 6,\n bgElevated: 7,\n textPrimary: 8,\n textMuted: 9,\n accent: 10,\n success: 11,\n error: 12,\n} as const;\n\nexport const SERIES_COUNT = 5;\nexport const TOTAL_SLOTS = 13;\n\nexport const SLOT_LABELS: Record<keyof typeof SLOT_INDEX, string> = {\n series0: 'Série 1',\n series1: 'Série 2',\n series2: 'Série 3',\n series3: 'Série 4',\n series4: 'Série 5',\n bgDark: 'Fundo Escuro',\n bgPaper: 'Fundo Cartão',\n bgElevated: 'Fundo Elevado',\n textPrimary: 'Texto Primário',\n textMuted: 'Texto Secundário',\n accent: 'Destaque',\n success: 'Sucesso',\n error: 'Erro',\n};\n\n// -------Presets-------\n\nexport const PALETTES: Record<PaletteKey, Palette> = {\n action: {\n label: 'Action',\n colors: [\n '#ff6b00', '#a3e635', '#e3f544', '#65ffd1', '#ff0404',\n '#1a1a1a',\n '#262626',\n '#333333',\n '#f5f5f5',\n '#999999',\n '#ff6b00',\n '#a3e635',\n '#ef4444',\n ],\n },\n westCoast: {\n label: 'West Coast',\n colors: [\n '#a3b86c', '#c89b3c', '#8b6f47', '#6b8e23', '#d2691e',\n '#1f1a14',\n '#2a241b',\n '#3a3225',\n '#e8dcc4',\n '#a89878',\n '#c89b3c',\n '#a3b86c',\n '#c44536',\n ],\n },\n mono: {\n label: 'Monocromático',\n colors: [\n '#f8fafc', '#cbd5e1', '#94a3b8', '#64748b', '#475569',\n '#0a0a0a',\n '#171717',\n '#262626',\n '#fafafa',\n '#a3a3a3',\n '#e5e5e5',\n '#cbd5e1',\n '#ef4444',\n ],\n },\n ocean: {\n label: 'Ocean',\n colors: [\n '#0ea5e9', '#06b6d4', '#0891b2', '#3b82f6', '#22d3ee',\n '#0a1929',\n '#0f2740',\n '#173554',\n '#e0f2fe',\n '#7dd3fc',\n '#22d3ee',\n '#10b981',\n '#f43f5e',\n ],\n },\n princess: {\n label: 'Cute Pink',\n colors: [\n '#ff79bc', '#a855f7', '#f472b6', '#d946ef', '#fb7185',\n '#fff0f6',\n '#ffe4ec',\n '#ffffff',\n '#ff4099',\n '#ffadd5',\n '#ec4899',\n '#10b981',\n '#e11d48',\n ],\n },\n};\n\nexport const DEFAULT_PALETTE: PaletteKey = 'action';\n\n// Array de cores default expandido (13 slots)\nexport const DEFAULT_PALETTE_COLORS: string[] = PALETTES.action.colors;\n\n// -------Helpers-------\n\n/** Garante que a paleta tem TOTAL_SLOTS cores. Preenche faltantes com fallback do default. */\nexport function ensurePaletteShape(colors?: string[]): string[] {\n const fallback = DEFAULT_PALETTE_COLORS;\n if (!colors || colors.length === 0) return [...fallback];\n if (colors.length >= TOTAL_SLOTS) return colors.slice(0, TOTAL_SLOTS);\n const result = [...colors];\n for (let i = colors.length; i < TOTAL_SLOTS; i++) result.push(fallback[i]);\n return result;\n}\n\n/** Extrai apenas as cores de series (uso em charts/gauge). */\nexport function getSeries(colors?: string[]): string[] {\n const full = ensurePaletteShape(colors);\n return full.slice(0, SERIES_COUNT);\n}\n\n/** Gera objeto de CSS variables para aplicar inline no escopo do dashboard. */\nexport function getPaletteCssVars(colors?: string[]): Record<string, string> {\n const c = ensurePaletteShape(colors);\n return {\n '--bg-dark': c[SLOT_INDEX.bgDark],\n '--bg-paper': c[SLOT_INDEX.bgPaper],\n '--bg-elevated': c[SLOT_INDEX.bgElevated],\n '--text-primary': c[SLOT_INDEX.textPrimary],\n '--text-secondary': c[SLOT_INDEX.textMuted],\n '--text-muted': c[SLOT_INDEX.textMuted],\n '--action-orange': c[SLOT_INDEX.accent],\n '--action-green': c[SLOT_INDEX.success],\n '--color-success': c[SLOT_INDEX.success],\n '--color-error': c[SLOT_INDEX.error],\n '--color-info': c[SLOT_INDEX.series2],\n '--color-warning': c[SLOT_INDEX.series3],\n };\n}\n","// Purpose: Utilitarios de data para filtros temporais de dashboards.\n// Scope: Calculo de intervalos anuais/mensais/semanais, parse de ranges, ISO week.\n// Public API: MONTH_NAMES_*, getFullYearRange, getMonthRange, getWeekRange, getISOWeek,\n// getWeeksInMonth, parseYearFromRange, parseMonthFromRange, parseWeekFromRange,\n// getYearRange, getMonthWeeks, MonthWeek\n\nexport const MONTH_NAMES_SHORT = [\n 'Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun',\n 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez',\n];\n\nexport const MONTH_NAMES_FULL = [\n 'Janeiro', 'Fevereiro', 'Marco', 'Abril', 'Maio', 'Junho',\n 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro',\n];\n\nexport function getFullYearRange(year: number): { start: string; end: string } {\n return { start: `${year}-01-01`, end: `${year}-12-31` };\n}\n\nexport function parseYearFromRange(start: string): { year: number } | null {\n if (!start) return null;\n const m = start.match(/^(\\d{4})/);\n return m ? { year: parseInt(m[1]) } : null;\n}\n\nexport function getMonthRange(year: number, month: number): { start: string; end: string } {\n const lastDay = new Date(year, month, 0).getDate();\n const pad = (n: number) => String(n).padStart(2, '0');\n return {\n start: `${year}-${pad(month)}-01`,\n end: `${year}-${pad(month)}-${pad(lastDay)}`,\n };\n}\n\nexport function getISOWeek(dt: Date): number {\n const d = new Date(Date.UTC(dt.getFullYear(), dt.getMonth(), dt.getDate()));\n d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));\n return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n}\n\nexport function getWeekRange(year: number, week: number): { start: string; end: string } {\n const jan4 = new Date(year, 0, 4);\n const dayOfWeek = (jan4.getDay() + 6) % 7;\n const firstMonday = new Date(jan4.getTime() - dayOfWeek * 86400000);\n const start = new Date(firstMonday.getTime() + (week - 1) * 7 * 86400000);\n const end = new Date(start.getTime() + 6 * 86400000);\n const pad = (n: number) => String(n).padStart(2, '0');\n const fmt = (d: Date) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n return { start: fmt(start), end: fmt(end) };\n}\n\nexport function getWeeksInMonth(year: number, month: number): number[] {\n const weeks: Set<number> = new Set();\n const daysInMonth = new Date(year, month, 0).getDate();\n for (let d = 1; d <= daysInMonth; d++) {\n weeks.add(getISOWeek(new Date(year, month - 1, d)));\n }\n return Array.from(weeks).sort((a, b) => a - b);\n}\n\nexport interface MonthWeek {\n index: number;\n startDay: number;\n endDay: number;\n start: string;\n end: string;\n label: string;\n}\n\nexport function getMonthWeeks(year: number, month: number): MonthWeek[] {\n const daysInMonth = new Date(year, month, 0).getDate();\n const pad = (n: number) => String(n).padStart(2, '0');\n const weeks: MonthWeek[] = [];\n let day = 1;\n let index = 1;\n\n while (day <= daysInMonth) {\n const startDay = day;\n const endDay = Math.min(day + 6, daysInMonth);\n const start = `${year}-${pad(month)}-${pad(startDay)}`;\n const end = `${year}-${pad(month)}-${pad(endDay)}`;\n const label = `${index}° Semana (${pad(startDay)}/${pad(month)} - ${pad(endDay)}/${pad(month)})`;\n weeks.push({ index, startDay, endDay, start, end, label });\n day = endDay + 1;\n index++;\n }\n\n return weeks;\n}\n\nexport function parseMonthWeekFromRange(start: string, year: number, month: number): number {\n if (!start) return 1;\n const pad = (n: number) => String(n).padStart(2, '0');\n const dayMatch = start.match(new RegExp(`^${year}-${pad(month)}-(\\\\d{2})`));\n if (!dayMatch) return 1;\n const day = parseInt(dayMatch[1]);\n return Math.ceil(day / 7);\n}\n\nexport function parseMonthFromRange(start: string): { year: number; month: number } | null {\n if (!start) return null;\n const m = start.match(/^(\\d{4})-(\\d{2})/);\n return m ? { year: parseInt(m[1]), month: parseInt(m[2]) } : null;\n}\n\nexport function parseWeekFromRange(start: string): { year: number; week: number } | null {\n if (!start) return null;\n const d = new Date(start + 'T00:00:00');\n if (isNaN(d.getTime())) return null;\n return { year: d.getFullYear(), week: getISOWeek(d) };\n}\n\nexport function getYearRange(dateBounds?: { min: string | null; max: string | null } | null): number[] {\n const now = new Date();\n const minYear = dateBounds?.min ? parseInt(dateBounds.min.slice(0, 4)) : now.getFullYear() - 2;\n const maxYear = dateBounds?.max ? parseInt(dateBounds.max.slice(0, 4)) : now.getFullYear();\n const years: number[] = [];\n for (let y = maxYear; y >= minYear; y--) years.push(y);\n return years;\n}\n","// Purpose: Wrapper react-datepicker para dashboards.\n// Scope: Converte YYYY-MM-DD <-> Date, aplica estilos escopados via .ddp-field.\n// Public API: DashboardDatePicker, isoToDate, dateToIso\n\nimport DatePicker from 'react-datepicker';\nimport 'react-datepicker/dist/react-datepicker.css';\n\n// -------Helpers ISO <-> Date-------\n// Usam local-time para evitar timezone shift (toISOString() converte para UTC).\n\nexport function isoToDate(iso?: string | null): Date | null {\n if (!iso) return null;\n const [y, m, d] = iso.split('-').map(Number);\n if (!y || !m || !d) return null;\n return new Date(y, m - 1, d);\n}\n\nexport function dateToIso(date?: Date | null): string {\n if (!date) return '';\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\n// -------Componente-------\n\ninterface Props {\n value: string; // 'YYYY-MM-DD' ou ''\n onChange: (iso: string) => void; // emite '' quando limpo\n minIso?: string | null;\n maxIso?: string | null;\n placeholder?: string;\n selectsStart?: boolean;\n selectsEnd?: boolean;\n startIso?: string | null;\n endIso?: string | null;\n className?: string;\n disabled?: boolean;\n}\n\nexport function DashboardDatePicker({\n value, onChange, minIso, maxIso, placeholder,\n selectsStart, selectsEnd, startIso, endIso, className, disabled,\n}: Props) {\n return (\n <div className={`ddp-field ${className ?? ''}`}>\n <DatePicker\n selected={isoToDate(value)}\n onChange={(d: Date | null) => onChange(dateToIso(d))}\n selectsStart={selectsStart}\n selectsEnd={selectsEnd}\n startDate={isoToDate(startIso) ?? undefined}\n endDate={isoToDate(endIso) ?? undefined}\n minDate={isoToDate(minIso) ?? undefined}\n maxDate={isoToDate(maxIso) ?? undefined}\n dateFormat=\"dd/MM/yyyy\"\n placeholderText={placeholder ?? 'Selecione...'}\n disabled={disabled}\n portalId=\"ddp-portal\"\n popperPlacement=\"bottom-start\"\n popperModifiers={[\n {\n name: 'flip',\n options: { fallbackPlacements: ['bottom-end', 'top-start', 'top-end'] },\n fn: (state) => state,\n },\n ]}\n />\n </div>\n );\n}\n","// Purpose: Seletor categorico com busca por digitacao (selecao unica e multipla).\n// Scope: Reaproveitado pelo FilterWidget (runtime) e pelo builder (valor padrao do filtro).\n// Mantem o mesmo formato de valor do select nativo/checkboxes: unica = string da\n// opcao ('' = Todos); multipla = csv das opcoes selecionadas.\n// Public API: SearchableSelect\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\ninterface Props {\n options: string[];\n value: string;\n multi: boolean;\n onChange: (value: string) => void;\n // Texto exibido quando nada esta selecionado (default: \"Todos\")\n placeholder?: string;\n}\n\nexport function SearchableSelect({ options, value, multi, onChange, placeholder }: Props) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const rootRef = useRef<HTMLDivElement>(null);\n\n const selected = useMemo(\n () => (value ? value.split(',').filter(Boolean) : []),\n [value],\n );\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return options;\n return options.filter((opt) => opt.toLowerCase().includes(q));\n }, [options, query]);\n\n // Fecha o painel ao clicar fora do componente\n useEffect(() => {\n if (!open) return;\n const handleOutside = (e: MouseEvent) => {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener('mousedown', handleOutside);\n return () => document.removeEventListener('mousedown', handleOutside);\n }, [open]);\n\n const commitSingle = (opt: string) => {\n onChange(opt);\n setQuery('');\n setOpen(false);\n };\n\n const toggleMulti = (opt: string) => {\n const next = selected.includes(opt)\n ? selected.filter((s) => s !== opt)\n : [...selected, opt];\n onChange(next.join(','));\n };\n\n const hasSelection = multi ? selected.length > 0 : Boolean(value);\n const triggerLabel = multi\n ? (selected.length > 0 ? `${selected.length} selecionado(s)` : (placeholder || 'Todos'))\n : (value || placeholder || 'Todos');\n\n return (\n <div ref={rootRef} className=\"widget-filter__search\">\n <button\n type=\"button\"\n className=\"widget-filter__search-trigger\"\n onClick={() => setOpen((prev) => !prev)}\n >\n <span className={`widget-filter__search-value${hasSelection ? '' : ' is-placeholder'}`}>\n {triggerLabel}\n </span>\n <span className=\"widget-filter__search-caret\" aria-hidden>▾</span>\n </button>\n\n {open && (\n <div className=\"widget-filter__search-panel\">\n <input\n type=\"text\"\n className=\"widget-filter__search-input\"\n autoFocus\n value={query}\n placeholder=\"Buscar...\"\n onChange={(e) => setQuery(e.target.value)}\n />\n <div className=\"widget-filter__search-list\">\n {/* Selecao unica: opcao explicita para limpar o filtro */}\n {!multi && (\n <button\n type=\"button\"\n className={`widget-filter__search-option${value ? '' : ' is-selected'}`}\n onClick={() => commitSingle('')}\n >\n Todos\n </button>\n )}\n\n {filtered.length === 0 ? (\n <span className=\"widget-filter__search-empty\">Nenhuma opção</span>\n ) : (\n filtered.map((opt) =>\n multi ? (\n <label key={opt} className=\"widget-filter__search-option\">\n <input\n type=\"checkbox\"\n checked={selected.includes(opt)}\n onChange={() => toggleMulti(opt)}\n />\n {opt}\n </label>\n ) : (\n <button\n key={opt}\n type=\"button\"\n className={`widget-filter__search-option${value === opt ? ' is-selected' : ''}`}\n onClick={() => commitSingle(opt)}\n >\n {opt}\n </button>\n ),\n )\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n","// Purpose: Seletor de paleta de cores (13 slots semanticos).\n// Scope: Presets pre-definidos + modo customizado com color pickers nomeados por slot.\n// Public API: ColorPaletteSelector\n\nimport {\n PALETTES, ensurePaletteShape, getSeries, SLOT_INDEX, SLOT_LABELS, TOTAL_SLOTS,\n type PaletteKey,\n} from '../palettes';\n\n// Slots de tema usados para a segunda barra de preview do preset\nconst THEME_PREVIEW_SLOTS = [\n SLOT_INDEX.bgDark,\n SLOT_INDEX.bgPaper,\n SLOT_INDEX.bgElevated,\n SLOT_INDEX.accent,\n SLOT_INDEX.success,\n];\n\ninterface Props {\n selected?: string[];\n onSelect: (colors: string[]) => void;\n customMode?: boolean;\n onCustomModeChange?: (custom: boolean) => void;\n disabled?: boolean;\n}\n\nfunction isPreset(colors?: string[]): boolean {\n if (!colors) return true;\n const normalized = ensurePaletteShape(colors);\n return Object.values(PALETTES).some(\n (p) => JSON.stringify(p.colors) === JSON.stringify(normalized)\n );\n}\n\n// Slots agrupados por categoria para a UI customizada\nconst SLOT_ROWS: { label: string; slots: (keyof typeof SLOT_INDEX)[] }[] = [\n { label: 'Series', slots: ['series0', 'series1', 'series2', 'series3', 'series4'] },\n { label: 'Tema', slots: ['bgDark', 'bgPaper', 'bgElevated', 'textPrimary', 'textMuted'] },\n { label: 'Estados', slots: ['accent', 'success', 'error'] },\n];\n\nexport function ColorPaletteSelector({\n selected, onSelect, customMode, onCustomModeChange, disabled,\n}: Props) {\n const isCustom = customMode ?? !isPreset(selected);\n const colors = ensurePaletteShape(selected);\n\n const selectedKey = !isCustom\n ? (Object.entries(PALETTES).find(\n ([, p]) => JSON.stringify(p.colors) === JSON.stringify(colors)\n )?.[0] as PaletteKey | undefined)\n : undefined;\n\n const handleSlotChange = (slotIdx: number, color: string) => {\n const updated = [...colors];\n while (updated.length < TOTAL_SLOTS) updated.push('#000000');\n updated[slotIdx] = color;\n onSelect(updated);\n };\n\n return (\n <div className={`palette-selector ${disabled ? 'palette-selector--disabled' : ''}`}>\n {onCustomModeChange && (\n <label className=\"config-panel__checkbox\">\n <input\n type=\"checkbox\"\n checked={isCustom}\n onChange={(e) => onCustomModeChange(e.target.checked)}\n disabled={disabled}\n />\n Customizar\n </label>\n )}\n\n {isCustom ? (\n <div className=\"palette-selector__custom\">\n {SLOT_ROWS.map((row) => (\n <div key={row.label} className=\"palette-selector__row\">\n <span className=\"palette-selector__row-label\">{row.label}</span>\n <div className=\"palette-selector__row-slots\">\n {row.slots.map((slotName) => {\n const slotIdx = SLOT_INDEX[slotName];\n return (\n <input\n key={slotName}\n type=\"color\"\n className=\"palette-selector__color-input\"\n value={colors[slotIdx] || '#000000'}\n onChange={(e) => handleSlotChange(slotIdx, e.target.value)}\n disabled={disabled}\n title={SLOT_LABELS[slotName]}\n />\n );\n })}\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"palette-selector__options\">\n {(Object.entries(PALETTES) as [PaletteKey, typeof PALETTES[PaletteKey]][]).map(([key, palette]) => {\n const fullColors = ensurePaletteShape(palette.colors);\n return (\n <button\n key={key}\n className={`palette-selector__option ${selectedKey === key ? 'palette-selector__option--active' : ''}`}\n onClick={() => onSelect(palette.colors)}\n disabled={disabled}\n >\n <div className=\"palette-selector__bar\">\n {getSeries(palette.colors).map((color, i) => (\n <span\n key={i}\n className=\"palette-selector__swatch\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n <div className=\"palette-selector__bar palette-selector__bar--theme\">\n {THEME_PREVIEW_SLOTS.map((slotIdx, i) => (\n <span\n key={i}\n className=\"palette-selector__swatch\"\n style={{ backgroundColor: fullColors[slotIdx] }}\n />\n ))}\n </div>\n <span className=\"palette-selector__label\">{palette.label}</span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","// Purpose: Tipos compartilhados entre backend Python (schemas Pydantic) e frontend.\n// Scope: Union discriminada de WidgetDefinition, configs por tipo, respostas da API.\n// Public API: Todos os tipos e interfaces exportados + defaults + labels.\n\nimport { DEFAULT_PALETTE_COLORS } from '../palettes';\n\n// -------Enums como string literals-------\n\nexport type AggregationType = 'sum' | 'avg' | 'count' | 'min' | 'max' | 'count_distinct';\nexport type ComparisonType = 'yoy' | 'mom' | 'target' | 'none';\nexport type FilterType = 'date_range' | 'select' | 'multi_select';\nexport type WidgetType = 'kpi_card' | 'gauge' | 'chart' | 'filter' | 'variable' | 'color_palette';\nexport type DataWidgetType = 'kpi_card' | 'gauge' | 'chart';\nexport type ControlWidgetType = 'filter' | 'variable' | 'color_palette';\nexport type ChartType = 'bar' | 'line' | 'area' | 'pie';\nexport type FormatType = 'currency' | 'number' | 'integer' | 'percentage' | 'date' | 'text';\nexport type DateFilterMode = 'range' | 'monthly' | 'weekly' | 'yearly';\nexport type Granularity = 'day' | 'week' | 'month' | 'year' | 'weekday';\n\n// -------Pedacos compartilhados pelos configs-------\n\nexport interface FilterDefinition {\n id: string;\n type: FilterType;\n label: string;\n column?: string | null;\n defaultValue?: unknown;\n}\n\nexport interface TargetDefinition {\n id: string;\n label: string;\n value: number;\n format: FormatType;\n}\n\nexport interface GridPosition {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface ComparisonConfig {\n type: ComparisonType;\n targetId?: string;\n}\n\nexport interface AggregationStep {\n aggregation: AggregationType;\n groupBy: string;\n groupGranularity?: Granularity;\n}\n\nexport interface ColumnExpressionTerm {\n column: string;\n operator?: '+' | '-' | '*' | '/';\n}\n\nexport interface KpiOperand {\n column?: string;\n columnExpression?: ColumnExpressionTerm[];\n intermediateSteps?: AggregationStep[];\n finalAggregation?: AggregationType;\n constant?: number;\n}\n\nexport interface KpiTerm {\n operand: KpiOperand;\n operator?: '+' | '-' | '*' | '/'; // undefined apenas no primeiro termo\n}\n\nexport interface ChartSeriesConfig {\n label: string;\n // Formula simples\n column?: string;\n aggregation?: AggregationType;\n // Formula composta (pipeline identico ao KPI card, avaliado por grupo do eixo X)\n kpiTerms?: KpiTerm[];\n}\n\nexport interface ChartAxisConfig {\n column: string;\n granularity: Granularity;\n}\n\n// -------Config por tipo de widget-------\n\nexport interface KpiCardConfig {\n label: string;\n format?: FormatType;\n column?: string;\n aggregation?: AggregationType;\n groupBy?: string;\n groupGranularity?: Granularity;\n outerAggregation?: AggregationType;\n kpiTerms?: KpiTerm[];\n comparison?: ComparisonConfig;\n filterExpression?: Record<string, unknown>;\n}\n\nexport interface GaugeConfig {\n label: string;\n format?: FormatType;\n column?: string;\n aggregation?: AggregationType;\n targetId?: string;\n comparison?: ComparisonConfig;\n kpiTerms?: KpiTerm[];\n groupBy?: string;\n groupGranularity?: Granularity;\n outerAggregation?: AggregationType;\n filterExpression?: Record<string, unknown>;\n}\n\nexport interface ChartConfig {\n label: string;\n chartType?: ChartType;\n xAxis?: ChartAxisConfig;\n series?: ChartSeriesConfig[];\n categoryColumn?: string;\n format?: FormatType;\n filterExpression?: Record<string, unknown>;\n}\n\nexport interface FilterConfig {\n label: string;\n filterType: FilterType;\n filterColumn?: string;\n defaultValue?: unknown;\n dateFilterMode?: DateFilterMode;\n // Apresentacao categorica: true = lista com busca por digitacao; ausente = padrao\n // (select unico / checkboxes). Aplica-se a select e multi_select; nao afeta a query.\n searchable?: boolean;\n}\n\nexport interface VariableConfig {\n label: string;\n variableValue?: number;\n variableFormat?: FormatType;\n locked?: boolean;\n}\n\nexport interface PaletteConfig {\n paletteColors: string[];\n label?: string;\n locked?: boolean;\n}\n\nexport type AnyWidgetConfig =\n | KpiCardConfig | GaugeConfig | ChartConfig\n | FilterConfig | VariableConfig | PaletteConfig;\n\n// -------Union discriminada de WidgetDefinition-------\n\nexport type WidgetDefinition =\n | { id: string; type: 'kpi_card'; grid: GridPosition; config: KpiCardConfig }\n | { id: string; type: 'gauge'; grid: GridPosition; config: GaugeConfig }\n | { id: string; type: 'chart'; grid: GridPosition; config: ChartConfig }\n | { id: string; type: 'filter'; grid: GridPosition; config: FilterConfig }\n | { id: string; type: 'variable'; grid: GridPosition; config: VariableConfig }\n | { id: string; type: 'color_palette'; grid: GridPosition; config: PaletteConfig };\n\nexport type WidgetConfigOf<T extends WidgetType> = Extract<WidgetDefinition, { type: T }>['config'];\n\n// -------Layout completo-------\n\nexport interface DashboardLayout {\n gridColumns: number;\n gridRows: number;\n widgets: WidgetDefinition[];\n}\n\n// -------Respostas da API-------\n\nexport interface FilterValuesResponse {\n date_bounds: { min: string | null; max: string | null };\n filter_options: Record<string, string[]>;\n headers: string[];\n column_types: Record<string, string>;\n}\n\nexport interface RenderResponse {\n date_bounds: { min: string; max: string };\n applied: Record<string, unknown>;\n widgets: Record<string, Record<string, unknown>>;\n}\n\nexport interface LayoutResponse {\n name: string;\n palette: string[];\n gridColumns: number;\n gridRows: number;\n dateBounds: { min: string; max: string };\n widgets: WidgetDefinition[];\n}\n\n// -------Defaults-------\n\n// Re-export para compatibilidade com codigo existente que importa de dashboardLayout\nexport const DEFAULT_PALETTE = DEFAULT_PALETTE_COLORS;\n\nexport const DEFAULT_GRID_COLUMNS = 30;\nexport const DEFAULT_GRID_ROWS = 10;\n\nexport const EMPTY_LAYOUT: DashboardLayout = {\n gridColumns: DEFAULT_GRID_COLUMNS,\n gridRows: DEFAULT_GRID_ROWS,\n widgets: [],\n};\n\nexport const WIDGET_TYPE_LABELS: Record<WidgetType, string> = {\n kpi_card: 'KPI Card',\n gauge: 'Gauge',\n chart: 'Gráfico',\n filter: 'Filtro',\n variable: 'Variável',\n color_palette: 'Paleta de Cores',\n};\n\nexport const DATA_WIDGET_TYPES: DataWidgetType[] = ['kpi_card', 'gauge', 'chart'];\nexport const CONTROL_WIDGET_TYPES: ControlWidgetType[] = ['filter', 'variable', 'color_palette'];\nexport const CONTROL_WIDGET_SET = new Set<WidgetType>(['filter', 'variable', 'color_palette']);\n\nexport const AGGREGATION_LABELS: Record<AggregationType, string> = {\n sum: 'Soma',\n avg: 'Média',\n count: 'Contagem',\n min: 'Mínimo',\n max: 'Máximo',\n count_distinct: 'Contagem Distinta',\n};\n\nexport const FORMAT_LABELS: Record<FormatType, string> = {\n currency: 'Moeda (R$)',\n number: 'Número',\n integer: 'Inteiro',\n percentage: 'Porcentagem',\n date: 'Data',\n text: 'Texto',\n};\n\n// Subset de formatos numericos — usado nos configs de KPI, Gauge, Variable\nexport const NUMERIC_FORMAT_OPTIONS = Object.entries(FORMAT_LABELS)\n .filter(([k]) => k !== 'date' && k !== 'text') as [FormatType, string][];\n\nexport const COMPARISON_LABELS: Record<ComparisonType, string> = {\n yoy: 'vs Ano Anterior',\n mom: 'vs Mês Anterior',\n target: 'vs Meta',\n none: 'Nenhuma',\n};\n\nexport const CHART_TYPE_LABELS: Record<ChartType, string> = {\n bar: 'Barras',\n line: 'Linhas',\n area: 'Área',\n pie: 'Pizza',\n};\n\nexport const FILTER_TYPE_LABELS: Record<FilterType, string> = {\n date_range: 'Periodo',\n select: 'Seleção Única',\n multi_select: 'Seleção Múltipla',\n};\n\n// -------Default grid sizes por tipo de widget-------\n\nexport const DEFAULT_GRID: Record<WidgetType, GridPosition> = {\n kpi_card: { x: 0, y: 0, w: 6, h: 3 },\n gauge: { x: 0, y: 0, w: 6, h: 5 },\n chart: { x: 0, y: 0, w: 6, h: 6 },\n filter: { x: 0, y: 0, w: 4, h: 2 },\n variable: { x: 0, y: 0, w: 4, h: 2 },\n color_palette: { x: 0, y: 0, w: 4, h: 2 },\n};\n\nexport const DEFAULT_CONFIG: { [K in WidgetType]: Partial<WidgetConfigOf<K>> } = {\n kpi_card: { label: 'Novo KPI', aggregation: 'sum', format: 'number' },\n gauge: { label: 'Novo Gauge', aggregation: 'sum' },\n chart: { label: 'Novo Grafico', chartType: 'bar', xAxis: { column: '', granularity: 'day' }, series: [] },\n filter: { label: 'Novo Filtro', filterType: 'select' },\n variable: { label: 'Nova Variavel', variableValue: 0, variableFormat: 'number', locked: false },\n color_palette: { label: 'Paleta de Cores', paletteColors: DEFAULT_PALETTE, locked: false },\n};\n"],"names":["DEFAULT_API_URL","ENDPOINT_PREFIX","apiUrl","setApiUrl","url","ApiError","message","status","payload","get","path","token","params","k","v","res","fetchLayout","fetchRender","SLOT_INDEX","SERIES_COUNT","TOTAL_SLOTS","SLOT_LABELS","PALETTES","DEFAULT_PALETTE_COLORS","ensurePaletteShape","colors","fallback","result","i","getSeries","getPaletteCssVars","c","MONTH_NAMES_SHORT","MONTH_NAMES_FULL","getFullYearRange","year","parseYearFromRange","start","m","getMonthRange","month","lastDay","pad","n","getISOWeek","dt","d","yearStart","getWeekRange","week","jan4","dayOfWeek","firstMonday","end","fmt","getWeeksInMonth","weeks","daysInMonth","a","b","getMonthWeeks","day","index","startDay","endDay","label","parseMonthWeekFromRange","dayMatch","parseMonthFromRange","parseWeekFromRange","getYearRange","dateBounds","now","minYear","maxYear","years","y","isoToDate","iso","dateToIso","date","DashboardDatePicker","value","onChange","minIso","maxIso","placeholder","selectsStart","selectsEnd","startIso","endIso","className","disabled","jsx","DatePicker","state","SearchableSelect","options","multi","open","setOpen","useState","query","setQuery","rootRef","useRef","selected","useMemo","filtered","q","opt","useEffect","handleOutside","e","commitSingle","toggleMulti","next","s","hasSelection","triggerLabel","jsxs","prev","THEME_PREVIEW_SLOTS","isPreset","normalized","p","SLOT_ROWS","ColorPaletteSelector","onSelect","customMode","onCustomModeChange","isCustom","selectedKey","_a","handleSlotChange","slotIdx","color","updated","row","slotName","key","palette","fullColors","DEFAULT_PALETTE","DEFAULT_GRID_COLUMNS","DEFAULT_GRID_ROWS","EMPTY_LAYOUT","WIDGET_TYPE_LABELS","DATA_WIDGET_TYPES","CONTROL_WIDGET_TYPES","CONTROL_WIDGET_SET","AGGREGATION_LABELS","FORMAT_LABELS","NUMERIC_FORMAT_OPTIONS","COMPARISON_LABELS","CHART_TYPE_LABELS","FILTER_TYPE_LABELS","DEFAULT_GRID","DEFAULT_CONFIG"],"mappings":"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"}
|