feat: redirect to the task page after creation (#18626)

Close https://github.com/coder/coder/issues/18184
This commit is contained in:
Bruno Quaresma
2025-06-27 14:45:42 +00:00
committed by GitHub
parent 1c87796b33
commit 29ef3a8ed6
2 changed files with 40 additions and 24 deletions
+26 -19
View File
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react";
import { expect, spyOn, userEvent, waitFor, within } from "@storybook/test";
import { API } from "api/api";
import { MockUsers } from "pages/UsersPage/storybookData/users";
import { reactRouterParameters } from "storybook-addon-remix-react-router";
import {
MockTemplate,
MockTemplateVersionExternalAuthGithub,
@@ -132,6 +133,23 @@ const newTaskData = {
export const CreateTaskSuccessfully: Story = {
decorators: [withProxyProvider()],
parameters: {
reactRouter: reactRouterParameters({
location: {
path: "/tasks",
},
routing: [
{
path: "/tasks",
useStoryElement: true,
},
{
path: "/tasks/:ownerName/:workspaceName",
element: <h1>Task page</h1>,
},
],
}),
},
beforeEach: () => {
spyOn(data, "fetchAITemplates").mockResolvedValue([MockTemplate]);
spyOn(data, "fetchTasks")
@@ -150,10 +168,8 @@ export const CreateTaskSuccessfully: Story = {
await userEvent.click(submitButton);
});
await step("Verify task in the table", async () => {
await canvas.findByRole("row", {
name: new RegExp(newTaskData.prompt, "i"),
});
await step("Redirects to the task page", async () => {
await canvas.findByText(/task page/i);
});
},
};
@@ -187,7 +203,7 @@ export const CreateTaskError: Story = {
},
};
export const WithExternalAuth: Story = {
export const WithAuthenticatedExternalAuth: Story = {
decorators: [withProxyProvider()],
beforeEach: () => {
spyOn(data, "fetchTasks")
@@ -201,26 +217,17 @@ export const WithExternalAuth: Story = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
await step("Run task", async () => {
const prompt = await canvas.findByLabelText(/prompt/i);
await userEvent.type(prompt, newTaskData.prompt);
const submitButton = canvas.getByRole("button", { name: /run task/i });
await waitFor(() => expect(submitButton).toBeEnabled());
await userEvent.click(submitButton);
});
await step("Verify task in the table", async () => {
await canvas.findByRole("row", {
name: new RegExp(newTaskData.prompt, "i"),
});
});
await step("Does not render external auth", async () => {
expect(
canvas.queryByText(/external authentication/),
).not.toBeInTheDocument();
});
},
parameters: {
chromatic: {
disableSnapshot: true,
},
},
};
export const MissingExternalAuth: Story = {
+14 -5
View File
@@ -52,7 +52,7 @@ import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName"
import { type FC, type ReactNode, useState } from "react";
import { Helmet } from "react-helmet-async";
import { useMutation, useQuery, useQueryClient } from "react-query";
import { Link as RouterLink } from "react-router-dom";
import { Link as RouterLink, useNavigate } from "react-router-dom";
import TextareaAutosize from "react-textarea-autosize";
import { pageTitle } from "utils/page";
import { relativeTime } from "utils/time";
@@ -163,6 +163,7 @@ const TaskFormSection: FC<{
filter: TasksFilter;
onFilterChange: (filter: TasksFilter) => void;
}> = ({ showFilter, filter, onFilterChange }) => {
const navigate = useNavigate();
const {
data: templates,
error,
@@ -190,7 +191,14 @@ const TaskFormSection: FC<{
}
return (
<>
<TaskForm templates={templates} />
<TaskForm
templates={templates}
onSuccess={(task) => {
navigate(
`/tasks/${task.workspace.owner_name}/${task.workspace.name}`,
);
}}
/>
{showFilter && (
<TasksFilter filter={filter} onFilterChange={onFilterChange} />
)}
@@ -202,9 +210,10 @@ type CreateTaskMutationFnProps = { prompt: string; templateId: string };
type TaskFormProps = {
templates: Template[];
onSuccess: (task: Task) => void;
};
const TaskForm: FC<TaskFormProps> = ({ templates }) => {
const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
const { user } = useAuthenticated();
const queryClient = useQueryClient();
const [selectedTemplateId, setSelectedTemplateId] = useState<string>(
@@ -229,10 +238,11 @@ const TaskForm: FC<TaskFormProps> = ({ templates }) => {
const createTaskMutation = useMutation({
mutationFn: async ({ prompt, templateId }: CreateTaskMutationFnProps) =>
data.createTask(prompt, user.id, templateId),
onSuccess: async () => {
onSuccess: async (task) => {
await queryClient.invalidateQueries({
queryKey: ["tasks"],
});
onSuccess(task);
},
});
@@ -249,7 +259,6 @@ const TaskForm: FC<TaskFormProps> = ({ templates }) => {
prompt,
templateId: templateID,
});
form.reset();
} catch (error) {
const message = getErrorMessage(error, "Error creating task");
const detail = getErrorDetail(error) ?? "Please try again";