From d9712403f86e766e59e01693f011fb0a993a16e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:16:27 +0300 Subject: [PATCH] =?UTF-8?q?AuditLogs=20sayfas=C4=B1nda=20g=C3=BCncellemele?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AuditLogs/AuditLogActionDto.cs | 15 ++ .../AuditLogs/AuditLogAppService.cs | 78 +++++++ .../AuditLogs/AuditLogDto.cs | 35 +++ .../AuditLogs/EntityChangeDto.cs | 22 ++ .../AuditLogs/EntityPropertyChangeDto.cs | 13 ++ .../AuditLogs/LogsAutoMapperProfile.cs | 15 ++ .../Seeds/ListFormsSeeder.cs | 188 +-------------- .../Seeds/MenuSeeder.cs | 16 -- .../Seeds/PermissionSeeder.cs | 33 --- .../PlatformConsts.cs | 1 - .../Kurs.Platform.Domain/Data/SeedConsts.cs | 1 - ui/src/proxy/admin/identity.service.ts | 7 + ui/src/proxy/auditLog/audit-log.ts | 44 ++++ .../views/admin/auditLog/AuditLogDetail.tsx | 214 ++++++++++++++++++ .../DialogContext/DialogShowComponent.tsx | 9 + 15 files changed, 463 insertions(+), 228 deletions(-) create mode 100644 api/src/Kurs.Platform.Application/AuditLogs/AuditLogActionDto.cs create mode 100644 api/src/Kurs.Platform.Application/AuditLogs/AuditLogAppService.cs create mode 100644 api/src/Kurs.Platform.Application/AuditLogs/AuditLogDto.cs create mode 100644 api/src/Kurs.Platform.Application/AuditLogs/EntityChangeDto.cs create mode 100644 api/src/Kurs.Platform.Application/AuditLogs/EntityPropertyChangeDto.cs create mode 100644 api/src/Kurs.Platform.Application/AuditLogs/LogsAutoMapperProfile.cs create mode 100644 ui/src/proxy/auditLog/audit-log.ts create mode 100644 ui/src/views/admin/auditLog/AuditLogDetail.tsx diff --git a/api/src/Kurs.Platform.Application/AuditLogs/AuditLogActionDto.cs b/api/src/Kurs.Platform.Application/AuditLogs/AuditLogActionDto.cs new file mode 100644 index 00000000..f62cf64f --- /dev/null +++ b/api/src/Kurs.Platform.Application/AuditLogs/AuditLogActionDto.cs @@ -0,0 +1,15 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace Kurs.Platform.AuditLogs; + +public class AuditLogActionDto : EntityDto +{ + public virtual Guid AuditLogId { get; protected set; } + public virtual string ServiceName { get; protected set; } + public virtual string MethodName { get; protected set; } + public virtual string Parameters { get; protected set; } + public virtual DateTime ExecutionTime { get; protected set; } + public virtual int ExecutionDuration { get; protected set; } + +} \ No newline at end of file diff --git a/api/src/Kurs.Platform.Application/AuditLogs/AuditLogAppService.cs b/api/src/Kurs.Platform.Application/AuditLogs/AuditLogAppService.cs new file mode 100644 index 00000000..a2d8a7ba --- /dev/null +++ b/api/src/Kurs.Platform.Application/AuditLogs/AuditLogAppService.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.AuditLogging; +using static Kurs.Platform.Data.Seeds.SeedConsts; + +namespace Kurs.Platform.AuditLogs; + +public interface IAuditLogAppService + : ICrudAppService +{ + +} + +[Authorize(AppCodes.AuditLogs)] +public class AuditLogAppService + : CrudAppService + , IAuditLogAppService +{ + public AuditLogAppService(IAuditLogRepository auditLogRepository) : base(auditLogRepository) + { + } + + public override async Task GetAsync(Guid id) + { + var entity = await Repository.GetAsync(id, includeDetails: true); + + return await MapToGetOutputDtoAsync(entity); + } + + public override async Task> GetListAsync(PagedAndSortedResultRequestDto input) + { + var query = await CreateFilteredQueryAsync(input); + + var totalCount = await AsyncExecuter.CountAsync(query); + + query = ApplySorting(query, input); + query = ApplyPaging(query, input); + + var auditLogList = await AsyncExecuter.ToListAsync(query); + + var entityDtos = new List(); + foreach (var item in auditLogList) + { + var dto = await MapToGetListOutputDtoAsync(item); + dto.EntityChangeCount = item.EntityChanges?.Count ?? 0; // null kontrolü artık burada güvenli + entityDtos.Add(dto); + } + + return new PagedResultDto( + totalCount, + entityDtos + ); + } + + // Audit Log kayitlarini gormek istiyoruz fakat degistirmek istemiyoruz + [RemoteService(IsEnabled = false)] + public override Task CreateAsync(AuditLogDto input) + { + return null; + } + + [RemoteService(IsEnabled = false)] + public override Task UpdateAsync(Guid id, AuditLogDto input) + { + return null; + } + + [RemoteService(IsEnabled = false)] + public override Task DeleteAsync(Guid id) + { + return null; + } +} diff --git a/api/src/Kurs.Platform.Application/AuditLogs/AuditLogDto.cs b/api/src/Kurs.Platform.Application/AuditLogs/AuditLogDto.cs new file mode 100644 index 00000000..e1d89d93 --- /dev/null +++ b/api/src/Kurs.Platform.Application/AuditLogs/AuditLogDto.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Application.Dtos; + +namespace Kurs.Platform.AuditLogs; + +public class AuditLogDto : EntityDto +{ + public AuditLogDto() + { + Actions = new List(); + EntityChanges = new List(); + } + + public string ApplicationName { get; set; } + public Guid? UserId { get; protected set; } + public string UserName { get; protected set; } + public DateTime ExecutionTime { get; protected set; } + public int ExecutionDuration { get; protected set; } + public string ClientIpAddress { get; protected set; } + public string ClientName { get; protected set; } + public string ClientId { get; set; } + public string CorrelationId { get; set; } + public string BrowserInfo { get; protected set; } + public string HttpMethod { get; protected set; } + public string Url { get; protected set; } + public string Exceptions { get; protected set; } + public string Comments { get; protected set; } + public int? HttpStatusCode { get; set; } + public ICollection EntityChanges { get; protected set; } + public ICollection Actions { get; protected set; } + + public int? EntityChangeCount { get; set; } + +} diff --git a/api/src/Kurs.Platform.Application/AuditLogs/EntityChangeDto.cs b/api/src/Kurs.Platform.Application/AuditLogs/EntityChangeDto.cs new file mode 100644 index 00000000..ba66fd27 --- /dev/null +++ b/api/src/Kurs.Platform.Application/AuditLogs/EntityChangeDto.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Auditing; + +namespace Kurs.Platform.AuditLogs; + +public class EntityChangeDto : EntityDto +{ + public EntityChangeDto() + { + PropertyChanges = new List(); + } + + public virtual Guid AuditLogId { get; protected set; } + public virtual DateTime ChangeTime { get; protected set; } + public virtual EntityChangeType ChangeType { get; protected set; } + public virtual Guid? EntityTenantId { get; protected set; } + public virtual string EntityId { get; protected set; } + public virtual string EntityTypeFullName { get; protected set; } + public virtual ICollection PropertyChanges { get; protected set; } +} diff --git a/api/src/Kurs.Platform.Application/AuditLogs/EntityPropertyChangeDto.cs b/api/src/Kurs.Platform.Application/AuditLogs/EntityPropertyChangeDto.cs new file mode 100644 index 00000000..eb1c17b4 --- /dev/null +++ b/api/src/Kurs.Platform.Application/AuditLogs/EntityPropertyChangeDto.cs @@ -0,0 +1,13 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace Kurs.Platform.AuditLogs; + +public class EntityPropertyChangeDto : EntityDto +{ + public virtual Guid EntityChangeId { get; protected set; } + public virtual string NewValue { get; protected set; } + public virtual string OriginalValue { get; protected set; } + public virtual string PropertyName { get; protected set; } + public virtual string PropertyTypeFullName { get; protected set; } +} diff --git a/api/src/Kurs.Platform.Application/AuditLogs/LogsAutoMapperProfile.cs b/api/src/Kurs.Platform.Application/AuditLogs/LogsAutoMapperProfile.cs new file mode 100644 index 00000000..4e371692 --- /dev/null +++ b/api/src/Kurs.Platform.Application/AuditLogs/LogsAutoMapperProfile.cs @@ -0,0 +1,15 @@ +using AutoMapper; +using Volo.Abp.AuditLogging; + +namespace Kurs.Platform.AuditLogs; + +public class LogsAutoMapperProfile : Profile +{ + public LogsAutoMapperProfile() + { + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + } +} diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/ListFormsSeeder.cs b/api/src/Kurs.Platform.DbMigrator/Seeds/ListFormsSeeder.cs index c8dba414..4d3305a1 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/ListFormsSeeder.cs +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/ListFormsSeeder.cs @@ -7341,6 +7341,17 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency LoadPanelEnabled = "auto", LoadPanelText = "Loading..." }), + CommandColumnJson = JsonSerializer.Serialize(new CommandColumnDto[] { + new CommandColumnDto() { + Hint = "Details", + Text = "Details", + AuthName = AppCodes.AuditLogs, + DialogName = "AuditLogDetail", + DialogParameters = JsonSerializer.Serialize(new { + id = "@Id", + }) + }, + }), } ); @@ -7584,183 +7595,6 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency #endregion #endregion - #region Entity Changes - var listFormEntityChange = await _listFormRepository.InsertAsync( - new ListForm() - { - CultureName = LanguageCodes.En, - ListFormCode = ListFormCodes.EntityChange, - Name = AppCodes.EntityChanges, - Title = AppCodes.EntityChanges, - DataSourceCode = SeedConsts.DataSources.DefaultCode, - IsTenant = true, - IsOrganizationUnit = false, - Description = AppCodes.EntityChanges, - SelectCommandType = SelectCommandTypeEnum.Table, - SelectCommand = "AbpEntityChanges", - KeyFieldName = "Id", - KeyFieldDbSourceType = DbType.Guid, - SortMode = GridOptions.SortModeSingle, - FilterRowJson = JsonSerializer.Serialize(new GridFilterRowDto - { - Visible = true - }), - HeaderFilterJson = JsonSerializer.Serialize(new - { - Visible = true - }), - SearchPanelJson = JsonSerializer.Serialize(new - { - Visible = true - }), - GroupPanelJson = JsonSerializer.Serialize(new - { - Visible = true - }), - SelectionJson = JsonSerializer.Serialize(new SelectionDto - { - Mode = GridOptions.SelectionModeSingle, - AllowSelectAll = false - }), - ColumnOptionJson = JsonSerializer.Serialize(new - { - ColumnFixingEnabled = true, - ColumnChooserEnabled = true - }), - PermissionJson = JsonSerializer.Serialize(new PermissionCrudDto - { - C = AppCodes.EntityChanges + ".Create", - R = AppCodes.EntityChanges, - U = AppCodes.EntityChanges + ".Update", - D = AppCodes.EntityChanges + ".Delete", - E = AppCodes.EntityChanges + ".Export", - }), - PagerOptionJson = JsonSerializer.Serialize(new GridPagerOptionDto - { - Visible = true, - AllowedPageSizes = "10,20,50,100", - ShowPageSizeSelector = true, - ShowNavigationButtons = true, - ShowInfo = false, - InfoText = "Page {0} of {1} ({2} items)", - DisplayMode = GridColumnOptions.PagerDisplayModeAdaptive, - ScrollingMode = GridColumnOptions.ScrollingModeStandard, - LoadPanelEnabled = "auto", - LoadPanelText = "Loading..." - }), - } - ); - - #region Entity Changes Fields - await _listFormFieldRepository.InsertManyAsync( - [ - new() { - ListFormCode = listFormEntityChange.ListFormCode, - RoleId = null, - UserId = null, - CultureName = LanguageCodes.En, - SourceDbType = DbType.Guid, - FieldName = "Id", - Width = 100, - ListOrderNo = 1, - Visible = false, - IsActive = true, - IsDeleted = false, - PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto - { - C = AppCodes.AuditLogs + ".Create", - R = AppCodes.AuditLogs, - U = AppCodes.AuditLogs + ".Update", - E = true, - Deny = false - }), - PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto - { - IsPivot = true - }) - }, - new() { - ListFormCode = listFormEntityChange.ListFormCode, - RoleId = null, - UserId = null, - CultureName = LanguageCodes.En, - SourceDbType = DbType.DateTime, - FieldName = "ChangeTime", - Width = 150, - ListOrderNo = 2, - Visible = true, - IsActive = true, - IsDeleted = false, - AllowSearch = true, - PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto - { - C = AppCodes.AuditLogs + ".Create", - R = AppCodes.AuditLogs, - U = AppCodes.AuditLogs + ".Update", - E = true, - Deny = false - }), - PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto - { - IsPivot = true - }) - }, - new() { - ListFormCode = listFormEntityChange.ListFormCode, - RoleId = null, - UserId = null, - CultureName = LanguageCodes.En, - SourceDbType = DbType.String, - FieldName = "ChangeType", - Width = 125, - ListOrderNo = 3, - Visible = true, - IsActive = true, - IsDeleted = false, - AllowSearch = true, - PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto - { - C = AppCodes.AuditLogs + ".Create", - R = AppCodes.AuditLogs, - U = AppCodes.AuditLogs + ".Update", - E = true, - Deny = false - }), - PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto - { - IsPivot = true - }) - }, - new() { - ListFormCode = listFormEntityChange.ListFormCode, - RoleId = null, - UserId = null, - CultureName = LanguageCodes.En, - SourceDbType = DbType.String, - FieldName = "EntityTypeFullName", - Width = 300, - ListOrderNo = 4, - Visible = true, - IsActive = true, - IsDeleted = false, - AllowSearch = true, - PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto - { - C = AppCodes.AuditLogs + ".Create", - R = AppCodes.AuditLogs, - U = AppCodes.AuditLogs + ".Update", - E = true, - Deny = false - }), - PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto - { - IsPivot = true - }) - }, - ]); - #endregion - #endregion - #region Branches var listFormBranches = await _listFormRepository.InsertAsync( new ListForm() diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/MenuSeeder.cs b/api/src/Kurs.Platform.DbMigrator/Seeds/MenuSeeder.cs index 14d3aba7..9ab36a50 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/MenuSeeder.cs +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/MenuSeeder.cs @@ -501,22 +501,6 @@ public class MenuSeeder : IDataSeedContributor, ITransientDependency RequiredPermissionName = AppCodes.AuditLogs }); - //Entity Changes - await _repository.InsertAsync(new Menu - { - Code = AppCodes.EntityChanges, - DisplayName = AppCodes.EntityChanges, - Order = 9, - IsDisabled = false, - ParentCode = menuAdministration.Code, - Icon = "FcSurvey", - Target = null, - ElementId = null, - CssClass = null, - Url = $"/list/{PlatformConsts.ListFormCodes.EntityChange}", - RequiredPermissionName = AppCodes.EntityChanges - }); - #endregion } } diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/PermissionSeeder.cs b/api/src/Kurs.Platform.DbMigrator/Seeds/PermissionSeeder.cs index 713fb4a3..f9b18ae9 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/PermissionSeeder.cs +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/PermissionSeeder.cs @@ -837,39 +837,6 @@ public class PermissionSeeder : IDataSeedContributor, ITransientDependency } #endregion - #region EntityChanges - await repositoryGroup.InsertAsync(new PermissionGroupDefinitionRecord - { - Name = AppCodes.EntityChanges, - DisplayName = AppCodes.EntityChanges - }); - - var permEntityChanges = await repository.InsertAsync( - GetNewPermission( - AppCodes.EntityChanges, - AppCodes.EntityChanges, - AppCodes.EntityChanges, - null, - true, - MultiTenancySides.Both - )); - - foreach (var item in CUDE) - { - permissionName = AppCodes.EntityChanges + "." + item; - - await repository.InsertAsync( - GetNewPermission( - AppCodes.EntityChanges, - permissionName, - item, - permEntityChanges.Name, - true, - MultiTenancySides.Both - )); - } - #endregion - #region Branches await repositoryGroup.InsertAsync(new PermissionGroupDefinitionRecord { diff --git a/api/src/Kurs.Platform.Domain.Shared/PlatformConsts.cs b/api/src/Kurs.Platform.Domain.Shared/PlatformConsts.cs index ba4ebf5f..65a0633b 100644 --- a/api/src/Kurs.Platform.Domain.Shared/PlatformConsts.cs +++ b/api/src/Kurs.Platform.Domain.Shared/PlatformConsts.cs @@ -327,7 +327,6 @@ public static class PlatformConsts public const string GlobalSearch = "List-0018"; public const string SecurityLog = "List-0019"; public const string AuditLog = "List-0020"; - public const string EntityChange = "List-0021"; public const string Branch = "List-0022"; public const string ListformField = "List-1000"; public const string Order = "List-Order"; diff --git a/api/src/Kurs.Platform.Domain/Data/SeedConsts.cs b/api/src/Kurs.Platform.Domain/Data/SeedConsts.cs index 197b72f9..46fe4f51 100644 --- a/api/src/Kurs.Platform.Domain/Data/SeedConsts.cs +++ b/api/src/Kurs.Platform.Domain/Data/SeedConsts.cs @@ -362,7 +362,6 @@ public static class SeedConsts public const string IpRestrictions = Prefix.App + ".IpRestrictions"; public const string PublicApis = Prefix.App + ".PublicApis"; public const string AuditLogs = Prefix.App + ".AuditLogs"; - public const string EntityChanges = Prefix.App + ".EntityChanges"; public const string Branches = Prefix.App + ".Branches"; } diff --git a/ui/src/proxy/admin/identity.service.ts b/ui/src/proxy/admin/identity.service.ts index 34b7d58d..9824adc5 100644 --- a/ui/src/proxy/admin/identity.service.ts +++ b/ui/src/proxy/admin/identity.service.ts @@ -8,6 +8,7 @@ import { UserInfoViewModel, } from '@/proxy/admin' import apiService from '@/services/api.service' +import { AuditLogDto } from '../auditLog/audit-log' export const getRoles = (skipCount = 0, maxResultCount = 10) => apiService.fetchData>({ @@ -65,3 +66,9 @@ export const updatePermissions = ( url: `/api/permission-management/permissions?providerName=${providerName}&providerKey=${providerKey}`, data: input, }) + +export const getAuditLogs = (id: string) => + apiService.fetchData({ + method: 'GET', + url: `/api/app/audit-log/${id}`, + }) \ No newline at end of file diff --git a/ui/src/proxy/auditLog/audit-log.ts b/ui/src/proxy/auditLog/audit-log.ts new file mode 100644 index 00000000..02055096 --- /dev/null +++ b/ui/src/proxy/auditLog/audit-log.ts @@ -0,0 +1,44 @@ +export interface AuditLogActionDto { + serviceName: string + methodName: string + executionTime: string // Date string + executionDuration: number + parameters: string +} + +export interface EntityPropertyChangeDto { + propertyName: string + propertyTypeFullName: string + originalValue: string | null + newValue: string | null +} + +export interface EntityChangeDto { + changeTime: string // Date string + changeType: number + entityId: string + entityTypeFullName: string + propertyChanges: EntityPropertyChangeDto[] +} + +export interface AuditLogDto { + id: string + applicationName: string + userId?: string + userName?: string + executionTime: string + executionDuration: number + clientIpAddress?: string + clientName?: string + clientId?: string + correlationId?: string + browserInfo?: string + httpMethod?: string + url?: string + exceptions?: string + comments?: string + httpStatusCode?: number + entityChangeCount?: number + entityChanges: EntityChangeDto[] + actions: AuditLogActionDto[] +} diff --git a/ui/src/views/admin/auditLog/AuditLogDetail.tsx b/ui/src/views/admin/auditLog/AuditLogDetail.tsx new file mode 100644 index 00000000..1dc6f0a3 --- /dev/null +++ b/ui/src/views/admin/auditLog/AuditLogDetail.tsx @@ -0,0 +1,214 @@ +import { useEffect, useState } from 'react' +import Dialog from '@/components/ui/Dialog' +import TabList from '@/components/ui/Tabs/TabList' +import TabNav from '@/components/ui/Tabs/TabNav' +import TabContent from '@/components/ui/Tabs/TabContent' +import { Tabs } from '@/components/ui' +import { AdaptableCard } from '@/components/shared' +import { getAuditLogs } from '@/proxy/admin/identity.service' +import { AuditLogDto } from '@/proxy/auditLog/audit-log' + +function AuditLogs({ + open, + onDialogClose, + id, +}: { + open: boolean + onDialogClose: () => void + id: string +}) { + const [selectedLog, setSelectedLog] = useState() + + useEffect(() => { + if (open && id) { + fetchAuditLog(id) + } + }, [open, id]) + + const fetchAuditLog = async (logId: string) => { + const response = await getAuditLogs(logId) + setSelectedLog(response.data) + } + + return ( + +
+ Audit Log Detail + {selectedLog?.id && ( + ({selectedLog.id}) + )} +
+ + {!selectedLog ? ( +
Loading...
+ ) : ( + + + Log + + Actions {selectedLog.actions?.length > 0 && `(${selectedLog.actions.length})`} + + + Entity Changes{' '} + {selectedLog.entityChanges?.length > 0 && `(${selectedLog.entityChanges.length})`} + + + + {/* LOG DETAILS */} + +
+ +
Request Info
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User{selectedLog.userName}
Time{new Date(selectedLog.executionTime).toLocaleString()}
Duration{selectedLog.executionDuration} ms
IP{selectedLog.clientIpAddress}
Method{selectedLog.httpMethod}
Status Code{selectedLog.httpStatusCode}
URL{selectedLog.url}
+
+ + +
Client Info
+ + + + + + + + + + + +
Browser{selectedLog.browserInfo}
Exceptions +
+                          {selectedLog.exceptions || 'None'}
+                        
+
+
+
+
+ + {/* ACTIONS */} + + {selectedLog.actions?.map((action, index) => ( + +
Action #{index + 1}
+ + + + + + + + + + + + + + + + + + + + + + + +
Service{action.serviceName}
Method{action.methodName}
Time{action.executionTime}
Duration{action.executionDuration} ms
Parameters +
+                          {action.parameters}
+                        
+
+
+ ))} +
+ + {/* ENTITY CHANGES */} + + {selectedLog.entityChanges?.map((change, index) => ( + +
Change #{index + 1}
+ + + + + + + + + + + + + + + + + + + + + + + +
Time{new Date(change.changeTime).toLocaleString()}
Type{change.changeType}
Entity ID{change.entityId}
Entity Type{change.entityTypeFullName}
Property Changes +
    + {change.propertyChanges.map((p, i) => ( +
  • + {p.propertyName} ({p.propertyTypeFullName}):{' '} + {!p.originalValue || p.originalValue === 'null' ? ( + + {p.newValue} + + ) : ( + <> + {p.originalValue}{' '} + + + {p.newValue} + + + )} +
  • + ))} +
+
+
+ ))} +
+
+ )} +
+ ) +} + +export default AuditLogs diff --git a/ui/src/views/shared/DialogContext/DialogShowComponent.tsx b/ui/src/views/shared/DialogContext/DialogShowComponent.tsx index 3a4a3390..82253d76 100644 --- a/ui/src/views/shared/DialogContext/DialogShowComponent.tsx +++ b/ui/src/views/shared/DialogContext/DialogShowComponent.tsx @@ -3,6 +3,7 @@ import UsersPermission from '@/views/admin/identity/Users/UsersPermission' import TenantsConnectionString from '@/views/admin/tenant-management/TenantsConnectionString' import { useDialogContext } from './DialogProvider' import CreateNotification from '@/views/admin/notification/CreateNotification' +import AuditLogDetail from '@/views/admin/auditLog/AuditLogDetail' const DialogShowComponent = (): JSX.Element => { const dialogContext: any = useDialogContext() @@ -41,6 +42,14 @@ const DialogShowComponent = (): JSX.Element => { {...dialogContext.config?.props} > ) + case 'AuditLogDetail': + return ( + dialogContext.setConfig({})} + {...dialogContext.config?.props} + > + ) default: return <> }