Lines
0 %
Functions
Branches
100 %
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
pub mod autocomplete;
pub mod data_attrs;
pub mod entity_form_tag;
pub mod entity_tag;
pub mod htmx;
pub mod report;
pub mod transaction;
pub mod types;
pub use entity_form_tag::{add_entity_form_tag, load_existing_entity_tags, remove_entity_form_tag};
pub use entity_tag::{
add_entity_tag, cancel_entity_tag, delete_entity_tag, edit_entity_tag, filter_entity_tags,
};
pub use report::{
add_report_account_filter, add_report_tag_filter, add_report_tag_group,
remove_report_filter_item, restore_all_filters, sync_tag_filter_mode,
pub use transaction::{add_split_tag, get_split_count, load_existing_split_tags, remove_split_tag};
pub use types::*;
#[derive(Serialize, Deserialize)]
pub struct WasmStatus {
loaded: bool,
version: String,
message: String,
}
#[wasm_bindgen]
#[must_use]
pub fn get_wasm_status() -> JsValue {
let status = WasmStatus {
loaded: true,
version: env!("CARGO_PKG_VERSION").to_string(),
message: "WASM module loaded successfully".to_string(),
serde_wasm_bindgen::to_value(&status).unwrap()
#[cfg(feature = "auto-init")]
#[wasm_bindgen(start)]
pub fn main() {
console_error_panic_hook::set_once();
register_global_functions();
htmx::setup_htmx_validation();
setup_htmx_listener();
let Some(document) = web_sys::window().and_then(|w| w.document()) else {
return;
if document.ready_state() == "loading" {
let callback = wasm_bindgen::closure::Closure::wrap(Box::new(|| {
restore_all_filters();
autocomplete::init_all();
init_transaction_form();
}) as Box<dyn Fn()>);
let _ = document.add_event_listener_with_callback(
"DOMContentLoaded",
callback.as_ref().unchecked_ref(),
);
callback.forget();
} else {
fn register_global_functions() {
use wasm_bindgen::JsCast;
let Some(window) = web_sys::window() else {
let get_split_count = Closure::wrap(Box::new(get_split_count) as Box<dyn Fn() -> u32>);
let _ = js_sys::Reflect::set(
&window,
&"getSplitCount".into(),
get_split_count.as_ref().unchecked_ref(),
get_split_count.forget();
let add_split_tag = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
add_split_tag(&el);
}) as Box<dyn Fn(web_sys::HtmlElement)>);
&"addSplitTag".into(),
add_split_tag.as_ref().unchecked_ref(),
add_split_tag.forget();
let remove_split_tag = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
remove_split_tag(&el);
&"removeSplitTag".into(),
remove_split_tag.as_ref().unchecked_ref(),
remove_split_tag.forget();
let add_tag_filter = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
add_report_tag_filter(&el);
&"addReportTagFilter".into(),
add_tag_filter.as_ref().unchecked_ref(),
add_tag_filter.forget();
let add_account_filter = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
add_report_account_filter(&el);
&"addReportAccountFilter".into(),
add_account_filter.as_ref().unchecked_ref(),
add_account_filter.forget();
let add_tag_group = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
add_report_tag_group(&el);
&"addReportTagGroup".into(),
add_tag_group.as_ref().unchecked_ref(),
add_tag_group.forget();
let remove_filter_item = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
remove_report_filter_item(&el);
&"removeReportFilterItem".into(),
remove_filter_item.as_ref().unchecked_ref(),
remove_filter_item.forget();
let sync_mode = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
sync_tag_filter_mode(&el);
&"syncTagFilterMode".into(),
sync_mode.as_ref().unchecked_ref(),
sync_mode.forget();
let add_entity_tag_fn = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
add_entity_tag(&el);
&"addEntityTag".into(),
add_entity_tag_fn.as_ref().unchecked_ref(),
add_entity_tag_fn.forget();
let edit_entity_tag_fn = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
edit_entity_tag(&el);
&"editEntityTag".into(),
edit_entity_tag_fn.as_ref().unchecked_ref(),
edit_entity_tag_fn.forget();
let cancel_entity_tag_fn = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
cancel_entity_tag(&el);
&"cancelEntityTag".into(),
cancel_entity_tag_fn.as_ref().unchecked_ref(),
cancel_entity_tag_fn.forget();
let delete_entity_tag_fn = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
delete_entity_tag(&el);
&"deleteEntityTag".into(),
delete_entity_tag_fn.as_ref().unchecked_ref(),
delete_entity_tag_fn.forget();
let filter_entity_tags_fn = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
filter_entity_tags(&el);
&"filterEntityTags".into(),
filter_entity_tags_fn.as_ref().unchecked_ref(),
filter_entity_tags_fn.forget();
let add_entity_form_tag_fn = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
add_entity_form_tag(&el);
&"addEntityFormTag".into(),
add_entity_form_tag_fn.as_ref().unchecked_ref(),
add_entity_form_tag_fn.forget();
let remove_entity_form_tag_fn = Closure::wrap(Box::new(|el: web_sys::HtmlElement| {
remove_entity_form_tag(&el);
&"removeEntityFormTag".into(),
remove_entity_form_tag_fn.as_ref().unchecked_ref(),
remove_entity_form_tag_fn.forget();
fn init_transaction_form() {
let is_transaction_page = document
.query_selector("#splits-container")
.ok()
.flatten()
.is_some();
if is_transaction_page {
transaction::setup_field_validation();
transaction::setup_form_submit_handler();
transaction::setup_split_handlers();
transaction::initialize_transaction_form();
transaction::load_existing_split_tags();
fn init_entity_tag_forms() {
let has_entity_tags = document
.query_selector(".entity-tags-container")
if has_entity_tags {
entity_form_tag::load_existing_entity_tags();
fn setup_htmx_listener() {
let callback = Closure::wrap(Box::new(|_: web_sys::Event| {
}) as Box<dyn FnMut(_)>);
let _ = document
.add_event_listener_with_callback("htmx:afterSwap", callback.as_ref().unchecked_ref());