Archive dossier action

This commit is contained in:
Adina Țeudan 2022-02-18 01:53:08 +02:00
parent b998cf44d9
commit 84c4a128ef
13 changed files with 166 additions and 9 deletions

View File

@ -0,0 +1,32 @@
<section class="dialog">
<div [translateParams]="dossier" [translate]="'confirm-archive-dossier.title'" class="dialog-header heading-l"></div>
<div *ngIf="showToast" class="inline-dialog-toast toast-error">
<div translate="confirm-archive-dossier.toast-error"></div>
<a (click)="showToast = false" class="toast-close-button">
<mat-icon svgIcon="iqser:close"></mat-icon>
</a>
</div>
<div class="dialog-content">
<div class="heading mb-8" translate="confirm-archive-dossier.warning"></div>
<div class="mb-24" translate="confirm-archive-dossier.details"></div>
<mat-checkbox
*ngFor="let checkbox of checkboxes; let idx = index"
[(ngModel)]="checkbox.value"
[class.error]="!checkbox.value && showToast"
color="primary"
>
{{ checkbox.label | translate }}
</mat-checkbox>
</div>
<div class="dialog-actions">
<button (click)="archiveDossier()" color="primary" mat-flat-button>
{{ 'confirm-archive-dossier.archive' | translate }}
</button>
<div (click)="cancel()" [translate]="'confirm-archive-dossier.cancel'" class="all-caps-label cancel"></div>
</div>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
</section>

View File

@ -0,0 +1,13 @@
@use 'variables';
.dialog-header {
color: variables.$primary;
}
mat-checkbox {
width: 100%;
&:not(:last-of-type) {
margin-bottom: 6px;
}
}

View File

@ -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<ConfirmArchiveDossierDialogComponent>,
) {}
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();
}
}

View File

@ -55,7 +55,7 @@
<div class="flex fields-container">
<div class="iqser-input-group w-300">
<label translate="edit-dossier-dialog.general-info.form.dossier-status.label"></label>
<mat-select [placeholder]="statusPlaceholder" [disabled]="states.length === 0" formControlName="dossierStatusId">
<mat-select [disabled]="states.length === 0" [placeholder]="statusPlaceholder" formControlName="dossierStatusId">
<mat-option *ngFor="let state of states" [value]="state.dossierStatusId">
<div class="flex-align-items-center">
<redaction-small-chip [color]="state.color"></redaction-small-chip>
@ -95,5 +95,13 @@
[type]="iconButtonTypes.dark"
icon="iqser:trash"
></iqser-icon-button>
<iqser-icon-button
(action)="archiveDossier()"
*ngIf="permissionsService.canArchiveDossier(dossier)"
[label]="'dossier-listing.archive.action' | translate"
[type]="iconButtonTypes.dark"
icon="red:archive"
></iqser-icon-button>
</div>
</form>

View File

@ -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() {

View File

@ -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,

View File

@ -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<DialogType> {
component: AddDossierDialogComponent,
dialogConfig: { width: '900px', autoFocus: true },
},
archiveDossier: {
component: ConfirmArchiveDossierDialogComponent,
},
assignFile: {
component: AssignReviewerApproverDialogComponent,
dialogConfig: { disableClose: false },

View File

@ -13,6 +13,7 @@ export class IconsModule {
const icons = [
'ai',
'approved',
'archive',
'arrow-up',
'assign',
'assign-me',

View File

@ -108,19 +108,33 @@ export class DossiersService extends EntitiesService<Dossier, IDossier> {
}
delete(dossier: Dossier): Observable<unknown> {
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<unknown> {
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<unknown> {
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<Dossier, IDossier> {
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<QueryParam>): Observable<DossierStats[]> {
return super._getOne([id], this._defaultModelPath, queryParams).pipe(
map(entity => new Dossier(entity)),

View File

@ -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;
}

View File

@ -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"

View File

@ -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}"

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="100px" version="1.1" viewBox="0 0 100 100" width="100px" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd" id="Symbols" stroke="none" stroke-width="1">
<g fill="currentColor" fill-rule="nonzero" id="archive">
<path
d="M90,0 C95.5001786,0 100,4.49982143 100,10 L100,10 L100,30 L95,30 L95,90 C95,95.5001786 90.5001786,100 85,100 L85,100 L15,100 C9.49982143,100 5,95.5001786 5,90 L5,90 L5,30 L0,30 L0,10 C0,4.49982143 4.49982143,0 10,0 L10,0 Z M85,30 L15,30 L15,90 L85,90 L85,30 Z M65,40 L65,50 L35,50 L35,40 L65,40 Z M90,10 L10,10 L10,20 L90,20 L90,10 Z"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 703 B