From 9845267cc507ecdb79a92ba532c3c6e49b939c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Wed, 1 Dec 2021 21:30:31 +0200 Subject: [PATCH 01/10] Update workflow UI --- .../file-workload.component.html} | 0 .../file-workload.component.scss} | 0 .../file-workload.component.ts} | 8 +- .../table-item/table-item.component.html | 2 +- .../workflow-item.component.html | 15 +- .../workflow-item.component.scss | 25 +- .../workflow-item/workflow-item.component.ts | 7 +- .../dossier-overview/config.service.ts | 11 +- .../dossier-overview.module.ts | 4 +- .../dossier-overview-screen.component.html | 7 +- .../file-preview-screen.component.ts | 6 +- .../file-actions/file-actions.component.html | 153 +--------- .../file-actions/file-actions.component.scss | 10 - .../file-actions/file-actions.component.ts | 272 ++++++++++++++---- .../file-download-btn.component.ts | 6 +- .../expandable-file-actions.component.html | 64 +++++ .../expandable-file-actions.component.scss | 27 ++ .../expandable-file-actions.component.ts | 38 +++ .../expandable-file-actions/types.ts | 27 ++ .../src/app/modules/shared/shared.module.ts | 2 + .../src/app/services/permissions.service.ts | 9 +- libs/common-ui | 2 +- libs/red-domain/src/lib/files/file.model.ts | 1 - 23 files changed, 438 insertions(+), 258 deletions(-) rename apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/{file-workload-column/file-workload-column.component.html => file-workload/file-workload.component.html} (100%) rename apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/{file-workload-column/file-workload-column.component.scss => file-workload/file-workload.component.scss} (100%) rename apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/{file-workload-column/file-workload-column.component.ts => file-workload/file-workload.component.ts} (84%) create mode 100644 apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html create mode 100644 apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.scss create mode 100644 apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts create mode 100644 apps/red-ui/src/app/modules/shared/components/expandable-file-actions/types.ts diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload-column/file-workload-column.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload/file-workload.component.html similarity index 100% rename from apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload-column/file-workload-column.component.html rename to apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload/file-workload.component.html diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload-column/file-workload-column.component.scss b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload/file-workload.component.scss similarity index 100% rename from apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload-column/file-workload-column.component.scss rename to apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload/file-workload.component.scss diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload-column/file-workload-column.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload/file-workload.component.ts similarity index 84% rename from apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload-column/file-workload-column.component.ts rename to apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload/file-workload.component.ts index 5894045a9..0b69ee12a 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload-column/file-workload-column.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/file-workload/file-workload.component.ts @@ -4,12 +4,12 @@ import { File } from '@red/domain'; import { DossiersService } from '@services/entity-services/dossiers.service'; @Component({ - selector: 'redaction-file-workload-column', - templateUrl: './file-workload-column.component.html', - styleUrls: ['./file-workload-column.component.scss'], + selector: 'redaction-file-workload', + templateUrl: './file-workload.component.html', + styleUrls: ['./file-workload.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class FileWorkloadColumnComponent { +export class FileWorkloadComponent { @Input() file: File; constructor(private readonly _appStateService: AppStateService, private readonly _dossiersService: DossiersService) {} diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.html index aad72d891..501c43b8c 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.html @@ -17,7 +17,7 @@
- +
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html index 0cc78470c..3b0eaa732 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html @@ -13,5 +13,18 @@
- +
+ {{ file.fileAttributes.attributeIdToValue[config.id] || '-' }} +
+ + + +
+ +
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss index 75bdb518a..74a119427 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss @@ -1,7 +1,7 @@ @use 'common-mixins'; .workflow-item { - padding: 10px; + padding: 10px 10px 8px 10px; > div { display: flex; @@ -23,12 +23,31 @@ } } - redaction-file-actions { + redaction-file-workload { margin-top: 10px; + display: block; + min-height: 16px; + } + + .file-actions { + margin-top: 8px; + min-height: 34px; + overflow: hidden; + } + + redaction-file-actions:not(.keep-visible) { display: none; } + &:hover .filename { + text-decoration: underline; + } + &:hover redaction-file-actions { - display: block; + display: initial; } } + +.mt-4 { + margin-top: 4px; +} diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts index fffcf980d..b7b4c79d2 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts @@ -1,5 +1,6 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { File } from '@red/domain'; +import { File, IFileAttributeConfig } from '@red/domain'; +import { Required } from '@iqser/common-ui'; @Component({ selector: 'redaction-workflow-item', @@ -8,5 +9,7 @@ import { File } from '@red/domain'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class WorkflowItemComponent { - @Input() file: File; + @Input() @Required() file!: File; + @Input() @Required() displayedAttributes!: IFileAttributeConfig[]; + @Input() width: number; } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts index 135fa3130..36cdc8972 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts @@ -27,6 +27,7 @@ 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'; @Injectable() export class ConfigService { @@ -63,8 +64,8 @@ export class ConfigService { { label: workflowFileStatusTranslations[WorkflowFileStatuses.NEW], key: WorkflowFileStatuses.NEW, - enterFn: this._unassignFn, - enterPredicate: (file: File) => this._permissionsService.canUnassignUser(file), + enterFn: noop, + enterPredicate: () => false, color: '#D3D5DA', }, { @@ -362,12 +363,6 @@ export class ConfigService { this._dialogService.openDialog('editDossier', $event, { dossierId }); } - private _unassignFn = async (file: File) => { - this._loadingService.start(); - await this._filesService.setUnassigned([file.fileId], file.dossierId).toPromise(); - this._loadingService.stop(); - }; - private _underReviewFn = async (file: File) => { await this._fileAssignService.assignReviewer(null, file, true); }; diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts index 3d7b9fb5c..c9382a62a 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts @@ -11,7 +11,7 @@ import { DossierDetailsStatsComponent } from './components/dossier-details-stats import { TableItemComponent } from './components/table-item/table-item.component'; import { ConfigService } from './config.service'; import { SharedDossiersModule } from '../../shared/shared-dossiers.module'; -import { FileWorkloadColumnComponent } from './components/table-item/file-workload-column/file-workload-column.component'; +import { FileWorkloadComponent } from './components/table-item/file-workload/file-workload.component'; import { FileStatsComponent } from './components/file-stats/file-stats.component'; import { WorkflowItemComponent } from './components/workflow-item/workflow-item.component'; import { ScreenHeaderComponent } from './components/screen-header/screen-header.component'; @@ -36,7 +36,7 @@ const routes: Routes = [ DossierOverviewBulkActionsComponent, DossierDetailsComponent, DossierDetailsStatsComponent, - FileWorkloadColumnComponent, + FileWorkloadComponent, TableItemComponent, FileStatsComponent, WorkflowItemComponent, diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html index 39fdceef3..042e26b51 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html @@ -34,14 +34,13 @@ [addElementIcon]="'iqser:upload'" [config]="workflowConfig" [itemClasses]="{ disabled: disabledFn }" - [itemHeight]="'56px'" [itemTemplate]="workflowItemTemplate" [noDataButtonIcon]="'iqser:upload'" [noDataButtonLabel]="'dossier-overview.no-data.action' | translate" [noDataIcon]="'iqser:document'" [noDataText]="'dossier-overview.no-data.title' | translate" [showNoDataButton]="true" - addElementColumn="UNASSIGNED" + addElementColumn="NEW" > @@ -76,6 +75,6 @@ - - + + 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 b2ebd6476..8a34666eb 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 @@ -44,7 +44,6 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { clearStamps, stampPDFPage } from '@utils/page-stamper'; import { TranslateService } from '@ngx-translate/core'; import { handleFilterDelta } from '@utils/filter-utils'; -import { FileActionsComponent } from '../../shared/components/file-actions/file-actions.component'; import { FilesService } from '@services/entity-services/files.service'; import { DossiersService } from '@services/entity-services/dossiers.service'; import { FileManagementService } from '@services/entity-services/file-management.service'; @@ -55,6 +54,7 @@ import { ExcludedPagesService } from './services/excluded-pages.service'; import { ViewModeService } from './services/view-mode.service'; import { MultiSelectService } from './services/multi-select.service'; import { DocumentInfoService } from './services/document-info.service'; +import { ReanalysisService } from '../../../../services/reanalysis.service'; import Annotation = Core.Annotations.Annotation; import PDFNet = Core.PDFNet; @@ -78,7 +78,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni hideSkipped = false; displayPDFViewer = false; @ViewChild(PdfViewerComponent) readonly viewerComponent: PdfViewerComponent; - @ViewChild('fileActions') fileActions: FileActionsComponent; readonly dossierId: string; readonly canPerformAnnotationActions$: Observable; readonly dossier$: Observable; @@ -117,6 +116,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni private readonly _translateService: TranslateService, private readonly _filesMapService: FilesMapService, private readonly _dossiersService: DossiersService, + private readonly _reanalysisService: ReanalysisService, readonly excludedPagesService: ExcludedPagesService, readonly viewModeService: ViewModeService, readonly multiSelectService: MultiSelectService, @@ -239,7 +239,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni const file = this._filesMapService.get(this.dossierId, this.fileId); if (file?.analysisRequired) { - await this.fileActions.reanalyseFile(); + await this._reanalysisService.reanalyzeFilesForDossier([this.fileId], this.dossierId, true).toPromise(); } this.displayPDFViewer = true; diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html index 646de42ff..15dca9eca 100644 --- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html +++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html @@ -16,153 +16,12 @@
-
- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
+ >
diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.scss b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.scss index 4aabc4879..ba5702729 100644 --- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.scss +++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.scss @@ -3,9 +3,7 @@ .file-actions { display: flex; - overflow-y: auto; color: variables.$grey-1; - @include common-mixins.no-scroll-bar; > *:not(:last-child) { margin-right: 2px; @@ -27,14 +25,6 @@ iqser-status-bar { margin-left: 2px; } -mat-slide-toggle { - height: 34px; - width: 34px; - line-height: 33px; - margin-left: 8px; - margin-right: 5px; -} - .spinning-icon { margin: 0 12px 0 11px; } 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 ec6523584..e429341a8 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 @@ -1,4 +1,16 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Optional, Output } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + HostBinding, + Input, + OnChanges, + OnDestroy, + OnInit, + Optional, + Output, + ViewChild, +} from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import { File } from '@red/domain'; import { DossiersDialogService } from '../../../services/dossiers-dialog.service'; @@ -25,6 +37,8 @@ import { Router } from '@angular/router'; import { ExcludedPagesService } from '../../../screens/file-preview-screen/services/excluded-pages.service'; import { tap } from 'rxjs/operators'; import { DocumentInfoService } from '../../../screens/file-preview-screen/services/document-info.service'; +import { Action, ActionTypes } from '@shared/components/expandable-file-actions/types'; +import { ExpandableFileActionsComponent } from '@shared/components/expandable-file-actions/expandable-file-actions.component'; @Component({ selector: 'redaction-file-actions', @@ -36,8 +50,9 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, readonly circleButtonTypes = CircleButtonTypes; readonly currentUser = this._userService.currentUser; - @Input() file: File; + @Input() @Required() file: File; @Input() @Required() type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow'; + @Input() maxWidth: number; @Output() readonly ocredFile = new EventEmitter(); toggleTooltip?: string; @@ -56,16 +71,20 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, canToggleAnalysis: boolean; showStatusBar: boolean; showOpenDocument: boolean; + showReanalyseFilePreview: boolean; + showReanalyseDossierOverview: boolean; analysisForced: boolean; isDossierOverview = false; isDossierOverviewList = false; isDossierOverviewWorkflow = false; isFilePreview = false; tooltipPosition: IqserTooltipPosition; + buttons: Action[]; + @ViewChild(ExpandableFileActionsComponent) _expandableActionsComponent: ExpandableFileActionsComponent; constructor( - @Optional() readonly excludedPagesService: ExcludedPagesService, - @Optional() readonly documentInfoService: DocumentInfoService, + @Optional() private readonly _excludedPagesService: ExcludedPagesService, + @Optional() private readonly _documentInfoService: DocumentInfoService, private readonly _permissionsService: PermissionsService, private readonly _dossiersService: DossiersService, private readonly _dialogService: DossiersDialogService, @@ -82,6 +101,10 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, super(); } + @HostBinding('class.keep-visible') get expanded() { + return this._expandableActionsComponent?.expanded; + } + private get _toggleTooltip(): string { if (!this.currentUser.isManager) { return _('file-preview.toggle-analysis.only-managers'); @@ -90,6 +113,124 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, return this.file?.excluded ? _('file-preview.toggle-analysis.enable') : _('file-preview.toggle-analysis.disable'); } + private get _buttons(): Action[] { + return [ + { + type: ActionTypes.circleBtn, + action: () => this._openDocument(), + tooltip: _('dossier-overview.open-document'), + icon: 'iqser:collapse', + show: this.showOpenDocument, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._openDeleteFileDialog($event), + tooltip: _('dossier-overview.delete.action'), + icon: 'iqser:trash', + show: this.showDelete, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._assign($event), + tooltip: this.assignTooltip, + icon: 'red:assign', + show: this.showAssign, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._assignToMe($event), + tooltip: _('dossier-overview.assign-me'), + icon: 'red:assign-me', + show: this.showAssignToSelf, + }, + { + type: ActionTypes.downloadBtn, + show: true, + files: [this.file], + tooltipClass: 'small', + disabled: !this._permissionsService.canDownloadFiles([this.file]), + }, + { + type: ActionTypes.circleBtn, + action: () => this._documentInfoService.toggle(), + tooltip: _('file-preview.document-info'), + ariaExpanded: this._documentInfoService?.shown$, + icon: 'red:status-info', + show: !!this._documentInfoService, + }, + { + type: ActionTypes.circleBtn, + action: () => this._excludedPagesService.toggle(), + tooltip: _('file-preview.exclude-pages'), + ariaExpanded: this._excludedPagesService?.shown$, + showDot: !!this.file.excludedPages?.length, + icon: 'red:exclude-pages', + show: !!this._excludedPagesService, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._setFileUnderApproval($event), + tooltip: _('dossier-overview.under-approval'), + icon: 'red:ready-for-approval', + show: this.showUnderApproval, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._setFileUnderReview($event), + tooltip: _('dossier-overview.under-review'), + icon: 'red:undo', + show: this.showUnderReview, + }, + { + type: ActionTypes.circleBtn, + action: $event => this.setFileApproved($event), + tooltip: this.file.canBeApproved ? _('dossier-overview.approve') : _('dossier-overview.approve-disabled'), + icon: 'red:approved', + disabled: !this.file.canBeApproved, + show: this.showApprove, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._setFileUnderApproval($event), + tooltip: _('dossier-overview.under-approval'), + icon: 'red:undo', + show: this.showUndoApproval, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._ocrFile($event), + tooltip: _('dossier-overview.ocr-file'), + icon: 'iqser:ocr', + show: this.showOCR, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._reanalyseFile($event), + tooltip: _('file-preview.reanalyse-notification'), + buttonType: CircleButtonTypes.warn, + tooltipClass: 'warn small', + icon: 'iqser:refresh', + show: this.showReanalyseFilePreview, + }, + { + type: ActionTypes.circleBtn, + action: $event => this._reanalyseFile($event), + tooltip: _('dossier-overview.reanalyse.action'), + icon: 'iqser:refresh', + show: this.showReanalyseDossierOverview, + }, + { + type: ActionTypes.toggle, + action: () => this._toggleAnalysis(), + disabled: !this.canToggleAnalysis, + tooltip: this.toggleTooltip, + class: { 'mr-24': this.isDossierOverviewList }, + checked: !this.file.excluded, + show: true, + }, + ].filter(btn => btn.show); + } + ngOnInit() { this._dossiersService.getEntityChanged$(this.file.dossierId).pipe(tap(() => this._setup())); } @@ -98,57 +239,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, this._setup(); } - openDocument() { - this._router.navigate([this.file.routerLink]).then(); - } - - openDeleteFileDialog($event: MouseEvent) { - this._dialogService.openDialog( - 'confirm', - $event, - new ConfirmationDialogInput({ - title: _('confirmation-dialog.delete-file.title'), - question: _('confirmation-dialog.delete-file.question'), - }), - async () => { - this._loadingService.start(); - try { - const dossier = this._dossiersService.find(this.file.dossierId); - await this._fileManagementService.delete([this.file.fileId], this.file.dossierId).toPromise(); - await this._router.navigate([dossier.routerLink]); - } catch (error) { - this._toaster.error(_('error.http.generic'), { params: error }); - } - this._loadingService.stop(); - }, - ); - } - - assign($event: MouseEvent) { - const mode = this.file.isUnderApproval ? 'approver' : 'reviewer'; - const files = [this.file]; - const withCurrentUserAsDefault = true; - const withUnassignedOption = true; - this._dialogService.openDialog('assignFile', $event, { mode, files, withCurrentUserAsDefault, withUnassignedOption }); - } - - async assignToMe($event: MouseEvent) { - $event.stopPropagation(); - await this._fileAssignService.assignToMe([this.file]); - } - - async reanalyseFile($event?: MouseEvent) { - if ($event) { - $event.stopPropagation(); - } - await this._reanalysisService.reanalyzeFilesForDossier([this.file.fileId], this.file.dossierId, true).toPromise(); - } - - async setFileUnderApproval($event: MouseEvent) { - $event.stopPropagation(); - await this._fileAssignService.assignApprover($event, this.file, true); - } - async setFileApproved($event: MouseEvent) { $event.stopPropagation(); if (!this.file.hasUpdates) { @@ -169,7 +259,62 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, ); } - async ocrFile($event: MouseEvent) { + forceReanalysisAction($event: LongPressEvent) { + this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled; + } + + private _openDocument() { + this._router.navigate([this.file.routerLink]).then(); + } + + private _openDeleteFileDialog($event: MouseEvent) { + this._dialogService.openDialog( + 'confirm', + $event, + new ConfirmationDialogInput({ + title: _('confirmation-dialog.delete-file.title'), + question: _('confirmation-dialog.delete-file.question'), + }), + async () => { + this._loadingService.start(); + try { + const dossier = this._dossiersService.find(this.file.dossierId); + await this._fileManagementService.delete([this.file.fileId], this.file.dossierId).toPromise(); + await this._router.navigate([dossier.routerLink]); + } catch (error) { + this._toaster.error(_('error.http.generic'), { params: error }); + } + this._loadingService.stop(); + }, + ); + } + + private _assign($event: MouseEvent) { + const mode = this.file.isUnderApproval ? 'approver' : 'reviewer'; + const files = [this.file]; + const withCurrentUserAsDefault = true; + const withUnassignedOption = true; + this._dialogService.openDialog('assignFile', $event, { mode, files, withCurrentUserAsDefault, withUnassignedOption }); + } + + private async _assignToMe($event: MouseEvent) { + $event.stopPropagation(); + await this._fileAssignService.assignToMe([this.file]); + } + + private async _reanalyseFile($event?: MouseEvent) { + if ($event) { + $event.stopPropagation(); + } + await this._reanalysisService.reanalyzeFilesForDossier([this.file.fileId], this.file.dossierId, true).toPromise(); + } + + private async _setFileUnderApproval($event: MouseEvent) { + $event.stopPropagation(); + await this._fileAssignService.assignApprover($event, this.file, true); + } + + private async _ocrFile($event: MouseEvent) { $event.stopPropagation(); this._loadingService.start(); await this._reanalysisService.ocrFiles([this.file.fileId], this.file.dossierId).toPromise(); @@ -177,20 +322,16 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, this._loadingService.stop(); } - async setFileUnderReview($event: MouseEvent, ignoreDialogChanges = false) { - await this._fileAssignService.assignReviewer($event, this.file, ignoreDialogChanges); + private async _setFileUnderReview($event: MouseEvent) { + await this._fileAssignService.assignReviewer($event, this.file, true); } - async toggleAnalysis() { + private async _toggleAnalysis() { this._loadingService.start(); await this._reanalysisService.toggleAnalysis(this.file.dossierId, this.file.fileId, !this.file.excluded).toPromise(); this._loadingService.stop(); } - forceReanalysisAction($event: LongPressEvent) { - this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled; - } - private _setup() { this.isDossierOverviewList = this.type === 'dossier-overview-list'; this.isDossierOverviewWorkflow = this.type === 'dossier-overview-workflow'; @@ -221,6 +362,11 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, this.isDossierOverview; this.showOpenDocument = this.file.canBeOpened && this.isDossierOverviewWorkflow; + + this.showReanalyseFilePreview = this.canReanalyse && this.isFilePreview && this.analysisForced; + this.showReanalyseDossierOverview = this.canReanalyse && this.isDossierOverview && this.analysisForced; + + this.buttons = this._buttons; } private async _setFileApproved() { 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 d80079779..97645d398 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 @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import { File } from '@red/domain'; import { FileDownloadService } from '@upload-download/services/file-download.service'; -import { CircleButtonType, CircleButtonTypes, List, Toaster } from '@iqser/common-ui'; +import { CircleButtonType, CircleButtonTypes, Toaster } from '@iqser/common-ui'; import { TranslateService } from '@ngx-translate/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -15,7 +15,7 @@ export type MenuState = 'OPEN' | 'CLOSED'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class FileDownloadBtnComponent { - @Input() files: List; + @Input() files: File[]; @Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above'; @Input() type: CircleButtonType = CircleButtonTypes.default; @Input() tooltipClass: string; @@ -29,7 +29,7 @@ export class FileDownloadBtnComponent { ) {} get canDownloadFiles() { - return this.files.length > 0 && this.files.reduce((acc, file) => acc && this._permissionsService.canDownloadFiles(file), true); + return this._permissionsService.canDownloadFiles(this.files); } get tooltip() { 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 new file mode 100644 index 000000000..330b08556 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html @@ -0,0 +1,64 @@ + + + + + + + +
+ +
+
+ + + + + + diff --git a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.scss b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.scss new file mode 100644 index 000000000..0bc36396d --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.scss @@ -0,0 +1,27 @@ +:host { + display: contents; +} + +mat-slide-toggle { + height: 34px; + width: 34px; + line-height: 33px; + margin-left: 8px; + margin-right: 5px; +} + +.mat-menu-item { + mat-icon { + color: inherit; + width: 14px; + height: 14px; + } + + &[disabled] { + color: rgba(var(--iqser-accent-rgb), 0.3); + } +} + +.ml-0 { + margin-left: 0; +} 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 new file mode 100644 index 000000000..318ecab8d --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts @@ -0,0 +1,38 @@ +import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { Action } from './types'; +import { CircleButtonType, IqserTooltipPosition } from '@iqser/common-ui'; + +@Component({ + selector: 'redaction-expandable-file-actions', + templateUrl: './expandable-file-actions.component.html', + styleUrls: ['./expandable-file-actions.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ExpandableFileActionsComponent implements OnChanges { + @Input() maxWidth: number; + @Input() actions: Action[]; + @Input() buttonType: CircleButtonType; + @Input() tooltipPosition: IqserTooltipPosition; + + displayedButtons: Action[]; + hiddenButtons: Action[]; + expanded = false; + + ngOnChanges(changes: SimpleChanges) { + if (changes.actions || changes.maxWidth) { + if (this.maxWidth) { + const count = Math.floor(this.maxWidth / 36); + if (count >= this.actions.length) { + this.displayedButtons = [...this.actions]; + this.hiddenButtons = []; + } else { + this.displayedButtons = this.actions.slice(0, count - 1); + this.hiddenButtons = this.actions.slice(count - 1); + } + } else { + this.displayedButtons = [...this.actions]; + this.hiddenButtons = []; + } + } + } +} diff --git a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/types.ts b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/types.ts new file mode 100644 index 000000000..fe73bfd0b --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/types.ts @@ -0,0 +1,27 @@ +import { Observable } from 'rxjs'; +import { CircleButtonType } from '@iqser/common-ui'; +import { File } from '@red/domain'; + +export type ActionType = 'circleBtn' | 'downloadBtn' | 'toggle'; + +export const ActionTypes = { + circleBtn: 'circleBtn' as ActionType, + downloadBtn: 'downloadBtn' as ActionType, + toggle: 'toggle' as ActionType, +}; + +export interface Action { + action?: Function; + tooltip?: string; + icon?: string; + show?: boolean; + ariaExpanded?: Observable; + showDot?: boolean; + disabled?: boolean; + buttonType?: CircleButtonType; + tooltipClass?: string; + checked?: boolean; + class?: { [key: string]: boolean }; + files?: File[]; + type: ActionType; +} diff --git a/apps/red-ui/src/app/modules/shared/shared.module.ts b/apps/red-ui/src/app/modules/shared/shared.module.ts index 15067cdb9..4f606ceb9 100644 --- a/apps/red-ui/src/app/modules/shared/shared.module.ts +++ b/apps/red-ui/src/app/modules/shared/shared.module.ts @@ -25,6 +25,7 @@ import { NamePipe } from './pipes/name.pipe'; import { TypeFilterComponent } from './components/type-filter/type-filter.component'; import { TeamMembersComponent } from './components/team-members/team-members.component'; import { EditorComponent } from './components/editor/editor.component'; +import { ExpandableFileActionsComponent } from './components/expandable-file-actions/expandable-file-actions.component'; const buttons = [FileDownloadBtnComponent, UserButtonComponent]; @@ -39,6 +40,7 @@ const components = [ AssignUserDropdownComponent, TypeFilterComponent, TeamMembersComponent, + ExpandableFileActionsComponent, ...buttons, ]; diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index 65f8c7b24..f1ab0c5bb 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -99,13 +99,12 @@ export class PermissionsService { return (file.isUnderReview || file.isUnderApproval) && this.isFileAssignee(file); } - canDownloadFiles(file: File): boolean { - const dossier = this._getDossier(file); - if (!dossier) { + canDownloadFiles(files: File[]): boolean { + if (files.length === 0) { return false; } - - return file.isApproved && this.isApprover(dossier); + const dossier = this._getDossier(files[0]); + return this.isApprover(dossier) && files.reduce((prev, file) => prev && file.isApproved, true); } canDeleteDossier(dossier: Dossier): boolean { diff --git a/libs/common-ui b/libs/common-ui index 0a861bf60..4a27531b8 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 0a861bf60d47504a0c8cba019671da05dcdb3a28 +Subproject commit 4a27531b8e52cea707909f5d93f68b303e587945 diff --git a/libs/red-domain/src/lib/files/file.model.ts b/libs/red-domain/src/lib/files/file.model.ts index 2b38c7920..4e839dace 100644 --- a/libs/red-domain/src/lib/files/file.model.ts +++ b/libs/red-domain/src/lib/files/file.model.ts @@ -45,7 +45,6 @@ export class File extends Entity implements IFile { readonly hintsOnly: boolean; readonly hasNone: boolean; readonly isNew: boolean; - // readonly isUnassigned: boolean; readonly isError: boolean; readonly isProcessing: boolean; readonly isApproved: boolean; From eb5bffed626030e22f2cdc2216daff7abf647eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Thu, 2 Dec 2021 00:50:29 +0200 Subject: [PATCH 02/10] Workflow multi select --- .../dossier-overview/config.service.ts | 6 +- .../dossier-overview-screen.component.ts | 1 - .../file-workload.component.scss | 24 --- .../user-management.component.ts | 6 +- apps/red-ui/src/assets/i18n/en.json | 8 + libs/common-ui | 2 +- package.json | 2 +- yarn.lock | 154 ++++++++++++------ 8 files changed, 122 insertions(+), 81 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts index 36cdc8972..e00b5d3a9 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts @@ -67,6 +67,7 @@ export class ConfigService { enterFn: noop, enterPredicate: () => false, color: '#D3D5DA', + entities: new BehaviorSubject([]), }, { label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_REVIEW], @@ -77,6 +78,7 @@ export class ConfigService { this._permissionsService.canAssignUser(file), key: WorkflowFileStatuses.UNDER_REVIEW, color: '#FDBD00', + entities: new BehaviorSubject([]), }, { label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_APPROVAL], @@ -85,6 +87,7 @@ export class ConfigService { this._permissionsService.canSetUnderApproval(file) || this._permissionsService.canUndoApproval(file), key: WorkflowFileStatuses.UNDER_APPROVAL, color: '#374C81', + entities: new BehaviorSubject([]), }, { label: workflowFileStatusTranslations[WorkflowFileStatuses.APPROVED], @@ -92,6 +95,7 @@ export class ConfigService { enterPredicate: (file: File) => this._permissionsService.isReadyForApproval(file) && file.canBeApproved, key: WorkflowFileStatuses.APPROVED, color: '#48C9F7', + entities: new BehaviorSubject([]), }, ], }; @@ -324,7 +328,7 @@ export class ConfigService { _unassignedChecker = (file: File) => !file.assignee; - _assignedToOthersChecker = (file: File) => !file.isNew && file.assignee !== this._userService.currentUser.id; + _assignedToOthersChecker = (file: File) => file.assignee && file.assignee !== this._userService.currentUser.id; private _quickFilters(entities: File[]): NestedFilter[] { const recentPeriod = this._appConfigService.values.RECENT_PERIOD_IN_HOURS; diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts index d5e5ebcb4..c3e4f8505 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts @@ -123,7 +123,6 @@ export class DossierOverviewScreenComponent extends ListingComponent imple } disabledFn = (file: File) => file.excluded; - lastOpenedFn = (file: File) => this._userPreferenceService.getLastOpenedFileForDossier(file.dossierId) === file.id; async ngOnInit(): Promise { diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.scss b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.scss index 03df3c3aa..64f58538a 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.scss +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/file-workload/file-workload.component.scss @@ -46,30 +46,6 @@ } } - .multi-select { - min-height: 40px; - background: variables.$primary; - display: flex; - justify-content: space-between; - align-items: center; - padding: 0 8px 0 16px; - color: variables.$white; - - .selected-wrapper { - display: flex; - align-items: center; - - iqser-round-checkbox .wrapper.inactive { - cursor: default; - } - - .all-caps-label { - margin: 0 16px 0 8px; - opacity: 1; - } - } - } - .annotations-wrapper { display: flex; height: 100%; diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/user-management/user-management.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/user-management/user-management.component.ts index b919e7c97..6ec0a7db8 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/user-management/user-management.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/user-management/user-management.component.ts @@ -48,13 +48,13 @@ export class UserManagementComponent implements OnChanges { private get _assignOrChangeReviewerTooltip(): string { return this.file.assignee - ? this.translateService.instant('file-preview.change-reviewer') - : this.translateService.instant('file-preview.assign-reviewer'); + ? this.translateService.instant(_('file-preview.change-reviewer')) + : this.translateService.instant(_('file-preview.assign-reviewer')); } private get _assignTooltip(): string { return this.file.isUnderApproval - ? this.translateService.instant('dossier-overview.assign-approver') + ? this.translateService.instant(_('dossier-overview.assign-approver')) : this._assignOrChangeReviewerTooltip; } diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 171d9267d..a2e1649b8 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -1654,5 +1654,13 @@ }, "title": "Watermark" }, + "workflow": { + "selection": { + "all": "All", + "count": "{count} selected", + "none": "None", + "select": "Select" + } + }, "yesterday": "Yesterday" } diff --git a/libs/common-ui b/libs/common-ui index 4a27531b8..2d2cd9fcd 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 4a27531b8e52cea707909f5d93f68b303e587945 +Subproject commit 2d2cd9fcdaaa07877bfe0b04d36a7d924c0b338a diff --git a/package.json b/package.json index e83d5259c..e2eda5c03 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "@angular/cli": "13.0.3", "@angular/compiler-cli": "13.0.2", "@angular/language-service": "13.0.2", - "@biesbjerg/ngx-translate-extract": "^7.0.4", "@nrwl/cli": "13.2.3", "@nrwl/cypress": "13.2.3", "@nrwl/eslint-plugin-nx": "13.2.3", @@ -84,6 +83,7 @@ "@typescript-eslint/eslint-plugin": "4.33.0", "@typescript-eslint/parser": "4.33.0", "axios": "^0.24.0", + "@bartholomej/ngx-translate-extract": "^8.0.1", "cypress": "^6.9.1", "cypress-file-upload": "^5.0.8", "cypress-keycloak": "^1.7.0", diff --git a/yarn.lock b/yarn.lock index 9f5bfadbc..6e6bb5530 100644 --- a/yarn.lock +++ b/yarn.lock @@ -225,7 +225,7 @@ tslib "^2.3.0" yargs "^17.2.1" -"@angular/compiler@13.0.2": +"@angular/compiler@13.0.2", "@angular/compiler@^13.0.2": version "13.0.2" resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-13.0.2.tgz#5bc1bfc1931f1ff2813f8fff8b8ceaa57b47d717" integrity sha512-EvIFT8y5VNICrnPgiamv/z9hfQ7KjLCM52g4ssXGCeGPVj58OEfslEc3jO4BCJG7xuLm7dCuSRV0pBlJNTSYFg== @@ -1283,6 +1283,23 @@ "@babel/helper-validator-identifier" "^7.15.7" to-fast-properties "^2.0.0" +"@bartholomej/ngx-translate-extract@^8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@bartholomej/ngx-translate-extract/-/ngx-translate-extract-8.0.1.tgz#4d9cc6ffbc2ce7f34d88cd15b28da2f382f58f43" + integrity sha512-mf/G8Xjz865xjLekZ6U0q5g6BO9ZF++tn3bDs1bPPOAKCw2BjBmwbMOftfGOdHYrVcSTa0yl2sqafZqYa4+waA== + dependencies: + "@angular/compiler" "^13.0.2" + "@phenomnomnominal/tsquery" "^4.1.1" + boxen "^6.2.1" + colorette "^2.0.16" + flat "^5.0.2" + gettext-parser "^4.2.0" + glob "^7.2.0" + mkdirp "^1.0.4" + path "^0.12.7" + terminal-link "^3.0.0" + yargs "^17.2.1" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1295,22 +1312,6 @@ dependencies: tslib "^1.9.0" -"@biesbjerg/ngx-translate-extract@^7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@biesbjerg/ngx-translate-extract/-/ngx-translate-extract-7.0.4.tgz#98190aa798dfe78a9f33904256891e76634fd52c" - integrity sha512-33hR94Fu26LK7Z+ImW2IdZiHfOcAzyIs1CdkUXg/536z2MqxBYqPoI9Ghsk6RTEfnsGa65wMgOcDXn7Ilhp8ew== - dependencies: - "@phenomnomnominal/tsquery" "^4.1.1" - boxen "^5.0.1" - colorette "^1.2.2" - flat "^5.0.2" - gettext-parser "^4.0.4" - glob "^7.1.6" - mkdirp "^1.0.4" - path "^0.12.7" - terminal-link "^2.1.1" - yargs "^16.2.0" - "@cspotcode/source-map-consumer@0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" @@ -2792,7 +2793,7 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" -ansi-align@^3.0.0: +ansi-align@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== @@ -2816,6 +2817,13 @@ ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" +ansi-escapes@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-5.0.0.tgz#b6a0caf0eef0c41af190e9a749e0c00ec04bb2a6" + integrity sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA== + dependencies: + type-fest "^1.0.2" + ansi-gray@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" @@ -2872,6 +2880,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3" + integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== + ansi-wrap@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -3377,19 +3390,19 @@ boolbase@^1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= -boxen@^5.0.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== +boxen@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-6.2.1.tgz#b098a2278b2cd2845deef2dff2efc38d329b434d" + integrity sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw== dependencies: - ansi-align "^3.0.0" + ansi-align "^3.0.1" camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" + chalk "^4.1.2" + cli-boxes "^3.0.0" + string-width "^5.0.1" + type-fest "^2.5.0" + widest-line "^4.0.1" + wrap-ansi "^8.0.1" brace-expansion@^1.1.7: version "1.1.11" @@ -3747,7 +3760,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -3862,10 +3875,10 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +cli-boxes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" + integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g== cli-cursor@^1.0.2: version "1.0.2" @@ -4008,11 +4021,6 @@ color-support@^1.1.2, color-support@^1.1.3: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -colorette@^1.2.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" - integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== - colorette@^2.0.10, colorette@^2.0.16: version "2.0.16" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" @@ -5173,6 +5181,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -6628,7 +6641,7 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -gettext-parser@^4.0.4: +gettext-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-4.2.0.tgz#9327140f76b122d44f0e8cb9338fd855667d9434" integrity sha512-aMgPyjC9W5Mz9tbFU8DcQ7GYMXoFWq633kaWGt4imlcpBWzDIWk7HY7nCSZTCJxyjRaLq9L/NEjMKkZ9gR630Q== @@ -6677,7 +6690,7 @@ glob@7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.2.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@7.2.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -7465,6 +7478,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + is-generator-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" @@ -12128,7 +12146,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12145,6 +12163,15 @@ string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.0.1.tgz#0d8158335a6cfd8eb95da9b6b262ce314a036ffd" + integrity sha512-5ohWO/M4//8lErlUUtrFy3b11GtNOuMOU0ysKCDXFcfXuuvUXu95akgj/i8ofmaGdN0hCqyl6uu9i8dS/mQp5g== + dependencies: + emoji-regex "^9.2.2" + is-fullwidth-code-point "^4.0.0" + strip-ansi "^7.0.1" + string.prototype.padend@^3.0.0: version "3.1.3" resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1" @@ -12212,7 +12239,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.0: +strip-ansi@^7.0.0, strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== @@ -12324,7 +12351,7 @@ supports-color@^8.0.0, supports-color@^8.1.1: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^2.0.0: +supports-hyperlinks@^2.0.0, supports-hyperlinks@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== @@ -12393,7 +12420,7 @@ tar@^6.0.2, tar@^6.1.0, tar@^6.1.2: mkdirp "^1.0.3" yallist "^4.0.0" -terminal-link@^2.0.0, terminal-link@^2.1.1: +terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== @@ -12401,6 +12428,14 @@ terminal-link@^2.0.0, terminal-link@^2.1.1: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" +terminal-link@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-3.0.0.tgz#91c82a66b52fc1684123297ce384429faf72ac5c" + integrity sha512-flFL3m4wuixmf6IfhFJd1YPiLiMuxEc8uHRM1buzIeZPm22Au2pDqBJQgdo7n1WfPU1ONFGv7YDwpFBmHGF6lg== + dependencies: + ansi-escapes "^5.0.0" + supports-hyperlinks "^2.2.0" + terser-webpack-plugin@^1.4.3: version "1.4.5" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" @@ -12761,6 +12796,16 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +type-fest@^1.0.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== + +type-fest@^2.5.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.8.0.tgz#39d7c9f9c508df8d6ce1cf5a966b0e6568dcc50d" + integrity sha512-O+V9pAshf9C6loGaH0idwsmugI2LxVNR7DtS40gVo2EXZVYFgz9OuNtOhgHLdHdapOEWNdvz9Ob/eeuaWwwlxA== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -13321,12 +13366,12 @@ wide-align@^1.1.2: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== +widest-line@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" + integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig== dependencies: - string-width "^4.0.0" + string-width "^5.0.1" wildcard@^2.0.0: version "2.0.0" @@ -13371,6 +13416,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.0.1.tgz#2101e861777fec527d0ea90c57c6b03aac56a5b3" + integrity sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" From c86237e074a76c8e8fae7e27c84d93f220bc8dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Thu, 2 Dec 2021 01:53:30 +0200 Subject: [PATCH 03/10] Some fixes, workflow bulk actions WIP --- ...ssier-overview-bulk-actions.component.html | 78 +------ ...dossier-overview-bulk-actions.component.ts | 221 ++++++++++++------ .../dossier-overview-screen.component.html | 4 +- .../file-actions/file-actions.component.ts | 1 + libs/common-ui | 2 +- 5 files changed, 153 insertions(+), 153 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html index 73b1f5890..b1147ec9b 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html @@ -1,78 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - + + diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts index 3fbf84edc..21aedf4b5 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts @@ -1,16 +1,16 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import { Dossier, File } from '@red/domain'; import { FileAssignService } from '../../../../shared/services/file-assign.service'; import { DossiersDialogService } from '../../../../services/dossiers-dialog.service'; -import { CircleButtonTypes, ConfirmationDialogInput, LoadingService, Required } from '@iqser/common-ui'; -import { TranslateService } from '@ngx-translate/core'; +import { CircleButtonType, CircleButtonTypes, ConfirmationDialogInput, LoadingService, 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 { Action, ActionTypes } from '@shared/components/expandable-file-actions/types'; @Component({ selector: 'redaction-dossier-overview-bulk-actions', @@ -18,11 +18,26 @@ import { FilesService } from '@services/entity-services/files.service'; styleUrls: ['./dossier-overview-bulk-actions.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class DossierOverviewBulkActionsComponent { - readonly circleButtonTypes = CircleButtonTypes; +export class DossierOverviewBulkActionsComponent implements OnChanges { @Input() @Required() dossier: Dossier; @Input() @Required() selectedFiles: File[]; + @Input() buttonType: CircleButtonType = CircleButtonTypes.dark; + analysisForced: boolean; + canAssignToSelf: boolean; + canAssign: boolean; + canDelete: boolean; + canReanalyse: boolean; + canOcr: boolean; + canSetToUnderReview: boolean; + canSetToUnderApproval: boolean; + isReadyForApproval: boolean; + canApprove: boolean; + canUndoApproval: boolean; + assignTooltip: string; + buttons: Action[]; + + private _canMoveToSameState: boolean; constructor( private readonly _dialogService: DossiersDialogService, @@ -31,81 +46,95 @@ export class DossierOverviewBulkActionsComponent { private readonly _permissionsService: PermissionsService, private readonly _fileAssignService: FileAssignService, private readonly _loadingService: LoadingService, - private readonly _translateService: TranslateService, private readonly _userPreferenceService: UserPreferenceService, private readonly _filesService: FilesService, ) {} - get allSelectedFilesCanBeAssignedIntoSameState() { - const allFilesAreUnderReviewOrUnassigned = this.selectedFiles.reduce( - (acc, file) => acc && (file.isUnderReview || file.isNew), - true, - ); - const allFilesAreUnderApproval = this.selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true); - return allFilesAreUnderReviewOrUnassigned || allFilesAreUnderApproval; + private get _buttons(): Action[] { + return [ + { + type: ActionTypes.circleBtn, + action: () => this._delete(), + tooltip: _('dossier-overview.bulk.delete'), + icon: 'iqser:trash', + show: this.canDelete, + }, + { + type: ActionTypes.circleBtn, + action: () => this._assign(), + tooltip: this.assignTooltip, + icon: 'red:assign', + show: this.canAssign, + }, + { + type: ActionTypes.circleBtn, + action: () => this._assignToMe(), + tooltip: _('dossier-overview.assign-me'), + icon: 'red:assign-me', + show: this.canAssignToSelf, + }, + { + type: ActionTypes.circleBtn, + action: () => this._setToUnderApproval(), + tooltip: _('dossier-overview.under-approval'), + icon: 'red:ready-for-approval', + show: this.canSetToUnderApproval, + }, + { + type: ActionTypes.circleBtn, + action: () => this._setToUnderReview(), + tooltip: _('dossier-overview.under-review'), + icon: 'red:undo', + show: this.canSetToUnderReview, + }, + { + type: ActionTypes.downloadBtn, + show: true, + files: this.selectedFiles, + disabled: !this._permissionsService.canDownloadFiles(this.selectedFiles), + }, + { + type: ActionTypes.circleBtn, + action: () => this._approveDocuments(), + disabled: !this.canApprove, + tooltip: this.canApprove ? _('dossier-overview.approve') : _('dossier-overview.approve-disabled'), + icon: 'red:approved', + show: this.isReadyForApproval, + }, + { + type: ActionTypes.circleBtn, + action: () => this._setToUnderApproval(), + tooltip: _('dossier-overview.under-approval'), + icon: 'red:undo', + show: this.canUndoApproval, + }, + { + type: ActionTypes.circleBtn, + action: () => this._ocr(), + tooltip: _('dossier-overview.ocr-file'), + icon: 'iqser:ocr', + show: this.canOcr, + }, + { + type: ActionTypes.circleBtn, + action: () => this._reanalyse(), + tooltip: _('dossier-overview.bulk.reanalyse'), + icon: 'iqser:refresh', + show: this.canReanalyse && this.analysisForced, + }, + ].filter(btn => btn.show); } - get canAssignToSelf() { - return ( - this.allSelectedFilesCanBeAssignedIntoSameState && - this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignToSelf(file), true) - ); - } - - get canAssign() { - return ( - this.allSelectedFilesCanBeAssignedIntoSameState && - this.selectedFiles.reduce( - (acc, file) => (acc && this._permissionsService.canAssignUser(file)) || this._permissionsService.canUnassignUser(file), - true, - ) - ); - } - - get canDelete() { - return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canDeleteFile(file), true); - } - - get canReanalyse() { - return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canReanalyseFile(file), true); - } - - get canOcr() { - return this.selectedFiles.reduce((acc, file) => acc && file.canBeOCRed, true); - } - - get canSetToUnderReview() { - return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderReview(file), true); - } - - get canSetToUnderApproval() { - return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderApproval(file), true); - } - - get isReadyForApproval() { - return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.isReadyForApproval(file), true); - } - - get canApprove() { - return this.selectedFiles.reduce((acc, file) => acc && file.canBeApproved, true); - } - - get canUndoApproval() { - return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canUndoApproval(file), true); - } - - get assignTooltip() { - const allFilesAreUnderApproval = this.selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true); - return allFilesAreUnderApproval - ? this._translateService.instant('dossier-overview.assign-approver') - : this._translateService.instant('dossier-overview.assign-reviewer'); + ngOnChanges() { + this._setup(); } forceReanalysisAction($event: LongPressEvent) { this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled; + this._setup(); } - delete() { + private _delete() { this._dialogService.openDialog( 'confirm', null, @@ -126,7 +155,7 @@ export class DossierOverviewBulkActionsComponent { ); } - async setToUnderApproval() { + 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); @@ -143,14 +172,14 @@ export class DossierOverviewBulkActionsComponent { } } - async reanalyse() { + 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(); } - async ocr() { + private async _ocr() { this._loadingService.start(); await this._reanalysisService .ocrFiles( @@ -161,7 +190,7 @@ export class DossierOverviewBulkActionsComponent { this._loadingService.stop(); } - async setToUnderReview() { + private async _setToUnderReview() { this._loadingService.start(); await this._filesService .setUnderReviewFor( @@ -172,7 +201,7 @@ export class DossierOverviewBulkActionsComponent { this._loadingService.stop(); } - async approveDocuments(): Promise { + private async _approveDocuments(): Promise { const foundUpdatedFile = this.selectedFiles.find(file => file.hasUpdates); if (foundUpdatedFile) { this._dialogService.openDialog( @@ -205,15 +234,57 @@ export class DossierOverviewBulkActionsComponent { } } - async assignToMe() { + private async _assignToMe() { await this._fileAssignService.assignToMe(this.selectedFiles); } - assign() { + 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), + true, + ); + this.canAssignToSelf = + this._canMoveToSameState && + this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignToSelf(file), true); + + this.canDelete = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canDeleteFile(file), true); + + this.canReanalyse = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canReanalyseFile(file), true); + + this.canOcr = this.selectedFiles.reduce((acc, file) => acc && file.canBeOCRed, true); + + this.canSetToUnderReview = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderReview(file), true); + + this.canSetToUnderApproval = this.selectedFiles.reduce( + (acc, file) => acc && this._permissionsService.canSetUnderApproval(file), + true, + ); + + this.isReadyForApproval = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.isReadyForApproval(file), true); + + this.canApprove = this.selectedFiles.reduce((acc, file) => acc && file.canBeApproved, true); + + this.canUndoApproval = this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canUndoApproval(file), true); + + this.assignTooltip = allFilesAreUnderApproval ? _('dossier-overview.assign-approver') : _('dossier-overview.assign-reviewer'); + + this.buttons = this._buttons; + } + private _assignFiles(mode: 'reviewer' | 'approver', ignoreChanged = false) { const data = { mode, files: this.selectedFiles, ignoreChanged }; this._dialogService.openDialog('assignFile', null, data); diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html index 042e26b51..9be2ad255 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html @@ -32,6 +32,7 @@ (noDataAction)="fileInput.click()" *ngIf="mode === listingModes.workflow" [addElementIcon]="'iqser:upload'" + [bulkActions]="bulkActions" [config]="workflowConfig" [itemClasses]="{ disabled: disabledFn }" [itemTemplate]="workflowItemTemplate" @@ -55,8 +56,9 @@ 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 e429341a8..c389b5f2b 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 @@ -261,6 +261,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, forceReanalysisAction($event: LongPressEvent) { this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled; + this._setup(); } private _openDocument() { diff --git a/libs/common-ui b/libs/common-ui index 2d2cd9fcd..ea2d5fc69 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 2d2cd9fcdaaa07877bfe0b04d36a7d924c0b338a +Subproject commit ea2d5fc69b114ee9a8d117f55865a34e2efc0303 From 5886b34d9bb9c2935e463c352e1b42685d8ec12d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Thu, 2 Dec 2021 02:21:38 +0200 Subject: [PATCH 04/10] Reset selection on view mode change --- .../view-mode-selection.component.html | 4 ++-- .../view-mode-selection.component.ts | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/view-mode-selection/view-mode-selection.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/view-mode-selection/view-mode-selection.component.html index 1ce54287c..9df37d5f9 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/view-mode-selection/view-mode-selection.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/view-mode-selection/view-mode-selection.component.html @@ -2,7 +2,7 @@
) {} + + setListingMode(listingMode: ListingMode): void { + this.configService.listingMode = listingMode; + this._listingService.setSelected([]); + } } From 37bd733fbfa8747a63f0241ddded1deb72599b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Thu, 2 Dec 2021 03:38:36 +0200 Subject: [PATCH 05/10] Workflow bulk actions --- ...ssier-overview-bulk-actions.component.html | 2 +- ...dossier-overview-bulk-actions.component.ts | 2 +- .../dossier-overview-screen.component.html | 3 +- .../file-actions/file-actions.component.ts | 1 - .../expandable-file-actions.component.ts | 33 +++++++++++++++++-- libs/common-ui | 2 +- 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html index b1147ec9b..2514ba77b 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html @@ -1,4 +1,4 @@ - + diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts index 21aedf4b5..060e4c237 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts @@ -22,6 +22,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { @Input() @Required() dossier: Dossier; @Input() @Required() selectedFiles: File[]; @Input() buttonType: CircleButtonType = CircleButtonTypes.dark; + @Input() maxWidth: number; analysisForced: boolean; canAssignToSelf: boolean; @@ -91,7 +92,6 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { type: ActionTypes.downloadBtn, show: true, files: this.selectedFiles, - disabled: !this._permissionsService.canDownloadFiles(this.selectedFiles), }, { type: ActionTypes.circleBtn, diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html index 9be2ad255..f59df8959 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html @@ -54,10 +54,11 @@ - + 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 c389b5f2b..09031d88c 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 @@ -148,7 +148,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, show: true, files: [this.file], tooltipClass: 'small', - disabled: !this._permissionsService.canDownloadFiles([this.file]), }, { type: ActionTypes.circleBtn, 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 318ecab8d..454fd9242 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 @@ -1,6 +1,10 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; -import { Action } from './types'; -import { CircleButtonType, IqserTooltipPosition } from '@iqser/common-ui'; +import { Action, ActionTypes } from './types'; +import { CircleButtonType, IqserTooltipPosition, Toaster } from '@iqser/common-ui'; +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { File } from '@red/domain'; +import { FileDownloadService } from '@upload-download/services/file-download.service'; +import { PermissionsService } from '@services/permissions.service'; @Component({ selector: 'redaction-expandable-file-actions', @@ -18,10 +22,16 @@ export class ExpandableFileActionsComponent implements OnChanges { hiddenButtons: Action[]; expanded = false; + constructor( + private readonly _fileDownloadService: FileDownloadService, + private readonly _toaster: Toaster, + private readonly _permissionsService: PermissionsService, + ) {} + ngOnChanges(changes: SimpleChanges) { if (changes.actions || changes.maxWidth) { if (this.maxWidth) { - const count = Math.floor(this.maxWidth / 36); + const count = Math.floor(this.maxWidth / 36) || 1; if (count >= this.actions.length) { this.displayedButtons = [...this.actions]; this.hiddenButtons = []; @@ -34,5 +44,22 @@ export class ExpandableFileActionsComponent implements OnChanges { this.hiddenButtons = []; } } + + if (changes.actions) { + // Patch download button + const downloadBtn = this.actions.find(btn => btn.type === ActionTypes.downloadBtn); + if (downloadBtn) { + downloadBtn.action = $event => this._downloadFiles($event, downloadBtn.files); + downloadBtn.disabled = !this._permissionsService.canDownloadFiles(downloadBtn.files); + } + } + } + + private async _downloadFiles($event: MouseEvent, files: File[]) { + $event.stopPropagation(); + const dossierId = files[0].dossierId; + const filesIds = files.map(f => f.fileId); + await this._fileDownloadService.downloadFiles(filesIds, dossierId).toPromise(); + this._toaster.info(_('download-status.queued')); } } diff --git a/libs/common-ui b/libs/common-ui index ea2d5fc69..67ae38160 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit ea2d5fc69b114ee9a8d117f55865a34e2efc0303 +Subproject commit 67ae381607fa946231e44c2946a66bef1b13498f From 067b67efd060667deeb399249d28c9932b8803fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 6 Dec 2021 04:09:11 +0200 Subject: [PATCH 06/10] More workflow updates (multi drag almost done) --- .../dossier-overview-bulk-actions.component.ts | 3 +-- .../workflow-item/workflow-item.component.html | 2 +- .../file-actions/file-actions.component.ts | 16 +--------------- .../expandable-file-actions.component.html | 2 +- .../expandable-file-actions.component.ts | 3 +-- apps/red-ui/src/assets/i18n/en.json | 1 - libs/common-ui | 2 +- .../src/lib/shared/expandable-file-actions.ts | 2 +- libs/red-domain/src/lib/shared/index.ts | 1 + 9 files changed, 8 insertions(+), 24 deletions(-) rename apps/red-ui/src/app/modules/shared/components/expandable-file-actions/types.ts => libs/red-domain/src/lib/shared/expandable-file-actions.ts (94%) diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts index 060e4c237..445aa6a8e 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; -import { Dossier, File } from '@red/domain'; +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'; @@ -10,7 +10,6 @@ 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 { Action, ActionTypes } from '@shared/components/expandable-file-actions/types'; @Component({ selector: 'redaction-dossier-overview-bulk-actions', diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html index 3b0eaa732..ec7481294 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html @@ -1,7 +1,7 @@
-
+
{{ file.filename }}
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 09031d88c..f13b86b1a 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 @@ -12,7 +12,7 @@ import { ViewChild, } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; -import { File } from '@red/domain'; +import { Action, ActionTypes, File } from '@red/domain'; import { DossiersDialogService } from '../../../services/dossiers-dialog.service'; import { AutoUnsubscribe, @@ -37,7 +37,6 @@ import { Router } from '@angular/router'; import { ExcludedPagesService } from '../../../screens/file-preview-screen/services/excluded-pages.service'; import { tap } from 'rxjs/operators'; import { DocumentInfoService } from '../../../screens/file-preview-screen/services/document-info.service'; -import { Action, ActionTypes } from '@shared/components/expandable-file-actions/types'; import { ExpandableFileActionsComponent } from '@shared/components/expandable-file-actions/expandable-file-actions.component'; @Component({ @@ -115,13 +114,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, private get _buttons(): Action[] { return [ - { - type: ActionTypes.circleBtn, - action: () => this._openDocument(), - tooltip: _('dossier-overview.open-document'), - icon: 'iqser:collapse', - show: this.showOpenDocument, - }, { type: ActionTypes.circleBtn, action: $event => this._openDeleteFileDialog($event), @@ -263,10 +255,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, this._setup(); } - private _openDocument() { - this._router.navigate([this.file.routerLink]).then(); - } - private _openDeleteFileDialog($event: MouseEvent) { this._dialogService.openDialog( 'confirm', @@ -361,8 +349,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, (this._permissionsService.canAssignUser(this.file) || this._permissionsService.canUnassignUser(this.file)) && this.isDossierOverview; - this.showOpenDocument = this.file.canBeOpened && this.isDossierOverviewWorkflow; - this.showReanalyseFilePreview = this.canReanalyse && this.isFilePreview && this.analysisForced; this.showReanalyseDossierOverview = this.canReanalyse && this.isDossierOverview && this.analysisForced; 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 330b08556..5dda8405a 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 @@ -41,7 +41,7 @@ (menuOpened)="expanded = true" *ngIf="hiddenButtons.length > 0" [attr.aria-expanded]="expanded" - [icon]="'iqser:plus'" + [icon]="'iqser:more-actions'" [matMenuTriggerFor]="hiddenButtonsMenu" [type]="buttonType" > 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 454fd9242..1ccc95efe 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 @@ -1,8 +1,7 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; -import { Action, ActionTypes } from './types'; +import { Action, ActionTypes, File } from '@red/domain'; import { CircleButtonType, IqserTooltipPosition, Toaster } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { File } from '@red/domain'; import { FileDownloadService } from '@upload-download/services/file-download.service'; import { PermissionsService } from '@services/permissions.service'; diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index a2e1649b8..f81c13f51 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -728,7 +728,6 @@ }, "ocr-file": "OCR Document", "ocr-performed": "OCR was performed for this file.", - "open-document": "Open Document", "quick-filters": { "assigned-to-me": "Assigned to me", "assigned-to-others": "Assigned to others", diff --git a/libs/common-ui b/libs/common-ui index 6286eea9d..4c119e2a7 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 6286eea9dbfbf4f34de8da4c5ad486e555c99af7 +Subproject commit 4c119e2a7870d0778457d22d50ac380316c68e29 diff --git a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/types.ts b/libs/red-domain/src/lib/shared/expandable-file-actions.ts similarity index 94% rename from apps/red-ui/src/app/modules/shared/components/expandable-file-actions/types.ts rename to libs/red-domain/src/lib/shared/expandable-file-actions.ts index fe73bfd0b..f53c95fe0 100644 --- a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/types.ts +++ b/libs/red-domain/src/lib/shared/expandable-file-actions.ts @@ -11,7 +11,7 @@ export const ActionTypes = { }; export interface Action { - action?: Function; + action?: (...args: any[]) => void; tooltip?: string; icon?: string; show?: boolean; diff --git a/libs/red-domain/src/lib/shared/index.ts b/libs/red-domain/src/lib/shared/index.ts index 3da2cbc13..585848bd6 100644 --- a/libs/red-domain/src/lib/shared/index.ts +++ b/libs/red-domain/src/lib/shared/index.ts @@ -4,3 +4,4 @@ export * from './rules'; export * from './watermark'; export * from './default-color-type'; export * from './view-mode'; +export * from './expandable-file-actions'; From 0373f1a7b96bb950a4cbe16a63a7a2f87c6365c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 6 Dec 2021 15:21:29 +0200 Subject: [PATCH 07/10] Fix some stuff, break other stuff --- .../workflow-item.component.html | 20 +++-- .../workflow-item.component.scss | 80 ++++++++++--------- .../workflow-item/workflow-item.component.ts | 25 +++++- .../dossier-overview/config.service.ts | 2 +- .../dossier-overview-screen.component.html | 4 +- .../file-download-btn.component.html | 2 +- .../file-download-btn.component.ts | 20 ++--- libs/common-ui | 2 +- 8 files changed, 91 insertions(+), 64 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html index ec7481294..a5f36933f 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html @@ -1,5 +1,5 @@
-
+
{{ file.filename }} @@ -20,11 +20,17 @@
- +
+ +
+ +
+ +
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss index 74a119427..60fd71e08 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss @@ -3,42 +3,6 @@ .workflow-item { padding: 10px 10px 8px 10px; - > div { - display: flex; - justify-content: space-between; - - .details { - max-width: calc(100% - 28px); - - .filename { - font-weight: 600; - line-height: 18px; - @include common-mixins.line-clamp(1); - } - } - - .user { - display: flex; - align-items: flex-end; - } - } - - redaction-file-workload { - margin-top: 10px; - display: block; - min-height: 16px; - } - - .file-actions { - margin-top: 8px; - min-height: 34px; - overflow: hidden; - } - - redaction-file-actions:not(.keep-visible) { - display: none; - } - &:hover .filename { text-decoration: underline; } @@ -48,6 +12,50 @@ } } +.details-wrapper { + display: flex; + justify-content: space-between; + + .details { + max-width: calc(100% - 28px); + + .filename { + font-weight: 600; + line-height: 18px; + @include common-mixins.line-clamp(1); + } + } + + .user { + display: flex; + align-items: flex-end; + } +} + +redaction-file-workload { + margin-top: 10px; + display: block; + min-height: 16px; +} + +.file-actions { + margin-top: 8px; + min-height: 34px; + overflow: hidden; + align-items: center; + display: flex; +} + +.actions-wrapper { + border: 1px solid; + overflow: hidden; + flex: 1; +} + +redaction-file-actions:not(.keep-visible) { + //display: none; +} + .mt-4 { margin-top: 4px; } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts index b7b4c79d2..7c3916b84 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts @@ -1,6 +1,6 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { File, IFileAttributeConfig } from '@red/domain'; -import { Required } from '@iqser/common-ui'; +import { Debounce, Required } from '@iqser/common-ui'; @Component({ selector: 'redaction-workflow-item', @@ -8,8 +8,25 @@ import { Required } from '@iqser/common-ui'; styleUrls: ['./workflow-item.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class WorkflowItemComponent { +export class WorkflowItemComponent implements OnInit { @Input() @Required() file!: File; @Input() @Required() displayedAttributes!: IFileAttributeConfig[]; - @Input() width: number; + width: number; + + @ViewChild('actionsWrapper', { static: true }) private _actionsWrapper: ElementRef; + + constructor(private readonly _changeRef: ChangeDetectorRef) {} + + ngOnInit(): void { + const _observer = new ResizeObserver((entries: ResizeObserverEntry[]) => { + this._updateItemWidth(entries[0]); + }); + _observer.observe(this._actionsWrapper.nativeElement); + } + + @Debounce(30) + private _updateItemWidth(entry: ResizeObserverEntry): void { + this.width = entry.contentRect.width; + this._changeRef.detectChanges(); + } } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts index e00b5d3a9..72e1ac733 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts @@ -32,7 +32,7 @@ import { noop } from 'lodash'; @Injectable() export class ConfigService { readonly listingMode$: Observable; - private readonly _listingMode$ = new BehaviorSubject(ListingModes.table); + private readonly _listingMode$ = new BehaviorSubject(ListingModes.workflow); constructor( private readonly _fileAssignService: FileAssignService, diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html index f59df8959..1010b0c02 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html @@ -78,6 +78,6 @@ - - + + diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.html b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.html index d006ab32c..87eb0a2a2 100644 --- a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.html +++ b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.html @@ -3,7 +3,7 @@ [disabled]="disabled || !canDownloadFiles" [tooltipClass]="tooltipClass" [tooltipPosition]="tooltipPosition" - [tooltip]="tooltip" + [tooltip]="tooltip | translate: { count: this.files.length }" [type]="type" icon="iqser:download" > 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 97645d398..2a3f107ab 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,9 +1,8 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import { File } from '@red/domain'; import { FileDownloadService } from '@upload-download/services/file-download.service'; import { CircleButtonType, CircleButtonTypes, Toaster } from '@iqser/common-ui'; -import { TranslateService } from '@ngx-translate/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; export type MenuState = 'OPEN' | 'CLOSED'; @@ -14,28 +13,25 @@ export type MenuState = 'OPEN' | 'CLOSED'; styleUrls: ['./file-download-btn.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class FileDownloadBtnComponent { +export class FileDownloadBtnComponent implements OnChanges { @Input() files: File[]; @Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above'; @Input() type: CircleButtonType = CircleButtonTypes.default; @Input() tooltipClass: string; @Input() disabled = false; + tooltip: string; + canDownloadFiles: boolean; + constructor( private readonly _permissionsService: PermissionsService, private readonly _fileDownloadService: FileDownloadService, private readonly _toaster: Toaster, - private readonly _translateService: TranslateService, ) {} - get canDownloadFiles() { - return this._permissionsService.canDownloadFiles(this.files); - } - - get tooltip() { - return this.canDownloadFiles - ? this._translateService.instant('dossier-overview.download-file') - : this._translateService.instant('dossier-overview.download-file-disabled', { count: this.files.length }); + ngOnChanges(): void { + this.canDownloadFiles = this._permissionsService.canDownloadFiles(this.files); + this.tooltip = this.canDownloadFiles ? _('dossier-overview.download-file') : _('dossier-overview.download-file-disabled'); } async downloadFiles($event: MouseEvent) { diff --git a/libs/common-ui b/libs/common-ui index 4c119e2a7..7ec9b548f 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 4c119e2a7870d0778457d22d50ac380316c68e29 +Subproject commit 7ec9b548fa77f9ce36b285626b702efb8981bb39 From 722cf6dc262f55991d54cd7137023f4fa857a464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Tue, 7 Dec 2021 05:15:27 +0200 Subject: [PATCH 08/10] Minor updates --- .../components/workflow-item/workflow-item.component.html | 7 ++++++- .../components/workflow-item/workflow-item.component.scss | 3 +-- libs/common-ui | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html index a5f36933f..a16491ed7 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.html @@ -20,7 +20,12 @@
-
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss index 60fd71e08..9468a2610 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss @@ -47,13 +47,12 @@ redaction-file-workload { } .actions-wrapper { - border: 1px solid; overflow: hidden; flex: 1; } redaction-file-actions:not(.keep-visible) { - //display: none; + display: none; } .mt-4 { diff --git a/libs/common-ui b/libs/common-ui index 7ec9b548f..276b202f6 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 7ec9b548fa77f9ce36b285626b702efb8981bb39 +Subproject commit 276b202f6a390155b27d4dab9317dc2b1e3506f2 From 5c2f8ed0843416bb97138ff312bab22da90ffa3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Tue, 7 Dec 2021 16:00:39 +0200 Subject: [PATCH 09/10] Updated common --- libs/common-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common-ui b/libs/common-ui index 276b202f6..567de98f3 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 276b202f6a390155b27d4dab9317dc2b1e3506f2 +Subproject commit 567de98f30d622c6bbc9a47d87a784c7aa36055f From 02da8e5a02e7d414550900e66acecf58f1ad9692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Wed, 8 Dec 2021 00:21:55 +0200 Subject: [PATCH 10/10] File bulk actions service, permissions for multiple files, workflow done --- ...sign-reviewer-approver-dialog.component.ts | 2 +- ...dossier-overview-bulk-actions.component.ts | 196 ++++-------------- .../dossier-overview/config.service.ts | 62 ++---- .../dossier-overview.module.ts | 3 +- .../services/bulk-actions.service.ts | 140 +++++++++++++ .../user-management.component.ts | 6 +- .../src/app/services/permissions.service.ts | 126 +++++++---- .../src/app/services/reanalysis.service.ts | 4 +- libs/common-ui | 2 +- 9 files changed, 295 insertions(+), 246 deletions(-) create mode 100644 apps/red-ui/src/app/modules/dossier/screens/dossier-overview/services/bulk-actions.service.ts 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 b5863f77e..27757ca3e 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 @@ -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: diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts index 445aa6a8e..633791158 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts @@ -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 { - 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; + } } } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts index 72e1ac733..77a6b107e 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts @@ -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; - private readonly _listingMode$ = new BehaviorSubject(ListingModes.workflow); + private readonly _listingMode$ = new BehaviorSubject(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(); - }; } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts index c9382a62a..57f081d3b 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts @@ -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 {} diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/services/bulk-actions.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/services/bulk-actions.service.ts new file mode 100644 index 000000000..40aed1fe3 --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/services/bulk-actions.service.ts @@ -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 { + this._loadingService.start(); + await this._filesService + .setUnderReviewFor( + files.map(f => f.id), + files[0].dossierId, + ) + .toPromise(); + this._loadingService.stop(); + } + + async approve(files: File[]): Promise { + 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 }); + } +} diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/user-management/user-management.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/user-management/user-management.component.ts index 6ec0a7db8..fdbe6d8f3 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/user-management/user-management.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/user-management/user-management.component.ts @@ -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; diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index d979b2ebf..6a7bfbbee 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -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); } diff --git a/apps/red-ui/src/app/services/reanalysis.service.ts b/apps/red-ui/src/app/services/reanalysis.service.ts index c9802f6a6..1707aca5a 100644 --- a/apps/red-ui/src/app/services/reanalysis.service.ts +++ b/apps/red-ui/src/app/services/reanalysis.service.ts @@ -45,8 +45,8 @@ export class ReanalysisService extends GenericService { } @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() diff --git a/libs/common-ui b/libs/common-ui index 567de98f3..28a6b735f 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 567de98f30d622c6bbc9a47d87a784c7aa36055f +Subproject commit 28a6b735f700351f36c2583de4b581fe5fb8106b