fix(kube): correct kubectl context, dialog close, icon visibility, cluster name #80
@ -270,7 +270,8 @@ pub async fn test_cluster_connection(
|
||||
let output = Command::new(kubectl_path)
|
||||
.arg("cluster-info")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -323,7 +324,8 @@ pub async fn discover_pods(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -458,8 +460,9 @@ pub async fn start_port_forward(
|
||||
// Spawn kubectl subprocess
|
||||
let child = Command::new(kubectl_path)
|
||||
.args(&args)
|
||||
.arg("--context")
|
||||
.arg(cluster.context.as_str())
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", &cluster.context)
|
||||
.spawn()
|
||||
.map_err(|e| format!("Failed to spawn kubectl: {e}"))?;
|
||||
|
||||
@ -768,7 +771,8 @@ pub async fn list_namespaces(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -854,7 +858,8 @@ pub async fn list_pods(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -976,7 +981,8 @@ pub async fn list_services(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -1133,7 +1139,8 @@ pub async fn list_deployments(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -1266,7 +1273,8 @@ pub async fn list_statefulsets(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -1383,7 +1391,8 @@ pub async fn list_daemonsets(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -1547,7 +1556,8 @@ pub async fn get_pod_logs(
|
||||
.arg("-c")
|
||||
.arg(container_name)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -1596,7 +1606,8 @@ pub async fn scale_deployment(
|
||||
.arg("-n")
|
||||
.arg(namespace)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -1641,7 +1652,8 @@ pub async fn restart_deployment(
|
||||
.arg("-n")
|
||||
.arg(namespace)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -1686,7 +1698,8 @@ pub async fn delete_resource(
|
||||
.arg("-n")
|
||||
.arg(namespace)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -1754,7 +1767,8 @@ pub async fn exec_pod(
|
||||
cmd.arg("--").arg(shell_cmd).arg("-c").arg(&command);
|
||||
|
||||
cmd.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context);
|
||||
.arg("--context")
|
||||
.arg(context.as_str());
|
||||
|
||||
let output = cmd
|
||||
.output()
|
||||
@ -2014,7 +2028,8 @@ pub async fn list_replicasets(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -2131,7 +2146,8 @@ pub async fn list_jobs(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -2286,7 +2302,8 @@ pub async fn list_cronjobs(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -2412,7 +2429,8 @@ pub async fn list_configmaps(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -2509,7 +2527,8 @@ pub async fn list_secrets(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -2607,7 +2626,8 @@ pub async fn list_nodes(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -2799,7 +2819,8 @@ pub async fn list_events(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -2927,7 +2948,8 @@ pub async fn list_ingresses(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3052,7 +3074,8 @@ pub async fn list_persistentvolumeclaims(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3176,7 +3199,8 @@ pub async fn list_persistentvolumes(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3306,7 +3330,8 @@ pub async fn list_serviceaccounts(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3403,7 +3428,8 @@ pub async fn list_roles(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3487,7 +3513,8 @@ pub async fn list_clusterroles(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3566,7 +3593,8 @@ pub async fn list_rolebindings(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3661,7 +3689,8 @@ pub async fn list_clusterrolebindings(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3751,7 +3780,8 @@ pub async fn list_horizontalpodautoscalers(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3863,7 +3893,8 @@ pub async fn list_storageclasses(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -3972,7 +4003,8 @@ pub async fn list_networkpolicies(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -4082,7 +4114,8 @@ pub async fn list_resourcequotas(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -4202,7 +4235,8 @@ pub async fn list_limitranges(
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -4293,7 +4327,8 @@ pub async fn cordon_node(
|
||||
.arg("cordon")
|
||||
.arg(node_name)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -4333,7 +4368,8 @@ pub async fn uncordon_node(
|
||||
.arg("uncordon")
|
||||
.arg(node_name)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -4376,7 +4412,8 @@ pub async fn drain_node(
|
||||
.arg("--delete-emptydir-data")
|
||||
.arg("--force")
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -4421,7 +4458,8 @@ pub async fn rollback_deployment(
|
||||
.arg("-n")
|
||||
.arg(namespace)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||
@ -4466,7 +4504,8 @@ pub async fn create_resource(
|
||||
.arg("-n")
|
||||
.arg(namespace)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped());
|
||||
@ -4528,7 +4567,8 @@ pub async fn edit_resource(
|
||||
.arg("-n")
|
||||
.arg(namespace)
|
||||
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||
.env("KUBERNETES_CONTEXT", context)
|
||||
.arg("--context")
|
||||
.arg(context.as_str())
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped());
|
||||
|
||||
@ -117,9 +117,11 @@ export function ClusterOverview({ clusterId, clusterName }: ClusterOverviewProps
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold">Cluster Overview</h2>
|
||||
<p className="text-muted-foreground text-sm mt-0.5" data-testid="cluster-name-header">
|
||||
{clusterName ?? clusterId}
|
||||
</p>
|
||||
{clusterName && (
|
||||
<p className="text-muted-foreground text-sm mt-0.5" data-testid="cluster-name-header">
|
||||
{clusterName}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => void loadData()}
|
||||
|
||||
@ -2,8 +2,6 @@ import React from "react";
|
||||
import { Button } from "@/components/ui";
|
||||
import { Settings, Bell, User, Search, Plus, RefreshCw } from "lucide-react";
|
||||
import { Badge } from "@/components/ui";
|
||||
import { useKubernetesStore } from "@/stores/kubernetesStore";
|
||||
import { useStore } from "zustand";
|
||||
|
||||
interface HotbarProps {
|
||||
onRefresh: () => void;
|
||||
@ -11,21 +9,25 @@ interface HotbarProps {
|
||||
onSettings: () => void;
|
||||
onNotifications?: () => void;
|
||||
notificationCount?: number;
|
||||
clusterName?: string;
|
||||
}
|
||||
|
||||
export function Hotbar({ onRefresh, onAddResource, onSettings, onNotifications, notificationCount = 0 }: HotbarProps) {
|
||||
const clusters = useStore(useKubernetesStore, (state) => state.clusters);
|
||||
const selectedClusterId = useStore(useKubernetesStore, (state) => state.selectedClusterId);
|
||||
const selectedCluster = clusters.find((c: { id: string }) => c.id === selectedClusterId);
|
||||
|
||||
export function Hotbar({
|
||||
onRefresh,
|
||||
onAddResource,
|
||||
onSettings,
|
||||
onNotifications,
|
||||
notificationCount = 0,
|
||||
clusterName,
|
||||
}: HotbarProps) {
|
||||
return (
|
||||
<div className="h-12 bg-background border-b flex items-center justify-between px-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Button variant="ghost" size="sm" onClick={onRefresh}>
|
||||
<Button variant="ghost" size="sm" onClick={onRefresh} className="text-foreground">
|
||||
<RefreshCw className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" onClick={onAddResource}>
|
||||
<Button variant="ghost" size="sm" onClick={onAddResource} className="text-foreground">
|
||||
<Plus className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
@ -33,33 +35,35 @@ export function Hotbar({ onRefresh, onAddResource, onSettings, onNotifications,
|
||||
<div className="flex items-center gap-2">
|
||||
<Search className="w-4 h-4 text-muted-foreground" />
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{selectedCluster?.name || "No cluster selected"}
|
||||
{clusterName ?? "No cluster selected"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={onNotifications}
|
||||
aria-label="Notifications"
|
||||
>
|
||||
<Bell className="w-4 h-4" />
|
||||
{notificationCount > 0 && (
|
||||
<Badge variant="destructive" className="h-4 w-4 flex items-center justify-center p-0 text-[10px]">
|
||||
{notificationCount}
|
||||
</Badge>
|
||||
)}
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" onClick={onSettings}>
|
||||
<Settings className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm">
|
||||
<User className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={onNotifications}
|
||||
aria-label="Notifications"
|
||||
className="text-foreground"
|
||||
>
|
||||
<Bell className="w-4 h-4" />
|
||||
{notificationCount > 0 && (
|
||||
<Badge
|
||||
variant="destructive"
|
||||
className="h-4 w-4 flex items-center justify-center p-0 text-[10px]"
|
||||
>
|
||||
{notificationCount}
|
||||
</Badge>
|
||||
)}
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" onClick={onSettings} className="text-foreground">
|
||||
<Settings className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="text-foreground">
|
||||
<User className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -605,13 +605,26 @@ export function DialogContent({ className, children }: { className?: string; chi
|
||||
if (!ctx.open) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
|
||||
<div
|
||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm"
|
||||
onClick={() => ctx.onOpenChange(false)}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg",
|
||||
"relative w-full max-w-lg gap-4 border bg-background p-6 shadow-lg duration-200 rounded-lg",
|
||||
className
|
||||
)}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<button
|
||||
onClick={() => ctx.onOpenChange(false)}
|
||||
className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground"
|
||||
aria-label="Close"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M18 6 6 18"/><path d="m6 6 12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -594,11 +594,10 @@ export function KubernetesPage() {
|
||||
}
|
||||
|
||||
if (activeSection === "overview") {
|
||||
const overviewConfig = kubeconfigs.find((c) => c.id === selectedClusterId);
|
||||
return (
|
||||
<ClusterOverview
|
||||
clusterId={selectedClusterId}
|
||||
clusterName={overviewConfig?.context}
|
||||
clusterName={selectedConfig?.name}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -706,6 +705,7 @@ export function KubernetesPage() {
|
||||
onAddResource={() => setIsCommandPaletteOpen(true)}
|
||||
onSettings={() => {}}
|
||||
onNotifications={() => setIsNotificationsOpen(true)}
|
||||
clusterName={selectedConfig?.name}
|
||||
/>
|
||||
|
||||
{/* Top bar: cluster selector + namespace selector */}
|
||||
|
||||
@ -178,14 +178,20 @@ describe("ClusterOverview", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("falls back gracefully when clusterName prop is not provided", async () => {
|
||||
it("hides the subtitle when clusterName prop is not provided (never shows UUID)", async () => {
|
||||
mockInvoke.mockImplementation(() => Promise.resolve([]));
|
||||
|
||||
render(<ClusterOverview clusterId="cluster-1" />);
|
||||
render(<ClusterOverview clusterId="019e9ff0-b6a4-78e1-a566-7a0c05e32577" />);
|
||||
|
||||
await waitFor(() => {
|
||||
const header = screen.getByTestId("cluster-name-header");
|
||||
expect(header).toBeInTheDocument();
|
||||
// Heading still present
|
||||
expect(screen.getByText("Cluster Overview")).toBeInTheDocument();
|
||||
// UUID must NOT be rendered anywhere
|
||||
expect(
|
||||
screen.queryByText("019e9ff0-b6a4-78e1-a566-7a0c05e32577")
|
||||
).not.toBeInTheDocument();
|
||||
// Subtitle element should not exist when no name is passed
|
||||
expect(screen.queryByTestId("cluster-name-header")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user