Skip to content

Commit 79309b8

Browse files
author
Bruno Bergher
committed
More task ehader visual tweaks
1 parent 8f6a091 commit 79309b8

File tree

4 files changed

+166
-131
lines changed

4 files changed

+166
-131
lines changed

webview-ui/src/components/chat/ContextWindowProgress.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const ContextWindowProgress = ({ contextWindow, contextTokens, maxTokens
5555

5656
return (
5757
<>
58-
<div className="flex items-center gap-2 flex-1 whitespace-nowrap px-2">
58+
<div className="flex items-center gap-2 flex-1 whitespace-nowrap">
5959
<div data-testid="context-tokens-count">{formatLargeNumber(safeContextTokens)}</div>
6060
<StandardTooltip content={tooltipContent} side="top" sideOffset={8}>
6161
<div className="flex-1 relative">

webview-ui/src/components/chat/ShareButton.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ import {
2727
interface ShareButtonProps {
2828
item?: HistoryItem
2929
disabled?: boolean
30+
showLabel?: boolean
3031
}
3132

32-
export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => {
33+
export const ShareButton = ({ item, disabled = false, showLabel = false }: ShareButtonProps) => {
3334
const [shareDropdownOpen, setShareDropdownOpen] = useState(false)
3435
const [connectModalOpen, setConnectModalOpen] = useState(false)
3536
const [shareSuccess, setShareSuccess] = useState<{ visibility: ShareVisibility; url: string } | null>(null)
@@ -156,14 +157,20 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => {
156157
<PopoverTrigger asChild>
157158
<Button
158159
variant="ghost"
159-
size="icon"
160+
size={showLabel ? "sm" : "icon"}
160161
disabled={disabled || shareButtonState.disabled}
161-
className="h-7 w-7 p-1.5 hover:bg-vscode-toolbar-hoverBackground"
162+
className={
163+
showLabel
164+
? "h-7 px-2 hover:bg-vscode-toolbar-hoverBackground"
165+
: "h-7 w-7 p-1.5 hover:bg-vscode-toolbar-hoverBackground"
166+
}
162167
onClick={handleShareButtonClick}>
163168
<Share size={16} />
169+
{showLabel && <span className="ml-0">{t("chat:task.share")}</span>}
164170
</Button>
165171
</PopoverTrigger>
166172
</StandardTooltip>
173+
167174
<PopoverContent className="w-56 p-0" align="start">
168175
{shareSuccess ? (
169176
<div className="p-3">
@@ -218,11 +225,16 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => {
218225
<StandardTooltip content={shareButtonState.title}>
219226
<Button
220227
variant="ghost"
221-
size="icon"
228+
size={showLabel ? "sm" : "icon"}
222229
disabled={disabled || shareButtonState.disabled}
223-
className="h-7 w-7 p-1.5 hover:bg-vscode-toolbar-hoverBackground"
230+
className={
231+
showLabel
232+
? "h-7 px-2 hover:bg-vscode-toolbar-hoverBackground"
233+
: "h-7 w-7 p-1.5 hover:bg-vscode-toolbar-hoverBackground"
234+
}
224235
onClick={handleShareButtonClick}>
225236
<Share size={16} />
237+
{showLabel && <span className="ml-1.5">{t("chat:task.share")}</span>}
226238
</Button>
227239
</StandardTooltip>
228240
)}
Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useState } from "react"
2-
import prettyBytes from "pretty-bytes"
32
import { useTranslation } from "react-i18next"
43

54
import type { HistoryItem } from "@roo-code/types"
@@ -22,48 +21,54 @@ export const TaskActions = ({ item, buttonsDisabled }: TaskActionsProps) => {
2221
const { copyWithFeedback, showCopyFeedback } = useCopyToClipboard()
2322

2423
return (
25-
<div className="flex flex-row gap-1">
26-
<ShareButton item={item} disabled={false} />
27-
<IconButton
28-
iconClass="codicon-desktop-download"
29-
title={t("chat:task.export")}
30-
onClick={() => vscode.postMessage({ type: "exportCurrentTask" })}
31-
/>
32-
{item?.task && (
24+
<div className="flex flex-row justify-between items-center">
25+
{/* Share button with label on the left */}
26+
<div className="flex items-center">
27+
<ShareButton item={item} disabled={false} showLabel={true} />
28+
</div>
29+
30+
{/* Other action buttons on the right */}
31+
<div className="flex flex-row gap-1">
3332
<IconButton
34-
iconClass={showCopyFeedback ? "codicon-check" : "codicon-copy"}
35-
title={t("history:copyPrompt")}
36-
onClick={(e) => copyWithFeedback(item.task, e)}
33+
iconClass="codicon-desktop-download"
34+
title={t("chat:task.export")}
35+
onClick={() => vscode.postMessage({ type: "exportCurrentTask" })}
3736
/>
38-
)}
39-
{!!item?.size && item.size > 0 && (
40-
<>
41-
<div className="flex items-center">
42-
<IconButton
43-
iconClass="codicon-trash"
44-
title={t("chat:task.delete")}
45-
disabled={buttonsDisabled}
46-
onClick={(e) => {
47-
e.stopPropagation()
37+
{item?.task && (
38+
<IconButton
39+
iconClass={showCopyFeedback ? "codicon-check" : "codicon-copy"}
40+
title={t("history:copyPrompt")}
41+
onClick={(e) => copyWithFeedback(item.task, e)}
42+
/>
43+
)}
44+
{!!item?.size && item.size > 0 && (
45+
<>
46+
<div className="flex items-center">
47+
<IconButton
48+
iconClass="codicon-trash"
49+
title={t("chat:task.delete")}
50+
disabled={buttonsDisabled}
51+
onClick={(e) => {
52+
e.stopPropagation()
4853

49-
if (e.shiftKey) {
50-
vscode.postMessage({ type: "deleteTaskWithId", text: item.id })
51-
} else {
52-
setDeleteTaskId(item.id)
53-
}
54-
}}
55-
/>
56-
<span className="ml-1 text-xs text-vscode-foreground opacity-85">{prettyBytes(item.size)}</span>
57-
</div>
58-
{deleteTaskId && (
59-
<DeleteTaskDialog
60-
taskId={deleteTaskId}
61-
onOpenChange={(open) => !open && setDeleteTaskId(null)}
62-
open
63-
/>
64-
)}
65-
</>
66-
)}
54+
if (e.shiftKey) {
55+
vscode.postMessage({ type: "deleteTaskWithId", text: item.id })
56+
} else {
57+
setDeleteTaskId(item.id)
58+
}
59+
}}
60+
/>
61+
</div>
62+
{deleteTaskId && (
63+
<DeleteTaskDialog
64+
taskId={deleteTaskId}
65+
onOpenChange={(open) => !open && setDeleteTaskId(null)}
66+
open
67+
/>
68+
)}
69+
</>
70+
)}
71+
</div>
6772
</div>
6873
)
6974
}

webview-ui/src/components/chat/TaskHeader.tsx

Lines changed: 103 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -154,100 +154,118 @@ const TaskHeader = ({
154154
</div>
155155
{task.images && task.images.length > 0 && <Thumbnails images={task.images} />}
156156

157-
<div className="flex flex-col gap-1">
158-
{contextWindow > 0 && (
159-
<div
160-
className={`w-full flex ${windowWidth < 400 ? "flex-col" : "flex-row"} gap-1 h-auto`}>
161-
<div className="flex items-center gap-1 flex-shrink-0">
162-
<span className="font-bold" data-testid="context-window-label">
163-
{t("chat:task.contextWindow")}
164-
</span>
165-
</div>
166-
<ContextWindowProgress
167-
contextWindow={contextWindow}
168-
contextTokens={contextTokens || 0}
169-
maxTokens={
170-
model
171-
? getModelMaxOutputTokens({
172-
modelId,
173-
model,
174-
settings: apiConfiguration,
175-
})
176-
: undefined
177-
}
178-
/>
179-
{condenseButton}
180-
</div>
181-
)}
157+
<div className="border-t border-b border-vscode-panel-border/50 py-4 mt-2 mb-1">
158+
<table className="w-full">
159+
<tbody>
160+
{contextWindow > 0 && (
161+
<tr>
162+
<th
163+
className="font-bold text-left align-top w-1 whitespace-nowrap pl-1 pr-2 h-[24px]"
164+
data-testid="context-window-label">
165+
{t("chat:task.contextWindow")}
166+
</th>
167+
<td className="align-top">
168+
<div
169+
className={`max-w-64 flex ${windowWidth < 400 ? "flex-col" : "flex-row"} gap-1 h-auto`}>
170+
<ContextWindowProgress
171+
contextWindow={contextWindow}
172+
contextTokens={contextTokens || 0}
173+
maxTokens={
174+
model
175+
? getModelMaxOutputTokens({
176+
modelId,
177+
model,
178+
settings: apiConfiguration,
179+
})
180+
: undefined
181+
}
182+
/>
183+
{condenseButton}
184+
</div>
185+
</td>
186+
</tr>
187+
)}
182188

183-
<div className="flex items-center gap-1 flex-wrap h-[20px]">
184-
<span className="font-bold">{t("chat:task.tokens")}</span>
185-
{typeof tokensIn === "number" && tokensIn > 0 && (
186-
<span className="flex items-center gap-0.5">
187-
<i className="codicon codicon-arrow-up text-xs font-bold" />
188-
{formatLargeNumber(tokensIn)}
189-
</span>
190-
)}
191-
{typeof tokensOut === "number" && tokensOut > 0 && (
192-
<span className="flex items-center gap-0.5">
193-
<i className="codicon codicon-arrow-down text-xs font-bold" />
194-
{formatLargeNumber(tokensOut)}
195-
</span>
196-
)}
197-
</div>
189+
<tr>
190+
<th className="font-bold text-left align-top w-1 whitespace-nowrap pl-1 pr-2 h-[24px]">
191+
{t("chat:task.tokens")}
192+
</th>
193+
<td className="align-top">
194+
<div className="flex items-center gap-1 flex-wrap">
195+
{typeof tokensIn === "number" && tokensIn > 0 && (
196+
<span>{formatLargeNumber(tokensIn)}</span>
197+
)}
198+
{typeof tokensOut === "number" && tokensOut > 0 && (
199+
<span>{formatLargeNumber(tokensOut)}</span>
200+
)}
201+
</div>
202+
</td>
203+
</tr>
198204

199-
{((typeof cacheReads === "number" && cacheReads > 0) ||
200-
(typeof cacheWrites === "number" && cacheWrites > 0)) && (
201-
<div className="flex items-center gap-1 flex-wrap h-[20px]">
202-
<span className="font-bold">{t("chat:task.cache")}</span>
203-
{typeof cacheWrites === "number" && cacheWrites > 0 && (
204-
<span className="flex items-center gap-0.5">
205-
<CloudUpload size={16} />
206-
{formatLargeNumber(cacheWrites)}
207-
</span>
205+
{((typeof cacheReads === "number" && cacheReads > 0) ||
206+
(typeof cacheWrites === "number" && cacheWrites > 0)) && (
207+
<tr>
208+
<th className="font-bold text-left align-top w-1 whitespace-nowrap pl-1 pr-2 h-[24px]">
209+
{t("chat:task.cache")}
210+
</th>
211+
<td className="align-top">
212+
<div className="flex items-center gap-1 flex-wrap">
213+
{typeof cacheWrites === "number" && cacheWrites > 0 && (
214+
<span className="flex items-center gap-1">
215+
<CloudUpload size={14} />
216+
{formatLargeNumber(cacheWrites)}
217+
</span>
218+
)}
219+
{typeof cacheReads === "number" && cacheReads > 0 && (
220+
<span className="flex items-center gap-1">
221+
<CloudDownload size={14} />
222+
{formatLargeNumber(cacheReads)}
223+
</span>
224+
)}
225+
</div>
226+
</td>
227+
</tr>
208228
)}
209-
{typeof cacheReads === "number" && cacheReads > 0 && (
210-
<span className="flex items-center gap-0.5">
211-
<CloudDownload size={16} />
212-
{formatLargeNumber(cacheReads)}
213-
</span>
214-
)}
215-
</div>
216-
)}
217229

218-
{!!totalCost && (
219-
<div className="flex items-center gap-1 h-[20px]">
220-
<span className="font-bold">{t("chat:task.apiCost")}</span>
221-
<span>${totalCost?.toFixed(2)}</span>
222-
</div>
223-
)}
230+
{!!totalCost && (
231+
<tr>
232+
<th className="font-bold text-left align-top w-1 whitespace-nowrap pl-1 pr-2 h-[24px]">
233+
{t("chat:task.apiCost")}
234+
</th>
235+
<td className="align-top">
236+
<span>${totalCost?.toFixed(2)}</span>
237+
</td>
238+
</tr>
239+
)}
224240

225-
{/* Cache size display */}
226-
{((typeof cacheReads === "number" && cacheReads > 0) ||
227-
(typeof cacheWrites === "number" && cacheWrites > 0)) && (
228-
<div className="flex items-center gap-1 h-[20px]">
229-
<span className="font-bold">Cache size</span>
230-
<span className="text-xs text-vscode-foreground opacity-85">
231-
{prettyBytes(((cacheReads || 0) + (cacheWrites || 0)) * 4)}
232-
</span>
233-
</div>
234-
)}
241+
{/* Cache size display */}
242+
{((typeof cacheReads === "number" && cacheReads > 0) ||
243+
(typeof cacheWrites === "number" && cacheWrites > 0)) && (
244+
<tr>
245+
<th className="font-bold text-left align-top w-1 whitespace-nowrap pl-1 pr-2 h-[24px]">
246+
Cache size
247+
</th>
248+
<td className="align-top">
249+
{prettyBytes(((cacheReads || 0) + (cacheWrites || 0)) * 4)}
250+
</td>
251+
</tr>
252+
)}
235253

236-
{/* Size display */}
237-
{!!currentTaskItem?.size && currentTaskItem.size > 0 && (
238-
<div className="flex items-center gap-1 h-[20px]">
239-
<span className="font-bold">Size</span>
240-
<span className="text-xs text-vscode-foreground opacity-85">
241-
{prettyBytes(currentTaskItem.size)}
242-
</span>
243-
</div>
244-
)}
254+
{/* Size display */}
255+
{!!currentTaskItem?.size && currentTaskItem.size > 0 && (
256+
<tr>
257+
<th className="font-bold text-left align-top w-1 whitespace-nowrap pl-1 pr-2 h-[20px]">
258+
Size
259+
</th>
260+
<td className="align-top">{prettyBytes(currentTaskItem.size)}</td>
261+
</tr>
262+
)}
263+
</tbody>
264+
</table>
245265
</div>
246266

247267
{/* Footer with task management buttons */}
248-
<div
249-
className="border-t border-vscode-panel-border/50 pt-2 mt-2"
250-
onClick={(e) => e.stopPropagation()}>
268+
<div onClick={(e) => e.stopPropagation()}>
251269
<TaskActions item={currentTaskItem} buttonsDisabled={buttonsDisabled} />
252270
</div>
253271
</>

0 commit comments

Comments
 (0)