File bulk actions service, permissions for multiple files, workflow done
This commit is contained in:
parent
a660f3e3af
commit
02da8e5a02
@ -66,7 +66,7 @@ export class AssignReviewerApproverDialogComponent {
|
||||
}
|
||||
|
||||
private get _canUnassignFiles() {
|
||||
return this.data.files.reduce((prev, file) => prev && this.permissionsService.canUnassignUser(file), true);
|
||||
return this.permissionsService.canUnassignUser(this.data.files);
|
||||
}
|
||||
|
||||
/** Initialize the form with:
|
||||
|
||||
@ -1,15 +1,11 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { Action, ActionTypes, Dossier, File } from '@red/domain';
|
||||
import { FileAssignService } from '../../../../shared/services/file-assign.service';
|
||||
import { DossiersDialogService } from '../../../../services/dossiers-dialog.service';
|
||||
import { CircleButtonType, CircleButtonTypes, ConfirmationDialogInput, LoadingService, Required } from '@iqser/common-ui';
|
||||
import { CircleButtonType, CircleButtonTypes, Required } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { LongPressEvent } from '@shared/directives/long-press.directive';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { FileManagementService } from '@services/entity-services/file-management.service';
|
||||
import { ReanalysisService } from '@services/reanalysis.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { BulkActionsService } from '../../services/bulk-actions.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-overview-bulk-actions',
|
||||
@ -40,49 +36,44 @@ export class DossierOverviewBulkActionsComponent implements OnChanges {
|
||||
private _canMoveToSameState: boolean;
|
||||
|
||||
constructor(
|
||||
private readonly _dialogService: DossiersDialogService,
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
private readonly _reanalysisService: ReanalysisService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _fileAssignService: FileAssignService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _bulkActionsService: BulkActionsService,
|
||||
) {}
|
||||
|
||||
private get _buttons(): Action[] {
|
||||
return [
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._delete(),
|
||||
action: () => this._bulkActionsService.delete(this.selectedFiles),
|
||||
tooltip: _('dossier-overview.bulk.delete'),
|
||||
icon: 'iqser:trash',
|
||||
show: this.canDelete,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._assign(),
|
||||
action: () => this._bulkActionsService.assign(this.selectedFiles),
|
||||
tooltip: this.assignTooltip,
|
||||
icon: 'red:assign',
|
||||
show: this.canAssign,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._assignToMe(),
|
||||
action: () => this._bulkActionsService.assignToMe(this.selectedFiles),
|
||||
tooltip: _('dossier-overview.assign-me'),
|
||||
icon: 'red:assign-me',
|
||||
show: this.canAssignToSelf,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._setToUnderApproval(),
|
||||
action: () => this._bulkActionsService.setToUnderApproval(this.selectedFiles),
|
||||
tooltip: _('dossier-overview.under-approval'),
|
||||
icon: 'red:ready-for-approval',
|
||||
show: this.canSetToUnderApproval,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._setToUnderReview(),
|
||||
action: () => this._bulkActionsService.backToUnderReview(this.selectedFiles),
|
||||
tooltip: _('dossier-overview.under-review'),
|
||||
icon: 'red:undo',
|
||||
show: this.canSetToUnderReview,
|
||||
@ -94,7 +85,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges {
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._approveDocuments(),
|
||||
action: () => this._bulkActionsService.approve(this.selectedFiles),
|
||||
disabled: !this.canApprove,
|
||||
tooltip: this.canApprove ? _('dossier-overview.approve') : _('dossier-overview.approve-disabled'),
|
||||
icon: 'red:approved',
|
||||
@ -102,21 +93,21 @@ export class DossierOverviewBulkActionsComponent implements OnChanges {
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._setToUnderApproval(),
|
||||
action: () => this._bulkActionsService.setToUnderApproval(this.selectedFiles),
|
||||
tooltip: _('dossier-overview.under-approval'),
|
||||
icon: 'red:undo',
|
||||
show: this.canUndoApproval,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._ocr(),
|
||||
action: () => this._bulkActionsService.ocr(this.selectedFiles),
|
||||
tooltip: _('dossier-overview.ocr-file'),
|
||||
icon: 'iqser:ocr',
|
||||
show: this.canOcr,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: () => this._reanalyse(),
|
||||
action: () => this._bulkActionsService.reanalyse(this.selectedFiles),
|
||||
tooltip: _('dossier-overview.bulk.reanalyse'),
|
||||
icon: 'iqser:refresh',
|
||||
show: this.canReanalyse && this.analysisForced,
|
||||
@ -133,159 +124,42 @@ export class DossierOverviewBulkActionsComponent implements OnChanges {
|
||||
this._setup();
|
||||
}
|
||||
|
||||
private _delete() {
|
||||
this._dialogService.openDialog(
|
||||
'confirm',
|
||||
null,
|
||||
new ConfirmationDialogInput({
|
||||
title: _('confirmation-dialog.delete-file.title'),
|
||||
question: _('confirmation-dialog.delete-file.question'),
|
||||
}),
|
||||
async () => {
|
||||
this._loadingService.start();
|
||||
await this._fileManagementService
|
||||
.delete(
|
||||
this.selectedFiles.map(item => item.fileId),
|
||||
this.dossier.dossierId,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
private async _setToUnderApproval() {
|
||||
// If more than 1 approver - show dialog and ask who to assign
|
||||
if (this.dossier.approverIds.length > 1) {
|
||||
this._assignFiles('approver', true);
|
||||
} else {
|
||||
this._loadingService.start();
|
||||
await this._filesService
|
||||
.setUnderApprovalFor(
|
||||
this.selectedFiles.map(f => f.id),
|
||||
this.dossier.id,
|
||||
this.dossier.approverIds[0],
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private async _reanalyse() {
|
||||
this._loadingService.start();
|
||||
const fileIds = this.selectedFiles.filter(file => file.analysisRequired).map(file => file.fileId);
|
||||
await this._reanalysisService.reanalyzeFilesForDossier(fileIds, this.dossier.id).toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
private async _ocr() {
|
||||
this._loadingService.start();
|
||||
await this._reanalysisService
|
||||
.ocrFiles(
|
||||
this.selectedFiles.map(f => f.fileId),
|
||||
this.dossier.id,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
private async _setToUnderReview() {
|
||||
this._loadingService.start();
|
||||
await this._filesService
|
||||
.setUnderReviewFor(
|
||||
this.selectedFiles.map(f => f.id),
|
||||
this.dossier.id,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
private async _approveDocuments(): Promise<void> {
|
||||
const foundUpdatedFile = this.selectedFiles.find(file => file.hasUpdates);
|
||||
if (foundUpdatedFile) {
|
||||
this._dialogService.openDialog(
|
||||
'confirm',
|
||||
null,
|
||||
new ConfirmationDialogInput({
|
||||
title: _('confirmation-dialog.approve-multiple-files.title'),
|
||||
question: _('confirmation-dialog.approve-multiple-files.question'),
|
||||
}),
|
||||
async () => {
|
||||
this._loadingService.start();
|
||||
await this._filesService
|
||||
.setApprovedFor(
|
||||
this.selectedFiles.map(f => f.id),
|
||||
this.dossier.id,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
this._loadingService.start();
|
||||
await this._filesService
|
||||
.setApprovedFor(
|
||||
this.selectedFiles.map(f => f.id),
|
||||
this.dossier.id,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private async _assignToMe() {
|
||||
await this._fileAssignService.assignToMe(this.selectedFiles);
|
||||
}
|
||||
|
||||
private _assign() {
|
||||
const mode = this.selectedFiles[0].isUnderApproval ? 'approver' : 'reviewer';
|
||||
this._assignFiles(mode);
|
||||
}
|
||||
|
||||
private _setup() {
|
||||
const allFilesAreUnderReviewOrUnassigned = this.selectedFiles.reduce(
|
||||
(acc, file) => acc && (file.isUnderReview || file.isNew),
|
||||
true,
|
||||
);
|
||||
const allFilesAreUnderApproval = this.selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true);
|
||||
this._canMoveToSameState = allFilesAreUnderReviewOrUnassigned || allFilesAreUnderApproval;
|
||||
|
||||
this.canAssign =
|
||||
this._canMoveToSameState &&
|
||||
this.selectedFiles.reduce(
|
||||
(acc, file) => (acc && this._permissionsService.canAssignUser(file)) || this._permissionsService.canUnassignUser(file),
|
||||
if (this.selectedFiles.length) {
|
||||
const allFilesAreUnderReviewOrUnassigned = this.selectedFiles.reduce(
|
||||
(acc, file) => acc && (file.isUnderReview || file.isNew),
|
||||
true,
|
||||
);
|
||||
this.canAssignToSelf =
|
||||
this._canMoveToSameState &&
|
||||
this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignToSelf(file), true);
|
||||
const allFilesAreUnderApproval = this.selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true);
|
||||
this._canMoveToSameState = allFilesAreUnderReviewOrUnassigned || allFilesAreUnderApproval;
|
||||
|
||||
this.canDelete = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canDeleteFile(file), true);
|
||||
this.canAssign =
|
||||
this._canMoveToSameState &&
|
||||
this.selectedFiles.reduce(
|
||||
(acc, file) => (acc && this._permissionsService.canAssignUser(file)) || this._permissionsService.canUnassignUser(file),
|
||||
true,
|
||||
);
|
||||
this.canAssignToSelf = this._canMoveToSameState && this._permissionsService.canAssignToSelf(this.selectedFiles);
|
||||
|
||||
this.canReanalyse = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canReanalyseFile(file), true);
|
||||
this.canDelete = this._permissionsService.canDeleteFile(this.selectedFiles);
|
||||
|
||||
this.canOcr = this.selectedFiles.reduce((acc, file) => acc && file.canBeOCRed, true);
|
||||
this.canReanalyse = this._permissionsService.canReanalyseFile(this.selectedFiles);
|
||||
|
||||
this.canSetToUnderReview = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderReview(file), true);
|
||||
this.canOcr = this.selectedFiles.reduce((acc, file) => acc && file.canBeOCRed, true);
|
||||
|
||||
this.canSetToUnderApproval = this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canSetUnderApproval(file),
|
||||
true,
|
||||
);
|
||||
this.canSetToUnderReview = this._permissionsService.canSetUnderReview(this.selectedFiles);
|
||||
|
||||
this.isReadyForApproval = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.isReadyForApproval(file), true);
|
||||
this.canSetToUnderApproval = this._permissionsService.canSetUnderApproval(this.selectedFiles);
|
||||
|
||||
this.canApprove = this.selectedFiles.reduce((acc, file) => acc && file.canBeApproved, true);
|
||||
this.isReadyForApproval = this._permissionsService.isReadyForApproval(this.selectedFiles);
|
||||
|
||||
this.canUndoApproval = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canUndoApproval(file), true);
|
||||
this.canApprove = this._permissionsService.canBeApproved(this.selectedFiles);
|
||||
|
||||
this.assignTooltip = allFilesAreUnderApproval ? _('dossier-overview.assign-approver') : _('dossier-overview.assign-reviewer');
|
||||
this.canUndoApproval = this._permissionsService.canUndoApproval(this.selectedFiles);
|
||||
|
||||
this.buttons = this._buttons;
|
||||
}
|
||||
this.assignTooltip = allFilesAreUnderApproval ? _('dossier-overview.assign-approver') : _('dossier-overview.assign-reviewer');
|
||||
|
||||
private _assignFiles(mode: 'reviewer' | 'approver', ignoreChanged = false) {
|
||||
const data = { mode, files: this.selectedFiles, ignoreChanged };
|
||||
this._dialogService.openDialog('assignFile', null, data);
|
||||
this.buttons = this._buttons;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,14 +7,12 @@ import {
|
||||
List,
|
||||
ListingMode,
|
||||
ListingModes,
|
||||
LoadingService,
|
||||
NestedFilter,
|
||||
TableColumnConfig,
|
||||
WorkflowConfig,
|
||||
} from '@iqser/common-ui';
|
||||
import { File, IFileAttributeConfig, StatusSorter, WorkflowFileStatus, WorkflowFileStatuses } from '@red/domain';
|
||||
import { workflowFileStatusTranslations } from '../../translations/file-status-translations';
|
||||
import { FileAssignService } from '../../shared/services/file-assign.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
@ -24,26 +22,22 @@ import { annotationFilterChecker, RedactionFilterSorter } from '@utils/index';
|
||||
import { workloadTranslations } from '../../translations/workload-translations';
|
||||
import * as moment from 'moment';
|
||||
import { ConfigService as AppConfigService } from '@services/config.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { noop } from 'lodash';
|
||||
import noop from 'lodash/noop';
|
||||
import { BulkActionsService } from './services/bulk-actions.service';
|
||||
|
||||
@Injectable()
|
||||
export class ConfigService {
|
||||
readonly listingMode$: Observable<ListingMode>;
|
||||
private readonly _listingMode$ = new BehaviorSubject<ListingMode>(ListingModes.workflow);
|
||||
private readonly _listingMode$ = new BehaviorSubject<ListingMode>(ListingModes.table);
|
||||
|
||||
constructor(
|
||||
private readonly _fileAssignService: FileAssignService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _dialogService: DossiersDialogService,
|
||||
private readonly _appConfigService: AppConfigService,
|
||||
private readonly _bulkActionsService: BulkActionsService,
|
||||
) {
|
||||
this.listingMode$ = this._listingMode$.asObservable();
|
||||
}
|
||||
@ -71,28 +65,35 @@ export class ConfigService {
|
||||
},
|
||||
{
|
||||
label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_REVIEW],
|
||||
enterFn: this._underReviewFn,
|
||||
enterPredicate: (file: File) =>
|
||||
this._permissionsService.canSetUnderReview(file) ||
|
||||
this._permissionsService.canAssignToSelf(file) ||
|
||||
this._permissionsService.canAssignUser(file),
|
||||
enterFn: async (files: File[]) => {
|
||||
if (files[0].workflowStatus === WorkflowFileStatuses.UNDER_APPROVAL) {
|
||||
await this._bulkActionsService.backToUnderReview(files);
|
||||
} else {
|
||||
await this._bulkActionsService.assignToMe(files);
|
||||
}
|
||||
},
|
||||
enterPredicate: (files: File[]) =>
|
||||
this._permissionsService.canSetUnderReview(files) ||
|
||||
this._permissionsService.canAssignToSelf(files) ||
|
||||
this._permissionsService.canAssignUser(files),
|
||||
key: WorkflowFileStatuses.UNDER_REVIEW,
|
||||
color: '#FDBD00',
|
||||
entities: new BehaviorSubject([]),
|
||||
},
|
||||
{
|
||||
label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_APPROVAL],
|
||||
enterFn: this._underApprovalFn,
|
||||
enterPredicate: (file: File) =>
|
||||
this._permissionsService.canSetUnderApproval(file) || this._permissionsService.canUndoApproval(file),
|
||||
enterFn: (files: File[]) => this._bulkActionsService.setToUnderApproval(files),
|
||||
enterPredicate: (files: File[]) =>
|
||||
this._permissionsService.canSetUnderApproval(files) || this._permissionsService.canUndoApproval(files),
|
||||
key: WorkflowFileStatuses.UNDER_APPROVAL,
|
||||
color: '#374C81',
|
||||
entities: new BehaviorSubject([]),
|
||||
},
|
||||
{
|
||||
label: workflowFileStatusTranslations[WorkflowFileStatuses.APPROVED],
|
||||
enterFn: this._approveFn,
|
||||
enterPredicate: (file: File) => this._permissionsService.isReadyForApproval(file) && file.canBeApproved,
|
||||
enterFn: (files: File[]) => this._bulkActionsService.approve(files),
|
||||
enterPredicate: (files: File[]) =>
|
||||
this._permissionsService.isReadyForApproval(files) && this._permissionsService.canBeApproved(files),
|
||||
key: WorkflowFileStatuses.APPROVED,
|
||||
color: '#48C9F7',
|
||||
entities: new BehaviorSubject([]),
|
||||
@ -366,25 +367,4 @@ export class ConfigService {
|
||||
private _openEditDossierDialog($event: MouseEvent, dossierId: string) {
|
||||
this._dialogService.openDialog('editDossier', $event, { dossierId });
|
||||
}
|
||||
|
||||
private _underReviewFn = async (file: File) => {
|
||||
await this._fileAssignService.assignReviewer(null, file, true);
|
||||
};
|
||||
|
||||
private _underApprovalFn = async (file: File) => {
|
||||
const dossier = this._dossiersService.find(file.dossierId);
|
||||
if (dossier.approverIds.length > 1) {
|
||||
await this._fileAssignService.assignApprover(null, file, true);
|
||||
} else {
|
||||
this._loadingService.start();
|
||||
await this._filesService.setUnderApprovalFor([file.id], dossier.dossierId, dossier.approverIds[0]).toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
};
|
||||
|
||||
private _approveFn = async (file: File) => {
|
||||
this._loadingService.start();
|
||||
await this._filesService.setApprovedFor([file.id], file.dossierId).toPromise();
|
||||
this._loadingService.stop();
|
||||
};
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ import { ScreenHeaderComponent } from './components/screen-header/screen-header.
|
||||
import { ViewModeSelectionComponent } from './components/view-mode-selection/view-mode-selection.component';
|
||||
import { FileNameColumnComponent } from './components/table-item/file-name-column/file-name-column.component';
|
||||
import { AddedColumnComponent } from './components/table-item/added-column/added-column.component';
|
||||
import { BulkActionsService } from './services/bulk-actions.service';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -45,7 +46,7 @@ const routes: Routes = [
|
||||
FileNameColumnComponent,
|
||||
AddedColumnComponent,
|
||||
],
|
||||
providers: [ConfigService],
|
||||
providers: [ConfigService, BulkActionsService],
|
||||
imports: [RouterModule.forChild(routes), CommonModule, SharedModule, SharedDossiersModule, IqserIconsModule, TranslateModule],
|
||||
})
|
||||
export class DossierOverviewModule {}
|
||||
|
||||
@ -0,0 +1,140 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Dossier, File } from '@red/domain';
|
||||
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
|
||||
import { ConfirmationDialogInput, LoadingService } from '@iqser/common-ui';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { FileAssignService } from '../../../shared/services/file-assign.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { ReanalysisService } from '../../../../../services/reanalysis.service';
|
||||
import { FileManagementService } from '@services/entity-services/file-management.service';
|
||||
|
||||
@Injectable()
|
||||
export class BulkActionsService {
|
||||
constructor(
|
||||
private readonly _dialogService: DossiersDialogService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _fileAssignService: FileAssignService,
|
||||
private readonly _reanalysisService: ReanalysisService,
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
) {}
|
||||
|
||||
async setToUnderApproval(files: File[]) {
|
||||
const dossier = this._getDossier(files);
|
||||
// If more than 1 approver - show dialog and ask who to assign
|
||||
if (dossier.approverIds.length > 1) {
|
||||
this._assignFiles(files, 'approver', true);
|
||||
} else {
|
||||
this._loadingService.start();
|
||||
await this._filesService
|
||||
.setUnderApprovalFor(
|
||||
files.map(f => f.id),
|
||||
dossier.id,
|
||||
dossier.approverIds[0],
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
|
||||
async assignToMe(files: File[]) {
|
||||
await this._fileAssignService.assignToMe(files);
|
||||
}
|
||||
|
||||
async ocr(files: File[]) {
|
||||
this._loadingService.start();
|
||||
await this._reanalysisService
|
||||
.ocrFiles(
|
||||
files.map(f => f.fileId),
|
||||
files[0].dossierId,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
delete(files: File[]) {
|
||||
this._dialogService.openDialog(
|
||||
'confirm',
|
||||
null,
|
||||
new ConfirmationDialogInput({
|
||||
title: _('confirmation-dialog.delete-file.title'),
|
||||
question: _('confirmation-dialog.delete-file.question'),
|
||||
}),
|
||||
async () => {
|
||||
this._loadingService.start();
|
||||
await this._fileManagementService
|
||||
.delete(
|
||||
files.map(item => item.fileId),
|
||||
files[0].dossierId,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async reanalyse(files: File[]) {
|
||||
this._loadingService.start();
|
||||
const fileIds = files.filter(file => file.analysisRequired).map(file => file.fileId);
|
||||
await this._reanalysisService.reanalyzeFilesForDossier(fileIds, files[0].dossierId).toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
async backToUnderReview(files: File[]): Promise<void> {
|
||||
this._loadingService.start();
|
||||
await this._filesService
|
||||
.setUnderReviewFor(
|
||||
files.map(f => f.id),
|
||||
files[0].dossierId,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
async approve(files: File[]): Promise<void> {
|
||||
const foundUpdatedFile = files.find(file => file.hasUpdates);
|
||||
if (foundUpdatedFile) {
|
||||
this._dialogService.openDialog(
|
||||
'confirm',
|
||||
null,
|
||||
new ConfirmationDialogInput({
|
||||
title: _('confirmation-dialog.approve-multiple-files.title'),
|
||||
question: _('confirmation-dialog.approve-multiple-files.question'),
|
||||
}),
|
||||
async () => {
|
||||
this._loadingService.start();
|
||||
await this._filesService
|
||||
.setApprovedFor(
|
||||
files.map(f => f.id),
|
||||
files[0].dossierId,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
this._loadingService.start();
|
||||
await this._filesService
|
||||
.setApprovedFor(
|
||||
files.map(f => f.id),
|
||||
files[0].dossierId,
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
|
||||
assign(files: File[], mode: 'reviewer' | 'approver' = files[0].isUnderApproval ? 'approver' : 'reviewer') {
|
||||
this._assignFiles(files, mode);
|
||||
}
|
||||
|
||||
private _getDossier(files: File[]): Dossier {
|
||||
return this._dossiersService.find(files[0].dossierId);
|
||||
}
|
||||
|
||||
private _assignFiles(files: File[], mode: 'reviewer' | 'approver', ignoreChanged = false) {
|
||||
this._dialogService.openDialog('assignFile', null, { mode, files, ignoreChanged });
|
||||
}
|
||||
}
|
||||
@ -68,9 +68,9 @@ export class UserManagementComponent implements OnChanges {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.canAssignToSelf = this.permissionsService.canAssignToSelf(this.file, this.dossier);
|
||||
this.canAssignUser = this.permissionsService.canAssignUser(this.file, this.dossier);
|
||||
this.canUnassignUser = this.permissionsService.canUnassignUser(this.file, this.dossier);
|
||||
this.canAssignToSelf = this.permissionsService.canAssignToSelf(this.file);
|
||||
this.canAssignUser = this.permissionsService.canAssignUser(this.file);
|
||||
this.canUnassignUser = this.permissionsService.canUnassignUser(this.file);
|
||||
this.canAssignOrUnassign = this.canAssignUser || this.canUnassignUser;
|
||||
this.canAssign = this.canAssignToSelf || this.canAssignOrUnassign;
|
||||
|
||||
|
||||
@ -22,58 +22,57 @@ export class PermissionsService {
|
||||
return this.isReviewerOrApprover(file) && (file.isNew || file.isUnderReview || file.isUnderApproval);
|
||||
}
|
||||
|
||||
canReanalyseFile(file: File): boolean {
|
||||
return this.isReviewerOrApprover(file) || file.isNew || (file.isError && file.isNew);
|
||||
canReanalyseFile(file: File | File[]): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return files.reduce((acc, _file) => this._canReanalyseFile(_file) && acc, true);
|
||||
}
|
||||
|
||||
isFileAssignee(file: File): boolean {
|
||||
return file.assignee === this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
// https://jira.iqser.com/browse/RED-2787
|
||||
canDeleteFile(file: File): boolean {
|
||||
const dossier = this._getDossier(file);
|
||||
return (
|
||||
file.isNew ||
|
||||
(file.isUnderReview && !file.assignee && this.isDossierMember(dossier)) ||
|
||||
(file.isUnderApproval && !file.assignee && this.isApprover(dossier)) ||
|
||||
(file.assignee && !file.isApproved && (this.isFileAssignee(file) || this.isOwner(dossier)))
|
||||
);
|
||||
canDeleteFile(file: File | File[]): 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);
|
||||
}
|
||||
|
||||
canAssignToSelf(file: File, dossier = this._getDossier(file)): boolean {
|
||||
const precondition = this.isDossierMember(dossier) && !this.isFileAssignee(file) && !file.isError && !file.isProcessing;
|
||||
return precondition && (file.isNew || file.isUnderReview || (file.isUnderApproval && this.isApprover(dossier)));
|
||||
canAssignToSelf(file: File | File[]): 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, dossier = this._getDossier(file)): boolean {
|
||||
const precondition = !file.isProcessing && !file.isError && !file.isApproved && this.isApprover(dossier);
|
||||
|
||||
if (precondition) {
|
||||
if ((file.isNew || file.isUnderReview) && dossier.hasReviewers) {
|
||||
return true;
|
||||
}
|
||||
if (file.isUnderApproval && dossier.approverIds.length > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
canAssignUser(file: File | File[]): 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, dossier = this._getDossier(file)): boolean {
|
||||
return (file.isUnderReview || file.isUnderApproval) && (this.isFileAssignee(file) || this.isApprover(dossier));
|
||||
canUnassignUser(file: File | File[]): 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);
|
||||
}
|
||||
|
||||
canSetUnderReview(file: File, dossier = this._getDossier(file)): boolean {
|
||||
return file.isUnderApproval && this.isApprover(dossier);
|
||||
canSetUnderReview(file: File | File[]): 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);
|
||||
}
|
||||
|
||||
isReadyForApproval(file: File): boolean {
|
||||
return this.canSetUnderReview(file);
|
||||
canBeApproved(file: File | File[]): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return files.reduce((acc, _file) => this._canBeApproved(_file) && acc, true);
|
||||
}
|
||||
|
||||
canSetUnderApproval(file: File): boolean {
|
||||
return file.isUnderReview && this.isReviewerOrApprover(file);
|
||||
isReadyForApproval(files: File | File[]): boolean {
|
||||
return this.canSetUnderReview(files);
|
||||
}
|
||||
|
||||
canSetUnderApproval(file: File | File[]): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return files.reduce((acc, _file) => this._canSetUnderApproval(_file) && acc, true);
|
||||
}
|
||||
|
||||
isOwner(dossier: Dossier, user = this._userService.currentUser): boolean {
|
||||
@ -97,8 +96,10 @@ export class PermissionsService {
|
||||
return (file?.isUnderReview || file?.isUnderApproval) && this.isFileAssignee(file);
|
||||
}
|
||||
|
||||
canUndoApproval(file: File): boolean {
|
||||
return file.isApproved && this.isApprover(this._getDossier(file));
|
||||
canUndoApproval(file: File | File[]): 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);
|
||||
}
|
||||
|
||||
canMarkPagesAsViewed(file: File): boolean {
|
||||
@ -135,6 +136,59 @@ export class PermissionsService {
|
||||
return (comment.user === this._userService.currentUser.id || this.isApprover(dossier)) && !file.isApproved;
|
||||
}
|
||||
|
||||
// https://jira.iqser.com/browse/RED-2787
|
||||
private _canDeleteFile(file: File, dossier: Dossier): boolean {
|
||||
return (
|
||||
file.isNew ||
|
||||
(file.isUnderReview && !file.assignee && this.isDossierMember(dossier)) ||
|
||||
(file.isUnderApproval && !file.assignee && this.isApprover(dossier)) ||
|
||||
(file.assignee && !file.isApproved && (this.isFileAssignee(file) || this.isOwner(dossier)))
|
||||
);
|
||||
}
|
||||
|
||||
private _canReanalyseFile(file: File): boolean {
|
||||
return this.isReviewerOrApprover(file) || file.isNew || (file.isError && file.isNew);
|
||||
}
|
||||
|
||||
private _canAssignToSelf(file: File, dossier: Dossier): boolean {
|
||||
const precondition = this.isDossierMember(dossier) && !this.isFileAssignee(file) && !file.isError && !file.isProcessing;
|
||||
return precondition && (file.isNew || file.isUnderReview || (file.isUnderApproval && this.isApprover(dossier)));
|
||||
}
|
||||
|
||||
private _canSetUnderApproval(file: File): boolean {
|
||||
return file.isUnderReview && this.isReviewerOrApprover(file);
|
||||
}
|
||||
|
||||
private _canUndoApproval(file: File, dossier: Dossier): boolean {
|
||||
return file.isApproved && this.isApprover(dossier);
|
||||
}
|
||||
|
||||
private _canBeApproved(file: File): boolean {
|
||||
return file.canBeApproved;
|
||||
}
|
||||
|
||||
private _canAssignUser(file: File, dossier: Dossier) {
|
||||
const precondition = !file.isProcessing && !file.isError && !file.isApproved && this.isApprover(dossier);
|
||||
|
||||
if (precondition) {
|
||||
if ((file.isNew || file.isUnderReview) && dossier.hasReviewers) {
|
||||
return true;
|
||||
}
|
||||
if (file.isUnderApproval && dossier.approverIds.length > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private _canUnassignUser(file: File, dossier: Dossier) {
|
||||
return (file.isUnderReview || file.isUnderApproval) && (this.isFileAssignee(file) || this.isApprover(dossier));
|
||||
}
|
||||
|
||||
private _canSetUnderReview(file: File): boolean {
|
||||
return file.isUnderApproval;
|
||||
}
|
||||
|
||||
private _getDossier(file: File): Dossier {
|
||||
return this._dossiersService.find(file.dossierId);
|
||||
}
|
||||
|
||||
@ -45,8 +45,8 @@ export class ReanalysisService extends GenericService<unknown> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
ocrFiles(@RequiredParam() body: List, @RequiredParam() dossierId: string) {
|
||||
return this._post(body, `ocr/reanalyze/${dossierId}/bulk`).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
ocrFiles(@RequiredParam() fileIds: List, @RequiredParam() dossierId: string) {
|
||||
return this._post(fileIds, `ocr/reanalyze/${dossierId}/bulk`).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 567de98f30d622c6bbc9a47d87a784c7aa36055f
|
||||
Subproject commit 28a6b735f700351f36c2583de4b581fe5fb8106b
|
||||
Loading…
x
Reference in New Issue
Block a user