feat(site): use new task data model and endpoints (#20431)

Updates the UI to use the new API endpoints for tasks and use its new
data model.

Disclaimer: Since the base data model for tasks changed, we had to do a
quite large refactor and I'm sorry for that 🙏, but you'll notice most of
the changes are to adjust the types.

Closes coder/internal#976

---------

Co-authored-by: Bruno Quaresma <bruno_nonato_quaresma@hotmail.com>
This commit is contained in:
Mathias Fredriksson
2025-10-24 10:45:19 -03:00
committed by GitHub
co-authored by Bruno Quaresma
parent c6e551f538
commit 51d3abb904
32 changed files with 607 additions and 659 deletions
+4 -10
View File
@@ -339,6 +339,7 @@ func taskFromDBTaskAndWorkspace(dbTask database.Task, ws codersdk.Workspace) cod
OrganizationID: dbTask.OrganizationID,
OwnerID: dbTask.OwnerID,
OwnerName: ws.OwnerName,
OwnerAvatarURL: ws.OwnerAvatarURL,
Name: dbTask.Name,
TemplateID: ws.TemplateID,
TemplateVersionID: dbTask.TemplateVersionID,
@@ -346,6 +347,7 @@ func taskFromDBTaskAndWorkspace(dbTask database.Task, ws codersdk.Workspace) cod
TemplateDisplayName: ws.TemplateDisplayName,
TemplateIcon: ws.TemplateIcon,
WorkspaceID: dbTask.WorkspaceID,
WorkspaceName: ws.Name,
WorkspaceBuildNumber: dbTask.WorkspaceBuildNumber.Int32,
WorkspaceStatus: ws.LatestBuild.Status,
WorkspaceAgentID: dbTask.WorkspaceAgentID,
@@ -360,21 +362,13 @@ func taskFromDBTaskAndWorkspace(dbTask database.Task, ws codersdk.Workspace) cod
}
}
// tasksListResponse wraps a list of experimental tasks.
//
// Experimental: Response shape is experimental and may change.
type tasksListResponse struct {
Tasks []codersdk.Task `json:"tasks"`
Count int `json:"count"`
}
// @Summary List AI tasks
// @Description: EXPERIMENTAL: this endpoint is experimental and not guaranteed to be stable.
// @ID list-tasks
// @Security CoderSessionToken
// @Tags Experimental
// @Param q query string false "Search query for filtering tasks. Supports: owner:<username/uuid/me>, organization:<org-name/uuid>, status:<status>"
// @Success 200 {object} coderd.tasksListResponse
// @Success 200 {object} codersdk.TasksListResponse
// @Router /api/experimental/tasks [get]
//
// EXPERIMENTAL: This endpoint is experimental and not guaranteed to be stable.
@@ -413,7 +407,7 @@ func (api *API) tasksList(rw http.ResponseWriter, r *http.Request) {
return
}
httpapi.Write(ctx, rw, http.StatusOK, tasksListResponse{
httpapi.Write(ctx, rw, http.StatusOK, codersdk.TasksListResponse{
Tasks: tasks,
Count: len(tasks),
})
+2
View File
@@ -268,6 +268,7 @@ func TestTasks(t *testing.T) {
require.True(t, ok, "task should be found in the list")
assert.Equal(t, wantPrompt, got.InitialPrompt, "task prompt should match the AI Prompt parameter")
assert.Equal(t, task.WorkspaceID.UUID, got.WorkspaceID.UUID, "workspace id should match")
assert.Equal(t, task.WorkspaceName, got.WorkspaceName, "workspace name should match")
// Status should be populated via the tasks_with_status view.
assert.NotEmpty(t, got.Status, "task status should not be empty")
assert.NotEmpty(t, got.WorkspaceStatus, "workspace status should not be empty")
@@ -323,6 +324,7 @@ func TestTasks(t *testing.T) {
assert.Equal(t, task.Name, updated.Name, "task name should match")
assert.Equal(t, wantPrompt, updated.InitialPrompt, "task prompt should match the AI Prompt parameter")
assert.Equal(t, task.WorkspaceID.UUID, updated.WorkspaceID.UUID, "workspace id should match")
assert.Equal(t, task.WorkspaceName, updated.WorkspaceName, "workspace name should match")
assert.Equal(t, ws.LatestBuild.BuildNumber, updated.WorkspaceBuildNumber, "workspace build number should match")
assert.Equal(t, agentID, updated.WorkspaceAgentID.UUID, "workspace agent id should match")
assert.Equal(t, taskAppID, updated.WorkspaceAppID.UUID, "workspace app id should match")
+21 -15
View File
@@ -160,7 +160,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/coderd.tasksListResponse"
"$ref": "#/definitions/codersdk.TasksListResponse"
}
}
}
@@ -11640,20 +11640,6 @@ const docTemplate = `{
}
}
},
"coderd.tasksListResponse": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"tasks": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.Task"
}
}
}
},
"codersdk.ACLAvailable": {
"type": "object",
"properties": {
@@ -17744,6 +17730,9 @@ const docTemplate = `{
"type": "string",
"format": "uuid"
},
"owner_avatar_url": {
"type": "string"
},
"owner_id": {
"type": "string",
"format": "uuid"
@@ -17820,6 +17809,9 @@ const docTemplate = `{
}
]
},
"workspace_name": {
"type": "string"
},
"workspace_status": {
"enum": [
"pending",
@@ -17941,6 +17933,20 @@ const docTemplate = `{
"TaskStatusError"
]
},
"codersdk.TasksListResponse": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"tasks": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.Task"
}
}
}
},
"codersdk.TelemetryConfig": {
"type": "object",
"properties": {
+21 -15
View File
@@ -134,7 +134,7 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/coderd.tasksListResponse"
"$ref": "#/definitions/codersdk.TasksListResponse"
}
}
}
@@ -10336,20 +10336,6 @@
}
}
},
"coderd.tasksListResponse": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"tasks": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.Task"
}
}
}
},
"codersdk.ACLAvailable": {
"type": "object",
"properties": {
@@ -16232,6 +16218,9 @@
"type": "string",
"format": "uuid"
},
"owner_avatar_url": {
"type": "string"
},
"owner_id": {
"type": "string",
"format": "uuid"
@@ -16308,6 +16297,9 @@
}
]
},
"workspace_name": {
"type": "string"
},
"workspace_status": {
"enum": [
"pending",
@@ -16418,6 +16410,20 @@
"TaskStatusError"
]
},
"codersdk.TasksListResponse": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"tasks": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.Task"
}
}
}
},
"codersdk.TelemetryConfig": {
"type": "object",
"properties": {