From 7a97ebe037593b382c2ecce008057841648b40dc Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 30 Oct 2025 12:08:58 +0000 Subject: [PATCH] refactor!: remove TaskAppID from codersdk.WorkspaceBuild We can instead use the new data model for this, there is no reason to have it stored inside the workspace build. `TaskAppID` has not _yet_ been shipped into a release. This would need cherry-picking if we wanted to go ahead with it. If we don't want to cherry-pick, we should instead mark the TaskAppID as deprecated. This isn't ideal as it hasn't even been released yet. --- coderd/apidoc/docs.go | 6 +- coderd/apidoc/swagger.json | 6 +- coderd/workspacebuilds.go | 1 - codersdk/workspacebuilds.go | 3 +- docs/reference/api/builds.md | 8 +- docs/reference/api/schemas.md | 6 +- docs/reference/api/workspaces.md | 6 - site/src/api/typesGenerated.ts | 3 +- site/src/pages/TaskPage/TaskApps.stories.tsx | 14 +- site/src/pages/TaskPage/TaskApps.tsx | 13 +- site/src/pages/TaskPage/TaskPage.stories.tsx | 196 +++++++++---------- site/src/pages/TaskPage/TaskPage.tsx | 4 +- 12 files changed, 121 insertions(+), 145 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 2fe716a0775f6..beacf64fc20b4 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -20530,7 +20530,7 @@ const docTemplate = `{ "type": "object", "properties": { "ai_task_sidebar_app_id": { - "description": "Deprecated: This field has been replaced with ` + "`" + `TaskAppID` + "`" + `", + "description": "Deprecated: This field has been replaced with ` + "`" + `Task.WorkspaceAppID` + "`" + `", "type": "string", "format": "uuid" }, @@ -20612,10 +20612,6 @@ const docTemplate = `{ } ] }, - "task_app_id": { - "type": "string", - "format": "uuid" - }, "template_version_id": { "type": "string", "format": "uuid" diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 10031b2dd36be..477b01a8970aa 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -18864,7 +18864,7 @@ "type": "object", "properties": { "ai_task_sidebar_app_id": { - "description": "Deprecated: This field has been replaced with `TaskAppID`", + "description": "Deprecated: This field has been replaced with `Task.WorkspaceAppID`", "type": "string", "format": "uuid" }, @@ -18942,10 +18942,6 @@ } ] }, - "task_app_id": { - "type": "string", - "format": "uuid" - }, "template_version_id": { "type": "string", "format": "uuid" diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index e4e3e497a1a22..d064a0ef3f574 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -1228,7 +1228,6 @@ func (api *API) convertWorkspaceBuild( TemplateVersionPresetID: presetID, HasAITask: hasAITask, AITaskSidebarAppID: taskAppID, - TaskAppID: taskAppID, HasExternalAgent: hasExternalAgent, }, nil } diff --git a/codersdk/workspacebuilds.go b/codersdk/workspacebuilds.go index fee4c114b7eae..8c38bd5c6469b 100644 --- a/codersdk/workspacebuilds.go +++ b/codersdk/workspacebuilds.go @@ -89,9 +89,8 @@ type WorkspaceBuild struct { MatchedProvisioners *MatchedProvisioners `json:"matched_provisioners,omitempty"` TemplateVersionPresetID *uuid.UUID `json:"template_version_preset_id" format:"uuid"` HasAITask *bool `json:"has_ai_task,omitempty"` - // Deprecated: This field has been replaced with `TaskAppID` + // Deprecated: This field has been replaced with `Task.WorkspaceAppID` AITaskSidebarAppID *uuid.UUID `json:"ai_task_sidebar_app_id,omitempty" format:"uuid"` - TaskAppID *uuid.UUID `json:"task_app_id,omitempty" format:"uuid"` HasExternalAgent *bool `json:"has_external_agent,omitempty"` } diff --git a/docs/reference/api/builds.md b/docs/reference/api/builds.md index ea207f84eab39..82b7cb8365a3e 100644 --- a/docs/reference/api/builds.md +++ b/docs/reference/api/builds.md @@ -222,7 +222,6 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -464,7 +463,6 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -1197,7 +1195,6 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -1512,7 +1509,6 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -1540,7 +1536,7 @@ Status Code **200** | Name | Type | Required | Restrictions | Description | |----------------------------------|--------------------------------------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `[array item]` | array | false | | | -| `» ai_task_sidebar_app_id` | string(uuid) | false | | Deprecated: This field has been replaced with `TaskAppID` | +| `» ai_task_sidebar_app_id` | string(uuid) | false | | Deprecated: This field has been replaced with `Task.WorkspaceAppID` | | `» build_number` | integer | false | | | | `» created_at` | string(date-time) | false | | | | `» daily_cost` | integer | false | | | @@ -1691,7 +1687,6 @@ Status Code **200** | `»» type` | string | false | | | | `»» workspace_transition` | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition) | false | | | | `» status` | [codersdk.WorkspaceStatus](schemas.md#codersdkworkspacestatus) | false | | | -| `» task_app_id` | string(uuid) | false | | | | `» template_version_id` | string(uuid) | false | | | | `» template_version_name` | string | false | | | | `» template_version_preset_id` | string(uuid) | false | | | @@ -2013,7 +2008,6 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index 300b79b6f435a..351afae7aa8c0 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -10166,7 +10166,6 @@ If the schedule is empty, the user will be updated to use the default schedule.| } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -11341,7 +11340,6 @@ If the schedule is empty, the user will be updated to use the default schedule.| } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -11359,7 +11357,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| | Name | Type | Required | Restrictions | Description | |------------------------------|-------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------| -| `ai_task_sidebar_app_id` | string | false | | Deprecated: This field has been replaced with `TaskAppID` | +| `ai_task_sidebar_app_id` | string | false | | Deprecated: This field has been replaced with `Task.WorkspaceAppID` | | `build_number` | integer | false | | | | `created_at` | string | false | | | | `daily_cost` | integer | false | | | @@ -11375,7 +11373,6 @@ If the schedule is empty, the user will be updated to use the default schedule.| | `reason` | [codersdk.BuildReason](#codersdkbuildreason) | false | | | | `resources` | array of [codersdk.WorkspaceResource](#codersdkworkspaceresource) | false | | | | `status` | [codersdk.WorkspaceStatus](#codersdkworkspacestatus) | false | | | -| `task_app_id` | string | false | | | | `template_version_id` | string | false | | | | `template_version_name` | string | false | | | | `template_version_preset_id` | string | false | | | @@ -12165,7 +12162,6 @@ If the schedule is empty, the user will be updated to use the default schedule.| } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", diff --git a/docs/reference/api/workspaces.md b/docs/reference/api/workspaces.md index 3e52d9e0a2d60..4bd188df3daf5 100644 --- a/docs/reference/api/workspaces.md +++ b/docs/reference/api/workspaces.md @@ -277,7 +277,6 @@ of the template will be used. } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -573,7 +572,6 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -894,7 +892,6 @@ of the template will be used. } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -1176,7 +1173,6 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -1473,7 +1469,6 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \ } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", @@ -2029,7 +2024,6 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \ } ], "status": "pending", - "task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735", "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "template_version_name": "string", "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1", diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 1c5d101e2676d..b6e17cf467320 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -6394,10 +6394,9 @@ export interface WorkspaceBuild { readonly template_version_preset_id: string | null; readonly has_ai_task?: boolean; /** - * Deprecated: This field has been replaced with `TaskAppID` + * Deprecated: This field has been replaced with `Task.WorkspaceAppID` */ readonly ai_task_sidebar_app_id?: string; - readonly task_app_id?: string; readonly has_external_agent?: boolean; } diff --git a/site/src/pages/TaskPage/TaskApps.stories.tsx b/site/src/pages/TaskPage/TaskApps.stories.tsx index 752c52cfde423..dcce3f5949d21 100644 --- a/site/src/pages/TaskPage/TaskApps.stories.tsx +++ b/site/src/pages/TaskPage/TaskApps.stories.tsx @@ -1,5 +1,6 @@ import { MockPrimaryWorkspaceProxy, + MockTask, MockUserOwner, MockWorkspace, MockWorkspaceAgent, @@ -8,7 +9,7 @@ import { } from "testHelpers/entities"; import { withAuthProvider, withProxyProvider } from "testHelpers/storybook"; import type { Meta, StoryObj } from "@storybook/react-vite"; -import type { Workspace, WorkspaceApp } from "api/typesGenerated"; +import type { Task, Workspace, WorkspaceApp } from "api/typesGenerated"; import { getPreferredProxy } from "contexts/ProxyContext"; import kebabCase from "lodash/kebabCase"; import { TaskApps } from "./TaskApps"; @@ -19,6 +20,11 @@ const mockExternalApp: WorkspaceApp = { health: "healthy", }; +const mockTask: Task = { + ...MockTask, + workspace_app_id: null, +}; + const meta: Meta = { title: "pages/TaskPage/TaskApps", component: TaskApps, @@ -33,24 +39,28 @@ type Story = StoryObj; export const NoEmbeddedApps: Story = { args: { + task: mockTask, workspace: mockWorkspaceWithApps([]), }, }; export const WithExternalAppsOnly: Story = { args: { + task: mockTask, workspace: mockWorkspaceWithApps([mockExternalApp]), }, }; export const WithEmbeddedApps: Story = { args: { + task: mockTask, workspace: mockWorkspaceWithApps([mockEmbeddedApp()]), }, }; export const WithMixedApps: Story = { args: { + task: mockTask, workspace: mockWorkspaceWithApps([mockEmbeddedApp(), mockExternalApp]), }, }; @@ -69,6 +79,7 @@ export const WithWildcardWarning: Story = { user: MockUserOwner, }, args: { + task: mockTask, workspace: mockWorkspaceWithApps([ { ...mockEmbeddedApp(), @@ -80,6 +91,7 @@ export const WithWildcardWarning: Story = { export const WithManyEmbeddedApps: Story = { args: { + task: mockTask, workspace: mockWorkspaceWithApps([ mockEmbeddedApp("Code Server"), mockEmbeddedApp("Jupyter Notebook"), diff --git a/site/src/pages/TaskPage/TaskApps.tsx b/site/src/pages/TaskPage/TaskApps.tsx index 2f05145bca46a..59ada2181119b 100644 --- a/site/src/pages/TaskPage/TaskApps.tsx +++ b/site/src/pages/TaskPage/TaskApps.tsx @@ -1,4 +1,4 @@ -import type { Workspace } from "api/typesGenerated"; +import type { Task, Workspace } from "api/typesGenerated"; import { Button } from "components/Button/Button"; import { DropdownMenu, @@ -24,18 +24,17 @@ import { docs } from "utils/docs"; import { TaskAppIFrame, TaskIframe } from "./TaskAppIframe"; type TaskAppsProps = { + task: Task; workspace: Workspace; }; const TERMINAL_TAB_ID = "terminal"; -export const TaskApps: FC = ({ workspace }) => { +export const TaskApps: FC = ({ task, workspace }) => { const apps = getAllAppsWithAgent(workspace).filter( // The Chat UI app will be displayed in the sidebar, so we don't want to // show it as a web app. - (app) => - app.id !== workspace.latest_build.task_app_id && - app.health !== "disabled", + (app) => app.id !== task.workspace_app_id && app.health !== "disabled", ); const [embeddedApps, externalApps] = splitEmbeddedAndExternalApps(apps); const [activeAppId, setActiveAppId] = useState(embeddedApps.at(0)?.id); @@ -43,8 +42,8 @@ export const TaskApps: FC = ({ workspace }) => { embeddedApps.length > 0 || externalApps.length > 0; const taskAgent = apps.at(0)?.agent; const terminalHref = getTerminalHref({ - username: workspace.owner_name, - workspace: workspace.name, + username: task.owner_name, + workspace: task.workspace_name, agent: taskAgent?.name, }); const isTerminalActive = activeAppId === TERMINAL_TAB_ID; diff --git a/site/src/pages/TaskPage/TaskPage.stories.tsx b/site/src/pages/TaskPage/TaskPage.stories.tsx index 22fccb7349863..b247a2a16b377 100644 --- a/site/src/pages/TaskPage/TaskPage.stories.tsx +++ b/site/src/pages/TaskPage/TaskPage.stories.tsx @@ -23,7 +23,7 @@ import { } from "testHelpers/storybook"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { API } from "api/api"; -import type { Workspace, WorkspaceApp } from "api/typesGenerated"; +import type { Task, Workspace, WorkspaceApp } from "api/typesGenerated"; import { expect, spyOn, userEvent, waitFor, within } from "storybook/test"; import { reactRouterParameters } from "storybook-addon-remix-react-router"; import TaskPage from "./TaskPage"; @@ -220,87 +220,70 @@ export const WaitingStartupScripts: Story = { export const SidebarAppNotFound: Story = { beforeEach: () => { - const workspace = mockTaskWorkspace(MockClaudeCodeApp, MockVSCodeApp); - spyOn(API.experimental, "getTask").mockResolvedValue(MockTask); - spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue({ - ...workspace, - latest_build: { - ...workspace.latest_build, - task_app_id: "non-existent-app-id", - }, + const [task, workspace] = mockTaskWithWorkspace( + MockClaudeCodeApp, + MockVSCodeApp, + ); + spyOn(API.experimental, "getTask").mockResolvedValue({ + ...task, + workspace_app_id: null, }); + spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace); }, }; export const SidebarAppHealthDisabled: Story = { beforeEach: () => { - spyOn(API.experimental, "getTask").mockResolvedValue(MockTask); - spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue( - mockTaskWorkspace( - { - ...MockClaudeCodeApp, - health: "disabled", - }, - MockVSCodeApp, - ), + const [task, workspace] = mockTaskWithWorkspace( + { ...MockClaudeCodeApp, health: "disabled" }, + MockVSCodeApp, ); + spyOn(API.experimental, "getTask").mockResolvedValue(task); + spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace); }, }; export const SidebarAppInitializing: Story = { beforeEach: () => { - spyOn(API.experimental, "getTask").mockResolvedValue(MockTask); - spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue( - mockTaskWorkspace( - { - ...MockClaudeCodeApp, - health: "initializing", - }, - MockVSCodeApp, - ), + const [task, workspace] = mockTaskWithWorkspace( + { ...MockClaudeCodeApp, health: "initializing" }, + MockVSCodeApp, ); + spyOn(API.experimental, "getTask").mockResolvedValue(task); + spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace); }, }; export const SidebarAppHealthy: Story = { beforeEach: () => { - spyOn(API.experimental, "getTask").mockResolvedValue(MockTask); - spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue( - mockTaskWorkspace( - { - ...MockClaudeCodeApp, - health: "healthy", - }, - MockVSCodeApp, - ), + const [task, workspace] = mockTaskWithWorkspace( + { ...MockClaudeCodeApp, health: "healthy" }, + MockVSCodeApp, ); + spyOn(API.experimental, "getTask").mockResolvedValue(task); + spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace); }, }; export const SidebarAppUnhealthy: Story = { beforeEach: () => { - spyOn(API.experimental, "getTask").mockResolvedValue(MockTask); - spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue( - mockTaskWorkspace( - { - ...MockClaudeCodeApp, - health: "unhealthy", - }, - MockVSCodeApp, - ), + const [task, workspace] = mockTaskWithWorkspace( + { ...MockClaudeCodeApp, health: "unhealthy" }, + MockVSCodeApp, ); + spyOn(API.experimental, "getTask").mockResolvedValue(task); + spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace); }, }; const mainAppHealthStory = (health: WorkspaceApp["health"]) => ({ beforeEach: () => { - spyOn(API.experimental, "getTask").mockResolvedValue(MockTask); - spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue( - mockTaskWorkspace(MockClaudeCodeApp, { - ...MockVSCodeApp, - health, - }), - ); + const [task, workspace] = mockTaskWithWorkspace(MockClaudeCodeApp, { + ...MockVSCodeApp, + health, + }); + spyOn(API.experimental, "getTask").mockResolvedValue(task); + spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace); }, }); @@ -311,10 +294,12 @@ export const MainAppUnhealthy: Story = mainAppHealthStory("unhealthy"); export const Active: Story = { decorators: [withProxyProvider()], beforeEach: () => { - spyOn(API.experimental, "getTask").mockResolvedValue(MockTask); - spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue( - mockTaskWorkspace(MockClaudeCodeApp, MockVSCodeApp), + const [task, workspace] = mockTaskWithWorkspace( + MockClaudeCodeApp, + MockVSCodeApp, ); + spyOn(API.experimental, "getTask").mockResolvedValue(task); + spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace); }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -332,10 +317,12 @@ export const Active: Story = { export const ActivePreview: Story = { decorators: [withProxyProvider()], beforeEach: () => { - spyOn(API.experimental, "getTask").mockResolvedValue(MockTask); - spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue( - mockTaskWorkspace(MockClaudeCodeApp, MockVSCodeApp), + const [task, workspace] = mockTaskWithWorkspace( + MockClaudeCodeApp, + MockVSCodeApp, ); + spyOn(API.experimental, "getTask").mockResolvedValue(task); + spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace); }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -464,51 +451,56 @@ export const WorkspaceStartFailureWithDialog: Story = { }, }; -function mockTaskWorkspace( +function mockTaskWithWorkspace( sidebarApp: WorkspaceApp, activeApp: WorkspaceApp, -): Workspace { - return { - ...MockWorkspace, - latest_build: { - ...MockWorkspace.latest_build, - has_ai_task: true, - task_app_id: sidebarApp.id, - resources: [ - { - ...MockWorkspaceResource, - agents: [ - { - ...MockWorkspaceAgentReady, - apps: [ - sidebarApp, - activeApp, - { - ...MockWorkspaceApp, - slug: "zed", - id: "zed", - display_name: "Zed", - icon: "/icon/zed.svg", - health: "healthy", - }, - { - ...MockWorkspaceApp, - slug: "preview", - id: "preview", - display_name: "Preview", - health: "healthy", - }, - { - ...MockWorkspaceApp, - slug: "disabled", - id: "disabled", - display_name: "Disabled", - }, - ], - }, - ], - }, - ], +): [Task, Workspace] { + return [ + { + ...MockTask, + workspace_app_id: sidebarApp.id, + }, + { + ...MockWorkspace, + latest_build: { + ...MockWorkspace.latest_build, + has_ai_task: true, + resources: [ + { + ...MockWorkspaceResource, + agents: [ + { + ...MockWorkspaceAgentReady, + apps: [ + sidebarApp, + activeApp, + { + ...MockWorkspaceApp, + slug: "zed", + id: "zed", + display_name: "Zed", + icon: "/icon/zed.svg", + health: "healthy", + }, + { + ...MockWorkspaceApp, + slug: "preview", + id: "preview", + display_name: "Preview", + health: "healthy", + }, + { + ...MockWorkspaceApp, + slug: "disabled", + id: "disabled", + display_name: "Disabled", + }, + ], + }, + ], + }, + ], + }, }, - }; + ]; } diff --git a/site/src/pages/TaskPage/TaskPage.tsx b/site/src/pages/TaskPage/TaskPage.tsx index 49f9d7569680b..f57d0e9f1772c 100644 --- a/site/src/pages/TaskPage/TaskPage.tsx +++ b/site/src/pages/TaskPage/TaskPage.tsx @@ -149,7 +149,7 @@ const TaskPage = () => { content = ; } else { const chatApp = getAllAppsWithAgent(workspace).find( - (app) => app.id === workspace.latest_build.task_app_id, + (app) => app.id === task.workspace_app_id, ); content = ( @@ -174,7 +174,7 @@ const TaskPage = () => {
- + );