@hmcts/annotation-ui-lib
Version:
PDF Viewer and ability to highlight text with and comment tracking
2,776 lines • 96.2 kB
JavaScript
import { v4 } from 'uuid';
import { isPlatformServer, CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { __awaiter } from 'tslib';
import { WINDOW, NgtUniversalModule } from '@ng-toolkit/universal';
import { Injectable, Inject, PLATFORM_ID, Component, ViewChildren, Input, Output, EventEmitter, ViewChild, ChangeDetectorRef, Renderer2, ComponentFactoryResolver, Injector, ApplicationRef, Directive, ViewContainerRef, NgModule, defineInjectable, inject } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpClientModule } from '@angular/common/http';
import { BehaviorSubject, Subject, of, throwError } from 'rxjs';
import { TransferState, makeStateKey } from '@angular/platform-browser';
import { tap, catchError, map } from 'rxjs/operators';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class Comment {
/**
* @param {?} id
* @param {?} annotationId
* @param {?} createdBy
* @param {?} createdByDetails
* @param {?} createdDate
* @param {?} lastModifiedBy
* @param {?} lastModifiedByDetails
* @param {?} lastModifiedDate
* @param {?} content
*/
constructor(id, annotationId, createdBy, createdByDetails, createdDate, lastModifiedBy, lastModifiedByDetails, lastModifiedDate, content) {
this.id = id;
this.annotationId = annotationId;
this.createdBy = createdBy;
this.createdByDetails = createdByDetails;
this.createdDate = createdDate;
this.lastModifiedBy = lastModifiedBy;
this.lastModifiedByDetails = lastModifiedByDetails;
this.lastModifiedDate = lastModifiedDate;
this.content = content;
}
}
class Annotation {
/**
* @param {?=} id
* @param {?=} annotationSetId
* @param {?=} createdBy
* @param {?=} createdDate
* @param {?=} createdByDetails
* @param {?=} lastModifiedBy
* @param {?=} lastModifiedByDetails
* @param {?=} lastModifiedDate
* @param {?=} documentId
* @param {?=} page
* @param {?=} color
* @param {?=} comments
* @param {?=} rectangles
* @param {?=} type
*/
constructor(id, annotationSetId, createdBy, createdDate, createdByDetails, lastModifiedBy, lastModifiedByDetails, lastModifiedDate, documentId, page, color, comments, rectangles, type) {
this.id = id;
this.annotationSetId = annotationSetId;
this.createdBy = createdBy;
this.createdDate = createdDate;
this.createdByDetails = createdByDetails;
this.lastModifiedBy = lastModifiedBy;
this.lastModifiedByDetails = lastModifiedByDetails;
this.lastModifiedDate = lastModifiedDate;
this.documentId = documentId;
this.page = page;
this.color = color;
this.comments = comments;
this.rectangles = rectangles;
this.type = type;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class PdfAnnotateWrapper {
/**
* @param {?} pageNumber
* @return {?}
*/
createPage(pageNumber) {
return PDFAnnotate.UI.createPage(pageNumber);
}
/**
* @param {?} pageNumber
* @param {?} RENDER_OPTIONS
* @return {?}
*/
renderPage(pageNumber, RENDER_OPTIONS) {
return PDFAnnotate.UI.renderPage(pageNumber, RENDER_OPTIONS);
}
/**
* @param {?} type
* @return {?}
*/
enableRect(type) {
PDFAnnotate.UI.enableRect(type);
}
/**
* @return {?}
*/
disableRect() {
PDFAnnotate.UI.disableRect();
}
/**
* @param {?=} storeAdapter
* @return {?}
*/
setStoreAdapter(storeAdapter) {
if (storeAdapter) {
PDFAnnotate.setStoreAdapter(storeAdapter);
}
else {
PDFAnnotate.setStoreAdapter(new PDFAnnotate.LocalStoreAdapter());
}
}
/**
* @return {?}
*/
getStoreAdapter() {
return PDFAnnotate.getStoreAdapter();
}
/**
* @return {?}
*/
getUi() {
return PDFAnnotate.UI;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class EmLoggerService {
/**
* @param {?} loggingClass
* @return {?}
*/
setClass(loggingClass) {
this.loggingClass = loggingClass;
}
/**
* @param {?} message
* @return {?}
*/
error(message) {
this.buildLog('error-' + JSON.stringify(message));
}
/**
* @param {?} message
* @return {?}
*/
info(message) {
this.buildLog('info-' + JSON.stringify(message));
}
/**
* @param {?} message
* @return {?}
*/
buildLog(message) {
console.log(`${this.loggingClass}-${message}`);
}
}
EmLoggerService.decorators = [
{ type: Injectable }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class PdfService {
/**
* @param {?} log
* @param {?} pdfAnnotateWrapper
*/
constructor(log, pdfAnnotateWrapper) {
this.log = log;
this.pdfAnnotateWrapper = pdfAnnotateWrapper;
log.setClass('PdfService');
}
/**
* @return {?}
*/
preRun() {
this.pageNumber = new BehaviorSubject(1);
}
/**
* @return {?}
*/
getAnnotationWrapper() {
return this.annotationWrapper;
}
/**
* @param {?} annotationWrapper
* @return {?}
*/
setAnnotationWrapper(annotationWrapper) {
this.annotationWrapper = annotationWrapper;
}
/**
* @return {?}
*/
getPageNumber() {
return this.pageNumber;
}
/**
* @param {?} pageNumber
* @return {?}
*/
setPageNumber(pageNumber) {
this.pageNumber.next(pageNumber);
}
/**
* @return {?}
*/
setHighlightTool() {
this.log.info('Highlight cursor is enabled');
this.pdfAnnotateWrapper.enableRect('highlight');
}
/**
* @return {?}
*/
setCursorTool() {
this.pdfAnnotateWrapper.disableRect();
}
}
PdfService.decorators = [
{ type: Injectable }
];
PdfService.ctorParameters = () => [
{ type: EmLoggerService },
{ type: PdfAnnotateWrapper }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class Utils {
/**
* @param {?} rectangles
* @return {?}
*/
buildLineRectangle(rectangles) {
this.sortByY(rectangles);
/** @type {?} */
const lowestY = rectangles[0].y;
/** @type {?} */
const lineHeight = rectangles[0].height;
this.sortByX(rectangles);
/** @type {?} */
const lowestX = rectangles[0].x;
/** @type {?} */
const upperX = rectangles[rectangles.length - 1].x;
/** @type {?} */
const width = rectangles[rectangles.length - 1].width;
/** @type {?} */
const rectangle = {
y: lowestY,
x: lowestX,
width: (upperX - lowestX) + width,
height: lineHeight
};
return rectangle;
}
/**
* @param {?} annotationRectangles
* @param {?} generatedRectangles
* @return {?}
*/
generateRectanglePerLine(annotationRectangles, generatedRectangles) {
this.sortByY(annotationRectangles);
/** @type {?} */
const highestY = annotationRectangles[annotationRectangles.length - 1].y;
/** @type {?} */
const lowestY = annotationRectangles[0].y;
/** @type {?} */
const lineHeight = this.getAnnotationLineHeight(annotationRectangles);
if (this.difference(highestY, lowestY) > lineHeight) {
/** @type {?} */
const currentLineRectangles = annotationRectangles.filter(rectangle => rectangle.y <= (lowestY + lineHeight));
/** @type {?} */
const nextLineRectangles = annotationRectangles.filter(rectangle => rectangle.y > (lowestY + lineHeight));
generatedRectangles.push(this.buildLineRectangle(currentLineRectangles));
this.generateRectanglePerLine(nextLineRectangles, generatedRectangles);
}
else {
generatedRectangles.push(this.buildLineRectangle(annotationRectangles));
}
}
/**
* @param {?} rectangles
* @return {?}
*/
getAnnotationLineHeight(rectangles) {
return rectangles[0].height;
}
/**
* @param {?} rectangles
* @param {?=} lowest
* @return {?}
*/
sortByY(rectangles, lowest = true) {
rectangles.sort(function (a, b) {
/** @type {?} */
const keyA = a.y;
/** @type {?} */
const keyB = b.y;
if (keyA < keyB) {
return lowest ? -1 : 1;
}
if (keyA > keyB) {
return lowest ? 1 : -1;
}
return 0;
});
}
/**
* @param {?} rectangles
* @param {?=} lowest
* @return {?}
*/
sortByX(rectangles, lowest = true) {
rectangles.sort(function (a, b) {
/** @type {?} */
const keyA = a.x;
/** @type {?} */
const keyB = b.x;
if (keyA < keyB) {
return lowest ? -1 : 1;
}
if (keyA > keyB) {
return lowest ? 1 : -1;
}
return 0;
});
}
/**
* @param {?} a
* @param {?} b
* @return {?}
*/
sortByLinePosition(a, b) {
this.sortByX(a);
this.sortByX(b);
return (a[0].x > b[0].x) ? 1 : -1;
}
/**
* @param {?} a
* @param {?} b
* @return {?}
*/
difference(a, b) { return Math.abs(a - b); }
/**
* @param {?} event
* @return {?}
*/
clickIsHighlight(event) {
/** @type {?} */
const target = (/** @type {?} */ (event.target));
/** @type {?} */
const isHighlight = target.firstElementChild;
if (isHighlight == null) {
return false;
}
else if (isHighlight.id.includes('pdf-annotate-screenreader')) {
return true;
}
else {
return false;
}
}
/**
* @param {?} event
* @return {?}
*/
getClickedPage(event) {
/** @type {?} */
let currentParent = event.target;
for (let step = 0; step < 5; step++) {
if (currentParent.parentNode != null) {
/** @type {?} */
const pageNumber = currentParent.parentNode.getAttribute('data-page-number');
if (pageNumber != null) {
return parseInt(pageNumber, null);
}
currentParent = currentParent.parentNode;
}
}
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class PdfAdapter {
/**
* @param {?} log
* @param {?} utils
* @param {?} window
*/
constructor(log, utils, window) {
this.log = log;
this.utils = utils;
this.window = window;
this.annotationChangeSubject = new Subject();
log.setClass('PdfAdapter');
}
/**
* @return {?}
*/
getAnnotationChangeSubject() {
return this.annotationChangeSubject;
}
/**
* @param {?} annotationSet
* @return {?}
*/
setStoreData(annotationSet) {
this.annotationSet = annotationSet;
this.annotations = annotationSet.annotations;
this.commentData = [];
this.annotations.forEach((annotation) => {
annotation.comments.forEach((comment) => {
this.commentData.push(comment);
});
});
this.annotationSetId = annotationSet.id;
}
/**
* @param {?} comment
* @return {?}
*/
editComment(comment) {
this.annotations.forEach((annotation) => {
annotation.comments
.filter(storeComment => storeComment.id === comment.id)
.map(storeComment => {
this.log.info('Editing comment:' + comment.id);
storeComment.content = comment.content;
this.annotationChangeSubject.next({ 'type': 'editComment', 'annotation': annotation });
});
});
}
/**
* @param {?} documentId
* @param {?} comment
* @return {?}
*/
updateComments(documentId, comment) {
this.commentData.push(comment);
}
/**
* @param {?} documentId
* @return {?}
*/
_getAnnotations(documentId) {
return this.annotations || [];
}
/**
* @param {?} documentId
* @return {?}
*/
_getComments(documentId) {
return this.commentData || [];
}
/**
* @return {?}
*/
clearSelection() {
/** @type {?} */
const sel = this.window.getSelection();
if (sel) {
if (sel.removeAllRanges) {
sel.removeAllRanges();
}
else if (sel.empty) {
sel.empty();
}
}
}
/**
* @param {?} comment
* @return {?}
*/
isDraftComment(comment) {
return (comment.content === null || comment.content === '');
}
/**
* @return {?}
*/
getStoreAdapter() {
/** @type {?} */
const getAnnotations = (documentId, pageNumber) => {
return new Promise((resolve, reject) => {
/** @type {?} */
const annotations = this._getAnnotations(documentId).filter(function (i) {
return i.page === pageNumber;
});
resolve({
documentId: documentId,
pageNumber: pageNumber,
annotations: annotations
});
});
};
/** @type {?} */
const getComments = (documentId, annotationId) => {
return new Promise((resolve, reject) => {
resolve(this._getComments(documentId).filter(function (i) {
return i.annotationId === annotationId;
}));
});
};
/** @type {?} */
const getAnnotation = (documentId, annotationId) => {
return new Promise((resolve, reject) => {
/** @type {?} */
const annotation = this._getAnnotations(documentId).find(function (i) {
return i.id === annotationId;
});
resolve(annotation);
});
};
/** @type {?} */
const addAnnotation = (documentId, pageNumber, annotation) => {
return new Promise((resolve, reject) => {
this.clearSelection();
/** @type {?} */
const persistAnnotation = new Annotation();
persistAnnotation.id = v4();
persistAnnotation.page = pageNumber;
persistAnnotation.color = annotation.color;
persistAnnotation.type = annotation.type;
persistAnnotation.comments = [];
persistAnnotation.annotationSetId = this.annotationSetId;
/** @type {?} */
const rectangles = [];
this.log.info('Generating efficient rectangles for new annotation:' + persistAnnotation.id);
this.utils.generateRectanglePerLine(annotation.rectangles, rectangles);
rectangles.forEach((rectangle) => {
rectangle.id = v4();
});
persistAnnotation.rectangles = rectangles;
/** @type {?} */
const annotations = this._getAnnotations(documentId);
annotations.push(persistAnnotation);
this.log.info('Added annotation:' + annotation.id);
this.annotationChangeSubject.next({ 'type': 'addAnnotation', 'annotation': persistAnnotation });
resolve(persistAnnotation);
});
};
/** @type {?} */
const deleteAnnotation = (documentId, annotationId) => {
return new Promise((resolve, reject) => {
/** @type {?} */
const annotation = this.findById(this.annotations, annotationId);
this.remove(this.annotations, annotationId);
this.log.info('Deleted annotation:' + annotationId);
this.annotationChangeSubject.next({ 'type': 'deleteAnnotation', 'annotation': annotation });
resolve(this.annotations);
});
};
/** @type {?} */
const addComment = (documentId, annotationId, content) => {
return new Promise((resolve, reject) => {
/** @type {?} */
const comment = new Comment(v4(), annotationId, null, null, new Date(), null, null, null, content);
this.updateComments(documentId, comment);
/** @type {?} */
const annotation = this.findById(this.annotations, annotationId);
this.log.info('Comment:' + comment.id + ' has been added to annotation:' + annotationId);
annotation.comments.push(comment);
if (this.isDraftComment(comment)) {
this.log.info('Removing comment box because no content exists');
resolve(comment);
}
else {
this.log.info('Add comment:' + comment.id + '-' + 'annotationId:' + annotation.id);
this.annotationChangeSubject.next({ 'type': 'addComment', 'annotation': annotation });
resolve(comment);
}
});
};
/** @type {?} */
const deleteComment = (documentId, commentId) => {
return new Promise((resolve, reject) => {
/** @type {?} */
const comment = this.findById(this.commentData, commentId);
/** @type {?} */
const annotation = this.findById(this.annotations, comment.annotationId);
this.remove(this.commentData, commentId);
this.remove(annotation.comments, commentId);
if (this.isDraftComment(comment)) {
this.log.info('Removing comment box because no content exists');
resolve(comment);
}
else {
this.log.info('Deleted comment:' + commentId + '-' + 'annotationId:' + annotation.id);
this.annotationChangeSubject.next({ 'type': 'deleteComment', 'annotation': annotation });
resolve(this.annotations);
}
});
};
// Unused
/** @type {?} */
const editAnnotation = (documentId, pageNumber, annotation) => {
return new Promise((resolve, reject) => {
this.annotationChangeSubject.next({ 'type': 'editAnnotation', 'annotation': annotation });
resolve(this.commentData);
});
};
return {
getAnnotations,
getComments,
getAnnotation,
addAnnotation,
editAnnotation,
deleteAnnotation,
addComment,
deleteComment
};
}
/**
* @param {?} array
* @param {?} id
* @return {?}
*/
findById(array, id) {
return array.find(e => e.id === id);
}
/**
* @param {?} array
* @param {?} id
* @return {?}
*/
remove(array, id) {
return array.splice(array.findIndex(e => e.id === id), 1);
}
}
PdfAdapter.decorators = [
{ type: Injectable }
];
PdfAdapter.ctorParameters = () => [
{ type: EmLoggerService },
{ type: Utils },
{ type: undefined, decorators: [{ type: Inject, args: [WINDOW,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ApiHttpService {
/**
* @param {?} log
* @param {?} httpClient
* @param {?} platformId
* @param {?} transferState
*/
constructor(log, httpClient, platformId, transferState) {
this.log = log;
this.httpClient = httpClient;
this.platformId = platformId;
this.transferState = transferState;
log.setClass('ApiHttpService');
}
/**
* @param {?} baseUrl
* @return {?}
*/
setBaseUrl(baseUrl) {
this.baseUrl = baseUrl;
}
/**
* @return {?}
*/
getBaseUrl() {
return this.baseUrl;
}
/**
* @param {?} baseUrl
* @param {?} body
* @return {?}
*/
createAnnotationSet(baseUrl, body) {
return this.httpClient.post(`${baseUrl}/em-anno/annotation-sets`, body, { observe: 'response' });
}
/**
* @param {?} baseUrl
* @param {?} dmDocumentId
* @return {?}
*/
fetch(baseUrl, dmDocumentId) {
/** @type {?} */
const STATE_KEY = makeStateKey('annotationSet-' + dmDocumentId);
if (this.transferState.hasKey(STATE_KEY)) {
/** @type {?} */
const annotationSet = this.transferState.get(STATE_KEY, null);
this.transferState.remove(STATE_KEY);
return of(annotationSet);
}
else {
/** @type {?} */
const url = `${baseUrl}/em-anno/annotation-sets/${dmDocumentId}`;
return this.httpClient.get(url, { observe: 'response' })
.pipe(tap(annotationSet => {
if (isPlatformServer(this.platformId)) {
this.transferState.set(STATE_KEY, annotationSet);
}
}));
}
}
/**
* @param {?} dmDocumentId
* @param {?} outputDmDocumentId
* @param {?} baseUrl
* @return {?}
*/
documentTask(dmDocumentId, outputDmDocumentId, baseUrl) {
/** @type {?} */
const url = `${baseUrl}/api/em-npa/document-tasks`;
/** @type {?} */
const documentTasks = {
inputDocumentId: dmDocumentId,
outputDocumentId: outputDmDocumentId
};
this.log.info('Calling NPA service-' + dmDocumentId);
return this.httpClient.post(url, documentTasks, { observe: 'response' });
}
/**
* @param {?} annotation
* @return {?}
*/
deleteAnnotation(annotation) {
/** @type {?} */
const url = `${this.baseUrl}/em-anno/annotations/${annotation.id}`;
return this.httpClient.delete(url, { observe: 'response' });
}
/**
* @param {?} annotation
* @return {?}
*/
saveAnnotation(annotation) {
/** @type {?} */
const url = `${this.baseUrl}/em-anno/annotations`;
return this.httpClient.post(url, annotation, { observe: 'response' });
}
}
ApiHttpService.decorators = [
{ type: Injectable }
];
ApiHttpService.ctorParameters = () => [
{ type: EmLoggerService },
{ type: HttpClient },
{ type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
{ type: TransferState }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class PdfWrapper {
/**
* @param {?} documentId
* @return {?}
*/
getDocument(documentId) {
return PDFJS.getDocument(documentId);
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class RotationModel {
/**
* @param {?} pageNumber
* @param {?} pageDom
*/
constructor(pageNumber, pageDom) {
this.pageNumber = pageNumber;
this.pageDom = pageDom;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class PdfRenderService {
/**
* @param {?} pdfWrapper
* @param {?} log
* @param {?} pdfAnnotateWrapper
*/
constructor(pdfWrapper, log, pdfAnnotateWrapper) {
this.pdfWrapper = pdfWrapper;
this.log = log;
this.pdfAnnotateWrapper = pdfAnnotateWrapper;
this.listPages = [];
this.log.setClass('PdfRenderService');
this.dataLoadedSubject = new BehaviorSubject(false);
this.listPagesSubject = new Subject();
}
/**
* @return {?}
*/
getDataLoadedSub() {
return this.dataLoadedSubject;
}
/**
* @param {?} isLoaded
* @return {?}
*/
dataLoadedUpdate(isLoaded) {
this.dataLoadedSubject.next(isLoaded);
}
/**
* @return {?}
*/
getRenderOptions() {
return Object.assign({}, this.RENDER_OPTIONS);
}
/**
* @param {?} RENDER_OPTIONS
* @return {?}
*/
setRenderOptions(RENDER_OPTIONS) {
this.RENDER_OPTIONS = RENDER_OPTIONS;
}
/**
* @return {?}
*/
getViewerElementRef() {
return this.viewerElementRef;
}
/**
* @return {?}
*/
getPdfPages() {
return this.pdfPages;
}
/**
* @param {?=} viewerElementRef
* @return {?}
*/
render(viewerElementRef) {
if (viewerElementRef != null) {
this.viewerElementRef = viewerElementRef;
}
/** @type {?} */
const renderOptions = this.getRenderOptions();
this.pdfWrapper.getDocument(renderOptions.documentId)
.then(pdf => {
renderOptions.pdfDocument = pdf;
/** @type {?} */
const viewer = this.viewerElementRef.nativeElement;
viewer.innerHTML = '';
this.pdfPages = pdf.pdfInfo.numPages;
this.listPages = [];
for (let i = 1; i < this.pdfPages + 1; i++) {
/** @type {?} */
const pageDom = this.pdfAnnotateWrapper.createPage(i);
// Create a copy of the render options for each page.
/** @type {?} */
const pageOptions = Object.assign({}, renderOptions);
viewer.appendChild(pageDom);
this.addDomPage(pageDom, i);
pdf.getPage(i).then((pdfPage) => {
// Get current page rotation from page rotation objects
pageOptions.rotate = this.addPageRotation(renderOptions, pageOptions, pdfPage);
setTimeout(() => {
this.pdfAnnotateWrapper.renderPage(i, pageOptions).then(() => {
if (i === this.pdfPages) {
this.setRenderOptions(renderOptions);
this.dataLoadedUpdate(true);
this.listPagesSubject.next(this.listPages);
}
});
});
});
}
}).catch((error) => {
/** @type {?} */
const errorMessage = new Error('Unable to render your supplied PDF. ' +
renderOptions.documentId + '. Error is: ' + error);
this.log.error('Encountered error while rendering the PDF:' + errorMessage);
});
}
/**
* @param {?} pageDom
* @param {?} pageNumber
* @return {?}
*/
addDomPage(pageDom, pageNumber) {
/** @type {?} */
const pagedetails = new RotationModel(pageNumber, pageDom);
/** @type {?} */
const index = this.listPages.findIndex(pageElement => pageElement.pageNumber === pageNumber);
if (index > 0) {
this.listPages[index] = pagedetails;
}
else {
this.listPages.push(pagedetails);
}
}
/**
* @param {?} renderOptions
* @param {?} pageOptions
* @param {?} pdfPage
* @return {?}
*/
addPageRotation(renderOptions, pageOptions, pdfPage) {
/** @type {?} */
let rotation = this.getPageRotation(pageOptions, pdfPage);
if (!rotation) {
renderOptions.rotationPages.push({ page: pdfPage.pageNumber, rotate: pdfPage.rotate });
rotation = pdfPage.rotate;
}
return rotation;
}
/**
* @param {?} pageOptions
* @param {?} pdfPage
* @return {?}
*/
getPageRotation(pageOptions, pdfPage) {
return pageOptions.rotationPages
.filter(rotateObj => rotateObj.page === pdfPage.pageNumber)
.map(rotateObj => rotateObj.rotate)[0];
}
}
PdfRenderService.decorators = [
{ type: Injectable }
];
PdfRenderService.ctorParameters = () => [
{ type: PdfWrapper },
{ type: EmLoggerService },
{ type: PdfAnnotateWrapper }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class AnnotationStoreService {
/**
* @param {?} log
* @param {?} pdfAdapter
* @param {?} apiHttpService
* @param {?} pdfService
* @param {?} pdfAnnotateWrapper
* @param {?} pdfRenderService
*/
constructor(log, pdfAdapter, apiHttpService, pdfService, pdfAnnotateWrapper, pdfRenderService) {
this.log = log;
this.pdfAdapter = pdfAdapter;
this.apiHttpService = apiHttpService;
this.pdfService = pdfService;
this.pdfAnnotateWrapper = pdfAnnotateWrapper;
this.pdfRenderService = pdfRenderService;
log.setClass('AnnotationStoreService');
this.commentBtnSubject = new Subject();
this.commentFocusSubject = new BehaviorSubject({ annotation: new Annotation(null, null, null, null, null, null, null, null, null, null, null, null) });
this.contextualToolBarOptions = new Subject();
this.annotationFocusSubject = new Subject();
this.annotationChangeSubscription = this.pdfAdapter.getAnnotationChangeSubject().subscribe((e) => this.handleAnnotationEvent(e));
}
/**
* @return {?}
*/
getAnnotationFocusSubject() {
return this.annotationFocusSubject;
}
/**
* @param {?} annotation
* @return {?}
*/
setAnnotationFocusSubject(annotation) {
this.annotationFocusSubject.next(annotation);
}
/**
* @return {?}
*/
getCommentFocusSubject() {
return this.commentFocusSubject;
}
/**
* @param {?} annotation
* @param {?=} showButton
* @return {?}
*/
setCommentFocusSubject(annotation, showButton) {
this.commentFocusSubject.next({ annotation, showButton });
}
/**
* @return {?}
*/
getCommentBtnSubject() {
return this.commentBtnSubject;
}
/**
* @param {?} commentId
* @return {?}
*/
setCommentBtnSubject(commentId) {
this.commentBtnSubject.next(commentId);
}
/**
* @param {?} annotation
* @param {?=} showDelete
* @return {?}
*/
setToolBarUpdate(annotation, showDelete) {
/** @type {?} */
const contextualOptions = {
annotation,
showDelete
};
this.contextualToolBarOptions.next(contextualOptions);
}
/**
* @return {?}
*/
getToolbarUpdate() {
return this.contextualToolBarOptions;
}
/**
* @param {?} annotationData
* @return {?}
*/
preLoad(annotationData) {
if (annotationData != null) {
this.pdfAdapter.setStoreData(annotationData);
this.pdfAnnotateWrapper.setStoreAdapter(this.pdfAdapter.getStoreAdapter());
this.pdfService.setHighlightTool();
}
else {
this.pdfService.setCursorTool();
this.pdfAnnotateWrapper.setStoreAdapter();
}
}
/**
* @param {?} e
* @return {?}
*/
handleAnnotationEvent(e) {
switch (e.type) {
case 'addAnnotation': {
this.saveAnnotation(e.annotation);
break;
}
case 'addComment': {
this.saveAnnotation(e.annotation, e.type);
break;
}
case 'editComment': {
this.saveAnnotation(e.annotation, e.type);
break;
}
case 'deleteComment': {
this.saveAnnotation(e.annotation);
break;
}
case 'editAnnotation': {
this.saveAnnotation(e.annotation);
break;
}
case 'deleteAnnotation': {
this.deleteAnnotation(e.annotation);
break;
}
}
}
/**
* @param {?} baseUrl
* @param {?} dmDocumentId
* @return {?}
*/
getAnnotationSet(baseUrl, dmDocumentId) {
return this.apiHttpService.fetch(baseUrl, dmDocumentId).pipe(catchError((err) => {
if (err instanceof HttpErrorResponse) {
switch (err.status) {
case 400: {
this.log.error('Bad request: ' + err.error);
return throwError(err.error);
}
case 404: {
/** @type {?} */
const body = {
documentId: dmDocumentId,
id: v4()
};
this.log.info('Creating new annotation set for document id:' + dmDocumentId);
return this.apiHttpService.createAnnotationSet(baseUrl, body);
}
case 500: {
this.log.error('Internal server error: ' + err);
return throwError('Internal server error: ' + err);
}
}
}
}));
}
/**
* @return {?}
*/
saveData() {
/** @type {?} */
let loadedData;
/** @type {?} */
let toKeepAnnotations;
/** @type {?} */
let toRemoveAnnotations;
loadedData = this.pdfAdapter.annotationSet;
toKeepAnnotations = this.pdfAdapter.annotations;
toRemoveAnnotations = this.pdfAdapter.annotationSet.annotations
.filter((annotation) => !this.pdfAdapter.annotations.map(a => a.id).includes(annotation.id));
toKeepAnnotations.forEach((annotation) => {
this.apiHttpService.saveAnnotation(annotation).subscribe(response => this.log.info('Successfully saved annotation:' + response), error => this.log.error('There has been a problem saving the annotation:' + annotation.id + '-' + error));
});
toRemoveAnnotations.forEach((annotation) => {
this.apiHttpService.deleteAnnotation(annotation).subscribe(response => this.log.info('Successfully deleted annotation:' + response), error => this.log.error('There has been a problem deleting annotation:' + annotation.id + '-' + error));
});
loadedData.annotations.splice(0, loadedData.annotations.length);
loadedData.annotations.concat(toKeepAnnotations);
this.pdfAdapter.annotationSet = loadedData;
}
/**
* @param {?} annotation
* @param {?=} type
* @return {?}
*/
saveAnnotation(annotation, type) {
this.apiHttpService.saveAnnotation(annotation).subscribe(response => {
if (type === 'addComment' || type === 'editComment') {
this.pdfAdapter.annotationSet.annotations[this.pdfAdapter.annotationSet.annotations
.findIndex(x => x.id === annotation.id)] = response.body;
}
this.log.info('Successfully saved annotation:' + response);
}, error => this.log.error('There has been a problem saving the annotation:' + annotation.id + '-' + error));
}
/**
* @param {?} annotation
* @return {?}
*/
deleteAnnotation(annotation) {
this.apiHttpService.deleteAnnotation(annotation).subscribe(response => {
this.log.info('Successfully deleted annotation:' + annotation.id + '-' + response);
}, error => this.log.error('There has been a problem deleting annotation:' + annotation.id + '-' + error));
}
/**
* @param {?} comment
* @return {?}
*/
editComment(comment) {
this.pdfAdapter.editComment(comment);
}
/**
* @param {?} annotationId
* @return {?}
*/
getAnnotationById(annotationId) {
return new Promise((resolve) => {
this.getAnnotation(annotationId, annotation => {
resolve(annotation);
});
});
}
/**
* @param {?} pageNumber
* @return {?}
*/
getAnnotationsForPage(pageNumber) {
return new Promise((resolve) => {
this.getAnnotations(pageNumber, pageData => {
resolve(pageData);
});
});
}
/**
* @param {?} annotationId
* @return {?}
*/
getCommentsForAnnotation(annotationId) {
return new Promise((resolve) => {
this.getComments(annotationId, comments => {
resolve(comments);
});
});
}
/**
* @param {?} annotationId
* @param {?} callback
* @return {?}
*/
getAnnotation(annotationId, callback) {
this.pdfAnnotateWrapper.getStoreAdapter()
.getAnnotation(this.pdfRenderService.getRenderOptions().documentId, annotationId)
.then(callback);
}
/**
* @param {?} annotationId
* @param {?} callback
* @return {?}
*/
getComments(annotationId, callback) {
this.pdfAnnotateWrapper.getStoreAdapter()
.getComments(this.pdfRenderService.getRenderOptions().documentId, annotationId)
.then(callback);
}
/**
* @param {?} comment
* @return {?}
*/
addComment(comment) {
this.pdfAnnotateWrapper.getStoreAdapter()
.addComment(this.pdfRenderService.getRenderOptions().documentId, comment.annotationId, comment.content)
.then();
}
/**
* @param {?} pageNumber
* @param {?} callback
* @return {?}
*/
getAnnotations(pageNumber, callback) {
this.pdfAnnotateWrapper.getStoreAdapter()
.getAnnotations(this.pdfRenderService.getRenderOptions().documentId, pageNumber)
.then(callback);
}
/**
* @param {?} commentId
* @return {?}
*/
deleteComment(commentId) {
this.pdfAnnotateWrapper.getStoreAdapter()
.deleteComment(this.pdfRenderService.getRenderOptions().documentId, commentId)
.then();
}
/**
* @param {?} annotationId
* @param {?} pageNumber
* @return {?}
*/
deleteAnnotationById(annotationId, pageNumber) {
return __awaiter(this, void 0, void 0, function* () {
/** @type {?} */
const renderOptions = this.pdfRenderService.getRenderOptions();
yield this.pdfAnnotateWrapper.getStoreAdapter()
.deleteAnnotation(renderOptions.documentId, annotationId);
this.renderPage(renderOptions, pageNumber);
});
}
/**
* @param {?} renderOptions
* @param {?} pageNumber
* @return {?}
*/
renderPage(renderOptions, pageNumber) {
renderOptions.rotate = this.pdfRenderService.getPageRotation(renderOptions, { pageNumber: pageNumber });
this.pdfAnnotateWrapper.renderPage(pageNumber, renderOptions);
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.annotationChangeSubscription) {
this.annotationChangeSubscription.unsubscribe();
}
}
}
AnnotationStoreService.decorators = [
{ type: Injectable }
];
AnnotationStoreService.ctorParameters = () => [
{ type: EmLoggerService },
{ type: PdfAdapter },
{ type: ApiHttpService },
{ type: PdfService },
{ type: PdfAnnotateWrapper },
{ type: PdfRenderService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class CommentsComponent {
/**
* @param {?} annotationStoreService
* @param {?} pdfService
* @param {?} utils
* @param {?} pdfRenderService
* @param {?} log
*/
constructor(annotationStoreService, pdfService, utils, pdfRenderService, log) {
this.annotationStoreService = annotationStoreService;
this.pdfService = pdfService;
this.utils = utils;
this.pdfRenderService = pdfRenderService;
this.log = log;
this.log.setClass('CommentsComponent');
}
/**
* @return {?}
*/
ngOnInit() {
this.dataLoadedSub = this.pdfRenderService.getDataLoadedSub()
.subscribe(isDataLoaded => {
if (isDataLoaded) {
this.showAllComments();
this.preRun();
}
});
}
/**
* @return {?}
*/
redrawCommentItemComponents() {
setTimeout(() => {
/** @type {?} */
let previousCommentItem;
this.sortCommentItemComponents().forEach((commentItem) => {
previousCommentItem = this.isOverlapping(commentItem, previousCommentItem);
});
});
}
/**
* @return {?}
*/
sortCommentItemComponents() {
return this.commentItems.map((commentItem) => commentItem)
.sort((a, b) => {
return this.processSort(a, b);
});
}
/**
* @param {?} a
* @param {?} b
* @return {?}
*/
processSort(a, b) {
if (this.isAnnotationOnSameLine(a, b)) {
if (a.annotationLeftPos < b.annotationLeftPos) {
return -1;
}
if (a.annotationLeftPos >= b.annotationLeftPos) {
return 1;
}
}
if (a.annotationTopPos < b.annotationTopPos) {
return -1;
}
if (a.annotationTopPos >= b.annotationTopPos) {
return 1;
}
return 0;
}
/**
* @param {?} a
* @param {?} b
* @return {?}
*/
isAnnotationOnSameLine(a, b) {
/** @type {?} */
const delta = (a.annotationHeight >= b.annotationHeight) ? a.annotationHeight : b.annotationHeight;
if (this.utils.difference(a.annotationTopPos, b.annotationTopPos) > delta) {
return false;
}
return true;
}
/**
* @param {?} commentItem
* @param {?} previousCommentItem
* @return {?}
*/
isOverlapping(commentItem, previousCommentItem) {
commentItem.commentTopPos = commentItem.annotationTopPos;
if (previousCommentItem) {
/** @type {?} */
const endOfPreviousCommentItem = (previousCommentItem.commentTopPos + previousCommentItem.commentHeight);
if (commentItem.commentTopPos <= endOfPreviousCommentItem) {
commentItem.commentTopPos = endOfPreviousCommentItem;
}
}
return commentItem;
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.pageNumSub) {
this.pageNumSub.unsubscribe();
}
if (this.dataLoadedSub) {
this.dataLoadedSub.unsubscribe();
}
}
/**
* @return {?}
*/
preRun() {
this.pageNumSub = this.pdfService.getPageNumber().subscribe(pageNumber => {
this.pageNumber = pageNumber;
});
}
/**
* @return {?}
*/
showAllComments() {
// todo - refactor this out of component
this.annotations = [];
for (let i = 0; i < this.pdfRenderService.getPdfPages() + 1; i++) {
this.annotationStoreService.getAnnotationsForPage(i)
.then((pageData) => {
this.annotations = this.annotations.concat(pageData.annotations.slice());
});
}
}
/**
* @return {?}
*/
handleAnnotationBlur() {
this.showAllComments();
}
/**
* @param {?} event
* @return {?}
*/
handleAnnotationClick(event) {
/** @type {?} */
const annotationId = event.getAttribute('data-pdf-annotate-id');
this.annotationStoreService.getAnnotationById(annotationId)
.then((annotation) => {
this.annotationStoreService.setAnnotationFocusSubject(annotation);
this.annotationStoreService.setCommentFocusSubject(annotation);
this.annotationStoreService.setToolBarUpdate(annotation, true);
});
}
}
CommentsComponent.decorators = [
{ type: Component, args: [{
selector: 'app-comments',
template: "<div *ngIf=\"pageNumber\" id=\"comment-wrapper\">\n <div class=\"comment-list-container\">\n\n <div *ngFor=\"let annotation of annotations\" class=\"highlight-group\">\n <app-comment-item #commentItem\n *ngFor=\"let comment of annotation.comments\"\n [annotation]=\"annotation\"\n [comment]=\"comment\"\n (commentSubmitted)='showAllComments()'\n (commentRendered)='redrawCommentItemComponents()'\n ></app-comment-item>\n </div>\n </div>\n</div>\n",
styles: ["#comment-wrapper{position:absolute;height:100%;width:380px;right:0;overflow:hidden;z-index:0;font-family:nta,Arial,sans-serif;-webkit-font-smoothing:antialiased;font-size:12px}#comment-wrapper .comment-list{font-size:12px;position:absolute;top:38px;left:0;right:0;bottom:0}#comment-wrapper .comment-list-container{position:absolute;top:0;left:0;right:0;bottom:47px;overflow-x:hidden;overflow-y:auto}"]
}] }
];
CommentsComponent.ctorParameters = () => [
{ type: AnnotationStoreService },
{ type: PdfService },
{ type: Utils },
{ type: PdfRenderService },
{ type: EmLoggerService }
];
CommentsComponent.propDecorators = {
commentItems: [{ type: ViewChildren, args: ['commentItem',] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class CommentItemComponent {
/**
* @param {?} annotationStoreService
* @param {?} pdfService
* @param {?} pdfRenderService
* @param {?} ref
* @param {?} renderer
* @param {?} utils
* @param {?} log
*/
constructor(annotationStoreService, pdfService, pdfRenderService, ref, renderer, utils, log) {
this.annotationStoreService = annotationStoreService;
this.pdfService = pdfService;
this.pdfRenderService = pdfRenderService;
this.ref = ref;
this.renderer = renderer;
this.utils = utils;
this.log = log;
this.commentSubmitted = new EventEmitter();
this.commentRendered = new EventEmitter();
this.model = new Comment(null, null, null, null, null, null, null, null, null);
this.log.setClass('CommentItemComponent');
}
/**
* @return {?}
*/
ngOnInit() {
this.hideButton = true;
this.focused = false;
this.sliceComment = this.comment.content;
this.commentFocusSub = this.annotationStoreService.getCommentFocusSubject()
.subscribe((options) => {
if (options.annotation.id === this.comment.annotationId) {
if (options.showButton) {
this.onEdit();
}
else {
this.handleShowBtn();
}
this.ref.detectChanges();
}
else {
this.onBlur();
}
});
this.commentBtnSub = this.annotationStoreService.getCommentBtnSubject()
.subscribe((commentId) => {
(commentId === this.comment.id) ? this.handleShowBtn() : this.handleHideBtn();
});
this.dataLoadedSub = this.pdfRenderService.getDataLoadedSub()
.subscribe((dataLoaded) => {
if (dataLoaded) {
this.annotationTopPos = this.getRelativePosition(this.comment.annotationId);
this.commentTopPos = this.annotationTopPos;
this.utils.sortByX(this.annotation.rectangles, true);
this.annotationHeight = this.utils.getAnnotationLineHeight(this.annotation.rectangles);
this.annotationLeftPos = this.annotation.rectangles[0].x;
this.commentRendered.emit(true);
this.collapseComment();
}
});
this.commentItem.statusChanges.subscribe(() => {
if (this.focused) {
this.expandComment();
}
});
}
/**
* @return {?}
*/
setHeight() {
this.renderer.setStyle(this.commentArea.nativeElement, 'height', 'fit-content');
this.renderer.setStyle(this.commentArea.nativeElement, 'height', (this.commentArea.nativeElement.scrollHeight) + 'px');
this.commentHeight = this.commentSelector.nativeElement.getBoundingClientRect().height;
this.commentRendered.emit(true);
if (!this.ref['destroyed']) {
this.ref.detectChanges();
}
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.commentFocusSub) {
this.commentFocusSub.unsubscribe();
}
if (this.commentBtnSub) {
this.commentBtnSub.unsubscribe();
}
if (this.dataLoadedSub) {
this.dataLoadedSub.unsubscribe();
}
}
/**
* @return {?}
*/
onSubmit() {
/** @type {?} */
const comment = this.convertFormToComment(this.commentItem);
this.annotationStoreService.editComment(comment);
this.commentSubmitted.emit(this.annotation);
this.viewOnly();
}
/**
* @return {?}
*/
onEdit() {
this.editOnly();
}
/**
* @return {?}
*/
onCancel() {
this.renderer.setProperty(this.commentArea.nativeElement, 'value', this.comment.content);
this.viewOnly();
}
/**
* @return {?}
*/
viewOnly() {
this.renderer.addClass(this.commentArea.nativeElement, 'view-mode');
this.focused = false;
}
/**
* @return {?}
*/
editOnly() {
this.focused = true;
this.renderer.removeClass(this.commentArea.nativeElement, 'view-mode');
}
/**
* @return {?}
*/
isModified() {
if (this.comment.createdDate === null) {
return false;
}
else if (this.comment.lastModifiedBy === null) {
return false;
}
else if (this.comment.createdDate === this.comment.lastModifiedDate) {
return false;
}
else {
return true;
}
}
/**
* @return {?}
*/
onBlur() {
if (!this.ref['destroyed']) {
this.ref.detectChanges();
}
}
/**
* @param {?} commentForm
* @return {?}
*/
convertFormToComment(commentForm) {
return new Comment(this.comment.id, this.comment.annotationId, null, null, new Date(), null, null, null, commentForm.value.content);
}
/**
* @return {?}
*/
handleDeleteComment() {
this.annotationStoreService.deleteComment(this.comment.id);
}
/**
* @param {?} event
* @return {?}
*/
handleCommentClick(event) {
event.stopPropagation();
this.annotationStoreService.setCommentBtnSubject(this.comment.id);
this.annotationStoreService.setAnnotationFocusSubject(this.annotation);
}
/**
* @return {?}
*/
handleShowBtn() {
new Promise(resolve => {
this.hideButton = false;
this.expandComment();
resolve('Success');
}).then(() => {
this.setHeight();
setTimeout(() => {
this.commentArea.nativeElement.focus();
});
});
}
/**
* @return {?}
*/
handleHideBtn() {
new Promise(resolve => {
if (!this.commentItem.value.content) {
this.annotationStoreService.deleteComment(this.comment.id);
}
this.focused = false;
this.hideButton = true;
this.collapseComment();
resolve('Success');
}).then(() => {
this.setHeight();
});
}
/**
* @return {?}
*/
collapseComment() {
new Promise(resolve => {
this.expandComment();
resolve('Success');
}).then(() => {
if (!this.isCommentEmpty()) {
this.shrinkComment();
}
this.renderer.addClass(this.commentArea.nativeElement, 'collapsed');
this.renderer.removeClass(this.commentArea.nativeElement, 'expanded');
this.renderer.addClass(this.detailsWrapper.nativeElement, 'collapsed');
this.renderer.addClass(this.commentArea.nativeElement, 'view-mode');
this.setHeight();
});
}
/**
* @return {?}
*/
isCommentEmpty() {
return this.comment.content === null;
}
/**
* @return {?}
*/
isShrinkable() {
return this.commentArea.nativeElement.scrollHeight > 31;
}
/**
* @return {?}
*/
shrinkComment() {
if (this.isShrinkable()) {
this.sliceComment = this.removeMultipleLines().slice(0, 20) + '...';
}
}
/**
* @return {?}
*/
removeMultipleLines() {
return this.comment.content.split('\n').join(' ');
}
/**
* @return {?}
*/
expandComment() {
this.renderer.addClass(this.commentArea.nativeElement, 'expanded');
this.renderer.removeClass(this.commentArea.nativeElement, 'collapsed');
this.renderer.removeClass(this.detailsWrapper.nativeElement, 'collapsed');
this.renderer.addClass(this.detailsWrapper.nativeElement, 'expanded');
this.sliceComment = this.comment.content;
this.setHeight();
}
/**
* @param {?} annotationId
* @return {?}
*/
getRelativePosition(annotationId) {
/** @type {?} */
const svgSelector = this.pdfRenderService.getViewerElementRef().nativeElement
.querySelector(`g[data-pdf-annotate-id="${annotationId}"]`);
if (svgSelector === null) {
return null;
}
else {
/** @type {?} */
const highlightRect = (/** @type {?} */ (svgSelector.getBoundingClientRect()));
/** @type {?} */
const wrapperRect = (/** @type {?} */ (this.pdfService.getAnnotationWrapper().nativeElement.getBoundingClientRect()));
return (highlightRect.y - wrapperRect.top);
}
}
}
CommentItemComponent.decorators = [
{ type: Component, args: [{
selector: 'app-comment-item',
template: "<form class=\"aui-comment comment-list-item\"\n (ngSubmit)=\"onSubmit()\"\n #commentSelector\n #commentItem=\"ngForm\"\n (click)=\"handleCommentClick($event)\"\n [style.top.px]=\"commentTopPos\">\n <div #detailsWrapper id=\"detailsWrapper\" class=\"aui-comment__header\">\n <span *ngIf=\"comment.createdByDetails\" class=\"aui-comment__author\">{{comment.createdByDetails.forename}} {{comment.createdByDetails.surname}}</span>\n <time #commentDate class=\"aui-comment__meta\" ng-controller=\"datCtrl\">{{ comment.createdDate | date: 'd MMMM y h:mm a' }}</time>\n <div *ngIf=\"false\">\n <span>modified By: {{comment.lastModifiedByDetails.forename}} {{comment.lastModifiedByDetails.surname}}</span>\n <time class=\"aui-comment__meta\" ng-controller=\"datCtrl\"><br>{{ comment.lastModifiedDate | date: 'd MMMM y h:mm a' }}</time>\n </div>\n </div>\n\n <textarea\n #commentArea\n (blur)=\"onBlur()\"\n type=\"text\"\n [class.mimic-focus]=\"focused\"\n class=\"aui-comment__content form-control mimic-focus view-mode\"\n required\n [ngModel]=\"sliceComment\" name=\"content\"\n value=\"comment.content\"\n [readonly]=\"!focused\"></textarea>\n\n <div [hidden]=\"hideButton\" class=\"aui-comment__footer commentBtns\">\n <button *ngIf=\"focused\" type=\"submit\" class=\"govuk-button\" role=\"button\">Save</button>\n <button *ngIf=\"!focused\" (click)=\"onEdit()\" class=\"govuk-button\" role=\"button\">Edit</button>\n <button\n *ngIf=\"!focused\"\n class=\"govuk-button hmcts hmcts-button--secondary\"\n role=\"button\"\n (click)=\"handleDeleteComment()\">Delete</button>\n <button\n *ngIf=\"focused\"\n class=\"govuk-button hmcts hmcts-button--secondary\"\n role=\"button\"\n (click)=\"onCancel()\">Cancel</button>\n </div>\n</form>\n",
styles: ["form{width:95%;margin-bottom:5px;position:absolute;background-color:#fff;padding:20px 20px 0}form textarea{width:95%;padding:2px;border:none;font-size:17px;font-family:nta,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;overflow:hidden;resize:none}.mimic-focus{outline-offset:-2px;outline:#0b0c0c auto 5px}textarea.view-mode:focus{outline:0}#detailsWrapper{padding:0}#detailsWrapper.expanded{margin-bottom:15px}.commentBtns{height:50px}.expanded{margin-top:0}.collapsed{height:30px}textarea.expanded{margin-bottom:10px}textarea.collapsed{margin-top:-25px;max-height:20px}.collapsed>time{display:none}"]
}] }
];
CommentItemComponent.ctorParameters = () => [
{ type: AnnotationStoreService },
{ type: PdfService },
{ type: PdfRenderService },
{ type: ChangeDetectorRef },
{ type: Renderer2 },
{ type: Utils },
{ type: EmLoggerService }
];
CommentItemComponent.propDecorators = {
comment: [{ type: Input }],
annotation: [{ type: Input }],
commentSubmitted: [{ type: Output }],
commentRendered: [{ type: Output }],
commentSelector: [{ type: ViewChild, args: ['commentSelector',] }],
commentArea: [{ type: ViewChild, args: ['commentArea',] }],
commentItem: [{ type: ViewChild, args: ['commentItem',] }],
detailsWrapper: [{ type: ViewChild, args: ['detailsWrapper',] }],
commentDate: [{ type: ViewChild, args: ['commentDate',] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NpaService {
/**
* @param {?} log
* @param {?} apiHttpService
*/
constructor(log, apiHttpService) {
this.log = log;
this.apiHttpService = apiHttpService;
log.setClass('NpaService');
this.outputDmDocumentId = new Subject();
this.documentTask = new Subject();
}
/**
* @param {?} dmDocumentId
* @param {?} outputDmDocumentId
* @param {?} baseUrl
* @return {?}
*/
exportPdf(dmDocumentId, outputDmDocumentId, baseUrl) {
this.log.info('Calling HTTP service for NPA');
return this.apiHttpService.documentTask(dmDocumentId, outputDmDocumentId, baseUrl);
}
}
NpaService.decorators = [
{ type: Injectable }
];
NpaService.ctorParameters = () => [
{ type: EmLoggerService },
{ type: ApiHttpService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ContextualToolbarComponent {
/**
* @param {?} annotationStoreService
* @param {?} ref
* @param {?} pdfRenderService
* @param {?} pdfService
* @param {?} log
*/
constructor(annotationStoreService, ref, pdfRenderService, pdfService, log) {
this.annotationStoreService = annotationStoreService;
this.ref = ref;
this.pdfRenderService = pdfRenderService;
this.pdfService = pdfService;
this.log = log;
this.deletedAnnotation = new EventEmitter();
this.log.setClass('ContextualToolbarComponent');
this.toolPos = {
left: 0,
top: 0
};
}
/**
* @return {?}
*/
ngOnInit() {
this.contextualToolBarOptions = this.annotationStoreService.getToolbarUpdate()
.subscribe(contextualOptions => {
if (contextualOptions.annotation != null) {
this.showToolBar(contextualOptions.annotation, contextualOptions.showDelete);
}
else {
this.hideToolBar();
}
});
this.isShowToolbar = false;
}
/**
* @return {?}
*/
ngOnDestroy() {
this.ref.detach();
if (this.contextualToolBarOptions) {
this.contextualToolBarOptions.unsubscribe();
}
}
/**
* @param {?} annotation
* @param {?=} showDelete
* @return {?}
*/
showToolBar(annotation, showDelete) {
this.annotation = annotation;
this.showDelete = showDelete;
this.toolPos = this.getRelativePosition(annotation.id);
this.isShowToolbar = true;
if (!this.ref['destroyed']) {
this.ref.detectChanges();
}
}
/**
* @param {?} annotationId
* @return {?}
*/
getRelativePosition(annotationId) {
/** @type {?} */
const svgSelector = this.pdfRenderService.getViewerElementRef().nativeElement
.querySelector(`g[data-pdf-annotate-id="${annotationId}"]`);
/** @type {?} */
const highlightRect = (/** @type {?} */ (svgSelector.getBoundingClientRect()));
/** @type {?} */
const wrapper = this.pdfService.getAnnotationWrapper().nativeElement;
/** @type {?} */
const wrapperRect = (/** @type {?} */ (wrapper.getBoundingClientRect()));
/** @type {?} */
const left = ((highlightRect.x - wrapperRect.left)
- 175) + highlightRect.width / 2;
// Minus half the toolbar width + half the length of the highlight
/** @type {?} */
const top = ((highlightRect.y - wrapperRect.top)
- 59) - 5;
return {
left,
top
};
}
/**
* @return {?}
*/
hideToolBar() {
this.annotation = null;
this.isShowToolbar = false;
this.showDelete = false;
if (!this.ref['destroyed']) {
this.ref.detectChanges();
}
}
/**
* @return {?}
*/
handleCommentBtnClick() {
if (this.annotation.comments.length === 0) {
this.annotationStoreService.addComment(new Comment(null, this.annotation.id, null, null, null, null, null, null, null));
}
setTimeout(() => {
/** @type {?} */
const tempAnnotation = this.annotation;
this.hideToolBar();
this.annotationStoreService.setCommentFocusSubject(tempAnnotation, true);
}, 10);
}
/**
* @return {?}
*/
handleHighlightBtnClick() {
this.hideToolBar();
}
/**
* @return {?}
*/
handleDeleteBtnClick() {
return __awaiter(this, void 0, void 0, function* () {
yield this.annotationStoreService.deleteAnnotationById(this.annotation.id, this.annotation.page);
this.hideToolBar();
this.deletedAnnotation.emit('deleted annotation');
});
}
}
ContextualToolbarComponent.decorators = [
{ type: Component, args: [{
selector: 'app-contextual-toolbar',
template: "<div [hidden]=\"!isShowToolbar\" class=\"toolbar\"\n [style.left.px]=\"toolPos.left\"\n [style.top.px]=\"toolPos.top\">\n\n <button\n [hidden]=\"showDelete\"\n type=\"button\" class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n title=\"Highlight\"\n (click)=\"handleHighlightBtnClick()\"\n ><span>Add Highlight</span></button>\n\n <button\n [hidden]=\"!showDelete\"\n type=\"button\"\n title=\"Delete\" class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n (click)=\"handleDeleteBtnClick()\"\n ><span>Remove Highlight</span></button>\n\n <button type=\"button\" title=\"Comment\" class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton\"\n (click)=\"handleCommentBtnClick()\"\n ><span>Comment</span></button>\n\n\n <div class=\"arrow-down\">\n <div class=\"inner-triangle\"></div>\n </div>\n\n</div>\n",
styles: [".toolbar{position:absolute;background-color:#fff;height:52px;width:350px;margin:0 auto;text-shadow:1px 1px 0 #fff;z-index:1;border:1px solid #c1c1c1;box-shadow:0 2px #c1c1c1}.toolbar .spacer{display:inline-block;border-left:1px solid #c1c1c1;height:34px;margin:0 5px -11px}.toolbar button span{margin-left:20px}.toolbar button{padding:0;margin-left:2.5%;margin-right:2.5%;margin-top:6px;height:40px;border:0}.toolbar button:hover{border:1px solid #000}.contextual-btn{font-size:16px;background:5px 50%/20px 20px no-repeat #fff}.rightButton{width:124px;background-image:url(/assets/images/icon-document-comments.svg)}.leftButton{background-image:url(/assets/images/annotate-highlight.svg);width:190px}.arrow-down{margin:53px auto 0;width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid #c1c1c1}.inner-triangle{position:relative;top:-13px;left:-10px;width:0;height:0;border-left:10px solid transparent;border-right:10px solid transparent;border-top:10px solid #fff}"]
}] }
];
ContextualToolbarComponent.ctorParameters = () => [
{ type: AnnotationStoreService },
{ type: ChangeDetectorRef },
{ type: PdfRenderService },
{ type: PdfService },
{ type: EmLoggerService }
];
ContextualToolbarComponent.propDecorators = {
deletedAnnotation: [{ type: Output }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class RenderOptions {
/**
* @param {?} documentId
* @param {?} pdfDocument
* @param {?} scale
* @param {?} rotate
* @param {?} rotationPages
*/
constructor(documentId, pdfDocument, scale, rotate, rotationPages) {
this.documentId = documentId;
this.pdfDocument = pdfDocument;
this.scale = scale;
this.rotate = rotate;
this.rotationPages = rotationPages;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class RotationComponent {
/**
* @param {?} pdfRenderService
* @param {?} log
*/
constructor(pdfRenderService, log) {
this.pdfRenderService = pdfRenderService;
this.log = log;
this.rotationStyle = {};
this.viewerStyle = {};
this.log.setClass('RotationComponent');
}
/**
* @return {?}
*/
ngOnInit() {
/** @type {?} */
const height = `${((/** @type {?} */ (document.getElementById('pageContainer' + this.pageNumber).querySelector('.textLayer')))).style.height}`;
this.rotationStyle = {
'margin-top': `-${height}`
};
this.viewerStyle = {
'top': `${height}`
};
}
/**
* @param {?} rotateVal
* @return {?}
*/
calculateRotation(rotateVal) {
/** @type {?} */
const circleDegrees = 360;
return (rotateVal % circleDegrees + circleDegrees) % circleDegrees;
}
/**
* @return {?}
*/
onRotateClockwise() {
/** @type {?} */
const RENDER_OPTIONS = this.pdfRenderService.getRenderOptions();
/** @type {?} */
const rotation = RENDER_OPTIONS.rotationPages
.find(rotatePage => rotatePage.page === this.pageNumber).rotate;
RENDER_OPTIONS.rotationPages
.find(rotatePage => rotatePage.page === this.pageNumber).rotate = this.calculateRotation(rotation + 90);
this.pdfRenderService.setRenderOptions(RENDER_OPTIONS);
this.pdfRenderService.render();
}
}
RotationComponent.decorators = [
{ type: Component, args: [{
selector: 'app-rotation-toolbar',
template: "<div class=\"viewer-menu\" [ngStyle]=\"viewerStyle\">\n <button\n [ngStyle]=\"rotationStyle\"\n class=\"govuk-button hmcts hmcts-button--secondary rotate\"\n title=\"Clockwise\"\n role=\"button\"\n (click)=\"onRotateClockwise()\">Rotate</button>\n</div>\n",
styles: [".viewer-menu{width:100%;position:-webkit-sticky;position:sticky;left:0}.rotate{background-repeat:no-repeat;background-size:14px 14px;background-position:3px 50%;background-image:url(/assets/images/viewer-rotate.svg);padding-left:25px;float:right}"]
}] }
];
RotationComponent.ctorParameters = () => [
{ type: PdfRenderService },
{ type: EmLoggerService }
];
RotationComponent.propDecorators = {
pageNumber: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class RotationFactoryService {
/**
* @param {?} componentFactoryResolver
* @param {?} log
* @param {?} injector
* @param {?} appRef
*/
constructor(componentFactoryResolver, log, injector, appRef) {
this.componentFactoryResolver = componentFactoryResolver;
this.log = log;
this.injector = injector;
this.appRef = appRef;
this.log.setClass('RotationFactoryService');
}
/**
* @param {?} rotationModel
* @return {?}
*/
addToDom(rotationModel) {
this.log.info('Adding rotate button to PDF page ' + rotationModel.pageNumber);
/** @type {?} */
const componentRef = this.componentFactoryResolver
.resolveComponentFactory(RotationComponent)
.create(this.injector);
componentRef.instance.pageNumber = rotationModel.pageNumber;
this.appRef.attachView(componentRef.hostView);
/** @type {?} */
const domElem = (/** @type {?} */ (((/** @type {?} */ (componentRef.hostView)))
.rootNodes[0]));
rotationModel.pageDom.appendChild(domElem);
return componentRef;
}
}
RotationFactoryService.decorators = [
{ type: Injectable }
];
RotationFactoryService.ctorParameters = () => [
{ type: ComponentFactoryResolver },
{ type: EmLoggerService },
{ type: Injector },
{ type: ApplicationRef }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class AnnotationPdfViewerComponent {
/**
* @param {?} pdfService
* @param {?} npaService
* @param {?} apiHttpService
* @param {?} annotationStoreService
* @param {?} utils
* @param {?} ref
* @param {?} renderer
* @param {?} pdfAnnotateWrapper
* @param {?} pdfRenderService
* @param {?} rotationFactoryService
* @param {?} log
*/
constructor(pdfService, npaService, apiHttpService, annotationStoreService, utils, ref, renderer, pdfAnnotateWrapper, pdfRenderService, rotationFactoryService, log) {
this.pdfService = pdfService;
this.npaService = npaService;
this.apiHttpService = apiHttpService;
this.annotationStoreService = annotationStoreService;
this.utils = utils;
this.ref = ref;
this.renderer = renderer;
this.pdfAnnotateWrapper = pdfAnnotateWrapper;
this.pdfRenderService = pdfRenderService;
this.rotationFactoryService = rotationFactoryService;
this.log = log;
this.rotationComponents = [];
}
/**
* @return {?}
*/
ngOnInit() {
this.loadAnnotations(this.annotate);
this.pdfService.preRun();
this.pdfRenderService.setRenderOptions(new RenderOptions(this.url, null, parseFloat('1.33'), 0, []));
if (this.rotate) {
this.pdfPageSubscription = this.pdfRenderService.listPagesSubject
.subscribe((listPages) => {
this.rotationComponents.forEach(rc => rc.destroy());
listPages.forEach(pageDetails => {
this.rotationComponents.push(this.rotationFactoryService.addToDom(pageDetails));
});
});
}
this.pdfRenderService.render(this.viewerElementRef);
this.pdfService.setAnnotationWrapper(this.annotationWrapper);
this.pageNumberSubscription = this.pdfService.getPageNumber()
.subscribe(page => this.page = page);
this.focusedAnnotationSubscription = this.annotationStoreService.getAnnotationFocusSubject()
.subscribe(focusedAnnotation => this.focusHighlightStyle(focusedAnnotation));
}
/**
* @return {?}
*/
ngAfterViewInit() {
this.pdfAnnotateWrapper.getUi().addEventListener('annotation:click', this.handleAnnotationClick.bind(this));
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.pageNumberSubscription) {
this.pageNumberSubscription.unsubscribe();
}
if (this.focusedAnnotationSubscription) {
this.focusedAnnotationSubscription.unsubscribe();
}
if (this.pdfPageSubscription) {
this.pdfPageSubscription.unsubscribe();
}
}
/**
* @param {?} annotate
* @return {?}
*/
loadAnnotations(annotate) {
if (annotate) {
this.log.info('annotations are enabled');
this.apiHttpService.setBaseUrl(this.baseUrl);
this.annotationStoreService.preLoad(this.annotationSet);
this.npaService.outputDmDocumentId.next(this.outputDmDocumentId);
}
else {
this.log.info('annotations are disabled');
this.annotationStoreService.preLoad(null);
}
}
/**
* @param {?} event
* @param {?=} isPage
* @return {?}
*/
handleClick(event, isPage) {
if (this.annotate) {
if (!this.utils.clickIsHighlight(event)) {
this.unfocusAnnotation();
this.annotationStoreService.setToolBarUpdate(null, null);
}
this.commentsComponent.handleAnnotationBlur();
if (isPage) {
this.pdfService.setPageNumber(this.utils.getClickedPage(event));
}
}
}
/**
* @return {?}
*/
renderComments() {
this.unfocusAnnotation();
this.commentsComponent.showAllComments();
}
/**
* @return {?}
*/
unfocusAnnotation() {
this.annotationStoreService.setAnnotationFocusSubject(new Annotation());
this.annotationStoreService.setCommentBtnSubject(null);
this.annotationStoreService.setCommentFocusSubject(new Annotation(), null);
}
/**
* @param {?} event
* @return {?}
*/
handleAnnotationClick(event) {
if (!this.contextualToolbar.isShowToolbar) {
/** @type {?} */
const annotationId = event.getAttribute('data-pdf-annotate-id');
this.annotationStoreService.getAnnotationById(annotationId)
.then((annotation) => {
this.annotationStoreService.setAnnotationFocusSubject(annotation);
this.annotationStoreService.setCommentFocusSubject(annotation);
this.annotationStoreService.setToolBarUpdate(annotation, true);
});
}
}
/**
* @param {?} focusedAnnotation
* @return {?}
*/
focusHighlightStyle(focusedAnnotation) {
Array.from(this.viewerElementRef.nativeElement.querySelector(`#pageContainer${this.page} .annotationLayer`).childNodes)
.forEach((annotationDom) => {
if (annotationDom.dataset.pdfAnnotateId === focusedAnnotation.id) {
this.renderer.addClass(annotationDom, 'comment-selected');
}
else {
this.renderer.removeClass(annotationDom, 'comment-selected');
}
});
if (!this.ref['destroyed']) {
this.ref.detectChanges();
}
}
}
AnnotationPdfViewerComponent.decorators = [
{ type: Component, args: [{
selector: 'app-annotation-pdf-viewer',
template: "\n<app-comments (click)=\"handleClick($event, false)\" #commentsComponent\n *ngIf=\"annotate\"></app-comments>\n\n<div id=\"annotation-wrapper\" #annotationWrapper>\n <app-contextual-toolbar (deletedAnnotation)=\"renderComments()\" #contextualToolbar></app-contextual-toolbar>\n\n <div id=\"content-wrapper\"\n #contentWrapper\n (click)=\"handleClick($event, true)\">\n <div id=\"viewer\" #viewer class=\"pdfViewer\"></div>\n </div>\n</div>\n",
styles: ["#annotation-wrapper{position:relative;width:100%}#content-wrapper{overflow:hidden}"]
}] }
];
AnnotationPdfViewerComponent.ctorParameters = () => [
{ type: PdfService },
{ type: NpaService },
{ type: ApiHttpService },
{ type: AnnotationStoreService },
{ type: Utils },
{ type: ChangeDetectorRef },
{ type: Renderer2 },
{ type: PdfAnnotateWrapper },
{ type: PdfRenderService },
{ type: RotationFactoryService },
{ type: EmLoggerService }
];
AnnotationPdfViewerComponent.propDecorators = {
annotate: [{ type: Input }],
dmDocumentId: [{ type: Input }],
outputDmDocumentId: [{ type: Input }],
url: [{ type: Input }],
annotationSet: [{ type: Input }],
baseUrl: [{ type: Input }],
rotate: [{ type: Input }],
contentWrapper: [{ type: ViewChild, args: ['contentWrapper',] }],
viewerElementRef: [{ type: ViewChild, args: ['viewer',] }],
annotationWrapper: [{ type: ViewChild, args: ['annotationWrapper',] }],
commentsComponent: [{ type: ViewChild, args: ['commentsComponent',] }],
contextualToolbar: [{ type: ViewChild, args: ['contextualToolbar',] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ImageViewerComponent {
/**
* @param {?} renderer
* @param {?} log
*/
constructor(renderer, log) {
this.renderer = renderer;
this.log = log;
this.log.setClass('ImageViewerComponent');
}
/**
* @return {?}
*/
ngOnInit() {
this.rotation = 0;
}
/**
* @return {?}
*/
onRotateClockwise() {
this.rotation = this.rotation + 90;
this.rotateImage();
}
/**
* @return {?}
*/
rotateImage() {
this.log.info('rotating to-' + this.rotation + 'degrees');
/** @type {?} */
const styles = ['transform', '-ms-transform', '-o-transform', '-moz-transform', '-webkit-transform'];
for (const style of styles) {
this.renderer.setStyle(this.img.nativeElement, style, `rotate(${this.rotation}deg)`);
}
}
}
ImageViewerComponent.decorators = [
{ type: Component, args: [{
selector: 'app-image-viewer',
template: "\n <div id=\"viewer-wrapper\">\n <button\n *ngIf=\"rotate\"\n class=\"govuk-button hmcts hmcts-button--secondary rotate\"\n title=\"Clockwise\"\n role=\"button\"\n (click)=\"onRotateClockwise()\">Rotate</button>\n\n <img #img *ngIf=\"url\" data-hook=\"dm.viewer.img\" [src]=\"url\" />\n </div>",
styles: ["#viewer-wrapper{position:relative;width:100%}.rotate{z-index:1;position:absolute;right:0;background-repeat:no-repeat;background-size:14px 14px;background-position:3px 50%;padding-left:25px;background-image:url(/assets/images/viewer-rotate.svg)}.anti{right:24px;-webkit-transform:scaleX(-1);transform:scaleX(-1)}img{width:100%}"]
}] }
];
ImageViewerComponent.ctorParameters = () => [
{ type: Renderer2 },
{ type: EmLoggerService }
];
ImageViewerComponent.propDecorators = {
url: [{ type: Input }],
originalUrl: [{ type: Input }],
rotate: [{ type: Input }],
img: [{ type: ViewChild, args: ['img',] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class UnsupportedViewerComponent {
constructor() { }
/**
* @return {?}
*/
ngOnInit() {
}
}
UnsupportedViewerComponent.decorators = [
{ type: Component, args: [{
selector: 'app-unsupported-viewer',
template: "<p data-hook=\"dm.viewer.unsupported\">\n This file type is not supported. Please <a href=\"{{url}}\">click here to download</a>.\n</p>\n",
styles: [""]
}] }
];
UnsupportedViewerComponent.ctorParameters = () => [];
UnsupportedViewerComponent.propDecorators = {
url: [{ type: Input }],
originalUrl: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class UrlFixerService {
/**
* @param {?} url
* @param {?} baseUrl
* @return {?}
*/
fixDm(url, baseUrl) {
return url.replace(/http.*\/documents\//, `${baseUrl}/documents/`);
}
}
UrlFixerService.decorators = [
{ type: Injectable }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ViewerFactoryService {
/**
* @param {?} componentFactoryResolver
* @param {?} annotationStoreService
* @param {?} urlFixer
* @param {?} log
*/
constructor(componentFactoryResolver, annotationStoreService, urlFixer, log) {
this.componentFactoryResolver = componentFactoryResolver;
this.annotationStoreService = annotationStoreService;
this.urlFixer = urlFixer;
this.log = log;
this.log.setClass('ViewerFactoryService');
}
/**
* @private
* @param {?} mimeType
* @return {?}
*/
static determineComponent(mimeType) {
if (ViewerFactoryService.isImage(mimeType)) {
return ImageViewerComponent;
}
return UnsupportedViewerComponent;
}
/**
* @private
* @param {?} mimeType
* @return {?}
*/
static isImage(mimeType) {
return mimeType.startsWith('image/') || mimeType === 'image';
}
/**
* @private
* @param {?} mimeType
* @return {?}
*/
static isPdf(mimeType) {
return mimeType === 'application/pdf' || mimeType === 'pdf';
}
/**
* @param {?} documentMetaData
* @return {?}
*/
getDocumentId(documentMetaData) {
/** @type {?} */
const docArray = documentMetaData._links.self.href.split('/');
return docArray[docArray.length - 1];
}
/**
* @param {?} viewContainerRef
* @param {?} contentType
* @param {?} url
* @param {?} baseUrl
* @param {?} originalUrl
* @param {?} annotate
* @param {?} annotationSet
* @param {?} rotate
* @return {?}
*/
buildComponent(viewContainerRef, contentType, url, baseUrl, originalUrl, annotate, annotationSet, rotate) {
if (ViewerFactoryService.isPdf(contentType) && annotate) {
this.log.info('Selected pdf viewer with annotations enabled');
return this.buildAnnotateUi(url, viewContainerRef, baseUrl, annotate, annotationSet, rotate);
}
else if (ViewerFactoryService.isPdf(contentType) && !annotate) {
this.log.info('Selected pdf viewer with annotations disabled');
return this.buildAnnotateUi(url, viewContainerRef, baseUrl, annotate, null, rotate);
}
else if (ViewerFactoryService.isImage(contentType)) {
this.log.info('Selected image viewer');
return this.createComponent(ImageViewerComponent, viewContainerRef, originalUrl, url, rotate);
}
else {
this.log.info('Unsupported type for viewer');
return this.createComponent(UnsupportedViewerComponent, viewContainerRef, originalUrl, url);
}
}
/**
* @param {?} url
* @param {?} viewContainerRef
* @param {?} baseUrl
* @param {?} annotate
* @param {?} annotationSet
* @param {?} rotate
* @return {?}
*/
buildAnnotateUi(url, viewContainerRef, baseUrl, annotate, annotationSet, rotate) {
viewContainerRef.clear();
/** @type {?} */
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(AnnotationPdfViewerComponent);
/** @type {?} */
const componentRef = viewContainerRef.createComponent(componentFactory);
componentRef.instance.annotate = annotate;
componentRef.instance.annotationSet = annotationSet;
componentRef.instance.outputDmDocumentId = null; // '4fbdde23-e9a7-4843-b6c0-24d5bf2140ab';
componentRef.instance.baseUrl = baseUrl;
componentRef.instance.url = url;
componentRef.instance.rotate = rotate;
return componentRef.instance;
}
/**
* @param {?} component
* @param {?} viewContainerRef
* @param {?} originalUrl
* @param {?} url
* @param {?=} rotate
* @return {?}
*/
createComponent(component, viewContainerRef, originalUrl, url, rotate) {
/** @type {?} */
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
viewContainerRef.clear();
/** @type {?} */
const componentRef = viewContainerRef.createComponent(componentFactory);
componentRef.instance.originalUrl = originalUrl;
componentRef.instance.url = url;
componentRef.instance.rotate = rotate;
return componentRef.instance;
}
}
ViewerFactoryService.decorators = [
{ type: Injectable }
];
ViewerFactoryService.ctorParameters = () => [
{ type: ComponentFactoryResolver },
{ type: AnnotationStoreService },
{ type: UrlFixerService },
{ type: EmLoggerService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ViewerAnchorDirective {
/**
* @param {?} viewContainerRef
*/
constructor(viewContainerRef) {
this.viewContainerRef = viewContainerRef;
}
}
ViewerAnchorDirective.decorators = [
{ type: Directive, args: [{
selector: '[appViewerAnchor]',
},] }
];
ViewerAnchorDirective.ctorParameters = () => [
{ type: ViewContainerRef }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DocumentViewerService {
/**
* @param {?} log
* @param {?} httpClient
* @param {?} state
*/
constructor(log, httpClient, state) {
this.log = log;
this.httpClient = httpClient;
this.state = state;
log.setClass('DocumentViewerService');
}
/**
* @param {?} documentUri
* @return {?}
*/
getDocumentMetadata(documentUri) {
/** @type {?} */
const key = makeStateKey(documentUri);
/** @type {?} */
const cache = this.state.get(key, (/** @type {?} */ (null)));
if (cache) {
return of(cache);
}
return this.httpClient
.get(documentUri)
.pipe(map(data => {
this.state.set(key, data);
return data;
}))
.pipe(catchError(error => {
/** @type {?} */
const value = { error };
this.state.set(key, value);
this.log.error('Encountered error while downloading document:' + documentUri + '-' + error);
return of(value);
}));
}
}
DocumentViewerService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
DocumentViewerService.ctorParameters = () => [
{ type: EmLoggerService },
{ type: HttpClient },
{ type: TransferState }
];
/** @nocollapse */ DocumentViewerService.ngInjectableDef = defineInjectable({ factory: function DocumentViewerService_Factory() { return new DocumentViewerService(inject(EmLoggerService), inject(HttpClient), inject(TransferState)); }, token: DocumentViewerService, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DocumentViewerComponent {
/**
* @param {?} log
* @param {?} viewerFactoryService
* @param {?} annotationStoreService
* @param {?} urlFixer
* @param {?} documentViewerService
*/
constructor(log, viewerFactoryService, annotationStoreService, urlFixer, documentViewerService) {
this.log = log;
this.viewerFactoryService = viewerFactoryService;
this.annotationStoreService = annotationStoreService;
this.urlFixer = urlFixer;
this.documentViewerService = documentViewerService;
this.url = '';
this.rotate = false;
log.setClass('DocumentViewerComponent');
}
/**
* @return {?}
*/
ngOnInit() {
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
if (changes.url || changes.annotate) {
this.buildViewer();
}
}
/**
* @return {?}
*/
buildViewer() {
if (!this.url) {
this.log.error('url is required argument');
throw new Error('url is required argument');
}
if (this.isDM) {
this.documentViewerService.getDocumentMetadata(`${this.urlFixer.fixDm(this.url, this.baseUrl)}`).subscribe(metadata => {
this.log.info(metadata);
if (metadata && metadata._links) {
/** @type {?} */
const url = this.urlFixer.fixDm(metadata._links.binary.href, this.baseUrl);
/** @type {?} */
const dmDocumentId = this.viewerFactoryService.getDocumentId(metadata);
if (this.annotate) {
this.annotationStoreService.getAnnotationSet(this.baseUrl, dmDocumentId).subscribe(annotationSet => {
this.buildComponent(metadata, url, annotationSet.body);
});
}
else {
this.buildComponent(metadata, url, null);
}
}
}, err => {
this.log.error('An error has occured while fetching document' + err);
this.error = err;
});
}
else {
this.viewerComponent = this.viewerFactoryService.buildComponent(this.viewerAnchor.viewContainerRef, this.contentType, this.url, this.baseUrl, this.url, this.annotate, null, this.rotate);
}
}
/**
* @param {?} metadata
* @param {?} url
* @param {?=} annotationSet
* @return {?}
*/
buildComponent(metadata, url, annotationSet) {
this.viewerFactoryService.buildComponent(this.viewerAnchor.viewContainerRef, metadata.mimeType, url, this.baseUrl, metadata._links.self.href, this.annotate, annotationSet, this.rotate);
}
}
DocumentViewerComponent.decorators = [
{ type: Component, args: [{
selector: 'app-document-viewer',
template: "\n<ng-template appViewerAnchor></ng-template>\n\n<div class=\"grid-row\">\n <div *ngIf=\"error\" class=\"error-summary\" role=\"alert\" aria-labelledby=\"error-summary-heading-example-1\" tabindex=\"-1\">\n <h2 class=\"heading-medium error-summary-heading\" id=\"error-summary-heading-example-1\">There was an error while loading your document.</h2>\n <p>Response status was {{error.status}}.</p>\n </div>\n</div>\n\n"
}] }
];
DocumentViewerComponent.ctorParameters = () => [
{ type: EmLoggerService },
{ type: ViewerFactoryService },
{ type: AnnotationStoreService },
{ type: UrlFixerService },
{ type: DocumentViewerService }
];
DocumentViewerComponent.propDecorators = {
viewerAnchor: [{ type: ViewChild, args: [ViewerAnchorDirective,] }],
url: [{ type: Input }],
annotate: [{ type: Input }],
baseUrl: [{ type: Input }],
isDM: [{ type: Input }],
contentType: [{ type: Input }],
rotate: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class HmctsEmViewerUiModule {
}
HmctsEmViewerUiModule.decorators = [
{ type: NgModule, args: [{
imports: [
NgtUniversalModule,
CommonModule,
FormsModule,
HttpClientModule
],
declarations: [
CommentsComponent,
CommentItemComponent,
ContextualToolbarComponent,
AnnotationPdfViewerComponent,
ImageViewerComponent,
UnsupportedViewerComponent,
DocumentViewerComponent,
ViewerAnchorDirective,
RotationComponent
],
entryComponents: [
AnnotationPdfViewerComponent,
ImageViewerComponent,
UnsupportedViewerComponent,
RotationComponent
],
providers: [
PdfAnnotateWrapper,
PdfWrapper,
PdfService,
AnnotationStoreService,
PdfAdapter,
NpaService,
ApiHttpService,
Utils,
UrlFixerService,
ViewerFactoryService,
DocumentViewerService,
RotationFactoryService,
PdfRenderService,
EmLoggerService
],
exports: [
DocumentViewerComponent
]
},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { HmctsEmViewerUiModule, AnnotationStoreService as ɵb, ApiHttpService as ɵf, PdfAnnotateWrapper as ɵh, PdfWrapper as ɵj, NpaService as ɵn, PdfAdapter as ɵd, PdfRenderService as ɵi, PdfService as ɵg, UrlFixerService as ɵu, Utils as ɵe, DocumentViewerComponent as ɵr, DocumentViewerService as ɵv, ViewerAnchorDirective as ɵs, EmLoggerService as ɵc, AnnotationPdfViewerComponent as ɵm, CommentItemComponent as ɵk, CommentsComponent as ɵa, ContextualToolbarComponent as ɵl, RotationFactoryService as ɵo, RotationComponent as ɵw, ImageViewerComponent as ɵp, UnsupportedViewerComponent as ɵq, ViewerFactoryService as ɵt };
//# sourceMappingURL=hmcts-annotation-ui-lib.js.map