diff --git a/src/components/pages/admin/services/(partials)/service.tsx b/src/components/pages/admin/services/(partials)/service.tsx index 300c9b5..f35cf1f 100644 --- a/src/components/pages/admin/services/(partials)/service.tsx +++ b/src/components/pages/admin/services/(partials)/service.tsx @@ -1,19 +1,73 @@ import { AppContext } from "@/src/pages/_app"; -import { ParsedDeploymentServiceConfig } from "@/src/types"; +import { + NormalizedServerObject, + ParsedDeploymentServiceConfig, +} from "@/src/types"; import ArrowedLink from "@/twui/components/layout/ArrowedLink"; +import Button from "@/twui/components/layout/Button"; import H2 from "@/twui/components/layout/H2"; import Row from "@/twui/components/layout/Row"; import Stack from "@/twui/components/layout/Stack"; -import { useContext } from "react"; +import { useContext, useEffect, useRef, useState } from "react"; +import ServiceClusterServer from "../service/(partials)/cluster-server"; +import { twMerge } from "tailwind-merge"; +import Select from "@/twui/components/form/Select"; +import useStatus from "@/twui/components/hooks/useStatus"; +import Loading from "@/twui/components/elements/Loading"; +import _ from "lodash"; type Props = { service: ParsedDeploymentServiceConfig; }; export default function DeploymentService({ service }: Props) { - const { pageProps } = useContext(AppContext); + const { pageProps, ws } = useContext(AppContext); const { deployment } = pageProps; + const { ready, setReady } = useStatus(); + + const children_services = deployment?.services.filter( + (srv) => srv.parent_service_name == service.service_name, + ); + + const all_clusters = [service, ...(children_services || [])]; + + const [targetCluster, setTargetCluster] = useState< + ParsedDeploymentServiceConfig | undefined + >(all_clusters?.[0]); + + const targetClusterIndex = + all_clusters.findIndex( + (cl) => cl.service_name == targetCluster?.service_name, + ) + 1; + + const cluster_servers = targetCluster?.servers; + + const [targetServer, setTargetServer] = useState< + NormalizedServerObject | undefined + >(cluster_servers?.[0]); + + const portRef = useRef(undefined); + + useEffect(() => { + setReady(false); + + console.log("portRef", portRef); + + if (targetServer && portRef.current) { + ws.sendData({ + event: "client:kill-port", + server: targetServer, + service: _.omit(service, ["servers"]), + port: portRef.current, + }); + } + + setTimeout(() => { + setReady(true); + }, 2000); + }, [targetCluster, targetServer]); + return ( @@ -27,7 +81,75 @@ export default function DeploymentService({ service }: Props) { /> - {service.service_name} + {service.service_name} service + + +
+ + + ({ + value: srv.private_ip!, + title: srv.private_ip, + }))} + changeHandler={(v) => { + setTargetServer( + cluster_servers.find( + (srv) => srv.private_ip == v, + ), + ); + }} + /> + ) : undefined} + + {/* {cluster_servers?.map((server, index) => { + const is_active = + server?.private_ip == targetServer?.private_ip; + + return ( + + ); + })} */} + + + {ready ? ( + targetServer ? ( + + ) : undefined + ) : undefined}
); diff --git a/src/components/pages/admin/services/service/(partials)/cluster-server-log-selector-select-log.tsx b/src/components/pages/admin/services/service/(partials)/cluster-server-log-selector-select-log.tsx new file mode 100644 index 0000000..b360200 --- /dev/null +++ b/src/components/pages/admin/services/service/(partials)/cluster-server-log-selector-select-log.tsx @@ -0,0 +1,65 @@ +import { Dispatch, Fragment, SetStateAction, useContext, useRef } from "react"; +import { ParsedDeploymentServiceConfig } from "@/src/types"; +import Select, { TWUISelectOptionObject } from "@/twui/components/form/Select"; +import Row from "@/twui/components/layout/Row"; +import Button from "@/twui/components/layout/Button"; +import Span from "@/twui/components/layout/Span"; +import Border from "@/twui/components/elements/Border"; +import { X } from "lucide-react"; + +type Props = { + service: ParsedDeploymentServiceConfig; + setLog: Dispatch>; + log?: string; +}; + +export default function ServiceClusterServerLogSelectorSelectLog({ + service, + setLog, + log, +}: Props) { + const logs = service.logs; + + const log_strings = logs?.map((l) => (typeof l == "string" ? l : l.cmd)); + const is_custom_log = + log?.match(/./) && !Boolean(log_strings?.find((l) => l == log)); + + return ( + + {is_custom_log ? ( + + + + {log} + + + + + ) : ( +