feat(items-list): enhance the ItemsList
component to integrate focus and blur signal handling for suggestions from Wikidata
This commit is contained in:
parent
5306efc447
commit
139ea0805c
1 changed files with 90 additions and 44 deletions
|
@ -27,6 +27,9 @@ pub fn ItemsList(
|
||||||
// State to manage dynamic property names
|
// State to manage dynamic property names
|
||||||
let (custom_properties, set_custom_properties) = create_signal(Vec::<String>::new());
|
let (custom_properties, set_custom_properties) = create_signal(Vec::<String>::new());
|
||||||
|
|
||||||
|
// state to manage suggestions visibility
|
||||||
|
let (show_suggestions, set_show_suggestions) = create_signal(false);
|
||||||
|
|
||||||
// Ensure there's an initial empty row
|
// Ensure there's an initial empty row
|
||||||
set_items.set(vec![Item {
|
set_items.set(vec![Item {
|
||||||
id: Uuid::new_v4().to_string(),
|
id: Uuid::new_v4().to_string(),
|
||||||
|
@ -42,6 +45,7 @@ pub fn ItemsList(
|
||||||
|
|
||||||
// Fetch Wikidata suggestions
|
// Fetch Wikidata suggestions
|
||||||
let fetch_wikidata_suggestions = move |key:String, query: String| {
|
let fetch_wikidata_suggestions = move |key:String, query: String| {
|
||||||
|
log!("Fetching suggestions for key: {}, query: {}", key, query);
|
||||||
spawn_local(async move {
|
spawn_local(async move {
|
||||||
if query.is_empty() {
|
if query.is_empty() {
|
||||||
set_wikidata_suggestions.update(|suggestions| {
|
set_wikidata_suggestions.update(|suggestions| {
|
||||||
|
@ -58,7 +62,9 @@ pub fn ItemsList(
|
||||||
match gloo_net::http::Request::get(&url).send().await {
|
match gloo_net::http::Request::get(&url).send().await {
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
if let Ok(data) = response.json::<WikidataResponse>().await {
|
if let Ok(data) = response.json::<WikidataResponse>().await {
|
||||||
|
log!("Fetching suggestions for key: {}, query: {}", key, query);
|
||||||
set_wikidata_suggestions.update(|suggestions| {
|
set_wikidata_suggestions.update(|suggestions| {
|
||||||
|
log!("Updated suggestions: {:?}", suggestions);
|
||||||
suggestions.insert(key, data.search);
|
suggestions.insert(key, data.search);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -163,52 +169,80 @@ pub fn ItemsList(
|
||||||
<td>
|
<td>
|
||||||
{match property {
|
{match property {
|
||||||
"Name" => view! {
|
"Name" => view! {
|
||||||
<EditableCell
|
<div class="editable-cell">
|
||||||
value=item.name.clone()
|
<EditableCell
|
||||||
on_input=move |value| {
|
value=item.name.clone()
|
||||||
update_item(index, "name", value.clone());
|
on_input=move |value| {
|
||||||
fetch_wikidata_suggestions(format!("name-{}", index), value);
|
update_item(index, "name", value.clone());
|
||||||
}
|
fetch_wikidata_suggestions(format!("name-{}", index), value);
|
||||||
key=Arc::new(format!("name-{}", index))
|
}
|
||||||
focused_cell=focused_cell
|
key=Arc::new(format!("name-{}", index))
|
||||||
set_focused_cell=set_focused_cell.clone()
|
focused_cell=focused_cell
|
||||||
/>
|
set_focused_cell=set_focused_cell.clone()
|
||||||
<ul>
|
on_focus=Some(Callback::new(move |_| {
|
||||||
{move || {
|
log!("Input focused, showing suggestions");
|
||||||
let suggestions = wikidata_suggestions.get()
|
set_show_suggestions.set(true);
|
||||||
.get(&format!("name-{}", index))
|
}))
|
||||||
.cloned()
|
on_blur=Some(Callback::new(move |_| {
|
||||||
.unwrap_or_default();
|
log!("Input blurred, delaying hiding suggestions");
|
||||||
suggestions.into_iter().map(|suggestion| {
|
spawn_local(async move {
|
||||||
let label_for_click = suggestion.label.clone();
|
gloo_timers::future::sleep(std::time::Duration::from_millis(500)).await;
|
||||||
let label_for_display = suggestion.label.clone();
|
log!("Hiding suggestions after delay");
|
||||||
let description_for_click = suggestion.description.clone().unwrap_or_default();
|
set_show_suggestions.set(false);
|
||||||
let description_for_display = suggestion.description.clone().unwrap_or_default();
|
|
||||||
let id = suggestion.id.clone();
|
|
||||||
|
|
||||||
// Tags for the item
|
|
||||||
let tags = vec![
|
|
||||||
("source".to_string(), "wikidata".to_string()),
|
|
||||||
("wikidata_id".to_string(), id.clone()),
|
|
||||||
];
|
|
||||||
|
|
||||||
view! {
|
|
||||||
<li on:click=move |_| {
|
|
||||||
set_items.update(|items| {
|
|
||||||
if let Some(item) = items.get_mut(index) {
|
|
||||||
item.description = description_for_click.clone();
|
|
||||||
item.tags.extend(tags.clone());
|
|
||||||
item.wikidata_id = Some(id.clone());
|
|
||||||
item.name = label_for_click.clone();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}>
|
}))
|
||||||
{ format!("{} - {}", label_for_display, description_for_display) }
|
/>
|
||||||
</li>
|
{move || {
|
||||||
}
|
if show_suggestions.get() {
|
||||||
}).collect::<Vec<_>>()
|
log!("Rendering suggestions list");
|
||||||
|
view! {
|
||||||
|
<ul class="editable-cell-suggestions">
|
||||||
|
{move || {
|
||||||
|
let suggestions = wikidata_suggestions.get()
|
||||||
|
.get(&format!("name-{}", index))
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
log!("Suggestions for cell {}: {:?}", index, suggestions);
|
||||||
|
suggestions.into_iter().map(|suggestion| {
|
||||||
|
let label_for_click = suggestion.label.clone();
|
||||||
|
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();
|
||||||
|
|
||||||
|
// Tags for the item
|
||||||
|
let tags = vec![
|
||||||
|
("source".to_string(), "wikidata".to_string()),
|
||||||
|
("wikidata_id".to_string(), id.clone()),
|
||||||
|
];
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<li class="editable-cell-suggestions-li" on:click=move |_| {
|
||||||
|
set_items.update(|items| {
|
||||||
|
if let Some(item) = items.get_mut(index) {
|
||||||
|
item.description = description_for_click.clone();
|
||||||
|
item.tags.extend(tags.clone());
|
||||||
|
item.wikidata_id = Some(id.clone());
|
||||||
|
item.name = label_for_click.clone();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
set_show_suggestions.set(false);
|
||||||
|
}>
|
||||||
|
{ format!("{} - {}", label_for_display, description_for_display) }
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
}).collect::<Vec<_>>()
|
||||||
|
}}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log!("Suggestions list hidden");
|
||||||
|
view! {
|
||||||
|
<ul></ul>
|
||||||
|
}
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
</ul>
|
</div>
|
||||||
}.into_view(),
|
}.into_view(),
|
||||||
"Description" => view! {
|
"Description" => view! {
|
||||||
<EditableCell
|
<EditableCell
|
||||||
|
@ -217,6 +251,12 @@ pub fn ItemsList(
|
||||||
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()
|
||||||
|
on_focus=Some(Callback::new(move |_| {
|
||||||
|
log!("Description input focused");
|
||||||
|
}))
|
||||||
|
on_blur=Some(Callback::new(move |_| {
|
||||||
|
log!("Description input blurred");
|
||||||
|
}))
|
||||||
/>
|
/>
|
||||||
}.into_view(),
|
}.into_view(),
|
||||||
"Tags" => view! {
|
"Tags" => view! {
|
||||||
|
@ -259,6 +299,12 @@ pub fn ItemsList(
|
||||||
key=Arc::new(format!("custom-{}-{}", property_clone, index))
|
key=Arc::new(format!("custom-{}-{}", property_clone, index))
|
||||||
focused_cell=focused_cell
|
focused_cell=focused_cell
|
||||||
set_focused_cell=set_focused_cell.clone()
|
set_focused_cell=set_focused_cell.clone()
|
||||||
|
on_focus=Some(Callback::new(move |_| {
|
||||||
|
log!("Custom property input focused");
|
||||||
|
}))
|
||||||
|
on_blur=Some(Callback::new(move |_| {
|
||||||
|
log!("Custom property input blurred");
|
||||||
|
}))
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue