@hmcts/media-viewer 2.9.3 → 2.9.4-RC.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/assets/images/icon-bookmarks-custom.png +0 -0
  2. package/assets/images/icon-bookmarks-position.png +0 -0
  3. package/assets/images/toolbarButton-bookmarkDark.png +0 -0
  4. package/assets/sass/comment-set-panel.scss +1 -0
  5. package/assets/sass/comment.scss +4 -6
  6. package/assets/sass/image-viewer.scss +2 -1
  7. package/assets/sass/pdf-viewer.scss +4 -0
  8. package/assets/sass/toolbar/buttons.scss +24 -0
  9. package/assets/sass/toolbar/main-toolbar.scss +20 -7
  10. package/assets/sass/toolbar/side-bar.scss +17 -17
  11. package/bundles/hmcts-media-viewer.umd.js +744 -324
  12. package/bundles/hmcts-media-viewer.umd.js.map +1 -1
  13. package/bundles/hmcts-media-viewer.umd.min.js +1 -1
  14. package/bundles/hmcts-media-viewer.umd.min.js.map +1 -1
  15. package/esm2015/hmcts-media-viewer.js +53 -52
  16. package/esm2015/lib/annotations/annotation-set/annotation-create/box-highlight-create/box-highlight-create.component.js +2 -2
  17. package/esm2015/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.directive.js +2 -2
  18. package/esm2015/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.service.js +2 -2
  19. package/esm2015/lib/annotations/annotation-set/annotation-view/annotation-view.component.js +1 -1
  20. package/esm2015/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.js +3 -2
  21. package/esm2015/lib/annotations/annotations.module.js +3 -1
  22. package/esm2015/lib/annotations/comment-set/comment/comment.component.js +3 -2
  23. package/esm2015/lib/annotations/comment-set/comment/comment.service.js +6 -2
  24. package/esm2015/lib/annotations/comment-set/comment-set-header/comment-set-header.component.js +13 -2
  25. package/esm2015/lib/media-viewer.component.js +4 -2
  26. package/esm2015/lib/print.service.js +4 -2
  27. package/esm2015/lib/redaction/components/redaction.component.js +2 -2
  28. package/esm2015/lib/redaction/services/redaction-api.service.js +7 -1
  29. package/esm2015/lib/redaction/services/redaction.model.js +1 -1
  30. package/esm2015/lib/store/actions/redaction.actions.js +22 -1
  31. package/esm2015/lib/store/effects/redaction.effects.js +18 -4
  32. package/esm2015/lib/store/reducers/bookmarks.reducer.js +3 -2
  33. package/esm2015/lib/store/reducers/redaction.reducer.js +9 -1
  34. package/esm2015/lib/store/selectors/bookmark.selectors.js +2 -2
  35. package/esm2015/lib/toolbar/main-toolbar/main-toolbar.component.js +19 -4
  36. package/esm2015/lib/toolbar/redaction-search-bar/redaction-search-bar.component.js +201 -0
  37. package/esm2015/lib/toolbar/redaction-search-bar/redaction-search.model.js +2 -0
  38. package/esm2015/lib/toolbar/redaction-toolbar/redaction-toolbar.component.js +18 -6
  39. package/esm2015/lib/toolbar/toolbar-event.service.js +9 -1
  40. package/esm2015/lib/toolbar/toolbar.module.js +6 -3
  41. package/esm2015/lib/viewers/image-viewer/image-viewer.component.js +2 -2
  42. package/esm2015/lib/viewers/pdf-viewer/pdf-js/pdf-js-wrapper.js +15 -4
  43. package/esm2015/lib/viewers/pdf-viewer/pdf-viewer.component.js +3 -2
  44. package/esm2015/lib/viewers/pdf-viewer/side-bar/bookmarks/bookmarks.component.js +70 -5
  45. package/esm2015/lib/viewers/pdf-viewer/side-bar/outline-item/outline-item.component.js +4 -1
  46. package/esm2015/lib/viewers/pdf-viewer/side-bar/side-bar.component.js +24 -19
  47. package/fesm2015/hmcts-media-viewer.js +586 -204
  48. package/fesm2015/hmcts-media-viewer.js.map +1 -1
  49. package/hmcts-media-viewer.d.ts +56 -55
  50. package/hmcts-media-viewer.d.ts.map +1 -1
  51. package/hmcts-media-viewer.metadata.json +1 -1
  52. package/lib/annotations/annotation-set/annotation-create/box-highlight-create/box-highlight-create.component.d.ts.map +1 -1
  53. package/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.service.d.ts.map +1 -1
  54. package/lib/annotations/annotation-set/annotation-view/annotation-view.component.d.ts.map +1 -1
  55. package/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.d.ts.map +1 -1
  56. package/lib/annotations/annotations.module.d.ts.map +1 -1
  57. package/lib/annotations/comment-set/comment/comment.component.d.ts +2 -0
  58. package/lib/annotations/comment-set/comment/comment.component.d.ts.map +1 -1
  59. package/lib/annotations/comment-set/comment/comment.service.d.ts +3 -1
  60. package/lib/annotations/comment-set/comment/comment.service.d.ts.map +1 -1
  61. package/lib/annotations/comment-set/comment-set-header/comment-set-header.component.d.ts +4 -1
  62. package/lib/annotations/comment-set/comment-set-header/comment-set-header.component.d.ts.map +1 -1
  63. package/lib/media-viewer.component.d.ts +1 -0
  64. package/lib/media-viewer.component.d.ts.map +1 -1
  65. package/lib/media-viewer.module.ngfactory.d.ts.map +1 -1
  66. package/lib/print.service.d.ts.map +1 -1
  67. package/lib/redaction/components/redaction.component.d.ts.map +1 -1
  68. package/lib/redaction/services/redaction-api.service.d.ts +3 -1
  69. package/lib/redaction/services/redaction-api.service.d.ts.map +1 -1
  70. package/lib/redaction/services/redaction.model.d.ts +3 -0
  71. package/lib/redaction/services/redaction.model.d.ts.map +1 -1
  72. package/lib/store/actions/redaction.actions.d.ts +20 -2
  73. package/lib/store/actions/redaction.actions.d.ts.map +1 -1
  74. package/lib/store/effects/redaction.effects.d.ts +4 -1
  75. package/lib/store/effects/redaction.effects.d.ts.map +1 -1
  76. package/lib/store/reducers/bookmarks.reducer.d.ts.map +1 -1
  77. package/lib/store/reducers/redaction.reducer.d.ts.map +1 -1
  78. package/lib/store/selectors/annotation.selectors.d.ts +5 -5
  79. package/lib/store/selectors/redaction.selectors.d.ts +1 -1
  80. package/lib/store/selectors/tag.selectors.d.ts +2 -2
  81. package/lib/toolbar/main-toolbar/main-toolbar.component.d.ts +3 -1
  82. package/lib/toolbar/main-toolbar/main-toolbar.component.d.ts.map +1 -1
  83. package/lib/toolbar/redaction-search-bar/redaction-search-bar.component.d.ts +51 -0
  84. package/lib/toolbar/redaction-search-bar/redaction-search-bar.component.d.ts.map +1 -0
  85. package/lib/toolbar/redaction-search-bar/redaction-search-bar.component.ngfactory.d.ts.map +1 -0
  86. package/lib/toolbar/redaction-search-bar/redaction-search-bar.component.scss.shim.ngstyle.d.ts.map +1 -0
  87. package/lib/toolbar/redaction-search-bar/redaction-search.model.d.ts +12 -0
  88. package/lib/toolbar/redaction-search-bar/redaction-search.model.d.ts.map +1 -0
  89. package/lib/toolbar/redaction-toolbar/redaction-toolbar.component.d.ts +4 -2
  90. package/lib/toolbar/redaction-toolbar/redaction-toolbar.component.d.ts.map +1 -1
  91. package/lib/toolbar/toolbar-event.service.d.ts +6 -0
  92. package/lib/toolbar/toolbar-event.service.d.ts.map +1 -1
  93. package/lib/toolbar/toolbar.module.d.ts.map +1 -1
  94. package/lib/toolbar/toolbar.module.ngfactory.d.ts.map +1 -1
  95. package/lib/viewers/pdf-viewer/pdf-js/pdf-js-wrapper.d.ts +1 -0
  96. package/lib/viewers/pdf-viewer/pdf-js/pdf-js-wrapper.d.ts.map +1 -1
  97. package/lib/viewers/pdf-viewer/pdf-viewer.component.d.ts +1 -0
  98. package/lib/viewers/pdf-viewer/pdf-viewer.component.d.ts.map +1 -1
  99. package/lib/viewers/pdf-viewer/side-bar/bookmarks/bookmarks.component.d.ts +17 -4
  100. package/lib/viewers/pdf-viewer/side-bar/bookmarks/bookmarks.component.d.ts.map +1 -1
  101. package/lib/viewers/pdf-viewer/side-bar/outline-item/outline-item.component.d.ts.map +1 -1
  102. package/lib/viewers/pdf-viewer/side-bar/side-bar.component.d.ts +7 -4
  103. package/lib/viewers/pdf-viewer/side-bar/side-bar.component.d.ts.map +1 -1
  104. package/package.json +5 -4
  105. package/hmcts-media-viewer-v2.9.3.tgz +0 -0
@@ -14,15 +14,15 @@ import 'pdfjs-dist/build/pdf.worker';
14
14
  import uuid from 'uuid/v4';
15
15
  import moment from 'moment-timezone';
16
16
  import 'hammerjs';
17
+ import uuid$1, { v4 } from 'uuid';
17
18
  import { ConnectionPositionPair, OverlayModule } from '@angular/cdk/overlay';
18
19
  import { RouterModule } from '@angular/router';
19
20
  import { A11yModule } from '@angular/cdk/a11y';
20
21
  import { MutableDivModule } from 'mutable-div';
21
22
  import { TagInputModule } from 'ngx-chips';
22
23
  import { NgxDatatableModule } from '@swimlane/ngx-datatable';
23
- import uuid$1, { v4 } from 'uuid';
24
+ import { TreeComponent, TreeModule } from '@circlon/angular-tree-component';
24
25
  import { ofType, Actions, Effect, EffectsModule } from '@ngrx/effects';
25
- import { TreeModule } from '@circlon/angular-tree-component';
26
26
 
27
27
  pdfjsLib.GlobalWorkerOptions.workerSrc = '/assets/build/pdf.worker.min.js';
28
28
  /**
@@ -55,15 +55,26 @@ class PdfJsWrapper {
55
55
  this.pdfViewer.eventBus.on('scalechanging', (e) => this.emitDocumentInfo(e));
56
56
  this.pdfViewer.eventBus.on('rotationchanging', (e) => this.emitDocumentInfo(e));
57
57
  this.pdfViewer.eventBus.on('updatefindcontrolstate', event => {
58
- if (event.state !== FindState.PENDING) {
59
- this.toolbarEvents.searchResultsCountSubject.next(event.matchesCount);
60
- }
58
+ this.sendSearchDetails(event);
61
59
  });
62
60
  this.pdfViewer.eventBus.on('updatefindmatchescount', event => {
63
61
  this.toolbarEvents.searchResultsCountSubject.next(event.matchesCount);
64
62
  });
65
63
  this.zoomValue = 1;
66
64
  }
65
+ sendSearchDetails(event) {
66
+ var _a, _b, _c, _d, _e, _f;
67
+ if (event.state !== FindState.PENDING) {
68
+ this.toolbarEvents.searchResultsCountSubject.next(event.matchesCount);
69
+ if (((_b = (_a = event === null || event === void 0 ? void 0 : event.source) === null || _a === void 0 ? void 0 : _a.selected) === null || _b === void 0 ? void 0 : _b.pageIdx) !== -1 && event.matchesCount.total > 0) {
70
+ this.toolbarEvents.redactionSerachSubject.next({
71
+ page: (_d = (_c = event === null || event === void 0 ? void 0 : event.source) === null || _c === void 0 ? void 0 : _c.selected) === null || _d === void 0 ? void 0 : _d.pageIdx,
72
+ matchedIndex: (_f = (_e = event === null || event === void 0 ? void 0 : event.source) === null || _e === void 0 ? void 0 : _e.selected) === null || _f === void 0 ? void 0 : _f.matchIdx,
73
+ matchesCount: event.matchesCount.total
74
+ });
75
+ }
76
+ }
77
+ }
67
78
  emitDocumentInfo(e) {
68
79
  const allPages = [...this.pdfViewer._pages].map(page => {
69
80
  return {
@@ -283,7 +294,11 @@ class ToolbarEventService {
283
294
  this.applyRedactToDocument = new Subject();
284
295
  this.clearAllRedactMarkers = new Subject();
285
296
  this.redactWholePage = new Subject();
297
+ this.redactionSerachSubject = new Subject();
298
+ this.redactAllInProgressSubject = new BehaviorSubject(false);
299
+ this.openRedactionSearch = new Subject();
286
300
  this.sidebarOpen = new BehaviorSubject(false);
301
+ this.sidebarOutlineView = new BehaviorSubject(true);
287
302
  this.searchBarHidden = new BehaviorSubject(true);
288
303
  this.commentsPanelVisible = new BehaviorSubject(false);
289
304
  this.icp = icpEvents;
@@ -373,6 +388,9 @@ class ToolbarEventService {
373
388
  toggleSideBar(toggle) {
374
389
  this.sidebarOpen.next(toggle);
375
390
  }
391
+ toggleSideBarView(toggle) {
392
+ this.sidebarOutlineView.next(toggle);
393
+ }
376
394
  toggleRedactionMode() {
377
395
  if (this.redactionMode.getValue() === false) {
378
396
  this.drawModeSubject.next(false);
@@ -382,6 +400,7 @@ class ToolbarEventService {
382
400
  else {
383
401
  this.redactionMode.next(false);
384
402
  }
403
+ this.openRedactionSearch.next(false);
385
404
  }
386
405
  toggleRedactionPreview(viewMode) {
387
406
  this.redactionPreview.next(viewMode);
@@ -456,7 +475,9 @@ class PrintService {
456
475
  }
457
476
  printElementNatively(element, width, height) {
458
477
  const printWindow = window.open('', '', `left=0,top=0,width=${width},height=${height},toolbar=0,scrollbars=0,status=0`);
459
- printWindow.document.write(element.innerHTML);
478
+ const documentHead = document.head;
479
+ printWindow.document.body.appendChild(documentHead.cloneNode(true));
480
+ printWindow.document.body.appendChild(element.cloneNode(true));
460
481
  printWindow.document.close();
461
482
  printWindow.focus();
462
483
  printWindow.print();
@@ -1426,7 +1447,8 @@ function bookmarksReducer(state = initialBookmarksState, action) {
1426
1447
  delete bookmarkEntities[bookmarkId];
1427
1448
  });
1428
1449
  Object.entries(removeBookmarksByPage).forEach(([pageNumber, bmrkIds]) => {
1429
- bookmarkPageEntities[pageNumber] = bookmarkPageEntities[pageNumber].filter(bookmarkId => bmrkIds.includes(bookmarkId));
1450
+ bookmarkPageEntities[pageNumber]
1451
+ = bookmarkPageEntities[pageNumber].filter(bookmark => !bmrkIds.includes(bookmark.id));
1430
1452
  });
1431
1453
  return Object.assign(Object.assign({}, state), { bookmarkEntities,
1432
1454
  bookmarkPageEntities, loading: false, loaded: true });
@@ -1455,6 +1477,9 @@ const LOAD_REDACTION_FAIL = '[Redaction] Load Redaction Fail';
1455
1477
  const SAVE_REDACTION = '[Redaction] Save Redaction';
1456
1478
  const SAVE_REDACTION_SUCCESS = '[Redaction] Save Redaction Success';
1457
1479
  const SAVE_REDACTION_FAIL = '[Redaction] Save Redaction Fail';
1480
+ const SAVE_BULK_REDACTION = '[Redaction] Save bulk Redaction';
1481
+ const SAVE_BULK_REDACTION_SUCCESS = '[Redaction] Save bulk Redaction Success';
1482
+ const SAVE_BULK_REDACTION_FAIL = '[Redaction] Save bulk Redaction Fail';
1458
1483
  const DELETE_REDACTION = '[Redaction] Delete Redaction';
1459
1484
  const DELETE_REDACTION_SUCCESS = '[Redaction] Delete Redaction Success';
1460
1485
  const DELETE_REDACTION_FAIL = '[Redaction] Delete Redaction Fail';
@@ -1501,6 +1526,24 @@ class SaveRedactionFailure {
1501
1526
  this.type = SAVE_REDACTION_FAIL;
1502
1527
  }
1503
1528
  }
1529
+ class SaveBulkRedactionFailure {
1530
+ constructor(payload) {
1531
+ this.payload = payload;
1532
+ this.type = SAVE_BULK_REDACTION_FAIL;
1533
+ }
1534
+ }
1535
+ class SaveBulkRedaction {
1536
+ constructor(payload) {
1537
+ this.payload = payload;
1538
+ this.type = SAVE_BULK_REDACTION;
1539
+ }
1540
+ }
1541
+ class SaveBulkRedactionSuccess {
1542
+ constructor(payload) {
1543
+ this.payload = payload;
1544
+ this.type = SAVE_BULK_REDACTION_SUCCESS;
1545
+ }
1546
+ }
1504
1547
  class DeleteRedaction {
1505
1548
  constructor(payload) {
1506
1549
  this.payload = payload;
@@ -1590,6 +1633,14 @@ function redactionReducer(state = initialRedactionState, action) {
1590
1633
  return Object.assign(Object.assign({}, state), { redactionEntities,
1591
1634
  redactionPageEntities });
1592
1635
  }
1636
+ case SAVE_BULK_REDACTION_SUCCESS: {
1637
+ const payloadResult = Object.assign({}, ...action.payload.searchRedactions.map((x) => ({ [x.redactionId]: x })));
1638
+ const redactionEntities = Object.assign(Object.assign({}, state.redactionEntities), payloadResult);
1639
+ const redactionArray = Object.keys(redactionEntities).map(key => redactionEntities[key]);
1640
+ const redactionPageEntities = StoreUtils.groupByKeyEntities(redactionArray, 'page');
1641
+ return Object.assign(Object.assign({}, state), { redactionEntities,
1642
+ redactionPageEntities });
1643
+ }
1593
1644
  case SELECT_REDACTION:
1594
1645
  case SELECT_ANNOTATION: {
1595
1646
  return Object.assign(Object.assign({}, state), { selectedRedaction: action.payload });
@@ -2272,7 +2323,7 @@ class PdfViewerComponent {
2272
2323
  PdfViewerComponent.decorators = [
2273
2324
  { type: Component, args: [{
2274
2325
  selector: 'mv-pdf-viewer',
2275
- template: "<mv-side-bar *ngIf=\"toolbarEvents.sidebarOpen\"\n id=\"sidebarContainer\"\n [url]=\"url\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [outline]=\"documentOutline\"\n [annotationsEnabled]=\"enableAnnotations\"\n [currentPageNumber]=\"getCurrentPageNumber()\">\n</mv-side-bar>\n<mv-comment-set-header\n *ngIf=\"enableAnnotations\"\n [ngClass]=\"{'show-comments-panel': showCommentsPanel}\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\">\n</mv-comment-set-header>\n<mv-participants-list></mv-participants-list>\n<div\n class=\"pdfContainer\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ 'pdfContainer': true, hidden: errorMessage }\">\n <div\n #viewerContainer\n mvGrabNDrag\n [dragX]=\"viewerContainer\"\n [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewerContainer\"\n class=\"viewer-container\"\n [class.annotations]=\"enableAnnotations\"\n [class.show-comments-panel]=\"(showCommentsPanel || showIcpParticipantsList) && !(toolbarEvents.redactionMode | async)\"\n [class.grabNDrag]=\"enableGrabNDrag\">\n <div #pdfViewer\n class=\"pdfViewer\"\n mvCreateTextHighlight\n [ngClass]=\"{ hidden: loadingDocument, highlightMode: highlightMode | async, drawMode: drawMode | async }\">\n </div>\n <mv-redactions *ngIf=\"(toolbarEvents.redactionMode | async); else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer\n *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\">\n </mv-metadata-layer>\n <mv-bookmark-icons [zoom]=\"zoom\"\n [rotate]=\"rotation\">\n </mv-bookmark-icons>\n </ng-template>\n </div>\n <mv-comment-set [contentScrollTop]=\"viewerContainer.scrollTop\"\n *ngIf=\"enableAnnotations && annotationSet && !(toolbarEvents.redactionMode | async)\"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"pdfViewer.offsetHeight\"\n [pageHeights]=\"pageHeights\">\n </mv-comment-set>\n <div class=\"loadingMessage\" *ngIf=\"loadingDocument\">\n <h3 class=\"govuk-heading-m\">Loading...{{ loadingDocumentProgress ? loadingDocumentProgress + '%' : '' }}</h3>\n </div>\n</div>\n",
2326
+ template: "<mv-side-bar\n *ngIf=\"toolbarEvents.sidebarOpen\"\n id=\"sidebarContainer\"\n [url]=\"url\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [outline]=\"documentOutline\"\n [annotationsEnabled]=\"enableAnnotations\"\n [currentPageNumber]=\"getCurrentPageNumber()\"\n>\n</mv-side-bar>\n<mv-comment-set-header\n *ngIf=\"enableAnnotations\"\n [ngClass]=\"{ 'show-comments-panel': showCommentsPanel }\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\"\n>\n</mv-comment-set-header>\n<mv-participants-list></mv-participants-list>\n<div\n class=\"pdfContainer\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ pdfContainer: true, hidden: errorMessage }\"\n>\n <mv-redaction-search-bar></mv-redaction-search-bar>\n <div\n #viewerContainer\n mvGrabNDrag\n [dragX]=\"viewerContainer\"\n [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewerContainer\"\n class=\"viewer-container\"\n [class.annotations]=\"enableAnnotations\"\n [class.show-comments-panel]=\"\n (showCommentsPanel || showIcpParticipantsList) &&\n !(toolbarEvents.redactionMode | async)\n \"\n [class.grabNDrag]=\"enableGrabNDrag\"\n >\n <div\n #pdfViewer\n class=\"pdfViewer\"\n mvCreateTextHighlight\n [ngClass]=\"{\n hidden: loadingDocument,\n highlightMode: highlightMode | async,\n drawMode: drawMode | async\n }\"\n ></div>\n <mv-redactions\n *ngIf=\"toolbarEvents.redactionMode | async; else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer\n *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n >\n </mv-metadata-layer>\n <mv-bookmark-icons [zoom]=\"zoom\" [rotate]=\"rotation\"> </mv-bookmark-icons>\n </ng-template>\n </div>\n <mv-comment-set\n [contentScrollTop]=\"viewerContainer.scrollTop\"\n *ngIf=\"\n enableAnnotations &&\n annotationSet &&\n !(toolbarEvents.redactionMode | async)\n \"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"pdfViewer.offsetHeight\"\n [pageHeights]=\"pageHeights\"\n >\n </mv-comment-set>\n <div class=\"loadingMessage\" *ngIf=\"loadingDocument\">\n <h3 class=\"govuk-heading-m\">\n Loading...{{\n loadingDocumentProgress ? loadingDocumentProgress + \"%\" : \"\"\n }}\n </h3>\n </div>\n</div>\n",
2276
2327
  encapsulation: ViewEncapsulation.None
2277
2328
  },] }
2278
2329
  ];
@@ -2298,6 +2349,7 @@ PdfViewerComponent.propDecorators = {
2298
2349
  enableRedactions: [{ type: Input }],
2299
2350
  enableICP: [{ type: Input }],
2300
2351
  annotationSet: [{ type: Input }],
2352
+ enableRedactSearch: [{ type: Input }],
2301
2353
  height: [{ type: Input }],
2302
2354
  caseId: [{ type: Input }],
2303
2355
  viewerContainer: [{ type: ViewChild, args: ['viewerContainer', { static: true },] }],
@@ -2453,7 +2505,7 @@ class ImageViewerComponent {
2453
2505
  ImageViewerComponent.decorators = [
2454
2506
  { type: Component, args: [{
2455
2507
  selector: 'mv-image-viewer',
2456
- template: "<mv-comment-set-header [ngClass]=\"{'show-comments-panel': showCommentsPanel}\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\">\n</mv-comment-set-header>\n<div mvGrabNDrag [dragX]=\"imageContainer\" [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewer-wrapper\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ 'grabNDrag': enableGrabNDrag }\"\n *ngIf=\"url && !errorMessage\">\n <div #imageContainer id=\"image-container\"\n [ngClass]=\"{ 'image-container': true, 'annotations': enableAnnotations, 'show-comments-panel': showCommentsPanel }\"\n [style.height.px]=\"imageHeight\">\n <img #img\n [src]=\"url\"\n [ngClass]=\"'rot' + rotation\"\n (error)=\"onLoadError(url)\"\n (load)=\"onLoad(img)\"/>\n <mv-redactions *ngIf=\"(toolbarEvents.redactionMode | async);else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\">\n </mv-metadata-layer>\n </ng-template>\n </div>\n\n <div class=\"comments\" [style.height.px]=\"imageHeight\">\n <mv-comment-set *ngIf=\"enableAnnotations && annotationSet && !(toolbarEvents.redactionMode | async)\"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"imageHeight\">\n </mv-comment-set>\n </div>\n</div>\n"
2508
+ template: "<mv-comment-set-header [ngClass]=\"{'show-comments-panel': showCommentsPanel}\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\">\n</mv-comment-set-header>\n<div id=\"viewer-wrapper\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ 'grabNDrag': enableGrabNDrag }\"\n *ngIf=\"url && !errorMessage\">\n <div #imageContainer id=\"image-container\"\n mvGrabNDrag [dragX]=\"imageContainer\" [dragEnabled]=\"enableGrabNDrag\"\n (scroll)=\"$event\"\n [ngClass]=\"{ 'image-container': true, 'annotations': enableAnnotations, 'show-comments-panel': showCommentsPanel }\">\n <img #img\n [src]=\"url\"\n [ngClass]=\"'rot' + rotation\"\n (error)=\"onLoadError(url)\"\n (load)=\"onLoad(img)\"/>\n <mv-redactions *ngIf=\"(toolbarEvents.redactionMode | async);else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\">\n </mv-metadata-layer>\n </ng-template>\n </div>\n\n <mv-comment-set [contentScrollTop]=\"imageContainer.scrollTop\"\n *ngIf=\"enableAnnotations && annotationSet && !(toolbarEvents.redactionMode | async)\"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"imageHeight\">\n </mv-comment-set>\n</div>\n"
2457
2509
  },] }
2458
2510
  ];
2459
2511
  /** @nocollapse */
@@ -2580,6 +2632,7 @@ AnnotationApiService.ctorParameters = () => [
2580
2632
  class CommentService {
2581
2633
  constructor() {
2582
2634
  this.unsavedChanges = new Subject();
2635
+ this.marginToCommentEmitter = new BehaviorSubject(false);
2583
2636
  }
2584
2637
  setCommentSet(commentSetComponent) {
2585
2638
  this.commentSetComponent = commentSetComponent;
@@ -2612,6 +2665,9 @@ class CommentService {
2612
2665
  allCommentsSaved() {
2613
2666
  this.onCommentChange(this.commentSetComponent.commentComponents.some(comment => comment.hasUnsavedChanges === true));
2614
2667
  }
2668
+ createMarginToCommentEvent(margin) {
2669
+ this.marginToCommentEmitter.next(margin);
2670
+ }
2615
2671
  }
2616
2672
  CommentService.decorators = [
2617
2673
  { type: Injectable }
@@ -2745,6 +2801,7 @@ class MediaViewerComponent {
2745
2801
  this.enableRedactions = false;
2746
2802
  this.enableICP = false;
2747
2803
  this.multimediaPlayerEnabled = false;
2804
+ this.enableRedactSearch = false;
2748
2805
  this.multimediaContent = false;
2749
2806
  this.convertibleContent = false;
2750
2807
  this.unsupportedContent = false;
@@ -2868,7 +2925,7 @@ class MediaViewerComponent {
2868
2925
  MediaViewerComponent.decorators = [
2869
2926
  { type: Component, args: [{
2870
2927
  selector: 'mv-media-viewer',
2871
- template: "<div id=\"outerContainer\"\n [ngClass]=\"{\n 'has-redact-bar': toolbarEvents.redactionMode | async,\n 'icp-mode': toolbarEvents.icp.enabled | async,\n 'is-redaction-preview': toolbarEvents.redactionPreview | async,\n sidebarOpen: toolbarEvents.sidebarOpen | async,\n 'has-scroll-bar': hasScrollBar,\n 'has-different-page-size': hasDifferentPageSize$ | async\n }\"\n [ngStyle]=\"{ width: width }\">\n\n <mv-comments-summary *ngIf=\"showCommentSummary\"\n [title]=\"documentTitle || 'Comment Summary'\"\n [contentType]=\"contentType\">\n </mv-comments-summary>\n\n <mv-confirm-action *ngIf=\"toolbarEvents.icp.leavingSession | async\"></mv-confirm-action>\n\n <div id=\"mainContainer\">\n <mv-main-toolbar *ngIf=\"showToolbar\"\n [enableAnnotations]=\"enableAnnotations\"\n [enableICP]=\"enableICP\"\n [enableRedactions]=\"enableRedactions\"\n [contentType]=\"contentType\"\n >\n </mv-main-toolbar>\n <mv-redaction-toolbar *ngIf=\"toolbarEvents.redactionMode | async\"></mv-redaction-toolbar>\n <mv-icp-toolbar *ngIf=\"toolbarEvents.icp.enabled | async\"></mv-icp-toolbar>\n\n <div #viewerRef>\n <mv-conversion-viewer *ngIf=\"convertibleContent\"\n (documentTitle)=\"onDocumentTitleChange($event)\"\n (mediaLoadStatus)=\"onMediaLoad($event)\"\n (viewerException)=\"onLoadException($event)\"\n [enableAnnotations]=\"enableAnnotations\"\n [enableRedactions]=\"enableRedactions\"\n [annotationSet]=\"enableAnnotations ? (annotationSet$ | async) : null\"\n [originalUrl]=\"url\"\n [downloadFileName]=\"downloadFileName\"\n [height]=\"viewerHeight\"\n mvRotationPersist>\n </mv-conversion-viewer>\n <mv-pdf-viewer *ngIf=\"contentType === 'pdf'\"\n #pdfViewer\n (mediaLoadStatus)=\"onMediaLoad($event)\"\n (pdfViewerException)=\"onLoadException($event)\"\n (documentTitle)=\"onDocumentTitleChange($event)\"\n [url]=\"url\"\n [enableAnnotations]=\"enableAnnotations\"\n [enableRedactions]=\"enableRedactions\"\n [enableICP]=\"enableICP\"\n [annotationSet]=\"enableAnnotations ? (annotationSet$ | async) : null\"\n [downloadFileName]=\"downloadFileName\"\n [height]=\"viewerHeight\"\n [caseId]=\"caseId\"\n mvRotationPersist>\n </mv-pdf-viewer>\n <mv-image-viewer *ngIf=\"contentType === 'image'\"\n (mediaLoadStatus)=\"onMediaLoad($event)\"\n (imageViewerException)=\"onLoadException($event)\"\n [url]=\"url\"\n [enableAnnotations]=\"enableAnnotations\"\n [annotationSet]=\"enableAnnotations ? (annotationSet$ | async) : null\"\n [downloadFileName]=\"downloadFileName\"\n [height]=\"viewerHeight\"\n mvRotationPersist>\n </mv-image-viewer>\n <mv-multimedia-player *ngIf=\"multimediaContent\"\n [multimediaOn]=\"multimediaPlayerEnabled\"\n [url]=\"url\"\n [downloadFileName]=\"downloadFileName\"\n (loadStatus)=\"onMediaLoad($event)\">\n </mv-multimedia-player>\n <mv-unsupported-viewer *ngIf=\"unsupportedContent\"\n [url]=\"url\"\n [typeException]=\"typeException\"\n [downloadFileName]=\"downloadFileName\"\n (loadStatus)=\"onMediaLoad($event)\"\n (unsupportedViewerException)=\"onLoadException($event)\">\n </mv-unsupported-viewer>\n </div>\n </div>\n</div>\n",
2928
+ template: "<div\n id=\"outerContainer\"\n [ngClass]=\"{\n 'has-redact-bar': toolbarEvents.redactionMode | async,\n 'icp-mode': toolbarEvents.icp.enabled | async,\n 'is-redaction-preview': toolbarEvents.redactionPreview | async,\n sidebarOpen: toolbarEvents.sidebarOpen | async,\n 'has-scroll-bar': hasScrollBar,\n 'has-different-page-size': hasDifferentPageSize$ | async\n }\"\n [ngStyle]=\"{ width: width }\"\n>\n <mv-comments-summary\n *ngIf=\"showCommentSummary\"\n [title]=\"documentTitle || 'Comment Summary'\"\n [contentType]=\"contentType\"\n >\n </mv-comments-summary>\n\n <mv-confirm-action\n *ngIf=\"toolbarEvents.icp.leavingSession | async\"\n ></mv-confirm-action>\n\n <div id=\"mainContainer\">\n <mv-main-toolbar\n *ngIf=\"showToolbar\"\n [enableAnnotations]=\"enableAnnotations\"\n [enableICP]=\"enableICP\"\n [enableRedactions]=\"enableRedactions\"\n [contentType]=\"contentType\"\n >\n </mv-main-toolbar>\n <mv-redaction-toolbar\n [showRedactSearch]=\"enableRedactSearch\"\n *ngIf=\"toolbarEvents.redactionMode | async\"\n ></mv-redaction-toolbar>\n <mv-icp-toolbar *ngIf=\"toolbarEvents.icp.enabled | async\"></mv-icp-toolbar>\n\n <div #viewerRef>\n <mv-conversion-viewer\n *ngIf=\"convertibleContent\"\n (documentTitle)=\"onDocumentTitleChange($event)\"\n (mediaLoadStatus)=\"onMediaLoad($event)\"\n (viewerException)=\"onLoadException($event)\"\n [enableAnnotations]=\"enableAnnotations\"\n [enableRedactions]=\"enableRedactions\"\n [annotationSet]=\"enableAnnotations ? (annotationSet$ | async) : null\"\n [originalUrl]=\"url\"\n [downloadFileName]=\"downloadFileName\"\n [height]=\"viewerHeight\"\n mvRotationPersist\n >\n </mv-conversion-viewer>\n <mv-pdf-viewer\n *ngIf=\"contentType === 'pdf'\"\n #pdfViewer\n (mediaLoadStatus)=\"onMediaLoad($event)\"\n (pdfViewerException)=\"onLoadException($event)\"\n (documentTitle)=\"onDocumentTitleChange($event)\"\n [url]=\"url\"\n [enableAnnotations]=\"enableAnnotations\"\n [enableRedactions]=\"enableRedactions\"\n [enableICP]=\"enableICP\"\n [annotationSet]=\"enableAnnotations ? (annotationSet$ | async) : null\"\n [downloadFileName]=\"downloadFileName\"\n [height]=\"viewerHeight\"\n [caseId]=\"caseId\"\n mvRotationPersist\n >\n </mv-pdf-viewer>\n <mv-image-viewer\n *ngIf=\"contentType === 'image'\"\n (mediaLoadStatus)=\"onMediaLoad($event)\"\n (imageViewerException)=\"onLoadException($event)\"\n [url]=\"url\"\n [enableAnnotations]=\"enableAnnotations\"\n [annotationSet]=\"enableAnnotations ? (annotationSet$ | async) : null\"\n [downloadFileName]=\"downloadFileName\"\n [height]=\"viewerHeight\"\n mvRotationPersist\n >\n </mv-image-viewer>\n <mv-multimedia-player\n *ngIf=\"multimediaContent\"\n [multimediaOn]=\"multimediaPlayerEnabled\"\n [url]=\"url\"\n [downloadFileName]=\"downloadFileName\"\n (loadStatus)=\"onMediaLoad($event)\"\n >\n </mv-multimedia-player>\n <mv-unsupported-viewer\n *ngIf=\"unsupportedContent\"\n [url]=\"url\"\n [typeException]=\"typeException\"\n [downloadFileName]=\"downloadFileName\"\n (loadStatus)=\"onMediaLoad($event)\"\n (unsupportedViewerException)=\"onLoadException($event)\"\n >\n </mv-unsupported-viewer>\n </div>\n </div>\n</div>\n",
2872
2929
  encapsulation: ViewEncapsulation.None
2873
2930
  },] }
2874
2931
  ];
@@ -2900,9 +2957,256 @@ MediaViewerComponent.propDecorators = {
2900
2957
  enableRedactions: [{ type: Input }],
2901
2958
  enableICP: [{ type: Input }],
2902
2959
  multimediaPlayerEnabled: [{ type: Input }],
2960
+ enableRedactSearch: [{ type: Input }],
2903
2961
  caseId: [{ type: Input }]
2904
2962
  };
2905
2963
 
2964
+ class HighlightCreateService {
2965
+ constructor(toolBarEvents, store) {
2966
+ this.toolBarEvents = toolBarEvents;
2967
+ this.store = store;
2968
+ }
2969
+ saveAnnotation(rectangles, page) {
2970
+ this.store.pipe(select(getDocumentIdSetId), take(1)).subscribe(anoSetDocId => {
2971
+ const anno = Object.assign(Object.assign({ id: v4(), color: 'FFFF00', comments: [], page: page, rectangles: rectangles, type: 'highlight' }, anoSetDocId), { createdBy: '', createdByDetails: undefined, createdDate: moment.utc().tz('Europe/London').toISOString(), lastModifiedBy: '', lastModifiedByDetails: undefined, lastModifiedDate: '', tags: [] });
2972
+ this.store.dispatch(new SaveAnnotation(anno));
2973
+ });
2974
+ }
2975
+ applyRotation(pageHeight, pageWidth, offsetHeight, offsetWidth, offsetTop, offsetLeft, rotate, zoom) {
2976
+ const { x, y, width, height } = {
2977
+ x: +(offsetLeft / zoom).toFixed(2),
2978
+ y: +(offsetTop / zoom).toFixed(2),
2979
+ width: +(offsetWidth / zoom).toFixed(2),
2980
+ height: +(offsetHeight / zoom).toFixed(2)
2981
+ };
2982
+ const rectangle = { x, y, width, height };
2983
+ switch (rotate) {
2984
+ case 90:
2985
+ rectangle.width = height;
2986
+ rectangle.height = width;
2987
+ rectangle.x = y;
2988
+ rectangle.y = +(pageWidth / zoom - x - width).toFixed(2);
2989
+ break;
2990
+ case 180:
2991
+ rectangle.x = +(pageWidth / zoom - x - width).toFixed(2);
2992
+ rectangle.y = +(pageHeight / zoom - y - height).toFixed(2);
2993
+ break;
2994
+ case 270:
2995
+ rectangle.width = height;
2996
+ rectangle.height = width;
2997
+ rectangle.x = +(pageHeight / zoom - y - height).toFixed(2);
2998
+ rectangle.y = x;
2999
+ break;
3000
+ }
3001
+ return rectangle;
3002
+ }
3003
+ resetHighlight() {
3004
+ window.getSelection().removeAllRanges();
3005
+ this.toolBarEvents.highlightModeSubject.next(false);
3006
+ }
3007
+ }
3008
+ HighlightCreateService.decorators = [
3009
+ { type: Injectable }
3010
+ ];
3011
+ /** @nocollapse */
3012
+ HighlightCreateService.ctorParameters = () => [
3013
+ { type: ToolbarEventService },
3014
+ { type: Store }
3015
+ ];
3016
+
3017
+ class RedactionSearchBarComponent {
3018
+ constructor(store, toolbarButtons, toolbarEvents, highlightService) {
3019
+ this.store = store;
3020
+ this.toolbarButtons = toolbarButtons;
3021
+ this.toolbarEvents = toolbarEvents;
3022
+ this.highlightService = highlightService;
3023
+ this.highlightAll = true;
3024
+ this.matchCase = false;
3025
+ this.wholeWord = false;
3026
+ this.resultsText = '';
3027
+ this.searchText = '';
3028
+ this.resultCount = 0;
3029
+ this.redactElements = [];
3030
+ this.advancedSearchVisible = false;
3031
+ }
3032
+ ngOnInit() {
3033
+ this.subscription = this.toolbarEvents.redactionSerachSubject.subscribe((results) => this.redactAllSearched(results));
3034
+ this.subscription.add(this.store.pipe(select(getDocumentId)).subscribe(docId => this.documentId = docId));
3035
+ this.subscription.add(this.store.pipe(select(getPages)).subscribe((pages) => {
3036
+ if (pages[1]) {
3037
+ this.allPages = pages;
3038
+ }
3039
+ }));
3040
+ this.subscription.add(this.toolbarEvents.searchResultsCountSubject.subscribe(results => this.setSearchResultsCount(results)));
3041
+ this.subscription.add(this.toolbarEvents.openRedactionSearch.subscribe(isOpen => this.openSearchModal = isOpen));
3042
+ this.subscription.add(this.toolbarEvents.redactAllInProgressSubject
3043
+ .subscribe(inProgress => this.redactAllInProgress = inProgress));
3044
+ }
3045
+ ngOnDestroy() {
3046
+ this.subscription.unsubscribe();
3047
+ }
3048
+ onWindowKeyDown(e) {
3049
+ if (e.code === 'F3' || (e.ctrlKey && e.code === 'KeyF')) {
3050
+ e.preventDefault();
3051
+ this.toolbarEvents.searchBarHidden.next(false);
3052
+ setTimeout(() => this.findInput.nativeElement.focus(), 200);
3053
+ }
3054
+ }
3055
+ search(reset = true) {
3056
+ this.redactAll = !reset;
3057
+ if (this.redactAll) {
3058
+ this.toolbarEvents.redactAllInProgressSubject.next(true);
3059
+ }
3060
+ if (reset) {
3061
+ this.redactElements = [];
3062
+ }
3063
+ this.toolbarEvents.search({
3064
+ searchTerm: this.searchText,
3065
+ highlightAll: this.highlightAll,
3066
+ matchCase: this.matchCase,
3067
+ wholeWord: this.wholeWord,
3068
+ previous: false,
3069
+ reset
3070
+ });
3071
+ }
3072
+ saveRedaction(redactRectangle) {
3073
+ const redaction = redactRectangle.map(ele => {
3074
+ return { page: ele.page, rectangles: ele.rectangles, redactionId: uuid$1(), documentId: this.documentId };
3075
+ });
3076
+ this.store.dispatch(new SaveBulkRedaction({ searchRedactions: redaction }));
3077
+ }
3078
+ existInRedactElements(pageNumber, matechedIndex, rectangles) {
3079
+ if (this.redactElements && this.redactElements.length > 0) {
3080
+ const pagesFound = this.redactElements.find(re => re.page === pageNumber && re.matchedIndex === matechedIndex);
3081
+ const pageRectangles = pagesFound === null || pagesFound === void 0 ? void 0 : pagesFound.rectangles;
3082
+ if (!pageRectangles || pageRectangles.length <= 0) {
3083
+ return false;
3084
+ }
3085
+ let matchesRectangles = 0;
3086
+ for (let rectIndx = 0; rectIndx < pageRectangles.length; rectIndx++) {
3087
+ const rectangle = pageRectangles[rectIndx];
3088
+ const foundRectangle = rectangles.find(re => re.width === rectangle.width &&
3089
+ re.height === rectangle.height && re.x === rectangle.x && re.y === rectangle.y);
3090
+ if (foundRectangle) {
3091
+ matchesRectangles++;
3092
+ }
3093
+ }
3094
+ return pageRectangles.length === matchesRectangles;
3095
+ }
3096
+ return false;
3097
+ }
3098
+ onCloseSearchModal() {
3099
+ this.toolbarEvents.openRedactionSearch.next(false);
3100
+ }
3101
+ setSearchResultsCount(results) {
3102
+ this.resultCount = results.total;
3103
+ this.resultsText = this.resultCount > 0
3104
+ ? `${results.total} results founds`
3105
+ : 'No results found';
3106
+ }
3107
+ redactAllSearched(results) {
3108
+ const $this = this;
3109
+ const intervalId = setInterval(() => {
3110
+ const highlightElement = document.getElementsByClassName('highlight selected');
3111
+ if (highlightElement && highlightElement.length > 0) {
3112
+ clearInterval(intervalId);
3113
+ $this.redactAllSearchedTick(results);
3114
+ }
3115
+ }, 100);
3116
+ }
3117
+ redactAllSearchedTick(results) {
3118
+ const highlightElement = document.getElementsByClassName('highlight selected');
3119
+ if (highlightElement && highlightElement.length > 0) {
3120
+ this.resultCount = results.matchesCount;
3121
+ const pageNumber = results.page + 1;
3122
+ const rectangles = this.getRectangles(pageNumber);
3123
+ if (rectangles && this.redactElements.length <= this.resultCount
3124
+ && !this.existInRedactElements(pageNumber, results.matchedIndex, rectangles)) {
3125
+ this.redactElements.push({ page: pageNumber, matchedIndex: results === null || results === void 0 ? void 0 : results.matchedIndex, rectangles });
3126
+ this.CreateRedactAllText();
3127
+ }
3128
+ if (this.redactAll && this.resultCount && this.resultCount > 0
3129
+ && rectangles && this.redactElements.length < this.resultCount) {
3130
+ this.search(false);
3131
+ }
3132
+ if (this.redactAll && this.resultCount && this.redactElements.length === this.resultCount) {
3133
+ this.redactAll = false;
3134
+ this.redactAllText = null;
3135
+ this.saveRedaction(this.redactElements);
3136
+ }
3137
+ }
3138
+ }
3139
+ CreateRedactAllText() {
3140
+ this.redactAllText = `${this.redactElements.length} of ${this.resultCount}`;
3141
+ }
3142
+ onEscapeKeyPress(e) {
3143
+ this.toolbarEvents.searchBarHidden.next(true);
3144
+ }
3145
+ onEnterKeyPress(e) {
3146
+ this.search();
3147
+ }
3148
+ toggleSearchBar() {
3149
+ this.toolbarEvents.searchBarHidden.next(!this.toolbarEvents.searchBarHidden.getValue());
3150
+ }
3151
+ getRectangles(page) {
3152
+ this.pageHeight = this.allPages[page].styles.height;
3153
+ this.pageWidth = this.allPages[page].styles.width;
3154
+ this.zoom = parseFloat(this.allPages[page].scaleRotation.scale);
3155
+ this.rotate = parseInt(this.allPages[page].scaleRotation.rotation, 10);
3156
+ const selectedHighLightedElements = document.getElementsByClassName('highlight selected');
3157
+ if (selectedHighLightedElements && selectedHighLightedElements.length > 0) {
3158
+ const docRange = document.createRange();
3159
+ docRange.selectNodeContents(selectedHighLightedElements[0]);
3160
+ const selection = window.getSelection();
3161
+ selection === null || selection === void 0 ? void 0 : selection.removeAllRanges();
3162
+ selection === null || selection === void 0 ? void 0 : selection.addRange(docRange);
3163
+ if (selection.rangeCount && !selection.isCollapsed) {
3164
+ const range = selection.getRangeAt(0).cloneRange();
3165
+ const clientRects = range.getClientRects();
3166
+ if (clientRects) {
3167
+ const parentRect = selectedHighLightedElements[0].parentElement.parentElement.getBoundingClientRect();
3168
+ const selectionRectangles = [];
3169
+ for (let i = 0; i < clientRects.length; i++) {
3170
+ const selectionRectangle = this.createTextRectangle(clientRects[i], parentRect);
3171
+ const findSelecttionRectangle = selectionRectangles.find((rect) => rect.width === selectionRectangle.width && rect.x === selectionRectangle.x);
3172
+ if (!findSelecttionRectangle) {
3173
+ selectionRectangles.push(selectionRectangle);
3174
+ }
3175
+ }
3176
+ return selectionRectangles;
3177
+ }
3178
+ }
3179
+ }
3180
+ }
3181
+ createTextRectangle(rect, parentRect) {
3182
+ const height = rect.bottom - rect.top;
3183
+ const width = rect.right - rect.left;
3184
+ const top = rect.top - parentRect.top;
3185
+ const left = rect.left - parentRect.left;
3186
+ let rectangle = this.highlightService.applyRotation(this.pageHeight, this.pageWidth, height, width, top, left, this.rotate, this.zoom);
3187
+ rectangle = Object.assign({ id: uuid$1() }, rectangle);
3188
+ return rectangle;
3189
+ }
3190
+ }
3191
+ RedactionSearchBarComponent.decorators = [
3192
+ { type: Component, args: [{
3193
+ selector: 'mv-redaction-search-bar',
3194
+ template: "<div\n *ngIf=\"openSearchModal\"\n class=\"searchbar redaction-search-bar govuk-!-padding-3\"\n>\n <div class=\"govuk-grid-row\">\n <div class=\"govuk-grid-column-full govuk-!-padding-right-0\">\n <div class=\"redaction-search-buttons-area\">\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button searchbar-button--close\"\n title=\"Close Search\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"onCloseSearchModal()\"\n ></button>\n </div>\n <input\n id=\"search_input\"\n class=\"govuk-input govuk-!-width-three-quarters govuk-!-display-inline-block govuk-!-margin-top-5\"\n type=\"text\"\n aria-label=\"Find in document\"\n #findInput\n title=\"Find in document\"\n placeholder=\"Redact from search...\"\n tabindex=\"0\"\n data-l10n-id=\"search_input\"\n [(ngModel)]=\"searchText\"\n (keydown.escape)=\"onEscapeKeyPress($event)\"\n (keydown.enter)=\"onEnterKeyPress($event)\"\n />\n <div class=\"redaction-search-buttons-area\">\n <button\n id=\"mvSearchAllBtn\"\n class=\"govuk-button govuk-!-margin-bottom-0\"\n data-module=\"govuk-button\"\n (click)=\"search()\"\n [disabled]=\"redactAllInProgress\"\n >\n Search\n </button>\n <button\n id=\"mvRedactAllBtn\"\n class=\"govuk-button govuk-!-margin-left-2 govuk-!-margin-bottom-0\"\n data-module=\"govuk-button\"\n (click)=\"search(false)\"\n [disabled]=\"redactAllInProgress\"\n >\n Redact all\n </button>\n </div>\n <div\n class=\"govuk-grid-column-three-quarters govuk-!-padding-left-0 govuk-!-padding-top-2 redaction-status-text\"\n >\n <span\n id=\"findRedactResultsCount\"\n class=\"govuk-grid-column-full govuk-!-margin-right-4 govuk-!-margin-left-0 govuk-!-padding-left-0\"\n ><h4\n class=\"govuk-!-display-inline-block govuk-!-margin-top-0 govuk-!-margin-bottom-1\"\n *ngIf=\"redactAllInProgress\"\n >\n Redacting in progress\n </h4>\n {{ redactAllInProgress ? \"\" : resultsText }}</span\n >\n <span>\n <h5\n id=\"redactAllInProgressCount\"\n class=\"govuk-!-display-inline-block govuk-!-margin-top-0 govuk-!-margin-bottom-1\"\n >\n {{ redactAllInProgress ? redactAllText : \"\" }}\n </h5>\n </span>\n </div>\n </div>\n </div>\n</div>\n",
3195
+ styles: [".redaction-search-buttons-area{display:flex;flex-direction:row;padding-top:.5rem}.redaction-search-bar{width:20rem;left:73%;top:2%}.redaction-status-text{height:2.6rem}"]
3196
+ },] }
3197
+ ];
3198
+ /** @nocollapse */
3199
+ RedactionSearchBarComponent.ctorParameters = () => [
3200
+ { type: Store },
3201
+ { type: ToolbarButtonVisibilityService },
3202
+ { type: ToolbarEventService },
3203
+ { type: HighlightCreateService }
3204
+ ];
3205
+ RedactionSearchBarComponent.propDecorators = {
3206
+ findInput: [{ type: ViewChild, args: ['findInput', { static: true },] }],
3207
+ onWindowKeyDown: [{ type: HostListener, args: ['window:keydown', ['$event'],] }]
3208
+ };
3209
+
2906
3210
  /**
2907
3211
  * Number Helper Service
2908
3212
  * */
@@ -2962,6 +3266,8 @@ class MainToolbarComponent {
2962
3266
  }
2963
3267
  }), this.toolbarEvents.redactionMode.subscribe(enabled => {
2964
3268
  this.redactionEnabled = enabled;
3269
+ }), this.toolbarEvents.redactAllInProgressSubject.subscribe(disable => {
3270
+ this.redactAllInProgress = disable;
2965
3271
  }));
2966
3272
  }
2967
3273
  ngOnDestroy() {
@@ -2985,8 +3291,21 @@ class MainToolbarComponent {
2985
3291
  onClickDrawToggle() {
2986
3292
  this.toolbarEvents.toggleDrawMode();
2987
3293
  }
2988
- toggleSideBar() {
2989
- this.toolbarEvents.sidebarOpen.next(!this.toolbarEvents.sidebarOpen.getValue());
3294
+ toggleIndexSideBar() {
3295
+ const sidebarOpen = this.toolbarEvents.sidebarOpen.getValue();
3296
+ const sidebarView = this.toolbarEvents.sidebarOutlineView.getValue();
3297
+ if (!(sidebarOpen && !sidebarView)) {
3298
+ this.toolbarEvents.toggleSideBar(!sidebarOpen);
3299
+ }
3300
+ this.toolbarEvents.toggleSideBarView(true);
3301
+ }
3302
+ toggleBookmarksSideBar() {
3303
+ const sidebarOpen = this.toolbarEvents.sidebarOpen.getValue();
3304
+ const sidebarView = this.toolbarEvents.sidebarOutlineView.getValue();
3305
+ if (!(sidebarOpen && sidebarView)) {
3306
+ this.toolbarEvents.toggleSideBar(!sidebarOpen);
3307
+ }
3308
+ this.toolbarEvents.toggleSideBarView(false);
2990
3309
  }
2991
3310
  togglePresentBar() {
2992
3311
  this.toolbarEvents.searchBarHidden.next(true);
@@ -3053,7 +3372,7 @@ class MainToolbarComponent {
3053
3372
  MainToolbarComponent.decorators = [
3054
3373
  { type: Component, args: [{
3055
3374
  selector: 'mv-main-toolbar',
3056
- template: "<div class=\"toolbar\">\n <div id=\"toolbarContainer\">\n <div class=\"mv-toolbar__container\">\n <div #mvToolbar class=\"mv-toolbar\" [class.notSupported]=\"!contentType\">\n <!-- The mvToolbarMain div contains all toolbar buttons except the \"More options\" button. This allows for calculation of the available space to display buttons -->\n <div id=\"mvToolbarMain\" class=\"mv-toolbar-main\" #mvToolbarMain>\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n <!-- The mvToolbarMoreOptions div contains the \"More options\" toolbar button (and the overlay template for the dropdown menu).\n The space occupied by the button (if visible) is excluded from the toolbar space available calculation -->\n <div id=\"mvToolbarMoreOptions\" class=\"mv-toolbar-more-options\">\n <button id=\"mvMoreOptionsBtn\" class=\"mv-button mv-toolbar__menu-button--more-options\"\n [class.mv-toolbar__menu-button--more-options__hidden]=\"mvToolbar.offsetWidth >= allButtonsWidth\" aria-pressed=\"false\"\n (click)=\"toggleMoreOptions()\" cdkOverlayOrigin #trigger=\"cdkOverlayOrigin\">\n <span>More options</span>\n </button>\n <!-- This template displays the overlay content for the dropdown menu and is connected to the \"More options\" button -->\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isDropdownMenuOpen\" [cdkConnectedOverlayPositions]=\"dropdownMenuPositions\">\n <div class=\"dropdown-menu\" #dropdownMenu tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n\n <div id=\"mvMenuItems\" #mvMenuItems>\n <ng-template #menuItems>\n\n <button *ngIf=\"toolbarButtons.showSidebar\" id=\"mvIndexBtn\" title=\"Index\" data-l10n-id=\"index\" #mvIndexBtn\n class=\"mv-button mv-toolbar__menu-button--index\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvIndexBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvIndexBtn']\" aria-pressed=\"false\"\n (click)=\"toggleSideBar(); isDropdownMenuOpen = false\">\n <span>Index</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showDrawButton\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvDrawBtn\"\n #mvDrawBtn class=\"mv-button mv-toolbar__menu-button--draw\" title=\"Draw a box\" tabindex=\"-1\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDrawBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDrawBtn']\"\n [class.toggled]=\"toolbarEvents.drawModeSubject | async\" aria-hidden=\"true\" aria-pressed=\"false\"\n data-l10n-id=\"toggleDrawButton\" (click)=\"onClickDrawToggle(); isDropdownMenuOpen = false\">\n <span data-l10n-id=\"draw_label\">Draw a box</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showHighlightButton\" [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvHighlightBtn\" #mvHighlightBtn class=\"mv-button mv-toolbar__menu-button--highlight\" title=\"Highlight\"\n tabindex=\"-1\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvHighlightBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvHighlightBtn']\"\n [class.toggled]=\"toolbarEvents.highlightModeSubject | async\" aria-hidden=\"true\" aria-pressed=\"false\"\n (click)=\"onClickHighlightToggle(); isDropdownMenuOpen = false\" data-l10n-id=\"toggleHighlightButton\">\n <span data-l10n-id=\"highlight_label\">Highlight</span>\n </button>\n\n <ng-container *ngIf=\"toolbarButtons.showNavigation\">\n <div id=\"mvPageBtn\" #mvPageBtn class=\"mv-toolbar__menu-button--page\" aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPageBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPageBtn']\">\n <span>Page</span>\n\n <button id=\"mvUpBtn\" [disabled]=\"pageNumber === 1\" title=\"Previous Page\"\n class=\"mv-toolbar__menu-button--up button-image\" data-l10n-id=\"previous\"\n (click)=\"decreasePageNumber()\"><span></span></button>\n <button id=\"mvDownBtn\" [disabled]=\"pageNumber === pageCount\" title=\"Next Page\"\n class=\"mv-toolbar__menu-button--down button-image\" data-l10n-id=\"next\"\n (click)=\"increasePageNumber()\"><span></span></button>\n\n <input type=\"number\" id=\"pageNumber\" class=\"hmcts-toolbar-input govuk-input--width-2\" title=\"Page Number\"\n value=\"1\" size=\"4\" min=\"1\" [value]=\"pageNumber\" aria-label=\"page number\" tabindex=\"0\"\n data-l10n-id=\"page\" (change)=\"onPageNumberInputChange(pageNumberInput.value)\" #pageNumberInput>\n <span id=\"numPages\" class=\"toolbarLabel\">/ {{ pageCount }}</span>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"toolbarButtons.showZoom\">\n <div id=\"mvZoomBtn\" #mvZoomBtn class=\"mv-toolbar__menu-button--zoom\" aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvZoomBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvZoomBtn']\">\n <button [disabled]=\"toolbarEvents.zoomValueSubject.value == 0.1\" id=\"mvMinusBtn\"\n class=\"mv-toolbar__menu-button--zoom-out button-image\" title=\"Zoom Out\" data-l10n-id=\"zoom_out\"\n (click)=\"stepZoom(-0.1)\"><span></span></button>\n <select id=\"scaleSelect\" class=\"hmcts-toolbar-select\" title=\"Zoom\" tabindex=\"0\" data-l10n-id=\"zoom\"\n (change)=\"zoom($event.target.value)\" aria-label=\"zoom\">\n <option #zoomSelect id=\"customScaleOption\" title=\"\" [value]=\"toolbarEvents.zoomValueSubject.value\">\n {{(toolbarEvents.zoomValueSubject.value) * 100 | number: '1.0-0'}}%</option>\n <option *ngFor=\"let zoomScale of zoomScales\" title=\"\" [value]=\"zoomScale\"\n [attr.data-l10n-id]=\"'page_scale_percent_' + zoomScale*100\">{{ zoomScale *100 }}%\n </option>\n </select>\n\n <button [disabled]=\"toolbarEvents.zoomValueSubject.value == 5\" id=\"mvPlusBtn\"\n class=\"mv-toolbar__menu-button--zoom-in button-image\" (click)=\"stepZoom(0.1)\" title=\"Zoom In\"\n data-l10n-id=\"zoom_in\"><span></span></button>\n </div>\n </ng-container>\n\n <div *ngIf=\"toolbarButtons.showRotate\" id=\"mvRotateBtn\" #mvRotateBtn class=\"mv-toolbar__menu-button--rotate\"\n aria-pressed=\"false\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRotateBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRotateBtn']\">\n <button id=\"mvRotateLeftBtn\" class=\"mv-toolbar__menu-button--rotate_left button-image\"\n title=\"Rotate Counterclockwise\" data-l10n-id=\"page_rotate_ccw\" (click)=\"rotate(270)\"><span></span>\n </button>\n <button id=\"mvRotateRightBtn\" class=\"mv-toolbar__menu-button--rotate_right button-image\"\n title=\"Rotate Clockwise\" data-l10n-id=\"page_rotate_cw\" (click)=\"rotate(90)\"><span></span>\n </button>\n <span>Rotate</span>\n </div>\n\n <button *ngIf=\"toolbarButtons.showSearchBar\" [disabled]=\"icpEnabled\" id=\"mvSearchBtn\" #mvSearchBtn\n title=\"Search\" data-l10n-id=\"searchbar\" class=\"mv-button mv-toolbar__menu-button--search\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvSearchBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvSearchBtn']\" aria-pressed=\"false\"\n (click)=\"toggleSearchBar(); isDropdownMenuOpen = false\">\n </button>\n\n <button *ngIf=\"enableICP && toolbarButtons.showPresentationMode && isPdf()\"\n [disabled]=\"icpEnabled || !contentType || redactionEnabled\" id=\"mvPresentBtn\" #mvPresentBtn\n class=\"mv-button mv-toolbar__menu-button--present\" title=\"In-Court Presentation Mode\"\n data-l10n-id=\"icpMode_label\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPresentBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPresentBtn']\" aria-pressed=\"false\"\n (click)=\"togglePresentBar(); isDropdownMenuOpen = false\"><span data-l10n-id=\"icpMode_label\">Present</span>\n </button>\n\n <button *ngIf=\"enableRedactions && toolbarButtons.showRedact\" [disabled]=\"icpEnabled\" id=\"mvRedactBtn\"\n #mvRedactBtn title=\"Redact\" data-l10n-id=\"redact\" class=\"mv-button mv-toolbar__menu-button--redact\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRedactBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRedactBtn']\" aria-pressed=\"false\"\n (click)=\"toggleRedactBar(); isDropdownMenuOpen = false\">\n <span>Redact</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showGrabNDragButton\" [disabled]=\"icpEnabled\" id=\"mvGrabBtn\" #mvGrabBtn\n class=\"mv-button mv-toolbar__menu-button--grab\" title=\"Grab and drag\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvGrabBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvGrabBtn']\" aria-pressed=\"false\"\n (click)=\"toggleGrabNDrag(); isDropdownMenuOpen = false\">\n <span>Grab and drag</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showDownload\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvDownloadBtn\"\n #mvDownloadBtn class=\"mv-button mv-toolbar__menu-button--download\" title=\"Download\" data-l10n-id=\"download\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDownloadBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDownloadBtn']\" aria-pressed=\"false\"\n (click)=\"downloadFile(); isDropdownMenuOpen = false\">\n </button>\n\n <button *ngIf=\"toolbarButtons.showPrint\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvPrintBtn\"\n #mvPrintBtn title=\"Print\" data-l10n-id=\"print\" class=\"mv-button mv-toolbar__menu-button--print\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPrintBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPrintBtn']\" aria-pressed=\"false\"\n (click)=\"printFile(); isDropdownMenuOpen = false\">\n </button>\n\n <button *ngIf=\"enableAnnotations && toolbarButtons.showCommentSummary\" [disabled]=\"redactionEnabled\"\n id=\"mvCommentsBtn\" #mvCommentsBtn class=\"mv-button mv-toolbar__menu-button--comments\" title=\"Comments\"\n data-l10n-id=\"comments\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvCommentsBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvCommentsBtn']\" aria-pressed=\"false\"\n (click)=\"toggleCommentsPanel(); isDropdownMenuOpen = false\">\n <span>Comments</span>\n </button>\n\n </ng-template>\n </div>\n <mv-search-bar></mv-search-bar>\n </div>\n\n <div id=\"loadingBar\">\n <div class=\"progress\">\n <div class=\"glimmer\">\n </div>\n </div>\n </div>\n </div>\n</div>\n"
3375
+ template: "<div class=\"toolbar\">\n <div id=\"toolbarContainer\">\n <div class=\"mv-toolbar__container\">\n <div #mvToolbar class=\"mv-toolbar\" [class.notSupported]=\"!contentType\">\n <!-- The mvToolbarMain div contains all toolbar buttons except the \"More options\" button. This allows for calculation of the available space to display buttons -->\n <div id=\"mvToolbarMain\" class=\"mv-toolbar-main\" #mvToolbarMain>\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n <!-- The mvToolbarMoreOptions div contains the \"More options\" toolbar button (and the overlay template for the dropdown menu).\n The space occupied by the button (if visible) is excluded from the toolbar space available calculation -->\n <div id=\"mvToolbarMoreOptions\" class=\"mv-toolbar-more-options\">\n <button\n id=\"mvMoreOptionsBtn\"\n class=\"mv-button mv-toolbar__menu-button--more-options\"\n [class.mv-toolbar__menu-button--more-options__hidden]=\"\n mvToolbar.offsetWidth >= allButtonsWidth\n \"\n aria-pressed=\"false\"\n (click)=\"toggleMoreOptions()\"\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [disabled]=\"redactAllInProgress\"\n >\n <span>More options</span>\n </button>\n <!-- This template displays the overlay content for the dropdown menu and is connected to the \"More options\" button -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isDropdownMenuOpen\"\n [cdkConnectedOverlayPositions]=\"dropdownMenuPositions\"\n >\n <div class=\"dropdown-menu\" #dropdownMenu tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n\n <div id=\"mvMenuItems\" #mvMenuItems>\n <ng-template #menuItems>\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvIndexBtn\"\n title=\"Index\"\n data-l10n-id=\"index\"\n #mvIndexBtn\n class=\"mv-button mv-toolbar__menu-button--index\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvIndexBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvIndexBtn']\n \"\n aria-pressed=\"false\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleIndexSideBar(); isDropdownMenuOpen = false\"\n >\n <span>Index</span>\n </button>\n \n <button \n *ngIf=\"toolbarButtons.showSidebar\" \n id=\"mvBookmarksBtn\" \n title=\"Bookmarks\" \n data-l10n-id=\"bookmarks\"\n #mvBookmarksBtn \n [ngClass]=\"{ \n 'mv-button mv-toolbar__menu-button--bookmarks' : true,\n 'button-hidden-on-toolbar': mvToolbarMain.offsetWidth < widthRequiredForBtn['mvBookmarksBtn'],\n 'button-hidden-on-dropdown': mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvBookmarksBtn']\n }\"\n aria-pressed=\"false\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleBookmarksSideBar(); isDropdownMenuOpen = false\"\n >\n <span>Bookmarks</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDrawButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw\"\n title=\"Draw a box\"\n tabindex=\"-1\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDrawBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDrawBtn']\n \"\n [class.toggled]=\"toolbarEvents.drawModeSubject | async\"\n aria-hidden=\"true\"\n aria-pressed=\"false\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"onClickDrawToggle(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"draw_label\">Draw a box</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvHighlightBtn\"\n #mvHighlightBtn\n class=\"mv-button mv-toolbar__menu-button--highlight\"\n title=\"Highlight\"\n tabindex=\"-1\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.toggled]=\"toolbarEvents.highlightModeSubject | async\"\n aria-hidden=\"true\"\n aria-pressed=\"false\"\n (click)=\"onClickHighlightToggle(); isDropdownMenuOpen = false\"\n data-l10n-id=\"toggleHighlightButton\"\n >\n <span data-l10n-id=\"highlight_label\">Highlight</span>\n </button>\n\n <ng-container *ngIf=\"toolbarButtons.showNavigation\">\n <div\n id=\"mvPageBtn\"\n #mvPageBtn\n class=\"mv-toolbar__menu-button--page\"\n aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPageBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPageBtn']\n \"\n >\n <span>Page</span>\n\n <button\n id=\"mvUpBtn\"\n [disabled]=\"pageNumber === 1 || redactAllInProgress\"\n title=\"Previous Page\"\n class=\"mv-toolbar__menu-button--up button-image\"\n data-l10n-id=\"previous\"\n (click)=\"decreasePageNumber()\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvDownBtn\"\n [disabled]=\"pageNumber === pageCount || redactAllInProgress\"\n title=\"Next Page\"\n class=\"mv-toolbar__menu-button--down button-image\"\n data-l10n-id=\"next\"\n (click)=\"increasePageNumber()\"\n >\n <span></span>\n </button>\n\n <input\n type=\"number\"\n id=\"pageNumber\"\n class=\"hmcts-toolbar-input govuk-input--width-2\"\n title=\"Page Number\"\n value=\"1\"\n size=\"4\"\n min=\"1\"\n [value]=\"pageNumber\"\n aria-label=\"page number\"\n tabindex=\"0\"\n data-l10n-id=\"page\"\n (change)=\"onPageNumberInputChange(pageNumberInput.value)\"\n [disabled]=\"redactAllInProgress\"\n #pageNumberInput\n />\n <span id=\"numPages\" class=\"toolbarLabel\">/ {{ pageCount }}</span>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"toolbarButtons.showZoom\">\n <div\n id=\"mvZoomBtn\"\n #mvZoomBtn\n class=\"mv-toolbar__menu-button--zoom\"\n aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvZoomBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvZoomBtn']\n \"\n >\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value == 0.1 ||\n redactAllInProgress\n \"\n id=\"mvMinusBtn\"\n class=\"mv-toolbar__menu-button--zoom-out button-image\"\n title=\"Zoom Out\"\n data-l10n-id=\"zoom_out\"\n (click)=\"stepZoom(-0.1)\"\n >\n <span></span>\n </button>\n <select\n id=\"scaleSelect\"\n class=\"hmcts-toolbar-select\"\n title=\"Zoom\"\n tabindex=\"0\"\n data-l10n-id=\"zoom\"\n (change)=\"zoom($event.target.value)\"\n aria-label=\"zoom\"\n [disabled]=\"redactAllInProgress\"\n >\n <option\n #zoomSelect\n id=\"customScaleOption\"\n title=\"\"\n [value]=\"toolbarEvents.zoomValueSubject.value\"\n >\n {{\n toolbarEvents.zoomValueSubject.value * 100\n | number : \"1.0-0\"\n }}%\n </option>\n <option\n *ngFor=\"let zoomScale of zoomScales\"\n title=\"\"\n [value]=\"zoomScale\"\n [attr.data-l10n-id]=\"'page_scale_percent_' + zoomScale * 100\"\n >\n {{ zoomScale * 100 }}%\n </option>\n </select>\n\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value == 5 ||\n redactAllInProgress\n \"\n id=\"mvPlusBtn\"\n class=\"mv-toolbar__menu-button--zoom-in button-image\"\n (click)=\"stepZoom(0.1)\"\n title=\"Zoom In\"\n data-l10n-id=\"zoom_in\"\n >\n <span></span>\n </button>\n </div>\n </ng-container>\n\n <div\n *ngIf=\"toolbarButtons.showRotate\"\n id=\"mvRotateBtn\"\n #mvRotateBtn\n class=\"mv-toolbar__menu-button--rotate\"\n aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRotateBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRotateBtn']\n \"\n >\n <button\n id=\"mvRotateLeftBtn\"\n class=\"mv-toolbar__menu-button--rotate_left button-image\"\n title=\"Rotate Counterclockwise\"\n data-l10n-id=\"page_rotate_ccw\"\n (click)=\"rotate(270)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvRotateRightBtn\"\n class=\"mv-toolbar__menu-button--rotate_right button-image\"\n title=\"Rotate Clockwise\"\n data-l10n-id=\"page_rotate_cw\"\n (click)=\"rotate(90)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <span>Rotate</span>\n </div>\n\n <button\n *ngIf=\"toolbarButtons.showSearchBar\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvSearchBtn\"\n #mvSearchBtn\n title=\"Search\"\n data-l10n-id=\"searchbar\"\n class=\"mv-button mv-toolbar__menu-button--search\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvSearchBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvSearchBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"toggleSearchBar(); isDropdownMenuOpen = false\"\n ></button>\n\n <button\n *ngIf=\"enableICP && toolbarButtons.showPresentationMode && isPdf()\"\n [disabled]=\"icpEnabled || !contentType || redactionEnabled\"\n id=\"mvPresentBtn\"\n #mvPresentBtn\n class=\"mv-button mv-toolbar__menu-button--present\"\n title=\"In-Court Presentation Mode\"\n data-l10n-id=\"icpMode_label\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPresentBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPresentBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"togglePresentBar(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"icpMode_label\">Present</span>\n </button>\n\n <button\n *ngIf=\"enableRedactions && toolbarButtons.showRedact\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvRedactBtn\"\n #mvRedactBtn\n title=\"Redact\"\n data-l10n-id=\"redact\"\n class=\"mv-button mv-toolbar__menu-button--redact\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRedactBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRedactBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"toggleRedactBar(); isDropdownMenuOpen = false\"\n >\n <span>Redact</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showGrabNDragButton\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvGrabBtn\"\n #mvGrabBtn\n class=\"mv-button mv-toolbar__menu-button--grab\"\n title=\"Grab and drag\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvGrabBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvGrabBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"toggleGrabNDrag(); isDropdownMenuOpen = false\"\n >\n <span>Grab and drag</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDownload\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDownloadBtn\"\n #mvDownloadBtn\n class=\"mv-button mv-toolbar__menu-button--download\"\n title=\"Download\"\n data-l10n-id=\"download\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDownloadBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDownloadBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"downloadFile(); isDropdownMenuOpen = false\"\n ></button>\n\n <button\n *ngIf=\"toolbarButtons.showPrint\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvPrintBtn\"\n #mvPrintBtn\n title=\"Print\"\n data-l10n-id=\"print\"\n class=\"mv-button mv-toolbar__menu-button--print\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPrintBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPrintBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"printFile(); isDropdownMenuOpen = false\"\n ></button>\n\n <button\n *ngIf=\"enableAnnotations && toolbarButtons.showCommentSummary\"\n [disabled]=\"redactionEnabled\"\n id=\"mvCommentsBtn\"\n #mvCommentsBtn\n class=\"mv-button mv-toolbar__menu-button--comments\"\n title=\"Comments\"\n data-l10n-id=\"comments\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvCommentsBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvCommentsBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"toggleCommentsPanel(); isDropdownMenuOpen = false\"\n >\n <span>Comments</span>\n </button>\n </ng-template>\n </div>\n <mv-search-bar></mv-search-bar>\n </div>\n\n <div id=\"loadingBar\">\n <div class=\"progress\">\n <div class=\"glimmer\"></div>\n </div>\n </div>\n </div>\n</div>\n"
3057
3376
  },] }
3058
3377
  ];
3059
3378
  /** @nocollapse */
@@ -3205,11 +3524,18 @@ class RedactionToolbarComponent {
3205
3524
  this.store = store;
3206
3525
  this.preview = false;
3207
3526
  this.hasRedactions = false;
3527
+ this.subscriptions = [];
3208
3528
  }
3209
3529
  ngOnInit() {
3210
- this.$subscription = this.store.pipe(select(getRedactionArray)).subscribe(redactions => {
3530
+ this.subscriptions.push(this.store.pipe(select(getRedactionArray)).subscribe(redactions => {
3211
3531
  this.hasRedactions = !!redactions.redactions.length;
3212
- });
3532
+ }));
3533
+ this.subscriptions.push(this.toolbarEventService.redactAllInProgressSubject.subscribe(inprogress => {
3534
+ this.redactionAllInProgress = inprogress;
3535
+ }));
3536
+ }
3537
+ onRedactAllSearch() {
3538
+ this.toolbarEventService.openRedactionSearch.next(true);
3213
3539
  }
3214
3540
  toggleTextRedactionMode() {
3215
3541
  this.toolbarEventService.highlightModeSubject.next(true);
@@ -3235,13 +3561,15 @@ class RedactionToolbarComponent {
3235
3561
  this.toolbarEventService.redactPage();
3236
3562
  }
3237
3563
  ngOnDestroy() {
3238
- this.$subscription.unsubscribe();
3564
+ for (const subscription of this.subscriptions) {
3565
+ subscription.unsubscribe();
3566
+ }
3239
3567
  }
3240
3568
  }
3241
3569
  RedactionToolbarComponent.decorators = [
3242
3570
  { type: Component, args: [{
3243
3571
  selector: 'mv-redaction-toolbar',
3244
- template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\">Redaction options</label>\n <button id=\"toggleDrawButton\" class=\"mv-button redaction-button--draw\" title=\"Draw a box\"\n data-l10n-id=\"toggleDrawButton\" (click)=\"toggleDrawMode()\">\n <span data-l10n-id=\"toggleDrawButton_label\">Draw a box</span>\n </button>\n\n <button id=\"redactPageButton\" class=\"mv-button redaction-button--redact-page\" title=\"Redact Page\"\n data-l10n-id=\"redactPageButton\" (click)=\"redactPage()\">\n <span data-l10n-id=\"redactPageButton_label\">Redact page</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showHighlightButton\" id=\"toggleHighlightButton\"\n class=\"mv-button redaction-button--redact\" aria-pressed=\"false\" title=\"Redact text\"\n data-l10n-id=\"toggleTextRedactionButton\" (click)=\"toggleTextRedactionMode()\">\n <span data-l10n-id=\"toggleTextRedactionButton_label\">Redact text</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvClearBtn\" #mvClearBtn class=\"mv-button redaction-button--clear\" aria-pressed=\"false\" title=\"Clear all\"\n data-l10n-id=\"toggleClearAllButton\" (click)=\"unmarkAll()\">\n <span data-l10n-id=\"Clear all\">Clear all</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvPreviewBtn\" class=\"mv-button\" [class.redaction-button--preview]=\"!preview\"\n [class.redaction-button--hide-preview]=\"preview\" redaction-button--preview aria-pressed=\"false\" title=\"Preview\"\n data-l10n-id=\"togglePreviewButton\" (click)=\"togglePreview()\">\n <span *ngIf=\"!preview\" data-l10n-id=\"redaction-preview_label\">Preview</span>\n <span *ngIf=\"preview\" data-l10n-id=\"redaction-hide-preview_label\">Hide preview</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvRedactBtn\" class=\"mv-button redaction-button--download\" aria-pressed=\"false\" title=\"Redact\"\n data-l10n-id=\"mvRedactBtn\" (click)=\"redact()\">\n <span data-l10n-id=\"Save Document\">Save document</span>\n </button>\n\n <button id=\"mvCloseBtn\" #mvCloseBtn class=\"mv-button redaction-button--close\" title=\"Close Redaction\" data-l10n-id=\"mvRedactBtn\"\n (click)=\"toggleRedactBar()\">\n <span data-l10n-id=\"Close Redaction\">Close Redaction</span>\n </button>\n\n</div>\n"
3572
+ template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\"\n >Redaction options</label\n >\n <button\n id=\"toggleDrawButton\"\n class=\"mv-button redaction-button--draw\"\n title=\"Draw a box\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"toggleDrawMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleDrawButton_label\">Draw a box</span>\n </button>\n\n <button\n id=\"redactPageButton\"\n class=\"mv-button redaction-button--redact-page\"\n title=\"Redact Page\"\n data-l10n-id=\"redactPageButton\"\n (click)=\"redactPage()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"redactPageButton_label\">Redact page</span>\n </button>\n <button\n *ngIf=\"showRedactSearch\"\n id=\"mvRedactFromSearchBtn\"\n title=\"From search\"\n data-l10n-id=\"fromSearchButton\"\n class=\"mv-button redaction-button--search\"\n (click)=\"onRedactAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\"\n >From search</span\n >\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n id=\"toggleHighlightButton\"\n class=\"mv-button redaction-button--redact\"\n aria-pressed=\"false\"\n title=\"Redact text\"\n data-l10n-id=\"toggleTextRedactionButton\"\n (click)=\"toggleTextRedactionMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleTextRedactionButton_label\">Redact text</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvClearBtn\"\n #mvClearBtn\n class=\"mv-button redaction-button--clear\"\n aria-pressed=\"false\"\n title=\"Clear all\"\n data-l10n-id=\"toggleClearAllButton\"\n (click)=\"unmarkAll()\"\n >\n <span data-l10n-id=\"Clear all\">Clear all</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvPreviewBtn\"\n class=\"mv-button\"\n [class.redaction-button--preview]=\"!preview\"\n [class.redaction-button--hide-preview]=\"preview\"\n redaction-button--preview\n aria-pressed=\"false\"\n title=\"Preview\"\n data-l10n-id=\"togglePreviewButton\"\n (click)=\"togglePreview()\"\n >\n <span *ngIf=\"!preview\" data-l10n-id=\"redaction-preview_label\">Preview</span>\n <span *ngIf=\"preview\" data-l10n-id=\"redaction-hide-preview_label\"\n >Hide preview</span\n >\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvRedactBtn\"\n class=\"mv-button redaction-button--download\"\n aria-pressed=\"false\"\n title=\"Redact\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"redact()\"\n >\n <span data-l10n-id=\"Save Document\">Save document</span>\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close\"\n title=\"Close Redaction\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"toggleRedactBar()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">Close Redaction</span>\n </button>\n</div>\n"
3245
3573
  },] }
3246
3574
  ];
3247
3575
  /** @nocollapse */
@@ -3250,6 +3578,9 @@ RedactionToolbarComponent.ctorParameters = () => [
3250
3578
  { type: ToolbarButtonVisibilityService },
3251
3579
  { type: Store }
3252
3580
  ];
3581
+ RedactionToolbarComponent.propDecorators = {
3582
+ showRedactSearch: [{ type: Input }]
3583
+ };
3253
3584
 
3254
3585
  class IcpToolbarComponent {
3255
3586
  constructor(toolbarEventService, store) {
@@ -3298,7 +3629,8 @@ ToolbarModule.decorators = [
3298
3629
  SearchBarComponent,
3299
3630
  MainToolbarComponent,
3300
3631
  RedactionToolbarComponent,
3301
- IcpToolbarComponent
3632
+ IcpToolbarComponent,
3633
+ RedactionSearchBarComponent
3302
3634
  ],
3303
3635
  providers: [
3304
3636
  ToolbarButtonVisibilityService,
@@ -3308,7 +3640,8 @@ ToolbarModule.decorators = [
3308
3640
  MainToolbarComponent,
3309
3641
  SearchBarComponent,
3310
3642
  RedactionToolbarComponent,
3311
- IcpToolbarComponent
3643
+ IcpToolbarComponent,
3644
+ RedactionSearchBarComponent
3312
3645
  ],
3313
3646
  imports: [
3314
3647
  CommonModule,
@@ -3441,59 +3774,6 @@ AnnotationSetComponent.propDecorators = {
3441
3774
  pageWidth: [{ type: Input }]
3442
3775
  };
3443
3776
 
3444
- class HighlightCreateService {
3445
- constructor(toolBarEvents, store) {
3446
- this.toolBarEvents = toolBarEvents;
3447
- this.store = store;
3448
- }
3449
- saveAnnotation(rectangles, page) {
3450
- this.store.pipe(select(getDocumentIdSetId), take(1)).subscribe(anoSetDocId => {
3451
- const anno = Object.assign(Object.assign({ id: uuid$1(), color: 'FFFF00', comments: [], page: page, rectangles: rectangles, type: 'highlight' }, anoSetDocId), { createdBy: '', createdByDetails: undefined, createdDate: moment.utc().tz('Europe/London').toISOString(), lastModifiedBy: '', lastModifiedByDetails: undefined, lastModifiedDate: '', tags: [] });
3452
- this.store.dispatch(new SaveAnnotation(anno));
3453
- });
3454
- }
3455
- applyRotation(pageHeight, pageWidth, offsetHeight, offsetWidth, offsetTop, offsetLeft, rotate, zoom) {
3456
- const { x, y, width, height } = {
3457
- x: +(offsetLeft / zoom).toFixed(2),
3458
- y: +(offsetTop / zoom).toFixed(2),
3459
- width: +(offsetWidth / zoom).toFixed(2),
3460
- height: +(offsetHeight / zoom).toFixed(2)
3461
- };
3462
- const rectangle = { x, y, width, height };
3463
- switch (rotate) {
3464
- case 90:
3465
- rectangle.width = height;
3466
- rectangle.height = width;
3467
- rectangle.x = y;
3468
- rectangle.y = +(pageWidth / zoom - x - width).toFixed(2);
3469
- break;
3470
- case 180:
3471
- rectangle.x = +(pageWidth / zoom - x - width).toFixed(2);
3472
- rectangle.y = +(pageHeight / zoom - y - height).toFixed(2);
3473
- break;
3474
- case 270:
3475
- rectangle.width = height;
3476
- rectangle.height = width;
3477
- rectangle.x = +(pageHeight / zoom - y - height).toFixed(2);
3478
- rectangle.y = x;
3479
- break;
3480
- }
3481
- return rectangle;
3482
- }
3483
- resetHighlight() {
3484
- window.getSelection().removeAllRanges();
3485
- this.toolBarEvents.highlightModeSubject.next(false);
3486
- }
3487
- }
3488
- HighlightCreateService.decorators = [
3489
- { type: Injectable }
3490
- ];
3491
- /** @nocollapse */
3492
- HighlightCreateService.ctorParameters = () => [
3493
- { type: ToolbarEventService },
3494
- { type: Store }
3495
- ];
3496
-
3497
3777
  class RectangleComponent {
3498
3778
  constructor(toolbarEvents, highlightService) {
3499
3779
  this.toolbarEvents = toolbarEvents;
@@ -3653,6 +3933,7 @@ class CommentComponent {
3653
3933
  this.subscriptions = this.store.select(getComponentSearchText)
3654
3934
  .pipe(distinctUntilChanged()).subscribe(searchString => this.searchString = searchString);
3655
3935
  this.reRenderComments();
3936
+ this.marginToComment$ = this.commentService.marginToCommentEmitter.asObservable();
3656
3937
  }
3657
3938
  ngAfterContentInit() {
3658
3939
  if (this.tagItems && this.tagItems.length) {
@@ -3763,7 +4044,7 @@ class CommentComponent {
3763
4044
  CommentComponent.decorators = [
3764
4045
  { type: Component, args: [{
3765
4046
  selector: 'mv-anno-comment',
3766
- template: "<div #form (click)=\"onCommentClick()\" class=\"aui-comment\"\n [style.top.px]=\"commentTop\"\n [style.zIndex]=\"selected ? 100 : 0\">\n <div id=\"detailsWrapper {{index}}\" class=\"aui-comment__header\">\n <span *ngIf=\"author && !editor\" class=\"aui-comment__author\">\n {{ author.forename }} {{ author.surname }}\n </span>\n <span *ngIf=\"editor\" class=\"aui-comment__author\">\n {{ editor.forename }} {{ editor.surname }}\n </span>\n <time [hidden]=\"!selected && !this.editable\" class=\"aui-comment__meta\">\n {{ lastUpdate | momentDate: 'd MMMM y h:mm a' }}\n </time>\n </div>\n <mv-tags\n [tagItems]=\"tagItems\"\n [userId]=\"createdBy\"\n [editable]=\"editable\"\n [annoId]=\"_comment.annotationId\">\n </mv-tags>\n <textarea *ngIf=\"selected && editable\"\n #editableComment\n mvTextAreaAutoExpand\n type=\"text\"\n required\n name=\"content\"\n [maxlength]=\"CHAR_LIMIT\"\n class=\"aui-comment__content form-control mimic-focus edit-mode expanded\"\n [(ngModel)]=\"fullComment\"\n (ngModelChange)=\"reRenderComments(); onCommentChange($event);\"\n aria-label=\"comment\">\n </textarea>\n <p *ngIf=\"!editable\"\n mvTextHighlight class=\"commentText\" [textToHighlight]=\"searchString\">\n {{ fullComment }}\n </p>\n <div *ngIf=\"selected || this.editable || (!fullComment.length && (tagItems && !tagItems.length))\"\n class=\"aui-comment__footer commentBtns\">\n <button class=\"govuk-button\"\n type=\"button\" role=\"button\"\n (click)=\"editOrSave()\">\n {{ !editable ? 'Edit' : 'Save' }}\n </button>\n <button type=\"button\" role=\"button\"\n class=\"govuk-button govuk-button--secondary\"\n (click)=\"deleteOrCancel()\">\n {{ !editable ? 'Delete' : 'Cancel' }}\n </button>\n </div>\n <span class=\"aui-comment__private\">private</span>\n</div>\n"
4047
+ template: "<div #form (click)=\"onCommentClick()\" class=\"aui-comment\"\n [ngClass]=\"{'stylestoggle' : (marginToComment$ | async ) }\"\n [style.top.px]=\"commentTop\"\n [style.zIndex]=\"selected ? 100 : 0\">\n <div id=\"detailsWrapper {{index}}\" class=\"aui-comment__header\">\n <span *ngIf=\"author && !editor\" class=\"aui-comment__author\">\n {{ author.forename }} {{ author.surname }}\n </span>\n <span *ngIf=\"editor\" class=\"aui-comment__author\">\n {{ editor.forename }} {{ editor.surname }}\n </span>\n <time [hidden]=\"!selected && !this.editable\" class=\"aui-comment__meta\">\n {{ lastUpdate | momentDate: 'd MMMM y h:mm a' }}\n </time>\n </div>\n <mv-tags\n [tagItems]=\"tagItems\"\n [userId]=\"createdBy\"\n [editable]=\"editable\"\n [annoId]=\"_comment.annotationId\">\n </mv-tags>\n <textarea *ngIf=\"selected && editable\"\n #editableComment\n mvTextAreaAutoExpand\n type=\"text\"\n required\n name=\"content\"\n [maxlength]=\"CHAR_LIMIT\"\n class=\"aui-comment__content form-control mimic-focus edit-mode expanded\"\n [(ngModel)]=\"fullComment\"\n (ngModelChange)=\"reRenderComments(); onCommentChange($event);\"\n aria-label=\"comment\">\n </textarea>\n <p *ngIf=\"!editable\"\n mvTextHighlight class=\"commentText\" [textToHighlight]=\"searchString\">\n {{ fullComment }}\n </p>\n <div *ngIf=\"selected || this.editable || (!fullComment.length && (tagItems && !tagItems.length))\"\n class=\"aui-comment__footer commentBtns\">\n <button class=\"govuk-button\"\n type=\"button\" role=\"button\"\n (click)=\"editOrSave()\">\n {{ !editable ? 'Edit' : 'Save' }}\n </button>\n <button type=\"button\" role=\"button\"\n class=\"govuk-button govuk-button--secondary\"\n (click)=\"deleteOrCancel()\">\n {{ !editable ? 'Delete' : 'Cancel' }}\n </button>\n </div>\n <span class=\"aui-comment__private\">private</span>\n</div>\n"
3767
4048
  },] }
3768
4049
  ];
3769
4050
  /** @nocollapse */
@@ -4240,7 +4521,7 @@ class BoxHighlightCreateComponent {
4240
4521
  if (this.height / this.zoom > 5 || this.width / this.zoom > 5) {
4241
4522
  let rectangle = this.highlightService
4242
4523
  .applyRotation(this.pageHeight, this.pageWidth, this.height, this.width, this.top, this.left, this.rotate, this.zoom);
4243
- rectangle = Object.assign({ id: uuid$1() }, rectangle);
4524
+ rectangle = Object.assign({ id: v4() }, rectangle);
4244
4525
  this.saveSelection.emit({ rectangles: [rectangle], page: this.page });
4245
4526
  this.resetHighlight();
4246
4527
  }
@@ -4284,8 +4565,9 @@ BoxHighlightCreateComponent.propDecorators = {
4284
4565
  };
4285
4566
 
4286
4567
  class CommentSetHeaderComponent {
4287
- constructor(store, toolbarEvents) {
4568
+ constructor(store, commentService, toolbarEvents) {
4288
4569
  this.store = store;
4570
+ this.commentService = commentService;
4289
4571
  this.toolbarEvents = toolbarEvents;
4290
4572
  this.showCommentSummaryDialog = new EventEmitter();
4291
4573
  this.tabs = [];
@@ -4309,6 +4591,14 @@ class CommentSetHeaderComponent {
4309
4591
  }
4310
4592
  selectTab(tab) {
4311
4593
  this.tabSelected = tab !== this.tabSelected ? tab : undefined;
4594
+ if (this.tabSelected) {
4595
+ this.marginToComment = true;
4596
+ this.commentService.createMarginToCommentEvent(this.marginToComment);
4597
+ }
4598
+ else {
4599
+ this.marginToComment = false;
4600
+ this.commentService.createMarginToCommentEvent(this.marginToComment);
4601
+ }
4312
4602
  }
4313
4603
  toggleCommentsPanel() {
4314
4604
  this.toolbarEvents.toggleCommentsPanel(!this.toolbarEvents.commentsPanelVisible.getValue());
@@ -4327,6 +4617,7 @@ CommentSetHeaderComponent.decorators = [
4327
4617
  /** @nocollapse */
4328
4618
  CommentSetHeaderComponent.ctorParameters = () => [
4329
4619
  { type: Store },
4620
+ { type: CommentService },
4330
4621
  { type: ToolbarEventService }
4331
4622
  ];
4332
4623
  CommentSetHeaderComponent.propDecorators = {
@@ -4899,7 +5190,7 @@ const ɵ2 = (bookmarkNodes, docId, pdfPosition, pages) => {
4899
5190
  pageNumber: pdfPosition.pageNumber - 1,
4900
5191
  xCoordinate: pdfPosition.left,
4901
5192
  yCoordinate: pages[pdfPosition.pageNumber].styles.height - (pdfPosition.top * pages[pdfPosition.pageNumber].viewportScale),
4902
- previous: bookmarkNodes.length > 0 ? bookmarkNodes[bookmarkNodes.length - 1].id : undefined,
5193
+ previous: bookmarkNodes.length > 0 ? bookmarkNodes.sort((a, b) => a.index - b.index)[bookmarkNodes.length - 1].id : undefined,
4903
5194
  documentId: docId
4904
5195
  };
4905
5196
  };
@@ -4960,8 +5251,9 @@ class MetadataLayerComponent {
4960
5251
  this.store.pipe(select(getBookmarkInfo), take(1))
4961
5252
  .subscribe((bookmarkInfo) => {
4962
5253
  const selection = window.getSelection().toString();
4963
- this.store.dispatch(new CreateBookmark(Object.assign(Object.assign({}, bookmarkInfo), { name: selection.length > 0 ? selection.substr(0, 30) : 'new bookmark', id: uuid$1(), pageNumber: this.highlightPage - 1, xCoordinate: rectangle.x, yCoordinate: rectangle.y })));
5254
+ this.store.dispatch(new CreateBookmark(Object.assign(Object.assign({}, bookmarkInfo), { name: selection.length > 0 ? selection.substr(0, 30) : 'new bookmark', id: v4(), pageNumber: this.highlightPage - 1, xCoordinate: rectangle.x, yCoordinate: rectangle.y })));
4964
5255
  this.toolbarEvents.toggleSideBar(true);
5256
+ this.toolbarEvents.toggleSideBarView(false);
4965
5257
  this.highlightService.resetHighlight();
4966
5258
  this.rectangles = undefined;
4967
5259
  });
@@ -5036,6 +5328,7 @@ AnnotationsModule.decorators = [
5036
5328
  BookmarksApiService,
5037
5329
  CommentSetRenderService,
5038
5330
  HighlightCreateService,
5331
+ CommentService,
5039
5332
  TagsServices
5040
5333
  ],
5041
5334
  exports: [
@@ -5106,16 +5399,191 @@ GrabNDragDirective.propDecorators = {
5106
5399
  onWindowPointerUp: [{ type: HostListener, args: ['window:pointerup',] }]
5107
5400
  };
5108
5401
 
5402
+ class BookmarksComponent {
5403
+ constructor(store) {
5404
+ this.store = store;
5405
+ this.goToDestination = new EventEmitter();
5406
+ this.pageLookup = {};
5407
+ this.BOOKMARK_CHAR_LIMIT = 30;
5408
+ this.options = {
5409
+ allowDrag: true,
5410
+ allowDrop: true
5411
+ };
5412
+ this._customSort = 'CUSTOM';
5413
+ this._positionSort = 'POSITION';
5414
+ }
5415
+ ngOnInit() {
5416
+ this.sortMode = this.customSort;
5417
+ this.$subscription = this.store.pipe(select(getEditableBookmark))
5418
+ .subscribe(editableId => this.editableBookmark = editableId);
5419
+ this.$subscription.add(this.store.select(getPages)
5420
+ .subscribe(pages => {
5421
+ Object.keys(pages).map(key => {
5422
+ this.pageLookup[key] = pages[key];
5423
+ });
5424
+ }));
5425
+ }
5426
+ ngOnChanges(changes) {
5427
+ if (changes.bookmarkNodes && this.sortMode !== this.customSort) {
5428
+ this.sortBookmarks();
5429
+ }
5430
+ }
5431
+ ngOnDestroy() {
5432
+ this.$subscription.unsubscribe();
5433
+ }
5434
+ editBookmark(id) {
5435
+ this.editableBookmark = id;
5436
+ }
5437
+ onAddBookmarkClick() {
5438
+ this.store.pipe(select(getBookmarkInfo), take(1))
5439
+ .subscribe((bookmarkInfo) => {
5440
+ this.store.dispatch(new CreateBookmark(Object.assign(Object.assign({}, bookmarkInfo), { name: '', id: uuid$1() })));
5441
+ });
5442
+ }
5443
+ onBookmarkMove({ node, from, to }) {
5444
+ let movedBookmarks = [Object.assign(Object.assign({}, node), { previous: to.index > 0 ? to.parent.children[to.index - 1].id : undefined, parent: to.parent.documentId ? to.parent.id : undefined })];
5445
+ let fromNext = this.getSibling(from, from.index);
5446
+ fromNext = fromNext && fromNext.id === node.previous ? this.getSibling(from, from.index + 1) : fromNext;
5447
+ if (fromNext) {
5448
+ movedBookmarks = [...movedBookmarks, Object.assign(Object.assign({}, fromNext), { previous: node.previous })];
5449
+ }
5450
+ const toNext = this.getSibling(to, to.index + 1);
5451
+ if (toNext) {
5452
+ movedBookmarks = [...movedBookmarks, Object.assign(Object.assign({}, toNext), { previous: node.id })];
5453
+ }
5454
+ this.store.dispatch(new MoveBookmark(movedBookmarks));
5455
+ }
5456
+ deleteBookmark(node) {
5457
+ this.customSortBookmarks();
5458
+ let next;
5459
+ node = this.tree.treeModel.getNodeById(node.id);
5460
+ if (!node.parent) {
5461
+ node.parent = this.tree.treeModel.virtualRoot;
5462
+ }
5463
+ const siblings = node.parent.children;
5464
+ if (siblings.length > node.index + 1) {
5465
+ next = siblings[node.index + 1].data;
5466
+ next.previous = node.data.previous;
5467
+ }
5468
+ this.store.dispatch(new DeleteBookmark({
5469
+ deleted: [node.data.id, ...getBookmarkChildren(node.data.children)], updated: next
5470
+ }));
5471
+ }
5472
+ updateBookmark(bookmark, name) {
5473
+ const editedBookmark = Object.assign(Object.assign({}, bookmark), { name });
5474
+ if (name) {
5475
+ this.store.dispatch(new UpdateBookmark(editedBookmark));
5476
+ this.editableBookmark = undefined;
5477
+ }
5478
+ }
5479
+ goToBookmark(bookmark) {
5480
+ const thisPage = this.pageLookup[bookmark.pageNumber + 1];
5481
+ const defaultHeight = thisPage.styles.height;
5482
+ const defaultScaleY = this.scaledY(bookmark.yCoordinate, defaultHeight, thisPage);
5483
+ let top = 0, left = 0;
5484
+ switch (this.rotate) {
5485
+ case 90:
5486
+ left = -defaultScaleY;
5487
+ break;
5488
+ case 180:
5489
+ top = this.scaledY(bookmark.yCoordinate, (defaultHeight - (24 * this.zoom)), thisPage);
5490
+ break;
5491
+ case 270:
5492
+ left = defaultScaleY;
5493
+ break;
5494
+ default:
5495
+ top = defaultScaleY;
5496
+ }
5497
+ this.goToDestination.emit([
5498
+ bookmark.pageNumber,
5499
+ { 'name': 'XYZ' },
5500
+ left,
5501
+ top
5502
+ ]);
5503
+ }
5504
+ get customSort() {
5505
+ return this._customSort;
5506
+ }
5507
+ get positionSort() {
5508
+ return this._positionSort;
5509
+ }
5510
+ sort(mode) {
5511
+ this.sortMode = mode;
5512
+ this.sortBookmarks();
5513
+ }
5514
+ sortBookmarks() {
5515
+ switch (this.sortMode) {
5516
+ case this.customSort: {
5517
+ this.customSortBookmarks();
5518
+ break;
5519
+ }
5520
+ case this.positionSort: {
5521
+ this.positionSortBookmarks();
5522
+ break;
5523
+ }
5524
+ default: {
5525
+ this.customSortBookmarks();
5526
+ break;
5527
+ }
5528
+ }
5529
+ }
5530
+ positionSortBookmarks() {
5531
+ this.bookmarkNodes.sort((a, b) => a.pageNumber === b.pageNumber ? a.yCoordinate - b.yCoordinate : a.pageNumber - b.pageNumber);
5532
+ this.tree.treeModel.update();
5533
+ this.setDragNDrop(false);
5534
+ }
5535
+ customSortBookmarks() {
5536
+ this.bookmarkNodes.sort((a, b) => a.index - b.index);
5537
+ this.tree.treeModel.update();
5538
+ this.setDragNDrop(true);
5539
+ }
5540
+ setDragNDrop(enabled) {
5541
+ this.options = {
5542
+ allowDrag: enabled,
5543
+ allowDrop: enabled
5544
+ };
5545
+ }
5546
+ getSibling(node, index) {
5547
+ return node.parent.children.length > index ? node.parent.children[index] : undefined;
5548
+ }
5549
+ scaledY(yCoordinate, height, page) {
5550
+ const viewportScale = page.viewportScale / this.zoom;
5551
+ return ((height / this.zoom) - yCoordinate) / viewportScale;
5552
+ }
5553
+ }
5554
+ BookmarksComponent.decorators = [
5555
+ { type: Component, args: [{
5556
+ selector: 'mv-bookmarks',
5557
+ template: "<a *ngIf=\"bookmarkNodes?.length === 0\" class=\"highlightedOutlineItem\">No bookmarks created yet</a>\n<tree-root [nodes]=\"bookmarkNodes\" class=\"bookmarks-tree\" [options]=\"options\" (moveNode)=\"onBookmarkMove($event)\">\n <ng-template #treeNodeTemplate let-node let-index=\"index\">\n <div class=\"outlineItem\" *ngIf=\"node.data.id !== editableBookmark; else inputBookmark\">\n <a (click)=\"goToBookmark(node.data)\">\n {{ node.data.name }}\n </a>\n <button class=\"bookmark__rename\" (click)=\"editBookmark(node.data.id)\"></button>\n <button class=\"bookmark__delete\" (click)=\"deleteBookmark(node)\"></button>\n </div>\n <ng-template #inputBookmark>\n <input #bookmarkName class=\"bookmark__input\" [value]=\"node.data.name\" [maxLength]=\"BOOKMARK_CHAR_LIMIT\">\n <button class=\"bookmark__save\" (click)=\"updateBookmark(node.data, bookmarkName.value)\"></button>\n </ng-template>\n </ng-template>\n</tree-root>\n"
5558
+ },] }
5559
+ ];
5560
+ /** @nocollapse */
5561
+ BookmarksComponent.ctorParameters = () => [
5562
+ { type: Store }
5563
+ ];
5564
+ BookmarksComponent.propDecorators = {
5565
+ bookmarkNodes: [{ type: Input }],
5566
+ zoom: [{ type: Input }],
5567
+ rotate: [{ type: Input }],
5568
+ goToDestination: [{ type: Output }],
5569
+ tree: [{ type: ViewChild, args: [TreeComponent,] }]
5570
+ };
5571
+
5109
5572
  class SideBarComponent {
5110
- constructor(viewerEvents, store) {
5573
+ constructor(viewerEvents, store, toolbarEvents) {
5111
5574
  this.viewerEvents = viewerEvents;
5112
5575
  this.store = store;
5576
+ this.toolbarEvents = toolbarEvents;
5113
5577
  this.selectedView = 'outline';
5578
+ this.subscriptions = [];
5114
5579
  }
5115
5580
  ngOnInit() {
5116
5581
  this.bookmarkNodes$ = this.store.pipe(select(getBookmarkNodes));
5117
- this.$subscription = this.store.pipe(select(getEditableBookmark))
5118
- .subscribe(editable => this.selectedView = editable ? 'bookmarks' : this.selectedView);
5582
+ this.subscriptions.push(this.store.pipe(select(getEditableBookmark))
5583
+ .subscribe(editable => this.selectedView = editable ? 'bookmarks' : this.selectedView));
5584
+ this.subscriptions.push(this.toolbarEvents.sidebarOutlineView.subscribe(toggle => {
5585
+ this.selectedView = toggle ? 'outline' : 'bookmarks';
5586
+ }));
5119
5587
  }
5120
5588
  ngOnChanges(changes) {
5121
5589
  if (changes.url && this.url) {
@@ -5123,7 +5591,9 @@ class SideBarComponent {
5123
5591
  }
5124
5592
  }
5125
5593
  ngOnDestroy() {
5126
- this.$subscription.unsubscribe();
5594
+ if (this.subscriptions.length > 0) {
5595
+ this.subscriptions.forEach(subscription => subscription.unsubscribe());
5596
+ }
5127
5597
  }
5128
5598
  goToDestination(destination) {
5129
5599
  this.viewerEvents.goToDestination(destination);
@@ -5131,14 +5601,10 @@ class SideBarComponent {
5131
5601
  toggleSidebarView(sidebarView) {
5132
5602
  this.selectedView = sidebarView;
5133
5603
  }
5134
- onAddBookmarkClick() {
5135
- this.toggleSidebarView('bookmarks');
5136
- this.store.pipe(select(getBookmarkInfo), take(1))
5137
- .subscribe((bookmarkInfo) => {
5138
- this.store.dispatch(new CreateBookmark(Object.assign(Object.assign({}, bookmarkInfo), { name: '', id: uuid$1() })));
5139
- });
5140
- }
5141
5604
  isViewedItem(current, next) {
5605
+ if (current.pageNumber === this.currentPageNumber) {
5606
+ return true;
5607
+ }
5142
5608
  return next === undefined ? current.pageNumber <= this.currentPageNumber :
5143
5609
  current.pageNumber <= this.currentPageNumber && (next.pageNumber > this.currentPageNumber);
5144
5610
  }
@@ -5149,13 +5615,14 @@ class SideBarComponent {
5149
5615
  SideBarComponent.decorators = [
5150
5616
  { type: Component, args: [{
5151
5617
  selector: 'mv-side-bar',
5152
- template: "<div id=\"toolbarSidebar\">\n <div class=\"splitToolbarButton toggled\">\n <button id=\"viewOutline\"\n [ngClass]=\"{ 'toolbarButton': true, 'toggled': selectedView === 'outline' }\"\n (click)=\"toggleSidebarView('outline')\"\n title=\"Show Document Outline\" tabindex=\"1\" data-l10n-id=\"document_outline\">\n <span data-l10n-id=\"document_outline_label\">Document Outline</span>\n </button>\n <button *ngIf=\"annotationsEnabled\"\n id=\"viewBookmark\" class=\"toolbarButton bookmark\"\n [ngClass]=\"{ toggled: selectedView === 'bookmarks' }\"\n (click)=\"toggleSidebarView('bookmarks')\"\n title=\"Show Bookmarks\" tabindex=\"2\" data-l10n-id=\"bookmarks\">\n <span data-l10n-id=\"bookmarks_label\">Bookmarks</span>\n </button>\n </div>\n <div class=\"splitToolbarButtonSeparator\"></div>\n <div *ngIf=\"annotationsEnabled\"\n class=\"splitToolbarButton right\">\n <button id=\"addBookmark\"\n class=\"toolbarButton addBookmark\"\n (click)=\"onAddBookmarkClick()\"\n title=\"Add bookmark\" tabindex=\"3\" data-l10n-id=\"addBookmark\">\n <span data-l10n-id=\"addBookmark_label\">Add bookmark</span>\n </button>\n </div>\n</div>\n<div id=\"sidebarContent\">\n <div id=\"outlineView\" class=\"outlineWithDeepNesting\">\n <div class=\"outlineItem\" *ngIf=\"selectedView === 'outline'\">\n <mv-outline-item *ngFor=\"let outlineItem of outline; index as i\"\n [outline]=\"outlineItem\"\n [currentPageNumber]=\"currentPageNumber\"\n [isCurrentSection]= \"isViewedItem(outlineItem, outline[i+1])\"\n [endPage]=\"findEndPage(outline[i+1])\"\n (navigationEvent)=\"goToDestination($event)\"></mv-outline-item>\n </div>\n <div *ngIf=\"annotationsEnabled && selectedView === 'bookmarks'\"\n id=\"bookmarkContainer\">\n <mv-bookmarks [bookmarkNodes]=\"bookmarkNodes$ | async\"\n [zoom]=\"zoom\" [rotate]=\"rotate\"\n (goToDestination)=\"goToDestination($event)\"></mv-bookmarks>\n </div>\n </div>\n</div>\n"
5618
+ template: "<div id=\"toolbarSidebar\">\n <div *ngIf=\"annotationsEnabled && selectedView == 'bookmarks'\"\n class=\"splitToolbarButton toggled\">\n <button id=\"sortBookmarkPosition\" class=\"splitToolbarButton left bookmark__sort__position\"\n (click)=\"bookmarks.sort(bookmarks.positionSort)\" title=\"Order by place in document\"></button>\n <button id=\"sortBookmarkCustom\" class=\"splitToolbarButton left bookmark__sort__custom\"\n (click)=\"bookmarks.sort(bookmarks.customSort)\" title=\"Order manually\"></button></div>\n <div class=\"splitToolbarButtonSeparator\"></div>\n <div *ngIf=\"annotationsEnabled && selectedView == 'bookmarks'\"\n class=\"splitToolbarButton right\">\n <button id=\"addBookmark\"\n class=\"toolbarButton addBookmark\"\n (click)=\"bookmarks.onAddBookmarkClick()\"\n title=\"Add bookmark\" tabindex=\"3\" data-l10n-id=\"addBookmark\">\n <span data-l10n-id=\"addBookmark_label\">Add bookmark</span>\n </button>\n </div>\n</div>\n<div id=\"sidebarContent\">\n <div id=\"outlineView\" class=\"outlineWithDeepNesting\">\n <div class=\"outlineItem\" *ngIf=\"selectedView === 'outline'\">\n <mv-outline-item *ngFor=\"let outlineItem of outline; index as i\"\n [outline]=\"outlineItem\"\n [currentPageNumber]=\"currentPageNumber\"\n [isCurrentSection]= \"isViewedItem(outlineItem, outline[i+1])\"\n [endPage]=\"findEndPage(outline[i+1])\"\n (navigationEvent)=\"goToDestination($event)\"></mv-outline-item>\n </div>\n <div *ngIf=\"annotationsEnabled && selectedView === 'bookmarks'\"\n id=\"bookmarkContainer\">\n <mv-bookmarks [bookmarkNodes]=\"bookmarkNodes$ | async\"\n [zoom]=\"zoom\" [rotate]=\"rotate\"\n (goToDestination)=\"goToDestination($event)\"></mv-bookmarks>\n </div>\n </div>\n</div>\n"
5153
5619
  },] }
5154
5620
  ];
5155
5621
  /** @nocollapse */
5156
5622
  SideBarComponent.ctorParameters = () => [
5157
5623
  { type: ViewerEventService },
5158
- { type: Store }
5624
+ { type: Store },
5625
+ { type: ToolbarEventService }
5159
5626
  ];
5160
5627
  SideBarComponent.propDecorators = {
5161
5628
  annotationsEnabled: [{ type: Input }],
@@ -5163,7 +5630,8 @@ SideBarComponent.propDecorators = {
5163
5630
  url: [{ type: Input }],
5164
5631
  zoom: [{ type: Input }],
5165
5632
  rotate: [{ type: Input }],
5166
- currentPageNumber: [{ type: Input }]
5633
+ currentPageNumber: [{ type: Input }],
5634
+ bookmarks: [{ type: ViewChild, args: [BookmarksComponent,] }]
5167
5635
  };
5168
5636
 
5169
5637
  class OutlineItemComponent {
@@ -5182,6 +5650,9 @@ class OutlineItemComponent {
5182
5650
  this.showOutlineItems = !this.showOutlineItems;
5183
5651
  }
5184
5652
  isViewedItem(current, next) {
5653
+ if (current.pageNumber === this.currentPageNumber) {
5654
+ return true;
5655
+ }
5185
5656
  return next === undefined ? current.pageNumber <= this.currentPageNumber && this.endPage > this.currentPageNumber :
5186
5657
  current.pageNumber <= this.currentPageNumber && (next.pageNumber > this.currentPageNumber);
5187
5658
  }
@@ -5244,7 +5715,7 @@ class RedactionComponent {
5244
5715
  this.toolbarEvents.drawModeSubject.next(false);
5245
5716
  }
5246
5717
  saveRedaction(page, rectangles) {
5247
- const redaction = { page, rectangles, redactionId: uuid$1(), documentId: this.documentId };
5718
+ const redaction = { page, rectangles, redactionId: v4(), documentId: this.documentId };
5248
5719
  this.store.dispatch(new SaveRedaction(redaction));
5249
5720
  }
5250
5721
  onMarkerDelete(event) {
@@ -5420,6 +5891,7 @@ class RedactionApiService {
5420
5891
  this.httpClient = httpClient;
5421
5892
  this.markupsApiUrl = '/api/markups';
5422
5893
  this.redactApiUrl = '/api/redaction';
5894
+ this.markupsSearchApiUrl = '/api/markups/search';
5423
5895
  }
5424
5896
  getRedactions(documentId) {
5425
5897
  const fixedUrl = `${this.markupsApiUrl}/${documentId}`;
@@ -5431,6 +5903,11 @@ class RedactionApiService {
5431
5903
  .post(this.markupsApiUrl, body, { observe: 'response', withCredentials: true })
5432
5904
  .pipe(map(response => response.body), catchError(() => []));
5433
5905
  }
5906
+ saveBulkRedaction(body) {
5907
+ return this.httpClient
5908
+ .post(this.markupsSearchApiUrl, body, { observe: 'response', withCredentials: true })
5909
+ .pipe(map(response => response.body), catchError(() => []));
5910
+ }
5434
5911
  deleteRedaction(payload) {
5435
5912
  const url = `${this.markupsApiUrl}/${payload.documentId}/${payload.redactionId}`;
5436
5913
  return this.httpClient
@@ -5458,9 +5935,10 @@ RedactionApiService.ctorParameters = () => [
5458
5935
  ];
5459
5936
 
5460
5937
  class RedactionEffects {
5461
- constructor(actions$, redactionApiService) {
5938
+ constructor(actions$, redactionApiService, toolbarEvents) {
5462
5939
  this.actions$ = actions$;
5463
5940
  this.redactionApiService = redactionApiService;
5941
+ this.toolbarEvents = toolbarEvents;
5464
5942
  this.loadRedactions$ = this.actions$.pipe(ofType(LOAD_REDACTIONS), map((action) => action.payload), switchMap((documentId) => {
5465
5943
  return this.redactionApiService.getRedactions(documentId).pipe(map(resp => {
5466
5944
  return new LoadRedactionSuccess(resp.body);
@@ -5475,6 +5953,13 @@ class RedactionEffects {
5475
5953
  return of(new SaveRedactionFailure(error));
5476
5954
  }));
5477
5955
  }));
5956
+ this.saveBulkRedaction$ = this.actions$.pipe(ofType(SAVE_BULK_REDACTION), map((action) => action.payload), exhaustMap((redaction) => {
5957
+ return this.redactionApiService.saveBulkRedaction(redaction).pipe(tap(() => this.toolbarEvents.redactAllInProgressSubject.next(false))).pipe(map(resp => {
5958
+ return new SaveBulkRedactionSuccess(resp);
5959
+ }), catchError(error => {
5960
+ return of(new SaveBulkRedactionFailure(error));
5961
+ }));
5962
+ }));
5478
5963
  this.deleteRedaction$ = this.actions$.pipe(ofType(DELETE_REDACTION), map((action) => action.payload), exhaustMap((redactionPayload) => {
5479
5964
  return this.redactionApiService.deleteRedaction(redactionPayload).pipe(map(() => {
5480
5965
  return new DeleteRedactionSuccess(redactionPayload);
@@ -5507,7 +5992,8 @@ RedactionEffects.decorators = [
5507
5992
  /** @nocollapse */
5508
5993
  RedactionEffects.ctorParameters = () => [
5509
5994
  { type: Actions },
5510
- { type: RedactionApiService }
5995
+ { type: RedactionApiService },
5996
+ { type: ToolbarEventService }
5511
5997
  ];
5512
5998
  __decorate([
5513
5999
  Effect(),
@@ -5517,6 +6003,10 @@ __decorate([
5517
6003
  Effect(),
5518
6004
  __metadata("design:type", Object)
5519
6005
  ], RedactionEffects.prototype, "saveRedaction$", void 0);
6006
+ __decorate([
6007
+ Effect(),
6008
+ __metadata("design:type", Object)
6009
+ ], RedactionEffects.prototype, "saveBulkRedaction$", void 0);
5520
6010
  __decorate([
5521
6011
  Effect(),
5522
6012
  __metadata("design:type", Object)
@@ -5656,114 +6146,6 @@ __decorate([
5656
6146
 
5657
6147
  const effects = [AnnotationEffects, BookmarksEffects, RedactionEffects, DocumentEffects, IcpEffects];
5658
6148
 
5659
- class BookmarksComponent {
5660
- constructor(store) {
5661
- this.store = store;
5662
- this.goToDestination = new EventEmitter();
5663
- this.pageLookup = {};
5664
- this.BOOKMARK_CHAR_LIMIT = 30;
5665
- this.options = {
5666
- allowDrag: true,
5667
- allowDrop: true
5668
- };
5669
- }
5670
- ngOnInit() {
5671
- this.$subscription = this.store.pipe(select(getEditableBookmark))
5672
- .subscribe(editableId => this.editableBookmark = editableId);
5673
- this.$subscription.add(this.store.select(getPages)
5674
- .subscribe(pages => {
5675
- Object.keys(pages).map(key => {
5676
- this.pageLookup[key] = pages[key];
5677
- });
5678
- }));
5679
- }
5680
- ngOnDestroy() {
5681
- this.$subscription.unsubscribe();
5682
- }
5683
- editBookmark(id) {
5684
- this.editableBookmark = id;
5685
- }
5686
- onBookmarkMove({ node, from, to }) {
5687
- let movedBookmarks = [Object.assign(Object.assign({}, node), { previous: to.index > 0 ? to.parent.children[to.index - 1].id : undefined, parent: to.parent.documentId ? to.parent.id : undefined })];
5688
- let fromNext = this.getSibling(from, from.index);
5689
- fromNext = fromNext && fromNext.id === node.previous ? this.getSibling(from, from.index + 1) : fromNext;
5690
- if (fromNext) {
5691
- movedBookmarks = [...movedBookmarks, Object.assign(Object.assign({}, fromNext), { previous: node.previous })];
5692
- }
5693
- const toNext = this.getSibling(to, to.index + 1);
5694
- if (toNext) {
5695
- movedBookmarks = [...movedBookmarks, Object.assign(Object.assign({}, toNext), { previous: node.id })];
5696
- }
5697
- this.store.dispatch(new MoveBookmark(movedBookmarks));
5698
- }
5699
- deleteBookmark(node) {
5700
- let next;
5701
- const siblings = node.parent.children;
5702
- if (siblings.length > node.index + 1) {
5703
- next = siblings[node.index + 1].data;
5704
- next.previous = node.data.previous;
5705
- }
5706
- this.store.dispatch(new DeleteBookmark({
5707
- deleted: [node.data.id, ...getBookmarkChildren(node.data.children)], updated: next
5708
- }));
5709
- }
5710
- updateBookmark(bookmark, name) {
5711
- const editedBookmark = Object.assign(Object.assign({}, bookmark), { name });
5712
- if (name) {
5713
- this.store.dispatch(new UpdateBookmark(editedBookmark));
5714
- this.editableBookmark = undefined;
5715
- }
5716
- }
5717
- goToBookmark(bookmark) {
5718
- const thisPage = this.pageLookup[bookmark.pageNumber + 1];
5719
- const defaultHeight = thisPage.styles.height;
5720
- const defaultScaleY = this.scaledY(bookmark.yCoordinate, defaultHeight, thisPage);
5721
- let top = 0, left = 0;
5722
- switch (this.rotate) {
5723
- case 90:
5724
- left = -defaultScaleY;
5725
- break;
5726
- case 180:
5727
- top = this.scaledY(bookmark.yCoordinate, (defaultHeight - (24 * this.zoom)), thisPage);
5728
- break;
5729
- case 270:
5730
- left = defaultScaleY;
5731
- break;
5732
- default:
5733
- top = defaultScaleY;
5734
- }
5735
- this.goToDestination.emit([
5736
- bookmark.pageNumber,
5737
- { 'name': 'XYZ' },
5738
- left,
5739
- top
5740
- ]);
5741
- }
5742
- getSibling(node, index) {
5743
- return node.parent.children.length > index ? node.parent.children[index] : undefined;
5744
- }
5745
- scaledY(yCoordinate, height, page) {
5746
- const viewportScale = page.viewportScale / this.zoom;
5747
- return ((height / this.zoom) - yCoordinate) / viewportScale;
5748
- }
5749
- }
5750
- BookmarksComponent.decorators = [
5751
- { type: Component, args: [{
5752
- selector: 'mv-bookmarks',
5753
- template: "<tree-root [nodes]=\"bookmarkNodes\"\n class=\"bookmarks-tree\"\n [options]=\"options\"\n (moveNode)=\"onBookmarkMove($event)\">\n <ng-template #treeNodeTemplate let-node let-index=\"index\">\n <div class=\"outlineItem\" *ngIf=\"node.data.id !== editableBookmark; else inputBookmark\">\n <a (click)=\"goToBookmark(node.data)\">\n {{ node.data.name }}\n </a>\n <button class=\"bookmark__rename\" (click)=\"editBookmark(node.data.id)\" ></button>\n <button class=\"bookmark__delete\" (click)=\"deleteBookmark(node)\"></button>\n </div>\n <ng-template #inputBookmark>\n <input #bookmarkName class=\"bookmark__input\" [value]=\"node.data.name\" [maxLength]=\"BOOKMARK_CHAR_LIMIT\">\n <button class=\"bookmark__save\" (click)=\"updateBookmark(node.data, bookmarkName.value)\"></button>\n </ng-template>\n <a *ngIf=\"bookmarkNodes?.length === 0\" class=\"outlineItem\">No bookmarks created yet</a>\n </ng-template>\n</tree-root>\n"
5754
- },] }
5755
- ];
5756
- /** @nocollapse */
5757
- BookmarksComponent.ctorParameters = () => [
5758
- { type: Store }
5759
- ];
5760
- BookmarksComponent.propDecorators = {
5761
- bookmarkNodes: [{ type: Input }],
5762
- zoom: [{ type: Input }],
5763
- rotate: [{ type: Input }],
5764
- goToDestination: [{ type: Output }]
5765
- };
5766
-
5767
6149
  class ConvertibleContentViewerComponent {
5768
6150
  constructor(store) {
5769
6151
  this.store = store;
@@ -6032,7 +6414,7 @@ class HighlightCreateDirective {
6032
6414
  const top = rect.top - parentRect.top;
6033
6415
  const left = rect.left - parentRect.left;
6034
6416
  let rectangle = this.highlightService.applyRotation(this.pageHeight, this.pageWidth, height, width, top, left, this.rotate, this.zoom);
6035
- rectangle = Object.assign({ id: uuid$1() }, rectangle);
6417
+ rectangle = Object.assign({ id: v4() }, rectangle);
6036
6418
  return rectangle;
6037
6419
  }
6038
6420
  removeEnhancedTextModeStyling(element) {
@@ -6186,5 +6568,5 @@ MediaViewerModule.decorators = [
6186
6568
  * Generated bundle index. Do not edit.
6187
6569
  */
6188
6570
 
6189
- export { ADD_OR_EDIT_COMMENT, APPLY_COMMENT_SUMMARY_FILTER, AddOrEditComment, AnnotationApiService, AnnotationEffects, AnnotationSetComponent, AnnotationViewComponent, AnnotationsModule, ApplyCommentSymmaryFilter, BoxHighlightCreateComponent, CLEAR_COMMENT_SUMMARY_FILTER, ClearCommentSummaryFilters, CommentFilterComponent, CommentSearchComponent, CommentSetComponent, CommentSetHeaderComponent, CommentsSummaryComponent, DELETE_ANNOTATION, DELETE_ANNOTATION_FAIL, DELETE_ANNOTATION_SUCCESS, DeleteAnnotation, DeleteAnnotationFail, DeleteAnnotationSuccess, FilterPipe, IcpToolbarComponent, LOAD_ANNOTATION_SET, LOAD_ANNOTATION_SET_FAIL, LOAD_ANNOTATION_SET_SUCCESS, LoadAnnotationSet, LoadAnnotationSetFail, LoadAnnotationSetSucess, MainToolbarComponent, MediaViewerComponent, MediaViewerModule, MetadataLayerComponent, MomentDatePipe, RedactionToolbarComponent, ResponseType, SAVE_ANNOTATION, SAVE_ANNOTATION_FAIL, SAVE_ANNOTATION_SUCCESS, SEARCH_COMMENT, SELECT_ANNOTATION, SaveAnnotation, SaveAnnotationFail, SaveAnnotationSuccess, SearchBarComponent, SearchComment, SelectedAnnotation, TagsComponent, ToolbarButtonVisibilityService, ToolbarEventService, ToolbarModule, UnsnakePipe, ViewerException, commentSearchQ, getAnnoEnt, getAnnoPageEnt, getAnnoPerPage, getAnnoSet, getAnnotationEntities, getAnnotationSet, getAnnotationsSetState, getCommentEntities, getCommentEnts, getCommentSummary, getCommentSummaryFilters, getCommentsArray, getComponentSearchQueries, getComponentSearchText, getDocumentIdSetId, getFilteredAnnotations, getPageEntities, getSelectedAnno, getSelectedAnnotation, getSet, getSummaryFilters, initialState, reducer, ɵ0$2 as ɵ0, ɵ1$2 as ɵ1, ɵ2$2 as ɵ2, ɵ3$1 as ɵ3, ɵ4, ɵ5, ɵ6, ɵ7, NumberHelperService as ɵa, TextHighlightDirective as ɵba, CtxToolbarComponent as ɵbb, CommentSetRenderService as ɵbc, CommentsNavigateComponent as ɵbd, TextareaAutoExpandDirective as ɵbe, PrintService as ɵbf, BookmarksApiService as ɵbg, effects as ɵbh, BookmarksEffects as ɵbi, RedactionEffects as ɵbj, RedactionApiService as ɵbk, DocumentEffects as ɵbl, DocumentConversionApiService as ɵbm, RotationApiService as ɵbn, IcpEffects as ɵbo, IcpSessionApiService as ɵbp, IcpUpdateService as ɵbq, SocketService as ɵbr, PdfViewerComponent as ɵbs, PdfJsWrapperFactory as ɵbt, IcpService as ɵbu, IcpPresenterService as ɵbv, IcpFollowerService as ɵbw, SideBarComponent as ɵbx, BookmarksComponent as ɵby, OutlineItemComponent as ɵbz, reducers as ɵc, ImageViewerComponent as ɵca, ViewerUtilService as ɵcb, UnsupportedViewerComponent as ɵcc, MultimediaPlayerComponent as ɵcd, ConvertibleContentViewerComponent as ɵce, GrabNDragDirective as ɵcf, RotationPersistDirective as ɵcg, HighlightCreateDirective as ɵch, ConfirmActionDialogComponent as ɵci, RedactionComponent as ɵcj, BookmarkIconsComponent as ɵck, ParticipantsListComponent as ɵcl, getDocumentState as ɵcm, getPages as ɵcn, getTagsRootState as ɵco, getTagFiltered as ɵcp, getFilteredPageEntities as ɵcq, getMVState as ɵd, docReducer as ɵf, getDocPages as ɵg, tagsReducer as ɵh, getFilteredComments as ɵi, getFilteredPageEnt as ɵj, bookmarksReducer as ɵl, redactionReducer as ɵm, icpReducer as ɵn, SharedModule as ɵp, GovUkDateComponent as ɵq, GovUkErrorMessageComponent as ɵr, GovUkFieldsetComponent as ɵs, GovUkLabelComponent as ɵt, HighlightCreateService as ɵu, ViewerEventService as ɵv, CommentService as ɵw, RectangleComponent as ɵx, CommentComponent as ɵy, TagsServices as ɵz };
6571
+ export { ADD_OR_EDIT_COMMENT, APPLY_COMMENT_SUMMARY_FILTER, AddOrEditComment, AnnotationApiService, AnnotationEffects, AnnotationSetComponent, AnnotationViewComponent, AnnotationsModule, ApplyCommentSymmaryFilter, BoxHighlightCreateComponent, CLEAR_COMMENT_SUMMARY_FILTER, ClearCommentSummaryFilters, CommentFilterComponent, CommentSearchComponent, CommentSetComponent, CommentSetHeaderComponent, CommentsSummaryComponent, DELETE_ANNOTATION, DELETE_ANNOTATION_FAIL, DELETE_ANNOTATION_SUCCESS, DeleteAnnotation, DeleteAnnotationFail, DeleteAnnotationSuccess, FilterPipe, IcpToolbarComponent, LOAD_ANNOTATION_SET, LOAD_ANNOTATION_SET_FAIL, LOAD_ANNOTATION_SET_SUCCESS, LoadAnnotationSet, LoadAnnotationSetFail, LoadAnnotationSetSucess, MainToolbarComponent, MediaViewerComponent, MediaViewerModule, MetadataLayerComponent, MomentDatePipe, RedactionToolbarComponent, ResponseType, SAVE_ANNOTATION, SAVE_ANNOTATION_FAIL, SAVE_ANNOTATION_SUCCESS, SEARCH_COMMENT, SELECT_ANNOTATION, SaveAnnotation, SaveAnnotationFail, SaveAnnotationSuccess, SearchBarComponent, SearchComment, SelectedAnnotation, TagsComponent, ToolbarButtonVisibilityService, ToolbarEventService, ToolbarModule, UnsnakePipe, ViewerException, commentSearchQ, getAnnoEnt, getAnnoPageEnt, getAnnoPerPage, getAnnoSet, getAnnotationEntities, getAnnotationSet, getAnnotationsSetState, getCommentEntities, getCommentEnts, getCommentSummary, getCommentSummaryFilters, getCommentsArray, getComponentSearchQueries, getComponentSearchText, getDocumentIdSetId, getFilteredAnnotations, getPageEntities, getSelectedAnno, getSelectedAnnotation, getSet, getSummaryFilters, initialState, reducer, ɵ0$2 as ɵ0, ɵ1$2 as ɵ1, ɵ2$2 as ɵ2, ɵ3$1 as ɵ3, ɵ4, ɵ5, ɵ6, ɵ7, NumberHelperService as ɵa, TagsServices as ɵba, TextHighlightDirective as ɵbb, CtxToolbarComponent as ɵbc, CommentSetRenderService as ɵbd, CommentsNavigateComponent as ɵbe, TextareaAutoExpandDirective as ɵbf, PrintService as ɵbg, BookmarksApiService as ɵbh, effects as ɵbi, BookmarksEffects as ɵbj, RedactionEffects as ɵbk, RedactionApiService as ɵbl, DocumentEffects as ɵbm, DocumentConversionApiService as ɵbn, RotationApiService as ɵbo, IcpEffects as ɵbp, IcpSessionApiService as ɵbq, IcpUpdateService as ɵbr, SocketService as ɵbs, PdfViewerComponent as ɵbt, PdfJsWrapperFactory as ɵbu, IcpService as ɵbv, IcpPresenterService as ɵbw, IcpFollowerService as ɵbx, SideBarComponent as ɵby, BookmarksComponent as ɵbz, reducers as ɵc, OutlineItemComponent as ɵca, ImageViewerComponent as ɵcb, ViewerUtilService as ɵcc, UnsupportedViewerComponent as ɵcd, MultimediaPlayerComponent as ɵce, ConvertibleContentViewerComponent as ɵcf, GrabNDragDirective as ɵcg, RotationPersistDirective as ɵch, HighlightCreateDirective as ɵci, ConfirmActionDialogComponent as ɵcj, RedactionComponent as ɵck, BookmarkIconsComponent as ɵcl, ParticipantsListComponent as ɵcm, getDocumentState as ɵcn, getPages as ɵco, getTagsRootState as ɵcp, getTagFiltered as ɵcq, getFilteredPageEntities as ɵcr, getMVState as ɵd, docReducer as ɵf, getDocPages as ɵg, tagsReducer as ɵh, getFilteredComments as ɵi, getFilteredPageEnt as ɵj, bookmarksReducer as ɵl, redactionReducer as ɵm, icpReducer as ɵn, RedactionSearchBarComponent as ɵp, HighlightCreateService as ɵq, SharedModule as ɵr, GovUkDateComponent as ɵs, GovUkErrorMessageComponent as ɵt, GovUkFieldsetComponent as ɵu, GovUkLabelComponent as ɵv, ViewerEventService as ɵw, CommentService as ɵx, RectangleComponent as ɵy, CommentComponent as ɵz };
6190
6572
  //# sourceMappingURL=hmcts-media-viewer.js.map