[ACA-4681] Added file auto download feature to DocumentList component (#8423)

* [ACA-4681] Added feature in DocumentListComponent to auto download a file if it exceeds a pre defined file size threshold

* [ACA-4681] Added test cases for file auto download feature in document list (NOT WORKING)

* [ACA-4681] Fixed unit tests for file auto download feature of document list

* [ACA-4681] Removed unused variables from app.config.json

* [ACA-4681] Resolved code review findings. Local constants are no longer upper case only (used camelCase instead). FileAutoDownload component template now uses mat-dialog provided directives and components. Removed file-auto-download.component.scss. Removed unused methods from file-auto-download.component.ts

* [ACA-4681] Added licence info to file-auto-download-actions.enum.ts

* [ACA-4681] Added license info to file-auto-download.component.ts

* [ACA-4681] Removed empty constructor

* [ACA-4681] Updated appConfig property name from "preview-config" to "viewer".

* [ACA-4681] Added JSDoc for FileAutoDownloadActionsEnum

* [ACA-4681] Updated ADF demo shell application to use "viewer" appConfig object instead of "preview-config"

* [ACA-4681] Resolved lint issues

* [ACA-4681] Removed dependency from NodeActionsService inside DocumentListComponent. FileAutoDownload component now directly triggers the file download, instead of emitting FileAutoDownloadActionsEnum.Download.

* [ACA-4681] Removed unused async. Updated import statement

* [ACA-4681] Added FileAutoDownloadComponent to public-api.ts
This commit is contained in:
swapnil-verma-gl
2023-04-04 13:01:23 +05:30
committed by GitHub
parent 2bd72f71d5
commit fc3ad78004
12 changed files with 247 additions and 7 deletions

View File

@@ -27,7 +27,7 @@ import {
DataTableModule,
ObjectDataTableAdapter,
ShowHeaderMode,
ThumbnailService
ThumbnailService, AppConfigService
} from '@alfresco/adf-core';
import { ContentService } from '../../common/services/content.service';
@@ -62,6 +62,12 @@ import { ShareDataRow } from '../data/share-data-row.model';
import { DocumentLoaderNode } from '../models/document-folder.model';
import { matIconRegistryMock } from '../../testing/mat-icon-registry-mock';
import { domSanitizerMock } from '../../testing/dom-sanitizer-mock';
import { MatDialog } from '@angular/material/dialog';
import { FileAutoDownloadComponent } from './file-auto-download/file-auto-download.component';
const mockDialog = {
open: jasmine.createSpy('open')
};
describe('DocumentList', () => {
@@ -71,6 +77,7 @@ describe('DocumentList', () => {
let customResourcesService: CustomResourcesService;
let thumbnailService: ThumbnailService;
let contentService: ContentService;
let appConfigService: AppConfigService;
let fixture: ComponentFixture<DocumentListComponent>;
let element: HTMLElement;
let eventMock: any;
@@ -84,7 +91,10 @@ describe('DocumentList', () => {
TranslateModule.forRoot(),
ContentTestingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: MatDialog, useValue: mockDialog }
]
});
beforeEach(() => {
@@ -102,6 +112,7 @@ describe('DocumentList', () => {
customResourcesService = TestBed.inject(CustomResourcesService);
thumbnailService = TestBed.inject(ThumbnailService);
contentService = TestBed.inject(ContentService);
appConfigService = TestBed.inject(AppConfigService);
spyFolder = spyOn(documentListService, 'getFolder').and.returnValue(of({ list: {} }));
spyFolderNode = spyOn(documentListService, 'getFolderNode').and.returnValue(of(new NodeEntry({ entry: {} })));
@@ -1567,6 +1578,30 @@ describe('DocumentList', () => {
}), undefined);
});
it('should display fileAutoDownload dialog if node size exceeds appConfig.viewer.fileAutoDownloadSizeThresholdInMB', async () => {
appConfigService.config = {
...appConfigService.config,
'viewer': {
'enableFileAutoDownload': true,
'fileAutoDownloadSizeThresholdInMB': 10
}
};
documentList.navigationMode = DocumentListComponent.SINGLE_CLICK_NAVIGATION;
const node = { entry: {
...mockNode1,
content: {
...mockNode1.content,
sizeInBytes: 104857600
}
} };
documentList.onNodeClick(node);
fixture.detectChanges();
await fixture.whenStable();
expect(mockDialog.open).toHaveBeenCalledWith(FileAutoDownloadComponent, { disableClose: true, data: node });
});
describe('Preselect nodes', () => {
beforeEach(() => {

View File

@@ -66,6 +66,10 @@ import { LockService } from '../services/lock.service';
import { DocumentLoaderNode } from '../models/document-folder.model';
import { takeUntil } from 'rxjs/operators';
import { ADF_DOCUMENT_PARENT_COMPONENT } from './document-list.token';
import { MatDialog } from '@angular/material/dialog';
import { FileAutoDownloadComponent } from './file-auto-download/file-auto-download.component';
const BYTES_TO_MB_CONVERSION_VALUE = 1048576;
@Component({
selector: 'adf-document-list',
@@ -367,7 +371,8 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
private alfrescoApiService: AlfrescoApiService,
private nodeService: NodesApiService,
private dataTableService: DataTableService,
private lockService: LockService) {
private lockService: LockService,
private dialog: MatDialog) {
this.nodeService.nodeUpdated.subscribe((node) => {
this.dataTableService.rowUpdate.next({id: node.id, obj: {entry: node}});
@@ -758,7 +763,16 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
onPreviewFile(node: NodeEntry) {
if (node) {
this.preview.emit(new NodeEntityEvent(node));
const sizeInMB = node.entry?.content?.sizeInBytes / BYTES_TO_MB_CONVERSION_VALUE;
const fileAutoDownloadFlag: boolean = this.appConfig.get('viewer.enableFileAutoDownload', true);
const sizeThreshold: number = this.appConfig.get('viewer.fileAutoDownloadSizeThresholdInMB', 15);
if (fileAutoDownloadFlag && sizeInMB && sizeInMB > sizeThreshold) {
this.dialog.open(FileAutoDownloadComponent, { disableClose: true, data: node });
} else {
this.preview.emit(new NodeEntityEvent(node));
}
}
}

View File

@@ -0,0 +1,24 @@
<div mat-dialog-title>
<h3>{{ 'ADF-DOCUMENT-LIST.FILE_AUTO_DOWNLOAD_DIALOG.HEADER' | translate }}</h3>
</div>
<mat-dialog-content>
{{ 'ADF-DOCUMENT-LIST.FILE_AUTO_DOWNLOAD_DIALOG.LABEL' | translate }}
</mat-dialog-content>
<mat-dialog-actions align="end">
<button
mat-button
mat-dialog-close
id="cancelButton"
[attr.aria-label]="'ADF-DOCUMENT-LIST.FILE_AUTO_DOWNLOAD_DIALOG.ACTIONS.CANCEL' | translate">
{{ 'ADF-DOCUMENT-LIST.FILE_AUTO_DOWNLOAD_DIALOG.ACTIONS.CANCEL' | translate }}
</button>
<button
mat-button
mat-dialog-close
id="downloadButton"
color="primary"
[attr.aria-label]="'ADF-DOCUMENT-LIST.FILE_AUTO_DOWNLOAD_DIALOG.ACTIONS.DOWNLOAD' | translate"
[adfNodeDownload]="node">
{{ 'ADF-DOCUMENT-LIST.FILE_AUTO_DOWNLOAD_DIALOG.ACTIONS.DOWNLOAD' | translate }}
</button>
</mat-dialog-actions>

View File

@@ -0,0 +1,76 @@
/*!
* @license
* Copyright 2019 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 { ComponentFixture, TestBed } from '@angular/core/testing';
import { FileAutoDownloadComponent } from './file-auto-download.component';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { By } from '@angular/platform-browser';
import { CoreTestingModule } from '@alfresco/adf-core';
import { TranslateModule } from '@ngx-translate/core';
import { NO_ERRORS_SCHEMA } from '@angular/core';
const mockDialog = {
close: jasmine.createSpy('close')
};
describe('FileAutoDownloadComponent', () => {
let matDialogRef: MatDialogRef<FileAutoDownloadComponent>;
let fixture: ComponentFixture<FileAutoDownloadComponent>;
const getButton = (buttonId: string) => {
return fixture.debugElement.query(By.css(buttonId)).nativeElement;
};
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [FileAutoDownloadComponent],
imports: [
TranslateModule.forRoot(),
CoreTestingModule
],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{ provide: MatDialogRef, useValue: mockDialog },
{ provide: MAT_DIALOG_DATA, useValue: null }
]
});
fixture = TestBed.createComponent(FileAutoDownloadComponent);
matDialogRef = TestBed.inject(MatDialogRef);
fixture.detectChanges();
});
it('should emit FileAutoDownloadActionsEnum.CANCEL and close dialog when clicking on the cancel button', async () => {
const waitButton = getButton('#cancelButton');
waitButton.dispatchEvent(new Event('click'));
await fixture.detectChanges();
await fixture.whenStable();
expect(matDialogRef.close).toHaveBeenCalled();
});
it('should emit FileAutoDownloadActionsEnum.DOWNLOAD and close dialog when clicking on the wait button', async () => {
const waitButton = getButton('#downloadButton');
waitButton.dispatchEvent(new Event('click'));
await fixture.detectChanges();
await fixture.whenStable();
expect(matDialogRef.close).toHaveBeenCalled();
});
});

View File

@@ -0,0 +1,28 @@
/*!
* @license
* Copyright 2019 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, Inject } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { NodeEntry } from '@alfresco/js-api';
@Component({
selector: 'adf-file-auto-download',
templateUrl: './file-auto-download.component.html'
})
export class FileAutoDownloadComponent {
constructor(@Inject(MAT_DIALOG_DATA) public node: NodeEntry) {}
}

View File

@@ -35,6 +35,8 @@ import { LibraryRoleColumnComponent } from './components/library-role-column/lib
import { LibraryNameColumnComponent } from './components/library-name-column/library-name-column.component';
import { NameColumnComponent } from './components/name-column/name-column.component';
import { FilterHeaderComponent } from './components/filter-header/filter-header.component';
import { FileAutoDownloadComponent } from './components/file-auto-download/file-auto-download.component';
import { ContentDirectiveModule } from '../directives/content-directive.module';
@NgModule({
imports: [
@@ -45,7 +47,8 @@ import { FilterHeaderComponent } from './components/filter-header/filter-header.
MaterialModule,
UploadModule,
EditJsonDialogModule,
SearchModule
SearchModule,
ContentDirectiveModule
],
declarations: [
DocumentListComponent,
@@ -56,7 +59,8 @@ import { FilterHeaderComponent } from './components/filter-header/filter-header.
NameColumnComponent,
ContentActionComponent,
ContentActionListComponent,
FilterHeaderComponent
FilterHeaderComponent,
FileAutoDownloadComponent
],
exports: [
DocumentListComponent,

View File

@@ -25,6 +25,7 @@ export * from './components/library-status-column/library-status-column.componen
export * from './components/name-column/name-column.component';
export * from './components/filter-header/filter-header.component';
export * from './components/trashcan-name-column/trashcan-name-column.component';
export * from './components/file-auto-download/file-auto-download.component';
// data
export * from './data/share-datatable-adapter';

View File

@@ -73,7 +73,15 @@
"REMOVE": "Remove",
"DOWNLOAD": "Download"
},
"LOADER_LABEL": "Document list loader"
"LOADER_LABEL": "Document list loader",
"FILE_AUTO_DOWNLOAD_DIALOG": {
"HEADER": "Preview loading unresponsive",
"LABEL": "Download to view this document, or cancel to continue without preview.",
"ACTIONS": {
"CANCEL": "Cancel",
"DOWNLOAD": "Download"
}
}
},
"ALFRESCO_DOCUMENT_LIST": {
"BUTTON": {