diff --git a/apps/red-ui/src/app/modules/dossier/components/annotation-actions/annotation-actions.component.ts b/apps/red-ui/src/app/modules/dossier/components/annotation-actions/annotation-actions.component.ts index e0aa2c6ec..a9d14fb73 100644 --- a/apps/red-ui/src/app/modules/dossier/components/annotation-actions/annotation-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/annotation-actions/annotation-actions.component.ts @@ -6,6 +6,8 @@ import { AnnotationPermissions } from '@models/file/annotation.permissions'; import { AnnotationActionsService } from '../../services/annotation-actions.service'; import { WebViewerInstance } from '@pdftron/webviewer'; import { UserService } from '@services/user.service'; +import { ActivatedRoute } from '@angular/router'; +import { DossiersService } from '@services/entity-services/dossiers.service'; export const AnnotationButtonTypes = { dark: 'dark', @@ -27,13 +29,18 @@ export class AnnotationActionsComponent implements OnInit { @Input() alwaysVisible: boolean; @Output() annotationsChanged = new EventEmitter(); annotationPermissions: AnnotationPermissions; + readonly dossierId: string; constructor( readonly appStateService: AppStateService, readonly annotationActionsService: AnnotationActionsService, private readonly _permissionsService: PermissionsService, private readonly _userService: UserService, - ) {} + private readonly _dossiersService: DossiersService, + activatedRoute: ActivatedRoute, + ) { + this.dossierId = activatedRoute.snapshot.paramMap.get('dossierId'); + } private _annotations: AnnotationWrapper[]; @@ -94,14 +101,6 @@ export class AnnotationActionsComponent implements OnInit { this.annotationActionsService.updateHiddenAnnotation(this.annotations, this.viewerAnnotations, false); } - private _setPermissions() { - this.annotationPermissions = AnnotationPermissions.forUser( - this._permissionsService.isApprover(), - this._userService.currentUser, - this.annotations, - ); - } - resize($event: MouseEvent) { this.annotationActionsService.resize($event, this.viewer, this.annotations[0]); } @@ -113,4 +112,13 @@ export class AnnotationActionsComponent implements OnInit { cancelResize($event: MouseEvent) { this.annotationActionsService.cancelResize($event, this.viewer, this.annotations[0], this.annotationsChanged); } + + private _setPermissions() { + const dossier = this._dossiersService.find(this.dossierId); + this.annotationPermissions = AnnotationPermissions.forUser( + this._permissionsService.isApprover(dossier), + this._userService.currentUser, + this.annotations, + ); + } } diff --git a/apps/red-ui/src/app/modules/dossier/components/comments/comments.component.html b/apps/red-ui/src/app/modules/dossier/components/comments/comments.component.html index 190e5a2c7..9bb9e5592 100644 --- a/apps/red-ui/src/app/modules/dossier/components/comments/comments.component.html +++ b/apps/red-ui/src/app/modules/dossier/components/comments/comments.component.html @@ -8,7 +8,7 @@
+
{{ range.startPage }} -{{ range.endPage }} @@ -29,7 +29,7 @@
diff --git a/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts b/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts index 743b86fd5..04b1f1836 100644 --- a/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts @@ -14,7 +14,7 @@ import { PermissionsService } from '@services/permissions.service'; import { ConfigService } from '@services/config.service'; import { DossiersService } from '@services/entity-services/dossiers.service'; import { ViewedPagesService } from '../../shared/services/viewed-pages.service'; -import { IViewedPage } from '@red/domain'; +import { File, IViewedPage } from '@red/domain'; import { AutoUnsubscribe } from '@iqser/common-ui'; @Component({ @@ -24,6 +24,7 @@ import { AutoUnsubscribe } from '@iqser/common-ui'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class PageIndicatorComponent extends AutoUnsubscribe implements OnChanges, OnInit, OnDestroy { + @Input() file: File; @Input() active: boolean; @Input() showDottedIcon = false; @Input() number: number; @@ -60,8 +61,8 @@ export class PageIndicatorComponent extends AutoUnsubscribe implements OnChanges ngOnInit(): void { this.addSubscription = this._appStateService.fileChanged$.subscribe(() => { - if (this.canMarkPagesAsViewed !== this._permissionService.canMarkPagesAsViewed()) { - this.canMarkPagesAsViewed = this._permissionService.canMarkPagesAsViewed(); + if (this.canMarkPagesAsViewed !== this._permissionService.canMarkPagesAsViewed(this.file)) { + this.canMarkPagesAsViewed = this._permissionService.canMarkPagesAsViewed(this.file); this._handlePageRead(); } }); @@ -119,20 +120,16 @@ export class PageIndicatorComponent extends AutoUnsubscribe implements OnChanges // } private async _markPageRead() { - await this._viewedPagesService - .addPage({ page: this.number }, this._dossiersService.activeDossierId, this._appStateService.activeFileId) - .toPromise(); + await this._viewedPagesService.addPage({ page: this.number }, this.file.dossierId, this.file.fileId).toPromise(); if (this.activePage) { this.activePage.hasChanges = false; } else { - this.viewedPages?.push({ page: this.number, fileId: this._appStateService.activeFileId }); + this.viewedPages?.push({ page: this.number, fileId: this.file.fileId }); } } private async _markPageUnread() { - await this._viewedPagesService - .removePage(this._dossiersService.activeDossierId, this._appStateService.activeFileId, this.number) - .toPromise(); + await this._viewedPagesService.removePage(this.file.dossierId, this.file.fileId, this.number).toPromise(); this.viewedPages?.splice( this.viewedPages?.findIndex(p => p.page === this.number), 1, diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts index e9fc4bce4..cd1573fa1 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts @@ -15,7 +15,6 @@ export interface LegalBasisOption { } @Component({ - selector: 'redaction-change-legal-basis-dialog', templateUrl: './change-legal-basis-dialog.component.html', styleUrls: ['./change-legal-basis-dialog.component.scss'], }) diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts index 41906f856..943ebfef6 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts @@ -599,7 +599,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni private _updateCanPerformActions() { this.canPerformAnnotationActions = - this.permissionsService.canPerformAnnotationActions() && + this.permissionsService.canPerformAnnotationActions(this.file) && this.viewMode === 'STANDARD' && !this.viewerComponent?.utils.isCompareMode; } diff --git a/apps/red-ui/src/app/modules/dossier/shared/services/file-action.service.ts b/apps/red-ui/src/app/modules/dossier/shared/services/file-action.service.ts index dd97c5865..c1bd99f69 100644 --- a/apps/red-ui/src/app/modules/dossier/shared/services/file-action.service.ts +++ b/apps/red-ui/src/app/modules/dossier/shared/services/file-action.service.ts @@ -1,5 +1,4 @@ import { Injectable } from '@angular/core'; -import { AppStateService } from '@state/app-state.service'; import { UserService } from '@services/user.service'; import { File } from '@red/domain'; import { DossiersDialogService } from '../../services/dossiers-dialog.service'; @@ -16,16 +15,15 @@ export class FileActionService { private readonly _userService: UserService, private readonly _filesService: FilesService, private readonly _reanalysisService: ReanalysisService, - private readonly _appStateService: AppStateService, private readonly _dossiersService: DossiersService, private readonly _toaster: Toaster, ) {} - reanalyseFile(file = this._appStateService.activeFile) { + reanalyseFile(file: File) { return this._reanalysisService.reanalyzeFilesForDossier([file.fileId], this._dossiersService.activeDossier.id, true); } - toggleAnalysis(file = this._appStateService.activeFile) { + toggleAnalysis(file: File) { return this._reanalysisService.toggleAnalysis(file.dossierId, file.fileId, !file.excluded); } @@ -83,13 +81,7 @@ export class FileActionService { ); } - assignFile( - mode: 'reviewer' | 'approver', - $event: MouseEvent, - file = this._appStateService.activeFile, - callback?: Function, - ignoreChanged = false, - ) { + assignFile(mode: 'reviewer' | 'approver', $event: MouseEvent, file: File, callback?: Function, ignoreChanged = false) { const userIds = this._getUserIds(mode); if (userIds.length === 1 || userIds.includes(this._userService.currentUser.id)) { $event?.stopPropagation(); // event$ is null when called from workflow view diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index 75e12021f..02790f675 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -1,5 +1,4 @@ import { Injectable } from '@angular/core'; -import { AppStateService } from '@state/app-state.service'; import { UserService } from './user.service'; import { Dossier, File, IComment } from '@red/domain'; import { DossiersService } from './entity-services/dossiers.service'; @@ -8,22 +7,14 @@ import { DossiersService } from './entity-services/dossiers.service'; providedIn: 'root', }) export class PermissionsService { - constructor( - private readonly _appStateService: AppStateService, - private readonly _userService: UserService, - private readonly _dossiersService: DossiersService, - ) {} - - private get _activeFile(): File | undefined { - return this._appStateService.activeFile; - } + constructor(private readonly _userService: UserService, private readonly _dossiersService: DossiersService) {} private get _activeDossier(): Dossier | undefined { return this._dossiersService.activeDossier; } - isReviewerOrApprover(file?: File): boolean { - return this.isFileReviewer(file) || this.isApprover(); + isReviewerOrApprover(file: File): boolean { + return this.isFileReviewer(file) || this.isApprover(this._getDossier(file)); } displayReanalyseBtn(dossier: Dossier): boolean { @@ -34,27 +25,28 @@ export class PermissionsService { return this.isReviewerOrApprover(file) && ['UNASSIGNED', 'UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status); } - canReanalyseFile(file = this._activeFile): boolean { + canReanalyseFile(file: File): boolean { return this.isReviewerOrApprover(file) || file.isUnassigned || (file.isError && file.isUnassigned); } - isFileReviewer(file = this._activeFile): boolean { + isFileReviewer(file: File): boolean { return file.currentReviewer === this._userService.currentUser.id; } - canDeleteFile(file = this._activeFile, dossier?: Dossier): boolean { + canDeleteFile(file: File, dossier?: Dossier): boolean { return (this.isOwner(dossier) && !file.isApproved) || file.isUnassigned; } - canAssignToSelf(file = this._activeFile): boolean { - const precondition = this.isDossierMember() && !file.isProcessing && !file.isError && !file.isApproved; + canAssignToSelf(file: File): boolean { + const dossier = this._getDossier(file); + const precondition = this.isDossierMember(dossier) && !file.isProcessing && !file.isError && !file.isApproved; - const isTheOnlyReviewer = !this._activeDossier?.hasReviewers; + const isTheOnlyReviewer = !dossier?.hasReviewers; if (precondition) { if ( (file.isUnassigned || (file.isUnderReview && !this.isFileReviewer(file))) && - (this.isApprover() || isTheOnlyReviewer || (this.isDossierReviewer() && file.isUnassigned)) + (this.isApprover(dossier) || isTheOnlyReviewer || (this.isDossierReviewer(dossier) && file.isUnassigned)) ) { return true; } @@ -62,37 +54,39 @@ export class PermissionsService { return false; } - canAssignUser(file = this._activeFile): boolean { - const precondition = !file.isProcessing && !file.isError && !file.isApproved && this.isApprover(); + canAssignUser(file: File): boolean { + const dossier = this._getDossier(file); + const precondition = !file.isProcessing && !file.isError && !file.isApproved && this.isApprover(dossier); if (precondition) { - if ((file.isUnassigned || file.isUnderReview) && this._activeDossier.hasReviewers) { + if ((file.isUnassigned || file.isUnderReview) && dossier.hasReviewers) { return true; } - if (file.isUnderApproval && this._activeDossier.approverIds.length > 1) { + if (file.isUnderApproval && dossier.approverIds.length > 1) { return true; } } return false; } - canUnassignUser(file = this._activeFile): boolean { - return (file.isUnderReview || file.isUnderApproval) && (this.isFileReviewer(file) || this.isApprover()); + canUnassignUser(file: File): boolean { + const dossier = this._getDossier(file); + return (file.isUnderReview || file.isUnderApproval) && (this.isFileReviewer(file) || this.isApprover(dossier)); } - canSetUnderReview(file = this._activeFile): boolean { - return file?.isUnderApproval && this.isApprover(); + canSetUnderReview(file: File): boolean { + return file?.isUnderApproval && this.isApprover(this._getDossier(file)); } - isReadyForApproval(file = this._activeFile): boolean { + isReadyForApproval(file: File): boolean { return this.canSetUnderReview(file); } - canSetUnderApproval(file = this._activeFile): boolean { + canSetUnderApproval(file: File): boolean { return file?.isUnderReview && this.isReviewerOrApprover(file); } - isOwner(dossier = this._activeDossier, user = this._userService.currentUser): boolean { + isOwner(dossier: Dossier, user = this._userService.currentUser): boolean { return dossier?.ownerId === user.id; } @@ -100,28 +94,28 @@ export class PermissionsService { return dossier?.approverIds.indexOf(user.id) >= 0; } - isDossierReviewer(dossier = this._activeDossier, user = this._userService.currentUser): boolean { + isDossierReviewer(dossier: Dossier, user = this._userService.currentUser): boolean { return this.isDossierMember(dossier, user) && !this.isApprover(dossier, user); } - isDossierMember(dossier = this._activeDossier, user = this._userService.currentUser): boolean { + isDossierMember(dossier: Dossier, user = this._userService.currentUser): boolean { return dossier?.memberIds.includes(user.id); } - canPerformAnnotationActions(file = this._activeFile): boolean { + canPerformAnnotationActions(file: File): boolean { return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file?.status) && this.isFileReviewer(file); } - canUndoApproval(file = this._activeFile): boolean { - return file?.isApproved && this.isApprover(); + canUndoApproval(file: File): boolean { + return file?.isApproved && this.isApprover(this._getDossier(file)); } - canMarkPagesAsViewed(file = this._activeFile): boolean { + canMarkPagesAsViewed(file: File): boolean { return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file?.status) && this.isFileReviewer(file); } canDownloadFiles(file: File): boolean { - const dossier = this._dossiersService.find(file?.dossierId); + const dossier = this._getDossier(file); if (!dossier) { return false; } @@ -129,7 +123,7 @@ export class PermissionsService { return file.isApproved && this.isApprover(dossier); } - canDeleteDossier(dossier = this._activeDossier): boolean { + canDeleteDossier(dossier: Dossier): boolean { return dossier.ownerId === this._userService.currentUser.id; } @@ -137,15 +131,21 @@ export class PermissionsService { return user.isAdmin; } - canAddComment(file = this._activeFile): boolean { - return (this.isFileReviewer(file) || this.isApprover()) && !file.isApproved; + canAddComment(file: File): boolean { + return (this.isFileReviewer(file) || this.isApprover(this._getDossier(file))) && !file.isApproved; } - canExcludePages(file = this._activeFile): boolean { - return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status) && (this.isFileReviewer(file) || this.isApprover()); + canExcludePages(file: File): boolean { + const dossier = this._getDossier(file); + return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status) && (this.isFileReviewer(file) || this.isApprover(dossier)); } - canDeleteComment(comment: IComment, file = this._activeFile) { - return (comment.user === this._userService.currentUser.id || this.isApprover()) && !file.isApproved; + canDeleteComment(comment: IComment, file: File) { + const dossier = this._getDossier(file); + return (comment.user === this._userService.currentUser.id || this.isApprover(dossier)) && !file.isApproved; + } + + private _getDossier(file: File): Dossier { + return this._dossiersService.find(file.dossierId); } }