mongodb on backend
This commit is contained in:
+63
-40
@@ -1,6 +1,49 @@
|
||||
use crate::components::server::Server;
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::components::server::Server;
|
||||
#[cfg(feature = "server")]
|
||||
use futures_util::stream::TryStreamExt;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
const DB_URL: &'static str = "mongodb://admin:admin@localhost/";
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub async fn get_mongo<T: Send + Sync>(
|
||||
collection: &str,
|
||||
) -> Result<mongodb::Collection<T>, mongodb::error::Error> {
|
||||
let client = mongodb::Client::with_uri_str(DB_URL).await?;
|
||||
|
||||
Ok(client.database("sentryx").collection(collection))
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
fn parse_search_query(input: &str) -> Vec<String> {
|
||||
let re = regex::Regex::new(r#""([^"]+)"|(\S+)"#).unwrap();
|
||||
|
||||
re.captures_iter(input)
|
||||
.filter_map(|cap| cap.get(1).or_else(|| cap.get(2)))
|
||||
.map(|m| m.as_str().to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
fn build_or_filter(input: &str, fields: &[&str]) -> mongodb::bson::Document {
|
||||
let phrases = parse_search_query(input);
|
||||
let mut or_clauses = Vec::new();
|
||||
|
||||
for phrase in phrases {
|
||||
for &field in fields {
|
||||
or_clauses.push(mongodb::bson::doc! {
|
||||
field: mongodb::bson::Regex {
|
||||
pattern: phrase.clone(),
|
||||
options: "i".into(), // case-insensitive
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
mongodb::bson::doc! { "$or": or_clauses }
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn log_in(username: String, password: String) -> Result<String, ServerFnError> {
|
||||
@@ -8,43 +51,23 @@ pub async fn log_in(username: String, password: String) -> Result<String, Server
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn get_servers() -> Result<Vec<Server>, ServerFnError> {
|
||||
Ok(vec![
|
||||
Server {
|
||||
name: "Main Server".to_string(),
|
||||
status: crate::components::server::Status::Online,
|
||||
ip: "10.0.0.5".to_string(),
|
||||
cpu: 95,
|
||||
memory: 60,
|
||||
storage: 43,
|
||||
network: 88,
|
||||
},
|
||||
Server {
|
||||
name: "Cache Node".to_string(),
|
||||
status: crate::components::server::Status::Warning,
|
||||
ip: "192.168.1.12".to_string(),
|
||||
cpu: 47,
|
||||
memory: 72,
|
||||
storage: 81,
|
||||
network: 34,
|
||||
},
|
||||
Server {
|
||||
name: "Database".to_string(),
|
||||
status: crate::components::server::Status::Offline,
|
||||
ip: "172.16.254.3".to_string(),
|
||||
cpu: 12,
|
||||
memory: 90,
|
||||
storage: 22,
|
||||
network: 10,
|
||||
},
|
||||
Server {
|
||||
name: "Backup Node".to_string(),
|
||||
status: crate::components::server::Status::Maintenance,
|
||||
ip: "192.168.100.22".to_string(),
|
||||
cpu: 83,
|
||||
memory: 41,
|
||||
storage: 96,
|
||||
network: 70,
|
||||
},
|
||||
])
|
||||
pub async fn get_servers(search: String) -> Result<Vec<Server>, ServerFnError> {
|
||||
let servers = get_mongo::<Server>("servers").await?;
|
||||
|
||||
let filter = if search.trim().is_empty() {
|
||||
mongodb::bson::doc! {}
|
||||
} else {
|
||||
build_or_filter(&search, &["name", "ip"])
|
||||
};
|
||||
|
||||
|
||||
let mut cursor = servers.find(filter).await?;
|
||||
|
||||
let mut svo = Vec::new();
|
||||
|
||||
while let Some(doc) = cursor.try_next().await? {
|
||||
svo.push(doc);
|
||||
}
|
||||
|
||||
Ok(svo)
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ pub fn ServerComponent(server: Server) -> Element {
|
||||
fn get_level(i: u8) -> String {
|
||||
if i > 80 {
|
||||
String::from("high")
|
||||
} else if i > 30 {
|
||||
} else if i > 50 {
|
||||
String::from("medium")
|
||||
} else {
|
||||
String::from("low")
|
||||
|
||||
+29
-11
@@ -10,12 +10,15 @@ const DASHBOARD_CSS: Asset = asset!("/assets/styles/dashboard.css");
|
||||
|
||||
#[component]
|
||||
pub fn Dashboard() -> Element {
|
||||
let servers = use_resource(move || async move {
|
||||
if let Ok(v) = backend::get_servers().await {
|
||||
v
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
let mut servers = use_signal(|| Vec::new());
|
||||
let server_search = use_signal(|| String::new());
|
||||
|
||||
use_effect(move || {
|
||||
spawn(async move {
|
||||
if let Ok(v) = backend::get_servers(String::new()).await {
|
||||
servers.set(v);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
rsx! {
|
||||
@@ -101,7 +104,24 @@ pub fn Dashboard() -> Element {
|
||||
div { class: "search-container",
|
||||
div { class: "search-input",
|
||||
lucide_dioxus::Search { size: 16, color: "currentColor" }
|
||||
input { placeholder: "Search servers by name, location, or IP..." }
|
||||
input {
|
||||
onchange: {let mut server_search = server_search.clone(); move |e: Event<FormData>| {server_search.set(e.value())}},
|
||||
onkeypress: {
|
||||
let server_search = server_search.clone();
|
||||
let mut servers = servers.clone();
|
||||
move |e: Event<KeyboardData>| {
|
||||
let query = (*server_search.read()).clone();
|
||||
async move {
|
||||
if e.key() == Key::Enter {
|
||||
if let Ok(v) = backend::get_servers(query).await {
|
||||
servers.set(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
placeholder: "Search servers by name, location, or IP..." }
|
||||
}
|
||||
button { class: "fg", "All (4)" }
|
||||
button { class: "online", "Online (3)" }
|
||||
@@ -111,10 +131,8 @@ pub fn Dashboard() -> Element {
|
||||
}
|
||||
|
||||
div { class: "server-container",
|
||||
if let Some(ss) = servers.read().clone() {
|
||||
for s in ss {
|
||||
ServerComponent { server: s }
|
||||
}
|
||||
for s in (*servers.read()).clone() {
|
||||
ServerComponent { server: s }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user