Canvas: Reuse node details component in overview

Make app details tabular.

Change-Id: I78a641e8e513eec44573bb8c8a391ef81a66e7fe
diff --git a/apps/canvas/front/src/components/node-github.tsx b/apps/canvas/front/src/components/node-github.tsx
index dd7c68a..4373359 100644
--- a/apps/canvas/front/src/components/node-github.tsx
+++ b/apps/canvas/front/src/components/node-github.tsx
@@ -20,7 +20,6 @@
 import { Form, FormControl, FormField, FormItem, FormMessage } from "./ui/form";
 import { Handle, Position } from "@xyflow/react";
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
-import { GitHubRepository } from "../lib/github";
 import { useProjectId } from "@/lib/state";
 import { Alert, AlertDescription } from "./ui/alert";
 import { AlertCircle, LoaderCircle, RefreshCw } from "lucide-react";
@@ -64,36 +63,11 @@
 	const repoError = useGithubRepositoriesError();
 	const fetchStoreRepositories = useFetchGithubRepositories();
 
-	const [displayRepos, setDisplayRepos] = useState<GitHubRepository[]>([]);
-
 	const [isAnalyzing, setIsAnalyzing] = useState(false);
 	const [showModal, setShowModal] = useState(false);
 	const [discoveredServices, setDiscoveredServices] = useState<z.infer<typeof serviceAnalyzisSchema>[]>([]);
 	const [selectedServices, setSelectedServices] = useState<Record<string, boolean>>({});
 
-	useEffect(() => {
-		let currentRepoInStore = false;
-		if (data.repository) {
-			currentRepoInStore = storeRepos.some((r) => r.id === data.repository!.id);
-		}
-
-		if (data.repository && !currentRepoInStore) {
-			const currentRepoForDisplay: GitHubRepository = {
-				id: data.repository.id,
-				name: data.repository.sshURL.split("/").pop() || "",
-				full_name: data.repository.fullName || data.repository.sshURL.split("/").slice(-2).join("/"),
-				html_url: "",
-				ssh_url: data.repository.sshURL,
-				description: null,
-				private: false,
-				default_branch: "main",
-			};
-			setDisplayRepos([currentRepoForDisplay, ...storeRepos.filter((r) => r.id !== data.repository!.id)]);
-		} else {
-			setDisplayRepos(storeRepos);
-		}
-	}, [data.repository, storeRepos]);
-
 	const form = useForm<z.infer<typeof schema>>({
 		resolver: zodResolver(schema),
 		mode: "onChange",
@@ -118,7 +92,7 @@
 				switch (name) {
 					case "repositoryId":
 						if (value.repositoryId) {
-							const repo = displayRepos.find((r) => r.id === value.repositoryId);
+							const repo = storeRepos.find((r) => r.id === value.repositoryId);
 							if (repo) {
 								store.updateNodeData<"github">(id, {
 									repository: {
@@ -134,7 +108,7 @@
 			},
 		);
 		return () => sub.unsubscribe();
-	}, [form, store, id, displayRepos]);
+	}, [form, store, id, storeRepos]);
 
 	const analyze = useCallback(async () => {
 		if (!data.repository?.sshURL) return;
@@ -177,7 +151,8 @@
 				const newNodeData: Omit<ServiceData, "activeField" | "state"> = {
 					label: service.name,
 					repository: {
-						id: id,
+						id: data.repository!.id,
+						repoNodeId: id,
 					},
 					info: service,
 					type: "nodejs:24.0.2" as ServiceType,
@@ -239,7 +214,7 @@
 															githubService
 																? isLoadingRepos
 																	? "Loading..."
-																	: displayRepos.length === 0
+																	: storeRepos.length === 0
 																		? "No repositories found"
 																		: "Select a repository"
 																: "GitHub not configured"
@@ -248,7 +223,7 @@
 												</SelectTrigger>
 											</FormControl>
 											<SelectContent>
-												{displayRepos.map((repo) => (
+												{storeRepos.map((repo) => (
 													<SelectItem key={repo.id} value={repo.id.toString()}>
 														{repo.full_name}
 														{repo.description && ` - ${repo.description}`}