mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
[ADF-643] upload enhancements (#1949)
* rework folder uploading - flatterns hierarchy on folder upload - performs a single traversal for the entire folder heirarchy and ends with a comple file list - allows now dropping folders on existing folders - overall code improvements * fix unit tests * readme updates * clean old and unused code * code cleanup * limit concurrent uploads * update code as per review * fix upload button for Safari * fixes for Safari - Safari compatibility - code updates based on review * fix code * fix unit tests
This commit is contained in:
committed by
Eugenio Romano
parent
e7a1f46ac8
commit
a02ba4ad71
@@ -16,12 +16,10 @@
|
||||
*/
|
||||
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { AlfrescoTranslationService, AlfrescoContentService, LogService, NotificationService } from 'ng2-alfresco-core';
|
||||
import { AlfrescoTranslationService, NotificationService, FileUtils, FileInfo } from 'ng2-alfresco-core';
|
||||
import { UploadService } from '../services/upload.service';
|
||||
import { FileModel } from '../models/file.model';
|
||||
|
||||
const ERROR_FOLDER_ALREADY_EXIST = 409;
|
||||
|
||||
@Component({
|
||||
selector: 'alfresco-upload-drag-area',
|
||||
templateUrl: './upload-drag-area.component.html',
|
||||
@@ -29,31 +27,39 @@ const ERROR_FOLDER_ALREADY_EXIST = 409;
|
||||
})
|
||||
export class UploadDragAreaComponent {
|
||||
|
||||
private static DEFAULT_ROOT_ID: string = '-root-';
|
||||
|
||||
@Input()
|
||||
enabled: boolean = true;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof UploadButtonComponent
|
||||
*/
|
||||
@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
|
||||
*/
|
||||
@Input()
|
||||
currentFolderPath: string = '/';
|
||||
|
||||
@Input()
|
||||
rootFolderId: string = UploadDragAreaComponent.DEFAULT_ROOT_ID;
|
||||
rootFolderId: string = '-root-';
|
||||
|
||||
@Output()
|
||||
onSuccess = new EventEmitter();
|
||||
|
||||
constructor(private uploadService: UploadService,
|
||||
private translateService: AlfrescoTranslationService,
|
||||
private logService: LogService,
|
||||
private notificationService: NotificationService,
|
||||
private contentService: AlfrescoContentService) {
|
||||
private notificationService: NotificationService) {
|
||||
if (translateService) {
|
||||
translateService.addTranslationFolder('ng2-alfresco-upload', 'assets/ng2-alfresco-upload');
|
||||
}
|
||||
@@ -67,15 +73,18 @@ export class UploadDragAreaComponent {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (this.enabled) {
|
||||
let files: File[] = e.detail.files;
|
||||
let files: FileInfo[] = e.detail.files;
|
||||
if (files && files.length > 0) {
|
||||
const fileModels = files.map(f => new FileModel(f, { newVersion: this.versioning }));
|
||||
if (e.detail.data.obj.entry.isFolder) {
|
||||
let id = e.detail.data.obj.entry.id;
|
||||
this.onFilesDropped(fileModels, id, '/');
|
||||
} else {
|
||||
this.onFilesDropped(fileModels);
|
||||
let parentId = this.rootFolderId;
|
||||
if (e.detail.data && e.detail.data.obj.entry.isFolder) {
|
||||
parentId = e.detail.data.obj.entry.id || this.rootFolderId;
|
||||
}
|
||||
const fileModels = files.map(fileInfo => new FileModel(fileInfo.file, {
|
||||
newVersion: this.versioning,
|
||||
path: fileInfo.relativeFolder,
|
||||
parentId: parentId
|
||||
}));
|
||||
this.uploadFiles(fileModels);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,10 +94,15 @@ export class UploadDragAreaComponent {
|
||||
*
|
||||
* @param {File[]} files - files dropped in the drag area.
|
||||
*/
|
||||
onFilesDropped(files: FileModel[], rootId?: string, directory?: string): void {
|
||||
onFilesDropped(files: File[]): void {
|
||||
if (this.enabled && files.length) {
|
||||
this.uploadService.addToQueue(...files);
|
||||
this.uploadService.uploadFilesInTheQueue(rootId || this.rootFolderId, directory || this.currentFolderPath, this.onSuccess);
|
||||
const fileModels = files.map(file => new FileModel(file, {
|
||||
newVersion: this.versioning,
|
||||
path: '/',
|
||||
parentId: this.rootFolderId
|
||||
}));
|
||||
this.uploadService.addToQueue(...fileModels);
|
||||
this.uploadService.uploadFilesInTheQueue(this.onSuccess);
|
||||
let latestFilesAdded = this.uploadService.getQueue();
|
||||
if (this.showNotificationBar) {
|
||||
this.showUndoNotificationBar(latestFilesAdded);
|
||||
@@ -103,11 +117,13 @@ export class UploadDragAreaComponent {
|
||||
onFilesEntityDropped(item: any): void {
|
||||
if (this.enabled) {
|
||||
item.file((file: File) => {
|
||||
const fileModel = new FileModel(file, { newVersion: this.versioning });
|
||||
const fileModel = new FileModel(file, {
|
||||
newVersion: this.versioning,
|
||||
parentId: this.rootFolderId,
|
||||
path: item.fullPath.replace(item.name, '')
|
||||
});
|
||||
this.uploadService.addToQueue(fileModel);
|
||||
let path = item.fullPath.replace(item.name, '');
|
||||
let filePath = this.currentFolderPath + path;
|
||||
this.uploadService.uploadFilesInTheQueue(this.rootFolderId, filePath, this.onSuccess);
|
||||
this.uploadService.uploadFilesInTheQueue(this.onSuccess);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -118,52 +134,22 @@ export class UploadDragAreaComponent {
|
||||
*/
|
||||
onFolderEntityDropped(folder: any): void {
|
||||
if (this.enabled && folder.isDirectory) {
|
||||
let relativePath = folder.fullPath.replace(folder.name, '');
|
||||
relativePath = this.currentFolderPath + relativePath;
|
||||
|
||||
this.contentService.createFolder(relativePath, folder.name, this.rootFolderId)
|
||||
.subscribe(
|
||||
message => {
|
||||
this.onSuccess.emit({
|
||||
value: 'Created folder'
|
||||
});
|
||||
let dirReader = folder.createReader();
|
||||
dirReader.readEntries((entries: any) => {
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
this._traverseFileTree(entries[i]);
|
||||
}
|
||||
if (this.showNotificationBar) {
|
||||
let latestFilesAdded = this.uploadService.getQueue();
|
||||
this.showUndoNotificationBar(latestFilesAdded);
|
||||
}
|
||||
});
|
||||
},
|
||||
error => {
|
||||
let errorMessagePlaceholder = this.getErrorMessage(error.response);
|
||||
let errorMessage = this.formatString(errorMessagePlaceholder, [folder.name]);
|
||||
if (this.showNotificationBar) {
|
||||
this.showErrorNotificationBar(errorMessage);
|
||||
} else {
|
||||
this.logService.error(errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Travers all the files and folders, and create it on the alfresco.
|
||||
*
|
||||
* @param {Object} item - can contains files or folders.
|
||||
*/
|
||||
private _traverseFileTree(item: any): void {
|
||||
if (item.isFile) {
|
||||
this.onFilesEntityDropped(item);
|
||||
} else {
|
||||
if (item.isDirectory) {
|
||||
this.onFolderEntityDropped(item);
|
||||
}
|
||||
FileUtils.flattern(folder).then(entries => {
|
||||
let files = entries.map(entry => {
|
||||
return new FileModel(entry.file, {
|
||||
newVersion: this.versioning,
|
||||
parentId: this.rootFolderId,
|
||||
path: entry.relativeFolder
|
||||
});
|
||||
});
|
||||
this.uploadService.addToQueue(...files);
|
||||
/* @deprecated in 1.6.0 */
|
||||
if (this.showNotificationBar) {
|
||||
let latestFilesAdded = this.uploadService.getQueue();
|
||||
this.showUndoNotificationBar(latestFilesAdded);
|
||||
}
|
||||
this.uploadService.uploadFilesInTheQueue(this.onSuccess);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,41 +168,14 @@ export class UploadDragAreaComponent {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the error inside Notification bar
|
||||
* @param Error message
|
||||
* @private
|
||||
*/
|
||||
showErrorNotificationBar(errorMessage: string) {
|
||||
this.notificationService.openSnackMessage(errorMessage, 3000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive the error message using the error status code
|
||||
* @param response - object that contain the HTTP response
|
||||
* @returns {string}
|
||||
*/
|
||||
private getErrorMessage(response: any): string {
|
||||
if (response.body.error.statusCode === ERROR_FOLDER_ALREADY_EXIST) {
|
||||
let errorMessage: any;
|
||||
errorMessage = this.translateService.get('FILE_UPLOAD.MESSAGES.FOLDER_ALREADY_EXIST');
|
||||
return errorMessage.value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a placeholder {0} in a message with the input keys
|
||||
* @param message - the message that conains the placeholder
|
||||
* @param keys - array of value
|
||||
* @returns {string} - The message without placeholder
|
||||
*/
|
||||
private formatString(message: string, keys: any []) {
|
||||
if (message) {
|
||||
let i = keys.length;
|
||||
while (i--) {
|
||||
message = message.replace(new RegExp('\\{' + i + '\\}', 'gm'), keys[i]);
|
||||
private uploadFiles(files: FileModel[]): void {
|
||||
if (this.enabled && files.length) {
|
||||
this.uploadService.addToQueue(...files);
|
||||
this.uploadService.uploadFilesInTheQueue(this.onSuccess);
|
||||
let latestFilesAdded = this.uploadService.getQueue();
|
||||
if (this.showNotificationBar) {
|
||||
this.showUndoNotificationBar(latestFilesAdded);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user