feat(db): add API endpoint for updating items to db and implement server-side functionality
This commit is contained in:
parent
5bd19803fe
commit
af3f89c561
5 changed files with 95 additions and 28 deletions
46
src/api.rs
Normal file
46
src/api.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
use leptos::*;
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
use leptos::logging::log;
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
use crate::db::{Database, DbItem};
|
||||||
|
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
#[server(UpdateItem, "/api")]
|
||||||
|
pub async fn update_item_db(client_db_item: ClientDbItem) -> Result<(), ServerFnError> {
|
||||||
|
|
||||||
|
let db_item = DbItem {
|
||||||
|
id: client_db_item.id,
|
||||||
|
name: client_db_item.name,
|
||||||
|
description: client_db_item.description,
|
||||||
|
wikidata_id: client_db_item.wikidata_id,
|
||||||
|
custom_properties: client_db_item.custom_properties,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log the start of the function
|
||||||
|
log!("Starting update_item function for item: {:?}", db_item);
|
||||||
|
|
||||||
|
// Open the database
|
||||||
|
let db = match Database::new("items.db") {
|
||||||
|
Ok(db) => {
|
||||||
|
log!("Database opened successfully");
|
||||||
|
db
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log!("Failed to open database: {}", e);
|
||||||
|
return Err(ServerFnError::ServerError(e.to_string()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Insert the item into the database
|
||||||
|
match db.insert_item(&db_item) {
|
||||||
|
Ok(_) => {
|
||||||
|
log!("Item inserted successfully: {:?}", db_item);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log!("Failed to insert item into database: {}", e);
|
||||||
|
Err(ServerFnError::ServerError(e.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
use crate::components::editable_cell::EditableCell;
|
use crate::components::editable_cell::EditableCell;
|
||||||
use crate::components::editable_cell::InputType;
|
use crate::components::editable_cell::InputType;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use leptos::logging::log;
|
use leptos::logging::log;
|
||||||
use crate::models::item::Item;
|
use crate::models::item::Item;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
use crate::api::update_item_db;
|
||||||
|
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
use crate::db::{Database, DbItem};
|
use crate::db::{Database, DbItem};
|
||||||
|
@ -19,6 +20,15 @@ struct WikidataSuggestion {
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct ClientDbItem {
|
||||||
|
id: String,
|
||||||
|
name: String,
|
||||||
|
description: String,
|
||||||
|
wikidata_id: Option<String>,
|
||||||
|
custom_properties: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn ItemsList(
|
pub fn ItemsList(
|
||||||
items: ReadSignal<Vec<Item>>,
|
items: ReadSignal<Vec<Item>>,
|
||||||
|
@ -247,7 +257,7 @@ pub fn ItemsList(
|
||||||
let set_property_labels = set_property_labels.clone();
|
let set_property_labels = set_property_labels.clone();
|
||||||
spawn_local(async move {
|
spawn_local(async move {
|
||||||
let properties = fetch_item_properties(&wikidata_id, set_fetched_properties, set_property_labels).await;
|
let properties = fetch_item_properties(&wikidata_id, set_fetched_properties, set_property_labels).await;
|
||||||
// log!("Fetched properties for index {}: {:?}", index, properties);
|
log!("Fetched properties for index {}: {:?}", index, properties);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,27 +270,27 @@ pub fn ItemsList(
|
||||||
item.custom_properties.insert(field.to_string(), value.clone());
|
item.custom_properties.insert(field.to_string(), value.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#[cfg(feature = "ssr")]
|
// Send the updated item to the server using the API endpoint
|
||||||
{
|
let client_db_item = ClientDbItem {
|
||||||
log!("SSR block in update_item is executing");
|
id: item.id.clone(),
|
||||||
// Update items in the database
|
name: item.name.clone(),
|
||||||
let db_item = DbItem {
|
description: item.description.clone(),
|
||||||
id: items[index].id.clone(),
|
wikidata_id: item.wikidata_id.clone(),
|
||||||
name: items[index].name.clone(),
|
custom_properties: serde_json::to_string(&item.custom_properties).unwrap(),
|
||||||
description: items[index].description.clone(),
|
|
||||||
wikidata_id: items[index].wikidata_id.clone(),
|
|
||||||
custom_properties: serde_json::to_string(&items[index].custom_properties).unwrap(),
|
|
||||||
};
|
};
|
||||||
let db = Database::new("items.db").expect("Failed to open database");
|
|
||||||
match db.insert_item(&db_item) {
|
|
||||||
|
spawn_local(async move {
|
||||||
|
match update_item_db(client_db_item).await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
log!("Item inserted successfully");
|
log!("Item updated successfully on the server");
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log!("Error inserting item: {}", e);
|
log!("Error updating item on the server: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// Automatically add a new row when editing the last row
|
// Automatically add a new row when editing the last row
|
||||||
if index == items.len() - 1 && !value.is_empty() {
|
if index == items.len() - 1 && !value.is_empty() {
|
||||||
|
|
|
@ -61,7 +61,7 @@ mod db_impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define a struct to represent an item in the database
|
// Define a struct to represent an item in the database
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct DbItem {
|
pub struct DbItem {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
@ -2,6 +2,7 @@ pub mod app;
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod nostr;
|
pub mod nostr;
|
||||||
|
pub mod api;
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
pub mod db;
|
pub mod db;
|
||||||
|
|
||||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -1,3 +1,6 @@
|
||||||
|
use actix_web::{web, App, HttpServer};
|
||||||
|
use compareware::api::update_item_db; // Corrected server function name
|
||||||
|
use compareware::db::Database;
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
|
@ -7,24 +10,31 @@ async fn main() -> std::io::Result<()> {
|
||||||
use leptos_actix::{generate_route_list, LeptosRoutes};
|
use leptos_actix::{generate_route_list, LeptosRoutes};
|
||||||
use compareware::app::*;
|
use compareware::app::*;
|
||||||
|
|
||||||
|
// Load configuration
|
||||||
let conf = get_configuration(None).await.unwrap();
|
let conf = get_configuration(None).await.unwrap();
|
||||||
let addr = conf.leptos_options.site_addr;
|
let addr = conf.leptos_options.site_addr;
|
||||||
|
|
||||||
// Generate the list of routes in your Leptos App
|
// Generate the list of routes in your Leptos App
|
||||||
let routes = generate_route_list(App);
|
let routes = generate_route_list(App);
|
||||||
println!("listening on http://{}", &addr);
|
println!("listening on http://{}", &addr);
|
||||||
|
|
||||||
|
// Start the Actix Web server
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
let leptos_options = &conf.leptos_options;
|
let leptos_options = &conf.leptos_options;
|
||||||
let site_root = &leptos_options.site_root;
|
let site_root = &leptos_options.site_root;
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
// serve JS/WASM/CSS from `pkg`
|
// Register server functions
|
||||||
|
.route("/api/{tail:.*}", leptos_actix::handle_server_fns())
|
||||||
|
// Serve JS/WASM/CSS from `pkg`
|
||||||
.service(Files::new("/pkg", format!("{site_root}/pkg")))
|
.service(Files::new("/pkg", format!("{site_root}/pkg")))
|
||||||
// serve other assets from the `assets` directory
|
// Serve other assets from the `assets` directory
|
||||||
.service(Files::new("/assets", site_root))
|
.service(Files::new("/assets", site_root))
|
||||||
// serve the favicon from /favicon.ico
|
// Serve the favicon from /favicon.ico
|
||||||
.service(favicon)
|
.service(favicon)
|
||||||
|
// Register Leptos routes
|
||||||
.leptos_routes(leptos_options.to_owned(), routes.to_owned(), App)
|
.leptos_routes(leptos_options.to_owned(), routes.to_owned(), App)
|
||||||
|
// Pass Leptos options to the app
|
||||||
.app_data(web::Data::new(leptos_options.to_owned()))
|
.app_data(web::Data::new(leptos_options.to_owned()))
|
||||||
//.wrap(middleware::Compress::default())
|
//.wrap(middleware::Compress::default())
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue