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