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/09/06 14:44:18 UTC
[metron] branch master updated: METRON-2211 [UI] Alerts UI should
optionally render timestamp in local time (sardell) closes
apache/metron#1495
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 722eb66 METRON-2211 [UI] Alerts UI should optionally render timestamp in local time (sardell) closes apache/metron#1495
722eb66 is described below
commit 722eb66a6a6a1208185e238f29864d95c673f404
Author: sardell <sh...@gmail.com>
AuthorDate: Fri Sep 6 16:43:54 2019 +0200
METRON-2211 [UI] Alerts UI should optionally render timestamp in local time (sardell) closes apache/metron#1495
---
.../alerts-list/table-view/table-view.component.ts | 13 +++-
.../alerts-list/tree-view/tree-view.component.ts | 6 +-
.../configure-rows/configure-rows.component.html | 3 +
.../configure-rows.component.spec.ts | 2 +
.../alerts/configure-rows/configure-rows.module.ts | 8 ++-
.../timezone-config.component.spec.ts | 76 ++++++++++++++++++++++
.../timezone-config.component.ts} | 32 ++++-----
.../timezone-config.service.spec.ts | 55 ++++++++++++++++
.../timezone-config.service.ts} | 34 ++++++----
9 files changed, 192 insertions(+), 37 deletions(-)
diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts
index 4092193..d0a4dc9 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts
@@ -37,6 +37,8 @@ import { ConfirmationType } from 'app/model/confirmation-type';
import {HttpErrorResponse} from '@angular/common/http';
import { merge } from '../../../shared/context-menu/context-menu.util'
+import * as moment from 'moment/moment';
+import { TimezoneConfigService } from 'app/alerts/configure-rows/timezone-config/timezone-config.service';
export enum MetronAlertDisplayState {
COLLAPSE, EXPAND
@@ -67,6 +69,7 @@ export class TableViewComponent implements OnInit, OnChanges, OnDestroy {
configSubscription: Subscription;
merge: Function = merge;
+ localTime: boolean;
@Input() alerts: Alert[] = [];
@Input() pagination: Pagination;
@@ -85,7 +88,8 @@ export class TableViewComponent implements OnInit, OnChanges, OnDestroy {
public updateService: UpdateService,
public metaAlertService: MetaAlertService,
public globalConfigService: GlobalConfigService,
- public dialogService: DialogService) {
+ public dialogService: DialogService,
+ public timezoneConfigService: TimezoneConfigService, ) {
}
ngOnInit() {
@@ -187,9 +191,12 @@ export class TableViewComponent implements OnInit, OnChanges, OnDestroy {
}
formatValue(column: ColumnMetadata, returnValue: string) {
+ this.localTime = this.timezoneConfigService.getTimezoneConfig();
try {
- if (column.name.endsWith(':ts') || column.name.endsWith('timestamp')) {
- returnValue = new Date(parseInt(returnValue, 10)).toISOString().replace('T', ' ').slice(0, 19);
+ if ((column.name.endsWith(':ts') || column.name.endsWith('timestamp')) && this.localTime === true) {
+ returnValue = moment.utc(returnValue).local().format('YYYY-MM-DD H:mm:ss');
+ } else if ((column.name.endsWith(':ts') || column.name.endsWith('timestamp')) && this.localTime === false) {
+ returnValue = moment.utc(returnValue).format('YYYY-MM-DD H:mm:ss');
}
} catch (e) {}
diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts
index 3bd0055..ef3cc35 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts
@@ -42,6 +42,7 @@ import { AlertSource } from '../../../model/alert-source';
import { QueryBuilder } from '../query-builder';
import { GroupRequest } from 'app/model/group-request';
import { Group } from 'app/model/group';
+import { TimezoneConfigService } from 'app/alerts/configure-rows/timezone-config/timezone-config.service';
@Component({
selector: 'app-tree-view',
@@ -71,8 +72,9 @@ export class TreeViewComponent extends TableViewComponent implements OnInit, OnC
updateService: UpdateService,
metaAlertService: MetaAlertService,
globalConfigService: GlobalConfigService,
- dialogService: DialogService) {
- super(searchService, updateService, metaAlertService, globalConfigService, dialogService);
+ dialogService: DialogService,
+ timezoneConfigService: TimezoneConfigService, ) {
+ super(searchService, updateService, metaAlertService, globalConfigService, dialogService, timezoneConfigService);
}
addAlertChangedListner() {
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.html b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.html
index 38a0967..98c62fd 100644
--- a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.html
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.html
@@ -39,6 +39,9 @@
<label> HIDE ALERT ENTRIES </label>
<app-show-hide-alert-entries (changed)="configRowsChange.emit($event)" ></app-show-hide-alert-entries>
+
+ <label class="pt-2"> TIMEZONE CONFIGURATION </label>
+ <app-timezone-config></app-timezone-config>
</form>
</div>
</div>
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.spec.ts b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.spec.ts
index 533483b..1fe95ac 100644
--- a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.spec.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.spec.ts
@@ -22,6 +22,7 @@ import { ConfigureRowsComponent } from './configure-rows.component';
import { ConfigureTableService } from '../../service/configure-table.service';
import { ShowHideAlertEntriesComponent } from './show-hide/show-hide-alert-entries.component';
import { SwitchComponent } from 'app/shared/switch/switch.component';
+import { TimezoneConfigComponent } from './timezone-config/timezone-config.component';
@Injectable()
class ConfigureTableServiceStub {}
@@ -36,6 +37,7 @@ describe('ConfigureRowsComponent', () => {
ConfigureRowsComponent,
ShowHideAlertEntriesComponent,
SwitchComponent,
+ TimezoneConfigComponent,
],
providers: [
{ provide: ConfigureTableService, useValue: ConfigureTableServiceStub }
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
index 89585c1..9915007 100644
--- a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
@@ -22,15 +22,17 @@ import { ShowHideAlertEntriesComponent } from './show-hide/show-hide-alert-entri
import { SwitchModule } from 'app/shared/switch/switch.module';
import { QueryBuilder } from '../alerts-list/query-builder';
import { ShowHideService } from './show-hide/show-hide.service';
+import { TimezoneConfigComponent } from './timezone-config/timezone-config.component';
+import { TimezoneConfigService } from './timezone-config/timezone-config.service';
@NgModule({
imports: [ SharedModule, SwitchModule ],
- declarations: [ ConfigureRowsComponent, ShowHideAlertEntriesComponent ],
+ declarations: [ ConfigureRowsComponent, ShowHideAlertEntriesComponent, TimezoneConfigComponent ],
exports: [ ConfigureRowsComponent ],
- providers: [ QueryBuilder, ShowHideService ],
+ providers: [ QueryBuilder, ShowHideService, TimezoneConfigService, ],
})
export class ConfigureRowsModule {
- constructor(private showHideService: ShowHideService) {}
+ constructor(private showHideService: ShowHideService, private timezoneConfigService: TimezoneConfigService) {}
}
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.component.spec.ts b/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.component.spec.ts
new file mode 100644
index 0000000..fd693ca
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.component.spec.ts
@@ -0,0 +1,76 @@
+/**
+ * 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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TimezoneConfigComponent } from './timezone-config.component';
+import { SwitchComponent } from 'app/shared/switch/switch.component';
+import { TimezoneConfigService } from './timezone-config.service';
+import { By } from '@angular/platform-browser';
+
+class TimezoneConfigServiceStub {
+ toggleUTCtoLocal(showLocal) {}
+}
+
+describe('TimezoneConfigComponent', () => {
+ let component: TimezoneConfigComponent;
+ let fixture: ComponentFixture<TimezoneConfigComponent>;
+ let service: TimezoneConfigService;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [
+ TimezoneConfigComponent,
+ SwitchComponent,
+ ],
+ providers: [
+ { provide: TimezoneConfigService, useClass: TimezoneConfigServiceStub },
+ ]
+ })
+ .compileComponents();
+ service = TestBed.get(TimezoneConfigService);
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TimezoneConfigComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should toggle between UTC and Local time when clicked', () => {
+ spyOn(service, 'toggleUTCtoLocal');
+ spyOn(component, 'toggleTimezoneConfig').and.callThrough();
+ fixture.detectChanges();
+
+ const timeToggle = fixture.debugElement.query(By.css('[data-qe-id="UTCtoLocalToggle"] input')).nativeElement;
+ timeToggle.click();
+ fixture.detectChanges();
+ expect(timeToggle.checked).toBe(true);
+ expect(component.toggleTimezoneConfig).toHaveBeenCalledWith(true);
+ expect(service.toggleUTCtoLocal).toHaveBeenCalledWith(true);
+
+ timeToggle.click();
+ fixture.detectChanges();
+ expect(timeToggle.checked).toBe(false);
+ expect(component.toggleTimezoneConfig).toHaveBeenCalledWith(false);
+ expect(component.timezoneConfigService.toggleUTCtoLocal).toHaveBeenCalledWith(false);
+ });
+});
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts b/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.component.ts
similarity index 51%
copy from metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
copy to metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.component.ts
index 89585c1..7c1436f 100644
--- a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.component.ts
@@ -15,22 +15,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { NgModule } from '@angular/core';
-import { SharedModule } from '../../shared/shared.module';
-import { ConfigureRowsComponent } from './configure-rows.component';
-import { ShowHideAlertEntriesComponent } from './show-hide/show-hide-alert-entries.component';
-import { SwitchModule } from 'app/shared/switch/switch.module';
-import { QueryBuilder } from '../alerts-list/query-builder';
-import { ShowHideService } from './show-hide/show-hide.service';
+import { Component } from '@angular/core';
+import { TimezoneConfigService } from './timezone-config.service';
-@NgModule({
- imports: [ SharedModule, SwitchModule ],
- declarations: [ ConfigureRowsComponent, ShowHideAlertEntriesComponent ],
- exports: [ ConfigureRowsComponent ],
- providers: [ QueryBuilder, ShowHideService ],
+@Component({
+ selector: 'app-timezone-config',
+ template: `
+ <app-switch
+ data-qe-id="UTCtoLocalToggle"
+ [text]="'Convert timestamps to local time'"
+ (onChange)="toggleTimezoneConfig($event)"
+ [selected]="timezoneConfigService.showLocal"
+ ></app-switch>
+ `,
})
-export class ConfigureRowsModule {
-
- constructor(private showHideService: ShowHideService) {}
+export class TimezoneConfigComponent {
+ constructor(public timezoneConfigService: TimezoneConfigService) {}
+ toggleTimezoneConfig(isLocal) {
+ this.timezoneConfigService.toggleUTCtoLocal(isLocal);
+ }
}
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.service.spec.ts b/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.service.spec.ts
new file mode 100644
index 0000000..758336b
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.service.spec.ts
@@ -0,0 +1,55 @@
+/**
+ * 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 { TestBed } from '@angular/core/testing';
+
+import { TimezoneConfigService } from './timezone-config.service';
+import { SwitchComponent } from 'app/shared/switch/switch.component';
+
+describe('TimezoneConfigService', () => {
+ let service: TimezoneConfigService;
+
+ beforeEach(() => {
+ spyOn(localStorage, 'getItem').and.returnValues('true');
+
+ TestBed.configureTestingModule({
+ declarations: [ SwitchComponent ],
+ providers: [ TimezoneConfigService ]
+ });
+
+ spyOn(TimezoneConfigService.prototype, 'toggleUTCtoLocal').and.callThrough();
+ service = TestBed.get(TimezoneConfigService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should get persisted state from localStorage', () => {
+ expect(localStorage.getItem).toHaveBeenCalledWith(service.CONVERT_UTC_TO_LOCAL_KEY);
+ });
+
+ it('should set initial switch state', () => {
+ expect(service.toggleUTCtoLocal).toHaveBeenCalledWith(true);
+ });
+
+ it('should return the current timezone configuration with getTimezoneConfig()', () => {
+ expect(service.getTimezoneConfig()).toBe(true);
+ service.showLocal = false;
+ expect(service.getTimezoneConfig()).toBe(false);
+ });
+});
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts b/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.service.ts
similarity index 51%
copy from metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
copy to metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.service.ts
index 89585c1..db736f1 100644
--- a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/timezone-config/timezone-config.service.ts
@@ -15,22 +15,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { NgModule } from '@angular/core';
-import { SharedModule } from '../../shared/shared.module';
-import { ConfigureRowsComponent } from './configure-rows.component';
-import { ShowHideAlertEntriesComponent } from './show-hide/show-hide-alert-entries.component';
-import { SwitchModule } from 'app/shared/switch/switch.module';
-import { QueryBuilder } from '../alerts-list/query-builder';
-import { ShowHideService } from './show-hide/show-hide.service';
+import { Injectable } from '@angular/core';
-@NgModule({
- imports: [ SharedModule, SwitchModule ],
- declarations: [ ConfigureRowsComponent, ShowHideAlertEntriesComponent ],
- exports: [ ConfigureRowsComponent ],
- providers: [ QueryBuilder, ShowHideService ],
+@Injectable({
+ providedIn: 'root'
})
-export class ConfigureRowsModule {
+export class TimezoneConfigService {
- constructor(private showHideService: ShowHideService) {}
+ public readonly CONVERT_UTC_TO_LOCAL_KEY = 'convertUTCtoLocal';
+ showLocal = false;
+
+ constructor() {
+ this.showLocal = localStorage.getItem(this.CONVERT_UTC_TO_LOCAL_KEY) === 'true';
+ this.toggleUTCtoLocal(this.showLocal);
+ }
+
+ toggleUTCtoLocal(isLocal: boolean) {
+ this.showLocal = isLocal;
+ localStorage.setItem(this.CONVERT_UTC_TO_LOCAL_KEY, isLocal.toString());
+ }
+
+ getTimezoneConfig() {
+ return this.showLocal;
+ }
}