Compare commits
2
Commits
d91667f698
...
9f021289c0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f021289c0 | ||
|
|
40c8a8d38a |
No files matched your search
@@ -60,7 +60,7 @@
|
||||
<div class="bg-background flex min-h-screen">
|
||||
<aside
|
||||
class={cn(
|
||||
'border-border bg-sidebar flex shrink-0 flex-col border-r transition-all duration-200',
|
||||
'border-border bg-sidebar sticky top-0 flex h-screen shrink-0 flex-col overflow-hidden border-r transition-all duration-200',
|
||||
collapsed ? 'w-14' : 'w-56'
|
||||
)}
|
||||
aria-label="Основная навигация"
|
||||
@@ -122,7 +122,7 @@
|
||||
<Separator />
|
||||
|
||||
<!-- Main nav -->
|
||||
<nav class="flex flex-1 flex-col gap-0.5 p-2">
|
||||
<nav class="flex flex-1 flex-col gap-0.5 overflow-y-auto p-2">
|
||||
{#each nav as item (item.href)}
|
||||
{@const Icon = item.icon}
|
||||
{@const active = isActive(item.href)}
|
||||
|
||||
+15
-10
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { apiJSON, apiFetch } from '$lib/api/client.js';
|
||||
import { apiJSON, apiFetch, apiPageAll } from '$lib/api/client.js';
|
||||
import type { ModulesResponse, RevisionsResponse, PeersResponse, SpeakersResponse, JobsResponse } from '$lib/api/types.js';
|
||||
import { Badge } from '$lib/components/ui/badge/index.js';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
@@ -26,6 +26,11 @@ const resolve = (path: string) => path as any;
|
||||
let runningJobs = $state(0);
|
||||
let loading = $state(true);
|
||||
|
||||
async function countAll(path: string): Promise<number> {
|
||||
const items = await apiPageAll<unknown>(path, 500);
|
||||
return items.length;
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
loading = true;
|
||||
try {
|
||||
@@ -35,17 +40,17 @@ const resolve = (path: string) => path as any;
|
||||
healthy = false;
|
||||
}
|
||||
try {
|
||||
const [m, r, p, s, j] = await Promise.all([
|
||||
apiJSON<ModulesResponse>('/v1/modules?limit=1'),
|
||||
apiJSON<RevisionsResponse>('/v1/revisions?limit=1'),
|
||||
apiJSON<PeersResponse>('/v1/peers?limit=1'),
|
||||
apiJSON<SpeakersResponse>('/v1/speakers?limit=1'),
|
||||
const [mCount, rCount, pCount, sCount, j] = await Promise.all([
|
||||
countAll('/v1/modules'),
|
||||
countAll('/v1/revisions'),
|
||||
countAll('/v1/peers'),
|
||||
countAll('/v1/speakers'),
|
||||
apiJSON<JobsResponse>('/v1/jobs?limit=100')
|
||||
]);
|
||||
modules = m.has_more ? 99 : (m.items?.length ?? 0);
|
||||
revisions = r.has_more ? 99 : (r.items?.length ?? 0);
|
||||
peers = p.has_more ? 99 : (p.items?.length ?? 0);
|
||||
speakers = s.has_more ? 99 : (s.items?.length ?? 0);
|
||||
modules = mCount;
|
||||
revisions = rCount;
|
||||
peers = pCount;
|
||||
speakers = sCount;
|
||||
runningJobs = (j.items ?? []).filter((i) => i.status === 'running' || i.status === 'queued').length;
|
||||
} catch {/* ignore */}
|
||||
loading = false;
|
||||
|
||||
Reference in new issue
Block a user