DM-311 simple workflow
This commit is contained in:
parent
e4c355cb0a
commit
2dca5bf3f5
@ -49,11 +49,11 @@ import { Roles } from '@users/roles';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ConfigService {
|
export class ConfigService {
|
||||||
readonly listingMode$: Observable<ListingMode>;
|
|
||||||
readonly #dossierId = getParam(DOSSIER_ID);
|
readonly #dossierId = getParam(DOSSIER_ID);
|
||||||
readonly #currentUser = getCurrentUser<User>();
|
readonly #currentUser = getCurrentUser<User>();
|
||||||
readonly #config = getConfig<AppConfig>();
|
readonly #config = getConfig<AppConfig>();
|
||||||
readonly #listingMode$: BehaviorSubject<ListingMode>;
|
readonly #listingMode$: BehaviorSubject<ListingMode>;
|
||||||
|
readonly listingMode$: Observable<ListingMode>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _permissionsService: PermissionsService,
|
private readonly _permissionsService: PermissionsService,
|
||||||
@ -87,63 +87,10 @@ export class ConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
workflowConfig(): WorkflowConfig<File, WorkflowFileStatus> {
|
workflowConfig(): WorkflowConfig<File, WorkflowFileStatus> {
|
||||||
const { NEW, UNDER_REVIEW, UNDER_APPROVAL, APPROVED } = WorkflowFileStatuses;
|
const newColumn = this.#getNewColumn();
|
||||||
|
const underReviewColumn = this.#getUnderReviewColumn();
|
||||||
const newColumn: WorkflowColumn<File, typeof NEW> = {
|
const underApprovalColumn = this.#getUnderApprovalColumn();
|
||||||
label: workflowFileStatusTranslations[NEW],
|
const approvedColumn = this.#getApprovedColumn();
|
||||||
key: NEW,
|
|
||||||
enterFn: files => this._bulkActionsService.setToNew(files),
|
|
||||||
enterPredicate: files => this._permissionsService.canSetToNew(files, this.#dossier),
|
|
||||||
color: '#D3D5DA',
|
|
||||||
entities: new BehaviorSubject([]),
|
|
||||||
};
|
|
||||||
|
|
||||||
const underReviewColumn: WorkflowColumn<File, typeof UNDER_REVIEW> = {
|
|
||||||
label: workflowFileStatusTranslations[UNDER_REVIEW],
|
|
||||||
enterFn: async files => {
|
|
||||||
const statuses: WorkflowFileStatus[] = [UNDER_APPROVAL, APPROVED];
|
|
||||||
if (statuses.includes(files[0].workflowStatus)) {
|
|
||||||
await this._bulkActionsService.backToUnderReview(files);
|
|
||||||
} else {
|
|
||||||
await this._bulkActionsService.assignToMe(files);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
enterPredicate: files => {
|
|
||||||
const dossier = this.#dossier;
|
|
||||||
return (
|
|
||||||
this._permissionsService.canSetUnderReview(files, dossier) ||
|
|
||||||
this._permissionsService.canAssignToSelf(files, dossier) ||
|
|
||||||
this._permissionsService.canAssignUser(files, dossier) ||
|
|
||||||
this._permissionsService.canUndoApproval(files, dossier)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
key: UNDER_REVIEW,
|
|
||||||
color: '#FDBD00',
|
|
||||||
entities: new BehaviorSubject([]),
|
|
||||||
};
|
|
||||||
|
|
||||||
const underApprovalColumn: WorkflowColumn<File, typeof UNDER_APPROVAL> = {
|
|
||||||
label: workflowFileStatusTranslations[UNDER_APPROVAL],
|
|
||||||
enterFn: files => this._bulkActionsService.setToUnderApproval(files),
|
|
||||||
enterPredicate: files => {
|
|
||||||
const dossier = this.#dossier;
|
|
||||||
return (
|
|
||||||
this._permissionsService.canSetUnderApproval(files, dossier) || this._permissionsService.canUndoApproval(files, dossier)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
key: UNDER_APPROVAL,
|
|
||||||
color: '#374C81',
|
|
||||||
entities: new BehaviorSubject([]),
|
|
||||||
};
|
|
||||||
|
|
||||||
const approvedColumn: WorkflowColumn<File, typeof APPROVED> = {
|
|
||||||
label: workflowFileStatusTranslations[APPROVED],
|
|
||||||
enterFn: files => this._bulkActionsService.approve(files),
|
|
||||||
enterPredicate: files => this._permissionsService.canBeApproved(files, this.#dossier),
|
|
||||||
key: APPROVED,
|
|
||||||
color: '#48C9F7',
|
|
||||||
entities: new BehaviorSubject([]),
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
columnIdentifierFn: entity => entity.workflowStatus,
|
columnIdentifierFn: entity => entity.workflowStatus,
|
||||||
@ -152,12 +99,24 @@ export class ConfigService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workflowConfigRss(): WorkflowConfig<File, WorkflowFileStatus> {
|
||||||
|
const newColumn = this.#getNewColumn();
|
||||||
|
const underReviewColumn = this.#getUnderReviewColumn();
|
||||||
|
const approvedColumn = this.#getApprovedColumn();
|
||||||
|
|
||||||
|
return {
|
||||||
|
columnIdentifierFn: entity => entity.workflowStatus,
|
||||||
|
itemVersionFn: (entity: File) => `${entity.lastUpdated}-${entity.numberOfAnalyses}`,
|
||||||
|
columns: [newColumn, underReviewColumn, approvedColumn],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
actionConfig(dossierId: string, disabled$: Observable<boolean>): List<ActionConfig> {
|
actionConfig(dossierId: string, disabled$: Observable<boolean>): List<ActionConfig> {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
id: 'editDossier',
|
id: 'editDossier',
|
||||||
label: this._translateService.instant('dossier-overview.header-actions.edit'),
|
label: this._translateService.instant('dossier-overview.header-actions.edit'),
|
||||||
action: () => this._openEditDossierDialog(dossierId),
|
action: () => this.#openEditDossierDialog(dossierId),
|
||||||
icon: 'iqser:edit',
|
icon: 'iqser:edit',
|
||||||
hide: !this.#currentUser.isManager && !this._iqserPermissionsService.has(Roles.dossiers.edit),
|
hide: !this.#currentUser.isManager && !this._iqserPermissionsService.has(Roles.dossiers.edit),
|
||||||
helpModeKey: 'edit_dossier_in_dossier',
|
helpModeKey: 'edit_dossier_in_dossier',
|
||||||
@ -306,7 +265,7 @@ export class ConfigService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._sortByName([...allDistinctPeople]).forEach(userId => {
|
this.#sortByName([...allDistinctPeople]).forEach(userId => {
|
||||||
peopleFilters.push(
|
peopleFilters.push(
|
||||||
new NestedFilter({
|
new NestedFilter({
|
||||||
id: userId,
|
id: userId,
|
||||||
@ -376,7 +335,7 @@ export class ConfigService {
|
|||||||
|
|
||||||
filterGroups.push({
|
filterGroups.push({
|
||||||
slug: 'quickFilters',
|
slug: 'quickFilters',
|
||||||
filters: this._quickFilters(entities),
|
filters: this.#quickFilters(entities),
|
||||||
checker: (file: File) =>
|
checker: (file: File) =>
|
||||||
checkedRequiredFilters().reduce((acc, f) => acc && f.checker(file), true) &&
|
checkedRequiredFilters().reduce((acc, f) => acc && f.checker(file), true) &&
|
||||||
(checkedNotRequiredFilters().length === 0 || checkedNotRequiredFilters().reduce((acc, f) => acc || f.checker(file), false)),
|
(checkedNotRequiredFilters().length === 0 || checkedNotRequiredFilters().reduce((acc, f) => acc || f.checker(file), false)),
|
||||||
@ -410,7 +369,71 @@ export class ConfigService {
|
|||||||
|
|
||||||
_assignedToOthersChecker = (file: File) => file.assignee && file.assignee !== this._userService.currentUser.id;
|
_assignedToOthersChecker = (file: File) => file.assignee && file.assignee !== this._userService.currentUser.id;
|
||||||
|
|
||||||
private _quickFilters(entities: File[]): NestedFilter[] {
|
#getNewColumn(): WorkflowColumn<File, typeof WorkflowFileStatuses.NEW> {
|
||||||
|
return {
|
||||||
|
label: workflowFileStatusTranslations[WorkflowFileStatuses.NEW],
|
||||||
|
key: WorkflowFileStatuses.NEW,
|
||||||
|
enterFn: files => this._bulkActionsService.setToNew(files),
|
||||||
|
enterPredicate: files => this._permissionsService.canSetToNew(files, this.#dossier),
|
||||||
|
color: '#D3D5DA',
|
||||||
|
entities: new BehaviorSubject([]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#getUnderReviewColumn(): WorkflowColumn<File, typeof WorkflowFileStatuses.UNDER_REVIEW> {
|
||||||
|
return {
|
||||||
|
label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_REVIEW],
|
||||||
|
enterFn: async files => {
|
||||||
|
const statuses: WorkflowFileStatus[] = [WorkflowFileStatuses.UNDER_APPROVAL, WorkflowFileStatuses.APPROVED];
|
||||||
|
if (statuses.includes(files[0].workflowStatus)) {
|
||||||
|
await this._bulkActionsService.backToUnderReview(files);
|
||||||
|
} else {
|
||||||
|
await this._bulkActionsService.assignToMe(files);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enterPredicate: files => {
|
||||||
|
const dossier = this.#dossier;
|
||||||
|
return (
|
||||||
|
this._permissionsService.canSetUnderReview(files, dossier) ||
|
||||||
|
this._permissionsService.canAssignToSelf(files, dossier) ||
|
||||||
|
this._permissionsService.canAssignUser(files, dossier) ||
|
||||||
|
this._permissionsService.canUndoApproval(files, dossier)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
key: WorkflowFileStatuses.UNDER_REVIEW,
|
||||||
|
color: '#FDBD00',
|
||||||
|
entities: new BehaviorSubject([]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#getUnderApprovalColumn(): WorkflowColumn<File, typeof WorkflowFileStatuses.UNDER_APPROVAL> {
|
||||||
|
return {
|
||||||
|
label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_APPROVAL],
|
||||||
|
enterFn: files => this._bulkActionsService.setToUnderApproval(files),
|
||||||
|
enterPredicate: files => {
|
||||||
|
const dossier = this.#dossier;
|
||||||
|
return (
|
||||||
|
this._permissionsService.canSetUnderApproval(files, dossier) || this._permissionsService.canUndoApproval(files, dossier)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
key: WorkflowFileStatuses.UNDER_APPROVAL,
|
||||||
|
color: '#374C81',
|
||||||
|
entities: new BehaviorSubject([]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#getApprovedColumn(): WorkflowColumn<File, typeof WorkflowFileStatuses.APPROVED> {
|
||||||
|
return {
|
||||||
|
label: workflowFileStatusTranslations[WorkflowFileStatuses.APPROVED],
|
||||||
|
enterFn: files => this._bulkActionsService.approve(files),
|
||||||
|
enterPredicate: files => this._permissionsService.canBeApproved(files, this.#dossier),
|
||||||
|
key: WorkflowFileStatuses.APPROVED,
|
||||||
|
color: '#48C9F7',
|
||||||
|
entities: new BehaviorSubject([]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#quickFilters(entities: File[]): NestedFilter[] {
|
||||||
const recentPeriod = this.#config.RECENT_PERIOD_IN_HOURS;
|
const recentPeriod = this.#config.RECENT_PERIOD_IN_HOURS;
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -447,11 +470,11 @@ export class ConfigService {
|
|||||||
].map(filter => new NestedFilter(filter));
|
].map(filter => new NestedFilter(filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _openEditDossierDialog(dossierId: string) {
|
#openEditDossierDialog(dossierId: string) {
|
||||||
this._dialogService.openDialog('editDossier', { dossierId });
|
this._dialogService.openDialog('editDossier', { dossierId });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _sortByName(ids: string[]) {
|
#sortByName(ids: string[]) {
|
||||||
return ids.sort((a, b) => this._userService.getName(a).localeCompare(this._userService.getName(b)));
|
return ids.sort((a, b) => this._userService.getName(a).localeCompare(this._userService.getName(b)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import {
|
|||||||
CustomError,
|
CustomError,
|
||||||
ErrorService,
|
ErrorService,
|
||||||
getParam,
|
getParam,
|
||||||
|
IqserPermissionsService,
|
||||||
ListingComponent,
|
ListingComponent,
|
||||||
ListingModes,
|
ListingModes,
|
||||||
listingProvidersFactory,
|
listingProvidersFactory,
|
||||||
@ -44,6 +45,7 @@ import { FilesService } from '@services/files/files.service';
|
|||||||
import { BulkActionsService } from '../services/bulk-actions.service';
|
import { BulkActionsService } from '../services/bulk-actions.service';
|
||||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||||
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
|
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
|
||||||
|
import { Roles } from '@users/roles';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './dossier-overview-screen.component.html',
|
templateUrl: './dossier-overview-screen.component.html',
|
||||||
@ -51,10 +53,15 @@ import { dossiersServiceProvider } from '@services/entity-services/dossiers.serv
|
|||||||
providers: [...listingProvidersFactory(DossierOverviewScreenComponent), ConfigService, BulkActionsService, dossiersServiceProvider],
|
providers: [...listingProvidersFactory(DossierOverviewScreenComponent), ConfigService, BulkActionsService, dossiersServiceProvider],
|
||||||
})
|
})
|
||||||
export class DossierOverviewScreenComponent extends ListingComponent<File> implements OnInit, OnAttach, OnDetach, OnDestroy {
|
export class DossierOverviewScreenComponent extends ListingComponent<File> implements OnInit, OnAttach, OnDetach, OnDestroy {
|
||||||
|
#dossier: Dossier;
|
||||||
|
@ViewChild('needsWorkFilterTemplate', { read: TemplateRef, static: true })
|
||||||
|
private readonly _needsWorkFilterTemplate: TemplateRef<unknown>;
|
||||||
|
@ViewChild('fileInput', { static: true }) private readonly _fileInput: ElementRef;
|
||||||
|
@ViewChild(TableComponent) private readonly _tableComponent: TableComponent<Dossier>;
|
||||||
|
private _fileAttributeConfigs: IFileAttributeConfig[];
|
||||||
readonly listingModes = ListingModes;
|
readonly listingModes = ListingModes;
|
||||||
readonly circleButtonTypes = CircleButtonTypes;
|
readonly circleButtonTypes = CircleButtonTypes;
|
||||||
readonly tableHeaderLabel = _('dossier-overview.table-header.title');
|
readonly tableHeaderLabel = _('dossier-overview.table-header.title');
|
||||||
|
|
||||||
collapsedDetails = false;
|
collapsedDetails = false;
|
||||||
dossierAttributes: DossierAttributeWithValue[] = [];
|
dossierAttributes: DossierAttributeWithValue[] = [];
|
||||||
tableColumnConfigs: readonly TableColumnConfig<File>[];
|
tableColumnConfigs: readonly TableColumnConfig<File>[];
|
||||||
@ -70,18 +77,13 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
|||||||
readonly dossierId = getParam(DOSSIER_ID);
|
readonly dossierId = getParam(DOSSIER_ID);
|
||||||
readonly workflowConfig: WorkflowConfig<File, WorkflowFileStatus>;
|
readonly workflowConfig: WorkflowConfig<File, WorkflowFileStatus>;
|
||||||
readonly dossierAttributes$: Observable<DossierAttributeConfig[]>;
|
readonly dossierAttributes$: Observable<DossierAttributeConfig[]>;
|
||||||
#dossier: Dossier;
|
|
||||||
@ViewChild('needsWorkFilterTemplate', { read: TemplateRef, static: true })
|
|
||||||
private readonly _needsWorkFilterTemplate: TemplateRef<unknown>;
|
|
||||||
@ViewChild('fileInput', { static: true }) private readonly _fileInput: ElementRef;
|
|
||||||
@ViewChild(TableComponent) private readonly _tableComponent: TableComponent<Dossier>;
|
|
||||||
private _fileAttributeConfigs: IFileAttributeConfig[];
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly configService: ConfigService,
|
readonly configService: ConfigService,
|
||||||
private readonly _errorService: ErrorService,
|
private readonly _errorService: ErrorService,
|
||||||
private readonly _filesService: FilesService,
|
private readonly _filesService: FilesService,
|
||||||
readonly permissionsService: PermissionsService,
|
readonly permissionsService: PermissionsService,
|
||||||
|
iqserPermissionsService: IqserPermissionsService,
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _fileMapService: FilesMapService,
|
private readonly _fileMapService: FilesMapService,
|
||||||
private readonly _dossiersService: DossiersService,
|
private readonly _dossiersService: DossiersService,
|
||||||
@ -97,7 +99,8 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
|||||||
this.dossier$ = _dossiersService.getEntityChanged$(this.dossierId).pipe(tap(dossier => (this.#dossier = dossier)));
|
this.dossier$ = _dossiersService.getEntityChanged$(this.dossierId).pipe(tap(dossier => (this.#dossier = dossier)));
|
||||||
this.dossierAttributes$ = this._dossierAttributesService.all$.pipe(tap(() => this.#updateDossierAttributes()));
|
this.dossierAttributes$ = this._dossierAttributesService.all$.pipe(tap(() => this.#updateDossierAttributes()));
|
||||||
this.#dossier = _dossiersService.find(this.dossierId);
|
this.#dossier = _dossiersService.find(this.dossierId);
|
||||||
this.workflowConfig = configService.workflowConfig();
|
const hasRss = iqserPermissionsService.has(Roles.getRss);
|
||||||
|
this.workflowConfig = hasRss ? configService.workflowConfigRss() : configService.workflowConfig();
|
||||||
this.files$ = merge(this.#files$, this.#dossierFilesChange$).pipe(shareLast());
|
this.files$ = merge(this.#files$, this.#dossierFilesChange$).pipe(shareLast());
|
||||||
this.#updateFileAttributes();
|
this.#updateFileAttributes();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ export class PermissionsService {
|
|||||||
entities.length &&
|
entities.length &&
|
||||||
this.isAdmin() &&
|
this.isAdmin() &&
|
||||||
this._iqserPermissionsService.has(Roles.dictionaryTypes.delete) &&
|
this._iqserPermissionsService.has(Roles.dictionaryTypes.delete) &&
|
||||||
entities.reduce((acc, _entity) => this._canDeleteEntity(_entity) && acc, true)
|
entities.reduce((acc, _entity) => this.#canDeleteEntity(_entity) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ export class PermissionsService {
|
|||||||
|
|
||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
const sameState = new Set(files.map(f => f.excluded)).size === 1;
|
const sameState = new Set(files.map(f => f.excluded)).size === 1;
|
||||||
return sameState && files.reduce((acc, _file) => this._canToggleAnalysis(_file, dossier) && acc, true);
|
return sameState && files.reduce((acc, _file) => this.#canToggleAnalysis(_file, dossier) && acc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
showToggleAnalysis(dossier: Dossier): boolean {
|
showToggleAnalysis(dossier: Dossier): boolean {
|
||||||
@ -105,21 +105,21 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
||||||
files.reduce((acc, _file) => this._canReanalyseFile(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canReanalyseFile(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
canEnableAutoAnalysis(files: File[], dossier: Dossier): boolean {
|
canEnableAutoAnalysis(files: File[], dossier: Dossier): boolean {
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
||||||
files.reduce((acc, _file) => this._canEnableAutoAnalysis(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canEnableAutoAnalysis(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
canDisableAutoAnalysis(files: File[], dossier: Dossier): boolean {
|
canDisableAutoAnalysis(files: File[], dossier: Dossier): boolean {
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
||||||
files.reduce((acc, _file) => this._canDisableAutoAnalysis(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canDisableAutoAnalysis(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.delete) &&
|
this._iqserPermissionsService.has(Roles.files.delete) &&
|
||||||
files.reduce((acc, _file) => this._canSoftDeleteFile(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canSoftDeleteFile(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.delete) &&
|
this._iqserPermissionsService.has(Roles.files.delete) &&
|
||||||
files.reduce((acc, _file) => this._canRestoreFile(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canRestoreFile(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.delete) &&
|
this._iqserPermissionsService.has(Roles.files.delete) &&
|
||||||
files.reduce((acc, _file) => this._canHardDeleteFile(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canHardDeleteFile(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
||||||
files.reduce((acc, _file) => this._canOcrFile(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canOcrFile(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
||||||
files.reduce((acc, _file) => this._canAssignToSelf(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canAssignToSelf(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
||||||
files.reduce((acc, _file) => this._canAssignUser(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canAssignUser(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,25 +179,25 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
||||||
files.reduce((acc, _file) => this._canUnassignUser(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canUnassignUser(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
canSetToNew(file: File | File[], dossier: Dossier): boolean {
|
canSetToNew(file: File | File[], dossier: Dossier): boolean {
|
||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return files.reduce((acc, _file) => this._canSetToNew(_file, dossier) && acc, true);
|
return files.reduce((acc, _file) => this.#canSetToNew(_file, dossier) && acc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
canSetUnderReview(file: File | File[], dossier: Dossier): boolean {
|
canSetUnderReview(file: File | File[], dossier: Dossier): boolean {
|
||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return files.reduce((acc, _file) => this._canSetUnderReview(_file, dossier) && acc, true);
|
return files.reduce((acc, _file) => this.#canSetUnderReview(_file, dossier) && acc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
canBeApproved(file: File | File[], dossier: Dossier): boolean {
|
canBeApproved(file: File | File[], dossier: Dossier): boolean {
|
||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
||||||
files.reduce((acc, _file) => this._canBeApproved(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canBeApproved(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
||||||
files.reduce((acc, _file) => this._isReadyForApproval(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#isReadyForApproval(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.setUnderApproval) &&
|
this._iqserPermissionsService.has(Roles.files.setUnderApproval) &&
|
||||||
files.reduce((acc, _file) => this._canSetUnderApproval(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canSetUnderApproval(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ export class PermissionsService {
|
|||||||
const files = file instanceof File ? [file] : file;
|
const files = file instanceof File ? [file] : file;
|
||||||
return (
|
return (
|
||||||
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
||||||
files.reduce((acc, _file) => this._canUndoApproval(_file, dossier) && acc, true)
|
files.reduce((acc, _file) => this.#canUndoApproval(_file, dossier) && acc, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,11 +354,11 @@ export class PermissionsService {
|
|||||||
return this._iqserPermissionsService.has(Roles.rules.write) && this.isAdmin();
|
return this._iqserPermissionsService.has(Roles.rules.write) && this.isAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canDeleteEntity(entity: Dictionary): boolean {
|
#canDeleteEntity(entity: Dictionary): boolean {
|
||||||
return !entity.systemManaged;
|
return !entity.systemManaged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canOcrFile(file: File, dossier: Dossier): boolean {
|
#canOcrFile(file: File, dossier: Dossier): boolean {
|
||||||
return (
|
return (
|
||||||
dossier.isActive &&
|
dossier.isActive &&
|
||||||
!!file.lastProcessed &&
|
!!file.lastProcessed &&
|
||||||
@ -367,7 +367,7 @@ export class PermissionsService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canToggleAnalysis(file: File, dossier: Dossier): boolean {
|
#canToggleAnalysis(file: File, dossier: Dossier): boolean {
|
||||||
return (
|
return (
|
||||||
dossier.isActive &&
|
dossier.isActive &&
|
||||||
!!file.lastProcessed &&
|
!!file.lastProcessed &&
|
||||||
@ -376,78 +376,86 @@ export class PermissionsService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canSoftDeleteFile(file: File, dossier: Dossier): boolean {
|
#canSoftDeleteFile(file: File, dossier: Dossier): boolean {
|
||||||
return dossier.isActive && (this.isAssigneeOrApprover(file, dossier) || (!file.assignee && this.isDossierMember(dossier)));
|
return dossier.isActive && (this.isAssigneeOrApprover(file, dossier) || (!file.assignee && this.isDossierMember(dossier)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canRestoreFile(file: File, dossier: Dossier): boolean {
|
#canRestoreFile(file: File, dossier: Dossier): boolean {
|
||||||
return this.isAssigneeOrApprover(file, dossier);
|
return this.isAssigneeOrApprover(file, dossier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canHardDeleteFile(file: File, dossier: Dossier): boolean {
|
#canHardDeleteFile(file: File, dossier: Dossier): boolean {
|
||||||
return this.isAssigneeOrApprover(file, dossier) || (!file.assignee && this.isDossierMember(dossier));
|
return this.isAssigneeOrApprover(file, dossier) || (!file.assignee && this.isDossierMember(dossier));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canReanalyseFile(file: File, dossier: Dossier): boolean {
|
#canReanalyseFile(file: File, dossier: Dossier): boolean {
|
||||||
return dossier.isActive && this.isAssigneeOrApprover(file, dossier) && file.analysisRequired;
|
return dossier.isActive && this.isAssigneeOrApprover(file, dossier) && file.analysisRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canEnableAutoAnalysis(file: File, dossier: Dossier): boolean {
|
#canEnableAutoAnalysis(file: File, dossier: Dossier): boolean {
|
||||||
return (
|
return (
|
||||||
dossier.isActive && file.excludedFromAutomaticAnalysis && this.isFileAssignee(file) && !file.isApproved && !!file.lastProcessed
|
dossier.isActive && file.excludedFromAutomaticAnalysis && this.isFileAssignee(file) && !file.isApproved && !!file.lastProcessed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canDisableAutoAnalysis(file: File, dossier: Dossier): boolean {
|
#canDisableAutoAnalysis(file: File, dossier: Dossier): boolean {
|
||||||
return (
|
return (
|
||||||
dossier.isActive && !file.excludedFromAutomaticAnalysis && this.isFileAssignee(file) && !file.isApproved && !!file.lastProcessed
|
dossier.isActive && !file.excludedFromAutomaticAnalysis && this.isFileAssignee(file) && !file.isApproved && !!file.lastProcessed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UNDER_REVIEW => NEW */
|
/** UNDER_REVIEW => NEW */
|
||||||
private _canSetToNew(file: File, dossier: Dossier): boolean {
|
#canSetToNew(file: File, dossier: Dossier): boolean {
|
||||||
return dossier.isActive && file.isUnderReview && this.isAssigneeOrApprover(file, dossier);
|
return dossier.isActive && file.isUnderReview && this.isAssigneeOrApprover(file, dossier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UNDER_REVIEW => UNDER_APPROVAL */
|
/** UNDER_REVIEW => UNDER_APPROVAL */
|
||||||
private _canSetUnderApproval(file: File, dossier: Dossier): boolean {
|
#canSetUnderApproval(file: File, dossier: Dossier): boolean {
|
||||||
return dossier.isActive && file.isUnderReview && this.isAssigneeOrApprover(file, dossier);
|
const hasRss = this._iqserPermissionsService.has(Roles.getRss);
|
||||||
|
const fileCanBeSetUnderApproval = !hasRss && file.isUnderReview;
|
||||||
|
return dossier.isActive && fileCanBeSetUnderApproval && this.isAssigneeOrApprover(file, dossier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UNDER_APPROVAL => UNDER_REVIEW OR NEW => UNDER_REVIEW */
|
/** UNDER_APPROVAL => UNDER_REVIEW OR NEW => UNDER_REVIEW */
|
||||||
private _canSetUnderReview(file: File, dossier: Dossier): boolean {
|
#canSetUnderReview(file: File, dossier: Dossier): boolean {
|
||||||
if (!dossier.isActive) {
|
if (!dossier.isActive) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return file.isUnderApproval && this.isAssigneeOrApprover(file, dossier);
|
const hasRss = this._iqserPermissionsService.has(Roles.getRss);
|
||||||
|
const fileCanBeSetUnderReview = file.isUnderApproval || (hasRss && file.isApproved);
|
||||||
|
return fileCanBeSetUnderReview && this.isAssigneeOrApprover(file, dossier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UNDER_APPROVAL => APPROVED */
|
/** UNDER_APPROVAL => APPROVED */
|
||||||
private _canBeApproved(file: File, dossier: Dossier): boolean {
|
#canBeApproved(file: File, dossier: Dossier): boolean {
|
||||||
return this._isReadyForApproval(file, dossier) && file.canBeApproved;
|
return this.#isReadyForApproval(file, dossier) && file.canBeApproved;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isReadyForApproval(file: File, dossier: Dossier): boolean {
|
#isReadyForApproval(file: File, dossier: Dossier) {
|
||||||
return dossier.isActive && file.isUnderApproval && this.isAssigneeOrApprover(file, dossier);
|
const hasRss = this._iqserPermissionsService.has(Roles.getRss);
|
||||||
|
const fileCanBeApproved = file.isUnderApproval || (hasRss && file.isUnderReview);
|
||||||
|
return dossier.isActive && fileCanBeApproved && this.isAssigneeOrApprover(file, dossier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** APPROVED => UNDER_APPROVAL */
|
/** APPROVED => UNDER_APPROVAL */
|
||||||
private _canUndoApproval(file: File, dossier: Dossier): boolean {
|
#canUndoApproval(file: File, dossier: Dossier): boolean {
|
||||||
return dossier.isActive && file.isApproved && this.isApprover(dossier);
|
const hasRss = this._iqserPermissionsService.has(Roles.getRss);
|
||||||
|
const fileCanBeSetUnderApproval = !hasRss && file.isApproved;
|
||||||
|
return dossier.isActive && fileCanBeSetUnderApproval && this.isApprover(dossier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _assignmentPrecondition(file: File, dossier: Dossier): boolean {
|
#assignmentPrecondition(file: File, dossier: Dossier): boolean {
|
||||||
return dossier.isActive && !file.isError && !file.isProcessing && !!file.lastProcessed;
|
return dossier.isActive && !file.isError && !file.isProcessing && !!file.lastProcessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canAssignToSelf(file: File, dossier: Dossier): boolean {
|
#canAssignToSelf(file: File, dossier: Dossier): boolean {
|
||||||
const precondition = this._assignmentPrecondition(file, dossier) && !this.isFileAssignee(file);
|
const precondition = this.#assignmentPrecondition(file, dossier) && !this.isFileAssignee(file);
|
||||||
return precondition && (this.isApprover(dossier) || (this.isDossierMember(dossier) && (file.isNew || file.isUnderReview)));
|
return precondition && (this.isApprover(dossier) || (this.isDossierMember(dossier) && (file.isNew || file.isUnderReview)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canAssignUser(file: File, dossier: Dossier) {
|
#canAssignUser(file: File, dossier: Dossier) {
|
||||||
const precondition = this._assignmentPrecondition(file, dossier);
|
const precondition = this.#assignmentPrecondition(file, dossier);
|
||||||
|
|
||||||
if (precondition) {
|
if (precondition) {
|
||||||
if ((file.isNew || file.isUnderReview) && dossier.hasReviewers && this.isDossierMember(dossier)) {
|
if ((file.isNew || file.isUnderReview) && dossier.hasReviewers && this.isDossierMember(dossier)) {
|
||||||
@ -460,7 +468,7 @@ export class PermissionsService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _canUnassignUser(file: File, dossier: Dossier) {
|
#canUnassignUser(file: File, dossier: Dossier) {
|
||||||
return this._assignmentPrecondition(file, dossier) && !!file.assignee && this.isAssigneeOrApprover(file, dossier);
|
return this.#assignmentPrecondition(file, dossier) && !!file.assignee && this.isAssigneeOrApprover(file, dossier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1435,7 +1435,7 @@
|
|||||||
},
|
},
|
||||||
"file-status": {
|
"file-status": {
|
||||||
"analyse": "Analyzing",
|
"analyse": "Analyzing",
|
||||||
"approved": "Approved",
|
"approved": "Done",
|
||||||
"error": "Re-processing required",
|
"error": "Re-processing required",
|
||||||
"figure-detection-analyzing": "",
|
"figure-detection-analyzing": "",
|
||||||
"full-processing": "Processing",
|
"full-processing": "Processing",
|
||||||
@ -1453,7 +1453,7 @@
|
|||||||
"table-parsing-analyzing": "Table Parsing",
|
"table-parsing-analyzing": "Table Parsing",
|
||||||
"unassigned": "Unassigned",
|
"unassigned": "Unassigned",
|
||||||
"under-approval": "Under Approval",
|
"under-approval": "Under Approval",
|
||||||
"under-review": "Under Review",
|
"under-review": "In Progress",
|
||||||
"unprocessed": "Unprocessed"
|
"unprocessed": "Unprocessed"
|
||||||
},
|
},
|
||||||
"file-upload": {
|
"file-upload": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user