excluded pages fix and legal basis / image reacat fix
This commit is contained in:
parent
8eba40d5f5
commit
929aa355d7
@ -26,7 +26,8 @@ export type AnnotationSuperType =
|
||||
export class AnnotationWrapper {
|
||||
superType: AnnotationSuperType;
|
||||
|
||||
dictionary: string;
|
||||
typeValue: string;
|
||||
recategorizationType: string;
|
||||
color: string;
|
||||
comments: Comment[] = [];
|
||||
firstTopLeftPoint: Point;
|
||||
@ -42,7 +43,7 @@ export class AnnotationWrapper {
|
||||
dictionaryOperation: boolean;
|
||||
positions: Rectangle[];
|
||||
recommendationType: string;
|
||||
legalBasis: string;
|
||||
legalBasisValue: string;
|
||||
legalBasisChangeValue?: string;
|
||||
|
||||
manual?: boolean;
|
||||
@ -89,11 +90,15 @@ export class AnnotationWrapper {
|
||||
}
|
||||
|
||||
get isImage() {
|
||||
return this.dictionary?.toLowerCase() === 'image' || this.image;
|
||||
return this.type?.toLowerCase() === 'image' || this.image;
|
||||
}
|
||||
|
||||
get isOCR() {
|
||||
return this.dictionary?.toLowerCase() === 'ocr';
|
||||
return this.type?.toLowerCase() === 'ocr';
|
||||
}
|
||||
|
||||
get type() {
|
||||
return this.recategorizationType || this.typeValue;
|
||||
}
|
||||
|
||||
get isManuallySkipped() {
|
||||
@ -102,7 +107,7 @@ export class AnnotationWrapper {
|
||||
|
||||
get isFalsePositive() {
|
||||
return (
|
||||
this.dictionary?.toLowerCase() === 'false_positive' &&
|
||||
this.type?.toLowerCase() === 'false_positive' &&
|
||||
(this.superType === 'skipped' || this.superType === 'hint' || this.superType === 'redaction')
|
||||
);
|
||||
}
|
||||
@ -185,6 +190,10 @@ export class AnnotationWrapper {
|
||||
return this.firstTopLeftPoint.y;
|
||||
}
|
||||
|
||||
get legalBasis() {
|
||||
return this.legalBasisChangeValue || this.legalBasisValue;
|
||||
}
|
||||
|
||||
static fromData(redactionLogEntry?: RedactionLogEntryWrapper) {
|
||||
const annotationWrapper = new AnnotationWrapper();
|
||||
|
||||
@ -195,7 +204,8 @@ export class AnnotationWrapper {
|
||||
annotationWrapper.changeLogType = redactionLogEntry.changeLogType;
|
||||
annotationWrapper.redaction = redactionLogEntry.redacted;
|
||||
annotationWrapper.hint = redactionLogEntry.hint;
|
||||
annotationWrapper.dictionary = redactionLogEntry.type;
|
||||
annotationWrapper.typeValue = redactionLogEntry.type;
|
||||
annotationWrapper.recategorizationType = redactionLogEntry.recategorizationType;
|
||||
annotationWrapper.value = redactionLogEntry.value;
|
||||
annotationWrapper.firstTopLeftPoint = redactionLogEntry.positions[0]?.topLeft;
|
||||
annotationWrapper.pageNumber = redactionLogEntry.positions[0]?.page;
|
||||
@ -206,8 +216,8 @@ export class AnnotationWrapper {
|
||||
annotationWrapper.dictionaryOperation = redactionLogEntry.dictionaryEntry;
|
||||
annotationWrapper.image = redactionLogEntry.image;
|
||||
annotationWrapper.legalBasisChangeValue = redactionLogEntry.legalBasisChangeValue;
|
||||
annotationWrapper.legalBasisValue = redactionLogEntry.legalBasis;
|
||||
annotationWrapper.comments = redactionLogEntry.comments || [];
|
||||
annotationWrapper.legalBasis = redactionLogEntry.legalBasis;
|
||||
annotationWrapper.manual = redactionLogEntry.manual;
|
||||
|
||||
this._createContent(annotationWrapper, redactionLogEntry);
|
||||
@ -247,7 +257,7 @@ export class AnnotationWrapper {
|
||||
return;
|
||||
}
|
||||
|
||||
if (annotationWrapper.dictionary?.toLowerCase() === 'false_positive') {
|
||||
if (annotationWrapper.type?.toLowerCase() === 'false_positive') {
|
||||
if (redactionLogEntryWrapper.status === 'REQUESTED') {
|
||||
annotationWrapper.superType = 'suggestion-add-dictionary';
|
||||
return;
|
||||
@ -372,24 +382,24 @@ export class AnnotationWrapper {
|
||||
content += entry.reason + '\n\n';
|
||||
}
|
||||
|
||||
if (entry.legalBasisChangeValue || entry.legalBasis) {
|
||||
content += 'Legal basis: ' + entry.legalBasis + '\n\n';
|
||||
if (annotationWrapper.legalBasis) {
|
||||
content += 'Legal basis: ' + annotationWrapper.legalBasis + '\n\n';
|
||||
}
|
||||
|
||||
if (entry.section) {
|
||||
content += 'In section: "' + entry.section + '"';
|
||||
}
|
||||
|
||||
annotationWrapper.shortContent = this._getShortContent(entry) || content;
|
||||
annotationWrapper.shortContent = this._getShortContent(annotationWrapper, entry) || content;
|
||||
annotationWrapper.content = content;
|
||||
}
|
||||
|
||||
private static _getShortContent(entry: RedactionLogEntryWrapper) {
|
||||
if (entry.legalBasis) {
|
||||
const lb = entry.legalBasisMapping?.find(lbm => lbm.reason.toLowerCase().includes(entry.legalBasis.toLowerCase()));
|
||||
private static _getShortContent(annotationWrapper: AnnotationWrapper, entry: RedactionLogEntryWrapper) {
|
||||
if (annotationWrapper.legalBasis) {
|
||||
const lb = entry.legalBasisMapping?.find(lbm => lbm.reason.toLowerCase().includes(annotationWrapper.legalBasis.toLowerCase()));
|
||||
if (lb) return lb.name;
|
||||
}
|
||||
|
||||
return entry.legalBasis;
|
||||
return annotationWrapper.legalBasis;
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ export class WatermarkScreenComponent implements OnInit {
|
||||
const opacity = this.configForm.get('opacity').value;
|
||||
const color = this.configForm.get('hexColor').value;
|
||||
|
||||
await stampPDFPage(document, pdfNet, text, fontSize, fontType, orientation, opacity, color, 1);
|
||||
await stampPDFPage(document, pdfNet, text, fontSize, fontType, orientation, opacity, color, [1]);
|
||||
this._instance.docViewer.refreshAll();
|
||||
this._instance.docViewer.updateView([0], 0);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
|
||||
@ -180,11 +180,11 @@
|
||||
<div>
|
||||
<strong>{{ annotation.typeLabel | translate }}</strong>
|
||||
</div>
|
||||
<div *ngIf="annotation?.dictionary !== 'manual'">
|
||||
<div *ngIf="annotation?.type !== 'manual'">
|
||||
<strong>
|
||||
<span>{{ annotation.descriptor | translate }}</span
|
||||
>: </strong
|
||||
>{{ annotation.dictionary | humanize: false }}
|
||||
>{{ annotation.type | humanize: false }}
|
||||
</div>
|
||||
<div *ngIf="annotation.shortContent && !annotation.isHint">
|
||||
<strong><span translate="content"></span>: </strong>{{ annotation.shortContent }}
|
||||
@ -225,7 +225,7 @@
|
||||
<redaction-page-exclusion
|
||||
(actionPerformed)="actionPerformed.emit($event)"
|
||||
*ngIf="excludePages"
|
||||
[fileData]="fileData"
|
||||
[fileStatus]="fileData.fileStatus"
|
||||
></redaction-page-exclusion>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -6,6 +6,7 @@ import { FileDataModel } from '../../../../models/file/file-data.model';
|
||||
import { Toaster } from '@services/toaster.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { FileStatusWrapper } from '../../../../models/file/file-status.wrapper';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-page-exclusion',
|
||||
@ -13,7 +14,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
styleUrls: ['./page-exclusion.component.scss']
|
||||
})
|
||||
export class PageExclusionComponent implements OnChanges {
|
||||
@Input() fileData: FileDataModel;
|
||||
@Input() fileStatus: FileStatusWrapper;
|
||||
@Output() actionPerformed = new EventEmitter<string>();
|
||||
|
||||
excludePagesForm: FormGroup;
|
||||
@ -31,22 +32,20 @@ export class PageExclusionComponent implements OnChanges {
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.fileData) {
|
||||
const excludedPages = (this.fileData?.fileStatus?.excludedPages || []).sort((p1, p2) => p1 - p2);
|
||||
this.excludedPagesRanges = excludedPages.reduce((ranges, page) => {
|
||||
if (!ranges.length) {
|
||||
return [{ startPage: page, endPage: page }];
|
||||
}
|
||||
ngOnChanges() {
|
||||
const excludedPages = (this.fileStatus?.excludedPages || []).sort((p1, p2) => p1 - p2);
|
||||
this.excludedPagesRanges = excludedPages.reduce((ranges, page) => {
|
||||
if (!ranges.length) {
|
||||
return [{ startPage: page, endPage: page }];
|
||||
}
|
||||
|
||||
if (page === ranges[ranges.length - 1].endPage + 1) {
|
||||
ranges[ranges.length - 1].endPage = page;
|
||||
} else {
|
||||
ranges.push({ startPage: page, endPage: page });
|
||||
}
|
||||
return ranges;
|
||||
}, []);
|
||||
}
|
||||
if (page === ranges[ranges.length - 1].endPage + 1) {
|
||||
ranges[ranges.length - 1].endPage = page;
|
||||
} else {
|
||||
ranges.push({ startPage: page, endPage: page });
|
||||
}
|
||||
return ranges;
|
||||
}, []);
|
||||
}
|
||||
|
||||
async excludePagesRange() {
|
||||
@ -72,8 +71,8 @@ export class PageExclusionComponent implements OnChanges {
|
||||
{
|
||||
pageRanges: pageRanges
|
||||
},
|
||||
this.fileData.fileStatus.dossierId,
|
||||
this.fileData.fileStatus.fileId
|
||||
this.fileStatus.dossierId,
|
||||
this.fileStatus.fileId
|
||||
)
|
||||
.toPromise();
|
||||
this.excludePagesForm.reset();
|
||||
@ -91,8 +90,8 @@ export class PageExclusionComponent implements OnChanges {
|
||||
{
|
||||
pageRanges: [range]
|
||||
},
|
||||
this.fileData.fileStatus.dossierId,
|
||||
this.fileData.fileStatus.fileId
|
||||
this.fileStatus.dossierId,
|
||||
this.fileStatus.fileId
|
||||
)
|
||||
.toPromise();
|
||||
this.excludePagesForm.reset();
|
||||
|
||||
@ -21,7 +21,7 @@ export class TypeAnnotationIconComponent implements OnChanges {
|
||||
if (this.annotation.isSuperTypeBasedColor) {
|
||||
this.color = this._appStateService.getDictionaryColor(this.annotation.superType);
|
||||
} else {
|
||||
this.color = this._appStateService.getDictionaryColor(this.annotation.dictionary);
|
||||
this.color = this._appStateService.getDictionaryColor(this.annotation.type);
|
||||
}
|
||||
this.type =
|
||||
this.annotation.isSuggestion || this.annotation.isDeclinedSuggestion
|
||||
@ -38,7 +38,7 @@ export class TypeAnnotationIconComponent implements OnChanges {
|
||||
? 'S'
|
||||
: this.annotation.isReadyForAnalysis
|
||||
? 'A'
|
||||
: this.annotation.dictionary[0].toUpperCase();
|
||||
: this.annotation.type[0].toUpperCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,14 +25,14 @@ export class RecategorizeImageDialogComponent implements OnInit {
|
||||
) {}
|
||||
|
||||
get changed(): boolean {
|
||||
return this.recategorizeImageForm.get('type').value !== this.annotations[0].dictionary;
|
||||
return this.recategorizeImageForm.get('type').value !== this.annotations[0].type;
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.isDocumentAdmin = this._permissionsService.isApprover();
|
||||
|
||||
this.recategorizeImageForm = this._formBuilder.group({
|
||||
type: [this.annotations[0].dictionary, Validators.required],
|
||||
type: [this.annotations[0].type, Validators.required],
|
||||
comment: this.isDocumentAdmin ? [null] : [null, Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let annotation of data.annotationsToRemove">
|
||||
<td>{{ annotation.dictionary }}</td>
|
||||
<td>{{ annotation.type }}</td>
|
||||
<td>{{ annotation.value }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@ -42,7 +42,7 @@ export class RemoveAnnotationsDialogComponent {
|
||||
printable(annotation: AnnotationWrapper) {
|
||||
if (annotation.isImage) {
|
||||
return this._translateService.instant('remove-annotations-dialog.image-type', {
|
||||
typeLabel: humanize(annotation.dictionary)
|
||||
typeLabel: humanize(annotation.type)
|
||||
});
|
||||
} else {
|
||||
return annotation.value;
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
[showCloseButton]="true"
|
||||
>
|
||||
<redaction-file-download-btn
|
||||
[disabled]="entitiesService.areSomeSelected$ | async"
|
||||
[dossier]="currentDossier"
|
||||
[file]="entitiesService.all$ | async"
|
||||
tooltipPosition="below"
|
||||
@ -14,7 +13,6 @@
|
||||
<iqser-circle-button
|
||||
(action)="reanalyseDossier()"
|
||||
*ngIf="permissionsService.displayReanalyseBtn()"
|
||||
[disabled]="entitiesService.areSomeSelected$ | async"
|
||||
[tooltipClass]="'small ' + ((entitiesService.areSomeSelected$ | async) ? '' : 'warn')"
|
||||
[tooltip]="'dossier-overview.new-rule.toast.actions.reanalyse-all' | translate"
|
||||
icon="red:refresh"
|
||||
|
||||
@ -93,8 +93,8 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
||||
constructor(
|
||||
private readonly _toaster: Toaster,
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _userService: UserService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _appConfigService: AppConfigService,
|
||||
|
||||
@ -31,7 +31,7 @@ import { FileWorkloadComponent } from '../../components/file-workload/file-workl
|
||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { stampPDFPage } from '@utils/page-stamper';
|
||||
import { clearStamps, stampPDFPage } from '@utils/page-stamper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { fileStatusTranslations } from '../../translations/file-status-translations';
|
||||
import { handleFilterDelta } from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
@ -443,6 +443,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
case 'exclude-pages':
|
||||
await this.appStateService.reloadActiveDossierFiles();
|
||||
await this._loadFileData(true);
|
||||
await this._stampExcludedPages();
|
||||
this._loadingService.stop();
|
||||
return;
|
||||
|
||||
@ -525,25 +526,26 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
window.open(`/html-debug/${this.dossierId}/${this.fileId}`, '_blank');
|
||||
}
|
||||
|
||||
private async _stampPage(page: number) {
|
||||
const document = await this._instance.docViewer.getDocument().getPDFDoc();
|
||||
await stampPDFPage(
|
||||
document,
|
||||
this._instance.PDFNet,
|
||||
this._translateService.instant('file-preview.excluded-from-redaction'),
|
||||
25,
|
||||
'courier',
|
||||
'DIAGONAL',
|
||||
33,
|
||||
'#283241',
|
||||
page
|
||||
);
|
||||
private async _doStampExcludedPages(excludedPages: number[]) {
|
||||
if (excludedPages && excludedPages.length > 0) {
|
||||
const document = await this._instance.docViewer.getDocument().getPDFDoc();
|
||||
await clearStamps(document, this._instance.PDFNet, [...Array(this.fileData.fileStatus.numberOfPages).keys()]);
|
||||
await stampPDFPage(
|
||||
document,
|
||||
this._instance.PDFNet,
|
||||
this._translateService.instant('file-preview.excluded-from-redaction'),
|
||||
25,
|
||||
'courier',
|
||||
'DIAGONAL',
|
||||
33,
|
||||
'#283241',
|
||||
excludedPages
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async _stampExcludedPages() {
|
||||
for (const page of this.fileData.fileStatus.excludedPages) {
|
||||
await this._stampPage(page);
|
||||
}
|
||||
await this._doStampExcludedPages(this.fileData.fileStatus.excludedPages);
|
||||
this._instance.docViewer.refreshAll();
|
||||
this._instance.docViewer.updateView([this.activeViewerPage], this.activeViewerPage);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
|
||||
@ -84,7 +84,7 @@ export class AnnotationDrawService {
|
||||
const pageNumber = compareMode ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
|
||||
const highlight = new activeViewer.Annotations.TextHighlightAnnotation();
|
||||
highlight.PageNumber = pageNumber;
|
||||
highlight.StrokeColor = this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.dictionary);
|
||||
highlight.StrokeColor = this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type);
|
||||
highlight.setContents(annotationWrapper.content);
|
||||
highlight.Quads = this._rectanglesToQuads(annotationWrapper.positions, activeViewer, pageNumber);
|
||||
highlight.Id = annotationWrapper.id;
|
||||
@ -99,7 +99,7 @@ export class AnnotationDrawService {
|
||||
highlight.setCustomData('changeLog', annotationWrapper.isChangeLogEntry);
|
||||
highlight.setCustomData('changeLogRemoved', annotationWrapper.isChangeLogRemoved);
|
||||
highlight.setCustomData('redactionColor', this.getColor(activeViewer, 'redaction', 'redaction'));
|
||||
highlight.setCustomData('annotationColor', this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.dictionary));
|
||||
highlight.setCustomData('annotationColor', this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type));
|
||||
|
||||
return highlight;
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ export class AnnotationProcessingService {
|
||||
|
||||
annotations?.forEach(a => {
|
||||
const topLevelFilter = a.superType !== 'hint' && a.superType !== 'redaction' && a.superType !== 'recommendation';
|
||||
const key = topLevelFilter ? a.superType : a.superType + a.dictionary;
|
||||
const key = topLevelFilter ? a.superType : a.superType + a.type;
|
||||
const filter = filterMap.get(key);
|
||||
if (filter) {
|
||||
filter.matches += 1;
|
||||
@ -51,8 +51,8 @@ export class AnnotationProcessingService {
|
||||
parentFilter = this._createParentFilter(a.superType, filterMap, filters);
|
||||
}
|
||||
const childFilter = {
|
||||
key: a.dictionary,
|
||||
label: a.dictionary,
|
||||
key: a.type,
|
||||
label: a.type,
|
||||
checked: false,
|
||||
filters: [],
|
||||
matches: 1
|
||||
@ -172,7 +172,7 @@ export class AnnotationProcessingService {
|
||||
const superType = annotation.superType;
|
||||
const isNotTopLevelFilter = superType === 'hint' || superType === 'redaction' || superType === 'recommendation';
|
||||
|
||||
return filter.key === superType || (filter.key === annotation.dictionary && isNotTopLevelFilter);
|
||||
return filter.key === superType || (filter.key === annotation.type && isNotTopLevelFilter);
|
||||
};
|
||||
|
||||
private _sortAnnotations(annotations: AnnotationWrapper[]): AnnotationWrapper[] {
|
||||
|
||||
@ -168,7 +168,7 @@ export class ManualAnnotationService {
|
||||
|
||||
if (this._permissionsService.isApprover()) {
|
||||
// if it was something manual simply decline the existing request
|
||||
if (annotationWrapper.dictionary === 'manual') {
|
||||
if (annotationWrapper.type === 'manual') {
|
||||
mode = 'undo';
|
||||
body = annotationWrapper.id;
|
||||
} else {
|
||||
|
||||
@ -9,17 +9,9 @@ const processPage = async (pageNumber, document1, document2, mergedDocument, PDF
|
||||
const blankPage = await mergedDocument.pageCreate(await pageToCopy.getCropBox());
|
||||
await blankPage.setRotation(await pageToCopy.getRotation());
|
||||
await mergedDocument.pagePushBack(blankPage);
|
||||
await stampPDFPage(
|
||||
mergedDocument,
|
||||
PDFNet,
|
||||
'<< Compare Placeholder Page >>',
|
||||
20,
|
||||
'courier',
|
||||
'DIAGONAL',
|
||||
33,
|
||||
'#ffb83b',
|
||||
await stampPDFPage(mergedDocument, PDFNet, '<< Compare Placeholder Page >>', 20, 'courier', 'DIAGONAL', 33, '#ffb83b', [
|
||||
await mergedDocument.getPageCount()
|
||||
);
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -3,6 +3,17 @@ import { environment } from '@environments/environment';
|
||||
import { PDFNet } from '@pdftron/webviewer';
|
||||
import PDFDoc = PDFNet.PDFDoc;
|
||||
|
||||
export async function clearStamps(document: PDFDoc, PdfNet: any, pages: number[]) {
|
||||
await PdfNet.runWithCleanup(
|
||||
async () => {
|
||||
await document.lock();
|
||||
const pageSet = await createPageSet(PdfNet, pages);
|
||||
await PdfNet.Stamper.deleteStamps(document, pageSet);
|
||||
},
|
||||
environment.licenseKey ? atob(environment.licenseKey) : null
|
||||
);
|
||||
}
|
||||
|
||||
export async function stampPDFPage(
|
||||
document: PDFDoc,
|
||||
PdfNet: any,
|
||||
@ -12,14 +23,13 @@ export async function stampPDFPage(
|
||||
orientation: 'DIAGONAL' | 'HORIZONTAL' | 'VERTICAL',
|
||||
opacity: number,
|
||||
color: string,
|
||||
page: number
|
||||
pages: number[]
|
||||
) {
|
||||
await PdfNet.runWithCleanup(
|
||||
async () => {
|
||||
await document.lock();
|
||||
|
||||
const pageSet = await PdfNet.PageSet.createSinglePage(page);
|
||||
|
||||
const pageSet = await createPageSet(PdfNet, pages);
|
||||
await PdfNet.Stamper.deleteStamps(document, pageSet);
|
||||
|
||||
const rgbColor = hexToRgb(color);
|
||||
@ -50,6 +60,16 @@ export async function stampPDFPage(
|
||||
);
|
||||
}
|
||||
|
||||
async function createPageSet(PdfNet: any, pages: number[]) {
|
||||
const pageSet = await PdfNet.PageSet.create();
|
||||
for (const page of pages) {
|
||||
if (page > 0) {
|
||||
await pageSet.addPage(page);
|
||||
}
|
||||
}
|
||||
return pageSet;
|
||||
}
|
||||
|
||||
function convertFont(type: string): number {
|
||||
switch (type) {
|
||||
case 'times-new-roman':
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user