Merge pull request #5156 from tsiegleauq/dymanic-ngrid-index-jumping

Scroll to previous offset rather than index
This commit is contained in:
Emanuel Schütze 2019-12-09 11:07:23 +01:00 committed by GitHub
commit 50ce5e7d61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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>