diff --git a/demo-shell/src/app/components/datatable/datatable.component.html b/demo-shell/src/app/components/datatable/datatable.component.html index d93b286659..84ca436c4e 100644 --- a/demo-shell/src/app/components/datatable/datatable.component.html +++ b/demo-shell/src/app/components/datatable/datatable.component.html @@ -1,30 +1,34 @@ -
- - - - + + + + + +
+ Selected items: {{ dataTable.selection?.length }}
-
+ +
{{ 'DATATABLE.MULTISELECT'| translate }}
-
+

{{ 'DATATABLE.MULTISELECT_DESCRIPTION'| translate }}

@@ -34,7 +38,7 @@
-
+
diff --git a/demo-shell/src/app/components/datatable/datatable.component.scss b/demo-shell/src/app/components/datatable/datatable.component.scss deleted file mode 100644 index e54696a4ba..0000000000 --- a/demo-shell/src/app/components/datatable/datatable.component.scss +++ /dev/null @@ -1,16 +0,0 @@ -adf-datatable ::ng-deep .custom-row-style.alfresco-datatable__row:focus { - outline-offset: -1px; - outline-width: 1px; - outline-color: green; - outline-style: solid; -} - -adf-datatable ::ng-deep .custom-row-style.alfresco-datatable__row--selected { - color: green; -} - -adf-datatable ::ng-deep table { - max-width: 100%; - overflow: hidden; - white-space: normal !important; -} diff --git a/demo-shell/src/app/components/datatable/datatable.component.ts b/demo-shell/src/app/components/datatable/datatable.component.ts index cb8c92cc59..32a7490d4d 100644 --- a/demo-shell/src/app/components/datatable/datatable.component.ts +++ b/demo-shell/src/app/components/datatable/datatable.component.ts @@ -22,8 +22,7 @@ import { Observable } from 'rxjs/Observable'; @Component({ selector: 'app-datatable', - templateUrl: './datatable.component.html', - styleUrls: ['./datatable.component.scss'] + templateUrl: './datatable.component.html' }) export class DataTableComponent { @@ -41,8 +40,8 @@ export class DataTableComponent { private _imageUrl = 'http://placehold.it/140x100'; private _createdBy: any = { - name: 'Denys Vuika', - email: 'denys.vuika@alfresco.com' + name: 'Administrator', + email: 'admin@alfresco.com' }; constructor(private apiService: AlfrescoApiService, private logService: LogService) { diff --git a/docs/core/datatable-adapter.interface.md b/docs/core/datatable-adapter.interface.md index b199905dff..8b293a2d95 100644 --- a/docs/core/datatable-adapter.interface.md +++ b/docs/core/datatable-adapter.interface.md @@ -14,6 +14,12 @@ and [Tasklist](../process-services/task-list.component.md) components. | ---- | ---- | ----------- | | selectedRow | DataRow | The data for the currently selected row. | +## Events + +| Name | Type | Description | +| ---- | ---- | ----------- | +| rowsChanged | `Subject>` | Raised when data adapter gets new rows. | + ## Methods [`getRows(): Array;`](../../lib/core/datatable/data/data-row.model.ts)
@@ -27,11 +33,11 @@ Get/set an array of column specifications. `getValue(row: DataRow, col: DataColumn): any;`
Get the data value from a specific table cell. -`getSorting(): DataSorting;` -`setSorting(sorting: DataSorting): void;` +`getSorting(): DataSorting;`
+`setSorting(sorting: DataSorting): void;`
Get/set the sorting key and direction (ascending or descending). -`sort(key?: string, direction?: string): void;` +`sort(key?: string, direction?: string): void;`
Sort the table with a specified key and direction (ascending or descending). ## Details diff --git a/lib/core/datatable/components/datatable/datatable.component.spec.ts b/lib/core/datatable/components/datatable/datatable.component.spec.ts index 6afcb5e085..951da490aa 100644 --- a/lib/core/datatable/components/datatable/datatable.component.spec.ts +++ b/lib/core/datatable/components/datatable/datatable.component.spec.ts @@ -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( { 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(); diff --git a/lib/core/datatable/components/datatable/datatable.component.ts b/lib/core/datatable/components/datatable/datatable.component.ts index c41eac7f12..69c362d012 100644 --- a/lib/core/datatable/components/datatable/datatable.component.ts +++ b/lib/core/datatable/components/datatable/datatable.component.ts @@ -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; + } } } diff --git a/lib/core/datatable/data/datatable-adapter.ts b/lib/core/datatable/data/datatable-adapter.ts index cad48181ca..3c0ef1937a 100644 --- a/lib/core/datatable/data/datatable-adapter.ts +++ b/lib/core/datatable/data/datatable-adapter.ts @@ -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>; + selectedRow: DataRow; getRows(): Array; setRows(rows: Array): void; diff --git a/lib/core/datatable/data/object-datatable-adapter.ts b/lib/core/datatable/data/object-datatable-adapter.ts index dc737be03f..7875a6bf64 100644 --- a/lib/core/datatable/data/object-datatable-adapter.ts +++ b/lib/core/datatable/data/object-datatable-adapter.ts @@ -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>; 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>(); } getRows(): Array { @@ -84,6 +88,7 @@ export class ObjectDataTableAdapter implements DataTableAdapter { setRows(rows: Array) { this._rows = rows || []; this.sort(); + this.rowsChanged.next(this._rows); } getColumns(): Array {