46 Commits

Author SHA1 Message Date
9fc4c6c01d widget:global_state: remove usage of navigate
* this needs to be adopted to use event handler code

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-06 15:20:30 +01:00
9ef2e3816e examples: initial version of messages_test
* destinct sender and receiver  widgets
* update PopupBox in receiver view, if send button on sender view
  is pressed
* sending of inserted message text of sender view is initiated, if
  you hit 'Ctrl+S' inside the text box. Text block in receiver view
  is updated with sending Text

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-06 00:37:32 +01:00
3162233c85 widget:ticketdata: prepare mail_cc or mail_to change handling
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-05 20:58:06 +01:00
30131ecdb1 ticketdata: code cleanup 2021-03-04 20:24:21 +01:00
6d9d82bb8e advotracker: updated localization strings and constants
* update due to customer request
* constants
* translation strings
* disable WIP menu widget
* labels used in Email submission

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-04 17:13:28 +01:00
5e390a8cfa main_view: disable wip menu widget
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-04 08:09:51 +01:00
8630ee1c12 Cargo.toml: bump version to 0.1.5
* include dependency to crate lettre
* include depenency to crate maud
* this version initially supports ticketdata dialo
* data can be send via Email

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-04 07:07:01 +01:00
791b451d39 main: handle test_policy_number
* provide cli-flag `testPolicyNumber` as String
  since viperus doesnt support u64
* handle stringconversion (String -> u64) inside main

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-04 07:07:01 +01:00
aeaafd8c57 widget:ticketdata: function extention to handle Email sending
* remap to use `policy code`
* adapt the constants
* start with clear_form()
* use service 'send_ticketdata' which crate lettre
* enable smtp authorization via credentilas
* support html using crate 'maud'
* provide the needed structures
* update the constants for property and entity assigns
* include send Email service (sendticketdata)
* send_ticketdata: include html  maud modules

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-04 07:06:03 +01:00
1af299dc01 widget:policycheck: map to ID_POLICY_CHECK_POLICY_CODE
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 22:35:20 +01:00
bd6971d4d0 .gitmodules: update dead module path
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 16:32:33 +01:00
85fb4ceb16 advotracker-db: update to head
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 16:32:21 +01:00
a451b58ab4 widget:menu: deactivate requirement for new popup_code
* since new popup code is just in PR #304, do not rely on its availibility

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 11:53:17 +01:00
b96c3c510f widgets:main_view: update widget activation handling
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 11:51:50 +01:00
2c903c67dd data:constants: update widget id's identifier
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 11:50:33 +01:00
a40f6e94dd widget:global_state: activate navigate() method
* allow widgets to nagivate to other widget context

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 11:48:16 +01:00
8af49deb34 widget:ticketdata: introduce message passing
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 11:47:26 +01:00
202ba81b4f widget:policycheck: introduce message passing
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 11:46:39 +01:00
43db004179 examples: move csv-test
* test validity of a given policy number
* cli program will match via  hashmap
* hashmap is constructed from a csv file

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 00:38:10 +01:00
3b65dafbec examples: introduce messages_test
* showcase demenstrating messages passing from a sender (widget1)
  to a receiver (widget 2)
* use modular source tree structure

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-03 00:33:26 +01:00
23732350ca policycheck: refine header bar
* place tenent logo at upper right
* adapt header text placement

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 20:15:31 +01:00
3c40055e2e theming: update default_dark
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:25 +01:00
6a61d2f878 policycheck: functionality cleanup
* sorting
* string usage

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:25 +01:00
044ad84598 services: allianzdireectcall update
* rust update using &str instead of &String

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:25 +01:00
b2a9d9aa52 widget/configuration: typo and documentation update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
157da4228a include substring handling
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
26cf43bfae ticketdata: introduce new widget
* Cargo.toml: introduce carte `lettre` used in send_ticketdata.rs
* locales: extend translations
* theme: extend translations
* send_ticketdata: send harm data via email
* ticket_data: aquisition of harm data
* update constant usage

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
a2314d4909 envy: update .env
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
0dab2dddb3 csv-test: typo update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>

csv-test: update

* move to subdir `examples`
* typo update

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
bb40033554 parse_args: typo update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
a4a09bc37c data/structures: typo update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
9fba66d8a6 widget/configuration: styling update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
7d6476205f Cargo.toml: include crate if_cfg
* use macro to compile os-dependent features

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:24 +01:00
41ebf4168a widgets/configuration: reference styling to theme handling
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
c4caf12706 widget/policycheck: update logic
* remove handling of the menu logic (isolated in dedicated widget)
* reference styling via theme
* update documentation strings

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
075505eec9 widgets/menu: introduce dedicated module menu
* new menu_view
* new menu_state
* update constants
* update main_view referencing a tab_view

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
59e7e71143 assets: update theme definitions for default_dark.ron
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
7440f7a6dd widgets/menu: introduce dedicated menu module
* new menu_view
* new menu_state
* adapt constant values for the menu structure

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
a401379f9e theme update dark
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
be9b8b1a1c widget/configuration: correcting label constant
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
70bd6b8b8d language: update
* update constants
* adopt width of languages combo box

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
1f3c6a7fff widget/policycheck: intoduce os dependent theme handling
* theme_fluent: only makes sense in windows environment

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:23 +01:00
ef26a3bf65 widgets/localization: update label constant
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:22 +01:00
fa4914839e assets: adapt default_dark theme definitions
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:46:18 +01:00
571243731d assets: adapt fluent_dark theme definitions
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:45:57 +01:00
b38a677b7b policycheck: function update
* insert copyright hint
* more descriptive import of allianzdirectcall function
* documentation update
* introduce KeyHandler in menu popup
* rename action function to `set_action`

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:45:33 +01:00
46 changed files with 2398 additions and 813 deletions

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "backend"]
path = backend
url = ./backend/
[submodule "advotracker-db"] [submodule "advotracker-db"]
path = advotracker-db path = advotracker-db
url = https://gitea.networkx.de:50443/rzerres/advotracker-db url = https://gitea.networkx.de:50443/rzerres/advotracker-db

View File

@@ -3,13 +3,14 @@
# will overwrite standard environment viariables # will overwrite standard environment viariables
### ###
# set the language variable used in test-runs # set the language variable used in test-runs
#test LANG=de-DE
#test LANG=es-ES #test LANG=es-ES
#test LANG=it-IT
#test LANG=C #test LANG=C
# set the language variable (overwriting standard Enviroment) # set the language variable (overwriting standard Enviroment)
#TEST_LANG=de_DE #TEST_LANG=de_DE
#TEST_LANG=C #TEST_LANG=C
#RUST_LOG=advotracker=trace #RUST_LOG=advotracker=trace
#LANG=de_DE
RUST_LOG=trace RUST_LOG=trace
#RUST_LOG=none #RUST_LOG=none
USERNAME=hiedemann USERNAME=hiedemann

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "advotracker" name = "advotracker"
version = "0.1.4" version = "0.1.5"
authors = ["Ralf Zerres <ralf.zerres@networkx.de>"] authors = ["Ralf Zerres <ralf.zerres@networkx.de>"]
description = "Frontend component that supports lawyers to capture relevant data encountered during an online legal advice." description = "Frontend component that supports lawyers to capture relevant data encountered during an online legal advice."
readme = "README.md" readme = "README.md"
@@ -19,24 +19,29 @@ winapi = { version = "0.3", features = ["winuser"] }
[dependencies] [dependencies]
async-stream = "~0.2" async-stream = "~0.2"
chrono = { version = "~0.4.0", features = ["serde"] } chrono = { version = "~0.4.0", features = ["serde"] }
cfg-if = { version = "~1.0" }
clap = { version = "~2.33", features = ["suggestions", "color"] } clap = { version = "~2.33", features = ["suggestions", "color"] }
csv = { version = "~1.1" } csv = { version = "~1.1" }
dotenv = { version = "~0.15.0" } dotenv = { version = "~0.15.0" }
envy = { version = "~0.4" } envy = { version = "~0.4" }
lettre = "0.10.0-beta.1"
lazy_static = { version = "~1.4.0" } lazy_static = { version = "~1.4.0" }
log = { version = "~0.4.8" } log = { version = "~0.4.8" }
locales = { version = "~0.1" } locales = { version = "~0.1" }
maud = { version = "~0.22.1" }
#orbtk = { version = "~0.3.1-alpha4" } #orbtk = { version = "~0.3.1-alpha4" }
orbtk = { git = "https://github.com/redox-os/orbtk.git", branch = "develop" } #orbtk = { git = "https://github.com/redox-os/orbtk.git", branch = "develop" }
#orbtk = { path = "../../orbtk" } orbtk = { path = "../../orbtk" }
serde = { version = "~1.0", features = ["derive"] } serde = { version = "~1.0", features = ["derive"] }
substring = { version = "~1" }
#tokio = { version = "~0.2", features = ["macros", "rt-threaded", "stream", "time"] } #tokio = { version = "~0.2", features = ["macros", "rt-threaded", "stream", "time"] }
tracing = { version = "~0.1" } tracing = { version = "~0.1" }
tracing-subscriber = { version = "~0.2.0", features = ["tracing-log"] } tracing-subscriber = { version = "~0.2.0", features = ["tracing-log"] }
viperus = { git = "https://github.com/maurocordioli/viperus", features = ["cache", "fmt-clap", "fmt-env", "global", "watch"] } viperus = { git = "https://github.com/maurocordioli/viperus", features = ["cache", "fmt-clap", "fmt-env", "global", "watch"] }
[dev-dependencies]
[features] [features]
# no features by default
default = [] default = []
debug = ["orbtk/debug"] debug = ["orbtk/debug"]
light = [] light = []
@@ -46,3 +51,18 @@ name = "advotracker"
identifier = "nwx.advotracker" identifier = "nwx.advotracker"
short_description = "Online legal advice helper." short_description = "Online legal advice helper."
description = "Supports lawyers to capture relevant data encountered during an online legal advice.\n" description = "Supports lawyers to capture relevant data encountered during an online legal advice.\n"
[profile.dev]
opt-level = 1
incremental = true
[profile.release]
incremental = true
#[[bin]]
#//name = "policycheck"
#path = "src/bin/policycheck.rs"
[[bin]]
name = "advotracker"
path = "src/main.rs"

View File

@@ -10,37 +10,50 @@ Dictionary (
// the map of active identifiers // the map of active identifiers
// like a struct, but keys are also values instead of just beenig identifiers // like a struct, but keys are also values instead of just beenig identifiers
words: { words: {
// policycheck_view // policycheck_view
"Validation policy number": "Prüfung Versicherungsnummer", "Validation policy number": "Prüfung Versicherungsnummer",
"Policy number": "Versicherungsnummer", "Policy number": "Versicherungsnummer",
"Policy code": "ID der Vers.-Nummer", "Policy code": "Vers.-Schein/Schadennummer",
"Checklist elements: ": "Prüflistenelemente: ", "Policy holder": "Versicherungsnehmer",
"Check result": "Prüfungsergebnis", "Checklist elements: ": "Prüflistenelemente: ",
"Importing data": "Importiere Datensätze", "Check result": "Prüfungsergebnis",
"Processing time": "Bearbeitungszeit", "Importing data": "Importiere Datensätze",
"Error:": "Fehler:", "Processing time": "Bearbeitungszeit",
"Reason": "Grund", "Error:": "Fehler:",
"Policy number is to long": "Die Nummer ist zu lang", "Reason": "Grund",
"Policy number is to short": "Die Nummer ist zu kurz", "Policy number is to long": "Die Nummer ist zu lang",
"The given policy number is invalid": "Die Versicherungsnummer ist ungültig", "Policy number is to short": "Die Nummer ist zu kurz",
"The given policy number is valid": "Die Versicherungsnummer ist gültig", "The given policy number is invalid": "Die Versicherungsnummer ist ungültig",
"Only numbers are valid": "Nur Nummern sind zulässig", "The given policy number is valid": "Die Versicherungsnummer ist gültig",
"Account": "Benutzer", "Only numbers are valid": "Nur Nummern sind zulässig",
"Toggle theme": "Thema wechseln", "Account": "Benutzer",
"Quit": "Beenden", "Toggle theme": "Thema wechseln",
"Quit": "Beenden",
// localization view // ticketdata_view
"Language ID": "Sprache ID", "Callback number": "Rückrufnummer",
"Localization dialog": "Lokalisierungs-Dialog", "Callback date": "Erreichbarkeit",
"German": "Deutsch", "Clear": "Zurücksetzen",
"English": "Englisch", "Deductible": "Selbstbehalt",
"Harm type": "Rechtsproblem",
"IVR comment": "Rechtsrat",
"Policy holder": "Versicherungsnehmer",
"Recipient (To)": "Empfänger (To)",
"Copie (CC)": "Kopie (CC)",
"Send": "Senden",
// configuration view // localization view
"Configuration settings": "Konfigurationseinstellungen", "Language ID": "Sprache ID",
"Configuration file": "Konfigurationsdatei", "Localization dialog": "Lokalisierungs-Dialog",
"Language Id": "Sprach-Id", "German": "Deutsch",
"Default theme": "Standard-Thema", "English": "Englisch",
"load": "laden",
"save": "speichern" // configuration view
"Configuration settings": "Konfigurationseinstellungen",
"Configuration file": "Konfigurationsdatei",
"Language Id": "Sprach-Id",
"Default theme": "Standard-Thema",
"Load": "Laden",
"Save": "Speichern",
} }
) )

View File

@@ -1,54 +1,187 @@
Theme ( Theme (
styles: { styles: {
"button_menu": ( "button_action": (
base: "button", base: "button",
properties: { properties: {
"padding": 4, //"background": "transparent",
"border_radius": 0, "border_radius": 3,
}, "h_align": "center",
), "v_align": "center",
"container_form": ( },
base: "container", ),
properties: { "button_menu": (
"padding": 14, base: "button_single_content",
"border_width": 1, properties: {
"border_radius": 0, "h_align": "end",
"border_brush": "$CONTAINER_BORDER", //"icon": "material_icons_font::MD_MENU",
}, },
), ),
"configuration_form": ( "combo_box_form": (
base: "container", base: "combo_box",
properties: { properties: {
"margin": 4, "width": 200,
}, "height": 28,
), },
"container_progress": ( ),
base: "container", "mail_label": (
properties: { base: "base",
"padding": 14, properties: {
//"border_width": 1, "h_align": "end",
//"border_radius": 0, "v_align": "center",
"border_brush": "$CONTAINER_BORDER", },
}, ),
), "mail_to": (
"popup_progress": ( base: "combo_box_form",
base: "popup", properties: {
properties: { "h_align": "end",
//"background": "$BACKGROUND", },
"padding": 4, ),
}, "mail_cc": (
), base: "combo_box_form",
"text_block_progress": ( properties: {
base: "small_text", "h_align": "end",
properties: { },
"background": "$PROGRESS_BAR_BACKGROUND", ),
}, "combo_box_popup": (
), //base: "popup",
"stack_progress": ( properties: {
base: "container", //"height": 120,
properties: { "width": 240,
"spacing": 10, },
}, ),
), "configuration_form": (
base: "container",
properties: {
"margin": 4,
},
),
"container_action": (
base: "container_form",
properties: {
"border_width": 1,
"padding": {
"left": 14,
"top": 0,
"right": 14,
"bottom": 0,
},
"h_align": "center",
},
),
"container_form": (
base: "container",
properties: {
"padding": 14,
"border_brush": "$CONTAINER_BORDER",
"border_radius": 0,
"border_width": 1,
"min_height": 330,
},
),
"container_mail": (
base: "container_form",
properties: {
"border_width": 0,
"padding": {
"left": 14,
"top": 0,
"right": 14,
"bottom": 14,
}
},
),
"container_progress": (
base: "container",
properties: {
"border_brush": "$CONTAINER_BORDER",
"h_align": "center",
"padding": 14,
"v_align": "center",
},
),
"header_bar": (
base: "header",
properties: {
//"h_align": "center",
//"v_align": "center",
"min_height": 32,
//"padding": 14,
}
),
"header_text": (
base: "header",
properties: {
"h_align": "center",
"v_align": "center",
}
),
"popup_form": (
//base: "popup",
properties: {
"background": "#FFFFFF",
"border_brush": "#0000FF",
"border_radius": 3,
"border_width": 2,
"padding": 4,
},
),
"popup_menu": (
//base: "popup",
properties: {
"width": 300,
"hight": 200,
"border_radius": 0,
"border_width": 1,
"h_align": "center",
},
),
"popup_progress": (
base: "popup",
properties: {
"padding": 4,
},
),
"stack_action": (
//base: "stack",
properties: {
//"min_height": 50,
"orientation": "Horizontal",
"spacing": 50,
},
),
"stack_progress": (
base: "container",
properties: {
"spacing": 10,
},
),
"ticket_data_form_label": (
base: "container_form",
properties: {
"padding": 1,
"h_align": "end",
"v_align": "center",
"margin": {
"left": 0,
"top": 0,
"right": 0,
"bottom": 0,
},
"min_size": 300,
"max_size": 400,
},
),
"ticket_data_form_input": (
base: "ticket_data_form_label",
properties: {
"h_align": "start",
},
),
"text_block_progress": (
base: "small_text",
properties: {
"background": "$PROGRESS_BAR_BACKGROUND",
},
),
} }
) )

View File

@@ -0,0 +1 @@
../../../data/POLLFNR_WOECHENTLICH.txt

View File

@@ -9,9 +9,12 @@ use chrono::{Local, DateTime};
use locales::t; use locales::t;
//use serde::{Deserialize, Serialize}; //use serde::{Deserialize, Serialize};
use serde::Deserialize; use serde::Deserialize;
use std::env; use std::{
use std::{error::Error, process}; collections::HashMap,
use std::collections::HashMap; env,
{error::Error, process},
//path::{Path, PathBuf},
};
use tracing::{debug, trace, Level}; use tracing::{debug, trace, Level};
use advotracker::data::structures::{PolicyCode, PolicyList, PolicyDataList, PolicyData}; use advotracker::data::structures::{PolicyCode, PolicyList, PolicyDataList, PolicyData};
@@ -49,14 +52,6 @@ fn export(p: &mut String, lang: &String) -> Result<u64, Box<dyn Error>> {
// Note: slash syntax also works on Windows! // Note: slash syntax also works on Windows!
let path = Path::new(p); let path = Path::new(p);
// only create files with a '.txt' extensions
//let extension = path.extension();
// match extension {
// //Some(String) => println!("file extension ok!"),
// //_ => extension = OsStr::new("txt")
// _ => println!("got file extension {:?}", extension)
// };
// open the file descriptor // open the file descriptor
let mut file = File::create(path)?; let mut file = File::create(path)?;
trace!(target: "csv-export", extension = ?path.extension(), file = ?file); trace!(target: "csv-export", extension = ?path.extension(), file = ?file);
@@ -103,10 +98,6 @@ fn import(p: &mut String, data_list: &mut PolicyDataList,
// must be a readable file // must be a readable file
trace!(target: "csv-test", path = ?path); trace!(target: "csv-test", path = ?path);
let valid = path.is_file();
println!("is_file: {}", valid);
//if let Some(res) = valid
assert_eq!(path.is_file(), true); assert_eq!(path.is_file(), true);
// only accept files with '.txt' extensions // only accept files with '.txt' extensions
@@ -333,8 +324,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
state = t!("state.started", lang); state = t!("state.started", lang);
trace!(target: "csv-test", process = ?res, state = ?state); trace!(target: "csv-test", process = ?res, state = ?state);
// importing policy code elements from csv-file // create policy structures
let policy_list = PolicyList::new("Allianz Versicherungsnummen-List"); let policy_list = PolicyList::new("Allianz Versicherungsnummen-Liste");
println!("Policy List {:?} ", policy_list.name); println!("Policy List {:?} ", policy_list.name);
let mut policy_data = PolicyDataList::new("Allianz-Import 20200628"); let mut policy_data = PolicyDataList::new("Allianz-Import 20200628");
@@ -355,9 +346,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
// test if policy_number is_valid // test if policy_number is_valid
let test_policy_number = v.get::<i32>("test_policy_number").unwrap() as u64; // type conversion (viperus String -> u64)
let test_policy_number = v.get::<String>("test_policy_number").unwrap().parse::<u64>().unwrap();
trace!(target: "csv-test", test_policy_number = ?test_policy_number); trace!(target: "csv-test", test_policy_number = ?test_policy_number);
//let policy_number : u64 = 1999999999;
//match is_valid(&policy_number, &policy_data, &mut policy_numbers, &lang) { //match is_valid(&policy_number, &policy_data, &mut policy_numbers, &lang) {
// Ok(true) => { // Ok(true) => {
// use Hashmap method 'get' to check if we have the given key // use Hashmap method 'get' to check if we have the given key
@@ -394,3 +385,25 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(()) Ok(())
} }
#[test]
fn test_policy_number() {
// Takes a reference and returns Option<&V>
let my_policy_numbers : [u64; 2] = [1511111111, 9999999993];
assert_eq!(my_policy_numbers, [1511111111, 9999999993]);
//let mut csv_import_path = v.get::<String>("import_file").unwrap();
let mut csv_import_path = String::from("data/POLLFNR_TEST.txt");
let mut policy_data = PolicyDataList::new("PolicyDataList");
let mut policy_numbers : HashMap<u64, PolicyCode> = HashMap::new();
let lang = "en".to_string();
println!("import with Path: {:?} PolicyData: {:?} PolicyNumbers: {:?}, Lang: {:?}",
csv_import_path, policy_data, policy_numbers, lang);
let count = import(&mut csv_import_path, &mut policy_data,
&mut policy_numbers, &lang);
assert_eq!(count.unwrap(), 15498);
}

View File

@@ -25,7 +25,7 @@ pub fn parse_args(v: &mut Viperus) -> Result<(), Box<dyn std::error::Error>> {
v.add_default("config_file", String::from("csv_import.ron")); v.add_default("config_file", String::from("csv_import.ron"));
v.add_default("import_file", String::from("POLLFNR_WOECHENTLICH.txt")); v.add_default("import_file", String::from("POLLFNR_WOECHENTLICH.txt"));
v.add_default("export_file", String::from("")); v.add_default("export_file", String::from(""));
v.add_default("test_policy_number", 123456789); v.add_default("test_policy_number", String::from("9999999992"));
v.add_default("to_email_address_file", String::from("Allianz RA-Hotline <smr-rahotline@allianz.de>")); v.add_default("to_email_address_file", String::from("Allianz RA-Hotline <smr-rahotline@allianz.de>"));
v.add_default("from_email_address_file", String::from("Allianz-Hotline RA-Hiedemann <azhotline@hiedemann.de>")); v.add_default("from_email_address_file", String::from("Allianz-Hotline RA-Hiedemann <azhotline@hiedemann.de>"));
//v.add_default("username", String::from("nctalkbot")); //v.add_default("username", String::from("nctalkbot"));
@@ -188,7 +188,7 @@ SMR Unerledigt: 089 92529 60222")
); );
println!( println!(
"test_policy_number: {:?}", "test_policy_number: {:?}",
v.get::<i32>("test_policy_number").unwrap_or_default() v.get::<String>("test_policy_number").unwrap_or_default()
); );
// println!( // println!(
// "username: {:?}", // "username: {:?}",

View File

@@ -0,0 +1,33 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
mod data;
mod main_view;
mod receiver;
mod sender;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// use this only if you want to run it as web application.
orbtk::initialize();
Application::new()
.window(|ctx| {
Window::new()
.name("Main")
.title("OrbTK: example send/receive messages")
.position((100.0, 100.0))
.resizeable(true)
.size(450.0, 500.0)
.child(main_view::MainView::new().build(ctx))
.build(ctx)
})
.run();
Ok(())
}

View File

@@ -0,0 +1,38 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
use crate::{
receiver::receiver_view::ReceiverView,
sender::sender_view::SenderView,
};
widget!(MainView {
//sender_view: ,
//receiver_view:
});
impl Template for MainView {
fn template(self, _id: Entity, ctx: &mut BuildContext<'_>) -> Self {
let receiver_view = ReceiverView::new()
.build(ctx);
let sender_view = SenderView::new()
.target(receiver_view.0) // entity of the target
.build(ctx);
self.name("MainView")
.child(
Stack::new()
.orientation("vertical")
.child(sender_view)
.child(receiver_view)
.build(ctx)
)
}
}

View File

@@ -0,0 +1,8 @@
// The starting point (Main View).
pub mod main_view;
/// Receiver widget
pub mod receiver;
/// Sender widget.
pub mod sender;

View File

@@ -0,0 +1,5 @@
/// The reciever state
pub mod receiver_state;
/// The receiver view
pub mod receiver_view;

View File

@@ -0,0 +1,86 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
use crate::{
data::constants::*,
sender::sender_state::SenderAction,
};
// /// Enumeration of valid `action variants` that need to be handled as
/// state changes for the `SenderView` widget.
pub enum TestMessageAction {
// Toggle visibility of a message TextBlock.
ToggleMessageBlock
}
/// Valid `structure members` of the `ReceiverState` used to react on
/// state changes inside the `ReceiverView` widget.
#[derive(Default, AsAny)]
pub struct ReceiverState {
message_block: Option<Entity>,
progress_bar: Entity
}
/// Method definitions, we provide inside the `ReceiverState`.
impl ReceiverState {
fn toggle_message_block(&self, ctx: &mut Context) {
if let Some(message_block) = self.message_block {
ctx.get_widget(message_block)
.set("visibility", Visibility::Visible);
}
}
}
/// Trait methods provided for the `ReceiverState`
impl State for ReceiverState {
// initialize the view entities
fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.progress_bar = ctx
.entity_of_child(ID_RECEIVER_PROGRESS_BAR)
.expect("Cannot find ProgressBar!");
//self.message_box = ctx
// .entity_of_child(ID_RECEIVER_MESSAGE)
// .expect("Cannot find 'ID_RECEIVER_MESSAGE'!");
}
// handle messages targeting the view
fn messages(
&mut self,
mut messages: MessageReader,
_registry: &mut Registry,
ctx: &mut Context
) {
for message in messages.read::<SenderAction>() {
match message {
SenderAction::UpdateProgress(amount) => {
println!("UpdateProgress message received");
let mut progress_bar = ctx.get_widget(self.progress_bar);
let current_progress = progress_bar.clone::<f64>("val");
progress_bar.set::<f64>("val", current_progress + amount);
}
SenderAction::UpdateMessage(message) => {
println!("UpdateMessage message received");
//Reciever::text_set(&mut ctx.widget(), self.message.to_string());
//Reciever::text_set(&mut ctx.widget(), self.message.to_string());
TextBlock::text_set(&mut ctx.child(ID_RECEIVER_MESSAGE_BLOCK), String::from(message));
}
}
}
for action in messages.read::<TestMessageAction>() {
match action {
TestMessageAction::ToggleMessageBlock => {
self.toggle_message_block(ctx);
}
}
}
}
}

View File

@@ -0,0 +1,56 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
use crate::{
data::constants::*,
//receiver::receiver_state::{TestMessageAction, ReceiverState},
receiver::receiver_state::ReceiverState,
};
widget!(ReceiverView<ReceiverState>);
impl Template for ReceiverView {
fn template(self, _id: Entity, build_context: &mut BuildContext) -> Self {
self.id(ID_RECEIVER)
.name(ID_RECEIVER)
.child(
Container::new()
.id(ID_RECEIVER_CONTAINER)
.border_brush(COLOR_BOMBAY)
.border_width(2)
.name(ID_RECEIVER_CONTAINER)
.padding(16)
.child(
Stack::new()
.orientation("vertical")
.spacing(8)
.child(
TextBlock::new()
.id(ID_RECEIVER_TEXT_BLOCK)
.text(ID_RECEIVER)
.build(build_context)
)
.child(
ProgressBar::new()
.id(ID_RECEIVER_PROGRESS_BAR)
.build(build_context)
)
.child(
TextBlock::new()
.id(ID_RECEIVER_MESSAGE_BLOCK)
.text("")
.water_mark("here we expect the message updates.")
.build(build_context)
)
.build(build_context)
)
.build(build_context)
)
}
}

View File

@@ -0,0 +1,5 @@
/// The sender state
pub mod sender_state;
/// The sender view
pub mod sender_view;

View File

@@ -0,0 +1,78 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
//use crate::data::constants::*;
/// Enumeration of valid `action variants` that need to be handled as
/// state changes for the `SenderView` widget.
#[derive(Clone, Debug)]
pub enum SenderAction {
UpdateProgress(f64),
UpdateMessage(String),
}
/// Valid `structure members` of the `SenderState` used to react on
/// state changes inside the `SenderView` widget.
#[derive(AsAny, Default)]
pub struct SenderState {
// actions
actions: Vec<SenderAction>,
// entity that will receive the message
target: Entity
}
/// Method definitions, we provide inside the `SenderState`.
impl SenderState {
/// Sending message with type 'UpdateProgress'
pub fn send_update_progress(&mut self) {
println!("Sender: push 'UpdateProgress' action");
self.actions.push(SenderAction::UpdateProgress(0.1));
}
/// Sending message with type 'UpdateMessage'
pub fn send_update_message(&mut self) {
println!("Sender: push 'UpdateMessage' action");
self.actions.push(SenderAction::UpdateMessage(String::from("Hey sender. I got your message. All fine.")));
}
}
/// Trait methods provided for the `SenderState`
impl State for SenderState {
// initialize the view entities
fn init(&mut self, _registry: &mut Registry, ctx: &mut Context) {
// create the target entity, that receives the Sender messages
self.target = Entity::from(ctx.widget().try_clone::<u32>("target")
.expect("ERROR: SenderState::init(): target entity not found!"));
}
// update entities, before we render the view
fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
let actions: Vec<SenderAction> = self.actions.drain(..).collect();
//let message = ctx.child(ID_SENDER_TEXT_BOX).get::<String>("text").to_string();
//println!("Child text: {:?}", message);
// create an explicit message_adapter context
let message_adapter = ctx.message_adapter();
for action in actions {
match action {
SenderAction::UpdateProgress(amount) => {
message_adapter.send_message(SenderAction::UpdateProgress(amount), self.target);
println!("Sender: send message 'SenderAction::UpdateProgress'");
}
SenderAction::UpdateMessage(message) => {
//let message = ctx.child(ID_SENDER_TEXT_BOX).get::<String>("text").to_string();
message_adapter.send_message(SenderAction::UpdateMessage(message), self.target);
println!("Sender: send message 'SenderAction::UpdateMessage'");
}
}
}
}
}

View File

@@ -0,0 +1,100 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::{
prelude::*,
shell::event::Key,
};
use crate::{
data::constants::*,
sender::sender_state::SenderState,
//sender::sender_state::{SenderAction, SenderState},
};
widget!(SenderView<SenderState> {
// the Entity of the widget that will receive the messages
target: u32
});
impl Template for SenderView {
fn template(self, id: Entity, build_context: &mut BuildContext) -> Self {
let sender_header = TextBlock::new()
.attach(Grid::row(0))
.text(ID_SENDER)
.build(build_context);
let sender_message = TextBox::new()
.attach(Grid::row(2))
.attach(Grid::column(0))
.name(ID_SENDER_TEXT_BOX)
.text("")
.water_mark("Message text to be send via MessageHandler.")
.on_key_down(move | states, key_event | {
match key_event.key {
Key::Tab | Key::S(..) => {
println!("KeyHandler: got Tab");
states.get_mut::<SenderState>(id).send_update_progress();
states.get_mut::<SenderState>(id).send_update_message();
},
_ => {
println!("KeyHandler: got {:?}", key_event.key);
},
};
true
})
.build(build_context);
let sender_button = Button::new()
.attach(Grid::row(2))
.attach(Grid::column(2))
.name(ID_SENDER_BUTTON)
.text("send")
.icon(material_icons_font::MD_SEND)
.on_click(move |states, _entity| {
states.get_mut::<SenderState>(id).send_update_progress();
false
})
.build(build_context);
//let sender_content =
self.id(ID_SENDER)
.name(ID_SENDER)
.child(
Container::new()
.id(ID_SENDER_CONTAINER)
.border_brush(COLOR_BOMBAY)
.border_width(2)
.padding(16)
.child(
Grid::new()
.id(ID_SENDER_GRID)
.columns(
Columns::create()
.push("stretch") // Message
.push(16) // Delimiter
.push("auto") // Button
)
.rows(
Rows::create()
.push("auto") // Header
.push(6) // Delimiter
.push("auto") // Message
.push(6) // Delimiter
)
.child(sender_header) // row 0
.child(sender_message) // row 2
.child(sender_button) // row 3
.build(build_context)
)
.build(build_context)
)
}
}

View File

@@ -1 +0,0 @@
../../../advotrackerd/data/POLLFNR_WOECHENTLICH.txt

View File

@@ -1,98 +0,0 @@
{
"err.lang.not_found": {
"de_DE.UTF-8": "Konnte die Umgebungsvarialbe LANG nicht auslesen",
"de": "Konnte die Umgebungsvarialbe LANG nicht auslesen",
"en": "Couldn't read LANG"
},
"err.user.not_found": {
"fr": "Utilisateur introuvable: $email, $id",
"de-DE.UTF-8": "Anwender nicht gefunden: $email, $id",
"de": "Anwender nicht gefunden: $email, $id",
"en": "User not found: $email, $id"
},
"main.started": {
"de_DE.UTF-8": "Programmlogik starten",
"de": "Programmlogik starten",
"en": "Program logic started"
},
"main.finished": {
"de_DE.UTF-8": "Programmlogik beendet",
"de": "Programmlogik beendet",
"en": "Program logic finished"
},
"parse.arguments": {
"de_DE.UTF-8": "Programmargumente prüfen",
"de": "Programmargumente prüfen",
"en": "Parsing arguments"
},
"parse.environment": {
"de_DE.UTF-8": "Umgebungsvariablen prüfen",
"de": "Umgebungsvariablen prüfen",
"en": "Parsing environment"
},
"parse.results": {
"de_DE.UTF-8": "Ergebnisse der Konfigurations-Parameterprüfung",
"de": "Ergebnisse der Konfigurationsparameterprüfung",
"en": "Config parsing results"
},
"config.name": {
"de_DE.UTF-8": "Konfigurationswert für",
"de": "Konfigurationswert für",
"en": "Config Value for"
},
"config.name.lang": {
"de_DE.UTF-8": "Sprach-Code",
"de": "Sprach-Code",
"en": "Language code"
},
"config.name.verbositylevel": {
"de_DE.UTF-8": "Ausgabe-Ebene",
"de": "Ausgabe-Ebene",
"en": "verbosity level"
},
"config.name.environment": {
"de_DE.UTF-8": "Umgebungsvariablen",
"de": "Umgebungsvariablen",
"en": "environment"
},
"config.name.configfile": {
"de_DE.UTF-8": "Konfigurations-Datei",
"de": "Konfigurations-Datei",
"en": "config file"
},
"config.name.dbdriver": {
"de_DE.UTF-8": "Datenbank-Treiber",
"de": "Datenbank-Treiber",
"en": "database driver"
},
"csv_import.started": {
"de_DE.UTF-8": "importieren von einer csv-datei gestartet",
"de": "importieren von einer csv-datei gestartet",
"en": "import from a csv-file started"
},
"csv_import.finished": {
"de_DE.UTF-8": "importieren von einer csv-datei beendet",
"de": "importieren von einer csv-datei beendet",
"en": "import from a csv-file finished"
},
"csv_export.started": {
"de_DE.UTF-8": "exportieren in eine csv-datei gestartet",
"de": "exportieren in eine csv-datei gestartet",
"en": "export to csv-file started"
},
"csv_export.finished": {
"de_DE.UTF-8": "exportieren in eine csv-datei beendet",
"de": "exportieren in eine csv-datei beendet",
"en": "export to csv-file finished"
},
"state.started": {
"de_DE.UTF-8": "gestartet",
"de": "gestartet",
"en": "started"
},
"state.finished": {
"de_DE.UTF-8": "beendet",
"de": "beended",
"en": "finished"
}
}

View File

@@ -1,11 +1,5 @@
use orbtk::prelude::*; use orbtk::prelude::*;
// use orbtk::theme::DEFAULT_THEME_CSS;
// use orbtk::theme::LIGHT_THEME_EXTENSION_CSS;
// //#[cfg(feature = "light-theme")]
// static WIDGET_EXT: &'static str = include_str!("../../resources/stylesheets/policyholder_check.css");
// fn get_theme() -> ThemeValue { // fn get_theme() -> ThemeValue {
// //ThemeValue::create_from_css(LIGHT_THEME_EXTENSION_CSS) // //ThemeValue::create_from_css(LIGHT_THEME_EXTENSION_CSS)
// ThemeValue::create_from_css(DEFAULT_THEME_CSS) // ThemeValue::create_from_css(DEFAULT_THEME_CSS)
@@ -15,12 +9,8 @@ use orbtk::prelude::*;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
enum Action { enum Action {
//ClearText,
EntryActivated(Entity), EntryActivated(Entity),
EntryChanged(Entity), EntryChanged(Entity)
//ValueChanged(Entity),
//ValueOk,
//ValueNone,
} }
#[derive(AsAny)] #[derive(AsAny)]
@@ -58,23 +48,16 @@ impl State for MainViewState {
// //ctx.widget().set("policynumber", background("#5b0f22")); // //ctx.widget().set("policynumber", background("#5b0f22"));
//} //}
Action::EntryActivated(entity) => { Action::EntryActivated(entity) => {
let mut text_box = TextBox::get(ctx.get_widget(entity)); //let text = ctx.get_widget(entity).clone::<String>("text");
let text = text_box.text_mut(); let widget = ctx.get_widget(entity);
//let mut widget = ctx.get_widget(entity); let text = widget.get::<String>("text");
//let text = widget.get_mut::<String16>("text");
println!("got value policynumber: {}", text); println!("got value policynumber: {}", text);
//text.clear();
} }
Action::EntryChanged(entity) => { Action::EntryChanged(entity) => {
let widget = ctx.get_widget(entity); let widget = ctx.get_widget(entity);
let text = widget.get::<String16>("text"); let text = widget.get::<String>("text");
println!("entry changed: {}", text); println!("entry changed: {}", text);
} }
// Action::ValueChanged(entity) => {
// let val =
// ((*ctx.get_widget(entity).get::<f64>("val")).floor() as i32).to_string();
// ctx.child("value_text").set("text", String16::from(val));
//}
} }
self.action = None; self.action = None;
@@ -85,7 +68,6 @@ impl State for MainViewState {
fn create_header(ctx: &mut BuildContext, text: &str) -> Entity { fn create_header(ctx: &mut BuildContext, text: &str) -> Entity {
TextBlock::new() TextBlock::new()
.text(text) .text(text)
//.element("text-block")
.style("header") .style("header")
.build(ctx) .build(ctx)
} }
@@ -101,26 +83,19 @@ widget!(
impl Template for MainView { impl Template for MainView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self { fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
self.name("MainView").child( self.name("MainView").child(
//.result("Anzahl Versicherungsnummern: 0")
//.result("Policyholders count: 0").sum_policynumbers(0)
//.sum_policynumbers(0)
Grid::new() Grid::new()
.background("#fafafa") .background("#fafafa")
//.width(200.0)
//.height(360.0)
.columns( .columns(
Columns::new() Columns::create()
.add(150.0) .push(150.0)
.add("*") .push("*")
//.add(120.0) .push(150.0)
//.add("auto")
.add(150.0)
.build(), .build(),
) )
.rows( .rows(
Rows::new() Rows::create()
.add("*") .push("*")
.add("*") .push("*")
.build(), .build(),
) )
.child( .child(
@@ -140,27 +115,22 @@ impl Template for MainView {
.child(create_header(ctx, "Validierung Versicherungsnummer")) .child(create_header(ctx, "Validierung Versicherungsnummer"))
.child( .child(
TextBox::new() TextBox::new()
//.class("text_box")
// overwriting the class defaults
/* .background("transparent")
.foreground("#9dafbf") .foreground("#9dafbf")
.background("#fafafa") .background("#fafafa")
/* .foreground(colors::LINK_WATER_COLOR) */
.border_brush("#5b0f22") .border_brush("#5b0f22")
.border_width(5) .border_width(5)
.border_radius(15) */ .border_radius(15)
//.name("policynumber") //.name("policynumber")
.focused(true) .focused(true)
.water_mark("Versicherungs-Nr...") .water_mark("Versicherungs-Nr...")
//.text("Number policyholder", id)
.text(("policynumber", id)) .text(("policynumber", id))
.font_size(24.0) .font_size(24.0)
.h_align("stretch") .h_align("stretch")
.on_activate(move |states, entity| { .on_activate(move |ctx, entity| {
state(id, states).action(Action::EntryActivated(entity)); state(id, ctx).action(Action::EntryActivated(entity));
}) })
.on_changed(move |states, entity| { .on_changed("text", move |ctx, entity| {
state(id, states).action(Action::EntryChanged(entity)); state(id, ctx).action(Action::EntryChanged(entity));
}) })
.build(ctx), .build(ctx),
) )
@@ -180,28 +150,28 @@ impl Template for MainView {
) )
.child( .child(
Grid::new() Grid::new()
//.element("logo_customer") //.class("logo_customer")
.margin((9.0, 16.0, 16.0, 9.0)) .margin((9.0, 16.0, 16.0, 9.0))
.attach(Grid::column(0)) .attach(Grid::column(0))
.attach(Grid::row(1)) .attach(Grid::row(1))
.v_align("end") .v_align("end")
.child( .child(
ImageWidget::new() ImageWidget::new()
.image("./resources/images/hiedemann_logo.png") .image("assets/images/customer_logo.png")
.build(ctx), .build(ctx),
) )
.build(ctx), .build(ctx),
) )
.child( .child(
Grid::new() Grid::new()
//.element("logo_vendor") //.class("logo_vendor")
.margin((9.0, 16.0, 16.0, 9.0)) .margin((9.0, 16.0, 16.0, 9.0))
.attach(Grid::column(2)) .attach(Grid::column(2))
.attach(Grid::row(1)) .attach(Grid::row(1))
.v_align("end") .v_align("end")
.child( .child(
ImageWidget::new() ImageWidget::new()
.image("./resources/images/networkx_logo.png") .image("assets/images/networkx_logo.png")
.build(ctx), .build(ctx),
) )
.build(ctx), .build(ctx),

View File

@@ -1,20 +1,52 @@
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT) * SPDX-License-Identifier: (0BSD or MIT)
*/ */
// Component Values (Properties)
pub static PROP_ADVOTRACKER: &str = "advotracker";
pub static PROP_MAIL_CC_1: &str = "info@hiedemann.de";
pub static PROP_MAIL_CC_2: &str = "service@hiedemann.de";
pub static PROP_MAIL_BCC_1: &str = "Networkx Support <support@networkx.de>";
pub static PROP_MAIL_BCC_2: &str = "knoche@hiedemann.de";
pub static PROP_MAIL_FROM: &str = "Kanzlei Hiedemann <info@heidemann.de>";
pub static PROP_MAIL_REPLY: &str = "Kanzlei Hiedemann <info@heidemann.de>";
pub static PROP_MAIL_SUBJECT: &str = "ZMB Allianz - neues Mandat";
pub static PROP_MAIL_TO_1: &str = "allianz@ponschab-partner.com";
pub static PROP_MAIL_TO_2: &str = "kontakt@chevalier.law";
pub static PROP_MAIL_TO_3: &str = "kontakt@metamedlaw.de";
pub static PROP_MAIL_TO_4: &str = "sekretariat@m2-mediation.de";
pub static PROP_POLICY_CHECK: &str = "policy_check";
pub static PROP_POLICY_PROGRESS_COUNT: &str = "policy_progress_count";
pub static PROP_POLICY_DATA_LIST: &str = "policy_data_list";
pub static PROP_POLICY_DATA_COUNT: &str = "policy_data_count";
pub static PROP_POLICY_LIST: &str = "policy_list";
pub static PROP_POLICY_LIST_COUNT: &str = "policy_list_count";
// Styles (RON based theme system) // Styles (RON based theme system)
pub static STYLE_BOTTOM_BAR: &str = "bottom_bar"; pub static STYLE_BOTTOM_BAR: &str = "bottom_bar";
pub static STYLE_HEADER_BAR: &str = "header_bar";
pub static STYLE_SEPERATOR: &str = "seperator";
//pub static STYLE_ITEM_BUTTON: &str = "item_button";
pub static STYLE_MENU: &str = "menu";
pub static STYLE_BUTTON_MENU: &str = "button_menu"; pub static STYLE_BUTTON_MENU: &str = "button_menu";
pub static STYLE_BUTTON_ACTION: &str = "button_action";
pub static STYLE_CONTAINER_ACTION: &str = "container_action";
pub static STYLE_CONTAINER_MAIL: &str = "container_mail";
pub static STYLE_HEADER_BAR: &str = "header_bar";
pub static STYLE_HEADER_TEXT: &str = "header_text";
pub static STYLE_SEPARATOR: &str = "separator";
pub static STYLE_MAIL_LABEL: &str = "mail_label";
pub static STYLE_MAIL_TO: &str = "mail_to";
pub static STYLE_MAIL_CC: &str = "mail_cc";
pub static STYLE_MENU: &str = "menu";
pub static STYLE_STACK_ACTION: &str = "stack_action";
pub static STYLE_STACK_MENU: &str = "stack_menu"; pub static STYLE_STACK_MENU: &str = "stack_menu";
// Widget IDs (DCES: Entity[id] => [Component1, .. , Component<n>] -> data or state) // Widget IDs (DCES: Entity[id] => [Component1, .. , Component<n>] -> data or state)
pub static ID_CONFIGURATION_VIEW: &str = "Configuration";
pub static ID_CONFIGURATION_FORM: &str = "configuration_form"; pub static ID_CONFIGURATION_FORM: &str = "configuration_form";
pub static ID_CONFIGURATION_HEADER: &str = "configuration_header"; pub static ID_CONFIGURATION_HEADER: &str = "configuration_header";
pub static ID_CONFIGURATION_LABEL_CONFIG_FILE: &str = "configuration_label_config_file"; pub static ID_CONFIGURATION_LABEL_CONFIG_FILE: &str = "configuration_label_config_file";
@@ -22,37 +54,50 @@ pub static ID_CONFIGURATION_CONFIG_FILE: &str = "configuration_config_file";
pub static ID_CONFIGURATION_LABEL_LANGUAGE_ID: &str = "configuration_label_language_id"; pub static ID_CONFIGURATION_LABEL_LANGUAGE_ID: &str = "configuration_label_language_id";
pub static ID_CONFIGURATION_LANGUAGE_ID: &str = "configuration_language_id"; pub static ID_CONFIGURATION_LANGUAGE_ID: &str = "configuration_language_id";
pub static ID_LOCALIZATION_VIEW: &str = "Localization";
pub static ID_LOCALIZATION_FORM: &str = "localization_form"; pub static ID_LOCALIZATION_FORM: &str = "localization_form";
pub static ID_LOCALIZATION_HEADER: &str = "localization_header"; pub static ID_LOCALIZATION_HEADER: &str = "localization_header";
pub static ID_LOCALIZATION_LANGUAGES: &str = "localization_languages"; pub static ID_LOCALIZATION_LANGUAGES: &str = "localization_languages";
pub static ID_LOCALIZATION_LABEL_LANGUAGE_NAME: &str = "localization_label_language_name"; pub static ID_LOCALIZATION_LABEL_LANGUAGE_NAME: &str = "localization_label_language_name";
pub static ID_LOCALIZATION_LANGUAGE_NAME: &str = "localization_language_name"; pub static ID_LOCALIZATION_LANGUAGE_NAME: &str = "localization_language_name";
pub static ID_MAIN_GRID: &str = "main_grid";
pub static ID_MAIN_TABWIDGET: &str = "main_tabwidget";
pub static ID_MAIN_BUTTON_MENU: &str = "main_button_menu";
pub static ID_MENU_VIEW: &str = "menu_view";
pub static ID_MENU_POPUP: &str = "menu_popup"; pub static ID_MENU_POPUP: &str = "menu_popup";
pub static ID_MENU_STACK: &str = "menu_stack"; pub static ID_MENU_STACK: &str = "menu_stack";
pub static ID_MENU_BOTTOM_BAR: &str = "menu_bottom_bar";
pub static ID_MENU_BUTTON: &str = "menu_button"; pub static ID_MENU_BUTTON: &str = "menu_button";
pub static ID_MENU_BUTTON_MENU: &str = "menu_button_menu";
pub static ID_MENU_GRID: &str = "menu_grid"; pub static ID_MENU_GRID: &str = "menu_grid";
pub static ID_MENU_HEADER: &str = "menu_header";
pub static ID_MENU_HEADER_BAR: &str = "menu_header_bar";
pub static ID_MENU_LABEL_ACCOUNT: &str = "menu_label_account"; pub static ID_MENU_LABEL_ACCOUNT: &str = "menu_label_account";
pub static ID_MENU_LABEL_QUIT: &str = "menu_label_quit"; pub static ID_MENU_LABEL_QUIT: &str = "menu_label_quit";
pub static ID_MENU_LABEL_TOGGLE_THEME: &str = "menu_label_toggle_theme"; pub static ID_MENU_LABEL_TOGGLE_THEME: &str = "menu_label_toggle_theme";
pub static ID_MENU_SHORTCUT_QUIT: &str = "menu_shortcut_quit"; pub static ID_MENU_SHORTCUT_QUIT: &str = "menu_shortcut_quit";
pub static ID_MENU_TOGGLE_THEME: &str = "menu_toggle_theme"; pub static ID_MENU_TOGGLE_THEME: &str = "menu_toggle_theme";
pub static ID_POLICY_CHECK_FORM: &str = "policy_check_form"; pub static ID_POLICY_CHECK_VIEW: &str = "policy_check_view";
pub static ID_POLICY_CHECK_FORM_ROW_0: &str = "policy_check_form_row_0"; pub static ID_POLICY_CHECK_ACTION_BUTTON_CREATE: &str = "policy_check_action_button_create";
pub static ID_POLICY_CHECK_FORM_ROW_1: &str = "policy_check_form_row_1"; pub static ID_POLICY_CHECK_ACTION_GRID: &str = "policy_check_action_grid";
pub static ID_POLICY_CHECK_FORM_ROW_2: &str = "policy_check_form_row_2"; pub static ID_POLICY_CHECK_BOTTOM_BAR: &str = "policy_check_bottom_bar";
pub static ID_POLICY_CHECK_HEADER: &str = "policy_check_header";
pub static ID_POLICY_CHECK_ITEMS_WIDGET: &str = "policy_check_items_widget";
pub static ID_POLICY_CHECK_BUTTON_RESULT: &str = "policy_check_button_result"; pub static ID_POLICY_CHECK_BUTTON_RESULT: &str = "policy_check_button_result";
pub static ID_POLICY_CHECK_BUTTON_MENU: &str = "policy_check_button_menu"; pub static ID_POLICY_CHECK_BUTTON_MENU: &str = "policy_check_button_menu";
pub static ID_POLICY_CHECK_DATA_COUNT_BLOCK: &str = "policy_check_data_count_block"; pub static ID_POLICY_CHECK_DATA_COUNT_BLOCK: &str = "policy_check_data_count_block";
pub static ID_POLICY_CHECK_FORM: &str = "policy_check_form";
pub static ID_POLICY_CHECK_HEADER: &str = "policy_check_header";
pub static ID_POLICY_CHECK_HEADER_BAR: &str = "policy_check_header_bar";
pub static ID_POLICY_CHECK_HINT: &str = "policy_check_hint"; pub static ID_POLICY_CHECK_HINT: &str = "policy_check_hint";
pub static ID_POLICY_CHECK_ITEMS_WIDGET: &str = "policy_check_items_widget";
pub static ID_POLICY_CHECK_LABEL_HINT: &str = "policy_check_label_hint"; pub static ID_POLICY_CHECK_LABEL_HINT: &str = "policy_check_label_hint";
pub static ID_POLICY_CHECK_LABEL_MENU: &str = "policy_check_label_menu"; pub static ID_POLICY_CHECK_LABEL_MENU: &str = "policy_check_label_menu";
pub static ID_POLICY_CHECK_LABEL_POLICY_NUMBER: &str = "policy_check_label_policy_number"; pub static ID_POLICY_CHECK_LABEL_POLICY_NUMBER: &str = "policy_check_label_policy_number";
pub static ID_POLICY_CHECK_LABEL_RESULT: &str = "policy_check_label_result"; pub static ID_POLICY_CHECK_LABEL_RESULT: &str = "policy_check_label_result";
pub static ID_POLICY_CHECK_POLICY_NUMBER: &str = "policy_check_policy_number"; pub static ID_POLICY_CHECK_POLICY_CODE: &str = "policy_check_policy_code";
pub static ID_POLICY_CHECK_POLICY_NUMBER: &str = "policy_number";
pub static ID_POLICY_CHECK_POPUP_PROGRESS: &str = "policy_check_popup_progress"; pub static ID_POLICY_CHECK_POPUP_PROGRESS: &str = "policy_check_popup_progress";
pub static ID_POLICY_CHECK_PROGRESS_BAR: &str = "policy_check_progress_bar"; pub static ID_POLICY_CHECK_PROGRESS_BAR: &str = "policy_check_progress_bar";
pub static ID_POLICY_CHECK_PROGRESS_TIME: &str = "policy_check_progress_time"; pub static ID_POLICY_CHECK_PROGRESS_TIME: &str = "policy_check_progress_time";
@@ -76,13 +121,44 @@ pub static ID_POLICY_LIST_ADD_BUTTON: &str = "policy_list_add_button";
pub static ID_POLICY_LIST_ITEMS_WIDGET: &str = "policy_list_items_widget"; pub static ID_POLICY_LIST_ITEMS_WIDGET: &str = "policy_list_items_widget";
pub static ID_POLICY_LIST_TEXT_BOX: &str = "policy_list_text_box"; pub static ID_POLICY_LIST_TEXT_BOX: &str = "policy_list_text_box";
// Component Values (Properties) pub static ID_TICKET_DATA_ACTION_BUTTON_CLEAR: &str = "ticket_data_action_button_clear";
pub static PROP_ADVOTRACKER: &str = "advotracker"; pub static ID_TICKET_DATA_ACTION_BUTTON_SEND: &str = "ticket_data_action_button_send";
pub static PROP_POLICY_CHECK: &str = "policy_check"; pub static ID_TICKET_DATA_ACTION_GRID: &str = "ticket_data_action_grid";
pub static PROP_POLICY_PROGRESS_COUNT: &str = "policy_progress_count"; pub static ID_TICKET_DATA_BOTTOM_BAR: &str = "ticket_data_bottom_bar";
pub static ID_TICKET_DATA_BUTTON_MENU: &str = "ticket_data_button_menu";
pub static PROP_POLICY_DATA_LIST: &str = "policy_data_list"; pub static ID_TICKET_DATA_BUTTON_RESULT: &str = "ticket_data_button_result";
pub static PROP_POLICY_DATA_COUNT: &str = "policy_data_count"; pub static ID_TICKET_DATA_CALLBACK_DATE: &str = "ticket_data_label_callback_date";
pub static ID_TICKET_DATA_CALLBACK_NUMBER: &str = "ticket_data_label_callback_number";
pub static PROP_POLICY_LIST: &str = "policy_list"; pub static ID_TICKET_DATA_COMBO_BOX_MAIL_CC: &str = "ticket_data_combo_box_mail_cc";
pub static PROP_POLICY_LIST_COUNT: &str = "policy_list_count"; pub static ID_TICKET_DATA_COMBO_BOX_MAIL_TO: &str = "ticket_data_combo_box_mail_to";
pub static ID_TICKET_DATA_CONTAINER_MAIL: &str = "ticket_data_container_mail";
pub static ID_TICKET_DATA_COUNT_BLOCK: &str = "ticket_data_count_block";
pub static ID_TICKET_DATA_DEDUCTIBLE: &str = "ticket_data_deductible";
pub static ID_TICKET_DATA_FORM: &str = "ticket_data_form";
pub static ID_TICKET_DATA_GRID: &str = "ticket_data_grid";
pub static ID_TICKET_DATA_GRID_MAIL: &str = "ticket_data_grid_mail";
pub static ID_TICKET_DATA_HARM_TYPE: &str = "ticket_data_harm_type";
pub static ID_TICKET_DATA_HEADER_BAR: &str = "ticket_data_header_bar";
pub static ID_TICKET_DATA_HEADER: &str = "ticket_data_header";
pub static ID_TICKET_DATA_HINT: &str = "ticket_data_hint";
pub static ID_TICKET_DATA_ITEMS_WIDGET: &str = "ticket_data_items_widget";
pub static ID_TICKET_DATA_IVR_COMMENT: &str = "ticket_data_ivr_comment";
pub static ID_TICKET_DATA_LABEL_CALLBACK_DATE: &str = "ticket_data_label_callback_data";
pub static ID_TICKET_DATA_LABEL_CALLBACK_NUMBER: &str = "ticket_data_label_callback_number";
pub static ID_TICKET_DATA_LABEL_DEDUCTIBLE: &str = "ticket_data_label_deductible";
pub static ID_TICKET_DATA_LABEL_HARM_TYPE: &str = "ticket_data_label_harm_type";
pub static ID_TICKET_DATA_LABEL_HINT: &str = "ticket_data_label_hint";
pub static ID_TICKET_DATA_LABEL_IVR_COMMENT: &str = "ticket_data_label_ivr_comment";
pub static ID_TICKET_DATA_LABEL_MAIL_CC: &str = "ticket_data_label_mail_cc";
pub static ID_TICKET_DATA_LABEL_MAIL_TO: &str = "ticket_data_label_mail_to";
pub static ID_TICKET_DATA_LABEL_MENU: &str = "ticket_data_label_menu";
pub static ID_TICKET_DATA_LABEL_POLICY_CODE: &str = "ticket_data_label_policy_code";
pub static ID_TICKET_DATA_LABEL_POLICY_HOLDER: &str = "ticket_data_label_policy_holder";
pub static ID_TICKET_DATA_LOGO_BAR: &str = "ticket_data_logo_bar";
pub static ID_TICKET_DATA_MAIL_CC: &str = "ticket_data_mail_cc";
pub static ID_TICKET_DATA_MAIL_TO: &str = "ticket_data_mail_to";
pub static ID_TICKET_DATA_POLICY_CODE: &str = "ticket_data_policy_code";
pub static ID_TICKET_DATA_POLICY_HOLDER: &str = "ticket_data_policy_holder";
pub static ID_TICKET_DATA_RESULT: &str = "ticket_data_result";
pub static ID_TICKET_DATA_VIEW: &str = "ticket_data_view";
pub static ID_TICKET_DATA_WIDGET: &str = "ticket_data_widget";

View File

@@ -110,6 +110,39 @@ pub struct CsvExportRecord {
pub ivr_comment: String, pub ivr_comment: String,
} }
/// Handel fields of an Email (header, body)
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct Email {
/// Recipient address
pub mail_to: String,
/// Carbon Copy recipient address
pub mail_cc: String,
/// Blind Carbon Copy recipient address
pub mail_bcc: String,
/// Sender address
pub mail_from: String,
/// Replay to given address
pub mail_reply: String,
/// Mail subject
pub subject: String,
/// Body policy code
pub policy_code: String,
/// Body type policy holder
pub policy_holder: String,
/// Body type deductible
pub deductible: String,
/// Body callback number
pub callback_number: String,
/// Body type callback date
pub callback_date: String,
/// Body type harm type
pub harm_type: String,
/// Body type ivr comment
pub ivr_comment: String
}
impl Email {}
/// Harm data are list/collections of harm types. You may toggle them to an unselected state. /// Harm data are list/collections of harm types. You may toggle them to an unselected state.
#[derive(Default, Debug, Clone, Deserialize, Serialize)] #[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct HarmData { pub struct HarmData {
@@ -157,20 +190,6 @@ pub struct PolicyCheck {
impl PolicyCheck {} impl PolicyCheck {}
// #[derive(Default, Clone, Debug, Serialize, Deserialize)]
// pub struct PolicyCheckList {
// pub title: String,
// pub list: Vec<PolicyCheck>
// }
// impl PolicyCheckList {
// pub fn new(title: impl Into<String>) -> Self {
// PolicyCheckList {
// title: title.into(),
// ..Default::default()
// }
// }
/// Structure collecting policy data elements /// Structure collecting policy data elements
#[derive(Default, Clone, Debug, Serialize, Deserialize)] #[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct PolicyList { pub struct PolicyList {
@@ -241,7 +260,7 @@ pub struct PolicyDataList {
/// implements the helper methods, to manage policy data collections. /// implements the helper methods, to manage policy data collections.
impl PolicyDataList { impl PolicyDataList {
/// Prüfung ob Versicherungselemente . /// Prüfung auf Versicherungselemente
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.policy_data.is_empty() self.policy_data.is_empty()
} }

View File

@@ -225,6 +225,16 @@
"de_DE": "Die Nummer ist zu kurz", "de_DE": "Die Nummer ist zu kurz",
"C": "Policy number is to short" "C": "Policy number is to short"
}, },
"sendticketdata.export.started":{
"de_DE.UTF-8": "Versenden von ticket daten via eMail gestartet",
"de_DE": "Versenden von ticket daten via eMail gestartet",
"C": "Send ticket data via eMail started"
},
"sendticketdata.export.finished":{
"de_DE.UTF-8": "Versenden von ticket daten via eMail beendet",
"de_DE": "Versenden von ticket daten via eMail beendet",
"C": "Send ticket data via eMail finished"
},
"state.started": { "state.started": {
"de_DE.UTF-8": "gestartet", "de_DE.UTF-8": "gestartet",
"de_DE": "gestartet", "de_DE": "gestartet",

View File

@@ -18,6 +18,7 @@ use cfg_if::cfg_if;
use serde::Deserialize; use serde::Deserialize;
use std::env; use std::env;
//use std::process; //use std::process;
use substring::Substring;
use tracing::{info, trace, Level}; use tracing::{info, trace, Level};
use orbtk::{ use orbtk::{
@@ -59,7 +60,9 @@ static ADVOTRACKER_DE_DE: &str = include_str!("../assets/advotracker/advotracker
/// Get the active language environment. /// Get the active language environment.
fn get_lang() -> String { fn get_lang() -> String {
// get system environment // get system environment
let mut lang = env::var("LANG").unwrap_or("C".to_string()); let mut lang = env::var("LANG").unwrap_or_else(|_| "C".to_string());
lang = lang.substring(0,5).to_string(); // "de_DE.UTF-8" -> "de_DE"
info!("GUI-Language: preset to {:?}", lang);
// testing environment: read from .env file // testing environment: read from .env file
dotenv().ok(); dotenv().ok();
@@ -70,6 +73,8 @@ fn get_lang() -> String {
Err(e) => { info!(target: "advotracker", "{}", e) } Err(e) => { info!(target: "advotracker", "{}", e) }
} }
trace!(target: "advotracker", lang = ?lang); trace!(target: "advotracker", lang = ?lang);
// return the active language
lang lang
} }
@@ -143,7 +148,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut state = t!("state.started", lang); let mut state = t!("state.started", lang);
let mut res = t!("parse.environment", lang); let mut res = t!("parse.environment", lang);
trace!(target: "advotracker", message = ?res, state = ?state); trace!(target: "advotracker", process = ?res, state = ?state);
trace!(target: "advotracker", environment = "system", lang = ?lang); trace!(target: "advotracker", environment = "system", lang = ?lang);
trace!(target: "advotracker", machine = ?&machine_kind); trace!(target: "advotracker", machine = ?&machine_kind);
@@ -151,7 +156,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
res = t!("parse.environment", lang); res = t!("parse.environment", lang);
trace!(target: "advotracker", environment = "envy", lang = ?lang); trace!(target: "advotracker", environment = "envy", lang = ?lang);
state = t!("state.finished", lang); state = t!("state.finished", lang);
trace!(target: "advotracker", message = ?res, state = ?state); trace!(target: "advotracker", process = ?res, state = ?state);
// initialize viperus structure // initialize viperus structure
let mut viperus = Viperus::new(); let mut viperus = Viperus::new();
@@ -165,6 +170,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
state = t!("state.finished", lang); state = t!("state.finished", lang);
trace!(target: "advotracker", process = ?res, state = ?state); trace!(target: "advotracker", process = ?res, state = ?state);
// type conversion (viperus String -> u64)
let test_policy_number = viperus.get::<String>("test_policy_number").unwrap().parse::<u64>().unwrap();
trace!(target: "advotracker", test_policy_number = ?test_policy_number);
// main tasks // main tasks
res = t!("main.started", lang); res = t!("main.started", lang);
state = t!("state.started", lang); state = t!("state.started", lang);
@@ -173,9 +182,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// use this only if you want to run it as web application. // use this only if you want to run it as web application.
orbtk::initialize(); orbtk::initialize();
// if no dictionary is set for the default language e.g. english the content of the text property will drawn. // Preset localization and language from given environment.
// if no dictionary is set for the chosen default language
// the content of the text property will be drawn.
//let language = lang.substring(0,5); // "de_DE.UTF-8" -> "de_DE"
//info!("GUI-Language: preset to {:?}", language);
let localization = RonLocalization::create() let localization = RonLocalization::create()
.language("en_US") .language(&lang)
.dictionary("de_DE", ADVOTRACKER_DE_DE) .dictionary("de_DE", ADVOTRACKER_DE_DE)
.build(); .build();
@@ -186,9 +199,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Window::new() Window::new()
.title("AdvoTracker - DirectCall") .title("AdvoTracker - DirectCall")
.position((500.0, 100.0)) .position((500.0, 100.0))
.size(580.0, 320.0) .size(800.0, 600.0)
//.min_width(460.0) //.min_width(460.0)
//.min_height(180.0) //.min_height(380.0)
.resizeable(true) .resizeable(true)
.child(main_view::MainView::new().build(ctx)) .child(main_view::MainView::new().build(ctx))
.build(ctx) .build(ctx)

View File

@@ -30,7 +30,7 @@ pub fn parse_args(viperus: &mut Viperus) -> Result<(), Box<dyn std::error::Error
viperus.add_default("config_file", String::from("csv_import.ron")); viperus.add_default("config_file", String::from("csv_import.ron"));
viperus.add_default("import_file", String::from("POLLFNR_WOECHENTLICH.txt")); viperus.add_default("import_file", String::from("POLLFNR_WOECHENTLICH.txt"));
viperus.add_default("export_file", String::from("")); viperus.add_default("export_file", String::from(""));
viperus.add_default("test_policy_number", 123456789); viperus.add_default("test_policy_number", String::from("9999999992"));
viperus.add_default("to_email_address_file", String::from("Allianz RA-Hotline <smr-rahotline@allianz.de>")); viperus.add_default("to_email_address_file", String::from("Allianz RA-Hotline <smr-rahotline@allianz.de>"));
viperus.add_default("from_email_address_file", String::from("Allianz-Hotline RA-Hiedemann <azhotline@hiedemann.de>")); viperus.add_default("from_email_address_file", String::from("Allianz-Hotline RA-Hiedemann <azhotline@hiedemann.de>"));
//viperus.add_default("username", String::from("nctalkbot")); //viperus.add_default("username", String::from("nctalkbot"));
@@ -139,7 +139,7 @@ SMR Unerledigt: 089 92529 60222")
// preset the prefix for relevant environment variables ("ADVOTRACKER_") // preset the prefix for relevant environment variables ("ADVOTRACKER_")
let mut env_prefix: String = crate_name!().to_uppercase(); let mut env_prefix: String = crate_name!().to_uppercase();
env_prefix.push_str("_"); env_prefix.push('_');
viperus.set_env_prefix(&env_prefix); viperus.set_env_prefix(&env_prefix);
// enable caching and automatic update of environment values // enable caching and automatic update of environment values

View File

@@ -8,16 +8,12 @@
//use chrono::{Local, DateTime}; //use chrono::{Local, DateTime};
use locales::t; use locales::t;
use std::error::Error; use std::error::Error;
//use std::collections::HashMap;
use tracing::trace; use tracing::trace;
//use crate::db::redis;
//use crate::data::structures::{PolicyCode, PolicyDataList, PolicyData};
/// export as csv format /// export as csv format
/// https://docs.rs/csv/1.1.3/csv/cookbook/index.html /// https://docs.rs/csv/1.1.3/csv/cookbook/index.html
/// https://blog.burntsushi.net/csv/ /// https://blog.burntsushi.net/csv/
pub fn export(p: &mut String, lang: &String) -> Result<(), Box<dyn Error>> { pub fn export(p: &mut String, lang: &str) -> Result<(), Box<dyn Error>> {
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
//use std::ffi::OsStr; //use std::ffi::OsStr;

View File

@@ -5,5 +5,8 @@
* SPDX-License-Identifier: (0BSD or MIT) * SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// Send ticketdata via email
pub mod send_ticketdata;
/// Exporting Allianz DirecCall data /// Exporting Allianz DirecCall data
pub mod allianzdirectcall; pub mod allianzdirectcall;

View File

@@ -0,0 +1,122 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use lettre::{
message::{header, MultiPart, SinglePart},
Message, SmtpTransport, Transport,
transport::smtp::authentication::Credentials,
};
use locales::t;
use maud::html;
use std::error::Error;
//use std::process;
use tracing::{info, error, trace};
use crate::data::structures::Email;
/// send ticket data via eMail
pub fn sendticketdata(email: &Email, lang: &str) -> Result<(), Box<dyn Error>> {
let mut res = t!("sendticketdata.export.started", lang);
let mut state = t!("state.started", lang);
trace!(target: "sendticketdata", process = ?res, state = ?state);
// The html we want to send.
// It uses https://crates.io/crates/maud
let html = html! {
head {
title { (email.subject) " (" (email.policy_code) ")" }
style type="text/css" {
"h2, h4 { font-family: Arial, Helvetica, sans-serif; }"
}
}
div style="display: flex; flex-direction: column; align-items: center;" {
// compose with variables and strings
h2 { (email.subject) " (" (email.policy_code) ")" }
p { "Vers.-Schein/Schadennummer: " (email.policy_code) }
p { "Versicherungsnehmer: " (email.policy_holder) }
p { "Selbstbehalt: "(email.deductible) }
p { "Rückrufnummer: " (email.callback_number) }
p { "Erreichbarkeit: " (email.callback_date) }
p { "Rechtsproblem: "(email.harm_type) }
p { "Rechtsrat: "(email.ivr_comment) }
}
};
let ascii_body = String::new()
+ &"Vers.-Schein/Schadennummer".to_string() + &(email.policy_code) + &"\n"
+ &"Versicherungsnehmer: ".to_string() + &(email.policy_holder) + &"\n"
+ &"Selbstbehalt: ".to_string() + &(email.deductible) + &"\n"
+ &"Rückrufnummer: ".to_string()+ &(email.callback_number) + &"\n"
+ &"Erreichbarkeit: ".to_string() + &(email.callback_date) + &"\n"
+ &"Rechtsproblem: ".to_string() + &(email.harm_type) + &"\n"
+ &"Rechtsrat: ".to_string() + &(email.ivr_comment) + &"\n";
info!("email body: {:?}", ascii_body);
let message = Message::builder()
//.reply_to("Kanzlei Hiedemann <info@hiedemann.de>".parse().unwrap())
.to("Kanzlei Hiedemann <info@hiedemann.de>".parse().unwrap())
.cc(" <ralf.zerres@networkx.de>".parse().unwrap())
.reply_to((email.mail_reply).parse().unwrap())
//.to((email.mail_to).parse().unwrap())
//.cc((email.mail_cc).parse().unwrap())
//.bcc((email.mail_bcc).parse().unwrap())
.from((email.mail_from).parse().unwrap())
.subject(String::new()
+ &email.subject.to_string()
+ &" (".to_string()
+ &email.policy_code.to_string()
+ &")".to_string()
)
.multipart(
MultiPart::alternative() // This is composed of two parts.
.singlepart(
SinglePart::builder()
.header(header::ContentType(
"text/plain; charset=utf8".parse().unwrap(),
))
.body(String::from(ascii_body)),
)
.singlepart(
SinglePart::builder()
.header(header::ContentType(
"text/html; charset=utf8".parse().unwrap(),
))
.body(html.into_string()),
),
)
.expect("failed to build email");
info!("message: {:?}", message);
// Create credential for remote authentication (username, password)
// WIP: get credentials from config file / cli
let creds = Credentials::new("info@kanzlei.hiedemann.de".to_string(), "17info67$".to_string());
// Open a remote connection to relay server (port 2525)
// WIP: get relay address from config file / cli
let mailer = SmtpTransport::relay("hiedemannsbs.kanzlei.hiedemann.de")
.unwrap()
.credentials(creds)
.build();
// Send the email
match mailer.send(&message) {
Ok(_) => info!("Email sent successfully!"),
Err(e) => error!("Could not send email: {:?}", e),
}
trace!(target: "sendticketdata", email = ?email);
state = t!("state.finished", lang);
res = t!("sendticketdata.export.finished", lang);
trace!(target: "sendticketdata", process = ?res, state = ?state);
Ok(())
}

View File

@@ -23,7 +23,7 @@ use crate::data::structures::{PolicyCode, PolicyDataList, PolicyData};
pub fn import(p: &mut String, data_list: &mut PolicyDataList, pub fn import(p: &mut String, data_list: &mut PolicyDataList,
policy_numbers: &mut HashMap<u64, PolicyCode>, policy_numbers: &mut HashMap<u64, PolicyCode>,
policy_data_count: &mut u64, policy_data_count: &mut u64,
lang: &String) lang: &str)
-> Result<(u64, Duration), Box<dyn Error>> { -> Result<(u64, Duration), Box<dyn Error>> {
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;

View File

@@ -24,7 +24,7 @@ fn import() -> Result<(), Box<dyn Error>> {
fn main() { fn main() {
if let Err(err) = import() { if let Err(err) = import() {
println!("error running example: {}", err); println!("import error: {}", err);
process::exit(1); process::exit(1);
} }
} }

View File

@@ -39,25 +39,31 @@ impl State for ConfigurationState {
) { ) {
for message in messages.read::<ConfigurationAction>() { for message in messages.read::<ConfigurationAction>() {
match message { match message {
ConfigurationAction::LoadConfiguration => registry ConfigurationAction::LoadConfiguration => {
.get::<Settings>("settings") registry
.load_async::<ConfigurationData>("configuration_data".to_string(), ctx.entity()), .get::<Settings>("settings")
.load_async::<ConfigurationData>(
"configuration_data".to_string(), ctx.entity()
);
}
ConfigurationAction::SaveConfiguration => { ConfigurationAction::SaveConfiguration => {
let configuration_file: String = ConfigurationView::configuration_file_clone(&ctx.widget()); let configuration_file: String = ConfigurationView::configuration_file_clone(&ctx.widget());
let language_id: String = ConfigurationView::language_id_clone(&ctx.widget()); let language_id: String = ConfigurationView::language_id_clone(&ctx.widget());
registry.get::<Settings>("settings").save_async( registry
"configuration_data".to_string(), .get::<Settings>("settings")
ConfigurationData( .save_async(
configuration_file, "configuration_data".to_string(),
language_id ConfigurationData(
), configuration_file,
ctx.entity(), language_id
); ),
ctx.entity(),
);
} }
} }
} }
// save result // save the result
for message in messages.read::<SettingsResult<()>>() { for message in messages.read::<SettingsResult<()>>() {
println!("Result {:?}", message); println!("Result {:?}", message);
} }

View File

@@ -27,7 +27,7 @@ impl Template for ConfigurationView {
self.child( self.child(
Grid::new() Grid::new()
.id(ID_CONFIGURATION_FORM) .id(ID_CONFIGURATION_FORM)
.style(configuration_form) .style("configuration_form")
.columns( .columns(
Columns::create() Columns::create()
.push(120) .push(120)
@@ -35,13 +35,13 @@ impl Template for ConfigurationView {
.push("auto") .push("auto")
) )
.rows(Rows::create() .rows(Rows::create()
.push("auto") .push("auto") // Header_Bar
.push(4) .push(4) // Seperator
.push("auto") .push("auto") // Configuartion_File
.push(4) .push(4) // Seperator
.push("auto") .push("auto") // Language_ID
.push(12) .push(12) // Seperator
.push("auto"), .push("auto"), // Action
) )
.child( .child(
TextBlock::new() TextBlock::new()
@@ -112,7 +112,7 @@ impl Template for ConfigurationView {
.style("button_single_content") .style("button_single_content")
.attach(Grid::column(0)) .attach(Grid::column(0))
.attach(Grid::row(0)) .attach(Grid::row(0))
.text("load") .text("Load")
.on_click(move |ctx, _| { .on_click(move |ctx, _| {
ctx.send_message(ConfigurationAction::LoadConfiguration, id); ctx.send_message(ConfigurationAction::LoadConfiguration, id);
true true
@@ -121,7 +121,7 @@ impl Template for ConfigurationView {
) )
.child( .child(
Button::new() Button::new()
.text("save") .text("Save")
.style("button_single_content") .style("button_single_content")
.attach(Grid::column(2)) .attach(Grid::column(2))
.attach(Grid::row(0)) .attach(Grid::row(0))

View File

@@ -8,6 +8,7 @@
use dotenv::dotenv; use dotenv::dotenv;
use serde::Deserialize; use serde::Deserialize;
use std::env; use std::env;
use substring::Substring;
use tracing::{info, trace}; use tracing::{info, trace};
use orbtk::prelude::*; use orbtk::prelude::*;
@@ -28,10 +29,11 @@ struct Environment {
/// Provides generic methods to handle states of datatypes. /// Provides generic methods to handle states of datatypes.
pub trait GlobalState { pub trait GlobalState {
/// Get the active language environment.
fn get_lang() -> String { fn get_lang() -> String {
// get system environment // get system environment
let mut lang = env::var("LANG").unwrap_or("C".to_string()); let mut lang = env::var("LANG").unwrap_or_else(|_| "C".to_string());
lang = lang.substring(0,5).to_string(); // "de_DE.UTF-8" -> "de_DE"
info!("GUI-Language: preset to {:?}", lang);
// testing environment: read from .env file // testing environment: read from .env file
dotenv().ok(); dotenv().ok();
@@ -42,17 +44,28 @@ pub trait GlobalState {
Err(e) => { info!(target: "advotracker", "{}", e) } Err(e) => { info!(target: "advotracker", "{}", e) }
} }
trace!(target: "advotracker", lang = ?lang); trace!(target: "advotracker", lang = ?lang);
// return the active language
lang lang
} }
/// Get the text of a widget.
fn get_text(&self, ctx: &mut Context<'_>, entity: Entity) -> Option<String> {
let text = TextBox::text_clone(&ctx.get_widget(entity));
if text.is_empty() {
return None;
}
TextBox::text_set(&mut ctx.get_widget(entity), String::default());
Some(text)
}
// /// Navigates to the given entity. // /// Navigates to the given entity.
// fn navigate(&self, to: Entity, ctx: &mut Context<'_>) { // fn navigate(&self, to: Entity, ctx: &mut Context<'_>) {
// if let Some(old_focused_element) = ctx.window().get::<Global>("global").focused_widget { // if let Some(old_focused_element) = *Window::focus_state_ref(&ctx.window()).focused_entity() {
// let mut old_focused_element = ctx.get_widget(old_focused_element); // ctx.push_event_by_window(FocusEvent::RemoveFocus(old_focused_element));
// old_focused_element.set("focused", false);
// //old_focused_element.update_theme_by_state(false);
// } // }
// ctx.window().get_mut::<Global>("global").focused_widget = None;
// ctx.widget().set("visibility", Visibility::Collapsed); // ctx.widget().set("visibility", Visibility::Collapsed);
// ctx.get_widget(to).set("visibility", Visibility::Visible); // ctx.get_widget(to).set("visibility", Visibility::Visible);
// } // }
@@ -62,7 +75,6 @@ pub trait GlobalState {
/// in users 'settings directory'. The directory location is OS dependant /// in users 'settings directory'. The directory location is OS dependant
/// (Windows: AppData, Unix: XDG_CONFIG_HOME, MacOS: $HOME/Library/Preferences). /// (Windows: AppData, Unix: XDG_CONFIG_HOME, MacOS: $HOME/Library/Preferences).
/// The data is stored in filename PROP_ADVOTRACKER (here: `advotracker.ron`) /// The data is stored in filename PROP_ADVOTRACKER (here: `advotracker.ron`)
fn save(&self, registry: &mut Registry, ctx: &mut Context<'_>) { fn save(&self, registry: &mut Registry, ctx: &mut Context<'_>) {
registry registry
.get::<Settings>("settings") .get::<Settings>("settings")

View File

@@ -8,11 +8,15 @@
use orbtk::prelude::*; use orbtk::prelude::*;
use crate::{ use crate::{
data::structures::PolicyCheck, data::{
constants::*,
structures::PolicyCheck,
},
widgets::configuration::configuration_view::ConfigurationView,
widgets::policycheck::policycheck_view::PolicycheckView, widgets::policycheck::policycheck_view::PolicycheckView,
widgets::localization::localization_view::LocalizationView, widgets::localization::localization_view::LocalizationView,
widgets::configuration::configuration_view::ConfigurationView, //widgets::menu::menu_view::MenuView,
widgets::menu::menu_view::MenuView, widgets::ticketdata::ticketdata_view::TicketdataView,
}; };
// [START] views // [START] views
@@ -23,13 +27,18 @@ widget!(MainView {
// policylist_view: u32, // policylist_view: u32,
// policydata_view: u32, // policydata_view: u32,
policycheck_view: PolicyCheck policycheck_view: PolicyCheck
//ticketdata_view: TicketData
}); });
impl Template for MainView { impl Template for MainView {
fn template(self, _id: Entity, ctx: &mut BuildContext<'_>) -> Self { fn template(self, _id: Entity, ctx: &mut BuildContext<'_>) -> Self {
let ticketdata_view = TicketdataView::new()
.build(ctx);
let policycheck_view = PolicycheckView::new() let policycheck_view = PolicycheckView::new()
//.policy_number_count(0) .target(ticketdata_view.0)
//.policylist_view(id) //.policy_number_count(0)
//.policylist_view(id)
.build(ctx); .build(ctx);
// let policylist_view = PolicyListView::new() // let policylist_view = PolicyListView::new()
@@ -46,7 +55,7 @@ impl Template for MainView {
// .build(ctx); // .build(ctx);
self.name("MainView") self.name("MainView")
.policycheck_view(PolicyCheck::default()) //.policycheck_view(PolicyCheck::default())
// //.policycheck_view(0) // //.policycheck_view(0)
// .policydata_view(policydata_view.0) // .policydata_view(policydata_view.0)
// //.policylist_view(PolicyList::default()) // //.policylist_view(PolicyList::default())
@@ -55,10 +64,11 @@ impl Template for MainView {
// .child(policylist_view) // .child(policylist_view)
.child( .child(
TabWidget::new() TabWidget::new()
.tab("Policynumber check", policycheck_view) .tab(ID_POLICY_CHECK_VIEW, policycheck_view)
.tab("Localization", LocalizationView::new().build(ctx)) .tab(ID_TICKET_DATA_VIEW, ticketdata_view)
.tab("Configuration", ConfigurationView::new().build(ctx)) .tab(ID_LOCALIZATION_VIEW, LocalizationView::new().build(ctx))
.tab("Menu", MenuView::new().build(ctx)) .tab(ID_CONFIGURATION_VIEW, ConfigurationView::new().build(ctx))
//.tab(ID_MENU_VIEW, MenuView::new().build(ctx))
.build(ctx), .build(ctx),
) )
//.child(policycheck_view) //.child(policycheck_view)

View File

@@ -1,13 +1,14 @@
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT) * SPDX-License-Identifier: (0BSD or MIT)
*/ */
use cfg_if::cfg_if; use cfg_if::cfg_if;
use orbtk::prelude::*; use orbtk::prelude::*;
use orbtk::shell::event::Key; use orbtk::shell::event::Key;
use tracing::{info, trace};
use std::process; use std::process;
@@ -21,88 +22,59 @@ use crate::{
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum MenuAction { pub enum MenuAction {
CreateMenu, CreateMenu,
CreateMenuToggleTheme(Entity), CreateMenuToggleTheme,
RemoveMenu, RemoveMenu,
RemoveMenuToggleTheme(Entity), RemoveMenuToggleTheme,
SetTheme SetTheme,
UpdateMenuRelativePosition
} }
/// Valid `structures` that are handled inside the state of the `Menu` widget. /// Valid `structures` that are handled inside the state of the `Menu` widget.
#[derive(AsAny, Default)] #[derive(AsAny, Default)]
pub struct MenuState { pub struct MenuState {
action: Option<MenuAction>, action: Option<MenuAction>,
menu: Entity, menu: Option<Entity>,
//menu_toggle_theme: Option<Entity>
menu_toggle_theme: Entity menu_toggle_theme: Entity
} }
/// Method definitions, that react on any given state change inside the `Menu` widget. /// Method definitions, that react on any given state change inside the `Menu` widget.
impl MenuState { impl MenuState {
/// Set a menu holding all valid menu elements /// Create a toggle_theme menu as a child of the given parent
/// The elements are ordered compontents inside a stack /// Select the active theme from a `ComboBox` offering a list of valid `themes`
pub fn create_menu(&mut self, ctx: &mut Context<'_>) { fn _create_menu_toggle_theme(&mut self, _ctx: &mut Context<'_>) {
// create a stack as a child of the given component self.action = Some(MenuAction::CreateMenuToggleTheme);
let stack = ctx
.entity_of_child(ID_MENU_BUTTON)
.expect("PolicycheckState: Can't find entity of resource 'ID_MENU_BUTTON'.");
//.entity_of_child(<PolicycheckView>ID_MENU_BUTTON)
//.expect("PolicycheckState: Can't find entity of resource 'ID_POLICY_CHECK_POPUP_MENU'.");
let current_entity = ctx.entity();
let build_context = &mut ctx.build_context();
// create a new popup menu overlay
self.menu = create_menu_popup(current_entity, build_context);
// create a menu_popup widget as a child of entity "ID_POLICY_CHECK_BUTTON_MENU"
build_context.append_child(stack, self.menu);
println!("Popup Menu created: {:?}", self.menu);
}
/// Set a toggle_theme menu
/// Select the active theme from a `ComboBox` offering a list of valid `themes``
fn create_menu_toggle_theme(&mut self, ctx: &mut Context<'_>) {
let stack = ctx
.entity_of_child(ID_MENU_LABEL_TOGGLE_THEME)
.expect("MenuState: Can't find entity of resource 'ID_MENU_LABEL_TOGGLE_THEME'.");
let current_entity = ctx.entity();
let build_context = &mut ctx.build_context();
// create a new menu overlay
self.menu_toggle_theme = create_menu_toggle_theme_popup(current_entity, build_context);
// create a menu_popup widget as a child of entity "ID_POPUP_MENU"
build_context.append_child(stack, self.menu_toggle_theme);
println!("Popup Menu Toggle Theme created: {:?}", self.menu_toggle_theme);
} }
/// Remove the menu popup box /// Remove the menu popup box
fn remove_menu(&mut self, ctx: &mut Context<'_>) { fn remove_menu(&mut self, ctx: &mut Context<'_>) {
self.action = Some(MenuAction::RemoveMenu);
ctx.remove_child(ctx.entity()); ctx.remove_child(ctx.entity());
println!("Popup {:?} removed !", ctx.entity()); println!("Popup {:?} removed.", ctx.entity());
} }
/// Remove the menu popup box /// Remove the menu popup box
fn remove_menu_toggle_theme(&mut self, id: Entity, ctx: &mut Context<'_>) { fn _remove_menu_toggle_theme(&mut self, _ctx: &mut Context<'_>) {
ctx.remove_child(self.menu_toggle_theme); self.action = Some(MenuAction::RemoveMenuToggleTheme);
println!("Popup {:?} removed !", id);
} }
/// Sets a new action. /// Sets a new action.
pub fn set_action(&mut self, action: MenuAction) { pub fn set_action(&mut self, action: MenuAction) {
self.action = action.into(); self.action = action.into();
} }
/// Update the relative position of the menu overlay
fn _update_menu_relative_position(&mut self) {
println!("TODO: Update relative position of menu {}.", ID_MENU_POPUP);
//self.action = Some(MenuAction::UpdateRelativePosition);
}
} }
/// Supported methods handled inside the `MenuState` /// Supported methods handled inside the `MenuState`
impl State for MenuState { impl State for MenuState {
/// Initialize the state of widgets inside `MenuState` // /// Initialize the state of widgets inside `MenuState`
fn init(&mut self, _: &mut Registry, _ctx: &mut Context<'_>) { // fn init(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
// Initialize required entities // }
// let menu_button = ctx
// .entity_of_child(ID_MENU_STACK)
// .expect("MenuState.init: Can't find resource entity 'PolicycheckView::ID_POLICY_CHECK_BUTTON_MENU'.");
}
/// Handle messages for the `MenuState` /// Handle messages for the `MenuState`
fn messages( fn messages(
@@ -113,6 +85,40 @@ impl State for MenuState {
) { ) {
for message in messages.read::<MenuAction>() { for message in messages.read::<MenuAction>() {
match message { match message {
MenuAction::CreateMenu => {
info!("WIP: create a menu popup in MenuState");
// assign parent entity
let parent = ctx.entity();
trace!(parent = ?parent);
//let parent_name = ctx.get_widget().get::<String16>("text");
//trace!(parent = ?parent, parent_name = ?parent_name);
// assign target -> search for a child of parent with given id
let target = ctx
.entity_of_child(ID_MENU_BUTTON_MENU)
.expect("MenuState: Can't find entity of resource 'ID_MENU_BUTTON_MENU'.");
trace!(target = ?target.0, entity_of_child = ?ID_MENU_BUTTON_MENU);
// create the target entity as child of parent
let menu_popup = create_menu_popup(parent, &mut ctx.build_context());
//let menu_popup = create_popup(target, "Testmenu Popup", &mut ctx.build_context());
// append the child to target (overlay stays on top of the main tree)
ctx.build_context()
.append_child_to_overlay(menu_popup)
.expect("Failed create an overlay that consumes popup `menu` as its child.");
self.menu = Some(menu_popup);
trace!(menu = ?self.menu);
// open: is the default
//ctx.get_widget(menu).set("open", true);
info!("CreateMenu: parent {:?}, target: {:?}, popup: {:?}", parent, target, self.menu);
}
MenuAction::SetTheme => { MenuAction::SetTheme => {
let theme_index = *MenuView::selected_index_ref(&ctx.widget()); let theme_index = *MenuView::selected_index_ref(&ctx.widget());
@@ -135,8 +141,8 @@ impl State for MenuState {
} }
} }
} }
}, }
_ => (), _ => {}
} }
} }
} }
@@ -145,18 +151,51 @@ impl State for MenuState {
fn update(&mut self, _registry: &mut Registry, ctx: &mut Context<'_>) { fn update(&mut self, _registry: &mut Registry, ctx: &mut Context<'_>) {
if let Some(action) = self.action { if let Some(action) = self.action {
match action { match action {
MenuAction::CreateMenu => { MenuAction::CreateMenuToggleTheme => {
println!("MenuAction::CreateMenu(_entity)"); let menu_target = ctx
self.create_menu(ctx); .entity_of_child(ID_MENU_LABEL_TOGGLE_THEME)
} .expect("MenuState: Can't find entity of resource 'ID_MENU_LABEL_TOGGLE_THEME'.");
MenuAction::CreateMenuToggleTheme(_entity) => { let current_entity = ctx.entity();
self.create_menu_toggle_theme(ctx); let build_context = &mut ctx.build_context();
// create a new menu popup
self.menu_toggle_theme = create_menu_toggle_theme_popup(current_entity, build_context);
// create a menu_popup widget as a child of entity "ID_POPUP_MENU"
build_context.append_child(menu_target, self.menu_toggle_theme);
ctx.get_widget(self.menu_toggle_theme).clone::<Visibility>("visibility");
println!("Popup Menu Toggle Theme created: {:?}", self.menu_toggle_theme);
} }
MenuAction::RemoveMenu => { MenuAction::RemoveMenu => {
self.remove_menu(ctx); self.remove_menu(ctx);
} }
MenuAction::RemoveMenuToggleTheme(entity) => { MenuAction::RemoveMenuToggleTheme => {
self.remove_menu_toggle_theme(entity, ctx); ctx.remove_child(self.menu_toggle_theme);
println!("Popup {:?} removed.", ctx.entity());
}
MenuAction::UpdateMenuRelativePosition => {
if let Some(menu) = self.menu {
// let theme_combo_box = ctx.entity_of_child(ID_MENU_TOGGLE_THEME).unwrap();
// let selected_index: i32 = ctx.get_widget(theme_combo_box).clone("selected_index");
// // let relative_position: RelativePosition =
// // ctx.get_widget(ID_MENU_POPUP).clone_or_default("relative_position");
// match selected_index {
// 0 => {
// RelativePosition::relative_position_mut(&mut ctx.widget()).into_bottom();
// //RelativePosition::get_mut::<MenuState>("relative_position").into_bottom();
// // ctx
// // .get_widget(self.ID_MENU_POPUP.unwrap())
// // .set("relative_position", relative_position.into_bottom());
// },
// 1 => RelativePosition::relative_position_mut(&mut ctx.widget()).into_top(),
// 2 => RelativePosition::relative_position_mut(&mut ctx.widget()).into_left(),
// 3 => RelativePosition::relative_position_mut(&mut ctx.widget()).into_right(),
// _ => panic!(),
// }
println!("Relative position of menu {:?} updated.", menu);
}
} }
_ => (), _ => (),
} }
@@ -165,14 +204,21 @@ impl State for MenuState {
} }
/// Create a new popup presenting the menu components /// Create a new popup presenting the menu components
pub fn create_menu_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity { fn create_menu_popup(target: Entity, ctx: &mut BuildContext<'_>) -> Entity {
Popup::new() Popup::new()
.id(ID_MENU_POPUP) .id(ID_MENU_POPUP)
.style("container_menu") .name(ID_MENU_POPUP)
.target(id) .target(target.0)
.open(true) .open(true)
.width(280) // WIP: this requires orbtk-develop with PR #304 (new_popup)
.height(140) // Specify the popup position relative to the target
//.relative_position(RelativePosition::Bottom(5.0))
// Reference target from given Point
//.target(Point::new(100.0,100.0))
//.style("popup_menu")
.width(300.0)
.height(100.0)
.on_key_down(move | ctx, key_event | { .on_key_down(move | ctx, key_event | {
match key_event.key { match key_event.key {
Key::Q(..) => { Key::Q(..) => {
@@ -183,7 +229,7 @@ pub fn create_menu_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
}, },
Key::Escape => { Key::Escape => {
println!("KeyHandler: got Escape"); println!("KeyHandler: got Escape");
ctx.get_mut::<MenuState>(id) ctx.get_mut::<MenuState>(target)
.set_action(MenuAction::RemoveMenu); .set_action(MenuAction::RemoveMenu);
}, },
_ => { _ => {
@@ -192,30 +238,43 @@ pub fn create_menu_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
}; };
true true
}) })
.child(
Container::new()
.child(
TextBlock::new()
//.style("popup_text_block")
.h_align("center")
.v_align("enter")
.text(ID_MENU_POPUP)
.build(ctx),
)
.build(ctx),
)
.child( .child(
Grid::new() Grid::new()
.id(ID_MENU_GRID) .id(ID_MENU_GRID)
.name(ID_MENU_GRID)
.columns( .columns(
Columns::create() Columns::create()
.push("80") // Menu Button .push("180") // Menu Button
.push("1") // Seperator .push("1") // Seperator
.push("*") // Keyboard Shortcut .push("auto") // Keyboard Shortcut
.build(),
) )
.rows( .rows(
Rows::create() Rows::create()
.push("auto") .push("auto")
.push("auto") .push("auto")
.push("auto") .push("auto")
.build(),
) )
.child( .child(
Button::new() Button::new()
.id(ID_MENU_LABEL_ACCOUNT) .id(ID_MENU_LABEL_ACCOUNT)
.name(ID_MENU_LABEL_ACCOUNT)
.style("button_menu") .style("button_menu")
//.h_align("start")
.attach(Grid::row(0)) .attach(Grid::row(0))
.attach(Grid::column(0)) .attach(Grid::column(0))
.attach(Grid::column_span(2)) //.attach(Grid::column_span(2))
.icon(material_icons_font::MD_PERSON) .icon(material_icons_font::MD_PERSON)
.text("Account") .text("Account")
.build(ctx), .build(ctx),
@@ -223,26 +282,30 @@ pub fn create_menu_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
.child( .child(
Button::new() Button::new()
.id(ID_MENU_LABEL_TOGGLE_THEME) .id(ID_MENU_LABEL_TOGGLE_THEME)
.name(ID_MENU_LABEL_TOGGLE_THEME)
.style("button_menu") .style("button_menu")
//.h_align("start")
.attach(Grid::row(1)) .attach(Grid::row(1))
.attach(Grid::column(0)) .attach(Grid::column(0))
.attach(Grid::column_span(2)) //.attach(Grid::column_span(2))
.icon(material_icons_font::MD_EDIT) .icon(material_icons_font::MD_EDIT)
.text("Toggle theme") .text("Toggle theme")
// .on_click(move |ctx, _| { .on_click(move |ctx, _| {
// ctx.get_mut::<MenuState>(id) ctx.get_mut::<MenuState>(target)
// .set_action(MenuAction::SetTheme(id)); .set_action(MenuAction::CreateMenuToggleTheme);
// true true
// }) })
.build(ctx), .build(ctx),
) )
.child( .child(
Button::new() Button::new()
.id(ID_MENU_LABEL_QUIT) .id(ID_MENU_LABEL_QUIT)
.name(ID_MENU_LABEL_QUIT)
.style("button_menu") .style("button_menu")
//.h_align("start")
.attach(Grid::row(2)) .attach(Grid::row(2))
.attach(Grid::column(0)) .attach(Grid::column(0))
.attach(Grid::column_span(2)) //.attach(Grid::column_span(2))
.icon(material_icons_font::MD_SETTINGS_POWER) .icon(material_icons_font::MD_SETTINGS_POWER)
.text("Quit") .text("Quit")
.on_mouse_down(move |_states, _| { .on_mouse_down(move |_states, _| {
@@ -253,7 +316,8 @@ pub fn create_menu_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
.child( .child(
TextBlock::new() TextBlock::new()
.id(ID_MENU_SHORTCUT_QUIT) .id(ID_MENU_SHORTCUT_QUIT)
.style("button_menu") .name(ID_MENU_SHORTCUT_QUIT)
//.style("button_menu")
.attach(Grid::row(2)) .attach(Grid::row(2))
.attach(Grid::column(2)) .attach(Grid::column(2))
.margin((0, 0, 16, 0)) .margin((0, 0, 16, 0))
@@ -267,30 +331,93 @@ pub fn create_menu_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
.build(ctx) .build(ctx)
} }
fn _create_popup(target: Entity, text: &str, ctx: &mut BuildContext<'_>) -> Entity {
Popup::new()
.id("test_popup")
.name("Test Popup")
// Reference target from given Entity
.target(target.0)
// Reference target from given Point
//.target(Point::new(0.0, 5.0))
// Specify the popup position relative to the target (the button in this case)
//.relative_position(RelativePosition::Bottom(5.0))
.open(true)
.style("popup_form")
.width(350.0)
.height(100.0)
.child(
Container::new()
.child(
TextBlock::new()
//.style("popup_text_block")
.h_align("center")
.text(text)
.build(ctx),
)
.build(ctx),
)
.build(ctx)
}
/// Create a new popup submenu to toogle the active theme /// Create a new popup submenu to toogle the active theme
pub fn create_menu_toggle_theme_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity { fn create_menu_toggle_theme_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
//let themes_count = themes.len(); cfg_if! {
//ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), new_width); if #[cfg(windows)] {
// define the list of supported themes
let themes = vec![
"default_dark".to_string(),
"default_light".to_string(),
"redox".to_string(),
"fluent_dark".to_string(),
"fluent_light".to_string()
];
} else {
// define the list of supported themes
let themes = vec![
"default_dark".to_string(),
"default_light".to_string(),
"redox".to_string(),
];
}
}
let themes_count = themes.len();
Popup::new() Popup::new()
.id(ID_MENU_TOGGLE_THEME) .id(ID_MENU_TOGGLE_THEME)
.target(id.0)
.style("container_menu") .style("container_menu")
.target(id)
.open(true)
.width(280) .width(280)
.height(140) .height(140)
.on_key_down(move | _ctx, key_event | {
match key_event.key {
Key::Escape => {
println!("KeyHandler: got Escape");
//ctx.get_mut::<MenuState>(id)
// .set_action(MenuAction::RemoveMenuToggleTheme);
},
_ => {
println!("KeyHandler: got {:?}", key_event.key);
},
};
true
})
.child( .child(
ComboBox::new() ComboBox::new()
.attach(Grid::column(2)) .attach(Grid::column(2))
.attach(Grid::row(6)) .attach(Grid::row(6))
//.count(themes_count) .count(themes_count)
.items_builder(move |build_ctx, index| { .style("combo_box_form")
.items_builder(move |ctx, index| {
let theme_name = let theme_name =
MenuView::themes_ref(&build_ctx.get_widget(id))[index].clone(); MenuView::themes_ref(&ctx.get_widget(id))[index].clone();
TextBlock::new().v_align("center").text(theme_name).build(build_ctx) TextBlock::new().v_align("center").text(theme_name).build(ctx)
}) })
.on_changed("selected_index", move |ctx, _| { .on_changed("selected_index", move |states, _entity| {
ctx.send_message(MenuAction::SetTheme, id); states.send_message(MenuAction::SetTheme, id);
println!("changed theme."); println!("changed theme.");
}) })
.selected_index(id) .selected_index(id)

View File

@@ -5,7 +5,6 @@
* SPDX-License-Identifier: (0BSD or MIT) * SPDX-License-Identifier: (0BSD or MIT)
*/ */
use cfg_if::cfg_if;
use orbtk::prelude::*; use orbtk::prelude::*;
use crate::data::constants::*; use crate::data::constants::*;
@@ -27,56 +26,102 @@ widget!(
/// All GUI elements are styled using the "style" attribute referencing to a ron based css /// All GUI elements are styled using the "style" attribute referencing to a ron based css
impl Template for MenuView { impl Template for MenuView {
fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self { fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self {
cfg_if! { let menu_bottom_bar = Container::new()
if #[cfg(windows)] { .id(ID_MENU_BOTTOM_BAR)
// define the list of supported themes .style(STYLE_BOTTOM_BAR)
let themes = vec![ .attach(Grid::row(3))
"default_dark".to_string(), .attach(Grid::column(1))
"default_light".to_string(), .attach(Grid::column_span(2))
"redox".to_string(), .v_align("end")
"fluent_dark".to_string(), .child(
"fluent_light".to_string() Container::new()
]; .child( Container::new()
} else { .margin((0, 16, 16, 0))
// define the list of supported themes .v_align("center")
let themes = vec![ .child(
"default_dark".to_string(), ImageWidget::new()
"default_light".to_string(), .image("assets/advotracker/hiedemann_logo.png")
"redox".to_string(), .v_align("center")
]; .build(ctx),
} )
} .build(ctx),
)
.build(ctx),
)
.child(
Container::new()
.attach(Grid::column(1))
.h_align("end")
.v_align("end")
.child(
TextBlock::new()
.margin((0, 9, 48, 0))
.text("©Networkx GmbH")
.build(ctx)
)
.build(ctx),
)
.build(ctx);
let menu_button_menu = Button::new()
.id(ID_MENU_BUTTON_MENU)
.name(ID_MENU_BUTTON_MENU)
.style("button_single_content")
.icon(material_icons_font::MD_MENU)
.attach(Grid::column(2))
//.min_size(16, 16)
//.h_align("end")
.h_align("start")
.on_click(move |ctx, _| {
ctx.send_message(MenuAction::CreateMenu, id);
true
})
.build(ctx);
let menu_header_bar = Container::new()
.id(ID_MENU_HEADER_BAR)
.style(STYLE_HEADER_BAR)
.attach(Grid::row(0))
.attach(Grid::column(1))
.attach(Grid::column_span(2))
.child(
Grid::new()
.child(
TextBlock::new()
.style("header")
.id(ID_MENU_HEADER)
.v_align("center")
.h_align("left")
.text("Ticket Data")
.build(ctx),
)
.build(ctx),
)
.child(menu_button_menu)
.build(ctx);
//self.themes(themes).child(MenuState::create_menu(ID_MENU_POPUP, ctx)) //self.themes(themes).child(MenuState::create_menu(ID_MENU_POPUP, ctx))
self.themes(themes).child( self.name("MenuView")
Stack::new() .child(
.id(ID_MENU_STACK) Grid::new()
.child( .id(ID_MENU_VIEW)
TextBlock::new() .columns(
.style("header") Columns::create()
.attach(Grid::row(0)) .push(50) // Left margin
.attach(Grid::column(0)) .push("*") // Content
.style("small_text") .push(50) // Right margin
.text("Select theme") )
.build(ctx), .rows(
) Rows::create()
.child( .push("auto") // Header_Bar
Button::new() .push(28) // Seperator
//.id("button_menu") .push("*") // InputForm
.id(ID_MENU_BUTTON) .push("auto") // Bottom_Bar
.style("button_single_content") )
.icon(material_icons_font::MD_MENU)
.attach(Grid::column(2)) .child(menu_header_bar) // Row 0
.h_align("end") .child(menu_bottom_bar) // Row 3
.on_click(move |ctx, _| { .build(ctx),
println!("WIP: open menu popup from MenuView"); )
ctx.get_mut::<MenuState>(id)
.set_action(MenuAction::CreateMenu);
true
})
.build(ctx),
)
.build(ctx),
)
} }
} }

View File

@@ -28,3 +28,6 @@ pub mod policycheck;
// /// Policylists widget. // /// Policylists widget.
// pub mod policylist; // pub mod policylist;
/// Ticketdata wigdet.
pub mod ticketdata;

View File

@@ -19,30 +19,37 @@ use crate::{
structures::{PolicyCode, PolicyDataList, PolicyList}, structures::{PolicyCode, PolicyDataList, PolicyList},
constants::*, constants::*,
}, },
widgets::global_state::GlobalState,
//widgets::menu::menu_view::MenuView,
//services::imports::allianzdirectcall::import, //services::imports::allianzdirectcall::import,
services::imports::allianzdirectcall, services::imports::allianzdirectcall,
widgets::global_state::GlobalState,
//widgets::menu::menu_view::MenuView,
//widgets::policycheck::policycheck_view::PolicycheckView,
//widgets::ticketdata::ticketdata_state::TicketdataAction,
}; };
/// Valid `actions` that are handled as state changes in the `Policycheck` widget. /// Enumeration of valid `action variants` that need to be handled as
#[derive(Debug, Clone, Copy)] /// state changes for the `PolicycheckView` widget.
#[derive(Debug, Clone)]
pub enum PolicycheckAction { pub enum PolicycheckAction {
AddProgress(f64),
ClearEntry(Entity), ClearEntry(Entity),
ChangeTheme(), ChangeTheme(),
SendPolicynumber(),
InputTextChanged(Entity), InputTextChanged(Entity),
ImportData, ImportData,
ParseEntry(Entity), NewTicket,
ParsePolicyNumber(Entity),
RemoveFocus(Entity), RemoveFocus(Entity),
RemovePopup(Entity), RemovePopup(Entity),
ResetProgress, ResetProgress,
GetProgress,
SetProgress(f64), SetProgress(f64),
SetProgressPopup(Entity), SetProgressPopup(Entity),
SetToggleTheme(Entity), SetToggleTheme(Entity),
SetEntry(Entity), SetEntry(Entity),
SetVisibility(Entity), SetVisibility(Entity),
TextChanged(Entity, usize) TextChanged(Entity, usize),
UpdatePolicyCode,
UpdateProgress(f64)
} }
/// Define valid environment variables provided via .env files /// Define valid environment variables provided via .env files
@@ -57,16 +64,20 @@ struct Environment {
/// Valid `structures` that are handled inside the state of the `Policycheck` widget. /// Valid `structures` that are handled inside the state of the `Policycheck` widget.
#[derive(AsAny, Default)] #[derive(AsAny, Default)]
pub struct PolicycheckState { pub struct PolicycheckState {
action: Option<PolicycheckAction>, actions: Vec<PolicycheckAction>,
button_menu: Entity,
duration: Duration, duration: Duration,
label_result: Entity, label_result: Entity,
lang: String, lang: String,
button_menu: Entity,
policy_data_count: u64, policy_data_count: u64,
//policy_number: Entity,
policy_numbers: HashMap<u64, PolicyCode>, policy_numbers: HashMap<u64, PolicyCode>,
progress_bar: Entity, progress_bar: Entity,
progress_count: f64, progress_count: f64,
progress_popup: Entity progress_popup: Entity,
// target that recieves messages
target: Entity,
ticketdata: Entity
} }
impl GlobalState for PolicycheckState {} impl GlobalState for PolicycheckState {}
@@ -74,7 +85,8 @@ impl GlobalState for PolicycheckState {}
/// Method definitions, that react on any given state change inside the `Policycheck` widget. /// Method definitions, that react on any given state change inside the `Policycheck` widget.
impl PolicycheckState { impl PolicycheckState {
/// Create a hashmap (key: policy number, value: policy type). /// Create a hashmap (key: policy number, value: policy type).
pub fn create_hashmap(&mut self, _ctx: &mut Context<'_>) -> 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"); trace!(target: "advotracker", create_hashmap = "started");
let policy_list = PolicyList::new("policy list"); let policy_list = PolicyList::new("policy list");
@@ -123,20 +135,19 @@ impl PolicycheckState {
-> Result<(), Box<dyn std::error::Error>> { -> Result<(), Box<dyn std::error::Error>> {
// WIP: for now, only import once per session // WIP: for now, only import once per session
if self.policy_data_count == 0 { if self.policy_data_count == 0 {
TextBlock::enabled_set(&mut ctx.child(ID_POLICY_CHECK_RESULT), true); TextBlock::enabled_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), true);
if self.policy_numbers.len() == 0 { if self.policy_numbers.is_empty() {
// initialize popup widget // initialize popup widget
self.set_popup_progress(ctx); self.set_popup_progress(ctx);
self.progress_count += 0.33; self.progress_count += 0.33;
self.update_progress_bar(ctx); self.update_progress_bar(ctx);
//sender.send(WindowRequest::Redraw).unwrap();
// for _ in 1..4 { for _ in 1..4 {
// self.progress_count += 0.33; self.progress_count += 0.33;
// self.update_progress_bar(ctx); self.update_progress_bar(ctx);
// sender.send(WindowRequest::Redraw).unwrap(); ctx.send_message(PolicycheckAction::UpdateProgress(self.progress_count), self.progress_popup);
//} }
// importing policy code elements from csv-file // importing policy code elements from csv-file
match self.create_hashmap(ctx) { match self.create_hashmap(ctx) {
@@ -150,7 +161,6 @@ impl PolicycheckState {
self.progress_count = 1.; self.progress_count = 1.;
self.update_progress_bar(ctx); self.update_progress_bar(ctx);
//sender.send(WindowRequest::Redraw).unwrap();
} }
_ => { _ => {
let res = t!("policy.hashmap.failed", self.lang); let res = t!("policy.hashmap.failed", self.lang);
@@ -168,12 +178,20 @@ impl PolicycheckState {
Ok(()) Ok(())
} }
/// Create new ticket
pub fn new_ticket(&mut self, ctx: &mut Context<'_>) {
println!("WIP: new ticket.");
self(ticketdata_view.0);
//ctx.widget().get_mut::<TicketdataView>(0).
//ctx.get_widget(self.ticketdata_view);
}
/// Parse validity of the given policy number. /// Parse validity of the given policy number.
fn parse_entry(&mut self, policy_check_policy_number: Entity, pub fn parse_entry(&mut self, policy_check_policy_number: Entity,
ctx: &mut Context<'_>) { ctx: &mut Context<'_>) {
trace!(target: "advotracker", parse_entry = "started"); trace!(target: "advotracker", parse_entry = "started");
let policy_number_string = TextBox::text_clone(&mut ctx.get_widget(policy_check_policy_number)); let policy_number_string = TextBox::text_clone(&ctx.get_widget(policy_check_policy_number));
let policy_number_length = policy_number_string.len(); let policy_number_length = policy_number_string.len();
if self.policy_data_count == 0 { if self.policy_data_count == 0 {
@@ -195,20 +213,13 @@ impl PolicycheckState {
// Parse policy code: "AS-123456789" // Parse policy code: "AS-123456789"
// DION VERS POLLFNR // DION VERS POLLFNR
// 1 AS 1515735810 // 1 AS 1515735810
//Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_1), Visibility::Collapsed);
//Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Collapsed);
//TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed);
//TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_RESULT), Visibility::Collapsed);
//TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_HINT), Visibility::Collapsed);
//TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Collapsed);
Button::background_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("transparent")); Button::background_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("transparent"));
//Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Collapsed);
if policy_number_length == 10 { if policy_number_length == 10 {
// cast policy_number_sting to <u64> // cast policy_number_sting to <u64>
match policy_number_string.parse::<u64>() { match policy_number_string.parse::<u64>() {
Ok(p) => { Ok(p) => {
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_RESULT), String::from("")); TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), String::from(""));
// match hashmap's key // match hashmap's key
match self.policy_numbers.get(&p) { match self.policy_numbers.get(&p) {
@@ -219,7 +230,7 @@ impl PolicycheckState {
let string_result = format!("1-{:?}-{}", let string_result = format!("1-{:?}-{}",
policy_code, p); policy_code, p);
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_RESULT), String::from(string_result)); TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), string_result);
TextBox::foreground_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_NUMBER), String::from("#008000")); TextBox::foreground_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_NUMBER), String::from("#008000"));
Button::icon_brush_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("#008000")); Button::icon_brush_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("#008000"));
@@ -227,8 +238,10 @@ impl PolicycheckState {
Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CHECK); Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CHECK);
Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible); Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_1), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Visible);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), Visibility::Visible);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Collapsed);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_HINT), Visibility::Collapsed);
} }
_ => { _ => {
// no matching key // no matching key
@@ -243,8 +256,10 @@ impl PolicycheckState {
Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CLEAR); Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CLEAR);
Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible); Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_1), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), Visibility::Collapsed);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Visible);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_HINT), Visibility::Visible);
} }
} }
}, },
@@ -253,17 +268,17 @@ impl PolicycheckState {
TextBox::foreground_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_NUMBER), String::from("#FF0000")); TextBox::foreground_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_NUMBER), String::from("#FF0000"));
//TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_HINT), Visibility::Visible);
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_HINT), String::from("Only numbers are valid")); TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_HINT), String::from("Only numbers are valid"));
//TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Visible);
Button::icon_brush_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("#FF0000")); Button::icon_brush_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("#FF0000"));
Button::foreground_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("#FF0000")); Button::foreground_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("#FF0000"));
Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CLEAR); Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CLEAR);
Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible); Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_1), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), Visibility::Collapsed);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Visible);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_HINT), Visibility::Visible);
} }
} }
} }
@@ -282,8 +297,10 @@ impl PolicycheckState {
Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CLEAR); Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CLEAR);
Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible); Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_1), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), Visibility::Collapsed);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Visible);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_HINT), Visibility::Visible);
} }
if policy_number_length > 10 { if policy_number_length > 10 {
let res = t!("policy.validation.failed", self.lang); let res = t!("policy.validation.failed", self.lang);
@@ -300,13 +317,20 @@ impl PolicycheckState {
Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CLEAR); Button::icon_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), material_icons_font::MD_CLEAR);
Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible); Button::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_1), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), Visibility::Collapsed);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Visible);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_HINT), Visibility::Visible);
} }
trace!(target: "advotracker", parse_entry = "finished"); trace!(target: "advotracker", parse_entry = "finished");
} }
/// parse message 'ParseEntry'
pub fn parse_policy_number(&mut self, entity: Entity) {
self.actions.push(PolicycheckAction::ParsePolicyNumber(entity));
}
/// Remove the popup box /// Remove the popup box
fn remove_popup(&mut self, id: Entity, ctx: &mut Context<'_>) { fn remove_popup(&mut self, id: Entity, ctx: &mut Context<'_>) {
ctx.remove_child(self.progress_popup); ctx.remove_child(self.progress_popup);
@@ -326,19 +350,23 @@ impl PolicycheckState {
// ctx.get_widget(self.policy_check_policy_number).update_theme_by_state(true); // ctx.get_widget(self.policy_check_policy_number).update_theme_by_state(true);
// } // }
/// Sets a new action. /// Sending message 'UpdatePolicyCode'
pub fn set_action(&mut self, action: PolicycheckAction) { pub fn send_message_update_policy_code(&mut self, entity: Entity) {
self.action = action.into(); println!("WIP: send_message_update_policy_code = {:?}", entity);
//self.actions.push(PolicycheckAction::UpdatePolicyNumber("4711".to_string()));
//let policy_number = (ctx.get_child(entity).get::<String>("text"));
//println!("WIP: poliy_number = {:?}", policy_number);
//self.actions.push(PolicycheckAction::UpdatePolicyNumber(self.policy_number));
} }
/// Change status of given text box to edit mode. /// Change status of given text box to edit mode.
fn set_entry(&mut self, text_box: Entity, ctx: &mut Context<'_>) { fn set_entry(&mut self, text_box: Entity, ctx: &mut Context<'_>) {
if ctx.get_widget(text_box).get::<String16>("text").is_empty() { if ctx.get_widget(text_box).get::<String16>("text").is_empty() {
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), Visibility::Collapsed);
} else { } else {
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Visible);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), Visibility::Visible);
} }
} }
@@ -353,18 +381,16 @@ impl PolicycheckState {
// create the progress_popup widget // create the progress_popup widget
self.progress_popup = create_popup_progress(current_entity, build_context); self.progress_popup = create_popup_progress(current_entity, build_context);
println!("New entity `progress_popup` created: {:?}", self.progress_popup); info!("set_popup_progress: New entity 'popup_progress' {:?} created", self.progress_popup);
// append the stack inside the progress_popup // append the stack inside the progress_popup
build_context.append_child(stack, self.progress_popup); build_context.append_child(stack, self.progress_popup);
// make sure we have a // make sure we have a progress bar
self.progress_bar = ctx self.progress_bar = ctx
.entity_of_child(ID_POLICY_CHECK_PROGRESS_BAR) .entity_of_child(ID_POLICY_CHECK_PROGRESS_BAR)
.expect("PolicycheckState.init: Can't find entity of resource 'ID_POLICY_CHECK_PROGRESS_BAR'."); .expect("PolicycheckState.init: Can't find entity of resource 'ID_POLICY_CHECK_PROGRESS_BAR'.");
println!("New entity `progress_bar` created: {:?}", self.progress_bar); info!("set_popup_progress: New entity 'progress_bar' created: {:?}", self.progress_bar);
println!("function `set_popup_progress()` finished!");
} }
/// Change visibility of the result label. /// Change visibility of the result label.
@@ -376,8 +402,6 @@ impl PolicycheckState {
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Visible);
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Visible);
} }
//ctx.get_widget(self.label_result).update_theme_by_state(true);
} }
/// Update count of elements in the policy data list. /// Update count of elements in the policy data list.
@@ -390,11 +414,19 @@ impl PolicycheckState {
let res = t!("policy.string.progress_time", self.lang); let res = t!("policy.string.progress_time", self.lang);
let string_duration = format!("{}: {:?}", res, self.duration); let string_duration = format!("{}: {:?}", res, self.duration);
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_TIME), String::from(string_duration)); TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_TIME), string_duration);
let mut progress_bar = ctx.child(ID_POLICY_CHECK_PROGRESS_BAR); let mut progress_bar = ctx.child(ID_POLICY_CHECK_PROGRESS_BAR);
progress_bar.set::<f64>("val", self.progress_count); progress_bar.set::<f64>("val", self.progress_count);
} }
/// Update the policy code policy data list.
fn update_policy_code(&self, _ctx: &mut Context<'_>) {
println!("update internal: policy_code");
//let policy_code = ctx.widget().get::<PolicycheckState>(ID_POLICY_CHECK_POLICY_CODE);
//ctx.widget().set(PROP_POLICY_DATA_COUNT, policy_code);
}
} }
/// Supported methods handled inside the `PolicycheckState` /// Supported methods handled inside the `PolicycheckState`
@@ -405,24 +437,32 @@ impl State for PolicycheckState {
trace!(target: "advotracker", policycheck_state = "init", status = "started"); trace!(target: "advotracker", policycheck_state = "init", status = "started");
// Get language from environment
self.lang = PolicycheckState::get_lang();
// Initialize required entities // Initialize required entities
self.button_menu = ctx self.button_menu = ctx
.entity_of_child(ID_POLICY_CHECK_BUTTON_MENU) .entity_of_child(ID_POLICY_CHECK_BUTTON_MENU)
.expect("PolicycheckState.init: Can't find resource entity 'ID_POLICY_CHECK_BUTTON_MENU'."); .expect("PolicycheckState::init: Can't find resource entity 'ID_POLICY_CHECK_BUTTON_MENU'.");
self.label_result = ctx self.label_result = ctx
.entity_of_child(ID_POLICY_CHECK_LABEL_RESULT) .entity_of_child(ID_POLICY_CHECK_LABEL_RESULT)
.expect("PolicycheckState.init: Can't find resource entity 'ID_POLICY_CHECK_LABEL_RESULT'."); .expect("PolicycheckState::init: Can't find resource entity 'ID_POLICY_CHECK_LABEL_RESULT'.");
//TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed);
//TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_CODE), Visibility::Collapsed);
//Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_0), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_HINT), Visibility::Collapsed);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_1), Visibility::Collapsed); TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Collapsed);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Collapsed);
// Preset localization with given environment lang //self.policy_number = Entity::from(ctx.widget().try_clone::<u32>(ID_POLICY_CHECK_POLICY_NUMBER)
self.lang = PolicycheckState::get_lang(); // .expect("PolicycheckState::init(): Can't find resource entity 'ID_POLICY_CHECK_POLICY_NUMBER'."));
ctx.set_language(&self.lang);
self.target = Entity::from(ctx.widget().try_clone::<u32>("target")
.expect("PolicycheckState::init(): Can't find resource entity 'target'."));
//self.ticketdata_view = (*ctx.widget().get::<u32>("ticketdata_view")).into();
//self.ticketdata = Entity::from(ctx.widget().try_clone::<u32>(ID_TICKET_DATA_VIEW)
// .expect("PolicycheckState::init(): Can't find resource entity 'ticketdata'."));
// // Load the saved data from a file in 'ron' format into our data structure. // // Load the saved data from a file in 'ron' format into our data structure.
// // The cargo package identifier (default: 'nwx.advotracker') is used as the // // The cargo package identifier (default: 'nwx.advotracker') is used as the
@@ -451,8 +491,8 @@ impl State for PolicycheckState {
) { ) {
for message in messages.read::<PolicycheckAction>() { for message in messages.read::<PolicycheckAction>() {
match message { match message {
PolicycheckAction::AddProgress(increment) => { PolicycheckAction::UpdateProgress(increment) => {
let old_width = ProgressBar::val_clone(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR)); let old_width = ProgressBar::val_clone(&ctx.child(ID_POLICY_CHECK_PROGRESS_BAR));
let new_width = old_width + increment; let new_width = old_width + increment;
// Set the ProgressBar's val property to the calculated percentage // Set the ProgressBar's val property to the calculated percentage
@@ -463,7 +503,13 @@ impl State for PolicycheckState {
ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), 1.); ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), 1.);
} }
} }
_ => (), PolicycheckAction::UpdatePolicyCode => {
self.update_policy_code(ctx);
}
PolicycheckAction::NewTicket => {
self.new_ticket(ctx);
}
_ => { println!("PolicycheckAction: action not implemented!"); }
} }
} }
} }
@@ -480,7 +526,10 @@ impl State for PolicycheckState {
// } // }
//} //}
if let Some(action) = self.action { // Create `actions`, a drained iterator (".." => full range that clears the vector)
let actions: Vec<PolicycheckAction> = self.actions.drain(..).collect();
for action in actions {
match action { match action {
PolicycheckAction::ClearEntry(policy_check_policy_number) => { PolicycheckAction::ClearEntry(policy_check_policy_number) => {
ctx.get_widget(policy_check_policy_number).set("enabled", false); ctx.get_widget(policy_check_policy_number).set("enabled", false);
@@ -499,7 +548,10 @@ impl State for PolicycheckState {
} }
} }
} }
PolicycheckAction::ParseEntry(text_box) => { PolicycheckAction::NewTicket => {
self.new_ticket(ctx);
}
PolicycheckAction::ParsePolicyNumber(text_box) => {
self.parse_entry(text_box, ctx); self.parse_entry(text_box, ctx);
} }
PolicycheckAction::RemoveFocus(policy_check_policy_number) => { PolicycheckAction::RemoveFocus(policy_check_policy_number) => {
@@ -507,7 +559,6 @@ impl State for PolicycheckState {
//ctx.EventAdapter(FocusEvent::RemoveFocus(policy_check_policy_number)); //ctx.EventAdapter(FocusEvent::RemoveFocus(policy_check_policy_number));
} }
PolicycheckAction::RemovePopup(entity) => { PolicycheckAction::RemovePopup(entity) => {
//println!("WIP: remove popup");
self.remove_popup(entity, ctx); self.remove_popup(entity, ctx);
} }
PolicycheckAction::ResetProgress => { PolicycheckAction::ResetProgress => {
@@ -532,11 +583,31 @@ impl State for PolicycheckState {
PolicycheckAction::TextChanged(entity, _index) => { PolicycheckAction::TextChanged(entity, _index) => {
self.set_entry(entity, ctx); self.set_entry(entity, ctx);
} }
PolicycheckAction::UpdatePolicyCode => {
self.update_policy_code(ctx);
//info!("Message send: 'PolicycheckAction::UpdatePolicyNumber({:?}) -> {:?}'", policy_number, self.target);
//let policy_number = (&mut ctx.get_widget(entity).get::<String>("text"));
//let policy_number = ctx.get_widget(ID_POLICY_CHECK_POLICY_NUMBER).get::<text>("text");
//ctx.send_message(PolicycheckAction::UpdatePolicyCode("AS-1-4711".to_string()), self.target);
//ctx.send_message(PolicycheckAction::UpdatePolicyCode, self.target);
//let mut widget_container : WidgetContainer = ctx.widget();
//widget_container.get::<String16>("text");
//let polnum: TextBox = TextBox::get(ctx.child(ID_POLICY_CHECK_POLICY_NUMBER));
//println!("Policy number: {:?}", polnum);
//let policy_number = ctx.get_widget(self.policy_check_policy_number);
//let policy_number2 = TextBox::text_clone(&ctx.get_widget(ID_POLICY_CHECK_POLICY_NUMBER));
//let policy_number_string = ctx.get_widget(entity).get::<String16>("text").is_empty();
//let policy_number = TextBox::text_clone(&mut ctx.child(ID_POLICY_CHECK_POLICY_NUMBER));
//ctx.send_message(PolicycheckAction::UpdatePolicyNumber(policy_check_policy_number), self.target);
//info!("Message send: 'PolicycheckAction::UpdatePolicyNumber({:?}) -> {:?}'", policy_check_policy_number, self.target);
}
_ => (), _ => (),
} }
} }
// Reset action
self.action = None;
} }
// /// Update the view after the layout is rendered. // /// Update the view after the layout is rendered.
@@ -548,15 +619,16 @@ impl State for PolicycheckState {
fn create_popup_progress(id: Entity, ctx: &mut BuildContext<'_>) -> Entity { fn create_popup_progress(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
Popup::new() Popup::new()
.id(ID_POLICY_CHECK_POPUP_PROGRESS) .id(ID_POLICY_CHECK_POPUP_PROGRESS)
.target(id) .target(id.0)
.open(true) .open(true)
.style("popup_progress") .style("popup_progress")
.width(280) .width(280)
.height(100) .height(100)
.on_click(move |ctx, _| { .visibility(Visibility::Visible)
.on_click(move |_ctx, _| {
println!("create_popup_progress: on_click -> remove_popup(popup_progress)"); println!("create_popup_progress: on_click -> remove_popup(popup_progress)");
ctx.get_mut::<PolicycheckState>(id) //ctx.get_mut::<PolicycheckState>(id)
.set_action(PolicycheckAction::RemovePopup(id)); // .set_action(PolicycheckAction::RemovePopup(id));
true true
}) })
.child( .child(

View File

@@ -23,10 +23,16 @@ widget!(
/// This identifier is checked agains a map of valid policy codes. /// This identifier is checked agains a map of valid policy codes.
// PolicycheckView<PolicycheckState>: KeyDownHandler { // PolicycheckView<PolicycheckState>: KeyDownHandler {
PolicycheckView<PolicycheckState> { PolicycheckView<PolicycheckState> {
// holds the language code
lang: String, lang: String,
// provides a struct with `PolicyCheck` members
policy_check: PolicyCheck, policy_check: PolicyCheck,
// holds number of imported data
policy_data_count: u32,
// holds the title string
policy_check_title: String, policy_check_title: String,
policy_data_count: u32 // widget entity that will receive the message
target: u32
} }
); );
@@ -35,27 +41,26 @@ widget!(
impl Template for PolicycheckView { impl Template for PolicycheckView {
//fn template(self, policycheck_view: Entity, ctx: &mut BuildContext<'_>) -> Self { //fn template(self, policycheck_view: Entity, ctx: &mut BuildContext<'_>) -> Self {
fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self { fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self {
let tenent_logo = Container::new()
.margin((16, 16, 0, 0))
.attach(Grid::column(0))
.v_align("center")
.child(
ImageWidget::new()
.image("assets/advotracker/hiedemann_logo.png")
.v_align("center")
.build(ctx),
)
.build(ctx);
let policy_check_bottom_bar = Container::new() let policy_check_bottom_bar = Container::new()
.id(ID_POLICY_CHECK_BOTTOM_BAR)
//.style(STYLE_BOTTOM_BAR) //.style(STYLE_BOTTOM_BAR)
.padding(14)
.attach(Grid::row(4)) .attach(Grid::row(4))
.attach(Grid::column(1)) .attach(Grid::column(1))
.attach(Grid::column_span(2)) .attach(Grid::column_span(2))
.v_align("end") .v_align("end")
.child(
Container::new()
.child( Container::new()
.margin((0, 16, 16, 0))
.v_align("center")
.child(
ImageWidget::new()
.image("assets/advotracker/hiedemann_logo.png")
.v_align("center")
.build(ctx),
)
.build(ctx),
)
.build(ctx),
)
.child( .child(
Container::new() Container::new()
.attach(Grid::column(1)) .attach(Grid::column(1))
@@ -89,235 +94,178 @@ impl Template for PolicycheckView {
let policy_check_button_result = Button::new() let policy_check_button_result = Button::new()
.id(ID_POLICY_CHECK_BUTTON_RESULT) .id(ID_POLICY_CHECK_BUTTON_RESULT)
.style("button_single_content") .style("button_single_content")
.attach(Grid::row(0))
.attach(Grid::column(3))
.h_align("start") .h_align("start")
.v_align("center") .v_align("center")
.visibility(Visibility::Collapsed) .visibility(Visibility::Collapsed)
.enabled(false) .enabled(false)
.build(ctx); .build(ctx);
let policy_check_header_text = TextBlock::new()
.id(ID_POLICY_CHECK_HEADER)
.attach(Grid::column(0))
.style(STYLE_HEADER_TEXT)
.text("Validation policy number")
.build(ctx);
let policy_check_header_bar = Container::new() let policy_check_header_bar = Container::new()
.style(STYLE_HEADER_BAR) .id(ID_POLICY_CHECK_HEADER_BAR)
.attach(Grid::row(0)) .attach(Grid::row(0))
.attach(Grid::column(1)) .attach(Grid::column_span(3))
.attach(Grid::column_span(2)) .style(STYLE_HEADER_BAR)
.child( .child(tenent_logo)
Grid::new() .child(policy_check_header_text)
.child(
TextBlock::new()
.style("header")
.id(ID_POLICY_CHECK_HEADER)
.v_align("center")
.h_align("left")
.text("Validation policy number")
.build(ctx),
)
.build(ctx),
)
.child(policy_check_button_menu) .child(policy_check_button_menu)
.build(ctx); .build(ctx);
let policy_check_form_row_0 = Stack::new() let policy_check_policy_code = TextBlock::new()
// 1st row .id(ID_POLICY_CHECK_POLICY_CODE)
.id(ID_POLICY_CHECK_FORM_ROW_0) .style("body")
.attach(Grid::row(0))
.attach(Grid::column(0))
.attach(Grid::column_span(5))
.orientation("horizontal")
.v_align("center")
//.h_align("center")
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_LABEL_POLICY_NUMBER)
.style("body")
.attach(Grid::row(0))
.attach(Grid::column(0))
.margin((0, 0, 16, 0))
.h_align("end")
.v_align("center")
.width(300)
.min_width(300)
.text("Policy number")
.build(ctx),
)
.child(
TextBox::new()
.attach(Grid::row(0))
.attach(Grid::column(2))
.id(ID_POLICY_CHECK_POLICY_NUMBER)
.h_align("start")
.lose_focus_on_activation(false)
//WIP: localization for water_mark
.water_mark("10-stellig")
.on_activate(move |ctx, entity| {
// Entity is entered/activated via Mouse/Keyboard
//ctx.get_mut::<PolicycheckState>(policy_check_view)
ctx.get_mut::<PolicycheckState>(id)
.set_action(PolicycheckAction::ParseEntry(entity));
})
//.on_changed(|_, entity, _, _| println!("Selection changed: {:?}", entity))
// .on_changed(move |ctx, entity, _| {
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::SetProgressBox(entity));
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::AddProgress(0.5));
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::InputTextChanged(entity));
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::SetVisibility(entity));
// ctx.get_widget(policy_check_label_policy_number).set("visible");
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::SetVisility(entity));
// })
// .on_mouse_down | .on_mouse_move | .on_mouse_up (move |ctx, entity| {
// state(id, states).set_action(Action::AddItem);
// })
.on_key_down(move |_, key_event| {
if key_event.key == Key::A(true) {
println!("A key down");
}
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::ImportData);
true
})
.build(ctx),
)
.child(policy_check_button_result)
.build(ctx);
let policy_check_form_row_1 = Stack::new()
// 2nd row
.id(ID_POLICY_CHECK_FORM_ROW_1)
.attach(Grid::row(1))
.attach(Grid::column(0))
.attach(Grid::column_span(5))
.orientation("horizontal")
.v_align("center")
//.h_align("center")
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_LABEL_RESULT)
.style("body")
.attach(Grid::row(1))
.attach(Grid::column(0))
.margin((0, 0, 16, 0))
.h_align("end")
.v_align("center")
.width(300)
.min_width(300)
.text("Policy code")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_RESULT)
.style("body")
.attach(Grid::row(1))
.attach(Grid::column(2))
.h_align("start")
.v_align("center")
.text("empty")
.build(ctx)
)
.build(ctx);
let policy_check_form_row_2 = Stack::new()
// 3nd row
.id(ID_POLICY_CHECK_FORM_ROW_2)
.attach(Grid::row(2)) .attach(Grid::row(2))
.attach(Grid::column(0)) .attach(Grid::column(2))
.attach(Grid::column_span(5)) .build(ctx);
.orientation("horizontal")
.v_align("center") let policy_check_form_action = Container::new()
.id(ID_POLICY_CHECK_ACTION_GRID)
.attach(Grid::row(3))
.attach(Grid::column(1))
//.style(STYLE_CONTAINER_ACTION)
.padding(14)
.h_align("center") .h_align("center")
.child( .child(
TextBlock::new() Stack::new()
.id(ID_POLICY_CHECK_LABEL_HINT) //.style(STYLE_STACK_ACTION)
//.style("hint") .orientation("horizontal")
.attach(Grid::row(2)) .spacing(50)
.attach(Grid::column(0)) .child(
.margin((0, 0, 16, 0)) Button::new()
.h_align("end") .id(ID_POLICY_CHECK_ACTION_BUTTON_CREATE)
.v_align("center") .style(STYLE_BUTTON_ACTION)
.width(300) .text("Create ticket")
.min_width(300) .on_click(move |states, _entity| {
.font_size(11.) //states.get_mut::<PolicycheckState>(id).send_message_update_policynumber(id);
.text("Error:") //states.send_message(PolicycheckAction::UpdatePolicyCode, policy_check_policy_code);
states.send_message(PolicycheckAction::UpdatePolicyCode, id);
states.send_message(PolicycheckAction::NewTicket, id);
false
})
.build(ctx),
)
.build(ctx), .build(ctx),
) )
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_HINT)
//.style("hint")
.attach(Grid::row(2))
.attach(Grid::column(2))
.h_align("start")
.v_align("center")
.font_size(11)
.build(ctx)
)
.build(ctx); .build(ctx);
let policy_check_form = Container::new() let policy_check_form = Container::new()
.id(ID_POLICY_CHECK_FORM) .id(ID_POLICY_CHECK_FORM)
.min_width(420) .name(ID_POLICY_CHECK_FORM)
.attach(Grid::row(2)) .attach(Grid::row(2))
.attach(Grid::column(1)) .attach(Grid::column(1))
.style("container_form") .style("container_form")
.child( .child(
Grid::new() Grid::new()
.id(ID_POLICY_CHECK_FORM) .id(ID_POLICY_CHECK_FORM)
.width(450)
.min_width(400)
.columns( .columns(
Columns::create() Columns::create()
// Label .push("auto") // Label
.push("300") .push("16") // Delimiter
// Seperator .push("200") // Data
.push("16") .push("16") // Delimiter
// Values .push("32") // Result-Button
.push("auto") .push("4") // Delimeter
// Seperator
.push("16")
// Result-Button
.push("32")
//.build(),
) )
.rows( .rows(
Rows::create() Rows::create()
.push("auto") .push("auto") // Row 0
.push("auto") .push("14") // Seperator
.push("*") .push("auto") // Row 2
//.build(), .push("14") // Seperator
.push("auto") // Row 3
)
//.child(policy_check_form_row_0)
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_LABEL_POLICY_NUMBER)
.style("body")
.attach(Grid::row(0))
.attach(Grid::column(0))
.h_align("end")
.v_align("center")
.text("Policy number")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_POLICY_CHECK_POLICY_NUMBER)
//.style("body")
.attach(Grid::row(0))
.attach(Grid::column(2))
//.lose_focus_on_activation(false)
//WIP: localization for water_mark
.water_mark("10-stellig")
.on_activate(move |states, entity| {
// Entity is entered/activated via Mouse/Keyboard
states.get_mut::<PolicycheckState>(id).parse_policy_number(entity);
})
.on_key_down(move |_, key_event| {
if key_event.key == Key::A(true) {
println!("A key down");
}
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::ImportData);
true
})
.build(ctx)
)
.child(policy_check_button_result)
//.child(policy_check_form_row_2)
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_LABEL_RESULT)
.style("body")
.attach(Grid::row(2))
.attach(Grid::column(0))
.h_align("end")
.v_align("center")
.text("Policy code")
.build(ctx),
)
// .child(
// TextBlock::new()
// .id(ID_POLICY_CHECK_RESULT)
// .style("body")
// .attach(Grid::row(2))
// .attach(Grid::column(2))
// .build(ctx)
//)
.child(policy_check_policy_code)
//.child(policy_check_form_row_2)
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_LABEL_HINT)
.style("hint")
.attach(Grid::row(4))
.attach(Grid::column(0))
//.margin((0, 0, 16, 0))
.h_align("end")
.v_align("center")
.text("Error:")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_HINT)
.style("hint")
.attach(Grid::row(4))
.attach(Grid::column(2))
.build(ctx),
) )
.child(policy_check_form_row_0)
.child(policy_check_form_row_1)
.child(policy_check_form_row_2)
.build(ctx), .build(ctx),
) )
.build(ctx); .build(ctx);
// WIP: this widget type should handle our target natively
// but it isn't able to get textinput, nor handle usize values
// ... yet
let _policy_check_numeric_box = NumericBox::new()
.id(ID_POLICY_CHECK_POLICY_NUMBER)
.h_align("start")
.width(100)
//.min(<usize>1000000000)
//.max(<usize>9999999999)
.val(0)
.min_width(95)
.margin((0, 0, 0, 16))
// WIP code @kivimango
// .on_activate(move |ctx, entity| {
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::ParseEntry(entity));
// })
// .on_changed(move |ctx, entity| {
// ctx.get_mut::<PolicycheckState>(id)
// .set_action(Action::InputTextChanged(entity));
//})
.build(ctx);
// row3: only shown, if we read in `policy numbers` in // row3: only shown, if we read in `policy numbers` in
// a hashmap as values // a hashmap as values
@@ -329,7 +277,6 @@ impl Template for PolicycheckView {
.v_align("top") .v_align("top")
.orientation("horizontal") .orientation("horizontal")
.visibility(Visibility::Collapsed) .visibility(Visibility::Collapsed)
//.spacing("4")
.child( .child(
TextBlock::new() TextBlock::new()
.id(ID_POLICY_DATA_LABEL) .id(ID_POLICY_DATA_LABEL)
@@ -357,40 +304,25 @@ impl Template for PolicycheckView {
.id(ID_POLICY_CHECK_WIDGET) .id(ID_POLICY_CHECK_WIDGET)
.columns( .columns(
Columns::create() Columns::create()
.push(50) .push(50) // Left margin
.push("*") .push("*") // Content
.push(50) .push(50) // Right margin
//.build(),
) )
.rows( .rows(
Rows::create() Rows::create()
.push("auto") .push("auto") // Header_Bar
.push(28) .push(28) // Seperator
.push("*") .push("*") // InputForm
.push("auto") .push("auto") // Data_Result
.push("auto") .push("auto") // Bottom_Bar
//.build(),
) )
// row 0: Policy Check Header .child(policy_check_header_bar) // row 0
.child(policy_check_header_bar) .child(policy_check_form) // row 2
.child(policy_data_stack) // row 3
// row 1: Seperator .child(policy_check_form_action) // row 4
.child(policy_check_bottom_bar) // row 5
// row 2: Policy Check Form
.child(policy_check_form)
// row 3: Sum HashMap elements
.child(policy_data_stack)
// row 4: Policy Check Bottom
.child(policy_check_bottom_bar)
.build(ctx), .build(ctx),
) )
} }
} }
// helper to request PolicycheckState
//fn state<'a>(id: Entity, states: &'a mut StatesContext) -> &'a mut PolicycheckState {
// states.get_mut(id)
//}

View File

@@ -0,0 +1,12 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
/// The ticket data state
pub mod ticketdata_state;
/// The tckicket data view
pub mod ticketdata_view;

View File

@@ -0,0 +1,223 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
//use locales::t;
use orbtk::prelude::*;
use serde::Deserialize;
//use std::process;
//use std::collections::HashMap;
use std::time::SystemTime;
use tracing::{info, trace};
use crate::{
data::{constants::*, structures::Email},
widgets::global_state::GlobalState,
services::exports::send_ticketdata::sendticketdata,
widgets::ticketdata::ticketdata_view::TicketdataView,
widgets::policycheck::policycheck_state::PolicycheckAction,
};
/// Valid `actions` that are handled as state changes in the `Ticketdata` widget.
#[derive(Debug, Clone)]
pub enum TicketdataAction {
ClearEntry(Entity),
/// Clear text in the form
ClearForm(),
ChangeTheme(),
//ChangeMailCc(),
//ChangeMailTo(),
InputTextChanged(Entity),
ParseEntry(Entity),
RemoveFocus(Entity),
SendForm(),
SetToggleTheme(Entity),
SetEntry(Entity),
SetVisibility(Entity),
TextChanged(Entity, usize),
UpdatePolicyCode(String)
}
/// Define valid environment variables provided via .env files
/// located in the current call directory.
/// This is primarily used in testing scenarios (eg. debugging).
#[derive(Debug, Deserialize)]
struct Environment {
test_lang: String,
rust_log: String,
}
/// Valid `structures` that are handled inside the state of the `Ticket` widget.
#[derive(AsAny, Default)]
pub struct TicketdataState {
actions: Vec<TicketdataAction>,
button_menu: Entity,
// ComboBox item of mail_cc has been changed
//pub change_mail_cc: bool,
//ComboBox item of mail_to has been changed
//pub change_mail_to: bool,
//duration: Duration,
lang: String,
target: Entity
}
impl GlobalState for TicketdataState {}
/// Method definitions, that react on any given state change inside the `Ticketdata` widget.
impl TicketdataState {
/// Clear the text property of all children of the given form entity
pub fn clear_form(entity: Entity, ctx: &mut Context<'_>) {
if let Some(count) = ctx.get_widget(entity).children_count() {
info!("Widget name: {:?}", ctx.get_widget(entity).get::<String>("name"));
info!("Widget id: {:?}", ctx.get_widget(entity).get::<String>("id"));
}
// form is identified by its id
if let form_entity = ctx.child(ID_TICKET_DATA_GRID).entity() {
info!("Form id: {:?}", ctx.get_widget(form_entity).get::<String>("id"));
info!("Form node name: {:?}", ctx.get_widget(form_entity).get::<String>("name"));
// Loop through children
if let Some(count) = ctx.get_widget(form_entity).children_count() {
for c in 1..=count {
info!("WIP clear entry of child {:?}", c);
//info!("WIP clear entry of child {:?}: {:?}", c, ctx.get_child(form_entity).get::<String>("name"));
}
}
}
}
// pub fn change_mail_cc(&mut self) {
// self.actions.push(TicketdataAction::ChangeMailCc());
// }
// pub fn change_mail_to(&mut self) {
// self.actions.push(TicketdataAction::ChangeMailTo());
// }
pub fn send_form(entity: Entity, ctx: &mut Context<'_>, lang: &str) {
// type conversion (String -> u64)
//let policy_code = ctx.child(ID_TICKET_DATA_POLICY_CODE).get::<String>("text").unwrap().parse::<u64>().unwrap();
// WIP: get selected items ComboBox'es
//let mail_cc_index = *TicketdataView::selected_index_ref(&ctx.widget()) as usize;
//let mail_cc_selected = TicketdataView::items_mail_cc_ref(&ctx.widget(id))[mail_cc_index].clone();
// create Email structures
let email = Email {
// WIP: mail_to -> selected index auslesen
//mail_to: ctx.child(ID_TICKET_DATA_MAIL_TO).get::<String>("text").to_string(),
// WIP: mail_cc -> selected index auslesen
//mail_cc: ctx.child(ID_TICKET_DATA_MAIL_CC).get::<String>("text").to_string(),
mail_to: PROP_MAIL_TO_1.to_string(),
mail_cc: PROP_MAIL_CC_1.to_string(),
mail_bcc: PROP_MAIL_BCC_1.to_string(),
mail_from: PROP_MAIL_FROM.to_string(),
mail_reply: PROP_MAIL_REPLY.to_string(),
subject: PROP_MAIL_SUBJECT.to_string(),
policy_code: ctx.child(ID_TICKET_DATA_POLICY_CODE).get::<String>("text").to_string(),
policy_holder: ctx.child(ID_TICKET_DATA_POLICY_HOLDER).get::<String>("text").to_string(),
deductible: ctx.child(ID_TICKET_DATA_DEDUCTIBLE).get::<String>("text").to_string(),
callback_number: ctx.child(ID_TICKET_DATA_CALLBACK_NUMBER).get::<String>("text").to_string(),
callback_date: ctx.child(ID_TICKET_DATA_CALLBACK_DATE).get::<String>("text").to_string(),
harm_type: ctx.child(ID_TICKET_DATA_HARM_TYPE).get::<String>("text").to_string(),
ivr_comment: ctx.child(ID_TICKET_DATA_IVR_COMMENT).get::<String>("text").to_string(),
};
info!("WIP: Sending form to construct eMail to {:?}", email);
// send email via service
if let Err(_e) = sendticketdata(&email, &lang) {
Button::icon_brush_set(&mut ctx.child(ID_TICKET_DATA_ACTION_BUTTON_SEND), String::from("#FF0000"));
Button::foreground_set(&mut ctx.child(ID_TICKET_DATA_ACTION_BUTTON_SEND), String::from("#FF0000"));
Button::icon_set(&mut ctx.child(ID_TICKET_DATA_ACTION_BUTTON_SEND), material_icons_font::MD_CLEAR);
};
}
}
/// Supported methods handled inside the `TicketState`
impl State for TicketdataState {
/// Initialize the state of widgets inside `TicketState`
fn init(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
let time_start= SystemTime::now();
trace!(target: "advotracker", ticketdata_state = "init", status = "started");
// Initialize required menu button entity
self.button_menu = ctx
.entity_of_child(ID_TICKET_DATA_BUTTON_MENU)
.expect("TicketState.init: Can't find resource entity 'ID_TICKET_DATA_BUTTON_MENU'.");
// initialize the entity object, that will receive messages
self.target = Entity::from(ctx.widget().try_clone::<u32>("target")
.expect("TicketState.init: Can't find resource entity 'target'."));
// Get language from environment
self.lang = TicketdataState::get_lang();
let time_end = SystemTime::now();
let duration = time_end.duration_since(time_start);
trace!(target: "advotracker", ticketdata_state = "init", status = "finished", duration = ?duration);
}
/// The reader component of the message system handing `TicketdataState``
fn messages(
&mut self,
mut messages: MessageReader,
_registry: &mut Registry,
ctx: &mut Context<'_>,
) {
for message in messages.read::<TicketdataAction>() {
match message {
TicketdataAction::ClearForm() => {
info!("message: {:?} recieved", message);
TicketdataState::clear_form(ctx.entity(), ctx);
}
TicketdataAction::SendForm() => {
info!("message: {:?} recieved", message);
TicketdataState::send_form(ctx.entity(), ctx, &self.lang);
}
_ => { println!("messages: action not implemented!"); }
}
}
for message in messages.read::<PolicycheckAction>() {
match message {
PolicycheckAction::UpdatePolicyCode => {
info!("Message received: 'PolicycheckAction::UpdatePolicyCode'");
//TextBlock::text_set(&mut ctx.child(ID_TICKET_DATA_POLICY_CODE), policy_code);
}
_ => { println!("messages: action not implemented!"); }
}
}
}
fn update(&mut self, _registry: &mut Registry, ctx: &mut Context<'_>) {
let actions: Vec<TicketdataAction> = self.actions.drain(..).collect();
for action in actions {
match action {
// TicketdataAction::ChangeMailCc() => {
// let index = *TicketdataView::items_ref(&ctx.widget()) as usize;
// let selected_index = TicketdataView::items_ref(&ctx.widget())[index].clone();
// info!("new selection for mail index: {:?}", selected_index);
// }
TicketdataAction::ClearForm() => {
info!("update: send_message {:?}", action);
ctx.send_message(TicketdataAction::ClearForm(), self.target);
}
TicketdataAction::SendForm() => {
//ctx.send_message(TicketdataAction::SendForm(), self.ID_TICKETDATA_FORM);
info!("update: send_message {:?}", action);
}
_ => { println!("TicketdataAction: action not implemented!"); }
}
}
}
}

View File

@@ -0,0 +1,446 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
use crate::{
data::constants::*,
widgets::ticketdata::ticketdata_state::{TicketdataAction, TicketdataState},
};
// Macro that initializes the widget structures/variables for the policy check view
widget!(
/// Form to enter data of a ticket record
TicketdataView<TicketdataState> {
// language used inside the widget
lang: String,
// title used in the header
ticket_data_title: String,
// entity id that will receive the messages
target: u32
}
);
/// The template implementation of the ticket view
/// All GUI elements are styled using the "style" attribute referencing to a ron based css
impl Template for TicketdataView {
fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self {
let tenent_logo = Container::new()
.margin((16, 16, 0, 0))
.attach(Grid::column(0))
.v_align("center")
.child(
ImageWidget::new()
.image("assets/advotracker/hiedemann_logo.png")
.v_align("center")
.build(ctx),
)
.build(ctx);
let ticket_data_bottom_bar = Container::new()
.id(ID_TICKET_DATA_BOTTOM_BAR)
.style(STYLE_BOTTOM_BAR)
.attach(Grid::row(4))
.attach(Grid::column(1))
.attach(Grid::column_span(2))
.v_align("end")
.child(
Container::new()
.attach(Grid::column(1))
.h_align("end")
.v_align("end")
.child(
TextBlock::new()
.margin((0, 9, 48, 0))
.text("©Networkx GmbH")
.build(ctx)
)
.build(ctx),
)
.build(ctx);
let ticket_data_button_menu = Button::new()
.id(ID_TICKET_DATA_BUTTON_MENU)
.attach(Grid::row(0))
.attach(Grid::column(2))
.h_align("end")
.icon(material_icons_font::MD_MENU)
//.style("button_single_content")
.style(STYLE_BUTTON_MENU)
.on_click(move |_ctx, _| {
println!("WIP: open menu popup from MenuView");
// ctx.get_mut::<MenuState>(id)
// .set_action(MenuAction::CreateMenu(ID_MENU_STACK));
true
})
.build(ctx);
let ticket_data_form = Container::new()
.id(ID_TICKET_DATA_FORM)
.name(ID_TICKET_DATA_FORM)
.attach(Grid::row(2))
.attach(Grid::column(1))
.style("container_form")
.child(
Grid::new()
.id(ID_TICKET_DATA_GRID)
.name(ID_TICKET_DATA_GRID)
.columns(
Columns::create()
.push("auto") // Label
.push(16) // Delimiter
.push("*") // Data
.push(32) // Delimiter (2x margin)
)
.rows(
Rows::create()
.push("auto") // Row 0
.push(14) // Seperator
.push("auto") // Row 2
.push(14) // Seperator
.push("auto") // Row 4
.push(14) // Seperator
.push("auto") // Row 6
.push(14) // Seperator
.push("auto") // Row 8
.push(14) // Seperator
.push("auto") // Row 10
.push(14) // Seperator
.push("auto") // Row 12
.push(14) // Seperator
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_POLICY_CODE)
.attach(Grid::row(0))
.attach(Grid::column(0))
.text("Policy code")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_POLICY_CODE)
.attach(Grid::row(0))
.attach(Grid::column(2))
.text("9999999990")
.v_align("center")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_POLICY_HOLDER)
.attach(Grid::row(2))
.attach(Grid::column(0))
.text("Policy holder")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_POLICY_HOLDER)
.attach(Grid::row(2))
.attach(Grid::column(2))
.text("")
.water_mark("Name des Versicherungsnehmers")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_DEDUCTIBLE)
.attach(Grid::row(4))
.attach(Grid::column(0))
.text("Deductible")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_DEDUCTIBLE)
.attach(Grid::row(4))
.attach(Grid::column(2))
.text("")
.water_mark("im Beratungsgespräch erfragen")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_CALLBACK_NUMBER)
.attach(Grid::row(6))
.attach(Grid::column(0))
.text("Callback number")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_CALLBACK_NUMBER)
.attach(Grid::row(6))
.attach(Grid::column(2))
.text("")
.water_mark("wie zu erreichen")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_CALLBACK_DATE)
.attach(Grid::row(8))
.attach(Grid::column(0))
.text("Callback date")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_CALLBACK_DATE)
.attach(Grid::row(8))
.attach(Grid::column(2))
.text("")
.water_mark("Rückruf gewünscht um")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_HARM_TYPE)
.attach(Grid::row(10))
.attach(Grid::column(0))
.text("Harm type")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_HARM_TYPE)
.name(ID_TICKET_DATA_HARM_TYPE)
.attach(Grid::row(10))
.attach(Grid::column(2))
.text("")
.water_mark("Schadenstyp")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_IVR_COMMENT)
.attach(Grid::row(12))
.attach(Grid::column(0))
.text("IVR comment")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_IVR_COMMENT)
.attach(Grid::row(12))
.attach(Grid::column(2))
.text("")
.water_mark("Kommentar zur Haftung, bzw. zur Deckung")
//.height(48.0)
.build(ctx),
)
.build(ctx),
)
.build(ctx);
let ticket_data_form_action = Container::new()
.id(ID_TICKET_DATA_ACTION_GRID)
.attach(Grid::row(3))
.attach(Grid::column(1))
//.style(STYLE_CONTAINER_ACTION)
.padding(14)
.h_align("center")
.child(
Stack::new()
//.style(STYLE_STACK_ACTION)
.orientation("horizontal")
.spacing(50)
.child(
Button::new()
.id(ID_TICKET_DATA_ACTION_BUTTON_CLEAR)
.style(STYLE_BUTTON_ACTION)
.text("Clear")
.on_click(move |states, _| {
states.send_message(TicketdataAction::ClearForm(), id);
false
})
.build(ctx),
)
.child(
Button::new()
.id(ID_TICKET_DATA_ACTION_BUTTON_SEND)
.style(STYLE_BUTTON_ACTION)
.text("Send")
//.visibility(Visibility::Collapsed)
.on_click(move |states, _entity| {
states.send_message(TicketdataAction::SendForm(), id);
false
})
.build(ctx),
)
.build(ctx),
)
.build(ctx);
let ticket_data_form_mail = Container::new()
.id(ID_TICKET_DATA_CONTAINER_MAIL)
.name(ID_TICKET_DATA_CONTAINER_MAIL)
.attach(Grid::row(1))
.attach(Grid::column(1))
.style(STYLE_CONTAINER_MAIL)
.child(
Grid::new()
.columns(
Columns::create()
.push(16) // Delimiter
.push("stretch") // Label
.push(16) // Delimiter
.push("auto") // MailAddress
.push("32") // Delimiter (2x margin)
)
.rows(
Rows::create()
.push("auto") // Row 0
.push(2) // Seperator
.push("auto") // Row 2
.push(2) // Seperator
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_MAIL_TO)
.attach(Grid::row(0))
.attach(Grid::column(1))
.style(STYLE_MAIL_LABEL)
.text("Recipient (To)")
.build(ctx),
)
.child(
ComboBox::new()
.id(ID_TICKET_DATA_COMBO_BOX_MAIL_TO)
.attach(Grid::row(0))
.attach(Grid::column(3))
.style(STYLE_MAIL_TO)
.on_changed("selected_item", move |states, _entity| {
states
.get_mut::<TicketdataState>(id);
})
.items_builder(move |ictx, index| match index {
0 => TextBlock::new()
.text(PROP_MAIL_TO_1)
.h_align("start")
.v_align("center")
.build(ictx),
1 => TextBlock::new()
.text(PROP_MAIL_TO_2)
.h_align("start")
.v_align("center")
.build(ictx),
2 => TextBlock::new()
.text(PROP_MAIL_TO_3)
.h_align("start")
.v_align("center")
.build(ictx),
3 => TextBlock::new()
.text(PROP_MAIL_TO_4)
.h_align("start")
.v_align("center")
.build(ictx),
_ => panic!(),
})
.count(4)
.selected_index(0)
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_MAIL_CC)
.attach(Grid::row(2))
.attach(Grid::column(1))
.style(STYLE_MAIL_LABEL)
.text("Copie (CC)")
.build(ctx),
)
.child(
ComboBox::new()
.id(ID_TICKET_DATA_MAIL_CC)
.attach(Grid::row(2))
.attach(Grid::column(3))
.style(STYLE_MAIL_CC)
.items_builder(move |ictx, index| match index {
0 => TextBlock::new()
.text(PROP_MAIL_CC_1)
.h_align("start")
.v_align("center")
.build(ictx),
1 => TextBlock::new()
.text(PROP_MAIL_CC_2)
.h_align("start")
.v_align("center")
.build(ictx),
_ => panic!(),
})
.count(2)
.selected_index(0)
.build(ctx),
)
.build(ctx),
)
.build(ctx);
let ticket_data_header_text = TextBlock::new()
.id(ID_TICKET_DATA_HEADER)
.attach(Grid::column(0))
.style(STYLE_HEADER_TEXT)
.text("Ticket Data")
.build(ctx);
let ticket_data_header_bar = Container::new()
.id(ID_TICKET_DATA_HEADER_BAR)
.attach(Grid::row(0))
.attach(Grid::column_span(3))
.style(STYLE_HEADER_BAR)
.child(tenent_logo)
.child(ticket_data_header_text)
.child(ticket_data_button_menu)
.build(ctx);
// Widget: Ticket data view
self.id(ID_TICKET_DATA_VIEW)
.name(ID_TICKET_DATA_VIEW)
.min_height(410.0)
.child(
Grid::new()
.id(ID_TICKET_DATA_GRID)
.columns(
Columns::create()
.push(50) // Left margin
.push("*") // Content
.push(50) // Right margin
)
.rows(
Rows::create()
.push("auto") // Header_Bar
.push("auto") // Mail_Form
.push("*") // Input_Form
.push("auto") // Action
.push("auto") // Bottom_Bar
)
.child(ticket_data_header_bar) // row 0
.child(ticket_data_form_mail) // row 1
.child(ticket_data_form) // row 2
.child(ticket_data_form_action) // row 3
.child(ticket_data_bottom_bar) // row 4
.build(ctx),
)
}
}