feat(ui): deploy geçmişi için scroll-area ekle
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
"@fortawesome/react-fontawesome": "^3.1.0",
|
"@fortawesome/react-fontawesome": "^3.1.0",
|
||||||
"@radix-ui/react-select": "^2.2.6",
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
|
"@radix-ui/react-scroll-area": "^1.2.5",
|
||||||
"@radix-ui/react-tabs": "^1.1.3",
|
"@radix-ui/react-tabs": "^1.1.3",
|
||||||
"axios": "^1.5.1",
|
"axios": "^1.5.1",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
|
|||||||
24
frontend/src/components/ui/scroll-area.tsx
Normal file
24
frontend/src/components/ui/scroll-area.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
||||||
|
import { cn } from "../../lib/utils";
|
||||||
|
|
||||||
|
const ScrollArea = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<ScrollAreaPrimitive.Root ref={ref} className={cn("relative overflow-hidden", className)} {...props}>
|
||||||
|
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
||||||
|
{children}
|
||||||
|
</ScrollAreaPrimitive.Viewport>
|
||||||
|
<ScrollAreaPrimitive.Scrollbar
|
||||||
|
orientation="vertical"
|
||||||
|
className="flex touch-none select-none p-0.5 transition-colors"
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.Thumb className="relative flex-1 rounded-full bg-border" />
|
||||||
|
</ScrollAreaPrimitive.Scrollbar>
|
||||||
|
<ScrollAreaPrimitive.Corner />
|
||||||
|
</ScrollAreaPrimitive.Root>
|
||||||
|
));
|
||||||
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
||||||
|
|
||||||
|
export { ScrollArea };
|
||||||
@@ -18,6 +18,7 @@ import { JobStatusBadge } from "../components/JobStatusBadge";
|
|||||||
import { Label } from "../components/ui/label";
|
import { Label } from "../components/ui/label";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../components/ui/select";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../components/ui/tabs";
|
||||||
|
import { ScrollArea } from "../components/ui/scroll-area";
|
||||||
import {
|
import {
|
||||||
DeploymentInput,
|
DeploymentInput,
|
||||||
DeploymentProject,
|
DeploymentProject,
|
||||||
@@ -422,29 +423,34 @@ export function DeploymentDetailPage() {
|
|||||||
Deploy Geçmişi
|
Deploy Geçmişi
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-3">
|
<CardContent>
|
||||||
{runs.length === 0 && (
|
{runs.length === 0 ? (
|
||||||
<div className="text-sm text-muted-foreground">Henüz deploy çalıştırılmadı.</div>
|
<div className="text-sm text-muted-foreground">Henüz deploy çalıştırılmadı.</div>
|
||||||
|
) : (
|
||||||
|
<ScrollArea className="max-h-[420px] pr-2">
|
||||||
|
<div className="space-y-3">
|
||||||
|
{runs.map((run) => (
|
||||||
|
<div
|
||||||
|
key={run._id}
|
||||||
|
className="flex flex-wrap items-center justify-between gap-3 rounded-md border border-border bg-background px-3 py-2 text-sm"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<JobStatusBadge status={run.status} />
|
||||||
|
<span className="text-muted-foreground">
|
||||||
|
{new Date(run.startedAt).toLocaleString()}
|
||||||
|
</span>
|
||||||
|
{run.message && (
|
||||||
|
<span className="truncate text-foreground/80">· {run.message}</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="text-muted-foreground">
|
||||||
|
{run.durationMs ? `${Math.round(run.durationMs / 1000)}s` : "-"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
)}
|
)}
|
||||||
{runs.map((run) => (
|
|
||||||
<div
|
|
||||||
key={run._id}
|
|
||||||
className="flex flex-wrap items-center justify-between gap-3 rounded-md border border-border bg-background px-3 py-2 text-sm"
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<JobStatusBadge status={run.status} />
|
|
||||||
<span className="text-muted-foreground">
|
|
||||||
{new Date(run.startedAt).toLocaleString()}
|
|
||||||
</span>
|
|
||||||
{run.message && (
|
|
||||||
<span className="truncate text-foreground/80">· {run.message}</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="text-muted-foreground">
|
|
||||||
{run.durationMs ? `${Math.round(run.durationMs / 1000)}s` : "-"}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user