mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
fix: update task link AppStatus using task_id (#20543)
Fixes https://github.com/coder/coder/issues/20515 Alternative to https://github.com/coder/coder/pull/20519 Adds `task_id` to `workspaces_expanded` view and updates the "View Task" link in `AppStatuses` component. NOTE: this contains a migration
This commit is contained in:
+2
-1
@@ -90,6 +90,7 @@
|
||||
"allow_renames": false,
|
||||
"favorite": false,
|
||||
"next_start_at": "====[timestamp]=====",
|
||||
"is_prebuild": false
|
||||
"is_prebuild": false,
|
||||
"task_id": null
|
||||
}
|
||||
]
|
||||
|
||||
@@ -259,6 +259,9 @@ func TestTasks(t *testing.T) {
|
||||
// Wait for the workspace to be built.
|
||||
workspace, err := client.Workspace(ctx, task.WorkspaceID.UUID)
|
||||
require.NoError(t, err)
|
||||
if assert.True(t, workspace.TaskID.Valid, "task id should be set on workspace") {
|
||||
assert.Equal(t, task.ID, workspace.TaskID.UUID, "workspace task id should match")
|
||||
}
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
// List tasks via experimental API and verify the prompt and status mapping.
|
||||
@@ -297,6 +300,9 @@ func TestTasks(t *testing.T) {
|
||||
// Get the workspace and wait for it to be ready.
|
||||
ws, err := client.Workspace(ctx, task.WorkspaceID.UUID)
|
||||
require.NoError(t, err)
|
||||
if assert.True(t, ws.TaskID.Valid, "task id should be set on workspace") {
|
||||
assert.Equal(t, task.ID, ws.TaskID.UUID, "workspace task id should match")
|
||||
}
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID)
|
||||
ws = coderdtest.MustWorkspace(t, client, task.WorkspaceID.UUID)
|
||||
// Assert invariant: the workspace has exactly one resource with one agent with one app.
|
||||
@@ -371,6 +377,9 @@ func TestTasks(t *testing.T) {
|
||||
require.True(t, task.WorkspaceID.Valid, "task should have a workspace ID")
|
||||
ws, err := client.Workspace(ctx, task.WorkspaceID.UUID)
|
||||
require.NoError(t, err)
|
||||
if assert.True(t, ws.TaskID.Valid, "task id should be set on workspace") {
|
||||
assert.Equal(t, task.ID, ws.TaskID.UUID, "workspace task id should match")
|
||||
}
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID)
|
||||
|
||||
err = exp.DeleteTask(ctx, "me", task.ID)
|
||||
@@ -417,6 +426,9 @@ func TestTasks(t *testing.T) {
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
ws := coderdtest.CreateWorkspace(t, client, template.ID)
|
||||
if assert.False(t, ws.TaskID.Valid, "task id should not be set on non-task workspace") {
|
||||
assert.Zero(t, ws.TaskID, "non-task workspace task id should be empty")
|
||||
}
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID)
|
||||
|
||||
exp := codersdk.NewExperimentalClient(client)
|
||||
|
||||
Generated
+8
@@ -19712,6 +19712,14 @@ const docTemplate = `{
|
||||
"description": "OwnerName is the username of the owner of the workspace.",
|
||||
"type": "string"
|
||||
},
|
||||
"task_id": {
|
||||
"description": "TaskID, if set, indicates that the workspace is relevant to the given codersdk.Task.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/uuid.NullUUID"
|
||||
}
|
||||
]
|
||||
},
|
||||
"template_active_version_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
|
||||
Generated
+8
@@ -18098,6 +18098,14 @@
|
||||
"description": "OwnerName is the username of the owner of the workspace.",
|
||||
"type": "string"
|
||||
},
|
||||
"task_id": {
|
||||
"description": "TaskID, if set, indicates that the workspace is relevant to the given codersdk.Task.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/uuid.NullUUID"
|
||||
}
|
||||
]
|
||||
},
|
||||
"template_active_version_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
|
||||
Generated
+5
-3
@@ -2922,11 +2922,13 @@ CREATE VIEW workspaces_expanded AS
|
||||
templates.name AS template_name,
|
||||
templates.display_name AS template_display_name,
|
||||
templates.icon AS template_icon,
|
||||
templates.description AS template_description
|
||||
FROM (((workspaces
|
||||
templates.description AS template_description,
|
||||
tasks.id AS task_id
|
||||
FROM ((((workspaces
|
||||
JOIN visible_users ON ((workspaces.owner_id = visible_users.id)))
|
||||
JOIN organizations ON ((workspaces.organization_id = organizations.id)))
|
||||
JOIN templates ON ((workspaces.template_id = templates.id)));
|
||||
JOIN templates ON ((workspaces.template_id = templates.id)))
|
||||
LEFT JOIN tasks ON ((workspaces.id = tasks.workspace_id)));
|
||||
|
||||
COMMENT ON VIEW workspaces_expanded IS 'Joins in the display name information such as username, avatar, and organization name.';
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
DROP VIEW workspaces_expanded;
|
||||
|
||||
-- Recreate the view from 000354_workspace_acl.up.sql
|
||||
CREATE VIEW workspaces_expanded AS
|
||||
SELECT workspaces.id,
|
||||
workspaces.created_at,
|
||||
workspaces.updated_at,
|
||||
workspaces.owner_id,
|
||||
workspaces.organization_id,
|
||||
workspaces.template_id,
|
||||
workspaces.deleted,
|
||||
workspaces.name,
|
||||
workspaces.autostart_schedule,
|
||||
workspaces.ttl,
|
||||
workspaces.last_used_at,
|
||||
workspaces.dormant_at,
|
||||
workspaces.deleting_at,
|
||||
workspaces.automatic_updates,
|
||||
workspaces.favorite,
|
||||
workspaces.next_start_at,
|
||||
workspaces.group_acl,
|
||||
workspaces.user_acl,
|
||||
visible_users.avatar_url AS owner_avatar_url,
|
||||
visible_users.username AS owner_username,
|
||||
visible_users.name AS owner_name,
|
||||
organizations.name AS organization_name,
|
||||
organizations.display_name AS organization_display_name,
|
||||
organizations.icon AS organization_icon,
|
||||
organizations.description AS organization_description,
|
||||
templates.name AS template_name,
|
||||
templates.display_name AS template_display_name,
|
||||
templates.icon AS template_icon,
|
||||
templates.description AS template_description
|
||||
FROM (((workspaces
|
||||
JOIN visible_users ON ((workspaces.owner_id = visible_users.id)))
|
||||
JOIN organizations ON ((workspaces.organization_id = organizations.id)))
|
||||
JOIN templates ON ((workspaces.template_id = templates.id)));
|
||||
|
||||
COMMENT ON VIEW workspaces_expanded IS 'Joins in the display name information such as username, avatar, and organization name.';
|
||||
@@ -0,0 +1,42 @@
|
||||
DROP VIEW workspaces_expanded;
|
||||
|
||||
-- Add nullable task_id to workspaces_expanded view
|
||||
CREATE VIEW workspaces_expanded AS
|
||||
SELECT workspaces.id,
|
||||
workspaces.created_at,
|
||||
workspaces.updated_at,
|
||||
workspaces.owner_id,
|
||||
workspaces.organization_id,
|
||||
workspaces.template_id,
|
||||
workspaces.deleted,
|
||||
workspaces.name,
|
||||
workspaces.autostart_schedule,
|
||||
workspaces.ttl,
|
||||
workspaces.last_used_at,
|
||||
workspaces.dormant_at,
|
||||
workspaces.deleting_at,
|
||||
workspaces.automatic_updates,
|
||||
workspaces.favorite,
|
||||
workspaces.next_start_at,
|
||||
workspaces.group_acl,
|
||||
workspaces.user_acl,
|
||||
visible_users.avatar_url AS owner_avatar_url,
|
||||
visible_users.username AS owner_username,
|
||||
visible_users.name AS owner_name,
|
||||
organizations.name AS organization_name,
|
||||
organizations.display_name AS organization_display_name,
|
||||
organizations.icon AS organization_icon,
|
||||
organizations.description AS organization_description,
|
||||
templates.name AS template_name,
|
||||
templates.display_name AS template_display_name,
|
||||
templates.icon AS template_icon,
|
||||
templates.description AS template_description,
|
||||
tasks.id AS task_id
|
||||
FROM ((((workspaces
|
||||
JOIN visible_users ON ((workspaces.owner_id = visible_users.id)))
|
||||
JOIN organizations ON ((workspaces.organization_id = organizations.id)))
|
||||
JOIN templates ON ((workspaces.template_id = templates.id)))
|
||||
LEFT JOIN tasks ON ((workspaces.id = tasks.workspace_id)));
|
||||
|
||||
COMMENT ON VIEW workspaces_expanded IS 'Joins in the display name information such as username, avatar, and organization name.';
|
||||
|
||||
@@ -321,6 +321,7 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
|
||||
&i.TemplateDisplayName,
|
||||
&i.TemplateIcon,
|
||||
&i.TemplateDescription,
|
||||
&i.TaskID,
|
||||
&i.TemplateVersionID,
|
||||
&i.TemplateVersionName,
|
||||
&i.LatestBuildCompletedAt,
|
||||
|
||||
@@ -4663,6 +4663,7 @@ type Workspace struct {
|
||||
TemplateDisplayName string `db:"template_display_name" json:"template_display_name"`
|
||||
TemplateIcon string `db:"template_icon" json:"template_icon"`
|
||||
TemplateDescription string `db:"template_description" json:"template_description"`
|
||||
TaskID uuid.NullUUID `db:"task_id" json:"task_id"`
|
||||
}
|
||||
|
||||
type WorkspaceAgent struct {
|
||||
|
||||
@@ -21927,7 +21927,7 @@ func (q *sqlQuerier) GetWorkspaceACLByID(ctx context.Context, id uuid.UUID) (Get
|
||||
|
||||
const getWorkspaceByAgentID = `-- name: GetWorkspaceByAgentID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description, task_id
|
||||
FROM
|
||||
workspaces_expanded as workspaces
|
||||
WHERE
|
||||
@@ -21988,13 +21988,14 @@ func (q *sqlQuerier) GetWorkspaceByAgentID(ctx context.Context, agentID uuid.UUI
|
||||
&i.TemplateDisplayName,
|
||||
&i.TemplateIcon,
|
||||
&i.TemplateDescription,
|
||||
&i.TaskID,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceByID = `-- name: GetWorkspaceByID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description, task_id
|
||||
FROM
|
||||
workspaces_expanded
|
||||
WHERE
|
||||
@@ -22036,13 +22037,14 @@ func (q *sqlQuerier) GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Worksp
|
||||
&i.TemplateDisplayName,
|
||||
&i.TemplateIcon,
|
||||
&i.TemplateDescription,
|
||||
&i.TaskID,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceByOwnerIDAndName = `-- name: GetWorkspaceByOwnerIDAndName :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description, task_id
|
||||
FROM
|
||||
workspaces_expanded as workspaces
|
||||
WHERE
|
||||
@@ -22091,13 +22093,14 @@ func (q *sqlQuerier) GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWo
|
||||
&i.TemplateDisplayName,
|
||||
&i.TemplateIcon,
|
||||
&i.TemplateDescription,
|
||||
&i.TaskID,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceByResourceID = `-- name: GetWorkspaceByResourceID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description, task_id
|
||||
FROM
|
||||
workspaces_expanded as workspaces
|
||||
WHERE
|
||||
@@ -22153,13 +22156,14 @@ func (q *sqlQuerier) GetWorkspaceByResourceID(ctx context.Context, resourceID uu
|
||||
&i.TemplateDisplayName,
|
||||
&i.TemplateIcon,
|
||||
&i.TemplateDescription,
|
||||
&i.TaskID,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceByWorkspaceAppID = `-- name: GetWorkspaceByWorkspaceAppID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite, next_start_at, group_acl, user_acl, owner_avatar_url, owner_username, owner_name, organization_name, organization_display_name, organization_icon, organization_description, template_name, template_display_name, template_icon, template_description, task_id
|
||||
FROM
|
||||
workspaces_expanded as workspaces
|
||||
WHERE
|
||||
@@ -22227,6 +22231,7 @@ func (q *sqlQuerier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspace
|
||||
&i.TemplateDisplayName,
|
||||
&i.TemplateIcon,
|
||||
&i.TemplateDescription,
|
||||
&i.TaskID,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -22276,7 +22281,7 @@ SELECT
|
||||
),
|
||||
filtered_workspaces AS (
|
||||
SELECT
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite, workspaces.next_start_at, workspaces.group_acl, workspaces.user_acl, workspaces.owner_avatar_url, workspaces.owner_username, workspaces.owner_name, workspaces.organization_name, workspaces.organization_display_name, workspaces.organization_icon, workspaces.organization_description, workspaces.template_name, workspaces.template_display_name, workspaces.template_icon, workspaces.template_description,
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite, workspaces.next_start_at, workspaces.group_acl, workspaces.user_acl, workspaces.owner_avatar_url, workspaces.owner_username, workspaces.owner_name, workspaces.organization_name, workspaces.organization_display_name, workspaces.organization_icon, workspaces.organization_description, workspaces.template_name, workspaces.template_display_name, workspaces.template_icon, workspaces.template_description, workspaces.task_id,
|
||||
latest_build.template_version_id,
|
||||
latest_build.template_version_name,
|
||||
latest_build.completed_at as latest_build_completed_at,
|
||||
@@ -22567,7 +22572,7 @@ WHERE
|
||||
-- @authorize_filter
|
||||
), filtered_workspaces_order AS (
|
||||
SELECT
|
||||
fw.id, fw.created_at, fw.updated_at, fw.owner_id, fw.organization_id, fw.template_id, fw.deleted, fw.name, fw.autostart_schedule, fw.ttl, fw.last_used_at, fw.dormant_at, fw.deleting_at, fw.automatic_updates, fw.favorite, fw.next_start_at, fw.group_acl, fw.user_acl, fw.owner_avatar_url, fw.owner_username, fw.owner_name, fw.organization_name, fw.organization_display_name, fw.organization_icon, fw.organization_description, fw.template_name, fw.template_display_name, fw.template_icon, fw.template_description, fw.template_version_id, fw.template_version_name, fw.latest_build_completed_at, fw.latest_build_canceled_at, fw.latest_build_error, fw.latest_build_transition, fw.latest_build_status, fw.latest_build_has_ai_task, fw.latest_build_has_external_agent
|
||||
fw.id, fw.created_at, fw.updated_at, fw.owner_id, fw.organization_id, fw.template_id, fw.deleted, fw.name, fw.autostart_schedule, fw.ttl, fw.last_used_at, fw.dormant_at, fw.deleting_at, fw.automatic_updates, fw.favorite, fw.next_start_at, fw.group_acl, fw.user_acl, fw.owner_avatar_url, fw.owner_username, fw.owner_name, fw.organization_name, fw.organization_display_name, fw.organization_icon, fw.organization_description, fw.template_name, fw.template_display_name, fw.template_icon, fw.template_description, fw.task_id, fw.template_version_id, fw.template_version_name, fw.latest_build_completed_at, fw.latest_build_canceled_at, fw.latest_build_error, fw.latest_build_transition, fw.latest_build_status, fw.latest_build_has_ai_task, fw.latest_build_has_external_agent
|
||||
FROM
|
||||
filtered_workspaces fw
|
||||
ORDER BY
|
||||
@@ -22588,7 +22593,7 @@ WHERE
|
||||
$25
|
||||
), filtered_workspaces_order_with_summary AS (
|
||||
SELECT
|
||||
fwo.id, fwo.created_at, fwo.updated_at, fwo.owner_id, fwo.organization_id, fwo.template_id, fwo.deleted, fwo.name, fwo.autostart_schedule, fwo.ttl, fwo.last_used_at, fwo.dormant_at, fwo.deleting_at, fwo.automatic_updates, fwo.favorite, fwo.next_start_at, fwo.group_acl, fwo.user_acl, fwo.owner_avatar_url, fwo.owner_username, fwo.owner_name, fwo.organization_name, fwo.organization_display_name, fwo.organization_icon, fwo.organization_description, fwo.template_name, fwo.template_display_name, fwo.template_icon, fwo.template_description, fwo.template_version_id, fwo.template_version_name, fwo.latest_build_completed_at, fwo.latest_build_canceled_at, fwo.latest_build_error, fwo.latest_build_transition, fwo.latest_build_status, fwo.latest_build_has_ai_task, fwo.latest_build_has_external_agent
|
||||
fwo.id, fwo.created_at, fwo.updated_at, fwo.owner_id, fwo.organization_id, fwo.template_id, fwo.deleted, fwo.name, fwo.autostart_schedule, fwo.ttl, fwo.last_used_at, fwo.dormant_at, fwo.deleting_at, fwo.automatic_updates, fwo.favorite, fwo.next_start_at, fwo.group_acl, fwo.user_acl, fwo.owner_avatar_url, fwo.owner_username, fwo.owner_name, fwo.organization_name, fwo.organization_display_name, fwo.organization_icon, fwo.organization_description, fwo.template_name, fwo.template_display_name, fwo.template_icon, fwo.template_description, fwo.task_id, fwo.template_version_id, fwo.template_version_name, fwo.latest_build_completed_at, fwo.latest_build_canceled_at, fwo.latest_build_error, fwo.latest_build_transition, fwo.latest_build_status, fwo.latest_build_has_ai_task, fwo.latest_build_has_external_agent
|
||||
FROM
|
||||
filtered_workspaces_order fwo
|
||||
-- Return a technical summary row with total count of workspaces.
|
||||
@@ -22624,6 +22629,7 @@ WHERE
|
||||
'', -- template_display_name
|
||||
'', -- template_icon
|
||||
'', -- template_description
|
||||
'00000000-0000-0000-0000-000000000000'::uuid, -- task_id
|
||||
-- Extra columns added to ` + "`" + `filtered_workspaces` + "`" + `
|
||||
'00000000-0000-0000-0000-000000000000'::uuid, -- template_version_id
|
||||
'', -- template_version_name
|
||||
@@ -22643,7 +22649,7 @@ WHERE
|
||||
filtered_workspaces
|
||||
)
|
||||
SELECT
|
||||
fwos.id, fwos.created_at, fwos.updated_at, fwos.owner_id, fwos.organization_id, fwos.template_id, fwos.deleted, fwos.name, fwos.autostart_schedule, fwos.ttl, fwos.last_used_at, fwos.dormant_at, fwos.deleting_at, fwos.automatic_updates, fwos.favorite, fwos.next_start_at, fwos.group_acl, fwos.user_acl, fwos.owner_avatar_url, fwos.owner_username, fwos.owner_name, fwos.organization_name, fwos.organization_display_name, fwos.organization_icon, fwos.organization_description, fwos.template_name, fwos.template_display_name, fwos.template_icon, fwos.template_description, fwos.template_version_id, fwos.template_version_name, fwos.latest_build_completed_at, fwos.latest_build_canceled_at, fwos.latest_build_error, fwos.latest_build_transition, fwos.latest_build_status, fwos.latest_build_has_ai_task, fwos.latest_build_has_external_agent,
|
||||
fwos.id, fwos.created_at, fwos.updated_at, fwos.owner_id, fwos.organization_id, fwos.template_id, fwos.deleted, fwos.name, fwos.autostart_schedule, fwos.ttl, fwos.last_used_at, fwos.dormant_at, fwos.deleting_at, fwos.automatic_updates, fwos.favorite, fwos.next_start_at, fwos.group_acl, fwos.user_acl, fwos.owner_avatar_url, fwos.owner_username, fwos.owner_name, fwos.organization_name, fwos.organization_display_name, fwos.organization_icon, fwos.organization_description, fwos.template_name, fwos.template_display_name, fwos.template_icon, fwos.template_description, fwos.task_id, fwos.template_version_id, fwos.template_version_name, fwos.latest_build_completed_at, fwos.latest_build_canceled_at, fwos.latest_build_error, fwos.latest_build_transition, fwos.latest_build_status, fwos.latest_build_has_ai_task, fwos.latest_build_has_external_agent,
|
||||
tc.count
|
||||
FROM
|
||||
filtered_workspaces_order_with_summary fwos
|
||||
@@ -22711,6 +22717,7 @@ type GetWorkspacesRow struct {
|
||||
TemplateDisplayName string `db:"template_display_name" json:"template_display_name"`
|
||||
TemplateIcon string `db:"template_icon" json:"template_icon"`
|
||||
TemplateDescription string `db:"template_description" json:"template_description"`
|
||||
TaskID uuid.NullUUID `db:"task_id" json:"task_id"`
|
||||
TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
|
||||
TemplateVersionName sql.NullString `db:"template_version_name" json:"template_version_name"`
|
||||
LatestBuildCompletedAt sql.NullTime `db:"latest_build_completed_at" json:"latest_build_completed_at"`
|
||||
@@ -22793,6 +22800,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
|
||||
&i.TemplateDisplayName,
|
||||
&i.TemplateIcon,
|
||||
&i.TemplateDescription,
|
||||
&i.TaskID,
|
||||
&i.TemplateVersionID,
|
||||
&i.TemplateVersionName,
|
||||
&i.LatestBuildCompletedAt,
|
||||
|
||||
@@ -457,6 +457,7 @@ WHERE
|
||||
'', -- template_display_name
|
||||
'', -- template_icon
|
||||
'', -- template_description
|
||||
'00000000-0000-0000-0000-000000000000'::uuid, -- task_id
|
||||
-- Extra columns added to `filtered_workspaces`
|
||||
'00000000-0000-0000-0000-000000000000'::uuid, -- template_version_id
|
||||
'', -- template_version_name
|
||||
|
||||
@@ -2654,6 +2654,7 @@ func convertWorkspace(
|
||||
Favorite: requesterFavorite,
|
||||
NextStartAt: nextStartAt,
|
||||
IsPrebuild: workspace.IsPrebuild(),
|
||||
TaskID: workspace.TaskID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,8 @@ type Workspace struct {
|
||||
// Once a prebuilt workspace is claimed by a user, it transitions to a regular workspace,
|
||||
// and IsPrebuild returns false.
|
||||
IsPrebuild bool `json:"is_prebuild"`
|
||||
// TaskID, if set, indicates that the workspace is relevant to the given codersdk.Task.
|
||||
TaskID uuid.NullUUID `json:"task_id,omitempty"`
|
||||
}
|
||||
|
||||
func (w Workspace) FullName() string {
|
||||
|
||||
Generated
+9
@@ -10184,6 +10184,10 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
"owner_avatar_url": "string",
|
||||
"owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
|
||||
"owner_name": "string",
|
||||
"task_id": {
|
||||
"uuid": "string",
|
||||
"valid": true
|
||||
},
|
||||
"template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
|
||||
"template_allow_user_cancel_workspace_jobs": true,
|
||||
"template_display_name": "string",
|
||||
@@ -10222,6 +10226,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
| `owner_avatar_url` | string | false | | |
|
||||
| `owner_id` | string | false | | |
|
||||
| `owner_name` | string | false | | Owner name is the username of the owner of the workspace. |
|
||||
| `task_id` | [uuid.NullUUID](#uuidnulluuid) | false | | Task ID if set, indicates that the workspace is relevant to the given codersdk.Task. |
|
||||
| `template_active_version_id` | string | false | | |
|
||||
| `template_allow_user_cancel_workspace_jobs` | boolean | false | | |
|
||||
| `template_display_name` | string | false | | |
|
||||
@@ -12178,6 +12183,10 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
"owner_avatar_url": "string",
|
||||
"owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
|
||||
"owner_name": "string",
|
||||
"task_id": {
|
||||
"uuid": "string",
|
||||
"valid": true
|
||||
},
|
||||
"template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
|
||||
"template_allow_user_cancel_workspace_jobs": true,
|
||||
"template_display_name": "string",
|
||||
|
||||
Generated
+24
@@ -297,6 +297,10 @@ of the template will be used.
|
||||
"owner_avatar_url": "string",
|
||||
"owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
|
||||
"owner_name": "string",
|
||||
"task_id": {
|
||||
"uuid": "string",
|
||||
"valid": true
|
||||
},
|
||||
"template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
|
||||
"template_allow_user_cancel_workspace_jobs": true,
|
||||
"template_display_name": "string",
|
||||
@@ -589,6 +593,10 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
|
||||
"owner_avatar_url": "string",
|
||||
"owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
|
||||
"owner_name": "string",
|
||||
"task_id": {
|
||||
"uuid": "string",
|
||||
"valid": true
|
||||
},
|
||||
"template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
|
||||
"template_allow_user_cancel_workspace_jobs": true,
|
||||
"template_display_name": "string",
|
||||
@@ -906,6 +914,10 @@ of the template will be used.
|
||||
"owner_avatar_url": "string",
|
||||
"owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
|
||||
"owner_name": "string",
|
||||
"task_id": {
|
||||
"uuid": "string",
|
||||
"valid": true
|
||||
},
|
||||
"template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
|
||||
"template_allow_user_cancel_workspace_jobs": true,
|
||||
"template_display_name": "string",
|
||||
@@ -1184,6 +1196,10 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \
|
||||
"owner_avatar_url": "string",
|
||||
"owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
|
||||
"owner_name": "string",
|
||||
"task_id": {
|
||||
"uuid": "string",
|
||||
"valid": true
|
||||
},
|
||||
"template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
|
||||
"template_allow_user_cancel_workspace_jobs": true,
|
||||
"template_display_name": "string",
|
||||
@@ -1477,6 +1493,10 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \
|
||||
"owner_avatar_url": "string",
|
||||
"owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
|
||||
"owner_name": "string",
|
||||
"task_id": {
|
||||
"uuid": "string",
|
||||
"valid": true
|
||||
},
|
||||
"template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
|
||||
"template_allow_user_cancel_workspace_jobs": true,
|
||||
"template_display_name": "string",
|
||||
@@ -2029,6 +2049,10 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \
|
||||
"owner_avatar_url": "string",
|
||||
"owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
|
||||
"owner_name": "string",
|
||||
"task_id": {
|
||||
"uuid": "string",
|
||||
"valid": true
|
||||
},
|
||||
"template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
|
||||
"template_allow_user_cancel_workspace_jobs": true,
|
||||
"template_display_name": "string",
|
||||
|
||||
Generated
+4
@@ -5875,6 +5875,10 @@ export interface Workspace {
|
||||
* and IsPrebuild returns false.
|
||||
*/
|
||||
readonly is_prebuild: boolean;
|
||||
/**
|
||||
* TaskID, if set, indicates that the workspace is relevant to the given codersdk.Task.
|
||||
*/
|
||||
readonly task_id?: string;
|
||||
}
|
||||
|
||||
// From codersdk/workspaces.go
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
createTimestamp,
|
||||
MockTaskWorkspace,
|
||||
MockWorkspace,
|
||||
MockWorkspaceAgent,
|
||||
MockWorkspaceApp,
|
||||
@@ -18,7 +19,7 @@ const meta: Meta<typeof AppStatuses> = {
|
||||
args: {
|
||||
referenceDate: new Date("2024-03-26T15:15:00Z"),
|
||||
agent: mockAgent(MockWorkspaceAppStatuses),
|
||||
workspace: MockWorkspace,
|
||||
workspace: MockTaskWorkspace,
|
||||
},
|
||||
decorators: [withProxyProvider()],
|
||||
};
|
||||
@@ -148,6 +149,24 @@ export const MultipleStatuses: Story = {
|
||||
},
|
||||
};
|
||||
|
||||
export const NoTaskWorkspace: Story = {
|
||||
args: {
|
||||
agent: mockAgent([
|
||||
{
|
||||
...MockWorkspaceAppStatus,
|
||||
id: "status-9",
|
||||
icon: "",
|
||||
message: "status updated via curl",
|
||||
created_at: createTimestamp(5, 15),
|
||||
uri: "",
|
||||
state: "complete" as const,
|
||||
},
|
||||
...MockWorkspaceAppStatuses,
|
||||
]),
|
||||
workspace: MockWorkspace,
|
||||
},
|
||||
};
|
||||
|
||||
function mockAgent(statuses: WorkspaceAppStatus[]) {
|
||||
return {
|
||||
...MockWorkspaceAgent,
|
||||
|
||||
@@ -121,12 +121,16 @@ export const AppStatuses: FC<AppStatusesProps> = ({
|
||||
</Button>
|
||||
))}
|
||||
|
||||
{workspace.task_id && (
|
||||
<Button asChild size="sm" variant="outline">
|
||||
<RouterLink to={`/tasks/${workspace.owner_name}/${workspace.name}`}>
|
||||
<RouterLink
|
||||
to={`/tasks/${workspace.owner_name}/${workspace.task_id}`}
|
||||
>
|
||||
<SquareCheckBigIcon />
|
||||
View task
|
||||
</RouterLink>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
|
||||
@@ -112,9 +112,9 @@ export const RunningWithChildAgent: Story = {
|
||||
export const RunningWithAppStatuses: Story = {
|
||||
args: {
|
||||
workspace: {
|
||||
...Mocks.MockWorkspace,
|
||||
...Mocks.MockTaskWorkspace,
|
||||
latest_build: {
|
||||
...Mocks.MockWorkspace.latest_build,
|
||||
...Mocks.MockTaskWorkspace.latest_build,
|
||||
resources: [
|
||||
{
|
||||
...Mocks.MockWorkspaceResource,
|
||||
|
||||
@@ -5027,6 +5027,11 @@ export const MockTask = {
|
||||
updated_at: "2022-05-17T17:39:01.382927298Z",
|
||||
} satisfies TypesGen.Task;
|
||||
|
||||
export const MockTaskWorkspace: TypesGen.Workspace = {
|
||||
...MockWorkspace,
|
||||
task_id: MockTask.id,
|
||||
};
|
||||
|
||||
export const MockTasks = [
|
||||
MockTask,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user