feature: Update WorkflowStepper to use Zustand stores directly

Complete the component refactoring by updating WorkflowStepper to
consume stores directly instead of receiving props.

Changes:
- Updated WorkflowStepper to use useMachineStore and usePatternStore
- Removed 7 props that were being passed from App.tsx
- Added hasError import to WorkflowStepper
- Removed unused hasError import from App.tsx

Now all major components use Zustand stores directly:
- FileUpload: 0 props (was 14)
- ProgressMonitor: 0 props (was 9)
- PatternCanvas: 0 props (was 7)
- PatternSummaryCard: 0 props (was 5)
- WorkflowStepper: 0 props (was 7)

Total props eliminated: 42

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Henrik Bruhn 2025-12-12 21:43:45 +01:00
parent c22216792a
commit fe2e68a457
2 changed files with 36 additions and 31 deletions

View file

@ -9,7 +9,7 @@ import { ProgressMonitor } from './components/ProgressMonitor';
import { WorkflowStepper } from './components/WorkflowStepper'; import { WorkflowStepper } from './components/WorkflowStepper';
import { PatternSummaryCard } from './components/PatternSummaryCard'; import { PatternSummaryCard } from './components/PatternSummaryCard';
import { BluetoothDevicePicker } from './components/BluetoothDevicePicker'; import { BluetoothDevicePicker } from './components/BluetoothDevicePicker';
import { hasError, getErrorDetails } from './utils/errorCodeHelpers'; import { getErrorDetails } from './utils/errorCodeHelpers';
import { getStateVisualInfo } from './utils/machineStateHelpers'; import { getStateVisualInfo } from './utils/machineStateHelpers';
import { CheckCircleIcon, BoltIcon, PauseCircleIcon, ExclamationTriangleIcon, ArrowPathIcon, XMarkIcon, InformationCircleIcon } from '@heroicons/react/24/solid'; import { CheckCircleIcon, BoltIcon, PauseCircleIcon, ExclamationTriangleIcon, ArrowPathIcon, XMarkIcon, InformationCircleIcon } from '@heroicons/react/24/solid';
import './App.css'; import './App.css';
@ -320,15 +320,7 @@ function App() {
{/* Workflow Stepper - Flexible width column */} {/* Workflow Stepper - Flexible width column */}
<div> <div>
<WorkflowStepper <WorkflowStepper />
machineStatus={machineStatus}
isConnected={isConnected}
hasPattern={pesData !== null}
patternUploaded={patternUploaded}
hasError={hasError(machineError)}
errorMessage={machineErrorMessage || undefined}
errorCode={machineError}
/>
</div> </div>
</div> </div>
</header> </header>

View file

@ -1,17 +1,10 @@
import { useState, useRef, useEffect } from 'react'; import { useState, useRef, useEffect } from 'react';
import { useShallow } from 'zustand/react/shallow';
import { useMachineStore } from '../stores/useMachineStore';
import { usePatternStore } from '../stores/usePatternStore';
import { CheckCircleIcon, InformationCircleIcon, ExclamationTriangleIcon } from '@heroicons/react/24/solid'; import { CheckCircleIcon, InformationCircleIcon, ExclamationTriangleIcon } from '@heroicons/react/24/solid';
import { MachineStatus } from '../types/machine'; import { MachineStatus } from '../types/machine';
import { getErrorDetails } from '../utils/errorCodeHelpers'; import { getErrorDetails, hasError } from '../utils/errorCodeHelpers';
interface WorkflowStepperProps {
machineStatus: MachineStatus;
isConnected: boolean;
hasPattern: boolean;
patternUploaded: boolean;
hasError?: boolean;
errorMessage?: string;
errorCode?: number;
}
interface Step { interface Step {
id: number; id: number;
@ -256,15 +249,35 @@ function getCurrentStep(machineStatus: MachineStatus, isConnected: boolean, hasP
} }
} }
export function WorkflowStepper({ export function WorkflowStepper() {
// Machine store
const {
machineStatus, machineStatus,
isConnected, isConnected,
hasPattern, machineError,
error: errorMessage,
} = useMachineStore(
useShallow((state) => ({
machineStatus: state.machineStatus,
isConnected: state.isConnected,
machineError: state.machineError,
error: state.error,
}))
);
// Pattern store
const {
pesData,
patternUploaded, patternUploaded,
hasError = false, } = usePatternStore(
errorMessage, useShallow((state) => ({
errorCode pesData: state.pesData,
}: WorkflowStepperProps) { patternUploaded: state.patternUploaded,
}))
);
const hasPattern = pesData !== null;
const hasErrorFlag = hasError(machineError);
const currentStep = getCurrentStep(machineStatus, isConnected, hasPattern, patternUploaded); const currentStep = getCurrentStep(machineStatus, isConnected, hasPattern, patternUploaded);
const [showPopover, setShowPopover] = useState(false); const [showPopover, setShowPopover] = useState(false);
const [popoverStep, setPopoverStep] = useState<number | null>(null); const [popoverStep, setPopoverStep] = useState<number | null>(null);
@ -383,7 +396,7 @@ export function WorkflowStepper({
aria-label="Step guidance" aria-label="Step guidance"
> >
{(() => { {(() => {
const content = getGuideContent(popoverStep, machineStatus, hasError, errorCode, errorMessage); const content = getGuideContent(popoverStep, machineStatus, hasErrorFlag, machineError, errorMessage || undefined);
if (!content) return null; if (!content) return null;
const colorClasses = { const colorClasses = {