use iced::{ alignment, widget::{column, row, Container}, Element, Length, }; use schist_models::{Account, AccountTransfer, Bucket, Transaction}; use crate::{ gui::components::{ AccountNavigationEntry, Navigation, NewTransactionForm, TransactionsTable, navigation, new_transaction_form, transactions_table }, style::SPACING_LG, traits::{Component, Viewable}, }; #[derive(Clone, Debug)] pub struct TransactionsView { navigation: Navigation, new_transaction_form: NewTransactionForm, transactions_table: TransactionsTable, } #[derive(Clone, Debug)] pub enum Message { NavigationMessage(navigation::Message), NewTransactionFormMessage(new_transaction_form::Message), SelectNextAccount, SelectPrevAccount, SetAccounts(Vec), SetAccountTransfers(Vec), SetBuckets(Vec), SetTransactions(Vec), TransactionsTableMessage(transactions_table::Message), } pub enum Action { None, } impl TransactionsView { pub fn new( accounts: &[Account], account_transfers: &[AccountTransfer], buckets: &[Bucket], transactions: &[Transaction], ) -> Self { let account_navigation_entries: Vec = accounts .iter() .cloned() .map(AccountNavigationEntry::new) .collect(); let active_nav_entry = account_navigation_entries.first().cloned(); let navigation = Navigation::new( active_nav_entry.clone(), account_navigation_entries); let transactions_table = TransactionsTable::new(accounts, &active_nav_entry.map(|entry| entry.account), account_transfers, buckets, transactions); Self { navigation: navigation, new_transaction_form: NewTransactionForm::new(), transactions_table, } } } impl<'a> Component<'a, Message, Action> for TransactionsView { fn update(&mut self, message: Message) -> Action { match message { Message::NavigationMessage(message) => self.update_navigation(message), Message::TransactionsTableMessage(message) => self.update_transactions_table(message), Message::NewTransactionFormMessage(message) => self.update_new_transaction_form(message), Message::SetAccounts(accounts) => { let action_1 = self.update_transactions_table( transactions_table::Message::SetAccounts(accounts.clone())); let account_navigation_entries: Vec = accounts .into_iter() .map(AccountNavigationEntry::new) .collect(); let action_2 = self.update_navigation(navigation::Message::SetOptions(account_navigation_entries)); match (action_1, action_2) { (Action::None, Action::None) => Action::None } } Message::SetAccountTransfers(account_transfers) => { self.update_transactions_table( transactions_table::Message::SetAccountTransfers(account_transfers.clone())) } Message::SetBuckets(buckets) => { self.update_transactions_table( transactions_table::Message::SetBuckets(buckets.clone())) } Message::SetTransactions(transactions) => { self.update_transactions_table( transactions_table::Message::SetTransactions(transactions.clone())) } Message::SelectNextAccount => self.update_navigation(navigation::Message::SelectNext), Message::SelectPrevAccount => self.update_navigation(navigation::Message::SelectPrev), } } } impl TransactionsView { fn update_navigation( &mut self, message: navigation::Message, ) -> Action { match self.navigation.update(message) { navigation::Action::ActivateOption(option) | navigation::Action::SelectOption(option) => { self.update_transactions_table(transactions_table::Message::SetActiveAccount(option.account)) } navigation::Action::None => Action::None, } } fn update_transactions_table( &mut self, message: transactions_table::Message, ) -> Action { match self.transactions_table.update(message) { transactions_table::Action::None => Action::None, } } fn update_new_transaction_form( &mut self, message: new_transaction_form::Message, ) -> Action { match self.new_transaction_form.update(message) { new_transaction_form::Action::None => Action::None, } } } impl<'a> Viewable<'a, Message> for TransactionsView { fn view(&'a self) -> Element<'a, Message> { let navigation = self.navigation.view().map(Message::NavigationMessage); let table = self.transactions_table.view().map(Message::TransactionsTableMessage); let new_transaction_form = self.new_transaction_form.view().map(Message::NewTransactionFormMessage); row![ Container::new(navigation).width(Length::FillPortion(1)), column![ new_transaction_form, table, ].spacing(u32::from(SPACING_LG)).width(Length::FillPortion(3)), ] .align_y(alignment::Vertical::Center) .height(Length::Fill) .spacing(u32::from(SPACING_LG)) .into() } }