refactor(campaigns): move CampaignTimingPanel next to Progress panel
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Progress and Timing now share a 2-column grid at the top of the detail page. Removed CampaignTimingPanel from the bottom Jira section. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -309,44 +309,50 @@ export default function CampaignDetailPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Progress Panel */}
|
{/* Progress + Timing side by side */}
|
||||||
<div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
|
<div className="grid gap-6 lg:grid-cols-2">
|
||||||
<h2 className="mb-4 text-lg font-semibold text-white">Progress</h2>
|
{/* Progress Panel */}
|
||||||
<div className="flex items-center gap-6 mb-4">
|
<div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
|
||||||
<div>
|
<h2 className="mb-4 text-lg font-semibold text-white">Progress</h2>
|
||||||
<span className="text-3xl font-bold text-white">{progress.completion_pct}%</span>
|
<div className="flex items-center gap-6 mb-4">
|
||||||
<span className="ml-1 text-sm text-gray-400">complete</span>
|
<div>
|
||||||
</div>
|
<span className="text-3xl font-bold text-white">{progress.completion_pct}%</span>
|
||||||
<div className="flex-1">
|
<span className="ml-1 text-sm text-gray-400">complete</span>
|
||||||
<div className="h-3 w-full rounded-full bg-gray-800 overflow-hidden">
|
|
||||||
<div
|
|
||||||
className={`h-full rounded-full transition-all ${
|
|
||||||
progress.completion_pct === 100 ? "bg-green-500" : "bg-cyan-500"
|
|
||||||
}`}
|
|
||||||
style={{ width: `${progress.completion_pct}%` }}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="h-3 w-full rounded-full bg-gray-800 overflow-hidden">
|
||||||
|
<div
|
||||||
|
className={`h-full rounded-full transition-all ${
|
||||||
|
progress.completion_pct === 100 ? "bg-green-500" : "bg-cyan-500"
|
||||||
|
}`}
|
||||||
|
style={{ width: `${progress.completion_pct}%` }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span className="text-sm text-gray-400">
|
||||||
|
{progress.by_state?.validated || 0} / {progress.total} tests
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-400">
|
|
||||||
{progress.by_state?.validated || 0} / {progress.total} tests
|
{/* State breakdown */}
|
||||||
</span>
|
{progress.total > 0 && (
|
||||||
|
<div className="flex flex-wrap gap-3">
|
||||||
|
{Object.entries(progress.by_state || {}).map(([state, count]) => (
|
||||||
|
<div
|
||||||
|
key={state}
|
||||||
|
className={`rounded-lg border px-3 py-1.5 text-xs font-medium ${
|
||||||
|
testStateColors[state] || testStateColors.draft
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{state.replace(/_/g, " ")}: {count}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* State breakdown */}
|
{/* Campaign Timing */}
|
||||||
{progress.total > 0 && (
|
<CampaignTimingPanel campaignId={campaignId!} />
|
||||||
<div className="flex flex-wrap gap-3">
|
|
||||||
{Object.entries(progress.by_state || {}).map(([state, count]) => (
|
|
||||||
<div
|
|
||||||
key={state}
|
|
||||||
className={`rounded-lg border px-3 py-1.5 text-xs font-medium ${
|
|
||||||
testStateColors[state] || testStateColors.draft
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{state.replace(/_/g, " ")}: {count}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Kill Chain Timeline */}
|
{/* Kill Chain Timeline */}
|
||||||
@@ -630,11 +636,8 @@ export default function CampaignDetailPage() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Jira + Campaign Timing */}
|
{/* Jira */}
|
||||||
<div className="grid gap-6 lg:grid-cols-2">
|
<JiraLinkPanel entityType="campaign" entityId={campaignId!} readOnly label={campaign.name} />
|
||||||
<JiraLinkPanel entityType="campaign" entityId={campaignId!} readOnly label={campaign.name} />
|
|
||||||
<CampaignTimingPanel campaignId={campaignId!} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Add Test to Campaign Modal */}
|
{/* Add Test to Campaign Modal */}
|
||||||
<AddTestToCampaignModal
|
<AddTestToCampaignModal
|
||||||
|
|||||||
Reference in New Issue
Block a user