UNPKG

@progress/sitefinity-nextjs-sdk

Version:

Provides OOB widgets developed using the Next.js framework, which includes an abstraction layer for Sitefinity communication. Additionally, it offers an expanded API, typings, and tools for further development and integration.

146 lines (145 loc) 7.11 kB
import { notFound } from 'next/navigation'; import { PagerMode } from '../common/page-mode'; import { setQueryParams } from '../common/query-params'; export class PagerViewModel { static PageNumberDefaultTemplate = '-page-{{pageNumber}}-'; static PageNumberDefaultQueryTemplate = 'page'; ProcessedUrlSegments = []; CurrentPage; StartPageIndex; EndPageIndex; TotalPagesCount; DisplayPagesCount; IsPreviousButtonVisible; IsNextButtonVisible; IsPageNumberValid = false; PreviousPageIndex; NextPageIndex; PagerQueryParameterTemplate; PagerSegmentTemplate; PagerMode; ViewUrl = ''; PageNumberSlot = '{{pageNumber}}'; constructor(currentPage, totalItemsCount, itemsPerPage, pagerSegmentTemplate, pagerQueryParamTemplate, pagerMode) { this.ProcessedUrlSegments = []; this.CurrentPage = currentPage; const pagesCount = totalItemsCount / itemsPerPage; const totalPagesCount = Math.ceil(pagesCount); this.TotalPagesCount = totalPagesCount === 0 ? 1 : totalPagesCount; this.StartPageIndex = 1; this.EndPageIndex = 1; this.DisplayPagesCount = 10; if (this.CurrentPage > this.DisplayPagesCount) { this.StartPageIndex = (Math.floor((this.CurrentPage - 1) / this.DisplayPagesCount) * this.DisplayPagesCount) + 1; } this.EndPageIndex = Math.min(this.TotalPagesCount, (this.StartPageIndex + this.DisplayPagesCount) - 1); if (!this.isPageValid(this.CurrentPage)) { notFound(); } // previous button this.IsPreviousButtonVisible = this.StartPageIndex > this.DisplayPagesCount ? true : false; this.PreviousPageIndex = this.StartPageIndex - 1; // next button this.IsNextButtonVisible = this.EndPageIndex < this.TotalPagesCount ? true : false; this.NextPageIndex = this.EndPageIndex + 1; this.PagerMode = pagerMode; this.PagerQueryParameterTemplate = pagerQueryParamTemplate; this.PagerSegmentTemplate = pagerSegmentTemplate; if (!this.PagerSegmentTemplate.startsWith('/')) { this.PagerSegmentTemplate = '/' + this.PagerSegmentTemplate; } } isPageValid(pageNumber) { return pageNumber >= 1 && pageNumber <= this.EndPageIndex; } getPagerUrl(pageNumber, context) { let path = context?.url || context?.layout.Fields?.ViewUrl; if (path[0] !== '/') { path = `/${path}`; } // in case we are accessing it from home page if (path === '/' && !this.ViewUrl) { path = this.ViewUrl; } let queryString = setQueryParams(context?.searchParams); if (this.PagerMode === PagerMode.URLSegments) { const desiredPage = this.PagerSegmentTemplate.replace(this.PageNumberSlot, pageNumber.toString()); const pattern = this.PagerSegmentTemplate.replace(this.PageNumberSlot, '(\\d{1,})'); if (queryString) { queryString = `?${queryString}`; } if (this.isSegmentMatch(path, pattern)) { return path.replace(new RegExp(pattern), desiredPage) + queryString; } return path + desiredPage + queryString; } else { const template = this.PagerQueryParameterTemplate; const queryDesiredPage = `${encodeURIComponent(template)}=${pageNumber}`; // Replace the page param in-place (preserving its position) to prevent duplicates // when the current value is non-numeric (e.g. ?page=asdasd). // If the param doesn't exist yet, append it. if (Object.prototype.hasOwnProperty.call(context.searchParams, template)) { const updatedParams = Object.fromEntries(Object.entries(context.searchParams).map(([key, value]) => key === template ? [key, pageNumber.toString()] : [key, value])); return path + '?' + setQueryParams(updatedParams); } const baseQueryString = setQueryParams(context.searchParams); if (baseQueryString) { return path + '?' + baseQueryString + '&' + queryDesiredPage; } return path + '?' + queryDesiredPage; } } isSegmentMatch(url, pattern) { const regex = new RegExp(pattern); const pagingMatch = regex.test(url); return pagingMatch; } } export function getPageNumber(pagerMode, requestContext, pagerQueryTemplate = PagerViewModel.PageNumberDefaultQueryTemplate, pagerTemplate = PagerViewModel.PageNumberDefaultTemplate) { if (pagerMode === PagerMode.QueryParameter) { const template = pagerQueryTemplate !== '' ? pagerQueryTemplate : PagerViewModel.PageNumberDefaultQueryTemplate; const queryParams = requestContext.searchParams; const pageNumberParam = queryParams[template]; if (!pageNumberParam && pageNumberParam !== '') { return 1; } const pagerQueryParam = parseInt(queryParams[template], 10); return !isNaN(pagerQueryParam) ? pagerQueryParam : 0; } else { let pageNumber = 1; const url = requestContext.url; const template = pagerTemplate !== '' ? pagerTemplate : PagerViewModel.PageNumberDefaultTemplate; const extractorRegex = template.match(/(.*?)\{\{[A-z]+\}\}(.*)/); if (extractorRegex) { const firstPart = extractorRegex[1]; const secondPart = extractorRegex[2]; const pageSegmentRegex = `${firstPart}\\d{1,}${secondPart}`; if (url.match(new RegExp(pageSegmentRegex))) { const templateSegments = pageSegmentRegex.split('/'); templateSegments.forEach(templateSegment => { if (templateSegment.indexOf('\\d{1,}') > -1) { let prefix = templateSegment.split('\\d{1,}')[0]; let suffix = templateSegment.split('\\d{1,}')[1]; let pattern = '^' + prefix + '(\\d{1,})' + suffix + '$'; const segments = url.split('/'); let numberSegmentMatches = segments.map(x => x.match(new RegExp(pattern))).filter(x => x); if (numberSegmentMatches?.length === 1) { pageNumber = parseInt(numberSegmentMatches[0][1], 10); const segmentIndex = requestContext.layout.UrlParameters?.findIndex(x => x === numberSegmentMatches[0][0]); requestContext.layout.UrlParameters?.splice(segmentIndex, 1); } } else { const segmentIndex = requestContext.layout.UrlParameters?.findIndex(x => x === templateSegment); if (segmentIndex > -1) { requestContext.layout.UrlParameters?.splice(segmentIndex, 1); } } }); } } return pageNumber; } }