RED-3800 Audit Info Dialog
This commit is contained in:
parent
8fb0c84c64
commit
f8fe1799f5
@ -46,6 +46,7 @@ import { ConfigureCertificateDialogComponent } from './dialogs/configure-digital
|
|||||||
import { PkcsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component';
|
import { PkcsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component';
|
||||||
import { KmsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component';
|
import { KmsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component';
|
||||||
import {
|
import {
|
||||||
|
HumanizeCamelCasePipe,
|
||||||
HumanizePipe,
|
HumanizePipe,
|
||||||
IqserButtonsModule,
|
IqserButtonsModule,
|
||||||
IqserEmptyStatesModule,
|
IqserEmptyStatesModule,
|
||||||
@ -59,6 +60,8 @@ import {
|
|||||||
IqserUsersModule,
|
IqserUsersModule,
|
||||||
} from '@iqser/common-ui';
|
} from '@iqser/common-ui';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { OverlayModule } from '@angular/cdk/overlay';
|
||||||
|
import { AuditInfoDialog } from './dialogs/audit-info-dialog/audit-info-dialog.component';
|
||||||
|
|
||||||
const dialogs = [
|
const dialogs = [
|
||||||
AddEditCloneDossierTemplateDialogComponent,
|
AddEditCloneDossierTemplateDialogComponent,
|
||||||
@ -74,6 +77,7 @@ const dialogs = [
|
|||||||
AddEditDossierStateDialogComponent,
|
AddEditDossierStateDialogComponent,
|
||||||
ConfirmDeleteDossierStateDialogComponent,
|
ConfirmDeleteDossierStateDialogComponent,
|
||||||
ConfigureCertificateDialogComponent,
|
ConfigureCertificateDialogComponent,
|
||||||
|
AuditInfoDialog,
|
||||||
];
|
];
|
||||||
|
|
||||||
const screens = [
|
const screens = [
|
||||||
@ -129,6 +133,8 @@ const components = [
|
|||||||
IqserSharedModule,
|
IqserSharedModule,
|
||||||
IqserHelpModeModule,
|
IqserHelpModeModule,
|
||||||
IqserPermissionsModule,
|
IqserPermissionsModule,
|
||||||
|
OverlayModule,
|
||||||
|
HumanizeCamelCasePipe,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AdminModule {}
|
export class AdminModule {}
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
<section class="dialog">
|
||||||
|
<div [translate]="'audit-screen.audit-info-dialog.title'" class="dialog-header heading-l"></div>
|
||||||
|
|
||||||
|
<div class="dialog-content">
|
||||||
|
<div class="table output-data">
|
||||||
|
<div class="table-header">Key</div>
|
||||||
|
<div class="table-header">Value</div>
|
||||||
|
|
||||||
|
<ng-container *ngFor="let entry of data.auditEntry.details | keyvalue: originalOrder">
|
||||||
|
<div class="bold">{{ entry.key | humanize }}</div>
|
||||||
|
<div>{{ entry.value }}</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
|
||||||
|
</section>
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
.table {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
|
||||||
|
> div {
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value-content {
|
||||||
|
.value {
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-header {
|
||||||
|
margin: 10px 0;
|
||||||
|
border-bottom: 1px solid var(--iqser-separator);
|
||||||
|
background-color: var(--iqser-grey-2);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||||
|
import { BaseDialogComponent } from '@iqser/common-ui';
|
||||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
|
import { IAudit } from '@red/domain';
|
||||||
|
import { DossierStatesService } from '@services/entity-services/dossier-states.service';
|
||||||
|
import { KeyValue } from '@angular/common';
|
||||||
|
|
||||||
|
interface DialogData {
|
||||||
|
readonly auditEntry: IAudit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'redaction-audit-info-dialog',
|
||||||
|
templateUrl: './audit-info-dialog.component.html',
|
||||||
|
styleUrls: ['./audit-info-dialog.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
})
|
||||||
|
export class AuditInfoDialogComponent extends BaseDialogComponent {
|
||||||
|
readonly originalOrder = (a: KeyValue<string, string>, b: KeyValue<string, string>): number => 0;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly _dossierStatesService: DossierStatesService,
|
||||||
|
protected readonly _dialogRef: MatDialogRef<AuditInfoDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) readonly data: DialogData,
|
||||||
|
) {
|
||||||
|
super(_dialogRef, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
async save(): Promise<void> {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@
|
|||||||
[noDataText]="'audit-screen.no-data.title' | translate"
|
[noDataText]="'audit-screen.no-data.title' | translate"
|
||||||
[tableColumnConfigs]="tableColumnConfigs"
|
[tableColumnConfigs]="tableColumnConfigs"
|
||||||
[totalSize]="logs?.totalHits || 0"
|
[totalSize]="logs?.totalHits || 0"
|
||||||
|
[emptyColumnWidth]="'2fr'"
|
||||||
></iqser-table>
|
></iqser-table>
|
||||||
|
|
||||||
<ng-template #headerTemplate>
|
<ng-template #headerTemplate>
|
||||||
@ -94,5 +95,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell">{{ (translations[log.category] | translate) || log.category | humanize }}</div>
|
<div class="cell">{{ (translations[log.category] | translate) || log.category | humanize }}</div>
|
||||||
|
|
||||||
|
<div class="cell">
|
||||||
|
<div class="action-buttons">
|
||||||
|
<iqser-circle-button
|
||||||
|
*ngIf="log.hasDetails"
|
||||||
|
(action)="openAuditDetails($event, log)"
|
||||||
|
cdkOverlayOrigin
|
||||||
|
#trigger="cdkOverlayOrigin"
|
||||||
|
[tooltip]="'audit-screen.action.info' | translate"
|
||||||
|
icon="red:info"
|
||||||
|
[type]="circleButtonTypes.dark"
|
||||||
|
></iqser-circle-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|||||||
@ -17,3 +17,9 @@ form {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item-info {
|
||||||
|
background: var(--iqser-light);
|
||||||
|
border: 1px solid var(--iqser-grey-1);
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { Component, inject, OnDestroy, OnInit } from '@angular/core';
|
|||||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||||
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
|
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
|
||||||
import {
|
import {
|
||||||
|
CircleButtonTypes,
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
IqserPermissionsService,
|
IqserPermissionsService,
|
||||||
ListingComponent,
|
ListingComponent,
|
||||||
@ -17,6 +18,7 @@ import { firstValueFrom } from 'rxjs';
|
|||||||
import { Dayjs } from 'dayjs';
|
import { Dayjs } from 'dayjs';
|
||||||
import { RouterHistoryService } from '@services/router-history.service';
|
import { RouterHistoryService } from '@services/router-history.service';
|
||||||
import { ROLES } from '@users/roles';
|
import { ROLES } from '@users/roles';
|
||||||
|
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||||
|
|
||||||
const PAGE_SIZE = 50;
|
const PAGE_SIZE = 50;
|
||||||
|
|
||||||
@ -26,6 +28,7 @@ const PAGE_SIZE = 50;
|
|||||||
providers: listingProvidersFactory(AuditScreenComponent),
|
providers: listingProvidersFactory(AuditScreenComponent),
|
||||||
})
|
})
|
||||||
export class AuditScreenComponent extends ListingComponent<Audit> implements OnInit, OnDestroy {
|
export class AuditScreenComponent extends ListingComponent<Audit> implements OnInit, OnDestroy {
|
||||||
|
readonly circleButtonTypes = CircleButtonTypes;
|
||||||
readonly ALL_CATEGORIES = 'allCategories';
|
readonly ALL_CATEGORIES = 'allCategories';
|
||||||
readonly ALL_USERS = _('audit-screen.all-users');
|
readonly ALL_USERS = _('audit-screen.all-users');
|
||||||
readonly translations = auditCategoriesTranslations;
|
readonly translations = auditCategoriesTranslations;
|
||||||
@ -38,6 +41,7 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
|
|||||||
categories: string[] = [];
|
categories: string[] = [];
|
||||||
userIds: Set<string>;
|
userIds: Set<string>;
|
||||||
logs: IAuditResponse;
|
logs: IAuditResponse;
|
||||||
|
|
||||||
readonly tableColumnConfigs: TableColumnConfig<Audit>[] = [
|
readonly tableColumnConfigs: TableColumnConfig<Audit>[] = [
|
||||||
{ label: _('audit-screen.table-col-names.message') },
|
{ label: _('audit-screen.table-col-names.message') },
|
||||||
{ label: _('audit-screen.table-col-names.date') },
|
{ label: _('audit-screen.table-col-names.date') },
|
||||||
@ -52,6 +56,7 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
|
|||||||
private readonly _formBuilder: UntypedFormBuilder,
|
private readonly _formBuilder: UntypedFormBuilder,
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _auditService: AuditService,
|
private readonly _auditService: AuditService,
|
||||||
|
private readonly _dialogService: AdminDialogService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -130,4 +135,8 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
|
|||||||
}
|
}
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openAuditDetails($event: MouseEvent, log: Audit) {
|
||||||
|
this._dialogService.openDialog('auditInfo', $event, { auditEntry: log });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import { UserService } from '@users/user.service';
|
|||||||
import { IDossierAttributeConfig, IFileAttributeConfig, IReportTemplate } from '@red/domain';
|
import { IDossierAttributeConfig, IFileAttributeConfig, IReportTemplate } from '@red/domain';
|
||||||
import { ReportTemplateService } from '@services/report-template.service';
|
import { ReportTemplateService } from '@services/report-template.service';
|
||||||
import { ConfigureCertificateDialogComponent } from '../dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component';
|
import { ConfigureCertificateDialogComponent } from '../dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component';
|
||||||
|
import { AuditInfoDialog } from '../dialogs/audit-info-dialog/audit-info-dialog.component';
|
||||||
|
|
||||||
type DialogType =
|
type DialogType =
|
||||||
| 'confirm'
|
| 'confirm'
|
||||||
@ -40,6 +41,7 @@ type DialogType =
|
|||||||
| 'addEditUser'
|
| 'addEditUser'
|
||||||
| 'smtpAuthConfig'
|
| 'smtpAuthConfig'
|
||||||
| 'addEditCloneDossierTemplate'
|
| 'addEditCloneDossierTemplate'
|
||||||
|
| 'auditInfo'
|
||||||
| 'addEditDossierAttribute'
|
| 'addEditDossierAttribute'
|
||||||
| 'uploadDictionary'
|
| 'uploadDictionary'
|
||||||
| 'addEditDossierState'
|
| 'addEditDossierState'
|
||||||
@ -101,6 +103,9 @@ export class AdminDialogService extends DialogService<DialogType> {
|
|||||||
component: ConfigureCertificateDialogComponent,
|
component: ConfigureCertificateDialogComponent,
|
||||||
dialogConfig: { disableClose: false, maxHeight: '100vh' },
|
dialogConfig: { disableClose: false, maxHeight: '100vh' },
|
||||||
},
|
},
|
||||||
|
auditInfo: {
|
||||||
|
component: AuditInfoDialog,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@ -402,7 +402,13 @@
|
|||||||
},
|
},
|
||||||
"audit": "Aktivitätenprotokoll",
|
"audit": "Aktivitätenprotokoll",
|
||||||
"audit-screen": {
|
"audit-screen": {
|
||||||
|
"action": {
|
||||||
|
"info": "Info"
|
||||||
|
},
|
||||||
"all-users": "Alle Benutzer",
|
"all-users": "Alle Benutzer",
|
||||||
|
"audit-info-dialog": {
|
||||||
|
"title": "Audit Info"
|
||||||
|
},
|
||||||
"categories": {
|
"categories": {
|
||||||
"all-categories": "Alle Bereiche",
|
"all-categories": "Alle Bereiche",
|
||||||
"audit": "Aktivitätenprotokoll",
|
"audit": "Aktivitätenprotokoll",
|
||||||
@ -1961,6 +1967,7 @@
|
|||||||
"save": "",
|
"save": "",
|
||||||
"undo": ""
|
"undo": ""
|
||||||
},
|
},
|
||||||
|
"annotations": "",
|
||||||
"title": ""
|
"title": ""
|
||||||
},
|
},
|
||||||
"rules-screen": {
|
"rules-screen": {
|
||||||
|
|||||||
@ -402,7 +402,13 @@
|
|||||||
},
|
},
|
||||||
"audit": "Audit",
|
"audit": "Audit",
|
||||||
"audit-screen": {
|
"audit-screen": {
|
||||||
|
"action": {
|
||||||
|
"info": "Info"
|
||||||
|
},
|
||||||
"all-users": "All Users",
|
"all-users": "All Users",
|
||||||
|
"audit-info-dialog": {
|
||||||
|
"title": "Audit Info"
|
||||||
|
},
|
||||||
"categories": {
|
"categories": {
|
||||||
"all-categories": "All Categories",
|
"all-categories": "All Categories",
|
||||||
"audit": "Audit",
|
"audit": "Audit",
|
||||||
@ -1961,6 +1967,7 @@
|
|||||||
"save": "Save",
|
"save": "Save",
|
||||||
"undo": "Undo"
|
"undo": "Undo"
|
||||||
},
|
},
|
||||||
|
"annotations": "",
|
||||||
"title": "Structured Component Management"
|
"title": "Structured Component Management"
|
||||||
},
|
},
|
||||||
"rules-screen": {
|
"rules-screen": {
|
||||||
|
|||||||
@ -402,7 +402,13 @@
|
|||||||
},
|
},
|
||||||
"audit": "Aktivitätenprotokoll",
|
"audit": "Aktivitätenprotokoll",
|
||||||
"audit-screen": {
|
"audit-screen": {
|
||||||
|
"action": {
|
||||||
|
"info": "Info"
|
||||||
|
},
|
||||||
"all-users": "Alle Benutzer",
|
"all-users": "Alle Benutzer",
|
||||||
|
"audit-info-dialog": {
|
||||||
|
"title": "Audit Info"
|
||||||
|
},
|
||||||
"categories": {
|
"categories": {
|
||||||
"all-categories": "Alle Bereiche",
|
"all-categories": "Alle Bereiche",
|
||||||
"audit": "Aktivitätenprotokoll",
|
"audit": "Aktivitätenprotokoll",
|
||||||
@ -1961,6 +1967,7 @@
|
|||||||
"save": "",
|
"save": "",
|
||||||
"undo": ""
|
"undo": ""
|
||||||
},
|
},
|
||||||
|
"annotations": "",
|
||||||
"title": ""
|
"title": ""
|
||||||
},
|
},
|
||||||
"rules-screen": {
|
"rules-screen": {
|
||||||
|
|||||||
@ -402,7 +402,13 @@
|
|||||||
},
|
},
|
||||||
"audit": "Audit",
|
"audit": "Audit",
|
||||||
"audit-screen": {
|
"audit-screen": {
|
||||||
|
"action": {
|
||||||
|
"info": "Info"
|
||||||
|
},
|
||||||
"all-users": "All Users",
|
"all-users": "All Users",
|
||||||
|
"audit-info-dialog": {
|
||||||
|
"title": "Audit Info"
|
||||||
|
},
|
||||||
"categories": {
|
"categories": {
|
||||||
"all-categories": "All Categories",
|
"all-categories": "All Categories",
|
||||||
"audit": "Audit",
|
"audit": "Audit",
|
||||||
|
|||||||
@ -4,11 +4,12 @@ import { IAudit } from './audit';
|
|||||||
export class Audit implements IAudit, IListable {
|
export class Audit implements IAudit, IListable {
|
||||||
readonly recordId: string;
|
readonly recordId: string;
|
||||||
readonly category: string;
|
readonly category: string;
|
||||||
readonly details?: unknown;
|
readonly details?: { [key: string]: string };
|
||||||
readonly message: string;
|
readonly message: string;
|
||||||
readonly objectId?: string;
|
readonly objectId?: string;
|
||||||
readonly recordDate: string;
|
readonly recordDate: string;
|
||||||
readonly userId: string;
|
readonly userId: string;
|
||||||
|
readonly hasDetails: boolean;
|
||||||
|
|
||||||
constructor(audit: IAudit) {
|
constructor(audit: IAudit) {
|
||||||
this.category = audit.category;
|
this.category = audit.category;
|
||||||
@ -18,6 +19,7 @@ export class Audit implements IAudit, IListable {
|
|||||||
this.recordDate = audit.recordDate;
|
this.recordDate = audit.recordDate;
|
||||||
this.recordId = audit.recordId;
|
this.recordId = audit.recordId;
|
||||||
this.userId = audit.userId;
|
this.userId = audit.userId;
|
||||||
|
this.hasDetails = audit.details ? Object.keys(audit.details).length > 0 : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get id(): string {
|
get id(): string {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
export interface IAudit {
|
export interface IAudit {
|
||||||
readonly category: string;
|
readonly category: string;
|
||||||
readonly details?: unknown;
|
readonly details?: { [key: string]: string };
|
||||||
readonly message: string;
|
readonly message: string;
|
||||||
readonly objectId?: string;
|
readonly objectId?: string;
|
||||||
readonly recordDate: string;
|
readonly recordDate: string;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user