| /** |
| * 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, Output, EventEmitter, forwardRef, OnDestroy, OnChanges, SimpleChanges } from '@angular/core'; |
| import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; |
| import { Observable } from 'rxjs/Observable'; |
| import 'rxjs/add/operator/map'; |
| import { BehaviorSubject } from 'rxjs/BehaviorSubject'; |
| import { Subscription } from 'rxjs/Subscription'; |
| import { Moment } from 'moment'; |
| import { ListItem } from '@app/classes/list-item'; |
| import { HomogeneousObject, LogLevelObject } from '@app/classes/object'; |
| import { LogIndexFilterComponentConfig } from '@app/classes/settings'; |
| import { LogLevel } from '@app/classes/string'; |
| import { LogsContainerService } from '@app/services/logs-container.service'; |
| import { ServerSettingsService } from '@app/services/server-settings.service'; |
| import { UtilsService } from '@app/services/utils.service'; |
| import { ClustersService } from '@app/services/storage/clusters.service'; |
| import { HostsService } from '@app/services/storage/hosts.service'; |
| import { DataAvailabilityStatesStore } from '@app/modules/app-load/stores/data-availability-state.store'; |
| import { DataAvailabilityValues } from '@app/classes/string'; |
| |
| @Component({ |
| selector: 'log-index-filter', |
| templateUrl: './log-index-filter.component.html', |
| styleUrls: ['./log-index-filter.component.less'], |
| providers: [ |
| { |
| provide: NG_VALUE_ACCESSOR, |
| useExisting: forwardRef(() => LogIndexFilterComponent), |
| multi: true |
| } |
| ] |
| }) |
| export class LogIndexFilterComponent implements OnInit, OnDestroy, OnChanges, ControlValueAccessor { |
| |
| @Output() |
| changeIsSubmitDisabled: EventEmitter<boolean> = new EventEmitter(); |
| |
| private onChange: (fn: any) => void; |
| |
| readonly columns: LogLevelObject[] = this.logsContainer.logLevels; |
| |
| readonly levelNames: LogLevel[] = this.columns.map((level: LogLevelObject): LogLevel => level.name); |
| |
| clusters: Observable<string[]> = this.clustersStorage.getAll(); |
| |
| hosts: Observable<string[]> = this.hostsStorage.getAll(); |
| |
| clustersListItems: Observable<ListItem[]> = this.clusters.map((clusterNames: string[]): ListItem[] => { |
| return clusterNames.map(this.utils.getListItemFromString); |
| }); |
| |
| configsAvailabilityState$: Observable<string> = this.dataAvailablilityStore.getParameter('logIndexFilter'); |
| configsAreLoading$: Observable<boolean> = this.configsAvailabilityState$.distinctUntilChanged().map( |
| (state: DataAvailabilityValues) => state === DataAvailabilityValues.LOADING |
| ); |
| |
| @Input() |
| activeClusterName = ''; |
| |
| private subscriptions: Subscription[] = []; |
| |
| /** |
| * Configs for all clusters |
| */ |
| private configs: HomogeneousObject<LogIndexFilterComponentConfig[]>; |
| |
| activeClusterConfigs$: BehaviorSubject<LogIndexFilterComponentConfig[]> = new BehaviorSubject(null); |
| |
| constructor( |
| private logsContainer: LogsContainerService, |
| private settingsService: ServerSettingsService, |
| private utils: UtilsService, |
| private clustersStorage: ClustersService, |
| private hostsStorage: HostsService, |
| private dataAvailablilityStore: DataAvailabilityStatesStore |
| ) { |
| } |
| |
| ngOnInit() { |
| this.changeIsSubmitDisabled.emit(true); |
| this.subscriptions.push( |
| this.clusters.subscribe((clusters: string[]) => this.settingsService.loadIndexFilterConfig(clusters)) |
| ); |
| } |
| |
| ngOnDestroy() { |
| this.subscriptions.forEach((subscription: Subscription) => subscription.unsubscribe()); |
| } |
| |
| ngOnChanges(changes: SimpleChanges) { |
| if (changes.activeClusterName && this.configs) { |
| this.setCurrentConfig(); |
| } |
| } |
| |
| /** |
| * Configs for selected cluster |
| * @returns {LogIndexFilterComponentConfig[]} |
| */ |
| get activeClusterConfigs(): LogIndexFilterComponentConfig[] { |
| return this.configs[this.activeClusterName] || []; |
| } |
| |
| private setCurrentConfig() { |
| this.activeClusterConfigs$.next((this.configs && this.configs[this.activeClusterName]) || []); |
| } |
| |
| /** |
| * Select or unselect checkboxes for all log levels for given component |
| * @param {string} componentName |
| * @param {boolean} isChecked |
| * @param {boolean} isOverride - indicates whether levels for override are processed |
| */ |
| processAllLevelsForComponent(componentName: string, isChecked: boolean, isOverride: boolean = false): void { |
| const componentConfig = this.getComponentConfigs(componentName), |
| key = isOverride ? 'overrides' : 'defaults'; |
| this.levelNames.forEach((levelName: LogLevel) => componentConfig[levelName][key] = isChecked); |
| this.updateValue(); |
| } |
| |
| /** |
| * Select or unselect checkboxes for all components for given log level |
| * @param {LogLevel} levelName |
| * @param {boolean} isChecked |
| */ |
| processAllComponentsForLevel(levelName: LogLevel, isChecked: boolean): void { |
| this.activeClusterConfigs.forEach((component: LogIndexFilterComponentConfig): void => { |
| component[levelName].defaults = isChecked; |
| component[levelName].overrides = component.hasOverrides && isChecked; |
| }); |
| this.updateValue(); |
| } |
| |
| /** |
| * Indicates whether all log levels for given component are checked |
| * @param {string} componentName |
| * @param {string} isOverride - indicates whether levels for override are overviewed |
| * @returns {boolean} |
| */ |
| isAllLevelsCheckedForComponent(componentName: string, isOverride: boolean = false): boolean { |
| const componentConfig = this.getComponentConfigs(componentName), |
| key = isOverride ? 'overrides' : 'defaults'; |
| return this.levelNames.every((levelName: LogLevel): boolean => componentConfig[levelName][key]); |
| } |
| |
| /** |
| * Indicates whether all components for given log level are checked |
| * @param {LogLevel} levelName |
| * @returns {boolean} |
| */ |
| isAllComponentsCheckedForLevel(levelName: LogLevel): boolean { |
| return this.activeClusterConfigs.every((component: LogIndexFilterComponentConfig): boolean => { |
| return component[levelName].defaults; |
| }); |
| } |
| |
| setActiveCluster(clusterName: string): void { |
| this.activeClusterName = clusterName; |
| this.changeIsSubmitDisabled.emit(false); |
| } |
| |
| getCheckBoxId(componentName: string, levelName: string, isOverride: boolean = false): string { |
| return `component_${componentName}_level_${levelName}${isOverride ? '_override' : ''}`; |
| } |
| |
| setExpiryTime(time: Moment, componentConfig): void { |
| componentConfig.expiryTime = time.toISOString(); |
| } |
| |
| private getComponentConfigs(componentName: string) { |
| return this.activeClusterConfigs.find((component: LogIndexFilterComponentConfig): boolean => { |
| return component.name === componentName; |
| }); |
| } |
| |
| writeValue(filters: HomogeneousObject<LogIndexFilterComponentConfig[]>): void { |
| this.configs = filters; |
| this.setCurrentConfig(); |
| } |
| |
| registerOnChange(callback: any): void { |
| this.onChange = callback; |
| } |
| |
| registerOnTouched(): void { |
| } |
| |
| updateValue(): void { |
| this.setCurrentConfig(); |
| if (this.onChange) { |
| this.onChange(this.configs); |
| } |
| } |
| |
| } |