diff --git a/apps/canvas/front/src/components/details.tsx b/apps/canvas/front/src/components/details.tsx
index d498771..252952d 100644
--- a/apps/canvas/front/src/components/details.tsx
+++ b/apps/canvas/front/src/components/details.tsx
@@ -7,54 +7,54 @@
 import { Icon } from "./icon";
 
 function unique<T>(v: T, i: number, a: T[]) {
-  return a.indexOf(v) === i;
+	return a.indexOf(v) === i;
 }
 
 const nodeTypeIndex = new Map<NodeType, number>([
-  ["github", 1],
-  // ["gitlab", 2],
-  ["volume", 3],
-  ["postgresql", 4],
-  ["mongodb", 5],
-  ["app", 6],
-  ["gateway-tcp", 7],
-  ["gateway-https", 8],
+	["github", 1],
+	// ["gitlab", 2],
+	["volume", 3],
+	["postgresql", 4],
+	["mongodb", 5],
+	["app", 6],
+	["gateway-tcp", 7],
+	["gateway-https", 8],
 ]);
 
 function cmpNodes(x: AppNode, y: AppNode): number {
-  if (x.type === y.type) {
-    if (nodeLabel(x) < nodeLabel(y)) {
-      return -1;
-    } else if (nodeLabel(x) > nodeLabel(y)) {
-      return 1;
-    }
-    return 0;
-  }
-  // TODO(gio): why !
-  return (nodeTypeIndex.get(x.type!) || 0) - (nodeTypeIndex.get(y.type!) || 0);
+	if (x.type === y.type) {
+		if (nodeLabel(x) < nodeLabel(y)) {
+			return -1;
+		} else if (nodeLabel(x) > nodeLabel(y)) {
+			return 1;
+		}
+		return 0;
+	}
+	// TODO(gio): why !
+	return (nodeTypeIndex.get(x.type!) || 0) - (nodeTypeIndex.get(y.type!) || 0);
 }
 
 export function Details() {
-  const nodes = useNodes<AppNode>();
-  const sorted = useMemo(() => nodes.filter((n) => n.type !== "network").sort(cmpNodes), [nodes]);
-  const [open, setOpen] = useState<string[]>([]);
-  const selected = useMemo(() => nodes.filter((n) => n.selected).map((n) => n.id), [nodes]);
-  const all = useMemo(() => open.concat(selected).filter(unique), [open, selected]);
-  return (
-    <Accordion type="multiple" value={all} onValueChange={(v) => setOpen(v)}>
-      {sorted.map((n) => (
-        <AccordionItem key={n.id} value={n.id} className="px-3">
-          <AccordionTrigger>
-            <div className="flex flex-row space-x-2">
-              {Icon(n.type)}
-              <span>{nodeLabel(n)}</span>
-            </div>
-          </AccordionTrigger>
-          <AccordionContent>
-            <NodeDetails {...n} />
-          </AccordionContent>
-        </AccordionItem>
-      ))}
-    </Accordion>
-  );
+	const nodes = useNodes<AppNode>();
+	const sorted = useMemo(() => nodes.filter((n) => n.type !== "network").sort(cmpNodes), [nodes]);
+	const [open, setOpen] = useState<string[]>([]);
+	const selected = useMemo(() => nodes.filter((n) => n.selected).map((n) => n.id), [nodes]);
+	const all = useMemo(() => open.concat(selected).filter(unique), [open, selected]);
+	return (
+		<Accordion type="multiple" value={all} onValueChange={(v) => setOpen(v)}>
+			{sorted.map((n) => (
+				<AccordionItem key={n.id} value={n.id} className="px-3">
+					<AccordionTrigger>
+						<div className="flex flex-row space-x-2">
+							{Icon(n.type)}
+							<span>{nodeLabel(n)}</span>
+						</div>
+					</AccordionTrigger>
+					<AccordionContent>
+						<NodeDetails {...n} />
+					</AccordionContent>
+				</AccordionItem>
+			))}
+		</Accordion>
+	);
 }
