RED-7980 - update to compute annotation type if state = PENDING, based on its old entity state

This commit is contained in:
Valentin Mihai 2024-03-06 12:59:16 +02:00
parent f16ebc505b
commit e835f27a3d
8 changed files with 38 additions and 29 deletions

View File

@ -9,8 +9,10 @@ import {
Dictionary,
Earmark,
EntityTypes,
EntryState,
EntryStates,
FalsePositiveSuperTypes,
IEntityLog,
IEntityLogEntry,
ILegalBasis,
IPoint,
@ -65,6 +67,7 @@ export class AnnotationWrapper implements IListable {
isRemoved = false;
isRemovedLocally = false;
lastManualChange: ManualRedactionType;
oldState: EntryState;
get isRuleBased() {
return this.engines.includes(LogEntryEngines.RULE);
@ -209,6 +212,7 @@ export class AnnotationWrapper implements IListable {
static fromData(
logEntry: IEntityLogEntry,
allLogEntries: IEntityLogEntry[],
dictionary: Dictionary,
changeLogType: ChangeType,
legalBasisList: ILegalBasis[],
@ -268,7 +272,13 @@ export class AnnotationWrapper implements IListable {
const lastRelevantManualChange = logEntry.manualChanges?.at(-1);
annotationWrapper.lastManualChange = lastRelevantManualChange?.manualRedactionType;
annotationWrapper.pending = lastRelevantManualChange && !lastRelevantManualChange.processed;
annotationWrapper.pending = logEntry.state === EntryStates.PENDING;
if (annotationWrapper.pending) {
const removedEntry = allLogEntries.find(
(e: IEntityLogEntry) => e.id === annotationWrapper.id && e.state === EntryStates.REMOVED,
);
logEntry.oldState = removedEntry?.state;
}
annotationWrapper.superType = SuperTypeMapper[logEntry.entryType][logEntry.state](logEntry);
annotationWrapper.superTypeLabel = annotationTypesTranslations[annotationWrapper.superType];

View File

@ -10,7 +10,7 @@
<div>
<strong>{{ annotation.superTypeLabel | translate }}</strong>
&nbsp;
<strong *ngIf="pending" class="pending-analysis">
<strong *ngIf="annotation.pending" class="pending-analysis">
{{ 'annotation.pending' | translate }}
</strong>
</div>

View File

@ -18,17 +18,4 @@ export class AnnotationCardComponent {
@Input() isSelected = false;
constructor(readonly multiSelectService: MultiSelectService) {}
get pending() {
return (
this.annotation.pending &&
((this.annotation.isModifyDictionary &&
!this.annotation.isRemovedLocally &&
!this.annotation.hasBeenForcedHint &&
this.annotation.lastManualChange !== ManualRedactionTypes.LEGAL_BASIS_CHANGE &&
this.annotation.lastManualChange !== ManualRedactionTypes.RESIZE_LOCALLY) ||
this.annotation.type === ImageCategory.SIGNATURE ||
this.annotation.IMAGE_HINT)
);
}
}

View File

@ -6,7 +6,6 @@
}
.popover {
width: 260px;
padding: 10px;
border-radius: 3px;
background-color: var(--iqser-grey-1);

View File

@ -226,6 +226,7 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
const changeType = this.#getChangeLogType(entry, file);
const annotation = AnnotationWrapper.fromData(
entry,
entityLog.entityLogEntry,
dictionary,
changeType,
entityLog.legalBasis ?? [],

View File

@ -14,23 +14,25 @@ export const SuperTypes = {
export type SuperType = ValuesOf<typeof SuperTypes>;
interface ResolveTypeOptions {
hint: boolean;
pending: boolean;
}
function wrongSuperTypeHandler(): never | undefined {
return undefined;
}
function resolveRedactionType(entry: IEntityLogEntry, hint = false) {
const redaction = hint ? SuperTypes.Hint : SuperTypes.Redaction;
const manualRedaction = hint ? SuperTypes.ManualHint : SuperTypes.ManualRedaction;
function resolveRedactionType(entry: IEntityLogEntry, options?: Partial<ResolveTypeOptions>) {
if (options?.pending && entry.oldState) {
return SuperTypeMapper[entry.entryType][entry.oldState](entry);
}
const manualChanges = entry.manualChanges;
const hasEngines = entry.engines.length;
const lastRelevantManualChange = manualChanges?.at(-1);
if (!!lastRelevantManualChange && !hasEngines) {
const pending = lastRelevantManualChange && !lastRelevantManualChange.processed;
if (pending && entry.dictionaryEntry) {
return redaction;
}
return manualRedaction;
const redaction = options?.hint ? SuperTypes.Hint : SuperTypes.Redaction;
const manualRedaction = options?.hint ? SuperTypes.ManualHint : SuperTypes.ManualRedaction;
if (!entry.engines.length) {
return options?.pending && entry.dictionaryEntry ? redaction : manualRedaction;
}
return redaction;
}
@ -44,48 +46,56 @@ export const SuperTypeMapper: Record<EntityType, Record<EntryState, (entry: IEnt
[EntryStates.SKIPPED]: () => SuperTypes.Skipped,
[EntryStates.IGNORED]: () => SuperTypes.Skipped,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
[EntryStates.PENDING]: entry => resolveRedactionType(entry, { pending: true }),
},
[EntityTypes.HINT]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: entry => resolveRedactionType(entry, true),
[EntryStates.SKIPPED]: entry => resolveRedactionType(entry, { hint: true }),
[EntryStates.IGNORED]: () => SuperTypes.IgnoredHint,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
[EntryStates.PENDING]: entry => resolveRedactionType(entry, { pending: true }),
},
[EntityTypes.FALSE_POSITIVE]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: wrongSuperTypeHandler,
[EntryStates.IGNORED]: wrongSuperTypeHandler,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
[EntryStates.PENDING]: entry => resolveRedactionType(entry, { pending: true }),
},
[EntityTypes.RECOMMENDATION]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: () => SuperTypes.Recommendation,
[EntryStates.IGNORED]: wrongSuperTypeHandler,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
[EntryStates.PENDING]: entry => resolveRedactionType(entry, { pending: true }),
},
[EntityTypes.FALSE_RECOMMENDATION]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: wrongSuperTypeHandler,
[EntryStates.IGNORED]: wrongSuperTypeHandler,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
[EntryStates.PENDING]: entry => resolveRedactionType(entry, { pending: true }),
},
[EntityTypes.AREA]: {
[EntryStates.APPLIED]: () => SuperTypes.Redaction,
[EntryStates.SKIPPED]: wrongSuperTypeHandler,
[EntryStates.IGNORED]: wrongSuperTypeHandler,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
[EntryStates.PENDING]: entry => resolveRedactionType(entry, { pending: true }),
},
[EntityTypes.IMAGE]: {
[EntryStates.APPLIED]: () => SuperTypes.Redaction,
[EntryStates.SKIPPED]: () => SuperTypes.Skipped,
[EntryStates.IGNORED]: () => SuperTypes.Skipped,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
[EntryStates.PENDING]: entry => resolveRedactionType(entry, { pending: true }),
},
[EntityTypes.IMAGE_HINT]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: () => SuperTypes.Hint,
[EntryStates.IGNORED]: () => SuperTypes.IgnoredHint,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
[EntryStates.PENDING]: entry => resolveRedactionType(entry, { pending: true }),
},
};

View File

@ -14,6 +14,7 @@ export interface IEntityLogEntry extends ITrackable {
type: string;
entryType: EntityType;
state: EntryState;
oldState?: EntryState;
value: string;
reason: string;
matchedRule: string;

View File

@ -3,6 +3,7 @@ export const EntryStates = {
SKIPPED: 'SKIPPED',
IGNORED: 'IGNORED',
REMOVED: 'REMOVED',
PENDING: 'PENDING',
} as const;
export type EntryState = (typeof EntryStates)[keyof typeof EntryStates];