Commit Graph
19 Commits
Author SHA1 Message Date
bruno c718fe06de fix: A20 (partiel) — CSP nonce par requête, unsafe-inline sort de script-src (v7.7.0)
FlowDeck CI / lint (push) Canceled after 0s
FlowDeck CI / test (push) Canceled after 0s
FlowDeck CI / docker (push) Canceled after 0s
- ContentSecurityPolicyMiddleware : nonce aléatoire par requête dans la
  ContextVar `CSP_NONCE` (posée avant `call_next` → visible des templates),
  `script-src 'self' 'unsafe-eval' 'nonce-…'` — plus aucun script inline
  sans nonce ne tourne (fin des XSS injectés en JS)
- 38 tags `<script>` des templates : `nonce="{{ csp_nonce() }}"` (passage
  scripté, vérifié : 0 restant) ; `LOCAL_LOGIN_HTML` (constante de module) :
  helper `_with_nonce()` au rendu ; collections.py : 3 scripts Python
  (chart/form/map) noncés
- `<meta name="htmx-config" content='{"inlineScriptNonce": …}'>` dans base.html
  : htmx ré-injecte les <script> des réponses boostées avec le bon nonce
- `script-src-attr 'unsafe-inline'` : les 74 handlers `onclick=` inline
  restent couverts (le nonce les aurait désactivés aussi)
- chart.js (cdn.jsdelivr.net) et leaflet (unpkg) ajoutés à script-src/style-src
  : vues chart/map déjà BLOQUÉES par la CSP depuis toujours
  (commentaire ponytail: upgrade = vendoriser puis retirer les hôtes)
- reste d'A20 : unsafe-eval (Alpine x-data → @alpinejs/csp), externalisation
  JS (A27), resserrer img-src/connect-src

test : test_csp_nonce_per_request (page base.html + page hors template,
nonce unique par requête)

suite **1037/1037** · `ruff check app tests` OK · docs à jour
2026-10-01 10:41:39 -04:00
bruno 3b3e95e23a fix(cloudflare): proteger les scripts inline des pages du Rocket Loader
FlowDeck CI / lint (push) Successful in 48s
FlowDeck CI / test (push) Successful in 5m2s
FlowDeck CI / docker (push) Successful in 42s
Rocket Loader (Cloudflare) reecrit les balises script inline en type=...-text/javascript et les execute de facon differee, ce qui casse l'enregistrement des composants Alpine et l'init des pages lors d'un acces direct via le tunnel (ex. /settings ne se chargeait pas au complet). Ajout de data-cfasync=false sur les scripts inline des pages completes et des partiels du shell (settings, accounts, trash, workspace, board, gitea_workspace, welcome, import, page_editor_collection/embed, _database_table_scripts, _notification_bell, public_page, local_workspace). Les fragments charges via HTMX restent inchanges.
2026-09-13 12:35:28 -04:00
bruno e707becbf8 feat(nav): partial HTMX navigation — swap main content without full reload
FlowDeck CI / lint (push) Successful in 45s
FlowDeck CI / test (push) Successful in 4m17s
FlowDeck CI / docker (push) Successful in 41s
Intercept internal links and load only .main-wrapper via htmx.ajax, keeping the sidebar/header shell in place. Adds history pushState/popstate handling, sidebar active-state resync and document title update. Moves page script blocks inside #main-content so they run on swap, and makes editor/board scripts idempotent. Routes navigateTo/breadcrumb/library/local-workspace through window.fdNavigate and fixes the duplicated navigateTo definition.
2026-09-12 21:26:56 -04:00
bruno 3fcc12ad8c feat: sweep complet — tous les émojis → outline SVG icons
Templates modifiés (22 fichiers):
- _icons.html: +14 new icons (paperclip, external-link, sparkles, lightbulb, tag,
  file-text, save, upload, trending-up, zap, alert-triangle, user, eye-off)
- base.html: +8 JS icons, 🦎🐙🔑🔗👁📋🔲📑❓⚠️→SVG
- page_editor.html: 43→0 émojis (📎📄🔒🔗⭐📋📁✨📝🗄📑📊📅🗓🖼📥🌐✏💬💡 etc)
- settings.html: 30→0 (⚙️📋🏷🧩👥💾🙈👁🔒🌙☀️🌳📊📝⚠🦎✅🐙🔗✏🗑)
- local_workspace.html: 25→0 (📄📁✏🗑⚠📋➕)
- gitea_workspace.html: 25→0 (🔗📄📤🔄⚙📁📄🔒✏🗑💾)
- board.html: 13→0 (📁📊📋☰📈👥✕✓🗑⚡🔍)
- workspace.html: 11→0 (🏠🔑⚙📁🔗📂🐙)
- landing.html: 8→0 (📚🚀📝📊🦎🌐🔒⚡)
- trash.html, table_view, dashboard, accounts, card_detail, public_page,
  workspaces, team_load, notes, _header, detailed_board, card, board_fragment
- Ajouté import _icons.html aux fragments standalone
- 143 tests passent
2026-07-21 08:27:10 -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 6b67b25d27 fix: CSRF token manquant dans les fetch() POST du board et card detail
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- board.html: ajout X-CSRF-Token header sur fetch /api/move et /api/issues
- card_detail.html: ajout helper getCsrf() + header sur tous les fetch POST/PATCH
- Sans ce fix, drag & drop, création issue, checklists échouent en production
2026-07-10 08:22:42 -04:00
bruno 8aaf1676c0 fix: refresh board after drag & drop move
FlowDeck CI / test (push) Failing after 3s
FlowDeck CI / docker (push) Has been skipped
2026-07-10 08:06:06 -04:00
bruno 4eaec52d66 feat: workspace contextuel — pages liées au projet, sidebar vues cliquables
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped
- pages.workspace = owner/repo (ex: bruno/flowdeck) au lieu du nom user
- Sidebar: Kanban board + 4 sous-vues avec URLs distinctes (?view=kanban|table|...)
- Cliquer sur 'Table view' dans sidebar → change la vue à droite
- Dashboard (/): sidebar montre uniquement les projets Gitea
- Board (/board/{o}/{r}): sidebar montre les pages de ce projet
- Changement de projet = changement de contexte (pages isolées)
- newPage/newSubPage passent workspace_key à l'API
- Auto-switch view depuis paramètre URL dans board.html
2026-07-08 15:38:25 -04:00
bruno 751f13869a feat: v0.5.0→v0.8.0 — multi-vues, filtres, tri, modale, checklists
CI / test (push) Failing after 4s
CI / lint (push) Failing after 3s
v0.5.0 (Kanban complet):
- Card detail modal avec checklists + commentaires Gitea
- Création d'issues inline (formulaire + POST /api/issues)
- Édition inline (contenteditable)

v0.6.0 (Table view):
- table_view.html: colonnes Name/Status/Assign/Deadline/Team/Keywords
- Tri par colonne (clic en-tête, asc/desc)
- Groupes rétractables (Design/Engineering)

v0.7.0 (Filtres & Tri):
- Filtres cumulables AND (backend _apply_filters + UI pastilles)
- Status dropdown avec checkboxes + dots colorés
- Sort panel multi-critères (+ Add sort / Delete sort)
- Backend _apply_sorts avec asc/desc

v0.8.0 (Vues spéciales):
- status_overview.html: SVG donut chart + légende + pourcentages
- team_load.html: barres empilées par avatar
- detailed_board.html: cartes avec toutes propriétés

Backend:
- /board/{o}/{r}/view/{view} — 5 fragments HTMX
- /api/issues/{o}/{r}/{id}?format=html — modal HTML
- _map_issue_to_card, STATUS_COLORS/LABELS exportés
2026-07-08 14:29:33 -04:00
bruno cc680a46c2 feat: Refonte UI Notion-complete — sidebar, topbar, multi-vues, dark mode
CI / test (push) Failing after 10s
CI / lint (push) Failing after 4s
- Layout 3 zones (sidebar 240px + topbar 44px + contenu)
- Sidebar: sections hiérarchiques, hover states, menu contextuel
- CSS design system Notion: #191919/#222/#333, Inter, coins 4-6px
- Vues: Kanban (groupes+colonnes), Dashboard Notion-style
- Templates: base.html refondu, card.html partial, board.html v2
- Backend: données sidebar + board Notion (groups/cards)
- Docs: ROADMAP v0.4→v1.0, WORKLOAD.md, README
- Backward compatible: conserve _issue_column pour api.py
- Images de référence + resized (analyse 2026-07-08)
2026-07-08 14:13:41 -04:00
bruno 74fe8aed64 feat: feedback visuel immédiat après drag-and-drop + correction résolution IDs labels
CI / test (push) Failing after 8s
CI / lint (push) Failing after 4s
- /api/move retourne maintenant les labels mis à jour
- Le frontend met à jour les labels de la carte sans recharger la page
- Flash vert sur la carte pour confirmer le succès du déplacement
- Correction: résolution noms→IDs des labels via l'API Gitea (update_issue_labels attend des ints)
- Mise à jour de data-column sur la carte déplacée
2026-07-08 11:42:05 -04:00
bruno c19503cf2f feat: UI de configuration des colonnes et mappings label→colonne
CI / test (push) Failing after 4s
CI / lint (push) Failing after 4s
- Bouton ⚙ sur chaque colonne pour configurer le mapping label Gitea
- Modal ⚙ Colonnes pour ajouter/renommer/supprimer des colonnes
- API DELETE /api/col-mapping pour supprimer un mapping
- Rafraîchit le board après chaque modification de colonne/mapping
- CSS pour les nouveaux éléments (config panel, column list)
2026-07-08 11:33:08 -04:00
bruno 7b2fa01b0a fix: positionnement des cartes selon les labels et mise à jour après édition
CI / test (push) Failing after 8s
CI / lint (push) Failing after 4s
- create_issue: utilise _issue_column() au lieu de hardcoder 'Backlog'
- update_issue_api: recalcule la colonne après changement de labels
- update_issue_api: utilise l'endpoint PUT /labels au lieu de PATCH (Gitea ignore labels dans PATCH)
- webhooks: utilise _issue_column() pour 'opened'/'reopened'
- saveIssueEdit: rafraîchit le board (HTMX) après édition au lieu de rouvrir la modale
- update_issue_labels: corrigé pour utiliser PUT /issues/{id}/labels (liste d'entiers)
2026-07-08 11:27:56 -04:00
bruno 6ca376a675 fix: JS syntax error in renderCardDetail breaking all interactivity
CI / test (push) Failing after 4s
CI / lint (push) Failing after 3s
Root cause: operator precedence bug with stray ')' in:
  '...+(card.priority||"Medium")===p?"selected":"")+'>...
The ')+' created an unmatched parenthesis, causing SyntaxError
that stopped ALL JS event handlers (dblclick, drag-drop, buttons).

Fix: replaced string concatenation with template literals ('')
throughout renderCardDetail, eliminating escape/quoting issues.
2026-07-08 10:53:32 -04:00
bruno ae41937b03 feat: multi-label selection + double-click column to create issue
CI / test (push) Failing after 4s
CI / lint (push) Failing after 4s
- Labels now rendered as checkboxes (not single-select dropdown)
  in both create modal and edit form
- ALL_LABELS and ALL_MILESTONES passed as JSON to JS
- Double-click on empty column area opens create modal
  (pre-fills with that column name in title placeholder context)
- '+ Issue' button also opens the same modal
- Removed old inline new-issue-form (Alpine x-show), replaced with modal
- Create modal: title, body, multi-label checkboxes, milestone, assignee
- Edit form: title, body, multi-label checkboxes, assignee
- CSS: .label-checkboxes + .label-cb styles
2026-07-08 10:47:54 -04:00
bruno 3e78d4343c feat: full inline issue editing (title + body + assignee)
CI / test (push) Failing after 4s
CI / lint (push) Failing after 4s
Replaced bare prompt() with proper edit form in card modal:
- showEditForm: renders title input + body textarea + assignee field
- saveIssueEdit: PATCH /api/issues/... with title, body, assignee
- 'Annuler' button returns to card detail view
- Old editIssueInline (prompt only) removed
- Added .form-label CSS style
2026-07-08 10:18:28 -04:00
bruno a67f42bfe6 fix: resolve 3 critical UI bugs
CI / test (push) Failing after 4s
CI / lint (push) Failing after 3s
1. Refresh button no longer doubles header
   - Added ?fragment=1 param to filter/refresh HTMX requests
   - Board route returns board_fragment.html (columns only) for fragment requests
   - Refresh button uses window.location.reload() for full page reload

2. No more raw JSON in header
   - base.html: user info rendered server-side via template variable
   - board.py: decodes session cookie, passes user to template
   - Dashboard/board templates show Login/Deconnexion based on auth state

3. New issue form works
   - Replaced HTMX post with JS fetch (handleNewIssue)
   - Adds CSRF token to form submission
   - Reloads page on successful creation
   - Cleaner error handling
2026-07-08 09:45:24 -04:00
bruno 5a124d1328 v0.3.0: OAuth2, CSRF, rate limiting, issue CRUD, webhooks, card detail, checklists
CI / test (push) Failing after 5s
CI / lint (push) Failing after 4s
- OAuth2 Gitea (login/callback/logout) with fallback admin mode
- Session management with signed cookies (itsdangerous, 7 days)
- CSRF protection middleware on all POST/PUT/PATCH/DELETE
- Rate limiting in-memory (60 req/min per IP)
- Issue creation from FlowDeck (POST /api/issues/{owner}/{repo})
- Inline issue editing (PATCH /api/issues/{owner}/{repo}/{issue_id})
- Card detail modal (double-click): description, labels, comments
- Checklists with toggleable items (CRUD endpoints + UI)
- Priority + due date editable on cards
- Webhook receiver (POST /api/webhook) with HMAC-SHA256
- Auto-register/status webhooks for repos
- GiteaClient: create_issue, update_issue, get_comments, webhooks, collaborators
- New DB tables: users, user_tokens, checklists, checklist_items
- CSS: modal, forms, checklists, comments, PR section
2026-07-08 09:23:57 -04:00
bruno 336c7d8dfe feat: FlowDeck v0.2.0 — Kanban Gitea intégré
- Dashboard projets Gitea (user + orgs)
- Board Kanban 5 colonnes avec drag & drop (SortableJS)
- Sync bidirectionnelle colonnes ↔ labels Gitea
- Filtres milestone/label/assignee
- Notes Markdown par projet
- API REST (/api/health, /api/move, /api/col-mapping…)
- Colonnes custom, WIP limits
- Thème clair/sombre
- Cache Gitea TTL
- Docker + docker-compose
- Tests pytest
- Docs: README, ARCHITECTURE, CHANGELOG, ROADMAP
2026-07-08 08:41:31 -04:00