-
Notifications
You must be signed in to change notification settings - Fork 2.6k
feat: add star functionality to tasks (#6244) #6246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -14,6 +14,7 @@ import { | |||||
| Button, | ||||||
| } from "@/components/ui" | ||||||
| import { useAppTranslation } from "@/i18n/TranslationContext" | ||||||
| import { useExtensionState } from "@/context/ExtensionStateContext" | ||||||
|
|
||||||
| import { vscode } from "@/utils/vscode" | ||||||
|
|
||||||
|
|
@@ -24,38 +25,49 @@ interface DeleteTaskDialogProps extends AlertDialogProps { | |||||
| export const DeleteTaskDialog = ({ taskId, ...props }: DeleteTaskDialogProps) => { | ||||||
| const { t } = useAppTranslation() | ||||||
| const [isEnterPressed] = useKeyPress("Enter") | ||||||
| const { taskHistory } = useExtensionState() | ||||||
|
|
||||||
| const { onOpenChange } = props | ||||||
|
|
||||||
| // Check if the task is starred | ||||||
| const task = taskHistory.find((t) => t.id === taskId) | ||||||
| const isStarred = task?.isStarred || false | ||||||
|
|
||||||
| const onDelete = useCallback(() => { | ||||||
| if (taskId) { | ||||||
| if (taskId && !isStarred) { | ||||||
| vscode.postMessage({ type: "deleteTaskWithId", text: taskId }) | ||||||
| onOpenChange?.(false) | ||||||
| } | ||||||
| }, [taskId, onOpenChange]) | ||||||
| }, [taskId, isStarred, onOpenChange]) | ||||||
|
|
||||||
| useEffect(() => { | ||||||
| if (taskId && isEnterPressed) { | ||||||
| if (taskId && isEnterPressed && !isStarred) { | ||||||
| onDelete() | ||||||
| } | ||||||
| }, [taskId, isEnterPressed, onDelete]) | ||||||
| }, [taskId, isEnterPressed, isStarred, onDelete]) | ||||||
|
|
||||||
| return ( | ||||||
| <AlertDialog {...props}> | ||||||
| <AlertDialogContent onEscapeKeyDown={() => onOpenChange?.(false)}> | ||||||
| <AlertDialogHeader> | ||||||
| <AlertDialogTitle>{t("history:deleteTask")}</AlertDialogTitle> | ||||||
| <AlertDialogDescription>{t("history:deleteTaskMessage")}</AlertDialogDescription> | ||||||
| <AlertDialogDescription> | ||||||
| {isStarred | ||||||
| ? "This task is starred. Please unstar it before deleting." | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The message for starred tasks ('This task is starred. Please unstar it before deleting.') is hardcoded. It should be translated using t() for consistency with i18n requirements.
Suggested change
This comment was generated because it violated a code review rule: irule_C0ez7Rji6ANcGkkX. |
||||||
| : t("history:deleteTaskMessage")} | ||||||
| </AlertDialogDescription> | ||||||
| </AlertDialogHeader> | ||||||
| <AlertDialogFooter> | ||||||
| <AlertDialogCancel asChild> | ||||||
| <Button variant="secondary">{t("history:cancel")}</Button> | ||||||
| </AlertDialogCancel> | ||||||
| <AlertDialogAction asChild> | ||||||
| <Button variant="destructive" onClick={onDelete}> | ||||||
| {t("history:delete")} | ||||||
| </Button> | ||||||
| </AlertDialogAction> | ||||||
| {!isStarred && ( | ||||||
| <AlertDialogAction asChild> | ||||||
| <Button variant="destructive" onClick={onDelete}> | ||||||
| {t("history:delete")} | ||||||
| </Button> | ||||||
| </AlertDialogAction> | ||||||
| )} | ||||||
| </AlertDialogFooter> | ||||||
| </AlertDialogContent> | ||||||
| </AlertDialog> | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,7 @@ import type { HistoryItem } from "@roo-code/types" | |||||
| import { formatDate } from "@/utils/format" | ||||||
| import { DeleteButton } from "./DeleteButton" | ||||||
| import { cn } from "@/lib/utils" | ||||||
| import { vscode } from "@/utils/vscode" | ||||||
|
|
||||||
| export interface TaskItemHeaderProps { | ||||||
| item: HistoryItem | ||||||
|
|
@@ -11,22 +12,38 @@ export interface TaskItemHeaderProps { | |||||
| } | ||||||
|
|
||||||
| const TaskItemHeader: React.FC<TaskItemHeaderProps> = ({ item, isSelectionMode, onDelete }) => { | ||||||
| const handleStarClick = (e: React.MouseEvent) => { | ||||||
| e.stopPropagation() | ||||||
| vscode.postMessage({ type: "toggleTaskStar", text: item.id }) | ||||||
| } | ||||||
|
|
||||||
| return ( | ||||||
| <div | ||||||
| className={cn("flex justify-between items-center", { | ||||||
| // this is to balance out the margin when we don't have a delete button | ||||||
| // because the delete button sorta pushes the date up due to its size | ||||||
| "mb-1": !onDelete, | ||||||
| "mb-1": !onDelete && !item.isStarred, | ||||||
| })}> | ||||||
| <div className="flex items-center flex-wrap gap-x-2 text-xs"> | ||||||
| <span className="text-vscode-descriptionForeground font-medium text-sm uppercase"> | ||||||
| {formatDate(item.ts)} | ||||||
| </span> | ||||||
| {item.isStarred && ( | ||||||
| <span className="text-vscode-textPreformat-foreground" title="Starred task"> | ||||||
| <i className="codicon codicon-star-full" /> | ||||||
| </span> | ||||||
| )} | ||||||
| </div> | ||||||
|
|
||||||
| {/* Action Buttons */} | ||||||
| {!isSelectionMode && ( | ||||||
| <div className="flex flex-row gap-0 items-center opacity-20 group-hover:opacity-50 hover:opacity-100"> | ||||||
| <button | ||||||
| onClick={handleStarClick} | ||||||
| className="p-1 hover:bg-vscode-toolbar-hoverBackground rounded" | ||||||
| title={item.isStarred ? "Unstar task" : "Star task"}> | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The title attribute on the star button uses inline text ('Star task'/'Unstar task'). Replace these with t()-based translation keys for proper internationalization.
Suggested change
This comment was generated because it violated a code review rule: irule_C0ez7Rji6ANcGkkX. |
||||||
| <i className={cn("codicon", item.isStarred ? "codicon-star-full" : "codicon-star-empty")} /> | ||||||
| </button> | ||||||
| {onDelete && <DeleteButton itemId={item.id} onDelete={onDelete} />} | ||||||
| </div> | ||||||
| )} | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inline string for starred tasks (e.g. 'All selected tasks are starred. Please unstar them before deleting.') is hardcoded. For proper internationalization, use the translation function (t) with a translation key.
This comment was generated because it violated a code review rule: irule_C0ez7Rji6ANcGkkX.