From a18ae487f6b7dd956457a705b6bdb57318b2afd1 Mon Sep 17 00:00:00 2001 From: "n.siegfried" Date: Mon, 15 Jun 2026 16:29:14 -0700 Subject: [PATCH] =?UTF-8?q?Fix=20SOP=E2=86=92home=20flow,=20stop=20sample-?= =?UTF-8?q?data=20fallback=20for=20real=20projects,=20add=20custom=20WP=20?= =?UTF-8?q?types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SOP Complete now returns to the project home page after the confirmation popup (instead of staying on the SOP tab), and stamps projectId onto the SOP. - WP creator no longer substitutes the Micron SAMPLE_SOP when a project is active but its SOP isn't found — it shows a "complete the SOP first" empty state instead. Sample is only used for a standalone (no-project) preview. This was the source of "loaded with sample data I didn't select." - SOP WP Types step gains "+ Add Custom Type" (editable name + remove); blank-named custom types are dropped from the generated SOP. Custom types round-trip via the saved state. Co-Authored-By: Claude Opus 4.8 (1M context) --- html/work-package-suite-app.js | 41 +++++++++++++++++++++++++++++----- html/wp-creation-app.js | 13 +++++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/html/work-package-suite-app.js b/html/work-package-suite-app.js index cab1e0b..c5faf2c 100644 --- a/html/work-package-suite-app.js +++ b/html/work-package-suite-app.js @@ -381,14 +381,24 @@ function renderWPTypes(){ state.wpTypes.forEach((t,i)=>{ const row = document.createElement('div'); row.className = 'wp-type-row'; + const nameCell = t.custom + ? `
+ + +
` + : `
${t.name}
`; row.innerHTML = ` -
${t.name}
+ ${nameCell}
`; container.appendChild(row); }); + const addRow = document.createElement('div'); + addRow.style.cssText = 'margin-top:0.85rem;'; + addRow.innerHTML = ``; + container.appendChild(addRow); } function toggleWPType(i){ @@ -396,6 +406,21 @@ function toggleWPType(i){ renderWPTypes(); } +function addCustomWPType(){ + state.wpTypes.push({name:'', enabled:true, notes:'', approval:'', custom:true}); + renderWPTypes(); + // Focus the new custom row's name input. + const rows = document.querySelectorAll('#wp-types-table .wp-type-row'); + const last = rows[rows.length-1]; + const nameInput = last && last.querySelector('input[type="text"]'); + if(nameInput) nameInput.focus(); +} + +function removeWPType(i){ + state.wpTypes.splice(i,1); + renderWPTypes(); +} + function renderTeamMembers(){ const container = document.getElementById('team-members-list'); if(!container) return; @@ -717,8 +742,8 @@ function completeSOP(){ instanceSuffix: state.governance.instanceSuffix || 'letter', sizeHoursMax: state.governance.sizeHoursMax || '' }, - woTypes: state.wpTypes.filter(t=>t.enabled).map(t=>({ - name: t.name, + woTypes: state.wpTypes.filter(t=>t.enabled && (t.name||'').trim()).map(t=>({ + name: t.name.trim(), enabled: true, notes: t.notes || '', approval: t.approval || '' @@ -741,6 +766,8 @@ function completeSOP(){ }; sopComplete = true; + // Stamp the active project onto the SOP so it's unambiguously tied to it. + try { if(typeof ProjectData!=='undefined' && ProjectData.getActiveId()) sop.projectId = ProjectData.getActiveId(); } catch(e){} updateProjectDisplay(); // Persist for the home page (green / "Review") and for the WP Creator tab, @@ -753,10 +780,12 @@ function completeSOP(){ track('sop_generated', {woTypes: sop.woTypes.length, constraints: sop.constraints.length}); - alert('✓ SOP Configuration Complete!\n\nSwitch to "Work Package Creation" to start creating Work Packages.'); - - // Hand the SOP to the embedded Work Package Creator and unlock its tab. + // Hand the SOP to the embedded Work Package Creator and unlock its tab (in case + // the user stays), then return to the project home page per the requested flow. if(typeof onSOPReady === 'function') onSOPReady(sop); + + alert('✓ SOP Configuration Complete!\n\nReturning to the project home page.'); + window.location.href = 'index.html'; } // ── COMMENTS ────────────────────────────────────────────────────────────────── diff --git a/html/wp-creation-app.js b/html/wp-creation-app.js index 0159e9a..bdc2f21 100644 --- a/html/wp-creation-app.js +++ b/html/wp-creation-app.js @@ -136,7 +136,12 @@ function editQuality(id){ } function renderCtxBar(){ const bar=document.getElementById('ctx-bar'); - if(!SOP){ bar.innerHTML=`
No SOP loaded — or import one from the Configuration tool.
`; return; } + if(!SOP){ + bar.innerHTML = activeProjectId + ? `
No SOP found for this project yet — complete the SOP Configuration first, then return here.
` + : `
No SOP loaded — or import one from the Configuration tool.
`; + return; + } const p=SOP.project||{}, g=SOP.governance||{}; const sample=SOP.meta&&SOP.meta.sample?`SAMPLE`:''; bar.innerHTML=`
${esc(p.name||'Untitled')} ${sample}
@@ -1039,7 +1044,11 @@ loadStore(); if(d && d.woTypes){ SOP = d; applySOP(); newPackage(); return; } } } catch(e){} - loadSampleSOP(); + // No SOP found. Only show the Micron SAMPLE for a standalone preview (no project + // context). For a real project, never substitute sample data — show the empty + // state so it's clear the project's SOP must be completed first. + if(activeProjectId){ SOP=null; renderCtxBar(); newPackage(); } + else { loadSampleSOP(); } })(); setRadio('status','Draft'); renderSavedList();