Skip to content

Commit 9392d85

Browse files
committed
add vaild jobs
1 parent bdc1fce commit 9392d85

File tree

11 files changed

+479
-0
lines changed

11 files changed

+479
-0
lines changed

apps/web/app/routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export default [
2424
),
2525
]),
2626

27+
route("jobs", "routes/ws/jobs.tsx"),
28+
2729
route("environments", "routes/ws/environments.tsx"),
2830
route("environments", "routes/ws/environments/_layout.tsx", [
2931
route(

apps/web/app/routes/ws/_layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
BadgeCheck,
3+
Briefcase,
34
ChevronRight,
45
ChevronsUpDown,
56
Cpu,
@@ -63,6 +64,7 @@ const navigationGroups = [
6364
{ title: "Environments", to: "/environments", icon: TreePine },
6465
{ title: "Runners", to: "/runners", icon: Cpu },
6566
{ title: "Policies", to: "/policies", icon: ShieldCheck },
67+
{ title: "Jobs", to: "/jobs", icon: Briefcase },
6668
],
6769
},
6870
{

apps/web/app/routes/ws/jobs.tsx

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import prettyMs from "pretty-ms";
2+
3+
import { trpc } from "~/api/trpc";
4+
import {
5+
Breadcrumb,
6+
BreadcrumbItem,
7+
BreadcrumbList,
8+
BreadcrumbPage,
9+
} from "~/components/ui/breadcrumb";
10+
import { Separator } from "~/components/ui/separator";
11+
import { SidebarTrigger } from "~/components/ui/sidebar";
12+
import {
13+
Table,
14+
TableBody,
15+
TableCell,
16+
TableHead,
17+
TableHeader,
18+
TableRow,
19+
} from "~/components/ui/table";
20+
import { useWorkspace } from "~/components/WorkspaceProvider";
21+
22+
export default function Jobs() {
23+
const { workspace } = useWorkspace();
24+
const jobQuery = trpc.jobs.list.useQuery({
25+
workspaceId: workspace.id,
26+
});
27+
28+
const jobs = jobQuery.data?.items ?? [];
29+
30+
return (
31+
<>
32+
<header className="flex h-16 shrink-0 items-center justify-between gap-2 border-b px-4">
33+
<div className="flex items-center gap-2">
34+
<SidebarTrigger className="-ml-1" />
35+
<Separator
36+
orientation="vertical"
37+
className="mr-2 data-[orientation=vertical]:h-4"
38+
/>
39+
<Breadcrumb>
40+
<BreadcrumbList>
41+
<BreadcrumbItem>
42+
<BreadcrumbPage>Jobs</BreadcrumbPage>
43+
</BreadcrumbItem>
44+
</BreadcrumbList>
45+
</Breadcrumb>
46+
</div>
47+
</header>
48+
<Table>
49+
<TableHeader>
50+
<TableRow className="bg-muted/50">
51+
<TableHead className="text-muted-foreground">ID</TableHead>
52+
<TableHead className="text-muted-foreground">Status</TableHead>
53+
<TableHead className="text-muted-foreground">Created At</TableHead>
54+
<TableHead className="text-muted-foreground">Updated At</TableHead>
55+
</TableRow>
56+
</TableHeader>
57+
<TableBody>
58+
{jobs.map(({ job }) => {
59+
return (
60+
<TableRow key={job.id}>
61+
<TableCell className="font-mono">{job.id}</TableCell>
62+
<TableCell>{job.status}</TableCell>
63+
<TableCell>
64+
{prettyMs(
65+
new Date(job.createdAt).getTime() -
66+
new Date(job.updatedAt).getTime(),
67+
)}
68+
</TableCell>
69+
<TableCell>
70+
{prettyMs(
71+
new Date(job.updatedAt).getTime() -
72+
new Date(job.createdAt).getTime(),
73+
)}
74+
</TableCell>
75+
</TableRow>
76+
);
77+
})}
78+
</TableBody>
79+
</Table>
80+
</>
81+
);
82+
}

apps/workspace-engine/oapi/openapi.json

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,30 @@
496496
],
497497
"type": "object"
498498
},
499+
"JobWithRelease": {
500+
"properties": {
501+
"deployment": {
502+
"$ref": "#/components/schemas/Deployment"
503+
},
504+
"environment": {
505+
"$ref": "#/components/schemas/Environment"
506+
},
507+
"job": {
508+
"$ref": "#/components/schemas/Job"
509+
},
510+
"release": {
511+
"$ref": "#/components/schemas/Release"
512+
},
513+
"resource": {
514+
"$ref": "#/components/schemas/Resource"
515+
}
516+
},
517+
"required": [
518+
"job",
519+
"release"
520+
],
521+
"type": "object"
522+
},
499523
"JsonSelector": {
500524
"properties": {
501525
"json": {
@@ -2450,6 +2474,105 @@
24502474
}
24512475
}
24522476
},
2477+
"/v1/workspaces/{workspaceId}/jobs": {
2478+
"get": {
2479+
"description": "Returns a list of jobs.",
2480+
"operationId": "getJobs",
2481+
"parameters": [
2482+
{
2483+
"description": "ID of the workspace",
2484+
"in": "path",
2485+
"name": "workspaceId",
2486+
"required": true,
2487+
"schema": {
2488+
"type": "string"
2489+
}
2490+
},
2491+
{
2492+
"description": "Maximum number of items to return",
2493+
"in": "query",
2494+
"name": "limit",
2495+
"required": false,
2496+
"schema": {
2497+
"default": 50,
2498+
"maximum": 1000,
2499+
"minimum": 1,
2500+
"type": "integer"
2501+
}
2502+
},
2503+
{
2504+
"description": "Number of items to skip",
2505+
"in": "query",
2506+
"name": "offset",
2507+
"required": false,
2508+
"schema": {
2509+
"default": 0,
2510+
"minimum": 0,
2511+
"type": "integer"
2512+
}
2513+
}
2514+
],
2515+
"responses": {
2516+
"200": {
2517+
"content": {
2518+
"application/json": {
2519+
"schema": {
2520+
"properties": {
2521+
"items": {
2522+
"items": {
2523+
"$ref": "#/components/schemas/JobWithRelease"
2524+
},
2525+
"type": "array"
2526+
},
2527+
"limit": {
2528+
"description": "Maximum number of items returned",
2529+
"type": "integer"
2530+
},
2531+
"offset": {
2532+
"description": "Number of items skipped",
2533+
"type": "integer"
2534+
},
2535+
"total": {
2536+
"description": "Total number of items available",
2537+
"type": "integer"
2538+
}
2539+
},
2540+
"required": [
2541+
"items",
2542+
"total",
2543+
"limit",
2544+
"offset"
2545+
],
2546+
"type": "object"
2547+
}
2548+
}
2549+
},
2550+
"description": "Paginated list of items"
2551+
},
2552+
"400": {
2553+
"content": {
2554+
"application/json": {
2555+
"schema": {
2556+
"$ref": "#/components/schemas/ErrorResponse"
2557+
}
2558+
}
2559+
},
2560+
"description": "Invalid request"
2561+
},
2562+
"404": {
2563+
"content": {
2564+
"application/json": {
2565+
"schema": {
2566+
"$ref": "#/components/schemas/ErrorResponse"
2567+
}
2568+
}
2569+
},
2570+
"description": "Resource not found"
2571+
}
2572+
},
2573+
"summary": "List jobs"
2574+
}
2575+
},
24532576
"/v1/workspaces/{workspaceId}/jobs/{jobId}": {
24542577
"get": {
24552578
"description": "Returns a specific job by ID.",

apps/workspace-engine/oapi/spec/paths/jobs.jsonnet

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
local openapi = import '../lib/openapi.libsonnet';
22

33
{
4+
'/v1/workspaces/{workspaceId}/jobs': {
5+
get: {
6+
summary: 'List jobs',
7+
operationId: 'getJobs',
8+
description: 'Returns a list of jobs.',
9+
parameters: [
10+
openapi.workspaceIdParam(),
11+
openapi.limitParam(),
12+
openapi.offsetParam(),
13+
],
14+
responses: openapi.paginatedResponse(openapi.schemaRef('JobWithRelease'))
15+
+ openapi.notFoundResponse()
16+
+ openapi.badRequestResponse(),
17+
},
18+
},
419
'/v1/workspaces/{workspaceId}/jobs/{jobId}': {
520
get: {
621
summary: 'Get job',

apps/workspace-engine/oapi/spec/schemas/jobs.jsonnet

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ local JobPropertyKeys = std.objectFields(Job.properties);
5454
],
5555
},
5656

57+
JobWithRelease: {
58+
type: 'object',
59+
required: ['job', 'release'],
60+
properties: {
61+
job: openapi.schemaRef('Job'),
62+
release: openapi.schemaRef('Release'),
63+
environment: openapi.schemaRef('Environment'),
64+
deployment: openapi.schemaRef('Deployment'),
65+
resource: openapi.schemaRef('Resource'),
66+
},
67+
},
68+
5769
JobUpdateEvent: {
5870
type: 'object',
5971
required: ['job'],

apps/workspace-engine/pkg/oapi/oapi.gen.go

Lines changed: 65 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)