RED-3791: use existing convert recommendation to annotation action

This commit is contained in:
Dan Percic 2022-07-06 13:53:43 +03:00
parent f4b9595725
commit b7d926046d
5 changed files with 205 additions and 259 deletions

View File

@ -14,6 +14,7 @@ import { FileDataService } from './services/file-data.service';
import { AnnotationsListingService } from './services/annotations-listing.service';
import { StampService } from './services/stamp.service';
import { PdfProxyService } from './services/pdf-proxy.service';
import { PdfAnnotationActionsService } from './services/pdf-annotation-actions.service';
export const filePreviewScreenProviders = [
FilterService,
@ -24,6 +25,7 @@ export const filePreviewScreenProviders = [
CommentingService,
SkippedService,
AnnotationActionsService,
PdfAnnotationActionsService,
FilePreviewStateService,
AnnotationReferencesService,
AnnotationProcessingService,

View File

@ -1,19 +1,13 @@
import { Inject, Injectable, NgZone } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { Injectable } from '@angular/core';
import { ManualRedactionService } from './manual-redaction.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Observable } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';
import { getFirstRelevantTextPart } from '../../../utils';
import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { BASE_HREF } from '../../../tokens';
import { UserService } from '@services/user.service';
import { Core } from '@pdftron/webviewer';
import {
DictionaryEntryTypes,
Dossier,
IAddRedactionRequest,
IHeaderElement,
ILegalBasisChangeRequest,
IRecategorizationRequest,
IRectangle,
@ -33,23 +27,16 @@ import { filter } from 'rxjs/operators';
import { MatDialog } from '@angular/material/dialog';
import { FilePreviewStateService } from './file-preview-state.service';
import { FilePreviewDialogService } from './file-preview-dialog.service';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { FileDataService } from './file-data.service';
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
import { SkippedService } from './skipped.service';
import { REDDocumentViewer } from '../../pdf-viewer/services/document-viewer.service';
import { AnnotationsListingService } from './annotations-listing.service';
@Injectable()
export class AnnotationActionsService {
constructor(
@Inject(BASE_HREF) private readonly _baseHref: string,
private readonly _ngZone: NgZone,
private readonly _userService: UserService,
private readonly _permissionsService: PermissionsService,
private readonly _manualRedactionService: ManualRedactionService,
private readonly _translateService: TranslateService,
private readonly _dialogService: FilePreviewDialogService,
private readonly _dialog: MatDialog,
private readonly _pdf: PdfViewer,
@ -57,11 +44,9 @@ export class AnnotationActionsService {
private readonly _annotationManager: REDAnnotationManager,
private readonly _annotationDrawService: AnnotationDrawService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _dictionariesMapService: DictionariesMapService,
private readonly _state: FilePreviewStateService,
private readonly _fileDataService: FileDataService,
private readonly _skippedService: SkippedService,
private readonly _listingService: AnnotationsListingService,
) {}
private get _dossier(): Dossier {
@ -71,29 +56,25 @@ export class AnnotationActionsService {
acceptSuggestion($event: MouseEvent, annotations: AnnotationWrapper[]) {
$event?.stopPropagation();
const { dossierId, fileId } = this._state;
this._processObsAndEmit(
this._manualRedactionService.approve(
annotations.map(a => a.id),
dossierId,
fileId,
),
);
const ids = annotations.map(a => a.id);
const request = this._manualRedactionService.approve(ids, dossierId, fileId);
this.#processObsAndEmit(request);
}
removeHighlights(highlights: AnnotationWrapper[]): void {
const data = this._getHighlightOperationData(TextHighlightOperation.REMOVE, highlights);
const data = this.#getHighlightOperationData(TextHighlightOperation.REMOVE, highlights);
this._dialogService.openDialog('highlightAction', null, data);
}
convertHighlights(highlights: AnnotationWrapper[]): void {
const data = this._getHighlightOperationData(TextHighlightOperation.CONVERT, highlights);
const data = this.#getHighlightOperationData(TextHighlightOperation.CONVERT, highlights);
this._dialogService.openDialog('highlightAction', null, data);
}
rejectSuggestion($event: MouseEvent, annotations: AnnotationWrapper[]) {
$event?.stopPropagation();
const { dossierId, fileId } = this._state;
this._processObsAndEmit(
this.#processObsAndEmit(
this._manualRedactionService.declineOrRemove(
annotations.map(a => a.id),
dossierId,
@ -107,7 +88,7 @@ export class AnnotationActionsService {
const { dossierId, fileId } = this._state;
const data = { dossier: this._dossier, annotations, hint };
this._dialogService.openDialog('forceAnnotation', $event, data, (request: ILegalBasisChangeRequest) => {
this._processObsAndEmit(
this.#processObsAndEmit(
this._manualRedactionService.bulkForce(
annotations.map(a => ({ ...request, annotationId: a.id })),
dossierId,
@ -132,7 +113,7 @@ export class AnnotationActionsService {
value: data.value,
}));
this._processObsAndEmit(this._manualRedactionService.changeLegalBasis(body, dossierId, fileId));
this.#processObsAndEmit(this._manualRedactionService.changeLegalBasis(body, dossierId, fileId));
},
);
}
@ -151,7 +132,7 @@ export class AnnotationActionsService {
removeFromDictionary,
comment: result.comment,
}));
this._processObsAndEmit(this._manualRedactionService.removeOrSuggestRemove(body, dossierId, fileId, removeFromDictionary));
this.#processObsAndEmit(this._manualRedactionService.removeOrSuggestRemove(body, dossierId, fileId, removeFromDictionary));
});
}
@ -164,7 +145,7 @@ export class AnnotationActionsService {
type,
comment,
}));
this._processObsAndEmit(this._manualRedactionService.recategorizeImage(body, dossierId, fileId));
this.#processObsAndEmit(this._manualRedactionService.recategorizeImage(body, dossierId, fileId));
});
}
@ -173,7 +154,7 @@ export class AnnotationActionsService {
const { dossierId, fileId } = this._state;
const modifyDictionary = annotations[0].isModifyDictionary;
this._processObsAndEmit(
this.#processObsAndEmit(
this._manualRedactionService.undoRequest(
annotations.map(a => a.id),
dossierId,
@ -194,205 +175,10 @@ export class AnnotationActionsService {
const dialogClosed = dialogRef.afterClosed().pipe(filter(value => !!value && !!value.annotations));
dialogClosed.subscribe(({ annotations, comment: commentText }) => {
const comment = commentText ? { text: commentText } : undefined;
this._processObsAndEmit(this._manualRedactionService.addRecommendation(annotations, dossierId, fileId, comment));
this.#processObsAndEmit(this._manualRedactionService.addRecommendation(annotations, dossierId, fileId, comment));
});
}
getViewerAvailableActions(annotations: AnnotationWrapper[]): IHeaderElement[] {
const dossier = this._state.dossier;
const availableActions: IHeaderElement[] = [];
const annotationPermissions = annotations.map(annotation => ({
annotation,
permissions: AnnotationPermissions.forUser(
this._permissionsService.isApprover(dossier),
this._userService.currentUser,
annotation,
this._dictionariesMapService.get(dossier.dossierTemplateId),
),
}));
// you can only resize one annotation at a time
const canResize = annotationPermissions.length === 1 && annotationPermissions[0].permissions.canResizeAnnotation;
if (canResize) {
const firstAnnotation = annotations[0];
// if we already entered resize-mode previously
if (firstAnnotation.resizing) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/check.svg'),
title: this._translateService.instant('annotation-actions.resize-accept.label'),
onClick: () =>
this._ngZone.run(async () => {
await this.acceptResize(null, firstAnnotation);
}),
});
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/close.svg'),
title: this._translateService.instant('annotation-actions.resize-cancel.label'),
onClick: () => this._ngZone.run(() => this.cancelResize(null, firstAnnotation)),
});
return availableActions;
}
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/resize.svg'),
title: this._translateService.instant('annotation-actions.resize.label'),
onClick: () => this._ngZone.run(() => this.resize(null, annotations[0])),
});
}
const canChangeLegalBasis = annotationPermissions.reduce((acc, next) => acc && next.permissions.canChangeLegalBasis, true);
if (canChangeLegalBasis) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/edit.svg'),
title: this._translateService.instant('annotation-actions.edit-reason.label'),
onClick: () =>
this._ngZone.run(() => {
this.changeLegalBasis(null, annotations);
}),
});
}
const canRecategorizeImage = annotationPermissions.reduce((acc, next) => acc && next.permissions.canRecategorizeImage, true);
if (canRecategorizeImage) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/thumb-down.svg'),
title: this._translateService.instant('annotation-actions.recategorize-image'),
onClick: () =>
this._ngZone.run(() => {
this.recategorizeImages(null, annotations);
}),
});
}
const canRemoveOrSuggestToRemoveFromDictionary = annotationPermissions.reduce(
(acc, next) => acc && next.permissions.canRemoveOrSuggestToRemoveFromDictionary,
true,
);
if (canRemoveOrSuggestToRemoveFromDictionary) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/remove-from-dict.svg'),
title: this._translateService.instant('annotation-actions.remove-annotation.remove-from-dict'),
onClick: () =>
this._ngZone.run(() => {
this.removeOrSuggestRemoveAnnotation(null, annotations, true);
}),
});
}
const canAcceptRecommendation = annotationPermissions.reduce((acc, next) => acc && next.permissions.canAcceptRecommendation, true);
if (canAcceptRecommendation) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/check.svg'),
title: this._translateService.instant('annotation-actions.accept-recommendation.label'),
onClick: () =>
this._ngZone.run(() => {
this.convertRecommendationToAnnotation(null, annotations);
}),
});
}
const canAcceptSuggestion = annotationPermissions.reduce((acc, next) => acc && next.permissions.canAcceptSuggestion, true);
if (canAcceptSuggestion) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/check.svg'),
title: this._translateService.instant('annotation-actions.accept-suggestion.label'),
onClick: () =>
this._ngZone.run(() => {
this.acceptSuggestion(null, annotations);
}),
});
}
const canUndo = annotationPermissions.reduce((acc, next) => acc && next.permissions.canUndo, true);
if (canUndo) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/undo.svg'),
title: this._translateService.instant('annotation-actions.undo'),
onClick: () =>
this._ngZone.run(() => {
this.undoDirectAction(null, annotations);
}),
});
}
const canMarkAsFalsePositive = annotationPermissions.reduce((acc, next) => acc && next.permissions.canMarkAsFalsePositive, true);
if (canMarkAsFalsePositive) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/thumb-down.svg'),
title: this._translateService.instant('annotation-actions.remove-annotation.false-positive'),
onClick: () =>
this._ngZone.run(() => {
this.markAsFalsePositive(null, annotations);
}),
});
}
const canForceRedaction = annotationPermissions.reduce((acc, next) => acc && next.permissions.canForceRedaction, true);
if (canForceRedaction) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/thumb-up.svg'),
title: this._translateService.instant('annotation-actions.force-redaction.label'),
onClick: () =>
this._ngZone.run(() => {
this.forceAnnotation(null, annotations);
}),
});
}
const canForceHint = annotationPermissions.reduce((acc, next) => acc && next.permissions.canForceHint, true);
if (canForceHint) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/thumb-up.svg'),
title: this._translateService.instant('annotation-actions.force-hint.label'),
onClick: () =>
this._ngZone.run(() => {
this.forceAnnotation(null, annotations, true);
}),
});
}
const canRejectSuggestion = annotationPermissions.reduce((acc, next) => acc && next.permissions.canRejectSuggestion, true);
if (canRejectSuggestion) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/close.svg'),
title: this._translateService.instant('annotation-actions.reject-suggestion'),
onClick: () => this._ngZone.run(() => this.rejectSuggestion(null, annotations)),
});
}
const canRemoveOrSuggestToRemoveOnlyHere = annotationPermissions.reduce(
(acc, next) => acc && next.permissions.canRemoveOrSuggestToRemoveOnlyHere,
true,
);
if (canRemoveOrSuggestToRemoveOnlyHere) {
availableActions.push({
type: 'actionButton',
img: this._convertPath('/assets/icons/general/trash.svg'),
title: this._translateService.instant('annotation-actions.remove-annotation.only-here'),
onClick: () =>
this._ngZone.run(() => {
this.removeOrSuggestRemoveAnnotation(null, annotations, false);
}),
});
}
return availableActions;
}
async resize($event: MouseEvent, annotationWrapper: AnnotationWrapper) {
$event?.stopPropagation();
@ -415,10 +201,19 @@ export class AnnotationActionsService {
}
async acceptResize($event: MouseEvent, annotation: AnnotationWrapper): Promise<void> {
const fileId = this._state.fileId;
const textAndPositions = await this._extractTextAndPositions(annotation.id);
const textAndPositions = await this.#extractTextAndPositions(annotation.id);
if (annotation.isRecommendation) {
const recommendation = {
...annotation,
value: textAndPositions.text,
positions: textAndPositions.positions,
} as AnnotationWrapper;
return this.convertRecommendationToAnnotation($event, [recommendation]);
}
const text = annotation.rectangle ? annotation.value : annotation.isImage ? 'Image' : textAndPositions.text;
const data = { annotation, text };
this._dialogService.openDialog('resizeAnnotation', $event, data, (result: { comment: string; updateDictionary: boolean }) => {
const resizeRequest: IResizeRequest = {
annotationId: annotation.id,
@ -428,14 +223,9 @@ export class AnnotationActionsService {
updateDictionary: result.updateDictionary,
};
let obs;
if (annotation.isRecommendation) {
obs = this.#convertRecommendationToRedaction(resizeRequest, annotation, fileId);
} else {
obs = this._manualRedactionService.resizeOrSuggestResize([resizeRequest], this._dossier.id, fileId);
}
this._processObsAndEmit(obs);
const { fileId, dossierId } = this._state;
const request = this._manualRedactionService.resizeOrSuggestResize([resizeRequest], dossierId, fileId);
this.#processObsAndEmit(request);
});
}
@ -466,17 +256,7 @@ export class AnnotationActionsService {
}));
const { dossierId, fileId } = this._state;
this._processObsAndEmit(this._manualRedactionService.addAnnotation(requests, dossierId, fileId));
}
#convertRecommendationToRedaction(resizeRequest: IResizeRequest, annotation: AnnotationWrapper, fileId: string) {
const addRequest: IAddRedactionRequest = {
...resizeRequest,
comment: resizeRequest.comment ? { text: resizeRequest.comment } : null,
reason: 'Dictionary Request',
type: annotation.type,
};
return this._manualRedactionService.add([addRequest], this._dossier.id, fileId);
this.#processObsAndEmit(this._manualRedactionService.addAnnotation(requests, dossierId, fileId));
}
#generateRectangle(annotationWrapper: AnnotationWrapper) {
@ -504,7 +284,7 @@ export class AnnotationActionsService {
return annotation;
}
private _getHighlightOperationData(operation: TextHighlightOperation, highlights: AnnotationWrapper[]) {
#getHighlightOperationData(operation: TextHighlightOperation, highlights: AnnotationWrapper[]) {
return {
dossierId: this._state.dossierId,
fileId: this._state.fileId,
@ -516,7 +296,7 @@ export class AnnotationActionsService {
};
}
private _processObsAndEmit(obs: Observable<unknown>) {
#processObsAndEmit(obs: Observable<unknown>) {
obs.subscribe({
next: () => this._fileDataService.annotationsChanged(),
error: () => this._fileDataService.annotationsChanged(),
@ -546,11 +326,7 @@ export class AnnotationActionsService {
return annotation.value;
}
private _convertPath(path: string): string {
return this._baseHref + path;
}
private async _extractTextAndPositions(annotationId: string) {
async #extractTextAndPositions(annotationId: string) {
const viewerAnnotation = this._annotationManager.get(annotationId);
const document = await this._documentViewer.PDFDoc;

View File

@ -68,7 +68,7 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
addToDictionary: true,
sourceId: annotation.annotationId,
value: annotation.value,
reason: annotation.legalBasis,
reason: annotation.legalBasis ?? 'Dictionary Request',
positions: annotation.positions,
type: annotation.recommendationType,
comment,

View File

@ -0,0 +1,168 @@
import { inject, Injectable, NgZone } from '@angular/core';
import { AnnotationWrapper } from '../../../models/file/annotation.wrapper';
import { AnnotationPermissions } from '../../../models/file/annotation.permissions';
import { PermissionsService } from '../../../services/permissions.service';
import { UserService } from '../../../services/user.service';
import { DictionariesMapService } from '../../../services/entity-services/dictionaries-map.service';
import { FilePreviewStateService } from './file-preview-state.service';
import { TranslateService } from '@ngx-translate/core';
import { AnnotationActionsService } from './annotation-actions.service';
import { BASE_HREF_FN } from '../../../tokens';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { IHeaderElement } from '@red/domain';
@Injectable()
export class PdfAnnotationActionsService {
readonly #permissionsService = inject(PermissionsService);
readonly #currentUser = inject(UserService).currentUser;
readonly #dictionariesMapService = inject(DictionariesMapService);
readonly #state = inject(FilePreviewStateService);
readonly #translateService = inject(TranslateService);
readonly #ngZone = inject(NgZone);
readonly #convertPath = inject(BASE_HREF_FN);
readonly #annotationActionsService = inject(AnnotationActionsService);
get(annotations: AnnotationWrapper[]): IHeaderElement[] {
const availableActions: IHeaderElement[] = [];
const permissions = this.#getAnnotationsPermissions(annotations);
// you can only resize one annotation at a time
if (permissions.canResize) {
const firstAnnotation = annotations[0];
// if we already entered resize-mode previously
if (firstAnnotation.resizing) {
const acceptResizeButton = this.#getButton('check', _('annotation-actions.resize-accept.label'), () =>
this.#annotationActionsService.acceptResize(null, firstAnnotation),
);
const cancelResizeButton = this.#getButton('close', _('annotation-actions.resize-cancel.label'), () =>
this.#annotationActionsService.cancelResize(null, firstAnnotation),
);
return [acceptResizeButton, cancelResizeButton];
}
const resizeButton = this.#getButton('resize', _('annotation-actions.resize.label'), () =>
this.#annotationActionsService.resize(null, firstAnnotation),
);
availableActions.push(resizeButton);
}
if (permissions.canChangeLegalBasis) {
const editButton = this.#getButton('edit', _('annotation-actions.edit-reason.label'), () =>
this.#annotationActionsService.changeLegalBasis(null, annotations),
);
availableActions.push(editButton);
}
if (permissions.canRecategorizeImage) {
const recategorizeButton = this.#getButton('thumb-down', _('annotation-actions.recategorize-image'), () =>
this.#annotationActionsService.recategorizeImages(null, annotations),
);
availableActions.push(recategorizeButton);
}
if (permissions.canRemoveOrSuggestToRemoveFromDictionary) {
const removeFromDictButton = this.#getButton(
'remove-from-dict',
_('annotation-actions.remove-annotation.remove-from-dict'),
() => this.#annotationActionsService.removeOrSuggestRemoveAnnotation(null, annotations, true),
);
availableActions.push(removeFromDictButton);
}
if (permissions.canAcceptRecommendation) {
const acceptRecommendationButton = this.#getButton('check', _('annotation-actions.accept-recommendation.label'), () =>
this.#annotationActionsService.convertRecommendationToAnnotation(null, annotations),
);
availableActions.push(acceptRecommendationButton);
}
if (permissions.canAcceptSuggestion) {
const acceptSuggestionButton = this.#getButton('check', _('annotation-actions.accept-suggestion.label'), () =>
this.#annotationActionsService.acceptSuggestion(null, annotations),
);
availableActions.push(acceptSuggestionButton);
}
if (permissions.canUndo) {
const undoButton = this.#getButton('undo', _('annotation-actions.undo'), () =>
this.#annotationActionsService.undoDirectAction(null, annotations),
);
availableActions.push(undoButton);
}
if (permissions.canMarkAsFalsePositive) {
const markAsFalsePositiveButton = this.#getButton('thumb-down', _('annotation-actions.remove-annotation.false-positive'), () =>
this.#annotationActionsService.markAsFalsePositive(null, annotations),
);
availableActions.push(markAsFalsePositiveButton);
}
if (permissions.canForceRedaction) {
const forceRedactionButton = this.#getButton('thumb-up', _('annotation-actions.force-redaction.label'), () =>
this.#annotationActionsService.forceAnnotation(null, annotations),
);
availableActions.push(forceRedactionButton);
}
if (permissions.canForceHint) {
const forceHintButton = this.#getButton('thumb-up', _('annotation-actions.force-hint.label'), () =>
this.#annotationActionsService.forceAnnotation(null, annotations, true),
);
availableActions.push(forceHintButton);
}
if (permissions.canRejectSuggestion) {
const rejectSuggestionButton = this.#getButton('close', _('annotation-actions.reject-suggestion'), () =>
this.#annotationActionsService.rejectSuggestion(null, annotations),
);
availableActions.push(rejectSuggestionButton);
}
if (permissions.canRemoveOrSuggestToRemoveOnlyHere) {
const removeOrSuggestToRemoveOnlyHereButton = this.#getButton(
'trash',
_('annotation-actions.remove-annotation.only-here'),
() => this.#annotationActionsService.removeOrSuggestRemoveAnnotation(null, annotations, false),
);
availableActions.push(removeOrSuggestToRemoveOnlyHereButton);
}
return availableActions;
}
#getButton(icon: string, title: string, action: () => void | Promise<void>): IHeaderElement {
return {
type: 'actionButton',
img: this.#convertPath(`/assets/icons/general/${icon}.svg`),
title: this.#translateService.instant(title),
onClick: () => this.#ngZone.run(async () => action()),
};
}
#getAnnotationsPermissions(annotations: AnnotationWrapper[]) {
const dossier = this.#state.dossier;
const isApprover = this.#permissionsService.isApprover(dossier);
const dictionaries = this.#dictionariesMapService.get(dossier.dossierTemplateId);
const permissions = annotations.map(a => AnnotationPermissions.forUser(isApprover, this.#currentUser, a, dictionaries));
return {
canResize: permissions.length === 1 && permissions[0].canResizeAnnotation,
canChangeLegalBasis: permissions.reduce((acc, next) => acc && next.canChangeLegalBasis, true),
canRecategorizeImage: permissions.reduce((acc, next) => acc && next.canRecategorizeImage, true),
canRemoveOrSuggestToRemoveFromDictionary: permissions.reduce(
(acc, next) => acc && next.canRemoveOrSuggestToRemoveFromDictionary,
true,
),
canAcceptRecommendation: permissions.reduce((acc, next) => acc && next.canAcceptRecommendation, true),
canAcceptSuggestion: permissions.reduce((acc, next) => acc && next.canAcceptSuggestion, true),
canUndo: permissions.reduce((acc, next) => acc && next.canUndo, true),
canMarkAsFalsePositive: permissions.reduce((acc, next) => acc && next.canMarkAsFalsePositive, true),
canForceRedaction: permissions.reduce((acc, next) => acc && next.canForceRedaction, true),
canForceHint: permissions.reduce((acc, next) => acc && next.canForceHint, true),
canRejectSuggestion: permissions.reduce((acc, next) => acc && next.canRejectSuggestion, true),
canRemoveOrSuggestToRemoveOnlyHere: permissions.reduce((acc, next) => acc && next.canRemoveOrSuggestToRemoveOnlyHere, true),
};
}
}

View File

@ -8,7 +8,6 @@ import {
ManualRedactionEntryWrapper,
} from '../../../models/file/manual-redaction-entry.wrapper';
import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service';
import { AnnotationActionsService } from './annotation-actions.service';
import { UserPreferenceService } from '../../../services/user-preference.service';
import { BASE_HREF_FN, BaseHrefFn } from '../../../tokens';
import { shareDistinctLast } from '@iqser/common-ui';
@ -28,6 +27,7 @@ import { combineLatest, Observable, Subject } from 'rxjs';
import { ViewModeService } from './view-mode.service';
import { PermissionsService } from '../../../services/permissions.service';
import { AnnotationsListingService } from './annotations-listing.service';
import { PdfAnnotationActionsService } from './pdf-annotation-actions.service';
import Annotation = Core.Annotations.Annotation;
import Quad = Core.Math.Quad;
@ -57,7 +57,7 @@ export class PdfProxyService {
private readonly _ngZone: NgZone,
private readonly _userPreferenceService: UserPreferenceService,
private readonly _annotationDrawService: AnnotationDrawService,
private readonly _annotationActionsService: AnnotationActionsService,
private readonly _pdfAnnotationActionsService: PdfAnnotationActionsService,
private readonly _fileDataService: FileDataService,
private readonly _viewerHeaderService: ViewerHeaderService,
private readonly _viewModeService: ViewModeService,
@ -191,7 +191,7 @@ export class PdfProxyService {
]);
}
const actions = this._annotationActionsService.getViewerAvailableActions(annotationWrappers);
const actions = this._pdfAnnotationActionsService.get(annotationWrappers);
this.instance.UI.annotationPopup.add(actions);
}