Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AMBARI-24551] [Log Search UI] get rid of redundant requests after undoing or redoing several history steps #5

Merged
merged 10 commits into from Nov 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 10 additions & 9 deletions ambari-logsearch-web/src/app/app-routing.module.ts
Expand Up @@ -16,14 +16,15 @@
* limitations under the License.
*/

import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {LogsContainerComponent} from '@app/components/logs-container/logs-container.component';
import {LoginFormComponent} from '@app/components/login-form/login-form.component';
import {AuthGuardService} from '@app/services/auth-guard.service';
import {TabGuard} from '@app/services/tab.guard';
import {LogsBreadcrumbsResolverService} from '@app/services/logs-breadcrumbs-resolver.service';
import {LoginScreenGuardService} from '@app/services/login-screen-guard.service';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LogsContainerComponent } from '@app/components/logs-container/logs-container.component';
import { LoginFormComponent } from '@app/components/login-form/login-form.component';
import { AuthGuardService } from '@app/services/auth-guard.service';
import { TabGuard } from '@app/services/tab.guard';
import { FilterHistoryIndexGuard } from '@app/services/filter-history.guard';
import { LogsBreadcrumbsResolverService } from '@app/services/logs-breadcrumbs-resolver.service';
import { LoginScreenGuardService } from '@app/services/login-screen-guard.service';

const appRoutes: Routes = [{
path: 'login',
Expand All @@ -43,7 +44,7 @@ const appRoutes: Routes = [{
resolve: {
breadcrumbs: LogsBreadcrumbsResolverService
},
canActivate: [AuthGuardService, TabGuard]
canActivate: [AuthGuardService, TabGuard, FilterHistoryIndexGuard]
}, {
path: 'logs',
redirectTo: '/logs/serviceLogs',
Expand Down
8 changes: 5 additions & 3 deletions ambari-logsearch-web/src/app/app.module.ts
Expand Up @@ -59,7 +59,6 @@ import {ServiceLogsFieldsService} from '@app/services/storage/service-logs-field
import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.service';
import {TabsService} from '@app/services/storage/tabs.service';
import {AuthService} from '@app/services/auth.service';
import {HistoryManagerService} from '@app/services/history-manager.service';
import {reducer} from '@app/services/storage/reducers.service';

import {AppComponent} from '@app/components/app.component';
Expand Down Expand Up @@ -109,13 +108,15 @@ import {ClusterSelectionService} from '@app/services/storage/cluster-selection.s
import {TranslateService as AppTranslateService} from '@app/services/translate.service';
import {RoutingUtilsService} from '@app/services/routing-utils.service';
import {TabGuard} from '@app/services/tab.guard';
import {FilterHistoryIndexGuard} from '@app/services/filter-history.guard';
import {LogsBreadcrumbsResolverService} from '@app/services/logs-breadcrumbs-resolver.service';
import {LogsFilteringUtilsService} from '@app/services/logs-filtering-utils.service';
import {LogsStateService} from '@app/services/storage/logs-state.service';
import {LoginScreenGuardService} from '@app/services/login-screen-guard.service';

import { AuthEffects } from '@app/store/effects/auth.effects';
import { NotificationEffects } from '@app/store/effects/notification.effects';
import { FilterHistoryManagerComponent } from './components/filter-history-manager/filter-history-manager.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -158,7 +159,8 @@ import { NotificationEffects } from '@app/store/effects/notification.effects';
TimerSecondsPipe,
ComponentLabelPipe,
BreadcrumbsComponent,
ClusterFilterComponent
ClusterFilterComponent,
FilterHistoryManagerComponent
],
imports: [
BrowserModule,
Expand Down Expand Up @@ -217,10 +219,10 @@ import { NotificationEffects } from '@app/store/effects/notification.effects';
AuditLogsFieldsService,
TabsService,
TabGuard,
FilterHistoryIndexGuard,
LogsBreadcrumbsResolverService,
AuthService,
AuthGuardService,
HistoryManagerService,
ClusterSelectionService,
LogsFilteringUtilsService,
LogsStateService,
Expand Down
@@ -0,0 +1,23 @@
/**
* 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.
*/

export interface FilterUrlParamChange {
previousPath?: string | null;
currentPath: string;
time?: Date;
}
2 changes: 2 additions & 0 deletions ambari-logsearch-web/src/app/classes/models/store.ts
Expand Up @@ -35,6 +35,7 @@ import { LogsState } from '@app/classes/models/logs-state';
import { DataAvaibilityStatesModel } from '@app/modules/app-load/models/data-availability-state.model';

import * as auth from '@app/store/reducers/auth.reducers';
import * as filterHistory from '@app/store/reducers/filter-history.reducers';

const storeActions = {
'ARRAY.ADD': 'ADD',
Expand Down Expand Up @@ -71,6 +72,7 @@ export interface AppStore {
logsState: LogsState;
dataAvailabilityStates: DataAvaibilityStatesModel;
auth: auth.State;
filterHistory: filterHistory.FilterHistoryState;
}

export class ModelService {
Expand Down
Expand Up @@ -14,19 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->

<!-- TODO use listClass="history-dropdown" for custom styling -->
<menu-button label="{{'topMenu.undo' | translate}}" [subItems]="undoItems" iconClass="fa fa-arrow-left"
class="history-menu" [class.disabled]="!undoItems.length" [isDisabled]="!undoItems.length"
listClass="history-dropdown" (buttonClick)="undoLatest()" (selectItem)="undo($event)">
</menu-button>
<menu-button label="{{'topMenu.redo' | translate}}" [subItems]="redoItems" iconClass="fa fa-arrow-right"
class="history-menu" [class.disabled]="!redoItems.length" [isDisabled]="!redoItems.length"
listClass="history-dropdown" (buttonClick)="redoLatest()" (selectItem)="redo($event)">
</menu-button>
<menu-button label="{{'topMenu.history' | translate}}" [subItems]="historyItems" iconClass="fa fa-history"
class="history-menu" [class.disabled]="!historyItems.length" [isDisabled]="!historyItems.length"
listClass="history-dropdown" [isRightAlign]="true"></menu-button>
<filter-history-manager></filter-history-manager>
<menu-button label="{{'topMenu.filter' | translate}}" iconClass="fa fa-filter"
(buttonClick)="openLogIndexFilter()"></menu-button>
<menu-button *ngIf="!captureSeconds" label="{{'filter.capture' | translate}}" iconClass="fa fa-caret-right"
Expand Down
Expand Up @@ -19,81 +19,11 @@

:host {
display: block;
menu-button {
/deep/ menu-button {
margin: 0 1em;
/deep/ .stop-icon {
color: @exclude-color;
}
&.history-menu {
/deep/ ul {
li:not(.selection-all) {
margin: 0;
overflow: hidden;
position: relative;
transition: background-color 300ms ease-in, opacity 300ms ease-in, height 100ms 400ms ease-in;
&:before {
border-left: 1px solid darken(@unknown-color, 25%);
bottom: 0;
content: "";
display: block;
left: 12px;
position: absolute;
top: 0;
}
&:after {
background: #fff;
border: 1px solid darken(@unknown-color, 25%);
border-radius: 100%;
content: "";
height: 12px;
left: 7px;
position: absolute;
top: 6px;
transition: background-color 300ms;
width: 12px;
}

.list-item-label.label-container {
border-radius: 3px;
display: flex;
margin: 0 3px 0 25px;
padding: 3px 25px 3px 1em;
.item-label-text {
flex-grow: 1;
padding-right: 1em;
}
/deep/ history-item-controls {
float: none;
justify-self: right;
}
}

&.active > a, &:hover {
color: #262626;
text-decoration: none;
background-color: transparent;
.list-item-label.label-container {
background-color: #f5f5f5;
}
}
}
li:not(.selection-all):first-child {
&:before {
top: 50%;
}
}
li:not(.selection-all):last-child {
&:before {
bottom: 50%;
}
}
li:not(.selection-all):hover {
&:after {
background: @unknown-color;
}
}
}
}
}
/deep/ .modal-body {
min-height: 25vh;
Expand Down
Expand Up @@ -22,14 +22,13 @@ import { ActivatedRoute, Router } from '@angular/router';

import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Subscription } from 'rxjs/Subscription';

import { LogsContainerService } from '@app/services/logs-container.service';
import { HistoryManagerService } from '@app/services/history-manager.service';
import { UserSettingsService } from '@app/services/user-settings.service';
import { ListItem } from '@app/classes/list-item';
import { ClustersService } from '@app/services/storage/clusters.service';
import { UtilsService } from '@app/services/utils.service';
import { Subject } from 'rxjs/Subject';

@Component({
selector: 'action-menu',
Expand Down Expand Up @@ -60,11 +59,10 @@ export class ActionMenuComponent implements OnInit, OnDestroy {

selectedClusterName$: BehaviorSubject<string> = new BehaviorSubject('');

subscriptions: Subscription[] = [];
destroyed$ = new Subject();

constructor(
private logsContainerService: LogsContainerService,
private historyManager: HistoryManagerService,
private settings: UserSettingsService,
private route: ActivatedRoute,
private router: Router,
Expand All @@ -74,27 +72,13 @@ export class ActionMenuComponent implements OnInit, OnDestroy {
}

ngOnInit() {
this.subscriptions.push(
this.selectedClusterName$.subscribe(
(clusterName: string) => this.setModalSubmitDisabled(!(!!clusterName))
)
this.selectedClusterName$.takeUntil(this.destroyed$).subscribe(
(clusterName: string) => this.setModalSubmitDisabled(!clusterName)
);
}

ngOnDestroy() {
this.subscriptions.forEach((subscription: Subscription) => subscription.unsubscribe());
}

get undoItems(): ListItem[] {
return this.historyManager.undoItems;
}

get redoItems(): ListItem[] {
return this.historyManager.redoItems;
}

get historyItems(): ListItem[] {
return this.historyManager.activeHistory;
this.destroyed$.next(true);
}

get captureSeconds(): number {
Expand All @@ -105,26 +89,6 @@ export class ActionMenuComponent implements OnInit, OnDestroy {
this.isModalSubmitDisabled = isDisabled;
}

undoLatest(): void {
if (this.undoItems.length) {
this.historyManager.undo(this.undoItems[0]);
}
}

redoLatest(): void {
if (this.redoItems.length) {
this.historyManager.redo(this.redoItems[0]);
}
}

undo(item: ListItem): void {
this.historyManager.undo(item);
}

redo(item: ListItem): void {
this.historyManager.redo(item);
}

refresh(): void {
this.logsContainerService.loadLogs();
}
Expand Down
4 changes: 4 additions & 0 deletions ambari-logsearch-web/src/app/components/app.component.html
Expand Up @@ -29,4 +29,8 @@ <h1>{{'common.title' | translate}}</h1>
<main-container *ngIf="!(isAuthorized$ | async) || (isBaseDataAvailable$ | async)"></main-container>

<simple-notifications [options]="notificationServiceOptions"></simple-notifications>
<div class="request-indicator" [class.open]="httpClient.requestInProgress | async">
<i class="fa fa-spin fa-gear"></i>
{{ 'common.loading' | translate }}
</div>
</ng-container>
25 changes: 25 additions & 0 deletions ambari-logsearch-web/src/app/components/app.component.less
Expand Up @@ -66,4 +66,29 @@
justify-content: center;
margin: 1rem 0;
}

.request-indicator {
background: rgba(255,255,255,.7);
top: calc(-1 * (3em + .3em));
color: @info-color;
left: 50%;
margin-left: auto;
margin-right: auto;
opacity: .7;
padding: .3em;
position: fixed;
transition: top 500ms ease-in-out;
transform: translateX(-50%);
z-index: 1200;
&.open {
top: 0;
}
// &:before {
// .circle-spinner(1em, 2px, @info-color);
// content: ' ';
// display: inline-block;
// line-height: 1.1em;
// }
}

}
7 changes: 5 additions & 2 deletions ambari-logsearch-web/src/app/components/app.component.ts
Expand Up @@ -29,7 +29,9 @@ import { notificationIcons } from '@modules/shared/services/notification.service
import { Store } from '@ngrx/store';
import { AppStore } from '@app/classes/models/store';
import { AuthorizationStatuses } from '@app/store/reducers/auth.reducers';
import { isAuthorizedSelector, authStatusSelector, isCheckingAuthStatusInProgressSelector } from '@app/store/selectors/auth.selectors';
import { isAuthorizedSelector, selectAuthStatus, isCheckingAuthStatusInProgressSelector } from '@app/store/selectors/auth.selectors';

import { HttpClientService } from '@app/services/http-client.service';

@Component({
selector: 'app-root',
Expand All @@ -44,7 +46,7 @@ export class AppComponent implements OnInit, OnDestroy {
authorizationStatuses = AuthorizationStatuses;

isAuthorized$: Observable<boolean> = this.store.select(isAuthorizedSelector);
authorizationStatus$: Observable<AuthorizationStatuses> = this.store.select(authStatusSelector);
authorizationStatus$: Observable<AuthorizationStatuses> = this.store.select(selectAuthStatus);
isCheckingAuthStatusInProgress$: Observable<boolean> = this.store.select(isCheckingAuthStatusInProgressSelector);
authorizationCode$: Observable<number> = this.appState.getParameter('authorizationCode');
isBaseDataAvailable$: Observable<boolean> = this.appState.getParameter('baseDataSetState')
Expand All @@ -66,6 +68,7 @@ export class AppComponent implements OnInit, OnDestroy {

constructor(
private appState: AppStateService,
public httpClient: HttpClientService,
private store: Store<AppStore>
) {}

Expand Down
Expand Up @@ -128,10 +128,10 @@ export class ClusterFilterComponent implements OnInit, OnDestroy {
.filter((state: DataAvailabilityValues) => state === DataAvailabilityValues.AVAILABLE)
.first()
.subscribe(() => {
this.filterDropdown.updateSelection(clusterSelection);
this.filterDropdown.writeValue(clusterSelection);
});
} else {
this.filterDropdown.updateSelection(null);
this.filterDropdown.clearSelection();
}
}

Expand Down