All files / app/directives pagination-href.directive.ts

36.84% Statements 35/95
100% Branches 0/0
0% Functions 0/5
36.84% Lines 35/95

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 961x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x         1x 1x                           1x 1x         1x 1x                                                         1x 1x                       1x  
import { isPlatformBrowser } from '@angular/common';
import { AfterViewInit, Directive, ElementRef, inject, Input, OnDestroy, PLATFORM_ID, Renderer2 } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
 
export interface HasPaginationInfo {
	currentPage: number;
	totalPages: number;
}
@Directive({
	selector: '[grtAddPaginationHrefs]',
})
export class PaginationHrefDirective implements AfterViewInit, OnDestroy {
	private el = inject(ElementRef);
	private renderer = inject(Renderer2);
	private router = inject(Router);
	private route = inject(ActivatedRoute);
 
	private observer!: MutationObserver;
	isBrowser: boolean;
 
	@Input('grtAddPaginationHrefs') paginationData!: {
		currentPage: number;
		totalPages: number;
	};
 
	constructor() {
		const platformId = inject(PLATFORM_ID);

		this.isBrowser = isPlatformBrowser(platformId);
	}
 
	ngAfterViewInit() {
		if (this.isBrowser) {
			this.observer = new MutationObserver(() => {
				this.addHrefs();
			});

			this.observer.observe(this.el.nativeElement, {
				childList: true,
				subtree: true,
			});

			this.addHrefs();
		}
	}
 
	ngOnDestroy() {
		if (this.isBrowser) {
			this.observer?.disconnect();
		}
	}
 
	private addHrefs() {
		if (!this.paginationData) return;

		const currentPage = this.paginationData.currentPage;
		const totalPages = this.paginationData.totalPages;

		const paginationElement = this.el.nativeElement;
		const links = paginationElement.querySelectorAll('a.page-link');

		links.forEach((link: HTMLAnchorElement) => {
			const pageText = link.textContent?.trim();
			let targetPage: number;

			if (pageText === 'Previous') {
				targetPage = currentPage - 1;
			} else if (pageText === 'Next') {
				targetPage = currentPage + 1;
			} else if (pageText && !isNaN(parseInt(pageText))) {
				targetPage = parseInt(pageText);
			} else {
				return;
			}

			if (targetPage >= 1 && targetPage <= totalPages) {
				const href = this.generateHref(targetPage);
				this.renderer.setAttribute(link, 'href', href);
			}
		});
	}
 
	private generateHref(page: number): string {
		const baseUrl = this.router.url.split('?')[0];
		const queryParams = { ...this.route.snapshot.queryParams };

		queryParams['number'] = page.toString();

		const queryString = Object.keys(queryParams)
			.map((key) => `${key}=${encodeURIComponent(queryParams[key])}`)
			.join('&');

		return `${baseUrl}?${queryString}`;
	}
}