add Jobs components
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
import { JobListItem, type JobListItemProps } from "@/components/JobListItem"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export interface JobListProps {
|
||||||
|
jobs: JobListItemProps[]
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function JobList({ jobs, className }: JobListProps) {
|
||||||
|
if (jobs.length === 0) {
|
||||||
|
return (
|
||||||
|
<div className={cn("flex flex-col gap-2", className)}>
|
||||||
|
<p className="text-sm text-muted-foreground">No running jobs.</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cn("flex flex-col gap-2", className)}>
|
||||||
|
{jobs.map((job, index) => (
|
||||||
|
<JobListItem key={index} {...job} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { Progress } from "@/components/ui/progress"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { formatTime } from "@/utils/datetime"
|
||||||
|
|
||||||
|
export interface JobListItemProps {
|
||||||
|
title: string
|
||||||
|
runningTime: string
|
||||||
|
progress: number
|
||||||
|
startTime?: string
|
||||||
|
eta?: string
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function JobListItem({ title, runningTime, progress, startTime, eta, className }: JobListItemProps) {
|
||||||
|
return (
|
||||||
|
<div className={cn("flex flex-col gap-2 rounded-lg border p-3", className)}>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<span className="text-sm font-medium">{title}</span>
|
||||||
|
<span className="text-xs text-muted-foreground tabular-nums">{runningTime}</span>
|
||||||
|
</div>
|
||||||
|
<Progress value={progress} />
|
||||||
|
{(startTime || eta) && (
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<span className="text-xs text-muted-foreground tabular-nums">{startTime ? formatTime(startTime) : ""} started</span>
|
||||||
|
<span className="text-xs text-muted-foreground tabular-nums">{eta ? `ETA ${formatTime(eta)}` : ""}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
function Label({ className, ...props }: React.ComponentProps<"label">) {
|
||||||
|
return (
|
||||||
|
<label
|
||||||
|
data-slot="label"
|
||||||
|
className={cn(
|
||||||
|
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Label }
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
import { Progress as ProgressPrimitive } from "@base-ui/react/progress"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
function Progress({
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
value,
|
||||||
|
...props
|
||||||
|
}: ProgressPrimitive.Root.Props) {
|
||||||
|
return (
|
||||||
|
<ProgressPrimitive.Root
|
||||||
|
value={value}
|
||||||
|
data-slot="progress"
|
||||||
|
className={cn("flex flex-wrap gap-3", className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<ProgressTrack>
|
||||||
|
<ProgressIndicator />
|
||||||
|
</ProgressTrack>
|
||||||
|
</ProgressPrimitive.Root>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {
|
||||||
|
return (
|
||||||
|
<ProgressPrimitive.Track
|
||||||
|
className={cn(
|
||||||
|
"relative flex h-1 w-full items-center overflow-x-hidden rounded-full bg-muted",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
data-slot="progress-track"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProgressIndicator({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: ProgressPrimitive.Indicator.Props) {
|
||||||
|
return (
|
||||||
|
<ProgressPrimitive.Indicator
|
||||||
|
data-slot="progress-indicator"
|
||||||
|
className={cn("h-full bg-primary transition-all", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {
|
||||||
|
return (
|
||||||
|
<ProgressPrimitive.Label
|
||||||
|
className={cn("text-sm font-medium", className)}
|
||||||
|
data-slot="progress-label"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {
|
||||||
|
return (
|
||||||
|
<ProgressPrimitive.Value
|
||||||
|
className={cn(
|
||||||
|
"ml-auto text-sm text-muted-foreground tabular-nums",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
data-slot="progress-value"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
Progress,
|
||||||
|
ProgressTrack,
|
||||||
|
ProgressIndicator,
|
||||||
|
ProgressLabel,
|
||||||
|
ProgressValue,
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import { JobList } from "@/components/JobList"
|
||||||
|
import mockJobs from "@/mocks/jobs.json"
|
||||||
|
|
||||||
export function JobsView() {
|
export function JobsView() {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 flex-col gap-1 p-4">
|
<div className="flex flex-1 flex-col gap-1 mt-4 mb-4">
|
||||||
<p className="text-sm text-muted-foreground">Running jobs coming soon.</p>
|
<JobList jobs={mockJobs} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user