Compare commits
2
Commits
88226f6dd9
...
6a7284245f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a7284245f | ||
|
|
67ce135b46 |
No files matched your search
@@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
<CardContent class="space-y-3 p-3 sm:p-4">
|
<CardContent class="space-y-3 p-3 sm:p-4">
|
||||||
{#each jobs as job (job.job_id)}
|
{#each jobs as job (job.job_id)}
|
||||||
<div class="bg-card min-w-0 rounded-lg border">
|
<div class="bg-card min-w-0 overflow-hidden rounded-lg border">
|
||||||
<div class="flex min-w-0 flex-col gap-3 p-3 sm:p-4">
|
<div class="flex min-w-0 flex-col gap-3 p-3 sm:p-4">
|
||||||
<div class="flex min-w-0 flex-wrap items-start justify-between gap-2">
|
<div class="flex min-w-0 flex-wrap items-start justify-between gap-2">
|
||||||
<div class="min-w-0 flex items-center gap-2">
|
<div class="min-w-0 flex items-center gap-2">
|
||||||
@@ -76,11 +76,11 @@
|
|||||||
aria-expanded={isJobExpanded(job.job_id)}
|
aria-expanded={isJobExpanded(job.job_id)}
|
||||||
onclick={() => void onToggleJobExpanded(job)}
|
onclick={() => void onToggleJobExpanded(job)}
|
||||||
>
|
>
|
||||||
<ChevronDown class={cn('size-3.5 transition-transform', isJobExpanded(job.job_id) && 'rotate-180')} />
|
<ChevronDown class={cn('size-4 transition-transform', isJobExpanded(job.job_id) && 'rotate-180')} />
|
||||||
</Button>
|
</Button>
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<p class="font-medium break-words">{job.kind}</p>
|
<p class="font-medium break-words">{job.kind}</p>
|
||||||
<p class="text-muted-foreground font-mono text-[11px] break-all">{job.job_id}</p>
|
<p class="text-muted-foreground font-mono text-xs break-all">{job.job_id}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
@@ -128,8 +128,8 @@
|
|||||||
{@const jobReport = jobReportsById.get(job.job_id)}
|
{@const jobReport = jobReportsById.get(job.job_id)}
|
||||||
{@const logEntries = getJobLogEntries(detailedJob)}
|
{@const logEntries = getJobLogEntries(detailedJob)}
|
||||||
{@const logTotal = getJobLogTotal(detailedJob, logEntries)}
|
{@const logTotal = getJobLogTotal(detailedJob, logEntries)}
|
||||||
<div class="border-t bg-muted/10 p-3 sm:p-4">
|
<div class="border-t bg-muted/10 p-3 sm:p-4 max-h-[70vh] overflow-y-auto overscroll-contain">
|
||||||
<div class="space-y-3">
|
<div class="space-y-3 pr-1">
|
||||||
{#if isDetailsLoading}
|
{#if isDetailsLoading}
|
||||||
<p class="text-muted-foreground text-xs">Догружаем свежие детали задачи…</p>
|
<p class="text-muted-foreground text-xs">Догружаем свежие детали задачи…</p>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -209,20 +209,20 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid gap-2 md:grid-cols-2 xl:grid-cols-4">
|
<div class="grid min-w-0 gap-2 md:grid-cols-2 xl:grid-cols-4">
|
||||||
<div class="rounded-md border bg-muted/40 p-2.5">
|
<div class="min-w-0 overflow-hidden rounded-md border bg-muted/40 p-2.5">
|
||||||
<p class="text-muted-foreground text-[11px] uppercase">Агрегация</p>
|
<p class="text-muted-foreground text-[11px] uppercase">Агрегация</p>
|
||||||
<p class="text-sm font-semibold">{jobReport.aggregationTotal} префиксов</p>
|
<p class="text-sm font-semibold">{jobReport.aggregationTotal} префиксов</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="rounded-md border bg-muted/40 p-2.5">
|
<div class="min-w-0 overflow-hidden rounded-md border bg-muted/40 p-2.5">
|
||||||
<p class="text-muted-foreground text-[11px] uppercase">Домены</p>
|
<p class="text-muted-foreground text-[11px] uppercase">Домены</p>
|
||||||
<p class="text-sm font-semibold">{jobReport.domains.length}</p>
|
<p class="text-sm font-semibold">{jobReport.domains.length}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="rounded-md border bg-muted/40 p-2.5">
|
<div class="min-w-0 overflow-hidden rounded-md border bg-muted/40 p-2.5">
|
||||||
<p class="text-muted-foreground text-[11px] uppercase">ASN</p>
|
<p class="text-muted-foreground text-[11px] uppercase">ASN</p>
|
||||||
<p class="text-sm font-semibold">{jobReport.asn.length}</p>
|
<p class="text-sm font-semibold">{jobReport.asn.length}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="rounded-md border bg-muted/40 p-2.5">
|
<div class="min-w-0 overflow-hidden rounded-md border bg-muted/40 p-2.5">
|
||||||
<p class="text-muted-foreground text-[11px] uppercase">CDN/IP Range</p>
|
<p class="text-muted-foreground text-[11px] uppercase">CDN/IP Range</p>
|
||||||
<p class="text-sm font-semibold">{jobReport.cdn.length}/{jobReport.ipRanges.length}</p>
|
<p class="text-sm font-semibold">{jobReport.cdn.length}/{jobReport.ipRanges.length}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -238,8 +238,8 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="grid gap-3 xl:grid-cols-2">
|
<div class="grid min-w-0 gap-3 xl:grid-cols-2">
|
||||||
<div class="space-y-1.5 rounded-lg border p-3">
|
<div class="min-w-0 overflow-hidden space-y-1.5 rounded-lg border p-3">
|
||||||
<p class="text-sm font-medium">Домены: какой домен какие IP/префиксы вернул</p>
|
<p class="text-sm font-medium">Домены: какой домен какие IP/префиксы вернул</p>
|
||||||
<ScrollArea class="max-h-44 rounded border bg-muted/25 p-2">
|
<ScrollArea class="max-h-44 rounded border bg-muted/25 p-2">
|
||||||
{#each jobReport.domains as row (`${job.job_id}-domain-${row.source}`)}
|
{#each jobReport.domains as row (`${job.job_id}-domain-${row.source}`)}
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-1.5 rounded-lg border p-3">
|
<div class="min-w-0 overflow-hidden space-y-1.5 rounded-lg border p-3">
|
||||||
<p class="text-sm font-medium">ASN: сколько префиксов получено по AS</p>
|
<p class="text-sm font-medium">ASN: сколько префиксов получено по AS</p>
|
||||||
<ScrollArea class="max-h-44 rounded border bg-muted/25 p-2">
|
<ScrollArea class="max-h-44 rounded border bg-muted/25 p-2">
|
||||||
{#each jobReport.asn as row (`${job.job_id}-asn-${row.asn}`)}
|
{#each jobReport.asn as row (`${job.job_id}-asn-${row.asn}`)}
|
||||||
@@ -266,7 +266,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-1.5 rounded-lg border p-3">
|
<div class="min-w-0 overflow-hidden space-y-1.5 rounded-lg border p-3">
|
||||||
<p class="text-sm font-medium">CDN: из каждой ссылки полученные IP/префиксы</p>
|
<p class="text-sm font-medium">CDN: из каждой ссылки полученные IP/префиксы</p>
|
||||||
<ScrollArea class="max-h-44 rounded border bg-muted/25 p-2">
|
<ScrollArea class="max-h-44 rounded border bg-muted/25 p-2">
|
||||||
{#each jobReport.cdn as row (`${job.job_id}-cdn-${row.source}`)}
|
{#each jobReport.cdn as row (`${job.job_id}-cdn-${row.source}`)}
|
||||||
@@ -280,7 +280,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-1.5 rounded-lg border p-3">
|
<div class="min-w-0 overflow-hidden space-y-1.5 rounded-lg border p-3">
|
||||||
<p class="text-sm font-medium">IP range: итог по статическим диапазонам</p>
|
<p class="text-sm font-medium">IP range: итог по статическим диапазонам</p>
|
||||||
<ScrollArea class="max-h-44 rounded border bg-muted/25 p-2">
|
<ScrollArea class="max-h-44 rounded border bg-muted/25 p-2">
|
||||||
{#each jobReport.ipRanges as row (`${job.job_id}-ipr-${row.source}`)}
|
{#each jobReport.ipRanges as row (`${job.job_id}-ipr-${row.source}`)}
|
||||||
|
|||||||
@@ -77,14 +77,14 @@
|
|||||||
<Badge variant={birdHealthyBadgeVariant(birdStatus.healthy)}>{birdHealthyShortLabel(birdStatus.healthy)}</Badge>
|
<Badge variant={birdHealthyBadgeVariant(birdStatus.healthy)}>{birdHealthyShortLabel(birdStatus.healthy)}</Badge>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<p class="text-muted-foreground max-w-[56ch] text-sm">
|
<p class="text-foreground/80 max-w-[56ch] text-sm">
|
||||||
Локально на хосте API: <code class="bg-muted rounded px-1 text-xs">birdc show protocols</code>. Не заменяет мониторинг спикеров.
|
Локально на хосте API: <code class="bg-muted rounded px-1 text-xs">birdc show protocols</code>. Не заменяет мониторинг спикеров.
|
||||||
</p>
|
</p>
|
||||||
{#if birdLoading}
|
{#if birdLoading}
|
||||||
<p class="text-muted-foreground text-sm">Загрузка…</p>
|
<p class="text-foreground/80 text-sm">Загрузка…</p>
|
||||||
{:else if birdStatus}
|
{:else if birdStatus}
|
||||||
{#if !birdStatus.birdc_configured}
|
{#if !birdStatus.birdc_configured}
|
||||||
<p class="text-muted-foreground text-sm">{birdStatus.message ?? 'birdc не настроен на API.'}</p>
|
<p class="text-foreground/80 text-sm">{birdStatus.message ?? 'birdc не настроен на API.'}</p>
|
||||||
{:else if birdStatus.error}
|
{:else if birdStatus.error}
|
||||||
<p class="text-destructive text-sm">{birdStatus.error}</p>
|
<p class="text-destructive text-sm">{birdStatus.error}</p>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<p class="text-muted-foreground text-sm">Статус не загружен</p>
|
<p class="text-foreground/80 text-sm">Статус не загружен</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="p-0">
|
<CardContent class="p-0">
|
||||||
|
<div class="overflow-x-auto [scrollbar-gutter:stable]">
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
@@ -76,5 +77,6 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -10,6 +10,6 @@
|
|||||||
}: WithElementRef<HTMLAttributes<HTMLTableRowElement>> = $props();
|
}: WithElementRef<HTMLAttributes<HTMLTableRowElement>> = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<tr bind:this={ref} data-slot="table-row" class={cn("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", className)} {...restProps}>
|
<tr bind:this={ref} data-slot="table-row" class={cn("hover:bg-muted/70 data-[state=selected]:bg-muted border-b transition-colors", className)} {...restProps}>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</tr>
|
</tr>
|
||||||
@@ -791,7 +791,7 @@
|
|||||||
<DialogTitle>Задача: {jobDetail?.kind}</DialogTitle>
|
<DialogTitle>Задача: {jobDetail?.kind}</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
{#if jobDetail}
|
{#if jobDetail}
|
||||||
<div class={dialogBodyPanel}>
|
<div class={cn(dialogBodyPanel, 'max-h-[80vh] overflow-y-auto')}>
|
||||||
<div class="grid grid-cols-2 gap-x-4 gap-y-1 text-sm">
|
<div class="grid grid-cols-2 gap-x-4 gap-y-1 text-sm">
|
||||||
<span class="text-muted-foreground">ID</span><span class="font-mono break-all">{jobDetail.job_id}</span>
|
<span class="text-muted-foreground">ID</span><span class="font-mono break-all">{jobDetail.job_id}</span>
|
||||||
<span class="text-muted-foreground">Статус</span><span><Badge variant={jobStatusVariant(jobDetail.status)}>{jobDetail.status}</Badge></span>
|
<span class="text-muted-foreground">Статус</span><span><Badge variant={jobStatusVariant(jobDetail.status)}>{jobDetail.status}</Badge></span>
|
||||||
|
|||||||
Reference in new issue
Block a user