feat(webapp): add MinIO health check in settings
This commit is contained in:
@@ -76,6 +76,7 @@ export const api = {
|
|||||||
finalizeRecording: (id, payload) => request(`/recordings/${id}/finalize`, { method: 'POST', body: JSON.stringify(payload) })
|
finalizeRecording: (id, payload) => request(`/recordings/${id}/finalize`, { method: 'POST', body: JSON.stringify(payload) })
|
||||||
},
|
},
|
||||||
ops: {
|
ops: {
|
||||||
|
getReadiness: () => request('/ops/ready'),
|
||||||
listRecordings: () => request('/recordings/me/list'),
|
listRecordings: () => request('/recordings/me/list'),
|
||||||
getRecordingDownloadUrl: (recordingId) => request(`/recordings/${recordingId}/download-url`),
|
getRecordingDownloadUrl: (recordingId) => request(`/recordings/${recordingId}/download-url`),
|
||||||
listNotifications: () => request('/push-notifications/me')
|
listNotifications: () => request('/push-notifications/me')
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// @ts-nocheck
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
import { afterEach, describe, expect, it } from 'vitest';
|
import { afterEach, describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
import { api } from '$lib/app/api';
|
||||||
import AppChrome from '$lib/sim/ui/AppChrome.svelte';
|
import AppChrome from '$lib/sim/ui/AppChrome.svelte';
|
||||||
import { appController } from '$lib/app/controller';
|
import { appController } from '$lib/app/controller';
|
||||||
import { appState } from '$lib/app/store';
|
import { appState } from '$lib/app/store';
|
||||||
@@ -11,6 +12,46 @@
|
|||||||
const profileName = () => $appState.session?.user?.name || 'User';
|
const profileName = () => $appState.session?.user?.name || 'User';
|
||||||
const profileEmail = () => $appState.session?.user?.email || 'user@example.com';
|
const profileEmail = () => $appState.session?.user?.email || 'user@example.com';
|
||||||
const profileInitial = () => ($appState.session?.user?.name?.[0] || 'U').toUpperCase();
|
const profileInitial = () => ($appState.session?.user?.name?.[0] || 'U').toUpperCase();
|
||||||
|
|
||||||
|
let isCheckingMinio = false;
|
||||||
|
let minioStatus: 'idle' | 'ok' | 'error' = 'idle';
|
||||||
|
let minioStatusMessage = '';
|
||||||
|
let minioCheckedAt = '';
|
||||||
|
|
||||||
|
const checkMinioServer = async () => {
|
||||||
|
isCheckingMinio = true;
|
||||||
|
minioStatus = 'idle';
|
||||||
|
minioStatusMessage = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const readiness = await api.ops.getReadiness();
|
||||||
|
const minioCheck = readiness?.checks?.minio;
|
||||||
|
minioStatus = minioCheck === 'ok' ? 'ok' : 'error';
|
||||||
|
minioStatusMessage =
|
||||||
|
minioCheck === 'ok'
|
||||||
|
? 'MinIO is reachable and the configured bucket responded successfully.'
|
||||||
|
: `MinIO readiness check returned: ${String(minioCheck ?? 'unknown')}`;
|
||||||
|
minioCheckedAt = readiness?.timestamp ?? new Date().toISOString();
|
||||||
|
} catch (error) {
|
||||||
|
minioStatus = 'error';
|
||||||
|
minioStatusMessage = error instanceof Error ? error.message : 'MinIO check failed';
|
||||||
|
minioCheckedAt = new Date().toISOString();
|
||||||
|
} finally {
|
||||||
|
isCheckingMinio = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatCheckedAt = (value) => {
|
||||||
|
if (!value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new Date(value).toLocaleString();
|
||||||
|
} catch {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AppChrome pageKey="settings">
|
<AppChrome pageKey="settings">
|
||||||
@@ -58,6 +99,46 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</Button>
|
</Button>
|
||||||
<Separator class="bg-white/5" />
|
<Separator class="bg-white/5" />
|
||||||
|
<div class="px-5 py-5">
|
||||||
|
<div class="flex flex-col gap-4 rounded-2xl border border-white/8 bg-white/[0.03] p-4">
|
||||||
|
<div class="flex items-start justify-between gap-4">
|
||||||
|
<div class="space-y-1">
|
||||||
|
<h4 class="text-sm font-semibold tracking-wide text-white">MinIO Storage Check</h4>
|
||||||
|
<p class="text-sm text-gray-400">
|
||||||
|
Test whether the backend can still reach the object storage server.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
id="checkMinioBtn"
|
||||||
|
size="sm"
|
||||||
|
class="shrink-0 rounded-xl"
|
||||||
|
disabled={isCheckingMinio}
|
||||||
|
onclick={checkMinioServer}
|
||||||
|
>
|
||||||
|
{isCheckingMinio ? 'Checking…' : 'Check MinIO Server'}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if minioStatus !== 'idle'}
|
||||||
|
<div
|
||||||
|
class={`rounded-xl border px-3 py-3 text-sm ${
|
||||||
|
minioStatus === 'ok'
|
||||||
|
? 'border-emerald-500/30 bg-emerald-500/10 text-emerald-300'
|
||||||
|
: 'border-red-500/30 bg-red-500/10 text-red-300'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<p class="font-medium">
|
||||||
|
{minioStatus === 'ok' ? 'MinIO is up' : 'MinIO check failed'}
|
||||||
|
</p>
|
||||||
|
<p class="mt-1 opacity-90">{minioStatusMessage}</p>
|
||||||
|
{#if minioCheckedAt}
|
||||||
|
<p class="mt-2 text-xs opacity-75">Last checked: {formatCheckedAt(minioCheckedAt)}</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Separator class="bg-white/5" />
|
||||||
<Button variant="ghost" class="group h-auto w-full justify-between rounded-none px-5 py-5 text-left text-gray-300 hover:bg-white/5">
|
<Button variant="ghost" class="group h-auto w-full justify-between rounded-none px-5 py-5 text-left text-gray-300 hover:bg-white/5">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<div class="p-2 rounded-lg bg-white/5 group-hover:bg-blue-500/20 group-hover:text-blue-400 transition-colors">
|
<div class="p-2 rounded-lg bg-white/5 group-hover:bg-blue-500/20 group-hover:text-blue-400 transition-colors">
|
||||||
|
|||||||
Reference in New Issue
Block a user