feat(list): Add initial empty row and auto-add new row on editing last row

This commit is contained in:
ryan 2024-12-24 15:26:52 +03:00
parent 863f05f8bc
commit 9f28d30d48
2 changed files with 39 additions and 45 deletions

View file

@ -4,7 +4,6 @@ use crate::components::items_list::ItemsList;
use crate::models::item::Item; use crate::models::item::Item;
use crate::nostr::NostrClient; use crate::nostr::NostrClient;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use uuid::Uuid;
use leptos::spawn_local; use leptos::spawn_local;
use nostr_sdk::serde_json; use nostr_sdk::serde_json;
@ -28,24 +27,10 @@ pub fn App() -> impl IntoView {
} }
}); });
// Handle adding a new item
let add_item = move || {
let new_item = Item {
id: Uuid::new_v4().to_string(),
name: "New Item".to_string(),
description: String::new(),
tags: vec![],
reviews: vec![],
wikidata_id: None,
};
set_items.update(|items| items.push(new_item));
};
view! { view! {
<Stylesheet href="/assets/style.css" /> <Stylesheet href="/assets/style.css" />
<div> <div>
<h1>{ "CompareWare" }</h1> <h1>{ "CompareWare" }</h1>
<button on:click=move |_| add_item()>{ "Add New Item" }</button>
<ItemsList items=items_signal set_items=set_items /> <ItemsList items=items_signal set_items=set_items />
</div> </div>
} }

View file

@ -14,12 +14,22 @@ struct WikidataSuggestion {
description: Option<String>, description: Option<String>,
} }
#[component] #[component]
pub fn ItemsList( pub fn ItemsList(
items: ReadSignal<Vec<Item>>, items: ReadSignal<Vec<Item>>,
set_items: WriteSignal<Vec<Item>>, set_items: WriteSignal<Vec<Item>>,
) -> impl IntoView { ) -> impl IntoView {
// Ensure there's an initial empty row
set_items.set(vec![Item {
id: Uuid::new_v4().to_string(),
name: String::new(),
description: String::new(),
tags: vec![],
reviews: vec![],
wikidata_id: None,
}]);
let (wikidata_suggestions, set_wikidata_suggestions) = let (wikidata_suggestions, set_wikidata_suggestions) =
create_signal(Vec::<WikidataSuggestion>::new()); create_signal(Vec::<WikidataSuggestion>::new());
@ -54,12 +64,26 @@ pub fn ItemsList(
match field { match field {
"name" => { "name" => {
item.name = value.clone(); item.name = value.clone();
fetch_wikidata_suggestions(value); fetch_wikidata_suggestions(value.clone());
}
"description" => {
item.description = value.clone();
} }
"description" => item.description = value,
_ => (), _ => (),
} }
} }
// Automatically add a new row when editing the last row
if index == items.len() - 1 && !value.is_empty() {
items.push(Item {
id: Uuid::new_v4().to_string(),
name: String::new(),
description: String::new(),
tags: vec![],
reviews: vec![],
wikidata_id: None,
});
}
}); });
}; };
@ -81,20 +105,6 @@ pub fn ItemsList(
}); });
}; };
// Add a new item
let add_item = move |_: web_sys::MouseEvent|{
set_items.update(|items| {
items.push(Item {
id: Uuid::new_v4().to_string(),
name: String::new(),
description: String::new(),
tags: vec![],
reviews: vec![],
wikidata_id: None,
});
});
};
// Remove an item // Remove an item
let remove_item = move |index: usize| { let remove_item = move |index: usize| {
set_items.update(|items| { set_items.update(|items| {
@ -105,7 +115,6 @@ pub fn ItemsList(
view! { view! {
<div> <div>
<h1>{ "Items List" }</h1> <h1>{ "Items List" }</h1>
<button on:click=add_item>{ "Add New Item" }</button>
<table> <table>
<thead> <thead>
<tr> <tr>
@ -121,11 +130,11 @@ pub fn ItemsList(
<tr> <tr>
// Editable Name Field with Wikidata Integration // Editable Name Field with Wikidata Integration
<td> <td>
<EditableCell <EditableCell
value=item.name.clone() value=item.name.clone()
on_input=move |value| update_item(index, "name", value) on_input=move |value| update_item(index, "name", value)
key=format!("name-{}", index) // Unique key per cell key=format!("name-{}", index) // Unique key per cell
/> />
<ul> <ul>
{move || { {move || {
let suggestions = wikidata_suggestions.get().to_vec(); let suggestions = wikidata_suggestions.get().to_vec();
@ -162,11 +171,11 @@ pub fn ItemsList(
</td> </td>
// Editable Description Field // Editable Description Field
<td> <td>
<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(index, "description", value)
key=format!("description-{}", index) key=format!("description-{}", index)
/> />
</td> </td>
// Tag Editor // Tag Editor
<td> <td>