100 lines
3.6 KiB
TypeScript
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;
|
|
}
|