Skip to content
This repository has been archived by the owner on Mar 25, 2023. It is now read-only.

Commit

Permalink
feat(vm-logs): scroll (#1399)
Browse files Browse the repository at this point in the history
* docs: LogView Plugin description corrected

* fix(config): remove outdated config properties (#1365)

* feat(vm-logs): scroll

* fix merge conflict

* fix tests

* fix autoscroll refresh

* move selector
  • Loading branch information
Vladimir Shakhov committed Nov 2, 2018
1 parent d9096e5 commit 7157434
Show file tree
Hide file tree
Showing 22 changed files with 365 additions and 62 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"ng-dynamic-component": "^3.0.0",
"ng2-dragula": "1.5.0",
"ngx-clipboard": "^11.1.7",
"ngx-infinite-scroll": "^6.0.1",
"rxjs": "^6.3.2",
"showdown": "^1.8.4",
"uuid": "^3.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/app/shared/components/list/list.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="detail-list margin-right">
<div id="list-scroll-container" class="detail-list">
<ng-content select="[cs-panels]"></ng-content>
<ng-content select="[cs-list]"></ng-content>
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/app/shared/components/list/list.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';

export const listScrollContainerId = 'list-scroll-container';

@Component({
selector: 'cs-list',
templateUrl: 'list.component.html',
Expand Down
17 changes: 16 additions & 1 deletion src/app/vm-logs/containers/vm-logs-table.container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,33 @@ import { Component } from '@angular/core';
import { select, Store } from '@ngrx/store';
import { State } from '../../reducers';
import * as fromVmLogs from '../redux/vm-logs.reducers';
import { map } from 'rxjs/operators';
import * as vmLogsActions from '../redux/vm-logs.actions';
import { selectIsAutoUpdateWithScroll } from '../redux/selectors/select-is-autoupdate-with-scroll.selector';

@Component({
selector: 'cs-vm-logs-table-container',
template: `
<cs-vm-logs-table
*loading="loading$ | async"
[csScrollToLast]="shouldScrollToLast$ | async"
[vmLogs]="vmLogs$ | async"
[enableShowMore]="enableShowMore$ | async"
(showMoreClicked)="onShowMore()"
></cs-vm-logs-table>`,
})
export class VmLogsTableContainerComponent {
readonly loading$ = this.store.pipe(select(fromVmLogs.isLoading));
readonly vmLogs$ = this.store.pipe(select(fromVmLogs.selectAll));
readonly vmLogs$ = this.store.pipe(select(fromVmLogs.selectScrolledLogs));
readonly enableShowMore$ = this.store.pipe(
select(fromVmLogs.selectAreAllLogsShown),
map(areAllLogsShown => !areAllLogsShown),
);
readonly shouldScrollToLast$ = this.store.pipe(select(selectIsAutoUpdateWithScroll));

constructor(private store: Store<State>) {}

public onShowMore() {
this.store.dispatch(new vmLogsActions.ScrollVmLogs());
}
}
1 change: 1 addition & 0 deletions src/app/vm-logs/models/vm-log.model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface VmLog {
id: string;
timestamp: string;
file: string;
log: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { createSelector } from '@ngrx/store';
import { filterSelectedVmId } from '../vm-logs-vm.reducers';
import { LoadVmLogsRequestParams } from '../../models/load-vm-logs-request-params';
import { filterKeywords, filterNewestFirst, filterSelectedLogFile } from '../vm-logs.reducers';
import { filterSearch, filterNewestFirst, filterSelectedLogFile } from '../vm-logs.reducers';
import * as pickBy from 'lodash/pickBy';
import { selectStartDate, selectEndDate } from '../vm-logs-auto-update.reducers';
import moment = require('moment');

export const loadAutoUpdateVmLogsRequestParams = createSelector(
filterSelectedVmId,
filterKeywords,
filterSearch,
selectStartDate,
selectEndDate,
filterSelectedLogFile,
filterNewestFirst,
(id, keywords, startDate, endDate, logFile, newestFirst): LoadVmLogsRequestParams => {
(id, search, startDate, endDate, logFile, newestFirst): LoadVmLogsRequestParams => {
const fields = {
id,
logFile,
keywords: keywords.map(keyword => keyword.text).join(','),
keywords: search,
startDate:
(startDate &&
moment(startDate)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createSelector } from '@ngrx/store';
import { filterNewestFirst } from '../vm-logs.reducers';
import { selectIsAutoUpdateEnabled } from '../vm-logs-auto-update.reducers';

export const selectIsAutoUpdateWithScroll = createSelector(
selectIsAutoUpdateEnabled,
filterNewestFirst,
(isAutoUpdateEnabled, newestFirst) => isAutoUpdateEnabled && !newestFirst,
);
24 changes: 18 additions & 6 deletions src/app/vm-logs/redux/vm-logs.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export enum VmLogsActionTypes {
DISABLE_AUTO_UPDATE = '[VM Logs] DISABLE_AUTO_UPDATE',
SET_AUTO_UPDATE_START_DATE = '[VM Logs] SET_AUTO_UPDATE_START_DATE',
SET_AUTO_UPDATE_END_DATE = '[VM Logs] SET_AUTO_UPDATE_END_DATE',
SCROLL_VM_LOGS = '[VM Logs] SCROLL_VM_LOGS',
RESET_VM_LOGS_SCROLL = '[VM Logs] RESET_VM_LOGS_SCROLL',
}

export class LoadVmLogsRequest implements Action {
Expand Down Expand Up @@ -63,7 +65,7 @@ export class LoadVmLogFilesRequest implements Action {
export class LoadVmLogFilesResponse implements Action {
readonly type = VmLogsActionTypes.LOAD_VM_LOG_FILES_RESPONSE;

constructor(public payload: VmLogFile[]) {}
constructor(readonly payload: VmLogFile[]) {}
}

export class VmLogsUpdateSearch implements Action {
Expand All @@ -75,7 +77,7 @@ export class VmLogsUpdateSearch implements Action {
export class VmLogsUpdateStartDateTime implements Action {
readonly type = VmLogsActionTypes.VM_LOGS_UPDATE_START_DATE_TIME;

constructor(public payload: DateObject) {}
constructor(readonly payload: DateObject) {}
}

export class VmLogsUpdateStartDate implements Action {
Expand All @@ -93,7 +95,7 @@ export class VmLogsUpdateStartTime implements Action {
export class VmLogsUpdateEndDateTime implements Action {
readonly type = VmLogsActionTypes.VM_LOGS_UPDATE_END_DATE_TIME;

constructor(public payload: DateObject) {}
constructor(readonly payload: DateObject) {}
}

export class VmLogsUpdateEndDate implements Action {
Expand All @@ -111,7 +113,7 @@ export class VmLogsUpdateEndTime implements Action {
export class VmLogsUpdateVmId implements Action {
readonly type = VmLogsActionTypes.VM_LOGS_UPDATE_VM_ID;

constructor(public payload: string) {}
constructor(readonly payload: string) {}
}

export class VmLogsUpdateAccountIds implements Action {
Expand All @@ -133,7 +135,15 @@ export class VmLogsToggleNewestFirst implements Action {
export class VmLogsUpdateLogFile implements Action {
readonly type = VmLogsActionTypes.VM_LOGS_UPDATE_LOG_FILE;

constructor(public payload: string) {}
constructor(readonly payload: string) {}
}

export class ScrollVmLogs implements Action {
readonly type = VmLogsActionTypes.SCROLL_VM_LOGS;
}

export class ResetVmLogsScroll implements Action {
readonly type = VmLogsActionTypes.RESET_VM_LOGS_SCROLL;
}

export class EnableAutoUpdate implements Action {
Expand Down Expand Up @@ -179,4 +189,6 @@ export type Actions =
| EnableAutoUpdate
| DisableAutoUpdate
| SetAutoUpdateStartDate
| SetAutoUpdateEndDate;
| SetAutoUpdateEndDate
| ScrollVmLogs
| ResetVmLogsScroll;
10 changes: 10 additions & 0 deletions src/app/vm-logs/redux/vm-logs.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ export class VmLogsEffects {
),
);

@Effect()
resetScroll$: Observable<Action> = this.actions$.pipe(
ofType(
vmLogsActions.VmLogsActionTypes.ENABLE_AUTO_UPDATE,
vmLogsActions.VmLogsActionTypes.DISABLE_AUTO_UPDATE,
vmLogsActions.VmLogsActionTypes.LOAD_VM_LOGS_REQUEST,
),
map(() => new vmLogsActions.ResetVmLogsScroll()),
);

constructor(
private actions$: Actions,
private router: Router,
Expand Down
3 changes: 3 additions & 0 deletions src/app/vm-logs/redux/vm-logs.reducers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ describe('VM logs reducer', () => {
].forEach(type => {
const logs = [
{
id: 'test-id1',
log: 'test-log1',
timestamp: 'test-timestamp1',
file: 'test-file1',
},
{
id: 'test-id2',
log: 'test-log2',
timestamp: 'test-timestamp2',
file: 'test-file2',
Expand Down Expand Up @@ -85,6 +87,7 @@ describe('VM logs reducer', () => {
ids: ['id1'],
entities: {
id1: {
id: 'id1',
timestamp: 'test1',
log: 'test1',
file: 'test1',
Expand Down
36 changes: 34 additions & 2 deletions src/app/vm-logs/redux/vm-logs.reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface VmLogsFilters {
export interface State extends EntityState<VmLog> {
loading: boolean;
filters: VmLogsFilters;
uiPage: number;
}

export interface VmLogsState {
Expand All @@ -27,12 +28,13 @@ export const vmLogsReducers = {
};

export const adapter: EntityAdapter<VmLog> = createEntityAdapter<VmLog>({
selectId: () => Math.random(),
selectId: vmLog => vmLog.id,
sortComparer: false,
});

export const initialState: State = adapter.getInitialState({
loading: false,
uiPage: 1,
filters: {
selectedLogFile: null,
search: null,
Expand Down Expand Up @@ -61,7 +63,9 @@ export function reducer(state = initialState, action: vmLogsActions.Actions): St
switch (action.type) {
case vmLogsActions.VmLogsActionTypes.ENABLE_AUTO_UPDATE:
case vmLogsActions.VmLogsActionTypes.DISABLE_AUTO_UPDATE: {
return adapter.removeAll(state);
return {
...adapter.removeAll(state),
};
}

case vmLogsActions.VmLogsActionTypes.LOAD_VM_LOGS_REQUEST: {
Expand Down Expand Up @@ -217,6 +221,20 @@ export function reducer(state = initialState, action: vmLogsActions.Actions): St
};
}

case vmLogsActions.VmLogsActionTypes.SCROLL_VM_LOGS: {
return {
...state,
uiPage: state.uiPage + 1,
};
}

case vmLogsActions.VmLogsActionTypes.RESET_VM_LOGS_SCROLL: {
return {
...state,
uiPage: 1,
};
}

default: {
return state;
}
Expand Down Expand Up @@ -254,3 +272,17 @@ export const filterEndTime = createSelector(filters, state => ({
export const filterNewestFirst = createSelector(filters, state => state.newestFirst);

export const filterSelectedLogFile = createSelector(filters, state => state.selectedLogFile);

export const selectUiPage = createSelector(getVmLogsEntitiesState, state => state.uiPage);

const uiPageSize = 100;

export const selectScrolledLogs = createSelector(selectAll, selectUiPage, (logs, uiPage) =>
logs.slice(0, uiPage * uiPageSize),
);

export const selectAreAllLogsShown = createSelector(
selectTotal,
selectUiPage,
(total, uiPage) => uiPage * uiPageSize >= total,
);
35 changes: 35 additions & 0 deletions src/app/vm-logs/vm-logs-table/scroll-to-last.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Directive, Input, AfterViewInit, QueryList, ElementRef, OnDestroy } from '@angular/core';
import { VmLogsTableComponent } from './vm-logs-table.component';
import { Subscription } from 'rxjs';

@Directive({
selector: '[csScrollToLast]',
})
export class ScrollToLastDirective implements AfterViewInit, OnDestroy {
private shouldScrollToLast: boolean;

@Input()
set csScrollToLast(value: boolean) {
this.shouldScrollToLast = value;
}

private focusLastRowSubscription: Subscription;

constructor(private host: VmLogsTableComponent) {}

public ngAfterViewInit() {
this.focusLastRowSubscription = this.host.rows.changes.subscribe(
(rows: QueryList<ElementRef>) => {
if (rows.last && this.shouldScrollToLast) {
rows.last.nativeElement.scrollIntoView();
}
},
);
}

public ngOnDestroy() {
if (this.focusLastRowSubscription) {
this.focusLastRowSubscription.unsubscribe();
}
}
}
13 changes: 10 additions & 3 deletions src/app/vm-logs/vm-logs-table/vm-logs-table.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<ng-container #vmIdSpecified *ngIf=" vmLogs?.length; then vmLogsTable else noVmLogs"></ng-container>
<ng-container #vmIdSpecified *ngIf="vmLogs?.length; then vmLogsTable else noVmLogs"></ng-container>

<ng-template #noVmLogs>
<cs-no-results></cs-no-results>
Expand Down Expand Up @@ -39,8 +39,15 @@
</ng-container>

<mat-header-row *cdkHeaderRowDef="tableColumns"></mat-header-row>
<mat-row *cdkRowDef="let row; columns: tableColumns;"></mat-row>
<mat-row #row *cdkRowDef="let row; columns: tableColumns;"></mat-row>
</mat-table>
<button
class="show-more"
*ngIf="enableShowMore"
mat-button
(click)="onShowMore()"
>
{{ 'LOGS_PAGE.LIST.SHOW_MORE' | translate }}
</button>
</div>
</ng-template>

5 changes: 5 additions & 0 deletions src/app/vm-logs/vm-logs-table/vm-logs-table.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@
.mat-header-cell {
padding-right: 24px;
}

.show-more {
width: 100%;
margin: 10px auto;
}
27 changes: 23 additions & 4 deletions src/app/vm-logs/vm-logs-table/vm-logs-table.component.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import {
Component,
Input,
Output,
EventEmitter,
OnChanges,
SimpleChanges,
ViewChildren,
QueryList,
ElementRef,
} from '@angular/core';
import { VmLog } from '../models/vm-log.model';
import { MatTableDataSource } from '@angular/material';
import { MatTableDataSource, MatRow } from '@angular/material';

@Component({
selector: 'cs-vm-logs-table',
templateUrl: 'vm-logs-table.component.html',
styleUrls: ['vm-logs-table.component.scss'],
})
export class VmLogsTableComponent implements OnChanges {
public tableColumns = ['date', 'logFile', 'text'];
public dataSource: MatTableDataSource<VmLog>;
@Input()
public vmLogs: VmLog[];

public tableColumns = ['date', 'logFile', 'text'];
@Input()
public enableShowMore: boolean;
@Output()
public showMoreClicked = new EventEmitter();
@ViewChildren(MatRow, { read: ElementRef })
public rows: QueryList<ElementRef>;

constructor() {
this.dataSource = new MatTableDataSource<VmLog>([]);
Expand All @@ -24,4 +39,8 @@ export class VmLogsTableComponent implements OnChanges {
this.dataSource.data = vmLogs.currentValue;
}
}

public onShowMore() {
this.showMoreClicked.emit();
}
}
Loading

0 comments on commit 7157434

Please sign in to comment.