finished modifications for annotation changed events

This commit is contained in:
Timo 2021-07-14 17:26:33 +03:00
parent 292e53de24
commit 378ab3f926
13 changed files with 225 additions and 240 deletions

View File

@ -1,24 +1,25 @@
import { UserWrapper } from '@services/user.service';
import { AnnotationWrapper } from './annotation.wrapper';
import { isArray } from 'rxjs/internal-compatibility';
export class AnnotationPermissions {
canUndo: boolean;
canUndo = true;
canAcceptRecommendation: boolean;
canMarkTextOnlyAsFalsePositive: boolean;
canMarkAsFalsePositive: boolean;
canAcceptRecommendation = true;
canMarkTextOnlyAsFalsePositive = true;
canMarkAsFalsePositive = true;
canRemoveOrSuggestToRemoveOnlyHere: boolean;
canRemoveOrSuggestToRemoveFromDictionary: boolean;
canRemoveOrSuggestToRemoveOnlyHere = true;
canRemoveOrSuggestToRemoveFromDictionary = true;
canAcceptSuggestion: boolean;
canRejectSuggestion: boolean;
canAcceptSuggestion = true;
canRejectSuggestion = true;
canForceRedaction: boolean;
canForceRedaction = true;
canChangeLegalBasis: boolean;
canChangeLegalBasis = true;
canRecategorizeImage: boolean;
canRecategorizeImage = true;
get canPerformMultipleRemoveActions() {
return (
@ -30,42 +31,64 @@ export class AnnotationPermissions {
);
}
static forUser(isApprover: boolean, user: UserWrapper, annotation: AnnotationWrapper) {
const permissions: AnnotationPermissions = new AnnotationPermissions();
static forUser(
isApprover: boolean,
user: UserWrapper,
annotations: AnnotationWrapper | AnnotationWrapper[]
) {
if (!isArray(annotations)) {
annotations = [annotations];
}
permissions.canUndo =
(!isApprover && annotation.isSuggestion) ||
(isApprover && annotation.isUndoableActionForApprover);
const summedPermissions: AnnotationPermissions = new AnnotationPermissions();
permissions.canForceRedaction = annotation.isSkipped && !permissions.canUndo;
for (const annotation of annotations) {
const permissions: AnnotationPermissions = new AnnotationPermissions();
permissions.canUndo =
(!isApprover && annotation.isSuggestion) ||
(isApprover && annotation.isUndoableActionForApprover);
permissions.canAcceptRecommendation = annotation.isRecommendation;
permissions.canForceRedaction = annotation.isSkipped && !permissions.canUndo;
permissions.canMarkAsFalsePositive =
annotation.canBeMarkedAsFalsePositive && !annotation.force;
permissions.canMarkTextOnlyAsFalsePositive =
annotation.canBeMarkedAsFalsePositiveWithTextOnly && !annotation.force;
permissions.canAcceptRecommendation = annotation.isRecommendation;
permissions.canRemoveOrSuggestToRemoveOnlyHere = annotation.isRedacted && !annotation.force;
permissions.canRemoveOrSuggestToRemoveFromDictionary =
annotation.isRedacted &&
!annotation.isManualRedaction &&
annotation.isModifyDictionary &&
!annotation.force;
permissions.canMarkAsFalsePositive =
annotation.canBeMarkedAsFalsePositive && !annotation.force;
permissions.canMarkTextOnlyAsFalsePositive =
annotation.canBeMarkedAsFalsePositiveWithTextOnly && !annotation.force;
permissions.canAcceptSuggestion =
isApprover && (annotation.isSuggestion || annotation.isDeclinedSuggestion);
permissions.canRejectSuggestion =
isApprover &&
(annotation.isSuggestion ||
(annotation.isReadyForAnalysis &&
!permissions.canUndo &&
annotation.superType !== 'pending-analysis'));
permissions.canRemoveOrSuggestToRemoveOnlyHere =
annotation.isRedacted && !annotation.force;
permissions.canRemoveOrSuggestToRemoveFromDictionary =
annotation.isRedacted &&
!annotation.isManualRedaction &&
annotation.isModifyDictionary &&
!annotation.force;
permissions.canChangeLegalBasis = !annotation.isManualRedaction && annotation.isRedacted;
permissions.canAcceptSuggestion =
isApprover && (annotation.isSuggestion || annotation.isDeclinedSuggestion);
permissions.canRejectSuggestion =
isApprover &&
(annotation.isSuggestion ||
(annotation.isReadyForAnalysis &&
!permissions.canUndo &&
annotation.superType !== 'pending-analysis'));
permissions.canRecategorizeImage = annotation.isImage;
permissions.canChangeLegalBasis =
!annotation.isManualRedaction && annotation.isRedacted;
return permissions;
permissions.canRecategorizeImage = annotation.isImage;
summedPermissions._merge(permissions);
}
return summedPermissions;
}
private _merge(permissions: AnnotationPermissions) {
for (const key of Object.keys(this)) {
if (typeof this[key] === 'boolean') {
this[key] = this[key] && permissions[key];
}
}
}
}

View File

@ -1,10 +1,13 @@
<div *ngIf="canPerformAnnotationActions" class="annotation-actions">
<redaction-circle-button
(action)="annotationActionsService.changeLegalBasis($event, annotation, annotationsChanged)"
(action)="
annotationActionsService.changeLegalBasis($event, annotations, annotationsChanged)
"
*ngIf="annotationPermissions.canChangeLegalBasis"
icon="red:edit"
tooltip="annotation-actions.edit-reason.label"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
@ -12,64 +15,69 @@
(action)="
annotationActionsService.convertRecommendationToAnnotation(
$event,
[annotation],
annotations,
annotationsChanged
)
"
*ngIf="annotationPermissions.canAcceptRecommendation"
icon="red:check"
tooltip="annotation-actions.accept-recommendation.label"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-circle-button
(action)="
annotationActionsService.acceptSuggestion($event, [annotation], annotationsChanged)
annotationActionsService.acceptSuggestion($event, annotations, annotationsChanged)
"
*ngIf="annotationPermissions.canAcceptSuggestion"
icon="red:check"
tooltip="annotation-actions.accept-suggestion.label"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-circle-button
(action)="
annotationActionsService.undoDirectAction($event, [annotation], annotationsChanged)
annotationActionsService.undoDirectAction($event, annotations, annotationsChanged)
"
*ngIf="annotationPermissions.canUndo"
icon="red:undo"
tooltip="annotation-actions.undo"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-circle-button
(action)="
annotationActionsService.rejectSuggestion($event, [annotation], annotationsChanged)
annotationActionsService.rejectSuggestion($event, annotations, annotationsChanged)
"
*ngIf="annotationPermissions.canRejectSuggestion"
icon="red:trash"
tooltip="annotation-actions.reject-suggestion"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-circle-button
(action)="
annotationActionsService.recategorizeImage($event, annotation, annotationsChanged)
annotationActionsService.recategorizeImage($event, annotations, annotationsChanged)
"
*ngIf="annotationPermissions.canRecategorizeImage"
icon="red:thumb-down"
tooltip="annotation-actions.recategorize-image"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-circle-button
(action)="
annotationActionsService.markAsFalsePositive($event, [annotation], annotationsChanged)
annotationActionsService.markAsFalsePositive($event, annotations, annotationsChanged)
"
*ngIf="
annotationPermissions.canMarkTextOnlyAsFalsePositive &&
@ -77,39 +85,68 @@
"
icon="red:thumb-down"
tooltip="annotation-actions.remove-annotation.false-positive"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-circle-button
(action)="annotationActionsService.forceRedaction($event, [annotation], annotationsChanged)"
(action)="annotationActionsService.forceRedaction($event, annotations, annotationsChanged)"
*ngIf="annotationPermissions.canForceRedaction"
icon="red:thumb-up"
tooltip="annotation-actions.force-redaction.label"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-circle-button
(action)="hideAnnotation($event)"
*ngIf="annotation.isImage && viewerAnnotation?.isVisible()"
*ngIf="isImage && isVisible"
icon="red:visibility-off"
tooltip="annotation-actions.hide"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-circle-button
(action)="showAnnotation($event)"
*ngIf="annotation.isImage && !viewerAnnotation?.isVisible()"
*ngIf="isImage && isVisible"
icon="red:visibility"
tooltip="annotation-actions.show"
type="dark-bg"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
>
</redaction-circle-button>
<redaction-annotation-remove-actions
[annotationsChanged]="annotationsChanged"
[annotations]="[annotation]"
></redaction-annotation-remove-actions>
<redaction-circle-button
(action)="suggestRemoveAnnotations($event, true)"
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveFromDictionary"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
icon="red:remove-from-dict"
tooltip="annotation-actions.remove-annotation.remove-from-dict"
>
</redaction-circle-button>
<redaction-circle-button
(action)="markAsFalsePositive($event)"
*ngIf="annotationPermissions.canMarkAsFalsePositive"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
icon="red:thumb-down"
tooltip="annotation-actions.remove-annotation.false-positive"
>
</redaction-circle-button>
<redaction-circle-button
(action)="suggestRemoveAnnotations($event, false)"
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveOnlyHere"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
icon="red:trash"
tooltip="annotation-actions.remove-annotation.only-here"
>
</redaction-circle-button>
</div>

View File

@ -12,7 +12,10 @@ import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
styleUrls: ['./annotation-actions.component.scss']
})
export class AnnotationActionsComponent implements OnInit {
@Input() annotation: AnnotationWrapper;
@Input() btnType: 'dark-bg' | 'primary' = 'dark-bg';
@Input() tooltipPosition: 'before' | 'above' = 'before';
@Input() _annotations: AnnotationWrapper[];
@Input() canPerformAnnotationActions: boolean;
@Input() viewer: WebViewerInstance;
@ -20,33 +23,80 @@ export class AnnotationActionsComponent implements OnInit {
annotationPermissions: AnnotationPermissions;
viewerAnnotations: Annotations.Annotation[];
constructor(
public appStateService: AppStateService,
public annotationActionsService: AnnotationActionsService,
private _permissionsService: PermissionsService
) {}
get viewerAnnotation(): Annotations.Annotation {
return this.viewer.annotManager.getAnnotationById(this.annotation.id);
get annotations(): AnnotationWrapper[] {
return this._annotations;
}
@Input()
set annotations(value: AnnotationWrapper[]) {
this._annotations = value.filter(a => a !== undefined);
this.viewerAnnotations = this._annotations.map(a =>
this.viewer.annotManager.getAnnotationById(a.id)
);
this._setPermissions();
}
get isVisible() {
return this.viewerAnnotations.reduce(
(accumulator, annotation) => annotation.isVisible() && accumulator,
true
);
}
get isImage() {
return this.annotations.reduce(
(accumulator, annotation) => annotation.isImage && accumulator,
true
);
}
ngOnInit(): void {
this.annotationPermissions = AnnotationPermissions.forUser(
this._permissionsService.isApprover(),
this._permissionsService.currentUser,
this.annotation
this._setPermissions();
}
suggestRemoveAnnotations($event, removeFromDict: boolean) {
$event.stopPropagation();
this.annotationActionsService.suggestRemoveAnnotation(
$event,
this.annotations,
removeFromDict,
this.annotationsChanged
);
}
markAsFalsePositive($event) {
this.annotationActionsService.markAsFalsePositive(
$event,
this.annotations,
this.annotationsChanged
);
}
hideAnnotation($event: MouseEvent) {
$event.stopPropagation();
this.viewer.annotManager.hideAnnotations([this.viewerAnnotation]);
this.viewer.annotManager.hideAnnotations(this.viewerAnnotations);
this.viewer.annotManager.deselectAllAnnotations();
}
showAnnotation($event: MouseEvent) {
$event.stopPropagation();
this.viewer.annotManager.showAnnotations([this.viewerAnnotation]);
this.viewer.annotManager.showAnnotations(this.viewerAnnotations);
this.viewer.annotManager.deselectAllAnnotations();
}
private _setPermissions() {
this.annotationPermissions = AnnotationPermissions.forUser(
this._permissionsService.isApprover(),
this._permissionsService.currentUser,
this.annotations
);
}
}

View File

@ -1,29 +0,0 @@
<redaction-circle-button
(action)="suggestRemoveAnnotations($event, true)"
*ngIf="permissions.canRemoveOrSuggestToRemoveFromDictionary"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
icon="red:remove-from-dict"
tooltip="annotation-actions.remove-annotation.remove-from-dict"
>
</redaction-circle-button>
<redaction-circle-button
(action)="markAsFalsePositive($event)"
*ngIf="permissions.canMarkAsFalsePositive"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
icon="red:thumb-down"
tooltip="annotation-actions.remove-annotation.false-positive"
>
</redaction-circle-button>
<redaction-circle-button
(action)="suggestRemoveAnnotations($event, false)"
*ngIf="permissions.canRemoveOrSuggestToRemoveOnlyHere"
[tooltipPosition]="tooltipPosition"
[type]="btnType"
icon="red:trash"
tooltip="annotation-actions.remove-annotation.only-here"
>
</redaction-circle-button>

View File

@ -1,7 +0,0 @@
:host {
display: flex;
> *:not(:last-child) {
margin-right: 2px;
}
}

View File

@ -1,93 +0,0 @@
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { AnnotationActionsService } from '../../services/annotation-actions.service';
import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { PermissionsService } from '@services/permissions.service';
import { MatMenuTrigger } from '@angular/material/menu';
@Component({
selector: 'redaction-annotation-remove-actions',
templateUrl: './annotation-remove-actions.component.html',
styleUrls: ['./annotation-remove-actions.component.scss']
})
export class AnnotationRemoveActionsComponent {
@Output() menuOpenChange = new EventEmitter<boolean>();
@Input() annotationsChanged: EventEmitter<AnnotationWrapper>;
@Input() menuOpen: boolean;
@Input() btnType: 'dark-bg' | 'primary' = 'dark-bg';
@Input() tooltipPosition: 'before' | 'above' = 'before';
@ViewChild(MatMenuTrigger) matMenuTrigger: MatMenuTrigger;
permissions: {
canRemoveOrSuggestToRemoveOnlyHere: boolean;
canRemoveOrSuggestToRemoveFromDictionary: boolean;
canMarkAsFalsePositive: boolean;
};
constructor(
readonly appStateService: AppStateService,
private readonly _annotationActionsService: AnnotationActionsService,
private readonly _permissionsService: PermissionsService
) {}
private _annotations: AnnotationWrapper[];
get annotations(): AnnotationWrapper[] {
return this._annotations;
}
@Input()
set annotations(value: AnnotationWrapper[]) {
this._annotations = value.filter(a => a !== undefined);
this._setPermissions();
}
suggestRemoveAnnotations($event, removeFromDict: boolean) {
$event.stopPropagation();
this._annotationActionsService.suggestRemoveAnnotation(
$event,
this.annotations,
removeFromDict,
this.annotationsChanged
);
}
markAsFalsePositive($event) {
this._annotationActionsService.markAsFalsePositive(
$event,
this.annotations,
this.annotationsChanged
);
}
private _setPermissions() {
this.permissions = {
canRemoveOrSuggestToRemoveOnlyHere: this._annotationsPermissions([
'canRemoveOrSuggestToRemoveOnlyHere'
]),
canRemoveOrSuggestToRemoveFromDictionary: this._annotationsPermissions([
'canRemoveOrSuggestToRemoveFromDictionary'
]),
canMarkAsFalsePositive: this._annotationsPermissions([
'canMarkAsFalsePositive',
'canMarkTextOnlyAsFalsePositive'
])
};
}
private _annotationsPermissions(keys: string[]): boolean {
return this.annotations.reduce((prevValue, annotation) => {
const annotationPermissions = AnnotationPermissions.forUser(
this._permissionsService.isApprover(),
this._permissionsService.currentUser,
annotation
);
const hasAtLeastOnePermission = keys.reduce(
(acc, key) => acc || annotationPermissions[key],
false
);
return prevValue && hasAtLeastOnePermission;
}, true);
}
}

View File

@ -53,13 +53,13 @@
type="red-bg"
></redaction-round-checkbox>
<span class="all-caps-label">{{ selectedAnnotations?.length || 0 }} selected </span>
<redaction-annotation-remove-actions
<redaction-annotation-actions
*ngIf="selectedAnnotations?.length > 0"
[annotationsChanged]="annotationsChanged"
(annotationsChanged)="annotationsChanged.emit($event)"
[annotations]="selectedAnnotations"
btnType="primary"
tooltipPosition="above"
></redaction-annotation-remove-actions>
></redaction-annotation-actions>
</div>
<redaction-circle-button
(action)="multiSelectActive = false"

View File

@ -30,11 +30,13 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
private readonly _permissionsService: PermissionsService,
private readonly _formBuilder: FormBuilder,
public dialogRef: MatDialogRef<ChangeLegalBasisDialogComponent>,
@Inject(MAT_DIALOG_DATA) public annotation: AnnotationWrapper
@Inject(MAT_DIALOG_DATA) public annotations: AnnotationWrapper[]
) {}
get changed(): boolean {
return this.legalBasisForm.get('reason').value.legalBasis !== this.annotation.legalBasis;
return (
this.legalBasisForm.get('reason').value.legalBasis !== this.annotations[0].legalBasis
);
}
async ngOnInit() {
@ -58,7 +60,7 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
this.legalBasisForm.patchValue({
reason: this.legalOptions.find(
option => option.legalBasis === this.annotation.legalBasis
option => option.legalBasis === this.annotations[0].legalBasis
)
});
}

View File

@ -18,18 +18,18 @@ export class RecategorizeImageDialogComponent implements OnInit {
private readonly _permissionsService: PermissionsService,
private readonly _formBuilder: FormBuilder,
public dialogRef: MatDialogRef<RecategorizeImageDialogComponent>,
@Inject(MAT_DIALOG_DATA) public annotation: AnnotationWrapper
@Inject(MAT_DIALOG_DATA) public annotations: AnnotationWrapper[]
) {}
get changed(): boolean {
return this.recategorizeImageForm.get('type').value !== this.annotation.dictionary;
return this.recategorizeImageForm.get('type').value !== this.annotations[0].dictionary;
}
async ngOnInit() {
this.isDocumentAdmin = this._permissionsService.isApprover();
this.recategorizeImageForm = this._formBuilder.group({
type: [this.annotation.dictionary, Validators.required],
type: [this.annotations[0].dictionary, Validators.required],
comment: this.isDocumentAdmin ? [null] : [null, Validators.required]
});
}

View File

@ -34,7 +34,6 @@ import { PdfViewerDataService } from './services/pdf-viewer-data.service';
import { ManualAnnotationService } from './services/manual-annotation.service';
import { AnnotationDrawService } from './services/annotation-draw.service';
import { AnnotationProcessingService } from './services/annotation-processing.service';
import { AnnotationRemoveActionsComponent } from './components/annotation-remove-actions/annotation-remove-actions.component';
import { DossierDictionaryDialogComponent } from './dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component';
import { EditDossierDialogComponent } from './dialogs/edit-dossier-dialog/edit-dossier-dialog.component';
import { EditDossierGeneralInfoComponent } from './dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component';
@ -84,7 +83,6 @@ const components = [
DossierListingActionsComponent,
DocumentInfoComponent,
FileWorkloadComponent,
AnnotationRemoveActionsComponent,
EditDossierGeneralInfoComponent,
EditDossierDownloadPackageComponent,
EditDossierDictionaryComponent,

View File

@ -201,7 +201,7 @@
<ng-template #annotationActionsTemplate let-annotation="annotation">
<redaction-annotation-actions
(annotationsChanged)="annotationsChangedByReviewAction($event)"
[annotation]="annotation"
[annotations]="[annotation]"
[canPerformAnnotationActions]="canPerformAnnotationActions"
[viewer]="activeViewer"
></redaction-annotation-actions>

View File

@ -76,22 +76,24 @@ export class AnnotationActionsService {
changeLegalBasis(
$event: MouseEvent,
annotation: AnnotationWrapper,
annotations: AnnotationWrapper[],
annotationsChanged: EventEmitter<AnnotationWrapper>
) {
this._dialogService.openChangeLegalBasisDialog(
$event,
annotation,
annotations,
(data: { comment: string; legalBasis: string }) => {
this._processObsAndEmit(
this._manualAnnotationService.changeLegalBasis(
annotation.annotationId,
data.legalBasis,
data.comment
),
annotation,
annotationsChanged
);
annotations.forEach(annotation => {
this._processObsAndEmit(
this._manualAnnotationService.changeLegalBasis(
annotation.annotationId,
data.legalBasis,
data.comment
),
annotation,
annotationsChanged
);
});
}
);
}
@ -142,22 +144,24 @@ export class AnnotationActionsService {
recategorizeImage(
$event: MouseEvent,
annotation: AnnotationWrapper,
annotations: AnnotationWrapper[],
annotationsChanged: EventEmitter<AnnotationWrapper>
) {
this._dialogService.openRecategorizeImageDialog(
$event,
annotation,
annotations,
(data: { type: string; comment: string }) => {
this._processObsAndEmit(
this._manualAnnotationService.recategorizeImage(
annotation.annotationId,
data.type,
data.comment
),
annotation,
annotationsChanged
);
annotations.forEach(annotation => {
this._processObsAndEmit(
this._manualAnnotationService.recategorizeImage(
annotation.annotationId,
data.type,
data.comment
),
annotation,
annotationsChanged
);
});
}
);
}
@ -218,7 +222,7 @@ export class AnnotationActionsService {
title: this._translateService.instant('annotation-actions.recategorize-image'),
onClick: () => {
this._ngZone.run(() => {
this.recategorizeImage(null, annotations[0], annotationsChanged);
this.recategorizeImage(null, annotations, annotationsChanged);
});
}
});

View File

@ -150,13 +150,13 @@ export class DossiersDialogService extends DialogService<DialogType> {
openChangeLegalBasisDialog(
$event: MouseEvent,
annotation: AnnotationWrapper,
annotations: AnnotationWrapper[],
cb?: Function
): MatDialogRef<ChangeLegalBasisDialogComponent> {
$event?.stopPropagation();
const ref = this._dialog.open(ChangeLegalBasisDialogComponent, {
...dialogConfig,
data: annotation
data: annotations
});
ref.afterClosed().subscribe(async result => {
if (result && cb) {
@ -168,13 +168,13 @@ export class DossiersDialogService extends DialogService<DialogType> {
openRecategorizeImageDialog(
$event: MouseEvent,
annotation: AnnotationWrapper,
annotations: AnnotationWrapper[],
cb?: Function
): MatDialogRef<RecategorizeImageDialogComponent> {
$event?.stopPropagation();
const ref = this._dialog.open(RecategorizeImageDialogComponent, {
...dialogConfig,
data: annotation
data: annotations
});
ref.afterClosed().subscribe(async result => {
if (result && cb) {