Merge pull request 'KPI-Monitor zeigt Agenten/Online-Kacheln wieder an' (#40) from fds2610-bot/monitor:main into main
Reviewed-on: https://codeberg.org/fds2610/monitor/pulls/40
This commit is contained in:
commit
5dcf080b27
4 changed files with 57 additions and 4 deletions
|
|
@ -245,8 +245,10 @@ externe Datenbankserver (nur PHP/Python-Standardbibliothek) auskommen, um die
|
|||
Klick-Modals. ✅ erledigt: Events/Systeme/KPIs kommen live von der API, ein neuer
|
||||
SSE-Endpoint (`GET /api/v1/stream`, F13) stoesst Frontend-Updates an (Polling-Fallback in
|
||||
`office-realtime.js`), KPI-Monitor zeichnet eine eigene SVG-Sparkline (F10, kein Chart-Lib)
|
||||
sobald KPIs gemeldet wurden - vorher weiterhin der Platzhalter aus Phase 2 (F7 ist
|
||||
inhaltlich weiterhin offen).
|
||||
sobald KPIs gemeldet wurden. "Agenten" (registrierte Agenten) und "Online" (davon
|
||||
praesent, isAgentPresent()) sind als erste zwei KPI-Kacheln immer sichtbar, direkt aus der
|
||||
Agentenliste abgeleitet statt gemeldet (Issue #39) - darueber hinaus ist F7 inhaltlich
|
||||
weiterhin offen, ohne gemeldete KPIs zeigt die Wand nur diese beiden Kacheln.
|
||||
6. **Phase 5 – Agenten & Animation**: Zustandsmaschine, Laufwege, Tipp-/Lese-/Kaffee-Animation,
|
||||
Reaktion auf neue Ticket-/Event-/Systemstatus-Meldungen. ✅ erledigt: `resolveAgentVisualState`
|
||||
bildet die von der API gemeldeten Zustaende auf Ort/Pose ab, Agenten-Avatare sind eine
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import {
|
|||
buildSystemModalContent,
|
||||
buildKpiTiles,
|
||||
buildKpiModalContent,
|
||||
buildAgentCountKpis,
|
||||
mapAgentsToDesks,
|
||||
normalizeAgentForDisplay,
|
||||
resolveAgentVisualState,
|
||||
|
|
@ -1401,6 +1402,11 @@ export function renderOfficeScene(container, data = {}) {
|
|||
// is_present-Feld wie registrierte Agenten (Issue #19).
|
||||
poIsLive = isLive;
|
||||
|
||||
// "Agenten"/"Online" (Issue #39) stehen vor den gemeldeten KPIs (F7), damit sie auf der
|
||||
// Wandkachel (MAX_KPI_TILES) immer sichtbar sind, statt von gemeldeten Kennzahlen verdraengt
|
||||
// zu werden.
|
||||
const displayKpis = [...buildAgentCountKpis(agents), ...kpis];
|
||||
|
||||
const groupedTickets = groupTicketsByColumn(tickets);
|
||||
|
||||
const boardGroup = renderBoard(ticketCounts, groupedTickets, (columnKey) => {
|
||||
|
|
@ -1417,10 +1423,10 @@ export function renderOfficeScene(container, data = {}) {
|
|||
svg.insertBefore(boardGroup, svg.querySelector(".agents-layer"));
|
||||
}
|
||||
|
||||
const wallGroup = renderMonitorWall(systems, events, kpis, {
|
||||
const wallGroup = renderMonitorWall(systems, events, displayKpis, {
|
||||
onEventsClick: () => openModal(buildEventModalContent(events), renderEventModalBody),
|
||||
onSystemsClick: () => openModal(buildSystemModalContent(systems), renderSystemModalBody),
|
||||
onKpiClick: () => openModal(buildKpiModalContent(kpis), renderKpiModalBody),
|
||||
onKpiClick: () => openModal(buildKpiModalContent(displayKpis), renderKpiModalBody),
|
||||
});
|
||||
const existingWall = svg.querySelector(".monitor-wall");
|
||||
if (existingWall) {
|
||||
|
|
|
|||
|
|
@ -415,6 +415,27 @@ export function isAgentPresent(agent) {
|
|||
return Boolean(agent.is_present);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die beiden im KPI-Monitor erwarteten Kennzahlen "Agenten" (registrierte Agenten) und
|
||||
* "Online" (davon innerhalb der letzten 10 Minuten aktiv, siehe isAgentPresent()) werden
|
||||
* anders als die per POST /api/v1/kpis/{key} gemeldeten Kennzahlen (F7, weiterhin offen)
|
||||
* direkt aus der ohnehin geladenen Agentenliste abgeleitet statt separat gemeldet.
|
||||
* Gibt KPI-foermige Eintraege zurueck (gleiche Form wie GET /api/v1/kpis), damit sie sich
|
||||
* mit den gemeldeten KPIs vor buildKpiTiles()/buildKpiModalContent() zusammenfuehren lassen.
|
||||
*
|
||||
* @param {Array<object|null>} agents - z.B. leere Schreibtisch-Plaetze der Demo-Daten sind null.
|
||||
* @returns {Array<object>}
|
||||
*/
|
||||
export function buildAgentCountKpis(agents = []) {
|
||||
const registered = agents.filter(Boolean);
|
||||
const online = registered.filter(isAgentPresent).length;
|
||||
|
||||
return [
|
||||
{ key: "agents_total", label: "Agenten", unit: "", current_value: registered.length, history: [] },
|
||||
{ key: "agents_online", label: "Online", unit: "", current_value: online, history: [] },
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ordnet eine rohe Agentenliste (GET /api/v1/agents) den Schreibtischen zu - anders als
|
||||
* buildDeskLayout()/Demo-Daten steht der Sitzplatz hier nicht in der Array-Reihenfolge,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import {
|
|||
buildKpiSparklinePoints,
|
||||
buildKpiTiles,
|
||||
buildKpiModalContent,
|
||||
buildAgentCountKpis,
|
||||
MAX_KPI_TILES,
|
||||
AGENT_LOCATIONS,
|
||||
resolveAgentVisualState,
|
||||
|
|
@ -331,6 +332,29 @@ test("buildKpiModalContent zeigt alle KPIs (kein Limit) inkl. Historie", () => {
|
|||
assert.equal(content.items[0].label, "Offene Tickets");
|
||||
});
|
||||
|
||||
test("buildAgentCountKpis liefert Anzahl registrierter und online-Agenten (Issue #39)", () => {
|
||||
const kpis = buildAgentCountKpis([
|
||||
{ id: 1, is_present: true },
|
||||
{ id: 2, is_present: false },
|
||||
{ id: 3, is_present: true },
|
||||
]);
|
||||
assert.equal(kpis.length, 2);
|
||||
assert.deepEqual(kpis[0], { key: "agents_total", label: "Agenten", unit: "", current_value: 3, history: [] });
|
||||
assert.deepEqual(kpis[1], { key: "agents_online", label: "Online", unit: "", current_value: 2, history: [] });
|
||||
});
|
||||
|
||||
test("buildAgentCountKpis ignoriert leere Schreibtisch-Plaetze (null) und faellt ohne is_present auf anwesend zurueck", () => {
|
||||
const kpis = buildAgentCountKpis([{ id: 1 }, null, { id: 2 }, null]);
|
||||
assert.equal(kpis[0].current_value, 2);
|
||||
assert.equal(kpis[1].current_value, 2);
|
||||
});
|
||||
|
||||
test("buildAgentCountKpis liefert 0/0 ohne Agenten", () => {
|
||||
const kpis = buildAgentCountKpis([]);
|
||||
assert.equal(kpis[0].current_value, 0);
|
||||
assert.equal(kpis[1].current_value, 0);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Phase 5 - Agenten-Zustandsmaschine & Animation
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue