import React from "react"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui"; import { Button } from "@/components/ui"; import { X, Loader2, AlertCircle, CheckCircle } from "lucide-react"; import { Input } from "@/components/ui"; import { YamlEditor } from "./YamlEditor"; import { createResourceCmd } from "@/lib/tauriCommands"; interface RbacEditorProps { clusterId: string; namespace: string; onClose?: () => void; } type TabKey = "roles" | "clusterroles" | "rolebindings" | "clusterrolebindings"; interface TabState { name: string; yaml: string; } function buildRoleYaml(name: string, namespace: string): string { return `apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ${name || "role-name"} namespace: ${namespace} rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"]`; } function buildClusterRoleYaml(name: string): string { return `apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: ${name || "clusterrole-name"} rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"]`; } function buildRoleBindingYaml(name: string, namespace: string): string { return `apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: ${name || "rolebinding-name"} namespace: ${namespace} subjects: - kind: User name: example-user apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io`; } function buildClusterRoleBindingYaml(name: string): string { return `apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: ${name || "clusterrolebinding-name"} subjects: - kind: User name: example-user apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: view apiGroup: rbac.authorization.k8s.io`; } export function RbacEditor({ clusterId, namespace, onClose }: RbacEditorProps) { const [activeTab, setActiveTab] = React.useState("roles"); const [tabState, setTabState] = React.useState>({ roles: { name: "", yaml: buildRoleYaml("", namespace) }, clusterroles: { name: "", yaml: buildClusterRoleYaml("") }, rolebindings: { name: "", yaml: buildRoleBindingYaml("", namespace) }, clusterrolebindings: { name: "", yaml: buildClusterRoleBindingYaml("") }, }); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); const [success, setSuccess] = React.useState(false); const setName = (tab: TabKey, name: string) => { setTabState((prev) => { let yaml = prev[tab].yaml; if (tab === "roles") yaml = buildRoleYaml(name, namespace); else if (tab === "clusterroles") yaml = buildClusterRoleYaml(name); else if (tab === "rolebindings") yaml = buildRoleBindingYaml(name, namespace); else if (tab === "clusterrolebindings") yaml = buildClusterRoleBindingYaml(name); return { ...prev, [tab]: { name, yaml } }; }); }; const setYaml = (tab: TabKey, yaml: string) => { setTabState((prev) => ({ ...prev, [tab]: { ...prev[tab], yaml } })); }; const handleCreate = async () => { const { name, yaml } = tabState[activeTab]; if (!name.trim()) return; setLoading(true); setError(null); setSuccess(false); const ns = activeTab === "clusterroles" || activeTab === "clusterrolebindings" ? "" : namespace; try { await createResourceCmd(clusterId, ns, activeTab, yaml); setSuccess(true); // Reset form for this tab setTabState((prev) => ({ ...prev, [activeTab]: { name: "", yaml: activeTab === "roles" ? buildRoleYaml("", namespace) : activeTab === "clusterroles" ? buildClusterRoleYaml("") : activeTab === "rolebindings" ? buildRoleBindingYaml("", namespace) : buildClusterRoleBindingYaml(""), }, })); setTimeout(() => { setSuccess(false); onClose?.(); }, 1200); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } finally { setLoading(false); } }; const tabMeta: { id: TabKey; label: string }[] = [ { id: "roles", label: "Roles" }, { id: "clusterroles", label: "ClusterRoles" }, { id: "rolebindings", label: "RoleBindings" }, { id: "clusterrolebindings", label: "ClusterRoleBindings" }, ]; return (

RBAC Editor

{error && (
{error}
)} {success && (
Resource created successfully.
)} setActiveTab(v as TabKey)}> {tabMeta.map((tab) => ( {tab.label} ))}
{tabMeta.map((tab) => (
setName(tab.id, e.target.value)} />
setYaml(tab.id, yaml)} showControls={false} height="100%" />
))}
); }