nuxeo-development-framework 5.6.0 → 5.6.2

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 (24) hide show
  1. package/bundles/nuxeo-development-framework.umd.js +62 -23
  2. package/bundles/nuxeo-development-framework.umd.js.map +1 -1
  3. package/esm2015/lib/components/documents/services/documents.service.js +16 -16
  4. package/esm2015/lib/components/dynamic-form/components/dynamic-form-select-users/dynamic-form-select-users.component.js +20 -6
  5. package/esm2015/lib/components/reports/ndf-reports/base/base-custom-report.js +10 -1
  6. package/esm2015/lib/components/reports/ndf-reports/charts-components/graph-chart/graph-chart.component.js +4 -1
  7. package/esm2015/lib/components/reports/ndf-reports/models/details.js +1 -1
  8. package/esm2015/lib/components/reports/ndf-reports/services/chart-data-transformers.service.js +11 -3
  9. package/esm2015/lib/components/reports/ndf-reports/services/chart-plugins-registry.service.js +6 -2
  10. package/esm2015/lib/components/tables/ndf-table/models/table-column.js +1 -1
  11. package/esm2015/lib/components/tables/ndf-table/models/table-config.js +1 -1
  12. package/esm2015/lib/components/tables/ndf-table/models/types.js +1 -1
  13. package/fesm2015/nuxeo-development-framework.js +61 -23
  14. package/fesm2015/nuxeo-development-framework.js.map +1 -1
  15. package/lib/components/dynamic-form/components/dynamic-form-select-users/dynamic-form-select-users.component.d.ts +1 -0
  16. package/lib/components/reports/ndf-reports/base/base-custom-report.d.ts +1 -0
  17. package/lib/components/reports/ndf-reports/models/details.d.ts +1 -1
  18. package/lib/components/reports/ndf-reports/services/chart-plugins-registry.service.d.ts +1 -1
  19. package/lib/components/tables/ndf-table/models/table-column.d.ts +0 -4
  20. package/lib/components/tables/ndf-table/models/table-config.d.ts +1 -13
  21. package/lib/components/tables/ndf-table/models/types.d.ts +0 -11
  22. package/package.json +2 -2
  23. package/src/docs/ndf-reports.doc.md +1213 -0
  24. package/src/docs/ndf-table.doc.md +1 -1
@@ -0,0 +1,1213 @@
1
+
2
+ # NDF Reports Component (`app-ndf-reports`) - Documentation
3
+
4
+
5
+ ## Overview
6
+
7
+ The `app-ndf-reports` is a highly configurable and extensible Angular component for rendering dynamic reports with Chart.js integration. It supports multiple chart types, advanced filtering, data transformation, and responsive layouts.
8
+
9
+ ### Key Features
10
+
11
+ - Server-side configuration loading via report keys
12
+ - Direct configuration injection for programmatic usage
13
+ - Built-in JSON configuration editor with navigation
14
+ - Dynamic report rendering with multiple chart types
15
+ - Query change event emission for external integration
16
+ - Navigation integration for seamless user experience
17
+
18
+ ### Input Properties
19
+
20
+ ```typescript
21
+ @Component({
22
+ selector: 'app-ndf-reports'
23
+ })
24
+ export class NdfReportsComponent {
25
+ @Input() jsonEditorEnabled: boolean = false;
26
+ @Input() reportsKey: string;
27
+ @Input() navigateRoute: string[] = [];
28
+ @Input() config: NdfReportsConfig;
29
+
30
+ @Output() onQueryChange = new EventEmitter();
31
+ }
32
+ ```
33
+
34
+ #### Property Specifications
35
+
36
+ | Property | Type | Required | Default | Description |
37
+ | ------------------ | ------------------- | -------- | ------- | ---------------------------------------------------- |
38
+ | jsonEditorEnabled | `boolean` | ❌ | `false` | Enable navigation to configuration editor interface |
39
+ | reportsKey | `string` | ⚠️ | - | Server-side configuration identifier |
40
+ | navigateRoute | `string[]` | ❌ | `[]` | Angular route array for navigation purposes |
41
+ | config | `NdfReportsConfig` | ⚠️ | - | Direct configuration object for report definitions |
42
+
43
+ > **⚠️ Configuration Requirement**: Either `reportsKey` OR `config` must be provided. These inputs are mutually exclusive.
44
+
45
+ #### Output Events
46
+
47
+ | Event | Type | Description |
48
+ | -------------- | ----------------------- | -------------------------------------------------- |
49
+ | onQueryChange | `EventEmitter<any>` | Emitted when report query parameters are modified |
50
+
51
+ ## Configuration Loading Strategy
52
+
53
+ The component supports two distinct configuration loading approaches:
54
+
55
+ ### Server-Side Configuration Loading
56
+
57
+ Use `reportsKey` to fetch configuration from server-side storage:
58
+
59
+ ```html
60
+ <!-- Template usage -->
61
+ <app-ndf-reports
62
+ [reportsKey]="'ARCHIVE_REPORTS_CONFIG'"
63
+ [jsonEditorEnabled]="true"
64
+ [navigateRoute]="['/reports', 'editor']"
65
+ (onQueryChange)="handleQueryChange($event)">
66
+ </app-ndf-reports>
67
+ ```
68
+
69
+ ```typescript
70
+ // Component usage
71
+ export class DashboardComponent {
72
+ handleQueryChange(queryData: any): void {
73
+ console.log('Report query changed:', queryData);
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### Direct Configuration Injection
79
+
80
+ Use `config` for programmatic configuration management:
81
+
82
+ ```html
83
+ <!-- Template usage -->
84
+ <app-ndf-reports
85
+ [config]="reportsConfiguration"
86
+ [jsonEditorEnabled]="false"
87
+ (onQueryChange)="handleQueryChange($event)">
88
+ </app-ndf-reports>
89
+ ```
90
+
91
+ ## Quick Start Guide
92
+
93
+ ### Basic Setup
94
+
95
+ ```typescript
96
+ const basicConfig: NdfReportsConfig = {
97
+ request: {
98
+ pageProvider: 'PP_SALES_DATA'
99
+ },
100
+ reports: {
101
+ items: [
102
+ {
103
+ id: 'sales-total',
104
+ label: 'Total Sales',
105
+ mode: 'digit',
106
+ datasource: {
107
+ propertyPath: 'totalSales'
108
+ }
109
+ }
110
+ ]
111
+ }
112
+ };
113
+ ```
114
+
115
+ ### With Filters
116
+
117
+ ```typescript
118
+ const configWithFilters: NdfReportsConfig = {
119
+ request: {
120
+ pageProvider: 'PP_SALES_DATA'
121
+ },
122
+ filters: {
123
+ mode: 'payload',
124
+ visible: true,
125
+ fields: [
126
+ {
127
+ type: 'predicate',
128
+ config: {
129
+ label: 'FILTERS.requestNumber',
130
+ fieldKey: 'requestcase:requestNumber',
131
+ sendMode: 'payload',
132
+ valueType: 'valueObject',
133
+ render: {
134
+ type: 'input',
135
+ options: {
136
+ debounceTime: 300,
137
+ },
138
+ },
139
+ },
140
+ },
141
+ {
142
+ type: 'aggregation',
143
+ config: {
144
+ label: 'LISTING.Last_Contributors',
145
+ aggregation: 'dublincore_lastContributor_agg',
146
+ fieldKey: 'dc:lastContributor',
147
+ order: 0,
148
+ sendMode: 'queryParam',
149
+ valueType: 'property',
150
+ condition: `show = values && values['ecm:currentLifeCycleState']?.includes('ended');`,
151
+ render: {
152
+ type: 'checkbox',
153
+ options: {
154
+ showTotal: true
155
+ }
156
+ }
157
+ }
158
+ }
159
+ ]
160
+ },
161
+ reports: {
162
+ items: [/* report definitions */]
163
+ }
164
+ };
165
+ ```
166
+
167
+ ## Core Configuration
168
+
169
+ ### `NdfReportsConfig` Interface
170
+
171
+ The main configuration interface that defines all aspects of the reports component.
172
+
173
+ ```typescript
174
+ export type NdfReportsConfig = {
175
+ request: NdfReportsRequest;
176
+ filters?: NdfReportsFilters;
177
+ options?: {
178
+ print?: boolean;
179
+ };
180
+ activeQuery?: Record<string, any>;
181
+ reports: ReportsDefinition;
182
+ };
183
+ ```
184
+
185
+ ### Properties
186
+
187
+ | Property | Type | Required | Description |
188
+ | ----------- | --------------------- | -------- | ------------------------------------------ |
189
+ | request | `NdfReportsRequest` | ✅ | Core request parameters for data fetching |
190
+ | filters | `NdfReportsFilters` | ❌ | Optional filtering configuration |
191
+ | options | `object` | ❌ | Additional component options |
192
+ | activeQuery | `Record<string, any>` | ❌ | Initial query parameters for first request |
193
+ | reports | `ReportsDefinition` | ✅ | Container for all report definitions |
194
+
195
+ #### Options Object
196
+
197
+ |Property|Type|Required|Description|
198
+ |---|---|---|---|
199
+ |print|`boolean`|❌|Enable print functionality for all reports|
200
+
201
+ ## Request Configuration
202
+
203
+ Defines how data is fetched from backend services or APIs.
204
+
205
+ ### `NdfReportsRequest` Type
206
+
207
+ ```typescript
208
+ type NdfReportsRequest = {
209
+ pageProvider: string;
210
+ customUrl?: { url: string; method: 'post' | 'get' };
211
+ payload?: Record<string, any>;
212
+ params?: Record<string, any>;
213
+ headers?: Record<string, any>;
214
+ transformer?: string;
215
+ };
216
+ ```
217
+
218
+ ### Properties
219
+
220
+ | Property | Type | Required | Description |
221
+ | ------------ | ------------------------------------------ | -------- | ----------------------------------------------------------- |
222
+ | pageProvider | `string` | ✅ | Identifier for the data source provider |
223
+ | customUrl | `{ url: string; method: 'post' \| 'get' }` | ❌ | Custom endpoint configuration |
224
+ | payload | `Record<string, any>` | ❌ | Request body for POST requests |
225
+ | params | `Record<string, any>` | ❌ | Query parameters |
226
+ | headers | `Record<string, any>` | ❌ | HTTP headers |
227
+ | transformer | `string` | ❌ | Name of registered transformer in `ReportsDataTransformers` |
228
+
229
+ ### Example Usage
230
+
231
+ ```json
232
+ {
233
+ "request": {
234
+ "pageProvider": "PP_RPT_Location",
235
+ "customUrl": {
236
+ "url": "/custom-search/admin/pp/PP_RPT_Location/execute",
237
+ "method": "post"
238
+ },
239
+ "params": {
240
+ "pageSize": 100
241
+ },
242
+ "headers": {
243
+ "properties": "*"
244
+ },
245
+ "transformer": "locationDataTransform"
246
+ }
247
+ }
248
+ ```
249
+
250
+ ## Filters Configuration
251
+
252
+ Optional filtering system that allows users to refine report data.
253
+
254
+ ### `NdfReportsFilters` Type
255
+
256
+ ```typescript
257
+ type NdfReportsFilters = {
258
+ mode: 'payload' | 'params';
259
+ payload?: Record<string, any>;
260
+ params?: Record<string, any>;
261
+ fields: FieldConfigModel[];
262
+ visible?: boolean;
263
+ togglePanel?: boolean;
264
+ reloadStrategy?: 'always' | 'never';
265
+ };
266
+ ```
267
+
268
+ ### Properties
269
+
270
+ | Property | Type | Required | Description |
271
+ | -------------- | ----------------------- | -------- | ---------------------------------------------- |
272
+ | mode | `'payload' \| 'params'` | ✅ | Where to apply filter values |
273
+ | payload | `Record<string, any>` | ❌ | Default payload values |
274
+ | params | `Record<string, any>` | ❌ | Default query parameters |
275
+ | fields | `FieldConfigModel[]` | ✅ | Filter field configurations |
276
+ | visible | `boolean` | ❌ | Initial visibility of filter UI |
277
+ | togglePanel | `boolean` | ❌ | Allow users to show/hide filter panel |
278
+ | reloadStrategy | `'always' \| 'never'` | ❌ | When to reload field data after filter changes |
279
+
280
+ ### Reload Strategy
281
+
282
+ |Strategy|Description|
283
+ |---|---|
284
+ |`always`|Reload field data every time filters are applied|
285
+ |`never`|Only reload on programmatic configuration changes|
286
+
287
+ ### Example Usage
288
+
289
+ ```json
290
+ {
291
+ "filters": {
292
+ "mode": "payload",
293
+ "visible": true,
294
+ "togglePanel": true,
295
+ "reloadStrategy": "never",
296
+ "fields": [
297
+ {
298
+ "type": "predicate",
299
+ "config": {
300
+ "label": "FILTERS.title",
301
+ "fieldKey": "dc:title",
302
+ "sendMode": "payload",
303
+ "valueType": "valueObject",
304
+ "render": {
305
+ "type": "input",
306
+ "options": {
307
+ "debounceTime": 300
308
+ }
309
+ }
310
+ }
311
+ }
312
+ ]
313
+ }
314
+ }
315
+ ```
316
+
317
+ ## Report Definitions
318
+
319
+ ### `ReportsDefinition` Type
320
+
321
+ Container for all report configurations.
322
+
323
+ ```typescript
324
+ type ReportsDefinition = {
325
+ items: ReportDefinitionModel[];
326
+ };
327
+ ```
328
+
329
+ ### `ReportDefinitionModel` Union Type
330
+
331
+ ```typescript
332
+ export type ReportDefinitionModel =
333
+ | DigitChartDefinition
334
+ | GraphChartDefinition
335
+ | DynamicLineChartDefinition
336
+ | CustomChartDefinition;
337
+ ```
338
+
339
+ ## Chart Types
340
+
341
+ ### Base Configuration
342
+
343
+ All chart types extend `BaseReportConfig`:
344
+
345
+ ```typescript
346
+ export interface BaseReportConfig {
347
+ id: string | number;
348
+ label: string;
349
+ mode: ReportMode;
350
+ navigate?: {
351
+ enabled?: boolean;
352
+ route: any[];
353
+ includeParams?: boolean;
354
+ };
355
+ details?: ReportDetailsConfig;
356
+ layout?: {
357
+ width?: GridWidth;
358
+ columnPosition?: GridWidth;
359
+ height?: number | 'auto';
360
+ rowPosition?: number | 'auto';
361
+ styleClass?: string;
362
+ };
363
+ }
364
+ ```
365
+
366
+ #### Base Properties
367
+
368
+ |Property|Type|Required|Description|
369
+ |---|---|---|---|
370
+ |id|`string \| number`|✅|Unique identifier|
371
+ |label|`string`|✅|Display name (supports i18n keys)|
372
+ |mode|`ReportMode`|✅|Chart type identifier|
373
+ |navigate|`object`|❌|Click navigation configuration|
374
+ |└─ enabled|`boolean`|❌|Enable click-to-navigate|
375
+ |└─ route|`any[]`|✅|Angular route array|
376
+ |└─ includeParams|`boolean`|❌|Include current filters in navigation|
377
+ |details|`ReportDetailsConfig`|❌|Detailed view configuration|
378
+ |layout|`object`|❌|Grid layout configuration|
379
+ |└─ width|`GridWidth`|❌|Column span (1-12 or 'auto')|
380
+ |└─ columnPosition|`GridWidth`|❌|Starting column|
381
+ |└─ height|`number \| 'auto'`|❌|Row span or auto-size|
382
+ |└─ rowPosition|`number \| 'auto'`|❌|Starting row|
383
+ |└─ styleClass|`string`|❌|Custom CSS classes|
384
+
385
+ ### Digit Charts
386
+
387
+ For displaying key performance indicators (KPIs) as large numbers.
388
+
389
+ #### `DigitChartDefinition` Type
390
+
391
+ ```typescript
392
+ type DigitChartDefinition = BaseReportConfig & {
393
+ mode: 'digit';
394
+ datasource: {
395
+ propertyPath: string;
396
+ transformer?: string;
397
+ bindValue?: string;
398
+ };
399
+ };
400
+ ```
401
+
402
+ #### Properties
403
+
404
+ |Property|Type|Required|Description|
405
+ |---|---|---|---|
406
+ |mode|`'digit'`|✅|Chart type identifier|
407
+ |datasource|`object`|✅|Data source configuration|
408
+ |└─ propertyPath|`string`|✅|Path to data property in response|
409
+ |└─ transformer|`string`|❌|Transformer name (registered in `ChartDataTransformers`)|
410
+ |└─ bindValue|`string`|❌|Property to extract from data object/array|
411
+
412
+ #### Example
413
+
414
+ ```json
415
+ {
416
+ "id": "resultsCount",
417
+ "label": "REPORTS.resultsCount",
418
+ "mode": "digit",
419
+ "datasource": {
420
+ "propertyPath": "resultsCount"
421
+ },
422
+ "layout": {
423
+ "width": 2,
424
+ "height": 1
425
+ }
426
+ }
427
+ ```
428
+
429
+ ### Graph Charts
430
+
431
+ For Chart.js-powered visualizations with full customization support.
432
+
433
+ #### `GraphChartDefinition` Type
434
+
435
+ ```typescript
436
+ type GraphChartDefinition<TType extends ChartType = ChartType> = BaseReportConfig & {
437
+ mode: 'graph';
438
+ datasource: ReportDataSource[];
439
+ chart: GraphChartOptionsDefinition<TType>;
440
+ prefix?: string;
441
+ print?: boolean;
442
+ typeConfig?: ChartTypeConfig;
443
+ dialog?: GraphDialogConfig;
444
+ };
445
+ ```
446
+
447
+ #### Properties
448
+
449
+ |Property|Type|Required|Description|
450
+ |---|---|---|---|
451
+ |mode|`'graph'`|✅|Chart type identifier|
452
+ |datasource|`ReportDataSource[]`|✅|Data source configurations|
453
+ |chart|`GraphChartOptionsDefinition<TType>`|✅|Chart.js configuration|
454
+ |prefix|`string`|❌|Translation key prefix|
455
+ |print|`boolean`|❌|Enable print support for this chart|
456
+ |typeConfig|`ChartTypeConfig`|❌|Chart type switching configuration|
457
+ |dialog|`GraphDialogConfig`|❌|Modal dialog configuration|
458
+
459
+ #### Chart Configuration
460
+
461
+ ```typescript
462
+ type GraphChartOptionsDefinition<TType extends ChartType = ChartType> = {
463
+ type: TType;
464
+ options?: CustomChartOptions<TType>;
465
+ datasets?: Omit<ChartDataset<TType>, 'data'>[];
466
+ overrides?: ChartOptionsByType;
467
+ plugins?: string[];
468
+ colors?: string[];
469
+ direction?: 'horizontal' | 'vertical';
470
+ };
471
+ ```
472
+
473
+ |Property|Type|Required|Description|
474
+ |---|---|---|---|
475
+ |type|`TType`|✅|Chart.js chart type|
476
+ |options|`CustomChartOptions<TType>`|❌|Chart.js options with extensions|
477
+ |datasets|`Omit<ChartDataset<TType>, 'data'>[]`|❌|Dataset configurations|
478
+ |overrides|`ChartOptionsByType`|❌|Type-specific overrides|
479
+ |plugins|`string[]`|❌|Plugin names (must be pre-registered)|
480
+ |colors|`string[]`|❌|Color palette (CSS colors/variables)|
481
+ |direction|`'horizontal' \| 'vertical'`|❌|Chart orientation (bar charts only)|
482
+
483
+ #### Data Source Configuration
484
+
485
+ ```typescript
486
+ type ReportDataSource = {
487
+ propertyPath: string;
488
+ bindLabel?: string;
489
+ bindValue?: string;
490
+ dataFormat?: string;
491
+ transformer?: string;
492
+ };
493
+ ```
494
+
495
+ |Property|Type|Required|Description|
496
+ |---|---|---|---|
497
+ |propertyPath|`string`|✅|Path to data in response|
498
+ |bindLabel|`string`|❌|Property for chart labels|
499
+ |bindValue|`string`|❌|Property for chart values|
500
+ |dataFormat|`string`|❌|Format string for data transformation|
501
+ |transformer|`string`|❌|Transformer name (registered in `ChartDataTransformers`)|
502
+
503
+ #### Example
504
+ ```json
505
+ {
506
+ "id": "future__generaldocument_secrecyLevel_agg",
507
+ "label": "REPORTS.gdocSecrecyLevel",
508
+ "mode": "graph",
509
+ "print": true,
510
+ "dialog": {
511
+ "active": true
512
+ },
513
+ "typeConfig": {
514
+ "enabled": true,
515
+ "allowedTypes": ["line", "bar", "pie"]
516
+ },
517
+ "prefix": "search.buckets.",
518
+ "details": {
519
+ "enabled": true,
520
+ "source": "secrecyLevel_aggDetailsConfig"
521
+ },
522
+ "datasource": [
523
+ {
524
+ "propertyPath": "aggregations.generaldocument_secrecyLevel_agg.buckets",
525
+ "transformer": "reduceData"
526
+ }
527
+ ],
528
+ "chart": {
529
+ "type": "bar",
530
+ "options": {
531
+ "indexAxis": "y",
532
+ "responsive": true,
533
+ "maintainAspectRatio": false,
534
+ "scales": {
535
+ "x": {
536
+ "ticks": {
537
+ "stepSize": 1,
538
+ "color": "var(--chart-ticks-x-color)"
539
+ },
540
+ "grid": {
541
+ "color": "var(--chart-grid-x-color)"
542
+ }
543
+ }
544
+ },
545
+ "plugins": {
546
+ "legend": {
547
+ "display": false
548
+ }
549
+ }
550
+ },
551
+ "plugins": ["chartDataLabels", "scrollableLegends", "doughnutEmptyState"]
552
+ }
553
+ }
554
+
555
+ ```
556
+
557
+ #### Chart Type Configuration
558
+
559
+ ```typescript
560
+ interface ChartTypeConfig {
561
+ enabled: boolean;
562
+ allowedTypes?: AllowedChartType[];
563
+ }
564
+ ```
565
+
566
+ |Property|Type|Required|Description|
567
+ |---|---|---|---|
568
+ |enabled|`boolean`|✅|Allow users to switch chart types|
569
+ |allowedTypes|`AllowedChartType[]`|❌|Restrict available chart types|
570
+
571
+ #### Dialog Configuration
572
+
573
+ ```typescript
574
+ type GraphDialogConfig = {
575
+ active: boolean;
576
+ panelClass?: string | string[];
577
+ width?: string;
578
+ height?: string;
579
+ minWidth?: number | string;
580
+ minHeight?: number | string;
581
+ maxWidth?: number | string;
582
+ maxHeight?: number | string;
583
+ position?: DialogPosition;
584
+ };
585
+ ```
586
+
587
+
588
+ ### Graph Charts
589
+
590
+
591
+ ### Report Details Configuration
592
+
593
+ Provides detailed tabular views of report data.
594
+
595
+ #### `ReportDetailsConfig` Type
596
+
597
+ ```typescript
598
+ export type ReportDetailsConfig = {
599
+ enabled: boolean;
600
+ source: ReportDetailsKey | ReportConfigOptions;
601
+ };
602
+ ```
603
+
604
+ #### Simple Configuration (String Key)
605
+
606
+ ```typescript
607
+ type ReportDetailsKey = string;
608
+ ```
609
+
610
+ Use a predefined report configuration from the server:
611
+
612
+ ```json
613
+ {
614
+ "details": {
615
+ "enabled": true,
616
+ "source": "DETAIL_REPORT"
617
+ }
618
+ }
619
+ ```
620
+
621
+ #### Advanced Configuration (Full Options)
622
+
623
+ ```typescript
624
+ export type ReportConfigOptions = {
625
+ request?: Partial<NdfReportsRequest> & {
626
+ actions?: {
627
+ beforeSubmit?: EvaluatedString<'payload'>;
628
+ };
629
+ };
630
+ columns?: TableColumnConfig[];
631
+ fields?: Record<string, string>;
632
+ prefix?: string;
633
+ quickFilters?: string;
634
+ columnsOptions?: {
635
+ toggle?: boolean;
636
+ sortable?: TableSortConfig;
637
+ };
638
+ sortingBy?: TableSortOptions;
639
+ export?: TableExportConfig;
640
+ };
641
+ ```
642
+
643
+ |Property|Type|Required|Description|
644
+ |---|---|---|---|
645
+ |request|`Partial<NdfReportsRequest> & ...`|❌|Request configuration with pre-submit actions|
646
+ |columns|`TableColumnConfig[]`|❌|Table column definitions|
647
+ |fields|`Record<string, string>`|❌|Field name mapping (response → display)|
648
+ |prefix|`string`|❌|Translation key prefix|
649
+ |quickFilters|`string`|❌|Quick filter configuration|
650
+ |columnsOptions|`object`|❌|Global column behavior settings|
651
+ |sortingBy|`TableSortOptions`|❌|Default sorting configuration|
652
+ |export|`TableExportConfig`|❌|Export functionality configuration|
653
+
654
+ #### Complete Example
655
+
656
+ ```json
657
+ {
658
+ "details": {
659
+ "enabled": true,
660
+ "source": {
661
+ "prefix": "REPORTS.",
662
+ "quickFilters": "After Archiving",
663
+ "columnsOptions": {
664
+ "toggle": true,
665
+ "sortable": {
666
+ "enabled": true
667
+ }
668
+ },
669
+ "request": {
670
+ "headers": {
671
+ "properties": "*"
672
+ },
673
+ "actions": {
674
+ "beforeSubmit": "payload.userId = 'getCurrentUser'"
675
+ }
676
+ },
677
+ "fields": {
678
+ "created": "dc:created",
679
+ "deptEnName": "padep:englishName",
680
+ "deptArName": "padep:arabicName"
681
+ },
682
+ "columns": [
683
+ {
684
+ "name": "Doc_Name",
685
+ "prop": "properties.title",
686
+ "display": true,
687
+ "type": "custom",
688
+ "template": "common.components.titleWithIcon",
689
+ "sortable": true,
690
+ "headerClass": "dc:title",
691
+ "defaultVisible": true
692
+ },
693
+ {
694
+ "name": "systemName",
695
+ "prop": "properties.systemName",
696
+ "display": true,
697
+ "type": "custom",
698
+ "template": "common.components.systemName",
699
+ "translatePrefix": "search.buckets",
700
+ "isOriginalKey": true,
701
+ "sortable": false,
702
+ "headerClass": "recdef:systemName",
703
+ "defaultVisible": true
704
+ }
705
+ ]
706
+ }
707
+ }
708
+ }
709
+ ```
710
+
711
+
712
+ ### Dynamic Line Charts
713
+
714
+ For time-based data visualization with dynamic grouping capabilities and temporal aggregation features.
715
+
716
+ #### `DynamicLineChartDefinition` Type
717
+
718
+ ```typescript
719
+ export type DynamicLineChartDefinition = ReportChartConfig & {
720
+ mode: 'dynamicLine';
721
+ prefix?: string;
722
+ colors?: string[];
723
+ print?: boolean;
724
+ request: NdfReportsRequest & {
725
+ actions?: {
726
+ beforeSubmit?: EvaluatedString<'payload'>;
727
+ };
728
+ };
729
+ datasource: ({ aggregation: string } & ReportDataSource)[];
730
+ group?: {
731
+ active: boolean;
732
+ selected?: TimeGroups;
733
+ };
734
+ chart: DynamicLineChartOptionsDefinition;
735
+ };
736
+ ```
737
+
738
+ #### Core Properties
739
+
740
+ |Property|Type|Required|Description|
741
+ |---|---|---|---|
742
+ |mode|`'dynamicLine'`|✅|Chart type identifier|
743
+ |prefix|`string`|❌|Translation key prefix for labels|
744
+ |colors|`string[]`|❌|Custom color palette (CSS colors/variables)|
745
+ |print|`boolean`|❌|Enable print functionality for this chart|
746
+ |request|`NdfReportsRequest & { actions? }`|✅|Enhanced request configuration with pre-submit actions|
747
+ |datasource|`({ aggregation: string } & ReportDataSource)[]`|✅|Data source configurations with aggregation identifiers|
748
+ |group|`TimeGroupConfig`|❌|Time grouping configuration for dynamic period selection|
749
+ |chart|`DynamicLineChartOptionsDefinition`|✅|Chart.js line chart specific configuration|
750
+
751
+ #### Enhanced Request Configuration
752
+
753
+ The `request` property extends the base `NdfReportsRequest` with action capabilities:
754
+
755
+ ```typescript
756
+ request: NdfReportsRequest & {
757
+ actions?: {
758
+ beforeSubmit?: EvaluatedString<'payload'>;
759
+ };
760
+ };
761
+ ```
762
+
763
+ **Actions Configuration**
764
+
765
+ |Property|Type|Required|Description|
766
+ |---|---|---|---|
767
+ |beforeSubmit|`EvaluatedString<'payload'>`|❌|Script executed before request submission for dynamic payload modification|
768
+
769
+ #### Data Source Configuration
770
+
771
+ Each data source combines standard `ReportDataSource` properties with aggregation-specific configuration:
772
+
773
+ ```typescript
774
+ datasource: ({ aggregation: string } & ReportDataSource)[];
775
+ ```
776
+
777
+ **Enhanced Properties**
778
+
779
+ |Property|Type|Required|Description|
780
+ |---|---|---|---|
781
+ |aggregation|`string`|✅|Aggregation identifier for time-based queries|
782
+ |propertyPath|`string`|✅|Path to data in API response|
783
+ |bindLabel|`string`|❌|Property for chart labels (typically time values)|
784
+ |bindValue|`string`|❌|Property for chart values (typically counts/metrics)|
785
+ |dataFormat|`string`|❌|Format string for data transformation|
786
+ |transformer|`string`|❌|Transformer name for data processing|
787
+
788
+ #### Time Grouping Configuration
789
+
790
+ ```typescript
791
+ const TIME_GROUPS = {
792
+ day: 'day',
793
+ week: 'week',
794
+ month: 'month',
795
+ year: 'year'
796
+ } as const;
797
+
798
+ export type TimeGroups = (typeof TIME_GROUPS)[keyof typeof TIME_GROUPS];
799
+
800
+ group?: {
801
+ active: boolean;
802
+ selected?: TimeGroups;
803
+ };
804
+ ```
805
+
806
+ **Time Group Properties**
807
+
808
+ |Property|Type|Required|Description|
809
+ |---|---|---|---|
810
+ |active|`boolean`|✅|Enable time grouping controls in UI|
811
+ |selected|`TimeGroups`|❌|Default selected time aggregation period|
812
+
813
+ **Available Time Groups**
814
+
815
+ |Value|Description|Use Case|
816
+ |---|---|---|
817
+ |`day`|Daily aggregation|Detailed short-term analysis|
818
+ |`week`|Weekly aggregation|Medium-term trend analysis|
819
+ |`month`|Monthly aggregation|Long-term trend visualization|
820
+ |`year`|Yearly aggregation|Historical data overview|
821
+
822
+ #### Chart Configuration
823
+
824
+ ```typescript
825
+ type DynamicLineChartOptionsDefinition = {
826
+ type: 'line';
827
+ options?: CustomChartOptions<'line'>;
828
+ datasets?: Omit<ChartDataset<'line'>, 'data'>[];
829
+ plugins?: string[];
830
+ colors?: string[];
831
+ };
832
+ ```
833
+
834
+ **Chart Properties**
835
+
836
+ |Property|Type|Required|Description|
837
+ |---|---|---|---|
838
+ |type|`'line'`|✅|Fixed chart type for dynamic line charts|
839
+ |options|`CustomChartOptions<'line'>`|❌|Chart.js line chart options with time scale support|
840
+ |datasets|`Omit<ChartDataset<'line'>, 'data'>[]`|❌|Dataset configurations excluding data property|
841
+ |plugins|`string[]`|❌|Plugin names (must be pre-registered in ChartPluginsRegistry)|
842
+ |colors|`string[]`|❌|Color palette override for chart elements|
843
+
844
+ #### Complete Example
845
+ ```json
846
+ {
847
+ "mode": "dynamicLine",
848
+ "id": "late_RetentionInfo_activeRetentionExpireDate_agg",
849
+ "label": "REPORTS.expectedTransferDate",
850
+ "print": true,
851
+ "dialog": {
852
+ "active": true,
853
+ "width": "80vw",
854
+ "height": "60vh"
855
+ },
856
+ "layout": {
857
+ "width": 12,
858
+ "height": 6
859
+ },
860
+ "group": {
861
+ "active": true,
862
+ "selected": "month"
863
+ },
864
+
865
+ "details": {
866
+ "enabled": true,
867
+ "source": "DETAILS_CONFIG"
868
+ },
869
+ "request": {
870
+ "pageProvider": "PP_RPT_Records",
871
+ "customUrl": {
872
+ "url": "/custom-search/admin/pp/PP_RPT_Records/execute",
873
+ "method": "post"
874
+ }
875
+ },
876
+ "datasource": [
877
+ {
878
+ "aggregation": "RetentionInfo_activeRetentionExpireDate_agg",
879
+ "propertyPath": "aggregations.RetentionInfo_activeRetentionExpireDate_agg.buckets",
880
+ "bindLabel": "key_as_string",
881
+ "bindValue": "doc_count",
882
+ "transformer": "timeFormat"
883
+ }
884
+ ],
885
+ "chart": {
886
+ "type": "line",
887
+ "options": {
888
+ "responsive": true,
889
+ "maintainAspectRatio": false,
890
+ "layout": {
891
+ "padding": {
892
+ "right": 40,
893
+ "left": 40
894
+ }
895
+ }
896
+ },
897
+ "plugins": ["singlePointCenter"],
898
+ "datasets": [
899
+ {
900
+ "borderWidth": 2,
901
+ "borderColor": "var(--chart-color-0)",
902
+ "pointBorderWidth": 0,
903
+ "pointBackgroundColor": "var(--chart-color-0)"
904
+ }
905
+ ]
906
+ }
907
+ }
908
+ ```
909
+
910
+
911
+ ### Custom Charts
912
+
913
+ For highly specialized visualizations using custom Angular components that extend the base report functionality with complete control over rendering and behavior.
914
+
915
+ #### `CustomChartDefinition` Type
916
+
917
+ ```typescript
918
+ export interface CustomChartDefinition extends BaseReportConfig {
919
+ mode: 'custom';
920
+ type: string;
921
+ prefix?: string;
922
+ print?: boolean;
923
+ datasource?: ReportDataSource[];
924
+ options?: Record<string, any>;
925
+ dialog?: GraphDialogConfig;
926
+ }
927
+ ```
928
+
929
+ #### Core Properties
930
+
931
+ |Property|Type|Required|Description|
932
+ |---|---|---|---|
933
+ |mode|`'custom'`|✅|Chart type identifier for custom components|
934
+ |type|`string`|✅|Unique identifier for component registration in `CustomReportsRegistry`|
935
+ |prefix|`string`|❌|Translation key prefix for component labels|
936
+ |print|`boolean`|❌|Enable print functionality for this component|
937
+ |datasource|`ReportDataSource[]`|❌|Optional data source configurations for component|
938
+ |options|`Record<string, any>`|❌|Custom configuration object passed to component|
939
+ |dialog|`GraphDialogConfig`|❌|Modal dialog configuration for detailed views|
940
+
941
+ #### Component Registration
942
+
943
+ Custom chart components must be registered with the `CustomReportsRegistry` before use:
944
+
945
+ ```typescript
946
+ export interface CustomReportRegistryDefinition {
947
+ type: string;
948
+ component: ComponentType<any>;
949
+ category?: string;
950
+ name?: string;
951
+ description?: string;
952
+ }
953
+ ```
954
+
955
+ **Registry Properties**
956
+
957
+ |Property|Type|Required|Description|
958
+ |---|---|---|---|
959
+ |type|`string`|✅|Unique identifier matching `CustomChartDefinition.type`|
960
+ |component|`ComponentType<any>`|✅|Angular component class extending `BaseCustomReport`|
961
+ |category|`string`|❌|Component categorization for organization|
962
+ |name|`string`|❌|Human-readable component name|
963
+ |description|`string`|❌|Component description and usage information|
964
+
965
+ #### Base Custom Report Class
966
+
967
+ All custom chart components must extend `BaseCustomReport`:
968
+
969
+ ```typescript
970
+ abstract class BaseCustomReport extends DestroySubject {
971
+ abstract print(): void;
972
+ @Input() direction: Direction = 'rtl';
973
+ @Input() definition: CustomChartDefinition;
974
+ @Input() data: ReportResponseModel;
975
+ @Input() criteria: CriteriaModel;
976
+ @Input() config : CustomChart ;
977
+ // ...
978
+ }
979
+ ```
980
+
981
+ **Base Class Properties**
982
+
983
+ |Property|Type|Description|
984
+ |---|---|---|
985
+ |chart|`Chart`|Chart.js instance when available|
986
+ |direction|`Direction`|Text direction for RTL/LTR support|
987
+ |definition|`CustomChartDefinition`|Complete chart configuration|
988
+ |data|`ReportResponseModel`|Current report data with reactive updates|
989
+ |criteria|`CriteriaModel`|Filter criteria with change notifications|
990
+ |config|`CustomChart`|Component-specific configuration|
991
+
992
+ **Required Implementation**
993
+
994
+ |Method|Return Type|Description|
995
+ |---|---|---|
996
+ |print()|`void`|Custom print functionality implementation|
997
+
998
+ #### Component Implementation Example
999
+ ```typescript
1000
+ @Component({
1001
+ selector: 'app-capacity-chart',
1002
+ template: `
1003
+ <div class="Heatmap-container" [class.rtl]="direction === 'rtl'">
1004
+ <app-chart
1005
+
1006
+ type="doughnut"
1007
+ [data]="chartData"
1008
+ [options]="options"
1009
+ [responsive]="true"
1010
+ [plugins]="plugins"
1011
+ (onReady)="chartReady($event)"
1012
+ >
1013
+ </app-chart>
1014
+ </div>
1015
+ `,
1016
+ })
1017
+ export class HeatmapChartComponent
1018
+ extends BaseCustomReport
1019
+ implements OnInit, OnDestroy
1020
+ {
1021
+ // Optional: Used to register the component in the system
1022
+ static registerInfo(): CustomReportRegistryDefinition {
1023
+ return {
1024
+ type: 'heatmap-chart',
1025
+ component: HeatmapChartComponent,
1026
+ category: 'visualization',
1027
+ name: 'Heatmap Chart',
1028
+ description: 'Advanced heatmap visualization for correlation data'
1029
+ };
1030
+ }
1031
+ // ...
1032
+ print(): void {
1033
+ this._chartHelperService.printChart(
1034
+ this.chart.id,
1035
+ this._translateService.instant(this.config.label),
1036
+ this.options,
1037
+ [
1038
+ circleLabel({
1039
+ shadowBlur: 0,
1040
+ font: 'bold 32px sans-serif',
1041
+ value: `15%`,
1042
+ }),
1043
+ ]
1044
+ )
1045
+ }
1046
+ }
1047
+ ```
1048
+
1049
+ #### Registration and Configuration
1050
+
1051
+ **Step 1: Register Component**
1052
+
1053
+ ```typescript
1054
+ // In your module or service
1055
+ constructor(private customReportsRegistry: CustomReportsRegistry) {
1056
+ this.customReportsRegistry.registerComponent({
1057
+ type: 'heatmap-chart',
1058
+ component: HeatmapChartComponent,
1059
+ category: 'visualization',
1060
+ name: 'Heatmap Chart',
1061
+ description: 'Advanced heatmap visualization for correlation data'
1062
+ } // or use HeatmapChartComponent.registerInfo()
1063
+ );
1064
+ }
1065
+ ```
1066
+
1067
+ **Step 2: Configure in Reports**
1068
+
1069
+ ```json
1070
+ {
1071
+ "id": "correlation-heatmap",
1072
+ "label": "REPORTS.correlationHeatmap",
1073
+ "mode": "custom",
1074
+ "type": "heatmap-chart",
1075
+ "prefix": "HEATMAP.",
1076
+ "print": true,
1077
+ "layout": {
1078
+ "width": 8,
1079
+ "height": 6
1080
+ },
1081
+ "datasource": [
1082
+ {
1083
+ "propertyPath": "aggregations.correlation_matrix.buckets",
1084
+ "transformer": "matrixDataProcessor"
1085
+ }
1086
+ ],
1087
+ "options": {
1088
+ "chartOptions": {
1089
+ "scales": {
1090
+ "x": {
1091
+ "type": 'linear',
1092
+ "position": 'bottom'
1093
+ },
1094
+ "y": {
1095
+ "type": 'linear'
1096
+ }
1097
+ }
1098
+ },
1099
+ "colorScheme": "viridis",
1100
+ "showValues": true,
1101
+ "gridLines": true
1102
+ },
1103
+ "dialog": {
1104
+ "active": true,
1105
+ "width": "90vw",
1106
+ "height": "80vh",
1107
+ "panelClass": "heatmap-dialog"
1108
+ }
1109
+ }
1110
+ ```
1111
+
1112
+ #### Development Best Practices
1113
+
1114
+ **Memory Management**
1115
+ ```typescript
1116
+ ngOnDestroy() {
1117
+ // Always clean up Chart.js instances
1118
+ if (this.customChart) {
1119
+ this.customChart.destroy();
1120
+ }
1121
+
1122
+ // Call parent cleanup
1123
+ super.ngOnDestroy();
1124
+ }
1125
+ ```
1126
+
1127
+
1128
+ ## Related Types Reference
1129
+
1130
+ ### Core Types
1131
+
1132
+ #### `REPORT_MODE` Constants
1133
+
1134
+ ```typescript
1135
+ export const REPORT_MODE = {
1136
+ graph: 'graph',
1137
+ digit: 'digit',
1138
+ dynamicLine: 'dynamicLine',
1139
+ custom: 'custom',
1140
+ } as const;
1141
+
1142
+ export type ReportMode = (typeof REPORT_MODE)[keyof typeof REPORT_MODE];
1143
+ ```
1144
+
1145
+ #### `GridWidth` Type
1146
+
1147
+ ```typescript
1148
+ export type GridWidth = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 'auto';
1149
+ ```
1150
+
1151
+ #### Chart Types
1152
+
1153
+ ```typescript
1154
+ const CHARTS_TYPES = {
1155
+ verticalBar: 'verticalBar',
1156
+ horizontalBar: 'horizontalBar',
1157
+ doughnut: 'doughnut',
1158
+ line: 'line',
1159
+ pie: 'pie'
1160
+ } as const;
1161
+
1162
+ type AllowedChartType = (typeof CHARTS_TYPES)[keyof Omit<typeof CHARTS_TYPES, 'line'>];
1163
+ ```
1164
+
1165
+
1166
+
1167
+ ## Troubleshooting
1168
+
1169
+ ### Common Issues
1170
+
1171
+ #### 1. Transformer Not Found
1172
+
1173
+ **Error**: `Transformer 'myTransformer' not registered` **Solution**: Register the transformer using the appropriate service method:
1174
+
1175
+ ```typescript
1176
+ // For digit charts
1177
+ chartDataTransformers.registerDigitsTransformer('myTransformer', transformFunction);
1178
+
1179
+ // For graph charts
1180
+ chartDataTransformers.registerGraphTransformers('myTransformer', transformFunction);
1181
+ ```
1182
+
1183
+ #### 2. Plugin Not Available
1184
+
1185
+ **Error**: `Plugin with key 'myPlugin' not found.` **Solution**: Register the plugin in `ChartPluginsRegistry` before using:
1186
+
1187
+ ```typescript
1188
+ chartPluginsRegistry.register('myPlugin', myPluginImplementation);
1189
+ ```
1190
+
1191
+ #### 3. Data Path Not Found
1192
+
1193
+ **Error**: Chart shows no data **Solution**: Verify the `propertyPath` matches your API response structure:
1194
+
1195
+ ```typescript
1196
+ // If API returns: { data: { aggregation: { total: 1000 } } }
1197
+ // Use propertyPath: "data.aggregation.total"
1198
+ ```
1199
+
1200
+ #### 4. Layout Issues
1201
+
1202
+ **Problem**: Charts overlapping or not displaying properly **Solution**: Check grid layout configuration:
1203
+
1204
+ ```json
1205
+ {
1206
+ "layout": {
1207
+ "width": 6, // Must be 1-12
1208
+ "height": "auto", // Use "auto" for dynamic sizing
1209
+ "columnPosition": 1,
1210
+ "rowPosition": "auto"
1211
+ }
1212
+ }
1213
+ ```