use std::sync::Arc; use leptos::either::either; use crate::components::{ActionButton, OutlinedTextField}; use leptos::prelude::*; use crate::common::InputType; use crate::components::ValueType; use super::{multi_entry_data::*, multi_entry_member::*}; fn render_entry_component(entry_data: MultiEntryData, member_info: MultiEntryMember, label: String) -> impl IntoView { // Parse the multientry members into the correct components let data = entry_data.data.get(&member_info.member_name); let reactive = RwSignal::new(data.unwrap().as_string().unwrap()); let temp = either!(member_info.input_type, InputType::Text => view! { }, _ => view! {} ); temp.into_view() } /// Represents a single entry in a MultiEntry component. /// These are displayed in a list, and function a little bit like a dropdown. /// When clicked, they expand to show all the inputs, which can be edited. #[component] pub fn Entry( /// The data for this entry. #[prop()] entry_data: MultiEntryData, /// The main display member for this entry. #[prop()] name_member: Signal, /// The secondary display member for this entry. #[prop()] info_member: Signal, /// The schema for all inputs that should be used, and what `MultiEntryMember` info is associated /// with them. #[prop()] schema: Arc> ) -> impl IntoView { let name_data = entry_data.data.get(&name_member.get().member_name).unwrap(); let info_data = entry_data.data.get(&info_member.get().member_name).unwrap(); let schema = Arc::clone(&schema); view! { // This div MUST have the same spacing CSS as the second-level header div
{name_data.to_string()} {info_data.to_string()}
{schema .iter() .map(|input_type| { let data = entry_data.clone(); let input = input_type.clone(); view! {
{render_entry_component(data, input, "test".to_owned())}
} }).collect::>() } } } /// Allows users to enter more open-ended information, and generates a `Vec` filled /// with the user's entered information. The schema for this data must be defined by this component /// such that it is constructable using a series of `String` keys, where each key stores a single /// `ValueType` enum. #[component] pub fn MultiEntry( /// The list of entries to use. #[prop()] entries: RwSignal>, /// The main display member for each entry object. #[prop()] name_member: Signal, /// The secondary display member for each entry object. #[prop()] info_member: Signal, /// The schema of the components. Determines what kind of data is stored and where. /// The `name_member` and `info_member` should be included in this list. #[prop(optional)] schema: Vec ) -> impl IntoView { // Creates an entry in the given entries list. let create_entry = move |_| { let mut new_entry = MultiEntryData::new(); new_entry.data.insert( name_member.get().member_name, ValueType::String(String::from("Testing")), ); new_entry.data.insert( info_member.get().member_name, ValueType::String(new_entry.id.to_string()), ); entries.update(|entry_vec| entry_vec.push(new_entry)); }; let rc_schema = Arc::new(schema); view! {
// Header section
// This div MUST have the same spacing CSS as the main entry div
{name_member.get().display_name} {info_member.get().display_name}
// Entry section
} } />
Add Entry } }