fix: 侧边详情显示产品/项目/版本上下文
所有 Drawer 新增 contextLabel 可选属性: - 从工作台打开时传入"产品 / 项目 / 版本"路径 - 显示在 Drawer 顶部灰色背景条中 - 从版本详情打开时不传,不显示(无需冗余) - 统一样式:px-5 py-2 bg-[var(--bg-subtle)] text-[11px] 涉及组件: - PlanDetailDrawer - DevTaskDetailDrawer - TestCaseDetailDrawer - BugDetailDrawer Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -222,16 +222,16 @@ export default function WorkspacePage() {
|
||||
|
||||
{/* Detail Drawers */}
|
||||
{drawerItem && (drawerItem.type === 'plan_research' || drawerItem.type === 'plan_product' || drawerItem.type === 'plan_ui') && (
|
||||
<PlanDetailDrawer planId={drawerItem.id} onClose={() => setDrawerItem(null)} />
|
||||
<PlanDetailDrawer planId={drawerItem.id} onClose={() => setDrawerItem(null)} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
|
||||
)}
|
||||
{drawerItem && drawerItem.type === 'devTask' && (
|
||||
<DevTaskDetailDrawer taskId={drawerItem.id} allTaskIds={devTasks.map((t) => t.id)} onClose={() => setDrawerItem(null)} />
|
||||
<DevTaskDetailDrawer taskId={drawerItem.id} allTaskIds={devTasks.map((t) => t.id)} onClose={() => setDrawerItem(null)} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
|
||||
)}
|
||||
{drawerItem && drawerItem.type === 'testCase' && (
|
||||
<TestCaseDetailDrawer testCaseId={drawerItem.id} onClose={() => setDrawerItem(null)} onCreateBug={(tcId) => { setDrawerItem(null); setBugFromTestCaseId(tcId); }} />
|
||||
<TestCaseDetailDrawer testCaseId={drawerItem.id} onClose={() => setDrawerItem(null)} onCreateBug={(tcId) => { setDrawerItem(null); setBugFromTestCaseId(tcId); }} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
|
||||
)}
|
||||
{drawerItem && drawerItem.type === 'bug' && (
|
||||
<BugDetailDrawer bugId={drawerItem.id} onClose={() => setDrawerItem(null)} />
|
||||
<BugDetailDrawer bugId={drawerItem.id} onClose={() => setDrawerItem(null)} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
|
||||
)}
|
||||
{bugFromTestCaseId && (
|
||||
<BugCreateModal testCaseId={bugFromTestCaseId} onClose={() => setBugFromTestCaseId(null)} />
|
||||
|
||||
@@ -21,9 +21,10 @@ const LOG_ACTION_LABEL: Record<string, string> = {
|
||||
interface Props {
|
||||
bugId: string;
|
||||
onClose: () => void;
|
||||
contextLabel?: string;
|
||||
}
|
||||
|
||||
export function BugDetailDrawer({ bugId, onClose }: Props) {
|
||||
export function BugDetailDrawer({ bugId, onClose, contextLabel }: Props) {
|
||||
const { bugs, changeStatus, transferBug } = useBugStore();
|
||||
const { testCases } = useTestCaseStore();
|
||||
const { requirements } = useRequirementStore();
|
||||
@@ -66,6 +67,11 @@ export function BugDetailDrawer({ bugId, onClose }: Props) {
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex justify-end" onClick={onClose}>
|
||||
<div className="w-full max-w-md h-full bg-[var(--bg)] border-l border-[var(--line)] shadow-2xl flex flex-col" onClick={(e) => e.stopPropagation()}>
|
||||
{contextLabel && (
|
||||
<div className="px-5 py-2 border-b border-[var(--line)] bg-[var(--bg-subtle)] shrink-0">
|
||||
<span className="text-[11px] text-[var(--ink-muted)]">{contextLabel}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center justify-between h-14 px-5 border-b border-[var(--line)] bg-[var(--bg-card)] shrink-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-[12px] font-mono text-[var(--ink-muted)]">{bug.bugNo}</span>
|
||||
|
||||
@@ -15,9 +15,10 @@ interface Props {
|
||||
taskId: string;
|
||||
allTaskIds: string[];
|
||||
onClose: () => void;
|
||||
contextLabel?: string;
|
||||
}
|
||||
|
||||
export function DevTaskDetailDrawer({ taskId, allTaskIds, onClose }: Props) {
|
||||
export function DevTaskDetailDrawer({ taskId, allTaskIds, onClose, contextLabel }: Props) {
|
||||
const { tasks, changeStatus, setBlocked, deleteTask, updateTask } = useDevTaskStore();
|
||||
const { categories } = useTaskCategoryStore();
|
||||
const { requirements } = useRequirementStore();
|
||||
@@ -56,6 +57,12 @@ export function DevTaskDetailDrawer({ taskId, allTaskIds, onClose }: Props) {
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex justify-end" onClick={onClose}>
|
||||
<div className="w-full max-w-md h-full bg-[var(--bg)] border-l border-[var(--line)] shadow-2xl flex flex-col" onClick={(e) => e.stopPropagation()}>
|
||||
{/* 上下文 */}
|
||||
{contextLabel && (
|
||||
<div className="px-5 py-2 border-b border-[var(--line)] bg-[var(--bg-subtle)] shrink-0">
|
||||
<span className="text-[11px] text-[var(--ink-muted)]">{contextLabel}</span>
|
||||
</div>
|
||||
)}
|
||||
{/* 顶栏 */}
|
||||
<div className="flex items-center justify-between h-14 px-5 border-b border-[var(--line)] bg-[var(--bg-card)] shrink-0">
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
@@ -17,9 +17,10 @@ interface Props {
|
||||
testCaseId: string;
|
||||
onClose: () => void;
|
||||
onCreateBug?: (testCaseId: string) => void;
|
||||
contextLabel?: string;
|
||||
}
|
||||
|
||||
export function TestCaseDetailDrawer({ testCaseId, onClose, onCreateBug }: Props) {
|
||||
export function TestCaseDetailDrawer({ testCaseId, onClose, onCreateBug, contextLabel }: Props) {
|
||||
const { testCases, changeStatus, deleteTestCase, updateTestCase } = useTestCaseStore();
|
||||
const { bugs } = useBugStore();
|
||||
const { requirements } = useRequirementStore();
|
||||
@@ -60,6 +61,11 @@ export function TestCaseDetailDrawer({ testCaseId, onClose, onCreateBug }: Props
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex justify-end" onClick={onClose}>
|
||||
<div className="w-full max-w-md h-full bg-[var(--bg)] border-l border-[var(--line)] shadow-2xl flex flex-col" onClick={(e) => e.stopPropagation()}>
|
||||
{contextLabel && (
|
||||
<div className="px-5 py-2 border-b border-[var(--line)] bg-[var(--bg-subtle)] shrink-0">
|
||||
<span className="text-[11px] text-[var(--ink-muted)]">{contextLabel}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center justify-between h-14 px-5 border-b border-[var(--line)] bg-[var(--bg-card)] shrink-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-[12px] font-mono text-[var(--ink-muted)]">{tc.caseNo}</span>
|
||||
|
||||
@@ -11,13 +11,14 @@ import type { PlanTask, VersionPlan } from '@/lib/version-plan';
|
||||
interface Props {
|
||||
planId: string;
|
||||
onClose: () => void;
|
||||
contextLabel?: string;
|
||||
}
|
||||
|
||||
const STATUS_STYLE: Record<string, string> = { pending: 'bg-zinc-100 text-zinc-600', in_progress: 'bg-blue-50 text-blue-600', completed: 'bg-emerald-50 text-emerald-600' };
|
||||
const STATUS_LABEL: Record<string, string> = { pending: '未开始', in_progress: '进行中', completed: '已完成' };
|
||||
const TYPE_LABEL: Record<string, string> = { research: '调研', product: '产品方案', ui: 'UI设计' };
|
||||
|
||||
export function PlanDetailDrawer({ planId, onClose }: Props) {
|
||||
export function PlanDetailDrawer({ planId, onClose, contextLabel }: Props) {
|
||||
const { plans, updatePlan, completePlan } = useVersionPlanStore();
|
||||
const { requirements } = useRequirementStore();
|
||||
const { members } = useMemberStore();
|
||||
@@ -77,6 +78,12 @@ export function PlanDetailDrawer({ planId, onClose }: Props) {
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex justify-end" onClick={onClose}>
|
||||
<div className="w-full max-w-md h-full bg-[var(--bg)] border-l border-[var(--line)] shadow-2xl flex flex-col overflow-hidden" onClick={(e) => e.stopPropagation()}>
|
||||
{/* Context */}
|
||||
{contextLabel && (
|
||||
<div className="px-5 py-2 border-b border-[var(--line)] bg-[var(--bg-subtle)] shrink-0">
|
||||
<span className="text-[11px] text-[var(--ink-muted)]">{contextLabel}</span>
|
||||
</div>
|
||||
)}
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between px-5 py-4 border-b border-[var(--line)] shrink-0">
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
Reference in New Issue
Block a user