@thkl/agrid 0.1.3 → 0.1.5
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 +30 -1
- package/fesm2022/thkl-agrid.mjs +338 -15
- package/fesm2022/thkl-agrid.mjs.map +1 -1
- package/package.json +2 -2
- package/types/thkl-agrid.d.ts +107 -2
- package/types/thkl-agrid.d.ts.map +1 -1
package/fesm2022/thkl-agrid.mjs
CHANGED
|
@@ -83,6 +83,15 @@ function isDataRowItem(item) {
|
|
|
83
83
|
function isGroupHeaderItem(item) {
|
|
84
84
|
return typeof item === 'object' && item !== null && 'groupLabel' in item;
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns whether a virtual-scroll item represents a tree row.
|
|
88
|
+
*
|
|
89
|
+
* Tree rows also pass {@link isDataRowItem} (they carry `row` + `originalIndex`); this guard
|
|
90
|
+
* additionally narrows to the indentation/expansion fields via the `level` discriminator.
|
|
91
|
+
*/
|
|
92
|
+
function isTreeRowItem(item) {
|
|
93
|
+
return typeof item === 'object' && item !== null && 'level' in item;
|
|
94
|
+
}
|
|
86
95
|
// Filtering
|
|
87
96
|
/** Apply text substring and value-set filters, returning the surviving row indices. */
|
|
88
97
|
function applyTextAndValueFilters(rows, indices, filters, colMap, locale) {
|
|
@@ -196,6 +205,63 @@ function buildGroupedItems(rows, indices, groupField, colMap, sortEntries, expan
|
|
|
196
205
|
}
|
|
197
206
|
return items;
|
|
198
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Flatten a parent/child hierarchy into a depth-first list of {@link TreeRowItem}s for the
|
|
210
|
+
* virtual scroll list, honoring the expanded-id set.
|
|
211
|
+
*
|
|
212
|
+
* `indices` is the already filtered and sorted set of source-array positions; sibling order
|
|
213
|
+
* follows that order. A row is treated as a **root** when its parent id is `null`/`undefined`
|
|
214
|
+
* or when that parent is not present in `indices` (orphan). Children of a collapsed row are
|
|
215
|
+
* omitted. Cycles and rows visited more than once are guarded so the walk always terminates.
|
|
216
|
+
*
|
|
217
|
+
* @param rows The full data-source array.
|
|
218
|
+
* @param indices Filtered/sorted source positions to include, in display order.
|
|
219
|
+
* @param accessors `getId` / `getParentId` for the rows.
|
|
220
|
+
* @param expandedIds Ids whose children should be rendered.
|
|
221
|
+
* @param forceExpandedIds Ids forced open regardless of `expandedIds` — used to reveal the
|
|
222
|
+
* ancestor path of filter matches. Optional.
|
|
223
|
+
*/
|
|
224
|
+
function buildTreeItems(rows, indices, accessors, expandedIds, forceExpandedIds) {
|
|
225
|
+
const { getId, getParentId } = accessors;
|
|
226
|
+
const includedIds = new Set();
|
|
227
|
+
for (const i of indices)
|
|
228
|
+
includedIds.add(getId(rows[i]));
|
|
229
|
+
// Bucket each included row under its parent, preserving the incoming (sorted) order.
|
|
230
|
+
const childrenByParent = new Map();
|
|
231
|
+
const roots = [];
|
|
232
|
+
for (const i of indices) {
|
|
233
|
+
const parentId = getParentId(rows[i]);
|
|
234
|
+
if (parentId == null || !includedIds.has(parentId)) {
|
|
235
|
+
roots.push(i);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const siblings = childrenByParent.get(parentId);
|
|
239
|
+
if (siblings)
|
|
240
|
+
siblings.push(i);
|
|
241
|
+
else
|
|
242
|
+
childrenByParent.set(parentId, [i]);
|
|
243
|
+
}
|
|
244
|
+
const items = [];
|
|
245
|
+
const visited = new Set();
|
|
246
|
+
const visit = (index, level) => {
|
|
247
|
+
const row = rows[index];
|
|
248
|
+
const id = getId(row);
|
|
249
|
+
if (visited.has(id))
|
|
250
|
+
return; // cycle / duplicate-parent guard
|
|
251
|
+
visited.add(id);
|
|
252
|
+
const children = childrenByParent.get(id);
|
|
253
|
+
const expandable = !!children?.length;
|
|
254
|
+
const expanded = expandable && (expandedIds.has(id) || !!forceExpandedIds?.has(id));
|
|
255
|
+
items.push({ row, originalIndex: index, level, expandable, expanded });
|
|
256
|
+
if (expanded && children) {
|
|
257
|
+
for (const childIndex of children)
|
|
258
|
+
visit(childIndex, level + 1);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
for (const rootIndex of roots)
|
|
262
|
+
visit(rootIndex, 0);
|
|
263
|
+
return items;
|
|
264
|
+
}
|
|
199
265
|
// Selection range
|
|
200
266
|
/** Build the set of original indices spanning from `fromOrig` to `toOrig` in display order. */
|
|
201
267
|
function buildSelectionRange(fromOrig, toOrig, items) {
|
|
@@ -238,6 +304,18 @@ class AgridCellComponent {
|
|
|
238
304
|
selected = input(false, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
239
305
|
/** Whether this cell is currently in edit mode. */
|
|
240
306
|
editing = input(false, ...(ngDevMode ? [{ debugName: "editing" }] : /* istanbul ignore next */ []));
|
|
307
|
+
/** Whether this cell is the tree column and should render indentation + a twisty. */
|
|
308
|
+
treeCell = input(false, ...(ngDevMode ? [{ debugName: "treeCell" }] : /* istanbul ignore next */ []));
|
|
309
|
+
/** Depth of the row in the tree (drives indentation). Root rows are `0`. */
|
|
310
|
+
treeLevel = input(0, ...(ngDevMode ? [{ debugName: "treeLevel" }] : /* istanbul ignore next */ []));
|
|
311
|
+
/** Whether the row has children and can be expanded/collapsed. */
|
|
312
|
+
treeExpandable = input(false, ...(ngDevMode ? [{ debugName: "treeExpandable" }] : /* istanbul ignore next */ []));
|
|
313
|
+
/** Whether the row is currently expanded. */
|
|
314
|
+
treeExpanded = input(false, ...(ngDevMode ? [{ debugName: "treeExpanded" }] : /* istanbul ignore next */ []));
|
|
315
|
+
/** Emitted when the user clicks the expand/collapse twisty. */
|
|
316
|
+
treeToggle = output();
|
|
317
|
+
/** Indentation in pixels applied per tree level. */
|
|
318
|
+
treeIndent = 16;
|
|
241
319
|
/**
|
|
242
320
|
* Optional character to pre-fill the edit input when the user presses a printable key
|
|
243
321
|
* while the cell is selected (type-to-start-editing behavior).
|
|
@@ -354,6 +432,11 @@ class AgridCellComponent {
|
|
|
354
432
|
}
|
|
355
433
|
});
|
|
356
434
|
}
|
|
435
|
+
/** Emit a tree expand/collapse request without selecting or editing the cell. */
|
|
436
|
+
onTreeToggle(event) {
|
|
437
|
+
event.stopPropagation();
|
|
438
|
+
this.treeToggle.emit();
|
|
439
|
+
}
|
|
357
440
|
/** Forward `<input>` changes to the grid. */
|
|
358
441
|
onInput(event) {
|
|
359
442
|
const val = event.target.value;
|
|
@@ -375,7 +458,7 @@ class AgridCellComponent {
|
|
|
375
458
|
this.draftChange.emit(rawValue);
|
|
376
459
|
}
|
|
377
460
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AgridCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
378
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AgridCellComponent, isStandalone: true, selector: "agrid-cell", inputs: { col: { classPropertyName: "col", publicName: "col", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, colIndex: { classPropertyName: "colIndex", publicName: "colIndex", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, seedChar: { classPropertyName: "seedChar", publicName: "seedChar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activate: "activate", startEdit: "startEdit", draftChange: "draftChange" }, host: { attributes: { "role": "gridcell", "tabindex": "-1" }, listeners: { "click": "activate.emit($event)", "dblclick": "startEdit.emit()" }, properties: { "class.selected": "selected()", "class.editing": "editing()", "attr.aria-readonly": "col().editable === false ? \"true\" : null" } }, viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["editInput"], descendants: true, isSignal: true }, { propertyName: "selectEl", first: true, predicate: ["editSelect"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
461
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AgridCellComponent, isStandalone: true, selector: "agrid-cell", inputs: { col: { classPropertyName: "col", publicName: "col", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, colIndex: { classPropertyName: "colIndex", publicName: "colIndex", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, treeCell: { classPropertyName: "treeCell", publicName: "treeCell", isSignal: true, isRequired: false, transformFunction: null }, treeLevel: { classPropertyName: "treeLevel", publicName: "treeLevel", isSignal: true, isRequired: false, transformFunction: null }, treeExpandable: { classPropertyName: "treeExpandable", publicName: "treeExpandable", isSignal: true, isRequired: false, transformFunction: null }, treeExpanded: { classPropertyName: "treeExpanded", publicName: "treeExpanded", isSignal: true, isRequired: false, transformFunction: null }, seedChar: { classPropertyName: "seedChar", publicName: "seedChar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { treeToggle: "treeToggle", activate: "activate", startEdit: "startEdit", draftChange: "draftChange" }, host: { attributes: { "role": "gridcell", "tabindex": "-1" }, listeners: { "click": "activate.emit($event)", "dblclick": "startEdit.emit()" }, properties: { "class.selected": "selected()", "class.editing": "editing()", "class.ag-cell--tree": "treeCell()", "attr.aria-readonly": "col().editable === false ? \"true\" : null" } }, viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["editInput"], descendants: true, isSignal: true }, { propertyName: "selectEl", first: true, predicate: ["editSelect"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
379
462
|
@if (editing()) {
|
|
380
463
|
@if (col().values?.length) {
|
|
381
464
|
<select
|
|
@@ -396,12 +479,29 @@ class AgridCellComponent {
|
|
|
396
479
|
(input)="onInput($event)"
|
|
397
480
|
/>
|
|
398
481
|
}
|
|
399
|
-
} @else if (col().cellRenderer) {
|
|
400
|
-
<span class="ag-cell-value" [innerHTML]="renderedHtml()"></span>
|
|
401
482
|
} @else {
|
|
402
|
-
|
|
483
|
+
@if (treeCell()) {
|
|
484
|
+
<span class="ag-tree-prefix" [style.padding-left.px]="treeLevel() * treeIndent">
|
|
485
|
+
@if (treeExpandable()) {
|
|
486
|
+
<button
|
|
487
|
+
type="button"
|
|
488
|
+
class="ag-tree-twisty"
|
|
489
|
+
[class.ag-tree-twisty--expanded]="treeExpanded()"
|
|
490
|
+
[attr.aria-label]="treeExpanded() ? 'Collapse' : 'Expand'"
|
|
491
|
+
(click)="onTreeToggle($event)"
|
|
492
|
+
>▶</button>
|
|
493
|
+
} @else {
|
|
494
|
+
<span class="ag-tree-twisty-spacer"></span>
|
|
495
|
+
}
|
|
496
|
+
</span>
|
|
497
|
+
}
|
|
498
|
+
@if (col().cellRenderer) {
|
|
499
|
+
<span class="ag-cell-value" [innerHTML]="renderedHtml()"></span>
|
|
500
|
+
} @else {
|
|
501
|
+
<span class="ag-cell-value">{{ displayValue() }}</span>
|
|
502
|
+
}
|
|
403
503
|
}
|
|
404
|
-
`, isInline: true, styles: [":host{position:relative;display:block;border-right:1px solid var(--agrid-color-border);border-bottom:1px solid var(--agrid-color-border);overflow:hidden;white-space:nowrap;padding:0 6px;line-height:32px;cursor:default;-webkit-user-select:none;user-select:none;outline:none;box-sizing:border-box}:host(.ag-cell--changed):after{content:\"\";position:absolute;top:0;right:0;width:0;height:0;border-top:8px solid var(--agrid-color-cell-changed);border-left:8px solid transparent;pointer-events:none}:host(.selected){outline:2px solid var(--agrid-color-accent);outline-offset:-2px}:host(.ag-cell--range-selected){outline:2px solid var(--agrid-color-accent);outline-offset:-2px}:host(.editing){padding:0;background:var(--agrid-color-bg)}.ag-cell-value{display:block;overflow:hidden;text-overflow:ellipsis}.ag-cell-input{width:100%;height:100%;border:none;outline:none;font:inherit;padding:0 6px;box-sizing:border-box;background:transparent}.ag-cell-select{width:100%;height:100%;border:none;outline:none;font:inherit;padding:0 2px;box-sizing:border-box;background:transparent;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
504
|
+
`, isInline: true, styles: [":host{position:relative;display:block;border-right:1px solid var(--agrid-color-border);border-bottom:1px solid var(--agrid-color-border);overflow:hidden;white-space:nowrap;padding:0 6px;line-height:32px;cursor:default;-webkit-user-select:none;user-select:none;outline:none;box-sizing:border-box}:host(.ag-cell--changed):after{content:\"\";position:absolute;top:0;right:0;width:0;height:0;border-top:8px solid var(--agrid-color-cell-changed);border-left:8px solid transparent;pointer-events:none}:host(.selected){outline:2px solid var(--agrid-color-accent);outline-offset:-2px}:host(.ag-cell--range-selected){outline:2px solid var(--agrid-color-accent);outline-offset:-2px}:host(.editing){padding:0;background:var(--agrid-color-bg)}.ag-cell-value{display:block;overflow:hidden;text-overflow:ellipsis}:host(.ag-cell--tree){display:flex;align-items:center}:host(.ag-cell--tree) .ag-cell-value{flex:1 1 auto;min-width:0}.ag-tree-prefix{flex:0 0 auto;display:inline-flex;align-items:center;height:100%}.ag-tree-twisty,.ag-tree-twisty-spacer{width:16px;flex:0 0 16px}.ag-tree-twisty{display:inline-flex;align-items:center;justify-content:center;height:100%;padding:0;border:none;background:transparent;color:var(--agrid-color-text-muted);font-size:9px;line-height:1;cursor:pointer;transition:transform .15s ease}.ag-tree-twisty--expanded{transform:rotate(90deg)}.ag-cell-input{width:100%;height:100%;border:none;outline:none;font:inherit;padding:0 6px;box-sizing:border-box;background:transparent}.ag-cell-select{width:100%;height:100%;border:none;outline:none;font:inherit;padding:0 2px;box-sizing:border-box;background:transparent;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
405
505
|
}
|
|
406
506
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AgridCellComponent, decorators: [{
|
|
407
507
|
type: Component,
|
|
@@ -409,6 +509,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
409
509
|
role: 'gridcell',
|
|
410
510
|
'[class.selected]': 'selected()',
|
|
411
511
|
'[class.editing]': 'editing()',
|
|
512
|
+
'[class.ag-cell--tree]': 'treeCell()',
|
|
412
513
|
'[attr.aria-readonly]': 'col().editable === false ? "true" : null',
|
|
413
514
|
'(click)': 'activate.emit($event)',
|
|
414
515
|
'(dblclick)': 'startEdit.emit()',
|
|
@@ -434,13 +535,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
434
535
|
(input)="onInput($event)"
|
|
435
536
|
/>
|
|
436
537
|
}
|
|
437
|
-
} @else if (col().cellRenderer) {
|
|
438
|
-
<span class="ag-cell-value" [innerHTML]="renderedHtml()"></span>
|
|
439
538
|
} @else {
|
|
440
|
-
|
|
539
|
+
@if (treeCell()) {
|
|
540
|
+
<span class="ag-tree-prefix" [style.padding-left.px]="treeLevel() * treeIndent">
|
|
541
|
+
@if (treeExpandable()) {
|
|
542
|
+
<button
|
|
543
|
+
type="button"
|
|
544
|
+
class="ag-tree-twisty"
|
|
545
|
+
[class.ag-tree-twisty--expanded]="treeExpanded()"
|
|
546
|
+
[attr.aria-label]="treeExpanded() ? 'Collapse' : 'Expand'"
|
|
547
|
+
(click)="onTreeToggle($event)"
|
|
548
|
+
>▶</button>
|
|
549
|
+
} @else {
|
|
550
|
+
<span class="ag-tree-twisty-spacer"></span>
|
|
551
|
+
}
|
|
552
|
+
</span>
|
|
553
|
+
}
|
|
554
|
+
@if (col().cellRenderer) {
|
|
555
|
+
<span class="ag-cell-value" [innerHTML]="renderedHtml()"></span>
|
|
556
|
+
} @else {
|
|
557
|
+
<span class="ag-cell-value">{{ displayValue() }}</span>
|
|
558
|
+
}
|
|
441
559
|
}
|
|
442
|
-
`, styles: [":host{position:relative;display:block;border-right:1px solid var(--agrid-color-border);border-bottom:1px solid var(--agrid-color-border);overflow:hidden;white-space:nowrap;padding:0 6px;line-height:32px;cursor:default;-webkit-user-select:none;user-select:none;outline:none;box-sizing:border-box}:host(.ag-cell--changed):after{content:\"\";position:absolute;top:0;right:0;width:0;height:0;border-top:8px solid var(--agrid-color-cell-changed);border-left:8px solid transparent;pointer-events:none}:host(.selected){outline:2px solid var(--agrid-color-accent);outline-offset:-2px}:host(.ag-cell--range-selected){outline:2px solid var(--agrid-color-accent);outline-offset:-2px}:host(.editing){padding:0;background:var(--agrid-color-bg)}.ag-cell-value{display:block;overflow:hidden;text-overflow:ellipsis}.ag-cell-input{width:100%;height:100%;border:none;outline:none;font:inherit;padding:0 6px;box-sizing:border-box;background:transparent}.ag-cell-select{width:100%;height:100%;border:none;outline:none;font:inherit;padding:0 2px;box-sizing:border-box;background:transparent;cursor:pointer}\n"] }]
|
|
443
|
-
}], ctorParameters: () => [], propDecorators: { col: [{ type: i0.Input, args: [{ isSignal: true, alias: "col", required: true }] }], rowIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIndex", required: true }] }], colIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "colIndex", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], seedChar: [{ type: i0.Input, args: [{ isSignal: true, alias: "seedChar", required: false }] }], activate: [{ type: i0.Output, args: ["activate"] }], startEdit: [{ type: i0.Output, args: ["startEdit"] }], draftChange: [{ type: i0.Output, args: ["draftChange"] }], inputEl: [{ type: i0.ViewChild, args: ['editInput', { isSignal: true }] }], selectEl: [{ type: i0.ViewChild, args: ['editSelect', { isSignal: true }] }] } });
|
|
560
|
+
`, styles: [":host{position:relative;display:block;border-right:1px solid var(--agrid-color-border);border-bottom:1px solid var(--agrid-color-border);overflow:hidden;white-space:nowrap;padding:0 6px;line-height:32px;cursor:default;-webkit-user-select:none;user-select:none;outline:none;box-sizing:border-box}:host(.ag-cell--changed):after{content:\"\";position:absolute;top:0;right:0;width:0;height:0;border-top:8px solid var(--agrid-color-cell-changed);border-left:8px solid transparent;pointer-events:none}:host(.selected){outline:2px solid var(--agrid-color-accent);outline-offset:-2px}:host(.ag-cell--range-selected){outline:2px solid var(--agrid-color-accent);outline-offset:-2px}:host(.editing){padding:0;background:var(--agrid-color-bg)}.ag-cell-value{display:block;overflow:hidden;text-overflow:ellipsis}:host(.ag-cell--tree){display:flex;align-items:center}:host(.ag-cell--tree) .ag-cell-value{flex:1 1 auto;min-width:0}.ag-tree-prefix{flex:0 0 auto;display:inline-flex;align-items:center;height:100%}.ag-tree-twisty,.ag-tree-twisty-spacer{width:16px;flex:0 0 16px}.ag-tree-twisty{display:inline-flex;align-items:center;justify-content:center;height:100%;padding:0;border:none;background:transparent;color:var(--agrid-color-text-muted);font-size:9px;line-height:1;cursor:pointer;transition:transform .15s ease}.ag-tree-twisty--expanded{transform:rotate(90deg)}.ag-cell-input{width:100%;height:100%;border:none;outline:none;font:inherit;padding:0 6px;box-sizing:border-box;background:transparent}.ag-cell-select{width:100%;height:100%;border:none;outline:none;font:inherit;padding:0 2px;box-sizing:border-box;background:transparent;cursor:pointer}\n"] }]
|
|
561
|
+
}], ctorParameters: () => [], propDecorators: { col: [{ type: i0.Input, args: [{ isSignal: true, alias: "col", required: true }] }], rowIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIndex", required: true }] }], colIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "colIndex", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], treeCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeCell", required: false }] }], treeLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeLevel", required: false }] }], treeExpandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeExpandable", required: false }] }], treeExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeExpanded", required: false }] }], treeToggle: [{ type: i0.Output, args: ["treeToggle"] }], seedChar: [{ type: i0.Input, args: [{ isSignal: true, alias: "seedChar", required: false }] }], activate: [{ type: i0.Output, args: ["activate"] }], startEdit: [{ type: i0.Output, args: ["startEdit"] }], draftChange: [{ type: i0.Output, args: ["draftChange"] }], inputEl: [{ type: i0.ViewChild, args: ['editInput', { isSignal: true }] }], selectEl: [{ type: i0.ViewChild, args: ['editSelect', { isSignal: true }] }] } });
|
|
444
562
|
|
|
445
563
|
/** Guarded access to browser-only APIs used by the grid. @internal */
|
|
446
564
|
class AgridBrowserAdapter {
|
|
@@ -1407,6 +1525,15 @@ class AgridColumnMenuController {
|
|
|
1407
1525
|
toggleColumnVisibility(field) {
|
|
1408
1526
|
this.opts.control()?.toggleColumnVisibility(field);
|
|
1409
1527
|
}
|
|
1528
|
+
/** Sets visibility for several fields from a sidebar header-group toggle. */
|
|
1529
|
+
setColumnsVisibility(fields, visible) {
|
|
1530
|
+
const control = this.opts.control();
|
|
1531
|
+
if (!control)
|
|
1532
|
+
return;
|
|
1533
|
+
for (const field of fields) {
|
|
1534
|
+
control.setColumnVisibility(field, visible);
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1410
1537
|
getColDef(field) {
|
|
1411
1538
|
return this.opts.colDefs().find(col => col.field === field);
|
|
1412
1539
|
}
|
|
@@ -2264,6 +2391,59 @@ class AgridGroupController {
|
|
|
2264
2391
|
}
|
|
2265
2392
|
}
|
|
2266
2393
|
|
|
2394
|
+
/**
|
|
2395
|
+
* Owns the expand/collapse state of a hierarchical (tree) grid.
|
|
2396
|
+
*
|
|
2397
|
+
* Expansion is keyed by **node id** (from {@link AgridTreeConfig.getId}), independent of any
|
|
2398
|
+
* column or grouping field, so it works at arbitrary depth. Ids that no longer exist in the
|
|
2399
|
+
* data simply never match and are harmless, so the state does not need to be reset when the
|
|
2400
|
+
* underlying rows change.
|
|
2401
|
+
*
|
|
2402
|
+
* Mirrors {@link AgridGroupController} in spirit but is intentionally option-free — the grid
|
|
2403
|
+
* component supplies node ids to {@link expandAll} from the current data source.
|
|
2404
|
+
* @internal
|
|
2405
|
+
*/
|
|
2406
|
+
class AgridTreeController {
|
|
2407
|
+
/** Ids of the nodes that are currently expanded (their children are visible). */
|
|
2408
|
+
expandedIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedIds" }] : /* istanbul ignore next */ []));
|
|
2409
|
+
/** Returns `true` when the node with `id` is currently expanded. */
|
|
2410
|
+
isExpanded(id) {
|
|
2411
|
+
return this.expandedIds().has(id);
|
|
2412
|
+
}
|
|
2413
|
+
/** Toggle the expanded state of a single node. */
|
|
2414
|
+
toggle(id) {
|
|
2415
|
+
this.expandedIds.update(ids => {
|
|
2416
|
+
const next = new Set(ids);
|
|
2417
|
+
if (next.has(id))
|
|
2418
|
+
next.delete(id);
|
|
2419
|
+
else
|
|
2420
|
+
next.add(id);
|
|
2421
|
+
return next;
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
/** Explicitly expand or collapse a single node. */
|
|
2425
|
+
setExpanded(id, expanded) {
|
|
2426
|
+
this.expandedIds.update(ids => {
|
|
2427
|
+
if (expanded === ids.has(id))
|
|
2428
|
+
return ids;
|
|
2429
|
+
const next = new Set(ids);
|
|
2430
|
+
if (expanded)
|
|
2431
|
+
next.add(id);
|
|
2432
|
+
else
|
|
2433
|
+
next.delete(id);
|
|
2434
|
+
return next;
|
|
2435
|
+
});
|
|
2436
|
+
}
|
|
2437
|
+
/** Expand every node in `ids` (typically all expandable nodes in the data source). */
|
|
2438
|
+
expandAll(ids) {
|
|
2439
|
+
this.expandedIds.set(new Set(ids));
|
|
2440
|
+
}
|
|
2441
|
+
/** Collapse every node. */
|
|
2442
|
+
collapseAll() {
|
|
2443
|
+
this.expandedIds.set(new Set());
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2267
2447
|
/**
|
|
2268
2448
|
* Owns grid keyboard navigation, cell activation, add-row creation, and visibility scrolling.
|
|
2269
2449
|
* @internal
|
|
@@ -3180,6 +3360,8 @@ class AgridProvider {
|
|
|
3180
3360
|
columns;
|
|
3181
3361
|
/** Header-group labels referenced by column definitions. */
|
|
3182
3362
|
headerGroups;
|
|
3363
|
+
/** Tree configuration, or `null` when the grid is not in tree mode. */
|
|
3364
|
+
treeConfig;
|
|
3183
3365
|
/** Shared grid options such as locale. */
|
|
3184
3366
|
options;
|
|
3185
3367
|
_localizations = new Map();
|
|
@@ -3252,6 +3434,7 @@ class AgridProvider {
|
|
|
3252
3434
|
this.control = config.control ?? new AgridControl({ allowRowReorder: true });
|
|
3253
3435
|
this.columns = signal(config.columns ?? [], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
3254
3436
|
this.headerGroups = config.headerGroups ?? [];
|
|
3437
|
+
this.treeConfig = config.treeConfig ?? null;
|
|
3255
3438
|
this.rowHeight = config.rowHeight ?? 32;
|
|
3256
3439
|
this.minHeight = config.minHeight;
|
|
3257
3440
|
this.maxHeight = config.maxHeight;
|
|
@@ -3310,6 +3493,18 @@ class AgridProjectionModel {
|
|
|
3310
3493
|
}, ...(ngDevMode ? [{ debugName: "filteredSortedIndices" }] : /* istanbul ignore next */ []));
|
|
3311
3494
|
/** Total filtered row count, unaffected by client-side pagination. */
|
|
3312
3495
|
filteredRowCount = computed(() => this.filteredSortedIndices().length, ...(ngDevMode ? [{ debugName: "filteredRowCount" }] : /* istanbul ignore next */ []));
|
|
3496
|
+
/** All source indices in active sort order, ignoring filters. Used for tree ancestor ordering. */
|
|
3497
|
+
allSortedIndices = computed(() => {
|
|
3498
|
+
const rows = this.opts.dataSource().rows();
|
|
3499
|
+
const control = this.opts.control();
|
|
3500
|
+
const indices = rows.map((_, index) => index);
|
|
3501
|
+
if (!control || this.opts.serverSideFiltering())
|
|
3502
|
+
return indices;
|
|
3503
|
+
const sortEntries = this.sortEntries(control.filters());
|
|
3504
|
+
return sortEntries.length
|
|
3505
|
+
? applySortToIndices(rows, indices, sortEntries, this.columnMap(), this.opts.locale())
|
|
3506
|
+
: indices;
|
|
3507
|
+
}, ...(ngDevMode ? [{ debugName: "allSortedIndices" }] : /* istanbul ignore next */ []));
|
|
3313
3508
|
/** Total page count using server total when server-side pagination is active. */
|
|
3314
3509
|
totalPages = computed(() => {
|
|
3315
3510
|
const control = this.opts.control();
|
|
@@ -3324,6 +3519,8 @@ class AgridProjectionModel {
|
|
|
3324
3519
|
/** Whether client or server pagination controls should be rendered. */
|
|
3325
3520
|
showPagination = computed(() => {
|
|
3326
3521
|
const control = this.opts.control();
|
|
3522
|
+
if (this.opts.treeConfig())
|
|
3523
|
+
return false;
|
|
3327
3524
|
return (control?.pageSize() ?? 0) > 0 && !control?.groupByField();
|
|
3328
3525
|
}, ...(ngDevMode ? [{ debugName: "showPagination" }] : /* istanbul ignore next */ []));
|
|
3329
3526
|
/** Whether at least one visible column has an aggregate footer. */
|
|
@@ -3374,6 +3571,42 @@ class AgridProjectionModel {
|
|
|
3374
3571
|
const rows = this.opts.dataSource().rows();
|
|
3375
3572
|
const control = this.opts.control();
|
|
3376
3573
|
let indices = this.filteredSortedIndices();
|
|
3574
|
+
// Tree mode takes precedence over grouping/pagination: the already filtered-and-sorted
|
|
3575
|
+
// indices are flattened into a hierarchy honoring the expanded-id set.
|
|
3576
|
+
const treeConfig = this.opts.treeConfig();
|
|
3577
|
+
if (treeConfig) {
|
|
3578
|
+
const expandedIds = this.opts.expandedTreeIds();
|
|
3579
|
+
// When a text/value filter is active, keep the ancestors of every match visible (and
|
|
3580
|
+
// force their path open) so deep matches don't vanish under filtered-out parents.
|
|
3581
|
+
const filters = control?.filters() ?? {};
|
|
3582
|
+
const filterActive = !this.opts.serverSideFiltering()
|
|
3583
|
+
&& Object.values(filters).some(f => f.text || f.selectedValues !== null);
|
|
3584
|
+
if (filterActive && treeConfig.keepAncestorsOnFilter !== false) {
|
|
3585
|
+
const { getId, getParentId } = treeConfig;
|
|
3586
|
+
const idToIndex = new Map();
|
|
3587
|
+
rows.forEach((row, index) => idToIndex.set(getId(row), index));
|
|
3588
|
+
const visible = new Set(indices);
|
|
3589
|
+
const forced = new Set();
|
|
3590
|
+
for (const matched of indices) {
|
|
3591
|
+
let parentId = getParentId(rows[matched]);
|
|
3592
|
+
while (parentId != null && idToIndex.has(parentId)) {
|
|
3593
|
+
const parentIndex = idToIndex.get(parentId);
|
|
3594
|
+
forced.add(parentId);
|
|
3595
|
+
if (visible.has(parentIndex))
|
|
3596
|
+
break; // chain already added by an earlier match
|
|
3597
|
+
visible.add(parentIndex);
|
|
3598
|
+
parentId = getParentId(rows[parentIndex]);
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
const ordered = this.allSortedIndices().filter(index => visible.has(index));
|
|
3602
|
+
const items = buildTreeItems(rows, ordered, treeConfig, expandedIds, forced);
|
|
3603
|
+
this.appendAddRow(items);
|
|
3604
|
+
return items;
|
|
3605
|
+
}
|
|
3606
|
+
const items = buildTreeItems(rows, indices, treeConfig, expandedIds);
|
|
3607
|
+
this.appendAddRow(items);
|
|
3608
|
+
return items;
|
|
3609
|
+
}
|
|
3377
3610
|
if (control) {
|
|
3378
3611
|
const groupField = control.groupByField();
|
|
3379
3612
|
const pageSize = control.pageSize();
|
|
@@ -3952,6 +4185,7 @@ class AgridSidebarComponent {
|
|
|
3952
4185
|
open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
3953
4186
|
activeTab = input('columns', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
|
|
3954
4187
|
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
4188
|
+
headerGroups = input([], ...(ngDevMode ? [{ debugName: "headerGroups" }] : /* istanbul ignore next */ []));
|
|
3955
4189
|
row = input(null, ...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
|
|
3956
4190
|
hiddenColumns = input(new Set(), ...(ngDevMode ? [{ debugName: "hiddenColumns" }] : /* istanbul ignore next */ []));
|
|
3957
4191
|
locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
@@ -3961,8 +4195,48 @@ class AgridSidebarComponent {
|
|
|
3961
4195
|
close = output();
|
|
3962
4196
|
tabChange = output();
|
|
3963
4197
|
toggleColumn = output();
|
|
4198
|
+
toggleColumnGroup = output();
|
|
3964
4199
|
detailEdit = output();
|
|
3965
4200
|
save = output();
|
|
4201
|
+
columnEntries = computed(() => {
|
|
4202
|
+
const groupLabels = new Map(this.headerGroups().map(group => [group.id, group.label]));
|
|
4203
|
+
const entries = [];
|
|
4204
|
+
const groupedEntries = new Map();
|
|
4205
|
+
for (const col of this.columns()) {
|
|
4206
|
+
const groupId = col.group;
|
|
4207
|
+
const groupLabel = groupId ? groupLabels.get(groupId) : undefined;
|
|
4208
|
+
if (!groupId || !groupLabel) {
|
|
4209
|
+
entries.push({ kind: 'column', col });
|
|
4210
|
+
continue;
|
|
4211
|
+
}
|
|
4212
|
+
let entry = groupedEntries.get(groupId);
|
|
4213
|
+
if (!entry) {
|
|
4214
|
+
entry = { kind: 'group', id: groupId, label: groupLabel, columns: [] };
|
|
4215
|
+
groupedEntries.set(groupId, entry);
|
|
4216
|
+
entries.push(entry);
|
|
4217
|
+
}
|
|
4218
|
+
entry.columns.push(col);
|
|
4219
|
+
}
|
|
4220
|
+
return entries;
|
|
4221
|
+
}, ...(ngDevMode ? [{ debugName: "columnEntries" }] : /* istanbul ignore next */ []));
|
|
4222
|
+
/** Whether every column in a group is currently visible. */
|
|
4223
|
+
isGroupVisible(columns) {
|
|
4224
|
+
const hidden = this.hiddenColumns();
|
|
4225
|
+
return columns.every(col => !hidden.has(col.field));
|
|
4226
|
+
}
|
|
4227
|
+
/** Whether a group contains both visible and hidden columns. */
|
|
4228
|
+
isGroupPartiallyVisible(columns) {
|
|
4229
|
+
const hidden = this.hiddenColumns();
|
|
4230
|
+
const visibleCount = columns.filter(col => !hidden.has(col.field)).length;
|
|
4231
|
+
return visibleCount > 0 && visibleCount < columns.length;
|
|
4232
|
+
}
|
|
4233
|
+
/** Emits a visibility request for all columns belonging to a group. */
|
|
4234
|
+
onGroupToggle(columns, event) {
|
|
4235
|
+
this.toggleColumnGroup.emit({
|
|
4236
|
+
fields: columns.map(col => col.field),
|
|
4237
|
+
visible: event.target.checked,
|
|
4238
|
+
});
|
|
4239
|
+
}
|
|
3966
4240
|
detailFields = computed(() => {
|
|
3967
4241
|
const row = this.row();
|
|
3968
4242
|
if (!row)
|
|
@@ -3988,12 +4262,12 @@ class AgridSidebarComponent {
|
|
|
3988
4262
|
});
|
|
3989
4263
|
}, ...(ngDevMode ? [{ debugName: "detailFields" }] : /* istanbul ignore next */ []));
|
|
3990
4264
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AgridSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3991
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AgridSidebarComponent, isStandalone: true, selector: "agrid-sidebar", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: false, transformFunction: null }, hiddenColumns: { classPropertyName: "hiddenColumns", publicName: "hiddenColumns", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, localeText: { classPropertyName: "localeText", publicName: "localeText", isSignal: true, isRequired: false, transformFunction: null }, readonlyGrid: { classPropertyName: "readonlyGrid", publicName: "readonlyGrid", isSignal: true, isRequired: false, transformFunction: null }, useSidebarEditor: { classPropertyName: "useSidebarEditor", publicName: "useSidebarEditor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", tabChange: "tabChange", toggleColumn: "toggleColumn", detailEdit: "detailEdit", save: "save" }, ngImport: i0, template: "@if (open()) {\n <div class=\"ag-sidebar\" role=\"region\"\n [attr.aria-label]=\"activeTab() === 'columns' ? localeText().columns : localeText().detail\">\n <div class=\"ag-sidebar-header\">\n <span>{{ activeTab() === 'columns' ? localeText().columns : localeText().detail }}</span>\n <button class=\"ag-sidebar-close\" (click)=\"close.emit()\" [title]=\"localeText().close\"\n [attr.aria-label]=\"localeText().close\">\u2715</button>\n </div>\n\n @if (activeTab() === 'columns') {\n @for (col of columns(); track col.field) {\n <label class=\"ag-sidebar-item\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"!hiddenColumns().has(col.field)\"\n (change)=\"toggleColumn.emit(col.field)\"\n />\n {{ col.header }}\n </label>\n }\n } @else {\n @if (detailFields(); as fields) {\n @for (field of fields; track field.col.field) {\n <div class=\"ag-detail-field\">\n <span class=\"ag-detail-label\">\n {{ field.label }}\n @if (field.hidden) {\n <span class=\"ag-detail-hidden\">{{ localeText().hiddenColumn }}</span>\n }\n </span>\n @if ((field.editable || useSidebarEditor()) && field.col.values?.length) {\n <select\n class=\"ag-detail-input\"\n (change)=\"detailEdit.emit({\n field: field.col.field,\n col: field.col,\n value: $any($event.target).value\n })\"\n >\n @for (opt of field.col.values; track $index) {\n @if ($any(opt).value !== undefined) {\n <option [value]=\"$any(opt).value\" [selected]=\"$any(opt).value === field.rawValue\">\n {{ $any(opt).label }}\n </option>\n } @else {\n <option [value]=\"opt\" [selected]=\"opt === field.rawValue\">{{ opt }}</option>\n }\n }\n </select>\n } @else if (field.editable || useSidebarEditor()) {\n <input\n class=\"ag-detail-input\"\n [type]=\"field.col.type === 'number' ? 'number' : field.col.type === 'date' ? 'date' : 'text'\"\n [value]=\"field.inputValue\"\n (change)=\"detailEdit.emit({\n field: field.col.field,\n col: field.col,\n value: $any($event.target).value\n })\"\n />\n } @else {\n <span class=\"ag-detail-value\">{{ field.value }}</span>\n }\n </div>\n }\n @if (useSidebarEditor()) {\n <div class=\"ag-detail-field\">\n <button class=\"ag-button\" (click)=\"save.emit(fields)\">{{ localeText().save }}</button>\n </div>\n }\n } @else {\n <div class=\"ag-detail-empty\">{{ localeText().noRows }}</div>\n }\n }\n </div>\n}\n\n<div class=\"ag-sidebar-strip\">\n <button\n class=\"ag-sidebar-strip-btn\"\n [class.active]=\"open() && activeTab() === 'columns'\"\n [attr.aria-pressed]=\"open() && activeTab() === 'columns'\"\n (click)=\"tabChange.emit('columns')\"\n >{{ localeText().columns }}</button>\n <button\n class=\"ag-sidebar-strip-btn\"\n [class.active]=\"open() && activeTab() === 'detail'\"\n [attr.aria-pressed]=\"open() && activeTab() === 'detail'\"\n (click)=\"tabChange.emit('detail')\"\n >{{ localeText().detail }}</button>\n</div>\n", styles: [":host{display:flex;flex-shrink:0;min-height:0}.ag-sidebar{width:200px;flex-shrink:0;border-left:1px solid var(--agrid-color-border);background:var(--agrid-color-bg);display:flex;flex-direction:column;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-sidebar::-webkit-scrollbar{width:8px;height:8px}.ag-sidebar::-webkit-scrollbar-track{background:transparent}.ag-sidebar::-webkit-scrollbar-thumb{background:#0000002e;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-sidebar::-webkit-scrollbar-thumb:hover{background:#00000052}.ag-sidebar-strip{width:24px;flex-shrink:0;border-left:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted);display:flex;flex-direction:column}.ag-sidebar-strip-btn{background:none;border:none;border-bottom:1px solid var(--agrid-color-border);cursor:pointer;color:var(--agrid-color-text-muted);-webkit-user-select:none;user-select:none;writing-mode:vertical-rl;transform:rotate(180deg);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;padding:10px 5px;text-align:center}.ag-sidebar-strip-btn:hover{background:var(--agrid-color-bg);color:var(--agrid-color-text)}.ag-sidebar-strip-btn.active{color:var(--agrid-color-text);background:var(--agrid-color-bg);border-left:2px solid var(--agrid-color-accent, #4f8ef7)}.ag-sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:0 8px 0 12px;height:32px;flex-shrink:0;border-bottom:1px solid var(--agrid-color-border);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--agrid-color-text-muted);background:var(--agrid-color-bg-muted)}.ag-sidebar-close{background:none;border:none;cursor:pointer;color:var(--agrid-color-text-muted);font-size:11px;padding:2px 4px;border-radius:3px;line-height:1}.ag-sidebar-close:hover,.ag-sidebar-item:hover{background:var(--agrid-color-bg-muted);color:var(--agrid-color-text)}.ag-sidebar-item{display:flex;align-items:center;gap:8px;padding:5px 12px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}.ag-sidebar-item input[type=checkbox]{cursor:pointer;margin:0;flex-shrink:0}.ag-detail-field{display:flex;flex-direction:column;gap:2px;padding:7px 12px;border-bottom:1px solid var(--agrid-color-border);font-size:13px}.ag-detail-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--agrid-color-text-muted)}.ag-detail-hidden{font-weight:400;text-transform:none;letter-spacing:0;opacity:.6}.ag-detail-value{color:var(--agrid-color-text);word-break:break-word}.ag-detail-empty{padding:16px 12px;font-size:13px;color:var(--agrid-color-text-muted);text-align:center}.ag-detail-input{width:100%;box-sizing:border-box;font-size:13px;font-family:inherit;color:var(--agrid-color-text);background:var(--agrid-color-bg);border:1px solid var(--agrid-color-border);border-radius:3px;padding:3px 6px;outline:none}.ag-detail-input:focus{border-color:var(--agrid-color-accent, #4f8ef7);box-shadow:0 0 0 2px color-mix(in srgb,var(--agrid-color-accent, #4f8ef7) 20%,transparent)}.ag-button{display:flex;align-items:center;justify-content:center;height:24px;border:1px solid var(--agrid-color-border);border-radius:3px;background:var(--agrid-color-bg-subtle);color:var(--agrid-color-text);cursor:pointer;font-size:13px;padding:0;line-height:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4265
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AgridSidebarComponent, isStandalone: true, selector: "agrid-sidebar", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, headerGroups: { classPropertyName: "headerGroups", publicName: "headerGroups", isSignal: true, isRequired: false, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: false, transformFunction: null }, hiddenColumns: { classPropertyName: "hiddenColumns", publicName: "hiddenColumns", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, localeText: { classPropertyName: "localeText", publicName: "localeText", isSignal: true, isRequired: false, transformFunction: null }, readonlyGrid: { classPropertyName: "readonlyGrid", publicName: "readonlyGrid", isSignal: true, isRequired: false, transformFunction: null }, useSidebarEditor: { classPropertyName: "useSidebarEditor", publicName: "useSidebarEditor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", tabChange: "tabChange", toggleColumn: "toggleColumn", toggleColumnGroup: "toggleColumnGroup", detailEdit: "detailEdit", save: "save" }, ngImport: i0, template: "@if (open()) {\n <div class=\"ag-sidebar\" role=\"region\"\n [attr.aria-label]=\"activeTab() === 'columns' ? localeText().columns : localeText().detail\">\n <div class=\"ag-sidebar-header\">\n <span>{{ activeTab() === 'columns' ? localeText().columns : localeText().detail }}</span>\n <button class=\"ag-sidebar-close\" (click)=\"close.emit()\" [title]=\"localeText().close\"\n [attr.aria-label]=\"localeText().close\">\u2715</button>\n </div>\n\n @if (activeTab() === 'columns') {\n @for (entry of columnEntries(); track entry.kind === 'group' ? 'group-' + entry.id : 'column-' + entry.col.field) {\n @if (entry.kind === 'group') {\n <div class=\"ag-sidebar-group\">\n <label class=\"ag-sidebar-item ag-sidebar-group-label\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"isGroupVisible(entry.columns)\"\n [indeterminate]=\"isGroupPartiallyVisible(entry.columns)\"\n (change)=\"onGroupToggle(entry.columns, $event)\"\n />\n {{ entry.label }}\n </label>\n <div class=\"ag-sidebar-group-children\">\n @for (col of entry.columns; track col.field) {\n <label class=\"ag-sidebar-item ag-sidebar-group-child\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"!hiddenColumns().has(col.field)\"\n (change)=\"toggleColumn.emit(col.field)\"\n />\n {{ col.header }}\n </label>\n }\n </div>\n </div>\n } @else {\n <label class=\"ag-sidebar-item\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"!hiddenColumns().has(entry.col.field)\"\n (change)=\"toggleColumn.emit(entry.col.field)\"\n />\n {{ entry.col.header }}\n </label>\n }\n }\n } @else {\n @if (detailFields(); as fields) {\n @for (field of fields; track field.col.field) {\n <div class=\"ag-detail-field\">\n <span class=\"ag-detail-label\">\n {{ field.label }}\n @if (field.hidden) {\n <span class=\"ag-detail-hidden\">{{ localeText().hiddenColumn }}</span>\n }\n </span>\n @if ((field.editable || useSidebarEditor()) && field.col.values?.length) {\n <select\n class=\"ag-detail-input\"\n (change)=\"detailEdit.emit({\n field: field.col.field,\n col: field.col,\n value: $any($event.target).value\n })\"\n >\n @for (opt of field.col.values; track $index) {\n @if ($any(opt).value !== undefined) {\n <option [value]=\"$any(opt).value\" [selected]=\"$any(opt).value === field.rawValue\">\n {{ $any(opt).label }}\n </option>\n } @else {\n <option [value]=\"opt\" [selected]=\"opt === field.rawValue\">{{ opt }}</option>\n }\n }\n </select>\n } @else if (field.editable || useSidebarEditor()) {\n <input\n class=\"ag-detail-input\"\n [type]=\"field.col.type === 'number' ? 'number' : field.col.type === 'date' ? 'date' : 'text'\"\n [value]=\"field.inputValue\"\n (change)=\"detailEdit.emit({\n field: field.col.field,\n col: field.col,\n value: $any($event.target).value\n })\"\n />\n } @else {\n <span class=\"ag-detail-value\">{{ field.value }}</span>\n }\n </div>\n }\n @if (useSidebarEditor()) {\n <div class=\"ag-detail-field\">\n <button class=\"ag-button\" (click)=\"save.emit(fields)\">{{ localeText().save }}</button>\n </div>\n }\n } @else {\n <div class=\"ag-detail-empty\">{{ localeText().noRows }}</div>\n }\n }\n </div>\n}\n\n<div class=\"ag-sidebar-strip\">\n <button\n class=\"ag-sidebar-strip-btn\"\n [class.active]=\"open() && activeTab() === 'columns'\"\n [attr.aria-pressed]=\"open() && activeTab() === 'columns'\"\n (click)=\"tabChange.emit('columns')\"\n >{{ localeText().columns }}</button>\n <button\n class=\"ag-sidebar-strip-btn\"\n [class.active]=\"open() && activeTab() === 'detail'\"\n [attr.aria-pressed]=\"open() && activeTab() === 'detail'\"\n (click)=\"tabChange.emit('detail')\"\n >{{ localeText().detail }}</button>\n</div>\n", styles: [":host{display:flex;flex-shrink:0;min-height:0}.ag-sidebar{width:200px;flex-shrink:0;border-left:1px solid var(--agrid-color-border);background:var(--agrid-color-bg);display:flex;flex-direction:column;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-sidebar::-webkit-scrollbar{width:8px;height:8px}.ag-sidebar::-webkit-scrollbar-track{background:transparent}.ag-sidebar::-webkit-scrollbar-thumb{background:#0000002e;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-sidebar::-webkit-scrollbar-thumb:hover{background:#00000052}.ag-sidebar-strip{width:24px;flex-shrink:0;border-left:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted);display:flex;flex-direction:column}.ag-sidebar-strip-btn{background:none;border:none;border-bottom:1px solid var(--agrid-color-border);cursor:pointer;color:var(--agrid-color-text-muted);-webkit-user-select:none;user-select:none;writing-mode:vertical-rl;transform:rotate(180deg);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;padding:10px 5px;text-align:center}.ag-sidebar-strip-btn:hover{background:var(--agrid-color-bg);color:var(--agrid-color-text)}.ag-sidebar-strip-btn.active{color:var(--agrid-color-text);background:var(--agrid-color-bg);border-left:2px solid var(--agrid-color-accent, #4f8ef7)}.ag-sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:0 8px 0 12px;height:32px;flex-shrink:0;border-bottom:1px solid var(--agrid-color-border);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--agrid-color-text-muted);background:var(--agrid-color-bg-muted)}.ag-sidebar-close{background:none;border:none;cursor:pointer;color:var(--agrid-color-text-muted);font-size:11px;padding:2px 4px;border-radius:3px;line-height:1}.ag-sidebar-close:hover,.ag-sidebar-item:hover{background:var(--agrid-color-bg-muted);color:var(--agrid-color-text)}.ag-sidebar-item{display:flex;align-items:center;gap:8px;padding:5px 12px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}.ag-sidebar-item input[type=checkbox]{cursor:pointer;margin:0;flex-shrink:0}.ag-sidebar-group-label{font-weight:600}.ag-sidebar-group-children{position:relative}.ag-sidebar-group-children:before{content:\"\";position:absolute;top:0;bottom:8px;left:19px;border-left:1px solid var(--agrid-color-border)}.ag-sidebar-group-child{position:relative;padding-left:30px}.ag-sidebar-group-child:before{content:\"\";position:absolute;left:19px;width:7px;border-top:1px solid var(--agrid-color-border)}.ag-detail-field{display:flex;flex-direction:column;gap:2px;padding:7px 12px;border-bottom:1px solid var(--agrid-color-border);font-size:13px}.ag-detail-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--agrid-color-text-muted)}.ag-detail-hidden{font-weight:400;text-transform:none;letter-spacing:0;opacity:.6}.ag-detail-value{color:var(--agrid-color-text);word-break:break-word}.ag-detail-empty{padding:16px 12px;font-size:13px;color:var(--agrid-color-text-muted);text-align:center}.ag-detail-input{width:100%;box-sizing:border-box;font-size:13px;font-family:inherit;color:var(--agrid-color-text);background:var(--agrid-color-bg);border:1px solid var(--agrid-color-border);border-radius:3px;padding:3px 6px;outline:none}.ag-detail-input:focus{border-color:var(--agrid-color-accent, #4f8ef7);box-shadow:0 0 0 2px color-mix(in srgb,var(--agrid-color-accent, #4f8ef7) 20%,transparent)}.ag-button{display:flex;align-items:center;justify-content:center;height:24px;border:1px solid var(--agrid-color-border);border-radius:3px;background:var(--agrid-color-bg-subtle);color:var(--agrid-color-text);cursor:pointer;font-size:13px;padding:0;line-height:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3992
4266
|
}
|
|
3993
4267
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AgridSidebarComponent, decorators: [{
|
|
3994
4268
|
type: Component,
|
|
3995
|
-
args: [{ selector: 'agrid-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (open()) {\n <div class=\"ag-sidebar\" role=\"region\"\n [attr.aria-label]=\"activeTab() === 'columns' ? localeText().columns : localeText().detail\">\n <div class=\"ag-sidebar-header\">\n <span>{{ activeTab() === 'columns' ? localeText().columns : localeText().detail }}</span>\n <button class=\"ag-sidebar-close\" (click)=\"close.emit()\" [title]=\"localeText().close\"\n [attr.aria-label]=\"localeText().close\">\u2715</button>\n </div>\n\n @if (activeTab() === 'columns') {\n @for (
|
|
3996
|
-
}], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: false }] }], hiddenColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenColumns", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], localeText: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeText", required: false }] }], readonlyGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonlyGrid", required: false }] }], useSidebarEditor: [{ type: i0.Input, args: [{ isSignal: true, alias: "useSidebarEditor", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }], toggleColumn: [{ type: i0.Output, args: ["toggleColumn"] }], detailEdit: [{ type: i0.Output, args: ["detailEdit"] }], save: [{ type: i0.Output, args: ["save"] }] } });
|
|
4269
|
+
args: [{ selector: 'agrid-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (open()) {\n <div class=\"ag-sidebar\" role=\"region\"\n [attr.aria-label]=\"activeTab() === 'columns' ? localeText().columns : localeText().detail\">\n <div class=\"ag-sidebar-header\">\n <span>{{ activeTab() === 'columns' ? localeText().columns : localeText().detail }}</span>\n <button class=\"ag-sidebar-close\" (click)=\"close.emit()\" [title]=\"localeText().close\"\n [attr.aria-label]=\"localeText().close\">\u2715</button>\n </div>\n\n @if (activeTab() === 'columns') {\n @for (entry of columnEntries(); track entry.kind === 'group' ? 'group-' + entry.id : 'column-' + entry.col.field) {\n @if (entry.kind === 'group') {\n <div class=\"ag-sidebar-group\">\n <label class=\"ag-sidebar-item ag-sidebar-group-label\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"isGroupVisible(entry.columns)\"\n [indeterminate]=\"isGroupPartiallyVisible(entry.columns)\"\n (change)=\"onGroupToggle(entry.columns, $event)\"\n />\n {{ entry.label }}\n </label>\n <div class=\"ag-sidebar-group-children\">\n @for (col of entry.columns; track col.field) {\n <label class=\"ag-sidebar-item ag-sidebar-group-child\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"!hiddenColumns().has(col.field)\"\n (change)=\"toggleColumn.emit(col.field)\"\n />\n {{ col.header }}\n </label>\n }\n </div>\n </div>\n } @else {\n <label class=\"ag-sidebar-item\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"!hiddenColumns().has(entry.col.field)\"\n (change)=\"toggleColumn.emit(entry.col.field)\"\n />\n {{ entry.col.header }}\n </label>\n }\n }\n } @else {\n @if (detailFields(); as fields) {\n @for (field of fields; track field.col.field) {\n <div class=\"ag-detail-field\">\n <span class=\"ag-detail-label\">\n {{ field.label }}\n @if (field.hidden) {\n <span class=\"ag-detail-hidden\">{{ localeText().hiddenColumn }}</span>\n }\n </span>\n @if ((field.editable || useSidebarEditor()) && field.col.values?.length) {\n <select\n class=\"ag-detail-input\"\n (change)=\"detailEdit.emit({\n field: field.col.field,\n col: field.col,\n value: $any($event.target).value\n })\"\n >\n @for (opt of field.col.values; track $index) {\n @if ($any(opt).value !== undefined) {\n <option [value]=\"$any(opt).value\" [selected]=\"$any(opt).value === field.rawValue\">\n {{ $any(opt).label }}\n </option>\n } @else {\n <option [value]=\"opt\" [selected]=\"opt === field.rawValue\">{{ opt }}</option>\n }\n }\n </select>\n } @else if (field.editable || useSidebarEditor()) {\n <input\n class=\"ag-detail-input\"\n [type]=\"field.col.type === 'number' ? 'number' : field.col.type === 'date' ? 'date' : 'text'\"\n [value]=\"field.inputValue\"\n (change)=\"detailEdit.emit({\n field: field.col.field,\n col: field.col,\n value: $any($event.target).value\n })\"\n />\n } @else {\n <span class=\"ag-detail-value\">{{ field.value }}</span>\n }\n </div>\n }\n @if (useSidebarEditor()) {\n <div class=\"ag-detail-field\">\n <button class=\"ag-button\" (click)=\"save.emit(fields)\">{{ localeText().save }}</button>\n </div>\n }\n } @else {\n <div class=\"ag-detail-empty\">{{ localeText().noRows }}</div>\n }\n }\n </div>\n}\n\n<div class=\"ag-sidebar-strip\">\n <button\n class=\"ag-sidebar-strip-btn\"\n [class.active]=\"open() && activeTab() === 'columns'\"\n [attr.aria-pressed]=\"open() && activeTab() === 'columns'\"\n (click)=\"tabChange.emit('columns')\"\n >{{ localeText().columns }}</button>\n <button\n class=\"ag-sidebar-strip-btn\"\n [class.active]=\"open() && activeTab() === 'detail'\"\n [attr.aria-pressed]=\"open() && activeTab() === 'detail'\"\n (click)=\"tabChange.emit('detail')\"\n >{{ localeText().detail }}</button>\n</div>\n", styles: [":host{display:flex;flex-shrink:0;min-height:0}.ag-sidebar{width:200px;flex-shrink:0;border-left:1px solid var(--agrid-color-border);background:var(--agrid-color-bg);display:flex;flex-direction:column;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-sidebar::-webkit-scrollbar{width:8px;height:8px}.ag-sidebar::-webkit-scrollbar-track{background:transparent}.ag-sidebar::-webkit-scrollbar-thumb{background:#0000002e;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-sidebar::-webkit-scrollbar-thumb:hover{background:#00000052}.ag-sidebar-strip{width:24px;flex-shrink:0;border-left:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted);display:flex;flex-direction:column}.ag-sidebar-strip-btn{background:none;border:none;border-bottom:1px solid var(--agrid-color-border);cursor:pointer;color:var(--agrid-color-text-muted);-webkit-user-select:none;user-select:none;writing-mode:vertical-rl;transform:rotate(180deg);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;padding:10px 5px;text-align:center}.ag-sidebar-strip-btn:hover{background:var(--agrid-color-bg);color:var(--agrid-color-text)}.ag-sidebar-strip-btn.active{color:var(--agrid-color-text);background:var(--agrid-color-bg);border-left:2px solid var(--agrid-color-accent, #4f8ef7)}.ag-sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:0 8px 0 12px;height:32px;flex-shrink:0;border-bottom:1px solid var(--agrid-color-border);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--agrid-color-text-muted);background:var(--agrid-color-bg-muted)}.ag-sidebar-close{background:none;border:none;cursor:pointer;color:var(--agrid-color-text-muted);font-size:11px;padding:2px 4px;border-radius:3px;line-height:1}.ag-sidebar-close:hover,.ag-sidebar-item:hover{background:var(--agrid-color-bg-muted);color:var(--agrid-color-text)}.ag-sidebar-item{display:flex;align-items:center;gap:8px;padding:5px 12px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}.ag-sidebar-item input[type=checkbox]{cursor:pointer;margin:0;flex-shrink:0}.ag-sidebar-group-label{font-weight:600}.ag-sidebar-group-children{position:relative}.ag-sidebar-group-children:before{content:\"\";position:absolute;top:0;bottom:8px;left:19px;border-left:1px solid var(--agrid-color-border)}.ag-sidebar-group-child{position:relative;padding-left:30px}.ag-sidebar-group-child:before{content:\"\";position:absolute;left:19px;width:7px;border-top:1px solid var(--agrid-color-border)}.ag-detail-field{display:flex;flex-direction:column;gap:2px;padding:7px 12px;border-bottom:1px solid var(--agrid-color-border);font-size:13px}.ag-detail-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--agrid-color-text-muted)}.ag-detail-hidden{font-weight:400;text-transform:none;letter-spacing:0;opacity:.6}.ag-detail-value{color:var(--agrid-color-text);word-break:break-word}.ag-detail-empty{padding:16px 12px;font-size:13px;color:var(--agrid-color-text-muted);text-align:center}.ag-detail-input{width:100%;box-sizing:border-box;font-size:13px;font-family:inherit;color:var(--agrid-color-text);background:var(--agrid-color-bg);border:1px solid var(--agrid-color-border);border-radius:3px;padding:3px 6px;outline:none}.ag-detail-input:focus{border-color:var(--agrid-color-accent, #4f8ef7);box-shadow:0 0 0 2px color-mix(in srgb,var(--agrid-color-accent, #4f8ef7) 20%,transparent)}.ag-button{display:flex;align-items:center;justify-content:center;height:24px;border:1px solid var(--agrid-color-border);border-radius:3px;background:var(--agrid-color-bg-subtle);color:var(--agrid-color-text);cursor:pointer;font-size:13px;padding:0;line-height:1}\n"] }]
|
|
4270
|
+
}], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], headerGroups: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerGroups", required: false }] }], row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: false }] }], hiddenColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenColumns", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], localeText: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeText", required: false }] }], readonlyGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonlyGrid", required: false }] }], useSidebarEditor: [{ type: i0.Input, args: [{ isSignal: true, alias: "useSidebarEditor", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }], toggleColumn: [{ type: i0.Output, args: ["toggleColumn"] }], toggleColumnGroup: [{ type: i0.Output, args: ["toggleColumnGroup"] }], detailEdit: [{ type: i0.Output, args: ["detailEdit"] }], save: [{ type: i0.Output, args: ["save"] }] } });
|
|
3997
4271
|
|
|
3998
4272
|
/**
|
|
3999
4273
|
* Excel-like data grid for Angular 21.
|
|
@@ -4036,6 +4310,7 @@ class AgridComponent {
|
|
|
4036
4310
|
groupActions = computed(() => this.provider().groupActions, ...(ngDevMode ? [{ debugName: "groupActions" }] : /* istanbul ignore next */ []));
|
|
4037
4311
|
cellMenuItems = computed(() => this.provider().cellMenuItems, ...(ngDevMode ? [{ debugName: "cellMenuItems" }] : /* istanbul ignore next */ []));
|
|
4038
4312
|
headerGroups = computed(() => this.provider().headerGroups, ...(ngDevMode ? [{ debugName: "headerGroups" }] : /* istanbul ignore next */ []));
|
|
4313
|
+
treeConfig = computed(() => this.provider().treeConfig, ...(ngDevMode ? [{ debugName: "treeConfig" }] : /* istanbul ignore next */ []));
|
|
4039
4314
|
zebraStripes = computed(() => this.provider().zebraStripes, ...(ngDevMode ? [{ debugName: "zebraStripes" }] : /* istanbul ignore next */ []));
|
|
4040
4315
|
showChangedCellIndicator = computed(() => this.provider().showChangedCellIndicator, ...(ngDevMode ? [{ debugName: "showChangedCellIndicator" }] : /* istanbul ignore next */ []));
|
|
4041
4316
|
confirmRowDelete = computed(() => this.provider().confirmRowDelete, ...(ngDevMode ? [{ debugName: "confirmRowDelete" }] : /* istanbul ignore next */ []));
|
|
@@ -4203,6 +4478,7 @@ class AgridComponent {
|
|
|
4203
4478
|
control: this.control,
|
|
4204
4479
|
groupDescription: this.groupDescription,
|
|
4205
4480
|
});
|
|
4481
|
+
treeController = new AgridTreeController();
|
|
4206
4482
|
// ── Derived state ─────────────────────────────────────────────────────────────
|
|
4207
4483
|
allowRowReorder = computed(() => (this.control()?.allowRowReorder() ?? false) && !this.control()?.groupByField(), ...(ngDevMode ? [{ debugName: "allowRowReorder" }] : /* istanbul ignore next */ []));
|
|
4208
4484
|
/** `true` when there is a committed edit that can be undone (Ctrl+Z). */
|
|
@@ -4254,6 +4530,8 @@ class AgridComponent {
|
|
|
4254
4530
|
allowAddRows: this.allowAddRows,
|
|
4255
4531
|
autoAddRows: this.autoAddRows,
|
|
4256
4532
|
expandedGroups: this.groupController.expandedGroups,
|
|
4533
|
+
treeConfig: this.treeConfig,
|
|
4534
|
+
expandedTreeIds: this.treeController.expandedIds,
|
|
4257
4535
|
});
|
|
4258
4536
|
editController = new AgridEditController({
|
|
4259
4537
|
control: this.control,
|
|
@@ -4744,6 +5022,47 @@ class AgridComponent {
|
|
|
4744
5022
|
getItemOriginalIndex(item) {
|
|
4745
5023
|
return isDataRowItem(item) ? item.originalIndex : null;
|
|
4746
5024
|
}
|
|
5025
|
+
// ── Template helpers — tree ───────────────────────────────────────────────────
|
|
5026
|
+
/** @internal True when `col` is the configured tree column. */
|
|
5027
|
+
isTreeCell(col) {
|
|
5028
|
+
return this.treeConfig()?.treeField === col.field;
|
|
5029
|
+
}
|
|
5030
|
+
/** @internal Tree depth of a row item (0 when not a tree row). */
|
|
5031
|
+
treeRowLevel(item) {
|
|
5032
|
+
return isTreeRowItem(item) ? item.level : 0;
|
|
5033
|
+
}
|
|
5034
|
+
/** @internal Whether a tree row has children and can be expanded. */
|
|
5035
|
+
treeRowExpandable(item) {
|
|
5036
|
+
return isTreeRowItem(item) && item.expandable;
|
|
5037
|
+
}
|
|
5038
|
+
/** @internal Whether a tree row is currently expanded. */
|
|
5039
|
+
treeRowExpanded(item) {
|
|
5040
|
+
return isTreeRowItem(item) && item.expanded;
|
|
5041
|
+
}
|
|
5042
|
+
/** @internal Toggle the expand/collapse state of a tree row from its twisty. */
|
|
5043
|
+
onTreeToggle(item) {
|
|
5044
|
+
const config = this.treeConfig();
|
|
5045
|
+
if (!config || !isTreeRowItem(item))
|
|
5046
|
+
return;
|
|
5047
|
+
this.treeController.toggle(config.getId(item.row));
|
|
5048
|
+
}
|
|
5049
|
+
/** Expand every expandable node in the tree. No-op when not in tree mode. */
|
|
5050
|
+
expandAllNodes() {
|
|
5051
|
+
const config = this.treeConfig();
|
|
5052
|
+
if (!config)
|
|
5053
|
+
return;
|
|
5054
|
+
const expandable = new Set();
|
|
5055
|
+
for (const row of this.dataSource().rows()) {
|
|
5056
|
+
const parentId = config.getParentId(row);
|
|
5057
|
+
if (parentId != null)
|
|
5058
|
+
expandable.add(parentId);
|
|
5059
|
+
}
|
|
5060
|
+
this.treeController.expandAll(expandable);
|
|
5061
|
+
}
|
|
5062
|
+
/** Collapse every node in the tree. No-op when not in tree mode. */
|
|
5063
|
+
collapseAllNodes() {
|
|
5064
|
+
this.treeController.collapseAll();
|
|
5065
|
+
}
|
|
4747
5066
|
/** @internal CDK trackBy — arrow to preserve `this`. */
|
|
4748
5067
|
trackByItem = (_di, item) => {
|
|
4749
5068
|
if (item === 'ghost')
|
|
@@ -5125,6 +5444,10 @@ class AgridComponent {
|
|
|
5125
5444
|
onSidebarToggleColumn(field) {
|
|
5126
5445
|
this.columnMenuController.toggleColumnVisibility(field);
|
|
5127
5446
|
}
|
|
5447
|
+
/** @internal Sets every column in a sidebar header group to the requested visibility. */
|
|
5448
|
+
onSidebarToggleColumnGroup(fields, visible) {
|
|
5449
|
+
this.columnMenuController.setColumnsVisibility(fields, visible);
|
|
5450
|
+
}
|
|
5128
5451
|
/** @internal Mirrors vertical scrolling from the main viewport into both pinned panes. */
|
|
5129
5452
|
onBodyScroll() {
|
|
5130
5453
|
const offset = this.viewport().measureScrollOffset();
|
|
@@ -5236,7 +5559,7 @@ class AgridComponent {
|
|
|
5236
5559
|
return this.columnSizing.getWidthToken(col);
|
|
5237
5560
|
}
|
|
5238
5561
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AgridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5239
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AgridComponent, isStandalone: true, selector: "agrid", inputs: { provider: { classPropertyName: "provider", publicName: "provider", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellEdit: "cellEdit", recordEdit: "recordEdit", rowRemoved: "rowRemoved", prepareAddRecord: "prepareAddRecord", rowReorder: "rowReorder", rowSelect: "rowSelect", rowDoubleClicked: "rowDoubleClicked", rowClick: "rowClick", rowChanged: "rowChanged", pageChange: "pageChange", filterChange: "filterChange", sortChange: "sortChange" }, host: { properties: { "class.ag-zebra": "zebraStripes()", "style.min-height": "minHeight()", "style.max-height": "maxHeight()" } }, viewQueries: [{ propertyName: "viewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }, { propertyName: "pinnedViewport", first: true, predicate: ["pinnedViewport"], descendants: true, isSignal: true }, { propertyName: "rightPinnedViewport", first: true, predicate: ["rightPinnedViewport"], descendants: true, isSignal: true }, { propertyName: "wrapperEl", first: true, predicate: ["wrapper"], descendants: true, isSignal: true }, { propertyName: "horizontalScrollerEl", first: true, predicate: ["horizontalScroller"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #wrapper class=\"ag-wrapper\" tabindex=\"0\" role=\"grid\" [attr.aria-label]=\"localeText().grid\"\n [attr.aria-rowcount]=\"ariaRowCount()\" [attr.aria-colcount]=\"ariaColCount()\"\n [attr.aria-multiselectable]=\"rowSelection() === 'multi' ? 'true' : null\"\n [attr.aria-readonly]=\"readonlyGrid() ? 'true' : null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\" (copy)=\"onCopy($event)\" (paste)=\"onPaste($event)\"\n (focusin)=\"onGridFocusIn($event)\"\n (click)=\"closeContextMenu(); closeCellContextMenu(); closeFilterMenu(); closeGroupActionsMenu()\">\n <div class=\"ag-main-area\">\n <div class=\"ag-grid-split\" [class.ag-has-right-pane]=\"hasRightPinnedPane()\">\n @if (hasPinnedPane()) {\n <div class=\"ag-pinned-pane\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups ag-header-groups--pinned\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (showControlColumn()) {\n <div class=\"ag-header-group-cell ag-header-group-cell--empty\"></div>\n }\n @for (run of pinnedHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header ag-header--pinned\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (showControlColumn()) {\n <div class=\"ag-header-cell ag-control-header\" role=\"columnheader\" aria-colindex=\"1\">\n <div class=\"ag-header-cell-top\"></div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\"></div>\n }\n </div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-header-cell ag-header-cell--pinned\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-header-cell--pinned-last]=\"isLastPinnedColumn(col.field)\" [attr.data-col-field]=\"col.field\"\n (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #pinnedViewport class=\"ag-body ag-pinned-body\" [itemSize]=\"rowHeight()\"\n [style.width.px]=\"pinnedPaneWidth()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-add-row--selected]=\"item === null && isAddRowSelected()\" [class.ag-ghost-row]=\"item === 'ghost'\"\n [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isPinnedPaneRowSelected(item)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [attr.data-original-index]=\"getItemOriginalIndex(item)\" [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? pinnedGridTemplateColumns() : null\"\n (pointerdown)=\"isDataRowItem(item) && onRowPointerDown($event, item.originalIndex)\"\n (click)=\"isDataRowItem(item) && onRowClick($event, item)\">\n @if (isDataRowItem(item)) {\n @if (showControlColumn()) {\n <div class=\"ag-control-cell\" role=\"rowheader\" aria-colindex=\"1\"\n [class.ag-control-cell--reorder]=\"allowRowReorder()\"\n (contextmenu)=\"onControlContextMenu($event, item.originalIndex)\" (click)=\"$event.stopPropagation()\"\n (pointerdown)=\"onControlPointerDown($event, item.originalIndex)\">\n @if (enableRowMarking()) {\n <input class=\"ag-row-marker\" type=\"checkbox\" [checked]=\"isRowMarked(item.originalIndex)\"\n [attr.aria-label]=\"localeText().markRow\"\n (pointerdown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRowMarked(item.originalIndex)\" />\n }\n </div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\" [class.ag-cell--pinned]=\"true\"\n [class.ag-cell--pinned-last]=\"isLastPinnedColumn(col.field)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\" (startEdit)=\"onStartEdit(item.originalIndex, ci)\"\n (draftChange)=\"onDraftChange($event)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-pinned-row-spacer\"></div>\n } @else if (item === 'ghost') {\n @if (showControlColumn()) {\n <div class=\"ag-control-cell ag-control-cell--reorder ag-ghost-handle\"></div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-ghost-cell ag-cell--pinned\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--pinned-last]=\"isLastPinnedColumn(col.field)\">{{\n getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-pinned-group-spacer\"></div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\">\n @if (showControlColumn()) {\n <div class=\"ag-footer-cell ag-footer-cell--control\" role=\"gridcell\" aria-colindex=\"1\"></div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [class.ag-footer-cell--pinned-last]=\"isLastPinnedColumn(col.field)\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"ag-scroll-pane\">\n <div #horizontalScroller class=\"ag-horizontal-scroll\" (scroll)=\"onHorizontalScroll()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (run of scrollableHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-header-cell\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.data-col-field]=\"col.field\" (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n @if (isGroupedByField(col.field)) {\n <span class=\"ag-sort-badge\">\u229F</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #scrollViewport class=\"ag-body\" [itemSize]=\"rowHeight()\"\n [style.min-width.px]=\"scrollableTotalWidth()\" (scroll)=\"onBodyScroll()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-add-row--selected]=\"item === null && isAddRowSelected()\" [class.ag-ghost-row]=\"item === 'ghost'\"\n [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [attr.data-original-index]=\"getItemOriginalIndex(item)\" [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? scrollableGridTemplateColumns() : null\"\n (pointerdown)=\"isDataRowItem(item) && onRowPointerDown($event, item.originalIndex)\"\n (click)=\"isDataRowItem(item) && onRowClick($event, item)\">\n @if (isDataRowItem(item)) {\n @for (col of scrollableColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\"\n (startEdit)=\"onStartEdit(item.originalIndex, ci)\" (draftChange)=\"onDraftChange($event)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-add-row-label\" (click)=\"onActivateAddRow()\">\n <span class=\"ag-add-row-icon\">+</span> {{ localeText().addRow }}\n </div>\n } @else if (item === 'ghost') {\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-ghost-cell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\">{{\n getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-group-header-content\" [style.min-width.px]=\"scrollableTotalWidth()\">\n <div class=\"ag-group-header-main\"\n (click)=\"onGroupHeaderClick(item.groupLabel); $event.stopPropagation()\">\n <span class=\"ag-group-icon\" [class.ag-group-icon--expanded]=\"!item.collapsed\">\u25B6</span>\n <span class=\"ag-group-label\">{{ item.groupLabel }}</span>\n @if (groupActions().length > 0) {\n <button class=\"ag-group-actions-btn\" [title]=\"localeText().actions\"\n (click)=\"openGroupActionsMenu($event, item.groupLabel)\">\u22EE</button>\n }\n <span class=\"ag-group-count\">{{ item.count }}</span>\n @if (getGroupDescription(item.groupLabel); as desc) {\n <span class=\"ag-group-description\">{{ desc }}</span>\n }\n </div>\n </div>\n }\n @if (isDataRowItem(item) && isRowPendingDelete(item.originalIndex)) {\n <div class=\"ag-delete-confirmation\" role=\"alertdialog\"\n [attr.aria-label]=\"localeText().confirmDeleteRow\"\n [style.left.px]=\"deleteConfirmationLeft()\"\n [style.width.px]=\"deleteConfirmationWidth() || null\"\n (pointerdown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\n <span class=\"ag-delete-confirmation-text\">{{ localeText().confirmDeleteRow }}</span>\n <button class=\"ag-delete-confirmation-btn ag-delete-confirmation-btn--yes\"\n type=\"button\" (click)=\"confirmPendingRowDelete()\">{{ localeText().confirmYes }}</button>\n <button class=\"ag-delete-confirmation-btn\" type=\"button\" data-delete-confirm-no\n (click)=\"cancelRowDelete()\">{{ localeText().confirmNo }}</button>\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (hasRightPinnedPane()) {\n <div class=\"ag-pinned-pane ag-pinned-pane--right\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @for (run of rightHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-header-cell ag-header-cell--pinned\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-header-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\" [attr.data-col-field]=\"col.field\"\n (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n @if (isGroupedByField(col.field)) {\n <span class=\"ag-sort-badge\">'\u229F '</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #rightPinnedViewport class=\"ag-body ag-pinned-body ag-right-pinned-body\"\n [itemSize]=\"rowHeight()\" [style.width.px]=\"rightPinnedPaneWidth()\" (scroll)=\"onRightPinnedBodyScroll()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-ghost-row]=\"item === 'ghost'\" [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? rightGridTemplateColumns() : null\">\n @if (isDataRowItem(item)) {\n @for (col of rightPinnedColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--pinned]=\"true\" [class.ag-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\" (startEdit)=\"onStartEdit(item.originalIndex, ci)\"\n (draftChange)=\"onDraftChange($event)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-pinned-row-spacer\"></div>\n } @else if (item === 'ghost') {\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-ghost-cell ag-cell--pinned\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\">{{ getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-pinned-group-spacer\"></div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\">\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [class.ag-footer-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n @if (loading()) {\n <div class=\"ag-state-overlay\" role=\"status\" aria-live=\"polite\">{{ localeText().loading }}</div>\n } @else if (isEmpty()) {\n <div class=\"ag-state-overlay\" role=\"status\" aria-live=\"polite\">{{ emptyTextLabel() }}</div>\n }\n\n @if (showSidebar()) {\n <agrid-sidebar\n [open]=\"sidebarOpen()\"\n [activeTab]=\"sidebarTab()\"\n [columns]=\"colDefs()\"\n [row]=\"sidebarRow()\"\n [hiddenColumns]=\"sidebarHiddenColumns()\"\n [locale]=\"locale()\"\n [localeText]=\"localeText()\"\n [readonlyGrid]=\"readonlyGrid()\"\n [useSidebarEditor]=\"useSidebarEditor()\"\n (close)=\"toggleSidebar()\"\n (tabChange)=\"onSidebarStripClick($event)\"\n (toggleColumn)=\"onSidebarToggleColumn($event)\"\n (detailEdit)=\"onSidebarDetailEdit($event)\"\n (save)=\"onSidebarDetailSave($event)\"\n />\n }\n </div><!-- /.ag-main-area -->\n\n @if (showPagination()) {\n <nav class=\"ag-pagination\" [attr.aria-label]=\"localeText().pagination\">\n <button class=\"ag-page-btn\" [attr.aria-label]=\"localeText().firstPage\"\n [disabled]=\"control()!.currentPage() <= 1\" (click)=\"goToFirstPage()\">\u00AB</button>\n <button class=\"ag-page-btn\" [attr.aria-label]=\"localeText().previous\"\n [disabled]=\"control()!.currentPage() <= 1\" (click)=\"goToPrevPage()\">\u2039</button>\n <span class=\"ag-page-info\" aria-live=\"polite\">{{ control()!.currentPage() }} / {{ totalPages() }}</span>\n <button class=\"ag-page-btn\" [disabled]=\"control()!.currentPage() >= totalPages()\"\n [attr.aria-label]=\"localeText().next\"\n (click)=\"goToNextPage()\">\u203A</button>\n <button class=\"ag-page-btn\" [disabled]=\"control()!.currentPage() >= totalPages()\"\n [attr.aria-label]=\"localeText().lastPage\"\n (click)=\"goToLastPage()\">\u00BB</button>\n <span class=\"ag-page-count\">{{ localeText().rows(filteredRowCount()) }}</span>\n </nav>\n }\n\n @if (findOpen()) {\n <agrid-find-panel [query]=\"findQuery()\" [matchCount]=\"findMatches().length\" [activeIndex]=\"findActiveIndex()\"\n [localeText]=\"localeText()\" (queryChange)=\"onFindInput($event)\" (previous)=\"goToFindMatch(-1)\"\n (next)=\"goToFindMatch(1)\" (close)=\"closeFind()\" />\n }\n\n <!-- Row context menu -->\n @if (contextMenu(); as menu) {\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"ag-context-item ag-context-item--danger\" role=\"menuitem\" (click)=\"deleteRow(menu.rowIndex)\">\n {{ localeText().deleteRow }}\n </button>\n </div>\n }\n\n <!-- Cell context menu -->\n @if (cellContextMenuState(); as menu) {\n @let col = getColDef(menu.field)!;\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"copyCellToClipboard(menu.rowIndex, col)\">{{ localeText().copyCellValue\n }}</button>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"copyRowToClipboard(menu.rowIndex)\">{{ localeText().copyRow }}</button>\n @if (allowAddRows() && !readonlyGrid()) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"insertRowAt(menu.rowIndex)\">{{ localeText().insertRowAbove }}</button>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"insertRowAt(menu.rowIndex + 1)\">{{ localeText().insertRowBelow }}</button>\n }\n @if (!readonlyGrid()) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n <button class=\"ag-context-item ag-context-item--danger\" role=\"menuitem\"\n (click)=\"deleteRow(menu.rowIndex)\">{{ localeText().deleteRow }}</button>\n }\n @if (cellMenuItems().length) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n @for (item of cellMenuItems(); track $index) {\n @if (item === null) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n } @else {\n <button class=\"ag-context-item\" role=\"menuitem\" [class.ag-context-item--danger]=\"item.danger\" [disabled]=\"item.disabled\"\n (click)=\"runCellMenuItem(item, menu)\">{{\n item.label }}</button>\n }\n }\n }\n </div>\n }\n\n <!-- Group actions menu -->\n @if (groupActionsMenu(); as menu) {\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n @for (action of groupActions(); track action.label) {\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"onGroupAction(action, menu.label)\">\n {{ action.label }}\n </button>\n }\n </div>\n }\n\n <!-- Filter dropdown -->\n @if (filterMenu(); as menu) {\n <agrid-column-menu [x]=\"menu.x\" [y]=\"menu.y\" [header]=\"getColDef(menu.field)?.header ?? menu.field\"\n [sortDir]=\"getSort(menu.field)\" [sortable]=\"sortOption() !== 'none'\"\n [showColumnActions]=\"!!control()\" [pinned]=\"getColumnPinState(menu.field)\"\n [groupable]=\"!!getColDef(menu.field)?.groupable\" [grouped]=\"isGroupedByField(menu.field)\"\n [filterable]=\"!!getColDef(menu.field)?.filterable\" [showValueFilter]=\"!serverSideFiltering()\"\n [search]=\"filterMenuSearch()\"\n [allSelected]=\"isMenuAllSelected(menu.field)\"\n [valueItems]=\"serverSideFiltering() || !getColDef(menu.field)?.filterable ? [] : columnMenuValueItems()\"\n [localeText]=\"localeText()\"\n [sortPriority]=\"getSortPriority(menu.field)\" [hasMultiSort]=\"hasMultiSort()\" (sort)=\"onMenuSort(menu.field, $event)\"\n (resetSort)=\"onMenuResetSort(menu.field, $event)\" (autosize)=\"onMenuAutosizeColumn(menu.field)\"\n (togglePin)=\"onMenuTogglePin(menu.field)\" (togglePinRight)=\"onMenuTogglePinRight(menu.field)\"\n (hide)=\"onMenuHideColumn(menu.field)\" (toggleGroup)=\"onMenuToggleGroupBy(menu.field)\"\n (clearFilter)=\"onMenuClearFilter(menu.field)\" (clearAll)=\"onMenuClearAll()\"\n (searchChange)=\"onFilterMenuSearch($event)\" (toggleAll)=\"onMenuToggleAll(menu.field)\"\n (toggleValue)=\"onMenuToggleValue(menu.field, $event)\" [aggregate]=\"getEffectiveAggregate(getColDef(menu.field)!)\"\n (setAggregate)=\"onMenuSetAggregate(menu.field, $event)\" />\n }\n\n @if (columnDragPreview(); as preview) {\n <div class=\"ag-column-drag-preview\"\n [style.left.px]=\"preview.x\" [style.top.px]=\"preview.y\"\n [style.width.px]=\"preview.width\" [style.height.px]=\"preview.height\">\n <span>{{ preview.label }}</span>\n </div>\n }\n</div>\n", styles: ["@layer agrid-defaults{:host{--agrid-color-text: #24292f;--agrid-color-text-muted: #57606a;--agrid-color-accent: #1a73e8;--agrid-color-accent-subtle: #e8f0fe;--agrid-color-accent-fg: #1558b0;--agrid-color-accent-border: #c8d8f8;--agrid-color-danger: #d1242f;--agrid-color-danger-subtle: #fff1f0;--agrid-color-border: #d0d7de;--agrid-color-bg: #ffffff;--agrid-color-bg-subtle: #fafbfc;--agrid-color-bg-muted: #f6f8fa;--agrid-color-shadow: rgba(140, 149, 159, .2);--agrid-color-bg-stripe: #f0f2f5;--agrid-color-cell-changed: #f59e0b;--agrid-color-row-marked: #fff8c5}}:host{display:flex;flex-direction:column;min-height:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--agrid-color-text)}.ag-wrapper{position:relative;display:flex;flex-direction:column;flex:1;min-height:0;border:1px solid var(--agrid-color-border);overflow:hidden;outline:none;border-radius:4px}.ag-state-overlay{position:absolute;inset:34px 0 0;display:flex;align-items:center;justify-content:center;color:var(--agrid-color-text-muted);background:color-mix(in srgb,var(--agrid-color-bg) 78%,transparent);pointer-events:none;z-index:3}.ag-header{display:grid;flex-shrink:0;background:var(--agrid-color-bg-muted);border-bottom:2px solid var(--agrid-color-border)}.ag-header-groups{display:grid;flex-shrink:0;height:28px;background:color-mix(in srgb,var(--agrid-color-bg-muted) 72%,var(--agrid-color-bg));border-bottom:1px solid var(--agrid-color-border)}.ag-header-group-cell{display:flex;align-items:center;justify-content:center;min-width:0;padding:0 8px;overflow:hidden;border-right:1px solid var(--agrid-color-border);box-sizing:border-box;color:var(--agrid-color-text);font-size:12px;font-weight:600;text-overflow:ellipsis;white-space:nowrap;cursor:grab;-webkit-user-select:none;user-select:none;transition:opacity .1s ease}.ag-header-group-cell:last-child{border-right:none}.ag-header-group-cell--empty,.ag-header-group-cell--locked{cursor:default}.ag-header-group-cell--dragging{opacity:.12}.ag-header-cell{position:relative;display:flex;align-items:center;font-weight:600;border-right:1px solid var(--agrid-color-border);overflow:hidden;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box}.ag-header-cell:last-child{border-right:none}.ag-header-cell-top{display:flex;align-items:center;flex:1;min-width:0;padding:0 6px;height:32px;overflow:hidden;white-space:nowrap}.ag-header-cell-label{overflow:hidden;text-overflow:ellipsis;flex:1}.ag-header--with-filters .ag-header-cell{flex-direction:column;align-items:stretch;height:auto;white-space:normal}.ag-header--with-filters .ag-header-cell-top{flex:0 0 32px}.ag-header-cell-filter{height:28px;display:flex;align-items:center;padding:0 2px;border-top:1px solid var(--agrid-color-border);background:var(--agrid-color-bg)}.ag-header-cell{cursor:grab;transition:transform .16s cubic-bezier(.2,0,0,1),opacity .1s ease;will-change:transform}.ag-row>agrid-cell,.ag-ghost-cell,.ag-footer-cell{transition:transform .16s cubic-bezier(.2,0,0,1),opacity .1s ease;will-change:transform}.ag-header-cell--dragging{opacity:.12;cursor:grabbing}.ag-column-reorder-item--dragging{opacity:.12}.ag-header-cell--drop-before,.ag-header-cell--drop-after{z-index:1}.ag-column-drag-preview{position:fixed;z-index:1000;display:flex;align-items:flex-start;padding:8px 10px;border:1px solid var(--agrid-color-accent);border-radius:5px;color:var(--agrid-color-text);background:color-mix(in srgb,var(--agrid-color-bg) 94%,var(--agrid-color-accent));box-shadow:0 10px 28px var(--agrid-color-shadow);font-weight:600;line-height:16px;box-sizing:border-box;pointer-events:none;opacity:.96}.ag-sort-badge{font-size:11px;color:var(--agrid-color-accent);flex-shrink:0;line-height:1}.ag-sort-priority{font-size:9px;vertical-align:super;opacity:.75}.ag-resize-handle{position:absolute;top:0;right:0;width:5px;height:100%;cursor:col-resize;z-index:1}.ag-resize-handle:hover{background:var(--agrid-color-accent);opacity:.5}.ag-filter-input{flex:1;min-width:0;height:20px;border:1px solid var(--agrid-color-border);border-radius:3px;outline:none;font:inherit;font-size:12px;padding:0 4px;background:var(--agrid-color-bg)}.ag-filter-input:focus{border-color:var(--agrid-color-accent)}.ag-header-cell--filtered .ag-header-cell-label:after{content:\" \\25be\";font-size:9px;color:var(--agrid-color-accent)}.ag-main-area{display:flex;flex:1;min-height:0;overflow:hidden}.ag-grid-split{display:flex;flex:1;min-width:0;min-height:0;overflow:hidden}.ag-pinned-pane{flex-shrink:0;min-height:0;display:flex;flex-direction:column;overflow:hidden;border-right:1px solid var(--agrid-color-border);background:var(--agrid-color-bg)}.ag-scroll-pane{flex:1;min-width:0;min-height:0;display:flex}.ag-horizontal-scroll{flex:1;min-width:0;min-height:0;overflow-x:auto;overflow-y:hidden;display:flex;flex-direction:column}.ag-body{flex:1;overflow-x:clip;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-horizontal-scroll{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-body::-webkit-scrollbar,.ag-horizontal-scroll::-webkit-scrollbar{width:8px;height:8px}.ag-body::-webkit-scrollbar-track,.ag-horizontal-scroll::-webkit-scrollbar-track{background:transparent}.ag-body::-webkit-scrollbar-thumb,.ag-horizontal-scroll::-webkit-scrollbar-thumb{background:#0000002e;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-body::-webkit-scrollbar-thumb:hover,.ag-horizontal-scroll::-webkit-scrollbar-thumb:hover{background:#00000052;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-pinned-body{overflow:hidden}.ag-right-pinned-body{overflow-y:auto}.ag-has-right-pane .ag-body:not(.ag-pinned-body){scrollbar-width:none}.ag-has-right-pane .ag-body:not(.ag-pinned-body)::-webkit-scrollbar{display:none}.ag-row{display:grid;position:relative}.ag-row--pending-delete>:not(.ag-delete-confirmation){opacity:.2;pointer-events:none;transition:opacity .14s ease}.ag-delete-confirmation{position:absolute;top:0;bottom:0;z-index:7;display:flex;align-items:center;justify-content:center;gap:8px;min-width:min(100%,320px);padding:2px 12px;box-sizing:border-box;color:var(--agrid-color-text);background:color-mix(in srgb,var(--agrid-color-danger-subtle) 88%,transparent);border-block:1px solid color-mix(in srgb,var(--agrid-color-danger) 35%,transparent)}.ag-delete-confirmation-text{font-weight:600;white-space:nowrap}.ag-delete-confirmation-btn{min-width:42px;padding:3px 9px;border:1px solid var(--agrid-color-border);border-radius:4px;color:var(--agrid-color-text);background:var(--agrid-color-bg);font:inherit;cursor:pointer}.ag-delete-confirmation-btn:hover,.ag-delete-confirmation-btn:focus-visible{border-color:var(--agrid-color-accent);outline:none}.ag-delete-confirmation-btn--yes{color:#fff;border-color:var(--agrid-color-danger);background:var(--agrid-color-danger)}.ag-delete-confirmation-btn--yes:hover,.ag-delete-confirmation-btn--yes:focus-visible{border-color:color-mix(in srgb,var(--agrid-color-danger) 75%,#000);background:color-mix(in srgb,var(--agrid-color-danger) 85%,#000)}:host(.ag-zebra) .ag-row--odd agrid-cell:not(.editing){background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd .ag-cell--pinned{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd .ag-control-cell{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd:hover agrid-cell:not(.editing){background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd:hover .ag-cell--pinned,:host(.ag-zebra) .ag-row--odd:hover .ag-control-cell{background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd.ag-row--selected agrid-cell:not(.editing){background:var(--agrid-color-accent-subtle)}:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-cell--pinned,:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-control-cell{background:var(--agrid-color-accent-subtle)}:host(.ag-zebra) .ag-row--odd .ag-cell--pinned-first{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd:hover .ag-cell--pinned-first{background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-cell--pinned-first{background:var(--agrid-color-accent-subtle)}.ag-row:hover agrid-cell:not(.editing){background:var(--agrid-color-bg-muted)}.ag-row--selected agrid-cell:not(.editing){background:var(--agrid-color-accent-subtle)}.ag-row--marked agrid-cell:not(.editing),.ag-row--marked .ag-control-cell{background:var(--agrid-color-row-marked)}.ag-row--marked{box-shadow:inset 3px 0 #bf8700}.ag-row--selected.ag-row--marked{box-shadow:inset 3px 0 0 var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--range-selected:not(.editing){background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1px var(--agrid-color-accent-border)}.ag-row agrid-cell.ag-cell--find-match:not(.editing){background:#fff7cc}.ag-row agrid-cell.ag-cell--find-active:not(.editing){background:#ffe58a;box-shadow:inset 0 0 0 2px #b7791f}.ag-row agrid-cell.ag-cell--range-selected.selected:not(.editing){box-shadow:inset 0 0 0 2px var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--fill-preview:not(.editing){background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1px var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--fill-handle:not(.editing){position:relative}.ag-row agrid-cell.ag-cell--fill-handle:not(.editing):after{content:\"\";position:absolute;right:1px;bottom:1px;width:6px;height:6px;background:var(--agrid-color-accent);border:1px solid var(--agrid-color-bg);box-sizing:border-box;cursor:crosshair;z-index:4}.ag-row--selected .ag-control-cell{background:var(--agrid-color-accent-subtle)}.ag-row--selected{box-shadow:inset 3px 0 0 var(--agrid-color-accent)}.ag-control-header{z-index:3;border-right:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted)}.ag-control-header .ag-header-cell-filter{background:var(--agrid-color-bg-subtle)}.ag-control-cell{z-index:2;border-right:1px solid var(--agrid-color-border);border-bottom:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-subtle);cursor:context-menu;display:flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;flex-direction:row-reverse}.ag-control-cell:after{content:\"\\22ee\";font-size:11px;color:var(--agrid-color-border);line-height:1}.ag-control-cell:hover:after{color:var(--agrid-color-text-muted)}.ag-control-cell--reorder{cursor:grab}.ag-control-cell--reorder:after{content:\"\\283f\";font-size:13px;color:var(--agrid-color-text)}.ag-control-cell--reorder:hover:after{color:var(--agrid-color-text-muted)}.ag-control-cell--reorder:active{cursor:grabbing}.ag-row-marker{position:relative;z-index:1;width:14px;height:14px;margin:0;accent-color:var(--agrid-color-accent);cursor:pointer}.ag-ghost-row{background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1.5px var(--agrid-color-accent);pointer-events:none;animation:ag-ghost-in .1s ease}@keyframes ag-ghost-in{0%{opacity:0}to{opacity:1}}.ag-ghost-handle:after{color:var(--agrid-color-accent)!important}.ag-ghost-cell{display:flex;align-items:center;padding:0 6px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;border-right:1px solid var(--agrid-color-accent-border);color:var(--agrid-color-accent-fg);font-size:13px;box-sizing:border-box;-webkit-user-select:none;user-select:none}.ag-ghost-cell:last-child{border-right:none}.ag-pinned-row-spacer,.ag-pinned-group-spacer{height:100%;border-bottom:1px solid var(--agrid-color-border);box-sizing:border-box}.ag-pinned-group-spacer{background:var(--agrid-color-bg-muted)}.ag-context-menu{position:fixed;z-index:1000;background:var(--agrid-color-bg-subtle);border:1px solid var(--agrid-color-border);border-radius:6px;box-shadow:0 8px 24px var(--agrid-color-shadow);min-width:160px;padding:4px 0;font-size:13px}.ag-context-item{display:block;width:100%;padding:6px 16px;text-align:left;background:none;border:none;cursor:pointer;color:var(--agrid-color-text);font:inherit}.ag-context-item:hover{background:var(--agrid-color-bg-muted)}.ag-context-separator{height:1px;background:var(--agrid-color-border);margin:3px 0}.ag-context-item--danger{color:var(--agrid-color-danger)}.ag-context-item--danger:hover{background:var(--agrid-color-danger-subtle)}.ag-group-header-row{display:flex;align-items:stretch;background:var(--agrid-color-bg-muted);border-bottom:1px solid var(--agrid-color-border);overflow:hidden}.ag-group-header-content{display:flex;align-items:stretch;height:100%;width:100%;-webkit-user-select:none;user-select:none}.ag-group-header-main{display:flex;align-items:center;gap:6px;padding:0 10px;flex:1;min-width:0;cursor:pointer}.ag-group-header-main:hover{background:var(--agrid-color-bg-subtle)}.ag-group-description{font-size:11px;color:var(--agrid-color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ag-group-actions-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:none;border-radius:3px;cursor:pointer;color:var(--agrid-color-text-muted);font-size:14px;padding:0}.ag-group-actions-btn:hover{background:var(--agrid-color-bg-muted);color:var(--agrid-color-text)}.ag-group-icon{font-size:9px;color:var(--agrid-color-text-muted);line-height:1;display:inline-block;transition:transform .15s ease}.ag-group-icon--expanded{transform:rotate(90deg)}.ag-group-label{font-weight:600;font-size:12px;color:var(--agrid-color-text)}.ag-group-count{font-size:11px;color:var(--agrid-color-text-muted);background:var(--agrid-color-bg);border:1px solid var(--agrid-color-border);border-radius:10px;padding:0 7px;line-height:16px}.ag-footer{display:grid;flex-shrink:0;background:var(--agrid-color-bg-muted);border-top:2px solid var(--agrid-color-border)}.ag-footer-cell{display:flex;align-items:center;gap:4px;padding:0 6px;height:30px;border-right:1px solid var(--agrid-color-border);box-sizing:border-box;overflow:hidden;white-space:nowrap;font-weight:600;font-size:12px;color:var(--agrid-color-text)}.ag-footer-cell:last-child{border-right:none}.ag-footer-cell--control{background:var(--agrid-color-bg-subtle);border-right:1px solid var(--agrid-color-border)}.ag-footer-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-footer-label{font-size:10px;font-weight:400;color:var(--agrid-color-text-muted);flex-shrink:0}.ag-pagination{display:flex;align-items:center;gap:4px;padding:0 10px;height:34px;flex-shrink:0;border-top:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted);font-size:12px;color:var(--agrid-color-text-muted)}.ag-page-btn{display:flex;align-items:center;justify-content:center;width:24px;height:22px;border:1px solid var(--agrid-color-border);border-radius:3px;background:var(--agrid-color-bg);color:var(--agrid-color-text);font-size:13px;cursor:pointer;padding:0;line-height:1}.ag-page-btn:hover:not(:disabled){background:var(--agrid-color-bg-muted);border-color:var(--agrid-color-text-muted)}.ag-page-btn:disabled{opacity:.35;cursor:default}.ag-page-info{padding:0 6px;font-weight:500;color:var(--agrid-color-text);min-width:48px;text-align:center}.ag-page-count{margin-left:auto;color:var(--agrid-color-text-muted)}.ag-add-row{border-bottom:1px dashed var(--agrid-color-border);color:var(--agrid-color-text-muted);cursor:pointer}.ag-add-row:hover .ag-add-row-label{background:var(--agrid-color-bg-muted)}.ag-add-row--selected .ag-add-row-label{outline:2px solid var(--agrid-color-accent);outline-offset:-2px}.ag-add-row-label{display:flex;align-items:center;gap:4px;height:100%;padding:0 6px;font-size:12px;-webkit-user-select:none;user-select:none}.ag-add-row-icon{font-size:16px;line-height:1;color:var(--agrid-color-text-muted)}.ag-pinned-pane--right{border-left:1px solid var(--agrid-color-border);border-right:none;box-shadow:-3px 0 6px -2px var(--agrid-color-shadow)}.ag-header-cell--pinned{background:var(--agrid-color-bg-muted)}.ag-header-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-header-cell--pinned-first{box-shadow:none}.ag-cell--pinned{background:var(--agrid-color-bg)}.ag-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-cell--pinned-first{box-shadow:none}.ag-row:hover .ag-cell--pinned{background:var(--agrid-color-bg-muted)}.ag-row--selected .ag-cell--pinned,.ag-row .ag-cell--pinned.ag-cell--range-selected,.ag-row .ag-cell--pinned.ag-cell--fill-preview{background:var(--agrid-color-accent-subtle)}.ag-row .ag-cell--pinned.ag-cell--find-match{background:#fff7cc}.ag-row .ag-cell--pinned.ag-cell--find-active{background:#ffe58a}.ag-header-menu-btn{flex-shrink:0;width:16px;height:16px;padding:0;margin-right:2px;background:none;border:1px solid transparent;border-radius:3px;cursor:pointer;font-size:10px;color:var(--agrid-color-text-muted);display:flex;align-items:center;justify-content:center;opacity:1;transition:opacity .12s;line-height:1}.ag-header-menu-btn--active{color:var(--agrid-color-accent);border-color:var(--agrid-color-accent-border);background:var(--agrid-color-accent-subtle)}.ag-header-menu-btn:hover{background:var(--agrid-color-bg);border-color:var(--agrid-color-border)}\n"], dependencies: [{ kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: AgridCellComponent, selector: "agrid-cell", inputs: ["col", "rowIndex", "colIndex", "value", "row", "locale", "selected", "editing", "seedChar"], outputs: ["activate", "startEdit", "draftChange"] }, { kind: "component", type: AgridColumnMenuComponent, selector: "agrid-column-menu", inputs: ["localeText", "x", "y", "header", "sortDir", "sortable", "showColumnActions", "pinned", "groupable", "grouped", "filterable", "showValueFilter", "search", "allSelected", "valueItems", "sortPriority", "hasMultiSort", "aggregate"], outputs: ["sort", "resetSort", "autosize", "togglePin", "togglePinRight", "hide", "toggleGroup", "clearFilter", "clearAll", "searchChange", "toggleAll", "toggleValue", "setAggregate"] }, { kind: "component", type: AgridFindPanelComponent, selector: "agrid-find-panel", inputs: ["localeText", "query", "matchCount", "activeIndex"], outputs: ["queryChange", "next", "previous", "close"] }, { kind: "component", type: AgridSidebarComponent, selector: "agrid-sidebar", inputs: ["open", "activeTab", "columns", "row", "hiddenColumns", "locale", "localeText", "readonlyGrid", "useSidebarEditor"], outputs: ["close", "tabChange", "toggleColumn", "detailEdit", "save"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5562
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AgridComponent, isStandalone: true, selector: "agrid", inputs: { provider: { classPropertyName: "provider", publicName: "provider", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellEdit: "cellEdit", recordEdit: "recordEdit", rowRemoved: "rowRemoved", prepareAddRecord: "prepareAddRecord", rowReorder: "rowReorder", rowSelect: "rowSelect", rowDoubleClicked: "rowDoubleClicked", rowClick: "rowClick", rowChanged: "rowChanged", pageChange: "pageChange", filterChange: "filterChange", sortChange: "sortChange" }, host: { properties: { "class.ag-zebra": "zebraStripes()", "style.min-height": "minHeight()", "style.max-height": "maxHeight()" } }, viewQueries: [{ propertyName: "viewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }, { propertyName: "pinnedViewport", first: true, predicate: ["pinnedViewport"], descendants: true, isSignal: true }, { propertyName: "rightPinnedViewport", first: true, predicate: ["rightPinnedViewport"], descendants: true, isSignal: true }, { propertyName: "wrapperEl", first: true, predicate: ["wrapper"], descendants: true, isSignal: true }, { propertyName: "horizontalScrollerEl", first: true, predicate: ["horizontalScroller"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #wrapper class=\"ag-wrapper\" tabindex=\"0\" role=\"grid\" [attr.aria-label]=\"localeText().grid\"\n [attr.aria-rowcount]=\"ariaRowCount()\" [attr.aria-colcount]=\"ariaColCount()\"\n [attr.aria-multiselectable]=\"rowSelection() === 'multi' ? 'true' : null\"\n [attr.aria-readonly]=\"readonlyGrid() ? 'true' : null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\" (copy)=\"onCopy($event)\" (paste)=\"onPaste($event)\"\n (focusin)=\"onGridFocusIn($event)\"\n (click)=\"closeContextMenu(); closeCellContextMenu(); closeFilterMenu(); closeGroupActionsMenu()\">\n <div class=\"ag-main-area\">\n <div class=\"ag-grid-split\" [class.ag-has-right-pane]=\"hasRightPinnedPane()\">\n @if (hasPinnedPane()) {\n <div class=\"ag-pinned-pane\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups ag-header-groups--pinned\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (showControlColumn()) {\n <div class=\"ag-header-group-cell ag-header-group-cell--empty\"></div>\n }\n @for (run of pinnedHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header ag-header--pinned\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (showControlColumn()) {\n <div class=\"ag-header-cell ag-control-header\" role=\"columnheader\" aria-colindex=\"1\">\n <div class=\"ag-header-cell-top\"></div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\"></div>\n }\n </div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-header-cell ag-header-cell--pinned\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-header-cell--pinned-last]=\"isLastPinnedColumn(col.field)\" [attr.data-col-field]=\"col.field\"\n (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #pinnedViewport class=\"ag-body ag-pinned-body\" [itemSize]=\"rowHeight()\"\n [style.width.px]=\"pinnedPaneWidth()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-add-row--selected]=\"item === null && isAddRowSelected()\" [class.ag-ghost-row]=\"item === 'ghost'\"\n [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isPinnedPaneRowSelected(item)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [attr.data-original-index]=\"getItemOriginalIndex(item)\" [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? pinnedGridTemplateColumns() : null\"\n (pointerdown)=\"isDataRowItem(item) && onRowPointerDown($event, item.originalIndex)\"\n (click)=\"isDataRowItem(item) && onRowClick($event, item)\">\n @if (isDataRowItem(item)) {\n @if (showControlColumn()) {\n <div class=\"ag-control-cell\" role=\"rowheader\" aria-colindex=\"1\"\n [class.ag-control-cell--reorder]=\"allowRowReorder()\"\n (contextmenu)=\"onControlContextMenu($event, item.originalIndex)\" (click)=\"$event.stopPropagation()\"\n (pointerdown)=\"onControlPointerDown($event, item.originalIndex)\">\n @if (enableRowMarking()) {\n <input class=\"ag-row-marker\" type=\"checkbox\" [checked]=\"isRowMarked(item.originalIndex)\"\n [attr.aria-label]=\"localeText().markRow\"\n (pointerdown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRowMarked(item.originalIndex)\" />\n }\n </div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [treeCell]=\"isTreeCell(col)\" [treeLevel]=\"treeRowLevel(item)\"\n [treeExpandable]=\"treeRowExpandable(item)\" [treeExpanded]=\"treeRowExpanded(item)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\" [class.ag-cell--pinned]=\"true\"\n [class.ag-cell--pinned-last]=\"isLastPinnedColumn(col.field)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\" (startEdit)=\"onStartEdit(item.originalIndex, ci)\"\n (draftChange)=\"onDraftChange($event)\" (treeToggle)=\"onTreeToggle(item)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-pinned-row-spacer\"></div>\n } @else if (item === 'ghost') {\n @if (showControlColumn()) {\n <div class=\"ag-control-cell ag-control-cell--reorder ag-ghost-handle\"></div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-ghost-cell ag-cell--pinned\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--pinned-last]=\"isLastPinnedColumn(col.field)\">{{\n getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-pinned-group-spacer\"></div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\">\n @if (showControlColumn()) {\n <div class=\"ag-footer-cell ag-footer-cell--control\" role=\"gridcell\" aria-colindex=\"1\"></div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [class.ag-footer-cell--pinned-last]=\"isLastPinnedColumn(col.field)\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"ag-scroll-pane\">\n <div #horizontalScroller class=\"ag-horizontal-scroll\" (scroll)=\"onHorizontalScroll()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (run of scrollableHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-header-cell\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.data-col-field]=\"col.field\" (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n @if (isGroupedByField(col.field)) {\n <span class=\"ag-sort-badge\">\u229F</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #scrollViewport class=\"ag-body\" [itemSize]=\"rowHeight()\"\n [style.min-width.px]=\"scrollableTotalWidth()\" (scroll)=\"onBodyScroll()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-add-row--selected]=\"item === null && isAddRowSelected()\" [class.ag-ghost-row]=\"item === 'ghost'\"\n [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [attr.data-original-index]=\"getItemOriginalIndex(item)\" [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? scrollableGridTemplateColumns() : null\"\n (pointerdown)=\"isDataRowItem(item) && onRowPointerDown($event, item.originalIndex)\"\n (click)=\"isDataRowItem(item) && onRowClick($event, item)\">\n @if (isDataRowItem(item)) {\n @for (col of scrollableColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [treeCell]=\"isTreeCell(col)\" [treeLevel]=\"treeRowLevel(item)\"\n [treeExpandable]=\"treeRowExpandable(item)\" [treeExpanded]=\"treeRowExpanded(item)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\"\n (startEdit)=\"onStartEdit(item.originalIndex, ci)\" (draftChange)=\"onDraftChange($event)\"\n (treeToggle)=\"onTreeToggle(item)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-add-row-label\" (click)=\"onActivateAddRow()\">\n <span class=\"ag-add-row-icon\">+</span> {{ localeText().addRow }}\n </div>\n } @else if (item === 'ghost') {\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-ghost-cell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\">{{\n getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-group-header-content\" [style.min-width.px]=\"scrollableTotalWidth()\">\n <div class=\"ag-group-header-main\"\n (click)=\"onGroupHeaderClick(item.groupLabel); $event.stopPropagation()\">\n <span class=\"ag-group-icon\" [class.ag-group-icon--expanded]=\"!item.collapsed\">\u25B6</span>\n <span class=\"ag-group-label\">{{ item.groupLabel }}</span>\n @if (groupActions().length > 0) {\n <button class=\"ag-group-actions-btn\" [title]=\"localeText().actions\"\n (click)=\"openGroupActionsMenu($event, item.groupLabel)\">\u22EE</button>\n }\n <span class=\"ag-group-count\">{{ item.count }}</span>\n @if (getGroupDescription(item.groupLabel); as desc) {\n <span class=\"ag-group-description\">{{ desc }}</span>\n }\n </div>\n </div>\n }\n @if (isDataRowItem(item) && isRowPendingDelete(item.originalIndex)) {\n <div class=\"ag-delete-confirmation\" role=\"alertdialog\"\n [attr.aria-label]=\"localeText().confirmDeleteRow\"\n [style.left.px]=\"deleteConfirmationLeft()\"\n [style.width.px]=\"deleteConfirmationWidth() || null\"\n (pointerdown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\n <span class=\"ag-delete-confirmation-text\">{{ localeText().confirmDeleteRow }}</span>\n <button class=\"ag-delete-confirmation-btn ag-delete-confirmation-btn--yes\"\n type=\"button\" (click)=\"confirmPendingRowDelete()\">{{ localeText().confirmYes }}</button>\n <button class=\"ag-delete-confirmation-btn\" type=\"button\" data-delete-confirm-no\n (click)=\"cancelRowDelete()\">{{ localeText().confirmNo }}</button>\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (hasRightPinnedPane()) {\n <div class=\"ag-pinned-pane ag-pinned-pane--right\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @for (run of rightHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-header-cell ag-header-cell--pinned\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-header-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\" [attr.data-col-field]=\"col.field\"\n (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n @if (isGroupedByField(col.field)) {\n <span class=\"ag-sort-badge\">'\u229F '</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #rightPinnedViewport class=\"ag-body ag-pinned-body ag-right-pinned-body\"\n [itemSize]=\"rowHeight()\" [style.width.px]=\"rightPinnedPaneWidth()\" (scroll)=\"onRightPinnedBodyScroll()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-ghost-row]=\"item === 'ghost'\" [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? rightGridTemplateColumns() : null\">\n @if (isDataRowItem(item)) {\n @for (col of rightPinnedColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [treeCell]=\"isTreeCell(col)\" [treeLevel]=\"treeRowLevel(item)\"\n [treeExpandable]=\"treeRowExpandable(item)\" [treeExpanded]=\"treeRowExpanded(item)\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--pinned]=\"true\" [class.ag-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\" (startEdit)=\"onStartEdit(item.originalIndex, ci)\"\n (draftChange)=\"onDraftChange($event)\" (treeToggle)=\"onTreeToggle(item)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-pinned-row-spacer\"></div>\n } @else if (item === 'ghost') {\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-ghost-cell ag-cell--pinned\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\">{{ getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-pinned-group-spacer\"></div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\">\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [class.ag-footer-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n @if (loading()) {\n <div class=\"ag-state-overlay\" role=\"status\" aria-live=\"polite\">{{ localeText().loading }}</div>\n } @else if (isEmpty()) {\n <div class=\"ag-state-overlay\" role=\"status\" aria-live=\"polite\">{{ emptyTextLabel() }}</div>\n }\n\n @if (showSidebar()) {\n <agrid-sidebar\n [open]=\"sidebarOpen()\"\n [activeTab]=\"sidebarTab()\"\n [columns]=\"colDefs()\"\n [headerGroups]=\"headerGroups()\"\n [row]=\"sidebarRow()\"\n [hiddenColumns]=\"sidebarHiddenColumns()\"\n [locale]=\"locale()\"\n [localeText]=\"localeText()\"\n [readonlyGrid]=\"readonlyGrid()\"\n [useSidebarEditor]=\"useSidebarEditor()\"\n (close)=\"toggleSidebar()\"\n (tabChange)=\"onSidebarStripClick($event)\"\n (toggleColumn)=\"onSidebarToggleColumn($event)\"\n (toggleColumnGroup)=\"onSidebarToggleColumnGroup($event.fields, $event.visible)\"\n (detailEdit)=\"onSidebarDetailEdit($event)\"\n (save)=\"onSidebarDetailSave($event)\"\n />\n }\n </div><!-- /.ag-main-area -->\n\n @if (showPagination()) {\n <nav class=\"ag-pagination\" [attr.aria-label]=\"localeText().pagination\">\n <button class=\"ag-page-btn\" [attr.aria-label]=\"localeText().firstPage\"\n [disabled]=\"control()!.currentPage() <= 1\" (click)=\"goToFirstPage()\">\u00AB</button>\n <button class=\"ag-page-btn\" [attr.aria-label]=\"localeText().previous\"\n [disabled]=\"control()!.currentPage() <= 1\" (click)=\"goToPrevPage()\">\u2039</button>\n <span class=\"ag-page-info\" aria-live=\"polite\">{{ control()!.currentPage() }} / {{ totalPages() }}</span>\n <button class=\"ag-page-btn\" [disabled]=\"control()!.currentPage() >= totalPages()\"\n [attr.aria-label]=\"localeText().next\"\n (click)=\"goToNextPage()\">\u203A</button>\n <button class=\"ag-page-btn\" [disabled]=\"control()!.currentPage() >= totalPages()\"\n [attr.aria-label]=\"localeText().lastPage\"\n (click)=\"goToLastPage()\">\u00BB</button>\n <span class=\"ag-page-count\">{{ localeText().rows(filteredRowCount()) }}</span>\n </nav>\n }\n\n @if (findOpen()) {\n <agrid-find-panel [query]=\"findQuery()\" [matchCount]=\"findMatches().length\" [activeIndex]=\"findActiveIndex()\"\n [localeText]=\"localeText()\" (queryChange)=\"onFindInput($event)\" (previous)=\"goToFindMatch(-1)\"\n (next)=\"goToFindMatch(1)\" (close)=\"closeFind()\" />\n }\n\n <!-- Row context menu -->\n @if (contextMenu(); as menu) {\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"ag-context-item ag-context-item--danger\" role=\"menuitem\" (click)=\"deleteRow(menu.rowIndex)\">\n {{ localeText().deleteRow }}\n </button>\n </div>\n }\n\n <!-- Cell context menu -->\n @if (cellContextMenuState(); as menu) {\n @let col = getColDef(menu.field)!;\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"copyCellToClipboard(menu.rowIndex, col)\">{{ localeText().copyCellValue\n }}</button>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"copyRowToClipboard(menu.rowIndex)\">{{ localeText().copyRow }}</button>\n @if (allowAddRows() && !readonlyGrid()) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"insertRowAt(menu.rowIndex)\">{{ localeText().insertRowAbove }}</button>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"insertRowAt(menu.rowIndex + 1)\">{{ localeText().insertRowBelow }}</button>\n }\n @if (!readonlyGrid()) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n <button class=\"ag-context-item ag-context-item--danger\" role=\"menuitem\"\n (click)=\"deleteRow(menu.rowIndex)\">{{ localeText().deleteRow }}</button>\n }\n @if (cellMenuItems().length) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n @for (item of cellMenuItems(); track $index) {\n @if (item === null) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n } @else {\n <button class=\"ag-context-item\" role=\"menuitem\" [class.ag-context-item--danger]=\"item.danger\" [disabled]=\"item.disabled\"\n (click)=\"runCellMenuItem(item, menu)\">{{\n item.label }}</button>\n }\n }\n }\n </div>\n }\n\n <!-- Group actions menu -->\n @if (groupActionsMenu(); as menu) {\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n @for (action of groupActions(); track action.label) {\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"onGroupAction(action, menu.label)\">\n {{ action.label }}\n </button>\n }\n </div>\n }\n\n <!-- Filter dropdown -->\n @if (filterMenu(); as menu) {\n <agrid-column-menu [x]=\"menu.x\" [y]=\"menu.y\" [header]=\"getColDef(menu.field)?.header ?? menu.field\"\n [sortDir]=\"getSort(menu.field)\" [sortable]=\"sortOption() !== 'none'\"\n [showColumnActions]=\"!!control()\" [pinned]=\"getColumnPinState(menu.field)\"\n [groupable]=\"!!getColDef(menu.field)?.groupable\" [grouped]=\"isGroupedByField(menu.field)\"\n [filterable]=\"!!getColDef(menu.field)?.filterable\" [showValueFilter]=\"!serverSideFiltering()\"\n [search]=\"filterMenuSearch()\"\n [allSelected]=\"isMenuAllSelected(menu.field)\"\n [valueItems]=\"serverSideFiltering() || !getColDef(menu.field)?.filterable ? [] : columnMenuValueItems()\"\n [localeText]=\"localeText()\"\n [sortPriority]=\"getSortPriority(menu.field)\" [hasMultiSort]=\"hasMultiSort()\" (sort)=\"onMenuSort(menu.field, $event)\"\n (resetSort)=\"onMenuResetSort(menu.field, $event)\" (autosize)=\"onMenuAutosizeColumn(menu.field)\"\n (togglePin)=\"onMenuTogglePin(menu.field)\" (togglePinRight)=\"onMenuTogglePinRight(menu.field)\"\n (hide)=\"onMenuHideColumn(menu.field)\" (toggleGroup)=\"onMenuToggleGroupBy(menu.field)\"\n (clearFilter)=\"onMenuClearFilter(menu.field)\" (clearAll)=\"onMenuClearAll()\"\n (searchChange)=\"onFilterMenuSearch($event)\" (toggleAll)=\"onMenuToggleAll(menu.field)\"\n (toggleValue)=\"onMenuToggleValue(menu.field, $event)\" [aggregate]=\"getEffectiveAggregate(getColDef(menu.field)!)\"\n (setAggregate)=\"onMenuSetAggregate(menu.field, $event)\" />\n }\n\n @if (columnDragPreview(); as preview) {\n <div class=\"ag-column-drag-preview\"\n [style.left.px]=\"preview.x\" [style.top.px]=\"preview.y\"\n [style.width.px]=\"preview.width\" [style.height.px]=\"preview.height\">\n <span>{{ preview.label }}</span>\n </div>\n }\n</div>\n", styles: ["@layer agrid-defaults{:host{--agrid-color-text: #24292f;--agrid-color-text-muted: #57606a;--agrid-color-accent: #1a73e8;--agrid-color-accent-subtle: #e8f0fe;--agrid-color-accent-fg: #1558b0;--agrid-color-accent-border: #c8d8f8;--agrid-color-danger: #d1242f;--agrid-color-danger-subtle: #fff1f0;--agrid-color-border: #d0d7de;--agrid-color-bg: #ffffff;--agrid-color-bg-subtle: #fafbfc;--agrid-color-bg-muted: #f6f8fa;--agrid-color-shadow: rgba(140, 149, 159, .2);--agrid-color-bg-stripe: #f0f2f5;--agrid-color-cell-changed: #f59e0b;--agrid-color-row-marked: #fff8c5}}:host{display:flex;flex-direction:column;min-height:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--agrid-color-text)}.ag-wrapper{position:relative;display:flex;flex-direction:column;flex:1;min-height:0;border:1px solid var(--agrid-color-border);overflow:hidden;outline:none;border-radius:4px}.ag-state-overlay{position:absolute;inset:34px 0 0;display:flex;align-items:center;justify-content:center;color:var(--agrid-color-text-muted);background:color-mix(in srgb,var(--agrid-color-bg) 78%,transparent);pointer-events:none;z-index:3}.ag-header{display:grid;flex-shrink:0;background:var(--agrid-color-bg-muted);border-bottom:2px solid var(--agrid-color-border)}.ag-header-groups{display:grid;flex-shrink:0;height:28px;background:color-mix(in srgb,var(--agrid-color-bg-muted) 72%,var(--agrid-color-bg));border-bottom:1px solid var(--agrid-color-border)}.ag-header-group-cell{display:flex;align-items:center;justify-content:center;min-width:0;padding:0 8px;overflow:hidden;border-right:1px solid var(--agrid-color-border);box-sizing:border-box;color:var(--agrid-color-text);font-size:12px;font-weight:600;text-overflow:ellipsis;white-space:nowrap;cursor:grab;-webkit-user-select:none;user-select:none;transition:opacity .1s ease}.ag-header-group-cell:last-child{border-right:none}.ag-header-group-cell--empty,.ag-header-group-cell--locked{cursor:default}.ag-header-group-cell--dragging{opacity:.12}.ag-header-cell{position:relative;display:flex;align-items:center;font-weight:600;border-right:1px solid var(--agrid-color-border);overflow:hidden;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box}.ag-header-cell:last-child{border-right:none}.ag-header-cell-top{display:flex;align-items:center;flex:1;min-width:0;padding:0 6px;height:32px;overflow:hidden;white-space:nowrap}.ag-header-cell-label{overflow:hidden;text-overflow:ellipsis;flex:1}.ag-header--with-filters .ag-header-cell{flex-direction:column;align-items:stretch;height:auto;white-space:normal}.ag-header--with-filters .ag-header-cell-top{flex:0 0 32px}.ag-header-cell-filter{height:28px;display:flex;align-items:center;padding:0 2px;border-top:1px solid var(--agrid-color-border);background:var(--agrid-color-bg)}.ag-header-cell{cursor:grab;transition:transform .16s cubic-bezier(.2,0,0,1),opacity .1s ease;will-change:transform}.ag-row>agrid-cell,.ag-ghost-cell,.ag-footer-cell{transition:transform .16s cubic-bezier(.2,0,0,1),opacity .1s ease;will-change:transform}.ag-header-cell--dragging{opacity:.12;cursor:grabbing}.ag-column-reorder-item--dragging{opacity:.12}.ag-header-cell--drop-before,.ag-header-cell--drop-after{z-index:1}.ag-column-drag-preview{position:fixed;z-index:1000;display:flex;align-items:flex-start;padding:8px 10px;border:1px solid var(--agrid-color-accent);border-radius:5px;color:var(--agrid-color-text);background:color-mix(in srgb,var(--agrid-color-bg) 94%,var(--agrid-color-accent));box-shadow:0 10px 28px var(--agrid-color-shadow);font-weight:600;line-height:16px;box-sizing:border-box;pointer-events:none;opacity:.96}.ag-sort-badge{font-size:11px;color:var(--agrid-color-accent);flex-shrink:0;line-height:1}.ag-sort-priority{font-size:9px;vertical-align:super;opacity:.75}.ag-resize-handle{position:absolute;top:0;right:0;width:5px;height:100%;cursor:col-resize;z-index:1}.ag-resize-handle:hover{background:var(--agrid-color-accent);opacity:.5}.ag-filter-input{flex:1;min-width:0;height:20px;border:1px solid var(--agrid-color-border);border-radius:3px;outline:none;font:inherit;font-size:12px;padding:0 4px;background:var(--agrid-color-bg)}.ag-filter-input:focus{border-color:var(--agrid-color-accent)}.ag-header-cell--filtered .ag-header-cell-label:after{content:\" \\25be\";font-size:9px;color:var(--agrid-color-accent)}.ag-main-area{display:flex;flex:1;min-height:0;overflow:hidden}.ag-grid-split{display:flex;flex:1;min-width:0;min-height:0;overflow:hidden}.ag-pinned-pane{flex-shrink:0;min-height:0;display:flex;flex-direction:column;overflow:hidden;border-right:1px solid var(--agrid-color-border);background:var(--agrid-color-bg)}.ag-scroll-pane{flex:1;min-width:0;min-height:0;display:flex}.ag-horizontal-scroll{flex:1;min-width:0;min-height:0;overflow-x:auto;overflow-y:hidden;display:flex;flex-direction:column}.ag-body{flex:1;overflow-x:clip;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-horizontal-scroll{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-body::-webkit-scrollbar,.ag-horizontal-scroll::-webkit-scrollbar{width:8px;height:8px}.ag-body::-webkit-scrollbar-track,.ag-horizontal-scroll::-webkit-scrollbar-track{background:transparent}.ag-body::-webkit-scrollbar-thumb,.ag-horizontal-scroll::-webkit-scrollbar-thumb{background:#0000002e;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-body::-webkit-scrollbar-thumb:hover,.ag-horizontal-scroll::-webkit-scrollbar-thumb:hover{background:#00000052;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-pinned-body{overflow:hidden}.ag-right-pinned-body{overflow-y:auto}.ag-has-right-pane .ag-body:not(.ag-pinned-body){scrollbar-width:none}.ag-has-right-pane .ag-body:not(.ag-pinned-body)::-webkit-scrollbar{display:none}.ag-row{display:grid;position:relative}.ag-row--pending-delete>:not(.ag-delete-confirmation){opacity:.2;pointer-events:none;transition:opacity .14s ease}.ag-delete-confirmation{position:absolute;top:0;bottom:0;z-index:7;display:flex;align-items:center;justify-content:center;gap:8px;min-width:min(100%,320px);padding:2px 12px;box-sizing:border-box;color:var(--agrid-color-text);background:color-mix(in srgb,var(--agrid-color-danger-subtle) 88%,transparent);border-block:1px solid color-mix(in srgb,var(--agrid-color-danger) 35%,transparent)}.ag-delete-confirmation-text{font-weight:600;white-space:nowrap}.ag-delete-confirmation-btn{min-width:42px;padding:3px 9px;border:1px solid var(--agrid-color-border);border-radius:4px;color:var(--agrid-color-text);background:var(--agrid-color-bg);font:inherit;cursor:pointer}.ag-delete-confirmation-btn:hover,.ag-delete-confirmation-btn:focus-visible{border-color:var(--agrid-color-accent);outline:none}.ag-delete-confirmation-btn--yes{color:#fff;border-color:var(--agrid-color-danger);background:var(--agrid-color-danger)}.ag-delete-confirmation-btn--yes:hover,.ag-delete-confirmation-btn--yes:focus-visible{border-color:color-mix(in srgb,var(--agrid-color-danger) 75%,#000);background:color-mix(in srgb,var(--agrid-color-danger) 85%,#000)}:host(.ag-zebra) .ag-row--odd agrid-cell:not(.editing){background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd .ag-cell--pinned{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd .ag-control-cell{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd:hover agrid-cell:not(.editing){background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd:hover .ag-cell--pinned,:host(.ag-zebra) .ag-row--odd:hover .ag-control-cell{background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd.ag-row--selected agrid-cell:not(.editing){background:var(--agrid-color-accent-subtle)}:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-cell--pinned,:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-control-cell{background:var(--agrid-color-accent-subtle)}:host(.ag-zebra) .ag-row--odd .ag-cell--pinned-first{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd:hover .ag-cell--pinned-first{background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-cell--pinned-first{background:var(--agrid-color-accent-subtle)}.ag-row:hover agrid-cell:not(.editing){background:var(--agrid-color-bg-muted)}.ag-row--selected agrid-cell:not(.editing){background:var(--agrid-color-accent-subtle)}.ag-row--marked agrid-cell:not(.editing),.ag-row--marked .ag-control-cell{background:var(--agrid-color-row-marked)}.ag-row--marked{box-shadow:inset 3px 0 #bf8700}.ag-row--selected.ag-row--marked{box-shadow:inset 3px 0 0 var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--range-selected:not(.editing){background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1px var(--agrid-color-accent-border)}.ag-row agrid-cell.ag-cell--find-match:not(.editing){background:#fff7cc}.ag-row agrid-cell.ag-cell--find-active:not(.editing){background:#ffe58a;box-shadow:inset 0 0 0 2px #b7791f}.ag-row agrid-cell.ag-cell--range-selected.selected:not(.editing){box-shadow:inset 0 0 0 2px var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--fill-preview:not(.editing){background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1px var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--fill-handle:not(.editing){position:relative}.ag-row agrid-cell.ag-cell--fill-handle:not(.editing):after{content:\"\";position:absolute;right:1px;bottom:1px;width:6px;height:6px;background:var(--agrid-color-accent);border:1px solid var(--agrid-color-bg);box-sizing:border-box;cursor:crosshair;z-index:4}.ag-row--selected .ag-control-cell{background:var(--agrid-color-accent-subtle)}.ag-row--selected{box-shadow:inset 3px 0 0 var(--agrid-color-accent)}.ag-control-header{z-index:3;border-right:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted)}.ag-control-header .ag-header-cell-filter{background:var(--agrid-color-bg-subtle)}.ag-control-cell{z-index:2;border-right:1px solid var(--agrid-color-border);border-bottom:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-subtle);cursor:context-menu;display:flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;flex-direction:row-reverse}.ag-control-cell:after{content:\"\\22ee\";font-size:11px;color:var(--agrid-color-border);line-height:1}.ag-control-cell:hover:after{color:var(--agrid-color-text-muted)}.ag-control-cell--reorder{cursor:grab}.ag-control-cell--reorder:after{content:\"\\283f\";font-size:13px;color:var(--agrid-color-text)}.ag-control-cell--reorder:hover:after{color:var(--agrid-color-text-muted)}.ag-control-cell--reorder:active{cursor:grabbing}.ag-row-marker{position:relative;z-index:1;width:14px;height:14px;margin:0;accent-color:var(--agrid-color-accent);cursor:pointer}.ag-ghost-row{background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1.5px var(--agrid-color-accent);pointer-events:none;animation:ag-ghost-in .1s ease}@keyframes ag-ghost-in{0%{opacity:0}to{opacity:1}}.ag-ghost-handle:after{color:var(--agrid-color-accent)!important}.ag-ghost-cell{display:flex;align-items:center;padding:0 6px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;border-right:1px solid var(--agrid-color-accent-border);color:var(--agrid-color-accent-fg);font-size:13px;box-sizing:border-box;-webkit-user-select:none;user-select:none}.ag-ghost-cell:last-child{border-right:none}.ag-pinned-row-spacer,.ag-pinned-group-spacer{height:100%;border-bottom:1px solid var(--agrid-color-border);box-sizing:border-box}.ag-pinned-group-spacer{background:var(--agrid-color-bg-muted)}.ag-context-menu{position:fixed;z-index:1000;background:var(--agrid-color-bg-subtle);border:1px solid var(--agrid-color-border);border-radius:6px;box-shadow:0 8px 24px var(--agrid-color-shadow);min-width:160px;padding:4px 0;font-size:13px}.ag-context-item{display:block;width:100%;padding:6px 16px;text-align:left;background:none;border:none;cursor:pointer;color:var(--agrid-color-text);font:inherit}.ag-context-item:hover{background:var(--agrid-color-bg-muted)}.ag-context-separator{height:1px;background:var(--agrid-color-border);margin:3px 0}.ag-context-item--danger{color:var(--agrid-color-danger)}.ag-context-item--danger:hover{background:var(--agrid-color-danger-subtle)}.ag-group-header-row{display:flex;align-items:stretch;background:var(--agrid-color-bg-muted);border-bottom:1px solid var(--agrid-color-border);overflow:hidden}.ag-group-header-content{display:flex;align-items:stretch;height:100%;width:100%;-webkit-user-select:none;user-select:none}.ag-group-header-main{display:flex;align-items:center;gap:6px;padding:0 10px;flex:1;min-width:0;cursor:pointer}.ag-group-header-main:hover{background:var(--agrid-color-bg-subtle)}.ag-group-description{font-size:11px;color:var(--agrid-color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ag-group-actions-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:none;border-radius:3px;cursor:pointer;color:var(--agrid-color-text-muted);font-size:14px;padding:0}.ag-group-actions-btn:hover{background:var(--agrid-color-bg-muted);color:var(--agrid-color-text)}.ag-group-icon{font-size:9px;color:var(--agrid-color-text-muted);line-height:1;display:inline-block;transition:transform .15s ease}.ag-group-icon--expanded{transform:rotate(90deg)}.ag-group-label{font-weight:600;font-size:12px;color:var(--agrid-color-text)}.ag-group-count{font-size:11px;color:var(--agrid-color-text-muted);background:var(--agrid-color-bg);border:1px solid var(--agrid-color-border);border-radius:10px;padding:0 7px;line-height:16px}.ag-footer{display:grid;flex-shrink:0;background:var(--agrid-color-bg-muted);border-top:2px solid var(--agrid-color-border)}.ag-footer-cell{display:flex;align-items:center;gap:4px;padding:0 6px;height:30px;border-right:1px solid var(--agrid-color-border);box-sizing:border-box;overflow:hidden;white-space:nowrap;font-weight:600;font-size:12px;color:var(--agrid-color-text)}.ag-footer-cell:last-child{border-right:none}.ag-footer-cell--control{background:var(--agrid-color-bg-subtle);border-right:1px solid var(--agrid-color-border)}.ag-footer-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-footer-label{font-size:10px;font-weight:400;color:var(--agrid-color-text-muted);flex-shrink:0}.ag-pagination{display:flex;align-items:center;gap:4px;padding:0 10px;height:34px;flex-shrink:0;border-top:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted);font-size:12px;color:var(--agrid-color-text-muted)}.ag-page-btn{display:flex;align-items:center;justify-content:center;width:24px;height:22px;border:1px solid var(--agrid-color-border);border-radius:3px;background:var(--agrid-color-bg);color:var(--agrid-color-text);font-size:13px;cursor:pointer;padding:0;line-height:1}.ag-page-btn:hover:not(:disabled){background:var(--agrid-color-bg-muted);border-color:var(--agrid-color-text-muted)}.ag-page-btn:disabled{opacity:.35;cursor:default}.ag-page-info{padding:0 6px;font-weight:500;color:var(--agrid-color-text);min-width:48px;text-align:center}.ag-page-count{margin-left:auto;color:var(--agrid-color-text-muted)}.ag-add-row{border-bottom:1px dashed var(--agrid-color-border);color:var(--agrid-color-text-muted);cursor:pointer}.ag-add-row:hover .ag-add-row-label{background:var(--agrid-color-bg-muted)}.ag-add-row--selected .ag-add-row-label{outline:2px solid var(--agrid-color-accent);outline-offset:-2px}.ag-add-row-label{display:flex;align-items:center;gap:4px;height:100%;padding:0 6px;font-size:12px;-webkit-user-select:none;user-select:none}.ag-add-row-icon{font-size:16px;line-height:1;color:var(--agrid-color-text-muted)}.ag-pinned-pane--right{border-left:1px solid var(--agrid-color-border);border-right:none;box-shadow:-3px 0 6px -2px var(--agrid-color-shadow)}.ag-header-cell--pinned{background:var(--agrid-color-bg-muted)}.ag-header-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-header-cell--pinned-first{box-shadow:none}.ag-cell--pinned{background:var(--agrid-color-bg)}.ag-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-cell--pinned-first{box-shadow:none}.ag-row:hover .ag-cell--pinned{background:var(--agrid-color-bg-muted)}.ag-row--selected .ag-cell--pinned,.ag-row .ag-cell--pinned.ag-cell--range-selected,.ag-row .ag-cell--pinned.ag-cell--fill-preview{background:var(--agrid-color-accent-subtle)}.ag-row .ag-cell--pinned.ag-cell--find-match{background:#fff7cc}.ag-row .ag-cell--pinned.ag-cell--find-active{background:#ffe58a}.ag-header-menu-btn{flex-shrink:0;width:16px;height:16px;padding:0;margin-right:2px;background:none;border:1px solid transparent;border-radius:3px;cursor:pointer;font-size:10px;color:var(--agrid-color-text-muted);display:flex;align-items:center;justify-content:center;opacity:1;transition:opacity .12s;line-height:1}.ag-header-menu-btn--active{color:var(--agrid-color-accent);border-color:var(--agrid-color-accent-border);background:var(--agrid-color-accent-subtle)}.ag-header-menu-btn:hover{background:var(--agrid-color-bg);border-color:var(--agrid-color-border)}\n"], dependencies: [{ kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: AgridCellComponent, selector: "agrid-cell", inputs: ["col", "rowIndex", "colIndex", "value", "row", "locale", "selected", "editing", "treeCell", "treeLevel", "treeExpandable", "treeExpanded", "seedChar"], outputs: ["treeToggle", "activate", "startEdit", "draftChange"] }, { kind: "component", type: AgridColumnMenuComponent, selector: "agrid-column-menu", inputs: ["localeText", "x", "y", "header", "sortDir", "sortable", "showColumnActions", "pinned", "groupable", "grouped", "filterable", "showValueFilter", "search", "allSelected", "valueItems", "sortPriority", "hasMultiSort", "aggregate"], outputs: ["sort", "resetSort", "autosize", "togglePin", "togglePinRight", "hide", "toggleGroup", "clearFilter", "clearAll", "searchChange", "toggleAll", "toggleValue", "setAggregate"] }, { kind: "component", type: AgridFindPanelComponent, selector: "agrid-find-panel", inputs: ["localeText", "query", "matchCount", "activeIndex"], outputs: ["queryChange", "next", "previous", "close"] }, { kind: "component", type: AgridSidebarComponent, selector: "agrid-sidebar", inputs: ["open", "activeTab", "columns", "headerGroups", "row", "hiddenColumns", "locale", "localeText", "readonlyGrid", "useSidebarEditor"], outputs: ["close", "tabChange", "toggleColumn", "toggleColumnGroup", "detailEdit", "save"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5240
5563
|
}
|
|
5241
5564
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AgridComponent, decorators: [{
|
|
5242
5565
|
type: Component,
|
|
@@ -5250,7 +5573,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
5250
5573
|
'[class.ag-zebra]': 'zebraStripes()',
|
|
5251
5574
|
'[style.min-height]': 'minHeight()',
|
|
5252
5575
|
'[style.max-height]': 'maxHeight()',
|
|
5253
|
-
}, template: "<div #wrapper class=\"ag-wrapper\" tabindex=\"0\" role=\"grid\" [attr.aria-label]=\"localeText().grid\"\n [attr.aria-rowcount]=\"ariaRowCount()\" [attr.aria-colcount]=\"ariaColCount()\"\n [attr.aria-multiselectable]=\"rowSelection() === 'multi' ? 'true' : null\"\n [attr.aria-readonly]=\"readonlyGrid() ? 'true' : null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\" (copy)=\"onCopy($event)\" (paste)=\"onPaste($event)\"\n (focusin)=\"onGridFocusIn($event)\"\n (click)=\"closeContextMenu(); closeCellContextMenu(); closeFilterMenu(); closeGroupActionsMenu()\">\n <div class=\"ag-main-area\">\n <div class=\"ag-grid-split\" [class.ag-has-right-pane]=\"hasRightPinnedPane()\">\n @if (hasPinnedPane()) {\n <div class=\"ag-pinned-pane\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups ag-header-groups--pinned\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (showControlColumn()) {\n <div class=\"ag-header-group-cell ag-header-group-cell--empty\"></div>\n }\n @for (run of pinnedHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header ag-header--pinned\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (showControlColumn()) {\n <div class=\"ag-header-cell ag-control-header\" role=\"columnheader\" aria-colindex=\"1\">\n <div class=\"ag-header-cell-top\"></div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\"></div>\n }\n </div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-header-cell ag-header-cell--pinned\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-header-cell--pinned-last]=\"isLastPinnedColumn(col.field)\" [attr.data-col-field]=\"col.field\"\n (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #pinnedViewport class=\"ag-body ag-pinned-body\" [itemSize]=\"rowHeight()\"\n [style.width.px]=\"pinnedPaneWidth()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-add-row--selected]=\"item === null && isAddRowSelected()\" [class.ag-ghost-row]=\"item === 'ghost'\"\n [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isPinnedPaneRowSelected(item)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [attr.data-original-index]=\"getItemOriginalIndex(item)\" [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? pinnedGridTemplateColumns() : null\"\n (pointerdown)=\"isDataRowItem(item) && onRowPointerDown($event, item.originalIndex)\"\n (click)=\"isDataRowItem(item) && onRowClick($event, item)\">\n @if (isDataRowItem(item)) {\n @if (showControlColumn()) {\n <div class=\"ag-control-cell\" role=\"rowheader\" aria-colindex=\"1\"\n [class.ag-control-cell--reorder]=\"allowRowReorder()\"\n (contextmenu)=\"onControlContextMenu($event, item.originalIndex)\" (click)=\"$event.stopPropagation()\"\n (pointerdown)=\"onControlPointerDown($event, item.originalIndex)\">\n @if (enableRowMarking()) {\n <input class=\"ag-row-marker\" type=\"checkbox\" [checked]=\"isRowMarked(item.originalIndex)\"\n [attr.aria-label]=\"localeText().markRow\"\n (pointerdown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRowMarked(item.originalIndex)\" />\n }\n </div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\" [class.ag-cell--pinned]=\"true\"\n [class.ag-cell--pinned-last]=\"isLastPinnedColumn(col.field)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\" (startEdit)=\"onStartEdit(item.originalIndex, ci)\"\n (draftChange)=\"onDraftChange($event)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-pinned-row-spacer\"></div>\n } @else if (item === 'ghost') {\n @if (showControlColumn()) {\n <div class=\"ag-control-cell ag-control-cell--reorder ag-ghost-handle\"></div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-ghost-cell ag-cell--pinned\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--pinned-last]=\"isLastPinnedColumn(col.field)\">{{\n getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-pinned-group-spacer\"></div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\">\n @if (showControlColumn()) {\n <div class=\"ag-footer-cell ag-footer-cell--control\" role=\"gridcell\" aria-colindex=\"1\"></div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [class.ag-footer-cell--pinned-last]=\"isLastPinnedColumn(col.field)\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"ag-scroll-pane\">\n <div #horizontalScroller class=\"ag-horizontal-scroll\" (scroll)=\"onHorizontalScroll()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (run of scrollableHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-header-cell\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.data-col-field]=\"col.field\" (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n @if (isGroupedByField(col.field)) {\n <span class=\"ag-sort-badge\">\u229F</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #scrollViewport class=\"ag-body\" [itemSize]=\"rowHeight()\"\n [style.min-width.px]=\"scrollableTotalWidth()\" (scroll)=\"onBodyScroll()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-add-row--selected]=\"item === null && isAddRowSelected()\" [class.ag-ghost-row]=\"item === 'ghost'\"\n [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [attr.data-original-index]=\"getItemOriginalIndex(item)\" [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? scrollableGridTemplateColumns() : null\"\n (pointerdown)=\"isDataRowItem(item) && onRowPointerDown($event, item.originalIndex)\"\n (click)=\"isDataRowItem(item) && onRowClick($event, item)\">\n @if (isDataRowItem(item)) {\n @for (col of scrollableColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\"\n (startEdit)=\"onStartEdit(item.originalIndex, ci)\" (draftChange)=\"onDraftChange($event)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-add-row-label\" (click)=\"onActivateAddRow()\">\n <span class=\"ag-add-row-icon\">+</span> {{ localeText().addRow }}\n </div>\n } @else if (item === 'ghost') {\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-ghost-cell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\">{{\n getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-group-header-content\" [style.min-width.px]=\"scrollableTotalWidth()\">\n <div class=\"ag-group-header-main\"\n (click)=\"onGroupHeaderClick(item.groupLabel); $event.stopPropagation()\">\n <span class=\"ag-group-icon\" [class.ag-group-icon--expanded]=\"!item.collapsed\">\u25B6</span>\n <span class=\"ag-group-label\">{{ item.groupLabel }}</span>\n @if (groupActions().length > 0) {\n <button class=\"ag-group-actions-btn\" [title]=\"localeText().actions\"\n (click)=\"openGroupActionsMenu($event, item.groupLabel)\">\u22EE</button>\n }\n <span class=\"ag-group-count\">{{ item.count }}</span>\n @if (getGroupDescription(item.groupLabel); as desc) {\n <span class=\"ag-group-description\">{{ desc }}</span>\n }\n </div>\n </div>\n }\n @if (isDataRowItem(item) && isRowPendingDelete(item.originalIndex)) {\n <div class=\"ag-delete-confirmation\" role=\"alertdialog\"\n [attr.aria-label]=\"localeText().confirmDeleteRow\"\n [style.left.px]=\"deleteConfirmationLeft()\"\n [style.width.px]=\"deleteConfirmationWidth() || null\"\n (pointerdown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\n <span class=\"ag-delete-confirmation-text\">{{ localeText().confirmDeleteRow }}</span>\n <button class=\"ag-delete-confirmation-btn ag-delete-confirmation-btn--yes\"\n type=\"button\" (click)=\"confirmPendingRowDelete()\">{{ localeText().confirmYes }}</button>\n <button class=\"ag-delete-confirmation-btn\" type=\"button\" data-delete-confirm-no\n (click)=\"cancelRowDelete()\">{{ localeText().confirmNo }}</button>\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (hasRightPinnedPane()) {\n <div class=\"ag-pinned-pane ag-pinned-pane--right\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @for (run of rightHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-header-cell ag-header-cell--pinned\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-header-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\" [attr.data-col-field]=\"col.field\"\n (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n @if (isGroupedByField(col.field)) {\n <span class=\"ag-sort-badge\">'\u229F '</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #rightPinnedViewport class=\"ag-body ag-pinned-body ag-right-pinned-body\"\n [itemSize]=\"rowHeight()\" [style.width.px]=\"rightPinnedPaneWidth()\" (scroll)=\"onRightPinnedBodyScroll()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-ghost-row]=\"item === 'ghost'\" [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? rightGridTemplateColumns() : null\">\n @if (isDataRowItem(item)) {\n @for (col of rightPinnedColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--pinned]=\"true\" [class.ag-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\" (startEdit)=\"onStartEdit(item.originalIndex, ci)\"\n (draftChange)=\"onDraftChange($event)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-pinned-row-spacer\"></div>\n } @else if (item === 'ghost') {\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-ghost-cell ag-cell--pinned\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\">{{ getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-pinned-group-spacer\"></div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\">\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [class.ag-footer-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n @if (loading()) {\n <div class=\"ag-state-overlay\" role=\"status\" aria-live=\"polite\">{{ localeText().loading }}</div>\n } @else if (isEmpty()) {\n <div class=\"ag-state-overlay\" role=\"status\" aria-live=\"polite\">{{ emptyTextLabel() }}</div>\n }\n\n @if (showSidebar()) {\n <agrid-sidebar\n [open]=\"sidebarOpen()\"\n [activeTab]=\"sidebarTab()\"\n [columns]=\"colDefs()\"\n [row]=\"sidebarRow()\"\n [hiddenColumns]=\"sidebarHiddenColumns()\"\n [locale]=\"locale()\"\n [localeText]=\"localeText()\"\n [readonlyGrid]=\"readonlyGrid()\"\n [useSidebarEditor]=\"useSidebarEditor()\"\n (close)=\"toggleSidebar()\"\n (tabChange)=\"onSidebarStripClick($event)\"\n (toggleColumn)=\"onSidebarToggleColumn($event)\"\n (detailEdit)=\"onSidebarDetailEdit($event)\"\n (save)=\"onSidebarDetailSave($event)\"\n />\n }\n </div><!-- /.ag-main-area -->\n\n @if (showPagination()) {\n <nav class=\"ag-pagination\" [attr.aria-label]=\"localeText().pagination\">\n <button class=\"ag-page-btn\" [attr.aria-label]=\"localeText().firstPage\"\n [disabled]=\"control()!.currentPage() <= 1\" (click)=\"goToFirstPage()\">\u00AB</button>\n <button class=\"ag-page-btn\" [attr.aria-label]=\"localeText().previous\"\n [disabled]=\"control()!.currentPage() <= 1\" (click)=\"goToPrevPage()\">\u2039</button>\n <span class=\"ag-page-info\" aria-live=\"polite\">{{ control()!.currentPage() }} / {{ totalPages() }}</span>\n <button class=\"ag-page-btn\" [disabled]=\"control()!.currentPage() >= totalPages()\"\n [attr.aria-label]=\"localeText().next\"\n (click)=\"goToNextPage()\">\u203A</button>\n <button class=\"ag-page-btn\" [disabled]=\"control()!.currentPage() >= totalPages()\"\n [attr.aria-label]=\"localeText().lastPage\"\n (click)=\"goToLastPage()\">\u00BB</button>\n <span class=\"ag-page-count\">{{ localeText().rows(filteredRowCount()) }}</span>\n </nav>\n }\n\n @if (findOpen()) {\n <agrid-find-panel [query]=\"findQuery()\" [matchCount]=\"findMatches().length\" [activeIndex]=\"findActiveIndex()\"\n [localeText]=\"localeText()\" (queryChange)=\"onFindInput($event)\" (previous)=\"goToFindMatch(-1)\"\n (next)=\"goToFindMatch(1)\" (close)=\"closeFind()\" />\n }\n\n <!-- Row context menu -->\n @if (contextMenu(); as menu) {\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"ag-context-item ag-context-item--danger\" role=\"menuitem\" (click)=\"deleteRow(menu.rowIndex)\">\n {{ localeText().deleteRow }}\n </button>\n </div>\n }\n\n <!-- Cell context menu -->\n @if (cellContextMenuState(); as menu) {\n @let col = getColDef(menu.field)!;\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"copyCellToClipboard(menu.rowIndex, col)\">{{ localeText().copyCellValue\n }}</button>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"copyRowToClipboard(menu.rowIndex)\">{{ localeText().copyRow }}</button>\n @if (allowAddRows() && !readonlyGrid()) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"insertRowAt(menu.rowIndex)\">{{ localeText().insertRowAbove }}</button>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"insertRowAt(menu.rowIndex + 1)\">{{ localeText().insertRowBelow }}</button>\n }\n @if (!readonlyGrid()) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n <button class=\"ag-context-item ag-context-item--danger\" role=\"menuitem\"\n (click)=\"deleteRow(menu.rowIndex)\">{{ localeText().deleteRow }}</button>\n }\n @if (cellMenuItems().length) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n @for (item of cellMenuItems(); track $index) {\n @if (item === null) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n } @else {\n <button class=\"ag-context-item\" role=\"menuitem\" [class.ag-context-item--danger]=\"item.danger\" [disabled]=\"item.disabled\"\n (click)=\"runCellMenuItem(item, menu)\">{{\n item.label }}</button>\n }\n }\n }\n </div>\n }\n\n <!-- Group actions menu -->\n @if (groupActionsMenu(); as menu) {\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n @for (action of groupActions(); track action.label) {\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"onGroupAction(action, menu.label)\">\n {{ action.label }}\n </button>\n }\n </div>\n }\n\n <!-- Filter dropdown -->\n @if (filterMenu(); as menu) {\n <agrid-column-menu [x]=\"menu.x\" [y]=\"menu.y\" [header]=\"getColDef(menu.field)?.header ?? menu.field\"\n [sortDir]=\"getSort(menu.field)\" [sortable]=\"sortOption() !== 'none'\"\n [showColumnActions]=\"!!control()\" [pinned]=\"getColumnPinState(menu.field)\"\n [groupable]=\"!!getColDef(menu.field)?.groupable\" [grouped]=\"isGroupedByField(menu.field)\"\n [filterable]=\"!!getColDef(menu.field)?.filterable\" [showValueFilter]=\"!serverSideFiltering()\"\n [search]=\"filterMenuSearch()\"\n [allSelected]=\"isMenuAllSelected(menu.field)\"\n [valueItems]=\"serverSideFiltering() || !getColDef(menu.field)?.filterable ? [] : columnMenuValueItems()\"\n [localeText]=\"localeText()\"\n [sortPriority]=\"getSortPriority(menu.field)\" [hasMultiSort]=\"hasMultiSort()\" (sort)=\"onMenuSort(menu.field, $event)\"\n (resetSort)=\"onMenuResetSort(menu.field, $event)\" (autosize)=\"onMenuAutosizeColumn(menu.field)\"\n (togglePin)=\"onMenuTogglePin(menu.field)\" (togglePinRight)=\"onMenuTogglePinRight(menu.field)\"\n (hide)=\"onMenuHideColumn(menu.field)\" (toggleGroup)=\"onMenuToggleGroupBy(menu.field)\"\n (clearFilter)=\"onMenuClearFilter(menu.field)\" (clearAll)=\"onMenuClearAll()\"\n (searchChange)=\"onFilterMenuSearch($event)\" (toggleAll)=\"onMenuToggleAll(menu.field)\"\n (toggleValue)=\"onMenuToggleValue(menu.field, $event)\" [aggregate]=\"getEffectiveAggregate(getColDef(menu.field)!)\"\n (setAggregate)=\"onMenuSetAggregate(menu.field, $event)\" />\n }\n\n @if (columnDragPreview(); as preview) {\n <div class=\"ag-column-drag-preview\"\n [style.left.px]=\"preview.x\" [style.top.px]=\"preview.y\"\n [style.width.px]=\"preview.width\" [style.height.px]=\"preview.height\">\n <span>{{ preview.label }}</span>\n </div>\n }\n</div>\n", styles: ["@layer agrid-defaults{:host{--agrid-color-text: #24292f;--agrid-color-text-muted: #57606a;--agrid-color-accent: #1a73e8;--agrid-color-accent-subtle: #e8f0fe;--agrid-color-accent-fg: #1558b0;--agrid-color-accent-border: #c8d8f8;--agrid-color-danger: #d1242f;--agrid-color-danger-subtle: #fff1f0;--agrid-color-border: #d0d7de;--agrid-color-bg: #ffffff;--agrid-color-bg-subtle: #fafbfc;--agrid-color-bg-muted: #f6f8fa;--agrid-color-shadow: rgba(140, 149, 159, .2);--agrid-color-bg-stripe: #f0f2f5;--agrid-color-cell-changed: #f59e0b;--agrid-color-row-marked: #fff8c5}}:host{display:flex;flex-direction:column;min-height:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--agrid-color-text)}.ag-wrapper{position:relative;display:flex;flex-direction:column;flex:1;min-height:0;border:1px solid var(--agrid-color-border);overflow:hidden;outline:none;border-radius:4px}.ag-state-overlay{position:absolute;inset:34px 0 0;display:flex;align-items:center;justify-content:center;color:var(--agrid-color-text-muted);background:color-mix(in srgb,var(--agrid-color-bg) 78%,transparent);pointer-events:none;z-index:3}.ag-header{display:grid;flex-shrink:0;background:var(--agrid-color-bg-muted);border-bottom:2px solid var(--agrid-color-border)}.ag-header-groups{display:grid;flex-shrink:0;height:28px;background:color-mix(in srgb,var(--agrid-color-bg-muted) 72%,var(--agrid-color-bg));border-bottom:1px solid var(--agrid-color-border)}.ag-header-group-cell{display:flex;align-items:center;justify-content:center;min-width:0;padding:0 8px;overflow:hidden;border-right:1px solid var(--agrid-color-border);box-sizing:border-box;color:var(--agrid-color-text);font-size:12px;font-weight:600;text-overflow:ellipsis;white-space:nowrap;cursor:grab;-webkit-user-select:none;user-select:none;transition:opacity .1s ease}.ag-header-group-cell:last-child{border-right:none}.ag-header-group-cell--empty,.ag-header-group-cell--locked{cursor:default}.ag-header-group-cell--dragging{opacity:.12}.ag-header-cell{position:relative;display:flex;align-items:center;font-weight:600;border-right:1px solid var(--agrid-color-border);overflow:hidden;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box}.ag-header-cell:last-child{border-right:none}.ag-header-cell-top{display:flex;align-items:center;flex:1;min-width:0;padding:0 6px;height:32px;overflow:hidden;white-space:nowrap}.ag-header-cell-label{overflow:hidden;text-overflow:ellipsis;flex:1}.ag-header--with-filters .ag-header-cell{flex-direction:column;align-items:stretch;height:auto;white-space:normal}.ag-header--with-filters .ag-header-cell-top{flex:0 0 32px}.ag-header-cell-filter{height:28px;display:flex;align-items:center;padding:0 2px;border-top:1px solid var(--agrid-color-border);background:var(--agrid-color-bg)}.ag-header-cell{cursor:grab;transition:transform .16s cubic-bezier(.2,0,0,1),opacity .1s ease;will-change:transform}.ag-row>agrid-cell,.ag-ghost-cell,.ag-footer-cell{transition:transform .16s cubic-bezier(.2,0,0,1),opacity .1s ease;will-change:transform}.ag-header-cell--dragging{opacity:.12;cursor:grabbing}.ag-column-reorder-item--dragging{opacity:.12}.ag-header-cell--drop-before,.ag-header-cell--drop-after{z-index:1}.ag-column-drag-preview{position:fixed;z-index:1000;display:flex;align-items:flex-start;padding:8px 10px;border:1px solid var(--agrid-color-accent);border-radius:5px;color:var(--agrid-color-text);background:color-mix(in srgb,var(--agrid-color-bg) 94%,var(--agrid-color-accent));box-shadow:0 10px 28px var(--agrid-color-shadow);font-weight:600;line-height:16px;box-sizing:border-box;pointer-events:none;opacity:.96}.ag-sort-badge{font-size:11px;color:var(--agrid-color-accent);flex-shrink:0;line-height:1}.ag-sort-priority{font-size:9px;vertical-align:super;opacity:.75}.ag-resize-handle{position:absolute;top:0;right:0;width:5px;height:100%;cursor:col-resize;z-index:1}.ag-resize-handle:hover{background:var(--agrid-color-accent);opacity:.5}.ag-filter-input{flex:1;min-width:0;height:20px;border:1px solid var(--agrid-color-border);border-radius:3px;outline:none;font:inherit;font-size:12px;padding:0 4px;background:var(--agrid-color-bg)}.ag-filter-input:focus{border-color:var(--agrid-color-accent)}.ag-header-cell--filtered .ag-header-cell-label:after{content:\" \\25be\";font-size:9px;color:var(--agrid-color-accent)}.ag-main-area{display:flex;flex:1;min-height:0;overflow:hidden}.ag-grid-split{display:flex;flex:1;min-width:0;min-height:0;overflow:hidden}.ag-pinned-pane{flex-shrink:0;min-height:0;display:flex;flex-direction:column;overflow:hidden;border-right:1px solid var(--agrid-color-border);background:var(--agrid-color-bg)}.ag-scroll-pane{flex:1;min-width:0;min-height:0;display:flex}.ag-horizontal-scroll{flex:1;min-width:0;min-height:0;overflow-x:auto;overflow-y:hidden;display:flex;flex-direction:column}.ag-body{flex:1;overflow-x:clip;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-horizontal-scroll{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-body::-webkit-scrollbar,.ag-horizontal-scroll::-webkit-scrollbar{width:8px;height:8px}.ag-body::-webkit-scrollbar-track,.ag-horizontal-scroll::-webkit-scrollbar-track{background:transparent}.ag-body::-webkit-scrollbar-thumb,.ag-horizontal-scroll::-webkit-scrollbar-thumb{background:#0000002e;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-body::-webkit-scrollbar-thumb:hover,.ag-horizontal-scroll::-webkit-scrollbar-thumb:hover{background:#00000052;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-pinned-body{overflow:hidden}.ag-right-pinned-body{overflow-y:auto}.ag-has-right-pane .ag-body:not(.ag-pinned-body){scrollbar-width:none}.ag-has-right-pane .ag-body:not(.ag-pinned-body)::-webkit-scrollbar{display:none}.ag-row{display:grid;position:relative}.ag-row--pending-delete>:not(.ag-delete-confirmation){opacity:.2;pointer-events:none;transition:opacity .14s ease}.ag-delete-confirmation{position:absolute;top:0;bottom:0;z-index:7;display:flex;align-items:center;justify-content:center;gap:8px;min-width:min(100%,320px);padding:2px 12px;box-sizing:border-box;color:var(--agrid-color-text);background:color-mix(in srgb,var(--agrid-color-danger-subtle) 88%,transparent);border-block:1px solid color-mix(in srgb,var(--agrid-color-danger) 35%,transparent)}.ag-delete-confirmation-text{font-weight:600;white-space:nowrap}.ag-delete-confirmation-btn{min-width:42px;padding:3px 9px;border:1px solid var(--agrid-color-border);border-radius:4px;color:var(--agrid-color-text);background:var(--agrid-color-bg);font:inherit;cursor:pointer}.ag-delete-confirmation-btn:hover,.ag-delete-confirmation-btn:focus-visible{border-color:var(--agrid-color-accent);outline:none}.ag-delete-confirmation-btn--yes{color:#fff;border-color:var(--agrid-color-danger);background:var(--agrid-color-danger)}.ag-delete-confirmation-btn--yes:hover,.ag-delete-confirmation-btn--yes:focus-visible{border-color:color-mix(in srgb,var(--agrid-color-danger) 75%,#000);background:color-mix(in srgb,var(--agrid-color-danger) 85%,#000)}:host(.ag-zebra) .ag-row--odd agrid-cell:not(.editing){background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd .ag-cell--pinned{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd .ag-control-cell{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd:hover agrid-cell:not(.editing){background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd:hover .ag-cell--pinned,:host(.ag-zebra) .ag-row--odd:hover .ag-control-cell{background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd.ag-row--selected agrid-cell:not(.editing){background:var(--agrid-color-accent-subtle)}:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-cell--pinned,:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-control-cell{background:var(--agrid-color-accent-subtle)}:host(.ag-zebra) .ag-row--odd .ag-cell--pinned-first{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd:hover .ag-cell--pinned-first{background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-cell--pinned-first{background:var(--agrid-color-accent-subtle)}.ag-row:hover agrid-cell:not(.editing){background:var(--agrid-color-bg-muted)}.ag-row--selected agrid-cell:not(.editing){background:var(--agrid-color-accent-subtle)}.ag-row--marked agrid-cell:not(.editing),.ag-row--marked .ag-control-cell{background:var(--agrid-color-row-marked)}.ag-row--marked{box-shadow:inset 3px 0 #bf8700}.ag-row--selected.ag-row--marked{box-shadow:inset 3px 0 0 var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--range-selected:not(.editing){background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1px var(--agrid-color-accent-border)}.ag-row agrid-cell.ag-cell--find-match:not(.editing){background:#fff7cc}.ag-row agrid-cell.ag-cell--find-active:not(.editing){background:#ffe58a;box-shadow:inset 0 0 0 2px #b7791f}.ag-row agrid-cell.ag-cell--range-selected.selected:not(.editing){box-shadow:inset 0 0 0 2px var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--fill-preview:not(.editing){background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1px var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--fill-handle:not(.editing){position:relative}.ag-row agrid-cell.ag-cell--fill-handle:not(.editing):after{content:\"\";position:absolute;right:1px;bottom:1px;width:6px;height:6px;background:var(--agrid-color-accent);border:1px solid var(--agrid-color-bg);box-sizing:border-box;cursor:crosshair;z-index:4}.ag-row--selected .ag-control-cell{background:var(--agrid-color-accent-subtle)}.ag-row--selected{box-shadow:inset 3px 0 0 var(--agrid-color-accent)}.ag-control-header{z-index:3;border-right:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted)}.ag-control-header .ag-header-cell-filter{background:var(--agrid-color-bg-subtle)}.ag-control-cell{z-index:2;border-right:1px solid var(--agrid-color-border);border-bottom:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-subtle);cursor:context-menu;display:flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;flex-direction:row-reverse}.ag-control-cell:after{content:\"\\22ee\";font-size:11px;color:var(--agrid-color-border);line-height:1}.ag-control-cell:hover:after{color:var(--agrid-color-text-muted)}.ag-control-cell--reorder{cursor:grab}.ag-control-cell--reorder:after{content:\"\\283f\";font-size:13px;color:var(--agrid-color-text)}.ag-control-cell--reorder:hover:after{color:var(--agrid-color-text-muted)}.ag-control-cell--reorder:active{cursor:grabbing}.ag-row-marker{position:relative;z-index:1;width:14px;height:14px;margin:0;accent-color:var(--agrid-color-accent);cursor:pointer}.ag-ghost-row{background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1.5px var(--agrid-color-accent);pointer-events:none;animation:ag-ghost-in .1s ease}@keyframes ag-ghost-in{0%{opacity:0}to{opacity:1}}.ag-ghost-handle:after{color:var(--agrid-color-accent)!important}.ag-ghost-cell{display:flex;align-items:center;padding:0 6px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;border-right:1px solid var(--agrid-color-accent-border);color:var(--agrid-color-accent-fg);font-size:13px;box-sizing:border-box;-webkit-user-select:none;user-select:none}.ag-ghost-cell:last-child{border-right:none}.ag-pinned-row-spacer,.ag-pinned-group-spacer{height:100%;border-bottom:1px solid var(--agrid-color-border);box-sizing:border-box}.ag-pinned-group-spacer{background:var(--agrid-color-bg-muted)}.ag-context-menu{position:fixed;z-index:1000;background:var(--agrid-color-bg-subtle);border:1px solid var(--agrid-color-border);border-radius:6px;box-shadow:0 8px 24px var(--agrid-color-shadow);min-width:160px;padding:4px 0;font-size:13px}.ag-context-item{display:block;width:100%;padding:6px 16px;text-align:left;background:none;border:none;cursor:pointer;color:var(--agrid-color-text);font:inherit}.ag-context-item:hover{background:var(--agrid-color-bg-muted)}.ag-context-separator{height:1px;background:var(--agrid-color-border);margin:3px 0}.ag-context-item--danger{color:var(--agrid-color-danger)}.ag-context-item--danger:hover{background:var(--agrid-color-danger-subtle)}.ag-group-header-row{display:flex;align-items:stretch;background:var(--agrid-color-bg-muted);border-bottom:1px solid var(--agrid-color-border);overflow:hidden}.ag-group-header-content{display:flex;align-items:stretch;height:100%;width:100%;-webkit-user-select:none;user-select:none}.ag-group-header-main{display:flex;align-items:center;gap:6px;padding:0 10px;flex:1;min-width:0;cursor:pointer}.ag-group-header-main:hover{background:var(--agrid-color-bg-subtle)}.ag-group-description{font-size:11px;color:var(--agrid-color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ag-group-actions-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:none;border-radius:3px;cursor:pointer;color:var(--agrid-color-text-muted);font-size:14px;padding:0}.ag-group-actions-btn:hover{background:var(--agrid-color-bg-muted);color:var(--agrid-color-text)}.ag-group-icon{font-size:9px;color:var(--agrid-color-text-muted);line-height:1;display:inline-block;transition:transform .15s ease}.ag-group-icon--expanded{transform:rotate(90deg)}.ag-group-label{font-weight:600;font-size:12px;color:var(--agrid-color-text)}.ag-group-count{font-size:11px;color:var(--agrid-color-text-muted);background:var(--agrid-color-bg);border:1px solid var(--agrid-color-border);border-radius:10px;padding:0 7px;line-height:16px}.ag-footer{display:grid;flex-shrink:0;background:var(--agrid-color-bg-muted);border-top:2px solid var(--agrid-color-border)}.ag-footer-cell{display:flex;align-items:center;gap:4px;padding:0 6px;height:30px;border-right:1px solid var(--agrid-color-border);box-sizing:border-box;overflow:hidden;white-space:nowrap;font-weight:600;font-size:12px;color:var(--agrid-color-text)}.ag-footer-cell:last-child{border-right:none}.ag-footer-cell--control{background:var(--agrid-color-bg-subtle);border-right:1px solid var(--agrid-color-border)}.ag-footer-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-footer-label{font-size:10px;font-weight:400;color:var(--agrid-color-text-muted);flex-shrink:0}.ag-pagination{display:flex;align-items:center;gap:4px;padding:0 10px;height:34px;flex-shrink:0;border-top:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted);font-size:12px;color:var(--agrid-color-text-muted)}.ag-page-btn{display:flex;align-items:center;justify-content:center;width:24px;height:22px;border:1px solid var(--agrid-color-border);border-radius:3px;background:var(--agrid-color-bg);color:var(--agrid-color-text);font-size:13px;cursor:pointer;padding:0;line-height:1}.ag-page-btn:hover:not(:disabled){background:var(--agrid-color-bg-muted);border-color:var(--agrid-color-text-muted)}.ag-page-btn:disabled{opacity:.35;cursor:default}.ag-page-info{padding:0 6px;font-weight:500;color:var(--agrid-color-text);min-width:48px;text-align:center}.ag-page-count{margin-left:auto;color:var(--agrid-color-text-muted)}.ag-add-row{border-bottom:1px dashed var(--agrid-color-border);color:var(--agrid-color-text-muted);cursor:pointer}.ag-add-row:hover .ag-add-row-label{background:var(--agrid-color-bg-muted)}.ag-add-row--selected .ag-add-row-label{outline:2px solid var(--agrid-color-accent);outline-offset:-2px}.ag-add-row-label{display:flex;align-items:center;gap:4px;height:100%;padding:0 6px;font-size:12px;-webkit-user-select:none;user-select:none}.ag-add-row-icon{font-size:16px;line-height:1;color:var(--agrid-color-text-muted)}.ag-pinned-pane--right{border-left:1px solid var(--agrid-color-border);border-right:none;box-shadow:-3px 0 6px -2px var(--agrid-color-shadow)}.ag-header-cell--pinned{background:var(--agrid-color-bg-muted)}.ag-header-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-header-cell--pinned-first{box-shadow:none}.ag-cell--pinned{background:var(--agrid-color-bg)}.ag-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-cell--pinned-first{box-shadow:none}.ag-row:hover .ag-cell--pinned{background:var(--agrid-color-bg-muted)}.ag-row--selected .ag-cell--pinned,.ag-row .ag-cell--pinned.ag-cell--range-selected,.ag-row .ag-cell--pinned.ag-cell--fill-preview{background:var(--agrid-color-accent-subtle)}.ag-row .ag-cell--pinned.ag-cell--find-match{background:#fff7cc}.ag-row .ag-cell--pinned.ag-cell--find-active{background:#ffe58a}.ag-header-menu-btn{flex-shrink:0;width:16px;height:16px;padding:0;margin-right:2px;background:none;border:1px solid transparent;border-radius:3px;cursor:pointer;font-size:10px;color:var(--agrid-color-text-muted);display:flex;align-items:center;justify-content:center;opacity:1;transition:opacity .12s;line-height:1}.ag-header-menu-btn--active{color:var(--agrid-color-accent);border-color:var(--agrid-color-accent-border);background:var(--agrid-color-accent-subtle)}.ag-header-menu-btn:hover{background:var(--agrid-color-bg);border-color:var(--agrid-color-border)}\n"] }]
|
|
5576
|
+
}, template: "<div #wrapper class=\"ag-wrapper\" tabindex=\"0\" role=\"grid\" [attr.aria-label]=\"localeText().grid\"\n [attr.aria-rowcount]=\"ariaRowCount()\" [attr.aria-colcount]=\"ariaColCount()\"\n [attr.aria-multiselectable]=\"rowSelection() === 'multi' ? 'true' : null\"\n [attr.aria-readonly]=\"readonlyGrid() ? 'true' : null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\" (copy)=\"onCopy($event)\" (paste)=\"onPaste($event)\"\n (focusin)=\"onGridFocusIn($event)\"\n (click)=\"closeContextMenu(); closeCellContextMenu(); closeFilterMenu(); closeGroupActionsMenu()\">\n <div class=\"ag-main-area\">\n <div class=\"ag-grid-split\" [class.ag-has-right-pane]=\"hasRightPinnedPane()\">\n @if (hasPinnedPane()) {\n <div class=\"ag-pinned-pane\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups ag-header-groups--pinned\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (showControlColumn()) {\n <div class=\"ag-header-group-cell ag-header-group-cell--empty\"></div>\n }\n @for (run of pinnedHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header ag-header--pinned\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\" [style.width.px]=\"pinnedPaneWidth()\">\n @if (showControlColumn()) {\n <div class=\"ag-header-cell ag-control-header\" role=\"columnheader\" aria-colindex=\"1\">\n <div class=\"ag-header-cell-top\"></div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\"></div>\n }\n </div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-header-cell ag-header-cell--pinned\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-header-cell--pinned-last]=\"isLastPinnedColumn(col.field)\" [attr.data-col-field]=\"col.field\"\n (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #pinnedViewport class=\"ag-body ag-pinned-body\" [itemSize]=\"rowHeight()\"\n [style.width.px]=\"pinnedPaneWidth()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-add-row--selected]=\"item === null && isAddRowSelected()\" [class.ag-ghost-row]=\"item === 'ghost'\"\n [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isPinnedPaneRowSelected(item)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [attr.data-original-index]=\"getItemOriginalIndex(item)\" [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? pinnedGridTemplateColumns() : null\"\n (pointerdown)=\"isDataRowItem(item) && onRowPointerDown($event, item.originalIndex)\"\n (click)=\"isDataRowItem(item) && onRowClick($event, item)\">\n @if (isDataRowItem(item)) {\n @if (showControlColumn()) {\n <div class=\"ag-control-cell\" role=\"rowheader\" aria-colindex=\"1\"\n [class.ag-control-cell--reorder]=\"allowRowReorder()\"\n (contextmenu)=\"onControlContextMenu($event, item.originalIndex)\" (click)=\"$event.stopPropagation()\"\n (pointerdown)=\"onControlPointerDown($event, item.originalIndex)\">\n @if (enableRowMarking()) {\n <input class=\"ag-row-marker\" type=\"checkbox\" [checked]=\"isRowMarked(item.originalIndex)\"\n [attr.aria-label]=\"localeText().markRow\"\n (pointerdown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRowMarked(item.originalIndex)\" />\n }\n </div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [treeCell]=\"isTreeCell(col)\" [treeLevel]=\"treeRowLevel(item)\"\n [treeExpandable]=\"treeRowExpandable(item)\" [treeExpanded]=\"treeRowExpanded(item)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\" [class.ag-cell--pinned]=\"true\"\n [class.ag-cell--pinned-last]=\"isLastPinnedColumn(col.field)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\" (startEdit)=\"onStartEdit(item.originalIndex, ci)\"\n (draftChange)=\"onDraftChange($event)\" (treeToggle)=\"onTreeToggle(item)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-pinned-row-spacer\"></div>\n } @else if (item === 'ghost') {\n @if (showControlColumn()) {\n <div class=\"ag-control-cell ag-control-cell--reorder ag-ghost-handle\"></div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-ghost-cell ag-cell--pinned\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--pinned-last]=\"isLastPinnedColumn(col.field)\">{{\n getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-pinned-group-spacer\"></div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"pinnedGridTemplateColumns()\">\n @if (showControlColumn()) {\n <div class=\"ag-footer-cell ag-footer-cell--control\" role=\"gridcell\" aria-colindex=\"1\"></div>\n }\n @for (col of pinnedColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [class.ag-footer-cell--pinned-last]=\"isLastPinnedColumn(col.field)\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"ag-scroll-pane\">\n <div #horizontalScroller class=\"ag-horizontal-scroll\" (scroll)=\"onHorizontalScroll()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (run of scrollableHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-header-cell\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.data-col-field]=\"col.field\" (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n @if (isGroupedByField(col.field)) {\n <span class=\"ag-sort-badge\">\u229F</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #scrollViewport class=\"ag-body\" [itemSize]=\"rowHeight()\"\n [style.min-width.px]=\"scrollableTotalWidth()\" (scroll)=\"onBodyScroll()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-add-row--selected]=\"item === null && isAddRowSelected()\" [class.ag-ghost-row]=\"item === 'ghost'\"\n [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [attr.data-original-index]=\"getItemOriginalIndex(item)\" [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? scrollableGridTemplateColumns() : null\"\n (pointerdown)=\"isDataRowItem(item) && onRowPointerDown($event, item.originalIndex)\"\n (click)=\"isDataRowItem(item) && onRowClick($event, item)\">\n @if (isDataRowItem(item)) {\n @for (col of scrollableColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [treeCell]=\"isTreeCell(col)\" [treeLevel]=\"treeRowLevel(item)\"\n [treeExpandable]=\"treeRowExpandable(item)\" [treeExpanded]=\"treeRowExpanded(item)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\"\n (startEdit)=\"onStartEdit(item.originalIndex, ci)\" (draftChange)=\"onDraftChange($event)\"\n (treeToggle)=\"onTreeToggle(item)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-add-row-label\" (click)=\"onActivateAddRow()\">\n <span class=\"ag-add-row-icon\">+</span> {{ localeText().addRow }}\n </div>\n } @else if (item === 'ghost') {\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-ghost-cell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\">{{\n getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-group-header-content\" [style.min-width.px]=\"scrollableTotalWidth()\">\n <div class=\"ag-group-header-main\"\n (click)=\"onGroupHeaderClick(item.groupLabel); $event.stopPropagation()\">\n <span class=\"ag-group-icon\" [class.ag-group-icon--expanded]=\"!item.collapsed\">\u25B6</span>\n <span class=\"ag-group-label\">{{ item.groupLabel }}</span>\n @if (groupActions().length > 0) {\n <button class=\"ag-group-actions-btn\" [title]=\"localeText().actions\"\n (click)=\"openGroupActionsMenu($event, item.groupLabel)\">\u22EE</button>\n }\n <span class=\"ag-group-count\">{{ item.count }}</span>\n @if (getGroupDescription(item.groupLabel); as desc) {\n <span class=\"ag-group-description\">{{ desc }}</span>\n }\n </div>\n </div>\n }\n @if (isDataRowItem(item) && isRowPendingDelete(item.originalIndex)) {\n <div class=\"ag-delete-confirmation\" role=\"alertdialog\"\n [attr.aria-label]=\"localeText().confirmDeleteRow\"\n [style.left.px]=\"deleteConfirmationLeft()\"\n [style.width.px]=\"deleteConfirmationWidth() || null\"\n (pointerdown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\n <span class=\"ag-delete-confirmation-text\">{{ localeText().confirmDeleteRow }}</span>\n <button class=\"ag-delete-confirmation-btn ag-delete-confirmation-btn--yes\"\n type=\"button\" (click)=\"confirmPendingRowDelete()\">{{ localeText().confirmYes }}</button>\n <button class=\"ag-delete-confirmation-btn\" type=\"button\" data-delete-confirm-no\n (click)=\"cancelRowDelete()\">{{ localeText().confirmNo }}</button>\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"scrollableGridTemplateColumns()\"\n [style.min-width.px]=\"scrollableTotalWidth()\">\n @for (col of scrollableColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (hasRightPinnedPane()) {\n <div class=\"ag-pinned-pane ag-pinned-pane--right\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @if (hasHeaderGroups()) {\n <div class=\"ag-header-groups\" role=\"row\" aria-rowindex=\"1\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @for (run of rightHeaderGroupRuns(); track run.key) {\n <div class=\"ag-header-group-cell\" role=\"columnheader\"\n [attr.data-header-group]=\"run.id\"\n [class.ag-header-group-cell--empty]=\"!run.id\"\n [class.ag-header-group-cell--locked]=\"isHeaderGroupLocked(run.fields)\"\n [class.ag-header-group-cell--dragging]=\"isHeaderGroupDragging(run.fields)\"\n [style.grid-column]=\"'span ' + run.span\"\n (pointerdown)=\"run.id && onHeaderGroupPointerDown($event, run.fields, run.label)\">\n {{ run.label }}\n </div>\n }\n </div>\n }\n <div class=\"ag-header\" role=\"row\" [attr.aria-rowindex]=\"headerRowCount()\"\n [class.ag-header--with-filters]=\"hasFilterableColumns()\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\" [style.width.px]=\"rightPinnedPaneWidth()\">\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-header-cell ag-header-cell--pinned\" role=\"columnheader\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [attr.aria-sort]=\"getSort(col.field) === 'asc' ? 'ascending' : getSort(col.field) === 'desc' ? 'descending' : 'none'\"\n [class.ag-header-cell--filtered]=\"hasActiveFilter(col.field)\"\n [class.ag-header-cell--dragging]=\"isColDragging(col.field)\"\n [class.ag-header-cell--drop-before]=\"getColDropSide(col.field) === 'before'\"\n [class.ag-header-cell--drop-after]=\"getColDropSide(col.field) === 'after'\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-header-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\" [attr.data-col-field]=\"col.field\"\n (pointerdown)=\"onColHeaderPointerDown($event, col.field)\">\n <div class=\"ag-header-cell-top\">\n <span class=\"ag-header-cell-label\">{{ col.header }}</span>\n @if (getSort(col.field); as dir) {\n <span class=\"ag-sort-badge\">{{ dir === 'asc' ? '\u2191' : '\u2193' }}@if (hasMultiSort()) {<sup\n class=\"ag-sort-priority\">{{ getSortPriority(col.field) }}</sup>}</span>\n }\n @if (isGroupedByField(col.field)) {\n <span class=\"ag-sort-badge\">'\u229F '</span>\n }\n <button class=\"ag-header-menu-btn\" [class.ag-header-menu-btn--active]=\"hasActiveFilter(col.field)\"\n [title]=\"localeText().columnMenu\" [attr.aria-label]=\"localeText().columnMenu + ': ' + col.header\"\n [attr.aria-expanded]=\"filterMenu()?.field === col.field\" aria-haspopup=\"menu\"\n (click)=\"openFilterMenu($event, col.field)\"\n (pointerdown)=\"$event.stopPropagation()\">\u25BE</button>\n </div>\n @if (hasFilterableColumns()) {\n <div class=\"ag-header-cell-filter\">\n @if (col.filterable) {\n <input class=\"ag-filter-input\" [value]=\"getTextFilter(col.field)\"\n (input)=\"onTextFilterChange($event, col.field)\" (click)=\"$event.stopPropagation()\"\n [placeholder]=\"localeText().filterPlaceholder\"\n [attr.aria-label]=\"localeText().filterPlaceholder + ' ' + col.header\" />\n }\n </div>\n }\n <div class=\"ag-resize-handle\" role=\"separator\" [attr.tabindex]=\"col.locked ? -1 : 0\"\n aria-orientation=\"vertical\" [attr.aria-disabled]=\"col.locked ? 'true' : null\"\n [attr.aria-label]=\"localeText().resizeColumn + ': ' + col.header\"\n [attr.aria-valuenow]=\"getColumnWidth(col)\" (keydown)=\"onResizeKeyDown($event, col)\"\n (mousedown)=\"onResizeStart($event, col)\"\n (pointerdown)=\"$event.stopPropagation()\" (dblclick)=\"onAutosizeColumn($event, col)\"></div>\n </div>\n }\n </div>\n\n <cdk-virtual-scroll-viewport #rightPinnedViewport class=\"ag-body ag-pinned-body ag-right-pinned-body\"\n [itemSize]=\"rowHeight()\" [style.width.px]=\"rightPinnedPaneWidth()\" (scroll)=\"onRightPinnedBodyScroll()\">\n <div *cdkVirtualFor=\"let item of displayItems(); let di = index; trackBy: trackByItem\" role=\"row\"\n [attr.aria-rowindex]=\"di + headerRowCount() + 1\"\n [attr.aria-selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex) ? 'true' : null\"\n [class.ag-row]=\"!isGroupHeaderItem(item)\" [class.ag-add-row]=\"item === null\"\n [class.ag-ghost-row]=\"item === 'ghost'\" [class.ag-group-header-row]=\"isGroupHeaderItem(item)\"\n [class.ag-row--odd]=\"isDataRowItem(item) && dataRowIsOdd().get(item.originalIndex) === true\"\n [class.ag-row--selected]=\"isDataRowItem(item) && isRowSelected(item.originalIndex)\"\n [class.ag-row--marked]=\"isDataRowItem(item) && isRowMarked(item.originalIndex)\"\n [class.ag-row--pending-delete]=\"isDataRowItem(item) && isRowPendingDelete(item.originalIndex)\"\n [style.height.px]=\"rowHeight()\"\n [style.grid-template-columns]=\"isDataRowItem(item) || item === 'ghost' ? rightGridTemplateColumns() : null\">\n @if (isDataRowItem(item)) {\n @for (col of rightPinnedColDefs(); track col.field) {\n @let ci = getVisibleColIndex(col.field);\n <agrid-cell [col]=\"col\" [rowIndex]=\"item.originalIndex\" [colIndex]=\"ci\" [value]=\"item.row[col.field]\"\n [row]=\"item.row\" [locale]=\"locale()\" [attr.title]=\"getCellTitle(col, item.row[col.field])\"\n [attr.data-cell-row]=\"item.originalIndex\" [attr.data-cell-col]=\"ci\"\n [attr.data-col-field]=\"col.field\"\n [attr.aria-colindex]=\"getAriaColIndex(ci)\"\n [attr.aria-selected]=\"isSelected(item.originalIndex, ci) || isRangeSelected(item.originalIndex, ci)\"\n [selected]=\"isSelected(item.originalIndex, ci)\" [editing]=\"isEditing(item.originalIndex, ci)\"\n [seedChar]=\"getSeedChar(item.originalIndex, ci)\"\n [treeCell]=\"isTreeCell(col)\" [treeLevel]=\"treeRowLevel(item)\"\n [treeExpandable]=\"treeRowExpandable(item)\" [treeExpanded]=\"treeRowExpanded(item)\"\n [class]=\"getCellClass(col, item.row[col.field], item.row)\"\n [class.ag-cell--range-selected]=\"isRangeSelected(item.originalIndex, ci)\"\n [class.ag-cell--fill-preview]=\"isFillPreviewCell(item.originalIndex, ci)\"\n [class.ag-cell--fill-handle]=\"isFillHandleCell(item.originalIndex, ci)\"\n [class.ag-cell--changed]=\"isCellChanged(item.originalIndex, col.field)\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--find-match]=\"isFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--find-active]=\"isActiveFindMatchCell(item.originalIndex, ci)\"\n [class.ag-cell--pinned]=\"true\" [class.ag-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\"\n (pointerdown)=\"onCellPointerDown($event, item.originalIndex, ci)\"\n (activate)=\"onActivate(item.originalIndex, ci, $event)\" (startEdit)=\"onStartEdit(item.originalIndex, ci)\"\n (draftChange)=\"onDraftChange($event)\" (treeToggle)=\"onTreeToggle(item)\"\n (contextmenu)=\"onCellContextMenu($event, item.originalIndex, ci, col, item.row)\" />\n }\n } @else if (item === null) {\n <div class=\"ag-pinned-row-spacer\"></div>\n } @else if (item === 'ghost') {\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-ghost-cell ag-cell--pinned\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [class.ag-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\">{{ getGhostCellDisplay(col) }}</div>\n }\n } @else {\n <div class=\"ag-pinned-group-spacer\"></div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n\n @if (showFooter()) {\n <div class=\"ag-footer\" role=\"row\"\n [attr.aria-rowindex]=\"displayItems().length + headerRowCount() + 1\"\n [style.grid-template-columns]=\"rightGridTemplateColumns()\">\n @for (col of rightPinnedColDefs(); track col.field) {\n <div class=\"ag-footer-cell\" role=\"gridcell\"\n [class.ag-column-reorder-item--dragging]=\"isColDragging(col.field)\"\n [style.transform]=\"'translateX(' + getColReorderOffset(col.field) + 'px)'\"\n [attr.aria-colindex]=\"getAriaColIndex(getVisibleColIndex(col.field))\"\n [class.ag-footer-cell--pinned-first]=\"isFirstRightPinnedColumn(col.field)\">\n @if (hasAggregate(col)) {\n <span class=\"ag-footer-label\">{{ getAggregateLabel(col) }}</span>\n {{ getFooterDisplay(col, footerValues()[col.field]) }}\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n @if (loading()) {\n <div class=\"ag-state-overlay\" role=\"status\" aria-live=\"polite\">{{ localeText().loading }}</div>\n } @else if (isEmpty()) {\n <div class=\"ag-state-overlay\" role=\"status\" aria-live=\"polite\">{{ emptyTextLabel() }}</div>\n }\n\n @if (showSidebar()) {\n <agrid-sidebar\n [open]=\"sidebarOpen()\"\n [activeTab]=\"sidebarTab()\"\n [columns]=\"colDefs()\"\n [headerGroups]=\"headerGroups()\"\n [row]=\"sidebarRow()\"\n [hiddenColumns]=\"sidebarHiddenColumns()\"\n [locale]=\"locale()\"\n [localeText]=\"localeText()\"\n [readonlyGrid]=\"readonlyGrid()\"\n [useSidebarEditor]=\"useSidebarEditor()\"\n (close)=\"toggleSidebar()\"\n (tabChange)=\"onSidebarStripClick($event)\"\n (toggleColumn)=\"onSidebarToggleColumn($event)\"\n (toggleColumnGroup)=\"onSidebarToggleColumnGroup($event.fields, $event.visible)\"\n (detailEdit)=\"onSidebarDetailEdit($event)\"\n (save)=\"onSidebarDetailSave($event)\"\n />\n }\n </div><!-- /.ag-main-area -->\n\n @if (showPagination()) {\n <nav class=\"ag-pagination\" [attr.aria-label]=\"localeText().pagination\">\n <button class=\"ag-page-btn\" [attr.aria-label]=\"localeText().firstPage\"\n [disabled]=\"control()!.currentPage() <= 1\" (click)=\"goToFirstPage()\">\u00AB</button>\n <button class=\"ag-page-btn\" [attr.aria-label]=\"localeText().previous\"\n [disabled]=\"control()!.currentPage() <= 1\" (click)=\"goToPrevPage()\">\u2039</button>\n <span class=\"ag-page-info\" aria-live=\"polite\">{{ control()!.currentPage() }} / {{ totalPages() }}</span>\n <button class=\"ag-page-btn\" [disabled]=\"control()!.currentPage() >= totalPages()\"\n [attr.aria-label]=\"localeText().next\"\n (click)=\"goToNextPage()\">\u203A</button>\n <button class=\"ag-page-btn\" [disabled]=\"control()!.currentPage() >= totalPages()\"\n [attr.aria-label]=\"localeText().lastPage\"\n (click)=\"goToLastPage()\">\u00BB</button>\n <span class=\"ag-page-count\">{{ localeText().rows(filteredRowCount()) }}</span>\n </nav>\n }\n\n @if (findOpen()) {\n <agrid-find-panel [query]=\"findQuery()\" [matchCount]=\"findMatches().length\" [activeIndex]=\"findActiveIndex()\"\n [localeText]=\"localeText()\" (queryChange)=\"onFindInput($event)\" (previous)=\"goToFindMatch(-1)\"\n (next)=\"goToFindMatch(1)\" (close)=\"closeFind()\" />\n }\n\n <!-- Row context menu -->\n @if (contextMenu(); as menu) {\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"ag-context-item ag-context-item--danger\" role=\"menuitem\" (click)=\"deleteRow(menu.rowIndex)\">\n {{ localeText().deleteRow }}\n </button>\n </div>\n }\n\n <!-- Cell context menu -->\n @if (cellContextMenuState(); as menu) {\n @let col = getColDef(menu.field)!;\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"copyCellToClipboard(menu.rowIndex, col)\">{{ localeText().copyCellValue\n }}</button>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"copyRowToClipboard(menu.rowIndex)\">{{ localeText().copyRow }}</button>\n @if (allowAddRows() && !readonlyGrid()) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"insertRowAt(menu.rowIndex)\">{{ localeText().insertRowAbove }}</button>\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"insertRowAt(menu.rowIndex + 1)\">{{ localeText().insertRowBelow }}</button>\n }\n @if (!readonlyGrid()) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n <button class=\"ag-context-item ag-context-item--danger\" role=\"menuitem\"\n (click)=\"deleteRow(menu.rowIndex)\">{{ localeText().deleteRow }}</button>\n }\n @if (cellMenuItems().length) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n @for (item of cellMenuItems(); track $index) {\n @if (item === null) {\n <div class=\"ag-context-separator\" role=\"separator\"></div>\n } @else {\n <button class=\"ag-context-item\" role=\"menuitem\" [class.ag-context-item--danger]=\"item.danger\" [disabled]=\"item.disabled\"\n (click)=\"runCellMenuItem(item, menu)\">{{\n item.label }}</button>\n }\n }\n }\n </div>\n }\n\n <!-- Group actions menu -->\n @if (groupActionsMenu(); as menu) {\n <div class=\"ag-context-menu\" role=\"menu\" [style.left.px]=\"menu.x\" [style.top.px]=\"menu.y\"\n (click)=\"$event.stopPropagation()\">\n @for (action of groupActions(); track action.label) {\n <button class=\"ag-context-item\" role=\"menuitem\" (click)=\"onGroupAction(action, menu.label)\">\n {{ action.label }}\n </button>\n }\n </div>\n }\n\n <!-- Filter dropdown -->\n @if (filterMenu(); as menu) {\n <agrid-column-menu [x]=\"menu.x\" [y]=\"menu.y\" [header]=\"getColDef(menu.field)?.header ?? menu.field\"\n [sortDir]=\"getSort(menu.field)\" [sortable]=\"sortOption() !== 'none'\"\n [showColumnActions]=\"!!control()\" [pinned]=\"getColumnPinState(menu.field)\"\n [groupable]=\"!!getColDef(menu.field)?.groupable\" [grouped]=\"isGroupedByField(menu.field)\"\n [filterable]=\"!!getColDef(menu.field)?.filterable\" [showValueFilter]=\"!serverSideFiltering()\"\n [search]=\"filterMenuSearch()\"\n [allSelected]=\"isMenuAllSelected(menu.field)\"\n [valueItems]=\"serverSideFiltering() || !getColDef(menu.field)?.filterable ? [] : columnMenuValueItems()\"\n [localeText]=\"localeText()\"\n [sortPriority]=\"getSortPriority(menu.field)\" [hasMultiSort]=\"hasMultiSort()\" (sort)=\"onMenuSort(menu.field, $event)\"\n (resetSort)=\"onMenuResetSort(menu.field, $event)\" (autosize)=\"onMenuAutosizeColumn(menu.field)\"\n (togglePin)=\"onMenuTogglePin(menu.field)\" (togglePinRight)=\"onMenuTogglePinRight(menu.field)\"\n (hide)=\"onMenuHideColumn(menu.field)\" (toggleGroup)=\"onMenuToggleGroupBy(menu.field)\"\n (clearFilter)=\"onMenuClearFilter(menu.field)\" (clearAll)=\"onMenuClearAll()\"\n (searchChange)=\"onFilterMenuSearch($event)\" (toggleAll)=\"onMenuToggleAll(menu.field)\"\n (toggleValue)=\"onMenuToggleValue(menu.field, $event)\" [aggregate]=\"getEffectiveAggregate(getColDef(menu.field)!)\"\n (setAggregate)=\"onMenuSetAggregate(menu.field, $event)\" />\n }\n\n @if (columnDragPreview(); as preview) {\n <div class=\"ag-column-drag-preview\"\n [style.left.px]=\"preview.x\" [style.top.px]=\"preview.y\"\n [style.width.px]=\"preview.width\" [style.height.px]=\"preview.height\">\n <span>{{ preview.label }}</span>\n </div>\n }\n</div>\n", styles: ["@layer agrid-defaults{:host{--agrid-color-text: #24292f;--agrid-color-text-muted: #57606a;--agrid-color-accent: #1a73e8;--agrid-color-accent-subtle: #e8f0fe;--agrid-color-accent-fg: #1558b0;--agrid-color-accent-border: #c8d8f8;--agrid-color-danger: #d1242f;--agrid-color-danger-subtle: #fff1f0;--agrid-color-border: #d0d7de;--agrid-color-bg: #ffffff;--agrid-color-bg-subtle: #fafbfc;--agrid-color-bg-muted: #f6f8fa;--agrid-color-shadow: rgba(140, 149, 159, .2);--agrid-color-bg-stripe: #f0f2f5;--agrid-color-cell-changed: #f59e0b;--agrid-color-row-marked: #fff8c5}}:host{display:flex;flex-direction:column;min-height:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--agrid-color-text)}.ag-wrapper{position:relative;display:flex;flex-direction:column;flex:1;min-height:0;border:1px solid var(--agrid-color-border);overflow:hidden;outline:none;border-radius:4px}.ag-state-overlay{position:absolute;inset:34px 0 0;display:flex;align-items:center;justify-content:center;color:var(--agrid-color-text-muted);background:color-mix(in srgb,var(--agrid-color-bg) 78%,transparent);pointer-events:none;z-index:3}.ag-header{display:grid;flex-shrink:0;background:var(--agrid-color-bg-muted);border-bottom:2px solid var(--agrid-color-border)}.ag-header-groups{display:grid;flex-shrink:0;height:28px;background:color-mix(in srgb,var(--agrid-color-bg-muted) 72%,var(--agrid-color-bg));border-bottom:1px solid var(--agrid-color-border)}.ag-header-group-cell{display:flex;align-items:center;justify-content:center;min-width:0;padding:0 8px;overflow:hidden;border-right:1px solid var(--agrid-color-border);box-sizing:border-box;color:var(--agrid-color-text);font-size:12px;font-weight:600;text-overflow:ellipsis;white-space:nowrap;cursor:grab;-webkit-user-select:none;user-select:none;transition:opacity .1s ease}.ag-header-group-cell:last-child{border-right:none}.ag-header-group-cell--empty,.ag-header-group-cell--locked{cursor:default}.ag-header-group-cell--dragging{opacity:.12}.ag-header-cell{position:relative;display:flex;align-items:center;font-weight:600;border-right:1px solid var(--agrid-color-border);overflow:hidden;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box}.ag-header-cell:last-child{border-right:none}.ag-header-cell-top{display:flex;align-items:center;flex:1;min-width:0;padding:0 6px;height:32px;overflow:hidden;white-space:nowrap}.ag-header-cell-label{overflow:hidden;text-overflow:ellipsis;flex:1}.ag-header--with-filters .ag-header-cell{flex-direction:column;align-items:stretch;height:auto;white-space:normal}.ag-header--with-filters .ag-header-cell-top{flex:0 0 32px}.ag-header-cell-filter{height:28px;display:flex;align-items:center;padding:0 2px;border-top:1px solid var(--agrid-color-border);background:var(--agrid-color-bg)}.ag-header-cell{cursor:grab;transition:transform .16s cubic-bezier(.2,0,0,1),opacity .1s ease;will-change:transform}.ag-row>agrid-cell,.ag-ghost-cell,.ag-footer-cell{transition:transform .16s cubic-bezier(.2,0,0,1),opacity .1s ease;will-change:transform}.ag-header-cell--dragging{opacity:.12;cursor:grabbing}.ag-column-reorder-item--dragging{opacity:.12}.ag-header-cell--drop-before,.ag-header-cell--drop-after{z-index:1}.ag-column-drag-preview{position:fixed;z-index:1000;display:flex;align-items:flex-start;padding:8px 10px;border:1px solid var(--agrid-color-accent);border-radius:5px;color:var(--agrid-color-text);background:color-mix(in srgb,var(--agrid-color-bg) 94%,var(--agrid-color-accent));box-shadow:0 10px 28px var(--agrid-color-shadow);font-weight:600;line-height:16px;box-sizing:border-box;pointer-events:none;opacity:.96}.ag-sort-badge{font-size:11px;color:var(--agrid-color-accent);flex-shrink:0;line-height:1}.ag-sort-priority{font-size:9px;vertical-align:super;opacity:.75}.ag-resize-handle{position:absolute;top:0;right:0;width:5px;height:100%;cursor:col-resize;z-index:1}.ag-resize-handle:hover{background:var(--agrid-color-accent);opacity:.5}.ag-filter-input{flex:1;min-width:0;height:20px;border:1px solid var(--agrid-color-border);border-radius:3px;outline:none;font:inherit;font-size:12px;padding:0 4px;background:var(--agrid-color-bg)}.ag-filter-input:focus{border-color:var(--agrid-color-accent)}.ag-header-cell--filtered .ag-header-cell-label:after{content:\" \\25be\";font-size:9px;color:var(--agrid-color-accent)}.ag-main-area{display:flex;flex:1;min-height:0;overflow:hidden}.ag-grid-split{display:flex;flex:1;min-width:0;min-height:0;overflow:hidden}.ag-pinned-pane{flex-shrink:0;min-height:0;display:flex;flex-direction:column;overflow:hidden;border-right:1px solid var(--agrid-color-border);background:var(--agrid-color-bg)}.ag-scroll-pane{flex:1;min-width:0;min-height:0;display:flex}.ag-horizontal-scroll{flex:1;min-width:0;min-height:0;overflow-x:auto;overflow-y:hidden;display:flex;flex-direction:column}.ag-body{flex:1;overflow-x:clip;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-horizontal-scroll{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.18) transparent}.ag-body::-webkit-scrollbar,.ag-horizontal-scroll::-webkit-scrollbar{width:8px;height:8px}.ag-body::-webkit-scrollbar-track,.ag-horizontal-scroll::-webkit-scrollbar-track{background:transparent}.ag-body::-webkit-scrollbar-thumb,.ag-horizontal-scroll::-webkit-scrollbar-thumb{background:#0000002e;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-body::-webkit-scrollbar-thumb:hover,.ag-horizontal-scroll::-webkit-scrollbar-thumb:hover{background:#00000052;border-radius:10px;border:2px solid transparent;background-clip:padding-box}.ag-pinned-body{overflow:hidden}.ag-right-pinned-body{overflow-y:auto}.ag-has-right-pane .ag-body:not(.ag-pinned-body){scrollbar-width:none}.ag-has-right-pane .ag-body:not(.ag-pinned-body)::-webkit-scrollbar{display:none}.ag-row{display:grid;position:relative}.ag-row--pending-delete>:not(.ag-delete-confirmation){opacity:.2;pointer-events:none;transition:opacity .14s ease}.ag-delete-confirmation{position:absolute;top:0;bottom:0;z-index:7;display:flex;align-items:center;justify-content:center;gap:8px;min-width:min(100%,320px);padding:2px 12px;box-sizing:border-box;color:var(--agrid-color-text);background:color-mix(in srgb,var(--agrid-color-danger-subtle) 88%,transparent);border-block:1px solid color-mix(in srgb,var(--agrid-color-danger) 35%,transparent)}.ag-delete-confirmation-text{font-weight:600;white-space:nowrap}.ag-delete-confirmation-btn{min-width:42px;padding:3px 9px;border:1px solid var(--agrid-color-border);border-radius:4px;color:var(--agrid-color-text);background:var(--agrid-color-bg);font:inherit;cursor:pointer}.ag-delete-confirmation-btn:hover,.ag-delete-confirmation-btn:focus-visible{border-color:var(--agrid-color-accent);outline:none}.ag-delete-confirmation-btn--yes{color:#fff;border-color:var(--agrid-color-danger);background:var(--agrid-color-danger)}.ag-delete-confirmation-btn--yes:hover,.ag-delete-confirmation-btn--yes:focus-visible{border-color:color-mix(in srgb,var(--agrid-color-danger) 75%,#000);background:color-mix(in srgb,var(--agrid-color-danger) 85%,#000)}:host(.ag-zebra) .ag-row--odd agrid-cell:not(.editing){background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd .ag-cell--pinned{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd .ag-control-cell{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd:hover agrid-cell:not(.editing){background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd:hover .ag-cell--pinned,:host(.ag-zebra) .ag-row--odd:hover .ag-control-cell{background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd.ag-row--selected agrid-cell:not(.editing){background:var(--agrid-color-accent-subtle)}:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-cell--pinned,:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-control-cell{background:var(--agrid-color-accent-subtle)}:host(.ag-zebra) .ag-row--odd .ag-cell--pinned-first{background:var(--agrid-color-bg-stripe)}:host(.ag-zebra) .ag-row--odd:hover .ag-cell--pinned-first{background:var(--agrid-color-bg-muted)}:host(.ag-zebra) .ag-row--odd.ag-row--selected .ag-cell--pinned-first{background:var(--agrid-color-accent-subtle)}.ag-row:hover agrid-cell:not(.editing){background:var(--agrid-color-bg-muted)}.ag-row--selected agrid-cell:not(.editing){background:var(--agrid-color-accent-subtle)}.ag-row--marked agrid-cell:not(.editing),.ag-row--marked .ag-control-cell{background:var(--agrid-color-row-marked)}.ag-row--marked{box-shadow:inset 3px 0 #bf8700}.ag-row--selected.ag-row--marked{box-shadow:inset 3px 0 0 var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--range-selected:not(.editing){background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1px var(--agrid-color-accent-border)}.ag-row agrid-cell.ag-cell--find-match:not(.editing){background:#fff7cc}.ag-row agrid-cell.ag-cell--find-active:not(.editing){background:#ffe58a;box-shadow:inset 0 0 0 2px #b7791f}.ag-row agrid-cell.ag-cell--range-selected.selected:not(.editing){box-shadow:inset 0 0 0 2px var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--fill-preview:not(.editing){background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1px var(--agrid-color-accent)}.ag-row agrid-cell.ag-cell--fill-handle:not(.editing){position:relative}.ag-row agrid-cell.ag-cell--fill-handle:not(.editing):after{content:\"\";position:absolute;right:1px;bottom:1px;width:6px;height:6px;background:var(--agrid-color-accent);border:1px solid var(--agrid-color-bg);box-sizing:border-box;cursor:crosshair;z-index:4}.ag-row--selected .ag-control-cell{background:var(--agrid-color-accent-subtle)}.ag-row--selected{box-shadow:inset 3px 0 0 var(--agrid-color-accent)}.ag-control-header{z-index:3;border-right:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted)}.ag-control-header .ag-header-cell-filter{background:var(--agrid-color-bg-subtle)}.ag-control-cell{z-index:2;border-right:1px solid var(--agrid-color-border);border-bottom:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-subtle);cursor:context-menu;display:flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;flex-direction:row-reverse}.ag-control-cell:after{content:\"\\22ee\";font-size:11px;color:var(--agrid-color-border);line-height:1}.ag-control-cell:hover:after{color:var(--agrid-color-text-muted)}.ag-control-cell--reorder{cursor:grab}.ag-control-cell--reorder:after{content:\"\\283f\";font-size:13px;color:var(--agrid-color-text)}.ag-control-cell--reorder:hover:after{color:var(--agrid-color-text-muted)}.ag-control-cell--reorder:active{cursor:grabbing}.ag-row-marker{position:relative;z-index:1;width:14px;height:14px;margin:0;accent-color:var(--agrid-color-accent);cursor:pointer}.ag-ghost-row{background:var(--agrid-color-accent-subtle);box-shadow:inset 0 0 0 1.5px var(--agrid-color-accent);pointer-events:none;animation:ag-ghost-in .1s ease}@keyframes ag-ghost-in{0%{opacity:0}to{opacity:1}}.ag-ghost-handle:after{color:var(--agrid-color-accent)!important}.ag-ghost-cell{display:flex;align-items:center;padding:0 6px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;border-right:1px solid var(--agrid-color-accent-border);color:var(--agrid-color-accent-fg);font-size:13px;box-sizing:border-box;-webkit-user-select:none;user-select:none}.ag-ghost-cell:last-child{border-right:none}.ag-pinned-row-spacer,.ag-pinned-group-spacer{height:100%;border-bottom:1px solid var(--agrid-color-border);box-sizing:border-box}.ag-pinned-group-spacer{background:var(--agrid-color-bg-muted)}.ag-context-menu{position:fixed;z-index:1000;background:var(--agrid-color-bg-subtle);border:1px solid var(--agrid-color-border);border-radius:6px;box-shadow:0 8px 24px var(--agrid-color-shadow);min-width:160px;padding:4px 0;font-size:13px}.ag-context-item{display:block;width:100%;padding:6px 16px;text-align:left;background:none;border:none;cursor:pointer;color:var(--agrid-color-text);font:inherit}.ag-context-item:hover{background:var(--agrid-color-bg-muted)}.ag-context-separator{height:1px;background:var(--agrid-color-border);margin:3px 0}.ag-context-item--danger{color:var(--agrid-color-danger)}.ag-context-item--danger:hover{background:var(--agrid-color-danger-subtle)}.ag-group-header-row{display:flex;align-items:stretch;background:var(--agrid-color-bg-muted);border-bottom:1px solid var(--agrid-color-border);overflow:hidden}.ag-group-header-content{display:flex;align-items:stretch;height:100%;width:100%;-webkit-user-select:none;user-select:none}.ag-group-header-main{display:flex;align-items:center;gap:6px;padding:0 10px;flex:1;min-width:0;cursor:pointer}.ag-group-header-main:hover{background:var(--agrid-color-bg-subtle)}.ag-group-description{font-size:11px;color:var(--agrid-color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ag-group-actions-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:none;border-radius:3px;cursor:pointer;color:var(--agrid-color-text-muted);font-size:14px;padding:0}.ag-group-actions-btn:hover{background:var(--agrid-color-bg-muted);color:var(--agrid-color-text)}.ag-group-icon{font-size:9px;color:var(--agrid-color-text-muted);line-height:1;display:inline-block;transition:transform .15s ease}.ag-group-icon--expanded{transform:rotate(90deg)}.ag-group-label{font-weight:600;font-size:12px;color:var(--agrid-color-text)}.ag-group-count{font-size:11px;color:var(--agrid-color-text-muted);background:var(--agrid-color-bg);border:1px solid var(--agrid-color-border);border-radius:10px;padding:0 7px;line-height:16px}.ag-footer{display:grid;flex-shrink:0;background:var(--agrid-color-bg-muted);border-top:2px solid var(--agrid-color-border)}.ag-footer-cell{display:flex;align-items:center;gap:4px;padding:0 6px;height:30px;border-right:1px solid var(--agrid-color-border);box-sizing:border-box;overflow:hidden;white-space:nowrap;font-weight:600;font-size:12px;color:var(--agrid-color-text)}.ag-footer-cell:last-child{border-right:none}.ag-footer-cell--control{background:var(--agrid-color-bg-subtle);border-right:1px solid var(--agrid-color-border)}.ag-footer-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-footer-label{font-size:10px;font-weight:400;color:var(--agrid-color-text-muted);flex-shrink:0}.ag-pagination{display:flex;align-items:center;gap:4px;padding:0 10px;height:34px;flex-shrink:0;border-top:1px solid var(--agrid-color-border);background:var(--agrid-color-bg-muted);font-size:12px;color:var(--agrid-color-text-muted)}.ag-page-btn{display:flex;align-items:center;justify-content:center;width:24px;height:22px;border:1px solid var(--agrid-color-border);border-radius:3px;background:var(--agrid-color-bg);color:var(--agrid-color-text);font-size:13px;cursor:pointer;padding:0;line-height:1}.ag-page-btn:hover:not(:disabled){background:var(--agrid-color-bg-muted);border-color:var(--agrid-color-text-muted)}.ag-page-btn:disabled{opacity:.35;cursor:default}.ag-page-info{padding:0 6px;font-weight:500;color:var(--agrid-color-text);min-width:48px;text-align:center}.ag-page-count{margin-left:auto;color:var(--agrid-color-text-muted)}.ag-add-row{border-bottom:1px dashed var(--agrid-color-border);color:var(--agrid-color-text-muted);cursor:pointer}.ag-add-row:hover .ag-add-row-label{background:var(--agrid-color-bg-muted)}.ag-add-row--selected .ag-add-row-label{outline:2px solid var(--agrid-color-accent);outline-offset:-2px}.ag-add-row-label{display:flex;align-items:center;gap:4px;height:100%;padding:0 6px;font-size:12px;-webkit-user-select:none;user-select:none}.ag-add-row-icon{font-size:16px;line-height:1;color:var(--agrid-color-text-muted)}.ag-pinned-pane--right{border-left:1px solid var(--agrid-color-border);border-right:none;box-shadow:-3px 0 6px -2px var(--agrid-color-shadow)}.ag-header-cell--pinned{background:var(--agrid-color-bg-muted)}.ag-header-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-header-cell--pinned-first{box-shadow:none}.ag-cell--pinned{background:var(--agrid-color-bg)}.ag-cell--pinned-last{box-shadow:inset -1px 0 0 var(--agrid-color-border),3px 0 6px -2px var(--agrid-color-shadow)}.ag-cell--pinned-first{box-shadow:none}.ag-row:hover .ag-cell--pinned{background:var(--agrid-color-bg-muted)}.ag-row--selected .ag-cell--pinned,.ag-row .ag-cell--pinned.ag-cell--range-selected,.ag-row .ag-cell--pinned.ag-cell--fill-preview{background:var(--agrid-color-accent-subtle)}.ag-row .ag-cell--pinned.ag-cell--find-match{background:#fff7cc}.ag-row .ag-cell--pinned.ag-cell--find-active{background:#ffe58a}.ag-header-menu-btn{flex-shrink:0;width:16px;height:16px;padding:0;margin-right:2px;background:none;border:1px solid transparent;border-radius:3px;cursor:pointer;font-size:10px;color:var(--agrid-color-text-muted);display:flex;align-items:center;justify-content:center;opacity:1;transition:opacity .12s;line-height:1}.ag-header-menu-btn--active{color:var(--agrid-color-accent);border-color:var(--agrid-color-accent-border);background:var(--agrid-color-accent-subtle)}.ag-header-menu-btn:hover{background:var(--agrid-color-bg);border-color:var(--agrid-color-border)}\n"] }]
|
|
5254
5577
|
}], ctorParameters: () => [], propDecorators: { provider: [{ type: i0.Input, args: [{ isSignal: true, alias: "provider", required: false }] }], cellEdit: [{ type: i0.Output, args: ["cellEdit"] }], recordEdit: [{ type: i0.Output, args: ["recordEdit"] }], rowRemoved: [{ type: i0.Output, args: ["rowRemoved"] }], prepareAddRecord: [{ type: i0.Output, args: ["prepareAddRecord"] }], rowReorder: [{ type: i0.Output, args: ["rowReorder"] }], rowSelect: [{ type: i0.Output, args: ["rowSelect"] }], rowDoubleClicked: [{ type: i0.Output, args: ["rowDoubleClicked"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], rowChanged: [{ type: i0.Output, args: ["rowChanged"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], viewport: [{ type: i0.ViewChild, args: ['scrollViewport', { isSignal: true }] }], pinnedViewport: [{ type: i0.ViewChild, args: ['pinnedViewport', { isSignal: true }] }], rightPinnedViewport: [{ type: i0.ViewChild, args: ['rightPinnedViewport', { isSignal: true }] }], wrapperEl: [{ type: i0.ViewChild, args: ['wrapper', { isSignal: true }] }], horizontalScrollerEl: [{ type: i0.ViewChild, args: ['horizontalScroller', { isSignal: true }] }] } });
|
|
5255
5578
|
|
|
5256
5579
|
/** Width sentinel that makes a column fill the remaining horizontal space. */
|