RED-4416: Annotation colors

This commit is contained in:
Adina Țeudan 2022-07-10 01:39:19 +03:00
parent 80cef8bad6
commit d9435b8b4d
25 changed files with 209 additions and 213 deletions

View File

@ -1,6 +1,16 @@
import { annotationTypesTranslations, SuggestionAddFalsePositive } from '@translations/annotation-types-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Highlight, IComment, IManualChange, IPoint, IRectangle, LogEntryStatus, ManualRedactionType } from '@red/domain';
import {
AnnotationIconType,
Dictionary,
Highlight,
IComment,
IManualChange,
IPoint,
IRectangle,
LogEntryStatus,
ManualRedactionType,
} from '@red/domain';
import { RedactionLogEntry } from '@models/file/redaction-log.entry';
import {
FalsePositiveSuperTypes,
@ -10,7 +20,7 @@ import {
SuperType,
SuperTypes,
} from '@models/file/super-types';
import { IListable, List } from '@iqser/common-ui';
import { IListable, KeysOf, List } from '@iqser/common-ui';
export class AnnotationWrapper implements IListable, Record<string, unknown> {
[x: string]: unknown;
@ -91,6 +101,10 @@ export class AnnotationWrapper implements IListable, Record<string, unknown> {
return this.isSuggestion || this.isDeclinedSuggestion;
}
get colorKey(): KeysOf<Dictionary> {
return this.isSkipped ? 'skippedHexColor' : this.isRecommendation ? 'recommendationHexColor' : 'hexColor';
}
get isSkipped() {
return this.superType === SuperTypes.Skipped;
}
@ -139,6 +153,10 @@ export class AnnotationWrapper implements IListable, Record<string, unknown> {
return this.superType === SuperTypes.TextHighlight;
}
get iconShape(): AnnotationIconType {
return this.isRecommendation ? 'hexagon' : this.isHint ? 'circle' : this.isSuggestion ? 'rhombus' : 'square';
}
get isIgnoredHint() {
return this.superType === SuperTypes.IgnoredHint;
}

View File

@ -83,7 +83,11 @@
</div>
<div class="cell center">
<redaction-annotation-icon [dictionary]="dict" [type]="dict.hint ? 'circle' : 'square'"></redaction-annotation-icon>
<redaction-annotation-icon
[color]="dict.hexColor"
[label]="dict.label.charAt(0)"
[type]="dict.hint ? 'circle' : 'square'"
></redaction-annotation-icon>
</div>
<div class="cell">

View File

@ -19,10 +19,6 @@
margin-top: 16px;
display: flex;
align-items: center;
redaction-dictionary-annotation-icon {
margin-right: 8px;
}
}
redaction-dictionary-manager {

View File

@ -11,7 +11,16 @@ import {
TableColumnConfig,
WorkflowConfig,
} from '@iqser/common-ui';
import { Dossier, File, IFileAttributeConfig, ProcessingType, StatusSorter, WorkflowFileStatus, WorkflowFileStatuses } from '@red/domain';
import {
AnnotationShapeMap,
Dossier,
File,
IFileAttributeConfig,
ProcessingType,
StatusSorter,
WorkflowFileStatus,
WorkflowFileStatuses,
} from '@red/domain';
import { workflowFileStatusTranslations } from '@translations/file-status-translations';
import { PermissionsService } from '@services/permissions.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -277,6 +286,7 @@ export class ConfigService {
new NestedFilter({
id: item,
label: workloadTranslations[item],
metadata: { shape: AnnotationShapeMap[item] },
}),
);

View File

@ -1,6 +1,6 @@
import { Injectable, TemplateRef } from '@angular/core';
import { ButtonConfig, IFilterGroup, INestedFilter, keyChecker, NestedFilter, TableColumnConfig } from '@iqser/common-ui';
import { Dossier, DossierTemplate, StatusSorter, User, WorkflowFileStatus } from '@red/domain';
import { AnnotationShapeMap, Dossier, DossierTemplate, StatusSorter, User, WorkflowFileStatus } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { TranslateService } from '@ngx-translate/core';
import { UserPreferenceService } from '@services/user-preference.service';
@ -145,6 +145,7 @@ export class ConfigService {
new NestedFilter({
id: type,
label: workloadTranslations[type],
metadata: { shape: AnnotationShapeMap[type] },
}),
);

View File

@ -32,12 +32,17 @@ export class TypeAnnotationIconComponent implements OnChanges {
this.color = this.annotation.color;
} else {
const type = this.annotation.isSuperTypeBasedColor ? this.annotation.superType : this.annotation.type;
this.color = this._dictionariesMapService.getDictionaryColor(
type,
this._dossierTemplateId,
isRecommendation,
isSkipped || isIgnoredHint,
);
if (type === 'dossier_redaction') {
this.color = this.screenStateService.dossierDictionary[this.annotation.colorKey] as string;
} else {
// todo: use annotation.colorKey
this.color = this._dictionariesMapService.getDictionaryColor(
type,
this._dossierTemplateId,
isRecommendation,
isSkipped || isIgnoredHint,
);
}
}
this.type =

View File

@ -101,18 +101,5 @@
</ng-template>
<ng-template #annotationFilterTemplate let-filter="filter">
<redaction-type-filter
*ngIf="filter.topLevelFilter"
[dossierTemplateId]="state.dossierTemplateId"
[filter]="filter"
></redaction-type-filter>
<ng-container *ngIf="!filter.topLevelFilter">
<redaction-dictionary-annotation-icon
[dictionaryKey]="filter.id"
[dossierTemplateId]="state.dossierTemplateId"
></redaction-dictionary-annotation-icon>
{{ filter.label }}
</ng-container>
<redaction-type-filter [dossierTemplateId]="state.dossierTemplateId" [filter]="filter"></redaction-type-filter>
</ng-template>

View File

@ -53,10 +53,6 @@
}
}
::ng-deep redaction-dictionary-annotation-icon {
margin-right: 8px;
}
.analysis-progress {
padding: 12px 20px;
max-width: 400px;

View File

@ -194,7 +194,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this._loadingService.start();
this._annotationManager.hide(annotations);
const highlights = await this._fileDataService.loadTextHighlights();
await this._annotationDrawService.draw(highlights, this.state.dossierTemplateId, this._skippedService.hideSkipped);
await this._annotationDrawService.draw(
highlights,
this.state.dossierTemplateId,
this._skippedService.hideSkipped,
this.state.dossierDictionary,
);
this._loadingService.stop();
}
}
@ -595,7 +600,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this._handleDeltaAnnotationFilters(currentFilters);
}
await this._annotationDrawService.draw(newAnnotations, this.state.dossierTemplateId, this._skippedService.hideSkipped);
await this._annotationDrawService.draw(
newAnnotations,
this.state.dossierTemplateId,
this._skippedService.hideSkipped,
this.state.dossierDictionary,
);
}
private _handleDeltaAnnotationFilters(currentFilters: NestedFilter[]) {

View File

@ -235,7 +235,12 @@ export class AnnotationActionsService {
annotationWrapper.resizing = false;
this._annotationManager.delete(annotationWrapper);
await this._annotationDrawService.draw([annotationWrapper], this._state.dossierTemplateId, this._skippedService.hideSkipped);
await this._annotationDrawService.draw(
[annotationWrapper],
this._state.dossierTemplateId,
this._skippedService.hideSkipped,
this._state.dossierDictionary,
);
this._annotationManager.deselect();
await this._fileDataService.annotationsChanged();
}
@ -275,6 +280,7 @@ export class AnnotationActionsService {
annotation.FillColor = this._annotationDrawService.getAndConvertColor(
annotationWrapper.superType,
dossierTemplateId,
this._state.dossierDictionary,
annotationWrapper.type,
);
annotation.StrokeColor = annotation.FillColor;

View File

@ -65,27 +65,34 @@ export class AnnotationProcessingService {
} else {
// top level filter
if (topLevelFilter) {
this._createParentFilter(
a.isHighlight ? a.filterKey : a.superType,
filterMap,
filters,
a.isHighlight,
a.isHighlight ? a.color : null,
);
this._createParentFilter(a.isHighlight ? a.filterKey : a.superType, filterMap, filters, a.isHighlight, {
color: a.isHighlight ? a.color : null,
shortLabel: a.isHighlight ? '' : null,
shape: a.iconShape,
});
} else {
let parentFilter = filterMap.get(a.superType);
if (!parentFilter) {
parentFilter = this._createParentFilter(a.superType, filterMap, filters);
}
const dictionary =
a.type === 'dossier_redaction'
? this.#state.dossierDictionary
: this.#dictionariesMapService.getDictionary(a.type, this.#state.dossierTemplateId);
if (!parentFilter) {
parentFilter = this._createParentFilter(a.superType, filterMap, filters, false, {
shape: a.iconShape,
});
}
const childFilter: IFilter = {
id: a.filterKey,
label: dictionary.label,
checked: false,
matches: 1,
metadata: {
color: dictionary[a.colorKey],
shape: a.iconShape,
},
skipTranslation: true,
};
filterMap.set(a.filterKey, childFilter);
parentFilter.children.push(new Filter(childFilter));
@ -154,7 +161,7 @@ export class AnnotationProcessingService {
filterMap: Map<string, INestedFilter>,
filters: INestedFilter[],
skipTranslation = false,
color?: string,
metadata?: Record<string, any>,
) {
const filter: INestedFilter = new NestedFilter({
id: key,
@ -162,7 +169,7 @@ export class AnnotationProcessingService {
matches: 1,
label: skipTranslation ? key : annotationTypesTranslations[key],
skipTranslation,
color,
metadata,
});
filterMap.set(key, filter);
filters.push(filter);

View File

@ -149,7 +149,12 @@ export class PdfProxyService {
private _configureElements() {
const dossierTemplateId = this._state.dossierTemplateId;
const color = this._annotationDrawService.getAndConvertColor(dossierTemplateId, dossierTemplateId, 'manual');
const color = this._annotationDrawService.getAndConvertColor(
dossierTemplateId,
dossierTemplateId,
this._state.dossierDictionary,
'manual',
);
this._documentViewer.setRectangleToolStyles(color);
}

View File

@ -1,11 +1,11 @@
import { Injectable } from '@angular/core';
import { Core } from '@pdftron/webviewer';
import { hexToRgb } from '../../../utils';
import { hexToRgb } from '@utils/functions';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { UserPreferenceService } from '@services/user-preference.service';
import { RedactionLogService } from '@services/files/redaction-log.service';
import { IRectangle, ISectionGrid, ISectionRectangle } from '@red/domain';
import { Dictionary, IRectangle, ISectionGrid, ISectionRectangle } from '@red/domain';
import { firstValueFrom } from 'rxjs';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { SuperTypes } from '@models/file/super-types';
@ -32,16 +32,16 @@ export class AnnotationDrawService {
private readonly _documentViewer: REDDocumentViewer,
) {}
async draw(annotations: List<AnnotationWrapper>, dossierTemplateId: string, hideSkipped: boolean) {
async draw(annotations: List<AnnotationWrapper>, dossierTemplateId: string, hideSkipped: boolean, dossierDictionary: Dictionary) {
try {
await this._draw(annotations, dossierTemplateId, hideSkipped);
await this._draw(annotations, dossierTemplateId, hideSkipped, dossierDictionary);
} catch (e) {
console.log(e);
}
}
getAndConvertColor(superType: string, dossierTemplateId: string, dictionary?: string) {
return this.convertColor(this.#getColor(superType, dossierTemplateId, dictionary));
getAndConvertColor(superType: string, dossierTemplateId: string, dossierDictionary: Dictionary, type?: string) {
return this.convertColor(this.#getColor(superType, dossierTemplateId, type, dossierDictionary));
}
convertColor(hexColor: string) {
@ -64,31 +64,45 @@ export class AnnotationDrawService {
return this._pdf.quad(x1, y1, x2, y2, x3, y3, x4, y4);
}
#getColor(superType: string, dossierTemplateId: string, dictionary?: string) {
#getColor(superType: string, dossierTemplateId: string, type: string, dossierDictionary: Dictionary) {
let color: string;
let dictionary: Dictionary;
if (type === 'dossier_redaction') {
dictionary = dossierDictionary;
} else {
dictionary = this._dictionariesMapService.getDictionary(type, dossierTemplateId);
}
switch (superType) {
case SuperTypes.Hint:
case SuperTypes.Redaction:
color = this._dictionariesMapService.getDictionaryColor(dictionary, dossierTemplateId);
color = dictionary.hexColor;
break;
case SuperTypes.Recommendation:
color = this._dictionariesMapService.getDictionaryColor(dictionary, dossierTemplateId, true);
color = dictionary.recommendationHexColor;
break;
case SuperTypes.Skipped:
case SuperTypes.IgnoredHint:
color = this._dictionariesMapService.getDictionaryColor(dictionary, dossierTemplateId, false, true);
color = dictionary.skippedHexColor;
break;
default:
color = this._dictionariesMapService.getDictionaryColor(superType, dossierTemplateId);
color = dictionary.hexColor;
break;
}
return color;
}
private async _draw(annotationWrappers: List<AnnotationWrapper>, dossierTemplateId: string, hideSkipped: boolean) {
private async _draw(
annotationWrappers: List<AnnotationWrapper>,
dossierTemplateId: string,
hideSkipped: boolean,
dossierDictionary: Dictionary,
) {
const totalPages = await firstValueFrom(this._pdf.totalPages$);
const annotations = annotationWrappers
.map(annotation => this._computeAnnotation(annotation, dossierTemplateId, hideSkipped, totalPages))
.map(annotation => this._computeAnnotation(annotation, dossierTemplateId, hideSkipped, totalPages, dossierDictionary))
.filterTruthy();
const documentLoaded = await firstValueFrom(this._documentViewer.loaded$);
if (!documentLoaded) {
@ -100,22 +114,27 @@ export class AnnotationDrawService {
const { dossierId, fileId } = this._pdf;
const sectionsGrid$ = this._redactionLogService.getSectionGrid(dossierId, fileId);
const sectionsGrid = await firstValueFrom(sectionsGrid$).catch(() => ({ rectanglesPerPage: {} }));
await this._drawSections(sectionsGrid, dossierTemplateId);
await this._drawSections(sectionsGrid, dossierTemplateId, dossierDictionary);
}
}
private async _drawSections(sectionGrid: ISectionGrid, dossierTemplateId: string) {
private async _drawSections(sectionGrid: ISectionGrid, dossierTemplateId: string, dossierDictionary: Dictionary) {
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(dossierTemplateId, parseInt(page, 10), sectionRectangle));
sections.push(this._computeSection(dossierTemplateId, parseInt(page, 10), sectionRectangle, dossierDictionary));
});
}
await this._annotationManager.add(sections);
}
private _computeSection(dossierTemplateId: string, pageNumber: number, sectionRectangle: ISectionRectangle) {
private _computeSection(
dossierTemplateId: string,
pageNumber: number,
sectionRectangle: ISectionRectangle,
dossierDictionary: Dictionary,
) {
const rectangleAnnot = this._pdf.rectangle();
const pageHeight = this._documentViewer.getHeight(pageNumber);
const rectangle: IRectangle = {
@ -130,13 +149,19 @@ export class AnnotationDrawService {
rectangleAnnot.Width = rectangle.width + 2;
rectangleAnnot.Height = rectangle.height + 2;
rectangleAnnot.ReadOnly = true;
rectangleAnnot.StrokeColor = this.getAndConvertColor('analysis', dossierTemplateId, 'analysis');
rectangleAnnot.StrokeColor = this.getAndConvertColor('analysis', dossierTemplateId, dossierDictionary, 'analysis');
rectangleAnnot.StrokeThickness = 1;
return rectangleAnnot;
}
private _computeAnnotation(annotationWrapper: AnnotationWrapper, dossierTemplateId: string, hideSkipped: boolean, totalPages: number) {
private _computeAnnotation(
annotationWrapper: AnnotationWrapper,
dossierTemplateId: string,
hideSkipped: boolean,
totalPages: number,
dossierDictionary: Dictionary,
) {
const pageNumber = this._pdf.isCompare ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
if (pageNumber > totalPages) {
// skip imported annotations from files that have more pages than the current one
@ -165,7 +190,12 @@ export class AnnotationDrawService {
annotation.Opacity = annotationWrapper.isChangeLogRemoved ? DEFAULT_REMOVED_ANNOTATION_OPACITY : DEFAULT_TEXT_ANNOTATION_OPACITY;
annotation.setContents(annotationWrapper.content);
annotation.PageNumber = pageNumber;
annotation.StrokeColor = this.getAndConvertColor(annotationWrapper.superType, dossierTemplateId, annotationWrapper.type);
annotation.StrokeColor = this.getAndConvertColor(
annotationWrapper.superType,
dossierTemplateId,
dossierDictionary,
annotationWrapper.type,
);
annotation.Id = annotationWrapper.id;
annotation.ReadOnly = true;
@ -180,10 +210,10 @@ export class AnnotationDrawService {
annotation.setCustomData('changeLog', String(annotationWrapper.isChangeLogEntry));
annotation.setCustomData('changeLogRemoved', String(annotationWrapper.isChangeLogRemoved));
annotation.setCustomData('opacity', String(annotation.Opacity));
annotation.setCustomData('redactionColor', String(this.#getColor('redaction', dossierTemplateId, 'preview')));
annotation.setCustomData('redactionColor', String(this.#getColor('redaction', dossierTemplateId, 'preview', dossierDictionary)));
annotation.setCustomData(
'annotationColor',
String(this.#getColor(annotationWrapper.superType, dossierTemplateId, annotationWrapper.type)),
String(this.#getColor(annotationWrapper.superType, dossierTemplateId, annotationWrapper.type, dossierDictionary)),
);
return annotation;

View File

@ -1,10 +1,3 @@
<div
#icon
[class.hint]="isHint"
[class.none]="type === 'none'"
[class.recommendation]="isRecommendation"
[class.request]="isRequest"
class="icon"
>
<span>{{ label || dictionary?.label?.charAt(0) }}</span>
<div #icon [class]="'icon ' + type">
<span>{{ label }}</span>
</div>

View File

@ -14,7 +14,7 @@
background-color: var(--color);
}
.request {
.rhombus {
transform: scale(0.8) rotate(45deg);
span {
@ -23,7 +23,7 @@
}
}
.recommendation {
.hexagon {
position: relative;
width: 16px;
height: 10px;
@ -52,15 +52,10 @@
}
}
.hint,
.skipped {
.circle {
border-radius: 50%;
}
.skipped {
background-color: var(--iqser-grey-5);
}
.none {
color: var(--iqser-accent);
}

View File

@ -1,36 +1,19 @@
import { Component, ElementRef, Input, OnChanges, ViewChild } from '@angular/core';
import { Dictionary } from '@red/domain';
import { AnnotationIconType } from '@red/domain';
@Component({
selector: 'redaction-annotation-icon',
selector: 'redaction-annotation-icon [color] [type] [label]',
templateUrl: './annotation-icon.component.html',
styleUrls: ['./annotation-icon.component.scss'],
})
export class AnnotationIconComponent implements OnChanges {
@Input() color: string;
@Input() type: 'square' | 'rhombus' | 'circle' | 'hexagon' | 'none';
@Input() type: AnnotationIconType;
@Input() label: string;
@Input() dictionary: Dictionary;
@ViewChild('icon', { static: true }) icon: ElementRef;
get isHint() {
return this.type === 'circle' || this.dictionary?.type === 'hint';
}
get isRequest() {
return this.type === 'rhombus' || this.dictionary?.type === 'redaction';
}
get isRecommendation() {
return this.type === 'hexagon' || this.dictionary?.type === 'recommendation';
}
get backgroundColor() {
return this.color || this.dictionary?.hexColor;
}
ngOnChanges() {
this.icon.nativeElement.style.setProperty('--color', this.backgroundColor);
this.icon.nativeElement.style.setProperty('--color', this.color);
}
}

View File

@ -1 +0,0 @@
<redaction-annotation-icon [color]="color" [label]="label" [type]="type"></redaction-annotation-icon>

View File

@ -1,27 +0,0 @@
import { Component, Input, OnChanges } from '@angular/core';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
@Component({
selector: 'redaction-dictionary-annotation-icon',
templateUrl: './dictionary-annotation-icon.component.html',
styleUrls: ['./dictionary-annotation-icon.component.scss'],
})
export class DictionaryAnnotationIconComponent implements OnChanges {
@Input() dictionaryKey: string;
@Input() dossierTemplateId: string;
color: string;
label: string;
type: 'square' | 'circle';
constructor(private readonly _dictionariesMapService: DictionariesMapService) {}
ngOnChanges(): void {
if (this.dictionaryKey) {
const dictionary = this._dictionariesMapService.getDictionary(this.dictionaryKey, this.dossierTemplateId);
this.color = this._dictionariesMapService.getDictionaryColor(this.dictionaryKey, this.dossierTemplateId);
this.type = dictionary.hint ? 'circle' : 'square';
this.label = this.dictionaryKey[0].toUpperCase();
}
}
}

View File

@ -1,67 +1,14 @@
<ng-container *ngIf="!filter.icon">
<redaction-annotation-icon
*ngIf="filter.id === 'redaction'"
[color]="dictionaryColor"
label="R"
type="square"
></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="filter.id === 'recommendation'"
[color]="dictionaryColor"
label="R"
type="hexagon"
></redaction-annotation-icon>
<redaction-annotation-icon *ngIf="filter.id === 'hint'" [color]="dictionaryColor" label="H" type="circle"></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="filter.id === 'manual-redaction'"
[color]="dictionaryColor"
label="M"
type="square"
></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="filter.id === 'skipped'"
[color]="dictionaryColor"
label="S"
type="square"
></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="filter.id === 'ignored-hint'"
[color]="dictionaryColor"
label="I"
type="circle"
></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="isSuggestion(filter.id)"
[color]="dictionaryColor"
label="S"
type="rhombus"
></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="needsAnalysis(filter.id)"
[color]="dictionaryColor"
label="A"
type="square"
></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="filter.id === 'declined-suggestion'"
[color]="dictionaryColor"
label="S"
type="rhombus"
></redaction-annotation-icon>
<redaction-annotation-icon *ngIf="filter.id === 'none'" color="transparent" label="-" type="none"></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="filter.id === 'updated'"
[color]="dictionaryColor"
label="U"
type="square"
></redaction-annotation-icon>
<redaction-annotation-icon *ngIf="filter.id === 'image'" [color]="dictionaryColor" label="I" type="square"></redaction-annotation-icon>
<div *ngIf="filter.id === 'comment'">
<mat-icon svgIcon="red:comment"></mat-icon>
</div>
<redaction-annotation-icon *ngIf="filter.color" [color]="filter.color" [label]="''" type="square"></redaction-annotation-icon>
<redaction-annotation-icon
*ngIf="filter.id !== 'comment'"
[color]="color"
[label]="label"
[type]="filter.metadata?.shape"
></redaction-annotation-icon>
</ng-container>
<ng-container *ngIf="filter.icon">

View File

@ -1,35 +1,47 @@
import { Component, Input, OnChanges } from '@angular/core';
import { INestedFilter, Required } from '@iqser/common-ui';
import { INestedFilter } from '@iqser/common-ui';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { SuperTypes } from '@models/file/super-types';
@Component({
selector: 'redaction-type-filter',
selector: 'redaction-type-filter [dossierTemplateId]',
templateUrl: './type-filter.component.html',
styleUrls: ['./type-filter.component.scss'],
})
export class TypeFilterComponent implements OnChanges {
@Input() filter: INestedFilter;
@Input() @Required() dossierTemplateId!: string;
@Input() dossierTemplateId: string;
@Input() dossierId: string;
dictionaryColor: string;
label: string;
color: string;
private _suggestionsKeys = [
'suggestion-remove',
private _suggestionsKeys: string[] = [
SuperTypes.SuggestionRemove,
SuperTypes.SuggestionForceRedaction,
SuperTypes.SuggestionAdd,
SuperTypes.SuggestionRemoveDictionary,
SuperTypes.SuggestionAddDictionary,
SuperTypes.DeclinedSuggestion,
'suggestion',
'suggestion-force-redaction',
'suggestion-add',
'suggestion-remove-dictionary',
'suggestion-add-dictionary',
];
private _needsAnalysisKeys = ['add-dictionary', 'remove-only-here', 'change-legal-basis', 'analysis'];
private _needsAnalysisKeys: string[] = ['remove-only-here', 'analysis'];
constructor(private readonly _dictionariesMapService: DictionariesMapService) {}
isSuggestion = (key: string) => this._suggestionsKeys.includes(key);
needsAnalysis = (key: string) => this._needsAnalysisKeys.includes(key);
ngOnChanges(): void {
this.dictionaryColor = this._dictionariesMapService.getDictionaryColor(this.filter.id, this.dossierTemplateId);
this.label =
this.filter.metadata?.shortLabel === ''
? ''
: this.filter.id === 'none'
? '-'
: this._needsAnalysisKeys.includes(this.filter.id)
? 'A'
: this._suggestionsKeys.includes(this.filter.id)
? 'S'
: this.filter.id.charAt(0);
this.color = this.filter.metadata?.color || (this.filter.id === 'none' ? 'transparent' : this.dictionaryColor);
}
}

View File

@ -10,7 +10,6 @@ import { IconsModule } from '../icons/icons.module';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AnnotationIconComponent } from './components/annotation-icon/annotation-icon.component';
import { DonutChartComponent } from './components/donut-chart/donut-chart.component';
import { DictionaryAnnotationIconComponent } from './components/dictionary-annotation-icon/dictionary-annotation-icon.component';
import { CommonUiModule } from '@iqser/common-ui';
import { SelectComponent } from './components/select/select.component';
import { NavigateLastDossiersScreenDirective } from './directives/navigate-last-dossiers-screen.directive';
@ -46,7 +45,6 @@ const components = [
PaginationComponent,
AnnotationIconComponent,
DonutChartComponent,
DictionaryAnnotationIconComponent,
SelectComponent,
DictionaryManagerComponent,
AssignUserDropdownComponent,

View File

@ -13,6 +13,7 @@ export class DictionariesMapService extends EntitiesMapService<Dictionary, IDict
return this.get(dossierTemplateId, type) || this.get(dossierTemplateId, 'default');
}
// todo is this necessary?
getDictionaryColor(type: string, dossierTemplateId: string, isRecommendation = false, isSkipped = false) {
const defaultColor = '#CCCCCC';
if (!this.get(dossierTemplateId)) {

View File

@ -5,7 +5,7 @@ export class GlobalErrorHandler extends ErrorHandler {
handleError(error: Error): void {
const chunkFailedMessage = /Loading chunk [\d]+ failed/;
console.write(error);
if (error.message.includes('An error happened during access validation')) {
if (error.message?.includes('An error happened during access validation')) {
console.log('User is not authorized to access this page');
}

View File

@ -16,3 +16,23 @@ export type ManualRedactionActions =
| 'undo'
| 'force-redaction'
| 'request-force-redaction';
export const AnnotationIconTypes = {
square: 'square',
rhombus: 'rhombus',
circle: 'circle',
hexagon: 'hexagon',
none: 'none',
} as const;
export type AnnotationIconType = keyof typeof AnnotationIconTypes;
export const AnnotationShapeMap: Record<string, AnnotationIconType> = {
analysis: AnnotationIconTypes.square,
hint: AnnotationIconTypes.circle,
redaction: AnnotationIconTypes.square,
suggestion: AnnotationIconTypes.rhombus,
updated: AnnotationIconTypes.square,
image: AnnotationIconTypes.square,
none: AnnotationIconTypes.none,
};