Added LXC resource page
This commit is contained in:
		@@ -1,16 +1,16 @@
 | 
				
			|||||||
import { Link, useSearchParams } from "expo-router";
 | 
					import { Link, useSearchParams } from "expo-router";
 | 
				
			||||||
import { View, Text, SafeAreaView, ScrollView, Button } from "react-native";
 | 
					import { View, Text, ScrollView } from "react-native";
 | 
				
			||||||
import { NodeResource, useNode } from "../../../hooks/useNode";
 | 
					import { NodeResource, ResourceType, useNode } from "../../../hooks/useNode";
 | 
				
			||||||
import Icon from "@expo/vector-icons/Feather";
 | 
					import Icon from "@expo/vector-icons/Feather";
 | 
				
			||||||
import tw from "twrnc";
 | 
					import tw from "twrnc";
 | 
				
			||||||
import { formatBytes, formatPercentage } from "../../../lib/helper/format";
 | 
					import { formatBytes } from "../../../lib/helper/format";
 | 
				
			||||||
import { useEffect, useMemo } from "react";
 | 
					import { useMemo } from "react";
 | 
				
			||||||
import { Gauge } from "../../../components/Gauge";
 | 
					import { Gauge } from "../../../components/Gauge";
 | 
				
			||||||
import ProgressBar from "../../../components/ProgressBar";
 | 
					import ProgressBar from "../../../components/ProgressBar";
 | 
				
			||||||
import Card from "../../../components/Card";
 | 
					import Card from "../../../components/Card";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface ResourceListItemProps {
 | 
					interface ResourceListItemProps {
 | 
				
			||||||
  type: "LXC" | "QEMU";
 | 
					  type: ResourceType;
 | 
				
			||||||
  resource: NodeResource;
 | 
					  resource: NodeResource;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,7 +23,7 @@ export function ResourceListItem({ type, resource }: ResourceListItemProps) {
 | 
				
			|||||||
          resource.status === "running" ? "bg-green-200" : "bg-slate-200"
 | 
					          resource.status === "running" ? "bg-green-200" : "bg-slate-200"
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        {type === "LXC" ? (
 | 
					        {type === "lxc" ? (
 | 
				
			||||||
          <Icon name="package" size={22} />
 | 
					          <Icon name="package" size={22} />
 | 
				
			||||||
        ) : (
 | 
					        ) : (
 | 
				
			||||||
          <Icon name="monitor" size={22} />
 | 
					          <Icon name="monitor" size={22} />
 | 
				
			||||||
@@ -72,24 +72,28 @@ export default function NodePage() {
 | 
				
			|||||||
              </View>
 | 
					              </View>
 | 
				
			||||||
            )}
 | 
					            )}
 | 
				
			||||||
          </View>
 | 
					          </View>
 | 
				
			||||||
          {node.rdd.isSuccess && (
 | 
					          {node.rddData.isSuccess && (
 | 
				
			||||||
            <View>
 | 
					            <View>
 | 
				
			||||||
              <View style={tw.style("mb-2")}>
 | 
					              <View style={tw.style("mb-2")}>
 | 
				
			||||||
                <ProgressBar label="CPU" value={node.rdd.data.cpu} max={1} />
 | 
					                <ProgressBar
 | 
				
			||||||
 | 
					                  label="CPU"
 | 
				
			||||||
 | 
					                  value={node.rddData.data.cpu}
 | 
				
			||||||
 | 
					                  max={1}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
              </View>
 | 
					              </View>
 | 
				
			||||||
              <View style={tw.style("mb-2")}>
 | 
					              <View style={tw.style("mb-2")}>
 | 
				
			||||||
                <ProgressBar
 | 
					                <ProgressBar
 | 
				
			||||||
                  label="Memory"
 | 
					                  label="Memory"
 | 
				
			||||||
                  value={node.rdd.data.memused}
 | 
					                  value={node.rddData.data.memused}
 | 
				
			||||||
                  max={node.rdd.data.memtotal}
 | 
					                  max={node.rddData.data.memtotal}
 | 
				
			||||||
                  formatFn={formatBytes}
 | 
					                  formatFn={formatBytes}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
              </View>
 | 
					              </View>
 | 
				
			||||||
              <View style={tw.style("mb-2")}>
 | 
					              <View style={tw.style("mb-2")}>
 | 
				
			||||||
                <ProgressBar
 | 
					                <ProgressBar
 | 
				
			||||||
                  label="Storage"
 | 
					                  label="Storage"
 | 
				
			||||||
                  value={node.rdd.data.rootused}
 | 
					                  value={node.rddData.data.rootused}
 | 
				
			||||||
                  max={node.rdd.data.roottotal}
 | 
					                  max={node.rddData.data.roottotal}
 | 
				
			||||||
                  formatFn={formatBytes}
 | 
					                  formatFn={formatBytes}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
              </View>
 | 
					              </View>
 | 
				
			||||||
@@ -101,13 +105,13 @@ export default function NodePage() {
 | 
				
			|||||||
                <View style={tw.style("flex-1")}>
 | 
					                <View style={tw.style("flex-1")}>
 | 
				
			||||||
                  <Gauge
 | 
					                  <Gauge
 | 
				
			||||||
                    label="Up"
 | 
					                    label="Up"
 | 
				
			||||||
                    value={`${formatBytes(node.rdd.data.netout)}/s`}
 | 
					                    value={`${formatBytes(node.rddData.data.netout)}/s`}
 | 
				
			||||||
                  />
 | 
					                  />
 | 
				
			||||||
                </View>
 | 
					                </View>
 | 
				
			||||||
                <View style={tw.style("flex-1")}>
 | 
					                <View style={tw.style("flex-1")}>
 | 
				
			||||||
                  <Gauge
 | 
					                  <Gauge
 | 
				
			||||||
                    label="Down"
 | 
					                    label="Down"
 | 
				
			||||||
                    value={`${formatBytes(node.rdd.data.netin)}/s`}
 | 
					                    value={`${formatBytes(node.rddData.data.netin)}/s`}
 | 
				
			||||||
                  />
 | 
					                  />
 | 
				
			||||||
                </View>
 | 
					                </View>
 | 
				
			||||||
              </View>
 | 
					              </View>
 | 
				
			||||||
@@ -120,12 +124,12 @@ export default function NodePage() {
 | 
				
			|||||||
          <Link
 | 
					          <Link
 | 
				
			||||||
            key={lxc.vmid}
 | 
					            key={lxc.vmid}
 | 
				
			||||||
            href={{
 | 
					            href={{
 | 
				
			||||||
              pathname: "/nodes/[name]/lxc/[vmid]",
 | 
					              pathname: "/nodes/[node]/lxc/[vmid]",
 | 
				
			||||||
              params: { name: nodeName, vmid: lxc.vmid },
 | 
					              params: { node: nodeName, vmid: lxc.vmid },
 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
            style={tw.style("m-2")}
 | 
					            style={tw.style("m-2")}
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <ResourceListItem type="LXC" resource={lxc} />
 | 
					            <ResourceListItem type="lxc" resource={lxc} />
 | 
				
			||||||
          </Link>
 | 
					          </Link>
 | 
				
			||||||
        ))}
 | 
					        ))}
 | 
				
			||||||
      </Card>
 | 
					      </Card>
 | 
				
			||||||
@@ -134,12 +138,12 @@ export default function NodePage() {
 | 
				
			|||||||
          <Link
 | 
					          <Link
 | 
				
			||||||
            key={vm.vmid}
 | 
					            key={vm.vmid}
 | 
				
			||||||
            href={{
 | 
					            href={{
 | 
				
			||||||
              pathname: "/nodes/[node]/lxc/[vmid]",
 | 
					              pathname: "/nodes/[node]/qemu/[vmid]",
 | 
				
			||||||
              params: { node: nodeName, vmid: vm.vmid },
 | 
					              params: { node: nodeName, vmid: vm.vmid },
 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
            style={tw.style("m-2")}
 | 
					            style={tw.style("m-2")}
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <ResourceListItem type="QEMU" resource={vm} />
 | 
					            <ResourceListItem type="qemu" resource={vm} />
 | 
				
			||||||
          </Link>
 | 
					          </Link>
 | 
				
			||||||
        ))}
 | 
					        ))}
 | 
				
			||||||
      </Card>
 | 
					      </Card>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,21 +14,20 @@ function buildConsoleUrl(domain: string, node: string, vmid: string) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function QEMUResourceConsolePage() {
 | 
					export default function QEMUResourceConsolePage() {
 | 
				
			||||||
  const { name, vmid } = useSearchParams<{ name: string; vmid: string }>();
 | 
					  const { node, vmid } = useSearchParams<{ node: string; vmid: string }>();
 | 
				
			||||||
  const { domain, ticketData } = useAuthStore();
 | 
					  const { domain, ticketData } = useAuthStore();
 | 
				
			||||||
 | 
					  console.log({ ticketData }, buildConsoleUrl(domain, node, vmid));
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SafeAreaView style={{ flex: 1 }}>
 | 
					    <SafeAreaView style={{ flex: 1 }}>
 | 
				
			||||||
      <WebView
 | 
					      <WebView
 | 
				
			||||||
        source={{
 | 
					        source={{
 | 
				
			||||||
          uri: buildConsoleUrl(domain, name, vmid),
 | 
					          uri: buildConsoleUrl(domain, node, vmid),
 | 
				
			||||||
          headers: {
 | 
					          headers: {
 | 
				
			||||||
            Cookie: `PVEAuthCookie=${ticketData.data.ticket}`,
 | 
					            Cookie: `PVEAuthCookie=${ticketData.data.ticket}`,
 | 
				
			||||||
            CSRFPreventionToken: ticketData.data.CSRFPreventionToken,
 | 
					 | 
				
			||||||
            Accept:
 | 
					            Accept:
 | 
				
			||||||
              "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
 | 
					              "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
        allowsFullscreenVideo={true}
 | 
					 | 
				
			||||||
        scalesPageToFit={false}
 | 
					        scalesPageToFit={false}
 | 
				
			||||||
        injectedJavaScript={`
 | 
					        injectedJavaScript={`
 | 
				
			||||||
            const meta = document.createElement('meta'); 
 | 
					            const meta = document.createElement('meta'); 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +1,128 @@
 | 
				
			|||||||
import { View, Text } from "react-native";
 | 
					import { useRouter, useSearchParams } from "expo-router";
 | 
				
			||||||
 | 
					import { useMemo } from "react";
 | 
				
			||||||
 | 
					import { View, Text, TouchableHighlight, ScrollView } from "react-native";
 | 
				
			||||||
 | 
					import Icon from "@expo/vector-icons/Feather";
 | 
				
			||||||
import tw from "twrnc";
 | 
					import tw from "twrnc";
 | 
				
			||||||
 | 
					import Card from "../../../../../components/Card";
 | 
				
			||||||
 | 
					import { Gauge } from "../../../../../components/Gauge";
 | 
				
			||||||
 | 
					import ProgressBar from "../../../../../components/ProgressBar";
 | 
				
			||||||
 | 
					import { useNode } from "../../../../../hooks/useNode";
 | 
				
			||||||
 | 
					import { useResource } from "../../../../../hooks/useResource";
 | 
				
			||||||
 | 
					import { formatBytes } from "../../../../../lib/helper/format";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function LXCResourcePage() {
 | 
					export default function LXCResourcePage() {
 | 
				
			||||||
  return (
 | 
					  const router = useRouter();
 | 
				
			||||||
    <View>
 | 
					  const { node, vmid } = useSearchParams<{ node: string; vmid: string }>();
 | 
				
			||||||
      <View
 | 
					  const { rddData, config } = useResource(node, "lxc", vmid);
 | 
				
			||||||
        style={tw.style("bg-white m-2 p-3 rounded-lg border border-slate-200")}
 | 
					  const { lxc: lxcs } = useNode(node);
 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        <Text>Currently not supported</Text>
 | 
					 | 
				
			||||||
      </View>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <Text style={tw.style("ml-6 mt-4")}>Config</Text>
 | 
					  const status = useMemo(() => {
 | 
				
			||||||
      <View
 | 
					    if (lxcs.isSuccess) {
 | 
				
			||||||
        style={tw.style("bg-white m-2 p-1 rounded-lg border border-slate-200")}
 | 
					      return lxcs.data.find((lxc) => lxc.vmid.toString() === vmid);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }, [lxcs]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <ScrollView>
 | 
				
			||||||
 | 
					      <Card>
 | 
				
			||||||
 | 
					        <View style={tw.style("p-1")}>
 | 
				
			||||||
 | 
					          <View style={tw.style("px-1 mb-4")}>
 | 
				
			||||||
 | 
					            <View style={tw.style("flex flex-row items-center")}>
 | 
				
			||||||
 | 
					              <View
 | 
				
			||||||
 | 
					                style={tw.style(
 | 
				
			||||||
 | 
					                  "h-12 w-12 rounded-lg flex flex-row justify-center items-center",
 | 
				
			||||||
 | 
					                  status.status === "running" ? "bg-green-200" : "bg-slate-200"
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <Icon name="monitor" size={22} />
 | 
				
			||||||
 | 
					              </View>
 | 
				
			||||||
 | 
					              <View style={tw.style("mx-2 flex-1")}>
 | 
				
			||||||
 | 
					                <Text style={tw.style("text-xl")}>
 | 
				
			||||||
 | 
					                  {vmid}: {status.name}
 | 
				
			||||||
 | 
					                </Text>
 | 
				
			||||||
 | 
					                <Text style={tw.style("text-base")}>Node: {node}</Text>
 | 
				
			||||||
 | 
					              </View>
 | 
				
			||||||
 | 
					              <View
 | 
				
			||||||
 | 
					                style={tw.style(
 | 
				
			||||||
 | 
					                  "h-12 w-12 flex flex-row justify-center items-center"
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <Icon name="power" size={22} />
 | 
				
			||||||
 | 
					              </View>
 | 
				
			||||||
 | 
					            </View>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					          {rddData.isSuccess && (
 | 
				
			||||||
 | 
					            <View>
 | 
				
			||||||
 | 
					              <View style={tw.style("mb-2")}>
 | 
				
			||||||
 | 
					                <ProgressBar label="CPU" value={rddData.data.cpu} max={1} />
 | 
				
			||||||
 | 
					              </View>
 | 
				
			||||||
 | 
					              <View style={tw.style("mb-2")}>
 | 
				
			||||||
 | 
					                <ProgressBar
 | 
				
			||||||
 | 
					                  label="Memory"
 | 
				
			||||||
 | 
					                  value={rddData.data.mem ?? 1}
 | 
				
			||||||
 | 
					                  max={rddData.data.maxmem ?? 1}
 | 
				
			||||||
 | 
					                  formatFn={formatBytes}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					              </View>
 | 
				
			||||||
 | 
					              <View style={tw.style("mb-2")}>
 | 
				
			||||||
 | 
					                <ProgressBar
 | 
				
			||||||
 | 
					                  label="Storage"
 | 
				
			||||||
 | 
					                  value={rddData.data.disk ?? 1}
 | 
				
			||||||
 | 
					                  max={rddData.data.maxdisk ?? 1}
 | 
				
			||||||
 | 
					                  formatFn={formatBytes}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					              </View>
 | 
				
			||||||
 | 
					              <View
 | 
				
			||||||
 | 
					                style={tw.style(
 | 
				
			||||||
 | 
					                  "flex flex-row justify-evenly items-center p-2"
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <View style={tw.style("flex-1")}>
 | 
				
			||||||
 | 
					                  <Gauge
 | 
				
			||||||
 | 
					                    label="Up"
 | 
				
			||||||
 | 
					                    value={`${formatBytes(rddData.data.netout)}/s`}
 | 
				
			||||||
 | 
					                  />
 | 
				
			||||||
 | 
					                </View>
 | 
				
			||||||
 | 
					                <View style={tw.style("flex-1")}>
 | 
				
			||||||
 | 
					                  <Gauge
 | 
				
			||||||
 | 
					                    label="Down"
 | 
				
			||||||
 | 
					                    value={`${formatBytes(rddData.data.netin)}/s`}
 | 
				
			||||||
 | 
					                  />
 | 
				
			||||||
 | 
					                </View>
 | 
				
			||||||
 | 
					              </View>
 | 
				
			||||||
 | 
					            </View>
 | 
				
			||||||
 | 
					          )}
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					      </Card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <TouchableHighlight
 | 
				
			||||||
 | 
					        style={tw.style("m-2 rounded-lg bg-slate-800")}
 | 
				
			||||||
 | 
					        onPress={() =>
 | 
				
			||||||
 | 
					          router.push({
 | 
				
			||||||
 | 
					            pathname: "/nodes/[node]/lxc/[vmid]/console",
 | 
				
			||||||
 | 
					            params: { node, vmid },
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <Text style={tw.style("px-2 py-7 flex flex-row text-center")}>
 | 
					        <View style={tw.style("flex flex-row m-4 items-center justify-center")}>
 | 
				
			||||||
          Currently not supported
 | 
					          <Icon name="terminal" size={22} style={tw.style("mr-2 text-white")} />
 | 
				
			||||||
        </Text>
 | 
					          <Text style={tw.style("text-white")}>Open terminal</Text>
 | 
				
			||||||
      </View>
 | 
					        </View>
 | 
				
			||||||
    </View>
 | 
					      </TouchableHighlight>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <Card>
 | 
				
			||||||
 | 
					        <View style={tw.style("m-2")}>
 | 
				
			||||||
 | 
					          {config.isSuccess &&
 | 
				
			||||||
 | 
					            Object.entries(config.data).map(([key, val]) => {
 | 
				
			||||||
 | 
					              return (
 | 
				
			||||||
 | 
					                <View key={key} style={tw.style("mb-1")}>
 | 
				
			||||||
 | 
					                  <Text style={tw.style("text-lg")}>{key}:</Text>
 | 
				
			||||||
 | 
					                  <Text>{val}</Text>
 | 
				
			||||||
 | 
					                </View>
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
 | 
					            })}
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					      </Card>
 | 
				
			||||||
 | 
					    </ScrollView>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import { Link } from "expo-router";
 | 
					import { Link } from "expo-router";
 | 
				
			||||||
import { View, Text, SafeAreaView } from "react-native";
 | 
					import { View, Text } from "react-native";
 | 
				
			||||||
import { ProxmoxNode, useNodes } from "../../hooks/useNodes";
 | 
					import { ProxmoxNode, useNodes } from "../../hooks/useNodes";
 | 
				
			||||||
import Icon from "@expo/vector-icons/Feather";
 | 
					import Icon from "@expo/vector-icons/Feather";
 | 
				
			||||||
import tw from "twrnc";
 | 
					import tw from "twrnc";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ interface CardProps {
 | 
				
			|||||||
export default function Card({ label, children }: CardProps) {
 | 
					export default function Card({ label, children }: CardProps) {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      {label && <Text style={tw.style("ml-6 mt-4")}>{label}</Text>}
 | 
					      {label && <Text style={tw.style("ml-6 mt-2")}>{label}</Text>}
 | 
				
			||||||
      <View
 | 
					      <View
 | 
				
			||||||
        style={tw.style("bg-white m-2 p-1 rounded-lg border border-slate-200")}
 | 
					        style={tw.style("bg-white m-2 p-1 rounded-lg border border-slate-200")}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
  View,
 | 
					  View,
 | 
				
			||||||
  TouchableOpacity,
 | 
					 | 
				
			||||||
  Text,
 | 
					  Text,
 | 
				
			||||||
  TextInput,
 | 
					  TextInput,
 | 
				
			||||||
  SafeAreaView,
 | 
					  SafeAreaView,
 | 
				
			||||||
  TextInputProps,
 | 
					  TextInputProps,
 | 
				
			||||||
 | 
					  TouchableHighlight,
 | 
				
			||||||
} from "react-native";
 | 
					} from "react-native";
 | 
				
			||||||
import React, { useState } from "react";
 | 
					import React, { useState } from "react";
 | 
				
			||||||
import tw from "twrnc";
 | 
					import tw from "twrnc";
 | 
				
			||||||
@@ -92,14 +92,14 @@ export default function Login() {
 | 
				
			|||||||
            secureTextEntry
 | 
					            secureTextEntry
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
        <TouchableOpacity
 | 
					        <TouchableHighlight
 | 
				
			||||||
          style={tw.style(
 | 
					          style={tw.style(
 | 
				
			||||||
            "flex bg-slate-700 rounded-md flex flex-row items-center justify-center"
 | 
					            "flex bg-slate-700 rounded-md flex flex-row items-center justify-center"
 | 
				
			||||||
          )}
 | 
					          )}
 | 
				
			||||||
          onPress={() => ticketMut.mutate({ domain, username, password })}
 | 
					          onPress={() => ticketMut.mutate({ domain, username, password })}
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <Text style={tw.style("text-white font-semibold py-3")}>Sign In</Text>
 | 
					          <Text style={tw.style("text-white font-semibold py-3")}>Sign In</Text>
 | 
				
			||||||
        </TouchableOpacity>
 | 
					        </TouchableHighlight>
 | 
				
			||||||
      </SafeAreaView>
 | 
					      </SafeAreaView>
 | 
				
			||||||
    </View>
 | 
					    </View>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import { useQueries, useQuery } from "react-query";
 | 
					import { useQueries, useQuery } from "react-query";
 | 
				
			||||||
import useAuthStore from "../stores/useAuthStore";
 | 
					import useAuthStore from "../stores/useAuthStore";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ResourceType = "LXC" | "QEMU";
 | 
					export type ResourceType = "lxc" | "qemu";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface NodeResource {
 | 
					export interface NodeResource {
 | 
				
			||||||
  status: "stopped" | "running";
 | 
					  status: "stopped" | "running";
 | 
				
			||||||
@@ -18,7 +18,7 @@ export interface NodeStatus {
 | 
				
			|||||||
  kversion: string;
 | 
					  kversion: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface NodeRDD {
 | 
					export interface NodeRddData {
 | 
				
			||||||
  netin: number;
 | 
					  netin: number;
 | 
				
			||||||
  netout: number;
 | 
					  netout: number;
 | 
				
			||||||
  rootused: number;
 | 
					  rootused: number;
 | 
				
			||||||
@@ -30,17 +30,17 @@ export interface NodeRDD {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export function useNode(name: string) {
 | 
					export function useNode(name: string) {
 | 
				
			||||||
  const http = useAuthStore((state) => state.http);
 | 
					  const http = useAuthStore((state) => state.http);
 | 
				
			||||||
  const [rdd, status, lxc, qemu] = useQueries([
 | 
					  const [rddData, status, lxc, qemu] = useQueries([
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      queryKey: ["nodes", name, "rdd"],
 | 
					      queryKey: ["nodes", name, "rddData"],
 | 
				
			||||||
      queryFn: () =>
 | 
					      queryFn: () =>
 | 
				
			||||||
        http.get<{ data: NodeRDD[] }>(`/api2/json/nodes/${name}/rrddata`, {
 | 
					        http.get<{ data: NodeRddData[] }>(`/api2/json/nodes/${name}/rrddata`, {
 | 
				
			||||||
          params: {
 | 
					          params: {
 | 
				
			||||||
            timeframe: "hour",
 | 
					            timeframe: "hour",
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
      enabled: !!name,
 | 
					      enabled: !!name,
 | 
				
			||||||
      select: (data): NodeRDD => data.data.data.at(-1),
 | 
					      select: (data): NodeRddData => data.data.data.at(-1),
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      queryKey: ["nodes", name, "status"],
 | 
					      queryKey: ["nodes", name, "status"],
 | 
				
			||||||
@@ -66,7 +66,7 @@ export function useNode(name: string) {
 | 
				
			|||||||
  ]);
 | 
					  ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    rdd,
 | 
					    rddData,
 | 
				
			||||||
    status,
 | 
					    status,
 | 
				
			||||||
    lxc,
 | 
					    lxc,
 | 
				
			||||||
    qemu,
 | 
					    qemu,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,22 +21,6 @@ export function useNodes() {
 | 
				
			|||||||
    ["nodes"],
 | 
					    ["nodes"],
 | 
				
			||||||
    async () => {
 | 
					    async () => {
 | 
				
			||||||
      return http.get<GetNodeResp>("/api2/json/nodes");
 | 
					      return http.get<GetNodeResp>("/api2/json/nodes");
 | 
				
			||||||
      // return {
 | 
					 | 
				
			||||||
      //   data: {
 | 
					 | 
				
			||||||
      //     data: [
 | 
					 | 
				
			||||||
      //       {
 | 
					 | 
				
			||||||
      //         cpu: 0.0166442953020134,
 | 
					 | 
				
			||||||
      //         mem: 21713018880,
 | 
					 | 
				
			||||||
      //         maxmem: 29306216448,
 | 
					 | 
				
			||||||
      //         uptime: 4854322,
 | 
					 | 
				
			||||||
      //         status: "online",
 | 
					 | 
				
			||||||
      //         maxcpu: 12,
 | 
					 | 
				
			||||||
      //         node: "pve",
 | 
					 | 
				
			||||||
      //       },
 | 
					 | 
				
			||||||
      //     ] as ProxmoxNode[],
 | 
					 | 
				
			||||||
      //   },
 | 
					 | 
				
			||||||
      //   isSuccess: true,
 | 
					 | 
				
			||||||
      // };
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    { select: (data) => data.data.data, refetchInterval: 6000 }
 | 
					    { select: (data) => data.data.data, refetchInterval: 6000 }
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										52
									
								
								hooks/useResource.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								hooks/useResource.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					import { useQueries } from "react-query";
 | 
				
			||||||
 | 
					import useAuthStore from "../stores/useAuthStore";
 | 
				
			||||||
 | 
					import { ResourceType } from "./useNode";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ResourceRddData {
 | 
				
			||||||
 | 
					  cpu: number;
 | 
				
			||||||
 | 
					  disk: number;
 | 
				
			||||||
 | 
					  maxdisk: number;
 | 
				
			||||||
 | 
					  mem: number;
 | 
				
			||||||
 | 
					  maxmem: number;
 | 
				
			||||||
 | 
					  netin: number;
 | 
				
			||||||
 | 
					  netout: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function useResource(
 | 
				
			||||||
 | 
					  node: string,
 | 
				
			||||||
 | 
					  type: ResourceType,
 | 
				
			||||||
 | 
					  vmid: string | number
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  console.log({ node, type, vmid });
 | 
				
			||||||
 | 
					  const http = useAuthStore((state) => state.http);
 | 
				
			||||||
 | 
					  const [rddData, config] = useQueries([
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      queryKey: ["nodes", node, type, vmid, "rdd"],
 | 
				
			||||||
 | 
					      queryFn: () =>
 | 
				
			||||||
 | 
					        http.get<{ data: ResourceRddData[] }>(
 | 
				
			||||||
 | 
					          `/api2/json/nodes/${node}/${type}/${vmid}/rrddata`,
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            params: {
 | 
				
			||||||
 | 
					              timeframe: "hour",
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      enabled: !!(node && vmid),
 | 
				
			||||||
 | 
					      select: (data): ResourceRddData => data.data.data.at(-1),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      queryKey: ["nodes", node, type, vmid, "config"],
 | 
				
			||||||
 | 
					      queryFn: () =>
 | 
				
			||||||
 | 
					        http.get<{ data: object }>(
 | 
				
			||||||
 | 
					          `/api2/json/nodes/${node}/${type}/${vmid}/config`
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      enabled: !!(node && vmid),
 | 
				
			||||||
 | 
					      select: (data): object => data.data.data,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    rddData,
 | 
				
			||||||
 | 
					    config,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -19,7 +19,7 @@ export async function createTicket({
 | 
				
			|||||||
  username,
 | 
					  username,
 | 
				
			||||||
  password,
 | 
					  password,
 | 
				
			||||||
}: CreateTicketOpts) {
 | 
					}: CreateTicketOpts) {
 | 
				
			||||||
  const url = `${domain}/api2/json/access/ticket`;
 | 
					  const url = new URL("/api2/json/access/ticket", domain).toString();
 | 
				
			||||||
  const headers = { "Content-Type": "application/json" };
 | 
					  const headers = { "Content-Type": "application/json" };
 | 
				
			||||||
  return axios.post<CreateTicketResp>(url, { username, password }, { headers });
 | 
					  return axios.post<CreateTicketResp>(url, { username, password }, { headers });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user