fixed annotation flows

This commit is contained in:
Timo Bejan 2020-10-30 12:41:35 +02:00
parent 8994c9b5de
commit 28a2ecb2ce
8 changed files with 118 additions and 45 deletions

View File

@ -8,6 +8,7 @@ import { TranslateService } from '@ngx-translate/core';
import { UserService } from '../../user/user.service';
import { ManualRedactionEntryWrapper } from '../../screens/file/model/manual-redaction-entry.wrapper';
import { ManualAnnotationService } from '../../screens/file/service/manual-annotation.service';
import { ManualAnnotationResponse } from '../../screens/file/model/manual-annotation-response';
@Component({
selector: 'redaction-manual-annotation-dialog',
@ -63,7 +64,9 @@ export class ManualAnnotationDialogComponent implements OnInit {
.makeDictionaryEntry(this.manualRedactionEntryWrapper.manualRedactionEntry)
.subscribe(
(response) => {
this.dialogRef.close(this.manualRedactionEntryWrapper);
this.dialogRef.close(
new ManualAnnotationResponse(this.manualRedactionEntryWrapper, response)
);
},
() => {
this.dialogRef.close();
@ -74,7 +77,9 @@ export class ManualAnnotationDialogComponent implements OnInit {
.makeRedaction(this.manualRedactionEntryWrapper.manualRedactionEntry)
.subscribe(
(response) => {
this.dialogRef.close(this.manualRedactionEntryWrapper);
this.dialogRef.close(
new ManualAnnotationResponse(this.manualRedactionEntryWrapper, response)
);
},
() => {
this.dialogRef.close();

View File

@ -268,6 +268,7 @@
<button
mat-icon-button
(click)="acceptSuggestion($event, annotation)"
*ngIf="appStateService.isActiveProjectOwnerAndManager"
>
<mat-icon svgIcon="red:check-alt"></mat-icon>
</button>

View File

@ -27,6 +27,7 @@ import { ManualRedactionEntryWrapper } from '../model/manual-redaction-entry.wra
import { hexToRgb } from '../../../utils/functions';
import { AnnotationWrapper } from '../model/annotation.wrapper';
import { ManualAnnotationService } from '../service/manual-annotation.service';
import { ManualAnnotationResponse } from '../model/manual-annotation-response';
@Component({
selector: 'redaction-file-preview-screen',
@ -195,9 +196,9 @@ export class FilePreviewScreenComponent implements OnInit {
this.ngZone.run(() => {
this._dialogRef = this._dialogService.openManualRedactionDialog(
$event,
(response: ManualRedactionEntryWrapper) => {
(response: ManualAnnotationResponse) => {
const manualRedactionEntry: ManualRedactionEntry =
response.manualRedactionEntry;
response.manualRedactionEntryWrapper.manualRedactionEntry;
const annotManager = this.activeViewer.annotManager;
const originalQuads = $event.quads;
@ -208,7 +209,7 @@ export class FilePreviewScreenComponent implements OnInit {
highlight.StrokeColor = this._getColor(manualRedactionEntry);
highlight.setContents(manualRedactionEntry.reason);
highlight.Quads = originalQuads[key];
highlight.Id = this._computeId(response.type, manualRedactionEntry);
highlight.Id = this._computeId(response);
annotManager.addAnnotation(highlight, true);
annotManager.redrawAnnotation(highlight);
}
@ -470,20 +471,20 @@ export class FilePreviewScreenComponent implements OnInit {
this._changeDetectorRef.detectChanges();
}
private _computeId(type: 'DICTIONARY' | 'REDACTION', request: ManualRedactionEntry) {
private _computeId(response: ManualAnnotationResponse) {
// if owner or not set the request prefix in the id
const prefix = this.appStateService.isActiveProjectOwner ? '' : 'request:add:';
if (prefix.length > 0) {
return prefix + request.type + ':' + new Date().getTime();
return prefix + response.dictionary + ':' + response.annotationId;
} else {
const dictionaryType: 'hint' | 'redaction' =
type === 'REDACTION'
response.manualRedactionEntryWrapper.type === 'REDACTION'
? 'redaction'
: this.appStateService.getDictionaryTypeValue(request.type).hint
: this.appStateService.getDictionaryTypeValue(response.dictionary).hint
? 'hint'
: 'redaction';
return dictionaryType + ':' + request.type + ':' + new Date().getTime();
return dictionaryType + ':' + response.dictionary + ':' + response.annotationId;
}
}

View File

@ -1,4 +1,5 @@
import { Annotations } from '@pdftron/webviewer';
import { ManualRedactionEntry } from '@redaction/red-ui-http';
export class AnnotationWrapper {
superType: 'request' | 'redaction' | 'hint' | 'ignore';
@ -6,8 +7,12 @@ export class AnnotationWrapper {
color: string;
comments: string[] = [];
uuid: string;
manualRedactionEntry: ManualRedactionEntry;
constructor(public annotation: Annotations.Annotation) {
constructor(
public annotation: Annotations.Annotation,
manualRedactionEntries?: ManualRedactionEntry[]
) {
this.comments = annotation['Mi'] ? annotation['Mi'].map((m) => m.eC) : [];
const parts = annotation.Id.split(':');
// first part is always the superType
@ -19,6 +24,13 @@ export class AnnotationWrapper {
this.dictionary = parts[2] !== 'only_here' ? parts[2] : undefined;
}
this.uuid = parts[parts.length - 1];
this.manualRedactionEntry = manualRedactionEntries
? manualRedactionEntries.find((e) => e.id === this.uuid)
: undefined;
}
get manualRedactionOwner() {
return this.manualRedactionEntry?.user;
}
get x() {

View File

@ -0,0 +1,23 @@
import { ManualRedactionEntryWrapper } from './manual-redaction-entry.wrapper';
import { ManualAddResponse } from '@redaction/red-ui-http';
export class ManualAnnotationResponse {
annotationId;
commentId;
constructor(
public manualRedactionEntryWrapper: ManualRedactionEntryWrapper,
public manualAddResponse: ManualAddResponse
) {
this.annotationId = manualAddResponse?.annotationId
? manualAddResponse.annotationId
: new Date().getTime();
this.commentId = manualAddResponse?.commentId
? manualAddResponse.commentId
: new Date().getTime();
}
get dictionary() {
return this.manualRedactionEntryWrapper.manualRedactionEntry.type;
}
}

View File

@ -81,7 +81,8 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
this._annotationEventDebouncer.pipe(throttleTime(300)).subscribe((value) => {
this.annotationsAdded.emit(
AnnotationUtils.filterAndConvertAnnotations(
this.instance.annotManager.getAnnotationsList()
this.instance.annotManager.getAnnotationsList(),
this._manualAnnotationService.manualEntries
)
);
// nasty double-emit fix, the annotationList is not updated when the event is fired
@ -89,15 +90,14 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
() =>
this.annotationsAdded.emit(
AnnotationUtils.filterAndConvertAnnotations(
this.instance.annotManager.getAnnotationsList()
this.instance.annotManager.getAnnotationsList(),
this._manualAnnotationService.manualEntries
)
),
200
);
});
this._manualAnnotationService.getManualAnnotations().subscribe((manualAnnotation) => {
this._manualAnnotations = manualAnnotation;
});
this._manualAnnotationService.loadManualAnnotationsForActiveFile().subscribe(() => {});
}
ngOnChanges(changes: SimpleChanges): void {

View File

@ -3,19 +3,28 @@ import { AppStateService } from '../../../state/app-state.service';
import {
DictionaryControllerService,
ManualRedactionControllerService,
ManualRedactionEntry
ManualRedactionEntry,
ManualRedactions
} from '@redaction/red-ui-http';
import { AnnotationWrapper } from '../model/annotation.wrapper';
import { NotificationService, NotificationType } from '../../../notification/notification.service';
import { TranslateService } from '@ngx-translate/core';
import { tap } from 'rxjs/operators';
import { map, mergeMap, tap } from 'rxjs/operators';
import { UserService } from '../../../user/user.service';
@Injectable({
providedIn: 'root'
})
export class ManualAnnotationService {
private _manualAnnotationsResponse: ManualRedactions;
get manualEntries(): ManualRedactionEntry[] {
return this._manualAnnotationsResponse ? this._manualAnnotationsResponse.entriesToAdd : [];
}
constructor(
private readonly _appStateService: AppStateService,
private readonly _userService: UserService,
private readonly _translateService: TranslateService,
private readonly _notificationService: NotificationService,
private readonly _manualRedactionControllerService: ManualRedactionControllerService,
@ -49,20 +58,7 @@ export class ManualAnnotationService {
.pipe(
tap(
() => {
// if approved - and not only here, make a dictionary entry
if (annotationWrapper.id.indexOf(':only_here:') < 0) {
this.getManualAnnotations().subscribe((annotations) => {
annotations.entriesToAdd.forEach((a) => {
// found the annotation
if (annotationWrapper.id.indexOf(a.id) >= 0) {
console.log(a);
this._makeDictionaryEntry(a).subscribe(() => {});
}
});
});
} else {
this._notify('manual-annotation.reject-request.success');
}
this._notify('manual-annotation.reject-request.success');
},
() => {
this._notify('manual-annotation.reject-request.error');
@ -72,12 +68,22 @@ export class ManualAnnotationService {
}
public rejectSuggestion(annotationWrapper: AnnotationWrapper) {
return this._manualRedactionControllerService
.undo(
this._appStateService.activeProjectId,
this._appStateService.activeFile.fileId,
annotationWrapper.uuid
)
console.log(annotationWrapper);
// if you're the owner, you undo, otherwise you reject
const observable =
annotationWrapper.manualRedactionOwner === this._userService.userId
? this._manualRedactionControllerService.undo(
this._appStateService.activeProjectId,
this._appStateService.activeFile.fileId,
annotationWrapper.uuid
)
: this._manualRedactionControllerService.declineRequest(
this._appStateService.activeProjectId,
this._appStateService.activeFile.fileId,
annotationWrapper.uuid
);
return observable
.pipe(
tap(
() => {
@ -87,6 +93,11 @@ export class ManualAnnotationService {
this._notify('manual-annotation.reject-request.error');
}
)
)
.pipe(
mergeMap((result) => {
return this.loadManualAnnotationsForActiveFile().pipe(map(() => result));
})
);
}
@ -129,6 +140,11 @@ export class ManualAnnotationService {
);
}
)
)
.pipe(
mergeMap((result) => {
return this.loadManualAnnotationsForActiveFile().pipe(map(() => result));
})
);
}
@ -149,6 +165,11 @@ export class ManualAnnotationService {
);
}
)
)
.pipe(
mergeMap((result) => {
return this.loadManualAnnotationsForActiveFile().pipe(map(() => result));
})
);
}
@ -176,10 +197,16 @@ export class ManualAnnotationService {
}
}
getManualAnnotations() {
return this._manualRedactionControllerService.getManualRedaction(
this._appStateService.activeProject.project.projectId,
this._appStateService.activeFile.fileId
);
loadManualAnnotationsForActiveFile() {
return this._manualRedactionControllerService
.getManualRedaction(
this._appStateService.activeProject.project.projectId,
this._appStateService.activeFile.fileId
)
.pipe(
tap((response) => {
this._manualAnnotationsResponse = response;
})
);
}
}

View File

@ -1,6 +1,7 @@
import { Annotations } from '@pdftron/webviewer';
import { AnnotationFilters } from './types';
import { AnnotationWrapper } from '../screens/file/model/annotation.wrapper';
import { ManualRedactionEntry } from '@redaction/red-ui-http';
export class AnnotationUtils {
public static sortAnnotations(annotations: AnnotationWrapper[]): AnnotationWrapper[] {
@ -88,11 +89,14 @@ export class AnnotationUtils {
return obj;
}
public static filterAndConvertAnnotations(annotations: Annotations.Annotation[]) {
public static filterAndConvertAnnotations(
annotations: Annotations.Annotation[],
manualRedactions: ManualRedactionEntry[]
) {
const convertedAnnotations: AnnotationWrapper[] = [];
for (const annotation of annotations) {
if (annotation.Id.indexOf(':') > 0) {
convertedAnnotations.push(new AnnotationWrapper(annotation));
convertedAnnotations.push(new AnnotationWrapper(annotation, manualRedactions));
}
}
return convertedAnnotations;