From 9beb9971258b9e0405310df4c11978c036b86970 Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 18 Feb 2025 20:01:45 +0300 Subject: [PATCH] feat(item_list): update `save_item_to_db` function to take `current_url` as an argument. Changes: * Replaced `let current_url = get_current_url();` with `let current_url = Rc::new(get_current_url());` to share the current URL between closures. * Wrapped `add_property` and `update_item` functions in Arc to share them between closures. * Updated `save_item_to_db` function to take `current_url` as an argument and use it to construct the ItemToSend struct. * Updated `fetch_property_labels` function to use the `property_ids` vector instead of a single property ID. * Updated `fetch_item_properties` function to use the `wikidata_id` parameter instead of a hardcoded value. * Updated `WikidataResponse` struct to use a `Vec` instead of a single `WikidataSuggestion`. --- src/components/items_list.rs | 76 +++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/src/components/items_list.rs b/src/components/items_list.rs index cef133c..6063051 100644 --- a/src/components/items_list.rs +++ b/src/components/items_list.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; use std::sync::Arc; use wasm_bindgen::JsCast; use web_sys::window; - +use std::rc::Rc; #[derive(Deserialize, Clone, Debug)] struct WikidataSuggestion { id: String, @@ -29,7 +29,7 @@ struct DbItem { //function to load items from database pub async fn load_items_from_db(current_url: &str) -> Result, String> { - let response = gloo_net::http::Request::get("/api/items?url={}") + let response = gloo_net::http::Request::get(&format!("/api/items?url={}", current_url)) .send() .await .map_err(|err| format!("Failed to fetch items: {:?}", err))?; @@ -101,9 +101,11 @@ pub fn ItemsList( .unwrap_or_else(|| "".to_string()) } - let current_url = get_current_url(); + let current_url = Rc::new(get_current_url()); - spawn_local(async move { + spawn_local({ + let current_url = Rc::clone(¤t_url); + async move { match load_items_from_db(¤t_url).await { Ok(loaded_items) => { // Set the loaded items @@ -158,7 +160,7 @@ pub fn ItemsList( log!("Error loading items: {}", err); } } - }); + }}); // Ensure there's an initial empty row @@ -173,7 +175,7 @@ pub fn ItemsList( } // Function to send an item to the backend API - async fn save_item_to_db(item: Item, selected_properties: ReadSignal>) { + async fn save_item_to_db(item: Item, selected_properties: ReadSignal>, current_url: String) { // Use a reactive closure to access `selected_properties` let custom_properties: HashMap = (move || { let selected_props = selected_properties.get(); // Access the signal inside a reactive closure @@ -189,6 +191,7 @@ pub fn ItemsList( // Create a new struct to send to the backend #[derive(Serialize, Debug)] struct ItemToSend { + url: String, id: String, name: String, description: String, @@ -197,6 +200,7 @@ pub fn ItemsList( } let item_to_send = ItemToSend { + url: current_url.to_string(), id: item.id, name: item.name, description: item.description, @@ -439,7 +443,10 @@ pub fn ItemsList( } // Add a new custom property - let add_property = move |property: String| { + let add_property = { + let current_url = Rc::clone(¤t_url); + let set_items = set_items.clone(); + Arc::new(move |property: String| { // Normalize the property ID let normalized_property = property.replace("http://www.wikidata.org/prop/", ""); @@ -459,8 +466,11 @@ pub fn ItemsList( // Save the updated item to the database let item_clone = item.clone(); - spawn_local(async move { - save_item_to_db(item_clone, selected_properties).await; + spawn_local({ + let current_url = Rc::clone(¤t_url); + async move { + save_item_to_db(item_clone, selected_properties, current_url.to_string()).await; + } }); } }); @@ -509,11 +519,16 @@ pub fn ItemsList( } } }); - }; + })}; // Update item fields - let update_item = move |index: usize, field: &str, value: String| { - set_items.update(|items| { + let update_item = { + let set_items = set_items.clone(); + let current_url = Rc::clone(¤t_url); + Arc::new(move |index: usize, field: &str, value: String| { + let set_items = set_items.clone(); + let current_url = Rc::clone(¤t_url); + set_items.update(move|items| { if let Some(item) = items.get_mut(index) { match field { "name" => { @@ -544,8 +559,11 @@ pub fn ItemsList( // Save the updated item to the database let item_clone = item.clone(); - spawn_local(async move { - save_item_to_db(item_clone, selected_properties).await; + spawn_local({ + let current_url = Rc::clone(¤t_url); + async move { + save_item_to_db(item_clone, selected_properties, current_url.to_string()).await; + } }); } // Automatically add a new row when editing the last row @@ -561,13 +579,16 @@ pub fn ItemsList( items.push(new_item.clone()); // Save the new item to the database - spawn_local(async move { - save_item_to_db(new_item, selected_properties).await; + spawn_local({ + let current_url = Rc::clone(¤t_url); + async move { + save_item_to_db(new_item, selected_properties, current_url.to_string()).await; + } }); } log!("Items updated: {:?}", items); }); - }; + })}; // List of properties to display as rows let properties = vec!["Name", "Description"]; @@ -591,11 +612,13 @@ pub fn ItemsList( {properties.into_iter().map(|property| { + let update_item_cloned = Arc::clone(&update_item); log!("Rendering property: {}", property); view! { { property } {move || items.get().iter().enumerate().map(|(index, item)| { + let update_item_clone = Arc::clone(&update_item_cloned); view! { {match property { @@ -604,7 +627,7 @@ pub fn ItemsList( view! { >()} // Dynamically adding custom properties as columns - {move || { + {{ + let update_item_outer = Arc::clone(&update_item); + + move || { + let update_item = Arc::clone(&update_item_outer); let custom_props = custom_properties.get().clone(); custom_props.into_iter().map(move |property| { + let update_item_inner = Arc::clone(&update_item); let normalized_property = property.replace("http://www.wikidata.org/prop/", ""); let property_label = property_labels.get().get(&normalized_property).cloned().unwrap_or_else(|| normalized_property.clone()); log!("Rendering property: {} -> {}", normalized_property, property_label); @@ -759,14 +787,16 @@ pub fn ItemsList( }>{ "Delete" } {move || { + let update_item_cell = Arc::clone(&update_item_inner); let property_clone_for_cells = normalized_property.clone(); items.get().iter().enumerate().map(move |(index, item)| { - let property_clone_for_closure = property_clone_for_cells.clone(); + let update_item_cell = Arc::clone(&update_item_cell); + let property_clone_for_closure = property_clone_for_cells.clone(); view! { } - }).collect::>() + }).collect::>()} }}