T9.4 - S7: one sample-data affordance, confirmed, and fenced off the project
Four affordances under three names became ONE: "Load sample data", on the creator's toolbar, at the far end of two separators from the live actions (New / Duplicate), pushed right with its own gap. It confirms through the T7.9 dialog, naming exactly what it does - and what it does not: "This page only: nothing is written to the project unless you then save." The probe verifies the fence the way the done-when demands - against a REAL project, reading the server's SOP and work-package list before and after and asserting byte-identical. Gone: the wizard's header "Load sample" (the dangerous one: it filled the state completeSOP() pushes to the LIVE project, one click, no confirm, no undo - reconciled with D1 exactly as the task records: the creator's control is the survivor, the wizard copy goes), the creator's split Sample SOP / Load example pair (now internals behind the one entry point), and the empty-state context bar's third button (its text now points at the toolbar control). The location/material "Load sample values" buttons stay: they fill a PASTE BOX that acts only through an explicit, dry-runnable import - a different thing, stated in the code. Probes re-pointed with reasons in place: frame_check's D1 toolbar list names the consolidated control; validation_check's sample-driven toast checks became the-affordance-is-gone checks (and its stale showAnalytics drive, orphaned by T7.10, became a the-duplicate-stays-gone check). Verification (each probe run alone): NEW tests/sample_check.py 10/10. Regressions: validation_check 77/77, frame_check 38/38, kitting_check 26/26, export_check 20/20, sections_check 95/95. Items: S7 (D1 reconciliation honored) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -397,6 +397,20 @@ function constraintNames(){
|
||||
function nextSeq(){ return savedPackages.length+1; }
|
||||
|
||||
// ── SOP LOADING ──────────────────────────────────────────────────────────────
|
||||
// S7 / T9.4: the one sample entry point. loadSampleSOP()/loadExample() stay as
|
||||
// internals (probes and this function call them); the USER reaches sample data
|
||||
// through exactly this, which says what it will and will not do before doing it.
|
||||
async function loadSampleAll(){
|
||||
if(!(await wpConfirmDialog({
|
||||
title:'Load sample data',
|
||||
message:'Replaces the SOP shown on this page with the fictional Micron sample and fills '
|
||||
+ 'the form with the example work package.\n\nThis page only: nothing is written to '
|
||||
+ 'the project unless you then save.',
|
||||
okLabel:'Load the sample'}))) return;
|
||||
loadSampleSOP();
|
||||
loadExample();
|
||||
}
|
||||
|
||||
function loadSampleSOP(){ SOP=JSON.parse(JSON.stringify(SAMPLE_SOP)); applySOP(); newPackage(); toast('Sample SOP loaded — ' + (SOP.project&&SOP.project.name||'project')); track('sample_loaded'); }
|
||||
function importSOP(ev){
|
||||
const f=ev.target.files&&ev.target.files[0]; if(!f) return; const r=new FileReader();
|
||||
@@ -531,7 +545,7 @@ function renderCtxBar(){
|
||||
if(!SOP){
|
||||
bar.innerHTML = activeProjectId
|
||||
? `<div class="ctx-empty">No SOP found for this project yet — complete the <strong>SOP Configuration</strong> first, then return here.</div>`
|
||||
: `<div class="ctx-empty">No SOP loaded — <button class="link-btn" onclick="loadSampleSOP()">load the sample</button> or import one from the Configuration tool.</div>`;
|
||||
: `<div class="ctx-empty">No SOP loaded — import one from the Configuration tool, or use <strong>Load sample data</strong> in the toolbar above.</div>`;
|
||||
return;
|
||||
}
|
||||
const p=SOP.project||{}, g=SOP.governance||{};
|
||||
|
||||
Reference in New Issue
Block a user