@toolbox-web/grid-angular 0.9.1 → 0.11.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.
- package/README.md +28 -22
- package/fesm2022/toolbox-web-grid-angular-features-export.mjs +123 -4
- package/fesm2022/toolbox-web-grid-angular-features-export.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs +123 -1
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-print.mjs +89 -1
- package/fesm2022/toolbox-web-grid-angular-features-print.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-selection.mjs +133 -1
- package/fesm2022/toolbox-web-grid-angular-features-selection.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-undo-redo.mjs +106 -1
- package/fesm2022/toolbox-web-grid-angular-features-undo-redo.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular.mjs +757 -122
- package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/types/toolbox-web-grid-angular-features-export.d.ts +113 -1
- package/types/toolbox-web-grid-angular-features-export.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-filtering.d.ts +120 -1
- package/types/toolbox-web-grid-angular-features-filtering.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-print.d.ts +91 -1
- package/types/toolbox-web-grid-angular-features-print.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-selection.d.ts +114 -1
- package/types/toolbox-web-grid-angular-features-selection.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-undo-redo.d.ts +107 -1
- package/types/toolbox-web-grid-angular-features-undo-redo.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular.d.ts +419 -91
- package/types/toolbox-web-grid-angular.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -434,14 +434,14 @@ Your components should implement one of these interfaces:
|
|
|
434
434
|
|
|
435
435
|
```typescript
|
|
436
436
|
import { Component, input } from '@angular/core';
|
|
437
|
-
import type {
|
|
437
|
+
import type { CellRenderer, ColumnConfig } from '@toolbox-web/grid-angular';
|
|
438
438
|
|
|
439
439
|
@Component({
|
|
440
440
|
selector: 'app-status-badge',
|
|
441
441
|
template: `<span [class]="'badge badge--' + value()">{{ value() }}</span>`,
|
|
442
442
|
standalone: true,
|
|
443
443
|
})
|
|
444
|
-
export class StatusBadgeComponent implements
|
|
444
|
+
export class StatusBadgeComponent implements CellRenderer<Employee, string> {
|
|
445
445
|
value = input.required<string>();
|
|
446
446
|
row = input.required<Employee>();
|
|
447
447
|
column = input<ColumnConfig>(); // Optional
|
|
@@ -452,7 +452,7 @@ export class StatusBadgeComponent implements AngularCellRenderer<Employee, strin
|
|
|
452
452
|
|
|
453
453
|
```typescript
|
|
454
454
|
import { Component, input, output } from '@angular/core';
|
|
455
|
-
import type {
|
|
455
|
+
import type { CellEditor, ColumnConfig } from '@toolbox-web/grid-angular';
|
|
456
456
|
|
|
457
457
|
@Component({
|
|
458
458
|
selector: 'app-bonus-editor',
|
|
@@ -462,7 +462,7 @@ import type { AngularCellEditor, ColumnConfig } from '@toolbox-web/grid-angular'
|
|
|
462
462
|
`,
|
|
463
463
|
standalone: true,
|
|
464
464
|
})
|
|
465
|
-
export class BonusEditorComponent implements
|
|
465
|
+
export class BonusEditorComponent implements CellEditor<Employee, number> {
|
|
466
466
|
value = input.required<number>();
|
|
467
467
|
row = input.required<Employee>();
|
|
468
468
|
column = input<ColumnConfig>(); // Optional
|
|
@@ -482,21 +482,21 @@ export class BonusEditorComponent implements AngularCellEditor<Employee, number>
|
|
|
482
482
|
|
|
483
483
|
### Using Components in Grid Config
|
|
484
484
|
|
|
485
|
-
Use `
|
|
485
|
+
Use `GridConfig` with the `gridConfig` input for type-safe component references:
|
|
486
486
|
|
|
487
487
|
```typescript
|
|
488
488
|
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
489
|
-
import { Grid, type
|
|
489
|
+
import { Grid, type GridConfig } from '@toolbox-web/grid-angular';
|
|
490
490
|
import { EditingPlugin } from '@toolbox-web/grid/plugins/editing';
|
|
491
491
|
import { StatusBadgeComponent, BonusEditorComponent } from './components';
|
|
492
492
|
|
|
493
493
|
@Component({
|
|
494
494
|
imports: [Grid],
|
|
495
495
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
496
|
-
template: `<tbw-grid [
|
|
496
|
+
template: `<tbw-grid [gridConfig]="config" [rows]="employees" />`,
|
|
497
497
|
})
|
|
498
498
|
export class MyGridComponent {
|
|
499
|
-
config:
|
|
499
|
+
config: GridConfig<Employee> = {
|
|
500
500
|
columns: [
|
|
501
501
|
{ field: 'name', header: 'Name' },
|
|
502
502
|
{ field: 'status', header: 'Status', renderer: StatusBadgeComponent },
|
|
@@ -507,14 +507,14 @@ export class MyGridComponent {
|
|
|
507
507
|
}
|
|
508
508
|
```
|
|
509
509
|
|
|
510
|
-
|
|
510
|
+
The `gridConfig` input accepts `GridConfig` (Angular-augmented) which allows both component classes and vanilla JS functions. When component classes are detected, the directive automatically converts them to grid-compatible renderer functions.
|
|
511
511
|
|
|
512
512
|
### Interfaces Reference
|
|
513
513
|
|
|
514
|
-
| Interface
|
|
515
|
-
|
|
|
516
|
-
| `
|
|
517
|
-
| `
|
|
514
|
+
| Interface | Required Inputs | Required Outputs | Description |
|
|
515
|
+
| -------------- | ------------------ | ------------------ | ------------------ |
|
|
516
|
+
| `CellRenderer` | `value()`, `row()` | - | Read-only renderer |
|
|
517
|
+
| `CellEditor` | `value()`, `row()` | `commit`, `cancel` | Editable cell |
|
|
518
518
|
|
|
519
519
|
Both interfaces also support an optional `column()` input for accessing the column configuration.
|
|
520
520
|
|
|
@@ -855,10 +855,11 @@ if (context?.hasFormGroups) {
|
|
|
855
855
|
|
|
856
856
|
### Grid Directive Inputs
|
|
857
857
|
|
|
858
|
-
| Input | Type
|
|
859
|
-
| --------------- |
|
|
860
|
-
| `
|
|
861
|
-
| `
|
|
858
|
+
| Input | Type | Description |
|
|
859
|
+
| --------------- | ------------------ | ------------------------------------------------- |
|
|
860
|
+
| `gridConfig` | `GridConfig<TRow>` | Grid config with optional component class support |
|
|
861
|
+
| `angularConfig` | `GridConfig<TRow>` | **Deprecated** - use `gridConfig` instead |
|
|
862
|
+
| `customStyles` | `string` | Custom CSS styles to inject into the grid |
|
|
862
863
|
|
|
863
864
|
### Grid Directive Outputs
|
|
864
865
|
|
|
@@ -900,13 +901,18 @@ import type {
|
|
|
900
901
|
// Events
|
|
901
902
|
CellCommitEvent,
|
|
902
903
|
RowCommitEvent,
|
|
903
|
-
//
|
|
904
|
-
|
|
905
|
-
|
|
904
|
+
// Primary config exports - use these
|
|
905
|
+
GridConfig,
|
|
906
|
+
ColumnConfig,
|
|
907
|
+
CellRenderer,
|
|
908
|
+
CellEditor,
|
|
909
|
+
TypeDefault,
|
|
910
|
+
// Deprecated aliases
|
|
911
|
+
AngularGridConfig,
|
|
912
|
+
AngularColumnConfig,
|
|
906
913
|
AngularCellRenderer,
|
|
907
914
|
AngularCellEditor,
|
|
908
|
-
|
|
909
|
-
AngularGridConfig,
|
|
915
|
+
AngularTypeDefault,
|
|
910
916
|
// Reactive Forms
|
|
911
917
|
FormArrayContext,
|
|
912
918
|
} from '@toolbox-web/grid-angular';
|
|
@@ -1,17 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { inject, ElementRef, signal } from '@angular/core';
|
|
2
2
|
import { registerFeature } from '@toolbox-web/grid-angular';
|
|
3
|
+
import { ExportPlugin } from '@toolbox-web/grid/plugins/export';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Export feature for @toolbox-web/grid-angular
|
|
6
7
|
*
|
|
7
|
-
* Import this module to enable the `
|
|
8
|
+
* Import this module to enable the `export` input on Grid directive.
|
|
9
|
+
* Also exports `injectGridExport()` for programmatic export control.
|
|
8
10
|
*
|
|
9
11
|
* @example
|
|
10
12
|
* ```typescript
|
|
11
13
|
* import '@toolbox-web/grid-angular/features/export';
|
|
12
14
|
*
|
|
13
|
-
* <tbw-grid [
|
|
14
|
-
* <tbw-grid [
|
|
15
|
+
* <tbw-grid [export]="true" />
|
|
16
|
+
* <tbw-grid [export]="{ fileName: 'data.csv' }" />
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example Using injectGridExport
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { injectGridExport } from '@toolbox-web/grid-angular/features/export';
|
|
22
|
+
*
|
|
23
|
+
* @Component({...})
|
|
24
|
+
* export class MyComponent {
|
|
25
|
+
* private gridExport = injectGridExport();
|
|
26
|
+
*
|
|
27
|
+
* exportData() {
|
|
28
|
+
* this.gridExport.exportToCsv('employees.csv');
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
15
31
|
* ```
|
|
16
32
|
*
|
|
17
33
|
* @packageDocumentation
|
|
@@ -22,8 +38,111 @@ registerFeature('export', (config) => {
|
|
|
22
38
|
}
|
|
23
39
|
return new ExportPlugin(config ?? undefined);
|
|
24
40
|
});
|
|
41
|
+
/**
|
|
42
|
+
* Angular inject function for programmatic export control.
|
|
43
|
+
*
|
|
44
|
+
* Uses **lazy grid discovery** - the grid element is found when methods are called,
|
|
45
|
+
* not during initialization. This ensures it works reliably with:
|
|
46
|
+
* - Lazy-rendered tabs
|
|
47
|
+
* - Conditional rendering (*ngIf)
|
|
48
|
+
* - Dynamic component loading
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
53
|
+
* import { Grid } from '@toolbox-web/grid-angular';
|
|
54
|
+
* import '@toolbox-web/grid-angular/features/export';
|
|
55
|
+
* import { injectGridExport } from '@toolbox-web/grid-angular/features/export';
|
|
56
|
+
*
|
|
57
|
+
* @Component({
|
|
58
|
+
* selector: 'app-my-grid',
|
|
59
|
+
* imports: [Grid],
|
|
60
|
+
* schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
61
|
+
* template: `
|
|
62
|
+
* <button (click)="handleExport()">Export CSV</button>
|
|
63
|
+
* <tbw-grid [rows]="rows" [export]="true"></tbw-grid>
|
|
64
|
+
* `
|
|
65
|
+
* })
|
|
66
|
+
* export class MyGridComponent {
|
|
67
|
+
* gridExport = injectGridExport();
|
|
68
|
+
*
|
|
69
|
+
* handleExport() {
|
|
70
|
+
* this.gridExport.exportToCsv('employees.csv');
|
|
71
|
+
* }
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
function injectGridExport() {
|
|
76
|
+
const elementRef = inject(ElementRef);
|
|
77
|
+
const isReady = signal(false, ...(ngDevMode ? [{ debugName: "isReady" }] : []));
|
|
78
|
+
// Lazy discovery: cached grid reference
|
|
79
|
+
let cachedGrid = null;
|
|
80
|
+
let readyPromiseStarted = false;
|
|
81
|
+
/**
|
|
82
|
+
* Lazily find the grid element. Called on each method invocation.
|
|
83
|
+
* Caches the reference once found and triggers ready() check.
|
|
84
|
+
*/
|
|
85
|
+
const getGrid = () => {
|
|
86
|
+
if (cachedGrid)
|
|
87
|
+
return cachedGrid;
|
|
88
|
+
const grid = elementRef.nativeElement.querySelector('tbw-grid');
|
|
89
|
+
if (grid) {
|
|
90
|
+
cachedGrid = grid;
|
|
91
|
+
// Start ready() check only once
|
|
92
|
+
if (!readyPromiseStarted) {
|
|
93
|
+
readyPromiseStarted = true;
|
|
94
|
+
grid.ready?.().then(() => isReady.set(true));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return grid;
|
|
98
|
+
};
|
|
99
|
+
const getPlugin = () => {
|
|
100
|
+
return getGrid()?.getPlugin(ExportPlugin);
|
|
101
|
+
};
|
|
102
|
+
return {
|
|
103
|
+
isReady: isReady.asReadonly(),
|
|
104
|
+
exportToCsv: (filename, params) => {
|
|
105
|
+
const plugin = getPlugin();
|
|
106
|
+
if (!plugin) {
|
|
107
|
+
console.warn(`[tbw-grid:export] ExportPlugin not found.\n\n` +
|
|
108
|
+
` → Enable export on the grid:\n` +
|
|
109
|
+
` <tbw-grid [export]="true" />`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
plugin.exportCsv({ ...params, fileName: filename ?? params?.fileName ?? 'export.csv' });
|
|
113
|
+
},
|
|
114
|
+
exportToExcel: (filename, params) => {
|
|
115
|
+
const plugin = getPlugin();
|
|
116
|
+
if (!plugin) {
|
|
117
|
+
console.warn(`[tbw-grid:export] ExportPlugin not found.\n\n` +
|
|
118
|
+
` → Enable export on the grid:\n` +
|
|
119
|
+
` <tbw-grid [export]="true" />`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
plugin.exportExcel({ ...params, fileName: filename ?? params?.fileName ?? 'export.xlsx' });
|
|
123
|
+
},
|
|
124
|
+
exportToJson: (filename, params) => {
|
|
125
|
+
const plugin = getPlugin();
|
|
126
|
+
if (!plugin) {
|
|
127
|
+
console.warn(`[tbw-grid:export] ExportPlugin not found.\n\n` +
|
|
128
|
+
` → Enable export on the grid:\n` +
|
|
129
|
+
` <tbw-grid [export]="true" />`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
plugin.exportJson({ ...params, fileName: filename ?? params?.fileName ?? 'export.json' });
|
|
133
|
+
},
|
|
134
|
+
isExporting: () => {
|
|
135
|
+
return getPlugin()?.isExporting() ?? false;
|
|
136
|
+
},
|
|
137
|
+
getLastExport: () => {
|
|
138
|
+
return getPlugin()?.getLastExport() ?? null;
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
25
142
|
|
|
26
143
|
/**
|
|
27
144
|
* Generated bundle index. Do not edit.
|
|
28
145
|
*/
|
|
146
|
+
|
|
147
|
+
export { injectGridExport };
|
|
29
148
|
//# sourceMappingURL=toolbox-web-grid-angular-features-export.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbox-web-grid-angular-features-export.mjs","sources":["../../../../libs/grid-angular/features/export/src/index.ts","../../../../libs/grid-angular/features/export/src/toolbox-web-grid-angular-features-export.ts"],"sourcesContent":["/**\n * Export feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `
|
|
1
|
+
{"version":3,"file":"toolbox-web-grid-angular-features-export.mjs","sources":["../../../../libs/grid-angular/features/export/src/index.ts","../../../../libs/grid-angular/features/export/src/toolbox-web-grid-angular-features-export.ts"],"sourcesContent":["/**\n * Export feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `export` input on Grid directive.\n * Also exports `injectGridExport()` for programmatic export control.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/export';\n *\n * <tbw-grid [export]=\"true\" />\n * <tbw-grid [export]=\"{ fileName: 'data.csv' }\" />\n * ```\n *\n * @example Using injectGridExport\n * ```typescript\n * import { injectGridExport } from '@toolbox-web/grid-angular/features/export';\n *\n * @Component({...})\n * export class MyComponent {\n * private gridExport = injectGridExport();\n *\n * exportData() {\n * this.gridExport.exportToCsv('employees.csv');\n * }\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport { ElementRef, inject, signal, type Signal } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { registerFeature } from '@toolbox-web/grid-angular';\nimport { ExportPlugin, type ExportFormat, type ExportParams } from '@toolbox-web/grid/plugins/export';\n\nregisterFeature('export', (config) => {\n if (config === true) {\n return new ExportPlugin();\n }\n return new ExportPlugin(config ?? undefined);\n});\n\n/**\n * Export methods returned from injectGridExport.\n *\n * Uses lazy discovery - the grid is found on first method call, not during initialization.\n * This ensures it works with lazy-rendered tabs, conditional rendering, etc.\n */\nexport interface ExportMethods {\n /**\n * Export grid data to CSV file.\n * @param filename - Optional filename (defaults to 'export.csv')\n * @param params - Optional export parameters\n */\n exportToCsv: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Export grid data to Excel file (XML Spreadsheet format).\n * @param filename - Optional filename (defaults to 'export.xlsx')\n * @param params - Optional export parameters\n */\n exportToExcel: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Export grid data to JSON file.\n * @param filename - Optional filename (defaults to 'export.json')\n * @param params - Optional export parameters\n */\n exportToJson: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Check if an export is currently in progress.\n */\n isExporting: () => boolean;\n\n /**\n * Get information about the last export.\n */\n getLastExport: () => { format: ExportFormat; timestamp: Date } | null;\n\n /**\n * Signal indicating if grid is ready.\n * The grid is discovered lazily, so this updates when first method call succeeds.\n */\n isReady: Signal<boolean>;\n}\n\n/**\n * Angular inject function for programmatic export control.\n *\n * Uses **lazy grid discovery** - the grid element is found when methods are called,\n * not during initialization. This ensures it works reliably with:\n * - Lazy-rendered tabs\n * - Conditional rendering (*ngIf)\n * - Dynamic component loading\n *\n * @example\n * ```typescript\n * import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import '@toolbox-web/grid-angular/features/export';\n * import { injectGridExport } from '@toolbox-web/grid-angular/features/export';\n *\n * @Component({\n * selector: 'app-my-grid',\n * imports: [Grid],\n * schemas: [CUSTOM_ELEMENTS_SCHEMA],\n * template: `\n * <button (click)=\"handleExport()\">Export CSV</button>\n * <tbw-grid [rows]=\"rows\" [export]=\"true\"></tbw-grid>\n * `\n * })\n * export class MyGridComponent {\n * gridExport = injectGridExport();\n *\n * handleExport() {\n * this.gridExport.exportToCsv('employees.csv');\n * }\n * }\n * ```\n */\nexport function injectGridExport(): ExportMethods {\n const elementRef = inject(ElementRef);\n const isReady = signal(false);\n\n // Lazy discovery: cached grid reference\n let cachedGrid: DataGridElement | null = null;\n let readyPromiseStarted = false;\n\n /**\n * Lazily find the grid element. Called on each method invocation.\n * Caches the reference once found and triggers ready() check.\n */\n const getGrid = (): DataGridElement | null => {\n if (cachedGrid) return cachedGrid;\n\n const grid = elementRef.nativeElement.querySelector('tbw-grid') as DataGridElement | null;\n if (grid) {\n cachedGrid = grid;\n // Start ready() check only once\n if (!readyPromiseStarted) {\n readyPromiseStarted = true;\n grid.ready?.().then(() => isReady.set(true));\n }\n }\n return grid;\n };\n\n const getPlugin = (): ExportPlugin | undefined => {\n return getGrid()?.getPlugin(ExportPlugin);\n };\n\n return {\n isReady: isReady.asReadonly(),\n\n exportToCsv: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportCsv({ ...params, fileName: filename ?? params?.fileName ?? 'export.csv' });\n },\n\n exportToExcel: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportExcel({ ...params, fileName: filename ?? params?.fileName ?? 'export.xlsx' });\n },\n\n exportToJson: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportJson({ ...params, fileName: filename ?? params?.fileName ?? 'export.json' });\n },\n\n isExporting: () => {\n return getPlugin()?.isExporting() ?? false;\n },\n\n getLastExport: () => {\n return getPlugin()?.getLastExport() ?? null;\n },\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { inject, ElementRef, signal } from '@angular/core';
|
|
2
2
|
import { registerFeature } from '@toolbox-web/grid-angular';
|
|
3
|
+
import { FilteringPlugin } from '@toolbox-web/grid/plugins/filtering';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Filtering feature for @toolbox-web/grid-angular
|
|
6
7
|
*
|
|
7
8
|
* Import this module to enable the `filtering` input on Grid directive.
|
|
9
|
+
* Also exports `injectGridFiltering()` for programmatic filter control.
|
|
8
10
|
*
|
|
9
11
|
* @example
|
|
10
12
|
* ```typescript
|
|
@@ -14,6 +16,20 @@ import { registerFeature } from '@toolbox-web/grid-angular';
|
|
|
14
16
|
* <tbw-grid [filtering]="{ debounceMs: 200 }" />
|
|
15
17
|
* ```
|
|
16
18
|
*
|
|
19
|
+
* @example Using injectGridFiltering
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { injectGridFiltering } from '@toolbox-web/grid-angular/features/filtering';
|
|
22
|
+
*
|
|
23
|
+
* @Component({...})
|
|
24
|
+
* export class MyComponent {
|
|
25
|
+
* private filtering = injectGridFiltering();
|
|
26
|
+
*
|
|
27
|
+
* filterByStatus(status: string) {
|
|
28
|
+
* this.filtering.setFilter('status', { operator: 'equals', value: status });
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
17
33
|
* @packageDocumentation
|
|
18
34
|
*/
|
|
19
35
|
registerFeature('filtering', (config) => {
|
|
@@ -22,8 +38,114 @@ registerFeature('filtering', (config) => {
|
|
|
22
38
|
}
|
|
23
39
|
return new FilteringPlugin(config ?? undefined);
|
|
24
40
|
});
|
|
41
|
+
/**
|
|
42
|
+
* Angular inject function for programmatic filter control.
|
|
43
|
+
*
|
|
44
|
+
* Uses **lazy grid discovery** - the grid element is found when methods are called,
|
|
45
|
+
* not during initialization.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
50
|
+
* import { Grid } from '@toolbox-web/grid-angular';
|
|
51
|
+
* import '@toolbox-web/grid-angular/features/filtering';
|
|
52
|
+
* import { injectGridFiltering } from '@toolbox-web/grid-angular/features/filtering';
|
|
53
|
+
*
|
|
54
|
+
* @Component({
|
|
55
|
+
* selector: 'app-my-grid',
|
|
56
|
+
* imports: [Grid],
|
|
57
|
+
* schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
58
|
+
* template: `
|
|
59
|
+
* <input (input)="applyFilter($event)" placeholder="Filter by name..." />
|
|
60
|
+
* <span>{{ filtering.getFilteredRowCount() }} results</span>
|
|
61
|
+
* <button (click)="filtering.clearAllFilters()">Clear</button>
|
|
62
|
+
* <tbw-grid [rows]="rows" [filtering]="true"></tbw-grid>
|
|
63
|
+
* `
|
|
64
|
+
* })
|
|
65
|
+
* export class MyGridComponent {
|
|
66
|
+
* filtering = injectGridFiltering();
|
|
67
|
+
*
|
|
68
|
+
* applyFilter(event: Event) {
|
|
69
|
+
* const value = (event.target as HTMLInputElement).value;
|
|
70
|
+
* this.filtering.setFilter('name', value ? { operator: 'contains', value } : null);
|
|
71
|
+
* }
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
function injectGridFiltering() {
|
|
76
|
+
const elementRef = inject(ElementRef);
|
|
77
|
+
const isReady = signal(false, ...(ngDevMode ? [{ debugName: "isReady" }] : []));
|
|
78
|
+
let cachedGrid = null;
|
|
79
|
+
let readyPromiseStarted = false;
|
|
80
|
+
const getGrid = () => {
|
|
81
|
+
if (cachedGrid)
|
|
82
|
+
return cachedGrid;
|
|
83
|
+
const grid = elementRef.nativeElement.querySelector('tbw-grid');
|
|
84
|
+
if (grid) {
|
|
85
|
+
cachedGrid = grid;
|
|
86
|
+
if (!readyPromiseStarted) {
|
|
87
|
+
readyPromiseStarted = true;
|
|
88
|
+
grid.ready?.().then(() => isReady.set(true));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return grid;
|
|
92
|
+
};
|
|
93
|
+
const getPlugin = () => {
|
|
94
|
+
return getGrid()?.getPlugin(FilteringPlugin);
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
isReady: isReady.asReadonly(),
|
|
98
|
+
setFilter: (field, filter) => {
|
|
99
|
+
const plugin = getPlugin();
|
|
100
|
+
if (!plugin) {
|
|
101
|
+
console.warn(`[tbw-grid:filtering] FilteringPlugin not found.\n\n` +
|
|
102
|
+
` → Enable filtering on the grid:\n` +
|
|
103
|
+
` <tbw-grid [filtering]="true" />`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
plugin.setFilter(field, filter);
|
|
107
|
+
},
|
|
108
|
+
getFilter: (field) => getPlugin()?.getFilter(field),
|
|
109
|
+
getFilters: () => getPlugin()?.getFilters() ?? [],
|
|
110
|
+
setFilterModel: (filters) => {
|
|
111
|
+
const plugin = getPlugin();
|
|
112
|
+
if (!plugin) {
|
|
113
|
+
console.warn(`[tbw-grid:filtering] FilteringPlugin not found.\n\n` +
|
|
114
|
+
` → Enable filtering on the grid:\n` +
|
|
115
|
+
` <tbw-grid [filtering]="true" />`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
plugin.setFilterModel(filters);
|
|
119
|
+
},
|
|
120
|
+
clearAllFilters: () => {
|
|
121
|
+
const plugin = getPlugin();
|
|
122
|
+
if (!plugin) {
|
|
123
|
+
console.warn(`[tbw-grid:filtering] FilteringPlugin not found.\n\n` +
|
|
124
|
+
` → Enable filtering on the grid:\n` +
|
|
125
|
+
` <tbw-grid [filtering]="true" />`);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
plugin.clearAllFilters();
|
|
129
|
+
},
|
|
130
|
+
clearFieldFilter: (field) => {
|
|
131
|
+
const plugin = getPlugin();
|
|
132
|
+
if (!plugin) {
|
|
133
|
+
console.warn(`[tbw-grid:filtering] FilteringPlugin not found.\n\n` +
|
|
134
|
+
` → Enable filtering on the grid:\n` +
|
|
135
|
+
` <tbw-grid [filtering]="true" />`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
plugin.clearFieldFilter(field);
|
|
139
|
+
},
|
|
140
|
+
isFieldFiltered: (field) => getPlugin()?.isFieldFiltered(field) ?? false,
|
|
141
|
+
getFilteredRowCount: () => getPlugin()?.getFilteredRowCount() ?? 0,
|
|
142
|
+
getUniqueValues: (field) => getPlugin()?.getUniqueValues(field) ?? [],
|
|
143
|
+
};
|
|
144
|
+
}
|
|
25
145
|
|
|
26
146
|
/**
|
|
27
147
|
* Generated bundle index. Do not edit.
|
|
28
148
|
*/
|
|
149
|
+
|
|
150
|
+
export { injectGridFiltering };
|
|
29
151
|
//# sourceMappingURL=toolbox-web-grid-angular-features-filtering.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbox-web-grid-angular-features-filtering.mjs","sources":["../../../../libs/grid-angular/features/filtering/src/index.ts","../../../../libs/grid-angular/features/filtering/src/toolbox-web-grid-angular-features-filtering.ts"],"sourcesContent":["/**\n * Filtering feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `filtering` input on Grid directive.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/filtering';\n *\n * <tbw-grid [filtering]=\"true\" />\n * <tbw-grid [filtering]=\"{ debounceMs: 200 }\" />\n * ```\n *\n * @packageDocumentation\n */\n\nimport {
|
|
1
|
+
{"version":3,"file":"toolbox-web-grid-angular-features-filtering.mjs","sources":["../../../../libs/grid-angular/features/filtering/src/index.ts","../../../../libs/grid-angular/features/filtering/src/toolbox-web-grid-angular-features-filtering.ts"],"sourcesContent":["/**\n * Filtering feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `filtering` input on Grid directive.\n * Also exports `injectGridFiltering()` for programmatic filter control.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/filtering';\n *\n * <tbw-grid [filtering]=\"true\" />\n * <tbw-grid [filtering]=\"{ debounceMs: 200 }\" />\n * ```\n *\n * @example Using injectGridFiltering\n * ```typescript\n * import { injectGridFiltering } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({...})\n * export class MyComponent {\n * private filtering = injectGridFiltering();\n *\n * filterByStatus(status: string) {\n * this.filtering.setFilter('status', { operator: 'equals', value: status });\n * }\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport { ElementRef, inject, signal, type Signal } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { registerFeature } from '@toolbox-web/grid-angular';\nimport { FilteringPlugin, type FilterModel } from '@toolbox-web/grid/plugins/filtering';\n\nregisterFeature('filtering', (config) => {\n if (config === true) {\n return new FilteringPlugin();\n }\n return new FilteringPlugin(config ?? undefined);\n});\n\n/**\n * Filtering methods returned from injectGridFiltering.\n *\n * Uses lazy discovery - the grid is found on first method call, not during initialization.\n */\nexport interface FilteringMethods {\n /**\n * Set a filter on a specific field.\n * @param field - The field name to filter\n * @param filter - Filter configuration, or null to remove\n */\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null) => void;\n\n /**\n * Get the current filter for a field.\n */\n getFilter: (field: string) => FilterModel | undefined;\n\n /**\n * Get all active filters.\n */\n getFilters: () => FilterModel[];\n\n /**\n * Set all filters at once (replaces existing).\n */\n setFilterModel: (filters: FilterModel[]) => void;\n\n /**\n * Clear all active filters.\n */\n clearAllFilters: () => void;\n\n /**\n * Clear filter for a specific field.\n */\n clearFieldFilter: (field: string) => void;\n\n /**\n * Check if a field has an active filter.\n */\n isFieldFiltered: (field: string) => boolean;\n\n /**\n * Get the count of rows after filtering.\n */\n getFilteredRowCount: () => number;\n\n /**\n * Get unique values for a field (for building filter dropdowns).\n */\n getUniqueValues: (field: string) => unknown[];\n\n /**\n * Signal indicating if grid is ready.\n */\n isReady: Signal<boolean>;\n}\n\n/**\n * Angular inject function for programmatic filter control.\n *\n * Uses **lazy grid discovery** - the grid element is found when methods are called,\n * not during initialization.\n *\n * @example\n * ```typescript\n * import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import '@toolbox-web/grid-angular/features/filtering';\n * import { injectGridFiltering } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * selector: 'app-my-grid',\n * imports: [Grid],\n * schemas: [CUSTOM_ELEMENTS_SCHEMA],\n * template: `\n * <input (input)=\"applyFilter($event)\" placeholder=\"Filter by name...\" />\n * <span>{{ filtering.getFilteredRowCount() }} results</span>\n * <button (click)=\"filtering.clearAllFilters()\">Clear</button>\n * <tbw-grid [rows]=\"rows\" [filtering]=\"true\"></tbw-grid>\n * `\n * })\n * export class MyGridComponent {\n * filtering = injectGridFiltering();\n *\n * applyFilter(event: Event) {\n * const value = (event.target as HTMLInputElement).value;\n * this.filtering.setFilter('name', value ? { operator: 'contains', value } : null);\n * }\n * }\n * ```\n */\nexport function injectGridFiltering(): FilteringMethods {\n const elementRef = inject(ElementRef);\n const isReady = signal(false);\n\n let cachedGrid: DataGridElement | null = null;\n let readyPromiseStarted = false;\n\n const getGrid = (): DataGridElement | null => {\n if (cachedGrid) return cachedGrid;\n\n const grid = elementRef.nativeElement.querySelector('tbw-grid') as DataGridElement | null;\n if (grid) {\n cachedGrid = grid;\n if (!readyPromiseStarted) {\n readyPromiseStarted = true;\n grid.ready?.().then(() => isReady.set(true));\n }\n }\n return grid;\n };\n\n const getPlugin = (): FilteringPlugin | undefined => {\n return getGrid()?.getPlugin(FilteringPlugin);\n };\n\n return {\n isReady: isReady.asReadonly(),\n\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.setFilter(field, filter);\n },\n\n getFilter: (field: string) => getPlugin()?.getFilter(field),\n\n getFilters: () => getPlugin()?.getFilters() ?? [],\n\n setFilterModel: (filters: FilterModel[]) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.setFilterModel(filters);\n },\n\n clearAllFilters: () => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.clearAllFilters();\n },\n\n clearFieldFilter: (field: string) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.clearFieldFilter(field);\n },\n\n isFieldFiltered: (field: string) => getPlugin()?.isFieldFiltered(field) ?? false,\n\n getFilteredRowCount: () => getPlugin()?.getFilteredRowCount() ?? 0,\n\n getUniqueValues: (field: string) => getPlugin()?.getUniqueValues(field) ?? [],\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { inject, ElementRef, signal } from '@angular/core';
|
|
2
2
|
import { registerFeature } from '@toolbox-web/grid-angular';
|
|
3
|
+
import { PrintPlugin } from '@toolbox-web/grid/plugins/print';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Print feature for @toolbox-web/grid-angular
|
|
6
7
|
*
|
|
7
8
|
* Import this module to enable the `print` input on Grid directive.
|
|
9
|
+
* Also exports `injectGridPrint()` for programmatic print control.
|
|
8
10
|
*
|
|
9
11
|
* @example
|
|
10
12
|
* ```typescript
|
|
@@ -13,6 +15,20 @@ import { registerFeature } from '@toolbox-web/grid-angular';
|
|
|
13
15
|
* <tbw-grid [print]="true" />
|
|
14
16
|
* ```
|
|
15
17
|
*
|
|
18
|
+
* @example Using injectGridPrint
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { injectGridPrint } from '@toolbox-web/grid-angular/features/print';
|
|
21
|
+
*
|
|
22
|
+
* @Component({...})
|
|
23
|
+
* export class MyComponent {
|
|
24
|
+
* private gridPrint = injectGridPrint();
|
|
25
|
+
*
|
|
26
|
+
* printReport() {
|
|
27
|
+
* this.gridPrint.print({ title: 'My Report' });
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
16
32
|
* @packageDocumentation
|
|
17
33
|
*/
|
|
18
34
|
registerFeature('print', (config) => {
|
|
@@ -21,8 +37,80 @@ registerFeature('print', (config) => {
|
|
|
21
37
|
}
|
|
22
38
|
return new PrintPlugin(config ?? undefined);
|
|
23
39
|
});
|
|
40
|
+
/**
|
|
41
|
+
* Angular inject function for programmatic print control.
|
|
42
|
+
*
|
|
43
|
+
* Uses **lazy grid discovery** - the grid element is found when methods are called,
|
|
44
|
+
* not during initialization.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
49
|
+
* import { Grid } from '@toolbox-web/grid-angular';
|
|
50
|
+
* import '@toolbox-web/grid-angular/features/print';
|
|
51
|
+
* import { injectGridPrint } from '@toolbox-web/grid-angular/features/print';
|
|
52
|
+
*
|
|
53
|
+
* @Component({
|
|
54
|
+
* selector: 'app-my-grid',
|
|
55
|
+
* imports: [Grid],
|
|
56
|
+
* schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
57
|
+
* template: `
|
|
58
|
+
* <button (click)="handlePrint()" [disabled]="gridPrint.isPrinting()">
|
|
59
|
+
* {{ gridPrint.isPrinting() ? 'Printing...' : 'Print' }}
|
|
60
|
+
* </button>
|
|
61
|
+
* <tbw-grid [rows]="rows" [print]="true"></tbw-grid>
|
|
62
|
+
* `
|
|
63
|
+
* })
|
|
64
|
+
* export class MyGridComponent {
|
|
65
|
+
* gridPrint = injectGridPrint();
|
|
66
|
+
*
|
|
67
|
+
* async handlePrint() {
|
|
68
|
+
* await this.gridPrint.print({ title: 'Employee Report', isolate: true });
|
|
69
|
+
* console.log('Print dialog closed');
|
|
70
|
+
* }
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
function injectGridPrint() {
|
|
75
|
+
const elementRef = inject(ElementRef);
|
|
76
|
+
const isReady = signal(false, ...(ngDevMode ? [{ debugName: "isReady" }] : []));
|
|
77
|
+
let cachedGrid = null;
|
|
78
|
+
let readyPromiseStarted = false;
|
|
79
|
+
const getGrid = () => {
|
|
80
|
+
if (cachedGrid)
|
|
81
|
+
return cachedGrid;
|
|
82
|
+
const grid = elementRef.nativeElement.querySelector('tbw-grid');
|
|
83
|
+
if (grid) {
|
|
84
|
+
cachedGrid = grid;
|
|
85
|
+
if (!readyPromiseStarted) {
|
|
86
|
+
readyPromiseStarted = true;
|
|
87
|
+
grid.ready?.().then(() => isReady.set(true));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return grid;
|
|
91
|
+
};
|
|
92
|
+
const getPlugin = () => {
|
|
93
|
+
return getGrid()?.getPlugin(PrintPlugin);
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
isReady: isReady.asReadonly(),
|
|
97
|
+
print: async (params) => {
|
|
98
|
+
const plugin = getPlugin();
|
|
99
|
+
if (!plugin) {
|
|
100
|
+
console.warn(`[tbw-grid:print] PrintPlugin not found.\n\n` +
|
|
101
|
+
` → Enable print on the grid:\n` +
|
|
102
|
+
` <tbw-grid [print]="true" />`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
await plugin.print(params);
|
|
106
|
+
},
|
|
107
|
+
isPrinting: () => getPlugin()?.isPrinting() ?? false,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
24
110
|
|
|
25
111
|
/**
|
|
26
112
|
* Generated bundle index. Do not edit.
|
|
27
113
|
*/
|
|
114
|
+
|
|
115
|
+
export { injectGridPrint };
|
|
28
116
|
//# sourceMappingURL=toolbox-web-grid-angular-features-print.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbox-web-grid-angular-features-print.mjs","sources":["../../../../libs/grid-angular/features/print/src/index.ts","../../../../libs/grid-angular/features/print/src/toolbox-web-grid-angular-features-print.ts"],"sourcesContent":["/**\n * Print feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `print` input on Grid directive.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/print';\n *\n * <tbw-grid [print]=\"true\" />\n * ```\n *\n * @packageDocumentation\n */\n\nimport {
|
|
1
|
+
{"version":3,"file":"toolbox-web-grid-angular-features-print.mjs","sources":["../../../../libs/grid-angular/features/print/src/index.ts","../../../../libs/grid-angular/features/print/src/toolbox-web-grid-angular-features-print.ts"],"sourcesContent":["/**\n * Print feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `print` input on Grid directive.\n * Also exports `injectGridPrint()` for programmatic print control.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/print';\n *\n * <tbw-grid [print]=\"true\" />\n * ```\n *\n * @example Using injectGridPrint\n * ```typescript\n * import { injectGridPrint } from '@toolbox-web/grid-angular/features/print';\n *\n * @Component({...})\n * export class MyComponent {\n * private gridPrint = injectGridPrint();\n *\n * printReport() {\n * this.gridPrint.print({ title: 'My Report' });\n * }\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport { ElementRef, inject, signal, type Signal } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { registerFeature } from '@toolbox-web/grid-angular';\nimport { PrintPlugin, type PrintParams } from '@toolbox-web/grid/plugins/print';\n\nregisterFeature('print', (config) => {\n if (config === true) {\n return new PrintPlugin();\n }\n return new PrintPlugin(config ?? undefined);\n});\n\n/**\n * Print methods returned from injectGridPrint.\n *\n * Uses lazy discovery - the grid is found on first method call, not during initialization.\n */\nexport interface PrintMethods {\n /**\n * Print the grid.\n * Opens browser print dialog after preparing the grid for printing.\n * @param params - Optional print parameters\n */\n print: (params?: PrintParams) => Promise<void>;\n\n /**\n * Check if a print operation is currently in progress.\n */\n isPrinting: () => boolean;\n\n /**\n * Signal indicating if grid is ready.\n */\n isReady: Signal<boolean>;\n}\n\n/**\n * Angular inject function for programmatic print control.\n *\n * Uses **lazy grid discovery** - the grid element is found when methods are called,\n * not during initialization.\n *\n * @example\n * ```typescript\n * import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import '@toolbox-web/grid-angular/features/print';\n * import { injectGridPrint } from '@toolbox-web/grid-angular/features/print';\n *\n * @Component({\n * selector: 'app-my-grid',\n * imports: [Grid],\n * schemas: [CUSTOM_ELEMENTS_SCHEMA],\n * template: `\n * <button (click)=\"handlePrint()\" [disabled]=\"gridPrint.isPrinting()\">\n * {{ gridPrint.isPrinting() ? 'Printing...' : 'Print' }}\n * </button>\n * <tbw-grid [rows]=\"rows\" [print]=\"true\"></tbw-grid>\n * `\n * })\n * export class MyGridComponent {\n * gridPrint = injectGridPrint();\n *\n * async handlePrint() {\n * await this.gridPrint.print({ title: 'Employee Report', isolate: true });\n * console.log('Print dialog closed');\n * }\n * }\n * ```\n */\nexport function injectGridPrint(): PrintMethods {\n const elementRef = inject(ElementRef);\n const isReady = signal(false);\n\n let cachedGrid: DataGridElement | null = null;\n let readyPromiseStarted = false;\n\n const getGrid = (): DataGridElement | null => {\n if (cachedGrid) return cachedGrid;\n\n const grid = elementRef.nativeElement.querySelector('tbw-grid') as DataGridElement | null;\n if (grid) {\n cachedGrid = grid;\n if (!readyPromiseStarted) {\n readyPromiseStarted = true;\n grid.ready?.().then(() => isReady.set(true));\n }\n }\n return grid;\n };\n\n const getPlugin = (): PrintPlugin | undefined => {\n return getGrid()?.getPlugin(PrintPlugin);\n };\n\n return {\n isReady: isReady.asReadonly(),\n\n print: async (params?: PrintParams) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:print] PrintPlugin not found.\\n\\n` +\n ` → Enable print on the grid:\\n` +\n ` <tbw-grid [print]=\"true\" />`,\n );\n return;\n }\n await plugin.print(params);\n },\n\n isPrinting: () => getPlugin()?.isPrinting() ?? false,\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;AAOH,eAAe,CAAC,OAAO,EAAE,CAAC,MAAM,KAAI;AAClC,IAAA,IAAI,MAAM,KAAK,IAAI,EAAE;QACnB,OAAO,IAAI,WAAW,EAAE;IAC1B;AACA,IAAA,OAAO,IAAI,WAAW,CAAC,MAAM,IAAI,SAAS,CAAC;AAC7C,CAAC,CAAC;AA0BF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCG;SACa,eAAe,GAAA;AAC7B,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACrC,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,mDAAC;IAE7B,IAAI,UAAU,GAA2B,IAAI;IAC7C,IAAI,mBAAmB,GAAG,KAAK;IAE/B,MAAM,OAAO,GAAG,MAA6B;AAC3C,QAAA,IAAI,UAAU;AAAE,YAAA,OAAO,UAAU;QAEjC,MAAM,IAAI,GAAG,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,UAAU,CAA2B;QACzF,IAAI,IAAI,EAAE;YACR,UAAU,GAAG,IAAI;YACjB,IAAI,CAAC,mBAAmB,EAAE;gBACxB,mBAAmB,GAAG,IAAI;AAC1B,gBAAA,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9C;QACF;AACA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;IAED,MAAM,SAAS,GAAG,MAA8B;AAC9C,QAAA,OAAO,OAAO,EAAE,EAAE,SAAS,CAAC,WAAW,CAAC;AAC1C,IAAA,CAAC;IAED,OAAO;AACL,QAAA,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE;AAE7B,QAAA,KAAK,EAAE,OAAO,MAAoB,KAAI;AACpC,YAAA,MAAM,MAAM,GAAG,SAAS,EAAE;YAC1B,IAAI,CAAC,MAAM,EAAE;gBACX,OAAO,CAAC,IAAI,CACV,CAAA,2CAAA,CAA6C;oBAC3C,CAAA,+BAAA,CAAiC;AACjC,oBAAA,CAAA,+BAAA,CAAiC,CACpC;gBACD;YACF;AACA,YAAA,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5B,CAAC;QAED,UAAU,EAAE,MAAM,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,KAAK;KACrD;AACH;;AC/IA;;AAEG;;;;"}
|