feat: Pro 买断门禁、SFTP 精简与批量多机改造
新增 entitlement/license IPC 与 Waffo 一次性结账服务骨架,挂载 AI/转发/代理/串口/广播/批量导入导出门禁;批量执行改为结果矩阵并复用连接池,SFTP 工具栏图标化并去掉已连接条,同时完善跨平台本地终端与窗口配置。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
101d2164b4
commit
fea6d8db04
72 files changed
+3307
-396
No files matched your search
@@ -1,39 +1,45 @@
|
||||
/**
|
||||
* Breadcrumb - 路径导航组件
|
||||
* Breadcrumb - 路径导航组件(本地支持 Windows / UNC,远程保持 POSIX)
|
||||
*/
|
||||
|
||||
import { ChevronRight, Home } from 'lucide-react'
|
||||
import { splitPathSegments } from '../../utils/localPath'
|
||||
|
||||
interface BreadcrumbProps {
|
||||
path: string
|
||||
isLocal?: boolean
|
||||
onNavigate: (p: string) => void
|
||||
onHome: () => void
|
||||
}
|
||||
|
||||
export function Breadcrumb({ path, onNavigate, onHome }: BreadcrumbProps) {
|
||||
const parts = path.split('/').filter(Boolean)
|
||||
export function Breadcrumb({ path, isLocal = false, onNavigate, onHome }: BreadcrumbProps) {
|
||||
const { root, parts, join } = splitPathSegments(path || (isLocal ? '' : '/'), isLocal)
|
||||
const rootLabel = isLocal && root !== '/' ? root.replace(/\\$/, '') || root : '/'
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1 text-sm min-w-0">
|
||||
<div className="flex min-w-0 items-center gap-1 text-sm">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onHome}
|
||||
className="p-1.5 hover:bg-dark-700 rounded transition-colors flex-shrink-0"
|
||||
className="flex-shrink-0 rounded p-1.5 transition-colors hover:bg-dark-700"
|
||||
title="主目录"
|
||||
>
|
||||
<Home className="w-4 h-4 text-txt-muted" />
|
||||
<Home className="h-4 w-4 text-txt-muted" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onNavigate('/')}
|
||||
className="px-1.5 py-0.5 hover:bg-dark-700 rounded text-txt-muted hover:text-dark-200 transition-colors"
|
||||
type="button"
|
||||
onClick={() => onNavigate(root || '/')}
|
||||
className="rounded px-1.5 py-0.5 text-txt-muted transition-colors hover:bg-dark-700 hover:text-dark-200"
|
||||
>
|
||||
/
|
||||
{rootLabel}
|
||||
</button>
|
||||
{parts.map((part, index) => (
|
||||
<span key={index} className="flex items-center min-w-0">
|
||||
<ChevronRight className="w-3 h-3 text-dark-600 mx-0.5 flex-shrink-0" />
|
||||
<span key={`${part}-${index}`} className="flex min-w-0 items-center">
|
||||
<ChevronRight className="mx-0.5 h-3 w-3 flex-shrink-0 text-dark-600" />
|
||||
<button
|
||||
onClick={() => onNavigate('/' + parts.slice(0, index + 1).join('/'))}
|
||||
className="px-1.5 py-0.5 hover:bg-dark-700 rounded text-content-primary hover:text-content-primary transition-colors truncate max-w-[120px]"
|
||||
type="button"
|
||||
onClick={() => onNavigate(join(parts.slice(0, index + 1)))}
|
||||
className="max-w-[120px] truncate rounded px-1.5 py-0.5 text-content-primary transition-colors hover:bg-dark-700"
|
||||
>
|
||||
{part}
|
||||
</button>
|
||||
|
||||
Reference in new issue
Block a user