FactuGES_ERP/packages/rdx-criteria/src/criteria-from-url-converter.ts
david a264f43b95 feat: enhance proforma listing and archiving functionality
- Updated proforma listing behavior to utilize `Criteria filters[]` for managing archived and active proformas.
- Removed `archived` query parameter from backend; frontend now manages `archiveView` state.
- Implemented new filters for `archived_at` and `status` in the proforma listing API.
- Adjusted proforma creation and deletion contracts to reflect changes in archiving logic.
- Introduced new utility functions for building proforma listing criteria based on UI state.
- Updated frontend components to support new filtering options and maintain state in the URL.
- Added SQL index for improved performance on proforma queries.
- Created new TypeScript types for managing proforma list filters and criteria.
2026-07-29 22:24:53 +02:00

87 lines
2.6 KiB
TypeScript

import type { FiltersPrimitives } from "./codelytv";
import { Criteria } from "./critera";
import { DEFAULT_ORDER, INITIAL_PAGE_INDEX, INITIAL_PAGE_SIZE } from "./defaults";
type defaultsType = {
order: "asc" | "desc";
pageSize: number;
pageNumber: number;
};
const defaultOptions: defaultsType = {
order: DEFAULT_ORDER,
pageSize: INITIAL_PAGE_SIZE,
pageNumber: INITIAL_PAGE_INDEX,
} as const;
export class CriteriaFromUrlConverter {
/**
* Converts a URL to a criteria object.
* @param url - The URL to convert.
* @returns The criteria object.
*/
public toCriteria(
url: URL,
options?: {
defaults: defaultsType;
}
): Criteria {
const { searchParams: urlParams } = url;
const defaults = {
order: options?.defaults?.order ?? defaultOptions.order,
pageSize: options?.defaults?.pageSize ?? defaultOptions.pageSize,
pageNumber: options?.defaults?.pageNumber ?? defaultOptions.pageNumber,
};
const quickSearch = urlParams.get("q");
const filters = this.parseFilters(urlParams);
const orderBy = urlParams.get("orderBy");
const order = urlParams.has("order") ? String(urlParams.get("order")) : defaults.order;
const pageSize = this.parseInteger(urlParams.get("pageSize"), defaults.pageSize);
const pageNumber = this.parseInteger(urlParams.get("pageNumber"), defaults.pageNumber);
return Criteria.fromPrimitives(filters, orderBy, order, pageSize, pageNumber, quickSearch);
}
public toFiltersPrimitives(url: URL): FiltersPrimitives[] {
const { searchParams } = url;
return this.parseFilters(searchParams);
}
private parseInteger(value: string | null, fallback: number): number {
const parsed = Number.parseInt(value ?? "", 10);
return Number.isNaN(parsed) ? fallback : parsed;
}
private parseFilters(searchParams: URLSearchParams): FiltersPrimitives[] {
const tempFilters: Record<string, Partial<FiltersPrimitives>> = {};
searchParams.forEach((value, key) => {
const match = key.match(/filters\[(\d+)]\[(.+)]/);
if (match) {
const index = match[1]!;
const property = match[2] as keyof FiltersPrimitives;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!tempFilters[index]) {
tempFilters[index] = {};
}
tempFilters[index][property] = value;
}
});
return Object.values(tempFilters).filter(
(filter) =>
filter.field !== undefined &&
filter.operator !== undefined &&
(filter.value !== undefined ||
filter.operator === "IS_NULL" ||
filter.operator === "IS_NOT_NULL")
);
}
}