Archive dossier action
This commit is contained in:
parent
b998cf44d9
commit
84c4a128ef
@ -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>
|
||||
@ -0,0 +1,13 @@
|
||||
@use 'variables';
|
||||
|
||||
.dialog-header {
|
||||
color: variables.$primary;
|
||||
}
|
||||
|
||||
mat-checkbox {
|
||||
width: 100%;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 },
|
||||
|
||||
@ -13,6 +13,7 @@ export class IconsModule {
|
||||
const icons = [
|
||||
'ai',
|
||||
'approved',
|
||||
'archive',
|
||||
'arrow-up',
|
||||
'assign',
|
||||
'assign-me',
|
||||
|
||||
@ -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)),
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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}"
|
||||
|
||||
9
apps/red-ui/src/assets/icons/general/archive.svg
Normal file
9
apps/red-ui/src/assets/icons/general/archive.svg
Normal 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 |
Loading…
x
Reference in New Issue
Block a user