// ============================================
// GIT PUSHER - MAIN JAVASCRIPT
// Version 2.1 avec déploiement vers SH Cluster
// ============================================
// Configuration par défaut
const DEFAULT_CONFIG = {
api: {
url: '',
port: 9999,
useProxy: true
},
deployer: {
enabled: false,
host: '',
port: 9998,
token: '',
useSSL: true
}
};
// Charger la configuration
function loadAppConfig() {
try {
const stored = localStorage.getItem('git_pusher_config');
if (stored) {
return JSON.parse(stored);
}
} catch (e) {
console.warn('Erreur chargement config localStorage:', e);
}
return DEFAULT_CONFIG;
}
// Déterminer l'URL du serveur API
function getServerUrl() {
const config = loadAppConfig();
const hostname = window.location.hostname;
const protocol = window.location.protocol;
// Si une URL est configurée, l'utiliser
if (config.api && config.api.url) {
let url = config.api.url;
// Ajouter le port si pas de proxy
if (!config.api.useProxy && config.api.port) {
url = url.replace(/\/$/, '') + ':' + config.api.port;
}
return url;
}
// Fallback : auto-détection basée sur le hostname
// Si c'est une IP ou localhost, ajouter le port 9999
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname) || hostname === 'localhost') {
return protocol + '//' + hostname + ':9999';
}
// Si c'est un domaine, essayer d'ajouter -api au sous-domaine
// Exemple: splunk.example.com → splunk-api.example.com
const parts = hostname.split('.');
if (parts.length >= 2) {
parts[0] = parts[0] + '-api';
return protocol + '//' + parts.join('.');
}
// Dernier fallback : même hostname avec port 9999
return protocol + '//' + hostname + ':9999';
}
// Configuration
const GIT_PUSHER_CONFIG = {
serverUrl: getServerUrl(),
credentialsKey: 'git_pusher_credentials',
deployerConfigKey: 'git_pusher_deployer_config',
version: '2.1.0'
};
// Configuration SH Deployer (peut être modifiée via l'interface)
let SH_DEPLOYER_CONFIG = {
enabled: false,
host: '',
port: 9998,
token: ''
};
// État global
let selectedApps = [];
let selectedShClusterApps = []; // Apps sélectionnées pour le SH Cluster
let isProcessing = false;
let deployerAvailable = false;
// ============================================
// INITIALISATION
// ============================================
require([
'jquery',
'splunkjs/mvc',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc/simplexml/ready!'
], function($, mvc, SearchManager) {
console.log("Git Pusher v2.1 initializing...");
// Initialiser le système de licence
if (typeof initializeLicense === 'function') {
initializeLicense();
} else {
console.warn("License system not loaded");
}
// Charger les credentials sauvegardés
loadSavedCredentials();
// Charger la config du deployer
loadDeployerConfig();
// Vérifier la disponibilité du SH Deployer
checkDeployerHealth();
// Récupérer les résultats de recherche pour les apps
const searchManager = mvc.Components.get('dsearch');
if (searchManager) {
searchManager.on('search:done', function() {
const results = searchManager.data('results');
if (results) {
results.on('data', function() {
const rows = results.data().rows;
const fields = results.data().fields;
renderAppsList(rows, fields);
});
}
});
}
// Exposer les fonctions globalement
window.pushDashboards = pushDashboards;
window.resetForm = resetForm;
window.toggleSelectAll = toggleSelectAll;
window.toggleShClusterAllApps = toggleShClusterAllApps;
window.updateSelectedShClusterApps = updateSelectedShClusterApps;
// Attacher les événements pour la section SH Cluster
setTimeout(function() {
// Checkbox "Deploy to SH Cluster"
const deployCheckbox = document.getElementById('deploy-to-shcluster');
if (deployCheckbox) {
deployCheckbox.addEventListener('change', function() {
toggleDeployerOptions();
});
}
// Checkbox "All apps"
const allAppsCheckbox = document.getElementById('shcluster-all-apps');
if (allAppsCheckbox) {
allAppsCheckbox.addEventListener('change', function() {
toggleShClusterAllApps();
});
}
// Bouton configure
const configBtn = document.getElementById('deployer-config-btn');
if (configBtn) {
configBtn.addEventListener('click', function() {
showDeployerConfigModal();
});
}
}, 500);
});
// Afficher/masquer les options du deployer
function toggleDeployerOptions() {
const checkbox = document.getElementById('deploy-to-shcluster');
const appsSection = document.getElementById('deployer-apps-section');
const authSection = document.getElementById('deployer-auth');
if (checkbox && checkbox.checked) {
if (appsSection) appsSection.classList.add('visible');
if (authSection) authSection.classList.add('visible');
} else {
if (appsSection) appsSection.classList.remove('visible');
if (authSection) authSection.classList.remove('visible');
}
}
// ============================================
// RENDU DE LA LISTE DES APPLICATIONS
// ============================================
function renderAppsList(rows, fields) {
const container = document.getElementById('dashboard-list');
if (!container) return;
// Trouver les index des colonnes
const nameIdx = fields.indexOf('name');
const labelIdx = fields.indexOf('label');
const descIdx = fields.indexOf('description');
// Générer le HTML
let html = `
`;
rows.forEach((row, index) => {
const name = row[nameIdx] || '';
const label = row[labelIdx] || name;
const desc = row[descIdx] || '';
// Ignorer certaines apps système
if (name.startsWith('splunk_') || name === 'learned' || name === 'launcher') {
return;
}
html += `
`;
});
container.innerHTML = html;
console.log(`Rendered ${rows.length} applications`);
}
// ============================================
// GESTION DE LA SÉLECTION
// ============================================
function updateSelectedApps() {
const checkboxes = document.querySelectorAll('#dashboard-list input[type="checkbox"][data-app-id]');
selectedApps = [];
checkboxes.forEach(cb => {
if (cb.checked) {
selectedApps.push({
id: cb.getAttribute('data-app-id'),
label: cb.getAttribute('data-app-label')
});
}
});
// Mettre à jour le "Select All"
const selectAll = document.getElementById('select-all');
if (selectAll) {
const allChecked = Array.from(checkboxes).every(cb => cb.checked);
const someChecked = Array.from(checkboxes).some(cb => cb.checked);
selectAll.checked = allChecked;
selectAll.indeterminate = someChecked && !allChecked;
}
// Mettre à jour la liste des apps pour le SH Cluster
updateShClusterAppsList();
console.log(`Selected ${selectedApps.length} apps`);
}
function updateShClusterAppsList() {
const container = document.getElementById('shcluster-apps-container');
if (!container) return;
if (selectedApps.length === 0) {
container.innerHTML = 'Select apps from the left panel first
';
selectedShClusterApps = [];
return;
}
// Sauvegarder l'état actuel des checkboxes
const currentState = {};
const existingCheckboxes = container.querySelectorAll('input[type="checkbox"][data-app-id]');
existingCheckboxes.forEach(cb => {
currentState[cb.getAttribute('data-app-id')] = cb.checked;
});
// Vérifier si la liste a changé (nouvelles apps ajoutées ou apps retirées)
const currentAppIds = Array.from(existingCheckboxes).map(cb => cb.getAttribute('data-app-id'));
const newAppIds = selectedApps.map(app => app.id);
const listChanged = currentAppIds.length !== newAppIds.length ||
!currentAppIds.every(id => newAppIds.includes(id));
// Ne recréer le HTML que si la liste a changé
if (listChanged || existingCheckboxes.length === 0) {
let html = '';
selectedApps.forEach((app, index) => {
// Préserver l'état si l'app existait, sinon cocher par défaut
const isChecked = currentState.hasOwnProperty(app.id) ? currentState[app.id] : true;
html += `
`;
});
container.innerHTML = html;
}
// Mettre à jour la liste des apps SH Cluster sélectionnées (sans recréer le HTML)
updateSelectedShClusterApps();
}
function updateSelectedShClusterApps() {
const allAppsCheckbox = document.getElementById('shcluster-all-apps');
if (allAppsCheckbox && allAppsCheckbox.checked) {
// Toutes les apps sélectionnées pour Git
selectedShClusterApps = [...selectedApps];
} else {
// Seulement les apps cochées dans la liste SH Cluster
const checkboxes = document.querySelectorAll('#shcluster-apps-container input[type="checkbox"][data-app-id]');
selectedShClusterApps = [];
checkboxes.forEach(cb => {
if (cb.checked) {
selectedShClusterApps.push({
id: cb.getAttribute('data-app-id'),
label: cb.getAttribute('data-app-label')
});
}
});
}
console.log(`Selected ${selectedShClusterApps.length} apps for SH Cluster`);
}
function toggleShClusterAllApps() {
const allAppsCheckbox = document.getElementById('shcluster-all-apps');
const appsList = document.getElementById('shcluster-apps-list');
if (allAppsCheckbox && appsList) {
if (allAppsCheckbox.checked) {
// Masquer la liste et utiliser toutes les apps
appsList.style.display = 'none';
selectedShClusterApps = [...selectedApps];
console.log('SH Cluster: Using all selected apps');
} else {
// Afficher la liste pour permettre la sélection manuelle
appsList.style.display = 'block';
// Ne PAS appeler updateSelectedShClusterApps() ici
// L'utilisateur va faire sa sélection manuellement
// La liste garde son état actuel (tous cochés par défaut)
console.log('SH Cluster: Manual selection enabled');
}
}
}
function toggleSelectAll(checked) {
const checkboxes = document.querySelectorAll('#dashboard-list input[type="checkbox"][data-app-id]');
checkboxes.forEach(cb => {
cb.checked = checked;
});
updateSelectedApps();
}
// ============================================
// PUSH VERS GIT
// ============================================
async function pushDashboards() {
console.log("Starting push process...");
// Vérifier si déjà en cours
if (isProcessing) {
console.log("Push already in progress");
return;
}
// Vérifier la licence AVANT tout
if (typeof checkLicenseBeforePush === 'function') {
const licenseOk = await checkLicenseBeforePush();
if (!licenseOk) {
console.log("License check failed");
return;
}
}
// Récupérer les valeurs du formulaire
const gitUrl = document.getElementById('git-url')?.value?.trim();
const gitBranch = document.getElementById('git-branch')?.value?.trim() || 'main';
const gitToken = document.getElementById('git-token')?.value?.trim();
const commitMessage = document.getElementById('commit-message')?.value?.trim();
const saveCredentials = document.getElementById('save-credentials')?.checked;
// Ne PAS rappeler updateSelectedApps() ici car cela réinitialiserait la liste SH Cluster
// La liste selectedApps est déjà à jour grâce aux événements onchange
// Validation
if (!gitUrl) {
showMessage('error', 'Please enter a Git repository URL');
return;
}
if (!gitToken) {
showMessage('error', 'Please enter a Git token or password');
return;
}
if (!commitMessage) {
showMessage('error', 'Please enter a commit message');
return;
}
if (selectedApps.length === 0) {
showMessage('error', 'Please select at least one application to deploy');
return;
}
// Sauvegarder les credentials si demandé
if (saveCredentials) {
saveCredentialsToStorage(gitUrl, gitBranch, gitToken);
}
// Vérifier si le déploiement vers SH Cluster est activé
const deployToSHCluster = document.getElementById('deploy-to-shcluster')?.checked || false;
const shAuthUser = document.getElementById('sh-auth-user')?.value?.trim() || '';
const shAuthPass = document.getElementById('sh-auth-pass')?.value?.trim() || '';
// La liste selectedShClusterApps est déjà à jour via les événements onchange
// Ne pas rappeler updateSelectedShClusterApps() pour éviter de réinitialiser la sélection
// Validation des apps SH Cluster si déploiement activé
if (deployToSHCluster && selectedShClusterApps.length === 0) {
showMessage('error', 'Please select at least one application to deploy to SH Cluster');
return;
}
// Démarrer le push
isProcessing = true;
showLoading(true, deployToSHCluster);
hideMessages();
try {
// Récupérer l'utilisateur courant
const currentUser = await getCurrentUser();
// Récupérer les infos de licence depuis le localStorage
const licenseInfo = getLicenseInfo ? getLicenseInfo() : null;
const licenseType = licenseInfo?.type_name || '';
const licenseId = licenseInfo?.license_id || '';
// Construire les paramètres
const params = new URLSearchParams({
git_url: gitUrl,
git_branch: gitBranch,
git_token: gitToken,
commit_message: commitMessage,
apps: JSON.stringify(selectedApps),
shcluster_apps: JSON.stringify(selectedShClusterApps), // Apps pour le SH Cluster
user: currentUser,
deploy_to_shcluster: deployToSHCluster.toString(),
deployer_host: SH_DEPLOYER_CONFIG.host,
deployer_token: SH_DEPLOYER_CONFIG.token,
license_type: licenseType,
license_id: licenseId
});
// Ajouter les credentials SH si fournis
if (shAuthUser) params.append('sh_auth_user', shAuthUser);
if (shAuthPass) params.append('sh_auth_pass', shAuthPass);
console.log(`Pushing ${selectedApps.length} apps to Git${deployToSHCluster ? `, ${selectedShClusterApps.length} apps to SH Cluster` : ''}`);
// Appeler le serveur
const response = await fetch(`${GIT_PUSHER_CONFIG.serverUrl}/push?${params.toString()}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
const result = await response.json();
console.log("Push result:", result);
if (result.status === 'success') {
// Incrémenter le compteur d'utilisation côté client
console.log("=== INCREMENT USAGE ===");
console.log("typeof incrementUsage:", typeof incrementUsage);
console.log("typeof window.incrementUsage:", typeof window.incrementUsage);
try {
if (typeof window.incrementUsage === 'function') {
const stats = window.incrementUsage();
console.log("✓ Usage incremented successfully:", stats);
} else if (typeof incrementUsage === 'function') {
const stats = incrementUsage();
console.log("✓ Usage incremented (local):", stats);
} else {
console.warn("✗ incrementUsage function not available");
}
} catch (e) {
console.error("✗ Error incrementing usage:", e);
}
let message = `✅ Successfully deployed ${result.apps_pushed || selectedApps.length} application(s) to Git!`;
// Ajouter le statut du déploiement SH Cluster
if (deployToSHCluster && result.shcluster_deployment) {
if (result.shcluster_deployment.success) {
message += '\n🚀 SH Cluster deployment triggered successfully!';
} else {
message += `\n⚠️ SH Cluster deployment failed: ${result.shcluster_deployment.message}`;
}
}
showMessage('success', message);
// Reset la sélection après succès
setTimeout(() => {
toggleSelectAll(false);
}, 2000);
} else if (result.error_code === 'LICENSE_ERROR') {
showMessage('error', `🔐 ${result.message}`);
// Afficher le modal de licence
if (typeof showLicenseModal === 'function') {
showLicenseModal(result.message, result.error_code);
}
} else if (result.error_code === 'APP_LIMIT') {
showMessage('error', `📦 ${result.message}`);
} else {
showMessage('error', result.message || 'Unknown error occurred');
}
} catch (error) {
console.error("Push error:", error);
showMessage('error', `Connection error: ${error.message}. Is the Git Pusher server running?`);
} finally {
isProcessing = false;
showLoading(false);
}
}
// ============================================
// UTILITAIRES UI
// ============================================
function showLoading(show, deployToSHCluster = false) {
const loading = document.getElementById('loading');
const pushBtn = document.getElementById('push-btn');
const loadingText = document.querySelector('.loading-text');
if (loading) {
loading.classList.toggle('active', show);
}
if (loadingText && show) {
if (deployToSHCluster) {
loadingText.textContent = 'Deploying to Git and SH Cluster... Please wait';
} else {
loadingText.textContent = 'Deploying applications to Git... Please wait';
}
}
if (pushBtn) {
pushBtn.disabled = show;
if (show) {
pushBtn.textContent = deployToSHCluster ? '⏳ Deploying to Git + SH...' : '⏳ Deploying...';
} else {
pushBtn.textContent = '✈️ Deploy to Git';
}
}
}
function showMessage(type, text) {
hideMessages();
const successMsg = document.getElementById('success-msg');
const errorMsg = document.getElementById('error-msg');
const successText = document.getElementById('success-text');
const errorText = document.getElementById('error-text');
if (type === 'success' && successMsg && successText) {
successText.textContent = text;
successMsg.classList.add('active');
// Auto-hide après 5 secondes
setTimeout(() => {
successMsg.classList.remove('active');
}, 5000);
} else if (type === 'error' && errorMsg && errorText) {
errorText.textContent = text;
errorMsg.classList.add('active');
}
}
function hideMessages() {
const successMsg = document.getElementById('success-msg');
const errorMsg = document.getElementById('error-msg');
if (successMsg) successMsg.classList.remove('active');
if (errorMsg) errorMsg.classList.remove('active');
}
function resetForm(clearCredentials = false) {
// Reset les champs
const commitMessage = document.getElementById('commit-message');
if (commitMessage) commitMessage.value = '';
if (clearCredentials) {
const gitUrl = document.getElementById('git-url');
const gitToken = document.getElementById('git-token');
const saveCredentials = document.getElementById('save-credentials');
if (gitUrl) gitUrl.value = '';
if (gitToken) gitToken.value = '';
if (saveCredentials) saveCredentials.checked = false;
// Supprimer les credentials sauvegardés
localStorage.removeItem(GIT_PUSHER_CONFIG.credentialsKey);
}
// Reset la sélection
toggleSelectAll(false);
// Cacher les messages
hideMessages();
console.log("Form reset" + (clearCredentials ? " (with credentials)" : ""));
}
// ============================================
// GESTION DES CREDENTIALS
// ============================================
function saveCredentialsToStorage(gitUrl, gitBranch, gitToken) {
try {
const credentials = {
gitUrl: gitUrl,
gitBranch: gitBranch,
// Note: En production, envisager une solution plus sécurisée
gitToken: btoa(gitToken), // Encodage basique (pas sécurisé, juste pour l'obfuscation)
savedAt: new Date().toISOString()
};
localStorage.setItem(GIT_PUSHER_CONFIG.credentialsKey, JSON.stringify(credentials));
console.log("Credentials saved");
} catch (error) {
console.error("Error saving credentials:", error);
}
}
function loadSavedCredentials() {
try {
const saved = localStorage.getItem(GIT_PUSHER_CONFIG.credentialsKey);
if (!saved) return;
const credentials = JSON.parse(saved);
const gitUrl = document.getElementById('git-url');
const gitBranch = document.getElementById('git-branch');
const gitToken = document.getElementById('git-token');
const saveCredentials = document.getElementById('save-credentials');
if (gitUrl && credentials.gitUrl) {
gitUrl.value = credentials.gitUrl;
}
if (gitBranch && credentials.gitBranch) {
gitBranch.value = credentials.gitBranch;
}
if (gitToken && credentials.gitToken) {
gitToken.value = atob(credentials.gitToken);
}
if (saveCredentials) {
saveCredentials.checked = true;
}
console.log("Credentials loaded from storage");
} catch (error) {
console.error("Error loading credentials:", error);
}
}
// ============================================
// RÉCUPÉRATION DE L'UTILISATEUR SPLUNK
// ============================================
async function getCurrentUser() {
try {
const response = await fetch('/en-US/splunkd/__raw/services/authentication/current-context?output_mode=json');
const data = await response.json();
return data.entry?.[0]?.content?.username || 'unknown';
} catch (error) {
console.error("Error getting current user:", error);
return 'unknown';
}
}
// ============================================
// VÉRIFICATION DU SERVEUR
// ============================================
async function checkServerHealth() {
try {
const response = await fetch(`${GIT_PUSHER_CONFIG.serverUrl}/health`, {
method: 'GET',
timeout: 5000
});
const data = await response.json();
return data.status === 'ok';
} catch (error) {
console.error("Server health check failed:", error);
return false;
}
}
// ============================================
// SH DEPLOYER FUNCTIONS
// ============================================
async function checkDeployerHealth() {
try {
const response = await fetch(`${GIT_PUSHER_CONFIG.serverUrl}/deployer/health`, {
method: 'GET',
timeout: 5000
});
const data = await response.json();
deployerAvailable = data.status === 'ok';
// Mettre à jour l'UI
updateDeployerUI();
console.log("SH Deployer status:", deployerAvailable ? "Available" : "Unavailable");
return deployerAvailable;
} catch (error) {
console.error("Deployer health check failed:", error);
deployerAvailable = false;
updateDeployerUI();
return false;
}
}
function updateDeployerUI() {
const deployerCheckbox = document.getElementById('deploy-to-shcluster');
const deployerStatus = document.getElementById('deployer-status');
const deployerSection = document.getElementById('deployer-section');
if (deployerCheckbox) {
deployerCheckbox.disabled = !deployerAvailable;
}
if (deployerStatus) {
if (deployerAvailable) {
deployerStatus.innerHTML = '● Connected';
} else {
deployerStatus.innerHTML = '● Disconnected';
}
}
if (deployerSection && !deployerAvailable) {
deployerSection.style.opacity = '0.6';
}
}
function loadDeployerConfig() {
try {
const saved = localStorage.getItem(GIT_PUSHER_CONFIG.deployerConfigKey);
if (saved) {
const config = JSON.parse(saved);
SH_DEPLOYER_CONFIG = { ...SH_DEPLOYER_CONFIG, ...config };
console.log("Deployer config loaded");
}
} catch (error) {
console.error("Error loading deployer config:", error);
}
}
function saveDeployerConfig() {
try {
localStorage.setItem(GIT_PUSHER_CONFIG.deployerConfigKey, JSON.stringify(SH_DEPLOYER_CONFIG));
console.log("Deployer config saved");
} catch (error) {
console.error("Error saving deployer config:", error);
}
}
function showDeployerConfigModal() {
const modal = document.createElement('div');
modal.id = 'deployer-config-modal';
modal.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
`;
modal.innerHTML = `
`;
document.body.appendChild(modal);
}
function closeDeployerConfigModal() {
const modal = document.getElementById('deployer-config-modal');
if (modal) modal.remove();
}
async function saveDeployerConfigFromModal() {
const host = document.getElementById('deployer-config-host')?.value?.trim();
const port = parseInt(document.getElementById('deployer-config-port')?.value) || 9998;
const token = document.getElementById('deployer-config-token')?.value?.trim();
const msgEl = document.getElementById('deployer-config-message');
if (!host) {
if (msgEl) {
msgEl.style.display = 'block';
msgEl.style.background = '#ffebee';
msgEl.style.color = '#c62828';
msgEl.textContent = 'Please enter a host';
}
return;
}
// Mettre à jour la config
SH_DEPLOYER_CONFIG.host = host;
SH_DEPLOYER_CONFIG.port = port;
SH_DEPLOYER_CONFIG.token = token;
// Sauvegarder
saveDeployerConfig();
// Tester la connexion
if (msgEl) {
msgEl.style.display = 'block';
msgEl.style.background = '#e3f2fd';
msgEl.style.color = '#1565c0';
msgEl.textContent = 'Testing connection...';
}
const isHealthy = await checkDeployerHealth();
if (isHealthy) {
if (msgEl) {
msgEl.style.background = '#e8f5e9';
msgEl.style.color = '#2e7d32';
msgEl.textContent = '✓ Connected successfully!';
}
setTimeout(closeDeployerConfigModal, 1500);
} else {
if (msgEl) {
msgEl.style.background = '#ffebee';
msgEl.style.color = '#c62828';
msgEl.textContent = '✗ Connection failed. Check host and port.';
}
}
}
// Vérifier la santé du serveur au démarrage
setTimeout(async () => {
const healthy = await checkServerHealth();
if (!healthy) {
console.warn("Git Pusher server may not be running");
} else {
console.log("Git Pusher server is healthy");
}
}, 1000);
// ============================================
// EXPORT FONCTIONS GLOBALES
// ============================================
// Exposer les fonctions du deployer globalement pour les onclick du HTML
window.showDeployerConfigModal = showDeployerConfigModal;
window.closeDeployerConfigModal = closeDeployerConfigModal;
window.saveDeployerConfigFromModal = saveDeployerConfigFromModal;
// Exposer les fonctions principales
window.pushDashboards = pushDashboards;
window.resetForm = resetForm;
window.toggleSelectAll = toggleSelectAll;
window.updateSelectedApps = updateSelectedApps;
// Fonction toggle pour le HTML
window.toggleDeployerAuth = function() {
var checkbox = document.getElementById('deploy-to-shcluster');
var authSection = document.getElementById('deployer-auth');
if (checkbox && authSection) {
authSection.classList.toggle('visible', checkbox.checked);
}
};
// ============================================
// ATTACHEMENT DES ÉVÉNEMENTS AUX BOUTONS
// ============================================
(function attachButtonEvents() {
function tryAttach() {
console.log("Trying to attach button events...");
// Bouton Deploy to Git
var pushBtn = document.getElementById('push-btn');
if (pushBtn) {
// Supprimer les anciens listeners
pushBtn.replaceWith(pushBtn.cloneNode(true));
pushBtn = document.getElementById('push-btn');
pushBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
console.log("Deploy button clicked!");
pushDashboards();
});
console.log("✓ Deploy button event attached");
} else {
console.log("✗ Deploy button not found yet");
}
// Bouton Reset - chercher par classe ou contenu
var buttons = document.querySelectorAll('button.btn, button.btn-secondary');
buttons.forEach(function(btn) {
if (btn.textContent.includes('Reset') || btn.textContent.includes('🔄')) {
// Supprimer les anciens listeners
var newBtn = btn.cloneNode(true);
btn.parentNode.replaceChild(newBtn, btn);
newBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
console.log("Reset button clicked!");
resetForm(true);
});
console.log("✓ Reset button event attached");
}
});
// Bouton Configure Deployer
var configBtn = document.querySelector('.deployer-config-btn');
if (configBtn) {
// Supprimer les anciens listeners
var newConfigBtn = configBtn.cloneNode(true);
configBtn.parentNode.replaceChild(newConfigBtn, configBtn);
newConfigBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
console.log("Configure button clicked!");
showDeployerConfigModal();
});
console.log("✓ Configure button event attached");
}
// Checkbox deploy to shcluster
var deployCheckbox = document.getElementById('deploy-to-shcluster');
if (deployCheckbox) {
deployCheckbox.addEventListener('change', function() {
var authSection = document.getElementById('deployer-auth');
if (authSection) {
authSection.classList.toggle('visible', this.checked);
}
});
console.log("✓ Deploy checkbox event attached");
}
// Si le bouton principal n'est pas encore là, réessayer
if (!pushBtn) {
console.log("Retrying in 500ms...");
setTimeout(tryAttach, 500);
} else {
console.log("=== All button events attached successfully ===");
}
}
// Démarrer après un délai pour laisser le DOM se charger
if (document.readyState === 'complete') {
console.log("Document ready, attaching events in 1s...");
setTimeout(tryAttach, 1000);
} else {
window.addEventListener('load', function() {
console.log("Window loaded, attaching events in 1s...");
setTimeout(tryAttach, 1000);
});
}
})();
// ============================================
// EXPORT POUR DEBUG
// ============================================
window.GitPusher = {
config: GIT_PUSHER_CONFIG,
deployerConfig: SH_DEPLOYER_CONFIG,
getSelectedApps: () => selectedApps,
checkServer: checkServerHealth,
checkDeployer: checkDeployerHealth,
version: GIT_PUSHER_CONFIG.version
};