diff --git a/advotracker/src/callbacks/policycheck_state.rs b/advotracker/src/callbacks/policycheck_state.rs index 5ffcb91..7cef10b 100644 --- a/advotracker/src/callbacks/policycheck_state.rs +++ b/advotracker/src/callbacks/policycheck_state.rs @@ -1,12 +1,12 @@ -use chrono::{Local, DateTime}; +//use chrono::{Local, DateTime, Duration}; use dotenv::dotenv; use locales::t; use orbtk::prelude::*; -//use orbtk::shell::WindowRequest; +use orbtk::shell::WindowRequest; use serde::Deserialize; -//use std::{env, process, thread, time}; use std::{env, process}; use std::collections::HashMap; +use std::time::{Duration, SystemTime}; use tracing::{debug, error, info, trace}; use crate::services::imports::allianzdirectcall::import; @@ -23,14 +23,15 @@ use crate::{ pub enum Action { ClearEntry(Entity), InputTextChanged(Entity), + ImportData, OpenMenu(Entity), ParseEntry(Entity), AddProgress(f64), ResetProgress, SetProgress(f64), - SetProgressBox(Entity), + SetProgressPopup(Entity), RemoveFocus(Entity), - RemoveProgressBox(Entity), + RemoveProgressPopup(Entity), SetEntry(Entity), SetVisibility(Entity), TextChanged(Entity, usize), @@ -46,15 +47,15 @@ struct Environment { #[derive(Default, AsAny)] pub struct PolicyCheckState { action: Option, + duration: Duration, label_result: Entity, last_focused: Option, menu_button: Entity, - //policy_check_clean_button: Entity, - //policy_check: PolicyCheck, policy_data_count: usize, - //policy_number_text_box: Entity, policy_numbers: HashMap, - progress_box: Option + progress_bar: Entity, + progress_count: f64, + progress_popup: Entity } impl GlobalState for PolicyCheckState {} @@ -67,7 +68,9 @@ impl PolicyCheckState { } /// Create a hashmap (key: policy number, value: policy type). - pub fn create_hashmap(&mut self) -> Result<(), Box> { + pub fn create_hashmap(&mut self, _ctx: &mut Context<'_>) -> Result<(), Box> { + trace!(target: "advotracker", create_hashmap = "started"); + // WIP: redundant lang selection (already in main!) let mut lang = env::var("lang").unwrap_or("en".to_string()); // testing environment: read from .env file @@ -79,10 +82,10 @@ impl PolicyCheckState { Err(e) => { debug!(target: "advotracker", "{}", e); } } - // importing policy code elements from csv-file let policy_list = PolicyList::new("Allianz Versicherungsnummen-List"); trace!(target: "advotracker", policy_list = ?policy_list); + // create vector to hold imported data let mut policy_data = PolicyDataList::new("Allianz-Import latest"); trace!(target: "advotracker", policy_data = ?policy_data); @@ -94,10 +97,12 @@ impl PolicyCheckState { match import(&mut csv_import_path, &mut policy_data, &mut policy_numbers, &mut self.policy_data_count, &lang) { - Ok(count) => { + Ok((count, duration)) => { self.policy_data_count = count; + self.duration = duration; trace!(target: "advotracker", csv_import_path = ?csv_import_path, - policy_data_count = ?&self.policy_data_count); + policy_data_count = ?&self.policy_data_count, + duration = ?&self.duration); } Err(err) => { error!("error running CSV-Import: {}", err); @@ -106,6 +111,9 @@ impl PolicyCheckState { }; self.policy_numbers = policy_numbers; + + trace!(target: "advotracker", create_hashmap = "finished"); + Ok(()) } @@ -116,49 +124,52 @@ impl PolicyCheckState { } /// Import policy numbers into hashmap - fn import_data(&mut self, ctx: &mut Context<'_>) + fn import_data(&mut self, lang: &String, ctx: &mut Context<'_>) -> Result<(), Box> { // WIP: for now, only import once per session - //let two_seconds = time::Duration::from_secs(2); - //let sender = ctx.window_sender(); - if self.policy_data_count == 0 { let mut text_block_wrapper: TextBlockCtx<'_> = text_block(ctx.child("policy_check_result")); text_block_wrapper.set_enabled(true); - text_block_wrapper.set_text("Importieren der Prüflisten-Elemente ..."); - // self.set_popup_box(ctx); - // progress_bar(ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)).set_val(0.25); - // for _ in 1..4 { - // let old_width = *progress_bar(ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)).val(); - // let new_width = old_width + 0.33; - // progress_bar(ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)).set_val(new_width); - // thread::sleep(two_seconds); - // } + if self.policy_numbers.len() == 0 { + // initialize popup widget + let sender = ctx.window_sender(); + self.set_progress_popup(&lang, ctx); + self.progress_count += 0.33; + self.update_progress_bar(&lang, ctx); + sender.send(WindowRequest::Redraw).unwrap(); - //sender.send(WindowRequest::Redraw).unwrap(); + // for _ in 1..4 { + // self.progress_count += 0.33; + // self.update_progress_bar(ctx); + // sender.send(WindowRequest::Redraw).unwrap(); + //} - match self.create_hashmap() { - Ok(()) => { - //let res = t!("policy.hashmap.success", lang); - //println!("{:?}", res); - info!("hashmap has: {:?} entries", self.policy_data_count); - trace!(target: "advotracker", - hashmap_status = "new import", - hashmap_entries = ?self.policy_data_count); - } - _ => { - // let res = t!("policy.hashmap.failed", lang); - // println - // !("{:?}", res); - error!("Creation of a hashmap failed!"); - trace!(target: "advotracker", hashmap_status = "failed"); + // importing policy code elements from csv-file + match self.create_hashmap(ctx) { + Ok(()) => { + let res = t!("policy.hashmap.success", lang); + info!("hashmap has: {:?} entries", self.policy_data_count); + trace!(target: "advotracker", + hashmap_status = ?res, + hashmap_entries = ?self.policy_data_count); + + self.progress_count = 1.; + self.update_progress_bar(&lang, ctx); + + sender.send(WindowRequest::Redraw).unwrap(); + } + _ => { + let res = t!("policy.hashmap.failed", lang); + error!("{:?}", res); + trace!(target: "advotracker", hashmap_status = ?res); + } } + + + // remove popup widget now, that we are done + //self.remove_progress_popup(ctx); } - - // remove popup widget now, that we are done - //self.remove_progress_box(ctx); - } else { trace!(target: "advotracker", hashmap_status = "consume", @@ -192,30 +203,10 @@ impl PolicyCheckState { Err(e) => { debug!(target: "advotracker", "{}", e); } } - // let sender = ctx.window_sender(); - // self.set_progress_box(ctx); - // let one_seconds = time::Duration::from_secs(1); - // for i in 1..4 { - // let old_width = *progress_bar(ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)).val(); - // let new_width = old_width + 0.33; - // println!("progress changed: {}", new_width); - // sender.send(WindowRequest::Redraw).unwrap(); - - // progress_bar(ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)).set_val(new_width); - // thread::sleep(one_seconds); - // } - //self.remove_progress_box(ctx); - // Load data into hashmap - trace!(target: "advotracker", state = "importing"); - match self.import_data(ctx) { - Ok(()) => { - trace!(target: "advotracker", import_data = "success"); - } - _ => { - error!("Importing data failed!"); - trace!(target: "advotracker", import_data = "failed"); - } + match self.import_data(&lang, ctx) { + Ok(()) => trace!(target: "advotracker", policycheck_state = "init", import_data = "success"), + Err(e) => trace!(target: "advotracker", policycheck_state = "init", import_data = ?e), } trace!(target: "advotracker", state = "parsing", policy_number = ?policy_number_string); @@ -284,7 +275,6 @@ impl PolicyCheckState { } } if policy_number_length < 10 { - //println!("Policy number is to short!"); let mut text_block_wrapper: TextBlockCtx<'_> = text_block(ctx.child("policy_check_result")); text_block_wrapper.set_enabled(true); let res = t!("policy.validation.to_short", lang); @@ -293,7 +283,6 @@ impl PolicyCheckState { //self.set_visibility(policy_check_policy_number, ctx); } if policy_number_length > 10 { - //println!("Policy number is to big!"); let mut text_block_wrapper: TextBlockCtx<'_> = text_block(ctx.child("policy_check_result")); text_block_wrapper.set_enabled(true); let res = t!("policy.validation.to_long", lang); @@ -306,12 +295,11 @@ impl PolicyCheckState { /// Remove a popup box showing the data import status in a progress bar fn remove_progress_popup(&mut self, ctx: &mut Context<'_>) { - text_block(ctx.child("policy_check_label_result")).set_visibility(Visibility::Collapsed); - //text_block(ctx.child("policy_check_label_result")).set_visibility(Visibility::Visible); - //if let progress_box = self.progress_box { - // ctx.remove_child(progress_box); - // println!("ProgressPopup removed !"); - //} + let progress_popup = self.progress_popup; + //let sleep = time::Duration::from_secs(3); + //thread::sleep(sleep); + ctx.remove_child(progress_popup); + println!("ProgressPopup {:?} removed !", progress_popup); } // /// If TextBox 'policy_check_policy_number' is empty, disable button "clear" @@ -347,20 +335,41 @@ impl PolicyCheckState { } - /// Set a popup box that updates the import status in a progress bar - fn set_progress_box(&mut self, ctx: &mut Context<'_>) { - //println!("Set up Progress box: {:?}", text_box); + /// Set a progress popup that updates the import status in a progress bar + fn set_progress_popup(&mut self, lang: &String, ctx: &mut Context<'_>) { + //println!("Set up Progress popup: {:?}", text_box); let stack = ctx .entity_of_child(ID_POLICY_CHECK_RESULT) .expect("PolicyCheckState.init: Can't find entity of resource 'ID_POLICY_CHECK_RESULT'."); let current_entity = ctx.entity; let build_context = &mut ctx.build_context(); - let progress_box = new_progress_box(current_entity, "Importing data ...", build_context); - // create a progress_box widget as a child of entity "ID_POLICY_CHECK_POLICY_NUMBER" - build_context.append_child(stack, progress_box); - self.progress_box = Some(progress_box); - println!("ProgressBox created: {:?}", Some(progress_box)); + let res = t!("policy.string.progress_text", lang); + let progress_popup = create_progress_popup(current_entity, &res, build_context); + + // create a progress_popup widget as a child of entity "ID_POLICY_CHECK_POLICY_NUMBER" + build_context.append_child(stack, progress_popup); + self.progress_popup = progress_popup; + + let progress_bar = ctx + .entity_of_child(ID_POLICY_CHECK_PROGRESS_BAR) + .expect("PolicyCheckState.init: Can't find entity of resource 'ID_POLICY_CHECK_PROGRESS_BAR'."); + self.progress_bar = progress_bar; + + println!("ProgressPopup created: {:?}", progress_popup); + } + + /// Change visibility of the result label. + fn _set_visibility(&self, entity: Entity, ctx: &mut Context<'_>) { + if ctx.get_widget(entity).get::("text").is_empty() { + text_block(ctx.child(ID_POLICY_CHECK_LABEL_RESULT)).set_visibility(Visibility::Collapsed); + text_block(ctx.child(ID_POLICY_CHECK_BUTTON_RESULT)).set_visibility(Visibility::Collapsed); + } else { + text_block(ctx.child(ID_POLICY_CHECK_LABEL_RESULT)).set_visibility(Visibility::Visible); + text_block(ctx.child(ID_POLICY_CHECK_BUTTON_RESULT)).set_visibility(Visibility::Visible); + } + + ctx.get_widget(self.label_result).update_theme_by_state(true); } /// Update count of elements in the policy data list. @@ -369,19 +378,13 @@ impl PolicyCheckState { ctx.widget().set(PROP_POLICY_DATA_COUNT, data_list_count); } - /// Change visibility of the result label. - fn _set_visibility(&self, entity: Entity, ctx: &mut Context<'_>) { - if ctx.get_widget(entity).get::("text").is_empty() { - text_block(ctx.child(ID_POLICY_CHECK_LABEL_RESULT)).set_visibility(Visibility::Collapsed); - text_block(ctx.child(ID_POLICY_CHECK_BUTTON_RESULT)).set_visibility(Visibility::Collapsed); - //ctx.get_widget(self.policy_check_label_policy_number).set("enabled", false); - } else { - text_block(ctx.child(ID_POLICY_CHECK_LABEL_RESULT)).set_text("Prüfungsergebnis:"); - text_block(ctx.child(ID_POLICY_CHECK_LABEL_RESULT)).set_visibility(Visibility::Visible); - text_block(ctx.child(ID_POLICY_CHECK_BUTTON_RESULT)).set_visibility(Visibility::Visible); - } + fn update_progress_bar(&self, lang: &String, ctx: &mut Context<'_>) { + let res = t!("policy.string.progress_time", lang); + let string_duration = format!("{}: {:?}", res, self.duration); + text_block(ctx.child(ID_POLICY_CHECK_PROGRESS_TIME)).set_text(string_duration); - ctx.get_widget(self.label_result).update_theme_by_state(true); + let mut progress_bar = ctx.child(ID_POLICY_CHECK_PROGRESS_BAR); + progress_bar.set::("val", self.progress_count); } } @@ -389,7 +392,7 @@ impl PolicyCheckState { impl State for PolicyCheckState { /// Initialize the widget state fn init(&mut self, _: &mut Registry, ctx: &mut Context<'_>) { - let dt_start: DateTime = Local::now(); + let time_start= SystemTime::now(); trace!(target: "advotracker", policycheck_state = "init", status = "started"); @@ -434,12 +437,6 @@ impl State for PolicyCheckState { text_block(ctx.child(ID_POLICY_CHECK_LABEL_RESULT)).set_text(string_label_result); text_block(ctx.child(ID_POLICY_CHECK_LABEL_RESULT)).set_visibility(Visibility::Collapsed); - let res = t!("policy.string.progress_text", lang); - let string_progress_text = format!("{}: {:?}", res, self.policy_numbers.len()); - //text_block(ctx.child(ID_POLICY_CHECK_PROGRESS_TEXT)).set_text(string_progress_text); - - let string_pro_text = format!("{}: {:?}", res, self.policy_numbers.len()); - // self.progress_popup = ctx // .entity_of_child(ID_POLICY_CHECK_PROGRESS_POPUP) // .expect("PolicyCheckState.init: Can't find entity of resource 'ID_POLICY_CHECK_PROGRESS_POPUP'."); @@ -460,14 +457,8 @@ impl State for PolicyCheckState { //policy_data_count = policy_data.len().clone; //self.update_data_count(ctx); - // Load data into hashmap - // match self.import_data(ctx) { - // Ok(()) => trace!(target: "advotracker", policycheck_state = "init", import_data = "success"), - // Err(e) => trace!(target: "advotracker", policycheck_state = "init", import_data = ?e), - //} - - let dt_end: DateTime = Local::now(); - let duration = dt_end.signed_duration_since(dt_start); + let time_end = SystemTime::now(); + let duration = time_end.duration_since(time_start); trace!(target: "advotracker", policycheck_state = "init", status = "finished", duration = ?duration); } @@ -502,31 +493,39 @@ impl State for PolicyCheckState { } Action::InputTextChanged(entity) => { println!("entry changed: {}", text_box(ctx.get_widget(entity)).text()); - //self.set_progress_box(ctx); - //self.set_check_button(policy_check_label_policy_number, ctx); - //self.set_visibility(entity, ctx); + } + Action::ImportData => { + let lang = "en".to_string(); + match self.import_data(&lang, ctx) { + Ok(()) => { + trace!(target: "advotracker", import_data = "success"); + } + _ => { + error!("Importing data failed!"); + trace!(target: "advotracker", import_data = "failed"); + } + } } Action::OpenMenu(text_block) => { self.open_menu(text_block, ctx); } Action::ParseEntry(text_box) => { - //println!("set_progress_box: {:#?}", text_box); - //self.set_progress_box(ctx); self.parse_entry(text_box, ctx); - //ctx.get_widget(text_box).get::("text").as_string(); - //self.parse_entry(text_box, &mut policy_numbers, - // &lang, ctx); } Action::RemoveFocus(policy_check_policy_number) => { ctx.get_widget(policy_check_policy_number).set("enabled", false); ctx.push_event_by_window(FocusEvent::RemoveFocus(policy_check_policy_number)); } - Action::RemoveProgressBox(_entity) => { - self.remove_progress_box(ctx); + Action::RemoveProgressPopup(_entity) => { + self.remove_progress_popup(ctx); } Action::ResetProgress => { progress_bar(ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)).set_val(0.); } + Action::SetEntry(policy_check_policy_number) => { + //self.last_focused = Some(); + self.set_entry(policy_check_policy_number, ctx); + } Action::SetProgress(value) => { if value >= 0. || value <= 1. { progress_bar(ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)).set_val(value); @@ -534,20 +533,11 @@ impl State for PolicyCheckState { progress_bar(ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)).set_val(0.); } } - Action::SetProgressBox(_entity) => { - //println!("set_progress_box: {:#?}", ctx.widget().get::("water_mark")); - //println!("set_progress_box: {:#?}", entity); - self.set_progress_box(ctx); - //let text = text_box(ctx.child(ID_POLICY_CHECK_POLICY_NUMBER)); - } - Action::SetEntry(policy_check_policy_number) => { - //self.last_focused = Some(); - self.set_entry(policy_check_policy_number, ctx); + Action::SetProgressPopup(_entity) => { + let lang = "en".to_string(); + self.set_progress_popup(&lang, ctx); } Action::SetVisibility(_entity) => { - //text_block(ctx.child(entity).set_visibility(Visibility::Visible)); - //println!("Entity: {:?}", entity); - //text_block(ctx.child(entity).set_visibility(Visibility::Collapsed)); text_block(ctx.child(ID_POLICY_CHECK_LABEL_RESULT)).set_visibility(Visibility::Collapsed); } Action::TextChanged(entity, _index) => { @@ -578,44 +568,58 @@ impl State for PolicyCheckState { } } -fn new_progress_popup(target: Entity, text: &str, ctx: &mut BuildContext<'_>) -> Entity { - Popup::new() - .id(ID_POLICY_CHECK_PROGRESS_POPUP) - .target(target) - .open(true) - .width(280.0) - .height(100.0) - .child( - Container::new() - .background("transparent") - .border_radius(3.) - .border_width(2.) - //.border_brush("#000000") - .padding(16.) - .child( Stack::new() - .h_align("center") - .margin((16., 16., 16., 16.)) - .spacing(16.) - // default: .orientation("vertical") - .child( - TextBlock::new() - .id(ID_POLICY_CHECK_PROGRESS_TEXT) - .h_align("center") - .v_align("top") - //.foreground("#000000") - .text(text) - .build(ctx) - ) - .child( - ProgressBar::new() - .id(ID_POLICY_CHECK_PROGRESS_BAR) - .val(0.) - .width(250.) - .build(ctx) - ) + /// Create a progress popup with update status of an onging data import + fn create_progress_popup(popup: Entity, text: &str, ctx: &mut BuildContext<'_>) -> Entity { + Popup::new() + .id(ID_POLICY_CHECK_PROGRESS_POPUP) + .target(popup) + .open(true) + .width(280.0) + .height(140.0) + .h_align("left") + .on_mouse_down(move |ctx, _| { + println!("on_click -> remove_progress_popup()"); + ctx.get_mut::(popup) + .action(Action::RemoveProgressPopup(popup)); + true + }) + .child( + Container::new() + //.background("transparent") + .border_radius(3.) + .border_width(2.) + .padding(16.) + .child( Stack::new() + .h_align("center") + .margin((16., 16., 16., 16.)) + .spacing(16.) + // default: .orientation("vertical") + .child( + TextBlock::new() + .id(ID_POLICY_CHECK_PROGRESS_TEXT) + .h_align("center") + .v_align("top") + .text(text) + .build(ctx) + ) + .child( + ProgressBar::new() + .id(ID_POLICY_CHECK_PROGRESS_BAR) + .val(0.) + .width(250.) + .build(ctx) + ) + .child( + TextBlock::new() + .id(ID_POLICY_CHECK_PROGRESS_TIME) + .h_align("end") + .v_align("bottom") + //.text() + .build(ctx) + ) + .build(ctx) + ) .build(ctx) - ) - .build(ctx) - ) - .build(ctx) -} + ) + .build(ctx) + }