mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 03:05:42 +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:
@@ -68,50 +68,63 @@ const defaultMeta = (
|
||||
dataLength: number,
|
||||
page = 1,
|
||||
pageSize = 10,
|
||||
): RuleEngineListMeta => ({
|
||||
total: dataLength,
|
||||
page,
|
||||
pageSize,
|
||||
totalPages: Math.max(1, Math.ceil(dataLength / pageSize)),
|
||||
});
|
||||
): RuleEngineListMeta => {
|
||||
const totalPages = Math.max(1, Math.ceil(dataLength / pageSize));
|
||||
return {
|
||||
total: dataLength,
|
||||
page,
|
||||
pageSize,
|
||||
totalPages,
|
||||
hasNextPage: page < totalPages,
|
||||
hasPreviousPage: page > 1,
|
||||
};
|
||||
};
|
||||
|
||||
const isPaginatedListResult = <T extends RuleEngineRecord>(
|
||||
/** Standard envelope from the shared pagination toolkit: `{ items, meta }`. */
|
||||
const isItemsEnvelope = <T extends RuleEngineRecord>(
|
||||
value: unknown,
|
||||
): value is RuleEngineListResult<T> =>
|
||||
Boolean(value) &&
|
||||
typeof value === "object" &&
|
||||
"data" in (value ?? {}) &&
|
||||
Array.isArray((value as RuleEngineListResult<T>).data);
|
||||
Array.isArray((value as { items?: unknown }).items);
|
||||
|
||||
/** Legacy envelope (`{ data, meta }`) — still returned by wagon-types. */
|
||||
const isLegacyEnvelope = <T extends RuleEngineRecord>(
|
||||
value: unknown,
|
||||
): value is { data: T[]; meta?: RuleEngineListMeta } =>
|
||||
Boolean(value) &&
|
||||
typeof value === "object" &&
|
||||
Array.isArray((value as { data?: unknown }).data);
|
||||
|
||||
const normalizeList = <T extends RuleEngineRecord>(
|
||||
payload: unknown,
|
||||
page = 1,
|
||||
pageSize = 10,
|
||||
): RuleEngineListResult<T> => {
|
||||
if (isPaginatedListResult<T>(payload)) {
|
||||
return {
|
||||
data: payload.data,
|
||||
meta: payload.meta ?? defaultMeta(payload.data.length, page, pageSize),
|
||||
};
|
||||
const candidates: unknown[] = [payload, unwrap(payload as { data: unknown })];
|
||||
|
||||
for (const body of candidates) {
|
||||
if (isItemsEnvelope<T>(body)) {
|
||||
return {
|
||||
items: body.items,
|
||||
meta: body.meta ?? defaultMeta(body.items.length, page, pageSize),
|
||||
};
|
||||
}
|
||||
if (isLegacyEnvelope<T>(body)) {
|
||||
return {
|
||||
items: body.data,
|
||||
meta: body.meta ?? defaultMeta(body.data.length, page, pageSize),
|
||||
};
|
||||
}
|
||||
if (Array.isArray(body)) {
|
||||
return {
|
||||
items: body as T[],
|
||||
meta: defaultMeta(body.length, page, pageSize),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const body = unwrap(payload as { data: unknown }) as unknown;
|
||||
|
||||
if (isPaginatedListResult<T>(body)) {
|
||||
return {
|
||||
data: body.data,
|
||||
meta: body.meta ?? defaultMeta(body.data.length, page, pageSize),
|
||||
};
|
||||
}
|
||||
|
||||
if (Array.isArray(body)) {
|
||||
return {
|
||||
data: body as T[],
|
||||
meta: defaultMeta(body.length, page, pageSize),
|
||||
};
|
||||
}
|
||||
|
||||
return { data: [], meta: defaultMeta(0, page, pageSize) };
|
||||
return { items: [], meta: defaultMeta(0, page, pageSize) };
|
||||
};
|
||||
|
||||
const normalizeEntity = <T extends RuleEngineRecord>(payload: unknown): T => {
|
||||
@@ -140,6 +153,34 @@ export const ruleEngineService = {
|
||||
return normalizeList<T>(response.data, page, pageSize);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch every row of a resource by walking the pages. The API caps pageSize
|
||||
* at 100, so option/dropdown consumers that used to ask for 200-500 rows in
|
||||
* one shot go through here instead of getting silently capped (or a 400).
|
||||
*/
|
||||
listAll: async <T extends RuleEngineRecord>(
|
||||
resource: RuleEngineResourceSlug,
|
||||
params?: Omit<RuleEngineListParams, "page" | "pageSize">,
|
||||
): Promise<T[]> => {
|
||||
const pageSize = 100;
|
||||
const first = await ruleEngineService.list<T>(resource, {
|
||||
...params,
|
||||
page: 1,
|
||||
pageSize,
|
||||
});
|
||||
const items = [...first.items];
|
||||
const totalPages = first.meta.totalPages ?? 1;
|
||||
for (let page = 2; page <= totalPages; page += 1) {
|
||||
const next = await ruleEngineService.list<T>(resource, {
|
||||
...params,
|
||||
page,
|
||||
pageSize,
|
||||
});
|
||||
items.push(...next.items);
|
||||
}
|
||||
return items;
|
||||
},
|
||||
|
||||
getById: async <T extends RuleEngineRecord>(
|
||||
resource: RuleEngineResourceSlug,
|
||||
id: string,
|
||||
|
||||
Reference in New Issue
Block a user