mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
support expand/collapse on all components on session details page
This commit is contained in:
@@ -100,6 +100,8 @@ export default function SessionDetailPage() {
|
||||
const [analysisResults, setAnalysisResults] = useState<RuleResult[]>([]);
|
||||
const [loadingAnalysis, setLoadingAnalysis] = useState(false);
|
||||
const [analysisExpanded, setAnalysisExpanded] = useState(true);
|
||||
const [phaseTimelineExpanded, setPhaseTimelineExpanded] = useState(true);
|
||||
const [perfExpanded, setPerfExpanded] = useState(true);
|
||||
const [timelineExpanded, setTimelineExpanded] = useState(true);
|
||||
const [adminMode, setAdminMode] = useState(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
@@ -897,16 +899,26 @@ export default function SessionDetailPage() {
|
||||
{/* Phase Timeline */}
|
||||
{!isGatherRulesSession && session && (
|
||||
<div id="section-enrollment-progress" className="bg-white shadow rounded-lg p-6 mb-6">
|
||||
<h2 className="text-xl font-semibold text-gray-900 mb-6">Enrollment Progress</h2>
|
||||
<PhaseTimeline
|
||||
currentPhase={session.currentPhase}
|
||||
completedPhases={session.status === 'Succeeded' ? [7] : []}
|
||||
events={events}
|
||||
sessionStatus={session.status}
|
||||
enrollmentType={session.enrollmentType}
|
||||
isPreProvisioned={isWhiteGloveSession}
|
||||
onPhaseClick={scrollToPhase}
|
||||
/>
|
||||
<button
|
||||
onClick={() => setPhaseTimelineExpanded(!phaseTimelineExpanded)}
|
||||
className="flex items-center justify-between w-full text-left"
|
||||
>
|
||||
<h2 className="text-xl font-semibold text-gray-900">Enrollment Progress</h2>
|
||||
<svg className={`w-5 h-5 text-gray-400 transition-transform duration-200 ${phaseTimelineExpanded ? 'rotate-90' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</button>
|
||||
{phaseTimelineExpanded && (
|
||||
<PhaseTimeline
|
||||
currentPhase={session.currentPhase}
|
||||
completedPhases={session.status === 'Succeeded' ? [7] : []}
|
||||
events={events}
|
||||
sessionStatus={session.status}
|
||||
enrollmentType={session.enrollmentType}
|
||||
isPreProvisioned={isWhiteGloveSession}
|
||||
onPhaseClick={scrollToPhase}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -928,6 +940,8 @@ export default function SessionDetailPage() {
|
||||
<div id="section-performance">
|
||||
<PerformanceChart
|
||||
events={events.filter(e => e.eventType === "performance_snapshot")}
|
||||
expanded={perfExpanded}
|
||||
setExpanded={setPerfExpanded}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -9,6 +9,8 @@ interface PerformanceEvent {
|
||||
|
||||
interface PerformanceChartProps {
|
||||
events: PerformanceEvent[];
|
||||
expanded?: boolean;
|
||||
setExpanded?: (expanded: boolean) => void;
|
||||
}
|
||||
|
||||
interface SparklineProps {
|
||||
@@ -229,7 +231,11 @@ function DiskFreeChart({ values, timestamps }: DiskFreeChartProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export default function PerformanceChart({ events }: PerformanceChartProps) {
|
||||
export default function PerformanceChart({ events, expanded: expandedProp, setExpanded: setExpandedProp }: PerformanceChartProps) {
|
||||
const isControlled = expandedProp !== undefined;
|
||||
const [internalExpanded, setInternalExpanded] = useState(true);
|
||||
const expanded = isControlled ? expandedProp : internalExpanded;
|
||||
const setExpanded = isControlled ? setExpandedProp! : setInternalExpanded;
|
||||
const metrics = useMemo(() => {
|
||||
if (events.length === 0) return null;
|
||||
|
||||
@@ -307,15 +313,23 @@ export default function PerformanceChart({ events }: PerformanceChartProps) {
|
||||
|
||||
return (
|
||||
<div className="bg-white shadow rounded-lg p-6 mb-6">
|
||||
<div className="flex items-center space-x-2 mb-4">
|
||||
<svg className="w-5 h-5 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||
<button
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
className="flex items-center justify-between w-full text-left"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<svg className="w-5 h-5 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||
</svg>
|
||||
<h2 className="text-lg font-semibold text-gray-900">Performance Metrics</h2>
|
||||
<span className="text-xs text-gray-400">({metrics.sampleCount} samples)</span>
|
||||
</div>
|
||||
<svg className={`w-5 h-5 text-gray-400 transition-transform duration-200 ${expanded ? 'rotate-90' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
<h2 className="text-lg font-semibold text-gray-900">Performance Metrics</h2>
|
||||
<span className="text-xs text-gray-400">({metrics.sampleCount} samples)</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className={`grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 ${metrics.netReceiveValues.length >= 2 ? "lg:grid-cols-6" : "lg:grid-cols-4"} gap-4`}>
|
||||
{expanded && <div className={`grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 ${metrics.netReceiveValues.length >= 2 ? "lg:grid-cols-6" : "lg:grid-cols-4"} gap-4 mt-4`}>
|
||||
{/* CPU */}
|
||||
<div className="bg-gray-50 rounded-lg p-3">
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
@@ -458,7 +472,7 @@ export default function PerformanceChart({ events }: PerformanceChartProps) {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user