mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-06-02 17:34:51 +00:00
use ADF printing feature (#630)
This commit is contained in:
parent
e3043e8187
commit
1dcd06d311
18
package-lock.json
generated
18
package-lock.json
generated
@ -5,17 +5,17 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alfresco/adf-content-services": {
|
"@alfresco/adf-content-services": {
|
||||||
"version": "2.6.0-d037a16d3c4215522a5f786e18ea0c8f018ecb25",
|
"version": "2.6.0-8fee6e217aae1f2de5ff4634c5cd1e699336fd20",
|
||||||
"resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.6.0-d037a16d3c4215522a5f786e18ea0c8f018ecb25.tgz",
|
"resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.6.0-8fee6e217aae1f2de5ff4634c5cd1e699336fd20.tgz",
|
||||||
"integrity": "sha512-4f0ANwvwlciNK4MPe2wNQ012/vE9XPa3uA63Cx1VvaIuqJPttJpV/hDSIt/rAA+X//SSqGOjlaqIw2NU4btA9g==",
|
"integrity": "sha512-sbqxrifmNVonQ/dukNDGKC2U8TuMPwW11QC0+uFNqB8JWYE5XE8p3Rdnm5OJD0GzD7bQ5wlC5RT3HKY4rrtMQQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^1.9.0"
|
"tslib": "^1.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@alfresco/adf-core": {
|
"@alfresco/adf-core": {
|
||||||
"version": "2.6.0-d037a16d3c4215522a5f786e18ea0c8f018ecb25",
|
"version": "2.6.0-8fee6e217aae1f2de5ff4634c5cd1e699336fd20",
|
||||||
"resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.6.0-d037a16d3c4215522a5f786e18ea0c8f018ecb25.tgz",
|
"resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.6.0-8fee6e217aae1f2de5ff4634c5cd1e699336fd20.tgz",
|
||||||
"integrity": "sha512-hPQVtmIiQXkwuJQz8HfsnZkG3frC/NU5xUXN6LMXMjJcu3yNDkuNunFaxLU4d2Z5Zb8UDAWUwgfsIeSBpD6aJA==",
|
"integrity": "sha512-cMZk5PSKKZfLDF93IhF6Yd/6bPeoCnre2fwOwOjYwWQBd38aO8jy9lv7szrbxWY4zliYAuNwiXSyy8CNFHQeLw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^1.9.0"
|
"tslib": "^1.9.0"
|
||||||
}
|
}
|
||||||
@ -2856,9 +2856,9 @@
|
|||||||
"integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo="
|
"integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo="
|
||||||
},
|
},
|
||||||
"alfresco-js-api": {
|
"alfresco-js-api": {
|
||||||
"version": "2.6.0-c87428564306f710159976b0d740a07a94326cf1",
|
"version": "2.6.0-48ee903f46585b1f0967311bde867dbe8ea9374d",
|
||||||
"resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.6.0-c87428564306f710159976b0d740a07a94326cf1.tgz",
|
"resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.6.0-48ee903f46585b1f0967311bde867dbe8ea9374d.tgz",
|
||||||
"integrity": "sha512-OPt75wllx+vjI0RgwbVdvUa4gs+UthJUS4iVaS8PhyXhXNxEHMuv2bKGH48cSolQbNH7kaurxqi80yl8b9kw3A==",
|
"integrity": "sha512-v7eahtOkxQD+jywQ1OQsSLdhKbFw9OLqn2ya+gGWbp4k7eAnUPdSmfV2Hahli0nYk0zVI9mhCt4u+Rqv4rXu0Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"event-emitter": "0.3.4",
|
"event-emitter": "0.3.4",
|
||||||
"superagent": "3.8.2"
|
"superagent": "3.8.2"
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alfresco/adf-content-services": "2.6.0-d037a16d3c4215522a5f786e18ea0c8f018ecb25",
|
"@alfresco/adf-content-services": "2.6.0-8fee6e217aae1f2de5ff4634c5cd1e699336fd20",
|
||||||
"@alfresco/adf-core": "2.6.0-d037a16d3c4215522a5f786e18ea0c8f018ecb25",
|
"@alfresco/adf-core": "2.6.0-8fee6e217aae1f2de5ff4634c5cd1e699336fd20",
|
||||||
"@angular/animations": "6.1.7",
|
"@angular/animations": "6.1.7",
|
||||||
"@angular/cdk": "^6.4.7",
|
"@angular/cdk": "^6.4.7",
|
||||||
"@angular/common": "6.1.7",
|
"@angular/common": "6.1.7",
|
||||||
@ -50,7 +50,7 @@
|
|||||||
"@ngrx/store-devtools": "^6.1.0",
|
"@ngrx/store-devtools": "^6.1.0",
|
||||||
"@ngstack/code-editor": "^0.4.3",
|
"@ngstack/code-editor": "^0.4.3",
|
||||||
"@ngx-translate/core": "^10.0.2",
|
"@ngx-translate/core": "^10.0.2",
|
||||||
"alfresco-js-api": "2.6.0-c87428564306f710159976b0d740a07a94326cf1",
|
"alfresco-js-api": "2.6.0-48ee903f46585b1f0967311bde867dbe8ea9374d",
|
||||||
"core-js": "^2.5.7",
|
"core-js": "^2.5.7",
|
||||||
"hammerjs": "2.0.8",
|
"hammerjs": "2.0.8",
|
||||||
"minimatch-browser": "^1.0.0",
|
"minimatch-browser": "^1.0.0",
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
[canNavigateBefore]="previousNodeId"
|
[canNavigateBefore]="previousNodeId"
|
||||||
[canNavigateNext]="nextNodeId"
|
[canNavigateNext]="nextNodeId"
|
||||||
[overlayMode]="true"
|
[overlayMode]="true"
|
||||||
(print)="printFile()"
|
|
||||||
(showViewerChange)="onVisibilityChanged($event)"
|
(showViewerChange)="onVisibilityChanged($event)"
|
||||||
(navigateBefore)="onNavigateBefore()"
|
(navigateBefore)="onNavigateBefore()"
|
||||||
(navigateNext)="onNavigateNext()">
|
(navigateNext)="onNavigateNext()">
|
||||||
|
@ -41,7 +41,6 @@ import { ContentApiService } from '../../services/content-api.service';
|
|||||||
import { AppExtensionService } from '../../extensions/extension.service';
|
import { AppExtensionService } from '../../extensions/extension.service';
|
||||||
import { ContentManagementService } from '../../services/content-management.service';
|
import { ContentManagementService } from '../../services/content-management.service';
|
||||||
import { ContentActionRef, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
import { ContentActionRef, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
||||||
import { ViewUtilService } from './view-util.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-preview',
|
selector: 'app-preview',
|
||||||
@ -74,7 +73,6 @@ export class PreviewComponent extends PageComponent implements OnInit {
|
|||||||
private preferences: UserPreferencesService,
|
private preferences: UserPreferencesService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private viewUtils: ViewUtilService,
|
|
||||||
store: Store<AppStore>,
|
store: Store<AppStore>,
|
||||||
extensions: AppExtensionService,
|
extensions: AppExtensionService,
|
||||||
content: ContentManagementService
|
content: ContentManagementService
|
||||||
@ -378,10 +376,6 @@ export class PreviewComponent extends PageComponent implements OnInit {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
printFile() {
|
|
||||||
this.viewUtils.printFileGeneric(this.nodeId, this.node.content.mimeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getNavigationCommands(url: string): any[] {
|
private getNavigationCommands(url: string): any[] {
|
||||||
const urlTree: UrlTree = this.router.parseUrl(url);
|
const urlTree: UrlTree = this.router.parseUrl(url);
|
||||||
const urlSegmentGroup: UrlSegmentGroup =
|
const urlSegmentGroup: UrlSegmentGroup =
|
||||||
|
@ -32,7 +32,6 @@ import { CoreExtensionsModule } from '../../extensions/core.extensions.module';
|
|||||||
import { DirectivesModule } from '../../directives/directives.module';
|
import { DirectivesModule } from '../../directives/directives.module';
|
||||||
import { AppInfoDrawerModule } from '../info-drawer/info.drawer.module';
|
import { AppInfoDrawerModule } from '../info-drawer/info.drawer.module';
|
||||||
import { PreviewComponent } from './preview.component';
|
import { PreviewComponent } from './preview.component';
|
||||||
import { ViewUtilService } from './view-util.service';
|
|
||||||
import { PreviewExtensionComponent } from './preview-extension.component';
|
import { PreviewExtensionComponent } from './preview-extension.component';
|
||||||
import { AppToolbarModule } from '../toolbar/toolbar.module';
|
import { AppToolbarModule } from '../toolbar/toolbar.module';
|
||||||
|
|
||||||
@ -55,7 +54,6 @@ const routes: Routes = [
|
|||||||
AppToolbarModule
|
AppToolbarModule
|
||||||
],
|
],
|
||||||
declarations: [PreviewComponent, PreviewExtensionComponent],
|
declarations: [PreviewComponent, PreviewExtensionComponent],
|
||||||
providers: [ViewUtilService],
|
|
||||||
exports: [PreviewComponent]
|
exports: [PreviewComponent]
|
||||||
})
|
})
|
||||||
export class PreviewModule {}
|
export class PreviewModule {}
|
||||||
|
@ -1,228 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
|
|
||||||
import { RenditionEntry } from 'alfresco-js-api';
|
|
||||||
import { ContentApiService } from './../../services/content-api.service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ViewUtilService {
|
|
||||||
static TARGET = '_new';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public static ContentGroup = {
|
|
||||||
IMAGE: 'image',
|
|
||||||
MEDIA: 'media',
|
|
||||||
PDF: 'pdf',
|
|
||||||
TEXT: 'text'
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Based on ViewerComponent Implementation, this value is used to determine how many times we try
|
|
||||||
* to get the rendition of a file for preview, or printing.
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
maxRetries = 5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mime-type grouping based on the ViewerComponent.
|
|
||||||
*/
|
|
||||||
private mimeTypes = {
|
|
||||||
text: [
|
|
||||||
'text/plain',
|
|
||||||
'text/csv',
|
|
||||||
'text/xml',
|
|
||||||
'text/html',
|
|
||||||
'application/x-javascript'
|
|
||||||
],
|
|
||||||
pdf: ['application/pdf'],
|
|
||||||
image: [
|
|
||||||
'image/png',
|
|
||||||
'image/jpeg',
|
|
||||||
'image/gif',
|
|
||||||
'image/bmp',
|
|
||||||
'image/svg+xml'
|
|
||||||
],
|
|
||||||
media: [
|
|
||||||
'video/mp4',
|
|
||||||
'video/webm',
|
|
||||||
'video/ogg',
|
|
||||||
'audio/mpeg',
|
|
||||||
'audio/ogg',
|
|
||||||
'audio/wav'
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private apiService: AlfrescoApiService,
|
|
||||||
private contentApi: ContentApiService,
|
|
||||||
private logService: LogService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method takes a url to trigger the print dialog against, and the type of artifact that it
|
|
||||||
* is.
|
|
||||||
* This URL should be one that can be rendered in the browser, for example PDF, Image, or Text
|
|
||||||
* @param {string} url
|
|
||||||
* @param {string} type
|
|
||||||
*/
|
|
||||||
public printFile(url: string, type: string) {
|
|
||||||
const pwa = window.open(url, ViewUtilService.TARGET);
|
|
||||||
// Because of the way chrome focus and close image window vs. pdf preview window
|
|
||||||
if (type === ViewUtilService.ContentGroup.IMAGE) {
|
|
||||||
pwa.onfocus = () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
pwa.close();
|
|
||||||
}, 500);
|
|
||||||
};
|
|
||||||
pwa.onload = () => {
|
|
||||||
pwa.print();
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
pwa.onload = () => {
|
|
||||||
pwa.print();
|
|
||||||
pwa.onfocus = () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
pwa.close();
|
|
||||||
}, 10);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch the File Print dialog from anywhere other than the preview service, which resolves the
|
|
||||||
* rendition of the object that can be printed from a web browser.
|
|
||||||
* These are: images, PDF files, or PDF rendition of files.
|
|
||||||
* We also force PDF rendition for TEXT type objects, otherwise the default URL is to download.
|
|
||||||
* TODO there are different TEXT type objects, (HTML, plaintext, xml, etc. we should determine how these are handled)
|
|
||||||
* @param {string} objectId
|
|
||||||
* @param {string} objectType
|
|
||||||
*/
|
|
||||||
public printFileGeneric(objectId: string, mimeType: string) {
|
|
||||||
const nodeId = objectId;
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public getRenditionUrl(
|
|
||||||
nodeId: string,
|
|
||||||
type: string,
|
|
||||||
renditionExists: boolean
|
|
||||||
): string {
|
|
||||||
return renditionExists && type !== ViewUtilService.ContentGroup.IMAGE
|
|
||||||
? this.apiService.contentApi.getRenditionUrl(
|
|
||||||
nodeId,
|
|
||||||
ViewUtilService.ContentGroup.PDF
|
|
||||||
)
|
|
||||||
: this.contentApi.getContentUrl(nodeId, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From ViewerComponent
|
|
||||||
* @param {string} nodeId
|
|
||||||
* @param {string} renditionId
|
|
||||||
* @param {number} retries
|
|
||||||
* @returns {Promise<AlfrescoApi.RenditionEntry>}
|
|
||||||
*/
|
|
||||||
private async waitRendition(
|
|
||||||
nodeId: string,
|
|
||||||
renditionId: string,
|
|
||||||
retries: number
|
|
||||||
): Promise<RenditionEntry> {
|
|
||||||
const rendition = await this.apiService.renditionsApi.getRendition(
|
|
||||||
nodeId,
|
|
||||||
renditionId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.maxRetries < retries) {
|
|
||||||
const status = rendition.entry.status.toString();
|
|
||||||
|
|
||||||
if (status === 'CREATED') {
|
|
||||||
return rendition;
|
|
||||||
} else {
|
|
||||||
retries += 1;
|
|
||||||
await this.wait(1000);
|
|
||||||
return await this.waitRendition(nodeId, renditionId, retries);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From ViewerComponent
|
|
||||||
* @param {string} mimeType
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
getViewerTypeByMimeType(mimeType: string) {
|
|
||||||
if (mimeType) {
|
|
||||||
mimeType = mimeType.toLowerCase();
|
|
||||||
|
|
||||||
const editorTypes = Object.keys(this.mimeTypes);
|
|
||||||
for (const type of editorTypes) {
|
|
||||||
if (this.mimeTypes[type].indexOf(mimeType) >= 0) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 'unknown';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From ViewerComponent
|
|
||||||
* @param {number} ms
|
|
||||||
* @returns {Promise<any>}
|
|
||||||
*/
|
|
||||||
public wait(ms: number): Promise<any> {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From ViewerComponent
|
|
||||||
* @param {string} nodeId
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
public 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
|
|
||||||
);
|
|
||||||
|
|
||||||
if (rendition) {
|
|
||||||
const status = rendition.entry.status.toString();
|
|
||||||
|
|
||||||
if (status === 'NOT_CREATED') {
|
|
||||||
try {
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
@ -60,7 +60,6 @@ import { NodeActionsService } from '../services/node-actions.service';
|
|||||||
import { NodePermissionService } from '../services/node-permission.service';
|
import { NodePermissionService } from '../services/node-permission.service';
|
||||||
import { ContentApiService } from '../services/content-api.service';
|
import { ContentApiService } from '../services/content-api.service';
|
||||||
import { AppExtensionService } from '../extensions/extension.service';
|
import { AppExtensionService } from '../extensions/extension.service';
|
||||||
import { ViewUtilService } from '../components/preview/view-util.service';
|
|
||||||
import {
|
import {
|
||||||
ExtensionLoaderService,
|
ExtensionLoaderService,
|
||||||
ExtensionService
|
ExtensionService
|
||||||
@ -112,8 +111,7 @@ import {
|
|||||||
ContentApiService,
|
ContentApiService,
|
||||||
AppExtensionService,
|
AppExtensionService,
|
||||||
ExtensionService,
|
ExtensionService,
|
||||||
ExtensionLoaderService,
|
ExtensionLoaderService
|
||||||
ViewUtilService
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppTestingModule {}
|
export class AppTestingModule {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user