@agility-workbench/angular-grid 1.10.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -2
- package/fesm2022/agility-workbench-angular-grid.mjs +179 -17
- package/index.d.ts +32 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -77,6 +77,13 @@ are not overwritten), `[pivotColumnMoveMode]` is live, `[pivotResultColumnDef]`
|
|
|
77
77
|
`[sheets]` renders the footer tab strip with the same app-owned persistence contract as
|
|
78
78
|
`[savedViews]`. See the core README for what pivot mode and sheets do.
|
|
79
79
|
|
|
80
|
+
Most inputs are live. The ones the grid reads only at creation (`rowHeight`, `getRowId`,
|
|
81
|
+
`rowIdKey`, `rowModelType`, `defaultColDef`, `groupColumnDef`, `pivotResultColumnDef`,
|
|
82
|
+
`initialSort`, … — the core's `CREATION_ONLY_OPTION_KEYS`, minus the bridged inputs) ignore later
|
|
83
|
+
changes; in development mode (`isDevMode()`) the grid logs one `console.warn` naming the input when
|
|
84
|
+
that happens. Re-create the `<awb-grid>` (for example under an `@if`, or a keyed `@for`) to apply
|
|
85
|
+
such a change. The Angular page of the documentation site has the full live-vs-creation table.
|
|
86
|
+
|
|
80
87
|
## Styling
|
|
81
88
|
|
|
82
89
|
Nothing to do — the grid delivers its own stylesheet when it attaches, once per document, and
|
|
@@ -91,8 +98,11 @@ copies do not fight in the cascade.
|
|
|
91
98
|
## Angular components in the grid
|
|
92
99
|
|
|
93
100
|
Column definitions accept Angular component classes wherever the core accepts a class component —
|
|
94
|
-
`cellRenderer`, `cellEditor`, `tooltipComponent`, `headerTooltip`,
|
|
95
|
-
|
|
101
|
+
`cellRenderer`, `cellEditor`, `tooltipComponent`, `headerTooltip`, `actionFrameComponent`, the
|
|
102
|
+
set-filter components in `filterParams`, and the header components `headerComponent` (header
|
|
103
|
+
content) and `headerCellComponent` (the whole header cell; contract `IHeaderNgComp`). The same slots
|
|
104
|
+
are adapted in `[defaultColDef]`, `[groupColumnDef]`, and `[pivotResultColumnDef]`. A component
|
|
105
|
+
receives its params either through an input named `params` or by implementing
|
|
96
106
|
`awbInit(params)` (plus optional `awbRefresh(params)`):
|
|
97
107
|
|
|
98
108
|
```ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { isClassRenderer, isClassTooltipComponent, isClassActionFrameComponent, isClassSetFilterComponent, createGrid } from '@agility-workbench/grid';
|
|
1
|
+
import { isClassRenderer, isClassTooltipComponent, isClassActionFrameComponent, isClassHeaderComponent, isClassSetFilterComponent, CREATION_ONLY_OPTION_KEYS, createGrid } from '@agility-workbench/grid';
|
|
2
2
|
export * from '@agility-workbench/grid';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { reflectComponentType, createComponent, input, output, inject, ElementRef, NgZone, Injector, ApplicationRef, EnvironmentInjector, afterNextRender, untracked, effect, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { reflectComponentType, createComponent, input, output, inject, ElementRef, NgZone, Injector, ApplicationRef, EnvironmentInjector, afterNextRender, isDevMode, untracked, isSignal, effect, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
5
5
|
|
|
6
6
|
/** True when `value` is a compiled Angular component class (vs a core class or plain function). */
|
|
7
7
|
function isNgComponent(value) {
|
|
@@ -40,6 +40,7 @@ class NgAdapters {
|
|
|
40
40
|
this.actionFrameCache = new WeakMap();
|
|
41
41
|
this.editorCache = new WeakMap();
|
|
42
42
|
this.setFilterComponentCache = new WeakMap();
|
|
43
|
+
this.headerComponentCache = new WeakMap();
|
|
43
44
|
}
|
|
44
45
|
/**
|
|
45
46
|
* Create `component` with `hostElement` as its host, deliver params, attach it to the app for
|
|
@@ -225,6 +226,57 @@ class NgAdapters {
|
|
|
225
226
|
}
|
|
226
227
|
};
|
|
227
228
|
}
|
|
229
|
+
// --- header components -----------------------------------------------------------------------
|
|
230
|
+
/**
|
|
231
|
+
* Adapt a `headerComponent` / `headerCellComponent`. Core class components and the core function
|
|
232
|
+
* form pass through; an Angular component is mounted into the header slot.
|
|
233
|
+
*/
|
|
234
|
+
adaptHeaderComponent(comp) {
|
|
235
|
+
if (!comp)
|
|
236
|
+
return undefined;
|
|
237
|
+
if (typeof comp === "function" && isClassHeaderComponent(comp)) {
|
|
238
|
+
return comp;
|
|
239
|
+
}
|
|
240
|
+
if (!isNgComponent(comp))
|
|
241
|
+
return comp;
|
|
242
|
+
const cached = this.headerComponentCache.get(comp);
|
|
243
|
+
if (cached)
|
|
244
|
+
return cached;
|
|
245
|
+
const adapted = this.createHeaderComponentClass(comp);
|
|
246
|
+
this.headerComponentCache.set(comp, adapted);
|
|
247
|
+
return adapted;
|
|
248
|
+
}
|
|
249
|
+
createHeaderComponentClass(component) {
|
|
250
|
+
const adapters = this;
|
|
251
|
+
return class NgHeaderComponentAdapter {
|
|
252
|
+
constructor() {
|
|
253
|
+
this.el = document.createElement("div");
|
|
254
|
+
this.mounted = null;
|
|
255
|
+
}
|
|
256
|
+
init(params) {
|
|
257
|
+
// Same box the core gives its function form, so an Angular header lays out like a native one.
|
|
258
|
+
this.el.className = "pte-hcell-custom-root";
|
|
259
|
+
this.el.style.display = "flex";
|
|
260
|
+
this.el.style.alignItems = "center";
|
|
261
|
+
this.el.style.width = "100%";
|
|
262
|
+
this.el.style.height = "100%";
|
|
263
|
+
this.el.style.overflow = "hidden";
|
|
264
|
+
// One component instance per header cell; sort/filter refreshes re-deliver params (an
|
|
265
|
+
// awbRefresh returning false asks the grid to recreate it). Header rebuilds destroy it.
|
|
266
|
+
this.mounted = adapters.mount(component, params, this.el, "headerComponent");
|
|
267
|
+
}
|
|
268
|
+
getGui() {
|
|
269
|
+
return this.el;
|
|
270
|
+
}
|
|
271
|
+
refresh(params) {
|
|
272
|
+
return this.mounted?.refresh(params) ?? false;
|
|
273
|
+
}
|
|
274
|
+
destroy() {
|
|
275
|
+
this.mounted?.destroy();
|
|
276
|
+
this.mounted = null;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
228
280
|
// --- cell editors ----------------------------------------------------------------------------
|
|
229
281
|
adaptCellEditor(editor) {
|
|
230
282
|
if (editor == null)
|
|
@@ -345,6 +397,8 @@ class NgAdapters {
|
|
|
345
397
|
headerTooltip: this.adaptHeaderTooltip(colDef.headerTooltip),
|
|
346
398
|
actionFrameComponent: this.adaptActionFrame(colDef.actionFrameComponent),
|
|
347
399
|
filterParams: this.adaptFilterParams(colDef.filterParams),
|
|
400
|
+
headerComponent: this.adaptHeaderComponent(colDef.headerComponent),
|
|
401
|
+
headerCellComponent: this.adaptHeaderComponent(colDef.headerCellComponent),
|
|
348
402
|
children: colDef.children ? (this.adaptColumnDefs(colDef.children) ?? undefined) : undefined,
|
|
349
403
|
};
|
|
350
404
|
}
|
|
@@ -361,20 +415,37 @@ class NgAdapters {
|
|
|
361
415
|
adaptDefaultColDef(defaultColDef) {
|
|
362
416
|
if (defaultColDef == null)
|
|
363
417
|
return undefined;
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
418
|
+
return this.adaptPartial(defaultColDef);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Adapt `groupColumnDef` / `pivotResultColumnDef`, the partial defs the grid layers over its
|
|
422
|
+
* synthesized columns. Present-fields-only, like {@link adaptDefaultColDef}: the core layers these
|
|
423
|
+
* with object spread, where an explicit `undefined` would clobber the layer beneath.
|
|
424
|
+
*/
|
|
425
|
+
adaptPartialColDef(def) {
|
|
426
|
+
if (def == null)
|
|
427
|
+
return undefined;
|
|
428
|
+
return this.adaptPartial(def);
|
|
429
|
+
}
|
|
430
|
+
adaptPartial(def) {
|
|
431
|
+
const next = { ...def };
|
|
432
|
+
if ("cellRenderer" in def)
|
|
433
|
+
next.cellRenderer = this.adaptCellRenderer(def.cellRenderer);
|
|
434
|
+
if ("cellEditor" in def)
|
|
435
|
+
next.cellEditor = this.adaptCellEditor(def.cellEditor);
|
|
436
|
+
if ("tooltipComponent" in def)
|
|
437
|
+
next.tooltipComponent = this.adaptTooltip(def.tooltipComponent);
|
|
438
|
+
if ("headerTooltip" in def)
|
|
439
|
+
next.headerTooltip = this.adaptHeaderTooltip(def.headerTooltip);
|
|
440
|
+
if ("actionFrameComponent" in def)
|
|
441
|
+
next.actionFrameComponent = this.adaptActionFrame(def.actionFrameComponent);
|
|
442
|
+
if ("filterParams" in def)
|
|
443
|
+
next.filterParams = this.adaptFilterParams(def.filterParams);
|
|
444
|
+
if ("headerComponent" in def)
|
|
445
|
+
next.headerComponent = this.adaptHeaderComponent(def.headerComponent);
|
|
446
|
+
if ("headerCellComponent" in def) {
|
|
447
|
+
next.headerCellComponent = this.adaptHeaderComponent(def.headerCellComponent);
|
|
375
448
|
}
|
|
376
|
-
if ("filterParams" in defaultColDef)
|
|
377
|
-
next.filterParams = this.adaptFilterParams(defaultColDef.filterParams);
|
|
378
449
|
return next;
|
|
379
450
|
}
|
|
380
451
|
}
|
|
@@ -404,6 +475,56 @@ function getActionFrameProps(params) {
|
|
|
404
475
|
return { ...params, ...extraParams };
|
|
405
476
|
}
|
|
406
477
|
|
|
478
|
+
/**
|
|
479
|
+
* Core creation-only options the Angular binding keeps live anyway: the value-returning hooks and
|
|
480
|
+
* `multiColumnMenu` are read through their input signals on every call. (The event callbacks are
|
|
481
|
+
* outputs, not inputs, so they never reach this list.) Everything else in core's
|
|
482
|
+
* {@link CREATION_ONLY_OPTION_KEYS} that `<awb-grid>` declares as an input is fixed once the grid
|
|
483
|
+
* exists.
|
|
484
|
+
*/
|
|
485
|
+
const BRIDGED_INPUTS = new Set([
|
|
486
|
+
"onBeforeCellCommit",
|
|
487
|
+
"fillOperation",
|
|
488
|
+
"multiColumnMenu",
|
|
489
|
+
]);
|
|
490
|
+
/** Core creation-only option names minus the inputs the binding bridges (derived from core). */
|
|
491
|
+
const CREATION_ONLY_INPUT_CANDIDATES = CREATION_ONLY_OPTION_KEYS.filter((key) => !BRIDGED_INPUTS.has(key));
|
|
492
|
+
/** The `treeData` members the binding reconciles live (via setTreeDataKeyboardNavigationOptions). */
|
|
493
|
+
const LIVE_TREE_DATA_KEYS = ["keyboardNavigationMode", "enableKeyboardNavigationModeSwitch"];
|
|
494
|
+
const UNCOMPARABLE = Symbol("uncomparable");
|
|
495
|
+
/**
|
|
496
|
+
* A structural fingerprint of an input value, so a template literal object or a function re-created
|
|
497
|
+
* with the same contents does not count as a change. Functions (and component classes) compare by
|
|
498
|
+
* source text; `treeData` ignores the members that are live. Values that cannot be serialized
|
|
499
|
+
* (cycles) compare by identity.
|
|
500
|
+
*/
|
|
501
|
+
function inputFingerprint(key, value) {
|
|
502
|
+
let subject = value;
|
|
503
|
+
if (key === "treeData" && value != null && typeof value === "object") {
|
|
504
|
+
const rest = { ...value };
|
|
505
|
+
for (const live of LIVE_TREE_DATA_KEYS)
|
|
506
|
+
delete rest[live];
|
|
507
|
+
subject = rest;
|
|
508
|
+
}
|
|
509
|
+
try {
|
|
510
|
+
return JSON.stringify(subject, (_k, v) => {
|
|
511
|
+
if (typeof v === "function")
|
|
512
|
+
return `ƒ ${String(v)}`;
|
|
513
|
+
if (v === undefined)
|
|
514
|
+
return "∅undefined";
|
|
515
|
+
return v;
|
|
516
|
+
}) ?? "∅undefined";
|
|
517
|
+
}
|
|
518
|
+
catch {
|
|
519
|
+
return UNCOMPARABLE;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
function creationOnlyWarning(key) {
|
|
523
|
+
return (`[agility-workbench] <awb-grid> input "${key}" changed after the grid was created. It is read ` +
|
|
524
|
+
`only at creation, so the change is ignored. Re-create the grid to apply it (for example, ` +
|
|
525
|
+
`render it under an @if or a keyed @for so Angular destroys and creates a new <awb-grid>).`);
|
|
526
|
+
}
|
|
527
|
+
|
|
407
528
|
function setIfDefined(options, key, value) {
|
|
408
529
|
if (value != null)
|
|
409
530
|
options[key] = value;
|
|
@@ -430,7 +551,6 @@ function getGridOptions(grid, adapters) {
|
|
|
430
551
|
setIfDefined(options, "maxColumnWidth", grid.maxColumnWidth());
|
|
431
552
|
setIfDefined(options, "pivotMode", grid.pivotMode());
|
|
432
553
|
setIfDefined(options, "pivotColumns", grid.pivotColumns());
|
|
433
|
-
setIfDefined(options, "pivotResultColumnDef", grid.pivotResultColumnDef());
|
|
434
554
|
setIfDefined(options, "maxPivotColumns", grid.maxPivotColumns());
|
|
435
555
|
setIfDefined(options, "pivotColumnMoveMode", grid.pivotColumnMoveMode());
|
|
436
556
|
setIfDefined(options, "autosizeColumnsOnDataChange", grid.autosizeColumnsOnDataChange());
|
|
@@ -481,7 +601,6 @@ function getGridOptions(grid, adapters) {
|
|
|
481
601
|
setIfDefined(options, "commitOnBlur", grid.commitOnBlur());
|
|
482
602
|
setIfDefined(options, "reevaluateOnEdit", grid.reevaluateOnEdit());
|
|
483
603
|
setIfDefined(options, "groupDisplayType", grid.groupDisplayType());
|
|
484
|
-
setIfDefined(options, "groupColumnDef", grid.groupColumnDef());
|
|
485
604
|
setIfDefined(options, "groupDefaultExpanded", grid.groupDefaultExpanded());
|
|
486
605
|
setIfDefined(options, "groupSortMode", grid.groupSortMode());
|
|
487
606
|
setIfDefined(options, "treeData", grid.treeData());
|
|
@@ -514,6 +633,14 @@ function getGridOptions(grid, adapters) {
|
|
|
514
633
|
const defaultColDef = grid.defaultColDef();
|
|
515
634
|
if (defaultColDef != null)
|
|
516
635
|
options.defaultColDef = adapters.adaptDefaultColDef(defaultColDef);
|
|
636
|
+
// The partial defs the grid layers over its synthesized columns carry component fields too.
|
|
637
|
+
const groupColumnDef = grid.groupColumnDef();
|
|
638
|
+
if (groupColumnDef != null)
|
|
639
|
+
options.groupColumnDef = adapters.adaptPartialColDef(groupColumnDef);
|
|
640
|
+
const pivotResultColumnDef = grid.pivotResultColumnDef();
|
|
641
|
+
if (pivotResultColumnDef != null) {
|
|
642
|
+
options.pivotResultColumnDef = adapters.adaptPartialColDef(pivotResultColumnDef);
|
|
643
|
+
}
|
|
517
644
|
// Forward only the boolean intent to core: false disables the menu (native menu shows);
|
|
518
645
|
// everything else (true / omitted / a function) leaves core at its "show menu" default and lets
|
|
519
646
|
// the body-menu adapter apply the function arm (so TemplateRef slots are handled). This avoids
|
|
@@ -894,6 +1021,8 @@ class AwbGrid {
|
|
|
894
1021
|
return created;
|
|
895
1022
|
});
|
|
896
1023
|
this.instance = instance;
|
|
1024
|
+
if (isDevMode())
|
|
1025
|
+
this.startCreationOnlyWarnings();
|
|
897
1026
|
this.startSyncEffects(instance);
|
|
898
1027
|
this.gridReady.emit(instance.api);
|
|
899
1028
|
}
|
|
@@ -1080,6 +1209,39 @@ class AwbGrid {
|
|
|
1080
1209
|
return () => api.updateGridOptions({ theme, icons: { ...theme?.getIcons(), ...icons } });
|
|
1081
1210
|
});
|
|
1082
1211
|
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Development only. Creation-only inputs are read once, by createGrid; a later change to one is
|
|
1214
|
+
* ignored. Instead of letting that change vanish silently, warn once per input (per grid
|
|
1215
|
+
* instance), comparing against the value the grid was created with. The input list is core's
|
|
1216
|
+
* creation-only key list, intersected with the inputs this component declares.
|
|
1217
|
+
*/
|
|
1218
|
+
startCreationOnlyWarnings() {
|
|
1219
|
+
const self = this;
|
|
1220
|
+
const inputs = CREATION_ONLY_INPUT_CANDIDATES.flatMap((key) => {
|
|
1221
|
+
const candidate = self[key];
|
|
1222
|
+
return isSignal(candidate) ? [{ key, read: candidate }] : [];
|
|
1223
|
+
});
|
|
1224
|
+
const created = new Map(inputs.map(({ key, read }) => {
|
|
1225
|
+
const value = untracked(read);
|
|
1226
|
+
return [key, { value, fingerprint: inputFingerprint(key, value) }];
|
|
1227
|
+
}));
|
|
1228
|
+
const warned = new Set();
|
|
1229
|
+
effect(() => {
|
|
1230
|
+
for (const { key, read } of inputs) {
|
|
1231
|
+
const value = read();
|
|
1232
|
+
if (warned.has(key))
|
|
1233
|
+
continue;
|
|
1234
|
+
const initial = created.get(key);
|
|
1235
|
+
if (Object.is(value, initial.value))
|
|
1236
|
+
continue;
|
|
1237
|
+
const fingerprint = inputFingerprint(key, value);
|
|
1238
|
+
if (fingerprint !== UNCOMPARABLE && fingerprint === initial.fingerprint)
|
|
1239
|
+
continue;
|
|
1240
|
+
warned.add(key);
|
|
1241
|
+
console.warn(creationOnlyWarning(key));
|
|
1242
|
+
}
|
|
1243
|
+
}, { injector: this.injector });
|
|
1244
|
+
}
|
|
1083
1245
|
/**
|
|
1084
1246
|
* Effect helper: `read` runs tracked (signal reads register dependencies) and returns the core
|
|
1085
1247
|
* call to make, or null to skip; the call itself runs outside the Angular zone so core-side
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _agility_workbench_grid from '@agility-workbench/grid';
|
|
2
|
-
import { ColDef, CellRenderer, CellEditor, TooltipComponent, ActionFrameComponent, FilterParams, SetFilterValueComponent, SetFilterSpecialValueComponent, SetFilterGroupComponent, NON_DEFAULTABLE_COLDEF_KEYS, RowPresentationParams, RowPresentation, RowTooltipPresentation, ActionFrameComponentParams, ICellEditorParams, CellRendererParams, SetFilterGroupComponentParams, SetFilterSpecialValueComponentParams, SetFilterValueComponentParams, TooltipComponentParams, MenuItem, ColumnMenuContext, BodyMenuContext, Column, IGridAPI, GridEventCellClickedParams, GridEventRowClickedParams, CellValueChangedParams, GridEventSelectionChangedParams, SortChangedParams, GridEventFilterChangedParams, GridEventQuickFilterFindChangedParams, GridEventHistoryChangedParams } from '@agility-workbench/grid';
|
|
2
|
+
import { ColDef, CellRenderer, CellEditor, TooltipComponent, ActionFrameComponent, FilterParams, SetFilterValueComponent, SetFilterSpecialValueComponent, SetFilterGroupComponent, HeaderComponent, NON_DEFAULTABLE_COLDEF_KEYS, RowPresentationParams, RowPresentation, RowTooltipPresentation, ActionFrameComponentParams, ICellEditorParams, CellRendererParams, HeaderComponentParams, SetFilterGroupComponentParams, SetFilterSpecialValueComponentParams, SetFilterValueComponentParams, TooltipComponentParams, MenuItem, ColumnMenuContext, BodyMenuContext, Column, IGridAPI, GridEventCellClickedParams, GridEventRowClickedParams, CellValueChangedParams, GridEventSelectionChangedParams, SortChangedParams, GridEventFilterChangedParams, GridEventQuickFilterFindChangedParams, GridEventHistoryChangedParams } from '@agility-workbench/grid';
|
|
3
3
|
export * from '@agility-workbench/grid';
|
|
4
4
|
import * as _angular_core from '@angular/core';
|
|
5
5
|
import { Type, TemplateRef, OnDestroy } from '@angular/core';
|
|
@@ -25,6 +25,15 @@ interface IActionFrameNgComp<P extends ActionFrameComponentParams = ActionFrameC
|
|
|
25
25
|
awbInit(params: P): void;
|
|
26
26
|
awbRefresh?(params: P): boolean;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Same contract as {@link ICellRendererNgComp}, for `headerComponent` / `headerCellComponent`.
|
|
30
|
+
* `awbRefresh` runs when the header's sort/filter state changes; without it the params are simply
|
|
31
|
+
* re-delivered.
|
|
32
|
+
*/
|
|
33
|
+
interface IHeaderNgComp<P extends HeaderComponentParams = HeaderComponentParams> {
|
|
34
|
+
awbInit(params: P): void;
|
|
35
|
+
awbRefresh?(params: P): boolean;
|
|
36
|
+
}
|
|
28
37
|
/** Angular component contract for a regular set-filter value label. */
|
|
29
38
|
interface ISetFilterValueNgComp<P extends SetFilterValueComponentParams = SetFilterValueComponentParams> {
|
|
30
39
|
awbInit(params: P): void;
|
|
@@ -57,7 +66,7 @@ interface ICellEditorNgComp<P extends ICellEditorParams = ICellEditorParams> {
|
|
|
57
66
|
/** Return true to abort opening the editor. */
|
|
58
67
|
isCancelBeforeStart?(): boolean;
|
|
59
68
|
}
|
|
60
|
-
/** An Angular component class usable as a cell renderer / tooltip / ActionFrame / editor. */
|
|
69
|
+
/** An Angular component class usable as a cell renderer / tooltip / ActionFrame / editor / header. */
|
|
61
70
|
type NgComponent = Type<unknown>;
|
|
62
71
|
type NgFilterParams = Omit<FilterParams, "valueComponent" | "selectAllComponent" | "blanksComponent" | "groupComponent"> & {
|
|
63
72
|
valueComponent?: SetFilterValueComponent | NgComponent;
|
|
@@ -74,17 +83,20 @@ type NgRowPresentation = Omit<RowPresentation, "tooltip"> & {
|
|
|
74
83
|
type NgGetRowPresentation = (params: RowPresentationParams) => NgRowPresentation | null | undefined;
|
|
75
84
|
/**
|
|
76
85
|
* Angular-aware column definition: identical to the core {@link ColDef}, but every component slot
|
|
77
|
-
* (cellRenderer, cellEditor, tooltipComponent, headerTooltip, actionFrameComponent
|
|
86
|
+
* (cellRenderer, cellEditor, tooltipComponent, headerTooltip, actionFrameComponent, headerComponent,
|
|
87
|
+
* headerCellComponent, and the set-filter components in filterParams) may also be an
|
|
78
88
|
* Angular component class. Angular components are wrapped in core adapter classes; core renderer
|
|
79
89
|
* classes and string aliases pass through unchanged.
|
|
80
90
|
*/
|
|
81
|
-
type NgColDef = Omit<ColDef, "cellRenderer" | "cellEditor" | "children" | "tooltipComponent" | "headerTooltip" | "actionFrameComponent" | "filterParams"> & {
|
|
91
|
+
type NgColDef = Omit<ColDef, "cellRenderer" | "cellEditor" | "children" | "tooltipComponent" | "headerTooltip" | "actionFrameComponent" | "filterParams" | "headerComponent" | "headerCellComponent"> & {
|
|
82
92
|
cellRenderer?: CellRenderer | NgComponent;
|
|
83
93
|
cellEditor?: CellEditor | NgComponent;
|
|
84
94
|
tooltipComponent?: TooltipComponent | NgComponent;
|
|
85
95
|
headerTooltip?: string | TooltipComponent | NgComponent;
|
|
86
96
|
actionFrameComponent?: ActionFrameComponent | NgComponent;
|
|
87
97
|
filterParams?: NgFilterParams;
|
|
98
|
+
headerComponent?: HeaderComponent | NgComponent;
|
|
99
|
+
headerCellComponent?: HeaderComponent | NgComponent;
|
|
88
100
|
children?: NgColDef[];
|
|
89
101
|
};
|
|
90
102
|
/**
|
|
@@ -93,6 +105,12 @@ type NgColDef = Omit<ColDef, "cellRenderer" | "cellEditor" | "children" | "toolt
|
|
|
93
105
|
* `DefaultColDef`, but its component fields may be Angular components.
|
|
94
106
|
*/
|
|
95
107
|
type NgDefaultColDef = Omit<NgColDef, (typeof NON_DEFAULTABLE_COLDEF_KEYS)[number]>;
|
|
108
|
+
/**
|
|
109
|
+
* Angular-aware shape of the partial column defs the grid layers over a synthesized column
|
|
110
|
+
* (`groupColumnDef`, `pivotResultColumnDef`): a `Partial<NgColDef>`, so component fields may be
|
|
111
|
+
* Angular components.
|
|
112
|
+
*/
|
|
113
|
+
type NgPartialColDef = Partial<Omit<NgColDef, "children">>;
|
|
96
114
|
|
|
97
115
|
/**
|
|
98
116
|
* A menu-item slot in the Angular wrapper: a plain string, a ready-made element, or an
|
|
@@ -128,7 +146,7 @@ declare class AwbGrid implements OnDestroy {
|
|
|
128
146
|
readonly maxColumnWidth: _angular_core.InputSignal<number | undefined>;
|
|
129
147
|
readonly pivotMode: _angular_core.InputSignal<boolean | undefined>;
|
|
130
148
|
readonly pivotColumns: _angular_core.InputSignal<string[] | undefined>;
|
|
131
|
-
readonly pivotResultColumnDef: _angular_core.InputSignal<Partial<
|
|
149
|
+
readonly pivotResultColumnDef: _angular_core.InputSignal<Partial<Omit<NgColDef, "children">> | undefined>;
|
|
132
150
|
readonly maxPivotColumns: _angular_core.InputSignal<number | undefined>;
|
|
133
151
|
readonly pivotColumnMoveMode: _angular_core.InputSignal<"measures" | "free" | undefined>;
|
|
134
152
|
readonly autosizeColumnsOnDataChange: _angular_core.InputSignal<boolean | undefined>;
|
|
@@ -178,7 +196,7 @@ declare class AwbGrid implements OnDestroy {
|
|
|
178
196
|
readonly quickFilter: _angular_core.InputSignal<boolean | _agility_workbench_grid.QuickFilterOptions | undefined>;
|
|
179
197
|
readonly filterDebounceMs: _angular_core.InputSignal<number | undefined>;
|
|
180
198
|
readonly groupDisplayType: _angular_core.InputSignal<_agility_workbench_grid.GroupDisplayType | undefined>;
|
|
181
|
-
readonly groupColumnDef: _angular_core.InputSignal<Partial<
|
|
199
|
+
readonly groupColumnDef: _angular_core.InputSignal<Partial<Omit<NgColDef, "children">> | undefined>;
|
|
182
200
|
readonly groupDefaultExpanded: _angular_core.InputSignal<number | undefined>;
|
|
183
201
|
readonly groupSortMode: _angular_core.InputSignal<_agility_workbench_grid.GroupSortMode | undefined>;
|
|
184
202
|
readonly groupRowsSelectable: _angular_core.InputSignal<boolean | undefined>;
|
|
@@ -280,6 +298,13 @@ declare class AwbGrid implements OnDestroy {
|
|
|
280
298
|
* rebuild UI on re-application skip their first run via `keyedEffect`.
|
|
281
299
|
*/
|
|
282
300
|
private startSyncEffects;
|
|
301
|
+
/**
|
|
302
|
+
* Development only. Creation-only inputs are read once, by createGrid; a later change to one is
|
|
303
|
+
* ignored. Instead of letting that change vanish silently, warn once per input (per grid
|
|
304
|
+
* instance), comparing against the value the grid was created with. The input list is core's
|
|
305
|
+
* creation-only key list, intersected with the inputs this component declares.
|
|
306
|
+
*/
|
|
307
|
+
private startCreationOnlyWarnings;
|
|
283
308
|
/**
|
|
284
309
|
* Effect helper: `read` runs tracked (signal reads register dependencies) and returns the core
|
|
285
310
|
* call to make, or null to skip; the call itself runs outside the Angular zone so core-side
|
|
@@ -299,4 +324,4 @@ declare class AwbGrid implements OnDestroy {
|
|
|
299
324
|
}
|
|
300
325
|
|
|
301
326
|
export { AwbGrid };
|
|
302
|
-
export type { IActionFrameNgComp, ICellEditorNgComp, ICellRendererNgComp, ISetFilterGroupNgComp, ISetFilterSpecialValueNgComp, ISetFilterValueNgComp, ITooltipNgComp, NgColDef, NgComponent, NgDefaultColDef, NgFilterParams, NgGetRowPresentation, NgMenuItem, NgMenuSlot, NgRowPresentation, NgRowTooltipPresentation };
|
|
327
|
+
export type { IActionFrameNgComp, ICellEditorNgComp, ICellRendererNgComp, IHeaderNgComp, ISetFilterGroupNgComp, ISetFilterSpecialValueNgComp, ISetFilterValueNgComp, ITooltipNgComp, NgColDef, NgComponent, NgDefaultColDef, NgFilterParams, NgGetRowPresentation, NgMenuItem, NgMenuSlot, NgPartialColDef, NgRowPresentation, NgRowTooltipPresentation };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agility-workbench/angular-grid",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Angular bindings for @agility-workbench/grid — a high-performance data grid. Supports Angular 20.3 through 22.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Himanshu M",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@agility-workbench/grid": "^1.
|
|
36
|
+
"@agility-workbench/grid": "^1.11.0",
|
|
37
37
|
"tslib": "^2.3.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|