diff --git a/ui-ngx/src/app/core/http/audit-log.service.ts b/ui-ngx/src/app/core/http/audit-log.service.ts index 8b49fd6da1..f45819db15 100644 --- a/ui-ngx/src/app/core/http/audit-log.service.ts +++ b/ui-ngx/src/app/core/http/audit-log.service.ts @@ -15,12 +15,12 @@ /// import { Injectable } from '@angular/core'; -import { defaultHttpOptionsFromConfig, RequestConfig } from './http-utils'; +import { createDefaultHttpOptions, RequestConfig } from './http-utils'; import { Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { TimePageLink } from '@shared/models/page/page-link'; import { PageData } from '@shared/models/page/page-data'; -import { AuditLog, AuditLogQuery } from '@shared/models/audit-log.models'; +import { AuditLog, AuditLogFilter } from '@shared/models/audit-log.models'; import { EntityId } from '@shared/models/id/entity-id'; @Injectable({ @@ -32,28 +32,58 @@ export class AuditLogService { private http: HttpClient ) { } - public getAuditLogs(auditLogQuery: AuditLogQuery, - config?: RequestConfig): Observable> { - return this.http.get>(`/api/audit/logs${auditLogQuery.toQuery()}`, - defaultHttpOptionsFromConfig(config)); + public getAuditLogs(pageLink: TimePageLink, config?: RequestConfig): Observable>; + public getAuditLogs(pageLink: TimePageLink, filters: AuditLogFilter, config?: RequestConfig): Observable>; + public getAuditLogs( + pageLink: TimePageLink, + filtersOrConfig?: AuditLogFilter | RequestConfig, + config?: RequestConfig + ): Observable> { + return this.http.get>( + `/api/audit/logs${pageLink.toQuery()}`, + createDefaultHttpOptions(filtersOrConfig, config) + ); } - public getAuditLogsByCustomerId(auditLogQuery: AuditLogQuery, - config?: RequestConfig): Observable> { - return this.http.get>(`/api/audit/logs/customer/${auditLogQuery.toQuery()}`, - defaultHttpOptionsFromConfig(config)); + public getAuditLogsByCustomerId(customerId: string, pageLink: TimePageLink, config?: RequestConfig): Observable>; + public getAuditLogsByCustomerId(customerId: string, pageLink: TimePageLink, filters: AuditLogFilter, config?: RequestConfig): Observable>; + public getAuditLogsByCustomerId( + customerId: string, + pageLink: TimePageLink, + filtersOrConfig?: AuditLogFilter | RequestConfig, + config?: RequestConfig + ): Observable> { + return this.http.get>( + `/api/audit/logs/customer/${customerId}${pageLink.toQuery()}`, + createDefaultHttpOptions(filtersOrConfig, config) + ); } - public getAuditLogsByUserId(auditLogQuery: AuditLogQuery, - config?: RequestConfig): Observable> { - return this.http.get>(`/api/audit/logs/user/${auditLogQuery.toQuery()}`, - defaultHttpOptionsFromConfig(config)); + public getAuditLogsByUserId(userId: string, pageLink: TimePageLink, config?: RequestConfig): Observable>; + public getAuditLogsByUserId(userId: string, pageLink: TimePageLink, filters: AuditLogFilter, config?: RequestConfig): Observable>; + public getAuditLogsByUserId( + userId: string, + pageLink: TimePageLink, + filtersOrConfig?: AuditLogFilter | RequestConfig, + config?: RequestConfig + ): Observable> { + return this.http.get>( + `/api/audit/logs/user/${userId}${pageLink.toQuery()}`, + createDefaultHttpOptions(filtersOrConfig, config) + ); } - public getAuditLogsByEntityId(auditLogQuery: AuditLogQuery, - config?: RequestConfig): Observable> { - return this.http.get>(`/api/audit/logs/entity/${auditLogQuery.toQuery()}`, - defaultHttpOptionsFromConfig(config)); + public getAuditLogsByEntityId(entityId: EntityId, pageLink: TimePageLink, config?: RequestConfig): Observable>; + public getAuditLogsByEntityId(entityId: EntityId, pageLink: TimePageLink, filters: AuditLogFilter, config?: RequestConfig): Observable>; + public getAuditLogsByEntityId( + entityId: EntityId, + pageLink: TimePageLink, + filtersOrConfig?: AuditLogFilter | RequestConfig, + config?: RequestConfig + ): Observable> { + return this.http.get>( + `/api/audit/logs/entity/${entityId.entityType}/${entityId.id}${pageLink.toQuery()}`, + createDefaultHttpOptions(filtersOrConfig, config) + ); } - } diff --git a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.html b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.html index 7e0a104ef4..b97285ba07 100644 --- a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.html +++ b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.html @@ -15,24 +15,36 @@ limitations under the License. --> - - - - - - - - + + -
- + +
+
+
audit-log.filter-types
+ + +
+
+ +
- -
- - -
-
diff --git a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.scss b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.scss index 502899f838..77bd5aea60 100644 --- a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.scss +++ b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.scss @@ -14,8 +14,7 @@ * limitations under the License. */ :host { - display: block; - overflow: hidden; + display: flex; max-width: 100%; padding-right: 20px; .mdc-button { diff --git a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.ts b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.ts index c2559fdfbc..41d6838120 100644 --- a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.ts +++ b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-filter.component.ts @@ -14,28 +14,27 @@ /// limitations under the License. /// -import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; +import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; import { TemplatePortal } from '@angular/cdk/portal'; -import { ChangeDetectorRef, Component, DestroyRef, ElementRef, forwardRef, Inject, InjectionToken, Input, OnInit, Optional, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core'; +import { ChangeDetectorRef, Component, DestroyRef, ElementRef, forwardRef, Input, OnInit, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { isDefinedAndNotNull } from '@app/core/utils'; +import { isDefined, isDefinedAndNotNull } from '@app/core/utils'; import { StringItemsOption } from '@app/shared/components/string-items-list.component'; -import { ActionType, actionTypeTranslations, AuditLogFilter, coerceBoolean } from '@app/shared/public-api'; +import { + ActionType, + actionTypeTranslations, + auditLogFilterEquals, + AuditLogFilter, + POSITION_MAP, +} from '@app/shared/public-api'; import { TranslateService } from '@ngx-translate/core'; - -export const AUDIT_LOG_FILTER_CONFIG_DATA = new InjectionToken('AuditLogFilterConfigData'); - -export interface AuditLogConfigData { - panelMode: boolean; - auditLogFilter: AuditLogFilter; -} - +// @dynamic @Component({ selector: 'tb-audit-log-filter', templateUrl: './audit-log-filter.component.html', - styleUrl: './audit-log-filter.component.scss', + styleUrls: ['./audit-log-filter.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -45,23 +44,17 @@ export interface AuditLogConfigData { ] }) export class AuditLogFilterComponent implements OnInit, ControlValueAccessor { - + @ViewChild('auditLogFilterPanel') auditLogFilterPanel: TemplateRef; @Input() disabled: boolean; - @coerceBoolean() - @Input() - buttonMode = true; - ActionType = ActionType; actionTypes = Object.values(ActionType); - - actionTypeTranslations = actionTypeTranslations; - panelMode = false; + actionTypeTranslations = actionTypeTranslations; buttonDisplayValue = this.translate.instant('audit-log.filter'); @@ -69,17 +62,13 @@ export class AuditLogFilterComponent implements OnInit, ControlValueAccessor { auditLogOverlayRef: OverlayRef; - panelResult: AuditLogFilter = null; + initialAuditLogFilter: AuditLogFilter; private auditLogFilter: AuditLogFilter; private propagateChange = (_: any) => {}; - constructor(@Optional() @Inject(AUDIT_LOG_FILTER_CONFIG_DATA) - private data: AuditLogConfigData | undefined, - @Optional() - private overlayRef: OverlayRef, - private fb: UntypedFormBuilder, + constructor(private fb: UntypedFormBuilder, private translate: TranslateService, private overlay: Overlay, private nativeElement: ElementRef, @@ -88,27 +77,16 @@ export class AuditLogFilterComponent implements OnInit, ControlValueAccessor { private destroyRef: DestroyRef) {} ngOnInit(): void { - if (this.data) { - this.panelMode = this.data.panelMode; - this.auditLogFilter = this.data.auditLogFilter; - } this.auditLogFilterForm = this.fb.group({ - types: ['', []] + actionTypes: [[]] }); - this.auditLogFilterForm.valueChanges.pipe( takeUntilDestroyed(this.destroyRef) ).subscribe( () => { this.updateValidators(); - if (!this.buttonMode) { - this.auditLogFilterUpdated(this.auditLogFilterForm.value); - } } ); - if (this.panelMode) { - this.updateAuditLogFilterForm(this.auditLogFilter); - } } registerOnChange(fn: any): void { @@ -127,18 +105,21 @@ export class AuditLogFilterComponent implements OnInit, ControlValueAccessor { this.updateValidators(); } } - + writeValue(auditLogFilter?: AuditLogFilter): void { this.auditLogFilter = auditLogFilter; + if(!this.initialAuditLogFilter && isDefined(this.auditLogFilter)) { + this.initialAuditLogFilter = this.auditLogFilterForm.getRawValue(); + } this.updateButtonDisplayValue(); this.updateAuditLogFilterForm(auditLogFilter); } - + get predefinedTypeValues (): StringItemsOption[] { return [...this.actionTypes].map(type => ({ name: this.translate.instant(this.actionTypeTranslations.get(type)), value: type - })) + })); } private updateValidators() { @@ -157,14 +138,9 @@ export class AuditLogFilterComponent implements OnInit, ControlValueAccessor { minWidth: '' }); config.hasBackdrop = true; - const connectedPosition: ConnectedPosition = { - originX: 'start', - originY: 'bottom', - overlayX: 'start', - overlayY: 'top' - }; - config.positionStrategy = this.overlay.position().flexibleConnectedTo(this.nativeElement) - .withPositions([connectedPosition]); + config.positionStrategy = this.overlay.position() + .flexibleConnectedTo(this.nativeElement) + .withPositions([POSITION_MAP.bottomLeft]); this.auditLogOverlayRef = this.overlay.create(config); this.auditLogOverlayRef.backdropClick().subscribe(() => { @@ -176,28 +152,26 @@ export class AuditLogFilterComponent implements OnInit, ControlValueAccessor { cancel() { this.updateAuditLogFilterForm(this.auditLogFilter); - if (this.overlayRef) { - this.overlayRef.dispose(); - } else { - this.auditLogOverlayRef.dispose(); - } + this.auditLogOverlayRef.dispose(); } update() { this.auditLogFilterUpdated(this.auditLogFilterForm.value); - if (this.panelMode) { - this.panelResult = this.auditLogFilter; - } - if (this.overlayRef) { - this.overlayRef.dispose(); - } else { - this.auditLogOverlayRef.dispose(); + this.auditLogOverlayRef.dispose(); + } + + reset() { + if (this.initialAuditLogFilter) { + if (!auditLogFilterEquals(this.auditLogFilter, this.initialAuditLogFilter)) { + this.updateAuditLogFilterForm(this.initialAuditLogFilter); + this.auditLogFilterForm.markAsDirty(); + } } } private updateAuditLogFilterForm(auditLogFilter?: AuditLogFilter) { this.auditLogFilterForm.patchValue({ - types: auditLogFilter?.types, + actionTypes: auditLogFilter?.actionTypes, }, {emitEvent: false}); this.updateValidators(); } @@ -209,18 +183,16 @@ export class AuditLogFilterComponent implements OnInit, ControlValueAccessor { } private updateButtonDisplayValue() { - if (this.buttonMode) { - const filterTextParts: string[] = []; - if (isDefinedAndNotNull(this.auditLogFilter?.types)) { - const types = this.auditLogFilter.types; - types.forEach(type => filterTextParts.push(this.translate.instant(this.actionTypeTranslations.get(type as ActionType)))) - } - if (!filterTextParts.length) { - this.buttonDisplayValue = this.translate.instant('audit-log.audit-log-filter-title'); - } else { - this.buttonDisplayValue = this.translate.instant('audit-log.filter-title') + `: ${filterTextParts.join(', ')}`; - } - this.cd.detectChanges(); + const filterTextParts: string[] = []; + if (isDefinedAndNotNull(this.auditLogFilter?.actionTypes)) { + const actionTypes = this.auditLogFilter.actionTypes; + actionTypes.forEach(actionType => filterTextParts.push(this.translate.instant(this.actionTypeTranslations.get(actionType as ActionType)))) + } + if (!filterTextParts.length) { + this.buttonDisplayValue = this.translate.instant('audit-log.audit-log-filter-title'); + } else { + this.buttonDisplayValue = this.translate.instant('audit-log.filter-title') + `: ${filterTextParts.join(', ')}`; } + this.cd.detectChanges(); } } diff --git a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-header.component.scss b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-header.component.scss new file mode 100644 index 0000000000..ee0899b5ca --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-header.component.scss @@ -0,0 +1,21 @@ +/** + * Copyright © 2016-2025 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +:host { + padding-right: 8px; + overflow: hidden; + max-width: 100%; +} diff --git a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-header.component.ts b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-header.component.ts index e596c74460..f3635415a7 100644 --- a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-header.component.ts +++ b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-header.component.ts @@ -26,13 +26,12 @@ import { Store } from '@ngrx/store'; styles: `` }) export class AuditLogHeaderComponent extends EntityTableHeaderComponent { - + constructor(protected store: Store) { super(store) } auditLogFiltersChanged(auditLogFilter: AuditLogFilter) { - console.log("auditLogFilter",auditLogFilter ) this.entitiesTableConfig.componentsData.auditLogFilter = auditLogFilter; this.entitiesTableConfig.getTable().resetSortAndFilter(true, true); } diff --git a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-table-config.ts b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-table-config.ts index e70ee5aec7..edad7b2cb7 100644 --- a/ui-ngx/src/app/modules/home/components/audit-log/audit-log-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/audit-log/audit-log-table-config.ts @@ -26,8 +26,7 @@ import { actionTypeTranslations, AuditLog, AuditLogMode, - AuditLogQuery, - AuditLogRequestParams + AuditLogFilter } from '@shared/models/audit-log.models'; import { AliasEntityType, @@ -50,7 +49,7 @@ import { AuditLogDetailsDialogComponent, AuditLogDetailsDialogData } from '@home/components/audit-log/audit-log-details-dialog.component'; -import { deepClone, isDefinedAndNotNull } from '@app/core/utils'; +import { deepClone } from '@app/core/utils'; import { AuditLogHeaderComponent } from '@home/components/audit-log/audit-log-header.component'; export class AuditLogTableConfig extends EntityTableConfig { @@ -84,7 +83,9 @@ export class AuditLogTableConfig extends EntityTableConfig; - if(!isDefinedAndNotNull(this.componentsData)) this.componentsData = {} + this.componentsData = { + auditLogFilter: [] + }; this.entitiesFetchFunction = pageLink => this.fetchAuditLogs(pageLink); @@ -146,19 +147,16 @@ export class AuditLogTableConfig extends EntityTableConfig> { - const auditLogFilter: AuditLogRequestParams = deepClone(this.componentsData?.auditLogFilter) || {}; + const auditLogFilter: AuditLogFilter = deepClone(this.componentsData?.auditLogFilter) || {}; switch (this.auditLogMode) { case AuditLogMode.TENANT: - return this.auditLogService.getAuditLogs(this.prepareAuditLogQuery(pageLink, auditLogFilter)); + return this.auditLogService.getAuditLogs(pageLink, auditLogFilter); case AuditLogMode.ENTITY: - auditLogFilter.id = `${this.entityId.entityType}/${this.entityId.id}`; - return this.auditLogService.getAuditLogsByEntityId(this.prepareAuditLogQuery(pageLink, auditLogFilter)); + return this.auditLogService.getAuditLogsByEntityId(this.entityId, pageLink, auditLogFilter); case AuditLogMode.USER: - auditLogFilter.id = this.userId.id; - return this.auditLogService.getAuditLogsByUserId(this.prepareAuditLogQuery(pageLink, auditLogFilter)); + return this.auditLogService.getAuditLogsByUserId(this.userId.id, pageLink, auditLogFilter); case AuditLogMode.CUSTOMER: - auditLogFilter.id = this.customerId.id; - return this.auditLogService.getAuditLogsByCustomerId(this.prepareAuditLogQuery(pageLink, auditLogFilter)); + return this.auditLogService.getAuditLogsByCustomerId(this.customerId.id, pageLink, auditLogFilter); } } @@ -172,8 +170,4 @@ export class AuditLogTableConfig extends EntityTableConfig, return this.entitiesTableConfigValue; } - protected constructor(protected store: Store) { - super(store); + protected constructor(...args: unknown[]) { + super(); } ngOnInit() { diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index 7959565151..7a94a84d2c 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -23,7 +23,7 @@ import { DetailsPanelComponent } from '@home/components/details-panel.component' import { EntityDetailsPanelComponent } from '@home/components/entity/entity-details-panel.component'; import { AuditLogDetailsDialogComponent } from '@home/components/audit-log/audit-log-details-dialog.component'; import { AuditLogTableComponent } from '@home/components/audit-log/audit-log-table.component'; -import { AuditLogFilterComponent } from '@home/components/audit-log/audit-log-filter.component'; +import { AuditLogHeaderComponent } from '@home/components/audit-log/audit-log-header.component'; import { EventTableHeaderComponent } from '@home/components/event/event-table-header.component'; import { EventTableComponent } from '@home/components/event/event-table.component'; import { EventFilterPanelComponent } from '@home/components/event/event-filter-panel.component'; @@ -198,6 +198,7 @@ import { import { CalculatedFieldsModule } from '@home/components/calculated-fields/calculated-field.module'; import { AlarmRuleModule } from "@home/components/alarm-rules/alarm-rule.module"; import { AlarmRulesTableComponent } from "@home/components/alarm-rules/alarm-rules-table.component"; +import { AuditLogFilterComponent } from "@home/components/audit-log/audit-log-filter.component"; @NgModule({ declarations: @@ -209,7 +210,6 @@ import { AlarmRulesTableComponent } from "@home/components/alarm-rules/alarm-rul EntityDetailsPanelComponent, EntityDetailsPageComponent, AuditLogTableComponent, - AuditLogFilterComponent, AuditLogDetailsDialogComponent, CalculatedFieldsTableComponent, CalculatedFieldDebugDialogComponent, @@ -350,6 +350,8 @@ import { AlarmRulesTableComponent } from "@home/components/alarm-rules/alarm-rul AIModelDialogComponent, ResourcesDialogComponent, ResourcesLibraryComponent, + AuditLogHeaderComponent, + AuditLogFilterComponent ], imports: [ CommonModule, diff --git a/ui-ngx/src/app/modules/home/pages/audit-log/audit-log.module.ts b/ui-ngx/src/app/modules/home/pages/audit-log/audit-log.module.ts index a70971f6ac..5f7c4b0626 100644 --- a/ui-ngx/src/app/modules/home/pages/audit-log/audit-log.module.ts +++ b/ui-ngx/src/app/modules/home/pages/audit-log/audit-log.module.ts @@ -18,17 +18,12 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@shared/shared.module'; import { AuditLogRoutingModule } from '@modules/home/pages/audit-log/audit-log-routing.module'; -import { AuditLogHeaderComponent } from '@home/components/audit-log/audit-log-header.component'; -import { HomeComponentsModule } from '@home/components/public-api'; @NgModule({ - declarations: [ - AuditLogHeaderComponent, - ], + declarations: [], imports: [ CommonModule, SharedModule, - HomeComponentsModule, AuditLogRoutingModule ] }) diff --git a/ui-ngx/src/app/shared/models/audit-log.models.ts b/ui-ngx/src/app/shared/models/audit-log.models.ts index 6449678b45..6c3fc5f062 100644 --- a/ui-ngx/src/app/shared/models/audit-log.models.ts +++ b/ui-ngx/src/app/shared/models/audit-log.models.ts @@ -20,9 +20,7 @@ import { CustomerId } from './id/customer-id'; import { EntityId } from './id/entity-id'; import { UserId } from './id/user-id'; import { TenantId } from './id/tenant-id'; -import { PageLink } from '@shared/models/page/page-link'; -import { isDefinedAndNotNull } from '@app/core/utils'; -import { StringItemsOption } from '../components/string-items-list.component'; +import {isArraysEqualIgnoreUndefined, isDefinedAndNotNull, isEmpty, isUndefinedOrNull} from "@core/utils"; export enum AuditLogMode { TENANT, @@ -136,37 +134,18 @@ export interface AuditLog extends BaseData { actionFailureDetails: string; } - export interface AuditLogFilter { - types?: string[]; -} - -export interface AuditLogRequestParams { - types?: string[]; - id?: string; + actionTypes?: string[]; } - -export class AuditLogQuery { - - pageLink: PageLink; - auditLogFilter: AuditLogRequestParams; - - constructor(pageLink: PageLink, auditLogFilter: AuditLogRequestParams) { - this.pageLink = pageLink; - this.auditLogFilter = auditLogFilter; +export const auditLogFilterEquals = (filter1?: AuditLogFilter, filter2?: AuditLogFilter): boolean => { + if (filter1 === filter2) { + return true; } - - public toQuery(): string { - let query = ''; - if(isDefinedAndNotNull(this.auditLogFilter.id)) { - query += `${this.auditLogFilter.id}`; - } - query += this.pageLink.toQuery(); - if (isDefinedAndNotNull(this.auditLogFilter?.types)) { - const types = this.auditLogFilter.types.join(','); - query += `&actionTypes=${types}`; - } - return query; + if ((isUndefinedOrNull(filter1) || isEmpty(filter1)) && (isUndefinedOrNull(filter2) || isEmpty(filter2))) { + return true; + } else if (isDefinedAndNotNull(filter1) && isDefinedAndNotNull(filter2)) { + return isArraysEqualIgnoreUndefined(filter1.actionTypes, filter2.actionTypes); } -} + return false; +}; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index fe3287f1ab..e2c8d1e070 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1038,7 +1038,8 @@ "filter":"Audit Log Filters", "audit-log-filter-title": "Audit Log Filter", "filter-title": "Filter", - "filter-type-add": "+ Add type" + "filter-type-add": "+ Add type", + "filter-types": "Audit Log Types" }, "debug-settings": { "label": "Debug Configuration",