mcdview 0.28.0__tar.gz → 0.28.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcdview
3
- Version: 0.28.0
3
+ Version: 0.28.2
4
4
  Summary: Turn a SQL data model into one self-contained, interactive HTML page
5
5
  Project-URL: Homepage, https://github.com/Gheop/mcdview
6
6
  Project-URL: Demo, https://gheop.github.io/mcdview/
@@ -324,6 +324,26 @@ file's header.
324
324
 
325
325
  ## Changelog
326
326
 
327
+ ### v0.28.2 — Fix the theme toggle and a stuck audit-FK checkbox (2026-09-01)
328
+
329
+ - The theme button no longer needs two clicks to reach dark from a light OS. It
330
+ cycled system → light → dark, but "system" and "light" look identical on a
331
+ light OS, so the first click seemed to do nothing. A click now always changes
332
+ the visible theme, skipping any step that would look the same.
333
+ - The "audit FKs" checkbox is hidden again when a model has no audit FKs. A
334
+ `#hud label { display: flex }` rule overrode the `hidden` attribute, so the
335
+ checkbox showed even with nothing to toggle.
336
+
337
+ ### v0.28.1 — Fix links pointing into space when saved positions load (2026-08-31)
338
+
339
+ - A viewer who had dragged tables saw the FK links briefly point into empty
340
+ space on the next open. Restoring the saved layout re-applied each box's
341
+ position after the page had settled, so the boxes animated from their
342
+ auto-placement spot to their saved spot and the first links were drawn against
343
+ them mid-slide. The restore now jumps the boxes into place with no animation,
344
+ so the links are correct from the first paint. Added a headless-Chrome
345
+ regression test (`tests/test_positions.py`).
346
+
327
347
  ### v0.28.0 — Auto attribution badge on branded pages (2026-08-31)
328
348
 
329
349
  - A branded page (`--logo` or `--home-url`) now carries a discreet clickable
@@ -302,6 +302,26 @@ file's header.
302
302
 
303
303
  ## Changelog
304
304
 
305
+ ### v0.28.2 — Fix the theme toggle and a stuck audit-FK checkbox (2026-09-01)
306
+
307
+ - The theme button no longer needs two clicks to reach dark from a light OS. It
308
+ cycled system → light → dark, but "system" and "light" look identical on a
309
+ light OS, so the first click seemed to do nothing. A click now always changes
310
+ the visible theme, skipping any step that would look the same.
311
+ - The "audit FKs" checkbox is hidden again when a model has no audit FKs. A
312
+ `#hud label { display: flex }` rule overrode the `hidden` attribute, so the
313
+ checkbox showed even with nothing to toggle.
314
+
315
+ ### v0.28.1 — Fix links pointing into space when saved positions load (2026-08-31)
316
+
317
+ - A viewer who had dragged tables saw the FK links briefly point into empty
318
+ space on the next open. Restoring the saved layout re-applied each box's
319
+ position after the page had settled, so the boxes animated from their
320
+ auto-placement spot to their saved spot and the first links were drawn against
321
+ them mid-slide. The restore now jumps the boxes into place with no animation,
322
+ so the links are correct from the first paint. Added a headless-Chrome
323
+ regression test (`tests/test_positions.py`).
324
+
305
325
  ### v0.28.0 — Auto attribution badge on branded pages (2026-08-31)
306
326
 
307
327
  - A branded page (`--logo` or `--home-url`) now carries a discreet clickable
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mcdview"
7
- version = "0.28.0"
7
+ version = "0.28.2"
8
8
  description = "Turn a SQL data model into one self-contained, interactive HTML page"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -46,6 +46,10 @@
46
46
  box-shadow: 0 2px 12px #0b74c455; }
47
47
  .table.efface { opacity: 0; pointer-events: none; }
48
48
  .table.deplace { transition: none; cursor: grabbing; }
49
+ /* restoring saved positions must be instant, never an animated slide from the
50
+ auto-placement spot (the initial links would be drawn against the moving box
51
+ and point into space until a redraw); see restaurerPositions */
52
+ #plan.instant .table { transition: none; }
49
53
  .table h3 { margin: 0; padding: 4px 10px; font-size: 13px; color: #1c1e22;
50
54
  border-radius: 4px 4px 0 0; white-space: nowrap; }
51
55
  .table ul { margin: 0; padding: 3px 10px 5px; list-style: none; }
@@ -151,6 +155,7 @@
151
155
  #hud button { padding: 4px 10px; border: 1px solid var(--bord); border-radius: 5px;
152
156
  background: var(--panneau); color: var(--encre); cursor: pointer; }
153
157
  #hud label { display: flex; gap: 4px; align-items: center; font-size: 13px; }
158
+ #hud label[hidden] { display: none; } /* author display:flex beats [hidden]; restore it */
154
159
  #compte { font-size: 12px; opacity: .55; white-space: nowrap; }
155
160
  .table:hover { border-color: var(--ligne-vive); }
156
161
  #panneau { position: absolute; top: 0; right: 0; bottom: 0; width: 340px;
@@ -392,6 +397,12 @@ function sauverPositions() {
392
397
  let pos = null;
393
398
  try { pos = JSON.parse(localStorage.getItem(CLE_POS)); } catch (e) { return; }
394
399
  if (!pos) return;
400
+ // the position snapshot above forced a layout at the auto-placement spot, so
401
+ // changing left/top here would animate (the .table left/top transition). Kill
402
+ // the transition while we jump the boxes to their saved spots, flush the
403
+ // layout, then re-enable it — otherwise the boxes slide in and the first links
404
+ // are drawn against them mid-flight, pointing into space until the next redraw.
405
+ plan.classList.add("instant");
395
406
  Object.keys(elems).forEach(cle => {
396
407
  if (pos[cle] && typeof pos[cle].x === "number") {
397
408
  origines[cle] = pos[cle];
@@ -399,6 +410,8 @@ function sauverPositions() {
399
410
  elems[cle].style.top = pos[cle].y + "px";
400
411
  }
401
412
  });
413
+ plan.offsetLeft; // flush the jump so it never animates
414
+ plan.classList.remove("instant");
402
415
  })();
403
416
 
404
417
  // --- schema legend: one chip per schema, click to frame its zone ---
@@ -741,7 +754,10 @@ document.addEventListener("keydown", e => {
741
754
  else if (e.key === "r" && !btnReorg.disabled) reorganiser();
742
755
  });
743
756
 
744
- // theme toggle: cycle system → light → dark, remembered per viewer
757
+ // theme toggle: cycle system → light → dark, remembered per viewer. A click
758
+ // always changes the visible theme: when the next state would render the same
759
+ // as now (e.g. "system" equals "light" on a light OS), skip it — otherwise the
760
+ // first click after load looked like a no-op (system → light on a light OS)
745
761
  const btnTheme = document.getElementById("theme");
746
762
  (function initTheme() {
747
763
  // a ?theme= deep-link wins over the remembered choice (see view deep-links)
@@ -753,8 +769,12 @@ const btnTheme = document.getElementById("theme");
753
769
  })();
754
770
  btnTheme.addEventListener("click", () => {
755
771
  const ordre = ["", "light", "dark"];
772
+ const sysSombre = matchMedia("(prefers-color-scheme: dark)").matches;
773
+ const rendu = e => e || (sysSombre ? "dark" : "light"); // what a state looks like
756
774
  const actuel = document.documentElement.dataset.theme || "";
757
- const suivant = ordre[(ordre.indexOf(actuel) + 1) % ordre.length];
775
+ let i = ordre.indexOf(actuel), suivant;
776
+ do { i = (i + 1) % ordre.length; suivant = ordre[i]; }
777
+ while (rendu(suivant) === rendu(actuel)); // never a step that looks identical
758
778
  if (suivant) document.documentElement.dataset.theme = suivant;
759
779
  else delete document.documentElement.dataset.theme;
760
780
  try {
File without changes
File without changes
File without changes
File without changes