Files
govoplan-campaign/webui/src/features/campaigns/utils/reportGridShortcuts.ts
T
zemion c51fc180fb
Module Package Release / publish-packages (push) Successful in 12s
Release govoplan-campaign v0.1.28: stabilize saving, review and delivery recovery
2026-09-08 01:32:26 +02:00

100 lines
3.6 KiB
TypeScript

export type ReportGridQueryState = {
sort: { columnId: string; direction: "asc" | "desc" } | null;
filters: Record<string, string>;
};
export const DEFAULT_REPORT_GRID_SORT = { columnId: "number", direction: "asc" as const };
export type ReportGridShortcutId =
| "all"
| "smtp_accepted"
| "smtp_active"
| "smtp_queued"
| "postbox_accepted"
| "print_accepted"
| "failed"
| "outcome_unknown"
| "not_attempted"
| "smtp_skipped"
| "cancelled"
| "imap_appended"
| "imap_failed"
| "imap_pending"
| "imap_active"
| "imap_unknown"
| "imap_skipped";
const REPORT_GRID_SHORTCUT_FILTERS: Record<ReportGridShortcutId, Record<string, string>> = {
all: {},
smtp_accepted: { send: listFilter(["smtp_accepted", "sent"]) },
smtp_active: { send: listFilter(["claimed", "sending"]) },
smtp_queued: { send: listFilter(["queued"]) },
postbox_accepted: { send: listFilter(["postbox_accepted"]) },
print_accepted: { send: listFilter(["print_accepted"]) },
failed: { send: listFilter(["failed_temporary", "failed_permanent"]) },
outcome_unknown: { send: listFilter(["outcome_unknown"]) },
not_attempted: { send: listFilter(["not_queued"]) },
smtp_skipped: { send: listFilter(["skipped"]) },
cancelled: { send: listFilter(["cancelled"]) },
imap_appended: { imap: listFilter(["appended"]) },
imap_failed: { imap: listFilter(["failed"]) },
imap_pending: { imap: listFilter(["pending"]) },
imap_active: { imap: listFilter(["appending"]) },
imap_unknown: { imap: listFilter(["outcome_unknown"]) },
imap_skipped: { imap: listFilter(["skipped"]) }
};
/**
* Return the complete grid query for a count shortcut. Shortcuts are exact
* report views, so applying one intentionally clears every unrelated filter
* and restores the stable report ordering.
*/
export function reportGridQueryForShortcut(shortcutId: ReportGridShortcutId): ReportGridQueryState {
return {
sort: { ...DEFAULT_REPORT_GRID_SORT },
filters: { ...REPORT_GRID_SHORTCUT_FILTERS[shortcutId] }
};
}
/** Applying an already selected outcome shortcut returns to the unfiltered report. */
export function toggleReportGridShortcut(
current: ReportGridQueryState,
shortcutId: ReportGridShortcutId
): ReportGridQueryState {
const target = reportGridQueryForShortcut(shortcutId);
if (shortcutId !== "all" && reportGridFiltersEqual(current.filters, target.filters)) {
return reportGridQueryForShortcut("all");
}
return target;
}
export function activeReportGridShortcut(query: ReportGridQueryState): ReportGridShortcutId | null {
const shortcutIds = Object.keys(REPORT_GRID_SHORTCUT_FILTERS) as ReportGridShortcutId[];
return shortcutIds.find((shortcutId) => reportGridFiltersEqual(
query.filters,
REPORT_GRID_SHORTCUT_FILTERS[shortcutId]
)) ?? null;
}
export function reportGridQueriesEqual(left: ReportGridQueryState, right: ReportGridQueryState): boolean {
if ((left.sort?.columnId ?? "") !== (right.sort?.columnId ?? "")) return false;
if ((left.sort?.direction ?? "") !== (right.sort?.direction ?? "")) return false;
const keys = new Set([...Object.keys(left.filters), ...Object.keys(right.filters)]);
for (const key of keys) {
if ((left.filters[key] ?? "") !== (right.filters[key] ?? "")) return false;
}
return true;
}
function listFilter(values: string[]): string {
return `list:${JSON.stringify(values)}`;
}
function reportGridFiltersEqual(left: Record<string, string>, right: Record<string, string>): boolean {
const keys = new Set([...Object.keys(left), ...Object.keys(right)]);
for (const key of keys) {
if ((left[key] ?? "") !== (right[key] ?? "")) return false;
}
return true;
}