This is an automated email from the ASF dual-hosted git repository. ababiichuk pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push: new 22f92e3 AMBARI-23535 Log Search UI: refine log actions 22f92e3 is described below commit 22f92e3bfda82826275d266d3f4cb919c00f13e2 Author: Istvan Tobias <tobias.ist...@gmail.com> AuthorDate: Mon Apr 16 11:53:50 2018 +0200 AMBARI-23535 Log Search UI: refine log actions --- .../filters-panel/filters-panel.component.html | 2 ++ .../filters-panel/filters-panel.component.ts | 2 ++ .../log-context/log-context.component.html | 19 ++++++---- .../log-context/log-context.component.less | 17 ++++++--- .../log-context/log-context.component.ts | 40 ++++++++++++---------- .../logs-container/logs-container.component.html | 2 +- .../logs-container/logs-container.component.ts | 2 ++ .../service-logs-table.component.spec.ts | 6 +++- .../service-logs-table.component.ts | 22 +++++++++--- .../shared/components/modal/modal.component.html | 3 +- .../shared/components/modal/modal.component.less | 13 +++++++ .../shared/components/modal/modal.component.ts | 3 ++ .../shared/services/notification.service.ts | 8 +++-- .../ambari-logsearch-web/src/assets/i18n/en.json | 4 +++ 14 files changed, 105 insertions(+), 38 deletions(-) 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 1ff8e62..aed8874 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 @@ -36,6 +36,7 @@ label="{{filters.hosts.label | translate}}" [iconClass]="filters.hosts.iconClass" [subItems]="filters.hosts.options" [isMultipleChoice]="true" [isRightAlign]="true" additionalLabelComponentSetter="getDataForHostsNodeBar" + [class.disabled]="isServiceLogsFileView$ | async" [isDisabled]="isServiceLogsFileView$ | async" [useDropDownLocalFilter]="true"></filter-button> <filter-button *ngIf="isFilterConditionDisplayed('users')" formControlName="users" label="{{filters.users.label | translate}}" [iconClass]="filters.users.iconClass" @@ -44,6 +45,7 @@ <filter-button *ngIf="isFilterConditionDisplayed('components')" formControlName="components" [useDropDownLocalFilter]="true" label="{{filters.components.label | translate}}" [iconClass]="filters.components.iconClass" [subItems]="filters.components.options" [isMultipleChoice]="true" [isRightAlign]="true" + [class.disabled]="isServiceLogsFileView$ | async" [isDisabled]="isServiceLogsFileView$ | async" additionalLabelComponentSetter="getDataForComponentsNodeBar"></filter-button> <filter-button *ngIf="isFilterConditionDisplayed('levels')" formControlName="levels" label="{{filters.levels.label | translate}}" [iconClass]="filters.levels.iconClass" 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 1b9b13e..cb97f99 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 @@ -47,6 +47,8 @@ export class FiltersPanelComponent implements OnDestroy, OnInit { searchBoxValueUpdate: Subject<void> = new Subject(); + private isServiceLogsFileView$: Observable<boolean> = this.appState.getParameter('isServiceLogsFileView'); + get containerEl(): Element { return this.viewContainerRef.element.nativeElement; } diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.html index 2e51e0b..b5eced0 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.html +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.html @@ -16,18 +16,23 @@ --> <modal title="{{hostName}} -> {{componentName}}" submitButtonLabel="modal.close" [showCancelButton]="false" - [isLargeModal]="true" (init)="scrollToCurrentEntry()" (submit)="closeLogContext()" (close)="closeLogContext()"> + [isLargeModal]="true" [isFlexLayout]="true" (init)="scrollToCurrentEntry()" (submit)="closeLogContext()" (close)="closeLogContext()" + [showSubmitButton]="false" [showFooter]="false"> <ng-template> - <button class="btn btn-primary" (click)="loadBefore()"> - {{'logs.loadMore' | translate}} <span class="fa fa-arrow-up"></span> - </button> + <div> + <button class="btn btn-primary btn-load-more" (click)="loadBefore()"> + {{'logs.loadMore' | translate}} <span class="fa fa-arrow-up"></span> + </button> + </div> <div class="logs"> <log-file-entry *ngFor="let log of logs | async" [ngClass]="log.id === id ? currentLogClassName : ''" [time]="log.time" [level]="log.level" [fileName]="log.fileName" [lineNumber]="log.lineNumber" [message]="log.message"></log-file-entry> </div> - <button class="btn btn-primary" (click)="loadAfter()"> - {{'logs.loadMore' | translate}} <span class="fa fa-arrow-down"></span> - </button> + <div> + <button class="btn btn-primary btn-load-more" (click)="loadAfter()"> + {{'logs.loadMore' | translate}} <span class="fa fa-arrow-down"></span> + </button> + </div> </ng-template> </modal> diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.less index c7a42ad..4055730 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.less +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.less @@ -16,8 +16,17 @@ */ @import '../../modules/shared/variables'; - -.logs { - max-height: @dropdown-max-height; // TODO implement actual styles - overflow-y: auto; +:host { + /deep/ .modal-body { + display: flex; + flex-direction: column; + } + .logs { + flex-grow: 1; + overflow-y: auto; + margin: 1em 0; + } + .btn.btn-load-more { + width: 100%; + } } diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.ts index c0411e5..338a154 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.ts @@ -31,9 +31,6 @@ import {ServiceLogContextEntry} from '@app/classes/service-log-context-entry'; }) export class LogContextComponent { - constructor(private element: ElementRef, private logsContainer: LogsContainerService, private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService) { - } - @Input() id: string; @@ -49,22 +46,29 @@ export class LogContextComponent { lastEntryId: string; - logs: Observable<ServiceLogContextEntry[]> = this.serviceLogsTruncatedStorage.getAll().map((logs: ServiceLog[]): ServiceLogContextEntry[] => { - if (logs.length) { - this.firstEntryId = logs[0].id; - this.lastEntryId = logs[logs.length - 1].id; - } - return logs.map((log: ServiceLog): ServiceLogContextEntry => { - return { - id: log.id, - time: log.logtime, - level: log.level, - message: log.log_message, - fileName: log.file, - lineNumber: log.line_number - }; + logs: Observable<ServiceLogContextEntry[]> = this.serviceLogsTruncatedStorage.getAll() + .map((logs: ServiceLog[]): ServiceLogContextEntry[] => { + if (logs.length) { + this.firstEntryId = logs[0].id; + this.lastEntryId = logs[logs.length - 1].id; + } + return logs.map((log: ServiceLog): ServiceLogContextEntry => { + return { + id: log.id, + time: log.logtime, + level: log.level, + message: log.log_message, + fileName: log.file, + lineNumber: log.line_number + }; + }); }); - }); + + constructor( + private element: ElementRef, + private logsContainer: LogsContainerService, + private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, + private appState: AppStateService) {} closeLogContext(): void { this.appState.setParameters({ 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 index 54af8ca..c16627c 100644 --- 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 @@ -43,7 +43,7 @@ </div> <ng-container [ngSwitch]="logsType"> <ng-container *ngSwitchCase="'serviceLogs'"> - <collapsible-panel openTitle="logs.hideGraph" collapsedTitle="logs.showGraph"> + <collapsible-panel [class.hide]="isServiceLogsFileView$ | async" openTitle="logs.hideGraph" collapsedTitle="logs.showGraph"> <time-histogram (selectArea)="setCustomTimeRange($event[0], $event[1])" [data]="serviceLogsHistogramData" [colors]="serviceLogsHistogramColors" [allowFractionalYTicks]="false" svgId="service-logs-histogram"></time-histogram> diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts index c59e51b..0d808fc 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts @@ -85,6 +85,8 @@ export class LogsContainerComponent implements OnInit, OnDestroy { private subscriptions: Subscription[] = []; private queryParamsSyncInProgress: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); + private isServiceLogsFileView$: Observable<boolean> = this.appState.getParameter('isServiceLogsFileView'); + constructor( private appState: AppStateService, private tabsStorage: TabsService, diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.spec.ts index 9a91572..7745781 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.spec.ts @@ -53,6 +53,8 @@ import {LogsStateService} from '@app/services/storage/logs-state.service'; import {RoutingUtilsService} from '@app/services/routing-utils.service'; import {LogsFilteringUtilsService} from '@app/services/logs-filtering-utils.service'; import {RouterTestingModule} from '@angular/router/testing'; +import {NotificationsService} from 'angular2-notifications/src/notifications.service'; +import {NotificationService} from '@modules/shared/services/notification.service'; describe('ServiceLogsTableComponent', () => { let component: ServiceLogsTableComponent; @@ -112,7 +114,9 @@ describe('ServiceLogsTableComponent', () => { ClusterSelectionService, RoutingUtilsService, LogsFilteringUtilsService, - LogsStateService + LogsStateService, + NotificationsService, + NotificationService ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.ts index ee19e1c..7a5e94a 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/service-logs-table/service-logs-table.component.ts @@ -23,6 +23,7 @@ import {LogsTableComponent} from '@app/classes/components/logs-table/logs-table- import {ServiceLog} from '@app/classes/models/service-log'; import {LogsContainerService} from '@app/services/logs-container.service'; import {UtilsService} from '@app/services/utils.service'; +import {NotificationService} from '@modules/shared/services/notification.service'; export enum ListLayout { Table = 'TABLE', @@ -39,7 +40,8 @@ export class ServiceLogsTableComponent extends LogsTableComponent implements Aft constructor( private logsContainer: LogsContainerService, private utils: UtilsService, - private cdRef:ChangeDetectorRef + private cdRef: ChangeDetectorRef, + private notificationService: NotificationService ) { super(); } @@ -122,13 +124,25 @@ export class ServiceLogsTableComponent extends LogsTableComponent implements Aft node.select(); if (document.queryCommandEnabled('copy')) { document.execCommand('copy'); + this.notificationService.addNotification({ + type: 'success', + title: 'logs.copy.title', + message: 'logs.copy.success' + }); } else { - // TODO open failed alert + this.notificationService.addNotification({ + type: 'success', + title: 'logs.copy.title', + message: 'logs.copy.failed' + }); } - // TODO success alert document.body.removeChild(node); } else { - // TODO failed alert + this.notificationService.addNotification({ + type: 'success', + title: 'logs.copy.title', + message: 'logs.copy.notSupported' + }); } }; diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.html index 799b840..2584ccd 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.html +++ b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.html @@ -18,7 +18,8 @@ <div class="modal-backdrop in"></div> <div class="modal in"> <div [ngClass]="{ - 'modal-dialog': true, 'modal-sm': isSmallModal, 'modal-lg': isLargeModal, 'modal-xl': isExtraLargeModal + 'modal-dialog': true, 'modal-sm': isSmallModal, 'modal-lg': isLargeModal, 'modal-xl': isExtraLargeModal, + 'modal-flex-layout': isFlexLayout }"> <div class="modal-content"> <div *ngIf="showHeader" class="modal-header"> diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.less index e88e2a4..326bd6f 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.less +++ b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.less @@ -20,3 +20,16 @@ .modal-xl { width: @large-modal-width; } + +.modal-flex-layout { + .modal-content { + display: flex; + flex-direction: column; + height: 85vh; + overflow: hidden; + .modal-body { + flex-grow: 1; + overflow: auto; + } + } +} diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.ts index a724086..6d31511 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/components/modal/modal.component.ts @@ -103,6 +103,9 @@ export class ModalComponent implements OnInit, AfterViewInit { @Output() close: EventEmitter<any> = new EventEmitter(); + @Input() + isFlexLayout: boolean = false; + show(): void { this.modalElements.show(); } diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/services/notification.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/services/notification.service.ts index 00a32ca..1406b24 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/services/notification.service.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/services/notification.service.ts @@ -22,6 +22,7 @@ import {NotificationsService as Angular2NotificationsService} from 'angular2-not import {Notification} from 'angular2-notifications/src/notification.type'; import {NotificationInterface} from '../interfaces/notification.interface'; +import {TranslateService} from '@ngx-translate/core'; export enum NotificationType { SUCCESS = 'success', @@ -33,12 +34,15 @@ export enum NotificationType { @Injectable() export class NotificationService { - constructor(private notificationService: Angular2NotificationsService) { } + constructor( + private notificationService: Angular2NotificationsService, + private translateService: TranslateService + ) { } addNotification(payload: NotificationInterface): Notification { const {message, title, ...config} = payload; const method: string = typeof this.notificationService[config.type] === 'function' ? config.type : 'info'; - return this.notificationService[method](title, message, config); + return this.notificationService[method](this.translateService.instant(title), this.translateService.instant(message), config); } } 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 4cb08cc..98b16df 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json +++ b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json @@ -170,6 +170,10 @@ "logs.addToQuery": "Add to Query", "logs.excludeFromQuery": "Exclude from Query", "logs.copy": "Copy", + "logs.copy.title": "Copy", + "logs.copy.success": "The log has been copied to the clipboard.", + "logs.copy.failed": "Error at copying the log into the clipboard.", + "logs.copy.notSupported": "This function is not supported in this browser.", "logs.open": "Open Log", "logs.context": "Context", "logs.loadMore": "Load more", -- To stop receiving notification emails like this one, please contact ababiic...@apache.org.