sky.html: DEL btn at wheel center; async SAVE SKY transitions into saved state without reload; pre-save hides wheel-col so form+SAVE SKY stay centered — TDD

DEL btn (.btn-danger, "Forget sky?" data-confirm wired to the global #id_guard_portal) sits absolutely centered inside .sky-wheel-col; OK submits a POST to the new sky_delete view, which clears every sky_* field on the User model & redirects back to /dashboard/sky/.

The sky.html aperture is now uniform across saved/unsaved: form-col is always flex-column align-center justify-center so the fields + SAVE SKY pair sits visually centered. body.sky-saved adds *only* the snap-binary scroll layer (scroll-snap-type:y, modal-body display:contents, cols min-height:100% scroll-snap-align:start, wheel-col aspect-ratio cap released, form-col flex:0 0 auto so the snap basis wins) — the column-stacking is no longer gated.

Async save: SAVE SKY's success branch now calls _activateSavedState(), which adds body.sky-saved, draws the wheel from _lastChartData, pins overlay.scrollTop to the form section's offsetTop, then runs the existing _scrollApertureToTop ease-out so the wheel reveals from above instead of replacing the form with a hard cut. The wheel preview that previously redrew during typing is now gated on _savedSky — pre-first-save typing fetches the chart data (so SAVE SKY enables) but does not render the wheel, mirroring the My Sky applet's "no wheel until saved" UX. The in-room PICK SKY overlay (_sky_overlay.html) still previews live, deliberately untouched.

Pre-save the wheel-col is hidden via `body:not(.sky-saved) .sky-page .sky-wheel-col { display: none }`, so the empty SVG can't shunt the form below the fold (& the DEL btn rides the same selector since it lives inside .sky-wheel-col).

Tests: SkyDeleteTest IT class (5: clears fields, redirects, 405 on GET, login required, preserves unrelated user fields). MySkyDeleteFlowTest FT class (3: DEL btn visibility gated on sky data, NVM dismisses w. data intact, OK clears + reverts body class). MySkyAsyncSaveTest FT (1: fresh user → SAVE SKY → body picks up sky-saved, wheel SVG populates, DEL btn becomes visible — all without a page reload). All 13 sky FTs + sky ITs green; existing MySkyApertureSnapScrollTest & MySkyTimezoneRefreshTest still pass.

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 13:07:56 -04:00
parent bbd1b22bb0
commit 9ff437012a
6 changed files with 346 additions and 34 deletions

View File

@@ -931,6 +931,18 @@ body.page-sky {
overflow-y: auto;
}
// DEL btn pinned at the wheel center — only rendered when chart_data exists.
// Anchored to .sky-wheel-col (which has position:relative) so the btn sits
// over the SVG's geometric center regardless of the snap layout's outer sizing.
#id_sky_delete_form {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 5;
margin: 0;
}
// Stack wheel above form; allow body to grow past viewport (page scrolls, not body)
.sky-page .sky-modal-body {
flex-direction: column;
@@ -948,21 +960,45 @@ body.page-sky {
align-self: center;
}
// Form col runs horizontally below the wheel (same compact pattern as narrow-portrait modal)
// Form col is a vertical stack — fields on top, SAVE SKY beneath, both
// centered horizontally. Pre-save the wheel-col is hidden so this column
// fills the aperture & sits visually centered. Post-save the snap layout
// (body.sky-saved) keeps the same internal stacking but pins each col to
// the aperture height.
.sky-page .sky-form-col {
flex: 0 0 auto;
flex-direction: row;
align-items: flex-end;
flex: 1 0 auto;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1rem;
min-height: 100%;
border-right: none;
border-top: 0.1rem solid rgba(var(--terUser), 0.12);
}
.sky-page .sky-form-main {
flex: 1;
flex: 0 0 auto;
width: 100%;
max-width: 22rem;
min-width: 0;
max-height: none;
overflow-y: visible;
}
// The (max-width:600px) block (written for the in-room PICK SKY modal where
// form-col is flex-row) sets align-self:flex-end on the btn — that's "right"
// once we flip to flex-column. Reset.
.sky-page .sky-form-col > #id_sky_confirm {
align-self: auto;
}
// Pre-save the wheel section is hidden — no preview wheel shunts the form
// downward & the user clearly sees SAVE SKY. The DEL btn rides along so
// async SAVE SKY can reveal it without a template re-render.
body:not(.sky-saved) .sky-page .sky-wheel-col {
display: none;
}
// ── Snap-binary aperture (post-save) ──────────────────────────────────────────
// Once a sky is saved, the .sky-page aperture flips into scroll-snap mode:
// the wheel section + form section each fill the aperture, so scrolling toggles
@@ -1004,30 +1040,11 @@ body.sky-saved {
width: 100%;
}
// Stack form-main on top, SAVE SKY beneath — both centered horizontally,
// and the pair vertically centered inside the aperture (parity w. the
// wheel). .sky-page .sky-form-col defaults to flex-row align-end which
// would otherwise pin form-main left and the btn bottom-right.
// form-col loses its grow/min-height fill so the snap basis (min-height:100%
// above) wins instead — without this, two `flex: 1 0 auto` sections compete
// for the aperture height and the snap stops landing at the col boundaries.
.sky-page .sky-form-col {
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1rem;
}
.sky-page .sky-form-main {
flex: 0 0 auto;
width: 100%;
max-width: 22rem;
max-height: none; // reset the (max-width:600px) cap
overflow-y: visible; // no inner scroll — aperture handles it
}
// The (max-width:600px) block sets align-self:flex-end on the btn — that's
// "bottom" under the default flex-row form-col, but becomes "right" once we
// flip the col to flex-direction:column. Reset to inherit align-items:center.
.sky-page .sky-form-col > #id_sky_confirm {
align-self: auto;
}
}