[AAE-10777] Move services from Core in Content the right place (#8242)

Clean core services and directive
This commit is contained in:
Eugenio Romano
2023-03-10 09:28:24 +01:00
committed by GitHub
parent 112e272ce7
commit 2590e7d0a9
263 changed files with 884 additions and 3393 deletions

View File

@@ -16,7 +16,8 @@
*/
import { ChangeDetectorRef, Component, ElementRef, SimpleChange } from '@angular/core';
import { ContentService, CoreTestingModule, setupTestBed } from '@alfresco/adf-core';
import { CoreTestingModule, setupTestBed } from '@alfresco/adf-core';
import { ContentService } from '../common/services/content.service';
import { CheckAllowableOperationDirective } from './check-allowable-operation.directive';
import { TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';

View File

@@ -19,7 +19,8 @@
import { ChangeDetectorRef, Directive, ElementRef, Host, Inject, Input, OnChanges, Optional, Renderer2, SimpleChanges } from '@angular/core';
import { NodeEntry } from '@alfresco/js-api';
import { ContentService, EXTENDIBLE_COMPONENT } from '@alfresco/adf-core';
import { EXTENDIBLE_COMPONENT } from '@alfresco/adf-core';
import { ContentService } from '../common/services/content.service';
import { NodeAllowableOperationSubject } from '../interfaces/node-allowable-operation-subject.interface';
@Directive({

View File

@@ -29,6 +29,7 @@ import { LibraryMembershipDirective } from './library-membership.directive';
import { NodeDeleteDirective } from './node-delete.directive';
import { NodeFavoriteDirective } from './node-favorite.directive';
import { NodeRestoreDirective } from './node-restore.directive';
import { NodeDownloadDirective } from './node-download.directive';
@NgModule({
imports: [
@@ -46,7 +47,8 @@ import { NodeRestoreDirective } from './node-restore.directive';
LibraryMembershipDirective,
NodeDeleteDirective,
NodeFavoriteDirective,
NodeRestoreDirective
NodeRestoreDirective,
NodeDownloadDirective
],
exports: [
NodeLockDirective,
@@ -57,7 +59,8 @@ import { NodeRestoreDirective } from './node-restore.directive';
LibraryMembershipDirective,
NodeDeleteDirective,
NodeFavoriteDirective,
NodeRestoreDirective
NodeRestoreDirective,
NodeDownloadDirective
]
})
export class ContentDirectiveModule {

View File

@@ -0,0 +1,190 @@
/*!
* @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 { TestBed, ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { MatDialog } from '@angular/material/dialog';
import { Component, DebugElement, ViewChild } from '@angular/core';
import { setupTestBed, AlfrescoApiService, CoreTestingModule } from '@alfresco/adf-core';
import { NodeDownloadDirective } from './node-download.directive';
import { TranslateModule } from '@ngx-translate/core';
import { ContentDirectiveModule } from '@alfresco/adf-content-services';
@Component({
template: '<div [adfNodeDownload]="selection" [version]="version"></div>'
})
class TestComponent {
@ViewChild(NodeDownloadDirective, { static: true })
downloadDirective: NodeDownloadDirective;
selection;
version;
}
describe('NodeDownloadDirective', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
let element: DebugElement;
let dialog: MatDialog;
let apiService: AlfrescoApiService;
let contentService;
let dialogSpy;
const mockOauth2Auth: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
},
isEcmLoggedIn: jasmine.createSpy('isEcmLoggedIn'),
reply: jasmine.createSpy('reply')
};
setupTestBed({
imports: [
ContentDirectiveModule,
TranslateModule.forRoot(),
CoreTestingModule
],
declarations: [
TestComponent
]
});
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
element = fixture.debugElement.query(By.directive(NodeDownloadDirective));
dialog = TestBed.inject(MatDialog);
apiService = TestBed.inject(AlfrescoApiService);
contentService = component.downloadDirective['contentApi'];
dialogSpy = spyOn(dialog, 'open');
});
it('should not download node when selection is empty', () => {
spyOn(apiService, 'getInstance').and.returnValue(mockOauth2Auth);
component.selection = [];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(apiService.getInstance).not.toHaveBeenCalled();
});
it('should not download zip when selection has no nodes', () => {
component.selection = [];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(dialogSpy).not.toHaveBeenCalled();
});
it('should download selected node as file', () => {
spyOn(contentService, 'getContentUrl');
const node = { entry: { id: 'node-id', isFile: true } };
component.selection = [node];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(contentService.getContentUrl).toHaveBeenCalledWith(node.entry.id, true);
});
it('should download selected node version as file', () => {
component.version = {
entry: {
id: '1.0'
}
};
spyOn(contentService, 'getVersionContentUrl');
const node = {entry: {id: 'node-id', isFile: true}};
component.selection = [node];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(contentService.getVersionContentUrl).toHaveBeenCalledWith(node.entry.id, '1.0', true);
});
it('should download selected shared node as file', () => {
spyOn(contentService, 'getContentUrl');
const node = { entry: { nodeId: 'shared-node-id', isFile: true } };
component.selection = [node];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(contentService.getContentUrl).toHaveBeenCalledWith(node.entry.nodeId, true);
});
it('should download selected files nodes as zip', () => {
const node1 = { entry: { id: 'node-1' } };
const node2 = { entry: { id: 'node-2' } };
component.selection = [node1, node2];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(dialogSpy.calls.argsFor(0)[1].data).toEqual({ nodeIds: [ 'node-1', 'node-2' ] });
});
it('should download selected shared files nodes as zip', () => {
const node1 = { entry: { nodeId: 'shared-node-1' } };
const node2 = { entry: { nodeId: 'shared-node-2' } };
component.selection = [node1, node2];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(dialogSpy.calls.argsFor(0)[1].data).toEqual({ nodeIds: [ 'shared-node-1', 'shared-node-2' ] });
});
it('should download selected folder node as zip', () => {
const node = { entry: { isFolder: true, id: 'node-id' } };
component.selection = [node];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(dialogSpy.calls.argsFor(0)[1].data).toEqual({ nodeIds: [ 'node-id' ] });
});
it('should create link element to download file node', () => {
const dummyLinkElement: any = {
download: null,
href: null,
click: () => null,
style: {
display: null
}
};
const node = { entry: { name: 'dummy', isFile: true, id: 'node-id' } };
spyOn(contentService, 'getContentUrl').and.returnValue('somewhere-over-the-rainbow');
spyOn(document, 'createElement').and.returnValue(dummyLinkElement);
spyOn(document.body, 'appendChild').and.stub();
spyOn(document.body, 'removeChild').and.stub();
component.selection = [node];
fixture.detectChanges();
element.triggerEventHandler('click', null);
expect(document.createElement).toHaveBeenCalled();
expect(dummyLinkElement.download).toBe('dummy');
expect(dummyLinkElement.href).toContain('somewhere-over-the-rainbow');
});
});

View File

@@ -0,0 +1,142 @@
/*!
* @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 { Directive, Input, HostListener } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AlfrescoApiService, DownloadService } from '@alfresco/adf-core';
import { DownloadZipDialogComponent } from '../dialogs/download-zip/download-zip.dialog';
import { ContentApi, NodeEntry, VersionEntry } from '@alfresco/js-api';
/**
* Directive selectors without adf- prefix will be deprecated on 3.0.0
*/
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
selector: '[adfNodeDownload]'
})
export class NodeDownloadDirective {
_contentApi: ContentApi;
get contentApi(): ContentApi {
this._contentApi = this._contentApi ?? new ContentApi(this.apiService.getInstance());
return this._contentApi;
}
/** Nodes to download. */
@Input('adfNodeDownload')
nodes: NodeEntry | NodeEntry[];
/** Node's version to download. */
@Input()
version: VersionEntry;
@HostListener('click')
onClick() {
this.downloadNodes(this.nodes);
}
constructor(
private apiService: AlfrescoApiService,
private downloadService: DownloadService,
private dialog: MatDialog) {
}
/**
* Downloads multiple selected nodes.
* Packs result into a .ZIP archive if there is more than one node selected.
*
* @param selection Multiple selected nodes to download
*/
downloadNodes(selection: NodeEntry | Array<NodeEntry>) {
if (!this.isSelectionValid(selection)) {
return;
}
if (selection instanceof Array) {
if (selection.length === 1) {
this.downloadNode(selection[0]);
} else {
this.downloadZip(selection);
}
} else {
this.downloadNode(selection);
}
}
/**
* Downloads a single node.
* Packs result into a .ZIP archive is the node is a Folder.
*
* @param node Node to download
*/
downloadNode(node: NodeEntry) {
if (node && node.entry) {
const entry = node.entry;
if (entry.isFile) {
this.downloadFile(node);
}
if (entry.isFolder) {
this.downloadZip([node]);
}
// Check if there's nodeId for Shared Files
if (!entry.isFile && !entry.isFolder && (entry as any).nodeId) {
this.downloadFile(node);
}
}
}
private isSelectionValid(selection: NodeEntry | Array<NodeEntry>) {
return selection || (selection instanceof Array && selection.length > 0);
}
private downloadFile(node: NodeEntry) {
if (node && node.entry) {
// nodeId for Shared node
const id = (node.entry as any).nodeId || node.entry.id;
let url;
let fileName;
if (this.version) {
url = this.contentApi.getVersionContentUrl(id, this.version.entry.id, true);
fileName = this.version.entry.name;
} else {
url = this.contentApi.getContentUrl(id, true);
fileName = node.entry.name;
}
this.downloadService.downloadUrl(url, fileName);
}
}
private downloadZip(selection: Array<NodeEntry>) {
if (selection && selection.length > 0) {
// nodeId for Shared node
const nodeIds = selection.map((node: any) => (node.entry.nodeId || node.entry.id));
this.dialog.open(DownloadZipDialogComponent, {
width: '600px',
disableClose: true,
data: {
nodeIds
}
});
}
}
}

View File

@@ -19,7 +19,8 @@
import { Directive, ElementRef, Renderer2, HostListener, Input, AfterViewInit } from '@angular/core';
import { Node } from '@alfresco/js-api';
import { AllowableOperationsEnum, ContentService } from '@alfresco/adf-core';
import { ContentService } from '../common/services/content.service';
import { AllowableOperationsEnum } from '../common/models/allowable-operations.enum';
import { ContentNodeDialogService } from '../content-node-selector/content-node-dialog.service';
@Directive({

View File

@@ -25,3 +25,4 @@ export * from './library-membership.directive';
export * from './node-delete.directive';
export * from './node-favorite.directive';
export * from './node-restore.directive';
export * from './node-download.directive';