mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-31 17:38:28 +00:00
[ACA-1057] Upload dialog - file upload error message (#832)
* Upload dialog * prettier lint * changed to Uploaded text * remove unnecessary implementation * todos
This commit is contained in:
committed by
Denys Vuika
parent
cd46070368
commit
db8be5c1b1
@@ -34,5 +34,5 @@
|
|||||||
|
|
||||||
</adf-sidenav-layout>
|
</adf-sidenav-layout>
|
||||||
|
|
||||||
<adf-file-uploading-dialog position="left"></adf-file-uploading-dialog>
|
<app-file-uploading-dialog position="left"></app-file-uploading-dialog>
|
||||||
</adf-upload-drag-area>
|
</adf-upload-drag-area>
|
||||||
|
@@ -32,6 +32,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
import { AppSidenavModule } from '../sidenav/sidenav.module';
|
import { AppSidenavModule } from '../sidenav/sidenav.module';
|
||||||
import { AppCommonModule } from '../common/common.module';
|
import { AppCommonModule } from '../common/common.module';
|
||||||
import { AppHeaderModule } from '../header/header.module';
|
import { AppHeaderModule } from '../header/header.module';
|
||||||
|
import { AppUploadingDialogModule } from '../upload-dialog/upload-dialog.module';
|
||||||
import { PageLayoutComponent } from './page-layout/page-layout.component';
|
import { PageLayoutComponent } from './page-layout/page-layout.component';
|
||||||
import { PageLayoutHeaderComponent } from './page-layout/page-layout-header.component';
|
import { PageLayoutHeaderComponent } from './page-layout/page-layout-header.component';
|
||||||
import { PageLayoutContentComponent } from './page-layout/page-layout-content.component';
|
import { PageLayoutContentComponent } from './page-layout/page-layout-content.component';
|
||||||
@@ -47,7 +48,8 @@ import { HttpClientModule } from '@angular/common/http';
|
|||||||
AppCommonModule,
|
AppCommonModule,
|
||||||
AppSidenavModule,
|
AppSidenavModule,
|
||||||
AppHeaderModule,
|
AppHeaderModule,
|
||||||
HttpClientModule
|
HttpClientModule,
|
||||||
|
AppUploadingDialogModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppLayoutComponent,
|
AppLayoutComponent,
|
||||||
|
@@ -0,0 +1,116 @@
|
|||||||
|
<div *ngIf="isDialogActive"
|
||||||
|
class="upload-dialog"
|
||||||
|
id="upload-dialog"
|
||||||
|
[class.upload-dialog--minimized]="isDialogMinimized"
|
||||||
|
[class.upload-dialog--position-left]="position === 'left'"
|
||||||
|
[class.upload-dialog--position-right]="position === 'right'">
|
||||||
|
<header class="upload-dialog__header">
|
||||||
|
<button
|
||||||
|
mat-button
|
||||||
|
color="secondary"
|
||||||
|
[disabled]="isConfirmation"
|
||||||
|
(click)="toggleMinimized()">
|
||||||
|
<mat-icon
|
||||||
|
mat-list-icon
|
||||||
|
title="{{ (isDialogMinimized ? 'ADF_FILE_UPLOAD.BUTTON.MAXIMIZE': 'ADF_FILE_UPLOAD.BUTTON.MINIMIZE') | translate }}">
|
||||||
|
{{ isDialogMinimized ? 'keyboard_arrow_up' : 'keyboard_arrow_down' }}
|
||||||
|
</mat-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="upload-dialog__title"
|
||||||
|
*ngIf="!uploadList.isUploadCancelled()">
|
||||||
|
{{ 'FILE_UPLOAD.MESSAGES.UPLOAD_COMPLETED'
|
||||||
|
| translate: {
|
||||||
|
completed: totalCompleted,
|
||||||
|
total: filesUploadingList.length
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="upload-dialog__title"
|
||||||
|
*ngIf="uploadList.isUploadCancelled()">
|
||||||
|
{{ 'FILE_UPLOAD.MESSAGES.UPLOAD_CANCELED' | translate }}
|
||||||
|
</span>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="upload-dialog__info"
|
||||||
|
*ngIf="totalErrors">
|
||||||
|
{{
|
||||||
|
(totalErrors > 1
|
||||||
|
? 'FILE_UPLOAD.MESSAGES.UPLOAD_ERRORS'
|
||||||
|
: 'FILE_UPLOAD.MESSAGES.UPLOAD_ERROR')
|
||||||
|
| translate: { total: totalErrors }
|
||||||
|
}}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="upload-dialog__content"
|
||||||
|
[class.upload-dialog--padding]="isConfirmation">
|
||||||
|
<app-file-uploading-list
|
||||||
|
[class.upload-dialog--hide]="isConfirmation"
|
||||||
|
#uploadList
|
||||||
|
[files]="filesUploadingList">
|
||||||
|
<ng-template let-file="$implicit">
|
||||||
|
<app-file-uploading-list-row
|
||||||
|
[file]="file"
|
||||||
|
[error]="getFileUploadError(file)"
|
||||||
|
(remove)="uploadList.removeFile(file)"
|
||||||
|
(cancel)="uploadList.cancelFile(file)">
|
||||||
|
</app-file-uploading-list-row>
|
||||||
|
</ng-template>
|
||||||
|
</app-file-uploading-list>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="upload-dialog__confirmation"
|
||||||
|
[class.upload-dialog--hide]="!isConfirmation">
|
||||||
|
<p class="upload-dialog__confirmation--title">
|
||||||
|
{{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TITLE' | translate }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="upload-dialog__confirmation--text">
|
||||||
|
{{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TEXT' | translate }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<footer class="upload-dialog__actions"
|
||||||
|
*ngIf="!isConfirmation">
|
||||||
|
<button
|
||||||
|
id="adf-upload-dialog-cancel-all"
|
||||||
|
color="primary"
|
||||||
|
mat-button
|
||||||
|
*ngIf="!uploadList.isUploadCompleted() && !uploadList.isUploadCancelled()"
|
||||||
|
(click)="toggleConfirmation()">
|
||||||
|
{{ 'ADF_FILE_UPLOAD.BUTTON.CANCEL_ALL' | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
id="adf-upload-dialog-close"
|
||||||
|
*ngIf="uploadList.isUploadCompleted() || uploadList.isUploadCancelled()"
|
||||||
|
mat-button
|
||||||
|
color="primary"
|
||||||
|
(click)="close()">
|
||||||
|
{{ 'ADF_FILE_UPLOAD.BUTTON.CLOSE' | translate }}
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<footer class="upload-dialog__actions"
|
||||||
|
*ngIf="isConfirmation">
|
||||||
|
<button
|
||||||
|
id="adf-upload-dialog-cancel"
|
||||||
|
color="secondary"
|
||||||
|
mat-button
|
||||||
|
(click)="cancelAllUploads()">
|
||||||
|
{{ 'ADF_FILE_UPLOAD.CONFIRMATION.BUTTON.CANCEL' | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
id="adf-upload-dialog-confirm"
|
||||||
|
mat-button
|
||||||
|
color="primary"
|
||||||
|
(click)="toggleConfirmation()">
|
||||||
|
{{ 'ADF_FILE_UPLOAD.CONFIRMATION.BUTTON.CONTINUE' | translate }}
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
@@ -0,0 +1,191 @@
|
|||||||
|
/*!
|
||||||
|
* @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,
|
||||||
|
FileUploadCompleteEvent,
|
||||||
|
FileUploadDeleteEvent,
|
||||||
|
FileUploadErrorEvent,
|
||||||
|
FileUploadStatus,
|
||||||
|
UploadService
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
|
import {
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Component,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
EventEmitter,
|
||||||
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
ViewChild
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Subscription, merge } from 'rxjs';
|
||||||
|
import { FileUploadingListComponent } from './file-uploading-list.component';
|
||||||
|
|
||||||
|
// @deprecated file-uploading-dialog TODO remove in 3.0.0
|
||||||
|
@Component({
|
||||||
|
selector: 'app-file-uploading-dialog',
|
||||||
|
templateUrl: './file-uploading-dialog.component.html'
|
||||||
|
})
|
||||||
|
export class FileUploadingDialogComponent implements OnInit, OnDestroy {
|
||||||
|
@ViewChild('uploadList')
|
||||||
|
uploadList: FileUploadingListComponent;
|
||||||
|
|
||||||
|
/** Dialog position. Can be 'left' or 'right'. */
|
||||||
|
@Input()
|
||||||
|
position = 'right';
|
||||||
|
|
||||||
|
/** Emitted when a file in the list has an error. */
|
||||||
|
@Output()
|
||||||
|
error: EventEmitter<any> = new EventEmitter();
|
||||||
|
|
||||||
|
filesUploadingList: FileModel[] = [];
|
||||||
|
isDialogActive = false;
|
||||||
|
totalCompleted = 0;
|
||||||
|
totalErrors = 0;
|
||||||
|
isDialogMinimized = false;
|
||||||
|
isConfirmation = false;
|
||||||
|
|
||||||
|
private listSubscription: Subscription;
|
||||||
|
private counterSubscription: Subscription;
|
||||||
|
private fileUploadSubscription: Subscription;
|
||||||
|
private errorSubscription: Subscription;
|
||||||
|
private errors = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private uploadService: UploadService,
|
||||||
|
private changeDetector: ChangeDetectorRef
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.listSubscription = this.uploadService.queueChanged.subscribe(
|
||||||
|
(fileList: FileModel[]) => {
|
||||||
|
this.filesUploadingList = fileList;
|
||||||
|
|
||||||
|
if (this.filesUploadingList.length) {
|
||||||
|
this.isDialogActive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.counterSubscription = merge(
|
||||||
|
this.uploadService.fileUploadComplete,
|
||||||
|
this.uploadService.fileUploadDeleted
|
||||||
|
).subscribe((event: FileUploadDeleteEvent | FileUploadCompleteEvent) => {
|
||||||
|
this.totalCompleted = event.totalComplete;
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
// todo: move to ADF ACA-2051
|
||||||
|
this.errorSubscription = this.uploadService.fileUploadError.subscribe(
|
||||||
|
(event: FileUploadErrorEvent) => {
|
||||||
|
this.errors.push({
|
||||||
|
fileName: event.file.name,
|
||||||
|
status: event.error.response.statusCode,
|
||||||
|
message: this.getUploadErrorMessage(event.error.response.statusCode)
|
||||||
|
});
|
||||||
|
this.totalErrors = event.totalError;
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.fileUploadSubscription = this.uploadService.fileUpload.subscribe(
|
||||||
|
event => {
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.uploadService.fileDeleted.subscribe(objId => {
|
||||||
|
if (this.filesUploadingList) {
|
||||||
|
const file = this.filesUploadingList.find(item => {
|
||||||
|
return item.data.entry.id === objId;
|
||||||
|
});
|
||||||
|
if (file) {
|
||||||
|
file.status = FileUploadStatus.Cancelled;
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getFileUploadError(file) {
|
||||||
|
return this.errors.find(error => (error.fileName = file.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle confirmation message.
|
||||||
|
*/
|
||||||
|
toggleConfirmation() {
|
||||||
|
this.isConfirmation = !this.isConfirmation;
|
||||||
|
|
||||||
|
if (this.isDialogMinimized) {
|
||||||
|
this.isDialogMinimized = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel uploads and hide confirmation
|
||||||
|
*/
|
||||||
|
cancelAllUploads() {
|
||||||
|
this.toggleConfirmation();
|
||||||
|
|
||||||
|
this.uploadList.cancelAllFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle dialog minimized state.
|
||||||
|
*/
|
||||||
|
toggleMinimized(): void {
|
||||||
|
this.isDialogMinimized = !this.isDialogMinimized;
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dismiss dialog
|
||||||
|
*/
|
||||||
|
close(): void {
|
||||||
|
this.isConfirmation = false;
|
||||||
|
this.totalCompleted = 0;
|
||||||
|
this.totalErrors = 0;
|
||||||
|
this.filesUploadingList = [];
|
||||||
|
this.isDialogActive = false;
|
||||||
|
this.isDialogMinimized = false;
|
||||||
|
this.uploadService.clearQueue();
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
this.errors = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.uploadService.clearQueue();
|
||||||
|
this.listSubscription.unsubscribe();
|
||||||
|
this.counterSubscription.unsubscribe();
|
||||||
|
this.fileUploadSubscription.unsubscribe();
|
||||||
|
this.errorSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: move to ADF ACA-2051
|
||||||
|
private getUploadErrorMessage(status) {
|
||||||
|
const messages = {
|
||||||
|
500: 'APP.MESSAGES.UPLOAD.ERROR.500',
|
||||||
|
504: 'APP.MESSAGES.UPLOAD.ERROR.504',
|
||||||
|
403: 'APP.MESSAGES.UPLOAD.ERROR.403',
|
||||||
|
404: 'APP.MESSAGES.UPLOAD.ERROR.404'
|
||||||
|
};
|
||||||
|
|
||||||
|
return messages[status];
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,81 @@
|
|||||||
|
<div class="adf-file-uploading-row">
|
||||||
|
<mat-icon
|
||||||
|
mat-list-icon
|
||||||
|
class="adf-file-uploading-row__type">
|
||||||
|
insert_drive_file
|
||||||
|
</mat-icon>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="adf-file-uploading-row__name"
|
||||||
|
title="{{ file.name }}">
|
||||||
|
{{ file.name }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div
|
||||||
|
*ngIf="file.status === FileUploadStatus.Progress || file.status === FileUploadStatus.Starting"
|
||||||
|
(click)="onCancel(file)"
|
||||||
|
class="adf-file-uploading-row__group adf-file-uploading-row__group--toggle"
|
||||||
|
title="{{ 'ADF_FILE_UPLOAD.BUTTON.CANCEL_FILE' | translate }}">
|
||||||
|
<span class="adf-file-uploading-row__status">
|
||||||
|
{{ file.progress.loaded | adfFileSize }} / {{ file.progress.total | adfFileSize }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<mat-icon
|
||||||
|
mat-list-icon
|
||||||
|
class="adf-file-uploading-row__action adf-file-uploading-row__action--cancel">
|
||||||
|
clear
|
||||||
|
</mat-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
*ngIf="file.status === FileUploadStatus.Complete"
|
||||||
|
(click)="onRemove(file)"
|
||||||
|
class="adf-file-uploading-row__group adf-file-uploading-row__group--toggle"
|
||||||
|
title="{{ 'ADF_FILE_UPLOAD.BUTTON.REMOVE_FILE' | translate }}">
|
||||||
|
<mat-icon
|
||||||
|
mat-list-icon
|
||||||
|
class="adf-file-uploading-row__status adf-file-uploading-row__status--done">
|
||||||
|
check_circle
|
||||||
|
</mat-icon>
|
||||||
|
|
||||||
|
<mat-icon
|
||||||
|
mat-list-icon
|
||||||
|
class="adf-file-uploading-row__action adf-file-uploading-row__action--remove">
|
||||||
|
remove_circle
|
||||||
|
</mat-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
*ngIf="file.status === FileUploadStatus.Pending"
|
||||||
|
(click)="onCancel(file)"
|
||||||
|
class="adf-file-uploading-row__group adf-file-uploading-row__group--toggle">
|
||||||
|
<mat-icon
|
||||||
|
mat-list-icon
|
||||||
|
class="adf-file-uploading-row__status adf-file-uploading-row__status--pending">
|
||||||
|
schedule
|
||||||
|
</mat-icon>
|
||||||
|
|
||||||
|
<mat-icon
|
||||||
|
mat-list-icon
|
||||||
|
class="adf-file-uploading-row__action adf-file-uploading-row__action--remove">
|
||||||
|
remove_circle
|
||||||
|
</mat-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--todo: move to ADF ACA-2051 -->
|
||||||
|
<div
|
||||||
|
*ngIf="file.status === FileUploadStatus.Error"
|
||||||
|
class="adf-file-uploading-row__block adf-file-uploading-row__status--error">
|
||||||
|
<mat-icon mat-list-icon [attr.title]="error?.message | translate">
|
||||||
|
report_problem
|
||||||
|
</mat-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
*ngIf="file.status === FileUploadStatus.Cancelled ||
|
||||||
|
file.status === FileUploadStatus.Aborted ||
|
||||||
|
file.status === FileUploadStatus.Deleted"
|
||||||
|
class="adf-file-uploading-row__block adf-file-uploading-row__status--cancelled">
|
||||||
|
{{ 'ADF_FILE_UPLOAD.STATUS.FILE_CANCELED_STATUS' | translate }}
|
||||||
|
</div>
|
||||||
|
<div>
|
@@ -0,0 +1,47 @@
|
|||||||
|
/*!
|
||||||
|
* @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 '@alfresco/adf-core';
|
||||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-file-uploading-list-row',
|
||||||
|
templateUrl: './file-uploading-list-row.component.html'
|
||||||
|
})
|
||||||
|
export class FileUploadingListRowComponent {
|
||||||
|
@Input()
|
||||||
|
file: FileModel;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
error: any;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
cancel: EventEmitter<FileModel> = new EventEmitter<FileModel>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
remove: EventEmitter<FileModel> = new EventEmitter<FileModel>();
|
||||||
|
|
||||||
|
FileUploadStatus = FileUploadStatus;
|
||||||
|
|
||||||
|
onCancel(file: FileModel): void {
|
||||||
|
this.cancel.emit(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemove(file: FileModel): void {
|
||||||
|
this.remove.emit(file);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
<div class="upload-list">
|
||||||
|
<ng-template
|
||||||
|
ngFor
|
||||||
|
[ngForOf]="files"
|
||||||
|
[ngForTemplate]="template">
|
||||||
|
</ng-template>
|
||||||
|
</div>
|
@@ -0,0 +1,180 @@
|
|||||||
|
/*!
|
||||||
|
* @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,
|
||||||
|
NodesApiService,
|
||||||
|
TranslationService,
|
||||||
|
UploadService
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
ContentChild,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
TemplateRef,
|
||||||
|
EventEmitter
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Observable, forkJoin, of } from 'rxjs';
|
||||||
|
import { map, catchError } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-file-uploading-list',
|
||||||
|
templateUrl: './file-uploading-list.component.html'
|
||||||
|
})
|
||||||
|
export class FileUploadingListComponent {
|
||||||
|
FileUploadStatus = FileUploadStatus;
|
||||||
|
|
||||||
|
@ContentChild(TemplateRef)
|
||||||
|
template: any;
|
||||||
|
|
||||||
|
@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 translateService: TranslationService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel file upload
|
||||||
|
*
|
||||||
|
* @param file File model to cancel upload for.
|
||||||
|
*
|
||||||
|
* @memberOf FileUploadingListComponent
|
||||||
|
*/
|
||||||
|
cancelFile(file: FileModel): void {
|
||||||
|
this.uploadService.cancelUpload(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFile(file: FileModel): void {
|
||||||
|
this.deleteNode(file).subscribe(() => {
|
||||||
|
if (file.status === FileUploadStatus.Error) {
|
||||||
|
this.notifyError(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.uploadService.cancelUpload(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call the appropriate method for each file, depending on state
|
||||||
|
*/
|
||||||
|
cancelAllFiles(): void {
|
||||||
|
this.getUploadingFiles().forEach(file =>
|
||||||
|
this.uploadService.cancelUpload(file)
|
||||||
|
);
|
||||||
|
|
||||||
|
const deletedFiles = this.files
|
||||||
|
.filter(file => file.status === FileUploadStatus.Complete)
|
||||||
|
.map(file => this.deleteNode(file));
|
||||||
|
|
||||||
|
forkJoin(...deletedFiles).subscribe((files: FileModel[]) => {
|
||||||
|
const errors = files.filter(
|
||||||
|
file => file.status === FileUploadStatus.Error
|
||||||
|
);
|
||||||
|
|
||||||
|
if (errors.length) {
|
||||||
|
this.notifyError(...errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.uploadService.cancelUpload(...files);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if all the files are uploaded false if there is at least one file in Progress | Starting | Pending
|
||||||
|
*/
|
||||||
|
isUploadCompleted(): boolean {
|
||||||
|
return (
|
||||||
|
!this.isUploadCancelled() &&
|
||||||
|
Boolean(this.files.length) &&
|
||||||
|
!this.files.some(
|
||||||
|
({ status }) =>
|
||||||
|
status === FileUploadStatus.Starting ||
|
||||||
|
status === FileUploadStatus.Progress ||
|
||||||
|
status === FileUploadStatus.Pending
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all the files are Cancelled | Aborted | Error. false if there is at least one file in uploading states
|
||||||
|
*/
|
||||||
|
isUploadCancelled(): boolean {
|
||||||
|
return (
|
||||||
|
!!this.files.length &&
|
||||||
|
this.files.every(
|
||||||
|
({ status }) =>
|
||||||
|
status === FileUploadStatus.Aborted ||
|
||||||
|
status === FileUploadStatus.Cancelled ||
|
||||||
|
status === FileUploadStatus.Deleted
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private deleteNode(file: FileModel): Observable<FileModel> {
|
||||||
|
const { id } = file.data.entry;
|
||||||
|
|
||||||
|
return this.nodesApi.deleteNode(id, { permanent: true }).pipe(
|
||||||
|
map(() => {
|
||||||
|
file.status = FileUploadStatus.Deleted;
|
||||||
|
return file;
|
||||||
|
}),
|
||||||
|
catchError(() => {
|
||||||
|
file.status = FileUploadStatus.Error;
|
||||||
|
return of(file);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private notifyError(...files: FileModel[]) {
|
||||||
|
let messageError: string = null;
|
||||||
|
|
||||||
|
if (files.length === 1) {
|
||||||
|
messageError = this.translateService.instant(
|
||||||
|
'FILE_UPLOAD.MESSAGES.REMOVE_FILE_ERROR',
|
||||||
|
{ fileName: files[0].name }
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
messageError = this.translateService.instant(
|
||||||
|
'FILE_UPLOAD.MESSAGES.REMOVE_FILES_ERROR',
|
||||||
|
{ total: files.length }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.error.emit(messageError);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getUploadingFiles() {
|
||||||
|
return this.files.filter(item => {
|
||||||
|
if (
|
||||||
|
item.status === FileUploadStatus.Pending ||
|
||||||
|
item.status === FileUploadStatus.Progress ||
|
||||||
|
item.status === FileUploadStatus.Starting
|
||||||
|
) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
46
src/app/components/upload-dialog/upload-dialog.module.ts
Normal file
46
src/app/components/upload-dialog/upload-dialog.module.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||||
|
*
|
||||||
|
* This file is part of the Alfresco Example Content Application.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { CoreModule } from '@alfresco/adf-core';
|
||||||
|
import { FileUploadingDialogComponent } from './file-uploading-dialog.component';
|
||||||
|
import { FileUploadingListRowComponent } from './file-uploading-list-row.component';
|
||||||
|
import { FileUploadingListComponent } from './file-uploading-list.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [CommonModule, CoreModule.forChild()],
|
||||||
|
declarations: [
|
||||||
|
FileUploadingDialogComponent,
|
||||||
|
FileUploadingListRowComponent,
|
||||||
|
FileUploadingListComponent
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
FileUploadingDialogComponent,
|
||||||
|
FileUploadingListRowComponent,
|
||||||
|
FileUploadingListComponent
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AppUploadingDialogModule {}
|
@@ -281,9 +281,12 @@
|
|||||||
},
|
},
|
||||||
"UPLOAD": {
|
"UPLOAD": {
|
||||||
"ERROR": {
|
"ERROR": {
|
||||||
"GENERIC": "There was a problem",
|
"GENERIC": "Upload unsuccessful. Contact IT if this problem persists",
|
||||||
"CONFLICT": "New version not uploaded, another file with the same name already exists",
|
"CONFLICT": "New version not uploaded, another file with the same name already exists",
|
||||||
"500": "There was a problem while uploading"
|
"500": "Internal server error, try again or contact IT support [500]",
|
||||||
|
"504": "The server timed out, try again or contact IT support [504]",
|
||||||
|
"403": "Insufficient permissions to upload in this location [403]",
|
||||||
|
"404": "Upload location no longer exists [404]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"INFO": {
|
"INFO": {
|
||||||
|
Reference in New Issue
Block a user