@skyux/ag-grid 12.5.0 → 12.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,16 @@
1
- import { DOCUMENT, AsyncPipe, NgClass, NgStyle, CommonModule, NgTemplateOutlet } from '@angular/common';
1
+ import { DOCUMENT, AsyncPipe, NgClass, CommonModule, NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { NgModule, Injectable, input, numberAttribute, computed, inject, ChangeDetectorRef, ElementRef, booleanAttribute, Input, HostBinding, ContentChild, ChangeDetectionStrategy, Component, contentChildren, effect, Directive, viewChildren, viewChild, output, contentChild, linkedSignal, EnvironmentInjector, ViewContainerRef, HostListener, ViewChild, ViewEncapsulation, signal, Optional } from '@angular/core';
3
+ import { NgModule, Injectable, input, numberAttribute, computed, inject, ChangeDetectorRef, ElementRef, booleanAttribute, Input, HostBinding, ContentChild, ChangeDetectionStrategy, Component, contentChildren, effect, Directive, InjectionToken, signal, model, output, contentChild, linkedSignal, EnvironmentInjector, HostListener, ViewChild, ViewEncapsulation, Optional } from '@angular/core';
4
4
  import { AgGridAngular } from 'ag-grid-angular';
5
5
  import * as i3 from '@skyux/i18n';
6
6
  import { SkyLibResourcesService, SkyI18nModule } from '@skyux/i18n';
7
- import { toSignal, toObservable } from '@angular/core/rxjs-interop';
7
+ import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
8
  import * as i1 from '@skyux/core';
9
- import { SkyMutationObserverService, SkyViewkeeperModule, SkyMediaQueryService, SkyAffixService, SkyDynamicComponentService, SkyOverlayService, SkyScrollableHostService, SKY_STACKING_CONTEXT, SkyAffixAutoFitContext, SkyIdModule, SkyNumericModule, SkyDynamicComponentLocation, SkyLogService } from '@skyux/core';
10
- import { Subject, BehaviorSubject, ReplaySubject, takeUntil, combineLatest, of, distinctUntilChanged, take, filter as filter$1, switchMap, merge, delay, tap, observeOn, asapScheduler, sample, animationFrames, map, fromEvent, Subscription, fromEventPattern, isObservable } from 'rxjs';
9
+ import { SkyMutationObserverService, SkyViewkeeperModule, SkyMediaQueryService, SkyResizeObserverService, SkyAffixModule, SkyOverlayService, SkyScrollableHostService, SKY_STACKING_CONTEXT, SkyIdModule, SkyNumericModule, SkyDynamicComponentService, SkyDynamicComponentLocation, SkyLogService } from '@skyux/core';
10
+ import { Subject, BehaviorSubject, ReplaySubject, takeUntil, combineLatest, of, distinctUntilChanged, take, Subscription, switchMap, merge, fromEvent, startWith, map, scan, filter as filter$1, fromEventPattern, isObservable } from 'rxjs';
11
11
  import { takeUntil as takeUntil$1, filter, first } from 'rxjs/operators';
12
12
  import * as i2$4 from '@skyux/theme';
13
- import { SkyThemeService, SkyThemeComponentClassDirective, SkyThemeModule } from '@skyux/theme';
13
+ import { SkyThemeService, SkyThemeModule } from '@skyux/theme';
14
14
  import { themeQuartz, colorSchemeLight, iconSetQuartz, colorSchemeDark, KeyCode, PopupComponent } from 'ag-grid-community';
15
15
  import * as i1$1 from '@skyux/data-manager';
16
16
  import * as i1$2 from '@skyux/layout';
@@ -1083,108 +1083,118 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
1083
1083
  type: Input
1084
1084
  }] } });
1085
1085
 
1086
+ /**
1087
+ * @internal
1088
+ */
1089
+ const SKY_AG_GRID_ROW_DELETE_CONTEXT = new InjectionToken('SkyAgGridRowDeleteContext');
1090
+ /**
1091
+ * Used to provide dependencies to the `SkyAgGridRowDeleteComponent` overlay.
1092
+ * @internal
1093
+ */
1094
+ class SkyAgGridRowDeleteContext {
1095
+ constructor(rows, gridElement, gridApi) {
1096
+ this.rows = rows;
1097
+ this.gridElement = gridElement;
1098
+ this.gridApi = gridApi;
1099
+ this.cancelRowDelete = new Subject();
1100
+ this.confirmRowDelete = new Subject();
1101
+ this.subscription = new Subscription();
1102
+ this.subscription.add(() => {
1103
+ this.cancelRowDelete.complete();
1104
+ this.confirmRowDelete.complete();
1105
+ });
1106
+ }
1107
+ }
1108
+
1086
1109
  /**
1087
1110
  * Component for rendering the inline delete template in the overlay.
1088
1111
  * @internal
1089
1112
  */
1090
1113
  class SkyAgGridRowDeleteComponent {
1114
+ #resizeObserverSvc;
1091
1115
  constructor() {
1092
- this.inlineDeleteRefs = viewChildren('inlineDeleteRef');
1093
- this.inlineDeleteTemplateRef = viewChild('inlineDeleteTemplateRef');
1116
+ this.service = inject(SKY_AG_GRID_ROW_DELETE_CONTEXT);
1117
+ this.tableWidthStyle = computed(() => {
1118
+ const tableWidth = this.tableWidth();
1119
+ if (tableWidth > 0) {
1120
+ return `${tableWidth}px`;
1121
+ }
1122
+ return 'auto';
1123
+ });
1124
+ this.rowsWithElements = computed(() => {
1125
+ const rows = this.service.rows();
1126
+ const gridElement = this.service.gridElement();
1127
+ const gridApi = this.service.gridApi();
1128
+ const increment = this.gridChanges();
1129
+ if (!gridElement || !gridApi) {
1130
+ return [];
1131
+ }
1132
+ return rows
1133
+ .filter((rowId) => !!rowId && !!gridApi.getRowNode(rowId))
1134
+ .map((rowId) => {
1135
+ const element = gridElement[0]?.nativeElement
1136
+ .querySelector(`
1137
+ [row-id="${rowId}"] div[aria-colindex],
1138
+ .ag-row.sky-ag-grid-row-${rowId} div[aria-colindex]
1139
+ `);
1140
+ return { rowId, element, increment: `${rowId}-${increment}` };
1141
+ });
1142
+ });
1143
+ this.pending = signal([]);
1144
+ this.tableWidth = signal(0);
1145
+ // Force redrawing overlays when the grid changes by incrementing a number.
1146
+ this.gridChanges = toSignal(toObservable(this.service.gridApi).pipe(switchMap((gridApi) => gridApi
1147
+ ? merge(fromEvent(gridApi, 'componentStateChanged'), fromEvent(gridApi, 'firstDataRendered'), fromEvent(gridApi, 'gridSizeChanged'), fromEvent(gridApi, 'modelUpdated'), fromEvent(gridApi, 'rowDataUpdated')).pipe(takeUntil(fromEvent(gridApi, 'gridPreDestroyed')))
1148
+ : of(undefined)), startWith(1), map(() => 1), scan((acc, val) => acc + val)), { initialValue: 0 });
1149
+ this.#resizeObserverSvc = inject(SkyResizeObserverService);
1150
+ // Maintain table width when the grid is resized.
1151
+ toObservable(this.service.gridElement)
1152
+ .pipe(filter$1((el) => Array.isArray(el) && !!el[0]), switchMap((gridElement) => this.#resizeObserverSvc
1153
+ .observe(gridElement[0])
1154
+ .pipe(map(() => gridElement[0].nativeElement.offsetWidth))), takeUntilDestroyed())
1155
+ .subscribe((tableWidth) => {
1156
+ this.tableWidth.set(tableWidth);
1157
+ });
1158
+ // Clean up pending rows when the grid data is updated.
1159
+ toObservable(this.service.gridApi)
1160
+ .pipe(filter$1((gridApi) => !!gridApi), switchMap((gridApi) => fromEvent(gridApi, 'rowDataUpdated').pipe(takeUntil(fromEvent(gridApi, 'gridPreDestroyed')), map(() => gridApi))), takeUntilDestroyed())
1161
+ .subscribe((gridApi) => {
1162
+ this.pending.update((pending) => pending.filter((rowId) => !!gridApi.getRowNode(rowId)));
1163
+ });
1164
+ }
1165
+ cancelDelete(rowId) {
1166
+ this.service.cancelRowDelete.next(rowId);
1167
+ }
1168
+ confirmDelete(rowId) {
1169
+ this.pending.update((pending) => pending.concat(rowId));
1170
+ this.service.confirmRowDelete.next(rowId);
1094
1171
  }
1095
1172
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SkyAgGridRowDeleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1096
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.7", type: SkyAgGridRowDeleteComponent, isStandalone: true, selector: "sky-ag-grid-row-delete", viewQueries: [{ propertyName: "inlineDeleteRefs", predicate: ["inlineDeleteRef"], descendants: true, isSignal: true }, { propertyName: "inlineDeleteTemplateRef", first: true, predicate: ["inlineDeleteTemplateRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
1097
- <ng-template
1098
- #inlineDeleteTemplateRef
1099
- let-row
1100
- let-tableWidth="tableWidth()"
1101
- let-getRowDeleteItem="getRowDeleteItem"
1102
- let-cancelRowDelete="cancelRowDelete"
1103
- let-confirmRowDelete="confirmRowDelete"
1104
- >
1105
- <div
1106
- #inlineDeleteRef
1107
- class="sky-ag-grid-row-delete"
1108
- [id]="'row-delete-ref-' + row.id"
1109
- [ngStyle]="{
1110
- height: row.rowHeight + 'px',
1111
- position: 'fixed',
1112
- top: '-100vh',
1113
- width: tableWidth + 'px',
1114
- }"
1115
- >
1116
- <sky-inline-delete
1117
- [pending]="getRowDeleteItem(row).pending"
1118
- (cancelTriggered)="cancelRowDelete(row)"
1119
- (deleteTriggered)="confirmRowDelete(row)"
1120
- />
1121
- </div>
1122
- </ng-template>
1123
- `, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: SkyInlineDeleteModule }, { kind: "component", type: i1$2.λ8, selector: "sky-inline-delete", inputs: ["pending"], outputs: ["cancelTriggered", "deleteTriggered"] }] }); }
1173
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: SkyAgGridRowDeleteComponent, isStandalone: true, selector: "sky-ag-grid-row-delete", host: { properties: { "style": "\"--table-width: \" + tableWidthStyle()" } }, ngImport: i0, template: "@for (row of rowsWithElements(); track row.increment) {\n @if (row.element?.offsetParent && row.element; as element) {\n <div\n class=\"sky-ag-grid-row-delete\"\n affixPlacement=\"above\"\n affixVerticalAlignment=\"top\"\n affixHorizontalAlignment=\"left\"\n [id]=\"'row-delete-ref-' + row.rowId\"\n [style.height]=\"element.offsetHeight + 'px'\"\n [skyAffixTo]=\"element\"\n [affixIsSticky]=\"true\"\n >\n <sky-inline-delete\n [pending]=\"pending().includes(row.rowId ?? '')\"\n (cancelTriggered)=\"cancelDelete(row.rowId)\"\n (deleteTriggered)=\"confirmDelete(row.rowId)\"\n />\n </div>\n }\n}\n", styles: [":host{display:block}.sky-ag-grid-row-delete{position:fixed;top:-100vh;width:var(--table-width, 100%)}\n"], dependencies: [{ kind: "ngmodule", type: SkyInlineDeleteModule }, { kind: "component", type: i1$2.λ8, selector: "sky-inline-delete", inputs: ["pending"], outputs: ["cancelTriggered", "deleteTriggered"] }, { kind: "ngmodule", type: SkyAffixModule }, { kind: "directive", type: i1.λ1, selector: "[skyAffixTo]", inputs: ["skyAffixTo", "affixAutoFitContext", "affixAutoFitOverflowOffset", "affixEnableAutoFit", "affixHorizontalAlignment", "affixIsSticky", "affixPlacement", "affixPosition", "affixVerticalAlignment"], outputs: ["affixOffsetChange", "affixOverflowScroll", "affixPlacementChange"] }] }); }
1124
1174
  }
1125
1175
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SkyAgGridRowDeleteComponent, decorators: [{
1126
1176
  type: Component,
1127
- args: [{
1128
- selector: 'sky-ag-grid-row-delete',
1129
- template: `
1130
- <ng-template
1131
- #inlineDeleteTemplateRef
1132
- let-row
1133
- let-tableWidth="tableWidth()"
1134
- let-getRowDeleteItem="getRowDeleteItem"
1135
- let-cancelRowDelete="cancelRowDelete"
1136
- let-confirmRowDelete="confirmRowDelete"
1137
- >
1138
- <div
1139
- #inlineDeleteRef
1140
- class="sky-ag-grid-row-delete"
1141
- [id]="'row-delete-ref-' + row.id"
1142
- [ngStyle]="{
1143
- height: row.rowHeight + 'px',
1144
- position: 'fixed',
1145
- top: '-100vh',
1146
- width: tableWidth + 'px',
1147
- }"
1148
- >
1149
- <sky-inline-delete
1150
- [pending]="getRowDeleteItem(row).pending"
1151
- (cancelTriggered)="cancelRowDelete(row)"
1152
- (deleteTriggered)="confirmRowDelete(row)"
1153
- />
1154
- </div>
1155
- </ng-template>
1156
- `,
1157
- imports: [NgStyle, SkyInlineDeleteModule],
1158
- }]
1159
- }] });
1177
+ args: [{ selector: 'sky-ag-grid-row-delete', imports: [SkyInlineDeleteModule, SkyAffixModule], host: {
1178
+ '[style]': '"--table-width: " + tableWidthStyle()',
1179
+ }, template: "@for (row of rowsWithElements(); track row.increment) {\n @if (row.element?.offsetParent && row.element; as element) {\n <div\n class=\"sky-ag-grid-row-delete\"\n affixPlacement=\"above\"\n affixVerticalAlignment=\"top\"\n affixHorizontalAlignment=\"left\"\n [id]=\"'row-delete-ref-' + row.rowId\"\n [style.height]=\"element.offsetHeight + 'px'\"\n [skyAffixTo]=\"element\"\n [affixIsSticky]=\"true\"\n >\n <sky-inline-delete\n [pending]=\"pending().includes(row.rowId ?? '')\"\n (cancelTriggered)=\"cancelDelete(row.rowId)\"\n (deleteTriggered)=\"confirmDelete(row.rowId)\"\n />\n </div>\n }\n}\n", styles: [":host{display:block}.sky-ag-grid-row-delete{position:fixed;top:-100vh;width:var(--table-width, 100%)}\n"] }]
1180
+ }], ctorParameters: () => [] });
1160
1181
 
1161
1182
  class SkyAgGridRowDeleteDirective {
1162
1183
  #ngUnsubscribe;
1163
- #rowDeleteComponent;
1164
- #rowDeleteConfigs;
1165
- #rowDeleteContents;
1166
- #rowDeleteContentsQueue;
1167
- #rowDeleteContentsQueued;
1168
1184
  #rowDeleteIdsInternal;
1169
1185
  #clipPath;
1170
1186
  #zIndex;
1171
- #affixService;
1172
- #dynamicComponentSvc;
1173
1187
  #elementRef;
1174
1188
  #environmentInjector;
1175
1189
  #overlayService;
1190
+ #rowDeleteSvc;
1176
1191
  #scrollableHostService;
1177
1192
  #stackingContext;
1178
- #viewContainerRef;
1179
- #viewUpdate;
1180
1193
  constructor() {
1181
1194
  /**
1182
1195
  * The IDs of the data in the rows where the inline delete appears.
1183
1196
  */
1184
- this.rowDeleteIds = input([], {
1185
- transform: (value) => (Array.isArray(value) ? value.map(String) : []),
1186
- });
1187
- this.rowDeleteIdsChange = output();
1197
+ this.rowDeleteIds = model([]);
1188
1198
  /**
1189
1199
  * Emits a `SkyAgGridRowDeleteCancelArgs` object when a row's inline delete is cancelled.
1190
1200
  */
@@ -1194,11 +1204,8 @@ class SkyAgGridRowDeleteDirective {
1194
1204
  */
1195
1205
  this.rowDeleteConfirm = output();
1196
1206
  this.agGrid = contentChild(AgGridAngular);
1207
+ this.agGridBodyViewport = new BehaviorSubject([]);
1197
1208
  this.#ngUnsubscribe = new Subject();
1198
- this.#rowDeleteConfigs = [];
1199
- this.#rowDeleteContents = [];
1200
- this.#rowDeleteContentsQueue = [];
1201
- this.#rowDeleteContentsQueued = new Subject();
1202
1209
  this.#rowDeleteIdsInternal = linkedSignal({
1203
1210
  source: this.rowDeleteIds,
1204
1211
  computation: (value) => [...new Set(value)]
@@ -1209,15 +1216,11 @@ class SkyAgGridRowDeleteDirective {
1209
1216
  });
1210
1217
  this.#clipPath = new BehaviorSubject(undefined);
1211
1218
  this.#zIndex = new BehaviorSubject(998);
1212
- this.#affixService = inject(SkyAffixService);
1213
- this.#dynamicComponentSvc = inject(SkyDynamicComponentService);
1214
1219
  this.#elementRef = inject((ElementRef));
1215
1220
  this.#environmentInjector = inject(EnvironmentInjector);
1216
1221
  this.#overlayService = inject(SkyOverlayService);
1217
1222
  this.#scrollableHostService = inject(SkyScrollableHostService);
1218
1223
  this.#stackingContext = inject(SKY_STACKING_CONTEXT, { optional: true });
1219
- this.#viewContainerRef = inject(ViewContainerRef);
1220
- this.#viewUpdate = new Subject();
1221
1224
  if (this.#stackingContext) {
1222
1225
  this.#stackingContext.zIndex
1223
1226
  .pipe(takeUntil(this.#ngUnsubscribe))
@@ -1225,198 +1228,85 @@ class SkyAgGridRowDeleteDirective {
1225
1228
  this.#zIndex.next(zIndex);
1226
1229
  });
1227
1230
  }
1228
- const rowDeleteIds = toObservable(this.#rowDeleteIdsInternal);
1229
- toObservable(this.agGrid)
1230
- .pipe(takeUntil(this.#ngUnsubscribe), filter$1((agGrid) => !!agGrid), switchMap((agGrid) => merge(agGrid.componentStateChanged, agGrid.filterChanged, agGrid.firstDataRendered, agGrid.gridReady, agGrid.gridSizeChanged.pipe(delay(500)), agGrid.rowDataUpdated.pipe(takeUntil(this.#ngUnsubscribe), tap((evt) => {
1231
- const ids = this.#rowDeleteIdsInternal();
1232
- this.#rowDeleteIdsInternal.set(ids.filter((id) => evt.api.getRowNode(id)));
1233
- })), agGrid.sortChanged, this.#viewUpdate.pipe(delay(200)), rowDeleteIds.pipe(takeUntil(this.#ngUnsubscribe), tap((value) => {
1234
- this.#rowDeleteConfigs = this.#rowDeleteConfigs.filter((config) => value.includes(config.id));
1235
- for (const id of value) {
1236
- if (!this.#rowDeleteConfigs.some((config) => config.id === id)) {
1237
- this.#rowDeleteConfigs.push({
1238
- id,
1239
- pending: false,
1240
- });
1241
- }
1231
+ this.#rowDeleteSvc = new SkyAgGridRowDeleteContext(this.#rowDeleteIdsInternal.asReadonly(), toSignal(this.agGridBodyViewport), signal(undefined));
1232
+ this.#rowDeleteSvc.cancelRowDelete
1233
+ .pipe(takeUntil(this.#ngUnsubscribe))
1234
+ .subscribe((rowId) => {
1235
+ if (rowId) {
1236
+ this.rowDeleteIds.update((rowIds) => rowIds.filter((id) => id !== rowId));
1237
+ this.rowDeleteCancel.emit({ id: rowId });
1238
+ }
1239
+ });
1240
+ this.#rowDeleteSvc.confirmRowDelete
1241
+ .pipe(takeUntil(this.#ngUnsubscribe))
1242
+ .subscribe((rowId) => {
1243
+ if (rowId) {
1244
+ this.rowDeleteConfirm.emit({ id: rowId });
1242
1245
  }
1243
- this.rowDeleteIdsChange.emit(value);
1244
- }))).pipe(takeUntil(this.#ngUnsubscribe),
1245
- // After change detection.
1246
- observeOn(asapScheduler),
1247
- // Wait for a render cycle.
1248
- sample(animationFrames()), map(() => undefined))))
1249
- .subscribe(() => {
1250
- this.#updateRowDeleteStates();
1251
1246
  });
1252
- this.#rowDeleteContentsQueued
1253
- .pipe(takeUntil(this.#ngUnsubscribe),
1254
- // After change detection.
1255
- observeOn(asapScheduler),
1256
- // Wait for a render cycle.
1257
- sample(animationFrames()))
1247
+ const agGrid = toObservable(this.agGrid);
1248
+ agGrid
1249
+ .pipe(filter$1((agGrid) => !!agGrid), switchMap((agGrid) => agGrid.gridReady), takeUntil(this.#ngUnsubscribe))
1258
1250
  .subscribe(() => {
1259
- const queue = [...this.#rowDeleteContentsQueue];
1260
- this.#rowDeleteContentsQueue = [];
1261
- queue.forEach(({ id, overlay }) => {
1262
- if (this.#rowDeleteContents.findIndex((content) => content.id === id) === -1 &&
1263
- this.#rowDeleteIdsInternal().includes(id)) {
1264
- const inlineDeleteRef = this.#rowDeleteComponent
1265
- ?.inlineDeleteRefs()
1266
- .find((elRef) => elRef.nativeElement.id === 'row-delete-ref-' + id);
1267
- const rowNode = this.agGrid()?.api.getRowNode(id);
1268
- if (rowNode && inlineDeleteRef) {
1269
- const affixer = this.#affixService.createAffixer(inlineDeleteRef);
1270
- this.#affixToRow(affixer, id);
1271
- this.#rowDeleteContents.push({ id, affixer, overlay });
1272
- return;
1273
- }
1274
- }
1275
- this.#overlayService.close(overlay);
1276
- });
1251
+ this.agGridBodyViewport.next([
1252
+ new ElementRef(this.#elementRef.nativeElement.querySelector('div.ag-root-wrapper')),
1253
+ ]);
1254
+ this.#rowDeleteSvc.gridApi.set(this.agGrid()?.api);
1255
+ });
1256
+ agGrid
1257
+ .pipe(filter$1((agGrid) => !!agGrid), switchMap((agGrid) => agGrid.rowDataUpdated), takeUntil(this.#ngUnsubscribe))
1258
+ .subscribe((evt) => {
1259
+ this.rowDeleteIds.update((rowIds) => (rowIds ?? []).filter((id) => !!evt.api.getRowNode(id)));
1277
1260
  });
1278
1261
  }
1279
1262
  ngAfterContentInit() {
1280
- this.#rowDeleteComponent = this.#dynamicComponentSvc.createComponent(SkyAgGridRowDeleteComponent, {
1263
+ const overlay = this.#overlayService.create({
1264
+ enableScroll: true,
1281
1265
  environmentInjector: this.#environmentInjector,
1282
- viewContainerRef: this.#viewContainerRef,
1283
- }).instance;
1266
+ showBackdrop: false,
1267
+ closeOnNavigation: true,
1268
+ enableClose: false,
1269
+ enablePointerEvents: true,
1270
+ });
1271
+ overlay.attachComponent(SkyAgGridRowDeleteComponent, [
1272
+ {
1273
+ provide: SKY_AG_GRID_ROW_DELETE_CONTEXT,
1274
+ useValue: this.#rowDeleteSvc,
1275
+ },
1276
+ ]);
1277
+ this.#zIndex
1278
+ .pipe(takeUntil(this.#ngUnsubscribe), takeUntil(overlay.closed), distinctUntilChanged())
1279
+ .subscribe((zIndex) => {
1280
+ overlay.componentRef.instance.zIndex = zIndex.toString(10);
1281
+ });
1282
+ this.#clipPath
1283
+ .pipe(takeUntil(this.#ngUnsubscribe), takeUntil(overlay.closed), distinctUntilChanged())
1284
+ .subscribe((clipPath) => {
1285
+ overlay.componentRef.instance.updateClipPath(clipPath);
1286
+ });
1284
1287
  }
1285
1288
  ngAfterViewInit() {
1286
- if (this.#stackingContext) {
1287
- this.#scrollableHostService
1288
- .watchScrollableHostClipPathChanges(this.#elementRef)
1289
- .pipe(takeUntil(this.#ngUnsubscribe))
1290
- .subscribe((clipPath) => {
1291
- this.#clipPath.next(clipPath);
1292
- });
1293
- }
1294
- this.#viewUpdate.next();
1289
+ this.#scrollableHostService
1290
+ .watchScrollableHostClipPathChanges(this.#elementRef, this.agGridBodyViewport.asObservable())
1291
+ .pipe(takeUntil(this.#ngUnsubscribe))
1292
+ .subscribe((clipPath) => {
1293
+ this.#clipPath.next(clipPath);
1294
+ });
1295
1295
  }
1296
1296
  ngOnDestroy() {
1297
- this.#viewUpdate.complete();
1298
1297
  this.#ngUnsubscribe.next();
1299
1298
  this.#ngUnsubscribe.complete();
1300
- this.#rowDeleteContents.forEach(({ id }) => {
1301
- this.#destroyRowDelete(id);
1302
- });
1303
- }
1304
- cancelRowDelete(row) {
1305
- if (row.id) {
1306
- this.#rowDeleteIdsInternal.set(this.#rowDeleteIdsInternal().filter((id) => id !== row.id));
1307
- this.rowDeleteCancel.emit({ id: row.id });
1308
- }
1309
- }
1310
- confirmRowDelete(row) {
1311
- const rowConfig = this.#rowDeleteConfigs.find((config) => config.id === row.id);
1312
- if (row.id && rowConfig) {
1313
- rowConfig.pending = true;
1314
- this.rowDeleteConfirm.emit({ id: row.id });
1315
- }
1316
- }
1317
- getRowDeleteItem(row) {
1318
- return (this.#rowDeleteConfigs.find((config) => config.id === row.id) ?? {
1319
- id: `${row.id}`,
1320
- pending: false,
1321
- });
1322
- }
1323
- #affixToRow(affixer, id) {
1324
- const rowElement = this.#elementRef.nativeElement.querySelector(`
1325
- [row-id="${id}"] div[aria-colindex],
1326
- .ag-row.sky-ag-grid-row-${id} div[aria-colindex]
1327
- `);
1328
- const values = this.#rowDeleteIdsInternal();
1329
- if (rowElement && values.includes(id)) {
1330
- affixer.affixTo(rowElement, {
1331
- autoFitContext: SkyAffixAutoFitContext.Viewport,
1332
- isSticky: true,
1333
- placement: 'above',
1334
- verticalAlignment: 'top',
1335
- horizontalAlignment: 'left',
1336
- enableAutoFit: false,
1337
- });
1338
- }
1339
- }
1340
- #destroyRowDelete(id) {
1341
- const idx = this.#rowDeleteContents.findIndex((content) => content.id === id);
1342
- if (idx > -1 && this.#rowDeleteContents[idx].overlay) {
1343
- this.#rowDeleteContents[idx].affixer.destroy();
1344
- this.#overlayService.close(this.#rowDeleteContents[idx].overlay);
1345
- this.#rowDeleteContents.splice(idx, 1);
1346
- }
1347
- }
1348
- #updateRowDeleteStates() {
1349
- const deleteTemplateRef = this.#rowDeleteComponent?.inlineDeleteTemplateRef();
1350
- const agGrid = this.agGrid();
1351
- const value = this.#rowDeleteIdsInternal();
1352
- const contentIds = this.#rowDeleteContents.map((content) => content.id);
1353
- for (const id of contentIds) {
1354
- if (!value.includes(id)) {
1355
- this.#destroyRowDelete(id);
1356
- }
1357
- }
1358
- if (deleteTemplateRef && agGrid) {
1359
- for (const id of value) {
1360
- this.#updateOneRowDeleteState(id, agGrid, deleteTemplateRef);
1361
- }
1362
- }
1363
- }
1364
- #updateOneRowDeleteState(id, agGrid, deleteTemplateRef) {
1365
- const rowNode = agGrid.api.getRowNode(id);
1366
- const idx = this.#rowDeleteContents.findIndex((content) => content.id === id);
1367
- if (idx > -1) {
1368
- if (rowNode?.displayed) {
1369
- // We must reaffix things when the data changes because the rows rerender and the previous element that the delete was affixed
1370
- // to is destroyed.
1371
- this.#affixToRow(this.#rowDeleteContents[idx].affixer, id);
1372
- }
1373
- else {
1374
- this.#destroyRowDelete(id);
1375
- }
1376
- }
1377
- else if (rowNode) {
1378
- const overlay = this.#overlayService.create({
1379
- enableScroll: true,
1380
- environmentInjector: this.#environmentInjector,
1381
- showBackdrop: false,
1382
- closeOnNavigation: true,
1383
- enableClose: false,
1384
- enablePointerEvents: true,
1385
- });
1386
- overlay.attachTemplate(deleteTemplateRef, {
1387
- $implicit: rowNode,
1388
- tableWidth: () => this.#elementRef.nativeElement.querySelector('.sky-ag-grid')
1389
- .offsetWidth,
1390
- getRowDeleteItem: (row) => this.getRowDeleteItem(row),
1391
- cancelRowDelete: (row) => this.cancelRowDelete(row),
1392
- confirmRowDelete: (row) => this.confirmRowDelete(row),
1393
- });
1394
- /**
1395
- * We are manually setting the z-index here because overlays will always be on top of
1396
- * the omnibar. The default manual setting is 2 less than the omnibar's z-index of 1000 and one less than
1397
- * the header row's viewkeeper which is 999. We discussed changing the overlay service to allow for this
1398
- * but decided against that change at this time due to its niche nature.
1399
- */
1400
- this.#zIndex
1401
- .pipe(takeUntil(this.#ngUnsubscribe), takeUntil(overlay.closed))
1402
- .subscribe((zIndex) => {
1403
- overlay.componentRef.instance.zIndex = zIndex.toString(10);
1404
- });
1405
- this.#clipPath
1406
- .pipe(takeUntil(this.#ngUnsubscribe), takeUntil(overlay.closed))
1407
- .subscribe((clipPath) => {
1408
- overlay.componentRef.instance.updateClipPath(clipPath);
1409
- });
1410
- this.#rowDeleteContentsQueue.push({ id, overlay });
1411
- this.#rowDeleteContentsQueued.next();
1412
- }
1299
+ this.#rowDeleteSvc.subscription.unsubscribe();
1300
+ this.#overlayService.closeAll();
1413
1301
  }
1414
1302
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SkyAgGridRowDeleteDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1415
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.2.7", type: SkyAgGridRowDeleteDirective, isStandalone: true, selector: "[skyAgGridRowDelete]", inputs: { rowDeleteIds: { classPropertyName: "rowDeleteIds", publicName: "rowDeleteIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowDeleteIdsChange: "rowDeleteIdsChange", rowDeleteCancel: "rowDeleteCancel", rowDeleteConfirm: "rowDeleteConfirm" }, queries: [{ propertyName: "agGrid", first: true, predicate: AgGridAngular, descendants: true, isSignal: true }], ngImport: i0 }); }
1303
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.2.7", type: SkyAgGridRowDeleteDirective, isStandalone: true, selector: "[skyAgGridRowDelete]", inputs: { rowDeleteIds: { classPropertyName: "rowDeleteIds", publicName: "rowDeleteIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowDeleteIds: "rowDeleteIdsChange", rowDeleteCancel: "rowDeleteCancel", rowDeleteConfirm: "rowDeleteConfirm" }, queries: [{ propertyName: "agGrid", first: true, predicate: AgGridAngular, descendants: true, isSignal: true }], ngImport: i0 }); }
1416
1304
  }
1417
1305
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SkyAgGridRowDeleteDirective, decorators: [{
1418
1306
  type: Directive,
1419
- args: [{ selector: '[skyAgGridRowDelete]' }]
1307
+ args: [{
1308
+ selector: '[skyAgGridRowDelete]',
1309
+ }]
1420
1310
  }], ctorParameters: () => [] });
1421
1311
 
1422
1312
  class SkyAgGridModule {
@@ -2508,7 +2398,7 @@ class SkyAgGridCellRendererRowSelectorComponent {
2508
2398
  }
2509
2399
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SkyAgGridCellRendererRowSelectorComponent, decorators: [{
2510
2400
  type: Component,
2511
- args: [{ selector: 'sky-ag-grid-cell-renderer-row-selector', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [SkyThemeComponentClassDirective, SkyCheckboxModule, AsyncPipe], template: "<sky-checkbox\n data-sky-id=\"row-checkbox\"\n [disabled]=\"(disabled | async) || false\"\n [tabindex]=\"0\"\n [labelHidden]=\"true\"\n [labelText]=\"(label | async) || ''\"\n [checked]=\"(checked | async) || false\"\n (change)=\"updateRow(!!$event.checked)\"\n/>\n", styles: [".sky-ag-grid-cell-row-selector .sky-switch-control{top:-6px}\n"] }]
2401
+ args: [{ selector: 'sky-ag-grid-cell-renderer-row-selector', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [SkyCheckboxModule, AsyncPipe], template: "<sky-checkbox\n data-sky-id=\"row-checkbox\"\n [disabled]=\"(disabled | async) || false\"\n [tabindex]=\"0\"\n [labelHidden]=\"true\"\n [labelText]=\"(label | async) || ''\"\n [checked]=\"(checked | async) || false\"\n (change)=\"updateRow(!!$event.checked)\"\n/>\n", styles: [".sky-ag-grid-cell-row-selector .sky-switch-control{top:-6px}\n"] }]
2512
2402
  }], ctorParameters: () => [] });
2513
2403
 
2514
2404
  class SkyAgGridCellRendererTemplateComponent {
@@ -2664,7 +2554,9 @@ class SkyAgGridHeaderGroupComponent {
2664
2554
  this.#columnGroup = params.columnGroup.getProvidedColumnGroup();
2665
2555
  this.#isExpandableSubject.next(this.#columnGroup.isExpandable());
2666
2556
  if (this.#isExpandableSubject.getValue()) {
2667
- this.#subscriptions.add(fromEventPattern((handler) => params.api.addEventListener('columnGroupOpened', handler), (handler) => params.api.removeEventListener('columnGroupOpened', handler)).subscribe((event) => {
2557
+ this.#subscriptions.add(fromEvent(params.api, 'columnGroupOpened')
2558
+ .pipe(takeUntil(fromEvent(params.api, 'gridPreDestroyed')))
2559
+ .subscribe((event) => {
2668
2560
  if (this.#columnGroup &&
2669
2561
  event.columnGroups.includes(this.#columnGroup)) {
2670
2562
  this.#isExpandedSubject.next(this.#columnGroup.isExpanded());
@@ -2794,7 +2686,9 @@ class SkyAgGridHeaderComponent {
2794
2686
  this.#leftPosition = params.column.getLeft() ?? 0;
2795
2687
  this.#subscriptions = new Subscription();
2796
2688
  if (params.column.isFilterAllowed()) {
2797
- this.#subscriptions.add(fromEventPattern((handler) => params.column.addEventListener('filterChanged', handler), (handler) => params.column.removeEventListener('filterChanged', handler)).subscribe(() => {
2689
+ this.#subscriptions.add(fromEvent(params.column, 'filterChanged')
2690
+ .pipe(takeUntil(fromEvent(params.api, 'gridPreDestroyed')))
2691
+ .subscribe(() => {
2798
2692
  const isFilterActive = params.column.isFilterActive();
2799
2693
  if (isFilterActive !== this.filterEnabled$.getValue()) {
2800
2694
  this.filterEnabled$.next(isFilterActive);
@@ -2803,11 +2697,15 @@ class SkyAgGridHeaderComponent {
2803
2697
  }
2804
2698
  if (params.enableSorting) {
2805
2699
  // Column sort state changes
2806
- this.#subscriptions.add(fromEventPattern((handler) => params.column.addEventListener('sortChanged', handler), (handler) => params.column.removeEventListener('sortChanged', handler)).subscribe(() => {
2700
+ this.#subscriptions.add(fromEvent(params.column, 'sortChanged')
2701
+ .pipe(takeUntil(fromEvent(params.api, 'gridPreDestroyed')))
2702
+ .subscribe(() => {
2807
2703
  this.#updateSort();
2808
2704
  }));
2809
2705
  // Other column sort state changes, for multi-column sorting
2810
- this.#subscriptions.add(fromEventPattern((handler) => params.api.addEventListener('sortChanged', handler), (handler) => params.api.removeEventListener('sortChanged', handler)).subscribe(() => {
2706
+ this.#subscriptions.add(fromEvent(params.api, 'sortChanged')
2707
+ .pipe(takeUntil(fromEvent(params.api, 'gridPreDestroyed')))
2708
+ .subscribe(() => {
2811
2709
  this.#updateSortIndex();
2812
2710
  }));
2813
2711
  this.#updateSort();
@@ -2815,7 +2713,9 @@ class SkyAgGridHeaderComponent {
2815
2713
  }
2816
2714
  // When the column is moved left via the keyboard, the element is detached
2817
2715
  // and reattached to the DOM to maintain DOM order, and its focus is lost.
2818
- this.#subscriptions.add(fromEventPattern((handler) => params.api.addEventListener('columnMoved', handler), (handler) => params.api.removeEventListener('columnMoved', handler)).subscribe((event) => {
2716
+ this.#subscriptions.add(fromEvent(params.api, 'columnMoved')
2717
+ .pipe(takeUntil(fromEvent(params.api, 'gridPreDestroyed')))
2718
+ .subscribe((event) => {
2819
2719
  const left = event.column?.getLeft() ?? 0;
2820
2720
  const oldLeft = this.#leftPosition;
2821
2721
  if (event.column === params.column &&