@toolbox-web/grid-angular 1.3.1 → 1.4.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 +146 -54
- package/fesm2022/toolbox-web-grid-angular-features-clipboard.mjs +58 -0
- package/fesm2022/toolbox-web-grid-angular-features-clipboard.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-column-virtualization.mjs +37 -0
- package/fesm2022/toolbox-web-grid-angular-features-column-virtualization.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-context-menu.mjs +51 -0
- package/fesm2022/toolbox-web-grid-angular-features-context-menu.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-editing.mjs +115 -1
- package/fesm2022/toolbox-web-grid-angular-features-editing.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-export.mjs +55 -2
- package/fesm2022/toolbox-web-grid-angular-features-export.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs +159 -5
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-grouping-columns.mjs +83 -0
- package/fesm2022/toolbox-web-grid-angular-features-grouping-columns.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-grouping-rows.mjs +82 -0
- package/fesm2022/toolbox-web-grid-angular-features-grouping-rows.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs +109 -2
- package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-multi-sort.mjs +38 -0
- package/fesm2022/toolbox-web-grid-angular-features-multi-sort.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-pinned-columns.mjs +37 -0
- package/fesm2022/toolbox-web-grid-angular-features-pinned-columns.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs +103 -0
- package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-pivot.mjs +36 -0
- package/fesm2022/toolbox-web-grid-angular-features-pivot.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-print.mjs +58 -2
- package/fesm2022/toolbox-web-grid-angular-features-print.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-reorder-columns.mjs +52 -0
- package/fesm2022/toolbox-web-grid-angular-features-reorder-columns.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-reorder-rows.mjs +41 -0
- package/fesm2022/toolbox-web-grid-angular-features-reorder-rows.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs +105 -2
- package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-row-drag-drop.mjs +77 -0
- package/fesm2022/toolbox-web-grid-angular-features-row-drag-drop.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-selection.mjs +52 -2
- package/fesm2022/toolbox-web-grid-angular-features-selection.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-server-side.mjs +36 -0
- package/fesm2022/toolbox-web-grid-angular-features-server-side.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-tooltip.mjs +36 -0
- package/fesm2022/toolbox-web-grid-angular-features-tooltip.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-tree.mjs +53 -0
- package/fesm2022/toolbox-web-grid-angular-features-tree.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-undo-redo.mjs +57 -2
- package/fesm2022/toolbox-web-grid-angular-features-undo-redo.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-visibility.mjs +53 -0
- package/fesm2022/toolbox-web-grid-angular-features-visibility.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular.mjs +1225 -728
- package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/types/toolbox-web-grid-angular-features-clipboard.d.ts +23 -0
- package/types/toolbox-web-grid-angular-features-clipboard.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-column-virtualization.d.ts +19 -0
- package/types/toolbox-web-grid-angular-features-column-virtualization.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-context-menu.d.ts +22 -0
- package/types/toolbox-web-grid-angular-features-context-menu.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-editing.d.ts +32 -0
- package/types/toolbox-web-grid-angular-features-editing.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-export.d.ts +21 -3
- package/types/toolbox-web-grid-angular-features-export.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-filtering.d.ts +67 -6
- package/types/toolbox-web-grid-angular-features-filtering.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-grouping-columns.d.ts +19 -0
- package/types/toolbox-web-grid-angular-features-grouping-columns.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-grouping-rows.d.ts +25 -0
- package/types/toolbox-web-grid-angular-features-grouping-rows.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-master-detail.d.ts +23 -0
- package/types/toolbox-web-grid-angular-features-master-detail.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-multi-sort.d.ts +19 -0
- package/types/toolbox-web-grid-angular-features-multi-sort.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-pinned-columns.d.ts +18 -0
- package/types/toolbox-web-grid-angular-features-pinned-columns.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-pinned-rows.d.ts +19 -0
- package/types/toolbox-web-grid-angular-features-pinned-rows.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-pivot.d.ts +19 -0
- package/types/toolbox-web-grid-angular-features-pivot.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-print.d.ts +22 -3
- package/types/toolbox-web-grid-angular-features-print.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-reorder-columns.d.ts +22 -0
- package/types/toolbox-web-grid-angular-features-reorder-columns.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-reorder-rows.d.ts +19 -0
- package/types/toolbox-web-grid-angular-features-reorder-rows.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-responsive.d.ts +22 -0
- package/types/toolbox-web-grid-angular-features-responsive.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-row-drag-drop.d.ts +27 -0
- package/types/toolbox-web-grid-angular-features-row-drag-drop.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-selection.d.ts +21 -3
- package/types/toolbox-web-grid-angular-features-selection.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-server-side.d.ts +19 -0
- package/types/toolbox-web-grid-angular-features-server-side.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-tooltip.d.ts +19 -0
- package/types/toolbox-web-grid-angular-features-tooltip.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-tree.d.ts +22 -0
- package/types/toolbox-web-grid-angular-features-tree.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-undo-redo.d.ts +22 -3
- package/types/toolbox-web-grid-angular-features-undo-redo.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-visibility.d.ts +22 -0
- package/types/toolbox-web-grid-angular-features-visibility.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular.d.ts +858 -128
- package/types/toolbox-web-grid-angular.d.ts.map +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ElementRef, contentChild, TemplateRef, effect, Directive,
|
|
2
|
+
import { inject, ElementRef, contentChild, TemplateRef, effect, Directive, DestroyRef, input, InjectionToken, Injectable, makeEnvironmentProviders, createComponent, signal, afterNextRender, computed, output, EnvironmentInjector, ApplicationRef, ViewContainerRef } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { FormGroup } from '@angular/forms';
|
|
5
5
|
import { startWith, debounceTime } from 'rxjs/operators';
|
|
@@ -85,6 +85,13 @@ function getEditorTemplate(element) {
|
|
|
85
85
|
* ```
|
|
86
86
|
*
|
|
87
87
|
* @category Directive
|
|
88
|
+
*
|
|
89
|
+
* MOVE-IN-V2: this directive (and its companion `GridEditorContext` type and
|
|
90
|
+
* `getEditorTemplate` helper) will physically move into
|
|
91
|
+
* `@toolbox-web/grid-angular/features/editing` in v2.0.0; the deprecated
|
|
92
|
+
* re-exports from the main `@toolbox-web/grid-angular` entry will be removed
|
|
93
|
+
* at the same time. Consumers should already be importing from the feature
|
|
94
|
+
* entry.
|
|
88
95
|
*/
|
|
89
96
|
class GridColumnEditor {
|
|
90
97
|
elementRef = inject((ElementRef));
|
|
@@ -189,119 +196,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
189
196
|
args: [{ selector: 'tbw-grid-column-view' }]
|
|
190
197
|
}], propDecorators: { template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
191
198
|
|
|
192
|
-
// Global registry mapping DOM elements to their templates
|
|
193
|
-
const detailTemplateRegistry = new Map();
|
|
194
|
-
/**
|
|
195
|
-
* Gets the detail template registered for a given grid element.
|
|
196
|
-
* Used by AngularGridAdapter to retrieve templates at render time.
|
|
197
|
-
*/
|
|
198
|
-
function getDetailTemplate(gridElement) {
|
|
199
|
-
// Look for tbw-grid-detail child and get its template
|
|
200
|
-
const detailElement = gridElement.querySelector('tbw-grid-detail');
|
|
201
|
-
if (detailElement) {
|
|
202
|
-
return detailTemplateRegistry.get(detailElement);
|
|
203
|
-
}
|
|
204
|
-
return undefined;
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Gets the configuration for the detail view.
|
|
208
|
-
*/
|
|
209
|
-
function getDetailConfig(gridElement) {
|
|
210
|
-
const detailElement = gridElement.querySelector('tbw-grid-detail');
|
|
211
|
-
if (detailElement) {
|
|
212
|
-
const animationAttr = detailElement.getAttribute('animation');
|
|
213
|
-
let animation = 'slide';
|
|
214
|
-
if (animationAttr === 'false') {
|
|
215
|
-
animation = false;
|
|
216
|
-
}
|
|
217
|
-
else if (animationAttr === 'fade') {
|
|
218
|
-
animation = 'fade';
|
|
219
|
-
}
|
|
220
|
-
return {
|
|
221
|
-
showExpandColumn: detailElement.getAttribute('showExpandColumn') !== 'false',
|
|
222
|
-
animation,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
return undefined;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Directive that captures an `<ng-template>` for use as a master-detail row renderer.
|
|
229
|
-
*
|
|
230
|
-
* This enables declarative Angular component usage for expandable detail rows
|
|
231
|
-
* that appear below the main row when expanded.
|
|
232
|
-
*
|
|
233
|
-
* ## Usage
|
|
234
|
-
*
|
|
235
|
-
* ```html
|
|
236
|
-
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
237
|
-
* <tbw-grid-detail [showExpandColumn]="true" animation="slide">
|
|
238
|
-
* <ng-template let-row>
|
|
239
|
-
* <app-detail-panel [employee]="row" />
|
|
240
|
-
* </ng-template>
|
|
241
|
-
* </tbw-grid-detail>
|
|
242
|
-
* </tbw-grid>
|
|
243
|
-
* ```
|
|
244
|
-
*
|
|
245
|
-
* The template context provides:
|
|
246
|
-
* - `$implicit` / `row`: The full row data object
|
|
247
|
-
*
|
|
248
|
-
* Import the directive in your component:
|
|
249
|
-
*
|
|
250
|
-
* ```typescript
|
|
251
|
-
* import { GridDetailView } from '@toolbox-web/grid-angular';
|
|
252
|
-
*
|
|
253
|
-
* @Component({
|
|
254
|
-
* imports: [GridDetailView],
|
|
255
|
-
* // ...
|
|
256
|
-
* })
|
|
257
|
-
* ```
|
|
258
|
-
*
|
|
259
|
-
* @example
|
|
260
|
-
* ```html
|
|
261
|
-
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
262
|
-
* <tbw-grid-detail [showExpandColumn]="true" animation="slide">
|
|
263
|
-
* <ng-template let-row>
|
|
264
|
-
* <app-detail-panel [employee]="row" />
|
|
265
|
-
* </ng-template>
|
|
266
|
-
* </tbw-grid-detail>
|
|
267
|
-
* </tbw-grid>
|
|
268
|
-
* ```
|
|
269
|
-
*
|
|
270
|
-
* @category Directive
|
|
271
|
-
*/
|
|
272
|
-
class GridDetailView {
|
|
273
|
-
elementRef = inject((ElementRef));
|
|
274
|
-
/** Whether to show the expand/collapse column. Default: true */
|
|
275
|
-
showExpandColumn = input(true, ...(ngDevMode ? [{ debugName: "showExpandColumn" }] : /* istanbul ignore next */ []));
|
|
276
|
-
/** Animation style for expand/collapse. Default: 'slide' */
|
|
277
|
-
animation = input('slide', ...(ngDevMode ? [{ debugName: "animation" }] : /* istanbul ignore next */ []));
|
|
278
|
-
/**
|
|
279
|
-
* Query for the ng-template content child.
|
|
280
|
-
*/
|
|
281
|
-
template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
282
|
-
/** Effect that triggers when the template is available */
|
|
283
|
-
onTemplateReceived = effect(() => {
|
|
284
|
-
const template = this.template();
|
|
285
|
-
if (template) {
|
|
286
|
-
// Register the template for this element
|
|
287
|
-
detailTemplateRegistry.set(this.elementRef.nativeElement, template);
|
|
288
|
-
}
|
|
289
|
-
}, ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
|
|
290
|
-
/**
|
|
291
|
-
* Static type guard for template context.
|
|
292
|
-
* Enables type inference in templates.
|
|
293
|
-
*/
|
|
294
|
-
static ngTemplateContextGuard(dir, ctx) {
|
|
295
|
-
return true;
|
|
296
|
-
}
|
|
297
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridDetailView, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
298
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridDetailView, isStandalone: true, selector: "tbw-grid-detail", inputs: { showExpandColumn: { classPropertyName: "showExpandColumn", publicName: "showExpandColumn", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
|
|
299
|
-
}
|
|
300
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridDetailView, decorators: [{
|
|
301
|
-
type: Directive,
|
|
302
|
-
args: [{ selector: 'tbw-grid-detail' }]
|
|
303
|
-
}], propDecorators: { showExpandColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExpandColumn", required: false }] }], animation: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
304
|
-
|
|
305
199
|
// Symbol for storing form context on the grid element
|
|
306
200
|
const FORM_ARRAY_CONTEXT$1 = Symbol('formArrayContext');
|
|
307
201
|
/**
|
|
@@ -370,6 +264,13 @@ function getFormArrayContext(gridElement) {
|
|
|
370
264
|
* ```
|
|
371
265
|
*
|
|
372
266
|
* @category Directive
|
|
267
|
+
*
|
|
268
|
+
* MOVE-IN-V2: this directive (and its `FormArrayContext` type and
|
|
269
|
+
* `getFormArrayContext` helper) will physically move into
|
|
270
|
+
* `@toolbox-web/grid-angular/features/editing` in v2.0.0; the deprecated
|
|
271
|
+
* re-exports from the main `@toolbox-web/grid-angular` entry will be removed
|
|
272
|
+
* at the same time. Consumers should already be importing from the feature
|
|
273
|
+
* entry.
|
|
373
274
|
*/
|
|
374
275
|
class GridFormArray {
|
|
375
276
|
destroyRef = inject(DestroyRef);
|
|
@@ -785,88 +686,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
785
686
|
}]
|
|
786
687
|
}], propDecorators: { formArray: [{ type: i0.Input, args: [{ isSignal: true, alias: "formArray", required: true }] }], syncValidation: [{ type: i0.Input, args: [{ isSignal: true, alias: "syncValidation", required: false }] }] } });
|
|
787
688
|
|
|
788
|
-
/**
|
|
789
|
-
* Registry to store responsive card templates by grid element.
|
|
790
|
-
* Used by AngularGridAdapter to create card renderers.
|
|
791
|
-
*/
|
|
792
|
-
const responsiveCardTemplateRegistry = new Map();
|
|
793
|
-
/**
|
|
794
|
-
* Retrieves the responsive card template for a grid element.
|
|
795
|
-
*
|
|
796
|
-
* @param gridElement - The grid element to look up
|
|
797
|
-
* @returns The template reference or undefined if not found
|
|
798
|
-
*/
|
|
799
|
-
function getResponsiveCardTemplate(gridElement) {
|
|
800
|
-
// Find the tbw-grid-responsive-card element inside the grid
|
|
801
|
-
const cardElement = gridElement.querySelector('tbw-grid-responsive-card');
|
|
802
|
-
if (!cardElement)
|
|
803
|
-
return undefined;
|
|
804
|
-
return responsiveCardTemplateRegistry.get(cardElement);
|
|
805
|
-
}
|
|
806
|
-
/**
|
|
807
|
-
* Directive for providing custom Angular templates for responsive card layout.
|
|
808
|
-
*
|
|
809
|
-
* Use this directive to define how each row should render when the grid
|
|
810
|
-
* is in responsive/mobile mode. The template receives the row data and index.
|
|
811
|
-
*
|
|
812
|
-
* ## Usage
|
|
813
|
-
*
|
|
814
|
-
* ```html
|
|
815
|
-
* <tbw-grid [rows]="employees">
|
|
816
|
-
* <tbw-grid-responsive-card>
|
|
817
|
-
* <ng-template let-employee let-idx="index">
|
|
818
|
-
* <div class="employee-card">
|
|
819
|
-
* <img [src]="employee.avatar" alt="">
|
|
820
|
-
* <div class="info">
|
|
821
|
-
* <strong>{{ employee.name }}</strong>
|
|
822
|
-
* <span>{{ employee.department }}</span>
|
|
823
|
-
* </div>
|
|
824
|
-
* </div>
|
|
825
|
-
* </ng-template>
|
|
826
|
-
* </tbw-grid-responsive-card>
|
|
827
|
-
* </tbw-grid>
|
|
828
|
-
* ```
|
|
829
|
-
*
|
|
830
|
-
* ## Important Notes
|
|
831
|
-
*
|
|
832
|
-
* - The ResponsivePlugin must be added to your grid config
|
|
833
|
-
* - The Grid directive will automatically configure the plugin's cardRenderer
|
|
834
|
-
* - Template context provides `$implicit` (row), `row`, and `index`
|
|
835
|
-
*
|
|
836
|
-
* @see ResponsivePlugin
|
|
837
|
-
* @category Directive
|
|
838
|
-
*/
|
|
839
|
-
class GridResponsiveCard {
|
|
840
|
-
elementRef = inject((ElementRef));
|
|
841
|
-
/**
|
|
842
|
-
* The ng-template containing the card content.
|
|
843
|
-
*/
|
|
844
|
-
template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
845
|
-
/**
|
|
846
|
-
* Effect that registers the template when it becomes available.
|
|
847
|
-
*/
|
|
848
|
-
onTemplateReceived = effect(() => {
|
|
849
|
-
const template = this.template();
|
|
850
|
-
if (template) {
|
|
851
|
-
responsiveCardTemplateRegistry.set(this.elementRef.nativeElement, template);
|
|
852
|
-
}
|
|
853
|
-
}, ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
|
|
854
|
-
/**
|
|
855
|
-
* Type guard for template context inference.
|
|
856
|
-
*/
|
|
857
|
-
static ngTemplateContextGuard(_directive, context) {
|
|
858
|
-
return true;
|
|
859
|
-
}
|
|
860
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridResponsiveCard, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
861
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridResponsiveCard, isStandalone: true, selector: "tbw-grid-responsive-card", queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
|
|
862
|
-
}
|
|
863
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridResponsiveCard, decorators: [{
|
|
864
|
-
type: Directive,
|
|
865
|
-
args: [{
|
|
866
|
-
selector: 'tbw-grid-responsive-card',
|
|
867
|
-
}]
|
|
868
|
-
}], propDecorators: { template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
869
|
-
|
|
870
689
|
// Global registry mapping DOM elements to their templates
|
|
871
690
|
const toolPanelTemplateRegistry = new Map();
|
|
872
691
|
/**
|
|
@@ -1173,6 +992,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
1173
992
|
* ```
|
|
1174
993
|
*
|
|
1175
994
|
* @category Directive
|
|
995
|
+
*
|
|
996
|
+
* MOVE-IN-V2: this directive (and its `StructuralEditorContext` type) will
|
|
997
|
+
* physically move into `@toolbox-web/grid-angular/features/editing` in v2.0.0;
|
|
998
|
+
* the deprecated re-export from the main `@toolbox-web/grid-angular` entry
|
|
999
|
+
* will be removed at the same time. Consumers should already be importing
|
|
1000
|
+
* from the feature entry. (`TbwRenderer` stays in the main entry — it is
|
|
1001
|
+
* editor-agnostic.)
|
|
1176
1002
|
*/
|
|
1177
1003
|
class TbwEditor {
|
|
1178
1004
|
template = inject((TemplateRef));
|
|
@@ -1214,6 +1040,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
1214
1040
|
args: [{ selector: '[tbwEditor]' }]
|
|
1215
1041
|
}], ctorParameters: () => [] });
|
|
1216
1042
|
|
|
1043
|
+
/**
|
|
1044
|
+
* Editor mount hook registry — append-only hooks called when an Angular-managed
|
|
1045
|
+
* editor host is mounted into the DOM with a known owner grid.
|
|
1046
|
+
*
|
|
1047
|
+
* This is the augmentation point that lets feature secondary entries
|
|
1048
|
+
* (e.g. `@toolbox-web/grid-angular/features/editing`) install per-editor
|
|
1049
|
+
* lifecycle behaviour (such as the `before-edit-close` blur bridge)
|
|
1050
|
+
* without coupling the central adapter file to the editing feature.
|
|
1051
|
+
* Mirrors React's and Vue's `editor-mount-hooks` and how core grid plugins
|
|
1052
|
+
* augment the grid via `registerPlugin()`.
|
|
1053
|
+
*
|
|
1054
|
+
* @packageDocumentation
|
|
1055
|
+
* @internal
|
|
1056
|
+
*/
|
|
1057
|
+
const editorMountHooks = [];
|
|
1058
|
+
/**
|
|
1059
|
+
* Install an editor-mount hook. Called by feature secondary entries
|
|
1060
|
+
* (e.g. `features/editing`) on import.
|
|
1061
|
+
*
|
|
1062
|
+
* @internal Plugin API
|
|
1063
|
+
*/
|
|
1064
|
+
function registerEditorMountHook(hook) {
|
|
1065
|
+
editorMountHooks.push(hook);
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Run all registered editor-mount hooks for a freshly mounted editor.
|
|
1069
|
+
* Returns a combined teardown that invokes each hook's teardown in
|
|
1070
|
+
* registration order.
|
|
1071
|
+
*
|
|
1072
|
+
* @internal Adapter use only.
|
|
1073
|
+
*/
|
|
1074
|
+
function notifyEditorMounted(container, gridEl) {
|
|
1075
|
+
const teardowns = [];
|
|
1076
|
+
for (const hook of editorMountHooks) {
|
|
1077
|
+
const teardown = hook({ container, gridEl });
|
|
1078
|
+
if (teardown)
|
|
1079
|
+
teardowns.push(teardown);
|
|
1080
|
+
}
|
|
1081
|
+
return () => {
|
|
1082
|
+
for (const teardown of teardowns)
|
|
1083
|
+
teardown();
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Returns a function that, when invoked, blurs the focused input/textarea/select
|
|
1088
|
+
* inside `host` (if any). Used by the `before-edit-close` bridge installed by
|
|
1089
|
+
* `@toolbox-web/grid-angular/features/editing` so editors that commit on
|
|
1090
|
+
* `(blur)` flush their pending value before the cell DOM is torn down by Tab /
|
|
1091
|
+
* programmatic row exit.
|
|
1092
|
+
* @internal
|
|
1093
|
+
*/
|
|
1094
|
+
function makeFlushFocusedInput(host) {
|
|
1095
|
+
return () => {
|
|
1096
|
+
const focused = host.ownerDocument.activeElement;
|
|
1097
|
+
if (focused &&
|
|
1098
|
+
host.contains(focused) &&
|
|
1099
|
+
(focused instanceof HTMLInputElement ||
|
|
1100
|
+
focused instanceof HTMLTextAreaElement ||
|
|
1101
|
+
focused instanceof HTMLSelectElement)) {
|
|
1102
|
+
focused.blur();
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1217
1107
|
/**
|
|
1218
1108
|
* Editor Wiring Helpers
|
|
1219
1109
|
*
|
|
@@ -1435,6 +1325,149 @@ function provideGridTypeDefaults(defaults) {
|
|
|
1435
1325
|
return makeEnvironmentProviders([{ provide: GRID_TYPE_DEFAULTS, useValue: defaults }]);
|
|
1436
1326
|
}
|
|
1437
1327
|
|
|
1328
|
+
/**
|
|
1329
|
+
* Append-only bridge registries used by `@toolbox-web/grid-angular`.
|
|
1330
|
+
*
|
|
1331
|
+
* These let feature secondary entries plug into the central `GridAdapter`
|
|
1332
|
+
* without the adapter needing to know about them. Mirrors React's and Vue's
|
|
1333
|
+
* `register*Bridge` modules and how core grid plugins augment the grid via
|
|
1334
|
+
* `registerPlugin()`.
|
|
1335
|
+
*
|
|
1336
|
+
* This module is deliberately framework-free: it holds plain module-level
|
|
1337
|
+
* `let` state and never imports from `@angular/core` or from
|
|
1338
|
+
* `@toolbox-web/grid/plugins/...`. Feature subpaths import the setters via
|
|
1339
|
+
* the `@toolbox-web/grid-angular` package barrel (relative imports outside
|
|
1340
|
+
* a secondary entry's `rootDir` are forbidden by ng-packagr).
|
|
1341
|
+
*
|
|
1342
|
+
* @internal
|
|
1343
|
+
*/
|
|
1344
|
+
let detailRendererBridge = null;
|
|
1345
|
+
let responsiveCardRendererBridge = null;
|
|
1346
|
+
let filterPanelTypeDefaultBridge = null;
|
|
1347
|
+
/**
|
|
1348
|
+
* Install the master-detail row-renderer bridge. Called once on import by
|
|
1349
|
+
* `@toolbox-web/grid-angular/features/master-detail`.
|
|
1350
|
+
* @internal Plugin API
|
|
1351
|
+
*/
|
|
1352
|
+
function registerDetailRendererBridge(bridge) {
|
|
1353
|
+
detailRendererBridge = bridge;
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* Install the responsive-card row-renderer bridge. Called once on import by
|
|
1357
|
+
* `@toolbox-web/grid-angular/features/responsive`.
|
|
1358
|
+
* @internal Plugin API
|
|
1359
|
+
*/
|
|
1360
|
+
function registerResponsiveCardRendererBridge(bridge) {
|
|
1361
|
+
responsiveCardRendererBridge = bridge;
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Install the type-default `filterPanelRenderer` wrapper. Called once on import
|
|
1365
|
+
* by `@toolbox-web/grid-angular/features/filtering`. Without this bridge,
|
|
1366
|
+
* type-default and grid-config-level component-class filterPanelRenderers are
|
|
1367
|
+
* silently dropped — same precondition as the FilteringPlugin (TBW031).
|
|
1368
|
+
* @internal Plugin API
|
|
1369
|
+
*/
|
|
1370
|
+
function registerFilterPanelTypeDefaultBridge(bridge) {
|
|
1371
|
+
filterPanelTypeDefaultBridge = bridge;
|
|
1372
|
+
}
|
|
1373
|
+
/** @internal Adapter use only. */
|
|
1374
|
+
function getDetailRendererBridge() {
|
|
1375
|
+
return detailRendererBridge;
|
|
1376
|
+
}
|
|
1377
|
+
/** @internal Adapter use only. */
|
|
1378
|
+
function getResponsiveCardRendererBridge() {
|
|
1379
|
+
return responsiveCardRendererBridge;
|
|
1380
|
+
}
|
|
1381
|
+
/** @internal Adapter use only. */
|
|
1382
|
+
function getFilterPanelTypeDefaultBridge() {
|
|
1383
|
+
return filterPanelTypeDefaultBridge;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
/**
|
|
1387
|
+
* Internal registries used by `@toolbox-web/grid-angular`.
|
|
1388
|
+
*
|
|
1389
|
+
* Two extension points are exposed so individual feature secondary entries
|
|
1390
|
+
* (e.g. `@toolbox-web/grid-angular/features/master-detail`) can plug into
|
|
1391
|
+
* the core `Grid` directive without the directive needing to know about them.
|
|
1392
|
+
*
|
|
1393
|
+
* - {@link registerTemplateBridge} — runs in `ngAfterContentInit` once Angular
|
|
1394
|
+
* templates inside the grid have been registered. Used to discover light-DOM
|
|
1395
|
+
* slot elements (`<tbw-grid-detail>`, `<tbw-grid-responsive-card>`, …) and
|
|
1396
|
+
* wire them to the corresponding plugin's renderer setter.
|
|
1397
|
+
* - {@link registerFeatureConfigPreprocessor} — runs inside the directive's
|
|
1398
|
+
* feature-plugin builder before `createPluginFromFeature` is called. Lets a
|
|
1399
|
+
* feature transform its config object (e.g. to convert Angular component
|
|
1400
|
+
* classes embedded in `customPanels` to renderer functions).
|
|
1401
|
+
*
|
|
1402
|
+
* Both registries are append-only and module-scoped: they are populated by
|
|
1403
|
+
* side-effect imports of feature secondary entries and consumed by the core
|
|
1404
|
+
* `Grid` directive. Order is insertion order.
|
|
1405
|
+
*
|
|
1406
|
+
* @internal — public for cross-entry-point use; not part of the supported API.
|
|
1407
|
+
*/
|
|
1408
|
+
const templateBridges = [];
|
|
1409
|
+
/**
|
|
1410
|
+
* Register a template bridge. Called by feature secondary entries at module
|
|
1411
|
+
* load (e.g. `import '@toolbox-web/grid-angular/features/master-detail'`).
|
|
1412
|
+
*
|
|
1413
|
+
* Bridges are append-only and never deduplicated; calling registration twice
|
|
1414
|
+
* for the same feature module is safe because module imports are deduplicated
|
|
1415
|
+
* by the JS loader.
|
|
1416
|
+
*
|
|
1417
|
+
* @internal
|
|
1418
|
+
*/
|
|
1419
|
+
function registerTemplateBridge(bridge) {
|
|
1420
|
+
templateBridges.push(bridge);
|
|
1421
|
+
}
|
|
1422
|
+
/**
|
|
1423
|
+
* Run all registered template bridges for a grid. The directive calls this
|
|
1424
|
+
* from `ngAfterContentInit` after `refreshColumns()`. Bridges run concurrently;
|
|
1425
|
+
* errors thrown by one bridge do not stop the others.
|
|
1426
|
+
*
|
|
1427
|
+
* @internal
|
|
1428
|
+
*/
|
|
1429
|
+
function runTemplateBridges(ctx) {
|
|
1430
|
+
for (const bridge of templateBridges) {
|
|
1431
|
+
try {
|
|
1432
|
+
const result = bridge(ctx);
|
|
1433
|
+
if (result && typeof result.catch === 'function') {
|
|
1434
|
+
result.catch((err) => {
|
|
1435
|
+
// eslint-disable-next-line no-console
|
|
1436
|
+
console.error('[tbw-grid-angular] template bridge threw:', err);
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
catch (err) {
|
|
1441
|
+
// eslint-disable-next-line no-console
|
|
1442
|
+
console.error('[tbw-grid-angular] template bridge threw:', err);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
const featureConfigPreprocessors = new Map();
|
|
1447
|
+
/**
|
|
1448
|
+
* Register a feature config preprocessor. Last registration wins (subsequent
|
|
1449
|
+
* imports of the same feature module re-register the same function, which is
|
|
1450
|
+
* a no-op).
|
|
1451
|
+
*
|
|
1452
|
+
* @internal
|
|
1453
|
+
*/
|
|
1454
|
+
function registerFeatureConfigPreprocessor(name, fn) {
|
|
1455
|
+
featureConfigPreprocessors.set(name, fn);
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* Look up the preprocessor for a feature, if any.
|
|
1459
|
+
*
|
|
1460
|
+
* @internal
|
|
1461
|
+
*/
|
|
1462
|
+
function getFeatureConfigPreprocessor(name) {
|
|
1463
|
+
return featureConfigPreprocessors.get(name);
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
// #region Feature bridge registries
|
|
1467
|
+
// (Storage lives in `./internal/feature-bridges` so feature subpaths can
|
|
1468
|
+
// install bridges without pulling Angular runtime into specs that mock
|
|
1469
|
+
// `@angular/core` — see filtering feature spec.)
|
|
1470
|
+
// #endregion
|
|
1438
1471
|
/**
|
|
1439
1472
|
* Helper to get view template from either structural directive or nested directive.
|
|
1440
1473
|
*/
|
|
@@ -1555,20 +1588,16 @@ class GridAdapter {
|
|
|
1555
1588
|
/** Editor-specific component refs tracked separately for per-cell cleanup via releaseCell. */
|
|
1556
1589
|
editorComponentRefs = [];
|
|
1557
1590
|
/**
|
|
1558
|
-
* Per-editor
|
|
1559
|
-
* editor host element.
|
|
1560
|
-
*
|
|
1561
|
-
* The grid's editing plugin emits `before-edit-close` on the host
|
|
1562
|
-
* `<tbw-grid>` before tearing down a row's managed editors. Angular
|
|
1563
|
-
* editors that commit on `(blur)` rely on the focused input firing `blur`
|
|
1564
|
-
* naturally, but Tab / programmatic row exit rebuilds the cell DOM
|
|
1565
|
-
* synchronously without giving the focused input a chance to blur first
|
|
1566
|
-
* — pending input is silently discarded.
|
|
1591
|
+
* Per-editor mount-hook teardown functions, keyed by editor host element.
|
|
1567
1592
|
*
|
|
1568
|
-
*
|
|
1569
|
-
*
|
|
1593
|
+
* Populated by {@link runEditorMountHooks} (which invokes
|
|
1594
|
+
* {@link notifyEditorMounted}) and torn down per-cell from
|
|
1595
|
+
* {@link releaseCell}, with full sweep on {@link destroy}. The actual
|
|
1596
|
+
* lifecycle behaviour is supplied by feature secondary entries (e.g.
|
|
1597
|
+
* `@toolbox-web/grid-angular/features/editing` installs the
|
|
1598
|
+
* `before-edit-close` blur bridge).
|
|
1570
1599
|
*/
|
|
1571
|
-
|
|
1600
|
+
editorMountTeardowns = new Map();
|
|
1572
1601
|
typeRegistry = null;
|
|
1573
1602
|
constructor(injector, appRef, viewContainerRef) {
|
|
1574
1603
|
this.injector = injector;
|
|
@@ -1656,9 +1685,13 @@ class GridAdapter {
|
|
|
1656
1685
|
if (config.editor && isComponentClass(config.editor)) {
|
|
1657
1686
|
processedConfig.editor = this.createComponentEditor(config.editor);
|
|
1658
1687
|
}
|
|
1659
|
-
// Convert filterPanelRenderer component class to function
|
|
1688
|
+
// Convert filterPanelRenderer component class to function via the
|
|
1689
|
+
// filtering feature bridge. Without `@toolbox-web/grid-angular/features/filtering`
|
|
1690
|
+
// imported, component-class filterPanelRenderers are dropped silently.
|
|
1660
1691
|
if (config.filterPanelRenderer && isComponentClass(config.filterPanelRenderer)) {
|
|
1661
|
-
|
|
1692
|
+
const wrapped = getFilterPanelTypeDefaultBridge()?.(config.filterPanelRenderer, this);
|
|
1693
|
+
if (wrapped)
|
|
1694
|
+
processedConfig.filterPanelRenderer = wrapped;
|
|
1662
1695
|
}
|
|
1663
1696
|
processed[type] = processedConfig;
|
|
1664
1697
|
}
|
|
@@ -1843,7 +1876,7 @@ class GridAdapter {
|
|
|
1843
1876
|
const container = document.createElement('span');
|
|
1844
1877
|
container.style.display = 'contents';
|
|
1845
1878
|
syncRootNodes(viewRef, container);
|
|
1846
|
-
this.
|
|
1879
|
+
this.runEditorMountHooks(container);
|
|
1847
1880
|
// Auto-wire: Listen for commit/cancel events on the rendered component.
|
|
1848
1881
|
// This allows components to just emit (commit) and (cancel) without
|
|
1849
1882
|
// requiring explicit template bindings like (commit)="onCommit($event)".
|
|
@@ -1869,101 +1902,40 @@ class GridAdapter {
|
|
|
1869
1902
|
};
|
|
1870
1903
|
}
|
|
1871
1904
|
/**
|
|
1872
|
-
* Creates a detail renderer function for MasterDetailPlugin.
|
|
1873
|
-
*
|
|
1905
|
+
* Creates a detail renderer function for MasterDetailPlugin. Delegates to
|
|
1906
|
+
* the bridge installed by `@toolbox-web/grid-angular/features/master-detail`.
|
|
1907
|
+
* Returns undefined if the feature is not imported or no `<tbw-grid-detail>`
|
|
1908
|
+
* template is registered for this grid.
|
|
1874
1909
|
*/
|
|
1875
1910
|
createDetailRenderer(gridElement) {
|
|
1876
|
-
|
|
1877
|
-
if (!template) {
|
|
1878
|
-
return undefined;
|
|
1879
|
-
}
|
|
1880
|
-
return (row) => {
|
|
1881
|
-
// Create the context for the template
|
|
1882
|
-
const context = {
|
|
1883
|
-
$implicit: row,
|
|
1884
|
-
row: row,
|
|
1885
|
-
};
|
|
1886
|
-
// Create embedded view from template
|
|
1887
|
-
const viewRef = this.viewContainerRef.createEmbeddedView(template, context);
|
|
1888
|
-
this.viewRefs.push(viewRef);
|
|
1889
|
-
// Trigger change detection
|
|
1890
|
-
viewRef.detectChanges();
|
|
1891
|
-
// Create a container for the root nodes
|
|
1892
|
-
const container = document.createElement('div');
|
|
1893
|
-
viewRef.rootNodes.forEach((node) => container.appendChild(node));
|
|
1894
|
-
return container;
|
|
1895
|
-
};
|
|
1911
|
+
return getDetailRendererBridge()?.(gridElement, this);
|
|
1896
1912
|
}
|
|
1897
1913
|
/**
|
|
1898
|
-
*
|
|
1899
|
-
*
|
|
1900
|
-
*
|
|
1901
|
-
* This enables MasterDetailPlugin to automatically use Angular templates
|
|
1902
|
-
* without manual configuration in the Grid directive.
|
|
1914
|
+
* FrameworkAdapter hook called by MasterDetailPlugin during attach(). Delegates
|
|
1915
|
+
* to {@link createDetailRenderer} (bridge installed by master-detail feature).
|
|
1903
1916
|
*/
|
|
1904
1917
|
parseDetailElement(detailElement) {
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
if (!template) {
|
|
1918
|
+
const gridElement = detailElement.closest('tbw-grid');
|
|
1919
|
+
if (!gridElement)
|
|
1908
1920
|
return undefined;
|
|
1909
|
-
|
|
1910
|
-
// Return a renderer function that creates embedded views
|
|
1911
|
-
// Note: rowIndex is part of the MasterDetailPlugin detailRenderer signature but not needed here
|
|
1912
|
-
return (row) => {
|
|
1913
|
-
const context = {
|
|
1914
|
-
$implicit: row,
|
|
1915
|
-
row: row,
|
|
1916
|
-
};
|
|
1917
|
-
const viewRef = this.viewContainerRef.createEmbeddedView(template, context);
|
|
1918
|
-
this.viewRefs.push(viewRef);
|
|
1919
|
-
viewRef.detectChanges();
|
|
1920
|
-
const container = document.createElement('div');
|
|
1921
|
-
viewRef.rootNodes.forEach((node) => container.appendChild(node));
|
|
1922
|
-
return container;
|
|
1923
|
-
};
|
|
1921
|
+
return getDetailRendererBridge()?.(gridElement, this);
|
|
1924
1922
|
}
|
|
1925
1923
|
/**
|
|
1926
|
-
* Creates a responsive card renderer function for ResponsivePlugin.
|
|
1927
|
-
*
|
|
1928
|
-
*
|
|
1929
|
-
* @param gridElement - The grid element to look up the template for
|
|
1930
|
-
* @returns A card renderer function or undefined if no template is found
|
|
1924
|
+
* Creates a responsive card renderer function for ResponsivePlugin. Delegates
|
|
1925
|
+
* to the bridge installed by `@toolbox-web/grid-angular/features/responsive`.
|
|
1931
1926
|
*/
|
|
1932
1927
|
createResponsiveCardRenderer(gridElement) {
|
|
1933
|
-
|
|
1934
|
-
if (!template) {
|
|
1935
|
-
return undefined;
|
|
1936
|
-
}
|
|
1937
|
-
return (row, rowIndex) => {
|
|
1938
|
-
// Create the context for the template
|
|
1939
|
-
const context = {
|
|
1940
|
-
$implicit: row,
|
|
1941
|
-
row: row,
|
|
1942
|
-
index: rowIndex,
|
|
1943
|
-
};
|
|
1944
|
-
// Create embedded view from template
|
|
1945
|
-
const viewRef = this.viewContainerRef.createEmbeddedView(template, context);
|
|
1946
|
-
this.viewRefs.push(viewRef);
|
|
1947
|
-
// Trigger change detection
|
|
1948
|
-
viewRef.detectChanges();
|
|
1949
|
-
// Create a container for the root nodes
|
|
1950
|
-
const container = document.createElement('div');
|
|
1951
|
-
viewRef.rootNodes.forEach((node) => container.appendChild(node));
|
|
1952
|
-
return container;
|
|
1953
|
-
};
|
|
1928
|
+
return getResponsiveCardRendererBridge()?.(gridElement, this);
|
|
1954
1929
|
}
|
|
1955
1930
|
/**
|
|
1956
|
-
* FrameworkAdapter hook called by ResponsivePlugin during attach().
|
|
1957
|
-
*
|
|
1958
|
-
* {@link createResponsiveCardRenderer}. Required for parity with the Vue
|
|
1959
|
-
* adapter so ResponsivePlugin's standard lookup path works for Angular
|
|
1960
|
-
* users without relying on imperative `refreshCardRenderer` calls.
|
|
1931
|
+
* FrameworkAdapter hook called by ResponsivePlugin during attach(). Delegates
|
|
1932
|
+
* to {@link createResponsiveCardRenderer} (bridge installed by responsive feature).
|
|
1961
1933
|
*/
|
|
1962
1934
|
parseResponsiveCardElement(cardElement) {
|
|
1963
1935
|
const gridElement = cardElement.closest('tbw-grid');
|
|
1964
1936
|
if (!gridElement)
|
|
1965
1937
|
return undefined;
|
|
1966
|
-
return
|
|
1938
|
+
return getResponsiveCardRendererBridge()?.(gridElement, this);
|
|
1967
1939
|
}
|
|
1968
1940
|
/**
|
|
1969
1941
|
* Creates a tool panel renderer from a light DOM element.
|
|
@@ -2047,8 +2019,11 @@ class GridAdapter {
|
|
|
2047
2019
|
typeDefault.editor = this.createComponentEditor(config.editor);
|
|
2048
2020
|
}
|
|
2049
2021
|
// Create filterPanelRenderer function that instantiates the Angular component
|
|
2022
|
+
// via the filtering feature bridge. Drop silently if the feature is not imported.
|
|
2050
2023
|
if (config.filterPanelRenderer && isComponentClass(config.filterPanelRenderer)) {
|
|
2051
|
-
|
|
2024
|
+
const wrapped = getFilterPanelTypeDefaultBridge()?.(config.filterPanelRenderer, this);
|
|
2025
|
+
if (wrapped)
|
|
2026
|
+
typeDefault.filterPanelRenderer = wrapped;
|
|
2052
2027
|
}
|
|
2053
2028
|
else if (config.filterPanelRenderer) {
|
|
2054
2029
|
typeDefault.filterPanelRenderer = config.filterPanelRenderer;
|
|
@@ -2056,47 +2031,56 @@ class GridAdapter {
|
|
|
2056
2031
|
return typeDefault;
|
|
2057
2032
|
}
|
|
2058
2033
|
/**
|
|
2059
|
-
*
|
|
2060
|
-
*
|
|
2034
|
+
* Generalized component-mount primitive. All `createComponent*Renderer` methods
|
|
2035
|
+
* are thin wrappers around this. Returns a function `(ctx) => { hostElement, componentRef }`
|
|
2036
|
+
* so callers that need the `componentRef` (editor wiring, value-change subscription)
|
|
2037
|
+
* still have it; callers that only need the host element use `.hostElement`.
|
|
2038
|
+
*
|
|
2039
|
+
* Public so feature secondary entries can compose their own component renderers
|
|
2040
|
+
* without re-implementing the mount/track plumbing.
|
|
2041
|
+
*
|
|
2042
|
+
* @param componentClass Angular component class to instantiate per call.
|
|
2043
|
+
* @param mapInputs Maps the renderer context to a `setInput()` bag.
|
|
2044
|
+
* @param pool Which `componentRefs[]` array tracks the instance for cleanup.
|
|
2045
|
+
* `'render'` (default) is the long-lived pool cleared at `dispose()`.
|
|
2046
|
+
* `'editor'` is the per-cell pool swept by `releaseCell()`.
|
|
2061
2047
|
* @internal
|
|
2062
2048
|
*/
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
if (isEditor) {
|
|
2078
|
-
this.editorComponentRefs.push(componentRef);
|
|
2079
|
-
}
|
|
2080
|
-
else {
|
|
2081
|
-
this.componentRefs.push(componentRef);
|
|
2082
|
-
}
|
|
2083
|
-
// Trigger change detection
|
|
2084
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
2085
|
-
return { hostElement, componentRef };
|
|
2049
|
+
mountComponentRenderer(componentClass, mapInputs, pool = 'render') {
|
|
2050
|
+
return (ctx) => {
|
|
2051
|
+
const hostElement = document.createElement('span');
|
|
2052
|
+
hostElement.style.display = 'contents';
|
|
2053
|
+
const componentRef = createComponent(componentClass, {
|
|
2054
|
+
environmentInjector: this.injector,
|
|
2055
|
+
hostElement,
|
|
2056
|
+
});
|
|
2057
|
+
this.setComponentInputs(componentRef, mapInputs(ctx));
|
|
2058
|
+
this.appRef.attachView(componentRef.hostView);
|
|
2059
|
+
(pool === 'editor' ? this.editorComponentRefs : this.componentRefs).push(componentRef);
|
|
2060
|
+
componentRef.changeDetectorRef.detectChanges();
|
|
2061
|
+
return { hostElement, componentRef };
|
|
2062
|
+
};
|
|
2086
2063
|
}
|
|
2087
2064
|
/**
|
|
2088
2065
|
* Creates a renderer function from an Angular component class.
|
|
2066
|
+
* Wraps {@link mountComponentRenderer} with a per-cell `WeakMap` cache so
|
|
2067
|
+
* scroll-recycled cells reuse the existing component (just refresh inputs)
|
|
2068
|
+
* instead of mounting a fresh one.
|
|
2089
2069
|
* @internal
|
|
2090
2070
|
*/
|
|
2091
2071
|
createComponentRenderer(componentClass) {
|
|
2092
|
-
// Cell cache for component-based renderers - maps cell element to its component ref
|
|
2093
2072
|
const cellCache = new WeakMap();
|
|
2073
|
+
const mount = this.mountComponentRenderer(componentClass, (ctx) => ({
|
|
2074
|
+
value: ctx.value,
|
|
2075
|
+
row: ctx.row,
|
|
2076
|
+
column: ctx.column,
|
|
2077
|
+
}));
|
|
2094
2078
|
return (ctx) => {
|
|
2095
2079
|
const cellEl = ctx.cellEl;
|
|
2096
2080
|
if (cellEl) {
|
|
2097
2081
|
const cached = cellCache.get(cellEl);
|
|
2098
2082
|
if (cached) {
|
|
2099
|
-
// Reuse existing component - just update inputs
|
|
2083
|
+
// Reuse existing component - just update inputs.
|
|
2100
2084
|
this.setComponentInputs(cached.componentRef, {
|
|
2101
2085
|
value: ctx.value,
|
|
2102
2086
|
row: ctx.row,
|
|
@@ -2106,31 +2090,25 @@ class GridAdapter {
|
|
|
2106
2090
|
return cached.hostElement;
|
|
2107
2091
|
}
|
|
2108
2092
|
}
|
|
2109
|
-
const { hostElement, componentRef } =
|
|
2110
|
-
|
|
2111
|
-
row: ctx.row,
|
|
2112
|
-
column: ctx.column,
|
|
2113
|
-
});
|
|
2114
|
-
// Cache for reuse on scroll recycles
|
|
2115
|
-
if (cellEl) {
|
|
2093
|
+
const { hostElement, componentRef } = mount(ctx);
|
|
2094
|
+
if (cellEl)
|
|
2116
2095
|
cellCache.set(cellEl, { componentRef, hostElement });
|
|
2117
|
-
}
|
|
2118
2096
|
return hostElement;
|
|
2119
2097
|
};
|
|
2120
2098
|
}
|
|
2121
2099
|
/**
|
|
2122
2100
|
* Creates an editor function from an Angular component class.
|
|
2101
|
+
* Wraps {@link mountComponentRenderer} (using the `'editor'` pool for per-cell
|
|
2102
|
+
* cleanup) plus editor-specific wiring: callback bridge, mount-hook fan-out
|
|
2103
|
+
* (see {@link runEditorMountHooks}), and external value-change subscription.
|
|
2123
2104
|
* @internal
|
|
2124
2105
|
*/
|
|
2125
2106
|
createComponentEditor(componentClass) {
|
|
2107
|
+
const mount = this.mountComponentRenderer(componentClass, (ctx) => ({ value: ctx.value, row: ctx.row, column: ctx.column }), 'editor');
|
|
2126
2108
|
return (ctx) => {
|
|
2127
|
-
const { hostElement, componentRef } =
|
|
2128
|
-
value: ctx.value,
|
|
2129
|
-
row: ctx.row,
|
|
2130
|
-
column: ctx.column,
|
|
2131
|
-
}, true);
|
|
2109
|
+
const { hostElement, componentRef } = mount(ctx);
|
|
2132
2110
|
wireEditorCallbacks(hostElement, componentRef.instance, (value) => ctx.commit(value), () => ctx.cancel());
|
|
2133
|
-
this.
|
|
2111
|
+
this.runEditorMountHooks(hostElement);
|
|
2134
2112
|
// Auto-update editor when value changes externally (e.g., via updateRow cascade
|
|
2135
2113
|
// or Escape-revert). Update the component input and run detectChanges() —
|
|
2136
2114
|
// the component's own template handles rendering regardless of editor type.
|
|
@@ -2154,180 +2132,31 @@ class GridAdapter {
|
|
|
2154
2132
|
}
|
|
2155
2133
|
/**
|
|
2156
2134
|
* Creates a header renderer function from an Angular component class.
|
|
2157
|
-
* Mounts the component with full header context (column, value, sortState, etc.).
|
|
2158
|
-
* @internal
|
|
2159
|
-
*/
|
|
2160
|
-
createComponentHeaderRenderer(componentClass) {
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
};
|
|
2181
|
-
|
|
2182
|
-
/**
|
|
2183
|
-
* Creates a header label renderer function from an Angular component class.
|
|
2184
|
-
* Mounts the component with label context (column, value).
|
|
2185
|
-
* @internal
|
|
2186
|
-
*/
|
|
2187
|
-
createComponentHeaderLabelRenderer(componentClass) {
|
|
2188
|
-
return (ctx) => {
|
|
2189
|
-
const hostElement = document.createElement('span');
|
|
2190
|
-
hostElement.style.display = 'contents';
|
|
2191
|
-
const componentRef = createComponent(componentClass, {
|
|
2192
|
-
environmentInjector: this.injector,
|
|
2193
|
-
hostElement,
|
|
2194
|
-
});
|
|
2195
|
-
this.setComponentInputs(componentRef, {
|
|
2196
|
-
column: ctx.column,
|
|
2197
|
-
value: ctx.value,
|
|
2198
|
-
});
|
|
2199
|
-
this.appRef.attachView(componentRef.hostView);
|
|
2200
|
-
this.componentRefs.push(componentRef);
|
|
2201
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
2202
|
-
return hostElement;
|
|
2203
|
-
};
|
|
2204
|
-
}
|
|
2205
|
-
/**
|
|
2206
|
-
* Creates a group header renderer function from an Angular component class.
|
|
2207
|
-
*
|
|
2208
|
-
* The component should accept group header inputs (id, label, columns, firstIndex, isImplicit).
|
|
2209
|
-
* Returns the host element directly (groupHeaderRenderer returns an element, not void).
|
|
2210
|
-
* @internal
|
|
2211
|
-
*/
|
|
2212
|
-
createComponentGroupHeaderRenderer(componentClass) {
|
|
2213
|
-
return (params) => {
|
|
2214
|
-
const hostElement = document.createElement('span');
|
|
2215
|
-
hostElement.style.display = 'contents';
|
|
2216
|
-
const componentRef = createComponent(componentClass, {
|
|
2217
|
-
environmentInjector: this.injector,
|
|
2218
|
-
hostElement,
|
|
2219
|
-
});
|
|
2220
|
-
this.setComponentInputs(componentRef, {
|
|
2221
|
-
id: params.id,
|
|
2222
|
-
label: params.label,
|
|
2223
|
-
columns: params.columns,
|
|
2224
|
-
firstIndex: params.firstIndex,
|
|
2225
|
-
isImplicit: params.isImplicit,
|
|
2226
|
-
});
|
|
2227
|
-
this.appRef.attachView(componentRef.hostView);
|
|
2228
|
-
this.componentRefs.push(componentRef);
|
|
2229
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
2230
|
-
return hostElement;
|
|
2231
|
-
};
|
|
2232
|
-
}
|
|
2233
|
-
/**
|
|
2234
|
-
* Processes a GroupingColumnsConfig, converting component class references
|
|
2235
|
-
* to actual renderer functions.
|
|
2236
|
-
*
|
|
2237
|
-
* @param config - Angular grouping columns configuration with possible component class references
|
|
2238
|
-
* @returns Processed GroupingColumnsConfig with actual renderer functions
|
|
2239
|
-
*/
|
|
2240
|
-
processGroupingColumnsConfig(config) {
|
|
2241
|
-
const processed = { ...config };
|
|
2242
|
-
let changed = false;
|
|
2243
|
-
// Bridge top-level groupHeaderRenderer component class
|
|
2244
|
-
if (config.groupHeaderRenderer && isComponentClass(config.groupHeaderRenderer)) {
|
|
2245
|
-
processed.groupHeaderRenderer = this.createComponentGroupHeaderRenderer(config.groupHeaderRenderer);
|
|
2246
|
-
changed = true;
|
|
2247
|
-
}
|
|
2248
|
-
// Bridge per-group renderer component classes inside columnGroups
|
|
2249
|
-
if (Array.isArray(config.columnGroups)) {
|
|
2250
|
-
const mappedGroups = config.columnGroups.map((def) => {
|
|
2251
|
-
if (def.renderer && isComponentClass(def.renderer)) {
|
|
2252
|
-
changed = true;
|
|
2253
|
-
return { ...def, renderer: this.createComponentGroupHeaderRenderer(def.renderer) };
|
|
2254
|
-
}
|
|
2255
|
-
return def;
|
|
2256
|
-
});
|
|
2257
|
-
if (changed)
|
|
2258
|
-
processed.columnGroups = mappedGroups;
|
|
2259
|
-
}
|
|
2260
|
-
return changed ? processed : config;
|
|
2261
|
-
}
|
|
2262
|
-
/**
|
|
2263
|
-
* Processes a GroupingRowsConfig, converting component class references
|
|
2264
|
-
* to actual renderer functions.
|
|
2265
|
-
*
|
|
2266
|
-
* @param config - Angular grouping rows configuration with possible component class references
|
|
2267
|
-
* @returns Processed GroupingRowsConfig with actual renderer functions
|
|
2268
|
-
*/
|
|
2269
|
-
processGroupingRowsConfig(config) {
|
|
2270
|
-
if (config.groupRowRenderer && isComponentClass(config.groupRowRenderer)) {
|
|
2271
|
-
return {
|
|
2272
|
-
...config,
|
|
2273
|
-
groupRowRenderer: this.createComponentGroupRowRenderer(config.groupRowRenderer),
|
|
2274
|
-
};
|
|
2275
|
-
}
|
|
2276
|
-
return config;
|
|
2277
|
-
}
|
|
2278
|
-
/**
|
|
2279
|
-
* Processes a PinnedRowsConfig, converting component class references
|
|
2280
|
-
* in `customPanels[].render` to actual renderer functions.
|
|
2281
|
-
*
|
|
2282
|
-
* @param config - Angular pinned rows configuration with possible component class references
|
|
2283
|
-
* @returns Processed PinnedRowsConfig with actual renderer functions
|
|
2284
|
-
*/
|
|
2285
|
-
processPinnedRowsConfig(config) {
|
|
2286
|
-
if (!Array.isArray(config.customPanels))
|
|
2287
|
-
return config;
|
|
2288
|
-
const hasComponentRender = config.customPanels.some((panel) => isComponentClass(panel.render));
|
|
2289
|
-
if (!hasComponentRender)
|
|
2290
|
-
return config;
|
|
2291
|
-
return {
|
|
2292
|
-
...config,
|
|
2293
|
-
customPanels: config.customPanels.map((panel) => {
|
|
2294
|
-
if (!isComponentClass(panel.render))
|
|
2295
|
-
return panel;
|
|
2296
|
-
return {
|
|
2297
|
-
...panel,
|
|
2298
|
-
render: this.createComponentPinnedRowsPanelRenderer(panel.render),
|
|
2299
|
-
};
|
|
2300
|
-
}),
|
|
2301
|
-
};
|
|
2302
|
-
}
|
|
2303
|
-
/**
|
|
2304
|
-
* Creates a pinned rows panel renderer function from an Angular component class.
|
|
2305
|
-
*
|
|
2306
|
-
* The component should accept inputs from PinnedRowsContext (totalRows, filteredRows,
|
|
2307
|
-
* selectedRows, columns, rows, grid).
|
|
2308
|
-
* @internal
|
|
2309
|
-
*/
|
|
2310
|
-
createComponentPinnedRowsPanelRenderer(componentClass) {
|
|
2311
|
-
return (ctx) => {
|
|
2312
|
-
const hostElement = document.createElement('span');
|
|
2313
|
-
hostElement.style.display = 'contents';
|
|
2314
|
-
const componentRef = createComponent(componentClass, {
|
|
2315
|
-
environmentInjector: this.injector,
|
|
2316
|
-
hostElement,
|
|
2317
|
-
});
|
|
2318
|
-
this.setComponentInputs(componentRef, {
|
|
2319
|
-
totalRows: ctx.totalRows,
|
|
2320
|
-
filteredRows: ctx.filteredRows,
|
|
2321
|
-
selectedRows: ctx.selectedRows,
|
|
2322
|
-
columns: ctx.columns,
|
|
2323
|
-
rows: ctx.rows,
|
|
2324
|
-
grid: ctx.grid,
|
|
2325
|
-
});
|
|
2326
|
-
this.appRef.attachView(componentRef.hostView);
|
|
2327
|
-
this.componentRefs.push(componentRef);
|
|
2328
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
2329
|
-
return hostElement;
|
|
2330
|
-
};
|
|
2135
|
+
* Mounts the component with full header context (column, value, sortState, etc.).
|
|
2136
|
+
* @internal
|
|
2137
|
+
*/
|
|
2138
|
+
createComponentHeaderRenderer(componentClass) {
|
|
2139
|
+
const mount = this.mountComponentRenderer(componentClass, (ctx) => ({
|
|
2140
|
+
column: ctx.column,
|
|
2141
|
+
value: ctx.value,
|
|
2142
|
+
sortState: ctx.sortState,
|
|
2143
|
+
filterActive: ctx.filterActive,
|
|
2144
|
+
renderSortIcon: ctx.renderSortIcon,
|
|
2145
|
+
renderFilterButton: ctx.renderFilterButton,
|
|
2146
|
+
}));
|
|
2147
|
+
return (ctx) => mount(ctx).hostElement;
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Creates a header label renderer function from an Angular component class.
|
|
2151
|
+
* Mounts the component with label context (column, value).
|
|
2152
|
+
* @internal
|
|
2153
|
+
*/
|
|
2154
|
+
createComponentHeaderLabelRenderer(componentClass) {
|
|
2155
|
+
const mount = this.mountComponentRenderer(componentClass, (ctx) => ({
|
|
2156
|
+
column: ctx.column,
|
|
2157
|
+
value: ctx.value,
|
|
2158
|
+
}));
|
|
2159
|
+
return (ctx) => mount(ctx).hostElement;
|
|
2331
2160
|
}
|
|
2332
2161
|
/**
|
|
2333
2162
|
* Creates a loading renderer function from an Angular component class.
|
|
@@ -2336,78 +2165,59 @@ class GridAdapter {
|
|
|
2336
2165
|
* @internal
|
|
2337
2166
|
*/
|
|
2338
2167
|
createComponentLoadingRenderer(componentClass) {
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
hostElement.style.display = 'contents';
|
|
2342
|
-
const componentRef = createComponent(componentClass, {
|
|
2343
|
-
environmentInjector: this.injector,
|
|
2344
|
-
hostElement,
|
|
2345
|
-
});
|
|
2346
|
-
this.setComponentInputs(componentRef, {
|
|
2347
|
-
size: ctx.size,
|
|
2348
|
-
});
|
|
2349
|
-
this.appRef.attachView(componentRef.hostView);
|
|
2350
|
-
this.componentRefs.push(componentRef);
|
|
2351
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
2352
|
-
return hostElement;
|
|
2353
|
-
};
|
|
2168
|
+
const mount = this.mountComponentRenderer(componentClass, (ctx) => ({ size: ctx.size }));
|
|
2169
|
+
return (ctx) => mount(ctx).hostElement;
|
|
2354
2170
|
}
|
|
2355
2171
|
/**
|
|
2356
|
-
*
|
|
2357
|
-
*
|
|
2358
|
-
*
|
|
2359
|
-
*
|
|
2172
|
+
* Create an embedded view from a `TemplateRef` and append-track it on the
|
|
2173
|
+
* adapter's view-ref pool so it is cleaned up on `destroy()` / `unmount()`.
|
|
2174
|
+
* Public so feature secondary entries can mount Angular templates (e.g.
|
|
2175
|
+
* master-detail rows, responsive cards) without reaching into the adapter's
|
|
2176
|
+
* private `viewContainerRef` / `viewRefs`.
|
|
2360
2177
|
* @internal
|
|
2361
2178
|
*/
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
environmentInjector: this.injector,
|
|
2368
|
-
hostElement,
|
|
2369
|
-
});
|
|
2370
|
-
this.setComponentInputs(componentRef, {
|
|
2371
|
-
key: params.key,
|
|
2372
|
-
value: params.value,
|
|
2373
|
-
depth: params.depth,
|
|
2374
|
-
rows: params.rows,
|
|
2375
|
-
expanded: params.expanded,
|
|
2376
|
-
toggleExpand: params.toggleExpand,
|
|
2377
|
-
});
|
|
2378
|
-
this.appRef.attachView(componentRef.hostView);
|
|
2379
|
-
this.componentRefs.push(componentRef);
|
|
2380
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
2381
|
-
return hostElement;
|
|
2382
|
-
};
|
|
2179
|
+
createTrackedEmbeddedView(template, context) {
|
|
2180
|
+
const viewRef = this.viewContainerRef.createEmbeddedView(template, context);
|
|
2181
|
+
this.viewRefs.push(viewRef);
|
|
2182
|
+
viewRef.detectChanges();
|
|
2183
|
+
return viewRef;
|
|
2383
2184
|
}
|
|
2384
2185
|
/**
|
|
2385
|
-
*
|
|
2386
|
-
*
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2186
|
+
* Processes a GroupingColumnsConfig. Delegates to the feature config
|
|
2187
|
+
* preprocessor installed by `@toolbox-web/grid-angular/features/grouping-columns`,
|
|
2188
|
+
* which handles converting Angular component class references to actual
|
|
2189
|
+
* renderer functions. Returns the input config unchanged if the feature
|
|
2190
|
+
* is not imported.
|
|
2191
|
+
*/
|
|
2192
|
+
processGroupingColumnsConfig(config) {
|
|
2193
|
+
return this.applyFeatureConfigPreprocessor('groupingColumns', config);
|
|
2194
|
+
}
|
|
2195
|
+
/**
|
|
2196
|
+
* Processes a GroupingRowsConfig. Delegates to the feature config preprocessor
|
|
2197
|
+
* installed by `@toolbox-web/grid-angular/features/grouping-rows`.
|
|
2198
|
+
*/
|
|
2199
|
+
processGroupingRowsConfig(config) {
|
|
2200
|
+
return this.applyFeatureConfigPreprocessor('groupingRows', config);
|
|
2201
|
+
}
|
|
2202
|
+
/**
|
|
2203
|
+
* Processes a PinnedRowsConfig. Delegates to the feature config preprocessor
|
|
2204
|
+
* installed by `@toolbox-web/grid-angular/features/pinned-rows`.
|
|
2205
|
+
*/
|
|
2206
|
+
processPinnedRowsConfig(config) {
|
|
2207
|
+
return this.applyFeatureConfigPreprocessor('pinnedRows', config);
|
|
2208
|
+
}
|
|
2209
|
+
/**
|
|
2210
|
+
* Run a registered feature-config preprocessor against `config`, returning
|
|
2211
|
+
* the original config unchanged when the feature is not imported.
|
|
2389
2212
|
* @internal
|
|
2390
2213
|
*/
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
});
|
|
2399
|
-
// Set params input
|
|
2400
|
-
try {
|
|
2401
|
-
componentRef.setInput('params', params);
|
|
2402
|
-
}
|
|
2403
|
-
catch {
|
|
2404
|
-
// Input doesn't exist on component — ignore
|
|
2405
|
-
}
|
|
2406
|
-
this.appRef.attachView(componentRef.hostView);
|
|
2407
|
-
this.componentRefs.push(componentRef);
|
|
2408
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
2409
|
-
container.appendChild(hostElement);
|
|
2410
|
-
};
|
|
2214
|
+
applyFeatureConfigPreprocessor(name, config) {
|
|
2215
|
+
if (!config || typeof config !== 'object')
|
|
2216
|
+
return config;
|
|
2217
|
+
const preprocessor = getFeatureConfigPreprocessor(name);
|
|
2218
|
+
if (!preprocessor)
|
|
2219
|
+
return config;
|
|
2220
|
+
return preprocessor(config, this);
|
|
2411
2221
|
}
|
|
2412
2222
|
/**
|
|
2413
2223
|
* Sets component inputs using Angular's setInput API.
|
|
@@ -2449,11 +2259,11 @@ class GridAdapter {
|
|
|
2449
2259
|
this.editorComponentRefs.splice(i, 1);
|
|
2450
2260
|
}
|
|
2451
2261
|
}
|
|
2452
|
-
// Detach
|
|
2453
|
-
for (const [hostEl, unsub] of this.
|
|
2262
|
+
// Detach editor-mount hook teardowns for editor hosts inside this cell.
|
|
2263
|
+
for (const [hostEl, unsub] of this.editorMountTeardowns) {
|
|
2454
2264
|
if (cellEl.contains(hostEl)) {
|
|
2455
2265
|
unsub();
|
|
2456
|
-
this.
|
|
2266
|
+
this.editorMountTeardowns.delete(hostEl);
|
|
2457
2267
|
}
|
|
2458
2268
|
}
|
|
2459
2269
|
}
|
|
@@ -2493,40 +2303,28 @@ class GridAdapter {
|
|
|
2493
2303
|
this.componentRefs = [];
|
|
2494
2304
|
this.editorComponentRefs.forEach((ref) => ref.destroy());
|
|
2495
2305
|
this.editorComponentRefs = [];
|
|
2496
|
-
this.
|
|
2497
|
-
this.
|
|
2306
|
+
this.editorMountTeardowns.forEach((unsub) => unsub());
|
|
2307
|
+
this.editorMountTeardowns.clear();
|
|
2498
2308
|
}
|
|
2499
2309
|
/**
|
|
2500
|
-
*
|
|
2501
|
-
*
|
|
2502
|
-
*
|
|
2503
|
-
*
|
|
2504
|
-
*
|
|
2505
|
-
* The grid is resolved lazily via `queueMicrotask` because the host is
|
|
2506
|
-
* appended to the cell *after* the editor wrapper returns. Mirror of
|
|
2507
|
-
* Vue's `attachBeforeEditCloseFlush` and React's `wrapReactEditor`
|
|
2310
|
+
* Runs every registered {@link EditorMountHook} against a freshly mounted
|
|
2311
|
+
* editor host once it has been parented to the grid. The grid is resolved
|
|
2312
|
+
* lazily via `queueMicrotask` because the host is appended to the cell
|
|
2313
|
+
* *after* the editor wrapper returns. Mirror of Vue's
|
|
2314
|
+
* `attachBeforeEditCloseFlush` and React's `wrapReactEditor`
|
|
2508
2315
|
* queueMicrotask bridge.
|
|
2316
|
+
*
|
|
2317
|
+
* Without any feature imports the hook list is empty and this is a no-op
|
|
2318
|
+
* — `before-edit-close` blur handling lives in
|
|
2319
|
+
* `@toolbox-web/grid-angular/features/editing`.
|
|
2509
2320
|
* @internal
|
|
2510
2321
|
*/
|
|
2511
|
-
|
|
2322
|
+
runEditorMountHooks(host) {
|
|
2512
2323
|
queueMicrotask(() => {
|
|
2513
2324
|
const gridEl = host.closest('tbw-grid');
|
|
2514
2325
|
if (!gridEl)
|
|
2515
2326
|
return;
|
|
2516
|
-
|
|
2517
|
-
const focused = host.ownerDocument.activeElement;
|
|
2518
|
-
if (focused &&
|
|
2519
|
-
host.contains(focused) &&
|
|
2520
|
-
(focused instanceof HTMLInputElement ||
|
|
2521
|
-
focused instanceof HTMLTextAreaElement ||
|
|
2522
|
-
focused instanceof HTMLSelectElement)) {
|
|
2523
|
-
focused.blur();
|
|
2524
|
-
}
|
|
2525
|
-
};
|
|
2526
|
-
gridEl.addEventListener('before-edit-close', flush);
|
|
2527
|
-
this.editorBeforeCloseUnsubs.set(host, () => {
|
|
2528
|
-
gridEl.removeEventListener('before-edit-close', flush);
|
|
2529
|
-
});
|
|
2327
|
+
this.editorMountTeardowns.set(host, notifyEditorMounted(host, gridEl));
|
|
2530
2328
|
});
|
|
2531
2329
|
}
|
|
2532
2330
|
}
|
|
@@ -2788,6 +2586,12 @@ function injectGrid(selector = 'tbw-grid') {
|
|
|
2788
2586
|
const unregisterStyles = (id) => {
|
|
2789
2587
|
element()?.unregisterStyles?.(id);
|
|
2790
2588
|
};
|
|
2589
|
+
const getPlugin = (pluginClass) => {
|
|
2590
|
+
return element()?.getPlugin?.(pluginClass);
|
|
2591
|
+
};
|
|
2592
|
+
const getPluginByName = ((name) => {
|
|
2593
|
+
return element()?.getPluginByName?.(name);
|
|
2594
|
+
});
|
|
2791
2595
|
return {
|
|
2792
2596
|
element,
|
|
2793
2597
|
isReady,
|
|
@@ -2798,6 +2602,8 @@ function injectGrid(selector = 'tbw-grid') {
|
|
|
2798
2602
|
toggleGroup,
|
|
2799
2603
|
registerStyles,
|
|
2800
2604
|
unregisterStyles,
|
|
2605
|
+
getPlugin,
|
|
2606
|
+
getPluginByName,
|
|
2801
2607
|
};
|
|
2802
2608
|
}
|
|
2803
2609
|
|
|
@@ -2864,6 +2670,11 @@ function injectGrid(selector = 'tbw-grid') {
|
|
|
2864
2670
|
* ```
|
|
2865
2671
|
*
|
|
2866
2672
|
* @typeParam TRow - The row data type (available via `params().column`)
|
|
2673
|
+
*
|
|
2674
|
+
* MOVE-IN-V2: this class will physically move into
|
|
2675
|
+
* `@toolbox-web/grid-angular/features/filtering` in v2.0.0; the deprecated
|
|
2676
|
+
* re-export from the main `@toolbox-web/grid-angular` entry will be removed at
|
|
2677
|
+
* the same time. Consumers should already be importing from the feature entry.
|
|
2867
2678
|
*/
|
|
2868
2679
|
class BaseFilterPanel {
|
|
2869
2680
|
/**
|
|
@@ -2967,6 +2778,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
2967
2778
|
*
|
|
2968
2779
|
* @typeParam TRow - The row data type
|
|
2969
2780
|
* @typeParam TValue - The cell value type
|
|
2781
|
+
*
|
|
2782
|
+
* MOVE-IN-V2: this class will physically move into
|
|
2783
|
+
* `@toolbox-web/grid-angular/features/editing` in v2.0.0; the deprecated
|
|
2784
|
+
* re-export from the main `@toolbox-web/grid-angular` entry will be removed at
|
|
2785
|
+
* the same time. Consumers should already be importing from the feature entry.
|
|
2970
2786
|
*/
|
|
2971
2787
|
class BaseGridEditor {
|
|
2972
2788
|
elementRef = inject(ElementRef);
|
|
@@ -3269,6 +3085,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
3269
3085
|
*
|
|
3270
3086
|
* @typeParam TRow - The row data type
|
|
3271
3087
|
* @typeParam TValue - The cell/control value type
|
|
3088
|
+
*
|
|
3089
|
+
* MOVE-IN-V2: this class will physically move into
|
|
3090
|
+
* `@toolbox-web/grid-angular/features/editing` in v2.0.0; the deprecated
|
|
3091
|
+
* re-export from the main `@toolbox-web/grid-angular` entry will be removed at
|
|
3092
|
+
* the same time. Consumers should already be importing from the feature entry.
|
|
3272
3093
|
*/
|
|
3273
3094
|
class BaseGridEditorCVA extends BaseGridEditor {
|
|
3274
3095
|
// ============================================================================
|
|
@@ -3532,6 +3353,12 @@ let anchorCounter = 0;
|
|
|
3532
3353
|
*
|
|
3533
3354
|
* @typeParam TRow - The row data type
|
|
3534
3355
|
* @typeParam TValue - The cell value type
|
|
3356
|
+
*
|
|
3357
|
+
* MOVE-IN-V2: this class (and its companion `OverlayPosition` type) will
|
|
3358
|
+
* physically move into `@toolbox-web/grid-angular/features/editing` in v2.0.0;
|
|
3359
|
+
* the deprecated re-export from the main `@toolbox-web/grid-angular` entry
|
|
3360
|
+
* will be removed at the same time. Consumers should already be importing
|
|
3361
|
+
* from the feature entry.
|
|
3535
3362
|
*/
|
|
3536
3363
|
class BaseOverlayEditor extends BaseGridEditor {
|
|
3537
3364
|
_elementRef = inject(ElementRef);
|
|
@@ -4010,6 +3837,102 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
4010
3837
|
}]
|
|
4011
3838
|
}] });
|
|
4012
3839
|
|
|
3840
|
+
// Global registry mapping DOM elements to their templates
|
|
3841
|
+
const detailTemplateRegistry = new Map();
|
|
3842
|
+
/**
|
|
3843
|
+
* Gets the detail template registered for a given grid element.
|
|
3844
|
+
* Used by AngularGridAdapter to retrieve templates at render time.
|
|
3845
|
+
*/
|
|
3846
|
+
function getDetailTemplate(gridElement) {
|
|
3847
|
+
// Look for tbw-grid-detail child and get its template
|
|
3848
|
+
const detailElement = gridElement.querySelector('tbw-grid-detail');
|
|
3849
|
+
if (detailElement) {
|
|
3850
|
+
return detailTemplateRegistry.get(detailElement);
|
|
3851
|
+
}
|
|
3852
|
+
return undefined;
|
|
3853
|
+
}
|
|
3854
|
+
/**
|
|
3855
|
+
* Directive that captures an `<ng-template>` for use as a master-detail row renderer.
|
|
3856
|
+
*
|
|
3857
|
+
* This enables declarative Angular component usage for expandable detail rows
|
|
3858
|
+
* that appear below the main row when expanded.
|
|
3859
|
+
*
|
|
3860
|
+
* ## Usage
|
|
3861
|
+
*
|
|
3862
|
+
* ```html
|
|
3863
|
+
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
3864
|
+
* <tbw-grid-detail [showExpandColumn]="true" animation="slide">
|
|
3865
|
+
* <ng-template let-row>
|
|
3866
|
+
* <app-detail-panel [employee]="row" />
|
|
3867
|
+
* </ng-template>
|
|
3868
|
+
* </tbw-grid-detail>
|
|
3869
|
+
* </tbw-grid>
|
|
3870
|
+
* ```
|
|
3871
|
+
*
|
|
3872
|
+
* The template context provides:
|
|
3873
|
+
* - `$implicit` / `row`: The full row data object
|
|
3874
|
+
*
|
|
3875
|
+
* Import the directive from the master-detail feature entry:
|
|
3876
|
+
*
|
|
3877
|
+
* ```typescript
|
|
3878
|
+
* import { GridDetailView } from '@toolbox-web/grid-angular/features/master-detail';
|
|
3879
|
+
*
|
|
3880
|
+
* @Component({
|
|
3881
|
+
* imports: [GridDetailView],
|
|
3882
|
+
* // ...
|
|
3883
|
+
* })
|
|
3884
|
+
* ```
|
|
3885
|
+
*
|
|
3886
|
+
* > Note: `GridDetailView` is also re-exported from `@toolbox-web/grid-angular`
|
|
3887
|
+
* > for backwards compatibility, but that re-export is deprecated and will be
|
|
3888
|
+
* > removed in v2.0.0. Always import from the feature entry.
|
|
3889
|
+
*
|
|
3890
|
+
* @example
|
|
3891
|
+
* ```html
|
|
3892
|
+
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
3893
|
+
* <tbw-grid-detail [showExpandColumn]="true" animation="slide">
|
|
3894
|
+
* <ng-template let-row>
|
|
3895
|
+
* <app-detail-panel [employee]="row" />
|
|
3896
|
+
* </ng-template>
|
|
3897
|
+
* </tbw-grid-detail>
|
|
3898
|
+
* </tbw-grid>
|
|
3899
|
+
* ```
|
|
3900
|
+
*
|
|
3901
|
+
* @category Directive
|
|
3902
|
+
*/
|
|
3903
|
+
class GridDetailView {
|
|
3904
|
+
elementRef = inject((ElementRef));
|
|
3905
|
+
/** Whether to show the expand/collapse column. Default: true */
|
|
3906
|
+
showExpandColumn = input(true, ...(ngDevMode ? [{ debugName: "showExpandColumn" }] : /* istanbul ignore next */ []));
|
|
3907
|
+
/** Animation style for expand/collapse. Default: 'slide' */
|
|
3908
|
+
animation = input('slide', ...(ngDevMode ? [{ debugName: "animation" }] : /* istanbul ignore next */ []));
|
|
3909
|
+
/**
|
|
3910
|
+
* Query for the ng-template content child.
|
|
3911
|
+
*/
|
|
3912
|
+
template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
3913
|
+
/** Effect that triggers when the template is available */
|
|
3914
|
+
onTemplateReceived = effect(() => {
|
|
3915
|
+
const template = this.template();
|
|
3916
|
+
if (template) {
|
|
3917
|
+
// Register the template for this element
|
|
3918
|
+
detailTemplateRegistry.set(this.elementRef.nativeElement, template);
|
|
3919
|
+
}
|
|
3920
|
+
}, ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
|
|
3921
|
+
/**
|
|
3922
|
+
* Static type guard for template context.
|
|
3923
|
+
* Enables type inference in templates.
|
|
3924
|
+
*/
|
|
3925
|
+
static ngTemplateContextGuard(dir, ctx) {
|
|
3926
|
+
return true;
|
|
3927
|
+
}
|
|
3928
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridDetailView, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3929
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridDetailView, isStandalone: true, selector: "tbw-grid-detail", inputs: { showExpandColumn: { classPropertyName: "showExpandColumn", publicName: "showExpandColumn", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
|
|
3930
|
+
}
|
|
3931
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridDetailView, decorators: [{
|
|
3932
|
+
type: Directive,
|
|
3933
|
+
args: [{ selector: 'tbw-grid-detail' }]
|
|
3934
|
+
}], propDecorators: { showExpandColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExpandColumn", required: false }] }], animation: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
3935
|
+
|
|
4013
3936
|
/**
|
|
4014
3937
|
* Directive that registers `<tbw-grid-header>` as a known Angular element.
|
|
4015
3938
|
*
|
|
@@ -4132,6 +4055,13 @@ function getLazyFormContext(gridElement) {
|
|
|
4132
4055
|
*
|
|
4133
4056
|
* @see GridFormArray For small datasets with full upfront validation
|
|
4134
4057
|
* @category Directive
|
|
4058
|
+
*
|
|
4059
|
+
* MOVE-IN-V2: this directive (and its `LazyFormFactory`, `RowFormChangeEvent`
|
|
4060
|
+
* types and `getLazyFormContext` helper) will physically move into
|
|
4061
|
+
* `@toolbox-web/grid-angular/features/editing` in v2.0.0; the deprecated
|
|
4062
|
+
* re-exports from the main `@toolbox-web/grid-angular` entry will be removed
|
|
4063
|
+
* at the same time. Consumers should already be importing from the feature
|
|
4064
|
+
* entry.
|
|
4135
4065
|
*/
|
|
4136
4066
|
class GridLazyForm {
|
|
4137
4067
|
elementRef = inject((ElementRef));
|
|
@@ -4517,15 +4447,119 @@ class GridLazyForm {
|
|
|
4517
4447
|
}
|
|
4518
4448
|
return true;
|
|
4519
4449
|
}
|
|
4520
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridLazyForm, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4521
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: GridLazyForm, isStandalone: true, selector: "tbw-grid[lazyForm]", inputs: { lazyForm: { classPropertyName: "lazyForm", publicName: "lazyForm", isSignal: true, isRequired: true, transformFunction: null }, syncValidation: { classPropertyName: "syncValidation", publicName: "syncValidation", isSignal: true, isRequired: false, transformFunction: null }, keepFormGroups: { classPropertyName: "keepFormGroups", publicName: "keepFormGroups", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowFormChange: "rowFormChange" }, ngImport: i0 });
|
|
4450
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridLazyForm, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4451
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: GridLazyForm, isStandalone: true, selector: "tbw-grid[lazyForm]", inputs: { lazyForm: { classPropertyName: "lazyForm", publicName: "lazyForm", isSignal: true, isRequired: true, transformFunction: null }, syncValidation: { classPropertyName: "syncValidation", publicName: "syncValidation", isSignal: true, isRequired: false, transformFunction: null }, keepFormGroups: { classPropertyName: "keepFormGroups", publicName: "keepFormGroups", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowFormChange: "rowFormChange" }, ngImport: i0 });
|
|
4452
|
+
}
|
|
4453
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridLazyForm, decorators: [{
|
|
4454
|
+
type: Directive,
|
|
4455
|
+
args: [{
|
|
4456
|
+
selector: 'tbw-grid[lazyForm]',
|
|
4457
|
+
}]
|
|
4458
|
+
}], propDecorators: { lazyForm: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazyForm", required: true }] }], syncValidation: [{ type: i0.Input, args: [{ isSignal: true, alias: "syncValidation", required: false }] }], keepFormGroups: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepFormGroups", required: false }] }], rowFormChange: [{ type: i0.Output, args: ["rowFormChange"] }] } });
|
|
4459
|
+
|
|
4460
|
+
/**
|
|
4461
|
+
* Registry to store responsive card templates by grid element.
|
|
4462
|
+
* Used by AngularGridAdapter to create card renderers.
|
|
4463
|
+
*/
|
|
4464
|
+
const responsiveCardTemplateRegistry = new Map();
|
|
4465
|
+
/**
|
|
4466
|
+
* Retrieves the responsive card template for a grid element.
|
|
4467
|
+
*
|
|
4468
|
+
* @param gridElement - The grid element to look up
|
|
4469
|
+
* @returns The template reference or undefined if not found
|
|
4470
|
+
*/
|
|
4471
|
+
function getResponsiveCardTemplate(gridElement) {
|
|
4472
|
+
// Find the tbw-grid-responsive-card element inside the grid
|
|
4473
|
+
const cardElement = gridElement.querySelector('tbw-grid-responsive-card');
|
|
4474
|
+
if (!cardElement)
|
|
4475
|
+
return undefined;
|
|
4476
|
+
return responsiveCardTemplateRegistry.get(cardElement);
|
|
4477
|
+
}
|
|
4478
|
+
/**
|
|
4479
|
+
* Directive for providing custom Angular templates for responsive card layout.
|
|
4480
|
+
*
|
|
4481
|
+
* Use this directive to define how each row should render when the grid
|
|
4482
|
+
* is in responsive/mobile mode. The template receives the row data and index.
|
|
4483
|
+
*
|
|
4484
|
+
* ## Usage
|
|
4485
|
+
*
|
|
4486
|
+
* ```html
|
|
4487
|
+
* <tbw-grid [rows]="employees">
|
|
4488
|
+
* <tbw-grid-responsive-card>
|
|
4489
|
+
* <ng-template let-employee let-idx="index">
|
|
4490
|
+
* <div class="employee-card">
|
|
4491
|
+
* <img [src]="employee.avatar" alt="">
|
|
4492
|
+
* <div class="info">
|
|
4493
|
+
* <strong>{{ employee.name }}</strong>
|
|
4494
|
+
* <span>{{ employee.department }}</span>
|
|
4495
|
+
* </div>
|
|
4496
|
+
* </div>
|
|
4497
|
+
* </ng-template>
|
|
4498
|
+
* </tbw-grid-responsive-card>
|
|
4499
|
+
* </tbw-grid>
|
|
4500
|
+
* ```
|
|
4501
|
+
*
|
|
4502
|
+
* ## Important Notes
|
|
4503
|
+
*
|
|
4504
|
+
* - The ResponsivePlugin must be added to your grid config
|
|
4505
|
+
* - The Grid directive will automatically configure the plugin's cardRenderer
|
|
4506
|
+
* - Template context provides `$implicit` (row), `row`, and `index`
|
|
4507
|
+
*
|
|
4508
|
+
* @see ResponsivePlugin
|
|
4509
|
+
* @category Directive
|
|
4510
|
+
*/
|
|
4511
|
+
class GridResponsiveCard {
|
|
4512
|
+
elementRef = inject((ElementRef));
|
|
4513
|
+
/**
|
|
4514
|
+
* Card row height in pixels. Use `'auto'` for dynamic height based on content.
|
|
4515
|
+
*
|
|
4516
|
+
* Mirrors to the `card-row-height` attribute on the underlying
|
|
4517
|
+
* `<tbw-grid-responsive-card>` element which the ResponsivePlugin reads.
|
|
4518
|
+
*
|
|
4519
|
+
* @default 'auto'
|
|
4520
|
+
*/
|
|
4521
|
+
cardRowHeight = input(...(ngDevMode ? [undefined, { debugName: "cardRowHeight" }] : /* istanbul ignore next */ []));
|
|
4522
|
+
/**
|
|
4523
|
+
* The ng-template containing the card content.
|
|
4524
|
+
*/
|
|
4525
|
+
template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
4526
|
+
/**
|
|
4527
|
+
* Effect that registers the template when it becomes available.
|
|
4528
|
+
*/
|
|
4529
|
+
onTemplateReceived = effect(() => {
|
|
4530
|
+
const template = this.template();
|
|
4531
|
+
if (template) {
|
|
4532
|
+
responsiveCardTemplateRegistry.set(this.elementRef.nativeElement, template);
|
|
4533
|
+
}
|
|
4534
|
+
}, ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
|
|
4535
|
+
/**
|
|
4536
|
+
* Effect that mirrors the `cardRowHeight` input to the kebab-cased attribute
|
|
4537
|
+
* read by the ResponsivePlugin.
|
|
4538
|
+
*/
|
|
4539
|
+
onCardRowHeightChange = effect(() => {
|
|
4540
|
+
const value = this.cardRowHeight();
|
|
4541
|
+
const element = this.elementRef.nativeElement;
|
|
4542
|
+
if (value === undefined) {
|
|
4543
|
+
element.removeAttribute('card-row-height');
|
|
4544
|
+
return;
|
|
4545
|
+
}
|
|
4546
|
+
element.setAttribute('card-row-height', value === 'auto' ? 'auto' : String(value));
|
|
4547
|
+
}, ...(ngDevMode ? [{ debugName: "onCardRowHeightChange" }] : /* istanbul ignore next */ []));
|
|
4548
|
+
/**
|
|
4549
|
+
* Type guard for template context inference.
|
|
4550
|
+
*/
|
|
4551
|
+
static ngTemplateContextGuard(_directive, context) {
|
|
4552
|
+
return true;
|
|
4553
|
+
}
|
|
4554
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridResponsiveCard, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4555
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridResponsiveCard, isStandalone: true, selector: "tbw-grid-responsive-card", inputs: { cardRowHeight: { classPropertyName: "cardRowHeight", publicName: "cardRowHeight", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
|
|
4522
4556
|
}
|
|
4523
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type:
|
|
4557
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridResponsiveCard, decorators: [{
|
|
4524
4558
|
type: Directive,
|
|
4525
4559
|
args: [{
|
|
4526
|
-
selector: 'tbw-grid
|
|
4560
|
+
selector: 'tbw-grid-responsive-card',
|
|
4527
4561
|
}]
|
|
4528
|
-
}], propDecorators: {
|
|
4562
|
+
}], propDecorators: { cardRowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardRowHeight", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
4529
4563
|
|
|
4530
4564
|
/**
|
|
4531
4565
|
* Directive that registers `<tbw-grid-tool-buttons>` as a known Angular element.
|
|
@@ -4566,6 +4600,149 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
4566
4600
|
}]
|
|
4567
4601
|
}] });
|
|
4568
4602
|
|
|
4603
|
+
/** Capitalize the first letter of a string for header generation. */
|
|
4604
|
+
function capitalize(str) {
|
|
4605
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
4606
|
+
}
|
|
4607
|
+
/**
|
|
4608
|
+
* Generate a human-readable header from a field name.
|
|
4609
|
+
*
|
|
4610
|
+
* Handles camelCase, snake_case, and kebab-case.
|
|
4611
|
+
*
|
|
4612
|
+
* @example
|
|
4613
|
+
* generateHeader('firstName') → 'First Name'
|
|
4614
|
+
* generateHeader('last_name') → 'Last Name'
|
|
4615
|
+
* generateHeader('email-address') → 'Email Address'
|
|
4616
|
+
* generateHeader('id') → 'ID' (special case)
|
|
4617
|
+
*/
|
|
4618
|
+
function generateHeader(field) {
|
|
4619
|
+
if (field.toLowerCase() === 'id')
|
|
4620
|
+
return 'ID';
|
|
4621
|
+
const words = field
|
|
4622
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
4623
|
+
.replace(/[_-]/g, ' ')
|
|
4624
|
+
.split(' ')
|
|
4625
|
+
.filter(Boolean);
|
|
4626
|
+
return words.map(capitalize).join(' ');
|
|
4627
|
+
}
|
|
4628
|
+
/** Valid column types from the shorthand notation. */
|
|
4629
|
+
const VALID_TYPES = new Set(['string', 'number', 'boolean', 'date', 'datetime', 'currency']);
|
|
4630
|
+
/**
|
|
4631
|
+
* Parse a column shorthand string into a ColumnConfig.
|
|
4632
|
+
*
|
|
4633
|
+
* Supports formats:
|
|
4634
|
+
* - `'fieldName'` → `{ field: 'fieldName', header: 'Field Name' }`
|
|
4635
|
+
* - `'fieldName:type'` → `{ field: 'fieldName', header: 'Field Name', type: 'type' }`
|
|
4636
|
+
*
|
|
4637
|
+
* @param shorthand - The shorthand string (e.g., 'name', 'salary:number')
|
|
4638
|
+
* @returns A ColumnConfig object
|
|
4639
|
+
*/
|
|
4640
|
+
function parseColumnShorthand(shorthand) {
|
|
4641
|
+
const colonIndex = shorthand.lastIndexOf(':');
|
|
4642
|
+
if (colonIndex > 0) {
|
|
4643
|
+
const potentialType = shorthand.slice(colonIndex + 1).toLowerCase();
|
|
4644
|
+
if (VALID_TYPES.has(potentialType)) {
|
|
4645
|
+
const field = shorthand.slice(0, colonIndex);
|
|
4646
|
+
return {
|
|
4647
|
+
field: field,
|
|
4648
|
+
header: generateHeader(field),
|
|
4649
|
+
type: potentialType,
|
|
4650
|
+
};
|
|
4651
|
+
}
|
|
4652
|
+
}
|
|
4653
|
+
return {
|
|
4654
|
+
field: shorthand,
|
|
4655
|
+
header: generateHeader(shorthand),
|
|
4656
|
+
};
|
|
4657
|
+
}
|
|
4658
|
+
/**
|
|
4659
|
+
* Normalize an array of column shorthands to ColumnConfig objects.
|
|
4660
|
+
*
|
|
4661
|
+
* @param columns - Array of column shorthands (strings or ColumnConfig objects)
|
|
4662
|
+
* @returns Array of ColumnConfig objects
|
|
4663
|
+
*/
|
|
4664
|
+
function normalizeColumns(columns) {
|
|
4665
|
+
return columns.map((col) => (typeof col === 'string' ? parseColumnShorthand(col) : col));
|
|
4666
|
+
}
|
|
4667
|
+
/**
|
|
4668
|
+
* Apply column defaults to a list of columns. Individual column properties
|
|
4669
|
+
* override defaults.
|
|
4670
|
+
*/
|
|
4671
|
+
function applyColumnDefaults(columns, defaults) {
|
|
4672
|
+
if (!defaults)
|
|
4673
|
+
return columns;
|
|
4674
|
+
return columns.map((col) => ({ ...defaults, ...col }));
|
|
4675
|
+
}
|
|
4676
|
+
/** Check if an array of columns contains any shorthand strings. */
|
|
4677
|
+
function hasColumnShorthands(columns) {
|
|
4678
|
+
return columns.some((col) => typeof col === 'string');
|
|
4679
|
+
}
|
|
4680
|
+
|
|
4681
|
+
/** Per-element map of claimed feature names → config getter. */
|
|
4682
|
+
const featureClaims = new WeakMap();
|
|
4683
|
+
/** Per-element set of claimed event names (matches `keyof DataGridEventMap`). */
|
|
4684
|
+
const eventClaims = new WeakMap();
|
|
4685
|
+
/**
|
|
4686
|
+
* Register a feature claim. Called by a feature directive's constructor;
|
|
4687
|
+
* the {@link Grid} directive will then use {@link getFeatureClaim} during
|
|
4688
|
+
* plugin creation instead of reading its own deprecated input.
|
|
4689
|
+
* @internal
|
|
4690
|
+
*/
|
|
4691
|
+
function registerFeatureClaim(grid, name, getConfig) {
|
|
4692
|
+
let map = featureClaims.get(grid);
|
|
4693
|
+
if (!map) {
|
|
4694
|
+
map = new Map();
|
|
4695
|
+
featureClaims.set(grid, map);
|
|
4696
|
+
}
|
|
4697
|
+
map.set(name, getConfig);
|
|
4698
|
+
}
|
|
4699
|
+
/**
|
|
4700
|
+
* Look up a feature claim. Returns the registered config getter, or
|
|
4701
|
+
* `undefined` if no directive owns this feature on this element.
|
|
4702
|
+
* @internal
|
|
4703
|
+
*/
|
|
4704
|
+
function getFeatureClaim(grid, name) {
|
|
4705
|
+
return featureClaims.get(grid)?.get(name);
|
|
4706
|
+
}
|
|
4707
|
+
/**
|
|
4708
|
+
* Drop a feature claim. Called by a feature directive's `ngOnDestroy` so
|
|
4709
|
+
* that, if the directive is removed (e.g. via `*ngIf`) but the host
|
|
4710
|
+
* `<tbw-grid>` survives, {@link Grid}'s deprecated input takes back over.
|
|
4711
|
+
* @internal
|
|
4712
|
+
*/
|
|
4713
|
+
function unregisterFeatureClaim(grid, name) {
|
|
4714
|
+
featureClaims.get(grid)?.delete(name);
|
|
4715
|
+
}
|
|
4716
|
+
/**
|
|
4717
|
+
* Mark an event as owned by a feature directive. {@link Grid}'s
|
|
4718
|
+
* `setupEventListeners` skips wiring its own deprecated `output()` for any
|
|
4719
|
+
* claimed event — the directive owns the listener and the emit.
|
|
4720
|
+
* @internal
|
|
4721
|
+
*/
|
|
4722
|
+
function claimEvent(grid, eventName) {
|
|
4723
|
+
let set = eventClaims.get(grid);
|
|
4724
|
+
if (!set) {
|
|
4725
|
+
set = new Set();
|
|
4726
|
+
eventClaims.set(grid, set);
|
|
4727
|
+
}
|
|
4728
|
+
set.add(eventName);
|
|
4729
|
+
}
|
|
4730
|
+
/**
|
|
4731
|
+
* Returns true if a directive has claimed this event on this grid element.
|
|
4732
|
+
* @internal
|
|
4733
|
+
*/
|
|
4734
|
+
function isEventClaimed(grid, eventName) {
|
|
4735
|
+
return eventClaims.get(grid)?.has(eventName) ?? false;
|
|
4736
|
+
}
|
|
4737
|
+
/**
|
|
4738
|
+
* Drop an event claim. Pair with {@link claimEvent} in a directive's
|
|
4739
|
+
* `ngOnDestroy`.
|
|
4740
|
+
* @internal
|
|
4741
|
+
*/
|
|
4742
|
+
function unclaimEvent(grid, eventName) {
|
|
4743
|
+
eventClaims.get(grid)?.delete(eventName);
|
|
4744
|
+
}
|
|
4745
|
+
|
|
4569
4746
|
/**
|
|
4570
4747
|
* Directive that automatically registers the Angular adapter with tbw-grid elements.
|
|
4571
4748
|
*
|
|
@@ -4683,13 +4860,25 @@ class Grid {
|
|
|
4683
4860
|
if (columnsValue === undefined)
|
|
4684
4861
|
return;
|
|
4685
4862
|
const grid = this.elementRef.nativeElement;
|
|
4863
|
+
// First normalize any shorthand strings to ColumnConfig objects, then
|
|
4864
|
+
// merge in any per-grid column defaults. Individual column props always win.
|
|
4865
|
+
// Note: Angular ColumnConfig allows component classes for renderer/editor,
|
|
4866
|
+
// which the adapter normalizes via processColumn below; we widen to `any`
|
|
4867
|
+
// here so the shorthand helpers (typed against the core ColumnConfig) accept
|
|
4868
|
+
// the Angular-flavoured payload unchanged.
|
|
4869
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4870
|
+
const normalized = applyColumnDefaults(
|
|
4871
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4872
|
+
normalizeColumns(columnsValue),
|
|
4873
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4874
|
+
this.columnDefaults());
|
|
4686
4875
|
// Process columns through the adapter to convert Angular component classes
|
|
4687
4876
|
// (renderer/editor) to functions — the grid's columns setter does NOT call
|
|
4688
4877
|
// processConfig, unlike gridConfig. Without this, raw component classes
|
|
4689
4878
|
// would be invoked without `new`, causing runtime errors.
|
|
4690
4879
|
const processed = this.adapter
|
|
4691
|
-
?
|
|
4692
|
-
:
|
|
4880
|
+
? normalized.map((col) => this.adapter.processColumn(col))
|
|
4881
|
+
: normalized;
|
|
4693
4882
|
grid.columns = processed;
|
|
4694
4883
|
});
|
|
4695
4884
|
// Effect to sync fitMode to the grid element
|
|
@@ -4824,21 +5013,35 @@ class Grid {
|
|
|
4824
5013
|
/**
|
|
4825
5014
|
* Column configuration array.
|
|
4826
5015
|
*
|
|
5016
|
+
* Accepts either full `ColumnConfig` objects or shorthand strings such as
|
|
5017
|
+
* `'name'` or `'salary:number'`. Shorthands auto-generate human-readable
|
|
5018
|
+
* headers from the field name.
|
|
5019
|
+
*
|
|
4827
5020
|
* Shorthand for setting columns without wrapping them in a full `gridConfig`.
|
|
4828
5021
|
* If both `columns` and `gridConfig.columns` are set, `columns` takes precedence
|
|
4829
5022
|
* (see configuration precedence system).
|
|
4830
5023
|
*
|
|
4831
5024
|
* @example
|
|
4832
5025
|
* ```html
|
|
4833
|
-
* <tbw-grid [rows]="data" [columns]="[
|
|
4834
|
-
* { field: 'id', header: 'ID', pinned: 'left', width: 80 },
|
|
4835
|
-
* { field: 'name', header: 'Name' },
|
|
4836
|
-
* { field: 'email', header: 'Email' }
|
|
4837
|
-
* ]" />
|
|
5026
|
+
* <tbw-grid [rows]="data" [columns]="['id:number', 'name', { field: 'status', editable: true }]" />
|
|
4838
5027
|
* ```
|
|
4839
5028
|
*/
|
|
4840
5029
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4841
5030
|
columns = input(...(ngDevMode ? [undefined, { debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
5031
|
+
/**
|
|
5032
|
+
* Default column properties applied to every column in `columns`.
|
|
5033
|
+
* Individual column properties override these defaults.
|
|
5034
|
+
*
|
|
5035
|
+
* @example
|
|
5036
|
+
* ```html
|
|
5037
|
+
* <tbw-grid
|
|
5038
|
+
* [columnDefaults]="{ sortable: true, resizable: true }"
|
|
5039
|
+
* [columns]="[{ field: 'id', sortable: false }, { field: 'name' }]"
|
|
5040
|
+
* />
|
|
5041
|
+
* ```
|
|
5042
|
+
*/
|
|
5043
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5044
|
+
columnDefaults = input(...(ngDevMode ? [undefined, { debugName: "columnDefaults" }] : /* istanbul ignore next */ []));
|
|
4842
5045
|
/**
|
|
4843
5046
|
* Column sizing strategy.
|
|
4844
5047
|
*
|
|
@@ -4912,6 +5115,9 @@ class Grid {
|
|
|
4912
5115
|
* <!-- Full config object -->
|
|
4913
5116
|
* <tbw-grid [selection]="{ mode: 'range', checkbox: true }" />
|
|
4914
5117
|
* ```
|
|
5118
|
+
*
|
|
5119
|
+
* @deprecated Use `GridSelectionDirective` from
|
|
5120
|
+
* `@toolbox-web/grid-angular/features/selection`. Will be removed in v2.0.0.
|
|
4915
5121
|
*/
|
|
4916
5122
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4917
5123
|
selection = input(...(ngDevMode ? [undefined, { debugName: "selection" }] : /* istanbul ignore next */ []));
|
|
@@ -4936,6 +5142,9 @@ class Grid {
|
|
|
4936
5142
|
* <!-- Full config with callbacks -->
|
|
4937
5143
|
* <tbw-grid [editing]="{ editOn: 'dblclick', onBeforeEditClose: myCallback }" />
|
|
4938
5144
|
* ```
|
|
5145
|
+
*
|
|
5146
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5147
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
4939
5148
|
*/
|
|
4940
5149
|
editing = input(...(ngDevMode ? [undefined, { debugName: "editing" }] : /* istanbul ignore next */ []));
|
|
4941
5150
|
/**
|
|
@@ -4950,6 +5159,9 @@ class Grid {
|
|
|
4950
5159
|
* ```html
|
|
4951
5160
|
* <tbw-grid [selection]="'range'" [clipboard]="true" />
|
|
4952
5161
|
* ```
|
|
5162
|
+
*
|
|
5163
|
+
* @deprecated Use `GridClipboardDirective` from
|
|
5164
|
+
* `@toolbox-web/grid-angular/features/clipboard`. Will be removed in v2.0.0.
|
|
4953
5165
|
*/
|
|
4954
5166
|
clipboard = input(...(ngDevMode ? [undefined, { debugName: "clipboard" }] : /* istanbul ignore next */ []));
|
|
4955
5167
|
/**
|
|
@@ -4964,6 +5176,9 @@ class Grid {
|
|
|
4964
5176
|
* ```html
|
|
4965
5177
|
* <tbw-grid [contextMenu]="true" />
|
|
4966
5178
|
* ```
|
|
5179
|
+
*
|
|
5180
|
+
* @deprecated Use `GridContextMenuDirective` from
|
|
5181
|
+
* `@toolbox-web/grid-angular/features/context-menu`. Will be removed in v2.0.0.
|
|
4967
5182
|
*/
|
|
4968
5183
|
contextMenu = input(...(ngDevMode ? [undefined, { debugName: "contextMenu" }] : /* istanbul ignore next */ []));
|
|
4969
5184
|
/**
|
|
@@ -4988,6 +5203,9 @@ class Grid {
|
|
|
4988
5203
|
* <!-- Full config -->
|
|
4989
5204
|
* <tbw-grid [multiSort]="{ maxSortColumns: 3 }" />
|
|
4990
5205
|
* ```
|
|
5206
|
+
*
|
|
5207
|
+
* @deprecated Use `GridMultiSortDirective` from
|
|
5208
|
+
* `@toolbox-web/grid-angular/features/multi-sort`. Will be removed in v2.0.0.
|
|
4991
5209
|
*/
|
|
4992
5210
|
multiSort = input(...(ngDevMode ? [undefined, { debugName: "multiSort" }] : /* istanbul ignore next */ []));
|
|
4993
5211
|
/**
|
|
@@ -5003,6 +5221,13 @@ class Grid {
|
|
|
5003
5221
|
* <tbw-grid [filtering]="true" />
|
|
5004
5222
|
* <tbw-grid [filtering]="{ debounceMs: 200 }" />
|
|
5005
5223
|
* ```
|
|
5224
|
+
*
|
|
5225
|
+
* @deprecated Use `GridFilteringDirective` from
|
|
5226
|
+
* `@toolbox-web/grid-angular/features/filtering` and add it to your
|
|
5227
|
+
* component's `imports`. The directive owns the `filtering` input + the
|
|
5228
|
+
* `filterChange` output and lets the typed surface tree-shake away when
|
|
5229
|
+
* the feature is not imported. This input remains as a non-breaking shim
|
|
5230
|
+
* and will be removed in v2.0.0.
|
|
5006
5231
|
*/
|
|
5007
5232
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5008
5233
|
filtering = input(...(ngDevMode ? [undefined, { debugName: "filtering" }] : /* istanbul ignore next */ []));
|
|
@@ -5018,6 +5243,9 @@ class Grid {
|
|
|
5018
5243
|
* ```html
|
|
5019
5244
|
* <tbw-grid [reorderColumns]="true" />
|
|
5020
5245
|
* ```
|
|
5246
|
+
*
|
|
5247
|
+
* @deprecated Use `GridReorderColumnsDirective` from
|
|
5248
|
+
* `@toolbox-web/grid-angular/features/reorder-columns`. Will be removed in v2.0.0.
|
|
5021
5249
|
*/
|
|
5022
5250
|
reorderColumns = input(...(ngDevMode ? [undefined, { debugName: "reorderColumns" }] : /* istanbul ignore next */ []));
|
|
5023
5251
|
/**
|
|
@@ -5032,6 +5260,9 @@ class Grid {
|
|
|
5032
5260
|
* ```html
|
|
5033
5261
|
* <tbw-grid [visibility]="true" />
|
|
5034
5262
|
* ```
|
|
5263
|
+
*
|
|
5264
|
+
* @deprecated Use `GridVisibilityDirective` from
|
|
5265
|
+
* `@toolbox-web/grid-angular/features/visibility`. Will be removed in v2.0.0.
|
|
5035
5266
|
*/
|
|
5036
5267
|
visibility = input(...(ngDevMode ? [undefined, { debugName: "visibility" }] : /* istanbul ignore next */ []));
|
|
5037
5268
|
/**
|
|
@@ -5051,6 +5282,9 @@ class Grid {
|
|
|
5051
5282
|
* { field: 'actions', pinned: 'right' }
|
|
5052
5283
|
* ]" />
|
|
5053
5284
|
* ```
|
|
5285
|
+
*
|
|
5286
|
+
* @deprecated Use `GridPinnedColumnsDirective` from
|
|
5287
|
+
* `@toolbox-web/grid-angular/features/pinned-columns`. Will be removed in v2.0.0.
|
|
5054
5288
|
*/
|
|
5055
5289
|
pinnedColumns = input(...(ngDevMode ? [undefined, { debugName: "pinnedColumns" }] : /* istanbul ignore next */ []));
|
|
5056
5290
|
/**
|
|
@@ -5065,6 +5299,9 @@ class Grid {
|
|
|
5065
5299
|
* ```html
|
|
5066
5300
|
* <tbw-grid [groupingColumns]="true" />
|
|
5067
5301
|
* ```
|
|
5302
|
+
*
|
|
5303
|
+
* @deprecated Use `GridGroupingColumnsDirective` from
|
|
5304
|
+
* `@toolbox-web/grid-angular/features/grouping-columns`. Will be removed in v2.0.0.
|
|
5068
5305
|
*/
|
|
5069
5306
|
groupingColumns = input(...(ngDevMode ? [undefined, { debugName: "groupingColumns" }] : /* istanbul ignore next */ []));
|
|
5070
5307
|
/**
|
|
@@ -5079,6 +5316,9 @@ class Grid {
|
|
|
5079
5316
|
* ```html
|
|
5080
5317
|
* <tbw-grid [columnVirtualization]="true" />
|
|
5081
5318
|
* ```
|
|
5319
|
+
*
|
|
5320
|
+
* @deprecated Use `GridColumnVirtualizationDirective` from
|
|
5321
|
+
* `@toolbox-web/grid-angular/features/column-virtualization`. Will be removed in v2.0.0.
|
|
5082
5322
|
*/
|
|
5083
5323
|
columnVirtualization = input(...(ngDevMode ? [undefined, { debugName: "columnVirtualization" }] : /* istanbul ignore next */ []));
|
|
5084
5324
|
/**
|
|
@@ -5104,6 +5344,9 @@ class Grid {
|
|
|
5104
5344
|
* ```html
|
|
5105
5345
|
* <tbw-grid [rowDragDrop]="{ dropZone: 'employees', operation: 'move' }" />
|
|
5106
5346
|
* ```
|
|
5347
|
+
*
|
|
5348
|
+
* @deprecated Use `GridRowDragDropDirective` from
|
|
5349
|
+
* `@toolbox-web/grid-angular/features/row-drag-drop`. Will be removed in v2.0.0.
|
|
5107
5350
|
*/
|
|
5108
5351
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5109
5352
|
rowDragDrop = input(...(ngDevMode ? [undefined, { debugName: "rowDragDrop" }] : /* istanbul ignore next */ []));
|
|
@@ -5119,6 +5362,9 @@ class Grid {
|
|
|
5119
5362
|
* ```html
|
|
5120
5363
|
* <tbw-grid [groupingRows]="{ groupBy: ['department'] }" />
|
|
5121
5364
|
* ```
|
|
5365
|
+
*
|
|
5366
|
+
* @deprecated Use `GridGroupingRowsDirective` from
|
|
5367
|
+
* `@toolbox-web/grid-angular/features/grouping-rows`. Will be removed in v2.0.0.
|
|
5122
5368
|
*/
|
|
5123
5369
|
groupingRows = input(...(ngDevMode ? [undefined, { debugName: "groupingRows" }] : /* istanbul ignore next */ []));
|
|
5124
5370
|
/**
|
|
@@ -5133,6 +5379,9 @@ class Grid {
|
|
|
5133
5379
|
* ```html
|
|
5134
5380
|
* <tbw-grid [pinnedRows]="{ bottom: [{ type: 'aggregation' }] }" />
|
|
5135
5381
|
* ```
|
|
5382
|
+
*
|
|
5383
|
+
* @deprecated Use `GridPinnedRowsDirective` from
|
|
5384
|
+
* `@toolbox-web/grid-angular/features/pinned-rows`. Will be removed in v2.0.0.
|
|
5136
5385
|
*/
|
|
5137
5386
|
pinnedRows = input(...(ngDevMode ? [undefined, { debugName: "pinnedRows" }] : /* istanbul ignore next */ []));
|
|
5138
5387
|
/**
|
|
@@ -5147,6 +5396,9 @@ class Grid {
|
|
|
5147
5396
|
* ```html
|
|
5148
5397
|
* <tbw-grid [tree]="{ childrenField: 'children' }" />
|
|
5149
5398
|
* ```
|
|
5399
|
+
*
|
|
5400
|
+
* @deprecated Use `GridTreeDirective` from
|
|
5401
|
+
* `@toolbox-web/grid-angular/features/tree`. Will be removed in v2.0.0.
|
|
5150
5402
|
*/
|
|
5151
5403
|
tree = input(...(ngDevMode ? [undefined, { debugName: "tree" }] : /* istanbul ignore next */ []));
|
|
5152
5404
|
/**
|
|
@@ -5161,6 +5413,9 @@ class Grid {
|
|
|
5161
5413
|
* ```html
|
|
5162
5414
|
* <tbw-grid [masterDetail]="{ detailRenderer: detailFn }" />
|
|
5163
5415
|
* ```
|
|
5416
|
+
*
|
|
5417
|
+
* @deprecated Use `GridMasterDetailDirective` from
|
|
5418
|
+
* `@toolbox-web/grid-angular/features/master-detail`. Will be removed in v2.0.0.
|
|
5164
5419
|
*/
|
|
5165
5420
|
masterDetail = input(...(ngDevMode ? [undefined, { debugName: "masterDetail" }] : /* istanbul ignore next */ []));
|
|
5166
5421
|
/**
|
|
@@ -5175,6 +5430,9 @@ class Grid {
|
|
|
5175
5430
|
* ```html
|
|
5176
5431
|
* <tbw-grid [responsive]="{ breakpoint: 768 }" />
|
|
5177
5432
|
* ```
|
|
5433
|
+
*
|
|
5434
|
+
* @deprecated Use `GridResponsiveDirective` from
|
|
5435
|
+
* `@toolbox-web/grid-angular/features/responsive`. Will be removed in v2.0.0.
|
|
5178
5436
|
*/
|
|
5179
5437
|
responsive = input(...(ngDevMode ? [undefined, { debugName: "responsive" }] : /* istanbul ignore next */ []));
|
|
5180
5438
|
/**
|
|
@@ -5189,6 +5447,9 @@ class Grid {
|
|
|
5189
5447
|
* ```html
|
|
5190
5448
|
* <tbw-grid [editing]="'dblclick'" [undoRedo]="true" />
|
|
5191
5449
|
* ```
|
|
5450
|
+
*
|
|
5451
|
+
* @deprecated Use `GridUndoRedoDirective` from
|
|
5452
|
+
* `@toolbox-web/grid-angular/features/undo-redo`. Will be removed in v2.0.0.
|
|
5192
5453
|
*/
|
|
5193
5454
|
undoRedo = input(...(ngDevMode ? [undefined, { debugName: "undoRedo" }] : /* istanbul ignore next */ []));
|
|
5194
5455
|
/**
|
|
@@ -5204,6 +5465,9 @@ class Grid {
|
|
|
5204
5465
|
* <tbw-grid [export]="true" />
|
|
5205
5466
|
* <tbw-grid [export]="{ filename: 'data.csv' }" />
|
|
5206
5467
|
* ```
|
|
5468
|
+
*
|
|
5469
|
+
* @deprecated Use `GridExportDirective` from
|
|
5470
|
+
* `@toolbox-web/grid-angular/features/export`. Will be removed in v2.0.0.
|
|
5207
5471
|
*/
|
|
5208
5472
|
exportFeature = input(undefined, { ...(ngDevMode ? { debugName: "exportFeature" } : /* istanbul ignore next */ {}), alias: 'export' });
|
|
5209
5473
|
/**
|
|
@@ -5218,6 +5482,9 @@ class Grid {
|
|
|
5218
5482
|
* ```html
|
|
5219
5483
|
* <tbw-grid [print]="true" />
|
|
5220
5484
|
* ```
|
|
5485
|
+
*
|
|
5486
|
+
* @deprecated Use `GridPrintDirective` from
|
|
5487
|
+
* `@toolbox-web/grid-angular/features/print`. Will be removed in v2.0.0.
|
|
5221
5488
|
*/
|
|
5222
5489
|
print = input(...(ngDevMode ? [undefined, { debugName: "print" }] : /* istanbul ignore next */ []));
|
|
5223
5490
|
/**
|
|
@@ -5232,6 +5499,9 @@ class Grid {
|
|
|
5232
5499
|
* ```html
|
|
5233
5500
|
* <tbw-grid [pivot]="{ rowFields: ['category'], valueField: 'sales' }" />
|
|
5234
5501
|
* ```
|
|
5502
|
+
*
|
|
5503
|
+
* @deprecated Use `GridPivotDirective` from
|
|
5504
|
+
* `@toolbox-web/grid-angular/features/pivot`. Will be removed in v2.0.0.
|
|
5235
5505
|
*/
|
|
5236
5506
|
pivot = input(...(ngDevMode ? [undefined, { debugName: "pivot" }] : /* istanbul ignore next */ []));
|
|
5237
5507
|
/**
|
|
@@ -5246,6 +5516,9 @@ class Grid {
|
|
|
5246
5516
|
* ```html
|
|
5247
5517
|
* <tbw-grid [serverSide]="{ dataSource: fetchDataFn }" />
|
|
5248
5518
|
* ```
|
|
5519
|
+
*
|
|
5520
|
+
* @deprecated Use `GridServerSideDirective` from
|
|
5521
|
+
* `@toolbox-web/grid-angular/features/server-side`. Will be removed in v2.0.0.
|
|
5249
5522
|
*/
|
|
5250
5523
|
serverSide = input(...(ngDevMode ? [undefined, { debugName: "serverSide" }] : /* istanbul ignore next */ []));
|
|
5251
5524
|
/**
|
|
@@ -5256,6 +5529,9 @@ class Grid {
|
|
|
5256
5529
|
* <tbw-grid [tooltip]="true" />
|
|
5257
5530
|
* <tbw-grid [tooltip]="{ header: true, cell: false }" />
|
|
5258
5531
|
* ```
|
|
5532
|
+
*
|
|
5533
|
+
* @deprecated Use `GridTooltipDirective` from
|
|
5534
|
+
* `@toolbox-web/grid-angular/features/tooltip`. Will be removed in v2.0.0.
|
|
5259
5535
|
*/
|
|
5260
5536
|
tooltip = input(...(ngDevMode ? [undefined, { debugName: "tooltip" }] : /* istanbul ignore next */ []));
|
|
5261
5537
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -5315,8 +5591,85 @@ class Grid {
|
|
|
5315
5591
|
* console.log(`Changed ${event.field} to ${event.value} in row ${event.rowIndex}`);
|
|
5316
5592
|
* }
|
|
5317
5593
|
* ```
|
|
5594
|
+
*
|
|
5595
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5596
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
5318
5597
|
*/
|
|
5319
5598
|
cellCommit = output();
|
|
5599
|
+
/**
|
|
5600
|
+
* Emitted when a cell edit is cancelled (Escape, click outside without
|
|
5601
|
+
* commit, or `editor.cancel()`).
|
|
5602
|
+
*
|
|
5603
|
+
* @example
|
|
5604
|
+
* ```html
|
|
5605
|
+
* <tbw-grid (cellCancel)="onCellCancel($event)">...</tbw-grid>
|
|
5606
|
+
* ```
|
|
5607
|
+
*
|
|
5608
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5609
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
5610
|
+
*/
|
|
5611
|
+
cellCancel = output();
|
|
5612
|
+
/**
|
|
5613
|
+
* Emitted when a cell editor opens.
|
|
5614
|
+
*
|
|
5615
|
+
* @example
|
|
5616
|
+
* ```html
|
|
5617
|
+
* <tbw-grid (editOpen)="onEditOpen($event)">...</tbw-grid>
|
|
5618
|
+
* ```
|
|
5619
|
+
*
|
|
5620
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5621
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
5622
|
+
*/
|
|
5623
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5624
|
+
editOpen = output();
|
|
5625
|
+
/**
|
|
5626
|
+
* Emitted before an editor closes. Useful for last-chance validation.
|
|
5627
|
+
*
|
|
5628
|
+
* @example
|
|
5629
|
+
* ```html
|
|
5630
|
+
* <tbw-grid (beforeEditClose)="onBeforeEditClose($event)">...</tbw-grid>
|
|
5631
|
+
* ```
|
|
5632
|
+
*
|
|
5633
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5634
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
5635
|
+
*/
|
|
5636
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5637
|
+
beforeEditClose = output();
|
|
5638
|
+
/**
|
|
5639
|
+
* Emitted after an editor closes (whether committed or cancelled).
|
|
5640
|
+
*
|
|
5641
|
+
* @example
|
|
5642
|
+
* ```html
|
|
5643
|
+
* <tbw-grid (editClose)="onEditClose($event)">...</tbw-grid>
|
|
5644
|
+
* ```
|
|
5645
|
+
*
|
|
5646
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5647
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
5648
|
+
*/
|
|
5649
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5650
|
+
editClose = output();
|
|
5651
|
+
/**
|
|
5652
|
+
* Emitted when the dirty / changed-rows state transitions.
|
|
5653
|
+
*
|
|
5654
|
+
* @example
|
|
5655
|
+
* ```html
|
|
5656
|
+
* <tbw-grid (dirtyChange)="onDirtyChange($event)">...</tbw-grid>
|
|
5657
|
+
* ```
|
|
5658
|
+
*
|
|
5659
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5660
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
5661
|
+
*/
|
|
5662
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5663
|
+
dirtyChange = output();
|
|
5664
|
+
/**
|
|
5665
|
+
* Emitted when row data is replaced (e.g. via the `rows` setter).
|
|
5666
|
+
*
|
|
5667
|
+
* @example
|
|
5668
|
+
* ```html
|
|
5669
|
+
* <tbw-grid (dataChange)="onDataChange($event)">...</tbw-grid>
|
|
5670
|
+
* ```
|
|
5671
|
+
*/
|
|
5672
|
+
dataChange = output();
|
|
5320
5673
|
/**
|
|
5321
5674
|
* Emitted when a row's values are committed (bulk/row editing).
|
|
5322
5675
|
* Provides the row data and change tracking information.
|
|
@@ -5325,6 +5678,9 @@ class Grid {
|
|
|
5325
5678
|
* ```html
|
|
5326
5679
|
* <tbw-grid (rowCommit)="onRowCommit($event)">...</tbw-grid>
|
|
5327
5680
|
* ```
|
|
5681
|
+
*
|
|
5682
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5683
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
5328
5684
|
*/
|
|
5329
5685
|
rowCommit = output();
|
|
5330
5686
|
/**
|
|
@@ -5334,6 +5690,9 @@ class Grid {
|
|
|
5334
5690
|
* ```html
|
|
5335
5691
|
* <tbw-grid (changedRowsReset)="onChangedRowsReset($event)">...</tbw-grid>
|
|
5336
5692
|
* ```
|
|
5693
|
+
*
|
|
5694
|
+
* @deprecated Use `GridEditingDirective` from
|
|
5695
|
+
* `@toolbox-web/grid-angular/features/editing`. Will be removed in v2.0.0.
|
|
5337
5696
|
*/
|
|
5338
5697
|
changedRowsReset = output();
|
|
5339
5698
|
/**
|
|
@@ -5352,6 +5711,11 @@ class Grid {
|
|
|
5352
5711
|
* ```html
|
|
5353
5712
|
* <tbw-grid (filterChange)="onFilterChange($event)">...</tbw-grid>
|
|
5354
5713
|
* ```
|
|
5714
|
+
*
|
|
5715
|
+
* @deprecated Use `GridFilteringDirective` from
|
|
5716
|
+
* `@toolbox-web/grid-angular/features/filtering` (the directive
|
|
5717
|
+
* declares the `(filterChange)` output). This output remains as a
|
|
5718
|
+
* non-breaking shim and will be removed in v2.0.0.
|
|
5355
5719
|
*/
|
|
5356
5720
|
filterChange = output();
|
|
5357
5721
|
/**
|
|
@@ -5363,6 +5727,15 @@ class Grid {
|
|
|
5363
5727
|
* ```
|
|
5364
5728
|
*/
|
|
5365
5729
|
columnResize = output();
|
|
5730
|
+
/**
|
|
5731
|
+
* Emitted when a column's width is reset (double-click on the resize handle).
|
|
5732
|
+
*
|
|
5733
|
+
* @example
|
|
5734
|
+
* ```html
|
|
5735
|
+
* <tbw-grid (columnResizeReset)="onColumnResizeReset($event)">...</tbw-grid>
|
|
5736
|
+
* ```
|
|
5737
|
+
*/
|
|
5738
|
+
columnResizeReset = output();
|
|
5366
5739
|
/**
|
|
5367
5740
|
* Emitted when a column is moved via drag-and-drop.
|
|
5368
5741
|
*
|
|
@@ -5370,15 +5743,23 @@ class Grid {
|
|
|
5370
5743
|
* ```html
|
|
5371
5744
|
* <tbw-grid (columnMove)="onColumnMove($event)">...</tbw-grid>
|
|
5372
5745
|
* ```
|
|
5746
|
+
*
|
|
5747
|
+
* @deprecated Use `GridReorderColumnsDirective` from
|
|
5748
|
+
* `@toolbox-web/grid-angular/features/reorder-columns`. Will be removed in v2.0.0.
|
|
5373
5749
|
*/
|
|
5374
5750
|
columnMove = output();
|
|
5375
5751
|
/**
|
|
5376
|
-
* Emitted when column visibility
|
|
5752
|
+
* Emitted when a column is shown or hidden — either via the visibility
|
|
5753
|
+
* sidebar, `grid.toggleColumnVisibility(field)`, `grid.setColumnVisible(field, visible)`,
|
|
5754
|
+
* or `grid.showAllColumns()`.
|
|
5377
5755
|
*
|
|
5378
5756
|
* @example
|
|
5379
5757
|
* ```html
|
|
5380
5758
|
* <tbw-grid (columnVisibility)="onColumnVisibility($event)">...</tbw-grid>
|
|
5381
5759
|
* ```
|
|
5760
|
+
*
|
|
5761
|
+
* @deprecated Use `GridVisibilityDirective` from
|
|
5762
|
+
* `@toolbox-web/grid-angular/features/visibility`. Will be removed in v2.0.0.
|
|
5382
5763
|
*/
|
|
5383
5764
|
columnVisibility = output();
|
|
5384
5765
|
/**
|
|
@@ -5397,6 +5778,9 @@ class Grid {
|
|
|
5397
5778
|
* ```html
|
|
5398
5779
|
* <tbw-grid (selectionChange)="onSelectionChange($event)">...</tbw-grid>
|
|
5399
5780
|
* ```
|
|
5781
|
+
*
|
|
5782
|
+
* @deprecated Use `GridSelectionDirective` from
|
|
5783
|
+
* `@toolbox-web/grid-angular/features/selection`. Will be removed in v2.0.0.
|
|
5400
5784
|
*/
|
|
5401
5785
|
selectionChange = output();
|
|
5402
5786
|
/**
|
|
@@ -5406,6 +5790,9 @@ class Grid {
|
|
|
5406
5790
|
* ```html
|
|
5407
5791
|
* <tbw-grid (rowMove)="onRowMove($event)">...</tbw-grid>
|
|
5408
5792
|
* ```
|
|
5793
|
+
*
|
|
5794
|
+
* @deprecated Use `GridRowDragDropDirective` from
|
|
5795
|
+
* `@toolbox-web/grid-angular/features/row-drag-drop`. Will be removed in v2.0.0.
|
|
5409
5796
|
*/
|
|
5410
5797
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5411
5798
|
rowMove = output();
|
|
@@ -5416,23 +5803,35 @@ class Grid {
|
|
|
5416
5803
|
* ```html
|
|
5417
5804
|
* <tbw-grid (rowDragStart)="onRowDragStart($event)">...</tbw-grid>
|
|
5418
5805
|
* ```
|
|
5806
|
+
*
|
|
5807
|
+
* @deprecated Use `GridRowDragDropDirective` from
|
|
5808
|
+
* `@toolbox-web/grid-angular/features/row-drag-drop`. Will be removed in v2.0.0.
|
|
5419
5809
|
*/
|
|
5420
5810
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5421
5811
|
rowDragStart = output();
|
|
5422
5812
|
/**
|
|
5423
5813
|
* Emitted when a row drag ends (after drop or cancel).
|
|
5814
|
+
*
|
|
5815
|
+
* @deprecated Use `GridRowDragDropDirective` from
|
|
5816
|
+
* `@toolbox-web/grid-angular/features/row-drag-drop`. Will be removed in v2.0.0.
|
|
5424
5817
|
*/
|
|
5425
5818
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5426
5819
|
rowDragEnd = output();
|
|
5427
5820
|
/**
|
|
5428
5821
|
* Emitted on the target grid when rows are dropped from another grid.
|
|
5429
5822
|
* Cancelable via `event.preventDefault()`.
|
|
5823
|
+
*
|
|
5824
|
+
* @deprecated Use `GridRowDragDropDirective` from
|
|
5825
|
+
* `@toolbox-web/grid-angular/features/row-drag-drop`. Will be removed in v2.0.0.
|
|
5430
5826
|
*/
|
|
5431
5827
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5432
5828
|
rowDrop = output();
|
|
5433
5829
|
/**
|
|
5434
5830
|
* Emitted on BOTH source and target grids after a successful cross-grid
|
|
5435
5831
|
* row transfer.
|
|
5832
|
+
*
|
|
5833
|
+
* @deprecated Use `GridRowDragDropDirective` from
|
|
5834
|
+
* `@toolbox-web/grid-angular/features/row-drag-drop`. Will be removed in v2.0.0.
|
|
5436
5835
|
*/
|
|
5437
5836
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5438
5837
|
rowTransfer = output();
|
|
@@ -5443,8 +5842,35 @@ class Grid {
|
|
|
5443
5842
|
* ```html
|
|
5444
5843
|
* <tbw-grid (groupToggle)="onGroupToggle($event)">...</tbw-grid>
|
|
5445
5844
|
* ```
|
|
5845
|
+
*
|
|
5846
|
+
* @deprecated Use `GridGroupingRowsDirective` from
|
|
5847
|
+
* `@toolbox-web/grid-angular/features/grouping-rows`. Will be removed in v2.0.0.
|
|
5446
5848
|
*/
|
|
5447
5849
|
groupToggle = output();
|
|
5850
|
+
/**
|
|
5851
|
+
* Emitted when a group is expanded.
|
|
5852
|
+
*
|
|
5853
|
+
* @example
|
|
5854
|
+
* ```html
|
|
5855
|
+
* <tbw-grid (groupExpand)="onGroupExpand($event)">...</tbw-grid>
|
|
5856
|
+
* ```
|
|
5857
|
+
*
|
|
5858
|
+
* @deprecated Use `GridGroupingRowsDirective` from
|
|
5859
|
+
* `@toolbox-web/grid-angular/features/grouping-rows`. Will be removed in v2.0.0.
|
|
5860
|
+
*/
|
|
5861
|
+
groupExpand = output();
|
|
5862
|
+
/**
|
|
5863
|
+
* Emitted when a group is collapsed.
|
|
5864
|
+
*
|
|
5865
|
+
* @example
|
|
5866
|
+
* ```html
|
|
5867
|
+
* <tbw-grid (groupCollapse)="onGroupCollapse($event)">...</tbw-grid>
|
|
5868
|
+
* ```
|
|
5869
|
+
*
|
|
5870
|
+
* @deprecated Use `GridGroupingRowsDirective` from
|
|
5871
|
+
* `@toolbox-web/grid-angular/features/grouping-rows`. Will be removed in v2.0.0.
|
|
5872
|
+
*/
|
|
5873
|
+
groupCollapse = output();
|
|
5448
5874
|
/**
|
|
5449
5875
|
* Emitted when a tree node is expanded.
|
|
5450
5876
|
*
|
|
@@ -5452,6 +5878,9 @@ class Grid {
|
|
|
5452
5878
|
* ```html
|
|
5453
5879
|
* <tbw-grid (treeExpand)="onTreeExpand($event)">...</tbw-grid>
|
|
5454
5880
|
* ```
|
|
5881
|
+
*
|
|
5882
|
+
* @deprecated Use `GridTreeDirective` from
|
|
5883
|
+
* `@toolbox-web/grid-angular/features/tree`. Will be removed in v2.0.0.
|
|
5455
5884
|
*/
|
|
5456
5885
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5457
5886
|
treeExpand = output();
|
|
@@ -5462,6 +5891,9 @@ class Grid {
|
|
|
5462
5891
|
* ```html
|
|
5463
5892
|
* <tbw-grid (detailExpand)="onDetailExpand($event)">...</tbw-grid>
|
|
5464
5893
|
* ```
|
|
5894
|
+
*
|
|
5895
|
+
* @deprecated Use `GridMasterDetailDirective` from
|
|
5896
|
+
* `@toolbox-web/grid-angular/features/master-detail`. Will be removed in v2.0.0.
|
|
5465
5897
|
*/
|
|
5466
5898
|
detailExpand = output();
|
|
5467
5899
|
/**
|
|
@@ -5471,8 +5903,23 @@ class Grid {
|
|
|
5471
5903
|
* ```html
|
|
5472
5904
|
* <tbw-grid (responsiveChange)="onResponsiveChange($event)">...</tbw-grid>
|
|
5473
5905
|
* ```
|
|
5906
|
+
*
|
|
5907
|
+
* @deprecated Use `GridResponsiveDirective` from
|
|
5908
|
+
* `@toolbox-web/grid-angular/features/responsive`. Will be removed in v2.0.0.
|
|
5474
5909
|
*/
|
|
5475
5910
|
responsiveChange = output();
|
|
5911
|
+
/**
|
|
5912
|
+
* Emitted when the context menu opens.
|
|
5913
|
+
*
|
|
5914
|
+
* @example
|
|
5915
|
+
* ```html
|
|
5916
|
+
* <tbw-grid (contextMenuOpen)="onContextMenuOpen($event)">...</tbw-grid>
|
|
5917
|
+
* ```
|
|
5918
|
+
*
|
|
5919
|
+
* @deprecated Use `GridContextMenuDirective` from
|
|
5920
|
+
* `@toolbox-web/grid-angular/features/context-menu`. Will be removed in v2.0.0.
|
|
5921
|
+
*/
|
|
5922
|
+
contextMenuOpen = output();
|
|
5476
5923
|
/**
|
|
5477
5924
|
* Emitted when cells are copied to clipboard.
|
|
5478
5925
|
*
|
|
@@ -5480,6 +5927,9 @@ class Grid {
|
|
|
5480
5927
|
* ```html
|
|
5481
5928
|
* <tbw-grid (copy)="onCopy($event)">...</tbw-grid>
|
|
5482
5929
|
* ```
|
|
5930
|
+
*
|
|
5931
|
+
* @deprecated Use `GridClipboardDirective` from
|
|
5932
|
+
* `@toolbox-web/grid-angular/features/clipboard`. Will be removed in v2.0.0.
|
|
5483
5933
|
*/
|
|
5484
5934
|
copy = output();
|
|
5485
5935
|
/**
|
|
@@ -5489,17 +5939,35 @@ class Grid {
|
|
|
5489
5939
|
* ```html
|
|
5490
5940
|
* <tbw-grid (paste)="onPaste($event)">...</tbw-grid>
|
|
5491
5941
|
* ```
|
|
5942
|
+
*
|
|
5943
|
+
* @deprecated Use `GridClipboardDirective` from
|
|
5944
|
+
* `@toolbox-web/grid-angular/features/clipboard`. Will be removed in v2.0.0.
|
|
5492
5945
|
*/
|
|
5493
5946
|
paste = output();
|
|
5494
5947
|
/**
|
|
5495
|
-
* Emitted when undo
|
|
5948
|
+
* Emitted when an undo action is performed.
|
|
5949
|
+
*
|
|
5950
|
+
* @example
|
|
5951
|
+
* ```html
|
|
5952
|
+
* <tbw-grid (undo)="onUndo($event)">...</tbw-grid>
|
|
5953
|
+
* ```
|
|
5954
|
+
*
|
|
5955
|
+
* @deprecated Use `GridUndoRedoDirective` from
|
|
5956
|
+
* `@toolbox-web/grid-angular/features/undo-redo`. Will be removed in v2.0.0.
|
|
5957
|
+
*/
|
|
5958
|
+
undo = output();
|
|
5959
|
+
/**
|
|
5960
|
+
* Emitted when a redo action is performed.
|
|
5496
5961
|
*
|
|
5497
5962
|
* @example
|
|
5498
5963
|
* ```html
|
|
5499
|
-
* <tbw-grid (
|
|
5964
|
+
* <tbw-grid (redo)="onRedo($event)">...</tbw-grid>
|
|
5500
5965
|
* ```
|
|
5966
|
+
*
|
|
5967
|
+
* @deprecated Use `GridUndoRedoDirective` from
|
|
5968
|
+
* `@toolbox-web/grid-angular/features/undo-redo`. Will be removed in v2.0.0.
|
|
5501
5969
|
*/
|
|
5502
|
-
|
|
5970
|
+
redo = output();
|
|
5503
5971
|
/**
|
|
5504
5972
|
* Emitted when export completes.
|
|
5505
5973
|
*
|
|
@@ -5507,6 +5975,9 @@ class Grid {
|
|
|
5507
5975
|
* ```html
|
|
5508
5976
|
* <tbw-grid (exportComplete)="onExportComplete($event)">...</tbw-grid>
|
|
5509
5977
|
* ```
|
|
5978
|
+
*
|
|
5979
|
+
* @deprecated Use `GridExportDirective` from
|
|
5980
|
+
* `@toolbox-web/grid-angular/features/export`. Will be removed in v2.0.0.
|
|
5510
5981
|
*/
|
|
5511
5982
|
exportComplete = output();
|
|
5512
5983
|
/**
|
|
@@ -5516,6 +5987,9 @@ class Grid {
|
|
|
5516
5987
|
* ```html
|
|
5517
5988
|
* <tbw-grid (printStart)="onPrintStart($event)">...</tbw-grid>
|
|
5518
5989
|
* ```
|
|
5990
|
+
*
|
|
5991
|
+
* @deprecated Use `GridPrintDirective` from
|
|
5992
|
+
* `@toolbox-web/grid-angular/features/print`. Will be removed in v2.0.0.
|
|
5519
5993
|
*/
|
|
5520
5994
|
printStart = output();
|
|
5521
5995
|
/**
|
|
@@ -5525,6 +5999,9 @@ class Grid {
|
|
|
5525
5999
|
* ```html
|
|
5526
6000
|
* <tbw-grid (printComplete)="onPrintComplete($event)">...</tbw-grid>
|
|
5527
6001
|
* ```
|
|
6002
|
+
*
|
|
6003
|
+
* @deprecated Use `GridPrintDirective` from
|
|
6004
|
+
* `@toolbox-web/grid-angular/features/print`. Will be removed in v2.0.0.
|
|
5528
6005
|
*/
|
|
5529
6006
|
printComplete = output();
|
|
5530
6007
|
/**
|
|
@@ -5543,18 +6020,31 @@ class Grid {
|
|
|
5543
6020
|
* ```
|
|
5544
6021
|
*/
|
|
5545
6022
|
tbwScroll = output();
|
|
5546
|
-
// Map of output names to event names for automatic wiring
|
|
6023
|
+
// Map of output names to event names for automatic wiring.
|
|
6024
|
+
//
|
|
6025
|
+
// The `satisfies` clause enforces compile-time sync against
|
|
6026
|
+
// `DataGridEventMap`: every value must be a real event name (typos and
|
|
6027
|
+
// stale entries pointing at non-existent events fail to compile).
|
|
6028
|
+
// Plugin event augmentations of `DataGridEventMap` flow through
|
|
6029
|
+
// automatically via the `/all` import.
|
|
5547
6030
|
eventOutputMap = {
|
|
5548
6031
|
cellClick: 'cell-click',
|
|
5549
6032
|
rowClick: 'row-click',
|
|
5550
6033
|
cellActivate: 'cell-activate',
|
|
5551
6034
|
cellChange: 'cell-change',
|
|
5552
6035
|
cellCommit: 'cell-commit',
|
|
6036
|
+
cellCancel: 'cell-cancel',
|
|
5553
6037
|
rowCommit: 'row-commit',
|
|
5554
6038
|
changedRowsReset: 'changed-rows-reset',
|
|
6039
|
+
editOpen: 'edit-open',
|
|
6040
|
+
beforeEditClose: 'before-edit-close',
|
|
6041
|
+
editClose: 'edit-close',
|
|
6042
|
+
dirtyChange: 'dirty-change',
|
|
6043
|
+
dataChange: 'data-change',
|
|
5555
6044
|
sortChange: 'sort-change',
|
|
5556
6045
|
filterChange: 'filter-change',
|
|
5557
6046
|
columnResize: 'column-resize',
|
|
6047
|
+
columnResizeReset: 'column-resize-reset',
|
|
5558
6048
|
columnMove: 'column-move',
|
|
5559
6049
|
columnVisibility: 'column-visibility',
|
|
5560
6050
|
columnStateChange: 'column-state-change',
|
|
@@ -5565,17 +6055,39 @@ class Grid {
|
|
|
5565
6055
|
rowDrop: 'row-drop',
|
|
5566
6056
|
rowTransfer: 'row-transfer',
|
|
5567
6057
|
groupToggle: 'group-toggle',
|
|
6058
|
+
groupExpand: 'group-expand',
|
|
6059
|
+
groupCollapse: 'group-collapse',
|
|
5568
6060
|
treeExpand: 'tree-expand',
|
|
5569
6061
|
detailExpand: 'detail-expand',
|
|
5570
6062
|
responsiveChange: 'responsive-change',
|
|
6063
|
+
contextMenuOpen: 'context-menu-open',
|
|
5571
6064
|
copy: 'copy',
|
|
5572
6065
|
paste: 'paste',
|
|
5573
|
-
|
|
6066
|
+
undo: 'undo',
|
|
6067
|
+
redo: 'redo',
|
|
5574
6068
|
exportComplete: 'export-complete',
|
|
5575
6069
|
printStart: 'print-start',
|
|
5576
6070
|
printComplete: 'print-complete',
|
|
5577
6071
|
tbwScroll: 'tbw-scroll',
|
|
5578
6072
|
};
|
|
6073
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
6074
|
+
// Forward-only event coverage guard.
|
|
6075
|
+
//
|
|
6076
|
+
// Mirrors the React adapter's `_AssertFeaturePropsCoverCore` pattern. If a
|
|
6077
|
+
// new event is added to core's `DataGridEventMap` (via plugin module
|
|
6078
|
+
// augmentation in `/all`) but no `eventOutputMap` entry covers it, this
|
|
6079
|
+
// type fails to evaluate to `true` and the build breaks. Adapter consumers
|
|
6080
|
+
// never see a silently-dropped event.
|
|
6081
|
+
//
|
|
6082
|
+
// Reverse direction (extra `eventOutputMap` entries pointing at non-existent
|
|
6083
|
+
// events) is already enforced by the `satisfies` clause above.
|
|
6084
|
+
//
|
|
6085
|
+
// To consciously omit an event from the Angular surface, add it to the
|
|
6086
|
+
// `IntentionallyOmittedEvents` union below with a comment explaining why.
|
|
6087
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
6088
|
+
/** Events deliberately not exposed as Angular outputs. Keep empty unless documented. */
|
|
6089
|
+
_intentionallyOmittedEvents;
|
|
6090
|
+
_assertEventOutputMapCoversCore;
|
|
5579
6091
|
// Store event listeners for cleanup
|
|
5580
6092
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5581
6093
|
eventListeners = new Map();
|
|
@@ -5594,10 +6106,18 @@ class Grid {
|
|
|
5594
6106
|
}
|
|
5595
6107
|
/**
|
|
5596
6108
|
* Sets up event listeners for all outputs using the eventOutputMap.
|
|
6109
|
+
*
|
|
6110
|
+
* Hybrid v1.x / v2 ownership: events claimed by an attribute-selector
|
|
6111
|
+
* feature directive (via `claimEvent` in `feature-claims.ts`) are skipped
|
|
6112
|
+
* here so the directive's own `output()` is the sole emitter. Without
|
|
6113
|
+
* this skip both this directive's deprecated output and the directive's
|
|
6114
|
+
* new output would fire for the same DOM event.
|
|
5597
6115
|
*/
|
|
5598
6116
|
setupEventListeners(grid) {
|
|
5599
6117
|
// Wire up all event listeners
|
|
5600
6118
|
for (const [outputName, eventName] of Object.entries(this.eventOutputMap)) {
|
|
6119
|
+
if (isEventClaimed(grid, eventName))
|
|
6120
|
+
continue;
|
|
5601
6121
|
const listener = (e) => {
|
|
5602
6122
|
const detail = e.detail;
|
|
5603
6123
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -5610,57 +6130,62 @@ class Grid {
|
|
|
5610
6130
|
/**
|
|
5611
6131
|
* Creates plugins from feature inputs.
|
|
5612
6132
|
* Uses the feature registry to allow tree-shaking - only imported features are bundled.
|
|
6133
|
+
* Per-feature config bridging (e.g. converting Angular component classes inside
|
|
6134
|
+
* `groupingColumns` / `groupingRows` / `pinnedRows` configs to renderer functions)
|
|
6135
|
+
* runs via `getFeatureConfigPreprocessor`, populated by feature secondary entries.
|
|
6136
|
+
*
|
|
6137
|
+
* Hybrid v1.x / v2 ownership: when an attribute-selector feature directive
|
|
6138
|
+
* (e.g. `GridFilteringDirective`) is present on the same `<tbw-grid>`
|
|
6139
|
+
* element it claims its feature in `feature-claims.ts`. We then read the
|
|
6140
|
+
* claim's config getter — which transitively reads the directive's input
|
|
6141
|
+
* signal, establishing reactive dependency tracking — instead of the
|
|
6142
|
+
* deprecated input on this directive. This keeps the existing `[filtering]`
|
|
6143
|
+
* binding working when used directly on `<tbw-grid>` (no directive, no
|
|
6144
|
+
* claim) while letting the directive own the binding when imported.
|
|
6145
|
+
*
|
|
5613
6146
|
* Returns the array of created plugins (doesn't modify grid).
|
|
5614
6147
|
*/
|
|
5615
6148
|
createFeaturePlugins() {
|
|
5616
6149
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5617
6150
|
const plugins = [];
|
|
6151
|
+
const adapter = this.adapter;
|
|
6152
|
+
const grid = this.elementRef.nativeElement;
|
|
5618
6153
|
// Helper to add plugin if feature is registered
|
|
5619
|
-
const addPlugin = (name,
|
|
6154
|
+
const addPlugin = (name, ownInput) => {
|
|
6155
|
+
// Directive-owned config wins. Reading the claim's getter inside this
|
|
6156
|
+
// effect registers the directive's input signal as a dependency, so
|
|
6157
|
+
// changes to e.g. `[filtering]` on the directive re-trigger this effect.
|
|
6158
|
+
const claim = getFeatureClaim(grid, name);
|
|
6159
|
+
const config = claim ? claim() : ownInput;
|
|
5620
6160
|
if (config === undefined || config === null || config === false)
|
|
5621
6161
|
return;
|
|
5622
|
-
|
|
6162
|
+
// Apply per-feature config preprocessor (registered by feature secondary entries)
|
|
6163
|
+
// to bridge Angular component classes embedded in the config before instantiation.
|
|
6164
|
+
let finalConfig = config;
|
|
6165
|
+
if (adapter && config !== true && typeof config === 'object') {
|
|
6166
|
+
const preprocess = getFeatureConfigPreprocessor(name);
|
|
6167
|
+
if (preprocess)
|
|
6168
|
+
finalConfig = preprocess(config, adapter);
|
|
6169
|
+
}
|
|
6170
|
+
const plugin = createPluginFromFeature(name, finalConfig);
|
|
5623
6171
|
if (plugin)
|
|
5624
6172
|
plugins.push(plugin);
|
|
5625
6173
|
};
|
|
5626
|
-
// Add plugins for each feature input
|
|
5627
6174
|
addPlugin('selection', this.selection());
|
|
5628
6175
|
addPlugin('editing', this.editing());
|
|
5629
6176
|
addPlugin('clipboard', this.clipboard());
|
|
5630
6177
|
addPlugin('contextMenu', this.contextMenu());
|
|
5631
|
-
// multiSort is the primary input
|
|
5632
6178
|
addPlugin('multiSort', this.multiSort());
|
|
5633
6179
|
addPlugin('filtering', this.filtering());
|
|
5634
6180
|
addPlugin('reorderColumns', this.reorderColumns());
|
|
5635
6181
|
addPlugin('visibility', this.visibility());
|
|
5636
6182
|
addPlugin('pinnedColumns', this.pinnedColumns());
|
|
5637
|
-
|
|
5638
|
-
const gcConfig = this.groupingColumns();
|
|
5639
|
-
if (gcConfig && typeof gcConfig === 'object' && this.adapter) {
|
|
5640
|
-
addPlugin('groupingColumns', this.adapter.processGroupingColumnsConfig(gcConfig));
|
|
5641
|
-
}
|
|
5642
|
-
else {
|
|
5643
|
-
addPlugin('groupingColumns', gcConfig);
|
|
5644
|
-
}
|
|
6183
|
+
addPlugin('groupingColumns', this.groupingColumns());
|
|
5645
6184
|
addPlugin('columnVirtualization', this.columnVirtualization());
|
|
5646
6185
|
addPlugin('reorderRows', this.reorderRows());
|
|
5647
6186
|
addPlugin('rowDragDrop', this.rowDragDrop());
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
if (grConfig && typeof grConfig === 'object' && this.adapter) {
|
|
5651
|
-
addPlugin('groupingRows', this.adapter.processGroupingRowsConfig(grConfig));
|
|
5652
|
-
}
|
|
5653
|
-
else {
|
|
5654
|
-
addPlugin('groupingRows', grConfig);
|
|
5655
|
-
}
|
|
5656
|
-
// Pre-process pinnedRows config to bridge Angular component classes in customPanels
|
|
5657
|
-
const prConfig = this.pinnedRows();
|
|
5658
|
-
if (prConfig && typeof prConfig === 'object' && this.adapter) {
|
|
5659
|
-
addPlugin('pinnedRows', this.adapter.processPinnedRowsConfig(prConfig));
|
|
5660
|
-
}
|
|
5661
|
-
else {
|
|
5662
|
-
addPlugin('pinnedRows', prConfig);
|
|
5663
|
-
}
|
|
6187
|
+
addPlugin('groupingRows', this.groupingRows());
|
|
6188
|
+
addPlugin('pinnedRows', this.pinnedRows());
|
|
5664
6189
|
addPlugin('tree', this.tree());
|
|
5665
6190
|
addPlugin('masterDetail', this.masterDetail());
|
|
5666
6191
|
addPlugin('responsive', this.responsive());
|
|
@@ -5680,10 +6205,13 @@ class Grid {
|
|
|
5680
6205
|
// Use setTimeout to ensure Angular effects have run (template registration)
|
|
5681
6206
|
setTimeout(() => {
|
|
5682
6207
|
grid.refreshColumns();
|
|
5683
|
-
//
|
|
5684
|
-
|
|
5685
|
-
//
|
|
5686
|
-
|
|
6208
|
+
// Run feature-registered template bridges. Each bridge wires a specific
|
|
6209
|
+
// light-DOM slot element (<tbw-grid-detail>, <tbw-grid-responsive-card>, ...)
|
|
6210
|
+
// to its plugin. Bridges are registered by feature secondary entries
|
|
6211
|
+
// (e.g. `import '@toolbox-web/grid-angular/features/master-detail';`).
|
|
6212
|
+
if (this.adapter) {
|
|
6213
|
+
runTemplateBridges({ grid, adapter: this.adapter });
|
|
6214
|
+
}
|
|
5687
6215
|
// Refresh shell header to pick up tool panel templates
|
|
5688
6216
|
// This allows Angular templates to be used in tool panels
|
|
5689
6217
|
if (typeof grid.refreshShellHeader === 'function') {
|
|
@@ -5707,85 +6235,6 @@ class Grid {
|
|
|
5707
6235
|
grid.registerStyles?.('angular-custom-styles', styles);
|
|
5708
6236
|
});
|
|
5709
6237
|
}
|
|
5710
|
-
/**
|
|
5711
|
-
* Configures the MasterDetailPlugin after Angular templates are registered.
|
|
5712
|
-
* - If plugin exists: refresh its detail renderer
|
|
5713
|
-
* - If plugin doesn't exist but <tbw-grid-detail> is present: dynamically import and add the plugin
|
|
5714
|
-
*/
|
|
5715
|
-
async configureMasterDetail(grid) {
|
|
5716
|
-
if (!this.adapter)
|
|
5717
|
-
return;
|
|
5718
|
-
// Check for existing plugin by name to avoid importing the class
|
|
5719
|
-
const existingPlugin = grid.gridConfig?.plugins?.find((p) => p.name === 'masterDetail');
|
|
5720
|
-
if (existingPlugin && typeof existingPlugin.refreshDetailRenderer === 'function') {
|
|
5721
|
-
// Plugin exists - just refresh the renderer to pick up Angular templates
|
|
5722
|
-
existingPlugin.refreshDetailRenderer();
|
|
5723
|
-
return;
|
|
5724
|
-
}
|
|
5725
|
-
// Check if <tbw-grid-detail> is present in light DOM
|
|
5726
|
-
const detailElement = grid.querySelector('tbw-grid-detail');
|
|
5727
|
-
if (!detailElement)
|
|
5728
|
-
return;
|
|
5729
|
-
// Create detail renderer from Angular template
|
|
5730
|
-
const detailRenderer = this.adapter.createDetailRenderer(grid);
|
|
5731
|
-
if (!detailRenderer)
|
|
5732
|
-
return;
|
|
5733
|
-
// Parse configuration from attributes
|
|
5734
|
-
const animationAttr = detailElement.getAttribute('animation');
|
|
5735
|
-
let animation = 'slide';
|
|
5736
|
-
if (animationAttr === 'false') {
|
|
5737
|
-
animation = false;
|
|
5738
|
-
}
|
|
5739
|
-
else if (animationAttr === 'fade') {
|
|
5740
|
-
animation = 'fade';
|
|
5741
|
-
}
|
|
5742
|
-
const showExpandColumn = detailElement.getAttribute('showExpandColumn') !== 'false';
|
|
5743
|
-
// Dynamically import the plugin to avoid bundling it when not used
|
|
5744
|
-
const { MasterDetailPlugin } = await import('@toolbox-web/grid/plugins/master-detail');
|
|
5745
|
-
// Create and add the plugin
|
|
5746
|
-
const plugin = new MasterDetailPlugin({
|
|
5747
|
-
detailRenderer: detailRenderer,
|
|
5748
|
-
showExpandColumn,
|
|
5749
|
-
animation,
|
|
5750
|
-
});
|
|
5751
|
-
const currentConfig = grid.gridConfig || {};
|
|
5752
|
-
const existingPlugins = currentConfig.plugins || [];
|
|
5753
|
-
grid.gridConfig = {
|
|
5754
|
-
...currentConfig,
|
|
5755
|
-
plugins: [...existingPlugins, plugin],
|
|
5756
|
-
};
|
|
5757
|
-
}
|
|
5758
|
-
/**
|
|
5759
|
-
* Configures the ResponsivePlugin with Angular template-based card renderer.
|
|
5760
|
-
* - If plugin exists: updates its cardRenderer configuration
|
|
5761
|
-
* - If plugin doesn't exist but <tbw-grid-responsive-card> is present: logs a warning
|
|
5762
|
-
*/
|
|
5763
|
-
configureResponsiveCard(grid) {
|
|
5764
|
-
if (!this.adapter)
|
|
5765
|
-
return;
|
|
5766
|
-
// Check if <tbw-grid-responsive-card> is present in light DOM
|
|
5767
|
-
const cardElement = grid.querySelector('tbw-grid-responsive-card');
|
|
5768
|
-
if (!cardElement)
|
|
5769
|
-
return;
|
|
5770
|
-
// Create card renderer from Angular template
|
|
5771
|
-
const cardRenderer = this.adapter.createResponsiveCardRenderer(grid);
|
|
5772
|
-
if (!cardRenderer)
|
|
5773
|
-
return;
|
|
5774
|
-
// Find existing plugin by name to avoid importing the class
|
|
5775
|
-
const existingPlugin = grid.gridConfig?.plugins?.find((p) => p.name === 'responsive');
|
|
5776
|
-
if (existingPlugin && typeof existingPlugin.setCardRenderer === 'function') {
|
|
5777
|
-
// Plugin exists - update its cardRenderer
|
|
5778
|
-
existingPlugin.setCardRenderer(cardRenderer);
|
|
5779
|
-
return;
|
|
5780
|
-
}
|
|
5781
|
-
// Plugin doesn't exist - log a warning
|
|
5782
|
-
console.warn('[tbw-grid-angular] <tbw-grid-responsive-card> found but ResponsivePlugin is not configured.\n' +
|
|
5783
|
-
'Add ResponsivePlugin to your gridConfig.plugins array:\n\n' +
|
|
5784
|
-
' import { ResponsivePlugin } from "@toolbox-web/grid/plugins/responsive";\n' +
|
|
5785
|
-
' gridConfig = {\n' +
|
|
5786
|
-
' plugins: [new ResponsivePlugin({ breakpoint: 600 })]\n' +
|
|
5787
|
-
' };');
|
|
5788
|
-
}
|
|
5789
6238
|
ngOnDestroy() {
|
|
5790
6239
|
const grid = this.elementRef.nativeElement;
|
|
5791
6240
|
// Cleanup all event listeners
|
|
@@ -5806,12 +6255,60 @@ class Grid {
|
|
|
5806
6255
|
}
|
|
5807
6256
|
}
|
|
5808
6257
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Grid, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
5809
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: Grid, isStandalone: true, selector: "tbw-grid", inputs: { customStyles: { classPropertyName: "customStyles", publicName: "customStyles", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, fitMode: { classPropertyName: "fitMode", publicName: "fitMode", isSignal: true, isRequired: false, transformFunction: null }, gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, clipboard: { classPropertyName: "clipboard", publicName: "clipboard", isSignal: true, isRequired: false, transformFunction: null }, contextMenu: { classPropertyName: "contextMenu", publicName: "contextMenu", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null }, reorderColumns: { classPropertyName: "reorderColumns", publicName: "reorderColumns", isSignal: true, isRequired: false, transformFunction: null }, visibility: { classPropertyName: "visibility", publicName: "visibility", isSignal: true, isRequired: false, transformFunction: null }, pinnedColumns: { classPropertyName: "pinnedColumns", publicName: "pinnedColumns", isSignal: true, isRequired: false, transformFunction: null }, groupingColumns: { classPropertyName: "groupingColumns", publicName: "groupingColumns", isSignal: true, isRequired: false, transformFunction: null }, columnVirtualization: { classPropertyName: "columnVirtualization", publicName: "columnVirtualization", isSignal: true, isRequired: false, transformFunction: null }, reorderRows: { classPropertyName: "reorderRows", publicName: "reorderRows", isSignal: true, isRequired: false, transformFunction: null }, rowDragDrop: { classPropertyName: "rowDragDrop", publicName: "rowDragDrop", isSignal: true, isRequired: false, transformFunction: null }, groupingRows: { classPropertyName: "groupingRows", publicName: "groupingRows", isSignal: true, isRequired: false, transformFunction: null }, pinnedRows: { classPropertyName: "pinnedRows", publicName: "pinnedRows", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, masterDetail: { classPropertyName: "masterDetail", publicName: "masterDetail", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, undoRedo: { classPropertyName: "undoRedo", publicName: "undoRedo", isSignal: true, isRequired: false, transformFunction: null }, exportFeature: { classPropertyName: "exportFeature", publicName: "export", isSignal: true, isRequired: false, transformFunction: null }, print: { classPropertyName: "print", publicName: "print", isSignal: true, isRequired: false, transformFunction: null }, pivot: { classPropertyName: "pivot", publicName: "pivot", isSignal: true, isRequired: false, transformFunction: null }, serverSide: { classPropertyName: "serverSide", publicName: "serverSide", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", rowClick: "rowClick", cellActivate: "cellActivate", cellChange: "cellChange", cellCommit: "cellCommit", rowCommit: "rowCommit", changedRowsReset: "changedRowsReset", sortChange: "sortChange", filterChange: "filterChange", columnResize: "columnResize", columnMove: "columnMove", columnVisibility: "columnVisibility", columnStateChange: "columnStateChange", selectionChange: "selectionChange", rowMove: "rowMove", rowDragStart: "rowDragStart", rowDragEnd: "rowDragEnd", rowDrop: "rowDrop", rowTransfer: "rowTransfer", groupToggle: "groupToggle", treeExpand: "treeExpand", detailExpand: "detailExpand", responsiveChange: "responsiveChange", copy: "copy", paste: "paste",
|
|
6258
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: Grid, isStandalone: true, selector: "tbw-grid", inputs: { customStyles: { classPropertyName: "customStyles", publicName: "customStyles", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnDefaults: { classPropertyName: "columnDefaults", publicName: "columnDefaults", isSignal: true, isRequired: false, transformFunction: null }, fitMode: { classPropertyName: "fitMode", publicName: "fitMode", isSignal: true, isRequired: false, transformFunction: null }, gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, clipboard: { classPropertyName: "clipboard", publicName: "clipboard", isSignal: true, isRequired: false, transformFunction: null }, contextMenu: { classPropertyName: "contextMenu", publicName: "contextMenu", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null }, reorderColumns: { classPropertyName: "reorderColumns", publicName: "reorderColumns", isSignal: true, isRequired: false, transformFunction: null }, visibility: { classPropertyName: "visibility", publicName: "visibility", isSignal: true, isRequired: false, transformFunction: null }, pinnedColumns: { classPropertyName: "pinnedColumns", publicName: "pinnedColumns", isSignal: true, isRequired: false, transformFunction: null }, groupingColumns: { classPropertyName: "groupingColumns", publicName: "groupingColumns", isSignal: true, isRequired: false, transformFunction: null }, columnVirtualization: { classPropertyName: "columnVirtualization", publicName: "columnVirtualization", isSignal: true, isRequired: false, transformFunction: null }, reorderRows: { classPropertyName: "reorderRows", publicName: "reorderRows", isSignal: true, isRequired: false, transformFunction: null }, rowDragDrop: { classPropertyName: "rowDragDrop", publicName: "rowDragDrop", isSignal: true, isRequired: false, transformFunction: null }, groupingRows: { classPropertyName: "groupingRows", publicName: "groupingRows", isSignal: true, isRequired: false, transformFunction: null }, pinnedRows: { classPropertyName: "pinnedRows", publicName: "pinnedRows", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, masterDetail: { classPropertyName: "masterDetail", publicName: "masterDetail", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, undoRedo: { classPropertyName: "undoRedo", publicName: "undoRedo", isSignal: true, isRequired: false, transformFunction: null }, exportFeature: { classPropertyName: "exportFeature", publicName: "export", isSignal: true, isRequired: false, transformFunction: null }, print: { classPropertyName: "print", publicName: "print", isSignal: true, isRequired: false, transformFunction: null }, pivot: { classPropertyName: "pivot", publicName: "pivot", isSignal: true, isRequired: false, transformFunction: null }, serverSide: { classPropertyName: "serverSide", publicName: "serverSide", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", rowClick: "rowClick", cellActivate: "cellActivate", cellChange: "cellChange", cellCommit: "cellCommit", cellCancel: "cellCancel", editOpen: "editOpen", beforeEditClose: "beforeEditClose", editClose: "editClose", dirtyChange: "dirtyChange", dataChange: "dataChange", rowCommit: "rowCommit", changedRowsReset: "changedRowsReset", sortChange: "sortChange", filterChange: "filterChange", columnResize: "columnResize", columnResizeReset: "columnResizeReset", columnMove: "columnMove", columnVisibility: "columnVisibility", columnStateChange: "columnStateChange", selectionChange: "selectionChange", rowMove: "rowMove", rowDragStart: "rowDragStart", rowDragEnd: "rowDragEnd", rowDrop: "rowDrop", rowTransfer: "rowTransfer", groupToggle: "groupToggle", groupExpand: "groupExpand", groupCollapse: "groupCollapse", treeExpand: "treeExpand", detailExpand: "detailExpand", responsiveChange: "responsiveChange", contextMenuOpen: "contextMenuOpen", copy: "copy", paste: "paste", undo: "undo", redo: "redo", exportComplete: "exportComplete", printStart: "printStart", printComplete: "printComplete", tbwScroll: "tbwScroll" }, ngImport: i0 });
|
|
5810
6259
|
}
|
|
5811
6260
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Grid, decorators: [{
|
|
5812
6261
|
type: Directive,
|
|
5813
6262
|
args: [{ selector: 'tbw-grid' }]
|
|
5814
|
-
}], ctorParameters: () => [], propDecorators: { customStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyles", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], fitMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitMode", required: false }] }], gridConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridConfig", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], clipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "clipboard", required: false }] }], contextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenu", required: false }] }], multiSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiSort", required: false }] }], filtering: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtering", required: false }] }], reorderColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderColumns", required: false }] }], visibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibility", required: false }] }], pinnedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedColumns", required: false }] }], groupingColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingColumns", required: false }] }], columnVirtualization: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVirtualization", required: false }] }], reorderRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderRows", required: false }] }], rowDragDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowDragDrop", required: false }] }], groupingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingRows", required: false }] }], pinnedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedRows", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], masterDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "masterDetail", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], undoRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoRedo", required: false }] }], exportFeature: [{ type: i0.Input, args: [{ isSignal: true, alias: "export", required: false }] }], print: [{ type: i0.Input, args: [{ isSignal: true, alias: "print", required: false }] }], pivot: [{ type: i0.Input, args: [{ isSignal: true, alias: "pivot", required: false }] }], serverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "serverSide", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellActivate: [{ type: i0.Output, args: ["cellActivate"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], rowCommit: [{ type: i0.Output, args: ["rowCommit"] }], changedRowsReset: [{ type: i0.Output, args: ["changedRowsReset"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], columnMove: [{ type: i0.Output, args: ["columnMove"] }], columnVisibility: [{ type: i0.Output, args: ["columnVisibility"] }], columnStateChange: [{ type: i0.Output, args: ["columnStateChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], rowMove: [{ type: i0.Output, args: ["rowMove"] }], rowDragStart: [{ type: i0.Output, args: ["rowDragStart"] }], rowDragEnd: [{ type: i0.Output, args: ["rowDragEnd"] }], rowDrop: [{ type: i0.Output, args: ["rowDrop"] }], rowTransfer: [{ type: i0.Output, args: ["rowTransfer"] }], groupToggle: [{ type: i0.Output, args: ["groupToggle"] }], treeExpand: [{ type: i0.Output, args: ["treeExpand"] }], detailExpand: [{ type: i0.Output, args: ["detailExpand"] }], responsiveChange: [{ type: i0.Output, args: ["responsiveChange"] }], copy: [{ type: i0.Output, args: ["copy"] }], paste: [{ type: i0.Output, args: ["paste"] }],
|
|
6263
|
+
}], ctorParameters: () => [], propDecorators: { customStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyles", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], columnDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnDefaults", required: false }] }], fitMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitMode", required: false }] }], gridConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridConfig", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], clipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "clipboard", required: false }] }], contextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenu", required: false }] }], multiSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiSort", required: false }] }], filtering: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtering", required: false }] }], reorderColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderColumns", required: false }] }], visibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibility", required: false }] }], pinnedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedColumns", required: false }] }], groupingColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingColumns", required: false }] }], columnVirtualization: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVirtualization", required: false }] }], reorderRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderRows", required: false }] }], rowDragDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowDragDrop", required: false }] }], groupingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingRows", required: false }] }], pinnedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedRows", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], masterDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "masterDetail", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], undoRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoRedo", required: false }] }], exportFeature: [{ type: i0.Input, args: [{ isSignal: true, alias: "export", required: false }] }], print: [{ type: i0.Input, args: [{ isSignal: true, alias: "print", required: false }] }], pivot: [{ type: i0.Input, args: [{ isSignal: true, alias: "pivot", required: false }] }], serverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "serverSide", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellActivate: [{ type: i0.Output, args: ["cellActivate"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], cellCancel: [{ type: i0.Output, args: ["cellCancel"] }], editOpen: [{ type: i0.Output, args: ["editOpen"] }], beforeEditClose: [{ type: i0.Output, args: ["beforeEditClose"] }], editClose: [{ type: i0.Output, args: ["editClose"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], dataChange: [{ type: i0.Output, args: ["dataChange"] }], rowCommit: [{ type: i0.Output, args: ["rowCommit"] }], changedRowsReset: [{ type: i0.Output, args: ["changedRowsReset"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], columnResizeReset: [{ type: i0.Output, args: ["columnResizeReset"] }], columnMove: [{ type: i0.Output, args: ["columnMove"] }], columnVisibility: [{ type: i0.Output, args: ["columnVisibility"] }], columnStateChange: [{ type: i0.Output, args: ["columnStateChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], rowMove: [{ type: i0.Output, args: ["rowMove"] }], rowDragStart: [{ type: i0.Output, args: ["rowDragStart"] }], rowDragEnd: [{ type: i0.Output, args: ["rowDragEnd"] }], rowDrop: [{ type: i0.Output, args: ["rowDrop"] }], rowTransfer: [{ type: i0.Output, args: ["rowTransfer"] }], groupToggle: [{ type: i0.Output, args: ["groupToggle"] }], groupExpand: [{ type: i0.Output, args: ["groupExpand"] }], groupCollapse: [{ type: i0.Output, args: ["groupCollapse"] }], treeExpand: [{ type: i0.Output, args: ["treeExpand"] }], detailExpand: [{ type: i0.Output, args: ["detailExpand"] }], responsiveChange: [{ type: i0.Output, args: ["responsiveChange"] }], contextMenuOpen: [{ type: i0.Output, args: ["contextMenuOpen"] }], copy: [{ type: i0.Output, args: ["copy"] }], paste: [{ type: i0.Output, args: ["paste"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], exportComplete: [{ type: i0.Output, args: ["exportComplete"] }], printStart: [{ type: i0.Output, args: ["printStart"] }], printComplete: [{ type: i0.Output, args: ["printComplete"] }], tbwScroll: [{ type: i0.Output, args: ["tbwScroll"] }] } });
|
|
6264
|
+
|
|
6265
|
+
/**
|
|
6266
|
+
* Combined provider helper for grid type defaults and icons.
|
|
6267
|
+
*
|
|
6268
|
+
* Convenience function that combines `provideGridTypeDefaults` and
|
|
6269
|
+
* `provideGridIcons` into a single call for application bootstrap.
|
|
6270
|
+
*
|
|
6271
|
+
* @example
|
|
6272
|
+
* ```typescript
|
|
6273
|
+
* // app.config.ts
|
|
6274
|
+
* import { ApplicationConfig } from '@angular/core';
|
|
6275
|
+
* import { provideGrid } from '@toolbox-web/grid-angular';
|
|
6276
|
+
*
|
|
6277
|
+
* export const appConfig: ApplicationConfig = {
|
|
6278
|
+
* providers: [
|
|
6279
|
+
* provideGrid({
|
|
6280
|
+
* typeDefaults: {
|
|
6281
|
+
* country: { renderer: CountryCellComponent },
|
|
6282
|
+
* },
|
|
6283
|
+
* icons: {
|
|
6284
|
+
* sortAsc: '↑',
|
|
6285
|
+
* sortDesc: '↓',
|
|
6286
|
+
* },
|
|
6287
|
+
* }),
|
|
6288
|
+
* ],
|
|
6289
|
+
* };
|
|
6290
|
+
* ```
|
|
6291
|
+
*/
|
|
6292
|
+
/**
|
|
6293
|
+
* Combined provider for grid type defaults and icons.
|
|
6294
|
+
*
|
|
6295
|
+
* Returns environment providers that can be added to your `ApplicationConfig`
|
|
6296
|
+
* `providers` array. Either field is optional — only the registries you
|
|
6297
|
+
* supply are wired up.
|
|
6298
|
+
*
|
|
6299
|
+
* Equivalent to calling `provideGridTypeDefaults(options.typeDefaults)` and
|
|
6300
|
+
* `provideGridIcons(options.icons)` separately.
|
|
6301
|
+
*/
|
|
6302
|
+
function provideGrid(options = {}) {
|
|
6303
|
+
const providers = [];
|
|
6304
|
+
if (options.typeDefaults) {
|
|
6305
|
+
providers.push(provideGridTypeDefaults(options.typeDefaults));
|
|
6306
|
+
}
|
|
6307
|
+
if (options.icons) {
|
|
6308
|
+
providers.push(provideGridIcons(options.icons));
|
|
6309
|
+
}
|
|
6310
|
+
return makeEnvironmentProviders(providers);
|
|
6311
|
+
}
|
|
5815
6312
|
|
|
5816
6313
|
/**
|
|
5817
6314
|
* @packageDocumentation
|
|
@@ -5825,5 +6322,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
5825
6322
|
* Generated bundle index. Do not edit.
|
|
5826
6323
|
*/
|
|
5827
6324
|
|
|
5828
|
-
export { BaseFilterPanel, BaseGridEditor, BaseGridEditorCVA, BaseOverlayEditor, GRID_ICONS, GRID_TYPE_DEFAULTS, Grid, GridAdapter, GridColumnEditor, GridColumnView, GridDetailView, GridFormArray, GridIconRegistry, GridLazyForm, GridResponsiveCard, GridToolPanel, GridTypeRegistry, TbwEditor, TbwGridColumn, TbwGridHeader, TbwGridToolButtons, TbwRenderer, getFormArrayContext, getLazyFormContext, injectGrid, isComponentClass, provideGridIcons, provideGridTypeDefaults };
|
|
6325
|
+
export { BaseFilterPanel, BaseGridEditor, BaseGridEditorCVA, BaseOverlayEditor, GRID_ICONS, GRID_TYPE_DEFAULTS, Grid, GridAdapter, GridColumnEditor, GridColumnView, GridDetailView, GridFormArray, GridIconRegistry, GridLazyForm, GridResponsiveCard, GridToolPanel, GridTypeRegistry, TbwEditor, TbwGridColumn, TbwGridHeader, TbwGridToolButtons, TbwRenderer, applyColumnDefaults, claimEvent, getDetailTemplate, getFeatureClaim, getFeatureConfigPreprocessor, getFormArrayContext, getLazyFormContext, getResponsiveCardTemplate, hasColumnShorthands, injectGrid, isComponentClass, isEventClaimed, makeFlushFocusedInput, normalizeColumns, parseColumnShorthand, provideGrid, provideGridIcons, provideGridTypeDefaults, registerDetailRendererBridge, registerEditorMountHook, registerFeatureClaim, registerFeatureConfigPreprocessor, registerFilterPanelTypeDefaultBridge, registerResponsiveCardRendererBridge, registerTemplateBridge, runTemplateBridges, unclaimEvent, unregisterFeatureClaim };
|
|
5829
6326
|
//# sourceMappingURL=toolbox-web-grid-angular.mjs.map
|