Publish Message
diff --git a/src/components/EmptyState.test.tsx b/src/components/EmptyState.test.tsx
index 3921b5e..74794f5 100644
--- a/src/components/EmptyState.test.tsx
+++ b/src/components/EmptyState.test.tsx
@@ -12,7 +12,7 @@ describe('EmptyState', () => {
render(
);
expect(screen.getByText('No Server Connected')).toBeInTheDocument();
- expect(screen.getByText('Connect to a SOVD server to browse entities.')).toBeInTheDocument();
+ expect(screen.getByText('Connect to a ros2_medkit gateway to browse entities.')).toBeInTheDocument();
});
it('renders no-entities state', () => {
diff --git a/src/components/EmptyState.tsx b/src/components/EmptyState.tsx
index b5dbd86..038bee7 100644
--- a/src/components/EmptyState.tsx
+++ b/src/components/EmptyState.tsx
@@ -11,7 +11,7 @@ export function EmptyState({ type, onAction }: EmptyStateProps) {
'no-connection': {
icon: Server,
title: 'No Server Connected',
- description: 'Connect to a SOVD server to browse entities.',
+ description: 'Connect to a ros2_medkit gateway to browse entities.',
actionLabel: 'Connect to Server',
},
'no-entities': {
diff --git a/src/components/EntityDetailPanel.tsx b/src/components/EntityDetailPanel.tsx
index 49fd200..cf6488c 100644
--- a/src/components/EntityDetailPanel.tsx
+++ b/src/components/EntityDetailPanel.tsx
@@ -33,8 +33,7 @@ import { FunctionsPanel } from '@/components/FunctionsPanel';
import { ServerInfoPanel } from '@/components/ServerInfoPanel';
import { FaultsDashboard } from '@/components/FaultsDashboard';
import { useAppStore, type AppState } from '@/lib/store';
-import type { ComponentTopic, Parameter } from '@/lib/types';
-import type { SovdResourceEntityType } from '@/lib/sovd-api';
+import type { ComponentTopic, Parameter, SovdResourceEntityType } from '@/lib/types';
type ComponentTab = 'data' | 'operations' | 'configurations' | 'faults';
@@ -367,9 +366,10 @@ export function EntityDetailPanel({ onConnectClick, viewMode = 'entity', onEntit
isLoadingDetails,
isRefreshing,
isConnected,
- client,
selectEntity,
refreshSelectedEntity,
+ prefetchResourceCounts,
+ fetchEntityData,
} = useAppStore(
useShallow((state: AppState) => ({
selectedPath: state.selectedPath,
@@ -377,9 +377,10 @@ export function EntityDetailPanel({ onConnectClick, viewMode = 'entity', onEntit
isLoadingDetails: state.isLoadingDetails,
isRefreshing: state.isRefreshing,
isConnected: state.isConnected,
- client: state.client,
selectEntity: state.selectEntity,
refreshSelectedEntity: state.refreshSelectedEntity,
+ prefetchResourceCounts: state.prefetchResourceCounts,
+ fetchEntityData: state.fetchEntityData,
}))
);
@@ -392,8 +393,8 @@ export function EntityDetailPanel({ onConnectClick, viewMode = 'entity', onEntit
// Fetch resource counts when entity changes
useEffect(() => {
- const fetchResourceCounts = async () => {
- if (!client || !selectedEntity) {
+ const doFetchResourceCounts = async () => {
+ if (!selectedEntity) {
setResourceCounts({ data: 0, operations: 0, configurations: 0, faults: 0 });
setTopicsData([]);
return;
@@ -419,30 +420,25 @@ export function EntityDetailPanel({ onConnectClick, viewMode = 'entity', onEntit
else if (isFunction) entityType = 'functions';
try {
- const [dataRes, opsRes, configRes, faultsRes] = await Promise.all([
- client.getEntityData(entityType, entityId).catch(() => []),
- client.listOperations(entityId, entityType).catch(() => []),
- client.listConfigurations(entityId, entityType).catch(() => ({ parameters: [] })),
- client.listEntityFaults(entityType, entityId).catch(() => ({ items: [] })),
+ // Fetch resource counts and data in parallel
+ const [counts, dataRes] = await Promise.all([
+ prefetchResourceCounts(entityType, entityId),
+ fetchEntityData(entityType, entityId).catch(() => [] as ComponentTopic[]),
]);
// Store the fetched data for the Data tab
const fetchedData = Array.isArray(dataRes) ? dataRes : [];
setTopicsData(fetchedData);
- setResourceCounts({
- data: fetchedData.length,
- operations: Array.isArray(opsRes) ? opsRes.length : 0,
- configurations: configRes.parameters?.length || 0,
- faults: faultsRes.items?.length || 0,
- });
+ // Use the already-fetched data length instead of a separate request
+ setResourceCounts({ ...counts, data: fetchedData.length });
} catch {
// Silently handle errors - counts will stay at 0
}
};
- fetchResourceCounts();
- }, [client, selectedEntity]);
+ doFetchResourceCounts();
+ }, [selectedEntity, prefetchResourceCounts, fetchEntityData]);
const handleCopyEntity = async () => {
if (selectedEntity) {
@@ -785,7 +781,6 @@ export function EntityDetailPanel({ onConnectClick, viewMode = 'entity', onEntit
topic={topic}
entityId={entityId}
entityType={entityType}
- client={client}
isRefreshing={isRefreshing}
onRefresh={refreshSelectedEntity}
/>
diff --git a/src/components/EntityResourceTabs.tsx b/src/components/EntityResourceTabs.tsx
index 7331243..1700391 100644
--- a/src/components/EntityResourceTabs.tsx
+++ b/src/components/EntityResourceTabs.tsx
@@ -1,4 +1,4 @@
-import { useState, useEffect, useCallback } from 'react';
+import { useState, useEffect, useCallback, useRef } from 'react';
import { useShallow } from 'zustand/shallow';
import { Database, Zap, Settings, AlertTriangle, Loader2, MessageSquare } from 'lucide-react';
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card';
@@ -7,8 +7,8 @@ import { useAppStore } from '@/lib/store';
import { ConfigurationPanel } from '@/components/ConfigurationPanel';
import { OperationsPanel } from '@/components/OperationsPanel';
import { FaultsPanel } from '@/components/FaultsPanel';
-import type { SovdResourceEntityType } from '@/lib/sovd-api';
-import type { ComponentTopic, Operation, Parameter, Fault } from '@/lib/types';
+import type { SovdResourceEntityType } from '@/lib/types';
+import type { ComponentTopic, Operation, Fault } from '@/lib/types';
type ResourceTab = 'data' | 'operations' | 'configurations' | 'faults';
@@ -56,49 +56,58 @@ export function EntityResourceTabs({ entityId, entityType, basePath, onNavigate
configurations: false,
faults: false,
});
+ const loadedTabsRef = useRef(loadedTabs);
+ loadedTabsRef.current = loadedTabs;
const [data, setData] = useState
([]);
const [operations, setOperations] = useState([]);
- const [configurations, setConfigurations] = useState([]);
const [faults, setFaults] = useState([]);
- const { client, selectEntity } = useAppStore(
+ const {
+ selectEntity,
+ fetchEntityData,
+ fetchEntityOperations,
+ fetchConfigurations,
+ listEntityFaults,
+ storeConfigurations,
+ } = useAppStore(
useShallow((state) => ({
- client: state.client,
selectEntity: state.selectEntity,
+ fetchEntityData: state.fetchEntityData,
+ fetchEntityOperations: state.fetchEntityOperations,
+ fetchConfigurations: state.fetchConfigurations,
+ listEntityFaults: state.listEntityFaults,
+ storeConfigurations: state.configurations,
}))
);
// Lazy load resources for the active tab
const loadTabResources = useCallback(
async (tab: ResourceTab) => {
- if (!client || loadedTabs[tab]) return;
+ if (loadedTabsRef.current[tab]) return;
setIsLoading(true);
try {
switch (tab) {
case 'data': {
- const dataRes = await client
- .getEntityData(entityType, entityId)
- .catch(() => [] as ComponentTopic[]);
+ const dataRes = await fetchEntityData(entityType, entityId).catch(() => [] as ComponentTopic[]);
setData(dataRes);
break;
}
case 'operations': {
- const opsRes = await client.listOperations(entityId, entityType).catch(() => [] as Operation[]);
+ const opsRes = await fetchEntityOperations(entityType, entityId).catch(() => [] as Operation[]);
setOperations(opsRes);
break;
}
case 'configurations': {
- const configRes = await client
- .listConfigurations(entityId, entityType)
- .catch(() => ({ parameters: [] }));
- setConfigurations(configRes.parameters || []);
+ await fetchConfigurations(entityId, entityType);
+ // Configurations are stored in the store's configurations map
break;
}
case 'faults': {
- const faultsRes = await client
- .listEntityFaults(entityType, entityId)
- .catch(() => ({ items: [] }));
+ const faultsRes = await listEntityFaults(entityType, entityId).catch(() => ({
+ items: [] as Fault[],
+ count: 0,
+ }));
setFaults(faultsRes.items || []);
break;
}
@@ -110,7 +119,8 @@ export function EntityResourceTabs({ entityId, entityType, basePath, onNavigate
setIsLoading(false);
}
},
- [client, entityId, entityType, loadedTabs]
+
+ [fetchEntityData, fetchEntityOperations, fetchConfigurations, listEntityFaults, entityId, entityType]
);
// Load resources when tab changes
@@ -136,7 +146,7 @@ export function EntityResourceTabs({ entityId, entityType, basePath, onNavigate
let count = 0;
if (tab.id === 'data') count = data.length;
if (tab.id === 'operations') count = operations.length;
- if (tab.id === 'configurations') count = configurations.length;
+ if (tab.id === 'configurations') count = storeConfigurations.get(entityId)?.length || 0;
if (tab.id === 'faults') count = faults.length;
return (
diff --git a/src/components/FaultsDashboard.tsx b/src/components/FaultsDashboard.tsx
index 5cab03b..45b5d15 100644
--- a/src/components/FaultsDashboard.tsx
+++ b/src/components/FaultsDashboard.tsx
@@ -30,7 +30,7 @@ import { Skeleton } from '@/components/ui/skeleton';
import { SnapshotCard } from './SnapshotCard';
import { useAppStore } from '@/lib/store';
import type { Fault, FaultSeverity, FaultStatus, FaultResponse } from '@/lib/types';
-import { mapFaultEntityTypeToResourceType } from '@/lib/sovd-api';
+import { mapFaultEntityTypeToResourceType } from '@/lib/utils';
/**
* Default polling interval in milliseconds
@@ -254,7 +254,7 @@ function FaultRow({
{environmentData.snapshots.map((snapshot, idx) => (
@@ -409,14 +409,22 @@ export function FaultsDashboard() {
const [groupByEntity, setGroupByEntity] = useState(true);
// Use shared faults state from store
- const { faults, isLoadingFaults, isConnected, fetchFaults, clearFault, client, hasFaultStream } = useAppStore(
+ const {
+ faults,
+ isLoadingFaults,
+ isConnected,
+ fetchFaults,
+ clearFault,
+ getFaultWithEnvironmentData,
+ hasFaultStream,
+ } = useAppStore(
useShallow((state) => ({
faults: state.faults,
isLoadingFaults: state.isLoadingFaults,
isConnected: state.isConnected,
fetchFaults: state.fetchFaults,
clearFault: state.clearFault,
- client: state.client,
+ getFaultWithEnvironmentData: state.getFaultWithEnvironmentData,
hasFaultStream: state.faultStreamCleanup !== null,
}))
);
@@ -486,16 +494,12 @@ export function FaultsDashboard() {
newExpanded.add(faultCode);
// Fetch details if not cached
- if (!faultDetails.has(faultCode) && client) {
+ if (!faultDetails.has(faultCode)) {
setLoadingDetails((prev) => new Set([...prev, faultCode]));
try {
const entityGroup = mapFaultEntityTypeToResourceType(fault.entity_type);
- const details = await client.getFaultWithEnvironmentData(
- entityGroup,
- fault.entity_id,
- faultCode
- );
- setFaultDetails((prev) => new Map(prev).set(faultCode, details));
+ const details = await getFaultWithEnvironmentData(entityGroup, fault.entity_id, faultCode);
+ setFaultDetails((prev) => new Map(prev).set(faultCode, details as FaultResponse));
} catch (err) {
console.error('Failed to fetch fault details:', err);
} finally {
@@ -510,7 +514,7 @@ export function FaultsDashboard() {
setExpandedFaults(newExpanded);
},
- [client, expandedFaults, faultDetails]
+ [getFaultWithEnvironmentData, expandedFaults, faultDetails]
);
// Filter faults
diff --git a/src/components/FaultsPanel.tsx b/src/components/FaultsPanel.tsx
index ae6196d..85aa1ae 100644
--- a/src/components/FaultsPanel.tsx
+++ b/src/components/FaultsPanel.tsx
@@ -18,9 +18,8 @@ import { Badge } from '@/components/ui/badge';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { SnapshotCard } from './SnapshotCard';
import { useAppStore, type AppState } from '@/lib/store';
-import type { Fault, FaultSeverity, FaultStatus, FaultResponse } from '@/lib/types';
-import { mapFaultEntityTypeToResourceType } from '@/lib/sovd-api';
-import type { SovdResourceEntityType } from '@/lib/sovd-api';
+import type { Fault, FaultSeverity, FaultStatus, FaultResponse, SovdResourceEntityType } from '@/lib/types';
+import { mapFaultEntityTypeToResourceType } from '@/lib/utils';
interface FaultsPanelProps {
entityId: string;
@@ -235,7 +234,7 @@ function FaultRow({
{environmentData.snapshots.map((snapshot, idx) => (
@@ -274,20 +273,20 @@ export function FaultsPanel({ entityId, entityType = 'components' }: FaultsPanel
const [faultDetails, setFaultDetails] = useState
>(new Map());
const [loadingDetails, setLoadingDetails] = useState>(new Set());
- const { client } = useAppStore(
+ const { listEntityFaults, getFaultWithEnvironmentData, clearFault } = useAppStore(
useShallow((state: AppState) => ({
- client: state.client,
+ listEntityFaults: state.listEntityFaults,
+ getFaultWithEnvironmentData: state.getFaultWithEnvironmentData,
+ clearFault: state.clearFault,
}))
);
const loadFaults = useCallback(async () => {
- if (!client) return;
-
setIsLoading(true);
setError(null);
try {
- const response = await client.listEntityFaults(entityType, entityId);
+ const response = await listEntityFaults(entityType, entityId);
setFaults(response.items || []);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to load faults');
@@ -295,7 +294,7 @@ export function FaultsPanel({ entityId, entityType = 'components' }: FaultsPanel
} finally {
setIsLoading(false);
}
- }, [client, entityId, entityType]);
+ }, [listEntityFaults, entityId, entityType]);
useEffect(() => {
loadFaults();
@@ -311,7 +310,7 @@ export function FaultsPanel({ entityId, entityType = 'components' }: FaultsPanel
newExpanded.add(faultCode);
// Fetch details if not cached
- if (!faultDetails.has(faultCode) && client) {
+ if (!faultDetails.has(faultCode)) {
setLoadingDetails((prev) => new Set([...prev, faultCode]));
try {
// Use the fault's own entity info (app-level) for correct bulk_data_uri.
@@ -322,12 +321,8 @@ export function FaultsPanel({ entityId, entityType = 'components' }: FaultsPanel
? mapFaultEntityTypeToResourceType(fault.entity_type)
: entityType;
const detailEntityId = fault?.entity_id || entityId;
- const details = await client.getFaultWithEnvironmentData(
- detailEntityType,
- detailEntityId,
- faultCode
- );
- setFaultDetails((prev) => new Map(prev).set(faultCode, details));
+ const details = await getFaultWithEnvironmentData(detailEntityType, detailEntityId, faultCode);
+ setFaultDetails((prev) => new Map(prev).set(faultCode, details as FaultResponse));
} catch (err) {
console.error('Failed to fetch fault details:', err);
} finally {
@@ -342,17 +337,15 @@ export function FaultsPanel({ entityId, entityType = 'components' }: FaultsPanel
setExpandedFaults(newExpanded);
},
- [client, entityType, entityId, expandedFaults, faultDetails, faults]
+ [getFaultWithEnvironmentData, entityType, entityId, expandedFaults, faultDetails, faults]
);
const handleClear = useCallback(
async (code: string) => {
- if (!client) return;
-
setClearingCodes((prev) => new Set([...prev, code]));
try {
- await client.clearFault(entityType, entityId, code);
+ await clearFault(entityType, entityId, code);
// Reload faults after clearing
await loadFaults();
} catch {
@@ -365,7 +358,7 @@ export function FaultsPanel({ entityId, entityType = 'components' }: FaultsPanel
});
}
},
- [client, entityId, entityType, loadFaults]
+ [clearFault, entityId, entityType, loadFaults]
);
// Count faults by severity
diff --git a/src/components/FunctionsPanel.tsx b/src/components/FunctionsPanel.tsx
index 431808f..dd21fc3 100644
--- a/src/components/FunctionsPanel.tsx
+++ b/src/components/FunctionsPanel.tsx
@@ -18,7 +18,7 @@ import { useAppStore } from '@/lib/store';
import { ConfigurationPanel } from '@/components/ConfigurationPanel';
import { OperationsPanel } from '@/components/OperationsPanel';
import { FaultsPanel } from '@/components/FaultsPanel';
-import type { ComponentTopic, Operation, Parameter, Fault } from '@/lib/types';
+import type { ComponentTopic, Operation, Fault } from '@/lib/types';
/** Host app object returned from /functions/{id}/hosts */
interface FunctionHost {
@@ -65,37 +65,42 @@ export function FunctionsPanel({ functionId, functionName, description, path, on
const [hosts, setHosts] = useState([]);
const [topics, setTopics] = useState([]);
const [operations, setOperations] = useState([]);
- const [configurations, setConfigurations] = useState([]);
const [faults, setFaults] = useState([]);
const [isLoading, setIsLoading] = useState(false);
- const { client, selectEntity } = useAppStore(
+ const {
+ selectEntity,
+ getFunctionHosts,
+ fetchEntityData,
+ fetchEntityOperations,
+ fetchConfigurations,
+ listEntityFaults,
+ storeConfigurations,
+ } = useAppStore(
useShallow((state) => ({
- client: state.client,
selectEntity: state.selectEntity,
+ getFunctionHosts: state.getFunctionHosts,
+ fetchEntityData: state.fetchEntityData,
+ fetchEntityOperations: state.fetchEntityOperations,
+ fetchConfigurations: state.fetchConfigurations,
+ listEntityFaults: state.listEntityFaults,
+ storeConfigurations: state.configurations,
}))
);
// Load function resources on mount
useEffect(() => {
const loadFunctionData = async () => {
- if (!client) return;
setIsLoading(true);
try {
// Load hosts, data, operations, configurations, and faults in parallel
- const [hostsData, topicsData, opsData, configData, faultsData] = await Promise.all([
- client.getFunctionHosts
- ? client.getFunctionHosts(functionId).catch(() => [] as FunctionHost[])
- : Promise.resolve([]),
- client.getFunctionData
- ? client.getFunctionData(functionId).catch(() => [] as ComponentTopic[])
- : Promise.resolve([]),
- client.getFunctionOperations
- ? client.getFunctionOperations(functionId).catch(() => [] as Operation[])
- : Promise.resolve([]),
- client.listConfigurations(functionId, 'functions').catch(() => ({ parameters: [] })),
- client.listEntityFaults('functions', functionId).catch(() => ({ items: [] })),
+ const [hostsData, topicsData, opsData, , faultsData] = await Promise.all([
+ getFunctionHosts(functionId).catch(() => [] as unknown[]),
+ fetchEntityData('functions', functionId).catch(() => [] as ComponentTopic[]),
+ fetchEntityOperations('functions', functionId).catch(() => [] as Operation[]),
+ fetchConfigurations(functionId, 'functions'),
+ listEntityFaults('functions', functionId).catch(() => ({ items: [] as Fault[], count: 0 })),
]);
// Normalize hosts - API returns objects with {id, name, href}
@@ -110,7 +115,6 @@ export function FunctionsPanel({ functionId, functionName, description, path, on
setHosts(normalizedHosts);
setTopics(topicsData);
setOperations(opsData);
- setConfigurations(configData.parameters || []);
setFaults(faultsData.items || []);
} catch (error) {
console.error('Failed to load function data:', error);
@@ -120,7 +124,7 @@ export function FunctionsPanel({ functionId, functionName, description, path, on
};
loadFunctionData();
- }, [client, functionId]);
+ }, [getFunctionHosts, fetchEntityData, fetchEntityOperations, fetchConfigurations, listEntityFaults, functionId]);
const handleResourceClick = (resourcePath: string) => {
if (onNavigate) {
@@ -162,7 +166,7 @@ export function FunctionsPanel({ functionId, functionName, description, path, on
if (tab.id === 'hosts') count = hosts.length;
if (tab.id === 'data') count = topics.length;
if (tab.id === 'operations') count = operations.length;
- if (tab.id === 'configurations') count = configurations.length;
+ if (tab.id === 'configurations') count = storeConfigurations.get(functionId)?.length || 0;
if (tab.id === 'faults') count = faults.length;
return (
@@ -240,7 +244,9 @@ export function FunctionsPanel({ functionId, functionName, description, path, on
className="p-3 rounded-lg border hover:bg-accent/50 transition-colors text-left"
>
- {configurations.length}
+
+ {storeConfigurations.get(functionId)?.length || 0}
+
Configs
({
useAppStore: vi.fn((selector) =>
selector({
- client: {
- downloadBulkData: mockDownloadBulkData,
- },
+ downloadBulkData: mockDownloadBulkData,
})
),
}));
diff --git a/src/components/RosbagDownloadButton.tsx b/src/components/RosbagDownloadButton.tsx
index 7c7230a..7fded98 100644
--- a/src/components/RosbagDownloadButton.tsx
+++ b/src/components/RosbagDownloadButton.tsx
@@ -4,8 +4,8 @@ import { useShallow } from 'zustand/shallow';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useAppStore } from '@/lib/store';
-import { formatBytes, formatDuration } from '@/lib/sovd-api';
-import type { SovdResourceEntityType } from '@/lib/sovd-api';
+import { formatBytes, formatDuration } from '@/lib/utils';
+import type { SovdResourceEntityType } from '@/lib/types';
import type { RosbagSnapshot } from '@/lib/types';
interface RosbagDownloadButtonProps {
@@ -39,14 +39,14 @@ export function RosbagDownloadButton({ snapshot, variant = 'outline', size = 'sm
const [isDownloading, setIsDownloading] = useState(false);
const [error, setError] = useState(null);
- const { client } = useAppStore(
+ const { downloadBulkData } = useAppStore(
useShallow((state) => ({
- client: state.client,
+ downloadBulkData: state.downloadBulkData,
}))
);
const handleDownload = useCallback(async () => {
- if (!client || !snapshot.bulk_data_uri) return;
+ if (!snapshot.bulk_data_uri) return;
setIsDownloading(true);
setError(null);
@@ -57,18 +57,17 @@ export function RosbagDownloadButton({ snapshot, variant = 'outline', size = 'sm
throw new Error('Invalid bulk_data_uri format');
}
- const { blob, filename } = await client.downloadBulkData(
- parsed.entityType,
- parsed.entityId,
- parsed.category,
- parsed.id
- );
+ const result = await downloadBulkData(parsed.entityType, parsed.entityId, parsed.category, parsed.id);
+
+ if (!result) {
+ throw new Error('Download failed');
+ }
// Create object URL and trigger download
- const url = URL.createObjectURL(blob);
+ const url = URL.createObjectURL(result.blob);
const link = document.createElement('a');
link.href = url;
- link.download = filename;
+ link.download = result.filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
@@ -78,7 +77,7 @@ export function RosbagDownloadButton({ snapshot, variant = 'outline', size = 'sm
} finally {
setIsDownloading(false);
}
- }, [client, snapshot]);
+ }, [downloadBulkData, snapshot]);
if (!snapshot.bulk_data_uri) {
return null;
diff --git a/src/components/ServerConnectionDialog.tsx b/src/components/ServerConnectionDialog.tsx
index ca85021..3eec2bb 100644
--- a/src/components/ServerConnectionDialog.tsx
+++ b/src/components/ServerConnectionDialog.tsx
@@ -18,23 +18,20 @@ interface ServerConnectionDialogProps {
}
export function ServerConnectionDialog({ open, onOpenChange }: ServerConnectionDialogProps) {
- const { serverUrl, baseEndpoint, isConnecting, connectionError, connect } = useAppStore();
+ const { serverUrl, isConnecting, connectionError, connect } = useAppStore();
const [url, setUrl] = useState(serverUrl || 'localhost:8080');
- const [endpoint, setEndpoint] = useState(baseEndpoint || 'api/v1');
- // Update local state when serverUrl/baseEndpoint changes (e.g., from localStorage)
- // Only update if the dialog is just opened or if the store values change externally
+ // Update local state when serverUrl changes (e.g., from localStorage)
useEffect(() => {
if (open) {
setUrl(serverUrl || '');
- setEndpoint(baseEndpoint || '');
}
- }, [open, serverUrl, baseEndpoint]);
+ }, [open, serverUrl]);
const handleConnect = async () => {
if (!url.trim()) return;
- const success = await connect(url.trim(), endpoint.trim());
+ const success = await connect(url.trim());
if (success) {
onOpenChange(false);
}
@@ -55,8 +52,8 @@ export function ServerConnectionDialog({ open, onOpenChange }: ServerConnectionD
- Connect to SOVD Server
- Enter the URL and base endpoint of your SOVD server
+ Connect to ros2_medkit Gateway
+ Enter the URL of your ros2_medkit gateway
@@ -68,7 +65,7 @@ export function ServerConnectionDialog({ open, onOpenChange }: ServerConnectionD
setUrl(e.target.value)}
onKeyDown={handleKeyDown}
@@ -76,24 +73,7 @@ export function ServerConnectionDialog({ open, onOpenChange }: ServerConnectionD
aria-invalid={!!connectionError}
/>
- You can enter just IP:port or a full URL with protocol
-
-
-
-