-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: add basic console app using dioxus
- Loading branch information
Showing
9 changed files
with
1,715 additions
and
259 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#![allow(non_snake_case, deprecated)] | ||
|
||
pub mod account; | ||
pub mod app; | ||
pub mod customer; | ||
Check failure on line 5 in ucelofka/src/tui.rs GitHub Actions / Check
|
||
pub mod list; | ||
pub mod table; | ||
|
||
pub use app::{App, AppProps}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#![allow(non_snake_case, deprecated)] | ||
|
||
use dioxus::prelude::*; | ||
use std::rc::Rc; | ||
use ucelofka_data::account::Account; | ||
|
||
use crate::actions::account::list; | ||
|
||
use super::{app::UcelofkaTuiCfg, list::List, table::Table}; | ||
|
||
struct CurrentAccountPage(usize); | ||
|
||
#[derive(Clone)] | ||
enum SubPage { | ||
Create, | ||
Account(Account), | ||
} | ||
|
||
impl AsRef<str> for SubPage { | ||
fn as_ref(&self) -> &str { | ||
match self { | ||
Self::Create => "<Create>", | ||
Self::Account(account) => account.name.as_str(), | ||
} | ||
} | ||
} | ||
|
||
#[inline_props] | ||
pub fn Accounts(cx: Scope) -> Element { | ||
use_shared_state_provider(cx, || CurrentAccountPage(0)); | ||
|
||
let account_page = use_shared_state::<CurrentAccountPage>(cx).unwrap(); | ||
|
||
let cfg = use_shared_state::<UcelofkaTuiCfg>(cx).unwrap(); | ||
let accounts = list(cfg.read().path.as_path()).unwrap().accounts; | ||
let items: Vec<SubPage> = vec![SubPage::Create] | ||
.into_iter() | ||
.chain(accounts.iter().map(|e| SubPage::Account(e.clone()))) | ||
.collect(); | ||
|
||
let items_str: Vec<String> = items.iter().map(|e| e.as_ref().to_string()).collect(); | ||
let selected_idx = account_page.read().0; | ||
let selected_account = if selected_idx == 0 { | ||
None | ||
} else { | ||
Some(accounts[selected_idx - 1].clone()) | ||
}; | ||
|
||
cx.render(rsx! { | ||
List { | ||
tabindex: 0, | ||
width: "20%", | ||
items: Rc::new(items_str), | ||
dot: "❱", | ||
idx: account_page.read().0.into(), | ||
onindexupdate: move |i: usize| { | ||
account_page.write().0 = i.into(); | ||
} | ||
} | ||
div { | ||
width: "60%", | ||
border_width: "1px", | ||
height: "100%", | ||
justify_content: "center", | ||
if let Some(account) = selected_account { | ||
rsx! { | ||
Table { | ||
width: "100%", | ||
items: vec![ | ||
("Name:", account.name), | ||
("Bank Name:", account.bank_name), | ||
("Account Name:", account.account_name), | ||
("Account number:", account.account_number), | ||
("IBAN:", account.IBAN), | ||
("BIC:", account.BIC), | ||
("Currency:", account.currency), | ||
|
||
] | ||
} | ||
} | ||
} else { | ||
rsx! {span { "TODO CREATE FORM"}} | ||
} | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
#![allow(non_snake_case, deprecated)] | ||
|
||
use dioxus::{ | ||
events::{KeyCode, KeyboardEvent}, | ||
prelude::*, | ||
}; | ||
use dioxus_tui::TuiContext; | ||
use std::{rc::Rc, path::PathBuf}; | ||
|
||
use super::{ | ||
list::List, | ||
account::Accounts, | ||
customer::Customers, | ||
Check failure on line 13 in ucelofka/src/tui/app.rs GitHub Actions / Check
|
||
}; | ||
|
||
struct CurrentPage(Page); | ||
|
||
pub struct UcelofkaTuiCfg { | ||
pub path: PathBuf | ||
} | ||
|
||
#[derive(Clone, Copy)] | ||
enum Page { | ||
Accounts, | ||
Customers, | ||
Entries, | ||
Identities, | ||
Invoices, | ||
} | ||
impl AsRef<str> for Page { | ||
fn as_ref(&self) -> &str { | ||
match self { | ||
Self::Accounts => "Accounts", | ||
Self::Customers => "Customers", | ||
Self::Entries => "Entries", | ||
Self::Identities => "Identities", | ||
Self::Invoices => "Invoices", | ||
} | ||
} | ||
} | ||
|
||
impl From<usize> for Page { | ||
fn from(page: usize) -> Self { | ||
match page { | ||
0 => Self::Accounts, | ||
1 => Self::Customers, | ||
2 => Self::Entries, | ||
3 => Self::Identities, | ||
4 => Self::Invoices, | ||
_ => unreachable!(), | ||
} | ||
} | ||
} | ||
|
||
impl Into<usize> for Page { | ||
fn into(self) -> usize { | ||
match self { | ||
Self::Accounts => 0, | ||
Self::Customers => 1, | ||
Self::Entries => 2, | ||
Self::Identities => 3, | ||
Self::Invoices => 4, | ||
} | ||
} | ||
} | ||
|
||
#[inline_props] | ||
pub fn App(cx: Scope, path: PathBuf) -> Element { | ||
let tui_ctx: TuiContext = cx.consume_context().unwrap(); | ||
|
||
use_shared_state_provider(cx, || CurrentPage(Page::Accounts)); | ||
use_shared_state_provider(cx, || UcelofkaTuiCfg {path: path.clone()}); | ||
|
||
let page = use_shared_state::<CurrentPage>(cx).unwrap(); | ||
|
||
let items = Rc::new(vec![ | ||
Page::Accounts.as_ref(), | ||
Page::Customers.as_ref(), | ||
Page::Entries.as_ref(), | ||
Page::Identities.as_ref(), | ||
Page::Invoices.as_ref(), | ||
]); | ||
|
||
let header_element = use_state(cx, || None::<Rc<MountedData>>); | ||
let onkeydown = move |k: KeyboardEvent| { | ||
match k.key_code { | ||
KeyCode::Q => { | ||
tui_ctx.quit(); | ||
} | ||
KeyCode::P => { | ||
if let Some(he) = header_element.as_ref() { | ||
let inner = he.clone(); | ||
cx.spawn(async move { | ||
let _ = inner.set_focus(true).await; | ||
}); | ||
} | ||
} | ||
_ => {} | ||
} | ||
}; | ||
|
||
let onmounted = move |ctx: MountedEvent| { | ||
header_element.set(Some(ctx.inner().clone())); | ||
let inner = ctx.inner().clone(); | ||
cx.spawn(async move { | ||
let _ = inner.set_focus(true).await; | ||
}); | ||
}; | ||
|
||
cx.render(rsx! { | ||
div { | ||
width: "100%", | ||
height: "100%", | ||
justify_content: "center", | ||
align_items: "center", | ||
onkeydown: onkeydown, | ||
onmounted: onmounted, | ||
tabindex: -1, | ||
List { | ||
tabindex: 0, | ||
width: "20%", | ||
items: items, | ||
dot: "❱", | ||
idx: page.read().0.into(), | ||
onindexupdate: move |i: usize| { | ||
page.write().0 = i.into(); | ||
} | ||
} | ||
match page.read().0 { | ||
Page::Accounts => { | ||
rsx! { | ||
Accounts {} | ||
} | ||
|
||
} | ||
Page::Customers => { | ||
rsx! { | ||
Customers {} | ||
} | ||
|
||
} | ||
_ => rsx! { | ||
div { background_color: "green", width: "80%", "{page.read().0.as_ref()} is under construction" } | ||
} | ||
} | ||
} | ||
}) | ||
} | ||
// div { background_color: "green", width: "50%", "Hello worlds! {page}" } | ||
// input { | ||
// background_color: "blue", | ||
// r#type: "checkbox", | ||
// value: "good", | ||
// height: "1px", | ||
// checked: "{bg_green}", | ||
// width: "2px", | ||
// oninput: move |data| { | ||
// if &data.value == "good" { | ||
// bg_green.set(true); | ||
// } else { | ||
// bg_green.set(false); | ||
// } | ||
// } | ||
// } |
Oops, something went wrong.