mirror of
https://github.com/coder/coder.git
synced 2026-09-21 20:51:01 +08:00
fix: complete Tasks GA promotion (docs, site) (#20927)
## Summary Completes the Coder Tasks GA promotion by updating swagger tags and regenerating API documentation and updating the frontend API structure. ## Related Follows #20923 and #20921 which promoted Tasks from Beta/Experimental to GA. --- 🤖 This change was written by Claude Sonnet 4.5 Thinking using [mux](https://github.com/coder/mux) and reviewed by a human 🏂
This commit is contained in:
+7
-7
@@ -35,7 +35,7 @@ import (
|
||||
// @Security CoderSessionToken
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags Experimental
|
||||
// @Tags Tasks
|
||||
// @Param user path string true "Username, user ID, or 'me' for the authenticated user"
|
||||
// @Param request body codersdk.CreateTaskRequest true "Create task request"
|
||||
// @Success 201 {object} codersdk.Task
|
||||
@@ -401,7 +401,7 @@ func deriveTaskCurrentState(
|
||||
// @ID list-ai-tasks
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Experimental
|
||||
// @Tags Tasks
|
||||
// @Param q query string false "Search query for filtering tasks. Supports: owner:<username/uuid/me>, organization:<org-name/uuid>, status:<status>"
|
||||
// @Success 200 {object} codersdk.TasksListResponse
|
||||
// @Router /tasks [get]
|
||||
@@ -501,7 +501,7 @@ func (api *API) convertTasks(ctx context.Context, requesterID uuid.UUID, dbTasks
|
||||
// @ID get-ai-task-by-id-or-name
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Experimental
|
||||
// @Tags Tasks
|
||||
// @Param user path string true "Username, user ID, or 'me' for the authenticated user"
|
||||
// @Param task path string true "Task ID, or task name"
|
||||
// @Success 200 {object} codersdk.Task
|
||||
@@ -573,7 +573,7 @@ func (api *API) taskGet(rw http.ResponseWriter, r *http.Request) {
|
||||
// @Summary Delete AI task
|
||||
// @ID delete-ai-task
|
||||
// @Security CoderSessionToken
|
||||
// @Tags Experimental
|
||||
// @Tags Tasks
|
||||
// @Param user path string true "Username, user ID, or 'me' for the authenticated user"
|
||||
// @Param task path string true "Task ID, or task name"
|
||||
// @Success 202
|
||||
@@ -642,7 +642,7 @@ func (api *API) taskDelete(rw http.ResponseWriter, r *http.Request) {
|
||||
// @ID update-ai-task-input
|
||||
// @Security CoderSessionToken
|
||||
// @Accept json
|
||||
// @Tags Experimental
|
||||
// @Tags Tasks
|
||||
// @Param user path string true "Username, user ID, or 'me' for the authenticated user"
|
||||
// @Param task path string true "Task ID, or task name"
|
||||
// @Param request body codersdk.UpdateTaskInputRequest true "Update task input request"
|
||||
@@ -722,7 +722,7 @@ func (api *API) taskUpdateInput(rw http.ResponseWriter, r *http.Request) {
|
||||
// @ID send-input-to-ai-task
|
||||
// @Security CoderSessionToken
|
||||
// @Accept json
|
||||
// @Tags Experimental
|
||||
// @Tags Tasks
|
||||
// @Param user path string true "Username, user ID, or 'me' for the authenticated user"
|
||||
// @Param task path string true "Task ID, or task name"
|
||||
// @Param request body codersdk.TaskSendRequest true "Task input request"
|
||||
@@ -791,7 +791,7 @@ func (api *API) taskSend(rw http.ResponseWriter, r *http.Request) {
|
||||
// @ID get-ai-task-logs
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Experimental
|
||||
// @Tags Tasks
|
||||
// @Param user path string true "Username, user ID, or 'me' for the authenticated user"
|
||||
// @Param task path string true "Task ID, or task name"
|
||||
// @Success 200 {object} codersdk.TaskLogsResponse
|
||||
|
||||
Generated
+7
-7
@@ -5463,7 +5463,7 @@ const docTemplate = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Experimental"
|
||||
"Tasks"
|
||||
],
|
||||
"summary": "List AI tasks",
|
||||
"operationId": "list-ai-tasks",
|
||||
@@ -5499,7 +5499,7 @@ const docTemplate = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Experimental"
|
||||
"Tasks"
|
||||
],
|
||||
"summary": "Create a new AI task",
|
||||
"operationId": "create-a-new-ai-task",
|
||||
@@ -5542,7 +5542,7 @@ const docTemplate = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Experimental"
|
||||
"Tasks"
|
||||
],
|
||||
"summary": "Get AI task by ID or name",
|
||||
"operationId": "get-ai-task-by-id-or-name",
|
||||
@@ -5578,7 +5578,7 @@ const docTemplate = `{
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Experimental"
|
||||
"Tasks"
|
||||
],
|
||||
"summary": "Delete AI task",
|
||||
"operationId": "delete-ai-task",
|
||||
@@ -5616,7 +5616,7 @@ const docTemplate = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Experimental"
|
||||
"Tasks"
|
||||
],
|
||||
"summary": "Update AI task input",
|
||||
"operationId": "update-ai-task-input",
|
||||
@@ -5663,7 +5663,7 @@ const docTemplate = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Experimental"
|
||||
"Tasks"
|
||||
],
|
||||
"summary": "Get AI task logs",
|
||||
"operationId": "get-ai-task-logs",
|
||||
@@ -5704,7 +5704,7 @@ const docTemplate = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Experimental"
|
||||
"Tasks"
|
||||
],
|
||||
"summary": "Send input to AI task",
|
||||
"operationId": "send-input-to-ai-task",
|
||||
|
||||
Generated
+7
-7
@@ -4819,7 +4819,7 @@
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Experimental"],
|
||||
"tags": ["Tasks"],
|
||||
"summary": "List AI tasks",
|
||||
"operationId": "list-ai-tasks",
|
||||
"parameters": [
|
||||
@@ -4849,7 +4849,7 @@
|
||||
],
|
||||
"consumes": ["application/json"],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Experimental"],
|
||||
"tags": ["Tasks"],
|
||||
"summary": "Create a new AI task",
|
||||
"operationId": "create-a-new-ai-task",
|
||||
"parameters": [
|
||||
@@ -4888,7 +4888,7 @@
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Experimental"],
|
||||
"tags": ["Tasks"],
|
||||
"summary": "Get AI task by ID or name",
|
||||
"operationId": "get-ai-task-by-id-or-name",
|
||||
"parameters": [
|
||||
@@ -4922,7 +4922,7 @@
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"tags": ["Experimental"],
|
||||
"tags": ["Tasks"],
|
||||
"summary": "Delete AI task",
|
||||
"operationId": "delete-ai-task",
|
||||
"parameters": [
|
||||
@@ -4956,7 +4956,7 @@
|
||||
}
|
||||
],
|
||||
"consumes": ["application/json"],
|
||||
"tags": ["Experimental"],
|
||||
"tags": ["Tasks"],
|
||||
"summary": "Update AI task input",
|
||||
"operationId": "update-ai-task-input",
|
||||
"parameters": [
|
||||
@@ -4999,7 +4999,7 @@
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Experimental"],
|
||||
"tags": ["Tasks"],
|
||||
"summary": "Get AI task logs",
|
||||
"operationId": "get-ai-task-logs",
|
||||
"parameters": [
|
||||
@@ -5036,7 +5036,7 @@
|
||||
}
|
||||
],
|
||||
"consumes": ["application/json"],
|
||||
"tags": ["Experimental"],
|
||||
"tags": ["Tasks"],
|
||||
"summary": "Send input to AI task",
|
||||
"operationId": "send-input-to-ai-task",
|
||||
"parameters": [
|
||||
|
||||
+4
-4
@@ -1166,10 +1166,6 @@
|
||||
"title": "Enterprise",
|
||||
"path": "./reference/api/enterprise.md"
|
||||
},
|
||||
{
|
||||
"title": "Experimental",
|
||||
"path": "./reference/api/experimental.md"
|
||||
},
|
||||
{
|
||||
"title": "Files",
|
||||
"path": "./reference/api/files.md"
|
||||
@@ -1214,6 +1210,10 @@
|
||||
"title": "Schemas",
|
||||
"path": "./reference/api/schemas.md"
|
||||
},
|
||||
{
|
||||
"title": "Tasks",
|
||||
"path": "./reference/api/tasks.md"
|
||||
},
|
||||
{
|
||||
"title": "Templates",
|
||||
"path": "./reference/api/templates.md"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Experimental
|
||||
# Tasks
|
||||
|
||||
## List AI tasks
|
||||
|
||||
+16
-16
@@ -2644,22 +2644,6 @@ class ApiMethods {
|
||||
markAllInboxNotificationsAsRead = async () => {
|
||||
await this.axios.put<void>("/api/v2/notifications/inbox/mark-all-as-read");
|
||||
};
|
||||
}
|
||||
|
||||
// Experimental API methods call endpoints under the /api/experimental/ prefix.
|
||||
// These endpoints are not stable and may change or be removed at any time.
|
||||
//
|
||||
// All methods must be defined with arrow function syntax. See the docstring
|
||||
// above the ApiMethods class for a full explanation.
|
||||
|
||||
export type TaskFeedbackRating = "good" | "okay" | "bad";
|
||||
|
||||
export type CreateTaskFeedbackRequest = {
|
||||
rate: TaskFeedbackRating;
|
||||
comment?: string;
|
||||
};
|
||||
class ExperimentalApiMethods {
|
||||
constructor(protected readonly axios: AxiosInstance) {}
|
||||
|
||||
createTask = async (
|
||||
user: string,
|
||||
@@ -2716,6 +2700,22 @@ class ExperimentalApiMethods {
|
||||
setTimeout(() => res(), 500);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export type TaskFeedbackRating = "good" | "okay" | "bad";
|
||||
|
||||
export type CreateTaskFeedbackRequest = {
|
||||
rate: TaskFeedbackRating;
|
||||
comment?: string;
|
||||
};
|
||||
|
||||
// Experimental API methods call endpoints under the /api/experimental/ prefix.
|
||||
// These endpoints are not stable and may change or be removed at any time.
|
||||
//
|
||||
// All methods must be defined with arrow function syntax. See the docstring
|
||||
// above the ApiMethods class for a full explanation.
|
||||
class ExperimentalApiMethods {
|
||||
constructor(protected readonly axios: AxiosInstance) {}
|
||||
|
||||
getAIBridgeInterceptions = async (options: SearchParamOptions) => {
|
||||
const url = getURLWithSearchParams(
|
||||
|
||||
@@ -207,7 +207,7 @@ const TasksNavItem: FC<TasksNavItemProps> = ({ user }) => {
|
||||
};
|
||||
const { data: idleCount } = useQuery({
|
||||
queryKey: ["tasks", filter],
|
||||
queryFn: () => API.experimental.getTasks(filter),
|
||||
queryFn: () => API.getTasks(filter),
|
||||
refetchInterval: 1_000 * 60,
|
||||
enabled: canSeeTasks,
|
||||
refetchOnWindowFocus: true,
|
||||
|
||||
@@ -27,7 +27,7 @@ export const DeleteTaskSuccess: Story = {
|
||||
},
|
||||
},
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "deleteTask").mockResolvedValue();
|
||||
spyOn(API, "deleteTask").mockResolvedValue();
|
||||
},
|
||||
play: async ({ canvasElement, step }) => {
|
||||
const body = within(canvasElement.ownerDocument.body);
|
||||
@@ -39,7 +39,7 @@ export const DeleteTaskSuccess: Story = {
|
||||
await userEvent.click(confirmButton);
|
||||
await step("Confirm delete", async () => {
|
||||
await waitFor(() => {
|
||||
expect(API.experimental.deleteTask).toHaveBeenCalledWith(
|
||||
expect(API.deleteTask).toHaveBeenCalledWith(
|
||||
MockTask.owner_name,
|
||||
MockTask.id,
|
||||
);
|
||||
|
||||
@@ -20,7 +20,7 @@ export const TaskDeleteDialog: FC<TaskDeleteDialogProps> = ({
|
||||
}) => {
|
||||
const queryClient = new QueryClient();
|
||||
const deleteTaskMutation = useMutation({
|
||||
mutationFn: () => API.experimental.deleteTask(task.owner_name, task.id),
|
||||
mutationFn: () => API.deleteTask(task.owner_name, task.id),
|
||||
onSuccess: async () => {
|
||||
await queryClient.invalidateQueries({ queryKey: ["tasks"] });
|
||||
},
|
||||
|
||||
@@ -21,7 +21,7 @@ export const Idle: Story = {};
|
||||
|
||||
export const Submitting: Story = {
|
||||
beforeEach: async () => {
|
||||
spyOn(API.experimental, "createTaskFeedback").mockImplementation(() => {
|
||||
spyOn(API, "createTaskFeedback").mockImplementation(() => {
|
||||
return new Promise(() => {});
|
||||
});
|
||||
},
|
||||
@@ -53,7 +53,7 @@ export const Success: Story = {
|
||||
},
|
||||
decorators: [withGlobalSnackbar],
|
||||
beforeEach: async () => {
|
||||
spyOn(API.experimental, "createTaskFeedback").mockResolvedValue();
|
||||
spyOn(API, "createTaskFeedback").mockResolvedValue();
|
||||
},
|
||||
play: async ({ canvasElement, step }) => {
|
||||
const body = within(canvasElement.ownerDocument.body);
|
||||
@@ -77,20 +77,17 @@ export const Success: Story = {
|
||||
|
||||
step("submitted successfully", async () => {
|
||||
await body.findByText("Feedback submitted successfully");
|
||||
expect(API.experimental.createTaskFeedback).toHaveBeenCalledWith(
|
||||
MockTask.id,
|
||||
{
|
||||
rate: "regular",
|
||||
comment: "This is my comment",
|
||||
},
|
||||
);
|
||||
expect(API.createTaskFeedback).toHaveBeenCalledWith(MockTask.id, {
|
||||
rate: "regular",
|
||||
comment: "This is my comment",
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Failure: Story = {
|
||||
beforeEach: async () => {
|
||||
spyOn(API.experimental, "createTaskFeedback").mockRejectedValue(
|
||||
spyOn(API, "createTaskFeedback").mockRejectedValue(
|
||||
mockApiError({
|
||||
message: "Failed to submit feedback",
|
||||
detail: "Server is down",
|
||||
|
||||
@@ -42,7 +42,7 @@ export const TaskFeedbackDialog: FC<TaskFeedbackDialogProps> = ({
|
||||
isPending,
|
||||
} = useMutation({
|
||||
mutationFn: (req: CreateTaskFeedbackRequest) =>
|
||||
API.experimental.createTaskFeedback(taskId, req),
|
||||
API.createTaskFeedback(taskId, req),
|
||||
onSuccess: () => {
|
||||
displaySuccess("Feedback submitted successfully");
|
||||
},
|
||||
|
||||
@@ -114,7 +114,7 @@ export const SubmitDisabledWhenPromptEmpty: Story = {
|
||||
export const Submitting: Story = {
|
||||
decorators: [withGlobalSnackbar],
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "createTask").mockImplementation(
|
||||
spyOn(API, "createTask").mockImplementation(
|
||||
() =>
|
||||
// Never resolve to keep the component in the submitting state for visual testing.
|
||||
new Promise(() => {}),
|
||||
@@ -153,7 +153,7 @@ export const OnSuccess: Story = {
|
||||
...MockTemplate,
|
||||
active_version_id: activeVersionId,
|
||||
});
|
||||
spyOn(API.experimental, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "createTask").mockResolvedValue(MockTask);
|
||||
},
|
||||
play: async ({ canvasElement, step }) => {
|
||||
const canvas = within(canvasElement);
|
||||
@@ -167,14 +167,11 @@ export const OnSuccess: Story = {
|
||||
});
|
||||
|
||||
await step("Uses latest template version", () => {
|
||||
expect(API.experimental.createTask).toHaveBeenCalledWith(
|
||||
MockUserOwner.id,
|
||||
{
|
||||
input: MockNewTaskData.initial_prompt,
|
||||
template_version_id: `${MockTemplate.active_version_id}-latest`,
|
||||
template_version_preset_id: undefined,
|
||||
},
|
||||
);
|
||||
expect(API.createTask).toHaveBeenCalledWith(MockUserOwner.id, {
|
||||
input: MockNewTaskData.initial_prompt,
|
||||
template_version_id: `${MockTemplate.active_version_id}-latest`,
|
||||
template_version_preset_id: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
await step("Displays success message", async () => {
|
||||
@@ -232,7 +229,7 @@ export const ChangeTemplate: Story = {
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
});
|
||||
spyOn(API.experimental, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "createTask").mockResolvedValue(MockTask);
|
||||
},
|
||||
play: async ({ canvasElement, step }) => {
|
||||
const canvas = within(canvasElement);
|
||||
@@ -268,7 +265,7 @@ export const SelectTemplateVersion: Story = {
|
||||
name: "v1.0.0",
|
||||
},
|
||||
]);
|
||||
spyOn(API.experimental, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "createTask").mockResolvedValue(MockTask);
|
||||
},
|
||||
play: async ({ canvasElement, step }) => {
|
||||
const canvas = within(canvasElement);
|
||||
@@ -295,14 +292,11 @@ export const SelectTemplateVersion: Story = {
|
||||
});
|
||||
|
||||
await step("Uses selected version", () => {
|
||||
expect(API.experimental.createTask).toHaveBeenCalledWith(
|
||||
MockUserOwner.id,
|
||||
{
|
||||
input: MockNewTaskData.initial_prompt,
|
||||
template_version_id: "test-template-version-2",
|
||||
template_version_preset_id: undefined,
|
||||
},
|
||||
);
|
||||
expect(API.createTask).toHaveBeenCalledWith(MockUserOwner.id, {
|
||||
input: MockNewTaskData.initial_prompt,
|
||||
template_version_id: "test-template-version-2",
|
||||
template_version_preset_id: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
await step("Displays success message", async () => {
|
||||
@@ -317,8 +311,8 @@ export const OnError: Story = {
|
||||
decorators: [withGlobalSnackbar],
|
||||
beforeEach: () => {
|
||||
spyOn(API, "getTemplate").mockResolvedValue(MockTemplate);
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API.experimental, "createTask").mockRejectedValue(
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "createTask").mockRejectedValue(
|
||||
mockApiError({
|
||||
message: "Failed to create task",
|
||||
detail: "You don't have permission to create tasks.",
|
||||
@@ -344,10 +338,10 @@ export const OnError: Story = {
|
||||
|
||||
export const AuthenticatedExternalAuth: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks")
|
||||
spyOn(API, "getTasks")
|
||||
.mockResolvedValueOnce(MockTasks)
|
||||
.mockResolvedValue([MockNewTaskData, ...MockTasks]);
|
||||
spyOn(API.experimental, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTemplateVersionExternalAuth").mockResolvedValue([
|
||||
MockTemplateVersionExternalAuthGithubAuthenticated,
|
||||
]);
|
||||
@@ -370,10 +364,10 @@ export const AuthenticatedExternalAuth: Story = {
|
||||
|
||||
export const MissingExternalAuth: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks")
|
||||
spyOn(API, "getTasks")
|
||||
.mockResolvedValueOnce(MockTasks)
|
||||
.mockResolvedValue([MockNewTaskData, ...MockTasks]);
|
||||
spyOn(API.experimental, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTemplateVersionExternalAuth").mockResolvedValue([
|
||||
MockTemplateVersionExternalAuthGithub,
|
||||
]);
|
||||
@@ -396,10 +390,10 @@ export const MissingExternalAuth: Story = {
|
||||
|
||||
export const ExternalAuthError: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks")
|
||||
spyOn(API, "getTasks")
|
||||
.mockResolvedValueOnce(MockTasks)
|
||||
.mockResolvedValue([MockNewTaskData, ...MockTasks]);
|
||||
spyOn(API.experimental, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "createTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTemplateVersionExternalAuth").mockRejectedValue(
|
||||
mockApiError({
|
||||
message: "Failed to load external auth",
|
||||
|
||||
@@ -193,7 +193,7 @@ const CreateTaskForm: FC<CreateTaskFormProps> = ({ templates, onSuccess }) => {
|
||||
mutationFn: async ({ prompt }: CreateTaskMutationFnProps) => {
|
||||
// Users with updateTemplates permission can select the version to use.
|
||||
if (permissions.updateTemplates) {
|
||||
return API.experimental.createTask(user.id, {
|
||||
return API.createTask(user.id, {
|
||||
input: prompt,
|
||||
template_version_id: selectedVersionId,
|
||||
template_version_preset_id: selectedPresetId,
|
||||
@@ -453,7 +453,7 @@ async function createTaskWithLatestTemplateVersion(
|
||||
presetId: string | undefined,
|
||||
): Promise<Task> {
|
||||
const template = await API.getTemplate(templateId);
|
||||
return API.experimental.createTask(userId, {
|
||||
return API.createTask(userId, {
|
||||
input,
|
||||
template_version_id: template.active_version_id,
|
||||
template_version_preset_id: presetId,
|
||||
|
||||
@@ -49,13 +49,13 @@ type Story = StoryObj<typeof TasksSidebar>;
|
||||
|
||||
export const Loading: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks").mockReturnValue(new Promise(() => {}));
|
||||
spyOn(API, "getTasks").mockReturnValue(new Promise(() => {}));
|
||||
},
|
||||
};
|
||||
|
||||
export const Failed: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks").mockRejectedValue(
|
||||
spyOn(API, "getTasks").mockRejectedValue(
|
||||
mockApiError({
|
||||
message: "Failed to fetch tasks",
|
||||
}),
|
||||
@@ -65,7 +65,7 @@ export const Failed: Story = {
|
||||
|
||||
export const Loaded: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -82,13 +82,13 @@ export const DisplayName: Story = {
|
||||
|
||||
export const Empty: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue([]);
|
||||
spyOn(API, "getTasks").mockResolvedValue([]);
|
||||
},
|
||||
};
|
||||
|
||||
export const Closed: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
@@ -99,7 +99,7 @@ export const Closed: Story = {
|
||||
|
||||
export const OpenOptionsMenu: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
@@ -112,7 +112,7 @@ export const OpenOptionsMenu: Story = {
|
||||
|
||||
export const OpenDeleteDialog: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
},
|
||||
play: async ({ canvasElement, step }) => {
|
||||
await step("Open menu", async () => {
|
||||
|
||||
@@ -135,7 +135,7 @@ const TasksSidebarGroup: FC<TasksSidebarGroupProps> = ({ owner }) => {
|
||||
const filter: TasksFilter = { owner };
|
||||
const tasksQuery = useQuery({
|
||||
queryKey: ["tasks", filter],
|
||||
queryFn: () => API.experimental.getTasks(filter),
|
||||
queryFn: () => API.getTasks(filter),
|
||||
refetchInterval: 10_000,
|
||||
});
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ const meta: Meta<typeof TaskPage> = {
|
||||
component: TaskPage,
|
||||
decorators: [withProxyProvider(), withAuthProvider],
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
},
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
@@ -88,13 +88,11 @@ type Story = StoryObj<typeof TaskPage>;
|
||||
|
||||
export const LoadingTask: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockImplementation(
|
||||
() => new Promise(() => {}),
|
||||
);
|
||||
spyOn(API, "getTask").mockImplementation(() => new Promise(() => {}));
|
||||
},
|
||||
play: async () => {
|
||||
await waitFor(() => {
|
||||
expect(API.experimental.getTask).toHaveBeenCalledWith(
|
||||
expect(API.getTask).toHaveBeenCalledWith(
|
||||
MockTask.owner_name,
|
||||
MockTask.id,
|
||||
);
|
||||
@@ -104,7 +102,7 @@ export const LoadingTask: Story = {
|
||||
|
||||
export const LoadingWorkspace: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockImplementation(
|
||||
() => new Promise(() => {}),
|
||||
);
|
||||
@@ -113,7 +111,7 @@ export const LoadingWorkspace: Story = {
|
||||
|
||||
export const LoadingTaskError: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockRejectedValue(
|
||||
spyOn(API, "getTask").mockRejectedValue(
|
||||
mockApiError({
|
||||
message: "Failed to load task",
|
||||
detail: "You don't have permission to access this resource.",
|
||||
@@ -124,7 +122,7 @@ export const LoadingTaskError: Story = {
|
||||
|
||||
export const LoadingWorkspaceError: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockRejectedValue(
|
||||
mockApiError({
|
||||
message: "Failed to load workspace",
|
||||
@@ -136,7 +134,7 @@ export const LoadingWorkspaceError: Story = {
|
||||
|
||||
export const WaitingOnBuild: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(
|
||||
MockStartingWorkspace,
|
||||
);
|
||||
@@ -145,7 +143,7 @@ export const WaitingOnBuild: Story = {
|
||||
|
||||
export const FailedBuild: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(
|
||||
MockFailedWorkspace,
|
||||
);
|
||||
@@ -154,7 +152,7 @@ export const FailedBuild: Story = {
|
||||
|
||||
export const TerminatedBuild: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(
|
||||
MockStoppedWorkspace,
|
||||
);
|
||||
@@ -163,7 +161,7 @@ export const TerminatedBuild: Story = {
|
||||
|
||||
export const TerminatedBuildWithStatus: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue({
|
||||
...MockStoppedWorkspace,
|
||||
latest_app_status: MockWorkspaceAppStatus,
|
||||
@@ -173,7 +171,7 @@ export const TerminatedBuildWithStatus: Story = {
|
||||
|
||||
export const DeletedWorkspace: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(
|
||||
MockDeletedWorkspace,
|
||||
);
|
||||
@@ -182,7 +180,7 @@ export const DeletedWorkspace: Story = {
|
||||
|
||||
export const WaitingStartupScripts: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue({
|
||||
...MockWorkspace,
|
||||
latest_build: {
|
||||
@@ -336,7 +334,7 @@ export const SidebarAppNotFound: Story = {
|
||||
MockClaudeCodeApp,
|
||||
MockVSCodeApp,
|
||||
);
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue({
|
||||
spyOn(API, "getTask").mockResolvedValue({
|
||||
...task,
|
||||
workspace_app_id: null,
|
||||
});
|
||||
@@ -350,7 +348,7 @@ export const SidebarAppHealthDisabled: Story = {
|
||||
{ ...MockClaudeCodeApp, health: "disabled" },
|
||||
MockVSCodeApp,
|
||||
);
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace);
|
||||
},
|
||||
};
|
||||
@@ -361,7 +359,7 @@ export const SidebarAppInitializing: Story = {
|
||||
{ ...MockClaudeCodeApp, health: "initializing" },
|
||||
MockVSCodeApp,
|
||||
);
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace);
|
||||
},
|
||||
};
|
||||
@@ -372,7 +370,7 @@ export const SidebarAppHealthy: Story = {
|
||||
{ ...MockClaudeCodeApp, health: "healthy" },
|
||||
MockVSCodeApp,
|
||||
);
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace);
|
||||
},
|
||||
};
|
||||
@@ -383,7 +381,7 @@ export const SidebarAppUnhealthy: Story = {
|
||||
{ ...MockClaudeCodeApp, health: "unhealthy" },
|
||||
MockVSCodeApp,
|
||||
);
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace);
|
||||
},
|
||||
};
|
||||
@@ -394,7 +392,7 @@ const mainAppHealthStory = (health: WorkspaceApp["health"]) => ({
|
||||
...MockVSCodeApp,
|
||||
health,
|
||||
});
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace);
|
||||
},
|
||||
});
|
||||
@@ -410,7 +408,7 @@ export const Active: Story = {
|
||||
MockClaudeCodeApp,
|
||||
MockVSCodeApp,
|
||||
);
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace);
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
@@ -433,7 +431,7 @@ export const ActivePreview: Story = {
|
||||
MockClaudeCodeApp,
|
||||
MockVSCodeApp,
|
||||
);
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getTask").mockResolvedValue(task);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(workspace);
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
@@ -446,7 +444,7 @@ export const ActivePreview: Story = {
|
||||
export const WorkspaceStarting: Story = {
|
||||
decorators: [withGlobalSnackbar],
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(
|
||||
MockStoppedWorkspace,
|
||||
);
|
||||
@@ -484,7 +482,7 @@ export const WorkspaceStarting: Story = {
|
||||
export const WorkspaceStartFailure: Story = {
|
||||
decorators: [withGlobalSnackbar],
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(
|
||||
MockStoppedWorkspace,
|
||||
);
|
||||
@@ -522,7 +520,7 @@ export const WorkspaceStartFailure: Story = {
|
||||
|
||||
export const WorkspaceStartFailureWithDialog: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API.experimental, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getTask").mockResolvedValue(MockTask);
|
||||
spyOn(API, "getWorkspaceByOwnerAndName").mockResolvedValue(
|
||||
MockStoppedWorkspace,
|
||||
);
|
||||
|
||||
@@ -62,7 +62,7 @@ const TaskPage = () => {
|
||||
};
|
||||
const { data: task, ...taskQuery } = useQuery({
|
||||
queryKey: ["tasks", username, taskId],
|
||||
queryFn: () => API.experimental.getTask(username, taskId),
|
||||
queryFn: () => API.getTask(username, taskId),
|
||||
refetchInterval: ({ state }) => {
|
||||
return state.error ? false : 5_000;
|
||||
},
|
||||
|
||||
@@ -83,7 +83,7 @@ export const LoadingTemplatesError: Story = {
|
||||
export const LoadingTasks: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]);
|
||||
spyOn(API.experimental, "getTasks").mockImplementation(
|
||||
spyOn(API, "getTasks").mockImplementation(
|
||||
() => new Promise(() => 1000 * 60 * 60),
|
||||
);
|
||||
},
|
||||
@@ -101,7 +101,7 @@ export const LoadingTasks: Story = {
|
||||
export const LoadingTasksError: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]);
|
||||
spyOn(API.experimental, "getTasks").mockRejectedValue(
|
||||
spyOn(API, "getTasks").mockRejectedValue(
|
||||
mockApiError({
|
||||
message: "Failed to load tasks",
|
||||
}),
|
||||
@@ -112,14 +112,14 @@ export const LoadingTasksError: Story = {
|
||||
export const EmptyTasks: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]);
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue([]);
|
||||
spyOn(API, "getTasks").mockResolvedValue([]);
|
||||
},
|
||||
};
|
||||
|
||||
export const LoadedTasks: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]);
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -142,7 +142,7 @@ export const LoadedTasksWaitingForInputTab: Story = {
|
||||
beforeEach: () => {
|
||||
const [firstTask, ...otherTasks] = MockTasks;
|
||||
spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]);
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue([
|
||||
spyOn(API, "getTasks").mockResolvedValue([
|
||||
{
|
||||
...firstTask,
|
||||
current_state: {
|
||||
@@ -173,7 +173,7 @@ export const NonAdmin: Story = {
|
||||
},
|
||||
beforeEach: () => {
|
||||
spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]);
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
},
|
||||
play: async ({ canvasElement, step }) => {
|
||||
const canvas = within(canvasElement);
|
||||
@@ -190,7 +190,7 @@ export const NonAdmin: Story = {
|
||||
export const OpenDeleteDialog: Story = {
|
||||
beforeEach: () => {
|
||||
spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]);
|
||||
spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks);
|
||||
spyOn(API, "getTasks").mockResolvedValue(MockTasks);
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
@@ -40,7 +40,7 @@ const TasksPage: FC = () => {
|
||||
};
|
||||
const tasksQuery = useQuery({
|
||||
queryKey: ["tasks", filter],
|
||||
queryFn: () => API.experimental.getTasks(filter),
|
||||
queryFn: () => API.getTasks(filter),
|
||||
refetchInterval: 10_000,
|
||||
});
|
||||
const idleTasks = tasksQuery.data?.filter(
|
||||
|
||||
Reference in New Issue
Block a user