Merge pull request #5156 from tsiegleauq/dymanic-ngrid-index-jumping
Scroll to previous offset rather than index
This commit is contained in:
commit
50ce5e7d61
@ -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