80 lines
2.3 KiB
JavaScript
80 lines
2.3 KiB
JavaScript
// The only values ever interpolated into SQL (sort column and direction) come
|
|
// from the whitelists here; everything else is a bind parameter.
|
|
|
|
const SORT_COLUMNS = {
|
|
agreementUuid: '"agreementUuid"',
|
|
eventUuid: '"eventUuid"',
|
|
sender: "sender",
|
|
date: "date",
|
|
size: '"size"',
|
|
};
|
|
|
|
export const SORTABLE_KEYS = Object.keys(SORT_COLUMNS);
|
|
|
|
export function sortClause(sort, dir) {
|
|
const col = SORT_COLUMNS[sort] || "date";
|
|
const direction = String(dir).toLowerCase() === "asc" ? "ASC" : "DESC";
|
|
return `ORDER BY ${col} ${direction} NULLS LAST`;
|
|
}
|
|
|
|
export function eventSearchClause(idx) {
|
|
return (
|
|
`(e.event_id_uuid::text ILIKE '%'||$${idx}||'%'` +
|
|
` OR agr.agreement_id_uuid::text ILIKE '%'||$${idx}||'%'` +
|
|
` OR e.sender_id ILIKE '%'||$${idx}||'%'` +
|
|
` OR e.recipient_id ILIKE '%'||$${idx}||'%')`
|
|
);
|
|
}
|
|
|
|
export const DEFAULT_LIMIT = 50;
|
|
const MAX_LIMIT = 200;
|
|
|
|
// Server-side bound, applied on every request regardless of what the UI sends.
|
|
export function clampLimit(v) {
|
|
const n = parseInt(v, 10);
|
|
if (!Number.isFinite(n)) return DEFAULT_LIMIT;
|
|
return Math.min(Math.max(n, 1), MAX_LIMIT);
|
|
}
|
|
|
|
export function clampOffset(v) {
|
|
const n = parseInt(v, 10);
|
|
if (!Number.isFinite(n) || n < 0) return 0;
|
|
return n;
|
|
}
|
|
|
|
export function pageCount(total, perPage = DEFAULT_LIMIT) {
|
|
return Math.max(1, Math.ceil((Number(total) || 0) / (perPage || DEFAULT_LIMIT)));
|
|
}
|
|
|
|
const MAX_WINDOW_DAYS = 366;
|
|
|
|
// Enforced server-side on every request, not in the UI.
|
|
export function windowParams(query = {}) {
|
|
const iso = (d) => d.toISOString().slice(0, 10);
|
|
const valid = (s) => typeof s === "string" && /^\d{4}-\d{2}-\d{2}$/.test(s);
|
|
|
|
const today = new Date();
|
|
today.setUTCHours(0, 0, 0, 0);
|
|
|
|
const to = valid(query.to) ? query.to : iso(today);
|
|
let from = valid(query.from) ? query.from : null;
|
|
if (!from) {
|
|
const d = new Date(`${to}T00:00:00Z`);
|
|
d.setUTCDate(d.getUTCDate() - 29);
|
|
from = iso(d);
|
|
}
|
|
|
|
let fromD = new Date(`${from}T00:00:00Z`);
|
|
const toD = new Date(`${to}T00:00:00Z`);
|
|
if (fromD > toD) {
|
|
from = to;
|
|
fromD = new Date(toD);
|
|
}
|
|
if ((toD - fromD) / 86_400_000 > MAX_WINDOW_DAYS) {
|
|
const capped = new Date(toD);
|
|
capped.setUTCDate(capped.getUTCDate() - MAX_WINDOW_DAYS);
|
|
from = iso(capped);
|
|
}
|
|
return { from, to };
|
|
}
|