import type { ReleaseAction, ReleaseStatus } from '../hooks/useIssues' import { GitCommit, ListPlus, Loader2, Lock, RefreshCw, Rocket, Search, Settings, Unlock, User, Users, X } from 'lucide-react' import { useEffect, useRef, useState } from 'react' interface Props { /** 顶部筛选框当前内容;按标题 / 工单号 / PR 号过滤看板卡片。 */ filterQuery: string onFilterChange: (query: string) => void onRefresh: () => void /** host 正在重拉看板;为 true 时刷新图标转起来。 */ refreshing: boolean /** 看板范围:'mine' 只看我的(assigned/created),'all' 团队全部工单。 */ scope: 'mine' | 'all' onToggleScope: () => void onEditAuth: () => void commitRunning: boolean /** * Whether the workspace git working tree has uncommitted changes. The * commit button is only rendered when this is true (or `commitRunning` is * true — we keep it visible mid-run so the spinner stays on screen even * if `cc` clears the tree before finishing). */ hasChanges: boolean onCommit: () => void /** 最近一次发布状态;首次消息到达前为 undefined,按钮显示「正在检查」并禁用。 */ release: ReleaseStatus | undefined onRelease: (action: ReleaseAction) => void /** * Whether the workspace's `.env*` files are currently chmod-locked (444). * Icon flips between Lock and Unlock based on this. */ envLocked: boolean /** * Number of `.env*` files discovered in the workspace at the last scan. * The button is disabled when 0 — nothing to lock. */ envFileCount: number /** * True while a chmod batch is in flight; disables the button to avoid * duplicate toggles. */ envLockRunning: boolean /** Hover tooltip, already includes file count + current lock state. */ envLockTitle: string onToggleEnvLock: () => void /** * Whether YouTrack is configured. The「导入 YouTrack 工单」button is only * rendered when true. */ youtrackConfigured: boolean /** * Open the native multi-select dialog to pick which YouTrack issues to * mirror onto the board. */ onImportYouTrack: () => void } const MENU_ITEM_CLASS = 'w-full px-3 py-1 text-left hover:bg-[var(--vscode-menu-selectionBackground)] hover:text-[var(--vscode-menu-selectionForeground)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent disabled:hover:text-inherit' function releaseTitle(release: ReleaseStatus | undefined): string { if (!release) return '正在检查发布状态…' if (release.unavailable) return release.unavailable if (!release.current) return '尚无发布点 · 点击切第一个发布分支' const lead = release.unreleased > 0 ? `${release.devBranch} 领先 ${release.unreleased} 个提交` : '已全部发布' return `正式服发布点 ${release.current} · ${lead}` } export function PanelHeader({ filterQuery, onFilterChange, onRefresh, refreshing, scope, onToggleScope, onEditAuth, commitRunning, hasChanges, onCommit, release, onRelease, envLocked, envFileCount, envLockRunning, envLockTitle, onToggleEnvLock, youtrackConfigured, onImportYouTrack, }: Props) { const showCommit = hasChanges || commitRunning // Env-lock button is always visible; disabled while a chmod batch is in // flight or when the workspace has no .env files to act on. const envLockDisabled = envLockRunning || envFileCount === 0 const [releaseMenuOpen, setReleaseMenuOpen] = useState(false) const menuRef = useRef(null) useEffect(() => { if (!releaseMenuOpen) return const onDown = (e: MouseEvent): void => { if (!menuRef.current?.contains(e.target as Node)) setReleaseMenuOpen(false) } document.addEventListener('mousedown', onDown) return () => document.removeEventListener('mousedown', onDown) }, [releaseMenuOpen]) const title = releaseTitle(release) // 发布按钮常驻,让用户随时看到发布点状态;结构性不可用或动作进行中禁用。 const releaseDisabled = !release || !!release.unavailable || release.running const unreleased = release?.unreleased ?? 0 function pickRelease(action: ReleaseAction): void { setReleaseMenuOpen(false) onRelease(action) } return (
onFilterChange(e.target.value)} onKeyDown={(e) => { if (e.key === 'Escape') { e.stopPropagation() onFilterChange('') } }} placeholder="筛选:标题 / 工单号 / PR 号" aria-label="筛选工单" className="h-6 w-56 rounded border border-[var(--vscode-input-border,transparent)] bg-[var(--vscode-input-background)] pl-6 pr-6 text-xs text-[var(--vscode-input-foreground)] outline-none placeholder:text-[var(--vscode-input-placeholderForeground)] focus:border-[var(--vscode-focusBorder)]" /> {filterQuery !== '' && ( )}
{releaseMenuOpen && release && (
{release.jenkinsConfigured && ( )}
)}
{showCommit && ( )} {youtrackConfigured && ( )}
) }