--- /home/shire3d/ARMOR/agents/apps/limbforge/src/shire/ShireApp.jsx +++ /home/shire3d/ARMOR/agents/apps/limbforge/src/shire/ShireApp.jsx.patched @@ -34,6 +34,7 @@ import Settings from '@/pages/Settings'; import TakeMeasurements from '@/pages/TakeMeasurements'; +import Workshop3D from '@/pages/Workshop3D'; export default function ShireApp() { return ( @@ -41,6 +42,10 @@ + } + /> }> } /> } /> --- /home/shire3d/ARMOR/agents/apps/limbforge/src/pages/TakeMeasurements.jsx +++ /home/shire3d/ARMOR/agents/apps/limbforge/src/pages/TakeMeasurements.jsx.patched @@ -490,11 +490,11 @@ } onClick={() => navigate( - `/measurements/${sessionUuid}` + `/workshop-3d?session=${encodeURIComponent(sessionUuid)}` ) } > - Begin measurements + Begin 3D measurements --- /home/shire3d/ARMOR/agents/apps/limbforge/src/pages/Workshop3D.jsx +++ /home/shire3d/ARMOR/agents/apps/limbforge/src/pages/Workshop3D.jsx.patched @@ -45,7 +45,7 @@ // Nav items that switch the in-workshop workflow (stay on the 3D page) const WORKFLOW_LINKS = [ - { id: null, label: 'Measurement Studio', icon: Ruler }, + { id: 'measure', label: 'Measurement Studio', icon: Ruler }, { id: 'assembly', label: 'Prosthesis Mapper', icon: Boxes }, { id: 'sensitive', label: 'Sensitive Zones', icon: Map }, { id: 'cover', label: 'Cover Build', icon: Hammer }, @@ -68,7 +68,7 @@ const [transparency, setTransparency] = useState(1); const [sectionCut, setSectionCut] = useState(false); const [display, setDisplay] = useState({ measurements: true, sensitive: true, keepOut: true, access: true, cover: true, movement: true, logo: true }); - const [activeWorkflow, setActiveWorkflow] = useState(null); + const [activeWorkflow, setActiveWorkflow] = useState('measure'); const [activeTool, setActiveTool] = useState('select'); const [component, setComponent] = useState(null); @@ -80,14 +80,32 @@ const [missingInfo, setMissingInfo] = useState([]); const [session, setSession] = useState(null); + // Bind the explicitly selected open session to the guided 3D workspace. // A project-only workflow may legitimately have no physical Component yet. - // Bind the sole open session so guided 3D measurements can still be saved. useEffect(() => { - if (session || sessions.length !== 1) return; - - const candidate = sessions[0]; - - if (candidate && candidate.status !== 'Complete') { + if (session || sessions.length === 0) return; + + const requestedUuid = + new URLSearchParams(window.location.search).get('session'); + + const requestedSession = requestedUuid + ? sessions.find( + item => + item.uuid === requestedUuid + && item.status !== 'Complete' + ) + : null; + + const soleOpenSession = + sessions.length === 1 + && sessions[0].status !== 'Complete' + ? sessions[0] + : null; + + const candidate = + requestedSession || soleOpenSession; + + if (candidate) { console.info( '[SHiRE] Bound sole open measurement session to 3D workspace', candidate.uuid,