diff --git a/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.ts index 7cb4a8184..0b9cbcd6c 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.ts @@ -14,7 +14,7 @@ import { RouterHistoryService } from '@services/router-history.service'; import { LicenseService } from '@services/license.service'; import { map } from 'rxjs/operators'; import { ROLES } from '@users/roles'; -import { User } from '@red/domain'; +import type { User } from '@red/domain'; @Component({ templateUrl: './license-screen.component.html', diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts b/apps/red-ui/src/app/modules/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts index a48dec4ab..443ed5c06 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts @@ -50,6 +50,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { private get _buttons(): Action[] { return [ { + id: 'delete-files-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.delete(this.selectedFiles), tooltip: _('dossier-overview.bulk.delete'), @@ -57,6 +58,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canDelete, }, { + id: 'assign-files-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.assign(this.selectedFiles), tooltip: this.#assignTooltip, @@ -64,6 +66,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canAssign, }, { + id: 'assign-files-to-me-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.assignToMe(this.selectedFiles), tooltip: _('dossier-overview.assign-me'), @@ -71,6 +74,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canAssignToSelf, }, { + id: 'to-new-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.setToNew(this.selectedFiles), tooltip: _('dossier-overview.back-to-new'), @@ -78,6 +82,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canSetToNew, }, { + id: 'to-under-approval-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.setToUnderApproval(this.selectedFiles), tooltip: _('dossier-overview.under-approval'), @@ -85,6 +90,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canSetToUnderApproval, }, { + id: 'to-under-review-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.backToUnderReview(this.selectedFiles), tooltip: _('dossier-overview.under-review'), @@ -92,12 +98,14 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canSetToUnderReview, }, { + id: 'download-files-btn', type: ActionTypes.downloadBtn, show: !this.selectedFiles.some(file => file.processingStatus === ProcessingFileStatuses.ERROR || !file.lastProcessed), files: this.selectedFiles, dossier: this.dossier, }, { + id: 'approve-files-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.approve(this.selectedFiles), disabled: !this.#canApprove, @@ -106,6 +114,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#isReadyForApproval, }, { + id: 'set-under-approval-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.setToUnderApproval(this.selectedFiles), tooltip: _('dossier-overview.under-approval'), @@ -113,6 +122,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canUndoApproval, }, { + id: 'ocr-files-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.ocr(this.selectedFiles), tooltip: _('dossier-overview.ocr-file'), @@ -120,6 +130,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canOcr, }, { + id: 'reanalyse-files-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.reanalyse(this.selectedFiles), tooltip: _('dossier-overview.bulk.reanalyse'), @@ -127,6 +138,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canReanalyse && (this.#analysisForced || this.#canEnableAutoAnalysis), }, { + id: 'stop-automatic-analysis-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.toggleAutomaticAnalysis(this.selectedFiles), tooltip: _('dossier-overview.stop-auto-analysis'), @@ -134,14 +146,15 @@ export class DossierOverviewBulkActionsComponent implements OnChanges { show: this.#canDisableAutoAnalysis, }, { + id: 'start-automatic-analysis-btn', type: ActionTypes.circleBtn, action: () => this._bulkActionsService.toggleAutomaticAnalysis(this.selectedFiles), tooltip: _('dossier-overview.start-auto-analysis'), icon: 'red:enable-analysis', show: this.#canEnableAutoAnalysis, }, - { + id: 'toggle-analysis-btn', type: ActionTypes.toggle, action: () => this._bulkActionsService.toggleAnalysis(this.selectedFiles, !this.#allFilesAreExcluded), tooltip: this.#toggleAnalysisTooltip, diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html index 6f54ab04f..1610f806f 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html +++ b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html @@ -7,6 +7,7 @@ >
this._openDeleteFileDialog($event), tooltip: _('dossier-overview.delete.action'), @@ -130,6 +130,7 @@ export class FileActionsComponent implements OnChanges { show: this.showDelete, }, { + id: 'assign-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._assign($event), tooltip: this.assignTooltip, @@ -137,6 +138,7 @@ export class FileActionsComponent implements OnChanges { show: this.showAssign, }, { + id: 'assign-to-me-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._assignToMe($event), tooltip: _('dossier-overview.assign-me'), @@ -144,6 +146,7 @@ export class FileActionsComponent implements OnChanges { show: this.showAssignToSelf, }, { + id: 'open-import-redactions-dialog-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._openImportRedactionsDialog($event), tooltip: _('dossier-overview.import-redactions'), @@ -151,6 +154,7 @@ export class FileActionsComponent implements OnChanges { show: this.showImportRedactions && !this._iqserPermissionsService.has(ROLES.getRss), }, { + id: 'download-file-btn', type: ActionTypes.downloadBtn, files: [this.file], dossier: this.dossier, @@ -159,6 +163,7 @@ export class FileActionsComponent implements OnChanges { disabled: this.file.processingStatus === ProcessingFileStatuses.ERROR, }, { + id: 'toggle-document-info-btn', type: ActionTypes.circleBtn, action: () => this._documentInfoService.toggle(), tooltip: _('file-preview.document-info'), @@ -167,6 +172,7 @@ export class FileActionsComponent implements OnChanges { show: !!this._documentInfoService, }, { + id: 'toggle-exclude-pages-btn', type: ActionTypes.circleBtn, action: () => this._excludedPagesService.toggle(), tooltip: _('file-preview.exclude-pages'), @@ -179,6 +185,7 @@ export class FileActionsComponent implements OnChanges { !this._iqserPermissionsService.has(ROLES.getRss), }, { + id: 'set-file-to-new-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._setToNew($event), tooltip: _('dossier-overview.back-to-new'), @@ -186,6 +193,7 @@ export class FileActionsComponent implements OnChanges { show: this.showSetToNew, }, { + id: 'set-file-under-approval-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._setFileUnderApproval($event), tooltip: _('dossier-overview.under-approval'), @@ -193,6 +201,7 @@ export class FileActionsComponent implements OnChanges { show: this.showUnderApproval, }, { + id: 'set-file-under-review-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._setFileUnderReview($event), tooltip: _('dossier-overview.under-review'), @@ -200,6 +209,7 @@ export class FileActionsComponent implements OnChanges { show: this.showUnderReview, }, { + id: 'set-file-approved-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this.setFileApproved($event), tooltip: this.file.canBeApproved ? _('dossier-overview.approve') : _('dossier-overview.approve-disabled'), @@ -208,6 +218,7 @@ export class FileActionsComponent implements OnChanges { show: this.showApprove, }, { + id: 'toggle-automatic-analysis-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._toggleAutomaticAnalysis($event), tooltip: _('dossier-overview.stop-auto-analysis'), @@ -215,6 +226,7 @@ export class FileActionsComponent implements OnChanges { show: this.canDisableAutoAnalysis, }, { + id: 'reanalyse-file-preview-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._reanalyseFile($event), tooltip: _('file-preview.reanalyse-notification'), @@ -224,6 +236,7 @@ export class FileActionsComponent implements OnChanges { disabled: this.file.isProcessing, }, { + id: 'toggle-automatic-analysis-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._toggleAutomaticAnalysis($event), tooltip: _('dossier-overview.start-auto-analysis'), @@ -232,6 +245,7 @@ export class FileActionsComponent implements OnChanges { show: this.canEnableAutoAnalysis, }, { + id: 'set-under-approval-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._setFileUnderApproval($event), tooltip: _('dossier-overview.under-approval'), @@ -239,6 +253,7 @@ export class FileActionsComponent implements OnChanges { show: this.showUndoApproval, }, { + id: 'ocr-file-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._ocrFile($event), tooltip: _('dossier-overview.ocr-file'), @@ -246,6 +261,7 @@ export class FileActionsComponent implements OnChanges { show: this.showOCR, }, { + id: 'reanalyse-file-btn', type: ActionTypes.circleBtn, action: ($event: MouseEvent) => this._reanalyseFile($event), tooltip: _('dossier-overview.reanalyse.action'), @@ -253,6 +269,7 @@ export class FileActionsComponent implements OnChanges { show: this.showReanalyseDossierOverview, }, { + id: 'toggle-analysis-btn', type: ActionTypes.toggle, action: () => this._toggleAnalysis(), disabled: !this.canToggleAnalysis, 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 daa4928a1..ffeba8738 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 @@ -1,9 +1,10 @@ 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 7979ca52c..b8b1f33eb 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,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; +import { Component, Input, OnChanges } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import { Dossier, File, ProcessingFileStatuses } from '@red/domain'; import { FileDownloadService } from '@upload-download/services/file-download.service'; @@ -13,9 +13,8 @@ import { import { firstValueFrom } from 'rxjs'; @Component({ - selector: 'redaction-file-download-btn [files] [dossier]', + selector: 'redaction-file-download-btn [files] [dossier] [buttonId]', templateUrl: './file-download-btn.component.html', - changeDetection: ChangeDetectionStrategy.OnPush, }) export class FileDownloadBtnComponent implements OnChanges { @Input() files: File[]; @@ -24,9 +23,11 @@ export class FileDownloadBtnComponent implements OnChanges { @Input() type: CircleButtonType = CircleButtonTypes.default; @Input() tooltipClass: string; @Input() disabled = false; + @Input() buttonId: string; tooltip: string; canDownloadFiles: boolean; + invalidDownload = false; constructor( private readonly _permissionsService: PermissionsService, @@ -35,11 +36,8 @@ export class FileDownloadBtnComponent implements OnChanges { private readonly _toaster: Toaster, ) {} - get invalidDownload() { - return this.files.some(file => file.processingStatus === ProcessingFileStatuses.ERROR); - } - ngOnChanges(): void { + this.invalidDownload = this.files.some(file => file.processingStatus === ProcessingFileStatuses.ERROR); this.canDownloadFiles = this._permissionsService.canDownloadFiles(this.files, this.dossier); this.tooltip = this.canDownloadFiles ? _('dossier-overview.download-file') : _('dossier-overview.download-file-disabled'); } @@ -55,12 +53,13 @@ export class FileDownloadBtnComponent implements OnChanges { return; } - await this._fileDownloadService - .downloadFiles({ - dossierId: this.dossier.id, - fileIds: this.files.map(f => f.id), - ...result, - }) + const downloadRequest = this._fileDownloadService.downloadFiles({ + dossierId: this.dossier.id, + fileIds: this.files.map(f => f.id), + ...result, + }); + + await downloadRequest .then(() => this._toaster.info(_('download-status.queued'))) .catch(() => this._toaster.error(_('download-status.error'))); } 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 40857cf4e..39f50ccd1 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 @@ -1,4 +1,4 @@ - + {{ btn.tooltip | translate }} + {{ 'dossier-overview.download-file' | translate }} + {{ btn.tooltip | translate }} 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 40ed0f46f..872e16569 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,6 @@ -import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core'; +import { Component, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core'; import { Action, ActionTypes, Dossier, File } from '@red/domain'; -import { CircleButtonType, defaultDialogConfig, IqserTooltipPosition, Toaster } from '@iqser/common-ui'; +import { CircleButtonType, defaultDialogConfig, IqserTooltipPosition, Toaster, trackByFactory } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { FileDownloadService } from '@upload-download/services/file-download.service'; import { PermissionsService } from '@services/permissions.service'; @@ -17,7 +17,6 @@ import { MatDialog } from '@angular/material/dialog'; 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; @@ -31,6 +30,7 @@ export class ExpandableFileActionsComponent implements OnChanges { expanded = false; @ViewChild(MatMenuTrigger) matMenu: MatMenuTrigger; + trackBy = trackByFactory(); constructor( private readonly _fileDownloadService: FileDownloadService, @@ -38,6 +38,7 @@ export class ExpandableFileActionsComponent implements OnChanges { private readonly _permissionsService: PermissionsService, private readonly _dialog: MatDialog, ) {} + ngOnChanges(changes: SimpleChanges) { if (changes.actions || changes.maxWidth || changes.minWidth) { let count = 0; diff --git a/libs/red-domain/src/lib/shared/expandable-file-actions.ts b/libs/red-domain/src/lib/shared/expandable-file-actions.ts index 5d498fb6f..ec27e0575 100644 --- a/libs/red-domain/src/lib/shared/expandable-file-actions.ts +++ b/libs/red-domain/src/lib/shared/expandable-file-actions.ts @@ -1,18 +1,18 @@ import { Observable } from 'rxjs'; -import { CircleButtonType } from '@iqser/common-ui'; -import { File } from '../files'; -import { Dossier } from '../dossiers'; - -export type ActionType = 'circleBtn' | 'downloadBtn' | 'toggle'; +import { CircleButtonType, ITrackable } from '@iqser/common-ui'; +import { type File } from '../files'; +import { type Dossier } from '../dossiers'; export const ActionTypes = { - circleBtn: 'circleBtn' as ActionType, - downloadBtn: 'downloadBtn' as ActionType, - toggle: 'toggle' as ActionType, -}; + circleBtn: 'circleBtn', + downloadBtn: 'downloadBtn', + toggle: 'toggle', +} as const; -export interface Action { - id?: string; +export type ActionType = keyof typeof ActionTypes; + +export interface Action extends ITrackable { + readonly id: string; action?: (...args: unknown[]) => void; tooltip?: string; icon?: string; @@ -23,7 +23,7 @@ export interface Action { buttonType?: CircleButtonType; tooltipClass?: string; checked?: boolean; - class?: { [key: string]: boolean }; + class?: Record; files?: File[]; dossier?: Dossier; type: ActionType;