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<WikidataSuggestion>` instead of a single `WikidataSuggestion`.
This commit is contained in:
parent
63f11f6a2d
commit
9beb997125
1 changed files with 53 additions and 23 deletions
|
@ -9,7 +9,7 @@ use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::window;
|
use web_sys::window;
|
||||||
|
use std::rc::Rc;
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
struct WikidataSuggestion {
|
struct WikidataSuggestion {
|
||||||
id: String,
|
id: String,
|
||||||
|
@ -29,7 +29,7 @@ struct DbItem {
|
||||||
|
|
||||||
//function to load items from database
|
//function to load items from database
|
||||||
pub async fn load_items_from_db(current_url: &str) -> Result<Vec<Item>, String> {
|
pub async fn load_items_from_db(current_url: &str) -> Result<Vec<Item>, 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()
|
.send()
|
||||||
.await
|
.await
|
||||||
.map_err(|err| format!("Failed to fetch items: {:?}", err))?;
|
.map_err(|err| format!("Failed to fetch items: {:?}", err))?;
|
||||||
|
@ -101,9 +101,11 @@ pub fn ItemsList(
|
||||||
.unwrap_or_else(|| "".to_string())
|
.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 {
|
match load_items_from_db(¤t_url).await {
|
||||||
Ok(loaded_items) => {
|
Ok(loaded_items) => {
|
||||||
// Set the loaded items
|
// Set the loaded items
|
||||||
|
@ -158,7 +160,7 @@ pub fn ItemsList(
|
||||||
log!("Error loading items: {}", err);
|
log!("Error loading items: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}});
|
||||||
|
|
||||||
|
|
||||||
// Ensure there's an initial empty row
|
// Ensure there's an initial empty row
|
||||||
|
@ -173,7 +175,7 @@ pub fn ItemsList(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to send an item to the backend API
|
// Function to send an item to the backend API
|
||||||
async fn save_item_to_db(item: Item, selected_properties: ReadSignal<HashMap<String, bool>>) {
|
async fn save_item_to_db(item: Item, selected_properties: ReadSignal<HashMap<String, bool>>, current_url: String) {
|
||||||
// Use a reactive closure to access `selected_properties`
|
// Use a reactive closure to access `selected_properties`
|
||||||
let custom_properties: HashMap<String, String> = (move || {
|
let custom_properties: HashMap<String, String> = (move || {
|
||||||
let selected_props = selected_properties.get(); // Access the signal inside a reactive closure
|
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
|
// Create a new struct to send to the backend
|
||||||
#[derive(Serialize, Debug)]
|
#[derive(Serialize, Debug)]
|
||||||
struct ItemToSend {
|
struct ItemToSend {
|
||||||
|
url: String,
|
||||||
id: String,
|
id: String,
|
||||||
name: String,
|
name: String,
|
||||||
description: String,
|
description: String,
|
||||||
|
@ -197,6 +200,7 @@ pub fn ItemsList(
|
||||||
}
|
}
|
||||||
|
|
||||||
let item_to_send = ItemToSend {
|
let item_to_send = ItemToSend {
|
||||||
|
url: current_url.to_string(),
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
description: item.description,
|
description: item.description,
|
||||||
|
@ -439,7 +443,10 @@ pub fn ItemsList(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new custom property
|
// 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
|
// Normalize the property ID
|
||||||
let normalized_property = property.replace("http://www.wikidata.org/prop/", "");
|
let normalized_property = property.replace("http://www.wikidata.org/prop/", "");
|
||||||
|
|
||||||
|
@ -459,8 +466,11 @@ pub fn ItemsList(
|
||||||
|
|
||||||
// Save the updated item to the database
|
// Save the updated item to the database
|
||||||
let item_clone = item.clone();
|
let item_clone = item.clone();
|
||||||
spawn_local(async move {
|
spawn_local({
|
||||||
save_item_to_db(item_clone, selected_properties).await;
|
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
|
// Update item fields
|
||||||
let update_item = move |index: usize, field: &str, value: String| {
|
let update_item = {
|
||||||
set_items.update(|items| {
|
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) {
|
if let Some(item) = items.get_mut(index) {
|
||||||
match field {
|
match field {
|
||||||
"name" => {
|
"name" => {
|
||||||
|
@ -544,8 +559,11 @@ pub fn ItemsList(
|
||||||
|
|
||||||
// Save the updated item to the database
|
// Save the updated item to the database
|
||||||
let item_clone = item.clone();
|
let item_clone = item.clone();
|
||||||
spawn_local(async move {
|
spawn_local({
|
||||||
save_item_to_db(item_clone, selected_properties).await;
|
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
|
// Automatically add a new row when editing the last row
|
||||||
|
@ -561,13 +579,16 @@ pub fn ItemsList(
|
||||||
items.push(new_item.clone());
|
items.push(new_item.clone());
|
||||||
|
|
||||||
// Save the new item to the database
|
// Save the new item to the database
|
||||||
spawn_local(async move {
|
spawn_local({
|
||||||
save_item_to_db(new_item, selected_properties).await;
|
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);
|
log!("Items updated: {:?}", items);
|
||||||
});
|
});
|
||||||
};
|
})};
|
||||||
|
|
||||||
// List of properties to display as rows
|
// List of properties to display as rows
|
||||||
let properties = vec!["Name", "Description"];
|
let properties = vec!["Name", "Description"];
|
||||||
|
@ -591,11 +612,13 @@ pub fn ItemsList(
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{properties.into_iter().map(|property| {
|
{properties.into_iter().map(|property| {
|
||||||
|
let update_item_cloned = Arc::clone(&update_item);
|
||||||
log!("Rendering property: {}", property);
|
log!("Rendering property: {}", property);
|
||||||
view! {
|
view! {
|
||||||
<tr>
|
<tr>
|
||||||
<td>{ property }</td>
|
<td>{ property }</td>
|
||||||
{move || items.get().iter().enumerate().map(|(index, item)| {
|
{move || items.get().iter().enumerate().map(|(index, item)| {
|
||||||
|
let update_item_clone = Arc::clone(&update_item_cloned);
|
||||||
view! {
|
view! {
|
||||||
<td>
|
<td>
|
||||||
{match property {
|
{match property {
|
||||||
|
@ -604,7 +627,7 @@ pub fn ItemsList(
|
||||||
<EditableCell
|
<EditableCell
|
||||||
value=item.name.clone()
|
value=item.name.clone()
|
||||||
on_input=move |value| {
|
on_input=move |value| {
|
||||||
update_item(index, "name", value.clone());
|
update_item_clone(index, "name", value.clone());
|
||||||
fetch_wikidata_suggestions(format!("name-{}", index), value);
|
fetch_wikidata_suggestions(format!("name-{}", index), value);
|
||||||
}
|
}
|
||||||
key=Arc::new(format!("name-{}", index))
|
key=Arc::new(format!("name-{}", index))
|
||||||
|
@ -707,7 +730,7 @@ pub fn ItemsList(
|
||||||
"Description" => view! {
|
"Description" => view! {
|
||||||
<EditableCell
|
<EditableCell
|
||||||
value=item.description.clone()
|
value=item.description.clone()
|
||||||
on_input=move |value| update_item(index, "description", value)
|
on_input=move |value| update_item_clone(index, "description", value)
|
||||||
key=Arc::new(format!("description-{}", index))
|
key=Arc::new(format!("description-{}", index))
|
||||||
focused_cell=focused_cell
|
focused_cell=focused_cell
|
||||||
set_focused_cell=set_focused_cell.clone()
|
set_focused_cell=set_focused_cell.clone()
|
||||||
|
@ -731,9 +754,14 @@ pub fn ItemsList(
|
||||||
}
|
}
|
||||||
}).collect::<Vec<_>>()}
|
}).collect::<Vec<_>>()}
|
||||||
// Dynamically adding custom properties as columns
|
// 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();
|
let custom_props = custom_properties.get().clone();
|
||||||
custom_props.into_iter().map(move |property| {
|
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 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());
|
let property_label = property_labels.get().get(&normalized_property).cloned().unwrap_or_else(|| normalized_property.clone());
|
||||||
log!("Rendering property: {} -> {}", normalized_property, property_label);
|
log!("Rendering property: {} -> {}", normalized_property, property_label);
|
||||||
|
@ -759,14 +787,16 @@ pub fn ItemsList(
|
||||||
}>{ "Delete" }</button>
|
}>{ "Delete" }</button>
|
||||||
</td>
|
</td>
|
||||||
{move || {
|
{move || {
|
||||||
|
let update_item_cell = Arc::clone(&update_item_inner);
|
||||||
let property_clone_for_cells = normalized_property.clone();
|
let property_clone_for_cells = normalized_property.clone();
|
||||||
items.get().iter().enumerate().map(move |(index, item)| {
|
items.get().iter().enumerate().map(move |(index, item)| {
|
||||||
|
let update_item_cell = Arc::clone(&update_item_cell);
|
||||||
let property_clone_for_closure = property_clone_for_cells.clone();
|
let property_clone_for_closure = property_clone_for_cells.clone();
|
||||||
view! {
|
view! {
|
||||||
<td>
|
<td>
|
||||||
<EditableCell
|
<EditableCell
|
||||||
value=item.custom_properties.get(&property_clone_for_closure).cloned().unwrap_or_default()
|
value=item.custom_properties.get(&property_clone_for_closure).cloned().unwrap_or_default()
|
||||||
on_input=move |value| update_item(index, &property_clone_for_closure, value)
|
on_input=move |value| update_item_cell(index, &property_clone_for_closure, value)
|
||||||
key=Arc::new(format!("custom-{}-{}", property_clone_for_cells, index))
|
key=Arc::new(format!("custom-{}-{}", property_clone_for_cells, index))
|
||||||
focused_cell=focused_cell
|
focused_cell=focused_cell
|
||||||
set_focused_cell=set_focused_cell.clone()
|
set_focused_cell=set_focused_cell.clone()
|
||||||
|
@ -782,7 +812,7 @@ pub fn ItemsList(
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
}).collect::<Vec<_>>()
|
}).collect::<Vec<_>>()}
|
||||||
}}
|
}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
Loading…
Add table
Reference in a new issue