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:
@@ -391,95 +391,14 @@ function initializeWPTypes(){
|
||||
}
|
||||
|
||||
// ── LOAD SAMPLE DATA ──────────────────────────────────────────────────────────
|
||||
// This page's sample is the sample SOP. It used to reach into the frame and call
|
||||
// the creator's loadExample() when the WP tab was open; the creator is its own
|
||||
// page since T7.1 and carries its own sample controls in its toolbar (D1), so
|
||||
// there is nothing to reach into and nothing to duplicate here.
|
||||
//
|
||||
// S7 still counts more sample affordances than it should. T9.4 reduces them; this
|
||||
// task only stops one of them pretending to belong to a document it is not in.
|
||||
function loadSampleData(){
|
||||
if(currentTool && currentTool !== 'sop'){
|
||||
wizardToast('The work package sample is on the Work Package Creation page, in its toolbar.',
|
||||
{role: 'status'});
|
||||
return;
|
||||
}
|
||||
// Populate Step 1
|
||||
document.getElementById('proj_name').value = 'MICRON_PH1_CUP_HPM_FMCS INSTALL';
|
||||
document.getElementById('proj_number').value = '26-67-008';
|
||||
document.getElementById('proj_client').value = 'Micron Technology, Inc.';
|
||||
document.getElementById('proj_division').value = 'Semiconductor';
|
||||
document.getElementById('proj_site').value = 'Boise, ID — Fab 7';
|
||||
// Removed at T9.4 (S7). This was the affordance one click from live project
|
||||
// data: it filled the wizard state that completeSOP() pushes to the PROJECT,
|
||||
// with no confirm and no undo. The suite's one sample control lives on the
|
||||
// creator's toolbar, where it fills that page only. The location and material
|
||||
// list steps keep their "Load sample values" buttons - those fill a PASTE BOX
|
||||
// that acts only through an explicit, dry-runnable Import, which is a
|
||||
// different thing from loading sample data into a live configuration.
|
||||
|
||||
// Populate Step 2. The leadership slots are account pickers now, so the sample's
|
||||
// fictional names can't be "selected" — setting .value on a <select> with no
|
||||
// matching option silently does nothing. Store them as names without an account,
|
||||
// which is exactly how the picker shows a person who isn't a suite user yet.
|
||||
state.team.pm = 'Mariano Sanchez';
|
||||
state.team.apm = 'Assistant PM';
|
||||
state.team.cm = 'K. Boyd';
|
||||
state.team.qm = 'D. Nguyen';
|
||||
state.teamIds = {pm:'', apm:'', cm:'', qm:''};
|
||||
state.qaGroupIds = [];
|
||||
renderTeamPickers();
|
||||
|
||||
// Step 3 — standard required roles
|
||||
if(state.signoffRoles[0]) state.signoffRoles[0].role = 'Superintendent';
|
||||
if(state.signoffRoles[1]) state.signoffRoles[1].role = 'Foreman';
|
||||
const stEl = document.getElementById('role_super_title'); if(stEl) stEl.value = 'Superintendent';
|
||||
const ftEl = document.getElementById('role_foreman_title'); if(ftEl) ftEl.value = 'Foreman';
|
||||
state.signoffRoles[0].name = 'John Smith'; state.signoffRoles[0].userId = '';
|
||||
state.signoffRoles[1].name = 'Mike Jones'; state.signoffRoles[1].userId = '';
|
||||
renderSignoffRolePickers();
|
||||
|
||||
// Populate Step 5
|
||||
document.getElementById('gov_woformat').value = 'WP##-[Sector]-[TYPE]';
|
||||
document.getElementById('gov_wosize').value = 'Standard — 3–5 days (≈40–80 hrs)';
|
||||
document.getElementById('gov_disciplines').value = 'Mechanical, Electrical, Tech';
|
||||
document.getElementById('gov_discmode').value = 'choice';
|
||||
document.getElementById('gov_size_hours_max').value = '80';
|
||||
|
||||
// Populate Step 6
|
||||
document.getElementById('qual_qcreq').value = 'Yes — Detailed inspection items';
|
||||
document.getElementById('qual_photo').value = 'Key checkpoints only';
|
||||
document.getElementById('qual_hold').value = 'HOLD: Prime QAQC to inspect rough-in before cover/cover-up.\nWITNESS: Client QC to observe megger test before energization.';
|
||||
|
||||
// Step 7 already has defaults
|
||||
|
||||
// CR-016 / T5.7. The sample is the Micron EUV configuration, and Micron does not
|
||||
// use Assets: its content duplicates the database Clinton's team maintains, and
|
||||
// that integration is deferred. Off by toggle, so the section and its model stay
|
||||
// in the application for the integration to land in — and any other project can
|
||||
// turn it back on from step 12 without a code change.
|
||||
//
|
||||
// A partial map on purpose. WPSections.normalize fills the rest in as ON, so a
|
||||
// section added after today is not silently off for this SOP.
|
||||
if(typeof WPSections !== 'undefined'){
|
||||
state.sections = WPSections.normalize({assets: false, kitting: false}); // CR-009: Micron EUV is not kitting today
|
||||
state.fields = WPSections.normalizeFields({costCode: false, acumaticaTask: false}); // CR-002, mirrored on the export (T9.1)
|
||||
}
|
||||
|
||||
// The Micron FMCS sample includes BIM/VDC — enable it so the sequence shows the
|
||||
// full BIM → construction flow (BIM steps first) and the Creator offers IWP/EWP.
|
||||
state.bimEnabled = true;
|
||||
const beEl = document.getElementById('bim_enabled'); if(beEl) beEl.checked = true;
|
||||
enableBIM();
|
||||
|
||||
// Collect all data
|
||||
collectStepData();
|
||||
track('sample_loaded');
|
||||
|
||||
wizardToast('Sample data loaded. Every step now holds example values — edit or replace any of them.');
|
||||
|
||||
// Switch to step 1. Every step now holds sample content, so the rail marks them
|
||||
// all as visited — otherwise a fully populated wizard shows ten unstarted steps.
|
||||
for(let i = 1; i <= LAST_STEP; i++) _visitedSteps.add(i);
|
||||
currentStep = 1;
|
||||
updateStepUI();
|
||||
updateProjectDisplay();
|
||||
}
|
||||
|
||||
// ── RESTORE A COMPLETED SOP (for "Review" + WP tab across reloads) ─────────────
|
||||
function restoreSavedSOP(){
|
||||
let savedState = null, savedSop = null, complete = false;
|
||||
try {
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button id="load-sample-btn" class="header-button" onclick="loadSampleData()" title="Load sample data for the current tool (SOP or Work Package)">Load sample</button>
|
||||
<button class="header-button" onclick="toggleComments()" title="Leave feedback for the current step">Feedback</button>
|
||||
<button class="header-button" onclick="openHelp()" title="How the suite works + key concepts">Help</button>
|
||||
<!-- A4/S9: the orphaned "1 / 10" counter lived here. It is retired — the
|
||||
|
||||
@@ -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||{};
|
||||
|
||||
@@ -84,12 +84,15 @@
|
||||
<button class="btn btn-ghost" onclick="openSopModal()">View SOP</button>
|
||||
<button class="btn btn-ghost" onclick="document.getElementById('sop-import').click()">Import SOP</button>
|
||||
<input type="file" id="sop-import" accept="application/json" style="display:none" onchange="importSOP(event)">
|
||||
<button class="btn btn-ghost" onclick="loadSampleSOP()">Sample SOP</button>
|
||||
<button class="btn btn-ghost" onclick="loadExample()">Load example</button>
|
||||
<span class="wp-toolbar-sep" aria-hidden="true"></span>
|
||||
<!-- T7.10 moves this to the admin console and deletes one of the two
|
||||
implementations. It stays visible here until then rather than being
|
||||
deleted by the task that dissolved the frame. -->
|
||||
<!-- S7 / T9.4: THE sample-data affordance - exactly one in the whole suite,
|
||||
under one name. Pushed to the far end, away from the live actions (New /
|
||||
Duplicate sit at the other side of two separators), it confirms before
|
||||
acting and names exactly what it does. It fills THIS PAGE only: nothing
|
||||
is written to the project unless the user then saves, which the probe
|
||||
verifies against a real project. The wizard's copy and the split
|
||||
Sample SOP / Load example pair are gone. -->
|
||||
<span class="wp-toolbar-sep" aria-hidden="true" style="margin-left:auto"></span>
|
||||
<button class="btn btn-ghost" onclick="loadSampleAll()">Load sample data</button>
|
||||
</div>
|
||||
|
||||
<div class="dev-banner" id="dev-banner" style="display:none">⚙ DEV MODE — usage tracking paused. This session's actions are not being recorded.</div>
|
||||
|
||||
Reference in New Issue
Block a user