fix: /local-workspace — chemin du header + clic sur un dossier du sidebar (v7.69.9)
FlowDeck CI / lint (push) Successful in 1m37s
FlowDeck CI / test (push) Failing after 24m19s
FlowDeck CI / docker (push) Skipped

Corrige deux régressions de /local-workspace :

- le chemin du header restait bloqué sur « Home / <workspace> » quel que
  soit le dossier affiché : la route rend désormais breadcrumb_items
  (Home / <workspace> / <dossier> / <sous-dossier>, niveaux cliquables,
  collapse « … » au-delà de 4) et la navigation sans rechargement recalcule
  le chemin via l'event flowdeck:breadcrumb-changed ;
- le clic sur un dossier du sidebar affichait TOUS les composants à la
  fois : Alpine.data('wsInitData') retournait le même objet singleton, le
  2e montage (navigation partielle) levait « Cannot redefine property:
  \ » et initTree abandonnait, laissant tout le contenu au state
  brut. La factory retourne désormais une enveloppe fraîche par montage
  qui délègue à l'état réactif partagé. #lw-config est aussi relu à chaque
  exécution (le 2e montage gardait le folder_id du 1er chargement).

Inclus également le travail en cours de l'arbre : Library (colonnes Last
visited/Source, ordre d'en-tête, favoris à icônes Workspace), Meeting
Notes (bloc, CSS, routes, docs), coloration de code hljs, badges
favori/publié dans l'arbre local-workspace, docs (DATA_MODEL,
architectures) et tests associés.
This commit is contained in:
2026-10-09 16:58:04 -04:00
parent 7468e497c6
commit 0218d8f5e5
44 changed files with 12060 additions and 1729 deletions
+113
View File
@@ -0,0 +1,113 @@
"""Vendor highlight.js (common bundle + extra languages + themes) into static/.
Run: python3 scripts/vendor_hljs.py
Fetches from cdnjs 11.9.0 (pinned for stability) and writes:
static/js/highlight.min.js (common bundle, ~40 languages)
static/js/highlight-extra.min.js (extra languages concatenated)
static/css/highlight.css (github light + github-dark scoped on [data-theme])
"""
import re
import urllib.request
VERSION = "11.9.0"
BASE = f"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/{VERSION}"
COMMON_JS = f"{BASE}/highlight.min.js"
LANG_URL = BASE + "/languages/{lang}.min.js"
LIGHT_CSS = BASE + "/styles/github.min.css"
DARK_CSS = BASE + "/styles/github-dark.min.css"
# Extra languages NOT in the common bundle, covering a maximum of file types.
# NOTE (verified 11.9.0): "fish", "toml" and "cobol" have NO standalone grammar
# on cdnjs for this version — code-highlight.js maps them to the closest
# bundled grammar (fish→shell, toml→ini, cobol→plaintext).
EXTRA_LANGS = [
# shells / ops
"powershell", "dos", "fish",
# build / containers / config
"dockerfile", "cmake", "toml", "graphql", "protobuf", "thrift",
# web servers / protocols (absent du bundle common cdnjs 11.9.0)
"apache", "http", "nginx",
# JVM / functional / misc popular
"scala", "groovy", "haskell", "elixir", "erlang", "clojure",
"ocaml", "fsharp", "nim", "d", "julia", "matlab",
"dart", "latex", "vim", "awk", "delphi",
# asm / hdl / legacy
"armasm", "x86asm", "vhdl", "verilog", "ada", "fortran", "cobol",
"gcode", "stata", "stan",
]
def fetch(url: str) -> str:
req = urllib.request.Request(url, headers={"User-Agent": "FlowDeck-vendor/1.0"})
with urllib.request.urlopen(req, timeout=30) as r:
return r.read().decode("utf-8", "replace")
def scope_css(css: str, scope: str) -> str:
"""Prefix every rule whose selector mentions .hljs with the theme scope."""
out = []
for chunk in css.split("}"):
if "{" not in chunk:
out.append(chunk)
continue
selectors, body = chunk.split("{", 1)
parts = []
for sel in selectors.split(","):
sel = sel.strip()
if not sel:
continue
if ".hljs" in sel:
parts.append(f"{scope} {sel}")
else:
parts.append(sel)
out.append(", ".join(parts) + "{" + body)
return "}".join(out)
def main() -> None:
from pathlib import Path
root = Path(__file__).resolve().parent.parent
js_dir = root / "static" / "js"
css_dir = root / "static" / "css"
common = fetch(COMMON_JS)
(js_dir / "highlight.min.js").write_text(common, encoding="utf-8")
print(f"highlight.min.js: {len(common)} bytes")
extra_parts = []
missing = []
for lang in EXTRA_LANGS:
try:
code = fetch(LANG_URL.format(lang=lang))
extra_parts.append(f"\n/* hljs lang: {lang} */\n" + code)
print(f" + {lang}: {len(code)} bytes")
except Exception as exc: # noqa: BLE001
missing.append(lang)
print(f" ! {lang} missing: {exc}")
(js_dir / "highlight-extra.min.js").write_text(
"/* FlowDeck — highlight.js extra languages (cdnjs %s) */\n" % VERSION
+ "\n".join(extra_parts),
encoding="utf-8",
)
light = fetch(LIGHT_CSS)
dark = fetch(DARK_CSS)
css = (
"/* FlowDeck — highlight.js themes (cdnjs %s): github (light) + "
"github-dark scoped on html[data-theme=\"dark\"] */\n" % VERSION
+ light
+ "\n"
+ scope_css(dark, 'html[data-theme="dark"]')
+ "\n/* FlowDeck tweaks: keep code blocks integrated with app surfaces */\n"
+ ".hljs{background:transparent;}\n"
)
(css_dir / "highlight.css").write_text(css, encoding="utf-8")
print(f"highlight.css: {len(css)} bytes")
if missing:
print("MISSING:", missing)
if __name__ == "__main__":
main()