Accept suggestion menu
This commit is contained in:
parent
4fc0c92753
commit
a4bcded240
@ -99,7 +99,7 @@ export class DialogService {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public acceptSuggestion(
|
||||
public openAcceptSuggestionModal(
|
||||
$event: MouseEvent,
|
||||
annotation: AnnotationWrapper
|
||||
): MatDialogRef<ConfirmationDialogComponent> {
|
||||
@ -115,7 +115,7 @@ export class DialogService {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public rejectSuggestion(
|
||||
public openRejectSuggestionModal(
|
||||
$event: MouseEvent,
|
||||
annotation: AnnotationWrapper,
|
||||
rejectCallback: () => void
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<section [class.hidden]="!viewReady">
|
||||
<div class="page-header">
|
||||
<div class="flex-1">
|
||||
<mat-slide-toggle color="primary" labelPosition="after" [(ngModel)]="redactedView">
|
||||
<mat-slide-toggle [(ngModel)]="redactedView" color="primary" labelPosition="after">
|
||||
{{ 'file-preview.view-toggle.label' | translate }}
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
@ -13,9 +13,9 @@
|
||||
<div class="flex-1 actions-container">
|
||||
<div class="actions-row">
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="openDeleteFileDialog($event)"
|
||||
*ngIf="userService.isManager(user)"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
@ -23,49 +23,49 @@
|
||||
<mat-icon svgIcon="red:report"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="assignReviewer()"
|
||||
*ngIf="appStateService.isActiveProjectMember"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon svgIcon="red:assign"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="reanalyseFile($event)"
|
||||
*ngIf="userService.isManager(user)"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon svgIcon="red:refresh"></mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="openFileDetailsDialog($event)">
|
||||
<button (click)="openFileDetailsDialog($event)" mat-icon-button>
|
||||
<mat-icon svgIcon="red:info"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
*ngIf="userService.isManager(user)"
|
||||
[matMenuTriggerFor]="downloadMenu"
|
||||
class="arrow-button"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
class="arrow-button"
|
||||
[matMenuTriggerFor]="downloadMenu"
|
||||
>
|
||||
<span translate="file-preview.download.label"></span>
|
||||
<mat-icon svgIcon="red:arrow-down"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #downloadMenu="matMenu" xPosition="before">
|
||||
<div
|
||||
(click)="downloadFile('ORIGINAL')"
|
||||
mat-menu-item
|
||||
translate="file-preview.download.dropdown.original.label"
|
||||
(click)="downloadFile('ORIGINAL')"
|
||||
></div>
|
||||
<div
|
||||
(click)="downloadFile('ANNOTATED')"
|
||||
mat-menu-item
|
||||
translate="file-preview.download.dropdown.annotated.label"
|
||||
(click)="downloadFile('ANNOTATED')"
|
||||
></div>
|
||||
<div
|
||||
(click)="downloadFile('REDACTED')"
|
||||
mat-menu-item
|
||||
translate="file-preview.download.dropdown.redacted.label"
|
||||
(click)="downloadFile('REDACTED')"
|
||||
></div>
|
||||
</mat-menu>
|
||||
</div>
|
||||
@ -74,68 +74,68 @@
|
||||
<div class="flex red-content-inner">
|
||||
<div class="left-container">
|
||||
<redaction-pdf-viewer
|
||||
(annotationSelected)="handleAnnotationSelected($event)"
|
||||
(keyUp)="handleKeyEvent($event)"
|
||||
(manualAnnotationRequested)="openManualRedactionDialog($event)"
|
||||
(pageChanged)="viewerPageChanged($event)"
|
||||
(viewerReady)="viewerReady($event)"
|
||||
*ngIf="fileData"
|
||||
[fileData]="redactedView ? fileData.redactedFileData : fileData.annotatedFileData"
|
||||
[fileStatus]="appStateService.activeFile"
|
||||
(keyUp)="handleKeyEvent($event)"
|
||||
(pageChanged)="viewerPageChanged($event)"
|
||||
(manualAnnotationRequested)="openManualRedactionDialog($event)"
|
||||
(annotationSelected)="handleAnnotationSelected($event)"
|
||||
(viewerReady)="viewerReady($event)"
|
||||
></redaction-pdf-viewer>
|
||||
</div>
|
||||
|
||||
<div class="right-fixed-container">
|
||||
<div class="right-title heading" translate="file-preview.tabs.annotations.label">
|
||||
<redaction-filter
|
||||
(filtersChanged)="filtersChanged($event)"
|
||||
[filterTemplate]="annotationFilterTemplate"
|
||||
[filters]="filters"
|
||||
(filtersChanged)="filtersChanged($event)"
|
||||
></redaction-filter>
|
||||
</div>
|
||||
|
||||
<div class="right-content">
|
||||
<div
|
||||
class="pages"
|
||||
[class.activePanel]="pagesPanelActive"
|
||||
tabindex="0"
|
||||
(keyup)="preventArrowDefault($event)"
|
||||
(keydown)="preventArrowDefault($event)"
|
||||
#quickNavigation
|
||||
(keydown)="preventArrowDefault($event)"
|
||||
(keyup)="preventArrowDefault($event)"
|
||||
[class.activePanel]="pagesPanelActive"
|
||||
class="pages"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="page-number pointer"
|
||||
[ngClass]="{ active: pageNumber === activeViewerPage }"
|
||||
(click)="selectPage(pageNumber)"
|
||||
*ngFor="let pageNumber of displayedPages"
|
||||
[id]="'quick-nav-page-' + pageNumber"
|
||||
(click)="selectPage(pageNumber)"
|
||||
[ngClass]="{ active: pageNumber === activeViewerPage }"
|
||||
class="page-number pointer"
|
||||
>
|
||||
{{ pageNumber }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="annotations"
|
||||
[class.activePanel]="!pagesPanelActive"
|
||||
#annotationsElement
|
||||
tabindex="1"
|
||||
(keyup)="preventArrowDefault($event)"
|
||||
(keydown)="preventArrowDefault($event)"
|
||||
(keyup)="preventArrowDefault($event)"
|
||||
[class.activePanel]="!pagesPanelActive"
|
||||
class="annotations"
|
||||
tabindex="1"
|
||||
>
|
||||
<div *ngFor="let page of displayedPages">
|
||||
<div class="page-separator" attr.anotation-page-header="{{ page }}">
|
||||
<div attr.anotation-page-header="{{ page }}" class="page-separator">
|
||||
<span class="all-caps-label"
|
||||
><span translate="page"></span> {{ page }}</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<div
|
||||
(click)="selectAnnotation(annotation)"
|
||||
*ngFor="let annotation of displayedAnnotations[page].annotations"
|
||||
class="annotation"
|
||||
[ngClass]="{ active: selectedAnnotation?.id === annotation.id }"
|
||||
attr.annotation-id="{{ annotation.id }}"
|
||||
attr.annotation-page="{{ page }}"
|
||||
[ngClass]="{ active: selectedAnnotation?.id === annotation.id }"
|
||||
(click)="selectAnnotation(annotation)"
|
||||
class="annotation"
|
||||
>
|
||||
<div class="details">
|
||||
<redaction-annotation-icon
|
||||
@ -169,19 +169,53 @@
|
||||
></redaction-comments>
|
||||
|
||||
<div
|
||||
class="annotation-actions"
|
||||
*ngIf="annotation.superType === 'request'"
|
||||
[class.visible]="isSuggestionVisible(annotation)"
|
||||
class="annotation-actions"
|
||||
>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="acceptSuggestion($event, annotation)"
|
||||
(click)="openAcceptSuggestionMenu($event, annotation)"
|
||||
*ngIf="appStateService.isActiveProjectOwnerAndManager"
|
||||
[class.active]="isSuggestionVisible(annotation)"
|
||||
[matMenuTriggerFor]="menu"
|
||||
class="confirm"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon svgIcon="red:check-alt"></mat-icon>
|
||||
</button>
|
||||
<mat-menu
|
||||
#menu="matMenu"
|
||||
(closed)="onSuggestionMenuClose()"
|
||||
xPosition="before"
|
||||
>
|
||||
<div
|
||||
(click)="acceptSuggestion($event, annotation)"
|
||||
mat-menu-item
|
||||
>
|
||||
<!-- TODO -->
|
||||
<redaction-annotation-icon
|
||||
[typeValue]="{ hexColor: '#5CE594', type: 'S' }"
|
||||
></redaction-annotation-icon>
|
||||
<div
|
||||
translate="file-preview.tabs.annotations.accept-suggestion.add-to-dict.label"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
(click)="acceptSuggestion($event, annotation)"
|
||||
mat-menu-item
|
||||
>
|
||||
<!-- TODO -->
|
||||
<redaction-annotation-icon
|
||||
[typeValue]="{ hexColor: '#5B97DB', type: 'S' }"
|
||||
></redaction-annotation-icon>
|
||||
<div
|
||||
translate="file-preview.tabs.annotations.accept-suggestion.only-here.label"
|
||||
></div>
|
||||
</div>
|
||||
</mat-menu>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="rejectSuggestion($event, annotation)"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
|
||||
@ -104,22 +104,7 @@ redaction-pdf-viewer {
|
||||
background-color: #f9fafb;
|
||||
|
||||
.annotation-actions {
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
transparent 0%,
|
||||
#f9fafb,
|
||||
#f9fafb,
|
||||
#f9fafb
|
||||
);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 120px;
|
||||
padding-right: 16px;
|
||||
|
||||
.confirm {
|
||||
color: $green-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +118,25 @@ redaction-pdf-viewer {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
width: 40px;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 120px;
|
||||
padding-right: 16px;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
transparent 0%,
|
||||
#f9fafb,
|
||||
#f9fafb,
|
||||
#f9fafb
|
||||
);
|
||||
|
||||
.confirm.active {
|
||||
background-color: $grey-2;
|
||||
}
|
||||
|
||||
&.visible {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ import { FileActionService } from '../service/file-action.service';
|
||||
import { AnnotationDrawService } from '../service/annotation-draw.service';
|
||||
import { AnnotationProcessingService } from '../service/annotation-processing.service';
|
||||
import { FilterModel } from '../../../common/filter/model/filter.model';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
|
||||
const KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||
|
||||
@ -38,24 +39,6 @@ const KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||
styleUrls: ['./file-preview-screen.component.scss']
|
||||
})
|
||||
export class FilePreviewScreenComponent implements OnInit {
|
||||
private projectId: string;
|
||||
private _activeViewer: 'ANNOTATED' | 'REDACTED' = 'ANNOTATED';
|
||||
private instance: WebViewerInstance;
|
||||
private _dialogRef: MatDialogRef<any>;
|
||||
|
||||
@ViewChild(PdfViewerComponent) private _viewerComponent: PdfViewerComponent;
|
||||
@ViewChild('annotationsElement') private _annotationsElement: ElementRef;
|
||||
@ViewChild('quickNavigation') private _quickNavigationElement: ElementRef;
|
||||
|
||||
public fileData: FileDataModel;
|
||||
public fileId: string;
|
||||
public annotations: AnnotationWrapper[] = [];
|
||||
public displayedAnnotations: { [key: number]: { annotations: AnnotationWrapper[] } } = {};
|
||||
public selectedAnnotation: AnnotationWrapper;
|
||||
public pagesPanelActive = true;
|
||||
public viewReady = false;
|
||||
filters: FilterModel[];
|
||||
|
||||
constructor(
|
||||
public readonly appStateService: AppStateService,
|
||||
public readonly userService: UserService,
|
||||
@ -90,6 +73,38 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
this._activeViewer = value ? 'REDACTED' : 'ANNOTATED';
|
||||
}
|
||||
|
||||
public get activeViewer() {
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
public get displayedPages(): number[] {
|
||||
return Object.keys(this.displayedAnnotations).map((key) => Number(key));
|
||||
}
|
||||
|
||||
get activeViewerPage() {
|
||||
return this.instance?.docViewer?.getCurrentPage();
|
||||
}
|
||||
private projectId: string;
|
||||
private _activeViewer: 'ANNOTATED' | 'REDACTED' = 'ANNOTATED';
|
||||
private instance: WebViewerInstance;
|
||||
private _dialogRef: MatDialogRef<any>;
|
||||
|
||||
@ViewChild(PdfViewerComponent) private _viewerComponent: PdfViewerComponent;
|
||||
@ViewChild('annotationsElement') private _annotationsElement: ElementRef;
|
||||
@ViewChild('quickNavigation') private _quickNavigationElement: ElementRef;
|
||||
@ViewChild('menu') private _matMenuTrigger: MatMenuTrigger;
|
||||
|
||||
public fileData: FileDataModel;
|
||||
public fileId: string;
|
||||
public annotations: AnnotationWrapper[] = [];
|
||||
public displayedAnnotations: { [key: number]: { annotations: AnnotationWrapper[] } } = {};
|
||||
public selectedAnnotation: AnnotationWrapper;
|
||||
public pagesPanelActive = true;
|
||||
public viewReady = false;
|
||||
public filters: FilterModel[];
|
||||
|
||||
private _activeSuggestion: AnnotationWrapper;
|
||||
|
||||
public ngOnInit(): void {
|
||||
this._loadFileData();
|
||||
this.appStateService.fileStatusChanged.subscribe((fileStatus) => {
|
||||
@ -152,14 +167,6 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
this._fileActionService.assignProjectReviewer();
|
||||
}
|
||||
|
||||
public get activeViewer() {
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
public get displayedPages(): number[] {
|
||||
return Object.keys(this.displayedAnnotations).map((key) => Number(key));
|
||||
}
|
||||
|
||||
public handleAnnotationSelected(annotationId: string) {
|
||||
this.selectedAnnotation = this.annotations.find((a) => a.id === annotationId);
|
||||
this.scrollToSelectedAnnotation();
|
||||
@ -197,10 +204,6 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
get activeViewerPage() {
|
||||
return this.instance?.docViewer?.getCurrentPage();
|
||||
}
|
||||
|
||||
@debounce()
|
||||
private _scrollViews() {
|
||||
this._scrollQuickNavigation();
|
||||
@ -242,18 +245,36 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
public isSuggestionVisible(annotation: AnnotationWrapper) {
|
||||
return annotation.id === this._activeSuggestion?.id;
|
||||
}
|
||||
|
||||
public acceptSuggestion($event: MouseEvent, annotation: AnnotationWrapper) {
|
||||
this.ngZone.run(() => {
|
||||
this._dialogRef = this._dialogService.acceptSuggestion($event, annotation);
|
||||
this._dialogRef = this._dialogService.openAcceptSuggestionModal($event, annotation);
|
||||
});
|
||||
}
|
||||
|
||||
public openAcceptSuggestionMenu($event: MouseEvent, annotation: AnnotationWrapper) {
|
||||
$event.preventDefault();
|
||||
this._activeSuggestion = annotation;
|
||||
this._matMenuTrigger.openMenu();
|
||||
}
|
||||
|
||||
public onSuggestionMenuClose() {
|
||||
this._activeSuggestion = null;
|
||||
}
|
||||
|
||||
public rejectSuggestion($event: MouseEvent, annotation: AnnotationWrapper) {
|
||||
this.ngZone.run(() => {
|
||||
this._dialogRef = this._dialogService.rejectSuggestion($event, annotation, () => {
|
||||
// TODO DELETE ANNOTATIOn
|
||||
//this.activeViewer.annotManager.deleteAnnotation(annotation, false, true);
|
||||
});
|
||||
this._dialogRef = this._dialogService.openRejectSuggestionModal(
|
||||
$event,
|
||||
annotation,
|
||||
() => {
|
||||
// TODO DELETE ANNOTATIOn
|
||||
//this.activeViewer.annotManager.deleteAnnotation(annotation, false, true);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -478,7 +478,15 @@
|
||||
"label": "Quick Navigation"
|
||||
},
|
||||
"annotations": {
|
||||
"label": "Annotations"
|
||||
"label": "Annotations",
|
||||
"accept-suggestion": {
|
||||
"add-to-dict": {
|
||||
"label": "Approve and add to dictionary"
|
||||
},
|
||||
"only-here": {
|
||||
"label": "Approve only here"
|
||||
}
|
||||
}
|
||||
},
|
||||
"info": {
|
||||
"label": "Info",
|
||||
|
||||
@ -43,3 +43,10 @@
|
||||
width: 9px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.mat-icon-button {
|
||||
transition: background-color 0.25s ease-in-out;
|
||||
&:hover {
|
||||
background-color: $grey-2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,10 @@
|
||||
font-size: 13px;
|
||||
color: $accent;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.arrow-wrapper {
|
||||
width: 16px;
|
||||
margin-right: 8px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user