scrum-skills 0.3.6 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +224 -224
- package/assets/board/200.html +1 -1
- package/assets/board/404.html +1 -1
- package/assets/board/_nuxt/{D1V1gysQ.js → 1XlYaCp9.js} +1 -1
- package/assets/board/_nuxt/{DwzGxoX2.js → BXL77dAA.js} +1 -1
- package/assets/board/_nuxt/BgYBC1A-.js +1 -0
- package/assets/board/_nuxt/{DwCE3305.js → BizDeOK5.js} +1 -1
- package/assets/board/_nuxt/{BGwhkDRl.js → BtzUbHO_.js} +1 -1
- package/assets/board/_nuxt/{NtgBvUDk.js → COK7QeK2.js} +1 -1
- package/assets/board/_nuxt/{BmrSh0rL.js → COecDWbb.js} +1 -1
- package/assets/board/_nuxt/{CoipdpDu.js → ChUHb39z.js} +1 -1
- package/assets/board/_nuxt/{Dh0tYNMD.js → CitsykCR.js} +4 -4
- package/assets/board/_nuxt/DPGo7nC4.js +3 -0
- package/assets/board/_nuxt/{Cajxc4Dw.js → DZ--fXuU.js} +1 -1
- package/assets/board/_nuxt/D_ct-Stz.js +1 -1
- package/assets/board/_nuxt/JybTzB-y.js +1 -0
- package/assets/board/_nuxt/_id_.JsxT0cgo.css +1 -0
- package/assets/board/_nuxt/builds/latest.json +1 -1
- package/assets/board/_nuxt/builds/meta/ef150044-a595-4b33-8a1a-103e86dccf28.json +1 -0
- package/assets/board/_nuxt/burndown.CT8fx1Ge.css +1 -0
- package/assets/board/_nuxt/diagrams.BWgRXpo3.css +1 -0
- package/assets/board/_nuxt/{entry.Birf8F5Z.css → entry.DplN301E.css} +1 -1
- package/assets/board/_nuxt/epics.CUeDIEa0.css +1 -0
- package/assets/board/_nuxt/error-404.Y9imKiDC.css +1 -0
- package/assets/board/_nuxt/error-500.DufSBGVC.css +1 -0
- package/assets/board/_nuxt/gantt.CiC2Ts1t.css +1 -0
- package/assets/board/_nuxt/last-change.Byf5fhdY.css +1 -0
- package/assets/board/_nuxt/milestones.CCdemaYm.css +1 -0
- package/assets/board/_nuxt/{b7xtxFRl.js → oSJF4yHw.js} +1 -1
- package/assets/board/_nuxt/pages.BshWbOyo.css +1 -0
- package/assets/board/_nuxt/tests.Ci9fBCka.css +1 -0
- package/assets/board/burndown/index.html +1 -1
- package/assets/board/diagrams/index.html +1 -1
- package/assets/board/epics/index.html +1 -1
- package/assets/board/favicon.svg +16 -16
- package/assets/board/gantt/index.html +1 -1
- package/assets/board/index.html +1 -1
- package/assets/board/last-change/index.html +1 -1
- package/assets/board/milestones/index.html +1 -1
- package/assets/board/tests/index.html +1 -1
- package/bin/scrum-skills.mjs +204 -204
- package/docs/ai-assistant-guide.md +1009 -1009
- package/package.json +1 -1
- package/templates/AGENTS.md +84 -84
- package/tools/agile-tools.mjs +510 -510
- package/tools/ai.mjs +508 -508
- package/tools/git-commit.mjs +216 -216
- package/tools/projects.mjs +240 -240
- package/tools/serve.mjs +182 -182
- package/assets/board/_nuxt/C-fx-vFO.js +0 -1
- package/assets/board/_nuxt/D5AHQ-N9.js +0 -3
- package/assets/board/_nuxt/_id_.B6iqDPxe.css +0 -1
- package/assets/board/_nuxt/builds/meta/36a46dc2-c9fd-444c-a454-4487435c77b9.json +0 -1
- package/assets/board/_nuxt/burndown.Do6IbM6o.css +0 -1
- package/assets/board/_nuxt/diagrams.pyhqNtmr.css +0 -1
- package/assets/board/_nuxt/epics.Dmessplu.css +0 -1
- package/assets/board/_nuxt/error-404.CgJNdpB5.css +0 -1
- package/assets/board/_nuxt/error-500.WYSoH44y.css +0 -1
- package/assets/board/_nuxt/gantt.Dmp00GUo.css +0 -1
- package/assets/board/_nuxt/last-change._l3ydJ-o.css +0 -1
- package/assets/board/_nuxt/milestones.Bp6jmeAm.css +0 -1
- package/assets/board/_nuxt/pages.Dbj2IVk8.css +0 -1
- package/assets/board/_nuxt/tests.dXlUX16A.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=/(?:^|(?<=[\s。;;::,,))]))(?:\d{1,2}[.)、]|[((]\d{1,2}[))]|[①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳]|[-*•·])\s+/gm,t=/(?<=[。;;])/,n=e=>typeof e==`string`?e.replace(/[\r\n]+/g,` `).replace(/\s{2,}/g,` `).trim():``,r=t=>t.match(e)?.length??0,i=20,a=e=>e.replace(/[;;,,]+$/,``).trim(),o=e=>e.length>1?e.map(a).filter(Boolean):e;function s(t){if(r(t)<2)return[];let a=t.split(e).map(n).filter(Boolean);return a.length>1&&a[0].length<=i&&/[::]$/.test(a[0])&&a.splice(0,2,`${a[0]}${a[1]}`),o(a)}function c(e){if(Array.isArray(e))return o(e.map(n).filter(Boolean));let r=n(e);if(!r)return[];let i=String(e).split(/\r?\n/).map(n).filter(Boolean);if(i.length>1)return o(i.flatMap(e=>{let t=s(e);return t.length?t:[e]}).filter(Boolean));let a=s(r);if(a.length>1)return a;let c=o(r.split(t).map(n).filter(Boolean));return c.length>1?c:[r]}export{c as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,o as n,r as ee,s as r}from"#entry";import{t as te}from"./DJM7u8P3.js";import{t as ne}from"./CI0scS-N.js";import{At as i,K as a,S as o,U as s,Xt as c,Yt as l,b as u,d,f as re,gt as ie,i as f,lt as p,m,p as h,qt as g,u as _,ut as ae,xt as v,y}from"./BxuBMtk_.js";import{a as oe,c as se}from"./BygIGL69.js";var ce={class:`tests-page`},le={class:`page-anchor`,"aria-label":`页内跳转`},ue=[`href`,`onClick`],de={id:`tc-overview`,class:`kpis`},fe={class:`v`},pe={class:`v`},me={class:`v`},he={class:`v`},ge={class:`v`},_e={key:0,class:`callout soft`},ve={class:`layers`},ye={class:`layer-hd`},be={class:`tag tag-neutral`},xe={class:`layer-body`},Se={class:`ok`},Ce={class:`bad`},b={class:`dim`},x={class:`dim`},S={id:`tc-coverage`,class:`card panel`},C={class:`card-bd cover-grid`},w={class:`cover-main`},T={class:`cover-big`},E={class:`sub`},D={class:`bar`},O={class:`cover-sub`},k={class:`cover-side`},A={key:0,class:`foot dim`},we={id:`tc-matrix`,class:`card`},Te={class:`card-hd`},Ee={class:`tag tag-neutral`},De={class:`filters inline`},Oe=[`onClick`],ke={class:`n`},Ae={class:`card-bd matrix-wrap`},je={class:`tbl`},Me={class:`ttl`},Ne={class:`dim`},Pe={class:`foot dim`},Fe={key:0},Ie={id:`tc-cases`,class:`card`},Le={class:`card-hd`},Re={class:`tag tag-neutral`},ze={class:`card-bd`},Be={class:`filters`},Ve=[`onClick`],He={class:`n`},Ue=[`onClick`],We={class:`n`},Ge={class:`tbl cases`},Ke=[`onClick`],qe={class:`mono`},Je={key:0,class:`code mono`},Ye={class:`tag tag-neutral`},Xe={class:`dim lv`},Ze={class:`mono covers`},Qe={key:0,class:`dim`},$e={class:`dim`},et={class:`r mono dim`},tt={colspan:`6`},nt={class:`detail`},rt={key:0,class:`steps`},it={key:1,class:`dim`},at={class:`dim`},ot={key:0},st={key:1},ct={key:2},lt={key:0,class:`foot dim`},ut={key:1,class:`foot dim`},dt={id:`tc-gaps`,class:`card`},ft={class:`card-hd`},pt={class:`card-bd gap-grid`},mt={class:`h3`},ht={key:0,class:`gap-list`},gt={class:`dim`},_t={class:`gap-text`},vt={key:1,class:`foot dim`},yt={class:`h3`},bt={key:0,class:`gap-list`},xt={class:`mono`},St={key:0,class:`dim`},Ct={key:1,class:`foot dim`},wt={id:`tc-runs`,class:`card`},Tt={class:`card-hd`},Et={class:`tag tag-neutral`},Dt={class:`card-bd`},Ot={class:`tbl`},kt={class:`mono`},At={class:`mono`},jt={class:`dim`},Mt={class:`r mono`},Nt={class:`r mono ok`},Pt={class:`r mono dim`},Ft={class:`r mono dim`},It={class:`mono dim cov-cell`},Lt={key:0},Rt={key:0,class:`foot dim`},zt={key:1,class:`foot dim`},j=t(o({__name:`tests`,setup(t){let{testCases:o,testStats:j,requirement:M,matrixRows:N,lastRun:P,testRuns:F,coverageRows:I,LAYERS:L,LAYER_LABEL:R,LEVEL_LABEL:Bt,CASE_STATUS_LABEL:z,CASE_STATUS_COLOR:Vt,CASE_STATUS_DOT:Ht,storyById:Ut,STATE_LABEL:Wt,PRIORITY_COLOR:B,md:Gt}=r(),V=v(`all`),H=v(`all`),U=v(``),W=v(``),Kt=[{id:`tc-overview`,label:`概览`},{id:`tc-coverage`,label:`覆盖率`},{id:`tc-matrix`,label:`覆盖矩阵`},{id:`tc-cases`,label:`用例清单`},{id:`tc-gaps`,label:`缺口与风险`},{id:`tc-runs`,label:`执行记录`}],qt=e=>{let t=document.getElementById(e);t&&(t.scrollIntoView({behavior:`smooth`,block:`start`}),history.replaceState(null,``,`#${e}`))},Jt=[`#8a63f7`,`#3f7fd4`,`#6aa844`],G=_(()=>[{key:`all`,label:`全部`,count:j.value.total},...L.map(e=>({key:e,label:R[e],count:j.value.byLayer[e]?.total??0}))]),K=_(()=>{let e=U.value.trim().toLowerCase();return o.value.filter(t=>V.value!==`all`&&t.layer!==V.value||H.value!==`all`&&t.status!==H.value?!1:!e||[t.id,t.title,t.code,t.suiteName,...t.covers??[]].join(` `).toLowerCase().includes(e))}),Yt=_(()=>{let e=P.value?.totals;if(e){let t=e.total-(e.skipped??0);return t>0?Math.round(e.pass/t*100):0}let t=j.value.total-j.value.byStatus[`not-run`];return t>0?Math.round((j.value.byStatus.pass??0)/t*100):0}),q=v(`covered`),Xt=_(()=>N.value.filter(e=>q.value===`all`?!0:q.value===`covered`?e.covered>0:e.covered===0)),J=_(()=>N.value.filter(e=>e.covered===0).length),Zt=_(()=>[{key:`covered`,label:`有用例`,count:N.value.filter(e=>e.covered>0).length},{key:`missing`,label:`未覆盖`,count:J.value},{key:`all`,label:`全部`,count:N.value.length}]),Y=e=>I.value.find(t=>t.layer===e),X=_(()=>o.value.filter(e=>e.status===`fail`)),Z=_(()=>[`pass`,`fail`,`skipped`,`blocked`,`not-run`].map(e=>({key:e,label:z[e],count:j.value.byStatus[e]??0}))),Q=e=>typeof e==`number`?e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e}ms`:`—`,Qt=e=>{W.value=W.value===e?``:e},$=e=>[...new Set((e.covers??[]).map(e=>e.replace(/-A\d+$/,``)))].map(e=>Ut.value.get(e)).filter(Boolean);return(t,r)=>{let _=ee,v=te,I=ne;return s(),m(`div`,ce,[d(`nav`,le,[r[2]||=d(`span`,{class:`anchor-label`},`跳到`,-1),(s(),m(f,null,a(Kt,e=>d(`a`,{key:e.id,href:`#${e.id}`,class:`anchor-chip`,onClick:se(t=>qt(e.id),[`prevent`])},c(e.label),9,ue)),64))]),d(`div`,de,[d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(0)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(0),size:`sm`},null,8,[`tone`]),r[3]||=d(`p`,{class:`k`},`用例总数`,-1),d(`p`,fe,[y(c(i(j).total),1),d(`small`,null,`自动 `+c(i(j).automated)+` / 手工 `+c(i(j).manual),1)])],2),d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(1)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(1),size:`sm`},null,8,[`tone`]),r[5]||=d(`p`,{class:`k`},`用例通过率`,-1),d(`p`,pe,[y(c(i(Yt)),1),r[4]||=d(`small`,null,`%`,-1)])],2),d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(2)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(2),size:`sm`},null,8,[`tone`]),r[6]||=d(`p`,{class:`k`},`需求覆盖`,-1),d(`p`,me,[y(c(i(M).covered),1),d(`small`,null,`/ `+c(i(M).total)+` 条验收`,1)])],2),d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(3)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(3),size:`sm`},null,8,[`tone`]),r[7]||=d(`p`,{class:`k`},`前端行覆盖率`,-1),d(`p`,he,[y(c(Y(`frontend`)?.lines??`—`),1),d(`small`,null,c(Y(`frontend`)?`%`:`未上报`),1)])],2),d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(4)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(4),size:`sm`},null,8,[`tone`]),r[8]||=d(`p`,{class:`k`},`后端行覆盖率`,-1),d(`p`,ge,[y(c(Y(`backend`)?.lines??`—`),1),d(`small`,null,c(Y(`backend`)?`%`:`未上报`),1)])],2)]),i(o).length?(s(),m(f,{key:1},[d(`div`,ve,[(s(!0),m(f,null,a(i(L),(e,t)=>(s(),m(`div`,{key:e,class:`card layer-card`},[d(`div`,ye,[d(`span`,{class:`layer-dot`,style:l({background:Jt[t]})},null,4),d(`b`,null,c(i(R)[e]),1),d(`span`,be,c(i(j).byLayer[e]?.total??0),1)]),d(`div`,xe,[d(`span`,Se,`通过 `+c(i(j).byLayer[e]?.pass??0),1),d(`span`,Ce,`失败 `+c(i(j).byLayer[e]?.fail??0),1),d(`span`,b,`跳过 `+c(i(j).byLayer[e]?.skipped??0),1),d(`span`,x,`未跑 `+c(i(j).byLayer[e]?.notRun??0),1)])]))),128))]),d(`div`,S,[r[12]||=d(`div`,{class:`card-hd`},[d(`h2`,{class:`h2`},`覆盖率`),d(`span`,{class:`tag tag-neutral`},`需求口径`),d(`span`,{class:`dim tip`},`分母是非草稿 / 未取消故事的验收条数`)],-1),d(`div`,C,[d(`div`,w,[d(`p`,T,[y(c(i(M).covered),1),d(`span`,null,`/`+c(i(M).total),1)]),d(`p`,E,`验收已被用例覆盖 `+c(i(M).rate)+`%`,1),d(`div`,D,[d(`i`,{style:l({width:i(M).rate+`%`})},null,4)]),d(`p`,O,[r[10]||=y(` 其中最近一次通过验证 `,-1),d(`b`,null,c(i(M).verified),1),y(` / `+c(i(M).total)+`(`+c(i(M).verifiedRate)+`%) `,1)]),r[11]||=d(`p`,{class:`foot dim`},`有用例但最近一次失败的不算「验证通过」——覆盖与通过是两件事。`,-1)]),d(`div`,k,[(s(!0),m(f,null,a(i(Z),e=>(s(),m(`div`,{key:e.key,class:`stat-row`},[d(`i`,{class:`dot`,style:l({background:i(Ht)[e.key]})},null,4),d(`span`,null,c(e.label),1),d(`b`,null,c(e.count),1)]))),128)),i(P)?(s(),m(`p`,A,[y(` 最近一次:`+c(i(P).at)+` · `+c(i(P).command||`未记录命令`),1),i(P).env?(s(),m(f,{key:0},[y(` · `+c(i(P).env),1)],64)):h(``,!0)])):h(``,!0)])])]),d(`div`,we,[d(`div`,Te,[r[13]||=d(`h2`,{class:`h2`},`分层覆盖矩阵`,-1),d(`span`,Ee,c(i(N).length),1),r[14]||=d(`span`,{class:`dim tip`},`前端 / 后端 / E2E 三条泳道分开看,— 表示这一层没有用例`,-1),d(`div`,De,[(s(!0),m(f,null,a(i(Zt),e=>(s(),m(`button`,{key:e.key,class:g([`chip`,{on:i(q)===e.key}]),onClick:t=>q.value=e.key},[y(c(e.label),1),d(`span`,ke,c(e.count),1)],10,Oe))),128))])]),d(`div`,Ae,[d(`table`,je,[r[15]||=d(`thead`,null,[d(`tr`,null,[d(`th`,null,`故事`),d(`th`,null,`优先级`),d(`th`,{class:`r`},`前端`),d(`th`,{class:`r`},`后端`),d(`th`,{class:`r`},`E2E`),d(`th`,{class:`r`},`验收覆盖`),d(`th`,null,`状态`)])],-1),d(`tbody`,null,[(s(!0),m(f,null,a(i(Xt),e=>(s(),m(`tr`,{key:e.id},[d(`td`,null,[u(I,{to:`/story/${e.id}`,class:`mono link`},{default:p(()=>[y(c(e.id),1)]),_:2},1032,[`to`]),d(`span`,Me,c(e.title),1)]),d(`td`,null,[d(`span`,{class:g([`tag`,`tag-${i(B)[e.priority]??`neutral`}`])},c(e.priority),3)]),d(`td`,{class:g([`r mono`,{zero:!e.layers.frontend}])},c(e.layers.frontend||`—`),3),d(`td`,{class:g([`r mono`,{zero:!e.layers.backend}])},c(e.layers.backend||`—`),3),d(`td`,{class:g([`r mono`,{zero:!e.layers.e2e}])},c(e.layers.e2e||`—`),3),d(`td`,{class:g([`r mono`,{bad:!e.allCovered}])},c(e.covered)+`/`+c(e.total),3),d(`td`,null,[d(`span`,Ne,c(i(Wt)[e.status]??e.status),1)])]))),128))])]),d(`p`,Pe,[r[16]||=y(` 一格 = 这一层覆盖了该故事几条验收;三个 — 全空就是完全没测。 `,-1),i(J)?(s(),m(`span`,Fe,`还有 `+c(i(J))+` 个故事一条用例都没有,切「未覆盖」查看。`,1)):h(``,!0)])])]),d(`div`,Ie,[d(`div`,Le,[r[17]||=d(`h2`,{class:`h2`},`用例清单`,-1),d(`span`,Re,c(i(K).length),1),ae(d(`input`,{"onUpdate:modelValue":r[0]||=e=>ie(U)?U.value=e:null,class:`input case-search`,placeholder:`搜编号 / 标题 / 文件 / 验收`,"aria-label":`搜索用例`},null,512),[[oe,i(U)]])]),d(`div`,ze,[d(`div`,Be,[(s(!0),m(f,null,a(i(G),e=>(s(),m(`button`,{key:e.key,class:g([`chip`,{on:i(V)===e.key}]),onClick:t=>V.value=e.key},[y(c(e.label),1),d(`span`,He,c(e.count),1)],10,Ve))),128)),r[18]||=d(`span`,{class:`sep`},null,-1),d(`button`,{class:g([`chip`,{on:i(H)===`all`}]),onClick:r[1]||=e=>H.value=`all`},`全部状态`,2),(s(!0),m(f,null,a(i(Z),e=>(s(),m(`button`,{key:e.key,class:g([`chip`,{on:i(H)===e.key}]),onClick:t=>H.value=e.key},[y(c(e.label),1),d(`span`,We,c(e.count),1)],10,Ue))),128))]),d(`table`,Ge,[r[23]||=d(`thead`,null,[d(`tr`,null,[d(`th`,null,`编号`),d(`th`,null,`用例`),d(`th`,null,`层 / 级别`),d(`th`,null,`覆盖验收`),d(`th`,null,`方式`),d(`th`,null,`状态`),d(`th`,{class:`r`},`最近执行`)])],-1),d(`tbody`,null,[(s(!0),m(f,null,a(i(K),e=>(s(),m(f,{key:e.id},[d(`tr`,{class:`case-row`,onClick:t=>Qt(e.id)},[d(`td`,qe,c(e.id),1),d(`td`,null,[d(`b`,null,c(e.title),1),e.code?(s(),m(`span`,Je,c(e.code),1)):h(``,!0)]),d(`td`,null,[d(`span`,Ye,c(i(R)[e.layer]??e.layer),1),d(`span`,Xe,c(i(Bt)[e.level]??e.level),1)]),d(`td`,Ze,[(s(!0),m(f,null,a(e.covers??[],e=>(s(),m(`span`,{key:e,class:`cov-ref`},c(e),1))),128)),(e.covers??[]).length?h(``,!0):(s(),m(`span`,Qe,`—`))]),d(`td`,null,[d(`span`,$e,c(e.automated?`自动`:`手工`),1)]),d(`td`,null,[d(`span`,{class:g([`tag`,`tag-${i(Vt)[e.status]??`neutral`}`])},c(i(z)[e.status]??e.status),3)]),d(`td`,et,c(e.lastRun?i(Gt)(e.lastRun):`—`),1)],8,Ke),i(W)===e.id?(s(),m(`tr`,{key:e.id+`-d`,class:`detail-row`},[r[22]||=d(`td`,null,null,-1),d(`td`,tt,[d(`div`,nt,[d(`p`,null,[r[19]||=d(`b`,null,`预期:`,-1),y(c(e.expect),1)]),(e.steps??[]).length?(s(),m(`ol`,rt,[(s(!0),m(f,null,a(e.steps,(e,t)=>(s(),m(`li`,{key:t},c(e),1))),128))])):h(``,!0),e.note?(s(),m(`p`,it,[r[20]||=d(`b`,null,`备注:`,-1),y(c(e.note),1)])):h(``,!0),d(`p`,at,[r[21]||=y(` 覆盖故事: `,-1),(s(!0),m(f,null,a($(e),e=>(s(),re(I,{key:e.id,to:`/story/${e.id}`,class:`mono link`},{default:p(()=>[y(c(e.id),1)]),_:2},1032,[`to`]))),128)),$(e).length?(s(),m(`span`,ot,` · 套件 `+c(e.suiteName)+`(`+c(e.suiteId)+`)`,1)):(s(),m(`span`,st,`未关联故事 · 套件 `+c(e.suiteName)+`(`+c(e.suiteId)+`)`,1)),e.durationMs===void 0?h(``,!0):(s(),m(`span`,ct,` · 耗时 `+c(Q(e.durationMs)),1))])])])])):h(``,!0)],64))),128))])]),i(K).length?(s(),m(`p`,ut,`点一行展开预期与步骤;手工用例按「步骤 + 预期」交接给 QA。`)):(s(),m(`p`,lt,`当前筛选下没有用例。`))])]),d(`div`,dt,[d(`div`,ft,[r[24]||=d(`h2`,{class:`h2`},`缺口与风险`,-1),d(`span`,{class:g([`tag`,i(M).gaps.length||i(X).length?`tag-error`:`tag-success`])},c(i(M).gaps.length+i(X).length),3),r[25]||=d(`span`,{class:`dim tip`},`未覆盖的验收 + 最近一次失败的用例`,-1)]),d(`div`,pt,[d(`div`,null,[d(`p`,mt,[u(v,{name:`i-lucide-shield-alert`,class:`size-3`}),y(`没有任何用例覆盖的验收(`+c(i(M).gaps.length)+`)`,1)]),i(M).gaps.length?(s(),m(`ul`,ht,[(s(!0),m(f,null,a(i(M).gaps,e=>(s(),m(`li`,{key:e.ref},[d(`span`,{class:g([`tag`,`tag-${i(B)[e.priority]??`neutral`}`])},c(e.priority),3),u(I,{to:`/story/${e.storyId}`,class:`mono link`},{default:p(()=>[y(c(e.ref),1)]),_:2},1032,[`to`]),d(`span`,gt,c(e.storyTitle),1),d(`span`,_t,c(e.text),1)]))),128))])):(s(),m(`p`,vt,`每条验收都有对应用例。`))]),d(`div`,null,[d(`p`,yt,[u(v,{name:`i-lucide-circle-x`,class:`size-3`}),y(`最近一次失败的用例(`+c(i(X).length)+`)`,1)]),i(X).length?(s(),m(`ul`,bt,[(s(!0),m(f,null,a(i(X),e=>(s(),m(`li`,{key:e.id},[d(`span`,xt,c(e.id),1),d(`b`,null,c(e.title),1),e.note?(s(),m(`span`,St,`· `+c(e.note),1)):h(``,!0)]))),128))])):(s(),m(`p`,Ct,`没有失败用例。`))])])]),d(`div`,wt,[d(`div`,Tt,[r[26]||=d(`h2`,{class:`h2`},`执行记录`,-1),d(`span`,Et,c(i(F).length),1),r[27]||=d(`span`,{class:`dim tip`},`最近 20 次,最新一条在最后`,-1)]),d(`div`,Dt,[d(`table`,Ot,[r[28]||=d(`thead`,null,[d(`tr`,null,[d(`th`,null,`时间`),d(`th`,null,`命令`),d(`th`,null,`环境`),d(`th`,{class:`r`},`总数`),d(`th`,{class:`r`},`通过`),d(`th`,{class:`r`},`失败`),d(`th`,{class:`r`},`跳过`),d(`th`,{class:`r`},`耗时`),d(`th`,null,`代码覆盖`)])],-1),d(`tbody`,null,[(s(!0),m(f,null,a(i(F),(e,t)=>(s(),m(`tr`,{key:e.id??e.at+t,class:g({last:t===i(F).length-1})},[d(`td`,kt,c(e.at),1),d(`td`,At,c(e.command||`—`),1),d(`td`,jt,c(e.env||`—`),1),d(`td`,Mt,c(e.totals?.total??`—`),1),d(`td`,Nt,c(e.totals?.pass??`—`),1),d(`td`,{class:g([`r mono`,{bad:e.totals?.fail}])},c(e.totals?.fail??`—`),3),d(`td`,Pt,c(e.totals?.skipped??`—`),1),d(`td`,Ft,c(Q(e.totals?.durationMs)),1),d(`td`,It,[(s(!0),m(f,null,a(e.coverage??{},(e,t)=>(s(),m(`span`,{key:t},c(i(R)[t]??t)+` `+c(e.lines??`—`)+`%`,1))),128)),Object.keys(e.coverage??{}).length?h(``,!0):(s(),m(`span`,Lt,`—`))])],2))),128))])]),i(F).length?(s(),m(`p`,zt,`覆盖率来自各层测试工具的报告,前端 / 后端分开,不做加权平均。`)):(s(),m(`p`,Rt,`还没有执行记录:跑完测试后把结果追加到 runs,页面上才有通过率与趋势。`))])])],64)):(s(),m(`div`,_e,[u(v,{name:`i-lucide-flask-conical`,class:`size-4`}),r[9]||=d(`div`,null,[d(`b`,null,`还没有测试用例`),d(`p`,{style:{"margin-top":`3px`}},[y(` 项目里没有 `),d(`code`,{class:`mono`},`agile/tests.json`),y(`,或者它还没有登记用例。 按纪律,Coding Agent 每推完一个 task / story 就该把本次新增用例与执行结果写进来: 结构见 `),d(`code`,{class:`mono`},`scrum-planning`),y(` 的 `),d(`code`,{class:`mono`},`references/schema.md`),y(` 第 5 节。 `)])],-1)]))])}}}),[[`__scopeId`,`data-v-d69ddc53`]]);export{j as default};
|
|
1
|
+
import{a as e,i as t,o as n,r as ee,s as r}from"#entry";import{t as te}from"./DJM7u8P3.js";import{t as ne}from"./CI0scS-N.js";import{At as i,K as a,S as o,U as s,Xt as c,Yt as l,b as u,d,f as re,gt as ie,i as f,lt as p,m,p as h,qt as g,u as _,ut as ae,xt as v,y}from"./BxuBMtk_.js";import{a as oe,c as se}from"./BygIGL69.js";var ce={class:`tests-page`},le={class:`page-anchor`,"aria-label":`页内跳转`},ue=[`href`,`onClick`],de={id:`tc-overview`,class:`kpis`},fe={class:`v`},pe={class:`v`},me={class:`v`},he={class:`v`},ge={class:`v`},_e={key:0,class:`callout soft`},ve={class:`layers`},ye={class:`layer-hd`},be={class:`tag tag-neutral`},xe={class:`layer-body`},Se={class:`ok`},Ce={class:`bad`},b={class:`dim`},x={class:`dim`},S={id:`tc-coverage`,class:`card panel`},C={class:`card-bd cover-grid`},w={class:`cover-main`},T={class:`cover-big`},E={class:`sub`},D={class:`bar`},O={class:`cover-sub`},k={class:`cover-side`},A={key:0,class:`foot dim`},we={id:`tc-matrix`,class:`card`},Te={class:`card-hd`},Ee={class:`tag tag-neutral`},De={class:`filters inline`},Oe=[`onClick`],ke={class:`n`},Ae={class:`card-bd matrix-wrap`},je={class:`tbl`},Me={class:`ttl`},Ne={class:`dim`},Pe={class:`foot dim`},Fe={key:0},Ie={id:`tc-cases`,class:`card`},Le={class:`card-hd`},Re={class:`tag tag-neutral`},ze={class:`card-bd`},Be={class:`filters`},Ve=[`onClick`],He={class:`n`},Ue=[`onClick`],We={class:`n`},Ge={class:`tbl cases`},Ke=[`onClick`],qe={class:`mono`},Je={key:0,class:`code mono`},Ye={class:`tag tag-neutral`},Xe={class:`dim lv`},Ze={class:`mono covers`},Qe={key:0,class:`dim`},$e={class:`dim`},et={class:`r mono dim`},tt={colspan:`6`},nt={class:`detail`},rt={key:0,class:`steps`},it={key:1,class:`dim`},at={class:`dim`},ot={key:0},st={key:1},ct={key:2},lt={key:0,class:`foot dim`},ut={key:1,class:`foot dim`},dt={id:`tc-gaps`,class:`card`},ft={class:`card-hd`},pt={class:`card-bd gap-grid`},mt={class:`h3`},ht={key:0,class:`gap-list`},gt={class:`dim`},_t={class:`gap-text`},vt={key:1,class:`foot dim`},yt={class:`h3`},bt={key:0,class:`gap-list`},xt={class:`mono`},St={key:0,class:`dim`},Ct={key:1,class:`foot dim`},wt={id:`tc-runs`,class:`card`},Tt={class:`card-hd`},Et={class:`tag tag-neutral`},Dt={class:`card-bd`},Ot={class:`tbl`},kt={class:`mono`},At={class:`mono`},jt={class:`dim`},Mt={class:`r mono`},Nt={class:`r mono ok`},Pt={class:`r mono dim`},Ft={class:`r mono dim`},It={class:`mono dim cov-cell`},Lt={key:0},Rt={key:0,class:`foot dim`},zt={key:1,class:`foot dim`},j=t(o({__name:`tests`,setup(t){let{testCases:o,testStats:j,requirement:M,matrixRows:N,lastRun:P,testRuns:F,coverageRows:I,LAYERS:L,LAYER_LABEL:R,LEVEL_LABEL:Bt,CASE_STATUS_LABEL:z,CASE_STATUS_COLOR:Vt,CASE_STATUS_DOT:Ht,storyById:Ut,STATE_LABEL:Wt,PRIORITY_COLOR:B,md:Gt}=r(),V=v(`all`),H=v(`all`),U=v(``),W=v(``),Kt=[{id:`tc-overview`,label:`概览`},{id:`tc-coverage`,label:`覆盖率`},{id:`tc-matrix`,label:`覆盖矩阵`},{id:`tc-cases`,label:`用例清单`},{id:`tc-gaps`,label:`缺口与风险`},{id:`tc-runs`,label:`执行记录`}],qt=e=>{let t=document.getElementById(e);t&&(t.scrollIntoView({behavior:`smooth`,block:`start`}),history.replaceState(null,``,`#${e}`))},Jt=[`#8a63f7`,`#3f7fd4`,`#6aa844`],G=_(()=>[{key:`all`,label:`全部`,count:j.value.total},...L.map(e=>({key:e,label:R[e],count:j.value.byLayer[e]?.total??0}))]),K=_(()=>{let e=U.value.trim().toLowerCase();return o.value.filter(t=>V.value!==`all`&&t.layer!==V.value||H.value!==`all`&&t.status!==H.value?!1:!e||[t.id,t.title,t.code,t.suiteName,...t.covers??[]].join(` `).toLowerCase().includes(e))}),Yt=_(()=>{let e=P.value?.totals;if(e){let t=e.total-(e.skipped??0);return t>0?Math.round(e.pass/t*100):0}let t=j.value.total-j.value.byStatus[`not-run`];return t>0?Math.round((j.value.byStatus.pass??0)/t*100):0}),q=v(`covered`),Xt=_(()=>N.value.filter(e=>q.value===`all`?!0:q.value===`covered`?e.covered>0:e.covered===0)),J=_(()=>N.value.filter(e=>e.covered===0).length),Zt=_(()=>[{key:`covered`,label:`有用例`,count:N.value.filter(e=>e.covered>0).length},{key:`missing`,label:`未覆盖`,count:J.value},{key:`all`,label:`全部`,count:N.value.length}]),Y=e=>I.value.find(t=>t.layer===e),X=_(()=>o.value.filter(e=>e.status===`fail`)),Z=_(()=>[`pass`,`fail`,`skipped`,`blocked`,`not-run`].map(e=>({key:e,label:z[e],count:j.value.byStatus[e]??0}))),Q=e=>typeof e==`number`?e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e}ms`:`—`,Qt=e=>{W.value=W.value===e?``:e},$=e=>[...new Set((e.covers??[]).map(e=>e.replace(/-A\d+$/,``)))].map(e=>Ut.value.get(e)).filter(Boolean);return(t,r)=>{let _=ee,v=te,I=ne;return s(),m(`div`,ce,[d(`nav`,le,[r[2]||=d(`span`,{class:`anchor-label`},`跳到`,-1),(s(),m(f,null,a(Kt,e=>d(`a`,{key:e.id,href:`#${e.id}`,class:`anchor-chip`,onClick:se(t=>qt(e.id),[`prevent`])},c(e.label),9,ue)),64))]),d(`div`,de,[d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(0)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(0),size:`sm`},null,8,[`tone`]),r[3]||=d(`p`,{class:`k`},`用例总数`,-1),d(`p`,fe,[y(c(i(j).total),1),d(`small`,null,`自动 `+c(i(j).automated)+` / 手工 `+c(i(j).manual),1)])],2),d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(1)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(1),size:`sm`},null,8,[`tone`]),r[5]||=d(`p`,{class:`k`},`用例通过率`,-1),d(`p`,pe,[y(c(i(Yt)),1),r[4]||=d(`small`,null,`%`,-1)])],2),d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(2)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(2),size:`sm`},null,8,[`tone`]),r[6]||=d(`p`,{class:`k`},`需求覆盖`,-1),d(`p`,me,[y(c(i(M).covered),1),d(`small`,null,`/ `+c(i(M).total)+` 条验收`,1)])],2),d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(3)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(3),size:`sm`},null,8,[`tone`]),r[7]||=d(`p`,{class:`k`},`前端行覆盖率`,-1),d(`p`,he,[y(c(Y(`frontend`)?.lines??`—`),1),d(`small`,null,c(Y(`frontend`)?`%`:`未上报`),1)])],2),d(`div`,{class:g([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(4)])},[u(_,{tone:(`cardTone`in t?t.cardTone:i(e))(4),size:`sm`},null,8,[`tone`]),r[8]||=d(`p`,{class:`k`},`后端行覆盖率`,-1),d(`p`,ge,[y(c(Y(`backend`)?.lines??`—`),1),d(`small`,null,c(Y(`backend`)?`%`:`未上报`),1)])],2)]),i(o).length?(s(),m(f,{key:1},[d(`div`,ve,[(s(!0),m(f,null,a(i(L),(e,t)=>(s(),m(`div`,{key:e,class:`card layer-card`},[d(`div`,ye,[d(`span`,{class:`layer-dot`,style:l({background:Jt[t]})},null,4),d(`b`,null,c(i(R)[e]),1),d(`span`,be,c(i(j).byLayer[e]?.total??0),1)]),d(`div`,xe,[d(`span`,Se,`通过 `+c(i(j).byLayer[e]?.pass??0),1),d(`span`,Ce,`失败 `+c(i(j).byLayer[e]?.fail??0),1),d(`span`,b,`跳过 `+c(i(j).byLayer[e]?.skipped??0),1),d(`span`,x,`未跑 `+c(i(j).byLayer[e]?.notRun??0),1)])]))),128))]),d(`div`,S,[r[12]||=d(`div`,{class:`card-hd`},[d(`h2`,{class:`h2`},`覆盖率`),d(`span`,{class:`tag tag-neutral`},`需求口径`),d(`span`,{class:`dim tip`},`分母是非草稿 / 未取消故事的验收条数`)],-1),d(`div`,C,[d(`div`,w,[d(`p`,T,[y(c(i(M).covered),1),d(`span`,null,`/`+c(i(M).total),1)]),d(`p`,E,`验收已被用例覆盖 `+c(i(M).rate)+`%`,1),d(`div`,D,[d(`i`,{style:l({width:i(M).rate+`%`})},null,4)]),d(`p`,O,[r[10]||=y(` 其中最近一次通过验证 `,-1),d(`b`,null,c(i(M).verified),1),y(` / `+c(i(M).total)+`(`+c(i(M).verifiedRate)+`%) `,1)]),r[11]||=d(`p`,{class:`foot dim`},`有用例但最近一次失败的不算「验证通过」——覆盖与通过是两件事。`,-1)]),d(`div`,k,[(s(!0),m(f,null,a(i(Z),e=>(s(),m(`div`,{key:e.key,class:`stat-row`},[d(`i`,{class:`dot`,style:l({background:i(Ht)[e.key]})},null,4),d(`span`,null,c(e.label),1),d(`b`,null,c(e.count),1)]))),128)),i(P)?(s(),m(`p`,A,[y(` 最近一次:`+c(i(P).at)+` · `+c(i(P).command||`未记录命令`),1),i(P).env?(s(),m(f,{key:0},[y(` · `+c(i(P).env),1)],64)):h(``,!0)])):h(``,!0)])])]),d(`div`,we,[d(`div`,Te,[r[13]||=d(`h2`,{class:`h2`},`分层覆盖矩阵`,-1),d(`span`,Ee,c(i(N).length),1),r[14]||=d(`span`,{class:`dim tip`},`前端 / 后端 / E2E 三条泳道分开看,— 表示这一层没有用例`,-1),d(`div`,De,[(s(!0),m(f,null,a(i(Zt),e=>(s(),m(`button`,{key:e.key,class:g([`chip`,{on:i(q)===e.key}]),onClick:t=>q.value=e.key},[y(c(e.label),1),d(`span`,ke,c(e.count),1)],10,Oe))),128))])]),d(`div`,Ae,[d(`table`,je,[r[15]||=d(`thead`,null,[d(`tr`,null,[d(`th`,null,`故事`),d(`th`,null,`优先级`),d(`th`,{class:`r`},`前端`),d(`th`,{class:`r`},`后端`),d(`th`,{class:`r`},`E2E`),d(`th`,{class:`r`},`验收覆盖`),d(`th`,null,`状态`)])],-1),d(`tbody`,null,[(s(!0),m(f,null,a(i(Xt),e=>(s(),m(`tr`,{key:e.id},[d(`td`,null,[u(I,{to:`/story/${e.id}`,class:`mono link`},{default:p(()=>[y(c(e.id),1)]),_:2},1032,[`to`]),d(`span`,Me,c(e.title),1)]),d(`td`,null,[d(`span`,{class:g([`tag`,`tag-${i(B)[e.priority]??`neutral`}`])},c(e.priority),3)]),d(`td`,{class:g([`r mono`,{zero:!e.layers.frontend}])},c(e.layers.frontend||`—`),3),d(`td`,{class:g([`r mono`,{zero:!e.layers.backend}])},c(e.layers.backend||`—`),3),d(`td`,{class:g([`r mono`,{zero:!e.layers.e2e}])},c(e.layers.e2e||`—`),3),d(`td`,{class:g([`r mono`,{bad:!e.allCovered}])},c(e.covered)+`/`+c(e.total),3),d(`td`,null,[d(`span`,Ne,c(i(Wt)[e.status]??e.status),1)])]))),128))])]),d(`p`,Pe,[r[16]||=y(` 一格 = 这一层覆盖了该故事几条验收;三个 — 全空就是完全没测。 `,-1),i(J)?(s(),m(`span`,Fe,`还有 `+c(i(J))+` 个故事一条用例都没有,切「未覆盖」查看。`,1)):h(``,!0)])])]),d(`div`,Ie,[d(`div`,Le,[r[17]||=d(`h2`,{class:`h2`},`用例清单`,-1),d(`span`,Re,c(i(K).length),1),ae(d(`input`,{"onUpdate:modelValue":r[0]||=e=>ie(U)?U.value=e:null,class:`input case-search`,placeholder:`搜编号 / 标题 / 文件 / 验收`,"aria-label":`搜索用例`},null,512),[[oe,i(U)]])]),d(`div`,ze,[d(`div`,Be,[(s(!0),m(f,null,a(i(G),e=>(s(),m(`button`,{key:e.key,class:g([`chip`,{on:i(V)===e.key}]),onClick:t=>V.value=e.key},[y(c(e.label),1),d(`span`,He,c(e.count),1)],10,Ve))),128)),r[18]||=d(`span`,{class:`sep`},null,-1),d(`button`,{class:g([`chip`,{on:i(H)===`all`}]),onClick:r[1]||=e=>H.value=`all`},`全部状态`,2),(s(!0),m(f,null,a(i(Z),e=>(s(),m(`button`,{key:e.key,class:g([`chip`,{on:i(H)===e.key}]),onClick:t=>H.value=e.key},[y(c(e.label),1),d(`span`,We,c(e.count),1)],10,Ue))),128))]),d(`table`,Ge,[r[23]||=d(`thead`,null,[d(`tr`,null,[d(`th`,null,`编号`),d(`th`,null,`用例`),d(`th`,null,`层 / 级别`),d(`th`,null,`覆盖验收`),d(`th`,null,`方式`),d(`th`,null,`状态`),d(`th`,{class:`r`},`最近执行`)])],-1),d(`tbody`,null,[(s(!0),m(f,null,a(i(K),e=>(s(),m(f,{key:e.id},[d(`tr`,{class:`case-row`,onClick:t=>Qt(e.id)},[d(`td`,qe,c(e.id),1),d(`td`,null,[d(`b`,null,c(e.title),1),e.code?(s(),m(`span`,Je,c(e.code),1)):h(``,!0)]),d(`td`,null,[d(`span`,Ye,c(i(R)[e.layer]??e.layer),1),d(`span`,Xe,c(i(Bt)[e.level]??e.level),1)]),d(`td`,Ze,[(s(!0),m(f,null,a(e.covers??[],e=>(s(),m(`span`,{key:e,class:`cov-ref`},c(e),1))),128)),(e.covers??[]).length?h(``,!0):(s(),m(`span`,Qe,`—`))]),d(`td`,null,[d(`span`,$e,c(e.automated?`自动`:`手工`),1)]),d(`td`,null,[d(`span`,{class:g([`tag`,`tag-${i(Vt)[e.status]??`neutral`}`])},c(i(z)[e.status]??e.status),3)]),d(`td`,et,c(e.lastRun?i(Gt)(e.lastRun):`—`),1)],8,Ke),i(W)===e.id?(s(),m(`tr`,{key:e.id+`-d`,class:`detail-row`},[r[22]||=d(`td`,null,null,-1),d(`td`,tt,[d(`div`,nt,[d(`p`,null,[r[19]||=d(`b`,null,`预期:`,-1),y(c(e.expect),1)]),(e.steps??[]).length?(s(),m(`ol`,rt,[(s(!0),m(f,null,a(e.steps,(e,t)=>(s(),m(`li`,{key:t},c(e),1))),128))])):h(``,!0),e.note?(s(),m(`p`,it,[r[20]||=d(`b`,null,`备注:`,-1),y(c(e.note),1)])):h(``,!0),d(`p`,at,[r[21]||=y(` 覆盖故事: `,-1),(s(!0),m(f,null,a($(e),e=>(s(),re(I,{key:e.id,to:`/story/${e.id}`,class:`mono link`},{default:p(()=>[y(c(e.id),1)]),_:2},1032,[`to`]))),128)),$(e).length?(s(),m(`span`,ot,` · 套件 `+c(e.suiteName)+`(`+c(e.suiteId)+`)`,1)):(s(),m(`span`,st,`未关联故事 · 套件 `+c(e.suiteName)+`(`+c(e.suiteId)+`)`,1)),e.durationMs===void 0?h(``,!0):(s(),m(`span`,ct,` · 耗时 `+c(Q(e.durationMs)),1))])])])])):h(``,!0)],64))),128))])]),i(K).length?(s(),m(`p`,ut,`点一行展开预期与步骤;手工用例按「步骤 + 预期」交接给 QA。`)):(s(),m(`p`,lt,`当前筛选下没有用例。`))])]),d(`div`,dt,[d(`div`,ft,[r[24]||=d(`h2`,{class:`h2`},`缺口与风险`,-1),d(`span`,{class:g([`tag`,i(M).gaps.length||i(X).length?`tag-error`:`tag-success`])},c(i(M).gaps.length+i(X).length),3),r[25]||=d(`span`,{class:`dim tip`},`未覆盖的验收 + 最近一次失败的用例`,-1)]),d(`div`,pt,[d(`div`,null,[d(`p`,mt,[u(v,{name:`i-lucide-shield-alert`,class:`size-3`}),y(`没有任何用例覆盖的验收(`+c(i(M).gaps.length)+`)`,1)]),i(M).gaps.length?(s(),m(`ul`,ht,[(s(!0),m(f,null,a(i(M).gaps,e=>(s(),m(`li`,{key:e.ref},[d(`span`,{class:g([`tag`,`tag-${i(B)[e.priority]??`neutral`}`])},c(e.priority),3),u(I,{to:`/story/${e.storyId}`,class:`mono link`},{default:p(()=>[y(c(e.ref),1)]),_:2},1032,[`to`]),d(`span`,gt,c(e.storyTitle),1),d(`span`,_t,c(e.text),1)]))),128))])):(s(),m(`p`,vt,`每条验收都有对应用例。`))]),d(`div`,null,[d(`p`,yt,[u(v,{name:`i-lucide-circle-x`,class:`size-3`}),y(`最近一次失败的用例(`+c(i(X).length)+`)`,1)]),i(X).length?(s(),m(`ul`,bt,[(s(!0),m(f,null,a(i(X),e=>(s(),m(`li`,{key:e.id},[d(`span`,xt,c(e.id),1),d(`b`,null,c(e.title),1),e.note?(s(),m(`span`,St,`· `+c(e.note),1)):h(``,!0)]))),128))])):(s(),m(`p`,Ct,`没有失败用例。`))])])]),d(`div`,wt,[d(`div`,Tt,[r[26]||=d(`h2`,{class:`h2`},`执行记录`,-1),d(`span`,Et,c(i(F).length),1),r[27]||=d(`span`,{class:`dim tip`},`最近 20 次,最新一条在最后`,-1)]),d(`div`,Dt,[d(`table`,Ot,[r[28]||=d(`thead`,null,[d(`tr`,null,[d(`th`,null,`时间`),d(`th`,null,`命令`),d(`th`,null,`环境`),d(`th`,{class:`r`},`总数`),d(`th`,{class:`r`},`通过`),d(`th`,{class:`r`},`失败`),d(`th`,{class:`r`},`跳过`),d(`th`,{class:`r`},`耗时`),d(`th`,null,`代码覆盖`)])],-1),d(`tbody`,null,[(s(!0),m(f,null,a(i(F),(e,t)=>(s(),m(`tr`,{key:e.id??e.at+t,class:g({last:t===i(F).length-1})},[d(`td`,kt,c(e.at),1),d(`td`,At,c(e.command||`—`),1),d(`td`,jt,c(e.env||`—`),1),d(`td`,Mt,c(e.totals?.total??`—`),1),d(`td`,Nt,c(e.totals?.pass??`—`),1),d(`td`,{class:g([`r mono`,{bad:e.totals?.fail}])},c(e.totals?.fail??`—`),3),d(`td`,Pt,c(e.totals?.skipped??`—`),1),d(`td`,Ft,c(Q(e.totals?.durationMs)),1),d(`td`,It,[(s(!0),m(f,null,a(e.coverage??{},(e,t)=>(s(),m(`span`,{key:t},c(i(R)[t]??t)+` `+c(e.lines??`—`)+`%`,1))),128)),Object.keys(e.coverage??{}).length?h(``,!0):(s(),m(`span`,Lt,`—`))])],2))),128))])]),i(F).length?(s(),m(`p`,zt,`覆盖率来自各层测试工具的报告,前端 / 后端分开,不做加权平均。`)):(s(),m(`p`,Rt,`还没有执行记录:跑完测试后把结果追加到 runs,页面上才有通过率与趋势。`))])])],64)):(s(),m(`div`,_e,[u(v,{name:`i-lucide-flask-conical`,class:`size-4`}),r[9]||=d(`div`,null,[d(`b`,null,`还没有测试用例`),d(`p`,{style:{"margin-top":`3px`}},[y(` 项目里没有 `),d(`code`,{class:`mono`},`agile/tests.json`),y(`,或者它还没有登记用例。 按纪律,Coding Agent 每推完一个 task / story 就该把本次新增用例与执行结果写进来: 结构见 `),d(`code`,{class:`mono`},`scrum-planning`),y(` 的 `),d(`code`,{class:`mono`},`references/schema.md`),y(` 第 5 节。 `)])],-1)]))])}}}),[[`__scopeId`,`data-v-ba251daf`]]);export{j as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./SrNUvNwO.js";import{U as t,Xt as n,d as r,m as i}from"./BxuBMtk_.js";import{i as a}from"#entry";var o={class:`antialiased bg-white dark:bg-neutral-950 dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-neutral-950 tracking-wide`},s={class:`max-w-520px text-center`},c=[`textContent`],l=[`textContent`],u=[`textContent`],d=a({__name:`error-500`,props:{appName:{type:String,default:`Nuxt`},status:{type:Number,default:500},statusText:{type:String,default:`Internal server error`},description:{type:String,default:`This page is temporarily unavailable.`},refresh:{type:String,default:`Refresh this page`}},setup(a){let d=a;return e({title:`${d.status} - ${d.statusText} | ${d.appName}`,script:[],style:[{innerHTML:`*,:after,:before{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb);--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset: ;--un-shadow:0 0 #0000;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:#93c5fd80;--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }:after,:before{--un-content:""}html{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}`}]}),(e,d)=>(t(),i(`div`,o,[r(`div`,s,[r(`h1`,{class:`font-medium leading-none mb-4 sm:text-[72px] tabular-nums text-[56px]`,textContent:n(a.status)},null,8,c),r(`h2`,{class:`font-semibold mb-2 sm:text-3xl text-2xl`,textContent:n(a.statusText)},null,8,l),r(`p`,{class:`mb-4 px-2 text-md text-neutral-500`,textContent:n(a.description)},null,8,u)])]))}},[[`__scopeId`,`data-v-
|
|
1
|
+
import{n as e}from"./SrNUvNwO.js";import{U as t,Xt as n,d as r,m as i}from"./BxuBMtk_.js";import{i as a}from"#entry";var o={class:`antialiased bg-white dark:bg-neutral-950 dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-neutral-950 tracking-wide`},s={class:`max-w-520px text-center`},c=[`textContent`],l=[`textContent`],u=[`textContent`],d=a({__name:`error-500`,props:{appName:{type:String,default:`Nuxt`},status:{type:Number,default:500},statusText:{type:String,default:`Internal server error`},description:{type:String,default:`This page is temporarily unavailable.`},refresh:{type:String,default:`Refresh this page`}},setup(a){let d=a;return e({title:`${d.status} - ${d.statusText} | ${d.appName}`,script:[],style:[{innerHTML:`*,:after,:before{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb);--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset: ;--un-shadow:0 0 #0000;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:#93c5fd80;--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }:after,:before{--un-content:""}html{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}`}]}),(e,d)=>(t(),i(`div`,o,[r(`div`,s,[r(`h1`,{class:`font-medium leading-none mb-4 sm:text-[72px] tabular-nums text-[56px]`,textContent:n(a.status)},null,8,c),r(`h2`,{class:`font-semibold mb-2 sm:text-3xl text-2xl`,textContent:n(a.statusText)},null,8,l),r(`p`,{class:`mb-4 px-2 text-md text-neutral-500`,textContent:n(a.description)},null,8,u)])]))}},[[`__scopeId`,`data-v-d4411f5a`]]);export{d as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,o as n,r as ee,s as r}from"#entry";import{t as te}from"./DJM7u8P3.js";import{t as i}from"./CI0scS-N.js";import{At as a,K as o,S as s,U as c,Xt as l,Yt as u,b as d,d as f,f as p,i as m,lt as ne,m as h,p as g,qt as _,u as v,v as re,y}from"./BxuBMtk_.js";var b={class:`kpis`},ie={class:`v`},ae={class:`v`},oe={class:`v`},se={class:`v`},x={class:`v`},S={class:`card tl-wrap`},C={class:`card-hd tl-hd`},w={class:`h2`},T={class:`timeline`},E={key:0,class:`tl-today`},D={class:`tl-item`},O={class:`when`},k={class:`when-date mono`},A={class:`when-year`},j={class:`axis`},M={class:`node-top`},N={class:`tag tag-ghost`},P={key:0,class:`tag tag-neutral mono`},F={class:`node-title`},I={class:`criteria`},L={class:`nums`},R={class:`dim`},z={class:`mpct`},B={class:`mss`},ce={class:`st-id mono`},V={class:`st-title`},H={class:`st-state dim`},U={class:`st-pts dim`},W={key:0,class:`tl-today`},G=t(s({__name:`milestones`,setup(t){let{milestones:s,milestoneProgress:G,now:K,md:le,MS_LABEL:ue,MS_COLOR:de,KIND_LABEL:fe,KIND_ICON:pe,STATE_DOT:me,STATE_LABEL:he,diffDays:q}=r(),J=v(()=>[...s.value].sort((e,t)=>e.due<t.due?-1:+(e.due>t.due))),Y=e=>q(K,e),X=e=>{let t=G(e);return t.total?Math.round(t.done/t.total*100):0},Z=e=>e===`mvp`?`mint`:e===`release`?`lilac`:`ink`,ge=e=>({reached:`ok`,"at-risk":`risk`,planned:`plan`,missed:`miss`,cancelled:`off`})[e]??`plan`,_e=[`日`,`一`,`二`,`三`,`四`,`五`,`六`],ve=e=>`周${_e[new Date(`${e}T00:00:00Z`).getUTCDay()]}`,ye=e=>{let t=Y(e);return t>0?`还剩 ${t} 天`:t===0?`今天到期`:`已过 ${-t} 天`},Q=v(()=>{let e=J.value.findIndex(e=>e.due>=K);return e<0?J.value.length:e}),$=v(()=>({mvp:s.value.filter(e=>e.kind===`mvp`).length,release:s.value.filter(e=>e.kind===`release`).length,checkpoint:s.value.filter(e=>e.kind===`checkpoint`).length,risk:s.value.filter(e=>e.status===`at-risk`||e.status===`missed`).length,reached:s.value.filter(e=>e.status===`reached`).length}));return(t,r)=>{let v=ee,K=te,q=i;return c(),h(`div`,null,[f(`div`,b,[f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(0)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(0),size:`sm`},null,8,[`tone`]),r[1]||=f(`p`,{class:`k`},`MVP 节点`,-1),f(`p`,ie,[y(l(a($).mvp),1),r[0]||=f(`small`,null,`个`,-1)])],2),f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(1)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(1),size:`sm`},null,8,[`tone`]),r[3]||=f(`p`,{class:`k`},`发布节点`,-1),f(`p`,ae,[y(l(a($).release),1),r[2]||=f(`small`,null,`个`,-1)])],2),f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(2)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(2),size:`sm`},null,8,[`tone`]),r[5]||=f(`p`,{class:`k`},`检查点`,-1),f(`p`,oe,[y(l(a($).checkpoint),1),r[4]||=f(`small`,null,`个`,-1)])],2),f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(3)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(3),size:`sm`},null,8,[`tone`]),r[6]||=f(`p`,{class:`k`},`已达成`,-1),f(`p`,se,[y(l(a($).reached),1),f(`small`,null,`/ `+l(a(s).length),1)])],2),f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(4)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(4),size:`sm`},null,8,[`tone`]),r[8]||=f(`p`,{class:`k`},`有风险 / 错过`,-1),f(`p`,x,[y(l(a($).risk),1),r[7]||=f(`small`,null,`个`,-1)])],2)]),f(`div`,S,[f(`div`,C,[f(`h2`,w,[d(K,{name:`i-lucide-git-commit-vertical`,class:`size-3.5`}),r[9]||=y(`时间线`,-1)]),r[10]||=re(`<span class="dim tip" data-v-
|
|
1
|
+
import{a as e,i as t,o as n,r as ee,s as r}from"#entry";import{t as te}from"./DJM7u8P3.js";import{t as i}from"./CI0scS-N.js";import{At as a,K as o,S as s,U as c,Xt as l,Yt as u,b as d,d as f,f as p,i as m,lt as ne,m as h,p as g,qt as _,u as v,v as re,y}from"./BxuBMtk_.js";var b={class:`kpis`},ie={class:`v`},ae={class:`v`},oe={class:`v`},se={class:`v`},x={class:`v`},S={class:`card tl-wrap`},C={class:`card-hd tl-hd`},w={class:`h2`},T={class:`timeline`},E={key:0,class:`tl-today`},D={class:`tl-item`},O={class:`when`},k={class:`when-date mono`},A={class:`when-year`},j={class:`axis`},M={class:`node-top`},N={class:`tag tag-ghost`},P={key:0,class:`tag tag-neutral mono`},F={class:`node-title`},I={class:`criteria`},L={class:`nums`},R={class:`dim`},z={class:`mpct`},B={class:`mss`},ce={class:`st-id mono`},V={class:`st-title`},H={class:`st-state dim`},U={class:`st-pts dim`},W={key:0,class:`tl-today`},G=t(s({__name:`milestones`,setup(t){let{milestones:s,milestoneProgress:G,now:K,md:le,MS_LABEL:ue,MS_COLOR:de,KIND_LABEL:fe,KIND_ICON:pe,STATE_DOT:me,STATE_LABEL:he,diffDays:q}=r(),J=v(()=>[...s.value].sort((e,t)=>e.due<t.due?-1:+(e.due>t.due))),Y=e=>q(K,e),X=e=>{let t=G(e);return t.total?Math.round(t.done/t.total*100):0},Z=e=>e===`mvp`?`mint`:e===`release`?`lilac`:`ink`,ge=e=>({reached:`ok`,"at-risk":`risk`,planned:`plan`,missed:`miss`,cancelled:`off`})[e]??`plan`,_e=[`日`,`一`,`二`,`三`,`四`,`五`,`六`],ve=e=>`周${_e[new Date(`${e}T00:00:00Z`).getUTCDay()]}`,ye=e=>{let t=Y(e);return t>0?`还剩 ${t} 天`:t===0?`今天到期`:`已过 ${-t} 天`},Q=v(()=>{let e=J.value.findIndex(e=>e.due>=K);return e<0?J.value.length:e}),$=v(()=>({mvp:s.value.filter(e=>e.kind===`mvp`).length,release:s.value.filter(e=>e.kind===`release`).length,checkpoint:s.value.filter(e=>e.kind===`checkpoint`).length,risk:s.value.filter(e=>e.status===`at-risk`||e.status===`missed`).length,reached:s.value.filter(e=>e.status===`reached`).length}));return(t,r)=>{let v=ee,K=te,q=i;return c(),h(`div`,null,[f(`div`,b,[f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(0)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(0),size:`sm`},null,8,[`tone`]),r[1]||=f(`p`,{class:`k`},`MVP 节点`,-1),f(`p`,ie,[y(l(a($).mvp),1),r[0]||=f(`small`,null,`个`,-1)])],2),f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(1)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(1),size:`sm`},null,8,[`tone`]),r[3]||=f(`p`,{class:`k`},`发布节点`,-1),f(`p`,ae,[y(l(a($).release),1),r[2]||=f(`small`,null,`个`,-1)])],2),f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(2)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(2),size:`sm`},null,8,[`tone`]),r[5]||=f(`p`,{class:`k`},`检查点`,-1),f(`p`,oe,[y(l(a($).checkpoint),1),r[4]||=f(`small`,null,`个`,-1)])],2),f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(3)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(3),size:`sm`},null,8,[`tone`]),r[6]||=f(`p`,{class:`k`},`已达成`,-1),f(`p`,se,[y(l(a($).reached),1),f(`small`,null,`/ `+l(a(s).length),1)])],2),f(`div`,{class:_([`kpi`,(`cardToneClass`in t?t.cardToneClass:a(n))(4)])},[d(v,{tone:(`cardTone`in t?t.cardTone:a(e))(4),size:`sm`},null,8,[`tone`]),r[8]||=f(`p`,{class:`k`},`有风险 / 错过`,-1),f(`p`,x,[y(l(a($).risk),1),r[7]||=f(`small`,null,`个`,-1)])],2)]),f(`div`,S,[f(`div`,C,[f(`h2`,w,[d(K,{name:`i-lucide-git-commit-vertical`,class:`size-3.5`}),r[9]||=y(`时间线`,-1)]),r[10]||=re(`<span class="dim tip" data-v-75b2db69>按到期日从早到晚 · 节点达成口径是「挂的故事全部完成」</span><div class="legend" data-v-75b2db69><span class="lg" data-v-75b2db69><i class="sw mint" data-v-75b2db69></i>MVP</span><span class="lg" data-v-75b2db69><i class="sw lilac" data-v-75b2db69></i>发布</span><span class="lg" data-v-75b2db69><i class="sw white" data-v-75b2db69></i>检查点</span><i class="sep" data-v-75b2db69></i><span class="lg" data-v-75b2db69><i class="dot ok" data-v-75b2db69></i>已达成</span><span class="lg" data-v-75b2db69><i class="dot risk" data-v-75b2db69></i>有风险</span><span class="lg" data-v-75b2db69><i class="dot plan" data-v-75b2db69></i>计划中</span></div>`,2)]),f(`div`,T,[(c(!0),h(m,null,o(a(J),(e,t)=>(c(),h(m,{key:e.id},[t===a(Q)?(c(),h(`div`,E,[...r[11]||=[f(`span`,{class:`today-when`},`今天`,-1),f(`span`,{class:`today-axis`},[f(`i`)],-1),f(`span`,{class:`today-line`},null,-1)]])):g(``,!0),f(`article`,D,[f(`div`,O,[f(`p`,k,l(a(le)(e.due)),1),f(`p`,A,l(ve(e.due)),1)]),f(`div`,j,[f(`span`,{class:_([`dot-lg`,ge(e.status)])},[e.status===`reached`?(c(),p(K,{key:0,name:`i-lucide-check`,class:`size-2.5`})):e.status===`cancelled`?(c(),p(K,{key:1,name:`i-lucide-x`,class:`size-2.5`})):g(``,!0)],2)]),f(`div`,{class:_([`node`,`node-${Z(e.kind)}`])},[d(v,{tone:Z(e.kind),size:`xl`,min:3,max:5},null,8,[`tone`]),f(`div`,M,[f(`span`,N,l(e.id),1),f(`span`,{class:_([`tag`,`tag-${a(de)[e.status]}`])},l(a(ue)[e.status]),3),f(`span`,{class:_([`tag`,e.kind===`mvp`?`tag-mint`:e.kind===`release`?`tag-primary`:`tag-neutral`])},[d(K,{name:a(pe)[e.kind],class:`size-3`},null,8,[`name`]),y(l(a(fe)[e.kind]),1)],2),e.sprintId?(c(),h(`span`,P,l(e.sprintId),1)):g(``,!0),f(`span`,{class:_([`days`,{over:e.status!==`cancelled`&&Y(e.due)<0,soon:e.status!==`cancelled`&&Y(e.due)>=0&&Y(e.due)<=7}])},l(e.status===`cancelled`?`不再跟踪`:ye(e.due)),3)]),f(`h3`,F,l(e.title),1),f(`p`,I,l(e.criteria),1),f(`div`,L,[f(`span`,null,[f(`b`,null,l(a(G)(e).done)+`/`+l(a(G)(e).total),1),r[12]||=y(` 个故事`,-1)]),a(G)(e).cancelled?(c(),h(m,{key:0},[r[13]||=f(`span`,{class:`dim`},`·`,-1),f(`span`,R,l(a(G)(e).cancelled)+` 个已取消`,1)],64)):g(``,!0),r[14]||=f(`span`,{class:`dim`},`·`,-1),f(`span`,null,l(a(G)(e).points)+` 点`,1),f(`span`,z,l(X(e))+`%`,1)]),f(`div`,{class:_([`bar`,e.kind===`checkpoint`?``:Z(e.kind)])},[f(`i`,{style:u({width:X(e)+`%`})},null,4)],2),f(`ul`,B,[(c(!0),h(m,null,o(a(G)(e).list,e=>(c(),h(`li`,{key:e.id},[d(q,{to:`/story/${e.id}`,class:`srow`},{default:ne(()=>[f(`i`,{class:`sdot`,style:u({background:a(me)[e.status]})},null,4),f(`span`,ce,l(e.id),1),f(`span`,V,l(e.title),1),f(`span`,H,l(a(he)[e.status]),1),f(`span`,U,l(e.points),1)]),_:2},1032,[`to`])]))),128))])],2)])],64))),128)),a(Q)===a(J).length?(c(),h(`div`,W,[...r[15]||=[f(`span`,{class:`today-when`},`今天`,-1),f(`span`,{class:`today-axis`},[f(`i`)],-1),f(`span`,{class:`today-line`},null,-1)]])):g(``,!0)])])])}}}),[[`__scopeId`,`data-v-75b2db69`]]);export{G as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,o as n,r,s as i}from"#entry";import{t as a}from"./DJM7u8P3.js";import{t as o}from"./CI0scS-N.js";import{At as s,K as c,S as l,U as u,Xt as d,Yt as f,b as p,d as m,i as h,lt as g,m as _,p as v,qt as y,u as b,y as x}from"./BxuBMtk_.js";var ee={class:`kpis`},te={class:`v`},S={class:`v`},C={class:`v`},w={class:`v`},T={class:`v`},E={class:`grid`},D={class:`hero`},O={class:`hero-top`},k={class:`tag tag-ghost`},A={class:`tag tag-neutral`},j={key:0,class:`tag tag-error`},M={key:1,class:`tag tag-warning`},N={class:`hero-pct`},P={class:`epic-title`},F={class:`goal`},I={class:`bar ink hero-bar`},L={class:`hero-foot`},ne={class:`bd`},R={class:`h3`},z={key:0,class:`dim empty`},B={class:`kr-top`},V={class:`kr-text`},H={class:`kr-num mono`},U={class:`h3 stories-hd`},W={class:`stlist`},G={class:`st-id mono`},K={class:`st-title`},q={class:`st-pts dim`},J={class:`st-state dim`},Y=t(l({__name:`epics`,setup(t){let{epics:l,storyById:Y,STATE_LABEL:X,STATE_DOT:Z,TYPE_LABEL:re,TYPE_COLOR:ie,TYPE_ICON:ae,PRIORITY_COLOR:oe}=i(),se={draft:`neutral`,active:`primary`,done:`success`,cancelled:`error`},ce={draft:`草稿`,active:`进行中`,done:`已完成`,cancelled:`已取消`},Q=b(()=>l.value.map(e=>{let t=(e.stories??[]).map(e=>Y.value.get(e)).filter(Boolean),n=t.filter(e=>e.status===`done`),r=t.reduce((e,t)=>e+t.points,0),i=n.reduce((e,t)=>e+t.points,0),a=(e.keyResults??[]).map(e=>{let t=e.target>0?Math.min(100,Math.round((e.current??0)/e.target*100)):(e.current??0)<=0?100:0;return{...e,pct:t,ok:t>=100}});return{...e,list:t,done:n,points:r,donePoints:i,pct:r?Math.round(i/r*100):0,krs:a,krOk:a.filter(e=>e.ok).length,blocked:t.filter(e=>e.blocked),bugs:t.filter(e=>e.type===`bug`)}})),$=b(()=>({epics:Q.value.length,stories:Q.value.reduce((e,t)=>e+t.list.length,0),points:Q.value.reduce((e,t)=>e+t.points,0),donePoints:Q.value.reduce((e,t)=>e+t.donePoints,0),kr:Q.value.reduce((e,t)=>e+t.krs.length,0),krOk:Q.value.reduce((e,t)=>e+t.krOk,0),blocked:Q.value.reduce((e,t)=>e+t.blocked.length,0)}));return(t,i)=>{let l=r,b=a,Y=o;return u(),_(`div`,null,[m(`div`,ee,[m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(0)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(0),size:`sm`},null,8,[`tone`]),i[1]||=m(`p`,{class:`k`},`史诗`,-1),m(`p`,te,[x(d(s($).epics),1),i[0]||=m(`small`,null,`个`,-1)])],2),m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(1)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(1),size:`sm`},null,8,[`tone`]),i[2]||=m(`p`,{class:`k`},`关键结果达成`,-1),m(`p`,S,[x(d(s($).krOk),1),m(`small`,null,`/ `+d(s($).kr),1)])],2),m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(2)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(2),size:`sm`},null,8,[`tone`]),i[3]||=m(`p`,{class:`k`},`故事点交付`,-1),m(`p`,C,[x(d(s($).donePoints),1),m(`small`,null,`/ `+d(s($).points),1)])],2),m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(3)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(3),size:`sm`},null,8,[`tone`]),i[5]||=m(`p`,{class:`k`},`覆盖故事`,-1),m(`p`,w,[x(d(s($).stories),1),i[4]||=m(`small`,null,`个`,-1)])],2),m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(4)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(4),size:`sm`},null,8,[`tone`]),i[7]||=m(`p`,{class:`k`},`阻塞`,-1),m(`p`,T,[x(d(s($).blocked),1),i[6]||=m(`small`,null,`个故事`,-1)])],2)]),m(`div`,E,[(u(!0),_(h,null,c(s(Q),e=>(u(),_(`article`,{key:e.id,class:`card epic`},[m(`div`,D,[m(`div`,O,[m(`span`,k,d(e.id),1),m(`span`,{class:y([`tag`,`tag-${se[e.status]}`])},d(ce[e.status]),3),m(`span`,A,d(e.list.length)+` 个故事`,1),e.bugs.length?(u(),_(`span`,j,[p(b,{name:`i-lucide-bug`,class:`size-3`}),x(d(e.bugs.length),1)])):v(``,!0),e.blocked.length?(u(),_(`span`,M,[p(b,{name:`i-lucide-octagon-alert`,class:`size-3`}),x(d(e.blocked.length),1)])):v(``,!0),m(`span`,N,[x(d(e.pct),1),i[8]||=m(`small`,null,`%`,-1)])]),m(`h2`,P,d(e.title),1),m(`p`,F,d(e.goal),1),m(`div`,I,[m(`i`,{style:f({width:e.pct+`%`})},null,4)]),m(`div`,L,[m(`span`,null,[m(`b`,null,d(e.donePoints),1),x(`/`+d(e.points)+` 点`,1)]),i[9]||=m(`i`,{class:`sep`},null,-1),m(`span`,null,`关键结果 `+d(e.krOk)+`/`+d(e.krs.length)+` 达成`,1),i[10]||=m(`i`,{class:`sep`},null,-1),m(`span`,null,d(e.done.length)+`/`+d(e.list.length)+` 个故事完成`,1)])]),m(`div`,ne,[m(`p`,R,[p(b,{name:`i-lucide-target`,class:`size-3`}),i[11]||=x(`关键结果`,-1)]),e.krs.length?v(``,!0):(u(),_(`p`,z,`这个史诗还没写 keyResults。`)),(u(!0),_(h,null,c(e.krs,e=>(u(),_(`div`,{key:e.id,class:`kr`},[m(`div`,B,[m(`span`,V,d(e.text),1),m(`span`,H,d(e.current??`—`)+` / `+d(e.target)+` `+d(e.unit??``),1),m(`span`,{class:y([`tag`,e.ok?`tag-success`:`tag-warning`])},d(e.pct)+`%`,3)]),m(`div`,{class:y([`bar slim`,e.ok?`mint`:`lilac`])},[m(`i`,{style:f({width:e.pct+`%`})},null,4)],2)]))),128)),m(`p`,U,[p(b,{name:`i-lucide-list-checks`,class:`size-3`}),i[12]||=x(`故事`,-1)]),m(`ul`,W,[(u(!0),_(h,null,c(e.list,e=>(u(),_(`li`,{key:e.id},[p(Y,{to:`/story/${e.id}`,class:`strow`},{default:g(()=>[m(`i`,{class:`sdot`,style:f({background:s(Z)[e.status]})},null,4),m(`span`,G,d(e.id),1),m(`span`,K,d(e.title),1),m(`span`,{class:y([`tag`,`tag-${s(ie)[e.type]}`])},[p(b,{name:s(ae)[e.type],class:`size-3`},null,8,[`name`]),x(d(s(re)[e.type]),1)],2),m(`span`,{class:y([`tag`,`tag-${s(oe)[e.priority]}`])},d(e.priority),3),m(`span`,q,d(e.points)+` 点`,1),m(`span`,J,d(s(X)[e.status]),1),p(b,{name:`i-lucide-chevron-right`,class:`st-chev`})]),_:2},1032,[`to`])]))),128))])])]))),128))])])}}}),[[`__scopeId`,`data-v-
|
|
1
|
+
import{a as e,i as t,o as n,r,s as i}from"#entry";import{t as a}from"./DJM7u8P3.js";import{t as o}from"./CI0scS-N.js";import{At as s,K as c,S as l,U as u,Xt as d,Yt as f,b as p,d as m,i as h,lt as g,m as _,p as v,qt as y,u as b,y as x}from"./BxuBMtk_.js";var ee={class:`kpis`},te={class:`v`},S={class:`v`},C={class:`v`},w={class:`v`},T={class:`v`},E={class:`grid`},D={class:`hero`},O={class:`hero-top`},k={class:`tag tag-ghost`},A={class:`tag tag-neutral`},j={key:0,class:`tag tag-error`},M={key:1,class:`tag tag-warning`},N={class:`hero-pct`},P={class:`epic-title`},F={class:`goal`},I={class:`bar ink hero-bar`},L={class:`hero-foot`},ne={class:`bd`},R={class:`h3`},z={key:0,class:`dim empty`},B={class:`kr-top`},V={class:`kr-text`},H={class:`kr-num mono`},U={class:`h3 stories-hd`},W={class:`stlist`},G={class:`st-id mono`},K={class:`st-title`},q={class:`st-pts dim`},J={class:`st-state dim`},Y=t(l({__name:`epics`,setup(t){let{epics:l,storyById:Y,STATE_LABEL:X,STATE_DOT:Z,TYPE_LABEL:re,TYPE_COLOR:ie,TYPE_ICON:ae,PRIORITY_COLOR:oe}=i(),se={draft:`neutral`,active:`primary`,done:`success`,cancelled:`error`},ce={draft:`草稿`,active:`进行中`,done:`已完成`,cancelled:`已取消`},Q=b(()=>l.value.map(e=>{let t=(e.stories??[]).map(e=>Y.value.get(e)).filter(Boolean),n=t.filter(e=>e.status===`done`),r=t.reduce((e,t)=>e+t.points,0),i=n.reduce((e,t)=>e+t.points,0),a=(e.keyResults??[]).map(e=>{let t=e.target>0?Math.min(100,Math.round((e.current??0)/e.target*100)):(e.current??0)<=0?100:0;return{...e,pct:t,ok:t>=100}});return{...e,list:t,done:n,points:r,donePoints:i,pct:r?Math.round(i/r*100):0,krs:a,krOk:a.filter(e=>e.ok).length,blocked:t.filter(e=>e.blocked),bugs:t.filter(e=>e.type===`bug`)}})),$=b(()=>({epics:Q.value.length,stories:Q.value.reduce((e,t)=>e+t.list.length,0),points:Q.value.reduce((e,t)=>e+t.points,0),donePoints:Q.value.reduce((e,t)=>e+t.donePoints,0),kr:Q.value.reduce((e,t)=>e+t.krs.length,0),krOk:Q.value.reduce((e,t)=>e+t.krOk,0),blocked:Q.value.reduce((e,t)=>e+t.blocked.length,0)}));return(t,i)=>{let l=r,b=a,Y=o;return u(),_(`div`,null,[m(`div`,ee,[m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(0)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(0),size:`sm`},null,8,[`tone`]),i[1]||=m(`p`,{class:`k`},`史诗`,-1),m(`p`,te,[x(d(s($).epics),1),i[0]||=m(`small`,null,`个`,-1)])],2),m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(1)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(1),size:`sm`},null,8,[`tone`]),i[2]||=m(`p`,{class:`k`},`关键结果达成`,-1),m(`p`,S,[x(d(s($).krOk),1),m(`small`,null,`/ `+d(s($).kr),1)])],2),m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(2)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(2),size:`sm`},null,8,[`tone`]),i[3]||=m(`p`,{class:`k`},`故事点交付`,-1),m(`p`,C,[x(d(s($).donePoints),1),m(`small`,null,`/ `+d(s($).points),1)])],2),m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(3)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(3),size:`sm`},null,8,[`tone`]),i[5]||=m(`p`,{class:`k`},`覆盖故事`,-1),m(`p`,w,[x(d(s($).stories),1),i[4]||=m(`small`,null,`个`,-1)])],2),m(`div`,{class:y([`kpi`,(`cardToneClass`in t?t.cardToneClass:s(n))(4)])},[p(l,{tone:(`cardTone`in t?t.cardTone:s(e))(4),size:`sm`},null,8,[`tone`]),i[7]||=m(`p`,{class:`k`},`阻塞`,-1),m(`p`,T,[x(d(s($).blocked),1),i[6]||=m(`small`,null,`个故事`,-1)])],2)]),m(`div`,E,[(u(!0),_(h,null,c(s(Q),e=>(u(),_(`article`,{key:e.id,class:`card epic`},[m(`div`,D,[m(`div`,O,[m(`span`,k,d(e.id),1),m(`span`,{class:y([`tag`,`tag-${se[e.status]}`])},d(ce[e.status]),3),m(`span`,A,d(e.list.length)+` 个故事`,1),e.bugs.length?(u(),_(`span`,j,[p(b,{name:`i-lucide-bug`,class:`size-3`}),x(d(e.bugs.length),1)])):v(``,!0),e.blocked.length?(u(),_(`span`,M,[p(b,{name:`i-lucide-octagon-alert`,class:`size-3`}),x(d(e.blocked.length),1)])):v(``,!0),m(`span`,N,[x(d(e.pct),1),i[8]||=m(`small`,null,`%`,-1)])]),m(`h2`,P,d(e.title),1),m(`p`,F,d(e.goal),1),m(`div`,I,[m(`i`,{style:f({width:e.pct+`%`})},null,4)]),m(`div`,L,[m(`span`,null,[m(`b`,null,d(e.donePoints),1),x(`/`+d(e.points)+` 点`,1)]),i[9]||=m(`i`,{class:`sep`},null,-1),m(`span`,null,`关键结果 `+d(e.krOk)+`/`+d(e.krs.length)+` 达成`,1),i[10]||=m(`i`,{class:`sep`},null,-1),m(`span`,null,d(e.done.length)+`/`+d(e.list.length)+` 个故事完成`,1)])]),m(`div`,ne,[m(`p`,R,[p(b,{name:`i-lucide-target`,class:`size-3`}),i[11]||=x(`关键结果`,-1)]),e.krs.length?v(``,!0):(u(),_(`p`,z,`这个史诗还没写 keyResults。`)),(u(!0),_(h,null,c(e.krs,e=>(u(),_(`div`,{key:e.id,class:`kr`},[m(`div`,B,[m(`span`,V,d(e.text),1),m(`span`,H,d(e.current??`—`)+` / `+d(e.target)+` `+d(e.unit??``),1),m(`span`,{class:y([`tag`,e.ok?`tag-success`:`tag-warning`])},d(e.pct)+`%`,3)]),m(`div`,{class:y([`bar slim`,e.ok?`mint`:`lilac`])},[m(`i`,{style:f({width:e.pct+`%`})},null,4)],2)]))),128)),m(`p`,U,[p(b,{name:`i-lucide-list-checks`,class:`size-3`}),i[12]||=x(`故事`,-1)]),m(`ul`,W,[(u(!0),_(h,null,c(e.list,e=>(u(),_(`li`,{key:e.id},[p(Y,{to:`/story/${e.id}`,class:`strow`},{default:g(()=>[m(`i`,{class:`sdot`,style:f({background:s(Z)[e.status]})},null,4),m(`span`,G,d(e.id),1),m(`span`,K,d(e.title),1),m(`span`,{class:y([`tag`,`tag-${s(ie)[e.type]}`])},[p(b,{name:s(ae)[e.type],class:`size-3`},null,8,[`name`]),x(d(s(re)[e.type]),1)],2),m(`span`,{class:y([`tag`,`tag-${s(oe)[e.priority]}`])},d(e.priority),3),m(`span`,q,d(e.points)+` 点`,1),m(`span`,J,d(s(X)[e.status]),1),p(b,{name:`i-lucide-chevron-right`,class:`st-chev`})]),_:2},1032,[`to`])]))),128))])])]))),128))])])}}}),[[`__scopeId`,`data-v-6cff08c9`]]);export{Y as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,o as n,r as ee,s as r}from"#entry";import{t as te}from"./OKKaKILz.js";import{t as ne}from"./DJM7u8P3.js";import{t as re}from"./CI0scS-N.js";import{At as i,K as a,S as o,U as s,Xt as c,Yt as ie,b as l,d as u,gt as ae,i as d,lt as oe,m as f,ot as p,p as m,qt as h,u as g,ut as se,v as _,xt as v,y}from"./BxuBMtk_.js";import{o as ce}from"./BygIGL69.js";var le={class:`kpis`},ue={class:`v`},de={class:`v`},fe={class:`v`},pe={class:`v`},me={key:0,class:`card panel`},he={class:`panel-hd`},ge={class:`ph-l`},_e={class:`sp-name`},ve={class:`sub mono`},ye={class:`goal`},be={class:`chart-wrap`},xe=[`viewBox`],Se=[`y1`,`x2`,`y2`],b=[`x`,`y`],x=[`d`],S=[`d`],C=[`points`],w=[`cx`,`cy`],T=[`x1`,`y1`,`x2`,`y2`],E=[`x`,`y`],D=[`x`,`y`],O=[`x1`,`y1`,`x2`,`y2`],k=[`cx`,`cy`],A={class:`cells`},j={class:`cd mono`},Ce={class:`ca`},we={class:`ci dim`},Te={key:0,class:`scope`},Ee={class:`h3`},De={class:`tag tag-info`},Oe={class:`dim`},ke={key:1,class:`callout soft`},Ae={class:`card`},je={class:`card-hd`},Me={class:`tag tag-neutral`},Ne={class:`card-bd`},Pe={class:`tbl`},Fe=[`onClick`],Ie={class:`mono`},Le={class:`mono dim`},Re={class:`r`},ze={class:`r mono`},Be=980,Ve=300,M=42,N=t(o({__name:`burndown`,setup(t){let{sprints:o,burndown:N,sprintCommit:P,md:F,now:I,sprintById:L,storyById:He,SCOPE_LABEL:R}=r(),z=v(``),Ue=g(()=>[...o.value].reverse().map(e=>({label:`${e.id} · ${e.name}`,value:e.id,icon:`i-lucide-calendar-range`}))),B=g(()=>L.value.get(z.value)??o.value[o.value.length-1]),V=g(()=>B.value?N(B.value):{total:0,days:[]});p(()=>{z.value&&!L.value.has(z.value)&&(z.value=``),!z.value&&o.value.length&&(z.value=o.value[o.value.length-1].id)});let H=g(()=>V.value.days.length||1),U=g(()=>V.value.total||1),W=e=>M+e*896/(H.value-1||1),G=e=>258-e*216/U.value,K=e=>V.value.days.map((t,n)=>`${W(n)},${G(t[e])}`).join(` `),We=g(()=>{let e=V.value.days.map((e,t)=>`${W(t)},${G(e.actual)}`).join(` `),t=V.value.days.length-1;return`M${W(0)},${G(0)} L${e.replaceAll(` `,` L`)} L${W(t)},${G(0)} Z`}),q=g(()=>V.value.days.findIndex(e=>e.date===I)),J=g(()=>V.value.days.find(e=>e.date===I)??V.value.days[V.value.days.length-1]),Y=g(()=>J.value?.actual??0),X=g(()=>J.value?.ideal??0),Z=g(()=>Math.round((Y.value-X.value)*10)/10),Q=g(()=>{let e=B.value;return e?(e.stories??[]).map(e=>He.value.get(e)).filter(Boolean).filter(t=>t.scopeChange&&t.scopeChange.at>=e.start&&t.scopeChange.at<=e.end).map(e=>({id:e.id,title:e.title,at:e.scopeChange.at,kind:e.scopeChange.kind,reason:e.scopeChange.reason,points:e.points,idx:V.value.days.findIndex(t=>t.date===e.scopeChange.at)})).filter(e=>e.idx>=0):[]}),Ge=g(()=>new Set(Q.value.map(e=>e.at))),$=g(()=>[...o.value].reverse().map(e=>{let t=e.start<=I&&e.end>=I;return{id:e.id,name:e.name,period:`${F(e.start)} ~ ${F(e.end)}`,stories:(e.stories??[]).length,commit:P(e),capacity:e.capacity,status:t?`进行中`:e.end<I?`已结束`:`未开始`,tone:t?`tag-primary`:e.end<I?`tag-neutral`:`tag-info`}}));return(t,r)=>{let o=ee,p=te,g=ne,v=re;return s(),f(`div`,null,[u(`div`,le,[u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(0)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(0),size:`sm`},null,8,[`tone`]),r[1]||=u(`p`,{class:`k`},`剩余故事点`,-1),u(`p`,ue,[y(c(i(Y)),1),u(`small`,null,`/ `+c(i(V).total),1)])],2),u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(1)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(1),size:`sm`},null,8,[`tone`]),r[3]||=u(`p`,{class:`k`},`理想剩余(今天)`,-1),u(`p`,de,[y(c(i(X)),1),r[2]||=u(`small`,null,`点`,-1)])],2),u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(2)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(2),size:`sm`},null,8,[`tone`]),r[5]||=u(`p`,{class:`k`},`偏差`,-1),u(`p`,{class:h([`v`,{bad:i(Z)>0,good:i(Z)<=0}])},[y(c(i(Z)>0?`+`+i(Z):i(Z)),1),r[4]||=u(`small`,null,`点`,-1)],2)],2),u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(3)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(3),size:`sm`},null,8,[`tone`]),r[6]||=u(`p`,{class:`k`},`承诺 / 容量`,-1),u(`p`,fe,[y(c(i(B)?i(P)(i(B)):0),1),u(`small`,null,`/ `+c(i(B)?.capacity??0),1)])],2),u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(4)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(4),size:`sm`},null,8,[`tone`]),r[8]||=u(`p`,{class:`k`},`范围变更`,-1),u(`p`,pe,[y(c(i(Q).length),1),r[7]||=u(`small`,null,`次`,-1)])],2)]),i(B)?(s(),f(`div`,me,[u(`div`,he,[u(`div`,ge,[u(`h2`,_e,c(i(B).name),1),u(`p`,ve,c(i(B).id)+` · `+c(i(F)(i(B).start))+` ~ `+c(i(F)(i(B).end)),1),u(`p`,ye,c(i(B).goal),1)]),l(p,{modelValue:i(z),"onUpdate:modelValue":r[0]||=e=>ae(z)?z.value=e:null,items:i(Ue),icon:`i-lucide-calendar-range`,"aria-label":`选择迭代`,class:`bd-select`},null,8,[`modelValue`,`items`])]),u(`div`,be,[r[10]||=_(`<div class="chart-legend" data-v-
|
|
1
|
+
import{a as e,i as t,o as n,r as ee,s as r}from"#entry";import{t as te}from"./OKKaKILz.js";import{t as ne}from"./DJM7u8P3.js";import{t as re}from"./CI0scS-N.js";import{At as i,K as a,S as o,U as s,Xt as c,Yt as ie,b as l,d as u,gt as ae,i as d,lt as oe,m as f,ot as p,p as m,qt as h,u as g,ut as se,v as _,xt as v,y}from"./BxuBMtk_.js";import{o as ce}from"./BygIGL69.js";var le={class:`kpis`},ue={class:`v`},de={class:`v`},fe={class:`v`},pe={class:`v`},me={key:0,class:`card panel`},he={class:`panel-hd`},ge={class:`ph-l`},_e={class:`sp-name`},ve={class:`sub mono`},ye={class:`goal`},be={class:`chart-wrap`},xe=[`viewBox`],Se=[`y1`,`x2`,`y2`],b=[`x`,`y`],x=[`d`],S=[`d`],C=[`points`],w=[`cx`,`cy`],T=[`x1`,`y1`,`x2`,`y2`],E=[`x`,`y`],D=[`x`,`y`],O=[`x1`,`y1`,`x2`,`y2`],k=[`cx`,`cy`],A={class:`cells`},j={class:`cd mono`},Ce={class:`ca`},we={class:`ci dim`},Te={key:0,class:`scope`},Ee={class:`h3`},De={class:`tag tag-info`},Oe={class:`dim`},ke={key:1,class:`callout soft`},Ae={class:`card`},je={class:`card-hd`},Me={class:`tag tag-neutral`},Ne={class:`card-bd`},Pe={class:`tbl`},Fe=[`onClick`],Ie={class:`mono`},Le={class:`mono dim`},Re={class:`r`},ze={class:`r mono`},Be=980,Ve=300,M=42,N=t(o({__name:`burndown`,setup(t){let{sprints:o,burndown:N,sprintCommit:P,md:F,now:I,sprintById:L,storyById:He,SCOPE_LABEL:R}=r(),z=v(``),Ue=g(()=>[...o.value].reverse().map(e=>({label:`${e.id} · ${e.name}`,value:e.id,icon:`i-lucide-calendar-range`}))),B=g(()=>L.value.get(z.value)??o.value[o.value.length-1]),V=g(()=>B.value?N(B.value):{total:0,days:[]});p(()=>{z.value&&!L.value.has(z.value)&&(z.value=``),!z.value&&o.value.length&&(z.value=o.value[o.value.length-1].id)});let H=g(()=>V.value.days.length||1),U=g(()=>V.value.total||1),W=e=>M+e*896/(H.value-1||1),G=e=>258-e*216/U.value,K=e=>V.value.days.map((t,n)=>`${W(n)},${G(t[e])}`).join(` `),We=g(()=>{let e=V.value.days.map((e,t)=>`${W(t)},${G(e.actual)}`).join(` `),t=V.value.days.length-1;return`M${W(0)},${G(0)} L${e.replaceAll(` `,` L`)} L${W(t)},${G(0)} Z`}),q=g(()=>V.value.days.findIndex(e=>e.date===I)),J=g(()=>V.value.days.find(e=>e.date===I)??V.value.days[V.value.days.length-1]),Y=g(()=>J.value?.actual??0),X=g(()=>J.value?.ideal??0),Z=g(()=>Math.round((Y.value-X.value)*10)/10),Q=g(()=>{let e=B.value;return e?(e.stories??[]).map(e=>He.value.get(e)).filter(Boolean).filter(t=>t.scopeChange&&t.scopeChange.at>=e.start&&t.scopeChange.at<=e.end).map(e=>({id:e.id,title:e.title,at:e.scopeChange.at,kind:e.scopeChange.kind,reason:e.scopeChange.reason,points:e.points,idx:V.value.days.findIndex(t=>t.date===e.scopeChange.at)})).filter(e=>e.idx>=0):[]}),Ge=g(()=>new Set(Q.value.map(e=>e.at))),$=g(()=>[...o.value].reverse().map(e=>{let t=e.start<=I&&e.end>=I;return{id:e.id,name:e.name,period:`${F(e.start)} ~ ${F(e.end)}`,stories:(e.stories??[]).length,commit:P(e),capacity:e.capacity,status:t?`进行中`:e.end<I?`已结束`:`未开始`,tone:t?`tag-primary`:e.end<I?`tag-neutral`:`tag-info`}}));return(t,r)=>{let o=ee,p=te,g=ne,v=re;return s(),f(`div`,null,[u(`div`,le,[u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(0)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(0),size:`sm`},null,8,[`tone`]),r[1]||=u(`p`,{class:`k`},`剩余故事点`,-1),u(`p`,ue,[y(c(i(Y)),1),u(`small`,null,`/ `+c(i(V).total),1)])],2),u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(1)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(1),size:`sm`},null,8,[`tone`]),r[3]||=u(`p`,{class:`k`},`理想剩余(今天)`,-1),u(`p`,de,[y(c(i(X)),1),r[2]||=u(`small`,null,`点`,-1)])],2),u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(2)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(2),size:`sm`},null,8,[`tone`]),r[5]||=u(`p`,{class:`k`},`偏差`,-1),u(`p`,{class:h([`v`,{bad:i(Z)>0,good:i(Z)<=0}])},[y(c(i(Z)>0?`+`+i(Z):i(Z)),1),r[4]||=u(`small`,null,`点`,-1)],2)],2),u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(3)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(3),size:`sm`},null,8,[`tone`]),r[6]||=u(`p`,{class:`k`},`承诺 / 容量`,-1),u(`p`,fe,[y(c(i(B)?i(P)(i(B)):0),1),u(`small`,null,`/ `+c(i(B)?.capacity??0),1)])],2),u(`div`,{class:h([`kpi`,(`cardToneClass`in t?t.cardToneClass:i(n))(4)])},[l(o,{tone:(`cardTone`in t?t.cardTone:i(e))(4),size:`sm`},null,8,[`tone`]),r[8]||=u(`p`,{class:`k`},`范围变更`,-1),u(`p`,pe,[y(c(i(Q).length),1),r[7]||=u(`small`,null,`次`,-1)])],2)]),i(B)?(s(),f(`div`,me,[u(`div`,he,[u(`div`,ge,[u(`h2`,_e,c(i(B).name),1),u(`p`,ve,c(i(B).id)+` · `+c(i(F)(i(B).start))+` ~ `+c(i(F)(i(B).end)),1),u(`p`,ye,c(i(B).goal),1)]),l(p,{modelValue:i(z),"onUpdate:modelValue":r[0]||=e=>ae(z)?z.value=e:null,items:i(Ue),icon:`i-lucide-calendar-range`,"aria-label":`选择迭代`,class:`bd-select`},null,8,[`modelValue`,`items`])]),u(`div`,be,[r[10]||=_(`<div class="chart-legend" data-v-8a03a4f8><span class="lg" data-v-8a03a4f8><i class="sw actual" data-v-8a03a4f8></i>实际剩余</span><span class="lg" data-v-8a03a4f8><i class="sw ideal" data-v-8a03a4f8></i>理想线</span><span class="lg" data-v-8a03a4f8><i class="sw scope" data-v-8a03a4f8></i>范围变更</span></div>`,1),(s(),f(`svg`,{viewBox:`0 0 ${Be} ${Ve}`,class:`chart`,role:`img`},[r[9]||=_(`<defs data-v-8a03a4f8><linearGradient id="bd-line" x1="0" y1="0" x2="1" y2="0" data-v-8a03a4f8><stop offset="0%" stop-color="#8a63f7" data-v-8a03a4f8></stop><stop offset="100%" stop-color="#c3aefb" data-v-8a03a4f8></stop></linearGradient><linearGradient id="bd-area" x1="0" y1="0" x2="0" y2="1" data-v-8a03a4f8><stop offset="0%" stop-color="#8a63f7" stop-opacity="0.16" data-v-8a03a4f8></stop><stop offset="100%" stop-color="#8a63f7" stop-opacity="0" data-v-8a03a4f8></stop></linearGradient></defs>`,1),u(`g`,null,[(s(),f(d,null,a([0,.25,.5,.75,1],e=>u(`line`,{key:`grid`+e,x1:M,y1:G(i(U)*e),x2:938,y2:G(i(U)*e),stroke:`#f1f0ea`,"stroke-width":`1`},null,8,Se)),64)),(s(),f(d,null,a([0,.25,.5,.75,1],e=>u(`text`,{key:`gl`+e,x:32,y:G(i(U)*e)+3.5,"text-anchor":`end`,"font-size":`9.5`,fill:`#b0b4ba`},c(Math.round(i(U)*e)),9,b)),64))]),u(`path`,{d:i(We),fill:`url(#bd-area)`},null,8,x),u(`path`,{d:`M${W(0)},${G(i(U))} L${W(i(H)-1)},${G(0)}`,stroke:`#cdc9d8`,"stroke-width":`1.4`,"stroke-dasharray":`5 5`,fill:`none`},null,8,S),u(`polyline`,{points:K(`actual`),stroke:`url(#bd-line)`,"stroke-width":`2.6`,fill:`none`,"stroke-linejoin":`round`,"stroke-linecap":`round`},null,8,C),(s(!0),f(d,null,a(i(V).days,(e,t)=>(s(),f(`circle`,{key:e.date,cx:W(t),cy:G(e.actual),r:`3`,fill:`#fff`,stroke:`#8a63f7`,"stroke-width":`1.8`},null,8,w))),128)),i(q)>=0?(s(),f(`line`,{key:0,x1:W(i(q)),y1:34,x2:W(i(q)),y2:G(0),stroke:`#cf4759`,"stroke-dasharray":`3 3`,"stroke-width":`1.2`,opacity:`0.7`},null,8,T)):m(``,!0),i(q)>=0?(s(),f(`text`,{key:1,x:W(i(q)),y:28,"text-anchor":`middle`,"font-size":`9.5`,fill:`#a5382f`},`今天`,8,E)):m(``,!0),(s(!0),f(d,null,a(i(V).days,(e,t)=>se((s(),f(`text`,{key:`t`+e.date,x:W(t),y:286,"text-anchor":`middle`,"font-size":`9.5`,fill:`#b0b4ba`},c(i(F)(e.date)),9,D)),[[ce,t%Math.ceil(i(H)/10)===0]])),128)),(s(!0),f(d,null,a(i(Q),e=>(s(),f(`g`,{key:e.at+e.id},[u(`title`,null,c(e.id)+` `+c(e.title)+`:`+c(i(R)[e.kind])+`(`+c(e.at)+`,`+c(e.points)+` 点)—— `+c(e.reason),1),u(`line`,{x1:W(e.idx),y1:36,x2:W(e.idx),y2:G(0),stroke:`#3f7fd4`,"stroke-dasharray":`4 3`,"stroke-width":`1.2`,opacity:`0.8`},null,8,O),u(`circle`,{cx:W(e.idx),cy:34,r:`3`,fill:`#3f7fd4`},null,8,k)]))),128))],8,xe))]),u(`div`,A,[(s(!0),f(d,null,a(i(V).days,e=>(s(),f(`div`,{key:`row`+e.date,class:h([`cell`,{today:e.date===i(I),future:e.date>i(I),scope:i(Ge).has(e.date)}])},[u(`span`,j,c(i(F)(e.date)),1),u(`span`,Ce,c(e.actual),1),u(`span`,we,c(e.ideal),1),u(`i`,{class:`underline`,style:ie({width:(i(U)?e.actual/i(U)*100:0)+`%`})},null,4)],2))),128))]),r[12]||=u(`p`,{class:`foot dim`},`每格:日期 / 实际剩余 / 理想剩余`,-1),i(Q).length?(s(),f(`div`,Te,[u(`p`,Ee,[l(g,{name:`i-lucide-git-branch`,class:`size-3`}),y(`本迭代范围变更(`+c(i(Q).length)+`)`,1)]),u(`ul`,null,[(s(!0),f(d,null,a(i(Q),e=>(s(),f(`li`,{key:e.id},[u(`span`,De,c(i(R)[e.kind]),1),l(v,{to:`/story/${e.id}`,class:`mono link`},{default:oe(()=>[y(c(e.id),1)]),_:2},1032,[`to`]),u(`span`,null,c(e.title),1),u(`span`,Oe,`· `+c(e.at)+` · `+c(e.points)+` 点 · `+c(e.reason),1)]))),128))]),r[11]||=u(`p`,{class:`foot dim`},`竖线标出的那几天,实际剩余没有按理想线下滑,是插了活而不是团队拖。`,-1)])):m(``,!0)])):(s(),f(`div`,ke,[l(g,{name:`i-lucide-info`,class:`size-4`}),r[13]||=y(`还没有迭代数据。 `,-1)])),u(`div`,Ae,[u(`div`,je,[r[14]||=u(`h2`,{class:`h2`},`迭代对照`,-1),u(`span`,Me,c(i($).length),1),r[15]||=u(`span`,{class:`dim tip`},`点一行切换上面的燃尽图`,-1)]),u(`div`,Ne,[u(`table`,Pe,[r[16]||=u(`thead`,null,[u(`tr`,null,[u(`th`,null,`迭代`),u(`th`,null,`名称`),u(`th`,null,`周期`),u(`th`,{class:`r`},`故事`),u(`th`,{class:`r`},`承诺 / 容量`),u(`th`,null,`状态`)])],-1),u(`tbody`,null,[(s(!0),f(d,null,a(i($),e=>(s(),f(`tr`,{key:e.id,class:h({on:e.id===i(z)}),onClick:t=>z.value=e.id},[u(`td`,Ie,c(e.id),1),u(`td`,null,c(e.name),1),u(`td`,Le,c(e.period),1),u(`td`,Re,c(e.stories),1),u(`td`,ze,c(e.commit)+`/`+c(e.capacity),1),u(`td`,null,[u(`span`,{class:h([`tag`,e.tone])},c(e.status),3)])],10,Fe))),128))])])])])])}}}),[[`__scopeId`,`data-v-8a03a4f8`]]);export{N as default};
|