mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ASD-2483] Validate folder name on change (#3088)
* notify service refactoring get translate eliminitation in favor of instant add error event where necessary fix config problem during test * fix delete notify test * remove fdescribe * fix core test * errors * fix types
This commit is contained in:
@@ -60,6 +60,7 @@
|
||||
class="upload-dialog__content"
|
||||
[class.upload-dialog--padding]="isConfirmation">
|
||||
<adf-file-uploading-list
|
||||
(error)="onError($event)"
|
||||
[class.upload-dialog--hide]="isConfirmation"
|
||||
#uploadList
|
||||
[files]="filesUploadingList">
|
||||
|
@@ -15,14 +15,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FileModel, FileUploadCompleteEvent, FileUploadDeleteEvent,
|
||||
FileUploadErrorEvent, FileUploadStatus, UploadService } from '@alfresco/adf-core';
|
||||
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import {
|
||||
FileModel, FileUploadCompleteEvent, FileUploadDeleteEvent,
|
||||
FileUploadErrorEvent, FileUploadStatus, UploadService
|
||||
} from '@alfresco/adf-core';
|
||||
import { ChangeDetectorRef, Component, Input, Output, EventEmitter, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { FileUploadingListComponent } from './file-uploading-list.component';
|
||||
import 'rxjs/add/observable/merge';
|
||||
|
||||
// @deprecated file-uploading-dialog TODO remove in 3.0.0
|
||||
@Component({
|
||||
selector: 'adf-file-uploading-dialog, file-uploading-dialog',
|
||||
templateUrl: './file-uploading-dialog.component.html',
|
||||
@@ -36,6 +39,10 @@ export class FileUploadingDialogComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
position: string = 'right';
|
||||
|
||||
/** Emitted when a file in the list has an error. */
|
||||
@Output()
|
||||
error: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
filesUploadingList: FileModel[] = [];
|
||||
isDialogActive: boolean = false;
|
||||
totalCompleted: number = 0;
|
||||
@@ -48,9 +55,9 @@ export class FileUploadingDialogComponent implements OnInit, OnDestroy {
|
||||
private fileUploadSubscription: Subscription;
|
||||
private errorSubscription: Subscription;
|
||||
|
||||
constructor(
|
||||
private uploadService: UploadService,
|
||||
private changeDetecor: ChangeDetectorRef) {}
|
||||
constructor(private uploadService: UploadService,
|
||||
private changeDetecor: ChangeDetectorRef) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.listSubscription = this.uploadService
|
||||
@@ -60,14 +67,14 @@ export class FileUploadingDialogComponent implements OnInit, OnDestroy {
|
||||
if (this.filesUploadingList.length) {
|
||||
this.isDialogActive = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.counterSubscription = Observable
|
||||
.merge(
|
||||
this.uploadService.fileUploadComplete,
|
||||
this.uploadService.fileUploadDeleted
|
||||
)
|
||||
.subscribe((event: (FileUploadDeleteEvent|FileUploadCompleteEvent)) => {
|
||||
.subscribe((event: (FileUploadDeleteEvent | FileUploadCompleteEvent)) => {
|
||||
this.totalCompleted = event.totalComplete;
|
||||
this.changeDetecor.detectChanges();
|
||||
});
|
||||
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { TranslationService, FileUploadStatus, NodesApiService, NotificationService, UploadService } from '@alfresco/adf-core';
|
||||
import { TranslationService, FileUploadStatus, NodesApiService, UploadService } from '@alfresco/adf-core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { UploadModule } from '../upload.module';
|
||||
import { FileUploadingListComponent } from './file-uploading-list.component';
|
||||
@@ -26,7 +26,6 @@ describe('FileUploadingListComponent', () => {
|
||||
let component: FileUploadingListComponent;
|
||||
let uploadService: UploadService;
|
||||
let nodesApiService: NodesApiService;
|
||||
let notificationService: NotificationService;
|
||||
let translateService: TranslationService;
|
||||
let file: any;
|
||||
|
||||
@@ -45,13 +44,11 @@ describe('FileUploadingListComponent', () => {
|
||||
beforeEach(() => {
|
||||
nodesApiService = TestBed.get(NodesApiService);
|
||||
uploadService = TestBed.get(UploadService);
|
||||
notificationService = TestBed.get(NotificationService);
|
||||
translateService = TestBed.get(TranslationService);
|
||||
fixture = TestBed.createComponent(FileUploadingListComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
spyOn(translateService, 'get').and.returnValue(Observable.of('some error message'));
|
||||
spyOn(notificationService, 'openSnackMessage');
|
||||
spyOn(uploadService, 'cancelUpload');
|
||||
});
|
||||
|
||||
@@ -82,15 +79,6 @@ describe('FileUploadingListComponent', () => {
|
||||
expect(file.status).toBe(FileUploadStatus.Error);
|
||||
});
|
||||
|
||||
it('should notify fail when api returns error', () => {
|
||||
spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.throw(file));
|
||||
|
||||
component.removeFile(file);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(notificationService.openSnackMessage).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call uploadService on error', () => {
|
||||
spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.throw(file));
|
||||
|
||||
@@ -108,6 +96,19 @@ describe('FileUploadingListComponent', () => {
|
||||
|
||||
expect(uploadService.cancelUpload).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('Events', () => {
|
||||
|
||||
it('should throw an error event if delete file goes wrong', (done) => {
|
||||
spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.throw(file));
|
||||
|
||||
component.error.subscribe(() => {
|
||||
done();
|
||||
});
|
||||
|
||||
component.removeFile(file);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('cancelAllFiles()', () => {
|
||||
@@ -159,15 +160,6 @@ describe('FileUploadingListComponent', () => {
|
||||
|
||||
expect(uploadService.cancelUpload).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should notify on deleting file error', () => {
|
||||
spyOn(nodesApiService, 'deleteNode').and.returnValue(Observable.throw({}));
|
||||
|
||||
component.files[0].status = FileUploadStatus.Complete;
|
||||
component.cancelAllFiles();
|
||||
|
||||
expect(notificationService.openSnackMessage).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isUploadCompleted()', () => {
|
||||
|
@@ -15,8 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FileModel, FileUploadStatus, NodesApiService, NotificationService, TranslationService, UploadService } from '@alfresco/adf-core';
|
||||
import { Component, ContentChild, Input, TemplateRef } from '@angular/core';
|
||||
import { FileModel, FileUploadStatus, NodesApiService, TranslationService, UploadService } from '@alfresco/adf-core';
|
||||
import { Component, ContentChild, Input, Output, TemplateRef, EventEmitter } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
@Component({
|
||||
@@ -34,10 +34,13 @@ export class FileUploadingListComponent {
|
||||
@Input()
|
||||
files: FileModel[] = [];
|
||||
|
||||
/** Emitted when a file in the list has an error. */
|
||||
@Output()
|
||||
error: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
constructor(
|
||||
private uploadService: UploadService,
|
||||
private nodesApi: NodesApiService,
|
||||
private notificationService: NotificationService,
|
||||
private translateService: TranslationService) {
|
||||
}
|
||||
|
||||
@@ -130,24 +133,23 @@ export class FileUploadingListComponent {
|
||||
}
|
||||
|
||||
private notifyError(...files: FileModel[]) {
|
||||
let translateSubscription = null;
|
||||
let messageError: string = null;
|
||||
|
||||
if (files.length === 1) {
|
||||
translateSubscription = this.translateService
|
||||
.get(
|
||||
messageError = this.translateService
|
||||
.instant(
|
||||
'FILE_UPLOAD.MESSAGES.REMOVE_FILE_ERROR',
|
||||
{ fileName: files[0].name}
|
||||
);
|
||||
} else {
|
||||
translateSubscription = this.translateService
|
||||
.get(
|
||||
messageError = this.translateService
|
||||
.instant(
|
||||
'FILE_UPLOAD.MESSAGES.REMOVE_FILES_ERROR',
|
||||
{ total: files.length }
|
||||
);
|
||||
}
|
||||
|
||||
translateSubscription
|
||||
.subscribe(message => this.notificationService.openSnackMessage(message, 4000));
|
||||
this.error.emit(messageError);
|
||||
}
|
||||
|
||||
private getUploadingFiles() {
|
||||
|
@@ -20,6 +20,7 @@ import { FileModel, LogService, UploadService } from '@alfresco/adf-core';
|
||||
|
||||
import { FileDraggableDirective } from '../directives/file-draggable.directive';
|
||||
import { UploadDragAreaComponent } from './upload-drag-area.component';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
function getFakeShareDataRow(allowableOperations = ['delete', 'update', 'create']) {
|
||||
return {
|
||||
@@ -95,7 +96,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
fixture.detectChanges();
|
||||
|
||||
const file = <File> {name: 'fake-name-1', size: 10, webkitRelativePath: 'fake-folder1/fake-name-1.json'};
|
||||
const file = <File> { name: 'fake-name-1', size: 10, webkitRelativePath: 'fake-folder1/fake-name-1.json' };
|
||||
let filesList = [file];
|
||||
component.onFilesDropped(filesList);
|
||||
|
||||
@@ -115,7 +116,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
@@ -161,7 +162,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
@@ -182,7 +183,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');
|
||||
|
||||
fixture.detectChanges();
|
||||
const file = <File> {name: 'fake-name-1', size: 10, webkitRelativePath: 'fake-folder1/fake-name-1.json'};
|
||||
const file = <File> { name: 'fake-name-1', size: 10, webkitRelativePath: 'fake-folder1/fake-name-1.json' };
|
||||
let filesList = [file];
|
||||
|
||||
spyOn(uploadService, 'addToQueue').and.callFake((f: FileModel) => {
|
||||
@@ -205,7 +206,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
@@ -226,7 +227,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
@@ -242,7 +243,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
@@ -262,4 +263,36 @@ describe('UploadDragAreaComponent', () => {
|
||||
|
||||
component.onUploadFiles(fakeCustomEvent);
|
||||
}));
|
||||
|
||||
describe('Events', () => {
|
||||
it('should raise an error if upload a file goes wrong', (done) => {
|
||||
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();
|
||||
spyOn(uploadService, 'fileUploadError').and.returnValue(Observable.throw(new Error()));
|
||||
|
||||
component.error.subscribe((error) => {
|
||||
expect(error).not.toBeNull();
|
||||
done();
|
||||
});
|
||||
|
||||
let fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', {
|
||||
detail: {
|
||||
data: getFakeShareDataRow(),
|
||||
files: [fakeItem]
|
||||
}
|
||||
});
|
||||
|
||||
component.onUploadFiles(fakeCustomEvent);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -32,7 +32,7 @@ import { Component, EventEmitter, forwardRef, Input, Output, ViewEncapsulation }
|
||||
templateUrl: './upload-drag-area.component.html',
|
||||
styleUrls: ['./upload-drag-area.component.css'],
|
||||
viewProviders: [
|
||||
{ provide: EXTENDIBLE_COMPONENT, useExisting: forwardRef(() => UploadDragAreaComponent)}
|
||||
{ provide: EXTENDIBLE_COMPONENT, useExisting: forwardRef(() => UploadDragAreaComponent) }
|
||||
],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
@@ -56,6 +56,10 @@ export class UploadDragAreaComponent implements NodePermissionSubject {
|
||||
@Output()
|
||||
success = new EventEmitter();
|
||||
|
||||
/** Raised when the file upload goes in error. */
|
||||
@Output()
|
||||
error = new EventEmitter();
|
||||
|
||||
constructor(private uploadService: UploadService,
|
||||
private translateService: TranslationService,
|
||||
private notificationService: NotificationService) {
|
||||
@@ -91,8 +95,8 @@ export class UploadDragAreaComponent implements NodePermissionSubject {
|
||||
parentId: this.parentId,
|
||||
path: item.fullPath.replace(item.name, '')
|
||||
});
|
||||
this.uploadService.addToQueue(fileModel);
|
||||
this.uploadService.uploadFilesInTheQueue(this.success);
|
||||
|
||||
this.addNodeInUploadQueue([fileModel]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -112,8 +116,18 @@ export class UploadDragAreaComponent implements NodePermissionSubject {
|
||||
path: entry.relativeFolder
|
||||
});
|
||||
});
|
||||
this.uploadService.addToQueue(...files);
|
||||
this.uploadService.uploadFilesInTheQueue(this.success);
|
||||
|
||||
this.addNodeInUploadQueue(files);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private addNodeInUploadQueue(files: FileModel[]) {
|
||||
if (files.length) {
|
||||
this.uploadService.addToQueue(...files);
|
||||
this.uploadService.uploadFilesInTheQueue(this.success);
|
||||
this.uploadService.fileUploadError.subscribe((error) => {
|
||||
this.error.emit(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -133,15 +147,6 @@ export class UploadDragAreaComponent implements NodePermissionSubject {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the error inside Notification bar
|
||||
*
|
||||
* @param Error message
|
||||
*/
|
||||
showErrorNotificationBar(errorMessage: string) {
|
||||
this.notificationService.openSnackMessage(errorMessage, 3000);
|
||||
}
|
||||
|
||||
/** Returns true or false considering the component options and node permissions */
|
||||
isDroppable(): boolean {
|
||||
return !this.disabled;
|
||||
@@ -168,23 +173,11 @@ export class UploadDragAreaComponent implements NodePermissionSubject {
|
||||
path: fileInfo.relativeFolder,
|
||||
parentId: parentId
|
||||
}));
|
||||
this.uploadFiles(fileModels);
|
||||
this.addNodeInUploadQueue(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.success);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if "create" permission is present on the given node
|
||||
*
|
||||
|
Reference in New Issue
Block a user