Repository: ambari Updated Branches: refs/heads/trunk 1a803ccab -> 63a15872f
AMBARI-22564 Log Search UI: layout and behaviour changes for filtering. (ababiichuk) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/63a15872 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/63a15872 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/63a15872 Branch: refs/heads/trunk Commit: 63a15872fec4ffec793878258b13b356e74528fa Parents: 1a803cc Author: ababiichuk <[email protected]> Authored: Thu Nov 30 18:03:18 2017 +0200 Committer: ababiichuk <[email protected]> Committed: Thu Nov 30 20:39:06 2017 +0200 ---------------------------------------------------------------------- .../action-menu/action-menu.component.less | 3 - .../action-menu/action-menu.component.ts | 4 -- .../audit-logs-table.component.html | 8 ++- .../dropdown-button.component.html | 4 +- .../dropdown-button.component.less | 17 +++--- .../dropdown-button.component.ts | 3 + .../filters-panel/filters-panel.component.html | 14 ++--- .../filters-panel/filters-panel.component.less | 11 +++- .../filters-panel/filters-panel.component.ts | 21 +++++-- .../menu-button/menu-button.component.less | 13 +--- .../src/app/components/mixins.less | 17 ++++++ .../pagination/pagination.component.html | 4 +- .../search-box/search-box.component.html | 2 +- .../search-box/search-box.component.less | 18 +++--- .../search-box/search-box.component.ts | 38 ++++++++---- .../service-logs-table.component.html | 7 ++- .../service-logs-table.component.less | 1 - .../components/top-menu/top-menu.component.html | 7 ++- .../components/top-menu/top-menu.component.less | 4 ++ .../top-menu/top-menu.component.spec.ts | 64 +++++++++++++++++++- .../components/top-menu/top-menu.component.ts | 25 +++++++- .../src/app/components/variables.less | 3 +- .../src/app/services/logs-container.service.ts | 11 +++- .../src/assets/i18n/en.json | 2 +- .../ambari-logsearch-web/webpack.config.js | 20 +++--- 25 files changed, 225 insertions(+), 96 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less index 880a97b..fff57df 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less @@ -15,13 +15,10 @@ * limitations under the License. */ -@import '../variables'; - :host { display: block; margin-left: auto; menu-button { margin: 0 1em; - color: @table-border-color; } } http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts index 58e0025..72037f8 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts @@ -30,7 +30,6 @@ export class ActionMenuComponent { { iconClass: 'fa fa-arrow-left', label: 'topMenu.undo', - labelClass: 'unstyled-link', action: 'undo', subItems: [ { @@ -50,7 +49,6 @@ export class ActionMenuComponent { { iconClass: 'fa fa-arrow-right', label: 'topMenu.redo', - labelClass: 'unstyled-link', action: 'redo', subItems: [ { @@ -67,13 +65,11 @@ export class ActionMenuComponent { { iconClass: 'fa fa-refresh', label: 'topMenu.refresh', - labelClass: 'unstyled-link', action: 'refresh' }, { iconClass: 'fa fa-history', label: 'topMenu.history', - labelClass: 'unstyled-link', action: 'openHistory', isRightAlign: true, subItems: [ http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/audit-logs-table/audit-logs-table.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/audit-logs-table/audit-logs-table.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/audit-logs-table/audit-logs-table.component.html index d6e9091..cad09bc 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/audit-logs-table/audit-logs-table.component.html +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/audit-logs-table/audit-logs-table.component.html @@ -15,12 +15,14 @@ limitations under the License. --> -<dropdown-button class="pull-right" label="logs.columns" [options]="columns" [isRightAlign]="true" +<dropdown-button class="pull-right" label="{{'logs.columns' | translate}}" [options]="columns" [isRightAlign]="true" [isMultipleChoice]="true" action="updateSelectedColumns" [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button> <form *ngIf="logs && logs.length" [formGroup]="filtersForm" class="row pull-right"> - <filter-dropdown class="col-md-12" [label]="filters.auditLogsSorting.label" formControlName="auditLogsSorting" - [options]="filters.auditLogsSorting.options" [isRightAlign]="true"></filter-dropdown></form> + <filter-dropdown class="col-md-12" label="{{filters.auditLogsSorting.label | translate}}" + formControlName="auditLogsSorting" [options]="filters.auditLogsSorting.options" + [isRightAlign]="true"></filter-dropdown> +</form> <div class="panel panel-default"> <div class="panel-body"> <table class="table"> http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html index b5f1e56..d047d7a 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html @@ -16,11 +16,11 @@ --> <div [ngClass]="{'dropup': isDropup}"> - <button class="btn btn-link dropdown-toggle" data-toggle="dropdown"> + <button [ngClass]="['btn', 'btn-link', 'dropdown-toggle', buttonClass]" data-toggle="dropdown"> <span *ngIf="iconClass || label" [ngClass]="{'filter-label': true, 'plain': !isMultipleChoice && !hideCaret && showSelectedValue}"> <span *ngIf="iconClass" [ngClass]="iconClass"></span> - <span *ngIf="label">{{label | translate}}</span> + <span *ngIf="label">{{label}}</span> </span> <span *ngIf="showSelectedValue && !isMultipleChoice && selection.length">{{selection[0].label | translate}}</span> <span *ngIf="!hideCaret" class="caret"></span> http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/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 index d767e15..7b560c1 100644 --- 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 @@ -20,17 +20,16 @@ :host { .default-flex; position: relative; - float: left; - .filter-label { - padding: @input-group-addon-padding; + button { + text-transform: none; - &.plain { - color: initial; - } - } + .filter-label { + padding: @input-group-addon-padding; - .btn { - text-transform: none; + &.plain { + color: initial; + } + } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts index 148e1b4..a8037d0 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts @@ -35,6 +35,9 @@ export class DropdownButtonComponent { label?: string; @Input() + buttonClass: string = ''; + + @Input() iconClass?: string; @Input() http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/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 4fe169d..440efde 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html @@ -17,22 +17,20 @@ <form [formGroup]="filtersForm"> <div class="form-inline filter-input-container col-md-8"> - <filter-dropdown *ngIf="isFilterConditionDisplayed('clusters')" [label]="filters.clusters.label" - formControlName="clusters" [options]="filters.clusters.options" [isMultipleChoice]="true" - class="filter-input"></filter-dropdown> <search-box [parameterAddSubject]="queryParameterAdd" [parameterNameChangeSubject]="queryParameterNameChange" formControlName="query" [items]="searchBoxItemsTranslated" [itemsOptions]="options" - class="filter-input"></search-box> + [updateValueImmediately]="false" [updateValueSubject]="searchBoxValueUpdate" class="filter-input"></search-box> <time-range-picker *ngIf="isFilterConditionDisplayed('timeRange')" formControlName="timeRange" class="filter-input"></time-range-picker> <timezone-picker class="filter-input"></timezone-picker> - <!--button class="btn btn-success" type="button"> + <button class="btn btn-success search-button" type="button" (click)="updateSearchBoxValue()"> <span class="fa fa-search"></span> - </button--> + </button> </div> <div class="filter-buttons col-md-4"> - <dropdown-button [options]="searchBoxItems | async" iconClass="fa fa-search-minus" label="filter.excluded" - [hideCaret]="true" [showSelectedValue]="false" action="proceedWithExclude"></dropdown-button> + <dropdown-button [options]="searchBoxItems | async" iconClass="fa fa-search-minus" action="proceedWithExclude" + label="{{'filter.exclude' | translate}}" [hideCaret]="true" + [showSelectedValue]="false"></dropdown-button> <filter-button *ngIf="isFilterConditionDisplayed('hosts')" formControlName="hosts" label="{{filters.hosts.label | translate}}" [iconClass]="filters.hosts.iconClass" [subItems]="filters.hosts.options" [isMultipleChoice]="true" [isRightAlign]="true" http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/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 962199b..e2f9a1e 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 @@ -28,9 +28,14 @@ align-items: flex-start; justify-content: flex-start; - .btn-success { - border-top-left-radius: 0; - border-bottom-left-radius: 0; + .search-button { + border: 1px solid @submit-color; + height: auto; + + &:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } } .filter-input { http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/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 01a8932..1717bd7 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 @@ -20,7 +20,8 @@ import {Component, OnChanges, SimpleChanges, Input} from '@angular/core'; import {FormGroup} from '@angular/forms'; import {Observable} from 'rxjs/Observable'; import {Subject} from 'rxjs/Subject'; -import {FilterCondition} from '@app/classes/filtering'; +import 'rxjs/add/observable/from'; +import {FilterCondition, SearchBoxParameter, SearchBoxParameterTriggered} from '@app/classes/filtering'; import {ListItem} from '@app/classes/list-item'; import {LogsType} from '@app/classes/string'; import {CommonEntry} from '@app/classes/models/common-entry'; @@ -46,6 +47,9 @@ export class FiltersPanelComponent implements OnChanges { case 'serviceLogs': result = this.logsContainer.serviceLogsColumns; break; + default: + result = Observable.from([]); + break; } this.searchBoxItems = result; } @@ -65,6 +69,8 @@ export class FiltersPanelComponent implements OnChanges { return this.logsContainer.auditLogsColumnsTranslated; case 'serviceLogs': return this.logsContainer.serviceLogsColumnsTranslated; + default: + return []; } } @@ -93,11 +99,11 @@ export class FiltersPanelComponent implements OnChanges { }, {}); } - get queryParameterNameChange(): Subject<any> { + get queryParameterNameChange(): Subject<SearchBoxParameterTriggered> { return this.logsContainer.queryParameterNameChange; } - get queryParameterAdd(): Subject<any> { + get queryParameterAdd(): Subject<SearchBoxParameter> { return this.logsContainer.queryParameterAdd; } @@ -105,9 +111,14 @@ export class FiltersPanelComponent implements OnChanges { return this.logsContainer.captureSeconds; } + searchBoxValueUpdate: Subject<void> = new Subject(); + isFilterConditionDisplayed(key: string): boolean { - return this.logsContainer.logsTypeMap[this.logsType].listFilters.indexOf(key) > -1 - && Boolean(this.filtersForm.controls[key]); + return this.logsContainer.isFilterConditionDisplayed(key); + } + + updateSearchBoxValue(): void { + this.searchBoxValueUpdate.next(); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less index 0207561..0ec3dd0 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less @@ -15,7 +15,7 @@ * limitations under the License. */ -@import '../variables'; +@import '../mixins'; :host { cursor: pointer; @@ -24,8 +24,7 @@ a { text-align: center; text-decoration: none; - i { - color: @link-color; + .icon { display: inline-block; position: relative; &.fa-caret-down { @@ -36,14 +35,6 @@ display: block; } } - a:hover, a:focus { - i { - color: @link-hover-color; - } - } - .unstyled-link { - color: inherit; - } .badge { background: @badge-bg; http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less index 4460821..0bf169d 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less @@ -140,6 +140,23 @@ } } +.grey { + color: @grey-color; +} + +.collapsed-form-control { + width: 0; + padding: 0; +} + +.inherited-color { + color: inherit; + + &:hover { + color: inherit; + } +} + /** * Caret mixin definition. * The .caret mixin has two parameters: the width of the caret and the direction of the caret http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html index 4be0a47..02ed84b 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html @@ -16,8 +16,8 @@ --> <form class="pagination-form" [formGroup]="filtersForm"> - <filter-dropdown [label]="filterInstance.label" formControlName="pageSize" [options]="filterInstance.options" - [isRightAlign]="true" [isDropup]="true"></filter-dropdown> + <filter-dropdown label="{{filterInstance.label | translate}}" formControlName="pageSize" + [options]="filterInstance.options" [isRightAlign]="true" [isDropup]="true"></filter-dropdown> <span>{{'pagination.numbers' | translate: numbersTranslateParams}}</span> <pagination-controls formControlName="page" [totalCount]="totalCount" [pagesCount]="pagesCount" (currentPageChange)="setCurrentPage($event)"></pagination-controls> http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/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 index 5bffdc5..5ab9a69 100644 --- 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 @@ -30,7 +30,7 @@ (valueChanged)="changeParameterName({value: $event.value, isExclude: false})" (keyup)="onParameterKeyUp($event)"> </span> - <span [ngClass]="{'no-value-options': !activeItemValueOptions.length}"> + <span [ngClass]="{'no-options': !activeItemValueOptions.length}"> <input #valueInput auto-complete [(ngModel)]="currentValue" [source]="activeItemValueOptions" [list-formatter]="itemsListFormatter" [value-formatter]="itemsValueFormatter" [match-formatted]="true" (valueChanged)="onParameterValueChange($event.value)" (keydown)="onParameterValueKeyDown($event)" http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/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 index eac3bd6..9deea92 100644 --- 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 @@ -20,10 +20,6 @@ @inactive-input-width: 1px; @label-margin: 2px; -.collapsed-form-control { - width: 0; - padding: 0; -} :host { display: flex; @@ -38,7 +34,7 @@ margin: @label-margin; border-radius: @dropdown-border-radius; padding: @search-parameter-padding; - background-color: @search-parameter-background-color; + background-color: @grey-color; color: @base-font-color; font-size: 0.8em; @@ -97,16 +93,16 @@ } } - .no-value-options { - /deep/ .ng2-auto-complete { - display: none; - } - } - .value-input { width: 100%; } } + + .no-options { + /deep/ .ng2-auto-complete { + display: none; + } + } } /deep/ .ng2-auto-complete { http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts index 14cc89b..64b8c36 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts @@ -51,6 +51,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess this.valueInput.addEventListener('blur', this.onValueInputBlur); this.parameterNameChangeSubject.subscribe(this.onParameterNameChange); this.parameterAddSubject.subscribe(this.onParameterAdd); + this.updateValueSubject.subscribe(this.updateValue); } ngOnDestroy(): void { @@ -61,6 +62,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess this.valueInput.removeEventListener('blur', this.onValueInputBlur); this.parameterNameChangeSubject.unsubscribe(); this.parameterAddSubject.unsubscribe(); + this.updateValueSubject.unsubscribe(); } private readonly messageParameterName: string = 'log_message'; @@ -69,8 +71,6 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess private isExclude: boolean = false; - private defaultSubject: Subject<any> = new Subject(); - isActive: boolean = false; isParameterInput: boolean = false; @@ -86,10 +86,20 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess itemsOptions: {[key: string]: CommonEntry[]}; @Input() - parameterNameChangeSubject: Subject<SearchBoxParameterTriggered> = this.defaultSubject; + parameterNameChangeSubject: Subject<SearchBoxParameterTriggered> = new Subject(); + + @Input() + parameterAddSubject: Subject<SearchBoxParameter> = new Subject(); + + @Input() + updateValueSubject: Subject<void> = new Subject(); + /** + * Indicates whether form should receive updated value immediately after user adds new search parameter + * @type {boolean} + */ @Input() - parameterAddSubject: Subject<SearchBoxParameter> = this.defaultSubject; + updateValueImmediately: boolean = true; @ViewChild('parameterInput') parameterInputRef: ElementRef; @@ -147,7 +157,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess private switchToParameterInput = (): void => { this.activeItem = null; this.isValueInput = false; - setTimeout(() => this.parameterInput.focus()); + setTimeout(() => this.parameterInput.focus(), 0); }; private getItemByValue(name: string): CommonEntry { @@ -211,7 +221,9 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess value: value, isExclude: this.isExclude }); - this.updateValue(); + if (this.updateValueImmediately) { + this.updateValueSubject.next(); + } } this.switchToParameterInput(); } @@ -225,7 +237,9 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess value: options.value, isExclude: options.isExclude }); - this.updateValue(); + if (this.updateValueImmediately) { + this.updateValueSubject.next(); + } }; onParameterKeyUp = (event: KeyboardEvent): void => { @@ -248,20 +262,22 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess removeParameter(event: MouseEvent, id: number): void { this.parameters = this.parameters.filter((parameter: SearchBoxParameterProcessed): boolean => parameter.id !== id); - this.updateValue(); + if (this.updateValueImmediately) { + this.updateValueSubject.next(); + } event.stopPropagation(); } - updateValue(): void { + updateValue = (): void => { this.currentValue = ''; if (this.onChange) { this.onChange(this.parameters); } - } + }; writeValue(parameters: SearchBoxParameterProcessed[] = []): void { this.parameters = parameters; - this.updateValue(); + this.updateValueSubject.next(); } registerOnChange(callback: any): void { http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.html index a2e666e..7f9c6d7 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.html +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.html @@ -15,12 +15,13 @@ limitations under the License. --> -<dropdown-button class="pull-right" label="logs.columns" [options]="columns" [isRightAlign]="true" +<dropdown-button class="pull-right" label="{{'logs.columns' | translate}}" [options]="columns" [isRightAlign]="true" [isMultipleChoice]="true" action="updateSelectedColumns" [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button> <form *ngIf="logs && logs.length" [formGroup]="filtersForm" class="row pull-right"> - <filter-dropdown class="col-md-12" [label]="filters.serviceLogsSorting.label" formControlName="serviceLogsSorting" - [options]="filters.serviceLogsSorting.options" [isRightAlign]="true"></filter-dropdown> + <filter-dropdown class="col-md-12" label="{{filters.serviceLogsSorting.label | translate}}" + formControlName="serviceLogsSorting" [options]="filters.serviceLogsSorting.options" + [isRightAlign]="true"></filter-dropdown> </form> <div class="panel panel-default"> <div class="panel-body"> http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.less index bd6d012..dfa1889 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.less +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.less @@ -53,7 +53,6 @@ } } &.log-time { - color: @grey-color; min-width: 7em; text-align: right; } http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html index 369ddd4..910e55f 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html @@ -16,8 +16,13 @@ --> <div class="pull-right"> + <form [formGroup]="filtersForm" class="filters"> + <filter-dropdown *ngIf="isClustersFilterDisplayed" formControlName="clusters" [options]="filters.clusters.options" + [isMultipleChoice]="true" label="{{filters.clusters.label | translate}}" [isRightAlign]="true" + buttonClass="inherited-color"></filter-dropdown> + </form> <menu-button *ngFor="let item of items" label="{{item.label | translate}}" [action]="item.action" [iconClass]="item.iconClass" [labelClass]="item.labelClass" [subItems]="item.subItems" - [hideCaret]="item.hideCaret" [badge]="item.badge" [isRightAlign]="item.isRightAlign"> + [hideCaret]="item.hideCaret" [badge]="item.badge" [isRightAlign]="item.isRightAlign"> </menu-button> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less index 32d1beb..257768c 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less @@ -20,4 +20,8 @@ :host { .default-flex; margin-right: 0; + + .filters { + display: inline-block; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.spec.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.spec.ts index 6679ba1..ba5b613 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.spec.ts @@ -18,18 +18,80 @@ import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {ReactiveFormsModule} from '@angular/forms'; +import {StoreModule} from '@ngrx/store'; import {TranslationModules} from '@app/test-config.spec'; +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 {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service'; +import {AppStateService, appState} from '@app/services/storage/app-state.service'; +import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service'; +import {TabsService, tabs} from '@app/services/storage/tabs.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 {LogsContainerService} from '@app/services/logs-container.service'; +import {HttpClientService} from '@app/services/http-client.service'; import {TopMenuComponent} from './top-menu.component'; describe('TopMenuComponent', () => { let component: TopMenuComponent; let fixture: ComponentFixture<TopMenuComponent>; + const httpClient = { + get: () => { + return { + subscribe: () => { + } + }; + } + }; beforeEach(async(() => { TestBed.configureTestingModule({ - imports: TranslationModules, + imports: [ + ReactiveFormsModule, + StoreModule.provideStore({ + auditLogs, + serviceLogs, + auditLogsFields, + serviceLogsFields, + serviceLogsHistogramData, + serviceLogsTruncated, + appState, + appSettings, + tabs, + clusters, + components, + hosts + }), + ...TranslationModules + ], declarations: [TopMenuComponent], + providers: [ + LogsContainerService, + { + provide: HttpClientService, + useValue: httpClient + }, + AuditLogsService, + ServiceLogsService, + AuditLogsFieldsService, + ServiceLogsFieldsService, + ServiceLogsHistogramDataService, + ServiceLogsTruncatedService, + AppStateService, + AppSettingsService, + TabsService, + ClustersService, + ComponentsService, + HostsService + ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) .compileComponents(); http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts index 91f27e8..6df7ab3 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts @@ -17,6 +17,10 @@ */ import {Component} from '@angular/core'; +import {FormGroup} from '@angular/forms'; +import {FilterCondition, TimeUnitListItem} from '@app/classes/filtering'; +import {ListItem} from '@app/classes/list-item'; +import {LogsContainerService} from '@app/services/logs-container.service'; @Component({ selector: 'top-menu', @@ -25,10 +29,21 @@ import {Component} from '@angular/core'; }) export class TopMenuComponent { + constructor(private logsContainer: LogsContainerService) { + } + + get filtersForm(): FormGroup { + return this.logsContainer.filtersForm; + }; + + get filters(): {[key: string]: FilterCondition} { + return this.logsContainer.filters; + }; + //TODO implement loading of real data into subItems readonly items = [ { - iconClass: 'fa fa-user unstyled-link', + iconClass: 'fa fa-user grey', hideCaret: true, isRightAlign: true, subItems: [ @@ -43,4 +58,12 @@ export class TopMenuComponent { } ]; + get clusters(): (ListItem | TimeUnitListItem[])[] { + return this.filters.clusters.options; + } + + get isClustersFilterDisplayed(): boolean { + return this.logsContainer.isFilterConditionDisplayed('clusters') && this.clusters.length > 1; + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/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 18268ad..a9ca3b4 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less @@ -27,7 +27,7 @@ @block-margin-top: 20px; @link-color: #1491C1; @link-hover-color: #23527C; -@grey-color: #666; +@grey-color: #DDD; @default-line-height: 1.42857143; @main-background-color: #ECECEC; @filters-panel-background-color: #FFF; @@ -52,7 +52,6 @@ @submit-color: #5CB85C; @submit-hover-color: #449D44; @exclude-color: #EF6162; -@search-parameter-background-color: #DDD; // Panels @panel-heading: rgba(255, 255, 255, 1); http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/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 64b14b8..4adf577 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 @@ -546,7 +546,7 @@ export class LogsContainerService { activeLogsType: LogsType; - private filtersFormChange: Subject<any> = new Subject(); + private filtersFormChange: Subject<void> = new Subject(); private columnsMapper<FieldT extends LogField>(fields: FieldT[]): ListItem[] { return fields.filter((field: FieldT): boolean => field.isAvailable).map((field: FieldT): ListItem => { @@ -628,9 +628,9 @@ export class LogsContainerService { queryParameterAdd: Subject<SearchBoxParameter> = new Subject(); - private stopTimer: Subject<any> = new Subject(); + private stopTimer: Subject<void> = new Subject(); - private stopAutoRefreshCountdown: Subject<any> = new Subject(); + private stopAutoRefreshCountdown: Subject<void> = new Subject(); captureSeconds: number = 0; @@ -962,4 +962,9 @@ export class LogsContainerService { }, {}); } + isFilterConditionDisplayed(key: string): boolean { + return this.logsTypeMap[this.activeLogsType].listFilters.indexOf(key) > -1 + && Boolean(this.filtersForm.controls[key]); + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json index 98b9e29..6c916aa 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json +++ b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json @@ -26,7 +26,7 @@ "filter.clusters": "Clusters", "filter.components": "Components", "filter.levels": "Levels", - "filter.excluded": "Excluded", + "filter.exclude": "Exclude", "filter.hosts": "Hosts", "filter.capture": "Capture", http://git-wip-us.apache.org/repos/asf/ambari/blob/63a15872/ambari-logsearch/ambari-logsearch-web/webpack.config.js ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/webpack.config.js b/ambari-logsearch/ambari-logsearch-web/webpack.config.js index 75d6aee..e1a2366 100644 --- a/ambari-logsearch/ambari-logsearch-web/webpack.config.js +++ b/ambari-logsearch/ambari-logsearch-web/webpack.config.js @@ -102,11 +102,11 @@ module.exports = { "./src/polyfills.ts" ], "styles": [ - "./src/styles.less", "./node_modules/bootstrap/dist/css/bootstrap.min.css", "./node_modules/font-awesome/css/font-awesome.min.css", "./src/vendor/css/bootstrap-logsearch.min.css", - "./src/vendor/css/bootstrap-datetimepicker.min.css" + "./src/vendor/css/bootstrap-datetimepicker.min.css", + "./src/styles.less" ] }, "output": { @@ -271,11 +271,11 @@ module.exports = { }, { "include": [ - path.join(process.cwd(), "src/styles.less"), path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"), path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"), path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css"), - path.join(process.cwd(), "src/vendor/css/bootstrap-datetimepicker.min.css") + path.join(process.cwd(), "src/vendor/css/bootstrap-datetimepicker.min.css"), + path.join(process.cwd(), "src/styles.less") ], "test": /\.css$/, "use": [ @@ -298,11 +298,11 @@ module.exports = { }, { "include": [ - path.join(process.cwd(), "src/styles.less"), path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"), path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"), path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css"), - path.join(process.cwd(), "src/vendor/css/bootstrap-datetimepicker.min.css") + path.join(process.cwd(), "src/vendor/css/bootstrap-datetimepicker.min.css"), + path.join(process.cwd(), "src/styles.less") ], "test": /\.scss$|\.sass$/, "use": [ @@ -333,11 +333,11 @@ module.exports = { }, { "include": [ - path.join(process.cwd(), "src/styles.less"), path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"), path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"), path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css"), - path.join(process.cwd(), "src/vendor/css/bootstrap-datetimepicker.min.css") + path.join(process.cwd(), "src/vendor/css/bootstrap-datetimepicker.min.css"), + path.join(process.cwd(), "src/styles.less") ], "test": /\.less$/, "use": [ @@ -367,11 +367,11 @@ module.exports = { }, { "include": [ - path.join(process.cwd(), "src/styles.less"), path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"), path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"), path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css"), - path.join(process.cwd(), "src/vendor/css/bootstrap-datetimepicker.min.css") + path.join(process.cwd(), "src/vendor/css/bootstrap-datetimepicker.min.css"), + path.join(process.cwd(), "src/styles.less") ], "test": /\.styl$/, "use": [
