[ADF-2541] reset datatable selection when rows are changed from code (#3410)

* reset selection when rows are replaced from code

* code fixes

* unit test updates

* visualise selection count for testing purposes

* make row selection api public

* remove question mark from the event name
This commit is contained in:
Denys Vuika
2018-05-30 11:53:12 +01:00
committed by Eugenio Romano
parent 7e59b24f2c
commit 3162a73f61
8 changed files with 98 additions and 64 deletions

View File

@@ -484,15 +484,6 @@ describe('DataTable', () => {
expect(table.data).toEqual(jasmine.any(ObjectDataTableAdapter));
});
it('should load data table on onChange', () => {
let table = new DataTableComponent(null, null);
let data = new ObjectDataTableAdapter([], []);
expect(table.data).toBeUndefined();
table.ngOnChanges({'data': new SimpleChange('123', data, true)});
expect(table.data).toEqual(data);
});
it('should initialize with custom data', () => {
let data = new ObjectDataTableAdapter([], []);
dataTable.data = data;
@@ -690,6 +681,22 @@ describe('DataTable', () => {
expect(dataTable.isSelectAllChecked).toBeFalsy();
});
it('should reset selection upon data rows change', () => {
let data = new ObjectDataTableAdapter([{}, {}, {}], []);
dataTable.data = data;
dataTable.multiselect = true;
dataTable.ngAfterContentInit();
dataTable.onSelectAllClick(<MatCheckboxChange> { checked: true });
expect(dataTable.selection.every(entry => entry.isSelected));
data.setRows([]);
fixture.detectChanges();
expect(dataTable.selection.every(entry => !entry.isSelected));
});
it('should update rows on "select all" click', () => {
let data = new ObjectDataTableAdapter([{}, {}, {}], []);
let rows = data.getRows();

View File

@@ -20,9 +20,7 @@ import {
IterableDiffers, OnChanges, Output, SimpleChange, SimpleChanges, TemplateRef, ViewEncapsulation, OnDestroy
} from '@angular/core';
import { MatCheckboxChange } from '@angular/material';
import { Subscription } from 'rxjs/Subscription';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { Subscription, Observable, Observer } from 'rxjs/Rx';
import { DataColumnListComponent } from '../../../data-column/data-column-list.component';
import { DataColumn } from '../../data/data-column.model';
import { DataRowEvent } from '../../data/data-row-event.model';
@@ -168,6 +166,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
private subscriptions: Subscription[] = [];
private singleClickStreamSub: Subscription;
private multiClickStreamSub: Subscription;
private dataRowsChanged: Subscription;
constructor(private elementRef: ElementRef,
differs: IterableDiffers,
@@ -196,6 +195,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
this.initTable();
} else {
this.data = changes['data'].currentValue;
this.setupData(this.data);
}
return;
}
@@ -205,6 +205,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
this.initTable();
} else {
this.setTableRows(changes['rows'].currentValue);
this.setupData(this.data);
}
return;
}
@@ -293,15 +294,34 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
private initTable() {
this.data = new ObjectDataTableAdapter(this.rows, this.schema);
this.setupData(this.data);
this.rowMenuCache = {};
}
private setupData(adapter: DataTableAdapter) {
if (this.dataRowsChanged) {
this.dataRowsChanged.unsubscribe();
this.dataRowsChanged = null;
}
this.resetSelection();
if (adapter && adapter.rowsChanged) {
this.dataRowsChanged = adapter.rowsChanged.subscribe(() => {
this.resetSelection();
});
}
}
isTableEmpty() {
return this.data === undefined || this.data === null;
}
private setTableRows(rows) {
private setTableRows(rows: any[]) {
if (this.data) {
if (rows && rows.length > 0) {
this.resetSelection();
}
this.data.setRows(this.convertToRowsData(rows));
}
}
@@ -560,7 +580,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
}
}
private selectRow(row: DataRow, value: boolean) {
selectRow(row: DataRow, value: boolean) {
if (row) {
row.isSelected = value;
const idx = this.selection.indexOf(row);
@@ -588,8 +608,8 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
}
getSortableColumns() {
return this.data.getColumns().filter((currentColum) => {
return currentColum.sortable === true;
return this.data.getColumns().filter(column => {
return column.sortable === true;
});
}
@@ -625,7 +645,13 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
ngOnDestroy() {
this.unsubscribeClickStream();
this.subscriptions.forEach(s => s.unsubscribe());
this.subscriptions = [];
if (this.dataRowsChanged) {
this.dataRowsChanged.unsubscribe();
this.dataRowsChanged = null;
}
}
}

View File

@@ -18,8 +18,11 @@
import { DataColumn } from './data-column.model';
import { DataRow } from './data-row.model';
import { DataSorting } from './data-sorting.model';
import { Subject } from 'rxjs/Rx';
export interface DataTableAdapter {
rowsChanged?: Subject<Array<DataRow>>;
selectedRow: DataRow;
getRows(): Array<DataRow>;
setRows(rows: Array<DataRow>): void;

View File

@@ -21,6 +21,7 @@ import { ObjectDataRow } from './object-datarow.model';
import { ObjectDataColumn } from './object-datacolumn.model';
import { DataSorting } from './data-sorting.model';
import { DataTableAdapter } from './datatable-adapter';
import { Subject } from 'rxjs/Subject';
// Simple implementation of the DataTableAdapter interface.
export class ObjectDataTableAdapter implements DataTableAdapter {
@@ -30,6 +31,7 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
private _columns: DataColumn[];
selectedRow: DataRow;
rowsChanged: Subject<Array<DataRow>>;
static generateSchema(data: any[]) {
let schema = [];
@@ -75,6 +77,8 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
this.sort(sortable[0].key, 'asc');
}
}
this.rowsChanged = new Subject<Array<DataRow>>();
}
getRows(): Array<DataRow> {
@@ -84,6 +88,7 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
setRows(rows: Array<DataRow>) {
this._rows = rows || [];
this.sort();
this.rowsChanged.next(this._rows);
}
getColumns(): Array<DataColumn> {