mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor!: remove TaskAppID from codersdk.WorkspaceBuild (#20583)
Remove the `TaskAppID` field from `codersdk.WorkspaceBuild`. Consumers can instead use the new `codersdk.Task` data model for this information.
This commit is contained in:
Generated
+1
-5
@@ -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"
|
||||
|
||||
Generated
+1
-5
@@ -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"
|
||||
|
||||
@@ -1228,7 +1228,6 @@ func (api *API) convertWorkspaceBuild(
|
||||
TemplateVersionPresetID: presetID,
|
||||
HasAITask: hasAITask,
|
||||
AITaskSidebarAppID: taskAppID,
|
||||
TaskAppID: taskAppID,
|
||||
HasExternalAgent: hasExternalAgent,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
|
||||
Generated
+1
-7
@@ -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",
|
||||
|
||||
Generated
+1
-5
@@ -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",
|
||||
|
||||
Generated
-6
@@ -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",
|
||||
|
||||
Generated
+1
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<typeof TaskApps> = {
|
||||
title: "pages/TaskPage/TaskApps",
|
||||
component: TaskApps,
|
||||
@@ -33,24 +39,28 @@ type Story = StoryObj<typeof TaskApps>;
|
||||
|
||||
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"),
|
||||
|
||||
@@ -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<TaskAppsProps> = ({ workspace }) => {
|
||||
export const TaskApps: FC<TaskAppsProps> = ({ 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<TaskAppsProps> = ({ 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;
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ const TaskPage = () => {
|
||||
content = <TaskStartingAgent agent={agent} />;
|
||||
} else {
|
||||
const chatApp = getAllAppsWithAgent(workspace).find(
|
||||
(app) => app.id === workspace.latest_build.task_app_id,
|
||||
(app) => app.id === task.workspace_app_id,
|
||||
);
|
||||
content = (
|
||||
<PanelGroup autoSaveId="task" direction="horizontal">
|
||||
@@ -174,7 +174,7 @@ const TaskPage = () => {
|
||||
<div className="w-1 bg-border h-full hover:bg-border-hover transition-all relative" />
|
||||
</PanelResizeHandle>
|
||||
<Panel className="[&>*]:h-full">
|
||||
<TaskApps workspace={workspace} />
|
||||
<TaskApps task={task} workspace={workspace} />
|
||||
</Panel>
|
||||
</PanelGroup>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user