From 9ce4ad01471d52d20f3ecc358922bcf851c299f9 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Tue, 21 Apr 2026 11:16:11 -0300 Subject: [PATCH] refactor: remove PinSelector component and associated styles --- .../src/components/simulator/PinSelector.css | 134 ------------------ .../src/components/simulator/PinSelector.tsx | 98 ------------- .../components/simulator/SimulatorCanvas.tsx | 70 +++------ 3 files changed, 18 insertions(+), 284 deletions(-) delete mode 100644 frontend/src/components/simulator/PinSelector.css delete mode 100644 frontend/src/components/simulator/PinSelector.tsx diff --git a/frontend/src/components/simulator/PinSelector.css b/frontend/src/components/simulator/PinSelector.css deleted file mode 100644 index e6a3c08c..00000000 --- a/frontend/src/components/simulator/PinSelector.css +++ /dev/null @@ -1,134 +0,0 @@ -.pin-selector-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - z-index: 1000; - display: flex; - align-items: center; - justify-content: center; -} - -.pin-selector { - position: relative; - background-color: #2d2d2d; - border: 1px solid #555; - border-radius: 8px; - padding: 20px; - min-width: 320px; - max-width: 400px; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); -} - -.pin-selector-header { - margin-bottom: 15px; - border-bottom: 1px solid #444; - padding-bottom: 10px; -} - -.pin-selector-header h4 { - margin: 0 0 5px 0; - color: #fff; - font-size: 16px; -} - -.component-type-label { - font-size: 12px; - color: #888; - text-transform: capitalize; -} - -.pin-group { - margin-bottom: 15px; -} - -.pin-group-label { - font-size: 13px; - color: #aaa; - margin-bottom: 8px; - font-weight: 500; -} - -.pin-grid { - display: grid; - grid-template-columns: repeat(7, 1fr); - gap: 6px; -} - -.pin-button { - padding: 8px 4px; - background-color: #3d3d3d; - border: 1px solid #555; - border-radius: 4px; - color: #fff; - cursor: pointer; - font-size: 12px; - font-weight: 500; - transition: all 0.2s; -} - -.pin-button:hover { - background-color: #4d4d4d; - border-color: #007acc; -} - -.pin-button.selected { - background-color: #007acc; - border-color: #007acc; - color: #fff; -} - -.pin-button.current { - background-color: #28a745; - border-color: #28a745; - color: #fff; -} - -.pin-button.selected.current { - background-color: #007acc; - border-color: #007acc; -} - -.pin-selector-footer { - display: flex; - justify-content: flex-end; - gap: 10px; - margin-top: 15px; - padding-top: 15px; - border-top: 1px solid #444; -} - -.pin-selector-footer .btn { - padding: 8px 16px; - border: none; - border-radius: 4px; - cursor: pointer; - font-size: 14px; - font-weight: 500; - transition: all 0.2s; -} - -.pin-selector-footer .btn:disabled { - opacity: 0.5; - cursor: not-allowed; -} - -.pin-selector-footer .btn-primary { - background-color: #007acc; - color: white; -} - -.pin-selector-footer .btn-primary:hover:not(:disabled) { - background-color: #005a9e; -} - -.pin-selector-footer .btn-secondary { - background-color: #6c757d; - color: white; -} - -.pin-selector-footer .btn-secondary:hover { - background-color: #5a6268; -} diff --git a/frontend/src/components/simulator/PinSelector.tsx b/frontend/src/components/simulator/PinSelector.tsx deleted file mode 100644 index 46e6fe17..00000000 --- a/frontend/src/components/simulator/PinSelector.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { useState } from 'react'; -import './PinSelector.css'; - -interface PinSelectorProps { - componentId: string; - componentType: string; - currentPin?: number; - onPinSelect: (componentId: string, pin: number) => void; - onClose: () => void; - position: { x: number; y: number }; -} - -// Arduino Uno pin groups -const PIN_GROUPS = [ - { - label: 'Digital Pins', - pins: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - }, - { - label: 'Analog Pins', - pins: [14, 15, 16, 17, 18, 19], // A0-A5 - }, -]; - -export const PinSelector = ({ - componentId, - componentType, - currentPin, - onPinSelect, - onClose, - position, -}: PinSelectorProps) => { - const [selectedPin, setSelectedPin] = useState(currentPin); - - const handlePinClick = (pin: number) => { - setSelectedPin(pin); - }; - - const handleConfirm = () => { - if (selectedPin !== undefined) { - onPinSelect(componentId, selectedPin); - onClose(); - } - }; - - const formatPinLabel = (pin: number): string => { - if (pin >= 14 && pin <= 19) { - return `A${pin - 14}`; - } - return `D${pin}`; - }; - - return ( -
-
e.stopPropagation()} - > -
-

Select Pin

- {componentType} -
- - {PIN_GROUPS.map((group) => ( -
-
{group.label}
-
- {group.pins.map((pin) => ( - - ))} -
-
- ))} - -
- - -
-
-
- ); -}; diff --git a/frontend/src/components/simulator/SimulatorCanvas.tsx b/frontend/src/components/simulator/SimulatorCanvas.tsx index 2ebeb03a..9d8e2223 100644 --- a/frontend/src/components/simulator/SimulatorCanvas.tsx +++ b/frontend/src/components/simulator/SimulatorCanvas.tsx @@ -7,7 +7,6 @@ import { SensorControlPanel } from './SensorControlPanel'; import { SENSOR_CONTROLS } from '../../simulation/sensorControlConfig'; import { DynamicComponent, createComponentFromMetadata } from '../DynamicComponent'; import { ComponentRegistry } from '../../services/ComponentRegistry'; -import { PinSelector } from './PinSelector'; import { getTabSessionId } from '../../simulation/Esp32Bridge'; import { WireLayer } from './WireLayer'; import type { SegmentHandle } from './WireLayer'; @@ -107,8 +106,6 @@ export const SimulatorCanvas = () => { // Component selection const [selectedComponentId, setSelectedComponentId] = useState(null); - const [showPinSelector, setShowPinSelector] = useState(false); - const [pinSelectorPos, setPinSelectorPos] = useState({ x: 0, y: 0 }); // Component property dialog const [showPropertyDialog, setShowPropertyDialog] = useState(false); @@ -573,14 +570,18 @@ export const SimulatorCanvas = () => { const boardId = touchId.slice('__board__:'.length); useSimulatorStore.getState().setActiveBoardId(boardId); } else if (touchId !== '__board__') { - // Short tap on component → open property dialog or sensor panel + // Short tap on component → open property dialog or sensor panel. + // While the simulator is running, components stay interactive — + // only sensor panels may open; property editing is disabled. const component = componentsRef.current.find( (c) => c.id === touchId ); if (component) { - if (runningRef.current && SENSOR_CONTROLS[component.metadataId] !== undefined) { - setSensorControlComponentId(touchId); - setSensorControlMetadataId(component.metadataId); + if (runningRef.current) { + if (SENSOR_CONTROLS[component.metadataId] !== undefined) { + setSensorControlComponentId(touchId); + setSensorControlMetadataId(component.metadataId); + } } else { setPropertyDialogComponentId(touchId); setPropertyDialogPosition({ @@ -903,24 +904,6 @@ export const SimulatorCanvas = () => { setShowComponentPicker(false); }; - // Component selection (double click to open pin selector) - const handleComponentDoubleClick = (componentId: string, event: React.MouseEvent) => { - event.stopPropagation(); - setSelectedComponentId(componentId); - setPinSelectorPos({ x: event.clientX, y: event.clientY }); - setShowPinSelector(true); - }; - - // Pin assignment - const handlePinSelect = (componentId: string, pin: number) => { - updateComponent(componentId, { - properties: { - ...components.find((c) => c.id === componentId)?.properties, - pin, - }, - } as any); - }; - // Component rotation const handleRotateComponent = (componentId: string) => { const component = components.find((c) => c.id === componentId); @@ -937,7 +920,7 @@ export const SimulatorCanvas = () => { // Component dragging handlers const handleComponentMouseDown = (componentId: string, e: React.MouseEvent) => { - if (showPinSelector || showPropertyDialog) return; + if (showPropertyDialog) return; e.stopPropagation(); const component = components.find((c) => c.id === componentId); @@ -1056,10 +1039,15 @@ export const SimulatorCanvas = () => { } else if (draggedComponentId !== '__board__') { const component = components.find((c) => c.id === draggedComponentId); if (component) { - // During simulation: sensor components show the SensorControlPanel - if (running && SENSOR_CONTROLS[component.metadataId] !== undefined) { - setSensorControlComponentId(draggedComponentId); - setSensorControlMetadataId(component.metadataId); + if (running) { + // During simulation only sensor panels open on click — every + // other component is interactive (pushbutton, switch, pot, …) + // and must handle its own clicks, so we suppress the property + // dialog entirely. + if (SENSOR_CONTROLS[component.metadataId] !== undefined) { + setSensorControlComponentId(draggedComponentId); + setSensorControlMetadataId(component.metadataId); + } } else { setPropertyDialogComponentId(draggedComponentId); setPropertyDialogPosition({ @@ -1294,12 +1282,6 @@ export const SimulatorCanvas = () => { onMouseDown={(e) => { handleComponentMouseDown(component.id, e); }} - onDoubleClick={(e) => { - // Only handle UI events when simulation is NOT running - if (!running) { - handleComponentDoubleClick(component.id, e); - } - }} /> {/* Pin overlay for wire creation - hide when running */} @@ -1595,22 +1577,6 @@ export const SimulatorCanvas = () => { - {/* Pin Selector Modal */} - {showPinSelector && selectedComponentId && ( - c.id === selectedComponentId)?.metadataId || 'unknown' - } - currentPin={ - components.find((c) => c.id === selectedComponentId)?.properties.pin as number | undefined - } - onPinSelect={handlePinSelect} - onClose={() => setShowPinSelector(false)} - position={pinSelectorPos} - /> - )} - {/* Component Property Dialog */} {showPropertyDialog && propertyDialogComponentId && (() => { const component = components.find((c) => c.id === propertyDialogComponentId);