import { Component , ViewChild , Input , OnChanges , SimpleChanges , AfterViewInit , } from "@angular/core" ; import { MatPaginator , PageEvent } from "@angular/material/paginator" ; import { MatTableDataSource } from "@angular/material/table" ; import { User } from "../../../user/user" ; import { SessionService } from "../../../session/session-service/session.service" ; import { EntityMapperService } from "../../../entity/entity-mapper.service" ; import { UntilDestroy , untilDestroyed } from "@ngneat/until-destroy" ; import { filter } from "rxjs/operators" ; @ UntilDestroy ( ) @ Component ( { selector : "app-list-paginator" , templateUrl : "./list-paginator.component.html" , styleUrls : [ "./list-paginator.component.scss" ] , } ) export class ListPaginatorComponent implements OnChanges , AfterViewInit { readonly pageSizeOptions = [ 10 , 20 , 50 ] ; readonly defaultPageSize = 10 ; @ Input ( ) dataSource : MatTableDataSource < any > ; @ Input ( ) idForSavingPagination : string ; @ ViewChild ( MatPaginator ) paginator : MatPaginator ; user : User ; pageSize = this . defaultPageSize ; currentPageIndex = 0 ; showingAll = false ; sizeBeforeToggling = this . defaultPageSize ; constructor ( private sessionService , private entityMapperService ) { } ngOnChanges ( changes ) { if ( changes . hasOwnProperty ( "idForSavingPagination" ) ) { this . applyUserPaginationSettings ( ) ; } if ( changes . hasOwnProperty ( "dataSource" ) ) { this . dataSource . connect ( ) . pipe ( untilDestroyed ( this ) , filter ( ( updatedDataSource ) => this . showingAll && ! ! this . paginator ) , filter ( ( updatedDataSource ) => updatedDataSource . length > 0 ) ) . subscribe ( ( ) => { this . pageSize = this . dataSource . data . length ; this . paginator . pageSize = this . dataSource . data . length ; } ) ; } } ngAfterViewInit ( ) { this . dataSource . paginator = this . paginator ; } onPaginateChange ( event ) { this . pageSize = event . pageSize ; this . currentPageIndex = event . pageIndex ; if ( this . pageSize !== this . dataSource . data . length ) { this . showingAll = false ; } this . updateUserPaginationSettings ( ) ; } changeAllToggle ( ) { this . showingAll = ! this . showingAll ; if ( this . showingAll ) { this . sizeBeforeToggling = this . pageSize ; this . pageSize = this . dataSource . data . length ; } else { this . pageSize = this . sizeBeforeToggling ; } this . paginator . _changePageSize ( this . pageSize ) ; this . updateUserPaginationSettings ( ) ; } private async applyUserPaginationSettings ( ) { await this . ensureUserIsLoaded ( ) ; const pageSize = this . user . paginatorSettingsPageSize [ this . idForSavingPagination ] ; if ( pageSize ) { if ( pageSize === - 1 ) { this . pageSize = this . dataSource . data . length ; this . showingAll = true ; } else { this . pageSize = pageSize ; } } this . currentPageIndex = this . user . paginatorSettingsPageIndex [ this . idForSavingPagination ] || this . currentPageIndex ; } private async updateUserPaginationSettings ( ) { await this . ensureUserIsLoaded ( ) ; const sizeToBeSaved = this . showingAll ? - 1 : this . pageSize ; const hasChangesToBeSaved = sizeToBeSaved !== this . user . paginatorSettingsPageSize [ this . idForSavingPagination ] ; this . user . paginatorSettingsPageIndex [ this . idForSavingPagination ] = this . currentPageIndex ; this . user . paginatorSettingsPageSize [ this . idForSavingPagination ] = sizeToBeSaved ; if ( hasChangesToBeSaved ) { await this . entityMapperService . save < User > ( this . user ) ; } } private async ensureUserIsLoaded ( ) { if ( ! this . user ) { const currentUser = this . sessionService . getCurrentUser ( ) ; this . user = await this . entityMapperService . load ( User , currentUser . name ) ; } } }