RED-6144: some refactorings

This commit is contained in:
Dan Percic 2023-02-11 23:34:18 +02:00
parent f9db9885da
commit fa0ae7e333
25 changed files with 100 additions and 177 deletions

View File

@ -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>

View File

@ -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;

View File

@ -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 {

View File

@ -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">

View File

@ -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>();

View File

@ -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;

View File

@ -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>

View File

@ -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];
}
}

View File

@ -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>

View File

@ -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>();

View File

@ -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">

View File

@ -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();

View File

@ -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[]>;

View File

@ -203,7 +203,6 @@
<redaction-annotations-list
(pagesPanelActive)="pagesPanelActive = $event"
[annotationActionsTemplate]="annotationActionsTemplate"
[annotations]="(displayedAnnotations$ | async)?.get(activeViewerPage)"
></redaction-annotations-list>
</div>

View File

@ -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 {

View File

@ -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;

View File

@ -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);

View File

@ -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>

View File

@ -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];
}
}

View File

@ -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'"

View File

@ -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;
}
}

View File

@ -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() {

View File

@ -5,7 +5,6 @@ import {
IRedactionLog,
IRedactionLogEntry,
LogEntryStatuses,
ManualRedactionType,
ViewedPage,
ViewMode,
ViewModes,

View File

@ -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' }) {

View File

@ -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();