Commit Graph
334 Commits
Author SHA1 Message Date
bruno 631c106b01 fix: context menu uses Alpine proxy (window._wsData) instead of raw object
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
The context menu component (_ctxMenuData) was calling methods on
window._wsInitData (the raw JS object), NOT on Alpine's reactive proxy.
This meant that changes made by ctxMenuDelete/ctxMenuDuplicate (like
updating displayTree) were applied to the raw object but not reflected
in Alpine's reactive proxy that controls DOM rendering.

Fix: _ctxMenuData now uses a _ws() helper that returns window._wsData
(Alpine proxy, set in init()) with fallback to window._wsInitData for
safety. All context menu actions now go through the reactive proxy.
2026-07-16 09:59:07 -04:00
bruno 30e1879ac2 fix: deleteWithUndo uses _reloadAfterAction() instead of manual tree manipulation
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Replaced fragile _removeFromTree() + displayTree spread (which had Alpine
reactivity issues) with a clean _reloadAfterAction() call that reloads the
tree from the API. This is the same approach used by doDelete() and
doRename(), which work reliably. _reloadAfterAction also triggers the
sidebar refresh via window.appState.refreshSidebarTree().
2026-07-16 09:45:45 -04:00
bruno 6e4adaad8b fix: direct sidebar refresh via window.appState instead of events
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Replaced the fragile event-based sidebar refresh with direct function calls:
- appState.init() now sets window.appState = this
- _reloadAfterAction(), doCreate(), deleteWithUndo() call
  window.appState.refreshSidebarTree() directly (no DOM event)
- Sidebar handlers (drop, deleteWorkspacePage, wsCtxAction, newFolder)
  call window._wsData._reloadAfterAction() directly (no DOM event)
- Removed event listeners for flowdeck:workspace-changed and
  flowdeck:sidebar-refresh from local_workspace.html

This is more reliable than CustomEvent which had timing/scope issues.
2026-07-16 09:41:46 -04:00
bruno 50f8e0a938 fix: sidebar drag-drop uses dynamic refresh instead of full page reload
FlowDeck CI / test (push) Failing after 6s
FlowDeck CI / docker (push) Has been skipped
- Sidebar 'drop' handler now calls refreshSidebarTree() + dispatches
  'flowdeck:workspace-changed' instead of window.location.reload()
- Global refreshSidebarFromEvent() now targets .app-layout[x-data] first
  to avoid picking up the wrong Alpine component when multiple x-data
  elements exist on the page
2026-07-16 09:29:34 -04:00
bruno 4217978eaa fix: ctxMenuDelete triggers sidebar refresh via flowdeck:sidebar-refresh
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
deleteWithUndo() (called by ctxMenuDelete) was removing the node from the
local tree but never notifying the sidebar to refresh. Added dispatch of
'flowdeck:sidebar-refresh' event so the sidebar tree updates dynamically
without requiring a full page reload.
2026-07-16 09:24:24 -04:00
bruno ae2b1c5664 fix: use backslash-escape for single quotes (not HTML entity)
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
HTML entities like ' are decoded by the browser BEFORE Alpine evaluates
the expression, so the JS parser still sees a raw single quote. Backslash
escape (\') is the correct approach: the HTML parser preserves it, then
JavaScript interprets \' as an escaped quote in the string literal.
2026-07-16 09:18:20 -04:00
bruno 5b6b251119 fix: escape single quotes in workspace tree macro to prevent JS parse errors
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
Page names containing apostrophes (e.g. "02-Structure d'entrainements.md")
broke Alpine.js directives because Jinja2's |e filter doesn't escape single
quotes. Replaced ' with ' HTML entity in Alpine expression attributes
(showWsContext, wsTouchEnd).
2026-07-16 09:16:33 -04:00
bruno 0edcdbe82a fix: le menu contextuel Delete/Rename rafraîchit maintenant les deux arbres
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- Nouvel événement 'flowdeck:workspace-changed' dispatché depuis les actions
  sidebar (deleteWorkspacePage, wsCtxAction rename/delete, newFolderInWorkspace)
- La vue principale local_workspace.html écoute 'flowdeck:workspace-changed'
  et appelle _reloadAfterAction() pour rafraîchir son arbre
- _reloadAfterAction() continue à dispatcher 'flowdeck:sidebar-refresh'
  pour le rafraîchissement sidebar uniquement (évite la boucle infinie)
- Correction du double confirm dans deleteWorkspacePage (skipConfirm=true
  depuis wsCtxAction qui a déjà confirmé)
2026-07-16 09:02:49 -04:00
bruno f6a022edf2 fix: extract render_workspace_tree macro, fix sidebar-tree endpoint
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- Extracted render_workspace_tree macro into _workspace_tree_macro.html
  so it can be imported independently from base.html (which has many
  template variables like user, workspace_name, etc.)
- Fixed GET /api/sidebar/workspace-tree to use the extracted macro
- Added error logging for easier debugging
2026-07-16 08:58:05 -04:00
bruno 6f40c8953a feat: sidebar tree dynamically refreshes after CRUD in local-workspace
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- New endpoint GET /api/sidebar/workspace-tree returns sidebar tree HTML fragment
- refreshSidebarTree() in appState() fetches and replaces #sidebar-workspace-items
- Custom event 'flowdeck:sidebar-refresh' dispatched after doCreate/doRename/doDelete
- newFolderInWorkspace, deleteWorkspacePage, wsCtxAction('rename') now use
  refreshSidebarTree() instead of window.location.reload()
- Sidebar stays in sync without full page refresh
2026-07-16 08:53:44 -04:00
bruno 72636a77ea test: met à jour les tests suite à la suppression du fallback admin token
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Tous les tests *_no_auth doivent maintenant retourner 401 au lieu de 200/502
car _require_gitea() ne fait plus de fallback vers le token admin global.
2026-07-16 08:39:49 -04:00
bruno 76c8a9a53c fix: supprime le fallback admin token dans _require_gitea()
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
_require_gitea() ne doit plus utiliser le token admin global comme fallback
quand l'utilisateur n'a pas lié son compte Gitea. Chaque utilisateur doit
connecter son propre compte Gitea pour voir les projets.

Les endpoints /api/gitea/projects et /api/gitea/orgs retournent maintenant
401 si l'utilisateur n'a pas lié Gitea, et la page /workspaces affiche
'Connect your Gitea account' au lieu de lister les repos du admin.
2026-07-16 08:37:27 -04:00
bruno 07a4f5ece6 fix: sidebar vide sur /workspaces — pas de contexte workspace actif
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
_sidebar_data() prend un nouveau parametre include_workspace (default True).
La page /workspaces passe include_workspace=False pour que la sidebar
n'affiche ni le nom du workspace actif, ni ses pages/folders.
2026-07-16 08:29:52 -04:00
bruno d645126b53 fix: /api/workspace/projects uses per-user Gitea token instead of global admin token
FlowDeck CI / test (push) Failing after 17s
FlowDeck CI / docker (push) Has been skipped
A local account without Gitea connection was seeing all Gitea repos
because the endpoint used the module-level gitea client (global admin token).
Now it checks get_user_gitea_client(request) and returns empty gitea_repos
if the user has no OAuth token for Gitea.
2026-07-16 08:20:45 -04:00
bruno 7cefc08abc fix: Gitea tree loading + auth system overhaul (v2.5.0)
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
ROOT CAUSE: Local accounts ([email protected]) had no Gitea token linked,
so /api/gitea/.../tree returned 401 → loadGiteaTree() failed silently.

FIXES:
1. _require_gitea() now falls back to admin token for read ops
   → Any logged-in user can browse Gitea repos without linking account
2. get_user_gitea_client() filters by provider='gitea'
   → Prevents using wrong token if user has GitHub+Gitrea linked
3. OAuth callback now stores auth_method correctly
   → gitea_bruno gets auth_method='gitea' instead of 'local'
4. Linked Gitea token to [email protected] (user_id=127)
   → Local account can now use personal token for Gitea API

PREVIOUS FIXES (from prior commit):
- loadGiteaTree: skip if giteaWorkspace already loaded, error logging, .bind(this)
- gitea_workspace.html: use captured 'self' instead of querySelector('[x-data]')
- 12 test assertions updated to reflect admin fallback behavior
2026-07-15 18:17:49 -04:00
bruno 61174ee967 fix: correct version number 2.4.7
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-15 16:55:27 -04:00
bruno aa64863bf7 fix: sidebar Gitea tree loading — race condition + silent errors + wrong Alpine scope
FlowDeck CI / test (push) Failing after 6s
FlowDeck CI / docker (push) Has been skipped
- loadGiteaTree: skip if giteaWorkspace component already loaded tree
- loadGiteaTree: check r.ok, add console.error logging, show error in UI
- loadGiteaTree: use .bind(this) for correct this in callbacks
- gitea_workspace.html: replace querySelector('[x-data]') with captured self
  in loadSidebarTree, loadSubdir, Private Pages click handlers
- Prevents loadGiteaTree from overwriting loadSidebarTree results
  on /gitea-workspace page
2026-07-15 16:54:20 -04:00
bruno efd957e827 fix: revert JS modal changes — preserve native prompt/confirm, add CSS+HTML modal only
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Root cause: callback wrappers introduced JS syntax errors ('appState is not defined')
Fix: keep modal HTML+CSS styles ready for future use, restore all JS functions
2026-07-15 09:28:35 -04:00
bruno 78092e6111 feat: custom modal system replaces browser prompt() and confirm()
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
- Added themed dark modal with CSS matching FlowDeck design
- showPrompt(title, message, placeholder, callback) replaces prompt()
- showConfirm(title, message, callback) replaces confirm()
- Updated: newPageInWorkspace, newFolderInWorkspace, deleteWorkspacePage
- Modal closes on escape, overlay click, or cancel button
- Consistent look across all dialogs on the site
2026-07-15 09:03:25 -04:00
bruno ec96fb86a5 fix: KeyError 'workspace_key' in create_local_workspace_item
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Root cause: ws dict from _get_active_workspace doesn't have 'workspace_key' column
           → ws['workspace_key'] → KeyError → 500 on New Page/New Folder

Fix: use ws['name'] instead (the workspace name from workspaces table)
2026-07-15 08:41:06 -04:00
bruno 3fdcc41d10 fix: auto-refresh page when closing Settings with X
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
closeSettings() now:
- Refreshes the parent page (history.back + reload)
- Handles tab navigation between settings sections
- Falls back to /workspaces redirect if no history
2026-07-15 08:10:01 -04:00
bruno 17666b51c2 fix: two UX issues
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
1. Settings X button: closeSettings() goes back, skipping hash-only navigation
   → No more double-click to close

2. Workspaces page: Connect Gitea link now includes &mode=link
   → Same link as Settings → Integrations (was missing mode=link)
2026-07-15 07:56:21 -04:00
bruno aedb07c962 fix: redirect to /workspaces after login (instead of /)
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- Local login JS: window.location='/workspaces' instead of '/'
- Root route /: if no workspace exists, redirect to /workspaces
- Existing users with workspaces: still go to /local-workspace
2026-07-15 07:41:22 -04:00
bruno bf19af2347 fix: restore missing template=env.get_template in gitea_workspace_page
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-15 07:33:31 -04:00
bruno fc6f2531b7 fix: gitea_workspace page now explicitly sets gitea_workspace=True
FlowDeck CI / test (push) Failing after 6s
FlowDeck CI / docker (push) Has been skipped
Root cause: _sidebar_data reads cookie from REQUEST, but cookie is set on RESPONSE
           → first visit: cookie empty → gitea_workspace=False → tree doesn't load

Fix: gitea_workspace_page ctx always sets gitea_workspace=True
     Also passes gitea_owner/gitea_repo for Alpine tree loading
2026-07-15 07:32:08 -04:00
bruno 0d8507a5c7 feat: Gitea file tree visible in sidebar on ALL pages
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- base.html Alpine: added giteaWorkspace, giteaOwner, giteaRepo data
- loadGiteaTree() fetches /api/gitea/.../tree and renders in sidebar
- board._sidebar_data returns gitea_owner/gitea_repo
- dashboard._sidebar_data returns gitea_owner/gitea_repo
- alpine:initialized triggers loadGiteaTree on every page load
2026-07-14 22:05:53 -04:00
bruno b83d9b6d35 fix: board._sidebar_data now handles Gitea workspace cookie — tree persists across all pages
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Root cause: board._sidebar_data tried int(gitea:owner:repo) → ValueError → lost context
           Library, Trash, page editor pages showed empty workspace tree

Fix: board._sidebar_data now mirrors dashboard._sidebar_data logic:
     - Detects gitea: prefixed cookie
     - Preserves active_ws_name, workspace_key, gitea_workspace
     - Loads local_ws_id for mirror workspace
     - Tree stays visible on /library, /trash, page editor, etc.
2026-07-14 21:13:37 -04:00
bruno 3c8529fd12 fix: OAuth callback — recover mode from state when session cookie is lost
FlowDeck CI / test (push) Failing after 16s
FlowDeck CI / docker (push) Has been skipped
Root cause: request.session cookie expires during Gitea OAuth redirect
           → oauth_mode lost → link mode falls through to login mode
           → Creates gitea_bruno user instead of linking to local account

Fix: state now carries mode suffix (state:mode)
     Callback recovers mode from state parameter even if session lost
     Allows full session loss but still correctly enters link mode
2026-07-14 20:34:43 -04:00
bruno c5ffab1e39 fix: encode OAuth mode in state parameter — survives session loss
FlowDeck CI / test (push) Failing after 3s
FlowDeck CI / docker (push) Has been skipped
Before: oauth_mode stored only in request.session cookie
        → Lost if session expires during Gitea OAuth redirect
        → Link mode falls through to login mode → creates gitea_bruno user

After:  state format: <random>:<mode> (e.g., abc123:link)
        → Mode survives session cookie loss
        → Link mode correctly links to current local user
2026-07-14 16:52:36 -04:00
bruno f4cd301f52 fix: _sidebar_data verifies workspace ownership before loading pages
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- Stale numeric workspace cookie from another user now rejected
- workspace_pages only loaded if owner_id matches current user
- Prevents sidebar tree leak of other users' content
2026-07-14 16:25:13 -04:00
bruno de86457f90 fix: prevent cross-user workspace leak via stale cookie
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- _get_active_workspace now verifies workspace owner matches current user
- Fallback: only picks workspace owned by current user (not any user)
- /local-workspace redirects to /workspaces when no workspace exists
- New users no longer see other users' workspaces/projects
2026-07-14 16:09:03 -04:00
bruno 364560c84b fix: Private section populates from mirror workspace when Gitea active
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- private_pages now queried from DB when gitea_workspace=True
- Pages with parent_section='Private' and workspace_id=mirror_ws_id
- Shown in sidebar Private section alongside remote 🔗 tree
2026-07-14 15:44:51 -04:00
bruno 0429ffd824 fix: remove hardcoded workspace_key override in homepage
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Line 146: workspace_key: '' overrideait la valeur correcte de _sidebar_data
→ 🔗 icon now shown for remote workspaces on homepage
2026-07-14 15:28:38 -04:00
bruno a7767f3a94 fix: add missing json import
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-14 15:25:44 -04:00
bruno e8f4cfb631 feat: auto-create local workspace mirror for Gitea projects
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- Opening /gitea-workspace auto-creates a local workspace with same name
- New Page/New Folder in remote context → saves to local mirror workspace
- Sidebar stays focused on remote workspace (🔗 icon, remote tree)
- local_ws_id passed to Alpine for API calls
- /api/local-workspace/items accepts workspace_id in body
2026-07-14 15:24:43 -04:00
bruno 7c3f62d094 fix: workspace_key set from cookie → 🔗 icon on homepage for remote workspaces
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-14 12:49:54 -04:00
bruno 9a063bc766 fix: toujours poser cookie gitea workspace côté serveur
FlowDeck CI / test (push) Failing after 8s
FlowDeck CI / docker (push) Has been skipped
2026-07-14 12:47:57 -04:00
bruno 234b880c5b fix: Gitea workspace — correct sidebar name, newPage stays remote, cookie persisted
FlowDeck CI / test (push) Failing after 3s
FlowDeck CI / docker (push) Has been skipped
Bug 1: newPageInWorkspace() allait toujours vers local-workspace API
→ Maintenant détecte workspaceKey contient '/' → Gitea API PUT file

Bug 2: workspace_name dans gitea_workspace ne persistait pas
→ Cookie flowdeck_workspace posé côté serveur au premier chargement

Bug 3: icône 📁 fixe dans sidebar — pas d'indication remote
→ 🔗 affiché quand workspace_key contient '/' (remote), 📁 sinon

newFolderInWorkspace() : avertissement si workspace distant
(car les dossiers n'existent pas dans un repo Git)
2026-07-14 12:47:08 -04:00
bruno 724ff4c880 feat(v4.0): wire Share/Publish modal with real API calls
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- publishPage() → POST /api/pages/{id}/publish
- unpublishPage() → DELETE /api/pages/{id}/publish
- shareInvite() → POST /api/pages/{id}/share
- loadShares() → GET /api/pages/{id}/shares
- removeShare() → DELETE /api/pages/{id}/share/{sid}
- All buttons now call real API instead of local state toggle
2026-07-14 12:23:05 -04:00
bruno 15bd9d5ed9 fix: github_routes use access_token (not github_token)
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
user_oauth_tokens has generic access_token column, not github_token/gitea_token
2026-07-14 12:21:10 -04:00
bruno 29ef0fb054 feat(v4.0): GitHub routes + CSRF exemptions for share/publish
FlowDeck CI / test (push) Failing after 3s
FlowDeck CI / docker (push) Has been skipped
- app/routers/github_routes.py: /api/github/status + disconnect
- CSRF: ajout /api/github, /api/pages, /api/recents aux exclusions
- main.py: registration github_router
2026-07-14 12:19:37 -04:00
bruno bd6fd62734 feat(v4.0): Library tabs + Sidebar OAuth badge + Sharing routes
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
app/routers/library.py: /api/library/recents|favorites|shared|published|private|workspace
app/routers/sharing.py: /api/pages/{id}/share|publish + page_shares
app/templates/base.html: OAuth badge 🦎/🐙, '→ Library' buttons
app/templates/library.html: page avec tabs + filtres source
app/routers/dashboard.py: auth_method + github_linked dans context
tests/test_app.py: tests library + sharing + recents
2026-07-14 12:16:28 -04:00
bruno 802d681212 feat(v4.0): Settings/Integrations — Gitea + GitHub connect/disconnect matrix
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- GitHub integration row ajoutée (🦎 Gitea + 🐙 GitHub)
- Badge 'Primary' sur le provider principal (auth_method)
- Disconnect masqué pour le provider principal
- authMethod, githubLinked, giteaLinked dans Alpine data
- loadGithubStatus() + disconnectGithub() methods
- Matrice respectée: local→déco OK, gitea→déco github OK, github→déco gitea OK
2026-07-14 12:14:41 -04:00
bruno 8eb7049460 docs: ARCHITECTURE v3.0 + ROADMAP v4.0 — comptes, intégrations, sidebar
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
ARCHITECTURE.md:
- Section 6.5: modèle de comptes (local/gitea/github)
- Matrice d'intégrations & règles de déconnexion
- 3 scénarios de workspace (A/B/C)
- Sidebar: règles d'affichage par type de compte
- Share & Publish: modale 2 tabs + schéma DB
- Library: /library?tab= + filtres source
- Trash local-only, édition unifiée, stockage Private
- Plan de migration 5 phases

ROADMAP.md:
- v4.0.0 section prioritaire: Account Model, Intégrations,
  Sidebar rules, Share/Publish, Library, Édition unifiée
2026-07-14 12:07:13 -04:00
bruno e2043123f0 fix: title_prefix block for browser tab — évite conflit Jinja2 page_title double
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Erreur: block 'page_title' defined twice → TemplateAssertionError
Fix: title_prefix (nouveau bloc) pour <title>, page_title (existant) pour Alpine

10 templates mis à jour avec title_prefix.
2026-07-14 09:35:52 -04:00
bruno 8cca247fcd fix: browser tab title uses page_title block — reflète le workspace actif
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
<title>FlowDeck</title> → <title>FlowDeck — {% block page_title %}Home{% endblock %}</title>

Maintenant l'onglet navigateur affiche:
- 'FlowDeck — Home' (page d'accueil)
- 'FlowDeck — bruno/flowdeck' (workspace Gitea)
- 'FlowDeck — Mon workspace local' (workspace local)
2026-07-14 09:34:38 -04:00
bruno cb44652554 fix: Gitea workspace affiche owner/repo dans le titre et topbar
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
- Le titre de page (onglet) : 'bruno/flowdeck' au lieu de 'Gitea Workspace'
- Le topbar breadcrumb : owner/repo correctement peuplé
- workspace_name + workspace_initial passés au template
2026-07-14 09:34:02 -04:00
bruno 921f1b7bc1 fix: servir JS/CSS en local — plus de dépendance CDN externe
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Téléchargés et servis depuis /static/js/:
- alpine.min.js (44 KB) — remplace unpkg.com
- htmx.min.js (51 KB) — remplace unpkg.com
- sortable.min.js (45 KB) — remplace cdn.jsdelivr.net
- prism.min.js (19 KB) + prism.css (1.3 KB) — remplace cdnjs

Corrige le bug 'rien ne fonctionne' quand le réseau est lent/absent:
sans CDN, Alpine.js/HTMX/SortableJS ne chargeaient pas →
tous les @click, x-show, x-data, drag-drop inopérants.
2026-07-14 07:44:28 -04:00
bruno 8458cf4a29 fix: defensive display:none on all modals — prevents phantom display
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Si Alpine échoue à s'initialiser, x-show n'était pas traité
et les modals apparaissaient par défaut. display:none en fallback
garantit qu'ils sont cachés, Alpine les montre via x-show.
2026-07-14 07:36:36 -04:00
bruno b755f75f15 fix: rollback Alpine.data registration — keep _wsInitData as global var only
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
L'enregistrement Alpine.data() pouvait créer un conflit avec x-data
qui utilise déjà la variable globale. Revert au comportement original.
2026-07-14 07:23:13 -04:00