84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
/**
|
||
* Paramètres d’affichage qui doivent survivre au passage par le détail d’une
|
||
* facture BAP. Seules ces clés sont sérialisées afin d’éviter de propager des
|
||
* paramètres de navigation arbitraires.
|
||
*/
|
||
export type BapFilters = {
|
||
searchQuery: string;
|
||
statusFilter: string;
|
||
selectedYear: string;
|
||
selectedMonth: string;
|
||
sortField: "invoiceDate" | "createdAt";
|
||
sortDir: "asc" | "desc";
|
||
};
|
||
|
||
const BAP_STATUSES = new Set([
|
||
"all",
|
||
"exported",
|
||
"not_exported",
|
||
"export_error",
|
||
"bap_validated",
|
||
"bap_pending",
|
||
"to_complete",
|
||
]);
|
||
|
||
function asSearchParams(search: string): URLSearchParams {
|
||
return new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
|
||
}
|
||
|
||
function isMonth(value: string | null): value is string {
|
||
return value !== null && /^(0[1-9]|1[0-2])$/.test(value);
|
||
}
|
||
|
||
function isYear(value: string | null): value is string {
|
||
return value === "all" || (value !== null && /^\d{4}$/.test(value));
|
||
}
|
||
|
||
/** Lit et valide les filtres BAP transmis dans l’URL. */
|
||
export function parseBapFilters(search: string, defaultYear: string): BapFilters {
|
||
const params = asSearchParams(search);
|
||
const status = params.get("status");
|
||
const year = params.get("year");
|
||
const month = params.get("month");
|
||
const sort = params.get("sort");
|
||
const direction = params.get("dir");
|
||
|
||
return {
|
||
searchQuery: params.get("q") || "",
|
||
statusFilter: status && BAP_STATUSES.has(status) ? status : "all",
|
||
selectedYear: isYear(year) ? year : defaultYear,
|
||
selectedMonth: month === "all" || isMonth(month) ? month : "all",
|
||
sortField: sort === "invoiceDate" ? "invoiceDate" : "createdAt",
|
||
sortDir: direction === "asc" ? "asc" : "desc",
|
||
};
|
||
}
|
||
|
||
/** Construit une URL de détail qui conserve explicitement le contexte BAP. */
|
||
export function buildBapDetailLocation(invoiceId: number, filters: BapFilters): string {
|
||
const params = new URLSearchParams({
|
||
returnTo: "bap",
|
||
q: filters.searchQuery,
|
||
status: filters.statusFilter,
|
||
year: filters.selectedYear,
|
||
month: filters.selectedMonth,
|
||
sort: filters.sortField,
|
||
dir: filters.sortDir,
|
||
});
|
||
|
||
return `/invoices/${invoiceId}?${params.toString()}`;
|
||
}
|
||
|
||
/** Retourne la liste d’origine. Sans contexte BAP, le comportement historique est conservé. */
|
||
export function getBapReturnLocation(search: string): string {
|
||
const params = asSearchParams(search);
|
||
if (params.get("returnTo") !== "bap") return "/invoices";
|
||
|
||
const allowed = new URLSearchParams();
|
||
for (const key of ["q", "status", "year", "month", "sort", "dir"]) {
|
||
const value = params.get(key);
|
||
if (value) allowed.set(key, value);
|
||
}
|
||
const query = allowed.toString();
|
||
return query ? `/invoices-bap?${query}` : "/invoices-bap";
|
||
}
|