diff --git a/packages/desktop/src/app/app.tsx b/packages/desktop/src/app/app.tsx index dcbbcf7f..3c13362d 100644 --- a/packages/desktop/src/app/app.tsx +++ b/packages/desktop/src/app/app.tsx @@ -20,6 +20,7 @@ import TemplateModal from "./components/template-modal"; import WorkspacePicker from "./components/workspace-picker"; import CreateWorkspaceModal from "./components/create-workspace-modal"; import McpAuthModal from "./components/mcp-auth-modal"; +import LanguagePickerModal from "./components/language-picker-modal"; import OnboardingView from "./pages/onboarding"; import DashboardView from "./pages/dashboard"; import SessionView from "./pages/session"; @@ -67,7 +68,7 @@ import { groupMessageParts, isTauriRuntime, } from "./utils"; -import { currentLocale, setLocale, t, type Language } from "../i18n"; +import { currentLocale, setLocale, t, type Language, initLocale } from "../i18n"; import { isWindowsPlatform, lastUserModelFromMessages, @@ -129,6 +130,7 @@ export default function App() { const [rememberModeChoice, setRememberModeChoice] = createSignal(false); const [tab, setTab] = createSignal("home"); const [themeMode, setThemeMode] = createSignal(getInitialThemeMode()); + const [languagePickerOpen, setLanguagePickerOpen] = createSignal(false); const [engineSource, setEngineSource] = createSignal<"path" | "sidecar">( isTauriRuntime() ? "sidecar" : "path" @@ -767,6 +769,19 @@ export default function App() { setModelPickerOpen(true); } + function openLanguagePicker() { + setLanguagePickerOpen(true); + } + + function closeLanguagePicker() { + setLanguagePickerOpen(false); + } + + function handleLanguageSelect(language: Language) { + setLocale(language); + setLanguagePickerOpen(false); + } + function applyModelSelection(next: ModelRef) { if (modelPickerTarget() === "default") { setDefaultModel(next); @@ -1177,6 +1192,9 @@ export default function App() { onMount(async () => { + // Initialize i18n locale from localStorage + initLocale(); + const modePref = readModePreference(); if (modePref) { setRememberModeChoice(true); @@ -1712,6 +1730,11 @@ export default function App() { onResetStartupPreference: () => clearModePreference(), themeMode: themeMode(), setThemeMode, + currentLanguage: currentLocale(), + languagePickerOpen: languagePickerOpen(), + openLanguagePicker, + closeLanguagePicker, + handleLanguageSelect, pendingPermissions: pendingPermissions(), events: events(), safeStringify, @@ -1873,6 +1896,13 @@ export default function App() { onScopeChange={setTemplateDraftScope} /> + + t(key, currentLocale()); return ( -
-
-

{translate("settings.language")}

+
+
+
+
+
+

{translate("settings.language")}

+

{translate("settings.language.description")}

+
+ +
-
- - {(option) => ( - - )} - -
+
+ + {(option) => { + const isActive = () => props.currentLanguage === option.value; + + return ( + + ); + }} + +
- +
+ +
+
diff --git a/packages/desktop/src/app/pages/dashboard.tsx b/packages/desktop/src/app/pages/dashboard.tsx index 6d88c2cd..7a153da6 100644 --- a/packages/desktop/src/app/pages/dashboard.tsx +++ b/packages/desktop/src/app/pages/dashboard.tsx @@ -10,7 +10,9 @@ import type { } from "../types"; import type { McpDirectoryInfo } from "../constants"; import type { WorkspaceInfo } from "../lib/tauri"; +import type { Language } from "../../i18n"; import { formatRelativeTime } from "../utils"; +import { t, currentLocale } from "../../i18n"; import Button from "../components/button"; import OpenWorkLogo from "../components/openwork-logo"; @@ -144,6 +146,11 @@ export type DashboardViewProps = { toggleUpdateAutoCheck: () => void; themeMode: "light" | "dark" | "system"; setThemeMode: (value: "light" | "dark" | "system") => void; + currentLanguage: Language; + languagePickerOpen: boolean; + openLanguagePicker: () => void; + closeLanguagePicker: () => void; + handleLanguageSelect: (language: Language) => void; updateStatus: { state: string; lastCheckedAt?: number | null; @@ -189,22 +196,25 @@ export type DashboardViewProps = { }; export default function DashboardView(props: DashboardViewProps) { + const translate = (key: string) => t(key, currentLocale()); + const title = createMemo(() => { + const locale = currentLocale(); switch (props.tab) { case "sessions": - return "Sessions"; + return t("nav.sessions", locale); case "templates": - return "Templates"; + return t("nav.templates", locale); case "skills": - return "Skills"; + return t("nav.skills", locale); case "plugins": - return "Plugins"; + return t("nav.plugins", locale); case "mcp": - return "MCPs"; + return t("nav.mcp", locale); case "settings": - return "Settings"; + return t("nav.settings", locale); default: - return "Dashboard"; + return t("nav.dashboard", locale); } }); @@ -273,8 +283,8 @@ export default function DashboardView(props: DashboardViewProps) { }); }); - const navItem = (t: DashboardTab, label: any, icon: any) => { - const active = () => props.tab === t; + const navItem = (tab: DashboardTab, label: any, icon: any) => { + const active = () => props.tab === tab; return (
- Connection + {translate("dashboard.connection")} - {props.mode === "host" ? "Local Engine" : "Client Mode"} + {props.mode === "host" ? translate("dashboard.local_engine") : translate("dashboard.client_mode")}
@@ -344,7 +354,7 @@ export default function DashboardView(props: DashboardViewProps) { props.clientConnected ? "text-green-11" : "text-gray-10" }`} > - {props.clientConnected ? "Connected" : "Not connected"} + {props.clientConnected ? translate("dashboard.connected") : translate("dashboard.not_connected")}
@@ -361,7 +371,7 @@ export default function DashboardView(props: DashboardViewProps) { disabled={props.busy} class="w-full" > - Connect + {translate("dashboard.connect")} @@ -372,7 +382,7 @@ export default function DashboardView(props: DashboardViewProps) { disabled={props.busy} class="w-full" > - Stop & Disconnect + {translate("dashboard.stop_disconnect")} @@ -383,7 +393,7 @@ export default function DashboardView(props: DashboardViewProps) { disabled={props.busy} class="w-full" > - Disconnect + {translate("dashboard.disconnect")}
@@ -418,10 +428,10 @@ export default function DashboardView(props: DashboardViewProps) { props.createSessionAndOpen(); }} disabled={props.newTaskDisabled} - title={props.newTaskDisabled ? props.busyHint ?? "Busy" : ""} + title={props.newTaskDisabled ? props.busyHint ?? translate("dashboard.busy") : ""} > - New Task + {translate("dashboard.new_task")}
@@ -443,7 +453,7 @@ export default function DashboardView(props: DashboardViewProps) { disabled={props.busy} > - New + {translate("common.new")} @@ -457,23 +467,22 @@ export default function DashboardView(props: DashboardViewProps) {

- What should we do today? + {translate("dashboard.hero_title")}

- Describe an outcome. OpenWork will run it and keep an - audit trail. + {translate("dashboard.hero_description")}

@@ -482,13 +491,13 @@ export default function DashboardView(props: DashboardViewProps) {

- Quick Start Templates + {translate("dashboard.quick_start_templates")}

@@ -496,7 +505,7 @@ export default function DashboardView(props: DashboardViewProps) { when={quickTemplates().length} fallback={
- No templates yet. Starter templates will appear here. + {translate("dashboard.no_templates")}
} > @@ -512,7 +521,7 @@ export default function DashboardView(props: DashboardViewProps) {

{t.title}

- {t.description || "Run a saved workflow"} + {t.description || translate("dashboard.run_workflow")}

)} @@ -523,7 +532,7 @@ export default function DashboardView(props: DashboardViewProps) {

- Recent Sessions + {translate("dashboard.recent_sessions")}

@@ -561,7 +570,7 @@ export default function DashboardView(props: DashboardViewProps) { } > - this workspace + {translate("dashboard.this_workspace")}
@@ -570,7 +579,7 @@ export default function DashboardView(props: DashboardViewProps) {
- {props.sessionStatusById[s.id] ?? "idle"} + {translate(`status.${props.sessionStatusById[s.id] ?? "idle"}`)}
@@ -579,7 +588,7 @@ export default function DashboardView(props: DashboardViewProps) {
- No sessions yet. + {translate("dashboard.no_sessions")}
@@ -589,7 +598,7 @@ export default function DashboardView(props: DashboardViewProps) {

- Recent Sessions + {translate("dashboard.recent_sessions")}

@@ -627,7 +636,7 @@ export default function DashboardView(props: DashboardViewProps) { } > - this workspace + {translate("dashboard.this_workspace")}
@@ -636,7 +645,7 @@ export default function DashboardView(props: DashboardViewProps) {
- {props.sessionStatusById[s.id] ?? "idle"} + {translate(`status.${props.sessionStatusById[s.id] ?? "idle"}`)}
@@ -645,7 +654,7 @@ export default function DashboardView(props: DashboardViewProps) {
- No sessions yet. + {translate("dashboard.no_sessions")}
@@ -748,6 +757,11 @@ export default function DashboardView(props: DashboardViewProps) { toggleUpdateAutoCheck={props.toggleUpdateAutoCheck} themeMode={props.themeMode} setThemeMode={props.setThemeMode} + currentLanguage={props.currentLanguage} + languagePickerOpen={props.languagePickerOpen} + openLanguagePicker={props.openLanguagePicker} + closeLanguagePicker={props.closeLanguagePicker} + handleLanguageSelect={props.handleLanguageSelect} updateStatus={props.updateStatus} updateEnv={props.updateEnv} appVersion={props.appVersion} @@ -821,7 +835,7 @@ export default function DashboardView(props: DashboardViewProps) { onClick={() => props.setTab("home")} > - Home + {t("nav.home", currentLocale())} diff --git a/packages/desktop/src/app/pages/plugins.tsx b/packages/desktop/src/app/pages/plugins.tsx index c843fb26..8deb7535 100644 --- a/packages/desktop/src/app/pages/plugins.tsx +++ b/packages/desktop/src/app/pages/plugins.tsx @@ -6,6 +6,7 @@ import { isTauriRuntime } from "../utils"; import Button from "../components/button"; import TextInput from "../components/text-input"; import { Cpu } from "lucide-solid"; +import { t, currentLocale } from "../../i18n"; export type PluginsViewProps = { busy: boolean; @@ -41,13 +42,15 @@ export type PluginsViewProps = { }; export default function PluginsView(props: PluginsViewProps) { + const translate = (key: string) => t(key, currentLocale()); + return (
-
OpenCode plugins
-
Manage `opencode.json` for your project or global OpenCode plugins.
+
{translate("plugins.title")}
+
{translate("plugins.description")}
-
Config
-
{props.pluginConfigPath ?? "Not loaded yet"}
+
{translate("plugins.config")}
+
{props.pluginConfigPath ?? translate("plugins.not_loaded")}
-
Suggested plugins
+
{translate("plugins.suggested")}
{(plugin) => { @@ -112,7 +115,7 @@ export default function PluginsView(props: PluginsViewProps) { variant="ghost" onClick={() => props.setActivePluginGuide(isGuideOpen() ? null : plugin.packageName)} > - {isGuideOpen() ? "Hide setup" : "Setup"} + {isGuideOpen() ? translate("plugins.hide_setup") : translate("plugins.setup")}
@@ -190,7 +193,7 @@ export default function PluginsView(props: PluginsViewProps) { {(pluginName) => (
{pluginName}
-
Enabled
+
{translate("plugins.enabled")}
)} @@ -201,11 +204,11 @@ export default function PluginsView(props: PluginsViewProps) {
props.setPluginInput(e.currentTarget.value)} - hint="Add npm package names, e.g. opencode-wakatime" + hint={translate("plugins.add_hint")} />
diff --git a/packages/desktop/src/app/pages/session.tsx b/packages/desktop/src/app/pages/session.tsx index 2a315668..163dad97 100644 --- a/packages/desktop/src/app/pages/session.tsx +++ b/packages/desktop/src/app/pages/session.tsx @@ -29,6 +29,7 @@ import Button from "../components/button"; import PartView from "../components/part-view"; import WorkspaceChip from "../components/workspace-chip"; import { isTauriRuntime, isWindowsPlatform } from "../utils"; +import { t, currentLocale } from "../../i18n"; export type SessionViewProps = { selectedSessionId: string | null; @@ -84,6 +85,8 @@ export type SessionViewProps = { }; export default function SessionView(props: SessionViewProps) { + const translate = (key: string) => t(key, currentLocale()); + let messagesEndEl: HTMLDivElement | undefined; createEffect(() => { @@ -132,9 +135,9 @@ export default function SessionView(props: SessionViewProps) { promptInputEl.scrollHeight > maxPromptHeight ? "auto" : "hidden"; }; - const artifactActionLabel = () => (isWindowsPlatform() ? "Open" : "Reveal"); + const artifactActionLabel = () => (isWindowsPlatform() ? translate("session.open") : translate("session.reveal")); - const artifactActionToast = () => (isWindowsPlatform() ? "Opened in default app." : "Revealed in file manager."); + const artifactActionToast = () => (isWindowsPlatform() ? translate("session.opened_toast") : translate("session.revealed_toast")); const resolveArtifactPath = (artifact: ArtifactItem) => { const rawPath = artifact.path?.trim(); @@ -273,7 +276,7 @@ export default function SessionView(props: SessionViewProps) { }); const showAnticipatoryCursor = createMemo(() => { - if (props.busyLabel !== "Running" && props.sessionStatus !== "running") return false; + if (props.busyLabel !== translate("status.running") && props.sessionStatus !== "running") return false; return !hasAssistantTextAfterLastUser(); }); @@ -408,14 +411,14 @@ export default function SessionView(props: SessionViewProps) { fallback={
-
No session selected
+
{translate("session.no_selected")}
@@ -468,12 +471,12 @@ export default function SessionView(props: SessionViewProps) { disabled={props.newTaskDisabled} > - New task + {translate("dashboard.new_task")}
-
Recents
+
{translate("session.recents")}
{(session) => ( @@ -509,9 +512,9 @@ export default function SessionView(props: SessionViewProps) {
-

Ready to work

+

{translate("session.ready_to_work_title")}

- Describe a task. I'll show progress and ask for permissions when needed. + {translate("session.ready_to_work_description")}

@@ -625,7 +628,7 @@ export default function SessionView(props: SessionViewProps) {
-
Artifacts
+
{translate("session.artifacts")}
{(artifact) => (
@@ -635,7 +638,7 @@ export default function SessionView(props: SessionViewProps) {
{artifact.name}
-
Document
+
{translate("session.document_label")}
@@ -991,9 +994,8 @@ export default function SessionView(props: SessionViewProps) { } disabled={props.permissionReplyBusy} > - - Deny - + {translate("session.deny")} +
diff --git a/packages/desktop/src/app/pages/settings.tsx b/packages/desktop/src/app/pages/settings.tsx index 96429bfe..9b3753bc 100644 --- a/packages/desktop/src/app/pages/settings.tsx +++ b/packages/desktop/src/app/pages/settings.tsx @@ -3,7 +3,9 @@ import { Match, Show, Switch } from "solid-js"; import { formatBytes, formatRelativeTime, isTauriRuntime } from "../utils"; import Button from "../components/button"; -import { HardDrive, RefreshCcw, Shield, Smartphone } from "lucide-solid"; +import { HardDrive, Languages, RefreshCcw, Shield, Smartphone } from "lucide-solid"; +import { currentLocale, t, type Language } from "../../i18n"; +import LanguagePickerModal from "../components/language-picker-modal"; export type SettingsViewProps = { mode: "host" | "client" | null; @@ -29,6 +31,11 @@ export type SettingsViewProps = { setDemoSequence: (value: "cold-open" | "scheduler" | "summaries" | "groceries") => void; themeMode: "light" | "dark" | "system"; setThemeMode: (value: "light" | "dark" | "system") => void; + currentLanguage: Language; + languagePickerOpen: boolean; + openLanguagePicker: () => void; + closeLanguagePicker: () => void; + handleLanguageSelect: (language: Language) => void; updateAutoCheck: boolean; toggleUpdateAutoCheck: () => void; updateStatus: { @@ -64,6 +71,8 @@ export type SettingsViewProps = { }; export default function SettingsView(props: SettingsViewProps) { + const translate = (key: string) => t(key, currentLocale()); + const updateState = () => props.updateStatus?.state ?? "idle"; const updateNotes = () => props.updateStatus?.notes ?? null; const updateVersion = () => props.updateStatus?.version ?? null; @@ -76,13 +85,13 @@ export default function SettingsView(props: SettingsViewProps) { const notionStatusLabel = () => { switch (props.notionStatus) { case "connected": - return "Connected"; + return translate("settings.notion_connected"); case "connecting": - return "Reload required"; + return translate("settings.reload_required"); case "error": - return "Connection failed"; + return translate("settings.connection_failed"); default: - return "Not connected"; + return translate("settings.notion_not_connected"); } }; @@ -103,50 +112,50 @@ export default function SettingsView(props: SettingsViewProps) { return (
-
Connection
+
{translate("settings.connection_title")}
{props.headerStatus}
{props.baseUrl}
-
Engine source
+
{translate("settings.engine_source_label")}
- PATH uses your installed OpenCode (default). Sidecar will use a bundled binary when available. + {translate("settings.engine_source_hint")} - Sidecar is currently unavailable on Windows. + {translate("settings.sidecar_unavailable")}
@@ -156,8 +165,8 @@ export default function SettingsView(props: SettingsViewProps) {
-
Model
-
Defaults + thinking controls for runs.
+
{translate("settings.model_title")}
+
{translate("settings.model_hint")}
@@ -171,14 +180,14 @@ export default function SettingsView(props: SettingsViewProps) { onClick={props.openDefaultModelPicker} disabled={props.busy} > - Change + {translate("common.change")}
-
Thinking
-
Show thinking parts (Developer mode only).
+
{translate("settings.thinking_label")}
+
{translate("settings.thinking_hint")}
-
Model variant
+
{translate("settings.model_variant_label")}
{props.modelVariantLabel}
-
Appearance
-
Match the system or force light/dark mode.
+
{translate("settings.appearance_title")}
+
{translate("settings.appearance_hint")}
@@ -219,7 +228,7 @@ export default function SettingsView(props: SettingsViewProps) { onClick={() => props.setThemeMode("system")} disabled={props.busy} > - System + {translate("settings.theme_system")}
- System mode follows your OS preference automatically. + {translate("settings.theme_system_hint")}
-
Demo mode
-
Lightweight scripted states for recording and review.
+
{translate("settings.language")}
+
{translate("settings.language.description")}
+
+ +
+
+ +
+
+ {props.currentLanguage === "en" ? "English" : "简体中文"} +
+
+ {props.currentLanguage === "en" ? "English" : "Simplified Chinese"} +
+
+
+ +
+
+ + + +
+
+
{translate("settings.demo_mode_title")}
+
{translate("settings.demo_mode_hint")}
-
Enable demo mode
-
Replaces live data with demo sequences.
+
{translate("settings.enable_demo_mode_label")}
+
{translate("settings.enable_demo_mode_hint")}
@@ -272,7 +317,7 @@ export default function SettingsView(props: SettingsViewProps) { onClick={() => props.setDemoSequence("cold-open")} disabled={props.busy || !props.demoMode} > - Cold open + {translate("settings.demo_cold_open")}
- Demo sequences swap in scripted sessions, artifacts, and workspace context. + {translate("settings.demo_sequences_hint")}
-
Updates
-
Keep OpenWork up to date.
+
{translate("settings.updates_title")}
+
{translate("settings.updates_hint")}
{props.appVersion ? `v${props.appVersion}` : ""}
@@ -323,8 +368,8 @@ export default function SettingsView(props: SettingsViewProps) { <>
-
Automatic checks
-
Once per day (quiet)
+
{translate("settings.automatic_checks_label")}
+
{translate("settings.automatic_checks_hint")}
@@ -342,21 +387,21 @@ export default function SettingsView(props: SettingsViewProps) {
- Checking... - Update available: v{updateVersion()} - Downloading... - Ready to install: v{updateVersion()} - Update check failed - Up to date + {translate("settings.update_checking")} + {translate("settings.update_available")} v{updateVersion()} + {translate("settings.update_downloading")} + {translate("settings.update_ready")} v{updateVersion()} + {translate("settings.update_error")} + {translate("settings.update_uptodate")}
- Last checked {formatRelativeTime(updateLastCheckedAt() as number)} + {translate("settings.last_checked_time", { time: formatRelativeTime(updateLastCheckedAt() as number) })}
-
Published {updateDate()}
+
{translate("settings.published_date", { date: updateDate() })}
@@ -378,7 +423,7 @@ export default function SettingsView(props: SettingsViewProps) { onClick={props.checkForUpdates} disabled={props.busy || updateState() === "checking" || updateState() === "downloading"} > - Check + {translate("settings.check_update")} @@ -388,7 +433,7 @@ export default function SettingsView(props: SettingsViewProps) { onClick={props.downloadUpdate} disabled={props.busy || updateState() === "downloading"} > - Download + {translate("settings.download_update")} @@ -398,9 +443,9 @@ export default function SettingsView(props: SettingsViewProps) { class="text-xs h-8 py-0 px-3" onClick={props.installUpdateAndRestart} disabled={props.busy || props.anyActiveRuns} - title={props.anyActiveRuns ? "Stop active runs to update" : ""} + title={props.anyActiveRuns ? translate("settings.stop_runs_to_update") : ""} > - Install & Restart + {translate("settings.install_update")}
@@ -415,19 +460,19 @@ export default function SettingsView(props: SettingsViewProps) { } >
- {props.updateEnv?.reason ?? "Updates are not supported in this environment."} + {props.updateEnv?.reason ?? translate("settings.updates_not_supported")}
} >
- Updates are only available in the desktop app. + {translate("settings.updates_desktop_only")}
-
Startup
+
{translate("settings.startup_title")}
@@ -440,76 +485,76 @@ export default function SettingsView(props: SettingsViewProps) {
- {props.mode} mode + {props.mode} {translate("settings.mode_suffix")}

- This clears your saved preference and shows mode selection on next launch. + {translate("settings.reset_startup_hint")}

-
Advanced
-
Reset OpenWork local state to retest onboarding.
+
{translate("settings.advanced_title")}
+
{translate("settings.advanced_hint")}
-
Reset onboarding
-
Clears OpenWork preferences and restarts the app.
+
{translate("settings.reset_onboarding_label")}
+
{translate("settings.reset_onboarding_hint")}
-
Reset app data
-
More aggressive. Clears OpenWork cache + app data.
+
{translate("settings.reset_app_data_label")}
+
{translate("settings.reset_app_data_hint")}
- Requires typing RESET and will restart the app. + {translate("settings.reset_requires_hint")}
-

Developer

+

{translate("settings.developer_title")}

-
OpenCode cache
+
{translate("settings.opencode_cache_label")}
- Repairs cached data used to start the engine. Safe to run. + {translate("settings.opencode_cache_hint")}
{props.cacheRepairResult}
@@ -520,21 +565,21 @@ export default function SettingsView(props: SettingsViewProps) { class="text-xs h-8 py-0 px-3 shrink-0" onClick={props.repairOpencodeCache} disabled={props.cacheRepairBusy || !isTauriRuntime()} - title={isTauriRuntime() ? "" : "Cache repair requires the desktop app"} + title={isTauriRuntime() ? "" : translate("settings.cache_repair_requires_desktop")} > - {props.cacheRepairBusy ? "Repairing cache" : "Repair cache"} + {props.cacheRepairBusy ? translate("settings.repairing_cache") : translate("settings.repair_cache")}
-
Pending permissions
+
{translate("settings.pending_permissions_label")}
                   {props.safeStringify(props.pendingPermissions)}
                 
-
Recent events
+
{translate("settings.recent_events_label")}
                   {props.safeStringify(props.events)}
                 
diff --git a/packages/desktop/src/app/pages/templates.tsx b/packages/desktop/src/app/pages/templates.tsx index 08d8dd4f..1091e916 100644 --- a/packages/desktop/src/app/pages/templates.tsx +++ b/packages/desktop/src/app/pages/templates.tsx @@ -5,6 +5,7 @@ import { formatRelativeTime } from "../utils"; import Button from "../components/button"; import { FileText, Play, Plus, Trash2 } from "lucide-solid"; +import { t, currentLocale } from "../../i18n"; export type TemplatesViewProps = { busy: boolean; @@ -21,6 +22,8 @@ export type TemplatesViewProps = { }; export default function TemplatesView(props: TemplatesViewProps) { + const translate = (key: string) => t(key, currentLocale()); + const openNewTemplate = () => { const reset = props.resetTemplateDraft; if (reset) { @@ -37,10 +40,10 @@ export default function TemplatesView(props: TemplatesViewProps) { return (
-

Templates

+

{translate("templates.title")}

@@ -48,14 +51,14 @@ export default function TemplatesView(props: TemplatesViewProps) { when={props.workspaceTemplates.length || props.globalTemplates.length} fallback={
- Starter templates will appear here. Create one or save from a session. + {translate("templates.empty_state")}
} >
-
Workspace
+
{translate("templates.workspace")}
{(t) => (
@@ -70,7 +73,7 @@ export default function TemplatesView(props: TemplatesViewProps) {
+
+ +
+ + {(option) => { + const isActive = () => props.currentLanguage === option.value; + + return ( + + ); + }} + +
+ +
+ +
+
+
+
+ + ); +}