137 lines
4.6 KiB
TypeScript
137 lines
4.6 KiB
TypeScript
import { SortedByDto } from "~/application/dtos/data/SortedByDto";
|
|
import { FiltersDto } from "~/application/dtos/data/FiltersDto";
|
|
import { FilterablePropertyDto } from "~/application/dtos/data/FilterablePropertyDto";
|
|
import Constants from "~/application/Constants";
|
|
|
|
export function getPaginationFromCurrentUrl(urlSearchParams: URLSearchParams): { page: number; pageSize: number; sortedBy: SortedByDto[]; query: string } {
|
|
return {
|
|
page: getPageFromCurrentUrl(urlSearchParams),
|
|
pageSize: getPageSizeFromCurrentUrl(urlSearchParams),
|
|
sortedBy: getSortByFromCurrentUrl(urlSearchParams),
|
|
query: getSearchQueryFromCurrentUrl(urlSearchParams),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Total page count for a paginated result set, safe against the two inputs that
|
|
* otherwise reach the UI as "1/NAN": a missing page size (`0/0` → `NaN`) and an
|
|
* absent total (upstream provider returned nothing). There is always at least
|
|
* one page, because an empty list still renders as page 1 of 1.
|
|
*/
|
|
export function getTotalPages(totalItems: number | null | undefined, pageSize: number | null | undefined): number {
|
|
const total = Number.isFinite(totalItems) ? Number(totalItems) : 0;
|
|
const size = Number.isFinite(pageSize) && Number(pageSize) > 0 ? Number(pageSize) : Constants.DEFAULT_PAGE_SIZE;
|
|
return Math.max(1, Math.ceil(total / size));
|
|
}
|
|
|
|
export function getFiltersFromCurrentUrl(request: Request, properties: FilterablePropertyDto[]): FiltersDto {
|
|
const url = new URL(request.url);
|
|
properties.forEach((property) => {
|
|
const params = url.searchParams.get(property.name);
|
|
property.value = params ?? null;
|
|
if (property.isNumber && property.value) {
|
|
if (isNaN(Number(property.value))) {
|
|
property.value = null;
|
|
}
|
|
}
|
|
});
|
|
|
|
const query = url.searchParams.get("q") ?? undefined;
|
|
|
|
return { query, properties };
|
|
}
|
|
|
|
function getPageFromCurrentUrl(urlSearchParams: URLSearchParams): number {
|
|
const paramsPage = urlSearchParams.get("page");
|
|
const page = paramsPage ? Number(paramsPage) : 1;
|
|
if (!Number.isSafeInteger(page) || page <= 0) {
|
|
return 1;
|
|
}
|
|
return page;
|
|
}
|
|
|
|
function getPageSizeFromCurrentUrl(urlSearchParams: URLSearchParams): number {
|
|
const paramsPageSize = urlSearchParams.get("pageSize");
|
|
const pageSize = paramsPageSize ? Number(paramsPageSize) : Constants.DEFAULT_PAGE_SIZE;
|
|
if (!Number.isSafeInteger(pageSize) || pageSize <= 0) {
|
|
return Constants.DEFAULT_PAGE_SIZE;
|
|
}
|
|
if (pageSize > Constants.MAX_PAGE_SIZE) {
|
|
return Constants.MAX_PAGE_SIZE;
|
|
}
|
|
return pageSize;
|
|
}
|
|
|
|
function getSearchQueryFromCurrentUrl(urlSearchParams: URLSearchParams): string {
|
|
return urlSearchParams.get("q")?.toString() ?? "";
|
|
}
|
|
|
|
function getSortByFromCurrentUrl(urlSearchParams: URLSearchParams): SortedByDto[] {
|
|
let sorts = urlSearchParams.get("sort")?.toString().split(",") ?? [];
|
|
return sorts.map((sort) => {
|
|
let direction: "asc" | "desc" = "asc";
|
|
if (sort) {
|
|
if (sort.startsWith("-")) {
|
|
sort = sort.replace("-", "");
|
|
direction = "desc";
|
|
} else {
|
|
direction = "asc";
|
|
}
|
|
}
|
|
const sortName = sort.replace("-", "").replace("+", "");
|
|
return { name: sortName, direction };
|
|
});
|
|
}
|
|
|
|
export function getNewPaginationUrl(request: Request, page: number, sortedBy?: { name: string; direction: "asc" | "desc" }): string {
|
|
const url = new URL(request.url);
|
|
const params = new URLSearchParams(url.search);
|
|
|
|
//Add a second foo parameter.
|
|
if (params.get("page")) {
|
|
params.set("page", page.toString());
|
|
} else {
|
|
params.append("page", page.toString());
|
|
}
|
|
|
|
if (sortedBy?.name) {
|
|
const withDirection = (sortedBy.direction === "desc" ? "-" : "") + sortedBy.name;
|
|
if (params.get("sort")) {
|
|
params.set("sort", withDirection);
|
|
} else {
|
|
params.append("sort", withDirection);
|
|
}
|
|
}
|
|
|
|
const newUrl = url + "?" + params;
|
|
return newUrl;
|
|
}
|
|
|
|
// export async function getPageFromCurrentUrl(request: Request): PaginationDto {
|
|
// const params = new URL(request.url).searchParams;
|
|
// const pageSize = Constants.DEFAULT_PAGE_SIZE;
|
|
|
|
// let page = 1;
|
|
// const paramsPage = params.get("page");
|
|
// if (paramsPage) {
|
|
// page = Number(paramsPage);
|
|
// }
|
|
|
|
// // const paramsSort = search.get("sort");
|
|
// // if (!paramsPage) {
|
|
// // throw redirect(request.url + "?page=1");
|
|
// // }
|
|
// // let orderBy: any = { createdAt: "desc" };
|
|
// // if (paramsSort) {
|
|
// // const column = paramsSort.replace("-", "").trim();
|
|
// // if (column === "createdAt" || column === "folio") {
|
|
// // orderBy = { [column]: paramsSort.startsWith("-") ? "desc" : "asc" };
|
|
// // }
|
|
// // }
|
|
// const pagination: PaginationDto = {
|
|
// page,
|
|
// pageSize,
|
|
// };
|
|
// return pagination;
|
|
// }
|