You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2017/11/10 21:52:33 UTC

[1/2] ambari git commit: AMBARI-22416 Log Search UI: fixes for filtering form. (ababiichuk)

Repository: ambari
Updated Branches:
  refs/heads/trunk 068d82f70 -> 7c4a7e4c5


http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
deleted file mode 100644
index 2b3e326..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * 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, inject} from '@angular/core/testing';
-import {StoreModule} from '@ngrx/store';
-import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
-import {AppStateService, appState} from '@app/services/storage/app-state.service';
-import {ClustersService, clusters} from '@app/services/storage/clusters.service';
-import {ComponentsService, components} from '@app/services/storage/components.service';
-import {HostsService, hosts} from '@app/services/storage/hosts.service';
-import {UtilsService} from '@app/services/utils.service';
-import {HttpClientService} from '@app/services/http-client.service';
-import {ListItem} from '@app/classes/list-item';
-import {Node} from '@app/classes/models/node';
-
-import {FilteringService} from './filtering.service';
-
-describe('FilteringService', () => {
-  beforeEach(() => {
-    const httpClient = {
-      get: () => {
-        return {
-          subscribe: () => {
-          }
-        }
-      }
-    };
-    TestBed.configureTestingModule({
-      imports: [
-        StoreModule.provideStore({
-          appSettings,
-          appState,
-          clusters,
-          components,
-          hosts
-        })
-      ],
-      providers: [
-        FilteringService,
-        AppSettingsService,
-        AppStateService,
-        ClustersService,
-        ComponentsService,
-        HostsService,
-        UtilsService,
-        {
-          provide: HttpClientService,
-          useValue: httpClient
-        }
-      ]
-    });
-  });
-
-  it('should create service', inject([FilteringService], (service: FilteringService) => {
-    expect(service).toBeTruthy();
-  }));
-
-  describe('#getListItemFromString()', () => {
-    it('should convert string to ListItem', inject([FilteringService], (service: FilteringService) => {
-      const getListItemFromString: (name: string) => ListItem = service['getListItemFromString'];
-      expect(getListItemFromString('customName')).toEqual({
-        label: 'customName',
-        value: 'customName'
-      });
-    }));
-  });
-
-  describe('#getListItemFromNode()', () => {
-    it('should convert Node to ListItem', inject([FilteringService], (service: FilteringService) => {
-      const getListItemFromNode: (node: Node) => ListItem = service['getListItemFromNode'];
-      expect(getListItemFromNode({
-        name: 'customName',
-        value: '1',
-        isParent: true,
-        isRoot: true
-      })).toEqual({
-        label: 'customName (1)',
-        value: 'customName'
-      });
-    }));
-  });
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
deleted file mode 100644
index 85dc408..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * 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, Input} from '@angular/core';
-import {FormGroup} from '@angular/forms';
-import {Response} from '@angular/http';
-import {Subject} from 'rxjs/Subject';
-import {Observable} from 'rxjs/Observable';
-import 'rxjs/add/observable/timer';
-import 'rxjs/add/operator/takeUntil';
-import * as moment from 'moment-timezone';
-import {ListItem} from '@app/classes/list-item';
-import {FilterCondition, filters} from '@app/classes/filtering';
-import {Node} from '@app/classes/models/node';
-import {AppSettingsService} from '@app/services/storage/app-settings.service';
-import {ClustersService} from '@app/services/storage/clusters.service';
-import {ComponentsService} from '@app/services/storage/components.service';
-import {HostsService} from '@app/services/storage/hosts.service';
-import {AppStateService} from '@app/services/storage/app-state.service';
-import {HttpClientService} from '@app/services/http-client.service';
-
-@Injectable()
-export class FilteringService {
-
-  constructor(private httpClient: HttpClientService, private appSettings: AppSettingsService, private clustersStorage: ClustersService, private componentsStorage: ComponentsService, private hostsStorage: HostsService, private appState: AppStateService) {
-    this.loadClusters();
-    this.loadComponents();
-    this.loadHosts();
-    appSettings.getParameter('timeZone').subscribe(value => this.timeZone = value || this.defaultTimeZone);
-    clustersStorage.getAll().subscribe((clusters: string[]): void => {
-      this.filters.clusters.options = [...this.filters.clusters.options, ...clusters.map(this.getListItemFromString)];
-    });
-    componentsStorage.getAll().subscribe((components: Node[]): void => {
-     this.filters.components.options = [...this.filters.components.options, ...components.map(this.getListItemFromNode)];
-    });
-    hostsStorage.getAll().subscribe((hosts: Node[]): void => {
-      this.filters.hosts.options = [...this.filters.hosts.options, ...hosts.map(this.getListItemFromNode)];
-    });
-    appState.getParameter('activeFiltersForm').subscribe((form: FormGroup) => this.activeFiltersForm = form);
-  }
-
-  /**
-   * Get instance for dropdown list from string
-   * @param name {string}
-   * @returns {ListItem}
-   */
-  private getListItemFromString(name: string): ListItem {
-    return {
-      label: name,
-      value: name
-    };
-  }
-
-  /**
-   * Get instance for dropdown list from Node object
-   * @param node {Node}
-   * @returns {ListItem}
-   */
-  private getListItemFromNode(node: Node): ListItem {
-    return {
-      label: `${node.name} (${node.value})`,
-      value: node.name
-    };
-  }
-
-  private readonly defaultTimeZone = moment.tz.guess();
-
-  timeZone: string = this.defaultTimeZone;
-
-  /**
-   * A configurable property to indicate the maximum capture time in milliseconds.
-   * @type {number}
-   * @default 600000 (10 minutes)
-   */
-  @Input()
-  maximumCaptureTimeLimit: number = 600000;
-
-  filters: {[key: string]: FilterCondition} = Object.assign({}, filters);
-
-  activeFiltersForm: FormGroup;
-
-  queryParameterNameChange: Subject<any> = new Subject();
-
-  queryParameterAdd: Subject<any> = new Subject();
-
-  private stopTimer: Subject<any> = new Subject();
-
-  private stopAutoRefreshCountdown: Subject<any> = new Subject();
-
-  captureSeconds: number = 0;
-
-  private readonly autoRefreshInterval: number = 30000;
-
-  autoRefreshRemainingSeconds: number = 0;
-
-  private startCaptureTime: number;
-
-  private stopCaptureTime: number;
-
-  startCaptureTimer(): void {
-    this.startCaptureTime = new Date().valueOf();
-    const maxCaptureTimeInSeconds = this.maximumCaptureTimeLimit / 1000;
-    Observable.timer(0, 1000).takeUntil(this.stopTimer).subscribe((seconds: number): void => {
-      this.captureSeconds = seconds;
-      if (this.captureSeconds >= maxCaptureTimeInSeconds) {
-        this.stopCaptureTimer();
-      }
-    });
-  }
-
-  stopCaptureTimer(): void {
-    const autoRefreshIntervalSeconds = this.autoRefreshInterval / 1000;
-    this.stopCaptureTime = new Date().valueOf();
-    this.captureSeconds = 0;
-    this.stopTimer.next();
-    this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
-    Observable.timer(0, 1000).takeUntil(this.stopAutoRefreshCountdown).subscribe((seconds: number): void => {
-      this.autoRefreshRemainingSeconds = autoRefreshIntervalSeconds - seconds;
-      if (!this.autoRefreshRemainingSeconds) {
-        this.stopAutoRefreshCountdown.next();
-        this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
-      }
-    });
-  }
-
-  loadClusters(): void {
-    this.httpClient.get('clusters').subscribe((response: Response): void => {
-      const clusterNames = response.json();
-      if (clusterNames) {
-        this.clustersStorage.addInstances(clusterNames);
-      }
-    });
-  }
-
-  loadComponents(): void {
-    this.httpClient.get('components').subscribe((response: Response): void => {
-      const jsonResponse = response.json(),
-        components = jsonResponse && jsonResponse.vNodeList.map((item): Node => Object.assign(item, {
-            value: item.logLevelCount.reduce((currentValue: number, currentItem): number => {
-              return currentValue + Number(currentItem.value);
-            }, 0)
-          }));
-      if (components) {
-        this.componentsStorage.addInstances(components);
-      }
-    });
-  }
-
-  loadHosts(): void {
-    this.httpClient.get('hosts').subscribe((response: Response): void => {
-      const jsonResponse = response.json(),
-        hosts = jsonResponse && jsonResponse.vNodeList;
-      if (hosts) {
-        this.hostsStorage.addInstances(hosts);
-      }
-    });
-  }
-
-  setCustomTimeRange(startTime: number, endTime: number): void {
-    this.activeFiltersForm.controls.timeRange.setValue({
-      type: 'CUSTOM',
-      start: moment(startTime),
-      end: moment(endTime)
-    });
-  }
-
-  private getStartTime = (value: any, current: string): string => {
-    let time;
-    if (value) {
-      const endTime = moment(moment(current).valueOf());
-      switch (value.type) {
-        case 'LAST':
-          time = endTime.subtract(value.interval, value.unit);
-          break;
-        case 'CURRENT':
-          time = moment().tz(this.timeZone).startOf(value.unit);
-          break;
-        case 'PAST':
-          time = endTime.startOf(value.unit);
-          break;
-        case 'CUSTOM':
-          time = value.start;
-          break;
-        default:
-          break;
-      }
-    }
-    return time ? time.toISOString() : '';
-  };
-
-  private getEndTime = (value: any): string => {
-    let time;
-    if (value) {
-      switch (value.type) {
-        case 'LAST':
-          time = moment();
-          break;
-        case 'CURRENT':
-          time = moment().tz(this.timeZone).endOf(value.unit);
-          break;
-        case 'PAST':
-          time = moment().tz(this.timeZone).startOf(value.unit).millisecond(-1);
-          break;
-        case 'CUSTOM':
-          time = value.end;
-          break;
-        default:
-          break;
-      }
-    }
-    return time ? time.toISOString() : '';
-  };
-
-  private getQuery(isExclude: boolean): (value: any[]) => string {
-    return (value: any[]): string => {
-      let parameters;
-      if (value && value.length) {
-        parameters = value.filter(item => item.isExclude === isExclude).map(parameter => {
-          return {
-            [parameter.name]: parameter.value.replace(/\s/g, '+')
-          };
-        });
-      }
-      return parameters && parameters.length ? JSON.stringify(parameters) : '';
-    }
-  }
-
-  readonly valueGetters = {
-    to: this.getEndTime,
-    from: this.getStartTime,
-    sortType: value => value && value.type,
-    sortBy: value => value && value.key,
-    page: value => value == null ? value : value.toString(),
-    includeQuery: this.getQuery(false),
-    excludeQuery: this.getQuery(true)
-  };
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
index ee0e1e7..47cb25d 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
@@ -31,7 +31,8 @@ import {HostsService, hosts} from '@app/services/storage/hosts.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {ListItem} from '@app/classes/list-item';
+import {NodeItem} from '@app/classes/models/node-item';
 
 import {LogsContainerService} from './logs-container.service';
 
@@ -79,8 +80,7 @@ describe('LogsContainerService', () => {
         {
           provide: HttpClientService,
           useValue: httpClient
-        },
-        FilteringService
+        }
       ]
     });
   });
@@ -88,4 +88,29 @@ describe('LogsContainerService', () => {
   it('should create service', inject([LogsContainerService], (service: LogsContainerService) => {
     expect(service).toBeTruthy();
   }));
+
+  describe('#getListItemFromString()', () => {
+    it('should convert string to ListItem', inject([LogsContainerService], (service: LogsContainerService) => {
+      const getListItemFromString: (name: string) => ListItem = service['getListItemFromString'];
+      expect(getListItemFromString('customName')).toEqual({
+        label: 'customName',
+        value: 'customName'
+      });
+    }));
+  });
+
+  describe('#getListItemFromNode()', () => {
+    it('should convert NodeItem to ListItem', inject([LogsContainerService], (service: LogsContainerService) => {
+      const getListItemFromNode: (node: NodeItem) => ListItem = service['getListItemFromNode'];
+      expect(getListItemFromNode({
+        name: 'customName',
+        value: '1',
+        isParent: true,
+        isRoot: true
+      })).toEqual({
+        label: 'customName (1)',
+        value: 'customName'
+      });
+    }));
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
index e187b00..f45887b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
@@ -17,9 +17,14 @@
  */
 
 import {Injectable} from '@angular/core';
+import {FormGroup, FormControl} from '@angular/forms';
 import {Response} from '@angular/http';
+import {Subject} from 'rxjs/Subject';
+import {Observable} from 'rxjs/Observable';
+import 'rxjs/add/observable/timer';
+import 'rxjs/add/operator/takeUntil';
+import * as moment from 'moment-timezone';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {AuditLogsService} from '@app/services/storage/audit-logs.service';
 import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.service';
 import {ServiceLogsService} from '@app/services/storage/service-logs.service';
@@ -27,30 +32,411 @@ import {ServiceLogsFieldsService} from '@app/services/storage/service-logs-field
 import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service';
 import {ServiceLogsTruncatedService} from '@app/services/storage/service-logs-truncated.service';
 import {AppStateService} from '@app/services/storage/app-state.service';
+import {AppSettingsService} from '@app/services/storage/app-settings.service';
 import {TabsService} from '@app/services/storage/tabs.service';
+import {ClustersService} from '@app/services/storage/clusters.service';
+import {ComponentsService} from '@app/services/storage/components.service';
+import {HostsService} from '@app/services/storage/hosts.service';
 import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry';
+import {FilterCondition, TimeUnitListItem, SortingListItem} from '@app/classes/filtering';
+import {ListItem} from '@app/classes/list-item';
 import {Tab} from '@app/classes/models/tab';
 import {AuditLogField} from '@app/classes/models/audit-log-field';
 import {ServiceLogField} from '@app/classes/models/service-log-field';
 import {BarGraph} from '@app/classes/models/bar-graph';
+import {NodeItem} from '@app/classes/models/node-item';
 
 @Injectable()
 export class LogsContainerService {
 
-  constructor(private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService, private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService, private tabsStorage: TabsService, private filtering: FilteringService) {
+  constructor(
+    private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService,
+    private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService,
+    private serviceLogsFieldsStorage: ServiceLogsFieldsService,
+    private serviceLogsHistogramStorage: ServiceLogsHistogramDataService,
+    private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService,
+    private appSettings: AppSettingsService, private tabsStorage: TabsService, private clustersStorage: ClustersService,
+    private componentsStorage: ComponentsService, private hostsStorage: HostsService
+  ) {
+    const formItems = Object.keys(this.filters).reduce((currentObject: any, key: string): {[key: string]: FormControl} => {
+      let formControl = new FormControl(),
+        item = {
+          [key]: formControl
+        };
+      formControl.setValue(this.filters[key].defaultSelection);
+      return Object.assign(currentObject, item);
+    }, {});
+    this.filtersForm = new FormGroup(formItems);
+    this.loadClusters();
+    this.loadComponents();
+    this.loadHosts();
     appState.getParameter('activeLog').subscribe((value: ActiveServiceLogEntry | null) => this.activeLog = value);
-    appState.getParameter('isServiceLogsFileView').subscribe((value: boolean): void => {
-      const activeLog = this.activeLog,
-        filtersForm = this.filtering.activeFiltersForm;
-      if (value && activeLog) {
-        filtersForm.controls.hosts.setValue(activeLog.host_name);
-        filtersForm.controls.components.setValue(activeLog.component_name);
-      }
-      this.isServiceLogsFileView = value;
-    });
+    appState.getParameter('isServiceLogsFileView').subscribe((value: boolean) => this.isServiceLogsFileView = value);
     appState.getParameter('activeLogsType').subscribe((value: string) => this.activeLogsType = value);
+    appSettings.getParameter('timeZone').subscribe((value: string) => this.timeZone = value || this.defaultTimeZone);
+    tabsStorage.mapCollection((tab: Tab): Tab => {
+      let currentAppState = tab.appState || {};
+      const appState = Object.assign({}, currentAppState, {
+        activeFilters: this.getFiltersData(tab.type)
+      });
+      return Object.assign({}, tab, {
+        appState
+      });
+    });
+    appState.getParameter('activeFilters').subscribe((filters: object): void => {
+      this.filtersFormChange.next();
+      if (filters) {
+        const controls = this.filtersForm.controls;
+        Object.keys(controls).forEach((key: string): void => {
+          controls[key].setValue(filters.hasOwnProperty(key) ? filters[key] : null);
+        });
+      }
+      this.loadLogs();
+      this.filtersForm.valueChanges.takeUntil(this.filtersFormChange).subscribe((value: object): void => {
+        this.tabsStorage.mapCollection((tab: Tab): Tab => {
+          const currentAppState = tab.appState || {},
+            appState = Object.assign({}, currentAppState, tab.isActive ? {
+              activeFilters: value
+            } : null);
+          return Object.assign({}, tab, {
+            appState
+          });
+        });
+        this.loadLogs();
+      });
+    });
   }
 
+  private readonly paginationOptions: string[] = ['10', '25', '50', '100'];
+
+  filters: {[key: string]: FilterCondition} = {
+    clusters: {
+      label: 'filter.clusters',
+      options: [],
+      defaultSelection: []
+    },
+    timeRange: {
+      options: [
+        [
+          {
+            label: 'filter.timeRange.7d',
+            value: {
+              type: 'LAST',
+              unit: 'd',
+              interval: 7
+            }
+          },
+          {
+            label: 'filter.timeRange.30d',
+            value: {
+              type: 'LAST',
+              unit: 'd',
+              interval: 30
+            }
+          },
+          {
+            label: 'filter.timeRange.60d',
+            value: {
+              type: 'LAST',
+              unit: 'd',
+              interval: 60
+            }
+          },
+          {
+            label: 'filter.timeRange.90d',
+            value: {
+              type: 'LAST',
+              unit: 'd',
+              interval: 90
+            }
+          },
+          {
+            label: 'filter.timeRange.6m',
+            value: {
+              type: 'LAST',
+              unit: 'M',
+              interval: 6
+            }
+          },
+          {
+            label: 'filter.timeRange.1y',
+            value: {
+              type: 'LAST',
+              unit: 'y',
+              interval: 1
+            }
+          },
+          {
+            label: 'filter.timeRange.2y',
+            value: {
+              type: 'LAST',
+              unit: 'y',
+              interval: 2
+            }
+          },
+          {
+            label: 'filter.timeRange.5y',
+            value: {
+              type: 'LAST',
+              unit: 'y',
+              interval: 5
+            }
+          }
+        ],
+        [
+          {
+            label: 'filter.timeRange.yesterday',
+            value: {
+              type: 'PAST',
+              unit: 'd'
+            }
+          },
+          // TODO implement time range calculation
+          /*
+           {
+           label: 'filter.timeRange.beforeYesterday',
+           value: {
+           type: 'PAST',
+           unit: 'd'
+           }
+           },
+           {
+           label: 'filter.timeRange.thisDayLastWeek',
+           value: {
+           type: 'PAST',
+           unit: 'd'
+           }
+           },
+           */
+          {
+            label: 'filter.timeRange.previousWeek',
+            value: {
+              type: 'PAST',
+              unit: 'w'
+            }
+          },
+          {
+            label: 'filter.timeRange.previousMonth',
+            value: {
+              type: 'PAST',
+              unit: 'M'
+            }
+          },
+          {
+            label: 'filter.timeRange.previousYear',
+            value: {
+              type: 'PAST',
+              unit: 'y'
+            }
+          }
+        ],
+        [
+          {
+            label: 'filter.timeRange.today',
+            value: {
+              type: 'CURRENT',
+              unit: 'd'
+            }
+          },
+          {
+            label: 'filter.timeRange.thisWeek',
+            value: {
+              type: 'CURRENT',
+              unit: 'w'
+            }
+          },
+          {
+            label: 'filter.timeRange.thisMonth',
+            value: {
+              type: 'CURRENT',
+              unit: 'M'
+            }
+          },
+          {
+            label: 'filter.timeRange.thisYear',
+            value: {
+              type: 'CURRENT',
+              unit: 'y'
+            }
+          }
+        ],
+        [
+          {
+            label: 'filter.timeRange.5min',
+            value: {
+              type: 'LAST',
+              unit: 'm',
+              interval: 5
+            }
+          },
+          {
+            label: 'filter.timeRange.15min',
+            value: {
+              type: 'LAST',
+              unit: 'm',
+              interval: 15
+            }
+          },
+          {
+            label: 'filter.timeRange.30min',
+            value: {
+              type: 'LAST',
+              unit: 'm',
+              interval: 30
+            }
+          },
+          {
+            label: 'filter.timeRange.1hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 1
+            }
+          },
+          {
+            label: 'filter.timeRange.3hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 3
+            }
+          },
+          {
+            label: 'filter.timeRange.6hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 6
+            }
+          },
+          {
+            label: 'filter.timeRange.12hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 12
+            }
+          },
+          {
+            label: 'filter.timeRange.24hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 24
+            }
+          },
+        ]
+      ],
+      defaultSelection: {
+        value: {
+          type: 'LAST',
+          unit: 'h',
+          interval: 1
+        },
+        label: 'filter.timeRange.1hr'
+      }
+    },
+    components: {
+      label: 'filter.components',
+      iconClass: 'fa fa-cubes',
+      options: [],
+      defaultSelection: []
+    },
+    levels: {
+      label: 'filter.levels',
+      iconClass: 'fa fa-sort-amount-asc',
+      options: [
+        {
+          label: 'levels.fatal',
+          value: 'FATAL'
+        },
+        {
+          label: 'levels.error',
+          value: 'ERROR'
+        },
+        {
+          label: 'levels.warn',
+          value: 'WARN'
+        },
+        {
+          label: 'levels.info',
+          value: 'INFO'
+        },
+        {
+          label: 'levels.debug',
+          value: 'DEBUG'
+        },
+        {
+          label: 'levels.trace',
+          value: 'TRACE'
+        },
+        {
+          label: 'levels.unknown',
+          value: 'UNKNOWN'
+        }
+      ],
+      defaultSelection: []
+    },
+    hosts: {
+      label: 'filter.hosts',
+      iconClass: 'fa fa-server',
+      options: [],
+      defaultSelection: []
+    },
+    sorting: {
+      label: 'sorting.title',
+      options: [
+        {
+          label: 'sorting.time.asc',
+          value: {
+            key: 'logtime',
+            type: 'asc'
+          }
+        },
+        {
+          label: 'sorting.time.desc',
+          value: {
+            key: 'logtime',
+            type: 'desc'
+          }
+        }
+      ],
+      defaultSelection: [
+        {
+          label: 'sorting.time.desc',
+          value: {
+            key: 'logtime',
+            type: 'desc'
+          }
+        }
+      ]
+    },
+    pageSize: {
+      label: 'pagination.title',
+      options: this.paginationOptions.map((option: string): ListItem => {
+        return {
+          label: option,
+          value: option
+        }
+      }),
+      defaultSelection: [
+        {
+          label: '10',
+          value: '10'
+        }
+      ]
+    },
+    page: {
+      defaultSelection: 0
+    },
+    query: {}
+  };
+
+  readonly filtersFormItemsMap: {[key: string]: string[]} = {
+    serviceLogs: ['clusters', 'timeRange', 'components', 'levels', 'hosts', 'sorting', 'pageSize', 'page', 'query'],
+    auditLogs: ['clusters', 'timeRange', 'sorting', 'pageSize', 'page', 'query'] // TODO add all the required fields
+  };
+
   readonly colors = {
     WARN: '#FF8916',
     ERROR: '#E81D1D',
@@ -93,14 +479,71 @@ export class LogsContainerService {
     }
   };
 
+  private readonly defaultTimeZone = moment.tz.guess();
+
+  timeZone: string = this.defaultTimeZone;
+
   totalCount: number = 0;
 
+  /**
+   * A configurable property to indicate the maximum capture time in milliseconds.
+   * @type {number}
+   * @default 600000 (10 minutes)
+   */
+  private readonly maximumCaptureTimeLimit: number = 600000;
+
   isServiceLogsFileView: boolean = false;
 
+  filtersForm: FormGroup;
+
   activeLog: ActiveServiceLogEntry | null = null;
 
   activeLogsType: string;
 
+  private filtersFormChange: Subject<any> = new Subject();
+
+  /**
+   * Get instance for dropdown list from string
+   * @param name {string}
+   * @returns {ListItem}
+   */
+  private getListItemFromString(name: string): ListItem {
+    return {
+      label: name,
+      value: name
+    };
+  }
+
+  /**
+   * Get instance for dropdown list from NodeItem object
+   * @param node {NodeItem}
+   * @returns {ListItem}
+   */
+  private getListItemFromNode(node: NodeItem): ListItem {
+    return {
+      label: `${node.name} (${node.value})`,
+      value: node.name
+    };
+  }
+
+  queryParameterNameChange: Subject<any> = new Subject();
+
+  queryParameterAdd: Subject<any> = new Subject();
+
+  private stopTimer: Subject<any> = new Subject();
+
+  private stopAutoRefreshCountdown: Subject<any> = new Subject();
+
+  captureSeconds: number = 0;
+
+  private readonly autoRefreshInterval: number = 30000;
+
+  autoRefreshRemainingSeconds: number = 0;
+
+  private startCaptureTime: number;
+
+  private stopCaptureTime: number;
+
   loadLogs = (logsType: string = this.activeLogsType): void => {
     this.httpClient.get(logsType, this.getParams('listFilters')).subscribe((response: Response): void => {
       const jsonResponse = response.json(),
@@ -128,7 +571,7 @@ export class LogsContainerService {
         }
       });
     }
-  }
+  };
 
   loadLogContext(id: string, hostName: string, componentName: string, scrollType: 'before' | 'after' | '' = ''): void {
     const params = {
@@ -161,22 +604,18 @@ export class LogsContainerService {
     });
   }
 
-  private getParams(filtersMapName: string): any {
+  private getParams(filtersMapName: string): {[key: string]: string} {
     let params = {};
     Object.keys(this[filtersMapName]).forEach((key: string): void => {
-      const inputValue = this.filtering.activeFiltersForm.getRawValue()[key],
+      const inputValue = this.filtersForm.getRawValue()[key],
         paramNames = this[filtersMapName][key];
-      paramNames.forEach(paramName => {
+      paramNames.forEach((paramName: string): void => {
         let value;
-        const valueGetter = this.filtering.valueGetters[paramName];
-        if (valueGetter) {
-          if (paramName === 'from') {
-            value = valueGetter(inputValue, params['to']);
-          } else {
-            value = valueGetter(inputValue);
-          }
+        const valueGetter = this.valueGetters[paramName] || this.defaultValueGetter;
+        if (paramName === 'from') {
+          value = valueGetter(inputValue, params['to']);
         } else {
-          value = inputValue;
+          value = valueGetter(inputValue);
         }
         if (value != null && value !== '') {
           params[paramName] = value;
@@ -222,12 +661,197 @@ export class LogsContainerService {
     return Object.keys(keysObject).map((key: string): {fieldClass} => new fieldClass(key));
   }
 
+  private getStartTime = (selection: TimeUnitListItem, current: string): string => {
+    let time;
+    const value = selection && selection.value;
+    if (value) {
+      const endTime = moment(moment(current).valueOf());
+      switch (value.type) {
+        case 'LAST':
+          time = endTime.subtract(value.interval, value.unit);
+          break;
+        case 'CURRENT':
+          time = moment().tz(this.timeZone).startOf(value.unit);
+          break;
+        case 'PAST':
+          time = endTime.startOf(value.unit);
+          break;
+        case 'CUSTOM':
+          time = value.start;
+          break;
+        default:
+          break;
+      }
+    }
+    return time ? time.toISOString() : '';
+  };
+
+  private getEndTime = (selection: TimeUnitListItem): string => {
+    let time;
+    const value = selection && selection.value;
+    if (value) {
+      switch (value.type) {
+        case 'LAST':
+          time = moment();
+          break;
+        case 'CURRENT':
+          time = moment().tz(this.timeZone).endOf(value.unit);
+          break;
+        case 'PAST':
+          time = moment().tz(this.timeZone).startOf(value.unit).millisecond(-1);
+          break;
+        case 'CUSTOM':
+          time = value.end;
+          break;
+        default:
+          break;
+      }
+    }
+    return time ? time.toISOString() : '';
+  };
+
+  private getQuery(isExclude: boolean): (value: any[]) => string {
+    return (value: any[]): string => {
+      let parameters;
+      if (value && value.length) {
+        parameters = value.filter(item => item.isExclude === isExclude).map(parameter => {
+          return {
+            [parameter.name]: parameter.value.replace(/\s/g, '+')
+          };
+        });
+      }
+      return parameters && parameters.length ? JSON.stringify(parameters) : '';
+    }
+  }
+
+  private getSortType(selection: SortingListItem[] = []): 'asc' | 'desc' {
+    return selection[0] && selection[0].value ? selection[0].value.type : 'desc';
+  }
+
+  private getSortKey(selection: SortingListItem[] = []): string {
+    return selection[0] && selection[0].value ? selection[0].value.key : '';
+  }
+
+  private getPage(value: number | undefined): string | undefined {
+    return typeof value === 'undefined' ? value : value.toString();
+  }
+
+  private defaultValueGetter(selection: ListItem | ListItem[] | null): string {
+    if (Array.isArray(selection)) {
+      return selection.map((item: ListItem): any => item.value).join(',');
+    } else if (selection) {
+      return selection.value;
+    } else {
+      return '';
+    }
+  }
+
+  private readonly valueGetters = {
+    to: this.getEndTime,
+    from: this.getStartTime,
+    sortType: this.getSortType,
+    sortBy: this.getSortKey,
+    page: this.getPage,
+    includeQuery: this.getQuery(false),
+    excludeQuery: this.getQuery(true)
+  };
+
   switchTab(activeTab: Tab): void {
+    this.tabsStorage.mapCollection((tab: Tab): Tab => {
+      return Object.assign({}, tab, {
+        isActive: tab.id === activeTab.id
+      });
+    });
     this.appState.setParameters(activeTab.appState);
-    this.tabsStorage.mapCollection((tab: Tab): Tab => Object.assign({}, tab, {
-      isActive: tab.id === activeTab.id
-    }));
-    this.loadLogs();
+  }
+
+  startCaptureTimer(): void {
+    this.startCaptureTime = new Date().valueOf();
+    const maxCaptureTimeInSeconds = this.maximumCaptureTimeLimit / 1000;
+    Observable.timer(0, 1000).takeUntil(this.stopTimer).subscribe((seconds: number): void => {
+      this.captureSeconds = seconds;
+      if (this.captureSeconds >= maxCaptureTimeInSeconds) {
+        this.stopCaptureTimer();
+      }
+    });
+  }
+
+  stopCaptureTimer(): void {
+    const autoRefreshIntervalSeconds = this.autoRefreshInterval / 1000;
+    this.stopCaptureTime = new Date().valueOf();
+    this.captureSeconds = 0;
+    this.stopTimer.next();
+    this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
+    Observable.timer(0, 1000).takeUntil(this.stopAutoRefreshCountdown).subscribe((seconds: number): void => {
+      this.autoRefreshRemainingSeconds = autoRefreshIntervalSeconds - seconds;
+      if (!this.autoRefreshRemainingSeconds) {
+        this.stopAutoRefreshCountdown.next();
+        this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
+      }
+    });
+  }
+
+  loadClusters(): Observable<Response> {
+    const request = this.httpClient.get('clusters');
+    request.subscribe((response: Response): void => {
+      const clusterNames = response.json();
+      if (clusterNames) {
+        this.filters.clusters.options.push(...clusterNames.map(this.getListItemFromString));
+        this.clustersStorage.addInstances(clusterNames);
+      }
+    });
+    return request;
+  }
+
+  loadComponents(): Observable<Response> {
+    const request = this.httpClient.get('components');
+    request.subscribe((response: Response): void => {
+      const jsonResponse = response.json(),
+        components = jsonResponse && jsonResponse.vNodeList.map((item): NodeItem => Object.assign(item, {
+            value: item.logLevelCount.reduce((currentValue: number, currentItem): number => {
+              return currentValue + Number(currentItem.value);
+            }, 0)
+          }));
+      if (components) {
+        this.filters.components.options.push(...components.map(this.getListItemFromNode));
+        this.componentsStorage.addInstances(components);
+      }
+    });
+    return request;
+  }
+
+  loadHosts(): Observable<Response> {
+    const request = this.httpClient.get('hosts');
+    request.subscribe((response: Response): void => {
+      const jsonResponse = response.json(),
+        hosts = jsonResponse && jsonResponse.vNodeList;
+      if (hosts) {
+        this.filters.hosts.options.push(...hosts.map(this.getListItemFromNode));
+        this.hostsStorage.addInstances(hosts);
+      }
+    });
+    return request;
+  }
+
+  setCustomTimeRange(startTime: number, endTime: number): void {
+    this.filtersForm.controls.timeRange.setValue({
+      label: 'filter.timeRange.custom',
+      value: {
+        type: 'CUSTOM',
+        start: moment(startTime),
+        end: moment(endTime)
+      }
+    });
+  }
+
+  getFiltersData(listType: string): object {
+    const itemsList = this.filtersFormItemsMap[listType],
+      keys = Object.keys(this.filters).filter((key: string): boolean => itemsList.indexOf(key) > -1);
+    return keys.reduce((currentObject: object, key: string): object => {
+      return Object.assign(currentObject, {
+        [key]: this.filters[key].defaultSelection
+      });
+    }, {});
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
index a4a0cf8..23d3726 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
@@ -31,56 +31,273 @@ describe('UtilsService', () => {
     expect(service).toBeTruthy();
   }));
 
-  describe('#updateMultiSelectValue()', () => {
+  describe('#isEqual()', () => {
     const cases = [
       {
-        currentValue: '',
-        value: 'v0',
-        isChecked: true,
-        result: 'v0',
-        title: 'check; no checked items before'
+        valueA: 1,
+        valueB: 1,
+        result: true,
+        title: 'same numbers'
       },
       {
-        currentValue: 'v1,v2',
-        value: 'v3',
-        isChecked: true,
-        result: 'v1,v2,v3',
-        title: 'check'
+        valueA: 1,
+        valueB: 2,
+        result: false,
+        title: 'different numbers'
       },
       {
-        currentValue: 'v4,v5',
-        value: 'v4',
-        isChecked: false,
-        result: 'v5',
-        title: 'uncheck'
+        valueA: 'a',
+        valueB: 'a',
+        result: true,
+        title: 'same strings'
       },
       {
-        currentValue: 'v6,v7',
-        value: 'v6',
-        isChecked: true,
-        result: 'v6,v7',
-        title: 'avoid repeating check action'
+        valueA: 'a',
+        valueB: 'b',
+        result: false,
+        title: 'different strings'
       },
       {
-        currentValue: 'v8,v9',
-        value: 'v10',
-        isChecked: false,
-        result: 'v8,v9',
-        title: 'avoid repeating uncheck action'
+        valueA: '1',
+        valueB: 1,
+        result: false,
+        title: 'different types'
       },
       {
-        currentValue: 'v11',
-        value: 'v11',
-        isChecked: false,
-        result: '',
-        title: 'uncheck last item'
+        valueA: true,
+        valueB: true,
+        result: true,
+        title: 'same booleans'
+      },
+      {
+        valueA: false,
+        valueB: true,
+        result: false,
+        title: 'different booleans'
+      },
+      {
+        valueA: {},
+        valueB: {},
+        result: true,
+        title: 'empty objects'
+      },
+      {
+        valueA: {
+          p0: 'v0'
+        },
+        valueB: {
+          p0: 'v0'
+        },
+        result: true,
+        title: 'same objects'
+      },
+      {
+        valueA: {
+          p0: 'v0'
+        },
+        valueB: {
+          p0: 'v1'
+        },
+        result: false,
+        title: 'different objects'
+      },
+      {
+        valueA: {
+          p0: {
+            p1: 'v1'
+          }
+        },
+        valueB: {
+          p0: {
+            p1: 'v1'
+          }
+        },
+        result: true,
+        title: 'same objects in depth'
+      },
+      {
+        valueA: {
+          p0: {
+            p1: 'v1'
+          }
+        },
+        valueB: {
+          p0: {
+            p1: 'v2'
+          }
+        },
+        result: false,
+        title: 'different objects in depth'
+      },
+      {
+        valueA: [],
+        valueB: [],
+        result: true,
+        title: 'empty arrays'
+      },
+      {
+        valueA: [1, 'a'],
+        valueB: [1, 'a'],
+        result: true,
+        title: 'same arrays'
+      },
+      {
+        valueA: [1, 'a'],
+        valueB: [1, 'b'],
+        result: false,
+        title: 'different arrays'
+      },
+      {
+        valueA: [1, 1],
+        valueB: [1, 1, 1],
+        result: false,
+        title: 'arrays of different length'
+      },
+      {
+        valueA: [{}],
+        valueB: [{}],
+        result: true,
+        title: 'arrays of empty objects'
+      },
+      {
+        valueA: [
+          {
+            p0: 'v0'
+          }
+        ],
+        valueB: [
+          {
+            p0: 'v0'
+          }
+        ],
+        result: true,
+        title: 'arrays of same objects'
+      },
+      {
+        valueA: [
+          {
+            p0: 'v0'
+          }
+        ],
+        valueB: [
+          {
+            p0: 'v1'
+          }
+        ],
+        result: false,
+        title: 'arrays of different objects'
+      },
+      {
+        valueA: function() {},
+        valueB: function() {},
+        result: true,
+        title: 'same functions'
+      },
+      {
+        valueA: function(a) {
+          return a;
+        },
+        valueB: function(b) {
+          return !b;
+        },
+        result: false,
+        title: 'different functions'
+      },
+      {
+        valueA: new Date(1),
+        valueB: new Date(1),
+        result: true,
+        title: 'same dates'
+      },
+      {
+        valueA: new Date(1),
+        valueB: new Date(2),
+        result: false,
+        title: 'different dates'
+      },
+      {
+        valueA: new RegExp('a'),
+        valueB: new RegExp('a'),
+        result: true,
+        title: 'same regexps'
+      },
+      {
+        valueA: new RegExp('a', 'i'),
+        valueB: new RegExp('a', 'g'),
+        result: false,
+        title: 'same regexps with different flags'
+      },
+      {
+        valueA: new RegExp('a'),
+        valueB: new RegExp('b'),
+        result: false,
+        title: 'different regexps'
+      },
+      {
+        valueA: new Number(1),
+        valueB: new Number(1),
+        result: true,
+        title: 'same number objects'
+      },
+      {
+        valueA: new Number(1),
+        valueB: new Number(2),
+        result: false,
+        title: 'different number objects'
+      },
+      {
+        valueA: new String('a'),
+        valueB: new String('a'),
+        result: true,
+        title: 'same string objects'
+      },
+      {
+        valueA: new String('a'),
+        valueB: new String('b'),
+        result: false,
+        title: 'different string objects'
+      },
+      {
+        valueA: new Boolean(true),
+        valueB: new Boolean(true),
+        result: true,
+        title: 'same boolean objects'
+      },
+      {
+        valueA: new Boolean(true),
+        valueB: new Boolean(false),
+        result: false,
+        title: 'different boolean objects'
+      },
+      {
+        valueA: null,
+        valueB: null,
+        result: true,
+        title: 'null values'
+      },
+      {
+        valueA: undefined,
+        valueB: undefined,
+        result: true,
+        title: 'undefined values'
+      },
+      {
+        valueA: undefined,
+        valueB: null,
+        result: false,
+        title: 'undefined vs null'
       }
     ];
 
     cases.forEach(test => {
-      it(test.title, inject([UtilsService], (service: UtilsService) => {
-        expect(service.updateMultiSelectValue(test.currentValue, test.value, test.isChecked)).toEqual(test.result);
-      }));
+      describe(test.title, () => {
+        it('equality', inject([UtilsService], (service: UtilsService) => {
+          expect(service.isEqual(test.valueA, test.valueB)).toEqual(test.result);
+        }));
+        it('symmetry', inject([UtilsService], (service: UtilsService) => {
+          expect(service.isEqual(test.valueA, test.valueB)).toEqual(service.isEqual(test.valueB, test.valueA));
+        }));
+      });
     });
   });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
index 3448dd4..175b585 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
@@ -22,27 +22,56 @@ import * as moment from 'moment-timezone';
 @Injectable()
 export class UtilsService {
 
-  valueHasChanged(currentValue: any, newValue: any): boolean {
-    if (newValue == null) {
+  /**
+   * Comparison of two instances of any data type be value instead of reference
+   * @param valueA
+   * @param valueB
+   * @returns {boolean}
+   */
+  isEqual = (valueA: any, valueB: any): boolean => {
+    if (valueA === valueB) {
+      return true;
+    }
+    if (valueA instanceof Date && valueB instanceof Date) {
+      return valueA.valueOf() === valueB.valueOf();
+    }
+    if ((typeof valueA === 'function' && typeof valueB === 'function') ||
+      (valueA instanceof RegExp && valueB instanceof RegExp) ||
+      (valueA instanceof String && valueB instanceof String) ||
+      (valueA instanceof Number && valueB instanceof Number) ||
+      (valueA instanceof Boolean && valueB instanceof Boolean)) {
+      return valueA.toString() === valueB.toString();
+    }
+    if (!(valueA instanceof Object) || !(valueB instanceof Object)) {
       return false;
     }
-    if (typeof newValue === 'object') {
-      return JSON.stringify(currentValue) !== JSON.stringify(newValue);
-    } else {
-      return currentValue !== newValue;
+    if (valueA.constructor !== valueB.constructor) {
+      return false;
     }
-  }
-
-  updateMultiSelectValue(currentValue: string, value: string, isChecked: boolean): string {
-    let valuesArray = currentValue ? currentValue.split(',') : [],
-      valuePosition = valuesArray.indexOf(value);
-    if (isChecked && valuePosition === -1) {
-      valuesArray.push(value);
-    } else if (!isChecked && valuePosition > -1) {
-      valuesArray.splice(valuePosition, 1);
-    }
-    return valuesArray.join(',');
-  }
+    if (valueA.isPrototypeOf(valueB) || valueB.isPrototypeOf(valueA)) {
+      return false;
+    }
+    for (const key in valueA) {
+      if (!valueA.hasOwnProperty(key)) {
+        continue;
+      }
+      if (!valueB.hasOwnProperty(key)) {
+        return false;
+      }
+      if (valueA[key] === valueB[key]) {
+        continue;
+      }
+      if (typeof valueA[key] !== 'object' || !this.isEqual(valueA[key], valueB[key])) {
+        return false;
+      }
+    }
+    for (const key in valueB) {
+      if (valueB.hasOwnProperty(key) && !valueA.hasOwnProperty(key)) {
+        return false;
+      }
+    }
+    return true;
+  };
 
   isEnterPressed(event: KeyboardEvent): boolean {
     return event.keyCode === 13;


[2/2] ambari git commit: AMBARI-22416 Log Search UI: fixes for filtering form. (ababiichuk)

Posted by ab...@apache.org.
AMBARI-22416 Log Search UI: fixes for filtering form. (ababiichuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7c4a7e4c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7c4a7e4c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7c4a7e4c

Branch: refs/heads/trunk
Commit: 7c4a7e4c52e00282e5b8b901cef14c143fd3da2b
Parents: 068d82f
Author: ababiichuk <ab...@hortonworks.com>
Authored: Fri Nov 10 18:16:45 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Fri Nov 10 23:53:24 2017 +0200

----------------------------------------------------------------------
 .../ambari-logsearch-web/src/app/app.module.ts  |   2 -
 .../src/app/classes/filtering.ts                | 355 +---------
 .../src/app/classes/models/app-state.ts         |   6 +-
 .../src/app/classes/models/node-item.ts         |  30 +
 .../src/app/classes/models/node.ts              |  30 -
 .../src/app/classes/models/store.ts             |   6 +-
 .../src/app/classes/models/tab.ts               |  12 +-
 .../src/app/components/app.component.ts         |   6 +-
 .../dropdown-button.component.html              |   4 +-
 .../dropdown-button.component.spec.ts           |   2 -
 .../dropdown-button.component.ts                |  55 +-
 .../dropdown-list/dropdown-list.component.html  |   2 +-
 .../dropdown-list.component.spec.ts             |   6 +-
 .../filter-button.component.spec.ts             |   2 -
 .../filter-button/filter-button.component.ts    |  35 +-
 .../filter-dropdown.component.spec.ts           |  14 +-
 .../filter-dropdown.component.ts                |  22 +-
 .../filters-panel/filters-panel.component.html  |   6 +-
 .../filters-panel.component.spec.ts             |   6 +-
 .../filters-panel/filters-panel.component.ts    |  18 +-
 .../log-context/log-context.component.spec.ts   |   4 +-
 .../logs-container.component.spec.ts            |   2 -
 .../logs-container/logs-container.component.ts  |  26 +-
 .../logs-list/logs-list.component.html          |   3 +-
 .../logs-list/logs-list.component.spec.ts       |  21 +-
 .../components/logs-list/logs-list.component.ts |  10 +-
 .../menu-button/menu-button.component.spec.ts   |   2 -
 .../menu-button/menu-button.component.ts        |   4 +-
 .../pagination-controls.component.ts            |   7 +-
 .../pagination/pagination.component.html        |   2 +-
 .../pagination/pagination.component.spec.ts     |   9 +-
 .../pagination/pagination.component.ts          |  10 +-
 .../search-box/search-box.component.ts          |  12 +-
 .../time-range-picker.component.html            |   3 +-
 .../time-range-picker.component.spec.ts         |  29 +-
 .../time-range-picker.component.ts              |  47 +-
 .../timezone-picker.component.spec.ts           |   2 -
 .../services/component-actions.service.spec.ts  |   2 -
 .../app/services/component-actions.service.ts   |  24 +-
 .../component-generator.service.spec.ts         |   2 -
 .../src/app/services/filtering.service.spec.ts  |  97 ---
 .../src/app/services/filtering.service.ts       | 253 -------
 .../app/services/logs-container.service.spec.ts |  31 +-
 .../src/app/services/logs-container.service.ts  | 678 ++++++++++++++++++-
 .../src/app/services/utils.service.spec.ts      | 285 +++++++-
 .../src/app/services/utils.service.ts           |  65 +-
 46 files changed, 1257 insertions(+), 992 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index 56562df..37f3a49 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -34,7 +34,6 @@ import {environment} from '@envs/environment';
 import {mockApiDataService} from '@app/services/mock-api-data.service'
 import {HttpClientService} from '@app/services/http-client.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {UtilsService} from '@app/services/utils.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {ComponentGeneratorService} from '@app/services/component-generator.service';
@@ -164,7 +163,6 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
   providers: [
     HttpClientService,
     ComponentActionsService,
-    FilteringService,
     UtilsService,
     LogsContainerService,
     ComponentGeneratorService,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
index dde144b..2a7205f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
@@ -16,354 +16,37 @@
  * limitations under the License.
  */
 
-import {FormGroup, FormControl} from '@angular/forms';
+import {Moment, unitOfTime} from 'moment';
 import {ListItem} from '@app/classes/list-item';
 
 export interface TimeUnit {
   type: 'CURRENT' | 'LAST' | 'PAST';
-  unit: 'ms' | 's' | 'm' | 'h' | 'd' | 'w' | 'M' | 'Y';
+  unit: unitOfTime.DurationConstructor;
   interval?: number;
 }
 
+export interface CustomTimeRange {
+  type: 'CUSTOM';
+  start?: Moment;
+  end?: Moment;
+}
+
+export interface SortingConditions {
+  key: string;
+  type: 'asc' | 'desc';
+}
+
 export interface TimeUnitListItem extends ListItem {
-  value: TimeUnit;
+  value: TimeUnit | CustomTimeRange;
+}
+
+export interface SortingListItem extends ListItem {
+  value: SortingConditions;
 }
 
 export interface FilterCondition {
   label?: string;
   options?: (ListItem | TimeUnitListItem[])[];
-  defaultValue?: string | number | {[key: string]: any};
-  defaultLabel?: string;
+  defaultSelection?: ListItem | ListItem[] | number;
   iconClass?: string;
 }
-
-const paginationOptions: string[] = ['10', '25', '50', '100'];
-
-export const filters: {[key: string]: FilterCondition} = {
-  clusters: {
-    label: 'filter.clusters',
-    options: [],
-    defaultValue: ''
-  },
-  timeRange: {
-    options: [
-      [
-        {
-          label: 'filter.timeRange.7d',
-          value: {
-            type: 'LAST',
-            unit: 'd',
-            interval: 7
-          }
-        },
-        {
-          label: 'filter.timeRange.30d',
-          value: {
-            type: 'LAST',
-            unit: 'd',
-            interval: 30
-          }
-        },
-        {
-          label: 'filter.timeRange.60d',
-          value: {
-            type: 'LAST',
-            unit: 'd',
-            interval: 60
-          }
-        },
-        {
-          label: 'filter.timeRange.90d',
-          value: {
-            type: 'LAST',
-            unit: 'd',
-            interval: 90
-          }
-        },
-        {
-          label: 'filter.timeRange.6m',
-          value: {
-            type: 'LAST',
-            unit: 'M',
-            interval: 6
-          }
-        },
-        {
-          label: 'filter.timeRange.1y',
-          value: {
-            type: 'LAST',
-            unit: 'Y',
-            interval: 1
-          }
-        },
-        {
-          label: 'filter.timeRange.2y',
-          value: {
-            type: 'LAST',
-            unit: 'Y',
-            interval: 2
-          }
-        },
-        {
-          label: 'filter.timeRange.5y',
-          value: {
-            type: 'LAST',
-            unit: 'Y',
-            interval: 5
-          }
-        }
-      ],
-      [
-        {
-          label: 'filter.timeRange.yesterday',
-          value: {
-            type: 'PAST',
-            unit: 'd'
-          }
-        },
-        // TODO implement time range calculation
-        /*
-         {
-         label: 'filter.timeRange.beforeYesterday',
-         value: {
-         type: 'PAST',
-         unit: 'd'
-         }
-         },
-         {
-         label: 'filter.timeRange.thisDayLastWeek',
-         value: {
-         type: 'PAST',
-         unit: 'd'
-         }
-         },
-         */
-        {
-          label: 'filter.timeRange.previousWeek',
-          value: {
-            type: 'PAST',
-            unit: 'w'
-          }
-        },
-        {
-          label: 'filter.timeRange.previousMonth',
-          value: {
-            type: 'PAST',
-            unit: 'M'
-          }
-        },
-        {
-          label: 'filter.timeRange.previousYear',
-          value: {
-            type: 'PAST',
-            unit: 'Y'
-          }
-        }
-      ],
-      [
-        {
-          label: 'filter.timeRange.today',
-          value: {
-            type: 'CURRENT',
-            unit: 'd'
-          }
-        },
-        {
-          label: 'filter.timeRange.thisWeek',
-          value: {
-            type: 'CURRENT',
-            unit: 'w'
-          }
-        },
-        {
-          label: 'filter.timeRange.thisMonth',
-          value: {
-            type: 'CURRENT',
-            unit: 'M'
-          }
-        },
-        {
-          label: 'filter.timeRange.thisYear',
-          value: {
-            type: 'CURRENT',
-            unit: 'Y'
-          }
-        }
-      ],
-      [
-        {
-          label: 'filter.timeRange.5min',
-          value: {
-            type: 'LAST',
-            unit: 'm',
-            interval: 5
-          }
-        },
-        {
-          label: 'filter.timeRange.15min',
-          value: {
-            type: 'LAST',
-            unit: 'm',
-            interval: 15
-          }
-        },
-        {
-          label: 'filter.timeRange.30min',
-          value: {
-            type: 'LAST',
-            unit: 'm',
-            interval: 30
-          }
-        },
-        {
-          label: 'filter.timeRange.1hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 1
-          }
-        },
-        {
-          label: 'filter.timeRange.3hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 3
-          }
-        },
-        {
-          label: 'filter.timeRange.6hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 6
-          }
-        },
-        {
-          label: 'filter.timeRange.12hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 12
-          }
-        },
-        {
-          label: 'filter.timeRange.24hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 24
-          }
-        },
-      ]
-    ],
-    defaultValue: {
-      type: 'LAST',
-      unit: 'h',
-      interval: 1
-    },
-    defaultLabel: 'filter.timeRange.1hr'
-  },
-  components: {
-    label: 'filter.components',
-    iconClass: 'fa fa-cubes',
-    options: [],
-    defaultValue: ''
-  },
-  levels: {
-    label: 'filter.levels',
-    iconClass: 'fa fa-sort-amount-asc',
-    options: [
-      {
-        label: 'levels.fatal',
-        value: 'FATAL'
-      },
-      {
-        label: 'levels.error',
-        value: 'ERROR'
-      },
-      {
-        label: 'levels.warn',
-        value: 'WARN'
-      },
-      {
-        label: 'levels.info',
-        value: 'INFO'
-      },
-      {
-        label: 'levels.debug',
-        value: 'DEBUG'
-      },
-      {
-        label: 'levels.trace',
-        value: 'TRACE'
-      },
-      {
-        label: 'levels.unknown',
-        value: 'UNKNOWN'
-      }
-    ],
-    defaultValue: ''
-  },
-  hosts: {
-    label: 'filter.hosts',
-    iconClass: 'fa fa-server',
-    options: [],
-    defaultValue: ''
-  },
-  sorting: {
-    label: 'sorting.title',
-    options: [
-      {
-        label: 'sorting.time.asc',
-        value: {
-          key: 'logtime',
-          type: 'asc'
-        }
-      },
-      {
-        label: 'sorting.time.desc',
-        value: {
-          key: 'logtime',
-          type: 'desc'
-        }
-      }
-    ],
-    defaultValue: '',
-    defaultLabel: ''
-  },
-  pageSize: {
-    label: 'pagination.title',
-    options: paginationOptions.map((option: string): ListItem => {
-      return {
-        label: option,
-        value: option
-      }
-    }),
-    defaultValue: '10',
-    defaultLabel: '10'
-  },
-  page: {
-    defaultValue: 0
-  },
-  query: {}
-};
-
-export const filtersFormItemsMap: {[key: string]: string[]} = {
-  serviceLogs: ['clusters', 'timeRange', 'components', 'levels', 'hosts', 'sorting', 'pageSize', 'page', 'query'],
-  auditLogs: ['clusters', 'timeRange', 'sorting', 'pageSize', 'page', 'query'] // TODO add all the required fields
-};
-
-export const getFiltersForm = (listType: string): FormGroup => {
-  const itemsList = filtersFormItemsMap[listType],
-    keys = Object.keys(filters).filter((key: string): boolean => itemsList.indexOf(key) > -1),
-    items = keys.reduce((currentObject: any, key: string): any => {
-      let formControl = new FormControl(),
-        item = {
-          [key]: formControl
-        };
-      formControl.setValue(filters[key].defaultValue);
-      return Object.assign(currentObject, item);
-    }, {});
-  return new FormGroup(items);
-};

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
index 2c5c083..afed497 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
@@ -16,9 +16,7 @@
  * limitations under the License.
  */
 
-import {FormGroup} from '@angular/forms';
 import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry';
-import {Tab, initialTabs} from '@app/classes/models/tab';
 
 export interface AppState {
   isAuthorized: boolean;
@@ -28,7 +26,7 @@ export interface AppState {
   isServiceLogsFileView: boolean;
   isServiceLogContextView: boolean;
   activeLog: ActiveServiceLogEntry | null;
-  activeFiltersForm: FormGroup;
+  activeFilters: object;
 }
 
 export const initialState: AppState = {
@@ -39,5 +37,5 @@ export const initialState: AppState = {
   isServiceLogsFileView: false,
   isServiceLogContextView: false,
   activeLog: null,
-  activeFiltersForm: initialTabs.find((tab: Tab): boolean => tab.isActive).appState.activeFiltersForm
+  activeFilters: null
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts
new file mode 100644
index 0000000..ef5f772
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.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 {CommonEntry} from '@app/classes/models/common-entry';
+
+export interface NodeItem {
+  name: string;
+  type?: string;
+  value: string;
+  isParent: boolean;
+  isRoot: boolean;
+  childs?: NodeItem[];
+  logLevelCount?: CommonEntry[];
+  vNodeList?: CommonEntry[];
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
deleted file mode 100644
index a14e51a..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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 {CommonEntry} from '@app/classes/models/common-entry';
-
-export interface Node {
-  name: string;
-  type?: string;
-  value: string;
-  isParent: boolean;
-  isRoot: boolean;
-  childs?: Node[];
-  logLevelCount?: CommonEntry[];
-  vNodeList?: CommonEntry[];
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
index d912b35..f996d92 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
@@ -24,7 +24,7 @@ import {AuditLog} from '@app/classes/models/audit-log';
 import {ServiceLog} from '@app/classes/models/service-log';
 import {BarGraph} from '@app/classes/models/bar-graph';
 import {Graph} from '@app/classes/models/graph';
-import {Node} from '@app/classes/models/node';
+import {NodeItem} from '@app/classes/models/node-item';
 import {UserConfig} from '@app/classes/models/user-config';
 import {Filter} from '@app/classes/models/filter';
 import {AuditLogField} from '@app/classes/models/audit-log-field';
@@ -50,11 +50,11 @@ export interface AppStore {
   serviceLogsHistogramData: BarGraph[];
   serviceLogsTruncated: ServiceLog[];
   graphs: Graph[];
-  hosts: Node[];
+  hosts: NodeItem[];
   userConfigs: UserConfig[];
   filters: Filter[];
   clusters: string[];
-  components: Node[];
+  components: NodeItem[];
   serviceLogsFields: ServiceLogField[];
   auditLogsFields: AuditLogField[];
   tabs: Tab[];

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
index bb8028a..05ea59d 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
@@ -16,15 +16,13 @@
  * limitations under the License.
  */
 
-import {getFiltersForm} from '@app/classes/filtering';
-
 export interface Tab {
   id: string;
   type: string;
-  isActive: boolean;
+  isActive?: boolean;
   isCloseable?: boolean;
   label: string;
-  appState: any;
+  appState?: object;
 }
 
 export const initialTabs: Tab[] = [
@@ -35,8 +33,7 @@ export const initialTabs: Tab[] = [
     label: 'common.serviceLogs',
     appState: {
       activeLogsType: 'serviceLogs',
-      isServiceLogsFileView: false,
-      activeFiltersForm: getFiltersForm('serviceLogs')
+      isServiceLogsFileView: false
     }
   },
   {
@@ -46,8 +43,7 @@ export const initialTabs: Tab[] = [
     label: 'common.auditLogs',
     appState: {
       activeLogsType: 'auditLogs',
-      isServiceLogsFileView: false,
-      activeFiltersForm: getFiltersForm('auditLogs')
+      isServiceLogsFileView: false
     }
   }
 ];

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
index 4de47ea..038dd2a 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
@@ -30,12 +30,12 @@ import {HttpClientService} from '@app/services/http-client.service';
 export class AppComponent {
 
   constructor(private httpClient: HttpClientService, private translate: TranslateService, private appState: AppStateService) {
-    appState.getParameter('isAuthorized').subscribe(value => this.isAuthorized = value);
+    appState.getParameter('isAuthorized').subscribe((value: boolean) => this.isAuthorized = value);
     appState.setParameter('isInitialLoading', true);
-    this.httpClient.get('status').subscribe(() => this.appState.setParameters({
+    httpClient.get('status').subscribe(() => appState.setParameters({
       isAuthorized: true,
       isInitialLoading: false
-    }), () => this.appState.setParameter('isInitialLoading', false));
+    }), () => appState.setParameter('isInitialLoading', false));
     translate.setDefaultLang('en');
     translate.use('en');
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
index 798a609..b5f1e56 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
@@ -22,10 +22,10 @@
       <span *ngIf="iconClass" [ngClass]="iconClass"></span>
       <span *ngIf="label">{{label | translate}}</span>
     </span>
-    <span *ngIf="showSelectedValue && !isMultipleChoice">{{selectedLabel | translate}}</span>
+    <span *ngIf="showSelectedValue && !isMultipleChoice && selection.length">{{selection[0].label | translate}}</span>
     <span *ngIf="!hideCaret" class="caret"></span>
   </button>
   <ul data-component="dropdown-list" [ngClass]="{'dropdown-menu': true, 'dropdown-menu-right': isRightAlign}"
-      [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateValue($event)"
+      [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateSelection($event)"
       [actionArguments]="additionalArgs"></ul>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
index f11ca09..bd41c04 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
 import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {UtilsService} from '@app/services/utils.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 import {HttpClientService} from '@app/services/http-client.service';
@@ -85,7 +84,6 @@ describe('DropdownButtonComponent', () => {
         ServiceLogsHistogramDataService,
         ServiceLogsTruncatedService,
         TabsService,
-        FilteringService,
         UtilsService,
         ComponentActionsService,
         {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
index 0bf4422..148e1b4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-import {Component, OnInit, Input} from '@angular/core';
+import {Component, Input} from '@angular/core';
 import {ListItem} from '@app/classes/list-item';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 import {UtilsService} from '@app/services/utils.service';
@@ -26,14 +26,10 @@ import {UtilsService} from '@app/services/utils.service';
   templateUrl: './dropdown-button.component.html',
   styleUrls: ['./dropdown-button.component.less']
 })
-export class DropdownButtonComponent implements OnInit {
+export class DropdownButtonComponent {
 
   constructor(protected actions: ComponentActionsService, protected utils: UtilsService) {
   }
-
-  ngOnInit() {
-    this.selectedLabel = this.defaultLabel;
-  }
   
   @Input()
   label?: string;
@@ -48,13 +44,7 @@ export class DropdownButtonComponent implements OnInit {
   showSelectedValue: boolean = true;
 
   @Input()
-  options?: ListItem[];
-
-  @Input()
-  defaultValue?: string;
-
-  @Input()
-  defaultLabel?: string;
+  options: ListItem[] = [];
 
   @Input()
   action?: string;
@@ -71,36 +61,33 @@ export class DropdownButtonComponent implements OnInit {
   @Input()
   isDropup: boolean = false;
 
-  protected selectedValue?: any;
-
-  selectedLabel: string;
+  protected selectedItems?: ListItem[] = [];
 
-  get value(): any {
-    return this.selectedValue;
+  get selection(): ListItem[] {
+    return this.selectedItems;
   }
 
-  set value(value: any) {
-    this.selectedValue = value;
+  set selection(items: ListItem[]) {
+    this.selectedItems = items;
   }
 
-  updateValue(eventOptions: ListItem): void {
-    const value = eventOptions && eventOptions.value,
-      action = this.action && this.actions[this.action];
+  updateSelection(item: ListItem): void {
+    const action = this.action && this.actions[this.action];
     if (this.isMultipleChoice) {
-      this.value = this.utils.updateMultiSelectValue(this.value, value, eventOptions.isChecked);
-      this.options.find(item => item.value === value).isChecked = eventOptions.isChecked;
+      this.options.find((option: ListItem): boolean => {
+        return this.utils.isEqual(option.value, item.value);
+      }).isChecked = item.isChecked;
+      const checkedItems = this.options.filter((option: ListItem): boolean => option.isChecked);
+      this.selection = checkedItems;
       if (action) {
-        action(this.options.filter(item => item.isChecked).map(item => item.value), ...this.additionalArgs);
+        action(checkedItems.map((option: ListItem): any => option.value), ...this.additionalArgs);
       }
-    } else {
-      if (this.utils.valueHasChanged(this.value, value)) {
-        this.value = value;
-        this.selectedLabel = eventOptions.label;
-        if (action) {
-          action(this.value, ...this.additionalArgs);
-        }
+    } else if (!this.utils.isEqual(this.selection[0], item)) {
+      this.selection = [item];
+      if (action) {
+        action(item.value, ...this.additionalArgs);
       }
     }
   }
-  
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
index 5de78ad..df564e5 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
@@ -17,7 +17,7 @@
 
 <li *ngFor="let item of items">
   <label class="list-item-label" *ngIf="isMultipleChoice">
-    <input type="checkbox" [attr.id]="item.id || item.value" [attr.checked]="item.isChecked ? 'checked' : null"
+    <input type="checkbox" [attr.id]="item.id || item.value" [(ngModel)]="item.isChecked"
            (change)="changeSelectedItem({value: item.value, isChecked: $event.currentTarget.checked})">
     <label [attr.for]="item.id || item.value" class="label-container">
       <span *ngIf="item.iconClass" [ngClass]="item.iconClass"></span>

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
index 5455e67..ac2fa84 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
@@ -17,6 +17,7 @@
  */
 
 import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {FormsModule} from '@angular/forms';
 import {StoreModule} from '@ngrx/store';
 import {TranslationModules} from '@app/test-config.spec';
 import {HostsService, hosts} from '@app/services/storage/hosts.service';
@@ -34,7 +35,6 @@ import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {ComponentGeneratorService} from '@app/services/component-generator.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 
 import {DropdownListComponent} from './dropdown-list.component';
@@ -69,7 +69,8 @@ describe('DropdownListComponent', () => {
           components,
           serviceLogsTruncated,
           tabs
-        })
+        }),
+        FormsModule
       ],
       providers: [
         ComponentGeneratorService,
@@ -78,7 +79,6 @@ describe('DropdownListComponent', () => {
           provide: HttpClientService,
           useValue: httpClient
         },
-        FilteringService,
         ComponentActionsService,
         HostsService,
         AuditLogsService,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
index 3e40455..f9ae154 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
@@ -33,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {UtilsService} from '@app/services/utils.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
@@ -86,7 +85,6 @@ describe('FilterButtonComponent', () => {
         ServiceLogsTruncatedService,
         TabsService,
         ComponentActionsService,
-        FilteringService,
         UtilsService,
         {
           provide: HttpClientService,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
index 2c8ecd7..2dcecd1 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
@@ -41,34 +41,35 @@ export class FilterButtonComponent extends MenuButtonComponent implements Contro
     super(actions);
   }
 
-  @Input()
-  defaultValue?: string;
-
-  private selectedValue: any;
+  private selectedItems: ListItem[] = [];
 
   private onChange: (fn: any) => void;
 
-  get value(): any {
-    return this.selectedValue;
+  get selection(): ListItem[] {
+    return this.selectedItems;
   }
 
-  set value(newValue: any) {
-    this.selectedValue = newValue;
-    this.onChange(newValue);
+  set selection(items: ListItem[]) {
+    this.selectedItems = items;
+    if (this.onChange) {
+      this.onChange(items);
+    }
   }
 
-  updateValue(options: ListItem): void {
-    const value = options && options.value;
+  updateSelection(item: ListItem): void {
     if (this.isMultipleChoice) {
-      this.value = this.utils.updateMultiSelectValue(this.value, value, options.isChecked);
-    } else {
-      if (this.utils.valueHasChanged(this.selectedValue, value)) {
-        this.value = value;
-      }
+      this.subItems.find((option: ListItem): boolean => {
+        return this.utils.isEqual(option.value, item.value);
+      }).isChecked = item.isChecked;
+      const checkedItems = this.subItems.filter((option: ListItem): boolean => option.isChecked);
+      this.selection = checkedItems;
+    } else if (!this.utils.isEqual(this.selection[0], item)) {
+      this.selection = [item];
     }
   }
 
-  writeValue() {
+  writeValue(items: ListItem[]) {
+    this.selection = items;
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
index c294e8e..f9192f4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
@@ -28,7 +28,9 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
 import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {ClustersService, clusters} from '@app/services/storage/clusters.service';
+import {ComponentsService, components} from '@app/services/storage/components.service';
+import {HostsService, hosts} from '@app/services/storage/hosts.service';
 import {UtilsService} from '@app/services/utils.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
@@ -77,7 +79,10 @@ describe('FilterDropdownComponent', () => {
           serviceLogsFields,
           serviceLogsHistogramData,
           serviceLogsTruncated,
-          tabs
+          tabs,
+          clusters,
+          components,
+          hosts
         }),
         ...TranslationModules
       ],
@@ -91,8 +96,11 @@ describe('FilterDropdownComponent', () => {
         ServiceLogsHistogramDataService,
         ServiceLogsTruncatedService,
         TabsService,
+        ClustersService,
+        ComponentsService,
+        HostsService,
         {
-          provide: FilteringService,
+          provide: LogsContainerService,
           useValue: filtering
         },
         UtilsService,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
index 9e5a6f1..d677d81 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
@@ -20,6 +20,7 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 import {UtilsService} from '@app/services/utils.service';
 import {DropdownButtonComponent} from '@app/components/dropdown-button/dropdown-button.component';
+import {ListItem} from '@app/classes/list-item';
 
 @Component({
   selector: 'filter-dropdown',
@@ -41,16 +42,25 @@ export class FilterDropdownComponent extends DropdownButtonComponent implements
 
   private onChange: (fn: any) => void;
 
-  get value(): any {
-    return this.selectedValue;
+  get selection(): ListItem[] {
+    return this.selectedItems;
   }
 
-  set value(newValue: any) {
-    this.selectedValue = newValue;
-    this.onChange(newValue);
+  set selection(items: ListItem[]) {
+    this.selectedItems = items;
+    if (this.isMultipleChoice) {
+      this.options.forEach((option: ListItem): void => {
+        const selectionItem = items.find((item: ListItem): boolean => this.utils.isEqual(item.value, option.value));
+        option.isChecked = Boolean(selectionItem);
+      });
+    }
+    if (this.onChange) {
+      this.onChange(items);
+    }
   }
 
-  writeValue() {
+  writeValue(items: ListItem[]) {
+    this.selection = items;
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
index fa739a4..2d327a6 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
@@ -17,13 +17,13 @@
 
 <form [formGroup]="filtersForm">
   <div class="form-inline filter-input-container col-md-8">
-    <filter-dropdown [label]="filters.clusters.label" formControlName="clusters" [options]="filters.clusters.options"
-                     [defaultLabel]="filters.clusters.defaultLabel" [isMultipleChoice]="true"
+    <filter-dropdown *ngIf="isFilterConditionDisplayed('clusters')" [label]="filters.clusters.label"
+                     formControlName="clusters" [options]="filters.clusters.options" [isMultipleChoice]="true"
                      class="filter-input"></filter-dropdown>
     <search-box formControlName="query" [items]="searchBoxItemsTranslated" class="filter-input"
                 [parameterNameChangeSubject]="queryParameterNameChange"
                 [parameterAddSubject]="queryParameterAdd"></search-box>
-    <time-range-picker formControlName="timeRange" [defaultLabel]="filters.timeRange.defaultLabel"
+    <time-range-picker *ngIf="isFilterConditionDisplayed('timeRange')" formControlName="timeRange"
                        class="filter-input"></time-range-picker>
     <timezone-picker class="filter-input"></timezone-picker>
     <!--button class="btn btn-success" type="button">

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
index 0bb0204..1f7e8db 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
@@ -18,6 +18,7 @@
 
 import {NO_ERRORS_SCHEMA} from '@angular/core';
 import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {FormGroup, FormControl} from '@angular/forms';
 import {TranslationModules} from '@app/test-config.spec';
 import {StoreModule} from '@ngrx/store';
 import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
@@ -32,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
 import {AppStateService, appState} from '@app/services/storage/app-state.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {UtilsService} from '@app/services/utils.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
@@ -88,7 +88,6 @@ describe('FiltersPanelComponent', () => {
         AppStateService,
         ServiceLogsTruncatedService,
         TabsService,
-        FilteringService,
         LogsContainerService,
         {
           provide: HttpClientService,
@@ -104,6 +103,9 @@ describe('FiltersPanelComponent', () => {
   beforeEach(() => {
     fixture = TestBed.createComponent(FiltersPanelComponent);
     component = fixture.componentInstance;
+    component.filtersForm = new FormGroup({
+      control: new FormControl()
+    });
     fixture.detectChanges();
   });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
index 9601a0e..3314252 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
@@ -21,10 +21,8 @@ import {FormGroup} from '@angular/forms';
 import {Subject} from 'rxjs/Subject';
 import {TranslateService} from '@ngx-translate/core';
 import {ListItem} from '@app/classes/list-item';
-import {filtersFormItemsMap} from '@app/classes/filtering';
 import {CommonEntry} from '@app/classes/models/common-entry';
 import {LogField} from '@app/classes/models/log-field';
-import {FilteringService} from '@app/services/filtering.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {AppStateService} from '@app/services/storage/app-state.service';
 
@@ -35,7 +33,10 @@ import {AppStateService} from '@app/services/storage/app-state.service';
 })
 export class FiltersPanelComponent {
 
-  constructor(private translate: TranslateService, private filtering: FilteringService, private logsContainer: LogsContainerService, private appState: AppStateService) {
+  constructor(
+    private translate: TranslateService, private logsContainer: LogsContainerService,
+    private appState: AppStateService
+  ) {
     appState.getParameter('activeLogsType').subscribe(value => {
       this.logsType = value;
       logsContainer.logsTypeMap[value].fieldsModel.getAll().subscribe((fields: LogField[]): void => {
@@ -80,23 +81,24 @@ export class FiltersPanelComponent {
   searchBoxItemsTranslated: CommonEntry[] = [];
 
   get filters(): any {
-    return this.filtering.filters;
+    return this.logsContainer.filters;
   }
 
   get queryParameterNameChange(): Subject<any> {
-    return this.filtering.queryParameterNameChange;
+    return this.logsContainer.queryParameterNameChange;
   }
 
   get queryParameterAdd(): Subject<any> {
-    return this.filtering.queryParameterAdd;
+    return this.logsContainer.queryParameterAdd;
   }
 
   get captureSeconds(): number {
-    return this.filtering.captureSeconds;
+    return this.logsContainer.captureSeconds;
   }
 
   isFilterConditionDisplayed(key: string): boolean {
-    return filtersFormItemsMap[this.logsType].indexOf(key) > -1;
+    return this.logsContainer.filtersFormItemsMap[this.logsType].indexOf(key) > -1
+      && Boolean(this.filtersForm.controls[key]);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
index 4e9bdc9..7bd87ad 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
@@ -34,7 +34,6 @@ import {TranslationModules} from '@app/test-config.spec';
 import {ModalComponent} from '@app/components/modal/modal.component';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 
 import {LogContextComponent} from './log-context.component';
 
@@ -90,8 +89,7 @@ describe('LogContextComponent', () => {
         {
           provide: HttpClientService,
           useValue: httpClient
-        },
-        FilteringService
+        }
       ],
       schemas: [CUSTOM_ELEMENTS_SCHEMA]
     })

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
index 0a9418f..2bb8731 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
@@ -33,7 +33,6 @@ import {HostsService, hosts} from '@app/services/storage/hosts.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {UtilsService} from '@app/services/utils.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {TabsComponent} from '@app/components/tabs/tabs.component';
@@ -92,7 +91,6 @@ describe('LogsContainerComponent', () => {
         HostsService,
         ServiceLogsTruncatedService,
         TabsService,
-        FilteringService,
         UtilsService,
         LogsContainerService
       ],

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
index 21949f1..f8acd50 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
@@ -22,7 +22,6 @@ import {Observable} from 'rxjs/Observable';
 import {Subject} from 'rxjs/Subject';
 import 'rxjs/add/operator/map';
 import 'rxjs/add/operator/takeUntil';
-import {FilteringService} from '@app/services/filtering.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service';
 import {AppStateService} from '@app/services/storage/app-state.service';
@@ -43,9 +42,11 @@ import {ListItem} from '@app/classes/list-item';
 })
 export class LogsContainerComponent {
 
-  constructor(private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private appState: AppStateService, private tabsStorage: TabsService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
+  constructor(
+    private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private appState: AppStateService,
+    private tabsStorage: TabsService, private logsContainer: LogsContainerService
+  ) {
     this.logsContainer.loadColumnsNames();
-    this.logsTypeChange.first().subscribe(() => this.logsContainer.loadLogs());
     appState.getParameter('activeLogsType').subscribe((value: string): void => {
       this.logsType = value;
       this.logsTypeChange.next();
@@ -75,11 +76,6 @@ export class LogsContainerComponent {
         this.displayedColumns = columns.filter((column: LogField): boolean => column.isAvailable && column.isDisplayed);
       });
     });
-    appState.getParameter('activeFiltersForm').subscribe((form: FormGroup): void => {
-      this.filtersFormChange.next();
-      form.valueChanges.takeUntil(this.filtersFormChange).subscribe(() => this.logsContainer.loadLogs());
-      this.filtersForm = form;
-    });
     serviceLogsHistogramStorage.getAll().subscribe((data: BarGraph[]): void => {
       this.histogramData = this.logsContainer.getHistogramData(data);
     });
@@ -88,12 +84,12 @@ export class LogsContainerComponent {
 
   tabs: Observable<Tab[]> = this.tabsStorage.getAll();
 
-  filtersForm: FormGroup;
+  get filtersForm(): FormGroup {
+    return this.logsContainer.filtersForm;
+  };
 
   private logsType: string;
 
-  private filtersFormChange: Subject<any> = new Subject();
-
   private logsTypeChange: Subject<any> = new Subject();
 
   get logsTypeMapObject(): any {
@@ -117,10 +113,10 @@ export class LogsContainerComponent {
   };
 
   get autoRefreshRemainingSeconds(): number {
-    return this.filtering.autoRefreshRemainingSeconds;
+    return this.logsContainer.autoRefreshRemainingSeconds;
   }
 
-  get autoRefreshMessageParams(): any {
+  get autoRefreshMessageParams(): object {
     return {
       remainingSeconds: this.autoRefreshRemainingSeconds
     };
@@ -133,7 +129,7 @@ export class LogsContainerComponent {
   get totalEventsFoundMessageParams(): object {
     return {
       totalCount: this.totalCount
-    }
+    };
   }
 
   isServiceLogContextView: boolean = false;
@@ -147,7 +143,7 @@ export class LogsContainerComponent {
   }
 
   setCustomTimeRange(startTime: number, endTime: number): void {
-    this.filtering.setCustomTimeRange(startTime, endTime);
+    this.logsContainer.setCustomTimeRange(startTime, endTime);
   }
 
   onSwitchTab(activeTab: Tab): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
index 10f4af1..7de0b96 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
@@ -17,8 +17,7 @@
 
 <form *ngIf="logs && logs.length" [formGroup]="filtersForm" class="row pull-right">
   <filter-dropdown [label]="filters.sorting.label" formControlName="sorting" [options]="filters.sorting.options"
-                   [defaultLabel]="filters.sorting.defaultLabel" [isRightAlign]="true"
-                   class="col-md-12"></filter-dropdown>
+                   [isRightAlign]="true" class="col-md-12"></filter-dropdown>
 </form>
 <div class="panel panel-default">
  <div class="panel-body">

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
index 8ee4ca3..21c4f02 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
@@ -28,8 +28,13 @@ import {AppStateService, appState} from '@app/services/storage/app-state.service
 import {ClustersService, clusters} from '@app/services/storage/clusters.service';
 import {ComponentsService, components} from '@app/services/storage/components.service';
 import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.service';
+import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
+import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
+import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
 import {UtilsService} from '@app/services/utils.service';
 
 import {LogsListComponent} from './logs-list.component';
@@ -57,7 +62,12 @@ describe('LogsListComponent', () => {
           appState,
           clusters,
           components,
-          hosts
+          hosts,
+          auditLogsFields,
+          serviceLogsFields,
+          serviceLogsHistogramData,
+          serviceLogsTruncated,
+          tabs
         }),
         MomentModule,
         MomentTimezoneModule,
@@ -75,7 +85,12 @@ describe('LogsListComponent', () => {
         ClustersService,
         ComponentsService,
         HostsService,
-        FilteringService,
+        AuditLogsFieldsService,
+        ServiceLogsFieldsService,
+        ServiceLogsHistogramDataService,
+        ServiceLogsTruncatedService,
+        TabsService,
+        LogsContainerService,
         UtilsService
       ],
       schemas: [NO_ERRORS_SCHEMA]

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
index 017bc82..3a56fca 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
@@ -18,7 +18,7 @@
 import {Component, AfterViewInit, Input, ViewChild, ElementRef} from '@angular/core';
 import {FormGroup} from '@angular/forms';
 import 'rxjs/add/operator/map';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
 import {UtilsService} from '@app/services/utils.service';
 import {AuditLog} from '@app/classes/models/audit-log';
 import {ServiceLog} from '@app/classes/models/service-log';
@@ -31,7 +31,7 @@ import {LogField} from '@app/classes/models/log-field';
 })
 export class LogsListComponent implements AfterViewInit {
 
-  constructor(private filtering: FilteringService, private utils: UtilsService) {
+  constructor(private logsContainer: LogsContainerService, private utils: UtilsService) {
   }
 
   ngAfterViewInit() {
@@ -104,11 +104,11 @@ export class LogsListComponent implements AfterViewInit {
   readonly timeFormat: string = 'h:mm:ss A';
 
   get timeZone(): string {
-    return this.filtering.timeZone;
+    return this.logsContainer.timeZone;
   }
 
   get filters(): any {
-    return this.filtering.filters;
+    return this.logsContainer.filters;
   }
 
   isDifferentDates(dateA, dateB): boolean {
@@ -135,7 +135,7 @@ export class LogsListComponent implements AfterViewInit {
   }
 
   updateQuery(event: any) {
-    this.filtering.queryParameterAdd.next({
+    this.logsContainer.queryParameterAdd.next({
       name: this.messageFilterParameterName,
       value: this.selectedText,
       isExclude: event.value

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
index 261e213..71bbf67 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
@@ -33,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 
@@ -85,7 +84,6 @@ describe('MenuButtonComponent', () => {
         ServiceLogsTruncatedService,
         TabsService,
         ComponentActionsService,
-        FilteringService,
         {
           provide: HttpClientService,
           useValue: httpClient

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
index 5932e1b..ca89935 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
@@ -202,11 +202,11 @@ export class MenuButtonComponent {
    * @param {ListItem} options The selected item(s) from the dropdown list.
    */
   onDropdownItemChange(options: ListItem) {
-    this.updateValue(options);
+    this.updateSelection(options);
     !this.isMultipleChoice && this.closeDropdown();
   }
 
-  updateValue(options: ListItem) {
+  updateSelection(options: ListItem) {
     // TODO implement value change behaviour
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
index 81676a9..5f85da7 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
@@ -54,7 +54,9 @@ export class PaginationControlsComponent implements ControlValueAccessor {
     if (this.isValidValue(newValue)) { // this is the last validation check
       this.currentPage = newValue;
       this.currentPageChange.emit(newValue);
-      this.onChange(newValue);
+      if (this.onChange) {
+        this.onChange(newValue);
+      }
     } else {
       throw new Error(`Invalid value ${newValue}. The currentPage should be between 0 and ${this.pagesCount}.`);
     }
@@ -121,7 +123,8 @@ export class PaginationControlsComponent implements ControlValueAccessor {
     return this.pagesCount > 0 && this.value > 0;
   }
 
-  writeValue() {
+  writeValue(value: number) {
+    this.value = value;
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
index 679a7e5..4be0a47 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
@@ -17,7 +17,7 @@
 
 <form class="pagination-form" [formGroup]="filtersForm">
   <filter-dropdown [label]="filterInstance.label" formControlName="pageSize" [options]="filterInstance.options"
-                   [defaultLabel]="filterInstance.defaultLabel" [isRightAlign]="true" isDropup="true"></filter-dropdown>
+                   [isRightAlign]="true" [isDropup]="true"></filter-dropdown>
   <span>{{'pagination.numbers' | translate: numbersTranslateParams}}</span>
   <pagination-controls formControlName="page" [totalCount]="totalCount" [pagesCount]="pagesCount"
                        (currentPageChange)="setCurrentPage($event)"></pagination-controls>

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
index ff8675d..c820027 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
@@ -39,7 +39,14 @@ describe('PaginationComponent', () => {
   beforeEach(() => {
     fixture = TestBed.createComponent(PaginationComponent);
     component = fixture.componentInstance;
-    component.filterInstance = {};
+    component.filterInstance = {
+      defaultSelection: [
+        {
+          label: '10',
+          value: '10'
+        }
+      ]
+    };
     component.filtersForm = new FormGroup({
       pageSize: new FormControl()
     });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
index cc5589f..890c2ee 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
@@ -18,6 +18,8 @@
 
 import {Component, OnInit, Input} from '@angular/core';
 import {FormGroup} from '@angular/forms';
+import {ListItem} from '@app/classes/list-item';
+import {FilterCondition} from '@app/classes/filtering';
 
 @Component({
   selector: 'pagination',
@@ -27,9 +29,9 @@ import {FormGroup} from '@angular/forms';
 export class PaginationComponent implements OnInit {
 
   ngOnInit() {
-    this.setPageSizeFromString(this.filterInstance.defaultValue);
-    this.filtersForm.controls.pageSize.valueChanges.subscribe((value: string): void => {
-      this.setPageSizeFromString(value);
+    this.setPageSizeFromString(this.filterInstance.defaultSelection[0].value);
+    this.filtersForm.controls.pageSize.valueChanges.subscribe((selection: ListItem): void => {
+      this.setPageSizeFromString(selection[0].value);
     });
   }
 
@@ -37,7 +39,7 @@ export class PaginationComponent implements OnInit {
   filtersForm: FormGroup;
 
   @Input()
-  filterInstance: any;
+  filterInstance: FilterCondition;
 
   @Input()
   currentCount?: number;

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
index 5520310..18ff715 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
@@ -159,7 +159,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
     this.isValueInput = true;
     this.currentValue = '';
     setTimeout(() => this.valueInput.focus(), 0);
-  }
+  };
 
   onParameterValueChange(event: KeyboardEvent): void {
     if (this.utils.isEnterPressed(event) && this.currentValue) {
@@ -187,7 +187,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
       isExclude: options.isExclude
     });
     this.updateValue();
-  }
+  };
 
   removeParameter(event: MouseEvent, id: number): void {
     this.parameters = this.parameters.filter(parameter => parameter.id !== id);
@@ -196,10 +196,14 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
   }
 
   updateValue() {
-    this.onChange(this.parameters);
+    if (this.onChange) {
+      this.onChange(this.parameters);
+    }
   }
 
-  writeValue() {
+  writeValue(parameters: any [] = []) {
+    this.parameters = parameters;
+    this.updateValue();
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
index 973db61..621f995 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
@@ -16,7 +16,8 @@
 -->
 
 <button class="btn btn-link dropdown-toggle" data-toggle="dropdown">
-  {{selectedLabel | translate}} <span class="caret"></span>
+  <span *ngIf="selection">{{selection.label | translate}}</span>
+  <span class="caret"></span>
 </button>
 <div class="dropdown-menu row col-md-12">
   <div class="col-md-4" (click)="$event.stopPropagation()">

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
index 7612cc3..43e4bd5 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
@@ -25,8 +25,15 @@ import {AppStateService, appState} from '@app/services/storage/app-state.service
 import {ClustersService, clusters} from '@app/services/storage/clusters.service';
 import {ComponentsService, components} from '@app/services/storage/components.service';
 import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {AuditLogsService, auditLogs} from '@app/services/storage/audit-logs.service';
+import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.service';
+import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-logs.service';
+import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
+import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
+import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
 
 import {TimeRangePickerComponent} from './time-range-picker.component';
 
@@ -51,7 +58,14 @@ describe('TimeRangePickerComponent', () => {
           appState,
           clusters,
           components,
-          hosts
+          hosts,
+          auditLogs,
+          auditLogsFields,
+          serviceLogs,
+          serviceLogsFields,
+          serviceLogsHistogramData,
+          serviceLogsTruncated,
+          tabs
         }),
         ...TranslationModules
       ],
@@ -60,12 +74,19 @@ describe('TimeRangePickerComponent', () => {
           provide: HttpClientService,
           useValue: httpClient
         },
-        FilteringService,
+        LogsContainerService,
         AppSettingsService,
         AppStateService,
         ClustersService,
         ComponentsService,
-        HostsService
+        HostsService,
+        AuditLogsService,
+        AuditLogsFieldsService,
+        ServiceLogsService,
+        ServiceLogsFieldsService,
+        ServiceLogsHistogramDataService,
+        ServiceLogsTruncatedService,
+        TabsService
       ],
       schemas: [CUSTOM_ELEMENTS_SCHEMA]
     })

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
index af4933a..cacabc3 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
@@ -16,10 +16,10 @@
  * limitations under the License.
  */
 
-import {Component, OnInit, Input, forwardRef} from '@angular/core';
+import {Component, forwardRef} from '@angular/core';
 import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
 import {Moment} from 'moment';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
 import {ListItem} from '@app/classes/list-item';
 import {TimeUnitListItem} from '@app/classes/filtering';
 
@@ -35,20 +35,11 @@ import {TimeUnitListItem} from '@app/classes/filtering';
     }
   ]
 })
-export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
+export class TimeRangePickerComponent implements ControlValueAccessor {
 
-  constructor(private filtering: FilteringService) {
+  constructor(private logsContainer: LogsContainerService) {
   }
 
-  ngOnInit() {
-    this.selectedLabel = this.defaultLabel;
-  }
-
-  @Input()
-  defaultLabel?: string;
-
-  selectedLabel: string;
-
   startTime: Moment;
 
   endTime: Moment;
@@ -56,18 +47,20 @@ export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
   private onChange: (fn: any) => void;
 
   get quickRanges(): (ListItem | TimeUnitListItem[])[] {
-    return this.filtering.filters.timeRange.options;
+    return this.logsContainer.filters.timeRange.options;
   }
 
-  private timeRange?: any;
+  private timeRange?: TimeUnitListItem;
 
-  get value(): any {
+  get selection(): TimeUnitListItem {
     return this.timeRange;
   }
 
-  set value(newValue: any) {
+  set selection(newValue: TimeUnitListItem) {
     this.timeRange = newValue;
-    this.onChange(newValue);
+    if (this.onChange) {
+      this.onChange(newValue);
+    }
   }
 
   setStartTime(timeObject: Moment): void {
@@ -79,20 +72,22 @@ export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
   }
 
   setTimeRange(value: any, label: string) {
-    this.value = value;
-    this.selectedLabel = label;
+    this.selection = {label, value};
   }
 
   setCustomTimeRange() {
-    this.value = {
-      type: 'CUSTOM',
-      start: this.startTime,
-      end: this.endTime
+    this.selection = {
+      label: 'filter.timeRange.custom',
+      value: {
+        type: 'CUSTOM',
+        start: this.startTime,
+        end: this.endTime
+      }
     };
-    this.selectedLabel = 'filter.timeRange.custom';
   }
 
-  writeValue() {
+  writeValue(selection: TimeUnitListItem) {
+    this.selection = selection;
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
index 53afc47..0e4c8a8 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {TimeZoneAbbrPipe} from '@app/pipes/timezone-abbr.pipe';
@@ -90,7 +89,6 @@ describe('TimeZonePickerComponent', () => {
         ServiceLogsTruncatedService,
         TabsService,
         ComponentActionsService,
-        FilteringService,
         {
           provide: HttpClientService,
           useValue: httpClient

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
index e6a02c0..6f54e65 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
@@ -30,7 +30,6 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
 import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 
@@ -78,7 +77,6 @@ describe('ComponentActionsService', () => {
         ServiceLogsHistogramDataService,
         ServiceLogsTruncatedService,
         TabsService,
-        FilteringService,
         {
           provide: HttpClientService,
           useValue: httpClient

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
index c483cd8..73fc94c 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
@@ -20,15 +20,17 @@ import {Injectable} from '@angular/core';
 import {AppSettingsService} from '@app/services/storage/app-settings.service';
 import {TabsService} from '@app/services/storage/tabs.service';
 import {CollectionModelService} from '@app/classes/models/store';
-import {FilteringService} from '@app/services/filtering.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {ServiceLog} from '@app/classes/models/service-log';
-import {getFiltersForm} from '@app/classes/filtering';
+import {ListItem} from '@app/classes/list-item';
 
 @Injectable()
 export class ComponentActionsService {
 
-  constructor(private appSettings: AppSettingsService, private tabsStorage: TabsService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
+  constructor(
+    private appSettings: AppSettingsService, private tabsStorage: TabsService,
+    private logsContainer: LogsContainerService
+  ) {
   }
 
   //TODO implement actions
@@ -81,7 +83,6 @@ export class ComponentActionsService {
     const tab = {
       id: log.id,
       type: 'serviceLogs',
-      isActive: true,
       isCloseable: true,
       label: `${log.host} >> ${log.type}`,
       appState: {
@@ -92,7 +93,14 @@ export class ComponentActionsService {
           host_name: log.host,
           component_name: log.type
         },
-        activeFiltersForm: getFiltersForm('serviceLogs')
+        activeFilters: Object.assign(this.logsContainer.getFiltersData('serviceLogs'), {
+          components: this.logsContainer.filters.components.options.find((option: ListItem): boolean => {
+            return option.value === log.type;
+          }),
+          hosts: this.logsContainer.filters.hosts.options.find((option: ListItem): boolean => {
+            return option.value === log.host;
+          })
+        })
       }
     };
     this.tabsStorage.addInstance(tab);
@@ -104,11 +112,11 @@ export class ComponentActionsService {
   }
 
   startCapture(): void {
-    this.filtering.startCaptureTimer();
+    this.logsContainer.startCaptureTimer();
   }
 
   stopCapture(): void {
-    this.filtering.stopCaptureTimer();
+    this.logsContainer.stopCaptureTimer();
   }
 
   setTimeZone(timeZone: string): void {
@@ -121,7 +129,7 @@ export class ComponentActionsService {
     }));
   }
 
-  proceedWithExclude = (item: string): void => this.filtering.queryParameterNameChange.next({
+  proceedWithExclude = (item: string): void => this.logsContainer.queryParameterNameChange.next({
     item: item,
     isExclude: true
   });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
index 5dc38b4..a161190 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/s
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 
 import {ComponentGeneratorService} from './component-generator.service';
 
@@ -70,7 +69,6 @@ describe('ComponentGeneratorService', () => {
           provide: HttpClientService,
           useValue: httpClient
         },
-        FilteringService,
         HostsService,
         AuditLogsService,
         ServiceLogsService,