From 37d157725ee2bb46b453d3944dde2346fd7496cd Mon Sep 17 00:00:00 2001 From: ryan Date: Fri, 18 Apr 2025 15:43:23 +0300 Subject: [PATCH] fix(typeahead): create a new row when typing in the name input field --- src/components/items_list.rs | 52 +++++++++++++++++++++++++++---- src/components/typeahead_input.rs | 13 ++++++-- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/components/items_list.rs b/src/components/items_list.rs index d0eeec5..bb3cb6e 100644 --- a/src/components/items_list.rs +++ b/src/components/items_list.rs @@ -804,12 +804,18 @@ pub fn ItemsList( {properties.into_iter().map(|property| { let update_item_cloned = Arc::clone(&update_item); + let current_url_for_closure = Rc::clone(¤t_url); log!("Rendering property: {}", property); view! { { property } - {move || items.get().iter().enumerate().map(|(index, item)| { - let update_item_clone = Arc::clone(&update_item_cloned); + {{ + move || { + let items = items.get(); + items.iter().enumerate().map(|(index, item)| { + let update_item_clone = Arc::clone(&update_item_cloned); + let current_url_clone = Rc::clone(¤t_url_for_closure); + view! { {match property { @@ -855,7 +861,38 @@ pub fn ItemsList( } }); }) - node_ref=node_ref + is_last_row={index == items.len() - 1} + on_input=Callback::new({ + // Clone items.len() before moving into the closure + let items_len = items.len(); + let current_url_for_spawn = Rc::clone(¤t_url_clone); + move |value: String| { + if index == items_len - 1 && !value.is_empty() { + // Use the cloned current_url + let current_url_for_new_item = Rc::clone(¤t_url_for_spawn); + set_items.update(|items| { + let new_item = Item { + id: Uuid::new_v4().to_string(), + name: String::new(), + description: String::new(), + 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_for_new_item); + let selected_properties = selected_properties; + async move { + save_item_to_db(new_item, selected_properties, current_url.to_string()).await; + } + }); + }); + } + } + }) + node_ref=create_node_ref() /> }.into_view(), @@ -882,7 +919,9 @@ pub fn ItemsList( }} } - }).collect::>()} + }).collect::>() + } + }} } }).collect::>()} @@ -924,7 +963,8 @@ pub fn ItemsList( {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 items = items.get(); + items.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(); view! { @@ -986,7 +1026,7 @@ pub fn ItemsList( - } + } } #[derive(Deserialize, Clone, Debug)] diff --git a/src/components/typeahead_input.rs b/src/components/typeahead_input.rs index c43ba6b..53b9f45 100644 --- a/src/components/typeahead_input.rs +++ b/src/components/typeahead_input.rs @@ -1,4 +1,3 @@ - use leptos::*; use wasm_bindgen::prelude::*; use crate::models::item::WikidataSuggestion; @@ -16,6 +15,8 @@ pub fn TypeaheadInput( on_select: Callback, fetch_suggestions: Callback>, node_ref: NodeRef, + #[prop(optional)] is_last_row: bool, + #[prop(optional)] on_input: Option>, ) -> impl IntoView { let (is_initialized, set_initialized) = create_signal(false); @@ -111,6 +112,14 @@ pub fn TypeaheadInput( on:input=move |ev| { let value = event_target_value(&ev); log!("[INPUT] Value changed: {}", value); + + // If this is the last row and we have an on_input callback, call it + if is_last_row && !value.is_empty() { + if let Some(callback) = &on_input { + callback.call(value.clone()); + } + } + let _ = js_sys::eval("console.log('jQuery version:', $.fn.jquery)"); let _ = js_sys::eval("console.log('Typeahead version:', $.fn.typeahead ? 'loaded' : 'missing')"); } @@ -371,4 +380,4 @@ fn initialize_typeahead( if let Err(e) = js_sys::eval(&init_script) { log!("[RUST] Eval error: {:?}", e); } -} +} \ No newline at end of file