feat(site): use display name field for tasks (#20918)

## Description

This PR updates the frontend to use the new `display_name` field for
tasks. In the tasks list view, `display_name` replaces `initial_prompt`,
and in the tasks sidebar, `display_name` replaces `name`. This is a
follow-up to https://github.com/coder/coder/pull/20856, which introduced
the `display_name` field in the backend.

## Changes

- Display `task.display_name` instead of `task.initial_prompt` in the
tasks table
- Display `task.display_name` instead of `task.name` in the task sidebar
view
- Updated mock data to include `display_name` for all test tasks
- Added Storybook story to showcase display name rendering with
different lengths (short, max length with ellipsis, and edge cases)

Follow-up: https://github.com/coder/coder/pull/20856
Closes: https://github.com/coder/coder/issues/20801
This commit is contained in:
Susana Ferreira
2025-11-25 16:29:54 +00:00
committed by GitHub
parent 02bac71421
commit 2f399eafae
5 changed files with 84 additions and 11 deletions
@@ -1,4 +1,9 @@
import { MockTasks, MockUserOwner, mockApiError } from "testHelpers/entities";
import {
MockDisplayNameTasks,
MockTasks,
MockUserOwner,
mockApiError,
} from "testHelpers/entities";
import { withAuthProvider } from "testHelpers/storybook";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { API } from "api/api";
@@ -64,6 +69,17 @@ export const Loaded: Story = {
},
};
export const DisplayName: Story = {
parameters: {
queries: [
{
key: ["tasks", { owner: MockUserOwner.username }],
data: MockDisplayNameTasks,
},
],
},
};
export const Empty: Story = {
beforeEach: () => {
spyOn(API.experimental, "getTasks").mockResolvedValue([]);
@@ -203,7 +203,9 @@ const TaskSidebarMenuItem: FC<TaskSidebarMenuItemProps> = ({ task }) => {
}}
>
<TaskSidebarMenuItemStatus task={task} />
<span className="truncate">{task.name}</span>
<span className="block max-w-[220px] truncate">
{task.display_name}
</span>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
@@ -1,4 +1,5 @@
import {
MockDisplayNameTasks,
MockInitializingTasks,
MockTasks,
MockTemplate,
@@ -122,6 +123,21 @@ export const LoadedTasks: Story = {
},
};
export const DisplayName: Story = {
parameters: {
queries: [
{
key: ["tasks", { owner: MockUserOwner.username }],
data: MockDisplayNameTasks,
},
{
key: getTemplatesQueryKey({ q: "has-ai-task:true" }),
data: [MockTemplate],
},
],
},
};
export const LoadedTasksWaitingForInputTab: Story = {
beforeEach: () => {
const [firstTask, ...otherTasks] = MockTasks;
+2 -2
View File
@@ -135,8 +135,8 @@ const TaskRow: FC<TaskRowProps> = ({ task }) => {
<TableCell>
<AvatarData
title={
<span className="block max-w-[520px] overflow-hidden text-ellipsis whitespace-nowrap">
{task.initial_prompt}
<span className="block max-w-[520px] truncate">
{task.display_name}
</span>
}
subtitle={templateDisplayName}
+46 -7
View File
@@ -4996,8 +4996,8 @@ export const MockAIPromptPresets: TypesGen.Preset[] = [
export const MockTask = {
id: "test-task",
name: "task-wild-test-123",
display_name: "Task wild test 123",
name: "wild-test-123",
display_name: "Task wild test",
organization_id: MockOrganization.id,
owner_id: MockUserOwner.id,
owner_name: MockUserOwner.username,
@@ -5038,6 +5038,7 @@ export const MockTasks = [
...MockTask,
id: "task-2",
name: "fix-avatar-size",
display_name: "Fix avatar size",
current_state: {
...MockTask.current_state,
message: "Avatar size fixed!",
@@ -5048,6 +5049,7 @@ export const MockTasks = [
...MockTask,
id: "task-3",
name: "fix-accessibility-issues",
display_name: "Fix accessibility issues",
current_state: {
...MockTask.current_state,
message: "Accessibility issues fixed!",
@@ -5060,7 +5062,8 @@ export const MockInitializingTasks = [
{
...MockTask,
id: "task-1",
name: "task-workspace-pending",
name: "workspace-pending",
display_name: "Workspace pending",
initial_prompt: "Task Workspace Pending",
status: "initializing",
current_state: {
@@ -5073,7 +5076,8 @@ export const MockInitializingTasks = [
{
...MockTask,
id: "task-2",
name: "task-workspace-starting",
name: "workspace-starting",
display_name: "Workspace starting",
initial_prompt: "Task Workspace Starting",
status: "initializing",
current_state: {
@@ -5086,7 +5090,8 @@ export const MockInitializingTasks = [
{
...MockTask,
id: "task-3",
name: "task-agent-connecting",
name: "agent-connecting",
display_name: "Agent connecting",
initial_prompt: "Task Agent Connecting",
status: "initializing",
current_state: {
@@ -5099,7 +5104,8 @@ export const MockInitializingTasks = [
{
...MockTask,
id: "task-4",
name: "task-agent-starting",
name: "agent-starting",
display_name: "Agent Starting",
initial_prompt: "Task Agent Starting",
status: "initializing",
current_state: {
@@ -5112,7 +5118,8 @@ export const MockInitializingTasks = [
{
...MockTask,
id: "task-5",
name: "task-app-initializing",
name: "app-initializing",
display_name: "App Initializing",
initial_prompt: "Task App Initializing",
status: "initializing",
current_state: {
@@ -5124,6 +5131,38 @@ export const MockInitializingTasks = [
},
] satisfies TypesGen.Task[];
export const MockDisplayNameTasks = [
{
...MockTask,
},
{
...MockTask,
id: "task-4",
name: "validate-email-regex",
// Display name with 64 characters with ellipsis
display_name:
"Write a function to validate email addresses using regular expr…",
current_state: {
...MockTask.current_state,
message: "Email validation complete!",
state: "complete",
},
},
{
...MockTask,
id: "payment-api-tests",
name: "payment-api-tests",
// Display name with 81 characters
display_name:
"Create a comprehensive test suite for the new payment processing microservice API",
current_state: {
...MockTask.current_state,
message: "Test suite created!",
state: "complete",
},
},
] satisfies TypesGen.Task[];
export const MockInterception: TypesGen.AIBridgeInterception = {
id: "5c1da48a-9eb0-440e-9c82-5bc5692a603d",
initiator: {