diff --git a/html/work-package-suite-app.js b/html/work-package-suite-app.js index c5faf2c..bc64b85 100644 --- a/html/work-package-suite-app.js +++ b/html/work-package-suite-app.js @@ -155,7 +155,7 @@ window.addEventListener('DOMContentLoaded',()=>{ // Deep-link: ?tab=sop | ?tab=wp | ?view=dashboard from the home page. const tab = params.get('tab'); - if(params.get('view') === 'dashboard') switchTool('wp'); + if(params.get('view') === 'dashboard') switchTool('dashboard'); else if(tab === 'wp' || tab === 'sop') switchTool(tab); track('app_open'); @@ -176,7 +176,15 @@ function initializeWPTypes(){ } // ── LOAD SAMPLE DATA ────────────────────────────────────────────────────────── +// Context-aware: on the SOP tab it loads the sample SOP; on the WP / Dashboard +// tab it loads the example Work Package inside the embedded creator. function loadSampleData(){ + if(currentTool && currentTool !== 'sop'){ + const f = document.getElementById('wp-frame'); + if(f && f.contentWindow && typeof f.contentWindow.loadExample === 'function'){ f.contentWindow.loadExample(); } + else { alert('Open the Work Package Creation tab first, then load the sample.'); } + return; + } // Populate Step 1 document.getElementById('proj_name').value = 'MICRON_PH1_CUP_HPM_FMCS INSTALL'; document.getElementById('proj_number').value = '26-67-008'; @@ -281,30 +289,32 @@ function repopulateForm(){ // ── TOOL SWITCHING ──────────────────────────────────────────────────────────── function switchTool(tool){ currentTool = tool; - + // 'dashboard' is a pseudo-tab: it reuses the WP tool's content (the embedded + // creator) but opens it straight to the dashboard view. + const isDash = (tool === 'dashboard'); + const contentTool = isDash ? 'wp' : tool; + // Update nav tabs document.querySelectorAll('.nav-tab').forEach(t=>t.classList.remove('active')); - document.querySelector(`[data-tab="${tool}"]`).classList.add('active'); - + const tabBtn = document.querySelector(`[data-tab="${tool}"]`); + if(tabBtn) tabBtn.classList.add('active'); + // Update content document.querySelectorAll('.tool').forEach(t=>t.classList.remove('active')); - document.getElementById(`tool-${tool}`).classList.add('active'); - - // Reset step counter - if(tool === 'sop'){ - document.getElementById('total-steps').textContent = '10'; - }else{ - document.getElementById('total-steps').textContent = '—'; - } + document.getElementById(`tool-${contentTool}`).classList.add('active'); - if(tool === 'wp') renderWPTab(); + // Reset step counter + document.getElementById('total-steps').textContent = (tool === 'sop') ? '10' : '—'; + + if(contentTool === 'wp') renderWPTab(isDash); updateStepUI(); updateProjectDisplay(); } // Show the gate or the embedded Work Package Creator depending on SOP status. -function renderWPTab(){ +// wantDash=true opens the creator straight to the dashboard view. +function renderWPTab(wantDash){ const gate = document.getElementById('wp-gate'); const frame = document.getElementById('wp-frame'); if(!gate || !frame) return; @@ -313,9 +323,9 @@ function renderWPTab(){ frame.style.display = 'block'; // Reload each time so the creator picks up the latest SOP from localStorage. const sp = new URLSearchParams(window.location.search); - const wantDash = sp.get('view') === 'dashboard'; + const dash = wantDash || sp.get('view') === 'dashboard'; const projId = sp.get('project') || (activeProject && activeProject.id) || ''; - frame.src = 'wp-creation-index.html?embedded=1' + (wantDash ? '&view=dashboard' : '') + frame.src = 'wp-creation-index.html?embedded=1' + (dash ? '&view=dashboard' : '') + (projId ? '&project=' + encodeURIComponent(projId) : '') + '&t=' + Date.now(); }else{ gate.style.display = 'block'; diff --git a/html/work-package-suite.html b/html/work-package-suite.html index cea153c..cdc26cd 100644 --- a/html/work-package-suite.html +++ b/html/work-package-suite.html @@ -22,7 +22,7 @@
- + 1 / 10 @@ -37,6 +37,9 @@ +
@@ -348,7 +351,7 @@
- +
diff --git a/html/wp-creation-app.js b/html/wp-creation-app.js index bdc2f21..68235f2 100644 --- a/html/wp-creation-app.js +++ b/html/wp-creation-app.js @@ -34,12 +34,12 @@ const STATUS_ORDER = ['Draft','Scheduled','Issued','In Progress','QC','Closed']; const ISSUED_IDX = STATUS_ORDER.indexOf('Issued'); // Acumatica cost codes (comment 10) — code|description -const COST_CODES = ['1000|Project Management','2000|Design and Development','2100|Design','2110|Control System Design','2120|Instrument Design','2130|Electrical Design','2140|Panel Design','2141|Panel Design Rework','2150|BIM','2151|BIM Rework','2160|Documentation','2200|Development','2210|PLC Programming','2220|OIT Programming','2230|SCADA Programming','2240|Simulation Development','2290|Programming Subcontract','2300|Customer Training','3000|Operational Technology','3100|OT Design','3200|Rack Assembly','3300|Network Configuration','3400|Computer Configuration','4000|Construction','4010|Instruments Install','4020|Network & Computers Install','4040|PLC Install','4050|Panel Install','4060|Electrical Install','4070|Mechanical Install','4080|Security Install','4090|Radio Install','4100|Commissioning','4940|Contract Labor','4960|Electrical Subcontract','4970|Mechanical Subcontract','4980|Security Subcontract','4990|Other/Radio Subcontract','5010|Instrument Material','5020|Network & Computers Material','5030|Software Material','5040|PLC Material','5050|Panel Material','5060|Electrical Material','5070|Mechanical Material','5080|Security Material','5090|Radio Material','6000|Production','7000|Quality','7100|Panel Quality Control','7200|Factory Acceptance Testing','7300|Site Acceptance Testing','8000|Safety','9000|Administration','9100|Warranty','9200|Freight','9300|Travel','9350|Jobsite Costs/Consumable/Other Direct Costs','9400|Contingency','9450|Other','9500|Accrued Incentive Compensation','9600|Sales Tax','9650|Job Cost Labor Burden','9700|Bonding','9800|Non-Billable Compensation']; +const COST_CODES = ['1000|Project Management','2000|Design and Development','2100|Design','2110|Control System Design','2120|Instrument Design','2130|Electrical Design','2140|Panel Design','2141|Panel Design Rework','2150|BIM','2151|BIM Rework','2160|Documentation','2200|Development','2210|PLC Programming','2220|OIT Programming','2230|SCADA Programming','2240|Simulation Development','2290|Programming Subcontract','2300|Customer Training','3000|Operational Technology','3100|OT Design','3200|Rack Assembly','3300|Network Configuration','3400|Computer Configuration','4000|Construction','4010|Instruments Install','4020|Network & Computers Install','4040|PLC Install','4050|Panel Install','4060|Electrical Install','4070|Mechanical Install','4080|Security Install','4090|Radio Install','4100|Commissioning','4940|Contract Labor','4960|Electrical Subcontract','4970|Mechanical Subcontract','4980|Security Subcontract','4990|Other/Radio Subcontract']; // Acumatica allowed units of measure (comment 15) — common first const ACU_UNITS = ['EA','EACH','FT','M','METER','HR','DAYS','MINUTE','KG','LITER','CASE','LOT','LS','PK','PACK','PALLET','PIECE','BOTTLE','CAN']; // Example built work package (comment 4 / "Load Example") — WP02 export -const EXAMPLE_PKG = {"number":"WP02-1P-ELEC-Conduit","status":"Issue","subject":"FAB 1P Horn Strobe Conduit","type":"Conduit Install","system":"Chilled Water","location":"FAB / LVL 1 / Sect P","cost":"4060","wbs":"2001","assignees":"David Velazquez (Catapult Solutions Group), Jesus Casiano-Figueroa (Prime Controls)","distribution":"Bill Clarida (Prime Controls), Sean Tolley (Prime Controls), Jefferson Dufriend (Prime Controls)","due":"2026-06-18","spec":"26_05_33_31 - Conduit","desc":"1P Conduit run for horns and strobes","assets":[{"tag":"1P-HS-NORTH","desc":"1P North horn/strobe circuit","link":"https://controls.dev/assets/1P-HS-NORTH"}],"work":"Layout conduit route\nUsing ladders and MEWP install conduit and boxes with proper strapping, supports, and pull points according to 2D drawings and 3D model. Reference package drawings included in attachments.\nWhen complete initiate inspection with Prime QAQC","workSteps":["Layout conduit route","Using ladders and MEWP install conduit and boxes with proper strapping, supports, and pull points according to 2D drawings and 3D model. Reference package drawings included in attachments.","When complete initiate inspection with Prime QAQC"],"numberDims":{"Sector":"1P","Discipline":"ELEC"},"hours":"60","seq":"Layout","materials":[{"qty":"400","unit":"FT","desc":"3/4\" EMT"},{"qty":"300","unit":"FT","desc":"1\" EMT"},{"qty":"50","unit":"FT","desc":"7/8\" strut"},{"qty":"50","unit":"FT","desc":"1-5/8\" strut"},{"qty":"8","unit":"EA","desc":"4x4x4 NEMA 3 Box"},{"qty":"2","unit":"EA","desc":"1\" C-Type Conduit Body"},{"qty":"1","unit":"EA","desc":"1\" T-Type Conduit Body"},{"qty":"2","unit":"EA","desc":"3/4\" C-Type Conduit Body"},{"qty":"2","unit":"EA","desc":"3/4\" T-Type Conduit Body"},{"qty":"3","unit":"EA","desc":"3/4\" EMT LB & Cover"},{"qty":"6","unit":"EA","desc":"Hoffman F44GCPNK Horn Strobe Box"},{"qty":"2","unit":"EA","desc":"EMO 2x4 Box"},{"qty":"4","unit":"EA","desc":"1\" Bond Bushing w/ Lug"},{"qty":"4","unit":"EA","desc":"3/4\" Bond Bushing w/ Lug"},{"qty":"50","unit":"EA","desc":"1/4\"x3\" Toggle Bolt"},{"qty":"100","unit":"EA","desc":"Drywall Anchor"},{"qty":"5","unit":"EA","desc":"1\" to 3/4\" threaded reducer"}],"attachments":[{"doc":"EE-1YA-2P-5_ HPM PANEL CALLOUT 05","rev":"0","link":"https://us02.procore.com/webclients/host/companies/562949953431440/projects/562949954073428/tools/document-viewer/prostore/562950644886790"}],"kitStatus":"Open","kitOwner":"Ian Spielburg","kitDate":"2026-06-15","mimoTime":"2026-06-11T10:30","mimoLoc":"04","constraints":[{"name":"Safety & Permitting","status":"cleared","comment":""},{"name":"Quality Control / Inspection","status":"cleared","comment":""},{"name":"IFC Drawings & Specs","status":"cleared","comment":""},{"name":"Schedule","status":"cleared","comment":""},{"name":"Materials (on site, bagged & tagged)","status":"cleared","comment":""},{"name":"Prefabrication","status":"cleared","comment":""},{"name":"Work Access & Laydown","status":"cleared","comment":""},{"name":"Craft Availability","status":"cleared","comment":""},{"name":"Construction Equipment & Tools","status":"open","comment":"Boom lift not yet on site"},{"name":"Scaffolding / Access Equipment","status":"cleared","comment":""}],"qc":"Yes — Detailed inspection items","photo":"Key checkpoints only","hold":"HOLD: Prime QAQC to inspect rough-in before cover/cover-up. WITNESS: client QC to observe megger / insulation-resistance test before energization.","overrides":{"wp_photo":"Change Order"},"signoffs":[{"role":"Planner","name":"L. Graver","date":"2026-06-10","signed":true,"dateReason":""},{"role":"Superintendent","name":"K. Boyd","date":"2026-06-10","signed":true,"dateReason":""},{"role":"HSE Professional","name":"A. Reyes","date":"","signed":false,"dateReason":""},{"role":"Quality Representative","name":"D. Nguyen","date":"","signed":false,"dateReason":""},{"role":"Work Foreman","name":"M. Torres","date":"","signed":false,"dateReason":""}],"holds":[],"actualHrs":"54","installedQty":"200 ft","redlines":"Conduit size changed. need to update model","lessons":"Prepping trapeze hangers with conduit straps saved time","project":"Micron — INC Construction Work Packages","track":"CxAlloy"}; +const EXAMPLE_PKG = {"number":"WP02-1P-ELEC-Conduit","status":"Issue","subject":"FAB 1P Horn Strobe Conduit","type":"Conduit Install","system":"Chilled Water","location":"FAB / LVL 1 / Sect P","cost":"4060","wbs":"2001","assignees":"David Velazquez (Catapult Solutions Group), Jesus Casiano-Figueroa (Prime Controls)","distribution":"Sean Tolley (Prime Controls), Jefferson Dufriend (Prime Controls)","due":"2026-06-18","spec":"26_05_33_31 - Conduit","desc":"1P Conduit run for horns and strobes","assets":[{"tag":"1P-HS-NORTH","desc":"1P North horn/strobe circuit","link":"https://controls.dev/assets/1P-HS-NORTH"}],"work":"Layout conduit route\nUsing ladders and MEWP install conduit and boxes with proper strapping, supports, and pull points according to 2D drawings and 3D model. Reference package drawings included in attachments.\nWhen complete initiate inspection with Prime QAQC","workSteps":["Layout conduit route","Using ladders and MEWP install conduit and boxes with proper strapping, supports, and pull points according to 2D drawings and 3D model. Reference package drawings included in attachments.","When complete initiate inspection with Prime QAQC"],"numberDims":{"Sector":"1P","Discipline":"ELEC"},"hours":"60","seq":"Layout","materials":[{"qty":"400","unit":"FT","desc":"3/4\" EMT"},{"qty":"300","unit":"FT","desc":"1\" EMT"},{"qty":"50","unit":"FT","desc":"7/8\" strut"},{"qty":"50","unit":"FT","desc":"1-5/8\" strut"},{"qty":"8","unit":"EA","desc":"4x4x4 NEMA 3 Box"},{"qty":"2","unit":"EA","desc":"1\" C-Type Conduit Body"},{"qty":"1","unit":"EA","desc":"1\" T-Type Conduit Body"},{"qty":"2","unit":"EA","desc":"3/4\" C-Type Conduit Body"},{"qty":"2","unit":"EA","desc":"3/4\" T-Type Conduit Body"},{"qty":"3","unit":"EA","desc":"3/4\" EMT LB & Cover"},{"qty":"6","unit":"EA","desc":"Hoffman F44GCPNK Horn Strobe Box"},{"qty":"2","unit":"EA","desc":"EMO 2x4 Box"},{"qty":"4","unit":"EA","desc":"1\" Bond Bushing w/ Lug"},{"qty":"4","unit":"EA","desc":"3/4\" Bond Bushing w/ Lug"},{"qty":"50","unit":"EA","desc":"1/4\"x3\" Toggle Bolt"},{"qty":"100","unit":"EA","desc":"Drywall Anchor"},{"qty":"5","unit":"EA","desc":"1\" to 3/4\" threaded reducer"}],"attachments":[{"doc":"EE-1YA-2P-5_ HPM PANEL CALLOUT 05","rev":"0","link":"https://us02.procore.com/webclients/host/companies/562949953431440/projects/562949954073428/tools/document-viewer/prostore/562950644886790"}],"kitStatus":"Open","kitOwner":"Ian Spielburg","kitDate":"2026-06-15","mimoTime":"2026-06-11T10:30","mimoLoc":"04","constraints":[{"name":"Safety & Permitting","status":"cleared","comment":""},{"name":"Quality Control / Inspection","status":"cleared","comment":""},{"name":"IFC Drawings & Specs","status":"cleared","comment":""},{"name":"Schedule","status":"cleared","comment":""},{"name":"Materials (on site, bagged & tagged)","status":"cleared","comment":""},{"name":"Prefabrication","status":"cleared","comment":""},{"name":"Work Access & Laydown","status":"cleared","comment":""},{"name":"Craft Availability","status":"cleared","comment":""},{"name":"Construction Equipment & Tools","status":"open","comment":"Boom lift not yet on site"},{"name":"Scaffolding / Access Equipment","status":"cleared","comment":""}],"qc":"Yes — Detailed inspection items","photo":"Key checkpoints only","hold":"HOLD: Prime QAQC to inspect rough-in before cover/cover-up. WITNESS: client QC to observe megger / insulation-resistance test before energization.","overrides":{"wp_photo":"Change Order"},"signoffs":[{"role":"Planner","name":"L. Graver","date":"2026-06-10","signed":true,"dateReason":""},{"role":"Superintendent","name":"K. Boyd","date":"2026-06-10","signed":true,"dateReason":""},{"role":"HSE Professional","name":"A. Reyes","date":"","signed":false,"dateReason":""},{"role":"Quality Representative","name":"D. Nguyen","date":"","signed":false,"dateReason":""},{"role":"Work Foreman","name":"M. Torres","date":"","signed":false,"dateReason":""}],"holds":[],"actualHrs":"54","installedQty":"200 ft","redlines":"Conduit size changed. need to update model","lessons":"Prepping trapeze hangers with conduit straps saved time","project":"Micron — INC Construction Work Packages","track":"CxAlloy"}; // ── STATE ──────────────────────────────────────────────────────────────────── let SOP=null, editingId=null, numberDirty=false; @@ -830,6 +830,36 @@ function renderConstraintRows(){ const tmp=pkgConstraints; pkgConstraints=[]; bu buildConstraints(); } function renderSignoffRows(){ const tmp=pkgSignoffs; pkgSignoffs=[]; buildSignoffs(); tmp.forEach(s=>{ const c=pkgSignoffs.find(x=>x.role===s.role); if(c){ c.name=s.name; c.date=s.date; c.signed=s.signed; c.dateReason=s.dateReason||''; }}); buildSignoffs(); } +// Duplicate the current work package N times (asks how many). Each copy is a +// fresh Draft with a unique number/subject and approvals/closeout cleared. +function duplicateWP(){ + if(!gv('wp_subject')){ alert('Open or fill in a work package first, then Duplicate.'); return; } + const ans=prompt('How many copies of this work package do you want to create?','1'); + if(ans===null) return; + const n=parseInt(ans,10); + if(!n || n<1 || n>50){ alert('Enter a whole number between 1 and 50.'); return; } + const base=collectPackage(); + const baseNum = base.number || ('WP'+pad2(editingSeq())); + const made=[]; + for(let i=1;i<=n;i++){ + const c=JSON.parse(JSON.stringify(base)); + c.id='wp_'+Date.now().toString(36)+Math.random().toString(36).slice(2,5)+i; + c.number = baseNum + '-C' + i; + c.subject = base.subject + (n>1 ? ' (copy '+i+')' : ' (copy)'); + c.status='Draft'; + c.instanceOf=undefined; c.instanceLabel=undefined; c.parentNumber=undefined; c.split=undefined; c.children=undefined; + if(Array.isArray(c.signoffs)) c.signoffs=c.signoffs.map(s=>({...s, signed:false, date:'', dateReason:''})); + c.holds=[]; c.actualHrs=''; c.installedQty=''; c.redlines=''; c.lessons=''; + c.projectId = base.projectId || activeProjectId || ''; + c.updatedAt=new Date().toISOString(); + savedPackages.push(c); made.push(c); + } + editingId=null; saveStore(); renderSavedList(); + toast('Created '+n+' duplicate'+(n>1?'s':'')); + track('wp_duplicated',{count:n}); + alert('Created '+n+' duplicate'+(n>1?'s':'')+':\n\n• '+made.map(m=>m.number).join('\n• ')+'\n\nThey are in the Saved Work Packages list — edit each as needed.'); +} + function newPackage(){ editingId=null; ['wp_subject','wp_system','wp_location','wp_wbs','wp_assignees','wp_distribution','wp_due','wp_spec','wp_desc','wp_hours','wp_kit_owner','wp_kit_date','wp_mimo_time','wp_mimo_loc','wp_actual_hrs','wp_installed_qty','wp_redlines','wp_lessons'].forEach(id=>{const el=document.getElementById(id); if(el) el.value='';}); diff --git a/html/wp-creation-index.html b/html/wp-creation-index.html index 846c12f..e684e1e 100644 --- a/html/wp-creation-index.html +++ b/html/wp-creation-index.html @@ -13,21 +13,22 @@
Saving work package…
-
+
-
|
+
|
Work Package (IWP)
- - - - - - + + + + + + +