Disable upload button with no permission (#1820)

* Add the permission check on the activiti button

* Fix code after unit test

* Add basic documentation
This commit is contained in:
Maurizio Vitale
2017-04-20 12:06:10 +01:00
committed by Mario Romano
parent 721e96c01b
commit 0e4dab8b66
11 changed files with 301 additions and 29 deletions

View File

@@ -9,6 +9,27 @@
z-index: 4;
}
.mdl-button--file--disabled {
background: rgba(0,0,0,.12);
color: rgba(0,0,0,.26);
}
.mdl-button--file--disabled:hover {
background: rgba(0,0,0,.12);
color: rgba(0,0,0,.26);
}
.mdl-button--file--disabled:focus:not(:active) {
box-shadow: 0 0 8px rgba(0,0,0,.18), 0 8px 16px rgba(0,0,0,.36);
background-color: rgba(158,158,158,.4);
}
.mdl-button--file--disabled input[type="file"]:disabled {
cursor: default;
background-color: transparent;
}
.mdl-textfield--file .mdl-textfield__input {
box-sizing: border-box;
width: calc(100% - 32px);

View File

@@ -1,6 +1,6 @@
<form>
<!--Files Upload-->
<div *ngIf="!uploadFolders" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-button--file">
<div *ngIf="!uploadFolders" [class.mdl-button--file--disabled]="disableButton" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-button--file">
<i class="material-icons">file_upload</i>
<!--Multiple Files Upload-->
@@ -11,6 +11,7 @@
(change)="onFilesAdded($event)"
multiple="multiple"
accept="{{acceptedFilesType}}"
[attr.disabled]="disableButton"
#uploadFiles>
</span>
@@ -21,6 +22,7 @@
<input id="upload-single-file" data-automation-id="upload-single-file" type="file" name="uploadFiles"
(change)="onFilesAdded($event)"
accept="{{acceptedFilesType}}"
[attr.disabled]="disableButton"
#uploadFiles>
</span>
</div>
@@ -34,6 +36,7 @@
(change)="onDirectoryAdded($event)"
multiple="multiple"
accept="{{acceptedFilesType}}"
[attr.disabled]="disableButton"
webkitdirectory directory
multiple #uploadFolders>
</div>

View File

@@ -21,6 +21,7 @@ import { DebugElement } from '@angular/core';
import { CoreModule, AlfrescoTranslationService, NotificationService } from 'ng2-alfresco-core';
import { TranslationMock } from '../assets/translation.service.mock';
import { UploadService } from '../services/upload.service';
import { Observable } from 'rxjs/Rx';
describe('UploadButtonComponent', () => {
@@ -53,6 +54,25 @@ describe('UploadButtonComponent', () => {
}
};
let fakeFolderNodeWithoutPermission = {
allowableOperations: [
'update'
],
isFolder: true,
name: 'Folder Fake Name',
nodeType: 'cm:folder'
};
let fakeFolderNodeWithPermission = {
allowableOperations: [
'create',
'update'
],
isFolder: true,
name: 'Folder Fake Name',
nodeType: 'cm:folder'
};
let fakeRejectPromise = new Promise(function (resolve, reject) {
reject(fakeRejectRest);
});
@@ -117,9 +137,70 @@ describe('UploadButtonComponent', () => {
expect(compiled.querySelector('#uploadFolder')).toBeDefined();
});
it('should emit the permissionEvent, without permission and disableWithNoPermission false', (done) => {
component.rootFolderId = '-my-';
component.disableWithNoPermission = false;
spyOn(uploadService, 'getFolderNode').and.returnValue(Observable.of(fakeFolderNodeWithoutPermission));
fixture.detectChanges();
component.permissionEvent.subscribe( permission => {
expect(permission).toBeDefined();
expect(permission.type).toEqual('content');
expect(permission.action).toEqual('upload');
expect(permission.permission).toEqual('create');
done();
});
component.onFilesAdded(fakeEvent);
});
it('should show the disabled button, without permission and disableWithNoPermission true', () => {
component.rootFolderId = '-my-';
component.disableWithNoPermission = true;
spyOn(uploadService, 'getFolderNode').and.returnValue(Observable.of(fakeFolderNodeWithoutPermission));
component.onFilesAdded(fakeEvent);
let compiled = fixture.debugElement.nativeElement;
fixture.detectChanges();
expect(compiled.querySelector('#upload-single-file')).toBeDefined();
expect(compiled.querySelector('#upload-single-file').disabled).toBe(true);
});
it('should show the enabled button with permission and disableWithNoPermission true', () => {
component.rootFolderId = '-my-';
component.disableWithNoPermission = true;
spyOn(uploadService, 'getFolderNode').and.returnValue(Observable.of(fakeFolderNodeWithPermission));
component.onFilesAdded(fakeEvent);
let compiled = fixture.debugElement.nativeElement;
fixture.detectChanges();
expect(compiled.querySelector('#upload-single-file')).toBeDefined();
expect(compiled.querySelector('#upload-single-file').disabled).toBe(false);
});
it('should show the enabled button with permission and disableWithNoPermission false', () => {
component.rootFolderId = '-my-';
component.disableWithNoPermission = false;
spyOn(uploadService, 'getFolderNode').and.returnValue(Observable.of(fakeFolderNodeWithPermission));
component.onFilesAdded(fakeEvent);
let compiled = fixture.debugElement.nativeElement;
fixture.detectChanges();
expect(compiled.querySelector('#upload-single-file')).toBeDefined();
expect(compiled.querySelector('#upload-single-file').disabled).toBe(false);
});
it('should call uploadFile with the default root folder', () => {
component.currentFolderPath = '/root-fake-/sites-fake/folder-fake';
component.onSuccess = null;
spyOn(uploadService, 'getFolderNode').and.returnValue(Observable.of(fakeFolderNodeWithPermission));
uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');
fixture.detectChanges();
@@ -132,6 +213,8 @@ describe('UploadButtonComponent', () => {
component.currentFolderPath = '/root-fake-/sites-fake/folder-fake';
component.rootFolderId = '-my-';
component.onSuccess = null;
spyOn(uploadService, 'getFolderNode').and.returnValue(Observable.of(fakeFolderNodeWithPermission));
uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');
fixture.detectChanges();
@@ -144,6 +227,7 @@ describe('UploadButtonComponent', () => {
component.currentFolderPath = '/fake-root-path';
fixture.detectChanges();
spyOn(uploadService, 'getFolderNode').and.returnValue(Observable.of(fakeFolderNodeWithPermission));
spyOn(uploadService, 'callApiCreateFolder').and.returnValue(fakeResolvePromise);
component.onSuccess.subscribe(e => {
@@ -161,6 +245,7 @@ describe('UploadButtonComponent', () => {
});
it('should emit an onError event when the folder already exist', (done) => {
spyOn(uploadService, 'getFolderNode').and.returnValue(Observable.of(fakeFolderNodeWithPermission));
spyOn(uploadService, 'callApiCreateFolder').and.returnValue(fakeRejectPromise);
component.onError.subscribe(e => {
expect(e.value).toEqual('FILE_UPLOAD.MESSAGES.FOLDER_ALREADY_EXIST');

View File

@@ -15,11 +15,12 @@
* limitations under the License.
*/
import { Component, ElementRef, Input, Output, EventEmitter } from '@angular/core';
import 'rxjs/Rx';
import { Component, ElementRef, Input, Output, EventEmitter, OnInit, OnChanges } from '@angular/core';
import { Subject } from 'rxjs/Rx';
import { AlfrescoTranslationService, LogService, NotificationService } from 'ng2-alfresco-core';
import { UploadService } from '../services/upload.service';
import { FileModel } from '../models/file.model';
import { PermissionModel } from '../models/permissions.model';
declare let componentHandler: any;
@@ -51,7 +52,7 @@ const ERROR_FOLDER_ALREADY_EXIST = 409;
templateUrl: './upload-button.component.html',
styleUrls: ['./upload-button.component.css']
})
export class UploadButtonComponent {
export class UploadButtonComponent implements OnInit, OnChanges {
private static DEFAULT_ROOT_ID: string = '-root-';
@@ -79,6 +80,9 @@ export class UploadButtonComponent {
@Input()
rootFolderId: string = UploadButtonComponent.DEFAULT_ROOT_ID;
@Input()
disableWithNoPermission: boolean = false;
@Output()
onSuccess = new EventEmitter();
@@ -88,6 +92,13 @@ export class UploadButtonComponent {
@Output()
createFolder = new EventEmitter();
@Output()
permissionEvent: EventEmitter<PermissionModel> = new EventEmitter<PermissionModel>();
private disableButton: boolean = false;
private permissionValue: Subject<boolean> = new Subject<boolean>();
constructor(private el: ElementRef,
private uploadService: UploadService,
private translateService: AlfrescoTranslationService,
@@ -98,7 +109,18 @@ export class UploadButtonComponent {
}
}
ngOnInit() {
this.permissionValue.subscribe((hasPermission: boolean) => {
if (!hasPermission && this.disableWithNoPermission) {
this.disableButton = true;
} else {
this.disableButton = undefined;
}
});
}
ngOnChanges(changes) {
this.checkPermission();
let formFields = this.createFormFields();
this.uploadService.setOptions(formFields, this.versioning);
}
@@ -110,7 +132,15 @@ export class UploadButtonComponent {
*/
onFilesAdded($event: any): void {
let files = $event.currentTarget.files;
this.uploadFiles(this.currentFolderPath, files);
this.permissionValue.subscribe((hasPermission: boolean) => {
if (hasPermission) {
this.uploadFiles(this.currentFolderPath, files);
} else {
this.permissionEvent.emit(new PermissionModel({type: 'content', action: 'upload', permission: 'create'}));
}
});
this.checkPermission();
// reset the value of the input file
$event.target.value = '';
}
@@ -122,31 +152,39 @@ export class UploadButtonComponent {
*/
onDirectoryAdded($event: any): void {
let files = $event.currentTarget.files;
let hashMapDir = this.convertIntoHashMap(files);
this.permissionValue.subscribe((hasPermission: boolean) => {
if (hasPermission) {
let hashMapDir = this.convertIntoHashMap(files);
hashMapDir.forEach((filesDir, directoryPath) => {
let directoryName = this.getDirectoryName(directoryPath);
let absolutePath = this.currentFolderPath + this.getDirectoryPath(directoryPath);
hashMapDir.forEach((filesDir, directoryPath) => {
let directoryName = this.getDirectoryName(directoryPath);
let absolutePath = this.currentFolderPath + this.getDirectoryPath(directoryPath);
this.uploadService.createFolder(absolutePath, directoryName, this.rootFolderId)
.subscribe(
res => {
let relativeDir = this.currentFolderPath + '/' + directoryPath;
this.uploadFiles(relativeDir, filesDir);
},
error => {
let errorMessagePlaceholder = this.getErrorMessage(error.response);
if (errorMessagePlaceholder) {
this.onError.emit({value: errorMessagePlaceholder});
let errorMessage = this.formatString(errorMessagePlaceholder, [directoryName]);
if (errorMessage) {
this._showErrorNotificationBar(errorMessage);
this.uploadService.createFolder(absolutePath, directoryName, this.rootFolderId)
.subscribe(
res => {
let relativeDir = this.currentFolderPath + '/' + directoryPath;
this.uploadFiles(relativeDir, filesDir);
},
error => {
let errorMessagePlaceholder = this.getErrorMessage(error.response);
if (errorMessagePlaceholder) {
this.onError.emit({value: errorMessagePlaceholder});
let errorMessage = this.formatString(errorMessagePlaceholder, [directoryName]);
if (errorMessage) {
this._showErrorNotificationBar(errorMessage);
}
}
this.logService.error(error);
}
}
this.logService.error(error);
}
);
);
});
} else {
this.permissionEvent.emit(new PermissionModel({type: 'content', action: 'upload', permission: 'create'}));
}
});
this.checkPermission();
// reset the value of the input file
$event.target.value = '';
}
@@ -272,4 +310,28 @@ export class UploadButtonComponent {
}
};
}
checkPermission() {
if (this.rootFolderId) {
this.uploadService.getFolderNode(this.rootFolderId).subscribe(
res => {
this.permissionValue.next(this.hasCreatePermission(res));
},
error => {
this.logService.error(error);
}
);
}
}
private hasCreatePermission(node: any): boolean {
if (this.hasPermissions(node)) {
return node.allowableOperations.find(permision => permision === 'create') ? true : false;
}
return false;
}
private hasPermissions(node: any): boolean {
return node && node.allowableOperations ? true : false;
}
}