diff --git a/apps/red-ui/src/app/modules/admin/admin.module.ts b/apps/red-ui/src/app/modules/admin/admin.module.ts index 834bee174..95d6d512c 100644 --- a/apps/red-ui/src/app/modules/admin/admin.module.ts +++ b/apps/red-ui/src/app/modules/admin/admin.module.ts @@ -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 { KmsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component'; import { + HumanizeCamelCasePipe, HumanizePipe, IqserButtonsModule, IqserEmptyStatesModule, @@ -59,6 +60,8 @@ import { IqserUsersModule, } from '@iqser/common-ui'; 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 = [ AddEditCloneDossierTemplateDialogComponent, @@ -74,6 +77,7 @@ const dialogs = [ AddEditDossierStateDialogComponent, ConfirmDeleteDossierStateDialogComponent, ConfigureCertificateDialogComponent, + AuditInfoDialog, ]; const screens = [ @@ -129,6 +133,8 @@ const components = [ IqserSharedModule, IqserHelpModeModule, IqserPermissionsModule, + OverlayModule, + HumanizeCamelCasePipe, ], }) export class AdminModule {} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.html b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.html new file mode 100644 index 000000000..85ff1afba --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.html @@ -0,0 +1,17 @@ +
+
+ +
+
+
Key
+
Value
+ + +
{{ entry.key | humanize }}
+
{{ entry.value }}
+
+
+
+ + +
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.scss b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.scss new file mode 100644 index 000000000..ba44cd120 --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.scss @@ -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; + } +} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.ts new file mode 100644 index 000000000..94e043a81 --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.ts @@ -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, b: KeyValue): number => 0; + + constructor( + private readonly _dossierStatesService: DossierStatesService, + protected readonly _dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) readonly data: DialogData, + ) { + super(_dialogRef, false); + } + + async save(): Promise { + return; + } +} diff --git a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.html index 1b54546db..cc177e99e 100644 --- a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.html @@ -11,6 +11,7 @@ [noDataText]="'audit-screen.no-data.title' | translate" [tableColumnConfigs]="tableColumnConfigs" [totalSize]="logs?.totalHits || 0" + [emptyColumnWidth]="'2fr'" > @@ -94,5 +95,19 @@
{{ (translations[log.category] | translate) || log.category | humanize }}
+ +
+
+ +
+
diff --git a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.scss b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.scss index fee44202a..0b9886d50 100644 --- a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.scss +++ b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.scss @@ -17,3 +17,9 @@ form { font-size: 16px; opacity: 0.7; } + +.item-info { + background: var(--iqser-light); + border: 1px solid var(--iqser-grey-1); + padding: 20px; +} diff --git a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts index 210646292..6bfeea8b1 100644 --- a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts @@ -2,6 +2,7 @@ import { Component, inject, OnDestroy, OnInit } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { applyIntervalConstraints } from '@utils/date-inputs-utils'; import { + CircleButtonTypes, getCurrentUser, IqserPermissionsService, ListingComponent, @@ -17,6 +18,7 @@ import { firstValueFrom } from 'rxjs'; import { Dayjs } from 'dayjs'; import { RouterHistoryService } from '@services/router-history.service'; import { ROLES } from '@users/roles'; +import { AdminDialogService } from '../../services/admin-dialog.service'; const PAGE_SIZE = 50; @@ -26,6 +28,7 @@ const PAGE_SIZE = 50; providers: listingProvidersFactory(AuditScreenComponent), }) export class AuditScreenComponent extends ListingComponent implements OnInit, OnDestroy { + readonly circleButtonTypes = CircleButtonTypes; readonly ALL_CATEGORIES = 'allCategories'; readonly ALL_USERS = _('audit-screen.all-users'); readonly translations = auditCategoriesTranslations; @@ -38,6 +41,7 @@ export class AuditScreenComponent extends ListingComponent implements OnI categories: string[] = []; userIds: Set; logs: IAuditResponse; + readonly tableColumnConfigs: TableColumnConfig[] = [ { label: _('audit-screen.table-col-names.message') }, { label: _('audit-screen.table-col-names.date') }, @@ -52,6 +56,7 @@ export class AuditScreenComponent extends ListingComponent implements OnI private readonly _formBuilder: UntypedFormBuilder, private readonly _loadingService: LoadingService, private readonly _auditService: AuditService, + private readonly _dialogService: AdminDialogService, ) { super(); } @@ -130,4 +135,8 @@ export class AuditScreenComponent extends ListingComponent implements OnI } this._loadingService.stop(); } + + openAuditDetails($event: MouseEvent, log: Audit) { + this._dialogService.openDialog('auditInfo', $event, { auditEntry: log }); + } } diff --git a/apps/red-ui/src/app/modules/admin/services/admin-dialog.service.ts b/apps/red-ui/src/app/modules/admin/services/admin-dialog.service.ts index f766a0b10..7fadc8488 100644 --- a/apps/red-ui/src/app/modules/admin/services/admin-dialog.service.ts +++ b/apps/red-ui/src/app/modules/admin/services/admin-dialog.service.ts @@ -29,6 +29,7 @@ import { UserService } from '@users/user.service'; import { IDossierAttributeConfig, IFileAttributeConfig, IReportTemplate } from '@red/domain'; import { ReportTemplateService } from '@services/report-template.service'; 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 = | 'confirm' @@ -40,6 +41,7 @@ type DialogType = | 'addEditUser' | 'smtpAuthConfig' | 'addEditCloneDossierTemplate' + | 'auditInfo' | 'addEditDossierAttribute' | 'uploadDictionary' | 'addEditDossierState' @@ -101,6 +103,9 @@ export class AdminDialogService extends DialogService { component: ConfigureCertificateDialogComponent, dialogConfig: { disableClose: false, maxHeight: '100vh' }, }, + auditInfo: { + component: AuditInfoDialog, + }, }; constructor( diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 1045a6ad2..3813043ba 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -402,7 +402,13 @@ }, "audit": "Aktivitätenprotokoll", "audit-screen": { + "action": { + "info": "Info" + }, "all-users": "Alle Benutzer", + "audit-info-dialog": { + "title": "Audit Info" + }, "categories": { "all-categories": "Alle Bereiche", "audit": "Aktivitätenprotokoll", @@ -1961,6 +1967,7 @@ "save": "", "undo": "" }, + "annotations": "", "title": "" }, "rules-screen": { diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 4ba768210..265506d97 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -402,7 +402,13 @@ }, "audit": "Audit", "audit-screen": { + "action": { + "info": "Info" + }, "all-users": "All Users", + "audit-info-dialog": { + "title": "Audit Info" + }, "categories": { "all-categories": "All Categories", "audit": "Audit", @@ -1961,6 +1967,7 @@ "save": "Save", "undo": "Undo" }, + "annotations": "", "title": "Structured Component Management" }, "rules-screen": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 2e29848a1..8735afdb1 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -402,7 +402,13 @@ }, "audit": "Aktivitätenprotokoll", "audit-screen": { + "action": { + "info": "Info" + }, "all-users": "Alle Benutzer", + "audit-info-dialog": { + "title": "Audit Info" + }, "categories": { "all-categories": "Alle Bereiche", "audit": "Aktivitätenprotokoll", @@ -1961,6 +1967,7 @@ "save": "", "undo": "" }, + "annotations": "", "title": "" }, "rules-screen": { diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 634c5d846..17692aa7a 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -402,7 +402,13 @@ }, "audit": "Audit", "audit-screen": { + "action": { + "info": "Info" + }, "all-users": "All Users", + "audit-info-dialog": { + "title": "Audit Info" + }, "categories": { "all-categories": "All Categories", "audit": "Audit", diff --git a/libs/red-domain/src/lib/audit/audit.model.ts b/libs/red-domain/src/lib/audit/audit.model.ts index 0cad3389f..e36a4e1ca 100644 --- a/libs/red-domain/src/lib/audit/audit.model.ts +++ b/libs/red-domain/src/lib/audit/audit.model.ts @@ -4,11 +4,12 @@ import { IAudit } from './audit'; export class Audit implements IAudit, IListable { readonly recordId: string; readonly category: string; - readonly details?: unknown; + readonly details?: { [key: string]: string }; readonly message: string; readonly objectId?: string; readonly recordDate: string; readonly userId: string; + readonly hasDetails: boolean; constructor(audit: IAudit) { this.category = audit.category; @@ -18,6 +19,7 @@ export class Audit implements IAudit, IListable { this.recordDate = audit.recordDate; this.recordId = audit.recordId; this.userId = audit.userId; + this.hasDetails = audit.details ? Object.keys(audit.details).length > 0 : false; } get id(): string { diff --git a/libs/red-domain/src/lib/audit/audit.ts b/libs/red-domain/src/lib/audit/audit.ts index 12d90b2f2..59b9b785b 100644 --- a/libs/red-domain/src/lib/audit/audit.ts +++ b/libs/red-domain/src/lib/audit/audit.ts @@ -1,6 +1,6 @@ export interface IAudit { readonly category: string; - readonly details?: unknown; + readonly details?: { [key: string]: string }; readonly message: string; readonly objectId?: string; readonly recordDate: string;