[MNT-24128] in ADW/ADF, when downloading a ZIP from a selection of files and folders, display a progress bar (#9957)

This commit is contained in:
jacekpluta
2024-07-30 14:56:03 +02:00
committed by GitHub
parent 33b669cf1c
commit 9cb01e2085
9 changed files with 93 additions and 12 deletions

View File

@@ -1,6 +1,12 @@
<h1 matDialogTitle>{{ 'CORE.DIALOG.DOWNLOAD_ZIP.TITLE' | translate }}</h1> <h1 matDialogTitle>{{ 'CORE.DIALOG.DOWNLOAD_ZIP.TITLE' | translate }}</h1>
<div mat-dialog-content> <div mat-dialog-content class="adf-dialog-content">
<mat-progress-bar color="primary" mode="indeterminate"></mat-progress-bar> <mat-progress-bar value="{{ percentageDone }}" color="primary" mode="determinate"></mat-progress-bar>
<div class="adf-dialog-content-progress-text">
<span class="adf-dialog-content-progress-text-percentage">
{{ percentageDone }}%
</span>
{{ 'CORE.DIALOG.DOWNLOAD_ZIP.COMPLETE' | translate }}
</div>
</div> </div>
<mat-dialog-actions align="end"> <mat-dialog-actions align="end">
<button class="adf-download-zip-dialog-button" mat-button color="primary" id="cancel-button" (click)="cancelDownload()"> <button class="adf-download-zip-dialog-button" mat-button color="primary" id="cancel-button" (click)="cancelDownload()">

View File

@@ -1,3 +1,15 @@
.adf-download-zip-dialog-button { .adf-download-zip-dialog-button {
text-transform: uppercase; text-transform: uppercase;
} }
.adf-dialog-content:has(.adf-dialog-content-progress-text) {
padding: 0;
.adf-dialog-content-progress-text {
margin-top: 4px;
&-percentage {
font-weight: 900;
}
}
}

View File

@@ -19,6 +19,7 @@ import { TestBed, ComponentFixture } from '@angular/core/testing';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { DownloadZipDialogComponent } from './download-zip.dialog'; import { DownloadZipDialogComponent } from './download-zip.dialog';
import { DownloadZipService } from './services/download-zip.service'; import { DownloadZipService } from './services/download-zip.service';
import { DownloadEntry, FileDownloadStatus } from '@alfresco/js-api';
import { EMPTY, Observable, of } from 'rxjs'; import { EMPTY, Observable, of } from 'rxjs';
import { AlfrescoApiService, AlfrescoApiServiceMock, RedirectAuthService, TranslationMock, TranslationService } from '@alfresco/adf-core'; import { AlfrescoApiService, AlfrescoApiServiceMock, RedirectAuthService, TranslationMock, TranslationService } from '@alfresco/adf-core';
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing';
@@ -167,4 +168,28 @@ describe('DownloadZipDialogComponent', () => {
expect(component.cancelDownload).toHaveBeenCalled(); expect(component.cancelDownload).toHaveBeenCalled();
expect(component.download).not.toHaveBeenCalled(); expect(component.download).not.toHaveBeenCalled();
}); });
it('should waitForDownload and display correct download %', () => {
const downloadEntry$: Observable<DownloadEntry> = new Observable((observer) => {
observer.next({
entry: {
filesAdded: 10,
bytesAdded: 1000,
id: '1',
totalFiles: 10,
totalBytes: 1000,
status: FileDownloadStatus.DONE
}
});
observer.complete();
});
const downloadZipSpy = spyOn(downloadZipService, 'getDownload').and.callFake(() => downloadEntry$);
component.waitAndDownload('1', 'testUrl', 'filename');
fixture.detectChanges();
expect(downloadZipSpy).toHaveBeenCalledWith('1');
expect(component.percentageDone).toBe(100);
});
}); });

View File

@@ -19,6 +19,7 @@ import { Component, Input, OnInit, OnChanges } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { DownloadZipDialogComponent } from './download-zip.dialog'; import { DownloadZipDialogComponent } from './download-zip.dialog';
import { zipNode, downloadEntry } from './mock/download-zip-data.mock'; import { zipNode, downloadEntry } from './mock/download-zip-data.mock';
import { FileDownloadStatus } from '@alfresco/js-api';
@Component({ @Component({
selector: 'adf-download-zip-dialog-storybook', selector: 'adf-download-zip-dialog-storybook',
@@ -38,11 +39,11 @@ export class DownloadZipDialogStorybookComponent implements OnInit, OnChanges {
this.setEntryStatus(this.showLoading); this.setEntryStatus(this.showLoading);
} }
setEntryStatus(isLoading: boolean){ setEntryStatus(isLoading: boolean) {
if (!isLoading) { if (!isLoading) {
downloadEntry.entry.status = 'DONE'; downloadEntry.entry.status = FileDownloadStatus.DONE;
} else { } else {
downloadEntry.entry.status = 'PACKING'; downloadEntry.entry.status = FileDownloadStatus.IN_PROGRESS;
} }
} }

View File

@@ -20,6 +20,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { NodesApiService } from '../../common/services/nodes-api.service'; import { NodesApiService } from '../../common/services/nodes-api.service';
import { DownloadZipService } from './services/download-zip.service'; import { DownloadZipService } from './services/download-zip.service';
import { ContentService } from '../../common/services/content.service'; import { ContentService } from '../../common/services/content.service';
import { FileDownloadStatus } from '@alfresco/js-api';
@Component({ @Component({
selector: 'adf-download-zip-dialog', selector: 'adf-download-zip-dialog',
@@ -32,6 +33,7 @@ export class DownloadZipDialogComponent implements OnInit {
// flag for async threads // flag for async threads
cancelled = false; cancelled = false;
downloadId: string; downloadId: string;
percentageDone = 0;
constructor( constructor(
private dialogRef: MatDialogRef<DownloadZipDialogComponent>, private dialogRef: MatDialogRef<DownloadZipDialogComponent>,
@@ -79,7 +81,12 @@ export class DownloadZipDialogComponent implements OnInit {
this.downloadZipService.getDownload(downloadId).subscribe((downloadEntry) => { this.downloadZipService.getDownload(downloadId).subscribe((downloadEntry) => {
if (downloadEntry.entry) { if (downloadEntry.entry) {
if (downloadEntry.entry.status === 'DONE') { if (downloadEntry.entry.status === FileDownloadStatus.IN_PROGRESS) {
this.percentageDone = Number(((downloadEntry.entry.bytesAdded * 100) / downloadEntry.entry.totalBytes).toFixed(2));
}
if (downloadEntry.entry.status === FileDownloadStatus.DONE) {
this.percentageDone = 100;
this.download(url, fileName); this.download(url, fileName);
} else { } else {
setTimeout(() => { setTimeout(() => {

View File

@@ -107,7 +107,8 @@
"ACTIONS": { "ACTIONS": {
"CANCEL": "Cancel" "CANCEL": "Cancel"
}, },
"TITLE": "Adding files to zip, this could take a few minutes" "TITLE": "Adding files to zip, this could take a few minutes",
"COMPLETE": "complete"
}, },
"EDIT_JSON": { "EDIT_JSON": {
"CLOSE": "Close", "CLOSE": "Close",

View File

@@ -0,0 +1,26 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 const FileDownloadStatus = {
PENDING: 'PENDING',
CANCELLED: 'CANCELLED',
IN_PROGRESS: 'IN_PROGRESS',
DONE: 'DONE',
MAX_CONTENT_SIZE_EXCEEDED: 'MAX_CONTENT_SIZE_EXCEEDED'
} as const;
export type DownloadStatus = keyof typeof FileDownloadStatus;

View File

@@ -15,6 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { DownloadStatus } from './download-status';
export interface Download { export interface Download {
/** /**
* number of files added so far in the zip * number of files added so far in the zip
@@ -39,5 +41,5 @@ export interface Download {
/** /**
* the current status of the download node creation * the current status of the download node creation
*/ */
status?: 'PENDING' | 'CANCELLED' | 'IN_PROGRESS' | 'DONE' | 'MAX_CONTENT_SIZE_EXCEEDED' | string; status?: DownloadStatus;
} }

View File

@@ -68,6 +68,7 @@ export * from './deletedNodesPagingList';
export * from './directAccessUrl'; export * from './directAccessUrl';
export * from './directAccessUrlEntry'; export * from './directAccessUrlEntry';
export * from './download'; export * from './download';
export * from './download-status';
export * from './downloadBodyCreate'; export * from './downloadBodyCreate';
export * from './downloadEntry'; export * from './downloadEntry';
export * from './errorError'; export * from './errorError';