Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e27040e
Updated the data returned by 'checkMultigridControllerStatus', and up…
tieneupin Jul 21, 2025
db1493f
Updated the 'SessionRow' component
tieneupin Jul 21, 2025
8d36f73
Updated 'sessionClients' loader
tieneupin Jul 22, 2025
24279ea
Removed a leftover debug log from the 'sessionRow' component
tieneupin Jul 22, 2025
ef1309b
Updated index.tsx to reflect new sessions loader name
tieneupin Jul 22, 2025
b29c667
Simplified the 'Navbar' component by adding the navigation logic toth…
tieneupin Jul 22, 2025
033fd11
Fixed instrument server connectivity indicator so that the Tooltip me…
tieneupin Jul 22, 2025
18b7d97
Updated the 'Home' route
tieneupin Jul 22, 2025
86b8a8a
Removed the URL query parameter insertion logic when navigating to ho…
tieneupin Jul 22, 2025
82f1ab6
Migrated 'queryBuilder' function into the loader it's contributing to
tieneupin Jul 22, 2025
581686b
Migrated WebSocket conection logic to a standalone component which is…
tieneupin Jul 22, 2025
0a0dc94
Converted 'SessionRow' into a proper React component instead of a fun…
tieneupin Jul 22, 2025
006f4ff
* Refactored 'Home' route to render content with 'useQuery' instead o…
tieneupin Jul 22, 2025
8080f4b
Further improvements to 'SessionRow' component
tieneupin Jul 22, 2025
fb7da7f
Added 'queryClient.invalidateQueries' to 'allSessionsLoader' to ensur…
tieneupin Jul 23, 2025
92238f6
Updated 'rsyncerLoader' so that it returns fresh RSyncer info each ti…
tieneupin Jul 23, 2025
c93ef42
Updated the 'handleReconnect' function so that it correctly sets the …
tieneupin Jul 23, 2025
f90c389
Replaced the transferring status indicator in the 'SessionRow' compon…
tieneupin Jul 24, 2025
c13795e
Standardised how loaders are defined in 'index.tsx' and streamlined l…
tieneupin Jul 24, 2025
79b7a74
Added logic to the instrument server connectivity checker function to…
tieneupin Jul 24, 2025
6fda141
Removed need for passing in RSyncer finalisation and removal logic fr…
tieneupin Jul 24, 2025
d396247
Added logic to the 'SessionRow' component to update itself when a los…
tieneupin Jul 24, 2025
57a3b1a
Added logs to the web socket handler, and use query refetch to update…
tieneupin Jul 24, 2025
b44a9a4
Tidied up messages in 'GridSquares'
tieneupin Jul 24, 2025
08cee5b
Use loader data for 'Home' route to provide initial data for its query
tieneupin Jul 24, 2025
3e3ccde
Load session parameters for a given session via query instead
tieneupin Jul 24, 2025
f7b2df5
Updated data fetching logic in 'Session' page
tieneupin Jul 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 56 additions & 44 deletions src/components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import {
Box,
Flex,
HStack,
Link,
IconButton,
useDisclosure,
Image,
Tooltip,
BoxProps,
Icon,
} from '@chakra-ui/react'
import { useQueryClient } from '@tanstack/react-query'
import { getInstrumentConnectionStatus } from 'loaders/general'
import React from 'react'
import {
Expand All @@ -19,7 +19,7 @@ import {
MdOutlineSignalWifiBad,
} from 'react-icons/md'
import { TbMicroscope, TbSnowflake, TbHomeCog } from 'react-icons/tb'
import { Link as LinkRouter } from 'react-router-dom'
import { useNavigate } from 'react-router-dom'

export interface LinkDescriptor {
label: string
Expand All @@ -43,27 +43,35 @@ export const Navbar = ({
logo,
...props
}: NavbarProps) => {
const { isOpen, onOpen, onClose } = useDisclosure()
const [instrumentConnectionStatus, setInsrumentConnectionStatus] =
React.useState(false)
const navigate = useNavigate()
const { isOpen, onOpen, onClose } = useDisclosure()
const queryClient = useQueryClient()
const instrumentName = sessionStorage.getItem('instrumentName')

// Check connectivity every few seconds
React.useEffect(() => {
const resolveConnectionStatus = async () => {
try {
const status: boolean = await getInstrumentConnectionStatus()
setInsrumentConnectionStatus(status)
if (status !== instrumentConnectionStatus) {
setInsrumentConnectionStatus(status)
queryClient.refetchQueries({
queryKey: ['instrumentServerConnection', instrumentName],
})
}
} catch (err) {
console.error('Error checking connection status:', err)
setInsrumentConnectionStatus(false)
}
}
resolveConnectionStatus() // Fetch data once to start with

// Set it to run every 4s
// Set it to run every 10s
const interval = setInterval(resolveConnectionStatus, 10000)
return () => clearInterval(interval)
}, [])
}, [instrumentName, instrumentConnectionStatus, queryClient])

return (
<Box position="sticky" top="0" zIndex={1} w="100%" {...props}>
Expand Down Expand Up @@ -95,51 +103,55 @@ export const Navbar = ({
/>
</Box>
) : null}
<Link as={LinkRouter} to="/hub">
<Tooltip label="Back to the Hub">
<IconButton
size={'sm'}
icon={
<>
<TbHomeCog />
</>
}
aria-label={'Back to the Hub'}
_hover={{ background: 'transparent', color: 'murfey.500' }}
/>
</Tooltip>
</Link>
<Link as={LinkRouter} to="/home">
<Tooltip label="Back to the microscope">
<IconButton
size={'sm'}
icon={
<>
<TbSnowflake />
<TbMicroscope />
</>
}
aria-label={'Back to the microscope'}
_hover={{ background: 'transparent', color: 'murfey.500' }}
/>
</Tooltip>
</Link>
<Tooltip label="Back to the Hub">
<IconButton
onClick={() => {
navigate(`/hub`)
}}
size={'sm'}
icon={
<>
<TbHomeCog />
</>
}
aria-label={'Back to the Hub'}
_hover={{ background: 'transparent', color: 'murfey.500' }}
/>
</Tooltip>
{/* Add the instrument name as a URL query parameter to trigger a reload */}
<Tooltip label="Back to the microscope">
<IconButton
onClick={() => {
navigate(`/home`)
}}
size={'sm'}
icon={
<>
<TbSnowflake />
<TbMicroscope />
</>
}
aria-label="Back to the microscope"
_hover={{ background: 'transparent', color: 'murfey.500' }}
/>
</Tooltip>
<Tooltip
label={
instrumentConnectionStatus
? 'Connected to instrument server'
: 'No instrument server connection'
}
placement="bottom"
>
<Icon
as={
instrumentConnectionStatus
? MdSignalWifi4Bar
: MdOutlineSignalWifiBad
}
color={instrumentConnectionStatus ? 'white' : 'red'}
/>
<span tabIndex={0}>
<Icon
as={
instrumentConnectionStatus
? MdSignalWifi4Bar
: MdOutlineSignalWifiBad
}
color={instrumentConnectionStatus ? 'white' : 'red'}
/>
</span>
</Tooltip>
</HStack>
</Flex>
Expand Down
6 changes: 3 additions & 3 deletions src/components/protectedRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Box } from '@chakra-ui/react'
import { Navbar } from 'components/navbar'
import { WebSocketHandler } from 'components/webSocketHandler'
import { Navigate, Outlet } from 'react-router-dom'

const ProtectedRoutes = () => {
export const ProtectedRoutes = () => {
// Read environment variable and demand user login if authenticating with 'password'
const sessionToken = sessionStorage.getItem('token')
const standard = (
<div className="rootContainer">
<WebSocketHandler />
<Box>
<Navbar logo="/images/diamondgs.png" />
</Box>
Expand All @@ -23,5 +25,3 @@ const ProtectedRoutes = () => {
<Navigate to="/login" replace />
)
}

export { ProtectedRoutes }
14 changes: 1 addition & 13 deletions src/components/rsyncCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,7 @@ import { components } from 'schema/main'

type RSyncerInfo = components['schemas']['RSyncerInfo']

export const RsyncCard = ({
rsyncer,
onRemove,
onFinalise,
}: {
rsyncer: RSyncerInfo
onRemove: (id: number, source: string) => void
onFinalise: (id: number, source: string) => void
}) => {
export const RsyncCard = ({ rsyncer }: { rsyncer: RSyncerInfo }) => {
const { isOpen, onOpen, onClose } = useDisclosure()
const [action, setAction] = React.useState('finalise')

Expand All @@ -67,12 +59,8 @@ export const RsyncCard = ({
const handleRsyncerAction = async () => {
if (action === 'finalise') {
await finaliseRsyncer(rsyncer.session_id, rsyncer.source)
// Run the function passed in from 'Session'
onFinalise(rsyncer.session_id, rsyncer.source)
} else if (action === 'remove') {
await removeRsyncer(rsyncer.session_id, rsyncer.source)
// Run the function passed in from 'Session'
onRemove(rsyncer.session_id, rsyncer.source)
}
onClose()
}
Expand Down
Loading