import $ from 'jquery'; import { JSONRPC } from '@/json-rpc.js'; const TDNS_COMPONENT_NAME = 'ru.kirillius.pf.sdn.External.API.Components.TDNS'; const FIELD_IDS = { container: 'tdns-config-container', instancesList: 'tdns-instances-list', addInstanceButton: 'tdns-add-instance-btn', saveButton: 'save-tdns-btn', status: 'tdns-status-message' }; const CLASS_NAMES = { instance: 'tdns-instance-entry', removeButton: 'tdns-remove-instance-btn', serverInput: 'tdns-server-input', tokenInput: 'tdns-token-input', forwarderInput: 'tdns-forwarder-input' }; const SELECTORS = { container: `#${FIELD_IDS.container}`, instancesList: `#${FIELD_IDS.instancesList}`, addInstanceButton: `#${FIELD_IDS.addInstanceButton}`, saveButton: `#${FIELD_IDS.saveButton}`, status: `#${FIELD_IDS.status}` }; let currentConfig = { instances: [] }; let statusTimeoutId = null; let instanceCounter = 0; const getStatusElement = () => $(SELECTORS.status); function normalizeConfig(config) { if (!config || !Array.isArray(config.instances)) { return { instances: [] }; } return { instances: config.instances.map(instance => ({ server: instance?.server || '', token: instance?.token || '', forwarder: instance?.forwarder || '' })) }; } function clearStatus() { const $status = getStatusElement(); if (!$status.length) { return; } if (statusTimeoutId) { clearTimeout(statusTimeoutId); statusTimeoutId = null; } $status.stop(true, true).hide().text('').removeClass('success-message error-message'); } function updateStatus(message, type) { const $status = getStatusElement(); if (!$status.length) { return; } if (statusTimeoutId) { clearTimeout(statusTimeoutId); } $status .removeClass('success-message error-message') .addClass(type === 'success' ? 'success-message' : 'error-message') .text(message) .show(); statusTimeoutId = window.setTimeout(() => { $status.fadeOut(); }, 5000); } async function runAction($button, pendingText, action, messages) { if (!$button.length) { return; } const originalText = $button.text(); $button.prop('disabled', true).text(pendingText); clearStatus(); try { const result = await action(); if (messages?.success) { const successMessage = typeof messages.success === 'function' ? messages.success(result) : messages.success; if (successMessage) { updateStatus(successMessage, 'success'); } } } catch (error) { console.error(messages?.log || 'Ошибка выполнения действия TDNS:', error); if (messages?.error) { updateStatus(messages.error, 'error'); } } finally { $button.prop('disabled', false).text(originalText); } } function resetInstanceCounter() { instanceCounter = 0; } function getNextInstanceId() { instanceCounter += 1; return instanceCounter; } function createInstanceRow(instance = {}) { const uid = getNextInstanceId(); const serverId = `tdns-server-${uid}`; const tokenId = `tdns-token-${uid}`; const forwarderId = `tdns-forwarder-${uid}`; return `

Инстанс

Адрес DNS сервера, на который будут перенаправляться запросы.
`; } function populateInstances() { const instances = currentConfig.instances.length ? currentConfig.instances : []; const $list = $(SELECTORS.instancesList); resetInstanceCounter(); $list.empty(); instances.forEach(instance => { $list.append(createInstanceRow(instance)); }); } function renderTDNSForm() { const $container = $(SELECTORS.container); $container.html(`

Инстансы TDNS

Настройте подключения TDNS. Можно указать несколько серверов с собственными токенами.

`); populateInstances(); attachEventHandlers(); } function collectConfigFromForm() { const instances = []; $(SELECTORS.instancesList).find(`.${CLASS_NAMES.instance}`).each((_, element) => { const $row = $(element); const server = $row.find(`.${CLASS_NAMES.serverInput}`).val().trim(); const token = $row.find(`.${CLASS_NAMES.tokenInput}`).val().trim(); const forwarder = $row.find(`.${CLASS_NAMES.forwarderInput}`).val().trim(); if (server || token || forwarder) { instances.push({ server, token, forwarder }); } }); return { instances }; } async function loadConfig() { try { const fullConfig = await JSONRPC.System.getComponentConfig(TDNS_COMPONENT_NAME); currentConfig = normalizeConfig(fullConfig); return true; } catch (error) { console.error('Ошибка при загрузке конфига TDNS:', error); currentConfig = { instances: [] }; return false; } } function handleAddInstance() { const $list = $(SELECTORS.instancesList); $list.append(createInstanceRow({})); } function handleRemoveInstance(event) { event.preventDefault(); $(event.currentTarget).closest(`.${CLASS_NAMES.instance}`).remove(); } async function handleSave() { const $button = $(SELECTORS.saveButton); await runAction($button, 'Применение...', async () => { const newConfig = collectConfigFromForm(); await JSONRPC.System.setComponentConfig(TDNS_COMPONENT_NAME, newConfig); currentConfig = normalizeConfig(newConfig); populateInstances(); }, { success: 'Конфигурация TDNS успешно сохранена.', error: 'Ошибка при сохранении конфигурации TDNS.', log: 'Ошибка сохранения конфига TDNS' }); } function attachEventHandlers() { $(SELECTORS.saveButton).off('click').on('click', handleSave); $(SELECTORS.addInstanceButton).off('click').on('click', handleAddInstance); $(SELECTORS.instancesList).off('click', `.${CLASS_NAMES.removeButton}`).on('click', `.${CLASS_NAMES.removeButton}`, handleRemoveInstance); } function detachEventHandlers() { $(SELECTORS.saveButton).off('click'); $(SELECTORS.addInstanceButton).off('click'); $(SELECTORS.instancesList).off('click', `.${CLASS_NAMES.removeButton}`); } export const TDNSConfig = { render: () => `

Настройка TDNS

Загрузка конфигурации...

`, mount: async () => { const success = await loadConfig(); if (success) { renderTDNSForm(); } else { $(SELECTORS.container).html('

Не удалось загрузить конфигурацию TDNS.

'); } }, unmount: () => { detachEventHandlers(); clearStatus(); currentConfig = { instances: [] }; } };