Scroll to previous offset rather than index

Changes some auto scrolling behavior in our virtual scrolling tables.
Save the scroll offset before any navigation attempt, rather than
saving the index on click.
Should work for every possible navigation action.
This commit is contained in:
Sean 2019-12-06 13:43:09 +01:00
parent 0bb2175f79
commit 01b626d3e7
9 changed files with 41 additions and 68 deletions

View File

@ -10,12 +10,13 @@ import {
ViewChild,
ViewEncapsulation
} from '@angular/core';
import { NavigationStart, Router } from '@angular/router';
import { columnFactory, createDS, DataSourcePredicate, PblDataSource, PblNgridComponent } from '@pebula/ngrid';
import { PblColumnDefinition, PblColumnFactory, PblNgridColumnSet } from '@pebula/ngrid/lib/table';
import { PblNgridDataMatrixRow } from '@pebula/ngrid/target-events';
import { Observable, Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { distinctUntilChanged, filter } from 'rxjs/operators';
import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service';
@ -384,6 +385,7 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
public constructor(
private operator: OperatorService,
vp: ViewportService,
router: Router,
private store: StorageService,
private cd: ChangeDetectorRef
) {
@ -393,6 +395,12 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
}
this.isMobile = mobile;
});
this.subs.push(
router.events.pipe(filter(event => event instanceof NavigationStart)).subscribe(() => {
this.saveScrollOffset();
})
);
}
public async ngOnInit(): Promise<void> {
@ -400,8 +408,9 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
await this.restoreSearchQuery();
this.createDataSource();
this.changeRowHeight();
this.scrollToPreviousPosition();
this.cd.detectChanges();
// ngrid exists after the first change detection
this.scrollToPreviousPosition();
}
/**
@ -600,9 +609,17 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
* @param key the key of the scroll index
* @returns the scroll index or 0 if not found
*/
public async getScrollIndex(key: string): Promise<number> {
const scrollIndex = await this.store.get<number>(`scroll_${key}`);
return scrollIndex ? scrollIndex : 0;
private async getScrollOffset(key: string): Promise<number> {
const scrollOffset = await this.store.get<number>(`scroll_${key}`);
return scrollOffset ? scrollOffset : 0;
}
/**
* Store the scroll offset
*/
private saveScrollOffset(): void {
const offset = this.ngrid.viewport.measureScrollOffset();
this.store.set(`scroll_${this.listStorageKey}`, offset);
}
/**
@ -626,18 +643,11 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
/**
* Automatically scrolls to a stored scroll position
*
* TODO: Only the position will be stored, not the item.
* Changing the filtering and sorting will confuse the order
*
* TODO: getScrollIndex is not supported by virtual scrolling with the `vScrollAuto` directive.
* Furthermore, dynamic assigning the amount of pixels in vScrollFixed
* does not work, tying the tables to the same hight.
*/
public async scrollToPreviousPosition(): Promise<void> {
private async scrollToPreviousPosition(): Promise<void> {
if (this.ngrid) {
const scrollIndex = await this.getScrollIndex(this.listStorageKey);
this.ngrid.viewport.scrollToIndex(scrollIndex);
const scrollIndex = await this.getScrollOffset(this.listStorageKey);
this.ngrid.viewport.scrollToOffset(scrollIndex);
}
}

View File

@ -29,12 +29,7 @@
>
<!-- Title column -->
<div *pblNgridCellDef="'title'; row as item; rowContext as rowContext" class="cell-slot fill">
<a
class="detail-link"
(click)="saveScrollIndex('agenda', rowContext.identity)"
[routerLink]="getDetailUrl(item)"
*ngIf="!isMultiSelect"
></a>
<a class="detail-link" [routerLink]="getDetailUrl(item)" *ngIf="!isMultiSelect"></a>
<div [ngStyle]="{ 'margin-left': item.level * 25 + 'px' }" class="innerTable">
<os-icon-container [noWrap]="true" [icon]="item.closed ? 'check' : null" size="large">
<div class="ellipsis-overflow">

View File

@ -33,12 +33,7 @@
>
<!-- Title -->
<div *pblNgridCellDef="'title'; row as assignment; rowContext as rowContext" class="cell-slot fill">
<a
class="detail-link"
(click)="saveScrollIndex('assignments', rowContext.identity)"
[routerLink]="assignment.id"
*ngIf="!isMultiSelect"
></a>
<a class="detail-link" [routerLink]="assignment.id" *ngIf="!isMultiSelect"></a>
<div>
<div class="title-line ellipsis-overflow">
{{ assignment.getListTitle() }}

View File

@ -106,14 +106,4 @@ export abstract class BaseListViewComponent<V extends BaseViewModel> extends Bas
public get isMultiSelect(): boolean {
return this._multiSelectMode;
}
/**
* Saves the scroll index in the storage
*
* @param key
* @param index
*/
public saveScrollIndex(key: string, index: number): void {
this.storage.set(`scroll_${key}`, index);
}
}

View File

@ -25,11 +25,7 @@
>
<!-- Title -->
<div *pblNgridCellDef="'title'; row as category; rowContext as rowContext" class="cell-slot fill">
<a
class="detail-link"
[routerLink]="category.id"
(click)="saveScrollIndex('category', rowContext.identity)"
></a>
<a class="detail-link" [routerLink]="category.id"></a>
<div [style.margin-left]="getMargin(category)">{{ category.prefixedName }}</div>
</div>

View File

@ -18,14 +18,14 @@
>
<!-- Title column -->
<div *pblNgridCellDef="'title'; value as title; row as block; rowContext as rowContext" class="cell-slot fill">
<a
class="detail-link"
(click)="saveScrollIndex('motionBlock', rowContext.identity)"
[routerLink]="block.id"
*ngIf="!isMultiSelect"
></a>
<a class="detail-link" [routerLink]="block.id" *ngIf="!isMultiSelect"></a>
<div class="innerTable">
<os-icon-container [noWrap]="true" [icon]="block.internal ? 'lock' : null" size="large" [matTooltip]="Internal">
<os-icon-container
[noWrap]="true"
[icon]="block.internal ? 'lock' : null"
size="large"
[matTooltip]="Internal"
>
<div class="ellipsis-overflow">
{{ title }}
</div>

View File

@ -63,12 +63,7 @@
<!-- Title -->
<div *pblNgridCellDef="'title'; row as motion; rowContext as rowContext" class="cell-slot fill">
<a
class="detail-link"
(click)="saveScrollIndex('motion', rowContext.identity)"
[routerLink]="motion.id"
*ngIf="!isMultiSelect"
></a>
<a class="detail-link" [routerLink]="motion.id" *ngIf="!isMultiSelect"></a>
<div class="column-title innerTable">
<div class="title-line ellipsis-overflow">
<!-- Is Favorite -->

View File

@ -15,12 +15,7 @@
>
<!-- Name column -->
<div *pblNgridCellDef="'name'; value as name; row as workflow; rowContext as rowContext" class="cell-slot fill">
<a
class="detail-link"
(click)="saveScrollIndex('workflow', rowContext.identity)"
[routerLink]="workflow.id"
*ngIf="!isMultiSelect"
></a>
<a class="detail-link" [routerLink]="workflow.id" *ngIf="!isMultiSelect"></a>
<div>{{ name | translate }}</div>
</div>

View File

@ -29,12 +29,7 @@
>
<!-- Name column -->
<div *pblNgridCellDef="'short_name'; value as name; row as user; rowContext as rowContext" class="cell-slot fill">
<a
class="detail-link"
(click)="saveScrollIndex('user', rowContext.identity)"
[routerLink]="user.id"
*ngIf="!isMultiSelect"
></a>
<a class="detail-link" [routerLink]="user.id" *ngIf="!isMultiSelect"></a>
<div class="nameCell">
<span>{{ name }}</span>
</div>
@ -89,7 +84,9 @@
comment
</mat-icon>
<os-icon-container *ngIf="user.isSamlUser" icon="device_hub"><span translate>Is SAML user</span></os-icon-container>
<os-icon-container *ngIf="user.isSamlUser" icon="device_hub"
><span translate>Is SAML user</span></os-icon-container
>
</div>
</div>