diff --git a/backend/api/Controllers/Models/RobotResponse.cs b/backend/api/Controllers/Models/RobotResponse.cs index 2b055c967..50a4d2575 100644 --- a/backend/api/Controllers/Models/RobotResponse.cs +++ b/backend/api/Controllers/Models/RobotResponse.cs @@ -33,6 +33,8 @@ public class RobotResponse public RobotType Type { get; set; } + public float? AverageDurationPerTag { get; set; } + public IList? RobotCapabilities { get; set; } [JsonConstructor] @@ -58,6 +60,7 @@ public RobotResponse(Robot robot) IsarUri = robot.IsarUri; RobotCapabilities = robot.RobotCapabilities; Type = robot.Type; + AverageDurationPerTag = robot.AverageDurationPerTag; } } } diff --git a/frontend/src/components/Contexts/SignalRContext.tsx b/frontend/src/components/Contexts/SignalRContext.tsx index 3e432f750..98a16f3d6 100644 --- a/frontend/src/components/Contexts/SignalRContext.tsx +++ b/frontend/src/components/Contexts/SignalRContext.tsx @@ -77,7 +77,7 @@ export const SignalRProvider: FC = ({ children }) => { signalR.HttpTransportType.LongPolling, }) .withAutomaticReconnect() - .configureLogging(signalR.LogLevel.Error) + .configureLogging(signalR.LogLevel.Critical) .build() newConnection.onclose((error) => { @@ -113,15 +113,19 @@ export const SignalRProvider: FC = ({ children }) => { setConnectionReady(true) }) .catch((error) => { - console.error('SignalR connection failed:', error) - setConnectionReady(false) + if (error instanceof Error && error.constructor?.name === 'AbortError') { + // Aborting a connection is expected when the user navigates away or the react dev remounts. + setConnectionReady(false) + } else { + console.error('SignalR connection failed:', error) + setConnectionReady(false) + } }) return newConnection } useEffect(() => { if (!accounts[0] || inProgress !== 'none') return - const newConnection = resetConnection() return () => { diff --git a/frontend/src/pages/AssetSelectionPage.tsx b/frontend/src/pages/AssetSelectionPage.tsx index b1e548c54..61136d85d 100644 --- a/frontend/src/pages/AssetSelectionPage.tsx +++ b/frontend/src/pages/AssetSelectionPage.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react' -import { Autocomplete, Button, CircularProgress } from '@equinor/eds-core-react' +import { Autocomplete, Button, CircularProgress, Typography } from '@equinor/eds-core-react' import styled from 'styled-components' import { useLanguageContext } from 'components/Contexts/LanguageContext' import { Header } from 'components/Header/Header' @@ -51,28 +51,37 @@ const InstallationPicker = () => { const [selectedInstallation, setSelectedInstallation] = useState(undefined) const [installations, setInstallations] = useState(undefined) + const [isLoadingInstallations, setIsLoadingInstallations] = useState(true) useEffect(() => { backendApi .getInstallations() .then((installations) => { setInstallations(installations) + setIsLoadingInstallations(false) }) .catch(() => { console.error(`Failed to retrieve list of installations`) + setIsLoadingInstallations(false) }) - }, []) + }, [backendApi]) const handleClick = () => { navigate(selectedInstallation!.installationCode) } - if (installations === undefined) { + if (isLoadingInstallations) { return ( <> ) + } else if (!installations) { + return ( + <> + Not able to load installations. + + ) } return (