Canvas: Prettier
Change-Id: I620dde109df0f29f0c85c6fe150e347d2c32a03e
diff --git a/apps/canvas/front/src/components/node-gateway-tcp.tsx b/apps/canvas/front/src/components/node-gateway-tcp.tsx
index e16fdd2..ada5ef9 100644
--- a/apps/canvas/front/src/components/node-gateway-tcp.tsx
+++ b/apps/canvas/front/src/components/node-gateway-tcp.tsx
@@ -1,284 +1,328 @@
import { v4 as uuidv4 } from "uuid";
-import { useStateStore, AppNode, nodeLabel, useEnv, GatewayTCPNode, nodeIsConnectable } from '@/lib/state';
-import { Edge, Handle, Position, useNodes } from '@xyflow/react';
-import { NodeRect } from './node-rect';
-import { useCallback, useEffect, useMemo, useState } from 'react';
+import { useStateStore, AppNode, nodeLabel, useEnv, GatewayTCPNode, nodeIsConnectable } from "@/lib/state";
+import { Edge, Handle, Position, useNodes } from "@xyflow/react";
+import { NodeRect } from "./node-rect";
+import { useCallback, useEffect, useMemo, useState } from "react";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
-import { useForm, EventType, DeepPartial } from 'react-hook-form';
-import { Form, FormControl, FormField, FormItem, FormMessage } from './ui/form';
-import { Input } from './ui/input';
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
+import { useForm, EventType, DeepPartial } from "react-hook-form";
+import { Form, FormControl, FormField, FormItem, FormMessage } from "./ui/form";
+import { Input } from "./ui/input";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
import { Button } from "./ui/button";
const schema = z.object({
- network: z.string().min(1, "reqired"),
- subdomain: z.string().min(1, "required"),
+ network: z.string().min(1, "reqired"),
+ subdomain: z.string().min(1, "required"),
});
const connectedToSchema = z.object({
- serviceId: z.string(),
- portId: z.string(),
+ serviceId: z.string(),
+ portId: z.string(),
});
export function NodeGatewayTCP(node: GatewayTCPNode) {
- const { id, selected } = node;
- const isConnectableNetwork = useMemo(() => nodeIsConnectable(node, "subdomain"), [node]);
- const isConnectable = useMemo(() => nodeIsConnectable(node, "tcp"), [node]);
- return (
- <NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
- {nodeLabel(node)}
- <Handle
- type={"source"}
- id="subdomain"
- position={Position.Top}
- isConnectable={isConnectableNetwork}
- isConnectableStart={isConnectableNetwork}
- isConnectableEnd={isConnectableNetwork}
- />
- <Handle
- type={"target"}
- id="tcp"
- position={Position.Bottom}
- isConnectable={isConnectable}
- isConnectableStart={isConnectable}
- isConnectableEnd={isConnectable}
- />
- </NodeRect>
- );
+ const { id, selected } = node;
+ const isConnectableNetwork = useMemo(() => nodeIsConnectable(node, "subdomain"), [node]);
+ const isConnectable = useMemo(() => nodeIsConnectable(node, "tcp"), [node]);
+ return (
+ <NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
+ {nodeLabel(node)}
+ <Handle
+ type={"source"}
+ id="subdomain"
+ position={Position.Top}
+ isConnectable={isConnectableNetwork}
+ isConnectableStart={isConnectableNetwork}
+ isConnectableEnd={isConnectableNetwork}
+ />
+ <Handle
+ type={"target"}
+ id="tcp"
+ position={Position.Bottom}
+ isConnectable={isConnectable}
+ isConnectableStart={isConnectable}
+ isConnectableEnd={isConnectable}
+ />
+ </NodeRect>
+ );
}
export function NodeGatewayTCPDetails({ id, data }: GatewayTCPNode) {
- const store = useStateStore();
- const env = useEnv();
- const form = useForm<z.infer<typeof schema>>({
- resolver: zodResolver(schema),
- mode: "onChange",
- defaultValues: {
- network: data.network,
- subdomain: data.subdomain,
- },
- });
- useEffect(() => {
- const sub = form.watch((value: DeepPartial<z.infer<typeof schema>>, { name }: { name?: keyof z.infer<typeof schema> | undefined, type?: EventType | undefined }) => {
- if (name === "network") {
- let edges = store.edges;
- if (data.network !== undefined) {
- edges = edges.filter((e) => {
- console.log(e);
- if (e.source === id && e.sourceHandle === "subdomain" && e.target === data.network && e.targetHandle === "subdomain") {
- return false;
- } else {
- return true;
- }
- });
- }
- if (value.network !== undefined) {
- edges = edges.concat({
- id: uuidv4(),
- source: id,
- sourceHandle: "subdomain",
- target: value.network,
- targetHandle: "subdomain",
- });
- }
- store.setEdges(edges);
- store.updateNodeData<"gateway-tcp">(id, { network: value.network });
- } else if (name === "subdomain") {
- store.updateNodeData<"gateway-tcp">(id, { subdomain: value.subdomain });
- }
- });
- return () => sub.unsubscribe();
- }, [id, data, form, store]);
- const connectedToForm = useForm<z.infer<typeof connectedToSchema>>({
- resolver: zodResolver(connectedToSchema),
- mode: "onSubmit",
- defaultValues: {
- serviceId: data.selected?.serviceId,
- portId: data.selected?.portId,
- },
- });
- useEffect(() => {
- connectedToForm.reset({
- serviceId: data.selected?.serviceId,
- portId: data.selected?.portId,
- });
- console.log(connectedToForm.getValues());
- }, [id, connectedToForm, data]);
- const nodes = useNodes<AppNode>();
- const [selected, setSelected] = useState<AppNode | undefined>(undefined);
- useEffect(() => {
- if (data.selected?.serviceId == null) {
- setSelected(undefined);
- } else {
- const serviceId = data.selected.serviceId;
- setSelected(nodes.find((n) => n.id === serviceId));
- }
- }, [id, data, setSelected, nodes]);
- const selectable = useMemo(() => {
- console.log(selected);
- return nodes.filter((n) => {
- if (n.id === id) {
- return false;
- }
- if (selected != null && selected.id === id) {
- return true;
- }
- if ("ports" in n.data && (n.data.ports || []).length > 0) {
- return true;
- }
- return false;
- })
- }, [id, nodes, selected]);
- useEffect(() => {
- const sub = connectedToForm.watch((value: DeepPartial<z.infer<typeof connectedToSchema>>, { name, type }: { name?: keyof z.infer<typeof connectedToSchema> | undefined, type?: EventType | undefined }) => {
- if (type !== "change") {
- return;
- }
- switch (name) {
- case "serviceId":
- if (!value.serviceId) {
- break;
- }
- store.updateNodeData<"gateway-tcp">(id, {
- selected: {
- serviceId: value.serviceId,
- },
- });
- break;
- case "portId":
- if (!value.portId) {
- break;
- }
- store.updateNodeData<"gateway-tcp">(id, {
- selected: {
- serviceId: value.serviceId,
- portId: value.portId,
- },
- });
- break;
- }
- });
- return () => sub.unsubscribe();
- }, [id, connectedToForm, store]);
- const [nodeLabels, setNodeLabels] = useState(new Map<string, string>());
- const [portLabels, setPortLabels] = useState(new Map<string, string>());
- useEffect(() => {
- setNodeLabels(new Map((data.exposed || []).map((e) => [e.serviceId, nodeLabel(nodes.find((n) => n.id === e.serviceId)!)])));
- setPortLabels(new Map((data.exposed || []).map((e) => [`${e.serviceId} - ${e.portId}`, (nodes.find((n) => n.id === e.serviceId)!.data.ports || []).find((p) => p.id === e.portId)!.name])));
- }, [nodes, data, setNodeLabels, setPortLabels]);
- const onSubmit = useCallback((values: z.infer<typeof connectedToSchema>) => {
- const edges = store.edges.filter((e) => e.target !== id);
- const exp = (data.exposed || []).concat({
- serviceId: values.serviceId,
- portId: values.portId,
- });
- store.updateNodeData<"gateway-tcp">(id, {
- exposed: exp,
- selected: undefined,
- });
- store.setEdges(edges.concat(exp.map((e): Edge => ({
- id: uuidv4(),
- source: e.serviceId,
- sourceHandle: "ports",
- target: id,
- targetHandle: "tcp",
- }))));
- }, [id, data, store]);
- return (
- <>
- <Form {...form}>
- <form className="space-y-2">
- <FormField
- control={form.control}
- name="network"
- render={({ field }) => (
- <FormItem>
- <Select onValueChange={field.onChange} defaultValue={field.value}>
- <FormControl>
- <SelectTrigger>
- <SelectValue placeholder="Network" />
- </SelectTrigger>
- </FormControl>
- <SelectContent>
- {env.networks.map((n) => (
- <SelectItem key={n.name} value={n.domain}>{`${n.name} - ${n.domain}`}</SelectItem>
- ))}
- </SelectContent>
- </Select>
- <FormMessage />
- </FormItem>
- )}
- />
- <FormField
- control={form.control}
- name="subdomain"
- render={({ field }) => (
- <FormItem>
- <FormControl>
- <Input placeholder="subdomain" className="border border-black" {...field} />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
- </form>
- </Form>
- Exposed Services
- <ul>
- {(data.exposed || []).map((e, i) => (
- <li key={i}>
- {nodeLabels.get(e.serviceId)} - {portLabels.get(`${e.serviceId} - ${e.portId}`)}
- </li>
- ))}
- </ul>
- <Form {...connectedToForm}>
- <form className="space-y-2" onSubmit={connectedToForm.handleSubmit(onSubmit)}>
- <FormField
- control={connectedToForm.control}
- name="serviceId"
- render={({ field }) => (
- <FormItem>
- <Select onValueChange={field.onChange} defaultValue={field.value}>
- <FormControl>
- <SelectTrigger>
- <SelectValue placeholder="Service" />
- </SelectTrigger>
- </FormControl>
- <SelectContent>
- {selectable.map((n) => (
- <SelectItem value={n.id}>{nodeLabel(n)}</SelectItem>
- ))}
- </SelectContent>
- </Select>
- <FormMessage />
- </FormItem>
- )}
- />
- <FormField
- control={connectedToForm.control}
- name="portId"
- render={({ field }) => (
- <FormItem>
- <Select onValueChange={field.onChange} defaultValue={field.value}>
- <FormControl>
- <SelectTrigger>
- <SelectValue placeholder="Port" />
- </SelectTrigger>
- </FormControl>
- <SelectContent>
- {selected && (selected.data.ports || []).map((p) => (
- <SelectItem key={p.id} value={p.id}>{p.name} - {p.value}</SelectItem>
- ))}
- </SelectContent>
- </Select>
- <FormMessage />
- </FormItem>
- )}
- />
- <Button type="submit">Expose</Button>
- </form>
- </Form>
- </>
- );
-}
\ No newline at end of file
+ const store = useStateStore();
+ const env = useEnv();
+ const form = useForm<z.infer<typeof schema>>({
+ resolver: zodResolver(schema),
+ mode: "onChange",
+ defaultValues: {
+ network: data.network,
+ subdomain: data.subdomain,
+ },
+ });
+ useEffect(() => {
+ const sub = form.watch(
+ (
+ value: DeepPartial<z.infer<typeof schema>>,
+ { name }: { name?: keyof z.infer<typeof schema> | undefined; type?: EventType | undefined },
+ ) => {
+ if (name === "network") {
+ let edges = store.edges;
+ if (data.network !== undefined) {
+ edges = edges.filter((e) => {
+ console.log(e);
+ if (
+ e.source === id &&
+ e.sourceHandle === "subdomain" &&
+ e.target === data.network &&
+ e.targetHandle === "subdomain"
+ ) {
+ return false;
+ } else {
+ return true;
+ }
+ });
+ }
+ if (value.network !== undefined) {
+ edges = edges.concat({
+ id: uuidv4(),
+ source: id,
+ sourceHandle: "subdomain",
+ target: value.network,
+ targetHandle: "subdomain",
+ });
+ }
+ store.setEdges(edges);
+ store.updateNodeData<"gateway-tcp">(id, { network: value.network });
+ } else if (name === "subdomain") {
+ store.updateNodeData<"gateway-tcp">(id, { subdomain: value.subdomain });
+ }
+ },
+ );
+ return () => sub.unsubscribe();
+ }, [id, data, form, store]);
+ const connectedToForm = useForm<z.infer<typeof connectedToSchema>>({
+ resolver: zodResolver(connectedToSchema),
+ mode: "onSubmit",
+ defaultValues: {
+ serviceId: data.selected?.serviceId,
+ portId: data.selected?.portId,
+ },
+ });
+ useEffect(() => {
+ connectedToForm.reset({
+ serviceId: data.selected?.serviceId,
+ portId: data.selected?.portId,
+ });
+ console.log(connectedToForm.getValues());
+ }, [id, connectedToForm, data]);
+ const nodes = useNodes<AppNode>();
+ const [selected, setSelected] = useState<AppNode | undefined>(undefined);
+ useEffect(() => {
+ if (data.selected?.serviceId == null) {
+ setSelected(undefined);
+ } else {
+ const serviceId = data.selected.serviceId;
+ setSelected(nodes.find((n) => n.id === serviceId));
+ }
+ }, [id, data, setSelected, nodes]);
+ const selectable = useMemo(() => {
+ console.log(selected);
+ return nodes.filter((n) => {
+ if (n.id === id) {
+ return false;
+ }
+ if (selected != null && selected.id === id) {
+ return true;
+ }
+ if ("ports" in n.data && (n.data.ports || []).length > 0) {
+ return true;
+ }
+ return false;
+ });
+ }, [id, nodes, selected]);
+ useEffect(() => {
+ const sub = connectedToForm.watch(
+ (
+ value: DeepPartial<z.infer<typeof connectedToSchema>>,
+ {
+ name,
+ type,
+ }: { name?: keyof z.infer<typeof connectedToSchema> | undefined; type?: EventType | undefined },
+ ) => {
+ if (type !== "change") {
+ return;
+ }
+ switch (name) {
+ case "serviceId":
+ if (!value.serviceId) {
+ break;
+ }
+ store.updateNodeData<"gateway-tcp">(id, {
+ selected: {
+ serviceId: value.serviceId,
+ },
+ });
+ break;
+ case "portId":
+ if (!value.portId) {
+ break;
+ }
+ store.updateNodeData<"gateway-tcp">(id, {
+ selected: {
+ serviceId: value.serviceId,
+ portId: value.portId,
+ },
+ });
+ break;
+ }
+ },
+ );
+ return () => sub.unsubscribe();
+ }, [id, connectedToForm, store]);
+ const [nodeLabels, setNodeLabels] = useState(new Map<string, string>());
+ const [portLabels, setPortLabels] = useState(new Map<string, string>());
+ useEffect(() => {
+ setNodeLabels(
+ new Map(
+ (data.exposed || []).map((e) => [e.serviceId, nodeLabel(nodes.find((n) => n.id === e.serviceId)!)]),
+ ),
+ );
+ setPortLabels(
+ new Map(
+ (data.exposed || []).map((e) => [
+ `${e.serviceId} - ${e.portId}`,
+ (nodes.find((n) => n.id === e.serviceId)!.data.ports || []).find((p) => p.id === e.portId)!.name,
+ ]),
+ ),
+ );
+ }, [nodes, data, setNodeLabels, setPortLabels]);
+ const onSubmit = useCallback(
+ (values: z.infer<typeof connectedToSchema>) => {
+ const edges = store.edges.filter((e) => e.target !== id);
+ const exp = (data.exposed || []).concat({
+ serviceId: values.serviceId,
+ portId: values.portId,
+ });
+ store.updateNodeData<"gateway-tcp">(id, {
+ exposed: exp,
+ selected: undefined,
+ });
+ store.setEdges(
+ edges.concat(
+ exp.map(
+ (e): Edge => ({
+ id: uuidv4(),
+ source: e.serviceId,
+ sourceHandle: "ports",
+ target: id,
+ targetHandle: "tcp",
+ }),
+ ),
+ ),
+ );
+ },
+ [id, data, store],
+ );
+ return (
+ <>
+ <Form {...form}>
+ <form className="space-y-2">
+ <FormField
+ control={form.control}
+ name="network"
+ render={({ field }) => (
+ <FormItem>
+ <Select onValueChange={field.onChange} defaultValue={field.value}>
+ <FormControl>
+ <SelectTrigger>
+ <SelectValue placeholder="Network" />
+ </SelectTrigger>
+ </FormControl>
+ <SelectContent>
+ {env.networks.map((n) => (
+ <SelectItem
+ key={n.name}
+ value={n.domain}
+ >{`${n.name} - ${n.domain}`}</SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+ <FormField
+ control={form.control}
+ name="subdomain"
+ render={({ field }) => (
+ <FormItem>
+ <FormControl>
+ <Input placeholder="subdomain" className="border border-black" {...field} />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+ </form>
+ </Form>
+ Exposed Services
+ <ul>
+ {(data.exposed || []).map((e, i) => (
+ <li key={i}>
+ {nodeLabels.get(e.serviceId)} - {portLabels.get(`${e.serviceId} - ${e.portId}`)}
+ </li>
+ ))}
+ </ul>
+ <Form {...connectedToForm}>
+ <form className="space-y-2" onSubmit={connectedToForm.handleSubmit(onSubmit)}>
+ <FormField
+ control={connectedToForm.control}
+ name="serviceId"
+ render={({ field }) => (
+ <FormItem>
+ <Select onValueChange={field.onChange} defaultValue={field.value}>
+ <FormControl>
+ <SelectTrigger>
+ <SelectValue placeholder="Service" />
+ </SelectTrigger>
+ </FormControl>
+ <SelectContent>
+ {selectable.map((n) => (
+ <SelectItem value={n.id}>{nodeLabel(n)}</SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+ <FormField
+ control={connectedToForm.control}
+ name="portId"
+ render={({ field }) => (
+ <FormItem>
+ <Select onValueChange={field.onChange} defaultValue={field.value}>
+ <FormControl>
+ <SelectTrigger>
+ <SelectValue placeholder="Port" />
+ </SelectTrigger>
+ </FormControl>
+ <SelectContent>
+ {selected &&
+ (selected.data.ports || []).map((p) => (
+ <SelectItem key={p.id} value={p.id}>
+ {p.name} - {p.value}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+ <Button type="submit">Expose</Button>
+ </form>
+ </Form>
+ </>
+ );
+}