use std::collections::HashMap; use iced::{ alignment, widget::{column, row, Container}, Element, Length, }; use itertools::Itertools; use schist_models::{Account, Transaction}; use crate::{ gui::components::{navigation, AccountNavigationEntry, Navigation, Text}, style::SPACING_LG, traits::{Component, Viewable}, }; #[derive(Clone, Debug)] pub struct TransactionsView { navigation: Navigation, transactions_by_account_id: HashMap>, } #[derive(Clone, Debug)] pub enum Message { NavigationMessage(navigation::Message), SelectNextAccount, SelectPrevAccount, SetAccounts(Vec), SetTransactions(Vec), } pub enum Action { None, } impl TransactionsView { pub fn new(accounts: Vec, transactions: Vec) -> Self { let account_navigation_entries: Vec = accounts .into_iter() .map(AccountNavigationEntry::new) .collect(); let navigation = Navigation::new( account_navigation_entries.first().cloned(), account_navigation_entries, ); Self { navigation: navigation, transactions_by_account_id: transactions .into_iter() .into_group_map_by(|t| t.account_id), } } } impl<'a> Viewable<'a, Message> for TransactionsView { fn view(&'a self) -> Element<'a, Message> { let navigation = self.navigation.view().map(Message::NavigationMessage); let main_content = column![ Text::default("Hello, transactions!").as_element(), Text::default(&format!( "{} transactions in this account.", self.navigation.active_option.clone().map_or( 0, |AccountNavigationEntry { account, .. }| self .transactions_by_account_id .get(&account.id) .map_or(0, |transactions| transactions.len()) ) )) .as_element(), ]; row![ Container::new(navigation).width(Length::FillPortion(1)), Container::new(main_content).width(Length::FillPortion(3)), ] .align_y(alignment::Vertical::Center) .height(Length::Fill) .spacing(SPACING_LG) .into() } } impl<'a> Component<'a, Message, Action> for TransactionsView { fn update(&mut self, message: Message) -> Action { match message { Message::NavigationMessage(message) => { self.navigation.update(message); Action::None } Message::SetAccounts(accounts) => { let account_navigation_entries: Vec = accounts .into_iter() .map(AccountNavigationEntry::new) .collect(); self.navigation .update(navigation::Message::SetOptions(account_navigation_entries)); Action::None } Message::SetTransactions(transactions) => { self.transactions_by_account_id = transactions.into_iter().into_group_map_by(|t| t.account_id); Action::None } Message::SelectNextAccount => { self.navigation.update(navigation::Message::SelectNext); Action::None } Message::SelectPrevAccount => { self.navigation.update(navigation::Message::SelectPrev); Action::None } } } }