stabilize dashboard card rendering to avoid constant article reloads
This commit is contained in:
parent
20568d2b3e
commit
c12952d4b2
1 changed files with 37 additions and 14 deletions
49
data.js
49
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) {
|
||||
for (const card of root.querySelectorAll("article.card")) {
|
||||
card.remove();
|
||||
}
|
||||
if (!$("dashboardEmpty")) {
|
||||
root.innerHTML = `<div class="empty" id="dashboardEmpty">No simulation instances yet. Create one to start the web simulation flow.</div>`;
|
||||
}
|
||||
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() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue