From 84c4a128ef32cd293d2be97ab028fc6142e1908d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Fri, 18 Feb 2022 01:53:08 +0200 Subject: [PATCH] Archive dossier action --- ...firm-archive-dossier-dialog.component.html | 32 ++++++++++++++ ...firm-archive-dossier-dialog.component.scss | 13 ++++++ ...onfirm-archive-dossier-dialog.component.ts | 43 +++++++++++++++++++ .../edit-dossier-general-info.component.html | 10 ++++- .../edit-dossier-general-info.component.ts | 8 +++- .../app/modules/dossier/dossiers.module.ts | 2 + .../services/dossiers-dialog.service.ts | 5 +++ .../src/app/modules/icons/icons.module.ts | 1 + .../entity-services/dossiers.service.ts | 28 +++++++++--- .../src/app/services/permissions.service.ts | 4 ++ apps/red-ui/src/assets/config/config.json | 4 +- apps/red-ui/src/assets/i18n/en.json | 16 +++++++ .../src/assets/icons/general/archive.svg | 9 ++++ 13 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.html create mode 100644 apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.scss create mode 100644 apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.ts create mode 100644 apps/red-ui/src/assets/icons/general/archive.svg diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.html b/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.html new file mode 100644 index 000000000..a076d6010 --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.html @@ -0,0 +1,32 @@ +
+
+ +
+
+ + + +
+ +
+
+
+ + + {{ checkbox.label | translate }} + +
+ +
+ +
+
+ +
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.scss b/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.scss new file mode 100644 index 000000000..1cbdb4e5b --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.scss @@ -0,0 +1,13 @@ +@use 'variables'; + +.dialog-header { + color: variables.$primary; +} + +mat-checkbox { + width: 100%; + + &:not(:last-of-type) { + margin-bottom: 6px; + } +} diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.ts new file mode 100644 index 000000000..ef3a45175 --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component.ts @@ -0,0 +1,43 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { LoadingService, Toaster } from '@iqser/common-ui'; +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { firstValueFrom } from 'rxjs'; +import { Dossier } from '@red/domain'; +import { DossiersService } from '@services/entity-services/dossiers.service'; + +@Component({ + templateUrl: './confirm-archive-dossier-dialog.component.html', + styleUrls: ['./confirm-archive-dossier-dialog.component.scss'], +}) +export class ConfirmArchiveDossierDialogComponent { + readonly checkboxes = [{ value: false, label: _('confirm-archive-dossier.checkbox.documents') }]; + showToast = false; + + constructor( + private readonly _loadingService: LoadingService, + private readonly _dossiersService: DossiersService, + private readonly _toaster: Toaster, + @Inject(MAT_DIALOG_DATA) readonly dossier: Dossier, + readonly dialogRef: MatDialogRef, + ) {} + + get valid() { + return this.checkboxes[0].value; + } + + async archiveDossier() { + if (this.valid) { + this._loadingService.start(); + await firstValueFrom(this._dossiersService.archive([this.dossier])); + this._toaster.success(_('dossier-listing.archive.archive-succeeded'), { params: this.dossier }); + this.dialogRef.close(true); + } else { + this.showToast = true; + } + } + + cancel() { + this.dialogRef.close(); + } +} diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.html b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.html index 4d60d4b0f..dc5f3cd46 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.html +++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.html @@ -55,7 +55,7 @@
- +
@@ -95,5 +95,13 @@ [type]="iconButtonTypes.dark" icon="iqser:trash" > + +
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts index 622aca251..5f895cdb9 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts @@ -148,6 +148,12 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti }); } + archiveDossier() { + this._dialogService.openDialog('archiveDossier', null, this.dossier, () => { + this._editDossierDialogRef.close(); + }); + } + #getForm(): FormGroup { return this._formBuilder.group({ dossierName: [this.dossier.dossierName, Validators.required], @@ -167,7 +173,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti } #notifyDossierDeleted() { - this._toaster.success(_('edit-dossier-dialog.delete-successful'), { params: { dossierName: this.dossier.dossierName } }); + this._toaster.success(_('edit-dossier-dialog.delete-successful'), { params: this.dossier }); } #filterInvalidDossierTemplates() { diff --git a/apps/red-ui/src/app/modules/dossier/dossiers.module.ts b/apps/red-ui/src/app/modules/dossier/dossiers.module.ts index 9fd58b8cb..2ff709a8a 100644 --- a/apps/red-ui/src/app/modules/dossier/dossiers.module.ts +++ b/apps/red-ui/src/app/modules/dossier/dossiers.module.ts @@ -25,12 +25,14 @@ import { OverlayModule } from '@angular/cdk/overlay'; import { SharedDossiersModule } from './shared/shared-dossiers.module'; import { ResizeAnnotationDialogComponent } from './dialogs/resize-annotation-dialog/resize-annotation-dialog.component'; import { EditDossierTeamComponent } from './dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component'; +import { ConfirmArchiveDossierDialogComponent } from './dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component'; const screens = [SearchScreenComponent]; const dialogs = [ AddDossierDialogComponent, EditDossierDialogComponent, + ConfirmArchiveDossierDialogComponent, ManualAnnotationDialogComponent, ForceAnnotationDialogComponent, RemoveAnnotationsDialogComponent, diff --git a/apps/red-ui/src/app/modules/dossier/services/dossiers-dialog.service.ts b/apps/red-ui/src/app/modules/dossier/services/dossiers-dialog.service.ts index ca5aef32e..2f0f150b4 100644 --- a/apps/red-ui/src/app/modules/dossier/services/dossiers-dialog.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/dossiers-dialog.service.ts @@ -11,12 +11,14 @@ import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-d import { RecategorizeImageDialogComponent } from '../dialogs/recategorize-image-dialog/recategorize-image-dialog.component'; import { ConfirmationDialogComponent, DialogConfig, DialogService, largeDialogConfig } from '@iqser/common-ui'; import { ResizeAnnotationDialogComponent } from '../dialogs/resize-annotation-dialog/resize-annotation-dialog.component'; +import { ConfirmArchiveDossierDialogComponent } from '../dialogs/confirm-archive-dossier-dialog/confirm-archive-dossier-dialog.component'; type DialogType = | 'confirm' | 'documentInfo' | 'editDossier' | 'addDossier' + | 'archiveDossier' | 'assignFile' | 'recategorizeImage' | 'changeLegalBasis' @@ -44,6 +46,9 @@ export class DossiersDialogService extends DialogService { component: AddDossierDialogComponent, dialogConfig: { width: '900px', autoFocus: true }, }, + archiveDossier: { + component: ConfirmArchiveDossierDialogComponent, + }, assignFile: { component: AssignReviewerApproverDialogComponent, dialogConfig: { disableClose: false }, diff --git a/apps/red-ui/src/app/modules/icons/icons.module.ts b/apps/red-ui/src/app/modules/icons/icons.module.ts index 7d808ccd7..06fa9e338 100644 --- a/apps/red-ui/src/app/modules/icons/icons.module.ts +++ b/apps/red-ui/src/app/modules/icons/icons.module.ts @@ -13,6 +13,7 @@ export class IconsModule { const icons = [ 'ai', 'approved', + 'archive', 'arrow-up', 'assign', 'assign-me', diff --git a/apps/red-ui/src/app/services/entity-services/dossiers.service.ts b/apps/red-ui/src/app/services/entity-services/dossiers.service.ts index 0e48fc9c7..669383561 100644 --- a/apps/red-ui/src/app/services/entity-services/dossiers.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dossiers.service.ts @@ -108,19 +108,33 @@ export class DossiersService extends EntitiesService { } delete(dossier: Dossier): Observable { - const updateDossiers = () => { - this.setEntities(this.all.filter(d => d.dossierId !== dossier.dossierId)); - }; const showToast = () => { this._toaster.error(_('dossier-listing.delete.delete-failed'), { params: dossier }); return of({}); }; - return super.delete(dossier.dossierId).pipe(tap(updateDossiers), catchError(showToast)); + return super.delete(dossier.dossierId).pipe( + tap(() => this.#removeDossiers([dossier])), + catchError(showToast), + ); + } + + archive(dossiers: Dossier[]): Observable { + const showToast = () => { + this._toaster.error(_('dossier-listing.archive.archive-failed'), { params: dossiers }); + return of({}); + }; + return this._post( + dossiers.map(d => d.id), + 'archived-dossiers/archive', + ).pipe( + tap(() => this.#removeDossiers(dossiers)), + catchError(showToast), + ); } @Validate() restore(@RequiredParam() dossierIds: List): Promise { - return firstValueFrom(this._post(dossierIds, 'deleted-dossiers/restore')); + return firstValueFrom(this._post(dossierIds, 'deleted-dossiers/restore').pipe(switchMap(() => this.loadAll()))); } @Validate() @@ -133,6 +147,10 @@ export class DossiersService extends EntitiesService { return this.all.filter(dossier => dossier.dossierStatusId === dossierStatusId).length; } + #removeDossiers(dossiers: Dossier[]): void { + this.setEntities(this.all.filter(dossier => !dossiers.find(d => dossier.id === d.id))); + } + private _load(id: string, queryParams?: List): Observable { return super._getOne([id], this._defaultModelPath, queryParams).pipe( map(entity => new Dossier(entity)), diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index 361e96385..22912c866 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -133,6 +133,10 @@ export class PermissionsService { return dossier.ownerId === this._userService.currentUser.id; } + canArchiveDossier(dossier: IDossier): boolean { + return dossier.ownerId === this._userService.currentUser.id; + } + canEditDossier(dossier: Dossier, user = this._userService.currentUser): boolean { return user.isManager && !!dossier?.ownerId; } diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index bf72886ff..4b275311e 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -1,7 +1,7 @@ { "ADMIN_CONTACT_NAME": null, "ADMIN_CONTACT_URL": null, - "API_URL": "https://dev-05.iqser.cloud/redaction-gateway-v1", + "API_URL": "https://dev-04.iqser.cloud/redaction-gateway-v1", "APP_NAME": "RedactManager", "AUTO_READ_TIME": 3, "BACKEND_APP_VERSION": "4.4.40", @@ -17,7 +17,7 @@ "MAX_RETRIES_ON_SERVER_ERROR": 3, "OAUTH_CLIENT_ID": "redaction", "OAUTH_IDP_HINT": null, - "OAUTH_URL": "https://dev-05.iqser.cloud/auth/realms/redaction", + "OAUTH_URL": "https://dev-04.iqser.cloud/auth/realms/redaction", "RECENT_PERIOD_IN_HOURS": 24, "SELECTION_MODE": "structural", "MANUAL_BASE_URL": "https://docs.redactmanager.com" diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 4facffb34..a1b84ce97 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -408,6 +408,17 @@ } }, "configurations": "Configurations", + "confirm-archive-dossier": { + "archive": "Archive Dossier", + "cancel": "Cancel", + "checkbox": { + "documents": "All documents will be archived and cannot be put back to active" + }, + "details": "Restoring an archived dossier is not possible anymore, once it got archived.", + "title": "Archive {dossierName}", + "toast-error": "Please confirm that you understand the ramifications of your action!", + "warning": "Are you sure you want to archive the dossier?" + }, "confirm-delete-dossier-state": { "cancel": "Cancel", "delete": "Delete only", @@ -678,6 +689,11 @@ }, "dossier-listing": { "add-new": "New Dossier", + "archive": { + "action": "Archive Dossier", + "archive-failed": "Failed to archive dossier {dossierName}!", + "archive-succeeded": "Successfully archived dossier {dossierName}." + }, "delete": { "action": "Delete Dossier", "delete-failed": "Failed to delete dossier: {dossierName}" diff --git a/apps/red-ui/src/assets/icons/general/archive.svg b/apps/red-ui/src/assets/icons/general/archive.svg new file mode 100644 index 000000000..0d4414f55 --- /dev/null +++ b/apps/red-ui/src/assets/icons/general/archive.svg @@ -0,0 +1,9 @@ + + + + + + + +