diff --git a/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts b/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts index e4950489e..c6c2e6cc2 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts @@ -11,7 +11,7 @@ import { SimpleChanges, ViewChild, } from '@angular/core'; -import { Dossier, File, IHeaderElement, IManualRedactionEntry } from '@red/domain'; +import { Dossier, File, IHeaderElement, IManualRedactionEntry, RotationType } from '@red/domain'; import { Core, WebViewerInstance } from '@pdftron/webviewer'; import { TranslateService } from '@ngx-translate/core'; import { @@ -353,8 +353,24 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha const closeCompareFn = async () => { await this._closeCompareMode(); }; + const addRotation = (type: RotationType) => { + this._pageRotationService.addRotation(type); + }; + const applyRotation = async () => { + await this._pageRotationService.applyRotation(); + }; + const discardRotation = () => { + this._pageRotationService.discardRotation(); + }; - this._headerConfigService.initialize(toggleTooltipsFn, this.compareFileInput, closeCompareFn); + this._headerConfigService.initialize( + toggleTooltipsFn, + this.compareFileInput, + closeCompareFn, + addRotation, + applyRotation, + discardRotation, + ); const dossierTemplateId = this.dossier.dossierTemplateId; @@ -514,7 +530,6 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha HeaderElements.SHAPE_TOOL_GROUP_BUTTON, HeaderElements.ROTATE_LEFT_BUTTON, HeaderElements.ROTATE_RIGHT_BUTTON, - HeaderElements.ANNOTATION_POPUP, ]; const isCurrentPageExcluded = this.pdf.isCurrentPageExcluded(await this.stateService.file); @@ -540,7 +555,6 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha if (isCurrentPageExcluded) { const allowedActionsWhenPageExcluded: string[] = [ - HeaderElements.ANNOTATION_POPUP, TextPopups.ADD_RECTANGLE, TextPopups.ADD_REDACTION, HeaderElements.SHAPE_TOOL_GROUP_BUTTON, diff --git a/apps/red-ui/src/app/modules/file-preview/services/page-rotation.service.ts b/apps/red-ui/src/app/modules/file-preview/services/page-rotation.service.ts index 1ed4f7332..df276d163 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/page-rotation.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/page-rotation.service.ts @@ -16,9 +16,10 @@ import { } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { MatDialog } from '@angular/material/dialog'; +import { ViewerHeaderConfigService } from './viewer-header-config.service'; -const actionButtons = [HeaderElements.APPLY_ROTATION, HeaderElements.DISCARD_ROTATION]; -const oneRotationDegree = 90; +const ACTION_BUTTONS = [HeaderElements.APPLY_ROTATION, HeaderElements.DISCARD_ROTATION]; +const ONE_ROTATION_DEGREE = 90; @Injectable() export class PageRotationService { @@ -31,6 +32,7 @@ export class PageRotationService { private readonly _screenState: FilePreviewStateService, private readonly _permissionsService: PermissionsService, private readonly _fileManagementService: FileManagementService, + private readonly _headerConfigService: ViewerHeaderConfigService, ) {} isRotated(page: number) { @@ -58,7 +60,7 @@ export class PageRotationService { const rotations = this.#rotations$.value; for (const page of Object.keys(rotations)) { - const times = rotations[page] / oneRotationDegree; + const times = rotations[page] / ONE_ROTATION_DEGREE; for (let i = 1; i <= times; i++) { this._pdf?.documentViewer?.rotateCounterClockwise(Number(page)); } @@ -116,14 +118,11 @@ export class PageRotationService { return this.hasRotations() ? this.showConfirmationDialog() : of(ConfirmOptions.DISCARD_CHANGES); } - // TODO: Ideally, enabling/disabling buttons should be done through ViewerHeaderConfigService, not through _pdf.UI, - // but circular dependencies =D - #showActionButtons() { - this._pdf.UI.enableElements(actionButtons); + this._headerConfigService.enable(ACTION_BUTTONS); } #hideActionButtons() { - this._pdf.UI.disableElements(actionButtons); + this._headerConfigService.disable(ACTION_BUTTONS); } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/viewer-header-config.service.ts b/apps/red-ui/src/app/modules/file-preview/services/viewer-header-config.service.ts index 9d62c4056..51a79e3bd 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/viewer-header-config.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/viewer-header-config.service.ts @@ -1,8 +1,7 @@ import { ElementRef, Inject, Injectable } from '@angular/core'; -import { IHeaderElement, RotationTypes } from '@red/domain'; +import { IHeaderElement, RotationType, RotationTypes } from '@red/domain'; import { HeaderElements, HeaderElementType } from '../shared/constants'; import { TranslateService } from '@ngx-translate/core'; -import { PageRotationService } from './page-rotation.service'; import { BASE_HREF } from '../../../tokens'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { UserPreferenceService } from '@services/user-preference.service'; @@ -16,68 +15,22 @@ export class ViewerHeaderConfigService { private _buttons: Map; private _config: Map = new Map([ [HeaderElements.SHAPE_TOOL_GROUP_BUTTON, true], - [HeaderElements.ROTATE_LEFT_BUTTON, true], - [HeaderElements.ROTATE_RIGHT_BUTTON, true], - [HeaderElements.APPLY_ROTATION, true], - [HeaderElements.DISCARD_ROTATION, true], [HeaderElements.TOGGLE_TOOLTIPS, true], - [HeaderElements.ANNOTATION_POPUP, true], [HeaderElements.COMPARE_BUTTON, true], [HeaderElements.CLOSE_COMPARE_BUTTON, false], + [HeaderElements.ROTATE_LEFT_BUTTON, true], + [HeaderElements.ROTATE_RIGHT_BUTTON, true], + [HeaderElements.APPLY_ROTATION, false], + [HeaderElements.DISCARD_ROTATION, false], ]); constructor( @Inject(BASE_HREF) private readonly _baseHref: string, private readonly _translateService: TranslateService, - private readonly _pageRotationService: PageRotationService, private readonly _userPreferenceService: UserPreferenceService, private readonly _pdfViewer: PdfViewer, ) {} - private get _applyRotation(): IHeaderElement { - return { - type: 'customElement', - dataElement: HeaderElements.APPLY_ROTATION, - render: () => { - const paragraph = document.createElement('p'); - paragraph.innerText = this._translateService.instant('page-rotation.apply'); - paragraph.style.cssText = ` - font-size: 11px; - font-weight: 600; - color: #DD4D50; - cursor: pointer; - margin: 0 12px; - `; - paragraph.addEventListener('click', async () => { - await this._pageRotationService.applyRotation(); - }); - return paragraph; - }, - }; - } - - private get _discardRotation(): IHeaderElement { - return { - type: 'customElement', - dataElement: HeaderElements.DISCARD_ROTATION, - render: () => { - const paragraph = document.createElement('p'); - paragraph.innerText = this._translateService.instant('page-rotation.discard'); - paragraph.style.cssText = ` - font-size: 11px; - font-weight: 600; - color: #283241; - cursor: pointer; - opacity: 0.7; - `; - paragraph.addEventListener('click', () => { - this._pageRotationService.discardRotation(); - }); - return paragraph; - }, - }; - } - private get _rectangle(): IHeaderElement { return { type: 'toolGroupButton', @@ -88,26 +41,6 @@ export class ViewerHeaderConfigService { }; } - private get _rotateLeft(): IHeaderElement { - return { - type: 'actionButton', - element: 'tooltips', - dataElement: HeaderElements.ROTATE_LEFT_BUTTON, - img: this._convertPath('/assets/icons/general/rotate-left.svg'), - onClick: () => this._pageRotationService.addRotation(RotationTypes.LEFT), - }; - } - - private get _rotateRight(): IHeaderElement { - return { - type: 'actionButton', - element: 'tooltips', - dataElement: HeaderElements.ROTATE_RIGHT_BUTTON, - img: this._convertPath('/assets/icons/general/rotate-right.svg'), - onClick: () => this._pageRotationService.addRotation(RotationTypes.RIGHT), - }; - } - private get _toggleTooltipsBtnTitle(): string { return this._translateService.instant(_('pdf-viewer.toggle-tooltips'), { active: this._userPreferenceService.getFilePreviewTooltipsPreference(), @@ -126,6 +59,9 @@ export class ViewerHeaderConfigService { toggleTooltips: (title: string, img: string) => Promise, compareFileInput: ElementRef, closeCompareMode: () => Promise, + addRotation: (type: RotationType) => void, + applyRotation: () => Promise, + discardRotation: () => void, ): void { if (this._buttons) { console.error('ERROR: ViewerHeaderConfigService can only be initialized once!'); @@ -134,10 +70,10 @@ export class ViewerHeaderConfigService { this._buttons = new Map([ [HeaderElements.SHAPE_TOOL_GROUP_BUTTON, this._rectangle], - [HeaderElements.ROTATE_LEFT_BUTTON, this._rotateLeft], - [HeaderElements.ROTATE_RIGHT_BUTTON, this._rotateRight], - [HeaderElements.APPLY_ROTATION, this._applyRotation], - [HeaderElements.DISCARD_ROTATION, this._discardRotation], + [HeaderElements.ROTATE_LEFT_BUTTON, this._rotateLeft(addRotation)], + [HeaderElements.ROTATE_RIGHT_BUTTON, this._rotateRight(addRotation)], + [HeaderElements.APPLY_ROTATION, this._applyRotation(applyRotation)], + [HeaderElements.DISCARD_ROTATION, this._discardRotation(discardRotation)], [HeaderElements.TOGGLE_TOOLTIPS, this._toggleTooltips(toggleTooltips)], [HeaderElements.COMPARE_BUTTON, this._compare(compareFileInput)], [HeaderElements.CLOSE_COMPARE_BUTTON, this._closeCompare(closeCompareMode)], @@ -154,6 +90,68 @@ export class ViewerHeaderConfigService { this._updateState(elements, false); } + private _applyRotation(applyRotation: () => Promise): IHeaderElement { + return { + type: 'customElement', + dataElement: HeaderElements.APPLY_ROTATION, + render: () => { + const paragraph = document.createElement('p'); + paragraph.innerText = this._translateService.instant('page-rotation.apply'); + paragraph.style.cssText = ` + font-size: 11px; + font-weight: 600; + color: #DD4D50; + cursor: pointer; + margin: 0 12px; + `; + paragraph.addEventListener('click', async () => { + await applyRotation(); + }); + return paragraph; + }, + }; + } + + private _discardRotation(discardRotation: () => void): IHeaderElement { + return { + type: 'customElement', + dataElement: HeaderElements.DISCARD_ROTATION, + render: () => { + const paragraph = document.createElement('p'); + paragraph.innerText = this._translateService.instant('page-rotation.discard'); + paragraph.style.cssText = ` + font-size: 11px; + font-weight: 600; + color: #283241; + cursor: pointer; + opacity: 0.7; + `; + paragraph.addEventListener('click', () => discardRotation()); + return paragraph; + }, + }; + } + + private _rotateLeft(addRotation: (type: RotationType) => void): IHeaderElement { + return { + type: 'actionButton', + element: 'tooltips', + dataElement: HeaderElements.ROTATE_LEFT_BUTTON, + img: this._convertPath('/assets/icons/general/rotate-left.svg'), + onClick: () => addRotation(RotationTypes.LEFT), + }; + } + + private _rotateRight(addRotation: (type: RotationType) => void): IHeaderElement { + return { + type: 'actionButton', + element: 'tooltips', + dataElement: HeaderElements.ROTATE_RIGHT_BUTTON, + img: this._convertPath('/assets/icons/general/rotate-right.svg'), + onClick: () => addRotation(RotationTypes.RIGHT), + }; + } + private _toggleTooltips(toggleTooltips: (title: string, img: string) => Promise): IHeaderElement { return { type: 'actionButton', diff --git a/apps/red-ui/src/app/modules/file-preview/shared/constants.ts b/apps/red-ui/src/app/modules/file-preview/shared/constants.ts index 2826adb84..75e87885e 100644 --- a/apps/red-ui/src/app/modules/file-preview/shared/constants.ts +++ b/apps/red-ui/src/app/modules/file-preview/shared/constants.ts @@ -9,7 +9,6 @@ export type HeaderElementType = | 'APPLY_ROTATION' | 'DISCARD_ROTATION' | 'TOGGLE_TOOLTIPS' - | 'ANNOTATION_POPUP' | 'COMPARE_BUTTON' | 'CLOSE_COMPARE_BUTTON'; @@ -20,7 +19,6 @@ export const HeaderElements: Record = { APPLY_ROTATION: 'APPLY_ROTATION', DISCARD_ROTATION: 'DISCARD_ROTATION', TOGGLE_TOOLTIPS: 'TOGGLE_TOOLTIPS', - ANNOTATION_POPUP: 'ANNOTATION_POPUP', COMPARE_BUTTON: 'COMPARE_BUTTON', CLOSE_COMPARE_BUTTON: 'CLOSE_COMPARE_BUTTON', } as const;