Add autocomplete status check and restructure test environments
Add Ollama autocomplete status endpoint to AI routes, update sync panel UI to display autocomplete state, replace monolithic test compose files with separate Linux/Windows variants, and add PowerShell build script for Windows deployment
This commit is contained in:
+58
-23
@@ -341,15 +341,18 @@ function _renderSyncPanel(panel) {
|
||||
|
||||
let _aiProcessing = false;
|
||||
let _aiConfigured = null; // null = unknown, true/false
|
||||
let _aiAutocomplete = null; // null = unknown, {available, server_ok, model_loaded, model, error}
|
||||
|
||||
/** Check if AI is configured by calling the /api/ai/status endpoint.
|
||||
* Updates _aiConfigured and refreshes the panel if open. */
|
||||
* Updates _aiConfigured, _aiAutocomplete and refreshes the panel if open. */
|
||||
async function _checkAIStatus() {
|
||||
try {
|
||||
const status = await api('/api/ai/status');
|
||||
_aiConfigured = status.configured === true;
|
||||
_aiAutocomplete = status.autocomplete || null;
|
||||
} catch {
|
||||
_aiConfigured = false;
|
||||
_aiAutocomplete = null;
|
||||
}
|
||||
_updateAIStatusInPanel();
|
||||
}
|
||||
@@ -359,34 +362,66 @@ function _renderAIStatusSection(panel) {
|
||||
section.className = 'sync-panel__ai-section';
|
||||
section.id = 'sync-panel-ai';
|
||||
|
||||
let statusIcon, statusText, statusClass;
|
||||
// ---- External provider status ----
|
||||
let extIcon, extText, extClass;
|
||||
if (_aiProcessing) {
|
||||
statusIcon = 'loader';
|
||||
statusText = 'Traitement en cours…';
|
||||
statusClass = 'sync-panel__ai--processing';
|
||||
extIcon = 'loader';
|
||||
extText = 'Traitement en cours…';
|
||||
extClass = 'sync-panel__ai--processing';
|
||||
} else if (_aiConfigured === true) {
|
||||
statusIcon = 'check-circle';
|
||||
statusText = 'IA configurée et active';
|
||||
statusClass = 'sync-panel__ai--active';
|
||||
extIcon = 'check-circle';
|
||||
extText = 'Fournisseur externe actif';
|
||||
extClass = 'sync-panel__ai--active';
|
||||
} else if (_aiConfigured === false) {
|
||||
statusIcon = 'x-circle';
|
||||
statusText = 'IA non configurée';
|
||||
statusClass = 'sync-panel__ai--inactive';
|
||||
extIcon = 'x-circle';
|
||||
extText = 'Aucun fournisseur';
|
||||
extClass = 'sync-panel__ai--inactive';
|
||||
} else {
|
||||
statusIcon = 'help-circle';
|
||||
statusText = 'Statut IA inconnu';
|
||||
statusClass = 'sync-panel__ai--unknown';
|
||||
extIcon = 'help-circle';
|
||||
extText = 'Vérification…';
|
||||
extClass = '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>
|
||||
`;
|
||||
// ---- Autocomplete (Ollama) status ----
|
||||
let acIcon, acText, acClass;
|
||||
if (_aiAutocomplete && _aiAutocomplete.available) {
|
||||
acIcon = 'check-circle';
|
||||
acText = 'Auto-complétion active';
|
||||
acClass = 'sync-panel__ai--active';
|
||||
} else if (_aiAutocomplete && _aiAutocomplete.server_ok && !_aiAutocomplete.model_loaded) {
|
||||
acIcon = 'alert-triangle';
|
||||
acText = 'Modèle non chargé';
|
||||
acClass = 'sync-panel__ai--inactive';
|
||||
} else if (_aiAutocomplete && _aiAutocomplete.error) {
|
||||
acIcon = 'x-circle';
|
||||
acText = 'Serveur Ollama injoignable';
|
||||
acClass = 'sync-panel__ai--inactive';
|
||||
} else if (_aiAutocomplete === null) {
|
||||
acIcon = 'help-circle';
|
||||
acText = 'Vérification…';
|
||||
acClass = 'sync-panel__ai--unknown';
|
||||
} else {
|
||||
acIcon = 'x-circle';
|
||||
acText = 'Non configuré';
|
||||
acClass = 'sync-panel__ai--inactive';
|
||||
}
|
||||
|
||||
section.innerHTML = '' +
|
||||
'<div class="sync-panel__ai-title">Intelligence Artificielle</div>' +
|
||||
'<div class="sync-panel__ai-row">' +
|
||||
'<span class="sync-panel__ai-label">Fournisseur</span>' +
|
||||
'<span class="sync-panel__ai-state ' + extClass + '" data-lucide-icon="' + extIcon + '">' +
|
||||
'<i data-lucide="' + extIcon + '" style="width:14px;height:14px"></i>' +
|
||||
extText +
|
||||
'</span>' +
|
||||
'</div>' +
|
||||
'<div class="sync-panel__ai-row">' +
|
||||
'<span class="sync-panel__ai-label">Auto-complétion</span>' +
|
||||
'<span class="sync-panel__ai-state ' + acClass + '" data-lucide-icon="' + acIcon + '">' +
|
||||
'<i data-lucide="' + acIcon + '" style="width:14px;height:14px"></i>' +
|
||||
acText +
|
||||
'</span>' +
|
||||
'</div>';
|
||||
|
||||
panel.appendChild(section);
|
||||
// Trigger icon refresh via global
|
||||
|
||||
+13
-6
@@ -4239,16 +4239,23 @@ body.resizing-v {
|
||||
padding: 10px 14px;
|
||||
}
|
||||
|
||||
.sync-panel__ai-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.sync-panel__ai-title {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sync-panel__ai-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.sync-panel__ai-label {
|
||||
font-size: 0.72rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.sync-panel__ai-state {
|
||||
|
||||
Reference in New Issue
Block a user