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/09/07 16:13:45 UTC
ambari git commit: AMBARI-21905 Log Search UI: implement combo search
filter. (ababiichuk)
Repository: ambari
Updated Branches:
refs/heads/trunk ab06654a4 -> a10e3887c
AMBARI-21905 Log Search UI: implement combo search filter. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a10e3887
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a10e3887
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a10e3887
Branch: refs/heads/trunk
Commit: a10e3887c714e6bdeb83c21b2d8ecfbba438639e
Parents: ab06654
Author: ababiichuk <ab...@hortonworks.com>
Authored: Thu Sep 7 18:13:39 2017 +0300
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Thu Sep 7 18:13:39 2017 +0300
----------------------------------------------------------------------
.../ambari-logsearch-web/package.json | 1 +
.../ambari-logsearch-web/src/app/app.module.ts | 10 +-
...service-logs-histogram-query-params.class.ts | 2 +
.../dropdown-list/dropdown-list.component.less | 2 +-
.../filter-text-field.component.html | 21 ---
.../filter-text-field.component.less | 33 ----
.../filter-text-field.component.spec.ts | 82 ---------
.../filter-text-field.component.ts | 87 ---------
.../filters-panel/filters-panel.component.html | 10 +-
.../filters-panel/filters-panel.component.less | 16 +-
.../filters-panel.component.spec.ts | 22 ++-
.../filters-panel/filters-panel.component.ts | 37 +++-
.../search-box/search-box.component.html | 31 ++++
.../search-box/search-box.component.less | 118 +++++++++++++
.../search-box/search-box.component.spec.ts | 63 +++++++
.../search-box/search-box.component.ts | 176 +++++++++++++++++++
.../src/app/components/variables.less | 24 ++-
.../src/app/models/app-state.model.ts | 4 +-
.../src/app/services/filtering.service.ts | 35 +++-
.../src/app/services/logs-container.service.ts | 6 +-
.../src/app/services/utils.service.ts | 4 +
ambari-logsearch/ambari-logsearch-web/yarn.lock | 4 +
22 files changed, 533 insertions(+), 255 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/package.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/package.json b/ambari-logsearch/ambari-logsearch-web/package.json
index 96733eb..92c5043 100644
--- a/ambari-logsearch/ambari-logsearch-web/package.json
+++ b/ambari-logsearch/ambari-logsearch-web/package.json
@@ -33,6 +33,7 @@
"jquery": "^1.12.4",
"moment": "^2.18.1",
"moment-timezone": "^0.5.13",
+ "ng2-auto-complete": "^0.12.0",
"ngx-bootstrap": "^1.6.6",
"rxjs": "^5.1.0",
"zone.js": "^0.8.4"
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/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 c08cb3a..c15ecbc 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -27,7 +27,10 @@ import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import {StoreModule} from '@ngrx/store';
import {MomentModule} from 'angular2-moment';
import {MomentTimezoneModule} from 'angular-moment-timezone';
+import {Ng2AutoCompleteModule} from 'ng2-auto-complete';
+
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';
@@ -59,7 +62,6 @@ import {MainContainerComponent} from '@app/components/main-container/main-contai
import {FiltersPanelComponent} from '@app/components/filters-panel/filters-panel.component';
import {FilterDropdownComponent} from '@app/components/filter-dropdown/filter-dropdown.component';
import {DropdownListComponent} from '@app/components/dropdown-list/dropdown-list.component';
-import {FilterTextFieldComponent} from '@app/components/filter-text-field/filter-text-field.component';
import {FilterButtonComponent} from '@app/components/filter-button/filter-button.component';
import {AccordionPanelComponent} from '@app/components/accordion-panel/accordion-panel.component';
import {LogsListComponent} from '@app/components/logs-list/logs-list.component';
@@ -71,6 +73,7 @@ import {LogsContainerComponent} from '@app/components/logs-container/logs-contai
import {ModalComponent} from '@app/components/modal/modal.component';
import {TimeZonePickerComponent} from '@app/components/timezone-picker/timezone-picker.component';
import {NodeBarComponent} from '@app/components/node-bar/node-bar.component';
+import {SearchBoxComponent} from '@app/components/search-box/search-box.component';
import {TimeZoneAbbrPipe} from '@app/pipes/timezone-abbr.pipe';
@@ -104,7 +107,6 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
FiltersPanelComponent,
DropdownListComponent,
FilterDropdownComponent,
- FilterTextFieldComponent,
FilterButtonComponent,
AccordionPanelComponent,
LogsListComponent,
@@ -116,6 +118,7 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
ModalComponent,
TimeZonePickerComponent,
NodeBarComponent,
+ SearchBoxComponent,
TimeZoneAbbrPipe
],
imports: [
@@ -133,7 +136,8 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
}),
StoreModule.provideStore(reducer),
MomentModule,
- MomentTimezoneModule
+ MomentTimezoneModule,
+ Ng2AutoCompleteModule
],
providers: [
HttpClientService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-histogram-query-params.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-histogram-query-params.class.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-histogram-query-params.class.ts
index 87e82f6..572af03 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-histogram-query-params.class.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-histogram-query-params.class.ts
@@ -66,4 +66,6 @@ export class ServiceLogsHistogramQueryParams extends QueryParams {
clusters?: string;
iMessage?: string;
level?: string;
+ includeQuery?: string;
+ excludeQuery?: string;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.less
index d47160f..6faa192 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.less
@@ -19,7 +19,7 @@
@import '../variables';
:host {
- max-height: 500px; // TODO get rid of magic number, base on actual design
+ max-height: @dropdown-max-height;
overflow-y: auto;
.list-item-label {
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.html
deleted file mode 100644
index 3f00e8b..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.html
+++ /dev/null
@@ -1,21 +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.
--->
-
-<div class="input-group">
- <span class="input-group-addon">{{label | translate}}</span>
- <input type="text" class="form-control" [(ngModel)]="instantValue" (ngModelChange)="updateInstantValue($event)">
-</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.less
deleted file mode 100644
index 1395959..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.less
+++ /dev/null
@@ -1,33 +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 '../variables';
-
-.input-group {
- border: @input-border;
- border-right-width: 0;
-}
-
-.input-group-addon {
- border: none;
- background-color: transparent;
- text-transform: uppercase;
-
- & + input {
- border: none;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.spec.ts
deleted file mode 100644
index 71039ed..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.spec.ts
+++ /dev/null
@@ -1,82 +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 {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
-import {async, ComponentFixture, TestBed} from '@angular/core/testing';
-import {Http} from '@angular/http';
-import {FormsModule} from '@angular/forms';
-import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
-import {TranslateHttpLoader} from '@ngx-translate/http-loader';
-import {StoreModule} from '@ngrx/store';
-import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
-import {FilteringService} from '@app/services/filtering.service';
-import {UtilsService} from '@app/services/utils.service';
-import {ComponentActionsService} from '@app/services/component-actions.service';
-
-import {FilterTextFieldComponent} from './filter-text-field.component';
-
-export function HttpLoaderFactory(http: Http) {
- return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
-}
-
-describe('FilterTextFieldComponent', () => {
- let component: FilterTextFieldComponent;
- let fixture: ComponentFixture<FilterTextFieldComponent>;
- const filtering = {
- filters: {
- f: {}
- }
- };
-
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- declarations: [FilterTextFieldComponent],
- imports: [
- FormsModule,
- TranslateModule.forRoot({
- provide: TranslateLoader,
- useFactory: HttpLoaderFactory,
- deps: [Http]
- }),
- StoreModule.provideStore({
- appSettings
- })
- ],
- providers: [
- AppSettingsService,
- {
- provide: FilteringService,
- useValue: filtering
- },
- UtilsService,
- ComponentActionsService
- ],
- schemas: [CUSTOM_ELEMENTS_SCHEMA]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(FilterTextFieldComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create component', () => {
- expect(component).toBeTruthy();
- });
-});
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.ts
deleted file mode 100644
index 2b6bfea..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.ts
+++ /dev/null
@@ -1,87 +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 {Component, Input, forwardRef} from '@angular/core';
-import {ControlValueAccessor, NG_VALUE_ACCESSOR, FormGroup} from '@angular/forms';
-import {Subject} from 'rxjs/Subject';
-import 'rxjs/add/operator/debounceTime';
-import {UtilsService} from '@app/services/utils.service';
-
-@Component({
- selector: 'filter-text-field',
- templateUrl: './filter-text-field.component.html',
- styleUrls: ['./filter-text-field.component.less'],
- providers: [
- {
- provide: NG_VALUE_ACCESSOR,
- useExisting: forwardRef(() => FilterTextFieldComponent),
- multi: true
- }
- ]
-})
-export class FilterTextFieldComponent implements ControlValueAccessor {
-
- constructor(private utils: UtilsService) {
- this.valueSubject.debounceTime(this.debounceInterval).subscribe(value => this.updateValue({
- value
- }));
- }
-
- @Input()
- label: string;
-
- private selectedValue: string;
-
- private onChange: (fn: any) => void;
-
- private readonly debounceInterval = 1500;
-
- instantValue: string;
-
- private valueSubject = new Subject<string>();
-
- get value(): any {
- return this.selectedValue;
- }
-
- set value(newValue: any) {
- this.selectedValue = newValue;
- this.onChange(newValue);
- }
-
- updateValue(options: any) {
- const value = options && options.value;
- if (this.utils.valueHasChanged(this.selectedValue, value)) {
- this.value = value;
- }
- }
-
- writeValue() {
- }
-
- registerOnChange(callback: any): void {
- this.onChange = callback;
- }
-
- registerOnTouched() {
- }
-
- updateInstantValue(value: string): void {
- this.valueSubject.next(value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/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 6df6988..5820b82 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
@@ -18,12 +18,12 @@
<form class="col-md-12" [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>
- <filter-text-field [label]="filters.text.label"
- formControlName="text"></filter-text-field>
+ [defaultLabel]="filters.clusters.defaultLabel" [isMultipleChoice]="true"
+ class="filter-input"></filter-dropdown>
+ <search-box formControlName="query" [items]="searchBoxItems" class="filter-input"></search-box>
<filter-dropdown formControlName="timeRange" [options]="filters.timeRange.options"
- [defaultLabel]="filters.timeRange.defaultLabel"></filter-dropdown>
- <timezone-picker></timezone-picker>
+ [defaultLabel]="filters.timeRange.defaultLabel" class="filter-input"></filter-dropdown>
+ <timezone-picker class="filter-input"></timezone-picker>
<!--button class="btn btn-success" type="button">
<span class="fa fa-search"></span>
</button-->
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.less
index 9ab09ef..6b2408d 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.less
@@ -24,7 +24,8 @@
background-color: @filters-panel-background-color;
.filter-input-container {
- .flex-vertical-align;
+ display: flex;
+ align-items: flex-start;
justify-content: flex-start;
.btn-success {
@@ -32,7 +33,7 @@
border-bottom-left-radius: 0;
}
- filter-dropdown, dropdown-button, timezone-picker {
+ .filter-input {
border: @input-border;
&:not(:last-child) {
@@ -40,12 +41,19 @@
}
&:first-child {
- border-radius: @button-border-radius 0 0 @button-border-radius;
+ border-top-left-radius: @button-border-radius;
+ border-bottom-left-radius: @button-border-radius;
}
&:last-child {
- border-radius: 0 @button-border-radius @button-border-radius 0;
+ border-top-right-radius: @button-border-radius;
+ border-bottom-right-radius: @button-border-radius;
}
}
+
+ search-box.filter-input:not(:last-child) {
+ border-right-width: @input-border-width;
+ margin-right: -1 * (@input-border-width);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/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 b1cf990..2ced41e 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
@@ -26,9 +26,16 @@ import {AppSettingsService, appSettings} from '@app/services/storage/app-setting
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 {ServiceLogsService, serviceLogs} from '@app/services/storage/service-logs.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 {AppStateService, appState} from '@app/services/storage/app-state.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';
import {FiltersPanelComponent} from './filters-panel.component';
@@ -56,7 +63,13 @@ describe('FiltersPanelComponent', () => {
appSettings,
clusters,
components,
- hosts
+ hosts,
+ auditLogs,
+ serviceLogs,
+ auditLogsFields,
+ serviceLogsFields,
+ serviceLogsHistogramData,
+ appState
}),
TranslateModule.forRoot({
provide: TranslateLoader,
@@ -69,7 +82,14 @@ describe('FiltersPanelComponent', () => {
ClustersService,
ComponentsService,
HostsService,
+ AuditLogsService,
+ ServiceLogsService,
+ AuditLogsFieldsService,
+ ServiceLogsFieldsService,
+ ServiceLogsHistogramDataService,
+ AppStateService,
FilteringService,
+ LogsContainerService,
{
provide: HttpClientService,
useValue: httpClient
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/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 e407021..644048f 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
@@ -18,7 +18,10 @@
import {Component} from '@angular/core';
import {FormGroup} from '@angular/forms';
+import {TranslateService} from '@ngx-translate/core';
import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
+import {AppStateService} from '@app/services/storage/app-state.service';
@Component({
selector: 'filters-panel',
@@ -27,12 +30,38 @@ import {FilteringService} from '@app/services/filtering.service';
})
export class FiltersPanelComponent {
- constructor(private filtering: FilteringService) {
- this.filtering.loadClusters();
- this.filtering.loadComponents();
- this.filtering.loadHosts();
+ constructor(private translate: TranslateService, private filtering: FilteringService, private logsContainer: LogsContainerService, private appState: AppStateService) {
+ appState.getParameter('activeLogsType').subscribe(value => {
+ this.logsType = value;
+ logsContainer.logsTypeMap[value].fieldsModel.getAll().subscribe(fields => {
+ if (fields.length) {
+ const items = fields.filter(field => this.excludedParameters.indexOf(field.name) === -1).map(field => {
+ return {
+ name: field.displayName || field.name,
+ value: field.name
+ };
+ }),
+ labelKeys = items.map(item => item.name);
+ translate.get(labelKeys).first().subscribe(translation => this.searchBoxItems = items.map(item => {
+ return {
+ name: translation[item.name],
+ value: item.value
+ };
+ }));
+ }
+ })
+ });
+ filtering.loadClusters();
+ filtering.loadComponents();
+ filtering.loadHosts();
}
+ private readonly excludedParameters = ['cluster', 'host', 'level', 'type', 'logtime'];
+
+ private logsType: string; // TODO implement setting the parameter depending on user's navigation
+
+ searchBoxItems: any[] = [];
+
get filters(): any {
return this.filtering.filters;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.html
new file mode 100644
index 0000000..64e15dc
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.html
@@ -0,0 +1,31 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<label class="parameter-label" *ngFor="let parameter of parameters">
+ {{parameter.label | translate}}:
+ <span class="parameter-value">{{parameter.value}}</span>
+ <span class="remove-parameter" (click)="removeParameter($event, parameter.id)">×</span>
+</label>
+<span class="active-parameter-label" *ngIf="isActive && activeItem">{{activeItem.name | translate}}:</span>
+<div [ngClass]="{'search-item-container': true, 'active': isActive, 'value': isValueInput}">
+ <input #parameterInput auto-complete [(ngModel)]="currentValue" [source]="items" [list-formatter]="itemsListFormatter"
+ display-property-name="name" (valueChanged)="onParameterNameChange($event)"
+ class="search-item-input parameter-input form-control">
+ <input #valueInput type="text" [(ngModel)]="currentValue" class="search-item-input value-input form-control"
+ (keyup)="onParameterValueChange($event)">
+ <div class="search-item-text" [innerHTML]="currentValue"></div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.less
new file mode 100644
index 0000000..cccf5d5
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.less
@@ -0,0 +1,118 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import '../variables';
+
+@inactive-input-width: 1px;
+@label-margin: 2px;
+.collapsed-form-control {
+ width: 0;
+ padding: 0;
+}
+
+:host {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ align-items: center;
+ width: 100%;
+ border: @input-border;
+ cursor: text;
+
+ .parameter-label {
+ // TODO implement actual styles
+ margin: @label-margin;
+ padding: @label-margin;
+ background-color: @main-background-color;
+ font-size: 0.8em;
+
+ .parameter-value {
+ font-weight: normal;
+ }
+
+ .remove-parameter {
+ cursor: pointer;
+ }
+ }
+
+ .active-parameter-label {
+ font-weight: bold;
+ margin: 0 @label-margin;
+ }
+
+ .search-item-container {
+ position: relative;
+ min-width: @inactive-input-width;
+ height: @input-height;
+
+ .search-item-input {
+ border: none;
+ box-shadow: none;
+ }
+
+ .parameter-input {
+ width: @inactive-input-width;
+ }
+
+ .value-input {
+ .collapsed-form-control;
+ }
+
+ .search-item-text {
+ visibility: hidden;
+ padding: 0 @input-padding;
+ }
+
+ &.active {
+ min-width: @dropdown-min-width;
+
+ .parameter-input {
+ width: 100%;
+ }
+
+ .value-input {
+ .collapsed-form-control;
+ }
+
+ &.value {
+ /deep/ .ng2-auto-complete-wrapper, .parameter-input {
+ display: none;
+ }
+
+ .value-input {
+ width: 100%;
+ }
+ }
+ }
+
+ /deep/ .ng2-auto-complete {
+ cursor: pointer;
+ .dropdown-list-default;
+
+ > ul {
+ border: none;
+
+ li {
+ border: none;
+ background-color: initial;
+ .dropdown-item-default;
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.spec.ts
new file mode 100644
index 0000000..2b3a957
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.spec.ts
@@ -0,0 +1,63 @@
+/**
+ * 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 {NO_ERRORS_SCHEMA} from '@angular/core';
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {Http} from '@angular/http';
+import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
+import {TranslateHttpLoader} from '@ngx-translate/http-loader';
+import {UtilsService} from '@app/services/utils.service';
+
+import {SearchBoxComponent} from './search-box.component';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
+}
+
+describe('SearchBoxComponent', () => {
+ let component: SearchBoxComponent;
+ let fixture: ComponentFixture<SearchBoxComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [SearchBoxComponent],
+ imports: [
+ TranslateModule.forRoot({
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ })
+ ],
+ providers: [
+ UtilsService
+ ],
+ schemas: [NO_ERRORS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SearchBoxComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/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
new file mode 100644
index 0000000..82c455e
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
@@ -0,0 +1,176 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Component, OnInit, OnDestroy, Input, ViewChild, ElementRef, forwardRef} from '@angular/core';
+import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
+import {UtilsService} from '@app/services/utils.service';
+
+@Component({
+ selector: 'search-box',
+ templateUrl: './search-box.component.html',
+ styleUrls: ['./search-box.component.less'],
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => SearchBoxComponent),
+ multi: true
+ }
+ ]
+})
+export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccessor {
+
+ constructor(private element: ElementRef, private utils: UtilsService) {
+ this.rootElement = element.nativeElement;
+ this.rootElement.addEventListener('click', this.onRootClick);
+ this.rootElement.addEventListener('keydown', this.onRootKeyDown);
+ }
+
+ ngOnInit() {
+ this.parameterInput = this.parameterInputRef.nativeElement;
+ this.valueInput = this.valueInputRef.nativeElement;
+ this.parameterInput.addEventListener('focus', this.onParameterInputFocus);
+ this.parameterInput.addEventListener('blur', this.onParameterInputBlur);
+ this.valueInput.addEventListener('blur', this.onValueInputBlur);
+ }
+
+ ngOnDestroy() {
+ this.rootElement.removeEventListener('click', this.onRootClick);
+ this.rootElement.removeEventListener('keydown', this.onRootKeyDown);
+ this.parameterInput.removeEventListener('focus', this.onParameterInputFocus);
+ this.parameterInput.removeEventListener('blur', this.onParameterInputBlur);
+ this.valueInput.removeEventListener('blur', this.onValueInputBlur);
+ }
+
+ private currentId: number = 0;
+
+ isActive: boolean = false;
+
+ isParameterInput: boolean = false;
+
+ isValueInput: boolean = false;
+
+ currentValue: string;
+
+ @Input()
+ items: any[] = [];
+
+ @ViewChild('parameterInput')
+ parameterInputRef: ElementRef;
+
+ @ViewChild('valueInput')
+ valueInputRef: ElementRef;
+
+ rootElement: HTMLElement;
+
+ parameterInput: HTMLElement;
+
+ valueInput: HTMLElement;
+
+ activeItem?: any;
+
+ parameters: any[] = [];
+
+ private onChange: (fn: any) => void;
+
+ private onRootClick = (): void => {
+ if (!this.isActive) {
+ this.parameterInput.focus();
+ }
+ };
+
+ private onRootKeyDown = (event: KeyboardEvent): void => {
+ if (this.utils.isEnterPressed(event)) {
+ event.preventDefault();
+ }
+ };
+
+ private onParameterInputFocus = (): void => {
+ this.isActive = true;
+ this.isValueInput = false;
+ this.isParameterInput = true;
+ };
+
+ private onParameterInputBlur = (): void => {
+ if (!this.isValueInput) {
+ this.clear();
+ }
+ };
+
+ private onValueInputBlur = (): void => {
+ if (!this.isParameterInput) {
+ this.clear();
+ }
+ };
+
+ clear(): void {
+ this.isActive = false;
+ this.activeItem = null;
+ this.currentValue = null;
+ }
+
+ itemsListFormatter(item: any): string {
+ return item.name;
+ }
+
+ onParameterNameChange(item: any): void {
+ if (item) {
+ this.isParameterInput = false;
+ this.isValueInput = true;
+ this.activeItem = item;
+ this.currentValue = '';
+ setTimeout(() => this.valueInput.focus(), 0);
+ }
+ }
+
+ onParameterValueChange(event: KeyboardEvent): void {
+ if (this.utils.isEnterPressed(event) && this.currentValue) {
+ this.parameters.push({
+ id: this.currentId++,
+ name: this.activeItem.value,
+ label: this.activeItem.name,
+ value: this.currentValue,
+ isExclude: false
+ });
+ this.currentValue = '';
+ this.activeItem = null;
+ this.isValueInput = false;
+ this.updateValue();
+ }
+ }
+
+ removeParameter(event: MouseEvent, id: number): void {
+ this.parameters = this.parameters.filter(parameter => parameter.id !== id);
+ this.updateValue();
+ event.stopPropagation();
+ }
+
+ updateValue() {
+ this.onChange(this.parameters);
+ }
+
+ writeValue() {
+ }
+
+ registerOnChange(callback: any): void {
+ this.onChange = callback;
+ }
+
+ registerOnTouched() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
index f72183c..3f59a0d 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
@@ -20,7 +20,8 @@
@navbar-background-color: #323544;
@h1-vertical-margin: 20px;
@button-border-radius: 4px;
-@input-border: 1px solid #CFD3D7;
+@input-border-width: 1px;
+@input-border: @input-border-width solid #CFD3D7;
@button-border-radius: 4px;
@input-group-addon-padding: 6px 0 6px 12px;
@block-margin-top: 20px;
@@ -33,6 +34,10 @@
@filters-panel-padding: 10px 0;
@list-header-background-color: #F2F2F2;
@checkbox-top: 4px;
+@dropdown-min-width: 200px;
+@dropdown-max-height: 500px; // TODO get rid of magic number, base on actual design
+@input-height: 34px;
+@input-padding: 10px;
@fatal-color: #830A0A;
@error-color: #E81D1D;
@@ -100,6 +105,21 @@
left: 0;
}
+.dropdown-list-default {
+ line-height: 1;
+ border-radius: 2px;
+ font-size: 14px;
+ min-width: @dropdown-min-width;
+ background: #FFF;
+ color: #666;
+ border: 1px solid #CFD3D7;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ text-align: left;
+ list-style: none;
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+
.dropdown-item-default {
display: block;
padding: 3px 20px;
@@ -113,6 +133,6 @@
&:hover {
color: #262626;
text-decoration: none;
- background-color: #f5f5f5;
+ background-color: #F5F5F5;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts b/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts
index 2995002..28ae763 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts
@@ -22,6 +22,7 @@ export interface AppState {
isLoginInProgress: boolean;
isAuditLogsSet: boolean;
isServiceLogsSet: boolean;
+ activeLogsType?: string;
}
export const initialState: AppState = {
@@ -29,5 +30,6 @@ export const initialState: AppState = {
isInitialLoading: false,
isLoginInProgress: false,
isAuditLogsSet: false,
- isServiceLogsSet: false
+ isServiceLogsSet: false,
+ activeLogsType: 'serviceLogs' // TODO implement setting the parameter depending on user's navigation
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/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
index 5b9e90d..38c063e 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
@@ -254,7 +254,8 @@ export class FilteringService {
},
page: {
defaultValue: 0
- }
+ },
+ query: {}
};
private filtersFormItems = Object.keys(this.filters).reduce((currentObject, key) => {
@@ -298,7 +299,7 @@ export class FilteringService {
});
}
- private getStartTime(value: any, current: string): string {
+ private getStartTime = (value: any, current: string): string => {
let time;
if (value) {
const endTime = moment(moment(current).valueOf());
@@ -317,9 +318,9 @@ export class FilteringService {
}
}
return time ? time.toISOString() : '';
- }
+ };
- private getEndTime(value: any): string {
+ private getEndTime = (value: any): string => {
let time;
if (value) {
switch (value.type) {
@@ -337,16 +338,32 @@ export class FilteringService {
}
}
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 = {
- end_time: this.getEndTime.bind(this),
- start_time: this.getStartTime.bind(this),
- to: this.getEndTime.bind(this),
- from: this.getStartTime.bind(this),
+ end_time: this.getEndTime,
+ start_time: this.getStartTime,
+ to: this.getEndTime,
+ from: this.getStartTime,
sortType: value => value && value.type,
sortBy: value => value && value.key,
- page: value => value == null ? value : value.toString()
+ 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/a10e3887/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 702deab..a90d099 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
@@ -50,7 +50,8 @@ export class LogsContainerService {
hosts: ['host_name'],
sorting: ['sortType', 'sortBy'],
pageSize: ['pageSize'],
- page: ['page']
+ page: ['page'],
+ query: ['includeQuery', 'excludeQuery']
};
private readonly histogramFilters = {
@@ -58,7 +59,8 @@ export class LogsContainerService {
text: ['iMessage'],
timeRange: ['to', 'from'],
components: ['mustBe'],
- levels: ['level']
+ levels: ['level'],
+ query: ['includeQuery', 'excludeQuery']
};
readonly logsTypeMap = {
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/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 9f6cacd..0f90ba3 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
@@ -43,4 +43,8 @@ export class UtilsService {
return valuesArray.join(',');
}
+ isEnterPressed(event: KeyboardEvent): boolean {
+ return event.keyCode === 13;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a10e3887/ambari-logsearch/ambari-logsearch-web/yarn.lock
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/yarn.lock b/ambari-logsearch/ambari-logsearch-web/yarn.lock
index 291b489..4883a15 100644
--- a/ambari-logsearch/ambari-logsearch-web/yarn.lock
+++ b/ambari-logsearch/ambari-logsearch-web/yarn.lock
@@ -3499,6 +3499,10 @@ negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
+ng2-auto-complete@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/ng2-auto-complete/-/ng2-auto-complete-0.12.0.tgz#9a78c39c5012404e7bc8365c03815ab7f68cea3d"
+
ngx-bootstrap@^1.6.6:
version "1.6.6"
resolved "https://registry.yarnpkg.com/ngx-bootstrap/-/ngx-bootstrap-1.6.6.tgz#0057141cfbdd7e8a50e81bda735fad8e95acb0dd"