(() =>
localStorage.getItem(tabKey) === 'groups' ? 'groups' : 'projects'
)
- // Hidden behind the projects tab, a running group would otherwise go unnoticed.
- const groupRunning = (useGroupStates().data ?? []).some((state) => state.status === 'running')
+ const activeGroups = useActiveGroups()
const changeTab = (value: string): void => {
const next: SidebarTab = value === 'groups' ? 'groups' : 'projects'
@@ -43,35 +44,51 @@ export function Sidebar({
}
return (
-
-
- 项目
-
- 批量
- {groupRunning && (
-
- )}
-
-
-
-
-
-
-
-
-
+
+ {/* Above the tabs, so active groups stay visible while browsing projects. */}
+
{
+ changeTab('groups')
+ onSelectGroup(groupId)
+ }}
+ />
+
+
+ 项目
+
+ 批量
+ {activeGroups.length > 0 && (
+ group.phase === 'starting')
+ ? 'animate-pulse bg-info'
+ : 'bg-success'
+ )}
+ />
+ )}
+
+
+
+
+
+
+
+
+
+
)
}
diff --git a/apps/desktop/src/renderer/src/features/title-bar/title-bar.tsx b/apps/desktop/src/renderer/src/features/title-bar/title-bar.tsx
index 3ec303a..444016f 100644
--- a/apps/desktop/src/renderer/src/features/title-bar/title-bar.tsx
+++ b/apps/desktop/src/renderer/src/features/title-bar/title-bar.tsx
@@ -1,7 +1,12 @@
-import { Copy, Menu, Minus, Settings as SettingsIcon, Square, X } from 'lucide-react'
+import { Copy, Layers, Menu, Minus, Settings as SettingsIcon, Square, X } from 'lucide-react'
import { shell } from '@renderer/api'
import { Button } from '@renderer/components/ui/button'
import { useAppInfo } from '@renderer/features/app-info/use-app-info'
+import {
+ describeActiveGroup,
+ describeActiveGroups,
+ useActiveGroups
+} from '@renderer/features/groups/use-active-groups'
import { UpdateBadge } from '@renderer/features/updates/update-badge'
import { cn } from '@renderer/lib/utils'
import { useWindowState } from './use-window-state'
@@ -11,6 +16,8 @@ interface TitleBarProps {
onToggleSettings: () => void
/** Opens the sidebar drawer; only given on narrow screens, where the sidebar is hidden. */
onOpenNavigation?: () => void
+ /** Shows a batch run named in the title bar. */
+ onSelectGroup: (groupId: string) => void
}
/**
@@ -20,7 +27,8 @@ interface TitleBarProps {
export function TitleBar({
showSettings,
onToggleSettings,
- onOpenNavigation
+ onOpenNavigation,
+ onSelectGroup
}: TitleBarProps): React.JSX.Element {
const { data: appInfo } = useAppInfo()
const windowState = useWindowState()
@@ -51,6 +59,8 @@ export function TitleBar({
DevHub
{appInfo && v{appInfo.version}}
+ {/* Phones show the drawer's list instead; there is no room here. */}
+ {!onOpenNavigation && }