mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-2503] conditional visibility for content actions (#3325)
* conditional visibility for content actions * fix typo * workaround for "target: all"
This commit is contained in:
committed by
Eugenio Romano
parent
7154eb1e84
commit
d67f160fdc
@@ -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 () {
|
||||
|
@@ -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 {
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user