refactor: replace task prompt by workspace name in the topbar (#19531)

Fixes https://github.com/coder/coder/issues/19524

**Screenshot:**

<img width="1512" height="773" alt="Screenshot 2025-08-25 at 14 59 11"
src="https://github.com/user-attachments/assets/5d958302-04b3-4cd6-8e59-41a3048798be"
/>

**Demo:**


https://github.com/user-attachments/assets/040490ea-b276-48d7-9f3a-d8261d982bb5

**Changes:**
- Change "View workspace" button to icon + "Workspace"
- Updated the title to use the workspace name instead of the prompt
- Added a prompt button, so the user can see what is the prompt that is
running + copy it easily
This commit is contained in:
Bruno Quaresma
2025-08-26 12:24:52 -03:00
committed by GitHub
parent 5baaf2747d
commit a1546b5414
2 changed files with 68 additions and 15 deletions
+1 -5
View File
@@ -151,7 +151,7 @@ const TaskPage = () => {
return (
<>
<Helmet>
<title>{pageTitle(ellipsizeText(task.prompt, 64))}</title>
<title>{pageTitle(task.workspace.name)}</title>
</Helmet>
<div className="flex flex-col h-full">
@@ -265,7 +265,3 @@ export const data = {
} satisfies Task;
},
};
const ellipsizeText = (text: string, maxLength = 80): string => {
return text.length <= maxLength ? text : `${text.slice(0, maxLength - 3)}...`;
};
+67 -10
View File
@@ -5,7 +5,14 @@ import {
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { ArrowLeftIcon } from "lucide-react";
import { useClipboard } from "hooks";
import {
ArrowLeftIcon,
CheckIcon,
CopyIcon,
LaptopMinimalIcon,
TerminalIcon,
} from "lucide-react";
import type { Task } from "modules/tasks/tasks";
import type { FC } from "react";
import { Link as RouterLink } from "react-router";
@@ -15,7 +22,7 @@ type TaskTopbarProps = { task: Task };
export const TaskTopbar: FC<TaskTopbarProps> = ({ task }) => {
return (
<header className="flex items-center px-3 h-14 border-solid border-border border-0 border-b">
<header className="flex items-center px-3 py-4 border-solid border-border border-0 border-b">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
@@ -30,7 +37,9 @@ export const TaskTopbar: FC<TaskTopbarProps> = ({ task }) => {
</Tooltip>
</TooltipProvider>
<h1 className="m-0 text-base font-medium truncate">{task.prompt}</h1>
<h1 className="m-0 pl-2 text-base font-medium truncate">
{task.workspace.name}
</h1>
{task.workspace.latest_app_status?.uri && (
<div className="flex items-center gap-2 flex-wrap ml-4">
@@ -38,13 +47,61 @@ export const TaskTopbar: FC<TaskTopbarProps> = ({ task }) => {
</div>
)}
<Button asChild size="sm" variant="outline" className="ml-auto">
<RouterLink
to={`/@${task.workspace.owner_name}/${task.workspace.name}`}
>
View workspace
</RouterLink>
</Button>
<div className="ml-auto gap-2 flex items-center">
<TooltipProvider delayDuration={250}>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm">
<TerminalIcon />
Prompt
</Button>
</TooltipTrigger>
<TooltipContent className="max-w-xs bg-surface-secondary p-4">
<p className="m-0 mb-2 select-all text-sm font-normal text-content-primary leading-snug">
{task.prompt}
</p>
<CopyPromptButton prompt={task.prompt} />
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Button asChild variant="outline" size="sm">
<RouterLink
to={`/@${task.workspace.owner_name}/${task.workspace.name}`}
>
<LaptopMinimalIcon />
Workspace
</RouterLink>
</Button>
</div>
</header>
);
};
type CopyPromptButtonProps = { prompt: string };
const CopyPromptButton: FC<CopyPromptButtonProps> = ({ prompt }) => {
const { copyToClipboard, showCopiedSuccess } = useClipboard({
textToCopy: prompt,
});
return (
<Button
disabled={showCopiedSuccess}
onClick={copyToClipboard}
size="sm"
variant="subtle"
className="p-0 min-w-0"
>
{showCopiedSuccess ? (
<>
<CheckIcon /> Copied!
</>
) : (
<>
<CopyIcon /> Copy
</>
)}
</Button>
);
};