[ADF-2589] conditional visibility for DL/DT components (#3223)

* watch data columns and update layout if needed

* update docs

* support DataTable, docs and tests
This commit is contained in:
Denys Vuika
2018-04-24 10:06:32 +01:00
committed by Eugenio Romano
parent 382ea3c1b3
commit edee2f12b6
9 changed files with 112 additions and 15 deletions

View File

@@ -209,6 +209,7 @@
class="image-table-cell"> class="image-table-cell">
</data-column> </data-column>
<data-column <data-column
*ngIf="showNameColumn"
key="name" key="name"
title="{{'DOCUMENT_LIST.COLUMNS.DISPLAY_NAME' | translate}}" title="{{'DOCUMENT_LIST.COLUMNS.DISPLAY_NAME' | translate}}"
[formatTooltip]="getNodeNameTooltip" [formatTooltip]="getNodeNameTooltip"
@@ -404,6 +405,12 @@
</div> </div>
<div class="container"> <div class="container">
<section>
<mat-slide-toggle color="primary" [(ngModel)]="showNameColumn">
Show Name Column
</mat-slide-toggle>
</section>
<section> <section>
<mat-slide-toggle [color]="'primary'" [(ngModel)]="multiselect">{{'DOCUMENT_LIST.MULTISELECT_CHECKBOXES' | <mat-slide-toggle [color]="'primary'" [(ngModel)]="multiselect">{{'DOCUMENT_LIST.MULTISELECT_CHECKBOXES' |
translate}} translate}}

View File

@@ -119,6 +119,9 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
@Input() @Input()
disableDragArea = false; disableDragArea = false;
@Input()
showNameColumn = true;
@Output() @Output()
documentListReady: EventEmitter<any> = new EventEmitter(); documentListReady: EventEmitter<any> = new EventEmitter();

View File

@@ -141,6 +141,18 @@ Below is a basic example of handling DOM events in the parent elements.
</div> </div>
``` ```
### Conditional visibility
You can use `ngIf` directives to provide conditional visibility support for the columns:
```html
<data-column
*nfIg="showNameColumn"
key="name"
title="MY.RESOURCE.KEY">
</data-column>
```
### Card view ### Card view
The Document List has an option to display items as "cards" instead of the The Document List has an option to display items as "cards" instead of the

View File

@@ -55,6 +55,18 @@ Defines column properties for DataTable, Tasklist, Document List and other compo
## Details ## Details
### Conditional visibility
You can use `ngIf` directives to provide conditional visibility support for the columns:
```html
<data-column
*nfIg="showNameColumn"
key="name"
title="MY.RESOURCE.KEY">
</data-column>
```
### Automatic column header translation ### Automatic column header translation
You can use i18n resource keys with DataColumn `title` property. You can use i18n resource keys with DataColumn `title` property.

View File

@@ -15,9 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange, TemplateRef } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange, TemplateRef, QueryList } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { AlfrescoApiService } from '@alfresco/adf-core'; import { AlfrescoApiService, DataColumnListComponent, DataColumnComponent } from '@alfresco/adf-core';
import { DataColumn, DataTableComponent } from '@alfresco/adf-core'; import { DataColumn, DataTableComponent } from '@alfresco/adf-core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject'; import { Subject } from 'rxjs/Subject';
@@ -74,6 +74,24 @@ describe('DocumentList', () => {
fixture.destroy(); fixture.destroy();
}); });
it('should update schema if columns change', fakeAsync(() => {
documentList.ngOnInit();
documentList.columnList = new DataColumnListComponent();
documentList.columnList.columns = new QueryList<DataColumnComponent>();
spyOn(documentList.data, 'setColumns').and.callThrough();
documentList.ngAfterContentInit();
documentList.columnList.columns.reset([new DataColumnComponent()]);
documentList.columnList.columns.notifyOnChanges();
tick(100);
expect(documentList.data.setColumns).toHaveBeenCalled();
}));
it('should setup default columns', () => { it('should setup default columns', () => {
fixture.detectChanges(); fixture.detectChanges();
documentList.ngAfterContentInit(); documentList.ngAfterContentInit();

View File

@@ -231,8 +231,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
private _pagination: BehaviorSubject<PaginationModel>; private _pagination: BehaviorSubject<PaginationModel>;
private layoutPresets = {}; private layoutPresets = {};
private subscriptions: Subscription[] = [];
private contextActionHandlerSubscription: Subscription;
constructor(private documentListService: DocumentListService, constructor(private documentListService: DocumentListService,
private ngZone: NgZone, private ngZone: NgZone,
@@ -342,12 +341,25 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
this.data.setImageResolver(this.imageResolver); this.data.setImageResolver(this.imageResolver);
} }
this.contextActionHandlerSubscription = this.contextActionHandler.subscribe(val => this.contextActionCallback(val)); this.subscriptions.push(
this.contextActionHandler.subscribe(val => this.contextActionCallback(val))
);
this.enforceSingleClickNavigationForMobile(); this.enforceSingleClickNavigationForMobile();
} }
ngAfterContentInit() { ngAfterContentInit() {
if (this.columnList) {
this.subscriptions.push(
this.columnList.columns.changes.subscribe(() => {
this.setTableSchema();
})
);
}
this.setTableSchema();
}
private setTableSchema() {
let schema: DataColumn[] = []; let schema: DataColumn[] = [];
if (this.hasCustomLayout) { if (this.hasCustomLayout) {
@@ -770,10 +782,8 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
} }
ngOnDestroy() { ngOnDestroy() {
if (this.contextActionHandlerSubscription) { this.subscriptions.forEach(s => s.unsubscribe());
this.contextActionHandlerSubscription.unsubscribe(); this.subscriptions = [];
this.contextActionHandlerSubscription = null;
}
} }
private handleError(err: any) { private handleError(err: any) {

View File

@@ -16,7 +16,7 @@
*/ */
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { VersionListComponent } from './version-list.component'; import { VersionListComponent } from './version-list.component';
import { AlfrescoApiService, setupTestBed, CoreModule, AlfrescoApiServiceMock } from '@alfresco/adf-core'; import { AlfrescoApiService, setupTestBed, CoreModule, AlfrescoApiServiceMock } from '@alfresco/adf-core';

View File

@@ -15,8 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { SimpleChange, NO_ERRORS_SCHEMA } from '@angular/core'; import { SimpleChange, NO_ERRORS_SCHEMA, QueryList } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { MatCheckboxChange } from '@angular/material'; import { MatCheckboxChange } from '@angular/material';
import { DataColumn } from '../../data/data-column.model'; import { DataColumn } from '../../data/data-column.model';
import { DataRow } from '../../data/data-row.model'; import { DataRow } from '../../data/data-row.model';
@@ -26,6 +26,8 @@ import { ObjectDataTableAdapter } from '../../data/object-datatable-adapter';
import { DataTableComponent } from './datatable.component'; import { DataTableComponent } from './datatable.component';
import { setupTestBed } from '../../../testing/setupTestBed'; import { setupTestBed } from '../../../testing/setupTestBed';
import { CoreTestingModule } from '../../../testing/core.testing.module'; import { CoreTestingModule } from '../../../testing/core.testing.module';
import { DataColumnListComponent } from '../../../data-column/data-column-list.component';
import { DataColumnComponent } from '../../../data-column/data-column.component';
describe('DataTable', () => { describe('DataTable', () => {
@@ -50,6 +52,23 @@ describe('DataTable', () => {
fixture.destroy(); fixture.destroy();
}); });
it('should update schema if columns change', fakeAsync(() => {
dataTable.columnList = new DataColumnListComponent();
dataTable.columnList.columns = new QueryList<DataColumnComponent>();
dataTable.data = new ObjectDataTableAdapter([], []);
spyOn(dataTable.data, 'setColumns').and.callThrough();
dataTable.ngAfterContentInit();
dataTable.columnList.columns.reset([new DataColumnComponent()]);
dataTable.columnList.columns.notifyOnChanges();
tick(100);
expect(dataTable.data.setColumns).toHaveBeenCalled();
}));
it('should use the cardview style if cardview is true', () => { it('should use the cardview style if cardview is true', () => {
let newData = new ObjectDataTableAdapter( let newData = new ObjectDataTableAdapter(
[ [

View File

@@ -17,7 +17,7 @@
import { import {
AfterContentInit, Component, ContentChild, DoCheck, ElementRef, EventEmitter, Input, AfterContentInit, Component, ContentChild, DoCheck, ElementRef, EventEmitter, Input,
IterableDiffers, OnChanges, Output, SimpleChange, SimpleChanges, TemplateRef, ViewEncapsulation IterableDiffers, OnChanges, Output, SimpleChange, SimpleChanges, TemplateRef, ViewEncapsulation, OnDestroy
} from '@angular/core'; } from '@angular/core';
import { MatCheckboxChange } from '@angular/material'; import { MatCheckboxChange } from '@angular/material';
import { Subscription } from 'rxjs/Subscription'; import { Subscription } from 'rxjs/Subscription';
@@ -50,7 +50,7 @@ export enum DisplayMode {
templateUrl: './datatable.component.html', templateUrl: './datatable.component.html',
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck { export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck, OnDestroy {
@ContentChild(DataColumnListComponent) @ContentChild(DataColumnListComponent)
columnList: DataColumnListComponent; columnList: DataColumnListComponent;
@@ -159,6 +159,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck
private differ: any; private differ: any;
private rowMenuCache: object = {}; private rowMenuCache: object = {};
private subscriptions: Subscription[] = [];
private singleClickStreamSub: Subscription; private singleClickStreamSub: Subscription;
private multiClickStreamSub: Subscription; private multiClickStreamSub: Subscription;
@@ -172,6 +173,13 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck
} }
ngAfterContentInit() { ngAfterContentInit() {
if (this.columnList) {
this.subscriptions.push(
this.columnList.columns.changes.subscribe(() => {
this.setTableSchema();
})
);
}
this.setTableSchema(); this.setTableSchema();
} }
@@ -258,9 +266,11 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck
private unsubscribeClickStream() { private unsubscribeClickStream() {
if (this.singleClickStreamSub) { if (this.singleClickStreamSub) {
this.singleClickStreamSub.unsubscribe(); this.singleClickStreamSub.unsubscribe();
this.singleClickStreamSub = null;
} }
if (this.multiClickStreamSub) { if (this.multiClickStreamSub) {
this.multiClickStreamSub.unsubscribe(); this.multiClickStreamSub.unsubscribe();
this.multiClickStreamSub = null;
} }
} }
@@ -590,4 +600,10 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck
}); });
this.elementRef.nativeElement.dispatchEvent(domEvent); this.elementRef.nativeElement.dispatchEvent(domEvent);
} }
ngOnDestroy() {
this.unsubscribeClickStream();
this.subscriptions.forEach(s => s.unsubscribe());
this.subscriptions = [];
}
} }