✨ feat(vscode): webview 移交/接管按钮、选人弹窗与待接管角标
Claude-Session: https://claude.ai/code/session_011cEyL6k351U2BzX1Qmygph
This commit is contained in:
1 parent
6d3720d424
commit
6770570f09
6 files changed
+226
-3
No files matched your search
@@ -283,6 +283,18 @@ export interface UseIssuesResult {
|
||||
*/
|
||||
pendingSelectId: string | null
|
||||
clearPendingSelect: () => void
|
||||
/** 当前 Gitea login,来自最近一次 `issues/update`;undefined = 身份未知。 */
|
||||
me: string | undefined
|
||||
/** 最近一次 `requestHandoffUsers` 的结果;`null` = 仍在加载或尚未请求。 */
|
||||
handoffUsers: { issueNumber: number, users: string[] } | null
|
||||
/** 拉取某工单可移交的候选用户列表,结果通过 `handoffUsers` 返回。 */
|
||||
requestHandoffUsers: (issueNumber: number) => void
|
||||
/** 发起移交:删本机 worktree、打包会话记录挂到附件、把工单指派给对方。 */
|
||||
startHandoff: (issueNumber: number, to: string) => void
|
||||
/** 接管一个待接管工单:拉取移交附件、恢复会话与 worktree。 */
|
||||
acceptHandoff: (issueNumber: number) => void
|
||||
/** 是否有移交/接管流程正在该工单上跑,直到扩展端回 `handoff/done` 才清除。 */
|
||||
isHandoffRunning: (issueNumber: number) => boolean
|
||||
}
|
||||
|
||||
export function useIssues(): UseIssuesResult {
|
||||
@@ -308,6 +320,10 @@ export function useIssues(): UseIssuesResult {
|
||||
const [envLockTitle, setEnvLockTitle] = useState<string>('正在检查 .env 锁定状态…')
|
||||
const prDiffSummaryRunningRef = useRef<Set<number>>(new Set())
|
||||
const [prDiffSummaryRunning, setPrDiffSummaryRunning] = useState<ReadonlySet<number>>(() => new Set())
|
||||
const [me, setMe] = useState<string | undefined>(undefined)
|
||||
const [handoffUsers, setHandoffUsers] = useState<{ issueNumber: number, users: string[] } | null>(null)
|
||||
const handoffRunningRef = useRef<Set<number>>(new Set())
|
||||
const [handoffRunning, setHandoffRunning] = useState<Set<number>>(new Set())
|
||||
|
||||
const clearPrDiffSummaryRunning = useCallback((issueNumber: number): void => {
|
||||
if (!prDiffSummaryRunningRef.current.delete(issueNumber))
|
||||
@@ -454,6 +470,35 @@ export function useIssues(): UseIssuesResult {
|
||||
return prDiffSummaryRunning.has(issueNumber)
|
||||
}, [prDiffSummaryRunning])
|
||||
|
||||
const requestHandoffUsers = useCallback((issueNumber: number): void => {
|
||||
setHandoffUsers(null)
|
||||
postMessage({ type: 'handoff/users', issueNumber })
|
||||
}, [])
|
||||
|
||||
const markHandoffRunning = useCallback((issueNumber: number, running: boolean): void => {
|
||||
if (running)
|
||||
handoffRunningRef.current.add(issueNumber)
|
||||
else
|
||||
handoffRunningRef.current.delete(issueNumber)
|
||||
setHandoffRunning(new Set(handoffRunningRef.current))
|
||||
}, [])
|
||||
|
||||
const startHandoff = useCallback((issueNumber: number, to: string): void => {
|
||||
if (handoffRunningRef.current.has(issueNumber))
|
||||
return
|
||||
markHandoffRunning(issueNumber, true)
|
||||
postMessage({ type: 'handoff/start', issueNumber, to })
|
||||
}, [markHandoffRunning])
|
||||
|
||||
const acceptHandoff = useCallback((issueNumber: number): void => {
|
||||
if (handoffRunningRef.current.has(issueNumber))
|
||||
return
|
||||
markHandoffRunning(issueNumber, true)
|
||||
postMessage({ type: 'handoff/accept', issueNumber })
|
||||
}, [markHandoffRunning])
|
||||
|
||||
const isHandoffRunning = useCallback((issueNumber: number): boolean => handoffRunning.has(issueNumber), [handoffRunning])
|
||||
|
||||
const openPr = useCallback((pr: string): void => {
|
||||
postMessage({ type: 'pr/open', pr })
|
||||
}, [])
|
||||
@@ -615,6 +660,7 @@ export function useIssues(): UseIssuesResult {
|
||||
setScope(msg.scope)
|
||||
setGlobalAutoReview(msg.globalAutoReview)
|
||||
setYoutrackConfigured(msg.youtrackConfigured)
|
||||
setMe(msg.me)
|
||||
break
|
||||
case 'issues/error':
|
||||
setState({ status: 'error', message: msg.message })
|
||||
@@ -636,6 +682,12 @@ export function useIssues(): UseIssuesResult {
|
||||
case 'issue/pr-diff-summary-done':
|
||||
clearPrDiffSummaryRunning(msg.issueNumber)
|
||||
break
|
||||
case 'handoff/users-result':
|
||||
setHandoffUsers({ issueNumber: msg.issueNumber, users: msg.users })
|
||||
break
|
||||
case 'handoff/done':
|
||||
markHandoffRunning(msg.issueNumber, false)
|
||||
break
|
||||
case 'issue/remove':
|
||||
// 工单被删除或关闭 — 从 open issues 数组移除。如果它是当前选中的,挑下一张
|
||||
// 同列的卡片(按该列排序取首张近邻:完成列按合并时间,其余按 number 降序);同列没有则交给 App.tsx 的
|
||||
@@ -815,7 +867,7 @@ export function useIssues(): UseIssuesResult {
|
||||
postMessage({ type: 'branch-sync/check' })
|
||||
postMessage({ type: 'env-lock/check' })
|
||||
return cleanup
|
||||
}, [clearPrDiffSummaryRunning])
|
||||
}, [clearPrDiffSummaryRunning, markHandoffRunning])
|
||||
|
||||
return { state, settings, globalAutoReview, youtrackConfigured, importYouTrack, toasts, profiles, setIssues, refresh, scope, toggleScope, saveSettings, listYouTrackProjects, youtrackProjects, dismissSettings, requestEditAuth, createIssue, dismissToast, openUrl, resumeSession, resumeReviewSession, startTestSession, resumeTestSession, focusSession, openFile, implement, generatePrDiffSummary, isPrDiffSummaryRunning, openPr, openWorktree, deleteWorktree, mergeBranch, deleteIssue, closeIssue, closeSessionTab, startBrainstormSession, changeColumn, setDependency, clearDependency, updateIssueAutoReview, updateIssueProfilePath, updateIssueBrainstormProfilePath, updateIssueTestProfilePath, logs, fetchLogs, clearLogs, pendingSelectId, clearPendingSelect, commitRunning, runCommit, hasChanges, branchSyncBehind, branchSyncRunning, branchSyncDisabled, branchSyncTitle, runBranchSync, envLocked, envFileCount, envLockRunning, envLockTitle, toggleEnvLock }
|
||||
return { state, settings, globalAutoReview, youtrackConfigured, importYouTrack, toasts, profiles, setIssues, refresh, scope, toggleScope, saveSettings, listYouTrackProjects, youtrackProjects, dismissSettings, requestEditAuth, createIssue, dismissToast, openUrl, resumeSession, resumeReviewSession, startTestSession, resumeTestSession, focusSession, openFile, implement, generatePrDiffSummary, isPrDiffSummaryRunning, openPr, openWorktree, deleteWorktree, mergeBranch, deleteIssue, closeIssue, closeSessionTab, startBrainstormSession, changeColumn, setDependency, clearDependency, updateIssueAutoReview, updateIssueProfilePath, updateIssueBrainstormProfilePath, updateIssueTestProfilePath, logs, fetchLogs, clearLogs, pendingSelectId, clearPendingSelect, commitRunning, runCommit, hasChanges, branchSyncBehind, branchSyncRunning, branchSyncDisabled, branchSyncTitle, runBranchSync, envLocked, envFileCount, envLockRunning, envLockTitle, toggleEnvLock, me, handoffUsers, requestHandoffUsers, startHandoff, acceptHandoff, isHandoffRunning }
|
||||
}
|
||||
Reference in new issue
Block a user