mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
DocumentList - Check permissions on delete folder/file (#1808)
* Add check permission on delete folder/file * Provide a way to disable the action when if there is no permission * Improve the code using the external permission inside the folder/document action service * Add basic documentation. - How disable the button when the permission is missing - How to show a notification message when the permission is missing * Resize the image * Change the value to true for demo purpose * Update folder-actions.service.ts * Update document-actions.service.ts
This commit is contained in:
parent
ab3d18e5c1
commit
f6102dfc07
@ -70,7 +70,10 @@
|
||||
</content-action>
|
||||
<content-action
|
||||
target="folder"
|
||||
permission="delete"
|
||||
[disableWithNoPermission]="true"
|
||||
title="{{'DOCUMENT_LIST.ACTIONS.FOLDER.DELETE' | translate}}"
|
||||
(permissionEvent)="onPermissionsFailed($event)"
|
||||
handler="delete">
|
||||
</content-action>
|
||||
<!-- document actions -->
|
||||
@ -91,6 +94,9 @@
|
||||
</content-action>
|
||||
<content-action
|
||||
target="document"
|
||||
permission="delete"
|
||||
[disableWithNoPermission]="true"
|
||||
(permissionEvent)="onPermissionsFailed($event)"
|
||||
title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.DELETE' | translate}}"
|
||||
handler="delete">
|
||||
</content-action>
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { Component, OnInit, AfterViewInit, Optional, ViewChild, ViewChildren, ChangeDetectorRef } from '@angular/core';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { AlfrescoAuthenticationService, LogService } from 'ng2-alfresco-core';
|
||||
import { AlfrescoAuthenticationService, LogService, NotificationService } from 'ng2-alfresco-core';
|
||||
import { DocumentActionsService, DocumentListComponent, ContentActionHandler, DocumentActionModel, FolderActionModel } from 'ng2-alfresco-documentlist';
|
||||
import { FormService } from 'ng2-activiti-form';
|
||||
import { UploadButtonComponent, UploadDragAreaComponent } from 'ng2-alfresco-upload';
|
||||
@ -55,6 +55,7 @@ export class FilesComponent implements OnInit, AfterViewInit {
|
||||
private logService: LogService,
|
||||
private changeDetector: ChangeDetectorRef,
|
||||
private router: Router,
|
||||
private notificationService: NotificationService,
|
||||
@Optional() private route: ActivatedRoute) {
|
||||
documentActions.setHandler('my-handler', this.myDocumentActionHandler.bind(this));
|
||||
}
|
||||
@ -168,6 +169,10 @@ export class FilesComponent implements OnInit, AfterViewInit {
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
onPermissionsFailed(event: any) {
|
||||
this.notificationService.openSnackMessage(`you don't have the ${event.permission} permission to ${event.action} the ${event.type} `, 4000);
|
||||
}
|
||||
|
||||
reload(event: any) {
|
||||
if (event && event.value && event.value.entry && event.value.entry.parentId) {
|
||||
if (this.documentList.currentFolderId === event.value.entry.parentId) {
|
||||
|
@ -34,14 +34,14 @@
|
||||
[class.alfresco-datatable__row--selected]="selectedRow === row"
|
||||
[adf-upload]="allowDropFiles" [adf-upload-data]="row">
|
||||
|
||||
<!-- Actions (right) -->
|
||||
<!-- Actions (left) -->
|
||||
<td *ngIf="actions && actionsPosition === 'left'" class="alfresco-datatable__actions-cell">
|
||||
<button [id]="'action_menu_' + idx" alfresco-mdl-button class="mdl-button--icon" [attr.data-automation-id]="actions_menu">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<ul alfresco-mdl-menu class="mdl-menu--bottom-left"
|
||||
[attr.for]="'action_menu_' + idx">
|
||||
<li class="mdl-menu__item"
|
||||
<li class="mdl-menu__item" [attr.disabled]="action.disabled"
|
||||
[attr.data-automation-id]="action.title"
|
||||
*ngFor="let action of getRowActions(row)"
|
||||
(click)="onExecuteRowAction(row, action)">
|
||||
@ -90,7 +90,7 @@
|
||||
</button>
|
||||
<ul alfresco-mdl-menu class="mdl-menu--bottom-right"
|
||||
[attr.for]="'action_menu_' + idx">
|
||||
<li class="mdl-menu__item"
|
||||
<li class="mdl-menu__item" [attr.disabled]="action.disabled"
|
||||
[attr.data-automation-id]="action.title"
|
||||
*ngFor="let action of getRowActions(row)"
|
||||
(click)="onExecuteRowAction(row, action)">
|
||||
|
@ -414,4 +414,87 @@ describe('DataTable', () => {
|
||||
dataTable.onImageLoadingError(event);
|
||||
expect(event.target.src).toBe(originalSrc);
|
||||
});
|
||||
|
||||
it('should disable the action if there is no permission and disableWithNoPermission true', () => {
|
||||
|
||||
dataTable.data = new ObjectDataTableAdapter(
|
||||
[{id: 1, name: 'xyz', allowableOperations: ['create', 'update']}],
|
||||
[]
|
||||
);
|
||||
|
||||
let row = dataTable.data.getRows();
|
||||
let actions = [
|
||||
{
|
||||
disableWithNoPermission: true,
|
||||
permission: 'delete',
|
||||
target: 'folder',
|
||||
title: 'action2'
|
||||
}
|
||||
];
|
||||
|
||||
let updateActions = dataTable.checkPermissions(row[0], actions);
|
||||
expect(updateActions[0].disabled).toBe(true);
|
||||
});
|
||||
|
||||
it('should not disable the action if there is no permission and disableWithNoPermission false', () => {
|
||||
|
||||
dataTable.data = new ObjectDataTableAdapter(
|
||||
[{id: 1, name: 'xyz', allowableOperations: ['create', 'update']}],
|
||||
[]
|
||||
);
|
||||
|
||||
let row = dataTable.data.getRows();
|
||||
let actions = [
|
||||
{
|
||||
disableWithNoPermission: false,
|
||||
permission: 'delete',
|
||||
target: 'folder',
|
||||
title: 'action2'
|
||||
}
|
||||
];
|
||||
|
||||
let updateActions = dataTable.checkPermissions(row[0], actions);
|
||||
expect(updateActions[0].disabled).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not disable the action if there is the right permission', () => {
|
||||
|
||||
dataTable.data = new ObjectDataTableAdapter(
|
||||
[{ id: 1, name: 'xyz', allowableOperations: ['create', 'update', 'delete'] }],
|
||||
[]
|
||||
);
|
||||
|
||||
let row = dataTable.data.getRows();
|
||||
let actions = [
|
||||
{
|
||||
permission: 'delete',
|
||||
target: 'folder',
|
||||
title: 'action2'
|
||||
}
|
||||
];
|
||||
|
||||
let updateActions = dataTable.checkPermissions(row[0], actions);
|
||||
expect(updateActions[0].disabled).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not disable the action if there are no permissions', () => {
|
||||
|
||||
dataTable.data = new ObjectDataTableAdapter(
|
||||
[{id: 1, name: 'xyz', allowableOperations: null}],
|
||||
[]
|
||||
);
|
||||
|
||||
let row = dataTable.data.getRows();
|
||||
let actions = [
|
||||
{
|
||||
permission: 'delete',
|
||||
target: 'folder',
|
||||
title: 'action2'
|
||||
}
|
||||
];
|
||||
|
||||
let updateActions = dataTable.checkPermissions(row[0], actions);
|
||||
expect(updateActions[0].disabled).toBeUndefined();
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -236,10 +236,40 @@ export class DataTableComponent implements AfterContentInit, OnChanges {
|
||||
getRowActions(row: DataRow, col: DataColumn): any[] {
|
||||
let event = new DataCellEvent(row, col, []);
|
||||
this.showRowActionsMenu.emit(event);
|
||||
return event.value.actions;
|
||||
|
||||
return this.checkPermissions(row, event.value.actions);
|
||||
}
|
||||
|
||||
checkPermissions(row: DataRow, actions: any[]) {
|
||||
let actionsPermission = [];
|
||||
actions.forEach((action) => {
|
||||
actionsPermission.push(this.checkPermission(row, action));
|
||||
});
|
||||
return actionsPermission;
|
||||
}
|
||||
|
||||
checkPermission(row: DataRow, action) {
|
||||
if (action.permission) {
|
||||
if (this.hasPermissions(row)) {
|
||||
let permissions = row.getValue('allowableOperations');
|
||||
let findPermission = permissions.find(permission => permission === action.permission);
|
||||
if (!findPermission && action.disableWithNoPermission === true) {
|
||||
action.disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
private hasPermissions(row: DataRow): boolean {
|
||||
return row.getValue('allowableOperations') ? true : false;
|
||||
}
|
||||
|
||||
onExecuteRowAction(row: DataRow, action: any) {
|
||||
if (action.disabled) {
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
this.executeRowAction.emit(new DataRowActionEvent(row, action));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -612,6 +612,61 @@ The following action handlers are provided out-of-box:
|
||||
All system handler names are case-insensitive, `handler="download"` and `handler="DOWNLOAD"`
|
||||
will trigger the same `download` action.
|
||||
|
||||
##### Delete - Show notification message with no permission
|
||||
You can show a notification error when the user don't have the right permission to perform the action.
|
||||
The ContentActionComponent provides the event permissionEvent that is raised when the permission specified in the permission property is missing
|
||||
You can subscribe to this event from your component and use the NotificationService to show a message.
|
||||
|
||||
```html
|
||||
<alfresco-document-list ...>
|
||||
<content-actions>
|
||||
|
||||
<content-action
|
||||
target="document"
|
||||
title="Delete"
|
||||
permission="delete"
|
||||
(permissionEvent)="onPermissionsFailed($event)"
|
||||
handler="delete">
|
||||
</content-action>
|
||||
|
||||
</content-actions>
|
||||
</alfresco-document-list>
|
||||
|
||||
|
||||
export class MyComponent {
|
||||
|
||||
onPermissionsFailed(event: any) {
|
||||
this.notificationService.openSnackMessage(`you don't have the ${event.permission} permission to ${event.action} the ${event.type} `, 4000);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
##### Delete - Disable button checking the permission
|
||||
You can easily disable a button when the user doesn't own the permission to perform the action related to the button.
|
||||
The ContentActionComponent provides the property permission that must contain the permission to check and a property disableWithNoPermission that can be true if
|
||||
you want see the button disabled.
|
||||
|
||||
```html
|
||||
<alfresco-document-list ...>
|
||||
<content-actions>
|
||||
|
||||
<content-action
|
||||
target="document"
|
||||
title="Delete"
|
||||
permission="delete"
|
||||
disableWithNoPermission="true"
|
||||
handler="delete">
|
||||
</content-action>
|
||||
|
||||
</content-actions>
|
||||
</alfresco-document-list>
|
||||
```
|
||||
|
||||

|
||||
|
||||
##### Download
|
||||
|
||||
Initiates download of the corresponding document file.
|
||||
@ -632,7 +687,6 @@ Initiates download of the corresponding document file.
|
||||
|
||||

|
||||
|
||||
|
||||
#### Folder actions
|
||||
|
||||
Folder actions have the same declaration as document actions except ```taget="folder"``` attribute value.
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 133 KiB |
Binary file not shown.
After Width: | Height: | Size: 173 KiB |
@ -53,6 +53,7 @@ export * from './src/services/document-list.service';
|
||||
// models
|
||||
export * from './src/models/content-action.model';
|
||||
export * from './src/models/document-library.model';
|
||||
export * from './src/models/permissions.model';
|
||||
|
||||
export const DOCUMENT_LIST_DIRECTIVES: any[] = [
|
||||
DocumentListComponent,
|
||||
|
@ -41,9 +41,18 @@ export class ContentActionComponent implements OnInit, OnChanges {
|
||||
@Input()
|
||||
target: string;
|
||||
|
||||
@Input()
|
||||
permission: string;
|
||||
|
||||
@Input()
|
||||
disableWithNoPermission: boolean;
|
||||
|
||||
@Output()
|
||||
execute = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
permissionEvent = new EventEmitter();
|
||||
|
||||
model: ContentActionModel;
|
||||
|
||||
constructor(
|
||||
@ -57,6 +66,8 @@ export class ContentActionComponent implements OnInit, OnChanges {
|
||||
this.model = new ContentActionModel({
|
||||
title: this.title,
|
||||
icon: this.icon,
|
||||
permission: this.permission,
|
||||
disableWithNoPermission: this.disableWithNoPermission,
|
||||
target: this.target
|
||||
});
|
||||
|
||||
@ -98,6 +109,9 @@ export class ContentActionComponent implements OnInit, OnChanges {
|
||||
|
||||
if (ltarget === 'folder') {
|
||||
if (this.folderActions) {
|
||||
this.folderActions.permissionEvent.subscribe((permision) => {
|
||||
this.permissionEvent.emit(permision);
|
||||
});
|
||||
return this.folderActions.getHandler(name);
|
||||
}
|
||||
return null;
|
||||
|
@ -86,7 +86,22 @@ describe('DocumentList', () => {
|
||||
spyOn(action, 'handler').and.stub();
|
||||
|
||||
documentList.executeContentAction(node, action);
|
||||
expect(action.handler).toHaveBeenCalledWith(node, documentList);
|
||||
expect(action.handler).toHaveBeenCalledWith(node, documentList, undefined);
|
||||
|
||||
});
|
||||
|
||||
it('should execute action with node and permission', () => {
|
||||
let node = new FileNode();
|
||||
let action = new ContentActionModel();
|
||||
action.handler = function () {
|
||||
console.log('mock handler');
|
||||
};
|
||||
action.permission = 'fake-permission';
|
||||
|
||||
spyOn(action, 'handler').and.stub();
|
||||
|
||||
documentList.executeContentAction(node, action);
|
||||
expect(action.handler).toHaveBeenCalledWith(node, documentList, 'fake-permission');
|
||||
|
||||
});
|
||||
|
||||
|
@ -306,7 +306,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
|
||||
*/
|
||||
executeContentAction(node: MinimalNodeEntity, action: ContentActionModel) {
|
||||
if (node && node.entry && action) {
|
||||
action.handler(node, this);
|
||||
action.handler(node, this, action.permission);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { PermissionModel } from './../models/permissions.model';
|
||||
|
||||
export class PermissionErrorEvent {
|
||||
|
||||
readonly error: PermissionModel;
|
||||
|
||||
constructor(error: PermissionModel) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
}
|
@ -20,6 +20,8 @@ export class ContentActionModel {
|
||||
title: string;
|
||||
handler: ContentActionHandler;
|
||||
target: string;
|
||||
permission: string;
|
||||
disableWithNoPermission: boolean;
|
||||
|
||||
constructor(obj?: any) {
|
||||
if (obj) {
|
||||
@ -27,12 +29,14 @@ export class ContentActionModel {
|
||||
this.title = obj.title;
|
||||
this.handler = obj.handler;
|
||||
this.target = obj.target;
|
||||
this.permission = obj.permission;
|
||||
this.disableWithNoPermission = obj.disableWithNoPermission;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface ContentActionHandler {
|
||||
(obj: any, target?: any): any;
|
||||
(obj: any, target?: any, permission?: string): any;
|
||||
}
|
||||
|
||||
export class DocumentActionModel extends ContentActionModel {
|
||||
|
@ -0,0 +1,30 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class PermissionModel {
|
||||
type: string;
|
||||
action: string;
|
||||
permission: string;
|
||||
|
||||
constructor(obj?: any) {
|
||||
if (obj) {
|
||||
this.type = obj.type || null;
|
||||
this.action = obj.action || null;
|
||||
this.permission = obj.permission || null;
|
||||
}
|
||||
}
|
||||
}
|
@ -101,6 +101,62 @@ describe('DocumentActionsService', () => {
|
||||
expect(service.getHandler('delete')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not delete the file node if there are no permissions', (done) => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
service.permissionEvent.subscribe((permission) => {
|
||||
expect(permission).toBeDefined();
|
||||
expect(permission.type).toEqual('content');
|
||||
expect(permission.action).toEqual('delete');
|
||||
done();
|
||||
});
|
||||
|
||||
let file = new FileNode();
|
||||
service.getHandler('delete')(file);
|
||||
|
||||
});
|
||||
|
||||
it('should delete the file node if there is the delete permission', () => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
let permission = 'delete';
|
||||
let file = new FileNode();
|
||||
let fileWithPermission: any = file;
|
||||
fileWithPermission.entry.allowableOperations = [permission];
|
||||
service.getHandler('delete')(fileWithPermission, null, permission);
|
||||
|
||||
expect(documentListService.deleteNode).toHaveBeenCalledWith(file.entry.id);
|
||||
});
|
||||
|
||||
it('should not delete the file node if there is no delete permission', (done) => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
service.permissionEvent.subscribe((permission) => {
|
||||
expect(permission).toBeDefined();
|
||||
expect(permission.type).toEqual('content');
|
||||
expect(permission.action).toEqual('delete');
|
||||
done();
|
||||
});
|
||||
|
||||
let permission = 'delete';
|
||||
let file = new FileNode();
|
||||
let fileWithPermission: any = file;
|
||||
fileWithPermission.entry.allowableOperations = ['create', 'update'];
|
||||
service.getHandler('delete')(fileWithPermission, null, permission);
|
||||
});
|
||||
|
||||
it('should delete the file node if there is the delete and others permission ', () => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
let permission = 'delete';
|
||||
let file = new FileNode();
|
||||
let fileWithPermission: any = file;
|
||||
fileWithPermission.entry.allowableOperations = ['create', 'update', permission];
|
||||
service.getHandler('delete')(fileWithPermission, null, permission);
|
||||
|
||||
expect(documentListService.deleteNode).toHaveBeenCalledWith(file.entry.id);
|
||||
});
|
||||
|
||||
it('should register download action', () => {
|
||||
expect(service.getHandler('download')).toBeDefined();
|
||||
});
|
||||
@ -152,8 +208,11 @@ describe('DocumentActionsService', () => {
|
||||
it('should delete file node', () => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
let permission = 'delete';
|
||||
let file = new FileNode();
|
||||
service.getHandler('delete')(file);
|
||||
let fileWithPermission: any = file;
|
||||
fileWithPermission.entry.allowableOperations = [permission];
|
||||
service.getHandler('delete')(fileWithPermission, null, permission);
|
||||
|
||||
expect(documentListService.deleteNode).toHaveBeenCalledWith(file.entry.id);
|
||||
});
|
||||
@ -165,8 +224,11 @@ describe('DocumentActionsService', () => {
|
||||
service.getHandler('delete')(folder);
|
||||
expect(documentListService.deleteNode).not.toHaveBeenCalled();
|
||||
|
||||
let permission = 'delete';
|
||||
let file = new FileNode();
|
||||
service.getHandler('delete')(file);
|
||||
let fileWithPermission: any = file;
|
||||
fileWithPermission.entry.allowableOperations = [permission];
|
||||
service.getHandler('delete')(fileWithPermission, null, permission);
|
||||
expect(documentListService.deleteNode).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -184,8 +246,11 @@ describe('DocumentActionsService', () => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
let target = jasmine.createSpyObj('obj', ['reload']);
|
||||
let permission = 'delete';
|
||||
let file = new FileNode();
|
||||
service.getHandler('delete')(file, target);
|
||||
let fileWithPermission: any = file;
|
||||
fileWithPermission.entry.allowableOperations = [permission];
|
||||
service.getHandler('delete')(fileWithPermission, target, permission);
|
||||
|
||||
expect(documentListService.deleteNode).toHaveBeenCalled();
|
||||
expect(target.reload).toHaveBeenCalled();
|
||||
|
@ -19,9 +19,14 @@ import { Injectable } from '@angular/core';
|
||||
import { ContentActionHandler } from '../models/content-action.model';
|
||||
import { DocumentListService } from './document-list.service';
|
||||
import { AlfrescoContentService } from 'ng2-alfresco-core';
|
||||
import { PermissionModel } from '../models/permissions.model';
|
||||
import { Subject } from 'rxjs/Rx';
|
||||
|
||||
@Injectable()
|
||||
export class DocumentActionsService {
|
||||
|
||||
permissionEvent: Subject<PermissionModel> = new Subject<PermissionModel>();
|
||||
|
||||
private handlers: { [id: string]: ContentActionHandler; } = {};
|
||||
|
||||
constructor(private documentListService?: DocumentListService,
|
||||
@ -82,13 +87,28 @@ export class DocumentActionsService {
|
||||
return false;
|
||||
}
|
||||
|
||||
private deleteNode(obj: any, target?: any) {
|
||||
if (this.canExecuteAction(obj) && obj.entry && obj.entry.id) {
|
||||
private deleteNode(obj: any, target?: any, permission?: string) {
|
||||
if (this.canExecuteAction(obj)) {
|
||||
if (this.hasPermission(obj.entry, permission)) {
|
||||
this.documentListService.deleteNode(obj.entry.id).subscribe(() => {
|
||||
if (target && typeof target.reload === 'function') {
|
||||
target.reload();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.permissionEvent.next(new PermissionModel({type: 'content', action: 'delete', permission: permission}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private hasPermission(node: any, permission: string): boolean {
|
||||
if (this.hasPermissions(node)) {
|
||||
return node.allowableOperations.find(permision => permision === permission) ? true : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private hasPermissions(node: any): boolean {
|
||||
return node && node.allowableOperations ? true : false;
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ export class DocumentListService {
|
||||
|
||||
let params: any = {
|
||||
includeSource: true,
|
||||
include: ['path', 'properties']
|
||||
include: ['path', 'properties', 'allowableOperations']
|
||||
};
|
||||
|
||||
if (folder) {
|
||||
@ -121,7 +121,7 @@ export class DocumentListService {
|
||||
getFolderNode(nodeId: string): Promise<MinimalNodeEntryEntity> {
|
||||
let opts: any = {
|
||||
includeSource: true,
|
||||
include: ['path', 'properties']
|
||||
include: ['path', 'properties', 'allowableOperations']
|
||||
};
|
||||
|
||||
let nodes: any = this.apiService.getInstance().nodes;
|
||||
|
@ -97,24 +97,73 @@ describe('FolderActionsService', () => {
|
||||
expect(service.getHandler('delete')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should delete folder node', () => {
|
||||
it('should not delete the folder node if there are no permissions', (done) => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
service.permissionEvent.subscribe((permission) => {
|
||||
expect(permission).toBeDefined();
|
||||
expect(permission.type).toEqual('folder');
|
||||
expect(permission.action).toEqual('delete');
|
||||
done();
|
||||
});
|
||||
|
||||
let folder = new FolderNode();
|
||||
service.getHandler('delete')(folder);
|
||||
|
||||
});
|
||||
|
||||
it('should delete the folder node if there is the delete permission', () => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
let permission = 'delete';
|
||||
let folder = new FolderNode();
|
||||
let folderWithPermission: any = folder;
|
||||
folderWithPermission.entry.allowableOperations = [ permission ];
|
||||
service.getHandler('delete')(folderWithPermission, null, permission);
|
||||
|
||||
expect(documentListService.deleteNode).toHaveBeenCalledWith(folder.entry.id);
|
||||
});
|
||||
|
||||
it('should not delete the folder node if there is no delete permission', (done) => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
service.permissionEvent.subscribe((permission) => {
|
||||
expect(permission).toBeDefined();
|
||||
expect(permission.type).toEqual('folder');
|
||||
expect(permission.action).toEqual('delete');
|
||||
done();
|
||||
});
|
||||
|
||||
let folder = new FolderNode();
|
||||
let folderWithPermission: any = folder;
|
||||
folderWithPermission.entry.allowableOperations = ['create', 'update'];
|
||||
service.getHandler('delete')(folderWithPermission);
|
||||
});
|
||||
|
||||
it('should delete the folder node if there is the delete and others permission ', () => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
let permission = 'delete';
|
||||
let folder = new FolderNode();
|
||||
let folderWithPermission: any = folder;
|
||||
folderWithPermission.entry.allowableOperations = ['create', 'update', permission];
|
||||
service.getHandler('delete')(folderWithPermission, null, permission);
|
||||
|
||||
expect(documentListService.deleteNode).toHaveBeenCalledWith(folder.entry.id);
|
||||
});
|
||||
|
||||
it('should support deletion only folder node', () => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
let permission = 'delete';
|
||||
let file = new FileNode();
|
||||
service.getHandler('delete')(file);
|
||||
expect(documentListService.deleteNode).not.toHaveBeenCalled();
|
||||
|
||||
let folder = new FolderNode();
|
||||
service.getHandler('delete')(folder);
|
||||
let folderWithPermission: any = folder;
|
||||
folderWithPermission.entry.allowableOperations = [permission];
|
||||
service.getHandler('delete')(folderWithPermission, null, permission);
|
||||
expect(documentListService.deleteNode).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -131,9 +180,13 @@ describe('FolderActionsService', () => {
|
||||
it('should reload target upon node deletion', () => {
|
||||
spyOn(documentListService, 'deleteNode').and.callThrough();
|
||||
|
||||
let permission = 'delete';
|
||||
let target = jasmine.createSpyObj('obj', ['reload']);
|
||||
let folder = new FolderNode();
|
||||
service.getHandler('delete')(folder, target);
|
||||
let folderWithPermission: any = folder;
|
||||
folderWithPermission.entry.allowableOperations = [permission];
|
||||
|
||||
service.getHandler('delete')(folderWithPermission, target, permission);
|
||||
|
||||
expect(documentListService.deleteNode).toHaveBeenCalled();
|
||||
expect(target.reload).toHaveBeenCalled();
|
||||
|
@ -17,10 +17,15 @@
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ContentActionHandler } from '../models/content-action.model';
|
||||
import { PermissionModel } from '../models/permissions.model';
|
||||
import { DocumentListService } from './document-list.service';
|
||||
import { Subject } from 'rxjs/Rx';
|
||||
|
||||
@Injectable()
|
||||
export class FolderActionsService {
|
||||
|
||||
permissionEvent: Subject<PermissionModel> = new Subject<PermissionModel>();
|
||||
|
||||
private handlers: { [id: string]: ContentActionHandler; } = {};
|
||||
|
||||
constructor(private documentListService?: DocumentListService) {
|
||||
@ -66,13 +71,28 @@ export class FolderActionsService {
|
||||
window.alert('standard folder action 2');
|
||||
}
|
||||
|
||||
private deleteNode(obj: any, target?: any) {
|
||||
if (this.canExecuteAction(obj) && obj.entry && obj.entry.id) {
|
||||
private deleteNode(obj: any, target?: any, permission?: string) {
|
||||
if (this.canExecuteAction(obj)) {
|
||||
if (this.hasPermission(obj.entry, permission)) {
|
||||
this.documentListService.deleteNode(obj.entry.id).subscribe(() => {
|
||||
if (target && typeof target.reload === 'function') {
|
||||
target.reload();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.permissionEvent.next(new PermissionModel({type: 'folder', action: 'delete', permission: permission}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private hasPermission(node: any, permissionToCheck: string): boolean {
|
||||
if (this.hasPermissions(node)) {
|
||||
return node.allowableOperations.find(permision => permision === permissionToCheck) ? true : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private hasPermissions(node: any): boolean {
|
||||
return node && node.allowableOperations ? true : false;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user