retrieved return events working but bug with return to be fixed

This commit is contained in:
GotthardG
2024-11-26 17:41:01 +01:00
parent fc8bb8d200
commit fbb868e255
3 changed files with 142 additions and 62 deletions

View File

@ -1,8 +1,8 @@
import React, { useEffect } from 'react';
import { Box, Typography, Button, Alert } from '@mui/material';
import styled from 'styled-components';
import styled, { keyframes, css } from 'styled-components';
import LocalGasStationIcon from '@mui/icons-material/LocalGasStation';
import LocationOnIcon from '@mui/icons-material/LocationOn'; // New import for location indication
import LocationOnIcon from '@mui/icons-material/LocationOn';
import CountdownTimer from './CountdownTimer';
export interface SlotData {
@ -15,7 +15,9 @@ export interface SlotData {
dewar_name?: string;
needs_refill?: boolean;
time_until_refill?: number;
at_beamline?: boolean; // New property to indicate the dewar is at the beamline
beamlineLocation?: string;
retrieved?: boolean; // Indicates if the dewar is retrieved
retrievedTimestamp?: string; // Timestamp of the retrieval event
}
interface SlotProps {
@ -26,19 +28,35 @@ interface SlotProps {
reloadSlots: () => Promise<void>;
}
interface StyledSlotProps {
isSelected: boolean;
isOccupied: boolean;
atBeamline: boolean;
}
const pulse = keyframes`
0% {
box-shadow: 0 0 5px 5px rgba(255, 0, 0, 0.6);
}
50% {
box-shadow: 0 0 5px 15px rgba(255, 0, 0, 0.2);
}
100% {
box-shadow: 0 0 5px 5px rgba(255, 0, 0, 0.6);
}
`;
const StyledSlot = styled(Box)<StyledSlotProps>`
const StyledSlot = styled(Box)<{ isSelected: boolean; isOccupied: boolean; atBeamline: boolean; isRetrieved: boolean; needsRefillSoon: boolean }>`
padding: 16px;
margin: 8px;
width: 150px;
height: 260px;
background-color: ${({ isSelected, isOccupied, atBeamline }) =>
atBeamline ? '#ff9800' : isSelected ? '#3f51b5' : isOccupied ? '#f44336' : '#4caf50'};
background-color: ${({ isSelected, isOccupied, atBeamline, isRetrieved }) => {
if (isSelected) {
return '#3f51b5';
}
if (isRetrieved && !atBeamline) {
return '#9e9e9e'; // Grey color for retrieved but not at beamline
}
if (atBeamline) {
return '#ff9800';
}
return isOccupied ? '#f44336' : '#4caf50';
}};
color: white;
cursor: pointer;
display: flex;
@ -48,6 +66,11 @@ const StyledSlot = styled(Box)<StyledSlotProps>`
border-radius: 8px;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
transition: transform 0.2s;
${({ isOccupied, needsRefillSoon }) =>
isOccupied && needsRefillSoon &&
css`
animation: ${pulse} 1.5s infinite;
`}
&:hover {
transform: scale(1.05);
@ -62,27 +85,32 @@ const BottleIcon: React.FC<{ fillHeight: number }> = ({ fillHeight }) => {
<svg height="100px" width="50px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 276.777 276.777">
<defs>
<clipPath id="bottle-clip">
<path d="M190.886,82.273c-3.23-2.586-7.525-7.643-7.525-21.639V43h8.027V0h-106v43h8.027v17.635
c0,11.66-1.891,17.93-6.524,21.639c-21.813,17.459-31.121,36.748-31.121,64.5v100.088c0,16.496,13.42,29.916,29.916,29.916
h105.405c16.496,0,29.916-13.42,29.916-29.916V146.773C221.007,121.103,210.029,97.594,190.886,82.273z"/>
<path
d="M190.886,82.273c-3.23-2.586-7.525-7.643-7.525-21.639V43h8.027V0h-106v43h8.027v17.635
c0,11.66-1.891,17.93-6.524,21.639c-21.813,17.459-31.121,36.748-31.121,64.5v100.088c0,16.496,13.42,29.916,29.916,29.916
h105.405c16.496,0,29.916-13.42,29.916-29.916V146.773C221.007,121.103,210.029,97.594,190.886,82.273z"
/>
</clipPath>
</defs>
<path fill="lightgray" d="M190.886,82.273c-3.23-2.586-7.525-7.643-7.525-21.639V43h8.027V0h-106v43h8.027v17.635
c0,11.66-1.891,17.93-6.524,21.639c-21.813,17.459-31.121,36.748-31.121,64.5v100.088c0,16.496,13.42,29.916,29.916,29.916
h105.405c16.496,0,29.916-13.42,29.916-29.916V146.773C221.007,121.103,210.029,97.594,190.886,82.273z"/>
<path
fill="lightgray"
d="M190.886,82.273c-3.23-2.586-7.525-7.643-7.525-21.639V43h8.027V0h-106v43h8.027v17.635
c0,11.66-1.891,17.93-6.524,21.639c-21.813,17.459-31.121,36.748-31.121,64.5v100.088c0,16.496,13.42,29.916,29.916,29.916
h105.405c16.496,0,29.916-13.42,29.916-29.916V146.773C221.007,121.103,210.029,97.594,190.886,82.273z"
/>
<rect x="0" y={yPosition} width="100%" height={pixelHeight} fill="#00bfff" clipPath="url(#bottle-clip)" />
</svg>
);
};
const Slot: React.FC<SlotProps> = ({ data, isSelected, onSelect, onRefillDewar, reloadSlots }) => {
const { id, qr_code, label, qr_base, occupied, needs_refill, time_until_refill, dewar_unique_id, dewar_name, at_beamline } = data;
const { id, qr_code, label, qr_base, occupied, needs_refill, time_until_refill, dewar_unique_id, dewar_name, beamlineLocation, retrieved, retrievedTimestamp } = data;
const calculateFillHeight = (timeUntilRefill?: number) => {
if (timeUntilRefill === undefined || timeUntilRefill <= 0) {
return 0;
}
const maxTime = 3600;
const maxTime = 3600; // Example maximum time for calculating fill height
return Math.min((timeUntilRefill / maxTime) * 100, 100);
};
@ -101,13 +129,30 @@ const Slot: React.FC<SlotProps> = ({ data, isSelected, onSelect, onRefillDewar,
}
};
const isSpecificBeamline = beamlineLocation === 'X10SA' || beamlineLocation === 'X06SA' || beamlineLocation === 'X06DA';
const isRetrieved = retrieved === true && !isSpecificBeamline;
// Consider slot needs a refill soon if it's occupied and time_until_refill is less than 3 hours (or 0)
const needsRefillSoon = occupied && (time_until_refill !== undefined && time_until_refill <= 10800);
return (
<StyledSlot isSelected={isSelected} isOccupied={occupied} atBeamline={!!at_beamline} onClick={() => onSelect(data)}>
<StyledSlot
isSelected={isSelected}
isOccupied={occupied}
atBeamline={isSpecificBeamline}
isRetrieved={isRetrieved} // prop to control slot color for retrieved
needsRefillSoon={needsRefillSoon} // prop to control pulsing animation
onClick={() => onSelect(data)}
>
<Typography variant="h6">{label}</Typography>
{dewar_name && <Typography variant="body2">{`${dewar_name}`}</Typography>} {/* Ensure correct dewar_name */}
{dewar_name && <Typography variant="body2">{`${dewar_name}`}</Typography>}
{needs_refill && <LocalGasStationIcon />}
{dewar_unique_id && <BottleIcon fillHeight={fillHeight} />}
{at_beamline && <Typography style={{fontSize: 12}}><LocationOnIcon /> At Beamline</Typography>} {/* Indicate at beamline */}
{isSpecificBeamline && (
<Typography style={{ fontSize: 12 }}>
<LocationOnIcon /> {beamlineLocation}
</Typography>
)}
{(dewar_unique_id && time_until_refill !== undefined && time_until_refill !== -1) ? (
<CountdownTimer key={dewar_unique_id} totalSeconds={time_until_refill} />
) : null}
@ -121,6 +166,6 @@ const Slot: React.FC<SlotProps> = ({ data, isSelected, onSelect, onRefillDewar,
)}
</StyledSlot>
);
}
};
export default Slot;