7 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
17 changed files with 273 additions and 143 deletions

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"
@@ -24,14 +24,14 @@ 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-alpha.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" }
#regex = { version = "~1" }
serde = { version = "~1.0", features = ["derive"] } serde = { version = "~1.0", features = ["derive"] }
substring = { version = "~1" } substring = { version = "~1" }
#tokio = { version = "~0.2", features = ["macros", "rt-threaded", "stream", "time"] } #tokio = { version = "~0.2", features = ["macros", "rt-threaded", "stream", "time"] }
@@ -39,8 +39,9 @@ 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 = []

View File

@@ -13,7 +13,8 @@ Dictionary (
// policycheck_view // policycheck_view
"Validation policy number": "Prüfung Versicherungsnummer", "Validation policy number": "Prüfung Versicherungsnummer",
"Policy number": "Versicherungsnummer", "Policy number": "Versicherungsnummer",
"Policy code": "Policen-Code", "Policy code": "Vers.-Schein/Schadennummer",
"Policy holder": "Versicherungsnehmer",
"Checklist elements: ": "Prüflistenelemente: ", "Checklist elements: ": "Prüflistenelemente: ",
"Check result": "Prüfungsergebnis", "Check result": "Prüfungsergebnis",
"Importing data": "Importiere Datensätze", "Importing data": "Importiere Datensätze",
@@ -31,11 +32,11 @@ Dictionary (
// ticketdata_view // ticketdata_view
"Callback number": "Rückrufnummer", "Callback number": "Rückrufnummer",
"Callback date": "Rückrufdatum", "Callback date": "Erreichbarkeit",
"Clear": "Zurücksetzen", "Clear": "Zurücksetzen",
"Deductible": "Selbstbehalt", "Deductible": "Selbstbehalt",
"Harm type": "Schadenstyp", "Harm type": "Rechtsproblem",
"IVR comment": "IVR Kommentar", "IVR comment": "Rechtsrat",
"Policy holder": "Versicherungsnehmer", "Policy holder": "Versicherungsnehmer",
"Recipient (To)": "Empfänger (To)", "Recipient (To)": "Empfänger (To)",
"Copie (CC)": "Kopie (CC)", "Copie (CC)": "Kopie (CC)",

View File

@@ -7,6 +7,7 @@
use orbtk::prelude::*; use orbtk::prelude::*;
mod data;
mod main_view; mod main_view;
mod receiver; mod receiver;
mod sender; mod sender;

View File

@@ -12,10 +12,6 @@ use crate::{
sender::sender_view::SenderView, sender::sender_view::SenderView,
}; };
// constants
pub static ID_SENDER_VIEW: &str = "sender_view";
pub static ID_RECEIVER_VIEW: &str = "receiver_view";
widget!(MainView { widget!(MainView {
//sender_view: , //sender_view: ,
//receiver_view: //receiver_view:
@@ -38,11 +34,5 @@ impl Template for MainView {
.child(receiver_view) .child(receiver_view)
.build(ctx) .build(ctx)
) )
// .child(
// TabWidget::new()
// .tab(ID_SENDER_VIEW, SenderView::new().build(ctx))
// .tab(ID_RECEIVER_VIEW, ReceiverView::new().build(ctx))
// .build(ctx),
// )
} }
} }

View File

@@ -7,39 +7,46 @@
use orbtk::prelude::*; use orbtk::prelude::*;
use crate::sender::sender_state::{SenderAction, SenderState}; use crate::{
data::constants::*,
sender::sender_state::SenderAction,
};
/// Enumeration of valid `action variants` that need to be handled as // /// Enumeration of valid `action variants` that need to be handled as
/// state changes for the `SenderView` widget. /// state changes for the `SenderView` widget.
pub enum TestMessageAction { pub enum TestMessageAction {
// Toggle visibility of a message TextBox. // Toggle visibility of a message TextBlock.
ToggleMessageBox ToggleMessageBlock
} }
/// Valid `structure members` of the `ReceiverState` used to react on /// Valid `structure members` of the `ReceiverState` used to react on
/// state changes inside the `ReceiverView` widget. /// state changes inside the `ReceiverView` widget.
#[derive(Default, AsAny)] #[derive(Default, AsAny)]
pub struct ReceiverState { pub struct ReceiverState {
message_box: Option<Entity>, message_block: Option<Entity>,
progress_bar: Entity progress_bar: Entity
} }
/// Method definitions, we provide inside the `ReceiverState`. /// Method definitions, we provide inside the `ReceiverState`.
impl ReceiverState { impl ReceiverState {
fn toggle_message_box(&self, ctx: &mut Context) { fn toggle_message_block(&self, ctx: &mut Context) {
if let Some(message_box) = self.message_box { if let Some(message_block) = self.message_block {
ctx.get_widget(message_box) ctx.get_widget(message_block)
.set("visibility", Visibility::Visible); .set("visibility", Visibility::Visible);
} }
} }
} }
/// Trait methods provided for the `SenderState` /// Trait methods provided for the `ReceiverState`
impl State for ReceiverState { impl State for ReceiverState {
// initialize the view entities // initialize the view entities
fn init(&mut self, _: &mut Registry, ctx: &mut Context) { fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.progress_bar = ctx.entity_of_child("progress_bar") self.progress_bar = ctx
.entity_of_child(ID_RECEIVER_PROGRESS_BAR)
.expect("Cannot find ProgressBar!"); .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 // handle messages targeting the view
@@ -52,17 +59,26 @@ impl State for ReceiverState {
for message in messages.read::<SenderAction>() { for message in messages.read::<SenderAction>() {
match message { match message {
SenderAction::UpdateProgress(amount) => { SenderAction::UpdateProgress(amount) => {
println!("Message received"); println!("UpdateProgress message received");
let mut progress_bar = ctx.get_widget(self.progress_bar); let mut progress_bar = ctx.get_widget(self.progress_bar);
let current_progress = progress_bar.clone::<f64>("val"); let current_progress = progress_bar.clone::<f64>("val");
progress_bar.set::<f64>("val", current_progress + amount); 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>() { for action in messages.read::<TestMessageAction>() {
match action { match action {
TestMessageAction::ToggleMessageBox => { TestMessageAction::ToggleMessageBlock => {
self.toggle_message_box(ctx); self.toggle_message_block(ctx);
} }
} }
} }

View File

@@ -7,31 +7,50 @@
use orbtk::prelude::*; use orbtk::prelude::*;
use crate::receiver::receiver_state::{TestMessageAction, ReceiverState}; use crate::{
data::constants::*,
//receiver::receiver_state::{TestMessageAction, ReceiverState},
receiver::receiver_state::ReceiverState,
};
widget!(ReceiverView<ReceiverState>); widget!(ReceiverView<ReceiverState>);
impl Template for ReceiverView { impl Template for ReceiverView {
fn template(self, _id: Entity, bc: &mut BuildContext) -> Self { fn template(self, _id: Entity, build_context: &mut BuildContext) -> Self {
self.name("ReceiverView") self.id(ID_RECEIVER)
.name(ID_RECEIVER)
.child( .child(
Stack::new() Container::new()
.orientation("vertical") .id(ID_RECEIVER_CONTAINER)
.spacing(16) .border_brush(COLOR_BOMBAY)
.border_width(2)
.name(ID_RECEIVER_CONTAINER)
.padding(16)
.child( .child(
ProgressBar::new() Stack::new()
.id("progress_bar") .orientation("vertical")
.build(bc) .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)
) )
.child( .build(build_context)
TextBox::new()
.id("message_box")
.h_align("center")
.text("message received. Box toggled!")
.visibility("hidden")
.build(bc)
)
.build(bc)
) )
} }
} }

View File

@@ -7,11 +7,14 @@
use orbtk::prelude::*; use orbtk::prelude::*;
//use crate::data::constants::*;
/// Enumeration of valid `action variants` that need to be handled as /// Enumeration of valid `action variants` that need to be handled as
/// state changes for the `SenderView` widget. /// state changes for the `SenderView` widget.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum SenderAction { pub enum SenderAction {
UpdateProgress(f64), UpdateProgress(f64),
UpdateMessage(String),
} }
/// Valid `structure members` of the `SenderState` used to react on /// Valid `structure members` of the `SenderState` used to react on
@@ -26,11 +29,17 @@ pub struct SenderState {
/// Method definitions, we provide inside the `SenderState`. /// Method definitions, we provide inside the `SenderState`.
impl SenderState { impl SenderState {
/// Sending message 'UpdateProgress' /// Sending message with type 'UpdateProgress'
pub fn send_message(&mut self) { pub fn send_update_progress(&mut self) {
println!("Sender: push 'UpdateProgress' action"); println!("Sender: push 'UpdateProgress' action");
self.actions.push(SenderAction::UpdateProgress(0.1)); 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` /// Trait methods provided for the `SenderState`
@@ -46,12 +55,23 @@ impl State for SenderState {
fn update(&mut self, _: &mut Registry, ctx: &mut Context) { fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
let actions: Vec<SenderAction> = self.actions.drain(..).collect(); 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 { for action in actions {
match action { match action {
SenderAction::UpdateProgress(amount) => { SenderAction::UpdateProgress(amount) => {
ctx.send_message(SenderAction::UpdateProgress(amount), self.target); message_adapter.send_message(SenderAction::UpdateProgress(amount), self.target);
println!("Sender: send message 'SenderAction::UpdateProgress'"); 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

@@ -5,9 +5,16 @@
* SPDX-License-Identifier: (0BSD or MIT) * SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::{
prelude::*,
shell::event::Key,
};
use crate::sender::sender_state::{SenderAction, SenderState}; use crate::{
data::constants::*,
sender::sender_state::SenderState,
//sender::sender_state::{SenderAction, SenderState},
};
widget!(SenderView<SenderState> { widget!(SenderView<SenderState> {
// the Entity of the widget that will receive the messages // the Entity of the widget that will receive the messages
@@ -15,20 +22,79 @@ widget!(SenderView<SenderState> {
}); });
impl Template for SenderView { impl Template for SenderView {
fn template(self, id: Entity, bc: &mut BuildContext) -> Self { fn template(self, id: Entity, build_context: &mut BuildContext) -> Self {
self.name("SenderView") 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( .child(
Button::new() Container::new()
.text("Click me to send a message!") .id(ID_SENDER_CONTAINER)
.v_align("center") .border_brush(COLOR_BOMBAY)
.h_align("center") .border_width(2)
.on_click(move |states, _entity| { .padding(16)
states.get_mut::<SenderState>(id).send_message(); .child(
//states.send_message(SenderAction::UpdateProgress, id); Grid::new()
//ctx.send_message(TestMessageAction::ToggleMessageBox, id); .id(ID_SENDER_GRID)
false .columns(
}) Columns::create()
.build(bc) .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

@@ -8,16 +8,17 @@
// Component Values (Properties) // Component Values (Properties)
pub static PROP_ADVOTRACKER: &str = "advotracker"; pub static PROP_ADVOTRACKER: &str = "advotracker";
pub static PROP_MAIL_CC_1: &str = "advotracker@hiedemann.de"; pub static PROP_MAIL_CC_1: &str = "info@hiedemann.de";
pub static PROP_MAIL_CC_2: &str = "service@hiedemann.de"; pub static PROP_MAIL_CC_2: &str = "service@hiedemann.de";
pub static PROP_MAIL_BCC_1: &str = "schloemer@hiedemann.de"; pub static PROP_MAIL_BCC_1: &str = "Networkx Support <support@networkx.de>";
pub static PROP_MAIL_BCC_2: &str = "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_1: &str = "allianz@ponschab-partner.com";
pub static PROP_MAIL_TO_2: &str = "kontakt@chevalier.law"; 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_3: &str = "kontakt@metamedlaw.de";
pub static PROP_MAIL_TO_4: &str = "sekretariat@m2-mediation.de"; pub static PROP_MAIL_TO_4: &str = "sekretariat@m2-mediation.de";
pub static PROP_MAIL_FROM: &str = "advotracker@heidemann.de";
pub static PROP_MAIL_SUBJECT: &str = "ZMB Allianz - neues Mandat";
pub static PROP_POLICY_CHECK: &str = "policy_check"; pub static PROP_POLICY_CHECK: &str = "policy_check";
pub static PROP_POLICY_PROGRESS_COUNT: &str = "policy_progress_count"; pub static PROP_POLICY_PROGRESS_COUNT: &str = "policy_progress_count";
@@ -128,6 +129,8 @@ pub static ID_TICKET_DATA_BUTTON_MENU: &str = "ticket_data_button_menu";
pub static ID_TICKET_DATA_BUTTON_RESULT: &str = "ticket_data_button_result"; pub static ID_TICKET_DATA_BUTTON_RESULT: &str = "ticket_data_button_result";
pub static ID_TICKET_DATA_CALLBACK_DATE: &str = "ticket_data_label_callback_date"; 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 ID_TICKET_DATA_CALLBACK_NUMBER: &str = "ticket_data_label_callback_number";
pub static ID_TICKET_DATA_COMBO_BOX_MAIL_CC: &str = "ticket_data_combo_box_mail_cc";
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_CONTAINER_MAIL: &str = "ticket_data_container_mail";
pub static ID_TICKET_DATA_COUNT_BLOCK: &str = "ticket_data_count_block"; 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_DEDUCTIBLE: &str = "ticket_data_deductible";

View File

@@ -113,7 +113,7 @@ pub struct CsvExportRecord {
/// Handel fields of an Email (header, body) /// Handel fields of an Email (header, body)
#[derive(Default, Debug, Clone, Deserialize, Serialize)] #[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct Email { pub struct Email {
/// recipient address /// Recipient address
pub mail_to: String, pub mail_to: String,
/// Carbon Copy recipient address /// Carbon Copy recipient address
pub mail_cc: String, pub mail_cc: String,
@@ -121,6 +121,8 @@ pub struct Email {
pub mail_bcc: String, pub mail_bcc: String,
/// Sender address /// Sender address
pub mail_from: String, pub mail_from: String,
/// Replay to given address
pub mail_reply: String,
/// Mail subject /// Mail subject
pub subject: String, pub subject: String,
/// Body policy code /// Body policy code

View File

@@ -172,6 +172,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// type conversion (viperus String -> u64) // type conversion (viperus String -> u64)
let test_policy_number = viperus.get::<String>("test_policy_number").unwrap().parse::<u64>().unwrap(); 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);

View File

@@ -36,37 +36,36 @@ pub fn sendticketdata(email: &Email, lang: &str) -> Result<(), Box<dyn Error>> {
div style="display: flex; flex-direction: column; align-items: center;" { div style="display: flex; flex-direction: column; align-items: center;" {
// compose with variables and strings // compose with variables and strings
h2 { (email.subject) " (" (email.policy_code) ")" } h2 { (email.subject) " (" (email.policy_code) ")" }
p { "Policen-Code: " (email.policy_code) } p { "Vers.-Schein/Schadennummer: " (email.policy_code) }
p { "Policen-Code: " (email.policy_code) } p { "Versicherungsnehmer: " (email.policy_holder) }
p { "Versicherungsnehmer: " (email.policy_holder) } p { "Selbstbehalt: "(email.deductible) }
p { "Selbstbehalt: "(email.deductible) } p { "Rückrufnummer: " (email.callback_number) }
p { "Rückrufnummer: " (email.callback_number) } p { "Erreichbarkeit: " (email.callback_date) }
p { "Rückrufdatum: " (email.callback_date) } p { "Rechtsproblem: "(email.harm_type) }
p { "Schadenstyp: "(email.harm_type) } p { "Rechtsrat: "(email.ivr_comment) }
p { "IVR Kommentar: "(email.ivr_comment) }
} }
}; };
let ascii_body = String::new() let ascii_body = String::new()
+ &"Policen-Code: ".to_string() + &(email.policy_code) + &"\n" + &"Vers.-Schein/Schadennummer".to_string() + &(email.policy_code) + &"\n"
+ &"Versicherungsnehmer: ".to_string() + &(email.policy_holder) + &"\n" + &"Versicherungsnehmer: ".to_string() + &(email.policy_holder) + &"\n"
+ &"Selbstbehalt: ".to_string() + &(email.deductible) + &"\n" + &"Selbstbehalt: ".to_string() + &(email.deductible) + &"\n"
+ &"Rückrufnummer: ".to_string()+ &(email.callback_number) + &"\n" + &"Rückrufnummer: ".to_string()+ &(email.callback_number) + &"\n"
+ &"Rückrufdatum: ".to_string() + &(email.callback_date) + &"\n" + &"Erreichbarkeit: ".to_string() + &(email.callback_date) + &"\n"
+ &"Schadenstyp: ".to_string() + &(email.harm_type) + &"\n" + &"Rechtsproblem: ".to_string() + &(email.harm_type) + &"\n"
+ &"IVR Kommentar: ".to_string() + &(email.ivr_comment) + &"\n"; + &"Rechtsrat: ".to_string() + &(email.ivr_comment) + &"\n";
info!("email body: {:?}", ascii_body); info!("email body: {:?}", ascii_body);
let message = Message::builder() let message = Message::builder()
.from((email.mail_from).parse().unwrap()) //.reply_to("Kanzlei Hiedemann <info@hiedemann.de>".parse().unwrap())
//.reply_to("Support <support@networkx.de>".parse().unwrap()) .to("Kanzlei Hiedemann <info@hiedemann.de>".parse().unwrap())
.to("Networkx-Info <info@networkx.de>".parse().unwrap()) .cc(" <ralf.zerres@networkx.de>".parse().unwrap())
.cc("Ralf Zerres <ralf.zerres@networkx.de>".parse().unwrap()) .reply_to((email.mail_reply).parse().unwrap())
.reply_to((email.mail_from).parse().unwrap())
//.to((email.mail_to).parse().unwrap()) //.to((email.mail_to).parse().unwrap())
//.cc((email.mail_cc).parse().unwrap()) //.cc((email.mail_cc).parse().unwrap())
//.bcc((email.mail_bcc).parse().unwrap()) //.bcc((email.mail_bcc).parse().unwrap())
.from((email.mail_from).parse().unwrap())
.subject(String::new() .subject(String::new()
+ &email.subject.to_string() + &email.subject.to_string()
+ &" (".to_string() + &" (".to_string()
@@ -96,11 +95,14 @@ pub fn sendticketdata(email: &Email, lang: &str) -> Result<(), Box<dyn Error>> {
info!("message: {:?}", message); info!("message: {:?}", message);
// Create credential for remote authentication (username, password) // Create credential for remote authentication (username, password)
// WIP: get credentials from config file / environment // WIP: get credentials from config file / cli
let creds = Credentials::new("ralf.zerres.de@gmail.com".to_string(), "20jacara03".to_string()); let creds = Credentials::new("info@kanzlei.hiedemann.de".to_string(), "17info67$".to_string());
// Open a remote connection to relay server
let mailer = SmtpTransport::relay("smtp.gmail.com")
// 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() .unwrap()
.credentials(creds) .credentials(creds)
.build(); .build();

View File

@@ -61,14 +61,14 @@ pub trait GlobalState {
Some(text) 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) = *Window::focus_state_ref(&ctx.window()).focused_entity() { // if let Some(old_focused_element) = *Window::focus_state_ref(&ctx.window()).focused_entity() {
ctx.push_event_by_window(FocusEvent::RemoveFocus(old_focused_element)); // ctx.push_event_by_window(FocusEvent::RemoveFocus(old_focused_element));
} // }
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);
} // }
/// Save the our data structure and convert it to `ron` file format. /// Save the our data structure and convert it to `ron` file format.
/// The cargo package identifier (here: 'nwx.advotracker') is taken to create the app directory. /// The cargo package identifier (here: 'nwx.advotracker') is taken to create the app directory.

View File

@@ -15,7 +15,7 @@ use crate::{
widgets::configuration::configuration_view::ConfigurationView, 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::menu::menu_view::MenuView, //widgets::menu::menu_view::MenuView,
widgets::ticketdata::ticketdata_view::TicketdataView, widgets::ticketdata::ticketdata_view::TicketdataView,
}; };
@@ -68,7 +68,7 @@ impl Template for MainView {
.tab(ID_TICKET_DATA_VIEW, ticketdata_view) .tab(ID_TICKET_DATA_VIEW, ticketdata_view)
.tab(ID_LOCALIZATION_VIEW, LocalizationView::new().build(ctx)) .tab(ID_LOCALIZATION_VIEW, LocalizationView::new().build(ctx))
.tab(ID_CONFIGURATION_VIEW, ConfigurationView::new().build(ctx)) .tab(ID_CONFIGURATION_VIEW, ConfigurationView::new().build(ctx))
.tab(ID_MENU_VIEW, MenuView::new().build(ctx)) //.tab(ID_MENU_VIEW, MenuView::new().build(ctx))
.build(ctx), .build(ctx),
) )
//.child(policycheck_view) //.child(policycheck_view)

View File

@@ -70,7 +70,7 @@ pub struct PolicycheckState {
label_result: Entity, label_result: Entity,
lang: String, lang: String,
policy_data_count: u64, policy_data_count: u64,
policy_number: Entity, //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,
@@ -181,7 +181,7 @@ impl PolicycheckState {
/// Create new ticket /// Create new ticket
pub fn new_ticket(&mut self, ctx: &mut Context<'_>) { pub fn new_ticket(&mut self, ctx: &mut Context<'_>) {
println!("WIP: new ticket."); println!("WIP: new ticket.");
self.navigate(self.ticketdata, ctx); self(ticketdata_view.0);
//ctx.widget().get_mut::<TicketdataView>(0). //ctx.widget().get_mut::<TicketdataView>(0).
//ctx.get_widget(self.ticketdata_view); //ctx.get_widget(self.ticketdata_view);
} }
@@ -421,7 +421,7 @@ impl PolicycheckState {
} }
/// Update the policy code policy data list. /// Update the policy code policy data list.
fn update_policy_code(&self, ctx: &mut Context<'_>) { fn update_policy_code(&self, _ctx: &mut Context<'_>) {
println!("update internal: policy_code"); println!("update internal: policy_code");
//let policy_code = ctx.widget().get::<PolicycheckState>(ID_POLICY_CHECK_POLICY_CODE); //let policy_code = ctx.widget().get::<PolicycheckState>(ID_POLICY_CHECK_POLICY_CODE);
//ctx.widget().set(PROP_POLICY_DATA_COUNT, policy_code); //ctx.widget().set(PROP_POLICY_DATA_COUNT, policy_code);

View File

@@ -18,7 +18,8 @@ use crate::{
data::{constants::*, structures::Email}, data::{constants::*, structures::Email},
widgets::global_state::GlobalState, widgets::global_state::GlobalState,
services::exports::send_ticketdata::sendticketdata, services::exports::send_ticketdata::sendticketdata,
widgets::policycheck::policycheck_state::{PolicycheckAction, PolicycheckState}, widgets::ticketdata::ticketdata_view::TicketdataView,
widgets::policycheck::policycheck_state::PolicycheckAction,
}; };
/// Valid `actions` that are handled as state changes in the `Ticketdata` widget. /// Valid `actions` that are handled as state changes in the `Ticketdata` widget.
@@ -28,12 +29,15 @@ pub enum TicketdataAction {
/// Clear text in the form /// Clear text in the form
ClearForm(), ClearForm(),
ChangeTheme(), ChangeTheme(),
//ChangeMailCc(),
//ChangeMailTo(),
InputTextChanged(Entity), InputTextChanged(Entity),
ParseEntry(Entity), ParseEntry(Entity),
RemoveFocus(Entity), RemoveFocus(Entity),
SendForm(),
SetToggleTheme(Entity), SetToggleTheme(Entity),
SetEntry(Entity), SetEntry(Entity),
SendForm(), SetVisibility(Entity), SetVisibility(Entity),
TextChanged(Entity, usize), TextChanged(Entity, usize),
UpdatePolicyCode(String) UpdatePolicyCode(String)
} }
@@ -52,6 +56,10 @@ struct Environment {
pub struct TicketdataState { pub struct TicketdataState {
actions: Vec<TicketdataAction>, actions: Vec<TicketdataAction>,
button_menu: Entity, 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, //duration: Duration,
lang: String, lang: String,
target: Entity target: Entity
@@ -68,7 +76,7 @@ impl TicketdataState {
info!("Widget id: {:?}", ctx.get_widget(entity).get::<String>("id")); info!("Widget id: {:?}", ctx.get_widget(entity).get::<String>("id"));
} }
// identify the form by its id // form is identified by its id
if let form_entity = ctx.child(ID_TICKET_DATA_GRID).entity() { if let form_entity = ctx.child(ID_TICKET_DATA_GRID).entity() {
info!("Form id: {:?}", ctx.get_widget(form_entity).get::<String>("id")); info!("Form id: {:?}", ctx.get_widget(form_entity).get::<String>("id"));
info!("Form node name: {:?}", ctx.get_widget(form_entity).get::<String>("name")); info!("Form node name: {:?}", ctx.get_widget(form_entity).get::<String>("name"));
@@ -81,27 +89,16 @@ impl TicketdataState {
} }
} }
} }
// let Some(count) = ctx.child(ID_TICKET_DATA_GRID).entitry().children_count() {
// for c in 1..=count {
// println!("WIP clear entry of child {:?}", c);
// }
// }
//let mut children = vec![];
//get_all_children(&mut children, entity, ecm.entity_store());
//trace!("Children {:?}: {:?}", children.len(), children);
//println!("Child name: {:?}", ctx.try_child("ticket_data_form"));
//TextBlock::text_set(&mut ctx.child(ID_TICKET_DATA_POLICY_HOLDER), "");
//println!("Number of childs: {:?}", count);
//for c in 1..=count {
// println!("WIP clear entry of child {:?}", c);
// children = get_all_children()
//println!("Child {:?}: Entity: {:?}", c, ctx.child_from_index(c));
//println!("Text: {:?}", ctx.get_widget(entity).entity_of_child(entity));
//TextBlock::text_set(&mut ctx.child(ID_TICKET_DATA_POLICY_HOLDER), "");
//}
//TextBox::text_set(&mut ctx.widget(entity), String::from(""));
} }
// 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) { pub fn send_form(entity: Entity, ctx: &mut Context<'_>, lang: &str) {
// type conversion (String -> u64) // type conversion (String -> u64)
@@ -109,7 +106,7 @@ impl TicketdataState {
// WIP: get selected items ComboBox'es // WIP: get selected items ComboBox'es
//let mail_cc_index = *TicketdataView::selected_index_ref(&ctx.widget()) as usize; //let mail_cc_index = *TicketdataView::selected_index_ref(&ctx.widget()) as usize;
//let mail_cc_selected = TicketdataView::mail_cc_ref(&ctx.widget())[mail_cc_index].clone(); //let mail_cc_selected = TicketdataView::items_mail_cc_ref(&ctx.widget(id))[mail_cc_index].clone();
// create Email structures // create Email structures
let email = Email { let email = Email {
@@ -117,10 +114,12 @@ impl TicketdataState {
//mail_to: ctx.child(ID_TICKET_DATA_MAIL_TO).get::<String>("text").to_string(), //mail_to: ctx.child(ID_TICKET_DATA_MAIL_TO).get::<String>("text").to_string(),
// WIP: mail_cc -> selected index auslesen // WIP: mail_cc -> selected index auslesen
//mail_cc: ctx.child(ID_TICKET_DATA_MAIL_CC).get::<String>("text").to_string(), //mail_cc: ctx.child(ID_TICKET_DATA_MAIL_CC).get::<String>("text").to_string(),
mail_to: PROP_MAIL_TO_1.to_string(), mail_to: PROP_MAIL_TO_1.to_string(),
mail_cc: PROP_MAIL_CC_1.to_string(), mail_cc: PROP_MAIL_CC_1.to_string(),
mail_bcc: PROP_MAIL_BCC_1.to_string(), mail_bcc: PROP_MAIL_BCC_1.to_string(),
mail_from: PROP_MAIL_FROM.to_string(), mail_from: PROP_MAIL_FROM.to_string(),
mail_reply: PROP_MAIL_REPLY.to_string(),
subject: PROP_MAIL_SUBJECT.to_string(), subject: PROP_MAIL_SUBJECT.to_string(),
policy_code: ctx.child(ID_TICKET_DATA_POLICY_CODE).get::<String>("text").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(), policy_holder: ctx.child(ID_TICKET_DATA_POLICY_HOLDER).get::<String>("text").to_string(),
@@ -133,7 +132,11 @@ impl TicketdataState {
info!("WIP: Sending form to construct eMail to {:?}", email); info!("WIP: Sending form to construct eMail to {:?}", email);
// send email via service // send email via service
let _ = sendticketdata(&email, &lang); 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);
};
} }
} }
@@ -145,13 +148,14 @@ impl State for TicketdataState {
trace!(target: "advotracker", ticketdata_state = "init", status = "started"); trace!(target: "advotracker", ticketdata_state = "init", status = "started");
// Initialize required entities // Initialize required menu button entity
self.button_menu = ctx self.button_menu = ctx
.entity_of_child(ID_TICKET_DATA_BUTTON_MENU) .entity_of_child(ID_TICKET_DATA_BUTTON_MENU)
.expect("TicketState.init: Can't find resource entity '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") self.target = Entity::from(ctx.widget().try_clone::<u32>("target")
.expect("TicketState.init: Can't find resource entity 'target'.")); .expect("TicketState.init: Can't find resource entity 'target'."));
// Get language from environment // Get language from environment
self.lang = TicketdataState::get_lang(); self.lang = TicketdataState::get_lang();
@@ -162,6 +166,7 @@ impl State for TicketdataState {
trace!(target: "advotracker", ticketdata_state = "init", status = "finished", duration = ?duration); trace!(target: "advotracker", ticketdata_state = "init", status = "finished", duration = ?duration);
} }
/// The reader component of the message system handing `TicketdataState``
fn messages( fn messages(
&mut self, &mut self,
mut messages: MessageReader, mut messages: MessageReader,
@@ -181,6 +186,7 @@ impl State for TicketdataState {
_ => { println!("messages: action not implemented!"); } _ => { println!("messages: action not implemented!"); }
} }
} }
for message in messages.read::<PolicycheckAction>() { for message in messages.read::<PolicycheckAction>() {
match message { match message {
PolicycheckAction::UpdatePolicyCode => { PolicycheckAction::UpdatePolicyCode => {
@@ -192,11 +198,16 @@ impl State for TicketdataState {
} }
} }
fn update(&mut self, _: &mut Registry, ctx: &mut Context<'_>) { fn update(&mut self, _registry: &mut Registry, ctx: &mut Context<'_>) {
let actions: Vec<TicketdataAction> = self.actions.drain(..).collect(); let actions: Vec<TicketdataAction> = self.actions.drain(..).collect();
for action in actions { for action in actions {
match action { 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() => { TicketdataAction::ClearForm() => {
info!("update: send_message {:?}", action); info!("update: send_message {:?}", action);
ctx.send_message(TicketdataAction::ClearForm(), self.target); ctx.send_message(TicketdataAction::ClearForm(), self.target);

View File

@@ -5,10 +5,7 @@
* SPDX-License-Identifier: (0BSD or MIT) * SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::{ use orbtk::prelude::*;
prelude::*,
//shell::event::Key,
};
use crate::{ use crate::{
data::constants::*, data::constants::*,
@@ -127,7 +124,7 @@ impl Template for TicketdataView {
.build(ctx), .build(ctx),
) )
.child( .child(
TextBlock::new() TextBox::new()
.id(ID_TICKET_DATA_POLICY_CODE) .id(ID_TICKET_DATA_POLICY_CODE)
.attach(Grid::row(0)) .attach(Grid::row(0))
.attach(Grid::column(2)) .attach(Grid::column(2))
@@ -228,7 +225,7 @@ impl Template for TicketdataView {
.attach(Grid::row(10)) .attach(Grid::row(10))
.attach(Grid::column(2)) .attach(Grid::column(2))
.text("") .text("")
.water_mark("Rechtsproblem/Schadenstyp") .water_mark("Schadenstyp")
.build(ctx), .build(ctx),
) )
.child( .child(
@@ -247,7 +244,7 @@ impl Template for TicketdataView {
.attach(Grid::row(12)) .attach(Grid::row(12))
.attach(Grid::column(2)) .attach(Grid::column(2))
.text("") .text("")
.water_mark("Rechtsrat / Kommentar zu Haftungs, bzw. Deckung") .water_mark("Kommentar zur Haftung, bzw. zur Deckung")
//.height(48.0) //.height(48.0)
.build(ctx), .build(ctx),
) )
@@ -319,7 +316,7 @@ impl Template for TicketdataView {
) )
.child( .child(
TextBlock::new() TextBlock::new()
.id(ID_TICKET_DATA_MAIL_TO) .id(ID_TICKET_DATA_LABEL_MAIL_TO)
.attach(Grid::row(0)) .attach(Grid::row(0))
.attach(Grid::column(1)) .attach(Grid::column(1))
.style(STYLE_MAIL_LABEL) .style(STYLE_MAIL_LABEL)
@@ -328,7 +325,7 @@ impl Template for TicketdataView {
) )
.child( .child(
ComboBox::new() ComboBox::new()
.id(ID_TICKET_DATA_MAIL_TO) .id(ID_TICKET_DATA_COMBO_BOX_MAIL_TO)
.attach(Grid::row(0)) .attach(Grid::row(0))
.attach(Grid::column(3)) .attach(Grid::column(3))
.style(STYLE_MAIL_TO) .style(STYLE_MAIL_TO)