metron-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nickal...@apache.org
Subject [04/10] metron git commit: METRON-988 UI for viewing alerts generated by Metron (iraghumitra via nickwallen) closes apache/metron#620
Date Thu, 10 Aug 2017 14:08:23 GMT
http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.ts b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.ts
new file mode 100644
index 0000000..9204ebf
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.component.ts
@@ -0,0 +1,112 @@
+/**
+ * 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 { Component, Input, HostListener, ElementRef, Output, EventEmitter } from '@angular/core';
+import {TableMetadata} from '../../model/table-metadata';
+import {ConfigureTableService} from '../../service/configure-table.service';
+
+@Component({
+  selector: 'app-configure-rows',
+  templateUrl: './configure-rows.component.html',
+  styleUrls: ['./configure-rows.component.scss']
+})
+export class ConfigureRowsComponent  {
+
+  showView = false;
+  tableMetadata = new TableMetadata();
+
+  @Input() srcElement: HTMLElement;
+  @Output() sizeChange = new EventEmitter();
+  @Output() intervalChange = new EventEmitter();
+  @Output() configRowsChange = new EventEmitter();
+
+  constructor(private elementRef: ElementRef,
+              private configureTableService: ConfigureTableService) {}
+
+  @Input()
+  get size() {
+    return this.tableMetadata.size;
+  }
+
+  set size(val) {
+    this.tableMetadata.size = val;
+  }
+
+  @Input()
+  get interval() {
+    return this.tableMetadata.refreshInterval;
+  }
+
+  set interval(val) {
+    this.tableMetadata.refreshInterval = val;
+  }
+
+  @Input()
+  get tableMetaData() {
+    return this.tableMetadata;
+  }
+
+  set tableMetaData(val) {
+    this.tableMetadata = val;
+  }
+
+  @HostListener('document:click', ['$event', '$event.target'])
+  public onClick(event: MouseEvent, targetElement: HTMLElement): void {
+    if (!targetElement) {
+      return;
+    }
+
+    if (targetElement === this.srcElement) {
+      this.showView = !this.showView;
+      return;
+    }
+
+    const clickedInside = this.elementRef.nativeElement.contains(targetElement);
+    if (!clickedInside) {
+      this.showView = false;
+    }
+  }
+
+  onPageSizeChange($event, parentElement) {
+    parentElement.querySelector('.is-active').classList.remove('is-active');
+    $event.target.classList.add('is-active');
+
+    this.size = parseInt($event.target.textContent.trim(), 10);
+    this.sizeChange.emit(this.tableMetadata.size);
+    this.configRowsChange.emit();
+    this.saveSettings();
+  }
+  onRefreshIntervalChange($event, parentElement) {
+    parentElement.querySelector('.is-active').classList.remove('is-active');
+    $event.target.classList.add('is-active');
+
+
+    this.interval = parseInt($event.target.getAttribute('value').trim(), 10);
+    this.intervalChange.emit(this.tableMetadata.refreshInterval);
+    this.configRowsChange.emit();
+    this.saveSettings();
+  }
+
+  saveSettings() {
+    if ( this.showView ) {
+      this.configureTableService.saveTableMetaData(this.tableMetadata).subscribe(() => {
+      }, error => {
+        console.log('Unable to save settings ....');
+      });
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..d011651
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-rows/configure-rows.module.ts
@@ -0,0 +1,28 @@
+/**
+ * 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 { NgModule } from '@angular/core';
+import {SharedModule} from '../../shared/shared.module';
+import {ConfigureRowsComponent} from './configure-rows.component';
+import {SwitchModule} from '../../shared/switch/switch.module';
+
+@NgModule ({
+    imports: [ SharedModule, SwitchModule ],
+    declarations: [ ConfigureRowsComponent ],
+    exports: [  ConfigureRowsComponent ]
+})
+export class ConfigureRowsModule { }

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.html
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.html b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.html
new file mode 100644
index 0000000..970c616
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.html
@@ -0,0 +1,72 @@
+<!--
+  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.
+  -->
+<div class="metron-slider-pane-editable load-right-to-left dialog2x">
+  <div class="container-fluid">
+    <div class="row mb-3">
+      <div class="col-md-10">
+        <div class="form-title font-weight-bold">Configure Table</div>
+      </div>
+      <div class="col-md-2"><i class="fa fa-times pull-right close-button" aria-hidden="true" (click)="goBack()"></i></div>
+    </div>
+    <div class="row mx-0">
+      <table class="table">
+        <thead>
+          <tr>
+            <th style="width: 10%"> <input id="select-deselect-all-col" class="fontawesome-checkbox" type="checkbox" (click)="onSelectDeselectAll($event)"><label for="select-deselect-all-col"></label> </th>
+            <th style="width: 30%"> Field </th>
+            <th style="width: 10%"> Short Name </th>
+            <th style="width: 30%"> Type  </th>
+            <th style="width: 10%"> </th>
+            <th style="width: 10%"> </th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td><input #selectColName id="select-deselect-score" class="fontawesome-checkbox" type="checkbox" [checked]="true" disabled><label for="select-deselect-score"></label></td>
+            <td> <span> Score </span></td>
+            <td> </td>
+            <td> <span> STRING </span></td>
+            <td> - </td>
+            <td> - </td>
+          </tr>
+          <tr *ngFor="let columns of allColumns; let i = index" [ngClass]="{'background-tiber': columns.selected}">
+            <td>
+              <input #selectColName id="select-deselect-{{ columns.columnMetadata.name }}" class="fontawesome-checkbox" type="checkbox" [checked]="columns.selected" (click)="selectColumn(columns)">
+              <label for="select-deselect-{{ columns.columnMetadata.name }}"></label>
+            </td>
+            <td #element>
+              <span [attr.title]="columns.key"> {{ columns.columnMetadata.name | centerEllipses }} </span>
+            </td>
+            <td>
+              <input class="input" placeholder="rename" [(ngModel)]="columns.displayName">
+            </td>
+            <td>
+              <span class="text-uppercase"> {{ columns.columnMetadata.type }} </span>
+            </td>
+            <td>
+              <span id="up-{{ columns.columnMetadata.name }}" class="up" (click)="swapUp(i)" [ngClass]="{'disabled': i === 0}"></span>
+            </td>
+            <td>
+              <span id="down-{{ columns.columnMetadata.name }}" class="down" (click)="swapDown(i)" [ngClass]="{'disabled': i + 1 === allColumns.length}"></span>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+  </div>
+  <div class="container-fluid metron-floating-button-bar-2x">
+    <button type="submit" class="btn btn-all_ports" (click)="save()">SAVE</button>
+    <button class="btn btn-mine_shaft_2" (click)="goBack()">CANCEL</button>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.scss
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.scss b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.scss
new file mode 100644
index 0000000..3ca4b2d
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.scss
@@ -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 "../../../slider";
+@import "../../../variables";
+
+.container-fluid {
+  padding-top: 15px;
+}
+
+.form-title {
+  font-size: 18px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.table th, .table td {
+  padding: 0.6rem 0.25rem;
+}
+
+.up:before {
+  font-family: "FontAwesome";
+  font-style: normal;
+  font-size: 14px;
+  content: '\f077';
+  color: $gothic;
+}
+
+.down:before {
+  font-family: "FontAwesome";
+  font-style: normal;
+  font-size: 14px;
+  content: '\f078';
+  color: $gothic;
+}
+
+.disabled:before {
+  opacity: 0.3;
+  cursor: default;
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts
new file mode 100644
index 0000000..941343e
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts
@@ -0,0 +1,174 @@
+/**
+ * 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 { Component, OnInit } from '@angular/core';
+import {Router, ActivatedRoute} from '@angular/router';
+import {Observable} from 'rxjs/Rx';
+
+import {ConfigureTableService} from '../../service/configure-table.service';
+import {ClusterMetaDataService} from '../../service/cluster-metadata.service';
+import {ColumnMetadata} from '../../model/column-metadata';
+import {ColumnNamesService} from '../../service/column-names.service';
+import {ColumnNames} from '../../model/column-names';
+
+export enum AlertState {
+  NEW, OPEN, ESCALATE, DISMISS, RESOLVE
+}
+
+export class ColumnMetadataWrapper {
+  columnMetadata: ColumnMetadata;
+  displayName: string;
+  selected: boolean;
+
+  constructor(columnMetadata: ColumnMetadata, selected: boolean, displayName: string) {
+    this.columnMetadata = columnMetadata;
+    this.selected = selected;
+    this.displayName = displayName;
+  }
+}
+
+@Component({
+  selector: 'app-configure-table',
+  templateUrl: './configure-table.component.html',
+  styleUrls: ['./configure-table.component.scss']
+})
+
+export class ConfigureTableComponent implements OnInit {
+
+  allColumns: ColumnMetadataWrapper[] = [];
+
+  constructor(private router: Router, private activatedRoute: ActivatedRoute, private configureTableService: ConfigureTableService,
+              private clusterMetaDataService: ClusterMetaDataService, private columnNamesService: ColumnNamesService) { }
+
+  goBack() {
+    this.router.navigateByUrl('/alerts-list');
+    return false;
+  }
+
+  indexOf(columnMetadata: ColumnMetadata, configuredColumns: ColumnMetadata[]): number {
+    for (let i = 0; i < configuredColumns.length; i++) {
+      if (configuredColumns[i].name === columnMetadata.name) {
+        return i;
+      }
+    }
+  }
+
+  indexToInsert(columnMetadata: ColumnMetadata, allColumns: ColumnMetadata[], configuredColumnNames: string[]): number {
+    let i = 0;
+    for ( ; i < allColumns.length; i++) {
+      if (configuredColumnNames.indexOf(allColumns[i].name) === -1 && columnMetadata.name.localeCompare(allColumns[i].name) === -1 ) {
+        break;
+      }
+    }
+    return i;
+  }
+
+  ngOnInit() {
+    Observable.forkJoin(
+      this.clusterMetaDataService.getDefaultColumns(),
+      this.clusterMetaDataService.getColumnMetaData(),
+      this.configureTableService.getTableMetadata()
+    ).subscribe((response: any) => {
+      this.prepareData(response[0], response[1], response[2].tableColumns);
+    });
+  }
+
+  onSelectDeselectAll($event) {
+    let checked = $event.target.checked;
+    this.allColumns.forEach(colMetaData => colMetaData.selected = checked);
+  }
+
+  /* Slight variation of insertion sort with bucketing the items in the display order*/
+  prepareData(defaultColumns: ColumnMetadata[], allColumns: ColumnMetadata[], savedColumns: ColumnMetadata[]) {
+    let configuredColumns: ColumnMetadata[] = (savedColumns && savedColumns.length > 0) ?  savedColumns : defaultColumns;
+    let configuredColumnNames: string[] = configuredColumns.map((mData: ColumnMetadata) => mData.name);
+
+    allColumns = allColumns.filter((mData: ColumnMetadata) => configuredColumnNames.indexOf(mData.name) === -1);
+    allColumns = allColumns.sort((mData1: ColumnMetadata, mData2: ColumnMetadata) => { return mData1.name.localeCompare(mData2.name); });
+
+    let sortedConfiguredColumns = JSON.parse(JSON.stringify(configuredColumns));
+    sortedConfiguredColumns = sortedConfiguredColumns.sort((mData1: ColumnMetadata, mData2: ColumnMetadata) => {
+                                                                return mData1.name.localeCompare(mData2.name);
+                                                          });
+
+    while (configuredColumns.length > 0 ) {
+      let columnMetadata = sortedConfiguredColumns.shift();
+
+      let index = this.indexOf(columnMetadata, configuredColumns);
+      let itemsToInsert: any[] = configuredColumns.splice(0, index + 1);
+
+
+      let indexInAll = this.indexToInsert(columnMetadata, allColumns, configuredColumnNames);
+      allColumns.splice.apply(allColumns, [indexInAll, 0].concat(itemsToInsert));
+    }
+
+    this.allColumns = allColumns.map(mData => {
+      return new ColumnMetadataWrapper(mData, configuredColumnNames.indexOf(mData.name) > -1,
+                                        ColumnNamesService.columnNameToDisplayValueMap[mData.name]);
+      });
+  }
+
+  postSave() {
+    this.configureTableService.fireTableChanged();
+    this.goBack();
+  }
+
+  save() {
+    let selectedColumns = this.allColumns.filter((mDataWrapper: ColumnMetadataWrapper) => mDataWrapper.selected)
+                          .map((mDataWrapper: ColumnMetadataWrapper) => mDataWrapper.columnMetadata);
+
+    this.configureTableService.saveColumnMetaData(selectedColumns).subscribe(() => {
+      this.saveColumnNames();
+    }, error => {
+      console.log('Unable to save column preferences ...');
+      this.saveColumnNames();
+    });
+
+
+  }
+
+  saveColumnNames() {
+    let columnNames = this.allColumns.map(mDataWrapper => {
+      return new ColumnNames(mDataWrapper.columnMetadata.name, mDataWrapper.displayName);
+    });
+
+    this.columnNamesService.save(columnNames).subscribe(() => {
+      this.postSave();
+    }, error => {
+      console.log('Unable to column names ...');
+      this.postSave();
+    });
+  }
+
+  selectColumn(columns: ColumnMetadataWrapper) {
+    columns.selected = !columns.selected;
+  }
+
+  swapUp(index: number) {
+    if (index > 0) {
+      [this.allColumns[index], this.allColumns[index - 1]] = [this.allColumns[index - 1], this.allColumns[index]];
+    }
+  }
+
+  swapDown(index: number) {
+    if (index + 1 < this.allColumns.length) {
+      [this.allColumns[index], this.allColumns[index + 1]] = [this.allColumns[index + 1], this.allColumns[index]];
+    }
+  }
+}
+
+

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.module.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.module.ts b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.module.ts
new file mode 100644
index 0000000..e67a63e
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.module.ts
@@ -0,0 +1,30 @@
+/**
+ * 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 { NgModule } from '@angular/core';
+import {routing} from './configure-table.routing';
+import {SharedModule} from '../../shared/shared.module';
+import {ConfigureTableComponent} from './configure-table.component';
+import {ClusterMetaDataService} from '../../service/cluster-metadata.service';
+import {ColumnNamesService} from '../../service/column-names.service';
+
+@NgModule ({
+    imports: [ routing,  SharedModule],
+    declarations: [ ConfigureTableComponent ],
+    providers: [ ClusterMetaDataService, ColumnNamesService ]
+})
+export class ConfigureTableModule { }

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.routing.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.routing.ts b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.routing.ts
new file mode 100644
index 0000000..71e08a2
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.routing.ts
@@ -0,0 +1,24 @@
+/**
+ * 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 { ModuleWithProviders }  from '@angular/core';
+import { RouterModule } from '@angular/router';
+import {ConfigureTableComponent} from './configure-table.component';
+
+export const routing: ModuleWithProviders = RouterModule.forChild([
+    { path: 'configure-table', component: ConfigureTableComponent, outlet: 'dialog'}
+]);

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.html
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.html b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.html
new file mode 100644
index 0000000..c425314
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.html
@@ -0,0 +1,34 @@
+<!--
+  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.
+  -->
+<div class="metron-slider-pane-details load-right-to-left dialog1x">
+  <div class="container-fluid my-3">
+    <div class="row mb-3">
+      <div class="col-md-10">
+        <div class="form-title"> Save Search</div>
+      </div>
+      <div class="col-md-2"><i class="fa fa-times pull-right close-button" aria-hidden="true" (click)="goBack()"></i></div>
+    </div>
+    <form>
+      <div class="form-group">
+        <label for="name">NAME*</label>
+        <input type="text" class="form-control" id="name" [(ngModel)]="saveSearch.name" [ngModelOptions]="{standalone: true}">
+      </div>
+
+      <div class="my-4">
+        <button type="submit" class="btn btn-all_ports" (click)="trySave()" [disabled]="saveSearch.name.length===0" title="Please specify a name to save the query">SAVE</button>
+        <button class="btn btn-mine_shaft_2" (click)="goBack()">CANCEL</button>
+      </div>
+    </form>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.scss
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.scss b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.scss
new file mode 100644
index 0000000..9c9126d
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.scss
@@ -0,0 +1,22 @@
+/**
+ * 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 "../../../variables";
+
+.form-title, .close-button {
+  color: $silver;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.spec.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.spec.ts b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.spec.ts
new file mode 100644
index 0000000..3ff673d
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.spec.ts
@@ -0,0 +1,38 @@
+/**
+ * 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 { SaveSearchComponent } from './save-search.component';
+
+describe('SaveSearchComponent', () => {
+  let component: SaveSearchComponent;
+  let fixture: ComponentFixture<SaveSearchComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ SaveSearchComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SaveSearchComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+});

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.ts b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.ts
new file mode 100644
index 0000000..d3bd9da
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.component.ts
@@ -0,0 +1,77 @@
+/**
+ * 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 { Component, OnInit } from '@angular/core';
+import {Router} from '@angular/router';
+
+import {SaveSearchService} from '../../service/save-search.service';
+import {SaveSearch} from '../../model/save-search';
+import {MetronDialogBox} from '../../shared/metron-dialog-box';
+
+@Component({
+  selector: 'app-save-search',
+  templateUrl: './save-search.component.html',
+  styleUrls: ['./save-search.component.scss']
+})
+export class SaveSearchComponent implements OnInit {
+
+  saveSearch = new SaveSearch();
+
+  constructor(private router: Router,
+              private saveSearchService: SaveSearchService,
+              private metronDialogBox: MetronDialogBox) {
+  }
+
+  goBack() {
+    this.router.navigateByUrl('/alerts-list');
+    return false;
+  }
+
+  ngOnInit() {
+  }
+
+  save() {
+    this.saveSearch.searchRequest = this.saveSearchService.queryBuilder.searchRequest;
+    this.saveSearch.tableColumns = this.saveSearchService.tableColumns;
+
+    this.saveSearchService.saveSearch(this.saveSearch).subscribe(() => {
+      this.goBack();
+    }, error => {
+    });
+  }
+
+  trySave() {
+    this.saveSearchService.listSavedSearches().subscribe((savedSearches: SaveSearch[]) => {
+      if (savedSearches && savedSearches.length > 0 && savedSearches.find(savedSearch => savedSearch.name === this.saveSearch.name)) {
+        this.update();
+      } else {
+        this.save();
+      }
+    });
+  }
+
+  update() {
+    let message = 'A Search with the name \'' + this.saveSearch.name + '\' already exist do you wish to override it?';
+    this.metronDialogBox.showConfirmationMessage(message).subscribe(result => {
+      if (result) {
+        this.saveSearch.searchRequest = this.saveSearchService.queryBuilder.searchRequest;
+        this.saveSearchService.updateSearch(this.saveSearch).subscribe(() => { this.goBack(); }, error => {});
+      }
+    });
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.module.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.module.ts b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.module.ts
new file mode 100644
index 0000000..8ca9e3f
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.module.ts
@@ -0,0 +1,29 @@
+/**
+ * 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 { NgModule } from '@angular/core';
+
+import {routing} from './save-search.routing';
+import {SharedModule} from '../../shared/shared.module';
+import {SaveSearchComponent} from './save-search.component';
+
+@NgModule ({
+  imports: [ routing,  SharedModule],
+  declarations: [ SaveSearchComponent ],
+  providers: [ ]
+})
+export class SaveSearchModule { }

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.routing.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.routing.ts b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.routing.ts
new file mode 100644
index 0000000..f1f5b5a
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/save-search/save-search.routing.ts
@@ -0,0 +1,24 @@
+/**
+ * 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 { ModuleWithProviders }  from '@angular/core';
+import { RouterModule } from '@angular/router';
+import {SaveSearchComponent} from './save-search.component';
+
+export const routing: ModuleWithProviders = RouterModule.forChild([
+  { path: 'save-search', component: SaveSearchComponent, outlet: 'dialog'}
+]);

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.html
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.html b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.html
new file mode 100644
index 0000000..925da9a
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.html
@@ -0,0 +1,30 @@
+<!--
+  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.
+  -->
+<div class="metron-slider-pane-details load-left-to-right dialog1x">
+  <div class="container-fluid my-3">
+    <div class="row mb-3">
+      <div class="col-md-10">
+        <div class="form-title"> Searches </div>
+      </div>
+      <div class="col-md-2"><i class="fa fa-times pull-right close-button" aria-hidden="true" (click)="goBack()"></i></div>
+    </div>
+
+    <div>
+      <metron-collapse [data]="recentSearches" [fontSize]="15" [titleSeperator]="true"  [show]="true"
+                       (onSelect)="onSaveRecentSearchSelect($event)" (onDelete)="deleteRecentSearch($event)"> </metron-collapse>
+      <metron-collapse [data]="savedSearches" [fontSize]="15" [titleSeperator]="true" [deleteOption]="true" [show]="true"
+                       (onSelect)="onSaveSearchSelect($event)" (onDelete)="deleteSearch($event)"> </metron-collapse>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.scss
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.scss b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.scss
new file mode 100644
index 0000000..9c9126d
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.scss
@@ -0,0 +1,22 @@
+/**
+ * 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 "../../../variables";
+
+.form-title, .close-button {
+  color: $silver;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.spec.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.spec.ts b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.spec.ts
new file mode 100644
index 0000000..7794f4c
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.spec.ts
@@ -0,0 +1,38 @@
+/**
+ * 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 { SavedSearchesComponent } from './saved-searches.component';
+
+describe('SavedSearchesComponent', () => {
+  let component: SavedSearchesComponent;
+  let fixture: ComponentFixture<SavedSearchesComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ SavedSearchesComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SavedSearchesComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+});

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.ts b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.ts
new file mode 100644
index 0000000..cb21b11
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.component.ts
@@ -0,0 +1,130 @@
+/**
+ * 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 { Component, OnInit } from '@angular/core';
+import {Router} from '@angular/router';
+import {Observable} from 'rxjs/Rx';
+
+import {SaveSearchService} from '../../service/save-search.service';
+import {SaveSearch} from '../../model/save-search';
+import {MetronDialogBox} from '../../shared/metron-dialog-box';
+import {NUM_SAVED_SEARCH} from '../../utils/constants';
+import {CollapseComponentData, CollapseComponentDataItems} from '../../shared/collapse/collapse-component-data';
+
+@Component({
+  selector: 'app-saved-searches',
+  templateUrl: './saved-searches.component.html',
+  styleUrls: ['./saved-searches.component.scss']
+})
+export class SavedSearchesComponent implements OnInit {
+
+  searches: SaveSearch[];
+  recentSearcheObj: SaveSearch[];
+  savedSearches: CollapseComponentData = new CollapseComponentData();
+  recentSearches: CollapseComponentData = new CollapseComponentData();
+  constructor(private router: Router,
+              private saveSearchService: SaveSearchService,
+              private metronDialog: MetronDialogBox) {
+  }
+
+  doDeleteRecentSearch(selectedSearch: SaveSearch) {
+    this.saveSearchService.deleteRecentSearch(selectedSearch).subscribe(() => {
+        this.ngOnInit();
+      },
+      error => {
+        this.ngOnInit();
+      });
+  }
+  doDeleteSearch(selectedSearch: SaveSearch) {
+    this.saveSearchService.deleteSavedSearch(selectedSearch).subscribe(() => {
+      this.doDeleteRecentSearch(selectedSearch);
+      this.ngOnInit();
+    },
+    error => {
+      this.ngOnInit();
+    });
+  }
+
+  deleteRecentSearch($event) {
+    let selectedSearch = this.recentSearcheObj.find(savedSearch => savedSearch.name === $event.key);
+    this.metronDialog.showConfirmationMessage('Do you wish to delete recent search ' + selectedSearch.name).subscribe((result: boolean) => {
+      if (result) {
+        this.doDeleteRecentSearch(selectedSearch);
+      }
+    });
+  }
+
+  deleteSearch($event) {
+    let selectedSearch = this.searches.find(savedSearch => savedSearch.name === $event.key);
+    this.metronDialog.showConfirmationMessage('Do you wish to delete saved search ' + selectedSearch.name).subscribe((result: boolean) => {
+      if (result) {
+        this.doDeleteSearch(selectedSearch);
+      }
+    });
+  }
+
+  ngOnInit() {
+    Observable.forkJoin(
+      this.saveSearchService.listSavedSearches(),
+      this.saveSearchService.listRecentSearches()
+    ).subscribe((response: any) => {
+      this.prepareData(response[0]);
+      this.preparedRecentlyAccessedSearches(response[1]);
+    });
+  }
+
+  prepareData(savedSearches: SaveSearch[]) {
+    savedSearches = savedSearches || [];
+    this.preparedSavedSearches(savedSearches);
+    this.searches = savedSearches;
+  }
+
+  preparedRecentlyAccessedSearches(recentSearches: SaveSearch[]) {
+    this.recentSearcheObj = recentSearches ? recentSearches : [];
+    let recentSearchNames = this.recentSearcheObj.sort((s1, s2) => { return s2.lastAccessed - s1.lastAccessed; }).slice(0, NUM_SAVED_SEARCH)
+                          .map(search => {
+                            return  new CollapseComponentDataItems(search.getDisplayString());
+                          });
+
+    this.recentSearches.groupName =  'Recent Searches';
+    this.recentSearches.groupItems = recentSearchNames;
+  }
+
+  preparedSavedSearches(savedSearches: SaveSearch[]) {
+    let savedSearchNames = savedSearches.map(savedSearch => { return new CollapseComponentDataItems(savedSearch.name); });
+
+    this.savedSearches.groupName =  'Saved Searches';
+    this.savedSearches.groupItems = savedSearchNames;
+  }
+
+  goBack() {
+    this.router.navigateByUrl('/alerts-list');
+    return false;
+  }
+
+  onSaveRecentSearchSelect($event) {
+    let selectedSearch = this.recentSearcheObj.find(savedSearch =>  savedSearch.name === $event.key);
+    this.saveSearchService.fireLoadSavedSearch(SaveSearch.fromJSON(selectedSearch));
+    this.goBack();
+  }
+
+  onSaveSearchSelect($event) {
+    let selectedSearch = this.searches.find(savedSearch => savedSearch.name === $event.key);
+    this.saveSearchService.fireLoadSavedSearch(SaveSearch.fromJSON(selectedSearch));
+    this.goBack();
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.module.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.module.ts b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.module.ts
new file mode 100644
index 0000000..4a7b35c
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.module.ts
@@ -0,0 +1,30 @@
+/**
+ * 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 { NgModule } from '@angular/core';
+
+import {routing} from './saved-searches.routing';
+import {SharedModule} from '../../shared/shared.module';
+import {SavedSearchesComponent} from './saved-searches.component';
+import {CollapseModule} from '../../shared/collapse/collapse.module';
+
+@NgModule ({
+  imports: [ routing,  SharedModule, CollapseModule],
+  declarations: [ SavedSearchesComponent ],
+  providers: [ ]
+})
+export class SavedSearchesModule { }

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.routing.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.routing.ts b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.routing.ts
new file mode 100644
index 0000000..24095fb
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/alerts/saved-searches/saved-searches.routing.ts
@@ -0,0 +1,24 @@
+/**
+ * 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 { ModuleWithProviders }  from '@angular/core';
+import { RouterModule } from '@angular/router';
+import {SavedSearchesComponent} from './saved-searches.component';
+
+export const routing: ModuleWithProviders = RouterModule.forChild([
+  { path: 'saved-searches', component: SavedSearchesComponent, outlet: 'dialog'}
+]);

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/app-routing.module.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app-routing.module.ts b/metron-interface/metron-alerts/src/app/app-routing.module.ts
new file mode 100644
index 0000000..d214650
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/app-routing.module.ts
@@ -0,0 +1,33 @@
+/**
+ * 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 { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+const routes: Routes = [
+  { path: '',  redirectTo: 'alerts-list', pathMatch: 'full'},
+  { path: 'alerts-list', loadChildren: 'app/alerts/alerts-list/alerts-list.module#AlertsListModule'},
+  { path: 'save-search', loadChildren: 'app/alerts/save-search/save-search.module#SaveSearchModule'},
+  { path: 'saved-searches', loadChildren: 'app/alerts/saved-searches/saved-searches.module.ts#SavedSearchesModule'}
+];
+
+@NgModule({
+  imports: [RouterModule.forRoot(routes)],
+  exports: [RouterModule],
+  providers: []
+})
+export class MetronAlertsRoutingModule { }

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/app.component.html
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app.component.html b/metron-interface/metron-alerts/src/app/app.component.html
new file mode 100644
index 0000000..103642a
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/app.component.html
@@ -0,0 +1,28 @@
+<!--
+  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.
+  -->
+<div class="container-fluid px-0">
+    <nav class="navbar">
+        <a class="navbar-brand" href="#">
+            <img alt="" src="../assets/images/logo.png" width="135" height="45">
+        </a>
+    </nav>
+    <div class="container-fluid">
+        <router-outlet></router-outlet>
+    </div>
+    <router-outlet name="dialog" ></router-outlet>
+</div>
+
+
+
+

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/app.component.scss
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app.component.scss b/metron-interface/metron-alerts/src/app/app.component.scss
new file mode 100644
index 0000000..ce52c56
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/app.component.scss
@@ -0,0 +1,25 @@
+/**
+ * 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 "../variables";
+
+.navbar
+{
+  background: $nav-bar-bg;
+  padding: 0rem 1rem;
+  max-height: 50px;
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/app.component.spec.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app.component.spec.ts b/metron-interface/metron-alerts/src/app/app.component.spec.ts
new file mode 100644
index 0000000..cfccb7d
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/app.component.spec.ts
@@ -0,0 +1,31 @@
+/**
+ * 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, async } from '@angular/core/testing';
+
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [
+        AppComponent
+      ],
+    }).compileComponents();
+  }));
+
+});

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/app.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app.component.ts b/metron-interface/metron-alerts/src/app/app.component.ts
new file mode 100644
index 0000000..73cce38
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/app.component.ts
@@ -0,0 +1,26 @@
+/**
+ * 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 { Component } from '@angular/core';
+
+@Component({
+  selector: 'metron-alerts-root',
+  templateUrl: './app.component.html',
+  styleUrls: ['./app.component.scss']
+})
+export class AppComponent {
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/app.config.interface.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app.config.interface.ts b/metron-interface/metron-alerts/src/app/app.config.interface.ts
new file mode 100644
index 0000000..898af94
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/app.config.interface.ts
@@ -0,0 +1,20 @@
+/**
+ * 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.
+ */
+export interface IAppConfig {
+  apiEndpoint: string;
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/app.config.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app.config.ts b/metron-interface/metron-alerts/src/app/app.config.ts
new file mode 100644
index 0000000..5d5f1e3
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/app.config.ts
@@ -0,0 +1,17 @@
+/**
+ * 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.
+ */

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app.module.ts b/metron-interface/metron-alerts/src/app/app.module.ts
new file mode 100644
index 0000000..26ea5f2
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/app.module.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 { Router } from '@angular/router';
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { HttpModule } from '@angular/http';
+import { APP_INITIALIZER } from '@angular/core';
+
+import { AppComponent } from './app.component';
+import {MetronAlertsRoutingModule} from './app-routing.module';
+import {AlertsListModule} from './alerts/alerts-list/alerts-list.module';
+import {AlertDetailsModule} from './alerts/alert-details/alerts-details.module';
+import {ConfigureTableModule} from './alerts/configure-table/configure-table.module';
+import {ConfigureTableService} from './service/configure-table.service';
+import {SaveSearchModule} from './alerts/save-search/save-search.module';
+import {SaveSearchService} from './service/save-search.service';
+import {SavedSearchesModule} from './alerts/saved-searches/saved-searches.module';
+import {MetronDialogBox} from './shared/metron-dialog-box';
+import {ConfigureRowsModule} from './alerts/configure-rows/configure-rows.module';
+import {SwitchModule} from './shared/switch/switch.module';
+import {ColumnNamesService} from './service/column-names.service';
+import {ElasticSearchLocalstorageImpl} from './service/elasticsearch-localstorage-impl';
+import {DataSource} from './service/data-source';
+import {environment} from '../environments/environment.prod';
+
+
+export function initConfig(config: ColumnNamesService) {
+  return () => config.list();
+}
+
+@NgModule({
+  declarations: [
+    AppComponent
+  ],
+  imports: [
+    BrowserModule,
+    FormsModule,
+    HttpModule,
+    MetronAlertsRoutingModule,
+    AlertsListModule,
+    AlertDetailsModule,
+    ConfigureTableModule,
+    ConfigureRowsModule,
+    SaveSearchModule,
+    SavedSearchesModule,
+    SwitchModule
+  ],
+  providers: [{ provide: APP_INITIALIZER, useFactory: initConfig, deps: [ColumnNamesService], multi: true },
+              { provide: DataSource, useClass: environment.dataSource === 'elastic' ? ElasticSearchLocalstorageImpl : null},
+              ConfigureTableService,
+              SaveSearchService,
+              MetronDialogBox,
+              ColumnNamesService],
+  bootstrap: [AppComponent]
+})
+
+export class AppModule {
+  constructor(router: Router) {
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/index.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/index.ts b/metron-interface/metron-alerts/src/app/index.ts
new file mode 100644
index 0000000..481941a
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/index.ts
@@ -0,0 +1,20 @@
+/**
+ * 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.
+ */
+export * from './app.component';
+export * from './app.module';
+export * from './app.config.interface';

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/alert.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/alert.ts b/metron-interface/metron-alerts/src/app/model/alert.ts
new file mode 100644
index 0000000..de8113d
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/alert.ts
@@ -0,0 +1,61 @@
+/**
+ * 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.
+ */
+export class Alert {
+  _index: string;
+  _type: string;
+  _id: string;
+  _score: number;
+  _timestamp: number;
+  _source: {
+    msg: string;
+    sig_rev: number;
+    ip_dst_port: number;
+    ethsrc: string;
+    tcpseq: number;
+    dgmlen: number;
+    tcpwindow: number;
+    tcpack: number;
+    protocol: string;
+    'source:type': string;
+    ip_dst_addr: number;
+    original_string: string;
+    tos: number;
+    id: number;
+    ip_src_addr: string;
+    timestamp: number;
+    ethdst: string;
+    is_alert: boolean;
+    ttl: number;
+    ethlen: number;
+    iplen: number;
+    ip_src_port: number;
+    tcpflags: string;
+    guid: string;
+    sig_id: number;
+    sig_generator: number;
+    'threat:triage:score': number;
+    'threatinteljoinbolt:joiner:ts': number;
+    'enrichmentsplitterbolt:splitter:begin:ts': number;
+    'enrichmentjoinbolt:joiner:ts': number;
+    'threatintelsplitterbolt:splitter:end:ts': number;
+    'enrichmentsplitterbolt:splitter:end:ts': number;
+    'threatintelsplitterbolt:splitter:begin:ts': number;
+  };
+
+  status: string;
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/alerts-search-response.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/alerts-search-response.ts b/metron-interface/metron-alerts/src/app/model/alerts-search-response.ts
new file mode 100644
index 0000000..265f66b
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/alerts-search-response.ts
@@ -0,0 +1,23 @@
+/**
+ * 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 {Alert} from './alert';
+
+export class AlertsSearchResponse {
+  total = 0;
+  results: Alert[] = [];
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/column-metadata.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/column-metadata.ts b/metron-interface/metron-alerts/src/app/model/column-metadata.ts
new file mode 100644
index 0000000..f2e06c7
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/column-metadata.ts
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+export class ColumnMetadata {
+  name: string;
+  type: string;
+
+  static fromJSON(objs: ColumnMetadata[]): ColumnMetadata[] {
+    let columns = [];
+    for (let obj of objs) {
+      columns.push(new ColumnMetadata(obj.name, obj.type));
+    }
+    return columns;
+  }
+
+  constructor(name: string, type: string) {
+    this.name = name;
+    this.type = type;
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/column-names.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/column-names.ts b/metron-interface/metron-alerts/src/app/model/column-names.ts
new file mode 100644
index 0000000..5898d1c
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/column-names.ts
@@ -0,0 +1,26 @@
+/**
+ * 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.
+ */
+export class ColumnNames {
+  key: string;
+  displayValue: string;
+
+  constructor(key: string, displayValue: string) {
+    this.key = key;
+    this.displayValue = displayValue;
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/filter.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/filter.ts b/metron-interface/metron-alerts/src/app/model/filter.ts
new file mode 100644
index 0000000..24c54d8
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/filter.ts
@@ -0,0 +1,26 @@
+/**
+ * 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.
+ */
+export class Filter {
+  field: string;
+  value: string;
+
+  constructor(field: string, value: string) {
+    this.field = field;
+    this.value = value;
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/pagination.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/pagination.ts b/metron-interface/metron-alerts/src/app/model/pagination.ts
new file mode 100644
index 0000000..1ba5fd0
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/pagination.ts
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+export class Pagination {
+  from = 0;
+  total: number;
+  size = 25;
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/rest-error.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/rest-error.ts b/metron-interface/metron-alerts/src/app/model/rest-error.ts
new file mode 100644
index 0000000..5daee25
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/rest-error.ts
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+export class RestError {
+  responseCode: number;
+  message: string;
+  fullMessage: string;
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/save-search.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/save-search.ts b/metron-interface/metron-alerts/src/app/model/save-search.ts
new file mode 100644
index 0000000..b2ee765
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/save-search.ts
@@ -0,0 +1,48 @@
+/**
+ * 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 {QueryBuilder} from '../alerts/alerts-list/query-builder';
+import {ColumnMetadata} from './column-metadata';
+import {SearchRequest} from './search-request';
+
+export class SaveSearch {
+  name  = '';
+  lastAccessed = 0;
+  searchRequest: SearchRequest;
+  tableColumns: ColumnMetadata[];
+
+  public static fromJSON(obj: SaveSearch): SaveSearch {
+    let saveSearch = new SaveSearch();
+    saveSearch.name = obj.name;
+    saveSearch.lastAccessed = obj.lastAccessed;
+    saveSearch.searchRequest = obj.searchRequest;
+    saveSearch.tableColumns = ColumnMetadata.fromJSON(obj.tableColumns);
+
+    return saveSearch;
+  }
+
+  getDisplayString() {
+    if (this.name && this.name.length > 0) {
+      return this.name;
+    }
+
+    let queryBuilder = new QueryBuilder();
+    queryBuilder.searchRequest = this.searchRequest;
+    return queryBuilder.generateSelectForDisplay();
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/search-request.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/search-request.ts b/metron-interface/metron-alerts/src/app/model/search-request.ts
new file mode 100644
index 0000000..3c7443e
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/search-request.ts
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ */
+export class SearchRequest {
+  _source: string[];
+  query = '*';
+  from = 0;
+  size = 15;
+  sort: {}[] = [{ timestamp: {order : 'desc', ignore_unmapped: true, unmapped_type: 'date'} }];
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/model/table-metadata.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/table-metadata.ts b/metron-interface/metron-alerts/src/app/model/table-metadata.ts
new file mode 100644
index 0000000..e624b6e
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/table-metadata.ts
@@ -0,0 +1,40 @@
+/**
+ * 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 {PageSize, RefreshInterval} from '../alerts/configure-rows/configure-rows-enums';
+import {ColumnMetadata} from './column-metadata';
+
+export class TableMetadata {
+  size = PageSize.TWENTY_FIVE;
+  refreshInterval = RefreshInterval.ONE_MIN;
+  hideResolvedAlerts = true;
+  hideDismissedAlerts = true;
+  tableColumns: ColumnMetadata[];
+
+  static fromJSON(obj: any): TableMetadata {
+    let tableMetadata = new TableMetadata();
+    if (obj) {
+      tableMetadata.size = obj.size;
+      tableMetadata.refreshInterval = obj.refreshInterval;
+      tableMetadata.hideResolvedAlerts = obj.hideResolvedAlerts;
+      tableMetadata.hideDismissedAlerts = obj.hideDismissedAlerts;
+      tableMetadata.tableColumns = (typeof (obj.tableColumns) === 'string') ? JSON.parse(obj.tableColumns) : obj.tableColumns;
+    }
+
+    return tableMetadata;
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/service/alert.service.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/service/alert.service.ts b/metron-interface/metron-alerts/src/app/service/alert.service.ts
new file mode 100644
index 0000000..6412dde
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/service/alert.service.ts
@@ -0,0 +1,69 @@
+/**
+ * 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 {Injectable, NgZone} from '@angular/core';
+import {Observable} from 'rxjs/Rx';
+import 'rxjs/add/observable/interval';
+import 'rxjs/add/operator/switchMap';
+import 'rxjs/add/operator/onErrorResumeNext';
+
+import {Alert} from '../model/alert';
+import {Http} from '@angular/http';
+import {DataSource} from './data-source';
+import {AlertsSearchResponse} from '../model/alerts-search-response';
+import {SearchRequest} from '../model/search-request';
+
+@Injectable()
+export class AlertService {
+
+  interval = 80000;
+  defaultHeaders = {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'};
+
+  constructor(private http: Http,
+              private dataSource: DataSource,
+              private ngZone: NgZone) { }
+
+  public search(searchRequest: SearchRequest): Observable<AlertsSearchResponse> {
+    return this.dataSource.getAlerts(searchRequest);
+  }
+
+  public pollSearch(searchRequest: SearchRequest): Observable<AlertsSearchResponse> {
+    return this.ngZone.runOutsideAngular(() => {
+      return Observable.interval(this.interval * 1000).switchMap(() => {
+        return this.dataSource.getAlerts(searchRequest);
+      });
+    });
+  }
+
+  public getAlert(index: string, type: string, alertId: string): Observable<Alert> {
+    return this.dataSource.getAlert(index, type, alertId);
+  }
+
+  public updateAlertState(alerts: Alert[], state: string, workflowId: string) {
+    let request = '';
+    for (let alert of alerts) {
+      request += '{ "update" : { "_index" : "' + alert._index + '", "_type" : "' + alert._type + '", "_id" : "' + alert._id + '" } }\n' +
+                  '{ "doc": { "alert_status": "' + state + '"';
+      if (workflowId) {
+        request += ', "workflow_id": "' + workflowId + '"';
+      }
+      request += ' }}\n';
+    }
+
+    return this.dataSource.updateAlertState(request);
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts b/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts
new file mode 100644
index 0000000..4077f30
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts
@@ -0,0 +1,38 @@
+/**
+ * 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 {Injectable} from '@angular/core';
+import {Observable} from 'rxjs/Rx';
+import {Http} from '@angular/http';
+import {ColumnMetadata} from '../model/column-metadata';
+import {DataSource} from './data-source';
+
+@Injectable()
+export class ClusterMetaDataService {
+
+  constructor(private http: Http,
+              private dataSource: DataSource) {
+  }
+
+  getDefaultColumns(): Observable<ColumnMetadata[]> {
+    return this.dataSource.getDefaultAlertTableColumnNames();
+  }
+
+  getColumnMetaData(): Observable<ColumnMetadata[]> {
+    return this.dataSource.getAllFieldNames();
+  }
+}


Mime
View raw message