From 7ad12f832af14c360bf2ed3858cc25cac7e89998 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Mon, 25 Feb 2019 11:27:19 +0200 Subject: [PATCH] [ACA-2207] Upload Dialog - restore previous version on delete (#951) * restore version over delete node * apply prettier * clean up unnecessary dependencies * remove style file * set CANCEL status on on deleted node version instances * Update upload.module.ts remove extra licence text * fix typo * remove duplicate strings --- .../app-layout/app-layout.component.html | 2 +- src/app/components/layout/layout.module.ts | 4 +- .../file-uploading-dialog.component.html | 133 +++++++++++ .../file-uploading-dialog.component.ts | 24 ++ .../file-uploading-list-row.component.html | 109 +++++++++ .../file-uploading-list-row.component.ts | 48 ++++ .../file-uploading-list.component.html | 4 + .../file-uploading-list.component.ts | 224 ++++++++++++++++++ .../components/upload-dialog/upload.module.ts | 47 ++++ .../ui/overrides/adf-upload-dialog.theme.scss | 22 ++ src/assets/i18n/en.json | 5 + 11 files changed, 620 insertions(+), 2 deletions(-) create mode 100644 src/app/components/upload-dialog/file-uploading-dialog.component.html create mode 100644 src/app/components/upload-dialog/file-uploading-dialog.component.ts create mode 100644 src/app/components/upload-dialog/file-uploading-list-row.component.html create mode 100644 src/app/components/upload-dialog/file-uploading-list-row.component.ts create mode 100644 src/app/components/upload-dialog/file-uploading-list.component.html create mode 100644 src/app/components/upload-dialog/file-uploading-list.component.ts create mode 100644 src/app/components/upload-dialog/upload.module.ts diff --git a/src/app/components/layout/app-layout/app-layout.component.html b/src/app/components/layout/app-layout/app-layout.component.html index e0e9a4733..2988e1ecb 100644 --- a/src/app/components/layout/app-layout/app-layout.component.html +++ b/src/app/components/layout/app-layout/app-layout.component.html @@ -32,5 +32,5 @@ - + diff --git a/src/app/components/layout/layout.module.ts b/src/app/components/layout/layout.module.ts index 78959e455..b7aa2d636 100644 --- a/src/app/components/layout/layout.module.ts +++ b/src/app/components/layout/layout.module.ts @@ -30,6 +30,7 @@ import { AppLayoutComponent } from './app-layout/app-layout.component'; import { ContentModule } from '@alfresco/adf-content-services'; import { RouterModule } from '@angular/router'; import { AppSidenavModule } from '../sidenav/sidenav.module'; +import { AppUploadingDialogModule } from '../upload-dialog/upload.module'; import { AppCommonModule } from '../common/common.module'; import { AppHeaderModule } from '../header/header.module'; import { PageLayoutComponent } from './page-layout/page-layout.component'; @@ -47,7 +48,8 @@ import { HttpClientModule } from '@angular/common/http'; AppCommonModule, AppSidenavModule, AppHeaderModule, - HttpClientModule + HttpClientModule, + AppUploadingDialogModule ], declarations: [ AppLayoutComponent, diff --git a/src/app/components/upload-dialog/file-uploading-dialog.component.html b/src/app/components/upload-dialog/file-uploading-dialog.component.html new file mode 100644 index 000000000..266df0a80 --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-dialog.component.html @@ -0,0 +1,133 @@ +
+
+ + + + {{ + 'FILE_UPLOAD.MESSAGES.UPLOAD_PROGRESS' + | translate + : { + completed: totalCompleted, + total: filesUploadingList.length + } + }} + + + + {{ 'FILE_UPLOAD.MESSAGES.UPLOAD_CANCELED' | translate }} + +
+ +
+ {{ + (totalErrors > 1 + ? 'FILE_UPLOAD.MESSAGES.UPLOAD_ERRORS' + : 'FILE_UPLOAD.MESSAGES.UPLOAD_ERROR') + | translate: { total: totalErrors } + }} +
+ +
+ + + + + + + +
+

+ {{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TITLE' | translate }} +

+ +

+ {{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TEXT' | translate }} +

+
+
+ +
+ + + +
+ +
+ + + +
+
diff --git a/src/app/components/upload-dialog/file-uploading-dialog.component.ts b/src/app/components/upload-dialog/file-uploading-dialog.component.ts new file mode 100644 index 000000000..129ec1f50 --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-dialog.component.ts @@ -0,0 +1,24 @@ +/*! + * @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 { Component } from '@angular/core'; +import { FileUploadingDialogComponent } from '@alfresco/adf-content-services'; +@Component({ + selector: 'app-file-uploading-dialog', + templateUrl: './file-uploading-dialog.component.html' +}) +export class AppFileUploadingDialogComponent extends FileUploadingDialogComponent {} diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.html b/src/app/components/upload-dialog/file-uploading-list-row.component.html new file mode 100644 index 000000000..315f70bfd --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-list-row.component.html @@ -0,0 +1,109 @@ +
+ + + insert_drive_file + + + + + + + {{ file.name }} + + + + {{ + versionNumber + }} + + +
+ + {{ file.progress.loaded | adfFileSize }} / + {{ file.progress.total | adfFileSize }} + + + + clear + +
+ +
+ + check_circle + + + + remove_circle + +
+ +
+ + schedule + + + + remove_circle + +
+ +
+ + report_problem + +
+ +
+ {{ 'ADF_FILE_UPLOAD.STATUS.FILE_CANCELED_STATUS' | translate }} +
+
diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.ts b/src/app/components/upload-dialog/file-uploading-list-row.component.ts new file mode 100644 index 000000000..688fc82ed --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-list-row.component.ts @@ -0,0 +1,48 @@ +/*! + * @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 { Component } from '@angular/core'; +import { FileUploadingListRowComponent } from '@alfresco/adf-content-services'; +@Component({ + selector: 'app-file-uploading-list-row', + templateUrl: './file-uploading-list-row.component.html' +}) +export class AppFileUploadingListRowComponent extends FileUploadingListRowComponent { + isUploadVersion() { + return ( + !!this.file.data && + this.file.options && + this.file.options.newVersion && + this.file.data.entry.properties && + this.file.data.entry.properties['cm:versionLabel'] + ); + } + + // todo: move to ADF 3.x.x + get versionNumber() { + return this.file.data.entry.properties['cm:versionLabel']; + } + + // todo: move to ADF 3.x.x + get mimeType(): string { + if (this.file && this.file.file && this.file.file.type) { + return this.file.file.type; + } + + return 'default'; + } +} diff --git a/src/app/components/upload-dialog/file-uploading-list.component.html b/src/app/components/upload-dialog/file-uploading-list.component.html new file mode 100644 index 000000000..475b084b1 --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-list.component.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/src/app/components/upload-dialog/file-uploading-list.component.ts b/src/app/components/upload-dialog/file-uploading-list.component.ts new file mode 100644 index 000000000..da8ea0add --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-list.component.ts @@ -0,0 +1,224 @@ +/*! + * @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, + AlfrescoApiService, + TranslationService, + UploadService +} from '@alfresco/adf-core'; +import { + Component, + ContentChild, + Input, + Output, + TemplateRef, + EventEmitter +} from '@angular/core'; +import { Observable, forkJoin, of, from } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; + +@Component({ + selector: 'app-file-uploading-list', + templateUrl: './file-uploading-list.component.html' +}) +export class AppFileUploadingListComponent { + FileUploadStatus = FileUploadStatus; + + @ContentChild(TemplateRef) + template: any; + + @Input() + files: FileModel[] = []; + + /** Emitted when a file in the list has an error. */ + @Output() + error: EventEmitter = new EventEmitter(); + + constructor( + private alfrescoApiService: AlfrescoApiService, + 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); + } + + // todo: move to ADF 3.x.x + removeFile(file: FileModel): void { + if (file.options && file.options.newVersion) { + this.deleteNodeVersion(file).subscribe(() => { + if (file.status === FileUploadStatus.Error) { + this.notifyError(file); + } + this.uploadService.cancelUpload(file); + }); + } else { + this.deleteNode(file).subscribe(() => { + if (file.status === FileUploadStatus.Error) { + this.notifyError(file); + } + + this.cancelNodeVersionInstances(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 + ) + ); + } + + // todo: move to ADF 3.x.x + private deleteNodeVersion(file: FileModel): Observable { + return from( + this.alfrescoApiService.versionsApi.deleteVersion( + file.data.entry.id, + file.data.entry.properties['cm:versionLabel'] + ) + ).pipe( + map(() => { + file.status = FileUploadStatus.Deleted; + return file; + }), + catchError(() => { + file.status = FileUploadStatus.Error; + return of(file); + }) + ); + } + + // todo: move to ADF 3.x.x + private cancelNodeVersionInstances(file) { + this.files + .filter( + item => + item.data.entry.id === file.data.entry.id && item.options.newVersion + ) + .map(item => { + item.status = FileUploadStatus.Deleted; + }); + } + + private deleteNode(file: FileModel): Observable { + 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; + } + }); + } +} diff --git a/src/app/components/upload-dialog/upload.module.ts b/src/app/components/upload-dialog/upload.module.ts new file mode 100644 index 000000000..12e3060d2 --- /dev/null +++ b/src/app/components/upload-dialog/upload.module.ts @@ -0,0 +1,47 @@ +/*! + * @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 . + */ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { CoreModule } from '@alfresco/adf-core'; +import { AppFileUploadingDialogComponent } from './file-uploading-dialog.component'; +import { AppFileUploadingListRowComponent } from './file-uploading-list-row.component'; +import { AppFileUploadingListComponent } from './file-uploading-list.component'; +import { UploadModule } from '@alfresco/adf-content-services'; + +@NgModule({ + imports: [CommonModule, CoreModule.forChild(), UploadModule], + declarations: [ + AppFileUploadingDialogComponent, + AppFileUploadingListRowComponent, + AppFileUploadingListComponent + ], + exports: [ + AppFileUploadingDialogComponent, + AppFileUploadingListRowComponent, + AppFileUploadingListComponent + ] +}) +export class AppUploadingDialogModule {} diff --git a/src/app/ui/overrides/adf-upload-dialog.theme.scss b/src/app/ui/overrides/adf-upload-dialog.theme.scss index 9dca64b86..364f2f44c 100644 --- a/src/app/ui/overrides/adf-upload-dialog.theme.scss +++ b/src/app/ui/overrides/adf-upload-dialog.theme.scss @@ -7,6 +7,28 @@ z-index: 999; } + // todo: move to ADF 3.x.x + .adf-file-uploading-row { + &__group, + &__block { + min-width: 100px; + display: flex; + justify-content: flex-end; + } + + &__version { + flex: 0; + + .mat-chip { + padding: 2px 6px; + } + + .mat-chip.mat-chip-disabled { + opacity: 1; + } + } + } + .adf-file-uploading-row { &__status { &--done { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 6f214673e..83e55abe5 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -467,6 +467,11 @@ "INFO": "View details" } }, + "FILE_UPLOAD": { + "ERRORS": { + "409": "This name is already in use, try a different name [409]" + } + }, "ADF_VERSION_LIST": { "ACTIONS": { "UPLOAD": {