feat(db): enable user to delete items and properties from the database.
This commit is contained in:
parent
afa3bd3ece
commit
68b458df5e
4 changed files with 103 additions and 11 deletions
30
src/api.rs
30
src/api.rs
|
@ -32,4 +32,34 @@ pub async fn create_item(
|
|||
HttpResponse::InternalServerError().body("Failed to insert 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")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
|
|
15
src/db.rs
15
src/db.rs
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Add table
Reference in a new issue