Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ACS-8508] Rework auto-download service #3990

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/

import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy, OnDestroy } from '@angular/core';
import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy, OnDestroy, inject } from '@angular/core';
import { NodeEntry, SearchEntryHighlight } from '@alfresco/js-api';
import { ViewNodeAction, NavigateToFolder } from '@alfresco/aca-shared/store';
import { Store } from '@ngrx/store';
import { BehaviorSubject, Subject } from 'rxjs';
import { NodesApiService } from '@alfresco/adf-content-services';
import { takeUntil } from 'rxjs/operators';
import { Router } from '@angular/router';
import { AcaFileAutoDownloadService } from '@alfresco/aca-shared';
import { AutoDownloadService, AppSettingsService } from '@alfresco/aca-shared';
import { CommonModule } from '@angular/common';
import { LocationLinkComponent } from '../../common/location-link/location-link.component';
import { MatDialogModule } from '@angular/material/dialog';
Expand All @@ -46,6 +46,8 @@ import { MatDialogModule } from '@angular/material/dialog';
host: { class: 'aca-search-results-row' }
})
export class SearchResultsRowComponent implements OnInit, OnDestroy {
private settings = inject(AppSettingsService);

private readonly highlightPrefix = "<span class='aca-highlight'>";
private readonly highlightPostfix = '</span>';

Expand All @@ -70,7 +72,7 @@ export class SearchResultsRowComponent implements OnInit, OnDestroy {
private store: Store<any>,
private nodesApiService: NodesApiService,
private router: Router,
private fileAutoDownloadService: AcaFileAutoDownloadService
private autoDownloadService: AutoDownloadService
) {}

ngOnInit() {
Expand Down Expand Up @@ -141,9 +143,8 @@ export class SearchResultsRowComponent implements OnInit, OnDestroy {

showPreview(event: Event) {
event.stopPropagation();
if (this.fileAutoDownloadService.shouldFileAutoDownload(this.node.entry.content.sizeInBytes)) {
this.fileAutoDownloadService.autoDownloadFile(this.node);
} else {

if (!this.settings.autoDownloadEnabled || !this.autoDownloadService.tryDownload(this.node, this.settings.authDownloadThreshold)) {
this.store.dispatch(new ViewNodeAction(this.node.entry.id, { location: this.router.url }));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/

import { Component, ViewEncapsulation, Input } from '@angular/core';
import { Component, ViewEncapsulation, Input, inject } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppStore, ViewNodeAction, getAppSelection } from '@alfresco/aca-shared/store';
import { ActivatedRoute, Router } from '@angular/router';
import { take } from 'rxjs/operators';
import { SharedLinkEntry } from '@alfresco/js-api';
import { AcaFileAutoDownloadService } from '@alfresco/aca-shared';
import { AutoDownloadService, AppSettingsService } from '@alfresco/aca-shared';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
Expand Down Expand Up @@ -60,12 +60,14 @@ import { MatDialogModule } from '@angular/material/dialog';
host: { class: 'app-view-node' }
})
export class ViewNodeComponent {
private settings = inject(AppSettingsService);

@Input() data: { title?: string; menuButton?: boolean; iconButton?: boolean };

constructor(
private store: Store<AppStore>,
private router: Router,
private fileAutoDownloadService: AcaFileAutoDownloadService,
private autoDownloadService: AutoDownloadService,
private activatedRoute: ActivatedRoute
) {}

Expand All @@ -74,9 +76,7 @@ export class ViewNodeComponent {
.select(getAppSelection)
.pipe(take(1))
.subscribe((selection) => {
if (this.fileAutoDownloadService.shouldFileAutoDownload(selection.file.entry?.content?.sizeInBytes)) {
this.fileAutoDownloadService.autoDownloadFile(selection.file);
} else {
if (!this.settings.autoDownloadEnabled || !this.autoDownloadService.tryDownload(selection.file, this.settings.authDownloadThreshold)) {
let id: string;

if (selection.file.entry.nodeType === 'app:filelink') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ import {
} from '@alfresco/aca-shared/store';
import { AppExtensionService } from '../../services/app.extension.service';
import { isLibrary, isLocked } from '../../utils/node.utils';
import { AcaFileAutoDownloadService } from '../../services/aca-file-auto-download.service';
import { AutoDownloadService } from '../../services/auto-download.service';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Router } from '@angular/router';
import { AppSettingsService } from '../../services/app-settings.service';

/* eslint-disable @angular-eslint/directive-class-suffix */
@Directive()
Expand All @@ -69,13 +70,14 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
createActions: Array<ContentActionRef> = [];
isSmallScreen = false;

protected settings = inject(AppSettingsService);
protected extensions = inject(AppExtensionService);
protected content = inject(DocumentBasePageService);
protected store = inject<Store<AppStore>>(Store<AppStore>);
protected breakpointObserver = inject(BreakpointObserver);
protected uploadService = inject(UploadService);
protected router = inject(Router);
private fileAutoDownloadService = inject(AcaFileAutoDownloadService, { optional: true });
private autoDownloadService = inject(AutoDownloadService, { optional: true });

protected subscriptions: Subscription[] = [];

Expand Down Expand Up @@ -143,9 +145,7 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {

showPreview(node: NodeEntry, extras?: ViewNodeExtras) {
if (node?.entry) {
if (this.fileAutoDownloadService?.shouldFileAutoDownload(node.entry?.content?.sizeInBytes)) {
this.fileAutoDownloadService.autoDownloadFile(node);
} else {
if (!this.settings.autoDownloadEnabled || !this.autoDownloadService.tryDownload(node, this.settings.authDownloadThreshold)) {
let id: string;

if (node.entry.nodeType === 'app:filelink') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@
*/

import { TestBed } from '@angular/core/testing';
import { AcaFileAutoDownloadService, initialState, LibTestingModule } from '@alfresco/aca-shared';
import { AutoDownloadService, initialState, LibTestingModule } from '@alfresco/aca-shared';
import { MatDialog } from '@angular/material/dialog';
import { AppConfigService } from '@alfresco/adf-core';
import { FileAutoDownloadComponent } from '@alfresco/adf-content-services';
import { provideMockStore } from '@ngrx/store/testing';

describe('AcaFileAutoDownloadService', () => {
let service: AcaFileAutoDownloadService;
let appConfig: AppConfigService;
let service: AutoDownloadService;

const mockDialogRef = {
open: jasmine.createSpy('open')
Expand All @@ -43,40 +41,24 @@ describe('AcaFileAutoDownloadService', () => {
providers: [provideMockStore({ initialState }), { provide: MatDialog, useValue: mockDialogRef }]
});

service = TestBed.inject(AcaFileAutoDownloadService);
appConfig = TestBed.inject(AppConfigService);
service = TestBed.inject(AutoDownloadService);
});

it('shouldFileAutoDownload should return true if fileSize exceeds configured threshold and file auto download is enabled', () => {
appConfig.config.viewer = {
enableFileAutoDownload: true,
fileAutoDownloadSizeThresholdInMB: 10
};
const shouldAutDownloadFlag = service.shouldFileAutoDownload(11000000);
expect(shouldAutDownloadFlag).toBe(true);
it('tryDownload should return true if fileSize exceeds configured threshold and file auto tryDownload is enabled', () => {
const node = { entry: { content: { sizeInBytes: 11000000 } } } as any;
const result = service.tryDownload(node, 10);
expect(result).toBe(true);
});

it('shouldFileAutoDownload should return false if fileSize does not exceeds configured threshold and file auto download is enabled', () => {
appConfig.config.viewer = {
enableFileAutoDownload: true,
fileAutoDownloadSizeThresholdInMB: 10
};
const shouldAutDownloadFlag = service.shouldFileAutoDownload(500000);
expect(shouldAutDownloadFlag).toBe(false);
it('tryDownload should return false if fileSize does not exceeds configured threshold and file auto tryDownload is enabled', () => {
const node = { entry: { content: { sizeInBytes: 500000 } } } as any;
const result = service.tryDownload(node, 10);
expect(result).toBe(false);
});

it('shouldFileAutoDownload should return false if fileSize exceeds configured threshold but file auto download is disabled', () => {
appConfig.config.viewer = {
enableFileAutoDownload: false,
fileAutoDownloadSizeThresholdInMB: 10
};
const shouldAutDownloadFlag = service.shouldFileAutoDownload(11000000);
expect(shouldAutDownloadFlag).toBe(false);
});

it('autoDownloadFile should open FileAutoDownload dialog when called', () => {
const nodeEntity: any = { entry: { isFile: true } };
service.autoDownloadFile(nodeEntity);
it('tryDownload should open the dialog when called', () => {
const nodeEntity: any = { entry: { isFile: true, content: { sizeInBytes: 11000000 } } };
service.tryDownload(nodeEntity, 10);
expect(mockDialogRef.open).toHaveBeenCalledWith(FileAutoDownloadComponent, { disableClose: true, data: nodeEntity });
});
});
14 changes: 14 additions & 0 deletions projects/aca-shared/src/lib/services/app-settings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,18 @@ export class AppSettingsService {
}
return result;
}

/**
* Gets the enablement of the file auto tryDownload feature from the app settings.
*/
get autoDownloadEnabled(): boolean {
return this.appConfig.get<boolean>('viewer.enableFileAutoDownload', true);
}

/**
* Gets the file auto tryDownload size threshold in MB from the app settings.
*/
get authDownloadThreshold(): number {
return this.appConfig.get<number>('viewer.fileAutoDownloadSizeThresholdInMB', 15);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/

import { Injectable } from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AppConfigService } from '@alfresco/adf-core';
import { NodeEntry } from '@alfresco/js-api';
import { FileAutoDownloadComponent } from '@alfresco/adf-content-services';

Expand All @@ -33,19 +32,28 @@ const BYTES_TO_MB_CONVERSION_VALUE = 1048576;
@Injectable({
providedIn: 'root'
})
export class AcaFileAutoDownloadService {
constructor(private dialog: MatDialog, private appConfig: AppConfigService) {}
export class AutoDownloadService {
private dialog = inject(MatDialog);

public shouldFileAutoDownload(fileSizeInBytes: number): boolean {
private shouldDownload(node: NodeEntry, threshold: number): boolean {
const fileSizeInBytes = node?.entry?.content?.sizeInBytes || 0;
const sizeInMB = fileSizeInBytes / BYTES_TO_MB_CONVERSION_VALUE;

const fileAutoDownloadFlag: boolean = this.appConfig.get('viewer.enableFileAutoDownload', true);
const sizeThreshold: number = this.appConfig.get('viewer.fileAutoDownloadSizeThresholdInMB', 15);

return fileAutoDownloadFlag && sizeInMB && sizeInMB > sizeThreshold;
return sizeInMB && sizeInMB > threshold;
}

public autoDownloadFile(node: NodeEntry) {
this.dialog.open(FileAutoDownloadComponent, { disableClose: true, data: node });
/**
* Opens the dialog to download the node content.
* Determines whether node content should be auto downloaded based on the file size and the configured threshold.
* @param node node entry
* @param threshold file size threshold in MB
*/
tryDownload(node: NodeEntry, threshold: number): boolean {
if (this.shouldDownload(node, threshold)) {
this.dialog.open(FileAutoDownloadComponent, { disableClose: true, data: node });
return true;
}

return false;
}
}
2 changes: 1 addition & 1 deletion projects/aca-shared/src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export * from './lib/services/node-permission.service';
export * from './lib/services/app.extension.service';
export * from './lib/services/router.extension.service';
export * from './lib/services/app-hook.service';
export * from './lib/services/aca-file-auto-download.service';
export * from './lib/services/auto-download.service';
export * from './lib/services/app-settings.service';
export * from './lib/services/user-profile.service';

Expand Down
Loading