Pull request #339: RED-3132

Merge in RED/ui from RED-3132 to master

* commit '46cec7e6b82bd63112af0603063f24a698db4e97':
  refactoring && update common
  report count in dialog
  get by placeholder method for report templates
  dossier and file attributes dialog in the same component
This commit is contained in:
Eduard Cziszter 2022-01-26 20:07:02 +01:00 committed by Dan Percic
commit dbaaaa1f3f
11 changed files with 135 additions and 79 deletions

View File

@ -17,7 +17,7 @@ import { ColorPickerModule } from 'ngx-color-picker';
import { AddEditFileAttributeDialogComponent } from './dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component'; import { AddEditFileAttributeDialogComponent } from './dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component';
import { AddEditDossierTemplateDialogComponent } from './dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component'; import { AddEditDossierTemplateDialogComponent } from './dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component';
import { AddEditDictionaryDialogComponent } from './dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component'; import { AddEditDictionaryDialogComponent } from './dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component';
import { ConfirmDeleteFileAttributeDialogComponent } from './dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component'; import { ConfirmDeleteAttributeDialogComponent } from './dialogs/confirm-delete-attribute-dialog/confirm-delete-attribute-dialog.component';
import { EditColorDialogComponent } from './dialogs/edit-color-dialog/edit-color-dialog.component'; import { EditColorDialogComponent } from './dialogs/edit-color-dialog/edit-color-dialog.component';
import { ComboChartComponent, ComboSeriesVerticalComponent } from './components/combo-chart'; import { ComboChartComponent, ComboSeriesVerticalComponent } from './components/combo-chart';
import { NgxChartsModule } from '@swimlane/ngx-charts'; import { NgxChartsModule } from '@swimlane/ngx-charts';
@ -53,7 +53,7 @@ const dialogs = [
AddEditDossierTemplateDialogComponent, AddEditDossierTemplateDialogComponent,
AddEditDictionaryDialogComponent, AddEditDictionaryDialogComponent,
AddEditFileAttributeDialogComponent, AddEditFileAttributeDialogComponent,
ConfirmDeleteFileAttributeDialogComponent, ConfirmDeleteAttributeDialogComponent,
EditColorDialogComponent, EditColorDialogComponent,
SmtpAuthDialogComponent, SmtpAuthDialogComponent,
AddEditUserDialogComponent, AddEditUserDialogComponent,

View File

@ -1,13 +1,6 @@
<section class="dialog"> <section class="dialog">
<div class="dialog-header heading-l"> <div class="dialog-header heading-l">
{{ {{ 'confirm-delete-file-attribute.title' | translate: translateArgs }}
'confirm-delete-file-attribute.title'
| translate
: {
type: type,
name: fileAttribute?.label
}
}}
</div> </div>
<div *ngIf="showToast" class="inline-dialog-toast toast-error"> <div *ngIf="showToast" class="inline-dialog-toast toast-error">
@ -20,14 +13,11 @@
<div class="dialog-content"> <div class="dialog-content">
<div class="heading" translate="confirm-delete-file-attribute.warning"></div> <div class="heading" translate="confirm-delete-file-attribute.warning"></div>
<mat-checkbox <ng-container *ngFor="let checkbox of checkboxes; let idx = index">
*ngFor="let checkbox of checkboxes; let idx = index" <mat-checkbox [(ngModel)]="checkbox.value" [class.error]="!checkbox.value && showToast" color="primary">
[(ngModel)]="checkbox.value" {{ checkbox.label }}
[class.error]="!checkbox.value && showToast"
color="primary"
>
{{ checkbox.label | translate: { type: type } }}
</mat-checkbox> </mat-checkbox>
</ng-container>
</div> </div>
<div class="dialog-actions"> <div class="dialog-actions">
@ -35,7 +25,7 @@
{{ 'confirm-delete-file-attribute.delete' | translate: { type: type } }} {{ 'confirm-delete-file-attribute.delete' | translate: { type: type } }}
</button> </button>
<div <div
(click)="cancel()" (click)="this.dialogRef.close()"
[translateParams]="{ type: type }" [translateParams]="{ type: type }"
[translate]="'confirm-delete-file-attribute.cancel'" [translate]="'confirm-delete-file-attribute.cancel'"
class="all-caps-label cancel" class="all-caps-label cancel"

View File

@ -0,0 +1,87 @@
import { Component, Inject } from '@angular/core';
import { DossierAttributeConfig, FileAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { TranslateService } from '@ngx-translate/core';
const isFileAttributeConfig = (value: DossierAttributeConfig | FileAttributeConfig): value is FileAttributeConfig =>
value instanceof FileAttributeConfig;
interface CheckBox {
value: boolean;
label: string;
}
interface DialogData {
attribute: FileAttributeConfig | DossierAttributeConfig;
count: number;
}
@Component({
selector: 'redaction-confirm-delete-attribute-dialog',
templateUrl: './confirm-delete-attribute-dialog.component.html',
styleUrls: ['./confirm-delete-attribute-dialog.component.scss'],
})
export class ConfirmDeleteAttributeDialogComponent {
checkboxes: CheckBox[];
showToast = false;
constructor(
private readonly _translateService: TranslateService,
readonly dialogRef: MatDialogRef<ConfirmDeleteAttributeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: DialogData,
) {
this.checkboxes = this.checkBoxConfig;
}
get checkBoxConfig(): CheckBox[] {
const checkBoxes = isFileAttributeConfig(this.data.attribute) ? this._fileAttributeCheckboxes : this._dossierAttributeCheckboxes;
if (this.data.count !== 0) {
checkBoxes.push({
value: false,
label: this._translateService.instant('confirm-delete-file-attribute.impacted-report', { count: this.data.count }),
});
}
return checkBoxes;
}
get valid() {
return this.checkboxes.reduce((acc, currentValue) => acc && currentValue.value, true);
}
get type(): 'bulk' | 'single' {
return this.data.attribute ? 'single' : 'bulk';
}
get translateArgs() {
return {
type: this.type,
name: this.data.attribute?.label,
};
}
private get _fileAttributeCheckboxes(): CheckBox[] {
return [
{
value: false,
label: this._translateService.instant('confirm-delete-file-attribute.file-impacted-documents', { type: this.type }),
},
{ value: false, label: this._translateService.instant('confirm-delete-file-attribute.file-lost-details') },
];
}
private get _dossierAttributeCheckboxes(): CheckBox[] {
return [
{ value: false, label: this._translateService.instant('confirm-delete-file-attribute.dossier-impacted-documents') },
{ value: false, label: this._translateService.instant('confirm-delete-file-attribute.dossier-lost-details') },
];
}
deleteFileAttribute() {
if (this.valid) {
this.dialogRef.close(true);
} else {
this.showToast = true;
}
}
}

View File

@ -1,45 +0,0 @@
import { Component, Inject } from '@angular/core';
import { IFileAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@Component({
selector: 'redaction-confirm-delete-file-attribute-dialog',
templateUrl: './confirm-delete-file-attribute-dialog.component.html',
styleUrls: ['./confirm-delete-file-attribute-dialog.component.scss'],
})
export class ConfirmDeleteFileAttributeDialogComponent {
fileAttribute: IFileAttributeConfig;
checkboxes = [
{ value: false, label: _('confirm-delete-file-attribute.impacted-documents') },
{ value: false, label: _('confirm-delete-file-attribute.lost-details') },
];
showToast = false;
constructor(
public dialogRef: MatDialogRef<ConfirmDeleteFileAttributeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: IFileAttributeConfig,
) {
this.fileAttribute = data;
}
get valid() {
return this.checkboxes[0].value && this.checkboxes[1].value;
}
get type(): 'bulk' | 'single' {
return this.fileAttribute ? 'single' : 'bulk';
}
deleteFileAttribute() {
if (this.valid) {
this.dialogRef.close(true);
} else {
this.showToast = true;
}
}
cancel() {
this.dialogRef.close();
}
}

View File

@ -16,6 +16,7 @@ import { UserService } from '@services/user.service';
import { DossierAttributeConfig, IDossierAttributeConfig } from '@red/domain'; import { DossierAttributeConfig, IDossierAttributeConfig } from '@red/domain';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service'; import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { ReportTemplateService } from '../../../../services/report-template.service';
@Component({ @Component({
templateUrl: './dossier-attributes-listing-screen.component.html', templateUrl: './dossier-attributes-listing-screen.component.html',
@ -45,6 +46,7 @@ export class DossierAttributesListingScreenComponent extends ListingComponent<Do
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _dossierAttributesService: DossierAttributesService, private readonly _dossierAttributesService: DossierAttributesService,
private readonly _userService: UserService, private readonly _userService: UserService,
private readonly _reportTemplateService: ReportTemplateService,
) { ) {
super(_injector); super(_injector);
} }
@ -53,8 +55,13 @@ export class DossierAttributesListingScreenComponent extends ListingComponent<Do
await this._loadData(); await this._loadData();
} }
openConfirmDeleteAttributeDialog($event: MouseEvent, dossierAttribute?: IDossierAttributeConfig) { async openConfirmDeleteAttributeDialog($event: MouseEvent, dossierAttribute?: DossierAttributeConfig) {
this._dialogService.openDialog('confirm', $event, null, async () => { const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId;
const resp = await firstValueFrom(
this._reportTemplateService.getTemplatesByPlaceholder(dossierTemplateId, dossierAttribute.placeholder),
);
this._dialogService.openDialog('deleteAttribute', $event, { attribute: dossierAttribute, count: resp.length }, async () => {
this._loadingService.start(); this._loadingService.start();
const ids = dossierAttribute ? [dossierAttribute.id] : this.listingService.selected.map(item => item.id); const ids = dossierAttribute ? [dossierAttribute.id] : this.listingService.selected.map(item => item.id);
await firstValueFrom(this._dossierAttributesService.delete(ids)); await firstValueFrom(this._dossierAttributesService.delete(ids));

View File

@ -18,6 +18,7 @@ import { FileAttributesService } from '@services/entity-services/file-attributes
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service'; import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { HttpStatusCode } from '@angular/common/http'; import { HttpStatusCode } from '@angular/common/http';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { ReportTemplateService } from '../../../../services/report-template.service';
@Component({ @Component({
templateUrl: './file-attributes-listing-screen.component.html', templateUrl: './file-attributes-listing-screen.component.html',
@ -60,6 +61,7 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _dialogService: AdminDialogService, private readonly _dialogService: AdminDialogService,
private readonly _fileAttributesService: FileAttributesService, private readonly _fileAttributesService: FileAttributesService,
private readonly _reportTemplateService: ReportTemplateService,
) { ) {
super(_injector); super(_injector);
} }
@ -88,10 +90,14 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
}); });
} }
openConfirmDeleteAttributeDialog($event: MouseEvent, fileAttribute?: IFileAttributeConfig) { async openConfirmDeleteAttributeDialog($event: MouseEvent, fileAttribute?: FileAttributeConfig) {
this._dialogService.openDialog('deleteFileAttribute', $event, fileAttribute, async () => {
this._loadingService.start();
const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId; const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId;
const resp = await firstValueFrom(
this._reportTemplateService.getTemplatesByPlaceholder(dossierTemplateId, fileAttribute.placeholder),
);
this._dialogService.openDialog('deleteAttribute', $event, { attribute: fileAttribute, count: resp.length }, async () => {
this._loadingService.start();
if (fileAttribute) { if (fileAttribute) {
await firstValueFrom(this._fileAttributesService.deleteFileAttributes([fileAttribute.id], dossierTemplateId)); await firstValueFrom(this._fileAttributesService.deleteFileAttributes([fileAttribute.id], dossierTemplateId));
} else { } else {

View File

@ -3,7 +3,7 @@ import { MatDialog } from '@angular/material/dialog';
import { AddEditFileAttributeDialogComponent } from '../dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component'; import { AddEditFileAttributeDialogComponent } from '../dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component';
import { AddEditDictionaryDialogComponent } from '../dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component'; import { AddEditDictionaryDialogComponent } from '../dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component';
import { AddEditDossierTemplateDialogComponent } from '../dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component'; import { AddEditDossierTemplateDialogComponent } from '../dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component';
import { ConfirmDeleteFileAttributeDialogComponent } from '../dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component'; import { ConfirmDeleteAttributeDialogComponent } from '../dialogs/confirm-delete-attribute-dialog/confirm-delete-attribute-dialog.component';
import { EditColorDialogComponent } from '../dialogs/edit-color-dialog/edit-color-dialog.component'; import { EditColorDialogComponent } from '../dialogs/edit-color-dialog/edit-color-dialog.component';
import { SmtpAuthDialogComponent } from '../dialogs/smtp-auth-dialog/smtp-auth-dialog.component'; import { SmtpAuthDialogComponent } from '../dialogs/smtp-auth-dialog/smtp-auth-dialog.component';
import { AddEditUserDialogComponent } from '../dialogs/add-edit-user-dialog/add-edit-user-dialog.component'; import { AddEditUserDialogComponent } from '../dialogs/add-edit-user-dialog/add-edit-user-dialog.component';
@ -19,7 +19,7 @@ type DialogType =
| 'addEditDictionary' | 'addEditDictionary'
| 'editColor' | 'editColor'
| 'addEditFileAttribute' | 'addEditFileAttribute'
| 'deleteFileAttribute' | 'deleteAttribute'
| 'importFileAttributes' | 'importFileAttributes'
| 'addEditUser' | 'addEditUser'
| 'deleteUsers' | 'deleteUsers'
@ -48,8 +48,8 @@ export class AdminDialogService extends DialogService<DialogType> {
component: AddEditFileAttributeDialogComponent, component: AddEditFileAttributeDialogComponent,
dialogConfig: { autoFocus: true }, dialogConfig: { autoFocus: true },
}, },
deleteFileAttribute: { deleteAttribute: {
component: ConfirmDeleteFileAttributeDialogComponent, component: ConfirmDeleteAttributeDialogComponent,
dialogConfig: { disableClose: false }, dialogConfig: { disableClose: false },
}, },
importFileAttributes: { importFileAttributes: {

View File

@ -43,6 +43,11 @@ export class ReportTemplateService extends GenericService<unknown> {
return this._getOne<IPlaceholdersResponse>([dossierTemplateId], 'placeholders'); return this._getOne<IPlaceholdersResponse>([dossierTemplateId], 'placeholders');
} }
@Validate()
getTemplatesByPlaceholder(@RequiredParam() dossierTemplateId: string, @RequiredParam() attributeId: string) {
return this._post<IReportTemplate[]>({ value: attributeId }, `templates/${dossierTemplateId}`);
}
downloadReportTemplate(dossierTemplateId: string, templateId: string, observe: 'response'): Observable<HttpResponse<Blob>>; downloadReportTemplate(dossierTemplateId: string, templateId: string, observe: 'response'): Observable<HttpResponse<Blob>>;
downloadReportTemplate(dossierTemplateId: string, templateId: string, observe: 'body'): Observable<Blob>; downloadReportTemplate(dossierTemplateId: string, templateId: string, observe: 'body'): Observable<Blob>;
@Validate() @Validate()

View File

@ -395,11 +395,14 @@
"confirm-delete-file-attribute": { "confirm-delete-file-attribute": {
"cancel": "{type, select, single{Attribut} bulk{Attribute} other{}} behalten", "cancel": "{type, select, single{Attribut} bulk{Attribute} other{}} behalten",
"delete": "{type, select, single{Attribut} bulk{Attribute} other{}} löschen", "delete": "{type, select, single{Attribut} bulk{Attribute} other{}} löschen",
"impacted-documents": "Alle Dokumente {type, select, single{ist} bulk{sind} other{}} betroffen", "file-impacted-documents": "Alle Dokumente {type, select, single{ist} bulk{sind} other{}} betroffen",
"lost-details": "Alle in die Dokumente eingegebenen Daten gehen verloren", "dossier-impacted-documents": "",
"file-lost-details": "Alle in die Dokumente eingegebenen Daten gehen verloren",
"dossier-lost-details": "",
"title": "{type, select, single{{name}} bulk{Datei-Attribute} other{}} löschen", "title": "{type, select, single{{name}} bulk{Datei-Attribute} other{}} löschen",
"toast-error": "Bitte bestätigen Sie, dass Ihnen die Konsequenzen dieser Aktion bewusst sind!", "toast-error": "Bitte bestätigen Sie, dass Ihnen die Konsequenzen dieser Aktion bewusst sind!",
"warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!" "warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!",
"impacted-report": "{count}"
}, },
"confirm-delete-users": { "confirm-delete-users": {
"cancel": "{usersCount, plural, one{Benutzer} other{Benutzer}} behalten", "cancel": "{usersCount, plural, one{Benutzer} other{Benutzer}} behalten",

View File

@ -395,11 +395,14 @@
"confirm-delete-file-attribute": { "confirm-delete-file-attribute": {
"cancel": "Keep {type, select, single{Attribute} bulk{Attributes} other{}}", "cancel": "Keep {type, select, single{Attribute} bulk{Attributes} other{}}",
"delete": "Delete {type, select, single{Attribute} bulk{Attributes} other{}}", "delete": "Delete {type, select, single{Attribute} bulk{Attributes} other{}}",
"impacted-documents": "All documents {type, select, single{it is} bulk{they are} other{}} used on will be impacted", "file-impacted-documents": "All documents {type, select, single{it is} bulk{they are} other{}} used on will be impacted",
"lost-details": "All inputted details on the documents will be lost", "dossier-impacted-documents": "All dossiers based on this template will be affected",
"file-lost-details": "All inputted details on the documents will be lost",
"dossier-lost-details": "All values for this attribute will be lost",
"title": "Delete {type, select, single{{name}} bulk{File Attributes} other{}}", "title": "Delete {type, select, single{{name}} bulk{File Attributes} other{}}",
"toast-error": "Please confirm that you understand the ramifications of your action!", "toast-error": "Please confirm that you understand the ramifications of your action!",
"warning": "Warning: this cannot be undone!" "warning": "Warning: this cannot be undone!",
"impacted-report": "{count} reports use the placeholder for this attribute and need to be adjusted"
}, },
"confirm-delete-users": { "confirm-delete-users": {
"cancel": "Keep {usersCount, plural, one{User} other{Users}}", "cancel": "Keep {usersCount, plural, one{User} other{Users}}",