@fayz-ai/plugin-reports 0.16.29 → 0.16.31
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/AnalyticsModule-YIH6MDCC.js +4 -0
- package/dist/AnalyticsModule-YIH6MDCC.js.map +1 -0
- package/dist/AnalyticsOverview-R3JEMUQL.js +4 -0
- package/dist/AnalyticsOverview-R3JEMUQL.js.map +1 -0
- package/dist/AnalyticsReportViewer-ORI3XI5D.js +5 -0
- package/dist/AnalyticsReportViewer-ORI3XI5D.js.map +1 -0
- package/dist/AnalyticsSettingsPage-XWPM3VSA.js +4 -0
- package/dist/AnalyticsSettingsPage-XWPM3VSA.js.map +1 -0
- package/dist/LiveViewPage-XMVZHJ3U.js +16 -0
- package/dist/LiveViewPage-XMVZHJ3U.js.map +1 -0
- package/dist/ReportsListPage-7FAKQZ4T.js +4 -0
- package/dist/ReportsListPage-7FAKQZ4T.js.map +1 -0
- package/dist/chunk-67JOMNSD.js +127 -0
- package/dist/chunk-67JOMNSD.js.map +1 -0
- package/dist/chunk-DP7S37Y2.js +145 -0
- package/dist/chunk-DP7S37Y2.js.map +1 -0
- package/dist/chunk-DTUN4WLI.js +577 -0
- package/dist/chunk-DTUN4WLI.js.map +1 -0
- package/dist/chunk-S4MICM4C.js +23 -0
- package/dist/chunk-S4MICM4C.js.map +1 -0
- package/dist/chunk-VGDOKFED.js +236 -0
- package/dist/chunk-VGDOKFED.js.map +1 -0
- package/dist/chunk-YVLQV4N7.js +307 -0
- package/dist/chunk-YVLQV4N7.js.map +1 -0
- package/dist/components/ReportPagination.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -2092
- package/dist/index.js.map +1 -1
- package/dist/migrations/main.browser.js +7 -0
- package/dist/migrations/main.browser.js.map +1 -0
- package/dist/migrations/main.js +692 -0
- package/dist/migrations/main.js.map +1 -0
- package/package.json +10 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/views/AnalyticsSettingsPage.tsx"],"names":[],"mappings":"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","file":"chunk-DTUN4WLI.js","sourcesContent":["import React from 'react'\nimport {\n Eye, EyeOff, GripVertical, RotateCcw, SlidersHorizontal, Trash2,\n ChevronUp, ChevronDown,\n} from 'lucide-react'\nimport type {\n AnalyticsCardDef, AnalyticsVizType, PluginAITool, PluginQuickAction,\n} from '@fayz-ai/core'\nimport { useTranslation } from '@fayz-ai/core'\nimport {\n Badge, Button, Card, Checkbox, Input, PageHeaderActions, SubpageHeader, getLucideIcon,\n Select, SelectTrigger, SelectValue, SelectContent, SelectItem,\n} from '@fayz-ai/ui'\nimport {\n QuickActionsButton, RightRailPage, askAI, useAgentSurface,\n type AgentSurfaceContribution, type AskAIIntro,\n} from '@fayz-ai/admin'\nimport {\n useAnalyticsConfig, useAnalyticsCatalogue, useAnalyticsCards, navigateAnalytics,\n ANALYTICS_BASE, REPORTS_BASE,\n} from './AnalyticsSurface'\nimport {\n analyticsSources, clearCardPref, deleteCustomReport, resetAnalyticsPrefs, saveCustomReport,\n setCardPref, setOverviewOrder, useAnalyticsPrefs,\n type AnalyticsSourceGroup, type CustomReport,\n} from '../lib/preferences'\n\n// ---------------------------------------------------------------------------\n// Configurar relatórios.\n//\n// One screen for the four things a user asks of a report catalogue: which ones\n// I see, in what order, what each one shows, and one of my own.\n//\n// It edits the PREFERENCE LAYER (lib/preferences), never the shipped card. Two\n// consequences worth stating: an app update still moves the base definition\n// under a user's choices instead of being overwritten by them, and \"restaurar\n// padrões\" is a delete, not a re-import — there is always a way back.\n//\n// Reordering is native drag-and-drop plus up/down buttons. Both, not either:\n// the drag is what a mouse expects and the buttons are what a keyboard, a\n// screen reader and a touch screen can actually use.\n// ---------------------------------------------------------------------------\n\nconst VIZ_TYPES: AnalyticsVizType[] = ['kpi', 'line', 'bar', 'area', 'donut', 'breakdown', 'table']\n\n/** A card with nothing to group by has no category axis — only a headline\n * number or a row listing can honestly render it. */\nfunction vizOptionsFor(card: AnalyticsCardDef): AnalyticsVizType[] {\n const hasDimension = (card.query.dimensions ?? []).some((d) => !d.hidden)\n return hasDimension ? VIZ_TYPES : ['kpi', 'table']\n}\n\nfunction CardIcon({ name, className }: { name?: string; className?: string }) {\n const Icon = getLucideIcon(name ?? 'FileText') ?? getLucideIcon('FileText')\n return Icon ? <Icon className={className} /> : null\n}\n\n// ---------------------------------------------------------------------------\n// Row\n// ---------------------------------------------------------------------------\n\ninterface RowProps {\n card: AnalyticsCardDef\n custom: boolean\n onEdit: () => void\n children?: React.ReactNode\n drag?: {\n onDragStart: () => void\n onDragOver: (event: React.DragEvent) => void\n onDragEnd: () => void\n dragging: boolean\n }\n}\n\nfunction ReportRow({ card, custom, onEdit, children, drag }: RowProps) {\n const t = useTranslation()\n return (\n <li\n draggable={Boolean(drag)}\n onDragStart={drag?.onDragStart}\n onDragOver={drag?.onDragOver}\n onDragEnd={drag?.onDragEnd}\n className={[\n 'flex items-center gap-2 border-b border-border/60 px-3 py-2 last:border-0',\n drag ? 'cursor-grab active:cursor-grabbing' : '',\n drag?.dragging ? 'opacity-40' : '',\n ].join(' ')}\n >\n {drag ? (\n <GripVertical className=\"h-4 w-4 shrink-0 text-muted-foreground/50\" aria-hidden />\n ) : (\n <span className=\"w-4 shrink-0\" aria-hidden />\n )}\n <CardIcon name={card.icon} className=\"h-4 w-4 shrink-0 text-muted-foreground\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"truncate text-sm font-medium\">{card.name}</span>\n {custom ? <Badge variant=\"secondary\">{t('reports.settings.custom')}</Badge> : null}\n </div>\n <p className=\"truncate text-xs text-muted-foreground\">{card.category}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {children}\n <Button variant=\"ghost\" size=\"sm\" onClick={onEdit} aria-label={t('reports.settings.edit')} title={t('reports.settings.edit')}>\n <SlidersHorizontal className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n </li>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Editor — one card's name, chart and columns\n// ---------------------------------------------------------------------------\n\nfunction CardEditor({ card, onClose }: { card: AnalyticsCardDef; onClose: () => void }) {\n const t = useTranslation()\n const prefs = useAnalyticsPrefs()\n const pref = prefs.cards[card.id] ?? {}\n const isCustom = prefs.custom.some((r) => r.id === card.id)\n\n const [name, setName] = React.useState(card.name)\n const measures = card.query.measures ?? []\n const dimensions = (card.query.dimensions ?? []).filter((d) => !d.hidden)\n\n const keptMeasures = new Set(pref.measures ?? measures.map((m) => m.key))\n const keptDimensions = new Set(pref.dimensions ?? dimensions.map((d) => d.key))\n\n const toggle = (set: Set<string>, key: string, field: 'measures' | 'dimensions', all: string[]) => {\n const next = new Set(set)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n // Everything selected is the same as no preference — record it as one and\n // the card stops tracking a list it would have to keep in sync forever.\n setCardPref(card.id, { [field]: next.size === all.length ? undefined : [...next] })\n }\n\n return (\n // A coluna da direita, não uma gaveta só desta tela: ajustar um relatório é\n // olhar a lista enquanto se mexe nele, e uma gaveta cobre exatamente a\n // lista. É a mesma coluna do assistente — RightRailPage cai numa Sheet\n // sozinha quando a shell não tem coluna nenhuma.\n <RightRailPage title={card.name} open onClose={onClose} width=\"max-w-md\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-4\">\n <div className=\"space-y-5\">\n {card.description ? (\n <p className=\"text-sm text-muted-foreground\">{card.description}</p>\n ) : null}\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.name')}</label>\n <Input\n value={name}\n onChange={(e) => setName(e.target.value)}\n onBlur={() => setCardPref(card.id, { name: name.trim() && name !== card.name ? name.trim() : undefined })}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.viz')}</label>\n <Select\n value={card.viz.type}\n onValueChange={(value) => setCardPref(card.id, { viz: value as AnalyticsVizType })}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {vizOptionsFor(card).map((viz) => (\n <SelectItem key={viz} value={viz}>{t(`reports.viz.${viz}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {dimensions.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.dimensions')}</p>\n {dimensions.map((d) => (\n <label key={d.key} className=\"flex cursor-pointer items-center gap-2 text-sm\">\n <Checkbox\n checked={keptDimensions.has(d.key)}\n onChange={() => toggle(keptDimensions, d.key, 'dimensions', dimensions.map((x) => x.key))}\n />\n {d.label}\n </label>\n ))}\n </div>\n ) : null}\n\n {measures.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.measures')}</p>\n {measures.map((m) => (\n <label key={m.key} className=\"flex cursor-pointer items-center gap-2 text-sm\">\n <Checkbox\n checked={keptMeasures.has(m.key)}\n onChange={() => toggle(keptMeasures, m.key, 'measures', measures.map((x) => x.key))}\n />\n {m.label}\n </label>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n\n {/* Sem \"Salvar\": cada controle grava ao mudar, e a coluna reflete o\n resultado atrás dela. O rodapé guarda só a saída — o desfazer. */}\n <div className=\"flex items-center justify-between border-t border-border p-3\">\n {isCustom ? (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => { deleteCustomReport(card.id); onClose() }}>\n <Trash2 className=\"mr-1.5 h-3.5 w-3.5\" />\n {t('reports.settings.delete')}\n </Button>\n ) : (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => { clearCardPref(card.id); onClose() }}>\n <RotateCcw className=\"mr-1.5 h-3.5 w-3.5\" />\n {t('reports.settings.resetCard')}\n </Button>\n )}\n <Button size=\"sm\" onClick={onClose}>{t('reports.settings.done')}</Button>\n </div>\n </RightRailPage>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Builder — a new report over a source the app already exposes\n// ---------------------------------------------------------------------------\n\nfunction slugify(value: string): string {\n return value.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'report'\n}\n\n/** Build a stored report from validated pieces. Shared by the form and by the\n * assistant's tool, so both produce the same object. */\nexport function buildCustomReport(input: {\n name: string\n category: string\n createdBy?: string\n source: AnalyticsSourceGroup\n dimensions: string[]\n measures: string[]\n viz: AnalyticsVizType\n}): CustomReport {\n const dimensionKeys = new Set(input.source.dimensions.map((d) => d.key))\n const measureKeys = new Set(input.source.measures.map((m) => m.key))\n return {\n id: `custom.${slugify(input.name)}-${Date.now().toString(36)}`,\n name: input.name.trim(),\n category: input.category.trim() || 'Geral',\n icon: 'FileText',\n createdBy: input.createdBy,\n baseId: input.source.base.id,\n // Filtered, not trusted: a field the source does not have would resolve to\n // nothing and the report would open empty with no explanation.\n dimensions: input.dimensions.filter((k) => dimensionKeys.has(k)),\n measures: input.measures.filter((k) => measureKeys.has(k)),\n viz: input.viz,\n createdAt: new Date().toISOString(),\n }\n}\n\nfunction NewReportPanel({\n sources, categories, onClose,\n}: { sources: AnalyticsSourceGroup[]; categories: string[]; onClose: () => void }) {\n const t = useTranslation()\n const { createdBy } = useAnalyticsConfig()\n\n const [name, setName] = React.useState('')\n const [category, setCategory] = React.useState(categories[0] ?? 'Geral')\n const [sourceKeyState, setSourceKey] = React.useState(sources[0]?.key ?? '')\n const [dimensions, setDimensions] = React.useState<string[]>([])\n const [measures, setMeasures] = React.useState<string[]>([])\n const [viz, setViz] = React.useState<AnalyticsVizType>('table')\n\n const source = sources.find((s) => s.key === sourceKeyState)\n\n // Switching source invalidates every field picked from the old one.\n React.useEffect(() => { setDimensions([]); setMeasures([]) }, [sourceKeyState])\n\n const toggle = (list: string[], set: (next: string[]) => void, key: string) => {\n set(list.includes(key) ? list.filter((k) => k !== key) : [...list, key])\n }\n\n const error = !name.trim()\n ? t('reports.settings.needName')\n : measures.length === 0\n ? t('reports.settings.needMeasure')\n : null\n\n const submit = () => {\n if (error || !source) return\n saveCustomReport(buildCustomReport({\n name, category, createdBy, source, dimensions, measures, viz,\n }))\n onClose()\n }\n\n return (\n <RightRailPage title={t('reports.settings.new')} open onClose={onClose} width=\"max-w-md\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-4\">\n <div className=\"space-y-5\">\n {/* Só o caminho manual. \"Criar com IA\" mora na barra do cabeçalho, ao\n lado do botão que abre este painel — duas portas para a mesma sala,\n uma dentro da outra, é o desenho que faz a de fora parecer inútil. */}\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.name')}</label>\n <Input value={name} onChange={(e) => setName(e.target.value)} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.category')}</label>\n <Input value={category} onChange={(e) => setCategory(e.target.value)} list=\"fayz-analytics-categories\" />\n <datalist id=\"fayz-analytics-categories\">\n {categories.map((c) => <option key={c} value={c} />)}\n </datalist>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.source')}</label>\n <Select value={sourceKeyState} onValueChange={setSourceKey}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {sources.map((s) => (\n <SelectItem key={s.key} value={s.key}>{s.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-muted-foreground\">{t('reports.settings.sourceHint')}</p>\n </div>\n\n <div className=\"space-y-2\">\n <p className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.dimensions')}</p>\n {(source?.dimensions ?? []).length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">—</p>\n ) : source!.dimensions.map((d) => (\n <label key={d.key} className=\"flex cursor-pointer items-center gap-2 text-sm\">\n <Checkbox checked={dimensions.includes(d.key)} onChange={() => toggle(dimensions, setDimensions, d.key)} />\n {d.label}\n </label>\n ))}\n </div>\n\n <div className=\"space-y-2\">\n <p className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.measures')}</p>\n {(source?.measures ?? []).map((m) => (\n <label key={m.key} className=\"flex cursor-pointer items-center gap-2 text-sm\">\n <Checkbox checked={measures.includes(m.key)} onChange={() => toggle(measures, setMeasures, m.key)} />\n {m.label}\n </label>\n ))}\n </div>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">{t('reports.settings.viz')}</label>\n <Select value={viz} onValueChange={(value) => setViz(value as AnalyticsVizType)}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {(dimensions.length > 0 ? VIZ_TYPES : (['kpi', 'table'] as AnalyticsVizType[])).map((v) => (\n <SelectItem key={v} value={v}>{t(`reports.viz.${v}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between gap-2 border-t border-border p-3\">\n <span className=\"truncate text-xs text-destructive\">{error}</span>\n <div className=\"flex shrink-0 items-center gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onClose}>{t('reports.settings.cancel')}</Button>\n <Button size=\"sm\" onClick={submit} disabled={Boolean(error)}>{t('reports.settings.save')}</Button>\n </div>\n </div>\n </RightRailPage>\n )\n}\n\n// ---------------------------------------------------------------------------\n// The assistant's way in\n//\n// Choosing a source, then dimensions, then measures is exactly the work someone\n// who already knows what they want should not have to do — and it is the work a\n// model does well GIVEN THE FIELD TABLE, which is why `describe()` below ships\n// every source with its askable fields rather than a prose summary.\n//\n// Client-plane on purpose: a custom report is a per-browser preference, not a\n// row in the tenant. The executor is the same `buildCustomReport` the form\n// calls, so a report built by conversation and one built by clicking are the\n// same object with the same guarantees.\n// ---------------------------------------------------------------------------\n\nconst CREATE_REPORT_TOOL: PluginAITool = {\n id: 'reports.createAnalyticsReport',\n name: 'createAnalyticsReport',\n description:\n 'Creates a custom analytics report for this user. Pick ONE source from the `sources` list in the surface state, then group_by and measures USING ONLY that source\\'s field keys — a key from another source resolves to nothing and the report opens empty. '\n + 'Understand the intent and propose the whole report in one call instead of asking field by field. '\n + 'Rules of thumb: one time dimension + one measure reads best as a line; a category dimension with one measure as bar or breakdown; three or more measures as a table; no dimension at all as a kpi.',\n icon: 'FileText',\n mode: 'persist',\n execution: { plane: 'client' },\n category: 'Analytics',\n suggestions: [\n { label: 'Um relatório de receita por mesa' },\n { label: 'Quanto cada praça produz por turno' },\n ],\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Report name, in the user\\'s language.' },\n source: { type: 'string', description: 'A `key` from the surface state\\'s `sources`.' },\n group_by: {\n type: 'array',\n description: 'Dimension keys from that source. Empty means a single headline number.',\n items: { type: 'string' },\n },\n measures: {\n type: 'array',\n description: 'Measure keys from that source. At least one.',\n items: { type: 'string' },\n },\n viz: {\n type: 'string',\n enum: ['kpi', 'line', 'bar', 'area', 'donut', 'breakdown', 'table'],\n description: 'How to draw it. Defaults to table.',\n },\n category: { type: 'string', description: 'Group it sits under in the rail. Reuse an existing one when it fits.' },\n pin: { type: 'boolean', description: 'Also place it on the overview grid.' },\n },\n required: ['name', 'source', 'measures'],\n },\n}\n\nconst AGENT_INSTRUCTIONS =\n 'The user is on the report configuration screen. `sources` in the surface state lists every data source with the exact dimension and measure keys askable of it — use those keys verbatim. '\n + 'When they describe a report, call createAnalyticsReport once with the full shape; do not interview them field by field. '\n + 'Name the report the way they said it. After creating, say in one line what it groups by and what it measures.'\n\n// ---------------------------------------------------------------------------\n// Page\n// ---------------------------------------------------------------------------\n\nexport function AnalyticsSettingsPage() {\n const t = useTranslation()\n const { labels } = useAnalyticsConfig()\n const catalogue = useAnalyticsCatalogue()\n const cards = useAnalyticsCards()\n const prefs = useAnalyticsPrefs()\n\n const { createdBy } = useAnalyticsConfig()\n const [editing, setEditing] = React.useState<string | null>(null)\n const [creating, setCreating] = React.useState(false)\n const [dragId, setDragId] = React.useState<string | null>(null)\n\n // A copy com que o assistente abre quando o handoff parte DESTA tela. Sem\n // ela o painel abre falando do que a tela oferecia antes (\"pergunte sobre\n // produção, cardápio e movimento\"), que é verdade e não é o assunto.\n const askIntro = React.useMemo<AskAIIntro>(() => ({\n role: 'setup',\n persona: t('reports.settings.askPersona'),\n pitch: t('reports.settings.askPitch'),\n description: t('reports.settings.askDescription'),\n suggestions: [0, 1, 2].map((i) => ({ label: t(`reports.settings.askSuggestion.${i}`) })),\n }), [t])\n\n const createActions = React.useMemo<PluginQuickAction[]>(() => [\n {\n id: 'with-ai',\n label: t('assistant.askAI'),\n description: t('reports.settings.newWithAIHint'),\n icon: 'WandSparkles',\n highlight: true,\n action: () => askAI({ hint: t('reports.settings.askPlaceholder'), intro: askIntro }),\n },\n {\n id: 'by-hand',\n label: t('reports.settings.newByHand'),\n description: t('reports.settings.newByHandHint'),\n icon: 'SlidersHorizontal',\n action: () => setCreating(true),\n },\n ], [t, askIntro])\n\n const sources = React.useMemo(() => analyticsSources(cards), [cards])\n const categories = React.useMemo(\n () => [...new Set(cards.map((c) => c.category))].sort((a, b) => a.localeCompare(b)),\n [cards],\n )\n\n const pinned = React.useMemo(\n () => cards.filter((c) => c.dashboard).sort((a, b) => (a.dashboard?.order ?? 0) - (b.dashboard?.order ?? 0)),\n [cards],\n )\n const unpinned = React.useMemo(\n () => cards.filter((c) => !c.dashboard).sort((a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name)),\n [cards],\n )\n // Removed built-ins live nowhere else — without this section a card taken out\n // of the catalogue can never be found again.\n const removed = React.useMemo(\n () => catalogue.filter((c) => prefs.cards[c.id]?.hidden),\n [catalogue, prefs],\n )\n\n // Live order during a drag: the committed order only moves on drop, so the\n // list under the cursor is state, not props.\n const [order, setOrder] = React.useState<string[] | null>(null)\n const pinnedIds = order ?? pinned.map((c) => c.id)\n const pinnedInOrder = pinnedIds\n .map((id) => pinned.find((c) => c.id === id))\n .filter((c): c is AnalyticsCardDef => Boolean(c))\n\n const move = (id: string, delta: number) => {\n const ids = pinned.map((c) => c.id)\n const from = ids.indexOf(id)\n const to = from + delta\n if (from < 0 || to < 0 || to >= ids.length) return\n ids.splice(to, 0, ids.splice(from, 1)[0]!)\n setOverviewOrder(ids)\n }\n\n const onDragOver = (targetId: string) => (event: React.DragEvent) => {\n event.preventDefault()\n if (!dragId || dragId === targetId) return\n const ids = [...pinnedIds]\n const from = ids.indexOf(dragId)\n const to = ids.indexOf(targetId)\n if (from < 0 || to < 0) return\n ids.splice(to, 0, ids.splice(from, 1)[0]!)\n setOrder(ids)\n }\n\n const commitDrag = () => {\n if (order) setOverviewOrder(order)\n setOrder(null)\n setDragId(null)\n }\n\n const editingCard = cards.find((c) => c.id === editing)\n const isCustom = (id: string) => prefs.custom.some((r) => r.id === id)\n\n // --- assistant surface ---------------------------------------------------\n // Read through a ref: `useAgentSurface` registers once and calls back later,\n // so a captured `sources` would go stale the moment a report is added.\n const surfaceRef = React.useRef({ sources, categories, cards, prefs, createdBy })\n surfaceRef.current = { sources, categories, cards, prefs, createdBy }\n\n const agentSurface = React.useMemo<AgentSurfaceContribution>(() => ({\n id: 'analytics.reports',\n pluginId: 'reports',\n instructions: AGENT_INSTRUCTIONS,\n describe: () => {\n const o = surfaceRef.current\n return {\n title: 'Configuração de relatórios',\n state: {\n sources: o.sources.map((source) => ({\n key: source.key,\n label: source.label,\n grain: source.base.grain ?? null,\n group_by: source.dimensions.map((d) => ({ key: d.key, label: d.label })),\n measures: source.measures.map((m) => ({ key: m.key, label: m.label, format: m.format ?? 'number' })),\n })),\n categories: o.categories,\n onOverview: o.cards.filter((c) => c.dashboard).map((c) => c.name),\n yourReports: o.prefs.custom.map((r) => r.name),\n },\n }\n },\n tools: [{\n tool: CREATE_REPORT_TOOL,\n execute: (args) => {\n const o = surfaceRef.current\n const source = o.sources.find((s) => s.key === args.source)\n ?? o.sources.find((s) => s.label === args.source)\n if (!source) {\n return { ok: false, error: 'unknown_source', sources: o.sources.map((s) => s.key) }\n }\n const report = buildCustomReport({\n name: String(args.name ?? '').trim() || 'Relatório',\n category: String(args.category ?? o.categories[0] ?? 'Geral'),\n createdBy: o.createdBy,\n source,\n dimensions: Array.isArray(args.group_by) ? (args.group_by as string[]) : [],\n measures: Array.isArray(args.measures) ? (args.measures as string[]) : [],\n viz: (args.viz as AnalyticsVizType) ?? 'table',\n })\n if (report.measures.length === 0) {\n return {\n ok: false,\n error: 'no_valid_measure',\n available: source.measures.map((m) => m.key),\n }\n }\n saveCustomReport(report)\n if (args.pin) setCardPref(report.id, { pinned: true, order: 999 })\n // Land on the thing that was just built: a report created and left\n // unopened is a claim the user has to go verify.\n navigateAnalytics(`${REPORTS_BASE}/${encodeURIComponent(report.id)}`)\n return {\n ok: true,\n id: report.id,\n name: report.name,\n group_by: report.dimensions,\n measures: report.measures,\n viz: report.viz,\n }\n },\n }],\n }), [])\n useAgentSurface(agentSurface)\n\n return (\n <div className=\"space-y-4\">\n <SubpageHeader\n title={t('reports.settings.title')}\n parentLabel={labels.analytics}\n onBack={() => navigateAnalytics(ANALYTICS_BASE)}\n />\n\n {/* Na barra da shell, junto do título — é onde toda tela do produto põe\n a sua ação principal. Numa faixa própria logo abaixo, elas abriam uma\n segunda barra de cabeçalho dizendo respeito à mesma página.\n \"Criar com IA\" é a PRIMÁRIA e o formulário fica em `outline`: descrever\n o relatório é o caminho curto, e enterrá-lo dentro do painel do\n caminho longo é escondê-lo atrás do que ele existe para evitar. */}\n <PageHeaderActions>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => resetAnalyticsPrefs()}>\n <RotateCcw className=\"mr-1.5 h-3.5 w-3.5\" />\n {t('reports.settings.reset')}\n </Button>\n {/* O mesmo menu de \"novo\" que o resto do produto usa (QuickActionsButton):\n ícone em ladrilho, rótulo e uma linha do que aquilo faz. A entrada de\n IA vai `highlight` — ver PluginQuickAction. */}\n <QuickActionsButton label={t('reports.settings.new')} variant=\"default\" actions={createActions} />\n </PageHeaderActions>\n\n <p className=\"max-w-2xl text-sm text-muted-foreground\">{t('reports.settings.subtitle')}</p>\n\n <Card className=\"overflow-hidden\">\n <div className=\"border-b border-border px-3 py-2\">\n <p className=\"text-sm font-medium\">{t('reports.settings.onOverview')}</p>\n <p className=\"text-xs text-muted-foreground\">{t('reports.settings.onOverviewHint')}</p>\n </div>\n {pinnedInOrder.length === 0 ? (\n <p className=\"px-3 py-6 text-center text-sm text-muted-foreground\">{t('reports.settings.empty')}</p>\n ) : (\n <ul>\n {pinnedInOrder.map((card, index) => (\n <ReportRow\n key={card.id}\n card={card}\n custom={isCustom(card.id)}\n onEdit={() => setEditing(card.id)}\n drag={{\n dragging: dragId === card.id,\n onDragStart: () => setDragId(card.id),\n onDragOver: onDragOver(card.id),\n onDragEnd: commitDrag,\n }}\n >\n <Select\n value={String(card.dashboard?.span ?? '')}\n onValueChange={(value) => setCardPref(card.id, { span: Number(value) as 1 | 2 | 3 | 4 })}\n >\n <SelectTrigger className=\"h-8 w-[150px]\">\n <SelectValue placeholder={t('reports.settings.width')} />\n </SelectTrigger>\n <SelectContent>\n {[1, 2, 3, 4].map((span) => (\n <SelectItem key={span} value={String(span)}>{t(`reports.settings.width.${span}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n variant=\"ghost\" size=\"sm\" disabled={index === 0}\n onClick={() => move(card.id, -1)} aria-label={t('reports.settings.up')} title={t('reports.settings.up')}\n >\n <ChevronUp className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" disabled={index === pinnedInOrder.length - 1}\n onClick={() => move(card.id, 1)} aria-label={t('reports.settings.down')} title={t('reports.settings.down')}\n >\n <ChevronDown className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setCardPref(card.id, { pinned: false })}\n aria-label={t('reports.settings.unpin')} title={t('reports.settings.unpin')}\n >\n <EyeOff className=\"h-3.5 w-3.5\" />\n </Button>\n </ReportRow>\n ))}\n </ul>\n )}\n </Card>\n\n <Card className=\"overflow-hidden\">\n <div className=\"border-b border-border px-3 py-2\">\n <p className=\"text-sm font-medium\">{t('reports.settings.offOverview')}</p>\n <p className=\"text-xs text-muted-foreground\">{t('reports.settings.offOverviewHint')}</p>\n </div>\n <ul>\n {unpinned.map((card) => (\n <ReportRow key={card.id} card={card} custom={isCustom(card.id)} onEdit={() => setEditing(card.id)}>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setCardPref(card.id, { pinned: true, order: pinned.length })}\n aria-label={t('reports.settings.pin')} title={t('reports.settings.pin')}\n >\n <Eye className=\"h-3.5 w-3.5\" />\n </Button>\n {isCustom(card.id) ? (\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => deleteCustomReport(card.id)}\n aria-label={t('reports.settings.delete')} title={t('reports.settings.delete')}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n ) : (\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setCardPref(card.id, { hidden: true })}\n aria-label={t('reports.settings.remove')} title={t('reports.settings.remove')}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </ReportRow>\n ))}\n </ul>\n </Card>\n\n {removed.length > 0 ? (\n <Card className=\"overflow-hidden\">\n <div className=\"border-b border-border px-3 py-2\">\n <p className=\"text-sm font-medium\">{t('reports.settings.hidden')}</p>\n </div>\n <ul>\n {removed.map((card) => (\n <li key={card.id} className=\"flex items-center gap-2 border-b border-border/60 px-3 py-2 last:border-0\">\n <span className=\"w-4 shrink-0\" aria-hidden />\n <CardIcon name={card.icon} className=\"h-4 w-4 shrink-0 text-muted-foreground\" />\n <div className=\"min-w-0 flex-1\">\n <span className=\"truncate text-sm text-muted-foreground\">{card.name}</span>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setCardPref(card.id, { hidden: undefined })}>\n <RotateCcw className=\"mr-1.5 h-3.5 w-3.5\" />\n {t('reports.settings.restore')}\n </Button>\n </li>\n ))}\n </ul>\n </Card>\n ) : null}\n\n {editingCard ? <CardEditor card={editingCard} onClose={() => setEditing(null)} /> : null}\n {creating ? <NewReportPanel sources={sources} categories={categories} onClose={() => setCreating(false)} /> : null}\n </div>\n )\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useAnalyticsConfig, useOverviewCards } from './chunk-YVLQV4N7.js';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { BarChart3 } from 'lucide-react';
|
|
4
|
+
import { collectFilters, AnalyticsControls, AnalyticsGrid } from '@fayz-ai/ui';
|
|
5
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function AnalyticsOverview() {
|
|
8
|
+
const { labels } = useAnalyticsConfig();
|
|
9
|
+
const cards = useOverviewCards();
|
|
10
|
+
const filters = React.useMemo(() => collectFilters(cards), [cards]);
|
|
11
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
12
|
+
/* @__PURE__ */ jsx(AnalyticsControls, { filters }),
|
|
13
|
+
cards.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center", children: [
|
|
14
|
+
/* @__PURE__ */ jsx("div", { className: "mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx(BarChart3, { className: "h-5 w-5 text-muted-foreground" }) }),
|
|
15
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: labels.emptyOverviewTitle }),
|
|
16
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: labels.emptyOverviewDescription })
|
|
17
|
+
] }) : /* @__PURE__ */ jsx(AnalyticsGrid, { cards })
|
|
18
|
+
] }) });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { AnalyticsOverview };
|
|
22
|
+
//# sourceMappingURL=chunk-S4MICM4C.js.map
|
|
23
|
+
//# sourceMappingURL=chunk-S4MICM4C.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/views/AnalyticsOverview.tsx"],"names":[],"mappings":";;;;;;AAcO,SAAS,iBAAA,GAAoB;AAClC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,MAAM,eAAe,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAIlE,EAAA,uBACE,GAAA,CAAA,QAAA,EAAA,EACE,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EAKb,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,qBAAkB,OAAA,EAAkB,CAAA;AAAA,IAEpC,MAAM,MAAA,KAAW,CAAA,mBAChB,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,6FAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,SAAI,SAAA,EAAU,uEAAA,EACb,8BAAC,SAAA,EAAA,EAAU,SAAA,EAAU,iCAAgC,CAAA,EACvD,CAAA;AAAA,sBACA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,aAAA,EAAe,iBAAO,kBAAA,EAAmB,CAAA;AAAA,sBACtD,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,6CAAA,EAA+C,iBAAO,wBAAA,EAAyB;AAAA,KAAA,EAC9F,CAAA,mBAEA,GAAA,CAAC,aAAA,EAAA,EAAc,KAAA,EAAc;AAAA,GAAA,EAEjC,CAAA,EACF,CAAA;AAEJ","file":"chunk-S4MICM4C.js","sourcesContent":["import React from 'react'\nimport { BarChart3 } from 'lucide-react'\nimport { AnalyticsControls, AnalyticsGrid, collectFilters } from '@fayz-ai/ui'\nimport { useAnalyticsConfig, useOverviewCards } from './AnalyticsSurface'\n\n// ---------------------------------------------------------------------------\n// The one general dashboard.\n//\n// It is not a separate feature from the report list — it is the subset of cards\n// a pack chose to place, rendered at tile size. Every tile's ↗ opens the very\n// same definition as a full report, which is why there is no \"dashboard metric\"\n// that has no report behind it.\n// ---------------------------------------------------------------------------\n\nexport function AnalyticsOverview() {\n const { labels } = useAnalyticsConfig()\n const cards = useOverviewCards()\n const filters = React.useMemo(() => collectFilters(cards), [cards])\n\n // The assistant's invite is mounted by the module, not here: it follows the\n // user from this grid into a report instead of belonging to one screen.\n return (\n <>\n <div className=\"space-y-4\">\n {/* Sem título nem descrição: a barra da shell já escreve \"Análises\", e a\n frase abaixo custava uma linha antes do primeiro número. */}\n {/* A superfície, o encosto à direita e o grudar no topo são de\n PageToolbar agora — a mesma barra que o dashboard usa. */}\n <AnalyticsControls filters={filters} />\n\n {cards.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <BarChart3 className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium\">{labels.emptyOverviewTitle}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">{labels.emptyOverviewDescription}</p>\n </div>\n ) : (\n <AnalyticsGrid cards={cards} />\n )}\n </div>\n </>\n )\n}\n"]}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { useAnalyticsConfig, useAnalyticsCards, markViewed, navigateAnalytics, REPORTS_BASE, ANALYTICS_BASE, cardColumns } from './chunk-YVLQV4N7.js';
|
|
2
|
+
import { expandBagColumns, formatValuePlain, reportColumnsToTanstack } from './chunk-4QIHTUXD.js';
|
|
3
|
+
import React2, { useState, useEffect } from 'react';
|
|
4
|
+
import { ArrowLeft, Printer, Construction, Download } from 'lucide-react';
|
|
5
|
+
import { Button, SubpageHeader, AnalyticsControls, useToolbarPanelClose, useAnalyticsCard, useAnalyticsCardRows, ToolbarAction, useAnalyticsContext, useAnalyticsAllRows, StatementTable, formatBucket, AnalyticsCard, DataTable, Dropdown, DropdownTrigger, DropdownContent, DropdownItem, Pagination, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@fayz-ai/ui';
|
|
6
|
+
import { exportCSV, useTranslation } from '@fayz-ai/core';
|
|
7
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function exportToCsv(columns, data, filename, currency) {
|
|
10
|
+
const { columns: cols, rows } = expandBagColumns(columns, data);
|
|
11
|
+
const visibleCols = cols.filter((c) => c.visible !== false);
|
|
12
|
+
const csvColumns = visibleCols.map((col) => ({
|
|
13
|
+
key: col.key,
|
|
14
|
+
label: col.label,
|
|
15
|
+
format: (value) => formatValuePlain(value, col, currency)
|
|
16
|
+
}));
|
|
17
|
+
exportCSV(csvColumns, rows, filename);
|
|
18
|
+
}
|
|
19
|
+
function ExportDropdown({ columns, data, filename, currency, title, fetchAll }) {
|
|
20
|
+
const t = useTranslation();
|
|
21
|
+
const [excelAvailable, setExcelAvailable] = useState(false);
|
|
22
|
+
const [pdfAvailable, setPdfAvailable] = useState(false);
|
|
23
|
+
const [busy, setBusy] = useState(false);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
import('./excel-NKWJ2AMC.js').then((m) => m.isExcelAvailable()).then(setExcelAvailable).catch(() => {
|
|
26
|
+
});
|
|
27
|
+
import('./pdf-H73MJGB6.js').then((m) => m.isPdfAvailable()).then(setPdfAvailable).catch(() => {
|
|
28
|
+
});
|
|
29
|
+
}, []);
|
|
30
|
+
const withRows = async (write) => {
|
|
31
|
+
if (busy) return;
|
|
32
|
+
setBusy(true);
|
|
33
|
+
try {
|
|
34
|
+
const rows = fetchAll ? await fetchAll().catch(() => data) : data;
|
|
35
|
+
await write(rows.length ? rows : data);
|
|
36
|
+
} finally {
|
|
37
|
+
setBusy(false);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const handleCsv = () => withRows((rows) => exportToCsv(columns, rows, filename, currency));
|
|
41
|
+
const handleExcel = () => withRows(async (rows) => {
|
|
42
|
+
const { exportToExcel } = await import('./excel-NKWJ2AMC.js');
|
|
43
|
+
await exportToExcel(columns, rows, filename, currency);
|
|
44
|
+
});
|
|
45
|
+
const handlePdf = () => withRows(async (rows) => {
|
|
46
|
+
const { exportToPdf } = await import('./pdf-H73MJGB6.js');
|
|
47
|
+
await exportToPdf(columns, rows, filename, { title, currency });
|
|
48
|
+
});
|
|
49
|
+
return /* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
50
|
+
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(ToolbarAction, { icon: Download, caret: true, disabled: busy, children: t("reports.export") }) }),
|
|
51
|
+
/* @__PURE__ */ jsxs(DropdownContent, { align: "end", children: [
|
|
52
|
+
/* @__PURE__ */ jsx(DropdownItem, { onClick: handleCsv, children: t("reports.exportCsv") }),
|
|
53
|
+
excelAvailable && /* @__PURE__ */ jsx(DropdownItem, { onClick: handleExcel, children: t("reports.exportExcel") }),
|
|
54
|
+
pdfAvailable && /* @__PURE__ */ jsx(DropdownItem, { onClick: handlePdf, children: t("reports.exportPdf") })
|
|
55
|
+
] })
|
|
56
|
+
] });
|
|
57
|
+
}
|
|
58
|
+
function ReportPagination({ page, pageSize, total, onPageChange, onPageSizeChange }) {
|
|
59
|
+
const t = useTranslation();
|
|
60
|
+
return /* @__PURE__ */ jsx(
|
|
61
|
+
Pagination,
|
|
62
|
+
{
|
|
63
|
+
page,
|
|
64
|
+
pageSize,
|
|
65
|
+
total,
|
|
66
|
+
onPageChange,
|
|
67
|
+
trailing: /* @__PURE__ */ jsxs(Select, { value: String(pageSize), onValueChange: (v) => onPageSizeChange(Number(v)), children: [
|
|
68
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-auto gap-2 bg-card px-2 shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
69
|
+
/* @__PURE__ */ jsx(SelectContent, { children: [25, 50, 100].map((size) => /* @__PURE__ */ jsx(SelectItem, { value: String(size), children: t("reports.pagination.perPage", { size }) }, size)) })
|
|
70
|
+
] })
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
function ViewerBody({ card }) {
|
|
75
|
+
const { labels, currency, defaultRange } = useAnalyticsConfig();
|
|
76
|
+
const { state, setPage, setPageSize, setPreset } = useAnalyticsContext();
|
|
77
|
+
const cardDefaultRange = card.defaultRange;
|
|
78
|
+
React2.useEffect(() => {
|
|
79
|
+
if (!cardDefaultRange) return;
|
|
80
|
+
setPreset(cardDefaultRange);
|
|
81
|
+
return () => setPreset(defaultRange);
|
|
82
|
+
}, [card.id, cardDefaultRange, defaultRange, setPreset]);
|
|
83
|
+
const isStatement = card.viz.type === "statement" && !!card.viz.statement;
|
|
84
|
+
const { result, loading, error, engineMissing } = useAnalyticsCard(card, { enabled: !isStatement });
|
|
85
|
+
const all = useAnalyticsAllRows(card, isStatement && card.available !== false);
|
|
86
|
+
const columns = React2.useMemo(() => cardColumns(card), [card]);
|
|
87
|
+
const expanded = React2.useMemo(
|
|
88
|
+
() => expandBagColumns(columns, result?.rows ?? []),
|
|
89
|
+
[columns, result?.rows]
|
|
90
|
+
);
|
|
91
|
+
const tanstackColumns = React2.useMemo(
|
|
92
|
+
() => reportColumnsToTanstack(expanded.columns, currency.code),
|
|
93
|
+
[expanded.columns, currency.code]
|
|
94
|
+
);
|
|
95
|
+
const rows = expanded.rows;
|
|
96
|
+
if (card.available === false) {
|
|
97
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center", children: [
|
|
98
|
+
/* @__PURE__ */ jsx("div", { className: "mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx(Construction, { className: "h-5 w-5 text-muted-foreground" }) }),
|
|
99
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: labels.unavailableTitle }),
|
|
100
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: labels.unavailableDescription })
|
|
101
|
+
] });
|
|
102
|
+
}
|
|
103
|
+
const hasViz = card.viz.type !== "table" || (card.query.measures?.length ?? 0) > 0;
|
|
104
|
+
if (isStatement && card.viz.statement) {
|
|
105
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
106
|
+
engineMissing ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-muted/40 p-3 text-sm", children: [
|
|
107
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: "Analytics engine not installed" }),
|
|
108
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-0.5 text-muted-foreground", children: [
|
|
109
|
+
"This report aggregates server-side and needs migration 0039 (",
|
|
110
|
+
/* @__PURE__ */ jsx("code", { className: "text-xs", children: "analytics_run" }),
|
|
111
|
+
" + the read models) applied to this project."
|
|
112
|
+
] })
|
|
113
|
+
] }) : error ?? all.error ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error ?? all.error }) : null,
|
|
114
|
+
/* @__PURE__ */ jsx(
|
|
115
|
+
StatementTable,
|
|
116
|
+
{
|
|
117
|
+
rows: all.rows,
|
|
118
|
+
def: card.viz.statement,
|
|
119
|
+
currency,
|
|
120
|
+
formatPeriod: (p) => formatBucket(p, "month"),
|
|
121
|
+
emptyMessage: labels.noResults,
|
|
122
|
+
loading: all.loading
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
] });
|
|
126
|
+
}
|
|
127
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
128
|
+
hasViz ? /* @__PURE__ */ jsx(
|
|
129
|
+
AnalyticsCard,
|
|
130
|
+
{
|
|
131
|
+
card: { ...card, viz: { ...card.viz, height: card.viz.height ?? 280, limit: void 0 } },
|
|
132
|
+
hideOpen: true
|
|
133
|
+
}
|
|
134
|
+
) : null,
|
|
135
|
+
engineMissing ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-muted/40 p-3 text-sm", children: [
|
|
136
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: "Analytics engine not installed" }),
|
|
137
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-0.5 text-muted-foreground", children: [
|
|
138
|
+
"This report aggregates server-side and needs migration 0039 (",
|
|
139
|
+
/* @__PURE__ */ jsx("code", { className: "text-xs", children: "analytics_run" }),
|
|
140
|
+
" + the read models) applied to this project."
|
|
141
|
+
] })
|
|
142
|
+
] }) : error ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }) : null,
|
|
143
|
+
/* @__PURE__ */ jsx("div", { className: "print-flow", children: /* @__PURE__ */ jsx(
|
|
144
|
+
DataTable,
|
|
145
|
+
{
|
|
146
|
+
columns: tanstackColumns,
|
|
147
|
+
data: rows,
|
|
148
|
+
loading,
|
|
149
|
+
skeletonRows: 5,
|
|
150
|
+
emptyMessage: labels.noResults,
|
|
151
|
+
variant: "card",
|
|
152
|
+
compact: true
|
|
153
|
+
}
|
|
154
|
+
) }),
|
|
155
|
+
!loading ? /* @__PURE__ */ jsx("div", { className: "no-print", children: /* @__PURE__ */ jsx(
|
|
156
|
+
ReportPagination,
|
|
157
|
+
{
|
|
158
|
+
page: state.page,
|
|
159
|
+
pageSize: state.pageSize,
|
|
160
|
+
total: result?.total ?? 0,
|
|
161
|
+
onPageChange: setPage,
|
|
162
|
+
onPageSizeChange: setPageSize
|
|
163
|
+
}
|
|
164
|
+
) }) : null
|
|
165
|
+
] });
|
|
166
|
+
}
|
|
167
|
+
function AnalyticsReportViewer({ cardId }) {
|
|
168
|
+
const { labels } = useAnalyticsConfig();
|
|
169
|
+
const cards = useAnalyticsCards();
|
|
170
|
+
const card = cards.find((c) => c.id === decodeURIComponent(cardId ?? ""));
|
|
171
|
+
React2.useEffect(() => {
|
|
172
|
+
if (card) markViewed(card.id);
|
|
173
|
+
}, [card?.id]);
|
|
174
|
+
if (!card) {
|
|
175
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
176
|
+
/* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => navigateAnalytics(REPORTS_BASE), children: [
|
|
177
|
+
/* @__PURE__ */ jsx(ArrowLeft, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
178
|
+
labels.reports
|
|
179
|
+
] }),
|
|
180
|
+
/* @__PURE__ */ jsx("p", { className: "py-12 text-center text-sm text-muted-foreground", children: labels.noResults })
|
|
181
|
+
] });
|
|
182
|
+
}
|
|
183
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
184
|
+
/* @__PURE__ */ jsx(
|
|
185
|
+
SubpageHeader,
|
|
186
|
+
{
|
|
187
|
+
title: card.name,
|
|
188
|
+
description: card.description,
|
|
189
|
+
parentLabel: labels.analytics,
|
|
190
|
+
onBack: () => navigateAnalytics(ANALYTICS_BASE)
|
|
191
|
+
}
|
|
192
|
+
),
|
|
193
|
+
/* @__PURE__ */ jsx(
|
|
194
|
+
AnalyticsControls,
|
|
195
|
+
{
|
|
196
|
+
filters: card.query.filters ?? [],
|
|
197
|
+
showCompare: card.compare !== false,
|
|
198
|
+
className: "no-print",
|
|
199
|
+
actions: /* @__PURE__ */ jsx(ViewerActions, { card })
|
|
200
|
+
}
|
|
201
|
+
),
|
|
202
|
+
/* @__PURE__ */ jsx(ViewerBody, { card })
|
|
203
|
+
] });
|
|
204
|
+
}
|
|
205
|
+
function ViewerActions({ card }) {
|
|
206
|
+
const { currency, labels } = useAnalyticsConfig();
|
|
207
|
+
const closePanel = useToolbarPanelClose();
|
|
208
|
+
const print = React2.useCallback(() => {
|
|
209
|
+
closePanel();
|
|
210
|
+
requestAnimationFrame(() => {
|
|
211
|
+
requestAnimationFrame(() => window.setTimeout(() => window.print(), 120));
|
|
212
|
+
});
|
|
213
|
+
}, [closePanel]);
|
|
214
|
+
const { result } = useAnalyticsCard(card);
|
|
215
|
+
const columns = React2.useMemo(() => cardColumns(card), [card]);
|
|
216
|
+
const fetchAll = useAnalyticsCardRows(card);
|
|
217
|
+
if (!result?.rows?.length) return null;
|
|
218
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
219
|
+
/* @__PURE__ */ jsx(
|
|
220
|
+
ExportDropdown,
|
|
221
|
+
{
|
|
222
|
+
columns,
|
|
223
|
+
data: result.rows,
|
|
224
|
+
fetchAll,
|
|
225
|
+
filename: card.id,
|
|
226
|
+
currency: currency.code,
|
|
227
|
+
title: card.name
|
|
228
|
+
}
|
|
229
|
+
),
|
|
230
|
+
/* @__PURE__ */ jsx(ToolbarAction, { icon: Printer, onClick: print, children: labels.print })
|
|
231
|
+
] });
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export { AnalyticsReportViewer, exportToCsv };
|
|
235
|
+
//# sourceMappingURL=chunk-VGDOKFED.js.map
|
|
236
|
+
//# sourceMappingURL=chunk-VGDOKFED.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/export/csv.ts","../src/components/ExportDropdown.tsx","../src/components/ReportPagination.tsx","../src/views/AnalyticsReportViewer.tsx"],"names":["useTranslation","jsx","jsxs","React","ToolbarAction"],"mappings":"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","file":"chunk-VGDOKFED.js","sourcesContent":["import { exportCSV } from '@fayz-ai/core'\nimport type { CSVColumn } from '@fayz-ai/core'\nimport type { ReportColumnDef } from '../types'\nimport { expandBagColumns, formatValuePlain } from '../lib/columns'\n\nexport function exportToCsv(\n columns: ReportColumnDef[],\n data: Record<string, any>[],\n filename: string,\n currency?: string,\n): void {\n // Uma coluna por resposta de formulário, não um JSON dentro da célula: é o\n // que deixa a planilha ordenável e filtrável por \"Estilo\".\n const { columns: cols, rows } = expandBagColumns(columns, data)\n const visibleCols = cols.filter((c) => c.visible !== false)\n\n const csvColumns: CSVColumn[] = visibleCols.map((col) => ({\n key: col.key,\n label: col.label,\n format: (value: any) => formatValuePlain(value, col, currency),\n }))\n\n exportCSV(csvColumns, rows, filename)\n}\n","import React, { useEffect, useState } from 'react'\nimport { Download } from 'lucide-react'\nimport {\n Dropdown,\n DropdownTrigger,\n DropdownContent,\n DropdownItem,\n ToolbarAction,\n} from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { ReportColumnDef } from '../types'\nimport { exportToCsv } from '../export/csv'\n\ninterface ExportDropdownProps {\n columns: ReportColumnDef[]\n data: Record<string, any>[]\n filename: string\n currency?: string\n title?: string\n /**\n * Fetch the WHOLE result set. The table on screen is one page of 50, and a\n * file holding 50 of 4,000 rows says nothing about being a fragment — so the\n * export asks for everything before it writes. Absent ⇒ the page is exported.\n */\n fetchAll?: () => Promise<Record<string, any>[]>\n}\n\nexport function ExportDropdown({ columns, data, filename, currency, title, fetchAll }: ExportDropdownProps) {\n const t = useTranslation()\n const [excelAvailable, setExcelAvailable] = useState(false)\n const [pdfAvailable, setPdfAvailable] = useState(false)\n const [busy, setBusy] = useState(false)\n\n useEffect(() => {\n import('../export/excel').then((m) => m.isExcelAvailable()).then(setExcelAvailable).catch(() => {})\n import('../export/pdf').then((m) => m.isPdfAvailable()).then(setPdfAvailable).catch(() => {})\n }, [])\n\n // One writer for the three formats: whichever one is picked, the rows come\n // from the same fetch, so a CSV and a PDF of the same report cannot hold\n // different numbers of lines. A failed fetch falls back to the page on\n // screen — a partial file beats a button that does nothing.\n const withRows = async (write: (rows: Record<string, any>[]) => void | Promise<void>) => {\n if (busy) return\n setBusy(true)\n try {\n const rows = fetchAll ? await fetchAll().catch(() => data) : data\n await write(rows.length ? rows : data)\n } finally {\n setBusy(false)\n }\n }\n\n const handleCsv = () => withRows((rows) => exportToCsv(columns, rows, filename, currency))\n\n const handleExcel = () => withRows(async (rows) => {\n const { exportToExcel } = await import('../export/excel')\n await exportToExcel(columns, rows, filename, currency)\n })\n\n const handlePdf = () => withRows(async (rows) => {\n const { exportToPdf } = await import('../export/pdf')\n await exportToPdf(columns, rows, filename, { title, currency })\n })\n\n return (\n <Dropdown>\n <DropdownTrigger asChild>\n {/* Sem contorno, como o resto da barra — ver ToolbarAction. */}\n <ToolbarAction icon={Download} caret disabled={busy}>{t('reports.export')}</ToolbarAction>\n </DropdownTrigger>\n <DropdownContent align=\"end\">\n <DropdownItem onClick={handleCsv}>{t('reports.exportCsv')}</DropdownItem>\n {excelAvailable && (\n <DropdownItem onClick={handleExcel}>{t('reports.exportExcel')}</DropdownItem>\n )}\n {pdfAvailable && (\n <DropdownItem onClick={handlePdf}>{t('reports.exportPdf')}</DropdownItem>\n )}\n </DropdownContent>\n </Dropdown>\n )\n}\n","import React from 'react'\nimport { useTranslation } from '@fayz-ai/core'\nimport { Pagination, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@fayz-ai/ui'\n\ninterface ReportPaginationProps {\n page: number\n pageSize: number\n total: number\n onPageChange: (page: number) => void\n onPageSizeChange: (size: number) => void\n}\n\nexport function ReportPagination({ page, pageSize, total, onPageChange, onPageSizeChange }: ReportPaginationProps) {\n // The product's one pager, with the page-size picker at its right margin.\n const t = useTranslation()\n\n return (\n <Pagination\n page={page}\n pageSize={pageSize}\n total={total}\n onPageChange={onPageChange}\n trailing={(\n <Select value={String(pageSize)} onValueChange={(v) => onPageSizeChange(Number(v))}>\n <SelectTrigger className=\"h-8 w-auto gap-2 bg-card px-2 shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {[25, 50, 100].map((size) => (\n <SelectItem key={size} value={String(size)}>{t('reports.pagination.perPage', { size })}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n />\n )\n}\n","import React from 'react'\nimport { ArrowLeft, Construction, Printer } from 'lucide-react'\nimport {\n Button, SubpageHeader, ToolbarAction, AnalyticsCard, AnalyticsControls,\n useAnalyticsContext, useAnalyticsCard, useAnalyticsCardRows, useAnalyticsAllRows,\n useToolbarPanelClose,\n} from '@fayz-ai/ui'\nimport type { AnalyticsCardDef, AnalyticsRow } from '@fayz-ai/core'\nimport { DataTable, StatementTable, formatBucket } from '@fayz-ai/ui'\nimport { expandBagColumns, reportColumnsToTanstack } from '../lib/columns'\nimport { ExportDropdown } from '../components/ExportDropdown'\nimport { ReportPagination } from '../components/ReportPagination'\nimport type { ReportColumnDef } from '../types'\nimport {\n useAnalyticsConfig, useAnalyticsCards, cardColumns, navigateAnalytics,\n ANALYTICS_BASE, REPORTS_BASE,\n} from './AnalyticsSurface'\nimport { markViewed } from '../lib/lastViewed'\n\n// ---------------------------------------------------------------------------\n// A report, full size.\n//\n// The chart is not decoration bolted onto a table: it is the SAME card that\n// renders as a tile on the overview, given the whole width. Underneath sits the\n// data it was computed from — so \"show me the number\" and \"show me the rows\n// behind the number\" stop being two different features in two different places.\n// ---------------------------------------------------------------------------\n\nfunction ViewerBody({ card }: { card: AnalyticsCardDef }) {\n const { labels, currency, defaultRange } = useAnalyticsConfig()\n const { state, setPage, setPageSize, setPreset } = useAnalyticsContext()\n const cardDefaultRange = (card as AnalyticsCardDef & { defaultRange?: typeof defaultRange }).defaultRange\n React.useEffect(() => {\n if (!cardDefaultRange) return\n setPreset(cardDefaultRange)\n return () => setPreset(defaultRange)\n }, [card.id, cardDefaultRange, defaultRange, setPreset])\n const isStatement = card.viz.type === 'statement' && !!card.viz.statement\n // Same query as the chart above and the export below — the provider\n // de-duplicates them into one round trip.\n // A statement reads the whole set below. Running the paged card query too\n // executed the same heavy DRE twice and made both requests hit the timeout.\n const { result, loading, error, engineMissing } = useAnalyticsCard(card, { enabled: !isStatement })\n // Um demonstrativo lê o CONJUNTO, nunca a página — ver `useAnalyticsAllRows`.\n const all = useAnalyticsAllRows(card, isStatement && card.available !== false)\n\n const columns = React.useMemo(() => cardColumns(card), [card])\n // As respostas do formulário viram COLUNAS de verdade — \"Estilo\", \"Perfil\" —\n // descobertas nas linhas desta página, porque cada campanha pergunta outra\n // coisa e declarar as colunas no card tornaria o próximo formulário\n // invisível. Mesma expansão que a planilha usa, então tela e arquivo mostram\n // as mesmas colunas.\n const expanded = React.useMemo(\n () => expandBagColumns(columns as unknown as ReportColumnDef[], (result?.rows ?? []) as Record<string, any>[]),\n [columns, result?.rows],\n )\n const tanstackColumns = React.useMemo(\n () => reportColumnsToTanstack(expanded.columns, currency.code),\n [expanded.columns, currency.code],\n )\n const rows = expanded.rows\n\n if (card.available === false) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <Construction className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium\">{labels.unavailableTitle}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">{labels.unavailableDescription}</p>\n </div>\n )\n }\n\n // A pure detail listing has nothing to chart — rendering an empty card frame\n // above the table would be chrome pretending to be information.\n const hasViz = card.viz.type !== 'table' || (card.query.measures?.length ?? 0) > 0\n\n // Um demonstrativo JÁ É a tela inteira. Repetir as mesmas linhas embaixo como\n // grade plana daria duas respostas para a mesma pergunta — e a de baixo, sem\n // hierarquia nem totalizadores, é a pior das duas.\n if (isStatement && card.viz.statement) {\n return (\n <>\n {engineMissing ? (\n <div className=\"rounded-lg border bg-muted/40 p-3 text-sm\">\n <p className=\"font-medium\">Analytics engine not installed</p>\n <p className=\"mt-0.5 text-muted-foreground\">\n This report aggregates server-side and needs migration 0039\n (<code className=\"text-xs\">analytics_run</code> + the read models) applied to this project.\n </p>\n </div>\n ) : (error ?? all.error) ? (\n <div className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive\">\n {error ?? all.error}\n </div>\n ) : null}\n <StatementTable\n rows={all.rows}\n def={card.viz.statement}\n currency={currency}\n formatPeriod={(p) => formatBucket(p, 'month')}\n emptyMessage={labels.noResults}\n loading={all.loading}\n />\n </>\n )\n }\n\n return (\n <>\n {hasViz ? (\n <AnalyticsCard\n card={{ ...card, viz: { ...card.viz, height: card.viz.height ?? 280, limit: undefined } }}\n hideOpen\n />\n ) : null}\n\n {engineMissing ? (\n <div className=\"rounded-lg border bg-muted/40 p-3 text-sm\">\n <p className=\"font-medium\">Analytics engine not installed</p>\n <p className=\"mt-0.5 text-muted-foreground\">\n This report aggregates server-side and needs migration 0039\n (<code className=\"text-xs\">analytics_run</code> + the read models) applied to this project.\n </p>\n </div>\n ) : error ? (\n <div className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n\n {/* `print-flow`: sem ele a regra de cartão (`break-inside: avoid`) prende a\n tabela inteira numa página e o resto do relatório não sai no papel. */}\n <div className=\"print-flow\">\n <DataTable\n columns={tanstackColumns}\n data={rows}\n loading={loading}\n skeletonRows={5}\n emptyMessage={labels.noResults}\n variant=\"card\"\n compact\n />\n </div>\n\n {!loading ? (\n <div className=\"no-print\">\n <ReportPagination\n page={state.page}\n pageSize={state.pageSize}\n total={result?.total ?? 0}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </div>\n ) : null}\n </>\n )\n}\n\nexport function AnalyticsReportViewer({ cardId }: { cardId?: string }) {\n const { labels } = useAnalyticsConfig()\n const cards = useAnalyticsCards()\n const card = cards.find((c) => c.id === decodeURIComponent(cardId ?? ''))\n\n React.useEffect(() => { if (card) markViewed(card.id) }, [card?.id])\n\n if (!card) {\n return (\n <div className=\"space-y-4\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateAnalytics(REPORTS_BASE)}>\n <ArrowLeft className=\"mr-1.5 h-3.5 w-3.5\" />\n {labels.reports}\n </Button>\n <p className=\"py-12 text-center text-sm text-muted-foreground\">{labels.noResults}</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {/* O título vive na barra da shell, não no corpo. Escrever \"← Relatórios /\n Nome\" aqui E deixar a rota declarar `parentRoute` produzia três\n cabeçalhos empilhados dizendo a mesma coisa. SubpageHeader reivindica a\n barra com o nome do card — que depende de dado e por isso não cabe em\n `route.title`. */}\n {/* A descrição vai para o (i) do breadcrumb, não para um parágrafo aqui.\n Era uma linha inteira entre o nome do relatório e o número que a\n pessoa abriu a tela para ver — lida uma vez, ruído em todas as\n visitas seguintes. No ícone ela continua a um gesto de distância. */}\n <SubpageHeader\n title={card.name}\n description={card.description}\n parentLabel={labels.analytics}\n onBack={() => navigateAnalytics(ANALYTICS_BASE)}\n />\n\n <AnalyticsControls\n filters={card.query.filters ?? []}\n showCompare={card.compare !== false}\n className=\"no-print\"\n actions={<ViewerActions card={card} />}\n />\n\n <ViewerBody card={card} />\n </div>\n )\n}\n\nfunction ViewerActions({ card }: { card: AnalyticsCardDef }) {\n const { currency, labels } = useAnalyticsConfig()\n const closePanel = useToolbarPanelClose()\n // Imprimir a partir de dentro do painel imprimia o PAINEL: `window.print()`\n // congela o documento como ele está, e como está inclui o popover aberto por\n // cima do relatório. Fecha primeiro, deixa o navegador pintar o quadro sem\n // ele, e só então manda imprimir.\n const print = React.useCallback(() => {\n closePanel()\n requestAnimationFrame(() => {\n requestAnimationFrame(() => window.setTimeout(() => window.print(), 120))\n })\n }, [closePanel])\n const { result } = useAnalyticsCard(card)\n const columns = React.useMemo(() => cardColumns(card), [card])\n // O arquivo leva o relatório INTEIRO, não a página de 50 que está na tela:\n // uma planilha com 50 de 4.000 leads não avisa em lugar nenhum que é um\n // pedaço, e é ela que sai por e-mail como se fosse o mês fechado.\n const fetchAll = useAnalyticsCardRows(card)\n if (!result?.rows?.length) return null\n return (\n <>\n <ExportDropdown\n columns={columns as unknown as ReportColumnDef[]}\n data={result.rows as Record<string, unknown>[]}\n fetchAll={fetchAll as () => Promise<Record<string, any>[]>}\n filename={card.id}\n currency={currency.code}\n title={card.name}\n />\n <ToolbarAction icon={Printer} onClick={print}>{labels.print}</ToolbarAction>\n </>\n )\n}\n"]}
|