🐛 fix(vscode): 详情属性格 data 引用变化不再清掉选中导致 PR 打不开
This commit is contained in:
@@ -491,7 +491,37 @@ export function IssueDetailPanel({
|
|||||||
[onResumeSession, onResumeReviewSession, onResumeTestSession, onStartTestSession, onOpenFile, onImplement, onOpenPr, onGeneratePrDiffSummary, onOpenWorktree, onDeleteWorktree, onMergeBranch, onCloseSessionTab, onStartBrainstormSession, onOpenLogs, issue, locked, lockTitle, globalAutoReview, prDiffSummaryRunning, profiles],
|
[onResumeSession, onResumeReviewSession, onResumeTestSession, onStartTestSession, onOpenFile, onImplement, onOpenPr, onGeneratePrDiffSummary, onOpenWorktree, onDeleteWorktree, onMergeBranch, onCloseSessionTab, onStartBrainstormSession, onOpenLogs, issue, locked, lockTitle, globalAutoReview, prDiffSummaryRunning, profiles],
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!issue) {
|
const data = useMemo<Record<string, unknown> | null>(() => {
|
||||||
|
if (!issue)
|
||||||
|
return null
|
||||||
|
return {
|
||||||
|
column: issue.column,
|
||||||
|
sessionId: issue.sessionId ?? null,
|
||||||
|
implementSessionId: issue.implementSessionId ?? null,
|
||||||
|
reviewSessionId: issue.reviewSessionId ?? null,
|
||||||
|
testSessionId: issue.testSessionId ?? null,
|
||||||
|
autoReview: issue.autoReview ?? globalAutoReview,
|
||||||
|
color: issue.color ?? null,
|
||||||
|
// 展示/选中值按 basename 映射到本机 profiles,避免跨机绝对路径变成「自定义」项。
|
||||||
|
brainstormProfilePath: matchProfileOption(issue.brainstormProfilePath, profiles) || null,
|
||||||
|
profilePath: matchProfileOption(issue.profilePath, profiles) || null,
|
||||||
|
testProfilePath: matchProfileOption(issue.testProfilePath, profiles) || null,
|
||||||
|
specFile: issue.specFile ?? null,
|
||||||
|
planFile: issue.planFile ?? null,
|
||||||
|
prDiffFile: issue.prDiffFile ?? null,
|
||||||
|
pr: issue.pr
|
||||||
|
? `${issue.pr}${issue.prMerged ? '(已合并)' : ''}`
|
||||||
|
: null,
|
||||||
|
branch: issue.branch ?? null,
|
||||||
|
worktreePath: issue.worktreePath ?? null,
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
issue,
|
||||||
|
globalAutoReview,
|
||||||
|
profiles,
|
||||||
|
])
|
||||||
|
|
||||||
|
if (!issue || !data) {
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full items-center justify-center border-t border-[var(--vscode-panel-border)] p-3 text-xs opacity-60">
|
<div className="flex h-full items-center justify-center border-t border-[var(--vscode-panel-border)] p-3 text-xs opacity-60">
|
||||||
按方向键或点击卡片查看详情
|
按方向键或点击卡片查看详情
|
||||||
@@ -499,28 +529,6 @@ export function IssueDetailPanel({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const data: Record<string, unknown> = {
|
|
||||||
column: issue.column,
|
|
||||||
sessionId: issue.sessionId ?? null,
|
|
||||||
implementSessionId: issue.implementSessionId ?? null,
|
|
||||||
reviewSessionId: issue.reviewSessionId ?? null,
|
|
||||||
testSessionId: issue.testSessionId ?? null,
|
|
||||||
autoReview: issue.autoReview ?? globalAutoReview,
|
|
||||||
color: issue.color ?? null,
|
|
||||||
// 展示/选中值按 basename 映射到本机 profiles,避免跨机绝对路径变成「自定义」项。
|
|
||||||
brainstormProfilePath: matchProfileOption(issue.brainstormProfilePath, profiles) || null,
|
|
||||||
profilePath: matchProfileOption(issue.profilePath, profiles) || null,
|
|
||||||
testProfilePath: matchProfileOption(issue.testProfilePath, profiles) || null,
|
|
||||||
specFile: issue.specFile ?? null,
|
|
||||||
planFile: issue.planFile ?? null,
|
|
||||||
prDiffFile: issue.prDiffFile ?? null,
|
|
||||||
pr: issue.pr
|
|
||||||
? `${issue.pr}${issue.prMerged ? '(已合并)' : ''}`
|
|
||||||
: null,
|
|
||||||
branch: issue.branch ?? null,
|
|
||||||
worktreePath: issue.worktreePath ?? null,
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full min-h-0 flex-col gap-3 border-t border-[var(--vscode-panel-border)] p-3">
|
<div className="flex h-full min-h-0 flex-col gap-3 border-t border-[var(--vscode-panel-border)] p-3">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
@@ -608,6 +616,7 @@ export function IssueDetailPanel({
|
|||||||
|
|
||||||
<div className="min-h-0 flex-1">
|
<div className="min-h-0 flex-1">
|
||||||
<PropertyGrid
|
<PropertyGrid
|
||||||
|
key={issue.number}
|
||||||
schema={schema}
|
schema={schema}
|
||||||
data={data}
|
data={data}
|
||||||
hideToolbar
|
hideToolbar
|
||||||
|
|||||||
@@ -503,11 +503,15 @@ function PropertyRow({
|
|||||||
ref={el => registerCellRef(fullKey, el)}
|
ref={el => registerCellRef(fullKey, el)}
|
||||||
data-property-cell={fullKey}
|
data-property-cell={fullKey}
|
||||||
onClickCapture={(e) => {
|
onClickCapture={(e) => {
|
||||||
if (!isSelected) {
|
if (isSelected)
|
||||||
e.stopPropagation()
|
return
|
||||||
e.preventDefault()
|
onSelect(fullKey)
|
||||||
onSelect(fullKey)
|
// 点在 action/file-link/pr-link 按钮上:只选中,不拦截,让 click 落到 primary
|
||||||
}
|
const t = e.target
|
||||||
|
if (t instanceof Element && t.closest('[data-property-action]'))
|
||||||
|
return
|
||||||
|
e.stopPropagation()
|
||||||
|
e.preventDefault()
|
||||||
}}
|
}}
|
||||||
className={`flex min-w-0 flex-1 ${
|
className={`flex min-w-0 flex-1 ${
|
||||||
propDef.type === 'multiline' ? 'items-stretch' : 'items-center'
|
propDef.type === 'multiline' ? 'items-stretch' : 'items-center'
|
||||||
@@ -568,12 +572,8 @@ export function PropertyGrid({
|
|||||||
const rootRef = useRef<HTMLDivElement | null>(null)
|
const rootRef = useRef<HTMLDivElement | null>(null)
|
||||||
const cellRefsRef = useRef<Map<string, HTMLDivElement>>(new Map())
|
const cellRefsRef = useRef<Map<string, HTMLDivElement>>(new Map())
|
||||||
|
|
||||||
/** 切换到新 data 时清空选中 */
|
|
||||||
useEffect(() => {
|
|
||||||
setSelectedKey(null)
|
|
||||||
}, [data])
|
|
||||||
|
|
||||||
/** 点击网格外部时清空选中 */
|
/** 点击网格外部时清空选中 */
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedKey == null)
|
if (selectedKey == null)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user