[ADF-2503] conditional visibility for content actions (#3325)

* conditional visibility for content actions

* fix typo

* workaround for "target: all"
This commit is contained in:
Denys Vuika
2018-05-15 16:53:52 +01:00
committed by Eugenio Romano
parent 7154eb1e84
commit d67f160fdc
8 changed files with 216 additions and 13 deletions

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core';
import { EventEmitter } from '@angular/core';
import { async, TestBed } from '@angular/core/testing';
import { ContentService, setupTestBed } from '@alfresco/adf-core';
@@ -81,6 +81,24 @@ describe('ContentAction', () => {
expect(model.icon).toBe(action.icon);
});
it('should update visibility binding', () => {
let action = new ContentActionComponent(actionList, null, null);
action.target = 'document';
action.title = '<title>';
action.icon = '<icon>';
action.visible = true;
action.ngOnInit();
expect(action.documentActionModel.visible).toBeTruthy();
action.visible = false;
action.ngOnChanges({
'visible': new SimpleChange(true, false, false)
});
expect(action.documentActionModel.visible).toBeFalsy();
});
it('should get action handler from document actions service', () => {
let handler = function () {

View File

@@ -17,7 +17,7 @@
/* tslint:disable:component-selector */
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';
import { ContentActionHandler } from '../../models/content-action.model';
import { DocumentActionsService } from '../../services/document-actions.service';
@@ -33,7 +33,7 @@ import { ContentActionListComponent } from './content-action-list.component';
FolderActionsService
]
})
export class ContentActionComponent implements OnInit {
export class ContentActionComponent implements OnInit, OnChanges {
/** The title of the action as shown in the menu. */
@Input()
@@ -43,6 +43,9 @@ export class ContentActionComponent implements OnInit {
@Input()
icon: string;
@Input()
visible: boolean | Function = true;
/** System actions. Can be "delete", "download", "copy" or "move". */
@Input()
handler: string;
@@ -83,6 +86,9 @@ export class ContentActionComponent implements OnInit {
@Output()
success = new EventEmitter();
documentActionModel: ContentActionModel;
folderActionModel: ContentActionModel;
constructor(
private list: ContentActionListComponent,
private documentActions: DocumentActionsService,
@@ -91,10 +97,21 @@ export class ContentActionComponent implements OnInit {
ngOnInit() {
if (this.target === ContentActionTarget.All) {
this.generateAction(ContentActionTarget.Folder);
this.generateAction(ContentActionTarget.Document);
this.folderActionModel = this.generateAction(ContentActionTarget.Folder);
this.documentActionModel = this.generateAction(ContentActionTarget.Document);
} else {
this.generateAction(this.target);
this.documentActionModel = this.generateAction(this.target);
}
}
ngOnChanges(changes: SimpleChanges) {
if (changes.visible && !changes.visible.firstChange) {
if (this.documentActionModel) {
this.documentActionModel.visible = changes.visible.currentValue;
}
if (this.folderActionModel) {
this.folderActionModel.visible = changes.visible.currentValue;
}
}
}
@@ -105,14 +122,15 @@ export class ContentActionComponent implements OnInit {
return false;
}
private generateAction(target: string) {
let model = new ContentActionModel({
private generateAction(target: string): ContentActionModel {
const model = new ContentActionModel({
title: this.title,
icon: this.icon,
permission: this.permission,
disableWithNoPermission: this.disableWithNoPermission,
target: target,
disabled: this.disabled
disabled: this.disabled,
visible: this.visible
});
if (this.handler) {
model.handler = this.getSystemHandler(target, this.handler);
@@ -125,6 +143,7 @@ export class ContentActionComponent implements OnInit {
}
this.register(model);
return model;
}
getSystemHandler(target: string, name: string): ContentActionHandler {

View File

@@ -312,6 +312,48 @@ describe('DocumentList', () => {
});
it('should not display hidden content actions', () => {
documentList.actions = [
new ContentActionModel({
target: 'document',
title: 'Action1',
visible: false
}),
new ContentActionModel({
target: 'document',
title: 'Action2',
visible: true
})
];
const nodeFile = { entry: { isFile: true, name: 'xyz' } };
const actions = documentList.getNodeActions(nodeFile);
expect(actions.length).toBe(1);
expect(actions[0].title).toBe('Action2');
});
it('should evaluate conditional visibility for content actions', () => {
documentList.actions = [
new ContentActionModel({
target: 'document',
title: 'Action1',
visible: (): boolean => true
}),
new ContentActionModel({
target: 'document',
title: 'Action2',
visible: (): boolean => false
})
];
const nodeFile = { entry: { isFile: true, name: 'xyz' } };
const actions = documentList.getNodeActions(nodeFile);
expect(actions.length).toBe(1);
expect(actions[0].title).toBe('Action1');
});
it('should not disable the action if there is copy permission', () => {
let documentMenu = new ContentActionModel({
disableWithNoPermission: true,

View File

@@ -434,9 +434,15 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
if (target) {
let actionsByTarget = this.actions.filter(entry => {
return entry.target.toLowerCase() === target;
}).map(action => new ContentActionModel(action));
let actionsByTarget = this.actions
.filter(entry => {
const isVisible = (typeof entry.visible === 'function')
? entry.visible(node)
: entry.visible;
return isVisible && entry.target.toLowerCase() === target;
})
.map(action => new ContentActionModel(action));
actionsByTarget.forEach((action) => {
this.disableActionsWithNoPermissions(node, action);

View File

@@ -24,6 +24,7 @@ export class ContentActionModel {
permission: string;
disableWithNoPermission: boolean = false;
disabled: boolean = false;
visible: boolean | Function = true;
constructor(obj?: any) {
if (obj) {
@@ -35,6 +36,10 @@ export class ContentActionModel {
this.permission = obj.permission;
this.disableWithNoPermission = obj.disableWithNoPermission;
this.disabled = obj.disabled;
if (obj.hasOwnProperty('visible')) {
this.visible = obj.visible;
}
}
}
}