dev #6
1 changed files with 77 additions and 19 deletions
|
@ -141,6 +141,8 @@ pub fn ItemsList(
|
||||||
// Signal to store the fetched property labels
|
// Signal to store the fetched property labels
|
||||||
let (property_labels, set_property_labels) = create_signal(HashMap::<String, String>::new());
|
let (property_labels, set_property_labels) = create_signal(HashMap::<String, String>::new());
|
||||||
|
|
||||||
|
// State to manage property cache
|
||||||
|
let (property_cache, set_property_cache) = create_signal(HashMap::<String, HashMap<String, String>>::new());
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
fn get_current_url() -> String {
|
fn get_current_url() -> String {
|
||||||
use leptos::use_context;
|
use leptos::use_context;
|
||||||
|
@ -381,7 +383,19 @@ pub fn ItemsList(
|
||||||
};
|
};
|
||||||
|
|
||||||
//function to fetch properties
|
//function to fetch properties
|
||||||
async fn fetch_item_properties(wikidata_id: &str, set_property_labels: WriteSignal<HashMap<String, String>>) -> HashMap<String, String> {
|
async fn fetch_item_properties(
|
||||||
|
wikidata_id: &str,
|
||||||
|
set_property_labels: WriteSignal<HashMap<String, String>>,
|
||||||
|
property_cache: ReadSignal<HashMap<String, HashMap<String, String>>>,
|
||||||
|
set_property_cache: WriteSignal<HashMap<String, HashMap<String, String>>>,
|
||||||
|
property_labels: ReadSignal<HashMap<String, String>>,
|
||||||
|
) -> HashMap<String, String> {
|
||||||
|
|
||||||
|
// Check cache first
|
||||||
|
if let Some(cached) = property_cache.get().get(wikidata_id) {
|
||||||
|
return cached.clone();
|
||||||
|
}
|
||||||
|
|
||||||
let sparql_query = format!(
|
let sparql_query = format!(
|
||||||
r#"
|
r#"
|
||||||
SELECT ?propLabel ?value ?valueLabel WHERE {{
|
SELECT ?propLabel ?value ?valueLabel WHERE {{
|
||||||
|
@ -408,28 +422,56 @@ pub fn ItemsList(
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
if let Ok(data) = response.json::<serde_json::Value>().await {
|
if let Ok(data) = response.json::<serde_json::Value>().await {
|
||||||
let mut result = HashMap::new();
|
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() {
|
if let Some(bindings) = data["results"]["bindings"].as_array() {
|
||||||
for binding in bindings {
|
for binding in bindings {
|
||||||
let prop = binding["propLabel"]["value"].as_str().unwrap_or("").to_string();
|
if let Some(prop) = binding["propLabel"]["value"].as_str() {
|
||||||
let prop_id = prop.replace("http://www.wikidata.org/prop/", "");
|
let prop_id = prop.replace("http://www.wikidata.org/prop/", "");
|
||||||
let value_label = binding["valueLabel"]["value"].as_str().unwrap_or("").to_string();
|
if !prop_ids.contains(&prop_id) {
|
||||||
|
prop_ids.push(prop_id.clone());
|
||||||
// Fetch property labels
|
|
||||||
let prop_label_map = fetch_property_labels(vec![prop_id]).await;
|
|
||||||
set_property_labels.update(|labels_map| {
|
|
||||||
for (key, value) in &prop_label_map {
|
|
||||||
labels_map.insert(key.clone(), value.clone());
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(prop_label) = prop_label_map.values().next() {
|
|
||||||
result.insert(prop_label.clone(), value_label);
|
|
||||||
}
|
}
|
||||||
log!("result: {:?}", result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Batch fetch missing labels
|
||||||
|
let existing_labels = property_labels.get();
|
||||||
|
let missing_ids: Vec<String> = prop_ids
|
||||||
|
.iter()
|
||||||
|
.filter(|id| !existing_labels.contains_key(*id))
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if !missing_ids.is_empty() {
|
||||||
|
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()
|
||||||
|
) {
|
||||||
|
let prop_id = prop.replace("http://www.wikidata.org/prop/", "");
|
||||||
|
if let Some(label) = property_labels.get().get(&prop_id).cloned() {
|
||||||
|
result.insert(label.clone(), value_label.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update cache
|
||||||
|
set_property_cache.update(|cache| {
|
||||||
|
cache.insert(wikidata_id.to_string(), result.clone());
|
||||||
|
});
|
||||||
|
|
||||||
result
|
result
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
HashMap::new()
|
HashMap::new()
|
||||||
}
|
}
|
||||||
|
@ -527,11 +569,27 @@ pub fn ItemsList(
|
||||||
let current_url = Rc::clone(¤t_url);
|
let current_url = Rc::clone(¤t_url);
|
||||||
let set_items = set_items.clone();
|
let set_items = set_items.clone();
|
||||||
let set_property_labels = set_property_labels.clone();
|
let set_property_labels = set_property_labels.clone();
|
||||||
|
let property_cache = property_cache.clone();
|
||||||
|
let set_property_cache = set_property_cache.clone();
|
||||||
Arc::new(move |property: String| {
|
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/", "");
|
||||||
let normalized_property_clone = normalized_property.clone();
|
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()]).await;
|
||||||
|
set_property_labels.update(|map| {
|
||||||
|
map.extend(labels);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Check if property is already selected
|
// Check if property is already selected
|
||||||
if !selected_properties.get().contains_key(&normalized_property) && !normalized_property.is_empty() {
|
if !selected_properties.get().contains_key(&normalized_property) && !normalized_property.is_empty() {
|
||||||
// Add property to selected properties
|
// Add property to selected properties
|
||||||
|
@ -608,7 +666,7 @@ pub fn ItemsList(
|
||||||
let set_property_labels = set_property_labels.clone();
|
let set_property_labels = set_property_labels.clone();
|
||||||
let property_clone = property.clone();
|
let property_clone = property.clone();
|
||||||
spawn_local(async move {
|
spawn_local(async move {
|
||||||
let properties = fetch_item_properties(&wikidata_id, set_property_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;
|
||||||
// Update fetched properties and property labels
|
// Update fetched properties and property labels
|
||||||
set_fetched_properties.update(|fp| {
|
set_fetched_properties.update(|fp| {
|
||||||
fp.insert(wikidata_id.clone(), properties.clone());
|
fp.insert(wikidata_id.clone(), properties.clone());
|
||||||
|
@ -650,7 +708,7 @@ pub fn ItemsList(
|
||||||
if let Some(wikidata_id) = &item.wikidata_id {
|
if let Some(wikidata_id) = &item.wikidata_id {
|
||||||
let wikidata_id = wikidata_id.clone();
|
let wikidata_id = wikidata_id.clone();
|
||||||
spawn_local(async move {
|
spawn_local(async move {
|
||||||
let properties = fetch_item_properties(&wikidata_id, set_property_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 index {}: {:?}", index, properties);
|
log!("Fetched properties for index {}: {:?}", index, properties);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -799,7 +857,7 @@ pub fn ItemsList(
|
||||||
// Fetch additional properties from Wikidata
|
// Fetch additional properties from Wikidata
|
||||||
let wikidata_id = id.clone();
|
let wikidata_id = id.clone();
|
||||||
spawn_local(async move {
|
spawn_local(async move {
|
||||||
let properties = fetch_item_properties(&wikidata_id, set_property_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);
|
// log!("Fetched properties for Wikidata ID {}: {:?}", wikidata_id, properties);
|
||||||
|
|
||||||
// Populate the custom properties for the new item
|
// Populate the custom properties for the new item
|
||||||
|
|
Loading…
Add table
Reference in a new issue