diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e71779..5f5fcb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog - FlowDeck +## v7.50.1 (2026-10-06) — Peek des bases : le contenu se rend enfin + tableau pleine largeur + +### Fixed + +- **Une base ouverte en side peek restait à « Loading database… »** — + `page_editor_embed.html` (le peek de `/pages/{id}?embed=1`) n'incluait pas + `database_table.js` : `window.FlowDeckDB` était undefined dans l'iframe et + le bloc `embed/collection` ne s'hydrat jamais. Inclus désormais (même + traitement que `page_editor.html`). +- **L'icône « Open » de fin de ligne d'un tableau de base ne faisait rien + hors page dédiée** — le panneau `#db-side-peek` n'existait que dans le + markup de `_database_table.html` ; sans lui, `openPageInSidePeek` était un + no-op. Le panneau est créé à la demande par `database_table.js` + (`ensureDbPeek`, comme `mt-peek` de My Tasks) : markup unique, le partial + ne contient plus le panneau statique. +- **Barre de scroll sous le tableau des bases** — `.database-table-container` + plafonnait à 1100 px (règle héritée de Library) : le tableau ne prenait + pas la largeur du document. Plafond retiré ; `max-width: 100%` aussi pour + les conteneurs `.db-first` (base embarquée en premier bloc) et le titre + des pages de base — les colonnes dictent seules le scroll horizontal. + +### Tests + +- `test_embed_editor_can_render_inline_databases` (include peek + panneau + créé à la demande, source unique de markup). Suite 1265 passed / 0 failed + (-n auto) + ruff 0. + ## v7.50.0 (2026-10-06) — Side peek : le document seul (mode édition), sans sidebar ni barre ### Fixed diff --git a/VERSION b/VERSION index cf89fc8..1e6c3f0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.50.0 +7.50.1 diff --git a/WORKLOAD.md b/WORKLOAD.md index c48de54..ad55298 100644 --- a/WORKLOAD.md +++ b/WORKLOAD.md @@ -1,6 +1,6 @@ # WORKLOAD — FlowDeck Notion Clone -> **Début**: 2026-07-08 | **Version**: v7.50.0 (side peek : document seul en mode édition, bouton Open calendrier/Kanban My Tasks) | **Statut**: EN COURS 🔄 +> **Début**: 2026-07-08 | **Version**: v7.50.1 (peek des bases : hydratation FlowDeckDB + Open de ligne, tableau pleine largeur) | **Statut**: EN COURS 🔄 > **Cible**: parité Notion + intégration forge · **Follow-ups v7.3 livrés**: sidebar teamspaces, notif `page.updated`, charts `number` + dashboards multi-DB, unfurl forge, UI Settings → Audit — voir `ROADMAP.md § v7.3.0` ## Avancement Global diff --git a/app/main.py b/app/main.py index 56f27a4..ee0e4ff 100644 --- a/app/main.py +++ b/app/main.py @@ -185,7 +185,7 @@ async def lifespan(_app: FastAPI): app = FastAPI( title="FlowDeck", - version="7.50.0", + version="7.50.1", docs_url="/docs", redoc_url="/redoc", lifespan=lifespan, diff --git a/app/templates/_database_table.html b/app/templates/_database_table.html index bbfb4a5..18a1792 100644 --- a/app/templates/_database_table.html +++ b/app/templates/_database_table.html @@ -125,21 +125,7 @@
- -Impossible d’ouvrir le contenu de cette ligne
'; - } - peekEl.classList.add('open'); - toast('Impossible d’ouvrir le contenu de cette ligne', 'error'); - }); - }; - var pc = document.getElementById('db-side-peek-close'); - if (pc) pc.addEventListener('click', closeDbPeek); - var pf = document.getElementById('db-side-peek-full'); - if (pf) pf.addEventListener('click', function() { - // `dataset.page` et non `iframe.src` : le src porte `?embed=1`, - // la pleine page doit garder sa sidebar et sa barre. - if (peekFrame && peekFrame.dataset.page) { - window.location.href = '/pages/' + peekFrame.dataset.page; - } - }); - document.addEventListener('keydown', function(e) { - if (e.key === 'Escape' && peekEl.classList.contains('open')) closeDbPeek(); - }); - document.addEventListener('pointerdown', function(e) { + peekEl.classList.add('open'); + if (peekLoading) peekLoading.style.display = ''; + if (peekFrame) peekFrame.src = 'about:blank'; + if (peekTitle) peekTitle.textContent = ''; + resolveRowContentPage(pageId).then(function(pid){ if (!peekEl.classList.contains('open')) return; - if (peekEl.contains(e.target)) return; - if (e.target.closest('#db-table-container, .database-table-container, [id^="inline-db-"]')) return; - closeDbPeek(); - }); - function wireDbPeekResize() { - if (window.fdWirePeekResize) { - window.fdWirePeekResize(peekEl, peekEl.querySelector('.peek-resize-handle'), closeDbPeek); - } else if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', wireDbPeekResize); + if (peekLoading) peekLoading.style.display = 'none'; + // `?embed=1` : uniquement le document edite, pas l'habillage + // (sidebar + barre) — la pleine page reste via le bouton « full ». + if (peekFrame) { peekFrame.dataset.page = pid; peekFrame.src = '/pages/'+pid+'?embed=1'; } + }) + .catch(function(){ + // L'échec est rendu DANS le panneau (srcdoc) : sous le build + // CSP d'Alpine les toasts ne s'affichent pas partout. + if (peekFrame) { + peekFrame.srcdoc = 'Impossible d’ouvrir le contenu de cette ligne
'; } - } - wireDbPeekResize(); - } + peekEl.classList.add('open'); + toast('Impossible d’ouvrir le contenu de cette ligne', 'error'); + }); + }; + document.addEventListener('keydown', function(e) { + var p = document.getElementById('db-side-peek'); + if (e.key === 'Escape' && p && p.classList.contains('open')) closeDbPeek(); + }); + document.addEventListener('pointerdown', function(e) { + var p = document.getElementById('db-side-peek'); + if (!p || !p.classList.contains('open')) return; + if (p.contains(e.target)) return; + if (e.target.closest('#db-table-container, .database-table-container, [id^="inline-db-"]')) return; + closeDbPeek(); + }); function resolveRowContentPage(rowId){ return fetch('/db/pages/'+rowId+'/open/api') diff --git a/tests/test_my_tasks_workspace_coherence.py b/tests/test_my_tasks_workspace_coherence.py index 62ee676..a719b1b 100644 --- a/tests/test_my_tasks_workspace_coherence.py +++ b/tests/test_my_tasks_workspace_coherence.py @@ -1485,6 +1485,22 @@ def test_base_page_collection_renders_the_table_when_embedded(): assert "not embed" not in branch.split("template")[0] +def test_embed_editor_can_render_inline_databases(): + """Le peek (`page_editor_embed.html`) doit charger database_table.js : + sans lui, une base embarquée restait bloquée à « Loading database… » et + l'icône Open de fin de ligne ne faisait rien. Le panneau #db-side-peek + est créé à la demande par database_table.js (markup unique).""" + from pathlib import Path + + html = Path("app/templates/page_editor_embed.html").read_text(encoding="utf-8") + assert "_database_table_scripts.html" in html + js = Path("static/js/database_table.js").read_text(encoding="utf-8") + assert "ensureDbPeek" in js + # Pas de second markup statique du panneau (source unique). + tbl = Path("app/templates/_database_table.html").read_text(encoding="utf-8") + assert 'id="db-side-peek"' not in tbl + + def test_open_button_carries_its_title_as_attribute(): """Le titre est lu depuis `dataset.openTitle` : disponible aussi dans le calendrier et la vue Jour, où il n'y a pas de ligne `.mt-row`."""