Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
omni-code / tui / dist / views / Containers.js
Size: Mime:
import React, { useCallback, useEffect, useState } from "react";
import { Box, Text, useInput } from "ink";
import { api } from "../rpc.js";
import { Panel } from "../components/Panel.js";
import { StatusBar } from "../components/StatusBar.js";
import { HelpOverlay } from "../components/HelpOverlay.js";
import { ConfirmDialog } from "../components/ConfirmDialog.js";
function clamp(value, max) {
    if (max <= 0)
        return 0;
    return Math.max(0, Math.min(value, max - 1));
}
function stateColor(state) {
    if (state === "running")
        return "green";
    if (state === "exited")
        return "red";
    if (state === "created")
        return "yellow";
    if (state === "paused")
        return "blue";
    return "gray";
}
const HELP_HINTS = [
    { key: "j/k", label: "navigate containers" },
    { key: "s", label: "start container" },
    { key: "x", label: "stop container" },
    { key: "R", label: "rebuild (remove) container" },
    { key: "r", label: "refresh" },
    { key: "?", label: "help" },
    { key: "q", label: "quit" },
];
const BAR_HINTS = [
    { key: "j/k", label: "navigate" },
    { key: "s", label: "start" },
    { key: "x", label: "stop" },
    { key: "R", label: "remove" },
    { key: "r", label: "refresh" },
    { key: "?", label: "help" },
    { key: "esc/q", label: "back" },
];
export function Containers({ onQuit }) {
    const [containers, setContainers] = useState([]);
    const [selected, setSelected] = useState(0);
    const [status, setStatus] = useState(null);
    const [loading, setLoading] = useState(true);
    const [showHelp, setShowHelp] = useState(false);
    const [confirmAction, setConfirmAction] = useState(null);
    const refresh = useCallback(async () => {
        try {
            const result = await api.listContainers();
            setContainers(result);
            setLoading(false);
        }
        catch (err) {
            setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`);
            setLoading(false);
        }
    }, []);
    useEffect(() => {
        refresh();
        const interval = setInterval(refresh, 5000);
        return () => clearInterval(interval);
    }, [refresh]);
    useEffect(() => {
        if (!status)
            return;
        const timer = setTimeout(() => setStatus(null), 4000);
        return () => clearTimeout(timer);
    }, [status]);
    const current = containers[selected] ?? null;
    useInput((input, key) => {
        if (showHelp || confirmAction)
            return;
        if (input === "?") {
            setShowHelp(true);
            return;
        }
        if (input === "q" || key.escape) {
            onQuit();
            return;
        }
        if (input === "r") {
            refresh();
            setStatus("Refreshed");
            return;
        }
        if (key.upArrow || input === "k") {
            setSelected((v) => clamp(v - 1, containers.length));
            return;
        }
        if (key.downArrow || input === "j") {
            setSelected((v) => clamp(v + 1, containers.length));
            return;
        }
        if (input === "s" && current) {
            setStatus(`Starting ${current.name}...`);
            api.startContainer(current.name)
                .then(() => { setStatus(`Started ${current.name}`); refresh(); })
                .catch((err) => setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`));
            return;
        }
        if (input === "x" && current) {
            const c = current;
            setConfirmAction({
                message: `Stop container "${c.name}"?`,
                action: () => {
                    setStatus(`Stopping ${c.name}...`);
                    api.stopContainer(c.name)
                        .then(() => { setStatus(`Stopped ${c.name}`); refresh(); })
                        .catch((err) => setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`));
                },
            });
            return;
        }
        if (input === "R" && current) {
            const c = current;
            setConfirmAction({
                message: `Remove container "${c.name}"?`,
                action: () => {
                    setStatus(`Removing ${c.name}...`);
                    api.rebuildContainer(c.name)
                        .then(() => { setStatus(`Removed ${c.name}`); refresh(); })
                        .catch((err) => setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`));
                },
            });
            return;
        }
    });
    if (showHelp) {
        return (React.createElement(Box, { flexDirection: "column", flexGrow: 1 },
            React.createElement(HelpOverlay, { title: "Containers", hints: HELP_HINTS, onClose: () => setShowHelp(false) })));
    }
    return (React.createElement(Box, { flexDirection: "column", flexGrow: 1 },
        React.createElement(Box, { flexDirection: "row", flexGrow: 1 },
            React.createElement(Panel, { title: `Containers (${containers.length})`, focused: true, flexGrow: 1 },
                React.createElement(Box, { flexDirection: "column", paddingX: 1 }, loading ? (React.createElement(Text, { color: "gray" }, "Loading containers...")) : containers.length === 0 ? (React.createElement(Text, { color: "gray" }, "No omni containers found.")) : (containers.map((c, i) => {
                    const isSelected = i === selected;
                    return (React.createElement(Text, { key: c.name, color: isSelected ? "cyan" : undefined, wrap: "truncate" },
                        isSelected ? "\u25B8 " : "  ",
                        React.createElement(Text, { color: stateColor(c.state), bold: true }, c.state.padEnd(8)),
                        "  ",
                        c.name));
                })))),
            current && !loading ? (React.createElement(Panel, { title: "Detail", flexGrow: 1 },
                React.createElement(Box, { flexDirection: "column", paddingX: 1 },
                    React.createElement(Box, null,
                        React.createElement(Text, { color: "gray" }, "Name    "),
                        React.createElement(Text, null, current.name)),
                    React.createElement(Box, null,
                        React.createElement(Text, { color: "gray" }, "Image   "),
                        React.createElement(Text, null, current.image)),
                    React.createElement(Box, null,
                        React.createElement(Text, { color: "gray" }, "Status  "),
                        React.createElement(Text, null, current.status)),
                    React.createElement(Box, null,
                        React.createElement(Text, { color: "gray" }, "Created "),
                        React.createElement(Text, null, current.created)),
                    current.ports ? React.createElement(Box, null,
                        React.createElement(Text, { color: "gray" }, "Ports   "),
                        React.createElement(Text, null, current.ports)) : null))) : null),
        confirmAction ? (React.createElement(Box, { paddingX: 1 },
            React.createElement(ConfirmDialog, { message: confirmAction.message, onConfirm: () => { confirmAction.action(); setConfirmAction(null); }, onCancel: () => setConfirmAction(null) }))) : null,
        React.createElement(StatusBar, { hints: BAR_HINTS, status: status })));
}
//# sourceMappingURL=Containers.js.map