RED-7158-2 layer service

This commit is contained in:
Timo Bejan 2023-08-16 13:43:07 +03:00
parent c3868d6a17
commit 5f252583f6
17 changed files with 130 additions and 32 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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) {

View File

@ -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[]) {

View File

@ -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<void> {
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,
});
}
}

View File

@ -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<HeaderElementType, boolean>([
[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],
[

View File

@ -40,7 +40,7 @@ export class FileManagementService extends GenericService<unknown> {
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),

View File

@ -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'],
},
];

View File

@ -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",

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M4.97883 9.68508C2.99294 8.89073 2 8.49355 2 8C2 7.50645 2.99294 7.10927 4.97883 6.31492L7.7873 5.19153C9.77318 4.39718 10.7661 4 12 4C13.2339 4 14.2268 4.39718 16.2127 5.19153L19.0212 6.31492C21.0071 7.10927 22 7.50645 22 8C22 8.49355 21.0071 8.89073 19.0212 9.68508L16.2127 10.8085C14.2268 11.6028 13.2339 12 12 12C10.7661 12 9.77318 11.6028 7.7873 10.8085L4.97883 9.68508Z"
stroke="#868E96" stroke-width="1.5"/>
<path
d="M5.76613 10L4.97883 10.3149C2.99294 11.1093 2 11.5065 2 12C2 12.4935 2.99294 12.8907 4.97883 13.6851L7.7873 14.8085C9.77318 15.6028 10.7661 16 12 16C13.2339 16 14.2268 15.6028 16.2127 14.8085L19.0212 13.6851C21.0071 12.8907 22 12.4935 22 12C22 11.5065 21.0071 11.1093 19.0212 10.3149L18.2339 10"
stroke="#868E96" stroke-width="1.5"/>
<path
d="M5.76613 14L4.97883 14.3149C2.99294 15.1093 2 15.5065 2 16C2 16.4935 2.99294 16.8907 4.97883 17.6851L7.7873 18.8085C9.77318 19.6028 10.7661 20 12 20C13.2339 20 14.2268 19.6028 16.2127 18.8085L19.0212 17.6851C21.0071 16.8907 22 16.4935 22 16C22 15.5065 21.0071 15.1093 19.0212 14.3149L18.2339 14"
stroke="#868E96" stroke-width="1.5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M4.97883 9.68508C2.99294 8.89073 2 8.49355 2 8C2 7.50645 2.99294 7.10927 4.97883 6.31492L7.7873 5.19153C9.77318 4.39718 10.7661 4 12 4C13.2339 4 14.2268 4.39718 16.2127 5.19153L19.0212 6.31492C21.0071 7.10927 22 7.50645 22 8C22 8.49355 21.0071 8.89073 19.0212 9.68508L16.2127 10.8085C14.2268 11.6028 13.2339 12 12 12C10.7661 12 9.77318 11.6028 7.7873 10.8085L4.97883 9.68508Z"
fill="#868E96"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M2 8C2 8.49355 2.99294 8.89073 4.97883 9.68508L7.7873 10.8085C9.77318 11.6028 10.7661 12 12 12C13.2339 12 14.2268 11.6028 16.2127 10.8085L19.0212 9.68508C21.0071 8.89073 22 8.49355 22 8C22 7.50645 21.0071 7.10927 19.0212 6.31492L16.2127 5.19153C14.2268 4.39718 13.2339 4 12 4C10.7661 4 9.77318 4.39718 7.7873 5.19153L4.97883 6.31492C2.99294 7.10927 2 7.50645 2 8Z"
fill="#868E96"/>
<path
d="M19.0212 13.6851L16.2127 14.8085C14.2268 15.6028 13.2339 16 12 16C10.7661 16 9.77318 15.6028 7.7873 14.8085L4.97883 13.6851C2.99294 12.8907 2 12.4935 2 12C2 11.5551 2.80681 11.1885 4.42043 10.5388L7.56143 11.7952C9.41007 12.535 10.572 13 12 13C13.428 13 14.5899 12.535 16.4386 11.7952L19.5796 10.5388C21.1932 11.1885 22 11.5551 22 12C22 12.4935 21.0071 12.8907 19.0212 13.6851Z"
fill="#868E96"/>
<path
d="M19.0212 17.6849L16.2127 18.8083C14.2268 19.6026 13.2339 19.9998 12 19.9998C10.7661 19.9998 9.77318 19.6026 7.7873 18.8083L4.97883 17.6849C2.99294 16.8905 2 16.4934 2 15.9998C2 15.5549 2.80681 15.1883 4.42043 14.5386L7.56143 15.795C9.41007 16.5348 10.572 16.9998 12 16.9998C13.428 16.9998 14.5899 16.5348 16.4386 15.795L19.5796 14.5386C21.1932 15.1883 22 15.5549 22 15.9998C22 16.4934 21.0071 16.8905 19.0212 17.6849Z"
fill="#868E96"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -40,6 +40,7 @@ export class File extends Entity<IFile> 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<IFile> 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<IFile> 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);

View File

@ -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.
*/