diff --git a/package-lock.json b/package-lock.json index 67e99d42..07c1bd34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "class-variance-authority": "^0.7", "clsx": "^2", "lucide-react": "latest", + "monaco-editor": "^0.55.1", "react": "^19", "react-chartjs-2": "^5.3.1", "react-diff-viewer-continued": "^4", @@ -3001,6 +3002,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -5706,6 +5714,15 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/domutils": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", @@ -9404,6 +9421,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", + "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -10603,6 +10632,16 @@ "node": ">=18.0.0" } }, + "node_modules/monaco-editor": { + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", + "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", + "license": "MIT", + "dependencies": { + "dompurify": "3.2.7", + "marked": "14.0.0" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/package.json b/package.json index 7b383dad..6536bac9 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "class-variance-authority": "^0.7", "clsx": "^2", "lucide-react": "latest", + "monaco-editor": "^0.55.1", "react": "^19", "react-chartjs-2": "^5.3.1", "react-diff-viewer-continued": "^4", diff --git a/src-tauri/src/commands/kube.rs b/src-tauri/src/commands/kube.rs index a6a59188..a9113172 100644 --- a/src-tauri/src/commands/kube.rs +++ b/src-tauri/src/commands/kube.rs @@ -96,6 +96,9 @@ pub struct PodInfo { pub ready: String, pub age: String, pub containers: Vec, + pub restarts: Option, + pub ip: Option, + pub node: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -1159,6 +1162,35 @@ fn parse_pods_json(json_str: &str) -> Result, String> { }) .unwrap_or_default(); + let restarts = item + .get("status") + .and_then(|s| s.get("containerStatuses")) + .and_then(|c| c.as_array()) + .map(|container_statuses| { + container_statuses + .iter() + .map(|c| { + c.get("restartCount") + .and_then(|r| r.as_u64()) + .unwrap_or(0) as u32 + }) + .sum::() + }); + + let ip = item + .get("status") + .and_then(|s| s.get("podIP")) + .and_then(|v| v.as_str()) + .filter(|s| !s.is_empty()) + .map(|s| s.to_string()); + + let node = item + .get("spec") + .and_then(|s| s.get("nodeName")) + .and_then(|v| v.as_str()) + .filter(|s| !s.is_empty()) + .map(|s| s.to_string()); + pods.push(PodInfo { name, namespace, @@ -1166,6 +1198,9 @@ fn parse_pods_json(json_str: &str) -> Result, String> { ready, age, containers, + restarts, + ip, + node, }); } diff --git a/src/hooks/useKeyboardShortcuts.ts b/src/hooks/useKeyboardShortcuts.ts index 8cf6f4e3..3b6bd19d 100644 --- a/src/hooks/useKeyboardShortcuts.ts +++ b/src/hooks/useKeyboardShortcuts.ts @@ -13,7 +13,10 @@ export interface KeyboardShortcut { export function useKeyboardShortcuts(shortcuts: KeyboardShortcut[]): void { const shortcutsRef = useRef(shortcuts); - shortcutsRef.current = shortcuts; + + useEffect(() => { + shortcutsRef.current = shortcuts; + }, [shortcuts]); const handleKeyDown = useCallback((event: KeyboardEvent) => { for (const shortcut of shortcutsRef.current) { diff --git a/src/main.tsx b/src/main.tsx index 7bf91f83..c356d7f9 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,9 +1,15 @@ import React from "react"; import ReactDOM from "react-dom/client"; import { BrowserRouter } from "react-router-dom"; +import { loader } from "@monaco-editor/react"; +import * as monaco from "monaco-editor"; import App from "./App"; import "./styles/globals.css"; +// Use the locally bundled Monaco instead of loading from CDN. +// Tauri's WebView has no internet access so the default CDN loader never resolves. +loader.config({ monaco }); + ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(