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:
parent
0bb2175f79
commit
01b626d3e7
@ -10,12 +10,13 @@ import {
|
|||||||
ViewChild,
|
ViewChild,
|
||||||
ViewEncapsulation
|
ViewEncapsulation
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { NavigationStart, Router } from '@angular/router';
|
||||||
|
|
||||||
import { columnFactory, createDS, DataSourcePredicate, PblDataSource, PblNgridComponent } from '@pebula/ngrid';
|
import { columnFactory, createDS, DataSourcePredicate, PblDataSource, PblNgridComponent } from '@pebula/ngrid';
|
||||||
import { PblColumnDefinition, PblColumnFactory, PblNgridColumnSet } from '@pebula/ngrid/lib/table';
|
import { PblColumnDefinition, PblColumnFactory, PblNgridColumnSet } from '@pebula/ngrid/lib/table';
|
||||||
import { PblNgridDataMatrixRow } from '@pebula/ngrid/target-events';
|
import { PblNgridDataMatrixRow } from '@pebula/ngrid/target-events';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
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 { OperatorService, Permission } from 'app/core/core-services/operator.service';
|
||||||
import { StorageService } from 'app/core/core-services/storage.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(
|
public constructor(
|
||||||
private operator: OperatorService,
|
private operator: OperatorService,
|
||||||
vp: ViewportService,
|
vp: ViewportService,
|
||||||
|
router: Router,
|
||||||
private store: StorageService,
|
private store: StorageService,
|
||||||
private cd: ChangeDetectorRef
|
private cd: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
@ -393,6 +395,12 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
|
|||||||
}
|
}
|
||||||
this.isMobile = mobile;
|
this.isMobile = mobile;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.subs.push(
|
||||||
|
router.events.pipe(filter(event => event instanceof NavigationStart)).subscribe(() => {
|
||||||
|
this.saveScrollOffset();
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ngOnInit(): Promise<void> {
|
public async ngOnInit(): Promise<void> {
|
||||||
@ -400,8 +408,9 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
|
|||||||
await this.restoreSearchQuery();
|
await this.restoreSearchQuery();
|
||||||
this.createDataSource();
|
this.createDataSource();
|
||||||
this.changeRowHeight();
|
this.changeRowHeight();
|
||||||
this.scrollToPreviousPosition();
|
|
||||||
this.cd.detectChanges();
|
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
|
* @param key the key of the scroll index
|
||||||
* @returns the scroll index or 0 if not found
|
* @returns the scroll index or 0 if not found
|
||||||
*/
|
*/
|
||||||
public async getScrollIndex(key: string): Promise<number> {
|
private async getScrollOffset(key: string): Promise<number> {
|
||||||
const scrollIndex = await this.store.get<number>(`scroll_${key}`);
|
const scrollOffset = await this.store.get<number>(`scroll_${key}`);
|
||||||
return scrollIndex ? scrollIndex : 0;
|
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
|
* 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) {
|
if (this.ngrid) {
|
||||||
const scrollIndex = await this.getScrollIndex(this.listStorageKey);
|
const scrollIndex = await this.getScrollOffset(this.listStorageKey);
|
||||||
this.ngrid.viewport.scrollToIndex(scrollIndex);
|
this.ngrid.viewport.scrollToOffset(scrollIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,12 +29,7 @@
|
|||||||
>
|
>
|
||||||
<!-- Title column -->
|
<!-- Title column -->
|
||||||
<div *pblNgridCellDef="'title'; row as item; rowContext as rowContext" class="cell-slot fill">
|
<div *pblNgridCellDef="'title'; row as item; rowContext as rowContext" class="cell-slot fill">
|
||||||
<a
|
<a class="detail-link" [routerLink]="getDetailUrl(item)" *ngIf="!isMultiSelect"></a>
|
||||||
class="detail-link"
|
|
||||||
(click)="saveScrollIndex('agenda', rowContext.identity)"
|
|
||||||
[routerLink]="getDetailUrl(item)"
|
|
||||||
*ngIf="!isMultiSelect"
|
|
||||||
></a>
|
|
||||||
<div [ngStyle]="{ 'margin-left': item.level * 25 + 'px' }" class="innerTable">
|
<div [ngStyle]="{ 'margin-left': item.level * 25 + 'px' }" class="innerTable">
|
||||||
<os-icon-container [noWrap]="true" [icon]="item.closed ? 'check' : null" size="large">
|
<os-icon-container [noWrap]="true" [icon]="item.closed ? 'check' : null" size="large">
|
||||||
<div class="ellipsis-overflow">
|
<div class="ellipsis-overflow">
|
||||||
|
@ -33,12 +33,7 @@
|
|||||||
>
|
>
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div *pblNgridCellDef="'title'; row as assignment; rowContext as rowContext" class="cell-slot fill">
|
<div *pblNgridCellDef="'title'; row as assignment; rowContext as rowContext" class="cell-slot fill">
|
||||||
<a
|
<a class="detail-link" [routerLink]="assignment.id" *ngIf="!isMultiSelect"></a>
|
||||||
class="detail-link"
|
|
||||||
(click)="saveScrollIndex('assignments', rowContext.identity)"
|
|
||||||
[routerLink]="assignment.id"
|
|
||||||
*ngIf="!isMultiSelect"
|
|
||||||
></a>
|
|
||||||
<div>
|
<div>
|
||||||
<div class="title-line ellipsis-overflow">
|
<div class="title-line ellipsis-overflow">
|
||||||
{{ assignment.getListTitle() }}
|
{{ assignment.getListTitle() }}
|
||||||
|
@ -106,14 +106,4 @@ export abstract class BaseListViewComponent<V extends BaseViewModel> extends Bas
|
|||||||
public get isMultiSelect(): boolean {
|
public get isMultiSelect(): boolean {
|
||||||
return this._multiSelectMode;
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,7 @@
|
|||||||
>
|
>
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div *pblNgridCellDef="'title'; row as category; rowContext as rowContext" class="cell-slot fill">
|
<div *pblNgridCellDef="'title'; row as category; rowContext as rowContext" class="cell-slot fill">
|
||||||
<a
|
<a class="detail-link" [routerLink]="category.id"></a>
|
||||||
class="detail-link"
|
|
||||||
[routerLink]="category.id"
|
|
||||||
(click)="saveScrollIndex('category', rowContext.identity)"
|
|
||||||
></a>
|
|
||||||
<div [style.margin-left]="getMargin(category)">{{ category.prefixedName }}</div>
|
<div [style.margin-left]="getMargin(category)">{{ category.prefixedName }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -18,14 +18,14 @@
|
|||||||
>
|
>
|
||||||
<!-- Title column -->
|
<!-- Title column -->
|
||||||
<div *pblNgridCellDef="'title'; value as title; row as block; rowContext as rowContext" class="cell-slot fill">
|
<div *pblNgridCellDef="'title'; value as title; row as block; rowContext as rowContext" class="cell-slot fill">
|
||||||
<a
|
<a class="detail-link" [routerLink]="block.id" *ngIf="!isMultiSelect"></a>
|
||||||
class="detail-link"
|
|
||||||
(click)="saveScrollIndex('motionBlock', rowContext.identity)"
|
|
||||||
[routerLink]="block.id"
|
|
||||||
*ngIf="!isMultiSelect"
|
|
||||||
></a>
|
|
||||||
<div class="innerTable">
|
<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">
|
<div class="ellipsis-overflow">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,12 +63,7 @@
|
|||||||
|
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div *pblNgridCellDef="'title'; row as motion; rowContext as rowContext" class="cell-slot fill">
|
<div *pblNgridCellDef="'title'; row as motion; rowContext as rowContext" class="cell-slot fill">
|
||||||
<a
|
<a class="detail-link" [routerLink]="motion.id" *ngIf="!isMultiSelect"></a>
|
||||||
class="detail-link"
|
|
||||||
(click)="saveScrollIndex('motion', rowContext.identity)"
|
|
||||||
[routerLink]="motion.id"
|
|
||||||
*ngIf="!isMultiSelect"
|
|
||||||
></a>
|
|
||||||
<div class="column-title innerTable">
|
<div class="column-title innerTable">
|
||||||
<div class="title-line ellipsis-overflow">
|
<div class="title-line ellipsis-overflow">
|
||||||
<!-- Is Favorite -->
|
<!-- Is Favorite -->
|
||||||
|
@ -15,12 +15,7 @@
|
|||||||
>
|
>
|
||||||
<!-- Name column -->
|
<!-- Name column -->
|
||||||
<div *pblNgridCellDef="'name'; value as name; row as workflow; rowContext as rowContext" class="cell-slot fill">
|
<div *pblNgridCellDef="'name'; value as name; row as workflow; rowContext as rowContext" class="cell-slot fill">
|
||||||
<a
|
<a class="detail-link" [routerLink]="workflow.id" *ngIf="!isMultiSelect"></a>
|
||||||
class="detail-link"
|
|
||||||
(click)="saveScrollIndex('workflow', rowContext.identity)"
|
|
||||||
[routerLink]="workflow.id"
|
|
||||||
*ngIf="!isMultiSelect"
|
|
||||||
></a>
|
|
||||||
<div>{{ name | translate }}</div>
|
<div>{{ name | translate }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -29,12 +29,7 @@
|
|||||||
>
|
>
|
||||||
<!-- Name column -->
|
<!-- Name column -->
|
||||||
<div *pblNgridCellDef="'short_name'; value as name; row as user; rowContext as rowContext" class="cell-slot fill">
|
<div *pblNgridCellDef="'short_name'; value as name; row as user; rowContext as rowContext" class="cell-slot fill">
|
||||||
<a
|
<a class="detail-link" [routerLink]="user.id" *ngIf="!isMultiSelect"></a>
|
||||||
class="detail-link"
|
|
||||||
(click)="saveScrollIndex('user', rowContext.identity)"
|
|
||||||
[routerLink]="user.id"
|
|
||||||
*ngIf="!isMultiSelect"
|
|
||||||
></a>
|
|
||||||
<div class="nameCell">
|
<div class="nameCell">
|
||||||
<span>{{ name }}</span>
|
<span>{{ name }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -89,7 +84,9 @@
|
|||||||
comment
|
comment
|
||||||
</mat-icon>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user