// static/js/components/secretsTable.js
import { configStore, cleanupConfigStore } from '../store/configStore.js';
import { fetchSecrets, toggleSecretStatus, removeSecret, fetchSecretYaml } from '../api/secretsService.js';
import { setupConfigModal } from './modals.js';
export async function renderSecretsTable() {
const tableBody = document.getElementById('secret-table-body');
if (!tableBody) return;
tableBody.innerHTML = '<tr><td colspan="4" style="text-align: center; padding: 20px;">Loading...</td></tr>';
try {
const secretResponse = await fetchSecrets();
const allSecrets = [
...(secretResponse.enabled || []).map(s => ({ ...s, status: 'Enabled', configData: s })),
...(secretResponse.disabled || []).map(s => ({ ...s, status: 'Disabled', configData: s }))
];
if (!allSecrets.length) {
tableBody.innerHTML = '<tr><td colspan="4" style="text-align: center; color: var(--secondary-color);">No secrets found.</td></tr>';
configStore.secrets = {};
return;
}
cleanupConfigStore();
configStore.secrets = allSecrets.reduce((acc, s) => {
const existing = acc[s.name] || {};
acc[s.name] = { ...s.configData, yaml: existing.yaml };
return acc;
}, configStore.secrets);
tableBody.innerHTML = '';
allSecrets.forEach(secret => {
const row = tableBody.insertRow();
if (secret.status === 'Disabled') row.classList.add('disabled-row');
const nameCell = row.insertCell();
const nameLink = document.createElement('a');
nameLink.href = '#';
nameLink.innerHTML = `<span class="secret-name">${secret.name}</span>`;
nameLink.onclick = (e) => {
e.preventDefault();
showSecretConfig(secret.name);
};
nameCell.appendChild(nameLink);
row.insertCell().textContent = secret.status;
const secretType = secret.tls_certificate ? 'TLS Certificate' : (secret.generic_secret ? 'Generic Secret' : 'Unknown');
row.insertCell().textContent = secretType;
const actionsCell = row.insertCell();
if (secret.status === 'Enabled') {
const disableBtn = document.createElement('button');
disableBtn.className = 'action-button disable';
disableBtn.textContent = 'Disable';
disableBtn.onclick = (e) => {
e.stopPropagation();
if (confirm(`Are you sure you want to DISABLE secret: ${secret.name}?`)) {
handleStatusToggle(secret.name, 'disable');
}
};
actionsCell.appendChild(disableBtn);
} else {
const enableBtn = document.createElement('button');
enableBtn.className = 'action-button enable';
enableBtn.textContent = 'Enable';
enableBtn.onclick = (e) => {
e.stopPropagation();
if (confirm(`Are you sure you want to ENABLE secret: ${secret.name}?`)) {
handleStatusToggle(secret.name, 'enable');
}
};
actionsCell.appendChild(enableBtn);
const removeBtn = document.createElement('button');
removeBtn.className = 'action-button remove';
removeBtn.textContent = 'Remove';
removeBtn.onclick = (e) => {
e.stopPropagation();
if (confirm(`⚠️ WARNING: Are you absolutely sure you want to PERMANENTLY REMOVE secret: ${secret.name}? This action cannot be undone.`)) {
handleStatusToggle(secret.name, 'remove');
}
};
actionsCell.appendChild(removeBtn);
}
});
} catch (error) {
tableBody.innerHTML = `<tr><td colspan="4" class="error" style="text-align: center;">🚨 Secret Error: ${error.message}</td></tr>`;
}
}
async function handleStatusToggle(name, action) {
try {
if (action === 'remove') {
await removeSecret(name);
} else {
await toggleSecretStatus(name, action);
}
cleanupConfigStore();
renderSecretsTable();
} catch (error) {
alert(`Failed to ${action} secret '${name}'. Error: ${error.message}`);
}
}
async function showSecretConfig(name) {
const config = configStore.secrets[name];
if (!config) return;
let yamlData = config.yaml || 'Loading YAML...';
if (yamlData === 'Loading YAML...') {
try {
yamlData = await fetchSecretYaml(name);
configStore.secrets[name].yaml = yamlData;
} catch (error) {
yamlData = `Error fetching YAML: ${error.message}`;
}
}
setupConfigModal(`Full Config for Secret: ${name}`, config, yamlData);
}