Skip to content
65 changes: 65 additions & 0 deletions projects/igniteui-angular-elements/src/app/custom-strategy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
IgcPaginatorComponent,
IgcGridStateComponent,
IgcColumnLayoutComponent,
IgcActionStripComponent,
IgcGridEditingActionsComponent,
} from './components';
import { defineComponents } from '../utils/register';

Expand All @@ -27,6 +29,8 @@ describe('Elements: ', () => {
IgcColumnLayoutComponent,
IgcPaginatorComponent,
IgcGridStateComponent,
IgcActionStripComponent,
IgcGridEditingActionsComponent
);
});

Expand Down Expand Up @@ -230,5 +234,66 @@ describe('Elements: ', () => {
expect(grid.columns.length).toEqual(6);
expect(grid.getColumnByVisibleIndex(1).field).toEqual('ProductName');
});

it('should not destroy action strip when row it is shown in is destroyed or cached.', async() => {
const innerHtml = `
<igc-grid id="testGrid" auto-generate>
<igc-action-strip id="testStrip">
<igc-grid-editing-actions add-row="true"></igc-grid-editing-actions>
</igc-action-strip>
</igc-grid>`;
testContainer.innerHTML = innerHtml;

// TODO: Better way to wait - potentially expose the queue or observable for update on the strategy
await firstValueFrom(timer(10 /* SCHEDULE_DELAY */ * 3));

const grid = document.querySelector<IgcNgElement & InstanceType<typeof IgcGridComponent>>('#testGrid');
const actionStrip = document.querySelector<IgcNgElement & InstanceType<typeof IgcActionStripComponent>>('#testStrip');
grid.data = SampleTestData.foodProductData();

// TODO: Better way to wait - potentially expose the queue or observable for update on the strategy
await firstValueFrom(timer(10 /* SCHEDULE_DELAY */ * 3));

let row = grid.dataRowList.toArray()[0];
actionStrip.show(row);
await firstValueFrom(timer(10 /* SCHEDULE_DELAY */ * 3));

expect(actionStrip.hidden).toBeFalse();

grid.data = [];
await firstValueFrom(timer(10 /* SCHEDULE_DELAY */ * 3));

// row destroyed
expect((row.cdr as any).destroyed).toBeTrue();
// action strip still in DOM, only hidden.
expect(actionStrip.hidden).toBeTrue();
expect(actionStrip.isConnected).toBeTrue();

grid.data = SampleTestData.foodProductData();
grid.groupBy({ fieldName: 'InStock', dir: 1, ignoreCase: false });

// TODO: Better way to wait - potentially expose the queue or observable for update on the strategy
await firstValueFrom(timer(10 /* SCHEDULE_DELAY */ * 3));

row = grid.dataRowList.toArray()[0];
actionStrip.show(row);
await firstValueFrom(timer(10 /* SCHEDULE_DELAY */ * 3));

expect(actionStrip.hidden).toBeFalse();

// collapse all data rows, leave only groups
grid.toggleAllGroupRows();

// TODO: Better way to wait - potentially expose the queue or observable for update on the strategy
await firstValueFrom(timer(10 /* SCHEDULE_DELAY */ * 3));

// row not destroyed, but also not in dom anymore
expect((row.cdr as any).destroyed).toBeFalse();
expect(row.element.nativeElement.isConnected).toBe(false);

// action strip still in DOM, only hidden.
expect(actionStrip.hidden).toBeTrue();
expect(actionStrip.isConnected).toBeTrue();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { IgxGridPinningActionsComponent } from './grid-pinning-actions.component
import { IgxActionStripComponent } from '../action-strip.component';
import { IRowDataCancelableEventArgs, IgxColumnComponent } from '../../grids/public_api';
import { SampleTestData } from '../../test-utils/sample-test-data.spec';
import { SortingDirection } from '../../data-operations/sorting-strategy';

describe('igxGridEditingActions #grid ', () => {
let fixture;
Expand Down Expand Up @@ -274,6 +275,59 @@ describe('igxGridEditingActions #grid ', () => {

expect(actionStrip.hidden).toBeTrue();
});

it('should auto-hide on delete action click.', () => {
const row = grid.rowList.toArray()[0];
actionStrip.show(row);
fixture.detectChanges();

expect(actionStrip.hidden).toBeFalse();

const deleteIcon = fixture.debugElement.queryAll(By.css(`igx-grid-editing-actions igx-icon`))[1];
expect(deleteIcon.nativeElement.innerText).toBe('delete');
deleteIcon.parent.triggerEventHandler('click', new Event('click'));
fixture.detectChanges();

expect(actionStrip.hidden).toBeTrue();

});

it('should auto-hide if context row is destroyed.', () => {
const row = grid.rowList.toArray()[0];
actionStrip.show(row);
fixture.detectChanges();

expect(actionStrip.hidden).toBeFalse();

// bind to no data, which removes all rows.
grid.data = [];
grid.cdr.detectChanges();

expect((row.cdr as any).destroyed).toBeTrue();
expect(actionStrip.hidden).toBeTrue();
});

it('should auto-hide if context row is cached.', () => {
// create group rows
grid.groupBy({ fieldName: 'ContactTitle', dir: SortingDirection.Desc, ignoreCase: false });
fixture.detectChanges();

// show for first data row
const row = grid.dataRowList.toArray()[0];
actionStrip.show(row);
fixture.detectChanges();

// collapse all groups to cache data rows
grid.toggleAllGroupRows();
fixture.detectChanges();

// not destroyed, but not in DOM anymore
expect((row.cdr as any).destroyed).toBeFalse();
expect(row.element.nativeElement.isConnected).toBe(false);

// action strip should be hidden
expect(actionStrip.hidden).toBeTrue();
});
});

describe('auto show/hide in HierarchicalGrid', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6438,6 +6438,12 @@ export abstract class IgxGridBaseDirective implements GridType,
}
}

protected viewDetachHandler(args) {
if (this.actionStrip && args.view.rootNodes.find(x => x === this.actionStrip.context?.element.nativeElement)) {
this.actionStrip.hide();
}
}

/**
* @hidden @internal
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
[igxTemplateOutletContext]="getContext(rowData, rowIndex)"
(cachedViewLoaded)="cachedViewLoaded($event)"
(viewCreated)="viewCreatedHandler($event)"
(beforeViewDetach)="viewDetachHandler($event)"
(viewMoved)="viewMovedHandler($event)">
</ng-template>
</ng-template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
<ng-template
[igxTemplateOutlet]="(isHierarchicalRecord(rowData) ? hierarchical_record_template : (isChildGridRecord(rowData) ? child_record_template : hierarchical_record_template))"
[igxTemplateOutletContext]="getContext(rowData, rowIndex, false)" (viewCreated)="viewCreatedHandler($event)"
(viewMoved)="viewMovedHandler($event)" (cachedViewLoaded)="cachedViewLoaded($event)">
(viewMoved)="viewMovedHandler($event)" (cachedViewLoaded)="cachedViewLoaded($event)" (beforeViewDetach)="viewDetachHandler($event)">
</ng-template>
<!-- <ng-container *igxTemplateOutlet="(isHierarchicalRecord(rowData) ? hierarchical_record_template : (isChildGridRecord(rowData) && isExpanded(rowData) ? child_record_template : hierarchical_record_template)); context: getContext(rowData)"></ng-container> -->
</ng-template>
Expand Down
4 changes: 4 additions & 0 deletions projects/igniteui-angular/src/lib/grids/row.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,10 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy {
* @internal
*/
public ngOnDestroy() {
// if action strip is shown here but row is about to be destroyed, hide it.
if (this.grid.actionStrip && this.grid.actionStrip.context === this) {
this.grid.actionStrip.hide();
}
this.destroy$.next(true);
this.destroy$.complete();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
(dataChanging)="dataRebinding($event)" (dataChanged)="dataRebound($event)">
<ng-template [igxTemplateOutlet]='isSummaryRow(rowData) ? summary_template : record_template'
[igxTemplateOutletContext]='getContext(rowData, rowIndex, false)'
(beforeViewDetach)="viewDetachHandler($event)"
(cachedViewLoaded)='cachedViewLoaded($event)'>
</ng-template>
</ng-template>
Expand Down
Loading