bways-report 0.1.6 → 0.1.7

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 (98) hide show
  1. package/README.md +293 -464
  2. package/esm2022/lib/core/config/bways-report-config.mjs +83 -0
  3. package/esm2022/lib/core/index.mjs +2 -1
  4. package/esm2022/lib/core/models/report-definition.model.mjs +1 -1
  5. package/esm2022/lib/core/services/report-data-discovery.service.mjs +6 -3
  6. package/esm2022/lib/core/services/report-session-context.service.mjs +11 -7
  7. package/esm2022/lib/core/tokens/reporting-config.token.mjs +1 -1
  8. package/esm2022/lib/core/utils/data-normalization.util.mjs +87 -1
  9. package/esm2022/lib/core/utils/report-parameter.util.mjs +119 -3
  10. package/esm2022/lib/data-access/adapters/endpoint-datasource.adapter.mjs +69 -0
  11. package/esm2022/lib/data-access/adapters/endpoint-lookup.adapter.mjs +98 -0
  12. package/esm2022/lib/data-access/adapters/endpoint-masterdata.adapter.mjs +57 -0
  13. package/esm2022/lib/data-access/adapters/endpoint-persistence.adapter.mjs +85 -0
  14. package/esm2022/lib/data-access/adapters/endpoint-schema-discovery.adapter.mjs +163 -0
  15. package/esm2022/lib/data-access/adapters/endpoint-tokens.mjs +12 -0
  16. package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +4 -23
  17. package/esm2022/lib/data-access/adapters/index.mjs +8 -1
  18. package/esm2022/lib/data-access/contracts/lookup.contract.mjs +1 -1
  19. package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +12 -2
  20. package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +5 -5
  21. package/esm2022/lib/features/designer/components/dialogs/report-saved-dialog.component.mjs +407 -0
  22. package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +109 -60
  23. package/esm2022/lib/features/designer/components/property-editor/property-editor-action.component.mjs +3 -3
  24. package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +110 -20
  25. package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +3 -3
  26. package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +60 -3
  27. package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +11 -5
  28. package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +3 -3
  29. package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +15 -3
  30. package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +204 -10
  31. package/esm2022/lib/features/designer/designer.component.mjs +43 -2
  32. package/esm2022/lib/features/designer/services/designer-state.service.mjs +9 -2
  33. package/esm2022/lib/features/embed/bways-report-builder.component.mjs +207 -0
  34. package/esm2022/lib/features/embed/bways-report-menu.component.mjs +433 -0
  35. package/esm2022/lib/features/embed/bways-report-page.component.mjs +204 -0
  36. package/esm2022/lib/features/embed/index.mjs +5 -0
  37. package/esm2022/lib/features/embed/inject-report-menu.mjs +99 -0
  38. package/esm2022/lib/features/index.mjs +2 -1
  39. package/esm2022/lib/features/persistence/services/report-store.service.mjs +43 -5
  40. package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +4 -4
  41. package/esm2022/lib/features/routing/index.mjs +2 -2
  42. package/esm2022/lib/features/routing/models/report-route.models.mjs +1 -1
  43. package/esm2022/lib/features/routing/report-routes.mjs +42 -1
  44. package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +6 -8
  45. package/esm2022/lib/features/routing/services/report-menu.service.mjs +14 -4
  46. package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +22 -3
  47. package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +16 -2
  48. package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +28 -5
  49. package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +86 -19
  50. package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +8 -1
  51. package/esm2022/lib/primitives/components/index.mjs +2 -1
  52. package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +9 -3
  53. package/esm2022/lib/primitives/components/searchable-select/rpt-searchable-select.component.mjs +386 -0
  54. package/esm2022/lib/provide-reporting.mjs +137 -7
  55. package/fesm2022/bways-report.mjs +4053 -840
  56. package/fesm2022/bways-report.mjs.map +1 -1
  57. package/lib/core/config/bways-report-config.d.ts +161 -0
  58. package/lib/core/index.d.ts +1 -0
  59. package/lib/core/models/report-definition.model.d.ts +16 -0
  60. package/lib/core/services/report-session-context.service.d.ts +1 -0
  61. package/lib/core/tokens/reporting-config.token.d.ts +16 -0
  62. package/lib/core/utils/data-normalization.util.d.ts +10 -0
  63. package/lib/core/utils/report-parameter.util.d.ts +18 -1
  64. package/lib/data-access/adapters/endpoint-datasource.adapter.d.ts +13 -0
  65. package/lib/data-access/adapters/endpoint-lookup.adapter.d.ts +14 -0
  66. package/lib/data-access/adapters/endpoint-masterdata.adapter.d.ts +11 -0
  67. package/lib/data-access/adapters/endpoint-persistence.adapter.d.ts +15 -0
  68. package/lib/data-access/adapters/endpoint-schema-discovery.adapter.d.ts +21 -0
  69. package/lib/data-access/adapters/endpoint-tokens.d.ts +21 -0
  70. package/lib/data-access/adapters/index.d.ts +7 -0
  71. package/lib/data-access/contracts/lookup.contract.d.ts +2 -2
  72. package/lib/features/designer/components/component-palette/component-palette.component.d.ts +1 -0
  73. package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +1 -1
  74. package/lib/features/designer/components/dialogs/report-saved-dialog.component.d.ts +34 -0
  75. package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +1 -0
  76. package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +12 -2
  77. package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +10 -0
  78. package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +13 -1
  79. package/lib/features/designer/designer.component.d.ts +4 -0
  80. package/lib/features/embed/bways-report-builder.component.d.ts +48 -0
  81. package/lib/features/embed/bways-report-menu.component.d.ts +40 -0
  82. package/lib/features/embed/bways-report-page.component.d.ts +61 -0
  83. package/lib/features/embed/index.d.ts +4 -0
  84. package/lib/features/embed/inject-report-menu.d.ts +44 -0
  85. package/lib/features/index.d.ts +1 -0
  86. package/lib/features/persistence/services/report-store.service.d.ts +5 -0
  87. package/lib/features/routing/index.d.ts +1 -1
  88. package/lib/features/routing/models/report-route.models.d.ts +3 -0
  89. package/lib/features/routing/report-routes.d.ts +40 -0
  90. package/lib/features/routing/resolvers/report.resolver.d.ts +1 -1
  91. package/lib/features/runtime/dynamic-renderer.component.d.ts +1 -0
  92. package/lib/features/runtime/report-grid-bridge.component.d.ts +1 -1
  93. package/lib/primitives/components/button/rpt-button.component.d.ts +3 -0
  94. package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +16 -3
  95. package/lib/primitives/components/index.d.ts +2 -0
  96. package/lib/primitives/components/searchable-select/rpt-searchable-select.component.d.ts +89 -0
  97. package/lib/provide-reporting.d.ts +22 -6
  98. package/package.json +1 -1
package/README.md CHANGED
@@ -1,605 +1,441 @@
1
1
  # BWays-Report — Integration & Developer Guide
2
2
 
3
- `bways-report` is an enterprise-grade, metadata-driven reporting platform and visual dynamic page builder for Angular 18+ business & ERP applications.
3
+ `bways-report` is an enterprise reporting platform and visual drag-and-drop page builder for Angular 18+ business & ERP applications with NestJS / SQL Server.
4
4
 
5
- It allows non-developers to visually design reporting pages with filters, KPI metric cards, charts, and grids. The report configuration is saved purely as JSON metadata (`ReportDefinition`), and the runtime engine dynamically instantiates the reactive forms, controls, data queries, and results grid on the fly.
5
+ It empowers developers and business users to visually design reporting pages with filters, lookup dropdowns, metric cards, charts, and data grids. Report configurations are saved as clean JSON metadata (`ReportDefinition`), and the runtime engine dynamically generates reactive forms, controls, queries, and live grid views on the fly.
6
6
 
7
7
  ---
8
8
  [![npm version](https://img.shields.io/npm/v/bways-report.svg)](https://www.npmjs.com/package/bways-report)
9
- [![license](https://img.shields.io/npm/l/bways-report.svg)](https://github.com/ccplProject/BWays-CustomeReport)
10
- [![Changelog](https://img.shields.io/badge/Changelog-v0.1.6-blue.svg)](CHANGELOG.md)
9
+ [![license](https://img.shields.io/badge/License-Proprietary-blue.svg)](LICENSE)
10
+ [![Changelog](https://img.shields.io/badge/Changelog-v0.2.0-blue.svg)](CHANGELOG.md)
11
+ ---
12
+
13
+ ## What's New in v0.2.0
14
+
15
+ - **1 Config Object + 3 Drop-in Components**: Eliminate boilerplate adapters with `BwaysReportConfig` and drop-in tags.
16
+ - **`<bways-report-builder>`**: Drop-in visual designer shell with width/height controls, starter blueprints, and save flow.
17
+ - **`<bways-report-page>`**: Live runtime form & dynamic grid page rendered automatically from a report slug.
18
+ - **`<bways-report-menu>` & `injectReportMenu()`**: Responsive navigation menu (sidebar, navbar, dropdown) with search and category folding.
19
+ - **`bwaysReportRoutes()`**: Declarative Angular routing for live report pages (`/reports/:slug`).
20
+ - **Post-Save Interactive Modal**: Immediate live form preview with page routing settings (slug, menu group, publish toggle).
21
+ - **CDK Overlay Viewport Flipping**: Zero clipping for searchable dropdowns inside cards and scroll containers.
22
+ - **Quick Action ("+") & Inline Renaming**: Double-click report title to rename in place; `+` button to start fresh pages.
23
+
11
24
  ---
12
25
 
13
26
  ## Table of Contents
14
27
 
15
- 1. [Automated Setup (ng add)](#1-automated-setup-ng-add)
16
- 2. [Quick Start (Rule of 1)](#2-quick-start-rule-of-1)
17
- - [A. 1-Line App Setup](#a-1-line-app-setup)
18
- - [B. 1-Tag Runtime Page](#b-1-tag-runtime-page)
19
- - [C. 1-Tag Visual Report Designer](#c-1-tag-visual-report-designer)
20
- - [D. Saved Views & Presets in JSON](#d-saved-views--presets-in-json)
21
- 3. [Configuration Options & Zero-Backend Dev](#3-configuration-options--zero-backend-dev)
22
- 4. [Implementing Host Adapters (Advanced)](#4-implementing-host-adapters)
23
- - [A. Data Source Adapter (Query Execution)](#a-data-source-adapter)
24
- - [B. Persistence Adapter (Saving & Loading Reports)](#b-persistence-adapter)
25
- - [C. Master Data Provider (Dropdown Lookups)](#c-master-data-provider)
26
- 5. [Routing & ERP Navigation Integration](#5-routing--erp-navigation-integration)
27
- 6. [Drill-Down Drill-Through & Slide-Over Drawers](#6-drill-down--slide-over-drawers)
28
- 7. [Starter Blueprints Gallery & Branded Exports](#7-starter-blueprints--branded-exports)
29
- 8. [Grid Bridge & Circular Echo Suppression](#8-grid-bridge--circular-echo-suppression)
30
- 9. [Stored Procedure Discovery & Smart Parameter Mapping](#9-stored-procedure-discovery--smart-parameter-mapping)
31
- 10. [Theming & CSS Custom Properties](#10-theming--css-custom-properties)
32
- 11. [Exporting Data (CSV & JSON)](#11-exporting-data-csv--json)
33
- 12. [Changelog & Version History](#12-changelog--version-history)
28
+ 1. [Quick Start (5 Steps)](#1-quick-start-5-steps)
29
+ - [Step 1: Install](#step-1-install)
30
+ - [Step 2: Configure Once (`app.config.ts`)](#step-2-configure-once-appconfigts)
31
+ - [Step 3: Drop-in Builder Component](#step-3-drop-in-builder-component)
32
+ - [Step 4: Host Navigation Menu](#step-4-host-navigation-menu)
33
+ - [Step 5: Declarative Routes (`app.routes.ts`)](#step-5-declarative-routes-approutests)
34
+ 2. [Visual Designer Features](#2-visual-designer-features)
35
+ - [Single-Mode Technical Property Editor](#single-mode-technical-property-editor)
36
+ - [CDK Overlay Viewport Flip](#cdk-overlay-viewport-flip)
37
+ - [Post-Save Live Preview & Settings Dialog](#post-save-live-preview--settings-dialog)
38
+ - [Inline Double-Click Renaming](#inline-double-click-renaming)
39
+ - [Report Switcher & Quick New Page ("+")](#report-switcher--quick-new-page-)
40
+ 3. [Backend Contract Reference](#3-backend-contract-reference)
41
+ 4. [Dynamic Session Context & Auto-Parameter Binding](#4-dynamic-session-context--auto-parameter-binding)
42
+ 5. [Plugging in BWays-Grid (`UltraGridComponent`)](#5-plugging-in-bways-grid-ultragridcomponent)
43
+ 6. [Advanced Custom Adapters](#6-advanced-custom-adapters)
44
+ 7. [Theming & CSS Custom Properties](#7-theming--css-custom-properties)
45
+ 8. [Exporting Data (CSV & JSON)](#8-exporting-data-csv--json)
34
46
 
35
47
  ---
36
48
 
37
- ## 1. Automated Setup (ng add)
49
+ ## 1. Quick Start (5 Steps)
38
50
 
39
- Run the Angular CLI schematic to configure your application in seconds:
51
+ ### Step 1: Install
40
52
 
41
53
  ```bash
42
- ng add bways-report
54
+ npm install bways-report bways-grid @angular/cdk
43
55
  ```
44
56
 
45
- This automatically installs required dependencies and adds `provideReporting()` to your `src/app/app.config.ts`.
57
+ > **Compatibility**: Angular 18+ or 19+ standalone architecture with Zone.js or Zoneless change detection.
46
58
 
47
59
  ---
48
60
 
49
- ## 2. Quick Start (Rule of 1)
50
-
51
- ### A. 1-Line App Setup
61
+ ### Step 2: Configure Once (`app.config.ts`)
52
62
 
53
- In your Angular 18+ application:
63
+ Configure `provideBwaysReport()` with a single `BwaysReportConfig` object:
54
64
 
55
65
  ```typescript
56
66
  // src/app/app.config.ts
57
- import { ApplicationConfig } from '@angular/core';
58
- import { provideReporting } from 'bways-report';
67
+ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
68
+ import { provideHttpClient } from '@angular/common/http';
69
+ import { provideRouter } from '@angular/router';
70
+ import { provideBwaysReport, BwaysReportConfig } from 'bways-report';
71
+ import { UltraGridComponent } from 'bways-grid';
72
+ import { routes } from './app.routes';
73
+ import { AuthService } from './services/auth.service';
74
+
75
+ const reportConfig: BwaysReportConfig = {
76
+ // Backend Endpoints (only these 3-4 URLs needed)
77
+ spEndpoint: 'http://localhost:3000/api/reporting/procedures', // GET -> SPs + parameters
78
+ tablesEndpoint: 'http://localhost:3000/api/reporting/tables', // GET -> Tables + columns
79
+ executeEndpoint: 'http://localhost:3000/api/reporting/execute', // POST -> Query / SP execution
80
+ lookupEndpoint: 'http://localhost:3000/api/reporting/lookup', // POST -> Dropdown master data / lookup (optional)
81
+ reportsEndpoint: 'http://localhost:3000/api/reporting/reports', // Optional CRUD (defaults to localStorage)
82
+
83
+ // Visual Designer Configuration
84
+ components: ['formInputs', 'actionButtons', 'displayLabels'], // Palette categories to show (default: all)
85
+ autoParameter: true, // Auto-bind @BranchId, @CompanyId from session
86
+ session: () => inject(AuthService).currentSession(), // Session source for autoParameter
87
+
88
+ // Live Pages & Data Grid
89
+ routeBase: 'reports', // Live pages mount at /reports/:slug
90
+ grid: UltraGridComponent, // UltraGrid from bways-grid (or built-in table)
91
+ defaultPageSize: 25,
92
+ };
59
93
 
60
94
  export const appConfig: ApplicationConfig = {
61
95
  providers: [
62
- // 1-line setup: automatically hooks up HTTP adapters, UltraGridComponent, and session headers
63
- provideReporting({ apiBaseUrl: '/api/reporting' }),
96
+ provideZoneChangeDetection({ eventCoalescing: true }),
97
+ provideHttpClient(),
98
+ provideRouter(routes),
99
+ provideBwaysReport(reportConfig),
64
100
  ],
65
101
  };
66
102
  ```
67
103
 
68
- > **Zero-Backend / Local Storage Mode:**
69
- > For local prototyping, offline demos, or frontend-only dev, use:
70
- > ```typescript
71
- > provideReporting(withLocalStorage()); // seeds built-in blueprints and saves to browser localStorage
72
- > ```
73
-
74
104
  ---
75
105
 
76
- ### B. 1-Tag Runtime Page
106
+ ### Step 3: Drop-in Builder Component
77
107
 
78
- Render any saved report with its dynamic filter form, auto-bound stored procedure results, top toolbar, export actions, and saved view presets:
108
+ Embed the full visual drag-and-drop report designer with one HTML tag:
109
+
110
+ ```html
111
+ <!-- src/app/pages/admin-reports/admin-reports.component.html -->
112
+ <bways-report-builder
113
+ width="100%"
114
+ height="calc(100vh - 64px)"
115
+ (saved)="onReportSaved($event)"
116
+ />
117
+ ```
79
118
 
80
119
  ```typescript
120
+ // src/app/pages/admin-reports/admin-reports.component.ts
81
121
  import { Component } from '@angular/core';
82
- import { RptReportComponent } from 'bways-report';
122
+ import { BwaysReportBuilderComponent, ReportDefinition } from 'bways-report';
83
123
 
84
124
  @Component({
85
125
  standalone: true,
86
- imports: [RptReportComponent],
87
- template: `
88
- <!-- 1 tag to run and render the full report page -->
89
- <rpt-report [id]="'sales-ledger'" />
90
- `,
126
+ imports: [BwaysReportBuilderComponent],
127
+ templateUrl: './admin-reports.component.html',
91
128
  })
92
- export class SalesReportPage {}
129
+ export class AdminReportsComponent {
130
+ onReportSaved(report: ReportDefinition): void {
131
+ console.log('Report saved and published:', report.name, report.slug);
132
+ }
133
+ }
93
134
  ```
94
135
 
95
136
  ---
96
137
 
97
- ### C. 1-Tag Visual Report Designer
138
+ ### Step 4: Host Navigation Menu
139
+
140
+ Display published reports in your host ERP navigation bar or sidebar:
98
141
 
99
- Embed the full drag-and-drop report builder into your ERP settings or admin portal:
142
+ #### Option A: Drop-in Component
143
+ ```html
144
+ <!-- Sidebar variant with search filter and category folding -->
145
+ <bways-report-menu variant="sidebar" />
100
146
 
147
+ <!-- Or dropdown variant for top navigation bars -->
148
+ <bways-report-menu variant="dropdown" />
149
+ ```
150
+
151
+ #### Option B: Reactive Signal (`injectReportMenu`)
101
152
  ```typescript
102
153
  import { Component } from '@angular/core';
103
- import { RptReportDesignerComponent } from 'bways-report';
154
+ import { RouterLink, RouterLinkActive } from '@angular/router';
155
+ import { injectReportMenu } from 'bways-report';
104
156
 
105
157
  @Component({
106
158
  standalone: true,
107
- imports: [RptReportDesignerComponent],
159
+ imports: [RouterLink, RouterLinkActive],
108
160
  template: `
109
- <!-- 1 tag to build, preview, or modify any report -->
110
- <rpt-report-designer
111
- [id]="'sales-ledger'"
112
- (saved)="onReportSaved($event)"
113
- />
161
+ <nav class="erp-menu">
162
+ @for (group of menu(); track group.groupName) {
163
+ <div class="menu-group">
164
+ <h3>{{ group.groupName }}</h3>
165
+ @for (item of group.items; track item.id) {
166
+ <a [routerLink]="item.route" routerLinkActive="active">
167
+ {{ item.name }}
168
+ </a>
169
+ }
170
+ </div>
171
+ }
172
+ </nav>
114
173
  `,
115
174
  })
116
- export class ReportBuilderPage {
117
- onReportSaved(definition: any) {
118
- console.log('Report saved successfully:', definition);
119
- }
175
+ export class NavigationSidebarComponent {
176
+ readonly menu = injectReportMenu();
120
177
  }
121
178
  ```
122
179
 
123
180
  ---
124
181
 
125
- ### D. Saved Views & Presets in JSON
126
-
127
- When users filter, reorder, group, or format columns in the grid, they can click **"+ Save View"** to persist their customized view preset. Presets are saved directly into the report's JSON:
182
+ ### Step 5: Declarative Routes (`app.routes.ts`)
128
183
 
129
- ```json
130
- {
131
- "grid": {
132
- "dataSourceId": "ds-sales",
133
- "columns": [...],
134
- "options": {
135
- "presets": [
136
- {
137
- "id": "preset_1728200000",
138
- "name": "Q3 High Value Clients",
139
- "gridState": {
140
- "filters": { "amount": { "operator": "gte", "value": 50000 } },
141
- "columnOrder": ["invoiceId", "amount", "customerName"]
142
- }
143
- }
144
- ]
145
- }
146
- }
147
- }
148
- ```
149
- Users can switch between views seamlessly from the top dropdown, keeping all formatting and custom filters intact.
150
-
151
- ---
152
-
153
- ### Backend Integration: Mounting `BwaysReportingModule` in NestJS
154
-
155
- To power the built-in HTTP adapters, mount `BwaysReportingModule` directly inside your existing NestJS host application:
184
+ Add one line to your route definitions to enable dynamic live report pages:
156
185
 
157
186
  ```typescript
158
- // app.module.ts (in your NestJS backend)
159
- import { Module } from '@nestjs/common';
160
- import { BwaysReportingModule } from '@bways/reporting-backend';
161
-
162
- @Module({
163
- imports: [
164
- BwaysReportingModule.forRoot({
165
- security: {
166
- allowedSchemas: ['dbo', 'reporting'],
167
- disallowRawSql: true, // SQL injection prevention
168
- validateEntitiesAgainstCatalog: true, // Checks sys.procedures catalog
169
- },
170
- }),
171
- ],
172
- })
173
- export class AppModule {}
174
- ```
175
-
176
- ---
177
-
178
- ### Option B: Custom Adapters (Full Manual Control)
187
+ // src/app/app.routes.ts
188
+ import { Routes } from '@angular/router';
189
+ import { bwaysReportRoutes } from 'bways-report';
190
+ import { AdminReportsComponent } from './pages/admin-reports/admin-reports.component';
179
191
 
180
- If you don't use the standard backend endpoints, you can implement your own adapters:
192
+ export const routes: Routes = [
193
+ // Admin visual designer route
194
+ { path: 'admin/reports', component: AdminReportsComponent },
181
195
 
182
- ```typescript
183
- export const appConfig: ApplicationConfig = {
184
- providers: [
185
- provideZoneChangeDetection({ eventCoalescing: true }),
186
- provideRouter(routes),
187
- provideBwaysReport({
188
- gridComponent: BWaysGridComponent,
189
- dataSourceAdapter: MyCustomDataSourceAdapter,
190
- persistenceAdapter: MyCustomPersistenceAdapter,
191
- masterDataProvider: MyCustomMasterDataProvider,
192
- defaultPageSize: 25,
193
- enableDesigner: true,
196
+ // Live user reporting pages: /reports/:slug (e.g. /reports/sale-report)
197
+ {
198
+ path: 'reports',
199
+ children: bwaysReportRoutes({
200
+ // includeBuilderRoute: false, // Set true to include /reports/new and /reports/:slug/edit
194
201
  }),
195
- ],
196
- };
202
+ },
203
+ ];
197
204
  ```
198
205
 
199
- ---
206
+ When users click "Sale Report" in the menu, `/reports/sale-report` opens the **live interactive form** with reactive inputs and data grid without needing custom page components!
200
207
 
201
- ## 3. Implementing Host Adapters
208
+ ---
202
209
 
203
- The library is decoupled from your backend. You provide your business application's API handlers by extending three abstract contracts:
210
+ ## 2. Visual Designer Features
204
211
 
205
- ### A. Data Source Adapter
212
+ ### Single-Mode Technical Property Editor
213
+ Eliminates confusing simplified/advanced toggles. Standardized on technical database terminology:
214
+ - `Database Table / View`
215
+ - `Stored Proc`
216
+ - `Display Field (Visible Text)`
217
+ - `Value Field (Stored Key)`
218
+ - `Dependent On (Cascading Parent Field)`
206
219
 
207
- Responsible for executing report queries and returning tabular result rows:
220
+ ### CDK Overlay Viewport Flip
221
+ Searchable selects (`<rpt-searchable-select>`) and comboboxes (`<rpt-dropdown>`) render inside Angular CDK Overlays attached to the document body. They automatically evaluate available viewport space and flip between `below-start`, `above-start`, `below-end`, and `above-end` to eliminate clipping inside cards and scrollable drawers.
208
222
 
209
- ```typescript
210
- // src/app/services/erp-datasource.adapter.ts
211
- import { Injectable, inject } from '@angular/core';
212
- import { HttpClient } from '@angular/common/http';
213
- import { Observable } from 'rxjs';
214
- import { ReportDataSourceAdapter, ReportDataSourceDefinition } from 'bways-report';
215
-
216
- @Injectable({ providedIn: 'root' })
217
- export class ErpDataSourceAdapter extends ReportDataSourceAdapter {
218
- private readonly http = inject(HttpClient);
219
-
220
- execute(
221
- dataSource: ReportDataSourceDefinition,
222
- parameters: Record<string, unknown>
223
- ): Observable<unknown[]> {
224
- // Send report filter parameters to your backend API endpoint
225
- return this.http.post<unknown[]>(dataSource.endpoint, parameters);
226
- }
227
- }
228
- ```
223
+ ### Post-Save Live Preview & Settings Dialog
224
+ Saving a report in the builder automatically opens a two-column modal:
225
+ - **Left Column**: Page settings (Display Name, URL Slug `/reports/:slug`, Menu Group, Publish to Menu toggle, and a Copy Route button).
226
+ - **Right Column**: Live interactive form preview rendered via `<rpt-runtime>` allowing instant testing of validation and execution before publishing.
229
227
 
230
- ### B. Persistence Adapter
228
+ ### Inline Double-Click Renaming
229
+ Double-click the report title in the toolbar to edit it inline:
230
+ - `Enter` saves the new name and suggests a URL slug.
231
+ - `Escape` cancels edits.
232
+ - `blur` persists the change.
233
+ - Changes are pushed to the undo/redo history stack.
231
234
 
232
- Responsible for saving, loading, listing, and publishing report metadata definitions (`ReportDefinition`):
235
+ ### Report Switcher & Quick New Page ("+")
236
+ - **"+" Button**: Immediately instantiates a fresh blank canvas (with confirmation if unsaved changes exist).
237
+ - **Report Switcher**: Dropdown populated from saved reports allowing rapid switching between report definitions.
233
238
 
234
- ```typescript
235
- // src/app/services/erp-persistence.adapter.ts
236
- import { Injectable, inject } from '@angular/core';
237
- import { HttpClient } from '@angular/common/http';
238
- import { Observable } from 'rxjs';
239
- import {
240
- ReportPersistenceAdapter,
241
- ReportDefinition,
242
- ReportSummary,
243
- } from 'bways-report';
244
-
245
- @Injectable({ providedIn: 'root' })
246
- export class ErpPersistenceAdapter extends ReportPersistenceAdapter {
247
- private readonly http = inject(HttpClient);
248
- private readonly baseUrl = '/api/reports';
249
-
250
- load(reportId: string): Observable<ReportDefinition> {
251
- return this.http.get<ReportDefinition>(`${this.baseUrl}/${reportId}`);
252
- }
239
+ ---
253
240
 
254
- save(report: ReportDefinition): Observable<ReportDefinition> {
255
- return this.http.post<ReportDefinition>(this.baseUrl, report);
256
- }
241
+ ## 3. Backend Contract Reference
257
242
 
258
- list(): Observable<ReportSummary[]> {
259
- return this.http.get<ReportSummary[]>(this.baseUrl);
260
- }
243
+ | Endpoint | Method | Path | Request Format | Response Format |
244
+ | :--- | :--- | :--- | :--- | :--- |
245
+ | `spEndpoint` | `GET` | `/api/reporting/procedures` | None | `StoredProcedureSummary[]` |
246
+ | `tablesEndpoint` | `GET` | `/api/reporting/tables` | None | `TableSummary[]` |
247
+ | `executeEndpoint` | `POST` | `/api/reporting/execute` | `{ kind, name, schema, parameters, columns?, top? }` | `Record<string, unknown>[]` |
248
+ | `reportsEndpoint` *(opt)* | `GET/POST/PUT/DELETE` | `/api/reporting/reports` | JSON `ReportDefinition` | `ReportSummary[]` / `ReportDefinition` |
261
249
 
262
- delete(reportId: string): Observable<void> {
263
- return this.http.delete<void>(`${this.baseUrl}/${reportId}`);
250
+ ### Stored Procedure Discovery Format
251
+ ```json
252
+ [
253
+ {
254
+ "name": "usp_GetCustomerList",
255
+ "schema": "dbo",
256
+ "parameters": [
257
+ { "name": "@BranchId", "sqlType": "int", "required": true },
258
+ { "name": "@SearchTerm", "sqlType": "varchar", "required": false, "defaultValue": "" }
259
+ ]
264
260
  }
261
+ ]
262
+ ```
265
263
 
266
- publish(reportId: string, version: number): Observable<void> {
267
- return this.http.post<void>(`${this.baseUrl}/${reportId}/publish`, { version });
264
+ ### Table Discovery Format
265
+ ```json
266
+ [
267
+ {
268
+ "name": "Customers",
269
+ "schema": "dbo",
270
+ "type": "table",
271
+ "columns": [
272
+ { "name": "CustomerId", "sqlType": "int" },
273
+ { "name": "CustomerName", "sqlType": "nvarchar" }
274
+ ]
268
275
  }
269
- }
276
+ ]
270
277
  ```
271
278
 
272
- ### C. Master Data Provider
279
+ ### Execution Request Format
280
+ Supports both simplified and enterprise DTO contracts out-of-the-box:
273
281
 
274
- Supplies option lists for dropdowns and lookups (e.g., Customers, Warehouses, Statuses):
275
-
276
- ```typescript
277
- // src/app/services/erp-masterdata.provider.ts
278
- import { Injectable, inject } from '@angular/core';
279
- import { HttpClient } from '@angular/common/http';
280
- import { Observable } from 'rxjs';
281
- import { MasterDataProvider, DropdownOption } from 'bways-report';
282
-
283
- @Injectable({ providedIn: 'root' })
284
- export class ErpMasterDataProvider extends MasterDataProvider {
285
- private readonly http = inject(HttpClient);
286
-
287
- getOptions(
288
- masterName: string,
289
- filter?: Record<string, unknown>
290
- ): Observable<DropdownOption[]> {
291
- return this.http.get<DropdownOption[]>(`/api/master-data/${masterName}`, {
292
- params: filter as any,
293
- });
282
+ **Option A (Simplified contract):**
283
+ ```json
284
+ {
285
+ "kind": "procedure",
286
+ "name": "usp_GetCustomerList",
287
+ "schema": "dbo",
288
+ "parameters": {
289
+ "BranchId": 1,
290
+ "SearchTerm": "Acme"
294
291
  }
295
292
  }
296
293
  ```
297
294
 
298
- ---
299
-
300
- ## 4. Routing & ERP Navigation Integration
301
-
302
- ### Dynamic Route Generation
303
-
304
- Mount all report runtime and designer routes with a single call in your `app.routes.ts`:
305
-
306
- ```typescript
307
- // src/app/app.routes.ts
308
- import { Routes } from '@angular/router';
309
- import { createReportRoutes } from 'bways-report';
310
-
311
- export const routes: Routes = [
312
- {
313
- path: 'reports',
314
- children: createReportRoutes({
315
- // Optional: enforce auth or role guards
316
- runtimeGuards: [],
317
- designerGuards: [], // e.g. [AdminGuard]
318
- enableDesignerRoutes: true, // creates 'new' and ':reportId/edit' routes
319
- }),
295
+ **Option B (Enterprise DTO contract):**
296
+ ```json
297
+ {
298
+ "dataSource": {
299
+ "id": "usp_GetCustomerList",
300
+ "type": "stored_procedure",
301
+ "name": "usp_GetCustomerList",
302
+ "schema": "dbo"
320
303
  },
321
- ];
304
+ "parameters": {
305
+ "BranchId": 1
306
+ },
307
+ "sessionContext": {
308
+ "companyId": 101,
309
+ "branchId": 1
310
+ }
311
+ }
322
312
  ```
323
313
 
324
- This instantly creates:
325
- - `/reports/:reportId` — Renders `RoutedReportRuntimeComponent` (resolves report via `reportResolver`, presents interactive filters, KPI metrics, chart, and result grid).
326
- - `/reports/:reportId/edit` — Renders `RoutedReportDesignerComponent` (visual drag-and-drop builder loaded with current definition).
327
- - `/reports/new` — Renders `RoutedReportDesignerComponent` initialized with a blank template.
328
-
329
- ### Categorized ERP Sidebar / Header Navigation
330
-
331
- Use `ReportMenuService` to generate hierarchical sidebar menus grouped by category (e.g. Finance, Sales, Inventory):
332
-
333
- ```typescript
334
- // src/app/components/sidebar/erp-sidebar.component.ts
335
- import { Component, inject } from '@angular/core';
336
- import { CommonModule } from '@angular/common';
337
- import { RouterModule } from '@angular/router';
338
- import { ReportMenuService } from 'bways-report';
339
-
340
- @Component({
341
- selector: 'erp-sidebar',
342
- standalone: true,
343
- imports: [CommonModule, RouterModule],
344
- template: `
345
- <aside class="sidebar">
346
- <input
347
- type="search"
348
- placeholder="Search reports..."
349
- (input)="onSearch($event)"
350
- />
351
-
352
- @for (group of menuService.menuGroups(); track group.category) {
353
- <div class="menu-group">
354
- <h4>{{ group.displayName }}</h4>
355
- <ul>
356
- @for (item of group.items; track item.id) {
357
- <li>
358
- <a [routerLink]="item.route" routerLinkActive="active">
359
- {{ item.name }}
360
- @if (item.isDraft) {
361
- <span class="badge">Draft</span>
362
- }
363
- </a>
364
- </li>
365
- }
366
- </ul>
367
- </div>
368
- }
369
- </aside>
370
- `,
371
- })
372
- export class ErpSidebarComponent {
373
- readonly menuService = inject(ReportMenuService);
374
-
375
- onSearch(event: Event): void {
376
- const query = (event.target as HTMLInputElement).value;
377
- this.menuService.setSearchQuery(query);
378
- }
314
+ ### Dropdown Lookup Request Format (`lookupEndpoint`)
315
+ Dropdowns with database data sources query `/api/reporting/lookup` (or fallback to `executeEndpoint`):
316
+ ```json
317
+ {
318
+ "entityName": "Sel_UserWiseCompUnit",
319
+ "sourceType": "stored_procedure",
320
+ "schema": "dbo",
321
+ "valueField": "COMPUNIT_ID",
322
+ "displayField": "COMPUNIT_NAME",
323
+ "parameters": {}
379
324
  }
380
325
  ```
381
326
 
382
327
  ---
383
328
 
384
- ## 5. Embedding Components Directly
329
+ ## 4. Dynamic Session Context & Auto-Parameter Binding
385
330
 
386
- If you prefer embedding components inside existing pages instead of routing:
331
+ When `autoParameter: true` is configured, parameters matching active ERP session keys are automatically populated and hidden from non-technical users:
387
332
 
388
- ### Report Runtime (Interactive Report Page)
333
+ | Stored Procedure Parameter | Matching Session Keys |
334
+ | :--- | :--- |
335
+ | `@BranchId`, `@branch_id`, `@bid`, `@branchcode`, `@locationid` | `branchId`, `branch`, `locationId` |
336
+ | `@CompanyId`, `@company_id`, `@cid`, `@companycode`, `@tenantid` | `companyId`, `company`, `tenantId` |
337
+ | `@UserId`, `@user_id`, `@uid`, `@usercode`, `@operatorid` | `userId`, `user`, `loginUser` |
338
+ | `@FinancialYearId`, `@fyear`, `@fiscalyear`, `@yearid` | `financialYearId`, `fYear` |
389
339
 
340
+ Session values can be updated at runtime:
390
341
  ```typescript
391
- import { Component } from '@angular/core';
392
- import { ReportRuntimeComponent, ReportDefinition } from 'bways-report';
342
+ import { inject } from '@angular/core';
343
+ import { ReportSessionContextService } from 'bways-report';
393
344
 
394
- @Component({
395
- selector: 'my-report-page',
396
- standalone: true,
397
- imports: [ReportRuntimeComponent],
398
- template: `
399
- <!-- Option A: Load by ID via persistence adapter -->
400
- <rpt-runtime [reportId]="'sales-register-2024'" />
401
-
402
- <!-- Option B: Pass ReportDefinition directly -->
403
- <!-- <rpt-runtime [report]="customDefinition" /> -->
404
- `,
405
- })
406
- export class MyReportPageComponent {}
407
- ```
408
-
409
- ### Visual Drag-and-Drop Designer
410
-
411
- ```typescript
412
- import { Component } from '@angular/core';
413
- import { DesignerComponent, ReportDefinition } from 'bways-report';
345
+ export class SessionWidget {
346
+ private readonly session = inject(ReportSessionContextService);
414
347
 
415
- @Component({
416
- selector: 'my-designer-page',
417
- standalone: true,
418
- imports: [DesignerComponent],
419
- template: `
420
- <rpt-designer
421
- [initialReport]="reportDefinition"
422
- (save)="onSaveReport($event)"
423
- />
424
- `,
425
- })
426
- export class MyDesignerPageComponent {
427
- reportDefinition: ReportDefinition = /* ... */;
428
-
429
- onSaveReport(updatedReport: ReportDefinition): void {
430
- console.log('Saved report schema:', updatedReport);
348
+ onBranchSwitch(branchId: number): void {
349
+ this.session.setSessionParameter('branchId', branchId);
431
350
  }
432
351
  }
433
352
  ```
434
353
 
435
354
  ---
436
355
 
437
- ## 6. Grid & Chart Bridge Integration (BWays-Grid)
356
+ ## 5. Plugging in BWays-Grid (`UltraGridComponent`)
438
357
 
439
- ### Using BWays-Grid or Custom Grid
358
+ `BWays-Report` provides first-class support for `bways-grid` (`v0.1.18+` / `v0.1.19+`). Pass `grid: UltraGridComponent` to `provideBwaysReport()`:
440
359
 
441
- Provide your grid component via the `GRID_COMPONENT` token in `provideBwaysReport()`:
442
-
443
- ```typescript
444
- provideBwaysReport({
445
- gridComponent: BWaysGridComponent, // or AgGridWrapperComponent
446
- })
447
- ```
360
+ - **Runtime `@Input()` Safety**: Dynamic grid bridging inspects component metadata (`ɵcmp.inputs`) before calling `ComponentRef.setInput()`, preventing Angular `NG0303` runtime template binding errors.
361
+ - **Row Selection Alignment**: Row selection mode (`single` vs `multiple`) is passed cleanly through `config.rowSelection` and `config.selectionMode`, preserving full compatibility with `UltraGridComponent`.
362
+ - **Circular Echo Suppression**: Grid state changes originating from user interaction are tracked to avoid re-triggering parent input cycles. Column menus, search inputs, and drag-handles stay open and focused without flicker.
363
+ - **Filter State Preservation**: Preserves both `activeFilters` (checkboxes) and `conditionFilters` (expressions) across runtime updates and JSON serialization.
364
+ - **Selective Layout Auto-Persistence**: Structural layout changes (column widths, pinning, grouping) persist immediately, while interactive data filtering is debounced to avoid undo stack pollution.
448
365
 
449
- `ReportGridBridgeComponent` dynamically passes the data rows, columns configuration, sorting, and aggregate settings directly to your grid component. If no grid is provided, `bways-report` renders its high-performance built-in tabular grid with pagination and column sorting.
366
+ ---
450
367
 
451
- ### Using Chart Components
368
+ ## 6. Advanced Custom Adapters
452
369
 
453
- Provide a chart component wrapper (Chart.js, ApexCharts, Highcharts) via `chartComponent`:
370
+ For applications with custom HTTP pipelines, gRPC, or microservice gateways, extend the library's abstract contracts:
454
371
 
455
372
  ```typescript
456
373
  provideBwaysReport({
457
- chartComponent: MyHostChartComponent,
458
- })
459
- ```
460
-
461
- If not provided, the built-in SVG visual chart renderer outputs crisp, responsive Bar charts, Donut charts, and Line/Area charts with zero external dependencies.
462
-
463
- ---
464
-
465
- ## 8. Grid Bridge & Circular Echo Suppression
466
-
467
- `bways-report` features an intelligent runtime bridge (`ReportGridBridgeComponent` and `RptGridOutletDirective`) that connects any underlying grid library (e.g., `UltraGridComponent` from `bways-grid`) to the dynamic report state:
468
-
469
- ```
470
- ┌─────────────────────────────────────────────────────────────┐
471
- │ Design Canvas / Runtime │
472
- │ │
473
- │ [gridDefinition] (ReportGridDefinition) │
474
- │ │ │
475
- │ ▼ │
476
- │ ┌─────────────────────────────────────────────────────┐ │
477
- │ │ ReportGridBridgeComponent │ │
478
- │ │ │ │
479
- │ │ - gridInputs: transforms definition into inputs │ │
480
- │ │ - gridReportState: preserves active & condition │ │
481
- │ │ filters from serialized report state │ │
482
- │ │ │ │
483
- │ │ ┌─────────────────────────────────────────────┐ │ │
484
- │ │ │ RptGridOutletDirective │ │ │
485
- │ │ │ │ │ │
486
- │ │ │ - Circular Echo Suppression: │ │ │
487
- │ │ │ Tracks last emitted state & col-defs │ │ │
488
- │ │ │ Skips setInput when update came from │ │ │
489
- │ │ │ the grid itself. │ │ │
490
- │ │ └─────────────────────┬───────────────────────┘ │ │
491
- │ └─────────────────────────┼───────────────────────────┘ │
492
- │ │ │
493
- │ ▼ │
494
- │ ┌───────────────────────┐ │
495
- │ │ UltraGridComponent │ │
496
- │ │ (Live ERP Grid) │ │
497
- │ └───────────────────────┘ │
498
- └─────────────────────────────────────────────────────────────┘
374
+ gridComponent: UltraGridComponent,
375
+ dataSourceAdapter: MyCustomDataSourceAdapter,
376
+ persistenceAdapter: MyCustomPersistenceAdapter,
377
+ schemaDiscoveryAdapter: MyCustomSchemaDiscoveryAdapter,
378
+ lookupAdapter: MyCustomLookupAdapter,
379
+ });
499
380
  ```
500
381
 
501
- ### Key Capabilities:
502
- - **Interactive Filtering without Popover Dismissal**: In traditional bindings, when a user types in a filter or checks a box, parent state updates re-trigger `setInput`, causing the grid to re-initialize headers and snap popovers shut. `RptGridOutletDirective` compares incoming states (`isReportStateMatching`) against the grid's own latest emission, preventing unnecessary re-renders.
503
- - **Layout Auto-Persist vs. Runtime Filtering**:
504
- - **Structural Layout** changes (`groupModel`, `sortModel`, column widths, visibility) trigger immediate persistence and display the `"Layout auto-persisted"` status banner.
505
- - **Column Data Filtering** (`activeFilters`, `conditionFilters`) is treated as runtime data exploration: debounced (1200ms) with `{ skipHistory: true }`, ensuring undo/redo stacks aren't flooded with intermediate keystrokes.
506
- - **Full Filter State Preservation**: Filter sets and expressions are preserved intact in `options.reportState` when saved or exported.
382
+ Abstract base classes:
383
+ - `ReportDataSourceAdapter`
384
+ - `ReportPersistenceAdapter`
385
+ - `ReportSchemaDiscoveryAdapter`
386
+ - `ReportLookupAdapter`
507
387
 
508
388
  ---
509
389
 
510
- ## 9. Stored Procedure Discovery & Smart Parameter Mapping
390
+ ## 7. Theming & CSS Custom Properties
511
391
 
512
- `bways-report` integrates with SQL Server stored procedures via `HttpReportSchemaDiscoveryAdapter`:
513
-
514
- 1. **Introspection (`sys.parameters`)**: Queries stored procedure signatures, determining data types, nullability, and default expressions.
515
- 2. **Smart Control Inference**:
516
- - Date parameters (`@FromDate`, `@ToDate`, `@AsOnDate`) automatically suggest date-picker or date-range controls.
517
- - Master entity parameters (`@SubGLCode`, `@BranchId`, `@CustomerId`) infer dropdown lookups from associated tables or views.
518
- 3. **Lookup Deduplication & Account Resolution**:
519
- - `identifier-humanizer.ts` prioritizes unique account numbers (`_acno`, `glacno`, `account_no`) over category codes (`_code`), preventing duplicate collapsing of customer accounts in dropdown lookups.
520
- 4. **Session Token Binding**:
521
- - Parameters matching ERP session context (`@BranchId`, `@CompanyId`, `@FinYearId`) are automatically resolved via `SessionContextProvider` without manual user intervention.
522
-
523
- ---
524
-
525
- ## 10. Theming & CSS Custom Properties
526
-
527
- `bways-report` uses CSS custom properties (`--rpt-*`) throughout all components, ensuring seamless alignment with your ERP application's design system:
392
+ `bways-report` uses Vanilla CSS custom properties. Customize the tokens in your application's `styles.css`:
528
393
 
529
394
  ```css
530
- /* In your host application's styles.scss or theme file */
531
395
  :root {
532
- /* Brand Colors */
533
- --rpt-primary: #2563eb;
534
- --rpt-primary-hover: #1d4ed8;
535
- --rpt-primary-focus: rgba(37, 99, 235, 0.25);
536
-
537
- /* Surface & Text */
538
- --rpt-surface-bg: #ffffff;
539
- --rpt-bg-subtle: #f8fafc;
540
- --rpt-text-color: #0f172a;
541
- --rpt-text-muted: #64748b;
542
- --rpt-border-color: #e2e8f0;
543
-
544
- /* Geometry & Typography */
545
- --rpt-radius-md: 6px;
546
- --rpt-radius-lg: 12px;
396
+ --rpt-color-primary: #2563eb;
397
+ --rpt-color-primary-hover: #1d4ed8;
398
+ --rpt-color-bg: #ffffff;
399
+ --rpt-color-surface: #f8fafc;
400
+ --rpt-color-text: #0f172a;
401
+ --rpt-color-text-muted: #64748b;
402
+ --rpt-color-border: #cbd5e1;
547
403
  --rpt-font-family: 'Inter', system-ui, sans-serif;
548
- --rpt-font-size-base: 0.875rem;
404
+ --rpt-border-radius: 6px;
405
+ --rpt-border-radius-lg: 8px;
406
+ }
549
407
 
550
- /* Status Colors */
551
- --rpt-success-color: #10b981;
552
- --rpt-warning-color: #f59e0b;
553
- --rpt-error-color: #ef4444;
408
+ [data-theme='dark'] {
409
+ --rpt-color-bg: #0f172a;
410
+ --rpt-color-surface: #1e293b;
411
+ --rpt-color-text: #f8fafc;
412
+ --rpt-color-text-muted: #94a3b8;
413
+ --rpt-color-border: #334155;
554
414
  }
555
415
  ```
556
416
 
557
417
  ---
558
418
 
559
- ## 11. Exporting Data (CSV & JSON)
419
+ ## 8. Exporting Data (CSV & JSON)
560
420
 
561
- Use `ReportExportService` for one-click file generation:
421
+ Inject `ReportExportService` in any host component:
562
422
 
563
423
  ```typescript
564
424
  import { Component, inject } from '@angular/core';
565
425
  import { ReportExportService } from 'bways-report';
566
426
 
567
- @Component({
568
- selector: 'export-actions',
569
- standalone: true,
570
- template: `
571
- <button (click)="downloadCsv()">Download CSV</button>
572
- <button (click)="downloadJson()">Download Metadata</button>
573
- `,
574
- })
575
- export class ExportActionsComponent {
427
+ @Component({ ... })
428
+ export class ExportComponent {
576
429
  private readonly exportService = inject(ReportExportService);
577
430
 
578
- downloadCsv(): void {
579
- const data = [
580
- { invoiceNo: 'INV-001', customer: 'Acme Corp', total: 4950 },
581
- { invoiceNo: 'INV-002', customer: 'Globex Inc', total: 14080 },
582
- ];
583
-
431
+ onExportCsv(data: unknown[]): void {
584
432
  this.exportService.exportCsv(data, {
585
- fileName: 'invoices-export.csv',
433
+ fileName: 'sales-register.csv',
586
434
  columns: [
587
435
  { field: 'invoiceNo', header: 'Invoice #' },
588
- { field: 'customer', header: 'Customer' },
589
- {
590
- field: 'total',
591
- header: 'Total ($)',
592
- formatter: (val: number) => `$${val.toLocaleString()}`
593
- },
436
+ { field: 'amount', header: 'Amount' },
594
437
  ],
595
- addBom: true, // Includes UTF-8 BOM so Microsoft Excel renders international characters properly
596
- });
597
- }
598
-
599
- downloadJson(): void {
600
- this.exportService.exportJson(myReportDefinition, {
601
- fileName: 'report-schema.json',
602
- pretty: true,
438
+ addBom: true, // UTF-8 Excel compatibility
603
439
  });
604
440
  }
605
441
  }
@@ -607,13 +443,6 @@ export class ExportActionsComponent {
607
443
 
608
444
  ---
609
445
 
610
- ## 12. Changelog & Version History
611
-
612
- For a complete record of releases, breaking changes, and bug fixes, refer to the **[Changelog](CHANGELOG.md)**.
613
-
614
- ---
615
-
616
446
  ## License
617
447
 
618
- MIT © BWays Technologies
619
-
448
+ Proprietary License. Copyright (c) 2026 CCPL / BWays Team. All rights reserved.