Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(components/ag-grid): row delete confirmation event handling #3078

Merged
merged 4 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {
ComponentFixture,
TestBed,
fakeAsync,
tick,
} from '@angular/core/testing';
import { SKY_STACKING_CONTEXT, SkyScrollableHostService } from '@skyux/core';

import { BehaviorSubject, Observable, of } from 'rxjs';
Expand Down Expand Up @@ -158,26 +163,26 @@ describe('SkyAgGridRowDeleteDirective', () => {
).toBe(2);
});

it('should respond dataset changes', async () => {
it('should respond dataset changes', fakeAsync(() => {
setupTest();
await fixture.whenStable();
tick(16);

fixture.componentInstance.rowDeleteIds = ['0', '2'];
fixture.detectChanges();
await fixture.whenStable();
tick(16);

fixture.componentInstance.removeFirstItem();

fixture.detectChanges();
await fixture.whenStable();
tick(16);

expect(fixture.componentInstance.rowDeleteIds).toEqual(['2']);
expect(document.querySelector('#row-delete-ref-0')).toBeNull();
expect(document.querySelector('#row-delete-ref-2')).not.toBeNull();
expect(
document.querySelectorAll('.sky-inline-delete-standard').length,
).toBe(1);
});
}));
});

it('should cancel row delete elements correctly via them being removed from the id array', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
AfterContentInit,
AfterViewInit,
ChangeDetectorRef,
ContentChild,
Directive,
ElementRef,
EnvironmentInjector,
Expand All @@ -11,6 +10,8 @@ import {
OnDestroy,
Output,
ViewContainerRef,
contentChild,
effect,
inject,
} from '@angular/core';
import {
Expand All @@ -25,7 +26,13 @@ import {

import { AgGridAngular } from 'ag-grid-angular';
import { IRowNode } from 'ag-grid-community';
import { BehaviorSubject, Subject } from 'rxjs';
import {
BehaviorSubject,
Subject,
animationFrames,
debounce,
merge,
} from 'rxjs';
import { takeUntil } from 'rxjs/operators';

import { SkyAgGridRowDeleteComponent } from './ag-grid-row-delete.component';
Expand Down Expand Up @@ -82,7 +89,7 @@ export class SkyAgGridRowDeleteDirective
overlay.attachTemplate(
this.#rowDeleteComponent.inlineDeleteTemplateRef,
{
$implicit: this.agGrid.api.getRowNode(id),
$implicit: this.agGrid()?.api.getRowNode(id),
tableWidth: () =>
this.#elementRef.nativeElement.querySelector('.sky-ag-grid')
.offsetWidth,
Expand Down Expand Up @@ -161,8 +168,7 @@ export class SkyAgGridRowDeleteDirective

#rowDeleteConfigs: SkyAgGridRowDeleteConfig[] = [];

@ContentChild(AgGridAngular)
public agGrid: AgGridAngular | undefined;
public agGrid = contentChild(AgGridAngular);

#ngUnsubscribe = new Subject<void>();
#rowDeleteComponent: SkyAgGridRowDeleteComponent | undefined;
Expand All @@ -182,6 +188,7 @@ export class SkyAgGridRowDeleteDirective
readonly #scrollableHostService = inject(SkyScrollableHostService);
readonly #stackingContext = inject(SKY_STACKING_CONTEXT, { optional: true });
readonly #viewContainerRef = inject(ViewContainerRef);
readonly #viewInit = new Subject<void>();

constructor() {
this.#hasStackingContext = !!this.#stackingContext;
Expand All @@ -193,6 +200,26 @@ export class SkyAgGridRowDeleteDirective
this.#zIndex.next(zIndex);
});
}
effect(() => {
const agGrid = this.agGrid();
if (agGrid) {
merge(
agGrid.filterChanged,
agGrid.firstDataRendered,
agGrid.gridReady,
agGrid.rowDataUpdated,
agGrid.sortChanged,
this.#viewInit,
)
.pipe(
takeUntil(this.#ngUnsubscribe),
debounce(() => animationFrames()),
)
.subscribe(() => {
this.#updateRowDeleteStates();
});
}
});
}

public ngAfterContentInit(): void {
Expand All @@ -203,26 +230,6 @@ export class SkyAgGridRowDeleteDirective
viewContainerRef: this.#viewContainerRef,
},
).instance;

if (this.agGrid) {
this.agGrid.rowDataUpdated
.pipe(takeUntil(this.#ngUnsubscribe))
.subscribe(() => {
this.#updateRowDeleteStates();
});

this.agGrid.sortChanged
.pipe(takeUntil(this.#ngUnsubscribe))
.subscribe(() => {
this.#updateRowDeleteStates();
});

this.agGrid.filterChanged
.pipe(takeUntil(this.#ngUnsubscribe))
.subscribe(() => {
this.#updateRowDeleteStates();
});
}
}

public ngAfterViewInit(): void {
Expand All @@ -234,6 +241,7 @@ export class SkyAgGridRowDeleteDirective
this.#clipPath.next(clipPath);
});
}
this.#viewInit.next();
}

public ngOnDestroy(): void {
Expand Down Expand Up @@ -291,26 +299,21 @@ export class SkyAgGridRowDeleteDirective

#destroyRowDelete(id: string): void {
const rowDeleteContents = this.#rowDeleteContents[id];

/* sanity check */
/* istanbul ignore else */
if (rowDeleteContents) {
rowDeleteContents.affixer.destroy();
this.#overlayService.close(rowDeleteContents.overlay);
delete this.#rowDeleteContents[id];
this.#rowDeleteConfigs = this.#rowDeleteConfigs.filter(
(config) => config.id !== id,
);
this.#rowDeleteIdsInternal = this.rowDeleteIds?.filter(
(arrayId) => arrayId !== id,
);
this.rowDeleteIdsChange.emit(this.#rowDeleteIdsInternal);
}
rowDeleteContents?.affixer.destroy();
this.#overlayService.close(rowDeleteContents?.overlay);
delete this.#rowDeleteContents[id];
this.#rowDeleteConfigs = this.#rowDeleteConfigs.filter(
(config) => config.id !== id,
);
this.#rowDeleteIdsInternal = this.rowDeleteIds?.filter(
(arrayId) => arrayId !== id,
);
this.rowDeleteIdsChange.emit(this.#rowDeleteIdsInternal);
}

#updateRowDeleteStates(): void {
this.#rowDeleteConfigs.forEach((config: SkyAgGridRowDeleteConfig) => {
if (!this.agGrid?.api.getRowNode(config.id)) {
if (!this.agGrid()?.api.getRowNode(config.id)) {
this.#destroyRowDelete(config.id);
} else {
// We must reaffix things when the data changes because the rows rerender and the previous element that the delete was affixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export class SkyAgGridRowDeleteFixtureComponent implements OnInit {

public changeToLongData(): void {
this.gridData = SKY_AG_GRID_LONG_DATA;
this.gridApi?.setGridOption('rowData', this.gridData);
}

public filterName(): Promise<void> {
Expand Down Expand Up @@ -159,6 +160,7 @@ export class SkyAgGridRowDeleteFixtureComponent implements OnInit {

public removeFirstItem(): void {
this.gridData = this.gridData.slice(1);
this.gridApi?.setGridOption('rowData', this.gridData);
}

public sortName(): Promise<void> {
Expand Down
Loading