mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Translate history preview and view
This commit is contained in:
parent
747c3bd552
commit
6cdd10251a
27 changed files with 594 additions and 41 deletions
|
|
@ -22,7 +22,7 @@
|
|||
"slug": "translate",
|
||||
"name": "Translate",
|
||||
"roleDefinition": "You are Roo, a linguistic specialist focused on translating and managing localization files. Your responsibility is to help maintain and update translation files for the application, ensuring consistency and accuracy across all language resources.",
|
||||
"customInstructions": "When internationalizing and translating content:\n\n# Translation Style and Tone\n- Maintain a direct and concise style that mirrors the tone of the original text\n- Carefully account for colloquialisms and idiomatic expressions in both source and target languages\n- Aim for culturally relevant and meaningful translations rather than literal translations\n- Adapt the formality level to match the original content (whether formal or informal)\n- Preserve the personality and voice of the original content\n- Use natural-sounding language that feels native to speakers of the target language\n\n# Technical Implementation\n- Use namespaces to organize translations logically\n- Handle pluralization using i18next's built-in capabilities\n- Implement proper interpolation for variables using {{variable}} syntax\n- Don't include defaultValue. The `en` translations are the fallback.\n\n# Quality Assurance\n- Maintain consistent terminology across all translations\n- Respect the JSON structure of translation files\n- Watch for placeholders and preserve them in translations\n- Be mindful of text length in UI elements when translating to languages that might require more characters\n- Use context-aware translations when the same string has different meanings\n\n# Supported Languages\n- Localize all strings into the following locale files: ar, ca, cs, de, en, es, fr, hi, hu, it, ja, ko, pl, pt, pt-BR, ru, tr, zh-CN, zh-TW",
|
||||
"customInstructions": "When internationalizing and translating content:\n\n# Translation Style and Tone\n- Maintain a direct and concise style that mirrors the tone of the original text\n- Carefully account for colloquialisms and idiomatic expressions in both source and target languages\n- Aim for culturally relevant and meaningful translations rather than literal translations\n- Adapt the formality level to match the original content (whether formal or informal)\n- Preserve the personality and voice of the original content\n- Use natural-sounding language that feels native to speakers of the target language\n- Don't translate the word \"token\" as it means something specific in English that all languages will understand\n\n# Technical Implementation\n- Use namespaces to organize translations logically\n- Handle pluralization using i18next's built-in capabilities\n- Implement proper interpolation for variables using {{variable}} syntax\n- Don't include defaultValue. The `en` translations are the fallback.\n\n# Quality Assurance\n- Maintain consistent terminology across all translations\n- Respect the JSON structure of translation files\n- Watch for placeholders and preserve them in translations\n- Be mindful of text length in UI elements when translating to languages that might require more characters\n- Use context-aware translations when the same string has different meanings\n\n# Supported Languages\n- Localize all strings into the following locale files: ar, ca, cs, de, en, es, fr, hi, hu, it, ja, ko, pl, pt, pt-BR, ru, tr, zh-CN, zh-TW",
|
||||
"groups": [
|
||||
"read",
|
||||
[
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { useCallback } from "react"
|
|||
import { useClipboard } from "@/components/ui/hooks"
|
||||
import { Button } from "@/components/ui"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useAppTranslation } from "@/i18n/TranslationContext"
|
||||
|
||||
type CopyButtonProps = {
|
||||
itemTask: string
|
||||
|
|
@ -10,6 +11,7 @@ type CopyButtonProps = {
|
|||
|
||||
export const CopyButton = ({ itemTask }: CopyButtonProps) => {
|
||||
const { isCopied, copy } = useClipboard()
|
||||
const { t } = useAppTranslation()
|
||||
|
||||
const onCopy = useCallback(
|
||||
(e: React.MouseEvent) => {
|
||||
|
|
@ -23,7 +25,7 @@ export const CopyButton = ({ itemTask }: CopyButtonProps) => {
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
title="Copy Prompt"
|
||||
title={t("history:copyPrompt")}
|
||||
onClick={onCopy}
|
||||
className="opacity-50 hover:opacity-100">
|
||||
<span className={cn("codicon scale-80", { "codicon-check": isCopied, "codicon-copy": !isCopied })} />
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
AlertDialogTitle,
|
||||
Button,
|
||||
} from "@/components/ui"
|
||||
import { useAppTranslation } from "@/i18n/TranslationContext"
|
||||
|
||||
import { vscode } from "@/utils/vscode"
|
||||
|
||||
|
|
@ -21,6 +22,7 @@ interface DeleteTaskDialogProps extends AlertDialogProps {
|
|||
}
|
||||
|
||||
export const DeleteTaskDialog = ({ taskId, ...props }: DeleteTaskDialogProps) => {
|
||||
const { t } = useAppTranslation()
|
||||
const [isEnterPressed] = useKeyPress("Enter")
|
||||
|
||||
const { onOpenChange } = props
|
||||
|
|
@ -42,18 +44,16 @@ export const DeleteTaskDialog = ({ taskId, ...props }: DeleteTaskDialogProps) =>
|
|||
<AlertDialog {...props}>
|
||||
<AlertDialogContent onEscapeKeyDown={() => onOpenChange?.(false)}>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Delete Task</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Are you sure you want to delete this task? This action cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
<AlertDialogTitle>{t("history:deleteTask")}</AlertDialogTitle>
|
||||
<AlertDialogDescription>{t("history:deleteTaskMessage")}</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel asChild>
|
||||
<Button variant="secondary">Cancel</Button>
|
||||
<Button variant="secondary">{t("history:cancel")}</Button>
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction asChild>
|
||||
<Button variant="destructive" onClick={onDelete}>
|
||||
Delete
|
||||
{t("history:delete")}
|
||||
</Button>
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,21 @@
|
|||
import { vscode } from "@/utils/vscode"
|
||||
import { Button } from "@/components/ui"
|
||||
import { useAppTranslation } from "@/i18n/TranslationContext"
|
||||
|
||||
export const ExportButton = ({ itemId }: { itemId: string }) => (
|
||||
<Button
|
||||
data-testid="export"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
title="Export Task"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
vscode.postMessage({ type: "exportTaskWithId", text: itemId })
|
||||
}}>
|
||||
<span className="codicon codicon-cloud-download" />
|
||||
</Button>
|
||||
)
|
||||
export const ExportButton = ({ itemId }: { itemId: string }) => {
|
||||
const { t } = useAppTranslation()
|
||||
|
||||
return (
|
||||
<Button
|
||||
data-testid="export"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
title={t("history:exportTask")}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
vscode.postMessage({ type: "exportTaskWithId", text: itemId })
|
||||
}}>
|
||||
<span className="codicon codicon-cloud-download" />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,24 +5,25 @@ import { formatLargeNumber, formatDate } from "@/utils/format"
|
|||
import { Button } from "@/components/ui"
|
||||
|
||||
import { useExtensionState } from "../../context/ExtensionStateContext"
|
||||
import { useAppTranslation } from "../../i18n/TranslationContext"
|
||||
import { CopyButton } from "./CopyButton"
|
||||
|
||||
type HistoryPreviewProps = {
|
||||
showHistoryView: () => void
|
||||
}
|
||||
|
||||
const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => {
|
||||
const { taskHistory } = useExtensionState()
|
||||
const { t } = useAppTranslation()
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3 shrink-0 mx-5">
|
||||
<div className="flex items-center justify-between text-vscode-descriptionForeground">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="codicon codicon-comment-discussion scale-90 mr-1" />
|
||||
<span className="font-medium text-xs uppercase">Recent Tasks</span>
|
||||
<span className="font-medium text-xs uppercase">{t("history:recentTasks")}</span>
|
||||
</div>
|
||||
<Button variant="ghost" size="sm" onClick={() => showHistoryView()} className="uppercase">
|
||||
View All
|
||||
{t("history:viewAll")}
|
||||
</Button>
|
||||
</div>
|
||||
{taskHistory.slice(0, 3).map((item) => (
|
||||
|
|
@ -50,22 +51,26 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => {
|
|||
</div>
|
||||
<div className="text-xs text-vscode-descriptionForeground">
|
||||
<span>
|
||||
Tokens: ↑{formatLargeNumber(item.tokensIn || 0)} ↓
|
||||
{formatLargeNumber(item.tokensOut || 0)}
|
||||
{t("history:tokens", {
|
||||
in: formatLargeNumber(item.tokensIn || 0),
|
||||
out: formatLargeNumber(item.tokensOut || 0),
|
||||
})}
|
||||
</span>
|
||||
{!!item.cacheWrites && (
|
||||
<>
|
||||
{" • "}
|
||||
<span>
|
||||
Cache: +{formatLargeNumber(item.cacheWrites || 0)} →{" "}
|
||||
{formatLargeNumber(item.cacheReads || 0)}
|
||||
{t("history:cache", {
|
||||
writes: formatLargeNumber(item.cacheWrites || 0),
|
||||
reads: formatLargeNumber(item.cacheReads || 0),
|
||||
})}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
{!!item.totalCost && (
|
||||
<>
|
||||
{" • "}
|
||||
<span>API Cost: ${item.totalCost?.toFixed(4)}</span>
|
||||
<span>{t("history:apiCost", { cost: item.totalCost?.toFixed(4) })}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { vscode } from "@/utils/vscode"
|
|||
import { formatLargeNumber, formatDate } from "@/utils/format"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button } from "@/components/ui"
|
||||
import { useAppTranslation } from "@/i18n/TranslationContext"
|
||||
|
||||
import { Tab, TabContent, TabHeader } from "../common/Tab"
|
||||
import { useTaskSearch } from "./useTaskSearch"
|
||||
|
|
@ -22,6 +23,7 @@ type SortOption = "newest" | "oldest" | "mostExpensive" | "mostTokens" | "mostRe
|
|||
|
||||
const HistoryView = ({ onDone }: HistoryViewProps) => {
|
||||
const { tasks, searchQuery, setSearchQuery, sortOption, setSortOption, setLastNonRelevantSort } = useTaskSearch()
|
||||
const { t } = useAppTranslation()
|
||||
|
||||
const [deleteTaskId, setDeleteTaskId] = useState<string | null>(null)
|
||||
|
||||
|
|
@ -29,13 +31,13 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||
<Tab>
|
||||
<TabHeader className="flex flex-col gap-2">
|
||||
<div className="flex justify-between items-center">
|
||||
<h3 className="text-vscode-foreground m-0">History</h3>
|
||||
<VSCodeButton onClick={onDone}>Done</VSCodeButton>
|
||||
<h3 className="text-vscode-foreground m-0">{t("history:history")}</h3>
|
||||
<VSCodeButton onClick={onDone}>{t("history:done")}</VSCodeButton>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<VSCodeTextField
|
||||
style={{ width: "100%" }}
|
||||
placeholder="Fuzzy search history..."
|
||||
placeholder={t("history:searchPlaceholder")}
|
||||
value={searchQuery}
|
||||
onInput={(e) => {
|
||||
const newValue = (e.target as HTMLInputElement)?.value
|
||||
|
|
@ -70,15 +72,15 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||
value={sortOption}
|
||||
role="radiogroup"
|
||||
onChange={(e) => setSortOption((e.target as HTMLInputElement).value as SortOption)}>
|
||||
<VSCodeRadio value="newest">Newest</VSCodeRadio>
|
||||
<VSCodeRadio value="oldest">Oldest</VSCodeRadio>
|
||||
<VSCodeRadio value="mostExpensive">Most Expensive</VSCodeRadio>
|
||||
<VSCodeRadio value="mostTokens">Most Tokens</VSCodeRadio>
|
||||
<VSCodeRadio value="newest">{t("history:newest")}</VSCodeRadio>
|
||||
<VSCodeRadio value="oldest">{t("history:oldest")}</VSCodeRadio>
|
||||
<VSCodeRadio value="mostExpensive">{t("history:mostExpensive")}</VSCodeRadio>
|
||||
<VSCodeRadio value="mostTokens">{t("history:mostTokens")}</VSCodeRadio>
|
||||
<VSCodeRadio
|
||||
value="mostRelevant"
|
||||
disabled={!searchQuery}
|
||||
style={{ opacity: searchQuery ? 1 : 0.5 }}>
|
||||
Most Relevant
|
||||
{t("history:mostRelevant")}
|
||||
</VSCodeRadio>
|
||||
</VSCodeRadioGroup>
|
||||
</div>
|
||||
|
|
@ -132,7 +134,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
title="Delete Task (Shift + Click to skip confirmation)"
|
||||
title={t("history:deleteTaskTitle")}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
|
||||
|
|
@ -181,7 +183,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||
fontWeight: 500,
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
}}>
|
||||
Tokens:
|
||||
{t("history:tokensLabel")}
|
||||
</span>
|
||||
<span
|
||||
data-testid="tokens-in"
|
||||
|
|
@ -242,7 +244,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||
fontWeight: 500,
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
}}>
|
||||
Cache:
|
||||
{t("history:cacheLabel")}
|
||||
</span>
|
||||
<span
|
||||
data-testid="cache-writes"
|
||||
|
|
@ -297,7 +299,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||
fontWeight: 500,
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
}}>
|
||||
API Cost:
|
||||
{t("history:apiCostLabel")}
|
||||
</span>
|
||||
<span style={{ color: "var(--vscode-descriptionForeground)" }}>
|
||||
${item.totalCost?.toFixed(4)}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { vscode } from "../../../utils/vscode"
|
|||
|
||||
jest.mock("../../../context/ExtensionStateContext")
|
||||
jest.mock("../../../utils/vscode")
|
||||
jest.mock("../../../i18n/TranslationContext")
|
||||
|
||||
jest.mock("react-virtuoso", () => ({
|
||||
Virtuoso: ({ data, itemContent }: any) => (
|
||||
|
|
|
|||
63
webview-ui/src/i18n/__mocks__/TranslationContext.tsx
Normal file
63
webview-ui/src/i18n/__mocks__/TranslationContext.tsx
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import React from "react"
|
||||
|
||||
// Create a mock for the useAppTranslation hook
|
||||
export const useAppTranslation = () => {
|
||||
return {
|
||||
t: (key: string, options?: Record<string, any>) => {
|
||||
const translations: Record<string, string> = {
|
||||
// History translations
|
||||
"history:recentTasks": "Recent Tasks",
|
||||
"history:viewAll": "View All",
|
||||
"history:history": "History",
|
||||
"history:done": "Done",
|
||||
"history:searchPlaceholder": "Fuzzy search history...",
|
||||
"history:newest": "Newest",
|
||||
"history:oldest": "Oldest",
|
||||
"history:mostExpensive": "Most Expensive",
|
||||
"history:mostTokens": "Most Tokens",
|
||||
"history:mostRelevant": "Most Relevant",
|
||||
"history:deleteTaskTitle": "Delete Task (Shift + Click to skip confirmation)",
|
||||
"history:tokensLabel": "Tokens:",
|
||||
"history:cacheLabel": "Cache:",
|
||||
"history:apiCostLabel": "API Cost:",
|
||||
"history:copyPrompt": "Copy Prompt",
|
||||
"history:exportTask": "Export Task",
|
||||
"history:deleteTask": "Delete Task",
|
||||
"history:deleteTaskMessage": "Are you sure you want to delete this task? This action cannot be undone.",
|
||||
"history:cancel": "Cancel",
|
||||
"history:delete": "Delete",
|
||||
}
|
||||
|
||||
// Handle interpolation
|
||||
if (options && key === "history:tokens") {
|
||||
return `Tokens: ↑${options.in} ↓${options.out}`
|
||||
}
|
||||
|
||||
if (options && key === "history:cache") {
|
||||
return `Cache: +${options.writes} → ${options.reads}`
|
||||
}
|
||||
|
||||
if (options && key === "history:apiCost") {
|
||||
return `API Cost: $${options.cost}`
|
||||
}
|
||||
|
||||
return translations[key] || key
|
||||
},
|
||||
i18n: {
|
||||
language: "en",
|
||||
changeLanguage: jest.fn(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const withTranslation = (Component: React.ComponentType<any>) => {
|
||||
return (props: any) => <Component {...props} />
|
||||
}
|
||||
|
||||
// Mock provider component
|
||||
export const AppTranslationProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
const TranslationContext = { AppTranslationProvider, useAppTranslation, withTranslation }
|
||||
export default TranslationContext
|
||||
25
webview-ui/src/i18n/locales/ar/history.json
Normal file
25
webview-ui/src/i18n/locales/ar/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "المهام الأخيرة",
|
||||
"viewAll": "عرض الكل",
|
||||
"tokens": "الرموز: ↑{{in}} ↓{{out}}",
|
||||
"cache": "التخزين المؤقت: +{{writes}} → {{reads}}",
|
||||
"apiCost": "تكلفة API: ${{cost}}",
|
||||
"history": "السجل",
|
||||
"done": "تم",
|
||||
"searchPlaceholder": "البحث في السجل...",
|
||||
"newest": "الأحدث",
|
||||
"oldest": "الأقدم",
|
||||
"mostExpensive": "الأكثر تكلفة",
|
||||
"mostTokens": "الأكثر رموزًا",
|
||||
"mostRelevant": "الأكثر صلة",
|
||||
"deleteTaskTitle": "حذف المهمة (Shift + نقرة لتخطي التأكيد)",
|
||||
"tokensLabel": "الرموز:",
|
||||
"cacheLabel": "التخزين المؤقت:",
|
||||
"apiCostLabel": "تكلفة API:",
|
||||
"copyPrompt": "نسخ السؤال",
|
||||
"exportTask": "تصدير المهمة",
|
||||
"deleteTask": "حذف المهمة",
|
||||
"deleteTaskMessage": "هل أنت متأكد من حذف هذه المهمة؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"cancel": "إلغاء",
|
||||
"delete": "حذف"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/ca/history.json
Normal file
25
webview-ui/src/i18n/locales/ca/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Tasques recents",
|
||||
"viewAll": "Veure tot",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Cau: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Cost d'API: ${{cost}}",
|
||||
"history": "Historial",
|
||||
"done": "Fet",
|
||||
"searchPlaceholder": "Cerca a l'historial...",
|
||||
"newest": "Més recents",
|
||||
"oldest": "Més antigues",
|
||||
"mostExpensive": "Més cares",
|
||||
"mostTokens": "Més tokens",
|
||||
"mostRelevant": "Més rellevants",
|
||||
"deleteTaskTitle": "Eliminar tasca (Maj + Clic per ometre confirmació)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Cau:",
|
||||
"apiCostLabel": "Cost d'API:",
|
||||
"copyPrompt": "Copiar prompt",
|
||||
"exportTask": "Exportar tasca",
|
||||
"deleteTask": "Eliminar tasca",
|
||||
"deleteTaskMessage": "Estàs segur que vols eliminar aquesta tasca? Aquesta acció no es pot desfer.",
|
||||
"cancel": "Cancel·lar",
|
||||
"delete": "Eliminar"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/cs/history.json
Normal file
25
webview-ui/src/i18n/locales/cs/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Nedávné úkoly",
|
||||
"viewAll": "Zobrazit vše",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Mezipaměť: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Náklady API: ${{cost}}",
|
||||
"history": "Historie",
|
||||
"done": "Hotovo",
|
||||
"searchPlaceholder": "Vyhledat v historii...",
|
||||
"newest": "Nejnovější",
|
||||
"oldest": "Nejstarší",
|
||||
"mostExpensive": "Nejdražší",
|
||||
"mostTokens": "Nejvíce tokenů",
|
||||
"mostRelevant": "Nejrelevantnější",
|
||||
"deleteTaskTitle": "Smazat úkol (Shift + klik pro přeskočení potvrzení)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Mezipaměť:",
|
||||
"apiCostLabel": "Náklady API:",
|
||||
"copyPrompt": "Kopírovat prompt",
|
||||
"exportTask": "Exportovat úkol",
|
||||
"deleteTask": "Smazat úkol",
|
||||
"deleteTaskMessage": "Opravdu chcete smazat tento úkol? Tuto akci nelze vrátit zpět.",
|
||||
"cancel": "Zrušit",
|
||||
"delete": "Smazat"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/de/history.json
Normal file
25
webview-ui/src/i18n/locales/de/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Neueste Aufgaben",
|
||||
"viewAll": "Alle anzeigen",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Cache: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API-Kosten: ${{cost}}",
|
||||
"history": "Verlauf",
|
||||
"done": "Fertig",
|
||||
"searchPlaceholder": "Verlauf durchsuchen...",
|
||||
"newest": "Neueste",
|
||||
"oldest": "Älteste",
|
||||
"mostExpensive": "Teuerste",
|
||||
"mostTokens": "Meiste Tokens",
|
||||
"mostRelevant": "Relevanteste",
|
||||
"deleteTaskTitle": "Aufgabe löschen (Umschalt + Klick um Bestätigung zu überspringen)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Cache:",
|
||||
"apiCostLabel": "API-Kosten:",
|
||||
"copyPrompt": "Prompt kopieren",
|
||||
"exportTask": "Aufgabe exportieren",
|
||||
"deleteTask": "Aufgabe löschen",
|
||||
"deleteTaskMessage": "Sind Sie sicher, dass Sie diese Aufgabe löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"cancel": "Abbrechen",
|
||||
"delete": "Löschen"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/en/history.json
Normal file
25
webview-ui/src/i18n/locales/en/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Recent Tasks",
|
||||
"viewAll": "View All",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Cache: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API Cost: ${{cost}}",
|
||||
"history": "History",
|
||||
"done": "Done",
|
||||
"searchPlaceholder": "Fuzzy search history...",
|
||||
"newest": "Newest",
|
||||
"oldest": "Oldest",
|
||||
"mostExpensive": "Most Expensive",
|
||||
"mostTokens": "Most Tokens",
|
||||
"mostRelevant": "Most Relevant",
|
||||
"deleteTaskTitle": "Delete Task (Shift + Click to skip confirmation)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Cache:",
|
||||
"apiCostLabel": "API Cost:",
|
||||
"copyPrompt": "Copy Prompt",
|
||||
"exportTask": "Export Task",
|
||||
"deleteTask": "Delete Task",
|
||||
"deleteTaskMessage": "Are you sure you want to delete this task? This action cannot be undone.",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/es/history.json
Normal file
25
webview-ui/src/i18n/locales/es/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Tareas recientes",
|
||||
"viewAll": "Ver todas",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Caché: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Costo de API: ${{cost}}",
|
||||
"history": "Historial",
|
||||
"done": "Listo",
|
||||
"searchPlaceholder": "Buscar en el historial...",
|
||||
"newest": "Más recientes",
|
||||
"oldest": "Más antiguas",
|
||||
"mostExpensive": "Más costosas",
|
||||
"mostTokens": "Más tokens",
|
||||
"mostRelevant": "Más relevantes",
|
||||
"deleteTaskTitle": "Eliminar tarea (Shift + Clic para omitir confirmación)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Caché:",
|
||||
"apiCostLabel": "Costo de API:",
|
||||
"copyPrompt": "Copiar prompt",
|
||||
"exportTask": "Exportar tarea",
|
||||
"deleteTask": "Eliminar tarea",
|
||||
"deleteTaskMessage": "¿Estás seguro de que quieres eliminar esta tarea? Esta acción no se puede deshacer.",
|
||||
"cancel": "Cancelar",
|
||||
"delete": "Eliminar"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/fr/history.json
Normal file
25
webview-ui/src/i18n/locales/fr/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Tâches récentes",
|
||||
"viewAll": "Voir tout",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Cache: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Coût API: ${{cost}}",
|
||||
"history": "Historique",
|
||||
"done": "Terminé",
|
||||
"searchPlaceholder": "Rechercher dans l'historique...",
|
||||
"newest": "Plus récentes",
|
||||
"oldest": "Plus anciennes",
|
||||
"mostExpensive": "Plus coûteuses",
|
||||
"mostTokens": "Plus de tokens",
|
||||
"mostRelevant": "Plus pertinentes",
|
||||
"deleteTaskTitle": "Supprimer la tâche (Maj + Clic pour ignorer la confirmation)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Cache:",
|
||||
"apiCostLabel": "Coût API:",
|
||||
"copyPrompt": "Copier le prompt",
|
||||
"exportTask": "Exporter la tâche",
|
||||
"deleteTask": "Supprimer la tâche",
|
||||
"deleteTaskMessage": "Êtes-vous sûr de vouloir supprimer cette tâche ? Cette action ne peut pas être annulée.",
|
||||
"cancel": "Annuler",
|
||||
"delete": "Supprimer"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/hi/history.json
Normal file
25
webview-ui/src/i18n/locales/hi/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "हालिया कार्य",
|
||||
"viewAll": "सभी देखें",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "कैश: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API लागत: ${{cost}}",
|
||||
"history": "इतिहास",
|
||||
"done": "पूर्ण",
|
||||
"searchPlaceholder": "इतिहास खोजें...",
|
||||
"newest": "नवीनतम",
|
||||
"oldest": "सबसे पुराना",
|
||||
"mostExpensive": "सबसे महंगा",
|
||||
"mostTokens": "सबसे अधिक टोकन",
|
||||
"mostRelevant": "सबसे प्रासंगिक",
|
||||
"deleteTaskTitle": "कार्य हटाएं (Shift + क्लिक पुष्टि छोड़ने के लिए)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "कैश:",
|
||||
"apiCostLabel": "API लागत:",
|
||||
"copyPrompt": "प्रॉम्प्ट कॉपी करें",
|
||||
"exportTask": "कार्य निर्यात करें",
|
||||
"deleteTask": "कार्य हटाएं",
|
||||
"deleteTaskMessage": "क्या आप वाकई इस कार्य को हटाना चाहते हैं? यह क्रिया पूर्ववत नहीं की जा सकती है।",
|
||||
"cancel": "रद्द करें",
|
||||
"delete": "हटाएं"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/hu/history.json
Normal file
25
webview-ui/src/i18n/locales/hu/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Legutóbbi feladatok",
|
||||
"viewAll": "Összes megtekintése",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Gyorsítótár: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API költség: ${{cost}}",
|
||||
"history": "Előzmények",
|
||||
"done": "Kész",
|
||||
"searchPlaceholder": "Előzmények keresése...",
|
||||
"newest": "Legújabb",
|
||||
"oldest": "Legrégebbi",
|
||||
"mostExpensive": "Legdrágább",
|
||||
"mostTokens": "Legtöbb token",
|
||||
"mostRelevant": "Legrelevánsabb",
|
||||
"deleteTaskTitle": "Feladat törlése (Shift + kattintás a megerősítés kihagyásához)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Gyorsítótár:",
|
||||
"apiCostLabel": "API költség:",
|
||||
"copyPrompt": "Prompt másolása",
|
||||
"exportTask": "Feladat exportálása",
|
||||
"deleteTask": "Feladat törlése",
|
||||
"deleteTaskMessage": "Biztosan törölni szeretné ezt a feladatot? Ez a művelet nem vonható vissza.",
|
||||
"cancel": "Mégsem",
|
||||
"delete": "Törlés"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/it/history.json
Normal file
25
webview-ui/src/i18n/locales/it/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Attività recenti",
|
||||
"viewAll": "Vedi tutto",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Cache: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Costo API: ${{cost}}",
|
||||
"history": "Cronologia",
|
||||
"done": "Fatto",
|
||||
"searchPlaceholder": "Ricerca nella cronologia...",
|
||||
"newest": "Più recenti",
|
||||
"oldest": "Più vecchie",
|
||||
"mostExpensive": "Più costose",
|
||||
"mostTokens": "Più token",
|
||||
"mostRelevant": "Più rilevanti",
|
||||
"deleteTaskTitle": "Elimina attività (Shift + Clic per saltare conferma)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Cache:",
|
||||
"apiCostLabel": "Costo API:",
|
||||
"copyPrompt": "Copia prompt",
|
||||
"exportTask": "Esporta attività",
|
||||
"deleteTask": "Elimina attività",
|
||||
"deleteTaskMessage": "Sei sicuro di voler eliminare questa attività? Questa azione non può essere annullata.",
|
||||
"cancel": "Annulla",
|
||||
"delete": "Elimina"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/ja/history.json
Normal file
25
webview-ui/src/i18n/locales/ja/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "最近のタスク",
|
||||
"viewAll": "すべて表示",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "キャッシュ: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API コスト: ${{cost}}",
|
||||
"history": "履歴",
|
||||
"done": "完了",
|
||||
"searchPlaceholder": "履歴をあいまい検索...",
|
||||
"newest": "最新",
|
||||
"oldest": "最古",
|
||||
"mostExpensive": "最も高価",
|
||||
"mostTokens": "最多トークン",
|
||||
"mostRelevant": "最も関連性の高い",
|
||||
"deleteTaskTitle": "タスクを削除(Shift + クリックで確認をスキップ)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "キャッシュ:",
|
||||
"apiCostLabel": "API コスト:",
|
||||
"copyPrompt": "プロンプトをコピー",
|
||||
"exportTask": "タスクをエクスポート",
|
||||
"deleteTask": "タスクを削除",
|
||||
"deleteTaskMessage": "このタスクを削除してもよろしいですか?この操作は元に戻せません。",
|
||||
"cancel": "キャンセル",
|
||||
"delete": "削除"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/ko/history.json
Normal file
25
webview-ui/src/i18n/locales/ko/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "최근 작업",
|
||||
"viewAll": "모두 보기",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "캐시: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API 비용: ${{cost}}",
|
||||
"history": "기록",
|
||||
"done": "완료",
|
||||
"searchPlaceholder": "기록 검색...",
|
||||
"newest": "최신순",
|
||||
"oldest": "오래된순",
|
||||
"mostExpensive": "가장 비싼순",
|
||||
"mostTokens": "토큰 많은순",
|
||||
"mostRelevant": "관련성 높은순",
|
||||
"deleteTaskTitle": "작업 삭제 (Shift + 클릭으로 확인 생략)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "캐시:",
|
||||
"apiCostLabel": "API 비용:",
|
||||
"copyPrompt": "프롬프트 복사",
|
||||
"exportTask": "작업 내보내기",
|
||||
"deleteTask": "작업 삭제",
|
||||
"deleteTaskMessage": "이 작업을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
|
||||
"cancel": "취소",
|
||||
"delete": "삭제"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/pl/history.json
Normal file
25
webview-ui/src/i18n/locales/pl/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Ostatnie zadania",
|
||||
"viewAll": "Zobacz wszystkie",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Pamięć podręczna: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Koszt API: ${{cost}}",
|
||||
"history": "Historia",
|
||||
"done": "Gotowe",
|
||||
"searchPlaceholder": "Szukaj w historii...",
|
||||
"newest": "Najnowsze",
|
||||
"oldest": "Najstarsze",
|
||||
"mostExpensive": "Najdroższe",
|
||||
"mostTokens": "Najwięcej tokenów",
|
||||
"mostRelevant": "Najbardziej trafne",
|
||||
"deleteTaskTitle": "Usuń zadanie (Shift + Klik, aby pominąć potwierdzenie)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Pamięć podręczna:",
|
||||
"apiCostLabel": "Koszt API:",
|
||||
"copyPrompt": "Kopiuj prompt",
|
||||
"exportTask": "Eksportuj zadanie",
|
||||
"deleteTask": "Usuń zadanie",
|
||||
"deleteTaskMessage": "Czy na pewno chcesz usunąć to zadanie? Tej akcji nie można cofnąć.",
|
||||
"cancel": "Anuluj",
|
||||
"delete": "Usuń"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/pt-BR/history.json
Normal file
25
webview-ui/src/i18n/locales/pt-BR/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Tarefas recentes",
|
||||
"viewAll": "Ver todas",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Cache: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Custo da API: ${{cost}}",
|
||||
"history": "Histórico",
|
||||
"done": "Concluído",
|
||||
"searchPlaceholder": "Pesquisar no histórico...",
|
||||
"newest": "Mais recentes",
|
||||
"oldest": "Mais antigas",
|
||||
"mostExpensive": "Mais caras",
|
||||
"mostTokens": "Mais tokens",
|
||||
"mostRelevant": "Mais relevantes",
|
||||
"deleteTaskTitle": "Excluir tarefa (Shift + Clique para pular confirmação)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Cache:",
|
||||
"apiCostLabel": "Custo da API:",
|
||||
"copyPrompt": "Copiar prompt",
|
||||
"exportTask": "Exportar tarefa",
|
||||
"deleteTask": "Excluir tarefa",
|
||||
"deleteTaskMessage": "Tem certeza que deseja excluir esta tarefa? Esta ação não pode ser desfeita.",
|
||||
"cancel": "Cancelar",
|
||||
"delete": "Excluir"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/pt/history.json
Normal file
25
webview-ui/src/i18n/locales/pt/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Tarefas recentes",
|
||||
"viewAll": "Ver todas",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Cache: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Custo da API: ${{cost}}",
|
||||
"history": "Histórico",
|
||||
"done": "Concluído",
|
||||
"searchPlaceholder": "Pesquisar no histórico...",
|
||||
"newest": "Mais recentes",
|
||||
"oldest": "Mais antigas",
|
||||
"mostExpensive": "Mais caras",
|
||||
"mostTokens": "Mais tokens",
|
||||
"mostRelevant": "Mais relevantes",
|
||||
"deleteTaskTitle": "Eliminar tarefa (Shift + Clique para ignorar confirmação)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Cache:",
|
||||
"apiCostLabel": "Custo da API:",
|
||||
"copyPrompt": "Copiar prompt",
|
||||
"exportTask": "Exportar tarefa",
|
||||
"deleteTask": "Eliminar tarefa",
|
||||
"deleteTaskMessage": "Tem a certeza que pretende eliminar esta tarefa? Esta ação não pode ser desfeita.",
|
||||
"cancel": "Cancelar",
|
||||
"delete": "Eliminar"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/ru/history.json
Normal file
25
webview-ui/src/i18n/locales/ru/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Недавние задачи",
|
||||
"viewAll": "Показать все",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Кэш: +{{writes}} → {{reads}}",
|
||||
"apiCost": "Стоимость API: ${{cost}}",
|
||||
"history": "История",
|
||||
"done": "Готово",
|
||||
"searchPlaceholder": "Поиск по истории...",
|
||||
"newest": "Новейшие",
|
||||
"oldest": "Старейшие",
|
||||
"mostExpensive": "Самые дорогие",
|
||||
"mostTokens": "Больше всего токенов",
|
||||
"mostRelevant": "Наиболее релевантные",
|
||||
"deleteTaskTitle": "Удалить задачу (Shift + Клик для пропуска подтверждения)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Кэш:",
|
||||
"apiCostLabel": "Стоимость API:",
|
||||
"copyPrompt": "Копировать запрос",
|
||||
"exportTask": "Экспортировать задачу",
|
||||
"deleteTask": "Удалить задачу",
|
||||
"deleteTaskMessage": "Вы уверены, что хотите удалить эту задачу? Это действие нельзя отменить.",
|
||||
"cancel": "Отмена",
|
||||
"delete": "Удалить"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/tr/history.json
Normal file
25
webview-ui/src/i18n/locales/tr/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "Son Görevler",
|
||||
"viewAll": "Tümünü Gör",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "Önbellek: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API Maliyeti: ${{cost}}",
|
||||
"history": "Geçmiş",
|
||||
"done": "Tamam",
|
||||
"searchPlaceholder": "Geçmişte ara...",
|
||||
"newest": "En Yeni",
|
||||
"oldest": "En Eski",
|
||||
"mostExpensive": "En Pahalı",
|
||||
"mostTokens": "En Çok Token",
|
||||
"mostRelevant": "En İlgili",
|
||||
"deleteTaskTitle": "Görevi Sil (Onayı atlamak için Shift + Tıkla)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "Önbellek:",
|
||||
"apiCostLabel": "API Maliyeti:",
|
||||
"copyPrompt": "Promptu Kopyala",
|
||||
"exportTask": "Görevi Dışa Aktar",
|
||||
"deleteTask": "Görevi Sil",
|
||||
"deleteTaskMessage": "Bu görevi silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.",
|
||||
"cancel": "İptal",
|
||||
"delete": "Sil"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/zh-CN/history.json
Normal file
25
webview-ui/src/i18n/locales/zh-CN/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "最近任务",
|
||||
"viewAll": "查看全部",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "缓存: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API 成本: ${{cost}}",
|
||||
"history": "历史记录",
|
||||
"done": "完成",
|
||||
"searchPlaceholder": "模糊搜索历史...",
|
||||
"newest": "最新",
|
||||
"oldest": "最早",
|
||||
"mostExpensive": "最贵",
|
||||
"mostTokens": "最多令牌",
|
||||
"mostRelevant": "最相关",
|
||||
"deleteTaskTitle": "删除任务(Shift + 点击跳过确认)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "缓存:",
|
||||
"apiCostLabel": "API 成本:",
|
||||
"copyPrompt": "复制提示词",
|
||||
"exportTask": "导出任务",
|
||||
"deleteTask": "删除任务",
|
||||
"deleteTaskMessage": "确定要删除此任务吗?此操作无法撤销。",
|
||||
"cancel": "取消",
|
||||
"delete": "删除"
|
||||
}
|
||||
25
webview-ui/src/i18n/locales/zh-TW/history.json
Normal file
25
webview-ui/src/i18n/locales/zh-TW/history.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"recentTasks": "最近任務",
|
||||
"viewAll": "查看全部",
|
||||
"tokens": "Tokens: ↑{{in}} ↓{{out}}",
|
||||
"cache": "快取: +{{writes}} → {{reads}}",
|
||||
"apiCost": "API 費用: ${{cost}}",
|
||||
"history": "歷史記錄",
|
||||
"done": "完成",
|
||||
"searchPlaceholder": "模糊搜尋歷史...",
|
||||
"newest": "最新",
|
||||
"oldest": "最舊",
|
||||
"mostExpensive": "最昂貴",
|
||||
"mostTokens": "最多令牌",
|
||||
"mostRelevant": "最相關",
|
||||
"deleteTaskTitle": "刪除任務(Shift + 點擊跳過確認)",
|
||||
"tokensLabel": "Tokens:",
|
||||
"cacheLabel": "快取:",
|
||||
"apiCostLabel": "API 費用:",
|
||||
"copyPrompt": "複製提示詞",
|
||||
"exportTask": "匯出任務",
|
||||
"deleteTask": "刪除任務",
|
||||
"deleteTaskMessage": "確定要刪除此任務嗎?此操作無法復原。",
|
||||
"cancel": "取消",
|
||||
"delete": "刪除"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue