Refactor pgroup handling and routing logic.
Enable synchronization of active pgroup across components using a callback mechanism. Improve handling of query parameters, props, and redirection to ensure accurate user context and state across pages like ResultsView and BeamtimeOverview. Update ProtectedRoute to support additional props.
This commit is contained in:
parent
a169a39edd
commit
26f8870d04
@ -66,10 +66,11 @@ const App: React.FC = () => {
|
||||
}, []);
|
||||
|
||||
const handlePgroupChange = (newPgroup: string) => {
|
||||
setActivePgroup(newPgroup);
|
||||
setActivePgroup(newPgroup); // Updates active pgroup state in App
|
||||
console.log(`pgroup changed to: ${newPgroup}`);
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<ResponsiveAppBar
|
||||
@ -85,9 +86,33 @@ const App: React.FC = () => {
|
||||
<Route path="/" element={<ProtectedRoute element={<HomePage />} />} />
|
||||
<Route path="/shipments" element={<ProtectedRoute element={<ShipmentView pgroups={pgroups} activePgroup={activePgroup} />} />} />
|
||||
<Route path="/planning" element={<ProtectedRoute element={<PlanningView />} />} />
|
||||
<Route path="/results/:beamtimeId" element={<ProtectedRoute element={<ResultsView pgroups={pgroups} activePgroup={activePgroup} />} />} />
|
||||
<Route path="/beamtime-overview" element={<ProtectedRoute element={<BeamtimeOverview activePgroup={activePgroup} />} />} />
|
||||
<Route path="/results" element={<ProtectedRoute element={<BeamtimeOverview activePgroup={activePgroup} />} />}/>
|
||||
<Route
|
||||
path="/results/:beamtimeId"
|
||||
element={
|
||||
<ProtectedRoute
|
||||
element={
|
||||
<ResultsView
|
||||
onPgroupChange={handlePgroupChange}
|
||||
currentPgroup={activePgroup}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/beamtime-overview"
|
||||
element={
|
||||
<ProtectedRoute
|
||||
element={
|
||||
<BeamtimeOverview
|
||||
activePgroup={activePgroup}
|
||||
onPgroupChange={handlePgroupChange} // Pass this prop correctly
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Route path="/results" element={<ProtectedRoute element={<BeamtimeOverview activePgroup={activePgroup} onPgroupChange={handlePgroupChange} />} />}/>
|
||||
{/* Optionally, add a 404 fallback route */}
|
||||
<Route path="*" element={<div>Page not found</div>} />
|
||||
|
||||
|
@ -16,9 +16,10 @@ interface BeamtimeRecord {
|
||||
|
||||
interface BeamtimeOverviewProps {
|
||||
activePgroup: string;
|
||||
onPgroupChange: (pgroup: string) => void; // Add callback to update the selected pgroup
|
||||
}
|
||||
|
||||
const BeamtimeOverview: React.FC<BeamtimeOverviewProps> = ({ activePgroup }) => {
|
||||
const BeamtimeOverview: React.FC<BeamtimeOverviewProps> = ({ activePgroup, onPgroupChange }) => {
|
||||
const [rows, setRows] = useState<BeamtimeRecord[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
@ -101,7 +102,7 @@ const BeamtimeOverview: React.FC<BeamtimeOverviewProps> = ({ activePgroup }) =>
|
||||
flex: 1,
|
||||
renderCell: (params) => (
|
||||
<button
|
||||
onClick={() => handleViewResults(params.row.id)}
|
||||
onClick={() => handleViewResults(params.row.id, params.row.pgroups)}
|
||||
style={{
|
||||
padding: '6px 12px',
|
||||
backgroundColor: '#1976d2',
|
||||
@ -118,8 +119,15 @@ const BeamtimeOverview: React.FC<BeamtimeOverviewProps> = ({ activePgroup }) =>
|
||||
];
|
||||
|
||||
// Navigate to the ResultsView page for the selected beamtime
|
||||
const handleViewResults = (beamtimeId: number) => {
|
||||
navigate(`/results/${beamtimeId}?pgroup=${activePgroup}`);
|
||||
const handleViewResults = (beamtimeId: number, pgroups: string) => {
|
||||
const pgroupArray = pgroups.split(',').map((pgroup) => pgroup.trim());
|
||||
const firstPgroup = pgroupArray[0] || ''; // Choose the first pgroup (or fallback to empty string)
|
||||
|
||||
// Ensure onPgroupChange is invoked correctly
|
||||
onPgroupChange(firstPgroup);
|
||||
|
||||
// Navigate directly to the Results page with the correct pgroup in the query
|
||||
navigate(`/results/${beamtimeId}?pgroup=${firstPgroup}`);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -3,16 +3,19 @@ import { Navigate } from 'react-router-dom';
|
||||
|
||||
interface ProtectedRouteProps {
|
||||
element: JSX.Element;
|
||||
[key: string]: any; // Allow additional props
|
||||
}
|
||||
|
||||
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ element }) => {
|
||||
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ element, ...rest }) => {
|
||||
const isAuthenticated = () => {
|
||||
const token = localStorage.getItem('token');
|
||||
console.log("Is Authenticated: ", token !== null);
|
||||
return token !== null;
|
||||
};
|
||||
const token = localStorage.getItem('token');
|
||||
console.log("Is Authenticated: ", token !== null);
|
||||
return token !== null;
|
||||
};
|
||||
|
||||
return isAuthenticated() ? element : <Navigate to="/login" />;
|
||||
return isAuthenticated()
|
||||
? React.cloneElement(element, { ...rest }) // Pass all additional props
|
||||
: <Navigate to="/login" />;
|
||||
};
|
||||
|
||||
export default ProtectedRoute;
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import Box from '@mui/material/Box';
|
||||
@ -38,6 +38,12 @@ const ResponsiveAppBar: React.FC<ResponsiveAppBarProps> = ({
|
||||
const [anchorElNav, setAnchorElNav] = useState<null | HTMLElement>(null);
|
||||
const [anchorElUser, setAnchorElUser] = useState<null | HTMLElement>(null);
|
||||
const [selectedPgroup, setSelectedPgroup] = useState(currentPgroup);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedPgroup(currentPgroup); // Sync local state with the global activePgroup
|
||||
}, [currentPgroup]);
|
||||
|
||||
|
||||
console.log('Active Pgroup:', activePgroup);
|
||||
const handlePgroupChange = (event: React.ChangeEvent<{ value: unknown }>) => {
|
||||
const newPgroup = event.target.value as string;
|
||||
|
@ -1,16 +1,39 @@
|
||||
import React from 'react';
|
||||
import { useParams, useSearchParams} from 'react-router-dom';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useParams, useSearchParams, useNavigate } from 'react-router-dom';
|
||||
import SampleTracker from '../components/SampleTracker';
|
||||
import ResultGrid from '../components/ResultGrid';
|
||||
|
||||
interface ResultsViewProps {
|
||||
onPgroupChange?: (pgroup: string) => void; // Callback to notify about pgroup changes
|
||||
currentPgroup: string; // Currently selected pgroup
|
||||
}
|
||||
|
||||
interface ResultsViewProps {}
|
||||
|
||||
const ResultsView: React.FC<ResultsViewProps> = () => {
|
||||
// Get the selected beamtime ID from the URL
|
||||
const ResultsView: React.FC<ResultsViewProps> = ({ onPgroupChange, currentPgroup }) => {
|
||||
const { beamtimeId } = useParams();
|
||||
const [searchParams] = useSearchParams();
|
||||
const activePgroup = searchParams.get("pgroup") ?? '';
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Get the active pgroup for the experiment from the query params.
|
||||
const activePgroup = searchParams.get("pgroup") ?? ''; // Default to an empty string if missing
|
||||
|
||||
// Redirect if the selected pgroup does not match the beamtime's pgroup
|
||||
useEffect(() => {
|
||||
if (!currentPgroup || currentPgroup !== activePgroup) {
|
||||
console.warn(
|
||||
`Redirecting to BeamtimeOverview because selected pgroup (${currentPgroup || "undefined"}) does not match beamtime's pgroup (${activePgroup})`
|
||||
);
|
||||
navigate('/beamtime-overview'); // Redirect to BeamtimeOverview
|
||||
}
|
||||
}, [currentPgroup, activePgroup, navigate]);
|
||||
|
||||
// Notify parent about the selected pgroup (if needed)
|
||||
useEffect(() => {
|
||||
// Synchronize the pgroup when the component loads
|
||||
if (onPgroupChange && activePgroup !== currentPgroup) {
|
||||
onPgroupChange(activePgroup); // Update the selected pgroup
|
||||
}
|
||||
}, [onPgroupChange, activePgroup, currentPgroup]);
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -24,4 +47,4 @@ const ResultsView: React.FC<ResultsViewProps> = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ResultsView;
|
||||
export default ResultsView;
|
Loading…
x
Reference in New Issue
Block a user