feat(db): enable user to delete items and properties from the database.

This commit is contained in:
ryan 2025-01-28 14:36:17 +03:00
parent afa3bd3ece
commit 68b458df5e
4 changed files with 103 additions and 11 deletions

View file

@ -33,3 +33,33 @@ pub async fn create_item(
}
}
}
#[cfg(feature = "ssr")]
pub async fn delete_item(
db: web::Data<Arc<Mutex<Database>>>,
item_id: web::Path<String>,
) -> HttpResponse {
let db = db.lock().await;
match db.delete_item(&item_id).await {
Ok(_) => HttpResponse::Ok().body("Item deleted"),
Err(err) => {
leptos::logging::error!("Failed to delete item: {:?}", err);
HttpResponse::InternalServerError().body("Failed to delete item")
}
}
}
#[cfg(feature = "ssr")]
pub async fn delete_property(
db: web::Data<Arc<Mutex<Database>>>,
property: web::Path<String>,
) -> HttpResponse {
let db = db.lock().await;
match db.delete_property(&property).await {
Ok(_) => HttpResponse::Ok().body("Property deleted"),
Err(err) => {
leptos::logging::error!("Failed to delete property: {:?}", err);
HttpResponse::InternalServerError().body("Failed to delete property")
}
}
}

View file

@ -203,6 +203,58 @@ pub fn ItemsList(
}
}
// remove an item
let remove_item = move |index: usize| {
let item_id = items.get()[index].id.clone();
spawn_local(async move {
let response = gloo_net::http::Request::delete(&format!("/api/items/{}", item_id))
.send()
.await;
match response {
Ok(resp) => {
if resp.status() == 200 {
set_items.update(|items| {
items.remove(index);
});
log!("Item deleted: {}", item_id);
} else {
log!("Failed to delete item: {}", resp.status_text());
}
}
Err(err) => log!("Failed to delete item: {:?}", err),
}
});
};
let remove_property = move |property: String| {
spawn_local(async move {
let response = gloo_net::http::Request::delete(&format!("/api/properties/{}", property))
.send()
.await;
match response {
Ok(resp) => {
if resp.status() == 200 {
set_custom_properties.update(|props| {
props.retain(|p| p != &property);
});
set_selected_properties.update(|selected| {
selected.remove(&property);
});
set_items.update(|items| {
for item in items {
item.custom_properties.remove(&property);
}
});
log!("Property deleted: {}", property);
} else {
log!("Failed to delete property: {}", resp.status_text());
}
}
Err(err) => log!("Failed to delete property: {:?}", err),
}
});
};
let (wikidata_suggestions, set_wikidata_suggestions) = create_signal(HashMap::<String, Vec<WikidataSuggestion>>::new());
// Fetch Wikidata suggestions
@ -432,14 +484,6 @@ pub fn ItemsList(
});
};
// Remove an item
let remove_item = move |index: usize| {
set_items.update(|items| {
items.remove(index);
});
};
// List of properties to display as rows
let properties = vec!["Name", "Description", "Actions"];
@ -616,6 +660,7 @@ pub fn ItemsList(
{ property_label }
<button class="delete-property" on:click=move |_| {
log!("Deleting property: {}", property_clone_for_button);
remove_property(property_clone_for_button.clone());
set_custom_properties.update(|props| {
props.retain(|p| p != &property_clone_for_button);
});

View file

@ -62,6 +62,21 @@ mod db_impl {
Ok(())
}
pub async fn delete_item(&self, item_id: &str) -> Result<(), Error> {
let conn = self.conn.lock().await;
conn.execute("DELETE FROM items WHERE id = ?", &[item_id])?;
logging::log!("Item deleted: {}", item_id);
Ok(())
}
pub async fn delete_property(&self, property: &str) -> Result<(), Error> {
let conn = self.conn.lock().await;
let query = format!("UPDATE items SET custom_properties = json_remove(custom_properties, '$.{}')", property);
conn.execute(&query, []).map_err(|e| Error::from(e))?;
logging::log!("Property deleted: {}", property);
Ok(())
}
// Retrieve all items from the database
pub async fn get_items(&self) -> Result<Vec<DbItem>, Error> {
let conn = self.conn.lock().await;

View file

@ -7,7 +7,7 @@ async fn main() -> std::io::Result<()> {
use leptos_actix::{generate_route_list, LeptosRoutes};
use compareware::app::*;
use compareware::db::{Database, DbItem};
use compareware::api::{get_items, create_item}; // Import API handlers
use compareware::api::{get_items, create_item, delete_item, delete_property}; // Import API handlers
use std::sync::Arc;
use tokio::sync::Mutex;
@ -35,8 +35,10 @@ async fn main() -> std::io::Result<()> {
// Register custom API routes BEFORE Leptos server functions
.service(
web::scope("/api")
.route("/items", web::get().to(get_items))
.route("/items", web::post().to(create_item)),
.route("/items", web::get().to(get_items)) // GET /api/items
.route("/items", web::post().to(create_item)) // POST /api/items
.route("/items/{id}", web::delete().to(delete_item)) // DELETE /api/items/{id}
.route("/properties/{property}", web::delete().to(delete_property)), // DELETE /api/properties/{property}
)
// Register server functions
.route("/api/{tail:.*}", leptos_actix::handle_server_fns())