From dc4d18433fb81355400b86b1aa9177dc9d525109 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Wed, 2 Feb 2022 14:27:42 +0200 Subject: [PATCH] add readonly to state service --- .../annotation-actions.component.ts | 5 +- .../annotations-list.component.ts | 13 +- .../file-workload.component.html | 9 +- .../file-workload/file-workload.component.ts | 10 +- .../file-preview-screen.component.html | 242 +++++++++--------- .../services/file-preview-state.service.ts | 28 +- .../services/multi-select.service.ts | 16 +- libs/common-ui | 2 +- 8 files changed, 167 insertions(+), 158 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-actions/annotation-actions.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-actions/annotation-actions.component.ts index b147cfcec..faf87375c 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-actions/annotation-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-actions/annotation-actions.component.ts @@ -8,7 +8,6 @@ import { UserService } from '@services/user.service'; import { AnnotationReferencesService } from '../../services/annotation-references.service'; import { MultiSelectService } from '../../services/multi-select.service'; import { FilePreviewStateService } from '../../services/file-preview-state.service'; -import { firstValueFrom } from 'rxjs'; export const AnnotationButtonTypes = { dark: 'dark', @@ -34,9 +33,9 @@ export class AnnotationActionsComponent implements OnChanges { constructor( private readonly _userService: UserService, readonly multiSelectService: MultiSelectService, + private readonly _state: FilePreviewStateService, private readonly _permissionsService: PermissionsService, readonly annotationActionsService: AnnotationActionsService, - private readonly _screenStateService: FilePreviewStateService, readonly annotationReferencesService: AnnotationReferencesService, ) {} @@ -115,7 +114,7 @@ export class AnnotationActionsComponent implements OnChanges { } private async _setPermissions() { - const dossier = await firstValueFrom(this._screenStateService.dossier$); + const dossier = await this._state.dossier; this.annotationPermissions = AnnotationPermissions.forUser( this._permissionsService.isApprover(dossier), this._userService.currentUser, diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.ts index d812af678..526eb3624 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.ts @@ -4,6 +4,8 @@ import { FilterService, HelpModeService, IqserEventTarget } from '@iqser/common- import { MultiSelectService } from '../../services/multi-select.service'; import { AnnotationReferencesService } from '../../services/annotation-references.service'; import { ViewModeService } from '../../services/view-mode.service'; +import { FilePreviewStateService } from '../../services/file-preview-state.service'; +import { firstValueFrom } from 'rxjs'; @Component({ selector: 'redaction-annotations-list', @@ -16,7 +18,6 @@ export class AnnotationsListComponent implements OnChanges { @Input() selectedAnnotations: AnnotationWrapper[]; @Input() annotationActionsTemplate: TemplateRef; @Input() activeViewerPage: number; - @Input() canMultiSelect = true; @Output() readonly pagesPanelActive = new EventEmitter(); @Output() readonly selectAnnotations = new EventEmitter(); @@ -28,6 +29,7 @@ export class AnnotationsListComponent implements OnChanges { readonly helpModeService: HelpModeService, readonly annotationReferencesService: AnnotationReferencesService, private readonly _filterService: FilterService, + private readonly _state: FilePreviewStateService, ) {} ngOnChanges(changes: SimpleChanges): void { @@ -36,7 +38,7 @@ export class AnnotationsListComponent implements OnChanges { } } - annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void { + async annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): Promise { if (($event?.target as IqserEventTarget)?.localName === 'input') { return; } @@ -50,15 +52,16 @@ export class AnnotationsListComponent implements OnChanges { if (this.isSelected(annotation.annotationId)) { this.deselectAnnotations.emit([annotation]); } else { - if (this.canMultiSelect && ($event?.ctrlKey || $event?.metaKey) && this.selectedAnnotations.length > 0) { + const canMultiSelect = await firstValueFrom(this._state.isWritable$); + if (canMultiSelect && ($event?.ctrlKey || $event?.metaKey) && this.selectedAnnotations.length > 0) { this.multiSelectService.activate(); } this.selectAnnotations.emit([annotation]); } } - referenceClicked(annotation: AnnotationWrapper): void { - this.annotationClicked(annotation, null); + async referenceClicked(annotation: AnnotationWrapper): Promise { + await this.annotationClicked(annotation, null); if (this._filterService.filtersEnabled('primaryFilters')) { this._filterService.toggleFilter('primaryFilters', annotation.superType, true); } diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.html index e36aef21a..80384739b 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.html @@ -14,7 +14,7 @@
-
+
@@ -53,7 +53,7 @@ *ngIf="selectedAnnotations?.length > 0" [alwaysVisible]="true" [annotations]="selectedAnnotations" - [canPerformAnnotationActions]="!isReadOnly" + [canPerformAnnotationActions]="state.isWritable$ | async" [viewer]="viewer" buttonType="primary" tooltipPosition="above" @@ -67,7 +67,7 @@ >
-
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.ts index 584a25e84..c3fd3396e 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.ts @@ -33,6 +33,7 @@ import { ExcludedPagesService } from '../../services/excluded-pages.service'; import { MultiSelectService } from '../../services/multi-select.service'; import { DocumentInfoService } from '../../services/document-info.service'; import { SkippedService } from '../../services/skipped.service'; +import { FilePreviewStateService } from '../../services/file-preview-state.service'; const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape']; const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; @@ -75,6 +76,7 @@ export class FileWorkloadComponent { readonly multiSelectService: MultiSelectService, readonly documentInfoService: DocumentInfoService, readonly skippedService: SkippedService, + readonly state: FilePreviewStateService, private readonly _permissionsService: PermissionsService, private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _filterService: FilterService, @@ -95,10 +97,6 @@ export class FileWorkloadComponent { return this.displayedAnnotations.get(this.activeViewerPage); } - get isReadOnly(): boolean { - return !this._permissionsService.canPerformAnnotationActions(this.file); - } - get currentPageIsExcluded(): boolean { return this.file?.excludedPages?.includes(this.activeViewerPage); } @@ -252,8 +250,8 @@ export class FileWorkloadComponent { this.selectPage.emit(1); } - scrollQuickNavLast(): void { - this.selectPage.emit(this.file.numberOfPages); + scrollQuickNavLast(): Promise { + return this.state.file.then(file => this.selectPage.emit(file.numberOfPages)); } pageSelectedByClick($event: number): void { diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html index aaf57ede5..c4a535d67 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html @@ -1,135 +1,137 @@ - -
-
+ + + + + + + + + + + + {{ filter.label | humanize: false }} + + diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/file-preview-state.service.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/file-preview-state.service.ts index c698ce8a4..5ba0e6889 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/file-preview-state.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/file-preview-state.service.ts @@ -5,40 +5,50 @@ import { Dossier, File } from '@red/domain'; import { DossiersService } from '../../../../../services/entity-services/dossiers.service'; import { ActivatedRoute } from '@angular/router'; import { FilesMapService } from '../../../../../services/entity-services/files-map.service'; +import { PermissionsService } from '../../../../../services/permissions.service'; +import { boolFactory } from '@iqser/common-ui'; @Injectable() export class FilePreviewStateService { readonly fileData$: Observable; readonly file$: Observable; readonly dossier$: Observable; + readonly isReadonly$: Observable; + readonly isWritable$: Observable; readonly dossierId: string; readonly dossierTemplateId: string; readonly fileId: string; - private readonly _fileData$ = new BehaviorSubject(undefined); + readonly #fileData$ = new BehaviorSubject(undefined); constructor( - private readonly _dossiersService: DossiersService, - private readonly _filesMapService: FilesMapService, + dossiersService: DossiersService, + filesMapService: FilesMapService, + permissionsService: PermissionsService, activatedRoute: ActivatedRoute, ) { this.dossierId = activatedRoute.snapshot.paramMap.get('dossierId'); - this.dossierTemplateId = this._dossiersService.find(this.dossierId).dossierTemplateId; - this.dossier$ = _dossiersService.getEntityChanged$(this.dossierId); + this.dossierTemplateId = dossiersService.find(this.dossierId).dossierTemplateId; + this.dossier$ = dossiersService.getEntityChanged$(this.dossierId); this.fileId = activatedRoute.snapshot.paramMap.get('fileId'); - this.fileData$ = this._fileData$.asObservable(); - this.file$ = _filesMapService.watch$(this.dossierId, this.fileId); + this.fileData$ = this.#fileData$.asObservable(); + this.file$ = filesMapService.watch$(this.dossierId, this.fileId); + [this.isReadonly$, this.isWritable$] = boolFactory(this.file$, file => !permissionsService.canPerformAnnotationActions(file)); } get fileData(): FileDataModel { - return this._fileData$.value; + return this.#fileData$.value; } set fileData(fileDataModel: FileDataModel) { - this._fileData$.next(fileDataModel); + this.#fileData$.next(fileDataModel); } get file(): Promise { return firstValueFrom(this.file$); } + + get dossier(): Promise { + return firstValueFrom(this.dossier$); + } } diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/multi-select.service.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/multi-select.service.ts index 60e990157..71455608d 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/multi-select.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/multi-select.service.ts @@ -1,32 +1,30 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; -import { shareDistinctLast } from '@iqser/common-ui'; -import { map } from 'rxjs/operators'; +import { boolFactory } from '@iqser/common-ui'; @Injectable() export class MultiSelectService { readonly active$: Observable; readonly inactive$: Observable; - private readonly _active$ = new BehaviorSubject(false); + readonly #active$ = new BehaviorSubject(false); constructor() { - this.active$ = this._active$.asObservable().pipe(shareDistinctLast()); - this.inactive$ = this.active$.pipe(map(value => !value)); + [this.active$, this.inactive$] = boolFactory(this.#active$.asObservable()); } get isActive() { - return this._active$.value; + return this.#active$.value; } activate() { - this._active$.next(true); + this.#active$.next(true); } deactivate() { - this._active$.next(false); + this.#active$.next(false); } toggle() { - this._active$.next(!this._active$.value); + this.#active$.next(!this.#active$.value); } } diff --git a/libs/common-ui b/libs/common-ui index 31b60ff11..b808e4661 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 31b60ff117a8d8ecb9617be3b0c9e1822d437034 +Subproject commit b808e4661e56aa93baca96c57f910443437112d4