@firestitch/report 18.1.0 → 18.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. package/app/reports/components/component-list/component-list.component.d.ts +6 -2
  2. package/app/reports/components/report-canvas/report-canvas.component.d.ts +1 -0
  3. package/app/reports/data/report.data.d.ts +1 -0
  4. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +5 -1
  5. package/app/reports/interfaces/report.interface.d.ts +8 -0
  6. package/app/reports/views/report/fs-ai-report.component.d.ts +2 -0
  7. package/esm2022/app/reports/components/component-list/component-list.component.mjs +69 -14
  8. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +19 -2
  9. package/esm2022/app/reports/data/report.data.mjs +10 -1
  10. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +30 -6
  11. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  12. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +42 -4
  13. package/esm2022/app/reports/views/report/report.component.mjs +11 -2
  14. package/fesm2022/{firestitch-report-echarts-DPeQc3Lq.mjs → firestitch-report-echarts-Id_HJuQO.mjs} +2 -2
  15. package/fesm2022/{firestitch-report-echarts-DPeQc3Lq.mjs.map → firestitch-report-echarts-Id_HJuQO.mjs.map} +1 -1
  16. package/fesm2022/{firestitch-report-firestitch-report-BSGrWdzK.mjs → firestitch-report-firestitch-report-CfSwIwzw.mjs} +175 -27
  17. package/fesm2022/firestitch-report-firestitch-report-CfSwIwzw.mjs.map +1 -0
  18. package/fesm2022/firestitch-report.mjs +1 -1
  19. package/package.json +2 -2
  20. package/fesm2022/firestitch-report-firestitch-report-BSGrWdzK.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"firestitch-report-firestitch-report-BSGrWdzK.mjs","sources":["../../src/app/reports/data/report.data.ts","../../src/app/reports/layout.ts","../../src/app/reports/interfaces/report.interface.ts","../../src/app/reports/report-filter-items.ts","../../src/app/reports/services/report-filter-state.service.ts","../../src/app/reports/option-builder.ts","../../src/app/reports/components/component-chart/component-chart.component.ts","../../src/app/reports/components/component-chart/component-chart.component.html","../../src/app/reports/format.ts","../../src/app/reports/components/component-kpi/component-kpi.component.ts","../../src/app/reports/components/component-kpi/component-kpi.component.html","../../src/app/reports/components/component-list/component-list.component.ts","../../src/app/reports/components/component-list/component-list.component.html","../../src/app/reports/components/report-component/report-component.component.ts","../../src/app/reports/components/report-component/report-component.component.html","../../src/app/reports/components/report-canvas/report-canvas.component.ts","../../src/app/reports/components/report-canvas/report-canvas.component.html","../../src/app/reports/dialogs/component-settings/component-settings.component.ts","../../src/app/reports/dialogs/component-settings/component-settings.component.html","../../src/app/reports/components/timezone-select/timezone-select.component.ts","../../src/app/reports/components/timezone-select/timezone-select.component.html","../../src/app/reports/dialogs/report-settings/report-settings-default.ts","../../src/app/reports/dialogs/report-settings/report-settings.component.ts","../../src/app/reports/dialogs/report-settings/report-settings.component.html","../../src/app/reports/export/report-export-collector.service.ts","../../src/app/reports/export/offscreen-chart.ts","../../src/app/reports/export/report-pdf.service.ts","../../src/app/reports/theme/palette.ts","../../src/app/reports/export/report-pptx.service.ts","../../src/app/reports/export/report-export.service.ts","../../src/app/reports/services/report.service.ts","../../src/app/reports/views/report/report.component.ts","../../src/app/reports/views/report/report.component.html","../../src/app/reports/dialogs/instruction-history/instruction-history.component.ts","../../src/app/reports/dialogs/instruction-history/instruction-history.component.html","../../src/app/reports/dialogs/global-settings/components/ai-knowledge/ai-knowledge.component.ts","../../src/app/reports/dialogs/global-settings/components/ai-knowledge/ai-knowledge.component.html","../../src/app/reports/dialogs/global-settings/components/general/general.component.ts","../../src/app/reports/dialogs/global-settings/components/general/general.component.html","../../src/app/reports/dialogs/entity-functions/entity-functions.component.ts","../../src/app/reports/dialogs/entity-functions/entity-functions.component.html","../../src/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.ts","../../src/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.html","../../src/app/reports/dialogs/global-settings/global-settings.component.ts","../../src/app/reports/dialogs/global-settings/global-settings.component.html","../../src/app/reports/views/reports/fs-ai-reports.component.ts","../../src/app/reports/views/reports/fs-ai-reports.component.html","../../src/app/reports/views/report/fs-ai-report.component.ts","../../src/app/reports/views/report/fs-ai-report.component.html","../../src/public_api.ts","../../src/firestitch-report.ts"],"sourcesContent":["import { Injectable, inject } from '@angular/core';\n\nimport { FsApi, RequestConfig } from '@firestitch/api';\n\nimport { Observable } from 'rxjs';\n\nimport {\n ComponentDataState,\n FilterGroupDefault,\n ReportComponentSql,\n ReportFilterLevel,\n ReportTree,\n ResolvedFilterValue,\n} from '../interfaces/report.interface';\n\n\n// API gateway for the Reports module. Every endpoint hangs off [basePath],\n// which defaults to \"reports\" (the framework reports backend at /api/reports)\n// and can be repointed by the host so the package stays self-contained and portable.\n@Injectable({\n providedIn: 'root',\n})\nexport class ReportData<T = any> {\n private _api = inject(FsApi);\n\n // The API root for every reports endpoint. Defaults to the framework reports\n // context; set it once (e.g. from the host's report page) to mount elsewhere.\n public basePath = 'reports';\n\n // Build an endpoint path under the configured base, e.g. _path() => \"ai/reports\",\n // _path(`${id}/pages`) => \"ai/reports/123/pages\".\n private _path(suffix = ''): string {\n return suffix ? `${this.basePath}/${suffix}` : this.basePath;\n }\n\n public reports(query: any = {}, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(),\n query,\n {\n key: 'reports',\n ...config,\n },\n );\n }\n\n // Both halves of the listing — reports AND the folders they are filed into —\n // from the one GET. No `key`, because the whole payload is the answer here;\n // reports() keeps its 'reports' key for callers that only want the flat list.\n public tree(query: any = {}, config: RequestConfig = {}): Observable<ReportTree> {\n return this._api.get(\n this._path(),\n query,\n config,\n );\n }\n\n public create(name: string, reportFolderId: number = null, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(),\n { name, reportFolderId },\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // File a report under a folder, or pass null to move it to the root. Sent\n // explicitly (never omitted) so the backend can tell \"move to root\" from\n // \"leave the folder alone\".\n public moveReport(reportId: number, reportFolderId: number | null, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path(`${reportId}`),\n { reportFolderId },\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n public createFolder(\n name: string,\n parentReportFolderId: number = null,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path('folders'),\n { name, parentReportFolderId },\n {\n key: 'folder',\n ...config,\n },\n );\n }\n\n // Rename and/or move a folder. Only the keys passed are acted on server-side,\n // so a rename never disturbs the parent and a drag never disturbs the name.\n public updateFolder(\n reportFolderId: number,\n folder: Record<string, unknown>,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`folders/${reportFolderId}`),\n folder,\n {\n key: 'folder',\n ...config,\n },\n );\n }\n\n // A real delete — the backend refuses while the folder still holds a\n // sub-folder or an active report, so there is no undelete counterpart.\n public deleteFolder(reportFolderId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.delete(\n this._path(`folders/${reportFolderId}`),\n {},\n {\n key: 'folder',\n ...config,\n },\n );\n }\n\n public rename(reportId: number, name: string, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path(`${reportId}`),\n { name },\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // Report settings: any subset of { name, pageWidth, pageHeight, layout,\n // styles } — styles carry the report's typographic config (e.g. heading size).\n // The page size is in inches and width/height go together.\n public update(reportId: number, settings: Record<string, unknown>, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path(`${reportId}`),\n settings,\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // Append a blank page to the report; resolves to the new page.\n public addPage(reportId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/pages`),\n {},\n {\n key: 'page',\n ...config,\n },\n );\n }\n\n // Rename one page. An empty name is stored as null server-side, which puts\n // the tab back on its positional \"Page N\" label.\n public updatePage(\n reportId: number,\n pageId: number,\n name: string,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/pages/${pageId}`),\n { name },\n {\n key: 'page',\n ...config,\n },\n );\n }\n\n // Delete a page and everything on it. Refused server-side for the last\n // remaining page — a report with no canvas is a deleted report, not a page\n // operation.\n public deletePage(reportId: number, pageId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.delete(\n this._path(`${reportId}/pages/${pageId}`),\n {},\n {\n key: 'page',\n ...config,\n },\n );\n }\n\n // Persist the tab order after a drag — the whole list, in its new order, so\n // the sequence stays gapless without the server inferring the move.\n public savePagePositions(\n reportId: number,\n positions: { pageId: number; order: number }[],\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/pages/positions`),\n { positions },\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Component settings: any subset of { title, padding } — the human-facing\n // dialog edits; geometry (x/y/w/h/flowWidth) is persisted via savePositions\n // from the canvas instead.\n public updateComponent(\n reportId: number,\n componentId: number,\n settings: Record<string, unknown>,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/components/${componentId}/settings`),\n settings,\n {\n key: 'component',\n ...config,\n },\n );\n }\n\n // Soft-delete: the report leaves the listing but keeps its pages and\n // components, so undelete() brings back the same document.\n public delete(reportId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.delete(\n this._path(`${reportId}`),\n {},\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // Restore a soft-deleted report through its own action endpoint — the report\n // PUT does not accept `state`.\n public undelete(reportId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/undelete`),\n {},\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // The assembled structure: pages → components (+ their filters) and the\n // report's filter groups.\n public get(reportId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(`${reportId}`),\n {},\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // Persist geometry for the moved components only — any subset of\n // { x, y, w, h } (inches), flowWidth (percent) and order (flow position).\n public savePositions(\n reportId: number,\n positions: ({ componentId: number } & Partial<{ x: number; y: number; w: number; h: number; flowWidth: number; order: number }>)[],\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/components/positions`),\n { positions },\n {\n key: null,\n ...config,\n },\n );\n }\n\n // One component's data. The body carries everything session-scoped: the\n // resolved filter values and the component's own interaction state.\n //\n // `isExport` marks the read as part of a PDF/PowerPoint render. The server\n // gives those a longer per-statement ceiling than an on-screen tile, because\n // a reader watching an export progress bar can wait for a query nobody would\n // tolerate waiting for on a dashboard.\n public componentData(\n reportId: number,\n componentId: number,\n filters: ResolvedFilterValue[] = [],\n state: ComponentDataState = {},\n isExport = false,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/components/${componentId}/data`),\n { filters, state, export: isExport },\n {\n key: 'data',\n ...config,\n },\n );\n }\n\n // Exports the component's FULL filtered dataset to CSV server-side and\n // resolves to a presigned download URL. The backend streams percentage\n // progress while chunking; consume through FsProcess.download.\n public exportComponent(\n reportId: number,\n componentId: number,\n filters: ResolvedFilterValue[] = [],\n state: ComponentDataState = {},\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/components/${componentId}/export`),\n { filters, state },\n {\n key: 'url',\n ...config,\n },\n );\n }\n\n // Exports EVERY component on the report — or on one page — server-side and\n // resolves to a presigned URL for a zip of one CSV per component, foldered by\n // page. `filters` carries the resolved values for every component together;\n // each one picks out its own. Same keep-alive contract as exportComponent,\n // over a longer run; consume through FsProcess.download.\n public exportReport(\n reportId: number,\n filters: ResolvedFilterValue[] = [],\n pageId: number | null = null,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/export`),\n { filters, ...(pageId ? { pageId } : {}) },\n {\n key: 'url',\n ...config,\n },\n );\n }\n\n // Distinct options for a select filter (drives multiselect controls).\n public filterOptions(reportId: number, filterId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(`${reportId}/filters/${filterId}/options`),\n {},\n {\n key: 'options',\n ...config,\n },\n );\n }\n\n // The statement a component runs, for the SQL tab.\n //\n // Fetched rather than read off the component, because a DERIVED component has\n // no stored SQL — it stores a document, and its statement only exists once\n // the backend compiles that document. Compiled per request, for the one\n // component being looked at, so opening a report never pays for it.\n //\n // `key: null` because the whole envelope is the answer here: a stale document\n // comes back as { sql: null, error, errorType } and unwrapping one field\n // would throw the diagnosis away.\n public componentSql(\n reportId: number,\n componentId: number,\n config: RequestConfig = {},\n ): Observable<ReportComponentSql> {\n return this._api.get(\n this._path(`${reportId}/components/${componentId}/sql`),\n {},\n {\n key: null,\n ...config,\n },\n );\n }\n\n // The component SQL's filterable output columns — drives the column picker\n // in the filter UI so a column name is never typed by hand.\n public componentColumns(reportId: number, componentId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(`${reportId}/components/${componentId}/columns`),\n {},\n {\n key: 'columns',\n ...config,\n },\n );\n }\n\n // Make one column filterable. `level` (component | report) places a new\n // group; `groupId` instead links into an existing group. A select filter's\n // options are derived from the component SQL when optionsSql is omitted.\n public addFilter(\n reportId: number,\n componentId: number,\n filter: { filterColumn: string; type?: string; label?: string; level?: string; optionsSql?: string; groupId?: number },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/components/${componentId}/filters`),\n filter,\n {\n key: 'filter',\n ...config,\n },\n );\n }\n\n // Update a filter — any subset of { label, optionsSql, enabled }.\n public updateFilter(\n reportId: number,\n filterId: number,\n changes: { label?: string; optionsSql?: string; enabled?: boolean },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/filters/${filterId}`),\n changes,\n {\n key: 'filter',\n ...config,\n },\n );\n }\n\n // Remove a filter (its group goes too when nothing else uses it).\n public deleteFilter(reportId: number, filterId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.delete(\n this._path(`${reportId}/filters/${filterId}`),\n {},\n {\n key: 'filter',\n ...config,\n },\n );\n }\n\n // The global AI knowledge document (operator-authored agent instructions)\n // and its full version history: { instructions, versions }.\n public instructions(config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path('instructions'),\n {},\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Save a new version of the document (append-only; an unchanged save is a\n // no-op server-side). Resolves to the same { instructions, versions } shape.\n public saveInstructions(content: string, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path('instructions'),\n { content },\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Make an earlier version of the document current (no new row is created).\n public restoreInstruction(instructionId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(`instructions/${instructionId}/restore`),\n {},\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Run a semantic-database build, streamed: emits an event per NDJSON frame\n // ({ kind: 'log', line, percent } feed lines and { kind: 'section' } phase\n // markers) and completes when the build ends. Feed the lines into FsProcess.\n public semanticBuild(config: RequestConfig = {}): Observable<any> {\n return this._api.stream(\n 'POST',\n this._path('semantic/build'),\n { stream: true },\n config,\n );\n }\n\n // Latest build status + entity scoreboard: { build, detail }.\n public semanticBuildStatus(config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path('semantic/build'),\n {},\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Stop the running build (the current semantic database stays in place).\n public semanticBuildStop(config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path('semantic/build/stop'),\n {},\n {\n key: 'build',\n ...config,\n },\n );\n }\n\n // One entity's cached AI-classified code functions — loaded on expand, one\n // entity at a time, because the full set across all entities is far too big\n // to ship inside the scoreboard call.\n public semanticEntityFunctions(entity: string, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(`semantic/entities/${entity}/functions`),\n {},\n {\n key: 'entityFunctions',\n ...config,\n },\n );\n }\n\n // The report module's General settings (semantic-build concurrency + its bounds).\n public settings(config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path('settings'),\n {},\n {\n key: 'settings',\n ...config,\n },\n );\n }\n\n // Save the General settings; resolves to the same { settings } shape.\n public saveSettings(settings: { semanticBuildConcurrency: number }, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path('settings'),\n settings,\n {\n key: 'settings',\n ...config,\n },\n );\n }\n\n // Update a filter group — its exposure level ('component' | 'report' | 'both')\n // and/or its default value (the value seeding the report bar on open). Send\n // `default: null` (or an empty default) to clear it. Only the keys provided\n // are changed.\n public updateFilterGroup(\n reportId: number,\n groupId: number,\n changes: { level?: ReportFilterLevel; default?: FilterGroupDefault | null },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/filtergroups/${groupId}`),\n changes,\n {\n key: 'filterGroup',\n ...config,\n },\n );\n }\n}\n","import { Report, ReportComponent, ReportPage } from './interfaces/report.interface';\n\n\n// Page padding for flow layout, inches — mirrored by the canvas CSS.\nexport const FLOW_PADDING = 0.25;\n\n// Default content padding around a component's body, inches (1/8\").\nexport const DEFAULT_COMPONENT_PADDING = 0.125;\n\n// Default report heading size, points (1/72\"). Applies to component titles.\nexport const DEFAULT_HEADING_SIZE = 16;\n\nexport interface ComponentGeometry {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n// Resolved geometry (inches) for every component on a page, in BOTH layout\n// modes — the single definition the PPT and PDF exports lay out from:\n//\n// Freeform: the stored x/y/w/h verbatim.\n// Flow: components in `order`, each flowWidth% of the content width,\n// wrapping into rows (a row breaks when the next component would\n// exceed 100%); row height = the tallest component in the row.\n// Matches the canvas's flex-wrap rendering.\nexport function pageGeometry(report: Report, page: ReportPage): Map<number, ComponentGeometry> {\n const geometry = new Map<number, ComponentGeometry>();\n\n if (report.layout !== 'flow') {\n for (const component of page.components) {\n geometry.set(component.id, {\n x: component.x, y: component.y, w: component.w, h: component.h,\n });\n }\n\n return geometry;\n }\n\n const contentW = report.pageWidth - FLOW_PADDING * 2;\n const sorted = [...page.components].sort((a, b) => (a.order - b.order) || (a.y - b.y) || (a.x - b.x));\n\n let cursorX = 0; // fraction of contentW consumed in the current row\n let rowTop = FLOW_PADDING;\n let rowHeight = 0;\n\n for (const component of sorted) {\n const fraction = Math.min(100, Math.max(10, component.flowWidth ?? 50)) / 100;\n\n // Wrap when this component doesn't fit the remainder (small tolerance for\n // 33.33+33.33+33.33 style splits).\n if (cursorX + fraction > 1.001) {\n rowTop += rowHeight;\n cursorX = 0;\n rowHeight = 0;\n }\n\n geometry.set(component.id, {\n x: FLOW_PADDING + cursorX * contentW,\n y: rowTop,\n w: fraction * contentW,\n h: component.h,\n });\n\n cursorX += fraction;\n rowHeight = Math.max(rowHeight, component.h);\n }\n\n return geometry;\n}\n\n// Bounds for a page dimension, in inches. Mirrors ReportModel::PAGE_DIMENSION_MIN\n// / MAX on the server, which is the enforcing side — these drive the field-level\n// message so the operator sees the limit before submitting. The ceiling is set by\n// PowerPoint, not by the canvas: ECMA-376 caps a slide at 56 inches, and a .pptx\n// over that is refused on open, so a page is not allowed to be sized past what it\n// can be exported as.\nexport const PAGE_DIMENSION_MIN = 1;\nexport const PAGE_DIMENSION_MAX = 50;\n","// The assembled report structure returned by GET /api/reports/:id — composed\r\n// server-side from the normalized tables (reports → report_pages →\r\n// report_components + report_filters, plus report_filter_groups). All keys are\r\n// camelCase; component `config` is the standard format the renderer maps to\r\n// ECharts options / FsList config.\r\n\r\n// Layout modes: Freeform = absolutely positioned components (drag anywhere);\r\n// Flow = components flow like rows, each taking flowWidth % of the page width.\r\nexport type ReportLayout = 'freeform' | 'flow';\r\n\r\nexport interface Report {\r\n id: number;\r\n name: string;\r\n layout: ReportLayout;\r\n // IANA timezone (e.g. America/New_York) anchoring date filtering + chart date\r\n // bucketing. null falls back to the account zone then UTC (resolved server-side).\r\n timezone: string | null;\r\n // Report-level config: typographic styles, etc. (camelCase JSON column).\r\n config: ReportConfig;\r\n // The page in INCHES (the report's native unit — PDFs and PowerPoint are\r\n // inch-based, so exports are dimensionally exact). Orientation is not a field\r\n // of its own: a page wider than it is tall IS landscape.\r\n pageWidth: number;\r\n pageHeight: number;\r\n pages: ReportPage[];\r\n filterGroups: ReportFilterGroup[];\r\n}\r\n\r\n// Report-level styling. Sizes are in POINTS (1/72\") — the report's typography\r\n// maps 1:1 to PDF (72pt/in) and PowerPoint (point font sizes), so a point\r\n// value is dimensionally exact on screen and in every export.\r\nexport interface ReportConfig {\r\n styles?: ReportStyles;\r\n // The report's group-by control. Optional on the type because a ReportConfig\r\n // literal need not carry it; the API always sends it, resolved.\r\n groupBy?: ReportGroupBy;\r\n}\r\n\r\n// The report's group-by control — the one switch that re-buckets every\r\n// time-series chart on the report between day, week, month, quarter and year.\r\n//\r\n// It is NOT a filter: a filter narrows which rows are counted, this changes how\r\n// the surviving rows are bucketed. It shares the report's filter bar because\r\n// that is the one row of controls a viewer reads a report through — the\r\n// separation that matters is in the model, not in where the control is painted.\r\n//\r\n// Always arrives RESOLVED (the backend fills an absent or partial stored block\r\n// in from its own defaults), so there is nothing to default here — render what\r\n// you are given.\r\nexport interface ReportGroupBy {\r\n enabled: boolean;\r\n label: string;\r\n granularities: ChartGranularity[];\r\n}\r\n\r\nexport interface ReportStyles {\r\n heading?: { size?: number };\r\n}\r\n\r\n// Content padding around a component's body, in INCHES (the geometry unit).\r\nexport interface ComponentPadding {\r\n top?: number;\r\n right?: number;\r\n bottom?: number;\r\n left?: number;\r\n}\r\n\r\nexport interface ReportPage {\r\n id: number;\r\n name: string | null;\r\n order: number;\r\n components: ReportComponent[];\r\n}\r\n\r\nexport type ReportComponentType = 'chart' | 'list' | 'kpi';\r\n\r\nexport interface ReportComponent {\r\n id: number;\r\n type: ReportComponentType;\r\n title: string | null;\r\n // Geometry in INCHES. Freeform: absolute position on the page canvas.\r\n // Flow: only flowWidth/order apply; x/y are remembered for a switch back to\r\n // freeform.\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n // Height mode, DERIVED from type server-side (not stored, read-only): lists\r\n // and KPI tiles are auto (the box sizes to its content, `h` ignored); charts\r\n // are always fixed (use `h`) so they fit the box and never overflow.\r\n autoHeight: boolean;\r\n // Flow layout: % of the page content width this component takes.\r\n flowWidth: number;\r\n // Flow layout ordering.\r\n order: number;\r\n // The stored SQL of a legacy sql-mode component. NULL for a derived one,\r\n // whose statement does not exist until its document is compiled — the SQL tab\r\n // fetches that separately (see ReportComponentSql).\r\n sql: string | null;\r\n config: ChartConfig & ListConfig & KpiConfig & ComponentLayoutConfig & Record<string, unknown>;\r\n filters: ReportFilter[];\r\n}\r\n\r\n// What the SQL tab fetches: the statement a component runs.\r\n//\r\n// For a derived component `baseline` is true and `sql` is what its document\r\n// compiles to with NO viewer state — no filters, UTC, the authored grain. The\r\n// numbers on screen come from that statement plus whatever the viewer picked,\r\n// so the two can legitimately differ and the tab says so rather than implying\r\n// they match.\r\n//\r\n// `error` is not a failure of the request: a document that no longer compiles\r\n// is precisely what someone opens this tab to discover, so it arrives as a\r\n// message to render with `errorType` naming which kind ('stale-query' or\r\n// 'sensitive-column'), and `sql` null.\r\nexport interface ReportComponentSql {\r\n sql: string | null;\r\n origin: 'sql' | 'dbq' | 'derived';\r\n baseline: boolean;\r\n error: string | null;\r\n errorType: string | null;\r\n}\r\n\r\n// Cross-type layout/style keys carried in a component's config (alongside the\r\n// type-specific chart/list/kpi keys).\r\nexport interface ComponentLayoutConfig {\r\n padding?: ComponentPadding;\r\n}\r\n\r\n// The presentation settings a component's settings dialog edits. Neither field\r\n// is part of what the component queries, so a change to them repaints without\r\n// re-running anything.\r\nexport interface ComponentSettings {\r\n title: string;\r\n padding: ComponentPadding;\r\n}\r\n\r\n// Where a chart's legend sits relative to the plot, or 'hidden' to drop it.\r\nexport type LegendPosition = 'top' | 'bottom' | 'left' | 'right' | 'hidden';\r\n\r\nexport type ChartGranularity = 'day' | 'week' | 'month' | 'quarter' | 'year';\r\n\r\n// How each granularity reads in the group-by control and on an export cover\r\n// sheet. WHICH of them a given report offers comes from its ReportGroupBy;\r\n// this is only the naming. 'year' reads as \"Annually\".\r\nexport const GRANULARITY_OPTIONS: { value: ChartGranularity; name: string }[] = [\r\n { value: 'day', name: 'Day' },\r\n { value: 'week', name: 'Week' },\r\n { value: 'month', name: 'Month' },\r\n { value: 'quarter', name: 'Quarter' },\r\n { value: 'year', name: 'Annually' },\r\n];\r\n\r\nexport interface ChartConfig {\r\n chartType?: 'bar' | 'line' | 'area' | 'pie' | 'donut';\r\n // For kind 'time', the server buckets the raw datetime column to `granularity`\r\n // in the report's timezone (the SQL exposes the raw column, unbucketed).\r\n xAxis?: { column: string; kind?: 'category' | 'time'; granularity?: ChartGranularity; label?: string };\r\n measures?: ChartMeasure[];\r\n splitBy?: { column: string; label?: string };\r\n // Single-dimension bar charts only: color each bar by its own category and\r\n // show a legend, WITHOUT splitting into multiple series (which slivers the\r\n // bars). v1 expects colorBy.column === xAxis.column. Ignored when splitBy is\r\n // set or the chart isn't a bar chart.\r\n colorBy?: { column: string; label?: string };\r\n orientation?: 'vertical' | 'horizontal';\r\n stacked?: boolean;\r\n legend?: LegendPosition;\r\n sort?: ReportSort;\r\n limit?: number;\r\n}\r\n\r\nexport interface ChartMeasure {\r\n column: string;\r\n aggregation?: 'sum' | 'count' | 'avg' | 'min' | 'max';\r\n label?: string;\r\n // Applied to a KPI's single value only — it is aggregated server-side after\r\n // the SQL runs, so the SQL cannot format it. Chart measures stay numeric.\r\n format?: 'number' | 'percent' | 'currency';\r\n // How many decimal places the value is shown to. Fixed rather than maximum:\r\n // a column of rates is unreadable when each one shows a different number of\r\n // decimals. Omitted leaves the locale's own default, which is what every\r\n // report authored before this did.\r\n //\r\n // It cannot be applied in the SQL: the value is aggregated after the report's\r\n // filters run, so pre-rounding would break live re-filtering by date range or\r\n // partner.\r\n precision?: number;\r\n}\r\n\r\nexport interface ListConfig {\r\n // A list cell renders the value verbatim: percent signs, currency symbols,\r\n // thousands separators and decimal places are produced by the component's\r\n // SQL (the backend rejects any other `format` here). `date` is the exception\r\n // — a date column stays a RAW timestamp so the report timezone and its\r\n // dateRange filters keep working, and the viewer localises it at render.\r\n // A SQL-formatted column is text, so it names `sortColumn`: the raw numeric\r\n // alias the query also outputs, which the server orders by instead.\r\n columns?: { column: string; label?: string; format?: 'date'; sortColumn?: string }[];\r\n sort?: ReportSort;\r\n pageSize?: number;\r\n}\r\n\r\nexport interface KpiConfig {\r\n measure?: ChartMeasure;\r\n}\r\n\r\nexport interface ReportSort {\r\n column: string;\r\n direction?: 'asc' | 'desc';\r\n}\r\n\r\nexport type ReportFilterType = 'dateRange' | 'select' | 'keyword';\r\n\r\n// Where a filter group's control is exposed. A group can be shown on its\r\n// components, in the report bar, or BOTH at once (the two are independent\r\n// toggles in the UI); a column with neither exposed simply has no filter.\r\nexport type ReportFilterLevel = 'component' | 'report' | 'both';\r\n\r\n// One filterable output column of a component's SQL, with the filter interface\r\n// INFERRED from its data (the human never picks the interface — it follows the\r\n// column's type). Drives the Filters tab listing.\r\nexport interface ReportFilterableColumn {\r\n column: string;\r\n type: ReportFilterType;\r\n}\r\n\r\n// Ground truth: one filterable output column ON one component's SQL. Always a\r\n// member of a filter group — the unit that links equivalent filters across\r\n// components and decides where the control renders (component vs report bar).\r\nexport interface ReportFilter {\r\n id: number;\r\n componentId: number;\r\n filterGroupId: number;\r\n filterColumn: string;\r\n label: string | null;\r\n enabled: boolean;\r\n hasOptions: boolean;\r\n config: Record<string, unknown>;\r\n}\r\n\r\n// One choice in a select filter's option list. The value is what the filter\r\n// matches on and gets stored in a saved default — for an entity that is its\r\n// stable id, never its name, so renaming the entity moves the label without\r\n// breaking the default. The label is only ever what the viewer reads.\r\nexport interface ReportFilterOption {\r\n value: unknown;\r\n label: string;\r\n}\r\n\r\nexport interface ReportFilterGroup {\r\n id: number;\r\n label: string | null;\r\n type: ReportFilterType;\r\n level: ReportFilterLevel;\r\n order: number;\r\n config: { default?: FilterGroupDefault } & Record<string, unknown>;\r\n filters: ReportFilter[];\r\n}\r\n\r\n// A filter group's authored default — the value that seeds the report bar on\r\n// every open. Shape follows the group's type: dateRange uses start/end (a fixed\r\n// calendar-day range) or a relative preset; select uses values; keyword uses\r\n// value.\r\nexport interface FilterGroupDefault {\r\n // dateRange relative preset, resolved against \"now\" on every open. One of:\r\n // thisWeek, lastWeek, last7Days, last30Days, last3Months, last6Months,\r\n // last12Months, thisMonth, thisQuarter, thisYear/yearToDate. The week ones\r\n // are whole calendar days, Sunday to Saturday, in the report's timezone.\r\n relative?: string;\r\n start?: string; // dateRange fixed start (yyyy-MM-dd)\r\n end?: string; // dateRange fixed end (yyyy-MM-dd)\r\n values?: unknown[]; // select default picked values\r\n value?: string; // keyword default text\r\n}\r\n\r\n// The session value of a filter group (never persisted): shape depends on the\r\n// group's type.\r\nexport interface FilterGroupValue {\r\n start?: Date | string | null; // dateRange\r\n end?: Date | string | null; // dateRange\r\n values?: unknown[]; // select\r\n value?: string; // keyword\r\n}\r\n\r\n// One resolved filter sent with a component's data request.\r\nexport interface ResolvedFilterValue {\r\n filterId: number;\r\n start?: string;\r\n end?: string;\r\n values?: unknown[];\r\n value?: string;\r\n}\r\n\r\n// Per-component interaction state sent with the data request: lists send\r\n// sort/paging; time-series charts send the grain picked on the report's group-by\r\n// control, which overrides the authored granularity for that request only. The\r\n// wire key stays `frequency` — it is the bucketing frequency the server applies.\r\nexport interface ComponentDataState {\r\n sort?: ReportSort;\r\n page?: number;\r\n pageSize?: number;\r\n frequency?: ChartGranularity;\r\n}\r\n\r\nexport interface ComponentData {\r\n columns: string[];\r\n rows: Record<string, unknown>[];\r\n paging?: { total: number; page: number; pageSize: number };\r\n truncated: boolean;\r\n // The effective time bucket the rows were grouped into (after any group-by\r\n // override), or null for a non-time axis. Drives the compact x-axis labels.\r\n granularity?: ChartGranularity | null;\r\n}\r\n\r\nexport interface ReportListItem {\r\n id: number;\r\n name: string;\r\n modifyDate: string;\r\n state?: ReportState;\r\n // The folder the report is filed under. null is a real, common value — the\r\n // report sits at the root of the listing tree alongside the folders.\r\n //\r\n // Optional like `state` beside it: the backend always sends it, but making it\r\n // required is a breaking type change for every consumer holding a\r\n // ReportListItem literal (fixtures, mocks) and buys nothing — the listing\r\n // reads it as `?? null` either way.\r\n reportFolderId?: number | null;\r\n}\r\n\r\n// One folder in the listing tree — an audience bucket (\"Management\",\r\n// \"Operations\") reports are filed into. Folders nest via parentReportFolderId;\r\n// reports never do, so the tree's only branch nodes are folders.\r\n//\r\n// No state: a folder is only deletable once it is empty, so there is nothing to\r\n// soft-delete and \"Show Deleted\" is a reports-only concept.\r\nexport interface ReportFolder {\r\n id: number;\r\n name: string;\r\n parentReportFolderId: number | null;\r\n}\r\n\r\n// GET /api/reports returns both halves flat; the listing nests them itself.\r\nexport interface ReportTree {\r\n reports: ReportListItem[];\r\n folders: ReportFolder[];\r\n}\r\n\r\nexport enum ReportNodeType {\r\n Folder = 'folder',\r\n Report = 'report',\r\n}\r\n\r\n// One node as fs-tree sees it. Folders and reports share one id space in the\r\n// view, so the ids are prefixed ('f:12' / 'r:34') — `id` is the original,\r\n// per-table id that the API endpoints take.\r\nexport interface ReportNode {\r\n key: string;\r\n id: number;\r\n name: string;\r\n type: ReportNodeType;\r\n // Only ever populated on a folder; a report is always a leaf.\r\n children: ReportNode[];\r\n // Present on report nodes only.\r\n report?: ReportListItem;\r\n}\r\n\r\n// Reports are soft-deletable: a deleted report leaves the listing but keeps its\r\n// pages and components, and the listing's \"Show Deleted\" mode restores it.\r\n// Folders have no equivalent — they are only deletable once empty, so they hard\r\n// delete and there is nothing to restore.\r\nexport enum ReportState {\r\n Active = 'active',\r\n Deleted = 'deleted',\r\n}\r\n\r\nexport const ReportStates = [\r\n { name: 'Active', value: ReportState.Active },\r\n { name: 'Deleted', value: ReportState.Deleted },\r\n];\r\n\r\n// The chat turn flags this context's backend adds (Reports\\AiView).\r\nexport interface ReportChatResponse {\r\n reportChanged?: boolean;\r\n reportRenamed?: boolean;\r\n}\r\n\r\n// One version of the global AI knowledge document — the operator-authored\r\n// markdown appended to the report agent's system instructions on every turn.\r\nexport interface ReportInstruction {\r\n id: number;\r\n content: string;\r\n current: boolean;\r\n createDate: Date;\r\n modifyDate: Date;\r\n accountId: number | null;\r\n accountName: string | null;\r\n}\r\n\r\n// GET/PUT instructions payload: the current version (null until one is\r\n// authored) plus the full history, newest first.\r\nexport interface ReportInstructions {\r\n instructions: ReportInstruction | null;\r\n versions: ReportInstruction[];\r\n}\r\n\r\n// The latest semantic-database build (an ff_processes row) — enough for the\r\n// settings dialog to say what state the build is in and when it last ran.\r\nexport interface SemanticBuild {\r\n id: number;\r\n state: string;\r\n percent: number | string;\r\n message: string;\r\n duration: number;\r\n createDate: Date;\r\n startDate: Date;\r\n endDate: Date;\r\n}\r\n\r\n// A build stage's state on the entity scoreboard: 'done' = built, 'missing' =\r\n// still needs building (a missing stage is unbuilt content, never an error).\r\nexport type SemanticBuildStage = 'done' | 'missing';\r\n\r\n// One enum column of an entity, with the allowed values the build inlined.\r\nexport interface SemanticBuildEnum {\r\n column: string;\r\n values: string[];\r\n}\r\n\r\n// One entity row of the scoreboard (an entity = a table + a model + a\r\n// handler): its table/shape counts, inlined enum values, computed fields, how\r\n// many code functions were cached (split model vs handler), and the per-stage\r\n// built/missing state.\r\n//\r\n// `model`/`handler` are the classes the functions were read from — what a\r\n// reader recognizes the row by, where `key` is what the report AI addresses it\r\n// by in describe_entity / compile_query.\r\nexport interface SemanticBuildEntity {\r\n key: string;\r\n table: string;\r\n model: string | null;\r\n handler: string | null;\r\n columns: number;\r\n relationships: number;\r\n enums: SemanticBuildEnum[];\r\n computedFields: string[];\r\n functionCount: number;\r\n modelFunctionCount: number;\r\n handlerFunctionCount: number;\r\n stages: Record<string, SemanticBuildStage>;\r\n}\r\n\r\n// One standalone code class the build read: domain logic with no table of its\r\n// own (a summary model, a calculation service). The report AI reads its code\r\n// exactly like an entity's, but it can never be queried — there is nothing to\r\n// select from — so it carries no table, columns or relationships.\r\nexport interface SemanticBuildClass {\r\n key: string;\r\n model: string | null;\r\n functionCount: number;\r\n}\r\n\r\n// What the build decided a physical table is. Entity and junction are both\r\n// reachable by the report AI — an entity directly, a junction through the\r\n// many-to-many it bridges. Excluded is not reachable at all.\r\nexport type SemanticTableClassification = 'entity' | 'junction' | 'excluded';\r\n\r\n// One physical table as the build classified it. `reason` answers a single\r\n// question — why can't the report AI see this table? — and is null when it can.\r\n// A junction with a reason bridged nothing, so it is just as invisible as an\r\n// excluded table.\r\nexport interface SemanticBuildTable {\r\n table: string;\r\n classification: SemanticTableClassification;\r\n model: string | null;\r\n reason: string | null;\r\n}\r\n\r\n// The build scoreboard shipped alongside the build status: the summary counts,\r\n// the full breakdown the settings dialog drills into — BOTH kinds of unit the\r\n// build caches, table-backed entities and standalone code classes — and the\r\n// catalog of every table the build saw, so the tab can show what the report AI\r\n// can't see, not just what it can.\r\n//\r\n// `functionCount` spans entities and classes alike: it is the same total the\r\n// build itself reports when it finishes.\r\n//\r\n// `tables` is empty for an artifact built before the catalog existed. Read that\r\n// as \"no catalog\", never as \"nothing was excluded\".\r\nexport interface SemanticBuildDetail {\r\n // Whether the artifact was produced by a build that ran to the end. Read it\r\n // beside `generatedAt`, never instead of it: the structural artifact is\r\n // published BEFORE the AI function pass, so a build whose AI pass failed still\r\n // carries a date and a full set of counts. The date says something was\r\n // written; only this says the build finished writing it.\r\n complete: boolean;\r\n generatedAt: Date | null;\r\n entityCount: number;\r\n classCount: number;\r\n functionCount: number;\r\n entities: SemanticBuildEntity[];\r\n classes: SemanticBuildClass[];\r\n tableCount: number;\r\n junctionCount: number;\r\n unlinkedJunctionCount: number;\r\n excludedCount: number;\r\n tables: SemanticBuildTable[];\r\n}\r\n\r\n// Which class a cached function was read from. An entity's cache splits into\r\n// 'model' and 'handler'; a standalone code class has one group, 'class'.\r\nexport type SemanticFunctionSource = 'model' | 'handler' | 'class';\r\n\r\n// One AI-classified code function from a model, handler or standalone class:\r\n// what kind of logic it is, what it does, and what it produces — the build's\r\n// cached \"what the code does\" knowledge shown in the functions dialog.\r\nexport interface SemanticEntityFunction {\r\n class: string;\r\n method: string;\r\n signature: string;\r\n kind: string;\r\n summary: string;\r\n produces: string;\r\n source: SemanticFunctionSource;\r\n}\r\n\r\n// One entity's cached code-function knowledge, fetched when a functions dialog\r\n// opens (the full set across all entities is too big to ship with the\r\n// scoreboard). One payload serves both dialogs — consumers filter by source.\r\nexport interface SemanticEntityFunctions {\r\n entity: string;\r\n generatedAt: Date | null;\r\n modelClass: string | null;\r\n handlerClass: string | null;\r\n functions: SemanticEntityFunction[];\r\n}\r\n\r\nexport interface SemanticBuildStatus {\r\n build: SemanticBuild | null;\r\n detail: SemanticBuildDetail;\r\n}\r\n\r\n// The report module's General settings (a small global key/value store, the\r\n// reporting counterpart of the app-wide settings). Each value ships with the\r\n// safe band its editor field is bounded to.\r\nexport interface ReportSettings {\r\n // How many summary calls the semantic build runs at once.\r\n semanticBuildConcurrency: number;\r\n semanticBuildConcurrencyMin: number;\r\n semanticBuildConcurrencyMax: number;\r\n}\r\n","import { IFilterConfigItem, ItemType } from '@firestitch/filter';\n\nimport { format, parseISO } from 'date-fns';\n\nimport { Observable, of } from 'rxjs';\nimport { map, shareReplay } from 'rxjs/operators';\n\nimport { ReportData } from './data/report.data';\nimport {\n ChartGranularity, FilterGroupValue, GRANULARITY_OPTIONS, Report, ReportFilterGroup, ReportFilterOption,\n} from './interfaces/report.interface';\n\n\n// A date-range boundary as the picked LOCAL calendar day (no time, no tz).\n// Date-range filters are calendar-day semantics, so the boundary must carry\n// only Y-M-D — never a timezone-bearing instant the backend would shift.\nexport function dateBoundString(value: Date | string | null | undefined): string | undefined {\n if (value instanceof Date) {\n return format(value, 'yyyy-MM-dd');\n }\n\n // Authored/relative defaults arrive as strings already in Y-M-D form;\n // keep just the date portion.\n return value ? String(value).slice(0, 10) : undefined;\n}\n\n\n// A date-range boundary as it should READ on a cover page — the same calendar\n// day dateBoundString() hands the server, so a printed period can never name a\n// different day than the numbers under it were filtered by. Returns null when\n// there is no boundary; the caller supplies its own placeholder.\n//\n// The parse has to be parseISO, not `new Date`: `new Date('2026-05-01')` is UTC\n// midnight, so formatting it anywhere west of UTC prints Apr 30. parseISO reads\n// a bare Y-M-D as LOCAL midnight, which no offset can shift.\nexport function dateBoundLabel(value: Date | string | null | undefined): string | null {\n const bound = dateBoundString(value);\n\n if (!bound) {\n return null;\n }\n\n const date = parseISO(bound);\n\n return Number.isNaN(date.getTime()) ? String(value) : format(date, 'MMM d, yyyy');\n}\n\n\n// Maps a report filter GROUP to an fs-filter config item, and reads fs-filter\n// query values back into per-group FilterGroupValues. Shared by the report-bar\n// fs-filter and the per-component fs-filter so both render through the same\n// library and write into ReportFilterStateService identically. Items are named\n// `g<groupId>` so the query keys map straight back to the group.\n//\n// (Lists keep their own filters in FsList and name items `f<filterId>`; this is\n// the group-keyed path for charts/KPIs and the report bar.)\n\n// The query key fs-filter uses for a group's item(s).\nconst itemName = (group: ReportFilterGroup): string => `g${group.id}`;\n\n// The query key for the report's group-by control. Fixed rather than derived\n// from an id because a report has exactly one — and it is NOT a filter group,\n// so it is read straight off the change query instead of through\n// groupValuesFromQuery. Client-side only: the grain travels to the server as\n// the data request's `state.frequency`.\nexport const GROUP_BY_ITEM = 'groupBy';\n\n// A select group's distinct options, as { name, value } pairs. The server sends\n// { value, label }: the value is what the filter matches on (an entity's stable\n// id) and the label is what the viewer reads — so a renamed entity keeps its id\n// and simply shows its new name here. Options come from the first member filter\n// that declares them — members are the same data point, so any member's list\n// serves the group. The list is fetched once (the server caps it) and replayed\n// (shareReplay), so repeated reads never refetch. Shared by the report-bar\n// select control and the report-settings default picker so the two never drift.\n// Returns an empty list when no member provides options.\nexport function loadGroupOptions(\n group: ReportFilterGroup,\n reportData: ReportData,\n reportId: number,\n): Observable<{ name: string; value: unknown }[]> {\n const optionFilter = (group.filters ?? []).find((member) => member.hasOptions);\n if (!optionFilter) {\n return of([]);\n }\n\n return reportData.filterOptions(reportId, optionFilter.id)\n .pipe(\n map((options: ReportFilterOption[]) => (options ?? [])\n .map((option) => ({ name: option.label, value: option.value }))),\n shareReplay({ bufferSize: 1, refCount: false }),\n );\n}\n\n// Stored filter values (ids) paired back with the labels to show for them.\n// A saved default holds only values, so the names have to be read back off the\n// option list — that indirection is exactly what survives a rename. A value with\n// no matching option (its entity was deleted, so it is no longer listed) falls\n// back to showing the raw value rather than dropping the chip, which would\n// silently widen the filter.\nexport function resolveOptionValues(\n options$: Observable<{ name: string; value: unknown }[]>,\n values: unknown[],\n): Observable<{ name: string; value: unknown }[]> {\n return options$.pipe(map((options) => values.map((value) => {\n const option = options.find((candidate) => String(candidate.value) === String(value));\n\n return { name: option?.name ?? String(value), value };\n })));\n}\n\n// Case-insensitive name filter applied to a loaded option list — the typed\n// keyword has to be matched here because fs-autocomplete renders what we return\n// verbatim.\nexport function matchOptions(\n options$: Observable<{ name: string; value: unknown }[]>,\n keyword?: string,\n): Observable<{ name: string; value: unknown }[]> {\n const term = (keyword ?? '').trim().toLowerCase();\n\n return options$.pipe(map((options) => term\n ? options.filter((option) => option.name.toLowerCase().includes(term))\n : options));\n}\n\n// Build the fs-filter config item for a group, seeding its default from the\n// current session value so authored/relative defaults show selected on open.\nexport function filterItemForGroup(\n group: ReportFilterGroup,\n reportData: ReportData,\n reportId: number,\n initial?: FilterGroupValue,\n): IFilterConfigItem {\n const name = itemName(group);\n const label = group.label || group.filters?.[0]?.filterColumn || '';\n\n switch (group.type) {\n case 'dateRange':\n return {\n name,\n type: ItemType.DateRange,\n label: { from: `${label} From`, to: `${label} To` },\n default: (initial?.start || initial?.end)\n ? { from: initial.start ?? undefined, to: initial.end ?? undefined }\n : undefined,\n };\n\n case 'select': {\n // One shared, replayed option stream so typing never refetches.\n const options$ = loadGroupOptions(group, reportData, reportId);\n const values = initial?.values;\n\n return {\n name,\n type: ItemType.AutoCompleteChips,\n label,\n fetchOnFocus: true,\n values: (keyword?: string) => matchOptions(options$, keyword),\n // Stored values are ids, so the chips can only be named once the option\n // list has loaded — hence the observable form of `default`.\n default: values?.length\n ? () => resolveOptionValues(options$, values)\n : undefined,\n };\n }\n\n case 'keyword':\n default:\n return {\n name,\n type: ItemType.Keyword,\n label,\n default: initial?.value,\n };\n }\n}\n\n// Whether the report has a chart the group-by control can re-bucket. A time\n// x-axis is the whole qualification: the control changes the grain of that\n// axis, and a category axis has no grain to change.\nexport function hasTimeSeriesChart(report: Report | null): boolean {\n return (report?.pages ?? []).some((page) => (page.components ?? []).some((component) =>\n component.type === 'chart' && component.config?.xAxis?.kind === 'time'));\n}\n\n// The grains the report's group-by control offers, named for the viewer. WHICH\n// of them comes from the report; how they read comes from GRANULARITY_OPTIONS.\n// An empty stored list means every grain — the same rule the backend applies.\nfunction groupByOptions(report: Report): { value: ChartGranularity; name: string }[] {\n const granularities = report.config?.groupBy?.granularities ?? [];\n\n return granularities.length\n ? GRANULARITY_OPTIONS.filter((option) => granularities.includes(option.value))\n : GRANULARITY_OPTIONS;\n}\n\n// Whether a grain is one the report's control still offers. A grain it doesn't\n// cannot stay in effect: the agent can narrow the list at any time, and a chart\n// left bucketing at a dropped grain is one the viewer can neither see nor change.\nexport function isGranularityOffered(report: Report, granularity: ChartGranularity | null): boolean {\n return !granularity || groupByOptions(report).some((option) => option.value === granularity);\n}\n\n// The fs-filter config item for the report's group-by control, or null when the\n// report has none to show.\n//\n// It leads the same bar the filters render in, but it is NOT one: a filter\n// narrows WHICH rows are counted, this changes how the surviving rows are\n// BUCKETED — and it comes first because the grain is what a viewer settles\n// before deciding which rows they want.\n// Picking a grain sets a session-wide override that rides along in each chart's\n// data request, so the charts themselves are never rewritten.\nexport function groupByFilterItem(\n report: Report,\n initial?: ChartGranularity | null,\n): IFilterConfigItem | null {\n const groupBy = report.config?.groupBy;\n\n // Only an EXPLICIT false hides the control. An absent block means a report\n // served by a build that predates the control being stored, and every one of\n // those had one — the backend resolves it the same way (ReportGroupBy).\n if (groupBy?.enabled === false || !hasTimeSeriesChart(report)) {\n return null;\n }\n\n const values = groupByOptions(report);\n\n return {\n name: GROUP_BY_ITEM,\n type: ItemType.Select,\n label: groupBy?.label || 'Group By',\n multiple: false,\n values: () => values,\n default: isGranularityOffered(report, initial ?? null) ? (initial ?? undefined) : undefined,\n };\n}\n\n// The group-by control's contribution to the toolbar's fs-filter key. fs-filter\n// reads its config once at init, and the agent can change the control's label\n// or the grains it offers — without those in the key the bar keeps rendering\n// the control it was created with until a full page reload.\nexport function groupBySignature(report: Report | null): string {\n if (!report || !groupByFilterItem(report)) {\n return '';\n }\n\n const groupBy = report.config?.groupBy;\n\n return ['groupBy', groupBy?.label ?? '', (groupBy?.granularities ?? []).join(',')].join(':');\n}\n\n// Read an fs-filter change query into per-group values. Returns one entry per\n// group with the value to store (or null to clear) — callers feed these to\n// ReportFilterStateService.setValue.\nexport function groupValuesFromQuery(\n query: Record<string, any>,\n groups: ReportFilterGroup[],\n): { groupId: number; value: FilterGroupValue | null }[] {\n return groups.map((group) => {\n const name = itemName(group);\n\n if (group.type === 'dateRange') {\n const start = query[`${name}From`];\n const end = query[`${name}To`];\n\n return {\n groupId: group.id,\n value: (start || end) ? { start: start || null, end: end || null } : null,\n };\n }\n\n if (group.type === 'select') {\n const values = selectQueryValues(query[name]);\n\n return { groupId: group.id, value: values.length ? { values } : null };\n }\n\n const keyword = String(query[name] ?? '').trim();\n\n return { groupId: group.id, value: keyword ? { value: keyword } : null };\n });\n}\n\n// fs-filter's AutoCompleteChips serialises a multi-select into ONE query value:\n// the selected values joined by \",\" (its `query` getter does `.map(value).join(',')`).\n// So a 2+ selection arrives as the string \"a,b\", not an array — splitting on \",\"\n// reverses that faithfully. Without this, a multi-select was sent as the single\n// value [\"a,b\"], producing `col IN ('a,b')` server-side, which matches nothing.\nfunction selectQueryValues(raw: unknown): unknown[] {\n if (Array.isArray(raw)) {\n return raw;\n }\n\n if (raw === null || raw === undefined || raw === '') {\n return [];\n }\n\n return String(raw).split(',');\n}\n","import { Injectable } from '@angular/core';\n\nimport { Observable, Subject } from 'rxjs';\nimport { filter as rxFilter } from 'rxjs/operators';\n\nimport {\n endOfWeek, startOfMonth, startOfQuarter, startOfWeek, startOfYear,\n subDays, subMonths, subWeeks,\n} from 'date-fns';\n\nimport {\n ChartGranularity,\n FilterGroupDefault,\n FilterGroupValue,\n Report,\n ReportComponent,\n ReportFilterGroup,\n ResolvedFilterValue,\n} from '../interfaces/report.interface';\nimport { dateBoundString } from '../report-filter-items';\n\n\n// Whether two stored filter-group defaults are the same. Compared on the fields a\n// default can actually carry, so key order in the payload can't read as a change.\nexport function sameDefault(\n a: FilterGroupDefault | null,\n b: FilterGroupDefault | null,\n): boolean {\n if (!a || !b) {\n return !a && !b;\n }\n\n return a.start === b.start\n && a.end === b.end\n && a.value === b.value\n && a.relative === b.relative\n && (a.values ?? []).length === (b.values ?? []).length\n && (a.values ?? []).every((value, index) => value === (b.values ?? [])[index]);\n}\n\n\n// A stable signature for a group's stored default. The report toolbar keys its\n// fs-filter on this, because fs-filter reads its config once at init — without a\n// key change it keeps rendering the values it was created with even after the\n// config behind it has been rebuilt.\nexport function defaultSignature(group: ReportFilterGroup): string {\n const groupDefault = group.config?.default;\n\n if (!groupDefault) {\n return '';\n }\n\n return [\n groupDefault.start ?? '',\n groupDefault.end ?? '',\n groupDefault.value ?? '',\n groupDefault.relative ?? '',\n (groupDefault.values ?? []).join(','),\n ].join('~');\n}\n\n\n// Session filter state for the open report. Filter VALUES are never persisted\n// — this service holds them per filter GROUP (the propagation unit), resolves\n// them into per-component member-filter values for each data request, and\n// notifies the components whose groups changed so only they refetch.\n//\n// Also session-scoped: per-filter enable/disable toggles from a component's\n// filter menu (the `enabled` column is the authored default; a viewer's toggle\n// shouldn't write to the report).\n@Injectable()\nexport class ReportFilterStateService {\n\n private _values = new Map<number, FilterGroupValue>();\n private _groups = new Map<number, ReportFilterGroup>();\n private _sessionDisabled = new Set<number>();\n\n // The report's group-by control: a single session-wide bucket override for all\n // time-series charts. Unset = each chart uses its authored granularity. Never\n // persisted (it dies with this report view), and carried in the data request's\n // `state`, so it propagates through to the PDF/PowerPoint exports too. Named\n // for the `frequency` wire key it travels under, not for the control's label.\n private _frequency: ChartGranularity | null = null;\n private _frequencyChanged$ = new Subject<void>();\n\n // Emits the group id that changed; components listen filtered to their own\n // group ids. null = everything changed (re-init).\n private _changed$ = new Subject<number | null>();\n\n // Seed groups + their defaults when a report loads. Existing session values\n // for still-existing groups survive a structure re-fetch (a chat edit\n // shouldn't reset the viewer's filters) — UNLESS the group's stored default\n // itself changed, which only happens when an operator saved a new default in\n // report settings. That is an explicit instruction to re-seed, so it wins over\n // the surviving session value; without it the bar keeps showing whatever it was\n // first seeded with until a full page reload.\n public init(report: Report): void {\n const previousGroups = this._groups;\n this._groups = new Map<number, ReportFilterGroup>();\n\n const validIds = new Set<number>();\n for (const group of report.filterGroups ?? []) {\n this._groups.set(group.id, group);\n validIds.add(group.id);\n\n const defaultChanged = !sameDefault(\n previousGroups.get(group.id)?.config?.default ?? null,\n group.config?.default ?? null,\n );\n\n if (!this._values.has(group.id) || defaultChanged) {\n const defaultValue = this._defaultValue(group);\n\n if (defaultValue) {\n this._values.set(group.id, defaultValue);\n } else if (defaultChanged) {\n // The default was cleared, so the value it seeded goes with it.\n this._values.delete(group.id);\n }\n }\n }\n\n for (const groupId of [...this._values.keys()]) {\n if (!validIds.has(groupId)) {\n this._values.delete(groupId);\n }\n }\n\n this._changed$.next(null);\n }\n\n public value(groupId: number): FilterGroupValue | undefined {\n return this._values.get(groupId);\n }\n\n public setValue(groupId: number, value: FilterGroupValue | null): void {\n if (value === null) {\n this._values.delete(groupId);\n } else {\n this._values.set(groupId, value);\n }\n\n this._changed$.next(groupId);\n }\n\n // The active group-by grain, or null when the viewer hasn't chosen one.\n public frequency(): ChartGranularity | null {\n return this._frequency;\n }\n\n public setFrequency(frequency: ChartGranularity | null): void {\n this._frequency = frequency;\n this._frequencyChanged$.next();\n }\n\n // Fires whenever the group-by grain changes — every time-series chart listens\n // so it refetches and re-buckets (the override isn't scoped to any filter\n // group, so changesFor() can't carry it).\n public frequencyChanges(): Observable<void> {\n return this._frequencyChanged$.asObservable();\n }\n\n public isFilterDisabled(filterId: number): boolean {\n return this._sessionDisabled.has(filterId);\n }\n\n public toggleFilter(filterId: number, groupId: number): void {\n if (this._sessionDisabled.has(filterId)) {\n this._sessionDisabled.delete(filterId);\n } else {\n this._sessionDisabled.add(filterId);\n }\n\n this._changed$.next(groupId);\n }\n\n // Notifications relevant to ONE component: any change to a group one of its\n // filters belongs to (or a full re-init).\n public changesFor(component: ReportComponent): Observable<number | null> {\n const groupIds = new Set((component.filters ?? []).map((filter) => filter.filterGroupId));\n\n return this._changed$.asObservable()\n .pipe(\n rxFilter((groupId) => groupId === null || groupIds.has(groupId)),\n );\n }\n\n // The group values resolved into this component's member-filter values —\n // what the data request carries. Disabled filters (authored or session) are\n // skipped entirely.\n public resolveForComponent(component: ReportComponent): ResolvedFilterValue[] {\n const resolved: ResolvedFilterValue[] = [];\n\n for (const filter of component.filters ?? []) {\n if (!filter.enabled || this._sessionDisabled.has(filter.id)) {\n continue;\n }\n\n const value = this._values.get(filter.filterGroupId);\n if (!value) {\n continue;\n }\n\n const entry: ResolvedFilterValue = { filterId: filter.id };\n\n if (value.start) {\n entry.start = dateBoundString(value.start);\n }\n if (value.end) {\n entry.end = dateBoundString(value.end);\n }\n if (value.values?.length) {\n entry.values = value.values;\n }\n if (value.value?.trim()) {\n entry.value = value.value.trim();\n }\n\n if (entry.start || entry.end || entry.values || entry.value) {\n resolved.push(entry);\n }\n }\n\n return resolved;\n }\n\n // Every component's resolved values in one array — what a report-level export\n // carries so each file in the archive is filtered exactly as the screen is.\n // Filter ids are unique per component, so the backend picks each component's\n // own out of the pile. A page id narrows it to that page.\n public resolveForReport(report: Report, pageId: number | null = null): ResolvedFilterValue[] {\n const pages = (report.pages ?? [])\n .filter((page) => !pageId || page.id === pageId);\n\n return pages\n .flatMap((page) => (page.components ?? [])\n .flatMap((component) => this.resolveForComponent(component)));\n }\n\n // A group's authored default, mapped to a session value by type. Relative\n // date presets resolve against \"now\" each time the report opens, so a saved\n // \"last 12 months\" stays relative; a fixed range, select values and keyword\n // text seed verbatim.\n private _defaultValue(group: ReportFilterGroup): FilterGroupValue | null {\n const groupDefault = group.config?.default;\n if (!groupDefault) {\n return null;\n }\n\n if (groupDefault.relative) {\n const range = this._relativeRange(groupDefault.relative);\n\n return range ? { start: range.start, end: range.end } : null;\n }\n\n if (groupDefault.start || groupDefault.end) {\n return {\n start: groupDefault.start ?? null,\n end: groupDefault.end ?? null,\n };\n }\n\n if (groupDefault.values?.length) {\n return { values: groupDefault.values };\n }\n\n if (groupDefault.value) {\n return { value: groupDefault.value };\n }\n\n return null;\n }\n\n private _relativeRange(relative: string): { start: Date; end: Date } | null {\n const now = new Date();\n\n switch (relative) {\n // A calendar week, Sunday to Saturday, in whole days — not the rolling\n // seven days `last7Days` gives, which never lines up with the week a\n // partner has already been sent. `lastWeek` is the one a weekly report\n // wants: it ends at endOfWeek rather than at `now`, because the week it\n // names has closed. `thisWeek` follows every other preset here and runs\n // up to now, so it is deliberately a part-finished week.\n case 'thisWeek':\n return { start: startOfWeek(now, { weekStartsOn: 0 }), end: now };\n case 'lastWeek': {\n const previous = subWeeks(now, 1);\n\n return {\n start: startOfWeek(previous, { weekStartsOn: 0 }),\n end: endOfWeek(previous, { weekStartsOn: 0 }),\n };\n }\n case 'last7Days':\n return { start: subDays(now, 7), end: now };\n case 'last30Days':\n return { start: subDays(now, 30), end: now };\n case 'last3Months':\n return { start: subMonths(now, 3), end: now };\n case 'last6Months':\n return { start: subMonths(now, 6), end: now };\n case 'last12Months':\n return { start: subMonths(now, 12), end: now };\n case 'thisMonth':\n return { start: startOfMonth(now), end: now };\n case 'thisQuarter':\n return { start: startOfQuarter(now), end: now };\n case 'thisYear':\n case 'yearToDate':\n return { start: startOfYear(now), end: now };\n default:\n return null;\n }\n }\n}\n","import type { EChartsOption, LegendComponentOption, SeriesOption } from 'echarts';\n\nimport { format, isValid, parseISO } from 'date-fns';\n\nimport { ChartConfig, ChartGranularity, ComponentData, GRANULARITY_OPTIONS, LegendPosition, ReportComponent } from './interfaces/report.interface';\n\n\n// colorBy applies only to single-dimension bar charts, and only when splitBy\n// isn't already driving multiple series: it colors each bar by its category and\n// shows a legend (one series per category, overlapped to full width).\nexport function isColorBy(config: ChartConfig): boolean {\n return !!config.colorBy?.column && !config.splitBy?.column && (config.chartType ?? 'bar') === 'bar';\n}\n\n\n// Categories + named series extracted from a chart component's config + rows —\n// the one pivot (splitBy → series, measures → series) shared by the on-screen\n// ECharts option below AND the PowerPoint export's native chart data, so both\n// media plot identical numbers.\nexport interface ExtractedChartSeries {\n categories: string[];\n series: { name: string; values: (number | null)[] }[];\n}\n\nexport function extractChartSeries(component: ReportComponent, data: ComponentData): ExtractedChartSeries {\n const config = component.config as ChartConfig;\n const xColumn = config.xAxis?.column ?? data.columns[0];\n const splitColumn = config.splitBy?.column;\n // colorBy emits one series per category too (so each bar carries its own\n // color + legend entry), but the bars are overlapped to full width in\n // buildAxisOption rather than laid side-by-side. splitBy wins if both are set.\n const groupColumn = splitColumn || (isColorBy(config) ? config.colorBy?.column : undefined);\n const measures = config.measures?.length\n ? config.measures\n : [{ column: data.columns[data.columns.length - 1] }];\n\n const rawCategories = uniqueValues(data.rows, xColumn);\n const categories = rawCategories.map((category) => String(category ?? '—'));\n const series: ExtractedChartSeries['series'] = [];\n\n if (groupColumn) {\n // One series per group value (splitBy/colorBy), pivoted over the first measure.\n const measure = measures[0];\n for (const groupValue of uniqueValues(data.rows, groupColumn)) {\n const byCategory = new Map<unknown, unknown>();\n for (const row of data.rows) {\n if (row[groupColumn] === groupValue) {\n byCategory.set(row[xColumn], row[measure.column]);\n }\n }\n\n series.push({\n name: String(groupValue ?? '—'),\n values: rawCategories.map((category) => numeric(byCategory.get(category))),\n });\n }\n } else {\n for (const measure of measures) {\n const byCategory = new Map<unknown, unknown>();\n for (const row of data.rows) {\n byCategory.set(row[xColumn], row[measure.column]);\n }\n\n series.push({\n name: measure.label ?? measure.column,\n values: rawCategories.map((category) => numeric(byCategory.get(category))),\n });\n }\n }\n\n return { categories, series };\n}\n\n// The one pure mapping from our standard camelCase chart config + the data\n// endpoint's rows to an ECharts option. Everything visual that isn't in the\n// registered 'report' theme is decided here, so report standards have exactly\n// two homes.\nexport function buildChartOption(component: ReportComponent, data: ComponentData): EChartsOption {\n const config = component.config as ChartConfig;\n const chartType = config.chartType ?? 'bar';\n\n if (chartType === 'pie' || chartType === 'donut') {\n return buildPieOption(component, data, chartType === 'donut');\n }\n\n return buildAxisOption(component, data, chartType);\n}\n\nfunction buildAxisOption(\n component: ReportComponent,\n data: ComponentData,\n chartType: 'bar' | 'line' | 'area',\n): EChartsOption {\n const config = component.config as ChartConfig;\n const extracted = extractChartSeries(component, data);\n const horizontal = config.orientation === 'horizontal';\n const colorBy = isColorBy(config);\n\n // colorBy emits one series per category; overlapping them (barGap -100%) makes\n // each render at the full category-band width — one full-width, distinctly\n // colored bar per category — instead of side-by-side slivers. The layout props\n // are read from the first series of the coordinate system.\n const series: SeriesOption[] = extracted.series.map((extractedSeries, index) =>\n buildSeries(extractedSeries.name, extractedSeries.values, chartType, config.stacked, colorBy && index === 0));\n\n const granularity = bucketGranularity(data);\n const categoryAxis = {\n type: 'category' as const,\n data: extracted.categories,\n name: config.xAxis?.label,\n nameLocation: 'middle' as const,\n nameGap: granularity && spansMultipleYears(extracted.categories) ? 40 : 28,\n ...periodAxisLabel(granularity, extracted.categories),\n };\n const valueAxis = { type: 'value' as const };\n\n const legendPosition = resolveLegendPosition(config, series.length, colorBy);\n\n return {\n grid: axisGrid(legendPosition),\n legend: legendOption(legendPosition),\n // colorBy charts overlap N mostly-null series, so an axis tooltip would list\n // every category; an item tooltip shows just the hovered bar.\n tooltip: { trigger: colorBy ? 'item' : 'axis' },\n xAxis: horizontal ? valueAxis : categoryAxis,\n yAxis: horizontal ? categoryAxis : valueAxis,\n series,\n };\n}\n\n// Default legend placement when the config doesn't pin one: pie charts read\n// best with the slice key beside them (right); axis charts only need a legend\n// to tell multiple series apart, so a single-series chart hides it. An explicit\n// config.legend (including 'hidden') always wins. Shared with the PowerPoint\n// export so both media place the legend identically.\nexport function resolveLegendPosition(config: ChartConfig, seriesCount: number, colorBy = false): LegendPosition {\n if (config.legend) {\n return config.legend;\n }\n\n const pie = config.chartType === 'pie' || config.chartType === 'donut';\n\n // colorBy maps each bar's color to its category, so it needs a legend even\n // though it's a single measure.\n return pie || colorBy || seriesCount > 1 ? (pie ? 'right' : 'top') : 'hidden';\n}\n\nfunction legendOption(position: LegendPosition): LegendComponentOption {\n if (position === 'hidden') {\n return { show: false };\n }\n\n const base: LegendComponentOption = { type: 'scroll' };\n\n switch (position) {\n case 'bottom':\n return { ...base, bottom: 0 };\n case 'left':\n return { ...base, orient: 'vertical', left: 0, top: 'middle' };\n case 'right':\n return { ...base, orient: 'vertical', right: 0, top: 'middle' };\n default:\n return { ...base, top: 0 };\n }\n}\n\n// Reserve plot-edge room on whichever side the legend occupies so it never\n// overlaps the bars/lines; containLabel already accounts for the axis labels.\nfunction axisGrid(position: LegendPosition): EChartsOption['grid'] {\n const base = { left: 8, right: 16, top: 8, bottom: 8, containLabel: true };\n\n switch (position) {\n case 'bottom':\n return { ...base, bottom: 32 };\n case 'left':\n return { ...base, left: 96 };\n case 'right':\n return { ...base, right: 96 };\n case 'hidden':\n return base;\n default:\n return { ...base, top: 32 };\n }\n}\n\nfunction buildSeries(\n name: string,\n values: (number | null)[],\n chartType: 'bar' | 'line' | 'area',\n stacked?: boolean,\n overlap?: boolean,\n): SeriesOption {\n if (chartType === 'bar') {\n return {\n name,\n type: 'bar',\n data: values,\n stack: stacked ? 'total' : undefined,\n barMaxWidth: 48,\n // colorBy: overlap the per-category series so each bar renders full-width.\n ...(overlap ? { barGap: '-100%', barCategoryGap: '20%' } : {}),\n };\n }\n\n return {\n name,\n type: 'line',\n data: values,\n stack: stacked ? 'total' : undefined,\n smooth: true,\n symbolSize: 6,\n areaStyle: chartType === 'area' ? { opacity: 0.25 } : undefined,\n };\n}\n\nfunction buildPieOption(component: ReportComponent, data: ComponentData, donut: boolean): EChartsOption {\n const config = component.config as ChartConfig;\n const extracted = extractChartSeries(component, data);\n const values = extracted.series[0]?.values ?? [];\n const legendPosition = resolveLegendPosition(config, extracted.series.length);\n\n return {\n tooltip: { trigger: 'item' },\n legend: legendOption(legendPosition),\n series: [\n {\n type: 'pie',\n radius: donut ? ['45%', '72%'] : '72%',\n center: pieCenter(legendPosition),\n label: { show: false },\n data: extracted.categories.map((category, index) => ({\n name: category,\n value: values[index] ?? 0,\n })),\n },\n ],\n };\n}\n\n// Nudge the pie off-center toward the opposite edge from its legend so the two\n// don't collide; centered when the legend is hidden.\nfunction pieCenter(position: LegendPosition): [string, string] {\n switch (position) {\n case 'left':\n return ['60%', '50%'];\n case 'right':\n return ['40%', '50%'];\n case 'top':\n return ['50%', '58%'];\n case 'bottom':\n return ['50%', '46%'];\n default:\n return ['50%', '50%'];\n }\n}\n\nfunction uniqueValues(rows: Record<string, unknown>[], column: string): unknown[] {\n const seen = new Set<unknown>();\n const values: unknown[] = [];\n for (const row of rows) {\n const value = row[column];\n if (!seen.has(value)) {\n seen.add(value);\n values.push(value);\n }\n }\n\n return values;\n}\n\nfunction numeric(value: unknown): number | null {\n if (value === null || value === undefined || value === '') {\n return null;\n }\n\n const parsed = Number(value);\n\n return Number.isFinite(parsed) ? parsed : null;\n}\n\n// The effective time bucket the rows were grouped into (from the data endpoint),\n// or null when the x-axis isn't a time axis — gates the compact period labels.\nfunction bucketGranularity(data: ComponentData): ChartGranularity | null {\n return data.granularity && GRANULARITY_OPTIONS.some((option) => option.value === data.granularity)\n ? data.granularity\n : null;\n}\n\n// Whether the period-start categories cross a year boundary. When they don't,\n// the year is pure noise on every label, so it's dropped entirely.\nexport function spansMultipleYears(categories: string[]): boolean {\n const years = new Set<number>();\n for (const category of categories) {\n const date = parseISO(category);\n if (isValid(date)) {\n years.add(date.getFullYear());\n }\n }\n\n return years.size > 1;\n}\n\n// A bucket's period-start split into its primary label and its year. Day/week\n// read as \"May 1\", month as \"May\", quarter as \"Q2\", year as \"2025\". Returns null\n// for a value that isn't a parseable date (left as-is by callers).\nfunction periodLabelParts(value: string, granularity: ChartGranularity): { primary: string; year: string } | null {\n const date = parseISO(value);\n if (!isValid(date)) {\n return null;\n }\n\n const year = String(date.getFullYear());\n switch (granularity) {\n case 'year':\n return { primary: year, year };\n case 'quarter':\n return { primary: `Q${Math.floor(date.getMonth() / 3) + 1}`, year };\n case 'month':\n return { primary: format(date, 'MMMM'), year };\n default: // day, week — the bucket start as a compact \"MMM d\"\n return { primary: format(date, 'MMM d'), year };\n }\n}\n\n// A compact single-line period label (year appended only when the data spans\n// years) — for media that can't do a styled second line, e.g. PowerPoint.\nexport function formatPeriodLabel(value: string, granularity: ChartGranularity, multiYear: boolean): string {\n const parts = periodLabelParts(value, granularity);\n if (!parts) {\n return value;\n }\n\n return multiYear && granularity !== 'year' ? `${parts.primary} ${parts.year}` : parts.primary;\n}\n\n// ECharts category-axis label config for a time bucket: the primary label on\n// line one, and — only when the data spans multiple years — the year on a small\n// gray second line, centered under the tick (year granularity needs no second\n// line, it already is the year). Empty for a non-time axis (labels as-is).\nfunction periodAxisLabel(granularity: ChartGranularity | null, categories: string[]): { axisLabel?: Record<string, unknown> } {\n if (!granularity) {\n return {};\n }\n\n const multiYear = spansMultipleYears(categories);\n\n return {\n axisLabel: {\n formatter: (value: string) => {\n const parts = periodLabelParts(value, granularity);\n if (!parts) {\n return value;\n }\n\n return multiYear && granularity !== 'year'\n ? `${parts.primary}\\n{yr|${parts.year}}`\n : parts.primary;\n },\n rich: { yr: { fontSize: 10, color: '#9aa0a6', lineHeight: 14 } },\n },\n };\n}\n","import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';\n\nimport type { EChartsOption, ECharts } from 'echarts';\nimport { NgxEchartsDirective } from 'ngx-echarts';\n\nimport { ComponentData, ReportComponent } from '../../interfaces/report.interface';\nimport { buildChartOption } from '../../option-builder';\n\n\n// ECharts host for a chart component. Pure rendering: the parent owns the\n// data fetch; this maps (component config, rows) → option and exposes the\n// chart instance for resize + the future image exports (getDataURL needs the\n// canvas renderer registered in theme/echarts.ts).\n@Component({\n selector: 'app-report-component-chart',\n templateUrl: './component-chart.component.html',\n styleUrls: ['./component-chart.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n NgxEchartsDirective,\n ],\n})\nexport class ComponentChartComponent implements OnChanges {\n\n @Input() public component: ReportComponent;\n @Input() public data: ComponentData | null = null;\n\n public options: EChartsOption | null = null;\n\n private _chart: ECharts | null = null;\n\n public ngOnChanges(): void {\n this.options = this.component && this.data\n ? buildChartOption(this.component, this.data)\n : null;\n }\n\n public onChartInit(chart: ECharts): void {\n this._chart = chart;\n }\n\n // Called by the canvas when the box is resized in edit mode.\n public resize(): void {\n this._chart?.resize();\n }\n\n // High-res image for the (later-phase) PPT/PDF exports.\n public getDataURL(pixelRatio = 3): string | null {\n return this._chart?.getDataURL({\n type: 'png',\n pixelRatio,\n backgroundColor: '#ffffff',\n }) ?? null;\n }\n}\n","<div\n class=\"chart-host\"\n echarts\n [options]=\"options ?? {}\"\n [theme]=\"'report'\"\n [autoResize]=\"true\"\n (chartInit)=\"onChartInit($event)\">\n</div>\n","// Measure-value formatting shared by the KPI renderer and the exports — the\n// config's `format` (number | percent | currency) and `precision` mean the same\n// thing on screen, in PowerPoint and in PDF.\n\n// A bare `new Intl.NumberFormat()` defaults to maximumFractionDigits: 3, which\n// is why an unconfigured percentage reads 38.298%. When the measure names a\n// precision it is pinned as BOTH the minimum and the maximum, so a column of\n// rates lines up instead of each value showing however many decimals it happens\n// to need. Undefined leaves the locale default alone, so a report authored\n// before precision existed renders exactly as it did.\nfunction getFractionDigits(precision?: number): Intl.NumberFormatOptions {\n return Number.isFinite(precision)\n ? { minimumFractionDigits: precision, maximumFractionDigits: precision }\n : {};\n}\n\nexport function formatMeasureValue(value: unknown, format?: string, precision?: number): string {\n if (value === null || value === undefined || value === '') {\n return '—';\n }\n\n const numeric = Number(value);\n if (!Number.isFinite(numeric)) {\n return String(value);\n }\n\n const fractionDigits = getFractionDigits(precision);\n\n switch (format) {\n case 'percent':\n return `${new Intl.NumberFormat(undefined, fractionDigits).format(numeric)}%`;\n case 'currency':\n return new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency: 'USD',\n // Whole dollars unless the measure asks for decimals — cents were\n // unrepresentable before, because this was hardcoded to 0.\n maximumFractionDigits: 0,\n ...fractionDigits,\n }).format(numeric);\n default:\n return new Intl.NumberFormat(undefined, fractionDigits).format(numeric);\n }\n}\n","import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';\n\nimport { formatMeasureValue } from '../../format';\nimport { ComponentData, KpiConfig, ReportComponent } from '../../interfaces/report.interface';\n\n\n// A single big number: the component's measure aggregated over all (filtered)\n// rows server-side; this just formats the one cell.\n@Component({\n selector: 'app-report-component-kpi',\n templateUrl: './component-kpi.component.html',\n styleUrls: ['./component-kpi.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n})\nexport class ComponentKpiComponent implements OnChanges {\n\n @Input() public component: ReportComponent;\n @Input() public data: ComponentData | null = null;\n\n public value = '—';\n public label = '';\n\n public ngOnChanges(): void {\n const config = (this.component?.config ?? {}) as KpiConfig;\n this.label = config.measure?.label ?? '';\n\n const row = this.data?.rows?.[0];\n if (!row) {\n this.value = '—';\n\n return;\n }\n\n const column = config.measure?.column ?? Object.keys(row)[0];\n this.value = formatMeasureValue(row[column], config.measure?.format, config.measure?.precision);\n }\n}\n","<div class=\"kpi\">\n <div class=\"kpi-value\">{{ value }}</div>\n @if (label) {\n <div class=\"kpi-label\">{{ label }}</div>\n }\n</div>\n","import { ChangeDetectionStrategy, Component, DestroyRef, Input, OnInit, ViewChild, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { DatePipe } from '@angular/common';\n\nimport { ItemType } from '@firestitch/filter';\nimport { FsListComponent, FsListConfig, FsListModule, PaginationStrategy } from '@firestitch/list';\n\nimport { Observable, map } from 'rxjs';\n\nimport { ReportData } from '../../data/report.data';\nimport {\n ComponentData,\n ComponentDataState,\n ListConfig,\n ReportComponent,\n ReportFilter,\n ReportFilterGroup,\n ReportFilterOption,\n ResolvedFilterValue,\n} from '../../interfaces/report.interface';\nimport { dateBoundString } from '../../report-filter-items';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\n\n\n// A list component: FsList + FsFilter rendered from the component's config and\n// its report_filters rows. The component's own filter bar carries its filters\n// whose group renders at the component level; report-level groups apply\n// through the shared filter-state service and merge into every request.\n// Paging and sorting are pushed into the SQL wrap server-side.\n@Component({\n selector: 'app-report-component-list',\n templateUrl: './component-list.component.html',\n styleUrls: ['./component-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n DatePipe,\n FsListModule,\n ],\n})\nexport class ComponentListComponent implements OnInit {\n\n @Input() public reportId: number;\n @Input() public component: ReportComponent;\n @Input() public groups: Map<number, ReportFilterGroup>;\n\n @ViewChild(FsListComponent)\n public listComponent: FsListComponent;\n\n public listConfig: FsListConfig;\n public columns: { column: string; label?: string; format?: string }[] = [];\n\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _destroyRef = inject(DestroyRef);\n\n public ngOnInit(): void {\n const config = (this.component.config ?? {}) as ListConfig;\n this.columns = config.columns ?? [];\n\n this._initListConfig(config);\n\n // Report-level filter changes that scope this component re-run the list.\n this._filterState.changesFor(this.component)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this.listComponent?.reload());\n }\n\n private _initListConfig(config: ListConfig): void {\n this.listConfig = {\n // Inside a report component the list is a clean data pane — no status\n // bar, no reload button (filter changes already refetch).\n status: false,\n reload: false,\n // Never touch the URL or persist filter/paging state — report filtering\n // is session-only.\n queryParam: false,\n persist: false,\n sort: config.sort\n ? { value: config.sort.column, direction: config.sort.direction ?? 'asc' }\n : undefined,\n // Load-more: the list keeps a fixed, scrollable height and appends the\n // next page in place instead of swapping pages. The button is pinned to\n // the bottom of the scroll pane (see component SCSS).\n //\n // Uses the Offset strategy (offset + limit) rather than Many: in\n // @firestitch/list the pagination template resolves `hasManyStrategy`\n // BEFORE `loadMoreEnabled`, and Many renders a forward-only page pager —\n // so Many would suppress the load-more button entirely. Offset + loadMore\n // is the combination that actually renders and appends. `_fetch` already\n // derives `page` from `offset`, so the server-side wrap is unaffected.\n paging: {\n limit: config.pageSize ?? 25,\n strategy: PaginationStrategy.Offset,\n },\n loadMore: {\n enabled: true,\n label: 'Load more',\n buttonType: 'stroked',\n },\n filters: this._ownFilters().map((filter) => this._filterItem(filter)),\n fetch: (query: any) => this._fetch(query),\n };\n }\n\n // The filters this list renders in its own bar: its report_filters whose\n // group is component-level. Report-level groups render in the report bar.\n private _ownFilters(): ReportFilter[] {\n return (this.component.filters ?? [])\n .filter((filter) => {\n const group = this.groups?.get(filter.filterGroupId);\n\n return filter.enabled && (!group || group.level === 'component' || group.level === 'both');\n });\n }\n\n private _filterItem(filter: ReportFilter): any {\n const group = this.groups?.get(filter.filterGroupId);\n const name = `f${filter.id}`;\n const label = filter.label || group?.label || filter.filterColumn;\n\n switch (group?.type) {\n case 'dateRange':\n return {\n name,\n type: ItemType.DateRange,\n label: [`${label} From`, `${label} To`],\n };\n\n case 'select':\n return {\n name,\n type: ItemType.AutoCompleteChips,\n label,\n // The server sends { value, label }: the filter matches on the value\n // (an entity's stable id) while the viewer reads the label.\n values: () => this._reportData.filterOptions(this.reportId, filter.id)\n .pipe(\n map((options: ReportFilterOption[]) => (options ?? [])\n .map((option) => ({ name: option.label, value: option.value }))),\n ),\n };\n\n case 'keyword':\n default:\n return {\n name,\n type: ItemType.Keyword,\n label,\n };\n }\n }\n\n private _fetch(query: any): Observable<{ data: Record<string, unknown>[]; paging: any }> {\n // Many/load-more sends `offset` + `limit` (not `page`); derive the page so\n // the server-side wrap keeps working unchanged. Page strategy still sends\n // `page` directly.\n const pageSize = query.limit ?? 25;\n const page = query.page\n ?? (query.offset != null ? Math.floor(query.offset / pageSize) + 1 : 1);\n\n const state: ComponentDataState = {\n page,\n pageSize,\n };\n\n const order = String(query.order ?? '');\n if (order) {\n const [column, direction] = order.split(',');\n state.sort = { column, direction: direction === 'desc' ? 'desc' : 'asc' };\n }\n\n // Report-level values from the shared session state, merged with this\n // list's own filter-bar values (own values win per filter).\n const resolved = new Map<number, ResolvedFilterValue>();\n for (const value of this._filterState.resolveForComponent(this.component)) {\n resolved.set(value.filterId, value);\n }\n for (const value of this._barValues(query)) {\n resolved.set(value.filterId, value);\n }\n\n return this._reportData\n .componentData(this.reportId, this.component.id, [...resolved.values()], state)\n .pipe(\n map((data: ComponentData) => ({\n data: data.rows ?? [],\n paging: {\n limit: data.paging?.pageSize ?? state.pageSize,\n records: data.paging?.total ?? (data.rows?.length ?? 0),\n page: data.paging?.page ?? state.page,\n },\n })),\n );\n }\n\n // The list's own FsFilter values, read back out of the fetch query by the\n // `f<filterId>` naming convention.\n private _barValues(query: any): ResolvedFilterValue[] {\n const values: ResolvedFilterValue[] = [];\n\n for (const filter of this._ownFilters()) {\n const group = this.groups?.get(filter.filterGroupId);\n const name = `f${filter.id}`;\n\n if (group?.type === 'dateRange') {\n const from = dateBoundString(query[`${name}From`]);\n const to = dateBoundString(query[`${name}To`]);\n if (from || to) {\n values.push({ filterId: filter.id, start: from, end: to });\n }\n } else if (group?.type === 'select') {\n // fs-filter joins a multi-select into one \"a,b\" string; split it back\n // so each value binds separately (else `col IN ('a,b')` matches nothing).\n const selected = query[name];\n const selectedValues = Array.isArray(selected)\n ? selected\n : (selected ? String(selected).split(',') : []);\n if (selectedValues.length) {\n values.push({ filterId: filter.id, values: selectedValues });\n }\n } else {\n const keyword = String(query[name] ?? '').trim();\n if (keyword) {\n values.push({ filterId: filter.id, value: keyword });\n }\n }\n }\n\n return values;\n }\n}\n","<fs-list [config]=\"listConfig\">\n @for (column of columns; track column.column) {\n <fs-list-column\n [name]=\"column.column\"\n [title]=\"column.label || column.column\"\n [sortable]=\"true\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n @if (column.format === 'date') {\n {{ row[column.column] | date: 'mediumDate' }}\n } @else {\n {{ row[column.column] }}\n }\n </ng-template>\n </fs-list-column>\n }\n</fs-list>\n","import {\r\n ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef,\r\n EventEmitter, HostBinding, Input, NgZone, OnChanges, OnInit, Output, SimpleChanges, ViewChild, inject,\r\n} from '@angular/core';\r\n\r\n\r\nimport { MatIconButton } from '@angular/material/button';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport { MatMenuModule } from '@angular/material/menu';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { FilterConfig, FsFilterModule } from '@firestitch/filter';\r\nimport { FsProcess } from '@firestitch/process';\r\n\r\nimport { Subject, debounceTime } from 'rxjs';\r\n\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\n\r\nimport { ReportData } from '../../data/report.data';\r\nimport {\r\n ComponentData,\r\n ComponentSettings,\r\n ReportComponent as ReportComponentModel,\r\n ReportFilterGroup,\r\n ReportLayout,\r\n} from '../../interfaces/report.interface';\r\nimport { DEFAULT_COMPONENT_PADDING } from '../../layout';\r\nimport { filterItemForGroup, groupValuesFromQuery } from '../../report-filter-items';\r\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\r\nimport { ComponentChartComponent } from '../component-chart/component-chart.component';\r\nimport { ComponentKpiComponent } from '../component-kpi/component-kpi.component';\r\nimport { ComponentListComponent } from '../component-list/component-list.component';\r\nimport { CanvasSnapper, PX_PER_INCH } from '../report-canvas/report-canvas.component';\r\n\r\n\r\n// Freeform resize handles, named by compass direction.\r\nconst HANDLES = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'] as const;\r\ntype Handle = typeof HANDLES[number];\r\n\r\n// Flow width snaps to the useful fractions of a page row.\r\nconst FLOW_WIDTH_STOPS = [25, 33.33, 50, 66.67, 75, 100];\r\n\r\nconst MIN_W = 0.6; // inches\r\nconst MIN_H = 0.4; // inches\r\n\r\n// One component on the page: title bar, the type-specific body (chart | list\r\n// | kpi), a menu (settings, filter toggles, export) — and the editing\r\n// interactions:\r\n//\r\n// Freeform: click selects; the selection frame shows 8 resize handles;\r\n// dragging the body moves with smart alignment guides (via the canvas\r\n// snapper); everything works at any zoom (pixel deltas ÷ zoom·96 → inches).\r\n//\r\n// Flow: dragging reorders (drop position decided by the canvas); the E\r\n// handle resizes flowWidth % (snapping to 25/33/50/66/75/100), the S handle\r\n// resizes height in inches.\r\n//\r\n// Charts and KPIs fetch their own data here; lists fetch inside\r\n// ComponentListComponent through FsList paging.\r\n@Component({\r\n selector: 'app-report-component',\r\n templateUrl: './report-component.component.html',\r\n styleUrls: ['./report-component.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true,\r\n imports: [\r\n MatIcon,\r\n MatIconButton,\r\n MatMenuModule,\r\n MatTooltip,\r\n FsFilterModule,\r\n ComponentChartComponent,\r\n ComponentKpiComponent,\r\n ComponentListComponent,\r\n ],\r\n})\r\nexport class ReportComponentComponent implements OnInit, OnChanges {\r\n\r\n @Input() public reportId: number;\r\n @Input() public component: ReportComponentModel;\r\n @Input() public groups: Map<number, ReportFilterGroup>;\r\n @Input() public editMode = false;\r\n @Input() public layout: ReportLayout = 'freeform';\r\n // The canvas zoom — converts on-screen pixel deltas back to inches.\r\n @Input() public zoom = 1;\r\n @Input() public snapper: CanvasSnapper | null = null;\r\n @Input() public selected = false;\r\n\r\n @Output() public selectComponent = new EventEmitter<number>();\r\n @Output() public positionChanged = new EventEmitter<{ componentId: number } & Record<string, number>>();\r\n @Output() public flowReorder = new EventEmitter<{ componentId: number; clientX: number; clientY: number }>();\r\n @Output() public openSettings = new EventEmitter<ReportComponentModel>();\r\n\r\n @ViewChild(ComponentChartComponent)\r\n public chartComponent: ComponentChartComponent;\r\n\r\n // Freeform resize handles by type: a fixed-height component (chart/list)\r\n // gets all eight (resize width AND height); an auto-height one (kpi) gets\r\n // only the side handles since its height fits its content and can't be set.\r\n public get resizeHandles(): readonly Handle[] {\r\n return this._heightAuto ? ['e', 'w'] : HANDLES;\r\n }\r\n\r\n // The component's header IS an fs-filter: heading template = its title (and\r\n // the drag handle), actions = the Settings / filter-toggles / Export menu,\r\n // items = its component-level filter groups (none for lists — they filter\r\n // through FsList). Rebuilt when a filter toggle changes which groups show.\r\n public filterConfig!: FilterConfig;\r\n\r\n public data: ComponentData | null = null;\r\n public loading = false;\r\n public error: string | null = null;\r\n\r\n private _refresh$ = new Subject<void>();\r\n private _reportData = inject(ReportData);\r\n private _filterState = inject(ReportFilterStateService);\r\n private _process = inject(FsProcess);\r\n private _destroyRef = inject(DestroyRef);\r\n private _cdRef = inject(ChangeDetectorRef);\r\n private _zone = inject(NgZone);\r\n private _host: ElementRef<HTMLElement> = inject(ElementRef);\r\n\r\n public ngOnInit(): void {\r\n this._buildFilterConfig();\r\n\r\n if (this.component.type !== 'list') {\r\n // Debounced so a rapid filter sweep fires one query, not one per change.\r\n this._refresh$\r\n .pipe(\r\n debounceTime(300),\r\n takeUntilDestroyed(this._destroyRef),\r\n )\r\n .subscribe(() => this._load());\r\n\r\n this._filterState.changesFor(this.component)\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe(() => this._refresh$.next());\r\n\r\n // A group-by change re-buckets every time-series chart; it isn't scoped\r\n // to a filter group, so it rides its own stream.\r\n if (this._isTimeSeries) {\r\n this._filterState.frequencyChanges()\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe(() => this._refresh$.next());\r\n }\r\n\r\n this._load();\r\n }\r\n }\r\n\r\n // The report reloads (e.g. after the settings dialog adds/moves a filter)\r\n // hand this instance fresh `component`/`groups` inputs without re-running\r\n // ngOnInit. Rebuild the header config so the inline component-filter strip\r\n // reflects the new filters; the template recreates the fs-filter via\r\n // `filterKey` so it actually re-reads this config.\r\n public ngOnChanges(changes: SimpleChanges): void {\r\n const filtersChanged = (changes.component && !changes.component.firstChange)\r\n || (changes.groups && !changes.groups.firstChange);\r\n\r\n if (filtersChanged) {\r\n this._buildFilterConfig();\r\n }\r\n }\r\n\r\n // fs-filter reads its config only once at init, so the header is keyed on what\r\n // it renders: the set of component-level filter groups AND the title, which\r\n // lives in fs-filter's heading template. fs-filter is OnPush and the heading is\r\n // rendered inside ITS view, so marking this component does not repaint the\r\n // title — recreating the block does.\r\n public get filterKey(): string {\r\n return [\r\n this.component.title,\r\n ...this.componentFilterGroups.map((group) => `${group.id}:${group.level}`),\r\n ].join('|');\r\n }\r\n\r\n public get truncated(): boolean {\r\n return !!this.data?.truncated;\r\n }\r\n\r\n // Content padding (inches → px at 96/in; the canvas zoom scales the page as\r\n // a whole). Each edge defaults to 1/8\".\r\n public get bodyPadding(): string {\r\n const padding = this.component.config?.padding;\r\n const edge = (value: number | undefined) => `${(value ?? DEFAULT_COMPONENT_PADDING) * PX_PER_INCH}px`;\r\n\r\n return `${edge(padding?.top)} ${edge(padding?.right)} ${edge(padding?.bottom)} ${edge(padding?.left)}`;\r\n }\r\n\r\n // The component-level filter groups that should render as an inline control\r\n // strip on THIS component: a group is included when it's level=component and\r\n // has an enabled, session-on filter here. Report-level groups live in the\r\n // top bar instead; lists render their own filters through FsList, so they\r\n // never use this strip.\r\n public get componentFilterGroups(): ReportFilterGroup[] {\r\n if (this.component.type === 'list' || !this.groups) {\r\n return [];\r\n }\r\n\r\n const groupIds = new Set<number>();\r\n for (const filter of this.component.filters ?? []) {\r\n if (!filter.enabled || this._filterState.isFilterDisabled(filter.id)) {\r\n continue;\r\n }\r\n const group = this.groups.get(filter.filterGroupId);\r\n if (group && (group.level === 'component' || group.level === 'both')) {\r\n groupIds.add(group.id);\r\n }\r\n }\r\n\r\n return [...groupIds].map((id) => this.groups.get(id)).filter(Boolean);\r\n }\r\n\r\n public settings(): void {\r\n this.openSettings.emit(this.component);\r\n }\r\n\r\n // Presentation settings saved from the settings dialog. Title and padding are\r\n // not part of the query, so the data already fetched still stands — this only\r\n // repaints. The header config is rebuilt because `filterKey` changes with the\r\n // title and recreates the fs-filter block around it. The chart follows its box\r\n // on its own (ngx-echarts observes the host), so nothing is told to resize.\r\n public applySettings(settings: ComponentSettings): void {\r\n this.component.title = settings.title;\r\n this.component.config = { ...this.component.config, padding: settings.padding };\r\n\r\n this._buildFilterConfig();\r\n this._cdRef.markForCheck();\r\n }\r\n\r\n public exportCsv(): void {\r\n const filters = this._filterState.resolveForComponent(this.component);\r\n\r\n this._process.download(\r\n `Exporting ${this.component.title ?? 'component'}`,\r\n this._reportData.exportComponent(this.reportId, this.component.id, filters),\r\n );\r\n }\r\n\r\n // Any interaction inside a component must never start a canvas pan (the\r\n // zoom-pan host listens for mousedown/touchstart at the container level).\r\n public stopCanvasPan(event: Event): void {\r\n event.stopPropagation();\r\n }\r\n\r\n public onComponentPointerDown(event: PointerEvent): void {\r\n event.stopPropagation();\r\n if (this.editMode && !this.selected) {\r\n this.selectComponent.emit(this.component.id);\r\n }\r\n }\r\n\r\n // ----- edit-mode gestures ---------------------------------------------------\r\n\r\n public onDragStart(event: PointerEvent): void {\r\n if (!this.editMode) {\r\n return;\r\n }\r\n\r\n this.selectComponent.emit(this.component.id);\r\n\r\n if (this.layout === 'flow') {\r\n this._flowDrag(event);\r\n\r\n return;\r\n }\r\n\r\n this._track(event, (deltaX, deltaY) => {\r\n let x = Math.max(0, this._origin.x + this._inches(deltaX));\r\n let y = Math.max(0, this._origin.y + this._inches(deltaY));\r\n\r\n if (this.snapper) {\r\n ({ x, y } = this.snapper.snapMove(this.component, x, y));\r\n }\r\n\r\n this.component.x = x;\r\n this.component.y = y;\r\n this._applyGeometry();\r\n }, () => this._emitGeometry());\r\n }\r\n\r\n public onResizeStart(event: PointerEvent, handle: Handle): void {\r\n if (!this.editMode) {\r\n return;\r\n }\r\n\r\n this.selectComponent.emit(this.component.id);\r\n\r\n if (this.layout === 'flow') {\r\n this._flowResize(event, handle);\r\n\r\n return;\r\n }\r\n\r\n this._track(event, (deltaX, deltaY) => {\r\n const dx = this._inches(deltaX);\r\n const dy = this._inches(deltaY);\r\n let { x, y, w, h } = this._origin;\r\n\r\n if (handle.includes('e')) {\r\n w = Math.max(MIN_W, this._origin.w + dx);\r\n }\r\n if (handle.includes('s')) {\r\n h = Math.max(MIN_H, this._origin.h + dy);\r\n }\r\n if (handle.includes('w')) {\r\n const clamped = Math.min(dx, this._origin.w - MIN_W);\r\n x = this._origin.x + clamped;\r\n w = this._origin.w - clamped;\r\n }\r\n if (handle.includes('n')) {\r\n const clamped = Math.min(dy, this._origin.h - MIN_H);\r\n y = this._origin.y + clamped;\r\n h = this._origin.h - clamped;\r\n }\r\n\r\n let geometry = { x, y, w, h };\r\n if (this.snapper) {\r\n geometry = this.snapper.snapResize(this.component, geometry, handle);\r\n }\r\n\r\n Object.assign(this.component, geometry);\r\n this._applyGeometry();\r\n this.chartComponent?.resize();\r\n }, () => this._emitGeometry());\r\n }\r\n\r\n // (Re)build the header fs-filter config: heading template renders the title\r\n // and items are this component's component-level filter groups. The actions\r\n // menu (Settings / Export CSV) is NOT here — it's a standalone kebab floated\r\n // top-right in the template, so its button height no longer drives the header\r\n // row's height (which would otherwise inflate the heading by ~40px).\r\n private _buildFilterConfig(): void {\r\n this.filterConfig = {\r\n // Never touch the URL or persist filter state — component filters are\r\n // session-only, owned by ReportFilterStateService.\r\n queryParam: false,\r\n persist: false,\r\n items: this.componentFilterGroups.map((group) =>\r\n filterItemForGroup(group, this._reportData, this.reportId, this._filterState.value(group.id))),\r\n change: (query) => {\r\n for (const { groupId, value } of groupValuesFromQuery(query ?? {}, this.componentFilterGroups)) {\r\n this._filterState.setValue(groupId, value);\r\n }\r\n },\r\n };\r\n }\r\n\r\n // Flow: only the east handle resizes (width %). Height is always auto in flow\r\n // (the box fits its content), so there's no south handle here.\r\n private _flowResize(event: PointerEvent, handle: Handle): void {\r\n const pageWidth = this._host.nativeElement.parentElement?.clientWidth || 1;\r\n\r\n this._track(event, (deltaX) => {\r\n if (handle.includes('e')) {\r\n const deltaPercent = (deltaX / this.zoom / pageWidth) * 100;\r\n const raw = Math.min(100, Math.max(10, this._origin.flowWidth + deltaPercent));\r\n this.component.flowWidth = this._snapFlowWidth(raw);\r\n this._host.nativeElement.style.width = `${this.component.flowWidth}%`;\r\n }\r\n }, () => {\r\n this.positionChanged.emit({\r\n componentId: this.component.id,\r\n flowWidth: this.component.flowWidth,\r\n });\r\n });\r\n }\r\n\r\n // Flow: drag lifts the component (ghost) and the canvas decides the drop\r\n // index from the pointer position.\r\n private _flowDrag(event: PointerEvent): void {\r\n const host = this._host.nativeElement;\r\n let lastClientX = event.clientX;\r\n let lastClientY = event.clientY;\r\n\r\n host.classList.add('flow-dragging');\r\n\r\n this._track(event, (deltaX, deltaY, e) => {\r\n lastClientX = e.clientX;\r\n lastClientY = e.clientY;\r\n host.style.transform = `translate(${deltaX / this.zoom}px, ${deltaY / this.zoom}px)`;\r\n }, () => {\r\n host.classList.remove('flow-dragging');\r\n host.style.transform = '';\r\n this.flowReorder.emit({\r\n componentId: this.component.id,\r\n clientX: lastClientX,\r\n clientY: lastClientY,\r\n });\r\n });\r\n }\r\n\r\n private _origin = { x: 0, y: 0, w: 0, h: 0, flowWidth: 50 };\r\n\r\n // Pointer-capture gesture loop: runs outside Angular, repaints imperatively,\r\n // and finishes back inside Angular (selection/persistence).\r\n private _track(\r\n event: PointerEvent,\r\n onMove: (deltaX: number, deltaY: number, e: PointerEvent) => void,\r\n onEnd: () => void,\r\n ): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const handle = event.target as HTMLElement;\r\n handle.setPointerCapture(event.pointerId);\r\n\r\n this._origin = {\r\n x: this.component.x,\r\n y: this.component.y,\r\n w: this.component.w,\r\n h: this.component.h,\r\n flowWidth: this.component.flowWidth ?? 50,\r\n };\r\n const startX = event.clientX;\r\n const startY = event.clientY;\r\n\r\n this._zone.runOutsideAngular(() => {\r\n const move = (e: PointerEvent) => onMove(e.clientX - startX, e.clientY - startY, e);\r\n const end = () => {\r\n handle.releasePointerCapture(event.pointerId);\r\n handle.removeEventListener('pointermove', move);\r\n handle.removeEventListener('pointerup', end);\r\n handle.removeEventListener('pointercancel', end);\r\n\r\n this._zone.run(() => {\r\n this.snapper?.clear();\r\n onEnd();\r\n this._cdRef.markForCheck();\r\n });\r\n };\r\n\r\n handle.addEventListener('pointermove', move);\r\n handle.addEventListener('pointerup', end);\r\n handle.addEventListener('pointercancel', end);\r\n });\r\n }\r\n\r\n private _emitGeometry(): void {\r\n this.component.x = this._round(this.component.x);\r\n this.component.y = this._round(this.component.y);\r\n this.component.w = this._round(Math.max(MIN_W, this.component.w));\r\n this.component.h = this._round(Math.max(MIN_H, this.component.h));\r\n this._applyGeometry();\r\n this.chartComponent?.resize();\r\n\r\n this.positionChanged.emit({\r\n componentId: this.component.id,\r\n x: this.component.x,\r\n y: this.component.y,\r\n w: this.component.w,\r\n h: this.component.h,\r\n });\r\n }\r\n\r\n // A chart on a time x-axis — the only component the report's group-by control\r\n // applies to.\r\n private get _isTimeSeries(): boolean {\r\n return this.component.type === 'chart' && this.component.config?.xAxis?.kind === 'time';\r\n }\r\n\r\n // Auto height (box fits its content) vs fixed (use `h` exactly). Derived from\r\n // type, server-side: KPI tiles are auto; charts and lists are fixed — charts\r\n // fit the box and never overflow, lists scroll inside it.\r\n private get _heightAuto(): boolean {\r\n return this.component.autoHeight !== false;\r\n }\r\n\r\n // Drives the auto-only CSS default (empty-state baseline) so it never applies\r\n // to a fixed-height component.\r\n @HostBinding('class.height-auto')\r\n public get heightAuto(): boolean {\r\n return this._heightAuto;\r\n }\r\n\r\n // Screen pixels → inches at the current zoom.\r\n private _inches(pixels: number): number {\r\n return pixels / (this.zoom * PX_PER_INCH);\r\n }\r\n\r\n // Clean persisted values: hundredths of an inch.\r\n private _round(value: number): number {\r\n return Math.round(value * 100) / 100;\r\n }\r\n\r\n private _snapFlowWidth(value: number): number {\r\n for (const stop of FLOW_WIDTH_STOPS) {\r\n if (Math.abs(value - stop) < 3) {\r\n return stop;\r\n }\r\n }\r\n\r\n return Math.round(value * 10) / 10;\r\n }\r\n\r\n // The canvas positions the host via [style]; mid-gesture we set it directly\r\n // so OnPush never re-renders in the move loop.\r\n private _applyGeometry(): void {\r\n const style = this._host.nativeElement.style;\r\n style.left = `${this.component.x * PX_PER_INCH}px`;\r\n style.top = `${this.component.y * PX_PER_INCH}px`;\r\n style.width = `${this.component.w * PX_PER_INCH}px`;\r\n\r\n // Auto (kpi): no fixed height — the box sizes to its content. Fixed\r\n // (chart/list): `h` is the exact height. Mirrors the canvas [style] binding\r\n // so the mid-gesture paint matches the post-gesture re-render.\r\n if (this._heightAuto) {\r\n style.height = '';\r\n } else {\r\n style.height = `${this.component.h * PX_PER_INCH}px`;\r\n }\r\n }\r\n\r\n // ----- data ----------------------------------------------------------------\r\n\r\n private _load(): void {\r\n this.loading = true;\r\n this.error = null;\r\n this._cdRef.markForCheck();\r\n\r\n const filters = this._filterState.resolveForComponent(this.component);\r\n // Time-series charts carry the group-by grain (if the viewer picked one) so\r\n // the backend re-buckets; everything else sends no interaction state here.\r\n const state = this._isTimeSeries && this._filterState.frequency()\r\n ? { frequency: this._filterState.frequency() }\r\n : {};\r\n\r\n this._reportData.componentData(this.reportId, this.component.id, filters, state)\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe({\r\n next: (data: ComponentData) => {\r\n this.data = data;\r\n this.loading = false;\r\n this._cdRef.markForCheck();\r\n },\r\n error: (error) => {\r\n this.loading = false;\r\n this.error = error?.error?.message ?? error?.message ?? 'Failed to load data';\r\n this._cdRef.markForCheck();\r\n },\r\n });\r\n }\r\n}\r\n","<div\n class=\"component-box\"\n [class.editing]=\"editMode\"\n [class.selected]=\"selected\"\n [style.padding]=\"bodyPadding\"\n (pointerdown)=\"onComponentPointerDown($event)\"\n (mousedown)=\"stopCanvasPan($event)\"\n (touchstart)=\"stopCanvasPan($event)\">\n <!-- The header is an fs-filter: heading template = title (and the edit-mode\n drag handle), actions = the menu, items = component-level filters.\n Lists carry no items here — they filter through FsList. fs-filter reads\n its config once, so the block is keyed on the component-filter set to be\n recreated when it changes. -->\n @for (key of [filterKey]; track key) {\n <fs-filter\n class=\"component-filter\"\n [config]=\"filterConfig\">\n <ng-template fsFilterHeading>\n <div\n class=\"component-title\"\n (pointerdown)=\"onDragStart($event)\">\n {{ component.title }}\n @if (truncated) {\n <mat-icon\n class=\"truncated-icon\"\n matTooltip=\"Showing a truncated result — refine the filters to see everything.\">\n warning_amber\n </mat-icon>\n }\n </div>\n </ng-template>\n </fs-filter>\n }\n <!-- The actions menu is floated top-right (absolute) rather than living in\n fs-filter's actions slot, so its ~40px button height no longer drives the\n header row's height. It overlays the box corner; the heading reserves\n right padding so a long title ellipsises before it. -->\n <button\n mat-icon-button\n class=\"component-menu\"\n [matMenuTriggerFor]=\"menu\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"stopCanvasPan($event)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"settings()\">\n <mat-icon>tune</mat-icon>\n <span>Settings</span>\n </button>\n <button mat-menu-item (click)=\"exportCsv()\">\n <mat-icon>download</mat-icon>\n <span>Export CSV</span>\n </button>\n </mat-menu>\n <div class=\"component-body\">\n @if (component.type === 'list') {\n <app-report-component-list\n [reportId]=\"reportId\"\n [component]=\"component\"\n [groups]=\"groups\">\n </app-report-component-list>\n } @else if (loading) {\n <div class=\"component-state\">\n <div class=\"loading-shimmer\"></div>\n </div>\n } @else if (error) {\n <div class=\"component-state error\">\n {{ error }}\n </div>\n } @else if (!data?.rows?.length) {\n <div class=\"component-state\">\n No data\n </div>\n } @else if (component.type === 'kpi') {\n <app-report-component-kpi\n [component]=\"component\"\n [data]=\"data\">\n </app-report-component-kpi>\n } @else {\n <app-report-component-chart\n [component]=\"component\"\n [data]=\"data\">\n </app-report-component-chart>\n }\n <!-- In edit mode a transparent veil over the body makes the WHOLE\n component draggable (industry standard: you grab the object, not just\n its title bar) and keeps inner widgets from swallowing the gesture. -->\n @if (editMode) {\n <div\n class=\"drag-veil\"\n (pointerdown)=\"onDragStart($event)\">\n </div>\n }\n </div>\n</div>\n<!-- Handles live OUTSIDE the clipped box so they straddle its edges. -->\n@if (editMode && selected) {\n @if (layout === 'freeform') {\n @for (handle of resizeHandles; track handle) {\n <div\n class=\"handle handle-{{ handle }}\"\n (mousedown)=\"stopCanvasPan($event)\"\n (pointerdown)=\"onResizeStart($event, handle)\">\n </div>\n }\n } @else {\n <!-- Flow height is always auto (the box fits its content), so only the\n east handle (width %) is offered here. -->\n <div\n class=\"handle handle-e\"\n matTooltip=\"Width (% of page)\"\n (mousedown)=\"stopCanvasPan($event)\"\n (pointerdown)=\"onResizeStart($event, 'e')\">\n </div>\n }\n}","import {\n AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef,\n ElementRef, EventEmitter, Input, OnChanges, Output, QueryList, ViewChild, ViewChildren, inject,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { MatButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { FsMenuModule } from '@firestitch/menu';\nimport { FsMessage } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsZoomPanComponent, FsZoomPanModule } from '@firestitch/zoom-pan';\n\nimport { map, switchMap } from 'rxjs';\n\nimport { ReportData } from '../../data/report.data';\nimport {\n ComponentSettings, Report, ReportComponent, ReportFilterGroup, ReportPage,\n} from '../../interfaces/report.interface';\nimport { DEFAULT_HEADING_SIZE, FLOW_PADDING } from '../../layout';\nimport { ReportComponentComponent } from '../report-component/report-component.component';\n\n\n// Screen density of the canvas: 96 CSS px per inch (the CSS reference pixel),\n// before zoom. All geometry stays in inches; only rendering multiplies by it.\nexport const PX_PER_INCH = 96;\n\n// One smart guide line, in page inches.\nexport interface GuideLine {\n orientation: 'v' | 'h';\n position: number;\n}\n\n// The snapping contract handed to each component's drag loop. Implemented by\n// the canvas because only it sees every component (alignment candidates) and\n// owns the guides overlay.\nexport interface CanvasSnapper {\n snapMove(component: ReportComponent, x: number, y: number): { x: number; y: number };\n snapResize(component: ReportComponent, geometry: { x: number; y: number; w: number; h: number }, handle: string): { x: number; y: number; w: number; h: number };\n clear(): void;\n}\n\n// The fixed-size page canvas — the PowerPoint model. Pages are tabs (only the\n// ACTIVE page's components exist → only they fetch); the page is a\n// pageWidth×pageHeight INCHES sheet rendered at 96px/in inside fs-zoom-pan\n// (wheel zoom, background drag pan, toolbar buttons).\n//\n// Freeform layout: components are absolutely positioned; dragging gets smart\n// alignment guides (edges + centers of siblings and the page) with snapping.\n// Flow layout: components flow into rows (flowWidth % of the content width),\n// drag reorders, east/south handles resize width%/height.\n@Component({\n selector: 'app-report-canvas',\n templateUrl: './report-canvas.component.html',\n styleUrls: ['./report-canvas.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n DragDropModule,\n MatButton,\n MatIcon,\n MatTooltip,\n FsMenuModule,\n FsZoomPanModule,\n ReportComponentComponent,\n ],\n})\nexport class ReportCanvasComponent implements OnChanges, AfterViewInit {\n\n @Input() public report: Report;\n @Input() public editMode = false;\n\n // The page the host wants on screen, by page id (a deep link). Keyed on id\n // rather than index so a link survives pages being reordered or deleted; an\n // id that no longer resolves falls back to the first page.\n @Input() public pageId: number | null = null;\n\n // A component asked for its settings dialog — the page-level host opens it\n // (it owns MatDialog + the post-save reload).\n @Output() public componentSettings = new EventEmitter<ReportComponent>();\n\n // The report's structure changed here (a page was added) — the host re-fetches\n // it (it owns the assembled report + filter state).\n @Output() public reportChanged = new EventEmitter<void>();\n\n // The viewer dismissed edit mode from the on-canvas badge — the host owns the\n // editMode flag, so it flips it off (mirrors the menu's \"Done editing layout\").\n @Output() public editDone = new EventEmitter<void>();\n\n // The page on screen changed — the host reflects it in the URL so a refresh\n // comes back to the same page. Carries the page id, never the index.\n @Output() public pageChanged = new EventEmitter<number | null>();\n\n @ViewChild(FsZoomPanComponent)\n public zoomPan: FsZoomPanComponent;\n\n // The rendered components of the active page — only the canvas can reach the\n // one instance a settings save applies to.\n @ViewChildren(ReportComponentComponent)\n private _renderedComponents: QueryList<ReportComponentComponent>;\n\n @ViewChild('viewport', { static: true })\n private _viewport: ElementRef<HTMLDivElement>;\n\n @ViewChild('guides', { static: false })\n private _guides: ElementRef<HTMLDivElement>;\n\n public readonly PX = PX_PER_INCH;\n public readonly flowPadding = FLOW_PADDING;\n\n public activePageIndex = 0;\n public zoom = 1;\n public groups = new Map<number, ReportFilterGroup>();\n public selectedComponentId: number | null = null;\n\n // The snapper handed to every component (stable identity for OnPush).\n public readonly snapper: CanvasSnapper = {\n snapMove: (component, x, y) => this._snapMove(component, x, y),\n snapResize: (component, geometry, handle) => this._snapResize(component, geometry, handle),\n clear: () => this._clearGuides(),\n };\n\n private _reportData = inject(ReportData);\n private _prompt = inject(FsPrompt);\n private _message = inject(FsMessage);\n private _cdRef = inject(ChangeDetectorRef);\n private _destroyRef = inject(DestroyRef);\n private _fitted = false;\n private _previousPageCount = 0;\n\n public ngOnChanges(): void {\n this.groups = new Map((this.report?.filterGroups ?? []).map((group) => [group.id, group]));\n\n const pageCount = this.report?.pages?.length ?? 0;\n\n // A page was just added (the host re-fetched the report) — land on it.\n const pageAdded = pageCount > this._previousPageCount && this._previousPageCount > 0;\n if (pageAdded) {\n this.activePageIndex = pageCount - 1;\n }\n this._previousPageCount = pageCount;\n\n // Honour an incoming deep link, but never over a just-added page: adding a\n // page is a deliberate act in this tab, while pageId is the stale value the\n // host is still holding from the URL. An id that does not resolve is left\n // alone rather than forced to the first page — the report may still be\n // loading, and the clamp below is the real guard.\n if (!pageAdded && this.pageId != null) {\n const index = this.report?.pages?.findIndex((page) => page.id === this.pageId) ?? -1;\n\n if (index > -1) {\n this.activePageIndex = index;\n }\n }\n\n if (this.activePageIndex >= pageCount) {\n this.activePageIndex = 0;\n }\n }\n\n // Report heading size in px (config is points; the canvas renders at\n // 96px/in, so points × 96/72). Inherited by component titles via a CSS var.\n public get headingSizePx(): number {\n const points = this.report?.config?.styles?.heading?.size ?? DEFAULT_HEADING_SIZE;\n\n return points * (PX_PER_INCH / 72);\n }\n\n public ngAfterViewInit(): void {\n // Fit the page to the viewport once on first render; after that the\n // viewer's zoom choice is respected across re-renders.\n setTimeout(() => this.zoomFit());\n }\n\n public get isFlow(): boolean {\n return this.report?.layout === 'flow';\n }\n\n public get activePage(): ReportPage | null {\n return this.report?.pages?.[this.activePageIndex] ?? null;\n }\n\n // Flow render order (the assembler already sorts, but a local reorder\n // mid-session must hold without a re-fetch).\n public get flowComponents(): ReportComponent[] {\n return [...(this.activePage?.components ?? [])].sort((a, b) => a.order - b.order);\n }\n\n public selectPage(index: number): void {\n this.activePageIndex = index;\n this.selectedComponentId = null;\n this.pageChanged.emit(this.activePage?.id ?? null);\n }\n\n // Append a blank page; the host re-fetches the report and ngOnChanges lands\n // the view on the new (last) page.\n public addPage(): void {\n if (!this.report) {\n return;\n }\n\n this._reportData.addPage(this.report.id)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this.reportChanged.emit());\n }\n\n public pageLabel(page: ReportPage, index: number): string {\n return page.name || `Page ${index + 1}`;\n }\n\n // Rename from the tab's kebab. The page list is patched in place rather than\n // re-fetching the report: nothing else on the canvas depends on a page's\n // name, and a re-fetch would re-run every component's query to repaint a\n // chip's label.\n public renamePage(page: ReportPage): void {\n this._prompt.input({\n title: 'Edit Page Name',\n label: 'Name',\n default: page.name ?? '',\n commitLabel: 'Save',\n required: true,\n })\n .pipe(\n switchMap((name: string) => this._reportData\n .updatePage(this.report.id, page.id, name)\n .pipe(map(() => name))),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((name: string) => {\n page.name = name;\n this._message.success('Saved page name');\n this._cdRef.markForCheck();\n });\n }\n\n // Delete from the tab's kebab. The confirm names the page and says the\n // components go with it — the server refuses the last page, and that refusal\n // surfaces as the API error message rather than being second-guessed here.\n public deletePage(page: ReportPage): void {\n this._prompt.confirm({\n title: 'Confirm',\n template: `Are you sure you would like to delete \"${this.pageLabel(page, this.report.pages.indexOf(page))}\" and everything on it?`,\n })\n .pipe(\n switchMap(() => this._reportData.deletePage(this.report.id, page.id)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n const index = this.report.pages.indexOf(page);\n this.report.pages.splice(index, 1);\n\n // Land on the neighbour rather than snapping back to the first page —\n // deleting page 4 of 6 should leave you looking at what is now page 4.\n this.activePageIndex = Math.min(index, this.report.pages.length - 1);\n this._previousPageCount = this.report.pages.length;\n this.selectedComponentId = null;\n\n // The id in the URL just stopped existing — replace it with the\n // neighbour we landed on, or a refresh would 404 its way to page one.\n this.pageChanged.emit(this.activePage?.id ?? null);\n\n this._message.success('Deleted page');\n this._cdRef.markForCheck();\n });\n }\n\n // A tab was dragged to a new slot: reorder locally so the chips settle\n // immediately, keep the viewer on the page they were looking at, and persist\n // the whole sequence in one PUT.\n public onPageDropped(event: CdkDragDrop<unknown>): void {\n if (event.previousIndex === event.currentIndex) {\n return;\n }\n\n const activePage = this.activePage;\n\n moveItemInArray(this.report.pages, event.previousIndex, event.currentIndex);\n\n const positions = this.report.pages.map((page, order) => {\n page.order = order;\n\n return { pageId: page.id, order };\n });\n\n this.activePageIndex = activePage\n ? this.report.pages.indexOf(activePage)\n : this.activePageIndex;\n\n this._reportData.savePagePositions(this.report.id, positions)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe();\n }\n\n // Hand presentation settings (title, padding) saved in the settings dialog to\n // the one component they belong to. Nothing here feeds the query, so that\n // component repaints and every other one on the page is left alone.\n public applyComponentSettings(componentId: number, settings: ComponentSettings): void {\n this._renderedComponents\n .find((rendered) => rendered.component.id === componentId)\n ?.applySettings(settings);\n }\n\n public selectComponent(componentId: number | null): void {\n this.selectedComponentId = componentId;\n this._cdRef.markForCheck();\n }\n\n public onCanvasPointerDown(): void {\n // Background click (pan start) deselects.\n if (this.selectedComponentId !== null) {\n this.selectComponent(null);\n }\n }\n\n // ----- zoom toolbar ---------------------------------------------------------\n\n public onZoomed(scale: number): void {\n this.zoom = scale;\n this._cdRef.markForCheck();\n }\n\n public zoomIn(): void {\n this.zoomPan?.zoomIn();\n }\n\n public zoomOut(): void {\n this.zoomPan?.zoomOut();\n }\n\n public zoomFit(): void {\n const viewport = this._viewport?.nativeElement;\n if (!viewport || !this.report?.pageWidth || !this.zoomPan) {\n return;\n }\n\n const fit = Math.min(\n (viewport.clientWidth - 32) / (this.report.pageWidth * PX_PER_INCH),\n (viewport.clientHeight - 32) / (this.report.pageHeight * PX_PER_INCH),\n );\n\n this.zoomPan.zoom(Math.min(1.5, Math.max(0.1, fit)));\n this.zoomPan.move(16, 16);\n this._fitted = true;\n }\n\n public zoomActual(): void {\n this.zoomPan?.zoom(1);\n }\n\n // ----- persistence ----------------------------------------------------------\n\n // A freeform drag/resize or a flow width resize landed — one PUT per gesture.\n public onPositionChanged(position: { componentId: number } & Record<string, number>): void {\n this._clearGuides();\n this._reportData.savePositions(this.report.id, [position as any])\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe();\n }\n\n // A flow drag dropped: reorder the page's components around the moved one\n // and persist every order in one PUT.\n public onFlowReorder(event: { componentId: number; clientX: number; clientY: number }): void {\n const page = this.activePage;\n if (!page) {\n return;\n }\n\n const ordered = this.flowComponents.filter((component) => component.id !== event.componentId);\n const moved = page.components.find((component) => component.id === event.componentId);\n if (!moved) {\n return;\n }\n\n const index = this._flowDropIndex(ordered, event.clientX, event.clientY);\n ordered.splice(index, 0, moved);\n\n const positions = ordered.map((component, order) => {\n component.order = order;\n\n return { componentId: component.id, order };\n });\n\n this._cdRef.markForCheck();\n this._reportData.savePositions(this.report.id, positions)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe();\n }\n\n // Where the pointer landed among the flowed components: before the first\n // component whose center the pointer is above/left of.\n private _flowDropIndex(ordered: ReportComponent[], clientX: number, clientY: number): number {\n const hosts = Array.from(\n this._viewport.nativeElement.querySelectorAll<HTMLElement>('app-report-component'),\n ).filter((host) => !host.classList.contains('flow-dragging'));\n\n for (let index = 0; index < hosts.length && index < ordered.length; index++) {\n const rect = hosts[index].getBoundingClientRect();\n if (clientY < rect.top + rect.height / 2\n || (clientY < rect.bottom && clientX < rect.left + rect.width / 2)) {\n return index;\n }\n }\n\n return ordered.length;\n }\n\n // ----- smart guides ---------------------------------------------------------\n\n // Pixel feel of the snap, converted to inches at the current zoom.\n private get _snapThreshold(): number {\n return 8 / (PX_PER_INCH * Math.max(0.1, this.zoom));\n }\n\n private _snapMove(component: ReportComponent, x: number, y: number): { x: number; y: number } {\n const { vertical, horizontal } = this._candidates(component);\n const guides: GuideLine[] = [];\n\n const snappedX = this._snapAxis(\n [\n { offset: 0, value: x },\n { offset: component.w / 2, value: x + component.w / 2 },\n { offset: component.w, value: x + component.w },\n ],\n vertical,\n );\n if (snappedX !== null) {\n x = snappedX.base;\n guides.push({ orientation: 'v', position: snappedX.guide });\n }\n\n const snappedY = this._snapAxis(\n [\n { offset: 0, value: y },\n { offset: component.h / 2, value: y + component.h / 2 },\n { offset: component.h, value: y + component.h },\n ],\n horizontal,\n );\n if (snappedY !== null) {\n y = snappedY.base;\n guides.push({ orientation: 'h', position: snappedY.guide });\n }\n\n this._renderGuides(guides);\n\n return { x, y };\n }\n\n private _snapResize(\n component: ReportComponent,\n geometry: { x: number; y: number; w: number; h: number },\n handle: string,\n ): { x: number; y: number; w: number; h: number } {\n const { vertical, horizontal } = this._candidates(component);\n const guides: GuideLine[] = [];\n const result = { ...geometry };\n\n // Only the edges the handle moves participate in snapping.\n if (handle.includes('e')) {\n const snapped = this._nearest(geometry.x + geometry.w, vertical);\n if (snapped !== null) {\n result.w = snapped - geometry.x;\n guides.push({ orientation: 'v', position: snapped });\n }\n }\n if (handle.includes('w')) {\n const snapped = this._nearest(geometry.x, vertical);\n if (snapped !== null) {\n result.w = geometry.x + geometry.w - snapped;\n result.x = snapped;\n guides.push({ orientation: 'v', position: snapped });\n }\n }\n if (handle.includes('s')) {\n const snapped = this._nearest(geometry.y + geometry.h, horizontal);\n if (snapped !== null) {\n result.h = snapped - geometry.y;\n guides.push({ orientation: 'h', position: snapped });\n }\n }\n if (handle.includes('n')) {\n const snapped = this._nearest(geometry.y, horizontal);\n if (snapped !== null) {\n result.h = geometry.y + geometry.h - snapped;\n result.y = snapped;\n guides.push({ orientation: 'h', position: snapped });\n }\n }\n\n this._renderGuides(guides);\n\n return result;\n }\n\n // Alignment candidates: the page's edges + center, and every sibling's\n // edges + centers.\n private _candidates(moving: ReportComponent): { vertical: number[]; horizontal: number[] } {\n const vertical = [0, this.report.pageWidth / 2, this.report.pageWidth];\n const horizontal = [0, this.report.pageHeight / 2, this.report.pageHeight];\n\n for (const component of this.activePage?.components ?? []) {\n if (component.id === moving.id) {\n continue;\n }\n\n vertical.push(component.x, component.x + component.w / 2, component.x + component.w);\n horizontal.push(component.y, component.y + component.h / 2, component.y + component.h);\n }\n\n return { vertical, horizontal };\n }\n\n // Snap one axis: of the moving box's three lines (edge/center/edge), find\n // the closest candidate within threshold and return the adjusted base\n // coordinate plus the guide to draw.\n private _snapAxis(\n lines: { offset: number; value: number }[],\n candidates: number[],\n ): { base: number; guide: number } | null {\n let best: { base: number; guide: number; distance: number } | null = null;\n\n for (const line of lines) {\n for (const candidate of candidates) {\n const distance = Math.abs(candidate - line.value);\n if (distance <= this._snapThreshold && (!best || distance < best.distance)) {\n best = { base: candidate - line.offset, guide: candidate, distance };\n }\n }\n }\n\n return best ? { base: best.base, guide: best.guide } : null;\n }\n\n private _nearest(value: number, candidates: number[]): number | null {\n let best: number | null = null;\n let bestDistance = this._snapThreshold;\n\n for (const candidate of candidates) {\n const distance = Math.abs(candidate - value);\n if (distance <= bestDistance) {\n best = candidate;\n bestDistance = distance;\n }\n }\n\n return best;\n }\n\n // The guides overlay is drawn imperatively — the drag loop runs outside\n // Angular and repaints on every pointermove.\n private _renderGuides(guides: GuideLine[]): void {\n const host = this._guides?.nativeElement;\n if (!host) {\n return;\n }\n\n host.replaceChildren(...guides.map((guide) => {\n const line = document.createElement('div');\n line.className = `guide guide-${guide.orientation}`;\n if (guide.orientation === 'v') {\n line.style.left = `${guide.position * PX_PER_INCH}px`;\n } else {\n line.style.top = `${guide.position * PX_PER_INCH}px`;\n }\n\n return line;\n }));\n }\n\n private _clearGuides(): void {\n this._guides?.nativeElement?.replaceChildren();\n }\n}\n","<div class=\"canvas\">\n <div\n #viewport\n class=\"page-viewport\"\n (pointerdown)=\"onCanvasPointerDown()\">\n <fs-zoom-pan\n [zoomMin]=\"0.1\"\n [zoomMax]=\"3\"\n (zoomed)=\"onZoomed($event)\">\n @if (activePage; as page) {\n <div\n class=\"page\"\n [class.flow]=\"isFlow\"\n [class.editing]=\"editMode\"\n [style.width.px]=\"report.pageWidth * PX\"\n [style.height.px]=\"report.pageHeight * PX\"\n [style.padding.px]=\"isFlow ? flowPadding * PX : 0\"\n [style.--canvas-zoom]=\"zoom\"\n [style.--report-heading-size.px]=\"headingSizePx\">\n @if (isFlow) {\n @for (component of flowComponents; track component.id) {\n <app-report-component\n class=\"flow-item\"\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"editMode\"\n [layout]=\"'flow'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [selected]=\"component.id === selectedComponentId\"\n [style.width.%]=\"component.flowWidth\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (flowReorder)=\"onFlowReorder($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n } @else {\n @for (component of page.components; track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"editMode\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [selected]=\"component.id === selectedComponentId\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n }\n\n <div\n #guides\n class=\"guides\">\n </div>\n\n @if (!page.components.length) {\n <div class=\"page-empty\">\n Ask the assistant to add a chart, list or KPI to this page.\n </div>\n }\n </div>\n }\n </fs-zoom-pan>\n\n @if (editMode) {\n <button\n mat-flat-button\n type=\"button\"\n color=\"primary\"\n class=\"edit-done\"\n matTooltip=\"Exit layout editing\"\n (click)=\"editDone.emit()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n }\n </div>\n\n <div class=\"canvas-toolbar\">\n <!-- Tabs are one horizontal drop list: dragging a chip reorders the pages.\n The drop INDEX is computed along X (orientation), but the preview is\n deliberately left unbounded on both axes — pinning it to the row with\n cdkDragBoundary means the chip you are dragging covers the chips you\n are dragging it past, and you cannot see where it is going to land. -->\n <div\n class=\"page-tabs\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onPageDropped($event)\">\n @if ((report?.pages?.length ?? 0) > 1) {\n @for (page of report.pages; track page.id; let index = $index) {\n <!-- The chip is the drag handle AND the tab: clicking selects,\n dragging reorders. The kebab lives inside it, so the whole\n control stays one chip instead of growing a second button. -->\n <div\n cdkDrag\n class=\"page-tab\"\n [class.active]=\"index === activePageIndex\"\n (click)=\"selectPage(index)\">\n <span class=\"page-tab-label\">{{ pageLabel(page, index) }}</span>\n <!-- The kebab opens the menu rather than starting a drag or\n switching pages, so it swallows its own click. -->\n <span\n class=\"page-tab-menu\"\n [fsMenuTriggerFor]=\"pageMenu\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>more_vert</mat-icon>\n </span>\n </div>\n <!-- Outside the chip: cdkDrag clones its host into the drag preview,\n and a menu overlay anchored to a cloned trigger opens detached\n from the real tab. -->\n <fs-menu #pageMenu>\n <ng-template\n fs-menu-item\n (click)=\"renamePage(page)\">\n Edit name\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"deletePage(page)\">\n Delete\n </ng-template>\n </fs-menu>\n }\n }\n <button\n type=\"button\"\n class=\"page-tab add-page\"\n matTooltip=\"Add page\"\n (click)=\"addPage()\">\n <mat-icon>add</mat-icon>\n Page\n </button>\n </div>\n\n <div class=\"zoom-controls\">\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom out\"\n (click)=\"zoomOut()\">\n <mat-icon>remove</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-label\"\n matTooltip=\"Zoom to 100%\"\n (click)=\"zoomActual()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom in\"\n (click)=\"zoomIn()\">\n <mat-icon>add</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Fit page\"\n (click)=\"zoomFit()\">\n <mat-icon>fit_screen</mat-icon>\n </button>\n </div>\n </div>\n</div>\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, OnInit, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';\nimport { MatFormField, MatLabel, MatSuffix } from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\nimport { MatSlideToggle } from '@angular/material/slide-toggle';\nimport { MatTabsModule } from '@angular/material/tabs';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsFormModule } from '@firestitch/form';\nimport { FsLabelModule } from '@firestitch/label';\nimport { FsMaskModule } from '@firestitch/mask';\nimport { FsMessage } from '@firestitch/message';\nimport { FsTabsModule } from '@firestitch/tabs';\n\nimport { Observable } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport {\n ComponentSettings,\n Report,\n ReportComponent,\n ReportComponentSql,\n ReportFilter,\n ReportFilterGroup,\n ReportFilterLevel,\n ReportFilterType,\n ReportFilterableColumn,\n} from '../../interfaces/report.interface';\nimport { DEFAULT_COMPONENT_PADDING } from '../../layout';\n\n\n// What the Settings tab hands back when it saves. Every other exit (Cancel,\n// Done, Escape, backdrop) closes with no result — filter work is announced as it\n// happens instead, through `filtersChanged`.\nexport interface ComponentSettingsResult {\n settings: ComponentSettings;\n}\n\n\n// One row of the Filters tab listing: a filterable column, the interface\n// inferred from its data, and where its filter is exposed (the two toggles).\ninterface FilterRow {\n column: string;\n type: ReportFilterType;\n label: string;\n report: boolean;\n component: boolean;\n}\n\n\n// Component settings, in tabs:\n// Settings — title and content padding. Position/size are tuned by dragging\n// on the canvas; height behaviour follows from the component type.\n// Filters — ONE listing of every filterable column on this component. Each\n// row carries two toggles: show in the report bar and/or show on this\n// component (both, either, or neither). The interface (date range vs value\n// picker) is inferred from the data, never chosen. Each toggle persists\n// immediately and refreshes the in-dialog list.\n// SQL / Config — read-only diagnostics.\n@Component({\n templateUrl: './component-settings.component.html',\n styleUrls: ['./component-settings.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsFormModule,\n FsMaskModule,\n FsDialogModule,\n FsLabelModule,\n FsTabsModule,\n MatTabsModule,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatFormField,\n MatLabel,\n MatSuffix,\n MatInput,\n MatSlideToggle,\n MatTooltip,\n ],\n})\nexport class ComponentSettingsComponent implements OnInit {\n\n // A filter was added, removed or re-levelled, so the report's filter groups\n // changed. Those mutations persist the moment they are clicked and the dialog\n // can then be dismissed by a route that carries no result (Escape, backdrop),\n // so the page is told here rather than through the close result.\n public readonly filtersChanged = new EventEmitter<void>();\n\n public component: ReportComponent;\n public report: Report;\n\n public selectedTab = 'settings';\n\n public title = '';\n\n // Component padding in inches. `number | string` for the same reason as the\n // page dimensions in report-settings: fsMaskNumber seeds from the number but\n // hands back the unmasked string, and save casts it once on the way out.\n public paddingTop: number | string = DEFAULT_COMPONENT_PADDING;\n public paddingRight: number | string = DEFAULT_COMPONENT_PADDING;\n public paddingBottom: number | string = DEFAULT_COMPONENT_PADDING;\n public paddingLeft: number | string = DEFAULT_COMPONENT_PADDING;\n\n public configJson = '';\n\n // ---- SQL tab state ----\n // The statement, once fetched. Null while it is in flight, and null when the\n // component's document could not be compiled (sqlError then says why).\n public sql: string | null = null;\n // True when the statement is a DERIVED baseline: no filters, UTC, the\n // authored grain. The tab says so, because the numbers on screen come from\n // this statement plus the viewer's own choices and the two can differ.\n public sqlBaseline = false;\n public sqlError: string | null = null;\n\n // ---- filter management state ----\n // One row per filterable column. The two booleans drive the toggles; we flip\n // them optimistically on click (so the UI never blinks while the request is\n // in flight) and reconcile from the server on reload.\n public rows: FilterRow[] = [];\n public columnsError: string | null = null;\n\n // The raw inputs the rows are built from.\n private _filterableColumns: ReportFilterableColumn[] = [];\n private _filters: ReportFilter[] = [];\n private _groupsById = new Map<number, ReportFilterGroup>();\n\n private readonly _typeLabels: Record<ReportFilterType, string> = {\n select: 'Pick values',\n dateRange: 'Date range',\n keyword: 'Search text',\n };\n\n private readonly _data: { report: Report; component: ReportComponent } = inject(MAT_DIALOG_DATA);\n private readonly _dialogRef = inject<MatDialogRef<ComponentSettingsComponent, ComponentSettingsResult>>(MatDialogRef);\n private readonly _reportData = inject(ReportData);\n private readonly _message = inject(FsMessage);\n private readonly _cdRef = inject(ChangeDetectorRef);\n\n public ngOnInit(): void {\n this.report = this._data.report;\n this.component = this._data.component;\n\n this.title = this.component.title ?? '';\n\n const padding = this.component.config?.padding;\n this.paddingTop = padding?.top ?? DEFAULT_COMPONENT_PADDING;\n this.paddingRight = padding?.right ?? DEFAULT_COMPONENT_PADDING;\n this.paddingBottom = padding?.bottom ?? DEFAULT_COMPONENT_PADDING;\n this.paddingLeft = padding?.left ?? DEFAULT_COMPONENT_PADDING;\n\n this.configJson = JSON.stringify(this.component.config ?? {}, null, 2);\n\n this._seedFilters(this.report, this.component.id);\n this._loadColumns();\n this._loadSql();\n }\n\n // Human-friendly name for the inferred interface shown beside each column.\n public typeLabel(type: ReportFilterType): string {\n return this._typeLabels[type] ?? type;\n }\n\n public save = () => {\n const settings: ComponentSettings = {\n title: this.title,\n padding: {\n top: this._padding(this.paddingTop),\n right: this._padding(this.paddingRight),\n bottom: this._padding(this.paddingBottom),\n left: this._padding(this.paddingLeft),\n },\n };\n\n return this._reportData.updateComponent(this.report.id, this.component.id, { ...settings })\n .pipe(\n tap(() => {\n this._message.success('Component saved');\n this._dialogRef.close({ settings });\n }),\n );\n };\n\n // Flip one exposure (report bar or this component) for a row. We update the\n // row's boolean first — so the toggle stays put with no blink — then persist\n // and reconcile on reload. Neither on → no filter (removed); either on → the\n // filter exists at the combined level. The interface type is inferred\n // server-side.\n public setExposure(row: FilterRow, target: 'report' | 'component', on: boolean): void {\n row[target] = on;\n\n const existing = this._filters.find((filter) => filter.filterColumn === row.column);\n\n if (!row.report && !row.component) {\n if (existing) {\n this._run(this._reportData.deleteFilter(this.report.id, existing.id));\n }\n\n return;\n }\n\n const level: ReportFilterLevel = row.report && row.component\n ? 'both'\n : (row.report ? 'report' : 'component');\n\n if (existing) {\n this._run(this._reportData.updateFilterGroup(this.report.id, existing.filterGroupId, { level }));\n } else {\n this._run(this._reportData.addFilter(this.report.id, this.component.id, {\n filterColumn: row.column,\n label: row.label,\n level,\n }));\n }\n }\n\n // The padding as a real number for the wire. fsMaskNumber hands back the\n // unmasked string it built with a fixed '.' radix, so this is a straight\n // parse - the whole reason for the mask is that a native number input would\n // paint (and read back) the viewer's own locale separator instead.\n private _padding(value: number | string): number {\n return typeof value === 'number' ? value : parseFloat(value);\n }\n\n // Run a filter mutation, then reload to reconcile the optimistic state.\n private _run(request: Observable<unknown>): void {\n request.subscribe({\n next: () => this._afterMutation(),\n error: (error) => this._mutationError(error),\n });\n }\n\n // Build the row view-model from the loaded columns + filters/groups. Each\n // row's toggles reflect where its filter group is currently exposed.\n private _rebuildRows(): void {\n this.rows = this._filterableColumns.map((column) => {\n const filter = this._filters.find((candidate) => candidate.filterColumn === column.column);\n const level = filter ? this._groupsById.get(filter.filterGroupId)?.level : undefined;\n\n return {\n column: column.column,\n type: column.type,\n label: filter?.label\n || this._groupsById.get(filter?.filterGroupId ?? -1)?.label\n || this._humanize(column.column),\n report: level === 'report' || level === 'both',\n component: level === 'component' || level === 'both',\n };\n });\n }\n\n // After any filter mutation: re-fetch the report so the dialog's filter list\n // (and the parent canvas, on close) reflect the new groups/levels.\n private _afterMutation(): void {\n this.filtersChanged.emit();\n\n this._reportData.get(this.report.id)\n .subscribe((report: Report) => {\n this.report = report;\n this._seedFilters(report, this.component.id);\n this._cdRef.markForCheck();\n });\n }\n\n private _mutationError(error: any): void {\n this._message.error(error?.error?.message ?? error?.message ?? 'Filter operation failed');\n // Re-seed from the server so the optimistic toggle snaps back to truth.\n this._afterMutation();\n }\n\n private _seedFilters(report: Report, componentId: number): void {\n this._groupsById = new Map((report.filterGroups ?? []).map((group) => [group.id, group]));\n\n const component = report.pages\n .flatMap((page) => page.components)\n .find((candidate) => candidate.id === componentId);\n\n this._filters = component?.filters ?? [];\n this._rebuildRows();\n }\n\n // The statement the SQL tab shows. Fetched rather than read off the\n // component: a derived component stores a document, not SQL, so its\n // statement only exists once the backend compiles it.\n //\n // Loaded in ngOnInit beside the columns, NOT on tab activation. The tabs are\n // not lazy (no matTabContent), and switching the tab-group's `[(selected)]`\n // banana-box to a one-way binding plus (selectedChange) to get a hook would\n // break it: FsTabsHeaderTabGroupDirective self-assigns `this.selected` before\n // it emits, so the event is filtered out and the load would never fire. One\n // small request when a dialog opens is not worth that risk.\n private _loadSql(): void {\n this._reportData.componentSql(this.report.id, this.component.id)\n .subscribe({\n next: (preview: ReportComponentSql) => {\n this.sql = preview?.sql ?? null;\n this.sqlBaseline = !!preview?.baseline;\n this.sqlError = preview?.error ?? null;\n this._cdRef.markForCheck();\n },\n error: (error) => {\n this.sql = null;\n this.sqlError = error?.error?.message ?? 'Could not read the component SQL';\n this._cdRef.markForCheck();\n },\n });\n }\n\n private _loadColumns(): void {\n this._reportData.componentColumns(this.report.id, this.component.id)\n .subscribe({\n next: (columns: ReportFilterableColumn[]) => {\n this._filterableColumns = columns ?? [];\n this._rebuildRows();\n this._cdRef.markForCheck();\n },\n error: (error) => {\n this.columnsError = error?.error?.message ?? 'Could not read the component columns';\n this._cdRef.markForCheck();\n },\n });\n }\n\n private _humanize(column: string): string {\n return column\n .replace(/[_\\-]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/\\b\\w/g, (character) => character.toUpperCase());\n }\n}\n","<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ component.title || 'Component' }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Title\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"title\"\n name=\"title\">\n </mat-form-field>\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError) {\n <div class=\"filters-empty error\">\n {{ columnsError }}\n </div>\n } @else if (rows.length) {\n <!-- Every filterable column. Toggle where its control shows: in\n the report bar, on this component, both, or neither. The\n interface (date range vs value picker) follows the data. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-toggle\">\n Report bar\n </th>\n <th class=\"filter-col-toggle\">\n This component\n </th>\n </tr>\n </thead>\n <tbody>\n @for (row of rows; track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n {{ typeLabel(row.type) }}\n </td>\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.report\"\n (ngModelChange)=\"setExposure(row, 'report', $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n matTooltip=\"Show in the report bar\">\n </mat-slide-toggle>\n </td>\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setExposure(row, 'component', $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n matTooltip=\"Show on this component\">\n </mat-slide-toggle>\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet — give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError) {\n <div class=\"filters-empty error\">\n {{ sqlError }}\n </div>\n } @else if (sql) {\n @if (sqlBaseline) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query — no filters applied, times in UTC.\n </div>\n }\n <pre class=\"code-block\">{{ sql }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions\n [save]=\"selectedTab === 'settings'\"\n [done]=\"selectedTab !== 'settings'\">\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>","import {\n ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output,\n} from '@angular/core';\nimport { ControlContainer, FormsModule, NgForm } from '@angular/forms';\nimport { MatFormField, MatLabel } from '@angular/material/form-field';\nimport { MatOption } from '@angular/material/core';\nimport { MatSelect } from '@angular/material/select';\n\nimport { guid } from '@firestitch/common';\nimport { FsFormModule } from '@firestitch/form';\n\n\n// Self-contained timezone picker for the report settings dialog. The IANA zone\n// list comes from the browser (Intl.supportedValuesOf), so the package carries no\n// dependency on any app timezone API. Defaults an empty value to the viewer's zone.\n@Component({\n selector: 'fs-ai-report-timezone-select',\n templateUrl: './timezone-select.component.html',\n styleUrls: ['./timezone-select.component.scss'],\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatFormField,\n MatLabel,\n MatSelect,\n MatOption,\n FormsModule,\n FsFormModule,\n ],\n})\nexport class TimezoneSelectComponent implements OnInit {\n\n @Input() public placeholder = 'Timezone';\n @Input() public required = false;\n @Input() public disabled = false;\n @Output() public timezoneChange = new EventEmitter<string>();\n\n @Input() public set timezone(value: string) {\n if (value && value !== this._timezone) {\n this._timezone = value;\n this.timezoneChange.emit(this.timezone);\n }\n }\n\n public get timezone(): string {\n return this._timezone;\n }\n\n public guid: string = guid();\n public timezones: string[] = [];\n\n private _browserTimezone: string = Intl.DateTimeFormat().resolvedOptions().timeZone;\n private _timezone: string = null;\n\n public ngOnInit(): void {\n this.timezones = this._supportedTimezones();\n\n if (!this.timezone) {\n this.timezone = this._browserTimezone;\n }\n }\n\n // The browser's IANA zone list where available; fall back to at least the\n // viewer's own zone so the control is never empty.\n private _supportedTimezones(): string[] {\n const intl = Intl as unknown as { supportedValuesOf?: (key: string) => string[] };\n\n return typeof intl.supportedValuesOf === 'function'\n ? intl.supportedValuesOf('timeZone')\n : [this._browserTimezone];\n }\n}\n","<mat-form-field class=\"full-width\">\n <mat-label>{{placeholder}}</mat-label>\n <mat-select\n [(ngModel)]=\"timezone\"\n [fsFormRequired]=\"required\"\n [disabled]=\"disabled\"\n name=\"timezone_select_{{ guid }}\">\n @for (item of timezones; track item) {\n <mat-option [value]=\"item\">{{ item }}</mat-option>\n }\n </mat-select>\n</mat-form-field>\n","import { format, parseISO } from 'date-fns';\n\n\n// Date-range defaults are stored as calendar-day strings (yyyy-MM-dd, no time,\n// no timezone) so the backend never shifts them; the date picker works in Date\n// objects. These two convert between the two forms — the only translation the\n// Filters tab needs for a fixed date range.\n\n// A stored yyyy-MM-dd boundary as a local Date for the picker, or null.\nexport function dateFromBound(value: string | null | undefined): Date | null {\n if (!value) {\n return null;\n }\n\n const date = parseISO(value.slice(0, 10));\n\n return isNaN(date.getTime()) ? null : date;\n}\n\n// A picked Date as a yyyy-MM-dd boundary for storage, or null. Uses the local\n// calendar day (format, not toISOString) so the boundary is the day the admin\n// picked, regardless of timezone.\nexport function dateToBound(value: Date | null | undefined): string | null {\n return value instanceof Date && !isNaN(value.getTime())\n ? format(value, 'yyyy-MM-dd')\n : null;\n}\n","import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\n\nimport { MatButton } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';\nimport { MatFormField, MatLabel, MatHint, MatSuffix } from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\nimport { MatOption, MatSelect } from '@angular/material/select';\nimport { MatTabsModule } from '@angular/material/tabs';\n\nimport { FsAutocompleteChipsModule } from '@firestitch/autocomplete-chips';\nimport { FsDatePickerModule } from '@firestitch/datepicker';\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsFormModule } from '@firestitch/form';\nimport { FsMaskModule } from '@firestitch/mask';\nimport { FsMessage, FsMessageModule } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsTabsModule } from '@firestitch/tabs';\n\nimport { TimezoneSelectComponent } from '../../components/timezone-select/timezone-select.component';\n\nimport { Observable, forkJoin } from 'rxjs';\nimport { switchMap, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport {\n FilterGroupDefault,\n Report,\n ReportFilterGroup,\n} from '../../interfaces/report.interface';\nimport { DEFAULT_HEADING_SIZE, PAGE_DIMENSION_MAX, PAGE_DIMENSION_MIN } from '../../layout';\nimport { loadGroupOptions, matchOptions, resolveOptionValues } from '../../report-filter-items';\nimport { dateFromBound, dateToBound } from './report-settings-default';\n\n\n// What the dialog hands back when it closes, so the page knows what happened\n// without sniffing magic strings. A dismissed dialog closes with `undefined`.\nexport interface ReportSettingsResult {\n action: 'saved' | 'deleted';\n}\n\n\n// One report-level filter in the Filters tab: its group, the inferred interface,\n// and an editable draft default. The draft fields used depend on the type\n// (dateRange → start/end Dates; select → values; keyword → text). `fetch` loads\n// the select options the same way the report bar does.\ninterface FilterDefaultRow {\n group: ReportFilterGroup;\n label: string;\n start: Date | null;\n end: Date | null;\n values: { name: string; value: unknown }[];\n value: string;\n fetch: (keyword?: string) => Observable<{ name: string; value: unknown }[]>;\n}\n\n\n// Report settings, in three tabs:\n// Settings — name + page setup (size in inches, layout mode).\n// Styles — the report's typographic styles (sizes in POINTS, 1:1 with\n// PDF/PowerPoint); the Heading size to start.\n// Filters — the report-level filters and their DEFAULT values. A default\n// seeds the report bar on every open (for every viewer) but stays\n// user-changeable — it pre-fills the control, it doesn't lock it. This is the\n// fix for heavy reports opening blank and timing out: a default month +\n// organization scopes the landing page from the first load.\n@Component({\n templateUrl: './report-settings.component.html',\n styleUrls: ['./report-settings.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsFormModule,\n FsMaskModule,\n FsDialogModule,\n FsMessageModule,\n FsTabsModule,\n FsDatePickerModule,\n FsAutocompleteChipsModule,\n MatTabsModule,\n MatButton,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatFormField,\n MatLabel,\n MatHint,\n MatSuffix,\n MatInput,\n MatSelect,\n MatOption,\n TimezoneSelectComponent,\n ],\n})\nexport class ReportSettingsComponent implements OnInit {\n\n public selectedTab = 'settings';\n\n public name = '';\n // The page in inches. No initializer: every report carries a size, and\n // ngOnInit seeds both before the tab renders, so a placeholder here could only\n // ever be a wrong number briefly showing as the operator's own.\n //\n // Typed `number | string` because fsMaskNumber is the control: it is seeded\n // with the report's number but hands back the unmasked STRING the operator\n // typed. Save casts it once, on the way out — see `_pageDimension()`.\n public pageWidth: number | string;\n public pageHeight: number | string;\n public readonly pageDimensionMin = PAGE_DIMENSION_MIN;\n public readonly pageDimensionMax = PAGE_DIMENSION_MAX;\n public layout: 'freeform' | 'flow' = 'freeform';\n // Empty until the report has one; app-timezone-select then defaults it to the\n // viewer's browser zone (which Save persists, making the report's zone explicit).\n public timezone = '';\n public headingSize = DEFAULT_HEADING_SIZE;\n\n // The report-level filters and their editable default values (Filters tab).\n public readonly filterRows = signal<FilterDefaultRow[]>([]);\n\n private readonly _data: { report: Report } = inject(MAT_DIALOG_DATA);\n private readonly _dialogRef = inject<MatDialogRef<ReportSettingsComponent, ReportSettingsResult>>(MatDialogRef);\n private readonly _reportData = inject(ReportData);\n private readonly _message = inject(FsMessage);\n private readonly _prompt = inject(FsPrompt);\n private readonly _destroyRef = inject(DestroyRef);\n\n public ngOnInit(): void {\n const report = this._data.report;\n this.name = report.name;\n this.pageWidth = report.pageWidth;\n this.pageHeight = report.pageHeight;\n this.layout = report.layout ?? 'freeform';\n this.timezone = report.timezone ?? '';\n this.headingSize = report.config?.styles?.heading?.size ?? DEFAULT_HEADING_SIZE;\n\n this._buildFilterRows(report);\n }\n\n // Confirm and delete here, while the dialog is still open, then close with\n // a `deleted` result. The page reacts to the result; it no longer owns the\n // prompt or the API call.\n public delete(): void {\n this._prompt.confirm({\n title: 'Delete Report',\n template: `Delete \"${this._data.report.name}\"? This cannot be undone.`,\n })\n .pipe(\n switchMap(() => this._reportData.delete(this._data.report.id)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success('Report deleted');\n this._dialogRef.close({ action: 'deleted' });\n });\n }\n\n public save = () => {\n const reportId = this._data.report.id;\n\n // Persist the report settings and each changed filter default together, so\n // the single Save covers all three tabs. The report reloads on the `saved`\n // result, re-seeding the bar from the new defaults.\n const settings$ = this._reportData.update(reportId, {\n name: this.name,\n pageWidth: this._pageDimension(this.pageWidth),\n pageHeight: this._pageDimension(this.pageHeight),\n layout: this.layout,\n timezone: this.timezone,\n styles: { heading: { size: this.headingSize } },\n });\n\n const defaults$ = this.filterRows()\n .filter((row) => this._defaultChanged(row))\n .map((row) => this._reportData.updateFilterGroup(reportId, row.group.id, {\n default: this._rowDefault(row),\n }));\n\n return forkJoin([settings$, ...defaults$])\n .pipe(\n tap(() => {\n this._message.success('Report settings saved');\n this._dialogRef.close({ action: 'saved' });\n }),\n );\n };\n\n // The page dimension as a real number for the wire. fsMaskNumber hands back\n // the unmasked string it built with a fixed '.' radix (which is the whole\n // point of the mask - a native number input paints the viewer's locale\n // separator instead), so the cast here is a straight parse and never sees a\n // comma. The backend rejects anything non-numeric rather than coercing, so a\n // NaN fails loudly instead of silently storing a wrong page size.\n private _pageDimension(value: number | string): number {\n return typeof value === 'number' ? value : parseFloat(value);\n }\n\n // Build one editable row per report-level filter group (level report or both),\n // in bar order, seeding each draft from the group's stored default.\n private _buildFilterRows(report: Report): void {\n const reportId = report.id;\n\n const built = (report.filterGroups ?? [])\n .filter((group) => group.level === 'report' || group.level === 'both')\n .sort((a, b) => a.order - b.order)\n .map((group) => {\n const groupDefault = group.config?.default;\n // One shared, replayed option stream per group: the chips fetch and the\n // stored default's labels read the same list, so it is fetched once.\n const options$ = loadGroupOptions(group, this._reportData, reportId);\n\n const row: FilterDefaultRow = {\n group,\n label: group.label || group.filters?.[0]?.filterColumn || 'Filter',\n start: dateFromBound(groupDefault?.start),\n end: dateFromBound(groupDefault?.end),\n // Named below, once the option list carrying their labels is in.\n values: [],\n value: groupDefault?.value ?? '',\n // fs-autocomplete-chips fetch: the group's distinct options, name-filtered.\n // Same loader the report bar uses, so the two never drift.\n fetch: (keyword?: string) => matchOptions(options$, keyword),\n };\n\n return { row, options$, values: groupDefault?.values ?? [] };\n });\n\n const rows = built.map((entry) => entry.row);\n const seeded = built.filter((entry) => entry.values.length);\n\n // Nothing to name — publish immediately rather than waiting on a request\n // no row needs.\n if (!seeded.length) {\n this.filterRows.set(rows);\n\n return;\n }\n\n // A stored select default holds ids, so its chips can only be named once the\n // option list is in. Resolve every seeded row first and publish the rows in\n // one go, so the tab never renders a chip showing a raw id.\n forkJoin(seeded.map((entry) => resolveOptionValues(entry.options$, entry.values)))\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((resolved) => {\n resolved.forEach((values, index) => seeded[index].row.values = values);\n this.filterRows.set(rows);\n });\n }\n\n // The draft default normalized to the wire shape for this row's type, or null\n // when empty (which clears the stored default).\n private _rowDefault(row: FilterDefaultRow): FilterGroupDefault | null {\n switch (row.group.type) {\n case 'dateRange': {\n const start = dateToBound(row.start);\n const end = dateToBound(row.end);\n\n return (start || end) ? { start: start ?? undefined, end: end ?? undefined } : null;\n }\n\n case 'select':\n return row.values.length ? { values: row.values.map((option) => option.value) } : null;\n\n case 'keyword':\n default: {\n const value = row.value.trim();\n\n return value ? { value } : null;\n }\n }\n }\n\n // Whether the row's draft differs from the group's stored default — only\n // changed rows are persisted on Save.\n private _defaultChanged(row: FilterDefaultRow): boolean {\n const before = JSON.stringify(this._normalize(row.group.config?.default ?? null));\n const after = JSON.stringify(this._normalize(this._rowDefault(row)));\n\n return before !== after;\n }\n\n // A stable comparison form: drop relative (not authored here) and undefined\n // keys so a no-op edit doesn't read as a change.\n private _normalize(value: FilterGroupDefault | null): FilterGroupDefault | null {\n if (!value) {\n return null;\n }\n\n const normalized: FilterGroupDefault = {};\n if (value.start) {\n normalized.start = value.start;\n }\n if (value.end) {\n normalized.end = value.end;\n }\n if (value.values?.length) {\n normalized.values = value.values;\n }\n if (value.value) {\n normalized.value = value.value;\n }\n if (value.relative) {\n normalized.relative = value.relative;\n }\n\n return Object.keys(normalized).length ? normalized : null;\n }\n}\n","<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <mat-form-field>\n <mat-label>\n Layout\n </mat-label>\n <mat-select\n [(ngModel)]=\"layout\"\n name=\"layout\">\n <mat-option value=\"freeform\">\n Freeform — position components anywhere on the page\n </mat-option>\n <mat-option value=\"flow\">\n Flow — components flow into rows by width %\n </mat-option>\n </mat-select>\n <mat-hint>\n Freeform is like PowerPoint; Flow is like a responsive dashboard.\n </mat-hint>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n @for (row of filterRows(); track row.group.id) {\n @switch (row.group.type) {\n @case ('dateRange') {\n <div class=\"fs-row.gap-sm.align-center fs-flex\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default From {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default To {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n </div>\n }\n @case ('select') {\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [label]=\"'Default ' + row.label\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n }\n @default {\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default {{ row.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report-level filters yet. Add a filter to a\n component (its settings → Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>","import { Injectable, inject } from '@angular/core';\n\nimport { Observable, forkJoin, from, map, of } from 'rxjs';\nimport { catchError, mergeMap, toArray } from 'rxjs/operators';\n\nimport { ReportData } from '../data/report.data';\nimport {\n ComponentData,\n GRANULARITY_OPTIONS,\n Report,\n ReportComponent,\n ReportFilterGroup,\n ReportPage,\n} from '../interfaces/report.interface';\nimport { dateBoundLabel, loadGroupOptions, resolveOptionValues } from '../report-filter-items';\nimport { ReportFilterStateService } from '../services/report-filter-state.service';\n\n\nexport interface CollectedComponent {\n component: ReportComponent;\n data: ComponentData | null; // null = its query failed; exports show a note\n}\n\nexport interface CollectedPage {\n page: ReportPage;\n components: CollectedComponent[];\n}\n\nexport interface CollectedReport {\n report: Report;\n pages: CollectedPage[];\n // Human-readable lines describing the active filters, for the title slide/page.\n filterSummary: string[];\n}\n\n// Rows fetched for a list component's export table — enough to fill a\n// slide/page table; the cap note covers the rest.\nconst LIST_EXPORT_ROWS = 100;\n\n// How many tile queries an export runs at once.\n//\n// Not a politeness setting — it is the difference between a deck and a broken\n// one. These queries are heavy and read the same tables, so firing all of them\n// together puts every one in contention for the same database at the same\n// moment and they cross the statement ceiling as a group: measured on report\n// 28, ten tiles that each answer in 9-24s run one after another all failed at\n// ~30s when released together. Concurrency buys wall-clock only up to the point\n// where the queries start taking it back off each other, and past that it buys\n// failures.\nconst EXPORT_CONCURRENCY = 3;\n\n// What a component with nothing to draw prints in the exported file.\n//\n// The two cases must not read alike. A tile that returned no rows is a finding\n// about the period — the report worked and the answer is \"none\". A tile whose\n// query failed is a hole in the file, and calling that \"Data unavailable\" tells\n// the reader the data does not exist when what happened is that nobody managed\n// to ask for it. Shared by both renderers so the PDF and the deck cannot end up\n// describing the same hole two different ways.\nexport function emptyLabel(item: CollectedComponent): string {\n return item.data ? 'No data' : 'Could not be generated';\n}\n\n// The pages of a collected report that have at least one tile whose query\n// failed — what the export gate names to the user, and what makes \"some of this\n// file is missing\" a fact the caller can act on rather than a thing they notice\n// in the PDF afterwards.\nexport function failedPageNames(collected: CollectedReport): string[] {\n // Numbered before the filter — an unnamed page 4 that failed has to read\n // \"Page 4\", not \"Page 1\" because it happened to be the first failure.\n return collected.pages\n .map((page, index) => ({ page, number: index + 1 }))\n .filter(({ page }) => page.components.some((item) => !item.data))\n .map(({ page, number }) => page.page.name || `Page ${number}`);\n}\n\n// Gathers everything an export needs: every component's data across ALL pages\n// (the canvas only renders the active page, so exports can't scrape the\n// screen), fetched fresh with the viewer's current filter state.\n//\n// A failed component resolves to a null `data` rather than failing the whole\n// collection — but that is so the caller can REPORT what failed, not so it can\n// be ignored: see failedPageNames() and the export gate that uses it.\n@Injectable()\nexport class ReportExportCollectorService {\n\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n\n public collect(report: Report): Observable<CollectedReport> {\n const slots: { pageIndex: number; component: ReportComponent }[] = [];\n\n report.pages.forEach((page, pageIndex) => {\n for (const component of page.components) {\n slots.push({ pageIndex, component });\n }\n });\n\n // Released a few at a time rather than all at once. mergeMap completes out\n // of order, so each result carries the slot it came from and the rows are\n // filed by index — the deck's page order can't depend on which query\n // happened to finish first.\n const all$ = slots.length\n ? from(slots.map((slot, index) => ({ slot, index })))\n .pipe(\n mergeMap(\n ({ slot, index }) => this._componentData(report, slot.component)\n .pipe(map((item) => ({ item, index }))),\n EXPORT_CONCURRENCY,\n ),\n toArray(),\n )\n : of([] as { item: CollectedComponent; index: number }[]);\n\n // The summary rides alongside the component data rather than being built at\n // the end, because naming a select filter's values is itself a request.\n return forkJoin({ collected: all$, filterSummary: this._filterSummary(report) })\n .pipe(\n map(({ collected, filterSummary }) => {\n const pages: CollectedPage[] = report.pages.map((page) => ({ page, components: [] }));\n\n [...collected]\n .sort((a, b) => a.index - b.index)\n .forEach(({ item, index }) => {\n pages[slots[index].pageIndex].components.push(item);\n });\n\n return {\n report,\n pages,\n filterSummary,\n };\n }),\n );\n }\n\n private _componentData(report: Report, component: ReportComponent): Observable<CollectedComponent> {\n const filters = this._filterState.resolveForComponent(component);\n // A time-series chart carries the viewer's group-by grain so the export\n // re-buckets exactly as the screen does; lists carry their export paging.\n const frequency = this._filterState.frequency();\n const isTimeSeries = component.type === 'chart' && component.config?.xAxis?.kind === 'time';\n const state = component.type === 'list'\n ? { page: 1, pageSize: LIST_EXPORT_ROWS }\n : (isTimeSeries && frequency ? { frequency } : {});\n\n // handlers: false keeps the app's global error dialog out of this. A failed\n // tile is reported once, by the export gate, naming the pages it cost —\n // never as ten stacked modals carrying the database's own wording.\n return this._reportData.componentData(report.id, component.id, filters, state, true, { handlers: false })\n .pipe(\n map((data: ComponentData) => ({ component, data })),\n catchError(() => of({ component, data: null })),\n );\n }\n\n // \"Report Period: Jun 12, 2025 – Jun 12, 2026\", \"Organization: Alnylam - AHP,\n // Alnylam - PH1\" — one line per filter group that has an active session value.\n //\n // A select group stores ids, so its line has to be named off the option list\n // before it can be printed; a date or keyword group already holds its own\n // display value and resolves synchronously.\n private _filterSummary(report: Report): Observable<string[]> {\n const lines: Observable<string>[] = [];\n\n for (const group of report.filterGroups ?? []) {\n const value = this._filterState.value(group.id);\n if (!value) {\n continue;\n }\n\n const label = group.label || 'Filter';\n\n if (value.start || value.end) {\n lines.push(of(`${label}: ${this._date(value.start)} – ${this._date(value.end)}`));\n } else if (value.values?.length) {\n lines.push(this._selectLine(label, group, report.id, value.values));\n } else if (value.value?.trim()) {\n lines.push(of(`${label}: \"${value.value.trim()}\"`));\n }\n }\n\n // The group-by grain, under the report's own name for the control — a cover\n // sheet reading \"Frequency\" when the report calls it \"Period\" describes a\n // control the reader cannot find on screen.\n const granularity = this._filterState.frequency();\n if (granularity) {\n const option = GRANULARITY_OPTIONS.find((item) => item.value === granularity);\n const label = report.config?.groupBy?.label || 'Group By';\n lines.push(of(`${label}: ${option?.name ?? granularity}`));\n }\n\n return lines.length ? forkJoin(lines) : of([]);\n }\n\n // One select group's line, with its stored ids resolved to the same names the\n // on-screen chips show — a cover reading \"Organization: 8774, 8777\" tells the\n // client nothing about what the report covers.\n //\n // Uses the report bar's own loader and resolver so the two can't drift, which\n // also means a value whose entity was deleted keeps showing its raw id rather\n // than dropping off the cover and silently understating the filter. A failed\n // option fetch degrades the whole line to ids for the same reason: an export\n // must never fail on a cosmetic lookup.\n private _selectLine(\n label: string,\n group: ReportFilterGroup,\n reportId: number,\n values: unknown[],\n ): Observable<string> {\n return resolveOptionValues(loadGroupOptions(group, this._reportData, reportId), values)\n .pipe(\n map((resolved) => `${label}: ${resolved.map((item) => item.name).join(', ')}`),\n catchError(() => of(`${label}: ${values.map((item) => String(item)).join(', ')}`)),\n );\n }\n\n // Rendered off the same calendar day the filter sends to the server, so the\n // cover's period is the period the numbers behind it were queried for.\n private _date(value: Date | string | null | undefined): string {\n return dateBoundLabel(value) ?? '…';\n }\n}\n","import { ComponentData, ReportComponent } from '../interfaces/report.interface';\nimport { buildChartOption } from '../option-builder';\n\n\n// Renders a chart to a PNG data URL WITHOUT it being on screen — the PDF\n// export needs every page's charts, but the canvas only renders the active\n// page. ECharts happily initializes against a detached element when given\n// explicit pixel dimensions; animations are disabled so getDataURL is\n// complete synchronously after setOption.\nexport async function renderChartImage(\n component: ReportComponent,\n data: ComponentData,\n width: number,\n height: number,\n pixelRatio = 3,\n): Promise<string> {\n // The same tree-shaken echarts build + 'report' theme the live canvas uses.\n const echarts = (await import('../theme/echarts')).default;\n\n const host = document.createElement('div');\n host.style.width = `${width}px`;\n host.style.height = `${height}px`;\n\n const chart = echarts.init(host, 'report', {\n renderer: 'canvas',\n width,\n height,\n });\n\n try {\n chart.setOption({\n ...buildChartOption(component, data),\n animation: false,\n });\n\n return chart.getDataURL({\n type: 'png',\n pixelRatio,\n backgroundColor: '#ffffff',\n });\n } finally {\n chart.dispose();\n }\n}\n","import { Injectable } from '@angular/core';\r\n\r\nimport { format } from 'date-fns';\r\n\r\nimport { formatMeasureValue } from '../format';\r\nimport {\r\n ComponentData,\r\n KpiConfig,\r\n ListConfig,\r\n ReportComponent,\r\n} from '../interfaces/report.interface'; // ComponentData used in method signatures below\r\nimport { ComponentGeometry, pageGeometry } from '../layout';\r\nimport { renderChartImage } from './offscreen-chart';\r\nimport { CollectedComponent, CollectedReport, emptyLabel } from './report-export-collector.service';\r\n\r\n\r\n// Inches → points (the PDF unit).\r\nconst PT = 72;\r\n\r\n// Component title strip height, points.\r\nconst TITLE_H = 18;\r\n// Approximate table row height, points — drives the rows-that-fit cap.\r\nconst TABLE_ROW_H = 16;\r\n\r\n// Builds the PDF client-side with jspdf. The report's unit is inches and PDFs\r\n// are points at exactly 72/inch, so each report page becomes one PDF page of\r\n// the exact physical size and components land at their precise positions.\r\n// Charts are rendered through an offscreen ECharts instance at 3× pixel\r\n// ratio — pixel-identical to the screen, crisp at print size — and tables are\r\n// drawn with jspdf-autotable. Both libraries load lazily into their own chunks.\r\n@Injectable()\r\nexport class ReportPdfService {\r\n\r\n public async export(collected: CollectedReport): Promise<void> {\r\n const { jsPDF } = await import('jspdf');\r\n const autoTable = (await import('jspdf-autotable')).default;\r\n\r\n const report = collected.report;\r\n const pageW = report.pageWidth * PT;\r\n const pageH = report.pageHeight * PT;\r\n\r\n const doc = new jsPDF({\r\n orientation: pageW >= pageH ? 'landscape' : 'portrait',\r\n unit: 'pt',\r\n format: [pageW, pageH],\r\n });\r\n\r\n this._titlePage(doc, collected, pageW, pageH);\r\n\r\n for (const collectedPage of collected.pages) {\r\n doc.addPage([pageW, pageH], pageW >= pageH ? 'landscape' : 'portrait');\r\n const geometry = pageGeometry(report, collectedPage.page);\r\n\r\n for (const item of collectedPage.components) {\r\n await this._renderComponent(doc, autoTable, item, geometry.get(item.component.id));\r\n }\r\n }\r\n\r\n doc.save(`${this._slug(report.name)}.pdf`);\r\n }\r\n\r\n private _titlePage(doc: any, collected: CollectedReport, pageW: number, pageH: number): void {\r\n doc.setFont('helvetica', 'bold');\r\n doc.setFontSize(28);\r\n doc.setTextColor('#1f2933');\r\n doc.text(collected.report.name, 40, pageH * 0.35);\r\n\r\n doc.setFont('helvetica', 'normal');\r\n doc.setFontSize(11);\r\n doc.setTextColor('#52606d');\r\n\r\n const lines = [\r\n format(new Date(), 'MMMM d, yyyy'),\r\n ...collected.filterSummary,\r\n ];\r\n doc.text(lines, 40, pageH * 0.35 + 26);\r\n }\r\n\r\n private async _renderComponent(doc: any, autoTable: any, item: CollectedComponent, geometry?: ComponentGeometry): Promise<void> {\r\n const component = item.component;\r\n // Geometry arrives in inches (flow layout pre-resolved); the PDF draws in\r\n // points.\r\n const inches = geometry ?? component;\r\n const x = inches.x * PT;\r\n const y = inches.y * PT;\r\n const w = inches.w * PT;\r\n const h = inches.h * PT;\r\n\r\n if (component.title) {\r\n doc.setFont('helvetica', 'bold');\r\n doc.setFontSize(9);\r\n doc.setTextColor('#1f2933');\r\n doc.text(component.title, x, y + 10, { maxWidth: w });\r\n }\r\n\r\n const bodyY = y + TITLE_H;\r\n const bodyH = Math.max(20, h - TITLE_H);\r\n\r\n if (!item.data || !item.data.rows?.length) {\r\n doc.setFont('helvetica', 'italic');\r\n doc.setFontSize(9);\r\n doc.setTextColor('#7b8794');\r\n doc.text(emptyLabel(item), x + w / 2, bodyY + bodyH / 2, { align: 'center' });\r\n\r\n return;\r\n }\r\n\r\n switch (component.type) {\r\n case 'chart': {\r\n const image = await renderChartImage(component, item.data, w, bodyH);\r\n doc.addImage(image, 'PNG', x, bodyY, w, bodyH);\r\n break;\r\n }\r\n case 'list':\r\n this._renderTable(doc, autoTable, component, item.data, x, bodyY, w, bodyH);\r\n break;\r\n case 'kpi':\r\n this._renderKpi(doc, component, item.data, x, bodyY, w, bodyH);\r\n break;\r\n }\r\n }\r\n\r\n private _renderTable(\r\n doc: any,\r\n autoTable: any,\r\n component: ReportComponent,\r\n data: ComponentData,\r\n x: number, y: number, w: number, h: number,\r\n ): void {\r\n const config = component.config as ListConfig;\r\n const columns = config.columns?.length\r\n ? config.columns\r\n : data.columns.map((column) => ({ column, label: column }));\r\n\r\n const cap = Math.max(2, Math.floor(h / TABLE_ROW_H) - 1);\r\n const rows = data.rows.slice(0, cap);\r\n const remaining = (data.paging?.total ?? data.rows.length) - rows.length;\r\n\r\n const body = rows.map((row) => columns.map((column) => this._cell(row[column.column], column.format)));\r\n\r\n if (remaining > 0) {\r\n body.push([`… ${remaining} more row(s) — use the component's CSV export for the full dataset`]);\r\n }\r\n\r\n autoTable(doc, {\r\n head: [columns.map((column) => column.label || column.column)],\r\n body,\r\n startY: y,\r\n margin: { left: x },\r\n tableWidth: w,\r\n styles: { fontSize: 8, cellPadding: 3, textColor: '#1f2933' },\r\n headStyles: { fillColor: '#4e79a7', textColor: '#ffffff', fontStyle: 'bold' },\r\n alternateRowStyles: { fillColor: '#f5f7fa' },\r\n theme: 'grid',\r\n });\r\n }\r\n\r\n private _renderKpi(\r\n doc: any,\r\n component: ReportComponent,\r\n data: ComponentData,\r\n x: number, y: number, w: number, h: number,\r\n ): void {\r\n const config = component.config as KpiConfig;\r\n const row = data.rows[0] ?? {};\r\n const column = config.measure?.column ?? Object.keys(row)[0];\r\n const value = formatMeasureValue(row[column], config.measure?.format, config.measure?.precision);\r\n\r\n doc.setFont('helvetica', 'bold');\r\n doc.setFontSize(26);\r\n doc.setTextColor('#1f2933');\r\n doc.text(value, x + w / 2, y + h / 2, { align: 'center' });\r\n\r\n if (config.measure?.label) {\r\n doc.setFont('helvetica', 'normal');\r\n doc.setFontSize(9);\r\n doc.setTextColor('#7b8794');\r\n doc.text(config.measure.label, x + w / 2, y + h / 2 + 16, { align: 'center' });\r\n }\r\n }\r\n\r\n // The exported cell must read like the on-screen cell: the SQL already\r\n // carries the formatting, so the value goes out verbatim. A raw date is the\r\n // one value the client renders (the column stays a RAW timestamp for the\r\n // report timezone), and it is rendered here too.\r\n private _cell(value: unknown, columnFormat?: string): string {\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n\r\n if (columnFormat === 'date') {\r\n const date = new Date(String(value));\r\n\r\n return Number.isNaN(date.getTime()) ? String(value) : format(date, 'MMM d, yyyy');\r\n }\r\n\r\n return String(value);\r\n }\r\n\r\n private _slug(name: string): string {\r\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'report';\r\n }\r\n}\r\n","// The report chart palette — one definition shared by the ECharts theme (on\n// screen), the PowerPoint export's native chart colors, and the PDF export,\n// so a series keeps its color across every medium.\nexport const REPORT_CHART_COLORS = [\n '4e79a7', 'f28e2b', 'e15759', '76b7b2', '59a14f',\n 'edc948', 'b07aa1', 'ff9da7', '9c755f', 'bab0ac',\n];\n\n// CSS-hex form for ECharts.\nexport const REPORT_CHART_COLORS_CSS = REPORT_CHART_COLORS.map((color) => `#${color}`);\n","import { Injectable } from '@angular/core';\r\n\r\nimport { format } from 'date-fns';\r\n\r\nimport { formatMeasureValue } from '../format';\r\nimport {\r\n ChartConfig,\r\n ComponentData,\r\n LegendPosition,\r\n ListConfig,\r\n KpiConfig,\r\n ReportComponent,\r\n} from '../interfaces/report.interface';\r\nimport { ComponentGeometry, pageGeometry } from '../layout';\r\nimport { extractChartSeries, formatPeriodLabel, isColorBy, resolveLegendPosition, spansMultipleYears } from '../option-builder';\r\nimport { REPORT_CHART_COLORS } from '../theme/palette';\r\nimport { CollectedComponent, CollectedReport, emptyLabel } from './report-export-collector.service';\r\n\r\n\r\n// Component title strip height on the slide, inches.\r\nconst TITLE_H = 0.28;\r\n// Approximate table row height, inches — drives the rows-that-fit cap.\r\nconst TABLE_ROW_H = 0.26;\r\n\r\n// Our legend positions mapped to pptxgenjs's single-letter legendPos codes.\r\n// 'hidden' has no slot — showLegend is turned off instead — so it falls back\r\n// to top.\r\nconst PPTX_LEGEND_POS: Record<LegendPosition, 't' | 'b' | 'l' | 'r'> = {\r\n top: 't',\r\n bottom: 'b',\r\n left: 'l',\r\n right: 'r',\r\n hidden: 't',\r\n};\r\n\r\n// Builds the PowerPoint deck client-side with pptxgenjs. Charts are NATIVE\r\n// editable PowerPoint charts (slide.addChart writes real chart XML with an\r\n// embedded data workbook — \"Edit Data\" works), never images. The page IS the\r\n// slide: the report's unit is inches — exactly PowerPoint's unit — so the\r\n// layout and every component position transfer with no conversion at all.\r\n// pptxgenjs is loaded lazily so it lives in its own webpack chunk.\r\n@Injectable()\r\nexport class ReportPptxService {\r\n\r\n public async export(collected: CollectedReport): Promise<void> {\r\n const PptxGenJS = (await import('pptxgenjs')).default;\r\n\r\n const report = collected.report;\r\n const pageW = report.pageWidth;\r\n const pageH = report.pageHeight;\r\n\r\n const pptx = new PptxGenJS();\r\n pptx.defineLayout({ name: 'REPORT', width: pageW, height: pageH });\r\n pptx.layout = 'REPORT';\r\n pptx.title = report.name;\r\n\r\n this._titleSlide(pptx, collected, pageW, pageH);\r\n\r\n for (const collectedPage of collected.pages) {\r\n const slide = pptx.addSlide();\r\n const geometry = pageGeometry(report, collectedPage.page);\r\n\r\n for (const item of collectedPage.components) {\r\n this._renderComponent(pptx, slide, item, geometry.get(item.component.id));\r\n }\r\n }\r\n\r\n await pptx.writeFile({ fileName: `${this._slug(report.name)}.pptx` });\r\n }\r\n\r\n private _titleSlide(pptx: any, collected: CollectedReport, pageW: number, pageH: number): void {\r\n const slide = pptx.addSlide();\r\n\r\n slide.addText(collected.report.name, {\r\n x: 0.5, y: pageH * 0.3, w: pageW - 1, h: 0.8,\r\n fontSize: 30, bold: true, color: '1F2933',\r\n });\r\n\r\n const lines = [\r\n format(new Date(), 'MMMM d, yyyy'),\r\n ...collected.filterSummary,\r\n ];\r\n\r\n slide.addText(lines.join('\\n'), {\r\n x: 0.5, y: pageH * 0.3 + 0.9, w: pageW - 1, h: Math.max(0.4, lines.length * 0.25),\r\n fontSize: 12, color: '52606D',\r\n });\r\n }\r\n\r\n private _renderComponent(pptx: any, slide: any, item: CollectedComponent, geometry?: ComponentGeometry): void {\r\n const component = item.component;\r\n // Geometry is in inches — PowerPoint's native unit (flow layout arrives\r\n // pre-resolved into rows by pageGeometry).\r\n const { x, y, w, h } = geometry ?? component;\r\n\r\n if (component.title) {\r\n slide.addText(component.title, {\r\n x, y, w, h: TITLE_H,\r\n fontSize: 10, bold: true, color: '1F2933', valign: 'top',\r\n });\r\n }\r\n\r\n const bodyY = y + TITLE_H;\r\n const bodyH = Math.max(0.3, h - TITLE_H);\r\n\r\n if (!item.data || !item.data.rows?.length) {\r\n slide.addText(emptyLabel(item), {\r\n x, y: bodyY, w, h: bodyH,\r\n fontSize: 10, italic: true, color: '7B8794', align: 'center', valign: 'middle',\r\n });\r\n\r\n return;\r\n }\r\n\r\n switch (component.type) {\r\n case 'chart':\r\n this._renderChart(pptx, slide, component, item.data, x, bodyY, w, bodyH);\r\n break;\r\n case 'list':\r\n this._renderTable(slide, component, item.data, x, bodyY, w, bodyH);\r\n break;\r\n case 'kpi':\r\n this._renderKpi(slide, component, item.data, x, bodyY, w, bodyH);\r\n break;\r\n }\r\n }\r\n\r\n private _renderChart(\r\n pptx: any,\r\n slide: any,\r\n component: ReportComponent,\r\n data: ComponentData,\r\n x: number, y: number, w: number, h: number,\r\n ): void {\r\n const config = component.config as ChartConfig;\r\n const chartType = config.chartType ?? 'bar';\r\n const extracted = extractChartSeries(component, data);\r\n\r\n const typeMap: Record<string, any> = {\r\n bar: pptx.ChartType.bar,\r\n line: pptx.ChartType.line,\r\n area: pptx.ChartType.area,\r\n pie: pptx.ChartType.pie,\r\n donut: pptx.ChartType.doughnut,\r\n };\r\n\r\n const pie = chartType === 'pie' || chartType === 'donut';\r\n const colorBy = isColorBy(config);\r\n\r\n // Compact period labels match the on-screen axis (year only when the data\r\n // spans years); PowerPoint can't do a styled second line, so it's inline.\r\n const granularity = data.granularity;\r\n const labels = granularity\r\n ? extracted.categories.map((category) =>\r\n formatPeriodLabel(category, granularity, spansMultipleYears(extracted.categories)))\r\n : extracted.categories;\r\n\r\n // Native chart data: one entry per series (pie charts take exactly one).\r\n // colorBy emits one series per category for the on-screen overlap; PowerPoint\r\n // has no equivalent overlap, so collapse them back into a single series (each\r\n // category's value sits at its own slot) — one full-width bar per category —\r\n // rather than letting PowerPoint cluster them into slivers.\r\n const chartData = colorBy\r\n ? [{\r\n name: config.measures?.[0]?.label ?? config.colorBy?.label ?? '',\r\n labels,\r\n values: extracted.categories.map((_, index) => extracted.series[index]?.values[index] ?? 0),\r\n }]\r\n : (pie ? extracted.series.slice(0, 1) : extracted.series)\r\n .map((series) => ({\r\n name: series.name,\r\n labels,\r\n values: series.values.map((value) => value ?? 0),\r\n }));\r\n\r\n // A single-series colorBy chart can't carry a per-category legend in a native\r\n // PowerPoint bar chart; the category axis labels identify each bar instead.\r\n const legendPosition = colorBy\r\n ? 'hidden'\r\n : resolveLegendPosition(config, extracted.series.length);\r\n\r\n slide.addChart(typeMap[chartType], chartData, {\r\n x, y, w, h,\r\n chartColors: REPORT_CHART_COLORS,\r\n showLegend: legendPosition !== 'hidden',\r\n legendPos: PPTX_LEGEND_POS[legendPosition],\r\n legendFontSize: 9,\r\n barDir: config.orientation === 'horizontal' ? 'bar' : 'col',\r\n barGrouping: config.stacked ? 'stacked' : 'clustered',\r\n holeSize: chartType === 'donut' ? 55 : undefined,\r\n catAxisLabelFontSize: 9,\r\n valAxisLabelFontSize: 9,\r\n showCatAxisTitle: !!config.xAxis?.label,\r\n catAxisTitle: config.xAxis?.label,\r\n catAxisTitleFontSize: 10,\r\n showValAxisTitle: !!config.measures?.[0]?.label && !pie,\r\n valAxisTitle: config.measures?.[0]?.label,\r\n valAxisTitleFontSize: 10,\r\n dataBorder: { pt: 0, color: 'FFFFFF' },\r\n });\r\n }\r\n\r\n private _renderTable(\r\n slide: any,\r\n component: ReportComponent,\r\n data: ComponentData,\r\n x: number, y: number, w: number, h: number,\r\n ): void {\r\n const config = component.config as ListConfig;\r\n const columns = config.columns?.length\r\n ? config.columns\r\n : data.columns.map((column) => ({ column, label: column }));\r\n\r\n const cap = Math.max(2, Math.floor(h / TABLE_ROW_H) - 1);\r\n const rows = data.rows.slice(0, cap);\r\n const remaining = (data.paging?.total ?? data.rows.length) - rows.length;\r\n\r\n const header = columns.map((column) => ({\r\n text: column.label || column.column,\r\n options: { bold: true, color: 'FFFFFF', fill: { color: '4E79A7' } },\r\n }));\r\n\r\n const body = rows.map((row) => columns.map((column) => ({\r\n text: this._cell(row[column.column], column.format),\r\n options: {},\r\n })));\r\n\r\n if (remaining > 0) {\r\n body.push([{\r\n text: `… ${remaining} more row(s) — use the component's CSV export for the full dataset`,\r\n options: { colspan: columns.length, italic: true, color: '7B8794' } as any,\r\n }]);\r\n }\r\n\r\n slide.addTable([header, ...body], {\r\n x, y, w,\r\n fontSize: 9,\r\n color: '1F2933',\r\n border: { type: 'solid', pt: 0.5, color: 'E4E7EB' },\r\n autoPage: false,\r\n rowH: TABLE_ROW_H,\r\n valign: 'middle',\r\n });\r\n }\r\n\r\n private _renderKpi(\r\n slide: any,\r\n component: ReportComponent,\r\n data: ComponentData,\r\n x: number, y: number, w: number, h: number,\r\n ): void {\r\n const config = component.config as KpiConfig;\r\n const row = data.rows[0] ?? {};\r\n const column = config.measure?.column ?? Object.keys(row)[0];\r\n const value = formatMeasureValue(row[column], config.measure?.format, config.measure?.precision);\r\n\r\n slide.addText([\r\n { text: value, options: { fontSize: 28, bold: true, color: '1F2933', breakLine: true } },\r\n { text: config.measure?.label ?? '', options: { fontSize: 10, color: '7B8794' } },\r\n ], {\r\n x, y, w, h,\r\n align: 'center',\r\n valign: 'middle',\r\n });\r\n }\r\n\r\n // The exported cell must read like the on-screen cell: the SQL already\r\n // carries the formatting, so the value goes out verbatim. A raw date is the\r\n // one value the client renders (the column stays a RAW timestamp for the\r\n // report timezone), and it is rendered here too.\r\n private _cell(value: unknown, columnFormat?: string): string {\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n\r\n if (columnFormat === 'date') {\r\n const date = new Date(String(value));\r\n\r\n return Number.isNaN(date.getTime()) ? String(value) : format(date, 'MMM d, yyyy');\r\n }\r\n\r\n return String(value);\r\n }\r\n\r\n private _slug(name: string): string {\r\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'report';\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\n\nimport { FsPrompt } from '@firestitch/prompt';\n\nimport { EMPTY, Observable, from, of } from 'rxjs';\nimport { catchError, switchMap } from 'rxjs/operators';\n\nimport { Report } from '../interfaces/report.interface';\nimport { CollectedReport, ReportExportCollectorService, failedPageNames } from './report-export-collector.service';\nimport { ReportPdfService } from './report-pdf.service';\nimport { ReportPptxService } from './report-pptx.service';\n\n\n// What the user chose when told the export is incomplete. Retry re-runs the\n// whole collection — the queries that failed were killed on a clock, not on\n// anything about the data, so a second attempt against a warmed database\n// genuinely often succeeds.\nconst RETRY = 'retry';\nconst DOWNLOAD = 'download';\n\n// Runs a report export end to end: collect every tile, refuse to write a file\n// that is missing any of them without saying so, then render.\n//\n// The gate is the reason this sits between the collector and the renderers\n// rather than in either of them. A deck with five blank pages is worse than no\n// deck: it looks finished, so it gets emailed to a client, and the pages that\n// are missing are exactly the ones nobody thinks to check. The renderers can\n// only describe a hole they are handed; the collector only knows one tile at a\n// time. Whether the FILE should exist is a decision about the whole report, and\n// this is the only place that sees it.\n@Injectable()\nexport class ReportExportService {\n\n private _collector = inject(ReportExportCollectorService);\n private _pdfService = inject(ReportPdfService);\n private _pptxService = inject(ReportPptxService);\n private _prompt = inject(FsPrompt);\n\n public pdf(report: Report): Observable<unknown> {\n return this._run(report, (collected) => this._pdfService.export(collected));\n }\n\n public powerpoint(report: Report): Observable<unknown> {\n return this._run(report, (collected) => this._pptxService.export(collected));\n }\n\n // Retry re-collects the WHOLE report, not just the tiles that failed. Every\n // number in one file has to have been true at one moment: refetching four\n // tiles and keeping nine from three minutes ago produces a deck whose pages\n // disagree with each other, and nothing on it would say so.\n private _run(report: Report, render: (collected: CollectedReport) => Promise<void>): Observable<unknown> {\n return this._collector.collect(report)\n .pipe(\n switchMap((collected) => this._gate(collected)\n .pipe(\n switchMap((choice) => choice === RETRY\n ? this._run(report, render)\n : from(render(collected))),\n )),\n );\n }\n\n // Resolves to DOWNLOAD when the export is whole (or the user accepted an\n // incomplete one) and to RETRY when they want another attempt. Cancelling\n // ends the export quietly: EMPTY completes without emitting, so nothing\n // renders and no error surfaces — they know what they just declined.\n private _gate(collected: CollectedReport): Observable<string> {\n const failed = failedPageNames(collected);\n if (!failed.length) {\n return of(DOWNLOAD);\n }\n\n const pages = failed.length === 1\n ? `<strong>${failed[0]}</strong> could not be generated`\n : `${failed.length} pages could not be generated: <strong>${failed.join('</strong>, <strong>')}</strong>`;\n\n return this._prompt.confirm({\n title: 'Export is incomplete',\n template: `${pages}. This usually means those tiles took too long to load. `\n + 'Retry, or download the file with those pages marked as missing.',\n buttons: [\n { label: 'Retry', value: RETRY, color: 'primary' },\n { label: 'Download Anyway', value: DOWNLOAD, color: '' },\n { label: 'Cancel', cancel: true, color: '' },\n ],\n })\n .pipe(catchError(() => EMPTY));\n }\n}\n","import { Injectable, inject } from '@angular/core';\n\nimport { BehaviorSubject, Observable, of } from 'rxjs';\nimport { map, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../data/report.data';\nimport { ReportListItem } from '../interfaces/report.interface';\n\n\n// Holds the report list in memory so the picker doesn't hit the API on every\n// focus. Loaded once when the page opens; create/rename/delete keep the cache\n// in sync.\n@Injectable({\n providedIn: 'root',\n})\nexport class ReportService {\n\n private _reportData = inject(ReportData);\n\n private _reports$ = new BehaviorSubject<ReportListItem[]>([]);\n\n public get reports$(): Observable<ReportListItem[]> {\n return this._reports$.asObservable();\n }\n\n public load(): Observable<ReportListItem[]> {\n return this._reportData.reports()\n .pipe(\n tap((reports: ReportListItem[]) => this._reports$.next(reports ?? [])),\n );\n }\n\n // Filters the cached list locally — what the autocomplete's [fetch] calls.\n public filter(keyword: string): Observable<ReportListItem[]> {\n const term = (keyword ?? '').trim().toLowerCase();\n const reports = this._reports$.getValue();\n\n if (!term) {\n return of(reports);\n }\n\n return of(reports.filter((report) => report.name.toLowerCase().includes(term)));\n }\n\n public create(name: string): Observable<ReportListItem> {\n return this._reportData.create(name)\n .pipe(\n tap((report: ReportListItem) => {\n this._reports$.next([...this._reports$.getValue(), report]);\n }),\n );\n }\n\n public rename(reportId: number, name: string): Observable<ReportListItem> {\n return this._reportData.rename(reportId, name)\n .pipe(\n tap((report: ReportListItem) => {\n this._reports$.next(\n this._reports$.getValue()\n .map((existing) => (existing.id === report.id ? report : existing)),\n );\n }),\n );\n }\n\n public delete(reportId: number): Observable<void> {\n return this._reportData.delete(reportId)\n .pipe(\n tap(() => {\n this._reports$.next(\n this._reports$.getValue().filter((report) => report.id !== reportId),\n );\n }),\n map(() => undefined),\n );\n }\n}\n","import {\r\n CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Component,\r\n DestroyRef, ElementRef, NgZone, ViewChild, inject,\r\n} from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\n\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\nimport { FsAutocompleteChipsModule } from '@firestitch/autocomplete-chips';\r\nimport { FilterConfig, FsFilterModule, IFilterConfigItem } from '@firestitch/filter';\r\nimport { FsMenuModule } from '@firestitch/menu';\r\nimport { FsProcess } from '@firestitch/process';\r\nimport { FsPrompt } from '@firestitch/prompt';\r\n\r\nimport { finalize, switchMap, takeUntil } from 'rxjs/operators';\r\n\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { provideEchartsCore } from 'ngx-echarts';\r\n\r\nimport { FsAiChatComponent, FsAiChatResponse } from '@firestitch/ai';\r\n\r\nimport { ReportCanvasComponent } from '../../components/report-canvas/report-canvas.component';\r\nimport { ReportData } from '../../data/report.data';\r\nimport { ComponentSettingsComponent, ComponentSettingsResult } from '../../dialogs/component-settings/component-settings.component';\r\nimport { ReportSettingsComponent, ReportSettingsResult } from '../../dialogs/report-settings/report-settings.component';\r\nimport { ReportExportCollectorService } from '../../export/report-export-collector.service';\r\nimport { ReportExportService } from '../../export/report-export.service';\r\nimport { ReportPdfService } from '../../export/report-pdf.service';\r\nimport { ReportPptxService } from '../../export/report-pptx.service';\r\nimport {\r\n ChartGranularity, Report,\r\n ReportComponent as ReportComponentModel, ReportFilterGroup, ReportListItem,\r\n} from '../../interfaces/report.interface';\r\nimport {\r\n GROUP_BY_ITEM, filterItemForGroup, groupByFilterItem, groupBySignature, groupValuesFromQuery,\r\n isGranularityOffered,\r\n} from '../../report-filter-items';\r\nimport { ReportFilterStateService, defaultSignature } from '../../services/report-filter-state.service';\r\nimport { ReportService } from '../../services/report.service';\r\n\r\n\r\n// The Reports page: AI chat on the left, the report canvas on the right —\r\n// a split-pane layout; the viewer is our own canvas (no iframe, no embed URLs).\r\n// The chat is always scoped to the selected report; its id rides on every\r\n// turn via [requestData].\r\n@Component({\r\n templateUrl: './report.component.html',\r\n styleUrls: ['./report.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true,\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n providers: [\r\n // Session filter state is per-open-report-page, not app-global; the export\r\n // services resolve filters through it, so they live at the same level.\r\n ReportFilterStateService,\r\n ReportExportCollectorService,\r\n ReportPptxService,\r\n ReportPdfService,\r\n ReportExportService,\r\n // Tree-shaken ECharts core + the 'report' house theme, loaded lazily with\r\n // this route's chunk.\r\n provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),\r\n ],\r\n imports: [\r\n FormsModule,\r\n FsAutocompleteChipsModule,\r\n FsFilterModule,\r\n FsMenuModule,\r\n FsAiChatComponent,\r\n MatIcon,\r\n ReportCanvasComponent,\r\n ],\r\n})\r\nexport class ReportComponent {\r\n\r\n // The single report the viewer and chat are focused on.\r\n public selected: ReportListItem | null = null;\r\n public report: Report | null = null;\r\n public loadingReports = true;\r\n public editMode = false;\r\n\r\n // The report toolbar IS an fs-filter: the picker rides in its heading\r\n // template, the menu becomes its actions, and report-level filter groups\r\n // become its items. Rebuilt whenever the loaded report (and thus its groups)\r\n // changes; the menu's show-guards keep working while no report is selected.\r\n public reportFilterConfig!: FilterConfig;\r\n\r\n @ViewChild('split', { static: true })\r\n private _split!: ElementRef<HTMLDivElement>;\r\n\r\n @ViewChild('chatPanel', { static: true, read: ElementRef })\r\n private _chatPanel!: ElementRef<HTMLElement>;\r\n\r\n // Only the canvas knows which page is on screen, and a page-scoped export\r\n // has to ask it.\r\n @ViewChild(ReportCanvasComponent)\r\n private _canvas?: ReportCanvasComponent;\r\n\r\n public readonly introMessage = {\r\n text: '',\r\n };\r\n\r\n private _reportData = inject(ReportData);\r\n private _reportService = inject(ReportService);\r\n private _filterState = inject(ReportFilterStateService);\r\n private _exportService = inject(ReportExportService);\r\n private _process = inject(FsProcess);\r\n private _prompt = inject(FsPrompt);\r\n private _dialog = inject(MatDialog);\r\n private _destroyRef = inject(DestroyRef);\r\n private _cdRef = inject(ChangeDetectorRef);\r\n private _zone = inject(NgZone);\r\n\r\n constructor() {\r\n this._buildReportConfig();\r\n\r\n this._reportService.load()\r\n .pipe(\r\n finalize(() => {\r\n this.loadingReports = false;\r\n this._cdRef.markForCheck();\r\n }),\r\n takeUntilDestroyed(this._destroyRef),\r\n )\r\n .subscribe({ error: () => undefined });\r\n }\r\n\r\n public fetchReports = (keyword: string) => {\r\n return this._reportService.filter(keyword);\r\n };\r\n\r\n public reportChange(report: ReportListItem | null): void {\r\n this.report = null;\r\n this.editMode = false;\r\n this._buildReportConfig();\r\n\r\n if (report) {\r\n this._loadReport(report.id);\r\n }\r\n }\r\n\r\n public createReport(): void {\r\n this._prompt.input({\r\n title: 'Create Report',\r\n label: 'Name',\r\n commitLabel: 'Create',\r\n required: true,\r\n })\r\n .pipe(\r\n switchMap((name: string) => this._reportService.create(name)),\r\n takeUntilDestroyed(this._destroyRef),\r\n )\r\n .subscribe((report: ReportListItem) => {\r\n this.selected = report;\r\n this._cdRef.markForCheck();\r\n this._loadReport(report.id);\r\n });\r\n }\r\n\r\n public toggleEditMode(): void {\r\n this.editMode = !this.editMode;\r\n }\r\n\r\n // Report settings — name, page size, orientation, layout mode. The picker\r\n // list and structure both reload on save (a layout switch re-renders the\r\n // whole canvas).\r\n public reportSettings(): void {\r\n if (!this.report) {\r\n return;\r\n }\r\n\r\n this._dialog.open<ReportSettingsComponent, unknown, ReportSettingsResult>(ReportSettingsComponent, {\r\n data: { report: this.report },\r\n width: '460px',\r\n })\r\n .afterClosed()\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe((result) => {\r\n // The dialog confirms + performs the delete itself; we just react to\r\n // what it reports back.\r\n if (result?.action === 'deleted') {\r\n this.selected = null;\r\n this.report = null;\r\n this._buildReportConfig();\r\n this._cdRef.markForCheck();\r\n\r\n return;\r\n }\r\n\r\n if (result?.action === 'saved' && this.selected) {\r\n this._loadReport(this.selected.id);\r\n this._refreshReportName(this.selected.id);\r\n }\r\n });\r\n }\r\n\r\n // Component settings — title, exact geometry, and the diagnostic views\r\n // (SQL, config, filter wiring).\r\n public componentSettings(component: ReportComponentModel): void {\r\n if (!this.report) {\r\n return;\r\n }\r\n\r\n const dialogRef = this._dialog.open<ComponentSettingsComponent, unknown, ComponentSettingsResult>(\r\n ComponentSettingsComponent,\r\n {\r\n data: { report: this.report, component },\r\n width: '640px',\r\n },\r\n );\r\n\r\n // Filter add/remove/level changes persist immediately inside the dialog (no\r\n // \"save\") and can leave it by an exit that carries no result, so they are\r\n // announced as they land. The reload waits for the close so the canvas isn't\r\n // re-rendering underneath an open dialog.\r\n let filtersChanged = false;\r\n dialogRef.componentInstance.filtersChanged\r\n .pipe(takeUntil(dialogRef.afterClosed()))\r\n .subscribe(() => filtersChanged = true);\r\n\r\n dialogRef.afterClosed()\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe((result) => {\r\n // The report's filter groups changed, so the report bar and the\r\n // on-component strips have to be rebuilt from a fresh report.\r\n if (filtersChanged) {\r\n if (this.selected) {\r\n this._loadReport(this.selected.id);\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Nothing else in the dialog touches the query — title and padding are\r\n // presentation. Repaint the one component it was opened for and leave\r\n // every other component's data, and its query, alone.\r\n if (result?.settings) {\r\n this._canvas?.applyComponentSettings(component.id, result.settings);\r\n }\r\n });\r\n }\r\n\r\n // The canvas changed the report's structure (added a page) — re-fetch so the\r\n // new page renders; the canvas lands the view on it.\r\n public onCanvasReportChanged(): void {\r\n if (this.selected) {\r\n this._loadReport(this.selected.id);\r\n }\r\n }\r\n\r\n // Export the report to PowerPoint, entirely client-side: every component's\r\n // data is fetched fresh with the current filter state (all pages, not just\r\n // the visible one), then pptxgenjs builds a deck of NATIVE editable charts —\r\n // page = slide, positions 1:1. The dock shows progress until the file saves.\r\n public exportPowerpoint(): void {\r\n if (!this.report) {\r\n return;\r\n }\r\n\r\n this._process.run(\r\n 'Exporting PowerPoint',\r\n this._exportService.powerpoint(this.report),\r\n );\r\n }\r\n\r\n // Export to PDF, entirely client-side: same collection pass, charts rendered\r\n // through an offscreen ECharts instance at 3× pixel ratio (pixel-identical\r\n // to the screen), tables via jspdf-autotable — page = PDF page.\r\n public exportPdf(): void {\r\n if (!this.report) {\r\n return;\r\n }\r\n\r\n this._process.run(\r\n 'Exporting PDF',\r\n this._exportService.pdf(this.report),\r\n );\r\n }\r\n\r\n // The raw data behind the whole report in one action: the server exports every\r\n // component's full filtered dataset and zips one CSV per component, foldered\r\n // by page. `thisPage` narrows it to the page the canvas is showing. Unlike the\r\n // PDF/PowerPoint exports this is entirely server-side — nothing is collected\r\n // in the browser, so it is not capped by what a slide can hold.\r\n public exportData(thisPage = false): void {\r\n const report = this.report;\r\n if (!report) {\r\n return;\r\n }\r\n\r\n const pageId = thisPage ? this._canvas?.activePage?.id ?? null : null;\r\n\r\n this._process.download(\r\n 'Exporting data',\r\n this._reportData.exportReport(report.id, this._filterState.resolveForReport(report, pageId), pageId),\r\n );\r\n }\r\n\r\n // React to each chat turn (fs-chat handles the request + persistence); we\r\n // only care about the report side effects this context's backend flags.\r\n public onChatResponse(response: FsAiChatResponse): void {\r\n // The agent changed the report's structure — re-fetch it. Session filter\r\n // values survive (the filter-state service keeps values for groups that\r\n // still exist).\r\n if (response.reportChanged && this.selected) {\r\n this._loadReport(this.selected.id);\r\n }\r\n\r\n // A rename changes nothing structural — refresh the picker chip label.\r\n if (response.reportRenamed && this.selected) {\r\n this._refreshReportName(this.selected.id);\r\n }\r\n }\r\n\r\n // Drag the divider between the chat and canvas panes (pointer-capture loop\r\n // outside Angular).\r\n public onResizeStart(event: PointerEvent): void {\r\n event.preventDefault();\r\n\r\n const handle = event.target as HTMLElement;\r\n handle.setPointerCapture(event.pointerId);\r\n this._split.nativeElement.classList.add('resizing');\r\n\r\n this._zone.runOutsideAngular(() => {\r\n const move = (e: PointerEvent) => this._resizeTo(e.clientX);\r\n const end = () => {\r\n handle.releasePointerCapture(event.pointerId);\r\n handle.removeEventListener('pointermove', move);\r\n handle.removeEventListener('pointerup', end);\r\n handle.removeEventListener('pointercancel', end);\r\n this._split.nativeElement.classList.remove('resizing');\r\n };\r\n\r\n handle.addEventListener('pointermove', move);\r\n handle.addEventListener('pointerup', end);\r\n handle.addEventListener('pointercancel', end);\r\n });\r\n }\r\n\r\n private _resizeTo(clientX: number): void {\r\n const rect = this._split.nativeElement.getBoundingClientRect();\r\n if (rect.width === 0) {\r\n return;\r\n }\r\n\r\n const ratio = (clientX - rect.left) / rect.width;\r\n const clamped = Math.min(0.8, Math.max(0.2, ratio));\r\n this._chatPanel.nativeElement.style.flexBasis = `${clamped * 100}%`;\r\n }\r\n\r\n private _loadReport(reportId: number): void {\r\n this._reportData.get(reportId)\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe((report: Report) => {\r\n this.report = report;\r\n this._filterState.init(report);\r\n this._buildReportConfig();\r\n this._cdRef.markForCheck();\r\n });\r\n }\r\n\r\n // Report-level filter groups in their saved order — the ones that render in\r\n // the toolbar (component-level groups render on their components).\r\n private _reportGroups(): ReportFilterGroup[] {\r\n return (this.report?.filterGroups ?? [])\r\n .filter((group) => group.level === 'report' || group.level === 'both')\r\n .sort((a, b) => a.order - b.order);\r\n }\r\n\r\n // Gates the toolbar fs-filter so it isn't rendered (taking space) when there\r\n // is nothing to put in it — no report-level filters and no group-by control.\r\n public get reportHasFilters(): boolean {\r\n return this._reportGroups().length > 0 || !!this._groupByItem();\r\n }\r\n\r\n // fs-filter reads its config only once (at init) — re-binding does nothing.\r\n // The template keys the toolbar fs-filter on this signature so it's recreated\r\n // (and re-reads the rebuilt config) whenever the report-level filter set\r\n // changes, e.g. after the component settings dialog adds/moves a filter.\r\n public get reportFilterKey(): string {\r\n return [\r\n // The stored default is part of the signature: saving a new default in report\r\n // settings rebuilds the config, but without a key change fs-filter keeps\r\n // rendering the values it was created with until a full page reload.\r\n groupBySignature(this.report),\r\n ...this._reportGroups().map((group) => `${group.id}:${group.level}:${group.label}:${defaultSignature(group)}`),\r\n ].join('|');\r\n }\r\n\r\n // (Re)build the toolbar fs-filter config — the report-level filter items and\r\n // then the group-by control. The report's actions live in the fs-menu beside\r\n // the picker, not here. Only built/used once a report is loaded (the template\r\n // gates it on `report`).\r\n private _buildReportConfig(): void {\r\n const reportId = this.report?.id ?? null;\r\n\r\n // Drop a grain the control no longer offers — the agent can narrow the list\r\n // mid-session, and an override the viewer can't see is worse than none.\r\n if (this.report && !isGranularityOffered(this.report, this._filterState.frequency())) {\r\n this._filterState.setFrequency(null);\r\n }\r\n\r\n const items = reportId\r\n ? this._reportGroups().map((group) =>\r\n filterItemForGroup(group, this._reportData, reportId, this._filterState.value(group.id)))\r\n : [];\r\n\r\n // The group-by control leads the bar, ahead of every filter: it sets the\r\n // grain the whole report is read at, so it is the first thing a viewer\r\n // decides. It is not a filter group — it re-buckets rows rather than\r\n // narrowing them — so it is placed here rather than ordered among them.\r\n const groupByItem = this._groupByItem();\r\n if (groupByItem) {\r\n items.unshift(groupByItem);\r\n }\r\n\r\n this.reportFilterConfig = {\r\n // Never touch the URL or persist filter state — report filters are\r\n // session-only, owned by ReportFilterStateService.\r\n queryParam: false,\r\n persist: false,\r\n items,\r\n change: (query) => {\r\n for (const { groupId, value } of groupValuesFromQuery(query ?? {}, this._reportGroups())) {\r\n this._filterState.setValue(groupId, value);\r\n }\r\n // Not a filter group — the grain is read straight off the query.\r\n this._filterState.setFrequency((query?.[GROUP_BY_ITEM] as ChartGranularity) || null);\r\n },\r\n };\r\n }\r\n\r\n // The report's group-by control as an fs-filter item, or null when the report\r\n // has none to show. Seeded from the session state so the grain the viewer\r\n // picked survives the report being re-fetched after a chat edit.\r\n private _groupByItem(): IFilterConfigItem | null {\r\n return this.report\r\n ? groupByFilterItem(this.report, this._filterState.frequency())\r\n : null;\r\n }\r\n\r\n private _refreshReportName(reportId: number): void {\r\n this._reportService.load()\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe((reports: ReportListItem[]) => {\r\n const renamed = reports.find((report) => report.id === reportId);\r\n if (renamed) {\r\n this.selected = renamed;\r\n if (this.report) {\r\n this.report = { ...this.report, name: renamed.name };\r\n }\r\n this._cdRef.markForCheck();\r\n }\r\n });\r\n }\r\n}\r\n","<div\n #split\n class=\"report fs-row.align-start\">\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n style=\"min-height: 500px;\"\n basePath=\"reports\"\n [requestData]=\"{ reportId: selected?.id ?? null }\"\n [introMessage]=\"introMessage\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n <div class=\"viewer fs-flex fs-column\">\n <div class=\"fs-row.align-center.gap-sm\">\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [fetch]=\"fetchReports\"\n [(ngModel)]=\"selected\"\n [disabled]=\"loadingReports\"\n [padless]=\"true\"\n [multiple]=\"false\"\n [fetchOnFocus]=\"true\"\n (ngModelChange)=\"reportChange($event)\"\n placeholder=\"Report\"\n name=\"report\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"createReport()\">\n Create Report\n </ng-template>\n </fs-autocomplete-chips>\n @if (report) {\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"reportSettings()\">\n <mat-icon>\n tune\n </mat-icon>\n Report settings\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"toggleEditMode()\"\n [disabled]=\"editMode\">\n <mat-icon>\n dashboard_2_edit\n </mat-icon>\n {{ editMode ? 'Done editing layout' : 'Edit layout' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n <mat-icon>\n slideshow\n </mat-icon>\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n <mat-icon>\n picture_as_pdf\n </mat-icon>\n Export PDF\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportData()\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data\n </ng-template>\n @if ((report?.pages?.length ?? 0) > 1) {\n <ng-template\n fs-menu-item\n (click)=\"exportData(true)\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data (This Page)\n </ng-template>\n }\n </fs-menu>\n }\n </div>\n @if (report) {\n <!-- Report-level filters only (the report's actions live in the menu\n above). fs-filter reads its config once at init, so it's keyed on the\n filter signature: when the report-level filter set changes the block\n is recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters) {\n @for (key of [reportFilterKey]; track key) {\n <fs-filter [config]=\"reportFilterConfig\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report\"\n [editMode]=\"editMode\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\"\n (editDone)=\"toggleEditMode()\">\n </app-report-canvas>\n }\n </div>\n</div>","import { ChangeDetectionStrategy, Component, DestroyRef, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { MatButton } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog';\n\nimport { FsChipModule } from '@firestitch/chip';\nimport { FsDateModule } from '@firestitch/date';\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsMarkdownRendererComponent } from '@firestitch/markdown-editor';\nimport { FsMessage, FsMessageModule } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\n\nimport { switchMap } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportInstruction, ReportInstructions } from '../../interfaces/report.interface';\n\n\nexport interface InstructionHistoryDialogData {\n versions: ReportInstruction[];\n}\n\n\n// The AI Knowledge document's version history (append-only), each version\n// previewed and restorable — opened from the Report Settings footer's View\n// History button. Restores happen here (confirm, then flip the current flag —\n// no new version is created); the opener refreshes its instructions after this\n// dialog closes, so a restore made here reseeds the editor there.\n@Component({\n templateUrl: './instruction-history.component.html',\n styleUrls: ['./instruction-history.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatButton,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n FsChipModule,\n FsDateModule,\n FsDialogModule,\n FsMarkdownRendererComponent,\n FsMessageModule,\n ],\n})\nexport class InstructionHistoryComponent {\n\n private readonly _data = inject<InstructionHistoryDialogData>(MAT_DIALOG_DATA);\n\n public readonly versions = signal<ReportInstruction[]>(this._data.versions);\n\n private readonly _reportData = inject(ReportData);\n private readonly _prompt = inject(FsPrompt);\n private readonly _message = inject(FsMessage);\n private readonly _destroyRef = inject(DestroyRef);\n\n // Make an earlier version current — flips the flag, creates no new version.\n public restore(version: ReportInstruction): void {\n this._prompt.confirm({\n title: 'Restore version',\n template: 'Make this version the current AI knowledge? The newer versions stay in the history.',\n commitLabel: 'Restore',\n })\n .pipe(\n switchMap(() => this._reportData.restoreInstruction(version.id)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((instructions: ReportInstructions) => {\n this.versions.set(instructions.versions);\n this._message.success('Version restored');\n });\n }\n}\n","<fs-dialog>\n <fs-dialog-title>\n AI Knowledge History\n </fs-dialog-title>\n <mat-dialog-content>\n @if (versions().length) {\n <div class=\"versions\">\n @for (version of versions(); track version.id) {\n <div class=\"version\">\n <div class=\"version-header\">\n <fs-date\n [date]=\"version.createDate\"\n format=\"date-time\">\n </fs-date>\n @if (version.accountName) {\n <span class=\"author\">{{ version.accountName }}</span>\n }\n <span class=\"spacer\"></span>\n @if (version.current) {\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"'#2e7d32'\"\n color=\"#ffffff\">\n Current\n </fs-chip>\n } @else {\n <button\n type=\"button\"\n mat-stroked-button\n (click)=\"restore(version)\">\n Restore\n </button>\n }\n </div>\n <div class=\"version-preview\">\n <fs-markdown-renderer [markdown]=\"version.content\"></fs-markdown-renderer>\n </div>\n </div>\n }\n </div>\n } @else {\n <fs-message-info>\n No versions yet — every save of the AI Knowledge document lands here, and\n any version can be restored.\n </fs-message-info>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Close\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n","import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';\nimport { ControlContainer, FormsModule, NgForm } from '@angular/forms';\n\nimport { FsFormModule } from '@firestitch/form';\nimport { FsMarkdownEditorComponent, FsMarkdownEditorConfig } from '@firestitch/markdown-editor';\n\n\n// The AI Knowledge tab: the operator-authored markdown document appended to the\n// report agent's system instructions on every chat turn — the lever for\n// terminology, business rules and special cases no code deploy can cover.\n//\n// A field-level child of the settings dialog form: the editor registers with\n// the parent <form fsForm> via the ControlContainer view provider, so the\n// dialog's Save button submits and validates this content. The draft itself\n// lives on the parent (bound through `content`), so switching tabs never loses\n// an edit.\n@Component({\n selector: 'fs-ai-report-global-settings-ai-knowledge',\n templateUrl: './ai-knowledge.component.html',\n styleUrls: ['./ai-knowledge.component.scss'],\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsFormModule,\n FsMarkdownEditorComponent,\n ],\n})\nexport class AiKnowledgeComponent {\n\n public readonly content = model<string>('');\n public readonly config = input.required<FsMarkdownEditorConfig>();\n}\n","<div class=\"fs-column tab-body\">\n <p class=\"hint\">\n This document is given to the report AI on every chat message. Use it for\n terminology, business rules and special cases the AI can't work out from the\n data on its own — it takes effect immediately, no deploy needed.\n </p>\n <fs-markdown-editor\n [ngModel]=\"content()\"\n (ngModelChange)=\"content.set($event)\"\n [config]=\"config()\"\n name=\"content\">\n </fs-markdown-editor>\n</div>\n","import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';\nimport { ControlContainer, FormsModule, NgForm } from '@angular/forms';\n\nimport { MatFormField, MatHint, MatLabel } from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\n\nimport { FsFormModule } from '@firestitch/form';\n\n\n// The General tab: report-module settings that aren't the AI knowledge document.\n// Currently just the semantic-build concurrency — how many summary calls the\n// build runs at once. A field-level child of the settings dialog form (its input\n// registers with the parent <form fsForm> via the ControlContainer view\n// provider), so the dialog's Save button submits and validates it. The value\n// itself is held on the shell (bound through `concurrency`), and the safe band\n// (`min`/`max`) comes from the backend so the field can't be set out of range.\n@Component({\n selector: 'fs-ai-report-global-settings-general',\n templateUrl: './general.component.html',\n styleUrls: ['./general.component.scss'],\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsFormModule,\n MatFormField,\n MatLabel,\n MatHint,\n MatInput,\n ],\n})\nexport class GeneralComponent {\n\n public readonly concurrency = model<number>(0);\n public readonly min = input.required<number>();\n public readonly max = input.required<number>();\n}\n","<div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>Semantic build concurrency</mat-label>\n <input\n matInput\n type=\"number\"\n [ngModel]=\"concurrency()\"\n (ngModelChange)=\"concurrency.set($event)\"\n name=\"semanticBuildConcurrency\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"min()\"\n [fsFormMax]=\"max()\">\n <mat-hint>\n How many AI calls the semantic-database build runs at once ({{ min() }}–{{ max() }}).\n Higher is faster but more likely to hit the AI provider's rate limit. Default is 8.\n </mat-hint>\n </mat-form-field>\n</div>\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { MatButton } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog';\n\nimport { FsChipModule } from '@firestitch/chip';\nimport { FsDateModule } from '@firestitch/date';\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\n\nimport { ReportData } from '../../data/report.data';\nimport {\n SemanticEntityFunction,\n SemanticEntityFunctions,\n SemanticFunctionSource,\n} from '../../interfaces/report.interface';\n\n\nexport interface EntityFunctionsDialogData {\n entityKey: string;\n source: SemanticFunctionSource;\n}\n\n\n// One group of a unit's AI-classified cached code functions — an entity's model\n// or handler class, or the single group of a standalone code class. Fetched on\n// open from the shared per-key endpoint (one payload carries every group, each\n// row tagged with its source) and filtered client-side.\n@Component({\n templateUrl: './entity-functions.component.html',\n styleUrls: ['./entity-functions.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatButton,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n FsChipModule,\n FsDateModule,\n FsDialogModule,\n FsSkeletonModule,\n ],\n})\nexport class EntityFunctionsComponent {\n\n // One color per AI classification kind, so a function's nature reads at a glance.\n private static readonly KIND_COLORS: Record<string, string> = {\n 'calculation': '#1565c0',\n 'business-rule': '#6a1b9a',\n 'query': '#00695c',\n 'mutation': '#e65100',\n 'accessor': '#546e7a',\n 'other': '#757575',\n };\n\n // Interesting logic first: derived values and rules, then data access, then the rest.\n private static readonly KIND_ORDER = ['calculation', 'business-rule', 'query', 'mutation', 'accessor', 'other'];\n\n // The dialog title per group. A standalone class has no model/handler split,\n // so its one group is just the code the build read.\n private static readonly SOURCE_LABELS: Record<SemanticFunctionSource, string> = {\n model: 'Model functions',\n handler: 'Handler functions',\n class: 'Code functions',\n };\n\n private readonly _data = inject<EntityFunctionsDialogData>(MAT_DIALOG_DATA);\n\n public readonly entityKey = this._data.entityKey;\n public readonly sourceLabel = EntityFunctionsComponent.SOURCE_LABELS[this._data.source];\n\n // null until loaded — gates the list behind the skeleton.\n public readonly entityFunctions = signal<SemanticEntityFunctions | null>(null);\n\n // The class this group's functions were discovered from. A standalone code\n // class has no handler, so its group reads the model slot like 'model' does.\n public readonly discoveredClass = computed<string | null>(() => {\n const loaded = this.entityFunctions();\n\n return this._data.source === 'handler' ? loaded?.handlerClass : loaded?.modelClass;\n });\n\n // This group's functions, ordered by kind priority then method name.\n public readonly functions = computed<SemanticEntityFunction[]>(() =>\n this._sortFunctions(\n (this.entityFunctions()?.functions ?? [])\n .filter((fn) => fn.source === this._data.source),\n ),\n );\n\n constructor() {\n inject(ReportData).semanticEntityFunctions(this._data.entityKey)\n .pipe(takeUntilDestroyed())\n .subscribe((entityFunctions: SemanticEntityFunctions) => {\n this.entityFunctions.set(entityFunctions);\n });\n }\n\n public kindColor(kind: string): string {\n return EntityFunctionsComponent.KIND_COLORS[kind] ?? EntityFunctionsComponent.KIND_COLORS.other;\n }\n\n private _sortFunctions(functions: SemanticEntityFunction[]): SemanticEntityFunction[] {\n return [...functions]\n .sort((a, b) => {\n const kindDiff = this._kindRank(a.kind) - this._kindRank(b.kind);\n\n return kindDiff !== 0 ? kindDiff : a.method.localeCompare(b.method);\n });\n }\n\n private _kindRank(kind: string): number {\n const rank = EntityFunctionsComponent.KIND_ORDER.indexOf(kind);\n\n return rank === -1 ? EntityFunctionsComponent.KIND_ORDER.length : rank;\n }\n}\n","<fs-dialog>\n <fs-dialog-title>\n {{ entityKey }} — {{ sourceLabel }}\n </fs-dialog-title>\n <mat-dialog-content>\n <div *fsSkeleton=\"entityFunctions()\">\n @if (entityFunctions(); as fns) {\n @if (functions().length) {\n @if (fns.generatedAt) {\n <div class=\"hint functions-generated\">\n Discovered from {{ discoveredClass() }} &middot;\n <fs-date\n [date]=\"fns.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n }\n <div class=\"functions-list\">\n @for (fn of functions(); track fn.class + '::' + fn.method) {\n <div class=\"function-row\">\n <div class=\"function-head\">\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"kindColor(fn.kind)\"\n color=\"#ffffff\">\n {{ fn.kind }}\n </fs-chip>\n <code class=\"function-method\">{{ fn.method }}</code>\n </div>\n <div class=\"function-summary\">{{ fn.summary }}</div>\n @if (fn.produces) {\n <div class=\"function-produces hint\">Produces: {{ fn.produces }}</div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"hint\">\n No functions cached for this entity yet — run a build to discover its code.\n </div>\n }\n }\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Close\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatExpansionModule } from '@angular/material/expansion';\nimport { MatTooltipModule } from '@angular/material/tooltip';\n\nimport { StreamEventType } from '@firestitch/api';\nimport { FsChipModule } from '@firestitch/chip';\nimport { FsDateModule } from '@firestitch/date';\nimport { FsMessage, FsMessageModule } from '@firestitch/message';\nimport { FsProcess } from '@firestitch/process';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\n\nimport { filter, map, switchMap, take, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../../../../data/report.data';\nimport {\n SemanticBuildClass,\n SemanticBuildEntity,\n SemanticBuildStatus,\n SemanticBuildTable,\n SemanticFunctionSource,\n} from '../../../../interfaces/report.interface';\nimport { EntityFunctionsComponent } from '../../../entity-functions/entity-functions.component';\n\n\n// One row of the scoreboard. The build caches two kinds of unit and the report\n// AI reads code from both, so they belong in ONE list: an entity (a table plus\n// its model and handler) and a standalone code class (domain logic with no\n// table — a summary model, a calculation service). A class row simply has no\n// table, columns or relationships to show.\ninterface SemanticUnitView {\n key: string;\n name: string;\n hasTable: boolean;\n entity: SemanticBuildEntity | null;\n model: string | null;\n functionCount: number;\n}\n\n\n// The Semantic Database tab: the scoreboard of everything the report AI was\n// built from. Shows the last build's status, runs (or stops) a build — streamed\n// into the FsProcess dock so it survives the dialog closing — and drills into\n// every unit to reveal its shape, inlined enum values, computed fields and its\n// cached function counts, whose links open the functions dialog (the full\n// function set is far too big to ship with the scoreboard).\n//\n// It also reports the other half of the picture: the tables the AI CANNOT see —\n// excluded ones (no model) and junctions that bridged nothing. Those are\n// invisible by omission otherwise: nothing errors, the capability just isn't\n// there, and the first anyone learns is a wrong answer or a refusal.\n@Component({\n selector: 'fs-ai-report-global-settings-semantic-database',\n templateUrl: './semantic-database.component.html',\n styleUrls: ['./semantic-database.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatExpansionModule,\n MatTooltipModule,\n FsChipModule,\n FsDateModule,\n FsMessageModule,\n FsSkeletonModule,\n ],\n})\nexport class SemanticDatabaseComponent {\n\n // The build-in-flight states of the ff_processes row (queued/running/stopping).\n private static readonly ACTIVE_STATES = ['Q', 'R', 'X'];\n\n private static readonly STATE_LABELS: Record<string, string> = {\n Q: 'Queued',\n R: 'Running',\n X: 'Stopping',\n C: 'Completed',\n K: 'Stopped',\n F: 'Failed',\n };\n\n // The streamed frames that carry a line for the feed: progress, and the final\n // frame the backend sends when a run ends badly. Without the error kind the\n // feed stops on the last progress line and never says what went wrong.\n private static readonly LOG_KINDS = ['log', 'error'];\n\n // A row that is still owed content says so; a built one says nothing. On a\n // finished build every stage is done on every row, so chipping them all was\n // noise that buried the one row that mattered.\n private static readonly PENDING_COLOR = '#b26500';\n\n // Class-name suffix stripped for display: `BudgetSummaryModel` reads as\n // `BudgetSummary`. Only `Model` — stripping `Handler` too would collide\n // `WorkOrderOneTimeHandler` with `WorkOrderOneTimeModel`, which are two\n // separate units.\n private static readonly NAME_SUFFIX = 'Model';\n\n // null until loaded — gates the tab behind the skeleton.\n public readonly status = signal<SemanticBuildStatus | null>(null);\n\n // Free-text filter over the unit list — at a few hundred rows the accordion\n // is only usable if you can narrow it.\n public readonly filter = signal<string>('');\n\n // True while a build started from this tab is streaming into the dock.\n public readonly building = signal(false);\n\n public readonly buildActive = computed<boolean>(() =>\n this.building()\n || SemanticDatabaseComponent.ACTIVE_STATES.includes(this.status()?.build?.state),\n );\n\n public readonly buildStateLabel = computed<string>(() =>\n SemanticDatabaseComponent.STATE_LABELS[this.status()?.build?.state] ?? '',\n );\n\n // Whether the published semantic database came from a build that finished.\n //\n // A failed or stopped build still leaves a dated, fully counted artifact\n // behind, because the structural half publishes BEFORE the AI function pass\n // and it is the AI pass that fails. So \"Last built\" and Coverage both filled\n // in and read as a clean success, and the only dissenting word on the whole\n // panel was one line of \"Last build run\" text (RE-T1302).\n //\n // Reads as complete while the status is still loading, so the warning cannot\n // flash on open before there is anything to warn about.\n public readonly buildComplete = computed<boolean>(() => this.status()?.detail?.complete !== false);\n\n // Entities the build never reached — those still owed the AI function pass.\n // The number the incomplete warning quotes, and the same rows the scoreboard\n // below already chips one at a time.\n public readonly incompleteEntityCount = computed<number>(() =>\n (this.status()?.detail?.entities ?? [])\n .filter((entity) => entity.stages.functions !== 'done')\n .length,\n );\n\n // An artifact built before the catalog existed carries no tables. Everything\n // catalog-driven stays hidden rather than claiming \"0 excluded\", which would\n // be a lie — a rebuild fills it in.\n public readonly hasCatalog = computed<boolean>(() => !!this.status()?.detail?.tables?.length);\n\n // Tables with no model: the report AI can't see them at all. Add a model to\n // promote one to an entity.\n public readonly excludedTables = computed<SemanticBuildTable[]>(() =>\n this._tables().filter((table) => table.classification === 'excluded'),\n );\n\n // Link tables that bridged nothing — a composite primary key made them a\n // junction, but they were folded into no relationship, so neither they nor\n // what they link are reachable.\n public readonly unlinkedJunctions = computed<SemanticBuildTable[]>(() =>\n this._tables().filter((table) => table.classification === 'junction' && !!table.reason),\n );\n\n // Everything the build cached, entities and standalone code classes together,\n // in one list ordered by the name a reader recognizes. Two arrays on the wire\n // because they are genuinely different shapes; one list on screen because\n // \"what did the build read?\" is a single question.\n public readonly units = computed<SemanticUnitView[]>(() => {\n const detail = this.status()?.detail;\n if (!detail) {\n return [];\n }\n\n const entities = (detail.entities ?? []).map((entity) => ({\n key: entity.key,\n name: this._displayName(entity.model, entity.key),\n hasTable: true,\n entity,\n model: entity.model,\n functionCount: entity.functionCount,\n }));\n\n const classes = (detail.classes ?? []).map((unit: SemanticBuildClass) => ({\n key: unit.key,\n name: this._displayName(unit.model, unit.key),\n hasTable: false,\n entity: null,\n model: unit.model,\n functionCount: unit.functionCount,\n }));\n\n return [...entities, ...classes]\n .sort((a, b) => a.name.localeCompare(b.name));\n });\n\n // The filter matches the display name, the class and the entity key, so\n // hunting by any of the three works.\n public readonly filteredUnits = computed<SemanticUnitView[]>(() => {\n const filter = this.filter().trim().toLowerCase();\n if (!filter) {\n return this.units();\n }\n\n return this.units().filter((unit) =>\n `${unit.name} ${unit.model ?? ''} ${unit.key}`.toLowerCase().includes(filter));\n });\n\n // The Coverage line. Assembled here because the catalog parts drop out\n // entirely on a pre-catalog artifact, which reads badly as template branches.\n public readonly coverage = computed<string>(() => {\n const detail = this.status()?.detail;\n if (!detail) {\n return '';\n }\n\n const parts = [`${detail.entityCount} entities`, `${detail.classCount} code classes`];\n\n if (this.hasCatalog()) {\n parts.push(detail.unlinkedJunctionCount\n ? `${detail.junctionCount} junctions (${detail.unlinkedJunctionCount} not linked)`\n : `${detail.junctionCount} junctions`);\n }\n\n parts.push(`${detail.functionCount} code functions`);\n\n if (this.hasCatalog()) {\n parts.push(`${detail.excludedCount} tables excluded`);\n }\n\n return parts.join(' · ');\n });\n\n // The table catalog, or [] when the status hasn't loaded or the artifact\n // predates it.\n private readonly _tables = computed<SemanticBuildTable[]>(() => this.status()?.detail?.tables ?? []);\n\n // Guards the outcome message to fire exactly once per run — whether the stream\n // completes (build finished, possibly failed) or errors outright.\n private _buildFinalized = false;\n\n private readonly _dialog = inject(MatDialog);\n private readonly _reportData = inject(ReportData);\n private readonly _process = inject(FsProcess);\n private readonly _prompt = inject(FsPrompt);\n private readonly _message = inject(FsMessage);\n private readonly _destroyRef = inject(DestroyRef);\n\n constructor() {\n this._init();\n }\n\n // Confirm before kicking off a build — a rebuild replaces the current\n // semantic database, so it should never fire on a stray click.\n public build(): void {\n const rebuild = !!this.status()?.detail?.generatedAt;\n\n this._prompt.confirm({\n title: rebuild ? 'Rebuild semantic database' : 'Build semantic database',\n template: rebuild\n ? 'Rebuild the semantic database? It runs in the background and replaces the current one when it finishes.'\n : 'Build the semantic database? It runs in the background.',\n commitLabel: rebuild ? 'Rebuild' : 'Build',\n })\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this._runBuild());\n }\n\n public stopBuild(): void {\n this._prompt.confirm({\n title: 'Stop build',\n template: 'Stop the running build? The current semantic database stays in place until a build finishes.',\n commitLabel: 'Stop',\n })\n .pipe(\n switchMap(() => this._reportData.semanticBuildStop()),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this.building.set(false);\n this._message.success('Stopping the build…');\n this._refreshStatus();\n });\n }\n\n // Run the semantic-database build. The live feed streams into the FsProcess\n // dock (bottom-right), whose subscription survives this dialog closing — so\n // dismissing the dialog never interrupts a running build.\n private _runBuild(): void {\n this.building.set(true);\n this._buildFinalized = false;\n\n const target$ = this._reportData.semanticBuild()\n .pipe(\n // A hard stream/transport failure (the build couldn't even start)\n // finalizes here — completed$ won't fire in that case.\n tap({ error: (error) => this._finalizeBuild(error) }),\n filter((event) =>\n event?.type === StreamEventType.Data\n && SemanticDatabaseComponent.LOG_KINDS.includes(event.data?.kind)\n && typeof event.data.line === 'string'),\n map((event) => event.data.line as string),\n );\n\n this._process\n .run('Semantic database build', target$)\n .completed$\n .pipe(\n take(1),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => this._finalizeBuild(null));\n }\n\n /**\n * Wrap up one build run exactly once. On a hard stream error, surface the\n * actual server-side reason pulled off the broken stream — the generic\n * \"could not run\" line only when the failure carried no server text at all;\n * otherwise refresh the status and announce how the build actually ended. A\n * failed build always names its reason on the row (the backend records one for\n * every way a run can die, fatals included), and that reason must surface\n * instead of the run silently doing nothing.\n */\n private _finalizeBuild(streamError: unknown): void {\n if (this._buildFinalized) {\n return;\n }\n this._buildFinalized = true;\n\n this.building.set(false);\n\n if (streamError) {\n const detail = this._streamErrorDetail(streamError);\n\n this._message.error(detail\n ? `The semantic database build failed — ${detail}`\n : 'The semantic database build could not run — the connection to the server was lost.');\n this._refreshStatus();\n\n return;\n }\n\n this._reportData.semanticBuildStatus()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((status: SemanticBuildStatus) => {\n this.status.set(status);\n this._announceOutcome(status);\n });\n }\n\n /**\n * The real reason a broken build stream broke, from what the server actually\n * sent. A structured error frame arrives as {message} on the error body; a\n * mid-stream crash dumps raw text into the stream (the stream interceptor\n * hands it back as statusText), where the frames are JSON lines and the\n * first non-JSON lines are the error and its location. '' when the failure\n * carried no server text at all (transport down / server unreachable).\n */\n private _streamErrorDetail(streamError: unknown): string {\n const error = streamError as { error?: { message?: string }; statusText?: string };\n\n if (error?.error?.message) {\n return error.error.message;\n }\n\n const statusText = error?.statusText;\n if (!statusText || statusText === 'Unknown Error') {\n return '';\n }\n\n const lines = statusText.split('\\n')\n .map((line) => line.trim())\n .filter((line) => {\n if (!line) {\n return false;\n }\n\n try {\n JSON.parse(line);\n\n return false;\n } catch {\n return true;\n }\n });\n\n return lines.slice(0, 2).join(' — ').substring(0, 300);\n }\n\n /**\n * Tell the operator how the build ended: a failed/stopped build surfaces its\n * reason (so an AI connection problem is never silent), a completed one\n * confirms success.\n */\n private _announceOutcome(status: SemanticBuildStatus): void {\n const build = status?.build;\n if (build?.state === 'F' || build?.state === 'K') {\n this._message.error(build.message || 'The semantic database build did not finish.');\n } else if (build?.state === 'C') {\n this._message.success('Semantic database build complete.');\n }\n }\n\n public pendingColor(): string {\n return SemanticDatabaseComponent.PENDING_COLOR;\n }\n\n /**\n * The build stages this row is still owed, or [] when it is fully built. A\n * stopped or interrupted build is the only way to get a non-empty list.\n */\n public pendingStages(unit: SemanticUnitView): string[] {\n const stages = unit.entity?.stages;\n\n return stages\n ? Object.keys(stages).filter((stage) => stages[stage] !== 'done')\n : [];\n }\n\n public setFilter(value: string): void {\n this.filter.set(value);\n }\n\n /**\n * Open the child dialog listing one group of a unit's cached functions — an\n * entity's model or handler class, or a standalone class's code. The dialog\n * fetches fresh on open, so the tab never holds function payloads.\n */\n public openFunctions(unit: SemanticUnitView, source: SemanticFunctionSource): void {\n this._dialog.open(EntityFunctionsComponent, {\n width: '700px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n autoFocus: false,\n data: { entityKey: unit.key, source },\n });\n }\n\n private _init(): void {\n this._refreshStatus();\n }\n\n /**\n * What a reader recognizes the unit by: its class's short name, minus the\n * `Model` suffix that every model carries and none of them are distinguished\n * by. Falls back to the cache key for a unit whose class could not be\n * resolved, so a row never renders nameless.\n */\n private _displayName(model: string | null, key: string): string {\n if (!model) {\n return key;\n }\n\n const shortName = model.split('\\\\').pop();\n\n return shortName.length > SemanticDatabaseComponent.NAME_SUFFIX.length\n && shortName.endsWith(SemanticDatabaseComponent.NAME_SUFFIX)\n ? shortName.slice(0, -SemanticDatabaseComponent.NAME_SUFFIX.length)\n : shortName;\n }\n\n private _refreshStatus(): void {\n this._reportData.semanticBuildStatus()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((status: SemanticBuildStatus) => this.status.set(status));\n }\n}\n","<div class=\"fs-column tab-body\">\n <p class=\"hint\">\n The semantic database is what the report AI uses to understand your data —\n tables, relationships and the calculations in code. Rebuild it after\n significant application updates. The build runs in the background; progress\n appears in the dock at the bottom right and this dialog can be closed while\n it runs.\n </p>\n\n <div *fsSkeleton=\"status()\">\n @if (status(); as buildStatus) {\n <div class=\"build-status\">\n @if (buildStatus.detail.generatedAt) {\n <div class=\"stat\">\n <span class=\"label\">Last built</span>\n <fs-date\n [date]=\"buildStatus.detail.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Coverage</span>\n <span>{{ coverage() }}</span>\n </div>\n } @else {\n <fs-message-warning>\n The semantic database has not been built yet — the report AI can't\n answer data questions until it is. Run the first build.\n </fs-message-warning>\n }\n @if (buildStatus.build) {\n <div class=\"stat\">\n <span class=\"label\">Last build run</span>\n <span>\n {{ buildStateLabel() }}\n @if (buildStatus.build.message) {\n — {{ buildStatus.build.message }}\n }\n </span>\n </div>\n }\n\n <!-- Everything above is true about what was published, and on its own it\n reads as a finished build: the structural half publishes BEFORE the\n AI function pass, so a run that died in that pass still stamps a\n date and still fills in the whole coverage line. This is the only\n line that says the build never got to the end. -->\n @if (buildStatus.detail.generatedAt && !buildComplete()) {\n <fs-message-warning>\n The last build did not finish, so this semantic database is incomplete —\n {{ incompleteEntityCount() }} of {{ buildStatus.detail.entityCount }}\n entities have no code-function knowledge. The report AI answers from what\n is here and cannot see the rest. Rebuild to complete it.\n </fs-message-warning>\n }\n </div>\n\n <!-- Everything the build read, in one list: entities (a table + a model +\n a handler) and standalone code classes (domain logic with no table).\n The AI reads code from both, so splitting them into two sections\n would hide half of what was built. Each row drills into its shape,\n enum values, computed fields and cached function counts — the counts\n link into the functions dialog. -->\n @if (units().length) {\n <h2>Included ({{ units().length }})</h2>\n <div class=\"subheading\">\n Everything the report AI was built from. Entities can be queried;\n code classes are logic it reads and translates into SQL.\n </div>\n\n <input\n class=\"unit-filter\"\n type=\"search\"\n placeholder=\"Filter by name, class or key…\"\n [value]=\"filter()\"\n (input)=\"setFilter($any($event.target).value)\">\n\n <mat-accordion class=\"entities\">\n @for (unit of filteredUnits(); track unit.key) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>{{ unit.name }}</mat-panel-title>\n <mat-panel-description>\n <div class=\"stage-chips\">\n @if (!unit.hasTable) {\n <fs-chip size=\"tiny\" matTooltip=\"Domain logic with no table — read, never queried\">\n code\n </fs-chip>\n }\n <!-- Silence means built. A chip here means an interrupted\n build left this row owing content. -->\n @for (stage of pendingStages(unit); track stage) {\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"pendingColor()\"\n color=\"#ffffff\"\n matTooltip=\"Needs building\">\n {{ stage }}\n </fs-chip>\n }\n </div>\n </mat-panel-description>\n </mat-expansion-panel-header>\n\n <!-- Deferred: the body only exists once expanded. -->\n <ng-template matExpansionPanelContent>\n <div class=\"entity-detail\">\n @if (unit.model) {\n <div class=\"stat\">\n <span class=\"label\">Class</span>\n <span>{{ unit.model }}</span>\n </div>\n }\n @if (unit.entity; as entity) {\n <div class=\"stat\">\n <span class=\"label\">Table</span>\n <span>{{ entity.table }}</span>\n </div>\n <!-- The handle the report AI addresses this entity by in\n describe_entity / compile_query. -->\n <div class=\"stat\">\n <span class=\"label\">Entity key</span>\n <span>{{ entity.key }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Columns</span>\n <span>{{ entity.columns }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Relationships</span>\n <span>{{ entity.relationships }}</span>\n </div>\n @if (entity.enums.length) {\n <div class=\"stat\">\n <span class=\"label\">Enumeration values</span>\n <div class=\"pair-list\">\n @for (enumColumn of entity.enums; track enumColumn.column) {\n <div class=\"pair-row\">\n <span class=\"pair-name\">{{ enumColumn.column }}</span>\n <span>{{ enumColumn.values.join(', ') }}</span>\n </div>\n }\n </div>\n </div>\n }\n @if (entity.computedFields.length) {\n <div class=\"stat\">\n <span class=\"label\">Computed fields</span>\n <span>{{ entity.computedFields.join(', ') }}</span>\n </div>\n }\n <div class=\"stat\">\n <span class=\"label\">Model functions</span>\n @if (entity.modelFunctionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(unit, 'model')\">\n {{ entity.modelFunctionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n <div class=\"stat\">\n <span class=\"label\">Handler functions</span>\n @if (entity.handlerFunctionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(unit, 'handler')\">\n {{ entity.handlerFunctionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n } @else {\n <div class=\"stat\">\n <span class=\"label\">Code functions</span>\n @if (unit.functionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(unit, 'class')\">\n {{ unit.functionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n }\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n </mat-accordion>\n\n @if (!filteredUnits().length) {\n <div class=\"subheading\">Nothing matches “{{ filter() }}”.</div>\n }\n }\n\n <!-- The other half of the picture: tables the AI can't reach. Excluded\n ones have no model; unlinked junctions have a composite primary key\n but were folded into no relationship, so nothing can navigate to\n them. Both are invisible by omission — no error, just a capability\n that silently isn't there. Collapsed by default: the excluded list is\n long and mostly framework plumbing. -->\n @if (hasCatalog()) {\n <h2>Not in the semantic database</h2>\n <div class=\"subheading\">\n Tables the report AI can't see. Give one a model to promote it to an\n entity, then rebuild.\n </div>\n <mat-accordion class=\"catalog\">\n @if (excludedTables().length) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n Tables excluded ({{ excludedTables().length }})\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n <!-- Deferred: the body only exists once expanded. -->\n <ng-template matExpansionPanelContent>\n <div class=\"pair-list\">\n @for (table of excludedTables(); track table.table) {\n <div class=\"pair-row\">\n <span class=\"pair-name\">{{ table.table }}</span>\n <span>{{ table.reason }}</span>\n </div>\n }\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n @if (unlinkedJunctions().length) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n Junctions not linked ({{ unlinkedJunctions().length }})\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n <ng-template matExpansionPanelContent>\n <p class=\"small\">\n Link tables the build couldn't fold into a relationship — so\n neither they nor what they link can be reported on.\n </p>\n <div class=\"pair-list\">\n @for (table of unlinkedJunctions(); track table.table) {\n <div class=\"pair-row\">\n <span class=\"pair-name\">{{ table.table }}</span>\n <span>{{ table.reason }}</span>\n </div>\n }\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n </mat-accordion>\n }\n }\n </div>\n</div>\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal, viewChild } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\n\nimport { MatButton } from '@angular/material/button';\nimport { MatDialog, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef } from '@angular/material/dialog';\nimport { MatTabsModule } from '@angular/material/tabs';\n\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsFormModule } from '@firestitch/form';\nimport { FsMarkdownEditorConfig } from '@firestitch/markdown-editor';\nimport { FsMessage } from '@firestitch/message';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\nimport { FsTabsModule } from '@firestitch/tabs';\n\nimport { switchMap, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportInstructions, ReportSettings } from '../../interfaces/report.interface';\nimport { InstructionHistoryComponent } from '../instruction-history/instruction-history.component';\nimport { AiKnowledgeComponent } from './components/ai-knowledge/ai-knowledge.component';\nimport { GeneralComponent } from './components/general/general.component';\nimport { SemanticDatabaseComponent } from './components/semantic-database/semantic-database.component';\n\n\n// Matches the backend cap (ReportsView::INSTRUCTIONS_MAX_LENGTH) — the document\n// rides along on every agent turn, so it is a prompt-budget guard.\nconst MAX_LENGTH = 50000;\n\n// Seeded into the editor (client-side, unsaved) when no version exists yet, so\n// the operator sees the intended shape of the document.\nconst SCAFFOLD = [\n '# Glossary',\n '',\n '*Terms your team uses and what they mean in the data — e.g. \"clients\" are client accounts.*',\n '',\n '# Business rules',\n '',\n '*Rules the AI should apply when building or explaining reports.*',\n '',\n '# Special cases',\n '',\n '*Known exceptions and data quirks the AI cannot infer on its own.*',\n '',\n].join('\\n');\n\n\n// Global report settings, opened from the reports listing's gear. A thin shell:\n// the dialog frame, the tab group, and a per-tab footer. Each tab is its own\n// component —\n// AI Knowledge — the operator-authored markdown document appended to the\n// report agent's system instructions on every chat turn. Its footer carries a\n// View History button opening the version-history dialog (restores happen\n// there; the shell refreshes on close).\n// Semantic Database — the build scoreboard the AI is built from, with a\n// self-contained Build action.\n// General — report-module settings (the semantic-build concurrency).\n// The shell owns the shared data (the instructions document, the settings for\n// General) plus the tab-aware save; everything else lives in the children.\n@Component({\n templateUrl: './global-settings.component.html',\n styleUrls: ['./global-settings.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsDialogModule,\n FsFormModule,\n FsSkeletonModule,\n FsTabsModule,\n MatButton,\n MatDialogActions,\n MatDialogClose,\n MatDialogContent,\n MatTabsModule,\n AiKnowledgeComponent,\n GeneralComponent,\n SemanticDatabaseComponent,\n ],\n})\nexport class GlobalSettingsComponent {\n\n public selectedTab = 'knowledge';\n\n // The Semantic Database tab component, so the shared footer can drive its\n // Build/Rebuild/Stop action inline next to Close (the build state lives there).\n public readonly semanticDatabase = viewChild(SemanticDatabaseComponent);\n\n // The editor's draft, held on the shell so switching tabs never loses an edit\n // — seeded from the current version (or the scaffold).\n public readonly content = signal<string>('');\n\n public readonly editorConfig: FsMarkdownEditorConfig = {\n maxLength: MAX_LENGTH,\n placeholder: 'Terminology, business rules and special cases the report AI should know…',\n };\n\n // Both null until loaded — the form waits behind the skeleton until each is in.\n public readonly instructions = signal<ReportInstructions | null>(null);\n public readonly settings = signal<ReportSettings | null>(null);\n\n // The General tab's concurrency draft (bound to its field), seeded from settings.\n public readonly concurrency = signal<number>(0);\n\n // Gate the whole form on both loads, so every tab's fields are ready to render.\n public readonly loaded = computed<boolean>(() => !!this.instructions() && !!this.settings());\n\n private readonly _dialogRef = inject<MatDialogRef<GlobalSettingsComponent>>(MatDialogRef);\n private readonly _dialog = inject(MatDialog);\n private readonly _reportData = inject(ReportData);\n private readonly _message = inject(FsMessage);\n private readonly _destroyRef = inject(DestroyRef);\n\n constructor() {\n this._init();\n }\n\n // The footer Save is shared, so it saves whatever the current tab owns: the\n // General tab persists its settings (and stays open); AI Knowledge saves a new\n // document version and closes.\n public save = () => {\n if (this.selectedTab === 'general') {\n return this._reportData.saveSettings({ semanticBuildConcurrency: this.concurrency() })\n .pipe(\n tap((settings: ReportSettings) => {\n this._applySettings(settings);\n this._message.success('Settings saved');\n }),\n );\n }\n\n return this._reportData.saveInstructions(this.content())\n .pipe(\n tap((instructions: ReportInstructions) => {\n this._message.success('AI knowledge saved');\n this._dialogRef.close(instructions);\n }),\n );\n };\n\n // Open the version-history dialog. Restores happen inside it, so when it\n // closes (however it closes) re-fetch the document: a restore changed the\n // current version and must reseed the editor; otherwise just refresh the\n // version list without touching an unsaved draft.\n public openHistory(): void {\n const currentId = this.instructions()?.instructions?.id;\n\n this._dialog.open(InstructionHistoryComponent, {\n width: '800px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n autoFocus: false,\n data: { versions: this.instructions()?.versions ?? [] },\n })\n .afterClosed()\n .pipe(\n switchMap(() => this._reportData.instructions()),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((instructions: ReportInstructions) => {\n if (instructions.instructions?.id !== currentId) {\n this._applyInstructions(instructions);\n } else {\n this.instructions.set(instructions);\n }\n });\n }\n\n private _init(): void {\n this._reportData.instructions()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((instructions: ReportInstructions) => this._applyInstructions(instructions));\n\n this._reportData.settings()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((settings: ReportSettings) => this._applySettings(settings));\n }\n\n private _applyInstructions(instructions: ReportInstructions): void {\n this.instructions.set(instructions);\n this.content.set(instructions.instructions?.content ?? SCAFFOLD);\n }\n\n private _applySettings(settings: ReportSettings): void {\n this.settings.set(settings);\n this.concurrency.set(settings.semanticBuildConcurrency);\n }\n}\n","<form\n *fsSkeletonForm=\"loaded()\"\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <fs-dialog-title>\n Report Settings\n </fs-dialog-title>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"AI Knowledge\"\n name=\"knowledge\">\n <fs-ai-report-global-settings-ai-knowledge\n [content]=\"content()\"\n (contentChange)=\"content.set($event)\"\n [config]=\"editorConfig\">\n </fs-ai-report-global-settings-ai-knowledge>\n </mat-tab>\n <mat-tab\n label=\"Semantic Database\"\n name=\"build\">\n <fs-ai-report-global-settings-semantic-database>\n </fs-ai-report-global-settings-semantic-database>\n </mat-tab>\n <mat-tab\n label=\"General\"\n name=\"general\">\n <fs-ai-report-global-settings-general\n [concurrency]=\"concurrency()\"\n (concurrencyChange)=\"concurrency.set($event)\"\n [min]=\"settings()!.semanticBuildConcurrencyMin\"\n [max]=\"settings()!.semanticBuildConcurrencyMax\">\n </fs-ai-report-global-settings-general>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- The footer follows the selected tab. AI Knowledge projects its own\n Save | View History | Cancel row (fs-form-dialog-actions renders\n projected content after Save/Cancel, so the default pair can't keep\n View History beside Save); General uses the default Save/Cancel; the\n Semantic Database tab is a read/run surface, so it gets a primary\n Close plus its Build/Rebuild/Stop action. -->\n <fs-form-dialog-actions [save]=\"selectedTab === 'general'\">\n @if (selectedTab === 'knowledge') {\n <button\n type=\"submit\"\n mat-button\n color=\"primary\">\n Save\n </button>\n <button\n type=\"button\"\n mat-button\n (click)=\"openHistory()\">\n View History\n </button>\n <button\n type=\"button\"\n mat-button\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n }\n @if (selectedTab === 'build') {\n <button\n type=\"button\"\n mat-button\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Close\n </button>\n }\n @if (selectedTab === 'build' && semanticDatabase(); as db) {\n @if (db.buildActive()) {\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"db.stopBuild()\">\n Stop Build\n </button>\n } @else {\n @if (db.status(); as buildStatus) {\n <button\n type=\"button\"\n mat-button\n (click)=\"db.build()\">\n {{ buildStatus.detail.generatedAt ? 'Rebuild' : 'Build' }}\n </button>\n }\n }\n }\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n OnInit,\n effect,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, Router, RouterLink } from '@angular/router';\n\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatIconModule } from '@angular/material/icon';\n\nimport { FilterConfig, FsFilterModule, ItemType } from '@firestitch/filter';\nimport { FsMessage } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\nimport {\n FlatItemNode,\n FsTreeComponent,\n FsTreeModule,\n ITreeChangeReorder,\n ITreeConfig,\n TreeActionType,\n TreeDragMode,\n} from '@firestitch/tree';\n\nimport { Observable, switchMap } from 'rxjs';\n\nimport { ReportData } from '../../data/report.data';\nimport { GlobalSettingsComponent } from '../../dialogs/global-settings/global-settings.component';\nimport {\n ReportFolder,\n ReportListItem,\n ReportNode,\n ReportNodeType,\n ReportState,\n ReportStates,\n ReportTree,\n} from '../../interfaces/report.interface';\n\n\n// The reports listing — an fs-tree of folders and the reports filed into them.\n// Rows link out through a URL pattern (a ':id' token → the report id; a leading\n// '/' makes it absolute, otherwise it's relative to this component's route).\n// Create prompts for a title, creates the report, then routes to it. The gear\n// opens the global Report Settings dialog (AI knowledge document +\n// semantic-database build), which lives in this package. No routing is\n// hard-coded here.\n//\n// Folders nest; reports are always leaves — canDrop enforces it here, and the\n// backend enforces it structurally by keeping the tree in its own table. A\n// report in no folder is a root node, which is where every report sat before\n// folders existed, so nothing had to be migrated or bucketed as \"uncategorized\".\n//\n// Reports are soft-deletable: the row kebab deletes, \"Show Deleted\" flips the\n// listing into deleted mode (the backend hides deleted reports otherwise), and\n// in that mode the kebab offers Restore instead. Folders do NOT take part in\n// that — a folder is only deletable once it is empty, so it hard deletes and has\n// nothing to restore. The upshot is that deleted mode keeps the folder structure\n// on screen with the deleted reports sitting where they belong, so restoring one\n// puts it back rather than dropping it at the root.\n@Component({\n selector: 'fs-ai-reports',\n templateUrl: './fs-ai-reports.component.html',\n styleUrls: ['./fs-ai-reports.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FsFilterModule,\n FsSkeletonModule,\n FsTreeModule,\n MatIconModule,\n RouterLink,\n ],\n})\nexport class FsAiReportsComponent implements OnInit {\n\n // How deep the tree opens on load. Folders are audience buckets, not a\n // filesystem, so there is nothing worth hiding behind a closed chevron.\n public static readonly EXPAND_LEVEL = 10;\n\n // API base for the reports endpoints; override to mount elsewhere.\n public readonly basePath = input<string>('reports');\n\n // Where a row links to; ':id' is replaced with the report id. Default takes\n // you to <current route>/:id. Absolute when it starts with '/'.\n public readonly openPattern = input<string>(':id');\n\n // Where a freshly-created report routes to; same ':id' pattern rules.\n public readonly createPattern = input<string>(':id');\n\n // Null until the first load resolves — that is what gates *fsSkeleton.\n public readonly nodes = signal<ReportNode[]>(null);\n\n public treeConfig: ITreeConfig<ReportNode[]>;\n public filterConfig: FilterConfig;\n\n // Template-side handle on the enum, so a row can tell a folder from a report.\n public readonly nodeType = ReportNodeType;\n\n private readonly _tree = viewChild(FsTreeComponent);\n\n private _reportData = inject(ReportData);\n private _router = inject(Router);\n private _route = inject(ActivatedRoute);\n private _prompt = inject(FsPrompt);\n private _message = inject(FsMessage);\n private _dialog = inject(MatDialog);\n private _destroyRef = inject(DestroyRef);\n\n // The filter bar's current query — carries `state` when Show Deleted is on.\n private _query: Record<string, unknown> = {};\n\n constructor() {\n effect(() => {\n this._reportData.basePath = this.basePath();\n });\n }\n\n public ngOnInit(): void {\n // Set before the first fetch rather than waiting on the effect above, which\n // does not run until after the initial change detection pass.\n this._reportData.basePath = this.basePath();\n\n this._initFilterConfig();\n this._initTreeConfig();\n this._load();\n }\n\n // routerLink commands for a report row (built from openPattern).\n public openLink(report: ReportListItem): unknown[] {\n return this._patternCommands(this.openPattern(), report.id);\n }\n\n // A deleted report can't be opened — the backend only assembles active ones —\n // so in Show Deleted mode its name renders as plain text rather than a link.\n public isDeleted(report: ReportListItem): boolean {\n return report?.state === ReportState.Deleted;\n }\n\n // Prompt for a title, create the report, then route to it (createPattern).\n public createReport(): void {\n this._prompt.input({\n title: 'Create Report',\n label: 'Title',\n commitLabel: 'Create',\n required: true,\n })\n .pipe(\n switchMap((name: string) => this._reportData.create(name)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((report: ReportListItem) => {\n const pattern = this.createPattern();\n this._router.navigate(\n this._patternCommands(pattern, report.id),\n pattern.startsWith('/') ? {} : { relativeTo: this._route },\n );\n });\n }\n\n // The global Report Settings dialog: the AI knowledge document and the\n // semantic-database build. A running build streams into the FsProcess dock,\n // which survives the dialog closing.\n public openSettings(): void {\n this._dialog.open(GlobalSettingsComponent, {\n width: '900px',\n maxWidth: '95vw',\n maxHeight: '90vh',\n autoFocus: false,\n });\n }\n\n private _initFilterConfig(): void {\n this.filterConfig = {\n items: [\n {\n name: 'keyword',\n type: ItemType.Keyword,\n label: 'Search',\n },\n {\n name: 'state',\n type: ItemType.Select,\n label: 'Status',\n multiple: true,\n values: () => ReportStates,\n isolate: { label: 'Show Deleted', value: ReportState.Deleted },\n },\n ],\n actions: [\n {\n icon: 'unfold_more',\n tooltip: 'Expand all',\n primary: false,\n click: () => this._tree()?.expandAll(),\n },\n {\n icon: 'unfold_less',\n tooltip: 'Collapse all',\n primary: false,\n click: () => this._tree()?.collapseAll(),\n },\n {\n icon: 'settings',\n tooltip: 'Report settings',\n primary: false,\n click: () => this.openSettings(),\n },\n {\n label: 'New Folder',\n primary: false,\n click: () => this._createFolder(null),\n },\n {\n label: 'Create',\n primary: true,\n click: () => this.createReport(),\n },\n ],\n // The two items are answered in different places and both have to run.\n // The keyword drives the tree's own search, which is the whole point of\n // searching a tree — it reveals a match nested inside collapsed folders\n // rather than only filtering what is already on screen. `state` is the\n // Show Deleted toggle, and only the server can answer that.\n change: (query) => {\n const stateChanged = String(query?.state ?? '') !== String(this._query.state ?? '');\n this._query = { ...query };\n\n this._search(query?.keyword);\n\n if (stateChanged) {\n this._load();\n }\n },\n };\n }\n\n private _initTreeConfig(): void {\n this.treeConfig = {\n data: [],\n childrenName: 'children',\n expandLevel: FsAiReportsComponent.EXPAND_LEVEL,\n draggable: true,\n // The whole row is the grip and the handle stays hidden; a press only\n // becomes a drag once the pointer moves, so the kebab, the chevron and the\n // report link all stay clickable.\n dragMode: TreeDragMode.Node,\n // canDrop is asked about the node being DRAGGED, so only `toParent`\n // describes the destination — reading node.level/node.parent here would\n // describe where it came from. A report can never be a parent because its\n // type says so, and that single test is the whole \"folders nest, reports\n // are leaves\" rule on this side.\n canDrop: (node: FlatItemNode, fromParent: FlatItemNode, toParent: FlatItemNode) => {\n return !toParent || toParent.data?.type === ReportNodeType.Folder;\n },\n changeReorder: (event: ITreeChangeReorder) => this._move(event),\n nodeClass: (node: FlatItemNode) => node.data?.type,\n // Match on the name only. The library's default matcher stringifies the\n // whole node, so it would hit ids, the literal type word, and everything\n // else riding on the row.\n filterItem: (node, query) => {\n return String(node.data?.name ?? '')\n .toLowerCase()\n .includes(String(query ?? '').toLowerCase());\n },\n actions: [\n {\n type: TreeActionType.Menu,\n icon: 'more_vert',\n items: [\n {\n label: 'Rename',\n show: (node: FlatItemNode) => !this._isDeletedNode(node),\n click: (node: FlatItemNode) => this._rename(node),\n },\n {\n label: 'New Folder Inside',\n show: (node: FlatItemNode) => this._isFolderNode(node),\n click: (node: FlatItemNode) => this._createFolder(node.data?.id),\n },\n {\n label: 'Delete',\n show: (node: FlatItemNode) => !this._isDeletedNode(node),\n click: (node: FlatItemNode) => this._delete(node),\n },\n // Folders never reach this: they hard delete, so a deleted folder\n // does not exist to be restored.\n {\n label: 'Restore',\n show: (node: FlatItemNode) => this._isDeletedNode(node),\n click: (node: FlatItemNode) => this._restore(node),\n },\n ],\n },\n ],\n };\n }\n\n private _isFolderNode(node: FlatItemNode): boolean {\n return node?.data?.type === ReportNodeType.Folder;\n }\n\n private _isDeletedNode(node: FlatItemNode): boolean {\n return this.isDeleted(node?.data?.report);\n }\n\n // Drive the tree's built-in search: it collapses everything, hides every node,\n // then unhides each match and walks its ancestors open, so a report several\n // folders deep surfaces with its path expanded. Clearing does NOT undo that\n // initial collapse, so the tree is re-opened here — otherwise the listing is\n // left fully collapsed the moment somebody empties the search box.\n private _search(keyword: string): void {\n const tree = this._tree();\n if (!tree) {\n return;\n }\n\n if (keyword) {\n tree.search(keyword);\n return;\n }\n\n tree.clearSearch();\n tree.expandAll();\n }\n\n private _load(): void {\n this._reportData.tree(this._query)\n .pipe(\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((tree: ReportTree) => {\n const nodes = this._buildNodes(tree);\n this.nodes.set(nodes);\n\n // The tree reads `config` once, in its own ngOnInit. The first load\n // lands before it exists, so the data has to arrive through the config;\n // every later one has to go through the instance or nothing changes.\n this.treeConfig = { ...this.treeConfig, data: nodes };\n this._tree()?.setData(nodes);\n });\n }\n\n // Flat API rows → the nested shape fs-tree renders. Folders come before\n // reports at every level, each already name-ordered by the backend.\n private _buildNodes(tree: ReportTree): ReportNode[] {\n const folders = tree?.folders ?? [];\n const reports = tree?.reports ?? [];\n\n const build = (parentId: number | null): ReportNode[] => {\n const folderNodes: ReportNode[] = folders\n .filter((folder: ReportFolder) => (folder.parentReportFolderId ?? null) === parentId)\n .map((folder: ReportFolder) => ({\n key: `f:${folder.id}`,\n id: folder.id,\n name: folder.name,\n type: ReportNodeType.Folder,\n children: build(folder.id),\n }));\n\n const reportNodes: ReportNode[] = reports\n .filter((report: ReportListItem) => (report.reportFolderId ?? null) === parentId)\n .map((report: ReportListItem) => ({\n key: `r:${report.id}`,\n id: report.id,\n name: report.name,\n type: ReportNodeType.Report,\n children: [],\n report,\n }));\n\n return [...folderNodes, ...reportNodes];\n };\n\n return build(null);\n }\n\n // A drop moved a node under a new parent, or out to the root. The tree has\n // already moved it on screen, so both outcomes reload: a success to pick up\n // the server's ordering, a failure to put the row back where it really is.\n private _move(event: ITreeChangeReorder): void {\n const node: ReportNode = event.node?.data;\n if (!node) {\n return;\n }\n\n const parentReportFolderId: number = event.toParent?.data?.id ?? null;\n\n if (event.toParent && !event.toParent.isExpanded()) {\n event.toParent.expand();\n }\n\n const save$: Observable<unknown> = node.type === ReportNodeType.Folder\n ? this._reportData.updateFolder(node.id, { parentReportFolderId })\n : this._reportData.moveReport(node.id, parentReportFolderId);\n\n save$\n .pipe(\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({\n next: () => {\n this._message.success('Saved changes');\n this._load();\n },\n error: () => this._load(),\n });\n }\n\n private _createFolder(parentReportFolderId: number): void {\n this._prompt.input({\n title: 'New Folder',\n label: 'Name',\n commitLabel: 'Create',\n required: true,\n })\n .pipe(\n switchMap((name: string) => this._reportData.createFolder(name, parentReportFolderId)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success('Created folder');\n this._load();\n });\n }\n\n private _rename(node: FlatItemNode): void {\n const data: ReportNode = node?.data;\n if (!data) {\n return;\n }\n\n const folder = data.type === ReportNodeType.Folder;\n\n this._prompt.input({\n title: folder ? 'Rename Folder' : 'Rename Report',\n label: 'Name',\n default: data.name,\n commitLabel: 'Save',\n required: true,\n })\n .pipe(\n switchMap((name: string) => (folder\n ? this._reportData.updateFolder(data.id, { name })\n : this._reportData.rename(data.id, name))),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success('Saved changes');\n this._load();\n });\n }\n\n // Deleting a folder is refused server-side while it still holds a sub-folder\n // or an active report, and the message says which — so the confirm here warns\n // that a folder delete is permanent rather than trying to restate the rule.\n private _delete(node: FlatItemNode): void {\n const data: ReportNode = node?.data;\n if (!data) {\n return;\n }\n\n const folder = data.type === ReportNodeType.Folder;\n\n this._prompt.confirm({\n title: 'Confirm',\n template: folder\n ? `Are you sure you would like to delete the folder \"${data.name}\"? This cannot be undone.`\n : 'Are you sure you would like to delete this report?',\n })\n .pipe(\n switchMap(() => (folder\n ? this._reportData.deleteFolder(data.id)\n : this._reportData.delete(data.id))),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success(folder ? 'Deleted folder' : 'Deleted report');\n this._load();\n });\n }\n\n private _restore(node: FlatItemNode): void {\n const data: ReportNode = node?.data;\n if (!data) {\n return;\n }\n\n this._reportData.undelete(data.id)\n .pipe(\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success('Restored report');\n this._load();\n });\n }\n\n // Turn a ':id' pattern into router commands. Relative unless it starts\n // with '/', in which case the first segment carries the leading slash.\n private _patternCommands(pattern: string, id: number): unknown[] {\n const absolute = pattern.startsWith('/');\n const segments: unknown[] = pattern.split('/')\n .filter((segment) => segment.length > 0)\n .map((segment) => (segment === ':id' ? id : segment));\n\n if (!segments.length) {\n return [id];\n }\n\n if (absolute) {\n segments[0] = `/${segments[0]}`;\n }\n\n return segments;\n }\n}\n","<fs-filter [config]=\"filterConfig\"></fs-filter>\n\n<ng-container *fsSkeleton=\"nodes()\">\n <fs-tree [config]=\"treeConfig\">\n <ng-template\n fsTreeNode\n let-data=\"data\">\n <div class=\"fs-row.gap-sm.align-center node-row\">\n <mat-icon class=\"node-icon\">\n {{ data.type === nodeType.Folder ? 'folder' : 'insert_chart_outlined' }}\n </mat-icon>\n\n @if (data.type === nodeType.Folder) {\n <span class=\"node-name\">{{ data.name }}</span>\n } @else if (isDeleted(data.report)) {\n <!-- A deleted report can't be opened (the backend only assembles\n active ones), so in Show Deleted mode the name is plain text —\n restore it from the row menu first. -->\n <span class=\"node-name\">{{ data.name }}</span>\n } @else {\n <a\n class=\"node-name\"\n [routerLink]=\"openLink(data.report)\">\n {{ data.name }}\n </a>\n }\n </div>\n </ng-template>\n </fs-tree>\n\n @if (!nodes().length) {\n <p class=\"small tree-empty\">\n No reports yet. Create one, or add a folder to group them.\n </p>\n }\n</ng-container>\n","import {\r\n CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Component,\r\n DestroyRef, ElementRef, NgZone, ViewChild, effect, inject, input, output,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { ActivatedRoute, Router } from '@angular/router';\r\n\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\n\r\nimport { FilterConfig, FsFilterModule, IFilterConfigItem } from '@firestitch/filter';\r\nimport { FsMenuModule } from '@firestitch/menu';\r\nimport { FsProcess } from '@firestitch/process';\r\n\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\nimport { provideEchartsCore } from 'ngx-echarts';\r\n\r\nimport { FsAiChatComponent, FsAiChatResponse } from '@firestitch/ai';\r\n\r\nimport { ReportCanvasComponent } from '../../components/report-canvas/report-canvas.component';\r\nimport { ReportData } from '../../data/report.data';\r\nimport { ComponentSettingsComponent, ComponentSettingsResult } from '../../dialogs/component-settings/component-settings.component';\r\nimport { ReportSettingsComponent, ReportSettingsResult } from '../../dialogs/report-settings/report-settings.component';\r\nimport { ReportExportCollectorService } from '../../export/report-export-collector.service';\r\nimport { ReportExportService } from '../../export/report-export.service';\r\nimport { ReportPdfService } from '../../export/report-pdf.service';\r\nimport { ReportPptxService } from '../../export/report-pptx.service';\r\nimport {\r\n ChartGranularity, Report, ReportChatResponse,\r\n ReportComponent as ReportComponentModel, ReportFilterGroup,\r\n} from '../../interfaces/report.interface';\r\nimport {\r\n GROUP_BY_ITEM, filterItemForGroup, groupByFilterItem, groupBySignature, groupValuesFromQuery,\r\n isGranularityOffered,\r\n} from '../../report-filter-items';\r\nimport { ReportFilterStateService, defaultSignature } from '../../services/report-filter-state.service';\r\n\r\n\r\n// A single report: the AI chat on the left, the report canvas on the right,\r\n// under an H2 title + settings gear. The host supplies [reportId] (from its\r\n// route) and switches reports by navigating — this component never picks one.\r\n@Component({\r\n selector: 'fs-ai-report',\r\n templateUrl: './fs-ai-report.component.html',\r\n styleUrls: ['./fs-ai-report.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true,\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n providers: [\r\n // Session filter state is per-open-report, not app-global; the export\r\n // services resolve filters through it, so they live at the same level.\r\n ReportFilterStateService,\r\n ReportExportCollectorService,\r\n ReportPptxService,\r\n ReportPdfService,\r\n ReportExportService,\r\n // Tree-shaken ECharts core + the 'report' house theme, loaded lazily.\r\n provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),\r\n ],\r\n imports: [\r\n FsFilterModule,\r\n FsMenuModule,\r\n FsAiChatComponent,\r\n MatButtonModule,\r\n MatIconModule,\r\n MatTooltipModule,\r\n ReportCanvasComponent,\r\n ],\r\n})\r\nexport class FsAiReportComponent {\r\n\r\n // The report this view is focused on — supplied by the host from the route.\r\n public readonly reportId = input<number | null>(null);\r\n\r\n // API base for the reports + chat endpoints; override to mount elsewhere.\r\n public readonly basePath = input<string>('reports');\r\n\r\n // The query param that carries the open page's id. Deep linking is on by\r\n // default; a host that mounts several reports on one route, or wants no URL\r\n // writes at all, sets this to null to turn it off.\r\n public readonly pageQueryParam = input<string | null>('page');\r\n\r\n // The report was deleted from its settings dialog — the host routes back to\r\n // the listing.\r\n public readonly deleted = output<number>();\r\n\r\n // The report was renamed (settings, or the agent) — the host can refresh a\r\n // breadcrumb / document title.\r\n public readonly renamed = output<Report>();\r\n\r\n // The viewer moved to another page. The URL is already updated by then —\r\n // this is for hosts that track the open page for their own reasons.\r\n public readonly pageChanged = output<number | null>();\r\n\r\n public report: Report | null = null;\r\n public editMode = false;\r\n\r\n // The page the canvas should open on, read from the URL once per report.\r\n // Cleared as soon as the canvas reports back, so a later in-app page change\r\n // is never fought by a stale value.\r\n public pageId: number | null = null;\r\n\r\n // The report-level filter toolbar (fs-filter). Rebuilt whenever the loaded\r\n // report (and thus its groups) changes.\r\n public reportFilterConfig!: FilterConfig;\r\n\r\n @ViewChild('split', { static: true })\r\n private _split!: ElementRef<HTMLDivElement>;\r\n\r\n @ViewChild('chatPanel', { static: true, read: ElementRef })\r\n private _chatPanel!: ElementRef<HTMLElement>;\r\n\r\n // Only the canvas knows which page is on screen, and a page-scoped export\r\n // has to ask it.\r\n @ViewChild(ReportCanvasComponent)\r\n private _canvas?: ReportCanvasComponent;\r\n\r\n private _reportData = inject(ReportData);\r\n private _router = inject(Router);\r\n private _route = inject(ActivatedRoute);\r\n private _filterState = inject(ReportFilterStateService);\r\n private _exportService = inject(ReportExportService);\r\n private _process = inject(FsProcess);\r\n private _dialog = inject(MatDialog);\r\n private _destroyRef = inject(DestroyRef);\r\n private _cdRef = inject(ChangeDetectorRef);\r\n private _zone = inject(NgZone);\r\n\r\n constructor() {\r\n // Point the shared data gateway at the configured base first (before any\r\n // load below reads it).\r\n effect(() => {\r\n this._reportData.basePath = this.basePath();\r\n });\r\n\r\n // (Re)load whenever the host switches the report id.\r\n effect(() => {\r\n const reportId = this.reportId();\r\n this.editMode = false;\r\n\r\n // Seed the open page from the URL for this report. Read per load rather\r\n // than once at construction: the host may swap reports on the same route,\r\n // and each arrival carries its own ?page=.\r\n this.pageId = this._pageIdFromUrl();\r\n\r\n if (reportId != null) {\r\n this._loadReport(reportId);\r\n } else {\r\n this.report = null;\r\n this._buildReportConfig();\r\n this._cdRef.markForCheck();\r\n }\r\n });\r\n\r\n this._buildReportConfig();\r\n }\r\n\r\n public toggleEditMode(): void {\r\n this.editMode = !this.editMode;\r\n }\r\n\r\n // Report settings — name, page size, orientation, layout mode, delete. The\r\n // dialog performs the delete itself; we react to what it reports back.\r\n public reportSettings(): void {\r\n if (!this.report) {\r\n return;\r\n }\r\n\r\n const reportId = this.report.id;\r\n\r\n this._dialog.open<ReportSettingsComponent, unknown, ReportSettingsResult>(ReportSettingsComponent, {\r\n data: { report: this.report },\r\n width: '460px',\r\n })\r\n .afterClosed()\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe((result) => {\r\n if (result?.action === 'deleted') {\r\n this.deleted.emit(reportId);\r\n\r\n return;\r\n }\r\n\r\n if (result?.action === 'saved') {\r\n this._loadReport(reportId, true);\r\n }\r\n });\r\n }\r\n\r\n // Component settings — title, exact geometry, and the diagnostic views\r\n // (SQL, config, filter wiring).\r\n public componentSettings(component: ReportComponentModel): void {\r\n if (!this.report) {\r\n return;\r\n }\r\n\r\n const reportId = this.report.id;\r\n\r\n const dialogRef = this._dialog.open<ComponentSettingsComponent, unknown, ComponentSettingsResult>(\r\n ComponentSettingsComponent,\r\n {\r\n data: { report: this.report, component },\r\n width: '640px',\r\n },\r\n );\r\n\r\n // Filter add/remove/level changes persist immediately inside the dialog (no\r\n // \"save\") and can leave it by an exit that carries no result, so they are\r\n // announced as they land. The reload waits for the close so the canvas isn't\r\n // re-rendering underneath an open dialog.\r\n let filtersChanged = false;\r\n dialogRef.componentInstance.filtersChanged\r\n .pipe(takeUntil(dialogRef.afterClosed()))\r\n .subscribe(() => filtersChanged = true);\r\n\r\n dialogRef.afterClosed()\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe((result) => {\r\n // The report's filter groups changed, so the report bar and the\r\n // on-component strips have to be rebuilt from a fresh report.\r\n if (filtersChanged) {\r\n this._loadReport(reportId);\r\n\r\n return;\r\n }\r\n\r\n // Nothing else in the dialog touches the query — title and padding are\r\n // presentation. Repaint the one component it was opened for and leave\r\n // every other component's data, and its query, alone.\r\n if (result?.settings) {\r\n this._canvas?.applyComponentSettings(component.id, result.settings);\r\n }\r\n });\r\n }\r\n\r\n // The canvas moved to another page: reflect it in the URL so a refresh or a\r\n // shared link comes back here. replaceUrl keeps paging out of the browser\r\n // history — Back should leave the report, not walk every page visited.\r\n public onCanvasPageChanged(pageId: number | null): void {\r\n // The deep link has been consumed; from here the canvas owns the page.\r\n this.pageId = null;\r\n this.pageChanged.emit(pageId);\r\n\r\n const param = this.pageQueryParam();\r\n if (!param) {\r\n return;\r\n }\r\n\r\n this._router.navigate([], {\r\n relativeTo: this._route,\r\n queryParams: { [param]: pageId },\r\n queryParamsHandling: 'merge',\r\n replaceUrl: true,\r\n });\r\n }\r\n\r\n // The canvas changed the report's structure (added a page) — re-fetch so the\r\n // new page renders; the canvas lands the view on it.\r\n public onCanvasReportChanged(): void {\r\n if (this.report) {\r\n this._loadReport(this.report.id);\r\n }\r\n }\r\n\r\n // Export the report to PowerPoint, entirely client-side (native editable\r\n // charts; page = slide). The dock shows progress until the file saves.\r\n public exportPowerpoint(): void {\r\n if (!this.report) {\r\n return;\r\n }\r\n\r\n this._process.run(\r\n 'Exporting PowerPoint',\r\n this._exportService.powerpoint(this.report),\r\n );\r\n }\r\n\r\n // Export to PDF, entirely client-side (offscreen ECharts at 3×; page = PDF page).\r\n public exportPdf(): void {\r\n if (!this.report) {\r\n return;\r\n }\r\n\r\n this._process.run(\r\n 'Exporting PDF',\r\n this._exportService.pdf(this.report),\r\n );\r\n }\r\n\r\n // The raw data behind the whole report in one action: the server exports every\r\n // component's full filtered dataset and zips one CSV per component, foldered\r\n // by page. `thisPage` narrows it to the page the canvas is showing. Unlike the\r\n // PDF/PowerPoint exports this is entirely server-side — nothing is collected\r\n // in the browser, so it is not capped by what a slide can hold.\r\n public exportData(thisPage = false): void {\r\n const report = this.report;\r\n if (!report) {\r\n return;\r\n }\r\n\r\n const pageId = thisPage ? this._canvas?.activePage?.id ?? null : null;\r\n\r\n this._process.download(\r\n 'Exporting data',\r\n this._reportData.exportReport(report.id, this._filterState.resolveForReport(report, pageId), pageId),\r\n );\r\n }\r\n\r\n // React to each chat turn (fs-chat handles the request + persistence); we\r\n // only care about the report side effects this context's backend flags.\r\n public onChatResponse(response: FsAiChatResponse): void {\r\n const reportId = this.reportId();\r\n if (reportId == null) {\r\n return;\r\n }\r\n\r\n const reportResponse = response as FsAiChatResponse & ReportChatResponse;\r\n\r\n // A structural change or a rename both re-fetch the report (session filter\r\n // values survive); a rename additionally notifies the host so it can\r\n // refresh a breadcrumb / title.\r\n if (reportResponse.reportChanged || reportResponse.reportRenamed) {\r\n this._loadReport(reportId, !!reportResponse.reportRenamed);\r\n }\r\n }\r\n\r\n // Drag the divider between the chat and canvas panes (pointer-capture loop\r\n // outside Angular).\r\n public onResizeStart(event: PointerEvent): void {\r\n event.preventDefault();\r\n\r\n const handle = event.target as HTMLElement;\r\n handle.setPointerCapture(event.pointerId);\r\n this._split.nativeElement.classList.add('resizing');\r\n\r\n this._zone.runOutsideAngular(() => {\r\n const move = (e: PointerEvent) => this._resizeTo(e.clientX);\r\n const end = () => {\r\n handle.releasePointerCapture(event.pointerId);\r\n handle.removeEventListener('pointermove', move);\r\n handle.removeEventListener('pointerup', end);\r\n handle.removeEventListener('pointercancel', end);\r\n this._split.nativeElement.classList.remove('resizing');\r\n };\r\n\r\n handle.addEventListener('pointermove', move);\r\n handle.addEventListener('pointerup', end);\r\n handle.addEventListener('pointercancel', end);\r\n });\r\n }\r\n\r\n private _resizeTo(clientX: number): void {\r\n const rect = this._split.nativeElement.getBoundingClientRect();\r\n if (rect.width === 0) {\r\n return;\r\n }\r\n\r\n const ratio = (clientX - rect.left) / rect.width;\r\n const clamped = Math.min(0.8, Math.max(0.2, ratio));\r\n this._chatPanel.nativeElement.style.flexBasis = `${clamped * 100}%`;\r\n }\r\n\r\n // The page id sitting in the URL right now, or null when deep linking is off\r\n // or the value is not a usable id.\r\n private _pageIdFromUrl(): number | null {\r\n const param = this.pageQueryParam();\r\n if (!param) {\r\n return null;\r\n }\r\n\r\n const pageId = Number(this._route.snapshot.queryParamMap.get(param));\r\n\r\n return Number.isFinite(pageId) && pageId > 0 ? pageId : null;\r\n }\r\n\r\n private _loadReport(reportId: number, emitRenamed = false): void {\r\n this._reportData.get(reportId)\r\n .pipe(takeUntilDestroyed(this._destroyRef))\r\n .subscribe((report: Report) => {\r\n this.report = report;\r\n this._filterState.init(report);\r\n this._buildReportConfig();\r\n\r\n if (emitRenamed) {\r\n this.renamed.emit(report);\r\n }\r\n\r\n this._cdRef.markForCheck();\r\n });\r\n }\r\n\r\n // Report-level filter groups in their saved order — the ones that render in\r\n // the toolbar (component-level groups render on their components).\r\n private _reportGroups(): ReportFilterGroup[] {\r\n return (this.report?.filterGroups ?? [])\r\n .filter((group) => group.level === 'report' || group.level === 'both')\r\n .sort((a, b) => a.order - b.order);\r\n }\r\n\r\n // Gates the toolbar fs-filter so it isn't rendered when there is nothing to\r\n // put in it — no report-level filters and no group-by control.\r\n public get reportHasFilters(): boolean {\r\n return this._reportGroups().length > 0 || !!this._groupByItem();\r\n }\r\n\r\n // fs-filter reads its config only once (at init). The template keys the\r\n // toolbar fs-filter on this signature so it's recreated (and re-reads the\r\n // rebuilt config) whenever the report-level filter set changes.\r\n public get reportFilterKey(): string {\r\n return [\r\n // The stored default is part of the signature: saving a new default in report\r\n // settings rebuilds the config, but without a key change fs-filter keeps\r\n // rendering the values it was created with until a full page reload.\r\n groupBySignature(this.report),\r\n ...this._reportGroups().map((group) => `${group.id}:${group.level}:${group.label}:${defaultSignature(group)}`),\r\n ].join('|');\r\n }\r\n\r\n // (Re)build the toolbar fs-filter config — the report-level filter items and\r\n // then the group-by control.\r\n private _buildReportConfig(): void {\r\n const reportId = this.report?.id ?? null;\r\n\r\n // Drop a grain the control no longer offers — the agent can narrow the list\r\n // mid-session, and an override the viewer can't see is worse than none.\r\n if (this.report && !isGranularityOffered(this.report, this._filterState.frequency())) {\r\n this._filterState.setFrequency(null);\r\n }\r\n\r\n const items = reportId\r\n ? this._reportGroups().map((group) =>\r\n filterItemForGroup(group, this._reportData, reportId, this._filterState.value(group.id)))\r\n : [];\r\n\r\n // The group-by control leads the bar, ahead of every filter: it sets the\r\n // grain the whole report is read at, so it is the first thing a viewer\r\n // decides. It is not a filter group — it re-buckets rows rather than\r\n // narrowing them — so it is placed here rather than ordered among them.\r\n const groupByItem = this._groupByItem();\r\n if (groupByItem) {\r\n items.unshift(groupByItem);\r\n }\r\n\r\n this.reportFilterConfig = {\r\n // Never touch the URL or persist filter state — report filters are\r\n // session-only, owned by ReportFilterStateService.\r\n queryParam: false,\r\n persist: false,\r\n items,\r\n change: (query) => {\r\n for (const { groupId, value } of groupValuesFromQuery(query ?? {}, this._reportGroups())) {\r\n this._filterState.setValue(groupId, value);\r\n }\r\n // Not a filter group — the grain is read straight off the query.\r\n this._filterState.setFrequency((query?.[GROUP_BY_ITEM] as ChartGranularity) || null);\r\n },\r\n };\r\n }\r\n\r\n // The report's group-by control as an fs-filter item, or null when the report\r\n // has none to show. Seeded from the session state so the grain the viewer\r\n // picked survives the report being re-fetched after a chat edit.\r\n private _groupByItem(): IFilterConfigItem | null {\r\n return this.report\r\n ? groupByFilterItem(this.report, this._filterState.frequency())\r\n : null;\r\n }\r\n}\r\n","<div class=\"fs-ai-report fs-column\">\n\n <div class=\"fs-ai-report__header fs-row.align-center\">\n <h2 class=\"fs-ai-report__title fs-flex\">{{ report?.name }}</h2>\n\n @if (report) {\n <!-- Report-level filters, inline with the toolbar actions. fs-filter\n reads its config once at init, so it's keyed on the filter\n signature: when the report-level filter set changes the block is\n recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters) {\n @for (key of [reportFilterKey]; track key) {\n <fs-filter\n class=\"fs-ai-report__filters\"\n [config]=\"reportFilterConfig\">\n </fs-filter>\n }\n }\n\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"editMode ? 'Done' : 'Edit layout'\"\n (click)=\"toggleEditMode()\">\n <mat-icon>{{ editMode ? 'lock' : 'open_with' }}</mat-icon>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Export\"\n [fsMenuTriggerFor]=\"exportMenu\">\n <mat-icon>download</mat-icon>\n </button>\n <fs-menu #exportMenu>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n Export PDF\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportData()\">\n Export Raw Data\n </ng-template>\n @if ((report?.pages?.length ?? 0) > 1) {\n <ng-template\n fs-menu-item\n (click)=\"exportData(true)\">\n Export Raw Data (This Page)\n </ng-template>\n }\n </fs-menu>\n\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Report settings\"\n (click)=\"reportSettings()\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </div>\n\n <div\n #split\n class=\"fs-ai-report__split fs-row.align-start\">\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n [basePath]=\"basePath()\"\n [requestData]=\"{ reportId: reportId() }\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n\n <div class=\"viewer fs-flex fs-column\">\n @if (report) {\n <app-report-canvas\n [report]=\"report\"\n [editMode]=\"editMode\"\n [pageId]=\"pageId\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\"\n (pageChanged)=\"onCanvasPageChanged($event)\"\n (editDone)=\"toggleEditMode()\">\n </app-report-canvas>\n }\n </div>\n </div>\n</div>\n","/*\n * Public API Surface of @firestitch/reports\n *\n * The AI-built report viewer/editor, its data gateway, session filter state and\n * renderer components. The host app only needs ReportComponent (route it) —\n * everything else is internal wiring. The AI chat is provided by @firestitch/ai.\n */\nexport { ReportComponent } from './app/reports/views/report/report.component';\n// Split, routing-free surface: a reports listing and a single-report view. The\n// host routes between them and passes [reportId] into FsAiReportComponent.\nexport { FsAiReportsComponent } from './app/reports/views/reports/fs-ai-reports.component';\nexport { FsAiReportComponent } from './app/reports/views/report/fs-ai-report.component';\nexport { ReportData } from './app/reports/data/report.data';\nexport { ReportService } from './app/reports/services/report.service';\nexport { ReportFilterStateService } from './app/reports/services/report-filter-state.service';\nexport * from './app/reports/interfaces/report.interface';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["rxFilter","map","i1","i2","i3","i4","switchMap","i6","i9","MatOption","TITLE_H","TABLE_ROW_H"],"mappings":"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"}