From 5f252583f659c986b4408edca57740ed4d16cba7 Mon Sep 17 00:00:00 2001 From: Timo Bejan Date: Wed, 16 Aug 2023 13:43:07 +0300 Subject: [PATCH] RED-7158-2 layer service --- .../modules/file-preview/utils/constants.ts | 1 + .../modules/pdf-viewer/pdf-viewer.module.ts | 2 + .../services/annotation-draw.service.ts | 22 +------- .../services/document-viewer.service.ts | 8 ++- .../pdf-viewer/services/layers.service.ts | 53 +++++++++++++++++++ .../services/viewer-header.service.ts | 18 ++++++- .../services/files/file-management.service.ts | 2 +- apps/red-ui/src/app/utils/constants.ts | 8 +++ apps/red-ui/src/assets/config/config.json | 4 +- apps/red-ui/src/assets/i18n/redact/de.json | 3 +- apps/red-ui/src/assets/i18n/redact/en.json | 3 +- apps/red-ui/src/assets/i18n/scm/de.json | 3 +- apps/red-ui/src/assets/i18n/scm/en.json | 3 +- .../general/pdftron-action-disable-layers.svg | 12 +++++ .../general/pdftron-action-enable-layers.svg | 15 ++++++ libs/red-domain/src/lib/files/file.model.ts | 4 +- libs/red-domain/src/lib/files/file.ts | 1 + 17 files changed, 130 insertions(+), 32 deletions(-) create mode 100644 apps/red-ui/src/app/modules/pdf-viewer/services/layers.service.ts create mode 100644 apps/red-ui/src/assets/icons/general/pdftron-action-disable-layers.svg create mode 100644 apps/red-ui/src/assets/icons/general/pdftron-action-enable-layers.svg diff --git a/apps/red-ui/src/app/modules/file-preview/utils/constants.ts b/apps/red-ui/src/app/modules/file-preview/utils/constants.ts index b92d4a436..093e039e2 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/constants.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/constants.ts @@ -23,6 +23,7 @@ export const HeaderElements = { COMPARE_BUTTON: 'COMPARE_BUTTON', CLOSE_COMPARE_BUTTON: 'CLOSE_COMPARE_BUTTON', TOGGLE_TOOLTIPS: 'TOGGLE_TOOLTIPS', + TOGGLE_LAYERS: 'TOGGLE_LAYERS', TOGGLE_READABLE_REDACTIONS: 'TOGGLE_READABLE_REDACTIONS', LOAD_ALL_ANNOTATIONS: 'LOAD_ALL_ANNOTATIONS', } as const; diff --git a/apps/red-ui/src/app/modules/pdf-viewer/pdf-viewer.module.ts b/apps/red-ui/src/app/modules/pdf-viewer/pdf-viewer.module.ts index 7af623aba..27fcbc622 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/pdf-viewer.module.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/pdf-viewer.module.ts @@ -12,6 +12,7 @@ import { MatIconModule } from '@angular/material/icon'; import { AnnotationDrawService } from './services/annotation-draw.service'; import { REDDocumentViewer } from './services/document-viewer.service'; import { ReadableRedactionsService } from './services/readable-redactions.service'; +import { LayersService } from './services/layers.service'; @NgModule({ declarations: [PdfViewerComponent, CompareFileInputComponent, PaginatorComponent], @@ -23,6 +24,7 @@ import { ReadableRedactionsService } from './services/readable-redactions.servic REDAnnotationManager, PageRotationService, TooltipsService, + LayersService, ReadableRedactionsService, ViewerHeaderService, AnnotationDrawService, diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts index 152a051e0..e6e11f82c 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts @@ -4,9 +4,7 @@ import { hexToRgb } from '@utils/functions'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { UserPreferenceService } from '@users/user-preference.service'; import { RedactionLogService } from '@services/files/redaction-log.service'; - -import { IRectangle, ISectionGrid, ISectionRectangle, SuperTypes } from '@red/domain'; -import { firstValueFrom } from 'rxjs'; +import { IRectangle, ISectionRectangle, SuperTypes } from '@red/domain'; import { PdfViewer } from './pdf-viewer.service'; import { REDAnnotationManager } from './annotation-manager.service'; import { List } from '@iqser/common-ui/lib/utils'; @@ -104,24 +102,6 @@ export class AnnotationDrawService { return; } await this._annotationManager.add(annotations); - - if (this._userPreferenceService.areDevFeaturesEnabled) { - const { dossierId, fileId } = this._pdf; - const sectionsGrid$ = this._redactionLogService.getSectionGrid(dossierId, fileId); - const sectionsGrid = await firstValueFrom(sectionsGrid$).catch(() => ({ rectanglesPerPage: {} })); - await this._drawSections(sectionsGrid, dossierTemplateId); - } - } - - private async _drawSections(sectionGrid: ISectionGrid, dossierTemplateId: string) { - const sections: Core.Annotations.RectangleAnnotation[] = []; - for (const page of Object.keys(sectionGrid.rectanglesPerPage)) { - const sectionRectangles = sectionGrid.rectanglesPerPage[page]; - sectionRectangles.forEach(sectionRectangle => { - sections.push(this._computeSection(parseInt(page, 10), sectionRectangle, dossierTemplateId)); - }); - } - await this._annotationManager.add(sections); } private _computeSection(pageNumber: number, sectionRectangle: ISectionRectangle, dossierTemplateId: string) { diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/document-viewer.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/document-viewer.service.ts index 1bdeea966..d39f33fb4 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/document-viewer.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/document-viewer.service.ts @@ -134,10 +134,14 @@ export class REDDocumentViewer { } } - refreshAndUpdateView(visiblePages: number[]) { + refreshAndUpdateView(visiblePages?: number[]) { const currentPage = this.#document.getCurrentPage(); this.#document.refreshAll(); - this.#document.updateView(visiblePages, currentPage); + if (visiblePages) { + this.#document.updateView(visiblePages, currentPage); + } else { + this.#document.updateView(); + } } resetRotation(pages: number | number[] | string | string[]) { diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/layers.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/layers.service.ts new file mode 100644 index 000000000..3e6d9a62c --- /dev/null +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/layers.service.ts @@ -0,0 +1,53 @@ +import { inject, Injectable } from '@angular/core'; +import { UserPreferenceService } from '@users/user-preference.service'; +import { HeaderElements } from '../../file-preview/utils/constants'; +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { TranslateService } from '@ngx-translate/core'; +import { PdfViewer } from './pdf-viewer.service'; +import { REDDocumentViewer } from './document-viewer.service'; +import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils'; + +@Injectable() +export class LayersService { + private readonly _convertPath = inject(BASE_HREF_FN); + readonly #enableIcon = this._convertPath('/assets/icons/general/pdftron-action-enable-layers.svg'); + readonly #disableIcon = this._convertPath('/assets/icons/general/pdftron-action-disable-layers.svg'); + + private _active = false; + + constructor( + private readonly _pdf: PdfViewer, + private readonly _documentViewer: REDDocumentViewer, + private readonly _userPreferenceService: UserPreferenceService, + private readonly _translateService: TranslateService, + ) {} + + get toggleLayersBtnTitle(): string { + return this._translateService.instant(_('pdf-viewer.toggle-layers'), { + active: this._active, + }); + } + + get toggleLayersBtnIcon(): string { + const tooltipsDisabled = this._active; + return tooltipsDisabled ? this.#enableIcon : this.#disableIcon; + } + + async toggleLayers(): Promise { + const layers = await this._documentViewer.document.getLayersArray(); + layers.forEach(layer => { + if ('Layout grid' === layer.name) { + layer.visible = !this._active; + } + }); + + this._documentViewer.document.setLayersArray(layers); + this._documentViewer.refreshAndUpdateView(); + + this._active = !this._active; + this._pdf.instance.UI.updateElement(HeaderElements.TOGGLE_LAYERS, { + title: this.toggleLayersBtnTitle, + img: this.toggleLayersBtnIcon, + }); + } +} diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts index 4e9a18089..6f3b53077 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts @@ -1,9 +1,10 @@ -import { inject, Injectable, NgZone } from '@angular/core'; +import { inject, Injectable, isDevMode, NgZone } from '@angular/core'; import { IHeaderElement, RotationTypes } from '@red/domain'; import { HeaderElements, HeaderElementType } from '../../file-preview/utils/constants'; import { TranslateService } from '@ngx-translate/core'; import { getConfig, IqserPermissionsService } from '@iqser/common-ui'; import { TooltipsService } from './tooltips.service'; +import { LayersService } from './layers.service'; import { PageRotationService } from './page-rotation.service'; import { PdfViewer } from './pdf-viewer.service'; import { ROTATION_ACTION_BUTTONS, ROTATION_BUTTONS, ViewerEvents } from '../utils/constants'; @@ -29,6 +30,7 @@ export class ViewerHeaderService { readonly #config = new Map([ [HeaderElements.SHAPE_TOOL_GROUP_BUTTON, !this.#iqserPermissionService.has(Roles.getRss)], [HeaderElements.TOGGLE_TOOLTIPS, true], + [HeaderElements.TOGGLE_LAYERS, this.#isDocumine || isDevMode()], [HeaderElements.TOGGLE_READABLE_REDACTIONS, false], [HeaderElements.LOAD_ALL_ANNOTATIONS, false], [HeaderElements.COMPARE_BUTTON, !this.#isDocumine], @@ -50,6 +52,7 @@ export class ViewerHeaderService { private readonly _documentViewer: REDDocumentViewer, private readonly _rotationService: PageRotationService, private readonly _tooltipsService: TooltipsService, + private readonly _layersService: LayersService, private readonly _readableRedactionsService: ReadableRedactionsService, private readonly _ngZone: NgZone, ) { @@ -86,6 +89,17 @@ export class ViewerHeaderService { }; } + get #toggleLayers(): IHeaderElement { + return { + type: 'actionButton', + element: HeaderElements.TOGGLE_LAYERS, + dataElement: HeaderElements.TOGGLE_LAYERS, + title: this._layersService.toggleLayersBtnTitle, + img: this._layersService.toggleLayersBtnIcon, + onClick: () => this._ngZone.run(() => this._layersService.toggleLayers()), + }; + } + get #toggleReadableRedactions(): IHeaderElement { return { type: 'actionButton', @@ -228,6 +242,7 @@ export class ViewerHeaderService { [HeaderElements.APPLY_ROTATION, this.#applyRotation], [HeaderElements.DISCARD_ROTATION, this.#discardRotationButton], [HeaderElements.TOGGLE_TOOLTIPS, this.#toggleTooltips], + [HeaderElements.TOGGLE_LAYERS, this.#toggleLayers], [HeaderElements.TOGGLE_READABLE_REDACTIONS, this.#toggleReadableRedactions], [HeaderElements.LOAD_ALL_ANNOTATIONS, this.#loadAllAnnotations], [HeaderElements.COMPARE_BUTTON, this.#compare], @@ -252,6 +267,7 @@ export class ViewerHeaderService { const groups: HeaderElementType[][] = [ [HeaderElements.COMPARE_BUTTON, HeaderElements.CLOSE_COMPARE_BUTTON], [HeaderElements.TOGGLE_TOOLTIPS], + [HeaderElements.TOGGLE_LAYERS], [HeaderElements.TOGGLE_READABLE_REDACTIONS], [HeaderElements.SHAPE_TOOL_GROUP_BUTTON], [ diff --git a/apps/red-ui/src/app/services/files/file-management.service.ts b/apps/red-ui/src/app/services/files/file-management.service.ts index c8462183c..3d018fad7 100644 --- a/apps/red-ui/src/app/services/files/file-management.service.ts +++ b/apps/red-ui/src/app/services/files/file-management.service.ts @@ -40,7 +40,7 @@ export class FileManagementService extends GenericService { return this._http.request( 'get', - `/${this._serviceName}/download/original/${encodeURIComponent(dossierId)}/${encodeURIComponent(fileId)}`, + `/${this._serviceName}/download/viewer_doc/${encodeURIComponent(dossierId)}/${encodeURIComponent(fileId)}`, { responseType: 'blob', params: this._queryParams(queryParams), diff --git a/apps/red-ui/src/app/utils/constants.ts b/apps/red-ui/src/app/utils/constants.ts index b5d27cb25..3008d5309 100644 --- a/apps/red-ui/src/app/utils/constants.ts +++ b/apps/red-ui/src/app/utils/constants.ts @@ -20,4 +20,12 @@ export const UI_CACHES: DynamicCaches = [ clearOnLogout: true, methods: ['GET'], }, + { + urls: ['/download/viewer_doc'], + name: 'files', + maxAge: 3600 * 24 * 7, + maxSize: 1000, + clearOnLogout: true, + methods: ['GET'], + }, ]; diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index 9734775ed..e6703cbac 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -1,7 +1,7 @@ { "ADMIN_CONTACT_NAME": null, "ADMIN_CONTACT_URL": null, - "API_URL": "https://dan.iqser.cloud", + "API_URL": "https://kilian2.iqser.cloud", "APP_NAME": "RedactManager", "IS_DOCUMINE": false, "AUTO_READ_TIME": 3, @@ -12,7 +12,7 @@ "MAX_RETRIES_ON_SERVER_ERROR": 3, "OAUTH_CLIENT_ID": "redaction", "OAUTH_IDP_HINT": null, - "OAUTH_URL": "https://dan.iqser.cloud/auth", + "OAUTH_URL": "https://kilian2.iqser.cloud/auth", "RECENT_PERIOD_IN_HOURS": 24, "SELECTION_MODE": "structural", "MANUAL_BASE_URL": "https://docs.redactmanager.com/preview", diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index c3851bed7..424b504de 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -1927,7 +1927,8 @@ } }, "toggle-readable-redactions": "", - "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} Kurzinfos für Anmerkungen" + "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} Kurzinfos für Anmerkungen", + "toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layers" }, "permissions-screen": { "dossier": { diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 2d1e94022..ee64b58f3 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1927,7 +1927,8 @@ } }, "toggle-readable-redactions": "Show redactions {active, select, true{as in final document} false{in preview color} other{}}", - "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips" + "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips", + "toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layers" }, "permissions-screen": { "dossier": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index fd8765d0c..5a8ddd64f 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -1927,7 +1927,8 @@ } }, "toggle-readable-redactions": "", - "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} Kurzinfos für Anmerkungen" + "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} Kurzinfos für Anmerkungen", + "toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layers grid" }, "permissions-screen": { "dossier": { diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index f0835dc62..3b04cb71b 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1927,7 +1927,8 @@ } }, "toggle-readable-redactions": "Show components {active, select, true{as in final document} false{in preview color} other{}}", - "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips" + "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips", + "toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layers grid" }, "permissions-screen": { "dossier": { diff --git a/apps/red-ui/src/assets/icons/general/pdftron-action-disable-layers.svg b/apps/red-ui/src/assets/icons/general/pdftron-action-disable-layers.svg new file mode 100644 index 000000000..53c3d8a54 --- /dev/null +++ b/apps/red-ui/src/assets/icons/general/pdftron-action-disable-layers.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/apps/red-ui/src/assets/icons/general/pdftron-action-enable-layers.svg b/apps/red-ui/src/assets/icons/general/pdftron-action-enable-layers.svg new file mode 100644 index 000000000..779e9a93d --- /dev/null +++ b/apps/red-ui/src/assets/icons/general/pdftron-action-enable-layers.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/libs/red-domain/src/lib/files/file.model.ts b/libs/red-domain/src/lib/files/file.model.ts index 9892c5163..b95588c01 100644 --- a/libs/red-domain/src/lib/files/file.model.ts +++ b/libs/red-domain/src/lib/files/file.model.ts @@ -40,6 +40,7 @@ export class File extends Entity implements IFile { readonly lastOCRTime?: string; readonly softDeletedTime?: string; readonly lastProcessed?: string; + readonly lastLayoutProcessed?: string; readonly lastReviewer?: string; readonly lastApprover?: string; readonly lastUpdated?: string; @@ -106,6 +107,7 @@ export class File extends Entity implements IFile { this.lastOCRTime = file.lastOCRTime; this.softDeletedTime = file.softDeletedTime; this.lastProcessed = file.lastProcessed; + this.lastLayoutProcessed = file.lastLayoutProcessed; this.lastReviewer = file.lastReviewer; this.lastApprover = file.lastApprover; this.lastUpdated = file.lastUpdated; @@ -131,7 +133,7 @@ export class File extends Entity implements IFile { this.numberOfOCRedPages = file.numberOfOCRedPages ?? 0; this.statusSort = StatusSorter[this.workflowStatus]; - this.cacheIdentifier = btoa(`${this.fileManipulationDate}${file.lastOCRTime}${file.ocrEndTime}`); + this.cacheIdentifier = btoa(`${this.fileManipulationDate}${file.lastOCRTime}${file.ocrEndTime}${file.lastLayoutProcessed}`); this.hintsOnly = this.hasHints && !this.hasRedactions; this.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions; this.isProcessing = isProcessingStatuses.includes(this.processingStatus); diff --git a/libs/red-domain/src/lib/files/file.ts b/libs/red-domain/src/lib/files/file.ts index fe862c441..083bc5c8a 100644 --- a/libs/red-domain/src/lib/files/file.ts +++ b/libs/red-domain/src/lib/files/file.ts @@ -90,6 +90,7 @@ export interface IFile { * Shows the last date of a successful analysis. */ readonly lastProcessed?: string; + readonly lastLayoutProcessed?: string; /** * The last reviewer's (if any) user id. */