feat: points 11a + 11b — Indicateur AI Actif & Page d'accueil voute
CI / lint (push) Failing after 4s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / security (push) Successful in 8s

Point 11a — Indicateur AI Actif:
- Badge sync flashe en blanc pendant traitement AI (animation CSS)
- Événements ai-processing-start/end dans ai.js
- Section statut IA dans panneau sync (configurée/non configurée/en cours)
- Endpoint GET /api/ai/status vérifiant les clés API configurées

Point 11b — Page d'accueil de voute:
- Endpoint GET /api/vault/{vault}/files?dir=... (trié par mtime)
- Module vaulthome.js: affichage style résultats de recherche
- Breadcrumb navigable, mise à jour auto sur clic dossier dans tree
- Déclenché auto quand un vault spécifique est sélectionné
This commit is contained in:
2026-06-03 22:36:31 -04:00
parent d1ba15c3aa
commit 7a4b3d1329
7 changed files with 692 additions and 5 deletions
+115
View File
@@ -246,6 +246,9 @@ function initSyncStatus() {
});
IndexUpdateManager.connect();
// Initialize AI status tracking
_initAIStatus();
}
function toggleSyncPanel() {
@@ -323,6 +326,118 @@ function _renderSyncPanel(panel) {
}
panel.innerHTML = html;
// ── AI Status section ──
_renderAIStatusSection(panel);
}
// ---------------------------------------------------------------------------
// AI Status Indicator (inside sync panel + header badge animation)
// ---------------------------------------------------------------------------
let _aiProcessing = false;
let _aiStatusChecked = false;
let _aiConfigured = null; // null = unknown, true/false
/** Check if AI is configured by calling the status endpoint. */
async function _checkAIStatus() {
if (_aiStatusChecked) return;
try {
const resp = await api('/api/ai/status');
_aiConfigured = !!(resp && resp.configured);
} catch (e) {
_aiConfigured = false;
}
_aiStatusChecked = true;
}
function _renderAIStatusSection(panel) {
const section = document.createElement('div');
section.className = 'sync-panel__ai-section';
section.id = 'sync-panel-ai';
let statusIcon, statusText, statusClass;
if (_aiProcessing) {
statusIcon = 'loader';
statusText = 'Traitement en cours…';
statusClass = 'sync-panel__ai--processing';
} else if (_aiConfigured === true) {
statusIcon = 'check-circle';
statusText = 'IA configurée et active';
statusClass = 'sync-panel__ai--active';
} else if (_aiConfigured === false) {
statusIcon = 'x-circle';
statusText = 'IA non configurée';
statusClass = 'sync-panel__ai--inactive';
} else {
statusIcon = 'help-circle';
statusText = 'Statut IA inconnu';
statusClass = 'sync-panel__ai--unknown';
}
section.innerHTML = `
<div class="sync-panel__ai-header">
<span class="sync-panel__ai-title">Intelligence Artificielle</span>
<span class="sync-panel__ai-state ${statusClass}" data-lucide-icon="${statusIcon}">
<i data-lucide="${statusIcon}" style="width:14px;height:14px"></i>
${statusText}
</span>
</div>
`;
panel.appendChild(section);
// Trigger icon refresh via global
if (window._obsigateRefreshIcons) window._obsigateRefreshIcons();
}
/** Update the AI section in the open sync panel. */
function _updateAIStatusInPanel() {
const section = document.getElementById('sync-panel-ai');
if (!section) return;
section.innerHTML = '';
const panel = document.getElementById('sync-panel');
if (panel) {
// Re-render just the AI section
const oldSection = panel.querySelector('.sync-panel__ai-section');
if (oldSection) oldSection.remove();
_renderAIStatusSection(panel);
}
}
/** Flash the sync badge white during AI processing. */
function _setBadgeAIProcessing(active) {
const badge = document.getElementById('sync-badge');
if (!badge) return;
if (active) {
badge.classList.add('sync-badge--ai-processing');
} else {
badge.classList.remove('sync-badge--ai-processing');
}
}
/** Initialize AI status tracking. */
function _initAIStatus() {
// Listen for AI processing events from ai.js
document.addEventListener('ai-processing-start', () => {
_aiProcessing = true;
_setBadgeAIProcessing(true);
_updateAIStatusInPanel();
});
document.addEventListener('ai-processing-end', () => {
_aiProcessing = false;
_setBadgeAIProcessing(false);
_updateAIStatusInPanel();
});
// Check AI status on first sync panel open
const badge = document.getElementById('sync-badge');
if (badge) {
const origClick = badge.onclick;
badge.addEventListener('click', () => {
_checkAIStatus().then(() => _updateAIStatusInPanel());
}, { once: false });
}
}
// ---------------------------------------------------------------------------