Merge branch 'dan' into 'master'
Update entity log migration See merge request redactmanager/red-ui!177
This commit is contained in:
commit
aa8e59aefa
@ -59,7 +59,7 @@ export class AnnotationWrapper implements IListable {
|
||||
hasBeenForcedHint: boolean;
|
||||
hasBeenForcedRedaction: boolean;
|
||||
hasBeenRemovedByManualOverride: boolean;
|
||||
isIgnored = false;
|
||||
isRemoved = false;
|
||||
|
||||
get searchKey(): string {
|
||||
return this.id;
|
||||
@ -212,7 +212,7 @@ export class AnnotationWrapper implements IListable {
|
||||
const annotationWrapper = new AnnotationWrapper();
|
||||
|
||||
annotationWrapper.id = logEntry.id;
|
||||
annotationWrapper.isChangeLogEntry = !!changeLogType;
|
||||
annotationWrapper.isChangeLogEntry = logEntry.state === EntryStates.REMOVED || !!changeLogType;
|
||||
annotationWrapper.type = logEntry.type;
|
||||
annotationWrapper.value = logEntry.value;
|
||||
annotationWrapper.firstTopLeftPoint = { x: logEntry.positions[0].rectangle[0], y: logEntry.positions[0].rectangle[1] };
|
||||
@ -232,7 +232,7 @@ export class AnnotationWrapper implements IListable {
|
||||
annotationWrapper.AREA = logEntry.entryType === EntityTypes.AREA;
|
||||
annotationWrapper.IMAGE_HINT = logEntry.entryType === EntityTypes.IMAGE_HINT;
|
||||
|
||||
annotationWrapper.isIgnored = logEntry.state === EntryStates.IGNORED;
|
||||
annotationWrapper.isRemoved = logEntry.state === EntryStates.REMOVED;
|
||||
|
||||
annotationWrapper.numberOfComments = logEntry.numberOfComments;
|
||||
annotationWrapper.imported = logEntry.imported;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<div class="active-bar-marker"></div>
|
||||
|
||||
<div [class.removed]="annotation.item.isIgnored" class="annotation">
|
||||
<div [class.removed]="annotation.item.isRemoved" class="annotation">
|
||||
<redaction-annotation-card
|
||||
[annotation]="annotation.item"
|
||||
[isSelected]="annotation.isSelected"
|
||||
|
||||
@ -3,7 +3,7 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { CircleButtonTypes, getConfig, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { FilterService, INestedFilter } from '@iqser/common-ui/lib/filtering';
|
||||
import { AutoUnsubscribe, bool, Debounce, IqserEventTarget } from '@iqser/common-ui/lib/utils';
|
||||
import { AutoUnsubscribe, Debounce, IqserEventTarget } from '@iqser/common-ui/lib/utils';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { ListItem } from '@models/file/list-item';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
@ -356,7 +356,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
if (this.viewModeService.isRedacted()) {
|
||||
annotations = annotations.filter(a => !bool(a.isIgnored));
|
||||
annotations = annotations.filter(a => !a.isRemoved);
|
||||
}
|
||||
|
||||
if (this.#isDocumine && !this.#isIqserDevMode) {
|
||||
|
||||
@ -3,22 +3,11 @@ import { toObservable } from '@angular/core/rxjs-interop';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { EntitiesService, getConfig, Toaster } from '@iqser/common-ui';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import {
|
||||
ChangeType,
|
||||
ChangeTypes,
|
||||
EntryStates,
|
||||
File,
|
||||
IEntityLog,
|
||||
IEntityLogEntry,
|
||||
SuperTypeMapper,
|
||||
ViewedPage,
|
||||
ViewMode,
|
||||
ViewModes,
|
||||
} from '@red/domain';
|
||||
import { ChangeType, ChangeTypes, File, IEntityLog, IEntityLogEntry, SuperTypeMapper, ViewedPage, ViewMode, ViewModes } from '@red/domain';
|
||||
import { DictionaryService } from '@services/entity-services/dictionary.service';
|
||||
import { EarmarksService } from '@services/files/earmarks.service';
|
||||
import { EntityLogService } from '@services/files/entity-log.service';
|
||||
import { FilesService } from '@services/files/files.service';
|
||||
import { RedactionLogService } from '@services/files/redaction-log.service';
|
||||
import { ViewedPagesMapService } from '@services/files/viewed-pages-map.service';
|
||||
import { ViewedPagesService } from '@services/files/viewed-pages.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
@ -48,6 +37,7 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly #logger = inject(NGXLogger);
|
||||
readonly #toaster = inject(Toaster);
|
||||
readonly #isIqserDevMode = inject(UserPreferenceService).isIqserDevMode;
|
||||
protected readonly _entityClass = AnnotationWrapper;
|
||||
missingTypes = new Set<string>();
|
||||
readonly earmarks: Signal<Map<number, AnnotationWrapper[]>>;
|
||||
@ -59,10 +49,9 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
private readonly _viewedPagesService: ViewedPagesService,
|
||||
private readonly _viewedPagesMapService: ViewedPagesMapService,
|
||||
private readonly _viewModeService: ViewModeService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
private readonly _dictionaryService: DictionaryService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _redactionLogService: RedactionLogService,
|
||||
private readonly _entityLogService: EntityLogService,
|
||||
private readonly _earmarksService: EarmarksService,
|
||||
private readonly _multiSelectService: MultiSelectService,
|
||||
private readonly _filesService: FilesService,
|
||||
@ -107,7 +96,7 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
this.#logger.info('[ANNOTATIONS] Loading annotations...');
|
||||
|
||||
await this.#loadViewedPages(file);
|
||||
await this.loadRedactionLog();
|
||||
await this.loadEntityLog();
|
||||
|
||||
this.#logger.info('[ANNOTATIONS] Annotations loaded');
|
||||
}
|
||||
@ -129,14 +118,14 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
return earmarks;
|
||||
}
|
||||
|
||||
async loadRedactionLog() {
|
||||
async loadEntityLog() {
|
||||
this.#logger.info('[REDACTION_LOG] Loading redaction log...');
|
||||
const redactionLog = await this._redactionLogService.getEntityLog(this._state.dossierId, this._state.fileId);
|
||||
const redactionLog = await this._entityLogService.getEntityLog(this._state.dossierId, this._state.fileId);
|
||||
|
||||
this.#logger.info('[REDACTION_LOG] Redaction log loaded', redactionLog);
|
||||
let annotations = await this.#convertData(redactionLog);
|
||||
this.#checkMissingTypes();
|
||||
annotations = this._userPreferenceService.isIqserDevMode ? annotations : annotations.filter(a => !a.isFalsePositive);
|
||||
annotations = this.#isIqserDevMode ? annotations : annotations.filter(a => !a.isFalsePositive);
|
||||
this.#annotations.set(annotations);
|
||||
}
|
||||
|
||||
@ -163,24 +152,18 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
}
|
||||
|
||||
#getVisibleAnnotations(annotations: AnnotationWrapper[], viewMode: ViewMode) {
|
||||
return annotations.filter(annotation => {
|
||||
if (viewMode === 'STANDARD') {
|
||||
return !annotation.isIgnored;
|
||||
}
|
||||
if (viewMode === ViewModes.STANDARD) {
|
||||
return annotations.filter(annotation => !annotation.isRemoved);
|
||||
}
|
||||
|
||||
if (viewMode === 'DELTA') {
|
||||
return annotation.isChangeLogEntry;
|
||||
}
|
||||
if (viewMode === ViewModes.DELTA) {
|
||||
return annotations.filter(annotation => annotation.isChangeLogEntry);
|
||||
}
|
||||
|
||||
return annotation.isRedacted;
|
||||
});
|
||||
return annotations.filter(annotation => annotation.isRedacted);
|
||||
}
|
||||
|
||||
async #convertData(entityLog: IEntityLog) {
|
||||
if (!entityLog.entityLogEntry) {
|
||||
return [] as AnnotationWrapper[];
|
||||
}
|
||||
|
||||
const file = this._state.file();
|
||||
const annotations: AnnotationWrapper[] = [];
|
||||
const dictionaries = this._state.dictionaries;
|
||||
@ -193,12 +176,8 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.state === EntryStates.REMOVED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const canBeMappedToASuperType = !!SuperTypeMapper[entry.entryType][entry.state](entry);
|
||||
if (!canBeMappedToASuperType && this._userPreferenceService.isIqserDevMode) {
|
||||
if (!canBeMappedToASuperType && this.#isIqserDevMode) {
|
||||
this.#logger.error(
|
||||
`[ENTITY_LOG] Entity ${entry.value} (${entry.entryType}, ${entry.state}) cannot be mapped to a super type!`,
|
||||
entry,
|
||||
@ -207,7 +186,7 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
`Skipping entity ${entry.value} (${entry.entryType}, ${entry.state}). It has unexpected state.
|
||||
Check console for details.`,
|
||||
{
|
||||
timeOut: 15000,
|
||||
timeOut: 10000,
|
||||
easing: 'ease-in-out',
|
||||
easeTime: 500,
|
||||
},
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { clearStamps, stampPDFPage } from '../../../utils';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
import { ViewModeService } from './view-mode.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
|
||||
import { REDDocumentViewer } from '../../pdf-viewer/services/document-viewer.service';
|
||||
import { LicenseService } from '@services/license.service';
|
||||
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||
import { WATERMARK_HORIZONTAL_ALIGNMENTS, WATERMARK_VERTICAL_ALIGNMENTS } from '@red/domain';
|
||||
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||
import { LicenseService } from '@services/license.service';
|
||||
import { clearStamps, stampPDFPage } from '../../../utils';
|
||||
import { REDDocumentViewer } from '../../pdf-viewer/services/document-viewer.service';
|
||||
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
import { ViewModeService } from './view-mode.service';
|
||||
import PDFNet = Core.PDFNet;
|
||||
|
||||
@Injectable()
|
||||
@ -61,7 +61,7 @@ export class StampService {
|
||||
this._translateService.instant('file-preview.excluded-from-redaction') as string,
|
||||
17,
|
||||
'courier',
|
||||
'TOP_LEFT',
|
||||
'DIAGONAL',
|
||||
WATERMARK_HORIZONTAL_ALIGNMENTS.CENTER,
|
||||
WATERMARK_VERTICAL_ALIGNMENTS.CENTER,
|
||||
50,
|
||||
|
||||
@ -147,7 +147,7 @@ export class AnnotationDrawService {
|
||||
|
||||
const annotation = this._pdf.textHighlight();
|
||||
annotation.Quads = this.#rectanglesToQuads(annotationWrapper.positions, pageNumber);
|
||||
annotation.Opacity = annotationWrapper.isIgnored ? DEFAULT_REMOVED_ANNOTATION_OPACITY : DEFAULT_TEXT_ANNOTATION_OPACITY;
|
||||
annotation.Opacity = annotationWrapper.isRemoved ? DEFAULT_REMOVED_ANNOTATION_OPACITY : DEFAULT_TEXT_ANNOTATION_OPACITY;
|
||||
annotation.setContents(annotationWrapper.content);
|
||||
annotation.PageNumber = pageNumber;
|
||||
annotation.StrokeColor = this.convertColor(annotationWrapper.color);
|
||||
@ -159,14 +159,14 @@ export class AnnotationDrawService {
|
||||
this._annotationManager.addToHidden(annotationWrapper.id);
|
||||
}
|
||||
annotation.Hidden =
|
||||
annotationWrapper.isIgnored ||
|
||||
annotationWrapper.isRemoved ||
|
||||
(hideSkipped && annotationWrapper.isSkipped) ||
|
||||
this._annotationManager.isHidden(annotationWrapper.id);
|
||||
annotation.setCustomData('redact-manager', 'true');
|
||||
annotation.setCustomData('redaction', String(annotationWrapper.isRedacted));
|
||||
annotation.setCustomData('skipped', String(annotationWrapper.isSkipped));
|
||||
annotation.setCustomData('changeLog', String(annotationWrapper.isChangeLogEntry));
|
||||
annotation.setCustomData('changeLogRemoved', String(annotationWrapper.isIgnored));
|
||||
annotation.setCustomData('changeLogRemoved', String(annotationWrapper.isRemoved));
|
||||
annotation.setCustomData('opacity', String(annotation.Opacity));
|
||||
|
||||
const redactionColor = this._defaultColorsService.getColor(dossierTemplateId, 'previewColor');
|
||||
|
||||
@ -77,7 +77,7 @@ export class ReadableRedactionsService {
|
||||
|
||||
setAnnotationsOpacity(annotations: Annotation[], restoreToOriginal = false) {
|
||||
annotations.forEach(annotation => {
|
||||
annotation['Opacity'] = restoreToOriginal ? parseFloat(annotation.getCustomData('opacity')) : 0.5;
|
||||
annotation['Opacity'] = restoreToOriginal ? parseFloat(annotation.getCustomData('opacity')) : 1;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import { catchError } from 'rxjs/operators';
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class RedactionLogService extends GenericService<unknown> {
|
||||
export class EntityLogService extends GenericService<unknown> {
|
||||
protected readonly _defaultModelPath = '';
|
||||
|
||||
async getEntityLog(dossierId: string, fileId: string) {
|
||||
@ -1,12 +1,12 @@
|
||||
import { hexToRgb } from './functions';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import PDFDoc = Core.PDFNet.PDFDoc;
|
||||
import {
|
||||
WATERMARK_HORIZONTAL_ALIGNMENTS,
|
||||
WATERMARK_VERTICAL_ALIGNMENTS,
|
||||
WatermarkHorizontalAlignment,
|
||||
WatermarkVerticalAlignment,
|
||||
} from '@red/domain';
|
||||
import { hexToRgb } from './functions';
|
||||
import PDFDoc = Core.PDFNet.PDFDoc;
|
||||
|
||||
const HORIZONTAL_TEXT_ALIGNMENT_MATRIX = [
|
||||
[-1, 0, 1],
|
||||
@ -62,7 +62,7 @@ export async function stampPDFPage(
|
||||
text: string,
|
||||
fontSize: number,
|
||||
fontType: string,
|
||||
orientation: 'DIAGONAL' | 'HORIZONTAL' | 'VERTICAL' | 'TOP_LEFT',
|
||||
orientation: 'DIAGONAL' | 'HORIZONTAL' | 'VERTICAL',
|
||||
horizontalTextAlignment: WatermarkHorizontalAlignment,
|
||||
verticalTextAlignment: WatermarkVerticalAlignment,
|
||||
opacity: number,
|
||||
@ -117,17 +117,17 @@ export async function stampPDFPage(
|
||||
case 'VERTICAL':
|
||||
await stamper.setRotation(-90);
|
||||
await stamper.setTextAlignment(VERTICAL_TEXT_ALIGNMENT_MATRIX[verticalAlignment + 1][horizontalAlignment + 1]);
|
||||
await stamper.setPosition(10, 20);
|
||||
await stamper.setPosition(10, 15);
|
||||
break;
|
||||
case 'HORIZONTAL':
|
||||
await stamper.setTextAlignment(HORIZONTAL_TEXT_ALIGNMENT_MATRIX[verticalAlignment + 1][horizontalAlignment + 1]);
|
||||
await stamper.setPosition(20, 10);
|
||||
await stamper.setPosition(15, 10);
|
||||
break;
|
||||
case 'DIAGONAL':
|
||||
default:
|
||||
await stamper.setRotation(-45);
|
||||
await stamper.setTextAlignment(DIAGONAL_TEXT_ALIGNMENT_MATRIX[verticalAlignment + 1][horizontalAlignment + 1]);
|
||||
await stamper.setPosition(20, 10);
|
||||
await stamper.setPosition(15, 10);
|
||||
}
|
||||
|
||||
const initialFont = await pdfNet.Font.create(document, convertFont(pdfNet, fontType));
|
||||
|
||||
@ -23,14 +23,28 @@ function wrongSuperTypeHandler(): never | undefined {
|
||||
*/
|
||||
export const SuperTypeMapper: Record<EntityType, Record<EntryState, (entry: IEntityLogEntry) => SuperType | undefined>> = {
|
||||
[EntityTypes.ENTITY]: {
|
||||
[EntryStates.APPLIED]: entry => (entry.manualChanges.length ? SuperTypes.ManualRedaction : SuperTypes.Redaction),
|
||||
[EntryStates.APPLIED]: entry => {
|
||||
const hasManualChanges = entry.manualChanges.length;
|
||||
const hasEngines = entry.engines.length;
|
||||
if (hasManualChanges && !hasEngines) {
|
||||
return SuperTypes.ManualRedaction;
|
||||
}
|
||||
return SuperTypes.Redaction;
|
||||
},
|
||||
[EntryStates.SKIPPED]: () => SuperTypes.Skipped,
|
||||
[EntryStates.IGNORED]: () => SuperTypes.Redaction,
|
||||
[EntryStates.IGNORED]: () => SuperTypes.Skipped,
|
||||
[EntryStates.REMOVED]: wrongSuperTypeHandler,
|
||||
},
|
||||
[EntityTypes.HINT]: {
|
||||
[EntryStates.APPLIED]: wrongSuperTypeHandler,
|
||||
[EntryStates.SKIPPED]: entry => (entry.manualChanges.length ? SuperTypes.ManualHint : SuperTypes.Hint),
|
||||
[EntryStates.SKIPPED]: entry => {
|
||||
const hasManualChanges = entry.manualChanges.length;
|
||||
const hasEngines = entry.engines.length;
|
||||
if (hasManualChanges && !hasEngines) {
|
||||
return SuperTypes.ManualHint;
|
||||
}
|
||||
return SuperTypes.Hint;
|
||||
},
|
||||
[EntryStates.IGNORED]: () => SuperTypes.IgnoredHint,
|
||||
[EntryStates.REMOVED]: wrongSuperTypeHandler,
|
||||
},
|
||||
@ -61,13 +75,13 @@ export const SuperTypeMapper: Record<EntityType, Record<EntryState, (entry: IEnt
|
||||
[EntityTypes.IMAGE]: {
|
||||
[EntryStates.APPLIED]: () => SuperTypes.Redaction,
|
||||
[EntryStates.SKIPPED]: () => SuperTypes.Skipped,
|
||||
[EntryStates.IGNORED]: wrongSuperTypeHandler,
|
||||
[EntryStates.IGNORED]: () => SuperTypes.Skipped,
|
||||
[EntryStates.REMOVED]: wrongSuperTypeHandler,
|
||||
},
|
||||
[EntityTypes.IMAGE_HINT]: {
|
||||
[EntryStates.APPLIED]: wrongSuperTypeHandler,
|
||||
[EntryStates.SKIPPED]: () => SuperTypes.Hint,
|
||||
[EntryStates.IGNORED]: wrongSuperTypeHandler,
|
||||
[EntryStates.IGNORED]: () => SuperTypes.IgnoredHint,
|
||||
[EntryStates.REMOVED]: wrongSuperTypeHandler,
|
||||
},
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user