Add pagination to Lightning nodes list and fix overflow
This commit is contained in:
		
							parent
							
								
									035068a72e
								
							
						
					
					
						commit
						17697e669a
					
				@ -64,8 +64,8 @@
 | 
				
			|||||||
        <th class="channels text-right" i18n="lightning.channels">Channels</th>
 | 
					        <th class="channels text-right" i18n="lightning.channels">Channels</th>
 | 
				
			||||||
        <th class="city text-right" i18n="lightning.location">Location</th>
 | 
					        <th class="city text-right" i18n="lightning.location">Location</th>
 | 
				
			||||||
      </thead>
 | 
					      </thead>
 | 
				
			||||||
      <tbody *ngIf="nodes$ | async as countryNodes; else skeleton">
 | 
					      <tbody *ngIf="nodesPagination$ | async as countryNodes; else skeleton">
 | 
				
			||||||
        <tr *ngFor="let node of countryNodes.nodes; let i= index; trackBy: trackByPublicKey">
 | 
					        <tr *ngFor="let node of countryNodes; let i= index; trackBy: trackByPublicKey">
 | 
				
			||||||
          <td class="alias text-left text-truncate">
 | 
					          <td class="alias text-left text-truncate">
 | 
				
			||||||
            <a [routerLink]="['/lightning/node/' | relativeUrl, node.public_key]">{{ node.alias }}</a>
 | 
					            <a [routerLink]="['/lightning/node/' | relativeUrl, node.public_key]">{{ node.alias }}</a>
 | 
				
			||||||
          </td>
 | 
					          </td>
 | 
				
			||||||
@ -116,5 +116,10 @@
 | 
				
			|||||||
      </ng-template>
 | 
					      </ng-template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </table>
 | 
					    </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <ngb-pagination *ngIf="nodes$ | async as countryNodes" class="pagination-container float-right mt-2" [class]="isLoading ? 'disabled' : ''"
 | 
				
			||||||
 | 
					        [collectionSize]="countryNodes.nodes.length" [rotate]="true" [maxSize]="maxSize" [pageSize]="pageSize" [(page)]="page"
 | 
				
			||||||
 | 
					        (pageChange)="pageChange(page)" [boundaryLinks]="true" [ellipses]="false">
 | 
				
			||||||
 | 
					      </ngb-pagination>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -22,14 +22,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.timestamp-first {
 | 
					.timestamp-first {
 | 
				
			||||||
  width: 20%;
 | 
					  width: 20%;
 | 
				
			||||||
  @media (max-width: 576px) {
 | 
					  @media (max-width: 1060px) {
 | 
				
			||||||
    display: none
 | 
					    display: none
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.timestamp-update {
 | 
					.timestamp-update {
 | 
				
			||||||
  width: 16%;
 | 
					  width: 16%;
 | 
				
			||||||
  @media (max-width: 576px) {
 | 
					  @media (max-width: 1060px) {
 | 
				
			||||||
    display: none
 | 
					    display: none
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -50,7 +50,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.city {
 | 
					.city {
 | 
				
			||||||
  max-width: 150px;
 | 
					  max-width: 150px;
 | 
				
			||||||
  @media (max-width: 576px) {
 | 
					  @media (max-width: 675px) {
 | 
				
			||||||
    display: none
 | 
					    display: none
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
 | 
					import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
 | 
				
			||||||
import { ActivatedRoute } from '@angular/router';
 | 
					import { ActivatedRoute } from '@angular/router';
 | 
				
			||||||
import { map, Observable, share } from 'rxjs';
 | 
					import { BehaviorSubject, combineLatest, map, Observable, share, tap } from 'rxjs';
 | 
				
			||||||
import { ApiService } from '../../services/api.service';
 | 
					import { ApiService } from '../../services/api.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
import { getFlagEmoji } from '../../shared/common.utils';
 | 
					import { getFlagEmoji } from '../../shared/common.utils';
 | 
				
			||||||
@ -15,6 +15,12 @@ import { GeolocationData } from '../../shared/components/geolocation/geolocation
 | 
				
			|||||||
export class NodesPerCountry implements OnInit {
 | 
					export class NodesPerCountry implements OnInit {
 | 
				
			||||||
  nodes$: Observable<any>;
 | 
					  nodes$: Observable<any>;
 | 
				
			||||||
  country: {name: string, flag: string};
 | 
					  country: {name: string, flag: string};
 | 
				
			||||||
 | 
					  nodesPagination$: Observable<any>;
 | 
				
			||||||
 | 
					  startingIndexSubject: BehaviorSubject<number> = new BehaviorSubject(0);
 | 
				
			||||||
 | 
					  page = 1;
 | 
				
			||||||
 | 
					  pageSize = 15;
 | 
				
			||||||
 | 
					  maxSize = window.innerWidth <= 767.98 ? 3 : 5;
 | 
				
			||||||
 | 
					  isLoading = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  skeletonLines: number[] = [];
 | 
					  skeletonLines: number[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -23,7 +29,7 @@ export class NodesPerCountry implements OnInit {
 | 
				
			|||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
    private route: ActivatedRoute,
 | 
					    private route: ActivatedRoute,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    for (let i = 0; i < 20; ++i) {
 | 
					    for (let i = 0; i < this.pageSize; ++i) {
 | 
				
			||||||
      this.skeletonLines.push(i);
 | 
					      this.skeletonLines.push(i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -31,6 +37,7 @@ export class NodesPerCountry implements OnInit {
 | 
				
			|||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    this.nodes$ = this.apiService.getNodeForCountry$(this.route.snapshot.params.country)
 | 
					    this.nodes$ = this.apiService.getNodeForCountry$(this.route.snapshot.params.country)
 | 
				
			||||||
      .pipe(
 | 
					      .pipe(
 | 
				
			||||||
 | 
					        tap(() => this.isLoading = true),
 | 
				
			||||||
        map(response => {
 | 
					        map(response => {
 | 
				
			||||||
          this.seoService.setTitle($localize`Lightning nodes in ${response.country.en}`);
 | 
					          this.seoService.setTitle($localize`Lightning nodes in ${response.country.en}`);
 | 
				
			||||||
          this.seoService.setDescription($localize`:@@meta.description.lightning.nodes-country:Explore all the Lightning nodes hosted in ${response.country.en} and see an overview of each node's capacity, number of open channels, and more.`);
 | 
					          this.seoService.setDescription($localize`:@@meta.description.lightning.nodes-country:Explore all the Lightning nodes hosted in ${response.country.en} and see an overview of each node's capacity, number of open channels, and more.`);
 | 
				
			||||||
@ -87,11 +94,21 @@ export class NodesPerCountry implements OnInit {
 | 
				
			|||||||
            ispCount: Object.keys(isps).length
 | 
					            ispCount: Object.keys(isps).length
 | 
				
			||||||
          };
 | 
					          };
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
 | 
					        tap(() => this.isLoading = false),
 | 
				
			||||||
        share()
 | 
					        share()
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.nodesPagination$ = combineLatest([this.nodes$, this.startingIndexSubject]).pipe(
 | 
				
			||||||
 | 
					      map(([response, startingIndex]) => response.nodes.slice(startingIndex, startingIndex + this.pageSize))
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  trackByPublicKey(index: number, node: any): string {
 | 
					  trackByPublicKey(index: number, node: any): string {
 | 
				
			||||||
    return node.public_key;
 | 
					    return node.public_key;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pageChange(page: number): void {
 | 
				
			||||||
 | 
					    this.startingIndexSubject.next((page - 1) * this.pageSize);
 | 
				
			||||||
 | 
					    this.page = page;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -61,8 +61,8 @@
 | 
				
			|||||||
        <th class="channels text-right" i18n="lightning.channels">Channels</th>
 | 
					        <th class="channels text-right" i18n="lightning.channels">Channels</th>
 | 
				
			||||||
        <th class="city text-right" i18n="lightning.location">Location</th>
 | 
					        <th class="city text-right" i18n="lightning.location">Location</th>
 | 
				
			||||||
      </thead>
 | 
					      </thead>
 | 
				
			||||||
      <tbody *ngIf="nodes$ | async as ispNodes; else skeleton">
 | 
					      <tbody *ngIf="nodesPagination$ | async as ispNodes; else skeleton">
 | 
				
			||||||
        <tr *ngFor="let node of ispNodes.nodes; let i= index; trackBy: trackByPublicKey">
 | 
					        <tr *ngFor="let node of ispNodes; let i= index; trackBy: trackByPublicKey">
 | 
				
			||||||
          <td class="alias text-left text-truncate">
 | 
					          <td class="alias text-left text-truncate">
 | 
				
			||||||
            <a [routerLink]="['/lightning/node/' | relativeUrl, node.public_key]">{{ node.alias }}</a>
 | 
					            <a [routerLink]="['/lightning/node/' | relativeUrl, node.public_key]">{{ node.alias }}</a>
 | 
				
			||||||
          </td>
 | 
					          </td>
 | 
				
			||||||
@ -113,5 +113,10 @@
 | 
				
			|||||||
      </ng-template>
 | 
					      </ng-template>
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    </table>
 | 
					    </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <ngb-pagination *ngIf="nodes$ | async as ispNodes" class="pagination-container float-right mt-2" [class]="isLoading ? 'disabled' : ''"
 | 
				
			||||||
 | 
					        [collectionSize]="ispNodes.nodes.length" [rotate]="true" [maxSize]="maxSize" [pageSize]="pageSize" [(page)]="page"
 | 
				
			||||||
 | 
					        (pageChange)="pageChange(page)" [boundaryLinks]="true" [ellipses]="false">
 | 
				
			||||||
 | 
					      </ngb-pagination>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@
 | 
				
			|||||||
.timestamp-first {
 | 
					.timestamp-first {
 | 
				
			||||||
  width: 20%;
 | 
					  width: 20%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @media (max-width: 576px) {
 | 
					  @media (max-width: 1060px) {
 | 
				
			||||||
    display: none
 | 
					    display: none
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -32,7 +32,7 @@
 | 
				
			|||||||
.timestamp-update {
 | 
					.timestamp-update {
 | 
				
			||||||
  width: 16%;
 | 
					  width: 16%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @media (max-width: 576px) {
 | 
					  @media (max-width: 1060px) {
 | 
				
			||||||
    display: none
 | 
					    display: none
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -56,7 +56,7 @@
 | 
				
			|||||||
.city {
 | 
					.city {
 | 
				
			||||||
  max-width: 150px;
 | 
					  max-width: 150px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @media (max-width: 576px) {
 | 
					  @media (max-width: 675px) {
 | 
				
			||||||
    display: none
 | 
					    display: none
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
 | 
					import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
 | 
				
			||||||
import { ActivatedRoute } from '@angular/router';
 | 
					import { ActivatedRoute } from '@angular/router';
 | 
				
			||||||
import { map, Observable, share } from 'rxjs';
 | 
					import { BehaviorSubject, combineLatest, map, Observable, share, tap } from 'rxjs';
 | 
				
			||||||
import { ApiService } from '../../services/api.service';
 | 
					import { ApiService } from '../../services/api.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
import { getFlagEmoji } from '../../shared/common.utils';
 | 
					import { getFlagEmoji } from '../../shared/common.utils';
 | 
				
			||||||
@ -15,6 +15,12 @@ import { GeolocationData } from '../../shared/components/geolocation/geolocation
 | 
				
			|||||||
export class NodesPerISP implements OnInit {
 | 
					export class NodesPerISP implements OnInit {
 | 
				
			||||||
  nodes$: Observable<any>;
 | 
					  nodes$: Observable<any>;
 | 
				
			||||||
  isp: {name: string, id: number};
 | 
					  isp: {name: string, id: number};
 | 
				
			||||||
 | 
					  nodesPagination$: Observable<any>;
 | 
				
			||||||
 | 
					  startingIndexSubject: BehaviorSubject<number> = new BehaviorSubject(0);
 | 
				
			||||||
 | 
					  page = 1;
 | 
				
			||||||
 | 
					  pageSize = 15;
 | 
				
			||||||
 | 
					  maxSize = window.innerWidth <= 767.98 ? 3 : 5;
 | 
				
			||||||
 | 
					  isLoading = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  skeletonLines: number[] = [];
 | 
					  skeletonLines: number[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -23,7 +29,7 @@ export class NodesPerISP implements OnInit {
 | 
				
			|||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
    private route: ActivatedRoute,
 | 
					    private route: ActivatedRoute,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    for (let i = 0; i < 20; ++i) {
 | 
					    for (let i = 0; i < this.pageSize; ++i) {
 | 
				
			||||||
      this.skeletonLines.push(i);
 | 
					      this.skeletonLines.push(i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -31,6 +37,7 @@ export class NodesPerISP implements OnInit {
 | 
				
			|||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    this.nodes$ = this.apiService.getNodeForISP$(this.route.snapshot.params.isp)
 | 
					    this.nodes$ = this.apiService.getNodeForISP$(this.route.snapshot.params.isp)
 | 
				
			||||||
      .pipe(
 | 
					      .pipe(
 | 
				
			||||||
 | 
					        tap(() => this.isLoading = true),
 | 
				
			||||||
        map(response => {
 | 
					        map(response => {
 | 
				
			||||||
          this.isp = {
 | 
					          this.isp = {
 | 
				
			||||||
            name: response.isp,
 | 
					            name: response.isp,
 | 
				
			||||||
@ -77,11 +84,21 @@ export class NodesPerISP implements OnInit {
 | 
				
			|||||||
            topCountry: topCountry,
 | 
					            topCountry: topCountry,
 | 
				
			||||||
          };
 | 
					          };
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
 | 
					        tap(() => this.isLoading = false),
 | 
				
			||||||
        share()
 | 
					        share()
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.nodesPagination$ = combineLatest([this.nodes$, this.startingIndexSubject]).pipe(
 | 
				
			||||||
 | 
					      map(([response, startingIndex]) => response.nodes.slice(startingIndex, startingIndex + this.pageSize))
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  trackByPublicKey(index: number, node: any): string {
 | 
					  trackByPublicKey(index: number, node: any): string {
 | 
				
			||||||
    return node.public_key;
 | 
					    return node.public_key;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pageChange(page: number): void {
 | 
				
			||||||
 | 
					    this.startingIndexSubject.next((page - 1) * this.pageSize);
 | 
				
			||||||
 | 
					    this.page = page;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user