RED-6144: some refactorings
This commit is contained in:
parent
f9db9885da
commit
fa0ae7e333
@ -1,7 +1,7 @@
|
||||
<div class="details">
|
||||
<redaction-annotation-icon
|
||||
[color]="annotation.color"
|
||||
[label]="annotation.isEarmark ? '' : (annotationTypesTranslations[annotation.superType] | translate)[0].toUpperCase()"
|
||||
[label]="annotation.isEarmark ? '' : ((annotationTypesTranslations[annotation.superType] | translate)[0] | uppercase)"
|
||||
[type]="annotation.iconShape"
|
||||
class="mt-6 mr-10"
|
||||
></redaction-annotation-icon>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { annotationTypesTranslations } from '@translations/annotation-types-translations';
|
||||
@ -8,7 +8,6 @@ import { ROLES } from '@users/roles';
|
||||
selector: 'redaction-annotation-card',
|
||||
templateUrl: './annotation-card.component.html',
|
||||
styleUrls: ['./annotation-card.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AnnotationCardComponent {
|
||||
readonly roles = ROLES;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, Input, OnChanges, OnDestroy } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, HostBinding, Input, OnChanges, OnDestroy } from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { BehaviorSubject, filter, Subscription } from 'rxjs';
|
||||
import { switchMap, tap } from 'rxjs/operators';
|
||||
@ -7,7 +7,6 @@ import { AnnotationsListingService } from '../../services/annotations-listing.se
|
||||
@Component({
|
||||
selector: 'redaction-annotation-reference [annotation]',
|
||||
templateUrl: './annotation-reference.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AnnotationReferenceComponent implements OnChanges, OnDestroy {
|
||||
@Input() annotation: AnnotationWrapper;
|
||||
@ -16,16 +15,15 @@ export class AnnotationReferenceComponent implements OnChanges, OnDestroy {
|
||||
readonly #subscription: Subscription;
|
||||
|
||||
constructor(private readonly _listingService: AnnotationsListingService, private readonly _changeRef: ChangeDetectorRef) {
|
||||
this.#subscription = this.#annotationChanged$
|
||||
.pipe(
|
||||
filter(annotation => !!annotation),
|
||||
switchMap(annotation => this._listingService.isSelected$(annotation)),
|
||||
tap((isSelected: boolean) => {
|
||||
this.isSelected = isSelected;
|
||||
this._changeRef.markForCheck();
|
||||
}),
|
||||
)
|
||||
.subscribe();
|
||||
const annotationsChanged$ = this.#annotationChanged$.pipe(
|
||||
filter(annotation => !!annotation),
|
||||
switchMap(annotation => this._listingService.isSelected$(annotation)),
|
||||
tap((isSelected: boolean) => {
|
||||
this.isSelected = isSelected;
|
||||
this._changeRef.markForCheck();
|
||||
}),
|
||||
);
|
||||
this.#subscription = annotationsChanged$.subscribe();
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
|
||||
@ -2,10 +2,11 @@
|
||||
<div class="dialog references-dialog">
|
||||
<div class="references-header flex">
|
||||
<div class="small-label uppercase">
|
||||
{{ 'references' | translate: { count: references.length } }}
|
||||
{{ 'references' | translate : { count: references.length } }}
|
||||
</div>
|
||||
<iqser-circle-button (action)="annotationReferencesService.hide()" icon="iqser:close"></iqser-circle-button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="annotationReferencesService.annotation$ | async as annotation" class="annotations-container flex">
|
||||
<div [class.active]="isSelected$ | async" class="annotation-container">
|
||||
<div class="annotation-card-container flex">
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Output } from '@angular/core';
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationReferencesService } from '../../services/annotation-references.service';
|
||||
import { Observable, switchMap } from 'rxjs';
|
||||
@ -9,7 +9,6 @@ import { filter } from 'rxjs/operators';
|
||||
selector: 'redaction-annotation-references-list',
|
||||
templateUrl: './annotation-references-list.component.html',
|
||||
styleUrls: ['./annotation-references-list.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AnnotationReferencesListComponent {
|
||||
@Output() readonly referenceClicked = new EventEmitter<AnnotationWrapper>();
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotation-references-page-indicator',
|
||||
templateUrl: './annotation-references-page-indicator.component.html',
|
||||
styleUrls: ['./annotation-references-page-indicator.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AnnotationReferencesPageIndicatorComponent {
|
||||
@Input() number: number;
|
||||
|
||||
@ -20,10 +20,13 @@
|
||||
</div>
|
||||
|
||||
<div *ngIf="multiSelectService.inactive$ | async" class="actions">
|
||||
<ng-container
|
||||
[ngTemplateOutletContext]="{ annotation: annotation }"
|
||||
[ngTemplateOutlet]="annotationActionsTemplate"
|
||||
></ng-container>
|
||||
<redaction-annotation-actions
|
||||
[annotations]="[annotation]"
|
||||
[canPerformAnnotationActions]="pdfProxyService.canPerformAnnotationActions$ | async"
|
||||
[iqserHelpMode]="getActionsHelpModeKey(annotation)"
|
||||
[overlappingElements]="['USER_MENU', 'WORKLOAD_FILTER', 'DOCUMENT_INFO']"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
></redaction-annotation-actions>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,46 +1,50 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, Input, OnChanges, TemplateRef } from '@angular/core';
|
||||
import { Component, HostBinding, Input, OnChanges } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { switchMap, tap } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, switchMap, tap } from 'rxjs/operators';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { AnnotationsListingService } from '../../services/annotations-listing.service';
|
||||
import { PdfProxyService } from '../../services/pdf-proxy.service';
|
||||
import { ScrollableParentViews } from '@iqser/common-ui';
|
||||
import { ActionsHelpModeKeys } from '../../utils/constants';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotation-wrapper [annotation] [annotationActionsTemplate]',
|
||||
selector: 'redaction-annotation-wrapper [annotation]',
|
||||
templateUrl: './annotation-wrapper.component.html',
|
||||
styleUrls: ['./annotation-wrapper.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AnnotationWrapperComponent implements OnChanges {
|
||||
@Input() annotation!: AnnotationWrapper;
|
||||
@Input() annotationActionsTemplate: TemplateRef<unknown>;
|
||||
|
||||
readonly isSelected$!: Observable<boolean>;
|
||||
@HostBinding('attr.annotation-id') annotationId: string;
|
||||
@HostBinding('attr.annotation-page') annotationPage: number;
|
||||
@HostBinding('class.active') active: boolean;
|
||||
private readonly _annotationChanged$ = new BehaviorSubject<AnnotationWrapper>(undefined);
|
||||
@HostBinding('class.active') active = false;
|
||||
readonly scrollableParentView = ScrollableParentViews.ANNOTATIONS_LIST;
|
||||
readonly #annotationChanged$ = new BehaviorSubject<AnnotationWrapper>(undefined);
|
||||
|
||||
constructor(
|
||||
private readonly _changeRef: ChangeDetectorRef,
|
||||
readonly listingService: AnnotationsListingService,
|
||||
readonly multiSelectService: MultiSelectService,
|
||||
readonly pdfProxyService: PdfProxyService,
|
||||
) {
|
||||
this.isSelected$ = this._annotationChanged$.pipe(
|
||||
tap(annotation => {
|
||||
this.annotationId = annotation.id;
|
||||
this.annotationPage = annotation.pageNumber;
|
||||
this._changeRef.markForCheck();
|
||||
}),
|
||||
this.isSelected$ = this.#annotationChanged$.pipe(
|
||||
switchMap(entity => this.listingService.isSelected$(entity)),
|
||||
tap(isSelected => {
|
||||
this.active = isSelected;
|
||||
this._changeRef.markForCheck();
|
||||
}),
|
||||
distinctUntilChanged(),
|
||||
tap(isSelected => (this.active = isSelected)),
|
||||
);
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
this._annotationChanged$.next(this.annotation);
|
||||
ngOnChanges() {
|
||||
this.#annotationChanged$.next(this.annotation);
|
||||
this.annotationId = this.annotation.id;
|
||||
}
|
||||
|
||||
getActionsHelpModeKey(annotation: AnnotationWrapper): string {
|
||||
const type = annotation?.typeLabel?.split('.')[1];
|
||||
const typeValue = annotation?.typeValue;
|
||||
if (type === 'hint' && (typeValue === 'ocr' || typeValue === 'formula' || typeValue === 'image')) {
|
||||
return ActionsHelpModeKeys[`${type}-${typeValue}`];
|
||||
}
|
||||
return ActionsHelpModeKeys[type];
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,13 +3,10 @@
|
||||
<redaction-highlights-separator [annotation]="annotation" [highlightGroup]="highlightGroup"></redaction-highlights-separator>
|
||||
</div>
|
||||
|
||||
<redaction-annotation-wrapper
|
||||
(click)="annotationClicked(annotation, $event)"
|
||||
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||
[annotation]="annotation"
|
||||
></redaction-annotation-wrapper>
|
||||
<redaction-annotation-wrapper (click)="annotationClicked(annotation, $event)" [annotation]="annotation"></redaction-annotation-wrapper>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="annotationReferencesService.annotation$ | async">
|
||||
<redaction-annotation-references-list (referenceClicked)="referenceClicked($event)"></redaction-annotation-references-list>
|
||||
</ng-container>
|
||||
<redaction-annotation-references-list
|
||||
(referenceClicked)="referenceClicked($event)"
|
||||
*ngIf="annotationReferencesService.annotation$ | async"
|
||||
></redaction-annotation-references-list>
|
||||
|
||||
@ -1,14 +1,4 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
TemplateRef,
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, OnChanges, Output } from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { FilterService, HasScrollbarDirective, IqserEventTarget } from '@iqser/common-ui';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
@ -24,11 +14,9 @@ import { AnnotationsListingService } from '../../services/annotations-listing.se
|
||||
selector: 'redaction-annotations-list',
|
||||
templateUrl: './annotations-list.component.html',
|
||||
styleUrls: ['./annotations-list.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AnnotationsListComponent extends HasScrollbarDirective implements OnChanges {
|
||||
@Input() annotations: AnnotationWrapper[];
|
||||
@Input() annotationActionsTemplate: TemplateRef<unknown>;
|
||||
|
||||
@Output() readonly pagesPanelActive = new EventEmitter<boolean>();
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<ng-container *ngIf="componentContext$ | async as ctx">
|
||||
<div *ngFor="let comment of annotation.comments; trackBy: trackBy" class="comment">
|
||||
<div class="comment-details-wrapper">
|
||||
<div [matTooltipPosition]="'above'" [matTooltip]="comment.date | date: 'exactDate'" class="small-label">
|
||||
<div [matTooltipPosition]="'above'" [matTooltip]="comment.date | date : 'exactDate'" class="small-label">
|
||||
<strong> {{ comment.user | name }} </strong>
|
||||
{{ comment.date | date: 'sophisticatedDate' }}
|
||||
{{ comment.date | date : 'sophisticatedDate' }}
|
||||
</div>
|
||||
|
||||
<div class="comment-actions">
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, Input, OnInit, ViewChild } from '@angular/core';
|
||||
import { Dossier, File, IComment } from '@red/domain';
|
||||
import { ChangeDetectorRef, Component, HostBinding, Input, OnInit, ViewChild } from '@angular/core';
|
||||
import type { Dossier, File, IComment, User } from '@red/domain';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { InputWithActionComponent, LoadingService, trackByFactory, ContextComponent } from '@iqser/common-ui';
|
||||
import { firstValueFrom, Observable } from 'rxjs';
|
||||
import { ContextComponent, getCurrentUser, InputWithActionComponent, LoadingService, trackByFactory } from '@iqser/common-ui';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CommentingService } from '../../services/commenting.service';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
@ -20,20 +19,17 @@ interface CommentsContext {
|
||||
selector: 'redaction-comments',
|
||||
templateUrl: './comments.component.html',
|
||||
styleUrls: ['./comments.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CommentsComponent extends ContextComponent<CommentsContext> implements OnInit {
|
||||
@Input() annotation: AnnotationWrapper;
|
||||
readonly trackBy = trackByFactory();
|
||||
readonly file$: Observable<File>;
|
||||
readonly dossier$: Observable<Dossier>;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
hiddenComments$: Observable<boolean>;
|
||||
@HostBinding('class.hidden') _hidden = true;
|
||||
@ViewChild(InputWithActionComponent) private readonly _input: InputWithActionComponent;
|
||||
|
||||
constructor(
|
||||
readonly permissionsService: PermissionsService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _manualRedactionService: ManualRedactionService,
|
||||
private readonly _commentingService: CommentingService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
@ -41,8 +37,6 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
|
||||
private readonly _stateService: FilePreviewStateService,
|
||||
) {
|
||||
super();
|
||||
this.file$ = _stateService.file$;
|
||||
this.dossier$ = _stateService.dossier$;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@ -53,8 +47,8 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
|
||||
);
|
||||
|
||||
super._initContext({
|
||||
file: this.file$,
|
||||
dossier: this.dossier$,
|
||||
file: this._stateService.file$,
|
||||
dossier: this._stateService.dossier$,
|
||||
hiddenComments: this.hiddenComments$,
|
||||
});
|
||||
}
|
||||
@ -65,12 +59,12 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
|
||||
}
|
||||
this._loadingService.start();
|
||||
const { dossierId, fileId } = this._stateService;
|
||||
const commentId = await firstValueFrom(this._manualRedactionService.addComment(value, this.annotation.id, dossierId, fileId));
|
||||
const commentId = await this._manualRedactionService.addComment(value, this.annotation.id, dossierId, fileId);
|
||||
this.annotation.comments.push({
|
||||
text: value,
|
||||
id: commentId,
|
||||
annotationId: this.annotation.id,
|
||||
user: this._userService.currentUser.id,
|
||||
user: this.currentUser.id,
|
||||
});
|
||||
this._input.reset();
|
||||
this._changeRef.markForCheck();
|
||||
@ -86,7 +80,7 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
|
||||
$event.stopPropagation();
|
||||
this._loadingService.start();
|
||||
const { dossierId, fileId } = this._stateService;
|
||||
await firstValueFrom(this._manualRedactionService.deleteComment(comment.id, this.annotation.id, dossierId, fileId));
|
||||
await this._manualRedactionService.deleteComment(comment.id, this.annotation.id, dossierId, fileId);
|
||||
this.annotation.comments.splice(this.annotation.comments.indexOf(comment), 1);
|
||||
this._changeRef.markForCheck();
|
||||
this._loadingService.stop();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { DocumentInfoService } from '../../services/document-info.service';
|
||||
import { combineLatest, Observable, switchMap } from 'rxjs';
|
||||
@ -19,7 +19,6 @@ interface FileAttribute {
|
||||
selector: 'redaction-document-info',
|
||||
templateUrl: './document-info.component.html',
|
||||
styleUrls: ['./document-info.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DocumentInfoComponent {
|
||||
readonly fileAttributes$: Observable<FileAttribute[]>;
|
||||
|
||||
@ -203,7 +203,6 @@
|
||||
|
||||
<redaction-annotations-list
|
||||
(pagesPanelActive)="pagesPanelActive = $event"
|
||||
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||
[annotations]="(displayedAnnotations$ | async)?.get(activeViewerPage)"
|
||||
></redaction-annotations-list>
|
||||
</div>
|
||||
|
||||
@ -1,17 +1,7 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
Input,
|
||||
OnDestroy,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, ElementRef, HostListener, Input, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
||||
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
|
||||
import { MatDialogState } from '@angular/material/dialog';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
import {
|
||||
AutoUnsubscribe,
|
||||
@ -25,7 +15,7 @@ import {
|
||||
shareDistinctLast,
|
||||
shareLast,
|
||||
} from '@iqser/common-ui';
|
||||
import { combineLatest, firstValueFrom, Observable } from 'rxjs';
|
||||
import { combineLatest, delay, Observable } from 'rxjs';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { File } from '@red/domain';
|
||||
import { ExcludedPagesService } from '../../services/excluded-pages.service';
|
||||
@ -49,7 +39,6 @@ const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||
selector: 'redaction-file-workload [file]',
|
||||
templateUrl: './file-workload.component.html',
|
||||
styleUrls: ['./file-workload.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
@ -57,9 +46,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
|
||||
|
||||
displayedAnnotations = new Map<number, AnnotationWrapper[]>();
|
||||
@Input() activeViewerPage: number;
|
||||
@Input() dialogRef: MatDialogRef<unknown>;
|
||||
@Input() file!: File;
|
||||
@Input() annotationActionsTemplate: TemplateRef<unknown>;
|
||||
displayedPages: number[] = [];
|
||||
pagesPanelActive = true;
|
||||
readonly displayedAnnotations$: Observable<Map<number, AnnotationWrapper[]>>;
|
||||
@ -166,6 +153,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
|
||||
const secondary$ = this.filterService.getFilterModels$('secondaryFilters');
|
||||
|
||||
return combineLatest([this.fileDataService.all$, primary$, secondary$]).pipe(
|
||||
delay(0),
|
||||
map(([annotations, primary, secondary]) => this._filterAnnotations(annotations, primary, secondary)),
|
||||
);
|
||||
}
|
||||
@ -198,7 +186,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
|
||||
handleKeyEvent($event: KeyboardEvent): void {
|
||||
if (
|
||||
!ALL_HOTKEY_ARRAY.includes($event.key) ||
|
||||
this.dialogRef?.getState() === MatDialogState.OPEN ||
|
||||
this.state.dialogRef?.getState() === MatDialogState.OPEN ||
|
||||
($event.target as IqserEventTarget).localName === 'input'
|
||||
) {
|
||||
return;
|
||||
@ -273,8 +261,8 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
|
||||
this.pdf.navigateTo(1);
|
||||
}
|
||||
|
||||
scrollQuickNavLast(): Promise<void> {
|
||||
return firstValueFrom(this.state.file$).then(file => this.pdf.navigateTo(file.numberOfPages));
|
||||
scrollQuickNavLast() {
|
||||
this.pdf.navigateTo(this.state.file.numberOfPages);
|
||||
}
|
||||
|
||||
preventKeyDefault($event: KeyboardEvent): void {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { EarmarkGroup, EarmarkOperation } from '@red/domain';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
@ -12,7 +12,6 @@ import { ROLES } from '@users/roles';
|
||||
selector: 'redaction-highlights-separator [highlightGroup] [annotation]',
|
||||
templateUrl: './highlights-separator.component.html',
|
||||
styleUrls: ['./highlights-separator.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class HighlightsSeparatorComponent {
|
||||
@Input() highlightGroup: EarmarkGroup;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { List } from '@iqser/common-ui';
|
||||
import { PdfViewer } from '../../../pdf-viewer/services/pdf-viewer.service';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
@ -12,13 +12,11 @@ import { ViewedPage } from '@red/domain';
|
||||
selector: 'redaction-pages [pages] [activePage] [displayedAnnotations]',
|
||||
templateUrl: './pages.component.html',
|
||||
styleUrls: ['./pages.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class PagesComponent {
|
||||
@Input() pages: List<number>;
|
||||
@Input() activePage: number;
|
||||
@Input() displayedAnnotations: Map<number, AnnotationWrapper[]>;
|
||||
|
||||
readonly #pdf = inject(PdfViewer);
|
||||
readonly #state = inject(FilePreviewStateService);
|
||||
readonly viewedPages$ = inject(ViewedPagesMapService).get$(this.#state.fileId);
|
||||
|
||||
@ -8,21 +8,5 @@
|
||||
|
||||
<redaction-document-info *ngIf="documentInfoService.shown$ | async" id="document-info"></redaction-document-info>
|
||||
|
||||
<redaction-file-workload
|
||||
*ngIf="!file.excluded"
|
||||
[activeViewerPage]="pdf.currentPage$ | async"
|
||||
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||
[dialogRef]="state.dialogRef"
|
||||
[file]="file"
|
||||
></redaction-file-workload>
|
||||
|
||||
<ng-template #annotationActionsTemplate let-annotation="annotation">
|
||||
<redaction-annotation-actions
|
||||
[annotations]="[annotation]"
|
||||
[canPerformAnnotationActions]="pdfProxyService.canPerformAnnotationActions$ | async"
|
||||
[iqserHelpMode]="getActionsHelpModeKey(annotation)"
|
||||
[overlappingElements]="['USER_MENU', 'WORKLOAD_FILTER', 'DOCUMENT_INFO']"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
></redaction-annotation-actions>
|
||||
</ng-template>
|
||||
<redaction-file-workload *ngIf="!file.excluded" [activeViewerPage]="pdf.currentPage$ | async" [file]="file"></redaction-file-workload>
|
||||
</ng-container>
|
||||
|
||||
@ -1,38 +1,19 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
import { DocumentInfoService } from '../../services/document-info.service';
|
||||
import { ExcludedPagesService } from '../../services/excluded-pages.service';
|
||||
import { PdfViewer } from '../../../pdf-viewer/services/pdf-viewer.service';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { PdfProxyService } from '../../services/pdf-proxy.service';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { ActionsHelpModeKeys } from '../../utils/constants';
|
||||
import { ScrollableParentView, ScrollableParentViews } from '@iqser/common-ui';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-preview-right-container',
|
||||
templateUrl: './file-preview-right-container.component.html',
|
||||
styleUrls: ['./file-preview-right-container.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FilePreviewRightContainerComponent {
|
||||
constructor(
|
||||
readonly pdf: PdfViewer,
|
||||
readonly pdfProxyService: PdfProxyService,
|
||||
readonly state: FilePreviewStateService,
|
||||
readonly documentInfoService: DocumentInfoService,
|
||||
readonly excludedPagesService: ExcludedPagesService,
|
||||
) {}
|
||||
|
||||
get scrollableParentView(): ScrollableParentView {
|
||||
return ScrollableParentViews.ANNOTATIONS_LIST;
|
||||
}
|
||||
|
||||
getActionsHelpModeKey(annotation: AnnotationWrapper): string {
|
||||
const type = annotation?.typeLabel?.split('.')[1];
|
||||
const typeValue = annotation?.typeValue;
|
||||
if (type === 'hint' && (typeValue === 'ocr' || typeValue === 'formula' || typeValue === 'image')) {
|
||||
return ActionsHelpModeKeys[`${type}-${typeValue}`];
|
||||
}
|
||||
return ActionsHelpModeKeys[type];
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
</div>
|
||||
|
||||
<iqser-initials-avatar
|
||||
*ngIf="(editingReviewer$ | async) === false"
|
||||
*ngIf="!editingReviewer"
|
||||
[id]="'assignee'"
|
||||
[tooltipPosition]="'below'"
|
||||
[user]="file.assignee"
|
||||
@ -15,24 +15,24 @@
|
||||
></iqser-initials-avatar>
|
||||
|
||||
<div
|
||||
(click)="editingReviewer$.next(true)"
|
||||
*ngIf="(editingReviewer$ | async) === false && (canAssignReviewer$ | async)"
|
||||
(click)="editingReviewer = true"
|
||||
*ngIf="!editingReviewer && (canAssignReviewer$ | async)"
|
||||
[id]="'assign-reviewer'"
|
||||
[translate]="'file-preview.assign-reviewer'"
|
||||
class="assign-reviewer pointer"
|
||||
></div>
|
||||
|
||||
<redaction-assign-user-dropdown
|
||||
(cancel)="editingReviewer$.next(false)"
|
||||
(cancel)="editingReviewer = false"
|
||||
(save)="assignReviewer(file, $event)"
|
||||
*ngIf="editingReviewer$ | async"
|
||||
*ngIf="editingReviewer"
|
||||
[options]="usersOptions$ | async"
|
||||
[value]="file.assignee"
|
||||
></redaction-assign-user-dropdown>
|
||||
|
||||
<div *ngIf="(editingReviewer$ | async) === false && canAssign$ | async" class="assign-actions-wrapper">
|
||||
<div *ngIf="!editingReviewer && canAssign$ | async" class="assign-actions-wrapper">
|
||||
<iqser-circle-button
|
||||
(action)="editingReviewer$.next(true)"
|
||||
(action)="editingReviewer = true"
|
||||
*ngIf="(canAssignOrUnassign$ | async) && !!file.assignee"
|
||||
[buttonId]="'change-assignee'"
|
||||
[icon]="'iqser:edit'"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
import { Dossier, File, StatusBarConfigs, User } from '@red/domain';
|
||||
import { List, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
@ -7,7 +7,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { FilesService } from '@services/files/files.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BehaviorSubject, combineLatest, combineLatestWith, firstValueFrom, Observable, switchMap } from 'rxjs';
|
||||
import { combineLatest, combineLatestWith, firstValueFrom, Observable, switchMap } from 'rxjs';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||
@ -17,7 +17,6 @@ import { FileAssignService } from '../../../shared-dossiers/services/file-assign
|
||||
selector: 'redaction-user-management',
|
||||
templateUrl: './user-management.component.html',
|
||||
styleUrls: ['./user-management.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class UserManagementComponent {
|
||||
readonly translations = workflowFileStatusTranslations;
|
||||
@ -25,7 +24,7 @@ export class UserManagementComponent {
|
||||
readonly assignTooltip$: Observable<string>;
|
||||
readonly canAssignReviewer$: Observable<boolean>;
|
||||
readonly canAssignToSelf$: Observable<boolean>;
|
||||
readonly editingReviewer$ = new BehaviorSubject<boolean>(false);
|
||||
editingReviewer = false;
|
||||
readonly canAssignOrUnassign$: Observable<boolean>;
|
||||
readonly canAssign$: Observable<boolean>;
|
||||
readonly usersOptions$: Observable<List>;
|
||||
@ -113,6 +112,6 @@ export class UserManagementComponent {
|
||||
this.loadingService.stop();
|
||||
|
||||
this.toaster.success(_('assignment.reviewer'), { params: { reviewerName, filename } });
|
||||
this.editingReviewer$.next(false);
|
||||
this.editingReviewer = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
@ -78,7 +77,6 @@ const textActions = [TextPopups.ADD_DICTIONARY, TextPopups.ADD_FALSE_POSITIVE];
|
||||
templateUrl: './file-preview-screen.component.html',
|
||||
styleUrls: ['./file-preview-screen.component.scss'],
|
||||
providers: filePreviewScreenProviders,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FilePreviewScreenComponent
|
||||
extends AutoUnsubscribe
|
||||
@ -300,7 +298,7 @@ export class FilePreviewScreenComponent
|
||||
await firstValueFrom(reanalyzeFiles);
|
||||
}
|
||||
|
||||
this.pdfProxyService.loadViewer();
|
||||
this.pdfProxyService.configureElements();
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
|
||||
@ -5,7 +5,6 @@ import {
|
||||
IRedactionLog,
|
||||
IRedactionLogEntry,
|
||||
LogEntryStatuses,
|
||||
ManualRedactionType,
|
||||
ViewedPage,
|
||||
ViewMode,
|
||||
ViewModes,
|
||||
|
||||
@ -12,7 +12,7 @@ import type {
|
||||
} from '@red/domain';
|
||||
import { type AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { GenericService, IqserPermissionsService, List, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { dictionaryActionsTranslations, manualRedactionActionsTranslations } from '@translations/annotation-actions-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
@ -21,7 +21,7 @@ import { ActiveDossiersService } from '@services/dossiers/active-dossiers.servic
|
||||
import { type ManualRedactionEntryType } from '@models/file/manual-redaction-entry.wrapper';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { of } from 'rxjs';
|
||||
import { firstValueFrom, of } from 'rxjs';
|
||||
|
||||
function getResponseType(error: boolean, isConflict: boolean) {
|
||||
const isConflictError = isConflict ? 'conflictError' : 'error';
|
||||
@ -54,15 +54,16 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
addComment(@RequiredParam() comment: string, @RequiredParam() annotationId: string, dossierId: string, fileId: string) {
|
||||
async addComment(@RequiredParam() comment: string, @RequiredParam() annotationId: string, dossierId: string, fileId: string) {
|
||||
const url = `${this._defaultModelPath}/comment/add/${dossierId}/${fileId}/${annotationId}`;
|
||||
return this._post<{ commentId: string }>({ text: comment }, url).pipe(map(res => res.commentId));
|
||||
const request = await firstValueFrom(this._post<{ commentId: string }>({ text: comment }, url));
|
||||
return request.commentId;
|
||||
}
|
||||
|
||||
@Validate()
|
||||
deleteComment(@RequiredParam() commentId: string, @RequiredParam() annotationId: string, dossierId: string, fileId: string) {
|
||||
const url = `${this._defaultModelPath}/comment/undo/${dossierId}/${fileId}/${annotationId}/${commentId}`;
|
||||
return super.delete({}, url);
|
||||
return firstValueFrom(super.delete({}, url));
|
||||
}
|
||||
|
||||
addRecommendation(annotations: AnnotationWrapper[], dossierId: string, fileId: string, comment = { text: 'Accepted Recommendation' }) {
|
||||
|
||||
@ -112,8 +112,10 @@ export class PdfProxyService {
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
loadViewer() {
|
||||
this._configureElements();
|
||||
configureElements() {
|
||||
const hexColor = this._dictionariesMapService.get(this._state.dossierTemplateId, 'manual').hexColor;
|
||||
const color = this._annotationDrawService.convertColor(hexColor);
|
||||
this._documentViewer.setRectangleToolStyles(color);
|
||||
}
|
||||
|
||||
#deactivateMultiSelect() {
|
||||
@ -185,12 +187,6 @@ export class PdfProxyService {
|
||||
this._annotationsActionsService.cancelResize(null, wrapper).then();
|
||||
}
|
||||
|
||||
private _configureElements() {
|
||||
const hexColor = this._dictionariesMapService.get(this._state.dossierTemplateId, 'manual').hexColor;
|
||||
const color = this._annotationDrawService.convertColor(hexColor);
|
||||
this._documentViewer.setRectangleToolStyles(color);
|
||||
}
|
||||
|
||||
#configureAnnotationSpecificActions(viewerAnnotations: Annotation[]) {
|
||||
if (!this.canPerformActions) {
|
||||
return this._pdf.resetAnnotationActions();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user