@firestitch/report 18.7.0 → 18.8.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 (64) hide show
  1. package/app/reports/components/component-kpi/component-kpi.component.d.ts +12 -3
  2. package/app/reports/components/component-kpi/components/sparkline/sparkline.component.d.ts +8 -0
  3. package/app/reports/components/component-list/component-list.component.d.ts +7 -1
  4. package/app/reports/components/component-note/component-note.component.d.ts +12 -0
  5. package/app/reports/components/report-canvas/report-canvas.component.d.ts +0 -9
  6. package/app/reports/components/report-component/report-component.component.d.ts +2 -11
  7. package/app/reports/data/report.data.d.ts +0 -2
  8. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +34 -2
  9. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +0 -1
  10. package/app/reports/enums/report-change-polarity.enum.d.ts +5 -0
  11. package/app/reports/enums/report-kpi-trend.enum.d.ts +5 -0
  12. package/app/reports/export/report-export-collector.service.d.ts +27 -1
  13. package/app/reports/export/report-pdf.service.d.ts +5 -0
  14. package/app/reports/export/report-pptx.service.d.ts +7 -0
  15. package/app/reports/format.d.ts +27 -1
  16. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +2 -0
  17. package/app/reports/interfaces/report.interface.d.ts +124 -4
  18. package/app/reports/kpi-card.d.ts +48 -0
  19. package/app/reports/layout.d.ts +0 -9
  20. package/app/reports/list-config.d.ts +8 -1
  21. package/app/reports/option-builder.d.ts +7 -0
  22. package/app/reports/output-notes.d.ts +14 -0
  23. package/app/reports/pipes/report-output.pipe.d.ts +10 -0
  24. package/app/reports/services/report-filter-state.service.d.ts +1 -0
  25. package/app/reports/theme/palette.d.ts +3 -0
  26. package/app/reports/theme/typography.d.ts +1 -0
  27. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +8 -4
  28. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +50 -17
  29. package/esm2022/app/reports/components/component-kpi/components/sparkline/sparkline.component.mjs +19 -0
  30. package/esm2022/app/reports/components/component-list/component-list.component.mjs +66 -6
  31. package/esm2022/app/reports/components/component-note/component-note.component.mjs +30 -0
  32. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +7 -56
  33. package/esm2022/app/reports/components/report-component/report-component.component.mjs +21 -82
  34. package/esm2022/app/reports/data/report.data.mjs +5 -5
  35. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +133 -13
  36. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +4 -8
  37. package/esm2022/app/reports/enums/report-change-polarity.enum.mjs +11 -0
  38. package/esm2022/app/reports/enums/report-kpi-trend.enum.mjs +10 -0
  39. package/esm2022/app/reports/export/report-export-collector.service.mjs +101 -10
  40. package/esm2022/app/reports/export/report-pdf.service.mjs +249 -40
  41. package/esm2022/app/reports/export/report-pptx.service.mjs +312 -49
  42. package/esm2022/app/reports/format.mjs +423 -2
  43. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  44. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  45. package/esm2022/app/reports/kpi-card.mjs +174 -0
  46. package/esm2022/app/reports/layout.mjs +1 -46
  47. package/esm2022/app/reports/list-config.mjs +33 -1
  48. package/esm2022/app/reports/option-builder.mjs +624 -54
  49. package/esm2022/app/reports/output-notes.mjs +158 -0
  50. package/esm2022/app/reports/pipes/report-output.pipe.mjs +28 -0
  51. package/esm2022/app/reports/services/report-filter-state.service.mjs +40 -3
  52. package/esm2022/app/reports/theme/palette.mjs +17 -1
  53. package/esm2022/app/reports/theme/typography.mjs +5 -1
  54. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +2 -2
  55. package/esm2022/app/reports/views/report/report.component.mjs +3 -4
  56. package/esm2022/public_api.mjs +2 -1
  57. package/fesm2022/{firestitch-report-echarts-u5ImuZT5.mjs → firestitch-report-echarts-qCBE3LqM.mjs} +2 -2
  58. package/fesm2022/{firestitch-report-echarts-u5ImuZT5.mjs.map → firestitch-report-echarts-qCBE3LqM.mjs.map} +1 -1
  59. package/fesm2022/{firestitch-report-firestitch-report-Cz-kA_id.mjs → firestitch-report-firestitch-report-DbsWbE-j.mjs} +2574 -487
  60. package/fesm2022/firestitch-report-firestitch-report-DbsWbE-j.mjs.map +1 -0
  61. package/fesm2022/firestitch-report.mjs +1 -1
  62. package/package.json +1 -1
  63. package/public_api.d.ts +1 -0
  64. package/fesm2022/firestitch-report-firestitch-report-Cz-kA_id.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"firestitch-report-firestitch-report-Cz-kA_id.mjs","sources":["../../src/app/reports/data/report.data.ts","../../src/app/reports/layout.ts","../../src/app/reports/dialogs/list-columns/list-columns.component.ts","../../src/app/reports/dialogs/list-columns/list-columns.component.html","../../src/app/reports/list-config.ts","../../src/app/reports/enums/report-list-column-format.enum.ts","../../src/app/reports/enums/report-number-units.enum.ts","../../src/app/reports/enums/report-value-format.enum.ts","../../src/app/reports/format.ts","../../src/app/reports/interfaces/report.interface.ts","../../src/app/reports/report-filter-items.ts","../../src/app/reports/consts/report-week.const.ts","../../src/app/reports/report-url-state.ts","../../src/app/reports/services/report-filter-state.service.ts","../../src/app/reports/enums/report-chart-color.enum.ts","../../src/app/reports/enums/report-chart-data-labels.enum.ts","../../src/app/reports/enums/report-chart-date-label.enum.ts","../../src/app/reports/enums/report-chart-line-style.enum.ts","../../src/app/reports/enums/report-chart-mark-stat.enum.ts","../../src/app/reports/text.ts","../../src/app/reports/theme/palette.ts","../../src/app/reports/theme/typography.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/components/component-kpi/component-kpi.component.ts","../../src/app/reports/components/component-kpi/component-kpi.component.html","../../src/app/reports/pipes/report-date.pipe.ts","../../src/app/reports/pipes/report-number.pipe.ts","../../src/app/reports/components/component-list/component-list.component.ts","../../src/app/reports/components/component-list/component-list.component.html","../../src/app/reports/components/component-text/component-text.component.ts","../../src/app/reports/components/component-text/component-text.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-locale-patch.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/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/data/report-ai-chat.data.ts","../../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 ChartGranularity,\n ComponentDataState,\n ComponentExportResponse,\n FilterGroupDefault,\n ReportComponentSql,\n ReportFilterLevel,\n ReportLocales,\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 // Soft-delete, whatever the folder holds: its contents leave the listing with\n // it, and undeleteFolder() brings the lot back.\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 // Restore a soft-deleted folder through its own action endpoint — the folder\n // PUT does not accept `state`. Any deleted folder above it is restored too, so\n // it lands back where it was.\n public undeleteFolder(reportFolderId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(`folders/${reportFolderId}/undelete`),\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 // timezone, locale, currency, styles, headerFooter } — styles carry the\n // report's typographic config (e.g. heading size), headerFooter the\n // header/footer band depths in inches. The page size is in inches and\n // width/height go together. locale (a BCP 47 tag) and currency (an ISO 4217\n // code) are each sent only to change them; '' returns the report to the\n // default, and the currency only names what the amounts are in.\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 // Any subset of { name, masterHidden }. An empty name is stored as null\n // server-side, which puts the tab back on its positional \"Page N\" label;\n // masterHidden hides the report's header and footer on this page.\n public updatePage(\n reportId: number,\n pageId: number,\n page: { name?: string; masterHidden?: boolean },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/pages/${pageId}`),\n page,\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 — or a text block's { html } from its inline editor; geometry\n // (x/y/w/h/flowWidth) is persisted via savePositions 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 // Place a text block — on a page, or in the header/footer when pageId is\n // omitted. The only component the UI creates itself: charts, lists and KPIs\n // need a query and come from the chat. Resolves to { id }.\n public addText(\n reportId: number,\n text: { pageId?: number; html?: string; x: number; y: number; w: number; h: number },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/components`),\n text,\n {\n key: 'component',\n ...config,\n },\n );\n }\n\n // Delete one component from the canvas, together with its filters and any\n // filter group they leave empty. Soft server-side, but there is no restore\n // anywhere in the UI, so the dialog's confirm presents it as permanent.\n public deleteComponent(\n reportId: number,\n componentId: number,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.delete(\n this._path(`${reportId}/components/${componentId}`),\n {},\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`. Its folder is restored too when it is deleted,\n // or inside one that is, so the report lands back where it was.\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 one component to CSV server-side: the file is what the screen\n // shows (a chart or KPI as rendered, a list in full in the screen's order).\n // The backend streams percentage progress while it writes.\n //\n // key: null on purpose, unlike the key: 'url' presigned-export pattern: the\n // response also carries `notes`, the sentences saying how the file falls\n // short of the full result, and the caller has to show them before it hands\n // the url to FsProcess.download.\n public exportComponent(\n reportId: number,\n componentId: number,\n filters: ResolvedFilterValue[] = [],\n state: ComponentDataState = {},\n config: RequestConfig = {},\n ): Observable<ComponentExportResponse> {\n return this._api.post(\n this._path(`${reportId}/components/${componentId}/export`),\n { filters, state },\n {\n key: null,\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, plus an 'Export Notes.txt'. `filters` carries the resolved values for\n // every component together; each one picks out its own. `frequency` is the\n // report's group-by grain (the server re-buckets only time-series charts to\n // it), and `filterSummary` is the filter bar as the viewer reads it, written\n // verbatim into the notes file. 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 frequency: ChartGranularity | null = null,\n filterSummary: string[] = [],\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/export`),\n {\n filters,\n ...(pageId ? { pageId } : {}),\n ...(frequency ? { frequency } : {}),\n filterSummary,\n },\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 // The locales and currencies a report can be written in, for the report\n // settings' Locale and Currency selects: the default locale, each offered\n // locale with the currency a report in it uses when it names none, and every\n // currency code. Only a server that sends effectiveLocale has this route.\n public locales(config: RequestConfig = {}): Observable<ReportLocales> {\n return this._api.get(\n this._path('locales'),\n {},\n {\n key: 'locales',\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\n// The deepest a header or footer band may be, in inches. Mirrors\n// ReportHeaderFooter::MAX_HEIGHT on the server, which clamps.\nexport const HEADER_FOOTER_MAX = 3;\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\n\nimport { MatButton } from '@angular/material/button';\nimport { MatCheckbox } from '@angular/material/checkbox';\nimport {\n MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef,\n} from '@angular/material/dialog';\n\nimport { FsDialogModule } from '@firestitch/dialog';\n\n\nexport interface ListColumnsDialogData {\n // The list's configured columns, in order, each with the heading it shows.\n columns: { column: string; label: string }[];\n // The names of the columns the viewer has hidden.\n hidden: string[];\n}\n\n\n// Which of a plain list's columns the viewer sees. One checkbox per column,\n// and the last one still checked is disabled, so the list always keeps a\n// column. Done closes with the hidden names, in the list's order; Cancel\n// closes with nothing. Nothing here is validated, so there is no fsForm.\n@Component({\n templateUrl: './list-columns.component.html',\n styleUrls: ['./list-columns.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatButton,\n MatCheckbox,\n MatDialogActions,\n MatDialogClose,\n MatDialogContent,\n FsDialogModule,\n ],\n})\nexport class ListColumnsComponent {\n\n public readonly data = inject<ListColumnsDialogData>(MAT_DIALOG_DATA);\n\n public readonly columns = this.data.columns;\n\n public readonly hidden = signal<ReadonlySet<string>>(new Set(this.data.hidden));\n\n // How many columns are still checked.\n public readonly shownCount = computed(() => this.columns\n .filter((column) => !this.hidden().has(column.column))\n .length);\n\n private readonly _dialogRef = inject<MatDialogRef<ListColumnsComponent, string[]>>(MatDialogRef);\n\n // Whether a column's box is the last one checked, which cannot be cleared.\n public isLastShown(name: string): boolean {\n return this.shownCount() === 1 && !this.hidden().has(name);\n }\n\n public toggle(name: string, shown: boolean): void {\n this.hidden.update((hidden) => {\n const next = new Set(hidden);\n\n if (shown) {\n next.delete(name);\n } else {\n next.add(name);\n }\n\n return next;\n });\n }\n\n public done(): void {\n this._dialogRef.close(this.columns\n .map((column) => column.column)\n .filter((name) => this.hidden().has(name)));\n }\n}\n","<fs-dialog>\n <fs-dialog-title>\n Columns\n </fs-dialog-title>\n <mat-dialog-content>\n <div class=\"fs-column.gap-xs\">\n @for (column of columns; track column.column) {\n <mat-checkbox\n class=\"column-option\"\n [checked]=\"!hidden().has(column.column)\"\n [disabled]=\"isLastShown(column.column)\"\n (change)=\"toggle(column.column, $event.checked)\">\n {{ column.label }}\n </mat-checkbox>\n }\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"primary\"\n (click)=\"done()\">\n Done\n </button>\n <button\n type=\"button\"\n mat-button\n [mat-dialog-close]=\"undefined\">\n Cancel\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n","import { ListColumn, ListConfig, ReportSort } from './interfaces/report.interface';\n\n\n// The most leading columns a list can keep in view while it scrolls sideways.\n// Mirrors the server's ListConfig::MAX_PINNED_COLUMNS, which refuses more.\nexport const MAX_PINNED_COLUMNS = 3;\n\n// A list's authored sort, most important first. A list sort is a list of\n// terms, but a list saved before multi-key sorting stores one object and is\n// never rewritten, so both shapes are read here. This is the one reader of a\n// list's config.sort: the config type intersects the chart and list configs,\n// so a direct `config.sort.column` still compiles and silently misreads an\n// array. A term without a column orders nothing and is dropped.\nexport function listSortTerms(config: ListConfig | null | undefined): ReportSort[] {\n const sort = config?.sort;\n\n if (!sort) {\n return [];\n }\n\n return (Array.isArray(sort) ? sort : [sort])\n .filter((term) => !!term?.column);\n}\n\n// The columns a viewer can hide on a list, by name: a plain list's configured\n// columns. A cross-tab offers none, since its columns are pivot values that\n// come and go with the data.\nexport function listHideableColumns(config: ListConfig | null | undefined): string[] {\n return config?.pivotBy?.column\n ? []\n : (config?.columns ?? []).map((column) => column.column);\n}\n\n// The hidden column names a list honors: only columns it can hide, each once,\n// in the list's own order, and none at all when they would hide every column\n// (a list always shows one, and the server ignores such a CSV list too). The\n// filter state, the screen and every export read this one rule.\nexport function listHiddenColumns(config: ListConfig | null | undefined, names: readonly string[]): string[] {\n const hideable = listHideableColumns(config);\n const hidden = hideable.filter((name) => names.includes(name));\n\n return hidden.length < hideable.length ? hidden : [];\n}\n\n// How many leading columns stay in view while a wide list scrolls sideways.\n// Unset, a cross-tab pins its row-key column and a plain list pins none. A\n// cross-tab pins at most that one column, since the rest are pivot values; a\n// stored config that asks for more is clamped here, as the server refuses it\n// only on save.\nexport function listPinnedColumns(config: ListConfig | null | undefined): number {\n const crossTab = !!config?.pivotBy?.column;\n const pinned = config?.pinnedColumns ?? (crossTab ? 1 : 0);\n\n return Math.min(Math.max(Math.floor(Number(pinned) || 0), 0), crossTab ? 1 : MAX_PINNED_COLUMNS);\n}\n\n// The classes a list column carries on its header, cells and footer. fs-list\n// copies a column's classes once, when it builds the column, so they are\n// static: `report-pin-{index}` names the column's place among the pinned ones\n// (its left offset is a CSS variable the list measures), `report-pin-last`\n// draws the separator after the last pinned column, and `report-nowrap` keeps\n// the column's cells on one line.\nexport function columnClasses(column: ListColumn, index: number, pinned: number): string {\n const classes: string[] = [];\n\n if (index < pinned) {\n classes.push('report-pinned', `report-pin-${index}`);\n\n if (index === pinned - 1) {\n classes.push('report-pin-last');\n }\n }\n\n if (column.wrap === false) {\n classes.push('report-nowrap');\n }\n\n return classes.join(' ');\n}\n\n// The label a list's totals row writes, on screen and in the PDF and deck.\nexport const LIST_TOTAL_LABEL = 'Total';\n\n// The column of a totals row that carries LIST_TOTAL_LABEL, among the columns\n// shown, in order: the first one, unless it holds a total itself, in which\n// case the row has no label. A cross-tab's first column is its row key, which\n// never holds one.\nexport function listTotalsLabelColumn(\n columns: readonly ListColumn[],\n totals: Record<string, unknown> | null | undefined,\n): string | null {\n const first = columns[0];\n\n return first && totals?.[first.column] === undefined ? first.column : null;\n}\n","// How a list column's cells are shown: a list column's `format`. date renders\n// a raw timestamp as a day in the report's zone and locale; number, percent\n// and currency format the value as a KPI measure does (ReportValueFormat). A\n// column without a format prints its value as it came.\n//\n// Mirrors the server's ListColumnFormatEnum value for value.\nexport enum ReportListColumnFormat {\n Date = 'date',\n Number = 'number',\n Percent = 'percent',\n Currency = 'currency',\n}\n","// How a formatted number is abbreviated: a number slot's `units`. thousands\n// writes 1,200 as 1.2K and millions 3,400,000 as 3.4M; auto picks by size\n// (once per chart on a value axis, per value everywhere else); none, like no\n// units at all, writes the full number. Units never apply to a percent.\n//\n// Mirrors the server's NumberUnitsEnum value for value.\nexport enum ReportNumberUnits {\n None = 'none',\n Thousands = 'thousands',\n Millions = 'millions',\n Auto = 'auto',\n}\n","// How a measure's value is shown: a chart measure's and a KPI measure's\n// `format`. The data stays raw; only the renderers format it. percent takes a\n// 0-1 ratio (0.3 reads 30%) when the report's percentFormat is 'ratio', and\n// currency labels the amount in the report's currency (nothing is converted).\n//\n// Mirrors the server's ValueFormatEnum value for value.\nexport enum ReportValueFormat {\n Number = 'number',\n Percent = 'percent',\n Currency = 'currency',\n}\n","import { isValid, parseISO } from 'date-fns';\nimport { formatInTimeZone, toZonedTime } from 'date-fns-tz';\n\nimport { ReportListColumnFormat } from './enums/report-list-column-format.enum';\nimport { ReportNumberUnits } from './enums/report-number-units.enum';\nimport { ReportValueFormat } from './enums/report-value-format.enum';\nimport {\n ChartMeasure,\n NumberFormatSpec,\n Report,\n ReportCurrencyCode,\n ReportFormatContext,\n ReportLocaleTag,\n} from './interfaces/report.interface';\n\n\n// What a report reads when the server names no usable locale or currency: an\n// older server that sends neither, or a value this browser's Intl cannot use.\n// Never the browser's own locale, so every viewer of a report sees the same text.\nexport const REPORT_FALLBACK_LOCALE: ReportLocaleTag = 'en-US';\nexport const REPORT_FALLBACK_CURRENCY: ReportCurrencyCode = 'USD';\n\nexport const DEFAULT_FORMAT_CONTEXT: Readonly<ReportFormatContext> = Object.freeze({\n locale: REPORT_FALLBACK_LOCALE,\n currency: REPORT_FALLBACK_CURRENCY,\n ratioPercent: true,\n});\n\nconst CURRENCY_PATTERN = /^[A-Z]{3}$/;\n\n\n// The server's resolved locale as one this browser can format in. A malformed\n// tag ('en_CA') makes supportedLocalesOf throw, and one Intl has no data for\n// ('xx-YY') comes back empty; both read the fallback.\nexport function resolveReportLocale(tag: string | null | undefined): ReportLocaleTag {\n if (!tag) {\n return REPORT_FALLBACK_LOCALE;\n }\n\n try {\n return Intl.NumberFormat.supportedLocalesOf([tag])[0] ?? REPORT_FALLBACK_LOCALE;\n } catch {\n return REPORT_FALLBACK_LOCALE;\n }\n}\n\n// The server's resolved currency as one Intl can label. The server decides\n// which codes name money; this only guards against a code Intl cannot take at\n// all. It is never checked against the runtime's own currency list, which\n// differs between browsers and leaves out codes the server offers (VEF, MRO),\n// so every viewer labels a report's money the same way.\nexport function resolveReportCurrency(code: string | null | undefined): ReportCurrencyCode {\n if (!code || !CURRENCY_PATTERN.test(code)) {\n return REPORT_FALLBACK_CURRENCY;\n }\n\n try {\n numberFormat(REPORT_FALLBACK_LOCALE, { style: 'currency', currency: code });\n\n return code;\n } catch {\n return REPORT_FALLBACK_CURRENCY;\n }\n}\n\n// The one place a report's format context is built: the server's effective\n// locale and currency (absent on an older server, which then reads en-US/USD)\n// and whether its percent measures arrive as 0-1 ratios.\nexport function resolveFormatContext(\n report: Pick<Report, 'effectiveLocale' | 'effectiveCurrency' | 'percentFormat'>,\n): ReportFormatContext {\n return {\n locale: resolveReportLocale(report.effectiveLocale),\n currency: resolveReportCurrency(report.effectiveCurrency),\n ratioPercent: report.percentFormat === 'ratio',\n };\n}\n\n\n// Building an Intl formatter is far slower than using one, and a chart formats\n// every tick and tooltip value, so each distinct locale + options (+ zone) is\n// built once and reused.\nconst NUMBER_FORMATS = new Map<string, Intl.NumberFormat>();\nconst DATE_FORMATS = new Map<string, Intl.DateTimeFormat>();\n\nexport function numberFormat(locale: string, options: Intl.NumberFormatOptions): Intl.NumberFormat {\n const key = `${locale}|${JSON.stringify(options)}`;\n let formatter = NUMBER_FORMATS.get(key);\n\n if (!formatter) {\n formatter = new Intl.NumberFormat(locale, options);\n NUMBER_FORMATS.set(key, formatter);\n }\n\n return formatter;\n}\n\n// No zone formats in the browser's own zone, which is right for a calendar day\n// parsed as local midnight: the day printed is the day stored.\nexport function dateFormat(\n locale: string,\n options: Intl.DateTimeFormatOptions,\n timeZone?: string,\n): Intl.DateTimeFormat {\n const key = `${locale}|${JSON.stringify(options)}|${timeZone ?? ''}`;\n let formatter = DATE_FORMATS.get(key);\n\n if (!formatter) {\n formatter = new Intl.DateTimeFormat(locale, { ...options, timeZone });\n DATE_FORMATS.set(key, formatter);\n }\n\n return formatter;\n}\n\n\n// Number formatting: the one engine behind every numeric slot (a chart\n// measure, a KPI measure, a list column, a cross-tab's cells), so a format\n// means the same thing on screen, in the PDF and in PowerPoint. The data stays\n// raw; only what is shown changes. The rules:\n// - Empty: null, undefined, '', '-' and a non-finite number print the caller's\n// `empty` ('—' unless it names another).\n// - Numeric: a finite number, or a string that spells one plainly ('1234.50',\n// '-3e2'). Anything else ('$1,234', an id with letters, ' ') prints as it\n// came, since a column the SQL already formatted is text.\n// - Styles: number is a plain decimal; currency is the report's currency\n// written in its locale with its symbol (USD reads '$1,235' in en-US and\n// 'US$1,235' in en-CA; EUR reads '1 235 €' in fr-FR); percent takes a 0-1\n// ratio (0.3 reads 30%), or, from an older server that sends percent values\n// already x100, a decimal with a % sign. Precision or units without a format\n// mean number.\n// - Decimals: a precision pins both the minimum and the maximum, so a column\n// of rates lines up. Without one: at most one for a percent and for an\n// abbreviated value (1.2K), whole units for currency, the locale's default\n// for a number.\n// - Units: thousands and millions divide and add a K or M after the digits\n// ('$1.2K', '1,2K $'); auto picks per value by size, and a value that would\n// round to 1000K reads 1M. Units never apply to a percent.\n// - Negatives keep the locale's leading minus. A negative that rounds to zero\n// prints as zero, never '-0'.\n// - Rounding is Intl's, on the digits shown. Every value is written in the\n// context's locale, never the browser's.\n\n// The most decimals a precision pins: the server's schema bound.\nconst MAX_PRECISION = 6;\n// At most one decimal for a percent, and for an abbreviated value (1.2K).\nconst PERCENT_DECIMALS = 1;\nconst SCALED_DECIMALS = 1;\n// Money shows whole units unless a precision asks for decimals.\nconst CURRENCY_DECIMALS = 0;\n// A currency axis whose ticks need decimals shows cents, not tenths.\nconst CURRENCY_AXIS_DECIMALS = 2;\n// What a missing value prints unless the caller names its own.\nconst EMPTY_VALUE = '—';\n// The tick count a value axis aims for, as ECharts' splitNumber default.\nconst AXIS_TICKS = 5;\n\nconst NUMERIC_PATTERN = /^\\s*[-+]?(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?\\s*$/;\n// The formatToParts types that carry a number's digits and separators.\nconst NUMBER_PARTS = new Set<Intl.NumberFormatPartTypes>(['integer', 'group', 'decimal', 'fraction']);\nconst DIGIT_PARTS = new Set<Intl.NumberFormatPartTypes>(['integer', 'fraction']);\n\n// A numeric format's units once decided: auto is resolved to one of these.\nexport type ResolvedUnits = ReportNumberUnits.None | ReportNumberUnits.Thousands | ReportNumberUnits.Millions;\n\ninterface UnitScale {\n divisor: number;\n suffix: string;\n // The PowerPoint/Excel scaling commas: each one divides by 1,000.\n commas: string;\n}\n\nconst UNIT_SCALES = new Map<ResolvedUnits, UnitScale>([\n [ReportNumberUnits.Thousands, { divisor: 1e3, suffix: 'K', commas: ',' }],\n [ReportNumberUnits.Millions, { divisor: 1e6, suffix: 'M', commas: ',,' }],\n]);\n\nexport interface FormatNumberOptions {\n // What an empty value prints: '—' for a KPI or a tooltip, '' for a cell.\n empty?: string;\n // Units already decided for the whole chart, in place of the spec's own.\n units?: ResolvedUnits;\n // Decimals already decided for the whole chart, pinned as min and max. null\n // leaves the spec's own.\n decimals?: number | null;\n}\n\n// How a chart's value axis writes its ticks, decided once per chart.\nexport interface ChartNumberFormat {\n units: ResolvedUnits;\n // Pinned decimals, or null for a plain number whose ticks keep their own.\n decimals: number | null;\n}\n\n// The value as a finite number when it is one or plainly spells one, else\n// null.\nexport function toFiniteNumber(value: unknown): number | null {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : null;\n }\n\n if (typeof value !== 'string' || !NUMERIC_PATTERN.test(value)) {\n return null;\n }\n\n const numeric = Number(value);\n\n return Number.isFinite(numeric) ? numeric : null;\n}\n\n// Whether a slot asks to be formatted at all. A slot without these keys, or a\n// list column whose format is date, keeps its own rendering. Units none is the\n// same as no units key, as it is on the server.\nexport function hasNumberFormat(spec?: NumberFormatSpec | null): boolean {\n if (!spec || spec.format === ReportListColumnFormat.Date) {\n return false;\n }\n\n return valueFormat(spec) !== null\n || (spec.precision ?? null) !== null\n || ((spec.units ?? ReportNumberUnits.None) !== ReportNumberUnits.None);\n}\n\n// The units a value is written in. auto decides by the magnitude: a million\n// and up reads M, a thousand and up K, unless the value would then round to\n// 1000K at these decimals, which reads 1M instead.\nexport function resolveUnits(\n units: ReportNumberUnits | null | undefined,\n magnitude: number,\n decimals: number,\n): ResolvedUnits {\n switch (units) {\n case ReportNumberUnits.Thousands:\n case ReportNumberUnits.Millions:\n return units;\n case ReportNumberUnits.Auto:\n return autoUnits(Math.abs(magnitude), decimals);\n default:\n return ReportNumberUnits.None;\n }\n}\n\nfunction autoUnits(magnitude: number, decimals: number): ResolvedUnits {\n if (magnitude >= 1e6) {\n return ReportNumberUnits.Millions;\n }\n\n if (magnitude < 1e3) {\n return ReportNumberUnits.None;\n }\n\n return roundTo(magnitude / 1e3, decimals) >= 1000\n ? ReportNumberUnits.Millions\n : ReportNumberUnits.Thousands;\n}\n\n// The value rounded as Intl rounds it for display, so the K-to-M promotion\n// agrees with the digits actually shown.\nfunction roundTo(value: number, decimals: number): number {\n const digits = clampDecimals(decimals) ?? 0;\n\n // A fixed locale only so Number() can parse the rounded digits back.\n return Number(numberFormat(REPORT_FALLBACK_LOCALE, {\n useGrouping: false,\n minimumFractionDigits: 0,\n maximumFractionDigits: digits,\n }).format(value));\n}\n\n// One value, written by the rules above.\nexport function formatNumber(\n value: unknown,\n spec: NumberFormatSpec | null | undefined,\n context: ReportFormatContext,\n options: FormatNumberOptions = {},\n): string {\n if (isEmptyValue(value)) {\n return options.empty ?? EMPTY_VALUE;\n }\n\n const numeric = toFiniteNumber(value);\n if (numeric === null) {\n return String(value);\n }\n\n const style = resolveStyle(spec);\n const precision = clampDecimals(spec?.precision);\n const units = style === ReportValueFormat.Percent\n ? ReportNumberUnits.None\n : options.units ?? resolveUnits(spec?.units, numeric, precision ?? SCALED_DECIMALS);\n const scale = UNIT_SCALES.get(units);\n const decimals = clampDecimals(options.decimals) ?? precision;\n const formatter = numberFormat(context.locale, styleOptions(style, context, decimals, !!scale));\n const text = writeNumber(formatter, (numeric === 0 ? 0 : numeric) / (scale?.divisor ?? 1), scale?.suffix);\n\n return style === ReportValueFormat.Percent && !context.ratioPercent ? `${text}%` : text;\n}\n\nfunction isEmptyValue(value: unknown): boolean {\n return value === null\n || value === undefined\n || value === ''\n || value === '-'\n || (typeof value === 'number' && !Number.isFinite(value));\n}\n\n// The value format a slot names, or null when it names none (or only date).\nfunction valueFormat(spec: NumberFormatSpec | null | undefined): ReportValueFormat | null {\n return Object.values(ReportValueFormat).find((format) => format === spec?.format) ?? null;\n}\n\nfunction resolveStyle(spec: NumberFormatSpec | null | undefined): ReportValueFormat {\n return valueFormat(spec) ?? ReportValueFormat.Number;\n}\n\n// A usable decimal count, or null. A stored value outside the schema's bounds\n// is brought inside them rather than thrown on by Intl.\nfunction clampDecimals(decimals: number | null | undefined): number | null {\n return typeof decimals === 'number' && Number.isFinite(decimals)\n ? Math.min(MAX_PRECISION, Math.max(0, Math.round(decimals)))\n : null;\n}\n\nfunction styleOptions(\n style: ReportValueFormat,\n context: ReportFormatContext,\n decimals: number | null,\n scaled: boolean,\n): Intl.NumberFormatOptions {\n const fractionDigits = fractionDigitOptions(decimals, defaultDecimals(style, scaled));\n\n switch (style) {\n case ReportValueFormat.Currency:\n return { ...currencyOptions(context.currency), ...fractionDigits };\n case ReportValueFormat.Percent:\n return context.ratioPercent ? { style: 'percent', ...fractionDigits } : fractionDigits;\n default:\n return fractionDigits;\n }\n}\n\nfunction currencyOptions(currency: ReportCurrencyCode): Intl.NumberFormatOptions {\n return { style: 'currency', currency, currencyDisplay: 'symbol' };\n}\n\n// The most decimals a style shows when nothing pins them; null leaves Intl's\n// own default.\nfunction defaultDecimals(style: ReportValueFormat, scaled: boolean): number | null {\n if (scaled) {\n return SCALED_DECIMALS;\n }\n\n switch (style) {\n case ReportValueFormat.Percent:\n return PERCENT_DECIMALS;\n case ReportValueFormat.Currency:\n return CURRENCY_DECIMALS;\n default:\n return null;\n }\n}\n\n// Pinned decimals set both bounds. Otherwise a maximum also sets the minimum\n// to zero, so no engine throws on a maximum below a currency's own minimum.\nfunction fractionDigitOptions(pinned: number | null, maximum: number | null): Intl.NumberFormatOptions {\n if (pinned !== null) {\n return { minimumFractionDigits: pinned, maximumFractionDigits: pinned };\n }\n\n return maximum === null ? {} : { minimumFractionDigits: 0, maximumFractionDigits: maximum };\n}\n\n// The formatted value, with the units letter after its digits. A negative\n// whose shown digits are all zero is written as zero, so no '-0' appears.\nfunction writeNumber(formatter: Intl.NumberFormat, value: number, suffix?: string): string {\n if (value >= 0 && !suffix) {\n return formatter.format(value);\n }\n\n const parts = formatter.formatToParts(value);\n\n if (value < 0 && !hasNonZeroDigit(formatter, parts)) {\n return writeNumber(formatter, 0, suffix);\n }\n\n if (!suffix) {\n return parts.map((part) => part.value).join('');\n }\n\n const last = parts.reduce((found, part, index) => NUMBER_PARTS.has(part.type) ? index : found, -1);\n\n return [\n ...parts.slice(0, last + 1).map((part) => part.value),\n suffix,\n ...parts.slice(last + 1).map((part) => part.value),\n ].join('');\n}\n\n// Compared with the locale's own zero, so a numbering system other than\n// 0-9 is read correctly.\nfunction hasNonZeroDigit(formatter: Intl.NumberFormat, parts: Intl.NumberFormatPart[]): boolean {\n const zero = formatter.formatToParts(0).find((part) => part.type === 'integer')?.value ?? '0';\n\n return parts.some((part) => DIGIT_PARTS.has(part.type)\n && Array.from(part.value).some((character) => character !== zero));\n}\n\n\n// A chart's value axis takes a format only when every measure on it agrees on\n// the style (each measure's format, number when it names none) and at least\n// one of them names a format. The first measure that does gives the axis its\n// precision and units. Otherwise null: the axis keeps its default ticks on\n// screen and in PowerPoint, and each series still formats its own tooltips.\nexport function axisNumberFormat(measures: ChartMeasure[]): NumberFormatSpec | null {\n const style = measures.length ? resolveStyle(measures[0]) : null;\n\n if (style === null || measures.some((measure) => resolveStyle(measure) !== style)) {\n return null;\n }\n\n const formatted = measures.find((measure) => hasNumberFormat(measure));\n\n return formatted ? numberFormatSpec(formatted) : null;\n}\n\nfunction numberFormatSpec(spec: NumberFormatSpec): NumberFormatSpec {\n return {\n ...(spec.format !== undefined ? { format: spec.format } : {}),\n ...(spec.precision !== undefined ? { precision: spec.precision } : {}),\n ...(spec.units !== undefined ? { units: spec.units } : {}),\n };\n}\n\n// How a chart's value axis writes its ticks: the units decided once from the\n// axis peak, and the decimals the precision pins, else as many as the axis's\n// tick step needs (a percent axis up to 0.12% steps by 0.02%, two decimals).\n// Pinned decimals keep the ticks distinct, and PowerPoint can only pin them.\nexport function resolveChartNumberFormat(\n spec: NumberFormatSpec,\n peak: number,\n context: ReportFormatContext,\n): ChartNumberFormat {\n const style = resolveStyle(spec);\n const precision = clampDecimals(spec.precision);\n const units = style === ReportValueFormat.Percent\n ? ReportNumberUnits.None\n : resolveUnits(spec.units, peak, precision ?? SCALED_DECIMALS);\n\n return { units, decimals: precision ?? axisDecimals(style, units, peak, context) };\n}\n\n// The decimals the axis's nice tick step needs. A plain, unabbreviated number\n// pins none (null): its ticks keep their own decimals. An unscaled currency\n// axis that needs decimals shows cents, and a K/M axis keeps its step's\n// decimals ('$0.5M', not '$0.50M').\nfunction axisDecimals(\n style: ReportValueFormat,\n units: ResolvedUnits,\n peak: number,\n context: ReportFormatContext,\n): number | null {\n const scale = UNIT_SCALES.get(units);\n\n if (style === ReportValueFormat.Number && !scale) {\n return null;\n }\n\n const shownPeak = style === ReportValueFormat.Percent && context.ratioPercent\n ? Math.abs(peak) * 100\n : Math.abs(peak) / (scale?.divisor ?? 1);\n const step = niceStep(shownPeak / AXIS_TICKS);\n const decimals = step > 0 ? clampDecimals(-Math.floor(Math.log10(step))) ?? 0 : 0;\n\n return style === ReportValueFormat.Currency && decimals > 0 && !scale ? CURRENCY_AXIS_DECIMALS : decimals;\n}\n\n// ECharts' nice(): the round number (1, 2, 3, 5 or 10 times a power of ten) a\n// rough tick step snaps to.\nfunction niceStep(rough: number): number {\n if (!(rough > 0) || !Number.isFinite(rough)) {\n return 0;\n }\n\n const exponent = Math.floor(Math.log10(rough));\n const power = Math.pow(10, exponent);\n const fraction = rough / power;\n let nice = 10;\n if (fraction < 1.5) {\n nice = 1;\n } else if (fraction < 2.5) {\n nice = 2;\n } else if (fraction < 4) {\n nice = 3;\n } else if (fraction < 7) {\n nice = 5;\n }\n\n return nice * power;\n}\n\n// PowerPoint's number format code for a formatted value axis, matching the\n// screen's ticks: '#,##0.0%' (percent), '\"$\"#,##0' (currency),\n// '#,##0.0,\"K\"' (thousands), '#,##0\" $\"' (fr-CA currency). A plain number\n// whose decimals are not pinned keeps chartAxisFormatCode's code. The code's\n// separators follow the opening machine's locale; the currency symbol and its\n// side follow the report's.\nexport function numberFormatCode(\n spec: NumberFormatSpec,\n context: ReportFormatContext,\n chart: ChartNumberFormat,\n series: (number | null)[][],\n stacked: boolean,\n): string {\n const style = resolveStyle(spec);\n const scale = style === ReportValueFormat.Percent ? undefined : UNIT_SCALES.get(chart.units);\n\n if (style === ReportValueFormat.Number && !scale && chart.decimals === null) {\n return chartAxisFormatCode(series, stacked);\n }\n\n const decimals = chart.decimals ?? 0;\n const digits = `#,##0${decimals > 0 ? `.${'0'.repeat(decimals)}` : ''}`;\n\n if (style === ReportValueFormat.Percent) {\n return `${digits}${context.ratioPercent ? '%' : '\"%\"'}`;\n }\n\n const scaled = `${digits}${scale?.commas ?? ''}`;\n const unit = scale?.suffix ?? '';\n\n if (style !== ReportValueFormat.Currency) {\n return unit ? `${scaled}\"${unit}\"` : scaled;\n }\n\n const symbol = currencySymbol(context);\n\n return symbol.prefix\n ? `\"${symbol.text}\"${scaled}${unit ? `\"${unit}\"` : ''}`\n : `${scaled}\"${unit}${symbol.text}\"`;\n}\n\n// The currency symbol as the locale writes it beside a number, with the space\n// between them, and which side it sits on: '$' before in en-US, ' $' after in\n// fr-CA. Quotes are dropped, as a format code cannot hold them.\ninterface CurrencySymbol {\n prefix: boolean;\n text: string;\n}\n\nconst CURRENCY_SYMBOLS = new Map<string, CurrencySymbol>();\n\nfunction currencySymbol(context: ReportFormatContext): CurrencySymbol {\n const key = `${context.locale}|${context.currency}`;\n let symbol = CURRENCY_SYMBOLS.get(key);\n\n if (!symbol) {\n const parts = numberFormat(context.locale, currencyOptions(context.currency)).formatToParts(1);\n const currency = parts.findIndex((part) => part.type === 'currency');\n const first = parts.findIndex((part) => NUMBER_PARTS.has(part.type));\n const last = parts.reduce((found, part, index) => NUMBER_PARTS.has(part.type) ? index : found, -1);\n const prefix = currency < first;\n const text = (prefix ? parts.slice(Math.max(currency, 0), first) : parts.slice(last + 1))\n .map((part) => part.value)\n .join('')\n .replace(/\"/g, '');\n\n symbol = { prefix, text };\n CURRENCY_SYMBOLS.set(key, symbol);\n }\n\n return symbol;\n}\n\n\n// Every decimal a number has, grouped, in the locale: what ECharts prints by\n// default (its addCommas), but in the report's locale, so a chart's axis and\n// tooltip read like the rest of the report. 1234.5 reads 1,234.5 in en-US and\n// 1 234,5 in fr-CA. A non-numeric string is shown as it came, and anything\n// else non-numeric as '-', as ECharts shows it. As there, an infinite value\n// reads 'Infinity' and negative zero (a tick a float error leaves just below\n// zero) reads '0'.\nconst PLAIN_NUMBER: Intl.NumberFormatOptions = { maximumFractionDigits: 20 };\n\nexport function formatPlainNumber(value: unknown, locale: ReportLocaleTag): string {\n const numeric = typeof value === 'number'\n ? value\n : typeof value === 'string' && value.trim() !== '' ? Number(value) : NaN;\n\n if (Number.isNaN(numeric)) {\n return typeof value === 'string' ? value : '-';\n }\n\n if (!Number.isFinite(numeric)) {\n return String(numeric);\n }\n\n return numberFormat(locale, PLAIN_NUMBER).format(numeric === 0 ? 0 : numeric);\n}\n\n\n// The axis peak at which a native chart's value axis gains thousands\n// separators. From here up the ticks are whole numbers in practice; below it\n// neither the screen nor PowerPoint's 'General' shows a separator.\nexport const AXIS_SEPARATOR_THRESHOLD = 1000;\n\n// PowerPoint's number format for a native chart's value axis, matching what the\n// on-screen axis prints by default: thousands separators with each tick's own\n// decimals. Excel has no \"General with separators\", so an axis reaching 1,000\n// (where ticks are whole numbers) gets '#,##0', and a smaller range keeps\n// 'General' so fractional ticks (0.25, 0.5) are not rounded away.\n//\n// The peak is chartValuePeak's.\nexport function chartAxisFormatCode(series: (number | null)[][], stacked: boolean): string {\n return chartValuePeak(series, stacked) >= AXIS_SEPARATOR_THRESHOLD ? '#,##0' : 'General';\n}\n\n// The largest magnitude a chart's value axis has to reach. A missing value\n// counts as 0. A stacked chart's peak is its tallest stack: the largest sum,\n// per category, of every series' absolute value.\nexport function chartValuePeak(series: (number | null)[][], stacked: boolean): number {\n const magnitudes = series.map((values) => values.map((value) => Math.abs(value ?? 0)));\n\n return stacked\n ? Math.max(0, ...(magnitudes[0] ?? []).map((_, index) => magnitudes\n .reduce((sum, values) => sum + (values[index] ?? 0), 0)))\n : Math.max(0, ...magnitudes.flat());\n}\n\n\n// The zone every date in a report is read in. The server resolves it (the\n// report's own zone, else the application's default reporting zone) and sends\n// it as `effectiveTimezone`. A server too old to send the field still used a\n// report's pinned `timezone`, so that comes next; the browser's zone is the last\n// fallback. This is the one place that chain lives, so every date the viewer\n// renders or resolves agrees with every other.\nexport function resolveReportTimezone(report: Pick<Report, 'effectiveTimezone' | 'timezone'>): string {\n return report.effectiveTimezone ?? report.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;\n}\n\n\n// The date shapes a report writes, each in the report's locale.\n// 'Jan 5, 2026' / '5 janv. 2026': a date cell, a filter bound.\nexport const DAY_SHORT: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric' };\n// 'January 5, 2026' / '5 janvier 2026': an export cover's date line.\nexport const DAY_LONG: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric' };\n// 'January' / 'janvier': a monthly period label (its year is added apart).\nexport const MONTH_LONG: Intl.DateTimeFormatOptions = { month: 'long' };\n// 'January 2026' / 'janvier 2026': a monthly period label written in full.\nexport const MONTH_YEAR: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long' };\n// 'Jan 5' / '5 janv.': a daily or weekly period label.\nexport const MONTH_DAY: Intl.DateTimeFormatOptions = { month: 'short', day: 'numeric' };\n\n// A date in the locale. With a zone, the day it falls on there; without one,\n// the browser's zone, which keeps a calendar day parsed as local midnight\n// unshifted. It never throws, since a pipe or an export calls it per cell: an\n// invalid Date reads '', a malformed locale ('en_CA') reads the fallback\n// locale, and an unknown zone reads UTC, which still names a real day.\nexport function formatLocalDate(\n date: Date,\n locale: ReportLocaleTag,\n options: Intl.DateTimeFormatOptions,\n timeZone?: string,\n): string {\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n\n try {\n return writeDate(dateFormat(locale, options, timeZone), date);\n } catch {\n return formatFallbackDate(date, resolveReportLocale(locale), options, timeZone);\n }\n}\n\nfunction formatFallbackDate(\n date: Date,\n locale: ReportLocaleTag,\n options: Intl.DateTimeFormatOptions,\n timeZone?: string,\n): string {\n try {\n return writeDate(dateFormat(locale, options, timeZone), date);\n } catch {\n return writeDate(dateFormat(locale, options, 'UTC'), date);\n }\n}\n\n// Intl writes a year below 1000 with only the digits it has ('Jan 1, 1'); a\n// date's year is always written with four ('Jan 1, 0001'), so a sentinel day\n// still reads as a date. Only such a year pays for formatToParts.\nfunction writeDate(formatter: Intl.DateTimeFormat, date: Date): string {\n if (date.getUTCFullYear() > 1000) {\n return formatter.format(date);\n }\n\n return formatter.formatToParts(date)\n .map((part) => part.type === 'year' ? part.value.padStart(4, '0') : part.value)\n .join('');\n}\n\n\nconst DATE_ONLY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst DATE_TIME_PATTERN = /^(\\d{4}-\\d{2}-\\d{2})[ T](\\d{2}:\\d{2}:\\d{2})(\\.\\d+)?$/;\n\n// A report row's date cell as a calendar day in the report's zone.\n//\n// Report rows are raw database strings, not serialized models, so their shape\n// is the wire contract: a DATE column arrives as 'YYYY-MM-DD' and a\n// date-and-time column as 'YYYY-MM-DD HH:MM:SS' in UTC. Reading that shape\n// here does not re-derive a server rule; it only stops the browser guessing.\n// - A calendar day is never shifted: parseISO reads it as local midnight, so\n// the day printed is the day stored, whatever the zone.\n// - An instant is pinned to UTC with an explicit 'Z', then shown as the day it\n// fell on in the report's zone, the same day the filters and time buckets use.\n// - Anything else is shown as it came, and so is a value that has the shape\n// but names no real day (a zero date '0000-00-00', or '2026-02-30'): one\n// bad cell must not throw out of a pipe or abort an export.\n// The day is written in the report's locale: 'Jan 5, 2026' in en-US, '5 janv.\n// 2026' in fr-CA.\nexport function formatReportDate(\n value: unknown,\n timezone: string,\n locale: ReportLocaleTag,\n): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const text = String(value);\n\n if (DATE_ONLY_PATTERN.test(text)) {\n const day = parseISO(text);\n\n return isValid(day) ? formatLocalDate(day, locale, DAY_SHORT) : text;\n }\n\n const dateTime = DATE_TIME_PATTERN.exec(text);\n if (!dateTime) {\n return text;\n }\n\n const instant = parseISO(`${dateTime[1]}T${dateTime[2]}Z`);\n\n return isValid(instant) ? formatLocalDate(instant, locale, DAY_SHORT, timezone) : text;\n}\n\n\n// English names for a locale and a currency, for the settings selects. The\n// interface stays English whatever the report's locale: 'fr-CA' reads\n// 'Canadian French', 'CAD' reads 'Canadian Dollar'. A runtime without the\n// names shows the code.\nexport function localeName(tag: ReportLocaleTag): string {\n return displayName('language', tag);\n}\n\nexport function currencyName(code: ReportCurrencyCode): string {\n return displayName('currency', code);\n}\n\nfunction displayName(type: 'language' | 'currency', code: string): string {\n try {\n return new Intl.DisplayNames(['en'], { type }).of(code) ?? code;\n } catch {\n return code;\n }\n}\n\n\n// A short, human label for a zone: its city plus the current abbreviation,\n// e.g. 'America/New_York' reads 'New York (EDT)'. UTC stays 'UTC', and an\n// unknown zone is shown as its id. An 'Etc/' zone names no city, and its POSIX\n// sign is the reverse of the offset ('Etc/GMT+5' is GMT-5), so it reads as the\n// abbreviation alone: 'Etc/UTC' is 'UTC', 'Etc/GMT+5' is 'GMT-5'.\nexport function getTimezoneLabel(timezone: string): string {\n if (timezone === 'UTC') {\n return timezone;\n }\n\n const segments = timezone.split('/');\n\n try {\n const abbreviation = formatInTimeZone(new Date(), timezone, 'zzz');\n\n return segments[0] === 'Etc'\n ? abbreviation\n : `${segments[segments.length - 1].replace(/_/g, ' ')} (${abbreviation})`;\n } catch {\n return timezone;\n }\n}\n\n\n// \"Now\" as a Date whose local fields read the wall clock in the given zone, so\n// date-fns calendar arithmetic (startOfWeek, startOfMonth, ...) and\n// dateBoundString() land on the zone's calendar day rather than the browser's.\n// An unknown zone falls back to the browser's clock.\nexport function getZonedNow(timezone: string): Date {\n const now = new Date();\n\n try {\n const zoned = toZonedTime(now, timezone);\n\n return Number.isNaN(zoned.getTime()) ? now : zoned;\n } catch {\n return now;\n }\n}\n","// The assembled report structure returned by GET /api/reports/:id — composed\n// server-side from the normalized tables (reports → report_pages →\n// report_components + report_filters, plus report_filter_groups). All keys are\n// camelCase; component `config` is the standard format the renderer maps to\n// ECharts options / FsList config.\n\nimport { ReportChartColor } from '../enums/report-chart-color.enum';\nimport { ReportChartDataLabels } from '../enums/report-chart-data-labels.enum';\nimport { ReportChartDateLabel } from '../enums/report-chart-date-label.enum';\nimport { ReportChartLineStyle } from '../enums/report-chart-line-style.enum';\nimport { ReportChartMarkStat } from '../enums/report-chart-mark-stat.enum';\nimport { ReportListColumnFormat } from '../enums/report-list-column-format.enum';\nimport { ReportNumberUnits } from '../enums/report-number-units.enum';\nimport { ReportValueFormat } from '../enums/report-value-format.enum';\n\n// Layout modes: Freeform = absolutely positioned components (drag anywhere);\n// Flow = components flow like rows, each taking flowWidth % of the page width.\nexport type ReportLayout = 'freeform' | 'flow';\n\n// A BCP 47 language tag naming how numbers and dates are written, e.g. 'fr-CA'.\n// The set is open (the server's provider decides which it offers), so this is a\n// named alias rather than a union.\nexport type ReportLocaleTag = string;\n\n// An ISO 4217 currency code, e.g. 'CAD'. Open for the same reason.\nexport type ReportCurrencyCode = string;\n\nexport interface Report {\n id: number;\n name: string;\n layout: ReportLayout;\n // The report's own stored IANA zone (e.g. America/New_York). null = the\n // report follows the application's default reporting zone.\n timezone: string | null;\n // The zone every date filter, time bucket and date cell of this report uses.\n // Resolved server-side; the same for every viewer, export and the assistant.\n // Optional only because older servers omit it; resolveReportTimezone() then\n // falls back to the report's own `timezone`, then the browser's zone. Resolve\n // the zone for rendering through resolveReportTimezone() (format.ts); read the\n // field directly only to check whether the server sent it.\n effectiveTimezone?: string;\n // The report's own stored locale. null = the report follows the default.\n locale?: ReportLocaleTag | null;\n // The locale every number and date of this report is written in, resolved\n // server-side (the report's own, else the application's default, else\n // en-US). Absent on older servers, whose reports then read en-US. Resolve it\n // for rendering through resolveFormatContext() (format.ts), never directly.\n effectiveLocale?: ReportLocaleTag;\n // The report's own stored currency. null = the report follows the default.\n currency?: ReportCurrencyCode | null;\n // The currency money amounts are labeled in, resolved like effectiveLocale\n // (falling back to the locale's own currency, then USD). A label only:\n // amounts are never converted.\n effectiveCurrency?: ReportCurrencyCode;\n // How the server sends a percent measure: 'ratio' = a 0-1 ratio (0.385 reads\n // 38.5%). Absent on older servers, whose percent values are already x100\n // (38.5 reads 38.5%).\n percentFormat?: 'ratio';\n // Report-level config: typographic styles, etc. (camelCase JSON column).\n config: ReportConfig;\n // The page in INCHES (the report's native unit — PDFs and PowerPoint are\n // inch-based, so exports are dimensionally exact). Orientation is not a field\n // of its own: a page wider than it is tall IS landscape.\n pageWidth: number;\n pageHeight: number;\n pages: ReportPage[];\n // The header and footer: the report's master page, whose components draw\n // under every page that does not hide them (PowerPoint's slide master). Null\n // until anything has been placed in them.\n master: ReportMaster | null;\n filterGroups: ReportFilterGroup[];\n}\n\nexport interface ReportMaster {\n id: number;\n components: ReportComponent[];\n}\n\n// How the open report writes its numbers and dates, resolved once per report\n// (resolveFormatContext) and read by the viewer, the PDF and PowerPoint alike.\n// Never the browser's locale.\nexport interface ReportFormatContext {\n locale: ReportLocaleTag;\n currency: ReportCurrencyCode;\n // Whether a percent measure arrives as a 0-1 ratio (the report's\n // percentFormat). An older server sends it already x100.\n ratioPercent: boolean;\n}\n\n// One locale the server offers, with the currency a report in it uses when it\n// names none of its own.\nexport interface ReportLocaleOption {\n locale: ReportLocaleTag;\n defaultCurrency: ReportCurrencyCode;\n}\n\n// GET reports/locales: what the report settings' Locale and Currency selects\n// offer.\nexport interface ReportLocales {\n defaultLocale: ReportLocaleTag;\n options: ReportLocaleOption[];\n currencies: ReportCurrencyCode[];\n}\n\n// The depth of the header band (top of every page) and the footer band (bottom\n// of every page), in INCHES. The bands hold no content of their own — the\n// master's components sit in them — they are the reserved margins the editor\n// draws as guides and snaps to. Always arrives resolved (0 = no band).\nexport interface ReportHeaderFooter {\n headerHeight: number;\n footerHeight: number;\n}\n\n// Report-level styling. Sizes are in POINTS (1/72\") — the report's typography\n// maps 1:1 to PDF (72pt/in) and PowerPoint (point font sizes), so a point\n// value is dimensionally exact on screen and in every export.\nexport interface ReportConfig {\n styles?: ReportStyles;\n // The report's group-by control. Optional on the type because a ReportConfig\n // literal need not carry it; the API always sends it, resolved.\n groupBy?: ReportGroupBy;\n // Resolved by the API like groupBy.\n headerFooter?: ReportHeaderFooter;\n}\n\n// The report's group-by control — the one switch that re-buckets every\n// time-series chart on the report between day, week, month, quarter and year.\n//\n// It is NOT a filter: a filter narrows which rows are counted, this changes how\n// the surviving rows are bucketed. It shares the report's filter bar because\n// that is the one row of controls a viewer reads a report through — the\n// separation that matters is in the model, not in where the control is painted.\n//\n// Always arrives RESOLVED (the backend fills an absent or partial stored block\n// in from its own defaults), so there is nothing to default here — render what\n// you are given.\nexport interface ReportGroupBy {\n enabled: boolean;\n label: string;\n granularities: ChartGranularity[];\n}\n\nexport interface ReportStyles {\n heading?: { size?: number };\n}\n\n// Content padding around a component's body, in INCHES (the geometry unit).\nexport interface ComponentPadding {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\nexport interface ReportPage {\n id: number;\n name: string | null;\n order: number;\n // The page opts out of the report's header and footer (a title page).\n masterHidden: boolean;\n components: ReportComponent[];\n}\n\n// 'text' is authored rich text with no query behind it — it never fetches data.\nexport type ReportComponentType = 'chart' | 'list' | 'kpi' | 'text';\n\nexport interface ReportComponent {\n id: number;\n type: ReportComponentType;\n title: string | null;\n // Geometry in INCHES. Freeform: absolute position on the page canvas.\n // Flow: only flowWidth/order apply; x/y are remembered for a switch back to\n // freeform.\n x: number;\n y: number;\n w: number;\n h: number;\n // Height mode, DERIVED from type server-side (not stored, read-only): lists\n // and KPI tiles are auto (the box sizes to its content, `h` ignored); charts\n // are always fixed (use `h`) so they fit the box and never overflow.\n autoHeight: boolean;\n // Flow layout: % of the page content width this component takes.\n flowWidth: number;\n // Flow layout ordering.\n order: number;\n // The stored SQL of a legacy sql-mode component. NULL for a derived one,\n // whose statement does not exist until its document is compiled — the SQL tab\n // fetches that separately (see ReportComponentSql).\n sql: string | null;\n config: ChartConfig & ListConfig & KpiConfig & TextConfig & ComponentLayoutConfig & Record<string, unknown>;\n filters: ReportFilter[];\n}\n\n// What the SQL tab fetches: the statement a component runs.\n//\n// For a derived component `baseline` is true and `sql` is what its document\n// compiles to with NO viewer state — no filters, the authored grain. The\n// numbers on screen come from that statement plus whatever the viewer picked,\n// so the two can legitimately differ and the tab says so rather than implying\n// they match.\n//\n// `timezone` is the IANA zone the statement was compiled in: the report's\n// effective zone. Optional because older servers omit it; they compiled in UTC.\n//\n// `error` is not a failure of the request: a document that no longer compiles\n// is precisely what someone opens this tab to discover, so it arrives as a\n// message to render with `errorType` naming which kind ('stale-query' or\n// 'sensitive-column'), and `sql` null.\nexport interface ReportComponentSql {\n sql: string | null;\n origin: 'sql' | 'dbq' | 'derived';\n baseline: boolean;\n timezone?: string;\n error: string | null;\n errorType: string | null;\n}\n\n// A text block's content: an html fragment the server has already rebuilt from\n// an allowlist, which may carry {{page.number}}, {{page.name}} and\n// {{report.name}} tokens (see text.ts).\nexport interface TextConfig {\n html?: string;\n}\n\n// Cross-type layout/style keys carried in a component's config (alongside the\n// type-specific chart/list/kpi keys).\nexport interface ComponentLayoutConfig {\n padding?: ComponentPadding;\n}\n\n// The presentation settings a component's settings dialog edits. Neither field\n// is part of what the component queries, so a change to them repaints without\n// re-running anything.\nexport interface ComponentSettings {\n title: string;\n padding: ComponentPadding;\n}\n\n// Where a chart's legend sits relative to the plot, or 'hidden' to drop it.\nexport type LegendPosition = 'top' | 'bottom' | 'left' | 'right' | 'hidden';\n\nexport type ChartGranularity = 'day' | 'week' | 'month' | 'quarter' | 'year';\n\n// How each granularity reads in the group-by control and on an export cover\n// sheet. WHICH of them a given report offers comes from its ReportGroupBy;\n// this is only the naming. 'year' reads as \"Annually\".\nexport const GRANULARITY_OPTIONS: { value: ChartGranularity; name: string }[] = [\n { value: 'day', name: 'Day' },\n { value: 'week', name: 'Week' },\n { value: 'month', name: 'Month' },\n { value: 'quarter', name: 'Quarter' },\n { value: 'year', name: 'Annually' },\n];\n\n// The chart types that plot series against a category and a value axis, and so\n// the types a measure's own series can be drawn as. A waterfall has the same\n// axes but is not one of them: it draws its one measure as floating steps.\nexport type AxisChartType = 'bar' | 'line' | 'area';\n\n// What one bar of a waterfall does to the running total — each is drawn in its\n// own color. The closing total is the last bar, standing on zero.\nexport type WaterfallStepKind = 'rise' | 'fall' | 'total';\n\nexport interface ChartConfig {\n // A waterfall takes ONE measure whose value per category is how far the\n // running total moves there: each bar starts where the one before it ended,\n // and a closing Total bar shows the sum.\n chartType?: AxisChartType | 'waterfall' | 'pie' | 'donut';\n // For kind 'time', the server buckets the raw datetime column to `granularity`\n // in the report's timezone (the SQL exposes the raw column, unbucketed).\n // dateLabel writes a time axis's period labels short ('May', the default),\n // long ('May 2026') or numeric ('2026-05'); a category axis ignores it.\n xAxis?: {\n column: string;\n kind?: 'category' | 'time';\n granularity?: ChartGranularity;\n label?: string;\n dateLabel?: ReportChartDateLabel;\n };\n measures?: ChartMeasure[];\n // Each value of this column becomes its own series. It carries no label: the\n // legend names the values themselves.\n splitBy?: { column: string };\n // Single-dimension bar charts only: color each bar by its own category and\n // show a legend, WITHOUT splitting into multiple series (which slivers the\n // bars). v1 expects colorBy.column === xAxis.column. Ignored when splitBy is\n // set or the chart isn't a bar chart.\n colorBy?: { column: string; label?: string };\n orientation?: 'vertical' | 'horizontal';\n stacked?: boolean;\n // Stacks the primary axis's bar and area series as shares of each\n // category's total, so every stack reaches 100%. The viewer computes the\n // shares from the rows it receives, after the filters ran; the rows and the\n // CSV keep the raw values. The value axis then always runs 0 to 100% (from\n // -100% when a share is negative).\n percentStacked?: boolean;\n // Values printed beside the points of a bar, line or area series: every\n // point (all), each series' latest point (last), or every point whose label\n // fits without overlapping another (auto). Omitted or none, no labels. A\n // pie, a donut and a waterfall never print them.\n dataLabels?: ReportChartDataLabels;\n // The primary value axis's title and range. Every series is plotted against\n // it unless its measure is secondary.\n valueAxis?: ChartValueAxis;\n // The second value axis, on the right, that secondary measures plot against.\n secondaryAxis?: ChartValueAxis;\n // Labeled lines across the plot at a constant value, or bands between two\n // values, at most 5. Vertical axis charts and waterfalls only.\n references?: ChartReference[];\n legend?: LegendPosition;\n sort?: ReportSort;\n limit?: number;\n}\n\n// A value axis's title and range. Each bound left out is picked from the data,\n// and the tick step without an interval. Its ticks take the number format of\n// the measures plotted against it.\nexport interface ChartValueAxis {\n label?: string;\n min?: number;\n max?: number;\n interval?: number;\n}\n\n// A reference drawn across a chart's plot: a line at `value`, or with `to` a\n// band between the two, labeled with `label`. The value is one the user or\n// the model states, never one read off the data. secondary plots it against\n// the second value axis, when the chart has one.\nexport interface ChartReference {\n value: number;\n label: string;\n to?: number;\n secondary?: boolean;\n}\n\n// How one numeric slot is shown: a chart measure, a KPI measure, a list column\n// or a cross-tab's cells. The data stays raw (it sorts and exports as a\n// number); only the renderers format it, the same way on screen, in the PDF\n// and in PowerPoint (format.ts). All three keys are optional, and precision or\n// units without a format mean number.\n//\n// Formatting is opt-in: a list column or cross-tab cell without these keys\n// prints its value as it came, and a chart without them keeps its plain\n// locale-grouped axis and tooltips. A KPI without them prints a plain number.\nexport interface NumberFormatSpec {\n // percent takes a 0-1 ratio (0.3 reads 30%) when the report's percentFormat\n // is 'ratio'; an older server leaves it out and sends x100. currency labels\n // the amount in the report's currency, written in its locale.\n format?: ReportValueFormat | ReportListColumnFormat;\n // How many decimal places the value is shown to (0-6). Fixed rather than\n // maximum: a column of rates is unreadable when each one shows a different\n // number of decimals. For percent it counts the decimals of the percentage\n // (precision 1 shows 0.3 as 30.0%). Omitted leaves the format's own default:\n // at most one decimal for percent (and for an abbreviated 1.2K), whole units\n // for currency, the locale's default for a number.\n //\n // It cannot be applied in the SQL: the value is aggregated after the report's\n // filters run, so pre-rounding would break live re-filtering.\n precision?: number;\n // Abbreviates to thousands (1.2K) or millions (3.4M), or picks by size.\n units?: ReportNumberUnits;\n}\n\nexport interface ChartMeasure extends NumberFormatSpec {\n column: string;\n aggregation?: 'sum' | 'count' | 'avg' | 'min' | 'max';\n label?: string;\n // Draws this measure's series as a different type from the chart's own\n // chartType — counts as bars with a rate as a line over them is a combo\n // chart. Omitted, the series takes the chart's type. Axis charts only (a pie\n // ignores it).\n type?: AxisChartType;\n // A chart measure's format shows on its tooltips, and on the value axis\n // when every measure sharing the axis agrees on it. A KPI's measure formats\n // its one value.\n format?: ReportValueFormat;\n // Plots this measure against the second value axis, on the right, for a\n // quantity on another scale. Omitted or false, it shares the primary axis.\n // A vertical axis chart only, with at least one measure left on the primary\n // axis.\n secondary?: boolean;\n // The palette color this measure's series is drawn in. Omitted, the series\n // takes the palette color of its position. A color on the first measure\n // turns off a category bar chart's default color per bar (isColorBy).\n color?: ReportChartColor;\n // How a line series' line is drawn. Omitted, solid.\n line?: ReportChartLineStyle;\n // Whether a line or area series draws a dot on each point. Omitted, true.\n markers?: boolean;\n // A line across the plot at this series' average, median, lowest or highest\n // value over the points on screen. Vertical axis charts only.\n markLine?: ReportChartMarkStat;\n}\n\n// One authored column of a plain list.\nexport interface ListColumn extends NumberFormatSpec {\n column: string;\n label?: string;\n // date keeps the column a RAW timestamp, so the report timezone and its\n // dateRange filters keep working, and the viewer renders it as a day in the\n // report's zone and locale. number, percent and currency format the value as\n // a KPI measure does. Without a format the value prints as it came.\n format?: ReportListColumnFormat;\n // A column the SQL already formatted is text, so it names `sortColumn`: the\n // raw numeric alias the query also outputs, which the server orders by\n // instead.\n sortColumn?: string;\n // false keeps the cell on one line. Omitted, a long value wraps.\n wrap?: boolean;\n}\n\nexport interface ListConfig {\n columns?: ListColumn[];\n // A cross-tab: `rowBy` stays down the side and every value of `pivotBy`\n // becomes a column. The two are set together, `columns` is omitted (the\n // backend rejects authoring both), and the column set arrives with the rows\n // in ComponentData.columns because only the result knows the pivot values.\n // rowBy.label heads the side column on screen and in every export, and\n // defaults to the column name. pivotBy carries no label: its values are the\n // headings.\n rowBy?: { column: string; label?: string };\n pivotBy?: { column: string };\n // The authored order, most important first. A list saved before multi-key\n // sorting stores one object, so read it through listSortTerms() only.\n sort?: ReportSort | ReportSort[];\n // How many leading columns stay in view while the list scrolls sideways\n // (0-3). Unset, a cross-tab pins its row-key column and a plain list none.\n pinnedColumns?: number | null;\n pageSize?: number;\n // true adds a totals row under the list: the server runs the measures again\n // over every row the filters keep, without grouping, and a cross-tab totals\n // each column.\n totals?: boolean;\n // A cross-tab only: how every cell of the grid is formatted, with a KPI\n // measure's keys. The row key column stays as it came.\n cellFormat?: NumberFormatSpec & { format?: ReportValueFormat };\n}\n\nexport interface KpiConfig {\n measure?: ChartMeasure;\n}\n\nexport interface ReportSort {\n column: string;\n direction?: 'asc' | 'desc';\n}\n\nexport type ReportFilterType = 'dateRange' | 'select' | 'keyword';\n\n// Where a filter group's control is exposed. A group can be shown on its\n// components, in the report bar, or BOTH at once (the two are independent\n// toggles in the UI); a column with neither exposed simply has no filter.\nexport type ReportFilterLevel = 'component' | 'report' | 'both';\n\n// One filterable output column of a component's SQL, with the filter interface\n// INFERRED from its data (the human never picks the interface — it follows the\n// column's type). Drives the Filters tab listing.\nexport interface ReportFilterableColumn {\n column: string;\n type: ReportFilterType;\n}\n\n// Ground truth: one filterable output column ON one component's SQL. Always a\n// member of a filter group — the unit that links equivalent filters across\n// components and decides where the control renders (component vs report bar).\nexport interface ReportFilter {\n id: number;\n componentId: number;\n filterGroupId: number;\n filterColumn: string;\n label: string | null;\n enabled: boolean;\n hasOptions: boolean;\n config: Record<string, unknown>;\n}\n\n// One choice in a select filter's option list. The value is what the filter\n// matches on and gets stored in a saved default — for an entity that is its\n// stable id, never its name, so renaming the entity moves the label without\n// breaking the default. The label is only ever what the viewer reads.\nexport interface ReportFilterOption {\n value: unknown;\n label: string;\n}\n\nexport interface ReportFilterGroup {\n id: number;\n label: string | null;\n type: ReportFilterType;\n level: ReportFilterLevel;\n order: number;\n config: { default?: FilterGroupDefault } & Record<string, unknown>;\n filters: ReportFilter[];\n}\n\n// A filter group's authored default — the value that seeds the report bar on\n// every open. Shape follows the group's type: dateRange uses start/end (a fixed\n// calendar-day range) or a relative preset; select uses values; keyword uses\n// value.\nexport interface FilterGroupDefault {\n // dateRange relative preset, resolved on every open against today in the\n // report's effective zone (Report.effectiveTimezone). One of: thisWeek,\n // lastWeek, last7Days, last30Days, last3Months, last6Months, last12Months,\n // thisMonth, thisQuarter, thisYear/yearToDate. Weeks run Monday to Sunday,\n // the same weeks the server's weekly time buckets use.\n relative?: string;\n start?: string; // dateRange fixed start (yyyy-MM-dd)\n end?: string; // dateRange fixed end (yyyy-MM-dd)\n values?: unknown[]; // select default picked values\n value?: string; // keyword default text\n}\n\n// The session value of a filter group: shape depends on the group's type. Not\n// stored on the server; the viewer's URL carries the values that differ from\n// the defaults (report-url-state.ts).\nexport interface FilterGroupValue {\n start?: Date | string | null; // dateRange\n end?: Date | string | null; // dateRange\n values?: unknown[]; // select\n value?: string; // keyword\n // dateRange only: the relative preset name these dates were resolved from\n // (a FilterGroupDefault.relative name). Set only when the value was seeded\n // from the group's relative default or read from a preset name in the URL,\n // so the URL keeps the range rolling ('last30Days') instead of freezing two\n // dates. Any date picked by the viewer, a picker shortcut included, is\n // stored without it.\n preset?: string;\n}\n\n// The viewer-state query params of a report URL, as raw strings, before they\n// are checked against the report (report-url-state.ts readReportUrlParams).\nexport interface ReportUrlParams {\n // g<groupId> -> the encoded group value ('' = the viewer cleared it).\n groups: Map<number, string>;\n // s<componentId> -> the encoded list sort ('-column' = descending).\n listSorts: Map<number, string>;\n // q<componentId> -> a list's search box text, as typed.\n listSearches: Map<number, string>;\n // h<componentId> -> the columns a viewer hid on a list, still encoded\n // (decodeColumnList).\n listHidden: Map<number, string>;\n // The group-by grain, or null when the URL has none.\n groupBy: string | null;\n}\n\n// The viewer state the URL should carry: only what differs from the report's\n// authored defaults (ReportFilterStateService.urlSnapshot).\nexport interface ReportUrlSnapshot {\n // A group's value, or null when the viewer cleared a group that has a default.\n groups: Map<number, FilterGroupValue | null>;\n // A list's sort, by component id, when it differs from the authored sort's\n // first term.\n listSorts: Map<number, ReportSort>;\n // A list's search box text, by component id. A list with an empty box is\n // left out.\n listSearches: Map<number, string>;\n // The config column names a viewer hid on a plain list, by component id. A\n // list showing every column is left out.\n listHidden: Map<number, string[]>;\n frequency: ChartGranularity | null;\n}\n\n// One resolved filter sent with a component's data request.\nexport interface ResolvedFilterValue {\n filterId: number;\n start?: string;\n end?: string;\n values?: unknown[];\n value?: string;\n}\n\n// Per-component interaction state sent with the data request: lists send\n// sort/paging and the text in their search box; time-series charts send the\n// grain picked on the report's group-by control, which overrides the authored\n// granularity for that request only. The wire key stays `frequency` — it is the\n// bucketing frequency the server applies.\nexport interface ComponentDataState {\n sort?: ReportSort;\n page?: number;\n pageSize?: number;\n frequency?: ChartGranularity;\n // A list's search box text. The server trims it, cuts it to its own maximum\n // length and matches it against every text column the list shows.\n search?: string;\n // The config column names a viewer hid on a plain list. Sent with a CSV\n // export only (the screen hides them itself): the file leaves them out. The\n // server ignores it on a cross-tab, and when it would hide every column.\n hiddenColumns?: string[];\n}\n\nexport interface ComponentData {\n columns: string[];\n rows: Record<string, unknown>[];\n paging?: { total: number; page: number; pageSize: number };\n truncated: boolean;\n // The effective time bucket the rows were grouped into (after any group-by\n // override), or null for a non-time axis. Drives the compact x-axis labels.\n granularity?: ChartGranularity | null;\n // Page 1 of a searched list whose search could not apply (the list has no\n // text column to search): why the rows are not narrowed. Absent otherwise.\n searchNote?: string | null;\n // Page 1 of a list with config.totals on: its totals row, as raw values\n // keyed like the columns (a plain list's measure aliases; a cross-tab's\n // pivot cell columns, the row-key column absent), or null with totalsNote\n // saying why there is none. Absent on every other page and list.\n totals?: Record<string, unknown> | null;\n totalsNote?: string | null;\n}\n\n// A component's CSV export: the presigned download URL, plus one sentence per\n// way the file falls short of the full result (cut at the export ceiling, or\n// cut as the chart itself is). Empty when the file is complete. Optional\n// because a server on an older framework answers with the url alone.\nexport interface ComponentExportResponse {\n url: string;\n notes?: string[];\n}\n\nexport interface ReportListItem {\n id: number;\n name: string;\n modifyDate: string;\n state?: ReportState;\n // The folder the report is filed under. null is a real, common value — the\n // report sits at the root of the listing tree alongside the folders.\n //\n // Optional like `state` beside it: the backend always sends it, but making it\n // required is a breaking type change for every consumer holding a\n // ReportListItem literal (fixtures, mocks) and buys nothing — the listing\n // reads it as `?? null` either way.\n reportFolderId?: number | null;\n}\n\n// One folder in the listing tree — an audience bucket (\"Management\",\n// \"Operations\") reports are filed into. Folders nest via parentReportFolderId;\n// reports never do, so the tree's only branch nodes are folders.\n//\n// `state` is the folder's OWN state. Deleting a folder writes only that, and\n// everything below it counts as deleted by position — see ReportNode.deleted.\nexport interface ReportFolder {\n id: number;\n name: string;\n parentReportFolderId: number | null;\n state?: ReportState;\n}\n\n// GET /api/reports returns both halves flat; the listing nests them itself.\nexport interface ReportTree {\n reports: ReportListItem[];\n folders: ReportFolder[];\n}\n\nexport enum ReportNodeType {\n Folder = 'folder',\n Report = 'report',\n}\n\n// One node as fs-tree sees it. Folders and reports share one id space in the\n// view, so the ids are prefixed ('f:12' / 'r:34') — `id` is the original,\n// per-table id that the API endpoints take.\nexport interface ReportNode {\n key: string;\n id: number;\n name: string;\n type: ReportNodeType;\n // Only ever populated on a folder; a report is always a leaf.\n children: ReportNode[];\n // Present on report nodes only.\n report?: ReportListItem;\n // The node's own row is deleted. What earns the \"Deleted\" chip — this is\n // what somebody actually deleted.\n stateDeleted: boolean;\n // Deleted itself OR anywhere below a deleted folder. Only ever true in Show\n // Deleted mode (the default listing never returns such a node), and it is what\n // swaps the row's actions for Restore.\n deleted: boolean;\n}\n\n// Reports and folders are both soft-deletable. A deleted report keeps its pages\n// and components; a deleted folder keeps everything filed under it, which leaves\n// the listing with it and comes back with it. \"Show Deleted\" shows the whole\n// tree, live and deleted together, so any of it can be restored in place.\nexport enum ReportState {\n Active = 'active',\n Deleted = 'deleted',\n}\n\n// The chat turn flags this context's backend adds (Reports\\AiView).\nexport interface ReportChatResponse {\n reportChanged?: boolean;\n reportRenamed?: boolean;\n}\n\n// One version of the global AI knowledge document — the operator-authored\n// markdown appended to the report agent's system instructions on every turn.\nexport interface ReportInstruction {\n id: number;\n content: string;\n current: boolean;\n createDate: Date;\n modifyDate: Date;\n accountId: number | null;\n accountName: string | null;\n}\n\n// GET/PUT instructions payload: the current version (null until one is\n// authored) plus the full history, newest first.\nexport interface ReportInstructions {\n instructions: ReportInstruction | null;\n versions: ReportInstruction[];\n}\n\n// The latest semantic-database build (an ff_processes row) — enough for the\n// settings dialog to say what state the build is in and when it last ran.\nexport interface SemanticBuild {\n id: number;\n state: string;\n percent: number | string;\n message: string;\n duration: number;\n createDate: Date;\n startDate: Date;\n endDate: Date;\n}\n\n// A build stage's state on the entity scoreboard: 'done' = built, 'missing' =\n// still needs building (a missing stage is unbuilt content, never an error).\nexport type SemanticBuildStage = 'done' | 'missing';\n\n// One enum column of an entity, with the allowed values the build inlined.\nexport interface SemanticBuildEnum {\n column: string;\n values: string[];\n}\n\n// One entity row of the scoreboard (an entity = a table + a model + a\n// handler): its table/shape counts, inlined enum values, computed fields, how\n// many code functions were cached (split model vs handler), and the per-stage\n// built/missing state.\n//\n// `model`/`handler` are the classes the functions were read from — what a\n// reader recognizes the row by, where `key` is what the report AI addresses it\n// by in describe_entity / compile_query.\nexport interface SemanticBuildEntity {\n key: string;\n table: string;\n model: string | null;\n handler: string | null;\n columns: number;\n relationships: number;\n enums: SemanticBuildEnum[];\n computedFields: string[];\n functionCount: number;\n modelFunctionCount: number;\n handlerFunctionCount: number;\n stages: Record<string, SemanticBuildStage>;\n}\n\n// One standalone code class the build read: domain logic with no table of its\n// own (a summary model, a calculation service). The report AI reads its code\n// exactly like an entity's, but it can never be queried — there is nothing to\n// select from — so it carries no table, columns or relationships.\nexport interface SemanticBuildClass {\n key: string;\n model: string | null;\n functionCount: number;\n}\n\n// What the build decided a physical table is. Entity and junction are both\n// reachable by the report AI — an entity directly, a junction through the\n// many-to-many it bridges. Excluded is not reachable at all.\nexport type SemanticTableClassification = 'entity' | 'junction' | 'excluded';\n\n// One physical table as the build classified it. `reason` answers a single\n// question — why can't the report AI see this table? — and is null when it can.\n// A junction with a reason bridged nothing, so it is just as invisible as an\n// excluded table.\nexport interface SemanticBuildTable {\n table: string;\n classification: SemanticTableClassification;\n model: string | null;\n reason: string | null;\n}\n\n// The build scoreboard shipped alongside the build status: the summary counts,\n// the full breakdown the settings dialog drills into — BOTH kinds of unit the\n// build caches, table-backed entities and standalone code classes — and the\n// catalog of every table the build saw, so the tab can show what the report AI\n// can't see, not just what it can.\n//\n// `functionCount` spans entities and classes alike: it is the same total the\n// build itself reports when it finishes.\n//\n// `tables` is empty for an artifact built before the catalog existed. Read that\n// as \"no catalog\", never as \"nothing was excluded\".\nexport interface SemanticBuildDetail {\n // Whether the artifact was produced by a build that ran to the end. Read it\n // beside `generatedAt`, never instead of it: the structural artifact is\n // published BEFORE the AI function pass, so a build whose AI pass failed still\n // carries a date and a full set of counts. The date says something was\n // written; only this says the build finished writing it.\n complete: boolean;\n generatedAt: Date | null;\n entityCount: number;\n classCount: number;\n functionCount: number;\n entities: SemanticBuildEntity[];\n classes: SemanticBuildClass[];\n tableCount: number;\n junctionCount: number;\n unlinkedJunctionCount: number;\n excludedCount: number;\n tables: SemanticBuildTable[];\n}\n\n// Which class a cached function was read from. An entity's cache splits into\n// 'model' and 'handler'; a standalone code class has one group, 'class'.\nexport type SemanticFunctionSource = 'model' | 'handler' | 'class';\n\n// One AI-classified code function from a model, handler or standalone class:\n// what kind of logic it is, what it does, and what it produces — the build's\n// cached \"what the code does\" knowledge shown in the functions dialog.\nexport interface SemanticEntityFunction {\n class: string;\n method: string;\n signature: string;\n kind: string;\n summary: string;\n produces: string;\n source: SemanticFunctionSource;\n}\n\n// One entity's cached code-function knowledge, fetched when a functions dialog\n// opens (the full set across all entities is too big to ship with the\n// scoreboard). One payload serves both dialogs — consumers filter by source.\nexport interface SemanticEntityFunctions {\n entity: string;\n generatedAt: Date | null;\n modelClass: string | null;\n handlerClass: string | null;\n functions: SemanticEntityFunction[];\n}\n\nexport interface SemanticBuildStatus {\n build: SemanticBuild | null;\n detail: SemanticBuildDetail;\n}\n\n// The report module's General settings (a small global key/value store, the\n// reporting counterpart of the app-wide settings). Each value ships with the\n// safe band its editor field is bounded to.\nexport interface ReportSettings {\n // How many summary calls the semantic build runs at once.\n semanticBuildConcurrency: number;\n semanticBuildConcurrencyMin: number;\n semanticBuildConcurrencyMax: number;\n}\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 { DAY_SHORT, formatLocalDate } from './format';\nimport {\n ChartGranularity, FilterGroupValue, GRANULARITY_OPTIONS, Report, ReportFilterGroup, ReportFilterOption,\n ReportLocaleTag,\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.\n//\n// The day is written in the report's locale, as its date cells are: 'Jan 5,\n// 2026' in en-US, '5 janv. 2026' in fr-CA.\nexport function dateBoundLabel(value: Date | string | null | undefined, locale: ReportLocaleTag): 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) : formatLocalDate(date, locale, DAY_SHORT);\n}\n\n\n// A stored yyyy-MM-dd boundary as a local Date for a date picker, or null.\n// parseISO reads a bare Y-M-D as LOCAL midnight, so the picker shows the day\n// that was stored, whatever the browser's zone.\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 Number.isNaN(date.getTime()) ? null : date;\n}\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 that was\n// picked, regardless of the browser's zone.\nexport function dateToBound(value: Date | null | undefined): string | null {\n return value instanceof Date && !Number.isNaN(value.getTime())\n ? format(value, 'yyyy-MM-dd')\n : null;\n}\n\n\n// A relative date-range preset key as a sentence-case label, derived from the\n// camelCase key itself ('last12Months' reads 'Last 12 months', 'thisWeek'\n// reads 'This week'), so no list of presets is mirrored here and a key the\n// server adds later still reads sensibly.\nexport function relativeLabel(relative: string): string {\n const words = relative\n .replace(/([a-z])([A-Z0-9])/g, '$1 $2')\n .replace(/(\\d)([A-Z])/g, '$1 $2')\n .toLowerCase();\n\n return words.charAt(0).toUpperCase() + words.slice(1);\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// The prefix of a group's item name, and of its key in the report URL.\nexport const GROUP_PARAM_PREFIX = 'g';\n\n// The query key fs-filter uses for a group's item(s), and the report URL's key\n// for the group's value (report-url-state.ts). One naming for both.\nexport function groupItemName(group: Pick<ReportFilterGroup, 'id'>): string {\n return `${GROUP_PARAM_PREFIX}${group.id}`;\n}\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. It is also the report URL's key for the grain\n// (report-url-state.ts). The grain travels to the server as the data\n// 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 = groupItemName(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// The query key of a list's search box in its component header. Fixed rather\n// than derived from an id because a header holds at most one, and it is NOT a\n// filter group: its text narrows that list alone, so it is read straight off\n// the change query and travels as the list's own `state.search`.\nexport const LIST_SEARCH_ITEM = 'listSearch';\n\n// The longest search the server applies (ReportQueryRunner::MAX_SEARCH_LENGTH).\n// The viewer cuts the text to it too, so the URL, the request and the export\n// title all carry the text that was actually searched.\nexport const LIST_SEARCH_MAX_LENGTH = 100;\n\n// The fs-filter config item for a list's search box, seeded with the text the\n// viewer last searched. fs-filter shows one search box per bar (its last\n// keyword item), so the caller adds this only to a header with no keyword\n// group of its own.\nexport function listSearchItem(value: string | null): IFilterConfigItem {\n return {\n type: ItemType.Keyword,\n name: LIST_SEARCH_ITEM,\n label: 'Search',\n default: value ?? undefined,\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 = groupItemName(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 { Day } from 'date-fns';\n\n\n// Report weeks start on Monday. This is a rule, not a setting: the server's\n// weekly time buckets (ReportTimeBucket::getPeriodStart() at the Week grain)\n// and its relative date presets (ReportRelativeRangeEnum) both start the week\n// on Monday, so the viewer's thisWeek/lastWeek presets must too, or a weekly\n// chart's buckets would straddle the range its own filter names.\nexport const REPORT_WEEK_STARTS_ON: Day = 1;\n","import { ParamMap, Params } from '@angular/router';\n\nimport {\n FilterGroupValue, ReportFilterType, ReportSort, ReportUrlParams, ReportUrlSnapshot,\n} from './interfaces/report.interface';\nimport {\n GROUP_BY_ITEM, GROUP_PARAM_PREFIX, dateBoundString, dateFromBound, groupItemName,\n} from './report-filter-items';\n\n\n// The report viewer's state in its URL: a pure codec, with no knowledge of a\n// loaded report. ReportFilterStateService decides WHAT is carried (only values\n// that differ from the authored defaults) and checks what is read back against\n// the report; this file only turns values into query params and back.\n//\n// ?page=7&groupBy=week&g12=last30Days&g15=3,5&g16=2026-01-01..&s31=-create_date&q31=north&h31=notes,total\n//\n// - g<groupId>: one key per filter group. A dateRange is its relative preset\n// name when it carries one, else 'YYYY-MM-DD..YYYY-MM-DD' (either side may be\n// empty); a select is its values joined by ','; a keyword is its text. An\n// empty value is an explicit clear of a group that has a default.\n// - s<componentId>: a list's sort column, '-' prefixed when descending.\n// - q<componentId>: the text in a list's search box.\n// - h<componentId>: the columns a viewer hid on a list (encodeColumnList).\n// - groupBy: the group-by grain (GROUP_BY_ITEM).\n// The page key is the host's (FsAiReportComponent.pageQueryParam) and is\n// written beside these, never by this codec.\n\n// The prefix of a group's value key. Declared beside the filter items, which\n// read it too (declaring it here would make the two files import each other);\n// re-exported so every codec constant can be imported from the codec.\nexport { GROUP_PARAM_PREFIX } from './report-filter-items';\n\n// The prefix of a list's sort key.\nexport const LIST_SORT_PARAM_PREFIX = 's';\n\n// Between the two days of an encoded fixed date range.\nexport const DATE_RANGE_SEPARATOR = '..';\n\n// The prefix of a list's search key.\nexport const LIST_SEARCH_PARAM_PREFIX = 'q';\n\n// The prefix of a list's hidden-columns key.\nexport const LIST_HIDDEN_PARAM_PREFIX = 'h';\n\n// The prefixes of the keys this codec owns, each followed by an id.\nconst OWNED_PREFIXES = [\n GROUP_PARAM_PREFIX, LIST_SORT_PARAM_PREFIX, LIST_SEARCH_PARAM_PREFIX, LIST_HIDDEN_PARAM_PREFIX,\n];\n\n// A key this codec owns: a group value, or a list's sort, search or hidden\n// columns. Any such key the snapshot no longer carries is removed from the\n// URL, so a host must not keep its own state under a key of this shape (one\n// of the prefixes above, then digits).\nexport const OWNED_PARAM = new RegExp(`^[${OWNED_PREFIXES.join('')}]\\\\d+$`);\n\nconst DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n// The viewer-state params of a URL as raw strings. Keys this codec does not\n// own are ignored.\nexport function readReportUrlParams(params: ParamMap): ReportUrlParams {\n const groups = new Map<number, string>();\n const listSorts = new Map<number, string>();\n const listSearches = new Map<number, string>();\n const listHidden = new Map<number, string>();\n // Each owned prefix names the map its keys go to; a prefix with no entry\n // here is never read as some other kind of state.\n const byPrefix: Record<string, Map<number, string>> = {\n [GROUP_PARAM_PREFIX]: groups,\n [LIST_SORT_PARAM_PREFIX]: listSorts,\n [LIST_SEARCH_PARAM_PREFIX]: listSearches,\n [LIST_HIDDEN_PARAM_PREFIX]: listHidden,\n };\n\n for (const key of params.keys) {\n if (OWNED_PARAM.test(key)) {\n byPrefix[key.charAt(0)]?.set(Number(key.slice(1)), params.get(key) ?? '');\n }\n }\n\n return { groups, listSorts, listSearches, listHidden, groupBy: params.get(GROUP_BY_ITEM) };\n}\n\n// A list's hidden column names as one param value. A name is a query's output\n// alias, which can hold a comma, so each is percent-encoded before the join.\nexport function encodeColumnList(names: readonly string[]): string {\n return names.map((name) => encodeURIComponent(name)).join(',');\n}\n\n// The column names of a hidden-columns param, in its order. Empty items are\n// dropped, and an item that does not decode (a hand-edited '%') is kept as\n// written. Whether a name is a column of the list is the caller's check.\nexport function decodeColumnList(raw: string): string[] {\n return raw.split(',')\n .filter((item) => item !== '')\n .map((item) => {\n try {\n return decodeURIComponent(item);\n } catch {\n return item;\n }\n });\n}\n\n// A group value read back from its URL param. null is an explicit clear (an\n// empty param). undefined means the param is unusable for a group of this type\n// (an unknown preset name, a malformed day, a wrong shape) and is ignored.\n// `resolveRelative` turns a preset name into today's range for it, or null for\n// a name it does not know.\nexport function decodeFilterValue(\n type: ReportFilterType,\n raw: string,\n resolveRelative: (name: string) => { start: Date; end: Date } | null,\n): FilterGroupValue | null | undefined {\n if (raw === '') {\n return null;\n }\n\n switch (type) {\n case 'dateRange':\n return raw.includes(DATE_RANGE_SEPARATOR)\n ? decodeFixedRange(raw)\n : decodePreset(raw, resolveRelative);\n\n case 'select': {\n const values = raw.split(',').filter((value) => value !== '');\n\n return values.length ? { values } : undefined;\n }\n\n case 'keyword':\n return raw.trim() ? { value: raw } : undefined;\n\n default:\n return undefined;\n }\n}\n\n// A group value as its URL param. The shape says how: a preset name, then a\n// date range, then select values, then keyword text. null (a cleared group)\n// is the empty param.\nexport function encodeFilterValue(value: FilterGroupValue | null): string {\n if (!value) {\n return '';\n }\n\n if (value.preset) {\n return value.preset;\n }\n\n if (value.start || value.end) {\n return [dateBoundString(value.start) ?? '', dateBoundString(value.end) ?? '']\n .join(DATE_RANGE_SEPARATOR);\n }\n\n if (value.values) {\n return value.values.map((item) => String(item)).join(',');\n }\n\n return value.value ?? '';\n}\n\nexport function encodeSort(sort: ReportSort): string {\n return `${sort.direction === 'desc' ? '-' : ''}${sort.column}`;\n}\n\n// A list sort read back from its URL param, or null when it names no column.\n// Whether the column is one the list can sort by is the caller's check.\nexport function decodeSort(raw: string): ReportSort | null {\n const descending = raw.startsWith('-');\n const column = descending ? raw.slice(1) : raw;\n\n return column\n ? { column, direction: descending ? 'desc' : 'asc' }\n : null;\n}\n\n// The query params that make the URL carry `snapshot`: every snapshot key is\n// set, and each owned key (or the grain) that `current` carries but the\n// snapshot does not is set to null, which removes it under the router's\n// 'merge' handling. Keys this codec does not own are left alone.\nexport function buildReportUrlParams(snapshot: ReportUrlSnapshot, current: ParamMap): Params {\n const params: Params = {};\n\n for (const key of current.keys) {\n if (OWNED_PARAM.test(key) || key === GROUP_BY_ITEM) {\n params[key] = null;\n }\n }\n\n snapshot.groups.forEach((value, groupId) => {\n params[groupItemName({ id: groupId })] = encodeFilterValue(value);\n });\n\n snapshot.listSorts.forEach((sort, componentId) => {\n params[`${LIST_SORT_PARAM_PREFIX}${componentId}`] = encodeSort(sort);\n });\n\n // The text as typed: the router percent-encodes it in the URL.\n snapshot.listSearches.forEach((search, componentId) => {\n params[`${LIST_SEARCH_PARAM_PREFIX}${componentId}`] = search;\n });\n\n snapshot.listHidden.forEach((names, componentId) => {\n params[`${LIST_HIDDEN_PARAM_PREFIX}${componentId}`] = encodeColumnList(names);\n });\n\n if (snapshot.frequency) {\n params[GROUP_BY_ITEM] = snapshot.frequency;\n }\n\n return params;\n}\n\n// 'YYYY-MM-DD..YYYY-MM-DD', either side optional but not both. Each side must\n// be a real calendar day.\nfunction decodeFixedRange(raw: string): FilterGroupValue | undefined {\n const sides = raw.split(DATE_RANGE_SEPARATOR);\n if (sides.length !== 2 || (!sides[0] && !sides[1])) {\n return undefined;\n }\n\n const [start, end] = sides.map((side) => side ? decodeDay(side) : null);\n if (start === undefined || end === undefined) {\n return undefined;\n }\n\n return { start, end };\n}\n\n// One side of a fixed range as a local Date, or undefined when it is not a\n// real Y-M-D day.\nfunction decodeDay(side: string): Date | undefined {\n return DAY_PATTERN.test(side) ? (dateFromBound(side) ?? undefined) : undefined;\n}\n\nfunction decodePreset(\n name: string,\n resolveRelative: (name: string) => { start: Date; end: Date } | null,\n): FilterGroupValue | undefined {\n const range = resolveRelative(name);\n\n return range ? { start: range.start, end: range.end, preset: name } : undefined;\n}\n","import { Injectable, signal } from '@angular/core';\n\nimport { Observable, Subject } from 'rxjs';\nimport { map, filter as rxFilter } from 'rxjs/operators';\n\nimport {\n endOfWeek, startOfMonth, startOfQuarter, startOfWeek, startOfYear,\n subDays, subMonths, subWeeks,\n} from 'date-fns';\n\nimport { REPORT_WEEK_STARTS_ON } from '../consts/report-week.const';\nimport {\n DEFAULT_FORMAT_CONTEXT, getZonedNow, resolveFormatContext, resolveReportTimezone,\n} from '../format';\nimport { ReportChatViewerFilter } from '../interfaces/report-chat-viewer-filter.interface';\nimport {\n ChartGranularity,\n FilterGroupDefault,\n FilterGroupValue,\n GRANULARITY_OPTIONS,\n Report,\n ReportComponent,\n ReportFilterGroup,\n ReportFormatContext,\n ReportSort,\n ReportUrlParams,\n ReportUrlSnapshot,\n ResolvedFilterValue,\n} from '../interfaces/report.interface';\nimport { listHiddenColumns, listSortTerms } from '../list-config';\nimport { dateBoundString, LIST_SEARCH_MAX_LENGTH } from '../report-filter-items';\nimport { decodeColumnList, decodeFilterValue, decodeSort } from '../report-url-state';\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// Whether two list sorts order the rows the same way. No direction reads as\n// ascending, the way the list applies it.\nfunction sameSort(a: ReportSort, b: ReportSort | null): boolean {\n return !!b\n && a.column === b.column\n && (a.direction ?? 'asc') === (b.direction ?? 'asc');\n}\n\n\n// Whether a value read off a filter bar is the value already stored for its\n// group: the same calendar days, the same select values in the same order and\n// the same trimmed text. A bar re-reads every group it shows on any change, so\n// this is what tells the group that changed from the ones that did not.\nexport function sameFilterValue(\n a: FilterGroupValue | null | undefined,\n b: FilterGroupValue | null | undefined,\n): boolean {\n if (!a || !b) {\n return !a && !b;\n }\n\n const values = (value: FilterGroupValue) => (value.values ?? []).map(String);\n\n return sameDays(a, b)\n && values(a).join('\\u0000') === values(b).join('\\u0000')\n && values(a).length === values(b).length\n && (a.value ?? '').trim() === (b.value ?? '').trim();\n}\n\n\n// The groups a bar re-read that it now shows with a value other than the one\n// it last reported, recording each new value in `lastReported`. A bar is\n// compared with itself, never with the stored value: a group shown in two bars\n// (level 'both') can be changed in the other one, and this bar is not\n// repainted, so its stale value must not be set back when the viewer changes\n// another of its items (the list search box, say).\nexport function movedGroupValues(\n lastReported: Map<number, FilterGroupValue | null>,\n reported: { groupId: number; value: FilterGroupValue | null }[],\n): { groupId: number; value: FilterGroupValue | null }[] {\n return reported.filter(({ groupId, value }) => {\n if (sameFilterValue(lastReported.get(groupId), value)) {\n return false;\n }\n\n lastReported.set(groupId, value);\n\n return true;\n });\n}\n\n\n// A list's search text as the server applies it: trimmed, then cut to\n// LIST_SEARCH_MAX_LENGTH characters (code points, as the server counts them).\nexport function listSearchText(text: string): string {\n return [...text.trim()].slice(0, LIST_SEARCH_MAX_LENGTH).join('');\n}\n\n\n// Whether two lists of column names are the same names in the same order.\nfunction sameNames(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((name, index) => name === b[index]);\n}\n\n\n// Whether two hidden-column maps hide the same columns on the same lists.\nfunction sameHidden(\n a: ReadonlyMap<number, readonly string[]>,\n b: ReadonlyMap<number, readonly string[]>,\n): boolean {\n return a.size === b.size\n && [...a].every(([componentId, names]) => sameNames(names, b.get(componentId) ?? []));\n}\n\n\n// Whether two date-range values cover the same calendar days.\nfunction sameDays(a: FilterGroupValue, b: FilterGroupValue): boolean {\n return dateBoundString(a.start) === dateBoundString(b.start)\n && dateBoundString(a.end) === dateBoundString(b.end);\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// Viewer filter state for the open report. Filter VALUES are never saved to\n// the report — this service holds them per filter GROUP (the propagation unit),\n// resolves them into per-component member-filter values for each data request,\n// and notifies the components whose groups changed so only they refetch.\n//\n// It is also the one source of the viewer state the report URL carries (group\n// values, the group-by grain, list sorts, searches and hidden columns):\n// urlSnapshot() says what differs from the authored defaults, init() restores\n// it, and urlChanges() tells the host's single URL writer when to write.\n//\n// Session-only, never in the URL: per-filter enable/disable toggles from a\n// component's filter menu (the `enabled` column is the authored default; a\n// viewer's toggle shouldn't write to the report).\n@Injectable()\nexport class ReportFilterStateService {\n\n // The open report's effective zone (resolveReportTimezone). Relative presets\n // resolve against today in it, and date cells render in it.\n public readonly timezone = signal<string>('UTC');\n\n // How the open report writes its numbers and dates (resolveFormatContext):\n // its locale, its currency and whether percents arrive as ratios. Every KPI,\n // chart, date cell and export reads it here. Compared by value, so a reload\n // of an unchanged report re-renders nothing.\n public readonly formatContext = signal<ReportFormatContext>(DEFAULT_FORMAT_CONTEXT, {\n equal: (a, b) => a.locale === b.locale\n && a.currency === b.currency\n && a.ratioPercent === b.ratioPercent,\n });\n\n // The config columns a viewer hid on each plain list (listHiddenColumns),\n // by component id; a list showing every column has no entry. A signal, so a\n // list hides and shows its columns in place: the rows do not change, so\n // nothing refetches. Compared by value, so a reload that keeps every column\n // repaints nothing.\n public readonly listHidden = signal<ReadonlyMap<number, readonly string[]>>(new Map(), {\n equal: sameHidden,\n });\n\n private _values = new Map<number, FilterGroupValue>();\n private _groups = new Map<number, ReportFilterGroup>();\n private _sessionDisabled = new Set<number>();\n\n // Groups that have a default the viewer cleared. Without this a reload of the\n // report (a chat edit, a dialog) would find no value for the group and seed\n // its default straight back. A change to the stored default releases it.\n private _cleared = new Set<number>();\n\n // The report's group-by control: a single report-wide bucket override for all\n // time-series charts. Unset = each chart uses its authored granularity. Never\n // saved to the report (the URL carries it), 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 // Each list's viewer-chosen sort, by component id. Held here rather than only\n // in the list's FsList so it survives the list being recreated (a page switch,\n // a reload after an edit) and so every consumer of viewer state reads one place.\n private _listSorts = new Map<number, ReportSort>();\n\n // Each list's search box text (listSearchText), by component id. A list with\n // an empty box has no entry. Held here for the same reasons as the sorts, and\n // because the box lives in the component header, not in the list.\n private _listSearches = new Map<number, string>();\n\n // The open report's lists, by component id, so a filter toggle can tell\n // which of them lose their search box (listSearchable).\n private _lists = new Map<number, ReportComponent>();\n\n // Whether the server answers a list search. List search and effectiveLocale\n // ship in the same framework change set, so a server that sends no\n // effectiveLocale has neither, and its lists show no search box.\n private _serverSearches = false;\n\n // Emits the id of the list whose search text changed.\n private _listSearchChanged$ = new Subject<number>();\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 // Fires whenever anything the URL carries may have changed.\n private _urlChanged$ = new Subject<void>();\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), and so does a group the viewer\n // cleared — UNLESS the group's stored default itself changed, which only\n // happens when an operator saved a new default in report settings or the\n // agent set one. 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\n // was first seeded with until a full page reload.\n //\n // A change of the report's zone moves \"today\", so a value still carrying its\n // group default's preset name is resolved again in the new zone. A value the\n // viewer picked, or one carrying another preset name, is kept as it is.\n //\n // `restore` is the viewer state read from the URL. The host passes it only on\n // the first load of a report; a reload after a chat or dialog edit passes\n // null, so the in-memory state wins. Params that name a group, list or column\n // the report no longer has, or that do not decode, are ignored.\n public init(report: Report, restore: ReportUrlParams | null = null): void {\n const previousTimezone = this.timezone();\n\n // Set first: the defaults seeded below resolve their relative presets in it.\n this.timezone.set(resolveReportTimezone(report));\n this.formatContext.set(resolveFormatContext(report));\n // Before any search restore: listSearchable reads it.\n this._serverSearches = report.effectiveLocale !== undefined;\n\n const timezoneChanged = previousTimezone !== this.timezone();\n const previousGroups = this._groups;\n this._groups = new Map<number, ReportFilterGroup>();\n\n for (const group of report.filterGroups ?? []) {\n this._groups.set(group.id, group);\n this._seed(group, previousGroups.get(group.id) ?? null, timezoneChanged);\n }\n\n this._lists = new Map(this._listComponents(report).map((component) => [component.id, component]));\n\n if (restore) {\n this._restore(report, restore);\n }\n\n this._prune(report);\n\n this._changed$.next(null);\n this._urlChanged$.next();\n }\n\n public value(groupId: number): FilterGroupValue | undefined {\n return this._values.get(groupId);\n }\n\n // A bar's value for a group. A date range keeps the stored preset name only\n // while its days are still the stored days: the bars re-set every group they\n // show whenever any one of them changes, and an untouched rolling range must\n // keep its name rather than turn into two fixed dates. Any other range, a\n // picker shortcut included, is stored as the fixed dates it shows.\n public setValue(groupId: number, value: FilterGroupValue | null): void {\n if (value === null) {\n this._values.delete(groupId);\n\n if (this._groups.get(groupId)?.config?.default) {\n this._cleared.add(groupId);\n }\n } else {\n this._values.set(groupId, this._withPreset(this._values.get(groupId), value));\n this._cleared.delete(groupId);\n }\n\n this._changed$.next(groupId);\n this._urlChanged$.next();\n }\n\n // A relative preset name as today's range in the report's zone, or null for\n // a name it does not know. The URL codec decodes preset names through this.\n public resolveRelative(name: string): { start: Date; end: Date } | null {\n return this._relativeRange(name);\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 this._urlChanged$.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 // The sort the viewer last fetched a list with, or null when it hasn't sorted\n // (the list then falls back to its authored sort).\n public listSort(componentId: number): ReportSort | null {\n return this._listSorts.get(componentId) ?? null;\n }\n\n // Records a list's sort when it is the viewer's own: a sort that is the\n // list's authored first term is the list's default, not a choice, so it\n // clears the entry instead (the rule the URL snapshot applies). Otherwise a\n // list's first fetch would record its seeded authored term, and a list the\n // agent re-sorts later in the session would keep sending the old term\n // first. Deliberately emits no change: the list sets this from the fetch\n // that already ran with that sort, so a notification would only make it\n // refetch the same rows. Only the URL hears about it.\n public setListSort(component: ReportComponent, sort: ReportSort | null): void {\n if (sort && !sameSort(sort, listSortTerms(component.config)[0] ?? null)) {\n this._listSorts.set(component.id, sort);\n } else {\n this._listSorts.delete(component.id);\n }\n\n this._urlChanged$.next();\n }\n\n // The text a list is searched by, or null when its search box is empty.\n public listSearch(componentId: number): string | null {\n return this._listSearches.get(componentId) ?? null;\n }\n\n // Whether a list shows the search box over its text columns: it does when the\n // server answers a list search (see _serverSearches), unless one of its live\n // filters belongs to a keyword group its header shows. A bar shows one search\n // box (its last keyword item), and that one is the author's. The header, the\n // URL restore, the pruning, the data request state and the exports all read\n // this one rule, so no search narrows a list whose screen has no box showing\n // it, and no export titles a search the server did not apply.\n public listSearchable(component: ReportComponent): boolean {\n return this._serverSearches\n && component.type === 'list'\n && !(component.filters ?? []).some((filter) => {\n const group = this._groups.get(filter.filterGroupId);\n\n return filter.enabled\n && !this._sessionDisabled.has(filter.id)\n && group?.type === 'keyword'\n && (group.level === 'component' || group.level === 'both');\n });\n }\n\n // Records a list's search box text (listSearchText); an empty box clears\n // it. The header calls this on every change of any of its items, so the\n // list and the URL hear about it only when the stored text actually changed.\n public setListSearch(componentId: number, text: string): void {\n const search = listSearchText(text);\n\n if (search === (this._listSearches.get(componentId) ?? '')) {\n return;\n }\n\n if (search) {\n this._listSearches.set(componentId, search);\n } else {\n this._listSearches.delete(componentId);\n }\n\n this._listSearchChanged$.next(componentId);\n this._urlChanged$.next();\n }\n\n // The config column names a viewer hid on a list; none when it shows them all.\n public hiddenColumns(componentId: number): readonly string[] {\n return this.listHidden().get(componentId) ?? [];\n }\n\n // Records the columns a viewer hid on a list, kept to listHiddenColumns:\n // names the list cannot hide are dropped, and none (or every column) clears\n // the entry. Only the URL hears about it, and only on a real change.\n public setHiddenColumns(componentId: number, names: readonly string[]): void {\n const hidden = listHiddenColumns(this._lists.get(componentId)?.config, names);\n\n if (sameNames(hidden, this.hiddenColumns(componentId))) {\n return;\n }\n\n const next = new Map(this.listHidden());\n\n if (hidden.length) {\n next.set(componentId, hidden);\n } else {\n next.delete(componentId);\n }\n\n this.listHidden.set(next);\n this._urlChanged$.next();\n }\n\n // Fires whenever one list's search text changes, so that list refetches.\n public listSearchChanges(componentId: number): Observable<void> {\n return this._listSearchChanged$.asObservable()\n .pipe(\n rxFilter((id) => id === componentId),\n map(() => undefined),\n );\n }\n\n // Fires whenever the viewer state the URL carries may have changed: a group\n // value, the grain, a list sort, search or hidden columns, or a (re)load of\n // the report.\n public urlChanges(): Observable<void> {\n return this._urlChanged$.asObservable();\n }\n\n // The viewer state the URL should carry for `report`: only what differs from\n // the authored defaults, so an untouched report has a bare URL and keeps\n // following its defaults when they change. A group the viewer cleared is\n // null. A date range is compared on its days against its default resolved\n // today, so a value that is the default under another preset name (thisYear\n // against a yearToDate default) is still the default.\n public urlSnapshot(report: Report): ReportUrlSnapshot {\n const groups = new Map<number, FilterGroupValue | null>();\n\n for (const group of this._groups.values()) {\n const value = this._values.get(group.id);\n\n if (this._cleared.has(group.id)) {\n groups.set(group.id, null);\n } else if (value && !this._isDefault(group, value)) {\n groups.set(group.id, value);\n }\n }\n\n const listSorts = new Map<number, ReportSort>();\n const listSearches = new Map<number, string>();\n const listHidden = new Map<number, string[]>();\n\n for (const component of this._listComponents(report)) {\n const sort = this._listSorts.get(component.id);\n const search = this._listSearches.get(component.id);\n const hidden = this.hiddenColumns(component.id);\n\n if (sort && !sameSort(sort, listSortTerms(component.config)[0] ?? null)) {\n listSorts.set(component.id, sort);\n }\n\n if (search) {\n listSearches.set(component.id, search);\n }\n\n if (hidden.length) {\n listHidden.set(component.id, [...hidden]);\n }\n }\n\n return { groups, listSorts, listSearches, listHidden, frequency: this._frequency };\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 // Turning a keyword filter back on takes its list's search box away, and\n // the search with it. The list refetches on the group change below.\n this._dropUnsearchable();\n\n this._changed$.next(groupId);\n this._urlChanged$.next();\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 const fields = value ? this._resolvedFields(value) : null;\n\n if (fields) {\n resolved.push({ filterId: filter.id, ...fields });\n }\n }\n\n return resolved;\n }\n\n // What the viewer has set, one entry per filter group, for the report chat:\n // the agent reads it to know what is on screen. Group order, not the order\n // the values were set in, so the same state always reads the same. A group\n // with nothing in it is left out, and a saved default counts until the\n // viewer changes it. Per-filter toggles are a component's own business, so\n // they are not part of it.\n public viewerFilters(): ReportChatViewerFilter[] {\n return [...this._values.entries()]\n .sort(([a], [b]) => a - b)\n .map(([groupId, value]) => {\n const fields = this._resolvedFields(value);\n\n return fields ? { groupId, ...fields } : null;\n })\n .filter((entry): entry is ReportChatViewerFilter => entry !== null);\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 value as the fields a request carries: date bounds as calendar\n // days, select values when any are picked, keyword text trimmed. Null when\n // all of them are empty. The preset name is URL state only, so it is left\n // behind.\n private _resolvedFields(value: FilterGroupValue): Omit<ResolvedFilterValue, 'filterId'> | null {\n const fields: Omit<ResolvedFilterValue, 'filterId'> = {};\n\n if (value.start) {\n fields.start = dateBoundString(value.start);\n }\n if (value.end) {\n fields.end = dateBoundString(value.end);\n }\n if (value.values?.length) {\n fields.values = value.values;\n }\n if (value.value?.trim()) {\n fields.value = value.value.trim();\n }\n\n return fields.start || fields.end || fields.values || fields.value\n ? fields\n : null;\n }\n\n // Seeds one group on (re)load; see init(). `previous` is the group as the\n // last load had it, or null when it is new.\n private _seed(\n group: ReportFilterGroup,\n previous: ReportFilterGroup | null,\n timezoneChanged: boolean,\n ): void {\n const defaultChanged = !sameDefault(previous?.config?.default ?? null, group.config?.default ?? null);\n\n if (defaultChanged) {\n this._cleared.delete(group.id);\n }\n\n if (this._cleared.has(group.id)) {\n return;\n }\n\n const value = this._values.get(group.id);\n const presetToResolve = timezoneChanged\n && !!value?.preset\n && value.preset === group.config?.default?.relative;\n\n if (value && !defaultChanged && !presetToResolve) {\n return;\n }\n\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 // Applies the viewer state read from the URL on top of the seeded defaults.\n private _restore(report: Report, restore: ReportUrlParams): void {\n this._restoreGroups(restore);\n this._restoreListSorts(report, restore);\n this._restoreListSearches(report, restore);\n this._restoreListHidden(restore);\n\n // The URL is the whole truth on a first load: no grain in it means the\n // authored ones. The host still drops a grain the report does not offer.\n this._frequency = GRANULARITY_OPTIONS\n .find((option) => option.value === restore.groupBy)?.value ?? null;\n }\n\n // The URL's group values. An empty one is an explicit clear of the group.\n private _restoreGroups(restore: ReportUrlParams): void {\n restore.groups.forEach((raw, groupId) => {\n const group = this._groups.get(groupId);\n const value = group\n ? decodeFilterValue(group.type, raw, (name) => this.resolveRelative(name))\n : undefined;\n\n if (value === null) {\n this._values.delete(groupId);\n\n if (group?.config?.default) {\n this._cleared.add(groupId);\n }\n } else if (value) {\n this._values.set(groupId, value);\n this._cleared.delete(groupId);\n }\n });\n }\n\n // The URL's list sorts, each kept only for a list the report has and a\n // column that list can be sorted by.\n private _restoreListSorts(report: Report, restore: ReportUrlParams): void {\n const lists = new Map(this._listComponents(report).map((component) => [component.id, component]));\n\n restore.listSorts.forEach((raw, componentId) => {\n const component = lists.get(componentId);\n const sort = decodeSort(raw);\n\n if (component && sort && this._sortableColumns(component).includes(sort.column)) {\n this._listSorts.set(componentId, sort);\n }\n });\n }\n\n // The URL's list searches, each kept only for a list the report has that\n // shows a search box (listSearchable). The text is read as listSearchText,\n // and an empty one is no search.\n private _restoreListSearches(report: Report, restore: ReportUrlParams): void {\n const lists = new Map(this._listComponents(report).map((component) => [component.id, component]));\n\n restore.listSearches.forEach((raw, componentId) => {\n const component = lists.get(componentId);\n const search = listSearchText(raw);\n\n if (component && this.listSearchable(component) && search) {\n this._listSearches.set(componentId, search);\n }\n });\n }\n\n // The URL's hidden columns, each list's kept to listHiddenColumns: only the\n // configured columns of a plain list the report has, and none when they\n // would hide every column.\n private _restoreListHidden(restore: ReportUrlParams): void {\n const next = new Map(this.listHidden());\n\n restore.listHidden.forEach((raw, componentId) => {\n const hidden = listHiddenColumns(this._lists.get(componentId)?.config, decodeColumnList(raw));\n\n if (hidden.length) {\n next.set(componentId, hidden);\n }\n });\n\n this.listHidden.set(next);\n }\n\n // Drops the search of every list that no longer shows a search box: one\n // the report no longer has, or one whose header now has a keyword group.\n private _dropUnsearchable(): void {\n this._listSearches.forEach((search, componentId) => {\n const component = this._lists.get(componentId);\n\n if (!component || !this.listSearchable(component)) {\n this._listSearches.delete(componentId);\n }\n });\n }\n\n // Drops state kept for groups, lists and filters the report no longer has.\n // A list sort also goes when its column does: the agent can remove or rename\n // it, and the recreated list would send a column the query does not know.\n // A list search goes with its list (or when the component is no longer a\n // list), and when the list gains a keyword group and so loses its box.\n // Hidden columns keep only the names their list still has as columns (the\n // agent can remove or rename one, or turn the list into a cross-tab), and go\n // when what is left would hide every column.\n private _prune(report: Report): void {\n for (const groupId of [...this._values.keys(), ...this._cleared]) {\n if (!this._groups.has(groupId)) {\n this._values.delete(groupId);\n this._cleared.delete(groupId);\n }\n }\n\n this._listSorts.forEach((sort, componentId) => {\n const component = this._lists.get(componentId);\n\n if (!component || !this._sortableColumns(component).includes(sort.column)) {\n this._listSorts.delete(componentId);\n }\n });\n\n const filterIds = new Set(this._components(report)\n .flatMap((component) => (component.filters ?? []).map((filter) => filter.id)));\n\n this._sessionDisabled.forEach((filterId) => {\n if (!filterIds.has(filterId)) {\n this._sessionDisabled.delete(filterId);\n }\n });\n\n this._dropUnsearchable();\n\n const hidden = new Map<number, readonly string[]>();\n\n this.listHidden().forEach((names, componentId) => {\n const kept = listHiddenColumns(this._lists.get(componentId)?.config, names);\n\n if (kept.length) {\n hidden.set(componentId, kept);\n }\n });\n\n this.listHidden.set(hidden);\n }\n\n // The value a bar sets, keeping the stored preset name while the days are\n // still the stored days (see setValue).\n private _withPreset(stored: FilterGroupValue | undefined, value: FilterGroupValue): FilterGroupValue {\n const fixed: FilterGroupValue = { ...value };\n delete fixed.preset;\n\n return stored?.preset && sameDays(stored, fixed)\n ? { ...fixed, preset: stored.preset }\n : fixed;\n }\n\n // Whether a value is the group's authored default, by type: a date range on\n // its days (the default resolved today), a select on its values in any\n // order, a keyword on its text.\n private _isDefault(group: ReportFilterGroup, value: FilterGroupValue): boolean {\n const defaultValue = this._defaultValue(group);\n if (!defaultValue) {\n return false;\n }\n\n switch (group.type) {\n case 'dateRange':\n // An untouched rolling default still carries its preset name. Its days\n // were resolved when it was seeded, and after midnight they no longer\n // match today's, but it is still the default and stays out of the URL.\n if (value.preset && value.preset === group.config?.default?.relative) {\n return true;\n }\n\n return sameDays(value, defaultValue);\n\n case 'select': {\n const values = (value.values ?? []).map(String).sort();\n const defaults = (defaultValue.values ?? []).map(String).sort();\n\n return values.length === defaults.length\n && values.every((item, index) => item === defaults[index]);\n }\n\n default:\n return (value.value ?? '').trim() === (defaultValue.value ?? '').trim();\n }\n }\n\n // Every component of the report: its pages' and its header and footer's.\n private _components(report: Report): ReportComponent[] {\n return [\n ...(report.pages ?? []).flatMap((page) => page.components ?? []),\n ...(report.master?.components ?? []),\n ];\n }\n\n private _listComponents(report: Report): ReportComponent[] {\n return this._components(report)\n .filter((component) => component.type === 'list');\n }\n\n // The columns a list can be sorted by: every authored column, or a\n // cross-tab's row column only (its pivot columns come and go with the data).\n private _sortableColumns(component: ReportComponent): string[] {\n const config = component.config;\n\n if (config?.pivotBy?.column) {\n return config.rowBy?.column ? [config.rowBy.column] : [];\n }\n\n return (config?.columns ?? []).map((column) => column.column);\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 and carries its preset name; a fixed\n // range, select values and keyword 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, preset: groupDefault.relative } : 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 // A relative preset as a calendar-day range. \"Today\" is the day in the\n // report's effective zone, not the browser's, so every viewer seeds the same\n // range. The server twin is ReportRelativeRangeEnum (framework/Report/Enum),\n // and ReportRelativeRangeEnumTest pins the table both sides must produce.\n private _relativeRange(relative: string): { start: Date; end: Date } | null {\n const now = getZonedNow(this.timezone());\n\n switch (relative) {\n // A calendar week, Monday to Sunday (REPORT_WEEK_STARTS_ON, the same week\n // the server's weekly buckets use), 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 on the previous week's Sunday rather than at `now`,\n // because the week it names has closed. `thisWeek` follows every other\n // preset here and runs up to now, so it is deliberately a part-finished\n // week (on a Sunday it is the whole Monday-to-Sunday week).\n case 'thisWeek':\n return { start: startOfWeek(now, { weekStartsOn: REPORT_WEEK_STARTS_ON }), end: now };\n case 'lastWeek': {\n const previous = subWeeks(now, 1);\n\n return {\n start: startOfWeek(previous, { weekStartsOn: REPORT_WEEK_STARTS_ON }),\n end: endOfWeek(previous, { weekStartsOn: REPORT_WEEK_STARTS_ON }),\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","// A chart measure's named color. The names follow the report chart palette in\n// order (REPORT_CHART_COLOR_BY_NAME), so blue is the first series' default\n// color and gray the tenth's.\n//\n// Mirrors the server's ChartColorEnum value for value, in the same order.\nexport enum ReportChartColor {\n Blue = 'blue',\n Orange = 'orange',\n Red = 'red',\n Teal = 'teal',\n Green = 'green',\n Yellow = 'yellow',\n Purple = 'purple',\n Pink = 'pink',\n Brown = 'brown',\n Gray = 'gray',\n}\n","// Which points of a chart's series print their value beside them: none, every\n// point, only each series' last point, or every point with the overlapping\n// labels hidden (auto). Axis charts only.\n//\n// Mirrors the server's ChartDataLabelsEnum value for value.\nexport enum ReportChartDataLabels {\n None = 'none',\n All = 'all',\n Last = 'last',\n Auto = 'auto',\n}\n","// How a time axis writes its period labels: short ('May', with the year on a\n// second line when the data spans years), long ('May 2026', in the report's\n// locale) or numeric ('2026-05', the same in every locale). A category axis\n// prints its values as they are.\n//\n// Mirrors the server's ChartDateLabelEnum value for value.\nexport enum ReportChartDateLabel {\n Short = 'short',\n Long = 'long',\n Numeric = 'numeric',\n}\n","// How a line series' line is drawn; the server refuses a non-solid line on\n// an area series. The values are ECharts'\n// lineStyle.type values, so the screen takes them as they are.\n//\n// Mirrors the server's ChartLineStyleEnum value for value.\nexport enum ReportChartLineStyle {\n Solid = 'solid',\n Dashed = 'dashed',\n Dotted = 'dotted',\n}\n","// The statistic of a series a chart measure draws as a horizontal line across\n// the plot: its average, median, lowest or highest value.\n//\n// Mirrors the server's ChartMarkStatEnum value for value.\nexport enum ReportChartMarkStat {\n Average = 'average',\n Median = 'median',\n Min = 'min',\n Max = 'max',\n}\n","// Text blocks — shared by the canvas and both exports, so a block reads the\n// same on screen, in the deck and in the PDF.\n//\n// A block's html arrives already rebuilt server-side from a small allowlist\n// (ReportTextHtml): p, h1-h3, strong, em, u, s, ul/ol/li, br, a, and span with\n// color / background-color / font-size / font-weight / font-family, plus\n// text-align on a block. Everything here only has to understand that set.\n\n\n// Body text size, points, and the heading sizes — the same numbers the canvas\n// stylesheet uses, so an unstyled paragraph is one size everywhere.\nexport const DEFAULT_TEXT_SIZE = 12;\nexport const HEADING_TEXT_SIZES: Record<number, number> = { 1: 24, 2: 18, 3: 14 };\nexport const DEFAULT_TEXT_COLOR = '#1f2933';\n\n// What the tokens in a block's html are filled with, per page.\nexport interface TextTokenContext {\n pageNumber: number;\n pageName: string;\n reportName: string;\n}\n\n// One styled stretch of text.\nexport interface TextRun {\n text: string;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strike?: boolean;\n // #rrggbb\n color?: string;\n highlight?: string;\n // points\n fontSize?: number;\n fontFace?: string;\n link?: string;\n}\n\n// One line-starting block: a paragraph, a heading or a list item.\nexport interface TextParagraph {\n runs: TextRun[];\n align?: 'left' | 'center' | 'right' | 'justify';\n bullet?: 'bullet' | 'number';\n heading?: number;\n}\n\n// The tokens a block may carry, with what fills each. {{page.number}} is the\n// page's position among the report's pages (1-based), which is what makes a\n// shared footer number every page correctly.\nconst TOKENS: Record<string, (context: TextTokenContext) => string> = {\n 'page.number': (context) => String(context.pageNumber),\n 'page.name': (context) => context.pageName,\n 'report.name': (context) => context.reportName,\n};\n\n// Replace every {{token}} in the html. Values are html-escaped: a page named\n// \"R&D <draft>\" must read as that, not as markup.\nexport function fillTextTokens(html: string, context: TextTokenContext): string {\n return html.replace(/\\{\\{\\s*([a-z.]+)\\s*\\}\\}/gi, (match, token: string) => {\n const fill = TOKENS[token.toLowerCase()];\n\n return fill ? escapeHtml(fill(context)) : match;\n });\n}\n\n// Walk a block's html into paragraphs of styled runs — the shape both exports\n// draw from. Tokens are filled first so a page number is just text by then.\nexport function textParagraphs(html: string, context: TextTokenContext): TextParagraph[] {\n const document = new DOMParser().parseFromString(`<body>${fillTextTokens(html, context)}</body>`, 'text/html');\n const paragraphs: TextParagraph[] = [];\n\n walkBlocks(document.body, paragraphs, null);\n\n return paragraphs.filter((paragraph, index) =>\n // Keep an empty paragraph between two others (a deliberate blank line), but\n // not one left dangling at either end.\n paragraph.runs.length || (index > 0 && index < paragraphs.length - 1));\n}\n\n// The html as plain text — what a block says, for anything that cannot style it.\nexport function textPlain(html: string, context: TextTokenContext): string {\n return textParagraphs(html, context)\n .map((paragraph) => paragraph.runs.map((run) => run.text).join(''))\n .join('\\n');\n}\n\nfunction walkBlocks(\n parent: Node,\n paragraphs: TextParagraph[],\n list: 'bullet' | 'number' | null,\n): void {\n // Loose inline content between blocks (text straight under <body> or <li>)\n // is gathered into a paragraph of its own.\n let loose: TextParagraph | null = null;\n const flush = () => {\n if (loose) {\n paragraphs.push(loose);\n loose = null;\n }\n };\n\n parent.childNodes.forEach((node) => {\n const name = node.nodeName.toLowerCase();\n\n if (name === 'ul' || name === 'ol') {\n flush();\n walkBlocks(node, paragraphs, name === 'ul' ? 'bullet' : 'number');\n\n return;\n }\n\n if (name === 'li') {\n flush();\n const item: TextParagraph = { runs: [], bullet: list ?? 'bullet' };\n const nested: TextParagraph[] = [];\n // A list item's first paragraph IS the item; anything after it is its own\n // line under the same bullet.\n walkBlocks(node, nested, list);\n const [first, ...rest] = nested.length ? nested : [item];\n paragraphs.push({ ...first, bullet: list ?? 'bullet' }, ...rest);\n\n return;\n }\n\n if (name === 'p' || /^h[1-3]$/.test(name)) {\n flush();\n const element = node as HTMLElement;\n const heading = name.startsWith('h') ? Number(name[1]) : undefined;\n const paragraph: TextParagraph = {\n runs: [],\n align: blockAlign(element),\n bullet: undefined,\n heading,\n };\n const base: Partial<TextRun> = heading\n ? { bold: true, fontSize: HEADING_TEXT_SIZES[heading] }\n : {};\n\n walkInline(node, base, paragraph, paragraphs);\n paragraphs.push(paragraph);\n\n return;\n }\n\n loose = loose ?? { runs: [] };\n walkInline(node, {}, loose, paragraphs, true);\n });\n\n flush();\n}\n\n// Accumulate inline styles down the tree. A <br> ends the current line: the\n// runs after it start a new paragraph with the same alignment and bullet.\nfunction walkInline(\n node: Node,\n style: Partial<TextRun>,\n paragraph: TextParagraph,\n paragraphs: TextParagraph[],\n isSelf = false,\n): void {\n const visit = (child: Node) => {\n if (child.nodeType === Node.TEXT_NODE) {\n const text = child.textContent ?? '';\n if (text) {\n paragraph.runs.push({ ...style, text });\n }\n\n return;\n }\n\n if (child.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n\n const element = child as HTMLElement;\n const name = element.nodeName.toLowerCase();\n\n if (name === 'br') {\n paragraphs.push({ ...paragraph, runs: [...paragraph.runs] });\n paragraph.runs.length = 0;\n\n return;\n }\n\n walkInline(element, { ...style, ...inlineStyle(element) }, paragraph, paragraphs);\n };\n\n if (isSelf) {\n visit(node);\n } else {\n node.childNodes.forEach(visit);\n }\n}\n\nfunction inlineStyle(element: HTMLElement): Partial<TextRun> {\n const name = element.nodeName.toLowerCase();\n const style: Partial<TextRun> = {};\n\n if (name === 'strong') {\n style.bold = true;\n }\n if (name === 'em') {\n style.italic = true;\n }\n if (name === 'u') {\n style.underline = true;\n }\n if (name === 's') {\n style.strike = true;\n }\n if (name === 'a') {\n style.link = element.getAttribute('href') ?? undefined;\n style.underline = true;\n }\n\n const css = element.style;\n if (css.color) {\n style.color = hexColor(css.color);\n }\n if (css.backgroundColor) {\n style.highlight = hexColor(css.backgroundColor);\n }\n if (css.fontSize) {\n style.fontSize = points(css.fontSize);\n }\n if (css.fontWeight) {\n style.bold = css.fontWeight === 'bold' || Number(css.fontWeight) >= 600;\n }\n if (css.fontStyle) {\n style.italic = css.fontStyle === 'italic';\n }\n if (css.textDecoration) {\n style.underline = css.textDecoration.includes('underline');\n style.strike = css.textDecoration.includes('line-through');\n }\n if (css.fontFamily) {\n style.fontFace = css.fontFamily.split(',')[0].replace(/[\"']/g, '').trim();\n }\n\n return style;\n}\n\nfunction blockAlign(element: HTMLElement): TextParagraph['align'] {\n const align = element.style.textAlign;\n\n return align === 'center' || align === 'right' || align === 'justify' ? align : undefined;\n}\n\n// A CSS font-size in points. The canvas renders at 96px per inch, so 1px is\n// exactly 0.75pt; em/rem/% are relative to the body size.\nfunction points(value: string): number | undefined {\n const match = /^([\\d.]+)(pt|px|em|rem|%)$/.exec(value.trim());\n if (!match) {\n return undefined;\n }\n\n const size = Number(match[1]);\n switch (match[2]) {\n case 'pt':\n return size;\n case 'px':\n return size * 0.75;\n case '%':\n return (size / 100) * DEFAULT_TEXT_SIZE;\n default:\n return size * DEFAULT_TEXT_SIZE;\n }\n}\n\n// Any CSS color the allowlist lets through (hex, rgb(), a name) as #rrggbb —\n// the one form both exports accept. The browser resolves it, so a named color\n// comes out exactly as the canvas painted it.\nlet colorContext: CanvasRenderingContext2D | null = null;\n\nfunction hexColor(value: string): string | undefined {\n colorContext = colorContext ?? document.createElement('canvas').getContext('2d');\n if (!colorContext) {\n return undefined;\n }\n\n colorContext.fillStyle = '#000000';\n colorContext.fillStyle = value;\n const resolved = String(colorContext.fillStyle);\n\n if (resolved.startsWith('#')) {\n return resolved;\n }\n\n // rgba(...) for a translucent color — drop the alpha, keep the hue.\n const channels = resolved.match(/[\\d.]+/g)?.slice(0, 3).map(Number) ?? [];\n\n return channels.length === 3\n ? `#${channels.map((channel) => Math.round(channel).toString(16).padStart(2, '0')).join('')}`\n : undefined;\n}\n\nexport function escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n","import { ReportChartColor } from '../enums/report-chart-color.enum';\nimport { WaterfallStepKind } from '../interfaces/report.interface';\n\n\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\n// A measure's named color is the palette entry at the name's position, so a\n// measure colored blue looks exactly like the first series left to the theme.\nexport const REPORT_CHART_COLOR_BY_NAME: Record<ReportChartColor, string> = {\n [ReportChartColor.Blue]: REPORT_CHART_COLORS[0],\n [ReportChartColor.Orange]: REPORT_CHART_COLORS[1],\n [ReportChartColor.Red]: REPORT_CHART_COLORS[2],\n [ReportChartColor.Teal]: REPORT_CHART_COLORS[3],\n [ReportChartColor.Green]: REPORT_CHART_COLORS[4],\n [ReportChartColor.Yellow]: REPORT_CHART_COLORS[5],\n [ReportChartColor.Purple]: REPORT_CHART_COLORS[6],\n [ReportChartColor.Pink]: REPORT_CHART_COLORS[7],\n [ReportChartColor.Brown]: REPORT_CHART_COLORS[8],\n [ReportChartColor.Gray]: REPORT_CHART_COLORS[9],\n};\n\n// Reference lines and bands are drawn in one neutral slate, apart from every\n// series color, so a target never reads as another series.\nexport const REPORT_REFERENCE_COLOR = '52606d';\n\n// A waterfall colors each bar by what it does to the running total, in the\n// order Excel and PowerPoint use by default: a rise takes the first series\n// color, a fall the second, and the closing total a neutral gray.\nexport const REPORT_WATERFALL_COLORS: Record<WaterfallStepKind, string> = {\n rise: REPORT_CHART_COLORS[0],\n fall: REPORT_CHART_COLORS[1],\n total: REPORT_CHART_COLORS[9],\n};\n","// The report charts' typeface and axis-label size. The ECharts theme draws with\n// them, and the option builder measures axis labels with them, so the room it\n// leaves around the labels matches what is drawn.\nexport const REPORT_CHART_FONT_FAMILY = 'Roboto, \"Helvetica Neue\", sans-serif';\nexport const REPORT_AXIS_LABEL_FONT_SIZE = 11;\n// The size a chart's data labels (the values printed beside its points) are\n// drawn in: a step under the axis labels, so they never outweigh the axes.\nexport const REPORT_DATA_LABEL_FONT_SIZE = 10;\n","import type { EChartsOption, LegendComponentOption, SeriesOption, TooltipComponentFormatterCallbackParams } from 'echarts';\n\nimport { isValid, parseISO } from 'date-fns';\n\nimport { ReportChartColor } from './enums/report-chart-color.enum';\nimport { ReportChartDataLabels } from './enums/report-chart-data-labels.enum';\nimport { ReportChartDateLabel } from './enums/report-chart-date-label.enum';\nimport { ReportChartLineStyle } from './enums/report-chart-line-style.enum';\nimport { ReportChartMarkStat } from './enums/report-chart-mark-stat.enum';\nimport { ReportListColumnFormat } from './enums/report-list-column-format.enum';\nimport { ReportNumberUnits } from './enums/report-number-units.enum';\nimport { ReportValueFormat } from './enums/report-value-format.enum';\nimport {\n axisNumberFormat,\n ChartNumberFormat,\n chartValuePeak,\n DAY_SHORT,\n formatLocalDate,\n formatNumber,\n formatPlainNumber,\n hasNumberFormat,\n MONTH_DAY,\n MONTH_LONG,\n MONTH_YEAR,\n resolveChartNumberFormat,\n} from './format';\nimport {\n AxisChartType,\n ChartConfig,\n ChartGranularity,\n ChartMeasure,\n ChartReference,\n ChartValueAxis,\n ComponentData,\n GRANULARITY_OPTIONS,\n LegendPosition,\n ListColumn,\n ListConfig,\n NumberFormatSpec,\n ReportComponent,\n ReportFormatContext,\n ReportLocaleTag,\n WaterfallStepKind,\n} from './interfaces/report.interface';\nimport { escapeHtml } from './text';\nimport {\n REPORT_CHART_COLOR_BY_NAME,\n REPORT_CHART_COLORS,\n REPORT_REFERENCE_COLOR,\n REPORT_WATERFALL_COLORS,\n} from './theme/palette';\nimport { REPORT_AXIS_LABEL_FONT_SIZE, REPORT_CHART_FONT_FAMILY, REPORT_DATA_LABEL_FONT_SIZE } from './theme/typography';\n\n\n// Room for an axis title. ECharts 5's containLabel keeps the TICK labels inside\n// the grid but not the axis name, so without this a vertical chart's category\n// title runs off the bottom edge or under a bottom legend, and its value title\n// above the plot runs off the top or under a top legend.\nconst AXIS_NAME_ROOM = 20;\n// ECharts' own default gap between the axis line and its tick labels.\nconst AXIS_LABEL_MARGIN = 8;\n// Clearance between the longest tick label and a horizontal chart's rotated\n// title, so the two never touch.\nconst AXIS_NAME_CLEARANCE = 6;\n// A horizontal chart's category labels are cut short with an ellipsis past\n// this width (the tooltip still shows them in full), so one long label cannot\n// squeeze the plot away.\nconst CATEGORY_LABEL_MAX_WIDTH = 160;\nconst LABEL_ELLIPSIS = '…';\n// The font the theme draws axis labels in, as a canvas font string. Labels are\n// measured in it the way ECharts measures them for containLabel, so a\n// horizontal chart's title lands exactly beyond the widest label.\nconst AXIS_LABEL_FONT = `${REPORT_AXIS_LABEL_FONT_SIZE}px ${REPORT_CHART_FONT_FAMILY}`;\n// The letter a quarter label starts with, by language subtag. French writes the\n// second quarter 'T2' (trimestre); every other language reads 'Q2'.\nconst QUARTER_PREFIXES = new Map<string, string>([['fr', 'T']]);\nconst QUARTER_PREFIX = 'Q';\n// A 100% stacked chart's value axis: whole percentages, a gridline every 25%,\n// up to 100%. Its tooltip gives each share to one decimal.\nconst PERCENT_AXIS_FORMAT: NumberFormatSpec = { format: ReportValueFormat.Percent, precision: 0 };\nconst PERCENT_SHARE_FORMAT: NumberFormatSpec = { format: ReportValueFormat.Percent, precision: 1 };\nexport const PERCENT_AXIS_MAX = 1;\nexport const PERCENT_AXIS_INTERVAL = 0.25;\n// A reference band's fill: the reference slate, faint enough that the series\n// drawn across it stay readable.\nconst REFERENCE_BAND_FILL = 'rgba(82, 96, 109, 0.08)';\n// A reference's or statistic line's label sits on a light box, so it stays\n// readable where it crosses a bar or a line.\nconst MARK_LABEL_BOX = { backgroundColor: 'rgba(255, 255, 255, 0.85)', padding: [1, 3], borderRadius: 2 };\n// The room an axis stretched to a reference leaves above it, for its label:\n// the bound is the round number at or past the reference plus this share.\nconst REFERENCE_HEADROOM = 1.05;\n\n// The words a statistic line's label starts with. They are interface text,\n// English in every report locale; only the value after them follows it.\nexport const STAT_LABEL: Record<ReportChartMarkStat, string> = {\n [ReportChartMarkStat.Average]: 'Average',\n [ReportChartMarkStat.Median]: 'Median',\n [ReportChartMarkStat.Min]: 'Minimum',\n [ReportChartMarkStat.Max]: 'Maximum',\n};\n\n// Which edge of the plot an axis title sits on. The category axis's is below a\n// vertical chart and to the left of a horizontal one; the value axis's is above\n// a vertical chart and below a horizontal one.\ntype AxisTitleSide = 'top' | 'bottom' | 'left';\n\n// Which value axis a series is plotted against: 0 the primary, 1 the second\n// axis on the right.\nexport type ValueAxisIndex = 0 | 1;\n\n// What valueAxisOption adds for one axis. `index` is the axis of a two-axis\n// chart it builds: the second one's title is aligned to read leftward from the\n// right edge. `percentMin` makes it a 100% stacked chart's share axis, from\n// that bound (0, or -1 when a share is negative) up to 100%, whatever range\n// the config pins. `reach` is the span of the references plotted against it,\n// which the axis stretches to when the data falls short of them.\ninterface ValueAxisExtras {\n index?: ValueAxisIndex;\n percentMin?: number;\n reach?: ReferenceReach;\n}\n\n// A reference as the chart draws it: its lower and upper edge (the same value\n// for a line), whether it is a band, and the value axis it is plotted against.\n// Shared with the PowerPoint export, which draws each edge as a constant line.\nexport interface DrawnReference {\n label: string;\n low: number;\n high: number;\n band: boolean;\n axisIndex: ValueAxisIndex;\n}\n\n// The lowest and highest edge of the references on one value axis.\ninterface ReferenceReach {\n low: number;\n high: number;\n}\n\n// What ECharts hands a value axis's min and max callbacks: the extent of the\n// data plotted against it.\ninterface AxisExtent {\n min: number;\n max: number;\n}\n\n// One point of a 100% stacked series: its share of the category's total,\n// which ECharts plots and stacks, and the value it came from.\ninterface ShareDataItem {\n value: number | null;\n raw: number | null;\n}\n\n// A point that prints its own data label: a 'last' series' latest point,\n// keeping the raw value a 100% stacked point carries.\ninterface LabeledDataItem<P extends DataLabelPosition> {\n value: number | null;\n raw?: number | null;\n label: DataLabel<P>;\n}\n\ntype SeriesDataItem<P extends DataLabelPosition> = number | null | ShareDataItem | LabeledDataItem<P>;\n\n// What a data label's formatter is handed: the point's plotted value and its\n// data item as given (a number, or an object carrying the raw value).\ninterface DataLabelParams {\n value?: unknown;\n data?: unknown;\n}\n\nexport type DataLabelFormatter = (params: DataLabelParams) => string;\n\n// Where a data label sits: 'outside' past an unstacked bar's end, on the side\n// its sign points to; 'inside' a stacked bar; 'top' above a line or area\n// point. ECharts takes 'outside' on a bar only.\nexport type DataLabelPosition = 'top' | 'inside' | 'outside';\n\n// One ECharts label, as a series or a single point prints it.\nexport interface DataLabel<P extends DataLabelPosition = DataLabelPosition> {\n show: true;\n position: P;\n fontSize: number;\n formatter: DataLabelFormatter;\n}\n\n// A series' data labels as dataLabelOption decides them, before buildSeries\n// places them by what the series draws: the label's text and size, whether\n// labels that would overlap are hidden ('auto'), and whether only the latest\n// point prints one ('last').\nexport interface SeriesDataLabels {\n text: Omit<DataLabel, 'position'>;\n hideOverlap: boolean;\n lastOnly: boolean;\n}\n\n// A series' data labels placed: `series` is spread over the series (its\n// label, and for 'auto' the overlap hiding), and `data` is its points, the\n// latest non-empty one carrying the label for 'last'.\ninterface PlacedDataLabels<P extends DataLabelPosition> {\n series: { label?: DataLabel<P>; labelLayout?: { hideOverlap: boolean } };\n data: SeriesDataItem<P>[];\n}\n\n// A value axis's number format, decided once for the axis: the format the\n// measures plotted against it agree on (axisNumberFormat), with the units and\n// decimals its peak calls for. null is a plain axis. Its ticks and its series'\n// data labels both write in it.\ninterface ValueAxisFormat {\n spec: NumberFormatSpec;\n chart: ChartNumberFormat;\n}\n\n// The shares a 100% stacked chart draws, by the index of the extracted series\n// they replace.\nexport type PercentShares = Map<number, (number | null)[]>;\n\n// The plot's distance from each edge of the chart, in pixels.\ninterface AxisGridRoom {\n left: number;\n right: number;\n top: number;\n bottom: number;\n containLabel: boolean;\n}\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).\n//\n// It is the DEFAULT for a categorical bar chart rather than something the config\n// has to ask for. A bar chart whose x-axis is a category — regions, statuses,\n// stores — is comparing those categories to each other, and one flat color with\n// no legend is the wrong reading of it in essentially every case. Requiring\n// colorBy to opt in meant every such chart rendered monochrome unless whoever\n// wrote the config remembered an optional property, which is a default set the\n// wrong way round: the common case should not need the flag.\n//\n// A TIME axis is excluded: consecutive periods are one series moving, not\n// categories being compared, and coloring each month differently reads as\n// unrelated groups. Explicitly opting out — colorBy: {column: ''}, a color on\n// the measure or a config.legend of 'hidden' — still wins, so a caller that\n// wants one flat color can say so.\n//\n// \"Bar chart\" is the type the lone measure is actually DRAWN as: its own type\n// when it names one, which can turn a line chart's single series into bars or\n// a bar chart's into a line.\nexport function isColorBy(config: ChartConfig): boolean {\n if (config.splitBy?.column || (config.measures?.[0]?.type ?? config.chartType ?? 'bar') !== 'bar') {\n return false;\n }\n\n if (config.colorBy) {\n return !!config.colorBy.column;\n }\n\n // A measure given its own color asks for one flat color.\n if (measureColorHex(config.measures?.[0])) {\n return false;\n }\n\n return (config.xAxis?.kind ?? 'category') === 'category'\n && !config.xAxis?.granularity\n && (config.measures?.length ?? 1) <= 1;\n}\n\n\n// The column colorBy groups by — its own when the config named one, otherwise\n// the x-axis it defaults to coloring.\nexport function colorByColumn(config: ChartConfig): string | undefined {\n return isColorBy(config)\n ? (config.colorBy?.column || config.xAxis?.column)\n : undefined;\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.\n//\n// A series' `type` is the type its measure asks to be drawn as, and is absent\n// when the measure leaves it to the chart's chartType (see seriesTypes). Its\n// `measure` is the one it plots, whose number format its tooltip uses and\n// whose display keys (color, axis) it follows, and `measureIndex` that\n// measure's position: the first measure, 0, for every series of a splitBy or\n// colorBy chart.\nexport interface ExtractedChartSeries {\n categories: string[];\n series: ExtractedChartSeriesItem[];\n}\n\nexport interface ExtractedChartSeriesItem {\n name: string;\n values: (number | null)[];\n type?: AxisChartType;\n measure: ChartMeasure;\n measureIndex: number;\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 || colorByColumn(config);\n const measures = chartMeasures(config, data);\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 type: measure.type,\n measure,\n measureIndex: 0,\n });\n }\n } else {\n for (const [measureIndex, measure] of measures.entries()) {\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 type: measure.type,\n measure,\n measureIndex,\n });\n }\n }\n\n return { categories, series };\n}\n\n// A series' own color as CSS hex: its measure's named color, or undefined when\n// it names none (or a name the palette does not know) and the theme colors it\n// by its position.\nexport function seriesColor(series: ExtractedChartSeriesItem): string | undefined {\n const hex = namedColorHex(series);\n\n return hex ? `#${hex}` : undefined;\n}\n\n// A series' color as the bare hex PowerPoint takes: its measure's named color,\n// else the palette color of its position, as the screen's theme picks it.\nexport function seriesHex(series: ExtractedChartSeriesItem, index: number): string {\n return namedColorHex(series) ?? REPORT_CHART_COLORS[index % REPORT_CHART_COLORS.length];\n}\n\nfunction namedColorHex(series: ExtractedChartSeriesItem): string | undefined {\n return measureColorHex(series.measure);\n}\n\n// A measure's named color as bare hex, or undefined when it names none or a\n// name the palette does not know. The name is read through the enum, so a\n// stored name such as '__proto__' never reaches the lookup object.\nfunction measureColorHex(measure: ChartMeasure | undefined): string | undefined {\n const color = Object.values(ReportChartColor).find((name) => name === measure?.color);\n\n return color ? REPORT_CHART_COLOR_BY_NAME[color] : undefined;\n}\n\n// A measure's line style when it names one ECharts knows, else undefined and\n// the line is solid.\nexport function measureLineStyle(measure: ChartMeasure | undefined): ReportChartLineStyle | undefined {\n return Object.values(ReportChartLineStyle).find((style) => style === measure?.line);\n}\n\n// A measure's statistic line when it names one the viewer knows, else\n// undefined and it draws none.\nexport function measureMarkStat(measure: ChartMeasure | undefined): ReportChartMarkStat | undefined {\n return Object.values(ReportChartMarkStat).find((stat) => stat === measure?.markLine);\n}\n\n// A series' statistic over its points that have a value: their mean, their\n// median (the mean of the two middle values when the count is even), the\n// lowest or the highest. null when no point has a value. Shared with the\n// PowerPoint export so both media draw the line at the same height.\nexport function seriesStat(values: (number | null)[], stat: ReportChartMarkStat): number | null {\n const present = values.filter((value): value is number => typeof value === 'number' && Number.isFinite(value));\n\n if (!present.length) {\n return null;\n }\n\n switch (stat) {\n case ReportChartMarkStat.Average:\n return present.reduce((sum, value) => sum + value, 0) / present.length;\n case ReportChartMarkStat.Median: {\n const sorted = [...present].sort((a, b) => a - b);\n const middle = Math.floor(sorted.length / 2);\n\n return sorted.length % 2 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;\n }\n case ReportChartMarkStat.Min:\n return Math.min(...present);\n case ReportChartMarkStat.Max:\n return Math.max(...present);\n default:\n return null;\n }\n}\n\n// Whether a chart draws statistic lines. A horizontal chart's values run\n// along x, and PowerPoint cannot draw a line beside horizontal bars, so\n// neither medium draws one there.\nexport function drawsStatLines(config: ChartConfig): boolean {\n return config.orientation !== 'horizontal';\n}\n\n// A colorBy chart's one value per category: series i holds category i's bar.\n// PowerPoint draws these as its one series, and a statistic line is taken\n// over them.\nexport function colorByValues(extracted: ExtractedChartSeries): (number | null)[] {\n return extracted.categories.map((_, index) => extracted.series[index]?.values[index] ?? null);\n}\n\n// The references a chart draws. A vertical axis chart and a waterfall draw\n// them; a pie has no value axis, and a horizontal chart is left without them\n// as PowerPoint cannot draw a line beside horizontal bars. An entry without a\n// finite value is skipped, and one whose `to` is missing or equal to its value\n// is a line. secondary reaches the second value axis only on a chart that has\n// one (twoAxes). Shared with the PowerPoint export.\nexport function chartReferences(config: ChartConfig, twoAxes: boolean): DrawnReference[] {\n const chartType = config.chartType ?? 'bar';\n const references: (ChartReference | null | undefined)[] = Array.isArray(config.references) ? config.references : [];\n\n if (config.orientation === 'horizontal' || chartType === 'pie' || chartType === 'donut') {\n return [];\n }\n\n return references.flatMap((reference): DrawnReference[] => {\n const value = axisNumber(reference?.value);\n\n if (!reference || value === undefined) {\n return [];\n }\n\n const to = axisNumber(reference.to);\n const label = typeof reference.label === 'string' ? reference.label : '';\n const axisIndex: ValueAxisIndex = twoAxes && reference.secondary === true ? 1 : 0;\n\n return [to !== undefined && to !== value\n ? { label, low: Math.min(value, to), high: Math.max(value, to), band: true, axisIndex }\n : { label, low: value, high: value, band: false, axisIndex }];\n });\n}\n\n// Each series as its share of its category's total: per category, the\n// denominator is the sum of every series' absolute value there, so the\n// magnitudes of a category's shares add up to 1. A mixed-sign category's\n// negative values take negative shares, drawn below zero. A missing value\n// stays missing, and a category whose total is zero has no shares. Shared by\n// the screen, the PDF and PowerPoint, so a 100% stack reads the same in each.\nexport function percentShares(values: (number | null)[][]): (number | null)[][] {\n const length = Math.max(0, ...values.map((series) => series.length));\n const totals = Array.from({ length }, (_, index) => values\n .reduce((sum, series) => sum + Math.abs(series[index] ?? 0), 0));\n\n return values.map((series) => series.map((value, index) => (\n value === null || !totals[index] ? null : value / totals[index]\n )));\n}\n\n// The shares a 100% stacked chart draws in place of its values, or null when\n// the chart is not one. The primary axis's bar and area series take them,\n// each type's series sharing among themselves, as each type stacks apart.\n// Lines and secondary-axis series keep their values. A pie, a waterfall and a\n// colorBy chart (one series per category, each of which would be 100%) are\n// never 100% stacked, nor is a chart with no bar or area on its primary axis.\nexport function percentStackedShares(extracted: ExtractedChartSeries, config: ChartConfig): PercentShares | null {\n const chartType = config.chartType ?? 'bar';\n\n if (config.percentStacked !== true\n || chartType === 'pie' || chartType === 'donut' || chartType === 'waterfall'\n || isColorBy(config)) {\n return null;\n }\n\n const types = seriesTypes(extracted, chartType);\n const axisIndexes = seriesAxisIndexes(extracted, config);\n const shares: PercentShares = new Map();\n\n for (const type of ['bar', 'area'] as const) {\n const indexes = types\n .map((seriesType, index) => (seriesType === type && axisIndexes[index] === 0 ? index : -1))\n .filter((index) => index >= 0);\n const typeShares = percentShares(indexes.map((index) => extracted.series[index].values));\n indexes.forEach((seriesIndex, position) => shares.set(seriesIndex, typeShares[position]));\n }\n\n return shares.size ? shares : null;\n}\n\n// Where a 100% stacked chart's value axis starts: at -100% when any share is\n// negative, else at zero.\nexport function percentAxisMin(shares: PercentShares): number {\n return [...shares.values()].some((series) => series.some((share) => (share ?? 0) < 0)) ? -1 : 0;\n}\n\n// The measures a chart plots: its configured ones, else the query's last\n// column, unformatted.\nfunction chartMeasures(config: ChartConfig, data: ComponentData): ChartMeasure[] {\n return config.measures?.length\n ? config.measures\n : [{ column: data.columns[data.columns.length - 1] }];\n}\n\n// The type each extracted series is drawn as: its measure's own type when it\n// names one, the chart's chartType otherwise. More than one distinct type is a\n// combo chart. Shared with the PowerPoint export so both media draw each series\n// the same way.\nexport function seriesTypes(extracted: ExtractedChartSeries, chartType: AxisChartType): AxisChartType[] {\n return extracted.series.map((series) => series.type ?? chartType);\n}\n\n// The value axis each extracted series is plotted against: 1 when its measure\n// is secondary, 0 otherwise. A second axis is drawn only on a vertical chart\n// that keeps at least one series on the primary axis, so a combination the\n// server refuses (a horizontal chart, every measure secondary, the one measure\n// of a splitBy or colorBy chart) plots everything on the primary axis. Shared\n// with the PowerPoint export so both media put each series on the same axis.\nexport function seriesAxisIndexes(extracted: ExtractedChartSeries, config: ChartConfig): ValueAxisIndex[] {\n const secondary = extracted.series.map((series) => !!series.measure.secondary);\n const twoAxes = config.orientation !== 'horizontal' && secondary.includes(true) && secondary.includes(false);\n\n return secondary.map((isSecondary) => (twoAxes && isSecondary ? 1 : 0));\n}\n\n// One bar of a waterfall. `start` is the running total before it, where the bar\n// starts, and `change` its signed height, so it ends at start + change. The\n// closing total starts at zero and its change is the whole running total.\nexport interface WaterfallStep {\n category: string;\n start: number;\n change: number | null;\n kind: WaterfallStepKind;\n}\n\nexport interface ExtractedWaterfall {\n name: string;\n steps: WaterfallStep[];\n}\n\nexport const WATERFALL_TOTAL_LABEL = 'Total';\n\n// A waterfall's bars from its one measure: each category's value is how far the\n// running total moves there, and a last Total bar shows where it ended. A\n// category with no value moves nothing and draws no bar. Shared with the\n// PowerPoint export so both media draw the same steps.\nexport function extractWaterfall(component: ReportComponent, data: ComponentData): ExtractedWaterfall {\n const extracted = extractChartSeries(component, data);\n const values = extracted.series[0]?.values ?? [];\n const steps: WaterfallStep[] = [];\n let total = 0;\n\n extracted.categories.forEach((category, index) => {\n const change = values[index] ?? null;\n steps.push({ category, start: total, change, kind: (change ?? 0) < 0 ? 'fall' : 'rise' });\n total += change ?? 0;\n });\n\n steps.push({ category: WATERFALL_TOTAL_LABEL, start: 0, change: total, kind: 'total' });\n\n return { name: extracted.series[0]?.name ?? '', steps };\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.\n//\n// Every number and period the chart writes (value-axis ticks, tooltip values,\n// period labels) is in the context's locale, never the browser's. A measure\n// with number-format keys formats its tooltips, and the value axis when every\n// measure on it agrees (axisNumberFormat); without them the axis and tooltips\n// keep the plain locale-grouped number.\nexport function buildChartOption(\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n): 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', context);\n }\n\n if (chartType === 'waterfall') {\n return buildWaterfallOption(component, data, context);\n }\n\n return buildAxisOption(component, data, chartType, context);\n}\n\nfunction buildAxisOption(\n component: ReportComponent,\n data: ComponentData,\n chartType: AxisChartType,\n context: ReportFormatContext,\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 const types = seriesTypes(extracted, chartType);\n const combo = new Set(types).size > 1;\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 //\n // Stacking sums every series that shares a stack name, whatever its type. In\n // a combo each type stacks only with its own kind, so a line of a rate never\n // sits on top of the bars' total, and on a two-axis chart only with the\n // series on its own axis.\n //\n // A 100% stacked chart (percentStackedShares) plots its primary bars and\n // areas as shares, each type in its own stack, and leaves every other series\n // unstacked on its own values.\n const axisIndexes = seriesAxisIndexes(extracted, config);\n const twoAxes = axisIndexes.includes(1);\n const shares = percentStackedShares(extracted, config);\n const references = chartReferences(config, twoAxes);\n const axisFormats = valueAxisFormats(config, extracted, axisIndexes, context, !!shares, references);\n // A series' statistic line is taken over the points it plots. On a colorBy\n // chart each series holds one bar, so the one line is taken over the bars\n // together and hangs off the first series (colorByStatLine).\n const statLines = drawsStatLines(config) && !colorBy;\n const series: SeriesOption[] = extracted.series.map((extractedSeries, index) => {\n const seriesShares = shares?.get(index);\n let stack: string | undefined;\n if (seriesShares) {\n stack = stackKey(types[index], combo, 0);\n } else if (config.stacked && !shares) {\n stack = stackKey(types[index], combo, twoAxes ? axisIndexes[index] : undefined);\n }\n\n const stat = statLines ? measureMarkStat(extractedSeries.measure) : undefined;\n const markLine = stat && statMarkLine(\n seriesShares ?? extractedSeries.values,\n stat,\n seriesShares ? shareWriter(context) : measureWriter(extractedSeries.measure, context),\n );\n const option = buildSeries(\n extractedSeries,\n seriesShares ? shareData(extractedSeries.values, seriesShares) : extractedSeries.values,\n {\n type: types[index],\n stack,\n overlap: colorBy && index === 0,\n combo,\n tooltip: seriesTooltip(extractedSeries.measure, context),\n axisIndex: twoAxes ? axisIndexes[index] : undefined,\n // A colorBy chart's bars take the palette by category, as in\n // PowerPoint, whatever color the measure names.\n color: colorBy ? undefined : seriesColor(extractedSeries),\n labels: dataLabelOption(config.dataLabels, dataLabelFormatter(\n extractedSeries.measure,\n axisFormats[axisIndexes[index]] ?? null,\n !!seriesShares,\n context,\n )),\n },\n );\n\n return markLine ? { ...option, markLine } as SeriesOption : option;\n });\n\n if (colorBy && drawsStatLines(config) && series.length) {\n series[0] = colorByStatLine(series[0], extracted, context);\n }\n\n const percentMin = shares ? percentAxisMin(shares) : undefined;\n const categoryAxis = categoryAxisOption(config, data, extracted.categories, horizontal, context.locale);\n const valueAxis = twoAxes\n ? twoValueAxesOption(config, axisFormats, context, percentMin, references)\n : valueAxisOption(config.valueAxis, horizontal, percentMin === undefined\n ? valueAxisLabel(axisFormats[0], context)\n : percentAxisLabel(context), { percentMin, reach: referenceReach(references, 0) });\n\n const legendPosition = resolveLegendPosition(config, series.length, colorBy);\n const valueTitles = [config.valueAxis, twoAxes ? config.secondaryAxis : undefined];\n const granularity = bucketGranularity(data);\n\n return {\n grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal), valueTitleSide(valueTitles, horizontal)),\n legend: referenceLegend(legendOption(legendPosition), series, references),\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. A 100%\n // stacked chart's tooltip gives each share and the value it came from.\n tooltip: shares\n ? {\n trigger: 'axis',\n formatter: (params: TooltipComponentFormatterCallbackParams) => percentTooltip(\n params,\n extracted,\n shares,\n granularity,\n chartDateLabel(config),\n context,\n ),\n }\n : { trigger: colorBy ? 'item' : 'axis' },\n xAxis: horizontal ? valueAxis : categoryAxis,\n yAxis: horizontal ? categoryAxis : valueAxis,\n series: [...series, ...referenceCarriers(references, extracted.categories)],\n };\n}\n\n// A colorBy chart's statistic line: one line over every bar, hung off the\n// first series and drawn in the reference slate, as no one category's color\n// speaks for the others.\nfunction colorByStatLine(\n first: SeriesOption,\n extracted: ExtractedChartSeries,\n context: ReportFormatContext,\n): SeriesOption {\n const measure = extracted.series[0]?.measure;\n const stat = measureMarkStat(measure);\n const markLine = stat && statMarkLine(\n colorByValues(extracted),\n stat,\n measureWriter(measure, context),\n `#${REPORT_REFERENCE_COLOR}`,\n );\n\n return markLine ? { ...first, markLine } as SeriesOption : first;\n}\n\n// A series' statistic line across the plot, labeled with the statistic and\n// its value ('Average: 1,234.5'), or undefined when no point has a value. It\n// takes the series' color unless it is given one.\nfunction statMarkLine(\n values: (number | null)[],\n stat: ReportChartMarkStat,\n write: (value: number) => string,\n color?: string,\n) {\n const value = seriesStat(values, stat);\n\n if (value === null) {\n return undefined;\n }\n\n const text = `${STAT_LABEL[stat]}: ${write(value)}`;\n\n return {\n silent: true,\n symbol: 'none',\n lineStyle: { type: 'dashed' as const, width: 1, ...(color ? { color } : {}) },\n label: { formatter: () => text, position: 'insideEndTop' as const, fontSize: REPORT_DATA_LABEL_FONT_SIZE, ...MARK_LABEL_BOX },\n data: [{ yAxis: value }],\n };\n}\n\n// A statistic's value in its measure's number format, in the report locale.\nfunction measureWriter(measure: ChartMeasure | undefined, context: ReportFormatContext): (value: number) => string {\n return (value) => formatNumber(value, measure, context);\n}\n\n// A 100% stacked series' statistic is a share, written as its tooltip writes\n// one.\nfunction shareWriter(context: ReportFormatContext): (value: number) => string {\n const ratioContext = { ...context, ratioPercent: true };\n\n return (value) => formatNumber(value, PERCENT_SHARE_FORMAT, ratioContext);\n}\n\n// The series that carry a chart's references, one per value axis that has\n// any: an empty line (every point null, so it draws nothing and stretches no\n// axis) whose markLine draws the reference lines and whose markArea fills the\n// bands. It is silent, left out of the tooltip and, by referenceLegend, out of\n// the legend. It has no name, so no measure series' legend entry (whatever its\n// name, '' included) toggles it.\n//\n// Labels are functions, as a string formatter is a template that would read\n// '{b}' or '{c}' in a label as a placeholder. ECharts draws a markArea under\n// the bars and a markLine over them, so a band's label rides an invisible\n// markLine on its upper edge, inside its top left corner, where the first bar\n// would otherwise cover it.\nfunction referenceCarriers(references: DrawnReference[], categories: string[]): SeriesOption[] {\n const color = `#${REPORT_REFERENCE_COLOR}`;\n\n return ([0, 1] as const).flatMap((axisIndex): SeriesOption[] => {\n const onAxis = references.filter((reference) => reference.axisIndex === axisIndex);\n const lines = onAxis.filter((reference) => !reference.band);\n const bands = onAxis.filter((reference) => reference.band);\n\n if (!onAxis.length) {\n return [];\n }\n\n return [{\n type: 'line',\n data: categories.map(() => null),\n yAxisIndex: axisIndex,\n silent: true,\n tooltip: { show: false },\n markLine: {\n silent: true,\n symbol: 'none',\n lineStyle: { color, type: 'dashed', width: 1 },\n label: { position: 'insideEndTop', color, fontSize: REPORT_DATA_LABEL_FONT_SIZE, ...MARK_LABEL_BOX },\n data: [\n ...lines.map((reference) => ({ yAxis: reference.low, label: { formatter: () => reference.label } })),\n ...bands.map((reference) => ({\n yAxis: reference.high,\n // Zero width, not zero opacity: a markLine's label takes the\n // line's opacity.\n lineStyle: { width: 0 },\n label: { position: 'insideStartBottom', formatter: () => reference.label },\n })),\n ],\n },\n ...(bands.length ? {\n markArea: {\n silent: true,\n itemStyle: { color: REFERENCE_BAND_FILL },\n data: bands.map((reference) => [{ yAxis: reference.low }, { yAxis: reference.high }]),\n },\n } : {}),\n } as SeriesOption];\n });\n}\n\n// The largest magnitude a value axis's references reach, which its number\n// format counts toward its peak, as the axis stretches to them; 0 when it\n// has none.\nexport function referencePeak(references: DrawnReference[], axisIndex: ValueAxisIndex): number {\n const reach = referenceReach(references, axisIndex);\n\n return reach ? Math.max(Math.abs(reach.low), Math.abs(reach.high)) : 0;\n}\n\n// The legend of a chart with references names its measure series alone, so\n// a carrier never shows as a blank entry. Without references it is left as it\n// was.\nfunction referenceLegend(\n legend: LegendComponentOption,\n series: SeriesOption[],\n references: DrawnReference[],\n): LegendComponentOption {\n return references.length\n ? { ...legend, data: series.map((item) => String(item.name ?? '')) }\n : legend;\n}\n\n// The span of the references on one value axis, or undefined when it has\n// none.\nfunction referenceReach(references: DrawnReference[], axisIndex: ValueAxisIndex): ReferenceReach | undefined {\n const onAxis = references.filter((reference) => reference.axisIndex === axisIndex);\n\n return onAxis.length\n ? { low: Math.min(...onAxis.map((reference) => reference.low)), high: Math.max(...onAxis.map((reference) => reference.high)) }\n : undefined;\n}\n\n// ECharts leaves a markLine or markArea out of an axis's extent, so a\n// reference beyond the data would fall off the plot. An axis bound the config\n// does not pin reaches past the furthest reference, to a round number with\n// room for its label (beyondReference), when the data (and the zero a value\n// axis always shows) falls short of it, and is left to ECharts otherwise: a\n// callback returning undefined keeps the bound automatic. Past the data and\n// zero, a reference beyond the max is above zero and one beyond the min below\n// it.\nfunction reachMin(reach: ReferenceReach | undefined) {\n return reach\n ? (extent: AxisExtent) => (reach.low < Math.min(extent.min, 0) ? -beyondReference(-reach.low) : undefined)\n : undefined;\n}\n\nfunction reachMax(reach: ReferenceReach | undefined) {\n return reach\n ? (extent: AxisExtent) => (reach.high > Math.max(extent.max, 0) ? beyondReference(reach.high) : undefined)\n : undefined;\n}\n\n// The bound an axis takes past a reference of this (positive) magnitude: the\n// smallest round number at or above it plus REFERENCE_HEADROOM. The steps are\n// finer than ECharts' tick steps, so a reference just past the data does not\n// double the axis (110 gives 120, not 200). The tolerance keeps a float error\n// from skipping a round number the value already is.\nconst NICE_STEPS = [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10];\nconst NICE_TOLERANCE = 1e-9;\n\nfunction beyondReference(magnitude: number): number {\n const target = magnitude * REFERENCE_HEADROOM;\n const power = Math.pow(10, Math.floor(Math.log10(target)));\n const step = NICE_STEPS.find((candidate) => candidate * power >= target * (1 - NICE_TOLERANCE)) ?? 10;\n\n // Rounded back to the power's own digits, so 1.2 x 0.1 reads 0.12, not\n // 0.12000000000000001.\n return Number((step * power).toPrecision(12));\n}\n\n// The category axis of an axis chart or a waterfall: the categories in row\n// order, labeled as periods when the rows were bucketed by time.\n//\n// Horizontal bars read top-down: ECharts draws category 0 at the bottom, so the\n// axis is inverted to put the first row (the largest of a top-N, a waterfall's\n// first step) at the top. The rotated title sits just beyond the longest label\n// rather than at a fixed gap that would put it on top of the labels.\n//\n// A bucketed axis also names its period in the axis tooltip's header: ECharts\n// heads it with the raw category ('2026-01-01') unless the axis pointer's label\n// has a formatter, so it reads 'January 2026' instead, always with its year.\n// The axis's dateLabel style writes both its tick labels and that header.\nfunction categoryAxisOption(\n config: ChartConfig,\n data: ComponentData,\n categories: string[],\n horizontal: boolean,\n locale: ReportLocaleTag,\n) {\n const granularity = bucketGranularity(data);\n const dateLabel = chartDateLabel(config);\n const periodLabel = periodAxisLabel(granularity, categories, locale, dateLabel);\n const axis = {\n type: 'category' as const,\n data: categories,\n inverse: horizontal,\n name: config.xAxis?.label,\n nameLocation: 'middle' as const,\n ...(granularity ? {\n axisPointer: {\n label: {\n formatter: (params: { value: unknown }) => formatPeriodLabel(\n String(params.value),\n granularity,\n true,\n locale,\n dateLabel,\n ),\n },\n },\n } : {}),\n };\n\n if (!horizontal) {\n // The gap clears the year's second line when the labels print one.\n const secondLine = granularity && dateLabel === ReportChartDateLabel.Short && spansMultipleYears(categories);\n\n return {\n ...axis,\n nameGap: secondLine ? 40 : 28,\n ...periodLabel,\n };\n }\n\n // Period labels, short, long or numeric ('May', 'Q2', 'May 2026'), are\n // bounded in length and never cut; only a plain category is truncated. The labels are cut here rather than by ECharts' own\n // truncation, so the title's gap is measured on exactly the text the axis\n // draws.\n const shown = granularity\n ? null\n : new Map(categories.map((category) => [category, truncateAxisLabel(category)]));\n const labels = shown ? [...shown.values()] : displayedCategoryLabels(categories, granularity, locale, dateLabel);\n\n return {\n ...axis,\n nameGap: widestAxisLabel(labels) + AXIS_LABEL_MARGIN + AXIS_NAME_CLEARANCE,\n ...(shown ? { axisLabel: { formatter: (value: string) => shown.get(value) ?? value } } : periodLabel),\n };\n}\n\n// The category axis's title side, or null when the axis has no title to make\n// room for.\nfunction categoryTitleSide(config: ChartConfig, horizontal: boolean): AxisTitleSide | null {\n if (!config.xAxis?.label) {\n return null;\n }\n\n return horizontal ? 'left' : 'bottom';\n}\n\n// The value axes' title side, or null when none of them has a title. A\n// vertical chart's titles sit above the plot, at the top of each axis line, so\n// room is made once for both; a horizontal chart's sits below.\nfunction valueTitleSide(axes: (ChartValueAxis | undefined)[], horizontal: boolean): AxisTitleSide | null {\n if (!axes.some((axis) => axis?.label)) {\n return null;\n }\n\n return horizontal ? 'bottom' : 'top';\n}\n\n// The tick labels as the axis shows them: a bucket's primary period label\n// ('May', 'Q2', 'May 2026'), otherwise the category itself. The year a\n// multi-year axis prints under a short period is left out, as it is never the\n// wider line.\nfunction displayedCategoryLabels(\n categories: string[],\n granularity: ChartGranularity | null,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel,\n): string[] {\n return granularity\n ? categories.map((category) => periodLabelParts(category, granularity, locale, dateLabel)?.primary ?? category)\n : categories;\n}\n\n// The pixel width of the widest label. A label that breaks over several lines\n// is as wide as its longest line.\nfunction widestAxisLabel(labels: string[]): number {\n return labels.reduce((widest, label) => label.split('\\n').reduce(\n (lineWidest, line) => Math.max(lineWidest, axisLabelWidth(line)),\n widest,\n ), 0);\n}\n\n// A category label cut to CATEGORY_LABEL_MAX_WIDTH, line by line: the longest\n// start of each line that still fits with the ellipsis after it.\nfunction truncateAxisLabel(label: string): string {\n return label.split('\\n').map((line) => {\n if (axisLabelWidth(line) <= CATEGORY_LABEL_MAX_WIDTH) {\n return line;\n }\n\n // Code points, so an emoji or other surrogate pair is never split.\n const characters = Array.from(line);\n const cut = (length: number) => `${characters.slice(0, length).join('').trimEnd()}${LABEL_ELLIPSIS}`;\n let fits = 0;\n let tooLong = characters.length;\n while (tooLong - fits > 1) {\n const length = Math.floor((fits + tooLong) / 2);\n if (axisLabelWidth(cut(length)) <= CATEGORY_LABEL_MAX_WIDTH) {\n fits = length;\n } else {\n tooLong = length;\n }\n }\n\n return cut(fits);\n }).join('\\n');\n}\n\n// One line's width in the axis-label font, measured on a canvas the way\n// ECharts measures it for containLabel. Outside a browser there is no canvas\n// to measure with, so the line counts as zero width.\nlet axisLabelContext: CanvasRenderingContext2D | null = null;\n\nfunction axisLabelWidth(line: string): number {\n if (!axisLabelContext && typeof document !== 'undefined') {\n axisLabelContext = document.createElement('canvas').getContext('2d');\n }\n\n if (!axisLabelContext) {\n return 0;\n }\n\n axisLabelContext.font = AXIS_LABEL_FONT;\n\n return axisLabelContext.measureText(line).width;\n}\n\nfunction buildWaterfallOption(\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n): EChartsOption {\n const config = component.config as ChartConfig;\n const waterfall = extractWaterfall(component, data);\n const horizontal = config.orientation === 'horizontal';\n const categories = waterfall.steps.map((step) => step.category);\n const categoryAxis = categoryAxisOption(config, data, categories, horizontal, context.locale);\n // The one measure's format writes the axis and the tooltip. The axis has to\n // reach the furthest point the running total gets to, on either side of\n // zero, or the furthest reference.\n const spec = config.measures?.[0];\n const references = chartReferences(config, false);\n const valueAxis = valueAxisOption(config.valueAxis, horizontal, valueAxisLabel(resolveValueAxisFormat(\n spec && hasNumberFormat(spec) ? spec : null,\n () => Math.max(referencePeak(references, 0), ...waterfall.steps.map((step) => Math.abs(step.start + (step.change ?? 0)))),\n context,\n ), context), { reach: referenceReach(references, 0) });\n // One visible series, so the legend is hidden unless the config pins it.\n const legendPosition = resolveLegendPosition(config, 1);\n const granularity = bucketGranularity(data);\n\n return {\n grid: axisGrid(\n legendPosition,\n categoryTitleSide(config, horizontal),\n valueTitleSide([config.valueAxis], horizontal),\n ),\n legend: { ...legendOption(legendPosition), data: [waterfall.name] },\n // Per bar: the invisible base is silent, so only a step answers the hover.\n tooltip: {\n trigger: 'item',\n formatter: (params: TooltipComponentFormatterCallbackParams) => waterfallTooltip(\n waterfall,\n (Array.isArray(params) ? params[0] : params).dataIndex,\n granularity,\n chartDateLabel(config),\n spec,\n context,\n ),\n },\n xAxis: horizontal ? valueAxis : categoryAxis,\n yAxis: horizontal ? categoryAxis : valueAxis,\n series: [...waterfallSeries(waterfall), ...referenceCarriers(references, categories)],\n };\n}\n\n// An invisible base series lifts each visible bar to where its step starts.\n// Both stack with the 'all' strategy, which adds signed values in series order,\n// so a fall draws DOWN from the total before it, even across zero. The default\n// same-sign stacking would hang a negative bar below the axis instead.\nfunction waterfallSeries(waterfall: ExtractedWaterfall): SeriesOption[] {\n return [\n {\n type: 'bar',\n stack: 'waterfall',\n stackStrategy: 'all',\n data: waterfall.steps.map((step) => step.start),\n barMaxWidth: 48,\n itemStyle: { color: 'transparent' },\n silent: true,\n },\n {\n name: waterfall.name,\n type: 'bar',\n stack: 'waterfall',\n stackStrategy: 'all',\n barMaxWidth: 48,\n // The series color is the rise color so a pinned legend shows it; each\n // bar is then colored by what it does to the total.\n itemStyle: { color: `#${REPORT_WATERFALL_COLORS.rise}` },\n data: waterfall.steps.map((step) => ({\n value: step.change,\n itemStyle: { color: `#${REPORT_WATERFALL_COLORS[step.kind]}` },\n })),\n },\n ];\n}\n\n// A step's tooltip: its period, how far it moved the running total and where\n// that left it. The closing Total shows the total alone. The category and the\n// measure name come from the data and the config, and ECharts sets the tooltip\n// as HTML, so both are escaped. Periods and amounts are written in the report's\n// locale, amounts in the measure's number format (a plain number without one);\n// the words ('Running total') stay English.\nfunction waterfallTooltip(\n waterfall: ExtractedWaterfall,\n index: number,\n granularity: ChartGranularity | null,\n dateLabel: ReportChartDateLabel,\n spec: NumberFormatSpec | undefined,\n context: ReportFormatContext,\n): string {\n const step = waterfall.steps[index];\n const category = escapeHtml(granularity\n ? formatPeriodLabel(step.category, granularity, true, context.locale, dateLabel)\n : step.category);\n const name = escapeHtml(waterfall.name);\n const amount = (value: number | null) => formatNumber(value, spec ?? {}, context);\n\n if (step.kind === 'total') {\n return `${category}<br/>${name}: ${amount(step.change)}`;\n }\n\n const sign = (step.change ?? 0) > 0 ? '+' : '';\n\n return `${category}<br/>${name}: ${sign}${amount(step.change)}`\n + `<br/>Running total: ${amount(step.start + (step.change ?? 0))}`;\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// The plot's grid: room on the legend's side so it never overlaps the\n// bars/lines, plus room for the category and value axes' titles on their\n// sides, which containLabel does not reserve (it covers the tick labels only).\nfunction axisGrid(\n position: LegendPosition,\n categoryTitle: AxisTitleSide | null,\n valueTitle: AxisTitleSide | null,\n): EChartsOption['grid'] {\n return [categoryTitle, valueTitle].reduce<AxisGridRoom>(\n (grid, side) => (side ? { ...grid, [side]: grid[side] + AXIS_NAME_ROOM } : grid),\n legendGrid(position),\n );\n}\n\n// Plot-edge room on whichever side the legend occupies; containLabel keeps the\n// tick labels inside what is left.\nfunction legendGrid(position: LegendPosition): AxisGridRoom {\n const base: AxisGridRoom = { 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\n// The stack a stacked series joins. On a two-axis chart (axisIndex set) each\n// type stacks per axis; otherwise a combo stacks per type and a single-type\n// chart stacks everything together.\nfunction stackKey(type: AxisChartType, combo: boolean, axisIndex: ValueAxisIndex | undefined): string {\n if (axisIndex !== undefined) {\n return `total-${type}-${axisIndex}`;\n }\n\n return combo ? `total-${type}` : 'total';\n}\n\n// How buildSeries draws one series: its drawn type, the stack it joins, whether\n// it lays the colorBy overlap, whether the chart is a combo, its tooltip, its\n// value axis on a two-axis chart, its own CSS color (undefined leaves it to\n// the theme's palette by position), and its data labels (null prints none).\ninterface SeriesLayout {\n type: AxisChartType;\n stack: string | undefined;\n overlap: boolean;\n combo: boolean;\n tooltip: SeriesTooltip;\n axisIndex: ValueAxisIndex | undefined;\n color: string | undefined;\n labels: SeriesDataLabels | null;\n}\n\n// One series of an axis chart. A measure's display keys only add what they\n// change, so a series that sets none is drawn by the theme as before: its own\n// color (the bar, the line, the area under it and its legend key all follow\n// itemStyle), its line style and its markers, shown on every point unless\n// markers is false. Data labels come last, on the series or on its latest\n// point.\nfunction buildSeries(\n series: ExtractedChartSeriesItem,\n values: (number | null | ShareDataItem)[],\n layout: SeriesLayout,\n): SeriesOption {\n // On a two-axis chart every series names its value axis.\n const axis = layout.axisIndex === undefined ? {} : { yAxisIndex: layout.axisIndex };\n const color = layout.color;\n const itemStyle = color ? { itemStyle: { color } } : {};\n\n if (layout.type === 'bar') {\n // 'outside' follows each bar's sign: past a positive bar's end and below\n // (or left of) a negative one's, where 'top' would sit at the zero line.\n const { series: labels, data } = placeDataLabels(layout.labels, layout.stack ? 'inside' : 'outside', values);\n\n return {\n name: series.name,\n type: 'bar',\n data,\n stack: layout.stack,\n tooltip: layout.tooltip,\n ...axis,\n ...itemStyle,\n barMaxWidth: 48,\n // colorBy: overlap the per-category series so each bar renders full-width.\n ...(layout.overlap ? { barGap: '-100%', barCategoryGap: '20%' } : {}),\n ...labels,\n };\n }\n\n const lineType = measureLineStyle(series.measure);\n const lineStyle = color || lineType\n ? { lineStyle: { ...(color ? { color } : {}), ...(lineType ? { type: lineType } : {}) } }\n : {};\n const { series: labels, data } = placeDataLabels(layout.labels, 'top', values);\n\n return {\n name: series.name,\n type: 'line',\n data,\n stack: layout.stack,\n tooltip: layout.tooltip,\n ...axis,\n ...itemStyle,\n ...lineStyle,\n ...(series.measure.markers === false ? { showSymbol: false } : {}),\n smooth: true,\n symbolSize: 6,\n areaStyle: layout.type === 'area' ? { opacity: 0.25 } : undefined,\n // In a combo the line is drawn over the bars whatever order the measures\n // come in; at the same z a later bar series would paint across it.\n ...(layout.combo ? { z: 3 } : {}),\n ...labels,\n };\n}\n\n// A 100% stacked series' points: each share, plotted and stacked, with the\n// value it came from.\nfunction shareData(values: (number | null)[], shares: (number | null)[]): ShareDataItem[] {\n return values.map((raw, index) => ({ value: shares[index] ?? null, raw }));\n}\n\n// What a series prints beside its points (A2 data labels): every point\n// ('all'), every point whose label fits without overlapping another ('auto',\n// LabelLayout's hideOverlap), or only its latest point ('last'). none, an\n// absent mode or one the viewer does not know prints nothing, and the series\n// is left as it was. A colorBy chart's series each hold one bar, so 'last'\n// labels every bar there, as 'all' does.\n//\n// Where the label sits depends on what the series draws, so buildSeries\n// places it (placeDataLabels).\nexport function dataLabelOption(\n mode: ReportChartDataLabels | undefined,\n formatter: DataLabelFormatter,\n): SeriesDataLabels | null {\n const text = { show: true as const, fontSize: REPORT_DATA_LABEL_FONT_SIZE, formatter };\n\n switch (mode) {\n case ReportChartDataLabels.All:\n return { text, hideOverlap: false, lastOnly: false };\n case ReportChartDataLabels.Auto:\n return { text, hideOverlap: true, lastOnly: false };\n case ReportChartDataLabels.Last:\n return { text, hideOverlap: false, lastOnly: true };\n default:\n return null;\n }\n}\n\n// A series' data labels at `position`: on the series ('all', and with the\n// overlap hiding 'auto'), or on its latest non-empty point alone ('last').\n// No labels leave the series and its points as they were.\nfunction placeDataLabels<P extends DataLabelPosition>(\n labels: SeriesDataLabels | null,\n position: P,\n values: (number | null | ShareDataItem)[],\n): PlacedDataLabels<P> {\n if (!labels) {\n return { series: {}, data: values };\n }\n\n const label: DataLabel<P> = { ...labels.text, position };\n\n if (labels.lastOnly) {\n return { series: {}, data: labelLastPoint(values, label) };\n }\n\n return {\n series: { label, ...(labels.hideOverlap ? { labelLayout: { hideOverlap: true } } : {}) },\n data: values,\n };\n}\n\n// A series' points with its latest non-empty point carrying the label. A\n// series with no value anywhere is left as it was.\nfunction labelLastPoint<P extends DataLabelPosition>(\n values: (number | null | ShareDataItem)[],\n label: DataLabel<P>,\n): SeriesDataItem<P>[] {\n const pointValue = (item: number | null | ShareDataItem) => (isShareDataItem(item) ? item.value : item);\n const last = values.reduce<number>((found, item, index) => (pointValue(item) === null ? found : index), -1);\n\n return values.map((item, index): SeriesDataItem<P> => {\n if (index !== last) {\n return item;\n }\n\n return isShareDataItem(item) ? { ...item, label } : { value: item, label };\n });\n}\n\nfunction isShareDataItem(item: number | null | ShareDataItem): item is ShareDataItem {\n return item !== null && typeof item === 'object';\n}\n\n// How a series' data labels write a value. A 100% stacked series prints its\n// share as a whole percentage, as the share axis's ticks do. A series on an\n// axis with a number format prints its value in its measure's format, at the\n// units and decimals the axis decided, so a label reads like the ticks beside\n// it. Any other prints the plain locale-grouped number its tooltip shows. A\n// share point's raw value is what a label reads when it carries one.\nfunction dataLabelFormatter(\n measure: ChartMeasure,\n axisFormat: ValueAxisFormat | null,\n share: boolean,\n context: ReportFormatContext,\n): DataLabelFormatter {\n if (share) {\n const percent = wholePercentFormatter(context);\n\n return (params) => percent(params.value);\n }\n\n if (axisFormat) {\n const options = { units: axisFormat.chart.units, decimals: axisFormat.chart.decimals };\n\n return (params) => formatNumber(dataLabelValue(params), measure, context, options);\n }\n\n return (params) => formatPlainNumber(dataLabelValue(params), context.locale);\n}\n\n// The value a data label writes: the raw value its point carries, else the\n// plotted one.\nfunction dataLabelValue(params: DataLabelParams): unknown {\n const data = params.data;\n const raw = data !== null && typeof data === 'object' ? (data as { raw?: unknown }).raw : undefined;\n\n return raw ?? params.value;\n}\n\n// A 100% stacked chart's tooltip: the category, then each series on its own\n// line, a share as its percentage to one decimal followed by the value it came\n// from in its measure's format ('25.0% (1)'), and any other series by its own\n// value. The category and the series names come from the data and the config,\n// and ECharts sets the tooltip as HTML, so both are escaped.\nfunction percentTooltip(\n params: TooltipComponentFormatterCallbackParams,\n extracted: ExtractedChartSeries,\n shares: PercentShares,\n granularity: ChartGranularity | null,\n dateLabel: ReportChartDateLabel,\n context: ReportFormatContext,\n): string {\n const items = Array.isArray(params) ? params : [params];\n const dataIndex = items[0]?.dataIndex ?? 0;\n const category = extracted.categories[dataIndex] ?? '';\n const heading = escapeHtml(granularity\n ? formatPeriodLabel(category, granularity, true, context.locale, dateLabel)\n : category);\n const ratioContext = { ...context, ratioPercent: true };\n\n const lines = items.map((item) => {\n const series = extracted.series[item.seriesIndex ?? -1];\n const marker = typeof item.marker === 'string' ? item.marker : '';\n const label = `${marker} ${escapeHtml(item.seriesName ?? series?.name ?? '')}`;\n const value = seriesTooltip(series?.measure, context).valueFormatter(series?.values[item.dataIndex] ?? null);\n const share = shares.get(item.seriesIndex ?? -1)?.[item.dataIndex] ?? null;\n\n return share === null\n ? `${label}: ${value}`\n : `${label}: ${formatNumber(share, PERCENT_SHARE_FORMAT, ratioContext)} (${value})`;\n });\n\n return [heading, ...lines].join('<br/>');\n}\n\n// A value axis: its title and range from the config, its tick labels from\n// valueAxisLabel. A vertical chart's title sits above the axis line, reading\n// away from the plot's edge; a horizontal chart's is centered below the ticks.\n// A bound or interval that is not a usable number is left to ECharts. A 100%\n// stacked chart's share axis (extras.percentMin) has its own fixed range.\nfunction valueAxisOption(\n axis: ChartValueAxis | undefined,\n horizontal: boolean,\n axisLabel: ValueAxisLabel,\n extras: ValueAxisExtras = {},\n) {\n const range = extras.percentMin === undefined\n ? valueAxisRange(axis)\n : { min: extras.percentMin, max: PERCENT_AXIS_MAX, interval: PERCENT_AXIS_INTERVAL };\n\n return {\n type: 'value' as const,\n name: axis?.label || undefined,\n nameLocation: horizontal ? 'middle' as const : 'end' as const,\n nameGap: horizontal ? 28 : 10,\n nameTextStyle: horizontal ? undefined : { align: extras.index === 1 ? 'right' as const : 'left' as const },\n // A pinned bound wins; one left open reaches the references (reachMin).\n min: range.min ?? reachMin(extras.reach),\n max: range.max ?? reachMax(extras.reach),\n interval: range.interval,\n axisLabel,\n };\n}\n\n// The part of a value axis's range the config pins. A bound that is not a\n// finite number, or an interval that is not a positive one, is left out, and\n// the chart picks it from the data. Shared with the PowerPoint export so both\n// media draw the same range.\nexport function valueAxisRange(axis: ChartValueAxis | undefined): { min?: number; max?: number; interval?: number } {\n const interval = axisNumber(axis?.interval);\n\n return {\n min: axisNumber(axis?.min),\n max: axisNumber(axis?.max),\n interval: interval !== undefined && interval > 0 ? interval : undefined,\n };\n}\n\n// A two-axis chart's value axes: the primary on the left, the second on the\n// right without gridlines of its own. Each axis's ticks take the format of the\n// measures plotted against it. Without a range on either axis the second axis\n// aligns its ticks to the primary's gridlines.\n//\n// On a 100% stacked chart (percentMin set) the primary axis is the share axis,\n// whose range is fixed, and the second axis's series are not stacked.\nfunction twoValueAxesOption(\n config: ChartConfig,\n axisFormats: (ValueAxisFormat | null)[],\n context: ReportFormatContext,\n percentMin: number | undefined,\n references: DrawnReference[],\n) {\n const percent = percentMin !== undefined;\n const label = (axisIndex: ValueAxisIndex) => valueAxisLabel(axisFormats[axisIndex] ?? null, context);\n\n return [\n valueAxisOption(config.valueAxis, false, percent ? percentAxisLabel(context) : label(0), {\n index: 0,\n percentMin,\n reach: referenceReach(references, 0),\n }),\n {\n ...valueAxisOption(config.secondaryAxis, false, label(1), { index: 1, reach: referenceReach(references, 1) }),\n position: 'right' as const,\n splitLine: { show: false },\n alignTicks: !percent && !hasAxisRange(config.valueAxis) && !hasAxisRange(config.secondaryAxis),\n },\n ];\n}\n\n// Whether the config pins any of an axis's range: a bound or a tick interval.\nfunction hasAxisRange(axis: ChartValueAxis | undefined): boolean {\n return Object.values(valueAxisRange(axis)).some((value) => value !== undefined);\n}\n\n// A configured bound or interval when it is a finite number, else undefined.\nfunction axisNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\n// A value axis's tick labels.\ninterface ValueAxisLabel {\n formatter: (value: number) => string;\n}\n\n// Tick labels written in the locale. ECharts' own ticks are grouped en-US\n// whatever the page's language.\n//\n// With a number format, the units and decimals decided once for the whole\n// axis (resolveValueAxisFormat) write every tick alike ('1.5K', '2.0K', never\n// '2K'). Without one, or when it leaves the ticks an unscaled number with no\n// pinned decimals (format 'number', or precision-less units none), each tick\n// is a plain locale-grouped number keeping its own decimals, so a 0.0002 tick\n// never rounds to '0'.\nfunction valueAxisLabel(format: ValueAxisFormat | null, context: ReportFormatContext): ValueAxisLabel {\n if (!format || (format.chart.units === ReportNumberUnits.None && format.chart.decimals === null)) {\n return { formatter: (value: number) => formatPlainNumber(value, context.locale) };\n }\n\n const options = { units: format.chart.units, decimals: format.chart.decimals };\n\n return {\n formatter: (value: number) => formatNumber(value, format.spec, context, options),\n };\n}\n\n// An axis's format from the spec its measures agree on, with the units and\n// decimals decided from its peak. Without a spec the axis is plain, and the\n// peak is never computed.\nfunction resolveValueAxisFormat(\n spec: NumberFormatSpec | null,\n peak: () => number,\n context: ReportFormatContext,\n): ValueAxisFormat | null {\n return spec ? { spec, chart: resolveChartNumberFormat(spec, peak(), context) } : null;\n}\n\n// Each value axis's format, by axis index. A chart with one value axis takes\n// the format the plotted series' measures agree on (a splitBy or colorBy chart\n// plots only its first measure), from the peak of all its series. On a two-axis chart each axis takes the format of the measures\n// plotted against it, from the peak of its own series, which are never\n// stacked with a 100% stacked chart's shares. A reference past the data\n// stretches its axis, so it counts toward the peak (referencePeak); a 100%\n// stacked chart's references are shares, which the raw values' peak leaves\n// out.\nfunction valueAxisFormats(\n config: ChartConfig,\n extracted: ExtractedChartSeries,\n axisIndexes: ValueAxisIndex[],\n context: ReportFormatContext,\n percent: boolean,\n references: DrawnReference[],\n): (ValueAxisFormat | null)[] {\n const reach = (axisIndex: ValueAxisIndex) => (percent && axisIndex === 0 ? 0 : referencePeak(references, axisIndex));\n\n if (!axisIndexes.includes(1)) {\n return [resolveValueAxisFormat(\n axisNumberFormat(extracted.series.map((series) => series.measure)),\n () => Math.max(chartValuePeak(extracted.series.map((series) => series.values), !!config.stacked), reach(0)),\n context,\n )];\n }\n\n return ([0, 1] as const).map((axisIndex) => {\n const onAxis = extracted.series.filter((_, index) => axisIndexes[index] === axisIndex);\n\n return resolveValueAxisFormat(\n axisNumberFormat(onAxis.map((series) => series.measure)),\n () => Math.max(chartValuePeak(onAxis.map((series) => series.values), !!config.stacked && !percent), reach(axisIndex)),\n context,\n );\n });\n}\n\n// A 100% stacked chart's share axis ticks: whole percentages in the locale\n// ('25%', '25 %' in fr-CA). The shares are ratios whatever the report's\n// percentFormat says of its stored values.\nfunction percentAxisLabel(context: ReportFormatContext): ValueAxisLabel {\n return { formatter: wholePercentFormatter(context) };\n}\n\n// A share as a whole percentage in the locale, for the share axis's ticks and\n// its series' data labels.\nfunction wholePercentFormatter(context: ReportFormatContext): (value: unknown) => string {\n const ratioContext = { ...context, ratioPercent: true };\n\n return (value: unknown) => formatNumber(value, PERCENT_AXIS_FORMAT, ratioContext);\n}\n\n// What a series' tooltip writes beside its name.\ninterface SeriesTooltip {\n valueFormatter: (value: unknown) => string;\n}\n\n// A series' tooltip value in its measure's number format, per value ('—' when\n// empty). A measure without one writes it as the plain value axis does. A\n// value can arrive as an array (a [value, ...] data item), whose first entry\n// is the value.\nfunction seriesTooltip(measure: ChartMeasure | undefined, context: ReportFormatContext): SeriesTooltip {\n if (!hasNumberFormat(measure)) {\n return { valueFormatter: (value: unknown) => formatPlainNumber(value, context.locale) };\n }\n\n return {\n valueFormatter: (value: unknown) => formatNumber(Array.isArray(value) ? value[0] : value, measure, context),\n };\n}\n\nfunction buildPieOption(\n component: ReportComponent,\n data: ComponentData,\n donut: boolean,\n context: ReportFormatContext,\n): 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 tooltip: seriesTooltip(extracted.series[0]?.measure, context),\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 time axis's date label style when its config names one the viewer knows,\n// else short.\nexport function chartDateLabel(config: ChartConfig | undefined): ReportChartDateLabel {\n return Object.values(ReportChartDateLabel).find((style) => style === config?.xAxis?.dateLabel)\n ?? ReportChartDateLabel.Short;\n}\n\n// A bucket's period-start split into its primary label and its year. A year\n// reads \"2025\" in every style. Short, in the locale: day/week read \"May 1\"\n// ('1 mai' in fr-CA), month \"May\" ('mai'), quarter \"Q2\" ('T2' in French).\n// Long carries its year, in the locale: \"May 1, 2026\", \"May 2026\" ('mai\n// 2026'), \"Q2 2026\". Numeric is the same in every locale: \"2026-05-01\",\n// \"2026-05\", \"2026-Q2\". Returns null for a value that isn't a parseable date\n// (left as-is by callers).\nfunction periodLabelParts(\n value: string,\n granularity: ChartGranularity,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel = ReportChartDateLabel.Short,\n): { 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 if (granularity === 'year') {\n return { primary: year, year };\n }\n\n return { primary: periodPrimaryLabel(date, granularity, locale, dateLabel), year };\n}\n\n// A period's label in the style asked for, the year aside (see\n// periodLabelParts).\nfunction periodPrimaryLabel(\n date: Date,\n granularity: Exclude<ChartGranularity, 'year'>,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel,\n): string {\n const year = String(date.getFullYear());\n const quarter = Math.floor(date.getMonth() / 3) + 1;\n\n if (dateLabel === ReportChartDateLabel.Numeric) {\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n switch (granularity) {\n case 'quarter':\n return `${year}-Q${quarter}`;\n case 'month':\n return `${year}-${month}`;\n default: // day, week — the bucket start\n return `${year}-${month}-${day}`;\n }\n }\n\n const long = dateLabel === ReportChartDateLabel.Long;\n switch (granularity) {\n case 'quarter':\n return long\n ? `${quarterPrefix(locale)}${quarter} ${year}`\n : `${quarterPrefix(locale)}${quarter}`;\n case 'month':\n return formatLocalDate(date, locale, long ? MONTH_YEAR : MONTH_LONG);\n default: // day, week — the bucket start as a month and day\n return formatLocalDate(date, locale, long ? DAY_SHORT : MONTH_DAY);\n }\n}\n\n// Whether a period label leaves its year to be added apart: only a short one\n// does, a long or numeric label already carries it.\nfunction periodYearApart(granularity: ChartGranularity, dateLabel: ReportChartDateLabel): boolean {\n return granularity !== 'year' && dateLabel === ReportChartDateLabel.Short;\n}\n\nfunction quarterPrefix(locale: ReportLocaleTag): string {\n return QUARTER_PREFIXES.get(locale.split('-')[0].toLowerCase()) ?? QUARTER_PREFIX;\n}\n\n// A compact single-line period label — for media that can't do a styled\n// second line, e.g. PowerPoint. A short label has its year appended only when\n// the data spans years; a long or numeric one always carries it.\nexport function formatPeriodLabel(\n value: string,\n granularity: ChartGranularity,\n multiYear: boolean,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel = ReportChartDateLabel.Short,\n): string {\n const parts = periodLabelParts(value, granularity, locale, dateLabel);\n if (!parts) {\n return value;\n }\n\n return multiYear && periodYearApart(granularity, dateLabel) ? `${parts.primary} ${parts.year}` : parts.primary;\n}\n\n// A cross-tab's column headings, the one rule the grid and the PDF/PowerPoint\n// exports share. The first is the row key and keeps its authored label; the\n// rest are pivot VALUES. When the pivot axis is a time dimension the server\n// sends the grain it bucketed at, so a period-start like \"2026-01-01\" reads\n// \"January 2026\" ('janvier 2026' in fr-CA), as the chart's x-axis labels it.\nexport function pivotHeadings(\n config: ListConfig,\n data: ComponentData,\n locale: ReportLocaleTag,\n): string[] {\n const columns = data.columns ?? [];\n const multiYear = spansMultipleYears(columns);\n\n return columns.map((column, index) => {\n if (index === 0) {\n return config.rowBy?.label || column;\n }\n\n return data.granularity ? formatPeriodLabel(column, data.granularity, multiYear, locale) : column;\n });\n}\n\n// A cross-tab's columns as the grid and the exports draw them: each headed by\n// pivotHeadings(), and every pivot-value column formatted by the one\n// config.cellFormat. The row key column stays as it came. `numeric` marks the\n// columns whose cells are formatted numbers, which are right-aligned.\nexport function pivotColumnSpecs(\n config: ListConfig,\n data: ComponentData,\n locale: ReportLocaleTag,\n): (ListColumn & { numeric: boolean })[] {\n const headings = pivotHeadings(config, data, locale);\n const cellFormat = config.cellFormat;\n const numeric = hasNumberFormat(cellFormat);\n const cells: Pick<ListColumn, 'format' | 'precision' | 'units'> = numeric && cellFormat\n ? { format: listColumnFormat(cellFormat.format), precision: cellFormat.precision, units: cellFormat.units }\n : {};\n\n return (data.columns ?? []).map((column, index) => index === 0\n ? { column, label: headings[index], numeric: false }\n : { column, label: headings[index], ...cells, numeric });\n}\n\n// A number format's style as a list column's format: the two enums share\n// their number values.\nfunction listColumnFormat(format: NumberFormatSpec['format']): ReportListColumnFormat | undefined {\n return Object.values(ReportListColumnFormat).find((value) => value === format);\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, and neither does a long or numeric label,\n// which carries its year). Empty for a non-time axis (labels as-is).\nfunction periodAxisLabel(\n granularity: ChartGranularity | null,\n categories: string[],\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel,\n): { 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, locale, dateLabel);\n if (!parts) {\n return value;\n }\n\n return multiYear && periodYearApart(granularity, dateLabel)\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, computed, inject, input } 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';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\n\n\n// ECharts host for a chart component. Pure rendering: the parent owns the\n// data fetch; this maps (component config, rows, the open report's format\n// context) → option and exposes the chart instance for resize + the future\n// image exports (getDataURL needs the canvas renderer registered in\n// 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 {\n\n public readonly component = input.required<ReportComponent>();\n public readonly data = input<ComponentData | null>(null);\n\n public readonly options = computed<EChartsOption | null>(() => {\n const data = this.data();\n\n return data\n ? buildChartOption(this.component(), data, this._filterState.formatContext())\n : null;\n });\n\n private _chart: ECharts | null = null;\n private readonly _filterState = inject(ReportFilterStateService);\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","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\n\nimport { formatNumber } from '../../format';\nimport { ComponentData, KpiConfig, ReportComponent } from '../../interfaces/report.interface';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\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, in the open report's\n// format context (its locale, its currency, and whether a percent arrives as a\n// 0-1 ratio or, from an older server, already x100).\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 {\n\n public readonly component = input.required<ReportComponent>();\n public readonly data = input<ComponentData | null>(null);\n\n public readonly label = computed(() => this._config().measure?.label ?? '');\n\n // A missing row or value reads '—'. A measure without number-format keys\n // reads as a plain number in the report's locale.\n public readonly value = computed(() => {\n const row = this.data()?.rows?.[0];\n const measure = this._config().measure;\n const column = measure?.column ?? Object.keys(row ?? {})[0];\n\n return formatNumber(row?.[column], measure, this._filterState.formatContext(), { empty: '—' });\n });\n\n private readonly _config = computed(() => (this.component().config ?? {}) as KpiConfig);\n private readonly _filterState = inject(ReportFilterStateService);\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 { Pipe, PipeTransform } from '@angular/core';\n\nimport { formatReportDate } from '../format';\nimport { ReportLocaleTag } from '../interfaces/report.interface';\n\n\n// A report row's date cell as the calendar day in the report's zone, written in\n// the report's locale. Use it in place of Angular's DatePipe, which reads a\n// 'YYYY-MM-DD HH:MM:SS' value as the browser's local wall time instead of the\n// UTC instant it is, and writes in the browser's language.\n@Pipe({\n name: 'fsReportDate',\n standalone: true,\n})\nexport class ReportDatePipe implements PipeTransform {\n\n public transform(value: unknown, timezone: string, locale: ReportLocaleTag): string {\n return formatReportDate(value, timezone, locale);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { formatNumber, hasNumberFormat } from '../format';\nimport { NumberFormatSpec, ReportFormatContext } from '../interfaces/report.interface';\n\n\n// A list cell in its column's number format, in the report's locale and\n// currency; an empty value reads ''. A column without number-format keys\n// prints its value as it came, as a cell always has, so an id or a year is\n// never grouped ('2,026').\n@Pipe({\n name: 'fsReportNumber',\n standalone: true,\n})\nexport class ReportNumberPipe implements PipeTransform {\n\n public transform(value: unknown, column: NumberFormatSpec, context: ReportFormatContext): string {\n if (hasNumberFormat(column)) {\n return formatNumber(value, column, context, { empty: '' });\n }\n\n return value === null || value === undefined ? '' : String(value);\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n AfterRenderRef,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n OnInit,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { FsListComponent, FsListConfig, FsListModule, PaginationStrategy } from '@firestitch/list';\n\nimport { Observable, map, merge, tap } from 'rxjs';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportListColumnFormat } from '../../enums/report-list-column-format.enum';\nimport { formatPlainNumber, hasNumberFormat } from '../../format';\nimport {\n ComponentData,\n ComponentDataState,\n ListColumn,\n ListConfig,\n ReportComponent,\n ReportSort,\n} from '../../interfaces/report.interface';\nimport {\n LIST_TOTAL_LABEL,\n columnClasses,\n listPinnedColumns,\n listSortTerms,\n listTotalsLabelColumn,\n} from '../../list-config';\nimport { pivotColumnSpecs } from '../../option-builder';\nimport { ReportDatePipe } from '../../pipes/report-date.pipe';\nimport { ReportNumberPipe } from '../../pipes/report-number.pipe';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\n\n\n// A list component: an FsList rendered from the component's config. It has no\n// filter bar of its own: its filters are group-keyed like every other\n// component's, so component-level groups render in the component header strip\n// (ReportComponentComponent) and report-level groups in the report bar, and\n// every request takes its values from the shared filter-state service.\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 FsListModule,\n NgTemplateOutlet,\n ReportDatePipe,\n ReportNumberPipe,\n ],\n})\nexport class ComponentListComponent implements OnInit {\n\n public readonly reportId = input.required<number>();\n public readonly component = input.required<ReportComponent>();\n\n public readonly listComponent = viewChild(FsListComponent);\n\n public listConfig: FsListConfig;\n\n // A plain list's columns are authored and fixed at init. A cross-tab's are\n // the pivot dimension's VALUES, so they arrive with the rows and change\n // whenever the filters do — which is why this is a signal rather than the\n // one-shot read it used to be. `numeric` marks a column whose cells are\n // formatted numbers, decided once here rather than per cell, so the column\n // and its header are right-aligned.\n public columns = signal<(ListColumn & { numeric: boolean })[]>([]);\n\n // A cross-tab sorts only by its row-key column: every other header is a\n // pivot value, and the server orders the long rows before pivoting, so a\n // click on \"Mar 2026\" has nothing to order by.\n public pivoted = signal(false);\n\n // A cut result is worse for a grid than for a list: the cut lands on the LONG\n // rows before the reshape, so a pivot value living only in the tail vanishes\n // as a whole COLUMN and straddled cells come back blank, indistinguishable\n // from a real zero. The parent's truncation banner never fires for a list\n // (it only renders what _load() fetched, which lists skip), so the warning\n // belongs here.\n public truncated = signal(false);\n\n // Why the search box did not narrow the rows (the list has no text column to\n // search), from the latest page 1; null when the search applied or none was\n // made.\n public readonly searchNote = signal<string | null>(null);\n\n // config.totals, read once at init: a list with totals renders its columns\n // with a footer template, which fs-list reads only when it builds them.\n public readonly showTotals = signal(false);\n\n // The totals row from the latest page 1, raw values keyed like the columns;\n // null when the list has none, or the server says why in totalsNote.\n public readonly totals = signal<Record<string, unknown> | null>(null);\n\n public readonly totalsNote = signal<string | null>(null);\n\n // How many rows the list shows (load more appends) out of how many its\n // filters keep. A cross-tab counts grid rows.\n public readonly rowCount = signal<{ shown: number; total: number } | null>(null);\n\n // The report's effective zone, which date cells render in. Injected right\n // here rather than read off _filterState, which is declared further down and\n // is still undefined while this initializer runs.\n public readonly timezone = inject(ReportFilterStateService).timezone;\n\n // The open report's format context: date cells, number cells and a\n // cross-tab's period headings are written in its locale (and money in its\n // currency). Injected here for the same reason.\n public readonly formatContext = inject(ReportFilterStateService).formatContext;\n\n public readonly ReportListColumnFormat = ReportListColumnFormat;\n\n // How many leading columns stay in view while the list scrolls sideways.\n public readonly pinned = computed(() => listPinnedColumns(this.component().config));\n\n public readonly columnClasses = columnClasses;\n\n // The config columns the viewer hid on this list (the Columns dialog, or the\n // URL). fs-list hides and shows them in place through [show], so the rows\n // already fetched stand.\n public readonly hidden = computed(() => new Set(this._filterState.hiddenColumns(this.component().id)));\n\n public readonly totalLabel = LIST_TOTAL_LABEL;\n\n // The column whose footer cell reads 'Total': the first one shown, unless\n // it holds a total itself.\n public readonly totalsLabelColumn = computed(() => listTotalsLabelColumn(\n this.columns().filter((column) => !this.hidden().has(column.column)),\n this.totals(),\n ));\n\n // The line under the list: its row count, then why it has no totals and why\n // its search narrowed nothing. The digits are written in the report's\n // locale, never the app's.\n public readonly caption = computed(() => {\n const count = this.rowCount();\n const locale = this.formatContext().locale;\n const parts: string[] = [];\n\n if (count) {\n const total = formatPlainNumber(count.total, locale);\n parts.push(count.shown < count.total\n ? `Showing ${formatPlainNumber(count.shown, locale)} of ${total}`\n : `${total} row(s)`);\n }\n\n return [...parts, this.totalsNote(), this.searchNote()]\n .filter((part): part is string => !!part)\n .join(' · ');\n });\n\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _destroyRef = inject(DestroyRef);\n private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private _injector = inject(Injector);\n private _pinOffsetsRef: AfterRenderRef | null = null;\n\n constructor() {\n // Hiding or showing a column moves the pinned columns after it.\n effect(() => {\n this.hidden();\n untracked(() => this._schedulePinOffsets());\n });\n }\n\n public ngOnInit(): void {\n const component = this.component();\n const config = (component.config ?? {}) as ListConfig;\n this.pivoted.set(!!config.pivotBy?.column);\n this.showTotals.set(config.totals === true);\n this.columns.set((config.columns ?? []).map((column) => ({ ...column, numeric: hasNumberFormat(column) })));\n\n this._initListConfig(config);\n this._observePinOffsets();\n\n // A change to any group this list's filters belong to (from the report bar\n // or the component header strip) re-runs the list.\n // So does a change of the text in its search box (in the component header).\n merge(this._filterState.changesFor(component), this._filterState.listSearchChanges(component.id))\n .pipe(\n tap(() => this.listComponent()?.reload()),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n private _initListConfig(config: ListConfig): void {\n // The viewer's last sort wins over the authored one, so a list recreated\n // in the same session (page switch, reload after an edit) keeps it.\n // fs-list holds one sorting column, so it shows the authored sort's first\n // term; the request sends only that term and the server appends the rest.\n const sort: ReportSort | undefined = this._filterState.listSort(this.component().id)\n ?? listSortTerms(config)[0];\n\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 // FsList never touches the URL or persists sort/paging state. The sort\n // reaches the URL through ReportFilterStateService (setListSort), and\n // paging stays out of it.\n queryParam: false,\n persist: false,\n sort: sort\n ? { value: sort.column, direction: 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 fetch: (query: any) => this._fetch(query),\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 const component = this.component();\n this._filterState.setListSort(component, state.sort ?? null);\n\n const search = this._filterState.listSearch(component.id);\n if (search) {\n state.search = search;\n }\n\n // One source for filter values, the same one charts, KPIs and the exports\n // read, so the list is filtered exactly as its header strip shows.\n const filters = this._filterState.resolveForComponent(component);\n\n return this._reportData\n .componentData(this.reportId(), component.id, filters, state)\n .pipe(\n map((data: ComponentData) => {\n // A cross-tab's headers come back with the rows: the row-key column\n // first, then one per pivot value. Re-read them on every fetch, since\n // a filter change can add or remove a column.\n if (this.pivoted()) {\n this.columns.set(this._pivotColumns(data));\n this.truncated.set(!!data.truncated);\n }\n\n // Only page 1 carries the notes and the totals; a load-more page\n // leaves them as they are.\n if (state.page === 1) {\n this.searchNote.set(data.searchNote ?? null);\n this.totals.set(data.totals ?? null);\n this.totalsNote.set(data.totalsNote ?? null);\n }\n\n // The server's page size when it sends one (it clamps the request),\n // the size the paging below hands fs-list too.\n const size = data.paging?.pageSize ?? state.pageSize;\n const shown = (state.page - 1) * size + (data.rows?.length ?? 0);\n this.rowCount.set({ shown, total: data.paging?.total ?? shown });\n\n // New rows can widen a pinned column, which moves the ones after it.\n this._schedulePinOffsets();\n\n return {\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\n // A cross-tab's columns, built from the wire by pivotColumnSpecs(): the same\n // headings and cell format the PDF and PowerPoint exports use.\n private _pivotColumns(data: ComponentData): (ListColumn & { numeric: boolean })[] {\n const config = (this.component().config ?? {}) as ListConfig;\n\n return pivotColumnSpecs(config, data, this.formatContext().locale);\n }\n\n // A tile resize reflows the table's auto layout, so the pinned columns'\n // widths, and with them their offsets, change.\n private _observePinOffsets(): void {\n if (this.pinned() < 2 || typeof ResizeObserver === 'undefined') {\n return;\n }\n\n const observer = new ResizeObserver(() => this._schedulePinOffsets());\n observer.observe(this._elementRef.nativeElement);\n this._destroyRef.onDestroy(() => observer.disconnect());\n }\n\n // Measures the pinned offsets once the next render has laid the table out.\n // One pending measurement covers every request made before it runs. Only\n // afterNextRender exists in every Angular version this library runs on.\n private _schedulePinOffsets(): void {\n if (this.pinned() < 2 || this._pinOffsetsRef) {\n return;\n }\n\n this._pinOffsetsRef = afterNextRender(() => {\n this._pinOffsetsRef = null;\n this._updatePinOffsets();\n }, { injector: this._injector });\n }\n\n // Each pinned column sticks at the summed width of the visible pinned\n // columns before it. A hidden column renders no header, so the next pinned\n // one takes its place. A variable is written only when its value changed,\n // which keeps a resize from restyling the table for nothing.\n private _updatePinOffsets(): void {\n const host = this._elementRef.nativeElement;\n let left = 0;\n\n for (let index = 0; index < this.pinned(); index++) {\n const header = host.querySelector<HTMLElement>(`thead th.report-pin-${index}`);\n\n if (!header) {\n continue;\n }\n\n const name = `--report-pin-left-${index}`;\n const value = `${Math.round(left * 100) / 100}px`;\n\n if (host.style.getPropertyValue(name) !== value) {\n host.style.setProperty(name, value);\n }\n\n left += header.getBoundingClientRect().width;\n }\n }\n}\n","@if (truncated()) {\n <div class=\"pivot-truncated\">\n This grid was built from a partial result, so some columns or values may be missing. Narrow it with a filter.\n </div>\n}\n\n<!-- fs-list reads a column's footer template once, as a direct child of\n fs-list-column, so a list with totals renders its columns in a branch of\n their own rather than wrapping the footer in an @if. -->\n<fs-list\n [config]=\"listConfig\"\n [class.report-totals-empty]=\"!totals()\">\n @if (showTotals()) {\n @for (column of columns(); track column.column) {\n <fs-list-column\n [name]=\"column.column\"\n [title]=\"column.label || column.column\"\n [show]=\"!hidden().has(column.column)\"\n [sortable]=\"!pivoted() || $first\"\n [align]=\"column.numeric ? 'right' : 'left'\"\n [class]=\"columnClasses(column, $index, pinned())\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <ng-container\n [ngTemplateOutlet]=\"cellTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row[column.column], column: column }\">\n </ng-container>\n </ng-template>\n <ng-template fs-list-footer>\n @if (totals()?.[column.column] !== undefined) {\n <ng-container\n [ngTemplateOutlet]=\"cellTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: totals()?.[column.column], column: column }\">\n </ng-container>\n } @else if (column.column === totalsLabelColumn()) {\n {{ totalLabel }}\n }\n </ng-template>\n </fs-list-column>\n }\n } @else {\n @for (column of columns(); track column.column) {\n <fs-list-column\n [name]=\"column.column\"\n [title]=\"column.label || column.column\"\n [show]=\"!hidden().has(column.column)\"\n [sortable]=\"!pivoted() || $first\"\n [align]=\"column.numeric ? 'right' : 'left'\"\n [class]=\"columnClasses(column, $index, pinned())\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <ng-container\n [ngTemplateOutlet]=\"cellTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row[column.column], column: column }\">\n </ng-container>\n </ng-template>\n </fs-list-column>\n }\n }\n</fs-list>\n\n@if (caption()) {\n <div class=\"list-caption small\">\n {{ caption() }}\n </div>\n}\n\n<!-- One cell, in the body and the totals row alike: a date column as a day in\n the report's zone and locale, any other through its number format. -->\n<ng-template\n #cellTpl\n let-value\n let-column=\"column\">\n @if (column.format === ReportListColumnFormat.Date) {\n {{ value | fsReportDate: timezone() : formatContext().locale }}\n } @else {\n {{ value | fsReportNumber: column : formatContext() }}\n }\n</ng-template>\n","import {\n ChangeDetectionStrategy, Component, DestroyRef, ElementRef, computed, effect, inject, input, output,\n untracked, viewChild,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\nimport { FsHtmlEditorComponent, FsHtmlEditorConfig } from '@firestitch/html-editor';\n\nimport {\n DEFAULT_TEXT_COLOR, DEFAULT_TEXT_SIZE, HEADING_TEXT_SIZES, TextTokenContext, fillTextTokens,\n} from '../../text';\n\n\n// Point sizes — the report's type unit (1:1 with PowerPoint and PDF).\nconst FONT_SIZES = ['8', '9', '10', '11', '12', '14', '16', '18', '20', '24', '28', '32', '36', '40', '48', '60', '72'];\n\n// The fields a block can carry, filled per page on the canvas and in exports.\nconst TOKENS = {\n '{{page.number}}': 'Page number',\n '{{page.name}}': 'Page name',\n '{{report.name}}': 'Report name',\n};\n\n// What the editor may produce — exactly what the server keeps\n// (ReportTextHtml) and the exports draw. Anything else would edit fine and\n// then vanish on save.\nconst ALLOWED_TAGS = ['p', 'h1', 'h2', 'h3', 'br', 'strong', 'em', 'u', 's', 'span', 'a', 'ul', 'ol', 'li'];\nconst ALLOWED_STYLES = ['color', 'background-color', 'font-size', 'font-weight', 'font-style', 'text-decoration', 'font-family', 'text-align'];\n\n// Froala's own toolbars and popups live on the body, not in the block; a press\n// on any of them is still part of editing the block.\nconst EDITOR_CHROME = '.fr-toolbar, .fr-popup, .fr-dropdown-menu, .fr-modal, .fr-tooltip';\n\n// A text block: authored rich text on the page.\n//\n// Read mode renders the stored html with its tokens ({{page.number}}, …) filled\n// for the page it is drawn on. The html has already been rebuilt server-side\n// from an allowlist (ReportTextHtml), which is what makes binding it as trusted\n// markup safe — Angular's own sanitizer would strip the inline styles that ARE\n// the formatting.\n//\n// Edit mode mounts <fs-html-editor> in its floating mode in place — the words\n// stay where they sit on the slide — with Froala's inline toolbar popping up\n// over them. The editor exists only while editing; the raw html is edited, so a\n// token reads as {{page.number}} while editing and as the number otherwise.\n//\n// The block never saves on its own: it emits the new html when editing ends\n// and the host persists it.\n@Component({\n selector: 'app-report-component-text',\n templateUrl: './component-text.component.html',\n styleUrls: ['./component-text.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsHtmlEditorComponent,\n ],\n host: {\n '(keydown)': 'onKeydown($event)',\n // The document type scale comes from the same constants the PowerPoint and\n // PDF exports draw with, so a paragraph is one size in all three.\n '[style.--text-size]': 'typeScale.body',\n '[style.--text-h1-size]': 'typeScale.h1',\n '[style.--text-h2-size]': 'typeScale.h2',\n '[style.--text-h3-size]': 'typeScale.h3',\n '[style.--text-color]': 'typeScale.color',\n },\n})\nexport class ComponentTextComponent {\n\n // The block's stored html (config.html). Its own input rather than read off\n // the component, so a saved edit — a new string on the same component — is\n // seen as a change and repaints.\n public readonly html = input('');\n public readonly tokens = input.required<TextTokenContext>();\n public readonly editing = input(false);\n\n // The html after an edit, only when it changed.\n public readonly saved = output<string>();\n\n // A press landed outside the block (or Escape): the host ends edit mode,\n // which saves.\n public readonly editEnded = output<void>();\n\n public readonly typeScale = {\n body: `${DEFAULT_TEXT_SIZE}pt`,\n h1: `${HEADING_TEXT_SIZES[1]}pt`,\n h2: `${HEADING_TEXT_SIZES[2]}pt`,\n h3: `${HEADING_TEXT_SIZES[3]}pt`,\n color: DEFAULT_TEXT_COLOR,\n };\n\n public readonly editorConfig: FsHtmlEditorConfig = {\n floating: true,\n autofocus: true,\n placeholder: 'Type here',\n buttons: [\n {\n name: 'insertField',\n title: 'Insert field',\n svgKey: 'tags',\n options: TOKENS,\n click: (editor, value) => editor.html.insert(value),\n },\n ],\n froalaConfig: {\n toolbarButtons: [\n 'paragraphFormat', 'fontSize', '|',\n 'bold', 'italic', 'underline', 'strikeThrough', 'textColor', '|',\n 'align', 'formatUL', 'formatOL', '|',\n 'insertLink', 'insertField', 'clearFormatting',\n ],\n paragraphFormat: { N: 'Normal', H1: 'Heading 1', H2: 'Heading 2', H3: 'Heading 3' },\n paragraphFormatSelection: true,\n fontSize: FONT_SIZES,\n fontSizeUnit: 'pt',\n fontSizeSelection: true,\n htmlAllowedTags: ALLOWED_TAGS,\n htmlAllowedAttrs: ['style', 'href', 'target', 'rel'],\n htmlAllowedStyleProps: ALLOWED_STYLES,\n htmlRemoveTags: ['script', 'style'],\n // Inline styles rather than Froala's fr-* classes, which neither the\n // server nor the exports know.\n useClasses: false,\n pastePlain: true,\n // Every keystroke reaches the model straight away, so ending the edit an\n // instant after typing never loses the last word.\n typingTimer: 0,\n },\n };\n\n public readonly displayHtml = computed<SafeHtml>(() => this._sanitizer.bypassSecurityTrustHtml(\n fillTextTokens(this.html(), this.tokens()),\n ));\n\n // What the editor holds right now.\n public draft = '';\n\n private readonly _editor = viewChild(FsHtmlEditorComponent);\n private readonly _sanitizer = inject(DomSanitizer);\n private readonly _host: ElementRef<HTMLElement> = inject(ElementRef);\n private readonly _destroyRef = inject(DestroyRef);\n private _isOpen = false;\n\n constructor() {\n // Opening seeds the draft; closing — whoever closed it: a press outside,\n // Escape, the block being deselected or edit mode ending — saves it.\n effect(() => {\n const editing = this.editing();\n\n untracked(() => {\n if (editing && !this._isOpen) {\n this._isOpen = true;\n this.draft = this.html();\n } else if (!editing && this._isOpen) {\n this._finish();\n }\n });\n });\n\n // A press anywhere that is not the block or the editor's own chrome ends\n // the edit. Captured, so it is seen before the canvas or a sibling\n // component acts on the same press.\n const onPress = (event: PointerEvent) => this._onDocumentPress(event);\n document.addEventListener('pointerdown', onPress, true);\n this._destroyRef.onDestroy(() => document.removeEventListener('pointerdown', onPress, true));\n }\n\n public onKeydown(event: KeyboardEvent): void {\n if (this.editing() && event.key === 'Escape') {\n event.preventDefault();\n this._close();\n }\n }\n\n private _onDocumentPress(event: PointerEvent): void {\n if (!this.editing()) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n if (target && (this._host.nativeElement.contains(target) || target.closest(EDITOR_CHROME))) {\n return;\n }\n\n this._close();\n }\n\n // Save NOW, then ask the host to close. Saving here rather than waiting for\n // the editing input to flip matters: the same press may be on a page tab,\n // and by the time the input changed this block could already be destroyed,\n // with its edit gone.\n private _close(): void {\n this._syncDraft();\n this._finish();\n this.editEnded.emit();\n }\n\n // Read the editor directly rather than trusting the last model update.\n private _syncDraft(): void {\n const html = this._editor()?.editor?.html?.get();\n if (typeof html === 'string') {\n this.draft = html;\n }\n }\n\n private _finish(): void {\n if (!this._isOpen) {\n return;\n }\n\n this._isOpen = false;\n if (this.draft !== this.html()) {\n this.saved.emit(this.draft);\n }\n }\n}\n","@if (editing()) {\n <!-- Floating fs-html-editor: no frame, Froala's inline toolbar pops up over\n the text. pointerdown stays here so a press in the text never starts a\n drag of the block or a pan of the canvas. -->\n <fs-html-editor\n class=\"text-content editing\"\n [config]=\"editorConfig\"\n [(ngModel)]=\"draft\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n </fs-html-editor>\n} @else {\n <div\n class=\"text-content\"\n [innerHTML]=\"displayHtml()\">\n </div>\n}\n","import {\n ChangeDetectionStrategy, Component, DestroyRef, ElementRef,\n EventEmitter, HostBinding, Input, NgZone, OnChanges, OnInit, Output, SimpleChanges, ViewChild, inject,\n input, output, signal,\n} from '@angular/core';\n\n\nimport { MatIconButton } from '@angular/material/button';\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { FilterConfig, FsFilterModule } from '@firestitch/filter';\nimport { FsMenuModule } from '@firestitch/menu';\nimport { FsMessage } from '@firestitch/message';\nimport { FsProcess } from '@firestitch/process';\nimport { FsPrompt } from '@firestitch/prompt';\n\nimport { Subject, debounceTime, map, switchMap, tap } from 'rxjs';\n\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { ReportData } from '../../data/report.data';\nimport { ListColumnsComponent, ListColumnsDialogData } from '../../dialogs/list-columns/list-columns.component';\nimport {\n ComponentData,\n ComponentDataState,\n ComponentSettings,\n ReportComponent as ReportComponentModel,\n ReportFilterGroup,\n ReportLayout,\n} from '../../interfaces/report.interface';\nimport { DEFAULT_COMPONENT_PADDING } from '../../layout';\nimport { listHideableColumns } from '../../list-config';\nimport {\n LIST_SEARCH_ITEM, filterItemForGroup, groupValuesFromQuery, listSearchItem,\n} from '../../report-filter-items';\nimport { movedGroupValues, ReportFilterStateService } from '../../services/report-filter-state.service';\nimport { ComponentChartComponent } from '../component-chart/component-chart.component';\nimport { ComponentKpiComponent } from '../component-kpi/component-kpi.component';\nimport { ComponentListComponent } from '../component-list/component-list.component';\nimport { ComponentTextComponent } from '../component-text/component-text.component';\nimport { TextTokenContext } from '../../text';\nimport { CanvasSnapper, PX_PER_INCH } from '../report-canvas/report-canvas.component';\n\n\n// Freeform resize handles, named by compass direction.\nconst HANDLES = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'] as const;\ntype Handle = typeof HANDLES[number];\n\n// Flow width snaps to the useful fractions of a page row.\nconst FLOW_WIDTH_STOPS = [25, 33.33, 50, 66.67, 75, 100];\n\nconst MIN_W = 0.6; // inches\nconst MIN_H = 0.4; // inches\n\n// Two presses on a text block this close together open its editor. Detected\n// here rather than with a dblclick listener because the drag loop claims the\n// pointer on every press, and a browser is not obliged to deliver dblclick\n// through a captured, default-prevented pointer.\nconst DOUBLE_PRESS_MS = 400;\n\n// One component on the page: title bar, the type-specific body (chart | list\n// | kpi), a menu (settings, filter toggles, export) — and the editing\n// interactions:\n//\n// Freeform: click selects; the selection frame shows 8 resize handles;\n// dragging the body moves with smart alignment guides (via the canvas\n// snapper); everything works at any zoom (pixel deltas ÷ zoom·96 → inches).\n//\n// Flow: dragging reorders (drop position decided by the canvas); the E\n// handle resizes flowWidth % (snapping to 25/33/50/66/75/100), the S handle\n// resizes height in inches.\n//\n// Charts and KPIs fetch their own data here; lists fetch inside\n// ComponentListComponent through FsList paging.\n@Component({\n selector: 'app-report-component',\n templateUrl: './report-component.component.html',\n styleUrls: ['./report-component.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatIcon,\n MatIconButton,\n MatTooltip,\n FsFilterModule,\n FsMenuModule,\n ComponentChartComponent,\n ComponentKpiComponent,\n ComponentListComponent,\n ComponentTextComponent,\n ],\n})\nexport class ReportComponentComponent implements OnInit, OnChanges {\n\n @Input() public reportId: number;\n @Input() public component: ReportComponentModel;\n @Input() public groups: Map<number, ReportFilterGroup>;\n @Input() public editMode = false;\n @Input() public layout: ReportLayout = 'freeform';\n // The canvas zoom — converts on-screen pixel deltas back to inches.\n @Input() public zoom = 1;\n @Input() public snapper: CanvasSnapper | null = null;\n @Input() public selected = false;\n\n @Output() public selectComponent = new EventEmitter<number>();\n @Output() public positionChanged = new EventEmitter<{ componentId: number } & Record<string, number>>();\n @Output() public flowReorder = new EventEmitter<{ componentId: number; clientX: number; clientY: number }>();\n @Output() public openSettings = new EventEmitter<ReportComponentModel>();\n\n // What a text block's {{tokens}} fill with on the page it is drawn on.\n public readonly tokens = input<TextTokenContext>({ pageNumber: 1, pageName: '', reportName: '' });\n\n // A text block was deleted from its menu — the canvas drops it.\n public readonly removed = output<number>();\n\n // The text block's editor is open (double-press in edit mode). Closed by focus\n // leaving the block, by deselecting it, or by leaving edit mode — each of\n // which saves.\n public readonly textEditing = signal(false);\n\n @ViewChild(ComponentChartComponent)\n public chartComponent: ComponentChartComponent;\n\n // Freeform resize handles by type: a fixed-height component (chart/list)\n // gets all eight (resize width AND height); an auto-height one (kpi) gets\n // only the side handles since its height fits its content and can't be set.\n public get resizeHandles(): readonly Handle[] {\n return this._heightAuto ? ['e', 'w'] : HANDLES;\n }\n\n // The component's header IS an fs-filter: heading template = its title (and\n // the drag handle), actions = the Settings / filter-toggles / Export menu,\n // items = its component-level filter groups, for every component type, lists\n // included, plus a list's search box. Rebuilt when a filter toggle changes which groups show,\n // and when the settings dialog changes the title or padding: setting it\n // repaints the header and body.\n public readonly filterConfig = signal<FilterConfig | null>(null);\n\n public readonly data = signal<ComponentData | null>(null);\n public readonly loading = signal(false);\n public readonly error = signal<string | null>(null);\n\n private _refresh$ = new Subject<void>();\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _process = inject(FsProcess);\n private _message = inject(FsMessage);\n private _prompt = inject(FsPrompt);\n private _dialog = inject(MatDialog);\n private _lastPress = 0;\n private _destroyRef = inject(DestroyRef);\n private _zone = inject(NgZone);\n private _host: ElementRef<HTMLElement> = inject(ElementRef);\n\n public ngOnInit(): void {\n this._buildFilterConfig();\n\n // Lists fetch through FsList; text has nothing to fetch.\n if (this.component.type !== 'list' && !this.isText) {\n // Debounced so a rapid filter sweep fires one query, not one per change.\n this._refresh$\n .pipe(\n debounceTime(300),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => this._load());\n\n this._filterState.changesFor(this.component)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this._refresh$.next());\n\n // A group-by change re-buckets every time-series chart; it isn't scoped\n // to a filter group, so it rides its own stream.\n if (this._isTimeSeries) {\n this._filterState.frequencyChanges()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this._refresh$.next());\n }\n\n this._load();\n }\n }\n\n // The report reloads (e.g. after the settings dialog adds/moves a filter)\n // hand this instance fresh `component`/`groups` inputs without re-running\n // ngOnInit. Rebuild the header config so the inline component-filter strip\n // reflects the new filters; the template recreates the fs-filter via\n // `filterKey` so it actually re-reads this config.\n public ngOnChanges(changes: SimpleChanges): void {\n // Clicking away (deselect) or leaving edit mode closes an open text editor,\n // which is what saves it.\n if ((changes.selected && !this.selected) || (changes.editMode && !this.editMode)) {\n this.textEditing.set(false);\n }\n\n const filtersChanged = (changes.component && !changes.component.firstChange)\n || (changes.groups && !changes.groups.firstChange);\n\n if (filtersChanged) {\n this._buildFilterConfig();\n }\n }\n\n // fs-filter reads its config only once at init, so the header is keyed on what\n // it renders: the set of component-level filter groups AND the title, which\n // lives in fs-filter's heading template. fs-filter is OnPush and the heading is\n // rendered inside ITS view, so marking this component does not repaint the\n // title — recreating the block does.\n public get filterKey(): string {\n return [\n this.component.title,\n ...this.componentFilterGroups.map((group) => `${group.id}:${group.level}`),\n ].join('|');\n }\n\n public get isText(): boolean {\n return this.component.type === 'text';\n }\n\n // Open the text editor in place.\n public editText(): void {\n if (!this.editMode || !this.isText) {\n return;\n }\n\n this.selectComponent.emit(this.component.id);\n this.textEditing.set(true);\n }\n\n // The editor closed with changed html. Kept locally at once so the block\n // re-renders what was typed; the server rebuilds it from its allowlist, which\n // for anything the editor can produce is the same html.\n public onTextSaved(html: string): void {\n this.component.config = { ...this.component.config, html };\n this._reportData.updateComponent(this.reportId, this.component.id, { html })\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe();\n }\n\n public deleteText(): void {\n this._prompt.confirm({\n title: 'Confirm',\n template: 'Are you sure you would like to delete this text?',\n })\n .pipe(\n switchMap(() => this._reportData.deleteComponent(this.reportId, this.component.id)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => this.removed.emit(this.component.id));\n }\n\n public get truncated(): boolean {\n return !!this.data()?.truncated;\n }\n\n // Content padding (inches → px at 96/in; the canvas zoom scales the page as\n // a whole). Each edge defaults to 1/8\".\n public get bodyPadding(): string {\n const padding = this.component.config?.padding;\n const edge = (value: number | undefined) => `${(value ?? DEFAULT_COMPONENT_PADDING) * PX_PER_INCH}px`;\n\n return `${edge(padding?.top)} ${edge(padding?.right)} ${edge(padding?.bottom)} ${edge(padding?.left)}`;\n }\n\n // The component-level filter groups that should render as an inline control\n // strip on THIS component: a group is included when it's level=component and\n // has an enabled, session-on filter here. Report-level groups live in the\n // top bar instead. Lists use this strip like charts do: a value set here is\n // the group's value, so it reaches every component in the group.\n public get componentFilterGroups(): ReportFilterGroup[] {\n if (!this.groups) {\n return [];\n }\n\n const groupIds = new Set<number>();\n for (const filter of this.component.filters ?? []) {\n if (!filter.enabled || this._filterState.isFilterDisabled(filter.id)) {\n continue;\n }\n const group = this.groups.get(filter.filterGroupId);\n if (group && (group.level === 'component' || group.level === 'both')) {\n groupIds.add(group.id);\n }\n }\n\n return [...groupIds].map((id) => this.groups.get(id)).filter(Boolean);\n }\n\n public settings(): void {\n this.openSettings.emit(this.component);\n }\n\n // Whether the menu offers Columns: a plain list with more than one\n // configured column. A cross-tab's columns come and go with the data.\n public get hidesColumns(): boolean {\n return this.component.type === 'list' && listHideableColumns(this.component.config).length > 1;\n }\n\n // Which of a plain list's columns show. The choice is the viewer's (kept in\n // the URL, never saved to the report), and the list hides the columns in\n // place, with no refetch.\n public chooseColumns(): void {\n const columns = (this.component.config?.columns ?? [])\n .map((column) => ({ column: column.column, label: column.label || column.column }));\n\n this._dialog.open<ListColumnsComponent, ListColumnsDialogData, string[]>(ListColumnsComponent, {\n data: { columns, hidden: [...this._filterState.hiddenColumns(this.component.id)] },\n width: '400px',\n maxWidth: '95vw',\n autoFocus: false,\n })\n .afterClosed()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((hidden) => {\n // Cancel closes with nothing, which changes nothing.\n if (hidden) {\n this._filterState.setHiddenColumns(this.component.id, hidden);\n }\n });\n }\n\n // Presentation settings saved from the settings dialog. Title and padding are\n // not part of the query, so the data already fetched still stands — this only\n // repaints. The header config is rebuilt because `filterKey` changes with the\n // title and recreates the fs-filter block around it; setting the config signal\n // is also what repaints the new padding. The chart follows its box on its own\n // (ngx-echarts observes the host), so nothing is told to resize.\n public applySettings(settings: ComponentSettings): void {\n this.component.title = settings.title;\n this.component.config = { ...this.component.config, padding: settings.padding };\n\n this._buildFilterConfig();\n }\n\n // The CSV is what the screen shows, so it carries the same interaction state\n // the screen fetched with: the group-by grain for a time-series chart, and the\n // viewer's header sort, search and hidden columns for a list. A note the\n // server returns (the file was cut) is shown before the download starts, so a\n // short file never passes for the whole result.\n public exportCsv(): void {\n const filters = this._filterState.resolveForComponent(this.component);\n const state: ComponentDataState = {};\n\n // A deliberate mirror of the server's ReportQueryRunner::_isTimeSeriesChart,\n // which is canonical and drops the grain for every other component. Kept so\n // a product pinned to an older framework does not re-bucket a non-time chart.\n if (this._isTimeSeries && this._filterState.frequency()) {\n state.frequency = this._filterState.frequency();\n }\n\n const isList = this.component.type === 'list';\n const sort = isList ? this._filterState.listSort(this.component.id) : null;\n if (sort) {\n state.sort = sort;\n }\n\n // A searched list exports only the rows the search leaves, as on screen.\n const search = isList ? this._filterState.listSearch(this.component.id) : null;\n if (search) {\n state.search = search;\n }\n\n // The columns the viewer hid stay out of the file, as off the screen.\n const hiddenColumns = isList ? this._filterState.hiddenColumns(this.component.id) : [];\n if (hiddenColumns.length) {\n state.hiddenColumns = [...hiddenColumns];\n }\n\n this._process.download(\n `Exporting ${this.component.title ?? 'component'}`,\n this._reportData.exportComponent(this.reportId, this.component.id, filters, state)\n .pipe(\n tap(({ notes }) => notes?.length && this._message.warning(notes.join(' '))),\n map(({ url }) => url),\n ),\n );\n }\n\n // Any interaction inside a component must never start a canvas pan (the\n // zoom-pan host listens for mousedown/touchstart at the container level).\n public stopCanvasPan(event: Event): void {\n event.stopPropagation();\n }\n\n public onComponentPointerDown(event: PointerEvent): void {\n event.stopPropagation();\n if (this.editMode && !this.selected) {\n this.selectComponent.emit(this.component.id);\n }\n }\n\n // ----- edit-mode gestures ---------------------------------------------------\n\n public onDragStart(event: PointerEvent): void {\n if (!this.editMode || this.textEditing()) {\n return;\n }\n\n // A second press on a text block opens its editor instead of dragging.\n if (this.isText) {\n const now = Date.now();\n const isDoublePress = now - this._lastPress < DOUBLE_PRESS_MS;\n this._lastPress = now;\n\n if (isDoublePress) {\n event.preventDefault();\n event.stopPropagation();\n this.editText();\n\n return;\n }\n }\n\n this.selectComponent.emit(this.component.id);\n\n if (this.layout === 'flow') {\n this._flowDrag(event);\n\n return;\n }\n\n this._track(event, (deltaX, deltaY) => {\n let x = Math.max(0, this._origin.x + this._inches(deltaX));\n let y = Math.max(0, this._origin.y + this._inches(deltaY));\n\n if (this.snapper) {\n ({ x, y } = this.snapper.snapMove(this.component, x, y));\n }\n\n this.component.x = x;\n this.component.y = y;\n this._applyGeometry();\n }, () => this._emitGeometry());\n }\n\n public onResizeStart(event: PointerEvent, handle: Handle): void {\n if (!this.editMode) {\n return;\n }\n\n this.selectComponent.emit(this.component.id);\n\n if (this.layout === 'flow') {\n this._flowResize(event, handle);\n\n return;\n }\n\n this._track(event, (deltaX, deltaY) => {\n const dx = this._inches(deltaX);\n const dy = this._inches(deltaY);\n let { x, y, w, h } = this._origin;\n\n if (handle.includes('e')) {\n w = Math.max(MIN_W, this._origin.w + dx);\n }\n if (handle.includes('s')) {\n h = Math.max(MIN_H, this._origin.h + dy);\n }\n if (handle.includes('w')) {\n const clamped = Math.min(dx, this._origin.w - MIN_W);\n x = this._origin.x + clamped;\n w = this._origin.w - clamped;\n }\n if (handle.includes('n')) {\n const clamped = Math.min(dy, this._origin.h - MIN_H);\n y = this._origin.y + clamped;\n h = this._origin.h - clamped;\n }\n\n let geometry = { x, y, w, h };\n if (this.snapper) {\n geometry = this.snapper.snapResize(this.component, geometry, handle);\n }\n\n Object.assign(this.component, geometry);\n this._applyGeometry();\n this.chartComponent?.resize();\n }, () => this._emitGeometry());\n }\n\n // (Re)build the header fs-filter config: heading template renders the title\n // and items are this component's component-level filter groups. The actions\n // menu (Settings / Export CSV) is NOT here — it's a standalone kebab floated\n // top-right in the template, so its button height no longer drives the header\n // row's height (which would otherwise inflate the heading by ~40px).\n //\n // A list also gets a search box over its text columns, unless its header\n // shows a keyword group (ReportFilterStateService.listSearchable, which also\n // drops a search kept from before such a group appeared).\n //\n // `reported` is what this header last reported for each of its groups,\n // starting from the values it is built with. A change sets only the groups\n // whose header value moved (movedGroupValues): fs-filter reports every item\n // on any change, and a group shown in the report bar too may have changed\n // there since, without this header being repainted.\n private _buildFilterConfig(): void {\n const groups = this.componentFilterGroups;\n const listSearch = this._filterState.listSearchable(this.component);\n const reported = new Map(groups.map((group) => [group.id, this._filterState.value(group.id) ?? null]));\n\n this.filterConfig.set({\n // fs-filter never touches the URL or persists filter state. The values\n // are owned by ReportFilterStateService, which feeds the report view's\n // one URL writer (report-url-state.ts).\n queryParam: false,\n persist: false,\n items: [\n ...groups.map((group) =>\n filterItemForGroup(group, this._reportData, this.reportId, this._filterState.value(group.id))),\n ...(listSearch ? [listSearchItem(this._filterState.listSearch(this.component.id))] : []),\n ],\n // Typing in the search box must not refetch through the groups, nor set\n // a stale group value back, and a group change must not refetch through\n // the search.\n change: (query) => {\n const values = groupValuesFromQuery(query ?? {}, this.componentFilterGroups);\n\n for (const { groupId, value } of movedGroupValues(reported, values)) {\n this._filterState.setValue(groupId, value);\n }\n\n if (listSearch) {\n this._filterState.setListSearch(this.component.id, String(query?.[LIST_SEARCH_ITEM] ?? ''));\n }\n },\n });\n }\n\n // Flow: only the east handle resizes (width %). Height is always auto in flow\n // (the box fits its content), so there's no south handle here.\n private _flowResize(event: PointerEvent, handle: Handle): void {\n const pageWidth = this._host.nativeElement.parentElement?.clientWidth || 1;\n\n this._track(event, (deltaX) => {\n if (handle.includes('e')) {\n const deltaPercent = (deltaX / this.zoom / pageWidth) * 100;\n const raw = Math.min(100, Math.max(10, this._origin.flowWidth + deltaPercent));\n this.component.flowWidth = this._snapFlowWidth(raw);\n this._host.nativeElement.style.width = `${this.component.flowWidth}%`;\n }\n }, () => {\n this.positionChanged.emit({\n componentId: this.component.id,\n flowWidth: this.component.flowWidth,\n });\n });\n }\n\n // Flow: drag lifts the component (ghost) and the canvas decides the drop\n // index from the pointer position.\n private _flowDrag(event: PointerEvent): void {\n const host = this._host.nativeElement;\n let lastClientX = event.clientX;\n let lastClientY = event.clientY;\n\n host.classList.add('flow-dragging');\n\n this._track(event, (deltaX, deltaY, e) => {\n lastClientX = e.clientX;\n lastClientY = e.clientY;\n host.style.transform = `translate(${deltaX / this.zoom}px, ${deltaY / this.zoom}px)`;\n }, () => {\n host.classList.remove('flow-dragging');\n host.style.transform = '';\n this.flowReorder.emit({\n componentId: this.component.id,\n clientX: lastClientX,\n clientY: lastClientY,\n });\n });\n }\n\n private _origin = { x: 0, y: 0, w: 0, h: 0, flowWidth: 50 };\n\n // Pointer-capture gesture loop: runs outside Angular, repaints imperatively,\n // and finishes back inside Angular (selection/persistence).\n private _track(\n event: PointerEvent,\n onMove: (deltaX: number, deltaY: number, e: PointerEvent) => void,\n onEnd: () => void,\n ): void {\n event.preventDefault();\n event.stopPropagation();\n\n const handle = event.target as HTMLElement;\n handle.setPointerCapture(event.pointerId);\n\n this._origin = {\n x: this.component.x,\n y: this.component.y,\n w: this.component.w,\n h: this.component.h,\n flowWidth: this.component.flowWidth ?? 50,\n };\n const startX = event.clientX;\n const startY = event.clientY;\n\n this._zone.runOutsideAngular(() => {\n const move = (e: PointerEvent) => onMove(e.clientX - startX, e.clientY - startY, e);\n const end = () => {\n handle.releasePointerCapture(event.pointerId);\n handle.removeEventListener('pointermove', move);\n handle.removeEventListener('pointerup', end);\n handle.removeEventListener('pointercancel', end);\n\n this._zone.run(() => {\n this.snapper?.clear();\n onEnd();\n });\n };\n\n handle.addEventListener('pointermove', move);\n handle.addEventListener('pointerup', end);\n handle.addEventListener('pointercancel', end);\n });\n }\n\n private _emitGeometry(): void {\n this.component.x = this._round(this.component.x);\n this.component.y = this._round(this.component.y);\n this.component.w = this._round(Math.max(MIN_W, this.component.w));\n this.component.h = this._round(Math.max(MIN_H, this.component.h));\n this._applyGeometry();\n this.chartComponent?.resize();\n\n this.positionChanged.emit({\n componentId: this.component.id,\n x: this.component.x,\n y: this.component.y,\n w: this.component.w,\n h: this.component.h,\n });\n }\n\n // A chart on a time x-axis — the only component the report's group-by control\n // applies to. The server owns this rule (ReportQueryRunner::_isTimeSeriesChart);\n // this is its documented browser-side mirror, for products on an older framework.\n private get _isTimeSeries(): boolean {\n return this.component.type === 'chart' && this.component.config?.xAxis?.kind === 'time';\n }\n\n // Auto height (box fits its content) vs fixed (use `h` exactly). Derived from\n // type, server-side: KPI tiles are auto; charts and lists are fixed — charts\n // fit the box and never overflow, lists scroll inside it.\n private get _heightAuto(): boolean {\n return this.component.autoHeight !== false;\n }\n\n // Drives the auto-only CSS default (empty-state baseline) so it never applies\n // to a fixed-height component.\n @HostBinding('class.height-auto')\n public get heightAuto(): boolean {\n return this._heightAuto;\n }\n\n // Screen pixels → inches at the current zoom.\n private _inches(pixels: number): number {\n return pixels / (this.zoom * PX_PER_INCH);\n }\n\n // Clean persisted values: hundredths of an inch.\n private _round(value: number): number {\n return Math.round(value * 100) / 100;\n }\n\n private _snapFlowWidth(value: number): number {\n for (const stop of FLOW_WIDTH_STOPS) {\n if (Math.abs(value - stop) < 3) {\n return stop;\n }\n }\n\n return Math.round(value * 10) / 10;\n }\n\n // The canvas positions the host via [style]; mid-gesture we set it directly\n // so OnPush never re-renders in the move loop.\n private _applyGeometry(): void {\n const style = this._host.nativeElement.style;\n style.left = `${this.component.x * PX_PER_INCH}px`;\n style.top = `${this.component.y * PX_PER_INCH}px`;\n style.width = `${this.component.w * PX_PER_INCH}px`;\n\n // Auto (kpi): no fixed height — the box sizes to its content. Fixed\n // (chart/list): `h` is the exact height. Mirrors the canvas [style] binding\n // so the mid-gesture paint matches the post-gesture re-render.\n if (this._heightAuto) {\n style.height = '';\n } else {\n style.height = `${this.component.h * PX_PER_INCH}px`;\n }\n }\n\n // ----- data ----------------------------------------------------------------\n\n private _load(): void {\n this.loading.set(true);\n this.error.set(null);\n\n const filters = this._filterState.resolveForComponent(this.component);\n // Time-series charts carry the group-by grain (if the viewer picked one) so\n // the backend re-buckets; everything else sends no interaction state here.\n const state = this._isTimeSeries && this._filterState.frequency()\n ? { frequency: this._filterState.frequency() }\n : {};\n\n this._reportData.componentData(this.reportId, this.component.id, filters, state)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe({\n next: (data: ComponentData) => {\n this.data.set(data);\n this.loading.set(false);\n },\n error: (error) => {\n this.loading.set(false);\n this.error.set(error?.error?.message ?? error?.message ?? 'Failed to load data');\n },\n });\n }\n}\n","<div\n class=\"component-box\"\n [class.editing]=\"editMode\"\n [class.text]=\"isText\"\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 filter groups,\n the same strip for every type (lists included). fs-filter reads its\n config once, so the block is keyed on the component-filter set to be\n recreated when it changes. -->\n <!-- A text block has no title bar — it IS its words, like a text box on a\n slide — so it gets neither the header nor the data actions. -->\n @for (key of isText ? [] : [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 @if (!isText || (editMode && !textEditing())) {\n <button\n mat-icon-button\n class=\"component-menu\"\n [fsMenuTriggerFor]=\"menu\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"stopCanvasPan($event)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <!-- Beside its trigger, inside the same block: an fs-menu that finds no\n trigger of its own draws one. -->\n <fs-menu #menu>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"editText()\">\n <mat-icon>edit</mat-icon>\n <span>Edit text</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"deleteText()\">\n <mat-icon>delete</mat-icon>\n <span>Delete</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"settings()\">\n <mat-icon>tune</mat-icon>\n <span>Settings</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"exportCsv()\">\n <mat-icon>download</mat-icon>\n <span>Export CSV</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!hidesColumns\"\n (click)=\"chooseColumns()\">\n <mat-icon>view_column</mat-icon>\n <span>Columns</span>\n </ng-template>\n </fs-menu>\n }\n <div class=\"component-body\">\n @if (isText) {\n <app-report-component-text\n [html]=\"component.config?.html ?? ''\"\n [tokens]=\"tokens()\"\n [editing]=\"textEditing()\"\n (saved)=\"onTextSaved($event)\"\n (editEnded)=\"textEditing.set(false)\">\n </app-report-component-text>\n } @else if (component.type === 'list') {\n <app-report-component-list\n [reportId]=\"reportId\"\n [component]=\"component\">\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 && !textEditing()) {\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, Component, DestroyRef,\n ElementRef, EventEmitter, Input, OnChanges, Output, QueryList, SimpleChanges, ViewChild, ViewChildren,\n inject, signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\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, ReportHeaderFooter, ReportPage,\n} from '../../interfaces/report.interface';\nimport { DEFAULT_HEADING_SIZE, FLOW_PADDING } from '../../layout';\nimport { TextTokenContext } from '../../text';\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// (Ctrl/Cmd + wheel or pinch to zoom, background drag pan, toolbar buttons; a\n// plain wheel scrolls the list under the pointer).\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//\n// Header and footer: the report's master components (report.master) are drawn\n// on a layer UNDER every page's own components, like a PowerPoint slide master,\n// unless the page hides them. In edit mode the host toolbar's \"Header & footer\"\n// (toggleMasterMode) switches which layer is live: the page's components dim\n// and the master's become the ones that drag, resize and snap. The header/footer bands (config.headerFooter)\n// are drawn as guides while editing and are snap lines for both layers.\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 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 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 // The report's pages as the canvas draws them. This is the host's own\n // `report.pages` array, patched in place (a rename, a delete, a reorder) so\n // the host's exports and page links see the change too. Because the array\n // and its pages keep their identity across a patch, the signal notifies on\n // every set rather than only when the reference changes.\n public readonly pages = signal<ReportPage[]>([], { equal: () => false });\n public readonly activePageIndex = signal(0);\n public readonly zoom = signal(1);\n\n // Editing the header and footer (the master layer) rather than the page.\n public readonly masterMode = signal(false);\n public groups = new Map<number, ReportFilterGroup>();\n public readonly selectedComponentId = signal<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 _destroyRef = inject(DestroyRef);\n private _fitted = false;\n private _tokens: TextTokenContext | null = null;\n private _previousPageCount = 0;\n\n // The page id last announced through pageChanged, so a re-render that lands on\n // the same page stays quiet — hosts reload on this and an unchanged page is\n // not news.\n private _emittedPageId: number | null = null;\n\n public ngOnChanges(changes: SimpleChanges): void {\n // Leaving edit mode always returns to the page layer, so the next edit\n // session starts where people expect.\n if (changes.editMode && !this.editMode) {\n this.masterMode.set(false);\n }\n\n this.groups = new Map((this.report?.filterGroups ?? []).map((group) => [group.id, group]));\n this.pages.set(this.report?.pages ?? []);\n\n const pageCount = this.pages().length;\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.set(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.pages().findIndex((page) => page.id === this.pageId);\n\n if (index > -1) {\n this.activePageIndex.set(index);\n }\n }\n\n if (this.activePageIndex() >= pageCount) {\n this.activePageIndex.set(0);\n }\n\n // Tell the host which page is open whenever that changes — including the\n // FIRST time the report renders, not only when someone clicks a page.\n // Hosts bind things to the open page (the report chat scopes its\n // conversations to it), and without this they would sit on no page at all\n // until the first manual page click.\n const activePageId = this.activePage?.id ?? null;\n if (activePageId !== this._emittedPageId) {\n this._emittedPageId = activePageId;\n this.pageChanged.emit(activePageId);\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.pages()[this.activePageIndex()] ?? null;\n }\n\n // The header/footer bands, in inches (0 = no band).\n public get bands(): ReportHeaderFooter {\n return this.report?.config?.headerFooter ?? { headerHeight: 0, footerHeight: 0 };\n }\n\n public get masterComponents(): ReportComponent[] {\n return this.report?.master?.components ?? [];\n }\n\n // The master draws unless the page hides it — and always while it is the\n // layer being edited, so a page that hides it can still be used to edit it.\n public get isMasterShown(): boolean {\n return this.masterMode() || !this.activePage?.masterHidden;\n }\n\n // Which layer the edit gestures reach.\n public get isPageEditing(): boolean {\n return this.editMode && !this.masterMode();\n }\n\n public get isMasterEditing(): boolean {\n return this.editMode && this.masterMode();\n }\n\n // What {{page.number}} / {{page.name}} / {{report.name}} fill with on the\n // page on screen — the master's footer numbers each page by its position.\n // The same object is handed back until one of the three changes: every text\n // block takes it as an input, and a fresh object per check would make each\n // of them repaint its html on every change-detection pass.\n public get tokens(): TextTokenContext {\n const page = this.activePage;\n const pageNumber = this.activePageIndex() + 1;\n const pageName = page ? this.pageLabel(page, this.activePageIndex()) : '';\n const reportName = this.report?.name ?? '';\n\n const tokens = this._tokens;\n if (tokens?.pageNumber !== pageNumber || tokens.pageName !== pageName || tokens.reportName !== reportName) {\n this._tokens = { pageNumber, pageName, reportName };\n }\n\n return this._tokens;\n }\n\n public toggleMasterMode(): void {\n this.masterMode.update((value) => !value);\n this.selectedComponentId.set(null);\n }\n\n // Drop a text block where it will be found: into the footer (or header) band\n // while editing the header and footer, below the header band on a page. The\n // host re-fetches the report and it appears; double-press opens its editor.\n public addText(): void {\n if (!this.report) {\n return;\n }\n\n const { headerHeight, footerHeight } = this.bands;\n const pageWidth = this.report.pageWidth;\n const pageHeight = this.report.pageHeight;\n const isMaster = this.masterMode();\n\n let geometry = { x: 0.5, y: headerHeight + 0.5, w: Math.min(5, pageWidth - 1), h: 0.8 };\n if (isMaster) {\n const bandHeight = footerHeight || headerHeight || 0.5;\n const y = footerHeight\n ? pageHeight - footerHeight\n : (headerHeight ? 0 : pageHeight - bandHeight);\n geometry = { x: 0.5, y: y + 0.05, w: Math.min(4, pageWidth - 1), h: Math.max(0.3, bandHeight - 0.1) };\n }\n\n this._reportData.addText(this.report.id, {\n ...geometry,\n pageId: isMaster ? undefined : this.activePage?.id,\n })\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this.reportChanged.emit());\n }\n\n // A text block deleted itself from its menu: drop it from whichever layer it\n // was on without re-fetching the report (nothing else depends on it).\n public onComponentRemoved(componentId: number): void {\n const layers = [this.activePage?.components, this.report?.master?.components];\n for (const components of layers) {\n const index = components?.findIndex((component) => component.id === componentId) ?? -1;\n if (index > -1) {\n components.splice(index, 1);\n }\n }\n\n this.selectedComponentId.set(null);\n this.pages.set(this.pages());\n this._message.success('Deleted text');\n }\n\n // Show or hide the header and footer on one page, from its tab's kebab.\n public toggleMasterHidden(page: ReportPage): void {\n const masterHidden = !page.masterHidden;\n\n this._reportData.updatePage(this.report.id, page.id, { masterHidden })\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => {\n page.masterHidden = masterHidden;\n this.pages.set(this.pages());\n this._message.success(masterHidden ? 'Header & footer hidden on this page' : 'Header & footer shown on this page');\n });\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.set(index);\n this.selectedComponentId.set(null);\n\n // Kept in step with the ngOnChanges announcement so the two can't disagree\n // about what the host was last told.\n this._emittedPageId = this.activePage?.id ?? null;\n this.pageChanged.emit(this._emittedPageId);\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.pages.set(this.pages());\n this._message.success('Saved page name');\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.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 pages = this.pages();\n const index = pages.indexOf(page);\n pages.splice(index, 1);\n this.pages.set(pages);\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.set(Math.min(index, pages.length - 1));\n this._previousPageCount = pages.length;\n this.selectedComponentId.set(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 });\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 const pages = this.pages();\n\n moveItemInArray(pages, event.previousIndex, event.currentIndex);\n this.pages.set(pages);\n\n const positions = pages.map((page, order) => {\n page.order = order;\n\n return { pageId: page.id, order };\n });\n\n if (activePage) {\n this.activePageIndex.set(pages.indexOf(activePage));\n }\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.set(componentId);\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.set(scale);\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.pages.set(this.pages());\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 // Flow items only — the header/footer blocks on the master layer are\n // components too, but they are not in the flow.\n const hosts = Array.from(\n this._viewport.nativeElement.querySelectorAll<HTMLElement>('app-report-component.flow-item'),\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, the header/footer band\n // lines, and every sibling's edges + centers — siblings on the SAME layer,\n // since a page component aligns with the page and a header block with the\n // header.\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 const { headerHeight, footerHeight } = this.bands;\n if (headerHeight) {\n horizontal.push(headerHeight);\n }\n if (footerHeight) {\n horizontal.push(this.report.pageHeight - footerHeight);\n }\n\n const isMaster = this.masterComponents.some((component) => component.id === moving.id);\n const siblings = isMaster ? this.masterComponents : (this.activePage?.components ?? []);\n\n for (const component of siblings) {\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 wheel=\"modifier\"\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 [class.master-editing]=\"isMasterEditing\"\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 <!-- The header and footer: the master's components, always freeform,\n drawn under the page's own. Out of the flow (absolute), so a flow\n page's rows are laid out as if it were not there. -->\n @if (isMasterShown && masterComponents.length) {\n <div\n class=\"master-layer\"\n [class.editable]=\"isMasterEditing\">\n @for (component of masterComponents; track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isMasterEditing\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom()\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\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 (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n </div>\n }\n\n <!-- The header and footer bands, as guides while editing. -->\n @if (editMode) {\n @if (bands.headerHeight) {\n <div\n class=\"band band-header\"\n [style.height.px]=\"bands.headerHeight * PX\">\n @if (isMasterEditing) {\n <span class=\"band-label small\">Header</span>\n }\n </div>\n }\n @if (bands.footerHeight) {\n <div\n class=\"band band-footer\"\n [style.height.px]=\"bands.footerHeight * PX\">\n @if (isMasterEditing) {\n <span class=\"band-label small\">Footer</span>\n }\n </div>\n }\n }\n\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]=\"isPageEditing\"\n [layout]=\"'flow'\"\n [zoom]=\"zoom()\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\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 (removed)=\"onComponentRemoved($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]=\"isPageEditing\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom()\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\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 (removed)=\"onComponentRemoved($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 && !masterMode()) {\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 </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 Every page gets a chip, including a lone one: the chip is what tells\n you which page you are on, and a report that hid it left you unable to\n tell page 1 of 1 from a page that failed to load. Deleting the last\n page is refused server-side, so the kebab is safe to expose here. -->\n <div\n class=\"page-tabs\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onPageDropped($event)\">\n @for (page of 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)=\"toggleMasterHidden(page)\">\n {{ page.masterHidden ? 'Show header & footer' : 'Hide header & footer' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"deletePage(page)\">\n Delete\n </ng-template>\n </fs-menu>\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 (Ctrl/Cmd + scroll)\"\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 (Ctrl/Cmd + scroll)\"\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, Component, DestroyRef, EventEmitter, OnInit, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\n\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';\nimport { MatFormField, MatLabel, MatSuffix } from '@angular/material/form-field';\nimport { MatButton } from '@angular/material/button';\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 { FsPrompt } from '@firestitch/prompt';\nimport { FsTabsModule } from '@firestitch/tabs';\n\nimport { Observable } from 'rxjs';\nimport { switchMap, 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 dialog hands back. The Settings tab's Save carries the new\n// `settings`; Delete carries `deleted` and no settings, because the component\n// it was opened for no longer exists. Every other exit (Cancel, Done, Escape,\n// backdrop) closes with no result — filter work is announced as it happens\n// instead, through `filtersChanged`.\nexport interface ComponentSettingsResult {\n settings?: ComponentSettings;\n deleted?: boolean;\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 MatDialogClose,\n MatFormField,\n MatLabel,\n MatSuffix,\n MatButton,\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 readonly sql = signal<string | null>(null);\n // True when the statement is a DERIVED baseline: no filters, the authored\n // grain, times in the report's effective zone. The tab says so, because the\n // numbers on screen come from this statement plus the viewer's own choices\n // and the two can differ.\n public readonly sqlBaseline = signal(false);\n // The zone the statement was compiled in: the report's effective zone, sent\n // with the SQL. A server too old to send it compiled in UTC.\n public readonly sqlTimezone = signal('UTC');\n public readonly sqlError = signal<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 readonly rows = signal<FilterRow[]>([]);\n public readonly columnsError = signal<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 _prompt = inject(FsPrompt);\n private readonly _destroyRef = inject(DestroyRef);\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 // Confirm and delete here, while the dialog is still open, then close with a\n // `deleted` result for the page to act on — the same shape the report\n // settings dialog uses for deleting a report.\n //\n // The confirm says it cannot be undone because, from the UI, it cannot: the\n // row is soft-deleted server-side but nothing here restores a component.\n public delete(): void {\n this._prompt.confirm({\n title: 'Delete Component',\n template: `Are you sure you would like to delete \"${this.component.title || 'this component'}\"? This cannot be undone.`,\n })\n .pipe(\n switchMap(() => this._reportData.deleteComponent(this.report.id, this.component.id)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success('Component deleted');\n this._dialogRef.close({ deleted: true });\n });\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.set(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 });\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.set(preview?.sql ?? null);\n this.sqlBaseline.set(!!preview?.baseline);\n this.sqlTimezone.set(preview?.timezone || 'UTC');\n this.sqlError.set(preview?.error ?? null);\n },\n error: (error) => {\n this.sql.set(null);\n this.sqlError.set(error?.error?.message ?? 'Could not read the component SQL');\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 },\n error: (error) => {\n this.columnsError.set(error?.error?.message ?? 'Could not read the component columns');\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 {{ sqlTimezone() }}.\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 <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>","import {\n ChangeDetectionStrategy, Component, EventEmitter, Input, Output, computed, signal,\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. It shows the zone it is given and never\n// picks one itself: the dialog always seeds the zone the report uses, and that\n// zone is listed even when the browser's list lacks it (some browsers leave\n// 'UTC' out).\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 {\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.set(value);\n this.timezoneChange.emit(value);\n }\n }\n\n public get timezone(): string {\n return this._timezone();\n }\n\n public guid: string = guid();\n public readonly timezones = computed(() => this._supportedTimezones(this._timezone()));\n\n private readonly _timezone = signal<string>('');\n\n // The browser's IANA zone list where available, with the current value\n // prepended when the list lacks it, so the select always shows the zone the\n // report uses.\n private _supportedTimezones(current: string): string[] {\n const intl = Intl as unknown as { supportedValuesOf?: (key: string) => string[] };\n const zones = typeof intl.supportedValuesOf === 'function'\n ? intl.supportedValuesOf('timeZone')\n : [];\n\n return current && !zones.includes(current)\n ? [current, ...zones]\n : zones;\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 { Report } from '../../interfaces/report.interface';\n\n\n// The locale and currency keys for the report settings PUT: each is sent only\n// when the dialog's value differs from the report's stored one ('' = follows\n// the default). An untouched dialog sends neither, so a report that follows the\n// default is never pinned to it, and a stored value the server no longer offers\n// is never sent back to be refused: renaming such a report still saves. A\n// changed value is sent as it is, and '' returns the report to the default.\nexport function reportLocalePatch(\n report: Pick<Report, 'locale' | 'currency'>,\n locale: string,\n currency: string,\n): { locale?: string; currency?: string } {\n return {\n ...(locale !== (report.locale ?? '') ? { locale } : {}),\n ...(currency !== (report.currency ?? '') ? { currency } : {}),\n };\n}\n","import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, computed, 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 { FsSkeletonModule } from '@firestitch/skeleton';\nimport { FsTabsModule } from '@firestitch/tabs';\n\nimport { TimezoneSelectComponent } from '../../components/timezone-select/timezone-select.component';\n\nimport { Observable, forkJoin, of } from 'rxjs';\nimport { catchError, finalize, switchMap, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportValueFormat } from '../../enums/report-value-format.enum';\nimport {\n DAY_SHORT,\n REPORT_FALLBACK_CURRENCY,\n currencyName,\n formatLocalDate,\n formatNumber,\n localeName,\n resolveReportCurrency,\n resolveReportLocale,\n} from '../../format';\nimport {\n FilterGroupDefault,\n Report,\n ReportFilterGroup,\n ReportLocales,\n} from '../../interfaces/report.interface';\nimport { DEFAULT_HEADING_SIZE, HEADER_FOOTER_MAX, PAGE_DIMENSION_MAX, PAGE_DIMENSION_MIN } from '../../layout';\nimport {\n dateFromBound, dateToBound, loadGroupOptions, matchOptions, relativeLabel, resolveOptionValues,\n} from '../../report-filter-items';\n\nimport { reportLocalePatch } from './report-locale-patch';\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 or a stored rolling `relative` preset; select →\n// values; keyword → text). `fetch` loads the select options the same way the\n// report bar does.\ninterface FilterDefaultRow {\n group: ReportFilterGroup;\n label: string;\n start: Date | null;\n end: Date | null;\n // The stored rolling preset (e.g. 'last12Months'). Not authored here: it is\n // carried so an untouched one is sent back as it was, and picked dates or\n // Clear replace it.\n relative: string | null;\n values: { name: string; value: unknown }[];\n value: string;\n fetch: (keyword?: string) => Observable<{ name: string; value: unknown }[]>;\n}\n\n// One entry of the Locale or Currency select. '' is the explicit Default.\ninterface LocaleSelectOption {\n value: string;\n label: string;\n}\n\n// The day the Locale hint writes, a fixed calendar day so the example never\n// changes under the operator.\nconst EXAMPLE_DAY = new Date(2026, 0, 5);\nconst EXAMPLE_AMOUNT = 1234.5;\n\n// 'Canadian French (fr-CA)', 'Canadian Dollar (CAD)': English names whatever\n// the report's locale, with the code that is stored.\nfunction localeLabel(tag: string): string {\n return `${localeName(tag)} (${tag})`;\n}\n\nfunction currencyLabel(code: string): string {\n return `${currencyName(code)} (${code})`;\n}\n\n\n// Report settings, in three tabs:\n// Settings — name + page setup (size in inches, header/footer band depths,\n// 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 FsSkeletonModule,\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 // The header and footer band depths, inches — typed like the page size\n // because fsMaskNumber hands back a string.\n public headerHeight: number | string = 0;\n public footerHeight: number | string = 0;\n public readonly headerFooterMax = HEADER_FOOTER_MAX;\n public layout: 'freeform' | 'flow' = 'freeform';\n // Seeded with the zone the report actually uses: its own stored zone, else\n // the application default the server resolved (effectiveTimezone). Save sends\n // it only when it differs from that effective zone, so opening and saving a\n // report that follows the default never pins it to a zone.\n public timezone = '';\n public headingSize = DEFAULT_HEADING_SIZE;\n\n // The locales and currencies the server offers. null until loaded, and\n // never loaded from a server too old to send effectiveLocale: there the\n // selects stay hidden and the report reads en-US/USD.\n public readonly locales = signal<ReportLocales | null>(null);\n // The report's own locale and currency, '' when it follows the default. Save\n // sends each only when it differs from the stored value.\n public readonly locale = signal('');\n public readonly currency = signal('');\n // The whole form waits behind one skeleton until the filter rows are built\n // and the locale request has settled, so the Settings tab never shows\n // without its Locale and Currency selects. A failed locale request settles\n // too: the two selects stay hidden (locales() is still null) and every other\n // setting stays editable.\n public readonly ready = computed(() => this._filtersReady() && (!this._serverHasLocale || this._localesSettled()));\n\n // An explicit Default ('') naming the locale it stands for, then each offered\n // locale. A stored locale the server no longer offers is listed first, so\n // the select still shows what the report holds.\n public readonly localeOptions = computed<LocaleSelectOption[]>(() => {\n const locales = this.locales();\n if (!locales) {\n return [];\n }\n\n const offered = locales.options.map((option) => option.locale);\n\n return [\n ...this._storedOption(this._data.report.locale, offered, localeLabel),\n { value: '', label: `Default — ${localeName(locales.defaultLocale)}` },\n ...offered.map((tag) => ({ value: tag, label: localeLabel(tag) })),\n ];\n });\n\n // An explicit Default ('') naming the currency the selected locale uses when\n // the report names none, then every currency. A stored code the server no\n // longer offers is listed first.\n public readonly currencyOptions = computed<LocaleSelectOption[]>(() => {\n const locales = this.locales();\n if (!locales) {\n return [];\n }\n\n return [\n ...this._storedOption(this._data.report.currency, locales.currencies, currencyLabel),\n { value: '', label: `Default — ${currencyLabel(this._defaultCurrency())}` },\n ...locales.currencies.map((code) => ({ value: code, label: currencyLabel(code) })),\n ];\n });\n\n // How the report will write an amount and a day once saved: the selected\n // locale and currency, or the defaults they fall back to, e.g.\n // '1 234,50 $ · 5 janv. 2026' in fr-CA.\n public readonly formatExample = computed(() => {\n const locale = resolveReportLocale(this._appliedLocale());\n const currency = resolveReportCurrency(this._appliedCurrency());\n\n return [\n formatNumber(\n EXAMPLE_AMOUNT,\n { format: ReportValueFormat.Currency, precision: 2 },\n { locale, currency, ratioPercent: true },\n ),\n formatLocalDate(EXAMPLE_DAY, locale, DAY_SHORT),\n ].join(' · ');\n });\n\n // The report-level filters and their editable default values (Filters tab).\n public readonly filterRows = signal<FilterDefaultRow[]>([]);\n public readonly relativeLabel = relativeLabel;\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 // Only a server that resolves a report's locale offers the locale list.\n private readonly _serverHasLocale = this._data.report.effectiveLocale !== undefined;\n // True once the locale request has answered, with the list or an error.\n private readonly _localesSettled = signal(false);\n // True once the filter rows are published (see _buildFilterRows).\n private readonly _filtersReady = signal(false);\n\n // The locale the report would be written in: the selected one when the\n // server offers it, else the default (a stored locale it no longer offers\n // falls back to the default, as it does on the server).\n private readonly _appliedLocale = computed(() => {\n const locales = this.locales();\n const locale = this.locale();\n\n return locales?.options.some((option) => option.locale === locale)\n ? locale\n : locales?.defaultLocale ?? '';\n });\n\n // The currency a report in the applied locale uses when it names none.\n private readonly _defaultCurrency = computed(() => {\n const locale = this._appliedLocale();\n\n return this.locales()?.options.find((option) => option.locale === locale)?.defaultCurrency\n ?? REPORT_FALLBACK_CURRENCY;\n });\n\n // The currency the report would label money in: the selected one when the\n // server offers it, else the default.\n private readonly _appliedCurrency = computed(() => {\n const currency = this.currency();\n\n return this.locales()?.currencies.includes(currency)\n ? currency\n : this._defaultCurrency();\n });\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.headerHeight = report.config?.headerFooter?.headerHeight ?? 0;\n this.footerHeight = report.config?.headerFooter?.footerHeight ?? 0;\n this.layout = report.layout ?? 'freeform';\n this.timezone = report.timezone ?? report.effectiveTimezone ?? '';\n this.headingSize = report.config?.styles?.heading?.size ?? DEFAULT_HEADING_SIZE;\n this.locale.set(report.locale ?? '');\n this.currency.set(report.currency ?? '');\n\n this._buildFilterRows(report);\n\n if (this._serverHasLocale) {\n this._reportData.locales()\n .pipe(\n tap((locales) => this.locales.set(locales)),\n catchError(() => of(null)),\n finalize(() => this._localesSettled.set(true)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\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 ...this._timezoneSetting(),\n ...reportLocalePatch(this._data.report, this.locale(), this.currency()),\n styles: { heading: { size: this.headingSize } },\n headerFooter: {\n headerHeight: this._pageDimension(this.headerHeight) || 0,\n footerHeight: this._pageDimension(this.footerHeight) || 0,\n },\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 // Drop the row's stored rolling preset (Clear). A new row object rather than\n // a mutation, so the signal sees the change; the @for tracks group.id, so\n // the row's bindings survive the swap.\n public clearRelative(row: FilterDefaultRow): void {\n this.filterRows.update((rows) => rows.map((item) => (item === row ? { ...item, relative: null } : item)));\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 // The zone for the settings PUT, sent only when it moves the report off the\n // zone it already uses, so an untouched dialog never pins a report that\n // follows the application default. A server too old to send\n // effectiveTimezone gets the zone every time, as it always did.\n private _timezoneSetting(): { timezone?: string } {\n const effectiveTimezone = this._data.report.effectiveTimezone;\n\n return effectiveTimezone === undefined || this.timezone !== effectiveTimezone\n ? { timezone: this.timezone }\n : {};\n }\n\n // The stored value as its own option when the server no longer offers it, so\n // the select names it instead of showing blank. Left as it is, it is never\n // sent (see reportLocalePatch), and the report reads the default meanwhile.\n private _storedOption(\n stored: string | null | undefined,\n offered: string[],\n label: (value: string) => string,\n ): LocaleSelectOption[] {\n return stored && !offered.includes(stored) ? [{ value: stored, label: label(stored) }] : [];\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 relative: groupDefault?.relative ?? null,\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._publishFilterRows(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. When an option\n // list fails to load, the rows publish unresolved: each chip names its id,\n // and an untouched row still saves the stored default unchanged.\n forkJoin(seeded.map((entry) => resolveOptionValues(entry.options$, entry.values)))\n .pipe(\n catchError(() => of(seeded.map((entry) => entry.values.map((value) => ({ name: String(value), value }))))),\n tap((resolved) => {\n resolved.forEach((values, index) => seeded[index].row.values = values);\n this._publishFilterRows(rows);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n private _publishFilterRows(rows: FilterDefaultRow[]): void {\n this.filterRows.set(rows);\n this._filtersReady.set(true);\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). A date range is the picked\n // dates when there are any, else the carried rolling preset, never both: the\n // server refuses a relative preset combined with dates.\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 if (start || end) {\n return { start: start ?? undefined, end: end ?? undefined };\n }\n\n return row.relative ? { relative: row.relative } : 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: empty and undefined keys are dropped so a no-op\n // edit doesn't read as a change. relative is compared like the rest: the row\n // carries it, so an untouched rolling default reads as unchanged.\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 <!-- One skeleton over the whole body until the locale list is in. -->\n <ng-container *fsSkeletonForm=\"ready() || null\">\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 <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout → Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\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 <!--\n How numbers and dates are written (formatting only: no text is\n translated) and which currency money is labeled in. Hidden on a\n server too old to resolve a report's locale.\n -->\n @if (locales()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Locale\n </mat-label>\n <mat-select\n [ngModel]=\"locale()\"\n (ngModelChange)=\"locale.set($event)\"\n name=\"locale\">\n @for (option of localeOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n {{ formatExample() }}\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Currency\n </mat-label>\n <mat-select\n [ngModel]=\"currency()\"\n (ngModelChange)=\"currency.set($event)\"\n name=\"currency\">\n @for (option of currencyOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Names the currency amounts are in; it does not convert them.\n </mat-hint>\n </mat-form-field>\n }\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 <!-- A stored rolling preset cannot be authored here, only\n kept, replaced by picking dates, or cleared. type=\"button\"\n keeps Clear from submitting the form. -->\n @if (row.relative && !row.start && !row.end) {\n <div class=\"fs-row.gap-sm.align-center\">\n <mat-hint class=\"fs-flex\">\n Rolling default: {{ relativeLabel(row.relative) }}. Pick dates to replace it.\n </mat-hint>\n <button\n mat-button\n type=\"button\"\n (click)=\"clearRelative(row)\">\n Clear\n </button>\n </div>\n }\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 </ng-container>\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 { ReportListColumnFormat } from '../enums/report-list-column-format.enum';\nimport {\n DAY_LONG,\n formatLocalDate,\n formatNumber,\n formatReportDate,\n hasNumberFormat,\n resolveReportTimezone,\n} from '../format';\nimport {\n ComponentData,\n ComponentDataState,\n GRANULARITY_OPTIONS,\n ListColumn,\n ListConfig,\n Report,\n ReportComponent,\n ReportFilterGroup,\n ReportFormatContext,\n ReportLocaleTag,\n ReportPage,\n} from '../interfaces/report.interface';\nimport { LIST_TOTAL_LABEL, listHiddenColumns, listTotalsLabelColumn } from '../list-config';\nimport { pivotColumnSpecs } from '../option-builder';\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 // null = its query failed; exports show a note. Always null for a text\n // block, which has no query — see isFailed().\n data: ComponentData | null;\n // The text a list was searched by when it was fetched; absent when its\n // search box was empty, and for every other component.\n search?: string;\n // The config columns a viewer hid on a plain list, which its table leaves\n // out (listColumns); empty for every other component.\n hiddenColumns: string[];\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 // What the numbers are measured in, for the title slide/page: the zone and\n // the currency the server resolved for the report. Each is left out when the\n // server does not send it, rather than a guess that would be wrong whenever\n // the default applies.\n contextLines: string[];\n // How the open report writes its numbers and dates (its locale, currency\n // and percent form), read once so every page of the file agrees.\n formatContext: ReportFormatContext;\n}\n\n// One exported list column: the cell key, its heading and its format, and\n// whether its cells are formatted numbers, which every export right-aligns\n// (header included) as the screen does.\nexport type ExportListColumn = ListColumn & { numeric: boolean };\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// A component's title as an exported file prints it. A searched list says so,\n// since its table holds only the matching rows: 'Orders (matching \"north\")'.\n// An untitled one reads 'Matching \"north\"'. '' when there is nothing to print.\n// Shared by the PDF and the deck, continuation pages included.\nexport function exportTitle(component: ReportComponent, search?: string | null): string {\n const title = component.title ?? '';\n\n if (!search) {\n return title;\n }\n\n return title ? `${title} (matching \"${search}\")` : `Matching \"${search}\"`;\n}\n\n// Whether a tile's query failed. A text block has no query, so it never did.\nexport function isFailed(item: CollectedComponent): boolean {\n return !item.data && item.component.type !== 'text';\n}\n\n// The lines under the report's name on the PDF title page and the title slide:\n// the export date, the active filters, then what the numbers are measured in.\n// The date always leads (the PowerPoint marks that line as written in the\n// report's locale). It is today in the report's zone, the same day its filters\n// resolve \"today\" to, written in the report's locale.\nexport function coverLines(collected: CollectedReport): string[] {\n return [\n formatLocalDate(\n new Date(),\n collected.formatContext.locale,\n DAY_LONG,\n resolveReportTimezone(collected.report),\n ),\n ...collected.filterSummary,\n ...collected.contextLines,\n ];\n}\n\n// An exported list cell, reading like the on-screen cell, through the same\n// functions as the screen: a date column renders in the report's zone and\n// locale, and a column with number-format keys (a cross-tab's cells through\n// its cellFormat) in the report's locale and currency. Any other value goes\n// out verbatim, and an empty one as ''. CSV never comes through here: its\n// values stay raw.\nexport function exportCell(\n value: unknown,\n column: ListColumn,\n timezone: string,\n context: ReportFormatContext,\n): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (column.format === ReportListColumnFormat.Date) {\n return formatReportDate(value, timezone, context.locale);\n }\n\n return hasNumberFormat(column) ? formatNumber(value, column, context, { empty: '' }) : String(value);\n}\n\n// The columns an exported list table draws. A cross-tab's arrive with its\n// rows (the row key first, then one per pivot value), since only the result\n// knows the pivot values, and are built by pivotColumnSpecs() as on screen:\n// headed by its periods in the report's locale, each pivot value formatted by\n// cellFormat. A plain list draws its configured columns but the ones the\n// viewer hid (`hidden`, kept to listHiddenColumns, so never all of them),\n// else every column the query returned, as it came.\nexport function listColumns(\n component: ReportComponent,\n data: ComponentData,\n locale: ReportLocaleTag,\n hidden: readonly string[] = [],\n): ExportListColumn[] {\n const config = (component.config ?? {}) as ListConfig;\n\n if (config.pivotBy?.column) {\n return pivotColumnSpecs(config, data, locale);\n }\n\n if (config.columns?.length) {\n const hiddenNames = listHiddenColumns(config, hidden);\n\n return config.columns\n .filter((column) => !hiddenNames.includes(column.column))\n .map((column) => ({ ...column, numeric: hasNumberFormat(column) }));\n }\n\n return data.columns.map((column) => ({ column, numeric: false }));\n}\n\n// The heading over each column of listColumns(): a plain list's configured\n// label, else its column; a cross-tab's heading from pivotColumnSpecs().\nexport function listHeadings(\n component: ReportComponent,\n data: ComponentData,\n locale: ReportLocaleTag,\n hidden: readonly string[] = [],\n): string[] {\n return listColumns(component, data, locale, hidden).map((column) => column.label || column.column);\n}\n\n// An exported list's totals row, one cell per column of listColumns(): each\n// total written like its column's cells, and LIST_TOTAL_LABEL in the first\n// column when that column holds no total (a cross-tab's row key). null when\n// the list has no totals. The CSV never carries one: its rows stay raw.\nexport function listTotalsRow(\n data: ComponentData,\n columns: readonly ExportListColumn[],\n timezone: string,\n context: ReportFormatContext,\n): string[] | null {\n const totals = data.totals;\n\n if (!totals) {\n return null;\n }\n\n const label = listTotalsLabelColumn(columns, totals);\n\n return columns.map((column) => (column.column === label\n ? LIST_TOTAL_LABEL\n : exportCell(totals[column.column], column, timezone, context)));\n}\n\n// The last row of an exported list table that stops short of its result: how\n// many rows the file leaves out and where the whole set can be had. Each\n// format fetches its own number of rows (PDF_LIST_ROWS, PPTX_LIST_ROWS), and\n// both name what is left with this one sentence.\nexport function moreRowsNotice(remaining: number): string {\n return `… ${remaining} more row(s) — use the component's CSV export for the full dataset`;\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(isFailed))\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 // listRows is how many rows each list fetches: the renderer's own cap, since\n // a PDF table continues onto extra pages and a slide table cannot.\n public collect(report: Report, listRows: number): 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 // Text blocks have nothing to fetch — they ride through with no data. The\n // header/footer (report.master) is read by the renderers straight off the\n // report for the same reason.\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, listRows)\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.getFilterSummary(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 contextLines: this._contextLines(report),\n formatContext: this._filterState.formatContext(),\n };\n }),\n );\n }\n\n // \"Report Period: Jun 12, 2025 – Jun 12, 2026\", \"Region: North, East\" — one\n // line per filter group that has an active session value, then the group-by\n // line. The filter bar as the viewer reads it: the PDF and PowerPoint covers\n // print it, and the report zip export sends it for its notes file. Dates are\n // written in the report's locale, so the notes name the period as the cover\n // does.\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 public getFilterSummary(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 private _componentData(report: Report, component: ReportComponent, listRows: number): Observable<CollectedComponent> {\n if (component.type === 'text') {\n return of({ component, data: null, hiddenColumns: [] });\n }\n\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 // and the viewer's header sort and search, so the table reads in the\n // screen's order and holds the screen's rows.\n //\n // The time-series check deliberately mirrors the server's canonical\n // ReportQueryRunner::_isTimeSeriesChart, so a product pinned to an older\n // framework does not re-bucket a non-time chart.\n const frequency = this._filterState.frequency();\n const isTimeSeries = component.type === 'chart' && component.config?.xAxis?.kind === 'time';\n const search = component.type === 'list'\n ? this._filterState.listSearch(component.id) ?? undefined\n : undefined;\n const state: ComponentDataState = component.type === 'list'\n ? { page: 1, pageSize: listRows, sort: this._filterState.listSort(component.id) ?? undefined, search }\n : (isTimeSeries && frequency ? { frequency } : {});\n // The table leaves out the columns the viewer hid. The rows are fetched\n // whole, as the screen fetches them, and the renderers drop the cells.\n const hiddenColumns = [...this._filterState.hiddenColumns(component.id)];\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 //\n // A search the server could not apply (searchNote: the list has no text\n // column) narrowed nothing, so the item does not carry it.\n return this._reportData.componentData(report.id, component.id, filters, state, true, { handlers: false })\n .pipe(\n map((data: ComponentData): CollectedComponent => (search && !data?.searchNote\n ? { component, data, search, hiddenColumns }\n : { component, data, hiddenColumns })),\n catchError(() => of({ component, data: null, hiddenColumns })),\n );\n }\n\n // The zone the server resolved, as its IANA id, and the currency it says\n // the report's money is in (a label: nothing is converted). Only the\n // server's values are printed: the browser's zone (resolveReportTimezone's\n // fallback for an older server) is not what the numbers were measured in,\n // and an older server names no currency at all.\n private _contextLines(report: Report): string[] {\n return [\n ...(report.effectiveTimezone ? [`Timezone: ${report.effectiveTimezone}`] : []),\n ...(report.effectiveCurrency ? [`Currency: ${report.effectiveCurrency}`] : []),\n ];\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 // reader 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, this._filterState.formatContext().locale) ?? '…';\n }\n}\n","import { ComponentData, ReportComponent, ReportFormatContext } 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. Its numbers and periods are written\n// in the report's format context, as on screen.\nexport async function renderChartImage(\n component: ReportComponent,\n data: ComponentData,\n width: number,\n height: number,\n context: ReportFormatContext,\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, context),\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';\n\nimport { formatNumber, resolveReportTimezone } from '../format';\nimport {\n ComponentData,\n KpiConfig,\n Report,\n ReportComponent,\n ReportFormatContext,\n ReportHeaderFooter,\n ReportPage,\n} from '../interfaces/report.interface';\nimport { ComponentGeometry, DEFAULT_COMPONENT_PADDING, pageGeometry } from '../layout';\nimport {\n DEFAULT_TEXT_COLOR, DEFAULT_TEXT_SIZE, TextParagraph, TextRun, TextTokenContext, textParagraphs,\n} from '../text';\nimport { renderChartImage } from './offscreen-chart';\nimport {\n CollectedComponent, CollectedPage, CollectedReport, coverLines, emptyLabel, exportCell, exportTitle, listColumns,\n listHeadings, listTotalsRow, moreRowsNotice,\n} from './report-export-collector.service';\n\n\n// Inches → points (the PDF unit).\nconst PT = 72;\n\n// Component title strip height, points.\nconst TITLE_H = 18;\n\n// Rows fetched for a list's PDF table. A table that outgrows its box\n// continues onto pages of its own, so this is how far it may run: about 12-15\n// continuation pages on a letter page, and a tenth of the server's 5000-row\n// ceiling. A longer result ends in a moreRowsNotice() row.\nexport const PDF_LIST_ROWS = 500;\n\n// How far a continuation table sits inside the header and footer bands,\n// points. A page with no band (or with the master hidden) keeps\n// NO_BAND_MARGIN from that edge instead.\nconst CONTINUATION_GAP = 0.25 * PT;\nconst NO_BAND_MARGIN = 0.5 * PT;\nconst NO_BANDS: ReportHeaderFooter = { headerHeight: 0, footerHeight: 0 };\n\n// The last row of a list box whose rows carry on past it.\nconst CONTINUED_NOTICE = 'Continued on the following pages';\n\n// A text line's height as a multiple of its largest font size — the canvas\n// stylesheet's line-height, so a block wraps and stacks the same way.\nconst TEXT_LINE_HEIGHT = 1.25;\n\n// How far a list item's text sits from the block's edge, points; the marker\n// hangs in that space.\nconst LIST_INDENT = 16;\n\n// What every drawing step of one export shares, built once in export().\n// Sizes are points.\ninterface PdfExportContext {\n doc: any;\n autoTable: any;\n jsPDF: any;\n report: Report;\n timezone: string;\n formatContext: ReportFormatContext;\n pageW: number;\n pageH: number;\n orientation: 'landscape' | 'portrait';\n}\n\n// Fixed column widths, by column index, in points, and the right alignment of\n// a column of formatted numbers.\ntype PdfColumnStyles = Record<number, { cellWidth: number; halign?: 'right' }>;\n\n// A table body cell: plain text, or a notice row's one cell spanning every\n// column.\ntype PdfTableCell = string | { content: string; colSpan: number; styles: Record<string, unknown> };\n\n// The rows of a list that did not fit its box, carried onto continuation\n// pages after its report page. x and w are the box's, in points, and the\n// column widths and alignments are the ones the on-page table was drawn with,\n// so the table reads as one across pages.\ninterface PdfTableOverflow {\n component: ReportComponent;\n // The text the list was searched by, for the continuation title.\n search?: string;\n head: string[];\n numeric: boolean[];\n rows: string[][];\n omitted: number;\n // The list's totals row, which closes the last continuation page.\n foot: string[] | null;\n x: number;\n w: number;\n columnStyles: PdfColumnStyles;\n}\n\n// Builds the PDF client-side with jspdf. The report's unit is inches and PDFs\n// are points at exactly 72/inch, so each report page becomes one PDF page of\n// the exact physical size and components land at their precise positions.\n// Charts are rendered through an offscreen ECharts instance at 3× pixel\n// ratio — pixel-identical to the screen, crisp at print size — and tables are\n// drawn with jspdf-autotable. Both libraries load lazily into their own chunks.\n//\n// A list table is fitted to its box by laying it out first, never by a\n// row-height estimate, so it cannot spill past the box. The rows that do not\n// fit continue on pages of their own after the report page, under the same\n// header/footer and with the same column widths, up to PDF_LIST_ROWS; a\n// longer result ends in a row pointing to the component's CSV export.\n@Injectable()\nexport class ReportPdfService {\n\n public async export(collected: CollectedReport): Promise<void> {\n const context = await this._context(collected);\n\n this._titlePage(context.doc, collected, context.pageW, context.pageH);\n\n // The physical page number {{page.number}} prints: report pages and\n // their continuation pages alike, the title page not counted.\n let pageNumber = 0;\n\n for (const [index, collectedPage] of collected.pages.entries()) {\n const overflows: PdfTableOverflow[] = [];\n pageNumber += 1;\n\n await this._renderPage(context, collectedPage, index, pageNumber, overflows);\n\n // Each continuation appends its pages at the end of the document, so\n // two lists that overflowed on one page follow it back to back.\n for (const overflow of overflows) {\n pageNumber = this._renderContinuation(context, collectedPage.page, index, pageNumber, overflow);\n }\n }\n\n context.doc.save(`${this._slug(collected.report.name)}.pdf`);\n }\n\n private async _context(collected: CollectedReport): Promise<PdfExportContext> {\n const report = collected.report;\n const { jsPDF } = await import('jspdf');\n const autoTable = (await import('jspdf-autotable')).default;\n\n const pageW = report.pageWidth * PT;\n const pageH = report.pageHeight * PT;\n const orientation = pageW >= pageH ? 'landscape' : 'portrait';\n\n return {\n doc: new jsPDF({ orientation, unit: 'pt', format: [pageW, pageH] }),\n autoTable,\n jsPDF,\n report,\n timezone: resolveReportTimezone(report),\n formatContext: collected.formatContext,\n pageW,\n pageH,\n orientation,\n };\n }\n\n // One report page: the header and footer first, under the page's own\n // components. A list that outgrows its box leaves its remaining rows in\n // overflows.\n private async _renderPage(\n context: PdfExportContext,\n collectedPage: CollectedPage,\n index: number,\n pageNumber: number,\n overflows: PdfTableOverflow[],\n ): Promise<void> {\n const { doc, report } = context;\n const geometry = pageGeometry(report, collectedPage.page);\n const tokens = this._tokens(report, collectedPage.page, index, pageNumber);\n\n doc.addPage([context.pageW, context.pageH], context.orientation);\n this._renderMaster(context, collectedPage.page, tokens);\n\n for (const item of collectedPage.components) {\n const box = geometry.get(item.component.id);\n\n if (item.component.type === 'text') {\n this._renderText(doc, item.component, box ?? item.component, tokens);\n } else {\n await this._renderComponent(context, item, overflows, box);\n }\n }\n }\n\n private _renderMaster(context: PdfExportContext, page: ReportPage, tokens: TextTokenContext): void {\n if (page.masterHidden) {\n return;\n }\n\n for (const component of context.report.master?.components ?? []) {\n this._renderText(context.doc, component, component, tokens);\n }\n }\n\n private _titlePage(doc: any, collected: CollectedReport, pageW: number, pageH: number): void {\n doc.setFont('helvetica', 'bold');\n doc.setFontSize(28);\n doc.setTextColor('#1f2933');\n doc.text(collected.report.name, 40, pageH * 0.35);\n\n doc.setFont('helvetica', 'normal');\n doc.setFontSize(11);\n doc.setTextColor('#52606d');\n\n doc.text(coverLines(collected).map((line) => this._pdfText(line)), 40, pageH * 0.35 + 26);\n }\n\n // A text block, laid out by hand: jsPDF draws strings, not rich text, so each\n // paragraph's runs are broken into words, wrapped to the block's width and\n // drawn word by word in their own font, size and color. Lines past the\n // block's height are dropped — the canvas clips the block there too.\n private _renderText(doc: any, component: ReportComponent, box: ComponentGeometry, tokens: TextTokenContext): void {\n const padding = component.config?.padding;\n const inset = (value: number | undefined) => (value ?? DEFAULT_COMPONENT_PADDING) * PT;\n\n const left = box.x * PT + inset(padding?.left);\n const top = box.y * PT + inset(padding?.top);\n const width = box.w * PT - inset(padding?.left) - inset(padding?.right);\n const bottom = (box.y + box.h) * PT - inset(padding?.bottom);\n\n let cursorY = top;\n let listNumber = 0;\n\n for (const paragraph of textParagraphs(component.config?.html ?? '', tokens)) {\n listNumber = paragraph.bullet === 'number' ? listNumber + 1 : 0;\n const indent = paragraph.bullet ? LIST_INDENT : 0;\n const lines = this._wrap(doc, paragraph, width - indent);\n\n lines.forEach((line, lineIndex) => {\n const size = Math.max(...line.map((word) => word.size), paragraph.runs[0]?.fontSize ?? DEFAULT_TEXT_SIZE);\n const lineHeight = size * TEXT_LINE_HEIGHT;\n if (cursorY + lineHeight > bottom + 0.5) {\n cursorY = Infinity;\n\n return;\n }\n\n const baseline = cursorY + size;\n const lineWidth = line.reduce((sum, word) => sum + word.width, 0);\n let x = left + indent + this._alignOffset(paragraph.align, width - indent, lineWidth);\n\n if (lineIndex === 0 && paragraph.bullet) {\n this._font(doc, line[0]?.run ?? { text: '' }, size);\n doc.text(paragraph.bullet === 'number' ? `${listNumber}.` : '•', left, baseline);\n }\n\n for (const word of line) {\n this._drawWord(doc, word, x, baseline);\n x += word.width;\n }\n\n cursorY += lineHeight;\n });\n\n if (cursorY === Infinity) {\n break;\n }\n\n // An empty paragraph is still a line.\n if (!lines.length) {\n cursorY += DEFAULT_TEXT_SIZE * TEXT_LINE_HEIGHT;\n }\n }\n }\n\n // Break a paragraph's runs into lines of measured words that fit the width.\n // A word keeps its trailing space so spacing survives run boundaries.\n private _wrap(doc: any, paragraph: TextParagraph, width: number): { run: TextRun; text: string; size: number; width: number }[][] {\n const lines: { run: TextRun; text: string; size: number; width: number }[][] = [];\n let line: { run: TextRun; text: string; size: number; width: number }[] = [];\n let lineWidth = 0;\n\n for (const run of paragraph.runs) {\n const size = run.fontSize ?? DEFAULT_TEXT_SIZE;\n this._font(doc, run, size);\n\n for (const text of run.text.match(/\\S+\\s*|\\s+/g) ?? []) {\n const wordWidth = doc.getTextWidth(text);\n\n if (line.length && lineWidth + wordWidth - this._trailingSpace(doc, text) > width) {\n lines.push(line);\n line = [];\n lineWidth = 0;\n }\n\n line.push({ run, text, size, width: wordWidth });\n lineWidth += wordWidth;\n }\n }\n\n if (line.length) {\n lines.push(line);\n }\n\n return lines;\n }\n\n private _drawWord(doc: any, word: { run: TextRun; text: string; size: number; width: number }, x: number, baseline: number): void {\n const run = word.run;\n\n if (run.highlight) {\n doc.setFillColor(run.highlight);\n doc.rect(x, baseline - word.size * 0.9, word.width, word.size * 1.15, 'F');\n }\n\n this._font(doc, run, word.size);\n doc.text(word.text, x, baseline);\n\n const color = run.color ?? DEFAULT_TEXT_COLOR;\n const inkWidth = word.width - this._trailingSpace(doc, word.text);\n if (run.underline) {\n doc.setDrawColor(color);\n doc.setLineWidth(word.size / 16);\n doc.line(x, baseline + word.size * 0.12, x + inkWidth, baseline + word.size * 0.12);\n }\n if (run.strike) {\n doc.setDrawColor(color);\n doc.setLineWidth(word.size / 16);\n doc.line(x, baseline - word.size * 0.3, x + inkWidth, baseline - word.size * 0.3);\n }\n\n if (run.link) {\n doc.link(x, baseline - word.size, inkWidth, word.size * 1.2, { url: run.link });\n }\n }\n\n // jsPDF's standard fonts are Helvetica, Times and Courier; a block's face is\n // mapped onto whichever of the three it resembles.\n private _font(doc: any, run: TextRun, size: number): void {\n const face = (run.fontFace ?? '').toLowerCase();\n const family = /courier|mono/.test(face)\n ? 'courier'\n : (/times|georgia|serif/.test(face) && !face.includes('sans') ? 'times' : 'helvetica');\n const style = run.bold && run.italic\n ? 'bolditalic'\n : (run.bold ? 'bold' : (run.italic ? 'italic' : 'normal'));\n\n doc.setFont(family, style);\n doc.setFontSize(size);\n doc.setTextColor(run.color ?? DEFAULT_TEXT_COLOR);\n }\n\n private _trailingSpace(doc: any, text: string): number {\n const trailing = text.length - text.trimEnd().length;\n\n return trailing ? doc.getTextWidth(' ') * trailing : 0;\n }\n\n private _alignOffset(align: TextParagraph['align'], width: number, lineWidth: number): number {\n switch (align) {\n case 'center':\n return Math.max(0, (width - lineWidth) / 2);\n case 'right':\n return Math.max(0, width - lineWidth);\n default:\n return 0;\n }\n }\n\n // What a text block's tokens fill with on this page. The number is the\n // physical page among the report's pages, continuation pages included — the\n // title page is not a report page. The name stays the report page's, so a\n // continuation page is named for the page its table started on.\n private _tokens(report: Report, page: ReportPage, index: number, pageNumber: number): TextTokenContext {\n return {\n pageNumber,\n pageName: page.name || `Page ${index + 1}`,\n reportName: report.name,\n };\n }\n\n private async _renderComponent(\n context: PdfExportContext,\n item: CollectedComponent,\n overflows: PdfTableOverflow[],\n geometry?: ComponentGeometry,\n ): Promise<void> {\n const { doc } = context;\n const component = item.component;\n // Geometry arrives in inches (flow layout pre-resolved); the PDF draws in\n // points.\n const inches = geometry ?? component;\n const x = inches.x * PT;\n const y = inches.y * PT;\n const w = inches.w * PT;\n const h = inches.h * PT;\n\n const title = exportTitle(component, item.search);\n if (title) {\n this._componentTitle(doc, title, x, y, w);\n }\n\n const bodyY = y + TITLE_H;\n const bodyH = Math.max(20, h - TITLE_H);\n\n if (!item.data || !item.data.rows?.length) {\n this._boxNote(doc, emptyLabel(item), x, bodyY, w, bodyH);\n\n return;\n }\n\n switch (component.type) {\n case 'chart': {\n const image = await renderChartImage(component, item.data, w, bodyH, context.formatContext);\n doc.addImage(image, 'PNG', x, bodyY, w, bodyH);\n break;\n }\n case 'list':\n this._renderTable(context, item, x, bodyY, w, bodyH, overflows);\n break;\n case 'kpi':\n this._renderKpi(context, component, item.data, x, bodyY, w, bodyH);\n break;\n }\n }\n\n // The bold strip over a component, and over each of its continuation pages.\n private _componentTitle(doc: any, title: string, x: number, y: number, w: number): void {\n doc.setFont('helvetica', 'bold');\n doc.setFontSize(9);\n doc.setTextColor('#1f2933');\n doc.text(title, x, y + 10, { maxWidth: w });\n }\n\n // An italic grey line centered in a component's body, for a body that holds\n // something other than its content.\n private _boxNote(doc: any, text: string, x: number, y: number, w: number, h: number): void {\n doc.setFont('helvetica', 'italic');\n doc.setFontSize(9);\n doc.setTextColor('#7b8794');\n doc.text(text, x + w / 2, y + h / 2, { align: 'center' });\n }\n\n // A list's on-page table. All of its fetched rows are laid out once to learn\n // how many the box holds; when they do not all fit, the box's last row says\n // the table continues and the rest go to overflows for continuation pages.\n // A box too short for even the head carries the notice as a line instead.\n // A totals row closes the table once: in the box when every row fits it,\n // else after the last continuation row. Points throughout.\n private _renderTable(\n context: PdfExportContext,\n item: CollectedComponent,\n x: number, y: number, w: number, h: number,\n overflows: PdfTableOverflow[],\n ): void {\n const { component, search, hiddenColumns } = item;\n const data = item.data as ComponentData;\n const head = listHeadings(component, data, context.formatContext.locale, hiddenColumns)\n .map((heading) => this._pdfText(heading));\n const { cells, numeric, foot } = this._tableCells(context, component, data, hiddenColumns);\n const omitted = Math.max(0, (data.paging?.total ?? cells.length) - cells.length);\n const bottom = context.pageH - (y + h);\n const { fit, columnStyles } = this._measure(context, head, cells, numeric, foot, x, y, w, bottom);\n\n if (fit === cells.length && omitted === 0) {\n this._drawTable(\n context,\n this._tableOptions(context, head, numeric, cells, x, y, w, bottom, columnStyles, foot),\n );\n\n return;\n }\n\n // The notice takes the place of the last row that fit, so that row moves\n // to the continuation. omitted > 0 means a full PDF_LIST_ROWS fetch, which\n // never fits one box, so the CSV notice always lands on a continuation\n // page.\n const kept = Math.max(0, fit - 1);\n overflows.push({ component, search, head, numeric, rows: cells.slice(kept), omitted, foot, x, w, columnStyles });\n\n if (fit >= 1) {\n const body = [...cells.slice(0, kept), this._noticeRow(CONTINUED_NOTICE, head.length, true)];\n this._drawTable(context, this._tableOptions(context, head, numeric, body, x, y, w, bottom, columnStyles));\n } else {\n this._boxNote(context.doc, CONTINUED_NOTICE, x, y, w, h);\n }\n }\n\n // Each fetched row as the strings its table cells print, in the report's\n // zone, locale and currency, which columns hold formatted numbers, and the\n // totals row (null without one). The columns the viewer hid are left out.\n private _tableCells(\n context: PdfExportContext,\n component: ReportComponent,\n data: ComponentData,\n hiddenColumns: readonly string[],\n ): { cells: string[][]; numeric: boolean[]; foot: string[] | null } {\n const columns = listColumns(component, data, context.formatContext.locale, hiddenColumns);\n const cells = data.rows.map((row) => columns.map((column) => this._pdfText(\n exportCell(row[column.column], column, context.timezone, context.formatContext),\n )));\n const foot = listTotalsRow(data, columns, context.timezone, context.formatContext);\n\n return {\n cells,\n numeric: columns.map((column) => column.numeric),\n foot: foot ? foot.map((cell) => this._pdfText(cell)) : null,\n };\n }\n\n // The autoTable options every list table shares: the dry run, the on-page\n // draw and the continuation pages, so the three lay a table out alike. The\n // font is named rather than inherited, since the doc carries whatever the\n // last text drawn left set. bottom is the margin under the table, points.\n //\n // A column of formatted numbers is right-aligned, its heading and total\n // too: the body through columnStyles, which autoTable applies to body cells\n // only, and the heading and total through the didParseCell hook, on every\n // page the heading repeats. A totals row (foot) prints once, under the\n // table's last row, bold on the border gray.\n private _tableOptions(\n context: PdfExportContext,\n head: string[],\n numeric: boolean[],\n body: PdfTableCell[][],\n x: number, startY: number, w: number, bottom: number,\n columnStyles?: PdfColumnStyles,\n foot?: string[] | null,\n ): Record<string, unknown> {\n return {\n theme: 'grid',\n head: [head],\n body,\n startY,\n margin: { left: x, right: context.pageW - x - w, bottom },\n tableWidth: w,\n rowPageBreak: 'avoid',\n styles: { font: 'helvetica', fontStyle: 'normal', fontSize: 8, cellPadding: 3, textColor: '#1f2933' },\n headStyles: { fillColor: '#4e79a7', textColor: '#ffffff', fontStyle: 'bold' },\n alternateRowStyles: { fillColor: '#f5f7fa' },\n ...(columnStyles ? { columnStyles } : {}),\n ...(foot\n ? {\n foot: [foot],\n showFoot: 'lastPage',\n footStyles: { fillColor: '#e4e7eb', textColor: '#1f2933', fontStyle: 'bold' },\n }\n : {}),\n didParseCell: (hook: any) => {\n if ((hook.section === 'head' || hook.section === 'foot') && numeric[hook.column.index]) {\n hook.cell.styles.halign = 'right';\n }\n },\n };\n }\n\n // A notice as a table row: one italic grey cell spanning every column. A\n // single-line notice is ellipsized at the box's width and keeps the data\n // cells' font size and padding, so it is never taller than the data row\n // whose place it takes.\n private _noticeRow(text: string, span: number, singleLine: boolean): PdfTableCell[] {\n return [{\n content: text,\n colSpan: span,\n // Left-aligned whatever the first column is: a spanned cell otherwise\n // takes columnStyles[0], right-aligned when that column is numeric.\n styles: {\n fontStyle: 'italic',\n textColor: '#7b8794',\n halign: 'left',\n ...(singleLine ? { overflow: 'ellipsize' } : {}),\n },\n }];\n }\n\n // Lays every fetched row out once on a scratch document of the same page\n // size, with the options the real draw uses, and reads back how many body\n // rows the box's page holds (fit) and the column widths autoTable chose,\n // with each numeric column's right alignment merged in, so the on-page\n // table and its continuation pages carry both. The totals row is laid out\n // too, so the widths hold it, and a table whose rows fit the box but whose\n // totals row does not moves its last row on. fit 0 means not even one\n // body row fits under the head (or the head itself did not fit): autoTable\n // moved to a new page before drawing. The real document is untouched.\n private _measure(\n context: PdfExportContext,\n head: string[],\n cells: string[][],\n numeric: boolean[],\n foot: string[] | null,\n x: number, y: number, w: number, bottom: number,\n ): { fit: number; columnStyles: PdfColumnStyles } {\n const scratch = new context.jsPDF({\n unit: 'pt',\n format: [context.pageW, context.pageH],\n orientation: context.orientation,\n });\n let fit = 0;\n\n context.autoTable(scratch, {\n ...this._tableOptions(context, head, numeric, cells, x, y, w, bottom, undefined, foot),\n didDrawCell: (hook: any) => {\n if (hook.section === 'body' && scratch.getCurrentPageInfo().pageNumber === 1) {\n fit = Math.max(fit, hook.row.index + 1);\n }\n },\n });\n\n const columns: { width: number }[] = scratch.lastAutoTable.columns;\n const columnStyles: PdfColumnStyles = {};\n columns.forEach((column, index) => {\n columnStyles[index] = numeric[index]\n ? { cellWidth: column.width, halign: 'right' }\n : { cellWidth: column.width };\n });\n\n // A row taller than a whole page is split rather than moved, so a last\n // row that started on the first page can still have run past it.\n if (fit === cells.length && scratch.getNumberOfPages() > 1) {\n fit -= 1;\n }\n\n return { fit, columnStyles };\n }\n\n // Draws an on-page table, then removes any page the draw added. That should\n // never happen: the measured fit, the identical column widths and a\n // single-line notice keep the table inside its box. The check exists so a\n // stray page can never catch the report page's remaining components.\n private _drawTable(context: PdfExportContext, options: Record<string, unknown>): void {\n const { doc } = context;\n const page = doc.getCurrentPageInfo().pageNumber;\n const pages = doc.getNumberOfPages();\n\n context.autoTable(doc, options);\n\n while (doc.getNumberOfPages() > pages) {\n doc.deletePage(doc.getNumberOfPages());\n }\n\n doc.setPage(page);\n }\n\n // The rows of one list that did not fit its box, on pages appended after\n // the report page, each with the page's header and footer, the table's\n // title and its head again. The table sits CONTINUATION_GAP inside the\n // bands. Returns the physical page counter after these pages.\n private _renderContinuation(\n context: PdfExportContext,\n page: ReportPage,\n index: number,\n pageNumber: number,\n overflow: PdfTableOverflow,\n ): number {\n const { doc, report } = context;\n const bands = page.masterHidden ? NO_BANDS : report.config?.headerFooter ?? NO_BANDS;\n const top = this._continuationMargin(bands.headerHeight);\n const bottom = this._continuationMargin(bands.footerHeight);\n const { x, w } = overflow;\n const body: PdfTableCell[][] = overflow.omitted > 0\n ? [...overflow.rows, this._noticeRow(moreRowsNotice(overflow.omitted), overflow.head.length, false)]\n : overflow.rows;\n let counter = pageNumber;\n\n doc.addPage([context.pageW, context.pageH], context.orientation);\n context.autoTable(doc, {\n ...this._tableOptions(\n context, overflow.head, overflow.numeric, body, x, top + TITLE_H, w, bottom, overflow.columnStyles,\n overflow.foot,\n ),\n margin: { top: top + TITLE_H, bottom, left: x, right: context.pageW - x - w },\n showHead: 'everyPage',\n // Fires on every page the table draws on, the first included.\n willDrawPage: () => {\n counter += 1;\n this._renderMaster(context, page, this._tokens(report, page, index, counter));\n this._componentTitle(doc, this._continuedTitle(overflow.component, overflow.search), x, top, w);\n },\n });\n\n return counter;\n }\n\n // The margin a continuation table keeps from one edge: inside the band when\n // the page has one.\n private _continuationMargin(band: number): number {\n return band ? band * PT + CONTINUATION_GAP : NO_BAND_MARGIN;\n }\n\n private _continuedTitle(component: ReportComponent, search?: string): string {\n const title = exportTitle(component, search);\n\n return title ? `${title} (continued)` : 'Continued';\n }\n\n private _renderKpi(\n context: PdfExportContext,\n component: ReportComponent,\n data: ComponentData,\n x: number, y: number, w: number, h: number,\n ): void {\n const { doc } = context;\n const config = component.config as KpiConfig;\n const row = data.rows[0] ?? {};\n const column = config.measure?.column ?? Object.keys(row)[0];\n const value = this._pdfText(formatNumber(row[column], config.measure, context.formatContext, { empty: '—' }));\n\n doc.setFont('helvetica', 'bold');\n doc.setFontSize(26);\n doc.setTextColor('#1f2933');\n doc.text(value, x + w / 2, y + h / 2, { align: 'center' });\n\n if (config.measure?.label) {\n doc.setFont('helvetica', 'normal');\n doc.setFontSize(9);\n doc.setTextColor('#7b8794');\n doc.text(config.measure.label, x + w / 2, y + h / 2 + 16, { align: 'center' });\n }\n }\n\n // A formatted value as jsPDF can draw it. Its standard fonts write text in\n // WinAnsi, which has the no-break space (U+00A0, fr-CA's digit grouping) but\n // not the narrow one (U+202F, which other locales group and space with) or the\n // minus sign (U+2212, some locales' negative sign): either would print as\n // stray glyphs. The narrow space becomes a no-break space, so a number still\n // never wraps across a line, and the minus sign a hyphen.\n private _pdfText(text: string): string {\n return text.replace(/\\u202F/g, '\\u00A0').replace(/\\u2212/g, '-');\n }\n\n private _slug(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'report';\n }\n}\n","import { Injectable } from '@angular/core';\n\nimport { ReportChartDataLabels } from '../enums/report-chart-data-labels.enum';\nimport { ReportChartDateLabel } from '../enums/report-chart-date-label.enum';\nimport { ReportChartLineStyle } from '../enums/report-chart-line-style.enum';\nimport { ReportChartMarkStat } from '../enums/report-chart-mark-stat.enum';\nimport { ReportListColumnFormat } from '../enums/report-list-column-format.enum';\nimport {\n axisNumberFormat,\n chartAxisFormatCode,\n chartValuePeak,\n formatNumber,\n hasNumberFormat,\n numberFormatCode,\n resolveChartNumberFormat,\n resolveReportTimezone,\n} from '../format';\nimport {\n ChartConfig,\n ChartGranularity,\n ChartMeasure,\n ChartValueAxis,\n ComponentData,\n LegendPosition,\n KpiConfig,\n NumberFormatSpec,\n Report,\n ReportComponent,\n ReportFormatContext,\n ReportLocaleTag,\n ReportPage,\n WaterfallStepKind,\n} from '../interfaces/report.interface';\nimport { ComponentGeometry, DEFAULT_COMPONENT_PADDING, pageGeometry } from '../layout';\nimport { listTotalsLabelColumn } from '../list-config';\nimport { DEFAULT_TEXT_COLOR, DEFAULT_TEXT_SIZE, TextTokenContext, textParagraphs } from '../text';\nimport {\n chartDateLabel,\n chartReferences,\n colorByValues,\n DrawnReference,\n drawsStatLines,\n ExtractedChartSeries,\n extractChartSeries,\n extractWaterfall,\n formatPeriodLabel,\n isColorBy,\n measureLineStyle,\n measureMarkStat,\n PERCENT_AXIS_INTERVAL,\n PERCENT_AXIS_MAX,\n percentAxisMin,\n PercentShares,\n percentStackedShares,\n referencePeak,\n resolveLegendPosition,\n seriesAxisIndexes,\n seriesHex,\n seriesStat,\n seriesTypes,\n spansMultipleYears,\n STAT_LABEL,\n ValueAxisIndex,\n valueAxisRange,\n WaterfallStep,\n} from '../option-builder';\nimport { REPORT_CHART_COLORS, REPORT_REFERENCE_COLOR, REPORT_WATERFALL_COLORS } from '../theme/palette';\nimport {\n CollectedComponent, CollectedReport, coverLines, emptyLabel, exportCell, exportTitle, listColumns, listHeadings,\n listTotalsRow, moreRowsNotice,\n} from './report-export-collector.service';\n\n\n// Component title strip height on the slide, inches.\nconst TITLE_H = 0.28;\n// Approximate table row height, inches — drives the rows-that-fit cap.\nconst SLIDE_ROW_H = 0.26;\n\n// Rows fetched for a list's slide table. A slide table never continues onto\n// another slide, so this only has to cover the rows a box can show; the\n// moreRowsNotice() row names the rest.\nexport const PPTX_LIST_ROWS = 100;\n\n// Our legend positions mapped to pptxgenjs's single-letter legendPos codes.\n// 'hidden' has no slot — showLegend is turned off instead — so it falls back\n// to top.\nconst PPTX_LEGEND_POS: Record<LegendPosition, 't' | 'b' | 'l' | 'r'> = {\n top: 't',\n bottom: 'b',\n left: 'l',\n right: 'r',\n hidden: 't',\n};\n\n// What a waterfall's series are called in PowerPoint's data sheet and on hover.\n// The legend stays off, as it does on screen, unless the chart draws\n// references, which only the legend can name in PowerPoint.\nconst WATERFALL_SERIES_NAMES: Record<WaterfallStepKind, string> = {\n rise: 'Increase',\n fall: 'Decrease',\n total: 'Total',\n};\n\n// A null is a period with no value. The screen breaks the line there, and\n// pptxgenjs's default ('span') would draw straight across it. The setting is\n// chart-level, so a combo's every type inherits it through the chart options.\nconst BLANKS_AS_GAPS = { displayBlanksAs: 'gap' } as const;\n\n// The axis label and title sizes every chart with axes shares, whichever axis\n// they land on.\nconst AXIS_FONT_SIZES = { catAxisLabelFontSize: 9, valAxisLabelFontSize: 9, valAxisTitleFontSize: 10 } as const;\n\n// A line style as PowerPoint's preset dash (a:prstDash). pptxgenjs writes it\n// on line series only, so an area is never dashed.\nconst PPTX_LINE_DASH: Record<ReportChartLineStyle, string> = {\n [ReportChartLineStyle.Solid]: 'solid',\n [ReportChartLineStyle.Dashed]: 'dash',\n [ReportChartLineStyle.Dotted]: 'sysDot',\n};\n\n// A line's markers, as on screen: a dot the screen's size on each point.\nconst PPTX_LINE_SYMBOL_SIZE = 6;\n\n// A 100% stacked chart's share axis: whole percentages. The shares are\n// ratios, so '0%' is right whatever the report's percentFormat.\nconst PPTX_PERCENT_FORMAT_CODE = '0%';\n\n// The size of a chart's data labels, a step under the axis labels, as on\n// screen.\nconst PPTX_DATA_LABEL_FONT_SIZE = 8;\n\n// The most categories an 'auto' data-labeled chart labels in PowerPoint,\n// which cannot hide the labels that overlap: past this many, it labels none.\nexport const PPTX_AUTO_LABEL_MAX_POINTS = 24;\n\n// A reference or statistic line's width in points: a hairline beside the\n// series, as on screen.\nconst PPTX_CONSTANT_LINE_SIZE = 1;\n\n// What the upper edge of a reference band is called in the data sheet and the\n// legend, after the band's own label on its lower edge.\nconst PPTX_BAND_UPPER_SUFFIX = ' (upper)';\n\n// Where the legend of a chart with reference or statistic lines sits when\n// the config does not pin it: the one place PowerPoint names those lines.\nconst PPTX_CONSTANT_LEGEND: LegendPosition = 'top';\n\n// One native chart series: its name, its fill and its value per category. A\n// null is a blank point: a gap in every axis chart, not only the waterfall,\n// and a zero where bars stack.\ninterface PptxChartSeries {\n name: string;\n color: string;\n values: (number | null)[];\n}\n\n// One native chart of a PowerPoint chart: the type it draws, which of the\n// chart data's series it holds (by index), whether they plot against the\n// secondary value axis, and the options laid over the chart's for it alone.\ninterface PptxEntry {\n type: string;\n indexes: number[];\n secondary: boolean;\n options: Record<string, unknown>;\n}\n\n// A line PowerPoint draws at one value the whole width of the plot, as a\n// series of its own: a reference line, one edge of a reference band, or a\n// measure's statistic line. pptxgenjs has no markLine or markArea.\ninterface PptxConstantLine {\n name: string;\n value: number;\n color: string;\n secondary: boolean;\n}\n\n// The options of one run of PowerPoint text. PowerPoint proofs every run in its\n// language, and pptxgenjs writes en-US for a run that names none. A run whose\n// whole text is a value written in the report's locale (a KPI value, a date\n// cell, the cover's date) passes that locale, so a French date is not marked\n// as misspelled English. Authored and interface text (titles, labels,\n// headings, filter lines, notices) passes none and keeps the default, so an\n// English title in a French report is never proofed as French.\nexport function pptxRunOptions(\n options: Record<string, unknown>,\n valueLocale?: ReportLocaleTag,\n): Record<string, unknown> {\n return valueLocale ? { ...options, lang: valueLocale } : options;\n}\n\n// Builds the PowerPoint deck client-side with pptxgenjs. Charts are NATIVE\n// editable PowerPoint charts (slide.addChart writes real chart XML with an\n// embedded data workbook — \"Edit Data\" works), never images. The page IS the\n// slide: the report's unit is inches — exactly PowerPoint's unit — so the\n// layout and every component position transfer with no conversion at all.\n// pptxgenjs is loaded lazily so it lives in its own webpack chunk.\n@Injectable()\nexport class ReportPptxService {\n\n public async export(collected: CollectedReport): Promise<void> {\n const PptxGenJS = (await import('pptxgenjs')).default;\n\n const report = collected.report;\n const pageW = report.pageWidth;\n const pageH = report.pageHeight;\n\n const pptx = new PptxGenJS();\n pptx.defineLayout({ name: 'REPORT', width: pageW, height: pageH });\n pptx.layout = 'REPORT';\n pptx.title = report.name;\n\n this._titleSlide(pptx, collected, pageW, pageH);\n\n const timezone = resolveReportTimezone(report);\n const context = collected.formatContext;\n\n collected.pages.forEach((collectedPage, index) => {\n const slide = pptx.addSlide();\n const geometry = pageGeometry(report, collectedPage.page);\n const tokens = this._tokens(report, collectedPage.page, index);\n\n // The header and footer first, so the page's own components sit on top\n // of them exactly as on the canvas.\n if (!collectedPage.page.masterHidden) {\n for (const component of report.master?.components ?? []) {\n this._renderText(slide, component, component, tokens);\n }\n }\n\n for (const item of collectedPage.components) {\n const box = geometry.get(item.component.id);\n\n if (item.component.type === 'text') {\n this._renderText(slide, item.component, box ?? item.component, tokens);\n } else {\n this._renderComponent(pptx, slide, item, timezone, context, box);\n }\n }\n });\n\n await pptx.writeFile({ fileName: `${this._slug(report.name)}.pptx` });\n }\n\n private _titleSlide(pptx: any, collected: CollectedReport, pageW: number, pageH: number): void {\n const slide = pptx.addSlide();\n\n slide.addText(collected.report.name, {\n x: 0.5, y: pageH * 0.3, w: pageW - 1, h: 0.8,\n fontSize: 30, bold: true, color: '1F2933',\n });\n\n // coverLines() leads with the export date, the one line written in the\n // report's locale; the filter and context lines are interface text.\n const lines = coverLines(collected);\n const runs = lines.map((line, index) => ({\n text: line,\n options: pptxRunOptions(\n { breakLine: index < lines.length - 1 },\n index === 0 ? collected.formatContext.locale : undefined,\n ),\n }));\n\n slide.addText(runs, {\n x: 0.5, y: pageH * 0.3 + 0.9, w: pageW - 1, h: Math.max(0.4, lines.length * 0.25),\n fontSize: 12, color: '52606D',\n });\n }\n\n // A text block as ONE native PowerPoint text box — editable in the deck, with\n // each paragraph's runs carrying their own bold/italic/color/size. The box's\n // inset is the block's padding, so the words land where they sat on screen.\n private _renderText(slide: any, component: ReportComponent, box: ComponentGeometry, tokens: TextTokenContext): void {\n const runs: any[] = [];\n const paragraphs = textParagraphs(component.config?.html ?? '', tokens);\n\n paragraphs.forEach((paragraph, index) => {\n const isLast = index === paragraphs.length - 1;\n const paragraphOptions = {\n align: paragraph.align,\n bullet: paragraph.bullet === 'number'\n ? { type: 'number' }\n : (paragraph.bullet === 'bullet' ? true : undefined),\n };\n const paragraphRuns = paragraph.runs.length ? paragraph.runs : [{ text: '' }];\n\n paragraphRuns.forEach((run, runIndex) => {\n runs.push({\n text: run.text,\n options: {\n ...paragraphOptions,\n bold: run.bold,\n italic: run.italic,\n underline: run.underline ? { style: 'sng' } : undefined,\n strike: run.strike ? 'sngStrike' : undefined,\n color: (run.color ?? DEFAULT_TEXT_COLOR).replace('#', ''),\n highlight: run.highlight?.replace('#', ''),\n fontSize: run.fontSize ?? DEFAULT_TEXT_SIZE,\n fontFace: run.fontFace,\n hyperlink: run.link ? { url: run.link } : undefined,\n breakLine: runIndex === paragraphRuns.length - 1 && !isLast,\n },\n });\n });\n });\n\n if (!runs.length) {\n return;\n }\n\n const padding = component.config?.padding;\n const inset = (value: number | undefined) => (value ?? DEFAULT_COMPONENT_PADDING) * 72;\n\n slide.addText(runs, {\n x: box.x, y: box.y, w: box.w, h: box.h,\n valign: 'top',\n fontFace: 'Arial',\n margin: [inset(padding?.left), inset(padding?.right), inset(padding?.bottom), inset(padding?.top)],\n fit: 'none',\n });\n }\n\n // What a text block's tokens fill with on this slide: the page's position\n // among the report's pages — the title slide is not a report page.\n private _tokens(report: Report, page: ReportPage, index: number): TextTokenContext {\n return {\n pageNumber: index + 1,\n pageName: page.name || `Page ${index + 1}`,\n reportName: report.name,\n };\n }\n\n private _renderComponent(\n pptx: any,\n slide: any,\n item: CollectedComponent,\n timezone: string,\n context: ReportFormatContext,\n geometry?: ComponentGeometry,\n ): void {\n const component = item.component;\n // Geometry is in inches — PowerPoint's native unit (flow layout arrives\n // pre-resolved into rows by pageGeometry).\n const { x, y, w, h } = geometry ?? component;\n\n const title = exportTitle(component, item.search);\n if (title) {\n slide.addText(title, {\n x, y, w, h: TITLE_H,\n fontSize: 10, bold: true, color: '1F2933', valign: 'top',\n });\n }\n\n const bodyY = y + TITLE_H;\n const bodyH = Math.max(0.3, h - TITLE_H);\n\n if (!item.data || !item.data.rows?.length) {\n slide.addText(emptyLabel(item), {\n x, y: bodyY, w, h: bodyH,\n fontSize: 10, italic: true, color: '7B8794', align: 'center', valign: 'middle',\n });\n\n return;\n }\n\n switch (component.type) {\n case 'chart':\n this._renderChart(pptx, slide, component, item.data, context, x, bodyY, w, bodyH);\n break;\n case 'list':\n this._renderTable(slide, component, item.data, item.hiddenColumns, timezone, context, x, bodyY, w, bodyH);\n break;\n case 'kpi':\n this._renderKpi(slide, component, item.data, context, x, bodyY, w, bodyH);\n break;\n }\n }\n\n private _renderChart(\n pptx: any,\n slide: any,\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const config = component.config as ChartConfig;\n const chartType = config.chartType ?? 'bar';\n\n if (chartType === 'waterfall') {\n this._renderWaterfall(pptx, slide, component, data, context, x, y, w, h);\n\n return;\n }\n\n const extracted = extractChartSeries(component, data);\n\n const typeMap: Record<string, any> = {\n bar: pptx.ChartType.bar,\n line: pptx.ChartType.line,\n area: pptx.ChartType.area,\n pie: pptx.ChartType.pie,\n donut: pptx.ChartType.doughnut,\n };\n\n const pie = chartType === 'pie' || chartType === 'donut';\n const colorBy = isColorBy(config);\n const labels = this._categoryLabels(\n extracted.categories,\n data.granularity,\n context.locale,\n chartDateLabel(config),\n );\n // A 100% stacked chart's primary bars and areas plot the shares the screen\n // draws, stacked: PowerPoint's own percentStacked grouping is dropped on an\n // area chart, so one rule covers both. The data sheet holds the shares;\n // the CSV keeps the raw values.\n const shares = percentStackedShares(extracted, config);\n\n // Native chart data: one entry per series (pie charts take exactly one).\n // colorBy emits one series per category for the on-screen overlap; PowerPoint\n // has no equivalent overlap, so collapse them back into a single series (each\n // category's value sits at its own slot) — one full-width bar per category —\n // rather than letting PowerPoint cluster them into slivers.\n const measureData = colorBy\n ? [{\n name: config.measures?.[0]?.label ?? config.colorBy?.label ?? '',\n labels,\n values: colorByValues(extracted),\n }]\n : (pie ? extracted.series.slice(0, 1) : extracted.series)\n .map((series, index) => ({\n name: series.name,\n labels,\n // A pie keeps the 0 the screen's pie uses; an axis chart keeps its\n // null so the point is a gap.\n values: pie ? series.values.map((value) => value ?? 0) : (shares?.get(index) ?? series.values),\n }));\n\n // The type each chartData entry is drawn as. A pie is one entry of its own\n // type; colorBy collapsed its series into one, drawn as the lone measure's.\n const seriesDataTypes: string[] = pie\n ? [chartType]\n : seriesTypes(extracted, chartType).slice(0, colorBy ? 1 : undefined);\n const dataTypes = seriesDataTypes.length ? seriesDataTypes : [chartType];\n // The value axis of each chartData entry; a pie and a colorBy chart have\n // one series on the one axis.\n const axisIndexes = pie || colorBy ? [0 as ValueAxisIndex] : seriesAxisIndexes(extracted, config);\n const twoAxes = axisIndexes.includes(1);\n const references = chartReferences(config, twoAxes);\n const formatCodes = pie ? [] : this._measureFormatCodes(config, extracted, axisIndexes, context, shares, references);\n\n // References and statistic lines follow the measures in the chart data,\n // each a constant series of its own.\n const constants = pie\n ? []\n : [\n ...this._referenceLines(references),\n ...this._statLines(config, extracted, axisIndexes, shares, colorBy, measureData[0]?.name ?? ''),\n ];\n const legendPosition = this._legendPosition(config, colorBy, extracted.series.length, constants.length);\n const chartData = [\n ...measureData,\n ...constants.map((line) => ({ name: line.name, labels, values: labels.map(() => line.value) })),\n ];\n\n // Series colors are per entry (_entryPlan), never chart-level, where a\n // multi-type chart's every entry would inherit them.\n const options = {\n x, y, w, h,\n showLegend: legendPosition !== 'hidden',\n legendPos: PPTX_LEGEND_POS[legendPosition],\n legendFontSize: 9,\n barDir: config.orientation === 'horizontal' ? 'bar' : 'col',\n barGrouping: config.stacked || shares ? 'stacked' : 'clustered',\n holeSize: chartType === 'donut' ? 55 : undefined,\n ...(twoAxes\n ? this._twoAxesOptions(config, formatCodes, shares)\n : this._axisTextOptions(config, pie)),\n ...BLANKS_AS_GAPS,\n // A pie has no axes. A combo's types inherit these from the chart level;\n // a two-axis chart's value axes carry their own format codes. A 100%\n // stacked chart's one value axis is the share axis.\n ...(pie || twoAxes ? {} : (shares ? this._percentAxisOptions(shares) : {\n valAxisLabelFormatCode: formatCodes[0],\n })),\n ...(pie ? {} : this._categoryOrderOptions(config, dataTypes)),\n dataBorder: { pt: 0, color: 'FFFFFF' },\n };\n\n const entries = [\n ...this._entryPlan(dataTypes, extracted, config, axisIndexes, shares, chartData.length)\n .map((entry) => this._withDataLabels(entry, config, formatCodes, shares, labels.length)),\n ...constants.map((line, index) => this._constantEntry(line, measureData.length + index, chartData.length)),\n ];\n\n this._addChart(slide, typeMap, entries, chartData, options);\n }\n\n // Where the legend sits, as on screen (resolveLegendPosition), with two\n // differences. A single-series colorBy chart can't carry a per-category\n // legend in a native PowerPoint bar chart, so the category axis labels\n // identify each bar instead. And a reference or statistic line is named in\n // the legend alone, where the screen labels it on the line, so a chart that\n // draws one shows the legend whenever the config does not pin it. A pinned\n // position, 'hidden' included, still wins.\n private _legendPosition(\n config: ChartConfig,\n colorBy: boolean,\n seriesCount: number,\n constantCount: number,\n ): LegendPosition {\n if (constantCount) {\n return config.legend ?? PPTX_CONSTANT_LEGEND;\n }\n\n return colorBy ? 'hidden' : resolveLegendPosition(config, seriesCount);\n }\n\n // Each reference (chartReferences) as constant lines: a line at its value,\n // or a band's lower edge under its label and its upper edge under the label\n // with PPTX_BAND_UPPER_SUFFIX. A chart draws the ones the screen draws: none\n // on a horizontal chart or a pie.\n private _referenceLines(references: DrawnReference[]): PptxConstantLine[] {\n return references.flatMap((reference) => {\n const line = { name: reference.label, value: reference.low, color: REPORT_REFERENCE_COLOR, secondary: reference.axisIndex === 1 };\n\n return reference.band\n ? [line, { ...line, name: `${reference.label}${PPTX_BAND_UPPER_SUFFIX}`, value: reference.high }]\n : [line];\n });\n }\n\n // Each measure's statistic line, taken over the values the series plots\n // (its shares on a 100% stacked chart), named after the series ('Visits\n // average') and drawn in its color on its axis. A colorBy chart's one line\n // is taken over its collapsed bars and drawn in the reference slate, as on\n // screen. A series with no value draws none, and a horizontal chart none.\n private _statLines(\n config: ChartConfig,\n extracted: ExtractedChartSeries,\n axisIndexes: ValueAxisIndex[],\n shares: PercentShares | null,\n colorBy: boolean,\n colorByName: string,\n ): PptxConstantLine[] {\n if (!drawsStatLines(config)) {\n return [];\n }\n\n const line = (\n name: string,\n values: (number | null)[],\n stat: ReportChartMarkStat,\n color: string,\n secondary: boolean,\n ): PptxConstantLine[] => {\n const value = seriesStat(values, stat);\n const statName = STAT_LABEL[stat];\n\n return value === null\n ? []\n : [{ name: name ? `${name} ${statName.toLowerCase()}` : statName, value, color, secondary }];\n };\n\n if (colorBy) {\n const stat = measureMarkStat(extracted.series[0]?.measure);\n\n return stat ? line(colorByName, colorByValues(extracted), stat, REPORT_REFERENCE_COLOR, false) : [];\n }\n\n return extracted.series.flatMap((series, index) => {\n const stat = measureMarkStat(series.measure);\n\n return stat\n ? line(series.name, shares?.get(index) ?? series.values, stat, seriesHex(series, index), axisIndexes[index] === 1)\n : [];\n });\n }\n\n // A constant line's own entry: dashed, without markers or data labels, on\n // its value axis. Its colors run the length of the chart's data, as a\n // measure line's do (_entryPlan), so no marker ever takes a random color.\n private _constantEntry(line: PptxConstantLine, index: number, totalData: number): PptxEntry {\n return {\n type: 'line',\n indexes: [index],\n secondary: line.secondary,\n options: {\n chartColors: Array<string>(totalData).fill(line.color),\n lineDash: PPTX_LINE_DASH[ReportChartLineStyle.Dashed],\n lineDataSymbol: 'none',\n lineSize: PPTX_CONSTANT_LINE_SIZE,\n showValue: false,\n ...(line.secondary ? { secondaryValAxis: true, secondaryCatAxis: true } : {}),\n },\n };\n }\n\n // The number format code of the measures plotted on each value axis, by\n // axis index, matching the screen's ticks (_valueAxisCode): a one-axis chart\n // takes the format its plotted series' measures agree on, as on screen. A 100% stacked\n // chart's share axis is drawn in PPTX_PERCENT_FORMAT_CODE instead; these\n // codes still write the raw values of the series beside its shares. The\n // references on an axis count toward its peak, as on screen\n // (referencePeak), except a 100% stacked chart's, which are shares.\n private _measureFormatCodes(\n config: ChartConfig,\n extracted: ExtractedChartSeries,\n axisIndexes: ValueAxisIndex[],\n context: ReportFormatContext,\n shares: PercentShares | null,\n references: DrawnReference[],\n ): string[] {\n const reach = (axisIndex: ValueAxisIndex) => (shares && axisIndex === 0 ? 0 : referencePeak(references, axisIndex));\n\n if (!axisIndexes.includes(1)) {\n const values = extracted.series.map((series) => series.values);\n const spec = axisNumberFormat(extracted.series.map((series) => series.measure));\n\n return [this._valueAxisCode(spec, values, !!config.stacked, context, reach(0))];\n }\n\n return ([0, 1] as const).map((axisIndex) => {\n const onAxis = extracted.series.filter((_, index) => axisIndexes[index] === axisIndex);\n\n return this._valueAxisCode(\n axisNumberFormat(onAxis.map((series) => series.measure)),\n onAxis.map((series) => series.values),\n !!config.stacked && !shares,\n context,\n reach(axisIndex),\n );\n });\n }\n\n // A measure entry with its data labels (config.dataLabels), set on the\n // entry alone: on a chart of several entries a chart-level key would reach\n // every one of them. Never called for a reference or statistic line.\n //\n // 'all' labels every point. PowerPoint cannot hide overlapping labels, so\n // 'auto' labels every point up to PPTX_AUTO_LABEL_MAX_POINTS categories\n // and none past that. pptxgenjs cannot label a single point, so 'last'\n // labels none (a documented gap), except on a colorBy chart: there every\n // bar is its own series' latest point on screen, so 'last' labels every\n // bar of the one collapsed series, as 'all' does.\n //\n // A label is written in its axis's format code ('0%' for a share). A\n // stacked bar's sits in the middle of its segment and a line's above its\n // point. A clustered bar keeps PowerPoint's default, outside its end, which\n // pptxgenjs would drop on a one-entry chart if named; an area takes no\n // position at all, and pptxgenjs does not strip one from a combo's area.\n private _withDataLabels(\n entry: PptxEntry,\n config: ChartConfig,\n formatCodes: string[],\n shares: PercentShares | null,\n categoryCount: number,\n ): PptxEntry {\n const mode = config.dataLabels;\n const show = mode === ReportChartDataLabels.All\n || (mode === ReportChartDataLabels.Auto && categoryCount <= PPTX_AUTO_LABEL_MAX_POINTS)\n || (mode === ReportChartDataLabels.Last && isColorBy(config));\n const chartType = config.chartType ?? 'bar';\n\n if (!show || chartType === 'pie' || chartType === 'donut') {\n return entry;\n }\n\n const share = !!shares?.has(entry.indexes[0]);\n const stacked = entry.type === 'bar' && (shares ? share : !!config.stacked);\n const position = this._dataLabelPosition(entry.type, stacked);\n\n return {\n ...entry,\n options: {\n ...entry.options,\n showValue: true,\n dataLabelFormatCode: share ? PPTX_PERCENT_FORMAT_CODE : formatCodes[entry.secondary ? 1 : 0],\n dataLabelFontSize: PPTX_DATA_LABEL_FONT_SIZE,\n ...(position ? { dataLabelPosition: position } : {}),\n },\n };\n }\n\n // A 100% stacked chart's share axis, as on screen: from 0 (-100% when a\n // share is negative) to 100%, a gridline every 25%, in whole percentages.\n private _percentAxisOptions(shares: PercentShares): Record<string, unknown> {\n return {\n valAxisMinVal: percentAxisMin(shares),\n valAxisMaxVal: PERCENT_AXIS_MAX,\n valAxisMajorUnit: PERCENT_AXIS_INTERVAL,\n valAxisLabelFormatCode: PPTX_PERCENT_FORMAT_CODE,\n };\n }\n\n // A two-axis chart's axes, each in its own object: pptxgenjs builds the\n // second value and category axes from the chart's options with these laid\n // over them, so a value-axis key left at the chart level would reach both.\n // The primary value axis is on the left with the category axis under it;\n // the second is on the right, without gridlines of its own, and its\n // category axis is hidden. Each value axis is titled only by its own label\n // and formatted by the measures plotted against it, as on screen. On a 100%\n // stacked chart the primary axis is the share axis, and the second axis's\n // series are not stacked.\n private _twoAxesOptions(\n config: ChartConfig,\n formatCodes: string[],\n shares: PercentShares | null,\n ): Record<string, unknown> {\n const valueAxis = (axisIndex: ValueAxisIndex) => {\n const axis = axisIndex === 1 ? config.secondaryAxis : config.valueAxis;\n const range = this._valueAxisRangeOptions(axis, axis?.label);\n\n if (shares && axisIndex === 0) {\n return { ...range, ...this._percentAxisOptions(shares) };\n }\n\n return { ...range, valAxisLabelFormatCode: formatCodes[axisIndex] };\n };\n\n return {\n ...AXIS_FONT_SIZES,\n valAxes: [valueAxis(0), { ...valueAxis(1), valGridLine: { style: 'none' } }],\n catAxes: [this._categoryTitleOptions(config), { catAxisHidden: true }],\n };\n }\n\n // A horizontal bar chart reads top-down, first category at the top, as it\n // does on screen. PowerPoint draws category 0 next to the value axis, at the\n // bottom, so the category axis is reversed ('maxMin'); the value axis then\n // crosses at the last category ('max'), which now sits at the bottom, and\n // 'nextTo' keeps its labels on that line (pptxgenjs's default for a bar\n // direction, 'low', would follow the first category to the top). Only an\n // all-bar chart: a line or area is never drawn sideways.\n private _categoryOrderOptions(config: ChartConfig, types: string[]): Record<string, unknown> {\n if (config.orientation !== 'horizontal' || types.some((type) => type !== 'bar')) {\n return {};\n }\n\n return { catAxisOrientation: 'maxMin', catAxisCrossesAt: 'max', valAxisLabelPos: 'nextTo' };\n }\n\n // The value axis's number format code, matching the screen's ticks: with an\n // axis format (axisNumberFormat, or a waterfall's formatted measure) the\n // units and decimals the screen decides from the same peak; without one,\n // the code for the screen's plain ticks. The peak is the series' or the\n // furthest reference on the axis (reach), whichever is larger; the format\n // helpers read it off a one-point series.\n private _valueAxisCode(\n spec: NumberFormatSpec | null,\n values: (number | null)[][],\n stacked: boolean,\n context: ReportFormatContext,\n reach: number,\n ): string {\n const peak = Math.max(chartValuePeak(values, stacked), reach);\n const peakSeries = [[peak]];\n\n if (!spec) {\n return chartAxisFormatCode(peakSeries, false);\n }\n\n const chart = resolveChartNumberFormat(spec, peak, context);\n\n return numberFormatCode(spec, context, chart, peakSeries, false);\n }\n\n // One native chart when the plan is a single entry, its options laid over\n // the chart's. Otherwise pptxgenjs's multi-type chart, where every entry's\n // own options are laid over the chart's.\n private _addChart(\n slide: any,\n typeMap: Record<string, any>,\n entries: PptxEntry[],\n chartData: unknown[],\n options: Record<string, unknown>,\n ): void {\n if (entries.length === 1) {\n const entry = entries[0];\n slide.addChart(typeMap[entry.type], entry.indexes.map((index) => chartData[index]), { ...options, ...entry.options });\n\n return;\n }\n\n slide.addChart(entries.map((entry) => ({\n type: typeMap[entry.type],\n data: entry.indexes.map((index) => chartData[index]),\n options: entry.options,\n })), options);\n }\n\n // How a chart's series (dataTypes, one per chartData entry) are cut into\n // native charts, and the colors each draws in.\n //\n // A pie's slices and a colorBy chart's collapsed bars are one series colored\n // point by point, so their one entry keeps the whole palette. Every other\n // entry is handed exactly its own series' colors (seriesHex), so a lone bar\n // series is one color, as on screen, rather than a color per bar.\n //\n // Bars share one entry per value axis, since separate bar charts on one axis\n // overlap instead of clustering, and areas likewise, since they stack only\n // inside one area chart. Each line gets an entry of its own, so its line\n // options are its own. pptxgenjs colors a line by its place in its entry but\n // fills its markers by its place across every entry's data, and with a\n // random color past the end of the list, so a line's list is its one color\n // the whole length of the chart's data (totalData, which counts the\n // constant lines after the measures too).\n //\n // An entry on the second value axis (seriesAxisIndexes) plots against the\n // second value and category axes.\n //\n // A line entry draws its measure's line style (PPTX_LINE_DASH) and its\n // markers, or none. On a 100% stacked chart only the share entries stack;\n // a bar or area entry on the second axis is drawn side by side, as on\n // screen.\n private _entryPlan(\n dataTypes: string[],\n extracted: ExtractedChartSeries,\n config: ChartConfig,\n axisIndexes: ValueAxisIndex[],\n shares: PercentShares | null,\n totalData: number,\n ): PptxEntry[] {\n const chartType = config.chartType ?? 'bar';\n if (chartType === 'pie' || chartType === 'donut' || isColorBy(config)) {\n return [{ type: dataTypes[0], indexes: [0], secondary: false, options: { chartColors: REPORT_CHART_COLORS } }];\n }\n\n const entries: PptxEntry[] = [];\n const perAxis = new Map<string, PptxEntry>();\n dataTypes.forEach((type, index) => {\n const secondary = axisIndexes[index] === 1;\n const key = `${type}-${secondary}`;\n let entry = type === 'line' ? undefined : perAxis.get(key);\n\n if (!entry) {\n entry = { type, indexes: [], secondary, options: {} };\n entries.push(entry);\n perAxis.set(key, entry);\n }\n\n entry.indexes.push(index);\n });\n\n const hex = (index: number) => (extracted.series[index]\n ? seriesHex(extracted.series[index], index)\n : REPORT_CHART_COLORS[index % REPORT_CHART_COLORS.length]);\n\n return entries.map((entry) => ({\n ...entry,\n options: {\n chartColors: entry.type === 'line'\n ? Array<string>(totalData).fill(hex(entry.indexes[0]))\n : entry.indexes.map(hex),\n ...(entry.type === 'line' ? this._lineOptions(extracted.series[entry.indexes[0]]?.measure) : {}),\n ...(shares && entry.type !== 'line' && !shares.has(entry.indexes[0])\n ? { barGrouping: entry.type === 'area' ? 'standard' : 'clustered' }\n : {}),\n ...(entry.secondary ? { secondaryValAxis: true, secondaryCatAxis: true } : {}),\n },\n }));\n }\n\n // Where a data label sits: PowerPoint's dLblPos code, or undefined to leave\n // it out (_withDataLabels says why).\n private _dataLabelPosition(type: string, stackedBar: boolean): string | undefined {\n if (type === 'line') {\n return 't';\n }\n\n return stackedBar ? 'ctr' : undefined;\n }\n\n // A line entry's dash and markers. A style PowerPoint has no dash for is\n // drawn solid.\n private _lineOptions(measure: ChartMeasure | undefined): Record<string, unknown> {\n const style = measureLineStyle(measure);\n\n return {\n lineDash: style ? PPTX_LINE_DASH[style] : PPTX_LINE_DASH[ReportChartLineStyle.Solid],\n lineDataSymbol: measure?.markers === false ? 'none' : 'circle',\n lineDataSymbolSize: PPTX_LINE_SYMBOL_SIZE,\n };\n }\n\n // A waterfall is a stacked bar chart whose first series is invisible: it\n // lifts each bar to where its step starts. The series are cut differently\n // from the screen's; _waterfallSeries says why.\n private _renderWaterfall(\n pptx: any,\n slide: any,\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const config = component.config as ChartConfig;\n const waterfall = extractWaterfall(component, data);\n const measure = config.measures?.[0];\n const labels = this._categoryLabels(\n waterfall.steps.map((step) => step.category),\n data.granularity,\n context.locale,\n chartDateLabel(config),\n );\n const series = this._waterfallSeries(waterfall.steps);\n // The references are constant lines beside the stacked bars, on the one\n // value axis. Without any the chart is the one stacked bar chart, without\n // a legend; with them the legend names them (_legendPosition), as it\n // alone can, beside the steps' kinds.\n const references = chartReferences(config, false);\n const constants = this._referenceLines(references);\n const legendPosition: LegendPosition = constants.length ? config.legend ?? PPTX_CONSTANT_LEGEND : 'hidden';\n const chartData = [\n ...series.map((entry) => ({ name: entry.name, labels, values: entry.values })),\n ...constants.map((line) => ({ name: line.name, labels, values: labels.map(() => line.value) })),\n ];\n const entries: PptxEntry[] = [\n {\n type: 'bar',\n indexes: series.map((_, index) => index),\n secondary: false,\n options: { chartColors: series.map((entry) => entry.color), barGrouping: 'stacked' },\n },\n ...constants.map((line, index) => this._constantEntry(line, series.length + index, chartData.length)),\n ];\n\n this._addChart(slide, { bar: pptx.ChartType.bar, line: pptx.ChartType.line }, entries, chartData, {\n x, y, w, h,\n showLegend: legendPosition !== 'hidden',\n legendPos: PPTX_LEGEND_POS[legendPosition],\n legendFontSize: 9,\n barDir: config.orientation === 'horizontal' ? 'bar' : 'col',\n ...this._axisTextOptions(config, false),\n ...BLANKS_AS_GAPS,\n // The axis spans the running total, so its peak is the furthest a step\n // ends from zero (or the furthest reference); the pieces it is cut into\n // never stack past that. The one measure's format writes it, as on\n // screen.\n valAxisLabelFormatCode: this._valueAxisCode(\n measure && hasNumberFormat(measure) ? measure : null,\n [waterfall.steps.map((step) => step.start + (step.change ?? 0))],\n false,\n context,\n referencePeak(references, 0),\n ),\n ...this._categoryOrderOptions(config, ['bar']),\n // A running total can go below zero, where the category axis crosses;\n // its labels stay at the plot's edge instead of across the bars.\n catAxisLabelPos: 'low',\n });\n }\n\n // PowerPoint stacks positive and negative values apart, each from zero, so a\n // bar cannot simply sit on the total before it the way it does on screen.\n // Each step is cut at zero instead: the invisible base carries it to its end\n // nearer zero, and its kind's series carries the rest — one series above zero\n // and one below, because a step that crosses zero needs both. Every other\n // point is left blank: a zero there would still draw a zero-height bar, which\n // renders as a hairline. A kind's series that stays blank is dropped.\n private _waterfallSeries(steps: WaterfallStep[]): PptxChartSeries[] {\n const base: PptxChartSeries = { name: '', color: 'transparent', values: [] };\n const kinds = Object.keys(WATERFALL_SERIES_NAMES) as WaterfallStepKind[];\n const piece = (kind: WaterfallStepKind) => ({\n kind, name: WATERFALL_SERIES_NAMES[kind], color: REPORT_WATERFALL_COLORS[kind], values: [] as (number | null)[],\n });\n const above = kinds.map(piece);\n const below = kinds.map(piece);\n const blankZero = (value: number) => (value === 0 ? null : value);\n\n for (const step of steps) {\n const end = step.start + (step.change ?? 0);\n const low = Math.min(step.start, end);\n const high = Math.max(step.start, end);\n\n base.values.push(blankZero(low > 0 ? low : (high < 0 ? high : 0)));\n above.forEach((entry) => entry.values.push(\n entry.kind === step.kind ? blankZero(Math.max(high, 0) - Math.max(low, 0)) : null,\n ));\n below.forEach((entry) => entry.values.push(\n entry.kind === step.kind ? blankZero(Math.min(low, 0) - Math.min(high, 0)) : null,\n ));\n }\n\n return [base, ...[...above, ...below].filter((entry) => entry.values.some((value) => value !== null))];\n }\n\n // Compact period labels match the on-screen axis, in the report's locale and\n // the axis's date label style (a short label takes its year only when the\n // data spans years); PowerPoint can't do a styled second line, so it's\n // inline.\n private _categoryLabels(\n categories: string[],\n granularity: ChartGranularity | null | undefined,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel,\n ): string[] {\n if (!granularity) {\n return categories;\n }\n\n const multiYear = spansMultipleYears(categories);\n\n return categories.map((category) => formatPeriodLabel(category, granularity, multiYear, locale, dateLabel));\n }\n\n // The axis label and title settings of a chart with one value axis, and that\n // axis's range (valueAxis). A pie has no value axis to title. Without a\n // valueAxis.label the value axis is titled by the first measure's label, as\n // decks always have been; the screen shows only an explicit title. An\n // explicit empty label suppresses that fallback, as it does on screen, and\n // a 100% stacked chart's share axis is never titled with one series' name.\n private _axisTextOptions(config: ChartConfig, pie: boolean): Record<string, unknown> {\n return {\n ...AXIS_FONT_SIZES,\n ...this._categoryTitleOptions(config),\n ...(pie\n ? { showValAxisTitle: false }\n : this._valueAxisRangeOptions(\n config.valueAxis,\n config.valueAxis?.label ?? (config.percentStacked === true ? undefined : config.measures?.[0]?.label),\n )),\n };\n }\n\n private _categoryTitleOptions(config: ChartConfig): Record<string, unknown> {\n return {\n showCatAxisTitle: !!config.xAxis?.label,\n catAxisTitle: config.xAxis?.label,\n catAxisTitleFontSize: 10,\n };\n }\n\n // One value axis's title and the range the config pins (valueAxisRange, as\n // on screen). Every key is set, even when empty, so on a two-axis chart\n // nothing is inherited from the chart's options.\n private _valueAxisRangeOptions(axis: ChartValueAxis | undefined, title: string | undefined): Record<string, unknown> {\n const range = valueAxisRange(axis);\n\n return {\n showValAxisTitle: !!title,\n valAxisTitle: title || undefined,\n valAxisMinVal: range.min,\n valAxisMaxVal: range.max,\n valAxisMajorUnit: range.interval,\n };\n }\n\n // A list's table, without the columns the viewer hid. A totals row closes\n // it, bold on the border gray, in a row kept free for it.\n private _renderTable(\n slide: any,\n component: ReportComponent,\n data: ComponentData,\n hiddenColumns: readonly string[],\n timezone: string,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const columns = listColumns(component, data, context.locale, hiddenColumns);\n const totals = listTotalsRow(data, columns, timezone, context);\n\n const cap = Math.max(2, Math.floor(h / SLIDE_ROW_H) - 1 - (totals ? 1 : 0));\n const rows = data.rows.slice(0, cap);\n const remaining = (data.paging?.total ?? data.rows.length) - rows.length;\n\n // A column of formatted numbers is right-aligned, its heading too, as on\n // screen.\n const align = (index: number) => (columns[index]?.numeric ? { align: 'right' } : {});\n\n const header = listHeadings(component, data, context.locale, hiddenColumns).map((heading, index) => ({\n text: heading,\n options: { bold: true, color: 'FFFFFF', fill: { color: '4E79A7' }, ...align(index) },\n }));\n\n // A date or formatted-number cell is a value written in the report's\n // locale; every other cell prints the query's text as it came.\n const valueLocale = (index: number) => {\n const column = columns[index];\n\n return column.numeric || column.format === ReportListColumnFormat.Date ? context.locale : undefined;\n };\n\n const body = rows.map((row) => columns.map((column, index) => ({\n text: exportCell(row[column.column], column, timezone, context),\n options: pptxRunOptions(align(index), valueLocale(index)),\n })));\n\n if (remaining > 0) {\n body.push([{\n text: moreRowsNotice(remaining),\n options: { colspan: columns.length, italic: true, color: '7B8794' } as any,\n }]);\n }\n\n // The label is interface text, so it keeps the default proofing language.\n if (totals) {\n const labelColumn = listTotalsLabelColumn(columns, data.totals);\n\n body.push(totals.map((text, index) => ({\n text,\n options: pptxRunOptions(\n { bold: true, fill: { color: 'E4E7EB' }, ...align(index) },\n columns[index].column === labelColumn ? undefined : valueLocale(index),\n ),\n })));\n }\n\n slide.addTable([header, ...body], {\n x, y, w,\n fontSize: 9,\n color: '1F2933',\n border: { type: 'solid', pt: 0.5, color: 'E4E7EB' },\n autoPage: false,\n rowH: SLIDE_ROW_H,\n valign: 'middle',\n });\n }\n\n private _renderKpi(\n slide: any,\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const config = component.config as KpiConfig;\n const row = data.rows[0] ?? {};\n const column = config.measure?.column ?? Object.keys(row)[0];\n const value = formatNumber(row[column], config.measure, context, { empty: '—' });\n\n slide.addText([\n {\n text: value,\n options: pptxRunOptions({ fontSize: 28, bold: true, color: '1F2933', breakLine: true }, context.locale),\n },\n { text: config.measure?.label ?? '', options: { fontSize: 10, color: '7B8794' } },\n ], {\n x, y, w, h,\n align: 'center',\n valign: 'middle',\n });\n }\n\n private _slug(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'report';\n }\n}\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 { PDF_LIST_ROWS, ReportPdfService } from './report-pdf.service';\nimport { PPTX_LIST_ROWS, 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, PDF_LIST_ROWS, (collected) => this._pdfService.export(collected));\n }\n\n public powerpoint(report: Report): Observable<unknown> {\n return this._run(report, PPTX_LIST_ROWS, (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 //\n // listRows is the format's own list cap, carried into the retry so a second\n // attempt fetches what the first did.\n private _run(\n report: Report,\n listRows: number,\n render: (collected: CollectedReport) => Promise<void>,\n ): Observable<unknown> {\n return this._collector.collect(report, listRows)\n .pipe(\n switchMap((collected) => this._gate(collected)\n .pipe(\n switchMap((choice) => choice === RETRY\n ? this._run(report, listRows, 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 {\n CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component,\n DestroyRef, ElementRef, NgZone, ViewChild, inject, signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { MatButton } from '@angular/material/button';\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { FsAutocompleteChipsModule } from '@firestitch/autocomplete-chips';\nimport { FilterConfig, FsFilterModule, IFilterConfigItem } from '@firestitch/filter';\nimport { FsMenuModule } from '@firestitch/menu';\nimport { FsProcess } from '@firestitch/process';\nimport { FsPrompt } from '@firestitch/prompt';\n\nimport { finalize, switchMap, takeUntil } from 'rxjs/operators';\n\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { provideEchartsCore } from 'ngx-echarts';\n\nimport { FsAiChatComponent, FsAiChatResponse } from '@firestitch/ai';\n\nimport { ReportCanvasComponent } from '../../components/report-canvas/report-canvas.component';\nimport { ReportData } from '../../data/report.data';\nimport { ComponentSettingsComponent, ComponentSettingsResult } from '../../dialogs/component-settings/component-settings.component';\nimport { ReportSettingsComponent, ReportSettingsResult } from '../../dialogs/report-settings/report-settings.component';\nimport { ReportExportCollectorService } from '../../export/report-export-collector.service';\nimport { ReportExportService } from '../../export/report-export.service';\nimport { ReportPdfService } from '../../export/report-pdf.service';\nimport { ReportPptxService } from '../../export/report-pptx.service';\nimport {\n ChartGranularity, Report,\n ReportComponent as ReportComponentModel, ReportFilterGroup, ReportListItem,\n} from '../../interfaces/report.interface';\nimport {\n GROUP_BY_ITEM, filterItemForGroup, groupByFilterItem, groupBySignature, groupValuesFromQuery,\n isGranularityOffered,\n} from '../../report-filter-items';\nimport { ReportFilterStateService, defaultSignature } from '../../services/report-filter-state.service';\nimport { ReportService } from '../../services/report.service';\n\n\n// The Reports page: AI chat on the left, the report canvas on the right —\n// a split-pane layout; the viewer is our own canvas (no iframe, no embed URLs).\n// The chat is always scoped to the selected report; its id rides on every\n// turn via [requestData].\n@Component({\n templateUrl: './report.component.html',\n styleUrls: ['./report.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n providers: [\n // Session filter state is per-open-report-page, not app-global; the export\n // services resolve filters through it, so they live at the same level.\n ReportFilterStateService,\n ReportExportCollectorService,\n ReportPptxService,\n ReportPdfService,\n ReportExportService,\n // Tree-shaken ECharts core + the 'report' house theme, loaded lazily with\n // this route's chunk.\n provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),\n ],\n imports: [\n FormsModule,\n FsAutocompleteChipsModule,\n FsFilterModule,\n FsMenuModule,\n FsAiChatComponent,\n MatButton,\n MatIcon,\n MatTooltip,\n ReportCanvasComponent,\n ],\n})\nexport class ReportComponent {\n\n // The single report the viewer and chat are focused on.\n public readonly selected = signal<ReportListItem | null>(null);\n public readonly report = signal<Report | null>(null);\n public readonly loadingReports = signal(true);\n public readonly editMode = signal(false);\n\n // The report toolbar IS an fs-filter: the picker rides in its heading\n // template, the menu becomes its actions, and report-level filter groups\n // become its items. Rebuilt whenever the loaded report (and thus its groups)\n // changes; the menu's show-guards keep working while no report is selected.\n public readonly reportFilterConfig = signal<FilterConfig | null>(null);\n\n @ViewChild('split', { static: true })\n private _split!: ElementRef<HTMLDivElement>;\n\n @ViewChild('chatPanel', { static: true, read: ElementRef })\n private _chatPanel!: ElementRef<HTMLElement>;\n\n // Only the canvas knows which page is on screen, and a page-scoped export\n // has to ask it.\n @ViewChild(ReportCanvasComponent)\n private _canvas?: ReportCanvasComponent;\n\n public readonly introMessage = {\n text: '',\n };\n\n private _reportData = inject(ReportData);\n private _reportService = inject(ReportService);\n private _filterState = inject(ReportFilterStateService);\n private _exportService = inject(ReportExportService);\n private _collector = inject(ReportExportCollectorService);\n private _process = inject(FsProcess);\n private _prompt = inject(FsPrompt);\n private _dialog = inject(MatDialog);\n private _destroyRef = inject(DestroyRef);\n private _zone = inject(NgZone);\n\n constructor() {\n this._buildReportConfig();\n\n this._reportService.load()\n .pipe(\n finalize(() => {\n this.loadingReports.set(false);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({ error: () => undefined });\n }\n\n public fetchReports = (keyword: string) => {\n return this._reportService.filter(keyword);\n };\n\n public reportChange(report: ReportListItem | null): void {\n this.report.set(null);\n this.editMode.set(false);\n this._buildReportConfig();\n\n if (report) {\n this._loadReport(report.id);\n }\n }\n\n public createReport(): void {\n this._prompt.input({\n title: 'Create Report',\n label: 'Name',\n commitLabel: 'Create',\n required: true,\n })\n .pipe(\n switchMap((name: string) => this._reportService.create(name)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((report: ReportListItem) => {\n this.selected.set(report);\n this._loadReport(report.id);\n });\n }\n\n public toggleEditMode(): void {\n this.editMode.update((editMode) => !editMode);\n }\n\n // The edit tools live in this toolbar, but the canvas owns what they act on\n // (the active page, the header/footer bands, which layer is live).\n public get isMasterMode(): boolean {\n return this._canvas?.masterMode() ?? false;\n }\n\n public addText(): void {\n this._canvas?.addText();\n }\n\n public toggleMasterMode(): void {\n this._canvas?.toggleMasterMode();\n }\n\n // Report settings — name, page size, orientation, layout mode. The picker\n // list and structure both reload on save (a layout switch re-renders the\n // whole canvas).\n public reportSettings(): void {\n if (!this.report()) {\n return;\n }\n\n this._dialog.open<ReportSettingsComponent, unknown, ReportSettingsResult>(ReportSettingsComponent, {\n data: { report: this.report() },\n width: '460px',\n })\n .afterClosed()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((result) => {\n // The dialog confirms + performs the delete itself; we just react to\n // what it reports back.\n if (result?.action === 'deleted') {\n this.selected.set(null);\n this.report.set(null);\n this._buildReportConfig();\n\n return;\n }\n\n if (result?.action === 'saved' && this.selected()) {\n this._loadReport(this.selected().id);\n this._refreshReportName(this.selected().id);\n }\n });\n }\n\n // Component settings — title, exact geometry, and the diagnostic views\n // (SQL, config, filter wiring).\n public componentSettings(component: ReportComponentModel): void {\n if (!this.report()) {\n return;\n }\n\n const dialogRef = this._dialog.open<ComponentSettingsComponent, unknown, ComponentSettingsResult>(\n ComponentSettingsComponent,\n {\n data: { report: this.report(), component },\n width: '640px',\n },\n );\n\n // Filter add/remove/level changes persist immediately inside the dialog (no\n // \"save\") and can leave it by an exit that carries no result, so they are\n // announced as they land. The reload waits for the close so the canvas isn't\n // re-rendering underneath an open dialog.\n let filtersChanged = false;\n dialogRef.componentInstance.filtersChanged\n .pipe(takeUntil(dialogRef.afterClosed()))\n .subscribe(() => filtersChanged = true);\n\n dialogRef.afterClosed()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((result) => {\n // The dialog confirms + performs the delete itself. The component is\n // gone from the report, so reload rather than patching it out locally —\n // its filters went with it, which the report bar has to be rebuilt for.\n if (result?.deleted) {\n if (this.selected()) {\n this._loadReport(this.selected().id);\n }\n\n return;\n }\n\n // The report's filter groups changed, so the report bar and the\n // on-component strips have to be rebuilt from a fresh report.\n if (filtersChanged) {\n if (this.selected()) {\n this._loadReport(this.selected().id);\n }\n\n return;\n }\n\n // Nothing else in the dialog touches the query — title and padding are\n // presentation. Repaint the one component it was opened for and leave\n // every other component's data, and its query, alone.\n if (result?.settings) {\n this._canvas?.applyComponentSettings(component.id, result.settings);\n }\n });\n }\n\n // The canvas changed the report's structure (added a page) — re-fetch so the\n // new page renders; the canvas lands the view on it.\n public onCanvasReportChanged(): void {\n if (this.selected()) {\n this._loadReport(this.selected().id);\n }\n }\n\n // Export the report to PowerPoint, entirely client-side: every component's\n // data is fetched fresh with the current filter state (all pages, not just\n // the visible one), then pptxgenjs builds a deck of NATIVE editable charts —\n // page = slide, positions 1:1. The dock shows progress until the file saves.\n public exportPowerpoint(): void {\n if (!this.report()) {\n return;\n }\n\n this._process.run(\n 'Exporting PowerPoint',\n this._exportService.powerpoint(this.report()),\n );\n }\n\n // Export to PDF, entirely client-side: same collection pass, charts rendered\n // through an offscreen ECharts instance at 3× pixel ratio (pixel-identical\n // to the screen), tables via jspdf-autotable — page = PDF page.\n public exportPdf(): void {\n if (!this.report()) {\n return;\n }\n\n this._process.run(\n 'Exporting PDF',\n this._exportService.pdf(this.report()),\n );\n }\n\n // The whole report as files in one action: the server writes one CSV per\n // component, each what the screen shows (a chart or KPI as drawn, at the\n // viewer's group-by grain; a list in full), and zips them foldered by page\n // with an Export Notes.txt that records the filters as the bar reads them.\n // Lists use their saved default sort; a header click is carried only by a\n // component's own CSV export. `thisPage` narrows it to the page the canvas is\n // showing. Unlike the PDF/PowerPoint exports the files are written\n // server-side, so they are not capped by what a slide can hold.\n public exportData(thisPage = false): void {\n const report = this.report();\n if (!report) {\n return;\n }\n\n const pageId = thisPage ? this._canvas?.activePage?.id ?? null : null;\n const filters = this._filterState.resolveForReport(report, pageId);\n const frequency = this._filterState.frequency();\n\n this._process.download(\n 'Exporting data',\n this._collector.getFilterSummary(report)\n .pipe(\n switchMap((lines) => this._reportData.exportReport(\n report.id,\n filters,\n pageId,\n frequency,\n lines,\n )),\n ),\n );\n }\n\n // React to each chat turn (fs-chat handles the request + persistence); we\n // only care about the report side effects this context's backend flags.\n public onChatResponse(response: FsAiChatResponse): void {\n // The agent changed the report's structure — re-fetch it. Session filter\n // values survive (the filter-state service keeps values for groups that\n // still exist).\n if (response.reportChanged && this.selected()) {\n this._loadReport(this.selected().id);\n }\n\n // A rename changes nothing structural — refresh the picker chip label.\n if (response.reportRenamed && this.selected()) {\n this._refreshReportName(this.selected().id);\n }\n }\n\n // Drag the divider between the chat and canvas panes (pointer-capture loop\n // outside Angular).\n public onResizeStart(event: PointerEvent): void {\n event.preventDefault();\n\n const handle = event.target as HTMLElement;\n handle.setPointerCapture(event.pointerId);\n this._split.nativeElement.classList.add('resizing');\n\n this._zone.runOutsideAngular(() => {\n const move = (e: PointerEvent) => this._resizeTo(e.clientX);\n const end = () => {\n handle.releasePointerCapture(event.pointerId);\n handle.removeEventListener('pointermove', move);\n handle.removeEventListener('pointerup', end);\n handle.removeEventListener('pointercancel', end);\n this._split.nativeElement.classList.remove('resizing');\n };\n\n handle.addEventListener('pointermove', move);\n handle.addEventListener('pointerup', end);\n handle.addEventListener('pointercancel', end);\n });\n }\n\n private _resizeTo(clientX: number): void {\n const rect = this._split.nativeElement.getBoundingClientRect();\n if (rect.width === 0) {\n return;\n }\n\n const ratio = (clientX - rect.left) / rect.width;\n const clamped = Math.min(0.8, Math.max(0.2, ratio));\n this._chatPanel.nativeElement.style.flexBasis = `${clamped * 100}%`;\n }\n\n private _loadReport(reportId: number): void {\n this._reportData.get(reportId)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((report: Report) => {\n this.report.set(report);\n // No URL state in this view: nothing is restored from the URL and\n // nothing listens to urlChanges(), so its filters stay session-only.\n this._filterState.init(report);\n this._buildReportConfig();\n });\n }\n\n // Report-level filter groups in their saved order — the ones that render in\n // the toolbar (component-level groups render on their components).\n private _reportGroups(): ReportFilterGroup[] {\n return (this.report()?.filterGroups ?? [])\n .filter((group) => group.level === 'report' || group.level === 'both')\n .sort((a, b) => a.order - b.order);\n }\n\n // Gates the toolbar fs-filter so it isn't rendered (taking space) when there\n // is nothing to put in it — no report-level filters and no group-by control.\n public get reportHasFilters(): boolean {\n return this._reportGroups().length > 0 || !!this._groupByItem();\n }\n\n // fs-filter reads its config only once (at init) — re-binding does nothing.\n // The template keys the toolbar fs-filter on this signature so it's recreated\n // (and re-reads the rebuilt config) whenever the report-level filter set\n // changes, e.g. after the component settings dialog adds/moves a filter.\n public get reportFilterKey(): string {\n return [\n // The effective zone is part of it too: a zone change re-resolves relative\n // presets, and the bar must be recreated to show the new days.\n this._filterState.timezone(),\n // The stored default is part of the signature: saving a new default in report\n // settings rebuilds the config, but without a key change fs-filter keeps\n // rendering the values it was created with until a full page reload.\n groupBySignature(this.report()),\n ...this._reportGroups().map((group) => `${group.id}:${group.level}:${group.label}:${defaultSignature(group)}`),\n ].join('|');\n }\n\n // (Re)build the toolbar fs-filter config — the report-level filter items and\n // then the group-by control. The report's actions live in the fs-menu beside\n // the picker, not here. Only built/used once a report is loaded (the template\n // gates it on `report`).\n private _buildReportConfig(): void {\n const reportId = this.report()?.id ?? null;\n\n // Drop a grain the control no longer offers — the agent can narrow the list\n // mid-session, and an override the viewer can't see is worse than none.\n if (this.report() && !isGranularityOffered(this.report(), this._filterState.frequency())) {\n this._filterState.setFrequency(null);\n }\n\n const items = reportId\n ? this._reportGroups().map((group) =>\n filterItemForGroup(group, this._reportData, reportId, this._filterState.value(group.id)))\n : [];\n\n // The group-by control leads the bar, ahead of every filter: it sets the\n // grain the whole report is read at, so it is the first thing a viewer\n // decides. It is not a filter group — it re-buckets rows rather than\n // narrowing them — so it is placed here rather than ordered among them.\n const groupByItem = this._groupByItem();\n if (groupByItem) {\n items.unshift(groupByItem);\n }\n\n this.reportFilterConfig.set({\n // Never touch the URL or persist filter state — report filters are\n // session-only, owned by ReportFilterStateService.\n queryParam: false,\n persist: false,\n items,\n change: (query) => {\n for (const { groupId, value } of groupValuesFromQuery(query ?? {}, this._reportGroups())) {\n this._filterState.setValue(groupId, value);\n }\n // Not a filter group — the grain is read straight off the query.\n this._filterState.setFrequency((query?.[GROUP_BY_ITEM] as ChartGranularity) || null);\n },\n });\n }\n\n // The report's group-by control as an fs-filter item, or null when the report\n // has none to show. Seeded from the session state so the grain the viewer\n // picked survives the report being re-fetched after a chat edit.\n private _groupByItem(): IFilterConfigItem | null {\n return this.report()\n ? groupByFilterItem(this.report(), this._filterState.frequency())\n : null;\n }\n\n private _refreshReportName(reportId: number): void {\n this._reportService.load()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((reports: ReportListItem[]) => {\n const renamed = reports.find((report) => report.id === reportId);\n if (renamed) {\n this.selected.set(renamed);\n if (this.report()) {\n this.report.set({ ...this.report(), name: renamed.name });\n }\n }\n });\n }\n}\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() && editMode()) {\n <!-- What layout editing can add or switch to, and the way out of it —\n the same outlined buttons as the fs-ai-report toolbar. -->\n <button\n mat-stroked-button\n type=\"button\"\n matTooltip=\"Add a block of text\"\n (click)=\"addText()\">\n <mat-icon>title</mat-icon>\n Add text\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"master-toggle\"\n [class.active]=\"isMasterMode\"\n [matTooltip]=\"isMasterMode ? 'Back to editing this page' : 'Edit the header and footer shown on every page'\"\n (click)=\"toggleMasterMode()\">\n <mat-icon>web_asset</mat-icon>\n Header & footer\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"toggleEditMode()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n }\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_customize\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 </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 { EMPTY, Observable } from 'rxjs';\nimport { catchError, 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 // The status request failed. Settles the skeleton and shows why; the Build\n // action never depends on the status, so a build can still be started.\n public readonly statusError = signal(false);\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 // A semantic database has been published before, so a build replaces it.\n // False while the status is unloaded or failed to load.\n public readonly rebuild = computed<boolean>(() => !!this.status()?.detail?.generatedAt);\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.rebuild();\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._loadStatus()\n .subscribe((status: SemanticBuildStatus) => this._announceOutcome(status));\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._loadStatus()\n .subscribe();\n }\n\n // Fetch the status into the tab. A failure flags statusError and completes\n // quietly, so the tab settles and callers never see the error.\n private _loadStatus(): Observable<SemanticBuildStatus> {\n return this._reportData.semanticBuildStatus()\n .pipe(\n tap((status: SemanticBuildStatus) => {\n this.statusError.set(false);\n this.status.set(status);\n }),\n catchError(() => {\n this.statusError.set(true);\n\n return EMPTY;\n }),\n takeUntilDestroyed(this._destroyRef),\n );\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 <!-- A failed status load settles the skeleton too, so the tab says what\n happened instead of loading forever. -->\n @if (statusError()) {\n <fs-message-warning>\n The build status could not be loaded, so the last build and its coverage\n can't be shown. You can still run a build.\n </fs-message-warning>\n }\n\n <div *fsSkeleton=\"status() || statusError()\">\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. \"active accounts\" are accounts with an order in the last 90 days.*',\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 <!-- Never gated on the status load: a status response that fails\n must not take the Build action away with it. -->\n <button\n type=\"button\"\n mat-button\n (click)=\"db.build()\">\n {{ db.rebuild() ? 'Rebuild' : 'Build' }}\n </button>\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 { FsChipModule } from '@firestitch/chip';\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 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// Folders and reports are both soft-deletable, and a folder deletes whatever it\n// holds. Only the folder's own row is written: everything under it drops out of\n// the listing because it sits under a deleted folder, and comes back with it.\n// \"Show Deleted\" shows the WHOLE tree — live and deleted together, each deleted\n// row where it was filed — and on anything deleted the kebab offers Restore\n// instead. Restoring also restores any deleted folder above the row, so it lands\n// back where it was rather than at the root.\n//\n// Every folder starts collapsed; the tree remembers what was opened across its\n// own reloads (a rename, a move, the Show Deleted toggle) and across a search.\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 FsChipModule,\n FsFilterModule,\n FsSkeletonModule,\n FsTreeModule,\n MatIconModule,\n RouterLink,\n ],\n})\nexport class FsAiReportsComponent implements OnInit {\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 // The folders that were open when a search started; null while no search is\n // running. The search opens every match's path over the top of them, and\n // clearing it puts these back.\n private _expandedBeforeSearch: string[] | null = null;\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 // Prompt for a title, create the report — filed under reportFolderId when a\n // folder's kebab asked, at the root otherwise — then route to it (createPattern).\n public createReport(reportFolderId: number = null): 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, reportFolderId)),\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 // A checkbox rather than the usual Status select with a \"Show Deleted\"\n // isolate. Isolating the deleted rows would strand them: a deleted\n // report in a live folder arrives without the folder it sits in, and a\n // tree cannot place a node whose parent it never received. So the\n // toggle asks for everything, and the rows mark what is deleted.\n {\n name: 'state',\n type: ItemType.Checkbox,\n label: 'Show Deleted',\n checked: [ReportState.Active, ReportState.Deleted].join(','),\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 each only when it\n // changed. The keyword drives the tree's own search, which is the whole\n // point of searching a tree — it reveals a match nested inside collapsed\n // folders rather than only filtering what is already on screen. `state` is\n // the Show Deleted toggle, and only the server can answer that. Running the\n // search on a toggle would clear it, and clearing collapses the tree.\n change: (query) => {\n const keywordChanged = String(query?.keyword ?? '') !== String(this._query.keyword ?? '');\n const stateChanged = String(query?.state ?? '') !== String(this._query.state ?? '');\n this._query = { ...query };\n\n if (keywordChanged) {\n this._search(query?.keyword);\n }\n\n if (stateChanged) {\n this._load();\n }\n },\n };\n }\n\n private _initTreeConfig(): void {\n // No expandLevel: every folder starts collapsed.\n this.treeConfig = {\n data: [],\n childrenName: 'children',\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 // Anything deleted is restored before it is moved — the backend refuses\n // to edit a deleted row, and a drag would only snap back.\n canDrag: (node: FlatItemNode) => !this._isDeletedNode(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. A deleted folder is no destination\n // either: whatever landed in it would vanish from the live listing.\n canDrop: (node: FlatItemNode, fromParent: FlatItemNode, toParent: FlatItemNode) => {\n return !toParent || (this._isFolderNode(toParent) && !this._isDeletedNode(toParent));\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 report',\n show: (node: FlatItemNode) => this._isFolderNode(node) && !this._isDeletedNode(node),\n click: (node: FlatItemNode) => this.createReport(node.data?.id),\n },\n {\n label: 'New folder',\n show: (node: FlatItemNode) => this._isFolderNode(node) && !this._isDeletedNode(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 // On every deleted row, including a live one that is only hidden by\n // a deleted folder above it — restoring that brings the folder back.\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 !!node?.data?.deleted;\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 collapses everything\n // again, so the folders that were open before the search are put back.\n private _search(keyword: string): void {\n const tree = this._tree();\n if (!tree) {\n return;\n }\n\n if (keyword) {\n this._expandedBeforeSearch ??= this._expandedKeys();\n tree.search(keyword);\n return;\n }\n\n tree.clearSearch();\n this._expandKeys(this._expandedBeforeSearch ?? []);\n this._expandedBeforeSearch = null;\n }\n\n private _load(): void {\n // Only the Show Deleted toggle is the server's to answer — the keyword is\n // the tree's own search — and an unchecked toggle sends nothing, leaving the\n // backend's active-only default in charge.\n const query = this._query.state ? { state: this._query.state } : {};\n\n this._reportData.tree(query)\n .pipe(\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((reportTree: ReportTree) => {\n const nodes = this._buildNodes(reportTree);\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\n const tree = this._tree();\n if (!tree) {\n return;\n }\n\n // setData() rebuilds every node collapsed, so a rename or a move would\n // otherwise slam shut every folder somebody had opened. Keys are stable\n // across loads ('f:12'), so what was open is reopened by key — and a\n // folder that no longer comes back simply is not.\n const expandedKeys = this._expandedKeys();\n tree.setData(nodes);\n this._expandKeys(expandedKeys);\n\n const keyword = String(this._query.keyword ?? '');\n if (keyword) {\n tree.search(keyword);\n }\n });\n }\n\n // The keys of every open folder, walked through the tree's public node API.\n private _expandedKeys(): string[] {\n const tree = this._tree();\n if (!tree) {\n return [];\n }\n\n const walk = (parent: FlatItemNode): string[] => tree.getNodes(parent)\n .filter((node: FlatItemNode) => node.isExpanded())\n .flatMap((node: FlatItemNode) => [node.data?.key, ...walk(node)]);\n\n return walk(null);\n }\n\n private _expandKeys(keys: string[]): void {\n const tree = this._tree();\n if (!tree || !keys.length) {\n return;\n }\n\n const open = new Set(keys);\n const walk = (parent: FlatItemNode): void => {\n tree.getNodes(parent)\n .filter((node: FlatItemNode) => open.has(node.data?.key))\n .forEach((node: FlatItemNode) => {\n node.expand();\n walk(node);\n });\n };\n\n walk(null);\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 //\n // `deleted` is inherited downward: a deleted folder hides everything below it\n // without the rows below being deleted themselves, and that is only visible\n // from here, where the parent is in hand. The backend applies the same rule\n // when it filters (ReportFolderModel::getDeletedFolderIds()).\n private _buildNodes(reportTree: ReportTree): ReportNode[] {\n const folders = reportTree?.folders ?? [];\n const reports = reportTree?.reports ?? [];\n\n const build = (parentId: number | null, parentDeleted: boolean): ReportNode[] => {\n const folderNodes: ReportNode[] = folders\n .filter((folder: ReportFolder) => (folder.parentReportFolderId ?? null) === parentId)\n .map((folder: ReportFolder) => {\n const stateDeleted = folder.state === ReportState.Deleted;\n const deleted = parentDeleted || stateDeleted;\n\n return {\n key: `f:${folder.id}`,\n id: folder.id,\n name: folder.name,\n type: ReportNodeType.Folder,\n children: build(folder.id, deleted),\n stateDeleted,\n deleted,\n };\n });\n\n const reportNodes: ReportNode[] = reports\n .filter((report: ReportListItem) => (report.reportFolderId ?? null) === parentId)\n .map((report: ReportListItem) => {\n const stateDeleted = report.state === ReportState.Deleted;\n\n return {\n key: `r:${report.id}`,\n id: report.id,\n name: report.name,\n type: ReportNodeType.Report,\n children: [],\n report,\n stateDeleted,\n deleted: parentDeleted || stateDeleted,\n };\n });\n\n return [...folderNodes, ...reportNodes];\n };\n\n return build(null, false);\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 // A folder deletes with everything in it, so the confirm says what that is —\n // and that it all comes back from Show Deleted, which is what makes it safe to\n // offer.\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 ? this._deleteFolderMessage(data)\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 // Counted from the node already on screen, live rows only: in Show Deleted\n // mode the folder can also hold rows that are gone already, and those are not\n // leaving with it.\n private _deleteFolderMessage(folder: ReportNode): string {\n const count = (node: ReportNode): { folders: number; reports: number } => node.children\n .filter((child) => !child.deleted)\n .reduce((total, child) => {\n const below = count(child);\n\n return {\n folders: total.folders + below.folders + (child.type === ReportNodeType.Folder ? 1 : 0),\n reports: total.reports + below.reports + (child.type === ReportNodeType.Report ? 1 : 0),\n };\n }, { folders: 0, reports: 0 });\n\n const { folders, reports } = count(folder);\n const contents = [\n folders ? `${folders} ${folders === 1 ? 'folder' : 'folders'}` : '',\n reports ? `${reports} ${reports === 1 ? 'report' : 'reports'}` : '',\n ].filter(Boolean);\n\n const inside = contents.length ? ` and the ${contents.join(' and ')} inside it` : '';\n\n return `Are you sure you would like to delete the folder \"${folder.name}\"${inside}? It can be restored from Show Deleted.`;\n }\n\n // Both endpoints also restore any deleted folder above the row, so a row that\n // is live itself but hidden by a deleted folder is restored by the same call.\n private _restore(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 (folder\n ? this._reportData.undeleteFolder(data.id)\n : this._reportData.undelete(data.id))\n .pipe(\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success(folder ? 'Restored folder' : '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\n class=\"fs-row.gap-sm.align-center node-row\"\n [class.deleted]=\"data.deleted\">\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 || data.deleted) {\n <!-- A deleted report can't be opened (the backend only assembles\n live ones, and one under a deleted folder is not on the live\n listing), 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\n <!-- Only on the row somebody deleted. Everything under a deleted\n folder is muted with it, but was not deleted itself. -->\n @if (data.stateDeleted) {\n <fs-chip size=\"tiny\">Deleted</fs-chip>\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 { Injectable } from '@angular/core';\n\nimport { FsAiChatData } from '@firestitch/ai';\n\n\n// The parent's own parameter types, so the override always matches the\n// @firestitch/ai build it extends (a linked build carries its own\n// @firestitch/api, whose RequestConfig is a different type).\ntype ChatStreamBody = Parameters<FsAiChatData['chatStream']>[1];\ntype ChatStreamConfig = Parameters<FsAiChatData['chatStream']>[2];\ntype ChatStream = ReturnType<FsAiChatData['chatStream']>;\n\n\n// The report view's chat gateway: the stock one, plus fields read at the\n// moment each turn is sent and merged into that turn's body only. The chat's\n// requestData can't carry them, because it is also the key of the conversation\n// list, and a change there reloads the list and drops the open conversation.\n//\n// It relies on FsAiChatData.chatStream(basePath, body, config) being the one\n// path a turn takes. Nothing else is overridden, so the conversation list and\n// the create never see these fields. It stands in for a per-turn input on\n// fs-ai-chat itself, and can be removed when @firestitch/ai ships one.\n@Injectable()\nexport class ReportAiChatData extends FsAiChatData {\n\n // Set by the host view. A function, so it is read at send time.\n public turnData: () => Record<string, unknown> = () => ({});\n\n public override chatStream(basePath: string, body: ChatStreamBody, config: ChatStreamConfig = {}): ChatStream {\n return super.chatStream(basePath, { ...body, ...this.turnData() }, config);\n }\n}\n","import {\r\n CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component,\r\n DestroyRef, ElementRef, NgZone, ViewChild, computed, effect, inject, input, output, signal, untracked,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { ActivatedRoute, Params, 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 { Subject, merge } from 'rxjs';\r\nimport { auditTime, switchMap, takeUntil, tap } from 'rxjs/operators';\r\n\r\nimport { provideEchartsCore } from 'ngx-echarts';\r\n\r\nimport { FsAiChatComponent, FsAiChatData, FsAiChatResponse } from '@firestitch/ai';\r\n\r\nimport { ReportCanvasComponent } from '../../components/report-canvas/report-canvas.component';\r\nimport { ReportAiChatData } from '../../data/report-ai-chat.data';\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 { getTimezoneLabel } from '../../format';\r\nimport { ReportChatViewerState } from '../../interfaces/report-chat-viewer-state.interface';\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 { buildReportUrlParams, readReportUrlParams } from '../../report-url-state';\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 through its own routes — this component never\r\n// 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 // fs-ai-chat sits in this template, so it resolves its gateway here: the\r\n // report one, which adds the viewer's state to each turn it sends.\r\n ReportAiChatData,\r\n { provide: FsAiChatData, useExisting: ReportAiChatData },\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 // Whether the viewer's filters, group-by grain and list sorts live in the URL\r\n // (g<groupId>, groupBy, s<componentId>; see report-url-state.ts), so a\r\n // refresh or a shared link opens the report as it was seen. On by default; a\r\n // host that mounts several reports on one route, or uses query keys shaped\r\n // like g<n> or s<n> itself, turns it off.\r\n public readonly urlState = input<boolean>(true);\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. This view writes the URL itself (right\r\n // after this fires) — this is for hosts that track the open page for their\r\n // own reasons.\r\n public readonly pageChanged = output<number | null>();\r\n\r\n public readonly report = signal<Report | null>(null);\r\n public readonly editMode = signal(false);\r\n\r\n // The toolbar's zone indicator ('New York (EDT)'): the zone every date in\r\n // this report is filtered and grouped in. Empty when the server is too old\r\n // to send the effective zone, and the indicator is not shown.\r\n public readonly timezoneLabel = computed(() => {\r\n const effectiveTimezone = this.report()?.effectiveTimezone;\r\n\r\n return effectiveTimezone ? getTimezoneLabel(effectiveTimezone) : '';\r\n });\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 readonly pageId = signal<number | null>(null);\r\n\r\n // The page the chat is bound to: the one on screen. A report conversation\r\n // belongs to exactly one page, so this both scopes the conversation list and\r\n // becomes the new conversation's page. A signal because it feeds\r\n // [requestData] — changing it is what reloads the panel onto the new page's\r\n // conversations. Null until the canvas reports which page it opened on, which\r\n // keeps the chat from listing against a page guess.\r\n public readonly chatPageId = signal<number | null>(null);\r\n\r\n // What the chat sends with every conversation call: the report, and the page\r\n // it is bound to.\r\n //\r\n // reportPageId is OMITTED, not sent as null, while the open page is unknown.\r\n // The backend reads a PRESENT reportPageId of 0/null as \"the report's earlier,\r\n // page-less conversations\", so sending null before the canvas has reported in\r\n // would ask for the wrong list — and, worse, would bind a conversation started\r\n // in that window to no page at all.\r\n //\r\n // The chat is also held closed ([ready] in the template) until the page is\r\n // known, so this partial context is never actually sent: on a fresh load the\r\n // report has to arrive and the canvas has to render before any page exists,\r\n // and a list fetched in that window would be the whole report's conversations\r\n // — the unscoped list, shown and auto-selected before the real one lands.\r\n public readonly chatRequestData = computed<Record<string, unknown>>(() => {\r\n const reportPageId = this.chatPageId();\r\n\r\n return reportPageId === null\r\n ? { reportId: this.reportId() }\r\n : { reportId: this.reportId(), reportPageId };\r\n });\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 readonly reportFilterConfig = signal<FilterConfig | null>(null);\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 readonly reportHasFilters = computed(() => {\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 readonly reportFilterKey = computed(() => {\r\n return [\r\n // The effective zone is part of it too: a zone change re-resolves relative\r\n // presets, and the bar must be recreated to show the new days.\r\n this._filterState.timezone(),\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 @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 _reportAiChatData = inject(ReportAiChatData);\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 _collector = inject(ReportExportCollectorService);\r\n private _process = inject(FsProcess);\r\n private _dialog = inject(MatDialog);\r\n private _destroyRef = inject(DestroyRef);\r\n private _zone = inject(NgZone);\r\n\r\n // The report whose URL state has been read. The URL is read only on a\r\n // report's first load; a reload after a chat or dialog edit keeps the state\r\n // in memory, which is newer than anything the URL holds.\r\n private _restoredReportId: number | null = null;\r\n\r\n // Whether the canvas has reported the open page for this report. Until it\r\n // has, the page param in the URL is the deep link still being honored, and\r\n // the URL writer leaves it alone.\r\n private _pageReported = false;\r\n\r\n // The canvas moved to another page. Merged into the single URL writer.\r\n private _pageWrite$ = new Subject<void>();\r\n\r\n constructor() {\r\n // Each chat turn carries what the viewer has on screen. Only the function\r\n // is set here; it is called when a turn is sent.\r\n this._reportAiChatData.turnData = () => ({ viewerState: this._chatViewerState() });\r\n\r\n // The ONE writer of this view's query params. Page moves and viewer-state\r\n // changes both funnel here, and auditTime(0) folds a burst (a bar re-sets\r\n // every group it shows) into a single write. Every write carries the whole\r\n // state, so a write that supersedes another loses nothing.\r\n merge(this._filterState.urlChanges(), this._pageWrite$)\r\n .pipe(\r\n auditTime(0),\r\n tap(() => this._writeUrl()),\r\n takeUntilDestroyed(this._destroyRef),\r\n )\r\n .subscribe();\r\n\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\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 const pageId = this._pageIdFromUrl();\r\n\r\n // Only the report id and the page param re-run this. The view state below\r\n // is written here and read by the config build, so it stays untracked.\r\n untracked(() => {\r\n this.editMode.set(false);\r\n\r\n // A new report's pages are not this report's pages — drop the binding\r\n // until its canvas says which page it landed on.\r\n this.chatPageId.set(null);\r\n this.pageId.set(pageId);\r\n this._pageReported = false;\r\n\r\n if (reportId != null) {\r\n this._loadReport(reportId);\r\n } else {\r\n // Forget the restored report, so a host that comes back to it reads\r\n // the URL again.\r\n this._restoredReportId = null;\r\n this.report.set(null);\r\n this._buildReportConfig();\r\n }\r\n });\r\n });\r\n\r\n this._buildReportConfig();\r\n }\r\n\r\n public toggleEditMode(): void {\r\n this.editMode.update((editMode) => !editMode);\r\n }\r\n\r\n // The edit tools live in this toolbar, but the canvas owns what they act on\r\n // (the active page, the header/footer bands, which layer is live).\r\n public get isMasterMode(): boolean {\r\n return this._canvas?.masterMode() ?? false;\r\n }\r\n\r\n public addText(): void {\r\n this._canvas?.addText();\r\n }\r\n\r\n public toggleMasterMode(): void {\r\n this._canvas?.toggleMasterMode();\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 const report = this.report();\r\n if (!report) {\r\n return;\r\n }\r\n\r\n const reportId = report.id;\r\n\r\n this._dialog.open<ReportSettingsComponent, unknown, ReportSettingsResult>(ReportSettingsComponent, {\r\n data: { 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 const report = this.report();\r\n if (!report) {\r\n return;\r\n }\r\n\r\n const reportId = report.id;\r\n\r\n const dialogRef = this._dialog.open<ComponentSettingsComponent, unknown, ComponentSettingsResult>(\r\n ComponentSettingsComponent,\r\n {\r\n data: { 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 dialog confirms + performs the delete itself. The component is\r\n // gone from the report, so reload rather than patching it out locally —\r\n // its filters went with it, which the report bar has to be rebuilt for.\r\n if (result?.deleted) {\r\n this._loadReport(reportId);\r\n\r\n return;\r\n }\r\n\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 (the write itself is _writeUrl's).\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.set(null);\r\n this.chatPageId.set(pageId);\r\n this._pageReported = true;\r\n this.pageChanged.emit(pageId);\r\n this._pageWrite$.next();\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 const report = this.report();\r\n if (report) {\r\n this._loadReport(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 const report = this.report();\r\n if (!report) {\r\n return;\r\n }\r\n\r\n this._process.run(\r\n 'Exporting PowerPoint',\r\n this._exportService.powerpoint(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 const report = this.report();\r\n if (!report) {\r\n return;\r\n }\r\n\r\n this._process.run(\r\n 'Exporting PDF',\r\n this._exportService.pdf(report),\r\n );\r\n }\r\n\r\n // The whole report as files in one action: the server writes one CSV per\r\n // component, each what the screen shows (a chart or KPI as drawn, at the\r\n // viewer's group-by grain; a list in full), and zips them foldered by page\r\n // with an Export Notes.txt that records the filters as the bar reads them.\r\n // Lists use their saved default sort; a header click is carried only by a\r\n // component's own CSV export. `thisPage` narrows it to the page the canvas is\r\n // showing. Unlike the PDF/PowerPoint exports the files are written\r\n // server-side, so they are 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 const filters = this._filterState.resolveForReport(report, pageId);\r\n const frequency = this._filterState.frequency();\r\n\r\n this._process.download(\r\n 'Exporting data',\r\n this._collector.getFilterSummary(report)\r\n .pipe(\r\n switchMap((lines) => this._reportData.exportReport(\r\n report.id,\r\n filters,\r\n pageId,\r\n frequency,\r\n lines,\r\n )),\r\n ),\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 // What the viewer has on screen as a chat turn sends it. The canvas\r\n // selection counts only in edit mode: it is drawn only then, and it is kept\r\n // (not cleared) when edit mode is left.\r\n private _chatViewerState(): ReportChatViewerState {\r\n return {\r\n granularity: this._filterState.frequency(),\r\n selectedComponentId: this.editMode() ? this._canvas?.selectedComponentId() ?? null : null,\r\n filters: this._filterState.viewerFilters(),\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 // Writes the open page and the viewer state into the URL in one go. Only\r\n // the keys this view owns are touched ('merge'), and replaceUrl keeps the\r\n // writes out of the browser history: Back leaves the report rather than\r\n // walking every page and filter visited.\r\n private _writeUrl(): void {\r\n const report = this.report();\r\n\r\n // A report still on screen while the host's next one loads must not write\r\n // its state over the new report's URL.\r\n if (!report || report.id !== this.reportId()) {\r\n return;\r\n }\r\n\r\n const queryParams: Params = this.urlState()\r\n ? buildReportUrlParams(this._filterState.urlSnapshot(report), this._route.snapshot.queryParamMap)\r\n : {};\r\n\r\n const pageParam = this.pageQueryParam();\r\n if (pageParam && this._pageReported) {\r\n queryParams[pageParam] = this.chatPageId();\r\n }\r\n\r\n if (!Object.keys(queryParams).length) {\r\n return;\r\n }\r\n\r\n this._router.navigate([], {\r\n relativeTo: this._route,\r\n queryParams,\r\n queryParamsHandling: 'merge',\r\n replaceUrl: true,\r\n });\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 // The URL is read once per report, on its first load; every later load\r\n // keeps the state in memory.\r\n const restore = this.urlState() && reportId !== this._restoredReportId\r\n ? readReportUrlParams(this._route.snapshot.queryParamMap)\r\n : null;\r\n this._restoredReportId = reportId;\r\n\r\n this.report.set(report);\r\n this._filterState.init(report, restore);\r\n this._buildReportConfig();\r\n\r\n if (emitRenamed) {\r\n this.renamed.emit(report);\r\n }\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 // (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 report = this.report();\r\n const reportId = 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 (report && !isGranularityOffered(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.set({\r\n // fs-filter never touches the URL or persists filter state: its keys are\r\n // not namespaced, it writes outside the router, and it would freeze a\r\n // rolling range as two dates. ReportFilterStateService owns the values,\r\n // and _writeUrl is the one writer of the URL.\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 const report = this.report();\r\n\r\n return report\r\n ? groupByFilterItem(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 <!-- What layout editing can add or switch to, and the way out of it.\n One style for all three — outlined, icon and text. \"Header & footer\"\n is a toggle: it keeps its label and turns gray while it is on. -->\n @if (editMode()) {\n <div class=\"fs-ai-report__edit-tools fs-row.align-center.gap-xs\">\n <button\n mat-stroked-button\n type=\"button\"\n matTooltip=\"Add a block of text\"\n (click)=\"addText()\">\n <mat-icon>title</mat-icon>\n Add text\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"fs-ai-report__master\"\n [class.active]=\"isMasterMode\"\n [matTooltip]=\"isMasterMode ? 'Back to editing this page' : 'Edit the header and footer shown on every page'\"\n (click)=\"toggleMasterMode()\">\n <mat-icon>web_asset</mat-icon>\n Header & footer\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"toggleEditMode()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n </div>\n }\n\n <!-- The zone every date in this report is filtered and grouped in, the\n same for every viewer. Shown only when the server sends it; a click\n opens Report settings, where it is changed. -->\n @if (report()?.effectiveTimezone; as effectiveTimezone) {\n <button\n mat-button\n type=\"button\"\n class=\"fs-ai-report__timezone\"\n [matTooltip]=\"'Dates are filtered and grouped in ' + effectiveTimezone + ' for everyone. Change it in Report settings.'\"\n (click)=\"reportSettings()\">\n <mat-icon>schedule</mat-icon>\n {{ timezoneLabel() }}\n </button>\n }\n\n <!-- One icon for both states: it reads as pressed while editing rather\n than swapping to something else. -->\n <button\n mat-icon-button\n type=\"button\"\n class=\"fs-ai-report__toggle\"\n [class.active]=\"editMode()\"\n [matTooltip]=\"editMode() ? 'Done editing' : 'Edit layout'\"\n (click)=\"toggleEditMode()\">\n <mat-icon>dashboard_customize</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]=\"chatRequestData()\"\n [ready]=\"chatPageId() !== null\"\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 </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';\nexport * from './app/reports/enums/report-value-format.enum';\nexport * from './app/reports/enums/report-list-column-format.enum';\nexport * from './app/reports/enums/report-number-units.enum';\nexport * from './app/reports/enums/report-chart-data-labels.enum';\nexport * from './app/reports/enums/report-chart-color.enum';\nexport * from './app/reports/enums/report-chart-line-style.enum';\nexport * from './app/reports/enums/report-chart-mark-stat.enum';\nexport * from './app/reports/enums/report-chart-date-label.enum';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["i1","rxFilter","TOKENS","map","switchMap","tap","i2","i3","i5","i6","i9","MatOption","TITLE_H","i4"],"mappings":"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"}