You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mr...@apache.org on 2017/09/11 04:39:08 UTC
[38/94] [abbrv] [partial] ambari git commit: AMBARI-21870. Integrate
LogSearch new UI with the server and get rid of the old one (oleewere)
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/accordion-panel/accordion-panel.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/accordion-panel/accordion-panel.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/accordion-panel/accordion-panel.component.ts
new file mode 100644
index 0000000..131edcd
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/accordion-panel/accordion-panel.component.ts
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Component, Input, ContentChild, TemplateRef} from '@angular/core';
+
+@Component({
+ selector: 'accordion-panel',
+ templateUrl: './accordion-panel.component.html',
+ styleUrls: ['./accordion-panel.component.less']
+})
+export class AccordionPanelComponent {
+
+ @Input()
+ toggleId: string;
+
+ @ContentChild(TemplateRef)
+ template;
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
new file mode 100644
index 0000000..a0444c9
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
@@ -0,0 +1,34 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<header>
+ <nav class="navbar navbar-fixed-top">
+ <div class="container-fluid">
+ <h1 [ngClass]="{'full-flex-width': !isAuthorized, 'navbar-left': true}">{{'common.title' | translate}}</h1>
+ <top-menu *ngIf="isAuthorized" class="navbar-right"></top-menu>
+ </div>
+ </nav>
+</header>
+
+<main-container>
+ <ng-template>
+ <!-- hidden element for moving the main bar outside the fixed header -->
+ <div class="navbar invisible">
+ <h1> </h1>
+ </div>
+ </ng-template>
+</main-container>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
new file mode 100644
index 0000000..d1aa7ff
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
@@ -0,0 +1,51 @@
+/**
+ * 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';
+
+:host {
+ .full-size;
+ display: flex;
+ flex-direction: column;
+ background-color: @main-background-color; // TODO implement actual color
+ line-height: @default-line-height;
+
+ .navbar {
+ margin-bottom: 0;
+ border-radius: 0;
+ background-color: @navbar-background-color;
+ color: #fff;
+
+ .container-fluid {
+ .default-flex;
+ }
+
+ h1 {
+ flex-basis: 70%;
+ margin-bottom: @h1-vertical-margin;
+ text-transform: uppercase;
+
+ &.full-flex-width {
+ flex-basis: 100%;
+ }
+ }
+
+ /deep/ top-menu {
+ flex-basis: 30%;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.spec.ts
new file mode 100644
index 0000000..bc16ea4
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.spec.ts
@@ -0,0 +1,71 @@
+/**
+ * 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 {TestBed, async} from '@angular/core/testing';
+import {Http} from '@angular/http';
+import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
+import {TranslateHttpLoader} from '@ngx-translate/http-loader';
+import {StoreModule} from '@ngrx/store';
+import {AppStateService, appState} from '@app/services/storage/app-state.service';
+import {HttpClientService} from '@app/services/http-client.service';
+
+import {AppComponent} from './app.component';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
+}
+
+describe('AppComponent', () => {
+ beforeEach(async(() => {
+ const httpClient = {
+ get: () => {
+ return {
+ subscribe: () => {}
+ }
+ }
+ };
+ TestBed.configureTestingModule({
+ declarations: [AppComponent],
+ imports: [
+ StoreModule.provideStore({
+ appState
+ }),
+ TranslateModule.forRoot({
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ })
+ ],
+ providers: [
+ AppStateService,
+ {
+ provide: HttpClientService,
+ useValue: httpClient
+ }
+ ],
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
+ }).compileComponents();
+ }));
+
+ it('should create the app', async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app).toBeTruthy();
+ }));
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..4de47ea
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Component} from '@angular/core';
+import {TranslateService} from '@ngx-translate/core';
+import {AppStateService} from '@app/services/storage/app-state.service';
+import {HttpClientService} from '@app/services/http-client.service';
+
+@Component({
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.less']
+})
+
+export class AppComponent {
+
+ constructor(private httpClient: HttpClientService, private translate: TranslateService, private appState: AppStateService) {
+ appState.getParameter('isAuthorized').subscribe(value => this.isAuthorized = value);
+ appState.setParameter('isInitialLoading', true);
+ this.httpClient.get('status').subscribe(() => this.appState.setParameters({
+ isAuthorized: true,
+ isInitialLoading: false
+ }), () => this.appState.setParameter('isInitialLoading', false));
+ translate.setDefaultLang('en');
+ translate.use('en');
+ }
+
+ isAuthorized: boolean = false;
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..a16b205
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
@@ -0,0 +1,25 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<div class="filter-label" *ngIf="label">{{label | translate}}</div>
+<div [ngClass]="{'dropup': isDropup}">
+ <button class="btn btn-link dropdown-toggle" data-toggle="dropdown">
+ <span *ngIf="!isMultipleChoice">{{selectedLabel | translate}}</span> <span class="caret"></span>
+ </button>
+ <ul data-component="dropdown-list" [ngClass]="{'dropdown-menu': true, 'dropdown-menu-right': isRightAlign}"
+ [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateValue($event)"></ul>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.less
new file mode 100644
index 0000000..55699b4
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.less
@@ -0,0 +1,32 @@
+/**
+ * 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';
+
+:host {
+ .default-flex;
+ position: relative;
+ float: left;
+
+ .filter-label {
+ padding: @input-group-addon-padding;
+ }
+
+ .btn {
+ text-transform: none;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..8efe320
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
@@ -0,0 +1,79 @@
+/**
+ * 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 {StoreModule} from '@ngrx/store';
+import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {ClustersService, clusters} from '@app/services/storage/clusters.service';
+import {ComponentsService, components} from '@app/services/storage/components.service';
+import {FilteringService} from '@app/services/filtering.service';
+import {UtilsService} from '@app/services/utils.service';
+import {ComponentActionsService} from '@app/services/component-actions.service';
+
+import {DropdownButtonComponent} from './dropdown-button.component';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
+}
+
+describe('DropdownButtonComponent', () => {
+ let component: DropdownButtonComponent;
+ let fixture: ComponentFixture<DropdownButtonComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [DropdownButtonComponent],
+ imports: [
+ StoreModule.provideStore({
+ appSettings,
+ clusters,
+ components
+ }),
+ TranslateModule.forRoot({
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ })
+ ],
+ providers: [
+ AppSettingsService,
+ ClustersService,
+ ComponentsService,
+ FilteringService,
+ UtilsService,
+ ComponentActionsService
+ ],
+ schemas: [NO_ERRORS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DropdownButtonComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..5800190
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
@@ -0,0 +1,96 @@
+/**
+ * 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, Input} from '@angular/core';
+import {ComponentActionsService} from '@app/services/component-actions.service';
+import {UtilsService} from '@app/services/utils.service';
+
+@Component({
+ selector: 'dropdown-button',
+ templateUrl: './dropdown-button.component.html',
+ styleUrls: ['./dropdown-button.component.less']
+})
+export class DropdownButtonComponent implements OnInit {
+
+ constructor(protected actions: ComponentActionsService, protected utils: UtilsService) {
+ }
+
+ ngOnInit() {
+ this.selectedLabel = this.defaultLabel;
+ }
+
+ @Input()
+ label?: string;
+
+ @Input()
+ options?: any[];
+
+ @Input()
+ defaultValue?: string;
+
+ @Input()
+ defaultLabel?: string;
+
+ @Input()
+ action?: string;
+
+ @Input()
+ additionalArgs: any[] = [];
+
+ @Input()
+ isMultipleChoice: boolean = false;
+
+ @Input()
+ isRightAlign: boolean = false;
+
+ @Input()
+ isDropup: boolean = false;
+
+ protected selectedValue?: any;
+
+ selectedLabel: string;
+
+ get value(): any {
+ return this.selectedValue;
+ }
+
+ set value(value: any) {
+ this.selectedValue = value;
+ }
+
+ updateValue(eventOptions: any): void {
+ const value = eventOptions && eventOptions.value,
+ 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;
+ if (action) {
+ action(this.options.filter(item => item.isChecked).map(item => item.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);
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..1baebed
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.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.
+-->
+
+<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"
+ (change)="changeSelectedItem({value: item.value, isChecked: $event.currentTarget.checked})">
+ <label [attr.for]="item.id || item.value" class="label-container">{{item.label | translate}}
+ <div #additionalComponent></div>
+ </label>
+ </label>
+ <span class="list-item-label label-container" *ngIf="!isMultipleChoice"
+ (click)="changeSelectedItem({value: item.value, label: item.label})">
+ {{item.label | translate}}
+ <div #additionalComponent></div>
+ </span>
+</li>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..d47160f
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.less
@@ -0,0 +1,41 @@
+/**
+ * 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';
+
+:host {
+ max-height: 500px; // TODO get rid of magic number, base on actual design
+ overflow-y: auto;
+
+ .list-item-label {
+ .dropdown-item-default;
+
+ label {
+ margin-bottom: 0;
+ cursor: pointer;
+ }
+
+ input[type=checkbox]:checked + label:after {
+ top: @checkbox-top;
+ }
+
+ .label-container {
+ width: 100%;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..5409d30
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
@@ -0,0 +1,130 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {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 {StoreModule} from '@ngrx/store';
+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 {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {ClustersService, clusters} from '@app/services/storage/clusters.service';
+import {ComponentsService, components} from '@app/services/storage/components.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 {DropdownListComponent} from './dropdown-list.component';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
+}
+
+describe('DropdownListComponent', () => {
+ let component: DropdownListComponent;
+ let fixture: ComponentFixture<DropdownListComponent>;
+
+ beforeEach(async(() => {
+ const httpClient = {
+ get: () => {
+ return {
+ subscribe: () => {
+ }
+ }
+ }
+ };
+ TestBed.configureTestingModule({
+ declarations: [DropdownListComponent],
+ imports: [
+ TranslateModule.forRoot({
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ }),
+ StoreModule.provideStore({
+ hosts,
+ auditLogs,
+ serviceLogs,
+ auditLogsFields,
+ serviceLogsFields,
+ serviceLogsHistogramData,
+ appSettings,
+ clusters,
+ components
+ })
+ ],
+ providers: [
+ ComponentGeneratorService,
+ LogsContainerService,
+ {
+ provide: HttpClientService,
+ useValue: httpClient
+ },
+ FilteringService,
+ HostsService,
+ AuditLogsService,
+ ServiceLogsService,
+ AuditLogsFieldsService,
+ ServiceLogsFieldsService,
+ ServiceLogsHistogramDataService,
+ AppSettingsService,
+ ClustersService,
+ ComponentsService
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DropdownListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('#changeSelectedItem()', () => {
+
+ const options = {
+ label: 'l',
+ value: 'v'
+ };
+
+ beforeEach(() => {
+ spyOn(component.selectedItemChange, 'emit').and.callFake(() => {});
+ component.changeSelectedItem(options);
+ });
+
+ it('event should be emitted', () => {
+ expect(component.selectedItemChange.emit).toHaveBeenCalled();
+ });
+
+ it('event emitter should be called with correct arguments', () => {
+ expect(component.selectedItemChange.emit).toHaveBeenCalledWith(options);
+ });
+
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.ts
new file mode 100644
index 0000000..3de664e
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.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 {Component, AfterViewInit, Input, Output, EventEmitter, ViewChildren, ViewContainerRef, QueryList} from '@angular/core';
+import {ComponentGeneratorService} from '@app/services/component-generator.service';
+
+@Component({
+ selector: 'ul[data-component="dropdown-list"]',
+ templateUrl: './dropdown-list.component.html',
+ styleUrls: ['./dropdown-list.component.less']
+})
+export class DropdownListComponent implements AfterViewInit {
+
+ constructor(private componentGenerator: ComponentGeneratorService) {
+ }
+
+ ngAfterViewInit() {
+ const setter = this.additionalLabelComponentSetter;
+ if (setter) {
+ this.containers.forEach((container, index) => this.componentGenerator[setter](this.items[index].value, container));
+ }
+ }
+
+ @Input()
+ items: any[];
+
+ @Input()
+ defaultAction: Function;
+
+ @Input()
+ isMultipleChoice?: boolean = false;
+
+ @Input()
+ additionalLabelComponentSetter?: string;
+
+ @Output()
+ selectedItemChange: EventEmitter<any> = new EventEmitter();
+
+ @ViewChildren('additionalComponent', {
+ read: ViewContainerRef
+ })
+ containers: QueryList<ViewContainerRef>;
+
+ changeSelectedItem(options: any): void {
+ this.selectedItemChange.emit(options);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..5d58b5c
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
@@ -0,0 +1,78 @@
+/**
+ * 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 {StoreModule} from '@ngrx/store';
+import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {ClustersService, clusters} from '@app/services/storage/clusters.service';
+import {ComponentsService, components} from '@app/services/storage/components.service';
+import {ComponentActionsService} from '@app/services/component-actions.service';
+import {FilteringService} from '@app/services/filtering.service';
+import {UtilsService} from '@app/services/utils.service';
+
+import {FilterButtonComponent} from './filter-button.component';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
+}
+
+describe('FilterButtonComponent', () => {
+ let component: FilterButtonComponent;
+ let fixture: ComponentFixture<FilterButtonComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [FilterButtonComponent],
+ imports: [
+ StoreModule.provideStore({
+ appSettings,
+ clusters,
+ components
+ }),
+ TranslateModule.forRoot({
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ })],
+ providers: [
+ AppSettingsService,
+ ClustersService,
+ ComponentsService,
+ ComponentActionsService,
+ FilteringService,
+ UtilsService
+ ],
+ schemas: [NO_ERRORS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FilterButtonComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..9940d73
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
@@ -0,0 +1,80 @@
+/**
+ * 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} from '@angular/forms';
+import {ComponentActionsService} from '@app/services/component-actions.service';
+import {UtilsService} from '@app/services/utils.service';
+import {MenuButtonComponent} from '@app/components/menu-button/menu-button.component';
+
+@Component({
+ selector: 'filter-button',
+ templateUrl: '../menu-button/menu-button.component.html',
+ styleUrls: ['../menu-button/menu-button.component.less'],
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => FilterButtonComponent),
+ multi: true
+ }
+ ]
+})
+export class FilterButtonComponent extends MenuButtonComponent implements ControlValueAccessor {
+
+ constructor(protected actions: ComponentActionsService, private utils: UtilsService) {
+ super(actions);
+ }
+
+ @Input()
+ defaultValue?: string;
+
+ private selectedValue: any;
+
+ private onChange: (fn: any) => void;
+
+ get value(): any {
+ return this.selectedValue;
+ }
+
+ set value(newValue: any) {
+ this.selectedValue = newValue;
+ this.onChange(newValue);
+ }
+
+ updateValue(options: any): void {
+ const value = options && options.value;
+ if (this.isMultipleChoice) {
+ this.value = this.utils.updateMultiSelectValue(this.value, value, options.isChecked);
+ } else {
+ if (this.utils.valueHasChanged(this.selectedValue, value)) {
+ this.value = value;
+ }
+ }
+ }
+
+ writeValue() {
+ }
+
+ registerOnChange(callback: any): void {
+ this.onChange = callback;
+ }
+
+ registerOnTouched() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..323aa56
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
@@ -0,0 +1,92 @@
+/**
+ * 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 {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 {FilterDropdownComponent} from './filter-dropdown.component';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
+}
+
+describe('FilterDropdownComponent', () => {
+ let component: FilterDropdownComponent;
+ let fixture: ComponentFixture<FilterDropdownComponent>;
+ const filtering = {
+ filters: {
+ f: {
+ options: [
+ {
+ value: 'v0',
+ label: 'l0'
+ },
+ {
+ value: 'v1',
+ label: 'l1'
+ }
+ ]
+ }
+ }
+ };
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [FilterDropdownComponent],
+ imports: [
+ StoreModule.provideStore({
+ appSettings
+ }),
+ TranslateModule.forRoot({
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ })
+ ],
+ providers: [
+ AppSettingsService,
+ {
+ provide: FilteringService,
+ useValue: filtering
+ },
+ UtilsService,
+ ComponentActionsService
+ ],
+ schemas: [NO_ERRORS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FilterDropdownComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..9e5a6f1
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.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 {Component, forwardRef} from '@angular/core';
+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';
+
+@Component({
+ selector: 'filter-dropdown',
+ templateUrl: '../dropdown-button/dropdown-button.component.html',
+ styleUrls: ['../dropdown-button/dropdown-button.component.less'],
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => FilterDropdownComponent),
+ multi: true
+ }
+ ]
+})
+export class FilterDropdownComponent extends DropdownButtonComponent implements ControlValueAccessor {
+
+ constructor(protected actions: ComponentActionsService, protected utils: UtilsService) {
+ super(actions, utils);
+ }
+
+ private onChange: (fn: any) => void;
+
+ get value(): any {
+ return this.selectedValue;
+ }
+
+ set value(newValue: any) {
+ this.selectedValue = newValue;
+ this.onChange(newValue);
+ }
+
+ writeValue() {
+ }
+
+ registerOnChange(callback: any): void {
+ this.onChange = callback;
+ }
+
+ registerOnTouched() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..3f00e8b
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.html
@@ -0,0 +1,21 @@
+<!--
+ 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/02360dd5/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
new file mode 100644
index 0000000..1395959
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.less
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import '../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/02360dd5/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
new file mode 100644
index 0000000..71039ed
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.spec.ts
@@ -0,0 +1,82 @@
+/**
+ * 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/02360dd5/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
new file mode 100644
index 0000000..2b6bfea
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-text-field/filter-text-field.component.ts
@@ -0,0 +1,87 @@
+/**
+ * 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/02360dd5/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
new file mode 100644
index 0000000..6df6988
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
@@ -0,0 +1,46 @@
+<!--
+ 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.
+-->
+
+<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>
+ <filter-dropdown formControlName="timeRange" [options]="filters.timeRange.options"
+ [defaultLabel]="filters.timeRange.defaultLabel"></filter-dropdown>
+ <timezone-picker></timezone-picker>
+ <!--button class="btn btn-success" type="button">
+ <span class="fa fa-search"></span>
+ </button-->
+ </div>
+ <div class="default-flex col-md-4">
+ <a href="#">
+ <span class="fa fa-search-minus"></span> {{'filter.excluded' | translate}}
+ </a>
+ <filter-button formControlName="hosts" [label]="filters.hosts.label"
+ [iconClass]="filters.hosts.iconClass" [subItems]="filters.hosts.options"
+ [isMultipleChoice]="true" [isRightAlign]="true"
+ additionalLabelComponentSetter="getDataForHostsNodeBar"></filter-button>
+ <filter-button formControlName="components" [label]="filters.components.label"
+ [iconClass]="filters.components.iconClass" [subItems]="filters.components.options"
+ [isMultipleChoice]="true" [isRightAlign]="true"></filter-button>
+ <filter-button formControlName="levels" [label]="filters.levels.label" [iconClass]="filters.levels.iconClass"
+ [subItems]="filters.levels.options" [isMultipleChoice]="true" [isRightAlign]="true"></filter-button>
+ <menu-button label="filter.capture" iconClass="fa fa-caret-right"></menu-button>
+ </div>
+</form>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..9ab09ef
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.less
@@ -0,0 +1,51 @@
+/**
+ * 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';
+
+:host {
+ display: block;
+ padding: @filters-panel-padding;
+ background-color: @filters-panel-background-color;
+
+ .filter-input-container {
+ .flex-vertical-align;
+ justify-content: flex-start;
+
+ .btn-success {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+
+ filter-dropdown, dropdown-button, timezone-picker {
+ border: @input-border;
+
+ &:not(:last-child) {
+ border-right-width: 0;
+ }
+
+ &:first-child {
+ border-radius: @button-border-radius 0 0 @button-border-radius;
+ }
+
+ &:last-child {
+ border-radius: 0 @button-border-radius @button-border-radius 0;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..b1cf990
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
@@ -0,0 +1,93 @@
+/**
+ * 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 {StoreModule} from '@ngrx/store';
+import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.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 {FilteringService} from '@app/services/filtering.service';
+import {HttpClientService} from '@app/services/http-client.service';
+import {UtilsService} from '@app/services/utils.service';
+
+import {FiltersPanelComponent} from './filters-panel.component';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
+}
+
+describe('FiltersPanelComponent', () => {
+ let component: FiltersPanelComponent;
+ let fixture: ComponentFixture<FiltersPanelComponent>;
+
+ beforeEach(async(() => {
+ const httpClient = {
+ get: () => {
+ return {
+ subscribe: () => {
+ }
+ }
+ }
+ };
+ TestBed.configureTestingModule({
+ declarations: [FiltersPanelComponent],
+ imports: [
+ StoreModule.provideStore({
+ appSettings,
+ clusters,
+ components,
+ hosts
+ }),
+ TranslateModule.forRoot({
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ })
+ ],
+ providers: [
+ AppSettingsService,
+ ClustersService,
+ ComponentsService,
+ HostsService,
+ FilteringService,
+ {
+ provide: HttpClientService,
+ useValue: httpClient
+ },
+ UtilsService
+ ],
+ schemas: [NO_ERRORS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FiltersPanelComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..e407021
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Component} from '@angular/core';
+import {FormGroup} from '@angular/forms';
+import {FilteringService} from '@app/services/filtering.service';
+
+@Component({
+ selector: 'filters-panel',
+ templateUrl: './filters-panel.component.html',
+ styleUrls: ['./filters-panel.component.less']
+})
+export class FiltersPanelComponent {
+
+ constructor(private filtering: FilteringService) {
+ this.filtering.loadClusters();
+ this.filtering.loadComponents();
+ this.filtering.loadHosts();
+ }
+
+ get filters(): any {
+ return this.filtering.filters;
+ }
+
+ get filtersForm(): FormGroup {
+ return this.filtering.filtersForm;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
new file mode 100644
index 0000000..a34cfb8
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
@@ -0,0 +1,33 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<div class="login-form well col-md-4 col-md-offset-4 col-sm-offset-4">
+ <div class="alert alert-danger" *ngIf="isLoginAlertDisplayed" [innerHTML]="'authorization.error' | translate"></div>
+ <form #loginForm="ngForm" (ngSubmit)="login()">
+ <div class="form-group">
+ <label for="username">{{'authorization.name' | translate}}</label>
+ <input class="form-control" type="text" id="username" name="username" required [(ngModel)]="username">
+ </div>
+ <div class="form-group">
+ <label for="password">{{'authorization.password' | translate}}</label>
+ <input class="form-control" type="password" id="password" name="password" required [(ngModel)]="password">
+ </div>
+ <button class="btn btn-success" [disabled]="!loginForm.form.valid || isLoginInProgress">
+ {{'authorization.signIn' | translate}}
+ </button>
+ </form>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.less
new file mode 100644
index 0000000..f760ee8
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.less
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import '../variables';
+
+.login-form {
+ margin-top: @block-margin-top;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.spec.ts
new file mode 100644
index 0000000..fd54fe6
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.spec.ts
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {FormsModule} from '@angular/forms';
+import {HttpModule, Http} from '@angular/http';
+import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
+import {TranslateHttpLoader} from '@ngx-translate/http-loader';
+import {StoreModule} from '@ngrx/store';
+import {AppStateService, appState} from '@app/services/storage/app-state.service';
+import {HttpClientService} from '@app/services/http-client.service';
+
+import {LoginFormComponent} from './login-form.component';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
+}
+
+describe('LoginFormComponent', () => {
+ let component: LoginFormComponent;
+ let fixture: ComponentFixture<LoginFormComponent>;
+
+ let authMock = {
+ isError: false
+ };
+ const httpClient = {
+ isAuthorized: true,
+ postFormData: () => {
+ return {
+ subscribe: (success: () => void, error: () => void) => {
+ authMock.isError ? error() : success();
+ }
+ }
+ }
+ };
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [LoginFormComponent],
+ imports: [
+ HttpModule,
+ FormsModule,
+ TranslateModule.forRoot({
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ }),
+ StoreModule.provideStore({
+ appState
+ })
+ ],
+ providers: [
+ AppStateService,
+ {
+ provide: HttpClientService,
+ useValue: httpClient
+ }
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LoginFormComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('#login()', () => {
+ const cases = [
+ {
+ isError: true,
+ isLoginAlertDisplayed: true,
+ isAuthorized: false,
+ title: 'login failure'
+ },
+ {
+ isError: false,
+ isLoginAlertDisplayed: false,
+ isAuthorized: true,
+ title: 'login success'
+ }
+ ];
+
+ cases.forEach(test => {
+ describe(test.title, () => {
+ beforeEach(() => {
+ authMock.isError = test.isError;
+ component.login();
+ });
+
+ it('isLoginAlertDisplayed', () => {
+ expect(component.isLoginAlertDisplayed).toEqual(test.isLoginAlertDisplayed);
+ });
+
+ it('isLoginInProgress', () => {
+ expect(component.isLoginInProgress).toEqual(false);
+ });
+ });
+ });
+
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
new file mode 100644
index 0000000..2bc45404
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Component} from '@angular/core';
+import 'rxjs/add/operator/finally';
+import {HttpClientService} from '@app/services/http-client.service';
+import {AppStateService} from '@app/services/storage/app-state.service';
+
+@Component({
+ selector: 'login-form',
+ templateUrl: './login-form.component.html',
+ styleUrls: ['./login-form.component.less']
+})
+export class LoginFormComponent {
+
+ constructor(private httpClient: HttpClientService, private appState: AppStateService) {
+ appState.getParameter('isLoginInProgress').subscribe(value => this.isLoginInProgress = value);
+ }
+
+ username: string;
+
+ password: string;
+
+ isLoginAlertDisplayed: boolean;
+
+ isLoginInProgress: boolean;
+
+ private setIsAuthorized(value: boolean): void {
+ this.appState.setParameters({
+ isAuthorized: value,
+ isLoginInProgress: false
+ });
+ this.isLoginAlertDisplayed = !value;
+ }
+
+ login() {
+ this.appState.setParameter('isLoginInProgress', true);
+ this.httpClient.postFormData('login', {
+ username: this.username,
+ password: this.password
+ }).subscribe(() => this.setIsAuthorized(true), () => this.setIsAuthorized(false));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
new file mode 100644
index 0000000..a43f6c0
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
@@ -0,0 +1,22 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<time-histogram class="col-md-12" [data]="histogramData" [customOptions]="histogramOptions"></time-histogram>
+<dropdown-button class="pull-right" label="logs.columns" [options]="availableColumns | async" [isRightAlign]="true"
+ isMultipleChoice="true" action="updateSelectedColumns"
+ [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button>
+<logs-list [logs]="logs | async" [totalCount]="totalCount" [displayedColumns]="displayedColumns"></logs-list>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
new file mode 100644
index 0000000..60082d6
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import '../variables';
+
+:host {
+ display: block;
+ overflow: hidden;
+ padding-top: @block-margin-top;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02360dd5/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
new file mode 100644
index 0000000..30c6a33
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
+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 {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 {HostsService, hosts} from '@app/services/storage/hosts.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 {LogsContainerComponent} from './logs-container.component';
+
+describe('LogsContainerComponent', () => {
+ const httpClient = {
+ get: () => {
+ return {
+ subscribe: () => {
+ }
+ };
+ }
+ };
+ let component: LogsContainerComponent;
+ let fixture: ComponentFixture<LogsContainerComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [LogsContainerComponent],
+ imports: [
+ StoreModule.provideStore({
+ appSettings,
+ appState,
+ clusters,
+ components,
+ auditLogs,
+ auditLogsFields,
+ serviceLogs,
+ serviceLogsFields,
+ serviceLogsHistogramData,
+ hosts
+ })
+ ],
+ providers: [
+ {
+ provide: HttpClientService,
+ useValue: httpClient
+ },
+ AppSettingsService,
+ AppStateService,
+ ClustersService,
+ ComponentsService,
+ AuditLogsService,
+ AuditLogsFieldsService,
+ ServiceLogsService,
+ ServiceLogsFieldsService,
+ ServiceLogsHistogramDataService,
+ HostsService,
+ FilteringService,
+ UtilsService,
+ LogsContainerService
+ ],
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LogsContainerComponent);
+ component = fixture.componentInstance;
+ component.logsType = 'serviceLogs';
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+});