diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts b/apps/red-ui/src/app/modules/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts index dfa7e203b..47edcdc94 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts @@ -96,6 +96,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { type: ActionTypes.downloadBtn, show: true, files: this.selectedFiles, + dossier: this.dossier, }, { type: ActionTypes.circleBtn, @@ -175,12 +176,14 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { this.#canAssign = this.#canMoveToSameState && this.selectedFiles.reduce( - (acc, file) => (acc && this._permissionsService.canAssignUser(file)) || this._permissionsService.canUnassignUser(file), + (acc, file) => + (acc && this._permissionsService.canAssignUser(file, this.dossier)) || + this._permissionsService.canUnassignUser(file, this.dossier), true, ); - this.#canAssignToSelf = this.#canMoveToSameState && this._permissionsService.canAssignToSelf(this.selectedFiles); + this.#canAssignToSelf = this.#canMoveToSameState && this._permissionsService.canAssignToSelf(this.selectedFiles, this.dossier); - this.#canDelete = this._permissionsService.canDeleteFile(this.selectedFiles); + this.#canDelete = this._permissionsService.canDeleteFile(this.selectedFiles, this.dossier); this.#canReanalyse = this._permissionsService.canReanalyseFile(this.selectedFiles, this.dossier); @@ -190,19 +193,19 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { this.#canToggleAnalysis = this._permissionsService.canToggleAnalysis(this.selectedFiles); - this.#canOcr = this._permissionsService.canOcrFile(this.selectedFiles); + this.#canOcr = this._permissionsService.canOcrFile(this.selectedFiles, this.dossier); this.#canSetToNew = this._permissionsService.canSetToNew(this.selectedFiles) && !isWorkflow; - this.#canSetToUnderReview = this._permissionsService.canSetUnderReview(this.selectedFiles) && !isWorkflow; + this.#canSetToUnderReview = this._permissionsService.canSetUnderReview(this.selectedFiles, this.dossier) && !isWorkflow; this.#canSetToUnderApproval = this._permissionsService.canSetUnderApproval(this.selectedFiles, this.dossier) && !isWorkflow; - this.#isReadyForApproval = this._permissionsService.isReadyForApproval(this.selectedFiles) && !isWorkflow; + this.#isReadyForApproval = this._permissionsService.isReadyForApproval(this.selectedFiles, this.dossier) && !isWorkflow; this.#canApprove = this._permissionsService.canBeApproved(this.selectedFiles) && !isWorkflow; - this.#canUndoApproval = this._permissionsService.canUndoApproval(this.selectedFiles) && !isWorkflow; + this.#canUndoApproval = this._permissionsService.canUndoApproval(this.selectedFiles, this.dossier) && !isWorkflow; this.#assignTooltip = allFilesAreUnderApproval ? _('dossier-overview.assign-approver') : _('dossier-overview.assign-reviewer'); diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html index 2edb909ac..15b9a88a0 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html +++ b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html @@ -7,6 +7,7 @@ > - this._permissionsService.canSetUnderReview(files) || - this._permissionsService.canAssignToSelf(files) || - this._permissionsService.canAssignUser(files), + this._permissionsService.canSetUnderReview(files, dossier) || + this._permissionsService.canAssignToSelf(files, dossier) || + this._permissionsService.canAssignUser(files, dossier), key: WorkflowFileStatuses.UNDER_REVIEW, color: '#FDBD00', entities: new BehaviorSubject([]), @@ -83,7 +83,8 @@ export class ConfigService { label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_APPROVAL], enterFn: (files: File[]) => this._bulkActionsService.setToUnderApproval(files), enterPredicate: (files: File[]) => - this._permissionsService.canSetUnderApproval(files, dossier) || this._permissionsService.canUndoApproval(files), + this._permissionsService.canSetUnderApproval(files, dossier) || + this._permissionsService.canUndoApproval(files, dossier), key: WorkflowFileStatuses.UNDER_APPROVAL, color: '#374C81', entities: new BehaviorSubject([]), @@ -92,7 +93,7 @@ export class ConfigService { label: workflowFileStatusTranslations[WorkflowFileStatuses.APPROVED], enterFn: (files: File[]) => this._bulkActionsService.approve(files), enterPredicate: (files: File[]) => - this._permissionsService.isReadyForApproval(files) && this._permissionsService.canBeApproved(files), + this._permissionsService.isReadyForApproval(files, dossier) && this._permissionsService.canBeApproved(files), key: WorkflowFileStatuses.APPROVED, color: '#48C9F7', entities: new BehaviorSubject([]), diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component.ts index b1f7e77b4..2f7bc49bb 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component.ts @@ -67,7 +67,7 @@ export class AssignReviewerApproverDialogComponent { } private get _canUnassignFiles() { - return this.permissionsService.canUnassignUser(this.data.files); + return this.permissionsService.canUnassignUser(this.data.files, this.dossier); } /** Initialize the form with: diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts index 508e8d097..4374b7c81 100644 --- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts @@ -162,6 +162,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, type: ActionTypes.downloadBtn, show: true, files: [this.file], + dossier: this.dossier, tooltipClass: 'small', }, { @@ -437,24 +438,25 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, this.toggleTooltip = this._toggleTooltip; this.showSetToNew = this._permissionsService.canSetToNew(this.file) && !this.isDossierOverviewWorkflow; - this.showUndoApproval = this._permissionsService.canUndoApproval(this.file) && !this.isDossierOverviewWorkflow; - this.showUnderReview = this._permissionsService.canSetUnderReview(this.file) && !this.isDossierOverviewWorkflow; + this.showUndoApproval = this._permissionsService.canUndoApproval(this.file, this.dossier) && !this.isDossierOverviewWorkflow; + this.showUnderReview = this._permissionsService.canSetUnderReview(this.file, this.dossier) && !this.isDossierOverviewWorkflow; this.showUnderApproval = this._permissionsService.canSetUnderApproval(this.file, this.dossier) && !this.isDossierOverviewWorkflow; - this.showApprove = this._permissionsService.isReadyForApproval(this.file) && !this.isDossierOverviewWorkflow; + this.showApprove = this._permissionsService.isReadyForApproval(this.file, this.dossier) && !this.isDossierOverviewWorkflow; this.canToggleAnalysis = this._permissionsService.canToggleAnalysis(this.file); this.showToggleAnalysis = this._permissionsService.showToggleAnalysis(this.file); - this.showDelete = this._permissionsService.canDeleteFile(this.file); - this.showOCR = this._permissionsService.canOcrFile(this.file); + this.showDelete = this._permissionsService.canDeleteFile(this.file, this.dossier); + this.showOCR = this._permissionsService.canOcrFile(this.file, this.dossier); this.canReanalyse = this._permissionsService.canReanalyseFile(this.file, this.dossier); this.canDisableAutoAnalysis = this._permissionsService.canDisableAutoAnalysis([this.file]); this.canEnableAutoAnalysis = this._permissionsService.canEnableAutoAnalysis([this.file]); this.showStatusBar = !this.file.isError && !this.file.isUnprocessed && this.isDossierOverviewList; - this.showAssignToSelf = this._permissionsService.canAssignToSelf(this.file) && this.isDossierOverview; + this.showAssignToSelf = this._permissionsService.canAssignToSelf(this.file, this.dossier) && this.isDossierOverview; this.showAssign = - (this._permissionsService.canAssignUser(this.file) || this._permissionsService.canUnassignUser(this.file)) && + (this._permissionsService.canAssignUser(this.file, this.dossier) || + this._permissionsService.canUnassignUser(this.file, this.dossier)) && this.isDossierOverview; this.showImportRedactions = this._permissionsService.canImportRedactions(this.file); diff --git a/apps/red-ui/src/app/modules/dossiers-listing/components/dossiers-listing-actions/dossiers-listing-actions.component.html b/apps/red-ui/src/app/modules/dossiers-listing/components/dossiers-listing-actions/dossiers-listing-actions.component.html index b58f96883..8e84ed10d 100644 --- a/apps/red-ui/src/app/modules/dossiers-listing/components/dossiers-listing-actions/dossiers-listing-actions.component.html +++ b/apps/red-ui/src/app/modules/dossiers-listing/components/dossiers-listing-actions/dossiers-listing-actions.component.html @@ -18,6 +18,7 @@ >
-
+
this.permissionsService.canAssignToSelf(file)), + map(([file, dossier]) => this.permissionsService.canAssignToSelf(file, dossier)), distinctUntilChanged(), ); this._canAssignUser$ = this.stateService.file$.pipe( combineLatestWith(this.stateService.dossier$), - map(([file]) => this.permissionsService.canAssignUser(file)), + map(([file, dossier]) => this.permissionsService.canAssignUser(file, dossier)), distinctUntilChanged(), ); this._canUnassignUser$ = this.stateService.file$.pipe( combineLatestWith(this.stateService.dossier$), - map(([file]) => this.permissionsService.canUnassignUser(file)), + map(([file, dossier]) => this.permissionsService.canUnassignUser(file, dossier)), distinctUntilChanged(), ); diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts index 0b595cdf7..66912c469 100644 --- a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts @@ -1,21 +1,20 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; -import { File } from '@red/domain'; +import { Dossier, File } from '@red/domain'; import { FileDownloadService } from '@upload-download/services/file-download.service'; import { CircleButtonType, CircleButtonTypes, Toaster } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { firstValueFrom } from 'rxjs'; -export type MenuState = 'OPEN' | 'CLOSED'; - @Component({ - selector: 'redaction-file-download-btn', + selector: 'redaction-file-download-btn [files] [dossier]', templateUrl: './file-download-btn.component.html', styleUrls: ['./file-download-btn.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class FileDownloadBtnComponent implements OnChanges { @Input() files: File[]; + @Input() dossier: Dossier; @Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above'; @Input() type: CircleButtonType = CircleButtonTypes.default; @Input() tooltipClass: string; @@ -31,7 +30,7 @@ export class FileDownloadBtnComponent implements OnChanges { ) {} ngOnChanges(): void { - this.canDownloadFiles = this._permissionsService.canDownloadFiles(this.files); + this.canDownloadFiles = this._permissionsService.canDownloadFiles(this.files, this.dossier); this.tooltip = this.canDownloadFiles ? _('dossier-overview.download-file') : _('dossier-overview.download-file-disabled'); } diff --git a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html index 2a838dfbf..3ad717745 100644 --- a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html @@ -5,24 +5,25 @@ [attr.aria-expanded]="btn.ariaExpanded && btn.ariaExpanded | async" [disabled]="btn.disabled" [icon]="btn.icon" + [iqserHelpMode]="helpModeKey" + [scrollableParentView]="scrollableParentView" [showDot]="btn.showDot" [tooltipClass]="btn.tooltipClass" [tooltipPosition]="tooltipPosition" [tooltip]="btn.tooltip | translate" [type]="btn.buttonType || buttonType" - [iqserHelpMode]="helpModeKey" - [scrollableParentView]="scrollableParentView" > @@ -32,10 +33,10 @@ (click)="$event.stopPropagation()" [checked]="btn.checked" [disabled]="btn.disabled" + [iqserHelpMode]="helpModeKey" [matTooltipPosition]="tooltipPosition" [matTooltip]="btn.tooltip | translate" [ngClass]="btn.class" - [iqserHelpMode]="helpModeKey" [scrollableParentView]="scrollableParentView" color="primary" > diff --git a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts index c3cf688a2..9e59249c4 100644 --- a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts @@ -55,7 +55,7 @@ export class ExpandableFileActionsComponent implements OnChanges { const downloadBtn = this.actions.find(btn => btn.type === ActionTypes.downloadBtn); if (downloadBtn) { downloadBtn.action = ($event: MouseEvent) => this._downloadFiles($event, downloadBtn.files); - downloadBtn.disabled = !this._permissionsService.canDownloadFiles(downloadBtn.files); + downloadBtn.disabled = !this._permissionsService.canDownloadFiles(downloadBtn.files, downloadBtn.dossier); } } } diff --git a/apps/red-ui/src/app/services/entity-services/trash.service.ts b/apps/red-ui/src/app/services/entity-services/trash.service.ts index b8dc6ad17..278a26fef 100644 --- a/apps/red-ui/src/app/services/entity-services/trash.service.ts +++ b/apps/red-ui/src/app/services/entity-services/trash.service.ts @@ -73,7 +73,7 @@ export class TrashService extends GenericService { this._permissionsService.canDeleteDossier(dossier), ), ), - switchMap(dossiers => this._dossierStatsService.getFor(dossiers.map(d => d.id) as string[]).pipe(map(() => dossiers))), + switchMap(dossiers => this._dossierStatsService.getFor(dossiers.map(d => d.id)).pipe(map(() => dossiers))), ); } @@ -82,12 +82,12 @@ export class TrashService extends GenericService { map(res => flatMap(Object.values(res))), mapEach(file => new File(file, this._userService.getNameForId(file.assignee), this._activeDossiersService.routerPath)), mapEach(file => { - const dossierTemplateId = this._activeDossiersService.find(file.dossierId).dossierTemplateId; + const dossier = this._activeDossiersService.find(file.dossierId); return new TrashFile( file, - dossierTemplateId, + dossier.dossierTemplateId, this._configService.values.DELETE_RETENTION_HOURS as number, - this._permissionsService.canDeleteFile(file), + this._permissionsService.canDeleteFile(file, dossier), ); }), ); diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index 95c65130c..a113be62a 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -42,8 +42,7 @@ export class PermissionsService { return dossier.isActive; } - canEditFileAttributes(file: File): boolean { - const dossier = this._getDossier(file); + canEditFileAttributes(file: File, dossier: Dossier): boolean { return ( this._isActive(file) && (((file.isUnderReview || file.isNew) && this.isDossierMember(dossier)) || (file.isUnderApproval && this.isApprover(dossier))) @@ -78,9 +77,8 @@ export class PermissionsService { return file.assignee === this._userService.currentUser.id; } - canDeleteFile(file: File | File[]): boolean { + canDeleteFile(file: File | File[], dossier: Dossier): boolean { const files = file instanceof File ? [file] : file; - const dossier = this._getDossier(files[0]); return files.reduce((acc, _file) => this._canDeleteFile(_file, dossier) && acc, true); } @@ -88,27 +86,23 @@ export class PermissionsService { return dossier.isActive; } - canOcrFile(file: File | File[]): boolean { + canOcrFile(file: File | File[], dossier: Dossier): boolean { const files = file instanceof File ? [file] : file; - const dossier = this._getDossier(files[0]); return files.reduce((acc, _file) => this._canOcrFile(_file, dossier) && acc, true); } - canAssignToSelf(file: File | File[]): boolean { + canAssignToSelf(file: File | File[], dossier: Dossier): boolean { const files = file instanceof File ? [file] : file; - const dossier = this._getDossier(files[0]); return files.reduce((acc, _file) => this._canAssignToSelf(_file, dossier) && acc, true); } - canAssignUser(file: File | File[]): boolean { + canAssignUser(file: File | File[], dossier: Dossier): boolean { const files = file instanceof File ? [file] : file; - const dossier = this._getDossier(files[0]); return files.reduce((acc, _file) => this._canAssignUser(_file, dossier) && acc, true); } - canUnassignUser(file: File | File[]): boolean { + canUnassignUser(file: File | File[], dossier: Dossier): boolean { const files = file instanceof File ? [file] : file; - const dossier = this._getDossier(files[0]); return files.reduce((acc, _file) => this._canUnassignUser(_file, dossier) && acc, true); } @@ -117,9 +111,8 @@ export class PermissionsService { return files.reduce((acc, _file) => this._canSetToNew(_file) && acc, true); } - canSetUnderReview(file: File | File[]): boolean { + canSetUnderReview(file: File | File[], dossier: Dossier): boolean { const files = file instanceof File ? [file] : file; - const dossier = this._getDossier(files[0]); return this.isApprover(dossier) && files.reduce((acc, _file) => this._canSetUnderReview(_file) && acc, true); } @@ -128,8 +121,8 @@ export class PermissionsService { return files.reduce((acc, _file) => this._canBeApproved(_file) && acc, true); } - isReadyForApproval(files: File | File[]): boolean { - return this.canSetUnderReview(files); + isReadyForApproval(files: File | File[], dossier: Dossier): boolean { + return this.canSetUnderReview(files, dossier); } canSetUnderApproval(file: File | File[], dossier: Dossier): boolean { @@ -149,20 +142,18 @@ export class PermissionsService { return dossier.memberIds.includes(user.id); } - // TODO: Remove '?', after we make sure file is loaded before page canPerformAnnotationActions(file: File): boolean { return ( this._isActive(file) && !file.isOcrProcessing && !file.excluded && - (file?.isUnderReview || file?.isUnderApproval) && + (file.isUnderReview || file.isUnderApproval) && this.isFileAssignee(file) ); } - canUndoApproval(file: File | File[]): boolean { + canUndoApproval(file: File | File[], dossier: Dossier): boolean { const files = file instanceof File ? [file] : file; - const dossier = this._getDossier(files[0]); return files.reduce((acc, _file) => this._canUndoApproval(_file, dossier) && acc, true); } @@ -170,11 +161,10 @@ export class PermissionsService { return (file.isUnderReview || file.isUnderApproval) && this.isFileAssignee(file); } - canDownloadFiles(files: File[]): boolean { + canDownloadFiles(files: File[], dossier: Dossier): boolean { if (files.length === 0) { return false; } - const dossier = this._getDossier(files[0]); return this.isApprover(dossier) && files.reduce((prev, file) => prev && file.isApproved, true); } diff --git a/libs/red-domain/src/lib/shared/expandable-file-actions.ts b/libs/red-domain/src/lib/shared/expandable-file-actions.ts index 3fd17d5e8..c599d9fef 100644 --- a/libs/red-domain/src/lib/shared/expandable-file-actions.ts +++ b/libs/red-domain/src/lib/shared/expandable-file-actions.ts @@ -1,6 +1,7 @@ import { Observable } from 'rxjs'; import { CircleButtonType } from '@iqser/common-ui'; import { File } from '../files'; +import { Dossier } from '../dossiers'; export type ActionType = 'circleBtn' | 'downloadBtn' | 'toggle'; @@ -23,6 +24,7 @@ export interface Action { checked?: boolean; class?: { [key: string]: boolean }; files?: File[]; + dossier?: Dossier; type: ActionType; readonly helpModeKey?: string; }