Newer
Older
EnvoyControlPlane / static / js / components / extensionConfigsTable.js
// static/js/components/extensionConfigsTable.js
import { configStore, cleanupConfigStore } from '../store/configStore.js';
import { fetchExtensionConfigs, toggleExtensionConfigStatus, removeExtensionConfig, fetchExtensionConfigYaml } from '../api/extensionConfigsService.js';
import { setupConfigModal } from './modals.js';

export async function renderExtensionConfigsTable() {
    const tableBody = document.getElementById('extensionconfig-table-body');
    if (!tableBody) return;

    tableBody.innerHTML = '<tr><td colspan="4" style="text-align: center; padding: 20px;">Loading...</td></tr>';

    try {
        const configResponse = await fetchExtensionConfigs();
        const allConfigs = [
            ...(configResponse.enabled || []).map(c => ({ ...c, status: 'Enabled', configData: c })),
            ...(configResponse.disabled || []).map(c => ({ ...c, status: 'Disabled', configData: c }))
        ];

        if (!allConfigs.length) {
            tableBody.innerHTML = '<tr><td colspan="4" style="text-align: center; color: var(--secondary-color);">No matches found.</td></tr>';
            configStore.extension_configs = {};
            return;
        }

        cleanupConfigStore();
        configStore.extension_configs = allConfigs.reduce((acc, c) => {
            const existing = acc[c.name] || {};
            acc[c.name] = { ...c.configData, yaml: existing.yaml };
            return acc;
        }, configStore.extension_configs);

        tableBody.innerHTML = '';
        allConfigs.forEach(config => {
            const row = tableBody.insertRow();
            if (config.status === 'Disabled') row.classList.add('disabled-row');

            const nameCell = row.insertCell();
            const nameLink = document.createElement('a');
            nameLink.href = '#';
            nameLink.innerHTML = `<span class="extension-config-name">${config.name}</span>`;
            nameLink.onclick = (e) => {
                e.preventDefault();
                showExtensionConfig(config.name);
            };
            nameCell.appendChild(nameLink);

            row.insertCell().textContent = config.status;
            row.insertCell().textContent = config.typed_config?.['@type'] || 'N/A';

            const actionsCell = row.insertCell();
            if (config.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 config: ${config.name}?`)) {
                        handleStatusToggle(config.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 config: ${config.name}?`)) {
                        handleStatusToggle(config.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 config: ${config.name}? This action cannot be undone.`)) {
                        handleStatusToggle(config.name, 'remove');
                    }
                };
                actionsCell.appendChild(removeBtn);
            }
        });
    } catch (error) {
        tableBody.innerHTML = `<tr><td colspan="4" class="error" style="text-align: center;">🚨 ExtensionConfig Error: ${error.message}</td></tr>`;
    }
}

async function handleStatusToggle(name, action) {
    try {
        if (action === 'remove') {
            await removeExtensionConfig(name);
        } else {
            await toggleExtensionConfigStatus(name, action);
        }
        cleanupConfigStore();
        renderExtensionConfigsTable();
    } catch (error) {
        alert(`Failed to ${action} config '${name}'. Error: ${error.message}`);
    }
}

async function showExtensionConfig(name) {
    const config = configStore.extension_configs[name];
    if (!config) return;

    let yamlData = config.yaml || 'Loading YAML...';
    if (yamlData === 'Loading YAML...') {
        try {
            yamlData = await fetchExtensionConfigYaml(name);
            configStore.extension_configs[name].yaml = yamlData;
        } catch (error) {
            yamlData = `Error fetching YAML: ${error.message}`;
        }
    }
    setupConfigModal(`Full Config for ExtensionConfig: ${name}`, config, yamlData);
}