use dioxus::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct GraphDataResponse { pub data: GraphData, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct GraphData { pub build: Option, pub nodes: Vec, pub edges: Vec, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct ImpactResponse { pub data: Option, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct CommunitiesResponse { pub data: Vec, pub total: Option, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct NodesResponse { pub data: Vec, pub total: Option, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct FileContentResponse { pub data: FileContentData, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct FileContentData { pub content: String, pub path: String, pub language: String, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct SearchResponse { pub data: Vec, pub total: Option, } #[server] pub async fn fetch_graph(repo_id: String) -> Result { let state: super::server_state::ServerState = dioxus_fullstack::FullstackContext::extract().await?; let url = format!("{}/api/v1/graph/{repo_id}", state.agent_api_url); let resp = reqwest::get(&url) .await .map_err(|e| ServerFnError::new(e.to_string()))?; let body: GraphDataResponse = resp .json() .await .map_err(|e| ServerFnError::new(e.to_string()))?; Ok(body) } #[server] pub async fn fetch_impact( repo_id: String, finding_id: String, ) -> Result { let state: super::server_state::ServerState = dioxus_fullstack::FullstackContext::extract().await?; let url = format!( "{}/api/v1/graph/{repo_id}/impact/{finding_id}", state.agent_api_url ); let resp = reqwest::get(&url) .await .map_err(|e| ServerFnError::new(e.to_string()))?; let body: ImpactResponse = resp .json() .await .map_err(|e| ServerFnError::new(e.to_string()))?; Ok(body) } #[server] pub async fn fetch_communities(repo_id: String) -> Result { let state: super::server_state::ServerState = dioxus_fullstack::FullstackContext::extract().await?; let url = format!("{}/api/v1/graph/{repo_id}/communities", state.agent_api_url); let resp = reqwest::get(&url) .await .map_err(|e| ServerFnError::new(e.to_string()))?; let body: CommunitiesResponse = resp .json() .await .map_err(|e| ServerFnError::new(e.to_string()))?; Ok(body) } #[server] pub async fn fetch_file_content( repo_id: String, file_path: String, ) -> Result { let state: super::server_state::ServerState = dioxus_fullstack::FullstackContext::extract().await?; let url = format!( "{}/api/v1/graph/{repo_id}/file-content?path={file_path}", state.agent_api_url ); let resp = reqwest::get(&url) .await .map_err(|e| ServerFnError::new(e.to_string()))?; let body: FileContentResponse = resp .json() .await .map_err(|e| ServerFnError::new(e.to_string()))?; Ok(body) } #[server] pub async fn search_nodes(repo_id: String, query: String) -> Result { let state: super::server_state::ServerState = dioxus_fullstack::FullstackContext::extract().await?; let url = format!( "{}/api/v1/graph/{repo_id}/search?q={query}&limit=50", state.agent_api_url ); let resp = reqwest::get(&url) .await .map_err(|e| ServerFnError::new(e.to_string()))?; let body: SearchResponse = resp .json() .await .map_err(|e| ServerFnError::new(e.to_string()))?; Ok(body) } #[server] pub async fn trigger_graph_build(repo_id: String) -> Result<(), ServerFnError> { let state: super::server_state::ServerState = dioxus_fullstack::FullstackContext::extract().await?; let url = format!("{}/api/v1/graph/{repo_id}/build", state.agent_api_url); let client = reqwest::Client::new(); client .post(&url) .send() .await .map_err(|e| ServerFnError::new(e.to_string()))?; Ok(()) }