mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 05:18:11 +00:00
enhance contract and booking services with server-side search and validation improvements
- Added parameter to and for server-side free-text search on contract reference, company name, and booking details. - Introduced new validation errors in for container clashes and space issues when creating bookings. - Implemented paginated dropdown settings retrieval in . - Updated to fetch active yards using a new method that handles pagination. - Enhanced with a method to fetch all records by walking through pages. - Refactored to support filtering and pagination in schedule listings. - Improved to return a paginated list of facilities. - Updated UI components in and to utilize debounced search inputs for better performance. - Added alerts in to inform users about booking constraints related to splits and capacity. - Enhanced to display notifications for split bookings and capacity usage.
This commit is contained in:
85
apps/edr-freight-api/src/common/utils/pagination.util.ts
Normal file
85
apps/edr-freight-api/src/common/utils/pagination.util.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { PaginatedResponse, PaginationMeta } from '@edr/types';
|
||||
import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';
|
||||
|
||||
/** Raw page/pageSize as they arrive from a query DTO (both optional). */
|
||||
export interface PageRequest {
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
export interface PaginationOptions {
|
||||
defaultPageSize?: number;
|
||||
maxPageSize?: number;
|
||||
}
|
||||
|
||||
export interface NormalizedPage {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
skip: number;
|
||||
take: number;
|
||||
}
|
||||
|
||||
const DEFAULT_PAGE_SIZE = 20;
|
||||
const MAX_PAGE_SIZE = 100;
|
||||
|
||||
/** Clamp raw query values into a safe page window (page ≥ 1, pageSize capped). */
|
||||
export function normalizePagination(
|
||||
request: PageRequest,
|
||||
options: PaginationOptions = {},
|
||||
): NormalizedPage {
|
||||
const defaultPageSize = options.defaultPageSize ?? DEFAULT_PAGE_SIZE;
|
||||
const maxPageSize = options.maxPageSize ?? MAX_PAGE_SIZE;
|
||||
|
||||
const page = Math.max(1, Math.floor(request.page ?? 1) || 1);
|
||||
const requested = Math.floor(request.pageSize ?? defaultPageSize) || defaultPageSize;
|
||||
const pageSize = Math.min(Math.max(1, requested), maxPageSize);
|
||||
|
||||
return { page, pageSize, skip: (page - 1) * pageSize, take: pageSize };
|
||||
}
|
||||
|
||||
export function buildPaginationMeta(
|
||||
total: number,
|
||||
page: number,
|
||||
pageSize: number,
|
||||
): PaginationMeta {
|
||||
const totalPages = pageSize > 0 ? Math.ceil(total / pageSize) : 0;
|
||||
return {
|
||||
page,
|
||||
pageSize,
|
||||
total,
|
||||
totalPages,
|
||||
hasNextPage: page < totalPages,
|
||||
hasPreviousPage: page > 1,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply skip/take to a query builder, run it, and wrap the result in the
|
||||
* shared `PaginatedResponse` envelope. Ordering and filtering must already be
|
||||
* applied by the caller.
|
||||
*/
|
||||
export async function paginateQuery<T extends ObjectLiteral>(
|
||||
qb: SelectQueryBuilder<T>,
|
||||
request: PageRequest,
|
||||
options?: PaginationOptions,
|
||||
): Promise<PaginatedResponse<T>> {
|
||||
const { page, pageSize, skip, take } = normalizePagination(request, options);
|
||||
const [items, total] = await qb.skip(skip).take(take).getManyAndCount();
|
||||
return { items, meta: buildPaginationMeta(total, page, pageSize) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate an already-materialized array. Prefer `paginateQuery` (DB-level
|
||||
* LIMIT/OFFSET); use this only for lists that are inherently in-memory.
|
||||
*/
|
||||
export function paginateArray<T>(
|
||||
rows: readonly T[],
|
||||
request: PageRequest,
|
||||
options?: PaginationOptions,
|
||||
): PaginatedResponse<T> {
|
||||
const { page, pageSize, skip } = normalizePagination(request, options);
|
||||
return {
|
||||
items: rows.slice(skip, skip + pageSize),
|
||||
meta: buildPaginationMeta(rows.length, page, pageSize),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user