From 4a916e80dbc36516e847854fce6ad8800b311809 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Fri, 29 May 2026 23:45:26 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20aper=C3=A7u=20markdown=20format=C3=A9?= =?UTF-8?q?=20+=20metadata=20dans=20tooltip=20normal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/js/graph.js | 79 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/frontend/js/graph.js b/frontend/js/graph.js index cb465a2..ebdc989 100644 --- a/frontend/js/graph.js +++ b/frontend/js/graph.js @@ -523,18 +523,34 @@ export const GraphViewManager = { _showTooltip(node, screenX, screenY, isPreview) { if (!this._tooltipEl) return; if (isPreview) return; // Preview tooltip handled by _showPreviewTooltip - const tags = (node.tags || []).slice(0, 5).join(', '); + const cacheKey = `${this._vault}:${node.path}`; + const cached = this._previewCache[cacheKey]; + const meta = cached?.meta; + // Build metadata summary if available + let metaHtml = ''; + if (meta?.frontmatter && Object.keys(meta.frontmatter).length > 0) { + const fm = meta.frontmatter; + const parts = []; + if (fm.auteur) parts.push(`✍️ ${fm.auteur}`); + if (fm.date || fm.creation_date) parts.push(`📅 ${fm.date || fm.creation_date}`); + if (fm.statut) parts.push(`📌 ${fm.statut}`); + if (fm.publish) parts.push('✅ publié'); + if (fm.favoris) parts.push('⭐ favoris'); + if (parts.length > 0) metaHtml = `
${parts.join(' · ')}`; + } + const tags = (meta?.tags || node.tags || []).slice(0, 5).join(', '); const inc = node.incoming_count || 0; const out = node.outgoing_count || 0; this._tooltipEl.innerHTML = ` - ${node.name} + ${meta?.title || node.name} ${node.type === 'file' ? `
${node.path}` : ''} + ${metaHtml} ${tags ? `
🏷️ ${tags}` : ''} ${inc + out > 0 ? `
🔗 ${out} sortants · ${inc} entrants` : ''} -
Ctrl+survol pour aperçu + ${node.type === 'file' ? `
Ctrl+survol pour aperçu` : ''} `; this._tooltipEl.style.display = 'block'; - this._tooltipEl.style.maxWidth = '250px'; + this._tooltipEl.style.maxWidth = '280px'; this._tooltipEl.style.left = (screenX + 15) + 'px'; this._tooltipEl.style.top = (screenY - 10) + 'px'; }, @@ -647,35 +663,64 @@ export const GraphViewManager = { async _fetchPreview(node, screenX, screenY) { const cacheKey = `${this._vault}:${node.path}`; if (this._previewCache[cacheKey] !== undefined) { - this._showPreviewTooltip(node, this._previewCache[cacheKey], screenX, screenY); + const cached = this._previewCache[cacheKey]; + this._showPreviewTooltip(node, cached.preview, screenX, screenY); return; } // Show loading indicator - this._showPreviewTooltip(node, 'Chargement...', screenX, screenY); + this._showPreviewTooltip(node, 'Chargement...', screenX, screenY); try { - const data = await api(`/api/file/${encodeURIComponent(this._vault)}/raw?path=${encodeURIComponent(node.path)}`); - const content = (data.raw || '').substring(0, 400).replace(/\n/g, ' '); - this._previewCache[cacheKey] = content; - this._showPreviewTooltip(node, content, screenX, screenY); + const data = await api(`/api/file/${encodeURIComponent(this._vault)}?path=${encodeURIComponent(node.path)}`); + // Strip HTML tags, keep line breaks, limit to 600 chars + const text = (data.html || '').replace(/<[^>]*>/g, '').replace(/\n+/g, '\n').trim(); + const preview = text.substring(0, 600) + (text.length > 600 ? '…' : ''); + // Cache both preview text and full metadata for tooltips + this._previewCache[cacheKey] = { + preview, + meta: { + title: data.title, + frontmatter: data.frontmatter || {}, + tags: data.tags || [], + path: node.path, + } + }; + this._showPreviewTooltip(node, preview, screenX, screenY); } catch { - this._previewCache[cacheKey] = '(impossible de charger le contenu)'; + this._previewCache[cacheKey] = { preview: '(impossible de charger)', meta: null }; this._showPreviewTooltip(node, '(impossible de charger le contenu)', screenX, screenY); } }, _showPreviewTooltip(node, preview, screenX, screenY) { if (!this._tooltipEl || this._ctrlHoverNode !== node) return; - const tags = (node.tags || []).slice(0, 3).join(', '); + const cacheKey = `${this._vault}:${node.path}`; + const cached = this._previewCache[cacheKey]; + const meta = cached?.meta; + // Format frontmatter summary + let fmSummary = ''; + if (meta?.frontmatter && Object.keys(meta.frontmatter).length > 0) { + const fm = meta.frontmatter; + const items = []; + if (fm.auteur) items.push(`✍️ ${fm.auteur}`); + if (fm.date || fm.creation_date) items.push(`📅 ${fm.date || fm.creation_date}`); + if (fm.statut) items.push(`📌 ${fm.statut}`); + if (fm.catégorie || fm.categorie) items.push(`📂 ${fm.catégorie || fm.categorie}`); + if (fm.publish) items.push('✅ publié'); + if (fm.favoris) items.push('⭐ favoris'); + if (items.length > 0) fmSummary = `
${items.join(' · ')}
`; + } + const tags = (meta?.tags || node.tags || []).slice(0, 5).join(', '); this._tooltipEl.innerHTML = ` - ${node.name} + ${meta?.title || node.name} ${node.path} + ${fmSummary} ${tags ? `🏷️ ${tags}` : ''} -
${preview}
+
${preview}
`; this._tooltipEl.style.display = 'block'; - this._tooltipEl.style.maxWidth = '350px'; - this._tooltipEl.style.left = Math.min(screenX + 15, window.innerWidth - 370) + 'px'; - this._tooltipEl.style.top = Math.min(screenY - 10, window.innerHeight - 180) + 'px'; + this._tooltipEl.style.maxWidth = '420px'; + this._tooltipEl.style.left = Math.min(screenX + 15, window.innerWidth - 440) + 'px'; + this._tooltipEl.style.top = Math.min(screenY - 10, window.innerHeight - 220) + 'px'; }, _onMouseUp(e) {