[ADF-1002] Move the UploadService from the upload to core component and share it with the Process service (#2055)

* use the same upload component between the content and process service

* Create a BaseUploadServe inside the core
The AlfrescoUpload should extend the BaseUpload

* Improve the code

* Move the process service from the demo shell to form component

* Merge [ADF-917] added exlcluded files into app config to prevent special files

* Remove typo

* Fix import

* Fix FileModel import

* Fix Denys comment

* Fix unit test with the new path of UploadService

* Add missing implementation
This commit is contained in:
Maurizio Vitale
2017-07-07 15:58:59 +01:00
committed by Eugenio Romano
parent dd61cf7b45
commit 183dd3c990
24 changed files with 141 additions and 57 deletions

View File

@@ -66,7 +66,7 @@ npm install ng2-alfresco-upload
```html
<adf-upload-button
[rootFolderId]="-my-"
[parentId]="-my-"
[uploadFolders]="true"
[multipleFiles]="false"
[acceptedFilesType]=".jpg,.gif,.png,.svg"
@@ -86,7 +86,9 @@ npm install ng2-alfresco-upload
| multipleFiles | boolean | false | Allow/disallow multiple files |
| acceptedFilesType | string | * | array of allowed file extensions , example: ".jpg,.gif,.png,.svg" |
| **(deprecated)** currentFolderPath | string | '/Sites/swsdp/documentLibrary' | define the path where the files are uploaded. **Deprecated in 1.6.0: use rootFolderId instead.** |
| rootFolderId | string | '-root-' | The ID of the root folder node. |
| **(deprecated)** rootFolderId | string | '-root-' | The ID of the root folder node.
**Deprecated in 1.6.2: use parentId instead.** |
| 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 rename 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 |

View File

@@ -24,17 +24,13 @@ import { FileUploadingListComponent } from './src/components/file-uploading-list
import { UploadButtonComponent } from './src/components/upload-button.component';
import { UploadDragAreaComponent } from './src/components/upload-drag-area.component';
import { FileDraggableDirective } from './src/directives/file-draggable.directive';
import { UploadService } from './src/services/upload.service';
export * from './src/components/upload-button.component';
export * from './src/components/file-uploading-dialog.component';
export * from './src/components/upload-drag-area.component';
export * from './src/services/upload.service';
export * from './src/directives/file-draggable.directive';
export * from './src/components/file-uploading-list.component';
export * from './src/models/file.model';
export * from './src/models/permissions.model';
export * from './src/events/file.event';
export const UPLOAD_DIRECTIVES: any[] = [
FileDraggableDirective,
@@ -45,7 +41,7 @@ export const UPLOAD_DIRECTIVES: any[] = [
];
export const UPLOAD_PROVIDERS: any[] = [
UploadService
];
@NgModule({

View File

@@ -21,9 +21,8 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { CoreModule } from 'ng2-alfresco-core';
import { FileUploadingDialogComponent } from './file-uploading-dialog.component';
import { FileUploadingListComponent } from './file-uploading-list.component';
import { UploadService } from '../services/upload.service';
import { FileModel, FileUploadStatus } from '../models/file.model';
import { FileUploadCompleteEvent, FileUploadEvent } from '../events/file.event';
import { FileModel, FileUploadStatus } from 'ng2-alfresco-core';
import { FileUploadCompleteEvent, FileUploadEvent, UploadService } from 'ng2-alfresco-core';
describe('FileUploadingDialogComponent', () => {

View File

@@ -16,10 +16,7 @@
*/
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
import { FileUploadCompleteEvent } from '../events/file.event';
import { FileModel, FileUploadStatus } from '../models/file.model';
import { UploadService } from '../services/upload.service';
import { AlfrescoTranslationService, FileModel, FileUploadCompleteEvent, FileUploadStatus, UploadService } from 'ng2-alfresco-core';
@Component({
selector: 'file-uploading-dialog',

View File

@@ -16,8 +16,7 @@
*/
import { Component, Input } from '@angular/core';
import { FileModel, FileUploadStatus } from '../models/file.model';
import { UploadService } from '../services/upload.service';
import { FileModel, FileUploadStatus, UploadService } from 'ng2-alfresco-core';
@Component({
selector: 'adf-file-uploading-list, alfresco-file-uploading-list',

View File

@@ -18,9 +18,8 @@
import { DebugElement, SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { UploadButtonComponent } from './upload-button.component';
import { CoreModule, AlfrescoTranslationService, AlfrescoContentService} from 'ng2-alfresco-core';
import { CoreModule, AlfrescoTranslationService, AlfrescoContentService, UploadService } from 'ng2-alfresco-core';
import { TranslationMock } from '../assets/translation.service.mock';
import { UploadService } from '../services/upload.service';
import { Observable } from 'rxjs/Rx';
describe('UploadButtonComponent', () => {

View File

@@ -17,11 +17,9 @@
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
import { AlfrescoApiService, AlfrescoContentService, AlfrescoTranslationService, FileUtils, LogService, NotificationService } from 'ng2-alfresco-core';
import { AlfrescoApiService, AlfrescoContentService, AlfrescoTranslationService, FileModel, FileUtils, LogService, NotificationService, UploadService } from 'ng2-alfresco-core';
import { Observable, Subject } from 'rxjs/Rx';
import { FileModel } from '../models/file.model';
import { PermissionModel } from '../models/permissions.model';
import { UploadService } from '../services/upload.service';
@Component({
selector: 'adf-upload-button, alfresco-upload-button',

View File

@@ -17,13 +17,11 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { DebugElement } from '@angular/core';
import { AlfrescoTranslationService, CoreModule, LogService, LogServiceMock } from 'ng2-alfresco-core';
import { AlfrescoTranslationService, CoreModule, FileModel, LogService, LogServiceMock, UploadService } from 'ng2-alfresco-core';
import { UploadDragAreaComponent } from './upload-drag-area.component';
import { FileDraggableDirective } from '../directives/file-draggable.directive';
import { TranslationMock } from '../assets/translation.service.mock';
import { UploadService } from '../services/upload.service';
import { FileModel } from '../models/file.model';
let fakeShareDataRow = {
obj: {

View File

@@ -16,9 +16,7 @@
*/
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { AlfrescoTranslationService, FileInfo, FileUtils, NotificationService } from 'ng2-alfresco-core';
import { FileModel } from '../models/file.model';
import { UploadService } from '../services/upload.service';
import { AlfrescoTranslationService, FileInfo, FileModel, FileUtils, NotificationService, UploadService } from 'ng2-alfresco-core';
@Component({
selector: 'adf-upload-drag-area, alfresco-upload-drag-area',
@@ -60,9 +58,18 @@ export class UploadDragAreaComponent {
@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
*/
@Input()
rootFolderId: string = '-root-';
@Input()
parentId: string;
@Output()
onSuccess = new EventEmitter();
@@ -85,9 +92,9 @@ export class UploadDragAreaComponent {
if (isAllowed) {
let files: FileInfo[] = event.detail.files;
if (files && files.length > 0) {
let parentId = this.rootFolderId;
let parentId = this.parentId || this.rootFolderId;
if (event.detail.data && event.detail.data.obj.entry.isFolder) {
parentId = event.detail.data.obj.entry.id || this.rootFolderId;
parentId = event.detail.data.obj.entry.id || this.parentId || this.rootFolderId;
}
const fileModels = files.map(fileInfo => new FileModel(fileInfo.file, {
newVersion: this.versioning,
@@ -109,7 +116,7 @@ export class UploadDragAreaComponent {
const fileModels = files.map(file => new FileModel(file, {
newVersion: this.versioning,
path: '/',
parentId: this.rootFolderId
parentId: this.parentId || this.rootFolderId
}));
this.uploadService.addToQueue(...fileModels);
this.uploadService.uploadFilesInTheQueue(this.onSuccess);
@@ -129,7 +136,7 @@ export class UploadDragAreaComponent {
item.file((file: File) => {
const fileModel = new FileModel(file, {
newVersion: this.versioning,
parentId: this.rootFolderId,
parentId: this.parentId || this.rootFolderId,
path: item.fullPath.replace(item.name, '')
});
this.uploadService.addToQueue(fileModel);
@@ -151,7 +158,7 @@ export class UploadDragAreaComponent {
let files = entries.map(entry => {
return new FileModel(entry.file, {
newVersion: this.versioning,
parentId: this.rootFolderId,
parentId: this.parentId || this.rootFolderId,
path: entry.relativeFolder
});
});

View File

@@ -1,36 +0,0 @@
/*!
* @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 { FileModel, FileUploadStatus } from '../models/file.model';
export class FileUploadEvent {
constructor(
public readonly file: FileModel,
public readonly status: FileUploadStatus = FileUploadStatus.Pending,
public readonly error: any = null) {
}
}
export class FileUploadCompleteEvent extends FileUploadEvent {
constructor(file: FileModel, public totalComplete: number = 0, public data?: any, public totalAborted: number = 0) {
super(file, FileUploadStatus.Complete);
}
}

View File

@@ -1,74 +0,0 @@
/*!
* @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 interface FileUploadProgress {
loaded: number;
total: number;
percent: number;
}
export interface FileUploadOptions {
newVersion?: boolean;
parentId?: string;
path?: string;
}
export enum FileUploadStatus {
Pending = 0,
Complete = 1,
Starting = 2,
Progress = 3,
Cancelled = 4,
Aborted = 5,
Error = 6
}
export class FileModel {
readonly id: string;
readonly name: string;
readonly size: number;
readonly file: File;
status: FileUploadStatus = FileUploadStatus.Pending;
progress: FileUploadProgress;
options: FileUploadOptions;
constructor(file: File, options?: FileUploadOptions) {
this.file = file;
this.id = this.generateId();
this.name = file.name;
this.size = file.size;
this.progress = {
loaded: 0,
total: 0,
percent: 0
};
this.options = Object.assign({}, {
newVersion: false
}, options);
}
private generateId(): string {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
}

View File

@@ -1,210 +0,0 @@
/*!
* @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 { EventEmitter } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { CoreModule, AppConfigModule } from 'ng2-alfresco-core';
import { UploadService } from './upload.service';
import { FileModel, FileUploadOptions } from '../models/file.model';
declare let jasmine: any;
describe('UploadService', () => {
let service: UploadService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
CoreModule.forRoot(),
AppConfigModule.forRoot('app.config.json', {
ecmHost: 'http://localhost:9876/ecm',
files: {
excluded: ['.DS_Store', 'desktop.ini', '.git', '*.git']
}
})
],
providers: [
UploadService
]
});
service = TestBed.get(UploadService);
jasmine.Ajax.install();
});
afterEach(() => {
jasmine.Ajax.uninstall();
});
it('should return an empty queue if no elements are added', () => {
expect(service.getQueue().length).toEqual(0);
});
it('should add an element in the queue and returns it', () => {
let filesFake = new FileModel(<File>{ name: 'fake-name', size: 10 });
service.addToQueue(filesFake);
expect(service.getQueue().length).toEqual(1);
});
it('should add two elements in the queue and returns them', () => {
let filesFake = [
new FileModel(<File>{ name: 'fake-name', size: 10 }),
new FileModel(<File>{ name: 'fake-name2', size: 20 })
];
service.addToQueue(...filesFake);
expect(service.getQueue().length).toEqual(2);
});
it('should skip hidden macOS files', () => {
const file1 = new FileModel(new File([''], '.git'));
const file2 = new FileModel(new File([''], 'readme.md'));
const result = service.addToQueue(file1, file2);
expect(result.length).toBe(1);
expect(result[0]).toBe(file2);
});
it('should make XHR done request after the file is added in the queue', (done) => {
let emitter = new EventEmitter();
emitter.subscribe(e => {
expect(e.value).toBe('File uploaded');
done();
});
let fileFake = new FileModel(
<File>{ name: 'fake-name', size: 10 },
<FileUploadOptions>{ parentId: '-root-', path: 'fake-dir' }
);
service.addToQueue(fileFake);
service.uploadFilesInTheQueue(emitter);
let request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toBe('http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children?autoRename=true');
expect(request.method).toBe('POST');
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'text/plain',
responseText: 'File uploaded'
});
});
it('should make XHR error request after an error occur', (done) => {
let emitter = new EventEmitter();
emitter.subscribe(e => {
expect(e.value).toBe('Error file uploaded');
done();
});
let fileFake = new FileModel(
<File>{ name: 'fake-name', size: 10 },
<FileUploadOptions>{ parentId: '-root-' }
);
service.addToQueue(fileFake);
service.uploadFilesInTheQueue(emitter);
expect(jasmine.Ajax.requests.mostRecent().url)
.toBe('http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children?autoRename=true');
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 404,
contentType: 'text/plain',
responseText: 'Error file uploaded'
});
});
it('should make XHR abort request after the xhr abort is called', (done) => {
let emitter = new EventEmitter();
emitter.subscribe(e => {
expect(e.value).toEqual('File aborted');
done();
});
let fileFake = new FileModel(<File>{ name: 'fake-name', size: 10 });
service.addToQueue(fileFake);
service.uploadFilesInTheQueue(emitter);
let file = service.getQueue();
service.cancelUpload(...file);
});
it('If versioning is true autoRename should not be present and majorVersion should be a param', () => {
let emitter = new EventEmitter();
const filesFake = new FileModel(<File>{ name: 'fake-name', size: 10 }, { newVersion: true });
service.addToQueue(filesFake);
service.uploadFilesInTheQueue(emitter);
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('autoRename=true')).toBe(false);
expect(jasmine.Ajax.requests.mostRecent().params.has('majorVersion')).toBe(true);
});
it('should use custom root folder ID given to the service', (done) => {
let emitter = new EventEmitter();
emitter.subscribe(e => {
expect(e.value).toBe('File uploaded');
done();
});
let filesFake = new FileModel(
<File>{ name: 'fake-name', size: 10 },
<FileUploadOptions> { parentId: '123', path: 'fake-dir' }
);
service.addToQueue(filesFake);
service.uploadFilesInTheQueue(emitter);
let request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toBe('http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/123/children?autoRename=true');
expect(request.method).toBe('POST');
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'text/plain',
responseText: 'File uploaded'
});
});
it('should start downloading the next one if a file of the list is aborted', (done) => {
let emitter = new EventEmitter();
service.fileUploadAborted.subscribe(e => {
expect(e).not.toBeNull();
});
service.fileUploadCancelled.subscribe(e => {
expect(e).not.toBeNull();
done();
});
let fileFake1 = new FileModel(<File>{ name: 'fake-name1', size: 10 });
let fileFake2 = new FileModel(<File>{ name: 'fake-name2', size: 10 });
let filelist = [fileFake1, fileFake2];
service.addToQueue(...filelist);
service.uploadFilesInTheQueue(emitter);
let file = service.getQueue();
service.cancelUpload(...file);
});
it('should remove from the queue all the files in the exluded list', () => {
const file1 = new FileModel(new File([''], '.git'));
const file2 = new FileModel(new File([''], '.DS_Store'));
const file3 = new FileModel(new File([''], 'desktop.ini'));
const file4 = new FileModel(new File([''], 'readme.md'));
const file5 = new FileModel(new File([''], 'test.git'));
const result = service.addToQueue(file1, file2, file3, file4, file5);
expect(result.length).toBe(1);
expect(result[0]).toBe(file4);
});
});

View File

@@ -1,251 +0,0 @@
/*!
* @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 { EventEmitter, Injectable } from '@angular/core';
import * as minimatch from 'minimatch';
import { AlfrescoApiService, AppConfigService } from 'ng2-alfresco-core';
import { Subject } from 'rxjs/Rx';
import { FileUploadCompleteEvent, FileUploadEvent } from '../events/file.event';
import { FileModel, FileUploadProgress, FileUploadStatus } from '../models/file.model';
@Injectable()
export class UploadService {
private queue: FileModel[] = [];
private cache: { [key: string]: any } = {};
private totalComplete: number = 0;
private totalAborted: number = 0;
private activeTask: Promise<any> = null;
private excludedFileList: String[] = [];
queueChanged: Subject<FileModel[]> = new Subject<FileModel[]>();
fileUpload: Subject<FileUploadEvent> = new Subject<FileUploadEvent>();
fileUploadStarting: Subject<FileUploadEvent> = new Subject<FileUploadEvent>();
fileUploadCancelled: Subject<FileUploadEvent> = new Subject<FileUploadEvent>();
fileUploadProgress: Subject<FileUploadEvent> = new Subject<FileUploadEvent>();
fileUploadAborted: Subject<FileUploadEvent> = new Subject<FileUploadEvent>();
fileUploadError: Subject<FileUploadEvent> = new Subject<FileUploadEvent>();
fileUploadComplete: Subject<FileUploadCompleteEvent> = new Subject<FileUploadCompleteEvent>();
constructor(private apiService: AlfrescoApiService, private appConfigService: AppConfigService) {
this.excludedFileList = <String[]>this.appConfigService.get('files.excluded');
}
/**
* Checks whether the service is uploading a file.
*
* @returns {boolean}
*
* @memberof UploadService
*/
isUploading(): boolean {
return this.activeTask ? true : false;
}
/**
* Returns the file Queue
*
* @return {FileModel[]} - files in the upload queue.
*/
getQueue(): FileModel[] {
return this.queue;
}
/**
* Add files to the uploading queue to be uploaded.
*
* Examples:
* addToQueue(file); // pass one file
* addToQueue(file1, file2, file3); // pass multiple files
* addToQueue(...[file1, file2, file3]); // pass an array of files
*/
addToQueue(...files: FileModel[]): FileModel[] {
const allowedFiles = files.filter(f => this.filterElement(f));
this.queue = this.queue.concat(allowedFiles);
this.queueChanged.next(this.queue);
return allowedFiles;
}
private filterElement(file: FileModel) {
let isAllowed = true;
if (this.excludedFileList) {
isAllowed = this.excludedFileList.filter(expr => minimatch(file.name, expr)).length === 0;
}
return isAllowed;
}
/**
* Pick all the files in the queue that are not been uploaded yet and upload it into the directory folder.
*
* @param {EventEmitter<any>} emitter @deprecated emitter to invoke on file status change
*
* @memberof UploadService
*/
uploadFilesInTheQueue(emitter: EventEmitter<any>): void {
if (!this.activeTask) {
let file = this.queue.find(f => f.status === FileUploadStatus.Pending);
if (file) {
this.onUploadStarting(file);
const promise = this.beginUpload(file, emitter);
this.activeTask = promise;
this.cache[file.id] = promise;
let next = () => {
this.activeTask = null;
setTimeout(() => this.uploadFilesInTheQueue(emitter), 100);
};
promise.next = next;
promise.then(
() => next(),
() => next()
);
}
}
}
cancelUpload(...files: FileModel[]) {
files.forEach(file => {
file.status = FileUploadStatus.Cancelled;
const promise = this.cache[file.id];
if (promise) {
promise.abort();
delete this.cache[file.id];
}
const event = new FileUploadEvent(file, FileUploadStatus.Cancelled);
this.fileUpload.next(event);
this.fileUploadCancelled.next(event);
});
}
clearQueue() {
this.queue = [];
this.totalComplete = 0;
this.totalAborted = 0;
}
private beginUpload(file: FileModel, /* @deprecated */emitter: EventEmitter<any>): any {
let opts: any = {
renditions: 'doclib'
};
if (file.options.newVersion === true) {
opts.overwrite = true;
opts.majorVersion = true;
} else {
opts.autoRename = true;
}
let promise = this.apiService.getInstance().upload.uploadFile(
file.file,
file.options.path,
file.options.parentId,
null,
opts
);
promise.on('progress', (progress: FileUploadProgress) => {
this.onUploadProgress(file, progress);
})
.on('abort', () => {
this.onUploadAborted(file);
emitter.emit({ value: 'File aborted' });
})
.on('error', err => {
this.onUploadError(file, err);
emitter.emit({ value: 'Error file uploaded' });
})
.on('success', data => {
this.onUploadComplete(file, data);
emitter.emit({ value: data });
})
.catch(err => {
this.onUploadError(file, err);
});
return promise;
}
private onUploadStarting(file: FileModel): void {
if (file) {
file.status = FileUploadStatus.Starting;
const event = new FileUploadEvent(file, FileUploadStatus.Starting);
this.fileUpload.next(event);
this.fileUploadStarting.next(event);
}
}
private onUploadProgress(file: FileModel, progress: FileUploadProgress): void {
if (file) {
file.progress = progress;
file.status = FileUploadStatus.Progress;
const event = new FileUploadEvent(file, FileUploadStatus.Progress);
this.fileUpload.next(event);
this.fileUploadProgress.next(event);
}
}
private onUploadError(file: FileModel, error: any): void {
if (file) {
file.status = FileUploadStatus.Error;
const promise = this.cache[file.id];
if (promise) {
delete this.cache[file.id];
}
const event = new FileUploadEvent(file, FileUploadStatus.Error, error);
this.fileUpload.next(event);
this.fileUploadError.next(event);
}
}
private onUploadComplete(file: FileModel, data: any): void {
if (file) {
file.status = FileUploadStatus.Complete;
this.totalComplete++;
const promise = this.cache[file.id];
if (promise) {
delete this.cache[file.id];
}
const event = new FileUploadCompleteEvent(file, this.totalComplete, data, this.totalAborted);
this.fileUpload.next(event);
this.fileUploadComplete.next(event);
}
}
private onUploadAborted(file: FileModel): void {
if (file) {
file.status = FileUploadStatus.Aborted;
this.totalAborted++;
const promise = this.cache[file.id];
if (promise) {
delete this.cache[file.id];
}
const event = new FileUploadEvent(file, FileUploadStatus.Aborted);
this.fileUpload.next(event);
this.fileUploadAborted.next(event);
promise.next();
}
}
}