callbacks: policycheck_state refine popup widget handling

* on first access, show a processing popup
* calculate the processing time
* update process status
* show processing time in popup

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
2020-07-15 00:09:39 +02:00
parent ffa8c18efb
commit fd61f90277

View File

@@ -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<Action>,
duration: Duration,
label_result: Entity,
last_focused: Option<Entity>,
menu_button: Entity,
//policy_check_clean_button: Entity,
//policy_check: PolicyCheck,
policy_data_count: usize,
//policy_number_text_box: Entity,
policy_numbers: HashMap<usize, PolicyCode>,
progress_box: Option<Entity>
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<dyn std::error::Error>> {
pub fn create_hashmap(&mut self, _ctx: &mut Context<'_>) -> Result<(), Box<dyn std::error::Error>> {
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<dyn std::error::Error>> {
// 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::<String16>("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::<String16>("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::<f64>("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> = 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> = 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::<String16>("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::<String16>("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::<PolicyCheckState>(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)
}