From 5e3666e8993ab583b0b4956ba4b1023059d7bdaa Mon Sep 17 00:00:00 2001 From: kirillius Date: Fri, 10 Oct 2025 02:29:16 +0300 Subject: [PATCH] =?UTF-8?q?push=20=D0=BF=D0=BE=D1=82=D0=B5=D1=80=D1=8F?= =?UTF-8?q?=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webui/src/pages/NetworkResources.js | 122 ++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 webui/src/pages/NetworkResources.js diff --git a/webui/src/pages/NetworkResources.js b/webui/src/pages/NetworkResources.js new file mode 100644 index 0000000..d0a9319 --- /dev/null +++ b/webui/src/pages/NetworkResources.js @@ -0,0 +1,122 @@ +import $ from 'jquery'; +import { JSONRPC } from '@/json-rpc.js'; + +let resourcesData = { + domains: [], + subnets: [], + ASN: [] +}; + +function escapeHtml(value) { + return String(value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +function buildAsnLink(asn) { + const numericPart = String(asn).match(/\d+/); + const asnId = numericPart ? numericPart[0] : String(asn).replace(/[^a-zA-Z0-9]/g, ''); + const safeId = asnId.length ? asnId : '0'; + return `https://bgp.he.net/AS${encodeURIComponent(safeId)}`; +} + +function normalizeArray(values) { + if (!Array.isArray(values)) { + return []; + } + + return values + .map(item => (item === null || item === undefined) ? '' : String(item)) + .filter(item => item.length > 0) + .sort((a, b) => a.localeCompare(b, 'ru', { numeric: true, sensitivity: 'base' })); +} + +async function fetchResources() { + try { + const result = await JSONRPC.NetworkManager.getOutputResources(); + resourcesData = { + domains: normalizeArray(result?.domains), + subnets: normalizeArray(result?.subnets), + ASN: normalizeArray(result?.ASN) + }; + return true; + } catch (error) { + console.error('Ошибка при загрузке сетевых ресурсов:', error); + resourcesData = { + domains: [], + subnets: [], + ASN: [] + }; + return false; + } +} + +function renderAsnSection(items) { + const content = items.length + ? items.map(item => `${escapeHtml(item)}`).join(', ') + : 'Данные отсутствуют'; + + return ` +
+

Автономные системы (ASN)

+

${content}

+
+ `; +} + +function renderGridSection(title, items) { + const listItems = items.length + ? items.map(item => `
  • ${escapeHtml(item)}
  • `).join('') + : '
  • Данные отсутствуют
  • '; + + return ` +
    +

    ${title}

    + +
    + `; +} + +function renderResources($container) { + const html = ` + ${renderAsnSection(resourcesData.ASN)} + ${renderGridSection('Доменные имена', resourcesData.domains)} + ${renderGridSection('Маршруты', resourcesData.subnets)} + `; + + $container.html(html); +} + +export const NetworkResourcesPage = { + render: () => ` +
    +

    Сетевые ресурсы

    +
    +

    Загрузка сетевых ресурсов...

    +
    +
    + `, + mount: async () => { + const $container = $('#network-resources-content'); + $container.html('

    Загрузка сетевых ресурсов...

    '); + + const success = await fetchResources(); + if (success) { + renderResources($container); + } else { + $container.html('

    Не удалось загрузить данные. Попробуйте обновить страницу позже.

    '); + } + }, + unmount: () => { + resourcesData = { + domains: [], + subnets: [], + ASN: [] + }; + } +};