Subfilters

This commit is contained in:
Adina Țeudan 2020-10-18 23:18:23 +03:00 committed by Timo Bejan
parent 0979287274
commit 89ba7efc36
8 changed files with 125 additions and 21 deletions

View File

@ -50,3 +50,15 @@
.ignore {
background-color: $grey-5;
}
.hint_only {
background-color: $orange-1;
}
.vertebrate {
background-color: $green-1;
}
.names {
background-color: $yellow-2;
}

View File

@ -56,17 +56,34 @@
<div class="all-caps-label" translate="file-preview.filter-menu.filter-types.label"></div>
<div class="actions">
<div class="all-caps-label primary pointer" translate="file-preview.filter-menu.all.label"
(click)="setAllFilters(true); $event.stopPropagation();"></div>
(click)="setAllFilters(filters, true); applyFilters(); $event.stopPropagation();"></div>
<div class="all-caps-label primary pointer" translate="file-preview.filter-menu.none.label"
(click)="setAllFilters(false); $event.stopPropagation();"></div>
(click)="setAllFilters(filters, false); applyFilters(); $event.stopPropagation();"></div>
</div>
</div>
<div class="mat-menu-item" *ngFor="let key of filterKeys" (click)="$event.stopPropagation()">
<mat-checkbox [(ngModel)]="filters[key]" (change)="applyFilters()" color="primary">
<redaction-annotation-icon [type]="key"></redaction-annotation-icon>
{{"file-preview.filter-menu."+ key + ".label" | translate }}
</mat-checkbox>
<div *ngFor="let key of filterKeys()">
<div class="mat-menu-item" (click)="$event.stopPropagation()">
<mat-checkbox [checked]="isChecked(key)"
[indeterminate]="isIndeterminate(key)"
(change)="setAllFilters(filters[key], $event.checked, hasSubsections(filters[key]) ? null : key)"
color="primary">
<redaction-annotation-icon [type]="key"></redaction-annotation-icon>
{{"file-preview.filter-menu." + key + ".label" | translate }}
</mat-checkbox>
</div>
<div *ngIf="hasSubsections(filters[key])">
<div *ngFor="let subkey of filterKeys(key)"
class="padding-left mat-menu-item"
(click)="$event.stopPropagation()"
>
<mat-checkbox [(ngModel)]="filters[key][subkey]" (change)="applyFilters()" color="primary">
<redaction-annotation-icon [type]="key + ' ' + subkey"></redaction-annotation-icon>
{{"file-preview.filter-menu." + key + "." + subkey + ".label" | translate }}
</mat-checkbox>
</div>
</div>
</div>
</mat-menu>
</div>
</div>
@ -94,7 +111,7 @@
(click)="selectAnnotation(annotation)"
>
<redaction-annotation-icon [type]="getType(annotation)"></redaction-annotation-icon>
<redaction-annotation-icon [type]="getType(annotation) + ' ' + getDictionary(annotation)"></redaction-annotation-icon>
<div class="flex-1">
<div><strong>{{getType(annotation) | translate}}</strong></div>
<div><strong><span translate="dictionary"></span>: </strong>{{getDictionary(annotation)}}</div>

View File

@ -82,7 +82,11 @@ export class FilePreviewScreenComponent implements OnInit {
return this._userService.user;
}
public get filterKeys() {
public filterKeys(key?: string) {
if (key) {
return Object.keys(this.filters[key]);
}
return Object.keys(this.filters);
}
@ -272,13 +276,36 @@ export class FilePreviewScreenComponent implements OnInit {
});
}
public setAllFilters(value: boolean) {
Object.keys(this.filters).map((key) => {
this.filters[key] = value;
});
public setAllFilters(filter: AnnotationFilters, value: boolean, rootKey?: string) {
if (rootKey) {
this.filters[rootKey] = value;
} else {
for (const key of Object.keys(filter)) {
if (AnnotationUtils.hasSubsections(filter[key])) {
this.setAllFilters(filter[key], value);
} else {
filter[key] = value;
}
}
}
this.applyFilters();
}
public isChecked(key: string): boolean {
return AnnotationUtils.isChecked(this.filters[key]);
}
public isIndeterminate(key: string): boolean {
return AnnotationUtils.isIndeterminate(this.filters[key]);
}
public get hasActiveFilters(): boolean {
return AnnotationUtils.hasActiveFilters(this.filters);
}
public hasSubsections(filter: AnnotationFilters | boolean) {
return AnnotationUtils.hasSubsections(filter);
}
}

View File

@ -9,7 +9,11 @@ export class FiltersService {
}
private _filters: AnnotationFilters = {
hint: false,
hint: {
hint_only: false,
vertebrate: false,
names: false,
},
redaction: false,
comment: false,
suggestion: false,

View File

@ -17,8 +17,31 @@ export class AnnotationUtils {
});
}
public static hasActiveFilters(filters: AnnotationFilters): boolean {
return Object.keys(filters).filter(type => filters[type]).length > 0;
public static hasSubsections(filter: AnnotationFilters | boolean) {
return filter instanceof Object;
}
public static checkedSubkeys(filter: AnnotationFilters | boolean) {
return Object.keys(filter).filter(subkey => this.isChecked(filter[subkey])).length;
}
// Only some of the sub-items are selected
public static isIndeterminate(filter: AnnotationFilters | boolean): boolean {
return this.hasSubsections(filter) ? AnnotationUtils.checkedSubkeys(filter) > 0 && !this.isChecked(filter) : false;
}
// All sub-items are selected
public static isChecked(filter: AnnotationFilters | boolean): boolean {
return this.hasSubsections(filter) ?
AnnotationUtils.checkedSubkeys(filter) === Object.keys(filter).length :
filter as boolean;
}
public static hasActiveFilters(filter: AnnotationFilters): boolean {
const activeFilters = Object.keys(filter).filter(key => {
return this.isChecked(filter[key]) || this.isIndeterminate(filter[key]);
});
return activeFilters.length > 0;
}
public static parseAnnotations(annotations: Annotations.Annotation[], filters: AnnotationFilters):
@ -28,9 +51,16 @@ export class AnnotationUtils {
for (const ann of annotations) {
const pageNumber = ann.getPageNumber();
const type = this.getType(ann);
const dictionary = this.getDictionary(ann);
if (this.hasActiveFilters(filters) && !filters[type]) {
continue;
if (this.hasActiveFilters(filters)) {
if (!this.hasSubsections(filters[type]) && !filters[type]) {
continue;
}
if (this.hasSubsections(filters[type]) && !filters[type][dictionary]) {
continue;
}
}
if (!obj[pageNumber]) {
@ -54,7 +84,6 @@ export class AnnotationUtils {
return obj;
}
public static addAnnotations(initialAnnotations: Annotations.Annotation[], addedAnnotations: Annotations.Annotation[]) {
for (const annotation of addedAnnotations) {
if (annotation.Id.indexOf(':') > 0) {

View File

@ -362,7 +362,16 @@
"label": "Filter types"
},
"hint": {
"label": "Hint annotation"
"label": "Hint annotation",
"hint_only": {
"label": "Hint only"
},
"vertebrate": {
"label": "Vertebrate"
},
"names": {
"label": "Names"
}
},
"redaction": {
"label": "Redaction"

View File

@ -9,6 +9,10 @@
font-size: 13px;
color: $accent;
&.padding-left {
padding-left: 40px;
}
.mat-checkbox-layout {
width: 100%;

View File

@ -14,8 +14,10 @@ $blue-3: #5B97DB;
$blue-4: #374C81;
$red-1: #DD4D50;
$yellow-1: #FFB83B;
$green-1: #46CE7D;
$yellow-2: #FFFF02;
$green-1: #00FF00;
$green-2: #5CE594;
$orange-1: #FF801A;
$primary: $red-1;
$accent: $grey-1;