From 56cb19d052d85ca154e0544462276b3387170d6a Mon Sep 17 00:00:00 2001 From: cynfo3000 Date: Tue, 10 Mar 2026 00:36:31 +0100 Subject: [PATCH] feat: API-Keys in Einstellungen gruppiert nach Kunde --- frontend/src/pages/SettingsPage.jsx | 127 +++++++++++++++++----------- 1 file changed, 76 insertions(+), 51 deletions(-) diff --git a/frontend/src/pages/SettingsPage.jsx b/frontend/src/pages/SettingsPage.jsx index 79289ba..ec72f4c 100644 --- a/frontend/src/pages/SettingsPage.jsx +++ b/frontend/src/pages/SettingsPage.jsx @@ -347,61 +347,86 @@ function APIKeysSection() { )} - {/* Key Liste */} + {/* Key Liste — gruppiert nach Kunde */} {loading ? (
Laden...
) : keys.length === 0 ? (
Keine API-Keys vorhanden
- ) : ( -
- {keys.map((k) => { - const perm = PERM_LABELS[k.permissions] || PERM_LABELS.read - const customer = k.customer_id ? customers.find(c => c.id === k.customer_id) : null - const lastUsedAgo = k.last_used - ? (() => { - const s = (Date.now() - new Date(k.last_used)) / 1000 - if (s < 120) return 'gerade eben' - if (s < 3600) return `${Math.floor(s/60)}m` - if (s < 86400) return `${Math.floor(s/3600)}h` - return `${Math.floor(s/86400)}d` - })() - : null - return ( -
- - {perm.label} - - {k.name} - {customer && ( - {customer.number} - )} - - {k.key.substring(0, 8)}…{k.key.substring(k.key.length - 4)} - - {lastUsedAgo && ( - - {lastUsedAgo} - - )} - - -
- ) - })} -
- )} + ) : (() => { + // Gruppen bauen: null-Kunde zuerst, dann nach Kundennummer sortiert + const groups = {} + keys.forEach(k => { + const gid = k.customer_id ?? '__global__' + if (!groups[gid]) groups[gid] = [] + groups[gid].push(k) + }) + const sorted = Object.entries(groups).sort(([a], [b]) => { + if (a === '__global__') return -1 + if (b === '__global__') return 1 + const ca = customers.find(c => c.id === parseInt(a)) + const cb = customers.find(c => c.id === parseInt(b)) + return (ca?.number || '').localeCompare(cb?.number || '') + }) + return ( +
+ {sorted.map(([gid, gkeys]) => { + const customer = gid !== '__global__' ? customers.find(c => c.id === parseInt(gid)) : null + return ( +
+ {/* Gruppen-Header */} +
+ + {customer ? `${customer.number} — ${customer.name}` : 'Global'} + + ({gkeys.length}) +
+ {/* Keys der Gruppe */} + {gkeys.map(k => { + const perm = PERM_LABELS[k.permissions] || PERM_LABELS.read + const lastUsedAgo = k.last_used + ? (() => { + const s = (Date.now() - new Date(k.last_used)) / 1000 + if (s < 120) return 'gerade eben' + if (s < 3600) return `${Math.floor(s/60)}m` + if (s < 86400) return `${Math.floor(s/3600)}h` + return `${Math.floor(s/86400)}d` + })() + : null + return ( +
+ + {perm.label} + + {k.name} + + {k.key.substring(0, 8)}…{k.key.substring(k.key.length - 4)} + + {lastUsedAgo && ( + + {lastUsedAgo} + + )} + + +
+ ) + })} +
+ ) + })} +
+ ) + })() + } ) }