From dd432e12d3544ff655a265ee1efa807ff76830bc Mon Sep 17 00:00:00 2001 From: Benjamin Shafii Date: Sun, 1 Feb 2026 00:36:03 -0800 Subject: [PATCH 1/2] fix: make workspace search states easier to understand --- .../src/app/components/workspace-picker.tsx | 190 +++++++++++------- packages/app/src/i18n/locales/en.ts | 4 + packages/app/src/i18n/locales/zh.ts | 4 + 3 files changed, 125 insertions(+), 73 deletions(-) diff --git a/packages/app/src/app/components/workspace-picker.tsx b/packages/app/src/app/components/workspace-picker.tsx index b754d0db..ea25d519 100644 --- a/packages/app/src/app/components/workspace-picker.tsx +++ b/packages/app/src/app/components/workspace-picker.tsx @@ -1,6 +1,6 @@ import { For, Show, createEffect, createMemo } from "solid-js"; -import { Check, Globe, Loader2, Plus, Search, Trash2, Upload } from "lucide-solid"; +import { Check, Globe, Loader2, Plus, Search, Trash2, Upload, X } from "lucide-solid"; import { t, currentLocale } from "../../i18n"; import type { WorkspaceInfo } from "../lib/tauri"; @@ -35,6 +35,17 @@ export default function WorkspacePicker(props: { }); const totalCount = createMemo(() => props.workspaces.length); + const filteredCount = createMemo(() => filtered().length); + const query = createMemo(() => props.search.trim()); + const hasSearch = createMemo(() => query().length > 0); + const countLabel = createMemo(() => (totalCount() ? `${filteredCount()}/${totalCount()}` : `${filteredCount()}`)); + const emptyTitle = createMemo(() => { + if (!totalCount()) return translate("dashboard.workspaces_empty"); + if (hasSearch()) { + return translate("dashboard.workspaces_no_results").replace("{query}", query()); + } + return translate("dashboard.workspaces_empty"); + }); let searchInputRef: HTMLInputElement | undefined; createEffect(() => { @@ -62,90 +73,123 @@ export default function WorkspacePicker(props: { placeholder={translate("dashboard.find_workspace")} value={props.search} onInput={(e) => props.onSearch(e.currentTarget.value)} - class="w-full bg-gray-1 border border-gray-6 rounded-lg py-1.5 pl-9 pr-3 text-sm text-gray-12 focus:outline-none focus:border-gray-7" + class="w-full bg-gray-1 border border-gray-6 rounded-lg py-1.5 pl-9 pr-9 text-sm text-gray-12 focus:outline-none focus:border-gray-7" /> + + +
- {translate("dashboard.workspaces")} ({totalCount()}) + {translate("dashboard.workspaces")} ({countLabel()})
- - {(ws) => ( -
- - - + {translate("dashboard.workspaces_clear_search")} + - - + +
+ {translate("dashboard.workspaces_empty_hint")} +
-
- )} -
+ } + > + + {(ws) => ( +
+ + + + + + + + +
+ )} +
+
diff --git a/packages/app/src/i18n/locales/en.ts b/packages/app/src/i18n/locales/en.ts index f9fa7fd5..8ca2c5bc 100644 --- a/packages/app/src/i18n/locales/en.ts +++ b/packages/app/src/i18n/locales/en.ts @@ -16,6 +16,10 @@ export default { "dashboard.runs": "Runs", "dashboard.find_workspace": "Find workspace...", "dashboard.workspaces": "Workspaces", + "dashboard.workspaces_empty": "No workspaces yet.", + "dashboard.workspaces_empty_hint": "Create or import a workspace to get started.", + "dashboard.workspaces_no_results": "No matches for \"{query}\".", + "dashboard.workspaces_clear_search": "Clear search", "dashboard.new_workspace": "New Workspace...", "dashboard.new_remote_workspace": "Add Remote Workspace...", "dashboard.forget_workspace": "Forget workspace", diff --git a/packages/app/src/i18n/locales/zh.ts b/packages/app/src/i18n/locales/zh.ts index 246b8425..3a26f84b 100644 --- a/packages/app/src/i18n/locales/zh.ts +++ b/packages/app/src/i18n/locales/zh.ts @@ -16,6 +16,10 @@ export default { "dashboard.runs": "运行", "dashboard.find_workspace": "查找工作区...", "dashboard.workspaces": "工作区", + "dashboard.workspaces_empty": "还没有工作区。", + "dashboard.workspaces_empty_hint": "创建或导入一个工作区以开始使用。", + "dashboard.workspaces_no_results": "没有匹配“{query}”的工作区。", + "dashboard.workspaces_clear_search": "清除搜索", "dashboard.new_workspace": "新建工作区...", "dashboard.new_remote_workspace": "添加远程工作区...", "dashboard.forget_workspace": "忘记工作区", From a68c2cffbce141e907b7e4541f2e445125ea7677 Mon Sep 17 00:00:00 2001 From: Benjamin Shafii Date: Mon, 2 Feb 2026 18:22:39 -0800 Subject: [PATCH 2/2] fix: add plugins CTA for scheduled tasks --- packages/app/src/app/pages/dashboard.tsx | 1 + packages/app/src/app/pages/scheduled.tsx | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/app/src/app/pages/dashboard.tsx b/packages/app/src/app/pages/dashboard.tsx index c6b32b1d..5560c3f6 100644 --- a/packages/app/src/app/pages/dashboard.tsx +++ b/packages/app/src/app/pages/dashboard.tsx @@ -825,6 +825,7 @@ export default function DashboardView(props: DashboardViewProps) { refreshJobs={props.refreshScheduledJobs} deleteJob={props.deleteScheduledJob} isWindows={props.isWindows} + openPlugins={() => props.setTab("plugins")} /> diff --git a/packages/app/src/app/pages/scheduled.tsx b/packages/app/src/app/pages/scheduled.tsx index f9e2225a..8221599a 100644 --- a/packages/app/src/app/pages/scheduled.tsx +++ b/packages/app/src/app/pages/scheduled.tsx @@ -7,6 +7,7 @@ import Button from "../components/button"; import { Calendar, Clock, + Cpu, FolderOpen, RefreshCw, Terminal, @@ -23,6 +24,7 @@ export type ScheduledTasksViewProps = { refreshJobs: (options?: { force?: boolean }) => void; deleteJob: (name: string) => Promise | void; isWindows: boolean; + openPlugins: () => void; }; const toRelative = (value?: string | null) => { @@ -194,9 +196,15 @@ export default function ScheduledTasksView(props: ScheduledTasksViewProps) { - No scheduled tasks yet. Add the opencode-scheduler plugin and create a job to - see it here. +
+
+ No scheduled tasks yet. Add the opencode-scheduler plugin and create a job to + see it here. +
+
} >