dsh-sa-workbench 0.1.28 → 0.1.29
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 +3 -1
- package/client.js +79 -32
- package/modules/dsh-pm-ui/client.js +79 -32
- package/modules/dsh-pm-ui/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
需求总览、版本计划、业务资料上传、需求/高阶方案/PRD/原型、节点 Skill、文档历史和交付归档在一个包里同步更新。复用 DSH 的模型、会话、权限和工具,不包含模型凭据或业务资料。
|
|
6
6
|
|
|
7
|
-
首次打开 SA
|
|
7
|
+
首次打开 SA 工作台会进入目录设置。确认默认目录后直接进入需求总览;选择其他工作目录后,按提示完整退出并重新打开 DSH。新用户默认亮色,用户主动选择的暗色偏好保留。插件更新、回退和卸载保留工作目录及配置。
|
|
8
|
+
|
|
9
|
+
工作台统一提供需求、知识库、归档库与工作方法导航。需求总览支持表格和看板;详情页以阶段图标和分段连线导航,未生成时展示交付预览及开始操作。助手按需展开,复用原需求会话。文档尚未保存时切换顶部页面,会提示继续编辑或放弃修改后离开。
|
|
8
10
|
|
|
9
11
|
需要 Node 24.9+ 运行时与 DSH 0.2.2-rc.1 系列;当前实机验证版本以发布验收文档为准,版本范围不代表所有未来宿主均已测试。
|
|
10
12
|
|
package/client.js
CHANGED
|
@@ -36,7 +36,7 @@ window.__ModuleLoader__.load({
|
|
|
36
36
|
return function(){if(previousShell===undefined)delete root.dataset.saShell;else root.dataset.saShell=previousShell;if(previousAppearance===undefined)delete root.dataset.saAppearance;else root.dataset.saAppearance=previousAppearance}
|
|
37
37
|
}
|
|
38
38
|
function toggleSaAppearance(){var next=(pmBus.state.appearance || saAppearance())==='dark'?'light':'dark';try{localStorage.setItem('sa-workbench-appearance',next)}catch(err){}pmBus.set({appearance:next})}
|
|
39
|
-
var CLIENT_VERSION = '0.1.
|
|
39
|
+
var CLIENT_VERSION = '0.1.29'
|
|
40
40
|
|
|
41
41
|
// A session may disappear or fail to open after selection. Keep failures
|
|
42
42
|
// inside the conversation pane, and release even a rejected/pending ref.
|
|
@@ -1788,6 +1788,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
1788
1788
|
edit: 'M12 20H4V12M9 15l3-.5L21 6l-3-3-8.5 9z', list: 'M8 5h13M8 12h13M8 19h13M3 5h.01M3 12h.01M3 19h.01',
|
|
1789
1789
|
chat: 'M4 4h16v12H9l-5 4z', expand: 'M8 3H3v5M16 3h5v5M21 16v5h-5M3 16v5h5', focus: 'M4 4h16v16H4zM15 4v16', history: 'M3 10a9 9 0 1 1 2 9M3 3v7h7M12 7v5l3 2',
|
|
1790
1790
|
check: 'M5 12l4 4L19 6', link: 'M10 13a5 5 0 0 0 7 0l4-4a5 5 0 0 0-7-7l-2 2M14 11a5 5 0 0 0-7 0l-4 4a5 5 0 0 0 7 7l2-2',
|
|
1791
|
+
users: 'M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75',
|
|
1791
1792
|
settings: 'M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8M10 3h4l1 3 3 1 3 3v4l-3 1-1 3-3 3h-4l-1-3-3-1-3-3v-4l3-1 1-3z',
|
|
1792
1793
|
folder: 'M3 7V5a2 2 0 0 1 2-2h5l2 3h7a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z',
|
|
1793
1794
|
route: 'M4 5h16M4 12h16M4 19h16M7 3v4M12 10v4M17 17v4',
|
|
@@ -1967,8 +1968,10 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
1967
1968
|
var progressGradientId=useState(function(){return 'pmw-progress-blue-'+(++overviewGradientSequence)})[0]
|
|
1968
1969
|
var planServiceReady=!!(props.releases && Array.isArray(props.releases.plans))
|
|
1969
1970
|
var rs=useState(props.releases || {currentVersion:null,plans:[],fingerprint:null}),releases=rs[0],setReleases=rs[1]
|
|
1970
|
-
var versionSt=useState(function(){return props.releases && props.releases.currentVersion || '*'}),version=versionSt[0],setVersion=versionSt[1]
|
|
1971
|
-
var statusSt=useState('all'),status=statusSt[0],setStatus=statusSt[1],querySt=useState(''),query=querySt[0],setQuery=querySt[1]
|
|
1971
|
+
var versionSt=useState(function(){return pmBus.overviewContext ? pmBus.overviewContext.version : props.releases && props.releases.currentVersion || '*'}),version=versionSt[0],setVersion=versionSt[1]
|
|
1972
|
+
var statusSt=useState(pmBus.overviewContext && pmBus.overviewContext.status || 'all'),status=statusSt[0],setStatus=statusSt[1],querySt=useState(pmBus.overviewContext && pmBus.overviewContext.query || ''),query=querySt[0],setQuery=querySt[1]
|
|
1973
|
+
var presentationSt=useState(pmBus.overviewContext && pmBus.overviewContext.presentation || 'table'),presentation=presentationSt[0],setPresentation=presentationSt[1]
|
|
1974
|
+
useEffect(function(){pmBus.overviewContext={version:version,status:status,query:query,presentation:presentation}},[version,status,query,presentation])
|
|
1972
1975
|
var sortSt=useState('updated'),sort=sortSt[0],setSort=sortSt[1],choiceSt=useState(false),choice=choiceSt[0],setChoice=choiceSt[1]
|
|
1973
1976
|
var infoSt=useState(null),info=infoSt[0],setInfo=infoSt[1],pickerRef=React.useRef(null),pickerButton=React.useRef(null)
|
|
1974
1977
|
var hs=useState(null),help=hs[0],setHelp=hs[1],helpRef=React.useRef(null),ims=useState(false),importOpen=ims[0],setImportOpen=ims[1]
|
|
@@ -2020,10 +2023,10 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
2020
2023
|
e('section',{className:'pmw-summary','aria-label':'本版需求统计'},e('div',{className:'pmw-summary__metrics'},statistic('total','需求总数',model.total),statistic('done','已完成',model.completed),statistic('running','进行中',model.running),statistic('waiting','待启动',model.waiting))),
|
|
2021
2024
|
e('div',{className:'pmw-overview__panels'},train),
|
|
2022
2025
|
e('section',{className:'pmw-overview__tablepanel','aria-label':'需求列表'},
|
|
2023
|
-
e('div',{className:'pmw-overview__boardhead'},e('span',{className:'pmw-panel-icon'},e(UiIcon,{name:'list'})),e('h2',null,'需求地图'),e('span',{role:'status'},model.rows.length)),
|
|
2026
|
+
e('div',{className:'pmw-overview__boardhead'},e('span',{className:'pmw-panel-icon'},e(UiIcon,{name:'list'})),e('h2',null,'需求地图'),e('span',{role:'status'},model.rows.length),e('div',{className:'sa-presentation',role:'group','aria-label':'需求展示方式'},[['table','表格'],['board','看板']].map(function(p){return e('button',{key:p[0],'aria-pressed':presentation===p[0],onClick:function(){setPresentation(p[0])}},p[1])}))),
|
|
2024
2027
|
e('div',{className:'pmw-overview__tools'},e('div',{className:'pmw-overview__views',role:'group','aria-label':'按需求状态筛选'},tabs.map(function(t){return e('button',{key:t.id,'aria-pressed':status===t.id,onClick:function(){setStatus(t.id)}},t.title,e('span',null,t.count))})),e('label',{className:'pmw-overview__search'},e(UiIcon,{name:'search'}),e('input',{'aria-label':'搜索需求、编码、负责人或应用',placeholder:'搜索需求、负责人或应用',value:query,onChange:function(ev){setQuery(ev.target.value)}}),query && e('button',{'aria-label':'清除总览搜索',onClick:function(){setQuery('')}},e(UiIcon,{name:'close'})))),
|
|
2025
2028
|
props.requirements.length===0?e('div',{className:'pmw-overview__empty'},e(UiIcon,{name:'grid'}),e('h2',null,'新建第一条需求'),e('button',{className:'pmw-btn pmw-btn--primary',onClick:props.onCreate},'新建需求')):model.rows.length===0?e('div',{className:'pmw-overview__empty'},e(UiIcon,{name:'search'}),e('h2',null,'当前范围没有需求'),e('button',{className:'pmw-btn',onClick:function(){setStatus('all');setQuery('')}},'清除状态与搜索筛选')):
|
|
2026
|
-
e('div',{className:'pmw-requirements-scroll'},e('table',{className:'pmw-requirements'},e('thead',null,e('tr',null,['需求','状态','业务方','SA','前端开发','后端开发','测试','外部应用','操作'].map(function(label){return e('th',{key:label,scope:'col'},label)}))),e('tbody',null,model.rows.map(card))))),
|
|
2029
|
+
presentation==='board'?e(RequirementKanban,{requirements:model.rows,onOpen:function(req){setInfo({requirement:req,editing:false})}}):e('div',{className:'pmw-requirements-scroll'},e('table',{className:'pmw-requirements'},e('thead',null,e('tr',null,['需求','状态','业务方','SA','前端开发','后端开发','测试','外部应用','操作'].map(function(label){return e('th',{key:label,scope:'col'},label)}))),e('tbody',null,model.rows.map(card))))),
|
|
2027
2030
|
help && e('div',{className:'pmw-overview__help',ref:helpRef,role:'dialog','aria-label':help.title,style:{left:help.left,top:help.top}},e('h3',null,help.title),e('p',null,help.text)),
|
|
2028
2031
|
importOpen && e(ReleaseImportDialog,{onClose:function(){setImportOpen(false)},onSaved:function(value){setReleases(value);props.onRefresh()}}),
|
|
2029
2032
|
info && e(RequirementInfoDialog,{requirement:info.requirement,startEditing:info.editing,onOpen:props.onOpen,onClose:function(){setInfo(null)},onSaved:props.onRefresh}))
|
|
@@ -2338,7 +2341,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
2338
2341
|
// 全局选择总线:左轨(常驻)与 SA 总览页(main 面板)共享选中态
|
|
2339
2342
|
// -----------------------------------------------------------------------
|
|
2340
2343
|
var pmBus = {
|
|
2341
|
-
state: { selectedId: null, activeSessionId: null, nav: 'home', selectedVersion: null, tabs: {}, scrolls: {}, files: {}, focus:
|
|
2344
|
+
state: { selectedId: null, activeSessionId: null, nav: 'home', selectedVersion: null, tabs: {}, scrolls: {}, files: {}, focus: true },
|
|
2342
2345
|
listeners: [],
|
|
2343
2346
|
set: function (patch) {
|
|
2344
2347
|
var changed = false
|
|
@@ -2937,6 +2940,57 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
2937
2940
|
directoryBrowser && e(DirectoryBrowser,{key:directoryBrowser.key,title:directoryBrowser.title,start:directoryBrowser.start,onCancel:function(){setDirectoryBrowser(null)},onSelect:function(location){changeField(directoryBrowser.key,location);setDirectoryBrowser(null)}}))
|
|
2938
2941
|
}
|
|
2939
2942
|
|
|
2943
|
+
var WORKSPACE_PREVIEW_CSS = "/* Task navigation is distinct from document controls. Preview is opt-in. */\r\nhtml:has(.sa-workspace-shell) .pmw-nav__group:last-child{display:none}\r\nhtml:root .pmw-root.sa-workspace-shell{--sa-preview-ink:var(--glass-ink,var(--dsw-alias-text-primary));--sa-preview-muted:var(--glass-muted,var(--dsw-alias-text-secondary));--sa-preview-card:var(--glass-card,var(--dsw-alias-background-container));--sa-preview-line:var(--glass-input,var(--dsw-alias-border-l2));}\r\n.sa-workspace-toolbar{display:flex;align-items:center;gap:16px;flex:none;padding:14px 22px 12px;min-height:66px;border-bottom:1px solid color-mix(in srgb,var(--sa-preview-line) 35%,transparent);}\r\n.sa-workspace-tabs{display:flex;gap:3px;padding:4px;border-radius:18px;background:var(--sa-preview-card);box-shadow:0 1px 0 color-mix(in srgb,var(--sa-preview-line) 30%,transparent);backdrop-filter:blur(16px);}\r\n.sa-workspace-tabs button{border:0;background:none;color:var(--sa-preview-muted);font:inherit;font-size:13px;border-radius:14px;padding:9px 16px;white-space:nowrap;cursor:pointer;}\r\n.sa-workspace-tabs button[aria-current=page]{background:var(--sa-preview-ink);color:var(--glass-bg,#fff);}\r\n.sa-workspace-tabs button:focus-visible,.sa-presentation button:focus-visible,.sa-board-card:focus-visible{outline:2px solid var(--glass-primary,#7663db);outline-offset:3px;}\r\n.sa-workspace-label{margin-left:auto;font-size:12px;color:var(--sa-preview-muted);}\r\n.sa-mobile-create{display:none;}\r\n.sa-workspace-toolbar .sa-theme-switch{flex:none;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-overview__head>.sa-theme-switch{display:none}\r\n.sa-settings-scroll{overflow:auto;min-height:0;flex:1;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-detail__head{padding:18px 24px 14px;gap:12px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-detail__head .sa-assistant-toggle{width:auto;margin-left:8px;gap:7px;border:1px solid var(--sa-preview-line);border-radius:16px;padding:7px 12px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-detail__head .sa-assistant-toggle[aria-expanded=true]{background:var(--glass-tint);}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-ai{border-left:1px solid var(--sa-preview-line);background:var(--sa-preview-card);}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-ai__context{gap:8px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-ai__context>span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-ai__context>button{margin-left:auto;padding:4px;flex:none;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-doc--empty{padding:28px 24px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state{max-width:920px;display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,.85fr);column-gap:32px;row-gap:16px;margin:0 auto;align-content:start;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state__heading,html:root .pmw-root.sa-workspace-shell .pmw-empty-state__description{grid-column:1;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state__heading{align-self:end;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state__description{margin:0;max-width:460px;line-height:1.8;}\r\n.sa-deliverable{grid-column:2;grid-row:1 / span 6;align-self:start;padding:24px;border:1px solid color-mix(in srgb,var(--sa-preview-line) 65%,transparent);border-radius:24px;background:var(--sa-preview-card);box-shadow:0 10px 30px -24px var(--sa-preview-ink);}\r\n.sa-deliverable__eyebrow{font-size:11px;letter-spacing:.12em;color:var(--sa-preview-muted);}\r\n.sa-deliverable h4{font-size:18px;line-height:1.55;margin:10px 0 18px;font-weight:600;color:var(--sa-preview-ink);}\r\n.sa-deliverable ul{padding:0;margin:0;list-style:none;display:grid;gap:14px;}\r\n.sa-deliverable li{display:flex;gap:10px;align-items:flex-start;font-size:13px;line-height:1.65;}\r\n.sa-deliverable li>span{flex:none;font-size:10px;width:24px;height:24px;display:grid;place-items:center;border-radius:50%;background:var(--glass-tint);color:var(--sa-preview-muted);}\r\n.sa-deliverable__hint,.sa-deliverable__missing{font-size:12px;line-height:1.8;color:var(--sa-preview-muted);margin:18px 0 0;}\r\n.sa-deliverable__missing{border-top:1px solid var(--sa-preview-line);padding-top:14px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-sources{grid-column:1;max-width:100%;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-empty-state__file,html:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-btn,html:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-empty-state__note{grid-column:1;justify-self:start;margin:0;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-btn{border-radius:16px;padding:11px 18px;}\r\n.sa-presentation{display:flex;margin-left:auto;padding:3px;border:1px solid var(--sa-preview-line);border-radius:14px;gap:2px;}\r\n.sa-presentation button{font:inherit;font-size:12px;padding:6px 11px;cursor:pointer;color:var(--sa-preview-muted);border:0;border-radius:10px;background:none;}\r\n.sa-presentation button[aria-pressed=true]{background:var(--sa-preview-card);box-shadow:0 1px 4px #0001;color:var(--sa-preview-ink);}\r\n.sa-requirement-board{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;padding:8px 0 20px;}\r\n.sa-board-column{background:color-mix(in srgb,var(--sa-preview-ink) 3%,transparent);border-radius:22px;padding:12px;min-height:240px;}\r\n.sa-board-column>header{display:flex;align-items:center;justify-content:space-between;margin:2px 4px 14px;font-size:12px;color:var(--sa-preview-muted);}\r\n.sa-board-card{display:flex;text-align:left;flex-direction:column;gap:10px;cursor:pointer;padding:18px;margin:0 0 12px;width:100%;font:inherit;color:var(--sa-preview-ink);border:1px solid color-mix(in srgb,var(--sa-preview-line) 65%,transparent);border-radius:18px;background:var(--sa-preview-card);transition:transform .15s;}\r\n.sa-board-card:hover{transform:translateY(-2px);}\r\n.sa-board-card code{font-size:11px;color:var(--sa-preview-muted);}\r\n.sa-board-card strong{font-size:15px;line-height:1.6;overflow-wrap:anywhere;}\r\n.sa-board-card__stage,.sa-board-card footer{font-size:11px;line-height:1.6;color:var(--sa-preview-muted);}\r\n.sa-board-card footer{display:flex;justify-content:space-between;gap:8px;padding-top:10px;border-top:1px solid var(--sa-preview-line);flex-wrap:wrap;}\r\n.sa-board-empty{font-size:12px;color:var(--sa-preview-muted);padding:20px 6px;}\r\n@media(max-width:1100px){html:root .pmw-root.sa-workspace-shell:has(.pmw-ai) .pmw-empty-state{grid-template-columns:minmax(0,1fr)}html:root .pmw-root.sa-workspace-shell:has(.pmw-ai) .sa-deliverable{grid-column:1;grid-row:auto;}}\r\n@media(max-width:760px){.sa-workspace-toolbar{padding:10px 14px;gap:8px;}.sa-workspace-tabs button{padding:8px 12px;}.sa-workspace-label{display:none}.sa-workspace-toolbar .sa-theme-switch{margin-left:auto;}html:root .pmw-root.sa-workspace-shell .pmw-empty-state{grid-template-columns:minmax(0,1fr);}.sa-deliverable{grid-column:1;grid-row:auto;}.sa-requirement-board{grid-template-columns:minmax(0,1fr)}html:root .pmw-root.sa-workspace-shell .pmw-doc--empty{padding:20px 16px;}html:root .pmw-root.sa-workspace-shell .pmw-detail__head{padding:14px 16px;}html:root .pmw-root.sa-workspace-shell .pmw-ai{position:absolute;right:0;top:0;bottom:0;z-index:20;width:min(420px,100%);box-shadow:-12px 0 40px #0002;}html:root .pmw-root.sa-workspace-shell .pmw-body{position:relative;}}\r\n@media(prefers-reduced-motion:reduce){.sa-board-card{transition:none}}\r\n\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-detail__title{font-size:20px;font-weight:600;line-height:1.45}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state{max-width:980px;width:100%}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-deliverable li>span{border-radius:50%!important;corner-shape:round!important}\r\n@media(max-width:760px){html:has(.sa-workspace-shell) .pmw-nav{display:none!important}html:root .pmw-root.sa-workspace-shell .pmw-empty-state{max-width:100%}.sa-workspace-toolbar{gap:6px}.sa-workspace-tabs{min-width:0;overflow-x:auto}.sa-workspace-tabs button{font-size:12px;padding:7px 8px}.sa-workspace-toolbar .sa-theme-switch{margin-left:0!important}}\r\n@media(max-width:760px){.sa-mobile-create{display:inline-flex;align-items:center;justify-content:center;flex:none;width:32px;height:32px;border:1px solid var(--sa-preview-line);border-radius:50%;color:var(--sa-preview-ink);background:var(--sa-preview-card);cursor:pointer}.sa-workspace-tabs{flex:1}.sa-workspace-toolbar{padding:10px}}\r\n\r\n/* Annotation revision: segmented stage route and composed start panel. */\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-stages{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0;padding:18px 24px 20px;overflow:visible}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:8px;padding:0;overflow:visible;background:none;border:0;min-width:0}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step::before,html:root .pmw-root.sa-workspace-shell .pmw-step::after{display:none}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step__number{position:relative;z-index:2;display:flex;align-items:center;justify-content:center;width:40px;height:40px;min-width:40px;padding:0;border-radius:50%!important;corner-shape:round!important;border:1.5px solid var(--sa-preview-line);background:var(--glass-popover,var(--glass-bg));color:var(--sa-preview-muted);box-shadow:none;outline:0}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step__number>svg{width:19px;height:19px}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step.is-current .pmw-step__number{background:var(--sa-preview-ink);border-color:var(--sa-preview-ink);color:var(--glass-bg)}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step.is-active:not(.is-current) .pmw-step__number{border-color:var(--glass-primary);color:var(--glass-primary);background:var(--glass-bg);box-shadow:0 0 0 4px var(--glass-tint)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-connector{position:absolute;z-index:1;top:19px;left:calc(-50% + 24px);width:calc(100% - 48px);height:0;border-top:2px solid var(--sa-preview-line);pointer-events:none}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-connector.is-reached{border-color:var(--sa-preview-ink)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-connector.is-optional{border-top-style:dashed}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-done{position:absolute;right:-3px;bottom:-2px;width:16px;height:16px;border-radius:50%;display:grid;place-items:center;background:var(--sa-preview-ink);color:var(--glass-bg);border:2px solid var(--glass-bg)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-done .pmw-icon{width:10px;height:10px}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step__label{font-size:13px;line-height:20px}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step small{margin:0;font-size:11px;line-height:16px}\r\n.sa-empty-workspace{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.9fr);gap:28px;max-width:1060px;margin:10px auto 0;width:100%;align-items:stretch}\r\n.sa-empty-workspace>.sa-deliverable{grid-column:auto;grid-row:auto;align-self:stretch;box-shadow:none}\r\n.sa-stage-start{display:flex;flex-direction:column;gap:0;padding:28px;border:1px solid color-mix(in srgb,var(--sa-preview-line) 60%,transparent);border-radius:24px;background:var(--sa-preview-card);min-width:0}\r\n.sa-stage-start__header{display:flex;gap:10px;align-items:center;font-size:12px;color:var(--sa-preview-muted)}\r\n.sa-stage-start__glyph{display:grid;place-items:center;width:36px;height:36px;border-radius:12px;color:var(--glass-primary);background:var(--glass-tint)}\r\n.sa-stage-start__state{margin-left:auto;font-size:11px;padding:4px 9px;border-radius:999px;background:var(--glass-secondary)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-start h3{font-size:24px;line-height:1.4;font-weight:600;margin:22px 0 12px;color:var(--sa-preview-ink)}\r\n.sa-stage-start__intro{font-size:13px;line-height:1.85;margin:0 0 24px;color:var(--sa-preview-muted)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-start>.pmw-sources{max-width:100%;width:100%;margin:0 0 18px}\r\n.sa-stage-output{display:flex;align-items:center;gap:12px;background:var(--glass-secondary);border:1px solid color-mix(in srgb,var(--sa-preview-line) 45%,transparent);border-radius:16px;padding:15px 16px;margin-top:auto}\r\n.sa-stage-output__icon{display:grid;place-items:center;width:36px;height:40px;border-radius:9px;background:var(--glass-card);color:var(--sa-preview-muted)}\r\n.sa-stage-output small{display:block;font-size:11px;color:var(--sa-preview-muted);margin-bottom:4px}\r\n.sa-stage-output code{display:block;font-size:13px;color:var(--sa-preview-ink);overflow-wrap:anywhere}\r\n.sa-stage-start__actions{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:22px}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-start__actions .pmw-btn{display:inline-flex;align-items:center;gap:18px;padding:11px 18px;border-radius:14px}\r\n.sa-stage-start__actions>span{font-size:11px;color:var(--sa-preview-muted)}\r\n@media(max-width:1100px){html:root .pmw-root.sa-workspace-shell:has(.pmw-ai) .sa-empty-workspace{grid-template-columns:minmax(0,1fr)}}\r\n@media(max-width:760px){.sa-empty-workspace{grid-template-columns:minmax(0,1fr);gap:18px;margin-top:0}.sa-stage-start{padding:22px}.sa-empty-workspace>.sa-deliverable{grid-column:auto;grid-row:auto}html:root .pmw-root.sa-workspace-shell .pmw-stages{padding:16px 12px 18px}html:root .pmw-root.sa-workspace-shell .pmw-step__number{width:34px;height:34px;min-width:34px}html:root .pmw-root.sa-workspace-shell .sa-stage-connector{top:16px;left:calc(-50% + 21px);width:calc(100% - 42px)}html:root .pmw-root.sa-workspace-shell .pmw-step__label{font-size:11px}}\r\n";
|
|
2944
|
+
function StageGlyph(props){
|
|
2945
|
+
var paths={intake:['M4 5h16v11H9l-5 4V5','M8 9h8M8 12h5'],solution:['M4 4h6v6H4zM14 14h6v6h-6z','M10 7h7v7M7 10v7h7'],prd:['M14 3H6a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8l-5-5z','M14 3v5h5M8 14l2 2 5-5'],prototype:['M3 4h18v16H3z','M3 9h18M9 9v11']};
|
|
2946
|
+
return e('svg',{width:20,height:20,viewBox:'0 0 24 24',fill:'none',stroke:'currentColor',strokeWidth:1.65,strokeLinecap:'round',strokeLinejoin:'round','aria-hidden':true},(paths[props.stage] || paths.prd).map(function(d,i){return e('path',{key:i,d:d})}))
|
|
2947
|
+
}
|
|
2948
|
+
function StageStartCard(props){
|
|
2949
|
+
var action={intake:'开始梳理',solution:'开始设计',prd:'开始编写',prototype:'开始制作'}[props.stage];
|
|
2950
|
+
return e('section',{className:'sa-stage-start','aria-label':props.title},
|
|
2951
|
+
e('header',{className:'sa-stage-start__header'},e('span',{className:'sa-stage-start__glyph'},e(StageGlyph,{stage:props.stage})),e('span',null,props.archived?'归档记录':'准备开始'),e('span',{className:'sa-stage-start__state'},props.archived?'未包含':'尚未生成')),
|
|
2952
|
+
e('h3',null,props.title),e('p',{className:'sa-stage-start__intro'},props.description),
|
|
2953
|
+
props.sources,
|
|
2954
|
+
props.artifact && e('div',{className:'sa-stage-output'},e('span',{className:'sa-stage-output__icon'},e(StageGlyph,{stage:props.stage})),e('div',null,e('small',null,props.archived?'未包含文件':'交付文件'),e('code',null,props.artifact.path))),
|
|
2955
|
+
!props.archived && props.artifact && e('footer',{className:'sa-stage-start__actions'},e('button',{className:'pmw-btn pmw-btn--primary',disabled:props.busy,onClick:props.onStart},props.busy?'正在准备…':action,e('svg',{width:16,height:16,viewBox:'0 0 24 24',fill:'none',stroke:'currentColor',strokeWidth:1.8,'aria-hidden':true},e('path',{d:'M5 12h14M13 6l6 6-6 6',strokeLinecap:'round',strokeLinejoin:'round'}))),e('span',null,'使用当前工作方法')))
|
|
2956
|
+
}
|
|
2957
|
+
function WorkspaceNavigation(props){
|
|
2958
|
+
var active=props.current==='create'?'home':props.current;
|
|
2959
|
+
return e('header',{className:'sa-workspace-toolbar'},
|
|
2960
|
+
e('nav',{'aria-label':'SA 工作台导航',className:'sa-workspace-tabs'},[['home','需求'],['kb','知识库'],['plib','归档库'],['settings','工作方法']].map(function(t){return e('button',{key:t[0],type:'button','aria-current':active===t[0]?'page':undefined,onClick:function(){props.onNavigate(t[0])}},t[1])})),
|
|
2961
|
+
e('span',{className:'sa-workspace-label'},'SA 工作台'),
|
|
2962
|
+
e('button',{className:'sa-mobile-create',type:'button','aria-label':'新建需求',onClick:function(){props.onNavigate('create')}},e(UiIcon,{name:'plus'})),
|
|
2963
|
+
e('div',{className:'sa-theme-switch','aria-label':'工作台外观'},['light','dark'].map(function(a){return e('button',{key:a,type:'button','aria-label':a==='light'?'浅色模式':'暗色模式','aria-pressed':(pmBus.state.appearance || saAppearance())===a,onClick:function(){setSaAppearance(a)}},a==='light'?'☀':'☾')})))
|
|
2964
|
+
}
|
|
2965
|
+
function stageDeliverableModel(stage,requirement,artifact){
|
|
2966
|
+
var definitions={
|
|
2967
|
+
intake:{title:'一份可继续设计的业务需求',items:['业务目标与使用场景','范围、现状与资料依据','需要进一步确认的问题']},
|
|
2968
|
+
solution:{title:'一份可讨论的高阶方案',items:['关键设计点与系统职责','业务流程、依赖及改造范围','方案依据与待决策事项']},
|
|
2969
|
+
prd:{title:'一份可评审、可验证的 PRD',items:['用户故事与完整业务规则','Given / When / Then 验收条件','相关流程与交互说明']},
|
|
2970
|
+
prototype:{title:'一份可操作的交互原型',items:['主要页面与关键任务路径','适用的正常、异常与空状态','供讨论与迭代的页面交互']}
|
|
2971
|
+
};
|
|
2972
|
+
var model=definitions[stage] || definitions.intake;
|
|
2973
|
+
var prior=stage==='solution'?['intake']:stage==='prd'?['intake','solution']:stage==='prototype'?['prd']:[];
|
|
2974
|
+
var missing=prior.filter(function(id){var s=(requirement.stages || []).find(function(s){return s.id===id});return !s || !(s.artifacts || []).some(function(a){return a.exists})});
|
|
2975
|
+
return {title:model.title,items:model.items,missing:missing.map(function(id){return {intake:'业务需求',solution:'高阶方案',prd:'PRD'}[id]}),file:artifact && artifact.path,archived:!!requirement.archived};
|
|
2976
|
+
}
|
|
2977
|
+
function StageDeliverablePreview(props){
|
|
2978
|
+
var model=stageDeliverableModel(props.stage,props.requirement,props.artifact);
|
|
2979
|
+
if(model.archived)return null;
|
|
2980
|
+
return e('aside',{className:'sa-deliverable','aria-label':'本阶段交付预览'},
|
|
2981
|
+
e('div',{className:'sa-deliverable__eyebrow'},'本阶段交付'),e('h4',null,model.title),
|
|
2982
|
+
e('ul',null,model.items.map(function(text,i){return e('li',{key:text},e('span',{'aria-hidden':true},String(i+1).padStart(2,'0')),text)})),
|
|
2983
|
+
model.missing.length>0 && e('p',{className:'sa-deliverable__missing'},'尚未发现'+model.missing.join('、')+'文档。助手会先核对依据,必要时补充澄清。'),
|
|
2984
|
+
e('p',{className:'sa-deliverable__hint'},'以上为预期内容,当前尚未生成;生成后仍需评审。'))
|
|
2985
|
+
}
|
|
2986
|
+
function RequirementKanban(props){
|
|
2987
|
+
return e('div',{className:'sa-requirement-board','aria-label':'需求状态看板'},[['waiting','待启动'],['running','进行中'],['done','已完成']].map(function(group){
|
|
2988
|
+
var rows=props.requirements.filter(function(r){return overviewStatus(r)===group[0]});
|
|
2989
|
+
return e('section',{key:group[0],className:'sa-board-column'},e('header',null,e('span',{className:'pmw-stage-pill is-'+group[0]},e('i',{'aria-hidden':true}),group[1]),e('span',null,rows.length)),
|
|
2990
|
+
rows.length?rows.map(function(req){var c=collaborationValue(req),stages=req.stages || [],existing=stages.filter(function(s){return (s.artifacts || []).some(function(a){return a.exists})}).length;return e('button',{key:req.id,className:'sa-board-card',onClick:function(){props.onOpen(req)},'aria-label':'查看 '+req.code+' '+req.title},e('code',null,req.code),e('strong',null,req.title),e('span',{className:'sa-board-card__stage'},stageTitle(req)),e('footer',null,e('span',null,c.pmOwner || 'SA 待填写'),e('span',null,existing?existing+' 个阶段已有稿':'尚无阶段稿')))}):e('p',{className:'sa-board-empty'},'当前筛选下暂无需求'))
|
|
2991
|
+
}))
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2940
2994
|
function Panel(props) {
|
|
2941
2995
|
var layout = props.layout
|
|
2942
2996
|
var pm = props.pm
|
|
@@ -2949,6 +3003,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
2949
3003
|
var form = useState('home')
|
|
2950
3004
|
var view = form[0]
|
|
2951
3005
|
var setView = form[1]
|
|
3006
|
+
var pendingNavigationSt=useState(null),pendingNavigation=pendingNavigationSt[0],setPendingNavigation=pendingNavigationSt[1]
|
|
2952
3007
|
var ft = useState('')
|
|
2953
3008
|
var formTitle = ft[0]
|
|
2954
3009
|
var setFormTitle = ft[1]
|
|
@@ -3348,7 +3403,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3348
3403
|
return pm.sendToReq(selected, dir, body.prompt).then(function (res) {
|
|
3349
3404
|
setBusy(false)
|
|
3350
3405
|
if (!res || !res.ok) setOpErr((res && res.error) || '发送失败')
|
|
3351
|
-
else {setNotice('已发送到对话 · 使用 '+body.skill.name+';请在会话中查看进展。');if(stageId==='intake')return apiSend('POST','/requirement-start',{id:selected.id}).then(reload)}
|
|
3406
|
+
else {pmBus.set({focus:false});setNotice('已发送到对话 · 使用 '+body.skill.name+';请在会话中查看进展。');if(stageId==='intake')return apiSend('POST','/requirement-start',{id:selected.id}).then(reload)}
|
|
3352
3407
|
})
|
|
3353
3408
|
}).catch(function (err) {
|
|
3354
3409
|
setBusy(false)
|
|
@@ -3517,10 +3572,16 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3517
3572
|
}).catch(function(err) { if (pmBus.state.selectedId === owner.id) setOpErr(String(err.message || err)) }).finally(function(){setBusy(false)})
|
|
3518
3573
|
}
|
|
3519
3574
|
|
|
3575
|
+
function navigateWorkspace(target){
|
|
3576
|
+
if(editor){setPendingNavigation(target);return}
|
|
3577
|
+
completeNavigation(target)
|
|
3578
|
+
}
|
|
3579
|
+
function completeNavigation(target){setPendingNavigation(null);setEditor(null);pmBus.set({nav:target,selectedId:null,activeSessionId:null,settingsReturn:null});setView(target)}
|
|
3580
|
+
var workspaceNav=e(WorkspaceNavigation,{current:view,onNavigate:navigateWorkspace})
|
|
3520
3581
|
var children = []
|
|
3521
3582
|
|
|
3522
3583
|
if (data.data && (data.data.setupRequired || data.data.restartRequired)) return e('div',{className:'pmw-root','data-sa-appearance':bus.appearance || saAppearance()},e(SettingsPanel,{onboarding:true,onComplete:function(){pmBus.set({nav:'home',selectedId:null,activeSessionId:null,settingsReturn:null});setView('home');reload()}}))
|
|
3523
|
-
if (view === 'settings') return e('div', { className: 'pmw-root', 'data-sa-appearance':bus.appearance || saAppearance() },
|
|
3584
|
+
if (view === 'settings') return e('div', { className: 'pmw-root sa-workspace-shell', 'data-sa-appearance':bus.appearance || saAppearance() },e('style',null,WORKSPACE_PREVIEW_CSS),workspaceNav,e('div',{className:'sa-settings-scroll'},e(SettingsPanel)))
|
|
3524
3585
|
|
|
3525
3586
|
// header(纯标题,动作全部收进各自语境:Tab 空态/地铁图归档站/右栏线程条)
|
|
3526
3587
|
if (!selected && (view !== 'home' || !data.data)) children.push(e('div', { className: 'pmw-header', key: 'header' },
|
|
@@ -3541,7 +3602,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3541
3602
|
e('div',{className:'pmw-dialog__body'},e('label',{className:'pmw-field'},e('span',{className:'pmw-field__label'},'文件名称'),e('input',{className:'pmw-input',autoFocus:true,'aria-label':'文件名称',value:newFile.name,maxLength:110,onChange:function(ev){setNewFile(Object.assign({},newFile,{name:ev.target.value}))},placeholder:'例如:接口说明'})),
|
|
3542
3603
|
e('label',{className:'pmw-field'},e('span',{className:'pmw-field__label'},'文档内容'),e('textarea',{className:'pmw-textarea','aria-label':'新增文档内容',value:newFile.content,onChange:function(ev){setNewFile(Object.assign({},newFile,{content:ev.target.value}))},placeholder:'支持 Markdown'})),opErr && e('p',{role:'alert'},opErr)),
|
|
3543
3604
|
e('div',{className:'pmw-dialog__foot'},e('button',{type:'button',className:'pmw-btn',disabled:isBusy,onClick:function(){setNewFile(null)}},'取消'),e('button',{type:'submit',className:'pmw-btn pmw-btn--primary',disabled:isBusy || !newFile.name.trim() || !newFile.content.trim()},isBusy?'正在添加…':'添加文档')))))
|
|
3544
|
-
return e('div', { ref:rootRef, className: 'pmw-root' + (expanded ? ' is-expanded' : ''), 'data-sa-appearance':bus.appearance || saAppearance() }, children)
|
|
3605
|
+
return e('div', { ref:rootRef, className: 'pmw-root sa-workspace-shell' + (expanded ? ' is-expanded' : ''), 'data-sa-appearance':bus.appearance || saAppearance() },e('style',null,WORKSPACE_PREVIEW_CSS),!expanded && workspaceNav,pendingNavigation && e(DetailDialog,{title:'离开未保存的文档?',onClose:function(){setPendingNavigation(null)},footer:e(React.Fragment,null,e('button',{className:'pmw-btn',onClick:function(){setPendingNavigation(null)}},'继续编辑'),e('button',{className:'pmw-btn pmw-btn--primary',onClick:function(){completeNavigation(pendingNavigation)}},'放弃修改并离开'))},e('p',null,'当前修改尚未保存。继续编辑可保留草稿;离开将放弃这些修改,原文件不变。')),children)
|
|
3545
3606
|
}
|
|
3546
3607
|
|
|
3547
3608
|
// body: main + chat
|
|
@@ -3676,13 +3737,10 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3676
3737
|
return e('button', { key: stage.id, className: 'pmw-step' + (stage.id === curTab ? ' is-active' : '') + (exists ? ' is-complete' : '') + (current ? ' is-current' : '') + (optional ? ' is-optional' : ''),
|
|
3677
3738
|
'aria-pressed': stage.id === curTab, 'aria-current': current ? 'step' : undefined, title: stage.title + ' · ' + (exists ? '已有文档' : '尚未生成') + (stage.id === curTab ? ' · 正在查看' : ''),
|
|
3678
3739
|
onClick: function () { if (stage.id === curTab) return; if (editor && !confirm('有未保存的修改,确定放弃并切换文档?')) return; setEditor(null); setTabSt(stage.id) },
|
|
3679
|
-
}, e('span',
|
|
3740
|
+
},index>0 && e('span',{className:'sa-stage-connector'+(optional?' is-optional':'')+((exists || current) && selected.stages[index-1].artifacts[0].exists?' is-reached':''),'aria-hidden':true}),e('span',{className:'pmw-step__number','aria-hidden':true},e(StageGlyph,{stage:stage.id}),exists && e('span',{className:'sa-stage-done'},e(UiIcon,{name:'check'}))),
|
|
3680
3741
|
e('span', {className:'pmw-step__label'}, label), e('small', null, status))
|
|
3681
3742
|
})
|
|
3682
|
-
|
|
3683
|
-
e('path',{className:'pmw-metro__line',d:'M125 20 H625',vectorEffect:'non-scaling-stroke'}),
|
|
3684
|
-
progressX > 125 && e('path',{className:'pmw-metro__line is-travelled',d:'M125 20 H'+progressX,vectorEffect:'non-scaling-stroke'}),
|
|
3685
|
-
e('path',{className:'pmw-metro__line pmw-metro__branch'+(prototypeExists ? ' is-travelled' : ''),d:'M625 20 H875',vectorEffect:'non-scaling-stroke'})))
|
|
3743
|
+
|
|
3686
3744
|
|
|
3687
3745
|
var currentDocReady = doc && curArt && doc.path === curArt.path && !doc.loading && !doc.error
|
|
3688
3746
|
var cloudReceipt = currentDocReady && doc.receipt
|
|
@@ -3713,20 +3771,9 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3713
3771
|
var sourcesNode = curTab === 'intake' && e(SourceInputs,{key:'sources-'+selected.id,id:selected.id,readOnly:!!selected.archived,hasDoc:!!(curArt && curArt.exists),stageBusy:isBusy,onBusy:setSourceBusy,onStart:function(){handStage('intake')}})
|
|
3714
3772
|
if (!curArt || !curArt.exists) {
|
|
3715
3773
|
var emptyCopy={intake:['梳理业务需求','从你的诉求和业务资料开始,澄清目标、使用场景与范围,保留待确认的问题。','梳理需求'],solution:['形成高阶方案','结合业务需求与现状,明确系统职责、改造方向、依赖与未决事项。','设计高阶方案'],prd:['编写 PRD','基于需求与高阶方案,展开可验证的功能、业务规则和验收条件。','编写 PRD'],prototype:['制作交互原型','用可操作的页面检验 PRD 中的流程与交互。原型按需交付,不阻止归档。','制作原型']}[curTab]
|
|
3716
|
-
contentNode
|
|
3717
|
-
e('
|
|
3718
|
-
|
|
3719
|
-
e('h3',null,selected.archived ? '本次归档未包含'+documentName : emptyCopy[0])),
|
|
3720
|
-
e('p',{className:'pmw-empty-state__description'},selected.archived ? '此归档保留了当时已有的交付文件,未生成的文档不会自动补齐。' : emptyCopy[1]),
|
|
3721
|
-
sourcesNode,
|
|
3722
|
-
curArt && e('div',{className:'pmw-empty-state__file'},e(UiIcon,{name:'doc'}),selected.archived?'未包含文件':'交付文件',e('code',null,curArt.path)),
|
|
3723
|
-
!selected.archived && curArt && e('button', {
|
|
3724
|
-
className: 'pmw-btn pmw-btn--primary',
|
|
3725
|
-
disabled: isBusy || sourceBusy,
|
|
3726
|
-
onClick: function () { handStage(curTab) },
|
|
3727
|
-
}, isBusy ? '正在准备…' : '开始动手吧'),
|
|
3728
|
-
!selected.archived && e('p',{className:'pmw-empty-state__note'},'使用当前绑定的工作方法发送到当前对话;信息不足时先澄清。'),
|
|
3729
|
-
))
|
|
3774
|
+
contentNode=e('div',{className:'pmw-doc pmw-doc--empty',key:'empty'},e('div',{className:'sa-empty-workspace'},
|
|
3775
|
+
e(StageStartCard,{stage:curTab,title:selected.archived?'本次归档未包含'+documentName:emptyCopy[0],description:selected.archived?'此归档保留了当时已有的交付文件,未生成的文档不会自动补齐。':emptyCopy[1],artifact:curArt,archived:!!selected.archived,sources:sourcesNode,busy:isBusy || sourceBusy,onStart:function(){handStage(curTab)}}),
|
|
3776
|
+
e(StageDeliverablePreview,{stage:curTab,requirement:selected,artifact:curArt})))
|
|
3730
3777
|
} else if (doc && doc.path === curArt.path) {
|
|
3731
3778
|
var isHtml = /\.html?$/i.test(doc.path)
|
|
3732
3779
|
// UX 标注工具条:原型 Tab、当前版本即出现;已归档降级为只读(可看 pin,不可新增/改稿)
|
|
@@ -3785,10 +3832,10 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3785
3832
|
mainChildren.push(e('div', { className: 'pmw-detail', key: 'detail' },
|
|
3786
3833
|
!expanded && e('div', { className: 'pmw-detail__head' },
|
|
3787
3834
|
e('h2', { className: 'pmw-detail__title' }, selected.title),
|
|
3788
|
-
e('button',{className:'pmw-btn pmw-btn--ghost',onClick:function(){setRequirementInfo(selected)}},e(UiIcon,{name:'
|
|
3835
|
+
e('button',{className:'pmw-btn pmw-btn--ghost',onClick:function(){setRequirementInfo(selected)}},e(UiIcon,{name:'users'}),'协作信息'),
|
|
3789
3836
|
selected.code ? e('span', { className: 'pmw-tag pmw-tag--code' }, selected.code) : null,
|
|
3790
3837
|
e('span', { className: 'pmw-detail__version' }, selected.version || '未排期'),
|
|
3791
|
-
e('button', { className: 'pmw-btn pmw-btn--ghost
|
|
3838
|
+
e('button', { className: 'pmw-btn pmw-btn--ghost sa-assistant-toggle', 'aria-label':bus.focus?'打开需求助手':'收起需求助手','aria-expanded':!bus.focus,onClick:function(){pmBus.set({focus:!bus.focus})} },e(UiIcon,{name:'chat'}),bus.focus?'助手':'收起助手'),
|
|
3792
3839
|
),
|
|
3793
3840
|
!expanded && e('nav', { className: 'pmw-stages', 'aria-label': '需求交付阶段' }, metroNodes),
|
|
3794
3841
|
tabBar,
|
|
@@ -3842,7 +3889,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3842
3889
|
var chatError = bus.sessionError || (convRef && convRef.id === activeSessionId && convRef.error)
|
|
3843
3890
|
chatNode = e('div', { className: 'pmw-ai', key: 'ai' },
|
|
3844
3891
|
barNode,
|
|
3845
|
-
e('div', { className: 'pmw-ai__context' }, e(UiIcon, { name: 'link' }), e('span', null, selected.code + ' · ' + selected.title)),
|
|
3892
|
+
e('div', { className: 'pmw-ai__context' }, e(UiIcon, { name: 'link' }), e('span', null, selected.code + ' · ' + selected.title),e('button',{className:'pmw-btn pmw-btn--ghost','aria-label':'收起需求助手',onClick:function(){pmBus.set({focus:true})}},e(UiIcon,{name:'close'}))),
|
|
3846
3893
|
canChat
|
|
3847
3894
|
? e('div', { className: 'pmw-ai__conv', key: 'conv' },
|
|
3848
3895
|
e(props.SessionProvider, { session: convRef.ref }, props.renderSlot('pm.conv', {})))
|
|
@@ -3881,7 +3928,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3881
3928
|
e('div',{className:'pmw-dialog__body'},e('label',{className:'pmw-field'},e('span',{className:'pmw-field__label'},'文件名称'),e('input',{className:'pmw-input',autoFocus:true,'aria-label':'文件名称',value:newFile.name,maxLength:110,onChange:function(ev){setNewFile(Object.assign({},newFile,{name:ev.target.value}))},placeholder:'例如:接口说明'})),
|
|
3882
3929
|
e('label',{className:'pmw-field'},e('span',{className:'pmw-field__label'},'文档内容'),e('textarea',{className:'pmw-textarea','aria-label':'新增文档内容',value:newFile.content,onChange:function(ev){setNewFile(Object.assign({},newFile,{content:ev.target.value}))},placeholder:'支持 Markdown'})),opErr && e('p',{role:'alert'},opErr)),
|
|
3883
3930
|
e('div',{className:'pmw-dialog__foot'},e('button',{type:'button',className:'pmw-btn',disabled:isBusy,onClick:function(){setNewFile(null)}},'取消'),e('button',{type:'submit',className:'pmw-btn pmw-btn--primary',disabled:isBusy || !newFile.name.trim() || !newFile.content.trim()},isBusy?'正在添加…':'添加文档')))))
|
|
3884
|
-
return e('div', { ref:rootRef, className: 'pmw-root' + (expanded ? ' is-expanded' : ''), 'data-sa-appearance':bus.appearance || saAppearance() }, children)
|
|
3931
|
+
return e('div', { ref:rootRef, className: 'pmw-root sa-workspace-shell' + (expanded ? ' is-expanded' : ''), 'data-sa-appearance':bus.appearance || saAppearance() },e('style',null,WORKSPACE_PREVIEW_CSS),!expanded && workspaceNav,pendingNavigation && e(DetailDialog,{title:'离开未保存的文档?',onClose:function(){setPendingNavigation(null)},footer:e(React.Fragment,null,e('button',{className:'pmw-btn',onClick:function(){setPendingNavigation(null)}},'继续编辑'),e('button',{className:'pmw-btn pmw-btn--primary',onClick:function(){completeNavigation(pendingNavigation)}},'放弃修改并离开'))},e('p',null,'当前修改尚未保存。继续编辑可保留草稿;离开将放弃这些修改,原文件不变。')),children)
|
|
3885
3932
|
}
|
|
3886
3933
|
|
|
3887
3934
|
// -----------------------------------------------------------------------
|
|
@@ -36,7 +36,7 @@ window.__ModuleLoader__.load({
|
|
|
36
36
|
return function(){if(previousShell===undefined)delete root.dataset.saShell;else root.dataset.saShell=previousShell;if(previousAppearance===undefined)delete root.dataset.saAppearance;else root.dataset.saAppearance=previousAppearance}
|
|
37
37
|
}
|
|
38
38
|
function toggleSaAppearance(){var next=(pmBus.state.appearance || saAppearance())==='dark'?'light':'dark';try{localStorage.setItem('sa-workbench-appearance',next)}catch(err){}pmBus.set({appearance:next})}
|
|
39
|
-
var CLIENT_VERSION = '0.1.
|
|
39
|
+
var CLIENT_VERSION = '0.1.29'
|
|
40
40
|
|
|
41
41
|
// A session may disappear or fail to open after selection. Keep failures
|
|
42
42
|
// inside the conversation pane, and release even a rejected/pending ref.
|
|
@@ -1788,6 +1788,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
1788
1788
|
edit: 'M12 20H4V12M9 15l3-.5L21 6l-3-3-8.5 9z', list: 'M8 5h13M8 12h13M8 19h13M3 5h.01M3 12h.01M3 19h.01',
|
|
1789
1789
|
chat: 'M4 4h16v12H9l-5 4z', expand: 'M8 3H3v5M16 3h5v5M21 16v5h-5M3 16v5h5', focus: 'M4 4h16v16H4zM15 4v16', history: 'M3 10a9 9 0 1 1 2 9M3 3v7h7M12 7v5l3 2',
|
|
1790
1790
|
check: 'M5 12l4 4L19 6', link: 'M10 13a5 5 0 0 0 7 0l4-4a5 5 0 0 0-7-7l-2 2M14 11a5 5 0 0 0-7 0l-4 4a5 5 0 0 0 7 7l2-2',
|
|
1791
|
+
users: 'M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75',
|
|
1791
1792
|
settings: 'M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8M10 3h4l1 3 3 1 3 3v4l-3 1-1 3-3 3h-4l-1-3-3-1-3-3v-4l3-1 1-3z',
|
|
1792
1793
|
folder: 'M3 7V5a2 2 0 0 1 2-2h5l2 3h7a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z',
|
|
1793
1794
|
route: 'M4 5h16M4 12h16M4 19h16M7 3v4M12 10v4M17 17v4',
|
|
@@ -1967,8 +1968,10 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
1967
1968
|
var progressGradientId=useState(function(){return 'pmw-progress-blue-'+(++overviewGradientSequence)})[0]
|
|
1968
1969
|
var planServiceReady=!!(props.releases && Array.isArray(props.releases.plans))
|
|
1969
1970
|
var rs=useState(props.releases || {currentVersion:null,plans:[],fingerprint:null}),releases=rs[0],setReleases=rs[1]
|
|
1970
|
-
var versionSt=useState(function(){return props.releases && props.releases.currentVersion || '*'}),version=versionSt[0],setVersion=versionSt[1]
|
|
1971
|
-
var statusSt=useState('all'),status=statusSt[0],setStatus=statusSt[1],querySt=useState(''),query=querySt[0],setQuery=querySt[1]
|
|
1971
|
+
var versionSt=useState(function(){return pmBus.overviewContext ? pmBus.overviewContext.version : props.releases && props.releases.currentVersion || '*'}),version=versionSt[0],setVersion=versionSt[1]
|
|
1972
|
+
var statusSt=useState(pmBus.overviewContext && pmBus.overviewContext.status || 'all'),status=statusSt[0],setStatus=statusSt[1],querySt=useState(pmBus.overviewContext && pmBus.overviewContext.query || ''),query=querySt[0],setQuery=querySt[1]
|
|
1973
|
+
var presentationSt=useState(pmBus.overviewContext && pmBus.overviewContext.presentation || 'table'),presentation=presentationSt[0],setPresentation=presentationSt[1]
|
|
1974
|
+
useEffect(function(){pmBus.overviewContext={version:version,status:status,query:query,presentation:presentation}},[version,status,query,presentation])
|
|
1972
1975
|
var sortSt=useState('updated'),sort=sortSt[0],setSort=sortSt[1],choiceSt=useState(false),choice=choiceSt[0],setChoice=choiceSt[1]
|
|
1973
1976
|
var infoSt=useState(null),info=infoSt[0],setInfo=infoSt[1],pickerRef=React.useRef(null),pickerButton=React.useRef(null)
|
|
1974
1977
|
var hs=useState(null),help=hs[0],setHelp=hs[1],helpRef=React.useRef(null),ims=useState(false),importOpen=ims[0],setImportOpen=ims[1]
|
|
@@ -2020,10 +2023,10 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
2020
2023
|
e('section',{className:'pmw-summary','aria-label':'本版需求统计'},e('div',{className:'pmw-summary__metrics'},statistic('total','需求总数',model.total),statistic('done','已完成',model.completed),statistic('running','进行中',model.running),statistic('waiting','待启动',model.waiting))),
|
|
2021
2024
|
e('div',{className:'pmw-overview__panels'},train),
|
|
2022
2025
|
e('section',{className:'pmw-overview__tablepanel','aria-label':'需求列表'},
|
|
2023
|
-
e('div',{className:'pmw-overview__boardhead'},e('span',{className:'pmw-panel-icon'},e(UiIcon,{name:'list'})),e('h2',null,'需求地图'),e('span',{role:'status'},model.rows.length)),
|
|
2026
|
+
e('div',{className:'pmw-overview__boardhead'},e('span',{className:'pmw-panel-icon'},e(UiIcon,{name:'list'})),e('h2',null,'需求地图'),e('span',{role:'status'},model.rows.length),e('div',{className:'sa-presentation',role:'group','aria-label':'需求展示方式'},[['table','表格'],['board','看板']].map(function(p){return e('button',{key:p[0],'aria-pressed':presentation===p[0],onClick:function(){setPresentation(p[0])}},p[1])}))),
|
|
2024
2027
|
e('div',{className:'pmw-overview__tools'},e('div',{className:'pmw-overview__views',role:'group','aria-label':'按需求状态筛选'},tabs.map(function(t){return e('button',{key:t.id,'aria-pressed':status===t.id,onClick:function(){setStatus(t.id)}},t.title,e('span',null,t.count))})),e('label',{className:'pmw-overview__search'},e(UiIcon,{name:'search'}),e('input',{'aria-label':'搜索需求、编码、负责人或应用',placeholder:'搜索需求、负责人或应用',value:query,onChange:function(ev){setQuery(ev.target.value)}}),query && e('button',{'aria-label':'清除总览搜索',onClick:function(){setQuery('')}},e(UiIcon,{name:'close'})))),
|
|
2025
2028
|
props.requirements.length===0?e('div',{className:'pmw-overview__empty'},e(UiIcon,{name:'grid'}),e('h2',null,'新建第一条需求'),e('button',{className:'pmw-btn pmw-btn--primary',onClick:props.onCreate},'新建需求')):model.rows.length===0?e('div',{className:'pmw-overview__empty'},e(UiIcon,{name:'search'}),e('h2',null,'当前范围没有需求'),e('button',{className:'pmw-btn',onClick:function(){setStatus('all');setQuery('')}},'清除状态与搜索筛选')):
|
|
2026
|
-
e('div',{className:'pmw-requirements-scroll'},e('table',{className:'pmw-requirements'},e('thead',null,e('tr',null,['需求','状态','业务方','SA','前端开发','后端开发','测试','外部应用','操作'].map(function(label){return e('th',{key:label,scope:'col'},label)}))),e('tbody',null,model.rows.map(card))))),
|
|
2029
|
+
presentation==='board'?e(RequirementKanban,{requirements:model.rows,onOpen:function(req){setInfo({requirement:req,editing:false})}}):e('div',{className:'pmw-requirements-scroll'},e('table',{className:'pmw-requirements'},e('thead',null,e('tr',null,['需求','状态','业务方','SA','前端开发','后端开发','测试','外部应用','操作'].map(function(label){return e('th',{key:label,scope:'col'},label)}))),e('tbody',null,model.rows.map(card))))),
|
|
2027
2030
|
help && e('div',{className:'pmw-overview__help',ref:helpRef,role:'dialog','aria-label':help.title,style:{left:help.left,top:help.top}},e('h3',null,help.title),e('p',null,help.text)),
|
|
2028
2031
|
importOpen && e(ReleaseImportDialog,{onClose:function(){setImportOpen(false)},onSaved:function(value){setReleases(value);props.onRefresh()}}),
|
|
2029
2032
|
info && e(RequirementInfoDialog,{requirement:info.requirement,startEditing:info.editing,onOpen:props.onOpen,onClose:function(){setInfo(null)},onSaved:props.onRefresh}))
|
|
@@ -2338,7 +2341,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
2338
2341
|
// 全局选择总线:左轨(常驻)与 SA 总览页(main 面板)共享选中态
|
|
2339
2342
|
// -----------------------------------------------------------------------
|
|
2340
2343
|
var pmBus = {
|
|
2341
|
-
state: { selectedId: null, activeSessionId: null, nav: 'home', selectedVersion: null, tabs: {}, scrolls: {}, files: {}, focus:
|
|
2344
|
+
state: { selectedId: null, activeSessionId: null, nav: 'home', selectedVersion: null, tabs: {}, scrolls: {}, files: {}, focus: true },
|
|
2342
2345
|
listeners: [],
|
|
2343
2346
|
set: function (patch) {
|
|
2344
2347
|
var changed = false
|
|
@@ -2937,6 +2940,57 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
2937
2940
|
directoryBrowser && e(DirectoryBrowser,{key:directoryBrowser.key,title:directoryBrowser.title,start:directoryBrowser.start,onCancel:function(){setDirectoryBrowser(null)},onSelect:function(location){changeField(directoryBrowser.key,location);setDirectoryBrowser(null)}}))
|
|
2938
2941
|
}
|
|
2939
2942
|
|
|
2943
|
+
var WORKSPACE_PREVIEW_CSS = "/* Task navigation is distinct from document controls. Preview is opt-in. */\r\nhtml:has(.sa-workspace-shell) .pmw-nav__group:last-child{display:none}\r\nhtml:root .pmw-root.sa-workspace-shell{--sa-preview-ink:var(--glass-ink,var(--dsw-alias-text-primary));--sa-preview-muted:var(--glass-muted,var(--dsw-alias-text-secondary));--sa-preview-card:var(--glass-card,var(--dsw-alias-background-container));--sa-preview-line:var(--glass-input,var(--dsw-alias-border-l2));}\r\n.sa-workspace-toolbar{display:flex;align-items:center;gap:16px;flex:none;padding:14px 22px 12px;min-height:66px;border-bottom:1px solid color-mix(in srgb,var(--sa-preview-line) 35%,transparent);}\r\n.sa-workspace-tabs{display:flex;gap:3px;padding:4px;border-radius:18px;background:var(--sa-preview-card);box-shadow:0 1px 0 color-mix(in srgb,var(--sa-preview-line) 30%,transparent);backdrop-filter:blur(16px);}\r\n.sa-workspace-tabs button{border:0;background:none;color:var(--sa-preview-muted);font:inherit;font-size:13px;border-radius:14px;padding:9px 16px;white-space:nowrap;cursor:pointer;}\r\n.sa-workspace-tabs button[aria-current=page]{background:var(--sa-preview-ink);color:var(--glass-bg,#fff);}\r\n.sa-workspace-tabs button:focus-visible,.sa-presentation button:focus-visible,.sa-board-card:focus-visible{outline:2px solid var(--glass-primary,#7663db);outline-offset:3px;}\r\n.sa-workspace-label{margin-left:auto;font-size:12px;color:var(--sa-preview-muted);}\r\n.sa-mobile-create{display:none;}\r\n.sa-workspace-toolbar .sa-theme-switch{flex:none;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-overview__head>.sa-theme-switch{display:none}\r\n.sa-settings-scroll{overflow:auto;min-height:0;flex:1;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-detail__head{padding:18px 24px 14px;gap:12px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-detail__head .sa-assistant-toggle{width:auto;margin-left:8px;gap:7px;border:1px solid var(--sa-preview-line);border-radius:16px;padding:7px 12px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-detail__head .sa-assistant-toggle[aria-expanded=true]{background:var(--glass-tint);}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-ai{border-left:1px solid var(--sa-preview-line);background:var(--sa-preview-card);}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-ai__context{gap:8px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-ai__context>span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-ai__context>button{margin-left:auto;padding:4px;flex:none;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-doc--empty{padding:28px 24px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state{max-width:920px;display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,.85fr);column-gap:32px;row-gap:16px;margin:0 auto;align-content:start;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state__heading,html:root .pmw-root.sa-workspace-shell .pmw-empty-state__description{grid-column:1;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state__heading{align-self:end;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state__description{margin:0;max-width:460px;line-height:1.8;}\r\n.sa-deliverable{grid-column:2;grid-row:1 / span 6;align-self:start;padding:24px;border:1px solid color-mix(in srgb,var(--sa-preview-line) 65%,transparent);border-radius:24px;background:var(--sa-preview-card);box-shadow:0 10px 30px -24px var(--sa-preview-ink);}\r\n.sa-deliverable__eyebrow{font-size:11px;letter-spacing:.12em;color:var(--sa-preview-muted);}\r\n.sa-deliverable h4{font-size:18px;line-height:1.55;margin:10px 0 18px;font-weight:600;color:var(--sa-preview-ink);}\r\n.sa-deliverable ul{padding:0;margin:0;list-style:none;display:grid;gap:14px;}\r\n.sa-deliverable li{display:flex;gap:10px;align-items:flex-start;font-size:13px;line-height:1.65;}\r\n.sa-deliverable li>span{flex:none;font-size:10px;width:24px;height:24px;display:grid;place-items:center;border-radius:50%;background:var(--glass-tint);color:var(--sa-preview-muted);}\r\n.sa-deliverable__hint,.sa-deliverable__missing{font-size:12px;line-height:1.8;color:var(--sa-preview-muted);margin:18px 0 0;}\r\n.sa-deliverable__missing{border-top:1px solid var(--sa-preview-line);padding-top:14px;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-sources{grid-column:1;max-width:100%;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-empty-state__file,html:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-btn,html:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-empty-state__note{grid-column:1;justify-self:start;margin:0;}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state>.pmw-btn{border-radius:16px;padding:11px 18px;}\r\n.sa-presentation{display:flex;margin-left:auto;padding:3px;border:1px solid var(--sa-preview-line);border-radius:14px;gap:2px;}\r\n.sa-presentation button{font:inherit;font-size:12px;padding:6px 11px;cursor:pointer;color:var(--sa-preview-muted);border:0;border-radius:10px;background:none;}\r\n.sa-presentation button[aria-pressed=true]{background:var(--sa-preview-card);box-shadow:0 1px 4px #0001;color:var(--sa-preview-ink);}\r\n.sa-requirement-board{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;padding:8px 0 20px;}\r\n.sa-board-column{background:color-mix(in srgb,var(--sa-preview-ink) 3%,transparent);border-radius:22px;padding:12px;min-height:240px;}\r\n.sa-board-column>header{display:flex;align-items:center;justify-content:space-between;margin:2px 4px 14px;font-size:12px;color:var(--sa-preview-muted);}\r\n.sa-board-card{display:flex;text-align:left;flex-direction:column;gap:10px;cursor:pointer;padding:18px;margin:0 0 12px;width:100%;font:inherit;color:var(--sa-preview-ink);border:1px solid color-mix(in srgb,var(--sa-preview-line) 65%,transparent);border-radius:18px;background:var(--sa-preview-card);transition:transform .15s;}\r\n.sa-board-card:hover{transform:translateY(-2px);}\r\n.sa-board-card code{font-size:11px;color:var(--sa-preview-muted);}\r\n.sa-board-card strong{font-size:15px;line-height:1.6;overflow-wrap:anywhere;}\r\n.sa-board-card__stage,.sa-board-card footer{font-size:11px;line-height:1.6;color:var(--sa-preview-muted);}\r\n.sa-board-card footer{display:flex;justify-content:space-between;gap:8px;padding-top:10px;border-top:1px solid var(--sa-preview-line);flex-wrap:wrap;}\r\n.sa-board-empty{font-size:12px;color:var(--sa-preview-muted);padding:20px 6px;}\r\n@media(max-width:1100px){html:root .pmw-root.sa-workspace-shell:has(.pmw-ai) .pmw-empty-state{grid-template-columns:minmax(0,1fr)}html:root .pmw-root.sa-workspace-shell:has(.pmw-ai) .sa-deliverable{grid-column:1;grid-row:auto;}}\r\n@media(max-width:760px){.sa-workspace-toolbar{padding:10px 14px;gap:8px;}.sa-workspace-tabs button{padding:8px 12px;}.sa-workspace-label{display:none}.sa-workspace-toolbar .sa-theme-switch{margin-left:auto;}html:root .pmw-root.sa-workspace-shell .pmw-empty-state{grid-template-columns:minmax(0,1fr);}.sa-deliverable{grid-column:1;grid-row:auto;}.sa-requirement-board{grid-template-columns:minmax(0,1fr)}html:root .pmw-root.sa-workspace-shell .pmw-doc--empty{padding:20px 16px;}html:root .pmw-root.sa-workspace-shell .pmw-detail__head{padding:14px 16px;}html:root .pmw-root.sa-workspace-shell .pmw-ai{position:absolute;right:0;top:0;bottom:0;z-index:20;width:min(420px,100%);box-shadow:-12px 0 40px #0002;}html:root .pmw-root.sa-workspace-shell .pmw-body{position:relative;}}\r\n@media(prefers-reduced-motion:reduce){.sa-board-card{transition:none}}\r\n\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-detail__title{font-size:20px;font-weight:600;line-height:1.45}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-empty-state{max-width:980px;width:100%}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-deliverable li>span{border-radius:50%!important;corner-shape:round!important}\r\n@media(max-width:760px){html:has(.sa-workspace-shell) .pmw-nav{display:none!important}html:root .pmw-root.sa-workspace-shell .pmw-empty-state{max-width:100%}.sa-workspace-toolbar{gap:6px}.sa-workspace-tabs{min-width:0;overflow-x:auto}.sa-workspace-tabs button{font-size:12px;padding:7px 8px}.sa-workspace-toolbar .sa-theme-switch{margin-left:0!important}}\r\n@media(max-width:760px){.sa-mobile-create{display:inline-flex;align-items:center;justify-content:center;flex:none;width:32px;height:32px;border:1px solid var(--sa-preview-line);border-radius:50%;color:var(--sa-preview-ink);background:var(--sa-preview-card);cursor:pointer}.sa-workspace-tabs{flex:1}.sa-workspace-toolbar{padding:10px}}\r\n\r\n/* Annotation revision: segmented stage route and composed start panel. */\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-stages{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0;padding:18px 24px 20px;overflow:visible}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:8px;padding:0;overflow:visible;background:none;border:0;min-width:0}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step::before,html:root .pmw-root.sa-workspace-shell .pmw-step::after{display:none}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step__number{position:relative;z-index:2;display:flex;align-items:center;justify-content:center;width:40px;height:40px;min-width:40px;padding:0;border-radius:50%!important;corner-shape:round!important;border:1.5px solid var(--sa-preview-line);background:var(--glass-popover,var(--glass-bg));color:var(--sa-preview-muted);box-shadow:none;outline:0}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step__number>svg{width:19px;height:19px}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step.is-current .pmw-step__number{background:var(--sa-preview-ink);border-color:var(--sa-preview-ink);color:var(--glass-bg)}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step.is-active:not(.is-current) .pmw-step__number{border-color:var(--glass-primary);color:var(--glass-primary);background:var(--glass-bg);box-shadow:0 0 0 4px var(--glass-tint)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-connector{position:absolute;z-index:1;top:19px;left:calc(-50% + 24px);width:calc(100% - 48px);height:0;border-top:2px solid var(--sa-preview-line);pointer-events:none}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-connector.is-reached{border-color:var(--sa-preview-ink)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-connector.is-optional{border-top-style:dashed}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-done{position:absolute;right:-3px;bottom:-2px;width:16px;height:16px;border-radius:50%;display:grid;place-items:center;background:var(--sa-preview-ink);color:var(--glass-bg);border:2px solid var(--glass-bg)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-done .pmw-icon{width:10px;height:10px}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step__label{font-size:13px;line-height:20px}\r\nhtml:root .pmw-root.sa-workspace-shell .pmw-step small{margin:0;font-size:11px;line-height:16px}\r\n.sa-empty-workspace{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.9fr);gap:28px;max-width:1060px;margin:10px auto 0;width:100%;align-items:stretch}\r\n.sa-empty-workspace>.sa-deliverable{grid-column:auto;grid-row:auto;align-self:stretch;box-shadow:none}\r\n.sa-stage-start{display:flex;flex-direction:column;gap:0;padding:28px;border:1px solid color-mix(in srgb,var(--sa-preview-line) 60%,transparent);border-radius:24px;background:var(--sa-preview-card);min-width:0}\r\n.sa-stage-start__header{display:flex;gap:10px;align-items:center;font-size:12px;color:var(--sa-preview-muted)}\r\n.sa-stage-start__glyph{display:grid;place-items:center;width:36px;height:36px;border-radius:12px;color:var(--glass-primary);background:var(--glass-tint)}\r\n.sa-stage-start__state{margin-left:auto;font-size:11px;padding:4px 9px;border-radius:999px;background:var(--glass-secondary)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-start h3{font-size:24px;line-height:1.4;font-weight:600;margin:22px 0 12px;color:var(--sa-preview-ink)}\r\n.sa-stage-start__intro{font-size:13px;line-height:1.85;margin:0 0 24px;color:var(--sa-preview-muted)}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-start>.pmw-sources{max-width:100%;width:100%;margin:0 0 18px}\r\n.sa-stage-output{display:flex;align-items:center;gap:12px;background:var(--glass-secondary);border:1px solid color-mix(in srgb,var(--sa-preview-line) 45%,transparent);border-radius:16px;padding:15px 16px;margin-top:auto}\r\n.sa-stage-output__icon{display:grid;place-items:center;width:36px;height:40px;border-radius:9px;background:var(--glass-card);color:var(--sa-preview-muted)}\r\n.sa-stage-output small{display:block;font-size:11px;color:var(--sa-preview-muted);margin-bottom:4px}\r\n.sa-stage-output code{display:block;font-size:13px;color:var(--sa-preview-ink);overflow-wrap:anywhere}\r\n.sa-stage-start__actions{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:22px}\r\nhtml:root .pmw-root.sa-workspace-shell .sa-stage-start__actions .pmw-btn{display:inline-flex;align-items:center;gap:18px;padding:11px 18px;border-radius:14px}\r\n.sa-stage-start__actions>span{font-size:11px;color:var(--sa-preview-muted)}\r\n@media(max-width:1100px){html:root .pmw-root.sa-workspace-shell:has(.pmw-ai) .sa-empty-workspace{grid-template-columns:minmax(0,1fr)}}\r\n@media(max-width:760px){.sa-empty-workspace{grid-template-columns:minmax(0,1fr);gap:18px;margin-top:0}.sa-stage-start{padding:22px}.sa-empty-workspace>.sa-deliverable{grid-column:auto;grid-row:auto}html:root .pmw-root.sa-workspace-shell .pmw-stages{padding:16px 12px 18px}html:root .pmw-root.sa-workspace-shell .pmw-step__number{width:34px;height:34px;min-width:34px}html:root .pmw-root.sa-workspace-shell .sa-stage-connector{top:16px;left:calc(-50% + 21px);width:calc(100% - 42px)}html:root .pmw-root.sa-workspace-shell .pmw-step__label{font-size:11px}}\r\n";
|
|
2944
|
+
function StageGlyph(props){
|
|
2945
|
+
var paths={intake:['M4 5h16v11H9l-5 4V5','M8 9h8M8 12h5'],solution:['M4 4h6v6H4zM14 14h6v6h-6z','M10 7h7v7M7 10v7h7'],prd:['M14 3H6a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8l-5-5z','M14 3v5h5M8 14l2 2 5-5'],prototype:['M3 4h18v16H3z','M3 9h18M9 9v11']};
|
|
2946
|
+
return e('svg',{width:20,height:20,viewBox:'0 0 24 24',fill:'none',stroke:'currentColor',strokeWidth:1.65,strokeLinecap:'round',strokeLinejoin:'round','aria-hidden':true},(paths[props.stage] || paths.prd).map(function(d,i){return e('path',{key:i,d:d})}))
|
|
2947
|
+
}
|
|
2948
|
+
function StageStartCard(props){
|
|
2949
|
+
var action={intake:'开始梳理',solution:'开始设计',prd:'开始编写',prototype:'开始制作'}[props.stage];
|
|
2950
|
+
return e('section',{className:'sa-stage-start','aria-label':props.title},
|
|
2951
|
+
e('header',{className:'sa-stage-start__header'},e('span',{className:'sa-stage-start__glyph'},e(StageGlyph,{stage:props.stage})),e('span',null,props.archived?'归档记录':'准备开始'),e('span',{className:'sa-stage-start__state'},props.archived?'未包含':'尚未生成')),
|
|
2952
|
+
e('h3',null,props.title),e('p',{className:'sa-stage-start__intro'},props.description),
|
|
2953
|
+
props.sources,
|
|
2954
|
+
props.artifact && e('div',{className:'sa-stage-output'},e('span',{className:'sa-stage-output__icon'},e(StageGlyph,{stage:props.stage})),e('div',null,e('small',null,props.archived?'未包含文件':'交付文件'),e('code',null,props.artifact.path))),
|
|
2955
|
+
!props.archived && props.artifact && e('footer',{className:'sa-stage-start__actions'},e('button',{className:'pmw-btn pmw-btn--primary',disabled:props.busy,onClick:props.onStart},props.busy?'正在准备…':action,e('svg',{width:16,height:16,viewBox:'0 0 24 24',fill:'none',stroke:'currentColor',strokeWidth:1.8,'aria-hidden':true},e('path',{d:'M5 12h14M13 6l6 6-6 6',strokeLinecap:'round',strokeLinejoin:'round'}))),e('span',null,'使用当前工作方法')))
|
|
2956
|
+
}
|
|
2957
|
+
function WorkspaceNavigation(props){
|
|
2958
|
+
var active=props.current==='create'?'home':props.current;
|
|
2959
|
+
return e('header',{className:'sa-workspace-toolbar'},
|
|
2960
|
+
e('nav',{'aria-label':'SA 工作台导航',className:'sa-workspace-tabs'},[['home','需求'],['kb','知识库'],['plib','归档库'],['settings','工作方法']].map(function(t){return e('button',{key:t[0],type:'button','aria-current':active===t[0]?'page':undefined,onClick:function(){props.onNavigate(t[0])}},t[1])})),
|
|
2961
|
+
e('span',{className:'sa-workspace-label'},'SA 工作台'),
|
|
2962
|
+
e('button',{className:'sa-mobile-create',type:'button','aria-label':'新建需求',onClick:function(){props.onNavigate('create')}},e(UiIcon,{name:'plus'})),
|
|
2963
|
+
e('div',{className:'sa-theme-switch','aria-label':'工作台外观'},['light','dark'].map(function(a){return e('button',{key:a,type:'button','aria-label':a==='light'?'浅色模式':'暗色模式','aria-pressed':(pmBus.state.appearance || saAppearance())===a,onClick:function(){setSaAppearance(a)}},a==='light'?'☀':'☾')})))
|
|
2964
|
+
}
|
|
2965
|
+
function stageDeliverableModel(stage,requirement,artifact){
|
|
2966
|
+
var definitions={
|
|
2967
|
+
intake:{title:'一份可继续设计的业务需求',items:['业务目标与使用场景','范围、现状与资料依据','需要进一步确认的问题']},
|
|
2968
|
+
solution:{title:'一份可讨论的高阶方案',items:['关键设计点与系统职责','业务流程、依赖及改造范围','方案依据与待决策事项']},
|
|
2969
|
+
prd:{title:'一份可评审、可验证的 PRD',items:['用户故事与完整业务规则','Given / When / Then 验收条件','相关流程与交互说明']},
|
|
2970
|
+
prototype:{title:'一份可操作的交互原型',items:['主要页面与关键任务路径','适用的正常、异常与空状态','供讨论与迭代的页面交互']}
|
|
2971
|
+
};
|
|
2972
|
+
var model=definitions[stage] || definitions.intake;
|
|
2973
|
+
var prior=stage==='solution'?['intake']:stage==='prd'?['intake','solution']:stage==='prototype'?['prd']:[];
|
|
2974
|
+
var missing=prior.filter(function(id){var s=(requirement.stages || []).find(function(s){return s.id===id});return !s || !(s.artifacts || []).some(function(a){return a.exists})});
|
|
2975
|
+
return {title:model.title,items:model.items,missing:missing.map(function(id){return {intake:'业务需求',solution:'高阶方案',prd:'PRD'}[id]}),file:artifact && artifact.path,archived:!!requirement.archived};
|
|
2976
|
+
}
|
|
2977
|
+
function StageDeliverablePreview(props){
|
|
2978
|
+
var model=stageDeliverableModel(props.stage,props.requirement,props.artifact);
|
|
2979
|
+
if(model.archived)return null;
|
|
2980
|
+
return e('aside',{className:'sa-deliverable','aria-label':'本阶段交付预览'},
|
|
2981
|
+
e('div',{className:'sa-deliverable__eyebrow'},'本阶段交付'),e('h4',null,model.title),
|
|
2982
|
+
e('ul',null,model.items.map(function(text,i){return e('li',{key:text},e('span',{'aria-hidden':true},String(i+1).padStart(2,'0')),text)})),
|
|
2983
|
+
model.missing.length>0 && e('p',{className:'sa-deliverable__missing'},'尚未发现'+model.missing.join('、')+'文档。助手会先核对依据,必要时补充澄清。'),
|
|
2984
|
+
e('p',{className:'sa-deliverable__hint'},'以上为预期内容,当前尚未生成;生成后仍需评审。'))
|
|
2985
|
+
}
|
|
2986
|
+
function RequirementKanban(props){
|
|
2987
|
+
return e('div',{className:'sa-requirement-board','aria-label':'需求状态看板'},[['waiting','待启动'],['running','进行中'],['done','已完成']].map(function(group){
|
|
2988
|
+
var rows=props.requirements.filter(function(r){return overviewStatus(r)===group[0]});
|
|
2989
|
+
return e('section',{key:group[0],className:'sa-board-column'},e('header',null,e('span',{className:'pmw-stage-pill is-'+group[0]},e('i',{'aria-hidden':true}),group[1]),e('span',null,rows.length)),
|
|
2990
|
+
rows.length?rows.map(function(req){var c=collaborationValue(req),stages=req.stages || [],existing=stages.filter(function(s){return (s.artifacts || []).some(function(a){return a.exists})}).length;return e('button',{key:req.id,className:'sa-board-card',onClick:function(){props.onOpen(req)},'aria-label':'查看 '+req.code+' '+req.title},e('code',null,req.code),e('strong',null,req.title),e('span',{className:'sa-board-card__stage'},stageTitle(req)),e('footer',null,e('span',null,c.pmOwner || 'SA 待填写'),e('span',null,existing?existing+' 个阶段已有稿':'尚无阶段稿')))}):e('p',{className:'sa-board-empty'},'当前筛选下暂无需求'))
|
|
2991
|
+
}))
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2940
2994
|
function Panel(props) {
|
|
2941
2995
|
var layout = props.layout
|
|
2942
2996
|
var pm = props.pm
|
|
@@ -2949,6 +3003,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
2949
3003
|
var form = useState('home')
|
|
2950
3004
|
var view = form[0]
|
|
2951
3005
|
var setView = form[1]
|
|
3006
|
+
var pendingNavigationSt=useState(null),pendingNavigation=pendingNavigationSt[0],setPendingNavigation=pendingNavigationSt[1]
|
|
2952
3007
|
var ft = useState('')
|
|
2953
3008
|
var formTitle = ft[0]
|
|
2954
3009
|
var setFormTitle = ft[1]
|
|
@@ -3348,7 +3403,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3348
3403
|
return pm.sendToReq(selected, dir, body.prompt).then(function (res) {
|
|
3349
3404
|
setBusy(false)
|
|
3350
3405
|
if (!res || !res.ok) setOpErr((res && res.error) || '发送失败')
|
|
3351
|
-
else {setNotice('已发送到对话 · 使用 '+body.skill.name+';请在会话中查看进展。');if(stageId==='intake')return apiSend('POST','/requirement-start',{id:selected.id}).then(reload)}
|
|
3406
|
+
else {pmBus.set({focus:false});setNotice('已发送到对话 · 使用 '+body.skill.name+';请在会话中查看进展。');if(stageId==='intake')return apiSend('POST','/requirement-start',{id:selected.id}).then(reload)}
|
|
3352
3407
|
})
|
|
3353
3408
|
}).catch(function (err) {
|
|
3354
3409
|
setBusy(false)
|
|
@@ -3517,10 +3572,16 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3517
3572
|
}).catch(function(err) { if (pmBus.state.selectedId === owner.id) setOpErr(String(err.message || err)) }).finally(function(){setBusy(false)})
|
|
3518
3573
|
}
|
|
3519
3574
|
|
|
3575
|
+
function navigateWorkspace(target){
|
|
3576
|
+
if(editor){setPendingNavigation(target);return}
|
|
3577
|
+
completeNavigation(target)
|
|
3578
|
+
}
|
|
3579
|
+
function completeNavigation(target){setPendingNavigation(null);setEditor(null);pmBus.set({nav:target,selectedId:null,activeSessionId:null,settingsReturn:null});setView(target)}
|
|
3580
|
+
var workspaceNav=e(WorkspaceNavigation,{current:view,onNavigate:navigateWorkspace})
|
|
3520
3581
|
var children = []
|
|
3521
3582
|
|
|
3522
3583
|
if (data.data && (data.data.setupRequired || data.data.restartRequired)) return e('div',{className:'pmw-root','data-sa-appearance':bus.appearance || saAppearance()},e(SettingsPanel,{onboarding:true,onComplete:function(){pmBus.set({nav:'home',selectedId:null,activeSessionId:null,settingsReturn:null});setView('home');reload()}}))
|
|
3523
|
-
if (view === 'settings') return e('div', { className: 'pmw-root', 'data-sa-appearance':bus.appearance || saAppearance() },
|
|
3584
|
+
if (view === 'settings') return e('div', { className: 'pmw-root sa-workspace-shell', 'data-sa-appearance':bus.appearance || saAppearance() },e('style',null,WORKSPACE_PREVIEW_CSS),workspaceNav,e('div',{className:'sa-settings-scroll'},e(SettingsPanel)))
|
|
3524
3585
|
|
|
3525
3586
|
// header(纯标题,动作全部收进各自语境:Tab 空态/地铁图归档站/右栏线程条)
|
|
3526
3587
|
if (!selected && (view !== 'home' || !data.data)) children.push(e('div', { className: 'pmw-header', key: 'header' },
|
|
@@ -3541,7 +3602,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3541
3602
|
e('div',{className:'pmw-dialog__body'},e('label',{className:'pmw-field'},e('span',{className:'pmw-field__label'},'文件名称'),e('input',{className:'pmw-input',autoFocus:true,'aria-label':'文件名称',value:newFile.name,maxLength:110,onChange:function(ev){setNewFile(Object.assign({},newFile,{name:ev.target.value}))},placeholder:'例如:接口说明'})),
|
|
3542
3603
|
e('label',{className:'pmw-field'},e('span',{className:'pmw-field__label'},'文档内容'),e('textarea',{className:'pmw-textarea','aria-label':'新增文档内容',value:newFile.content,onChange:function(ev){setNewFile(Object.assign({},newFile,{content:ev.target.value}))},placeholder:'支持 Markdown'})),opErr && e('p',{role:'alert'},opErr)),
|
|
3543
3604
|
e('div',{className:'pmw-dialog__foot'},e('button',{type:'button',className:'pmw-btn',disabled:isBusy,onClick:function(){setNewFile(null)}},'取消'),e('button',{type:'submit',className:'pmw-btn pmw-btn--primary',disabled:isBusy || !newFile.name.trim() || !newFile.content.trim()},isBusy?'正在添加…':'添加文档')))))
|
|
3544
|
-
return e('div', { ref:rootRef, className: 'pmw-root' + (expanded ? ' is-expanded' : ''), 'data-sa-appearance':bus.appearance || saAppearance() }, children)
|
|
3605
|
+
return e('div', { ref:rootRef, className: 'pmw-root sa-workspace-shell' + (expanded ? ' is-expanded' : ''), 'data-sa-appearance':bus.appearance || saAppearance() },e('style',null,WORKSPACE_PREVIEW_CSS),!expanded && workspaceNav,pendingNavigation && e(DetailDialog,{title:'离开未保存的文档?',onClose:function(){setPendingNavigation(null)},footer:e(React.Fragment,null,e('button',{className:'pmw-btn',onClick:function(){setPendingNavigation(null)}},'继续编辑'),e('button',{className:'pmw-btn pmw-btn--primary',onClick:function(){completeNavigation(pendingNavigation)}},'放弃修改并离开'))},e('p',null,'当前修改尚未保存。继续编辑可保留草稿;离开将放弃这些修改,原文件不变。')),children)
|
|
3545
3606
|
}
|
|
3546
3607
|
|
|
3547
3608
|
// body: main + chat
|
|
@@ -3676,13 +3737,10 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3676
3737
|
return e('button', { key: stage.id, className: 'pmw-step' + (stage.id === curTab ? ' is-active' : '') + (exists ? ' is-complete' : '') + (current ? ' is-current' : '') + (optional ? ' is-optional' : ''),
|
|
3677
3738
|
'aria-pressed': stage.id === curTab, 'aria-current': current ? 'step' : undefined, title: stage.title + ' · ' + (exists ? '已有文档' : '尚未生成') + (stage.id === curTab ? ' · 正在查看' : ''),
|
|
3678
3739
|
onClick: function () { if (stage.id === curTab) return; if (editor && !confirm('有未保存的修改,确定放弃并切换文档?')) return; setEditor(null); setTabSt(stage.id) },
|
|
3679
|
-
}, e('span',
|
|
3740
|
+
},index>0 && e('span',{className:'sa-stage-connector'+(optional?' is-optional':'')+((exists || current) && selected.stages[index-1].artifacts[0].exists?' is-reached':''),'aria-hidden':true}),e('span',{className:'pmw-step__number','aria-hidden':true},e(StageGlyph,{stage:stage.id}),exists && e('span',{className:'sa-stage-done'},e(UiIcon,{name:'check'}))),
|
|
3680
3741
|
e('span', {className:'pmw-step__label'}, label), e('small', null, status))
|
|
3681
3742
|
})
|
|
3682
|
-
|
|
3683
|
-
e('path',{className:'pmw-metro__line',d:'M125 20 H625',vectorEffect:'non-scaling-stroke'}),
|
|
3684
|
-
progressX > 125 && e('path',{className:'pmw-metro__line is-travelled',d:'M125 20 H'+progressX,vectorEffect:'non-scaling-stroke'}),
|
|
3685
|
-
e('path',{className:'pmw-metro__line pmw-metro__branch'+(prototypeExists ? ' is-travelled' : ''),d:'M625 20 H875',vectorEffect:'non-scaling-stroke'})))
|
|
3743
|
+
|
|
3686
3744
|
|
|
3687
3745
|
var currentDocReady = doc && curArt && doc.path === curArt.path && !doc.loading && !doc.error
|
|
3688
3746
|
var cloudReceipt = currentDocReady && doc.receipt
|
|
@@ -3713,20 +3771,9 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3713
3771
|
var sourcesNode = curTab === 'intake' && e(SourceInputs,{key:'sources-'+selected.id,id:selected.id,readOnly:!!selected.archived,hasDoc:!!(curArt && curArt.exists),stageBusy:isBusy,onBusy:setSourceBusy,onStart:function(){handStage('intake')}})
|
|
3714
3772
|
if (!curArt || !curArt.exists) {
|
|
3715
3773
|
var emptyCopy={intake:['梳理业务需求','从你的诉求和业务资料开始,澄清目标、使用场景与范围,保留待确认的问题。','梳理需求'],solution:['形成高阶方案','结合业务需求与现状,明确系统职责、改造方向、依赖与未决事项。','设计高阶方案'],prd:['编写 PRD','基于需求与高阶方案,展开可验证的功能、业务规则和验收条件。','编写 PRD'],prototype:['制作交互原型','用可操作的页面检验 PRD 中的流程与交互。原型按需交付,不阻止归档。','制作原型']}[curTab]
|
|
3716
|
-
contentNode
|
|
3717
|
-
e('
|
|
3718
|
-
|
|
3719
|
-
e('h3',null,selected.archived ? '本次归档未包含'+documentName : emptyCopy[0])),
|
|
3720
|
-
e('p',{className:'pmw-empty-state__description'},selected.archived ? '此归档保留了当时已有的交付文件,未生成的文档不会自动补齐。' : emptyCopy[1]),
|
|
3721
|
-
sourcesNode,
|
|
3722
|
-
curArt && e('div',{className:'pmw-empty-state__file'},e(UiIcon,{name:'doc'}),selected.archived?'未包含文件':'交付文件',e('code',null,curArt.path)),
|
|
3723
|
-
!selected.archived && curArt && e('button', {
|
|
3724
|
-
className: 'pmw-btn pmw-btn--primary',
|
|
3725
|
-
disabled: isBusy || sourceBusy,
|
|
3726
|
-
onClick: function () { handStage(curTab) },
|
|
3727
|
-
}, isBusy ? '正在准备…' : '开始动手吧'),
|
|
3728
|
-
!selected.archived && e('p',{className:'pmw-empty-state__note'},'使用当前绑定的工作方法发送到当前对话;信息不足时先澄清。'),
|
|
3729
|
-
))
|
|
3774
|
+
contentNode=e('div',{className:'pmw-doc pmw-doc--empty',key:'empty'},e('div',{className:'sa-empty-workspace'},
|
|
3775
|
+
e(StageStartCard,{stage:curTab,title:selected.archived?'本次归档未包含'+documentName:emptyCopy[0],description:selected.archived?'此归档保留了当时已有的交付文件,未生成的文档不会自动补齐。':emptyCopy[1],artifact:curArt,archived:!!selected.archived,sources:sourcesNode,busy:isBusy || sourceBusy,onStart:function(){handStage(curTab)}}),
|
|
3776
|
+
e(StageDeliverablePreview,{stage:curTab,requirement:selected,artifact:curArt})))
|
|
3730
3777
|
} else if (doc && doc.path === curArt.path) {
|
|
3731
3778
|
var isHtml = /\.html?$/i.test(doc.path)
|
|
3732
3779
|
// UX 标注工具条:原型 Tab、当前版本即出现;已归档降级为只读(可看 pin,不可新增/改稿)
|
|
@@ -3785,10 +3832,10 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3785
3832
|
mainChildren.push(e('div', { className: 'pmw-detail', key: 'detail' },
|
|
3786
3833
|
!expanded && e('div', { className: 'pmw-detail__head' },
|
|
3787
3834
|
e('h2', { className: 'pmw-detail__title' }, selected.title),
|
|
3788
|
-
e('button',{className:'pmw-btn pmw-btn--ghost',onClick:function(){setRequirementInfo(selected)}},e(UiIcon,{name:'
|
|
3835
|
+
e('button',{className:'pmw-btn pmw-btn--ghost',onClick:function(){setRequirementInfo(selected)}},e(UiIcon,{name:'users'}),'协作信息'),
|
|
3789
3836
|
selected.code ? e('span', { className: 'pmw-tag pmw-tag--code' }, selected.code) : null,
|
|
3790
3837
|
e('span', { className: 'pmw-detail__version' }, selected.version || '未排期'),
|
|
3791
|
-
e('button', { className: 'pmw-btn pmw-btn--ghost
|
|
3838
|
+
e('button', { className: 'pmw-btn pmw-btn--ghost sa-assistant-toggle', 'aria-label':bus.focus?'打开需求助手':'收起需求助手','aria-expanded':!bus.focus,onClick:function(){pmBus.set({focus:!bus.focus})} },e(UiIcon,{name:'chat'}),bus.focus?'助手':'收起助手'),
|
|
3792
3839
|
),
|
|
3793
3840
|
!expanded && e('nav', { className: 'pmw-stages', 'aria-label': '需求交付阶段' }, metroNodes),
|
|
3794
3841
|
tabBar,
|
|
@@ -3842,7 +3889,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3842
3889
|
var chatError = bus.sessionError || (convRef && convRef.id === activeSessionId && convRef.error)
|
|
3843
3890
|
chatNode = e('div', { className: 'pmw-ai', key: 'ai' },
|
|
3844
3891
|
barNode,
|
|
3845
|
-
e('div', { className: 'pmw-ai__context' }, e(UiIcon, { name: 'link' }), e('span', null, selected.code + ' · ' + selected.title)),
|
|
3892
|
+
e('div', { className: 'pmw-ai__context' }, e(UiIcon, { name: 'link' }), e('span', null, selected.code + ' · ' + selected.title),e('button',{className:'pmw-btn pmw-btn--ghost','aria-label':'收起需求助手',onClick:function(){pmBus.set({focus:true})}},e(UiIcon,{name:'close'}))),
|
|
3846
3893
|
canChat
|
|
3847
3894
|
? e('div', { className: 'pmw-ai__conv', key: 'conv' },
|
|
3848
3895
|
e(props.SessionProvider, { session: convRef.ref }, props.renderSlot('pm.conv', {})))
|
|
@@ -3881,7 +3928,7 @@ div:has(> [data-slot='sidebar.footer.action']) { display: contents; }
|
|
|
3881
3928
|
e('div',{className:'pmw-dialog__body'},e('label',{className:'pmw-field'},e('span',{className:'pmw-field__label'},'文件名称'),e('input',{className:'pmw-input',autoFocus:true,'aria-label':'文件名称',value:newFile.name,maxLength:110,onChange:function(ev){setNewFile(Object.assign({},newFile,{name:ev.target.value}))},placeholder:'例如:接口说明'})),
|
|
3882
3929
|
e('label',{className:'pmw-field'},e('span',{className:'pmw-field__label'},'文档内容'),e('textarea',{className:'pmw-textarea','aria-label':'新增文档内容',value:newFile.content,onChange:function(ev){setNewFile(Object.assign({},newFile,{content:ev.target.value}))},placeholder:'支持 Markdown'})),opErr && e('p',{role:'alert'},opErr)),
|
|
3883
3930
|
e('div',{className:'pmw-dialog__foot'},e('button',{type:'button',className:'pmw-btn',disabled:isBusy,onClick:function(){setNewFile(null)}},'取消'),e('button',{type:'submit',className:'pmw-btn pmw-btn--primary',disabled:isBusy || !newFile.name.trim() || !newFile.content.trim()},isBusy?'正在添加…':'添加文档')))))
|
|
3884
|
-
return e('div', { ref:rootRef, className: 'pmw-root' + (expanded ? ' is-expanded' : ''), 'data-sa-appearance':bus.appearance || saAppearance() }, children)
|
|
3931
|
+
return e('div', { ref:rootRef, className: 'pmw-root sa-workspace-shell' + (expanded ? ' is-expanded' : ''), 'data-sa-appearance':bus.appearance || saAppearance() },e('style',null,WORKSPACE_PREVIEW_CSS),!expanded && workspaceNav,pendingNavigation && e(DetailDialog,{title:'离开未保存的文档?',onClose:function(){setPendingNavigation(null)},footer:e(React.Fragment,null,e('button',{className:'pmw-btn',onClick:function(){setPendingNavigation(null)}},'继续编辑'),e('button',{className:'pmw-btn pmw-btn--primary',onClick:function(){completeNavigation(pendingNavigation)}},'放弃修改并离开'))},e('p',null,'当前修改尚未保存。继续编辑可保留草稿;离开将放弃这些修改,原文件不变。')),children)
|
|
3885
3932
|
}
|
|
3886
3933
|
|
|
3887
3934
|
// -----------------------------------------------------------------------
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"0.1.
|
|
1
|
+
{"type":"module","version":"0.1.29"}
|