feat: PTY kubectl终端 + 侧边栏对齐修复 + 构建缓存清理
**kubectl WebShell 修复:** - 引入 github.com/creack/pty 库实现真正的伪终端 - 替换 bash --noediting + TERM=dumb 方案为 PTY-backed bash - 支持 xterm-256color、窗口自适应、readline 交互 - 修复键盘输入无响应问题 **侧边栏优化:** - 独立菜单项高度从 py-1.5 改为 h-8,与父菜单对齐 - 独立菜单图标从 h-3 w-3 改为 h-3.5 w-3.5,统一 14px **构建优化:** - run.sh docker up 增加 docker image prune -f 清理悬空镜像 - 每次部署自动清理 builder cache + dangling images **认证修复(历史):** - Token 存储:Zustand + localStorage 双写,http.ts 双源 fallback - YamlViewer/DeploymentDetail token 来源统一为 Zustand store
This commit is contained in:
1 parent
cac1414917
commit
a3cd0d3910
29 files changed
+2954
-180
No files matched your search
@@ -26,11 +26,13 @@ import {
|
||||
Eye,
|
||||
Trash2,
|
||||
Search,
|
||||
Container,
|
||||
} from 'lucide-react';
|
||||
import { kubernetesApi } from '@/services/api';
|
||||
import type { KubernetesCluster } from '@/types';
|
||||
import { KubernetesClusterDetail } from './KubernetesClusterDetail';
|
||||
import { KubernetesClusterDialog } from './KubernetesClusterDialog';
|
||||
import { KubectlTerminal } from './KubectlTerminal';
|
||||
|
||||
export function KubernetesClusters() {
|
||||
const [clusters, setClusters] = useState<any[]>([]);
|
||||
@@ -42,6 +44,10 @@ export function KubernetesClusters() {
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [editingCluster, setEditingCluster] = useState<any>(null);
|
||||
|
||||
// kubectl 终端
|
||||
const [kubectlCluster, setKubectlCluster] = useState<{id: number; name: string} | null>(null);
|
||||
const [kubectlTerminalOpen, setKubectlTerminalOpen] = useState(false);
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
@@ -273,6 +279,17 @@ export function KubernetesClusters() {
|
||||
<Settings className="h-4 w-4 mr-2" />
|
||||
配置
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
className="text-emerald-400 focus:bg-slate-700 focus:text-emerald-300"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setKubectlCluster({ id: cluster.id, name: cluster.name });
|
||||
setKubectlTerminalOpen(true);
|
||||
}}
|
||||
>
|
||||
<Container className="h-4 w-4 mr-2" />
|
||||
kubectl
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator className="bg-slate-700" />
|
||||
<DropdownMenuItem
|
||||
className="text-red-400 focus:bg-slate-700 focus:text-red-400"
|
||||
@@ -355,6 +372,19 @@ export function KubernetesClusters() {
|
||||
editingCluster={editingCluster}
|
||||
onSaved={loadData}
|
||||
/>
|
||||
|
||||
{/* kubectl 终端 */}
|
||||
{kubectlCluster && (
|
||||
<KubectlTerminal
|
||||
open={kubectlTerminalOpen}
|
||||
onOpenChange={(open) => {
|
||||
setKubectlTerminalOpen(open);
|
||||
if (!open) setKubectlCluster(null);
|
||||
}}
|
||||
clusterId={kubectlCluster.id}
|
||||
clusterName={kubectlCluster.name}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user