From 1969a00151951f442e386867eaedaccb93854556 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Sun, 5 Apr 2026 23:47:15 +0700 Subject: [PATCH] feat: add bird configuration preview functionality with tabbed interface for fragments and prefixes. Implement fragment extraction and default path selection for improved user experience in previewing BIRD configurations. --- web/src/routes/operations/+page.svelte | 78 ++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/web/src/routes/operations/+page.svelte b/web/src/routes/operations/+page.svelte index 3a56e9d..356bd4f 100644 --- a/web/src/routes/operations/+page.svelte +++ b/web/src/routes/operations/+page.svelte @@ -60,6 +60,24 @@ let previewData = $state(null); let prefixesData = $state([]); let previewLoading = $state(false); + let previewSubTab = $state<'bird' | 'prefixes'>('bird'); + let birdPreviewPath = $state(''); + + function asPreviewFragments(d: unknown): Record { + if (!d || typeof d !== 'object' || Array.isArray(d)) return {}; + const out: Record = {}; + for (const [k, v] of Object.entries(d as Record)) { + if (typeof v === 'string') out[k] = v; + } + return out; + } + + function defaultBirdPreviewPath(frags: Record): string { + if (frags['_bird_full_expanded.conf']) return '_bird_full_expanded.conf'; + if (frags['bird.conf']) return 'bird.conf'; + const keys = Object.keys(frags).sort(); + return keys[0] ?? ''; + } // Diff let diffDialog = $state(false); @@ -112,8 +130,10 @@ previewRevision = rev; previewLoading = true; previewDialog = true; + previewSubTab = 'bird'; previewData = null; prefixesData = []; + birdPreviewPath = ''; try { const [prev, pfx] = await Promise.all([ apiJSON(`/v1/revisions/${rev.id}/preview`), @@ -121,6 +141,8 @@ ]); previewData = prev; prefixesData = (pfx.items ?? []).map((p: { prefix: string }) => p.prefix); + const frags = asPreviewFragments(prev); + birdPreviewPath = defaultBirdPreviewPath(frags); } catch (e) { toast.error(e instanceof Error ? e.message : String(e)); } finally { @@ -483,22 +505,58 @@ - + Ревизия {previewRevision?.id.slice(0, 8)}… - Предпросмотр префиксов ревизии + + Срендеренный конфиг BIRD 2 (фрагменты из control plane) и материализованные префиксы. + {#if previewLoading}

Загрузка…

{:else} -

Префиксов: {prefixesData.length}

- - {#each prefixesData as pfx} -

{pfx}

- {:else} -

Нет префиксов

- {/each} -
+ + + Конфиг BIRD + Префиксы + + + {@const frags = asPreviewFragments(previewData)} + {#if Object.keys(frags).length === 0} +

Нет фрагментов превью (старая ревизия или пустой render).

+ {:else} +
+ + +
+

+ Совет: откройте _bird_full_expanded.conf — один текст с + bird.conf и содержимым всех include. +

+ +
{frags[birdPreviewPath] ?? ''}
+
+ {/if} +
+ +

Префиксов: {prefixesData.length}

+ + {#each prefixesData as pfx} +

{pfx}

+ {:else} +

Нет префиксов

+ {/each} +
+
+
{/if}