leaflet_svelte/src/lib/features/tracking/TelemetryPanel.svelte
2026-05-23 13:04:06 +09:00

100 lines
2.7 KiB
Svelte

<script lang="ts">
import { onDestroy } from 'svelte';
import { FormGroup, Label, Input, InputGroup, Button, Badge } from '@sveltestrap/sveltestrap';
import { CollapsibleCard } from '$ui';
import { t } from '$i18n';
import { telemetryStore } from './telemetryStore.svelte';
let satelliteInput = $state('');
const STATUS_COLOR: Record<string, string> = {
idle: 'secondary',
connecting: 'warning',
connected: 'success',
error: 'danger',
};
function handleConnect() {
const id = satelliteInput.trim();
if (id) telemetryStore.connect(id);
}
function handleDisconnect() {
telemetryStore.disconnect();
satelliteInput = '';
}
onDestroy(() => {
telemetryStore.disconnect();
});
</script>
<CollapsibleCard title={$t('nav.track')}>
<FormGroup spacing="mb-2">
<Label class="small">{$t('tracking.satelliteId')}</Label>
<div class="d-flex gap-1">
<Input
type="text"
size="sm"
bind:value={satelliteInput}
placeholder={$t('tracking.satelliteIdPlaceholder')}
disabled={telemetryStore.status !== 'idle'}
/>
{#if telemetryStore.status === 'idle'}
<Button
size="sm"
color="primary"
onclick={handleConnect}
disabled={!satelliteInput.trim()}
>
{$t('tracking.connect')}
</Button>
{:else}
<Button size="sm" color="secondary" onclick={handleDisconnect}>
{$t('tracking.disconnect')}
</Button>
{/if}
</div>
</FormGroup>
<FormGroup spacing="mb-2">
<div class="d-flex align-items-center gap-2">
<Label class="small mb-0">{$t('tracking.status')}</Label>
<Badge color={STATUS_COLOR[telemetryStore.status]}>
{$t(`tracking.status_${telemetryStore.status}`)}
</Badge>
</div>
{#if telemetryStore.error}
<small class="text-danger">{telemetryStore.error}</small>
{/if}
</FormGroup>
{#if telemetryStore.latest}
<FormGroup spacing="mb-2">
<Label class="small">{$t('points.lat')}</Label>
<InputGroup size="sm">
<Input type="text" value={telemetryStore.latest.latitude.toFixed(6)} readonly />
</InputGroup>
</FormGroup>
<FormGroup spacing="mb-2">
<Label class="small">{$t('points.lon')}</Label>
<InputGroup size="sm">
<Input type="text" value={telemetryStore.latest.longitude.toFixed(6)} readonly />
</InputGroup>
</FormGroup>
<FormGroup spacing="mb-2">
<Label class="small">{$t('points.alt')}</Label>
<InputGroup size="sm">
<Input type="text" value={telemetryStore.latest.altitude.toFixed(1)} readonly />
</InputGroup>
</FormGroup>
<small class="text-muted">
{$t('tracking.packetCount', { count: telemetryStore.points.length })}
</small>
{:else if telemetryStore.status !== 'idle'}
<small class="text-muted">{$t('tracking.waitingData')}</small>
{/if}
</CollapsibleCard>