interface monitoring chatbot
This commit is contained in:
337
assets/js/chatbot_settings.js
Normal file
337
assets/js/chatbot_settings.js
Normal file
@ -0,0 +1,337 @@
|
||||
/**
|
||||
* JavaScript pour la gestion des clés API du chatbot
|
||||
*/
|
||||
|
||||
// État global
|
||||
let currentProvider = null;
|
||||
let editMode = false;
|
||||
|
||||
// Helper URLs
|
||||
const API_HELP_URLS = {
|
||||
'gemini': 'https://aistudio.google.com/apikey',
|
||||
'mistral': 'https://console.mistral.ai/api-keys/',
|
||||
'openai': 'https://platform.openai.com/api-keys'
|
||||
};
|
||||
|
||||
// ========== Modal Management ==========
|
||||
|
||||
function openAddKeyModal(provider = null) {
|
||||
const modal = document.getElementById('keyModal');
|
||||
const title = document.getElementById('modalTitle');
|
||||
const form = document.getElementById('keyForm');
|
||||
const providerSelect = document.getElementById('provider');
|
||||
const testResult = document.getElementById('testResult');
|
||||
|
||||
// Reset form
|
||||
form.reset();
|
||||
testResult.style.display = 'none';
|
||||
document.getElementById('keyAction').value = 'add';
|
||||
editMode = false;
|
||||
|
||||
// Pre-select provider if provided
|
||||
if (provider) {
|
||||
providerSelect.value = provider;
|
||||
updateModelsList();
|
||||
providerSelect.disabled = false;
|
||||
} else {
|
||||
providerSelect.disabled = false;
|
||||
}
|
||||
|
||||
title.textContent = 'Ajouter une clé API';
|
||||
modal.classList.add('show');
|
||||
}
|
||||
|
||||
function editKey(provider) {
|
||||
currentProvider = provider;
|
||||
editMode = true;
|
||||
|
||||
// Récupérer les infos de la clé
|
||||
fetch(`chatbot_api_ajax.php?action=get&provider=${provider}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const modal = document.getElementById('keyModal');
|
||||
const title = document.getElementById('modalTitle');
|
||||
const form = document.getElementById('keyForm');
|
||||
const providerSelect = document.getElementById('provider');
|
||||
const modelSelect = document.getElementById('model_default');
|
||||
const testResult = document.getElementById('testResult');
|
||||
|
||||
testResult.style.display = 'none';
|
||||
document.getElementById('keyAction').value = 'edit';
|
||||
|
||||
// Remplir le formulaire
|
||||
providerSelect.value = provider;
|
||||
providerSelect.disabled = true;
|
||||
updateModelsList();
|
||||
|
||||
// Attendre que la liste des modèles soit chargée
|
||||
setTimeout(() => {
|
||||
modelSelect.value = data.data.model_default;
|
||||
|
||||
if (data.data.quota_max) {
|
||||
document.getElementById('set_quota').checked = true;
|
||||
document.getElementById('quota_max').value = data.data.quota_max;
|
||||
toggleQuotaInput();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
title.textContent = `Modifier la clé ${provider}`;
|
||||
modal.classList.add('show');
|
||||
} else {
|
||||
showToast(data.error || 'Erreur lors du chargement', 'error');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
showToast('Erreur de connexion', 'error');
|
||||
});
|
||||
}
|
||||
|
||||
function closeKeyModal() {
|
||||
const modal = document.getElementById('keyModal');
|
||||
modal.classList.remove('show');
|
||||
currentProvider = null;
|
||||
editMode = false;
|
||||
}
|
||||
|
||||
// ========== Form Handling ==========
|
||||
|
||||
function updateModelsList() {
|
||||
const provider = document.getElementById('provider').value;
|
||||
const modelSelect = document.getElementById('model_default');
|
||||
const keyHelp = document.getElementById('keyHelp');
|
||||
|
||||
// Clear current options
|
||||
modelSelect.innerHTML = '<option value="">-- Sélectionner un modèle --</option>';
|
||||
|
||||
if (!provider) {
|
||||
keyHelp.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// Populate models for selected provider
|
||||
if (models[provider]) {
|
||||
models[provider].forEach(model => {
|
||||
const option = document.createElement('option');
|
||||
option.value = model.model_id;
|
||||
option.textContent = model.display_name;
|
||||
if (model.recommended) {
|
||||
option.textContent += ' ⭐';
|
||||
}
|
||||
modelSelect.appendChild(option);
|
||||
});
|
||||
|
||||
// Auto-select first recommended model
|
||||
const recommended = models[provider].find(m => m.recommended);
|
||||
if (recommended) {
|
||||
modelSelect.value = recommended.model_id;
|
||||
}
|
||||
}
|
||||
|
||||
// Update help text
|
||||
if (API_HELP_URLS[provider]) {
|
||||
keyHelp.innerHTML = `💡 Obtenir une clé : <a href="${API_HELP_URLS[provider]}" target="_blank">${API_HELP_URLS[provider]}</a>`;
|
||||
} else {
|
||||
keyHelp.innerHTML = '';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleQuotaInput() {
|
||||
const checkbox = document.getElementById('set_quota');
|
||||
const quotaGroup = document.getElementById('quotaGroup');
|
||||
quotaGroup.style.display = checkbox.checked ? 'block' : 'none';
|
||||
}
|
||||
|
||||
function toggleKeyVisibility() {
|
||||
const input = document.getElementById('api_key');
|
||||
const button = event.target;
|
||||
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
button.textContent = '🙈';
|
||||
} else {
|
||||
input.type = 'password';
|
||||
button.textContent = '👁️';
|
||||
}
|
||||
}
|
||||
|
||||
// ========== Form Submission ==========
|
||||
|
||||
document.getElementById('keyForm').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(this);
|
||||
formData.append('action', 'save');
|
||||
|
||||
// Show loading
|
||||
const submitBtn = this.querySelector('button[type="submit"]');
|
||||
const originalText = submitBtn.innerHTML;
|
||||
submitBtn.innerHTML = '⏳ Enregistrement...';
|
||||
submitBtn.disabled = true;
|
||||
|
||||
fetch('chatbot_api_ajax.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showToast(data.message || 'Clé enregistrée avec succès', 'success');
|
||||
closeKeyModal();
|
||||
|
||||
// Reload page to show updated keys
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
} else {
|
||||
showToast(data.error || 'Erreur lors de l\'enregistrement', 'error');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
showToast('Erreur de connexion', 'error');
|
||||
})
|
||||
.finally(() => {
|
||||
submitBtn.innerHTML = originalText;
|
||||
submitBtn.disabled = false;
|
||||
});
|
||||
});
|
||||
|
||||
// ========== Test Connection ==========
|
||||
|
||||
function testKeyBeforeSave() {
|
||||
const provider = document.getElementById('provider').value;
|
||||
const apiKey = document.getElementById('api_key').value;
|
||||
const model = document.getElementById('model_default').value;
|
||||
|
||||
if (!provider || !apiKey || !model) {
|
||||
showToast('Veuillez remplir tous les champs obligatoires', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
testConnectionWithParams(provider, apiKey, model);
|
||||
}
|
||||
|
||||
function testConnection(provider) {
|
||||
testConnectionWithParams(provider, null, null);
|
||||
}
|
||||
|
||||
function testConnectionWithParams(provider, apiKey = null, model = null) {
|
||||
const testResult = document.getElementById('testResult');
|
||||
testResult.style.display = 'block';
|
||||
testResult.className = 'test-result';
|
||||
testResult.innerHTML = '🔄 Test en cours...';
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'test');
|
||||
formData.append('provider', provider);
|
||||
if (apiKey) formData.append('api_key', apiKey);
|
||||
if (model) formData.append('model', model);
|
||||
|
||||
fetch('chatbot_api_ajax.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
testResult.className = 'test-result success';
|
||||
testResult.innerHTML = `✅ ${data.message}<br><small>Latence: ${data.latency_ms}ms</small>`;
|
||||
} else {
|
||||
testResult.className = 'test-result error';
|
||||
testResult.innerHTML = `❌ ${data.message}`;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
testResult.className = 'test-result error';
|
||||
testResult.innerHTML = '❌ Erreur de connexion au serveur';
|
||||
});
|
||||
}
|
||||
|
||||
// ========== Delete Key ==========
|
||||
|
||||
function deleteKey(provider) {
|
||||
if (!confirm(`Êtes-vous sûr de vouloir supprimer la clé ${provider} ?\n\nCette action est irréversible.`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'delete');
|
||||
formData.append('provider', provider);
|
||||
|
||||
fetch('chatbot_api_ajax.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showToast('Clé supprimée avec succès', 'success');
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
} else {
|
||||
showToast(data.error || 'Erreur lors de la suppression', 'error');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
showToast('Erreur de connexion', 'error');
|
||||
});
|
||||
}
|
||||
|
||||
// ========== Toast Notifications ==========
|
||||
|
||||
function showToast(message, type = 'info') {
|
||||
const container = document.getElementById('toast-container');
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `toast ${type}`;
|
||||
|
||||
const icons = {
|
||||
'success': '✅',
|
||||
'error': '❌',
|
||||
'warning': '⚠️',
|
||||
'info': 'ℹ️'
|
||||
};
|
||||
|
||||
toast.innerHTML = `
|
||||
<span class="toast-icon">${icons[type] || icons.info}</span>
|
||||
<span class="toast-message">${message}</span>
|
||||
`;
|
||||
|
||||
container.appendChild(toast);
|
||||
|
||||
// Auto-remove after 4 seconds
|
||||
setTimeout(() => {
|
||||
toast.style.opacity = '0';
|
||||
toast.style.transform = 'translateX(100%)';
|
||||
setTimeout(() => toast.remove(), 300);
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
// ========== Close modal on outside click ==========
|
||||
|
||||
document.getElementById('keyModal').addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
closeKeyModal();
|
||||
}
|
||||
});
|
||||
|
||||
// ========== Keyboard shortcuts ==========
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
// ESC to close modal
|
||||
if (e.key === 'Escape') {
|
||||
const modal = document.getElementById('keyModal');
|
||||
if (modal.classList.contains('show')) {
|
||||
closeKeyModal();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ========== Initialize ==========
|
||||
|
||||
console.log('✅ Chatbot Settings JS loaded');
|
||||
console.log('Available models:', models);
|
||||
Reference in New Issue
Block a user