Commit Graph
100 Commits
Author SHA1 Message Date
bruno d97a515eef Remove unused Notion library screenshots
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-18 10:35:05 -04:00
bruno 5b56f970ee feat: compact breadcrumb menu + 'X more' Notion-style in workspace
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
1. Compact breadcrumb hover menu:
   - Reduced font-size: header-breadcrumb 14→13px, breadcrumb-link 14→13px
   - Dropdown menus: fd-nav-menu min-width 240→200px, padding reduced
   - fd-nav-item: padding 6px8→4px6, font 14→13px, gap 8→6px
   - fd-nav-section: font 11→10px, padding reduced
   - fd-nav-ico: size 16→14px, width 20→18px
   - fd-nav-arrow: size 16→14px, margin-left 4→2px

2. 'X more' Notion-style (tree view):
   - Shows first 5 items in displayTree, hides rest
   - 6th item shows 'X more...' with count of remaining items
   - Click to expand and show all items
   - 'Show less' button to collapse back to 5
   - showAll state auto-resets on folder navigation, sort, filter
   - Styling: semi-transparent hover effect on ws-more-item
2026-07-18 10:18:08 -04:00
bruno 37c8e99151 refactor: remove dead code _render_file_viewer from board.py
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
The standalone file viewer page (with '← Workspace' topbar) was dead code —
never called after the rollback. 192 lines removed, zero references left.
2026-07-18 10:03:09 -04:00
bruno 298617af58 revert: rollback _render_file_viewer wiring and URL encoding
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Rollback des commits 2226e5e et 2534e2b — les fichiers continuent
de s'ouvrir dans page_editor.html (layout normal avec sidebar),
pas dans le viewer standalone _render_file_viewer.
2026-07-18 09:44:48 -04:00
bruno 2226e5e2c8 fix: PDF viewer - also wire up _render_file_viewer in dashboard.py view_page_root
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
The real route for /pages/{page_id} is in dashboard.py (no prefix router),
not board.py (prefix /board). Both routes now call _render_file_viewer
for content_format='file' pages.
2026-07-18 09:37:38 -04:00
bruno 2534e2b425 fix: PDF viewer - wire up _render_file_viewer + URL-encode filenames
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
- view_page now calls _render_file_viewer for content_format='file' pages
  instead of rendering the full page_editor template (which was the old path)
- URL-encode filenames in file_url using urllib.parse.quote() to handle
  spaces and special characters correctly
- Fixed in both board.py (viewer + page_data) and dashboard.py

The _render_file_viewer was dead code — defined but never called. File pages
were going through page_editor.html which rendered PDFs in an iframe embedded
in the editor UI. Now they get a clean standalone HTML viewer.
2026-07-18 09:34:24 -04:00
bruno bd02c9ea8a fix: startup log version v2.1.0 → v4.0.0
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-18 00:28:06 -04:00
bruno e85161dfc1 v4.0.0 — Route publique /p/<slug>, correctifs publish/share UI
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- Ajout route /p/<slug> qui sert les pages publiées (no auth, rendu HTML blocks)
- Template public_page.html — design épuré Notion-style
- Fix publishPage()/unpublishPage(): vérifient d.is_published au lieu de d.status==='ok'
- Fix shareInvite(): vérifie d.status==='shared'
- Fix removeShare(): vérifie d.status==='removed'
- ROADMAP.md: toutes les sections 4.0a-4.0e cochées ✅ (déjà implémentées)
- Version bump 2.5.0 → 4.0.0
2026-07-18 00:27:14 -04:00
bruno fe64617677 feat: star favoris dynamique + sidebar refresh sans reload
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- page_editor: étoile ⭐/☆ dynamique selon favorited (x-text)
- toggleFavorite() appelle refreshFavorites() du sidebar
- base.html: refreshFavorites() fetch /api/library/favorites + rebuild DOM
- Context menu 'Add to Favorites' → refreshFavorites() au lieu de location.reload()
- Les items dynamiques ont onclick/oncontextmenu pour fonctionner hors Alpine
2026-07-17 23:50:37 -04:00
bruno 25386bc79f feat: breadcrumb hover Notion-style + nav_workspace_id sur toutes les pages
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- _header.html: remplace click par hover (mouseenter/mouseleave)
  avec timer 200ms anti-flicker, cascade sous-menus au hover
- dashboard.py: ajoute nav_workspace_id à trash, library, workspace,
  gitea-workspace, local-workspace, workspaces, settings, pages/{id}
- La section du popover affiche 'Workspaces' pour Home, 'Private' pour le reste
- Les clics dans les popovers ferment le menu + naviguent
2026-07-17 23:43:16 -04:00
bruno d751415308 feat: add Notion-style breadcrumb navigation with dropdown menus
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
Backend:
- Added _nav_breadcrumb() to build page hierarchy chain (root → current)
- New /api/nav/menu endpoint returns workspace/folder children with has_children flag
- view_page() and view_page_root() now pass breadcrumb_items, nav_workspace_id, nav_page_id to template

Header template (_header.html):
- Replaced static breadcrumb with Alpine.js fdBreadcrumb() component
- Breadcrumb items now clickable with dropdown menus showing
2026-07-17 23:30:59 -04:00
bruno 6f1eabf91d fix: Windows path handling, light theme default, file viewer in editor, first-user admin logic
FlowDeck CI / test (push) Failing after 18s
FlowDeck CI / docker (push) Has been skipped
Config:
- Fixed SQLite path parsing on Windows (handle drive letters without prepending /)
- Changed default theme from dark to light
- Updated OAuth test credentials (gitea_oauth_client_id/secret)

Auth:
- First real user (excluding default admin with no password) becomes admin
- Changed user count query to exclude users without password_hash

File viewer:
- Removed separate _render_file_viewer() —
2026-07-17 20:38:39 -04:00
bruno 84a126cfd1 Merge branch 'main' of https://git.dracodev.net/bruno/flowdeck
FlowDeck CI / test (push) Failing after 18s
FlowDeck CI / docker (push) Has been skipped
2026-07-17 09:00:09 -04:00
bruno 7ea1c852dc chore: remove 44 Notion reference images — cleanup research artifacts
Deleted all Notion UI screenshots and .url shortcut from /images/:
- Kanban views (board, table, team load, status, detailed, sort/filter panels)
- Share menu (general access, permissions, publish section)
- Editor states (H1/paragraph/quote empty, format layouts)
- Navigation (sidebar, context menus, mouse-over states, collapse/expand)
- Misc UI (trash, config panel, library, user menu, filters)

These were research/reference
2026-07-17 08:59:44 -04:00
bruno c2ef7bfaa0 fix: show auto-created workspace name instead of 'Private' in sidebar
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
For Gitea workspaces, the sidebar section now displays the actual
workspace name (e.g. '📁 Projets/Ares') instead of the generic '📁 Private'.
The workspace name is auto-created from the Gitea project's owner/repo
when the remote workspace is first opened.
2026-07-16 14:27:47 -04:00
bruno c990382085 fix: use Alpine.data() to register giteaWorkspace component
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Replaced global function giteaWorkspace() with Alpine.data('giteaWorkspace', ...)
registered via document.addEventListener('alpine:init', ...). This is the
recommended Alpine 3 approach that guarantees the component factory is
available before Alpine processes x-data directives.

Changed x-data="giteaWorkspace()" to x-data="giteaWorkspace" (Alpine.data
calls the factory automatically, no parentheses needed).
2026-07-16 14:12:53 -04:00
bruno b141af886d fix: move giteaWorkspace() script before x-data div to fix init race
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
The <script> defining giteaWorkspace() was placed AFTER the <div x-data>
in the DOM, causing Alpine to try to evaluate giteaWorkspace() before
the function was defined. This resulted in 'Uncaught ReferenceError' for
all component properties (fileLoading, fileLanguage, showFile, etc.).

Fix: moved the <script> block to appear BEFORE the x-data div in the
HTML source, ensuring the function is defined when Alpine initializes.
2026-07-16 14:07:17 -04:00
bruno 56c5739605 fix: remove getter from giteaWorkspace() to fix Alpine 3.14.9 init error
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
The 'get sortedTreeItems()' getter caused Alpine's Proxy to fail during
component initialization, resulting in all properties being undefined
(fileLoading, fileLanguage, showFile, etc. — Uncaught ReferenceError).

Fix:
- Replaced getter with _sortTree() method + sortedTreeItems property
- _sortTree() called after treeItems is updated in loadMainTree()
- sortedTreeItems explicitly set to [] on error/empty paths
2026-07-16 13:48:47 -04:00
bruno 7613129204 fix: Gitea sidebar now has separate Repository section below Private
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Backend:
- _sidebar_data() no longer clears workspace_pages for Gitea workspaces
  The local tree stays intact in the 'Private' section
- workspace_pages is always loaded from DB (local files)

Sidebar template (base.html):
- Workspace section renamed to 'Private' when gitea_workspace is true
- New 'Repository (Gitea)' section added below, visible only for Gitea
  workspaces, with its own toggle (sectionsOpen.gitea) and refresh button
- Uses #sidebar-gitea-items container for the remote file tree

Gitea workspace:
- loadSidebarTree() now targets #sidebar-gitea-items
- window._gwData exposed for sidebar refresh button
- sectionsOpen now includes gitea: true by default
2026-07-16 13:44:10 -04:00
bruno f61f8b61ae fix: Gitea sidebar tree + header actions inline with title
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Gitea workspace sidebar:
- loadSidebarTree() now uses innerHTML replacement instead of DOM
  manipulation (avoids Alpine reactivity overwrites)
- Ensures workspace section is visible when tree loads
- Shows error message when Gitea API fails (no token/gateway)
- Better error handling with console.error catch

Header actions inline:
- page_editor: moved Edited/Share/Copy/Favorite/More buttons into
  the unified header (right_actions), accessible via window.E
  (editorState global reference set in init)
- Removed duplicate page-topbar div from content area
- Share dialog, More menu, and Activity popover stay in content
  area (triggered by header buttons via window.E references)
- Gitea workspace: header now uses page-action-btn for consistency
2026-07-16 13:08:14 -04:00
bruno 3210ac65a6 feat: Move to, Gitea context menu, Activity popover
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Move to workspace:
- movePage() opens a dialog listing all workspaces via /api/workspaces
- doMove(wsId) calls PUT /api/pages/{id}/move with workspace_id
- Updated move API to accept JSON body with workspace_id for cross-workspace moves

Gitea workspace context menu:
- Right-click on any file/folder shows Rename + Delete options
- gwRename() prompts for new name, calls PUT /api/gitea/.../file
- gwDelete() confirms then calls DELETE /api/gitea/.../file
- Both trigger refreshTree() after success

Activity popover:
- 'Edited X ago' timestamp is now clickable (▾ indicator)
- Opens popover showing edited time + created date
- formatDate() helper for readable date formatting
2026-07-16 12:53:38 -04:00
bruno cef267d7b5 feat: real timestamp + working Export + polished More menu in page editor
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- 'Edited X ago' now shows real relative time from page.updated_at
- timeAgo computed getter in editorState() calculates relative time
- Export now generates a Markdown file from blocks and triggers download
- blocksToMarkdown() helper converts blocks to proper Markdown syntax
  (headings, lists, todos, quotes, dividers, code blocks)
- More menu items: Duplicate (was working), Export (now works),
  Move to Trash (was working), Copy link (via shortcut)
2026-07-16 12:49:45 -04:00
bruno 043dd4871c feat: gitea-workspace now has file tree browser like local-workspace
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- Main content area now shows file/folder tree with breadcrumb navigation
- Click folders to drill down, click files to open
- Breadcrumb shows current path with clickable segments
- Sorted tree: folders first, then files alphabetically
- refreshTree() now reloads without full page reload
- Empty state with 'New file' button when folder is empty
2026-07-16 12:42:48 -04:00
bruno b5dd37a652 fix: remove duplicate action bar from page_editor (double header)
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
The unified _header.html already renders the topbar with breadcrumb. The
page_editor had a second 'page-topbar' div in the content area with the
same buttons (Share, Copy link, Favorite, More). Removed the duplicate
actions from the header, keeping them only in the content area where
they are in the correct Alpine scope (editorState()).

This fixes:
- Double header visual duplication
- Share/Copy/Favorite/More buttons now work (in editorState scope)
2026-07-16 12:41:25 -04:00
bruno d4fb095baf feat: unified header across all pages (Notion-inspired breadcrumb + actions)
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
Created a shared _header.html template with:
- Hamburger button (toggle sidebar)
- Breadcrumb navigation with clickable segments and separators
- Page icon + title display
- Right-side action buttons (configurable per page)
- Dropdown panel CSS for More/New menus

Updated all pages to use the unified header:
- workspaces.html: Home / Workspaces + login/settings
- workspace.html: Workspace — Projects + login/settings
- local_workspace.html: workspace name
- gitea_workspace.html: Home / owner/repo + New/Upload/Refresh/Settings
- page_editor.html: title + Edited/Share/Copy/Favorite/More dropdown
- settings.html: Settings

Added CSS for breadcrumb, dropdown panel components.
2026-07-16 12:30:18 -04:00
bruno 8c0b55635c feat: soft-delete and undo/restore for local-workspace items
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Backend:
- DELETE /api/local-workspace/items/{id} now soft-deletes (sets deleted_at
  instead of hard DELETE) — items go to trash, not permanently gone
- New POST /api/local-workspace/items/{id}/restore to undo a delete
- _load_workspace_pages() and _load_children() now filter deleted_at IS NULL
  so soft-deleted items disappear from sidebar and tree queries

Frontend:
- undoDelete() now calls the restore API per item (single or bulk)
- bulkDelete() now shows the same undo banner as context menu delete
- All delete paths (ctxMenu, bulk, modal) use the same soft-delete + undo flow
2026-07-16 10:28:17 -04:00
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 &#39; 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 &#39; 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
bruno b771708bdc fix: @click.away→@click.outside GLOBAL — 16 instances across 5 templates
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Alpine 3.x a renommé .away en .outside. Toutes les occurrences dans:
- base.html (3: user menu, context menu, ws ctx)
- page_editor.html (5: share, perm, access, more, gsMore)
- workspaces.html (1: dialog overlay)
- workspace.html (1: modal overlay)
- local_workspace.html (6: create, rename, delete modals, context menus)

Ces .away cassées empêchaient tous les @click Alpine de fonctionner
sur ces pages (Cancel, Delete, et tous les autres boutons modaux).
2026-07-14 07:16:56 -04:00
bruno 1e15e44a00 fix: Alpine 3.x — @click.away→@click.outside + register _wsInitData
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- @click.away n'existe pas dans Alpine 3.x (renommé @click.outside)
  6 occurrences corrigées dans local_workspace.html
- Ajout Alpine.data('_wsInitData') pour un binding fiable des @click
  (le IIFE seul ne garantissait pas une reconnaissance Alpine propre)
2026-07-14 07:16:27 -04:00
bruno 7edeb373f1 fix: guard delete confirm with null id check — prevents phantom dialog
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Le confirm('Delete') dans contextActions pouvait se déclencher sans
item valide (id null/undefined). Ajout d'un guard if (!id) break.
2026-07-14 07:10:26 -04:00
bruno 449550ac90 fix: wire CSP + RateLimit middleware in main.py (étaient définis mais pas branchés)
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Audit v3.0.1: 2/21 features ✗ → CSP/rate-limit middleware
non importés dans main.py. Maintenant branchés.
2026-07-14 00:47:08 -04:00
bruno 72dc4771b4 ROADMAP v4.0.0: ajout Database avancée, Kanban adaptable, Calendar & Meetings
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
4.8 Database Avancée: inline DB, full-page DB, templates de DB,
    validation propriétés, types manquants (Person, Last edited, Created by),
    Timeline/Gantt, Board swimlanes, Calendar drag-drop, Gallery covers

4.9 Kanban Adaptable: colonnes config., cartes configurables,
    couverture, sous-tâches visibles, WIP limits, vues sauvegardées,
    mode compact/détaillé

4.10 Calendar & Meetings: Day/Week/Month, drag-drop reschedule,
    récurrence, timezone, rappels, template Meeting Notes,
    auto-création action items
2026-07-14 00:41:08 -04:00
bruno ec9eb99c98 ROADMAP v4.0.0: delta analysis Notion vs FlowDeck
FlowDeck CI / test (push) Failing after 7s
FlowDeck CI / docker (push) Has been skipped
Analyse exhaustive: 60+ fonctionnalités Notion (2025) vs FlowDeck v3.0.1
→ 45 manquantes identifiées, 30 retenues pour v4.0.0

Tier 1 (Critique — 16 features):
- AI Assistant (LLM intégré, auto-complétion, slash AI)
- Embeds (60+ services, lightbox, previews PDF/vidéo)
- Export (PDF, Markdown, HTML) + Import (Confluence/Evernote)

Tier 2 (Important — 8 features):
- Realtime collaboration (WebSocket, curseurs)
- Comments + @mentions + email notifications
- Callout blocks, table of contents, LaTeX, toggle lists

Tier 3 (Avancé — 6 features):
- Linked databases, charts/dashboards, multi-colonnes
- Command palette Ctrl+P, automations, buttons

v4.1.0 (futur): PWA, SSO, API publique, web clipper
2026-07-14 00:28:26 -04:00
bruno de40c2d83e v3.0.1: qualité & stabilité — tests, sécurité, UX consolidée
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
🧪 Tests: 73 → 130 (+57 tests)
- Upload API, labels sync, commit history (401/400/502/cached)
- File create/update (sha=null, sha=abc)
- Admin delete cascade (12 tests: oauth, tags, workspaces, pages…)
- Gitea status (linked/unlinked/disconnect)
- OAuth link mode (session, redirect, callback)

🔒 Sécurité
- ContentSecurityPolicyMiddleware (CSP headers)
- RateLimitMiddleware (100 req/min/IP)
- Pydantic models: ErrorResponse, SuccessResponse
- Input validation upload (10MB, allowed extensions)
- Pydantic request models

🎨 UX
- static/css/design-tokens.css (500 lines, thèmes + skeletons)
- Toast system: 16 alert() remplacés par toast()
- 59 lignes CSS dupliquées retirées (6 templates)
- Skeletons cohérents sur toutes les vues

⚡ Performance
- Cache TTL sur get_file_commits (consistant avec les autres méthodes)
2026-07-13 23:08:53 -04:00
bruno e04b3a38a4 fix: get_file_commits use consistent caching (_cached/_set_cache)
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-13 22:57:46 -04:00
bruno b863afab59 ROADMAP: v2.8.0-v3.0.0 complétées — roadmap terminée 🎉
FlowDeck CI / test (push) Failing after 3s
FlowDeck CI / docker (push) Has been skipped
2026-07-13 22:36:01 -04:00
bruno a497c129d3 Upload via FlowDeck
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-13 22:34:37 -04:00
bruno 6f15ad3ad4 v2.8.0 WIP: create/upload files + commit history + labels sync
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- POST /api/gitea/projects/{owner}/{repo}/upload (binary upload)
- get_file_commits() in GiteaClient
- GET /api/gitea/projects/{owner}/{repo}/commits (per-file history)
- POST .../sync-labels (Gitea labels → FlowDeck tags)
- New file form + upload button in gitea_workspace.html topbar
2026-07-13 22:33:47 -04:00
bruno f25c8ebaf0 feat: force Gitea ré-auth en mode link (_force timestamp)
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Ajout d'un paramètre _force avec timestamp dans l'URL d'autorisation
quand mode=link, pour forcer Gitea à ne pas utiliser le cache.

NOTE: Gitea ne supporte pas prompt=login. Si auto-approve persiste,
il faudra ajouter un champ token manuel en fallback.
2026-07-13 22:18:31 -04:00
bruno 06bf016392 fix: bfcache restore — theme persistant après navigation retour
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Problème: window.history.back() restaurait la page depuis bfcache
→ le IIFE initTheme() ne se ré-exécutait pas
→ le thème dark s'affichait même après avoir sélectionné light

Fix:
- applySavedTheme() → fonction nommée, pas IIFE
- window.addEventListener('pageshow', e.persisted → reapply)
- Proper else branch: removeProperty pour le dark mode
2026-07-13 21:45:29 -04:00
bruno 17824deae2 fix: déconnexion Gitea effective + menu user light mode
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
1. _require_gitea: retrait fallback admin token → 401 si pas connecté
2. user-menu-dropdown: background var(--bg-primary) au lieu de #1E1E1E
3. applyTheme() déjà immédiat via style.setProperty sur documentElement
2026-07-13 21:39:16 -04:00
bruno e3851b4f12 feat: OAuth link mode + settings light mode CSS variables
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
1. /auth/login?provider=gitea&mode=link:
   - Sauve 'oauth_mode=link' dans la session
   - Callback: link OAuth token à l'utilisateur courant (pas de nouveau compte)
   - Redirige vers /settings#integrations

2. Bouton Connect dans Settings → mode=link

3. Settings light mode: remplacé 12 couleurs codées en dur par CSS variables
   - .settings-panel, .modal-box, .settings-input
   - .admin-table th/td, .stat-card
   - .btn-sm, .btn-sm:hover
2026-07-13 21:24:04 -04:00
bruno 6c8327c021 fix: delete_user cascade — ajout comments, page_history, favorites, gitea_private_pages, tags
FlowDeck CI / test (push) Failing after 5s
FlowDeck CI / docker (push) Has been skipped
2026-07-13 21:02:39 -04:00
bruno 1e36b03532 fix: delete_user cascade — pages n'a pas de owner_id, passe par workspace_id
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-13 21:02:10 -04:00
bruno aa2354a25a fix: exempt /api/admin + /api/gitea du CSRF middleware
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
Les endpoints admin ont déjà leur propre protection admin_required.
Le CSRF middleware bloquait les DELETE/PUT sur ces routes.
2026-07-13 21:01:21 -04:00
bruno ef88ee4c55 fix: virgule manquante après saveDefaultView() — SyntaxError cassait tout le JS
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
settings.html:773: '} async' → '}, async'
Cette SyntaxError empêchait Alpine.data('settingsInit') d'être parsé
→ toutes les variables Alpine étaient undefined
2026-07-13 20:56:42 -04:00
bruno 86b34dc063 test via FD
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
2026-07-13 20:48:40 -04:00
bruno 6d98070986 fix: ajout X-CSRF-Token dans les requêtes save/delete Gitea
FlowDeck CI / test (push) Failing after 8s
FlowDeck CI / docker (push) Has been skipped
2026-07-13 20:48:40 -04:00
bruno 0d66b5d543 fix: scope Alpine gitea_workspace + commit admin fallback + settings cleanup
FlowDeck CI / test (push) Failing after 6s
FlowDeck CI / docker (push) Has been skipped
1. gitea_workspace.html: owner/repo en Jinja2 dans la topbar (pas Alpine)
2. gitea.py: save_file/delete_file → _require_gitea (admin token can write)
3. settings.html: retrait doublon defaultView, fix workspace_name Jinja2
2026-07-13 20:47:46 -04:00
bruno e22efc1d9c fix: retirer bouton dark/light mode du sidebar, ajouter dans Settings
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- Sidebar: retrait du bouton 🌓 (dark/light) + bouton 🚪 logout
- Settings → Account → Preferences: nouveau sélecteur de thème (Dark/Light)
- Persistance localStorage 'fd_theme' — appliqué au chargement de chaque page
- initTheme() dans base.html + applyTheme() dans settings.html
- toggleTheme() conservé dans le JS mais plus utilisé dans l'UI
2026-07-13 17:08:30 -04:00
bruno c1f854a54a docs: mise à jour ROADMAP.md, CHANGELOG.md et docs/ROADMAP.md
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
ROADMAP.md:
- Ajout v2.4.0 (tags/user), v2.5.0 (admin panel), v2.6.0 (my account)
- Ajout v2.7.0 (Gitea P1), v2.7.1 (private pages)
- Roadmap future: v2.8.0 (Gitea P2), v2.9.0 (GitHub), v3.0.0 (Pro UX)

CHANGELOG.md:
- Entries v2.4.0 → v2.7.1 avec tous les détails
- Structure Added/Fixed cohérente

docs/ROADMAP.md (v3.0):
- Phase 1-5 checkboxes mises à jour (45/52 items done)
- Reste: GitHub OAuth, Quick switch, API tokens, sessions actives
2026-07-13 17:05:45 -04:00