File size: 2,835 Bytes
55847d9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { Zap, ScrollText, Cpu } from 'lucide-react'
import { useLayoutStore, type BottomTab } from '../../stores/layout-store'
import { useWorkflowStore } from '../../stores/workflow-store'
import { useTranslation } from 'react-i18next'

/**
 * 底部工具窗口左侧按钮栏(BottomToolWindowBar)
 * JetBrains 风格:28px 宽,纯图标 + title tooltip,激活时右侧 2px 竖线
 * 对应截图左下角红框区域
 */
export default function BottomToolWindowBar() {
  const { t } = useTranslation('layout')
  const bottomTab = useLayoutStore(s => s.bottomTab)
  const setBottomTab = useLayoutStore(s => s.setBottomTab)
  const activeRuns = useWorkflowStore(s => s.activeRuns)

  // Bottom tabs
  const bottomTabs: Array<{ id: BottomTab; icon: typeof Zap; label: string }> = [
    { id: 'tasks',  icon: Zap,        label: t('statusBar.tasksLabel')    },
    { id: 'log',    icon: ScrollText, label: t('bottomPanel.tabs.log')    },
    { id: 'models', icon: Cpu,        label: t('bottomPanel.tabs.models')    },
  ]

  return (
    <div
      className="no-select flex flex-col items-center justify-start h-full py-0.5"
      style={{
        width: 'var(--width-bottom-bar)',  /* 28px */
        backgroundColor: 'var(--color-activity-bar)',
        borderRight: '1px solid var(--color-border)',
        flexShrink: 0,
      }}
    >
      {bottomTabs.map(({ id, icon: Icon, label }) => {
        const isActive = bottomTab === id
        // 任务Tab:任何工作流运行中时显示脉冲小点
        const hasRunning = activeRuns.some(r => r.status === 'running')
        const hasWaiting = activeRuns.some(r => r.status === 'waiting')
        const showPulse = id === 'tasks' && (hasRunning || hasWaiting)

        return (
          <div key={id} className="relative w-full">
            <button
              onClick={() => setBottomTab(id)}
              title={label}
              className="bottom-tool-btn"
              style={{
                boxShadow: isActive
                  ? 'inset -2px 0 0 var(--color-accent)'
                  : 'none',
                color: isActive
                  ? 'var(--color-accent)'
                  : 'var(--color-activity-icon)',
              }}
            >
              <Icon size={13} strokeWidth={isActive ? 2 : 1.5} />
            </button>
            {/* 状态脉冲点(工作流运行中) */}
            {showPulse && (
              <span
                className="absolute top-[3px] right-[3px] w-[5px] h-[5px] rounded-full animate-pulse pointer-events-none"
                style={{
                  backgroundColor: hasWaiting && !hasRunning
                    ? 'var(--color-warning)'
                    : 'var(--color-accent)',
                }}
              />
            )}
          </div>
        )
      })}
    </div>
  )
}