import type { NextcloudInstance, RatingLevel } from '@/lib/nextcloud-status-api'; /** * Sortierung der Cloud-Kacheln (quick-261002-k67, L-07, D-G) — reine * Funktionen, kein React. */ export type SortKey = 'name' | 'status' | 'version' | 'eol'; export const SORT_KEYS: readonly SortKey[] = ['name', 'status', 'version', 'eol']; /** Rot zuerst, dann Gelb, Grau, Gruen. */ const LEVEL_ORDER: Record = { red: 0, yellow: 1, unknown: 2, green: 3 }; function byName(a: NextcloudInstance, b: NextcloudInstance): number { return a.customerName.localeCompare(b.customerName, 'de', { sensitivity: 'base' }); } function versionTriple(raw: string | null): [number, number, number] | null { if (!raw) return null; const m = /^(\d+)\.(\d+)\.(\d+)/.exec(raw.trim()); return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null; } function compareVersions(a: NextcloudInstance, b: NextcloudInstance): number { const va = versionTriple(a.status.versionString); const vb = versionTriple(b.status.versionString); if (!va && !vb) return 0; if (!va) return 1; // unbekannt zuletzt if (!vb) return -1; for (let i = 0; i < 3; i++) { if (va[i] !== vb[i]) return va[i] - vb[i]; } return 0; } function compareEol(a: NextcloudInstance, b: NextcloudInstance): number { const ea = a.rating.eolDate; const eb = b.rating.eolDate; if (!ea && !eb) return 0; if (!ea) return 1; // unbekannt zuletzt if (!eb) return -1; return ea < eb ? -1 : ea > eb ? 1 : 0; } /** Liefert eine neue, sortierte Liste; die Eingabe bleibt unveraendert. Gleiche Werte nach Kundenname. */ export function sortClouds(items: NextcloudInstance[], key: SortKey): NextcloudInstance[] { const compare = (a: NextcloudInstance, b: NextcloudInstance): number => { switch (key) { case 'status': return LEVEL_ORDER[a.rating.level] - LEVEL_ORDER[b.rating.level]; case 'version': return compareVersions(a, b); case 'eol': return compareEol(a, b); default: return 0; } }; return [...items].sort((a, b) => compare(a, b) || byName(a, b)); } function storageKey(userId: string): string { return `tessera:nextcloud-status:sort:${userId}`; } /** Gemerkte Sortierung dieses Benutzers; unbekannter Wert oder gesperrter Speicher ergeben 'name'. */ export function readSortPreference(userId: string): SortKey { try { const stored = window.localStorage.getItem(storageKey(userId)); return (SORT_KEYS as readonly string[]).includes(stored ?? '') ? (stored as SortKey) : 'name'; } catch { return 'name'; } } /** Merkt die Sortierung; ein gesperrter Speicher wird still uebergangen. */ export function writeSortPreference(userId: string, key: SortKey): void { try { window.localStorage.setItem(storageKey(userId), key); } catch { /* Speicher gesperrt oder voll — die Auswahl gilt dann nur fuer diese Sitzung */ } }