feat(版本): 优化概览与只读状态
关键改动: - 增加需求排序和版本只读状态规则及测试 - 完善版本概览阶段耗时、项目页和工作台展示 - 优化小宝预警请求节流、建议状态和风险过滤 Co-Authored-By: Codex GPT-5 <codex@openai.com>
This commit is contained in:
@@ -19,9 +19,10 @@ interface Props {
|
||||
onUnlink: (reqId: string) => void;
|
||||
onCreateChange: (data: Partial<Requirement>) => void;
|
||||
currentUserName: string;
|
||||
readOnly?: boolean;
|
||||
}
|
||||
|
||||
export function VersionRequirementsTab({ versionId, projectId, requirements, devTasks, versionMembers, onLink, onUnlink, onCreateChange, currentUserName }: Props) {
|
||||
export function VersionRequirementsTab({ versionId, projectId, requirements, devTasks, versionMembers, onLink, onUnlink, onCreateChange, currentUserName, readOnly = false }: Props) {
|
||||
const [showAddModal, setShowAddModal] = useState(false);
|
||||
const [showChangeModal, setShowChangeModal] = useState(false);
|
||||
const linkedReqs = requirements.filter((r) => r.versionId === versionId);
|
||||
@@ -31,16 +32,18 @@ export function VersionRequirementsTab({ versionId, projectId, requirements, dev
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-[12px] text-[var(--ink-muted)]">{linkedReqs.length} 条关联需求</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => setShowChangeModal(true)} className="flex h-8 items-center gap-1.5 rounded-lg border border-orange-300 px-3 text-[13px] font-medium text-orange-600 hover:bg-orange-50 transition-colors">
|
||||
<Plus className="h-3.5 w-3.5" strokeWidth={2} />
|
||||
需求变更
|
||||
</button>
|
||||
<button onClick={() => setShowAddModal(true)} className="flex h-8 items-center gap-1.5 rounded-lg bg-[var(--accent)] px-3 text-[13px] font-medium text-white shadow-[var(--shadow-sm)] hover:bg-[var(--accent-hover)] transition-colors">
|
||||
<Plus className="h-3.5 w-3.5" strokeWidth={2} />
|
||||
添加需求
|
||||
</button>
|
||||
</div>
|
||||
{!readOnly && (
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => setShowChangeModal(true)} className="flex h-8 items-center gap-1.5 rounded-lg border border-orange-300 px-3 text-[13px] font-medium text-orange-600 hover:bg-orange-50 transition-colors">
|
||||
<Plus className="h-3.5 w-3.5" strokeWidth={2} />
|
||||
需求变更
|
||||
</button>
|
||||
<button onClick={() => setShowAddModal(true)} className="flex h-8 items-center gap-1.5 rounded-lg bg-[var(--accent)] px-3 text-[13px] font-medium text-white shadow-[var(--shadow-sm)] hover:bg-[var(--accent-hover)] transition-colors">
|
||||
<Plus className="h-3.5 w-3.5" strokeWidth={2} />
|
||||
添加需求
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{linkedReqs.length === 0 ? (
|
||||
@@ -61,7 +64,7 @@ export function VersionRequirementsTab({ versionId, projectId, requirements, dev
|
||||
<th className="px-4 py-2.5 text-[11px] font-medium uppercase tracking-wide text-[var(--ink-muted)]">开发状态</th>
|
||||
<th className="px-4 py-2.5 text-[11px] font-medium uppercase tracking-wide text-[var(--ink-muted)]">添加人</th>
|
||||
<th className="px-4 py-2.5 text-[11px] font-medium uppercase tracking-wide text-[var(--ink-muted)]">添加日期</th>
|
||||
<th className="px-4 py-2.5 text-[11px] font-medium uppercase tracking-wide text-[var(--ink-muted)] text-right">操作</th>
|
||||
{!readOnly && <th className="px-4 py-2.5 text-[11px] font-medium uppercase tracking-wide text-[var(--ink-muted)] text-right">操作</th>}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -95,13 +98,15 @@ export function VersionRequirementsTab({ versionId, projectId, requirements, dev
|
||||
</td>
|
||||
<td className="px-4 py-3 text-[12px] text-[var(--ink-soft)]">{req.addedToVersionBy || '系统添加'}</td>
|
||||
<td className="px-4 py-3 text-[12px] text-[var(--ink-soft)]">{req.createdAt?.slice(0, 10) || '-'}</td>
|
||||
<td className="px-4 py-3 text-right">
|
||||
{isDeveloping ? (
|
||||
<span className="text-[11px] text-[var(--ink-muted)]">开发中</span>
|
||||
) : (
|
||||
<button onClick={() => onUnlink(req.id)} className="h-6 px-2 rounded text-[11px] font-medium text-red-500 hover:bg-red-50 transition-colors">移除</button>
|
||||
)}
|
||||
</td>
|
||||
{!readOnly && (
|
||||
<td className="px-4 py-3 text-right">
|
||||
{isDeveloping ? (
|
||||
<span className="text-[11px] text-[var(--ink-muted)]">开发中</span>
|
||||
) : (
|
||||
<button onClick={() => onUnlink(req.id)} className="h-6 px-2 rounded text-[11px] font-medium text-red-500 hover:bg-red-50 transition-colors">移除</button>
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
@@ -110,7 +115,7 @@ export function VersionRequirementsTab({ versionId, projectId, requirements, dev
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showAddModal && (
|
||||
{showAddModal && !readOnly && (
|
||||
<AddRequirementModal
|
||||
available={availableReqs}
|
||||
onClose={() => setShowAddModal(false)}
|
||||
@@ -118,7 +123,7 @@ export function VersionRequirementsTab({ versionId, projectId, requirements, dev
|
||||
/>
|
||||
)}
|
||||
|
||||
{showChangeModal && (
|
||||
{showChangeModal && !readOnly && (
|
||||
<ChangeRequirementModal
|
||||
versionMembers={versionMembers}
|
||||
currentUserName={currentUserName}
|
||||
|
||||
Reference in New Issue
Block a user