From c66cc9317ddc623f7c741430d7b8967e91cc505e Mon Sep 17 00:00:00 2001 From: Denozordec Date: Wed, 20 May 2026 14:13:32 +0700 Subject: [PATCH] feat(web): refactor directories and network pages with improved state management and UI components - Updated imports to utilize core UI components for better maintainability. - Refactored state management for communities and DoH profiles, enhancing loading and error handling. - Introduced derived states for KPI cards, providing better insights into community and DoH profile counts. - Streamlined loading functions to improve data fetching efficiency and user experience. - Enhanced UI layout with new icons and improved component structure for clarity. --- .../DirectoriesCommunitiesCard.svelte | 188 +++++ .../DirectoriesDohProfilesCard.svelte | 178 +++++ .../network/NetworkPeersCard.svelte | 290 ++++++++ .../network/NetworkSpeakersCard.svelte | 177 +++++ web/src/routes/directories/+page.svelte | 559 +++++---------- web/src/routes/network/+page.svelte | 641 +++++------------- 6 files changed, 1203 insertions(+), 830 deletions(-) create mode 100644 web/src/lib/components/directories/DirectoriesCommunitiesCard.svelte create mode 100644 web/src/lib/components/directories/DirectoriesDohProfilesCard.svelte create mode 100644 web/src/lib/components/network/NetworkPeersCard.svelte create mode 100644 web/src/lib/components/network/NetworkSpeakersCard.svelte diff --git a/web/src/lib/components/directories/DirectoriesCommunitiesCard.svelte b/web/src/lib/components/directories/DirectoriesCommunitiesCard.svelte new file mode 100644 index 0000000..330c53f --- /dev/null +++ b/web/src/lib/components/directories/DirectoriesCommunitiesCard.svelte @@ -0,0 +1,188 @@ + + + + +
+ Сообщества BGP + Используются для тегирования префиксов в AS- и CDN-модулях +
+
+ +
+
+ + c.id} + loading={initialLoading || loading} + {error} + emptyTitle="Нет сообществ BGP" + emptyDescription="Создайте первое сообщество для тегирования префиксов." + > + {#snippet cell({ row: c, column })} + {#if column.id === 'community'} + {c.community} + {:else if column.id === 'title'} + {c.title?.trim() || '—'} + {:else if column.id === 'id'} + {c.id} + {:else if column.id === 'actions'} +
+ + +
+ {/if} + {/snippet} +
+
+
+ + + + + {editTarget ? 'Редактировать сообщество BGP' : 'Новое сообщество BGP'} + +
+ + + + + + +
+ + + + +
+
diff --git a/web/src/lib/components/directories/DirectoriesDohProfilesCard.svelte b/web/src/lib/components/directories/DirectoriesDohProfilesCard.svelte new file mode 100644 index 0000000..380e2d0 --- /dev/null +++ b/web/src/lib/components/directories/DirectoriesDohProfilesCard.svelte @@ -0,0 +1,178 @@ + + + + +
+ DoH профили + DNS-over-HTTPS серверы для резолвинга доменных модулей +
+
+ +
+
+ + d.id} + loading={initialLoading || loading} + {error} + emptyTitle="Нет DoH профилей" + emptyDescription="Добавьте DNS-over-HTTPS сервер для доменных модулей." + > + {#snippet cell({ row: d, column })} + {#if column.id === 'url'} + {d.url} + {:else if column.id === 'timeout_ms'} + {d.timeout_ms ?? '—'} + {:else if column.id === 'id'} + {d.id} + {:else if column.id === 'actions'} +
+ + +
+ {/if} + {/snippet} +
+
+
+ + + + + {editTarget ? 'Редактировать' : 'Новый'} DoH профиль + +
+ + + + + + +
+ + + + +
+
diff --git a/web/src/lib/components/network/NetworkPeersCard.svelte b/web/src/lib/components/network/NetworkPeersCard.svelte new file mode 100644 index 0000000..921b333 --- /dev/null +++ b/web/src/lib/components/network/NetworkPeersCard.svelte @@ -0,0 +1,290 @@ + + + + +
+ BGP-пиры + Настройка BGP-соседей и привязка к спикерам +
+
+ +
+
+ + p.id} + loading={initialLoading || loading} + {error} + emptyTitle="Нет BGP-пиров" + emptyDescription="Добавьте первого BGP-соседа для установки сессии." + > + {#snippet cell({ row: p, column })} + {#if column.id === 'name'} + {p.name?.trim() || '—'} + {:else if column.id === 'neighbor'} + {p.neighbor} + {:else if column.id === 'remote_asn'} + {p.remote_asn ?? '—'} + {:else if column.id === 'enabled'} +
+ setEnabled(p, v)} + /> +
+ {:else if column.id === 'session_state'} + {p.session_state || '—'} + {:else if column.id === 'speaker'} + {speakerLabelById(p.bgp_speaker_id)} + {:else if column.id === 'actions'} +
+ + +
+ {/if} + {/snippet} +
+
+
+ + + + + {editTarget ? 'Редактировать пира' : 'Новый пир'} + BGP-сосед для установки сессии + +
+ + + + + + + + + + + + +
+
+ +

+ Выключенный пир не попадает в конфиг BIRD до следующей ревизии. +

+
+ { + form = { ...form, enabled: v }; + }} + /> +
+
+ + + + +
+
diff --git a/web/src/lib/components/network/NetworkSpeakersCard.svelte b/web/src/lib/components/network/NetworkSpeakersCard.svelte new file mode 100644 index 0000000..7d7d7b1 --- /dev/null +++ b/web/src/lib/components/network/NetworkSpeakersCard.svelte @@ -0,0 +1,177 @@ + + + + +
+ Спикеры + BIRD-агенты, применяющие конфигурацию на нодах +
+
+ +
+
+ + s.id} + loading={initialLoading || loading} + {error} + emptyTitle="Нет спикеров" + emptyDescription="Добавьте BIRD-агент для применения конфигурации." + > + {#snippet cell({ row: s, column })} + {#if column.id === 'endpoint'} + {s.endpoint} + {:else if column.id === 'role'} + {s.role} + {:else if column.id === 'last_applied_revision_id'} + + {s.last_applied_revision_id ? s.last_applied_revision_id.slice(0, 8) + '…' : '—'} + + {:else if column.id === 'actions'} +
+ + +
+ {/if} + {/snippet} +
+
+
+ + + + + {editTarget ? 'Редактировать спикера' : 'Новый спикер'} + +
+ + + + + + +
+ + + + +
+
diff --git a/web/src/routes/directories/+page.svelte b/web/src/routes/directories/+page.svelte index fb264ac..4a89929 100644 --- a/web/src/routes/directories/+page.svelte +++ b/web/src/routes/directories/+page.svelte @@ -1,219 +1,221 @@
+ > + {#snippet actions()} + + {/snippet} + + + + + О справочниках + + Сообщества BGP используются в AS- и CDN-модулях для тегирования префиксов. DoH-профили — в + доменных модулях для DNS-over-HTTPS резолвинга. Настройка модулей — на странице + . + + + +
+ {#if initialLoading} + {#each Array(3) as _, i (i)} + + {/each} + {:else} + {#each kpiCards as card (card.id)} + {@const Icon = card.icon} + {@const a = card.accent} + + +
+ + + {card.label} + + {#if card.href} + + {/if} +
+ {card.value} +
+ + {card.badge} +

{card.description}

+
+
+ {/each} + {/if} +
@@ -221,215 +223,24 @@ DoH профили - - - -
- Сообщества BGP - Используются для тегирования префиксов -
-
- - -
-
- - - - - Код сообщества - Название - ID - - - - - {#each communities as c (c.id)} - - {c.community} - {c.title?.trim() || '—'} - {c.id} - -
- - -
-
-
- {:else} - - - {commLoading ? 'Загрузка…' : 'Нет записей. Создайте первую.'} - - - {/each} -
-
-
-
+
- - - -
- DoH профили - DNS-over-HTTPS серверы для резолвинга доменных модулей -
-
- - -
-
- - - - - URL - Таймаут (мс) - ID - - - - - {#each dohProfiles as d (d.id)} - - {d.url} - {d.timeout_ms ?? '—'} - {d.id} - -
- - -
-
-
- {:else} - - - {dohLoading ? 'Загрузка…' : 'Нет DoH профилей.'} - - - {/each} -
-
-
-
+
- - - - - - {commEdit ? 'Редактировать сообщество BGP' : 'Новое сообщество BGP'} - -
- - - - - - -
- - - - -
-
- - { - if (!v) commDeleteTarget = null; - }} -> - - - Удалить сообщество «{commDisplay(commDeleteTarget)}»? - Это приведёт к удалению привязки во всех модулях. - - - (commDeleteTarget = null)}>Отмена - Удалить - - - - - - - - - {dohEdit ? 'Редактировать' : 'Новый'} DoH профиль - -
- - - - - - -
- - - - -
-
- - { - if (!v) dohDeleteTarget = null; - }} -> - - - Удалить DoH профиль? - {dohDeleteTarget?.url} - - - (dohDeleteTarget = null)}>Отмена - Удалить - - - diff --git a/web/src/routes/network/+page.svelte b/web/src/routes/network/+page.svelte index 6073d3a..2097814 100644 --- a/web/src/routes/network/+page.svelte +++ b/web/src/routes/network/+page.svelte @@ -1,250 +1,214 @@
+ > + {#snippet actions()} + + {/snippet} + + + + + О сетевой конфигурации + + Пиры привязаны к спикерам (BIRD-агентам). Apply запускает применение ревизии на ноде. Полный + список ревизий и задач — на странице + . + + + +
+ {#if initialLoading} + {#each Array(3) as _, i (i)} + + {/each} + {:else} + {#each kpiCards as card (card.id)} + {@const Icon = card.icon} + {@const a = card.accent} + + + + + {card.label} + + {card.value} + + + {card.badge} +

{card.description}

+
+
+ {/each} + {/if} +
@@ -252,260 +216,25 @@ Спикеры - - - -
- BGP-пиры - Настройка BGP-соседей -
-
- - -
-
- - - - - Имя - Адрес - Remote ASN - Вкл. - Состояние сессии - Спикер - - - - - {#each peers as p (p.id)} - - {p.name?.trim() || '—'} - {p.neighbor} - {p.remote_asn ?? '—'} - - setPeerEnabled(p, v)} - /> - - - {p.session_state || '—'} - - {speakerLabelById(p.bgp_speaker_id)} - -
- - -
-
-
- {:else} - - - {peersLoading ? 'Загрузка…' : 'Нет пиров.'} - - - {/each} -
-
-
-
+
- - - -
- Спикеры - BIRD-агенты, применяющие конфигурацию -
-
- - -
-
- - - - - Endpoint - Роль - Последняя ревизия - - - - - {#each speakers as s (s.id)} - - {s.endpoint} - {s.role} - {s.last_applied_revision_id - ? s.last_applied_revision_id.slice(0, 8) + '…' - : '—'} - -
- - -
-
-
- {:else} - - - {speakersLoading ? 'Загрузка…' : 'Нет спикеров.'} - - - {/each} -
-
-
-
+
- - - - - - {peerEdit ? 'Редактировать пира' : 'Новый пир'} - BGP-сосед для установки сессии - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- -

- Выключенный пир не попадает в конфиг BIRD до следующей ревизии. -

-
- { - peerForm = { ...peerForm, enabled: v }; - }} - /> -
-
- - - - -
-
- - { - if (!v) peerDeleteTarget = null; - }} -> - - - Удалить пира? - {peerDeleteTarget?.neighbor} - - - (peerDeleteTarget = null)}>Отмена - Удалить - - - - - - - - - {speakerEdit ? 'Редактировать спикера' : 'Новый спикер'} - -
-
- - -
-
- - -
-
- - - - -
-