@@ -278,6 +278,18 @@ interface DutyCatalogDoc {
assigned : boolean ; author? : string ; reviewers? : string [ ] ; approver? : string ; activeRound? : number
}
interface DocsTemplateRow {
templateId : string ; version : string ; title : string ; docTypes : string [ ] ; stage? : string
}
/** rdm.docs.instantiate 参数:docType 取首个适用类型;空标题交由后端取模板标题。 */
export function docsInstantiateParams ( tpl : DocsTemplateRow , title : string ) : Record < string , unknown > {
return {
docType : tpl.docTypes [ 0 ] , templateId : tpl.templateId , version : tpl.version ,
. . . ( title . trim ( ) ? { title : title.trim ( ) } : { } ) ,
}
}
interface DutyGetOut {
docId : string ; title : string ; assigned : boolean
roles : { author : string ; reviewers : string [ ] ; approver : string }
@@ -320,6 +332,9 @@ export function RdmDutiesSection({ project }: { project: Project }) {
const [ err , setErr ] = useState ( '' )
const [ notice , setNotice ] = useState ( '' )
const [ busy , setBusy ] = useState ( false )
const [ tpls , setTpls ] = useState < DocsTemplateRow [ ] | null > ( null )
const [ tplSel , setTplSel ] = useState ( '' )
const [ newTitle , setNewTitle ] = useState ( '' )
const cmd = < T , > ( id : string , params : Record < string , unknown > ) = > api . rdmProjectCommand < T > ( project , id , params )
const memberPage = useMemberPickerPage ( members )
@@ -388,6 +403,9 @@ export function RdmDutiesSection({ project }: { project: Project }) {
cmd < { members : { owner : string ; role : string } [ ] } > ( 'rdm.project.member.list' , { projectId } )
. then ( out = > { if ( currentProject ( epoch ) ) setMembers ( out . members ? ? [ ] ) } )
. catch ( ( ) = > { if ( currentProject ( epoch ) ) setMembers ( [ ] ) } )
api . rdmCommand < DocsTemplateRow [ ] > ( 'rdm.docs.templates' )
. then ( rows = > { if ( currentProject ( epoch ) ) setTpls ( rows ? ? [ ] ) } )
. catch ( ( ) = > { if ( currentProject ( epoch ) ) setTpls ( [ ] ) } )
return ( ) = > {
requests . current . epoch ++ ; requests . current . selection ++ ; requests . current . status ++
requests . current . catalog ++ ; requests . current . action ++ ; requests . current . selected = ''
@@ -431,8 +449,39 @@ export function RdmDutiesSection({ project }: { project: Project }) {
cmd ( 'rdm.review.assign.doc.batch' , { projectId , docs : [ . . . batchSel ] . map ( d = > ( {
docId : d , author : batchAuthor [ 0 ] , reviewers : batchReviewers , approver : batchApprover [ 0 ] } ) ) } ) )
/** U4/UI:按已发布 DHF 模板整份生成文档(章节骨架自动播种),随后选中新文档。 */
const instantiate = ( ) = > {
const tpl = ( tpls ? ? [ ] ) . find ( r = > ` ${ r . templateId } @ ${ r . version } ` === tplSel )
if ( ! tpl ) return
const title = newTitle . trim ( )
return run ( ` 已按模板生成「 ${ title || tpl . title } 」 ` , async ( ) = > {
const res = await cmd < { docId : string } > ( 'rdm.docs.instantiate' , docsInstantiateParams ( tpl , title ) )
await refreshCatalog ( )
await selectDoc ( res . docId , true )
} )
}
const tpl = ( tpls ? ? [ ] ) . find ( r = > ` ${ r . templateId } @ ${ r . version } ` === tplSel )
return (
< div >
< h4 className = "settings-group-title" > 按 模 板 生 成 文 档 < / h4 >
< div className = "ad-create" >
< div className = "ad-row" >
< select className = "lg-input" aria-label = "文档模板" value = { tplSel }
onChange = { e = > { setTplSel ( e . target . value ) ; setNewTitle ( '' ) } } >
< option value = "" > { tpls === null ? '模板加载中…' : '选择模板…' } < / option >
{ ( tpls ? ? [ ] ) . map ( r = > (
< option key = { ` ${ r . templateId } @ ${ r . version } ` } value = { ` ${ r . templateId } @ ${ r . version } ` } >
{ r . title } ( { r . templateId } @ { r . version } )
< / option >
) ) }
< / select >
< input className = "lg-input" aria-label = "文档标题" placeholder = { ` 文档标题(默认: ${ tpl ? . title ? ? '模板标题' } ) ` }
value = { newTitle } onChange = { e = > setNewTitle ( e . target . value ) } / >
< button className = "lg-submit ad-create-btn" disabled = { busy || ! tpl } onClick = { instantiate } > 生 成 文 档 < / button >
< / div >
< p className = "ad-hint" > 按 已 发 布 DHF 模 板 整 份 生 成 : 章 节 骨 架 自 动 播 种 ; 生 成 后 在 下 方 清 单 选 中 文 档 分 配 三 权 并 走 整 文 审 签 。 < / p >
< / div >
< h4 className = "settings-group-title" > 文 档 清 单 ( 职 责 分 配 对 象 为 整 份 文 档 ; 搜 索 / 浏 览 同 一 目 录 ) < / h4 >
< table className = "ad-table" >
< thead > < tr > < th > < / th > < th > 文 档 < / th > < th > 类 型 / 阶 段 < / th > < th > 当 前 职 责 < / th > < th > 状 态 < / th > < th > < / th > < / tr > < / thead >