diff --git a/data.js b/data.js index e7f6ec9..e3410ad 100644 --- a/data.js +++ b/data.js @@ -147,16 +147,26 @@ function createCardElement(sim) { return article; } +function setTextIfChanged(element, nextValue) { + if (!element) return; + if (element.textContent !== nextValue) { + element.textContent = nextValue; + } +} + function updateCardElement(card, sim) { - card.querySelector('[data-role="title"]').textContent = sim.title; - card.querySelector('[data-role="idline"]').textContent = `sim-${sim.id} | ${sim.mode} | seed=${sim.seed}`; - card.querySelector('[data-role="progress"]').textContent = sim.progress; - card.querySelector('[data-role="scoreboard"]').textContent = sim.scoreboard; - card.querySelector('[data-role="outcome"]').textContent = sim.outcome; + setTextIfChanged(card.querySelector('[data-role="title"]'), sim.title); + setTextIfChanged(card.querySelector('[data-role="idline"]'), `sim-${sim.id} | ${sim.mode} | seed=${sim.seed}`); + setTextIfChanged(card.querySelector('[data-role="progress"]'), sim.progress); + setTextIfChanged(card.querySelector('[data-role="scoreboard"]'), sim.scoreboard); + setTextIfChanged(card.querySelector('[data-role="outcome"]'), sim.outcome); const pill = card.querySelector('[data-role="pill"]'); - pill.className = `pill ${sim.status}`; - pill.textContent = sim.status; + const nextPillClass = `pill ${sim.status}`; + if (pill.className !== nextPillClass) { + pill.className = nextPillClass; + } + setTextIfChanged(pill, sim.status); if (card.dataset.status !== sim.status) { card.dataset.status = sim.status; @@ -169,33 +179,46 @@ function renderDashboard() { if (!root) return; if (state.simulations.length === 0) { - root.innerHTML = `
No simulation instances yet. Create one to start the web simulation flow.
`; + for (const card of root.querySelectorAll("article.card")) { + card.remove(); + } + if (!$("dashboardEmpty")) { + root.innerHTML = `
No simulation instances yet. Create one to start the web simulation flow.
`; + } return; } + const emptyNode = $("dashboardEmpty"); + if (emptyNode) { + emptyNode.remove(); + } + const existingCards = new Map( [...root.querySelectorAll("article.card")].map((card) => [Number(card.dataset.id), card]), ); const activeIds = new Set(state.simulations.map((sim) => sim.id)); - const fragment = document.createDocumentFragment(); - for (const sim of state.simulations) { + for (let index = 0; index < state.simulations.length; index += 1) { + const sim = state.simulations[index]; let card = existingCards.get(sim.id); if (!card) { card = createCardElement(sim); + root.appendChild(card); } + updateCardElement(card, sim); - fragment.appendChild(card); + + if (root.children[index] !== card) { + root.insertBefore(card, root.children[index] || null); + } } for (const [id, card] of existingCards.entries()) { - if (!activeIds.has(id) && card.parentElement === root) { + if (!activeIds.has(id)) { card.remove(); } } - - root.replaceChildren(fragment); } function renderStats() {