You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by sa...@apache.org on 2019/04/01 16:43:43 UTC
[metron] branch master updated: METRON-2052 [UI] Changing default
query time range to 15 minutes (tiborm via sardell) closes
apache/metron#1369
This is an automated email from the ASF dual-hosted git repository.
sardell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/metron.git
The following commit(s) were added to refs/heads/master by this push:
new 88d3ca8 METRON-2052 [UI] Changing default query time range to 15 minutes (tiborm via sardell) closes apache/metron#1369
88d3ca8 is described below
commit 88d3ca8a51f7b1ee059df4f1458dbceefd090e15
Author: tiborm <ti...@gmail.com>
AuthorDate: Mon Apr 1 18:35:46 2019 +0200
METRON-2052 [UI] Changing default query time range to 15 minutes (tiborm via sardell) closes apache/metron#1369
---
.../alerts-list/alerts-list.component.spec.ts | 99 ++++++++++++++++++++++
.../alerts/alerts-list/alerts-list.component.ts | 35 ++++++--
.../app/shared/time-range/time-range.component.ts | 39 ++++++---
.../metron-alerts/src/app/utils/utils.ts | 8 +-
4 files changed, 157 insertions(+), 24 deletions(-)
diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.spec.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.spec.ts
new file mode 100644
index 0000000..7adbbe9
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.spec.ts
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+import { AlertsListComponent } from './alerts-list.component';
+import { ComponentFixture, async, TestBed } from '@angular/core/testing';
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { RouterTestingModule } from '@angular/router/testing';
+import { SearchService } from 'app/service/search.service';
+import { UpdateService } from 'app/service/update.service';
+import { ConfigureTableService } from 'app/service/configure-table.service';
+import { AlertsService } from 'app/service/alerts.service';
+import { ClusterMetaDataService } from 'app/service/cluster-metadata.service';
+import { SaveSearchService } from 'app/service/save-search.service';
+import { MetaAlertService } from 'app/service/meta-alert.service';
+import { GlobalConfigService } from 'app/service/global-config.service';
+import { DialogService } from 'app/service/dialog.service';
+import { Observable } from 'rxjs';
+import { Filter } from 'app/model/filter';
+
+fdescribe('AlertsListComponent', () => {
+
+ let component: AlertsListComponent;
+ let fixture: ComponentFixture<AlertsListComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ schemas: [ NO_ERRORS_SCHEMA ],
+ imports: [
+ RouterTestingModule.withRoutes([]),
+ ],
+ declarations: [
+ AlertsListComponent,
+ ],
+ providers: [
+ { provide: SearchService, useClass: () => { return {} } },
+ { provide: UpdateService, useClass: () => { return {
+ alertChanged$: new Observable(),
+ } } },
+ { provide: ConfigureTableService, useClass: () => { return {
+ getTableMetadata: () => new Observable(),
+ tableChanged$: new Observable(),
+ } } },
+ { provide: AlertsService, useClass: () => { return {} } },
+ { provide: ClusterMetaDataService, useClass: () => { return {
+ getDefaultColumns: () => new Observable(),
+ } } },
+ { provide: SaveSearchService, useClass: () => { return {
+ loadSavedSearch$: new Observable(),
+ } } },
+ { provide: MetaAlertService, useClass: () => { return {
+ alertChanged$: new Observable(),
+ } } },
+ { provide: GlobalConfigService, useClass: () => { return {
+ get: () => new Observable(),
+ } } },
+ { provide: DialogService, useClass: () => { return {} } },
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AlertsListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should exist', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should set default query time range', () => {
+ expect(component.selectedTimeRange instanceof Filter).toBeTruthy();
+ expect(component.selectedTimeRange.value).toBe('last-15-minutes');
+ });
+
+ it('default query time range from date should be set', () => {
+ expect(component.selectedTimeRange.dateFilterValue.fromDate).toBeTruthy();
+ });
+
+ it('default query time range to date should be set', () => {
+ expect(component.selectedTimeRange.dateFilterValue.toDate).toBeTruthy();
+ });
+
+});
diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts
index 342f44e..e743359 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts
@@ -46,6 +46,7 @@ import {Facets} from '../../model/facets';
import { GlobalConfigService } from '../../service/global-config.service';
import { DialogService } from 'app/service/dialog.service';
import { DialogType } from 'app/model/dialog-type';
+import { Utils } from 'app/utils/utils';
@Component({
selector: 'app-alerts-list',
@@ -67,7 +68,9 @@ export class AlertsListComponent implements OnInit, OnDestroy {
lastIsRefreshPausedValue = false;
isMetaAlertPresentInSelectedAlerts = false;
timeStampfilterPresent = false;
- selectedTimeRange = new Filter(TIMESTAMP_FIELD_NAME, ALL_TIME, false);
+
+ readonly DEFAULT_TIME_RANGE = 'last-15-minutes';
+ selectedTimeRange: Filter;
@ViewChild('table') table: ElementRef;
@ViewChild('dataViewComponent') dataViewComponent: TableViewComponent;
@@ -135,7 +138,8 @@ export class AlertsListComponent implements OnInit, OnDestroy {
setSelectedTimeRange(filters: Filter[]) {
filters.forEach(filter => {
if (filter.field === TIMESTAMP_FIELD_NAME && filter.dateFilterValue) {
- this.selectedTimeRange = JSON.parse(JSON.stringify(filter));
+ this.selectedTimeRange = filter;
+ this.updateQueryBuilder(filter);
}
});
}
@@ -199,12 +203,20 @@ export class AlertsListComponent implements OnInit, OnDestroy {
}
}
});
+
+ this.setDefaultTimeRange(this.DEFAULT_TIME_RANGE);
this.getAlertColumnNames(true);
this.addAlertColChangedListner();
this.addLoadSavedSearchListner();
this.addAlertChangedListner();
}
+ private setDefaultTimeRange(timeRangeId: string) {
+ const timeRange = new Filter(TIMESTAMP_FIELD_NAME, timeRangeId, false);
+ timeRange.dateFilterValue = Utils.timeRangeToDateObj(timeRange.value);
+ this.setSelectedTimeRange([timeRange]);
+ }
+
onClear() {
this.timeStampfilterPresent = false;
this.queryBuilder.clearSearch();
@@ -229,7 +241,9 @@ export class AlertsListComponent implements OnInit, OnDestroy {
onSelectedAlertsChange(selectedAlerts) {
this.selectedAlerts = selectedAlerts;
- this.isMetaAlertPresentInSelectedAlerts = this.selectedAlerts.some(alert => (alert.source.metron_alert && alert.source.metron_alert.length > 0));
+ this.isMetaAlertPresentInSelectedAlerts = this.selectedAlerts.some(
+ alert => (alert.source.metron_alert && alert.source.metron_alert.length > 0)
+ );
if (selectedAlerts.length > 0) {
this.pause();
@@ -266,17 +280,20 @@ export class AlertsListComponent implements OnInit, OnDestroy {
onResize() {
clearTimeout(this.colNumberTimerId);
- this.colNumberTimerId = setTimeout(() => { this.calcColumnsToDisplay(); }, 500);
+ this.colNumberTimerId = window.setTimeout(() => { this.calcColumnsToDisplay(); }, 500);
}
onTimeRangeChange(filter: Filter) {
- if (filter.value === ALL_TIME) {
- this.queryBuilder.removeFilter(filter.field);
+ this.updateQueryBuilder(filter);
+ this.search();
+ }
+
+ private updateQueryBuilder(timeRangeFilter: Filter) {
+ if (timeRangeFilter.value === ALL_TIME) {
+ this.queryBuilder.removeFilter(timeRangeFilter.field);
} else {
- this.queryBuilder.addOrUpdateFilter(filter);
+ this.queryBuilder.addOrUpdateFilter(timeRangeFilter);
}
-
- this.search();
}
prepareColumnData(configuredColumns: ColumnMetadata[], defaultColumns: ColumnMetadata[]) {
diff --git a/metron-interface/metron-alerts/src/app/shared/time-range/time-range.component.ts b/metron-interface/metron-alerts/src/app/shared/time-range/time-range.component.ts
index 2600189..9c3a61f 100644
--- a/metron-interface/metron-alerts/src/app/shared/time-range/time-range.component.ts
+++ b/metron-interface/metron-alerts/src/app/shared/time-range/time-range.component.ts
@@ -15,15 +15,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { Component, OnInit, ViewChild, ElementRef, HostListener, EventEmitter, Output, Input, OnChanges, SimpleChanges} from '@angular/core';
+import {
+ Component,
+ ViewChild,
+ ElementRef,
+ HostListener,
+ EventEmitter,
+ Output,
+ Input,
+ OnChanges,
+ SimpleChanges
+} from '@angular/core';
import * as moment from 'moment/moment';
-import {Filter} from '../../model/filter';
+import { Filter } from '../../model/filter';
import {
DEFAULT_TIMESTAMP_FORMAT, CUSTOMM_DATE_RANGE_LABEL,
TIMESTAMP_FIELD_NAME, ALL_TIME
} from '../../utils/constants';
-import {DateFilterValue} from '../../model/date-filter-value';
+import { DateFilterValue } from '../../model/date-filter-value';
@Component({
selector: 'app-time-range',
@@ -35,14 +45,14 @@ export class TimeRangeComponent implements OnChanges {
fromDateStr = '';
datePickerFromDate = '';
datePickerToDate = '';
- selectedTimeRangeValue = 'All time';
+ selectedTimeRangeValue = 'Last 15 minutes';
@Input() disabled = false;
@Input() selectedTimeRange: Filter;
@ViewChild('datePicker') datePicker: ElementRef;
@Output() timeRangeChange = new EventEmitter<Filter>();
- timeRangeMappingCol1 = {
+ readonly timeRangeMappingCol1 = {
'Last 7 days': 'last-7-days',
'Last 30 days': 'last-30-days',
'Last 60 days': 'last-60-days',
@@ -52,7 +62,7 @@ export class TimeRangeComponent implements OnChanges {
'Last 2 years': 'last-2-years',
'Last 5 years': 'last-5-years'
};
- timeRangeMappingCol2 = {
+ readonly timeRangeMappingCol2 = {
'Yesterday': 'yesterday',
'Day before yesterday': 'day-before-yesterday',
'This day last week': 'this-day-last-week',
@@ -61,7 +71,7 @@ export class TimeRangeComponent implements OnChanges {
'Previous year': 'previous-year',
'All time': ALL_TIME
};
- timeRangeMappingCol3 = {
+ readonly timeRangeMappingCol3 = {
'Today': 'today',
'Today so far': 'today-so-far',
'This week': 'this-week',
@@ -69,7 +79,7 @@ export class TimeRangeComponent implements OnChanges {
'This month': 'this-month',
'This year': 'this-year'
};
- timeRangeMappingCol4 = {
+ readonly timeRangeMappingCol4 = {
'Last 5 minutes': 'last-5-minutes',
'Last 15 minutes': 'last-15-minutes',
'Last 30 minutes': 'last-30-minutes',
@@ -90,7 +100,14 @@ export class TimeRangeComponent implements OnChanges {
onSelectedTimeRangeChange() {
let foundQuickRange = false;
- let merged = Object.assign({}, this.timeRangeMappingCol1, this.timeRangeMappingCol2, this.timeRangeMappingCol3, this.timeRangeMappingCol4);
+ const merged = Object.assign(
+ {},
+ this.timeRangeMappingCol1,
+ this.timeRangeMappingCol2,
+ this.timeRangeMappingCol3,
+ this.timeRangeMappingCol4
+ );
+
Object.keys(merged).forEach(key => {
if (this.selectedTimeRange.value === merged[key]) {
foundQuickRange = true;
@@ -160,7 +177,7 @@ export class TimeRangeComponent implements OnChanges {
}
isPikaSelectElement(targetElement: HTMLElement): boolean {
- while(targetElement) {
+ while (targetElement) {
if (targetElement.classList.toString().startsWith('pika')){
return true;
}
@@ -176,7 +193,7 @@ export class TimeRangeComponent implements OnChanges {
return;
}
- if(this.isPikaSelectElement(targetElement)) {
+ if (this.isPikaSelectElement(targetElement)) {
return;
}
diff --git a/metron-interface/metron-alerts/src/app/utils/utils.ts b/metron-interface/metron-alerts/src/app/utils/utils.ts
index 4eb098a..872d33d 100644
--- a/metron-interface/metron-alerts/src/app/utils/utils.ts
+++ b/metron-interface/metron-alerts/src/app/utils/utils.ts
@@ -25,7 +25,7 @@ import { PcapFilterFormValue } from '../pcap/pcap-filters/pcap-filters.component
import { FormGroup } from '@angular/forms';
export class Utils {
-
+
public static escapeESField(field: string): string {
return field.replace(/:/g, '\\:');
}
@@ -45,7 +45,7 @@ export class Utils {
}
}
- public static timeRangeToDateObj(range:string) {
+ public static timeRangeToDateObj(range: string): DateFilterValue {
let timeRangeToDisplayStr = Utils.timeRangeToDisplayStr(range);
if (timeRangeToDisplayStr != null) {
let toDate = new Date((timeRangeToDisplayStr.toDate)).getTime();
@@ -60,7 +60,7 @@ export class Utils {
return null;
}
- public static parseTimeRange(range:string) {
+ public static parseTimeRange(range: string): { toDate: number, fromDate: number } {
let parsed = range.replace(/^\(>=/, '')
.replace(/\)$/, '')
.replace(/<=/, '').split('AND');
@@ -74,7 +74,7 @@ export class Utils {
return null;
}
- public static timeRangeToDisplayStr(range:string) {
+ public static timeRangeToDisplayStr(range: string): { toDate: string, fromDate: string } {
let toDate = '';
let fromDate = '';