Implement polling for tracking sample updates in real-time
Added a 1-second polling interval to fetch the latest sample data, ensuring the UI remains updated with real-time progress. Cleaned up code formatting for readability and consistency. Improved `getSampleStatus` logic to better distinguish sample states.
This commit is contained in:
parent
19ef20e6b0
commit
4a2d9bd1fc
@ -26,26 +26,37 @@ interface Puck {
|
|||||||
|
|
||||||
const SampleTracker: React.FC = () => {
|
const SampleTracker: React.FC = () => {
|
||||||
const [pucks, setPucks] = useState<Puck[]>([]);
|
const [pucks, setPucks] = useState<Puck[]>([]);
|
||||||
const [hoveredSample, setHoveredSample] = useState<{name: string, status: string} | null>(null);
|
const [hoveredSample, setHoveredSample] = useState<{ name: string; status: string } | null>(null);
|
||||||
|
|
||||||
|
// Fetch latest sample data
|
||||||
|
const fetchPucks = async () => {
|
||||||
|
try {
|
||||||
|
const data: Puck[] = await SamplesService.getAllPucksWithSamplesAndEventsSamplesPucksSamplesGet();
|
||||||
|
setPucks(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching pucks', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Polling logic using a 1-second interval
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchPucks = async () => {
|
// Fetch data immediately on component mount
|
||||||
try {
|
|
||||||
const data: Puck[] = await SamplesService.getAllPucksWithSamplesAndEventsSamplesPucksSamplesGet();
|
|
||||||
console.log(data);
|
|
||||||
setPucks(data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error fetching pucks", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
fetchPucks();
|
fetchPucks();
|
||||||
|
|
||||||
|
// Set up polling every 1 second
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
fetchPucks();
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
// Clear interval on component unmount
|
||||||
|
return () => clearInterval(interval);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const getSampleColor = (events: Event[] = []) => {
|
const getSampleColor = (events: Event[] = []) => {
|
||||||
const hasMounted = events.some(e => e.event_type === 'Mounted');
|
const hasMounted = events.some((e) => e.event_type === 'Mounted');
|
||||||
const hasUnmounted = events.some(e => e.event_type === 'Unmounted');
|
const hasUnmounted = events.some((e) => e.event_type === 'Unmounted');
|
||||||
const hasLost = events.some(e => e.event_type === 'Lost');
|
const hasLost = events.some((e) => e.event_type === 'Lost');
|
||||||
const hasFailed = events.some(e => e.event_type === 'Failed');
|
const hasFailed = events.some((e) => e.event_type === 'Failed');
|
||||||
|
|
||||||
if (hasFailed) return 'red';
|
if (hasFailed) return 'red';
|
||||||
if (hasLost) return 'orange';
|
if (hasLost) return 'orange';
|
||||||
@ -55,66 +66,72 @@ const SampleTracker: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getSampleStatus = (events: Event[] = []) => {
|
const getSampleStatus = (events: Event[] = []) => {
|
||||||
const hasMounted = events.some(e => e.event_type === 'Mounted');
|
const hasMounted = events.some((e) => e.event_type === 'Mounted');
|
||||||
const hasUnmounted = events.some(e => e.event_type === 'Unmounted');
|
const hasUnmounted = events.some((e) => e.event_type === 'Unmounted');
|
||||||
const hasLost = events.some(e => e.event_type === 'Lost');
|
const hasLost = events.some((e) => e.event_type === 'Lost');
|
||||||
const hasFailed = events.some(e => e.event_type === 'Failed');
|
const hasFailed = events.some((e) => e.event_type === 'Failed');
|
||||||
|
|
||||||
if (hasFailed) return 'Failed';
|
if (hasFailed) return 'Failed';
|
||||||
if (hasLost) return 'Lost';
|
if (hasLost) return 'Lost';
|
||||||
|
if (hasMounted && !hasUnmounted) return 'In Progress';
|
||||||
if (hasMounted && hasUnmounted) return 'Completed';
|
if (hasMounted && hasUnmounted) return 'Completed';
|
||||||
if (hasMounted) return 'In Progress';
|
|
||||||
|
|
||||||
return 'Pending';
|
return 'Pending';
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sample-tracker-container">
|
<div className="sample-tracker-container">
|
||||||
<div className="sample-tracker">
|
<div className="sample-tracker">
|
||||||
<div className="header-band">
|
<div className="header-band">
|
||||||
<h2>Sample Tracker</h2>
|
<h2>Sample Tracker</h2>
|
||||||
</div>
|
|
||||||
<div className="pucks-container">
|
|
||||||
{pucks.map((puck) => (
|
|
||||||
<div key={puck.id} className="puck-column">
|
|
||||||
<div className="puck-label" style={{fontSize: '6px'}}>
|
|
||||||
{puck.puck_name.split('').map((char, i) => (
|
|
||||||
<span key={i} style={{fontSize: '10px'}}>{char}</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="samples">
|
|
||||||
{Array.from({length: 16}).map((_, index) => {
|
|
||||||
const sample = puck.samples.find(s => s.position === index + 1);
|
|
||||||
const status = sample ? getSampleStatus(sample.events) : '';
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className="sample-dot"
|
|
||||||
style={{
|
|
||||||
backgroundColor: sample
|
|
||||||
? getSampleColor(sample.events)
|
|
||||||
: 'transparent',
|
|
||||||
border: sample && sample.events.some(e => e.event_type === 'Lost')
|
|
||||||
? '1px solid red'
|
|
||||||
: '1px solid lightgray',
|
|
||||||
}}
|
|
||||||
onMouseEnter={() => sample && setHoveredSample({name: sample.sample_name, status})}
|
|
||||||
onMouseLeave={() => setHoveredSample(null)}
|
|
||||||
></div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{hoveredSample && (
|
|
||||||
<div className="tooltip">
|
|
||||||
<p><strong>Name:</strong> {hoveredSample.name}</p>
|
|
||||||
<p><strong>Status:</strong> {hoveredSample.status}</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
<div className="pucks-container">
|
||||||
|
{pucks.map((puck) => (
|
||||||
|
<div key={puck.id} className="puck-column">
|
||||||
|
<div className="puck-label" style={{ fontSize: '6px' }}>
|
||||||
|
{puck.puck_name.split('').map((char, i) => (
|
||||||
|
<span key={i} style={{ fontSize: '10px' }}>
|
||||||
|
{char}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="samples">
|
||||||
|
{Array.from({ length: 16 }).map((_, index) => {
|
||||||
|
const sample = puck.samples.find((s) => s.position === index + 1);
|
||||||
|
const status = sample ? getSampleStatus(sample.events) : '';
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="sample-dot"
|
||||||
|
style={{
|
||||||
|
backgroundColor: sample ? getSampleColor(sample.events) : 'transparent',
|
||||||
|
border: sample && sample.events.some((e) => e.event_type === 'Lost')
|
||||||
|
? '1px solid red'
|
||||||
|
: '1px solid lightgray',
|
||||||
|
}}
|
||||||
|
onMouseEnter={() =>
|
||||||
|
sample && setHoveredSample({ name: sample.sample_name, status })
|
||||||
|
}
|
||||||
|
onMouseLeave={() => setHoveredSample(null)}
|
||||||
|
></div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{hoveredSample && (
|
||||||
|
<div className="tooltip">
|
||||||
|
<p>
|
||||||
|
<strong>Name:</strong> {hoveredSample.name}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Status:</strong> {hoveredSample.status}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user