RED-3893: File stamping service

This commit is contained in:
Adina Țeudan 2022-04-19 15:48:32 +03:00
parent a5afef8e8a
commit ed7652d8f7
4 changed files with 90 additions and 69 deletions

View File

@ -17,6 +17,7 @@ import { FileDataService } from './services/file-data.service';
import { ViewerHeaderConfigService } from './services/viewer-header-config.service';
import { TooltipsService } from './services/tooltips.service';
import { AnnotationsListingService } from './services/annotations-listing.service';
import { StampService } from './services/stamp.service';
export const filePreviewScreenProviders = [
FilterService,
@ -40,4 +41,5 @@ export const filePreviewScreenProviders = [
TooltipsService,
{ provide: ListingService, useClass: AnnotationsListingService },
SearchService,
StampService,
];

View File

@ -25,14 +25,12 @@ import { File, ViewMode, ViewModes } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
import { combineLatest, firstValueFrom, Observable, of, pairwise } from 'rxjs';
import { UserPreferenceService } from '@services/user-preference.service';
import { clearStamps, download, handleFilterDelta, stampPDFPage } from '../../utils';
import { download, handleFilterDelta } from '../../utils';
import { FileWorkloadComponent } from './components/file-workload/file-workload.component';
import { TranslateService } from '@ngx-translate/core';
import { FilesService } from '@services/entity-services/files.service';
import { FileManagementService } from '@services/entity-services/file-management.service';
import { catchError, debounceTime, map, startWith, switchMap, tap } from 'rxjs/operators';
import { FilesMapService } from '@services/entity-services/files-map.service';
import { WatermarkService } from '@shared/services/watermark.service';
import { ExcludedPagesService } from './services/excluded-pages.service';
import { ViewModeService } from './services/view-mode.service';
import { MultiSelectService } from './services/multi-select.service';
@ -51,8 +49,8 @@ import { FilePreviewDialogService } from './services/file-preview-dialog.service
import { FileDataService } from './services/file-data.service';
import { ALL_HOTKEYS } from './shared/constants';
import { NGXLogger } from 'ngx-logger';
import { StampService } from './services/stamp.service';
import Annotation = Core.Annotations.Annotation;
import PDFNet = Core.PDFNet;
@Component({
templateUrl: './file-preview-screen.component.html',
@ -101,8 +99,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
private readonly _dossiersService: DossiersService,
private readonly _fileDataService: FileDataService,
private readonly _viewModeService: ViewModeService,
private readonly _watermarkService: WatermarkService,
private readonly _translateService: TranslateService,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _reanalysisService: ReanalysisService,
private readonly _dialogService: FilePreviewDialogService,
@ -111,6 +107,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
private readonly _fileManagementService: FileManagementService,
private readonly _manualRedactionService: ManualRedactionService,
private readonly _annotationProcessingService: AnnotationProcessingService,
private readonly _stampService: StampService,
) {
super();
this.canPerformAnnotationActions$ = this._canPerformAnnotationActions$;
@ -188,7 +185,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
}
await this._stampPDF();
await this._stampService.stampPDF();
this.#rebuildFilters();
}
@ -504,67 +501,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}, 100);
}
private async _stampPDF() {
const pdfDoc = await this.pdf.documentViewer.getDocument()?.getPDFDoc();
if (!pdfDoc) {
return;
}
const file = await this.state.file;
const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);
try {
await clearStamps(pdfDoc, this.pdf.PDFNet, allPages);
} catch (e) {
this._logger.error('Error clearing stamps: ', e);
return;
}
if (this._viewModeService.isRedacted) {
const dossier = await this.state.dossier;
if (dossier.watermarkPreviewEnabled) {
await this._stampPreview(pdfDoc, dossier.dossierTemplateId);
}
} else {
await this._stampExcludedPages(pdfDoc, file.excludedPages);
}
this.pdf.documentViewer.refreshAll();
this.pdf.documentViewer.updateView([this.pdf.currentPage], this.pdf.currentPage);
this._changeDetectorRef.markForCheck();
}
private async _stampPreview(document: PDFNet.PDFDoc, dossierTemplateId: string) {
const watermark = await firstValueFrom(this._watermarkService.getWatermark(dossierTemplateId));
await stampPDFPage(
document,
this.pdf.PDFNet,
watermark.text,
watermark.fontSize,
watermark.fontType,
watermark.orientation,
watermark.opacity,
watermark.hexColor,
Array.from({ length: await document.getPageCount() }, (x, i) => i + 1),
);
}
private async _stampExcludedPages(document: PDFNet.PDFDoc, excludedPages: number[]) {
if (excludedPages && excludedPages.length > 0) {
await stampPDFPage(
document,
this.pdf.PDFNet,
this._translateService.instant('file-preview.excluded-from-redaction') as string,
17,
'courier',
'TOP_LEFT',
50,
'#dd4d50',
excludedPages,
);
}
}
private _subscribeToFileUpdates(): void {
this.addActiveScreenSubscription = this.loadAnnotations().subscribe();

View File

@ -0,0 +1,83 @@
import { Injectable } from '@angular/core';
import { clearStamps, stampPDFPage } from '../../../utils';
import { PdfViewer } from './pdf-viewer.service';
import { FilePreviewStateService } from './file-preview-state.service';
import { NGXLogger } from 'ngx-logger';
import { ViewModeService } from './view-mode.service';
import { TranslateService } from '@ngx-translate/core';
import { Core } from '@pdftron/webviewer';
import { firstValueFrom } from 'rxjs';
import { WatermarkService } from '../../shared/services/watermark.service';
import PDFNet = Core.PDFNet;
@Injectable()
export class StampService {
constructor(
private readonly _pdf: PdfViewer,
private readonly _state: FilePreviewStateService,
private readonly _logger: NGXLogger,
private readonly _viewModeService: ViewModeService,
private readonly _translateService: TranslateService,
private readonly _watermarkService: WatermarkService,
) {}
async stampPDF(): Promise<void> {
const pdfDoc = await this._pdf.documentViewer.getDocument()?.getPDFDoc();
if (!pdfDoc) {
return;
}
const file = await this._state.file;
const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);
try {
await clearStamps(pdfDoc, this._pdf.PDFNet, allPages);
} catch (e) {
this._logger.error('Error clearing stamps: ', e);
return;
}
if (this._viewModeService.isRedacted) {
const dossier = await this._state.dossier;
if (dossier.watermarkPreviewEnabled) {
await this._stampPreview(pdfDoc, dossier.dossierTemplateId);
}
} else {
await this._stampExcludedPages(pdfDoc, file.excludedPages);
}
this._pdf.documentViewer.refreshAll();
this._pdf.documentViewer.updateView([this._pdf.currentPage], this._pdf.currentPage);
}
private async _stampExcludedPages(document: PDFNet.PDFDoc, excludedPages: number[]): Promise<void> {
if (excludedPages && excludedPages.length > 0) {
await stampPDFPage(
document,
this._pdf.PDFNet,
this._translateService.instant('file-preview.excluded-from-redaction') as string,
17,
'courier',
'TOP_LEFT',
50,
'#dd4d50',
excludedPages,
);
}
}
private async _stampPreview(document: PDFNet.PDFDoc, dossierTemplateId: string): Promise<void> {
const watermark = await firstValueFrom(this._watermarkService.getWatermark(dossierTemplateId));
await stampPDFPage(
document,
this._pdf.PDFNet,
watermark.text,
watermark.fontSize,
watermark.fontType,
watermark.orientation,
watermark.opacity,
watermark.hexColor,
Array.from({ length: await document.getPageCount() }, (x, i) => i + 1),
);
}
}

@ -1 +1 @@
Subproject commit d8c2a342baa6acb330132c44000562bdd823f620
Subproject commit 6a0e22e68441a1dbbaaa38cfebed1aa8e8bb91be