mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-1188] Upload related components, unify interfaces, deprecate disableWithNoPermission (#2216)
* Deprecate enabled input property in UploadDragAreaComponent * Refactoring about disabled property * using adf-node-permission directive, deprecating disableWithNoPermission * Parent component access from directive * Upliad drag area component uses the directive also * Usage of property instead of helper method in the NodePermissionSubjects * Fix small issues * Update readme files
This commit is contained in:
committed by
Mario Romano
parent
9cd188aa4f
commit
ac55704220
@@ -92,7 +92,7 @@ npm install ng2-alfresco-upload
|
||||
| parentId | string | empty | The ID of the root. It can be the nodeId if you are using the upload for the Content Service or taskId/processId for the Process Service. |
|
||||
| versioning | boolean | false | Versioning false is the default uploader behaviour and it renames the file using an integer suffix if there is a name clash. Versioning true to indicate that a major version should be created |
|
||||
| staticTitle | string | (predefined) | define the text of the upload button |
|
||||
| disableWithNoPermission | boolean | false | If the value is true and the user doesn't have the permission to delete the node the button will be disabled |
|
||||
| **(deprecated)** disableWithNoPermission ***use node permission directive from core instead*** | boolean | false | If the value is true and the user doesn't have the permission to delete the node the button will be disabled |
|
||||
| tooltip | string | | Custom tooltip |
|
||||
|
||||
### Events
|
||||
@@ -171,7 +171,8 @@ export class AppComponent {
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| enabled | boolean | true | Toggle component enabled state |
|
||||
| disabled | boolean | false | Toggle component disabled state |
|
||||
| **(deprecated)** enabled | boolean | true | Toggle component enabled state |
|
||||
| **(deprecated)** showNotificationBar | boolean | true | Hide/show notification bar. **Deprecated in 1.6.0: use UploadService events and NotificationService api instead.** |
|
||||
| rootFolderId | string | '-root-' | The ID of the root folder node. |
|
||||
| **(deprecated)** currentFolderPath | string | '/' | define the path where the files are uploaded. **Deprecated in 1.6.0: use rootFolderId instead.** |
|
||||
|
@@ -15,31 +15,47 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { Component, EventEmitter, forwardRef, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||
import { AlfrescoApiService, AlfrescoTranslationService, FileModel, FileUtils, LogService, NotificationService, UploadService } from 'ng2-alfresco-core';
|
||||
import {
|
||||
AlfrescoApiService,
|
||||
AlfrescoTranslationService,
|
||||
EXTENDIBLE_COMPONENT,
|
||||
FileModel,
|
||||
FileUtils,
|
||||
LogService,
|
||||
NodePermissionSubject,
|
||||
NotificationService,
|
||||
UploadService
|
||||
} from 'ng2-alfresco-core';
|
||||
import { Observable, Subject } from 'rxjs/Rx';
|
||||
import { PermissionModel } from '../models/permissions.model';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-upload-button, alfresco-upload-button',
|
||||
templateUrl: './upload-button.component.html',
|
||||
styleUrls: ['./upload-button.component.css']
|
||||
styleUrls: ['./upload-button.component.css'],
|
||||
providers: [
|
||||
{ provide: EXTENDIBLE_COMPONENT, useExisting: forwardRef(() => UploadButtonComponent)}
|
||||
]
|
||||
})
|
||||
export class UploadButtonComponent implements OnInit, OnChanges {
|
||||
export class UploadButtonComponent implements OnInit, OnChanges, NodePermissionSubject {
|
||||
|
||||
/** @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead. */
|
||||
@Input()
|
||||
showNotificationBar: boolean = true;
|
||||
|
||||
/** @deprecated Deprecated in 1.6.0, this property is not used for couple of releases already. */
|
||||
@Input()
|
||||
currentFolderPath: string = '/';
|
||||
|
||||
/** @deprecated Deprecated in 1.8.0, use the button with combination of adf-node-permission directive */
|
||||
@Input()
|
||||
disableWithNoPermission: boolean = false;
|
||||
|
||||
@Input()
|
||||
disabled: boolean = false;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof UploadButtonComponent
|
||||
*/
|
||||
@Input()
|
||||
showNotificationBar: boolean = true;
|
||||
|
||||
@Input()
|
||||
uploadFolders: boolean = false;
|
||||
|
||||
@@ -58,21 +74,9 @@ export class UploadButtonComponent implements OnInit, OnChanges {
|
||||
@Input()
|
||||
tooltip: string = null;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, this property is not used for couple of releases already.
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UploadDragAreaComponent
|
||||
*/
|
||||
@Input()
|
||||
currentFolderPath: string = '/';
|
||||
|
||||
@Input()
|
||||
rootFolderId: string = '-root-';
|
||||
|
||||
@Input()
|
||||
disableWithNoPermission: boolean = false;
|
||||
|
||||
@Output()
|
||||
onSuccess = new EventEmitter();
|
||||
|
||||
@@ -117,6 +121,7 @@ export class UploadButtonComponent implements OnInit, OnChanges {
|
||||
return this.disabled ? true : undefined;
|
||||
}
|
||||
|
||||
/** @deprecated Deprecated in 1.8.0, use the button with combination of adf-node-permission directive */
|
||||
isDisableWithNoPermission(): boolean {
|
||||
return !this.hasPermission && this.disableWithNoPermission ? true : undefined;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<div [file-draggable]="enabled" id="UploadBorder" class="upload-border"
|
||||
<div [file-draggable]="isDroppable()" id="UploadBorder" class="upload-border"
|
||||
(onFilesDropped)="onFilesDropped($event)"
|
||||
(onFilesEntityDropped)="onFilesEntityDropped($event)"
|
||||
(onFolderEntityDropped)="onFolderEntityDropped($event)"
|
||||
|
@@ -23,40 +23,38 @@ import { TranslationMock } from '../assets/translation.service.mock';
|
||||
import { FileDraggableDirective } from '../directives/file-draggable.directive';
|
||||
import { UploadDragAreaComponent } from './upload-drag-area.component';
|
||||
|
||||
let fakeShareDataRow = {
|
||||
obj: {
|
||||
entry: {
|
||||
createdAt: '2017-06-04T04:32:15.597Z',
|
||||
path: {
|
||||
name: '/Company Home/User Homes/Test',
|
||||
isComplete: true,
|
||||
elements: [
|
||||
{
|
||||
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
|
||||
name: 'Company Home'
|
||||
},
|
||||
{
|
||||
id: '55052317-7e59-4058-8e07-769f41e615e1',
|
||||
name: 'User Homes'
|
||||
},
|
||||
{
|
||||
id: '70e1cc6a-6918-468a-b84a-1048093b06fd',
|
||||
name: 'Test'
|
||||
}
|
||||
]
|
||||
},
|
||||
isFolder: true,
|
||||
name: 'pippo',
|
||||
id: '7462d28e-bd43-4b91-9e7b-0d71598680ac',
|
||||
nodeType: 'cm:folder',
|
||||
allowableOperations: [
|
||||
'delete',
|
||||
'update',
|
||||
'create'
|
||||
]
|
||||
function getFakeShareDataRow(allowableOperations = ['delete', 'update', 'create']) {
|
||||
return {
|
||||
obj: {
|
||||
entry: {
|
||||
createdAt: '2017-06-04T04:32:15.597Z',
|
||||
path: {
|
||||
name: '/Company Home/User Homes/Test',
|
||||
isComplete: true,
|
||||
elements: [
|
||||
{
|
||||
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
|
||||
name: 'Company Home'
|
||||
},
|
||||
{
|
||||
id: '55052317-7e59-4058-8e07-769f41e615e1',
|
||||
name: 'User Homes'
|
||||
},
|
||||
{
|
||||
id: '70e1cc6a-6918-468a-b84a-1048093b06fd',
|
||||
name: 'Test'
|
||||
}
|
||||
]
|
||||
},
|
||||
isFolder: true,
|
||||
name: 'pippo',
|
||||
id: '7462d28e-bd43-4b91-9e7b-0d71598680ac',
|
||||
nodeType: 'cm:folder',
|
||||
allowableOperations
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
describe('UploadDragAreaComponent', () => {
|
||||
|
||||
@@ -100,6 +98,96 @@ describe('UploadDragAreaComponent', () => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
describe('When disabled', () => {
|
||||
|
||||
it('should NOT upload the list of files dropped', () => {
|
||||
component.enabled = false;
|
||||
spyOn(uploadService, 'addToQueue');
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
fixture.detectChanges();
|
||||
|
||||
const file = <File> {name: 'fake-name-1', size: 10, webkitRelativePath: 'fake-folder1/fake-name-1.json'};
|
||||
let filesList = [file];
|
||||
component.onFilesDropped(filesList);
|
||||
|
||||
expect(uploadService.addToQueue).not.toHaveBeenCalled();
|
||||
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should NOT upload the file dropped', () => {
|
||||
component.enabled = false;
|
||||
spyOn(uploadService, 'addToQueue');
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
fixture.detectChanges();
|
||||
|
||||
let itemEntity = {
|
||||
fullPath: '/folder-fake/file-fake.png',
|
||||
isDirectory: false,
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
component.onFilesEntityDropped(itemEntity);
|
||||
|
||||
expect(uploadService.addToQueue).not.toHaveBeenCalled();
|
||||
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should NOT upload the folder dropped', (done) => {
|
||||
component.enabled = false;
|
||||
spyOn(uploadService, 'addToQueue');
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
fixture.detectChanges();
|
||||
|
||||
let itemEntity = {
|
||||
isDirectory: true,
|
||||
createReader: () => {
|
||||
return {
|
||||
readEntries: (cb) => {
|
||||
cb([]);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
component.onFolderEntityDropped(itemEntity);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(uploadService.addToQueue).not.toHaveBeenCalled();
|
||||
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should NOT upload the files', () => {
|
||||
component.enabled = false;
|
||||
spyOn(uploadService, 'addToQueue');
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
|
||||
let fakeItem = {
|
||||
fullPath: '/folder-fake/file-fake.png',
|
||||
isDirectory: false,
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
fixture.detectChanges();
|
||||
|
||||
let fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', {
|
||||
detail: { data: getFakeShareDataRow([]), files: [fakeItem] }
|
||||
});
|
||||
component.onUploadFiles(fakeCustomEvent);
|
||||
|
||||
expect(uploadService.addToQueue).not.toHaveBeenCalled();
|
||||
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should upload the list of files dropped', (done) => {
|
||||
component.currentFolderPath = '/root-fake-/sites-fake/folder-fake';
|
||||
component.onSuccess = null;
|
||||
@@ -203,7 +291,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
|
||||
let fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', {
|
||||
detail: {
|
||||
data: fakeShareDataRow,
|
||||
data: getFakeShareDataRow(),
|
||||
files: [fakeItem]
|
||||
}
|
||||
});
|
||||
|
@@ -15,49 +15,59 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { AlfrescoTranslationService, FileInfo, FileModel, FileUtils, NotificationService, UploadService } from 'ng2-alfresco-core';
|
||||
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
|
||||
import {
|
||||
AlfrescoTranslationService,
|
||||
EXTENDIBLE_COMPONENT,
|
||||
FileInfo,
|
||||
FileModel,
|
||||
FileUtils,
|
||||
NodePermissionSubject,
|
||||
NotificationService,
|
||||
UploadService
|
||||
} from 'ng2-alfresco-core';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-upload-drag-area, alfresco-upload-drag-area',
|
||||
templateUrl: './upload-drag-area.component.html',
|
||||
styleUrls: ['./upload-drag-area.component.css']
|
||||
styleUrls: ['./upload-drag-area.component.css'],
|
||||
providers: [
|
||||
{ provide: EXTENDIBLE_COMPONENT, useExisting: forwardRef(() => UploadDragAreaComponent)}
|
||||
]
|
||||
})
|
||||
export class UploadDragAreaComponent {
|
||||
export class UploadDragAreaComponent implements NodePermissionSubject {
|
||||
|
||||
/** @deprecated Deprecated in favor of disabled input property */
|
||||
@Input()
|
||||
enabled: boolean = true;
|
||||
set enabled(enabled: boolean) {
|
||||
console.warn('Deprecated: enabled input property should not be used for UploadDragAreaComponent. Please use disabled instead.');
|
||||
this.disabled = !enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof UploadButtonComponent
|
||||
*/
|
||||
/** @deprecated Deprecated in favor of disabled input property */
|
||||
get enabled(): boolean {
|
||||
console.warn('Deprecated: enabled input property should not be used for UploadDragAreaComponent. Please use disabled instead.');
|
||||
return !this.disabled;
|
||||
}
|
||||
|
||||
/** @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead. */
|
||||
@Input()
|
||||
showNotificationBar: boolean = true;
|
||||
|
||||
@Input()
|
||||
versioning: boolean = false;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, this property is not used for couple of releases already. Use rootFolderId instead.
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UploadDragAreaComponent
|
||||
*/
|
||||
/** @deprecated Deprecated in 1.6.0, this property is not used for couple of releases already. Use rootFolderId instead. */
|
||||
@Input()
|
||||
currentFolderPath: string = '/';
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.2, this property is not used for couple of releases already. Use parentId instead.
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UploadDragAreaComponent
|
||||
*/
|
||||
/** @deprecated Deprecated in 1.6.2, this property is not used for couple of releases already. Use parentId instead. */
|
||||
@Input()
|
||||
rootFolderId: string = '-root-';
|
||||
|
||||
@Input()
|
||||
disabled: boolean = false;
|
||||
|
||||
@Input()
|
||||
versioning: boolean = false;
|
||||
|
||||
@Input()
|
||||
parentId: string;
|
||||
|
||||
@@ -69,38 +79,13 @@ export class UploadDragAreaComponent {
|
||||
private notificationService: NotificationService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 'upload-files' events raised by child components.
|
||||
* @param event DOM event
|
||||
*/
|
||||
onUploadFiles(event: CustomEvent) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
let isAllowed: boolean = this.isAllowed(event.detail.data.obj.entry);
|
||||
if (isAllowed) {
|
||||
let files: FileInfo[] = event.detail.files;
|
||||
if (files && files.length > 0) {
|
||||
let parentId = this.parentId || this.rootFolderId;
|
||||
if (event.detail.data && event.detail.data.obj.entry.isFolder) {
|
||||
parentId = event.detail.data.obj.entry.id || this.parentId || this.rootFolderId;
|
||||
}
|
||||
const fileModels = files.map(fileInfo => new FileModel(fileInfo.file, {
|
||||
newVersion: this.versioning,
|
||||
path: fileInfo.relativeFolder,
|
||||
parentId: parentId
|
||||
}));
|
||||
this.uploadFiles(fileModels, isAllowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when files are dropped in the drag area.
|
||||
*
|
||||
* @param {File[]} files - files dropped in the drag area.
|
||||
*/
|
||||
onFilesDropped(files: File[]): void {
|
||||
if (this.enabled && files.length) {
|
||||
if (!this.disabled && files.length) {
|
||||
const fileModels = files.map(file => new FileModel(file, {
|
||||
newVersion: this.versioning,
|
||||
path: '/',
|
||||
@@ -117,10 +102,11 @@ export class UploadDragAreaComponent {
|
||||
|
||||
/**
|
||||
* Called when the file are dropped in the drag area
|
||||
*
|
||||
* @param item - FileEntity
|
||||
*/
|
||||
onFilesEntityDropped(item: any): void {
|
||||
if (this.enabled) {
|
||||
if (!this.disabled) {
|
||||
item.file((file: File) => {
|
||||
const fileModel = new FileModel(file, {
|
||||
newVersion: this.versioning,
|
||||
@@ -138,10 +124,11 @@ export class UploadDragAreaComponent {
|
||||
|
||||
/**
|
||||
* Called when a folder are dropped in the drag area
|
||||
*
|
||||
* @param folder - name of the dropped folder
|
||||
*/
|
||||
onFolderEntityDropped(folder: any): void {
|
||||
if (this.enabled && folder.isDirectory) {
|
||||
if (!this.disabled && folder.isDirectory) {
|
||||
FileUtils.flattern(folder).then(entries => {
|
||||
let files = entries.map(entry => {
|
||||
return new FileModel(entry.file, {
|
||||
@@ -178,6 +165,7 @@ export class UploadDragAreaComponent {
|
||||
|
||||
/**
|
||||
* Show the error inside Notification bar
|
||||
*
|
||||
* @param Error message
|
||||
* @private
|
||||
*/
|
||||
@@ -185,8 +173,44 @@ export class UploadDragAreaComponent {
|
||||
this.notificationService.openSnackMessage(errorMessage, 3000);
|
||||
}
|
||||
|
||||
private uploadFiles(files: FileModel[], isAllowed: boolean): void {
|
||||
if (isAllowed && files.length) {
|
||||
/** Returns true or false considering the component options and node permissions */
|
||||
isDroppable(): boolean {
|
||||
return !this.disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 'upload-files' events raised by child components.
|
||||
*
|
||||
* @param event DOM event
|
||||
*/
|
||||
onUploadFiles(event: CustomEvent) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
let isAllowed: boolean = this.hasCreatePermission(event.detail.data.obj.entry);
|
||||
if (isAllowed) {
|
||||
let files: FileInfo[] = event.detail.files;
|
||||
if (files && files.length > 0) {
|
||||
let parentId = this.parentId || this.rootFolderId;
|
||||
if (event.detail.data && event.detail.data.obj.entry.isFolder) {
|
||||
parentId = event.detail.data.obj.entry.id || this.parentId || this.rootFolderId;
|
||||
}
|
||||
const fileModels = files.map(fileInfo => new FileModel(fileInfo.file, {
|
||||
newVersion: this.versioning,
|
||||
path: fileInfo.relativeFolder,
|
||||
parentId: parentId
|
||||
}));
|
||||
this.uploadFiles(fileModels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual file uploading and show the notification
|
||||
*
|
||||
* @param files
|
||||
*/
|
||||
private uploadFiles(files: FileModel[]): void {
|
||||
if (files.length) {
|
||||
this.uploadService.addToQueue(...files);
|
||||
this.uploadService.uploadFilesInTheQueue(this.onSuccess);
|
||||
let latestFilesAdded = this.uploadService.getQueue();
|
||||
@@ -196,6 +220,11 @@ export class UploadDragAreaComponent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if "create" permission is present on the given node
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
private hasCreatePermission(node: any): boolean {
|
||||
let isPermitted = false;
|
||||
if (node && node['allowableOperations']) {
|
||||
@@ -204,8 +233,4 @@ export class UploadDragAreaComponent {
|
||||
}
|
||||
return isPermitted;
|
||||
}
|
||||
|
||||
private isAllowed(node: any) {
|
||||
return this.enabled || this.hasCreatePermission(node);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user