BIM as a per-package kind; one project flows BIM -> construction
Replace the whole-project BIM 'mode' with an opt-in capability + a per-package kind, so a single project can produce both model and install packages (and install-only projects are unaffected). SOP tool: - Step 4 "Include BIM / VDC work packages" checkbox (state.bimEnabled). Enabling adds BIM package types + BIM release gates (flagged bim) plus BIM roles/sources/process steps alongside the construction defaults; disabling strips the bim-flagged items. - Generated SOP carries bimEnabled and a per-type / per-constraint bim flag. - Required sign-off role titles stay editable (no longer force-renamed). Work Package Creator: - Shows a Package Type selector (Install IWP / BIM EWP) only when the SOP has bimEnabled; kind is saved per package and labeled in the output. - WP types and release gates are filtered by kind (BIM types+gates for EWP, install types+gates for IWP). - EWP reveals the BIM Details card and hides controls.dev Assets / Materials / Kitting-MIMO; IWP shows those plus the "Enabled by - BIM package" traceability link. Supersedes the earlier whole-project BIM mode. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,7 @@ function onSizePresetChange(){
|
||||
}
|
||||
|
||||
let state = {
|
||||
mode: 'standard', // 'standard' (field IWP) | 'bim' (BIM/VDC EWP) — set by the BIM template
|
||||
bimEnabled: false, // does this project also produce BIM/VDC packages? If so the Creator tags each WP Install (IWP) or BIM (EWP); if not, it's IWP-only.
|
||||
project: {name:'', number:'', client:'', division:'', site:''},
|
||||
team: {pm:'', apm:'', cm:'', qm:''},
|
||||
teamMembers: [],
|
||||
@@ -148,8 +148,9 @@ const LABOR_COST_CODES = [
|
||||
// ── BIM / VDC TEMPLATE ──────────────────────────────────────────────────────────
|
||||
// The BIM/VDC department also produces work packages under Advanced Work Packaging —
|
||||
// model & engineering deliverables (EWPs) that feed the field's install packages.
|
||||
// These defaults are drawn from the EN06 SOP + work instructions and are applied by
|
||||
// loadBIMTemplate() (the "Load BIM / VDC template" button on Step 4). Everything
|
||||
// These defaults are drawn from the EN06 SOP + work instructions and are added by
|
||||
// enableBIM() when the "Include BIM / VDC work packages" box is ticked on Step 4
|
||||
// (each is flagged bim so the Creator can offer them under the EWP kind). Everything
|
||||
// remains editable afterward.
|
||||
const BIM_WP_TYPES = [
|
||||
'Model Area Package', 'Conduit Routing Package', 'Coordination / Clash Package',
|
||||
@@ -196,48 +197,43 @@ const BIM_SOURCES = [
|
||||
{label:'Constructability Review Sheet (CRS)', ph:'SharePoint'}
|
||||
];
|
||||
|
||||
function loadBIMTemplate(){
|
||||
if(!confirm('Load the BIM / VDC template?\n\nThis sets the WP types, release-gate constraints, sign-off roles, construction sequence, reference sources, disciplines (install phases) and numbering format to BIM/VDC defaults from the EN06 SOPs. Your project details (Step 1) and team (Step 2) are left alone, and you can edit everything afterward.')) return;
|
||||
|
||||
state.mode = 'bim'; // flags the Creator to show BIM fields / hide field-only sections
|
||||
|
||||
// Step 4 — deliverable package types
|
||||
state.wpTypes = BIM_WP_TYPES.map(n => ({name:n, enabled:true, notes:'', approval:''}));
|
||||
// Toggle BIM/VDC capability on the project. ON augments the SOP with BIM package
|
||||
// types + release gates (flagged bim) plus BIM roles/sources/sequence steps, so the
|
||||
// project produces both install (IWP) and BIM (EWP) packages. OFF strips the
|
||||
// bim-flagged items. Everything stays editable.
|
||||
function setBimEnabled(on){
|
||||
state.bimEnabled = !!on;
|
||||
if(on) enableBIM(); else disableBIM();
|
||||
const cb = document.getElementById('bim_enabled'); if(cb) cb.checked = !!on;
|
||||
track(on ? 'bim_enabled' : 'bim_disabled');
|
||||
}
|
||||
function enableBIM(){
|
||||
// Package types (flagged bim so the Creator can offer them under "BIM (EWP)").
|
||||
BIM_WP_TYPES.forEach(n => {
|
||||
const t = state.wpTypes.find(x => x.name === n);
|
||||
if(t){ t.bim = true; t.enabled = true; }
|
||||
else state.wpTypes.push({name:n, enabled:true, notes:'', approval:'', bim:true});
|
||||
});
|
||||
renderWPTypes();
|
||||
|
||||
// Step 5 — disciplines become install phases; multi-discipline; model numbering
|
||||
state.governance.disciplines = BIM_PHASES.slice();
|
||||
state.governance.discMode = 'multi';
|
||||
state.governance.woformat = 'MWP##-[Area]-[PHASE]';
|
||||
const setVal = (id, v) => { const el = document.getElementById(id); if(el) el.value = v; };
|
||||
setVal('gov_disciplines', BIM_PHASES.join(', '));
|
||||
setVal('gov_discmode', 'multi');
|
||||
setVal('gov_woformat', 'MWP##-[Area]-[PHASE]');
|
||||
|
||||
// Step 3 — set the two required roles to BIM titles, then add the rest as optional
|
||||
state.signoffRoles[0] = {role:'BIM Coordinator', name: (state.signoffRoles[0] && state.signoffRoles[0].name) || ''};
|
||||
state.signoffRoles[1] = {role:'Construction Lead (CRS)', name: (state.signoffRoles[1] && state.signoffRoles[1].name) || ''};
|
||||
setVal('role_super_title', 'BIM Coordinator');
|
||||
setVal('role_foreman_title', 'Construction Lead (CRS)');
|
||||
BIM_TEMPLATE_ROLES.filter(r => r !== 'BIM Coordinator' && r !== 'Construction Lead (CRS)')
|
||||
.forEach(r => { if(!state.signoffRoles.some(x => x.role === r)) state.signoffRoles.push({role:r, name:''}); });
|
||||
renderOptionalRoles();
|
||||
|
||||
// Step 9 — BIM release-gate constraints (replaces the field's standard 10)
|
||||
state.constraints = BIM_CONSTRAINTS.map(c => ({...c}));
|
||||
// Release-gate constraints (seed standard 10 first if empty, then add BIM gates).
|
||||
if(!state.constraints || !state.constraints.length) state.constraints = STANDARD_10_CONSTRAINTS.map(c => ({...c}));
|
||||
_constraintsSeeded = true;
|
||||
BIM_CONSTRAINTS.forEach(c => { if(!state.constraints.some(x => x.name === c.name)) state.constraints.push({...c, bim:true}); });
|
||||
renderStandardConstraints();
|
||||
|
||||
// Step 8 — BIM process sequence
|
||||
state.sequence = BIM_SEQUENCE.map(s => ({label:s, kind:'step'}));
|
||||
// BIM sign-off roles (optional), reference sources, and process steps (idempotent).
|
||||
BIM_TEMPLATE_ROLES.forEach(r => { if(!state.signoffRoles.some(x => x.role === r)) state.signoffRoles.push({role:r, name:'', bim:true}); });
|
||||
renderOptionalRoles();
|
||||
BIM_SEQUENCE.forEach(lbl => { if(!state.sequence.some(s => s.label === lbl)) state.sequence.push({label:lbl, kind:'step', bim:true}); });
|
||||
renderSequenceSteps();
|
||||
|
||||
// Step 10 — reference sources
|
||||
state.sources = BIM_SOURCES.map(s => ({label:s.label, system:'', notes:'', link:'', ph:s.ph, preset:true}));
|
||||
BIM_SOURCES.forEach(s => { if(!state.sources.some(x => x.label === s.label)) state.sources.push({label:s.label, system:'', notes:'', link:'', ph:s.ph, preset:true, bim:true}); });
|
||||
renderSources();
|
||||
|
||||
track('bim_template_loaded');
|
||||
alert('BIM / VDC template loaded.\n\nReview Step 5 (disciplines are now the install phases; numbering = MWP##-[Area]-[PHASE]) and Step 3 (BIM Coordinator + Construction Lead were added; leave the built-in Superintendent/Foreman blank if not used). Adjust anything as needed, then finish the SOP.');
|
||||
}
|
||||
function disableBIM(){
|
||||
state.wpTypes = state.wpTypes.filter(t => !t.bim); renderWPTypes();
|
||||
state.constraints = (state.constraints || []).filter(c => !c.bim); renderStandardConstraints();
|
||||
state.signoffRoles = state.signoffRoles.filter((r,i) => i < 2 || !r.bim); renderOptionalRoles();
|
||||
state.sequence = (state.sequence || []).filter(s => !s.bim); renderSequenceSteps();
|
||||
state.sources = (state.sources || []).filter(s => !s.bim); renderSources();
|
||||
}
|
||||
|
||||
// ── INITIALIZATION ────────────────────────────────────────────────────────────
|
||||
@@ -307,8 +303,9 @@ function loadSampleData(){
|
||||
document.getElementById('proj_cm').value = 'K. Boyd';
|
||||
document.getElementById('proj_qm').value = 'D. Nguyen';
|
||||
|
||||
// Step 3 — standard required roles
|
||||
state.mode = 'standard';
|
||||
// Step 3 — standard required roles (sample is an install-only project)
|
||||
state.bimEnabled = false;
|
||||
const beEl = document.getElementById('bim_enabled'); if(beEl) beEl.checked = false;
|
||||
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';
|
||||
@@ -400,6 +397,7 @@ function repopulateForm(){
|
||||
set('plat_commissioning', state.platforms.commissioning);
|
||||
set('plat_tracking_url', state.platforms.trackingUrl);
|
||||
set('plat_commissioning_url', state.platforms.commissioningUrl);
|
||||
const beEl = document.getElementById('bim_enabled'); if(beEl) beEl.checked = !!state.bimEnabled;
|
||||
}
|
||||
|
||||
// ── TOOL SWITCHING ────────────────────────────────────────────────────────────
|
||||
@@ -522,9 +520,8 @@ function renderWPTypes(){
|
||||
container.appendChild(row);
|
||||
});
|
||||
const addRow = document.createElement('div');
|
||||
addRow.style.cssText = 'margin-top:0.85rem; display:flex; gap:0.5rem; flex-wrap:wrap;';
|
||||
addRow.innerHTML = `<button onclick="addCustomWPType()" style="background:var(--primary,#0f62fe); color:#fff; border:none; padding:0.55rem 1rem; border-radius:4px; font-weight:600; cursor:pointer; font-size:13px;">+ Add Custom Type</button>
|
||||
<button onclick="loadBIMTemplate()" title="Configure this SOP for the BIM / VDC team's model & engineering work packages" style="background:var(--bg); color:var(--text); border:1px solid var(--border); padding:0.55rem 1rem; border-radius:4px; font-weight:600; cursor:pointer; font-size:13px;">Load BIM / VDC template</button>`;
|
||||
addRow.style.cssText = 'margin-top:0.85rem;';
|
||||
addRow.innerHTML = `<button onclick="addCustomWPType()" style="background:var(--primary,#0f62fe); color:#fff; border:none; padding:0.55rem 1rem; border-radius:4px; font-weight:600; cursor:pointer; font-size:13px;">+ Add Custom Type</button>`;
|
||||
container.appendChild(addRow);
|
||||
}
|
||||
|
||||
@@ -900,7 +897,7 @@ function completeSOP(){
|
||||
|
||||
sop = {
|
||||
meta: {tool:'Work Package Configuration', sample:false},
|
||||
mode: state.mode || 'standard', // 'bim' hides field-only sections + shows BIM fields in the Creator
|
||||
bimEnabled: !!state.bimEnabled, // project also produces BIM (EWP) packages → Creator offers per-package IWP/EWP kind
|
||||
project: {
|
||||
name: state.project.name,
|
||||
number: state.project.number,
|
||||
@@ -928,7 +925,8 @@ function completeSOP(){
|
||||
name: t.name.trim(),
|
||||
enabled: true,
|
||||
notes: t.notes || '',
|
||||
approval: t.approval || ''
|
||||
approval: t.approval || '',
|
||||
bim: !!t.bim
|
||||
})),
|
||||
sources: state.sources.filter(s=>s.label),
|
||||
field: {trackPlatform: state.platforms.tracking, trackPlatformUrl: state.platforms.trackingUrl || ''},
|
||||
@@ -950,7 +948,7 @@ function completeSOP(){
|
||||
kind: s.kind || 'step'
|
||||
})),
|
||||
costCodes: LABOR_COST_CODES,
|
||||
constraints: state.constraints.map(c=>({name: c.name, description: c.description || ''}))
|
||||
constraints: state.constraints.map(c=>({name: c.name, description: c.description || '', bim: !!c.bim}))
|
||||
};
|
||||
|
||||
sopComplete = true;
|
||||
|
||||
@@ -158,6 +158,11 @@
|
||||
<div class="step" id="sop-step-4" style="display: none;">
|
||||
<h2>4. Work Package Types</h2>
|
||||
<div class="notice">Enable the WP types your project will use. Add any special rules and the roles required to approve WO completion.</div>
|
||||
<label style="display:flex; align-items:flex-start; gap:0.6rem; padding:0.85rem 1rem; background:var(--bg); border:1px solid var(--border); border-radius:6px; margin:0 0 1rem; cursor:pointer;">
|
||||
<input type="checkbox" id="bim_enabled" onchange="setBimEnabled(this.checked)" style="width:18px; height:18px; margin-top:2px; flex:none;">
|
||||
<span><strong>Include BIM / VDC work packages on this project</strong><br>
|
||||
<span style="color:var(--text-dim); font-size:12px;">Adds model/engineering package types & release gates. In the Creator each package is then tagged <strong>Install (IWP)</strong> or <strong>BIM (EWP)</strong>, so the project can flow from BIM into construction. Leave off for install-only projects.</span></span>
|
||||
</label>
|
||||
<div id="wp-types-table" style="margin-top: 1.5rem;"></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ const EXAMPLE_PKG = {"number":"WP02-1P-ELEC-Conduit","status":"Issue","subject":
|
||||
|
||||
// ── STATE ────────────────────────────────────────────────────────────────────
|
||||
let SOP=null, editingId=null, numberDirty=false;
|
||||
let pkgKind='iwp'; // 'iwp' (install) | 'ewp' (BIM) — per-package, only relevant when SOP.bimEnabled
|
||||
let activeProjectId=''; // set at boot from ?project=<id>; stamped onto saved WPs for the API
|
||||
let pkgMaterials=[], pkgAttach=[], pkgConstraints=[], pkgSignoffs=[], pkgHolds=[], pkgWorkSteps=[], pkgAssets=[];
|
||||
let pkgOverrides={}; // {fieldId: reason} for SOP-locked fields that were edited
|
||||
@@ -67,7 +68,12 @@ function toast(msg){ let t=document.getElementById('toast'); if(!t){ t=document.
|
||||
function getRadio(name){ const s=document.querySelector(`.radio-pill.selected input[name="${name}"]`); return s?.closest('.radio-pill')?.dataset?.val||''; }
|
||||
function setRadio(name,val){ document.querySelectorAll(`.radio-pill input[name="${name}"]`).forEach(i=>{const p=i.closest('.radio-pill'); const on=p.dataset.val===val; p.classList.toggle('selected',on); i.checked=on;}); }
|
||||
function enabledTypes(){ return ((SOP&&SOP.woTypes)||[]).filter(t=>t.enabled!==false); }
|
||||
function constraintNames(){ return (SOP&&Array.isArray(SOP.constraints)&&SOP.constraints.length)?SOP.constraints:DEFAULT_CONSTRAINTS; }
|
||||
function constraintNames(){
|
||||
let cs = (SOP&&Array.isArray(SOP.constraints)&&SOP.constraints.length)?SOP.constraints:DEFAULT_CONSTRAINTS;
|
||||
// On a BIM-enabled project, EWPs use the BIM gates and IWPs use the install gates.
|
||||
if(bimSOP()) cs = cs.filter(c => (c && typeof c==='object') ? (isEwp() ? c.bim : !c.bim) : !isEwp());
|
||||
return cs;
|
||||
}
|
||||
function nextSeq(){ return savedPackages.length+1; }
|
||||
|
||||
// ── SOP LOADING ──────────────────────────────────────────────────────────────
|
||||
@@ -92,23 +98,38 @@ function applySOP(){
|
||||
lockQuality('wp_qc'); lockQuality('wp_photo'); lockQuality('wp_hold');
|
||||
const hint=document.getElementById('wp_number_hint'); hint.textContent = SOP.governance&&SOP.governance.woFormat ? 'auto-built · format: '+SOP.governance.woFormat : '';
|
||||
buildConstraints(); buildSignoffs();
|
||||
applyBimMode();
|
||||
applyKind();
|
||||
if(!pkgMaterials.length){ pkgMaterials=[{qty:'',unit:'',desc:''}]; buildMaterials(); }
|
||||
if(!pkgAttach.length){ pkgAttach=[{doc:'',rev:'',link:''}]; buildAttach(); }
|
||||
if(!pkgAssets.length){ pkgAssets=[{tag:'',desc:'',link:''}]; buildAssets(); }
|
||||
if(!pkgWorkSteps.length){ pkgWorkSteps=['']; buildWorkSteps(); }
|
||||
updateNumber(); updateReleaseBanner();
|
||||
}
|
||||
// In a BIM/VDC SOP, hide the field-only sections (controls.dev assets, materials,
|
||||
// kitting/MIMO) and reveal the BIM Details card. Driven by SOP.mode==='bim'.
|
||||
function isBimSOP(){ return !!(SOP && SOP.mode === 'bim'); }
|
||||
function applyBimMode(){
|
||||
const bim = isBimSOP();
|
||||
// Per-package kind. A project whose SOP has bimEnabled produces both install (IWP)
|
||||
// and BIM (EWP) packages; the kind selector tailors which fields, WP types, and
|
||||
// release gates apply. Install-only projects never show the selector.
|
||||
function bimSOP(){ return !!(SOP && SOP.bimEnabled); }
|
||||
function isEwp(){ return bimSOP() && pkgKind === 'ewp'; }
|
||||
function setKind(k){
|
||||
if(pkgKind === k) return;
|
||||
pkgKind = (k === 'ewp') ? 'ewp' : 'iwp';
|
||||
const tEl = document.getElementById('wp_type'); if(tEl) tEl.value = ''; // type list changes with kind
|
||||
applyKind();
|
||||
numberDirty = false; updateNumber(); updateReleaseBanner();
|
||||
track('kind_changed', {kind: pkgKind});
|
||||
}
|
||||
function applyKind(){
|
||||
const bimProj = bimSOP(), ewp = isEwp();
|
||||
const show = (id, on) => { const el = document.getElementById(id); if(el) el.style.display = on ? '' : 'none'; };
|
||||
show('bim-card', bim);
|
||||
show('asset-card', !bim);
|
||||
show('material-card', !bim);
|
||||
show('mimo-card', !bim);
|
||||
show('kind-row', bimProj);
|
||||
show('bim-card', ewp); // LOD / model area / clash / scan
|
||||
show('asset-card', !ewp); // controls.dev assets
|
||||
show('material-card', !ewp); // bill of materials
|
||||
show('mimo-card', !ewp); // kitting / MIMO
|
||||
show('bimlink-wrap', bimProj && !ewp); // an IWP references the BIM package that enabled it
|
||||
if(bimProj) setRadio('pkgkind', pkgKind);
|
||||
buildTypePicker(); // filtered by kind
|
||||
buildConstraints(); // filtered by kind
|
||||
}
|
||||
function buildCostCodes(){
|
||||
const sel=document.getElementById('wp_cost'); const cur=sel.value;
|
||||
@@ -183,7 +204,13 @@ function renderSpecFolderLink(){
|
||||
const spec=sopLinkedSources().find(s=>/spec/i.test(s.label));
|
||||
el.innerHTML = spec ? `<a href="${esc(spec.link)}" target="_blank" rel="noopener" class="ref-link-sm">↗ Open spec folder (${esc(spec.system||'SOP')})</a>` : '';
|
||||
}
|
||||
function buildTypePicker(){ document.getElementById('wp_type').innerHTML=`<option value="">Select…</option>`+enabledTypes().map(t=>`<option>${esc(t.name)}</option>`).join(''); }
|
||||
function buildTypePicker(){
|
||||
let types = enabledTypes();
|
||||
if(bimSOP()) types = types.filter(t => isEwp() ? t.bim : !t.bim); // BIM types only for EWP, install types only for IWP
|
||||
const sel=document.getElementById('wp_type'); const cur=sel.value;
|
||||
sel.innerHTML=`<option value="">Select…</option>`+types.map(t=>`<option>${esc(t.name)}</option>`).join('');
|
||||
if(types.some(t=>t.name===cur)) sel.value=cur;
|
||||
}
|
||||
function buildSequencePicker(){ const steps=((SOP&&SOP.sequence)||[]).filter(s=>s.kind!=='gate'&&(s.label||'').trim()); document.getElementById('wp_seq').innerHTML=`<option value="">None (no predecessor)</option>`+steps.map(s=>`<option>${esc(s.label)}</option>`).join(''); }
|
||||
function onTypeChange(){
|
||||
updateNumber(); track('type_selected');
|
||||
@@ -689,6 +716,7 @@ function collectPackage(){
|
||||
signoffs:pkgSignoffs.map(s=>({role:s.role,name:s.name,date:s.date,signed:s.signed,dateReason:s.dateReason||''})),
|
||||
holds:pkgHolds.map(h=>({...h})),
|
||||
actualHrs:gv('wp_actual_hrs'), installedQty:gv('wp_installed_qty'), redlines:gv('wp_redlines'), lessons:gv('wp_lessons'),
|
||||
kind: pkgKind, // 'iwp' (install) | 'ewp' (BIM) — drives which fields/types/gates apply
|
||||
// AWP traceability: which BIM/model package(s) enabled this install package.
|
||||
bimlink:gv('wp_bimlink'),
|
||||
// BIM/VDC package details (only meaningful on a BIM SOP).
|
||||
@@ -712,8 +740,9 @@ function savePackage(view){
|
||||
function renderPackage(pkg){
|
||||
const r = pkg.constraints ? {open:pkg.constraints.filter(c=>c.status==='open').length,total:pkg.constraints.length} : {open:0,total:0};
|
||||
const readyTxt = pkg.status==='Issue' ? 'ON HOLD' : (r.open===0?'RELEASE-READY':(r.open+' OPEN CONSTRAINTS'));
|
||||
const kindLbl = pkg.kind==='ewp' ? 'BIM (EWP)' : 'IWP';
|
||||
let h=`<h1>${esc(pkg.number||'(no number)')} — Work Package</h1>
|
||||
<div class="doc-subtitle">${esc(pkg.project)} · TYPE: ${esc(pkg.type).toUpperCase()} · STATUS: ${esc(pkg.status).toUpperCase()} · ${readyTxt}</div>`;
|
||||
<div class="doc-subtitle">${esc(pkg.project)} · ${kindLbl} · TYPE: ${esc(pkg.type).toUpperCase()} · STATUS: ${esc(pkg.status).toUpperCase()} · ${readyTxt}</div>`;
|
||||
const costDesc = (COST_CODES.find(c=>c.split('|')[0]===pkg.cost)||'').split('|')[1];
|
||||
// Project system links travel with the WP; fall back to the live SOP for older packages.
|
||||
const plinks = (pkg.projectLinks&&pkg.projectLinks.length) ? pkg.projectLinks : ((SOP&&SOP.projectLinks)||[]);
|
||||
@@ -875,6 +904,7 @@ function clearSaved(){ if(!savedPackages.length) return; if(!confirm('Delete all
|
||||
function editPackage(i){ const p=savedPackages[i]; if(!p) return; editingId=p.id; loadPackageIntoForm(p); }
|
||||
function loadExample(){ loadPackageIntoForm(JSON.parse(JSON.stringify(EXAMPLE_PKG))); editingId=null; toast('Example work package loaded'); track('example_loaded'); }
|
||||
function loadPackageIntoForm(p){
|
||||
pkgKind = (p.kind === 'ewp') ? 'ewp' : 'iwp'; // set before type/constraint pickers so they filter correctly
|
||||
const set=(id,v)=>{const el=document.getElementById(id); if(el) el.value=v||'';};
|
||||
set('wp_subject',p.subject); set('wp_system',p.system); set('wp_location',p.location);
|
||||
set('wp_assignees',p.assignees); set('wp_distribution',p.distribution);
|
||||
@@ -882,7 +912,7 @@ function loadPackageIntoForm(p){
|
||||
set('wp_kit_owner',p.kitOwner); set('wp_kit_date',p.kitDate); set('wp_mimo_time',p.mimoTime); set('wp_mimo_loc',p.mimoLoc);
|
||||
set('wp_actual_hrs',p.actualHrs); set('wp_installed_qty',p.installedQty); set('wp_redlines',p.redlines); set('wp_lessons',p.lessons);
|
||||
set('wp_bimlink',p.bimlink); set('wp_lod',p.lod); set('wp_model_area',p.modelArea); set('wp_clash',p.clash); set('wp_scan_link',p.scanLink);
|
||||
applyBimMode();
|
||||
applyKind();
|
||||
buildTypePicker(); document.getElementById('wp_type').value=p.type||'';
|
||||
buildCostCodes(); document.getElementById('wp_cost').value=p.cost||'';
|
||||
set('wp_wbs',p.wbs);
|
||||
@@ -952,7 +982,7 @@ function newPackage(){
|
||||
['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','wp_bimlink','wp_model_area','wp_scan_link'].forEach(id=>{const el=document.getElementById(id); if(el) el.value='';});
|
||||
document.getElementById('wp_type').value=''; document.getElementById('wp_kit_status').value=''; document.getElementById('wp_cost').value='';
|
||||
['wp_lod','wp_clash'].forEach(id=>{const el=document.getElementById(id); if(el) el.value='';});
|
||||
applyBimMode();
|
||||
pkgKind='iwp'; applyKind();
|
||||
setRadio('status','Draft');
|
||||
numberDims={}; buildNumberDims();
|
||||
pkgDisciplines=[]; pkgScope={}; pkgDiscStatus={}; buildDisciplinePicker(); renderScope(); onHoursChange();
|
||||
|
||||
@@ -44,6 +44,16 @@
|
||||
|
||||
<div class="main">
|
||||
|
||||
<!-- PACKAGE KIND (only shown when the project's SOP includes BIM/VDC) -->
|
||||
<div class="card" id="kind-row" style="display:none">
|
||||
<div class="sub-heading">Package Type</div>
|
||||
<div class="notice">This project includes BIM/VDC packages. Choose what this one is — it tailors the fields below and the WP types / release gates offered.</div>
|
||||
<div class="radio-group" id="kind-group" style="margin-bottom:0">
|
||||
<label class="radio-pill" data-val="iwp"><input type="radio" name="pkgkind" onclick="setKind('iwp')"><span class="dot"></span>Install package (IWP)</label>
|
||||
<label class="radio-pill" data-val="ewp"><input type="radio" name="pkgkind" onclick="setKind('ewp')"><span class="dot"></span>BIM package (EWP)</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- GENERAL INFORMATION -->
|
||||
<div class="card">
|
||||
<div class="section-header"><div class="section-title">General Information</div>
|
||||
@@ -80,7 +90,7 @@
|
||||
<div class="field"><label>Specification Section</label><input type="text" id="wp_spec" placeholder="e.g. 26_05_33_00 - Raceway and Boxes"><div class="field-hint" id="spec-folder-link"></div></div>
|
||||
</div>
|
||||
<div class="field field-grid col1"><div class="field"><label>Description</label><textarea id="wp_desc" rows="2" placeholder="Short summary of the package"></textarea></div></div>
|
||||
<div class="field field-grid col1"><div class="field"><label>Enabled by — BIM package(s)<span class="help-tip" data-tip="Advanced Work Packaging traceability: link the BIM / model package(s) that enabled this install package. Paste the MWP number(s) or a link to the model package.">i</span></label><input type="text" id="wp_bimlink" placeholder="e.g. MWP07-FAB-CONDUITS, or a link to the model package"></div></div>
|
||||
<div class="field field-grid col1" id="bimlink-wrap"><div class="field"><label>Enabled by — BIM package(s)<span class="help-tip" data-tip="Advanced Work Packaging traceability: link the BIM / model package(s) that enabled this install package. Paste the MWP number(s) or a link to the model package.">i</span></label><input type="text" id="wp_bimlink" placeholder="e.g. MWP07-FAB-CONDUITS, or a link to the model package"></div></div>
|
||||
</div>
|
||||
|
||||
<!-- BIM / MODEL DETAILS (shown for BIM/VDC SOPs) -->
|
||||
|
||||
Reference in New Issue
Block a user