fix(labels): display correct labels in dropdown and when properties are added
This commit is contained in:
parent
9d21d9999f
commit
8c7946091f
1 changed files with 230 additions and 257 deletions
|
@ -143,10 +143,6 @@ pub fn ItemsList(
|
|||
|
||||
// State to manage property cache
|
||||
let (property_cache, set_property_cache) = create_signal(HashMap::<String, HashMap<String, String>>::new());
|
||||
|
||||
// State to track when labels are being fetched
|
||||
let (is_fetching_labels, set_is_fetching_labels) = create_signal(false);
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
fn get_current_url() -> String {
|
||||
use leptos::use_context;
|
||||
|
@ -210,11 +206,7 @@ pub fn ItemsList(
|
|||
|
||||
// Fetch labels for the custom properties
|
||||
let property_ids = custom_props_clone;
|
||||
let labels = fetch_property_labels(
|
||||
property_ids,
|
||||
set_property_labels.clone(),
|
||||
move |value| set_is_fetching_labels.set(value),
|
||||
).await;
|
||||
let labels = fetch_property_labels(property_ids).await;
|
||||
set_property_labels.update(|labels_map| {
|
||||
for (key, value) in labels {
|
||||
labels_map.insert(key, value);
|
||||
|
@ -332,7 +324,7 @@ pub fn ItemsList(
|
|||
)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
|
||||
match response {
|
||||
Ok(resp) => {
|
||||
if resp.status() == 200 {
|
||||
|
@ -397,7 +389,6 @@ pub fn ItemsList(
|
|||
property_cache: ReadSignal<HashMap<String, HashMap<String, String>>>,
|
||||
set_property_cache: WriteSignal<HashMap<String, HashMap<String, String>>>,
|
||||
property_labels: ReadSignal<HashMap<String, String>>,
|
||||
set_is_fetching_labels: WriteSignal<bool>,
|
||||
) -> HashMap<String, String> {
|
||||
|
||||
// Check cache first
|
||||
|
@ -417,12 +408,12 @@ pub fn ItemsList(
|
|||
"#,
|
||||
wikidata_id
|
||||
);
|
||||
|
||||
|
||||
let url = format!(
|
||||
"https://query.wikidata.org/sparql?query={}&format=json",
|
||||
urlencoding::encode(&sparql_query)
|
||||
);
|
||||
|
||||
|
||||
match gloo_net::http::Request::get(&url)
|
||||
.header("Accept", "application/json")
|
||||
.send()
|
||||
|
@ -432,7 +423,7 @@ pub fn ItemsList(
|
|||
if let Ok(data) = response.json::<serde_json::Value>().await {
|
||||
let mut result = HashMap::new();
|
||||
let mut prop_ids = Vec::new();
|
||||
|
||||
|
||||
// First pass: collect unique property IDs
|
||||
if let Some(bindings) = data["results"]["bindings"].as_array() {
|
||||
for binding in bindings {
|
||||
|
@ -444,7 +435,7 @@ pub fn ItemsList(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Batch fetch missing labels
|
||||
let existing_labels = property_labels.get();
|
||||
let missing_ids: Vec<String> = prop_ids
|
||||
|
@ -452,39 +443,48 @@ pub fn ItemsList(
|
|||
.filter(|id| !existing_labels.contains_key(*id))
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
|
||||
if !missing_ids.is_empty() {
|
||||
|
||||
let new_labels = fetch_property_labels(
|
||||
missing_ids,
|
||||
set_property_labels.clone(),
|
||||
move |value| { set_is_fetching_labels.set(value) },
|
||||
).await;
|
||||
let new_labels = fetch_property_labels(missing_ids).await;
|
||||
set_property_labels.update(|labels| {
|
||||
labels.extend(new_labels.clone());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Second pass: build results
|
||||
if let Some(bindings) = data["results"]["bindings"].as_array() {
|
||||
for binding in bindings {
|
||||
if let (Some(prop), Some(value_label)) = (
|
||||
binding["propLabel"]["value"].as_str(),
|
||||
binding["valueLabel"]["value"].as_str(),
|
||||
if let (Some(prop_uri), Some(value_label)) = (
|
||||
binding["prop"]["value"].as_str(),
|
||||
binding["valueLabel"]["value"].as_str()
|
||||
) {
|
||||
let prop_id = prop.replace("http://www.wikidata.org/prop/", "");
|
||||
// Extract property ID from URI (e.g., "http://www.wikidata.org/prop/P123")
|
||||
let prop_id = prop_uri.split('/').last().unwrap_or_default().to_string();
|
||||
|
||||
// Get the label from property_labels signal
|
||||
if let Some(label) = property_labels.get().get(&prop_id).cloned() {
|
||||
result.insert(label.clone(), value_label.to_string());
|
||||
result.insert(
|
||||
prop_id.clone(),
|
||||
format!("{}: {}",
|
||||
property_labels.get().get(&prop_id).cloned().unwrap_or(prop_id.clone()),
|
||||
value_label
|
||||
)
|
||||
);
|
||||
|
||||
// Ensure the label is stored in property_labels
|
||||
set_property_labels.update(|labels| {
|
||||
labels.entry(prop_id.clone()).or_insert_with(|| label.clone());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update cache
|
||||
set_property_cache.update(|cache| {
|
||||
cache.insert(wikidata_id.to_string(), result.clone());
|
||||
});
|
||||
|
||||
|
||||
result
|
||||
} else {
|
||||
HashMap::new()
|
||||
|
@ -493,21 +493,16 @@ pub fn ItemsList(
|
|||
Err(_) => HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn fetch_property_labels(
|
||||
property_ids: Vec<String>,
|
||||
set_property_labels: WriteSignal<HashMap<String, String>>,
|
||||
set_is_fetching_labels: impl Fn(bool) + 'static,
|
||||
) -> HashMap<String, String> {
|
||||
set_is_fetching_labels(true);
|
||||
|
||||
async fn fetch_property_labels(property_ids: Vec<String>) -> HashMap<String, String> {
|
||||
log!("Fetching property labels for properties: {:?}", property_ids);
|
||||
|
||||
|
||||
// Remove the "http://www.wikidata.org/prop/" prefix from property IDs
|
||||
let property_ids: Vec<String> = property_ids
|
||||
.into_iter()
|
||||
.map(|id| id.replace("http://www.wikidata.org/prop/", ""))
|
||||
.collect();
|
||||
|
||||
|
||||
let property_ids_str = property_ids.join(" wd:");
|
||||
let sparql_query = format!(
|
||||
r#"
|
||||
|
@ -518,13 +513,13 @@ pub fn ItemsList(
|
|||
"#,
|
||||
property_ids_str
|
||||
);
|
||||
|
||||
|
||||
let url = format!(
|
||||
"https://query.wikidata.org/sparql?query={}&format=json",
|
||||
urlencoding::encode(&sparql_query)
|
||||
);
|
||||
log!("Sending request to URL: {}", url);
|
||||
|
||||
|
||||
match gloo_net::http::Request::get(&url)
|
||||
.header("Accept", "application/json")
|
||||
.send()
|
||||
|
@ -536,7 +531,7 @@ pub fn ItemsList(
|
|||
log!("Error: Unexpected status code {}", response.status());
|
||||
return HashMap::new();
|
||||
}
|
||||
|
||||
|
||||
match response.text().await {
|
||||
Ok(text) => {
|
||||
log!("Response body: {}", text);
|
||||
|
@ -551,8 +546,7 @@ pub fn ItemsList(
|
|||
binding["prop"]["value"].as_str(),
|
||||
binding["propLabel"]["value"].as_str()
|
||||
) {
|
||||
let prop_id =
|
||||
prop.split('/').last().unwrap_or("").to_string();
|
||||
let prop_id = prop.split('/').last().unwrap_or("").to_string();
|
||||
result.insert(prop_id.clone(), label.to_string());
|
||||
log!("Processed binding {}: prop_id = {}, label = {}", i, prop_id, label);
|
||||
} else {
|
||||
|
@ -563,7 +557,6 @@ pub fn ItemsList(
|
|||
log!("Warning: No bindings found in the response");
|
||||
}
|
||||
log!("Fetched {} property labels", result.len());
|
||||
set_is_fetching_labels(false);
|
||||
result
|
||||
}
|
||||
Err(e) => {
|
||||
|
@ -584,7 +577,7 @@ pub fn ItemsList(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add a new custom property
|
||||
let add_property = {
|
||||
let current_url = Rc::clone(¤t_url);
|
||||
|
@ -593,212 +586,199 @@ pub fn ItemsList(
|
|||
let property_cache = property_cache.clone();
|
||||
let set_property_cache = set_property_cache.clone();
|
||||
Arc::new(move |property: String| {
|
||||
// Normalize the property ID
|
||||
let normalized_property = property.replace("http://www.wikidata.org/prop/", "");
|
||||
let normalized_property_clone = normalized_property.clone();
|
||||
// Normalize the property ID
|
||||
let normalized_property = property.replace("http://www.wikidata.org/prop/", "");
|
||||
let normalized_property_clone = normalized_property.clone();
|
||||
|
||||
// Check if label already exists
|
||||
if !property_labels.get().contains_key(&normalized_property) {
|
||||
spawn_local({
|
||||
let normalized_property = normalized_property.clone();
|
||||
let set_property_labels = set_property_labels.clone();
|
||||
async move {
|
||||
let labels = fetch_property_labels(
|
||||
vec![normalized_property.clone()],
|
||||
set_property_labels.clone(),
|
||||
move |value| set_is_fetching_labels.set(value),
|
||||
)
|
||||
.await;
|
||||
set_property_labels.update(|map| {
|
||||
map.extend(labels);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check if property is already selected
|
||||
// Check if label already exists
|
||||
if !property_labels.get().contains_key(&normalized_property) {
|
||||
spawn_local({
|
||||
let normalized_property = normalized_property.clone();
|
||||
let set_property_labels = set_property_labels.clone();
|
||||
async move {
|
||||
let labels = fetch_property_labels(vec![normalized_property.clone()]).await;
|
||||
set_property_labels.update(|map| {
|
||||
map.extend(labels);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check if property is already selected
|
||||
if !selected_properties.get().contains_key(&normalized_property) && !normalized_property.is_empty() {
|
||||
// Add property to selected properties
|
||||
// Add property to selected properties
|
||||
set_selected_properties.update(|selected| {
|
||||
selected.insert(normalized_property.clone(), true);
|
||||
});
|
||||
|
||||
// Save the selected property to the database
|
||||
spawn_local({
|
||||
let current_url = Rc::clone(¤t_url);
|
||||
let normalized_property = normalized_property_clone.clone();
|
||||
async move {
|
||||
let response = gloo_net::http::Request::post(
|
||||
&format!("/api/urls/{}/properties", encode(¤t_url))
|
||||
)
|
||||
.json(&normalized_property)
|
||||
.unwrap()
|
||||
.send()
|
||||
.await;
|
||||
|
||||
match response {
|
||||
Ok(resp) => {
|
||||
if resp.status() == 200 {
|
||||
log!("Property saved successfully");
|
||||
} else {
|
||||
log!("Error saving property: {}", resp.status_text());
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log!("Error saving property: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
set_custom_properties.update(|props| {
|
||||
if !props.contains(&normalized_property) && !normalized_property.is_empty() {
|
||||
props.push(normalized_property.clone());
|
||||
|
||||
//update the selected_properties state when a new property is added
|
||||
set_selected_properties.update(|selected| {
|
||||
selected.insert(normalized_property.clone(), true);
|
||||
});
|
||||
|
||||
// Save the selected property to the database
|
||||
spawn_local({
|
||||
let current_url = Rc::clone(¤t_url);
|
||||
let normalized_property = normalized_property_clone.clone();
|
||||
async move {
|
||||
let response = gloo_net::http::Request::post(
|
||||
&format!("/api/urls/{}/properties", encode(¤t_url))
|
||||
)
|
||||
.json(&normalized_property)
|
||||
.unwrap()
|
||||
.send()
|
||||
.await;
|
||||
|
||||
match response {
|
||||
Ok(resp) => {
|
||||
if resp.status() == 200 {
|
||||
log!("Property saved successfully");
|
||||
} else {
|
||||
log!("Error saving property: {}", resp.status_text());
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log!("Error saving property: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
set_custom_properties.update(|props| {
|
||||
if !props.contains(&normalized_property) && !normalized_property.is_empty() {
|
||||
props.push(normalized_property.clone());
|
||||
|
||||
//update the selected_properties state when a new property is added
|
||||
set_selected_properties.update(|selected| {
|
||||
selected.insert(normalized_property.clone(), true);
|
||||
});
|
||||
|
||||
// Ensure the grid updates reactively
|
||||
set_items.update(|items| {
|
||||
for item in items {
|
||||
// Ensure the grid updates reactively
|
||||
set_items.update(|items| {
|
||||
for item in items {
|
||||
item.custom_properties.entry(normalized_property.clone()).or_insert_with(|| "".to_string());
|
||||
|
||||
// Save the updated item to the database
|
||||
let item_clone = item.clone();
|
||||
spawn_local({
|
||||
let current_url = Rc::clone(¤t_url);
|
||||
async move {
|
||||
|
||||
// Save the updated item to the database
|
||||
let item_clone = item.clone();
|
||||
spawn_local({
|
||||
let current_url = Rc::clone(¤t_url);
|
||||
async move {
|
||||
save_item_to_db(item_clone, selected_properties, current_url.to_string()).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Use the property label from the property_labels signal
|
||||
let property_label = property_labels.get().get(&normalized_property).cloned().unwrap_or_else(|| normalized_property.clone());
|
||||
log!("Added property with label: {}", property_label);
|
||||
|
||||
}
|
||||
});
|
||||
// Fetch the relevant value for each item and populate the corresponding cells
|
||||
set_items.update(|items| {
|
||||
for item in items {
|
||||
if let Some(wikidata_id) = &item.wikidata_id {
|
||||
let wikidata_id = wikidata_id.clone();
|
||||
let set_fetched_properties = set_fetched_properties.clone();
|
||||
let set_property_labels = set_property_labels.clone();
|
||||
let property_clone = property.clone();
|
||||
spawn_local(async move {
|
||||
let properties = fetch_item_properties(
|
||||
&wikidata_id,
|
||||
set_property_labels.clone(),
|
||||
property_cache.clone(),
|
||||
set_property_cache.clone(),
|
||||
property_labels.clone(),
|
||||
set_is_fetching_labels.clone()
|
||||
)
|
||||
.await;
|
||||
// Update fetched properties and property labels
|
||||
set_fetched_properties.update(|fp| {
|
||||
fp.insert(wikidata_id.clone(), properties.clone());
|
||||
});
|
||||
set_property_labels.update(|pl| {
|
||||
for (key, value) in properties.iter() {
|
||||
pl.entry(key.clone()).or_insert_with(|| value.clone());
|
||||
}
|
||||
});
|
||||
if let Some(value) = properties.get(&property_clone) {
|
||||
set_items.update(|items| {
|
||||
if let Some(item) = items.iter_mut().find(|item| item.wikidata_id.as_ref().unwrap() == &wikidata_id) {
|
||||
item.custom_properties.insert(property_clone.clone(), value.clone());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
// Use the property label from the property_labels signal
|
||||
let property_label = property_labels.get().get(&normalized_property).cloned().unwrap_or_else(|| normalized_property.clone());
|
||||
log!("Added property with label: {}", property_label);
|
||||
|
||||
}
|
||||
});
|
||||
// Fetch the relevant value for each item and populate the corresponding cells
|
||||
set_items.update(|items| {
|
||||
for item in items {
|
||||
// Initialize property with empty string if it doesn't exist
|
||||
item.custom_properties.entry(normalized_property.clone())
|
||||
.or_insert_with(|| "".to_string());
|
||||
|
||||
// Only fetch properties if Wikidata ID exists
|
||||
if let Some(wikidata_id) = &item.wikidata_id {
|
||||
let wikidata_id = wikidata_id.clone();
|
||||
let set_items = set_items.clone();
|
||||
let set_fetched_properties = set_fetched_properties.clone();
|
||||
let property_clone = normalized_property.clone();
|
||||
|
||||
spawn_local(async move {
|
||||
let properties = fetch_item_properties(
|
||||
&wikidata_id,
|
||||
set_property_labels.clone(),
|
||||
property_cache.clone(),
|
||||
set_property_cache.clone(),
|
||||
property_labels.clone()
|
||||
).await;
|
||||
|
||||
// Update the specific property for this item
|
||||
if let Some(value) = properties.get(&property_clone) {
|
||||
set_items.update(|items| {
|
||||
if let Some(item) = items.iter_mut()
|
||||
.find(|i| i.wikidata_id.as_ref() == Some(&wikidata_id))
|
||||
{
|
||||
item.custom_properties.insert(
|
||||
property_clone.clone(),
|
||||
value.clone()
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})};
|
||||
|
||||
// Update item fields
|
||||
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);
|
||||
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" => {
|
||||
item.name = value.clone();
|
||||
fetch_wikidata_suggestions(format!("name-{}", index), value.clone());
|
||||
if let Some(item) = items.get_mut(index) {
|
||||
match field {
|
||||
"name" => {
|
||||
item.name = value.clone();
|
||||
fetch_wikidata_suggestions(format!("name-{}", index), value.clone());
|
||||
|
||||
// Fetch Wikidata properties if the field is "name" and the item has a valid Wikidata ID
|
||||
if !value.is_empty() {
|
||||
if let Some(wikidata_id) = &item.wikidata_id {
|
||||
let wikidata_id = wikidata_id.clone();
|
||||
spawn_local(async move {
|
||||
let properties = fetch_item_properties(
|
||||
&wikidata_id,
|
||||
set_property_labels.clone(),
|
||||
property_cache.clone(),
|
||||
set_property_cache.clone(),
|
||||
property_labels.clone(),
|
||||
set_is_fetching_labels.clone()
|
||||
)
|
||||
.await;
|
||||
// Fetch Wikidata properties if the field is "name" and the item has a valid Wikidata ID
|
||||
if !value.is_empty() {
|
||||
if let Some(wikidata_id) = &item.wikidata_id {
|
||||
let wikidata_id = wikidata_id.clone();
|
||||
spawn_local(async move {
|
||||
let properties = fetch_item_properties(&wikidata_id, set_property_labels.clone(), property_cache.clone(), set_property_cache.clone(), property_labels.clone()).await;
|
||||
log!("Fetched properties for index {}: {:?}", index, properties);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
"description" => {
|
||||
item.description = value.clone();
|
||||
}
|
||||
_ => {
|
||||
// Update custom property
|
||||
item.custom_properties.insert(field.to_string(), value.clone());
|
||||
}
|
||||
}
|
||||
"description" => {
|
||||
item.description = value.clone();
|
||||
}
|
||||
_ => {
|
||||
// Update custom property
|
||||
item.custom_properties.insert(field.to_string(), value.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Save the updated item to the database
|
||||
let item_clone = item.clone();
|
||||
spawn_local({
|
||||
let current_url = Rc::clone(¤t_url);
|
||||
async move {
|
||||
// Save the updated item to the database
|
||||
let item_clone = item.clone();
|
||||
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
|
||||
if index == items.len() - 1 && !value.is_empty() {
|
||||
let new_item = Item {
|
||||
id: Uuid::new_v4().to_string(),
|
||||
name: String::new(),
|
||||
description: String::new(),
|
||||
// reviews: vec![],
|
||||
wikidata_id: None,
|
||||
custom_properties: HashMap::new(),
|
||||
};
|
||||
items.push(new_item.clone());
|
||||
}
|
||||
});
|
||||
}
|
||||
// Automatically add a new row when editing the last row
|
||||
if index == items.len() - 1 && !value.is_empty() {
|
||||
let new_item = Item {
|
||||
id: Uuid::new_v4().to_string(),
|
||||
name: String::new(),
|
||||
description: String::new(),
|
||||
// reviews: vec![],
|
||||
wikidata_id: None,
|
||||
custom_properties: HashMap::new(),
|
||||
};
|
||||
items.push(new_item.clone());
|
||||
|
||||
// Save the new item to the database
|
||||
spawn_local({
|
||||
let current_url = Rc::clone(¤t_url);
|
||||
async move {
|
||||
// Save the new item to the database
|
||||
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);
|
||||
});
|
||||
})
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
log!("Items updated: {:?}", items);
|
||||
});
|
||||
})};
|
||||
|
||||
// List of properties to display as rows
|
||||
let properties = vec!["Name", "Description"];
|
||||
|
@ -818,7 +798,7 @@ pub fn ItemsList(
|
|||
<button on:click=move |_| remove_item(index)>{ "Delete" }</button>
|
||||
</th>
|
||||
}
|
||||
}).collect::<Vec<_>>()}
|
||||
}).collect::<Vec<_>>()}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -886,7 +866,7 @@ pub fn ItemsList(
|
|||
let label_for_display = suggestion.label.clone();
|
||||
let description_for_click = suggestion.description.clone().unwrap_or_default();
|
||||
let description_for_display = suggestion.description.clone().unwrap_or_default();
|
||||
let id = suggestion.id.clone();
|
||||
let id = suggestion.id.clone();
|
||||
view! {
|
||||
<li class="editable-cell-suggestions-li" on:click=move |_| {
|
||||
// Update item with basic suggestion details
|
||||
|
@ -901,9 +881,9 @@ pub fn ItemsList(
|
|||
// Fetch additional properties from Wikidata
|
||||
let wikidata_id = id.clone();
|
||||
spawn_local(async move {
|
||||
let properties = fetch_item_properties(&wikidata_id, set_property_labels.clone(), property_cache.clone(), set_property_cache.clone(), property_labels.clone(),set_is_fetching_labels.clone()).await;
|
||||
let properties = fetch_item_properties(&wikidata_id, set_property_labels.clone(), property_cache.clone(), set_property_cache.clone(), property_labels.clone()).await;
|
||||
// log!("Fetched properties for Wikidata ID {}: {:?}", wikidata_id, properties);
|
||||
|
||||
|
||||
// Populate the custom properties for the new item
|
||||
set_items.update(|items| {
|
||||
if let Some(item) = items.iter_mut().find(|item| item.wikidata_id.as_ref() == Some(&wikidata_id)) {
|
||||
|
@ -958,7 +938,7 @@ pub fn ItemsList(
|
|||
}}
|
||||
</td>
|
||||
}
|
||||
}).collect::<Vec<_>>()}
|
||||
}).collect::<Vec<_>>()}
|
||||
</tr>
|
||||
}
|
||||
}).collect::<Vec<_>>()}
|
||||
|
@ -977,20 +957,10 @@ pub fn ItemsList(
|
|||
let property_label = property_labels.get().get(&normalized_property).cloned().unwrap_or_else(|| normalized_property.clone());
|
||||
log!("Rendering property: {} -> {}", normalized_property, property_label);
|
||||
let property_clone_for_button = normalized_property.clone();
|
||||
let normalized_property_clone = normalized_property.clone();
|
||||
view! {
|
||||
<tr>
|
||||
<td>
|
||||
{move || {
|
||||
let property_label = property_labels.get().get(&normalized_property).cloned();
|
||||
let is_fetching = is_fetching_labels.get();
|
||||
|
||||
if is_fetching {
|
||||
normalized_property.clone()
|
||||
} else {
|
||||
property_label.unwrap_or_else(|| normalized_property.clone())
|
||||
}
|
||||
}}
|
||||
{ property_label }
|
||||
<button class="delete-property" on:click=move |_| {
|
||||
log!("Deleting property: {}", property_clone_for_button);
|
||||
remove_property_clone(property_clone_for_button.clone());
|
||||
|
@ -1007,11 +977,9 @@ pub fn ItemsList(
|
|||
});
|
||||
}>{ "Delete" }</button>
|
||||
</td>
|
||||
let normalized_property = property.replace("http://www.wikidata.org/prop/", "");
|
||||
let normalized_property_clone = normalized_property.clone();
|
||||
{move || {
|
||||
let update_item_cell = Arc::clone(&update_item_inner);
|
||||
let property_clone_for_cells = normalized_property_clone.clone();
|
||||
let property_clone_for_cells = normalized_property.clone();
|
||||
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();
|
||||
|
@ -1041,17 +1009,21 @@ pub fn ItemsList(
|
|||
</table>
|
||||
<div style="margin-bottom: 20px;">
|
||||
<input type="text" id="new-property" placeholder="Add New Property" list="properties" on:keydown=move |event| {
|
||||
if event.key() == "Enter"{
|
||||
if event.key() == "Enter" {
|
||||
let input_element = event.target().unwrap().dyn_into::<web_sys::HtmlInputElement>().unwrap();
|
||||
let property = input_element.value();
|
||||
if !property.is_empty() {
|
||||
// Extract the coded name from the selected value
|
||||
let coded_name = property.split(" - ").next().unwrap_or(&property).to_string();
|
||||
|
||||
// Add the property using the coded name
|
||||
add_property(coded_name);
|
||||
|
||||
// Clear the input field
|
||||
let input_value = input_element.value();
|
||||
|
||||
// Extract property ID from "Label (P123)" format
|
||||
let property_id = input_value
|
||||
.split(" (")
|
||||
.last()
|
||||
.and_then(|s| s.strip_suffix(')'))
|
||||
.unwrap_or(&input_value)
|
||||
.to_string();
|
||||
|
||||
if !property_id.is_empty() {
|
||||
// Add the property using the extracted ID
|
||||
add_property(property_id);
|
||||
input_element.set_value("");
|
||||
}
|
||||
}
|
||||
|
@ -1059,10 +1031,11 @@ pub fn ItemsList(
|
|||
<datalist id="properties">
|
||||
{move || {
|
||||
let property_labels = property_labels.get().clone();
|
||||
property_labels.into_iter().map(|(property, label)| {
|
||||
let property_clone = property.clone();
|
||||
property_labels.into_iter().map(|(property_id, label)| {
|
||||
view! {
|
||||
<option value={property}>{ format!("{}", property_clone) }</option>
|
||||
<option value={format!("{} ({})", label, property_id)}>
|
||||
{ format!("{} ({})", label, property_id) }
|
||||
</option>
|
||||
}
|
||||
}).collect::<Vec<_>>()
|
||||
}}
|
||||
|
|
Loading…
Add table
Reference in a new issue