197 lines
7.0 KiB
TypeScript
197 lines
7.0 KiB
TypeScript
import React, { useEffect, useState } from "react";
|
|
import DataGrid from "react-data-grid";
|
|
import { Box, Typography, Snackbar, Alert, CircularProgress } from "@mui/material";
|
|
import { LogisticsService } from "../../../frontend/openapi";
|
|
import "react-data-grid/lib/styles.css";
|
|
|
|
|
|
|
|
interface Dewar {
|
|
id: string;
|
|
dewar_name: string;
|
|
shipment_name: string; // Added new field
|
|
slot_id: string; // Added new field
|
|
status: string;
|
|
beamline_location: string;
|
|
timestamp: string; // You can change this type based on your API response
|
|
}
|
|
|
|
const DewarStatusTab: React.FC = () => {
|
|
const [dewars, setDewars] = useState<Dewar[]>([]);
|
|
const [loading, setLoading] = useState<boolean>(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const slotQRCodes = [
|
|
"A1-X06SA",
|
|
"A2-X06SA",
|
|
"A3-X06SA",
|
|
"A4-X06SA",
|
|
"A5-X06SA",
|
|
"B1-X06SA",
|
|
"B2-X06SA",
|
|
"B3-X06SA",
|
|
"B4-X06SA",
|
|
"B5-X06SA",
|
|
"C1-X06SA",
|
|
"C2-X06SA",
|
|
"C3-X06SA",
|
|
"C4-X06SA",
|
|
"C5-X06SA",
|
|
"D1-X06SA",
|
|
"D2-X06SA",
|
|
"D3-X06SA",
|
|
"D4-X06SA",
|
|
"D5-X06SA",
|
|
"A1-X10SA",
|
|
"A2-X10SA",
|
|
"A3-X10SA",
|
|
"A4-X10SA",
|
|
"A5-X10SA",
|
|
"B1-X10SA",
|
|
"B2-X10SA",
|
|
"B3-X10SA",
|
|
"B4-X10SA",
|
|
"B5-X10SA",
|
|
"C1-X10SA",
|
|
"C2-X10SA",
|
|
"C3-X10SA",
|
|
"C4-X10SA",
|
|
"C5-X10SA",
|
|
"D1-X10SA",
|
|
"D2-X10SA",
|
|
"D3-X10SA",
|
|
"D4-X10SA",
|
|
"D5-X10SA",
|
|
"NB1",
|
|
"NB2",
|
|
"NB3",
|
|
"NB4",
|
|
"NB5",
|
|
"NB6",
|
|
"X10SA-Beamline",
|
|
"X06SA-Beamline",
|
|
"X06DA-Beamline",
|
|
"Outgoing X10SA",
|
|
"Outgoing X06SA",
|
|
];
|
|
|
|
// Updated columns array
|
|
const columns = [
|
|
{ key: "shipment_name", name: "Shipment Name", resizable: true },
|
|
{ key: "dewar_name", name: "Dewar Name", resizable: true },
|
|
{ key: "slot_id", name: "Storage", resizable: true },
|
|
{ key: "status", name: "Status", editable: true, resizable: true },
|
|
{ key: "beamline_location", name: "Location", resizable: true },
|
|
{ key: "last_updated", name: "Last Updated", resizable: true },
|
|
{ key: "local_contact", name: "Local Contact", resizable: true }, // Now a string
|
|
{ key: "contact", name: "Contact", resizable: true }, // Now a string
|
|
{ key: "address", name: "Return Address", resizable: true }, // Now a string
|
|
];
|
|
|
|
const fetchDewarData = async () => {
|
|
setLoading(true);
|
|
try {
|
|
// Fetch data from API
|
|
const dewarData = await LogisticsService.getAllDewarsTableLogisticsDewarTableGet();
|
|
|
|
// Log the raw data for debugging
|
|
console.log("Fetched dewarData:", dewarData);
|
|
|
|
// Flatten and enrich data
|
|
const enrichedData = dewarData.map((dewar: any) => {
|
|
// Format address into a single string
|
|
const returnAddress = dewar.address && dewar.address.length > 0
|
|
? `${dewar.address[0].house_number || ""} ${dewar.address[0].street || ""}, ${dewar.address[0].city || ""}, ${dewar.address[0].state || ""}, ${dewar.address[0].zipcode || ""}, ${dewar.address[0].country || ""}`.trim()
|
|
: "N/A";
|
|
|
|
// Format contact into a single string
|
|
const contact = dewar.contact && dewar.contact.length > 0
|
|
? `${dewar.contact[0].firstname || "N/A"} ${dewar.contact[0].lastname || "N/A"} (${dewar.contact[0].email || "N/A"})`
|
|
: "N/A";
|
|
|
|
// Format local_contact into a single string
|
|
const localContact = dewar.local_contact
|
|
? `${dewar.local_contact.firstname || "N/A"} ${dewar.local_contact.lastname || "N/A"} (${dewar.local_contact.phone_number || "N/A"})`
|
|
: "N/A";
|
|
const beamline_location = dewar.events.slot_id || "N/A";
|
|
console.log("Beamline location:", beamline_location);
|
|
// Log any fields that are missing or appear incorrect
|
|
if (!dewar.local_contact) console.warn("Missing local_contact for dewar:", dewar);
|
|
if (!dewar.contact) console.warn("Missing contact for dewar:", dewar);
|
|
if (!dewar.address) console.warn("Missing address for dewar:", dewar);
|
|
|
|
return {
|
|
...dewar,
|
|
local_contact: localContact,
|
|
contact: contact,
|
|
address: returnAddress, // Replace `address` object with single formatted string
|
|
beamline_location: dewar.events !== undefined && slotQRCodes[dewar.events]
|
|
? slotQRCodes[dewar.events -1]
|
|
: "",
|
|
slot_id: dewar.slot_id !== undefined && slotQRCodes[dewar.slot_id]
|
|
? slotQRCodes[dewar.slot_id -1]
|
|
: "", // Convert slot_id to descriptive label
|
|
last_updated: dewar.last_updated
|
|
? new Date(dewar.last_updated).toLocaleString('en-US', {
|
|
year: 'numeric',
|
|
month: 'short',
|
|
day: 'numeric',
|
|
hour: 'numeric',
|
|
minute: 'numeric',
|
|
hour12: true,
|
|
})
|
|
: ""
|
|
|
|
};
|
|
});
|
|
|
|
setDewars(enrichedData);
|
|
console.log("Final enrichedData:", enrichedData);
|
|
} catch (e) {
|
|
console.error("Failed to fetch or process dewar data:", e);
|
|
setError("Failed to fetch dewar data");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
|
|
useEffect(() => {
|
|
fetchDewarData();
|
|
}, []);
|
|
|
|
const onRowsChange = async (updatedRows: Dewar[]) => {
|
|
setDewars(updatedRows);
|
|
try {
|
|
const updatedDewar = updatedRows[updatedRows.length - 1]; // Get the last edited row
|
|
await LogisticsService.updateDewarStatus({ ...updatedDewar }); // Mock API update
|
|
} catch (err) {
|
|
setError("Error updating dewar");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Box>
|
|
<Typography variant="h5" gutterBottom>
|
|
Dewar Status
|
|
</Typography>
|
|
{loading ? (
|
|
<CircularProgress />
|
|
) : error ? (
|
|
<Snackbar open autoHideDuration={6000} onClose={() => setError(null)}>
|
|
<Alert severity="error" onClose={() => setError(null)}>
|
|
{error}
|
|
</Alert>
|
|
</Snackbar>
|
|
) : (
|
|
<DataGrid
|
|
columns={columns}
|
|
rows={dewars}
|
|
onRowsChange={onRowsChange}
|
|
style={{ height: 600, width: "100%" }} // Make sure height and width are set
|
|
/>
|
|
)}
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default DewarStatusTab; |