13 Commits

Author SHA1 Message Date
fafd38f210 widgets/configuration: reference styling to theme handling
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-08 18:52:41 +01:00
667a2e39bf 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>
2020-11-08 18:47:43 +01:00
c90099e1cf 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>
2020-11-08 18:45:33 +01:00
9624567dbd assets: update theme definitions for default_dark.ron
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-08 18:43:29 +01:00
014b98bd85 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>
2020-11-07 13:14:14 +01:00
8fd512b83f theme update dark
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 20:23:32 +01:00
85f9fdf7db widget/configuration: correcting label constant
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 20:10:16 +01:00
c4d6506dee language: update
* update constants
* adopt width of languages combo box

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 20:10:07 +01:00
646955c0fb widget/policycheck: intoduce os dependent theme handling
* theme_fluent: only makes sense in windows environment

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 20:02:17 +01:00
df6bae482c widgets/localization: update label constant
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 20:00:19 +01:00
00ad56ce71 assets: adapt default_dark theme definitions
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 17:51:45 +01:00
6350d14ce7 assets: adapt fluent_dark theme definitions
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 17:49:57 +01:00
e8a86e8afd policycheck:
* 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>
2020-11-05 17:46:18 +01:00
176 changed files with 2560 additions and 7470 deletions

12
.gitmodules vendored
View File

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

View File

@@ -1,5 +1,5 @@
[package] [package]
name = "advotracker" name = "advotracker-framework"
version = "0.1.0" version = "0.1.0"
authors = ["Ralf Zerres <ralf.zerres@networkx.de>"] authors = ["Ralf Zerres <ralf.zerres@networkx.de>"]
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"
@@ -8,39 +8,10 @@ homepage = "https://gitea.networkx.de:50443/rzerres/advotracker"
documentation = "https://docs.rs/advotracker" documentation = "https://docs.rs/advotracker"
readme = "README.md" readme = "README.md"
license = "0BSD OR MIT" license = "0BSD OR MIT"
keywords = [
"advotracker",
"lawyer",
]
edition = "2018" edition = "2018"
publish = false publish = false
#default-run = "advotracker_client"
[dependencies]
advotracker_db = { version = "0.1.0-alpha1", path = "advotracker_db" }
advotrackerd = { version = "0.1.0-alpha1", path = "advotrackerd", default-features = false }
advotracker_client = { version = "0.1.8", path = "advotracker_client", default-features = false }
[features]
default = ["sqlite"]
# enable optional db backends
sqlite = []
#sqlite = ["advotracker_db_sqlite"]
#postgresql = ["advotracker_db_pstgresql"]
[profile.dev]
#opt-level = 0
opt-level = 1
incremental = true
debug = true
lto = false
codegen-units = 5
panic = 'unwind'
overflow-checks = true
[profile.release] [profile.release]
incremental = true
panic = "abort" panic = "abort"
lto = true lto = true
codegen-units=1 codegen-units=1
@@ -50,6 +21,15 @@ opt-level="s"
# optimize to smallest size # optimize to smallest size
#opt-level = "z" #opt-level = "z"
[profile.dev]
opt-level = 0
debug = true
lto = false
codegen-units = 5
panic = 'unwind'
incremental = true
overflow-checks = true
[profile.test] [profile.test]
opt-level = 0 opt-level = 0
debug = 2 debug = 2
@@ -64,6 +44,7 @@ overflow-checks = true
[workspace] [workspace]
members = [ members = [
"advotrackerd", "advotrackerd",
"advotracker_db", "advotracker-db",
"advotracker_client", "advotracker",
"advotracker_qml",
] ]

View File

@@ -6,14 +6,14 @@
## About ## About
`advotracker` supports lawyers to capture relevant data encountered during an online `AdvoTracker` supports lawyers to capture relevant data encountered during an online
legal advice. legal advice.
The application components are implemented using the programming language *Rust*. The application components are implemented using the programming language *Rust*.
The graphical user interface (GUI) uses the class-lib *OrbTk*, which is natively The graphical user interface (GUI) uses the class-lib *OrbTk*, which is natively
encoded in *Rust* as well. encoded in *Rust* as well.
`advotracker` can be deployed on every target operating system that is officialy `AdvoTracker` can be deployed on every target operating system that is officialy
supported by the `OrbTK` toolkit. Currently included are: supported by the `OrbTK` toolkit. Currently included are:
* macOS * macOS
@@ -36,24 +36,24 @@ as documentation sources.
Dialogs and messages generated inside the application will respect the system language Dialogs and messages generated inside the application will respect the system language
of the active user. This is adaptable via the environment variable of the active user. This is adaptable via the environment variable
(default: LANG = en_US.UTF8 or LANG = C). (default: LANG = en_US.UTF8 ).
Within the source code you can find translated constants in the subdirectory 'locales' Within the source code you can find translated constants in the subdirectory 'locales'
(<crate-root>/src/locales/advotracker.json). (<src-root>/advotracker/src/locales/advotracker.json).
For every supported language-string, you will find a block starting with the For every supported language-string, you will find a block starting with the
generic message code, followed by the target language translation. Translation lines generic message code, followed by the target language translation. Translation lines
are identified by its ISO Code (e.g. de_DE.UTF8, es_ES.UTF8). are identified by its ISO Code (e.g. de_DE.UTF8, es_ES.UTF8).
## Installation from source code ## Installation from source code
You can either download the `advotracker` source code as a Zip-File or using `git` You can either download the `Advotracker` source code as a Zip-File or using `git`
from projects repositoy URL. from projects repositoy URL.
The source code is subdiveded in three crates: The source code is subdiveded in three submodules:
* advotracker * advotracker
* advotrackerd * advotrackerd
* advotrackerdb * advotracker-db
Currently the given WEB-URL certificate is signed by a Microsoft CA. Currently the given WEB-URL certificate is signed by a Microsoft CA.
Since this CA can't be verified from offical CA-lists you have to proceed as follows: Since this CA can't be verified from offical CA-lists you have to proceed as follows:
@@ -149,7 +149,7 @@ This work is licensed under a [Creative Common License 4.0][License-CC_BY]
![Creative Common Logo][Logo-CC_BY] ![Creative Common Logo][Logo-CC_BY]
<EFBFBD> 2020-2021 Ralf Zerres, Networkx GmbH <EFBFBD> 2020 Ralf Zerres, Networkx GmbH
--- ---

1
advotracker-db Submodule

Submodule advotracker-db added at d29c747d7b

48
advotracker/Cargo.toml Normal file
View File

@@ -0,0 +1,48 @@
[package]
name = "advotracker"
version = "0.1.4"
authors = ["Ralf Zerres <ralf.zerres@networkx.de>"]
description = "Frontend component that supports lawyers to capture relevant data encountered during an online legal advice."
readme = "README.md"
license = "(0BSD OR MIT)"
edition = "2018"
default-run = "advotracker"
[target.x86_64-pc-windows-gnu]
linker = "/usr/bin/x86_64-w64-mingw32-gcc"
ar = "/usr/x86_64-w64-mingw32i/bin/ar"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winuser"] }
#diesel = { version = "1.4", features = [ "postgres", "sqlite" ] }
[dependencies]
async-stream = "~0.2"
chrono = { version = "~0.4.0", features = ["serde"] }
clap = { version = "~2.33", features = ["suggestions", "color"] }
csv = { version = "~1.1" }
dotenv = { version = "~0.15.0" }
envy = { version = "~0.4" }
lazy_static = { version = "~1.4.0" }
log = { version = "~0.4.8" }
locales = { version = "~0.1" }
#orbtk = { version = "~0.3.1-alpha4" }
orbtk = { git = "https://github.com/redox-os/orbtk.git", branch = "develop" }
#orbtk = { path = "../../orbtk" }
serde = { version = "~1.0", features = ["derive"] }
#tokio = { version = "~0.2", features = ["macros", "rt-threaded", "stream", "time"] }
tracing = { version = "~0.1" }
tracing-subscriber = { version = "~0.2.0", features = ["tracing-log"] }
viperus = { git = "https://github.com/maurocordioli/viperus", features = ["cache", "fmt-clap", "fmt-env", "global", "watch"] }
[features]
# no features by default
default = []
debug = ["orbtk/debug"]
light = []
[package.metadata.bundle]
name = "advotracker"
identifier = "nwx.advotracker"
short_description = "Online legal advice helper."
description = "Supports lawyers to capture relevant data encountered during an online legal advice.\n"

View File

@@ -0,0 +1,46 @@
// *
// * advotracker - Hotline tackingtool for Advocats
// *
// * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
// * SPDX-License-Identifier: (0BSD or MIT)
// */
// the language class
Dictionary (
// the map of active identifiers
// like a struct, but keys are also values instead of just beenig identifiers
words: {
// policycheck_view
"Validation policy number": "Prüfung Versicherungsnummer",
"Policy number": "Versicherungsnummer",
"Policy code": "ID der Vers.-Nummer",
"Checklist elements: ": "Prüflistenelemente: ",
"Check result": "Prüfungsergebnis",
"Importing data": "Importiere Datensätze",
"Processing time": "Bearbeitungszeit",
"Error:": "Fehler:",
"Reason": "Grund",
"Policy number is to long": "Die Nummer ist zu lang",
"Policy number is to short": "Die Nummer ist zu kurz",
"The given policy number is invalid": "Die Versicherungsnummer ist ungültig",
"The given policy number is valid": "Die Versicherungsnummer ist gültig",
"Only numbers are valid": "Nur Nummern sind zulässig",
"Account": "Benutzer",
"Toggle theme": "Thema wechseln",
"Quit": "Beenden",
// localization view
"Language ID": "Sprache ID",
"Localization dialog": "Lokalisierungs-Dialog",
"German": "Deutsch",
"English": "Englisch",
// configuration view
"Configuration settings": "Konfigurationseinstellungen",
"Configuration file": "Konfigurationsdatei",
"Language Id": "Sprach-Id",
"Default theme": "Standard-Thema",
"load": "laden",
"save": "speichern"
}
)

View File

@@ -0,0 +1,54 @@
Theme (
styles: {
"button_menu": (
base: "button",
properties: {
"padding": 4,
"border_radius": 0,
},
),
"container_form": (
base: "container",
properties: {
"padding": 14,
"border_width": 1,
"border_radius": 0,
"border_brush": "$CONTAINER_BORDER",
},
),
"configuration_form": (
base: "container",
properties: {
"margin": 4,
},
),
"container_progress": (
base: "container",
properties: {
"padding": 14,
//"border_width": 1,
//"border_radius": 0,
"border_brush": "$CONTAINER_BORDER",
},
),
"popup_progress": (
base: "popup",
properties: {
//"background": "$BACKGROUND",
"padding": 4,
},
),
"text_block_progress": (
base: "small_text",
properties: {
"background": "$PROGRESS_BAR_BACKGROUND",
},
),
"stack_progress": (
base: "container",
properties: {
"spacing": 10,
},
),
}
)

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 220 B

View File

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 123 B

View File

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 123 B

View File

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 289 B

View File

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

View File

Before

Width:  |  Height:  |  Size: 158 B

After

Width:  |  Height:  |  Size: 158 B

View File

Before

Width:  |  Height:  |  Size: 351 B

After

Width:  |  Height:  |  Size: 351 B

View File

Before

Width:  |  Height:  |  Size: 130 B

After

Width:  |  Height:  |  Size: 130 B

View File

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 193 B

View File

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 452 B

View File

Before

Width:  |  Height:  |  Size: 131 B

After

Width:  |  Height:  |  Size: 131 B

View File

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 223 B

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 768 B

After

Width:  |  Height:  |  Size: 768 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 455 KiB

After

Width:  |  Height:  |  Size: 455 KiB

View File

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 237 KiB

After

Width:  |  Height:  |  Size: 237 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -8,7 +8,7 @@ static ID_CHECK_POLICY_NUMBER: &'static str = "ID_CHECK_POLICY_NUMBER";
static ID_PROGRESS_BAR: &'static str = "ID_PROGRESS_BAR"; static ID_PROGRESS_BAR: &'static str = "ID_PROGRESS_BAR";
enum Action { enum Action {
ParsePolicyNumber, ParsePolicyNumber
} }
#[derive(Default, AsAny)] #[derive(Default, AsAny)]
@@ -16,18 +16,15 @@ struct MainViewState {
action: Option<Action>, action: Option<Action>,
progress_bar: Entity, progress_bar: Entity,
text_box: Entity, text_box: Entity,
progress_counter: f64, //records: HashMap::<String, String>, progress_counter: f64
//records: HashMap::<String, String>,
//record_counter: u64 //record_counter: u64
} }
impl State for MainViewState { impl State for MainViewState {
fn init(&mut self, _: &mut Registry, ctx: &mut Context) { fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.text_box = ctx self.text_box = ctx.entity_of_child(ID_CHECK_POLICY_NUMBER).expect("Cannot get TextBox!");
.entity_of_child(ID_CHECK_POLICY_NUMBER) self.progress_bar = ctx.entity_of_child(ID_PROGRESS_BAR).expect("Cannot get progress bar !");
.expect("Cannot get TextBox!");
self.progress_bar = ctx
.entity_of_child(ID_PROGRESS_BAR)
.expect("Cannot get progress bar !");
} }
fn update(&mut self, _: &mut Registry, ctx: &mut Context) { fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
@@ -35,10 +32,7 @@ impl State for MainViewState {
if let Some(action) = &self.action { if let Some(action) = &self.action {
match action { match action {
Action::ParsePolicyNumber => { Action::ParsePolicyNumber => {
let value_to_parse = ctx let value_to_parse = ctx.get_widget(self.text_box).get::<String16>("text").clone();
.get_widget(self.text_box)
.get::<String16>("text")
.clone();
self.parse_policy_number(value_to_parse, ctx); self.parse_policy_number(value_to_parse, ctx);
} }
} }
@@ -87,7 +81,9 @@ widget!(MainView<MainViewState>);
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.margin(32.0).child( self
.margin(32.0)
.child(
Stack::new() Stack::new()
.orientation("vertical") .orientation("vertical")
.h_align("center") .h_align("center")
@@ -99,14 +95,16 @@ impl Template for MainView {
.water_mark("Mut value and type <Return>") .water_mark("Mut value and type <Return>")
.on_activate(move |states, _entity| { .on_activate(move |states, _entity| {
// you have to fire a new event to be able to get in the update() with access to Context // you have to fire a new event to be able to get in the update() with access to Context
states states.get_mut::<MainViewState>(id).action(Action::ParsePolicyNumber);
.get_mut::<MainViewState>(id)
.action(Action::ParsePolicyNumber);
}) })
.build(ctx), .build(ctx)
) )
.child(ProgressBar::new().id(ID_PROGRESS_BAR).build(ctx)) .child(
.build(ctx), ProgressBar::new()
.id(ID_PROGRESS_BAR)
.build(ctx)
)
.build(ctx)
) )
} }
} }

View File

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

View File

@@ -0,0 +1,98 @@
{
"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,23 +1,20 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use chrono::{DateTime, Local}; 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::{ use std::env;
collections::HashMap, use std::{error::Error, process};
env, use std::collections::HashMap;
{error::Error, process},
//path::{Path, PathBuf},
};
use tracing::{debug, trace, Level}; use tracing::{debug, trace, Level};
use advotracker::data::structures::{PolicyCode, PolicyData, PolicyDataList, PolicyList}; use advotracker::data::structures::{PolicyCode, PolicyList, PolicyDataList, PolicyData};
// include modules // include modules
mod parse_args; mod parse_args;
@@ -52,6 +49,14 @@ 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);
@@ -77,15 +82,12 @@ fn export(p: &mut String, lang: &String) -> Result<u64, Box<dyn Error>> {
/// import from csv format /// import from 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/
fn import( fn import(p: &mut String, data_list: &mut PolicyDataList,
p: &mut String, policy_numbers: &mut HashMap<u64, PolicyCode>, lang: &String)
data_list: &mut PolicyDataList, -> Result<u64, Box<dyn Error>> {
policy_numbers: &mut HashMap<u64, PolicyCode>,
lang: &String,
) -> Result<u64, Box<dyn Error>> {
use std::ffi::OsStr;
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
use std::ffi::OsStr;
let mut res = t!("csv.import.started", lang); let mut res = t!("csv.import.started", lang);
let mut state = t!("state.started", lang); let mut state = t!("state.started", lang);
@@ -101,6 +103,10 @@ fn import(
// 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
@@ -166,12 +172,10 @@ fn import(
#[allow(dead_code)] #[allow(dead_code)]
/// validate a given policy number /// validate a given policy number
/// result will return true or false /// result will return true or false
fn is_valid( fn is_valid(policy_number: &u64, policy_list: &PolicyDataList,
policy_number: &u64, policy_numbers: &mut HashMap<u64, PolicyCode>, lang: &String)
policy_list: &PolicyDataList, -> Result<bool, Box<dyn std::error::Error>> {
policy_numbers: &mut HashMap<u64, PolicyCode>,
lang: &String,
) -> Result<bool, Box<dyn std::error::Error>> {
let mut res = t!("policy.validation.started", lang); let mut res = t!("policy.validation.started", lang);
let mut state = t!("state.started", lang); let mut state = t!("state.started", lang);
let dt_start: DateTime<Local> = Local::now(); let dt_start: DateTime<Local> = Local::now();
@@ -191,6 +195,7 @@ fn is_valid(
// println!("policy_list: {:?} (with {:?} elements)", // println!("policy_list: {:?} (with {:?} elements)",
// policy_list.name, policy_list.policy_data.len()); // policy_list.name, policy_list.policy_data.len());
// policy_list.into_iter() // policy_list.into_iter()
// .filter(|num| matches(w, w1)) // .filter(|num| matches(w, w1))
// .clone // .clone
@@ -234,13 +239,14 @@ fn is_valid(
match policy_numbers.get(&policy_number) { match policy_numbers.get(&policy_number) {
Some(&policy_code) => { Some(&policy_code) => {
let res = t!("policy.validation.success", lang); let res = t!("policy.validation.success", lang);
println!("policy_number: {} ({:?})", policy_number, policy_code); println!("policy_number: {} ({:?})",
policy_number, policy_code);
result = true; result = true;
trace!(target: "csv-test", trace!(target: "csv-test",
policy_number = ?policy_number, policy_number = ?policy_number,
validation = ?res, validation = ?res,
policy_code = ?policy_code); policy_code = ?policy_code);
} },
_ => { _ => {
let res = t!("policy.validation.failed", lang); let res = t!("policy.validation.failed", lang);
//println!("Noop! Number isn't valid!"); //println!("Noop! Number isn't valid!");
@@ -248,8 +254,9 @@ fn is_valid(
trace!(target: "csv-test", trace!(target: "csv-test",
policy_number = ?policy_number, policy_number = ?policy_number,
validation = ?res); validation = ?res);
},
} }
}
let dt_end: DateTime<Local> = Local::now(); let dt_end: DateTime<Local> = Local::now();
let duration = dt_end.signed_duration_since(dt_start); let duration = dt_end.signed_duration_since(dt_start);
@@ -298,13 +305,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv().ok(); dotenv().ok();
match envy::from_env::<Environment>() { match envy::from_env::<Environment>() {
Ok(environment) => { Ok(environment) => {
if environment.test_lang != lang { if environment.test_lang != lang { lang = environment.test_lang; }
lang = environment.test_lang; },
} Err(e) => { debug!(target: "csv-test", "{}", e); }
}
Err(e) => {
debug!(target: "csv-test", "{}", e);
}
} }
// how to handle unumplemented lang resources?? // how to handle unumplemented lang resources??
res = t!("parse.environment", lang); res = t!("parse.environment", lang);
@@ -330,8 +333,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);
// create policy structures // importing policy code elements from csv-file
let policy_list = PolicyList::new("Allianz Versicherungsnummen-Liste"); let policy_list = PolicyList::new("Allianz Versicherungsnummen-List");
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");
@@ -340,12 +343,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut policy_numbers : HashMap<u64, PolicyCode> = HashMap::new(); let mut policy_numbers : HashMap<u64, PolicyCode> = HashMap::new();
let mut csv_import_path = v.get::<String>("import_file").unwrap(); let mut csv_import_path = v.get::<String>("import_file").unwrap();
match import( match import(&mut csv_import_path, &mut policy_data,
&mut csv_import_path, &mut policy_numbers, &lang) {
&mut policy_data,
&mut policy_numbers,
&lang,
) {
Ok(count) => { Ok(count) => {
println!("Imported {:?} records", count); println!("Imported {:?} records", count);
} }
@@ -356,13 +355,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
// test if policy_number is_valid // test if policy_number is_valid
// type conversion (viperus String -> u64) let test_policy_number = v.get::<i32>("test_policy_number").unwrap() as 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
@@ -370,13 +365,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Some(&policy_code) => { Some(&policy_code) => {
let res = t!("policy.validation.success", lang); let res = t!("policy.validation.success", lang);
println!("{:?}", res); println!("{:?}", res);
println!("policy_number: {} ({:?})", test_policy_number, policy_code); println!("policy_number: {} ({:?})",
test_policy_number, policy_code);
} }
_ => { _ => {
let res = t!("policy.validation.failed", lang); let res = t!("policy.validation.failed", lang);
println!("{:?}", res); println!("{:?}", res);
//println!("Nuup! Number isn't valid!"); //println!("Nuup! Number isn't valid!");
} },
} }
// export policy code elements to csv-file // export policy code elements to csv-file
@@ -398,30 +394,3 @@ 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

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
// parse CLI commandline arguments with clap // parse CLI commandline arguments with clap
@@ -25,32 +25,25 @@ 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", String::from("9999999992")); v.add_default("test_policy_number", 123456789);
v.add_default( v.add_default("to_email_address_file", String::from("Allianz RA-Hotline <smr-rahotline@allianz.de>"));
"to_email_address_file", v.add_default("from_email_address_file", String::from("Allianz-Hotline RA-Hiedemann <azhotline@hiedemann.de>"));
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("username", String::from("nctalkbot")); //v.add_default("username", String::from("nctalkbot"));
//v.add_default("password", String::from("botpassword")); //v.add_default("password", String::from("botpassword"));
v.add_default("verbose", 0); v.add_default("verbose", 0);
// CLI arguments are defined inline // CLI arguments are defined inline
let matches = App::new("csv-test") let matches = App::new("csv-test")
.name(crate_name!()) .name(crate_name!())
.version(crate_version!()) .version(crate_version!())
.author(crate_authors!()) .author(crate_authors!())
.about(crate_description!()) .about(crate_description!())
.after_help( .after_help("
"
Testprogramm: Allianz Online-Beratung Im/Export CSV-Daten Testprogramm: Allianz Online-Beratung Im/Export CSV-Daten
Direct-Call via IVR-System (Interactive Voice Response) Direct-Call via IVR-System (Interactive Voice Response)
SMR Deckungssummen-Prüfung: 089 92529 60211 SMR Deckungssummen-Prüfung: 089 92529 60211
SMR Unerledigt: 089 92529 60222", SMR Unerledigt: 089 92529 60222")
)
.template( .template(
"\ "\
{bin} v{version} {bin} v{version}
@@ -195,7 +188,7 @@ SMR Unerledigt: 089 92529 60222",
); );
println!( println!(
"test_policy_number: {:?}", "test_policy_number: {:?}",
v.get::<String>("test_policy_number").unwrap_or_default() v.get::<i32>("test_policy_number").unwrap_or_default()
); );
// println!( // println!(
// "username: {:?}", // "username: {:?}",

View File

@@ -1,5 +1,11 @@
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)
@@ -9,8 +15,12 @@ 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)]
@@ -48,16 +58,23 @@ impl State for MainViewState {
// //ctx.widget().set("policynumber", background("#5b0f22")); // //ctx.widget().set("policynumber", background("#5b0f22"));
//} //}
Action::EntryActivated(entity) => { Action::EntryActivated(entity) => {
//let text = ctx.get_widget(entity).clone::<String>("text"); let mut text_box = TextBox::get(ctx.get_widget(entity));
let widget = ctx.get_widget(entity); let text = text_box.text_mut();
let text = widget.get::<String>("text"); //let mut widget = ctx.get_widget(entity);
//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::<String>("text"); let text = widget.get::<String16>("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;
@@ -66,7 +83,11 @@ impl State for MainViewState {
} }
fn create_header(ctx: &mut BuildContext, text: &str) -> Entity { fn create_header(ctx: &mut BuildContext, text: &str) -> Entity {
TextBlock::new().text(text).style("header").build(ctx) TextBlock::new()
.text(text)
//.element("text-block")
.style("header")
.build(ctx)
} }
widget!( widget!(
@@ -80,10 +101,28 @@ 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")
.columns(Columns::create().push(150.0).push("*").push(150.0).build()) //.width(200.0)
.rows(Rows::create().push("*").push("*").build()) //.height(360.0)
.columns(
Columns::new()
.add(150.0)
.add("*")
//.add(120.0)
//.add("auto")
.add(150.0)
.build(),
)
.rows(
Rows::new()
.add("*")
.add("*")
.build(),
)
.child( .child(
Grid::new() Grid::new()
//.element("policyholder_check") //.element("policyholder_check")
@@ -101,22 +140,27 @@ 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 |ctx, entity| { .on_activate(move |states, entity| {
state(id, ctx).action(Action::EntryActivated(entity)); state(id, states).action(Action::EntryActivated(entity));
}) })
.on_changed("text", move |ctx, entity| { .on_changed(move |states, entity| {
state(id, ctx).action(Action::EntryChanged(entity)); state(id, states).action(Action::EntryChanged(entity));
}) })
.build(ctx), .build(ctx),
) )
@@ -132,32 +176,32 @@ impl Template for MainView {
) )
.build(ctx), .build(ctx),
) )
.build(ctx), .build(ctx)
) )
.child( .child(
Grid::new() Grid::new()
//.class("logo_customer") //.element("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("assets/images/customer_logo.png") .image("./resources/images/hiedemann_logo.png")
.build(ctx), .build(ctx),
) )
.build(ctx), .build(ctx),
) )
.child( .child(
Grid::new() Grid::new()
//.class("logo_vendor") //.element("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("assets/images/networkx_logo.png") .image("./resources/images/networkx_logo.png")
.build(ctx), .build(ctx),
) )
.build(ctx), .build(ctx),

View File

@@ -0,0 +1,88 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
// Styles (RON based theme system)
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_STACK_MENU: &str = "stack_menu";
// Widget IDs (DCES: Entity[id] => [Component1, .. , Component<n>] -> data or state)
pub static ID_CONFIGURATION_FORM: &str = "configuration_form";
pub static ID_CONFIGURATION_HEADER: &str = "configuration_header";
pub static ID_CONFIGURATION_LABEL_CONFIG_FILE: &str = "configuration_label_config_file";
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_LANGUAGE_ID: &str = "configuration_language_id";
pub static ID_LOCALIZATION_FORM: &str = "localization_form";
pub static ID_LOCALIZATION_HEADER: &str = "localization_header";
pub static ID_LOCALIZATION_LANGUAGES: &str = "localization_languages";
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_MENU_POPUP: &str = "menu_popup";
pub static ID_MENU_STACK: &str = "menu_stack";
pub static ID_MENU_BUTTON: &str = "menu_button";
pub static ID_MENU_GRID: &str = "menu_grid";
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_TOGGLE_THEME: &str = "menu_label_toggle_theme";
pub static ID_MENU_SHORTCUT_QUIT: &str = "menu_shortcut_quit";
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_FORM_ROW_0: &str = "policy_check_form_row_0";
pub static ID_POLICY_CHECK_FORM_ROW_1: &str = "policy_check_form_row_1";
pub static ID_POLICY_CHECK_FORM_ROW_2: &str = "policy_check_form_row_2";
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_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_HINT: &str = "policy_check_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_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_POLICY_NUMBER: &str = "policy_check_policy_number";
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_TIME: &str = "policy_check_progress_time";
pub static ID_POLICY_CHECK_PROGRESS_TEXT: &str = "policy_check_progress_text";
pub static ID_POLICY_CHECK_RESULT: &str = "policy_check_result";
pub static ID_POLICY_CHECK_WIDGET: &str = "policy_check_widget";
pub static ID_POLICY_DATA_ADD_BUTTON: &str = "policy_data_add_button";
pub static ID_POLICY_DATA_COUNT: &str = "policy_data_count";
pub static ID_POLICY_DATA_LABEL: &str = "policy_data_label";
pub static ID_POLICY_DATA_ITEMS_WIDGET: &str = "policy_data_items_widget";
pub static ID_POLICY_DATA_DATE_INSERTED: &str = "policy_data_date_inserted";
pub static ID_POLICY_DATA_DION: &str = "policy_data_dion";
pub static ID_POLICY_DATA_POLICY_CODE: &str = "policy_data_policy_code";
pub static ID_POLICY_DATA_POLICY_NUMBER: &str = "policy_data_policy_number";
pub static ID_POLICY_DATA_STACK: &str = "policy_data_stack";
pub static ID_POLICY_DATA_STATUS: &str = "policy_data_status";
pub static ID_POLICY_DATA_LIST_NAME: &str = "policy_data_list_name";
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_TEXT_BOX: &str = "policy_list_text_box";
// Component Values (Properties)
pub static PROP_ADVOTRACKER: &str = "advotracker";
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";

View File

@@ -1,10 +1,11 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// provides orbtk widgets constants /// provides orbtk widgets constants
pub mod constants; pub mod constants;

View File

@@ -1,8 +1,7 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT) * SPDX-License-Identifier: (0BSD or MIT)
*/ */
@@ -15,13 +14,11 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
pub enum PolicyCode { pub enum PolicyCode {
/// Allianz Sachversicherung /// Allianz Sachversicherung
AS, AS
} }
impl Default for PolicyCode { impl Default for PolicyCode {
fn default() -> Self { fn default() -> Self { PolicyCode::AS }
PolicyCode::AS
}
} }
/// Classifier of the Allinaz DirectCall communication type. /// Classifier of the Allinaz DirectCall communication type.
@@ -61,13 +58,11 @@ pub enum CommunicationType {
/// Zeugins /// Zeugins
ZE, ZE,
/// Typ is unspecified /// Typ is unspecified
XX, XX
} }
impl Default for CommunicationType { impl Default for CommunicationType {
fn default() -> Self { fn default() -> Self { CommunicationType::XX }
CommunicationType::XX
}
} }
/// Status of a given policy data element. /// Status of a given policy data element.
@@ -76,13 +71,11 @@ pub enum Status {
/// Active -> the policy is active an supported /// Active -> the policy is active an supported
Active, Active,
/// Inactive -> the policy is inactive or resigned /// Inactive -> the policy is inactive or resigned
Inactive, Inactive
} }
impl Default for Status { impl Default for Status {
fn default() -> Self { fn default() -> Self { Status::Active }
Status::Active
}
} }
/// A communication type describes possible classifications of customer calls. /// A communication type describes possible classifications of customer calls.
@@ -92,7 +85,7 @@ pub struct CommunicationData {
/// pub communication_type: CommunicationType, /// pub communication_type: CommunicationType,
pub communication_type: String, pub communication_type: String,
/// A literal name describing the selected communication type /// A literal name describing the selected communication type
pub communication_name: String, pub communication_name: String
} }
/// CSV Export /// CSV Export
@@ -117,39 +110,6 @@ 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,7 +117,7 @@ pub struct HarmData {
pub harm_data: Vec<HarmType>, pub harm_data: Vec<HarmType>,
/// Status der Schadenliste /// Status der Schadenliste
//pub name: String, //pub name: String,
pub selected: bool, pub selected: bool
} }
/// Harm types are destincted by a type code. /// Harm types are destincted by a type code.
@@ -192,11 +152,25 @@ pub struct PolicyCheck {
/// Referenz zur Versicherungsschein-Nummer /// Referenz zur Versicherungsschein-Nummer
pub policy_number: u64, pub policy_number: u64,
/// Validitätsergebnis /// Validitätsergebnis
pub policy_number_status: Status, pub policy_number_status: Status
} }
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 {
@@ -262,12 +236,12 @@ pub struct PolicyDataList {
/// Name der Versicherungsliste /// Name der Versicherungsliste
pub name: String, pub name: String,
/// Status der Versicherungsliste /// Status der Versicherungsliste
pub selected: bool, pub selected: bool
} }
/// implements the helper methods, to manage policy data collections. /// implements the helper methods, to manage policy data collections.
impl PolicyDataList { impl PolicyDataList {
/// Prüfung auf Versicherungselemente /// Prüfung ob Versicherungselemente .
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.policy_data.is_empty() self.policy_data.is_empty()
} }
@@ -341,7 +315,7 @@ pub struct PolicyData {
#[serde(rename = "POLLFNR")] #[serde(rename = "POLLFNR")]
pub policy_number: u64, pub policy_number: u64,
/// Status des Versicherungsscheins /// Status des Versicherungsscheins
pub status: Option<Status>, pub status: Option<Status>
} }
/// Policy Number Set /// Policy Number Set
@@ -356,7 +330,7 @@ pub struct AllianzPolicyNumber {
pub policy_code: String, pub policy_code: String,
/// 10-stellige Versicherungsscheinnummer (numerisch) /// 10-stellige Versicherungsscheinnummer (numerisch)
#[serde(rename = "POLLFNR")] #[serde(rename = "POLLFNR")]
pub policy_number: usize, pub policy_number: usize
} }
// /// List of Allianz Policy Number records // /// List of Allianz Policy Number records

View File

@@ -1,13 +1,12 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: 0BSD, MIT
*/ */
#![crate_name = "advotracker_client"] //#![warn(missing_docs, rust_2018_idioms, rust_2018_compatibility)]
#![crate_type = "lib"] #![warn(rust_2018_idioms, rust_2018_compatibility)]
#![warn(missing_docs, rust_2018_idioms, rust_2018_compatibility)]
//! advotracker //! advotracker
//! Supports lawyers to capture relevant data encountered during an //! Supports lawyers to capture relevant data encountered during an
@@ -24,9 +23,6 @@
//! WIP: provide a workflow image //! WIP: provide a workflow image
//! //!
// i18n: get twine generated translation strings for macro (t!)
include!(concat!(env!("OUT_DIR"), "/i18n.rs"));
// /// The client specific services // /// The client specific services
// pub mod clients; // pub mod clients;

View File

@@ -0,0 +1,238 @@
{
"err.lang.not_found": {
"de_DE.UTF-8": "Konnte Sprachkode nicht auslesen",
"de_DE": "Konnte Sprachkode nicht auslesen",
"C": "Couldn't read LANG"
},
"err.user.not_found": {
"fr": "Utilisateur introuvable: $email, $id",
"de_DE.UTF-8": "Anwender nicht gefunden: $email, $id",
"de_DE": "Anwender nicht gefunden: $email, $id",
"C": "User not found: $email, $id"
},
"main.started": {
"de_DE.UTF-8": "Programmlogik starten",
"de_DE": "Programmlogik starten",
"C": "Program logic started"
},
"main.finished": {
"de_DE.UTF-8": "Programmlogik beendet",
"de_DE": "Programmlogik beendet",
"C": "Program logic finished"
},
"parse.arguments": {
"de_DE.UTF-8": "Programmargumente prüfen",
"de_DE": "Programmargumente prüfen",
"C": "Parsing arguments"
},
"parse.environment": {
"de_DE.UTF-8": "Umgebungsvariablen prüfen",
"de_DE": "Umgebungsvariablen prüfen",
"C": "Parsing environment"
},
"parse.results": {
"de_DE.UTF-8": "Ergebnisse der Konfigurations-Parameterprüfung",
"de_DE": "Ergebnisse der Konfigurationsparameterprüfung",
"C": "Config parsing results"
},
"config.name": {
"de_DE.UTF-8": "Konfigurationswert für",
"de_DE": "Konfigurationswert für",
"C": "Config Value for"
},
"config.name.lang": {
"de_DE.UTF-8": "Sprach-Code_DE",
"de_DE": "Sprach-Code_DE",
"C": "Language code_DE"
},
"config.name.verbositylevel": {
"de_DE.UTF-8": "Ausgabe-Ebene",
"de_DE": "Ausgabe-Ebene",
"C": "verbosity level"
},
"config.name.environment": {
"de_DE.UTF-8": "Umgebungsvariablen",
"de_DE": "Umgebungsvariablen",
"C": "environment"
},
"config.name.configfile": {
"de_DE.UTF-8": "Konfigurations-Datei",
"de_DE": "Konfigurations-Datei",
"C": "config file"
},
"config.name.dbdriver": {
"de_DE.UTF-8": "Datenbank-Treiber",
"de_DE": "Datenbank-Treiber",
"C": "database driver"
},
"config.name.redis": {
"de_DE.UTF-8": "Redis Datenbank",
"de_DE": "Redis Datenbank",
"C": "Redis database"
},
"csv.export.started": {
"de_DE.UTF-8": "Export in eine CSV Datei starten",
"de_DE": "Export in eine CSV Datei starten",
"C": "Export to csv file started"
},
"csv.export.finished": {
"de_DE.UTF-8": "Export in eine CSV Datei beendet",
"de_DE": "Export in eine CSV Datei beendet",
"C": "Export to csv file finished"
},
"csv.import.started": {
"de_DE.UTF-8": "Import aus einer CSV Datei",
"de_DE": "Import aus einer CSV Datei",
"C": "Import from a csv file"
},
"csv.import.finished": {
"de_DE.UTF-8": "Import aus einer CSV Datei beendet",
"de_DE": "Import aus einer CSV Datei beendet",
"C": "Import from a csv file finished"
},
"redis.connection.error": {
"de_DE.UTF-8": "Es konnte keine Redis Verbindung aufgebaut werden",
"de_DE": "Es konnte keine Redis Verbindung aufgebaut werden",
"C": "Could not establish a redis connection"
},
"policy.hashmap.success": {
"de_DE.UTF-8": "Hashmap wurde erfolgreich erstellt",
"de_DE": "Hashmap wurde erfolgreich erstellt",
"C": "Hashmap creation was successfull"
},
"policy.hashmap.failed": {
"de_DE.UTF-8": "Hashmap konnte nicht erstellt werden",
"de_DE": "Hashmap konnte nicht erstellt werden",
"C": "Hashmap creation failed"
},
"policy.menu.label": {
"de_DE.UTF-8": "Menü",
"de_DE": "Menü",
"C": "Menu"
},
"policy.menu.label_account": {
"de_DE.UTF-8": "Aktueller Benutzer",
"de_DE": "Aktueller Benutzer",
"C": "Active user"
},
"policy.menu.label_quit": {
"de_DE.UTF-8": "Beenden",
"de_DE": "Beenden",
"C": "Quit"
},
"policy.menu.label_toggle_theme": {
"de_DE.UTF-8": "Thema wechseln",
"de_DE": "Thema wechseln",
"C": "Toggle theme"
},
"policy.string.header": {
"de_DE.UTF-8": "Validierung Versicherungsnummer",
"de_DE": "Validierung Versicherungsnummer",
"C": "Policy number validation"
},
"policy.string.label_policy_data": {
"de_DE.UTF-8": "Importierte Daten",
"de_DE": "Importierte Daten",
"C": "imported data"
},
"policy.string.label_policy_list": {
"de_DE.UTF-8": "Versicherungsnummern-Liste",
"de_DE": "Versicherungsnummern-Liste",
"C": "policy list"
},
"policy.string.label_policy_number": {
"de_DE.UTF-8": "Versicherungsnummer",
"de_DE": "Versicherungsnummer",
"C": "policy number"
},
"policy.string.label_result": {
"de_DE.UTF-8": "Prüfungsergebnis",
"de_DE": "Prüfungsergebnis",
"C": "check result"
},
"policy.string.data_count": {
"de_DE.UTF-8": "Anzahl Prüflistenelemente",
"de_DE": "Anzahl Prüflistenelemente",
"C": "Number of checklist elements"
},
"policy.string.import_data": {
"de_DE.UTF-8": "Importieren der Prüflisten-Elemente",
"de_DE": "Importieren der Prüflisten-Elemente",
"C": "Import checklist elements"
},
"policy.string.progress_time": {
"de_DE.UTF-8": "Bearbeitungszeit",
"de_DE": "Bearbeitungszeit",
"C": "processing time"
},
"policy.string.progress_text": {
"de_DE.UTF-8": "Importiere Daten",
"de_DE": "Importiere Daten",
"C": "Importing data"
},
"policy.validation.button_failed": {
"de_DE.UTF-8": "ungültig",
"de_DE": "ungültig",
"C": "invalid"
},
"policy.validation.button_success": {
"de_DE.UTF-8": "gültig",
"de_DE": "gültig",
"C": "valid"
},
"policy.validation.failed": {
"de_DE.UTF-8": "Die Versicherungsscheinnummber ist ungültig",
"de_DE": "Die Versicherungsscheinnummber ist ungültig",
"C": "The given policy number is invalid"
},
"policy.validation.new": {
"de_DE.UTF-8": "Neue Prüfung",
"de_DE": "Neue Prüfung",
"C": "New validation"
},
"policy.validation.success": {
"de_DE.UTF-8": "Die Versicherungsscheinnummber ist gültig",
"de_DE": "Die Versicherungsscheinnummber ist gültig",
"C": "The given policy number is valid"
},
"policy.validation.started": {
"de_DE.UTF-8": "Die Prüfung der Versicherungsscheinnummber wurde gestartet",
"de_DE": "Die Prüfung der Versicherungsscheinnummber wurde gestartet",
"C": "Validation of the policy number started"
},
"policy.validation.finished": {
"de_DE.UTF-8": "Die Prüfung der Versicherungsscheinnummber wurde beendet",
"de_DE": "Die Prüfung der Versicherungsscheinnummber wurde beendet",
"C": "Validation of the policy number finished"
},
"policy.validation.invalid_input": {
"de_DE.UTF-8": "Nur Nummer sind zulässig",
"de_DE": "Nur Nummer sind zulässig",
"C": "Only numbers are valid"
},
"policy.validation.not_found": {
"de_DE.UTF-8": "Nummer ist nicht aktiviert",
"de_DE": "Nummer ist nicht aktiviert",
"C": "number isn't marked active"
},
"policy.validation.to_long": {
"de_DE.UTF-8": "Die Nummer ist zu lang",
"de_DE": "Die Nummer ist zu lang",
"C": "Policy number is to long"
},
"policy.validation.to_short": {
"de_DE.UTF-8": "Die Nummer ist zu kurz",
"de_DE": "Die Nummer ist zu kurz",
"C": "Policy number is to short"
},
"state.started": {
"de_DE.UTF-8": "gestartet",
"de_DE": "gestartet",
"C": "started"
},
"state.finished": {
"de_DE.UTF-8": "beendet",
"de_DE": "beended",
"C": "finished"
}
}

212
advotracker/src/main.rs Normal file
View File

@@ -0,0 +1,212 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
// suppress creation of a new console window on window
#![windows_subsystem = "windows"]
//#[macro_use]
//extern crate lazy_static;
//use chrono::{Local, DateTime};
use dotenv::dotenv;
use locales::t;
use cfg_if::cfg_if;
use serde::Deserialize;
use std::env;
//use std::process;
use tracing::{info, trace, Level};
use orbtk::{
prelude::*,
theme_default::{THEME_DEFAULT, THEME_DEFAULT_COLORS_DARK, THEME_DEFAULT_FONTS},
theming::config::ThemeConfig,
};
#[cfg(target_os = "windows")]
use orbtk::theme_fluent::{THEME_FLUENT, THEME_FLUENT_COLORS_DARK, THEME_FLUENT_FONTS};
// The Main view
use advotracker::widgets::main_view;
mod parse_args;
/// 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 {
lang: String,
test_lang: String,
rust_log: String,
}
// Style extension
static DEFAULT_DARK_EXT: &str = include_str!("../assets/advotracker/default_dark.ron");
cfg_if! {
if #[cfg(windows)] {
static FLUENT_DARK_EXT: &str = include_str!("../assets/advotracker/fluent_dark.ron");
static FLUENT_LIGHT_EXT: &str = include_str!("../assets/advotracker/fluent_light.ron");
}
}
// German localization file.
static ADVOTRACKER_DE_DE: &str = include_str!("../assets/advotracker/advotracker_de_DE.ron");
/// Get the active language environment.
fn get_lang() -> String {
// get system environment
let mut lang = env::var("LANG").unwrap_or("C".to_string());
// testing environment: read from .env file
dotenv().ok();
match envy::from_env::<Environment>() {
Ok(environment) => {
if environment.test_lang != lang { lang = environment.test_lang; }
},
Err(e) => { info!(target: "advotracker", "{}", e) }
}
trace!(target: "advotracker", lang = ?lang);
lang
}
cfg_if! {
if #[cfg(windows)] {
/// Extend and register theme assets.
fn theme() -> Theme {
register_default_fonts(Theme::from_config(
ThemeConfig::from(DEFAULT_DARK_EXT)
.extend(ThemeConfig::from(THEME_DEFAULT))
.extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK))
.extend(ThemeConfig::from(THEME_DEFAULT_FONTS)),
))
}
fn theme_fluent() -> Theme {
register_fluent_fonts(Theme::from_config(
ThemeConfig::from(FLUENT_DARK_EXT)
.extend(ThemeConfig::from(THEME_FLUENT))
.extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK))
.extend(ThemeConfig::from(THEME_FLUENT_FONTS)),
))
// register_fluent_fonts(Theme::from_config(
// ThemeConfig::from(FLUENT_LIGHT_EXT)
// .extend(ThemeConfig::from(THEME_FLUENT))
// .extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK))
// .extend(ThemeConfig::from(THEME_FLUENT_FONTS)),
}
} else {
/// Extend and register theme assets.
fn theme() -> Theme {
register_default_fonts(Theme::from_config(
ThemeConfig::from(DEFAULT_DARK_EXT)
.extend(ThemeConfig::from(THEME_DEFAULT))
.extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK))
.extend(ThemeConfig::from(THEME_DEFAULT_FONTS)),
))
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
use parse_args::parse_args;
use tracing_subscriber::fmt;
use viperus::Viperus;
let machine_kind = if cfg!(unix) {
"unix"
} else if cfg!(windows) {
"windows"
} else {
"unknown/unsupported"
};
// respect dotenv environment (e.g for testing)
// -> overwrites the preset default values
let rust_log = dotenv::var("RUST_LOG").unwrap_or_else(|_| String::from("None"));
// initialize the tracing subsystem
// a drop in replacement for classical logging
// reference: https://tokio.rs/blog/2019-08-tracing/
let span = tracing::span!(Level::TRACE, "advotracker");
let _enter = span.enter();
let subscriber = fmt::Subscriber::builder()
.with_env_filter(&rust_log)
//.with_max_level(tracing::Level::DEBUG)
.finish();
tracing::subscriber::with_default(subscriber, || {
// get system environment
let lang = get_lang();
let mut state = t!("state.started", lang);
let mut res = t!("parse.environment", lang);
trace!(target: "advotracker", message = ?res, state = ?state);
trace!(target: "advotracker", environment = "system", lang = ?lang);
trace!(target: "advotracker", machine = ?&machine_kind);
// how to handle unimplemented lang resources??
res = t!("parse.environment", lang);
trace!(target: "advotracker", environment = "envy", lang = ?lang);
state = t!("state.finished", lang);
trace!(target: "advotracker", message = ?res, state = ?state);
// initialize viperus structure
let mut viperus = Viperus::new();
// parse commandline arguments
res = t!("parse.arguments", lang);
state = t!("state.started", lang);
trace!(target: "advotracker", process = ?res, state = ?state);
let _ = parse_args(&mut viperus);
state = t!("state.finished", lang);
trace!(target: "advotracker", process = ?res, state = ?state);
// main tasks
res = t!("main.started", lang);
state = t!("state.started", lang);
trace!(target: "advotracker", process = ?res, state = ?state);
// use this only if you want to run it as web application.
orbtk::initialize();
// if no dictionary is set for the default language e.g. english the content of the text property will drawn.
let localization = RonLocalization::create()
.language("en_US")
.dictionary("de_DE", ADVOTRACKER_DE_DE)
.build();
Application::from_name("nwx.advotracker")
.localization(localization)
.theme(theme())
.window(|ctx| {
Window::new()
.title("AdvoTracker - DirectCall")
.position((500.0, 100.0))
.size(580.0, 320.0)
//.min_width(460.0)
//.min_height(180.0)
.resizeable(true)
.child(main_view::MainView::new().build(ctx))
.build(ctx)
})
.run();
state = t!("state.finished", lang);
res = t!("main.finished", lang);
trace!(target: "advotracker", process = ?res, state = ?state);
});
Ok(())
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}

View File

@@ -1,12 +1,14 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
// parse CLI commandline arguments with clap
use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg}; use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg};
use directories::ProjectDirs;
//use log::{debug, info, trace, warn};
use std::env; use std::env;
use tracing::trace; use tracing::trace;
use viperus::Viperus; use viperus::Viperus;
@@ -14,39 +16,23 @@ use viperus::Viperus;
/// Parse the commandline arguments and preset default values /// Parse the commandline arguments and preset default values
/// Precedence: defaults -> config-file -> environment -> commandline /// Precedence: defaults -> config-file -> environment -> commandline
pub fn parse_args(viperus: &mut Viperus) -> Result<(), Box<dyn std::error::Error>> { pub fn parse_args(viperus: &mut Viperus) -> Result<(), Box<dyn std::error::Error>> {
if cfg!(feature = "parse_cli") { if cfg!(feature = "global") {
trace!(target: "Viperus", "Enabled parsing features."); trace!(target: "Viperus", "Viperus feature 'global' enabled.");
println!("Lasy static: 'VIPERUS' is accessible globaly");
} }
if let Some(proj_dirs) = ProjectDirs::from("de", "Networkx GmbH", "advotracker") { if cfg!(feature = "fmt-clap") {
proj_dirs.config_dir(); trace!(target: "Viperus", "Viperus feature 'fmt-clap' enabled.");
// Lin: $HOME/.config/advotracker println!("Using feature fmt-clap");
// Win: C:\Users\%USERNAME%\AppData\Roaming\Networkx GmbH\advotracker\config
// Mac: /Users/$USER/Library/Application Support/de.Networkx-GmbH.advotracker
trace!(target: "ProjectDirs", "Read from target-os defaults direcories.");
}
if let Some(proj_dirs) = ProjectDirs::from("de", "Networkx GmbH", "advotracker") {
proj_dirs.config_dir();
// Lin: $HOME/.config/advotracker
// Win: C:\Users\%USERNAME%\AppData\Roaming\Networkx GmbH\advotracker\config
// Mac: /Users/$USER/Library/Application Support/de.Networkx-GmbH.advotracker
trace!(target: "directories", config_dir = ?proj_dirs.config_dir().display());
} }
// preset default key/value pairs (lowest priority) // preset default key/value pairs (lowest priority)
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", String::from("9999999992")); viperus.add_default("test_policy_number", 123456789);
viperus.add_default( viperus.add_default("to_email_address_file", String::from("Allianz RA-Hotline <smr-rahotline@allianz.de>"));
"to_email_address_file", viperus.add_default("from_email_address_file", String::from("Allianz-Hotline RA-Hiedemann <azhotline@hiedemann.de>"));
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("username", String::from("nctalkbot")); //viperus.add_default("username", String::from("nctalkbot"));
//viperus.add_default("password", String::from("botpassword")); //viperus.add_default("password", String::from("botpassword"));
viperus.add_default("verbose", 0); viperus.add_default("verbose", 0);
@@ -57,13 +43,11 @@ pub fn parse_args(viperus: &mut Viperus) -> Result<(), Box<dyn std::error::Error
.version(crate_version!()) .version(crate_version!())
.author(crate_authors!()) .author(crate_authors!())
.about(crate_description!()) .about(crate_description!())
.after_help( .after_help("
"
Testprogramm: Allianz Online-Beratung Im/Export CSV-Daten Testprogramm: Allianz Online-Beratung Im/Export CSV-Daten
Direct-Call via IVR-System (Interactive Voice Response) Direct-Call via IVR-System (Interactive Voice Response)
SMR Deckungssummen-Prüfung: 089 92529 60211 SMR Deckungssummen-Prüfung: 089 92529 60211
SMR Unerledigt: 089 92529 60222", SMR Unerledigt: 089 92529 60222")
)
.template( .template(
"\ "\
{bin} v{version} {bin} v{version}
@@ -155,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('_'); env_prefix.push_str("_");
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
@@ -193,15 +177,11 @@ SMR Unerledigt: 089 92529 60222",
); );
println!( println!(
"to_email_address: {:?}", "to_email_address: {:?}",
viperus viperus.get::<String>("to_email_address").unwrap_or_default()
.get::<String>("to_email_address")
.unwrap_or_default()
); );
println!( println!(
"from_email_address: {:?}", "from_email_address: {:?}",
viperus viperus.get::<String>("from_email_address").unwrap_or_default()
.get::<String>("from_email_address")
.unwrap_or_default()
); );
println!( println!(
"test_policy_number: {:?}", "test_policy_number: {:?}",

View File

@@ -1,26 +1,29 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
//use chrono::{Local, DateTime}; //use chrono::{Local, DateTime};
use locales::t;
use std::error::Error; use std::error::Error;
//use std::collections::HashMap;
use tracing::trace; use tracing::trace;
use crate::Lang; //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: &Lang) -> Result<(), Box<dyn Error>> { pub fn export(p: &mut String, lang: &String) -> 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;
let mut res = t!(csv_export_started => lang); let mut res = t!("csv.export.started", lang);
let mut state = t!(state_started => lang); let mut state = t!("state.started", lang);
trace!(target: "csv-export", process = ?res, state = ?state); trace!(target: "csv-export", process = ?res, state = ?state);
// Note: slash syntax also works on Windows! // Note: slash syntax also works on Windows!
@@ -30,8 +33,8 @@ pub fn export(p: &mut String, lang: &Lang) -> Result<(), Box<dyn Error>> {
let file = File::open(path)?; let file = File::open(path)?;
trace!(target: "csv.export", extension = ?path.extension(), file = ?file); trace!(target: "csv.export", extension = ?path.extension(), file = ?file);
state = t!(state_finished => lang); state = t!("state.finished", lang);
res = t!(csv_export_finished => lang); res = t!("csv.export.finished", lang);
trace!(target: "csv-export", process = ?res, state = ?state); trace!(target: "csv-export", process = ?res, state = ?state);
Ok(()) Ok(())

View File

@@ -0,0 +1,9 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
/// Exporting Allianz DirecCall data
pub mod allianzdirectcall;

View File

@@ -1,46 +1,43 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use chrono::{DateTime, Local}; use chrono::{Local, DateTime};
use std::collections::HashMap; use locales::t;
use std::error::Error; use std::error::Error;
use std::collections::HashMap;
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use tracing::trace; use tracing::trace;
//use crate::db::redis; //use crate::db::redis;
use crate::{ use crate::data::structures::{PolicyCode, PolicyDataList, PolicyData};
data::structures::{PolicyCode, PolicyData, PolicyDataList}, //use crate::data::structures::PolicyDataList;
Lang,
};
/// import AllianzDirectCall data from a csv delimeted file /// import AllianzDirectCall data from a csv delimeted file
/// save records to redis backend /// save records to redis backend
/// 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 import( pub fn import(p: &mut String, data_list: &mut PolicyDataList,
path: &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,
) -> Result<(u64, Duration), Box<dyn Error>> { lang: &String)
use std::ffi::OsStr; -> Result<(u64, Duration), Box<dyn Error>> {
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
use std::ffi::OsStr;
let lang = Lang::De(""); let mut res = t!("csv.import.started", lang);
let mut res = t!(csv_import_started => lang); let mut state = t!("state.started", lang);
let mut state = t!(state_started => lang);
let time_start = SystemTime::now(); let time_start = SystemTime::now();
let datetime: DateTime<Local> = time_start.into(); let datetime: DateTime<Local> = time_start.into();
trace!(target: "csv-import", process = ?res, state = ?state, date_start = ?datetime.to_string()); trace!(target: "csv-import", process = ?res, state = ?state, date_start = ?datetime.to_string());
// Note: slash syntax also works on Windows! // Note: slash syntax also works on Windows!
let path = Path::new(path); let path = Path::new(p);
// must be a readable file // must be a readable file
trace!(target: "csv-import", path = ?path); trace!(target: "csv-import", path = ?path);
@@ -86,16 +83,15 @@ pub fn import(
count +=1; count +=1;
*policy_data_count = count; *policy_data_count = count;
} };
let time_end = SystemTime::now(); let time_end = SystemTime::now();
let duration = time_end let duration = time_end.duration_since(time_start)
.duration_since(time_start)
.expect("Clock may have gone backwards"); .expect("Clock may have gone backwards");
trace!(target: "csv-import", record_count = ?count, duration = ?duration); trace!(target: "csv-import", record_count = ?count, duration = ?duration);
state = t!(state_finished => lang); state = t!("state.finished", lang);
res = t!(csv_import_finished => lang); res = t!("csv.import.finished", lang);
let datetime: DateTime<Local> = time_end.into(); let datetime: DateTime<Local> = time_end.into();
trace!(target: "csv-import", process = ?res, state = ?state, date_stop = ?datetime.to_string()); trace!(target: "csv-import", process = ?res, state = ?state, date_stop = ?datetime.to_string());
@@ -114,13 +110,9 @@ fn test_import() {
let mut policy_data_count: u64 = 0; let mut policy_data_count: u64 = 0;
let lang = "en".to_string(); let lang = "en".to_string();
match import( match import(&mut csv_import_path, &mut policy_data,
&mut csv_import_path, &mut policy_numbers, &mut policy_data_count,
&mut policy_data, &lang) {
&mut policy_numbers,
&mut policy_data_count,
&lang,
) {
Ok((count, duration)) => { Ok((count, duration)) => {
println!("import {:?} records. Duration: {:?}", count, duration); println!("import {:?} records. Duration: {:?}", count, duration);
} }

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use std::error::Error; use std::error::Error;
@@ -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!("import error: {}", err); println!("error running example: {}", err);
process::exit(1); process::exit(1);
} }
} }

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// Importing Allianz DirecCall data /// Importing Allianz DirecCall data

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// advotracker import modules /// advotracker import modules

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;
@@ -14,16 +14,17 @@ use crate::widgets::configuration::configuration_view::ConfigurationView;
/// Valid `actions` that are handled as state changes in the `Configuration` widget. /// Valid `actions` that are handled as state changes in the `Configuration` widget.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum ConfigurationAction { pub enum ConfigurationAction {
/// Save configuration data
SaveConfiguration, SaveConfiguration,
/// Load configuration data
LoadConfiguration, LoadConfiguration,
} }
/// Define valid configuration data. /// Define valid configuration data.
/// This structure is serialized and saved inside the OS dependent settings file. /// This structure is serialized and saved inside the OS dependent settings file.
#[derive(Default, Debug, Clone, Serialize, Deserialize)] #[derive(Default, Debug, Clone, Serialize, Deserialize)]
struct ConfigurationData(pub String, pub String); struct ConfigurationData(
pub String,
pub String
);
/// Valid `structures` that are handled inside the state of the `Configuration` widget. /// Valid `structures` that are handled inside the state of the `Configuration` widget.
#[derive(Debug, Default, AsAny)] #[derive(Debug, Default, AsAny)]
@@ -38,28 +39,25 @@ impl State for ConfigurationState {
) { ) {
for message in messages.read::<ConfigurationAction>() { for message in messages.read::<ConfigurationAction>() {
match message { match message {
ConfigurationAction::LoadConfiguration => { ConfigurationAction::LoadConfiguration => registry
registry
.get::<Settings>("settings") .get::<Settings>("settings")
.load_async::<ConfigurationData>( .load_async::<ConfigurationData>("configuration_data".to_string(), ctx.entity()),
"configuration_data".to_string(),
ctx.entity(),
);
}
ConfigurationAction::SaveConfiguration => { ConfigurationAction::SaveConfiguration => {
let configuration_file: String = let configuration_file: String = ConfigurationView::configuration_file_clone(&ctx.widget());
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.get::<Settings>("settings").save_async(
"configuration_data".to_string(), "configuration_data".to_string(),
ConfigurationData(configuration_file, language_id), ConfigurationData(
configuration_file,
language_id
),
ctx.entity(), ctx.entity(),
); );
} }
} }
} }
// save the result // save result
for message in messages.read::<SettingsResult<()>>() { for message in messages.read::<SettingsResult<()>>() {
println!("Result {:?}", message); println!("Result {:?}", message);
} }

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;
@@ -14,11 +14,8 @@ use crate::{
// Macro that initializes the widget structures/variables for our view // Macro that initializes the widget structures/variables for our view
widget!( widget!(
/// Configuration View
ConfigurationView<ConfigurationState> { ConfigurationView<ConfigurationState> {
/// Configuration file
configuration_file: String, configuration_file: String,
/// Language identifier
language_id: String language_id: String
} }
); );
@@ -30,17 +27,21 @@ 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::create().push(120).push(12).push("auto")) .columns(
.rows( Columns::create()
Rows::create() .push(120)
.push("auto") // Header_Bar .push(12)
.push(4) // Seperator .push("auto")
.push("auto") // Configuartion_File )
.push(4) // Seperator .rows(Rows::create()
.push("auto") // Language_ID .push("auto")
.push(12) // Seperator .push(4)
.push("auto"), // Action .push("auto")
.push(4)
.push("auto")
.push(12)
.push("auto"),
) )
.child( .child(
TextBlock::new() TextBlock::new()
@@ -97,14 +98,21 @@ impl Template for ConfigurationView {
.attach(Grid::column(0)) .attach(Grid::column(0))
.attach(Grid::row(6)) .attach(Grid::row(6))
.attach(Grid::column_span(3)) .attach(Grid::column_span(3))
.columns(Columns::create().push("auto").push(8).push("auto")) .columns(
.rows(Rows::create().push("auto")) Columns::create()
.push("auto")
.push(8)
.push("auto")
)
.rows(Rows::create()
.push("auto")
)
.child( .child(
Button::new() Button::new()
.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
@@ -113,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

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// The configuration state /// The configuration state

View File

@@ -1,19 +1,21 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
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::*;
use crate::{data::constants::*, data::structures::PolicyList}; use crate::{
data::constants::*,
data::structures::PolicyList
};
/// define valid environment variables provided via .env files /// define valid environment variables provided via .env files
/// located in the current call directory /// located in the current call directory
@@ -26,48 +28,31 @@ 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 lanuage identifier /// 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_else(|_| "C".to_string()); let mut lang = env::var("LANG").unwrap_or("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();
match envy::from_env::<Environment>() { match envy::from_env::<Environment>() {
Ok(environment) => { Ok(environment) => {
if environment.test_lang != lang { if environment.test_lang != lang { lang = environment.test_lang; }
lang = environment.test_lang; },
} 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) = *Window::focus_state_ref(&ctx.window()).focused_entity() { // if let Some(old_focused_element) = ctx.window().get::<Global>("global").focused_widget {
// ctx.push_event_by_window(FocusEvent::RemoveFocus(old_focused_element)); // let mut old_focused_element = ctx.get_widget(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);
// } // }
@@ -77,6 +62,7 @@ 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

@@ -1,24 +1,20 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;
use tracing::info;
use crate::widgets::localization::localization_view::LocalizationView; use crate::widgets::localization::localization_view::LocalizationView;
/// Structure handling the localization status
#[derive(AsAny, Debug, Default)] #[derive(AsAny, Debug, Default)]
pub struct LocalizationState { pub struct LocalizationState {
/// Change the language boolean
change_language: bool, change_language: bool,
} }
impl LocalizationState { impl LocalizationState {
/// Change the active/selected language
pub fn change_language(&mut self) { pub fn change_language(&mut self) {
self.change_language = true; self.change_language = true;
} }
@@ -30,10 +26,8 @@ impl State for LocalizationState {
return; return;
} }
// get value of activ selected combo_box item
let index = *LocalizationView::selected_index_ref(&ctx.widget()) as usize; let index = *LocalizationView::selected_index_ref(&ctx.widget()) as usize;
let selected_language = LocalizationView::languages_ref(&ctx.widget())[index].clone(); let selected_language = LocalizationView::languages_ref(&ctx.widget())[index].clone();
info!("New selected language item: {:?}", selected_language);
match selected_language.as_str() { match selected_language.as_str() {
"English" => ctx.set_language("en_US"), "English" => ctx.set_language("en_US"),

View File

@@ -1,23 +1,22 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;
use crate::{data::constants::*, widgets::localization::localization_state::LocalizationState}; use crate::{
data::constants::*,
widgets::localization::localization_state::LocalizationState,
};
type List = Vec<String>; type List = Vec<String>;
// Macro that initializes the widget structures/variables for our view // Macro that initializes the widget structures/variables for our view
widget!( widget!(LocalizationView<LocalizationState> {
/// Dialog to change active localization settings
LocalizationView<LocalizationState> {
/// The language list
languages: List, languages: List,
/// The selected language index
selected_index: i32 } selected_index: i32 }
); );
@@ -28,13 +27,19 @@ impl Template for LocalizationView {
let languages = vec!["English".to_string(), "German".to_string()]; let languages = vec!["English".to_string(), "German".to_string()];
let count = languages.len(); let count = languages.len();
self.languages(languages).selected_index(1).child( self.languages(languages)
.selected_index(1)
.child(
Grid::new() Grid::new()
.id(ID_LOCALIZATION_FORM) .id(ID_LOCALIZATION_FORM)
.margin(4) .margin(4)
.columns(Columns::create().push(120).push(12).push(150)) .columns(
.rows( Columns::create()
Rows::create() .push(120)
.push(12)
.push(150)
)
.rows(Rows::create()
.push("auto") .push("auto")
.push(4) .push(4)
.push("auto") .push("auto")
@@ -71,8 +76,9 @@ impl Template for LocalizationView {
.attach(Grid::column(2)) .attach(Grid::column(2))
.attach(Grid::row(2)) .attach(Grid::row(2))
.items_builder(move |bc, index| { .items_builder(move |bc, index| {
let text = let text = bc.get_widget(id)
bc.get_widget(id).get::<Vec<String>>("languages")[index].clone(); .get::<Vec<String>>("languages")[index]
.clone();
TextBlock::new() TextBlock::new()
.id(ID_LOCALIZATION_LANGUAGE_NAME) .id(ID_LOCALIZATION_LANGUAGE_NAME)
.v_align("center") .v_align("center")

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// The localization state /// The localization state

View File

@@ -1,41 +1,33 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;
use crate::{ use crate::{
data::{constants::*, structures::PolicyCheck}, data::structures::PolicyCheck,
widgets::configuration::configuration_view::ConfigurationView,
widgets::localization::localization_view::LocalizationView,
widgets::policycheck::policycheck_view::PolicycheckView, widgets::policycheck::policycheck_view::PolicycheckView,
//widgets::menu::menu_view::MenuView, widgets::localization::localization_view::LocalizationView,
widgets::ticketdata::ticketdata_view::TicketdataView, widgets::configuration::configuration_view::ConfigurationView,
widgets::menu::menu_view::MenuView,
}; };
// [START] view // [START] views
widget!( widget!(MainView {
/// The main view offering accessible forms
MainView {
// policy_list: PolicyList, // policy_list: PolicyList,
// policy_data_list: PolicyDataList, // policy_data_list: PolicyDataList,
// policylist_view: u32, // policylist_view: u32,
// policydata_view: u32, // policydata_view: u32,
/// The policycheck view 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()
.target(ticketdata_view.0)
//.policy_number_count(0) //.policy_number_count(0)
//.policylist_view(id) //.policylist_view(id)
.build(ctx); .build(ctx);
@@ -54,7 +46,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())
@@ -63,11 +55,10 @@ impl Template for MainView {
// .child(policylist_view) // .child(policylist_view)
.child( .child(
TabWidget::new() TabWidget::new()
.tab(ID_POLICY_CHECK_VIEW, policycheck_view) .tab("Policynumber check", policycheck_view)
.tab(ID_TICKET_DATA_VIEW, ticketdata_view) .tab("Localization", LocalizationView::new().build(ctx))
.tab(ID_LOCALIZATION_VIEW, LocalizationView::new().build(ctx)) .tab("Configuration", ConfigurationView::new().build(ctx))
.tab(ID_CONFIGURATION_VIEW, ConfigurationView::new().build(ctx)) .tab("Menu", MenuView::new().build(ctx))
//.tab(ID_MENU_VIEW, MenuView::new().build(ctx))
.build(ctx), .build(ctx),
) )
//.child(policycheck_view) //.child(policycheck_view)

View File

@@ -0,0 +1,300 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use cfg_if::cfg_if;
use orbtk::prelude::*;
use orbtk::shell::event::Key;
use std::process;
use crate::{
data::constants::*,
widgets::menu::menu_view::MenuView,
//widgets::policycheck::policycheck_view::PolicycheckView,
};
/// Valid `actions` that are handled as state changes in the `Menu` widget.
#[derive(Debug, Clone, Copy)]
pub enum MenuAction {
CreateMenu,
CreateMenuToggleTheme(Entity),
RemoveMenu,
RemoveMenuToggleTheme(Entity),
SetTheme
}
/// Valid `structures` that are handled inside the state of the `Menu` widget.
#[derive(AsAny, Default)]
pub struct MenuState {
action: Option<MenuAction>,
menu: Entity,
menu_toggle_theme: Entity
}
/// Method definitions, that react on any given state change inside the `Menu` widget.
impl MenuState {
/// Set a menu holding all valid menu elements
/// The elements are ordered compontents inside a stack
pub fn create_menu(&mut self, ctx: &mut Context<'_>) {
// create a stack as a child of the given component
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
fn remove_menu(&mut self, ctx: &mut Context<'_>) {
ctx.remove_child(ctx.entity());
println!("Popup {:?} removed !", ctx.entity());
}
/// Remove the menu popup box
fn remove_menu_toggle_theme(&mut self, id: Entity, ctx: &mut Context<'_>) {
ctx.remove_child(self.menu_toggle_theme);
println!("Popup {:?} removed !", id);
}
/// Sets a new action.
pub fn set_action(&mut self, action: MenuAction) {
self.action = action.into();
}
}
/// Supported methods handled inside the `MenuState`
impl State for MenuState {
/// Initialize the state of widgets inside `MenuState`
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`
fn messages(
&mut self,
mut messages: MessageReader,
_registry: &mut Registry,
ctx: &mut Context<'_>,
) {
for message in messages.read::<MenuAction>() {
match message {
MenuAction::SetTheme => {
let theme_index = *MenuView::selected_index_ref(&ctx.widget());
cfg_if! {
if #[cfg(windows)] {
match theme_index {
0 => ctx.switch_theme(theme_default_dark()),
1 => ctx.switch_theme(theme_default_light()),
2 => ctx.switch_theme(theme_redox()),
3 => ctx.switch_theme(theme_fluent_dark()),
4 => ctx.switch_theme(theme_fluent_light()),
_ => {}
}
} else {
match theme_index {
0 => ctx.switch_theme(theme_default_dark()),
1 => ctx.switch_theme(theme_default_light()),
2 => ctx.switch_theme(theme_redox()),
_ => {}
}
}
}
},
_ => (),
}
}
}
/// Update the state of widgets inside the `Menu` view.
fn update(&mut self, _registry: &mut Registry, ctx: &mut Context<'_>) {
if let Some(action) = self.action {
match action {
MenuAction::CreateMenu => {
println!("MenuAction::CreateMenu(_entity)");
self.create_menu(ctx);
}
MenuAction::CreateMenuToggleTheme(_entity) => {
self.create_menu_toggle_theme(ctx);
}
MenuAction::RemoveMenu => {
self.remove_menu(ctx);
}
MenuAction::RemoveMenuToggleTheme(entity) => {
self.remove_menu_toggle_theme(entity, ctx);
}
_ => (),
}
}
}
}
/// Create a new popup presenting the menu components
pub fn create_menu_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
Popup::new()
.id(ID_MENU_POPUP)
.style("container_menu")
.target(id)
.open(true)
.width(280)
.height(140)
.on_key_down(move | ctx, key_event | {
match key_event.key {
Key::Q(..) => {
//if is_ctrl_home_down(ctx)
println!("KeyHandler: got Ctrl+Q");
process::exit(0);
//}
},
Key::Escape => {
println!("KeyHandler: got Escape");
ctx.get_mut::<MenuState>(id)
.set_action(MenuAction::RemoveMenu);
},
_ => {
println!("KeyHandler: got {:?}", key_event.key);
},
};
true
})
.child(
Grid::new()
.id(ID_MENU_GRID)
.columns(
Columns::create()
.push("80") // Menu Button
.push("1") // Seperator
.push("*") // Keyboard Shortcut
.build(),
)
.rows(
Rows::create()
.push("auto")
.push("auto")
.push("auto")
.build(),
)
.child(
Button::new()
.id(ID_MENU_LABEL_ACCOUNT)
.style("button_menu")
.attach(Grid::row(0))
.attach(Grid::column(0))
.attach(Grid::column_span(2))
.icon(material_icons_font::MD_PERSON)
.text("Account")
.build(ctx),
)
.child(
Button::new()
.id(ID_MENU_LABEL_TOGGLE_THEME)
.style("button_menu")
.attach(Grid::row(1))
.attach(Grid::column(0))
.attach(Grid::column_span(2))
.icon(material_icons_font::MD_EDIT)
.text("Toggle theme")
// .on_click(move |ctx, _| {
// ctx.get_mut::<MenuState>(id)
// .set_action(MenuAction::SetTheme(id));
// true
// })
.build(ctx),
)
.child(
Button::new()
.id(ID_MENU_LABEL_QUIT)
.style("button_menu")
.attach(Grid::row(2))
.attach(Grid::column(0))
.attach(Grid::column_span(2))
.icon(material_icons_font::MD_SETTINGS_POWER)
.text("Quit")
.on_mouse_down(move |_states, _| {
process::exit(0);
})
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_MENU_SHORTCUT_QUIT)
.style("button_menu")
.attach(Grid::row(2))
.attach(Grid::column(2))
.margin((0, 0, 16, 0))
.h_align("end")
.v_align("center")
.text("CTRL+Q")
.build(ctx),
)
.build(ctx),
)
.build(ctx)
}
/// Create a new popup submenu to toogle the active theme
pub fn create_menu_toggle_theme_popup(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
//let themes_count = themes.len();
//ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), new_width);
Popup::new()
.id(ID_MENU_TOGGLE_THEME)
.style("container_menu")
.target(id)
.open(true)
.width(280)
.height(140)
.child(
ComboBox::new()
.attach(Grid::column(2))
.attach(Grid::row(6))
//.count(themes_count)
.items_builder(move |build_ctx, index| {
let theme_name =
MenuView::themes_ref(&build_ctx.get_widget(id))[index].clone();
TextBlock::new().v_align("center").text(theme_name).build(build_ctx)
})
.on_changed("selected_index", move |ctx, _| {
ctx.send_message(MenuAction::SetTheme, id);
println!("changed theme.");
})
.selected_index(id)
.build(ctx),
)
.build(ctx)
}

View File

@@ -0,0 +1,82 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use cfg_if::cfg_if;
use orbtk::prelude::*;
use crate::data::constants::*;
use crate::widgets::menu::menu_state::{MenuAction, MenuState};
type List = Vec<String>;
// Macro that initializes the widget structures/variables for the menu view
widget!(
MenuView<MenuState> {
//menu_stack: Entity,
//button_menu: Entity,
selected_index: i32,
themes: List
}
);
/// The template implementation of the menu view
/// All GUI elements are styled using the "style" attribute referencing to a ron based css
impl Template for MenuView {
fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self {
cfg_if! {
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(),
];
}
}
//self.themes(themes).child(MenuState::create_menu(ID_MENU_POPUP, ctx))
self.themes(themes).child(
Stack::new()
.id(ID_MENU_STACK)
.child(
TextBlock::new()
.style("header")
.attach(Grid::row(0))
.attach(Grid::column(0))
.style("small_text")
.text("Select theme")
.build(ctx),
)
.child(
Button::new()
//.id("button_menu")
.id(ID_MENU_BUTTON)
.style("button_single_content")
.icon(material_icons_font::MD_MENU)
.attach(Grid::column(2))
.h_align("end")
.on_click(move |ctx, _| {
println!("WIP: open menu popup from MenuView");
ctx.get_mut::<MenuState>(id)
.set_action(MenuAction::CreateMenu);
true
})
.build(ctx),
)
.build(ctx),
)
}
}

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// The menu view /// The menu view

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// Configuration widget. /// Configuration widget.
@@ -28,6 +28,3 @@ pub mod policycheck;
// /// Policylists widget. // /// Policylists widget.
// pub mod policylist; // pub mod policylist;
/// Ticketdata wigdet.
pub mod ticketdata;

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// The policy check state /// The policy check state

View File

@@ -0,0 +1,596 @@
/*
* 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::{Duration, SystemTime};
use tracing::{error, info, trace};
use crate::{
data::{
structures::{PolicyCode, PolicyDataList, PolicyList},
constants::*,
},
widgets::global_state::GlobalState,
//widgets::menu::menu_view::MenuView,
//services::imports::allianzdirectcall::import,
services::imports::allianzdirectcall,
};
/// Valid `actions` that are handled as state changes in the `Policycheck` widget.
#[derive(Debug, Clone, Copy)]
pub enum PolicycheckAction {
AddProgress(f64),
ClearEntry(Entity),
ChangeTheme(),
InputTextChanged(Entity),
ImportData,
ParseEntry(Entity),
RemoveFocus(Entity),
RemovePopup(Entity),
ResetProgress,
SetProgress(f64),
SetProgressPopup(Entity),
SetToggleTheme(Entity),
SetEntry(Entity),
SetVisibility(Entity),
TextChanged(Entity, usize)
}
/// 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 `Policycheck` widget.
#[derive(AsAny, Default)]
pub struct PolicycheckState {
action: Option<PolicycheckAction>,
duration: Duration,
label_result: Entity,
lang: String,
button_menu: Entity,
policy_data_count: u64,
policy_numbers: HashMap<u64, PolicyCode>,
progress_bar: Entity,
progress_count: f64,
progress_popup: Entity
}
impl GlobalState for PolicycheckState {}
/// Method definitions, that react on any given state change inside the `Policycheck` widget.
impl PolicycheckState {
/// Create a hashmap (key: policy number, value: policy type).
pub fn create_hashmap(&mut self, _ctx: &mut Context<'_>) -> Result<(), Box<dyn std::error::Error>> {
trace!(target: "advotracker", create_hashmap = "started");
let policy_list = PolicyList::new("policy list");
trace!(target: "advotracker", policy_list = ?policy_list);
// create vector to hold imported data
let res = t!("policy.string.label_policy_data", self.lang);
let mut policy_data = PolicyDataList::new(res);
trace!(target: "advotracker", policy_data = ?policy_data);
let mut policy_numbers : HashMap<u64, PolicyCode> = HashMap::new();
// Wip: use cli parameter stored in viperus ...
//let mut csv_import_path = v.get::<String>("import_file").unwrap();
let mut csv_import_path = String::from("POLLFNR_WOECHENTLICH.txt");
match allianzdirectcall::import(&mut csv_import_path, &mut policy_data,
&mut policy_numbers, &mut self.policy_data_count,
&self.lang) {
Ok((count, duration)) => {
self.policy_data_count = count;
self.duration = duration;
trace!(target: "advotracker", csv_import_path = ?csv_import_path,
policy_data_count = ?&self.policy_data_count,
duration = ?&self.duration);
}
Err(err) => {
error!("error running CSV-Import: {}", err);
process::exit(1);
}
};
self.policy_numbers = policy_numbers;
trace!(target: "advotracker", create_hashmap = "finished");
Ok(())
}
/// Clear text in text box.
pub fn clear_entry(&mut self, _text_box: Entity, ctx: &mut Context<'_>) {
TextBox::text_set(&mut ctx.widget(), String::from(""));
}
/// Import policy numbers into hashmap
fn import_data(&mut self, ctx: &mut Context<'_>)
-> Result<(), Box<dyn std::error::Error>> {
// WIP: for now, only import once per session
if self.policy_data_count == 0 {
TextBlock::enabled_set(&mut ctx.child(ID_POLICY_CHECK_RESULT), true);
if self.policy_numbers.len() == 0 {
// initialize popup widget
self.set_popup_progress(ctx);
self.progress_count += 0.33;
self.update_progress_bar(ctx);
//sender.send(WindowRequest::Redraw).unwrap();
// for _ in 1..4 {
// self.progress_count += 0.33;
// self.update_progress_bar(ctx);
// sender.send(WindowRequest::Redraw).unwrap();
//}
// importing policy code elements from csv-file
match self.create_hashmap(ctx) {
Ok(()) => {
let res = t!("policy.hashmap.success", self.lang);
info!("hashmap has: {:?} entries", self.policy_data_count);
trace!(target: "advotracker",
hashmap_status = ?res,
hashmap_entries = ?self.policy_data_count);
self.progress_count = 1.;
self.update_progress_bar(ctx);
//sender.send(WindowRequest::Redraw).unwrap();
}
_ => {
let res = t!("policy.hashmap.failed", self.lang);
error!("{:?}", res);
trace!(target: "advotracker", hashmap_status = ?res);
}
}
}
} else {
trace!(target: "advotracker",
hashmap_status = "consume",
hashmap_entries = ?self.policy_data_count);
}
Ok(())
}
/// Parse validity of the given policy number.
fn parse_entry(&mut self, policy_check_policy_number: Entity,
ctx: &mut Context<'_>) {
trace!(target: "advotracker", parse_entry = "started");
let policy_number_string = TextBox::text_clone(&mut ctx.get_widget(policy_check_policy_number));
let policy_number_length = policy_number_string.len();
if self.policy_data_count == 0 {
// Load data into hashmap
match self.import_data(ctx) {
Ok(()) => {
trace!(target: "advotracker", policycheck_state = "init", import_data = "success");
Stack::visibility_set(&mut ctx.child(ID_POLICY_DATA_STACK), Visibility::Visible);
let policy_data_count_string = format!("{:?}", &self.policy_data_count);
TextBlock::text_set(&mut ctx.child(ID_POLICY_DATA_COUNT), String::from(&policy_data_count_string));
},
Err(e) => trace!(target: "advotracker", policycheck_state = "init", import_data = ?e),
}
}
trace!(target: "advotracker", state = "parsing", policy_number = ?policy_number_string);
// Parse policy code: "AS-123456789"
// DION VERS POLLFNR
// 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::visibility_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), Visibility::Collapsed);
if policy_number_length == 10 {
// cast policy_number_sting to <u64>
match policy_number_string.parse::<u64>() {
Ok(p) => {
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_RESULT), String::from(""));
// match hashmap's key
match self.policy_numbers.get(&p) {
Some(policy_code) => {
// matching key, get associated value
trace!(target: "advotracker", state = "success",
policy_number = ?p, policy_code = ?policy_code);
let string_result = format!("1-{:?}-{}",
policy_code, p);
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_RESULT), String::from(string_result));
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::foreground_set(&mut ctx.child(ID_POLICY_CHECK_BUTTON_RESULT), String::from("#008000"));
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);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_1), Visibility::Visible);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Collapsed);
}
_ => {
// no matching key
let res = t!("policy.validation.failed", self.lang);
trace!(target: "advotracker", state = ?res, policy_number = ?p);
TextBox::foreground_set(&mut ctx.child(ID_POLICY_CHECK_POLICY_NUMBER), String::from("#FF0000"));
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_HINT), String::from("The given policy number is invalid"));
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::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);
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::Visible);
}
}
},
Err(e) => {
trace!(target: "advotracker", state = "error", error_type = "invalid type", error = ?e);
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::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::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::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);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Visible);
}
}
}
if policy_number_length < 10 {
let res = t!("policy.validation.failed", self.lang);
trace!(target: "advotracker", state = ?res, reason = "number to short");
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::visibility_set(&mut ctx.child(ID_POLICY_CHECK_HINT), Visibility::Visible);
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_HINT), String::from("Policy number is to short"));
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::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);
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::Visible);
}
if policy_number_length > 10 {
let res = t!("policy.validation.failed", self.lang);
trace!(target: "advotracker", state = ?res, reason = "number to long");
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("Policy number is to long"));
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::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::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);
Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_2), Visibility::Visible);
}
trace!(target: "advotracker", parse_entry = "finished");
}
/// Remove the popup box
fn remove_popup(&mut self, id: Entity, ctx: &mut Context<'_>) {
ctx.remove_child(self.progress_popup);
println!("Popup {:?} removed !", id);
}
// /// If TextBox 'policy_check_policy_number' is empty, disable button "clear"
// /// otherwise enabled it.
// fn set_policy_check_clear(&mut self, policy_check_policy_number: Entity, ctx: &mut Context<'_>) {
// button(&self, policy_check_policy_number: Entity, ctx: &mut Context<' >) {
// if ctx.get_widget(clear_button).get::<String>("policy_check_policy_number").is_empty() {
// ctx.get_widget(self.policy_check_clear_button).set("enabled", false);
// } else {
// ctx.get_widget(self.policy_check_clear_button).set("enabled", true);
// }
// ctx.get_widget(self.policy_check_policy_number).update_theme_by_state(true);
// }
/// Sets a new action.
pub fn set_action(&mut self, action: PolicycheckAction) {
self.action = action.into();
}
/// Change status of given text box to edit mode.
fn set_entry(&mut self, text_box: Entity, ctx: &mut Context<'_>) {
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_BUTTON_RESULT), Visibility::Collapsed);
} else {
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);
}
}
/// Set a progress popup that updates the import status in a progress bar
fn set_popup_progress(&mut self, ctx: &mut Context<'_>) {
// create a stack as a child of entity "ID_POLICY_CHECK_POLICY_NUMBER"
let stack = ctx
.entity_of_child(ID_POLICY_CHECK_POLICY_NUMBER)
.expect("PolicycheckState: Can't find entity of resource 'ID_POLICY_CHECK_POLICY_NUMBER'.");
let current_entity = ctx.entity();
let build_context = &mut ctx.build_context();
// create the progress_popup widget
self.progress_popup = create_popup_progress(current_entity, build_context);
println!("New entity `progress_popup` created: {:?}", self.progress_popup);
// append the stack inside the progress_popup
build_context.append_child(stack, self.progress_popup);
// make sure we have a
self.progress_bar = ctx
.entity_of_child(ID_POLICY_CHECK_PROGRESS_BAR)
.expect("PolicycheckState.init: Can't find entity of resource 'ID_POLICY_CHECK_PROGRESS_BAR'.");
println!("New entity `progress_bar` created: {:?}", self.progress_bar);
println!("function `set_popup_progress()` finished!");
}
/// Change visibility of the result label.
fn _set_visibility(&self, entity: Entity, ctx: &mut Context<'_>) {
if ctx.get_widget(entity).get::<String16>("text").is_empty() {
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);
} else {
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);
}
//ctx.get_widget(self.label_result).update_theme_by_state(true);
}
/// Update count of elements in the policy data list.
fn _update_data_count(&self, ctx: &mut Context<'_>) {
let data_list_count = ctx.widget().get::<PolicyDataList>(PROP_POLICY_DATA_LIST).len();
ctx.widget().set(PROP_POLICY_DATA_COUNT, data_list_count);
}
fn update_progress_bar(&self, ctx: &mut Context<'_>) {
let res = t!("policy.string.progress_time", self.lang);
let string_duration = format!("{}: {:?}", res, self.duration);
TextBlock::text_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_TIME), String::from(string_duration));
let mut progress_bar = ctx.child(ID_POLICY_CHECK_PROGRESS_BAR);
progress_bar.set::<f64>("val", self.progress_count);
}
}
/// Supported methods handled inside the `PolicycheckState`
impl State for PolicycheckState {
/// Initialize the state of widgets inside `PolicycheckState`
fn init(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
let time_start= SystemTime::now();
trace!(target: "advotracker", policycheck_state = "init", status = "started");
// Initialize required entities
self.button_menu = ctx
.entity_of_child(ID_POLICY_CHECK_BUTTON_MENU)
.expect("PolicycheckState.init: Can't find resource entity 'ID_POLICY_CHECK_BUTTON_MENU'.");
self.label_result = ctx
.entity_of_child(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);
//Stack::visibility_set(&mut ctx.child(ID_POLICY_CHECK_FORM_ROW_0), Visibility::Collapsed);
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);
// Preset localization with given environment lang
self.lang = PolicycheckState::get_lang();
ctx.set_language(&self.lang);
// // 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
// // app directory name. The directory location is OS dependant
// // (Windows: AppData, Unix: XDG_CONFIG_HOME, MacOS: $HOME/Library/Preferences).
// // The filename is taken from the propertey PROP_ADVOTRACKER (default: 'advotracker'.ron).
// if let Ok(policy_data) = registry
// .get::<Settings>("settings")
// .load::<PolicyDataList>(PROP_ADVOTRACKER)
// {
// ctx.widget().set(PROP_ADVOTRACKER, policy_data);
// }
let time_end = SystemTime::now();
let duration = time_end.duration_since(time_start);
trace!(target: "advotracker", policycheck_state = "init", status = "finished", duration = ?duration);
}
/// Handle messages for `PolicycheckState`.
fn messages(
&mut self,
mut messages: MessageReader,
_registry: &mut Registry,
ctx: &mut Context<'_>,
) {
for message in messages.read::<PolicycheckAction>() {
match message {
PolicycheckAction::AddProgress(increment) => {
let old_width = ProgressBar::val_clone(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR));
let new_width = old_width + increment;
// Set the ProgressBar's val property to the calculated percentage
// (whereas 0.0 means 0%, and 1.0 means 100%)
if new_width <= 1. {
ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), new_width);
} else {
ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), 1.);
}
}
_ => (),
}
}
}
/// Update the state of widgets inside the `Policycheck` view.
fn update(&mut self, _registry: &mut Registry, ctx: &mut Context<'_>) {
// // clear focus on focus moved
// if self.last_focused != ctx.window().get::<Global>("global").focused_widget {
// if let Some(last_focused) = self.last_focused {
// ctx.get_widget(last_focused).set("focused", false);
// // widget is unvisible, but takes space to be considered
// ctx.get_widget(last_focused)
// .set("visibility", Visibility::Collapsed);
// }
//}
if let Some(action) = self.action {
match action {
PolicycheckAction::ClearEntry(policy_check_policy_number) => {
ctx.get_widget(policy_check_policy_number).set("enabled", false);
}
PolicycheckAction::InputTextChanged(entity) => {
println!("entry changed: {}", TextBox::text_clone(&ctx.get_widget(entity)));
}
PolicycheckAction::ImportData => {
match self.import_data(ctx) {
Ok(()) => {
trace!(target: "advotracker", import_data = "success");
}
_ => {
error!("Importing data failed!");
trace!(target: "advotracker", import_data = "failed");
}
}
}
PolicycheckAction::ParseEntry(text_box) => {
self.parse_entry(text_box, ctx);
}
PolicycheckAction::RemoveFocus(policy_check_policy_number) => {
ctx.get_widget(policy_check_policy_number).set("enabled", false);
//ctx.EventAdapter(FocusEvent::RemoveFocus(policy_check_policy_number));
}
PolicycheckAction::RemovePopup(entity) => {
//println!("WIP: remove popup");
self.remove_popup(entity, ctx);
}
PolicycheckAction::ResetProgress => {
ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), 0.);
}
PolicycheckAction::SetEntry(policy_check_policy_number) => {
//self.last_focused = Some();
self.set_entry(policy_check_policy_number, ctx);
}
PolicycheckAction::SetProgress(value) => {
if value >= 0. || value <= 1. {
ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), value);
} else {
ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), 0.);
} }
PolicycheckAction::SetProgressPopup(_entity) => {
self.set_popup_progress(ctx);
}
PolicycheckAction::SetVisibility(_entity) => {
TextBlock::visibility_set(&mut ctx.child(ID_POLICY_CHECK_LABEL_RESULT), Visibility::Collapsed);
}
PolicycheckAction::TextChanged(entity, _index) => {
self.set_entry(entity, ctx);
}
_ => (),
}
}
// Reset action
self.action = None;
}
// /// Update the view after the layout is rendered.
// fn update_post_layout(&mut self, _: &mut Registry, _ctx: &mut Context<'_>) {
// }
}
/// Create a progress popup with update status of an onging data import
fn create_popup_progress(id: Entity, ctx: &mut BuildContext<'_>) -> Entity {
Popup::new()
.id(ID_POLICY_CHECK_POPUP_PROGRESS)
.target(id)
.open(true)
.style("popup_progress")
.width(280)
.height(100)
.on_click(move |ctx, _| {
println!("create_popup_progress: on_click -> remove_popup(popup_progress)");
ctx.get_mut::<PolicycheckState>(id)
.set_action(PolicycheckAction::RemovePopup(id));
true
})
.child(
Container::new()
.style("container_progress")
.child(
Stack::new()
.style("stack_progress")
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_PROGRESS_TEXT)
.style("textblock_progress")
.text("Importing data")
.build(ctx)
)
.child(
ProgressBar::new()
.id(ID_POLICY_CHECK_PROGRESS_BAR)
.style("progress_bar")
.val(0)
//.width(250)
.build(ctx)
)
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_PROGRESS_TIME)
.style("textblock_progress")
.h_align("end")
.text("Processing time")
.build(ctx)
)
.build(ctx)
)
.build(ctx)
)
.build(ctx)
}

View File

@@ -0,0 +1,396 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
use orbtk::shell::event::Key;
use crate::{
data::{
constants::*,
structures::PolicyCheck,
},
//widgets::menu::menu_state::{MenuAction, MenuState},
widgets::policycheck::policycheck_state::{PolicycheckAction, PolicycheckState},
};
// Macro that initializes the widget structures/variables for the policy check view
widget!(
/// Dialog to enter a policy identifier/number.
/// This identifier is checked agains a map of valid policy codes.
// PolicycheckView<PolicycheckState>: KeyDownHandler {
PolicycheckView<PolicycheckState> {
lang: String,
policy_check: PolicyCheck,
policy_check_title: String,
policy_data_count: u32
}
);
/// The template implementation of the policy check view
/// All GUI elements are styled using the "style" attribute referencing to a ron based css
impl Template for PolicycheckView {
//fn template(self, policycheck_view: Entity, ctx: &mut BuildContext<'_>) -> Self {
fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self {
let policy_check_bottom_bar = Container::new()
//.style(STYLE_BOTTOM_BAR)
.attach(Grid::row(4))
.attach(Grid::column(1))
.attach(Grid::column_span(2))
.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(
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 policy_check_button_menu = Button::new()
.id(ID_POLICY_CHECK_BUTTON_MENU)
.style("button_single_content")
.icon(material_icons_font::MD_MENU)
.attach(Grid::column(2))
//.min_size(16, 16)
.h_align("end")
.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 policy_check_button_result = Button::new()
.id(ID_POLICY_CHECK_BUTTON_RESULT)
.style("button_single_content")
.h_align("start")
.v_align("center")
.visibility(Visibility::Collapsed)
.enabled(false)
.build(ctx);
let policy_check_header_bar = Container::new()
.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_POLICY_CHECK_HEADER)
.v_align("center")
.h_align("left")
.text("Validation policy number")
.build(ctx),
)
.build(ctx),
)
.child(policy_check_button_menu)
.build(ctx);
let policy_check_form_row_0 = Stack::new()
// 1st row
.id(ID_POLICY_CHECK_FORM_ROW_0)
.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::column(0))
.attach(Grid::column_span(5))
.orientation("horizontal")
.v_align("center")
.h_align("center")
.child(
TextBlock::new()
.id(ID_POLICY_CHECK_LABEL_HINT)
//.style("hint")
.attach(Grid::row(2))
.attach(Grid::column(0))
.margin((0, 0, 16, 0))
.h_align("end")
.v_align("center")
.width(300)
.min_width(300)
.font_size(11.)
.text("Error:")
.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);
let policy_check_form = Container::new()
.id(ID_POLICY_CHECK_FORM)
.min_width(420)
.attach(Grid::row(2))
.attach(Grid::column(1))
.style("container_form")
.child(
Grid::new()
.id(ID_POLICY_CHECK_FORM)
.width(450)
.min_width(400)
.columns(
Columns::create()
// Label
.push("300")
// Seperator
.push("16")
// Values
.push("auto")
// Seperator
.push("16")
// Result-Button
.push("32")
//.build(),
)
.rows(
Rows::create()
.push("auto")
.push("auto")
.push("*")
//.build(),
)
.child(policy_check_form_row_0)
.child(policy_check_form_row_1)
.child(policy_check_form_row_2)
.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
// a hashmap as values
let policy_data_stack = Stack::new()
.id(ID_POLICY_DATA_STACK)
.attach(Grid::row(3))
.attach(Grid::column(1))
.h_align("end")
.v_align("top")
.orientation("horizontal")
.visibility(Visibility::Collapsed)
//.spacing("4")
.child(
TextBlock::new()
.id(ID_POLICY_DATA_LABEL)
.margin((0, 4, 0, 0))
.enabled(true)
.text("Checklist elements: ")
.build(ctx)
)
.child(
TextBlock::new()
.id(ID_POLICY_DATA_COUNT)
.margin((0, 4, 0, 0))
.enabled(true)
.text("0")
.build(ctx)
)
.build(ctx);
// Starter page: check policy numbers
self.name("PolicycheckView")
// initialize struct (derived default macro)
.policy_check(PolicyCheck::default())
.child(
Grid::new()
.id(ID_POLICY_CHECK_WIDGET)
.columns(
Columns::create()
.push(50)
.push("*")
.push(50)
//.build(),
)
.rows(
Rows::create()
.push("auto")
.push(28)
.push("*")
.push("auto")
.push("auto")
//.build(),
)
// row 0: Policy Check Header
.child(policy_check_header_bar)
// row 1: Seperator
// 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),
)
}
}
// helper to request PolicycheckState
//fn state<'a>(id: Entity, states: &'a mut StatesContext) -> &'a mut PolicycheckState {
// states.get_mut(id)
//}

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// The policy check state /// The policy check state

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
/// The policy check state /// The policy check state

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: (0BSD or MIT)
/* /*
* advotracker - Hotline tackingtool for Advocats * advotracker - Hotline tackingtool for Advocats
* *
* Copyright 2020-2021 Ralf Zerres <ralf.zerres@networkx.de> * Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/ */
use orbtk::prelude::*; use orbtk::prelude::*;

View File

@@ -1,6 +0,0 @@
#[target.x86_64-pc-windows-msvc]
#linker = "lld-link"
#linker = "/usr/local/msvc-wine-rust/linker-scripts/linkx64.sh"
#[target.i686-pc-windows-msvc]
#linker = "/usr/local/msvc-wine-rust/linker-scripts/linkx32.sh"

View File

@@ -1,17 +0,0 @@
###
# .env
# will overwrite standard environment viariables
###
# set the language variable used in test-runs
#test LANG=de-DE
#test LANG=es-ES
#test LANG=C
# set the language variable (overwriting standard Enviroment)
#TEST_LANG=de_DE
#TEST_LANG=C
#RUST_LOG=advotracker=trace
#LANG=de_DE
RUST_LOG=trace
#RUST_LOG=none
USERNAME=hiedemann
DB_DRIVER=sqlite

View File

@@ -1,72 +0,0 @@
[package]
name = "advotracker_client"
version = "0.1.8"
authors = ["Ralf Zerres <ralf.zerres@networkx.de>"]
description = "Frontend component that supports lawyers to capture relevant data encountered during an online legal advice."
readme = "README.md"
license = "(0BSD OR MIT)"
edition = "2018"
default-run = "advotracker"
build = "build.rs"
[build-dependencies]
#twine = { version = "0.3.9", features = ["serde"] }
## twine with PR's
twine = { path = "../../twine", features = ["serde"] }
winres = { version = "0.1" }
winapi = { version = "0.3", features = ["winnt", "winuser"] }
[dependencies]
async-stream = "~0.2"
chrono = { version = "0.4.0", features = ["serde"] }
cfg-if = { version = "1.0" }
clap = { version = "2.33", features = ["suggestions", "color"] }
csv = { version = "1.1" }
directories = { version = "3.0" }
dotenv = { version = "0.15.0" }
envy = { version = "0.4" }
lettre ={ version = "0.10.0-rc.3" }
lazy_static = { version = "1.4.0" }
log = { version = "0.4.8" }
maud = { version = "0.22.1" }
orbtk = { git = "https://github.com/redox-os/orbtk.git", branch = "develop" }
#orbtk = { path = "../../../orbtk", branch="next" }
serde = { version = "1", features = ["derive"] }
sdl2 = { version = "0.34", features = ["bundled"] }
substring = { version = "1" }
tracing = { version = "0.1" }
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", default-features = false }
winapi = { version = "0.3", features = ["winuser"] }
[features]
default = ["parse_cli"]
debug = ["orbtk/debug"]
light = []
parse_cli = ["viperus/cache", "viperus/fmt-clap", "viperus/fmt-env", "viperus/global"]
[package.metadata.bundle]
name = "advotracker"
identifier = "nwx.advotracker"
short_description = "Online legal advice helper."
description = "Supports lawyers to capture relevant data encountered during an online legal advice.\n"
[package.metadata.winres]
OriginalFilename = "advotracker.exe"
FileDescription = "Windows frontend that supports lawyers to capture relevant data encountered during an online legal advice.❤"
LegalCopyright = "Copyright © 2020-2021"
#[target.'cfg(target_os="windows")'.build-dependencies]
[target.'cfg(windows)'.build-dependencies]
cfg-if = { version = "1.0" }
winapi = { version = "0.3", features = ["winnt"] }
winres = { version = "0.1" }
#windres = { version = "0.2" }
#[target.x86_64-pc-windows-gnu]
#linker = "lld-link"
[[bin]]
name = "advotracker"
path = "src/main.rs"

View File

@@ -1 +0,0 @@
POLLFNR_WOECHENTLICH_test.txt

Some files were not shown because too many files have changed in this diff Show More