Compare commits
2 Commits
4734c809d7
...
b66fec5075
| Author | SHA1 | Date |
|---|---|---|
|
|
b66fec5075 | |
|
|
55060cd5b7 |
|
|
@ -16,6 +16,9 @@ interface ReleaseDetailPageProps {
|
||||||
params: Promise<{
|
params: Promise<{
|
||||||
id: string;
|
id: string;
|
||||||
}>;
|
}>;
|
||||||
|
searchParams: Promise<{
|
||||||
|
tab?: string;
|
||||||
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const typeColors: Record<string, string> = {
|
const typeColors: Record<string, string> = {
|
||||||
|
|
@ -40,10 +43,12 @@ function getStatusColor(status: string) {
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic';
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
export default async function ReleaseDetailPage({ params }: ReleaseDetailPageProps) {
|
export default async function ReleaseDetailPage({ params, searchParams }: ReleaseDetailPageProps) {
|
||||||
const { id } = await params;
|
const { id } = await params;
|
||||||
|
const { tab } = await searchParams;
|
||||||
const releaseId = parseInt(id);
|
const releaseId = parseInt(id);
|
||||||
const release = await getReleaseById(releaseId);
|
const release = await getReleaseById(releaseId);
|
||||||
|
const activeTab = tab === 'verify' ? 'verify' : 'deploy';
|
||||||
|
|
||||||
if (!release) {
|
if (!release) {
|
||||||
notFound();
|
notFound();
|
||||||
|
|
@ -186,13 +191,17 @@ export default async function ReleaseDetailPage({ params }: ReleaseDetailPagePro
|
||||||
|
|
||||||
{/* Matrix View (for active) */}
|
{/* Matrix View (for active) */}
|
||||||
{release.status === 'active' && (
|
{release.status === 'active' && (
|
||||||
<Tabs defaultValue="deploy">
|
<Tabs defaultValue={activeTab}>
|
||||||
<TabsList>
|
<TabsList>
|
||||||
<TabsTrigger value="deploy">
|
<TabsTrigger value="deploy" asChild>
|
||||||
|
<Link href={`/releases/${releaseId}?tab=deploy`}>
|
||||||
Deploy ({stats.done + stats.skipped}/{stats.total})
|
Deploy ({stats.done + stats.skipped}/{stats.total})
|
||||||
|
</Link>
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="verify">
|
<TabsTrigger value="verify" asChild>
|
||||||
|
<Link href={`/releases/${releaseId}?tab=verify`}>
|
||||||
Verify
|
Verify
|
||||||
|
</Link>
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,9 @@ export function ReleaseMatrixClient({ stepsByCluster, category, releaseId }: Rel
|
||||||
const handleActionComplete = () => {
|
const handleActionComplete = () => {
|
||||||
setRefreshKey(prev => prev + 1);
|
setRefreshKey(prev => prev + 1);
|
||||||
setIsPanelOpen(false);
|
setIsPanelOpen(false);
|
||||||
// Refresh the page to get updated data
|
// Refresh the page to get updated data, preserving the current tab
|
||||||
window.location.reload();
|
const currentUrl = new URL(window.location.href);
|
||||||
|
window.location.href = currentUrl.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Server actions wrapped in async functions
|
// Server actions wrapped in async functions
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,42 @@ import {
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from '@/components/ui/dialog';
|
} from '@/components/ui/dialog';
|
||||||
|
|
||||||
|
// Copy button with subtle feedback
|
||||||
|
function CopyButton({ text }: { text: string }) {
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
|
||||||
|
const handleCopy = async () => {
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 1500);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
onClick={handleCopy}
|
||||||
|
className={`h-7 px-2 transition-colors duration-200 ${
|
||||||
|
copied
|
||||||
|
? 'text-green-600 bg-green-50 hover:bg-green-100 hover:text-green-700'
|
||||||
|
: 'text-slate-500 hover:text-slate-700'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{copied ? (
|
||||||
|
<>
|
||||||
|
<Check className="w-3.5 h-3.5 mr-1" />
|
||||||
|
Copied
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Copy className="w-3.5 h-3.5 mr-1" />
|
||||||
|
Copy
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
interface StepDetailPanelProps {
|
interface StepDetailPanelProps {
|
||||||
step: any;
|
step: any;
|
||||||
template: any;
|
template: any;
|
||||||
|
|
@ -223,15 +259,7 @@ export function StepDetailPanel({
|
||||||
<div className="flex items-center justify-between mb-2">
|
<div className="flex items-center justify-between mb-2">
|
||||||
<label className="text-sm font-medium text-slate-500">Content</label>
|
<label className="text-sm font-medium text-slate-500">Content</label>
|
||||||
{!isEditing && (
|
{!isEditing && (
|
||||||
<Button
|
<CopyButton text={step.content} />
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => navigator.clipboard.writeText(step.content)}
|
|
||||||
className="h-7 px-2 text-slate-500 hover:text-slate-700"
|
|
||||||
>
|
|
||||||
<Copy className="w-3.5 h-3.5 mr-1" />
|
|
||||||
Copy
|
|
||||||
</Button>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue