Merge pull request 'Entwickler-Agent laeuft sichtbar zum Board bei in_arbeit-Wechseln' (#78) from fds2610-bot/monitor:main into main
Reviewed-on: https://codeberg.org/fds2610/monitor/pulls/78
This commit is contained in:
commit
f2fc2bc2e0
3 changed files with 167 additions and 17 deletions
|
|
@ -47,6 +47,7 @@ import {
|
||||||
applyPendingTicketMoves,
|
applyPendingTicketMoves,
|
||||||
detectAgentOwnedTicketChanges,
|
detectAgentOwnedTicketChanges,
|
||||||
hasAgentReachedBoard,
|
hasAgentReachedBoard,
|
||||||
|
isAgentReportingBoardVisit,
|
||||||
PO_AGENT_ID,
|
PO_AGENT_ID,
|
||||||
PO_DISPLAY_NAME,
|
PO_DISPLAY_NAME,
|
||||||
resolveReloadIntervalSeconds,
|
resolveReloadIntervalSeconds,
|
||||||
|
|
@ -1056,12 +1057,88 @@ function updateDoorActiveClass() {
|
||||||
doorLeft.classList.toggle("door-active", anyAtDoor);
|
doorLeft.classList.toggle("door-active", anyAtDoor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------
|
||||||
|
// Board-Besuch des zustaendigen Agenten bei "in_arbeit"-Wechseln (Issue #76): analog zum
|
||||||
|
// PO-Besuch (triggerPoVisit()/advancePoVisit()), aber pro Agent statt eines einzelnen globalen
|
||||||
|
// Zustands, weil mehrere Agenten gleichzeitig eigene Tickets verschieben koennen. Nutzt bewusst
|
||||||
|
// dieselben Stages/denselben Ablauf wie PO_VISIT_STAGES/advancePoVisitStage (siehe
|
||||||
|
// office-scene.js) - ein eigenes, inhaltsgleiches Stage-Array waere nur Duplikat.
|
||||||
|
//
|
||||||
|
// agentId -> {agent: {id, name, role}, homeFeet, stage, onArrived}
|
||||||
|
const agentBoardVisitors = new Map();
|
||||||
|
|
||||||
|
function agentVisitorPlacements() {
|
||||||
|
return Array.from(agentBoardVisitors.values()).map((visitor) => {
|
||||||
|
const visual = resolveAgentVisualState(visitor.stage);
|
||||||
|
return {
|
||||||
|
agent: { ...visitor.agent, pose: visual.pose, location: visual.location },
|
||||||
|
homeFeet: visitor.homeFeet,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function advanceAgentBoardVisit(agentId) {
|
||||||
|
const visitor = agentBoardVisitors.get(agentId);
|
||||||
|
if (!visitor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextStage = advancePoVisitStage(visitor.stage);
|
||||||
|
if (nextStage === null) {
|
||||||
|
agentBoardVisitors.delete(agentId);
|
||||||
|
repaintAgentsLayer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
visitor.stage = nextStage;
|
||||||
|
|
||||||
|
// Wie beim PO-/Tuerbesuch (Issue #55): erst am Board wird die zurueckgehaltene Ticket-
|
||||||
|
// Aenderung sichtbar gemacht, danach wartet die Persona TICKET_PLACED_WAIT_MS, statt sofort
|
||||||
|
// weiterzulaufen.
|
||||||
|
if (visitor.stage === PO_VISIT_STAGES[1]) {
|
||||||
|
const onArrived = visitor.onArrived;
|
||||||
|
visitor.onArrived = null;
|
||||||
|
onArrived?.();
|
||||||
|
repaintAgentsLayer();
|
||||||
|
window.setTimeout(() => advanceAgentBoardVisit(agentId), TICKET_PLACED_WAIT_MS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
repaintAgentsLayer();
|
||||||
|
window.setTimeout(() => advanceAgentBoardVisit(agentId), DOOR_VISIT_STAGE_DURATION_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stoesst den sichtbaren Board-Besuch eines Entwickler-Agenten an (Issue #76). Laeuft bereits
|
||||||
|
* einer fuer denselben Agenten (z.B. mehrere Tickets wechseln kurz hintereinander), wird kein
|
||||||
|
* zweiter Besuch gestartet - onArrived wird sofort nachgeholt, damit die zurueckgehaltene(n)
|
||||||
|
* Ticket-Aenderung(en) nicht dauerhaft verborgen bleiben.
|
||||||
|
*
|
||||||
|
* @param {number|string} agentId
|
||||||
|
* @param {{id: number|string, name: string, role: string}} agentInfo
|
||||||
|
* @param {{x: number, y: number}} homeFeet - der eigene Schreibtisch des Agenten.
|
||||||
|
* @param {() => void} [onArrived] - wird aufgerufen, sobald der Agent am Board ankommt.
|
||||||
|
*/
|
||||||
|
function triggerAgentBoardVisit(agentId, agentInfo, homeFeet, onArrived) {
|
||||||
|
if (agentBoardVisitors.has(agentId)) {
|
||||||
|
onArrived?.();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Ein bereits laufender idle-Kosmetik-Ausflug (Kaffee/Zeitung/Schwaetzchen, siehe
|
||||||
|
// scheduleIdleCosmetic()) wuerde sonst mitten im Board-Besuch die Pose/Position ueberschreiben.
|
||||||
|
clearIdleCosmeticTimer(String(agentId));
|
||||||
|
|
||||||
|
agentBoardVisitors.set(agentId, { agent: agentInfo, homeFeet, stage: PO_VISIT_STAGES[0], onArrived });
|
||||||
|
repaintAgentsLayer();
|
||||||
|
window.setTimeout(() => advanceAgentBoardVisit(agentId), DOOR_VISIT_STAGE_DURATION_MS);
|
||||||
|
}
|
||||||
|
|
||||||
function repaintAgentsLayer() {
|
function repaintAgentsLayer() {
|
||||||
if (!currentAgentsLayer) return;
|
if (!currentAgentsLayer) return;
|
||||||
updateAgentsLayer(currentAgentsLayer, [
|
updateAgentsLayer(currentAgentsLayer, [
|
||||||
...currentRegularPlacements,
|
...currentRegularPlacements,
|
||||||
...poPlacement(),
|
...poPlacement(),
|
||||||
...doorVisitorPlacements(),
|
...doorVisitorPlacements(),
|
||||||
|
...agentVisitorPlacements(),
|
||||||
]);
|
]);
|
||||||
updateDoorActiveClass();
|
updateDoorActiveClass();
|
||||||
}
|
}
|
||||||
|
|
@ -2157,6 +2234,7 @@ export function renderOfficeScene(container, data = {}) {
|
||||||
idleCosmeticTimers.forEach((handle) => window.clearTimeout(handle.timeoutId));
|
idleCosmeticTimers.forEach((handle) => window.clearTimeout(handle.timeoutId));
|
||||||
idleCosmeticTimers.clear();
|
idleCosmeticTimers.clear();
|
||||||
doorVisitors.clear();
|
doorVisitors.clear();
|
||||||
|
agentBoardVisitors.clear();
|
||||||
if (poVisitTimeoutId) window.clearTimeout(poVisitTimeoutId);
|
if (poVisitTimeoutId) window.clearTimeout(poVisitTimeoutId);
|
||||||
poVisitTimeoutId = null;
|
poVisitTimeoutId = null;
|
||||||
poState = "idle";
|
poState = "idle";
|
||||||
|
|
@ -2214,7 +2292,14 @@ export function renderOfficeScene(container, data = {}) {
|
||||||
svg.insertBefore(wallGroup, svg.querySelector(".agents-layer"));
|
svg.insertBefore(wallGroup, svg.querySelector(".agents-layer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const deskLayout = buildDeskLayout(normalizedDeskAgents(agents));
|
// Issue #76: waehrend ein Agent sichtbar zum Board unterwegs ist (siehe agentBoardVisitors
|
||||||
|
// oben), soll sein Schreibtisch leer wirken statt weiterhin besetzt - genau wie bei einem
|
||||||
|
// Tuer-/PO-Besuch verlaesst die Person sichtbar ihren Platz.
|
||||||
|
const visitingAgentIds = new Set(agentBoardVisitors.keys());
|
||||||
|
const deskAgents = normalizedDeskAgents(agents).map((agent) =>
|
||||||
|
agent && visitingAgentIds.has(agent.id) ? null : agent
|
||||||
|
);
|
||||||
|
const deskLayout = buildDeskLayout(deskAgents);
|
||||||
const poDeskAgent = isLive ? { name: PO_DISPLAY_NAME, role: "product_owner", pose: "idle" } : null;
|
const poDeskAgent = isLive ? { name: PO_DISPLAY_NAME, role: "product_owner", pose: "idle" } : null;
|
||||||
// Auch ohne erreichbare API klickbar: das Modal sagt dann selbst, dass es die Projekte
|
// Auch ohne erreichbare API klickbar: das Modal sagt dann selbst, dass es die Projekte
|
||||||
// nicht laden konnte. Ein toter PO waere in genau der Lage, in der man nachsehen will,
|
// nicht laden konnte. Ein toter PO waere in genau der Lage, in der man nachsehen will,
|
||||||
|
|
@ -2227,7 +2312,7 @@ export function renderOfficeScene(container, data = {}) {
|
||||||
svg.insertBefore(desksGroup, svg.querySelector(".agents-layer"));
|
svg.insertBefore(desksGroup, svg.querySelector(".agents-layer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const placements = agentPlacements(agents, deskLayout);
|
const placements = agentPlacements(agents, deskLayout, visitingAgentIds);
|
||||||
currentAgentsLayer = svg.querySelector(".agents-layer");
|
currentAgentsLayer = svg.querySelector(".agents-layer");
|
||||||
currentRegularPlacements = placements;
|
currentRegularPlacements = placements;
|
||||||
repaintAgentsLayer();
|
repaintAgentsLayer();
|
||||||
|
|
@ -2249,7 +2334,11 @@ function normalizedDeskAgents(agents) {
|
||||||
return mapAgentsToDesks(agents).map((agent) => (agent ? normalizeAgentForDisplay(agent) : null));
|
return mapAgentsToDesks(agents).map((agent) => (agent ? normalizeAgentForDisplay(agent) : null));
|
||||||
}
|
}
|
||||||
|
|
||||||
function agentPlacements(agents, deskLayout) {
|
// excludeIds (Issue #76): Agenten, die gerade sichtbar zum Board unterwegs sind (siehe
|
||||||
|
// agentBoardVisitors) - agentVisitorPlacements() steuert ihre Platzierung, sie duerfen hier
|
||||||
|
// nicht zusaetzlich (z.B. als Ruheplatz-Ueberlauf mit ihrem regulaeren state) auftauchen, sonst
|
||||||
|
// gaebe es denselben Agenten doppelt in der Szene.
|
||||||
|
function agentPlacements(agents, deskLayout, excludeIds = new Set()) {
|
||||||
const hasDeskIndex = agents.some((a) => a && typeof a.desk_index !== "undefined");
|
const hasDeskIndex = agents.some((a) => a && typeof a.desk_index !== "undefined");
|
||||||
|
|
||||||
if (!hasDeskIndex) {
|
if (!hasDeskIndex) {
|
||||||
|
|
@ -2273,6 +2362,7 @@ function agentPlacements(agents, deskLayout) {
|
||||||
let overflowIndex = 0;
|
let overflowIndex = 0;
|
||||||
for (const raw of agents) {
|
for (const raw of agents) {
|
||||||
if (seatedIds.has(raw.id)) continue;
|
if (seatedIds.has(raw.id)) continue;
|
||||||
|
if (excludeIds.has(raw.id)) continue;
|
||||||
// isAgentVisible statt isAgentPresent, wie bei den Schreibtischen (mapAgentsToDesks): auch
|
// isAgentVisible statt isAgentPresent, wie bei den Schreibtischen (mapAgentsToDesks): auch
|
||||||
// ein blockierter Agent ohne festen Platz muss sichtbar bleiben.
|
// ein blockierter Agent ohne festen Platz muss sichtbar bleiben.
|
||||||
if (!isAgentVisible(raw)) continue;
|
if (!isAgentVisible(raw)) continue;
|
||||||
|
|
@ -2364,9 +2454,12 @@ async function boot() {
|
||||||
// zugehoerige Persona (Tuerbesucher oder PO) das Board erreicht hat - vorher wird das Ticket
|
// zugehoerige Persona (Tuerbesucher oder PO) das Board erreicht hat - vorher wird das Ticket
|
||||||
// weiterhin an seiner alten Stelle (bzw. bei neuen Tickets: gar nicht) angezeigt.
|
// weiterhin an seiner alten Stelle (bzw. bei neuen Tickets: gar nicht) angezeigt.
|
||||||
const pendingTicketMoves = new Map();
|
const pendingTicketMoves = new Map();
|
||||||
// Issue #61: ticketId -> zustaendiger agentId fuer zurueckgehaltene "in_arbeit"-Wechsel (siehe
|
// Issue #61/#76: ticketId -> zustaendiger agentId fuer zurueckgehaltene "in_arbeit"-Wechsel
|
||||||
// detectAgentOwnedTicketChanges() in office-scene.js). Anders als bei Tuer-/PO-Besuchen gibt es
|
// (siehe detectAgentOwnedTicketChanges() in office-scene.js), fuer die ausnahmsweise KEIN
|
||||||
// dafuer keinen eigenen onArrived-Callback - der Agent meldet seine Ankunft am Board
|
// selbst getakteter Board-Besuch laeuft (triggerAgentBoardVisit() unten deckt den Regelfall
|
||||||
|
// ab) - entweder weil der Agent seine Bewegung bereits selbst meldet
|
||||||
|
// (isAgentReportingBoardVisit()) oder weil kein Schreibtisch fuer eine Animation bekannt ist.
|
||||||
|
// Dafuer gibt es keinen eigenen onArrived-Callback - der Agent meldet seine Ankunft am Board
|
||||||
// unabhaengig ueber seinen eigenen state, daher wird bei jedem refresh() erneut geprueft
|
// unabhaengig ueber seinen eigenen state, daher wird bei jedem refresh() erneut geprueft
|
||||||
// (siehe resolvePendingAgentTicketMoves()).
|
// (siehe resolvePendingAgentTicketMoves()).
|
||||||
const pendingAgentTicketMoves = new Map();
|
const pendingAgentTicketMoves = new Map();
|
||||||
|
|
@ -2433,12 +2526,39 @@ async function boot() {
|
||||||
triggerPoVisit(() => commitTicketMoves(ticketIds));
|
triggerPoVisit(() => commitTicketMoves(ticketIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue #61: Wechsel von/zu "in_arbeit" meldet der zustaendige Agent selbst ueber seinen
|
// Issue #76: Wechsel von/zu "in_arbeit" (siehe AGENT_OWNED_COLUMN in office-scene.js)
|
||||||
// state (siehe AGENT_OWNED_COLUMN in office-scene.js) - das Ticket bleibt daher an seiner
|
// loesen einen selbst getakteten Board-Besuch des zustaendigen Agenten aus, analog zum
|
||||||
// alten Stelle, bis resolvePendingAgentTicketMoves() unten die Ankunft am Board bestaetigt.
|
// PO-/Tuerbesuch - der Agent meldete diese Bewegung in der Praxis so gut wie nie selbst
|
||||||
|
// (Issue #61 gescheitert). Mehrere Aenderungen desselben Agenten im selben Poll teilen
|
||||||
|
// sich einen Besuch statt mehrfach hin- und herzulaufen.
|
||||||
|
const agentsById = new Map(data.agents.map((agent) => [agent.id, agent]));
|
||||||
|
const agentVisitPlans = new Map();
|
||||||
detectAgentOwnedTicketChanges(previousTickets, data.tickets).forEach((change) => {
|
detectAgentOwnedTicketChanges(previousTickets, data.tickets).forEach((change) => {
|
||||||
pendingTicketMoves.set(change.ticketId, previousById.get(change.ticketId) ?? null);
|
pendingTicketMoves.set(change.ticketId, previousById.get(change.ticketId) ?? null);
|
||||||
pendingAgentTicketMoves.set(change.ticketId, change.agentId);
|
|
||||||
|
const agent = agentsById.get(change.agentId);
|
||||||
|
const homeFeet = agent && typeof agent.desk_index === "number" ? deskSeat(agent.desk_index).feet : null;
|
||||||
|
|
||||||
|
if (!homeFeet || isAgentReportingBoardVisit(agent.state)) {
|
||||||
|
// Kein bekannter Schreibtisch (z.B. Agent nicht mehr registriert), oder der Agent
|
||||||
|
// meldet seine Bewegung zum Board bereits selbst (Loesungsrichtung 1 aus Issue #76)
|
||||||
|
// - dann bleibt der selbst getaktete Besuch unten aus, die echte Meldung (bzw. die
|
||||||
|
// bestehende Ankunfts-Erkennung ueber hasAgentReachedBoard()) hat Vorrang.
|
||||||
|
pendingAgentTicketMoves.set(change.ticketId, change.agentId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const plan = agentVisitPlans.get(change.agentId) ?? {
|
||||||
|
agentInfo: { id: agent.id, name: agent.display_name ?? agent.name, role: agent.role },
|
||||||
|
homeFeet,
|
||||||
|
ticketIds: [],
|
||||||
|
};
|
||||||
|
plan.ticketIds.push(change.ticketId);
|
||||||
|
agentVisitPlans.set(change.agentId, plan);
|
||||||
|
});
|
||||||
|
|
||||||
|
agentVisitPlans.forEach(({ agentInfo, homeFeet, ticketIds }, agentId) => {
|
||||||
|
triggerAgentBoardVisit(agentId, agentInfo, homeFeet, () => commitTicketMoves(ticketIds));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
resolvePendingAgentTicketMoves(data.agents);
|
resolvePendingAgentTicketMoves(data.agents);
|
||||||
|
|
|
||||||
|
|
@ -875,13 +875,16 @@ export function detectUnassignedTicketChanges(previousTickets = [], currentTicke
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issue #61: Gegenstueck zu detectUnassignedTicketChanges() fuer genau die dort ausgeschlossenen
|
* Issue #61: Gegenstueck zu detectUnassignedTicketChanges() fuer genau die dort ausgeschlossenen
|
||||||
* Wechsel von/zu "in_arbeit" (siehe AGENT_OWNED_COLUMN). Anders als Tuer-/PO-Besuche gibt es fuer
|
* Wechsel von/zu "in_arbeit" (siehe AGENT_OWNED_COLUMN). office-render.js loest fuer jeden hier
|
||||||
* diese Wechsel keine hier selbst getaktete Animation - der zustaendige Agent meldet seine
|
* erkannten Wechsel einen sichtbaren Board-Besuch des zustaendigen Agenten aus, analog zu den
|
||||||
* Bewegung zum Board (state "walking_to_board"/"interacting_with_board") unabhaengig ueber seinen
|
* Tuer-/PO-Besuchen (Issue #76: bis dahin blieb der Agent sichtbar an seinem Platz sitzen, weil
|
||||||
* eigenen state. office-render.js nutzt das Ergebnis, um das Ticket so lange an seiner alten
|
* er die dafuer vorgesehenen states "walking_to_board"/"interacting_with_board" in der Praxis
|
||||||
* Stelle zu halten, bis hasAgentReachedBoard() fuer den zustaendigen Agenten zutrifft (siehe dort)
|
* nicht meldete). Meldet der Agent seine Bewegung ausnahmsweise doch selbst (siehe
|
||||||
* - sonst wuerde das Ticket bereits die Spalte wechseln, waehrend der Entwickler sichtbar noch
|
* isAgentReportingBoardVisit()), bleibt dieser selbst getaktete Besuch aus und die echte Meldung
|
||||||
* auf dem Weg zum Board ist.
|
* behaelt Vorrang - office-render.js nutzt das Ergebnis dann weiterhin, um das Ticket so lange an
|
||||||
|
* seiner alten Stelle zu halten, bis hasAgentReachedBoard() fuer den zustaendigen Agenten zutrifft
|
||||||
|
* (siehe dort) - sonst wuerde das Ticket bereits die Spalte wechseln, waehrend der Entwickler
|
||||||
|
* sichtbar noch auf dem Weg zum Board ist.
|
||||||
*
|
*
|
||||||
* @param {Array<{id: number, column_name: string, assignee_agent_id?: number|string|null}>} previousTickets
|
* @param {Array<{id: number, column_name: string, assignee_agent_id?: number|string|null}>} previousTickets
|
||||||
* @param {Array<{id: number, column_name: string, assignee_agent_id?: number|string|null}>} currentTickets
|
* @param {Array<{id: number, column_name: string, assignee_agent_id?: number|string|null}>} currentTickets
|
||||||
|
|
@ -923,6 +926,23 @@ export function hasAgentReachedBoard(agentState) {
|
||||||
return !STATES_BEFORE_BOARD_ARRIVAL.has(agentState);
|
return !STATES_BEFORE_BOARD_ARRIVAL.has(agentState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// States, an denen zu erkennen ist, dass der zustaendige Agent seine Bewegung zum Board bereits
|
||||||
|
// selbst meldet (Loesungsrichtung 1 aus Issue #76, ueber POST /api/v1/agents/{id}/activity,
|
||||||
|
// siehe API.md). In der Praxis meldeten Agenten diese States bislang so gut wie nie (siehe
|
||||||
|
// detectAgentOwnedTicketChanges()) - kommt die Meldung doch, soll sie Vorrang vor dem selbst
|
||||||
|
// getakteten Board-Besuch (Loesungsrichtung 2) behalten, statt dass beide gleichzeitig laufen.
|
||||||
|
const AGENT_REPORTED_BOARD_STATES = new Set(["walking_to_board", "interacting_with_board"]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string|undefined|null} agentState - zuletzt gemeldeter Agent.state (API).
|
||||||
|
* @returns {boolean} true, wenn der Agent seine Bewegung zum Board bereits selbst meldet - in dem
|
||||||
|
* Fall soll office-render.js keinen zusaetzlichen, selbst getakteten Board-Besuch anstossen
|
||||||
|
* (Issue #76).
|
||||||
|
*/
|
||||||
|
export function isAgentReportingBoardVisit(agentState) {
|
||||||
|
return AGENT_REPORTED_BOARD_STATES.has(agentState);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issue #55: Bislang wurde ein Ticket sofort an seinem neuen Platz gezeichnet, sobald eine
|
* Issue #55: Bislang wurde ein Ticket sofort an seinem neuen Platz gezeichnet, sobald eine
|
||||||
* Aenderung erkannt wurde - Tuerbesuch/PO-Besuch liefen davon unabhaengig erst danach als reine
|
* Aenderung erkannt wurde - Tuerbesuch/PO-Besuch liefen davon unabhaengig erst danach als reine
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ import {
|
||||||
applyPendingTicketMoves,
|
applyPendingTicketMoves,
|
||||||
detectAgentOwnedTicketChanges,
|
detectAgentOwnedTicketChanges,
|
||||||
hasAgentReachedBoard,
|
hasAgentReachedBoard,
|
||||||
|
isAgentReportingBoardVisit,
|
||||||
DEFAULT_RELOAD_INTERVAL_SECONDS,
|
DEFAULT_RELOAD_INTERVAL_SECONDS,
|
||||||
resolveReloadIntervalSeconds,
|
resolveReloadIntervalSeconds,
|
||||||
nextCountdownSeconds,
|
nextCountdownSeconds,
|
||||||
|
|
@ -810,6 +811,15 @@ test("hasAgentReachedBoard ist waehrend walking_to_board false, sonst true (Issu
|
||||||
assert.equal(hasAgentReachedBoard(undefined), true);
|
assert.equal(hasAgentReachedBoard(undefined), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("isAgentReportingBoardVisit erkennt eigene Meldung des Agenten (Issue #76)", () => {
|
||||||
|
assert.equal(isAgentReportingBoardVisit("walking_to_board"), true);
|
||||||
|
assert.equal(isAgentReportingBoardVisit("interacting_with_board"), true);
|
||||||
|
assert.equal(isAgentReportingBoardVisit("walking_back"), false);
|
||||||
|
assert.equal(isAgentReportingBoardVisit("idle"), false);
|
||||||
|
assert.equal(isAgentReportingBoardVisit("working"), false);
|
||||||
|
assert.equal(isAgentReportingBoardVisit(undefined), false);
|
||||||
|
});
|
||||||
|
|
||||||
test("advancePoVisitStage durchlaeuft alle Stages und liefert am Ende null", () => {
|
test("advancePoVisitStage durchlaeuft alle Stages und liefert am Ende null", () => {
|
||||||
let stage = PO_VISIT_STAGES[0];
|
let stage = PO_VISIT_STAGES[0];
|
||||||
const seen = [stage];
|
const seen = [stage];
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue