[ADF-2859] fixes for the conditional visibility and disabled states (#3465)

* fixes for the conditional visibility and disabled states

* update docs

* cleanup code

* remove unused code
This commit is contained in:
Denys Vuika
2018-06-11 12:53:09 +01:00
committed by Eugenio Romano
parent 1d69f5c407
commit 6f2cbdf697
9 changed files with 89 additions and 84 deletions

View File

@@ -279,13 +279,13 @@
</data-columns>
<content-actions>
<!-- Conditional actions demo -->
<content-action
target="all"
title="Action for 'custom' node"
[disabled]="isCustomActionDisabled"
(execute)="runCustomAction($event)">
</content-action>
<!-- Conditional actions demo -->
<content-action
icon="get_app"
title="Download this file now!"
@@ -298,12 +298,6 @@
handler="download"
[visible]="false">
</content-action>
<content-action
icon="get_app"
title="This can be toggled"
handler="download"
[visible]="showCustomDownloadAction">
</content-action>
<!-- common actions -->
<content-action
icon="get_app"
@@ -448,12 +442,6 @@
</mat-slide-toggle>
</section>
<section>
<mat-slide-toggle color="primary" [(ngModel)]="showCustomDownloadAction">
Toggle custom download action
</mat-slide-toggle>
</section>
<section>
<mat-slide-toggle [color]="'primary'" [(ngModel)]="multiselect">{{'DOCUMENT_LIST.MULTISELECT_CHECKBOXES' |
translate}}

View File

@@ -170,9 +170,6 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
@ViewChild(InfinitePaginationComponent)
infinitePaginationComponent: InfinitePaginationComponent;
@Input()
showCustomDownloadAction = false;
permissionsStyle: PermissionStyleModel[] = [];
infiniteScrolling: boolean;
supportedPages: number[];
@@ -514,7 +511,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
}
canDownloadNode = (node: MinimalNodeEntity): boolean => {
if (node && node.entry && node.entry.name === 'For Sale.docx') {
if (node && node.entry && node.entry.name === 'custom') {
return true;
}
return false;

View File

@@ -324,12 +324,10 @@ allow the item being copied/moved to be the destination if it is itself a folder
### Conditional visibility
The Content-action component allows you to control visibility with the help of the `visible`
property which can receive its value in three main ways:
The `<content-action>` component allows you to control visibility with the help of the `visible` property and supports the following scenarios:
- direct `boolean` value
- binding to a `boolean` property
- binding to a `Function` property that evaluates the condition and returns a `boolean` value
- direct value of `boolean` type
- binding to a property of the `Function` type that evaluates condition and returns `boolean` value
#### Using direct boolean value
@@ -342,30 +340,7 @@ property which can receive its value in three main ways:
</content-action>
```
#### Binding to a boolean property
```html
<content-action
icon="get_app"
title="This can be toggled"
handler="download"
[visible]="showCustomDownloadAction">
</content-action>
```
The markup above relies on the `showCustomDownloadAction` property declared in your
component class:
```ts
export class MyComponent {
@Input()
showCustomDownloadAction = true;
}
```
#### Binding to a Function property
#### Using a property of the Function type
```html
<content-action
@@ -409,7 +384,6 @@ funcName = (parameters): boolean => {
Similar to `visible` property, it is possible to control the `disabled` state with the following scenarios:
- direct value of `boolean` type
- binding to a property of the `boolean` type
- binding to a property of the `Function` type that evaluates condition and returns `boolean` value
#### Using direct value of boolean type
@@ -423,28 +397,6 @@ Similar to `visible` property, it is possible to control the `disabled` state wi
</content-action>
```
#### Using a property of the boolean type
```html
<content-action
target="all"
title="Action for 'custom' node"
[disabled]="shouldDisableAction"
(execute)="runCustomAction($event)">
</content-action>
```
The markup above relies on the `shouldDisableAction` property declared at your component class level:
```ts
export class MyComponent {
@Input()
shouldDisableAction = true;
}
```
#### Using a property of the Function type
```html

View File

@@ -42,4 +42,15 @@ export class ContentActionListComponent {
}
return false;
}
unregisterAction(action: ContentActionModel): boolean {
if (this.documentList && action) {
const idx = this.documentList.actions.indexOf(action);
if (idx >= 0) {
this.documentList.actions.splice(idx, 1);
return true;
}
}
return false;
}
}

View File

@@ -132,9 +132,16 @@ export class ContentActionComponent implements OnInit, OnChanges, OnDestroy {
this.subscriptions.forEach(subscription => subscription.unsubscribe());
this.subscriptions = [];
if (this.documentActionModel) {
this.unregister(this.documentActionModel);
this.documentActionModel = null;
}
if (this.folderActionModel) {
this.unregister(this.folderActionModel);
this.folderActionModel = null;
}
}
register(model: ContentActionModel): boolean {
if (this.list) {
@@ -143,6 +150,13 @@ export class ContentActionComponent implements OnInit, OnChanges, OnDestroy {
return false;
}
unregister(model: ContentActionModel): boolean {
if (this.list) {
return this.list.unregisterAction(model);
}
return false;
}
private generateAction(target: string): ContentActionModel {
const model = new ContentActionModel({
title: this.title,

View File

@@ -13,6 +13,7 @@
[display]="display"
[noPermission]="noPermission"
[showHeader]="!isEmpty() && showHeader"
[rowMenuCacheEnabled]="false"
(showRowContextMenu)="onShowRowContextMenu($event)"
(showRowActionsMenu)="onShowRowActionsMenu($event)"
(executeRowAction)="onExecuteRowAction($event)"

View File

@@ -236,6 +236,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
private _pagination: BehaviorSubject<PaginationModel>;
private layoutPresets = {};
private subscriptions: Subscription[] = [];
private rowMenuCache: { [key: string]: ContentActionModel[] } = {};
constructor(private documentListService: DocumentListService,
private ngZone: NgZone,
@@ -333,6 +334,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
ngOnInit() {
this.rowMenuCache = {};
this.loadLayoutPresets();
this.data = new ShareDataTableAdapter(this.documentListService, this.thumbnailService, null, this.getDefaultSorting(), this.sortingMode);
this.data.thumbnails = this.thumbnails;
@@ -444,9 +446,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
getNodeActions(node: MinimalNodeEntity | any): ContentActionModel[] {
let target = null;
if (node && node.entry) {
let target = null;
if (node.entry.isFile) {
target = 'document';
} else if (node.entry.isFolder) {
@@ -454,6 +457,14 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
if (target) {
const actions = this.rowMenuCache[node.entry.id];
if (actions) {
actions.forEach(action => {
this.refreshAction(action, node);
});
return actions;
}
let actionsByTarget = this.actions
.filter(entry => {
const isVisible = (typeof entry.visible === 'function')
@@ -465,9 +476,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
.map(action => new ContentActionModel(action));
actionsByTarget.forEach((action) => {
action.disabled = this.isActionDisabled(action, node);
this.refreshAction(action, node);
});
this.rowMenuCache[node.entry.id] = actionsByTarget;
return actionsByTarget;
}
}
@@ -475,6 +487,19 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
return [];
}
private refreshAction(action: ContentActionModel, node: MinimalNodeEntity) {
action.disabled = this.isActionDisabled(action, node);
action.visible = this.isActionVisible(action, node);
}
private isActionVisible(action: ContentActionModel, node: MinimalNodeEntity): boolean {
if (typeof action.visible === 'function') {
return action.visible(node);
}
return action.visible;
}
private isActionDisabled(action: ContentActionModel, node: MinimalNodeEntity): boolean {
if (typeof action.disabled === 'function') {
return action.disabled(node);
@@ -484,7 +509,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
return true;
}
return false;
return action.disabled;
}
@HostListener('contextmenu', ['$event'])

View File

@@ -29,13 +29,15 @@ import { ContextMenuService } from './context-menu.service';
template: `
<button mat-button [matMenuTriggerFor]="contextMenu"></button>
<mat-menu #contextMenu="matMenu" class="context-menu">
<button *ngFor="let link of links"
<ng-container *ngFor="let link of links">
<button *ngIf="link.model?.visible"
mat-menu-item
[disabled]="link.model?.disabled"
(click)="onMenuItemClick($event, link)">
<mat-icon *ngIf="showIcons && link.model?.icon">{{ link.model.icon }}</mat-icon>
{{ (link.title || link.model?.title) | translate }}
</button>
</ng-container>
</mat-menu>
`
})

View File

@@ -155,6 +155,9 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
@Input()
noPermission: boolean = false;
@Input()
rowMenuCacheEnabled = true;
noContentTemplate: TemplateRef<any>;
noPermissionTemplate: TemplateRef<any>;
loadingTemplate: TemplateRef<any>;
@@ -166,6 +169,8 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
private click$: Observable<DataRowEvent>;
private differ: any;
private rowMenuCache: object = {};
private subscriptions: Subscription[] = [];
private singleClickStreamSub: Subscription;
private multiClickStreamSub: Subscription;
@@ -297,6 +302,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
private initTable() {
this.data = new ObjectDataTableAdapter(this.rows, this.columns);
this.setupData(this.data);
this.rowMenuCache = {};
}
private setupData(adapter: DataTableAdapter) {
@@ -553,10 +559,19 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
}
getRowActions(row: DataRow, col: DataColumn): any[] {
const id = row.getValue('id');
if (!this.rowMenuCache[id]) {
let event = new DataCellEvent(row, col, []);
this.showRowActionsMenu.emit(event);
if (!this.rowMenuCacheEnabled) {
return event.value.actions;
}
this.rowMenuCache[id] = event.value.actions;
}
return this.rowMenuCache[id];
}
onExecuteRowAction(row: DataRow, action: any) {
if (action.disabled || action.disabled) {