PICK SKY DEL btn: JS-inject after wheel paints so a blank modal carries no DEL action — TDD

Previously the DEL btn was always template-rendered inside .sky-wheel-col, which on a fresh PICK SKY modal (form pristine, schedulePreview not yet fired) put a red DEL btn floating in the empty wheel area suggesting there's something to delete when the user hasn't even seen a wheel yet. Refactored: drop the <button id="id_sky_delete_btn"> from _sky_overlay.html, lazily create it in JS via _ensureDelBtn() called from the schedulePreview success handler (right after SkyWheel.draw/redraw); the existing DEL click handler now also removes the btn from the DOM after clearing the SVG, so the next preview re-injects it. PickSkyRenderingTest.test_no_sky_delete_btn_in_blank_sky_select_modal IT asserts `id="id_sky_delete_btn"` doesn't appear in the rendered HTML for a SKY_SELECT room (the literal identifier still lives inside the inline <script> that does the injection — assertion targets the HTML-attribute-syntax form so the JS reference doesn't trip it). Existing PickSkyDelTest FT still green: it fires preview before clicking DEL, so the btn is present at click time.

Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-05-08 14:56:43 -04:00
parent 301b4e8201
commit 8a8d1536b1
2 changed files with 39 additions and 13 deletions

View File

@@ -87,10 +87,12 @@
</div>
{# ── Wheel column ─────────────────────────────────────── #}
{# DEL btn is JS-injected after the wheel paints (see schedule #}
{# Preview success handler) — keeping it out of the template #}
{# means a blank PICK SKY modal can never show a DEL action #}
{# against a non-existent wheel. #}
<div class="sky-wheel-col">
<svg id="id_sky_svg" class="sky-svg"></svg>
<button type="button" id="id_sky_delete_btn"
class="btn btn-danger">DEL</button>
</div>
</div>{# /.sky-modal-body #}
@@ -343,6 +345,7 @@
} else {
SkyWheel.draw(svgEl, data);
}
_ensureDelBtn();
})
.catch(err => {
setStatus(`Could not fetch chart: ${err.message}`, 'error');
@@ -401,20 +404,26 @@
window.location.reload();
}
// ── DEL btn — clears wheel + form + localStorage (no server hit) ────────
// ── DEL btn — JS-injected after the wheel paints; absent on a blank modal
// PICK SKY's wheel is a live preview; un-saved data lives only in LS_KEY.
// Match the My Sky applet / Dashsky pattern but skip the server delete —
// there's no Character draft created during preview (sky_save fires only
// on SAVE SKY click w. action='confirm').
// The btn is created lazily after the first SkyWheel.draw so a blank modal
// can never offer a DEL action against a non-existent wheel; clearing the
// SVG removes the btn from the DOM entirely (re-injected on next preview).
// window.showGuard is assigned in a base.html script that loads BELOW the
// content block — defer the readiness check to click-time so the listener
// bind happens regardless of inline-script execution order.
const delBtn = document.getElementById('id_sky_delete_btn');
if (delBtn) {
delBtn.addEventListener('click', () => {
let _delBtn = null;
function _ensureDelBtn() {
if (_delBtn) return;
const wheelCol = document.querySelector('.sky-wheel-col');
if (!wheelCol) return;
_delBtn = document.createElement('button');
_delBtn.type = 'button';
_delBtn.id = 'id_sky_delete_btn';
_delBtn.className = 'btn btn-danger';
_delBtn.textContent = 'DEL';
wheelCol.appendChild(_delBtn);
_delBtn.addEventListener('click', () => {
if (!window.showGuard) return;
window.showGuard(delBtn, 'Forget sky?', () => {
window.showGuard(_delBtn, 'Forget sky?', () => {
while (svgEl.firstChild) svgEl.removeChild(svgEl.firstChild);
form.reset();
latInput.value = '';
@@ -425,6 +434,10 @@
confirmBtn.disabled = true;
setStatus('');
try { localStorage.removeItem(LS_KEY); } catch (_) {}
if (_delBtn) {
_delBtn.remove();
_delBtn = null;
}
});
});
}