upgrade: adopt V8.12.0-dev.1 (V8.11 unified professional UI + V8.12 workflow usability)

- Overlay 26 changed files from SiteForge_Enterprise_V8_12 (UI layer only:
  professional-ui.js/css, workspace/factory-v2/operations/editor templates,
  +2 test files, compose/ci/scripts/docs)
- Re-apply v8_workflows type-mapping fix (类型/分类) lost in upgrade
- Pin compose project name to siteforge-v8-10 so existing data volumes
  (hesupipe site 483295c29ea0, 193 entries) keep attached
- Drop stray .s10_* state files; ignore .s10_*/.sf_*/.s87_* patterns
- Plan/spec revisions per plan-review round 1 (icons are new design,
  real test assertions, recorded deviations)

Tests: 226 passed / 1 env-only failure (test needs node binary in PATH,
absent in python:3.12-slim container; host node v24 --check all 9 JS OK)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-22 17:02:45 +08:00
parent 19e865b889
commit 5c7643fcf2
31 changed files with 598 additions and 81 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ async function request(url,{method='GET',body=null,upload=false}={}){
}
const post=(url,body)=>request(url,{method:'POST',body});
function formatJobs(list){return list.length?list.map(j=>`<div class="row"><div><b>${esc(j.kind||'build')} <span class="flag">${esc(j.state)}</span></b><small>${esc(j.id)} · 尝试 ${esc(j.attempts||0)} 次</small></div>${['queued','running','retrying'].includes(j.state)?`<button class="secondary" onclick="cancelJob('${esc(j.id)}')">取消</button>`:''}</div>`).join(''):'当前没有任务';}
async function chooseSite(){siteId=$('#site').value;lastPreview=null;$('#commitImport').disabled=true;await reload()}
async function chooseSite(){siteId=$('#site').value;window.SiteForgeShell?.selectSite(siteId);lastPreview=null;$('#commitImport').disabled=true;await reload()}
async function init(){try{csrf=(await request('/api/auth/me')).csrf;sites=await request('/api/sites');$('#site').innerHTML=sites.map(s=>`<option value="${esc(s.id)}">${esc(s.name)}</option>`).join('');siteId=sites[0]?.id||'';$('#site').onchange=chooseSite;$('#reload').onclick=reload;$('#previewImport').onclick=()=>importJSON(false);$('#commitImport').onclick=()=>importJSON(true);$('#build').onclick=buildSite;$('#deploy').onclick=deploySite;$('#refreshRelease').onclick=reload;await reload()}catch(e){notify(e.message,true)}}
async function reload(){if(!siteId)return;try{
const [list,jobsData,buildData,approvals,history,reviewData]=await Promise.all([