[ADF-] update library to use new js-api 3.0.0 (#4097)

This commit is contained in:
Eugenio Romano
2019-01-06 23:57:01 +01:00
committed by Eugenio Romano
parent 2acd1b4e26
commit 3ef7d3b7ea
430 changed files with 1966 additions and 2149 deletions

View File

@@ -20,12 +20,12 @@
</ng-container>
<div class="adf-pdf-viewer__content">
<div id="viewer-pdf-viewer" class="adf-viewer-pdf-viewer" (window:resize)="onResize()">
<div id="viewer-viewerPdf" class="adf-pdfViewer">
<div [id]="randomPdfId+'-viewer-pdf-viewer'" class="adf-viewer-pdf-viewer" (window:resize)="onResize()">
<div [id]="randomPdfId+'-viewer-viewerPdf'" class="adf-pdfViewer">
<div id="loader-container" class="adf-loader-container">
<div class="adf-loader-item">
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div >
</div>
</div>
</div>
</div>

View File

@@ -90,6 +90,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
isPanelDisabled = true;
showThumbnails: boolean = false;
pdfThumbnailsContext: { viewer: any } = { viewer: null };
randomPdfId: string;
get currentScaleText(): string {
return Math.round(this.currentScale * 100) + '%';
@@ -103,6 +104,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
this.onPageChange = this.onPageChange.bind(this);
this.onPagesLoaded = this.onPagesLoaded.bind(this);
this.onPageRendered = this.onPageRendered.bind(this);
this.randomPdfId = this.generateUuid();
}
ngOnChanges(changes) {
@@ -159,8 +161,8 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
}
initPDFViewer(pdfDocument: any) {
const viewer: any = document.getElementById('viewer-viewerPdf');
const container = document.getElementById('viewer-pdf-viewer');
const viewer: any = document.getElementById(`${this.randomPdfId}-viewer-viewerPdf`);
const container = document.getElementById(`${this.randomPdfId}-viewer-pdf-viewer`);
if (viewer && container) {
this.documentContainer = container;
@@ -197,7 +199,8 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
if (this.loadingTask) {
try {
this.loadingTask.destroy();
} catch {}
} catch {
}
this.loadingTask = null;
}
@@ -217,8 +220,8 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
if (this.pdfViewer) {
let viewerContainer = document.getElementById('viewer-main-container');
let documentContainer = document.getElementById('viewer-pdf-viewer');
let viewerContainer = document.getElementById(`${this.randomPdfId}-viewer-main-container`);
let documentContainer = document.getElementById(`${this.randomPdfId}-viewer-pdf-viewer`);
let widthContainer;
let heightContainer;
@@ -453,4 +456,11 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
this.previousPage();
}
}
private generateUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
}

View File

@@ -90,16 +90,6 @@
<mat-icon>print</mat-icon>
</button>
<button
id="adf-viewer-share"
*ngIf="allowShare"
mat-icon-button
title="{{ 'ADF_VIEWER.ACTIONS.SHARE' | translate }}"
data-automation-id="adf-toolbar-share"
(click)="shareContent()">
<mat-icon>share</mat-icon>
</button>
<button
id="adf-viewer-fullscreen"
*ngIf="viewerType !== 'media' && allowFullScreen"

View File

@@ -29,6 +29,7 @@ import { RenderingQueueServices } from '../services/rendering-queue.services';
import { ViewerComponent } from './viewer.component';
import { setupTestBed } from '../../testing/setupTestBed';
import { AlfrescoApiServiceMock } from '../../mock/alfresco-api.service.mock';
import { NodeEntry } from '@alfresco/js-api';
@Component({
selector: 'adf-viewer-container-toolbar',
@@ -352,7 +353,7 @@ describe('ViewerComponent', () => {
content: { getContentUrl: () => contentUrl }
};
component.fileNodeId = '12';
component.nodeId = '12';
component.urlFile = null;
component.displayName = null;
spyOn(alfrescoApiService, 'getInstance').and.returnValue(alfrescoApiInstanceMock);
@@ -368,30 +369,26 @@ describe('ViewerComponent', () => {
});
it('should change display name every time node changes', fakeAsync(() => {
spyOn(alfrescoApiService.nodesApi, 'getNodeInfo').and.returnValues(
Promise.resolve({ name: 'file1', content: {} }),
Promise.resolve({ name: 'file2', content: {} })
spyOn(alfrescoApiService.nodesApi, 'getNode').and.returnValues(
Promise.resolve(new NodeEntry({ entry: { name: 'file1', content: {} } })),
Promise.resolve(new NodeEntry({ entry: { name: 'file2', content: {} } }))
);
spyOn(alfrescoApiService.nodesApi, 'getNode').and.returnValue(Promise.resolve({ id: 'fake-node' }));
component.urlFile = null;
component.displayName = null;
component.blobFile = null;
component.showViewer = true;
component.fileNodeId = 'id1';
component.nodeId = 'id1';
component.ngOnChanges({});
tick();
expect(alfrescoApiService.nodesApi.getNodeInfo).toHaveBeenCalledWith('id1', { include: ['allowableOperations'] });
expect(component.fileTitle).toBe('file1');
component.fileNodeId = 'id2';
component.nodeId = 'id2';
component.ngOnChanges({});
tick();
expect(alfrescoApiService.nodesApi.getNodeInfo).toHaveBeenCalledWith('id2', { include: ['allowableOperations'] });
expect(component.fileTitle).toBe('file2');
}));
@@ -602,57 +599,9 @@ describe('ViewerComponent', () => {
button.click();
});
it('should render default share button', (done) => {
component.allowShare = true;
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(element.querySelector('[data-automation-id="adf-toolbar-share"]')).toBeDefined();
done();
});
});
it('should not render default share button', (done) => {
component.allowShare = false;
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(element.querySelector('[data-automation-id="adf-toolbar-share"]')).toBeNull();
done();
});
});
it('should invoke share action with the toolbar button', (done) => {
component.allowShare = true;
fixture.detectChanges();
spyOn(component, 'shareContent').and.stub();
const button: HTMLButtonElement = element.querySelector('[data-automation-id="adf-toolbar-share"]') as HTMLButtonElement;
button.click();
fixture.whenStable().then(() => {
expect(component.shareContent).toHaveBeenCalled();
done();
});
});
it('should raise share event with the toolbar button', (done) => {
component.allowShare = true;
fixture.detectChanges();
component.share.subscribe((e) => {
expect(e).not.toBeNull();
done();
});
const button: HTMLButtonElement = element.querySelector('[data-automation-id="adf-toolbar-share"]') as HTMLButtonElement;
button.click();
});
it('should get and assign node for download', (done) => {
const node = { id: 'fake-node' };
component.fileNodeId = '12';
component.nodeId = '12';
component.urlFile = '';
const displayName = 'the-name';
const nodeDetails = { name: displayName, id: '12', content: { mimeType: 'txt' } };
@@ -751,9 +700,9 @@ describe('ViewerComponent', () => {
describe('Attribute', () => {
it('should Url or fileNodeId be mandatory', () => {
it('should Url or nodeId be mandatory', () => {
component.showViewer = true;
component.fileNodeId = undefined;
component.nodeId = undefined;
component.urlFile = undefined;
expect(() => {
@@ -763,7 +712,7 @@ describe('ViewerComponent', () => {
it('should FileNodeId present not thrown any error ', () => {
component.showViewer = true;
component.fileNodeId = 'file-node-id';
component.nodeId = 'file-node-id';
component.urlFile = undefined;
expect(() => {
@@ -773,7 +722,7 @@ describe('ViewerComponent', () => {
it('should urlFile present not thrown any error ', () => {
component.showViewer = true;
component.fileNodeId = undefined;
component.nodeId = undefined;
expect(() => {
component.ngOnChanges(null);
@@ -795,7 +744,7 @@ describe('ViewerComponent', () => {
describe('error handling', () => {
it('should show unknown view when node file not found', (done) => {
spyOn(alfrescoApiService.getInstance().nodes, 'getNodeInfo')
spyOn(alfrescoApiService.getInstance().nodes, 'getNode')
.and.returnValue(Promise.reject({}));
component.nodeId = 'the-node-id-of-the-file-to-preview';
@@ -920,18 +869,17 @@ describe('ViewerComponent', () => {
describe('display name property override by nodeId', () => {
const displayName = 'the-name';
const nodeDetails = { name: displayName, id: '12', content: { mimeType: 'txt' } };
const nodeDetails = new NodeEntry({ entry: { name: displayName, id: '12', content: { mimeType: 'txt' } } });
const contentUrl = '/content/url/path';
const alfrescoApiInstanceMock = {
nodes: {
getNodeInfo: () => Promise.resolve(nodeDetails),
getNode: () => Promise.resolve({ id: 'fake-node' })
getNode: () => Promise.resolve(nodeDetails)
},
content: { getContentUrl: () => contentUrl }
};
it('should use the node name if displayName is NOT set and fileNodeId is set', (done) => {
component.fileNodeId = '12';
it('should use the node name if displayName is NOT set and nodeId is set', (done) => {
component.nodeId = '12';
component.urlFile = null;
component.displayName = null;
spyOn(alfrescoApiService, 'getInstance').and.returnValue(alfrescoApiInstanceMock);

View File

@@ -21,7 +21,7 @@ import {
Input, OnChanges, Output, SimpleChanges, TemplateRef,
ViewEncapsulation, OnInit, OnDestroy
} from '@angular/core';
import { MinimalNodeEntryEntity, RenditionEntry, MinimalNodeEntity } from 'alfresco-js-api';
import { RenditionPaging, SharedLinkEntry, Node, RenditionEntry, NodeEntry } from '@alfresco/js-api';
import { BaseEvent } from '../../events';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { LogService } from '../../services/log.service';
@@ -69,15 +69,6 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
@Input()
blobFile: Blob;
/**
* Node Id of the file to load.
* @deprecated 2.4.0 use nodeId
*/
@Input()
set fileNodeId(nodeId: string) {
this.nodeId = nodeId;
}
/** Node Id of the file to load. */
@Input()
nodeId: string = null;
@@ -116,13 +107,6 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
@Input()
allowPrint = false;
/**
* Toggles sharing.
* @deprecated 2.5.0 - inject the share button directive as custom button
*/
@Input()
allowShare = false;
/** Toggles the 'Full Screen' feature. */
@Input()
allowFullScreen = true;
@@ -210,10 +194,6 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
@Output()
print = new EventEmitter<BaseEvent<any>>();
/** Emitted when user clicks the 'Share' button. */
@Output()
share = new EventEmitter<BaseEvent<any>>();
/** Emitted when the viewer is shown or hidden. */
@Output()
showViewerChange = new EventEmitter<boolean>();
@@ -236,15 +216,15 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
viewerType = 'unknown';
isLoading = false;
node: MinimalNodeEntity;
node: NodeEntry;
extensionTemplates: { template: TemplateRef<any>, isVisible: boolean }[] = [];
externalExtensions: string[] = [];
urlFileContent: string;
otherMenu: any;
extension: string;
sidebarTemplateContext: { node: MinimalNodeEntryEntity } = { node: null };
sidebarLeftTemplateContext: { node: MinimalNodeEntryEntity } = { node: null };
sidebarTemplateContext: { node: Node } = { node: null };
sidebarLeftTemplateContext: { node: Node } = { node: null };
fileTitle: string;
private cacheBusterNumber;
@@ -289,7 +269,7 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
this.subscriptions = [];
}
private onNodeUpdated(node: MinimalNodeEntryEntity) {
private onNodeUpdated(node: Node) {
if (node && node.id === this.nodeId) {
this.generateCacheBusterNumber();
this.isLoading = true;
@@ -313,9 +293,10 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
this.setUpUrlFile();
this.isLoading = false;
} else if (this.nodeId) {
this.apiService.nodesApi.getNodeInfo(this.nodeId, { include: ['allowableOperations'] }).then(
(data: MinimalNodeEntryEntity) => {
this.setUpNodeFile(data).then(() => {
this.apiService.nodesApi.getNode(this.nodeId, { include: ['allowableOperations'] }).then(
(node: NodeEntry) => {
this.node = node;
this.setUpNodeFile(node.entry).then(() => {
this.isLoading = false;
});
},
@@ -324,17 +305,11 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
this.logService.error('This node does not exist');
}
);
this.apiService.nodesApi.getNode(this.nodeId).then(
(node) => {
this.node = node;
}
);
} else if (this.sharedLinkId) {
this.apiService.sharedLinksApi.getSharedLink(this.sharedLinkId).then(
(details) => {
this.setUpSharedLinkFile(details);
(sharedLinkEntry: SharedLinkEntry) => {
this.setUpSharedLinkFile(sharedLinkEntry);
this.isLoading = false;
},
() => {
@@ -375,7 +350,7 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
this.scrollTop();
}
private async setUpNodeFile(data: MinimalNodeEntryEntity) {
private async setUpNodeFile(data: Node) {
let setupNode;
if (data.content) {
@@ -431,9 +406,9 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
toggleSidebar() {
this.showSidebar = !this.showSidebar;
if (this.showSidebar && this.nodeId) {
this.apiService.getInstance().nodes.getNodeInfo(this.nodeId, { include: ['allowableOperations'] })
.then((data: MinimalNodeEntryEntity) => {
this.sidebarTemplateContext.node = data;
this.apiService.getInstance().nodes.getNode(this.nodeId, { include: ['allowableOperations'] })
.then((nodeEntry: NodeEntry) => {
this.sidebarTemplateContext.node = nodeEntry.entry;
});
}
}
@@ -441,15 +416,15 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
toggleLeftSidebar() {
this.showLeftSidebar = !this.showLeftSidebar;
if (this.showSidebar && this.nodeId) {
this.apiService.getInstance().nodes.getNodeInfo(this.nodeId, { include: ['allowableOperations'] })
.then((data: MinimalNodeEntryEntity) => {
this.sidebarLeftTemplateContext.node = data;
this.apiService.getInstance().nodes.getNode(this.nodeId, { include: ['allowableOperations'] })
.then((nodeEntry: NodeEntry) => {
this.sidebarLeftTemplateContext.node = nodeEntry.entry;
});
}
}
private getDisplayName(name) {
return this.displayName || name ;
return this.displayName || name;
}
scrollTop() {
@@ -614,13 +589,6 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
}
}
shareContent() {
if (this.allowShare) {
const args = new BaseEvent();
this.share.next(args);
}
}
/**
* Triggers full screen mode with a main content area displayed.
*/
@@ -662,7 +630,7 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
private async displaySharedLinkRendition(sharedId: string) {
try {
const rendition = await this.apiService.renditionsApi.getSharedLinkRendition(sharedId, 'pdf');
const rendition: RenditionEntry = await this.apiService.renditionsApi.getSharedLinkRendition(sharedId, 'pdf');
if (rendition.entry.status.toString() === 'CREATED') {
this.viewerType = 'pdf';
this.urlFileContent = this.apiService.contentApi.getSharedLinkRenditionUrl(sharedId, 'pdf');
@@ -670,7 +638,7 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
} catch (error) {
this.logService.error(error);
try {
const rendition = await this.apiService.renditionsApi.getSharedLinkRendition(sharedId, 'imgpreview');
const rendition: RenditionEntry = await this.apiService.renditionsApi.getSharedLinkRendition(sharedId, 'imgpreview');
if (rendition.entry.status.toString() === 'CREATED') {
this.viewerType = 'image';
this.urlFileContent = this.apiService.contentApi.getSharedLinkRenditionUrl(sharedId, 'imgpreview');
@@ -681,26 +649,26 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
}
}
private async resolveRendition(nodeId: string, renditionId: string) {
private async resolveRendition(nodeId: string, renditionId: string): Promise<RenditionEntry> {
renditionId = renditionId.toLowerCase();
const supported = await this.apiService.renditionsApi.getRenditions(nodeId);
const supportedRendition: RenditionPaging = await this.apiService.renditionsApi.getRenditions(nodeId);
let rendition = supported.list.entries.find((obj) => obj.entry.id.toLowerCase() === renditionId);
let rendition: RenditionEntry = supportedRendition.list.entries.find((renditionEntry: RenditionEntry) => renditionEntry.entry.id.toLowerCase() === renditionId);
if (!rendition) {
renditionId = 'imgpreview';
rendition = supported.list.entries.find((obj) => obj.entry.id.toLowerCase() === renditionId);
rendition = supportedRendition.list.entries.find((renditionEntry: RenditionEntry) => renditionEntry.entry.id.toLowerCase() === renditionId);
}
if (rendition) {
const status = rendition.entry.status.toString();
const status: string = rendition.entry.status.toString();
if (status === 'NOT_CREATED') {
try {
await this.apiService.renditionsApi.createRendition(nodeId, { id: renditionId }).then(() => {
this.viewerType = 'in_creation';
});
rendition = await this.waitRendition(nodeId, renditionId, 0);
rendition = await this.waitRendition(nodeId, renditionId);
} catch (err) {
this.logService.error(err);
}
@@ -710,14 +678,14 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
return rendition;
}
private async waitRendition(nodeId: string, renditionId: string, retries: number): Promise<RenditionEntry> {
let currentRetry = 0;
return new Promise((resolve, reject) => {
private async waitRendition(nodeId: string, renditionId: string): Promise<RenditionEntry> {
let currentRetry: number = 0;
return new Promise<RenditionEntry>((resolve, reject) => {
let intervalId = setInterval(() => {
currentRetry++;
if (this.maxRetries >= currentRetry) {
this.apiService.renditionsApi.getRendition(nodeId, renditionId).then((rendition) => {
const status = rendition.entry.status.toString();
this.apiService.renditionsApi.getRendition(nodeId, renditionId).then((rendition: RenditionEntry) => {
const status: string = rendition.entry.status.toString();
if (status === 'CREATED') {
if (renditionId === 'pdf') {

View File

@@ -16,7 +16,7 @@
*/
import { Injectable } from '@angular/core';
import { RenditionEntry } from 'alfresco-js-api';
import { RenditionEntry, RenditionPaging } from '@alfresco/js-api';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { LogService } from '../../services/log.service';
@@ -30,7 +30,7 @@ export class ViewUtilService {
* Content groups based on categorization of files that can be viewed in the web browser. This
* implementation or grouping is tied to the definition the ng component: ViewerComponent
*/
// tslint:disable-next-line:variable-name
// tslint:disable-next-line:variable-name
static ContentGroup = {
IMAGE: 'image',
MEDIA: 'media',
@@ -69,7 +69,7 @@ export class ViewUtilService {
// Because of the way chrome focus and close image window vs. pdf preview window
if (type === ViewUtilService.ContentGroup.IMAGE) {
pwa.onfocus = () => {
setTimeout( () => {
setTimeout(() => {
pwa.close();
}, 500);
};
@@ -93,17 +93,17 @@ export class ViewUtilService {
const type: string = this.getViewerTypeByMimeType(mimeType);
this.getRendition(nodeId, ViewUtilService.ContentGroup.PDF)
.then((value) => {
const url: string = this.getRenditionUrl(nodeId, type, (value ? true : false));
const printType = (type === ViewUtilService.ContentGroup.PDF
|| type === ViewUtilService.ContentGroup.TEXT)
? ViewUtilService.ContentGroup.PDF : type;
this.printFile(url, printType);
})
.catch((err) => {
this.logService.error('Error with Printing');
this.logService.error(err);
});
.then((value) => {
const url: string = this.getRenditionUrl(nodeId, type, (value ? true : false));
const printType = (type === ViewUtilService.ContentGroup.PDF
|| type === ViewUtilService.ContentGroup.TEXT)
? ViewUtilService.ContentGroup.PDF : type;
this.printFile(url, printType);
})
.catch((err) => {
this.logService.error('Error with Printing');
this.logService.error(err);
});
}
getRenditionUrl(nodeId: string, type: string, renditionExists: boolean): string {
@@ -147,22 +147,22 @@ export class ViewUtilService {
}
async getRendition(nodeId: string, renditionId: string): Promise<RenditionEntry> {
const supported = await this.apiService.renditionsApi.getRenditions(nodeId);
let rendition = supported.list.entries.find((obj) => obj.entry.id.toLowerCase() === renditionId);
const renditionPaging: RenditionPaging = await this.apiService.renditionsApi.getRenditions(nodeId);
let rendition: RenditionEntry = renditionPaging.list.entries.find((renditionEntry: RenditionEntry) => renditionEntry.entry.id.toLowerCase() === renditionId);
if (rendition) {
const status = rendition.entry.status.toString();
if (status === 'NOT_CREATED') {
try {
await this.apiService.renditionsApi.createRendition(nodeId, {id: renditionId});
await this.apiService.renditionsApi.createRendition(nodeId, { id: renditionId });
rendition = await this.waitRendition(nodeId, renditionId, 0);
} catch (err) {
this.logService.error(err);
}
}
}
return new Promise((resolve) => resolve(rendition));
return new Promise<RenditionEntry>((resolve) => resolve(rendition));
}
}