254 Commits

Author SHA1 Message Date
9ed395d04b advotracker-client: more twine adaptions
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-22 23:50:59 +01:00
dd5d361116 advotracker_client: update build dependencies
* correction in build.rs: use rust edition 2018 syntax
* crate twine is a build dependency

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-21 21:43:37 +01:00
4a316b8080 advotracker_client: add i18n directory
* initial localization.ini: strings for `en` and `de`
2021-03-21 21:39:57 +01:00
067257e0dd advotracker_client: adopt usage of crate twine
* i18n crate
* twine::build_translations(): generate the i18n.rs with all
  language translation strings
* twine::build_translations_from_readers(): generates to t!() macro
  readers: the INI files with the translation strings
* twine::t() consumes the strings
2021-03-21 21:20:54 +01:00
60a7fc2d84 crates: code cleanup 2021-03-21 19:32:34 +01:00
cff156c024 advotracker_client: introduce Windows icon handling
* include `windres` crate
* create a `build.rs`
* include a `hotline.svg` that is converted to advotracker.ico
  using inkscape and imagemagick
* crate a `README.md`

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-18 11:06:36 +01:00
78851ebbcf Cargo: move profile definitions to workspace root
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-10 09:58:58 +01:00
f6ac43816f data:constants: correct callback_number bug
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-10 09:47:22 +01:00
2b4eb454cc examples: insert sdl2_demo
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-10 09:19:14 +01:00
abe56741e8 widgets:ticketdata: correct mail_from address
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-10 09:18:24 +01:00
0202d4a34b advotracker_client: bump version 0.1.5-alpha2
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 17:26:46 +01:00
520e0cb712 widget:ticketdata: error handling and button glyphs
* assign glyphs depending on action state
* feedback on send_ticketdata return code
* cleanup

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 17:24:07 +01:00
c555ce4d85 service:send_ticketdata: adapt alingnment of http mail and relay
* cleanup comments
* correct relay / credential handling

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 12:07:14 +01:00
a8f6ac6a37 services:send_ticketdata: correct relay authentication issues
* correct mail_from identifier
* correct mail_reply identifier
* correct mail_cc identifier

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 11:16:50 +01:00
8abdef6e44 widget: bump to 0.1.5-alpha2
* typo cleanup
* temporary disable mail-cc combobox
* correct mail_cc address

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 09:50:12 +01:00
a5dae6e397 advotrackerdb: update use reference after structure update
* binaries: reference advotrackerdb, not crate

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 04:32:12 +01:00
e03c5ab667 main: adapt window size
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 04:32:11 +01:00
d8e94513c3 widget:policycheck: enable ClearPolicyNumber
* new action button "Clear", "New ticket"
* enable needed send_message routine
* create action method
* update visibility state of involved view properties

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 04:32:11 +01:00
5a9965751a advotracker: reorganize the project using a crate based structure
* advotracker: the framework project
* crate/advotrackerdb: implementation of the database backend
* crate/advotrackerd: implementation of the backend (daemon)
* crate/adovtracker: implementaton of the application (CLI and GUI)

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 04:32:11 +01:00
4c88167bef advotracker: restructure project using crate tree
* advotracker: the framework crate
* crate/advotrackerdb: crate implementing the database backend
* crate/advotrackerd: the backend daemon
* crate/adovtracker: the application (CLI and GUI)

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 04:32:11 +01:00
1ce1d029e5 widget:ticketdata: bug correction for ComboBox
* always use 'TextBlock', since editing is not allowed
  'TextBox ' also disturbs correct rendering

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 04:32:10 +01:00
2e927c8a6a widget:ticketdata: implement ClearForm
* reset all children of a given form to clean initial state
* use `match` expression that compares the widget name,
  that resolves to the widget type (here: TextBox)

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 04:32:10 +01:00
f3db69ce62 Cargo.toml: bump version to 0.1.5-alpha0
* include dependency to crate lettre
* include depenency to crate maud
* this version initially supports ticketdata dialo
* data can be send via Email

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-08 04:31:40 +01:00
55040e37cf widget:global_state: remove usage of navigate
* this needs to be adopted to use event handler code

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-06 15:27:20 +01:00
ba3a6fb4d3 ticketdata: update ticketdata_view using widget builder
* create and handle items in combo boxes using list
  and widget builder

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-06 15:08:57 +01:00
8184af8135 ticketdata: code cleanup 2021-03-06 15:08:57 +01:00
87cbf493a2 advotracker: updated localization strings and constants
* update due to customer request
* constants
* translation strings
* disable WIP menu widget
* labels used in Email submission

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-06 15:08:57 +01:00
4381c3d299 main_view: disable wip menu widget
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-03-06 15:08:57 +01:00
791b451d39 main: handle test_policy_number
* provide cli-flag `testPolicyNumber` as String
  since viperus doesnt support u64
* handle stringconversion (String -> u64) inside main

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

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

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

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

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

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

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

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

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

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

csv-test: update

* move to subdir `examples`
* typo update

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

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

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

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

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

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

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

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2021-02-28 19:45:33 +01:00
26cea8e844 widgets/configuration: break out configuration functionality
* handle widget `configuration` in dedicated subdir
* adopt constants to handle widget id's

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 17:43:23 +01:00
48545d2879 widgets/localization: break out as localization functionality
* handle widget `localization` in dedicated subdir
* adopt constants to handle widget id's

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-05 17:38:11 +01:00
b352f2a581 widget/policycheck: introduce key_event
* handle Escape in menu

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-03 10:27:07 +01:00
89a6842106 policycheck: introduce toggle theme
* new functions:
  - popup_menu_toggle_theme
  - set_menu_toggle_theme
  - create_menu_toggle_theme
  - messages
* rename function: menu  -> popup_menu
* reorder enum: PolicycheckAction
* new actions: SetMenuPopup, SetToggleTheme

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-02 14:00:06 +01:00
76e6e7503f Merge branch 'next' of https://gitea.networkx.de:50443/rzerres/advotracker into wip_toggle_theme_menu
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-02 09:43:32 +01:00
520b959302 structure update
* rename PolicyCheckView to PolicycheckView
* rename PolicyCheckState to PolicycheckState
* rename menu to popup_menu

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:45:27 +01:00
7d459516d9 module structure update 2
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:19:55 +01:00
c511bdd62f main: reflect new module structure
* include from assets
* get widgets into place
* introduce style extensions (theme_fluent)

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:19:55 +01:00
40f715a79a update project structure
* assets: all resources are bundled in this subdirectory
* widgets: use subdirs to group them by function
  the subdir hold their callbacks (state handling) and views
* theming: update to new theming syntax
* fonts: remove fonts that are provovided by default in OrbTK

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:19:55 +01:00
6ea1f95ef0 main_view: introduce configuration view
* allow to load and save config parameters to ron file

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:19:54 +01:00
8986812038 policycheck_view: update to 0.3.1-alpha4 changes
* lose_focus_on_activate()

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:19:54 +01:00
e0eb0c5c90 policycheck_state: update localization of menu entries
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:19:54 +01:00
a1541ae307 implement a toggle theme menu
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:15:57 +01:00
c66335951f structure update
* rename PolicyCheckView to PolicycheckView
* rename PolicyCheckState to PolicycheckState
* rename menu to popup_menu

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-11-01 20:09:45 +01:00
d0e661d5d0 module structure update 2
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-10-31 16:42:04 +01:00
2253c2892b main: reflect new module structure
* include from assets
* get widgets into place
* introduce style extensions (theme_fluent)

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-10-31 14:39:41 +01:00
8cc9ba5782 update project structure
* assets: all resources are bundled in this subdirectory
* widgets: use subdirs to group them by function
  the subdir hold their callbacks (state handling) and views
* theming: update to new theming syntax
* fonts: remove fonts that are provovided by default in OrbTK

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-10-31 14:23:03 +01:00
ef8b884efa main_view: introduce configuration view
* allow to load and save config parameters to ron file

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-10-07 03:22:51 +02:00
6b7ae9d17d policycheck_view: update to 0.3.1-alpha4 changes
* lose_focus_on_activate()

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-10-07 03:20:56 +02:00
f0e9014fb7 policycheck_state: update localization of menu entries
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-10-02 17:34:15 +02:00
0ba99b3fb2 Merge branch 'orbtk-localization' into master
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-10-02 12:09:56 +02:00
f0d5f82549 advotracker: bump release to 0.1.4
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-10-02 11:57:52 +02:00
d2a188eee6 policycheck: update styling, constants and localization
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-28 13:06:50 +02:00
e297c82b85 resources: references used at runtime
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-27 10:44:03 +02:00
f87ab8ce08 advotracker: implement get_lang
* readin language environment and preset the strings

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 21:12:54 +02:00
0c16237c6c callbacks: remove unused global functions
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 19:29:34 +02:00
777fff3776 locales: remove redundant locales in json file
* locales in policy_check.json are included in advotracker.json

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 19:27:30 +02:00
c949b5fe32 Cargo.toml: update package dependencies
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 17:53:19 +02:00
0afe1f3bf8 Nodes.toml: application settings for nodes module
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 17:53:19 +02:00
bf54cb2242 .env: adapt test defaults for environment variables
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 17:53:19 +02:00
5b79229c00 advotracker: change localization handling
* main: adapt resource path for localization information
* data/constants: Stings used in policycheck state/view
* widgets/policycheck_view: change the used localization strings
* callbacks/policycheck_state: change child ID'S to use constants and localization strings

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 17:53:19 +02:00
16a538a805 resources: cleanup unneeded files since
* now using ron based files for localization
* resources are referencing application path names

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 17:53:19 +02:00
a887ffef1f services: adapte/update used strings
* for importp module
* for export module

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 17:52:15 +02:00
65c2da7706 advotracker-db: update to new head
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 17:52:15 +02:00
0467f601f0 locales: adapt language identifiers
* use lang in logging/tracing
* typo cleanup

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-26 17:51:55 +02:00
8a50e1ea78 widget: main_view: add obtk ron based localization support
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-24 10:18:14 +02:00
c54cca5f22 main: include orbtk ron based localization
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-24 10:18:14 +02:00
bf638ac196 callbacks/policycheck_state: convert to new API (orbtk v0.3.1-alpha4)
Before
* let text = *button(&mut ctx.widget()).text();
* let text = Button::get(&mut ctx.widget()).text();
* let text = *button(&mut ctx.widget()).clone_text();
* let text = Button::get(&mut ctx.widget()).clone_text();
* button(&mut ctx.widget()).text_mut().push_str("test");
* Button::get(&mut ctx.widget()).text_mut().push_str("test");
* button(&mut ctx.widget()).set_text(String16::from("test"));
* Button::get(&mut ctx.widget()).set_text(String16::from("test"));

Now
* let text = Button::text_clone(&ctx.widget());
* Button::text_mut(&mut ctx.widget()).push_str("test");
* Button::text_set(&mut ctx.widget(), String16::from("test"));
* ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), new_width);

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-17 16:49:49 +02:00
06e68adce6 callbacks/policycheck_state: convert to new API (orbtk-alpha4)
Before
* let text = *button(&mut ctx.widget()).text();
* let text = Button::get(&mut ctx.widget()).text();
* let text = *button(&mut ctx.widget()).clone_text();
* let text = Button::get(&mut ctx.widget()).clone_text();
* button(&mut ctx.widget()).text_mut().push_str("test");
* Button::get(&mut ctx.widget()).text_mut().push_str("test");
* button(&mut ctx.widget()).set_text(String16::from("test"));
* Button::get(&mut ctx.widget()).set_text(String16::from("test"));

Now
* let text = Button::text_clone(&ctx.widget());
* Button::text_mut(&mut ctx.widget()).push_str("test");
* Button::text_set(&mut ctx.widget(), String16::from("test"));
* ProgressBar::val_set(&mut ctx.child(ID_POLICY_CHECK_PROGRESS_BAR), new_width);

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-09-17 16:24:02 +02:00
645ea50350 callbacks: update commenting code in policycheck_state
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-28 11:56:22 +02:00
13d56e2e05 examples: new increment_progress_bar source
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-28 11:55:42 +02:00
ef63f62734 Main: update position
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-22 19:08:51 +02:00
5aff69c526 widgets/policycheck_view: template id's
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-22 19:03:52 +02:00
70e2e7f1e5 callbacks/policycheck_state: update theme, popup
* popup handling update
* handling of themes

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-22 19:02:18 +02:00
3697bc567a widgets/main_view: update use statement for our crate
* just a style update

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-15 19:34:37 +02:00
ece95344bf Grid .add() to .push()
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-15 19:34:13 +02:00
69405aaa76 main: initialize orbtk with initialize() functions
* needed at least for wayland client

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-15 19:33:24 +02:00
cd82f62a82 widgets/policycheck: update new syntax for Grid
* Columns,Row use create() functions
* update from .add() to new .push() method

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-15 19:31:51 +02:00
eb7a3608d7 data/structures: derive PartialEq macro
* enable PartialEq needed from new wayland client backend

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-08-15 19:30:32 +02:00
b6b12c45bb u64 update
* policynumber has 10 unsigned integers. usize is 32bit on
  on 32 machines. So we need to use u64 to assign the needed ram
  space to fit numbers like '9999999999'

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 20:55:53 +02:00
9b9afc2b5a examples: advowidgets: update to upstream orbtk example
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 20:55:11 +02:00
094fb6d0ea Node.toml: adapt fonts and app options
* remove unused fonts
* correct typo in app name
* correct active font name

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 20:54:25 +02:00
f983eca9aa widgets: policycheck_view: hinting NumericBox, typo correction
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 19:57:06 +02:00
bceec88741 Cargo.toml: reference to upstream orbtk (branch develop)
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 19:57:06 +02:00
daaa544e93 main: remove unused comments
* implement lazy pointer to struct if orbtk can handle it

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 19:57:06 +02:00
33da48b1b1 stylesheets: use explicit theme name
* Cargo.toml: add feature
* policy_state.rs: add handling of feature for choosen theme
* advotracker_dark.ron: advotrackers dark theme
* advotracker_light.ron: advotrackers light theme

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 19:57:06 +02:00
046812e04f README.md: typo correction
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 19:57:00 +02:00
bd70ad653b main: move theming support to callback code, cleanup
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 19:33:22 +02:00
ac855d0a54 widgets: policycheck_view: global "lang" and styling
* use ron styling
* language variable in struct

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 19:33:22 +02:00
b099064776 services: imports: refine tests in allianzdirectcall.rs
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-24 19:33:14 +02:00
65bec5a4a1 callbacks: introduce theming, i18n truning, introduce menu
* global_state: use global "lang", support env
* policycheck_state: use global "lang", new menu function, ron theming

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-22 18:11:39 +02:00
276c0fb5f0 bin: policycheck: simplified core to check policy number
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-22 18:10:51 +02:00
0f97202fbb widgets: policycheck_menu: update styling
* not used, since menu is dynamically created via function

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-22 18:08:16 +02:00
e91b91a2db i18n: update constants and translation messages
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-22 18:07:43 +02:00
25de70e75c examples: remove unused code
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-22 18:07:11 +02:00
9fffb093c3 resources: stylesheets: switching to ron bases CSS
* remove unused old theme.css files
* advotracker.ron: new ron based theming style
* main.rs: extend the dark theme with our stylesheet

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-20 16:43:51 +02:00
11d12718e8 README.md: update to version 1.0.3
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:33:37 +02:00
6e4ba029b7 Cargo.toml: bump version to 0.1.3
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:21:20 +02:00
fd61f90277 callbacks: policycheck_state refine popup widget handling
* on first access, show a processing popup
* calculate the processing time
* update process status
* show processing time in popup

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:18:27 +02:00
ffa8c18efb services: imports: refine to use SystemTime
* Use standard library to calculate SystemTime and Duration
* exporse results to be accessible in orbtk views

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:18:27 +02:00
3d913e7127 widgets: policycheck_view - use constants
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:17:16 +02:00
8ca257bf5c advotracker: rename 'keys' to 'constants'
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:17:16 +02:00
6907c0c393 callbacks: progressing I18n handling
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:17:16 +02:00
9e1a1e7359 widgets: policycheck_view typo cleanup
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:17:07 +02:00
16f174d53a I18N: update translation constants
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-15 00:16:46 +02:00
4406efc955 data: define constanst to be static strings
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-14 11:11:19 +02:00
20ddd78a8d Cargo.toml: enable cross-compile to target Windows x86_64
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-14 11:09:59 +02:00
863826a294 Cargo.toml: bump version to 0.1.2
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-13 03:43:47 +02:00
53d8f80b75 services: import allianzdirectcall update
* use usize for counter

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-13 03:43:47 +02:00
555a02fcc3 structures: CsvExportRecord type update for policy_number
* policy_number: type reset to usize

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-13 03:43:47 +02:00
4d2427a058 callbacks: policycheck_state update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-13 03:43:38 +02:00
5eeb80cdd4 structure: cosmetic update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-13 03:43:38 +02:00
aa26e6634d widgets: policycheck_view update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-13 03:43:24 +02:00
19ad9198d0 data: keys: update ID's
* ID_POLICY_CHECK_DATA_COUNT_BLOCK
* ID_POLICY_CHECK_PROGRESS_BOX

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>

keys: update

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-13 03:43:24 +02:00
e62fb8e990 I18N: translation update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-13 03:43:12 +02:00
d3d3be1442 I18N: README.md language variants (v0.1.2)
* update contents inside README.md
* provide language variant (english, german)
* document translation handling
* installation: download via git

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:27:26 +02:00
b579d039f1 advotracker: update copyright header
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:27:26 +02:00
c5334ac898 .env: test environment file
* use an .env with testing parameters

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:27:26 +02:00
224606d72e resources: new log and font to create the logo
* svg: scalable logo
* CynthoPro-Regular: font used to create text typo

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:27:26 +02:00
4e0b8166f2 callbacks: policycheck_state update
* experimental handling of a progress bar

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:27:26 +02:00
193f2de7ea widgets: update policycheck_view
* update margins
* add widget IDs
* experimental inclusion of a progress bar

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:27:21 +02:00
e2ced73db9 imports: policy_data_count as required variable
* function call will gain access

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:26:10 +02:00
09ec027e79 data: update widget static for used widget IDs
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:26:08 +02:00
656ffae9bf resources: update customer logo
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:25:49 +02:00
9753c37477 policycheck_state: import data to hashmap
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:25:49 +02:00
f503fc9713 parse_args: remove duplicate test of dotenv variables
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:25:49 +02:00
8564aaaf8d policycheck: i18n, tracing updates
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:25:46 +02:00
947e79eea4 policy_check: remove println macro calls
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:47 +02:00
a9f7c62e3d main: lazy_static prototyping, env handling
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:47 +02:00
c0d8e7a898 main: introduce machine specific handling
* machine_kind: differenciate depending on detected machine OS

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:47 +02:00
7a82640fd6 main: make log level dynamic
* set the log level via environment variable

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:47 +02:00
f9453ee18c main: suppress creation of consol window on MS Windows
* Rust applications on Windows always open a new console window
  if started by double-clicking on the executable.
* since rust 1.18 the the macro suppresses this behaviour

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:47 +02:00
f9dd2e3797 README: update project documentation
* i18n: howto extend translations
* installation: download via git

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:47 +02:00
ea57346119 examples: introduce advowidgets
* merge orbtk example widgets
* rename to advowidgets
* incorporate functionality of wip-orbtk branch
  - using latest material-icons-font code
  - merge bugfix to add ComboBox items
  - merge bugfix to handle ComboList

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:47 +02:00
e7ef33ee40 examples: advowidgets: update to new api syntax
* when addressing widgets properties the new api syntax
  seems more natural. It accesses the properties via a function
  oriented notation:

  - view_name(<ctx.widget()).<entity>_mut()

  - ctx.child("<entity>").set::<type>("<field>", <new_property>)

  - <widget_class>(ctx.child(<entity)).set_<field>(<new_property>)

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:47 +02:00
5a5bbb5d5e stylesheet: add advotracker.css
* redefine resources in a new application stylesheet

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:45 +02:00
e8c7d78de3 callbacks: global_state: save data vector to ron file on disk
* new functionality
* save imported / edited data-structures persitantliy
  on disk to file in 'ron' format

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:21 +02:00
bf0ee18f55 callbacks: global_state: compiler sanitization
* use unspecific lifetimes

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:21 +02:00
b709c90682 callbacks: policy_check: update identifier for tracing
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:21 +02:00
32405504a7 widgets: main_view: activate structure init via default()
* possible, since structure provides access via orbtk

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:17 +02:00
891919b64d imports: allianzdirectcall: use array to verify on startup
* using test dataset

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:02 +02:00
40896c6b8e structures: include reference to orbtk
* make structures accessible for orbtk
* documentation update

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:23:02 +02:00
9beeaa7190 data: keys: cleanup DCES id's and properties
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:22:59 +02:00
7e604f050a locales: remove redundant allianzdirectcal
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:22:40 +02:00
ebaf05132f policycheck_state: set_visibility: make param entity non-required
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:22:36 +02:00
ce7f802d3a policycheck_view: adapt width of policy number text_box
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:22:16 +02:00
d7da1335b1 policycheck_view: brake up bigger widget definitions into sub-groups
* improve maintainability
  - make sub-entities grouped into sub-widgets
  - reference this sub-widgets from inside their parents

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:22:12 +02:00
d6703e8df6 policycheck: introduce policy_check_button_result
* after validation, show suitables glyph and corresponding text
* improve user feedback with corresponding color

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:20:52 +02:00
24b9b08566 policycheck: use material_icons_font
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:14:21 +02:00
274a96b908 policycheck: functionality update
* show count of active hashmap members in GUI
* move import call to init function
* show results of policy_number validation in GUI
* improve tracing information
* disable stdout messages via println!()

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:13:49 +02:00
65e0ce3319 policycheck: initial standalone frontend
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:13:06 +02:00
77d41f733e csv-test: bugfix missing translation string
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:13:06 +02:00
18588ce75f csv-test: remove unneeded references
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:13:06 +02:00
d5788b9848 csv-test: structure path update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:13:06 +02:00
e853975c86 services: update im/exporter and remove unused source
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:13:06 +02:00
bc161878b3 parse_args: make vektor 'viperus' explicit
* when using as a globel, this is more easy to recognize

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:13:06 +02:00
d0c7a16ac7 main_view: set id to be non-required
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:12:55 +02:00
5745a3bd6c advotracker: policy_state update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:12:28 +02:00
7196013bb2 advotracker: get correct crates and modules into scope
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:12:28 +02:00
1aebd4338f advotracker: link to resources
* call from binary-directory will search resource files
  in subdirecotries beneath this directory

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:12:28 +02:00
6f668bf4c3 advotracker: widget update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:12:27 +02:00
97622ba5f5 advotracker: callback: update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:12:27 +02:00
533ae6f8d2 .gitignore: typo correction and commenting user config settings
* we don't save config.toml in upstream

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:12:27 +02:00
23c1875272 database: remove stale submodule
* substitued with 'advetrackerd'

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:12:27 +02:00
02d388c14f advotracker-db: update commit refering to new head
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:11:27 +02:00
016595d702 advotrackerd: introduce new submodule
* orign: https://gitea.networkx.de:50443/rzerres/advotrackerd
* for now, we do have a Microsoft CA which isn't handled as an
  official CA.
  You need to exclude SSL verification to push/pull/clone like this:

* # git config  --file .git/modules/advotrackerd/config --list
* # git config --file .git/modules/advotrackerd/config  http.https://gitea.networkx.de:50443.sslverify false

* # git -c http.https://gitea.networkx.de:50443.sslverify=false submodule add  https://gitea.networkx.de:50443/rzerres/advotrackerd

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:10:49 +02:00
8506b0ce90 advotracker-db: introduce new submodule
* orign: https://gitea.networkx.de:50443/rzerres/advotracker.db
* for now, we do have a Microsoft CA which isn't handled as an
  official CA.
  You need to exclude SSL verification to push/pull/clone like this:

* # git config  --file .git/modules/advotracker-db/config --list
* # git config --file .git/modules/advotracker-db/config  http.https://gitea.networkx.de:50443.sslverify false

* # git -c http.https://gitea.networkx.de:50443.sslverify=false submodule add  https://gitea.networkx.de:50443/rzerres/advotracker-db

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:10:49 +02:00
74fc662a67 Cargo.toml: rebase root of local orbtk sources
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:10:49 +02:00
4f3a63425a Cargo.toml: update repository location
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:10:49 +02:00
42dcd82df2 Cargo.toml: identifier change
* use 'nwx' as company prefix

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:10:49 +02:00
82c1aab492 Cargo.toml: preset the default binary
* use the GUI variant 'advotracker' as the default binary

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:10:48 +02:00
cf375770c1 Corgo.toml: change syntax to reference dependencies
* use explicit style with braces

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:10:48 +02:00
da24fea764 Cargo.toml: add workspace advotracker-db
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 19:10:48 +02:00
321b868bb8 Cargo.toml: comment out orbtk/debug
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:33 +02:00
5f4d01d919 advotracker-framework: restructure source tree
* remove subdirectory backend
  new handling as new submodule advotrackerd
* remove subdirectory frontend
  new hanling as advotracker
* examples: example binaries
* locales: i18n definitions
* src/callbacks: rust state handling for widgets
* src/services: provide service methods (e.g import/export)
* src/widgets: handle frontend definitions
* src/data: provide test-data

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:32 +02:00
8f7be15ef3 services: allianzdirectcall: update process logic
* return value: usize
* import: fill HashMap from source record
* import: fill in vector PolicyData

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:32 +02:00
cddb47b3ad csv-test: update the .env test environment
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:32 +02:00
56aa6ac72c csv-test: include cli flag to provide a test policy number
* TODO: viperus does not offer the input of usize/i64
  therefore we can't use big integer for now

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:32 +02:00
bde94bcce1 csv-test: update test data
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:32 +02:00
8a1f92e44d csv-test: integrate HashMap functionality
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:32 +02:00
267680f547 csv-test: new minimal test datasets
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:32 +02:00
ea4bcaabd6 data.rs: include copy macro for PolicyCode
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:19:32 +02:00
268207318d I18n: update translation patterns
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:18:41 +02:00
5dc3fa1509 Cargo.toml: update umbrella project name, rename submodules
* submodule advotrackerd: provides the database api
* submodule advotracker: the frontend app

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:16:21 +02:00
d57827ca4e examples: csv-test: new testfile that holds enough test records
* no need to parse 40MB
* ~15000 records are more then enough

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:16:16 +02:00
97a5a966d3 advotracker: services substructure
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:48 +02:00
5016cb6b47 advotracker: library definition to use as crate
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:48 +02:00
84e7a86bb3 I18N: update localization file to meet new project name
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:48 +02:00
b7e6d269dc advotracker-framework: Rename 'frontend' to advotracker
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:48 +02:00
0582c1be43 frontend: policycheck_menu
* orbtk code to handle a menu structure

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
507f13ade3 frontend: examples: pdf_check example
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
2bc37f6a24 frontend: resources: used in example code
* example advotracker: stylesheet orbtk test widgets
* example advotracker: MaterialIcons ttf font

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
985cee4f0b frontend: locales: i18n updates
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
267c4faa2c frontend: function update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
22ecaaa0fe frontend: Cargo.toml: include csv for example csv-test
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
9c2beabd33 frontend: examples: remove old orbtk examples maintained upstream
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
53702555a3 Cargo.toml: set projects framework name
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
c3e939c6bb frontend: examples: introduce csv-test
* cli to test data import and export
  - import from a csv file
  - export to a csv file

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
dd8c840cf9 fontend: examples: .env for testing
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:47 +02:00
9e65ef198a frontend: example: csv-import helper update
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
6a7d9a39d1 .gitignore: update new patterns
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
3b889d24e6 frontend: Node.toml
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
a6b6f84fec frontend: example: csv-import helper
* cli to import a given csv configured text file

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
de99076e53 frontend: Cargo.toml: new dependencies
* commandline parsing: clap, viperus
* csv file handling
* envirenment variable: dotenv, envy
* i18n: locales
* serde json support
* tracing: tracing, tracing-subscriber

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
8a8941f0cf policylist: wip: view and state handling updates
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
29b3876264 policydata: wip: view and state handling updates
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
62c786b671 policycheck: wip: view and state handling updates
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
717dc9ba03 frontend: update main_view
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
d4ae415ece frontend: main: update stylesheet reference, basic geometry
* new module 'policycheck_menu'
* reference the project stylesheet
* update a default geometry

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:46 +02:00
9354ea29ab frontend: keys: update Classes, DCES entities, component values
* the elements are available as public advertised string values

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:14:39 +02:00
7600f1b8df frontend: base: update 'PROP_POLICY_LISTS'
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 14:00:01 +02:00
f3af573bd7 frontend: data: define export structure for csv files
* data need to be transfered as a csv-file attachment via email
* each row takes a semicolon separeted list of string fields
* this structure is defined as rust 'struct CSVExport'
* the struct CSVExport will reference to its child stuctures.

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 13:59:56 +02:00
e93c19aacc Cargo.toml: reference to orbtk's local repository
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 13:55:10 +02:00
930d916e3f frontend: resources: assets/resources used inside the frontend
* images: referenced image files
* fonts: rendering elements
* stylesheets: theme definition using CSS subsystem

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 13:55:09 +02:00
2159cc0c24 frontend: base_state: global methods implemented as a trait
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 13:55:09 +02:00
36e90081b5 frontend: keys: static variables used in themes
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 13:55:09 +02:00
a59d364b62 advotracker: delete unused lib definition
Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2020-07-12 13:54:41 +02:00
249 changed files with 2543038 additions and 5279 deletions

17
.gitignore vendored
View File

@@ -1,10 +1,21 @@
# This file should only ignore things that are generated during a build,
# generated by common IDEs, and optional files controlled by the user that
# affect the build (such as config.toml).
# Backup files created from Editors
.#*
.DS_Store
**/*.rs.bk
Cargo.lock
**/*~
/target/
# user adaptions and configs values
/config.toml
# will have compiled files and executables
/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
***.rs.bk

12
.gitmodules vendored
View File

@@ -1,6 +1,6 @@
[submodule "database"]
path = database
url = ./database/
[submodule "backend"]
path = backend
url = ./backend/
[submodule "advotrackerdb"]
path = crates/advotrackerdb
url = https://gitea.networkx.de:50443/rzerres/advotrackerdb
[submodule "advotrackerd"]
path = crates/advotrackerd
url = https://gitea.networkx.de:50443/rzerres/advotrackerd

View File

@@ -3,15 +3,44 @@ name = "advotracker"
version = "0.1.0"
authors = ["Ralf Zerres <ralf.zerres@networkx.de>"]
description = "Supports lawyers to capture relevant data encountered during an online legal advice\n"
repository = "https://github.com/rzerres/advotracker"
homepage = "https://github.com/rzerres/advotracker"
repository = "https://gitea.networkx.de:50443/rzerres/advotracker"
homepage = "https://gitea.networkx.de:50443/rzerres/advotracker"
documentation = "https://docs.rs/advotracker"
readme = "README.md"
license = "0BSD OR MIT"
keywords = [
"advotracker",
"lawyer",
]
edition = "2018"
publish = false
#default-run = "crates/advotracker_client"
[dependencies]
advotrackerdb = { version = "0.1.0-alpha1", path = "crates/advotrackerdb" }
advotrackerd = { version = "0.1.0-alpha1", path = "crates/advotrackerd", default-features = false }
advotracker_client = { version = "0.1.5-alpha2", path = "crates/advotracker_client", default-features = false }
[features]
default = ["sqlite"]
# enable optional db backends
sqlite = []
#sqlite = ["advotrackerdb_sqlite"]
#postgresql = ["advotrackerdb_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]
incremental = true
panic = "abort"
lto = true
codegen-units=1
@@ -21,15 +50,6 @@ opt-level="s"
# optimize to smallest size
#opt-level = "z"
[profile.dev]
opt-level = 0
debug = true
lto = false
codegen-units = 5
panic = 'unwind'
incremental = true
overflow-checks = true
[profile.test]
opt-level = 0
debug = 2
@@ -43,7 +63,7 @@ overflow-checks = true
[workspace]
members = [
"backend",
"frontend",
"advotracker_qml",
"crates/advotrackerd",
"crates/advotrackerdb",
"crates/advotracker_client",
]

147
README.md
View File

@@ -1,24 +1,145 @@
<!-- AdvoTracker.markdown -->
<!-- version: 1.1 -->
<!-- AdvoTracker README.md -->
<!-- version: 0.1.3 -->
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-generate-toc again -->
<!-- markdown-toc end -->
# AdvoTracker - Hotline tool für Advokaten #
## About
AdvoTracker unterstützt Anwälte bei der Erfassung von Mandatsdaten zu einer Online-Beratung.
`advotracker` supports lawyers to capture relevant data encountered during an online
legal advice.
Das Tool wurde als multi-Pattform Anwendung konzipiert.
The application components are implemented using the programming language *Rust*.
The graphical user interface (GUI) uses the class-lib *OrbTk*, which is natively
encoded in *Rust* as well.
Als Programmiersprache wird *Rust* verwendet. Die Implementierung der
GUI Elemente erfolgt mit der Klassenbibliothek *OrbTk*.
`advotracker` can be deployed on every target operating system that is officialy
supported by the `OrbTK` toolkit. Currently included are:
Als Dokumentationsquellen wird auf die offiziellen Projektseiten [Rust Book][^1] und [OrbTk][^2] verwiesen.
* macOS
* Linux
* openBSD
* Redox OS
* Web-Browser
* Windows
# Internationalisierung #
Porting to and in activ development are:
In allen Dialogen und Meldungen erfolgt die Ausgabe entsprechend der Sprache, die als
aktive Sprache in der Umgebungsvariable definiert ist (default: LANG = en_US.UTF8 ) ausgewählt.
* Android
* iOS
* ubuntu Touch
Reference is made to the official project pages of [Rust Book][^1] and [OrbTk][^2]
as documentation sources.
## Internationalization
Dialogs and messages generated inside the application will respect the system language
of the active user. This is adaptable via the environment variable
(default: LANG = en_US.UTF8 or LANG = C).
Within the source code you can find translated constants in the subdirectory 'locales'
(<crate-root>/src/locales/advotracker.json).
For every supported language-string, you will find a block starting with the
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).
## Installation from source code
You can either download the `advotracker` source code as a Zip-File or using `git`
from projects repositoy URL.
The source code is subdiveded in three crates:
* advotracker
* advotrackerd
* advotrackerdb
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:
```sh
$ cd <your_path>
$ git -c http.https://gitea.networkx.de:50443.sslverify=false \
clone --recurse-submodules --jobs=10 \
https://gitea.networkx.de:50443/rzerres/advotracker
```
To compile the target binary code, you have to use rusts toolchain.
If this isn't already installed on your development system, please go ahead
and either use the official supported installation tool from the rust communtiy
([rustup][^3]). As an alternitiv, you can download and install the compiler package
using your systems package manager.
### native operating system binaries
A binary compatible with your target operating system will be compiled
with the following command:
```sh
$ cd <advotracker_root>
$ cargo build --release
```
The toolchain also allows to cross-compile for other operating systems. Please
consult the rust documentation for further instructions.
### web-browser application
- **Prerequisits**
To run as a browser, electron or cordova app, you have to install cargo-node:
```sh
cargo install -f cargo-node
```
cargo-node will require a working version of `npm` (>=v6.9.0).
You may download [Node.js][^4], which includes npm as well.
- **Start as browser app**
You can run `Advotracker` as a web-browser app with the following call.
Once the app is running, you can connect to it opening the given URL
in you Web-Browser.
```sh
cargo node run --target browser --bin advotracker
```
- **Start as electron app**
```sh
cargo node run --target electron advotracker
```
- **Start as android app**
```sh
cargo node run --target android --bin advotracker
```
## Build and run documentation
You can build and view the latest documentation by executing the following command:
```sh
cargo doc --no-deps --open
```
This will render the web-pages, collecting the documentation paragraphs in the
source-code. When finished, it will open a new tab in your web browser
presenting the documentation.
## Installation
To install the compiled binary you can use rust package manager `cargo` as well.
```sh
cd <advotracker_root>
$ cargo install
```
In addition, you will need to copy the resource folder into your target directory.
This will provide the access to used fonts, images und stylesheets.
---
@@ -28,7 +149,7 @@ This work is licensed under a [Creative Common License 4.0][License-CC_BY]
![Creative Common Logo][Logo-CC_BY]
© 2020 Ralf Zerres, Networkx GmbH
<EFBFBD> 2020-2021 Ralf Zerres, Networkx GmbH
---
@@ -36,3 +157,5 @@ Foodnotes
[^1]: Rust Book: https://doc.rust-lang.org/book/
[^2]: OrbTK GUI: https://gitlab.redox-os.org/redox-os/orbtk
[^3]: Rustup: https://rustup.rs/
[^4]: Node.js: https://nodejs.org/dist/v10.16.3/

Submodule backend deleted from 2dbea55fba

View File

@@ -0,0 +1,17 @@
###
# .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

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

View File

@@ -0,0 +1,61 @@
[package]
name = "advotracker_client"
version = "0.1.5-alpha2"
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"
[target.x86_64-pc-windows-gnu]
linker = "lld-link"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = [ "winuser" ] }
windres = { git = "https://github.com/FaultyRAM/windres-rs", branch = "master" }
[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" }
dotenv = { version = "~0.15.0" }
envy = { version = "~0.4" }
lettre ={ version = "0.10.0-beta.1" }
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" }
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"] }
[build-dependencies]
winres = { version = "0.1.11" }
#twine = { version = "0.3.8" }
twine = { path = "../../../twine", features = ["serde"] }
[features]
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"
[package.metadata.winres]
LegalCopyright = "Copyright © 2020-2021"
[[bin]]
name = "advotracker"
path = "src/main.rs"

View File

@@ -0,0 +1,8 @@
[[apps]]
name = "advotracker"
width = 580
height = 280
assets = "resources/advotracker"
[[apps.fonts]]
font_family = "MaterialIcons-Regular"
src = "resources/fonts/MaterialIcons.ttf"

View File

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

View File

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

View File

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

View File

@@ -0,0 +1 @@
Allianz DirectCall Protokoll!

View File

@@ -0,0 +1,38 @@
# About
This is the client component of `advotracker`.
## Windows specific
We like to support an icon an object attributes for the compiled
version of `advotracker`. While searching for a solution, the description of this
[Web link][https://graphicdesign.stackexchange.com/questions/77359/how-to-convert-a-square-svg-to-all-size-ico]
was adapted and combined with a `windres` crate.
### Icon creation
This commandline solution will create an icon that can be linked into the Windows binary.
* create the `svg` art file
You may use `inkscape`, a versitile and user frendly
tool to create your vector graphics art. Save it as `advotracker.svg`. Next export the scaled png files.
```
inkscape -w 16 -h 16 -o advotracker_16.png -l advotracker.svg
inkscape -w 32 -h 32 -o advotracker_32.png -l advotracker.svg
inkscape -w 48 -h 48 -o advotracker_48.png -l advotracker.svg
inkscape -w 64 -h 64 -o advotracker_64.png -l advotracker.svg
```
* create the `ico` file
The ico format can handle multiple layes with different resolutions.
We make use of ImageMagick to create the icon file like this:
```
convert advotracker_16.png advotracker_32.png advotracker_48.png advotracker_64.png advotracker.ico
```
* link in the icon
rust offers the `windres` crate, that will handle the linking of icons
as well as the definition of binary objet resources. `advotracker`
will define the needed settings in its `build.rs` file.

View File

@@ -0,0 +1,61 @@
// *
// * 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
"Check result": "Prüfungsergebnis",
"Checklist elements: ": "Prüflistenelemente: ",
"Clear": "Zurücksetzen",
"Create ticket": "Ticket erstellen",
"Importing data": "Importiere Datensätze",
"Only numbers are valid": "Nur Nummern sind zulässig",
"Error:": "Fehler:",
"Quit": "Beenden",
"Policy code": "Vers.-Schein/Schadennummer",
"Policy holder": "Versicherungsnehmer",
"Policy number is to long": "Die Nummer ist zu lang",
"Policy number is to short": "Die Nummer ist zu kurz",
"Policy number": "Versicherungsnummer",
"Processing time": "Bearbeitungszeit",
"Reason": "Grund",
"The given policy number is invalid": "Die Versicherungsnummer ist ungültig",
"The given policy number is valid": "Die Versicherungsnummer ist gültig",
"Account": "Benutzer",
"Toggle theme": "Thema wechseln",
"Validation policy number": "Prüfung Versicherungsnummer",
// ticketdata_view
"Callback number": "Rückrufnummer",
"Callback date": "Erreichbarkeit",
"Clear": "Zurücksetzen",
"Deductible": "Selbstbehalt",
"Harm type": "Rechtsproblem",
"IVR comment": "Rechtsrat",
"Policy holder": "Versicherungsnehmer",
"Recipient (To)": "Empfänger (To)",
"Copie (CC)": "Kopie (CC)",
"Send": "Senden",
// localization view
"English": "Englisch",
"German": "Deutsch",
"Language ID": "Sprache ID",
"Localization dialog": "Lokalisierungs-Dialog",
// configuration view
"Configuration settings": "Konfigurationseinstellungen",
"Configuration file": "Konfigurationsdatei",
"Default theme": "Standard-Thema",
"Language Id": "Sprach-Id",
"Load": "Laden",
"Save": "Speichern",
}
)

View File

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

View File

@@ -0,0 +1,10 @@
Theme (
styles: {
"container_form": (
base: "container",
properties: {
"border": 1,
},
),
}
)

Binary file not shown.

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

@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="105mm"
height="74mm"
viewBox="0 0 105 74"
version="1.1"
id="svg8"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="Hiedemann_Logo.svg">
<title
id="title850">Hiedemann Rechtsanwälte</title>
<defs
id="defs2" />
<sodipodi:namedview
units="mm"
inkscape:snap-global="true"
inkscape:snap-grids="true"
inkscape:snap-nodes="true"
inkscape:window-maximized="1"
inkscape:window-y="27"
inkscape:window-x="0"
inkscape:window-height="1088"
inkscape:window-width="2048"
showgrid="false"
inkscape:document-rotation="0"
inkscape:current-layer="layer1"
inkscape:document-units="mm"
inkscape:cy="285.11146"
inkscape:cx="343.98278"
inkscape:zoom="1.4564683"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Hiedemann Rechtsanwälte</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Hiedemann Rechtsanwälte</dc:title>
</cc:Agent>
</dc:creator>
<dc:publisher>
<cc:Agent>
<dc:title>Networkx GmbH</dc:title>
</cc:Agent>
</dc:publisher>
</cc:Work>
</rdf:RDF>
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>Hiedemann Rechtsanwälte</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
style="display:inline"
inkscape:label="Rahmen"
id="layer2"
inkscape:groupmode="layer" />
<g
style="display:inline"
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Logo">
<g
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
inkscape:export-filename="/data/development/advotracker/advotracker/resources/images/hiedemann_logo.png"
transform="matrix(0.5,0,0,0.5,26.483775,16.188821)"
id="g1005">
<g
id="g910"
style="display:inline"
transform="translate(-1.958558,18.772823)"
inkscape:export-filename="/data/development/advotracker/advotracker/resources/images/hiedemann_logo.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<rect
ry="6.2927017"
rx="0.08973857"
y="1.2013354"
x="4.9724188"
height="24.806967"
width="99.907379"
id="rect852"
style="vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.0926207;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g1098"
transform="matrix(1.3250965,0,0,1.3250965,-38.983201,-118.19402)"
inkscape:export-filename="/data/development/advotracker/advotracker/resources/images/hiedemann_logo.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<text
transform="scale(0.95388348,1.0483461)"
id="text835"
y="108.37959"
x="36.210163"
style="font-size:8.71712px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:'FreeSans, Normal';letter-spacing:2.60261px;word-spacing:0px;writing-mode:lr-tb;fill:#c46069;fill-opacity:1;stroke:#000000;stroke-width:0.363212px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.71712px;font-family:'Cyntho Pro';-inkscape-font-specification:'Cyntho Pro, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#c46069;fill-opacity:1;stroke:none;stroke-width:0.363212px"
y="108.37959"
x="36.210163"
id="tspan833"
sodipodi:role="line">HIEDE<tspan
id="tspan889"
style="letter-spacing:1.31762px">M</tspan><tspan
id="tspan883"
style="letter-spacing:1.31762px;stroke-width:0.363212px">A</tspan>NN</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.58611px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:'FreeSans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:3.43958px;word-spacing:0px;writing-mode:lr-tb;fill:#9d9b9b;fill-opacity:1;stroke:none;stroke-width:0.444725px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="40.402027"
y="104.09837"
id="text853"
transform="scale(0.86606999,1.1546411)"><tspan
sodipodi:role="line"
id="tspan851"
x="40.402027"
y="104.09837"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333px;font-family:'Cyntho Pro';-inkscape-font-specification:'Cyntho Pro';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#9d9b9b;fill-opacity:1;stroke:none;stroke-width:0.444725px"><tspan
id="tspan925"
style="letter-spacing:3.70417px">REC</tspan><tspan
style="letter-spacing:3.33375px"
id="tspan1083">HT</tspan><tspan
style="letter-spacing:2.92894px"
id="tspan1075">S</tspan><tspan
style="letter-spacing:3.23585px"
id="tspan1069">AN</tspan><tspan
id="tspan921"
style="letter-spacing:2.94746px">WÄLTE</tspan></tspan></text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="181.41733"
height="181.41733"
viewBox="0 0 48 48"
version="1.1"
id="svg8"
sodipodi:docname="Hotline.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
inkscape:export-filename="/data/development/advotracker/images/Hotline.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<title
id="title903">Hotline</title>
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.5001171"
inkscape:cx="106.62221"
inkscape:cy="103.19504"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
units="px"
inkscape:window-width="1280"
inkscape:window-height="656"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
showguides="false"
inkscape:guide-bbox="true">
<sodipodi:guide
position="-2.2601038,30.435621"
orientation="0,-1"
id="guide1331" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Hotline</dc:title>
<cc:license
rdf:resource="http://artlibre.org/licence/lal" />
</cc:Work>
<cc:License
rdf:about="http://artlibre.org/licence/lal">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Hotline-Icon"
inkscape:groupmode="layer"
id="layer1"
style="display:inline">
<g
id="g1369"
transform="translate(47.971251,-0.00147642)">
<path
style="fill:#ffc49b;fill-opacity:0.470588;stroke:#d1b5a4;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.988588;paint-order:markers fill stroke"
d="m -43.193278,41.999791 c 1.49691,-2.40444 3.504494,-4.137234 3.97049,-7.897551 -8.897002,-20.115732 11.448594,-39.761883 23.320156,-25.6774766 4.111107,0.7296566 15.904257,0.2419988 9.448496,27.2025326 0.655793,2.44805 2.687955,4.433014 5.1147,6.285219 -7.038787,4.303603 -14.139814,3.119543 -21.26392,-0.09939 -7.121959,1.345389 -14.838126,5.638639 -20.589922,0.186666 z"
id="path954"
sodipodi:nodetypes="ccccccc" />
<path
style="fill:#fff69f;fill-opacity:1;stroke:#d1b4a3;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.992157;paint-order:markers fill stroke"
d="m -16.566294,17.564379 c 2.321537,1.627329 4.680103,3.221015 5.43583,6.271019 l -0.128201,11.537305 c -1.500786,4.68743 -3.897101,6.738521 -6.558077,8.314102 -1.547997,0.916578 -2.915462,2.596633 -4.733266,2.74464 -2.358949,0.192067 -3.335981,-1.37334 -4.702985,-2.208498 -10.561198,-6.452258 -9.299955,-15.045913 -3.54451,-18.563078 5.999351,-1.157234 11.292071,-3.485647 14.231209,-8.09549 z"
id="path956"
sodipodi:nodetypes="cccssscc" />
<path
style="fill:none;fill-opacity:1;stroke:#acbac7;stroke-width:0.999997;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"
d="m -5.8305041,36.150455 c 0.3952343,5.0031 -3.5482004,3.771616 -15.3273579,3.956909"
id="path1001"
sodipodi:nodetypes="cc" />
<g
id="g1357">
<circle
style="opacity:0.902314;fill:#8c8c8c;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.470588;paint-order:markers fill stroke"
id="path1314"
cx="-16.847094"
cy="31.137058"
r="1.6374409" />
<circle
style="opacity:0.902314;fill:#8c8c8c;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.470588;paint-order:markers fill stroke"
id="circle1316"
cx="-29.12112"
cy="31.137058"
r="1.6374409" />
<ellipse
style="opacity:0.902314;fill:#8c8c8c;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.470588;paint-order:markers fill stroke"
id="path1301"
ry="1.5932699"
rx="2.0367212"
cy="39.994835"
cx="-22.984106" />
</g>
<g
id="g1337"
transform="translate(0,1.7607786)">
<rect
style="opacity:1;vector-effect:none;fill:#d9e0e5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect1293"
width="4.1744041"
height="8.3096123"
x="-7.5382333"
y="25.556793" />
<path
style="opacity:0.902314;mix-blend-mode:normal;fill:none;fill-opacity:0.975108;stroke:#acbac7;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"
d="m -7.6299573,25.267021 c 0,0 4.3765084,-0.627056 4.3333554,0.61985 -0.090936,2.627603 0.2119865,5.547594 -0.1762703,7.668357 -0.2291003,1.251407 -4.3491445,0.568011 -4.3491445,0.568011 z"
id="path999"
sodipodi:nodetypes="csscc" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -0,0 +1,25 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
extern crate winres;
use twine::build_translations;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
build_translations(&["./src/i18n/localization.ini"], "i18n.rs").unwrap();
if cfg!(target_os = "windows") {
let mut res = winres::WindowsResource::new();
//res.set_icon(".\assets\icons\adovtracker\advotracker.ico")
res.set_icon("advotracker.ico")
.set("InternalName", "ADVOTRACKER.EXE")
// manually set version 0.1.5.2
.set_version_info(winres::VersionInfo::PRODUCTVERSION, 0x0000000100050002);
res.compile().unwrap();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
Target: debug
[ralf@jacara-x1 frontend]$ time ../target/debug/examples/csv-import --importFile /home/ralf/projekte/Hiedemann/Allianz_Vorgaben_Policycheck/ERG.txt -v
Jun 27 02:43:48.886 TRACE csv-import: "Umgebungsvariablen prüfen" state="gestartet"
Jun 27 02:43:48.886 TRACE csv-import: environment="system" lang="de_DE.UTF-8"
Jun 27 02:43:48.887 DEBUG csv-import: missing value for field test_lang
Jun 27 02:43:48.887 TRACE csv-import: environment="envy" lang="de_DE.UTF-8"
Jun 27 02:43:48.887 TRACE csv-import: "Umgebungsvariablen prüfen" state="beendet"
Jun 27 02:43:48.887 TRACE csv-import: process="Programmargumente prüfen" state="gestartet"
RUST_LOG=None
Jun 27 02:43:48.887 TRACE csv_import::parse_args: verbose 1
config_file: "csv_import.ron"
import_file: "/home/ralf/projekte/Hiedemann/Allianz_Vorgaben_Policycheck/ERG.txt"
verbosity level: 1
Jun 27 02:43:48.887 TRACE csv-import: process="Programmargumente prüfen" state="beendet"
Jun 27 02:43:48.887 TRACE csv-import: process="Programmlogik starten" state="gestartet"
Jun 27 02:43:48.887 TRACE csv-import: extension=Some("txt") file=File { fd: 3, path: "/home/ralf/projekte/Hiedemann/Allianz_Vorgaben_Policycheck/ERG.txt", read: true, write: false }
Jun 27 02:43:48.888 TRACE csv-import: header=StringRecord(["DION", "VERS", "POLLFNR"])
Jun 27 02:43:57.513 TRACE csv-import: record_count=2498330
Imported 2498330 records
Jun 27 02:43:57.513 TRACE csv-import: process="Programmlogik beendet" state="beendet"
real 0m8,700s
user 0m8,675s
sys 0m0,017s
Target: release
[ralf@jacara-x1 frontend]$ time ../target/release/examples/csv-import --importFile /home/ralf/projekte/Hiedemann/Allianz_Vorgaben_Policycheck/ERG.txt -v
Jun 27 02:48:13.753 TRACE csv-import: "Umgebungsvariablen prüfen" state="gestartet"
Jun 27 02:48:13.753 TRACE csv-import: environment="system" lang="de_DE.UTF-8"
Jun 27 02:48:13.753 DEBUG csv-import: missing value for field test_lang
Jun 27 02:48:13.753 TRACE csv-import: environment="envy" lang="de_DE.UTF-8"
Jun 27 02:48:13.753 TRACE csv-import: "Umgebungsvariablen prüfen" state="beendet"
Jun 27 02:48:13.753 TRACE csv-import: process="Programmargumente prüfen" state="gestartet"
RUST_LOG=None
Jun 27 02:48:13.753 TRACE csv_import::parse_args: verbose 1
config_file: "csv_import.ron"
import_file: "/home/ralf/projekte/Hiedemann/Allianz_Vorgaben_Policycheck/ERG.txt"
verbosity level: 1
Jun 27 02:48:13.753 TRACE csv-import: process="Programmargumente prüfen" state="beendet"
Jun 27 02:48:13.753 TRACE csv-import: process="Programmlogik starten" state="gestartet"
Jun 27 02:48:13.754 TRACE csv-import: extension=Some("txt") file=File { fd: 3, path: "/home/ralf/projekte/Hiedemann/Allianz_Vorgaben_Policycheck/ERG.txt", read: true, write: false }
Jun 27 02:48:13.754 TRACE csv-import: header=StringRecord(["DION", "VERS", "POLLFNR"])
Jun 27 02:48:14.098 TRACE csv-import: record_count=2498330
Imported 2498330 records
Jun 27 02:48:14.098 TRACE csv-import: process="Programmlogik beendet" state="beendet"
real 0m0,355s
user 0m0,338s
sys 0m0,017s

View File

@@ -0,0 +1,7 @@
# set the language variable used in test-runs
#test lang=it
TEST_LANG=en
#RUST_LOG=csv-import=trace
LOG=debug
USERNAME=ralf
DB_DRIVER=sqlite

View File

@@ -11,6 +11,7 @@ enum Action {
ValueChanged(Entity),
IncrementCounter,
RemoveItem,
ToggleTheme(Entity),
}
#[derive(AsAny)]
@@ -31,64 +32,72 @@ impl MainViewState {
}
impl State for MainViewState {
fn update(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
if let Some(action) = self.action {
match action {
Action::AddItem => {
let len = ctx.widget().get::<List>("list").len();
let len = main_view(ctx.widget()).list().len();
if len < 5 {
ctx.widget()
.get_mut::<List>("list")
main_view(ctx.widget())
.list_mut()
.push(format!("Item {}", len + 1));
ctx.child("items").set("count", len + 1);
ctx.child("remove-item-button").set("enabled", true);
ctx.child("items").clone_or_default::<usize>("Item");
items_widget(ctx.child("items")).set_count(len + 1);
button(ctx.child("remove-item-button")).set_enabled(true);
button(ctx.child("remove-item-button")).set_visibility(Visibility::Visible);
if len == 4 {
ctx.child("add-item-button").set("enabled", false);
button(ctx.child("add-item-button")).set_enabled(false);
button(ctx.child("add-item-button"))
.set_visibility(Visibility::Collapsed);
}
}
}
Action::RemoveItem => {
let len = ctx.widget().get::<List>("list").len();
let len = main_view(ctx.widget()).list().len();
if len > 0 {
ctx.widget().get_mut::<List>("list").remove(len - 1);
ctx.child("items").set("count", len - 1);
ctx.child("add-item-button").set("enabled", true);
main_view(ctx.widget()).list_mut().remove(len - 1);
items_widget(ctx.child("items")).set_count(len - 1);
button(ctx.child("add-item-button")).set_enabled(true);
button(ctx.child("add-item-button")).set_visibility(Visibility::Visible);
if len == 1 {
ctx.child("remove-item-button").set("enabled", false);
button(ctx.child("remove-item-button")).set_enabled(false);
button(ctx.child("remove-item-button"))
.set_visibility(Visibility::Collapsed);
}
}
}
Action::IncrementCounter => {
*ctx.widget().get_mut::<usize>("counter") += 1;
*main_view(ctx.widget()).counter_mut() += 1;
let counter = *ctx.widget().get::<usize>("counter");
let counter = *main_view(ctx.widget()).counter();
ctx.widget().set(
"result",
String16::from(format!("Button count: {}", counter)),
);
main_view(ctx.widget())
.set_result(String16::from(format!("Button count: {}", counter)));
}
Action::ClearText => {
ctx.widget().set("text_one", String16::from(""));
ctx.widget().set("text_two", String16::from(""));
main_view(ctx.widget()).set_text_one(String16::default());
main_view(ctx.widget()).set_text_two(String16::default());
}
Action::EntryActivated(entity) => {
let mut widget = ctx.get_widget(entity);
let text = widget.get_mut::<String16>("text");
let mut text_box = text_box(ctx.get_widget(entity));
let text = text_box.text_mut();
println!("submitting {}", text);
text.clear();
}
Action::EntryChanged(entity) => {
let widget = ctx.get_widget(entity);
let text = widget.get::<String16>("text");
println!("entry changed: {}", text);
println!("entry changed: {}", text_box(ctx.get_widget(entity)).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));
Action::ValueChanged(_entity) => {
//println!("Slider value changed");
}
Action::ToggleTheme(entity) => {
let light = *ctx.get_widget(entity).get::<bool>("selected");
let theme = if light { light_theme() } else { dark_theme() };
ctx.switch_theme(theme);
}
}
@@ -96,24 +105,19 @@ impl State for MainViewState {
}
}
fn update_post_layout(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
fn update_post_layout(&mut self, _: &mut Registry, ctx: &mut Context) {
let mut selection_string = "Selected:".to_string();
for index in &ctx.widget().get::<SelectedIndices>("selected_indices").0 {
for index in &main_view(ctx.widget()).selected_indices().0 {
selection_string = format!("{} {}", selection_string, index);
}
ctx.child("selection")
.set("text", String16::from(selection_string));
text_block(ctx.child("selection")).set_text(selection_string);
}
}
fn create_header(ctx: &mut BuildContext, text: &str) -> Entity {
TextBlock::new()
.text(text)
.element("text-block")
.class("h1")
.build(ctx)
TextBlock::new().text(text).style("header").build(ctx)
}
type List = Vec<String>;
@@ -136,6 +140,14 @@ widget!(
impl Template for MainView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
let slider = Slider::new()
.min(0.0)
.max(1.0)
.on_changed(move |states, entity| {
state(id, states).action(Action::ValueChanged(entity));
})
.build(ctx);
self.name("MainView")
.result("Button count: 0")
.counter(0)
@@ -147,16 +159,16 @@ impl Template for MainView {
])
.list_count(3)
.selection_list(vec![
"Item 1".to_string(),
"Item 2".to_string(),
"Item 3".to_string(),
"Item 4".to_string(),
"Item 5".to_string(),
"Item 6".to_string(),
"Item 7".to_string(),
"Item 8".to_string(),
"Item 9".to_string(),
"Item 10".to_string(),
"Select Item 1".to_string(),
"Select Item 2".to_string(),
"Select Item 3".to_string(),
"Select Item 4".to_string(),
"Select Item 5".to_string(),
"Select Item 6".to_string(),
"Select Item 7".to_string(),
"Select Item 8".to_string(),
"Select Item 9".to_string(),
"Select Item 10".to_string(),
])
.combo_box_list(vec![
"CB 1".to_string(),
@@ -174,25 +186,21 @@ impl Template for MainView {
.combo_box_list_count(10)
.child(
Grid::new()
.margin(8.0)
.columns(
Columns::new()
.add(132.0)
.add(16.0)
.add(132.0)
.add(16.0)
.add(132.0),
)
.margin(8)
.columns(Columns::new().add(132).add(16).add(132).add(16).add(132))
.rows(Rows::new().add("*").add(32))
.child(
// Row 0
Stack::new()
.attach(Grid::column(0))
.attach(Grid::row(0))
// Column 0
.child(create_header(ctx, "Buttons"))
.child(
Button::new()
.text("Button")
.margin((0.0, 8.0, 0.0, 0.0))
.icon(material_font_icons::CHECK_FONT_ICON)
.margin((0, 8, 0, 0))
.icon(material_icons_font::MD_CHECK)
.attach(Grid::column(0))
.attach(Grid::row(1))
.on_click(move |states, _| {
@@ -204,19 +212,19 @@ impl Template for MainView {
.child(
Button::new()
.text("Primary")
.element("button")
.class("primary")
.margin((0.0, 8.0, 0.0, 0.0))
.icon(material_font_icons::CHECK_FONT_ICON)
.style("button_primary")
.margin((0, 8, 0, 0))
.icon(material_icons_font::MD_360)
.attach(Grid::column(0))
.attach(Grid::row(2))
.build(ctx),
)
.child(
ToggleButton::new()
.class("single_content")
.style("button_single_content")
.text("ToggleButton")
.margin((0.0, 8.0, 0.0, 0.0))
.margin((0, 8, 2, 0))
.icon(material_icons_font::MD_ALARM_ON)
.attach(Grid::column(0))
.attach(Grid::row(3))
.build(ctx),
@@ -224,45 +232,38 @@ impl Template for MainView {
.child(
CheckBox::new()
.text("CheckBox")
.margin((0.0, 8.0, 0.0, 0.0))
.margin((0, 8, 0, 0))
.attach(Grid::column(0))
.attach(Grid::row(4))
.build(ctx),
)
.child(
Switch::new()
.margin((0.0, 8.0, 0.0, 0.0))
.margin((0, 8, 0, 0))
.attach(Grid::column(0))
.attach(Grid::row(5))
.build(ctx),
)
.child(slider)
.child(
TextBlock::new()
.margin((0.0, 8.0, 0.0, 0.0))
.element("h1")
.id("value_text")
.text("0")
.h_align("center")
.build(ctx),
)
.child(
Slider::new()
.on_changed(move |states, entity| {
state(id, states).action(Action::ValueChanged(entity));
})
ProgressBar::new()
.val(slider)
.margin((0, 8, 0, 0))
.build(ctx),
)
.build(ctx),
)
.child(
Stack::new()
// Column 2
.attach(Grid::column(2))
.attach(Grid::row(0))
.child(create_header(ctx, "Text"))
.child(
TextBlock::new()
.class("body")
.style("body")
.text(("result", id))
.margin((0.0, 8.0, 0.0, 0.0))
.margin((0, 8, 0, 0))
.attach(Grid::column(2))
.attach(Grid::row(1))
.build(ctx),
@@ -271,7 +272,7 @@ impl Template for MainView {
TextBox::new()
.water_mark("TextBox...")
.text(("text_one", id))
.margin((0.0, 8.0, 0.0, 0.0))
.margin((0, 8, 0, 0))
.attach(Grid::column(2))
.attach(Grid::row(2))
.on_activate(move |states, entity| {
@@ -286,7 +287,7 @@ impl Template for MainView {
TextBox::new()
.water_mark("TextBox...")
.text(("text_two", id))
.margin((0.0, 8.0, 0.0, 0.0))
.margin((0, 8, 0, 0))
.attach(Grid::column(2))
.attach(Grid::row(2))
.on_activate(move |states, entity| {
@@ -299,9 +300,10 @@ impl Template for MainView {
)
.child(
Button::new()
.margin((0.0, 8.0, 0.0, 0.0))
.class("single_content")
.margin((0, 8, 0, 0))
.style("button_single_content")
.text("clear text")
.icon(material_icons_font::MD_CLEAR)
.on_click(move |states, _| {
state(id, states).action(Action::ClearText);
true
@@ -310,8 +312,8 @@ impl Template for MainView {
)
.child(
NumericBox::new()
.margin((0.0, 8.0, 0.0, 0.0))
.max(123.0)
.margin((0, 8, 0, 0))
.max(123)
.step(0.123)
.val(0.123)
.build(ctx),
@@ -319,24 +321,25 @@ impl Template for MainView {
.build(ctx),
)
.child(
// Column 4
Grid::new()
.rows(
Rows::new()
.add("auto")
.add(32.0)
.add(16.0)
.add(204.0)
.add(32)
.add(16)
.add(204)
.add("auto")
.add(192.0)
.add(192)
.add("auto"),
)
.columns(Columns::new().add("*").add(4.0).add("*"))
.columns(Columns::new().add("*").add(4).add("*"))
.attach(Grid::column(4))
.attach(Grid::row(0))
.child(
TextBlock::new()
.text("Items")
.element("text-block")
.class("h1")
.style("header")
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.attach(Grid::row(0))
@@ -350,7 +353,8 @@ impl Template for MainView {
.get::<Vec<String>>("combo_box_list")[index]
.clone();
TextBlock::new()
.margin((0.0, 0.0, 0.0, 2.0))
.style("small_text")
.margin((0, 0, 0, 2))
.v_align("center")
.text(text)
.build(bc)
@@ -359,58 +363,53 @@ impl Template for MainView {
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.attach(Grid::row(1))
.margin((0.0, 8.0, 0.0, 0.0))
.margin((0, 8, 0, 0))
.count(("combo_box_list_count", id))
.build(ctx),
)
.child(
ItemsWidget::new()
.element("items-widget")
.id("items")
.padding((4.0, 4.0, 4.0, 2.0))
.padding((4, 4, 4, 2))
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.attach(Grid::row(3))
.margin((0.0, 0.0, 0.0, 8.0))
.margin((0, 0, 0, 8))
// bc = build-context
.items_builder(move |bc, index| {
let text = bc.get_widget(id).get::<Vec<String>>("list")
[index]
.clone();
Button::new()
.margin((0.0, 0.0, 0.0, 2.0))
.text(text)
.build(bc)
Button::new().margin((0, 0, 0, 2)).text(text).build(bc)
})
.count(("list_count", id))
.build(ctx),
)
.child(
Button::new()
.element("button")
.class("single_content")
.style("button_single_content")
.id("remove-item-button")
.icon(material_font_icons::MINUS_FONT_ICON)
.icon(material_icons_font::MD_REMOVE_CIRCLE)
.on_click(move |states, _| {
state(id, states).action(Action::RemoveItem);
true
})
.min_width(0.0)
.min_width(0)
.attach(Grid::column(0))
.attach(Grid::row(4))
.build(ctx),
)
.child(
Button::new()
.element("button")
.class("single_content")
.style("button_single_content")
.id("add-item-button")
.icon(material_font_icons::ADD_FONT_ICON)
.icon(material_icons_font::MD_ADD_CIRCLE)
.on_click(move |states, _| {
state(id, states).action(Action::AddItem);
true
})
.min_width(0.0)
.min_width(0)
.attach(Grid::column(2))
.attach(Grid::row(4))
.build(ctx),
@@ -421,27 +420,28 @@ impl Template for MainView {
.attach(Grid::column_span(3))
.attach(Grid::row(5))
.selected_indices(id)
.margin((0.0, 16.0, 0.0, 8.0))
.margin((0, 16, 0, 8))
.items_builder(move |bc, index| {
let text = bc
.get_widget(id)
.get::<Vec<String>>("selection_list")[index]
.clone();
TextBlock::new()
.margin((0.0, 0.0, 0.0, 2.0))
.margin((0, 0, 0, 2))
.v_align("center")
.text(text)
.build(bc)
})
.on_selection_changed(|_, _, _| println!("Selection changed"))
.count(("selection_list_count", id))
.build(ctx),
)
.child(
// todo: wrong text width????
TextBlock::new()
.element("text-block")
.style("body")
.id("selection")
.max_width(120.0)
.max_width(120)
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.attach(Grid::row(6))
@@ -450,6 +450,30 @@ impl Template for MainView {
)
.build(ctx),
)
.child(
// Row 1
Stack::new()
.orientation("horizontal")
.attach(Grid::row(1))
.attach(Grid::column(0))
.child(
TextBlock::new()
.style("body")
.text("Toggle theme: ")
.v_align("center")
.margin((0, 0, 4, 0))
.build(ctx),
)
.child(
Switch::new()
.on_changed(move |states, entity| {
state(id, states).action(Action::ToggleTheme(entity));
})
.v_align("center")
.build(ctx),
)
.build(ctx),
)
.build(ctx),
)
}
@@ -463,8 +487,8 @@ fn main() {
.window(|ctx| {
Window::new()
.title("OrbTk - widgets example")
.position((100.0, 100.0))
.size(468.0, 730.0)
.position((100, 100))
.size(468, 730)
.resizeable(true)
.child(MainView::new().build(ctx))
.build(ctx)

View File

@@ -0,0 +1,89 @@
/*
* OrbTk - The Orbital Widget Toolkit
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (MIT)
*/
// use orbtk::prelude::*;
// /*
// * WidgetContainer = entity
// */
// // methods get, get_mut, try_get, try_get_mut and clone
// // ctx.widget returns a WidgetContainer that wraps the current widget of the state
// let mut widget_container: WidgetContainer = ctx.widget();
// // property handling (componets)
// // Gets a reference for the property
// // .get<PropertyType>("property_name");
// widget_container.get::<String16>("text");
// // Sets the value of a property
// // .set<PropertyType>("property_name", property_value);
// widget_container.set::<String16>("text", "my_text");
// /*
// * Child WidgetContainer = child entity
// */
// // child of a state's widget, that is referenced by an entity id.
// // e.g: .child(TextBox::new().id(child_entity_id).build(ctx)
// let mut child: WidgetContainer = ctx.get_widget(child_entity_id);
// // child of a state's widget that is referenced by an string id
// // e.g: .child(TextBox::new().id("text_box_id").build(ctx)
// let child: WidgetContainer = ctx.child("text_box_id");
// // property handling (components)
// // Gets an TextBoxCtx wrapper for the text box child.
// let mut text_box: TextBoxCtx = text_box(ctx.child("text_box_id"));
// // or as an alternative:
// let text_box: TextBoxCtx = TextBox::get(ctx.child("text_box_id"));
// // get child field attributes
// let text_len = text_box.text().len();
// // set child field attributes
// text_box.set_text("My new text");
// /*
// * Registry handling
// */
// // register service
// fn update(registry: &mut Registry, _: &mut Context) {
// registry.register("my_db_serve", MyDBServie::new());
// }
// // access service
// fn update(registry: &mut Registry, _: &mut Context) {
// let mut my_db_service: MyDBSerivce = registry.get_mut("my_db_service");
// }
// API Update: access properties of widgets in states
// Old style
// let text = *button(&mut ctx.widget()).text();
// let text = Button::get(&mut ctx.widget()).text();
// let text = *button(&mut ctx.widget()).clone_text();
// let text = Button::get(&mut ctx.widget()).clone_text();
// button(&mut ctx.widget()).text_mut().push_str("test");
// Button::get(&mut ctx.widget()).text_mut().push_str("test");
// button(&mut ctx.widget()).set_text(String16::from("test"));
// Button::get(&mut ctx.widget()).set_text(String16::from("test"));
// Current style
// let text = Button::text_clone(&ctx.widget());
// Button::text_mut(&mut ctx.widget()).push_str("test");
// Button::text_set(&mut ctx.widget(), String16::from("test"));
//
// TextBehaviour::offset_set(&mut ctx.widget(self.text_block), offset);
// or
// ctx.get_widget(self.text_block).set("offset", offset);
fn main() {}

View File

@@ -0,0 +1,800 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
// suppress creation of a new console window on window
#![windows_subsystem = "windows"]
use locales::t;
use orbtk::{
prelude::*,
theme_default::{THEME_DEFAULT, THEME_DEFAULT_COLORS_DARK, THEME_DEFAULT_FONTS},
theming::config::ThemeConfig,
};
use cfg_if::cfg_if;
use serde::Deserialize;
use std::env;
use std::time::SystemTime;
use tracing::{Level, info, trace};
use advotracker::{
data::{constants::*, structures::Email},
widgets::global_state::GlobalState,
//services::exports::send_ticketdata::sendticketdata,
widgets::policycheck::*,
widgets::policycheck_state::*,
widgets::main_view,
widgets::ticketdata::*,
};
#[cfg(target_os = "windows")]
use orbtk::theme_fluent::{THEME_FLUENT, THEME_FLUENT_COLORS_DARK, THEME_FLUENT_FONTS};
pub enum TicketdataAction {
ClearForm(),
SendForm(),
UpdatePolicyCode(String)
}
// 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_else(|_| "C".to_string());
lang = lang.substring(0,5).to_string(); // "de_DE.UTF-8" -> "de_DE"
info!("GUI-Language: preset to {:?}", lang);
// return the active language
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)),
))
}
}
}
// Main
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 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(trace)
//.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", process = ?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", 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();
// Preset localization and language from given environment.
// if no dictionary is set for the chosen default language
// the content of the text property will be drawn.
//let language = lang.substring(0,5); // "de_DE.UTF-8" -> "de_DE"
//info!("GUI-Language: preset to {:?}", language);
let localization = RonLocalization::create()
.language(&lang)
.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(800.0, 600.0)
//.min_width(460.0)
//.min_height(380.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(())
}
// View
widget!(MainView {
policycheck_view: PolicyCheck
});
impl Template for MainView {
fn template(self, _id: Entity, ctx: &mut BuildContext<'_>) -> Self {
let ticketdata_view = TicketdataView::new()
.build(ctx);
let policycheck_view = PolicycheckView::new()
.target(ticketdata_view.0)
.build(ctx);
self.name("MainView")
.child(
TabWidget::new()
.tab(ID_POLICY_CHECK_VIEW, policycheck_view)
.tab(ID_TICKET_DATA_VIEW, ticketdata_view)
.build(ctx),
)
}
}
// Macro that initializes the widget structures/variables for the policy check view
widget!(
/// Form to enter data of a ticket record
TicketdataView<TicketdataState> {
// language used inside the widget
lang: String,
// title used in the header
ticket_data_title: String,
// entity id that will receive the messages
target: u32
}
);
/// The template implementation of the ticket view
/// All GUI elements are styled using the "style" attribute referencing to a ron based css
impl Template for TicketdataView {
fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self {
let tenent_logo = Container::new()
.margin((16, 16, 0, 0))
.attach(Grid::column(0))
.v_align("center")
.child(
ImageWidget::new()
.image("assets/advotracker/hiedemann_logo.png")
.v_align("center")
.build(ctx),
)
.build(ctx);
let ticket_data_bottom_bar = Container::new()
.id(ID_TICKET_DATA_BOTTOM_BAR)
.style(STYLE_BOTTOM_BAR)
.attach(Grid::row(4))
.attach(Grid::column(1))
.attach(Grid::column_span(2))
.v_align("end")
.child(
Container::new()
.attach(Grid::column(1))
.h_align("end")
.v_align("end")
.child(
TextBlock::new()
.margin((0, 9, 48, 0))
.text("©Networkx GmbH")
.build(ctx)
)
.build(ctx),
)
.build(ctx);
let ticket_data_button_menu = Button::new()
.id(ID_TICKET_DATA_BUTTON_MENU)
.attach(Grid::row(0))
.attach(Grid::column(2))
.h_align("end")
.icon(material_icons_font::MD_MENU)
//.style("button_single_content")
.style(STYLE_BUTTON_MENU)
.build(ctx);
let ticket_data_form = Container::new()
.id(ID_TICKET_DATA_FORM)
.name(ID_TICKET_DATA_FORM)
.attach(Grid::row(2))
.attach(Grid::column(1))
.style("container_form")
.child(
Grid::new()
.id(ID_TICKET_DATA_GRID)
.name(ID_TICKET_DATA_GRID)
.columns(
Columns::create()
.push("auto") // Label
.push(16) // Delimiter
.push("*") // Data
.push(32) // Delimiter (2x margin)
)
.rows(
Rows::create()
.push("auto") // Row 0
.push(14) // Seperator
.push("auto") // Row 2
.push(14) // Seperator
.push("auto") // Row 4
.push(14) // Seperator
.push("auto") // Row 6
.push(14) // Seperator
.push("auto") // Row 8
.push(14) // Seperator
.push("auto") // Row 10
.push(14) // Seperator
.push("auto") // Row 12
.push(14) // Seperator
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_POLICY_CODE)
.attach(Grid::row(0))
.attach(Grid::column(0))
.text("Policy code")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_POLICY_CODE)
.attach(Grid::row(0))
.attach(Grid::column(2))
.text("")
.v_align("center")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_POLICY_HOLDER)
.attach(Grid::row(2))
.attach(Grid::column(0))
.text("Policy holder")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_POLICY_HOLDER)
.attach(Grid::row(2))
.attach(Grid::column(2))
.text("")
.water_mark("Name des Versicherungsnehmers")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_DEDUCTIBLE)
.attach(Grid::row(4))
.attach(Grid::column(0))
.text("Deductible")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_DEDUCTIBLE)
.attach(Grid::row(4))
.attach(Grid::column(2))
.text("")
.water_mark("im Beratungsgespräch erfragen")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_CALLBACK_NUMBER)
.attach(Grid::row(6))
.attach(Grid::column(0))
.text("Callback number")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_CALLBACK_NUMBER)
.attach(Grid::row(6))
.attach(Grid::column(2))
.text("")
.water_mark("wie zu erreichen")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_CALLBACK_DATE)
.attach(Grid::row(8))
.attach(Grid::column(0))
.text("Callback date")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_CALLBACK_DATE)
.attach(Grid::row(8))
.attach(Grid::column(2))
.text("")
.water_mark("Rückruf gewünscht um")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_HARM_TYPE)
.attach(Grid::row(10))
.attach(Grid::column(0))
.text("Harm type")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_HARM_TYPE)
.name(ID_TICKET_DATA_HARM_TYPE)
.attach(Grid::row(10))
.attach(Grid::column(2))
.text("")
.water_mark("Schadenstyp")
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_IVR_COMMENT)
.attach(Grid::row(12))
.attach(Grid::column(0))
.text("IVR comment")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.id(ID_TICKET_DATA_IVR_COMMENT)
.attach(Grid::row(12))
.attach(Grid::column(2))
.text("")
.water_mark("Kommentar zur Haftung, bzw. zur Deckung")
//.height(48.0)
.build(ctx),
)
.build(ctx),
)
.build(ctx);
let ticket_data_form_action = Container::new()
.id(ID_TICKET_DATA_ACTION_GRID)
.attach(Grid::row(3))
.attach(Grid::column(1))
//.style(STYLE_CONTAINER_ACTION)
.padding(14)
.h_align("center")
.child(
Stack::new()
//.style(STYLE_STACK_ACTION)
.orientation("horizontal")
.spacing(50)
.child(
Button::new()
.id(ID_TICKET_DATA_ACTION_BUTTON_CLEAR)
.style(STYLE_BUTTON_ACTION)
.text("Clear")
.on_click(move |states, _| {
states.send_message(TicketdataAction::ClearForm(), id);
false
})
.build(ctx),
)
.child(
Button::new()
.id(ID_TICKET_DATA_ACTION_BUTTON_SEND)
.style(STYLE_BUTTON_ACTION)
.text("Send")
//.visibility(Visibility::Collapsed)
.on_click(move |states, _entity| {
states.send_message(TicketdataAction::SendForm(), id);
false
})
.build(ctx),
)
.build(ctx),
)
.build(ctx);
// vector with valid mail recipients addresses (mail_to)
let items_mail_to = vec![
PROP_MAIL_TO_1,
PROP_MAIL_TO_2,
PROP_MAIL_TO_3,
PROP_MAIL_TO_4,
];
let items_mail_to_count = items_mail_to.len();
// vector with valid carbon copy recipients addresses (mail_to)
let items_mail_cc = vec![
PROP_MAIL_CC_1,
PROP_MAIL_CC_2,
];
let items_mail_cc_count = items_mail_cc.len();
let ticket_data_form_mail = Container::new()
.id(ID_TICKET_DATA_CONTAINER_MAIL)
.name(ID_TICKET_DATA_CONTAINER_MAIL)
.attach(Grid::row(1))
.attach(Grid::column(1))
.style(STYLE_CONTAINER_MAIL)
.child(
Grid::new()
.columns(
Columns::create()
.push(16) // Delimiter
.push("stretch") // Label
.push(16) // Delimiter
.push("auto") // MailAddress
.push("32") // Delimiter (2x margin)
)
.rows(
Rows::create()
.push("auto") // Row 0
.push(2) // Seperator
.push("auto") // Row 2
.push(2) // Seperator
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_MAIL_TO)
.attach(Grid::row(0))
.attach(Grid::column(1))
.style(STYLE_MAIL_LABEL)
.text("Recipient (To)")
.build(ctx),
)
.child(
/// WIP: get selected item
ComboBox::new()
.id(ID_TICKET_DATA_MAIL_TO)
.attach(Grid::row(0))
.attach(Grid::column(3))
.style(STYLE_MAIL_TO)
.count(items_mail_to_count)
.items_builder(move |ibc, index| {
let text_mail_to = TicketdataView::items_mail_to_ref(&ibc.get_widget(id))[index].clone();
TextBox::new()
.text(text_mail_to)
.v_align("center")
.build(ibc)
})
.selected_index(0)
.build(ctx),
)
.child(
TextBlock::new()
.id(ID_TICKET_DATA_LABEL_MAIL_CC)
.attach(Grid::row(2))
.attach(Grid::column(1))
.style(STYLE_MAIL_LABEL)
.text("Copie (CC)")
.build(ctx),
)
.child(
ComboBox::new()
.id(ID_TICKET_DATA_MAIL_CC)
.attach(Grid::row(2))
.attach(Grid::column(3))
.style(STYLE_MAIL_CC)
.count(items_mail_cc_count)
.items_builder(move |ibc, index| {
let text_mail_cc = TicketdataView::items_mail_cc_ref(&ibc.get_widget(id))[index].clone();
TextBox::new()
.text(text_mail_cc)
.v_align("center")
.build(ibc)
})
.selected_index(0)
.build(ctx),
)
.build(ctx),
)
.build(ctx);
let ticket_data_header_text = TextBlock::new()
.id(ID_TICKET_DATA_HEADER)
.attach(Grid::column(0))
.style(STYLE_HEADER_TEXT)
.text("Ticket Data")
.build(ctx);
let ticket_data_header_bar = Container::new()
.id(ID_TICKET_DATA_HEADER_BAR)
.attach(Grid::row(0))
.attach(Grid::column_span(3))
.style(STYLE_HEADER_BAR)
.child(tenent_logo)
.child(ticket_data_header_text)
.child(ticket_data_button_menu)
.build(ctx);
// Widget: Ticket data view
self.id(ID_TICKET_DATA_VIEW)
.name(ID_TICKET_DATA_VIEW)
.min_height(410.0)
.child(
Grid::new()
.id(ID_TICKET_DATA_GRID)
.columns(
Columns::create()
.push(50) // Left margin
.push("*") // Content
.push(50) // Right margin
)
.rows(
Rows::create()
.push("auto") // Header_Bar
.push("auto") // Mail_Form
.push("*") // Input_Form
.push("auto") // Action
.push("auto") // Bottom_Bar
)
.child(ticket_data_header_bar) // row 0
.child(ticket_data_form_mail) // row 1
.child(ticket_data_form) // row 2
.child(ticket_data_form_action) // row 3
.child(ticket_data_bottom_bar) // row 4
.build(ctx),
)
}
}
// State
impl GlobalState for TicketdataState {}
/// Method definitions, that react on any given state change inside the `Ticketdata` widget.
impl TicketdataState {
/// Clear the text property of all children of the given form entity
pub fn clear_form(entity: Entity, ctx: &mut Context<'_>) {
if let Some(count) = ctx.get_widget(entity).children_count() {
info!("Widget name: {:?}", ctx.get_widget(entity).get::<String>("name"));
info!("Widget id: {:?}", ctx.get_widget(entity).get::<String>("id"));
}
// identify the form by its id
if let form_entity = ctx.child(ID_TICKET_DATA_GRID).entity() {
info!("Form id: {:?}", ctx.get_widget(form_entity).get::<String>("id"));
info!("Form node name: {:?}", ctx.get_widget(form_entity).get::<String>("name"));
// Loop through children
if let Some(count) = ctx.get_widget(form_entity).children_count() {
for c in 1..=count {
info!("WIP clear entry of child {:?}", c);
//info!("WIP clear entry of child {:?}: {:?}", c, ctx.get_child(form_entity).get::<String>("name"));
}
}
}
}
pub fn send_form(entity: Entity, ctx: &mut Context<'_>, lang: &str) {
// type conversion (String -> u64)
//let policy_code = ctx.child(ID_TICKET_DATA_POLICY_CODE).get::<String>("text").unwrap().parse::<u64>().unwrap();
// WIP: get selected items ComboBox'es
//let mail_cc_index = *TicketdataView::selected_index_ref(&ctx.widget()) as usize;
//let mail_cc_selected = TicketdataView::mail_cc_ref(&ctx.widget())[mail_cc_index].clone();
// create Email structures
let email = Email {
// WIP: mail_to -> selected index auslesen
//mail_to: ctx.child(ID_TICKET_DATA_MAIL_TO).get::<String>("text").to_string(),
// WIP: mail_cc -> selected index auslesen
//mail_cc: ctx.child(ID_TICKET_DATA_MAIL_CC).get::<String>("text").to_string(),
mail_to: PROP_MAIL_TO_1.to_string(),
mail_cc: PROP_MAIL_CC_1.to_string(),
mail_bcc: PROP_MAIL_BCC_1.to_string(),
mail_from: PROP_MAIL_FROM.to_string(),
mail_reply: PROP_MAIL_REPLY.to_string(),
subject: PROP_MAIL_SUBJECT.to_string(),
policy_code: ctx.child(ID_TICKET_DATA_POLICY_CODE).get::<String>("text").to_string(),
policy_holder: ctx.child(ID_TICKET_DATA_POLICY_HOLDER).get::<String>("text").to_string(),
deductible: ctx.child(ID_TICKET_DATA_DEDUCTIBLE).get::<String>("text").to_string(),
callback_number: ctx.child(ID_TICKET_DATA_CALLBACK_NUMBER).get::<String>("text").to_string(),
callback_date: ctx.child(ID_TICKET_DATA_CALLBACK_DATE).get::<String>("text").to_string(),
harm_type: ctx.child(ID_TICKET_DATA_HARM_TYPE).get::<String>("text").to_string(),
ivr_comment: ctx.child(ID_TICKET_DATA_IVR_COMMENT).get::<String>("text").to_string(),
};
info!("WIP: Sending form to construct eMail to {:?}", email);
// send email via service
let _ = sendticketdata(&email, &lang);
}
}
/// Supported methods handled inside the `TicketState`
impl State for TicketdataState {
/// Initialize the state of widgets inside `TicketState`
fn init(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
let time_start= SystemTime::now();
trace!(target: "advotracker", ticketdata_state = "init", status = "started");
// Initialize required entities
self.button_menu = ctx
.entity_of_child(ID_TICKET_DATA_BUTTON_MENU)
.expect("TicketState.init: Can't find resource entity 'ID_TICKET_DATA_BUTTON_MENU'.");
self.target = Entity::from(ctx.widget().try_clone::<u32>("target")
.expect("TicketState.init: Can't find resource entity 'target'."));
// Get language from environment
self.lang = TicketdataState::get_lang();
let time_end = SystemTime::now();
let duration = time_end.duration_since(time_start);
trace!(target: "advotracker", ticketdata_state = "init", status = "finished", duration = ?duration);
}
fn messages(
&mut self,
mut messages: MessageReader,
_registry: &mut Registry,
ctx: &mut Context<'_>,
) {
for message in messages.read::<TicketdataAction>() {
match message {
TicketdataAction::ClearForm() => {
info!("message: {:?} recieved", message);
TicketdataState::clear_form(ctx.entity(), ctx);
}
TicketdataAction::SendForm() => {
info!("message: {:?} recieved", message);
TicketdataState::send_form(ctx.entity(), ctx, &self.lang);
}
_ => { println!("messages: action not implemented!"); }
}
}
for message in messages.read::<PolicycheckAction>() {
match message {
PolicycheckAction::UpdatePolicyCode => {
info!("Message received: 'PolicycheckAction::UpdatePolicyCode'");
TextBlock::text_set(&mut ctx.child(ID_TICKET_DATA_POLICY_CODE), policy_code);
}
_ => { println!("messages: action not implemented!"); }
}
}
}
fn update(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
let actions: Vec<TicketdataAction> = self.actions.drain(..).collect();
for action in actions {
match action {
TicketdataAction::ClearForm() => {
info!("update: send_message {:?}", action);
ctx.send_message(TicketdataAction::ClearForm(), self.target);
}
TicketdataAction::SendForm() => {
//ctx.send_message(TicketdataAction::SendForm(), self.ID_TICKETDATA_FORM);
info!("update: send_message {:?}", action);
}
_ => { println!("TicketdataAction: action not implemented!"); }
}
}
}
}
/// send ticket data via eMail
pub fn sendticketdata(email: &Email, lang: &str) -> Result<(), Box<dyn Error>> {
let mut res = t!("sendticketdata.export.started", lang);
let mut state = t!("state.started", lang);
trace!(target: "sendticketdata", process = ?res, state = ?state);
let ascii_body = String::new()
+ &"Vers.-Schein/Schadennummer".to_string() + &(email.policy_code) + &"\n"
+ &"Versicherungsnehmer: ".to_string() + &(email.policy_holder) + &"\n"
+ &"Selbstbehalt: ".to_string() + &(email.deductible) + &"\n"
+ &"Rückrufnummer: ".to_string()+ &(email.callback_number) + &"\n"
+ &"Erreichbarkeit: ".to_string() + &(email.callback_date) + &"\n"
+ &"Rechtsproblem: ".to_string() + &(email.harm_type) + &"\n"
+ &"Rechtsrat: ".to_string() + &(email.ivr_comment) + &"\n";
info!("email body: {:?}", ascii_body);
let message = Message::builder()
//.reply_to("Kanzlei Hiedemann <info@hiedemann.de>".parse().unwrap())
.to("Kanzlei Hiedemann <info@hiedemann.de>".parse().unwrap())
.cc(" <ralf.zerres@networkx.de>".parse().unwrap())
.reply_to((email.mail_reply).parse().unwrap())
//.to((email.mail_to).parse().unwrap())
//.cc((email.mail_cc).parse().unwrap())
//.bcc((email.mail_bcc).parse().unwrap())
.from((email.mail_from).parse().unwrap())
.subject(String::new()
+ &email.subject.to_string()
+ &" (".to_string()
+ &email.policy_code.to_string()
+ &")".to_string()
)
.multipart(
MultiPart::alternative() // This is composed of two parts.
.singlepart(
SinglePart::builder()
.header(header::ContentType(
"text/plain; charset=utf8".parse().unwrap(),
))
.body(String::from(ascii_body)),
)
)
.expect("failed to build email");
info!("message: {:?}", message);
trace!(target: "sendticketdata", email = ?email);
state = t!("state.finished", lang);
res = t!("sendticketdata.export.finished", lang);
trace!(target: "sendticketdata", process = ?res, state = ?state);
Ok(())
}

View File

@@ -0,0 +1,7 @@
# set the language variable used in test-runs
#test lang=de
TEST_LANG=en
#RUST_LOG=csv-test=trace
RUST_LOG=trace
USERNAME=ralf
DB_DRIVER=sqlite

View File

@@ -0,0 +1,23 @@
DION VERS POLLFNR
1 AS 1
1 AS 11
1 AS 123456789
9 AS 99
9 AS 999
1 AS 1511111111
1 AS 1511111119
1 AS 9000000001
1 AS 9000000002
1 AS 9999999991
1 AS 9999999992
1 AS 9999999999
3 AS 1515735920
3 AS 9999999991
3 AS 9999999992
3 AS 9999999999
9 AS 9927764110
9 AS 9927764251
9 AS 9927764426
9 AS 9999999991
9 AS 9999999992
9 AS 9999999999

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,409 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use chrono::{Local, DateTime};
use locales::t;
//use serde::{Deserialize, Serialize};
use serde::Deserialize;
use std::{
collections::HashMap,
env,
{error::Error, process},
//path::{Path, PathBuf},
};
use tracing::{debug, trace, Level};
use advotracker::data::structures::{PolicyCode, PolicyList, PolicyDataList, PolicyData};
// include modules
mod parse_args;
/// respect environment variables set in .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,
log: String,
}
/// export as csv format
/// https://docs.rs/csv/1.1.3/csv/cookbook/index.html
/// https://blog.burntsushi.net/csv/
fn export(p: &mut String, lang: &String) -> Result<u64, Box<dyn Error>> {
use std::fs::File;
use std::path::Path;
//use std::ffi::OsStr;
use std::io::prelude::*;
let mut res = t!("csv.export.started", lang);
let mut state = t!("state.started", lang);
let dt_start: DateTime<Local> = Local::now();
trace!(target: "csv-test",
process = ?res,
state = ?state,
date_start = ?dt_start.to_string());
// Note: slash syntax also works on Windows!
let path = Path::new(p);
// open the file descriptor
let mut file = File::create(path)?;
trace!(target: "csv-export", extension = ?path.extension(), file = ?file);
// Build the CSV writer and push selected records.
//for result in csv_reader.records() {
let mut count = 0;
file.write_all(b"Allianz DirectCall Protokoll!")?;
count += 1;
let dt_end: DateTime<Local> = Local::now();
let duration = dt_end.signed_duration_since(dt_start);
println!("Duration: {:#?}", duration);
trace!(target: "csv-test", record_count = ?count, duration = ?duration);
state = t!("state.finished", lang);
res = t!("csv.import.finished", lang);
trace!(target: "csv-test", process = ?res, state = ?state);
Ok(count)
}
/// import from csv format
/// https://docs.rs/csv/1.1.3/csv/cookbook/index.html
/// https://blog.burntsushi.net/csv/
fn import(p: &mut String, data_list: &mut PolicyDataList,
policy_numbers: &mut HashMap<u64, PolicyCode>, lang: &String)
-> Result<u64, Box<dyn Error>> {
use std::fs::File;
use std::path::Path;
use std::ffi::OsStr;
let mut res = t!("csv.import.started", lang);
let mut state = t!("state.started", lang);
let dt_start: DateTime<Local> = Local::now();
trace!(target: "csv-test",
process = ?res,
state = ?state,
date_start = ?dt_start.to_string());
// Note: slash syntax also workd on Windows!
let path = Path::new(p);
// must be a readable file
trace!(target: "csv-test", path = ?path);
assert_eq!(path.is_file(), true);
// only accept files with '.txt' extensions
let extension = path.extension();
assert_eq!(extension, Some(OsStr::new("txt")));
// open the file
let file = File::open(path)?;
trace!(target: "csv-test",
extension = ?extension,
file = ?file,
data_list = ?data_list.name);
// Build the CSV reader and iterate over each record.
let mut csv_reader = csv::ReaderBuilder::new()
.has_headers(true)
.delimiter(b' ')
.flexible(true)
//.comment(Some(b'#'))
//.from_reader(io::stdin());
//.from_path(path);
.from_reader(file);
{
// We nest this call in its own scope because of lifetimes.
let headers = csv_reader.headers()?;
trace!(target: "csv-test", header = ?headers);
}
// Deserialize the input data and push result to target vector
let mut count = 0;
for result in csv_reader.deserialize() {
// The iterator yields Result<StringRecord, Error>, so we check the
// error here.
let record: PolicyData = result?;
//println!("{:?}", record);
// WIP: write to redis backend
// append the policy_number to the HashMap
policy_numbers.insert(record.policy_number, record.policy_code);
// push record as new vector elements
data_list.push(record);
count +=1;
}
let dt_end: DateTime<Local> = Local::now();
let duration = dt_end.signed_duration_since(dt_start);
trace!(target: "csv-test", record_count = ?count, duration = ?duration);
state = t!("state.finished", lang);
res = t!("csv.import.finished", lang);
trace!(target: "csv-test",
process = ?res,
state = ?state,
date_stop = ?dt_end.to_string());
Ok(count)
}
#[allow(dead_code)]
/// validate a given policy number
/// result will return true or false
fn is_valid(policy_number: &u64, policy_list: &PolicyDataList,
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 state = t!("state.started", lang);
let dt_start: DateTime<Local> = Local::now();
trace!(target: "csv-test",
process = ?res,
state = ?state,
policy_number = ?policy_number,
policy_list = ?policy_list.name,
elements = ?policy_list.policy_data.len(),
date_start = ?dt_start.to_string());
//println!("Policy_number list: {:?}", policy_list.policy_data);
// WIP: testcode to collect policy_number via iterator
//println!("policy_number: {:?}", policy_list.policy_data[1].policy_number);
//println!("Policy_number list: {:?}", policy_list.policy_data);
// println!("policy_list: {:?} (with {:?} elements)",
// policy_list.name, policy_list.policy_data.len());
// policy_list.into_iter()
// .filter(|num| matches(w, w1))
// .clone
// .collect::<Vec<policy_number>>()
// let my_num = policy_list.policy_data.iter()
// .map(|policy_number| {
// policy_number
// })
// .collect::<Vec<_>>();
//println!("My policy_numbers: {:?}", my_num);
// let mut my_policy_list = [
// [ ("Jack", 20), ("Jane", 23), ("Jill", 18), ("John", 19), ],
// [ ("Bill", 17), ("Brenda", 16), ("Brad", 18), ("Barbara", 17), ]
// ];
// let teams_in_score_order = teams
// .iter_mut()
// .map(|team| {
// team.sort_by(|&a, &b| a.1.cmp(&b.1).reverse());
// team
// })
// .collect::<Vec<_>>();
//println!("Teams: {:?}", teams_in_score_order);
// if policy_list.policy_data.iter().any(|v| v == policy_number) {
// println!("{:?} contains {}", policy_list.name, policy_number);
// } else {
// println!("{:?} doesn't contain {}", policy_list, policy_number);
//}
// let test: Vec<_> = vec!["one", "two", "three"];
// let index: usize = test.iter().enumerate().find(|&r| r.1.to_string() == "two".to_string()).unwrap().0;
// println!("index: {:?} -> {:?}", index, test[index]);
//let index: usize = test.iter().enumerate().find(|&r| r.policy_number == "two".to_string()).unwrap().0;
let mut result = false;
match policy_numbers.get(&policy_number) {
Some(&policy_code) => {
let res = t!("policy.validation.success", lang);
println!("policy_number: {} ({:?})",
policy_number, policy_code);
result = true;
trace!(target: "csv-test",
policy_number = ?policy_number,
validation = ?res,
policy_code = ?policy_code);
},
_ => {
let res = t!("policy.validation.failed", lang);
//println!("Noop! Number isn't valid!");
println!("{:?}", res);
trace!(target: "csv-test",
policy_number = ?policy_number,
validation = ?res);
},
}
let dt_end: DateTime<Local> = Local::now();
let duration = dt_end.signed_duration_since(dt_start);
res = t!("policy.validation.finished", lang);
state = t!("state.finished", lang);
trace!(target: "csv-test",
process = ?res,
state = ?state,
date_stop = ?dt_end.to_string(),
duration = ?duration);
Ok(result)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
use dotenv::dotenv;
use parse_args::parse_args;
//use std::process;
//use std::sync::Arc;
use tracing_subscriber::fmt;
use viperus::Viperus;
//static DEFAULT_FILTER: &str = concat!(module_path!(), "=", "trace");
// 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, "csv-test");
let _enter = span.enter();
let subscriber = fmt::Subscriber::builder()
.with_env_filter("trace")
//.with_max_level(tracing::Level::DEBUG)
.finish();
tracing::subscriber::with_default(subscriber, || {
// get system environment
let mut lang = env::var("LANG").unwrap_or("en".to_string());
let mut res = t!("parse.environment", lang);
let mut state = t!("state.started", lang);
trace!(target: "csv-test", message = ?res, state = ?state);
//debug!(message = ?res, state = ?state);
trace!(target: "csv-test", environment = "system", lang = ?lang);
// 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) => { debug!(target: "csv-test", "{}", e); }
}
// how to handle unumplemented lang resources??
res = t!("parse.environment", lang);
trace!(target: "csv-test", environment = "envy", lang = ?lang);
state = t!("state.finished", lang);
trace!(target: "csv-test", message = ?res, state = ?state);
// initialize viperus structure
let mut v = Viperus::new();
// parse commandline arguments
res = t!("parse.arguments", lang);
state = t!("state.started", lang);
trace!(target: "csv-test", process = ?res, state = ?state);
let _ = parse_args(&mut v);
state = t!("state.finished", lang);
trace!(target: "csv-test", process = ?res, state = ?state);
//trace!(target: "Viperus", "Config results: {:?}", v);
// main tasks
res = t!("main.started", lang);
state = t!("state.started", lang);
trace!(target: "csv-test", process = ?res, state = ?state);
// create policy structures
let policy_list = PolicyList::new("Allianz Versicherungsnummen-Liste");
println!("Policy List {:?} ", policy_list.name);
let mut policy_data = PolicyDataList::new("Allianz-Import 20200628");
println!("Policy Data List {:?} ", policy_data.name);
let mut policy_numbers : HashMap<u64, PolicyCode> = HashMap::new();
let mut csv_import_path = v.get::<String>("import_file").unwrap();
match import(&mut csv_import_path, &mut policy_data,
&mut policy_numbers, &lang) {
Ok(count) => {
println!("Imported {:?} records", count);
}
Err(err) => {
println!("error running Csv-Test: {}", err);
process::exit(1);
}
}
// test if policy_number is_valid
// type conversion (viperus String -> u64)
let test_policy_number = v.get::<String>("test_policy_number").unwrap().parse::<u64>().unwrap();
trace!(target: "csv-test", test_policy_number = ?test_policy_number);
//match is_valid(&policy_number, &policy_data, &mut policy_numbers, &lang) {
// Ok(true) => {
// use Hashmap method 'get' to check if we have the given key
match policy_numbers.get(&test_policy_number) {
Some(&policy_code) => {
let res = t!("policy.validation.success", lang);
println!("{:?}", res);
println!("policy_number: {} ({:?})",
test_policy_number, policy_code);
}
_ => {
let res = t!("policy.validation.failed", lang);
println!("{:?}", res);
//println!("Nuup! Number isn't valid!");
},
}
// export policy code elements to csv-file
let mut csv_export_path = v.get::<String>("export_file").unwrap();
match export(&mut csv_export_path, &lang) {
Ok(count) => {
println!("Exported {:?} records", count);
}
Err(err) => {
println!("error running CSV-Export: {}", err);
process::exit(1);
}
}
state = t!("state.finished", lang);
res = t!("main.finished", lang);
trace!(target: "csv-test", process = ?res, state = ?state);
});
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

@@ -0,0 +1,216 @@
/*
* advotracker - Hotline tackingtool for Advocats
* 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 log::{debug, info, trace, warn};
use std::env;
use tracing::trace;
use viperus::Viperus;
/// Parse the commandline arguments and preset default values
/// Precedence: defaults -> config-file -> environment -> commandline
pub fn parse_args(v: &mut Viperus) -> Result<(), Box<dyn std::error::Error>> {
if cfg!(feature = "fmt-clap") {
trace!(target: "Viperus", "Viperus feature 'fmt-clap' enabled.");
println!("Using feature fmt-clap");
}
// preset default key/value pairs (lowest priority)
v.add_default("config_file", String::from("csv_import.ron"));
v.add_default("import_file", String::from("POLLFNR_WOECHENTLICH.txt"));
v.add_default("export_file", String::from(""));
v.add_default("test_policy_number", String::from("9999999992"));
v.add_default("to_email_address_file", String::from("Allianz RA-Hotline <smr-rahotline@allianz.de>"));
v.add_default("from_email_address_file", String::from("Allianz-Hotline RA-Hiedemann <azhotline@hiedemann.de>"));
//v.add_default("username", String::from("nctalkbot"));
//v.add_default("password", String::from("botpassword"));
v.add_default("verbose", 0);
// CLI arguments are defined inline
let matches = App::new("csv-test")
.name(crate_name!())
.version(crate_version!())
.author(crate_authors!())
.about(crate_description!())
.after_help("
Testprogramm: Allianz Online-Beratung Im/Export CSV-Daten
Direct-Call via IVR-System (Interactive Voice Response)
SMR Deckungssummen-Prüfung: 089 92529 60211
SMR Unerledigt: 089 92529 60222")
.template(
"\
{bin} v{version}
{about}
{all-args}
(C) 2020 {author}
{after-help}",
)
.arg(
Arg::with_name("configFile")
.short("c")
.long("configFile")
.value_name("FILE")
.help("Select a config file")
.default_value("csv_import.ron")
.takes_value(true),
)
.arg(
Arg::with_name("importFile")
.short("i")
.long("importFile")
.help("Select source file for the csv-import")
.default_value("POLLFNR_WOECHENTLICH.txt")
//.default_value("POLLFNR_MINI.txt")
.takes_value(true),
)
.arg(
Arg::with_name("exportFile")
.short("e")
.long("exportFile")
.help("Select target file for the csv-export")
.default_value("RA-Hiedemann_DirectCall.txt")
.takes_value(true),
)
.arg(
Arg::with_name("fromEmailAddress")
.short("f")
.long("fromEmailAddress")
.help("Select the sender email-address (From:)")
.default_value("Allianz-Hotline RA-Hiedemann <azhotline@hiedemann.de>")
.takes_value(true),
)
.arg(
Arg::with_name("toEmailAddress")
.short("t")
.long("toEmailAddress")
.help("Select the target email-address (To:)")
.default_value("Allianz RA-Hotline <smr-rahotline@allianz.de>")
.takes_value(true),
)
.arg(
Arg::with_name("testPolicyNumber")
.short("p")
.long("testPolicyNumber")
.help("Test validity of given policy number")
//.default_value("")
.takes_value(true),
)
// .arg(
// Arg::with_name("username")
// .short("u")
// .long("username")
// .help("Sets username")
// .takes_value(true),
// )
// .arg(
// Arg::with_name("password")
// .short("P")
// .long("password")
// .help("Sets password")
// .takes_value(true),
// )
.arg(
Arg::with_name("verbose")
.short("v")
.long("verbose")
.help("Sets verbosity level")
.multiple(true),
)
.get_matches();
if matches.occurrences_of("verbose") > 0 {
// clap is using i64, viperus i32
let n = matches.occurrences_of("verbose") as i32;
v.add("verbose", n);
}
// preset the prefix for relevant environment variables ("ADVOTRACKER_")
let mut env_prefix: String = crate_name!().to_uppercase();
env_prefix.push_str("_");
v.set_env_prefix(&env_prefix);
// respect dotenv environment (e.g for testing)
// -> overwrites the preset default values
println!(
"RUST_LOG={}",
dotenv::var("RUST_LOG").unwrap_or_else(|_| String::from("None"))
);
// enable caching and automatic update of environment values
v.cache(true);
v.automatic_env(true);
// load user selected call arguments
// -> overwrites values given via environment variables
v.load_clap(matches)?;
// bond the clap names to camel_case rust variable names
v.bond_clap("configFile", "config_file");
v.bond_clap("importFile", "import_file");
v.bond_clap("exportFile", "export_file");
v.bond_clap("toEmailAddress", "to_email_address");
v.bond_clap("fromEmailAddress", "from_email_address");
v.bond_clap("testPolicyNumber", "test_policy_number");
//v.bond_clap("username", "username");
//v.bond_clap("password", "password");
v.bond_clap("verbose", "verbose");
trace!("verbose {:?}", v.get::<i32>("verbose").unwrap());
if v.get::<i32>("verbose").unwrap() > 0 {
println!(
"config_file: {:?}",
v.get::<String>("config_file").unwrap_or_default()
);
println!(
"import_file: {:?}",
v.get::<String>("import_file").unwrap_or_default()
);
println!(
"export_file: {:?}",
v.get::<String>("export_file").unwrap_or_default()
);
println!(
"to_email_address: {:?}",
v.get::<String>("to_email_address").unwrap_or_default()
);
println!(
"from_email_address: {:?}",
v.get::<String>("from_email_address").unwrap_or_default()
);
println!(
"test_policy_number: {:?}",
v.get::<String>("test_policy_number").unwrap_or_default()
);
// println!(
// "username: {:?}",
// v.get::<String>("username").unwrap_or_default()
// );
// println!(
// "password: {:?}",
// v.get::<String>("password").unwrap_or_default()
// ); // only for testing now
println!(
"verbosity level: {:?}",
v.get::<i32>("verbose").unwrap_or_default()
);
}
if v.get::<i32>("verbose").unwrap() > 1 {
println!("\nEnvironment:");
for (key, value) in env::vars() {
println!("{}={}", key, value);
}
}
Ok(())
}

View File

@@ -0,0 +1,40 @@
use lettre::{
transport::smtp::authentication::Credentials,
Message, SmtpTransport, Transport,
};
fn main() {
let email = Message::builder()
.from("Info <info@networkx.de>".parse().unwrap())
.reply_to("Support <support@networkx.de>".parse().unwrap())
.to("Ralf Zerres <ralf.zerres@networkx.de>".parse().unwrap())
.subject("Eine advotracker eMail")
.body("Eine neue advotracker eMail!".to_string())
.unwrap();
// Create credential for remote authentication (username, password)
//let creds = Credentials::new("ralf.zerres@networkx.de".to_string(), "dekifjgh".to_string());
let creds = Credentials::new("ralf.zerres.de@gmail.com".to_string(), "20jacara03".to_string());
// Open a remote connection to relay server
//let mailer = SmtpTransport::relay("nwxex.networkx.de")
let mailer = SmtpTransport::relay("smtp.gmail.com")
.unwrap()
.credentials(creds)
.build();
// Open a remote connection to gmail using STARTTLS
// let mailer = SmtpTransport::starttls_relay("nwxex.networkx.de")
// .unwrap()
// .credentials(creds)
// .build();
// Open a local connection on port 25
//let mailer = SmtpTransport::unencrypted_localhost();
// Send the email
match mailer.send(&email) {
Ok(_) => println!("Email sent successfully!"),
Err(e) => panic!("Could not send email: {:?}", e),
}
}

View File

@@ -0,0 +1,124 @@
use std::collections::HashMap;
//use std::sync::mpsc;
use orbtk::prelude::*;
use orbtk::shell::WindowRequest;
static ID_CHECK_POLICY_NUMBER: &'static str = "ID_CHECK_POLICY_NUMBER";
static ID_PROGRESS_BAR: &'static str = "ID_PROGRESS_BAR";
enum Action {
ParsePolicyNumber
}
#[derive(Default, AsAny)]
struct MainViewState {
action: Option<Action>,
progress_bar: Entity,
text_box: Entity,
progress_counter: f64
//records: HashMap::<String, String>,
//record_counter: u64
}
impl State for MainViewState {
fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.text_box = ctx.entity_of_child(ID_CHECK_POLICY_NUMBER).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) {
// if there is an action, process it
if let Some(action) = &self.action {
match action {
Action::ParsePolicyNumber => {
let value_to_parse = ctx.get_widget(self.text_box).get::<String16>("text").clone();
self.parse_policy_number(value_to_parse, ctx);
}
}
// Reset action
self.action = None;
}
}
}
impl MainViewState {
fn action(&mut self, action: Action) {
self.action = Some(action);
}
fn parse_policy_number(&mut self, _value: String16, ctx: &mut Context) {
self.import_csv(ctx);
}
fn import_csv(&mut self, ctx: &mut Context) {
// code to import csv file into a hashmap
// will read in number_of_records = 100%
// progress_counter should be incremented, if
// read_in_loop will reach next 10% -> self.progress_counter += 0.1
// now fire an event to update the widget
// question: how to fire up the event inside import_csv function,
// without the need to mute "ID_CHECK_POLICY_NUMBER" ?
// given code just increments, if you change "ID_CHECK_POLICY_NUMBER"
self.progress_counter += 0.1;
self.update_progress(ctx);
}
fn update_progress(&self, ctx: &mut Context) {
// create a mpsc::Sender<WindowRequest> object
let sender = ctx.window_sender();
let mut pgbar = ctx.get_widget(self.progress_bar);
pgbar.set::<f64>("val", self.progress_counter);
// redraw screen if sender has changed
// only way to trigger a redraw: create an event
sender.send(WindowRequest::Redraw).unwrap()
}
}
widget!(MainView<MainViewState>);
impl Template for MainView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
self
.margin(32.0)
.child(
Stack::new()
.orientation("vertical")
.h_align("center")
.v_align("top")
.spacing(8.0)
.child(
TextBox::new()
.id(ID_CHECK_POLICY_NUMBER)
.water_mark("Mut value and type <Return>")
.on_activate(move |states, _entity| {
// you have to fire a new event to be able to get in the update() with access to Context
states.get_mut::<MainViewState>(id).action(Action::ParsePolicyNumber);
})
.build(ctx)
)
.child(
ProgressBar::new()
.id(ID_PROGRESS_BAR)
.build(ctx)
)
.build(ctx)
)
}
}
fn main() {
Application::new()
.window(|ctx| {
Window::new()
.title("incroment_progress_bar skeleton")
.position((100.0, 100.0))
.size(420.0, 730.0)
.resizeable(true)
.child(MainView::new().build(ctx))
.build(ctx)
})
.run();
}

View File

@@ -0,0 +1,23 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
// constants
pub static ID_RECEIVER: &str = "Receiver_Widget";
pub static ID_RECEIVER_CONTAINER: &str = "reciever_container";
pub static ID_RECEIVER_PROGRESS_BAR: &str = "receiver_progress_bar";
pub static ID_RECEIVER_TEXT_BLOCK: &str = "receiver_text_block";
//pub static ID_RECEIVER_MESSAGE_BOX: &str = "receiver_message_box";
pub static ID_RECEIVER_MESSAGE_BLOCK: &str = "receiver_message_block";
//pub static ID_RECEIVER_MESSAGE: &str = "receiver_message";
pub static ID_SENDER: &str = "Sender_Widget";
pub static ID_SENDER_CONTAINER: &str = "sender_container";
pub static ID_SENDER_GRID: &str = "sender_grid";
pub static ID_SENDER_BUTTON: &str = "sender_button";
pub static ID_SENDER_TEXT_BOX: &str = "sender_text_box";
pub static COLOR_BOMBAY: &str = "#adb3B8";

View File

@@ -0,0 +1,9 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
/// provides orbtk widgets constants
pub mod constants;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,37 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
use crate::receiver::receiver_state::{TestMessageAction, ReceiverState};
widget!(ReceiverView<ReceiverState>);
impl Template for ReceiverView {
fn template(self, _id: Entity, bc: &mut BuildContext) -> Self {
self.name("ReceiverView")
.child(
Stack::new()
.orientation("vertical")
.spacing(16)
.child(
ProgressBar::new()
.id("progress_bar")
.build(bc)
)
.child(
TextBox::new()
.id("message_box")
.h_align("center")
.text("message received. Box toggled!")
.visibility("hidden")
.build(bc)
)
.build(bc)
)
}
}

View File

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

View File

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

View File

@@ -0,0 +1,34 @@
/*
* OrbTK - The Orbital Widget Toolkit
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
use crate::sender::sender_state::{SenderAction, SenderState};
widget!(SenderView<SenderState> {
// the Entity of the widget that will receive the messages
target: u32
});
impl Template for SenderView {
fn template(self, id: Entity, bc: &mut BuildContext) -> Self {
self.name("SenderView")
.child(
Button::new()
.text("Click me to send a message!")
.v_align("center")
.h_align("center")
.on_click(move |states, _entity| {
states.get_mut::<SenderState>(id).send_message();
//states.send_message(SenderAction::UpdateProgress, id);
//ctx.send_message(TestMessageAction::ToggleMessageBox, id);
false
})
.build(bc)
)
}
}

View File

@@ -0,0 +1,143 @@
use orbtk::prelude::*;
//|---------------------------------------------------------------------------|
//|------------------------------SENDER---------------------------------------|
//|---------------------------------------------------------------------------|
// View
widget!(SenderWidget<SenderState> {
// the Entity of the widget that will receive the messages
target: u32
});
impl Template for SenderWidget {
fn template(self, id: Entity, bc: &mut BuildContext) -> Self {
self.name("SenderWidget")
.child(
Button::new()
.text("Click me to send a message!")
.v_align("center")
.h_align("center")
.on_click(move |states, _entity| {
states.get_mut::<SenderState>(id).send_message();
false
})
.build(bc)
)
}
}
// States
enum Action {
UpdateProgress(f64)
}
#[derive(Default, AsAny)]
struct SenderState {
actions: Vec<Action>,
target: Entity
}
impl SenderState {
fn send_message(&mut self) {
self.actions.push(Action::UpdateProgress(0.1));
}
}
impl State for SenderState {
fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.target = Entity::from(ctx.widget().try_clone::<u32>("target")
.expect("ERROR: SenderState::init(): target entity not found!"));
}
fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
let actions: Vec<Action> = self.actions.drain(..).collect();
for action in actions {
match action {
Action::UpdateProgress(amount) => {
ctx.send_message(Action::UpdateProgress(amount), self.target);
println!("Message sent!");
}
}
}
}
}
//|---------------------------------------------------------------------------|
//|------------------------------RECEIVER-------------------------------------|
//|---------------------------------------------------------------------------|
// View
widget!(ReceiverWidget<ReceiverState>);
impl Template for ReceiverWidget {
fn template(self, _id: Entity, bc: &mut BuildContext) -> Self {
self.name("ReceiverWidget")
.child(
ProgressBar::new()
.id("progress_bar")
.build(bc)
)
}
}
// States
#[derive(Default, AsAny)]
struct ReceiverState {
progress_bar: Entity
}
impl State for ReceiverState {
fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.progress_bar = ctx.entity_of_child("progress_bar").expect("Cannot find ProgressBar!");
}
fn messages(&mut self, mut messages: MessageReader, _registry: &mut Registry, ctx: &mut Context) {
for action in messages.read::<Action>() {
match action {
Action::UpdateProgress(amount) => {
println!("Message received");
let mut progress_bar = ctx.get_widget(self.progress_bar);
let current_progress = progress_bar.clone::<f64>("val");
progress_bar.set::<f64>("val", current_progress + amount);
}
}
}
}
}
//|---------------------------------------------------------------------------|
//|--------------------------------MAIN---------------------------------------|
//|---------------------------------------------------------------------------|
pub fn main() {
Application::new()
.window(|ctx| {
let receiver = ReceiverWidget::new().build(ctx);
let sender = SenderWidget::new()
// the entity of the target (receiver)
.target(receiver.0)
.build(ctx);
Window::new()
.title("Messages example")
.position((100.0, 100.0))
.resizeable(true)
.size(450.0, 500.0)
.child(
Stack::new()
.orientation("vertical")
.child(sender)
.child(receiver)
.build(ctx)
)
.build(ctx)
})
.run();
}

View File

@@ -0,0 +1,112 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use orbtk::prelude::*;
fn main() {
// use this only if you want to run it as web application.
orbtk::initialize();
Application::new()
.window(|ctx| {
Window::new()
.title("OrbTk - Pager test")
.position((100, 100))
.size(800, 600)
.resizeable(true)
.child(PagerTestView::new().build(ctx))
.build(ctx)
})
.run();
}
// Views
widget!(
PagerTestView<PagerTestState> {}
);
impl Template for PagerTestView {
fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self {
let pager = Pager::new()
.attach(Grid::row(1))
.child(TextBlock::new().text("Page 1").build(ctx))
.child(TextBlock::new().text("Page 2").build(ctx))
.child(TextBlock::new().text("Page 3").build(ctx))
.build(ctx);
let next_button = Button::new()
.style("button_single_content")
.icon(material_icons_font::MD_KEYBOARD_ARROW_RIGHT)
.h_align("end")
.attach(Grid::row(2))
.enabled(("next_enabled", pager))
.text("next")
.on_click(move |states, _| {
states.send_message(PagerAction::Next, pager);
true
})
.build(ctx);
let previous_button = Button::new()
.style("button_single_content")
.icon(material_icons_font::MD_KEYBOARD_ARROW_LEFT)
.h_align("start")
.attach(Grid::row(2))
.enabled(("previous_enabled", pager))
.text("previous")
.on_click(move |states, _| {
states.send_message(PagerAction::Previous, pager);
true
})
.build(ctx);
self.child(
Grid::new()
.margin(16)
.rows("32, *, 32")
.child(TextBlock::new().text("Pager Widget").build(ctx))
.child(pager)
.child(previous_button)
.child(next_button)
.build(ctx),
)
}
}
// States
static ID_PAGER_TEST: &str = "id_pager_test";
#[derive(Debug, Clone, Copy)]
pub enum PagerTestAction {}
/// Valid `structures` that are handled inside the state of the `PagerTest` widget.
#[derive(AsAny, Debug, Default)]
pub struct PagerTestState {
pager_test: Entity,
}
/// Method definitions, that react on any given state change inside the `Menu` widget.
impl PagerTestState {
fn init(&mut self, _registry: &mut Registry, ctx: &mut Context) {
self.pager_test = ctx.child(ID_PAGER_TEST).entity();
}
}
impl State for PagerTestState {
/// Handle messages for the `PagerTestState`
fn messages(
&mut self,
mut messages: MessageReader,
_registry: &mut Registry,
ctx: &mut Context<'_>,
) {
for message in messages.read::<PagerTestAction>() {
ctx.send_message(message, self.pager_test);
}
}
}

View File

@@ -0,0 +1,37 @@
//extern crate pdf_extract;
//extern crate lopdf;
use std::env;
use std::path::PathBuf;
use std::path;
use std::io::BufWriter;
use std::fs::File;
use pdf_extract::*;
use lopdf::*;
fn main() {
//let output_kind = "html";
//let output_kind = "txt";
//let output_kind = "svg";
let file = env::args().nth(1).unwrap();
let output_kind = env::args().nth(2).unwrap_or_else(|| "txt".to_owned());
println!("{}", file);
let path = path::Path::new(&file);
let filename = path.file_name().expect("expected a filename");
let mut output_file = PathBuf::new();
output_file.push(filename);
output_file.set_extension(&output_kind);
let mut output_file = BufWriter::new(File::create(output_file).expect("could not create output"));
let doc = Document::load(path).unwrap();
print_metadata(&doc);
let mut output: Box<dyn OutputDev> = match output_kind.as_ref() {
"txt" => Box::new(PlainTextOutput::new(&mut output_file as &mut dyn std::io::Write)),
"html" => Box::new(HTMLOutput::new(&mut output_file)),
"svg" => Box::new(SVGOutput::new(&mut output_file)),
_ => panic!(),
};
output_doc(&doc, output.as_mut());
}

View File

@@ -0,0 +1,65 @@
use ron::de::from_str;
use serde::Deserialize;
use std::collections::HashMap;
#[derive(Debug, Deserialize)]
struct Config {
boolean: bool,
float: f32,
map: HashMap<u8, char>,
nested: Nested,
option: Option<String>,
tuple: (u32, u32),
}
#[derive(Debug, Deserialize)]
struct Nested {
a: String,
b: char,
}
const CONFIG: &str = "
/*
* RON now has multi-line (C-style) block comments!
* They can be freely nested:
* /* This is a nested comment */
* If you just want a single-line comment,
* do it like here:
// Just put two slashes before the comment and the rest of the line
// can be used freely!
*/
// Note that block comments can not be started in a line comment
// (Putting a /* here will have no effect)
(
boolean: true,
float: 8.2,
map: {
1: '1',
2: '4',
3: '9',
4: '1',
5: '2',
6: '3',
},
nested: Nested(
a: \"Decode me!\",
b: 'z',
),
option: Some(\t \"Weird formatting!\" \n\n ),
tuple: (3 /*(2 + 1)*/, 7 /*(2 * 5 - 3)*/),
)";
fn main() {
let config: Config = match from_str(CONFIG) {
Ok(x) => x,
Err(e) => {
println!("Failed to load config: {}", e);
std::process::exit(1);
}
};
println!("Config: {:?}", &config);
}

View File

@@ -0,0 +1,50 @@
use ron::ser::{to_string_pretty, PrettyConfig};
use serde::Serialize;
use std::{collections::HashMap, iter::FromIterator};
#[derive(Serialize)]
struct Config {
float: (f32, f64),
tuple: TupleStruct,
map: HashMap<u8, char>,
nested: Nested,
var: Variant,
array: Vec<()>,
}
#[derive(Serialize)]
struct TupleStruct((), bool);
#[derive(Serialize)]
enum Variant {
A(u8, &'static str),
}
#[derive(Serialize)]
struct Nested {
a: String,
b: char,
}
fn main() {
let data = Config {
float: (2.18, -1.1),
tuple: TupleStruct((), false),
map: HashMap::from_iter(vec![(0, '1'), (1, '2'), (3, '5'), (8, '1')]),
nested: Nested {
a: "Hello from \"RON\"".to_string(),
b: 'b',
},
var: Variant::A(!0, ""),
array: vec![(); 3],
};
let pretty = PrettyConfig::new()
.with_depth_limit(2)
.with_separate_tuple_members(true)
.with_enumerate_arrays(true);
let s = to_string_pretty(&data, pretty).expect("Serialization failed");
println!("{}", s);
}

View File

@@ -0,0 +1,49 @@
use ron::ser::{to_string_pretty, PrettyConfig};
use serde::Serialize;
use std::{collections::HashMap, iter::FromIterator};
#[derive(Serialize)]
struct Config {
float: (f32, f64),
tuple: TupleStruct,
map: HashMap<u8, char>,
nested: Nested,
var: Variant,
array: Vec<()>,
}
#[derive(Serialize)]
struct TupleStruct((), bool);
#[derive(Serialize)]
enum Variant {
A(u8, &'static str),
}
#[derive(Serialize)]
struct Nested {
a: String,
b: char,
}
fn main() {
let data = Config {
float: (2.18, -1.1),
tuple: TupleStruct((), false),
map: HashMap::from_iter(vec![(0, '1'), (1, '2'), (3, '5'), (8, '1')]),
nested: Nested {
a: "Hello from \"RON\"".to_string(),
b: 'b',
},
var: Variant::A(!0, ""),
array: vec![(); 3],
};
let pretty = PrettyConfig::new()
.with_depth_limit(2)
.with_separate_tuple_members(true)
.with_enumerate_arrays(true);
let s = to_string_pretty(&data, pretty).expect("Serialization failed");
println!("{}", s);
}

View File

@@ -0,0 +1,45 @@
extern crate sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use std::time::Duration;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem
.window("rust-sdl2 demo: Video", 800, 600)
.position_centered()
.opengl()
.build()
.map_err(|e| e.to_string())?;
let mut canvas = window.into_canvas().build().map_err(|e| e.to_string())?;
canvas.set_draw_color(Color::RGB(255, 0, 0));
canvas.clear();
canvas.present();
let mut event_pump = sdl_context.event_pump()?;
'running: loop {
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
_ => {}
}
}
canvas.clear();
canvas.present();
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 30));
// The rest of the game loop goes here...
}
Ok(())
}

View File

@@ -0,0 +1,283 @@
use orbtk::prelude::*;
fn main() {
// use this only if you want to run it as web application.
orbtk::initialize();
Application::new()
.window(|ctx| {
Window::new()
.title("OrbTk - Test Size/Bounds")
.position((100.0, 100.0))
//.size(200.0, 150.0)
.size(800.0, 600.0)
//.min_size(160.0, 120.0)
//.max_size(240.0, 180.0)
.always_on_top(true)
.resizeable(true)
.child(MainView::new().build(ctx))
.build(ctx)
})
.run();
}
widget!(
MainView {
policy_number: String16
}
);
impl Template for MainView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
let ticket_data_header_bar = Container::new()
//.id(ID_TICKET_DATA_HEADER_CONTAINER)
//.style(STYLE_HEADER_BAR)
.attach(Grid::row(0))
.attach(Grid::column(1))
.attach(Grid::column_span(2))
.child(
Grid::new()
.child(
TextBlock::new()
//.id(ID_TICKET_DATA_HEADER_GRID)
.style("header")
.v_align("center")
.h_align("left")
.text("Ticket Data")
.build(ctx),
)
.build(ctx),
)
//.child(ticket_data_button_menu)
.build(ctx);
let ticket_data_form_row_0 = Stack::new()
.name("Row 0")
.build(ctx);
let ticket_data_form = Container::new()
//.id(ID_TICKET_DATA_FORM)
.name("TicketdataContainer")
.attach(Grid::row(2))
.attach(Grid::column(1))
//.margin(16)
.padding(14)
.border_brush("#dfebf5")
.border_radius(0)
.border_width(1)
.child(
Grid::new()
.columns(
Columns::create()
.push("auto") // Label
.push(14) // Delimiter
.push("*") // Data
.push(4) // Delimiter
)
.rows(
Rows::create()
.push("auto") // Row 0
.push(14) // Seperator
.push("auto") // Row 2
.push(14) // Seperator
.push("auto") // Row 4
.push(14) // Seperator
.push("auto") // Row 6
.push(14) // Seperator
.push("auto") // Row 8
.push(14) // Seperator
.push("auto") // Row 10
.push(14) // Seperator
.push("auto") // Row 12
)
//.child(ticket_data_form_row_0)
//.child(ticket_data_form_row_1)
//.child(ticket_data_form_row_2)
//.build(ctx),
.child(
TextBlock::new()
.attach(Grid::row(0))
.attach(Grid::column(0))
.name("TextLabel1")
.text("Policy number")
.h_align("end")
.v_align("center")
//.foreground("#516475")
.build(ctx),
)
.child(
TextBlock::new()
.attach(Grid::row(0))
.attach(Grid::column(2))
.name("TextBox1")
.text("9999999990")
.v_align("center")
.build(ctx),
)
.child(
TextBlock::new()
.attach(Grid::row(2))
.attach(Grid::column(0))
.name("TextLabel2")
.text("Policy holder")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.attach(Grid::row(2))
.attach(Grid::column(2))
.name("TextBox2")
.text("Name des Versicherungsnehmers")
.build(ctx),
)
.child(
TextBlock::new()
.attach(Grid::row(4))
.attach(Grid::column(0))
.name("TextLabel3")
.text("Deductible")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.attach(Grid::row(4))
.attach(Grid::column(2))
.name("TextBox3")
.text("im Beratungsgespräch erfragen")
.build(ctx),
)
.child(
TextBlock::new()
.attach(Grid::row(6))
.attach(Grid::column(0))
.name("TextLabel4")
.text("Callback number")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.attach(Grid::row(6))
.attach(Grid::column(2))
.name("TextBox4")
.water_mark("wie zu erreichen")
.build(ctx),
)
.child(
TextBlock::new()
.attach(Grid::row(8))
.attach(Grid::column(0))
.name("TextLabel5")
.text("Callback date")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.attach(Grid::row(8))
.attach(Grid::column(2))
.name("TextBox5")
.water_mark("Rückruf gewünscht um")
.build(ctx),
)
.child(
TextBlock::new()
.attach(Grid::row(10))
.attach(Grid::column(0))
.name("TextLabel6")
.water_mark("Harm type")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.attach(Grid::row(10))
.attach(Grid::column(2))
.name("TextBox6")
.water_mark("Rechtsproblem/Schadenstyp")
.build(ctx),
)
.child(
TextBlock::new()
.attach(Grid::row(12))
.attach(Grid::column(0))
.name("TextLabel7")
.text("IVR comment")
.h_align("end")
.v_align("center")
.build(ctx),
)
.child(
TextBox::new()
.attach(Grid::row(12))
.attach(Grid::column(2))
.name("TextBox7")
.water_mark("Rechtsrat / Kommentar zu Haftungs, bzw. Deckung")
.build(ctx),
)
.build(ctx),
)
.build(ctx);
let ticket_data_action = Stack::new()
//.id(ID_TICKET_DATA_STACK)
.attach(Grid::row(3))
.attach(Grid::column(1))
.h_align("end")
.v_align("top")
.orientation("horizontal")
.visibility(Visibility::Collapsed)
//.spacing("4")
.child(
Button::new()
.margin(14)
.name("TicketdataContainer")
.text("Senden")
.icon(material_icons_font::MD_MAIL)
.on_click(move |_ctx, _| {
println!("WIP: send mail");
// ctx.get_mut::<MenuState>(id)
// .set_action(MenuAction::CreateMenu(ID_MENU_STACK));
true
})
.build(ctx),
)
.build(ctx);
// Starter page: Ticket Data Widget
self.name("TicketdataView")
.child(
Grid::new()
//.id(ID_TICKET_DATA_WIDGET)
.columns(
Columns::create()
.push(50)
.push("*")
.push(50)
)
.rows(
Rows::create()
.push("auto") // Header
.push(28) // Seperator
.push("*") // InputForm
.push("auto") // ActionSend
//.push("auto") // Bottom )
)
.child(ticket_data_header_bar) // row 0
.child(ticket_data_form) // row 2
.child(ticket_data_action) // row 3
.build(ctx),
)
}
}

View File

@@ -0,0 +1 @@
advotracker ICON "./assets/icons/advotracker/advotracker.ico"

View File

@@ -0,0 +1,206 @@
use orbtk::prelude::*;
// fn get_theme() -> ThemeValue {
// //ThemeValue::create_from_css(LIGHT_THEME_EXTENSION_CSS)
// ThemeValue::create_from_css(DEFAULT_THEME_CSS)
// .extension_css(WIDGET_EXT)
// .build()
// }
#[derive(Debug, Copy, Clone)]
enum Action {
EntryActivated(Entity),
EntryChanged(Entity)
}
#[derive(AsAny)]
pub struct MainViewState {
action: Option<Action>,
}
impl Default for MainViewState {
fn default() -> Self {
MainViewState { action: None }
}
}
impl MainViewState {
fn action(&mut self, action: impl Into<Option<Action>>) {
self.action = action.into();
}
}
impl State for MainViewState {
fn update(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
if let Some(action) = self.action {
match action {
// Action::ClearText => {
// ctx.widget().set("policynumber", String16::from(""));
// }
// Action::ValueOk => {
// //let mut text_box = TextBox::get(ctx.get_widget(entity));
// //let text = text_box.text_mut();
// //ctx.widget().set("policynumber", background("#4d4c4c"));
// }
// Action::ValueNone => {
// //let mut text_box = TextBox::get(ctx.get_widget(entity));
// //let text = text_box.text_mut();
// //ctx.widget().set("policynumber", background("#5b0f22"));
//}
Action::EntryActivated(entity) => {
//let text = ctx.get_widget(entity).clone::<String>("text");
let widget = ctx.get_widget(entity);
let text = widget.get::<String>("text");
println!("got value policynumber: {}", text);
}
Action::EntryChanged(entity) => {
let widget = ctx.get_widget(entity);
let text = widget.get::<String>("text");
println!("entry changed: {}", text);
}
}
self.action = None;
}
}
}
fn create_header(ctx: &mut BuildContext, text: &str) -> Entity {
TextBlock::new()
.text(text)
.style("header")
.build(ctx)
}
widget!(
MainView<MainViewState> {
sum_policynumbers: usize,
policynumber: String16,
result: String16
}
);
impl Template for MainView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
self.name("MainView").child(
Grid::new()
.background("#fafafa")
.columns(
Columns::create()
.push(150.0)
.push("*")
.push(150.0)
.build(),
)
.rows(
Rows::create()
.push("*")
.push("*")
.build(),
)
.child(
Grid::new()
//.element("policyholder_check")
.margin((4.0, 24.0, 24.0, 4.0))
.min_width(180.0)
.min_height(80.0)
.attach(Grid::column(1))
.attach(Grid::row(0))
.child(
Stack::new()
.spacing(8.0)
.orientation("vertical")
.h_align("center")
//.child(create_header(ctx, "Validation number policyholder"))
.child(create_header(ctx, "Validierung Versicherungsnummer"))
.child(
TextBox::new()
.foreground("#9dafbf")
.background("#fafafa")
.border_brush("#5b0f22")
.border_width(5)
.border_radius(15)
//.name("policynumber")
.focused(true)
.water_mark("Versicherungs-Nr...")
.text(("policynumber", id))
.font_size(24.0)
.h_align("stretch")
.on_activate(move |ctx, entity| {
state(id, ctx).action(Action::EntryActivated(entity));
})
.on_changed("text", move |ctx, entity| {
state(id, ctx).action(Action::EntryChanged(entity));
})
.build(ctx),
)
.child(
TextBlock::new()
//.element("text-block")
.id("result")
.min_width(80.0)
.max_width(180.0)
//.text("Result:")
.text("Ergebnis:")
.build(ctx),
)
.build(ctx),
)
.build(ctx)
)
.child(
Grid::new()
//.class("logo_customer")
.margin((9.0, 16.0, 16.0, 9.0))
.attach(Grid::column(0))
.attach(Grid::row(1))
.v_align("end")
.child(
ImageWidget::new()
.image("assets/images/customer_logo.png")
.build(ctx),
)
.build(ctx),
)
.child(
Grid::new()
//.class("logo_vendor")
.margin((9.0, 16.0, 16.0, 9.0))
.attach(Grid::column(2))
.attach(Grid::row(1))
.v_align("end")
.child(
ImageWidget::new()
.image("assets/images/networkx_logo.png")
.build(ctx),
)
.build(ctx),
)
.build(ctx),
) // MainView
}
}
fn main() {
Application::new()
.window(|ctx| {
Window::new()
//.title("OrbTk - Policyholder checker example")
.name("MainWindow")
.title("AdvoTracker - Versicherungsnummern")
.position((-500.0, -100.0))
.size(480.0, 260.0)
.min_width(460.0)
.min_height(180.0)
.resizeable(true)
//.theme(get_theme())
.child(MainView::new().build(ctx))
.build(ctx)
})
.run();
}
// helper to request MainViewState
fn state<'a>(id: Entity, states: &'a mut StatesContext) -> &'a mut MainViewState {
states.get_mut(id)
}

View File

@@ -0,0 +1 @@
../../resources

View File

@@ -0,0 +1,169 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
// Component Values (Properties)
pub static PROP_ADVOTRACKER: &str = "advotracker";
pub static PROP_MAIL_CC_1: &str = "service@hiedemann.de";
pub static PROP_MAIL_CC_2: &str = "info@hiedemann.de";
pub static PROP_MAIL_BCC_1: &str = "Networkx Support <support@networkx.de>";
pub static PROP_MAIL_BCC_2: &str = "knoche@hiedemann.de";
pub static PROP_MAIL_FROM: &str = "Kanzlei Hiedemann <service@hiedemann.de>";
pub static PROP_MAIL_REPLY: &str = "Kanzlei Hiedemann <service@hiedemann.de>";
pub static PROP_MAIL_SUBJECT: &str = "ZMB Allianz - neues Mandat";
pub static PROP_MAIL_TO_1: &str = "allianz@ponschab-partner.com";
pub static PROP_MAIL_TO_2: &str = "kontakt@chevalier.law";
pub static PROP_MAIL_TO_3: &str = "kontakt@metamedlaw.de";
pub static PROP_MAIL_TO_4: &str = "sekretariat@m2-mediation.de";
pub static PROP_MAIL_TO_5: &str = "ralf.zerres@networkx.de";
pub static PROP_POLICY_CHECK: &str = "policy_check";
pub static PROP_POLICY_PROGRESS_COUNT: &str = "policy_progress_count";
pub static PROP_POLICY_DATA_LIST: &str = "policy_data_list";
pub static PROP_POLICY_DATA_COUNT: &str = "policy_data_count";
pub static PROP_POLICY_LIST: &str = "policy_list";
pub static PROP_POLICY_LIST_COUNT: &str = "policy_list_count";
// Styles (RON based theme system)
pub static STYLE_BOTTOM_BAR: &str = "bottom_bar";
pub static STYLE_BUTTON_MENU: &str = "button_menu";
pub static STYLE_BUTTON_ACTION: &str = "button_action";
pub static STYLE_CONTAINER_ACTION: &str = "container_action";
pub static STYLE_CONTAINER_MAIL: &str = "container_mail";
pub static STYLE_HEADER_BAR: &str = "header_bar";
pub static STYLE_HEADER_TEXT: &str = "header_text";
pub static STYLE_SEPARATOR: &str = "separator";
pub static STYLE_MAIL_LABEL: &str = "mail_label";
pub static STYLE_MAIL_TO: &str = "mail_to";
pub static STYLE_MAIL_CC: &str = "mail_cc";
pub static STYLE_MENU: &str = "menu";
pub static STYLE_STACK_ACTION: &str = "stack_action";
pub static STYLE_STACK_MENU: &str = "stack_menu";
// Widget IDs (DCES: Entity[id] => [Component1, .. , Component<n>] -> data or state)
pub static ID_CONFIGURATION_VIEW: &str = "Configuration";
pub static ID_CONFIGURATION_FORM: &str = "configuration_form";
pub static ID_CONFIGURATION_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_VIEW: &str = "Localization";
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_MAIN_GRID: &str = "main_grid";
pub static ID_MAIN_TABWIDGET: &str = "main_tabwidget";
pub static ID_MAIN_BUTTON_MENU: &str = "main_button_menu";
pub static ID_MENU_VIEW: &str = "menu_view";
pub static ID_MENU_POPUP: &str = "menu_popup";
pub static ID_MENU_STACK: &str = "menu_stack";
pub static ID_MENU_BOTTOM_BAR: &str = "menu_bottom_bar";
pub static ID_MENU_BUTTON: &str = "menu_button";
pub static ID_MENU_BUTTON_MENU: &str = "menu_button_menu";
pub static ID_MENU_GRID: &str = "menu_grid";
pub static ID_MENU_HEADER: &str = "menu_header";
pub static ID_MENU_HEADER_BAR: &str = "menu_header_bar";
pub static ID_MENU_LABEL_ACCOUNT: &str = "menu_label_account";
pub static ID_MENU_LABEL_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_VIEW: &str = "policy_check_view";
pub static ID_POLICY_CHECK_ACTION_BUTTON_CLEAR: &str = "policy_check_action_button_clear";
pub static ID_POLICY_CHECK_ACTION_BUTTON_CREATE: &str = "policy_check_action_button_create";
pub static ID_POLICY_CHECK_ACTION_GRID: &str = "policy_check_action_grid";
pub static ID_POLICY_CHECK_ACTION_STACK: &str = "policy_check_action_stack";
pub static ID_POLICY_CHECK_BOTTOM_BAR: &str = "policy_check_bottom_bar";
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_FORM: &str = "policy_check_form";
pub static ID_POLICY_CHECK_HEADER: &str = "policy_check_header";
pub static ID_POLICY_CHECK_HEADER_BAR: &str = "policy_check_header_bar";
pub static ID_POLICY_CHECK_HINT: &str = "policy_check_hint";
pub static ID_POLICY_CHECK_ITEMS_WIDGET: &str = "policy_check_items_widget";
pub static ID_POLICY_CHECK_LABEL_HINT: &str = "policy_check_label_hint";
pub static ID_POLICY_CHECK_LABEL_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_CODE: &str = "policy_check_policy_code";
pub static ID_POLICY_CHECK_POLICY_NUMBER: &str = "policy_number";
pub static ID_POLICY_CHECK_POPUP_PROGRESS: &str = "policy_check_popup_progress";
pub static ID_POLICY_CHECK_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";
pub static ID_TICKET_DATA_ACTION_BUTTON_CLEAR: &str = "ticket_data_action_button_clear";
pub static ID_TICKET_DATA_ACTION_BUTTON_SEND: &str = "ticket_data_action_button_send";
pub static ID_TICKET_DATA_ACTION_GRID: &str = "ticket_data_action_grid";
pub static ID_TICKET_DATA_ACTION_STACK: &str = "ticket_data_action_stack";
pub static ID_TICKET_DATA_BOTTOM_BAR: &str = "ticket_data_bottom_bar";
pub static ID_TICKET_DATA_BUTTON_MENU: &str = "ticket_data_button_menu";
pub static ID_TICKET_DATA_BUTTON_RESULT: &str = "ticket_data_button_result";
pub static ID_TICKET_DATA_CALLBACK_DATE: &str = "ticket_data_label_callback_date";
pub static ID_TICKET_DATA_CALLBACK_NUMBER: &str = "ticket_data_callback_number";
pub static ID_TICKET_DATA_COMBO_BOX_MAIL_CC: &str = "ticket_data_combo_box_mail_cc";
pub static ID_TICKET_DATA_COMBO_BOX_MAIL_TO: &str = "ticket_data_combo_box_mail_to";
pub static ID_TICKET_DATA_CONTAINER_MAIL: &str = "ticket_data_container_mail";
pub static ID_TICKET_DATA_COUNT_BLOCK: &str = "ticket_data_count_block";
pub static ID_TICKET_DATA_DEDUCTIBLE: &str = "ticket_data_deductible";
pub static ID_TICKET_DATA_FORM: &str = "ticket_data_form";
pub static ID_TICKET_DATA_FORM_GRID: &str = "ticket_data_form_grid";
pub static ID_TICKET_DATA_GRID: &str = "ticket_data_grid";
pub static ID_TICKET_DATA_GRID_MAIL: &str = "ticket_data_grid_mail";
pub static ID_TICKET_DATA_HARM_TYPE: &str = "ticket_data_harm_type";
pub static ID_TICKET_DATA_HEADER_BAR: &str = "ticket_data_header_bar";
pub static ID_TICKET_DATA_HEADER: &str = "ticket_data_header";
pub static ID_TICKET_DATA_HINT: &str = "ticket_data_hint";
pub static ID_TICKET_DATA_ITEMS_WIDGET: &str = "ticket_data_items_widget";
pub static ID_TICKET_DATA_IVR_COMMENT: &str = "ticket_data_ivr_comment";
pub static ID_TICKET_DATA_LABEL_CALLBACK_DATE: &str = "ticket_data_label_callback_data";
pub static ID_TICKET_DATA_LABEL_CALLBACK_NUMBER: &str = "ticket_data_label_callback_number";
pub static ID_TICKET_DATA_LABEL_DEDUCTIBLE: &str = "ticket_data_label_deductible";
pub static ID_TICKET_DATA_LABEL_HARM_TYPE: &str = "ticket_data_label_harm_type";
pub static ID_TICKET_DATA_LABEL_HINT: &str = "ticket_data_label_hint";
pub static ID_TICKET_DATA_LABEL_IVR_COMMENT: &str = "ticket_data_label_ivr_comment";
pub static ID_TICKET_DATA_LABEL_MAIL_CC: &str = "ticket_data_label_mail_cc";
pub static ID_TICKET_DATA_LABEL_MAIL_TO: &str = "ticket_data_label_mail_to";
pub static ID_TICKET_DATA_LABEL_MENU: &str = "ticket_data_label_menu";
pub static ID_TICKET_DATA_LABEL_POLICY_CODE: &str = "ticket_data_label_policy_code";
pub static ID_TICKET_DATA_LABEL_POLICY_HOLDER: &str = "ticket_data_label_policy_holder";
pub static ID_TICKET_DATA_LOGO_BAR: &str = "ticket_data_logo_bar";
pub static ID_TICKET_DATA_MAIL_CC: &str = "ticket_data_mail_cc";
pub static ID_TICKET_DATA_MAIL_TO: &str = "ticket_data_mail_to";
pub static ID_TICKET_DATA_POLICY_CODE: &str = "ticket_data_policy_code";
pub static ID_TICKET_DATA_POLICY_HOLDER: &str = "ticket_data_policy_holder";
pub static ID_TICKET_DATA_RESULT: &str = "ticket_data_result";
pub static ID_TICKET_DATA_VIEW: &str = "ticket_data_view";
pub static ID_TICKET_DATA_WIDGET: &str = "ticket_data_widget";

View File

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

View File

@@ -0,0 +1,364 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
use chrono::NaiveDateTime;
use orbtk::prelude::*;
use serde::{Deserialize, Serialize};
/// An enumeration of valid policy codes.
/// right now, only "AS" is used.
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
pub enum PolicyCode {
/// Allianz Sachversicherung
AS
}
impl Default for PolicyCode {
fn default() -> Self { PolicyCode::AS }
}
/// Classifier of the Allinaz DirectCall communication type.
pub enum CommunicationType {
/// Anhörung
A,
/// Bußgeldbescheid
BU,
/// Gdb
Gdb,
/// Geburt
GE,
/// Hochzeit
HO,
/// Kündigung
KD,
/// Kaufvertrag
KV,
/// Lohn
LO,
/// Nachbar
NA,
/// Rente
RE,
/// Unfallflucht
UF,
/// Unterhalt
UH,
/// Unfall
UN,
/// Vodafone
VF,
/// Vermieter
VM,
/// Verwaltungsrecht
VW,
/// Zeugins
ZE,
/// Typ is unspecified
XX
}
impl Default for CommunicationType {
fn default() -> Self { CommunicationType::XX }
}
/// Status of a given policy data element.
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub enum Status {
/// Active -> the policy is active an supported
Active,
/// Inactive -> the policy is inactive or resigned
Inactive
}
impl Default for Status {
fn default() -> Self { Status::Active }
}
/// A communication type describes possible classifications of customer calls.
/// If the type isn't selected, the default will be 'unclassified -> XX'.
#[derive(Default, Deserialize, Serialize)]
pub struct CommunicationData {
/// pub communication_type: CommunicationType,
pub communication_type: String,
/// A literal name describing the selected communication type
pub communication_name: String
}
/// CSV Export
/// The structure elements are required for an export to a comma seperated text list.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct CsvExportRecord {
/// Versicherungsschein Code
pub policy_code: String,
/// Versicherungsscheinnummer (10-stellig, numerisch)
pub policy_number: u64,
/// Anrufer: "Vorname, Nachname"
pub policy_holder: String,
/// Sachverhalt: "Kurzschilderung"
pub facts: String,
/// Schadensart: "harm_name (harm_id)"
pub harm_type: String,
/// communication_type => Kommunikationszeichen: "(communication_name)"
pub communication_name: String,
/// ra_hotline => RA_Hotline: Kanzlei Laqua, Kanzlei Buschbell, Kanzlei DAH, Kanzlei Hiedemann
pub ra_hotline: String, // const "Kanzlei Hiedemann",
/// ivr_comment => Haftungs-/Deckungskommentar; #IVR (ggf. ergänzt um das Beratungsergebnis)
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.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct HarmData {
/// Liste der Schadensdaten
pub harm_data: Vec<HarmType>,
/// Status der Schadenliste
//pub name: String,
pub selected: bool
}
/// Harm types are destincted by a type code.
/// The type code represents the unique harm identifier, bound with a literal name.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct HarmType {
/// Kennzeichen des Schadenstyps
// Schadenersatz-RS im Verkehrsbereich (RS112)
// Ordnungswidrigkeits-RS im Verkehrsbereich (RS122)
// Straf-RS im Verkehrsbereich (RS121)
// Vertrags-RS im Verkehrsbereich (RS118)
// Vertrags-RS im Privatbereich (RS218)
// Arbeits-RS im Berufsbereich (RS315)
// WuG-RS im Privatbereich (RS220)
// Sozialgerichts-RS im Privatbereich (RS216)
// Rechtsschutz im Familien- und Erbrecht (RS217)
// Wagnis nicht versicherbar / versichert (RS999)
pub harm_type: String,
/// Beschreibung des Schadenstyps
pub harm_name: String,
}
/// Structure used to verify a policy data element.
#[derive(Default, Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct PolicyCheck {
/// Versicherungsschein-Prüfnummer
pub policy_check_number: String,
/// Referenz zum Versicherungsschein-Typ
pub dion: u8,
/// Referenz zum Versicherungsschein-Typ
pub policy_code: PolicyCode,
/// Referenz zur Versicherungsschein-Nummer
pub policy_number: u64,
/// Validitätsergebnis
pub policy_number_status: Status
}
impl PolicyCheck {}
/// Structure collecting policy data elements
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct PolicyList {
/// Bescheibung der Versicherungsdatenliste
pub name: String,
/// Listenelemente der Versicherungsdatendaten
pub policy_list: Vec<PolicyDataList>,
}
/// implements helper methods, that manage lists of policy data collections
impl PolicyList {
/// Index auf Versicherungsliste zurückgeben (unveränderbar)
pub fn get(&self, index: usize) -> Option<&PolicyDataList> {
self.policy_list.get(index)
}
/// Index auf Versicherungsliste zurückgeben (veränderbar)
pub fn get_mut(&mut self, index: usize) -> Option<&mut PolicyDataList> {
self.policy_list.get_mut(index)
}
/// Neuer Eintrag am Anfang der Liste einfügen.
pub fn insert_front(&mut self, policy_list: PolicyDataList) {
self.policy_list.insert(0, policy_list);
}
/// Prüfung ob Versicherungsliste keine Elemente enthält.
pub fn is_empty(&self) -> bool {
self.policy_list.is_empty()
}
/// Berechnet die Anzahl der Versicherungslisten Elemente.
pub fn len(&self) -> usize {
self.policy_list.len()
}
/// Neuen Versicherungslisten-Namen erzeugen
pub fn new(name: impl Into<String>) -> Self {
PolicyList {
name: name.into(),
..Default::default()
}
}
/// Element der Versicherungsliste anfügen
pub fn push(&mut self, policy_list: PolicyDataList) {
self.policy_list.push(policy_list);
}
/// Element der Versicherungsliste löschen
pub fn remove(&mut self, index: usize) -> PolicyDataList {
self.policy_list.remove(index)
}
}
/// Structure collects policy data elements.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct PolicyDataList {
/// Verfalldatum des Versicherungslisten Elements
pub date_valid_until: Option<NaiveDateTime>,
/// Elemente des Versicherungsobjektes
pub policy_data: Vec<PolicyData>,
/// Name der Versicherungsliste
pub name: String,
/// Status der Versicherungsliste
pub selected: bool
}
/// implements the helper methods, to manage policy data collections.
impl PolicyDataList {
/// Prüfung auf Versicherungselemente
pub fn is_empty(&self) -> bool {
self.policy_data.is_empty()
}
/// Versicherungselement am Anfang anfügen
pub fn insert_front(&mut self, policy_data: PolicyData) {
self.policy_data.insert(0, policy_data);
}
/// Index zum Versicherungselement zurückgeben (unveränderbar)
pub fn get(&self, index: usize) -> Option<&PolicyData> {
self.policy_data.get(index)
}
/// Index zum Versicherungselement zurückgeben (veränderbar)
pub fn get_mut(&mut self, index: usize) -> Option<&mut PolicyData> {
self.policy_data.get_mut(index)
}
/// Berechnet die Anzahl der Versicherungselemente.
pub fn len(&self) -> usize {
self.policy_data.len()
}
/// Neues Versicherungselement erstellen.
pub fn new(name: impl Into<String>) -> Self {
// the new inserted element will be active by default
PolicyDataList {
date_valid_until: None,
name: name.into(),
selected: true,
..Default::default()
}
}
/// Versicherungselement anfügen
pub fn push(&mut self, policy_data: PolicyData) {
self.policy_data.push(policy_data);
}
/// Versicherungselement löschen
pub fn remove(&mut self, index: usize) -> PolicyData {
self.policy_data.remove(index)
}
}
/// Structure representing a policy data element
/// This structure groups a set of fields that describes a policy number.
/// The data are regularily updated via a data import from a comma seperated
/// text file (csv file).
/// Since we parse the source record fields to rust types (serde deserialize)
/// the field order in our struct must meet the data field order in the source!
/// We do use field attribute to precisely rename the source fields (header names)
/// to our target rust field names.
/// Referenz: POLLFNR_WOECHENTLICH.txt ->
/// Header 'DION VERS POLLFNR'
/// Record '1 AS 1515735810'
// DION: Allianz id => len = 1??
// VERS: policy_code => enum(AS; ??)
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct PolicyData {
/// Erstellungsdatum
pub date_inserted: Option<NaiveDateTime>,
/// Allianz Dion
#[serde(rename = "DION")]
pub dion: u8,
/// Kennzeichen des Allianz Versicherungscodes
#[serde(rename = "VERS")]
pub policy_code: PolicyCode,
/// Versicherungsscheinnummer (10stellig, numerisch)
#[serde(rename = "POLLFNR")]
pub policy_number: u64,
/// Status des Versicherungsscheins
pub status: Option<Status>
}
/// Policy Number Set
#[derive(Debug, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct AllianzPolicyNumber {
/// Allianz Dion
#[serde(rename = "DION")]
pub dion: u8,
/// Kennzeichen des Allianz Versicherungstyps
#[serde(rename = "VERS")]
pub policy_code: String,
/// 10-stellige Versicherungsscheinnummer (numerisch)
#[serde(rename = "POLLFNR")]
pub policy_number: usize
}
// /// List of Allianz Policy Number records
// /// The structure elements are required for an export to a comma seperated text list.
// #[derive(Default, Debug, Deserialize)]
// pub struct AllianzPolicyNumberList {
// records: Vec<AllianzPolicyNumber>
// }
into_property_source!(PolicyCheck);
into_property_source!(PolicyDataList);
into_property_source!(PolicyList);

View File

@@ -0,0 +1,147 @@
[err_lang_not_found]
de = Konnte Sprachkode nicht auslesen
en = Couldn't read
[err_user_not_found]
fr = Utilisateur introuvable
en = User not found
[main_started]
de = Programmlogik starten
en = Program logic started
[main_finished]
de = Programmlogik beendet
en = Program logic finished
[parse_arguments]
de = Programmargumente prüfen
en = Parsing arguments
[parse_environment]
de = Umgebungsvariablen prüfen
en = Parsing environment
[parse_results]
de = Ergebnisse der Konfigurationsparameterprüfung
en = Config parsing results
[config_name]
de = Konfigurationswert für
en = Config Value for
[config_name_lang]
de = Sprach-Co
en = Language co
[config_name_verbositylevel]
de = Ausgabe-Ebene
en = verbosity level
[config_name_environment]
de = Umgebungsvariablen
en = environment
[config_name_configfile]
de = Konfigurations-Datei
en = config file
[config_name_dbdriver]
de = Datenbank-Treiber
en = database driver
[config_name_redis]
de = Redis Datenbank
en = Redis database
[csv_export_started]
de = Export in eine CSV Datei starten
en = Export to csv file started
[csv_export_finished]
de = Export in eine CSV Datei beendet
en = Export to csv file finished
[csv_import_started]
de = Import aus einer CSV Datei
en = Import from a csv file
[csv_import_finished]
de = Import aus einer CSV Datei beendet
en = Import from a csv file finished
[redis_connection_error]
de = Es konnte keine Redis Verbindung aufgebaut werden
en = Could not establish a redis connection
[policy_hashmap_success]
de = Hashmap wurde erfolgreich erstellt
en = Hashmap creation was successfull
[policy_hashmap_failed]
de = Hashmap konnte nicht erstellt werden
en = Hashmap creation failed
[policy_menu_label]
de = Menü
en = Menu
[policy_menu_label_account]
de = Aktueller Benutzer
en = Active user
[policy_menu_label_quit]
de = Beenden
en = Quit
[policy_menu_label_toggle_theme]
de = Thema wechseln
en = Toggle theme
[policy_string_header]
de = Validierung Versicherungsnummer
en = Policy number validation
[policy_string_label_policy_data]
de = Importierte Daten
en = imported data
[policy_string_label_policy_list]
de = Versicherungsnummern-Liste
en = policy list
[policy_string_label_policy_number]
de = Versicherungsnummer
en = policy number
[policy_string_label_result]
de = Prüfungsergebnis
en = check result
[policy_string_data_count]
de = Anzahl Prüflistenelemente
en = Number of checklist elements
[policy_string_import_data]
de = Importieren der Prüflisten-Elemente
en = Import checklist elements
[policy_string_progress_time]
de = Bearbeitungszeit
en = processing time
[policy_string_progress_text]
de = Importiere Daten
en = Importing data
[policy_validation_button_failed]
de = ungültig
en = invalid
[policy_validation_button_success]
de = gültig
en = valid
[policy_validation_failed]
de = Die Versicherungsscheinnummber ist ungültig
en = The given policy number is invalid
[policy_validation_new]
de = Neue Prüfung
en = New validation
[policy_validation_success]
de = Die Versicherungsscheinnummber ist gültig
en = The given policy number is valid
[policy_validation_started]
de = Die Prüfung der Versicherungsscheinnummber wurde gestartet
en = Validation of the policy number started
[policy_validation_finished]
de = Die Prüfung der Versicherungsscheinnummber wurde beendet
en = Validation of the policy number finished
[policy_validation_invalid_input]
de = Nur Nummer sind zulässig
en = Only numbers are valid
[policy_validation_not_found]
de = Nummer ist nicht aktiviert
en = number isn't marked active
[policy_validation_to_long]
de = Die Nummer ist zu lang
en = Policy number is to long
[policy_validation_to_short]
de = Die Nummer ist zu kurz
en = Policy number is to short
[sendticketdata_export_started]
de = Versenden von ticket daten via eMail gestartet
en = Send ticket data via eMail started
[sendticketdata_export_finished]
de = Versenden von ticket daten via eMail beendet
en = Send ticket data via eMail finished
[state_started]
de = gestartet
en = started
[state_finished]
de = beended
en = finished

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