154 Commits

Author SHA256 Message Date
8ba6920a2b Scroll and wage fix - Employee 2025-05-23 14:11:06 +02:00
e49622136c Merge branch 'refs/heads/schnacke' into linuxero 2025-05-23 14:04:36 +02:00
096f60a2ec Add Customer/Object/Employee working - DEBUGGING anchor Errors done 2025-05-23 11:23:16 +02:00
75427b1326 Folder structure in Gui changed, window size to fullscreen, scrollview in AddCustomer 2025-05-14 09:54:51 +02:00
591216c9a8 Removed test hallo push in main.py 2025-05-14 09:22:53 +02:00
6ed9c47bbe Test hallo push in main.py 2025-05-14 09:22:06 +02:00
6e2eb95bd6 pushtest 2025-05-14 09:12:27 +02:00
5b16432767 A lot of changes going on 2025-05-13 16:40:48 +02:00
3ff830b3e2 new Diagrams 2025-05-09 10:59:11 +02:00
2dab5883e2 Merge branch 'main' into schnacke 2025-05-08 11:47:47 +02:00
0ee3a5f8b3 Need to 2025-04-28 13:46:21 +02:00
Yuri Becker
2832becccf Style EmployeesTable 2025-04-16 12:02:21 +02:00
Yuri Becker
cf5822c950 Somewhat fix errors when adding an applicant 2025-04-16 11:00:06 +02:00
Yuri Becker
f0382a960e Validate applicant and call database procedure 2025-04-15 15:24:31 +02:00
Yuri Becker
a720dfebeb Add fields in ApplicantForm 2025-04-08 11:23:16 +02:00
Yuri Becker
ddf35a55a8 Stub ApplicantForm 2025-04-03 15:33:28 +02:00
Yuri Becker
1e9ba40b6b Add global back button 2025-04-03 14:46:36 +02:00
Yuri Becker
fc9b1c0801 Use original icon names 2025-04-03 13:18:08 +02:00
Yuri Becker
3083406b1b Use common StackView 2025-04-03 13:06:37 +02:00
Yuri Becker
f172468ba6 Extract Employee View into own dir 2025-04-03 10:56:42 +02:00
0e397619f4 Merge branch 'main' into schnacke
merge main
2025-03-25 13:41:40 +01:00
d4ed18aaf9 filter names changed 2025-03-25 13:41:01 +01:00
eda50e036a Merge branch 'main' of https://git.danielsto.de/Linuxero/pyqcrm
merge main
2025-03-25 13:27:56 +01:00
Yuri Becker
7c66dcf890 Add Note to Angebot Erstellen Design 2025-03-25 13:23:19 +01:00
8fec981409 Merge branch 'main' of https://git.danielsto.de/Linuxero/pyqcrm 2025-03-25 13:23:14 +01:00
16ba24b13d offer form not ready 2025-03-25 13:20:54 +01:00
Yuri Becker
309f1f58d7 Fix up Menu 2025-03-25 12:28:30 +01:00
Yuri Becker
445c183e71 Clean up leftover files and commented code 2025-03-25 11:39:45 +01:00
7b8c3630f8 searchbar aligned 2025-03-25 11:15:25 +01:00
d125b56564 Merge branch 'main' of https://git.danielsto.de/Linuxero/pyqcrm 2025-03-25 00:24:28 +01:00
Yuri Becker
7f5675c06d Add Hover Effect to Buttons 2025-03-24 12:06:09 +01:00
Yuri Becker
30493dbdbf Fix Offers View 2025-03-24 11:41:07 +01:00
Yuri Becker
41ecdb658c Fix Objects Table 2025-03-24 11:36:09 +01:00
6e8c2f340c added barbutton, searchbar and qucickfilter positioning, combobox still not finished 2025-03-24 11:31:00 +01:00
76c4be7a7a Merge main 2025-03-24 11:28:57 +01:00
8236bd32e6 positioning searchbar and quickfilter 2025-03-24 11:21:50 +01:00
Yuri Becker
480dd673c4 Fix Mitarbeiter Table 2025-03-24 10:53:46 +01:00
3520c65879 for changing branch 2025-03-24 09:44:55 +01:00
04ad1981e1 Adding documentation comments for doxygen (#1) 2025-03-21 16:27:51 +01:00
a821956a67 to switch branch 2025-03-21 15:56:05 +01:00
46cba58ebe for branch switch 2025-03-21 15:47:56 +01:00
a7a1cd4913 merge 2025-03-21 15:17:07 +01:00
34bd7409df edited Layout 2025-03-21 14:01:23 +01:00
6df02d9ff2 Merge main 2025-03-21 13:45:53 +01:00
9499eace9b combobox 2025-03-21 13:27:54 +01:00
Yuri Becker
721232a975 Implement Quick Filters 2025-03-21 13:25:03 +01:00
8f6efac11e combobox still in progress 2025-03-21 11:44:52 +01:00
Yuri Becker
83f64f9af8 Use dark/light specification from system 2025-03-20 14:03:40 +01:00
d6034a5299 all changes not completed 2025-03-20 13:54:04 +01:00
Yuri Becker
dc1ea604f7 Add Icons to Buttons 2025-03-20 13:04:28 +01:00
15b14387df because i have to 2025-03-20 12:38:00 +01:00
fadd3d1b9e Merge branch 'main' into schnacke
merge main
2025-03-20 12:18:39 +01:00
Yuri Becker
fb06cea060 Fix ComboBox popup positioning 2025-03-20 10:46:51 +01:00
648753823f Merge branch 'main' into schnacke
merge main
2025-03-20 10:44:31 +01:00
495252c408 commit problems 2025-03-20 10:42:49 +01:00
Yuri Becker
5cf5676d9b Possibly size Combobox correctly 2025-03-20 10:39:35 +01:00
Yuri Becker
9a6d59a19b Add Designs 2025-03-20 10:24:56 +01:00
5b7e364c20 merge main 2025-03-20 09:42:00 +01:00
ce26d6d223 BarButton still in progress 2025-03-20 09:19:03 +01:00
Yuri Becker
13416edd25 Make ComboBoxes work a bit more 2025-03-19 13:28:31 +01:00
c49e4ebacd Merge branch 'main' into schnacke
merg
2025-03-18 08:52:44 +01:00
7b1f5cd3cc Style code 2025-03-18 08:50:39 +01:00
325e396774 Module_Dienstleistungen 2025-03-18 08:36:21 +01:00
f20cebab14 New Database Dump clean and with data 2025-03-17 12:04:27 +01:00
bd7cba5430 Merge branch 'style' into schnacke
merge mit style
2025-03-17 09:11:58 +01:00
607cccfb07 Merge branch 'main' into schnacke
Doku
2025-03-17 08:59:56 +01:00
8b82b49982 Doku 2025-03-17 08:59:23 +01:00
Yuri Becker
9ff0a0fbce Style Combobox 2025-03-14 11:57:21 +01:00
Yuri Becker
ef77e4c17d Style Login page 2025-03-14 10:24:32 +01:00
7b0ec6ed99 Remove faulty definition of viewCriterion in EmployeeModel.py 2025-03-14 09:34:52 +01:00
Yuri Becker
7099102e13 Style Buttons, re-layout Login 2025-03-13 17:23:36 +01:00
d300e9c92a TeroStyle - Theme initial try 2025-03-13 15:04:53 +01:00
Yuri Becker
343e15c873 Define Colors 2025-03-13 10:45:55 +01:00
Yuri Becker
2704177fdb Stub style 2025-03-13 10:32:24 +01:00
773d398f8c Fix adding a contact person to an object and db autocommit 2025-03-12 15:43:13 +01:00
714a12e2d3 Merge branch 'main' into schnacke
merge main
2025-03-12 10:25:38 +01:00
898d808b1f Committing changes to main 2025-03-12 10:02:42 +01:00
e3053be72e Object contact logic implemented 2025-03-12 09:50:06 +01:00
ac6a83c352 Merge branch 'main' of https://git.danielsto.de/linuxero/pyqcrm 2025-03-11 09:29:32 +01:00
Yuri Becker
469b8d0a21 Fix Window Restoring on Mac 2025-03-11 09:28:59 +01:00
0834ee8905 Not solved - GIT uthentication issues 2025-03-10 16:19:19 +01:00
c8114d9e54 testing ssh git with qt 1 2025-03-10 16:17:58 +01:00
002575baa1 testing git authentication in qt 2025-03-10 15:57:28 +01:00
66fce857ba Merge branch 'refs/heads/linuxero' 2025-03-10 15:55:00 +01:00
767200096f Make spinboxes editable and correct contact person's position 2025-03-10 15:54:33 +01:00
55a35d0931 rc deleted 2025-03-10 14:16:49 +01:00
2a01433cf0 Merge branch 'main' of https://git.danielsto.de/linuxero/pyqcrm 2025-03-10 14:14:17 +01:00
66c1b168c8 DB Configuration added 2025-03-10 14:10:31 +01:00
f61f1e5c8f file not needed 2025-03-10 10:33:51 +01:00
4c07689a4a file not needed 2025-03-10 10:33:40 +01:00
5bf1d8de08 Fix icon on linuxero's branch 2025-03-10 10:26:59 +01:00
09a0daad66 Merge branch 'refs/heads/linuxero' 2025-03-10 10:24:13 +01:00
5b031e9d8d Fixed None type in EmployeeModel.py 2025-03-10 10:23:48 +01:00
155794e489 merge main 2025-03-10 09:54:46 +01:00
712df39383 Merge branch 'refs/heads/linuxero' 2025-03-08 12:24:49 +01:00
f5b32d6621 Ensure only one instance is running and publish company info. 2025-03-08 12:23:59 +01:00
c132b6830a Windows version 2025-03-07 15:29:45 +01:00
a6bed81aaf linuxversion 2025-03-07 15:29:04 +01:00
78ede0fad8 linux version 2025-03-07 15:28:51 +01:00
26759be1cb Resources for André 2025-03-07 14:47:37 +01:00
35c977c89e pyqcrm.qrc image problem fixed 2025-03-07 12:14:36 +01:00
bd232a2a28 Merge Linuxero with main 2025-03-07 12:10:18 +01:00
b414a050be Recovery in Settings and start with OfferTable 2025-03-07 11:59:51 +01:00
821da47f98 COnfiguration and systray 2025-03-07 11:58:19 +01:00
fb81b764f1 Clip delegated items of object contacts and printer not ready 2025-02-28 11:59:33 +01:00
e81407b43d Merge linuxero 2025-02-27 14:48:08 +01:00
73542e8089 Backup Config 2025-02-27 14:45:27 +01:00
89e96422cc Merge branch 'refs/heads/linuxero' 2025-02-27 14:44:13 +01:00
eacd3dacc7 Merge branch 'main' into linuxero - Objects first step 2025-02-27 14:43:59 +01:00
e0ec99098e Fixing ObjectAddOnContactPerson.qml conflict 2025-02-27 14:28:27 +01:00
6bf6ff3111 Fixing ObjectAddOnContactPerson.qml conflict 2025-02-27 14:20:15 +01:00
4c62834369 merge main 2025-02-27 09:39:40 +01:00
e528729181 BackupSettings 2025-02-27 08:52:33 +01:00
d7928d25fc Objekte anlegen 2025-02-26 16:59:20 +01:00
bd2316dbfb BackupSettings.qml 2025-02-26 15:35:34 +01:00
82b3c2d403 test 2025-02-26 15:24:24 +01:00
8ee303227e Merge linuxero 2025-02-26 15:20:33 +01:00
2a09fed57a Test 2025-02-26 15:15:39 +01:00
e7d0b7cdb5 i dont know what im doing 2025-02-26 15:10:42 +01:00
f0cde5ec20 Fehler 2025-02-26 15:09:28 +01:00
3738bf1c6e Mitarbeiter anlegen funktioniert 2025-02-26 10:33:01 +01:00
dec4ca59f0 Merge linuxero 2025-02-26 09:23:28 +01:00
0f253c518d Configuration menu entry 2025-02-26 09:12:34 +01:00
7228d5fae9 Merge branch 'main' into schnacke
asdasd
2025-02-25 16:24:15 +01:00
e2410d0852 Änderung AddNewObject 2025-02-25 16:23:49 +01:00
a68ae311bf Test 2025-02-25 16:21:09 +01:00
cc25f85771 Objekt Formular bearbeitet 2025-02-25 15:58:58 +01:00
fdaae34678 Änderungen letzt Woche 2025-02-24 09:28:40 +01:00
b468c3d078 Adjusted display of applicant/employee and optimised the DB 2025-02-14 17:50:11 +01:00
5ff4749247 Employee/Applicant GUI and DB 2025-02-14 12:05:45 +01:00
80bd2c9be2 Employee and applicant frontend and backend 2025-02-13 09:11:26 +01:00
bfd1d0974d Fummeljob hierum darum 2025-02-12 09:01:38 +01:00
b162117a80 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-02-04 10:50:33 +01:00
3eeb6ab910 TopBar modified to style buttons 2025-02-04 10:49:14 +01:00
aca38067d0 DOC änderung 2025-02-04 10:45:25 +01:00
1f5e9c01e8 Email regex updated for employee and customers 2025-02-04 10:16:30 +01:00
42c7a9c33a Regular expression email in kunden 2025-02-04 10:06:03 +01:00
0813c3c8c0 Merge branch 'refs/heads/linuxero' 2025-02-04 09:43:25 +01:00
bcc616d3b5 Stale GUI deleted and menu buttons very attractive and sexy 2025-02-04 09:41:17 +01:00
f710db48de backup encryption file 2025-02-03 16:46:57 +01:00
a709aa6da1 not needed 2025-02-03 16:24:31 +01:00
83d44cf3c7 copied 2025-02-03 16:23:54 +01:00
b5c3b56fb3 copied 2025-02-03 16:23:43 +01:00
931a99c06b copied 2025-02-03 16:23:31 +01:00
337f383701 copied 2025-02-03 16:23:19 +01:00
af04b3baa1 Andre 2025-02-03 16:04:06 +01:00
0b55556fb4 Für Andre 2025-02-03 15:51:53 +01:00
0923365cbd Add Applicant form changed 2025-02-03 08:41:07 +01:00
74b00c0b94 residence informationen added 2025-01-30 11:33:03 +01:00
716915f333 changed AddApplicant 2025-01-28 16:38:13 +01:00
538399b59a changed AddApplicant 2025-01-28 13:45:02 +01:00
8e9fe46b96 checkfield ApplicantNationalInsurance and ApplicantVarious not ready yet 2025-01-24 15:47:18 +01:00
ba08715c9a NOCH NICHT FERTIG OSCHKARINO 2025-01-24 14:30:57 +01:00
104aba8347 changed jobstatus, country in AddApplicant 2025-01-24 14:24:32 +01:00
217 changed files with 71990 additions and 27395 deletions

3
.gitignore vendored
View File

@@ -210,7 +210,7 @@ dmypy.json
# pytype static type analyzer # pytype static type analyzer
.pytype/ .pytype/
.qtcreator/ .qtcreator/
*.pyproject.user *.pyproject.user*
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
@@ -228,3 +228,4 @@ cython_debug/
rc_*.py rc_*.py
.DS_STORE

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

17
.idea/QtSettings.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="QtSettings">
<option name="mySettingsPerProfile">
<map>
<entry key="">
<value>
<PerProfileState>
<option name="myCustomQmlPath" value="/opt/homebrew/share/qt/qml" />
<option name="myCustomQtBinPath" value="/opt/homebrew/bin" />
</PerProfileState>
</value>
</entry>
</map>
</option>
</component>
</project>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

16
.idea/discord.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="nameOverrideEnabled" value="true" />
<option name="nameOverrideText" value="the qml thing (╯°□°)╯︵ ┻━┻" />
<option name="description" value="" />
<option name="applicationTheme" value="default" />
<option name="iconsTheme" value="default" />
<option name="button1Title" value="" />
<option name="button1Url" value="" />
<option name="button2Title" value="" />
<option name="button2Url" value="" />
<option name="customApplicationId" value="" />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (pyqcrm)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (pyqcrm)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pyqcrm.iml" filepath="$PROJECT_DIR$/.idea/pyqcrm.iml" />
</modules>
</component>
</project>

10
.idea/pyqcrm.iml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (pyqcrm)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

22
.idea/qmlSettings.xml generated Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="QmlSettings">
<option name="mySettingsPerProfile">
<map>
<entry key="">
<value>
<PerProfileState>
<option name="myExtraQmlPaths">
<list>
<option value="$PROJECT_DIR$/TeroStyle" />
</list>
</option>
<option name="myLSPEnabled" value="true" />
<option name="myQmlFormatEnabled" value="true" />
</PerProfileState>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Compile pyqcrm.qrc" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value=".venv/bin/pyside6-rcc -o rc_pyqcrm.py pyqcrm.qrc" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value=".venv/bin/pyside6-rcc" />
<option name="SCRIPT_OPTIONS" value="-o rc_qml.py qml.qrc" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="false" />
<option name="EXECUTE_SCRIPT_FILE" value="false" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Compile qml.qrc" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value=".venv/bin/pyside6-rcc -o rc_qml.py qml.qrc" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value=".venv/bin/pyside6-rcc" />
<option name="SCRIPT_OPTIONS" value="-o rc_qml.py qml.qrc" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="false" />
<option name="EXECUTE_SCRIPT_FILE" value="false" />
<envs />
<method v="2" />
</configuration>
</component>

31
.idea/runConfigurations/main.xml generated Normal file
View File

@@ -0,0 +1,31 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="main" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
<module name="pyqcrm" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
<env name="QT_LOGGING_RULES" value="*.debug=true; qt.*.debug=false" />
<env name="QT_LOGGING_TO_CONSOLE" value="1" />
<env name="QT_QML_DEBUG" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="SDK_NAME" value="Python 3.12 (pyqcrm)" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2">
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Compile qml.qrc" run_configuration_type="ShConfigurationType" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Compile pyqcrm.qrc" run_configuration_type="ShConfigurationType" />
</method>
</configuration>
</component>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

BIN
Dienstleistungen.docx Normal file

Binary file not shown.

View File

@@ -1,175 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "../js/qmldict.js" as JsLib
// ScrollView
// {
// anchors.fill: parent
// ScrollBar.vertical: ScrollBar
// {
// policy: ScrollBar.AlwaysOn
// }
ColumnLayout
{
id: colPar
anchors.fill: parent
Label
{
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
id: headline
text: qsTr("Mitarbeiter / Bewerber hinzufügen")
font.pixelSize: 35
}
ButtonGroup
{
buttons: radio.children
onClicked:
{
checkFields()
personalData.requiredField()
}
}
Row
{
Layout.fillWidth: true
id: radio
Layout.columnSpan: 2
RadioButton
{
checked: true
text: qsTr("Bewerber")
}
RadioButton
{
text: qsTr("Mitarbeiter")
}
}
RowLayout
{
Layout.fillWidth: true
spacing: 50
Frame
{
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
ApplicantPersonalData
{
id: personalData
width: parent.width
}
}
Frame
{
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
visible: radio.children[1].checked
ColumnLayout
{
Layout.alignment: Qt.AlignTop
width: parent.width
// CheckBox
// {
// id: checkcontactdata
// Layout.fillWidth: true
// text: qsTr("Kontaktdaten")
// checked: false
// }
// ApplicantContactData
// {
// visible: checkcontactdata.checked
// }
CheckBox
{
id: miniJobber
Layout.fillWidth: true
text: qsTr("Minijob")
checked: false
}
ApplicantBankData
{
id: bankAccount
}
ApplicantNationalInsurance
{
id: nationalInsurance
}
ApplicantVarious
{
// Layout.margins:
// {
// top: 30
// }
}
}
}
}
RowLayout
{
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Button
{
text: qsTr("Abbrechen")
onClicked: appLoader.source = "EmployeeTable.qml"
}
Button
{
id: saveBtn
text: qsTr("Speichern")
enabled: false
onClicked:
{
if (radio.children[0].checked)
{
var new_applicant = JsLib.addApplicant(personalData)
// business_model.addApplicant(new_business, 0)
// appLoader.source = "EmployeeTable.qml"
console.log(JSON.stringify (new_applicant))
}
// else
// {
// new_applicant = JsLib.addApplicant(customerView)
// var new_contact = JsLib.addApplicant(addContactLayout)
// contact_model.addContact(new_contact)
// }
}
}
}
Item
{
Layout.fillHeight: true
}
function checkFields()
{
if(radio.children[1].checked)
{
if(!personalData.checkPersonalField() || !bankAccount.checkBankField() )
saveBtn.enabled = false
else
saveBtn.enabled = true
}
else if (!personalData.checkPersonalField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
}
//}

View File

@@ -83,7 +83,7 @@ Frame
placeholderText: qsTr("beispiel@domain.de") placeholderText: qsTr("beispiel@domain.de")
validator: RegularExpressionValidator validator: RegularExpressionValidator
{ {
regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~0-9A-Za-z]{1,185})@([0-9A-Za-z\.]{1,64})\.([a-zA-z]{2,5})/ regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
} }
} }
@@ -143,9 +143,7 @@ Frame
var bd = birthday.text var bd = birthday.text
if (len === 2 || len === 5) birthday.text = bd + "." if (len === 2 || len === 5) birthday.text = bd + "."
} }
} }
} }
Label Label

View File

@@ -1,121 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Fusion
import QtQuick.Dialogs
import "../js/qmldict.js" as JsLib
ColumnLayout
{
property var new_business: null
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 15
Label
{
text: qsTr("Kunden anlegen")
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
font.pixelSize: 35
}
CheckBox
{
id: checkAddContact
text: qsTr("Ansprechpartner hinzufügen")
Layout.alignment: Qt.AlignRight
checked: false
onCheckStateChanged:
{
checkFields()
}
}
RowLayout
{
id: addCustomer
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 45
Frame
{
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
CustomerView
{
id: customerView
width: parent.width
}
}
AddContact
{
id: addContactFrame
visible: checkAddContact.checked
}
}
RowLayout
{
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Button
{
text: qsTr("Abbrechen")
onClicked: appLoader.source = "CustomerTable.qml"
}
Button
{
id: saveBtn
text: qsTr("Speichern")
enabled: false
onClicked:
{
if (!checkAddContact.checked)
{
new_business = JsLib.addBusiness(customerView)
business_model.addBusiness(new_business, 0)
appLoader.source = "CustomerTable.qml"
}
else
{
new_business = JsLib.addBusiness(customerView)
var new_contact = JsLib.addBusiness(addContactFrame.contactGrid)
contact_model.addContact(new_contact)
}
}
}
}
Item
{
id: spacer3
Layout.fillHeight: true
}
//Component.onCompleted: contact_model.contactIdReady.connect(onContactId)
Connections
{
target: contact_model
function onContactIdReady()
{
var con_id = arguments[0]
business_model.addBusiness(new_business, con_id)
appLoader.source = "CustomerTable.qml"
}
}
function checkFields()
{
if(checkAddContact.checked)
{
if(!customerView.checkBusinessField() || !addContactFrame.checkContactField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
else if (!customerView.checkBusinessField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
}

230
Gui/AddNewObject.qml Normal file
View File

@@ -0,0 +1,230 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: newObject
columns: 4
Layout.fillWidth: true
Layout.fillHeight: true
rowSpacing: 9
//// New grid row
Label
{
text: qsTr("Straße*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "street"
id: street
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields()
}
Label
{
text: qsTr("Nr.*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "houseno"
id: houseno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields()
}
// New grid row
Label
{
text: qsTr("PLZ")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "postcode"
id: postcode
Layout.fillWidth: true
editable: true
onCurrentTextChanged: checkFields()
onEditTextChanged: checkFields()
onActivated: currentValue
model: address_model
textRole: "display"
popup.height: 300
currentIndex: -1
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
validator: RegularExpressionValidator
{
regularExpression: /([0-9]{1,5})/
}
}
Label
{
text: qsTr("Ort")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "city"
id: city
Layout.fillWidth: true
editable: true
onEditTextChanged: checkFields()
onCurrentTextChanged: checkFields()
model: address_model
textRole: "city"
popup.height: 300
currentIndex: -1
}
// New grid row
Label
{
text: qsTr("Parteien")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
SpinBox
{
property string name: "units"
id: partitions
Layout.fillWidth: true
from: 1
to: 100
value: 1
editable: true
}
Label
{
text: qsTr("Stockwerke")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
SpinBox
{
property string name: "floors"
id: floors
Layout.fillWidth: true
from: 1
to: 100
value: 1
editable: true
}
// New grid row
Label
{
text: qsTr("Zwischenetage")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "mezzanin"
id: mezzanin
Layout.fillWidth: true
editable: false
model: [qsTr("Ja"), qsTr("Nein")]
}
Label
{
text: qsTr("Aufzug")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "lift"
id: lift
Layout.fillWidth: true
editable: false
model: [qsTr("Ja"), qsTr("Nein")]
}
//New grid row
Label
{
text: qsTr("Objekt-Nr.")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "objectno"
id: objectno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
placeholderText: qsTr("0 oder leer um eine Nummer automatisch zu generieren")
placeholderTextColor: "pink"
}
Label
{
text: qsTr("Besonderheiten")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "remarks"
id: remarks
Layout.fillWidth: true
}
//// New grid row
Label
{
text: qsTr("Reinigungsmittel wo?*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "cleaningproducts"
id: cleaningproducts
Layout.fillWidth: true
onTextChanged: checkFields()
}
Item
{
Layout.fillHeight: true
}
function checkObjectField()
{
return street.text.trim() && houseno.text.trim() &&
(postcode.editText.trim() || postcode.currentText.trim()) &&
(city.editText.trim() || city.currentText.trim()) &&
cleaningproducts.text.trim()
}
}

View File

@@ -1,13 +1,13 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Fusion
import QtQuick.Dialogs import QtQuick.Dialogs
import "../js/qmldict.js" as JsLib import Js
ColumnLayout ColumnLayout
{ {
property var new_object: null property var new_object: null
//property alias checkAddContact: checkAddContact
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
spacing: 15 spacing: 15
@@ -20,19 +20,19 @@ ColumnLayout
} }
CheckBox CheckBox
{ {
id: checkAddObject id: checkAddObjectContact
text: qsTr("Mitarbeiter/Ansprechpartner hinzufügen") text: qsTr("Ansprechpartner hinzufügen")
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
checked: false checked: false
onCheckStateChanged: onCheckStateChanged:
{ {
//checkFields() checkFields()
} }
} }
RowLayout RowLayout
{ {
id: addobject id: addObject
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
spacing: 45 spacing: 45
@@ -41,9 +41,9 @@ ColumnLayout
{ {
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
Layout.fillWidth: true Layout.fillWidth: true
ObjectView AddNewObject
{ {
id: objectView id: newObject
width: parent.width width: parent.width
} }
} }
@@ -51,7 +51,7 @@ ColumnLayout
ObjectAddOns ObjectAddOns
{ {
id: addObjectLayout id: addObjectLayout
visible: checkAddObject.checked visible: checkAddObjectContact.checked
} }
} }
RowLayout RowLayout
@@ -61,27 +61,25 @@ ColumnLayout
Button Button
{ {
text: qsTr("Abbrechen") text: qsTr("Abbrechen")
onClicked: appLoader.source = "ObjectTable.qml" onClicked: contentStack.pop()
} }
Button Button
{ {
property var new_object: null
id: saveBtn id: saveBtn
text: qsTr("Speichern") text: qsTr("Speichern")
enabled: false enabled: false
onClicked: onClicked:
{ {
if (!checkAddObject.checked)
{ new_object = JsLib.parseForm(newObject)
new_object = JsLib.addObject(objectView) // For Debugging
object_model.addObject(new_object, 0) console.log(JSON.stringify(new_object))
appLoader.source = "ObjectTable.qml" //
} new_object['lift'] = new_object['lift'] === 'Ja' ? 1 : 0
else new_object['mezzanin'] = new_object['mezzanin'] === 'Ja' ? 1 : 0
{ object_model.addObject(new_object)
new_object = JsLib.addObject(objectView)
var new_objecto = JsLib.addObject(addObjectLayout)
objecto_model.addObject(new_objecto)
}
} }
} }
} }
@@ -91,32 +89,67 @@ ColumnLayout
Layout.fillHeight: true Layout.fillHeight: true
} }
Component.onCompleted:
{
//object_model.objectAdded.connect(onObjectAdded)
//contact_model.objectContactAdded.connect(onObjectContact)
}
// Connections Connections
{
target: object_model
function onObjectIdReady()
{
var obj_id = arguments[0]
if (checkAddObjectContact.checked && obj_id)
{
var new_objecto = addObjectLayout.getForm()
contact_model.addObjectContact(new_objecto, obj_id)
object_model.viewCriterion("Alle")
}
contentStack.pop()
}
}
// function onObjectAdded(added, oid)
// { // {
// target: spacer3 // if (!added)
// console.log(qsTr("Fehler beim Objekt-Anlegen!"))
// function onObjectIdReady() // if (checkAddObjectContact.checked && oid)
// { // {
// var obj_id = arguments[0] // var new_objecto = addObjectLayout.getForm()
// object_model.addObject(new_object, obj_id)
// contact_model.addObjectContact(new_objecto, oid)
// }
// else appLoader.source = "ObjectTable.qml"
// }
// function onObjectContact(added)
// {
// if (!added)
// console.log(qsTr("Fehler beim Objekt-Kontakt-Anlegen!"))
// else
// {
// //object_model.viewCriterion("Alle")
// appLoader.source = "ObjectTable.qml" // appLoader.source = "ObjectTable.qml"
// } // }
// } // }
// function checkFields() function checkFields()
// { {
// if(checkAddObject.checked) if(checkAddObjectContact.checked)
// { {
// if(!objectView.checkObjectField() || !addObjectLayout.checkObjectField()) if(!newObject.checkObjectField() || !addObjectLayout.contactPerson.contacts || !addObjectLayout.contactPerson.contacts.length)
// saveBtn.enabled = false saveBtn.enabled = false
// else else
// saveBtn.enabled = true saveBtn.enabled = true
// } }
// else if (!objectView.checkObjectField()) else if (!newObject.checkObjectField())
// saveBtn.enabled = false saveBtn.enabled = false
// else else
// saveBtn.enabled = true saveBtn.enabled = true
// } }
} }

View File

@@ -51,6 +51,15 @@ GridLayout
placeholderText: qsTr("Hier Passwort eingeben") placeholderText: qsTr("Hier Passwort eingeben")
Layout.fillWidth: true Layout.fillWidth: true
property string name: "PYQCRM_USER_PASS" property string name: "PYQCRM_USER_PASS"
color: acceptableInput ? "black" : "red"
ToolTip.visible: hovered && !acceptableInput
ToolTip.text: "Passwort muss mind. 12 Zeichen lang sein und Groß-, Kleinbuchstaben, Zahlen sowie Sonderzeichen (!@#$%^&*()_+-=) enthalten."
validator: RegularExpressionValidator {
regularExpression: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=]).{12,}$/
}
} }
Label Label
{ {

View File

@@ -1,40 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: bankAccount
columns: 2
Label
{
text: qsTr("IBAN")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: iban
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
}
Label
{
text: qsTr("Bank")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: bankname
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
}
function checkBankField()
{
return (iban.text.trim() && bankname.text.trim())
}
}

View File

@@ -1,52 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Label
{
text: qsTr("Geburtsname")
}
TextField
{
id: birthname
Layout.fillWidth: true
}
Label
{
text: qsTr("Geburtsdatum")
}
TextField
{
id: birthday
Layout.fillWidth: true
placeholderText: qsTr("TT.MM.JJJJ")
validator: RegularExpressionValidator
{
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
}
}
Label
{
text: qsTr("Geburtsort")
}
TextField
{
id: placeofbirth
Layout.fillWidth: true
}
Label
{
text: qsTr("Geschlecht")
}
ComboBox
{
id: gender
Layout.fillWidth: true
editable: false
model: [qsTr("Mann"), qsTr("Frau"), qsTr("Divers")]
}

View File

@@ -1,64 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: contactData
columns: 2
Label
{
text: qsTr("Straße")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: street
Layout.fillWidth: true
}
Label
{
text: qsTr("PLZ")
Layout.alignment: Qt.AlignRight
}
RowLayout
{
ComboBox
{
id: postcode
Layout.fillWidth: true
}
Label
{
text: qsTr("Ort")
}
ComboBox
{
id: city
Layout.fillWidth: true
}
}
Label
{
text: qsTr("Telefonnummer")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: phonenumber
Layout.fillWidth: true
}
Label
{
text: qsTr("E-Mail")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: email
Layout.fillWidth: true
}
}

View File

@@ -1,19 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
columns: 2
Label
{
text: qsTr("Knappschaft")
}
TextField
{
id: knappschaft
Layout.fillWidth: true
}
}

View File

@@ -1,131 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: nationalInsurance
columns: 2
Label
{
text: qsTr("Staatsangehörigkeit Deutsch")
}
ButtonGroup
{
buttons: radio.children
onClicked:
{
checkFields()
personalData.requiredField()
}
}
Row
{
id: radio
Layout.fillWidth: true
Layout.alignment: Qt.AlignLeft
RadioButton
{
text: qsTr("Ja")
checked: true
}
RadioButton
{
text: qsTr("Nein")
}
}
Label
{
text: qsTr("Sozialversicherungs-Nr")
}
TextField
{
id: socialnumber
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
}
Label
{
text: qsTr("Steuer-ID")
}
TextField
{
id: taxnumber
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
}
Label
{
text: qsTr("Krankenkasse")
}
TextField
{
id: medicalinsurance
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
}
CheckBox
{
Layout.columnSpan: 2
text: qsTr("Arbeitserlaubnis")
visible: radio.children[1].checked
}
Label
{
text: qsTr("Staatsangehörigkeit")
visible: radio.children[1].checked
}
TextField
{
id: nationality
visible: radio.children[1].checked
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
}
Label
{
text: qsTr("Pass gültig bis")
visible: radio.children[1].checked
}
TextField
{
id: pass
visible: radio.children[1].checked
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
}
Label
{
text: qsTr("Aufenthaltstitel gültig bis")
visible: radio.children[1].checked
}
TextField
{
id: aufenthalt
visible: radio.children[1].checked
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
}
}

View File

@@ -1,37 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
CheckBox
{
Layout.columnSpan: 2
text: qsTr("Arbeitserlaubnis")
}
Label
{
text: qsTr("Staatsangehörigkeit")
}
TextField
{
id: nationality
}
Label
{
text: qsTr("Pass gültig bis")
}
TextField
{
id: pass
}
Label
{
text: qsTr("Aufenthaltstitel gültig bis")
}
TextField
{
id: aufenthalt
}

View File

@@ -1,307 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: personalData
columns: 4
Label
{
text: qsTr("Anrede")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "title"
id: title
Layout.fillWidth: true
editable: false
Layout.columnSpan: 3
model: [qsTr("Keine Angabe"), qsTr("Herr"), qsTr("Frau")]
onCurrentTextChanged:
{
switch (title.currentIndex)
{
case 1:
briefAnrede.text = "Sehr geehrter Herr "
break
case 2:
briefAnrede.text = "Sehr geehrte Frau "
break
default:
briefAnrede.text = "Guten Tag "
}
}
}
Label
{
text: qsTr("Vorname")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "firstname"
id: firstname
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
onTextChanged: checkFields()
Layout.columnSpan: 3
}
Label
{
text: qsTr("Nachname")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "lastname"
id: lastname
Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
onTextChanged: checkFields()
Layout.columnSpan: 3
}
Label
{
text: qsTr("Straße")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "street"
id: street
Layout.fillWidth: true
placeholderTextColor: "red"
}
Label
{
text: qsTr("Nr.")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "houseno"
id: houseno
Layout.fillWidth: true
placeholderTextColor: "red"
}
Label
{
text: qsTr("PLZ")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "postcode"
id: postcode
Layout.fillWidth: true
editable: true
onCurrentTextChanged: checkFields()
onEditTextChanged: checkFields()
onActivated: currentValue
model: address_model
textRole: "display"
popup.height: 300
popup.y: postcode.y + 5 - (postcode.height * 2)
currentIndex: -1
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
validator: RegularExpressionValidator
{
regularExpression: /([0-9]{1,5})/
}
}
Label
{
text: qsTr("Ort")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "city"
id: city
Layout.fillWidth: true
editable: true
onEditTextChanged: checkFields()
onCurrentTextChanged: checkFields()
model: address_model
textRole: "city"
popup.height: 300
popup.y: postcode.y + 5 - (postcode.height * 2)
currentIndex: -1
}
Label
{
text: qsTr("Telefonnummer")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "phone"
id: phonenumber
Layout.fillWidth: true
placeholderTextColor: "red"
Layout.columnSpan: 3
}
Label
{
text: qsTr("Mobil")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "mobile"
id: cellphone
Layout.fillWidth: true
placeholderTextColor: "red"
Layout.columnSpan: 3
}
Label
{
text: qsTr("E-Mail")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "email"
id: email
Layout.fillWidth: true
placeholderTextColor: "red"
Layout.columnSpan: 3
}
Label
{
text: qsTr("Familienstand")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
ComboBox
{
property string name: "maritalstatus"
id: maritalstatus
Layout.fillWidth: true
editable: false
model: [qsTr("ledig"), qsTr("verheiratet"), qsTr("verwitwet"), qsTr("geschieden")]
visible: radio.children[1].checked
Layout.columnSpan: 3
}
Label
{
text: qsTr("Jobbeschreibung")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "jobdesc"
id: jobdescription
Layout.fillWidth: true
visible: radio.children[1].checked
placeholderTextColor: "red"
Layout.columnSpan: 3
}
Label
{
text: qsTr("Arbeitsbeginn")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "workstart"
id: workstart
Layout.fillWidth: true
visible: radio.children[1].checked
placeholderTextColor: "red"
Layout.columnSpan: 3
}
Label
{
text: qsTr("Bei Befristung Ende")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "workend"
id: workend
Layout.fillWidth: true
visible: radio.children[1].checked
placeholderTextColor: "red"
Layout.columnSpan: 3
}
Label
{
text: qsTr("Arbeitszeiten")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "timework"
id: timetowork
Layout.fillWidth: true
visible: radio.children[1].checked
placeholderTextColor: "red"
Layout.columnSpan: 3
}
Label
{
text: qsTr("Briefanrede")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "formofaddress"
id: briefAnrede
Layout.fillWidth: true
placeholderTextColor: "red"
Layout.columnSpan: 3
}
Item
{
Layout.fillHeight: true
Layout.columnSpan: 4
}
function checkPersonalField()
{
if (radio.children[0].checked)
{
return (firstname.text.trim() && lastname.text.trim())
}
else
{
console.log("Mitarbeiter")
return (firstname.text.trim() && lastname.text.trim())
}
}
function requiredField()
{
var pf = (radio.children[1].checked)?"Pflichtfeld":""
street.placeholderText = pf
phonenumber.placeholderText = pf
cellphone.placeholderText = pf
email.placeholderText = pf
jobdescription.placeholderText = pf
workstart.placeholderText = pf
workend.placeholderText = pf
timetowork.placeholderText = pf
briefAnrede.placeholderText = pf
}
}

57
Gui/BackupSettings.qml Normal file
View File

@@ -0,0 +1,57 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import QtCore
import Js
GridLayout
{
anchors.fill: parent
anchors.topMargin: 150
columns: 2
Label
{
Layout.columnSpan: 2
Layout.alignment: Qt.AlignHCenter
text: qsTr("Sicherung")
font.pixelSize: 35
}
Label
{
text: qsTr("Konfiguration")
Layout.alignment: Qt.AlignRight
}
Button
{
id: saveConfig
text: qsTr("Jetzt sichern!")
onClicked: utilityDialogs.item.backup_config.open()
}
Label
{
text: qsTr("Verschlüsselung")
Layout.alignment: Qt.AlignRight
}
Button
{
id: saveEncryption
text: qsTr("Jetzt sichern!")
onClicked: utilityDialogs.item.backup_encrypt_pw.open()
}
Item
{
id: spacer
Layout.fillHeight: true
}
Loader
{
id: utilityDialogs
source: "UtilityDialogs.qml"
}
}

122
Gui/CompanyConf.qml Normal file
View File

@@ -0,0 +1,122 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
ColumnLayout
{
property alias name: companyName
property alias street: street
property alias house: houseno
property alias zipcode: zipcode
property alias city: city
anchors.fill: parent
anchors.topMargin: 50
RowLayout
{
Layout.fillWidth: true
Label
{
text: qsTr("Namen")
// font.pixelSize: 57
// font.bold: true
}
TextField
{
id: companyName
Layout.fillWidth: true
}
}
RowLayout
{
Layout.fillWidth: true
Label
{
text: qsTr("Straße")
// font.pixelSize: 57
// font.bold: true
}
TextField
{
id: street
Layout.fillWidth: true
}
Label
{
text: qsTr("Haus-Nr.")
// font.pixelSize: 57
// font.bold: true
}
TextField
{
id: houseno
Layout.fillWidth: true
}
}
RowLayout
{
Layout.fillWidth: true
Label
{
text: qsTr("PLZ")
}
ComboBox
{
id: zipcode
Layout.fillWidth: true
editable: true
model: address_model
textRole: "display"
popup.height: 300
onCurrentIndexChanged: city.currentIndex = zipcode.currentIndex
validator: RegularExpressionValidator
{
regularExpression: /([0-9]{1,5})/
}
}
Label
{
text: qsTr("Stadt")
// font.pixelSize: 57
// font.bold: true
}
ComboBox
{
id: city
Layout.fillWidth: true
editable: true
model: address_model
textRole: "city"
popup.height: 300
currentIndex: -1
}
}
Item
{
Layout.fillHeight: true
}
Component.onCompleted:
{
var c = config.getCompanyInfo()
if (Object.keys(c).length)
{
companyName.text = c['NAME']
street.text = c['STREET']
houseno.text = c['HOUSE']
zipcode.editText = c['ZIPCODE']
city.editText = c['CITY']
}
}
}

View File

@@ -0,0 +1,136 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs
import Js
import Gui
ScrollView
{
id: scroll
width: parent.width
height: parent.height
property var new_business: null
ColumnLayout
{
height: Screen.desktopAvailableHeight
width: scroll.width
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 15
Label
{
text: qsTr("Kunden anlegen")
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
font.pixelSize: 35
}
CheckBox
{
id: checkAddContact
text: qsTr("Ansprechpartner hinzufügen")
Layout.alignment: Qt.AlignRight
checked: false
onCheckStateChanged:
{
checkFields()
}
}
RowLayout
{
id: addCustomer
// Layout.fillWidth: true
// Layout.fillHeight: true
spacing: 45
Frame
{
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
CustomerView
{
id: customerView
width: parent.width
}
}
AddContact
{
id: addContactFrame
visible: checkAddContact.checked
}
}
RowLayout
{
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Button
{
text: qsTr("Abbrechen")
onClicked: contentStack.pop()
}
Button
{
id: saveBtn
text: qsTr("Speichern")
enabled: false
onClicked:
{
if (!checkAddContact.checked)
{
new_business = JsLib.parseForm(customerView)
console.log(JSON.stringify(new_business))
business_model.addBusiness(new_business, 0)
contentStack.pop()
}
else
{
new_business = JsLib.parseForm(customerView)
var new_contact = JsLib.parseForm(addContactFrame.contactGrid)
contact_model.addContact(new_contact)
}
}
}
}
Item
{
id: spacer3
Layout.fillHeight: true
}
//Component.onCompleted: contact_model.contactIdReady.connect(onContactId)
Connections
{
target: contact_model
function onContactIdReady()
{
var con_id = arguments[0]
business_model.addBusiness(new_business, con_id)
contentStack.pop()
}
}
}
function checkFields()
{
if(checkAddContact.checked)
{
if(!customerView.checkBusinessField() || !addContactFrame.checkContactField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
else if (!customerView.checkBusinessField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
}

View File

@@ -0,0 +1,174 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
columns: 2
rowSpacing: 25
Layout.leftMargin: 7
// Grid row
ColumnLayout
{
Layout.columnSpan: 2
Label
{
id: contactLabel
color: "darksalmon"
font.bold: true
text: qsTr("Ansprechpartner")
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['salute'] + " " + contact['contact']['fname'] + " " + contact['contact']['lname']: ""
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Geburtsdatum")
font.bold: true
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['birthday']: ""
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("E-Mail")
font.bold: true
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['email']: ""
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Position")
font.bold: true
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['position']: ""
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Priorität")
font.bold: true
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['priority']: ""
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Telefon")
font.bold: true
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['phone']: ""
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Handy")
font.bold: true
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['cell']: ""
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Abrechnung")
font.bold: true
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['invoice']: ""
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Mahnung")
font.bold: true
}
Label
{
color: "goldenrod"
text: contact? contact['contact']['reminder']: ""
}
}
// Grid row
Item
{
Layout.columnSpan: 2
Layout.fillHeight: true
}
Component.onCompleted:
{
if (contact && contact['contact']['salute'] === "Frau")
contactLabel.text = qsTr("Ansprechpartnerin")
}
}

View File

@@ -0,0 +1,61 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ColumnLayout
{
property int selectedClient: -1
property var client: null
property var contact: null
id: clDet
Button
{
text: qsTr("Zurück")
onClicked: contentStack.pop()
}
SplitView
{
id: clDetView
Layout.fillHeight: true
Layout.fillWidth: true
leftPadding: 9
rightPadding: 9
CustomerDetailsView
{
id: customerDetails
}
CustomerContactDetails
{
id: contactDetails
visible: false
}
NoCustomerContact
{
id: noCustomerContact
visible: false
}
}
Item
{
//Layout.columnSpan: 2
Layout.fillHeight: true
}
Component.onCompleted:
{
//business_model.onRowClicked(selectedClient)
client = business_model.getClientDetails()
if (client['business']['contactid'] > 0)
{
contact = contact_model.getContactDetails(client['business']['contactid'])
contactDetails.visible = true
}
else noCustomerContact.visible = true
}
}

View File

@@ -0,0 +1,225 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
columns: 2
rowSpacing: 25
SplitView.preferredWidth: clDetView.width / 3 * 1.8
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Steuer-ID")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['tax']? client['business']['tax']: ""
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Anmerkungen")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['info']? client['business']['info']: ""
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Kundenname")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['company']
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("CEO")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['ceo']
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Telefon")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['phone']? client['business']['phone']: ""
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Handy")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['cell']? client['business']['cell']: ""
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Webseite")
font.bold: true
}
Label
{
id: clientWebsite
color: "goldenrod"
font.underline: false
text: client['business']['website']? '<a href="' + client['business']['website'] + '">' + client['business']['website'] + '</a>': ""
onLinkActivated:
{
var web_protocol = /^((http|https):\/\/)/;
var client_website = !web_protocol.test(client['business']['website'])? "https://" + client['business']['website']: client['business']['website'];
Qt.openUrlExternally(client_website)
}
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("E-Mail")
font.bold: true
}
Label
{
id: clientEmail
color: "goldenrod"
text: client['business']['email']? '<a href="mailto:' + client['business']['email'] + '">' + client['business']['email'] + '</a>': ""
onLinkActivated: Qt.openUrlExternally('mailto:' + client['business']['email'])
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Straße")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['street']? client['business']['tax']: ""
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Haus-Nr.")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['house']? client['business']['house']: ""
}
}
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("PLZ")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['zip']? client['business']['zip']: ""
}
}
ColumnLayout
{
Label
{
color: "darksalmon"
text: qsTr("Stadt")
font.bold: true
}
Label
{
color: "goldenrod"
text: client['business']['city']? client['business']['city']: ""
}
}
// Grid row
// Item
// {
// Layout.columnSpan: 2
// Layout.fillHeight: true
// }
}

View File

@@ -16,11 +16,10 @@ GridLayout
Label Label
{ {
id: lblFirmenName id: lblFirmenName
text: qsTr("Firmenname") text: qsTr("Firmenname*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
} }
TextField TextField
{ {
property string name: "business" property string name: "business"
@@ -29,52 +28,30 @@ GridLayout
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields() onTextChanged: checkFields()
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
Layout.columnSpan: 3 Layout.columnSpan: 3
} }
Label Label
{ {
text: qsTr("Straße") text: qsTr("Land")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
visible: false
} }
ComboBox
TextField
{ {
property string name: "street" property string name: "country"
id: streetid id: country
Layout.fillWidth: true Layout.fillWidth: true
onTextChanged: checkFields() editable: true
placeholderText: "Pflichtfeld" // onEditTextChanged: checkFields()
placeholderTextColor: "red" // onCurrentTextChanged: checkFields()
} model: address_model
textRole: "country"
popup.height: 300
currentIndex: 37
Layout.columnSpan: 3
visible: false
Label
{
text: qsTr("Nr.")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
} }
TextField
{
property string name: "houseno"
id: housenoid
Layout.fillWidth: true
onTextChanged: checkFields()
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
validator: RegularExpressionValidator
{
regularExpression: /([0-9a-zA-Z\-]{1,6})/
}
}
Label Label
{ {
text: qsTr("PLZ") text: qsTr("PLZ")
@@ -96,7 +73,6 @@ GridLayout
model: address_model model: address_model
textRole: "display" textRole: "display"
popup.height: 300 popup.height: 300
popup.y: postcode.y + 5 - (postcode.height * 2)
currentIndex: -1 currentIndex: -1
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
Layout.columnSpan: 3 Layout.columnSpan: 3
@@ -123,11 +99,43 @@ GridLayout
model: address_model model: address_model
textRole: "city" textRole: "city"
popup.height: 300 popup.height: 300
popup.y: postcode.y + 5 - (postcode.height * 2)
currentIndex: -1 currentIndex: -1
Layout.columnSpan: 3 Layout.columnSpan: 3
// onCurrentIndexChanged: postcode.currentIndex = city.currentIndex
} }
Label
{
text: qsTr("Straße*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "street"
id: streetid
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label
{
text: qsTr("Nr.*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "houseno"
id: housenoid
Layout.fillWidth: true
onTextChanged: checkFields()
validator: RegularExpressionValidator
{
regularExpression: /([0-9a-zA-Z\-]{1,6})/
}
}
Label Label
{ {
@@ -178,7 +186,7 @@ GridLayout
Layout.columnSpan: 3 Layout.columnSpan: 3
validator: RegularExpressionValidator validator: RegularExpressionValidator
{ {
regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~0-9A-Za-z]{1,185})@([0-9A-Za-z\.]{1,64})\.([a-zA-z]{2,5})/ regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
} }
} }
@@ -268,7 +276,7 @@ GridLayout
} }
function checkBusinessField() function checkBusinessField()
{ {
if (!firmenName.text.trim() || !streetid.text.trim()) if (!firmenName.text.trim() || !streetid.text.trim() || !housenoid.text.trim())
{ {
return false return false

View File

@@ -0,0 +1,177 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout {
property var availableFilters: ["Name", "Adresse", "PLZ", "Ort"]
function viewCriterion(criterion)
{
business_model.viewCriterion(criterion.text);
}
spacing: Dimensions.l
// Component.onCompleted: contentStack.pop()
RowLayout
{
Layout.fillWidth: true
spacing: Dimensions.l
SearchBar
{
}
QuickFilter {
onSelectedChanged: (name) => {
business_model.viewCriterion(name)
}
model: ListModel {
ListElement {
name: "Alle"
text: qsTr("Alle")
selected: true
}
ListElement {
name: "Interessent"
text: qsTr("Interessent")
selected: false
}
ListElement {
name: "Kunde"
text: qsTr("Kunde")
selected: false
}
ListElement {
name: "Lieferant"
text: qsTr("Lieferant")
selected: false
}
ListElement {
name: "Erledigt"
text: qsTr("Erledigt")
selected: false
}
}
}
Button
{
id: addCustomer
Layout.alignment: Qt.AlignRight
icon.source: "qrc:/images/PlusCircle.svg"
text: qsTr("Kunde Hinzufügen")
onClicked: contentStack.push("AddCustomer.qml")
}
}
ColumnLayout
{
Layout.fillWidth: true
Layout.fillHeight: true
Layout.verticalStretchFactor: 1
clip: true
HorizontalHeaderView
{
id: horizontalHeader
Layout.fillWidth: true
implicitHeight: 40
movableColumns: true //@disable-check M16
syncView: customerTable
delegate: Rectangle
{
Layout.fillWidth: true
border.color: addCustomer.palette.base
color: addCustomer.palette.alternateBase
implicitHeight: 40
implicitWidth: 1
Text
{
color: addCustomer.palette.text
elide: Text.ElideRight
height: parent.height
horizontalAlignment: Text.AlignHCenter
text: model.display
verticalAlignment: Text.AlignVCenter
width: parent.width
}
}
}
TableView {
id: customerTable
property real newWidth: 0
Layout.fillHeight: true
Layout.fillWidth: true
alternatingRows: true
columnSpacing: 1
model: business_model
resizableColumns: true
rowSpacing: 2
selectionBehavior: TableView.SelectRows
z: 1
ScrollBar.vertical: ScrollBar {
policy: customerTable.contentHeight > customerTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
}
delegate: Rectangle {
required property bool current
required property bool selected
color: selected ? addCustomer.palette.highlight //palette.highlight
: (customerTable.alternatingRows && row % 2 !== 0 ? addCustomer.palette.base // palette.base
: addCustomer.palette.alternateBase) //palette.alternateBase)
implicitHeight: 25
implicitWidth: customerTable.width / customerTable.columns
Text {
color: addCustomer.palette.text
elide: Text.ElideRight
height: parent.height
leftPadding: 9
text: model.display == null ? "" : model.display // @disable-check M126
verticalAlignment: Text.AlignVCenter
width: parent.width
}
MouseArea {
id: mouseArea
property bool hovered: false
anchors.fill: parent
hoverEnabled: true
onDoubleClicked: {
business_model.onRowClicked(row);
contentStack.push("CustomerDetails.qml", {
selectedClient: row
});
}
onEntered: {
customerTable.selectionModel.select(customerTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows);
}
}
}
selectionModel: ItemSelectionModel {
id: selModel
model: customerTable.model
}
}
}
Item {
Layout.fillHeight: true
}
}

View File

@@ -0,0 +1,33 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
columns: 2
rowSpacing: 25
// Grid row
ColumnLayout
{
Label
{
color: "darksalmon"
font.bold: true
text: qsTr("Kein Ansprechpartner gefunden")
}
Label
{
color: "goldenrod"
text: qsTr("Was willst du tun?")
}
}
// Grid row
Item
{
Layout.columnSpan: 2
Layout.fillHeight: true
}
}

1
Gui/Customer/qmldir Normal file
View File

@@ -0,0 +1 @@
module Customer

View File

@@ -1,27 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Item
{
property int selectedClient: -1
id: clDet
ColumnLayout
{
Label
{
text: qsTr("Ausgewählter Kunde " + selectedClient)
}
Button
{
text: qsTr("Kunden zeigen")
onClicked: customersStack.pop()
}
}
Component.onCompleted:
{
business_model.onRowClicked(selectedClient)
}
}

View File

@@ -1,22 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
import QtQuick.Controls.Fusion
Item {
anchors.fill: parent
property var availableFilters: ["Name", "Adresse", "PLZ", "Ort"]
id: test
StackView
{
id: customersStack
anchors.fill: parent
initialItem: "CustomersTable.qml"
}
}

View File

@@ -1,219 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
import QtQuick.Controls.Fusion
Item
{
SearchBar
{
id:searchBar
anchors.margins: 9
}
Button
{
id: addBusinessBtn
icon.source: "qrc:/images/addbusiness.svg"
icon.color: "olive"
anchors.right: parent.right
flat: true
onClicked: appLoader.source = "AddCustomer.qml"
}
ColumnLayout
{
id: tableColumn
anchors
{
top: searchBar.bottom
bottom: parent.bottom
left: parent.left
right: parent.right
}
RowLayout
{
RadioButton
{
id: showAll
checked: true
text: qsTr("Alle")
onClicked: viewCriterion(showAll)
}
RadioButton
{
id: showInterested
text: qsTr("Interessent")
onClicked: viewCriterion(showInterested)
}
RadioButton
{
id: showClientele
text: qsTr("Kunden")
onClicked: viewCriterion(showClientele)
}
RadioButton
{
id: showProvider
text: qsTr("Lieferant")
onClicked: viewCriterion(showProvider)
}
RadioButton
{
id: showFinished
text: qsTr("Erledigt")
onClicked: viewCriterion(showFinished)
}
}
HorizontalHeaderView
{
id: horizontalHeader
Layout.fillWidth: true
implicitHeight: 40
movableColumns: true //@disable-check M16
syncView: customerTable
delegate: Rectangle {
color: addBusinessBtn.palette.alternateBase
border.color: addBusinessBtn.palette.base
implicitHeight: 40
Layout.fillWidth: true
implicitWidth: 1
Text
{
text: model.display
elide: Text.ElideRight
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: addBusinessBtn.palette.text
}
}
}
TableView
{
//property var customWidths: [0.2, 0.5, 0.3, 05, 0.2, 0.2]
property real newWidth: 0
id: customerTable
Layout.fillHeight: true
Layout.fillWidth: true
ScrollBar.vertical: ScrollBar
{
policy: customerTable.contentHeight > customerTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
}
columnSpacing: 1
rowSpacing: 2
model: business_model
alternatingRows: true
resizableColumns: true // @disable-check M16
selectionBehavior: TableView.SelectRows
selectionModel: ItemSelectionModel
{
id: selModel
model: customerTable.model
}
// columnWidthProvider: function(column)
// {
// switch (column)
// {
// case 0: return width * 0.2;
// case 1: return width * 0.5;
// case 2: return width * 0.3;
// default: return width / model.columnCount();
// }
//return customWidths[column] * width;
//return tableColumn.content.implicitWidth // model.columnCount()
// newWidth = columnWidth(column)
// return newWidth
// }
Timer
{
id: redrawTable
running: true
interval: 1
repeat: false
onTriggered:
{
customerTable.forceLayout();
}
}
delegate:Rectangle
{
required property bool selected
required property bool current
implicitWidth: customerTable.width / customerTable.columns
implicitHeight: 25
color: selected
? addBusinessBtn.palette.highlight //palette.highlight
: (customerTable.alternatingRows && row % 2 !== 0
? addBusinessBtn.palette.base // palette.base
: addBusinessBtn.palette.alternateBase) //palette.alternateBase)
Text
{
text: model.display == null? "": model.display
elide: Text.ElideRight
width: parent.width
height: parent.height
verticalAlignment: Text.AlignVCenter
leftPadding: 9 //@d isable-check M16
color: addBusinessBtn.palette.text
}
MouseArea
{
property bool hovered: false
id: mouseArea
anchors.fill: parent
hoverEnabled: true
// onClicked:
// {
// business_model.onRowClicked(row)
// }
onDoubleClicked:
{
customersStack.push("CustomerDetails.qml", {selectedClient: row});
}
onEntered:
{
customerTable.selectionModel.select(customerTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows)
}
}
}
onContentWidthChanged:
{
//console.log("Model changed!!")
redrawTable.start()
}
}
Item
{
//Layout.fillHeight: true
Layout.fillWidth: true
}
}
function viewCriterion(criterion)
{
business_model.viewCriterion(criterion.text)
}
Component.onCompleted: customersStack.pop()
}

View File

@@ -2,127 +2,106 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
ColumnLayout ColumnLayout {
{ anchors.top: Navigation.bottom
anchors.top: TopBar.bottom
Rectangle Rectangle {
{ Layout.bottomMargin: 3
color: "dimgrey"
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
Layout.bottomMargin: 3 color: "dimgrey"
radius: 45 radius: 45
RowLayout RowLayout {
{
anchors.fill: parent anchors.fill: parent
Rectangle Rectangle {
{
id: contractButton id: contractButton
width: 300
height: 145
color: "darkslategray"
radius: 45
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
border.color: "steelblue" border.color: "steelblue"
border.width: 1 border.width: 1
Text color: "darkslategray"
{ height: 145
radius: 45
width: 300
Text {
anchors.centerIn: parent
color: "lightgoldenrodyellow"
font.bold: true
font.pixelSize: 45
text: qsTr("Aufträge") text: qsTr("Aufträge")
anchors.centerIn: parent
font.pixelSize: 45
font.bold: true
color: "lightgoldenrodyellow"
} }
MouseArea {
MouseArea
{
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
hoverEnabled: true hoverEnabled: true
onPressed:
{
contractButton.color = "darkolivegreen"
contractButton.border.width = 3
contractButton.border.color = "skyblue"
console.log("Aufträge...")
}
onReleased: onExited: {
{ contractButton.color = "darkslategray";
contractButton.color = "darkslategray" contractButton.border.color = "steelblue";
contractButton.border.width = 1 contractButton.border.width = 1;
contractButton.border.color = "steelblue"
} }
onHoveredChanged: {
onHoveredChanged: var w = contractButton.border.width === 3 ? 1 : 3;
{ contractButton.border.width = w;
var w = contractButton.border.width === 3? 1: 3
contractButton.border.width = w
} }
onPressed: {
onExited: contractButton.color = "darkolivegreen";
{ contractButton.border.width = 3;
contractButton.border.color = "skyblue";
contractButton.color = "darkslategray" console.log("Aufträge...");
contractButton.border.color = "steelblue" }
contractButton.border.width = 1 onReleased: {
contractButton.color = "darkslategray";
contractButton.border.width = 1;
contractButton.border.color = "steelblue";
} }
} }
} }
Rectangle {
Rectangle
{
id: offerButton id: offerButton
width: 300
height: 145
color: "darkslategray"
radius: 45
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
border.color: "steelblue" border.color: "steelblue"
border.width: 1 border.width: 1
Text color: "darkslategray"
{ height: 145
text: qsTr("Angebote") radius: 45
width: 300
Text {
anchors.centerIn: parent anchors.centerIn: parent
font.pixelSize: 45
font.bold: true
color: "lightgoldenrodyellow" color: "lightgoldenrodyellow"
font.bold: true
font.pixelSize: 45
text: qsTr("Angebote")
} }
MouseArea MouseArea {
{
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
hoverEnabled: true hoverEnabled: true
onPressed: onExited: {
{ offerButton.color = "darkslategray";
offerButton.color = "darkolivegreen" offerButton.border.color = "steelblue";
offerButton.border.width = 3 offerButton.border.width = 1;
offerButton.border.color = "skyblue"
console.log("Angebote...")
} }
onReleased: onHoveredChanged: {
{ var w = offerButton.border.width === 3 ? 1 : 3;
offerButton.color = "darkslategray" offerButton.border.width = w;
offerButton.border.width = 1
offerButton.border.color = "steelblue"
} }
onPressed: {
onHoveredChanged: offerButton.color = "darkolivegreen";
{ offerButton.border.width = 3;
var w = offerButton.border.width === 3? 1: 3 offerButton.border.color = "skyblue";
offerButton.border.width = w console.log("Angebote...");
} }
onReleased: {
onExited: offerButton.color = "darkslategray";
{ offerButton.border.width = 1;
offerButton.border.color = "steelblue";
offerButton.color = "darkslategray"
offerButton.border.color = "steelblue"
offerButton.border.width = 1
} }
} }
} }

View File

@@ -5,7 +5,11 @@ import QtQuick.Layouts
GridLayout GridLayout
{ {
// property alias firstStart: firstStartGrid property alias dbHost: dbHost
property alias dbPort: dbPort
property alias dbName: dbName
property alias dbUserName: dbUserName
property alias dbPassword: dbPassword
id: dbGrid id: dbGrid
columns: 2 columns: 2
columnSpacing: 5 columnSpacing: 5
@@ -102,4 +106,17 @@ GridLayout
{ {
Layout.fillHeight: true Layout.fillHeight: true
} }
Component.onCompleted:
{
var db = config.getDbConf()
if (Object.keys(db).length)
{
dbHost.text = db['DB_HOST']
dbPort.text = db['DB_PORT']
dbName.text = db['DB_NAME']
dbUserName.text = db['DB_USER']
dbPassword.text = db['DB_PASS']
}
}
} }

View File

@@ -1,18 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
Item
{
StackView
{
id: employeesStack
anchors.fill: parent
initialItem: "EmployeesTable.qml"
}
}

View File

@@ -0,0 +1,50 @@
import QtQuick
import QtQuick.Layouts
import TeroStyle
import Js
ColumnLayout {
anchors.fill: parent
spacing: Dimensions.l
Component.onCompleted: {
employee_model.addedNewEmployee.connect(successful => {
if (successful)
contentStack.pop();
});
}
ApplicantForm
{
id: applicantForm
Layout.alignment: Qt.AlignTop
Layout.fillHeight: true
Layout.verticalStretchFactor: 1
}
RowLayout
{
Layout.alignment: Qt.AlignRight
spacing: Dimensions.l
Button
{
icon.source: "qrc:/images/ArrowLeftCircle-Outline.svg"
text: qsTr("Verwerfen")
onClicked: contentStack.pop()
}
Button
{
enabled: applicantForm.valid
icon.source: "qrc:/images/CheckCircle.svg"
text: qsTr("Speichern")
onClicked:
{
employee_model.addApplicant(applicantForm.value);
}
}
}
}

View File

@@ -0,0 +1,110 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Js
ScrollView
{
id: scroll
width: parent.width
height: parent.height
function checkFields() {
if (!personalData.checkPersonalField())
saveBtn.enabled = false;
else
saveBtn.enabled = true;
}
function onAddNewEmployee(added) {
if (added) {
console.log('addedsuccesfully');
contentStack.pop();
} else {
console.log('failedtoadd');
}
}
ColumnLayout {
id: colPar
height: Screen.desktopAvailableHeight
width: scroll.width
Layout.fillHeight: true
Layout.fillWidth: true
implicitWidth: parent.width
Component.onCompleted: {
employee_model.addedNewEmployee.connect(onAddNewEmployee);
}
Label {
id: headline
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
font.pixelSize: 35
text: qsTr("Mitarbeiter hinzufügen")
}
RowLayout {
Layout.fillWidth: true
spacing: Dimensions.l
Frame {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.horizontalStretchFactor: 1
EmployeePersonalData {
id: personalData
implicitWidth: parent.width
}
}
Frame {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.horizontalStretchFactor: 1
ColumnLayout {
Layout.alignment: Qt.AlignTop
implicitWidth: parent.width
EmployeeBankData {
id: bankAccount
}
EmployeeNationalInsurance {
id: nationalInsurance
}
EmployeeVarious {
id: applicantVarious
}
}
}
}
Item {
Layout.fillHeight: true
}
RowLayout {
Layout.alignment: Qt.AlignRight
Layout.fillWidth: true
Button {
text: qsTr("Abbrechen")
onClicked: contentStack.pop()
}
Button {
id: saveBtn
enabled: false
text: qsTr("Speichern")
onClicked: {
const new_applicant = JsLib.parseForm(personalData, bankAccount, nationalInsurance, applicantVarious);
employee_model.addEmployee(new_applicant);
}
}
}
}
}

View File

@@ -0,0 +1,264 @@
import QtQuick
import QtQuick.Controls.impl
import QtQuick.Layouts
import TeroStyle
ColumnLayout
{
readonly property int fieldM: 235
readonly property int fieldS: 110
readonly property bool valid: city.acceptableInput && email.acceptableInput && firstname.acceptableInput && lastname.acceptableInput && mobile.acceptableInput && phone.acceptableInput && postcode.acceptableInput && formofaddress.acceptableInput && title.acceptableInput
readonly property var value: QtObject
{
readonly property string city: (city.editText ? city.editText : city.currentText) ?? ""
readonly property string email: email.text
readonly property string firstname: firstname.text
readonly property string formofaddress: formofaddress.text
readonly property string houseno: houseno.text
readonly property string lastname: lastname.text
readonly property string mobile: mobile.text
readonly property string phone: phone.text
readonly property string postcode: (postcode.editText ? postcode.editText : postcode.currentText) ?? ""
readonly property string street: street.text
readonly property string title: title.currentText
readonly property string country: (country.editText ? country.editText : country.currentText) ?? ""
}
spacing: Dimensions.l
IconLabel {
color: Colors.foreground
font: Typography.h2
icon.color: Colors.foreground
icon.height: Typography.h2.pixelSize
icon.source: "qrc:/images/UserCircle"
icon.width: Typography.h2.pixelSize
spacing: Dimensions.m
text: qsTr("Stammdaten")
}
RowLayout {
spacing: Dimensions.m
Field {
label: qsTr("Anrede")
ComboBox {
// property string name: "title"
id: title
implicitWidth: fieldM
model: [qsTr("Keine Angabe"), qsTr("Herr"), qsTr("Frau")]
onCurrentTextChanged: {
switch (title.currentIndex) {
case 1:
formofaddress.text = "Sehr geehrter Herr ";
break;
case 2:
formofaddress.text = "Sehr geehrte Frau ";
break;
default:
formofaddress.text = "Guten Tag ";
}
}
}
}
Field
{
label: qsTr("Vorname")
mandatory: true
TextField
{
// property string name: "firstname"
id: firstname
implicitWidth: fieldM
placeholderText: qsTr("Max")
validator: NotEmptyValidator {
}
}
}
Field {
label: qsTr("Nachname")
mandatory: true
TextField {
// property string name: "lastname"
id: lastname
implicitWidth: fieldM
placeholderText: qsTr("Mustermann")
validator: NotEmptyValidator {
}
}
}
}
RowLayout {
spacing: Dimensions.m
Field
{
label: qsTr("Straße")
mandatory: true
TextField
{
// property string name: "street"
id: street
implicitWidth: fieldM
placeholderText: qsTr("Musterstraße")
validator: NotEmptyValidator {
}
}
}
Field
{
mandatory: true
label: qsTr("Hausnummer")
TextField
{
// property string name: "houseno"
id: houseno
implicitWidth: fieldS
placeholderText: qsTr("1a")
validator: NotEmptyValidator {
}
}
}
Field
{
label: qsTr("PLZ")
mandatory: true
ComboBox
{
// property string name: "postcode"
id: postcode
currentIndex: -1
editable: true
implicitWidth: fieldS
model: address_model
textRole: "display"
onActivated: currentValue
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
validator: NotEmptyValidator {}
}
}
Field
{
label: qsTr("Ort")
mandatory: true
ComboBox
{
// property string name: "city"
id: city
currentIndex: -1
editable: true
implicitWidth: fieldM
model: address_model
textRole: "city"
validator: NotEmptyValidator {
}
}
}
Field
{
label: qsTr("Land")
mandatory: true
ComboBox
{
// property string name: "country"
id: country
currentIndex: 37
editable: true
implicitWidth: fieldM
model: address_model
textRole: "country"
}
}
}
IconLabel {
color: Colors.foreground
font: Typography.h2
icon.color: Colors.foreground
icon.height: Typography.h2.pixelSize
icon.source: "qrc:/images/Phone"
icon.width: Typography.h2.pixelSize
spacing: Dimensions.m
text: qsTr("Kontakt")
}
RowLayout {
spacing: Dimensions.m
Field {
label: qsTr("Telefonnummer")
TextField {
// property string name: "phone"
id: phone
implicitWidth: fieldM
placeholderText: "+49 1234 567890"
validator: OptionalPhoneNumberValidator {
}
}
}
Field
{
label: qsTr("Mobil")
TextField
{
// property string name: "mobile"
id: mobile
implicitWidth: fieldM
placeholderText: "+49 123 4567891011"
validator: OptionalPhoneNumberValidator {
}
}
}
Field
{
label: qsTr("E-Mail Adresse")
TextField
{
// property string name: "email"
id: email
implicitWidth: fieldM
placeholderText: "tero@example.org"
validator: OptionalEmailAddressValidator {
}
}
}
Field
{
label: qsTr("Briefanrede")
TextField
{
// property string name: "formofaddress"
id: formofaddress
implicitWidth: fieldM
}
}
}
}

View File

@@ -0,0 +1,51 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: bankAccount
columns: 2
property alias jobstatus: title
property alias longest: longest
Label
{
id: longest
text: qsTr("Beschäftigungsverhältnis")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "jobstatus"
id: title
Layout.fillWidth: true
editable: false
model: [qsTr("Vollzeit"), qsTr("Teilzeit"), qsTr("Minijob"), qsTr("Ausgeschieden")]
}
Label
{
text: qsTr("IBAN")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "iban"
id: iban
Layout.fillWidth: true
}
Label
{
text: qsTr("Bank")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "bank"
id: bankname
Layout.fillWidth: true
model: ["",qsTr("Sparkasse"),qsTr("Volksbank")]
editable: true
}
}

View File

@@ -16,12 +16,12 @@ Item
Button Button
{ {
text: qsTr("Mitarbeiter zeigen") text: qsTr("Mitarbeiter zeigen")
onClicked: employeesStack.pop() onClicked: contentStack.pop()
} }
} }
Component.onCompleted: Component.onCompleted:
{ {
business_model.onRowClicked(selectedEmployee) employee_model.onRowClicked(selectedEmployee)
} }
} }

View File

@@ -0,0 +1,263 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: nationalInsurance
columns: 2
Label
{
Layout.preferredWidth: bankAccount.longest.width
text: qsTr("Herkunftsland")
horizontalAlignment: Text.AlignRight
}
ComboBox
{
property string name: "country"
id: nation
Layout.fillWidth: true
editable: true
model: [qsTr("Deutschland"), qsTr("Syrien")]
}
Label
{
text: qsTr("Sozialversicherungs-Nr")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "socialno"
id: socialno
Layout.fillWidth: true
}
Label
{
text: qsTr("Steuer-ID")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "taxno"
id: taxnumber
Layout.fillWidth: true
}
Label
{
text: qsTr("Krankenkasse")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "medicalinsurance"
id: medicalinsurance
Layout.fillWidth: true
}
Label
{
text: qsTr("Knappschaft")
Layout.alignment: Qt.AlignRight
visible: bankAccount.jobstatus.currentText === "Minijob" ? 1:0
}
TextField
{
property string name: "knappschaft"
id: knappschaft
Layout.fillWidth: true
visible: bankAccount.jobstatus.currentText === "Minijob" ? 1:0
}
Label
{
text: qsTr("Ausweistyp")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "idtype"
id: idtype
Layout.fillWidth: true
editable: true
model: [qsTr("Personalausweis"), qsTr("Reisepass")]
}
Label
{
text: qsTr("Ausweis Nr.")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "idnumber"
id: idnumber
Layout.fillWidth: true
}
Label
{
text: qsTr("Ausweis gültig bis")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "idexpiry"
id: idexpiry
Layout.fillWidth: true
validator: RegularExpressionValidator
{
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
}
Keys.onPressed: (event)=>
{
if (event.key !== Qt.Key_Backspace)
{
var len = idexpiry.length
var bd = idexpiry.text
if (len === 2 || len === 5) idexpiry.text = bd + "."
}
}
}
Label
{
text: qsTr("Ausstellungsort")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "idauthority"
id: idauthority
Layout.fillWidth: true
}
Label
{
id: test
text: qsTr("Ausgestellt am")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "idissued"
id: idissued
Layout.fillWidth: true
validator: RegularExpressionValidator
{
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
}
Keys.onPressed: (event)=>
{
if (event.key !== Qt.Key_Backspace)
{
var len = idissued.length
var bd = idissued.text
if (len === 2 || len === 5) idissued.text = bd + "."
}
}
}
CheckBox
{
Layout.preferredWidth: bankAccount.longest.width
property string name: "worklicense"
id: worklicense
text: qsTr("Arbeitserlaubnis <font color='red'><b>?</b></font>")
visible: nation.currentText === "Deutschland"? false:true
}
CheckBox
{
property string name: "residencetype"
id: residencetype
text: qsTr("Aufenthaltstitel")
visible: nation.currentText === "Deutschland"? false:true
}
Label
{
text: qsTr("Aufenthaltstitel Nr.")
visible: residencetype.checked
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "residenceno"
id: residenceno
visible: residencetype.checked
Layout.fillWidth: true
}
Label
{
text: qsTr("Ausgestellt von")
visible: residencetype.checked
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "residenceauthority"
id: residenceauthority
visible: residencetype.checked
Layout.fillWidth: true
}
Label
{
text: qsTr("Ausgestellt am")
visible: residencetype.checked
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "residenceissued"
id: residenceissued
visible: residencetype.checked
Layout.fillWidth: true
validator: RegularExpressionValidator
{
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
}
Keys.onPressed: (event)=>
{
if (event.key !== Qt.Key_Backspace)
{
var len = residenceissued.length
var bd = residenceissued.text
if (len === 2 || len === 5) residenceissued.text = bd + "."
}
}
}
Label
{
text: qsTr("Gültig bis")
visible: residencetype.checked
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "residenceexpiry"
id: residenceexpiry
visible: residencetype.checked
Layout.fillWidth: true
validator: RegularExpressionValidator
{
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
}
Keys.onPressed: (event)=>
{
if (event.key !== Qt.Key_Backspace)
{
var len = residenceexpiry.length
var bd = residenceexpiry.text
if (len === 2 || len === 5) residenceexpiry.text = bd + "."
}
}
}
}

View File

@@ -0,0 +1,413 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import TeroStyle
GridLayout {
id: personalData
function checkPersonalField() {
return (firstname.text.trim() && lastname.text.trim() && street.text.trim() && houseno.text.trim() && (postcode.editText.trim() || postcode.currentText.trim()) && (city.editText.trim() || city.currentText.trim()) && birthday.text.trim() && phonenumber.text.trim() && cellphone.text.trim() && email.text.trim() && jobdescription.text.trim() && contractstart.text.trim() && contractend.text.trim() && briefAnrede.text.trim());
}
function requiredField() {
const pf = "Pflichtfeld";
street.placeholderText = pf;
phonenumber.placeholderText = pf;
cellphone.placeholderText = pf;
email.placeholderText = pf;
jobdescription.placeholderText = pf;
contractstart.placeholderText = pf;
contractend.placeholderText = pf;
briefAnrede.placeholderText = pf;
houseno.placeholderText = pf;
}
columns: 4
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Anrede")
}
ComboBox {
id: title
property string name: "title"
Layout.columnSpan: 3
Layout.fillWidth: true
editable: false
model: [qsTr("Keine Angabe"), qsTr("Herr"), qsTr("Frau")]
onCurrentTextChanged: {
switch (title.currentIndex) {
case 1:
briefAnrede.text = "Sehr geehrter Herr ";
break;
case 2:
briefAnrede.text = "Sehr geehrte Frau ";
break;
default:
briefAnrede.text = "Guten Tag ";
}
}
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Vorname*")
}
TextField {
id: firstname
property string name: "firstname"
Layout.columnSpan: 3
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Nachname*")
}
TextField {
id: lastname
property string name: "lastname"
Layout.columnSpan: 3
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Straße")
}
TextField {
id: street
property string name: "street"
Layout.fillWidth: true
placeholderTextColor: "red"
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Nr.")
}
TextField {
id: houseno
property string name: "houseno"
Layout.fillWidth: true
placeholderTextColor: "red"
validator: RegularExpressionValidator {
regularExpression: /([0-9a-zA-Z\-]{1,6})/
}
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("PLZ")
}
ComboBox {
id: postcode
property string name: "postcode"
Layout.fillWidth: true
currentIndex: -1
editable: true
model: address_model
popup.height: 300
textRole: "display"
validator: PostcodeValidator {
}
onActivated: currentValue
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
onCurrentTextChanged: checkFields()
onEditTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Ort")
}
ComboBox {
id: city
property string name: "city"
Layout.fillWidth: true
currentIndex: -1
editable: true
model: address_model
popup.height: 300
textRole: "city"
onCurrentTextChanged: checkFields()
onEditTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Geburtsname")
}
TextField {
id: birthname
property string name: "birthname"
Layout.columnSpan: 3
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Geburtsdatum*")
}
TextField {
id: birthday
property string name: "birthday"
Layout.columnSpan: 3
Layout.fillWidth: true
validator: RegularExpressionValidator {
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
}
Keys.onPressed: event => {
if (event.key !== Qt.Key_Backspace) {
var len = birthday.length;
var bd = birthday.text;
if (len === 2 || len === 5)
birthday.text = bd + ".";
}
}
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Geburtsort*")
}
TextField {
id: placeofbirth
property string name: "placeofbirth"
Layout.columnSpan: 3
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Telefonnummer")
}
TextField {
id: phonenumber
property string name: "phone"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
validator: RegularExpressionValidator {
regularExpression: /([+0-9]{1})([0-9]{1,17})/
}
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Mobil")
}
TextField {
id: cellphone
property string name: "mobile"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
validator: RegularExpressionValidator {
regularExpression: /([+0-9]{1})([0-9]{1,17})/
}
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("E-Mail")
}
TextField {
id: email
property string name: "email"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderText: qsTr("beispiel@domain.de")
placeholderTextColor: "red"
validator: EmailAddressValidator {
}
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Familienstand")
}
ComboBox {
id: maritalstatus
property string name: "maritalstatus"
Layout.columnSpan: 3
Layout.fillWidth: true
editable: false
model: [qsTr("ledig"), qsTr("verheiratet"), qsTr("verwitwet"), qsTr("geschieden")]
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Stundenlohn")
}
TextField {
id: salary
property string name: "salary"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
validator: RegularExpressionValidator {
regularExpression: /([0-9]{1,3})/
}
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Jobbeschreibung")
}
TextField {
id: jobdescription
property string name: "jobdesc"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Vertragsbeginn")
}
TextField {
id: contractstart
property string name: "contractstart"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
validator: RegularExpressionValidator {
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
}
Keys.onPressed: event => {
if (event.key !== Qt.Key_Backspace) {
var len = contractstart.length;
var bd = contractstart.text;
if (len === 2 || len === 5)
contractstart.text = bd + ".";
}
}
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Vertragsende")
}
TextField {
id: contractend
property string name: "contractend"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
validator: RegularExpressionValidator {
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
}
Keys.onPressed: event => {
if (event.key !== Qt.Key_Backspace) {
var len = contractend.length;
var bd = contractend.text;
if (len === 2 || len === 5)
contractend.text = bd + ".";
}
}
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Arbeitszeiten Tage")
}
ComboBox {
id: workdays
property string name: "workdays"
Layout.fillWidth: true
model: ["1", "2", "3", "4", "5", "6", "7"]
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Stunden")
}
ComboBox {
id: workhours
property string name: "workhours"
Layout.fillWidth: true
model: ["1", "2", "3", "4", "5", "6", "7", "8"]
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Briefanrede")
}
TextField {
id: briefAnrede
property string name: "formofaddress"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
onTextChanged: checkFields()
}
Item {
Layout.columnSpan: 4
Layout.fillHeight: true
}
}

View File

@@ -4,26 +4,32 @@ import QtQuick.Layouts
GridLayout GridLayout
{ {
id: applicantVarious
columns: 2 columns: 2
Label Label
{ {
Layout.preferredWidth: bankAccount.longest.width
text: qsTr("Grad der Behinderung") text: qsTr("Grad der Behinderung")
horizontalAlignment: Text.AlignRight
} }
TextField TextField
{ {
id: behinderung property string name: "disability"
id: disability
placeholderText: "0,0" placeholderText: "0,0"
Layout.fillWidth: true
} }
Label Label
{ {
text: qsTr("Disponent") text: qsTr("Disponent")
Layout.alignment: Qt.AlignRight
} }
TextField TextField
{ {
property string name: "disponent"
id: disponent id: disponent
Layout.fillWidth: true Layout.fillWidth: true
} }
@@ -31,22 +37,26 @@ GridLayout
Label Label
{ {
text: qsTr("Kostenstelle") text: qsTr("Kostenstelle")
Layout.alignment: Qt.AlignRight
} }
TextField TextField
{ {
id: kostenstelle property string name: "office"
id: office
Layout.fillWidth: true Layout.fillWidth: true
} }
Label Label
{ {
text: qsTr("Fremdlohn-Nr.") text: qsTr("Fremdlohn-Nr.")
Layout.alignment: Qt.AlignRight
} }
TextField TextField
{ {
id: fremdLohnNummer property string name: "empreference"
id: empreference
Layout.fillWidth: true Layout.fillWidth: true
} }
} }

View File

@@ -0,0 +1,141 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout {
spacing: Dimensions.l
RowLayout {
Layout.fillWidth: true
spacing: Dimensions.l
SearchBar {
}
QuickFilter {
model: ListModel {
ListElement {
name: "Alle"
selected: true
text: qsTr("Alle")
}
ListElement {
name: "Bewerber"
selected: false
text: qsTr("Bewerber")
}
ListElement {
name: "Mitarbeiter"
selected: false
text: qsTr("Mitarbeiter")
}
ListElement {
name: "Erledigt"
selected: false
text: qsTr("Erledigt")
}
}
onSelectedChanged: name => {
employee_model.viewCriterion(name);
}
}
Button {
Layout.alignment: Qt.AlignRight
flat: true
icon.source: "qrc:/images/PlusCircle.svg"
text: qsTr("Bewerber Hinzufügen")
onClicked: contentStack.push("AddApplicant.qml")
}
Button {
Layout.alignment: Qt.AlignRight
flat: true
icon.source: "qrc:/images/PlusCircle.svg"
text: qsTr("Mitarbeiter Hinzufügen")
onClicked: contentStack.push("AddEmployee.qml")
}
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
spacing: 2
HorizontalHeaderView {
movableColumns: true
syncView: employeesTable
delegate: Rectangle {
Layout.fillWidth: true
color: Colors.primary
implicitHeight: 33
implicitWidth: 1
Text {
color: Colors.primaryContrast
elide: Text.ElideRight
font: Typography.smallBold
height: parent.height
horizontalAlignment: Text.AlignLeft
padding: Dimensions.s
text: model.display
verticalAlignment: Text.AlignVCenter
width: parent.width
}
}
}
TableView {
id: employeesTable
Layout.fillHeight: true
Layout.fillWidth: true
columnSpacing: 2
model: employee_model
resizableColumns: true
rowSpacing: 2
selectionBehavior: TableView.SelectRows
z: 1
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
delegate: Rectangle {
required property bool selected
color: selected ? Colors.primaryHighlight : Colors.transparent
implicitHeight: 33
implicitWidth: employeesTable.width / employeesTable.columns
Text {
color: Colors.foreground
elide: Text.ElideRight
font: Typography.small
height: parent.height
padding: Dimensions.s
text: (model.display === null || model.display === undefined) ? "" : model.display
verticalAlignment: Text.AlignVCenter
width: parent.width
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: {
contentStack.push("EmployeeDetails.qml", {
selectedEmployee: row
});
}
onEntered: {
employeesTable.selectionModel.select(employeesTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows);
}
}
}
selectionModel: ItemSelectionModel {
model: employeesTable.model
}
}
}
}

1
Gui/Employees/qmldir Normal file
View File

@@ -0,0 +1 @@
module Employees

View File

@@ -1,132 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
Item
{
property var availableFilters: ["Name", "Adresse", "PLZ", "Ort", "Status"]
SearchBar
{
id:searchBar
anchors.margins: 9
}
Button
{
id: addEmployeeBtn
icon.source: "qrc:/images/addbusiness.svg"
icon.color: "olive"
anchors.right: parent.right
flat: true
onClicked: appLoader.source = "AddApplicant.qml"
}
ColumnLayout
{
anchors
{
top: searchBar.bottom
bottom: parent.bottom
left: parent.left
right: parent.right
}
RowLayout
{
RadioButton
{
checked: true
text: qsTr("Alle")
}
RadioButton
{
text: qsTr("Bewerber")
}
RadioButton
{
text: qsTr("Mitarbeiter")
}
RadioButton
{
text: qsTr("Erledigt")
}
RadioButton
{
text: qsTr("Ausgeschieden")
}
}
HorizontalHeaderView
{
id: horizontalHeader
Layout.fillWidth: true
syncView: testTable
}
TableView
{
id: testTable
Layout.fillHeight: true
Layout.fillWidth: true
columnSpacing: 1
rowSpacing: 2
model: business_model
selectionBehavior: TableView.SelectRows
selectionModel: ItemSelectionModel
{
id: selModel
model: testTable.model
}
delegate:Rectangle
{
required property bool selected
required property bool current
implicitWidth: 200
implicitHeight: 25
color: selected? "lightblue": palette.base
Text
{
Layout.fillWidth: true
text: model.display? model.display: ""
}
MouseArea
{
id: mouseArea
property bool hovered:false
anchors.fill: parent
hoverEnabled: true
onDoubleClicked:
{
employeesStack.push("EmployeeDetails.qml", {selectedEmployee: row});
}
}
}
}
}
Component.onCompleted: employeesStack.pop()
}

View File

@@ -7,11 +7,14 @@ import QtCore
import "../js/qmldict.js" as Qmldict import "../js/qmldict.js" as Qmldict
Item Item
{ {
property string recpass: "" property string recpass: ""
property bool adminAvailable: true property bool adminAvailable: true
id: firstStartItem
anchors.fill: parent anchors.fill: parent
StackView StackView
{ {
@@ -70,12 +73,11 @@ Item
MessageDialog MessageDialog
{ {
id: recoveryDialog id: recoveryDialog
text: qsTr("Diesen Wiederherstellungscode musst du sicher aufbewahren!\nMöchtest du das jetzt machen?") text: qsTr("Diesen Wiederherstellungscode musst du sicher aufbewahren!\nMöchtest du das jetzt machen?")
title: qsTr("Wiederherstellen") title: qsTr("Wiederherstellen")
buttons: MessageDialog.Yes | MessageDialog.No buttons: MessageDialog.Yes | MessageDialog.No
onAccepted: recoveryPaswordDialog.open() onAccepted: recoveryPaswordDialog.open()
onRejected: gotoLogin() onRejected: contentStack.replace("LoginSreen.qml")
} }
MessageDialog MessageDialog
@@ -87,6 +89,7 @@ Item
Dialog Dialog
{ {
id: recoveryPaswordDialog id: recoveryPaswordDialog
modal: true modal: true
title: qsTr("Wiederherstellung") title: qsTr("Wiederherstellung")
@@ -115,6 +118,19 @@ Item
implicitWidth: 300 implicitWidth: 300
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben") placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
} }
Label
{
text: qsTr("Wiederherstellungspasswort eingeben: ")
}
TextField
{
id: repeatRecoveryPaswordInput
text: ""
echoMode: TextInput.Password
implicitWidth: 300
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
}
} }
} }
} }
@@ -131,7 +147,7 @@ Item
if (!adminAvailable) config.saveRecoveryKey(saveRecoveryDialog.currentFile, recpass) if (!adminAvailable) config.saveRecoveryKey(saveRecoveryDialog.currentFile, recpass)
else config.getRecoveryKey(saveRecoveryDialog.currentFile, recpass) else config.getRecoveryKey(saveRecoveryDialog.currentFile, recpass)
gotoLogin() contentStack.replace("LoginSreen.qml")
} }
onRejected: onRejected:
@@ -140,6 +156,12 @@ Item
} }
} }
Loader
{
id: utilityDialogs
source: "UtilityDialogs.qml"
}
Component.onCompleted: Component.onCompleted:
{ {
config.dbConnectionError.connect(onDbConnectionError) config.dbConnectionError.connect(onDbConnectionError)
@@ -147,15 +169,10 @@ Item
config.backupEncryptionKey.connect(onBackupEncryptionKey) config.backupEncryptionKey.connect(onBackupEncryptionKey)
} }
function gotoLogin()
{
appLoader.source= "LoginScreen.qml"
topBar.visible = true
}
function onBackupEncryptionKey() function onBackupEncryptionKey()
{ {
recoveryDialog.open()
utilityDialogs.item.recoveryDialog.open()
} }
function onDbConnectionError(msg, success) function onDbConnectionError(msg, success)
@@ -176,5 +193,4 @@ Item
firstStart.push("AdminUserConfig.qml") firstStart.push("AdminUserConfig.qml")
} }
} }
} }

View File

@@ -4,210 +4,134 @@ import QtQuick.Controls
import QtQuick.Dialogs import QtQuick.Dialogs
import QtQuick.Layouts import QtQuick.Layouts
Item {
Item
{
property string recpass: "" property string recpass: ""
anchors.fill: parent
ColumnLayout function dbConnectionFailed(msg) {
{ notifications.notificationDialog.informativeText = msg;
notifications.notificationDialog.text = "Verbindung zum Datenbankserver verloren";
anchors.fill: parent notifications.notificationDialog.open();
}
FontLoader function getEncryptionKey() {
{ recoveryPaswordDialog.open();
id: helloStranger }
source: "qrc:/fonts/HelloStranger.otf" function loggedin() {
contentStack.replace("Dashboard.qml");
} }
FontLoader // anchors.fill: parent
{ // anchors.topMargin: Dimensions.l
id: damarWulan
source: "qrc:/fonts/Damarwulan.ttf" Component.onCompleted: {
loggedin_user.loginOkay.connect(loggedin);
config.invalidEncryptionKey.connect(getEncryptionKey);
config.checkEncryptionKey();
loggedin_user.noDbConnection.connect(dbConnectionFailed);
benutzerName.forceActiveFocus();
} }
FontLoader ColumnLayout {
{
id: hussarPrint
source: "qrc:/fonts/HussarPrintA.otf"
}
FontLoader
{
id: reginaldScript
source: "qrc:/fonts/ReginaldScript.ttf"
}
Item
{
height: 65
}
Label
{
text: qsTr ("Login*****")
font.family: helloStranger.font.family
font.weight: helloStranger.font.weight
font.styleName: helloStranger.font.styleName
font.pixelSize: 89
font.bold: true
Layout.alignment: Qt.AlignHCenter
}
Item
{
height: 25
}
RowLayout
{
Layout.alignment: Qt.AlignHCenter
spacing: 15
Label
{
text: qsTr ("Benutzername")
minimumPixelSize: 20
Layout.preferredWidth: 150
horizontalAlignment: Text.AlignRight
font.family: damarWulan.font.family
font.weight: damarWulan.font.weight
font.styleName: damarWulan.font.styleName
font.pixelSize: 21
}
TextField
{
id: benutzerName
placeholderText: qsTr ("Benutzernamen eingeben")
implicitWidth: 300
font: hussarPrint.font
}
}
RowLayout
{
Layout.alignment: Qt.AlignHCenter
spacing: 15
Label
{
minimumPixelSize: 20
Layout.preferredWidth: 150
text: qsTr ("Passwort")
font.family: damarWulan.font.family
font.weight: damarWulan.font.weight
font.styleName: damarWulan.font.styleName
font.pixelSize: 21
horizontalAlignment: Text.AlignRight
}
TextField
{
id: passwort
placeholderText: qsTr ("Passwort eingeben")
implicitWidth: 300
font: hussarPrint.font
echoMode: TextInput.Password
}
}
RowLayout
{
Layout.preferredWidth: 465
Layout.alignment: Qt.AlignHCenter
Button
{
text: qsTr ("Feierabend für heute!")
Layout.alignment: Qt.AlignRight
font: reginaldScript.font
onClicked:
{
if (benutzerName.text.trim() && passwort.text.trim())
loggedin_user.login(benutzerName.text.trim(), passwort.text)
}
}
}
Item
{
Layout.fillHeight: true
}
Dialog
{
id: recoveryPaswordDialog
modal: true
title: qsTr("Wiederherstellung")
anchors.centerIn: parent anchors.centerIn: parent
spacing: Dimensions.m
Label {
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: Dimensions.l
font: Typography.h1
text: qsTr("Login")
}
Field {
label: qsTr("Benutzername")
TextField {
id: benutzerName
focus: true
implicitWidth: 300
placeholderText: qsTr("Benutzernamen eingeben")
onAccepted: {
if (benutzerName.text.trim() && passwort.text.trim())
loggedin_user.login(benutzerName.text.trim(), passwort.text);
else if (benutzerName.text.trim())
passwort.forceActiveFocus();
}
}
}
Field {
label: qsTr("Passwort")
TextField {
id: passwort
echoMode: TextInput.Password
implicitWidth: 300
placeholderText: qsTr("Passwort eingeben")
onAccepted: {
if (benutzerName.text.trim() && passwort.text.trim())
loggedin_user.login(benutzerName.text.trim(), passwort.text);
else if (passwort.text.trim())
benutzerName.forceActiveFocus();
}
}
}
Button {
Layout.topMargin: Dimensions.m
icon.source: "qrc:/images/ArrowRightEndOnRectangle.svg"
implicitWidth: parent.width
text: qsTr("Login")
onClicked: {
if (benutzerName.text.trim() && passwort.text.trim())
loggedin_user.login(benutzerName.text.trim(), passwort.text);
}
}
Item {
Layout.fillHeight: true
}
Dialog {
id: recoveryPaswordDialog
anchors.centerIn: parent
modal: true
standardButtons: Dialog.Ok | Dialog.Cancel standardButtons: Dialog.Ok | Dialog.Cancel
onAccepted: title: qsTr("Wiederherstellung")
{
recpass = recoveryPaswordInput.text onAccepted: {
getRecoveryDialog.open() recpass = recoveryPaswordInput.text;
getRecoveryDialog.open();
} }
ColumnLayout ColumnLayout {
{ RowLayout {
RowLayout Label {
{
Label
{
text: qsTr("Wiederherstellungspasswort eingeben: ") text: qsTr("Wiederherstellungspasswort eingeben: ")
} }
TextField {
TextField
{
id: recoveryPaswordInput id: recoveryPaswordInput
text: ""
echoMode: TextInput.Password echoMode: TextInput.Password
implicitWidth: 300 implicitWidth: 300
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben") placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
text: ""
} }
} }
} }
} }
FileDialog {
FileDialog
{
id: getRecoveryDialog id: getRecoveryDialog
title: qsTr("Wiederherstellungsdatei")
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
fileMode: FileDialog.OpenFile fileMode: FileDialog.OpenFile
nameFilters: ["PYQCRM Recovery files (*.pyqrec)"] nameFilters: ["PYQCRM Recovery files (*.pyqrec)"]
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0] title: qsTr("Wiederherstellungsdatei")
onAccepted: config.getRecoveryKey(getRecoveryDialog.currentFile, recpass) onAccepted: config.getRecoveryKey(getRecoveryDialog.currentFile, recpass)
onRejected: quit() onRejected: quit()
} }
Notifications Notifications {
{ id: notifications
id: oschkar
} }
} }
Component.onCompleted:
{
loggedin_user.loginOkay.connect(loggedin)
config.invalidEncryptionKey.connect(getEncryptionKey)
config.checkEncryptionKey()
loggedin_user.noDbConnection.connect(dbConnectionFailed)
}
function loggedin()
{
appLoader.source = "Dashboard.qml"
}
function getEncryptionKey()
{
recoveryPaswordDialog.open()
}
function dbConnectionFailed(msg)
{
oschkar.notificationBox.informativeText = msg
oschkar.notificationBox.text = "Verbindung zum Datenbankserver verloren"
oschkar.notificationBox.open()
}
} }

22
Gui/MiscConf.qml Executable file
View File

@@ -0,0 +1,22 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ColumnLayout
{
property alias sysTray: sysTray
anchors.fill: parent
anchors.topMargin: 35
Switch
{
id: sysTray
text: qsTr("Beim minimieren, in der Taskleiste anzeigen")
checked: config.systray()
}
Item
{
Layout.fillHeight: true
}
}

120
Gui/Navigation.qml Normal file
View File

@@ -0,0 +1,120 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ColumnLayout {
property bool onSubPage: false
height: parent.height
spacing: 0
z: 3
Component.onCompleted: {
onSubPage = Qt.binding(() => contentStack.depth > 1);
}
anchors {
left: parent.left
top: parent.top
}
ButtonGroup {
id: mainNav
}
BarButton {
ButtonGroup.group: mainNav
icon.source: "qrc:/images/Square3Stack3D-Outline.svg"
target: "/Gui/Dashboard.qml"
text: qsTr("Dashboard")
visible: !onSubPage
}
BarButton {
ButtonGroup.group: mainNav
icon.source: "qrc:/images/UserGroup-Outline.svg"
target: "/Gui/Customer/CustomersTable.qml"
text: qsTr("Kunden")
visible: !onSubPage
}
BarButton {
ButtonGroup.group: mainNav
icon.source: "qrc:/images/BuildingOffice2-Outline.svg"
target: "/Gui/Objects/ObjectsTable.qml"
text: qsTr("Objekt")
visible: !onSubPage
}
BarButton {
ButtonGroup.group: mainNav
icon.source: "qrc:/images/Identification-Outline.svg"
target: "/Gui/Employees/EmployeesTable.qml"
text: qsTr("Mitarbeiter")
visible: !onSubPage
}
BarButton {
ButtonGroup.group: mainNav
icon.source: "qrc:/images/RectangleStack-Outline.svg"
target: "/Gui/Offers/OffersTable.qml"
text: qsTr("Angebote")
visible: !onSubPage
}
BarButton {
ButtonGroup.group: mainNav
icon.source: "qrc:/images/Wallet-Outline.svg"
text: qsTr("Abrechnung")
visible: !onSubPage
}
BarButton {
icon.source: "qrc:/images/ArrowLeftCircle-Outline.svg"
text: qsTr("Zurück")
visible: onSubPage
checkable: false
onClicked: contentStack.pop();
}
Item {
Layout.fillHeight: true
}
BarButton {
checkable: false
icon.source: "qrc:/images/Bars3.svg"
onClicked: mainMenu.open()
Menu {
id: mainMenu
MenuItem {
text: qsTr("Einstellungen")
onTriggered: {
// TODO: Check if logged-in user is admin first!!
contentStack.push("PyqcrmConf.qml");
}
}
MenuSeparator {
}
MenuItem {
text: qsTr("Als PDF exportieren")
}
MenuSeparator {
}
MenuItem {
text: qsTr("Drucken")
}
MenuItem {
text: qsTr("Erweiterter Druck")
onTriggered: printerDialog.show()
}
MenuSeparator {
}
MenuItem {
text: qsTr("Über PYQCRM")
onTriggered: readMeWin.show()
}
}
}
}

View File

@@ -1,74 +1,27 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts
Rectangle ColumnLayout {
{
anchors.fill: parent
color: "slateblue"
Rectangle
{
id: info
anchors.horizontalCenter: parent.horizontalCenter
color: "slateblue"
implicitHeight: 55
implicitWidth: parent.width / 4
y: parent.height / 4
Text
{
anchors.centerIn: parent anchors.centerIn: parent
spacing: Dimensions.s
height: implicitHeight
H1 {
Layout.alignment: Qt.AlignCenter
text: qsTr("Keine Verbindung zur Datenbank!") text: qsTr("Keine Verbindung zur Datenbank!")
color: "moccasin" color: Colors.foreground
font.bold: true
font.pixelSize: 45
} }
H2 {
Layout.alignment: Qt.AlignCenter
text: qsTr("Programm kann nicht starten…")
color: Colors.foreground
} }
Button {
Rectangle Layout.topMargin: Dimensions.l
{ Layout.alignment: Qt.AlignCenter
id: nostart
anchors.top: info.bottom
color: "slateblue"
anchors.horizontalCenter: parent.horizontalCenter
implicitHeight: 55
implicitWidth: parent.width / 4
Text
{
text: qsTr("Programm kann nicht starten..")
color: "moccasin"
anchors.centerIn: parent
font.bold: true
font.pixelSize: 45
}
}
Rectangle
{
anchors.top: nostart.bottom
anchors.topMargin: 25
anchors.horizontalCenter: parent.horizontalCenter
color: "slateblue"
implicitHeight: 55
implicitWidth: parent.width / 4
Button
{
width: parent.width
height: 75
Text
{
text: qsTr("Beenden") text: qsTr("Beenden")
color: "moccasin"
anchors.centerIn: parent
font.bold: true
font.pixelSize: 45
}
anchors.centerIn: parent
background: Rectangle
{
color: "dodgerblue"
radius: 50
}
onClicked: Qt.quit() onClicked: Qt.quit()
} }
} }
}

View File

@@ -3,8 +3,6 @@ import QtQuick.Dialogs
Item Item
{ {
id: oschkar
property alias notificationBox: notificationDialog
MessageDialog MessageDialog
{ {
id: notificationDialog id: notificationDialog

View File

@@ -6,13 +6,22 @@ GridLayout
{ {
property var contacts: null property var contacts: null
columns: 2 columns: 2
Layout.fillWidth: true
CheckBox Label
{ {
id: contactperson text: qsTr("Position")
text: qsTr("Ansprechpartner") Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.columnSpan: 2
} }
ComboBox
{
//property string name: "contacttype"
id: posizion
Layout.fillWidth: true
editable: false
model: [qsTr("Beirat"), qsTr("Hausmeister"), qsTr("Hausbewohner"), qsTr("Sonstiges")]
}
Label Label
{ {
text: qsTr("Anrede") text: qsTr("Anrede")
@@ -21,61 +30,49 @@ GridLayout
ComboBox ComboBox
{ {
id: title id: title
model: [qsTr("Herr"),qsTr("Frau")] model: [qsTr("Herr"), qsTr("Frau"), qsTr("Keine Angabe")]
Layout.fillWidth: true Layout.fillWidth: true
enabled: contactperson.checked
} }
Label Label
{ {
text: qsTr("Vorname") text: qsTr("Vorname*")
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField TextField
{ {
id: firstname id: firstname
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: "Pflichtfeld" // onTextChanged: checkContactFields()
placeholderTextColor: "red"
enabled: contactperson.checked
} }
Label Label
{ {
text: qsTr("Nachname") text: qsTr("Nachname*")
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField TextField
{ {
id: lastname id: lastname
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
enabled: contactperson.checked
} }
Label Label
{ {
text: qsTr("Telefonnummer") text: mobile.text ? qsTr("Telefonnummer") : qsTr("Telefonnummer*")
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField TextField
{ {
id: phonenumber id: phonenumber
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
enabled: contactperson.checked
} }
Label Label
{ {
text: qsTr("Position") text: phonenumber.text ? qsTr("Mobil") : qsTr("Mobil*")
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField TextField
{ {
id: posizion id: mobile
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
enabled: contactperson.checked
} }
RowLayout RowLayout
@@ -92,34 +89,60 @@ GridLayout
{ {
id: removeContact id: removeContact
text: qsTr("Entfernen") text: qsTr("Entfernen")
enabled: contactperson.checked enabled: false
onClicked:
{
if (contactView.highlightFollowsCurrentItem)
{
delete contacts[contactView.currentIndex]
contacts = contacts.filter(elm => elm)
contactModel.remove(contactView.currentIndex)
contactView.highlightFollowsCurrentItem = false
contactView.currentIndex = -1
if (Object.keys(contacts).length === 0)
{
enabled = false
console.log(contacts)
}
checkFields()
}
}
} }
Button Button
{ {
id: addContact id: addContact
text: qsTr("Hinzufügen") text: qsTr("Hinzufügen")
enabled: contactperson.checked enabled: firstname.text.trim() && lastname.text.trim() && (phonenumber.text.trim() || mobile.text.trim()) && (contacts === null || Object.keys(contacts).length < 3)
onClicked: onClicked:
{ {
var num_contacts = 0 var num_contacts = 0
if (contacts !== null && contacts !== undefined) num_contacts = Object.keys(contacts).length if (contacts !== null && contacts !== undefined) num_contacts = Object.keys(contacts).length
else contacts = {} else contacts = []
if (num_contacts < 3 && firstname.text.trim() !== "" && lastname.text.trim() !== "" && phonenumber.text.trim() !== "" && posizion.text.trim() !== "") if (num_contacts < 3 && firstname.text.trim() !== "" && lastname.text.trim() !== "" && (phonenumber.text.trim() !== "" || mobile.text.trim() !== ""))
{ {
contacts[num_contacts] = {} contacts[num_contacts] = {}
contacts[num_contacts]["title"] = title.currentText contacts[num_contacts]["title"] = title.currentText
contacts[num_contacts]["position"] = posizion.currentText
contacts[num_contacts]["fname"] = firstname.text.trim() contacts[num_contacts]["fname"] = firstname.text.trim()
contacts[num_contacts]["lname"] = lastname.text.trim() contacts[num_contacts]["lname"] = lastname.text.trim()
contacts[num_contacts]["phone"] = phonenumber.text.trim() contacts[num_contacts]["phone"] = phonenumber.text.trim()
contacts[num_contacts]["position"] = posizion.text.trim() contacts[num_contacts]["mobile"] = mobile.text.trim()
contactModel.append({name: title.currentText + " " + firstname.text.trim() + " " + lastname.text.trim(), phone: phonenumber.text.trim(), mobile: mobile.text.trim(), posizion: posizion.currentText})
contactModel.append({name: title.currentText + " " + firstname.text.trim() + " " + lastname.text.trim(), phone: phonenumber.text.trim(), posizion: posizion.text.trim()}) if (checkFields())
{
saveBtn.enabled = true
}
firstname.text = "" firstname.text = ""
lastname.text = "" lastname.text = ""
phonenumber.text = "" phonenumber.text = ""
posizion.text = "" mobile.text = ""
posizion.currentIndex = 0
title.currentIndex = 0
removeContact.enabled = true
checkFields()
} }
} }
} }
@@ -136,86 +159,159 @@ GridLayout
id: contactModel id: contactModel
} }
// Component
// {
// id: headline
// Row
// {
// spacing: 9
// Text
// {
// id: cpname
// text: qsTr("Name")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// Text
// {
// id: cpphone
// text: qsTr("Telefon")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// Text
// {
// id: cpmobile
// text: qsTr("Mobil")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// Text
// {
// id: cppos
// text: qsTr("Position")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// Text
// {
// id: cttype
// text: qsTr("Typ")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// }
// }
Component Component
{ {
id: headline id: highlight
Row Rectangle
{ {
Text width: parent.width
color: "lightsteelblue"; radius: 5
y: contactView.currentItem.y
Behavior on y
{ {
id: cpname SpringAnimation
text: qsTr("Name") {
width: 175 spring: 3
font.bold: true damping: 0.2
horizontalAlignment: Text.AlignLeft
color: "black"
} }
Text
{
id: cpphone
text: qsTr("Telefon")
width: 100
font.bold: true
horizontalAlignment: Text.AlignLeft
color: "black"
}
Text
{
id: cppos
text: qsTr("Position")
width: 150
font.bold: true
horizontalAlignment: Text.AlignLeft
color: "black"
} }
} }
} }
Rectangle Rectangle
{ {
id: mainRect
Layout.fillWidth: true Layout.fillWidth: true
implicitHeight: 100 implicitHeight: 100
color: firstname.palette.base color: firstname.palette.base
border.color: firstname.activeFocus? firstname.palette.highlight: firstname.palette.base border.color: firstname.activeFocus? firstname.palette.highlight: firstname.palette.base
clip: true
ScrollView
{
id: objContactView
// Layout.fillWidth: true
// Layout.preferredHeight: 100
//Layout.columnSpan: 3
anchors.fill: mainRect
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
ListView ListView
{ {
id: contactView id: contactView
implicitHeight: parent.height anchors.fill: objContactView
// implicitHeight: objContactView.height
// implicitWidth: objContactView.width
model: contactModel model: contactModel
// header: headline
header: headline highlight: Rectangle { color: "slategray"; radius: 3}
highlightFollowsCurrentItem: false
//focus: true test
onActiveFocusChanged: if(!focus) currentIndex = -1
delegate: Item delegate: Item
{ {
width: parent.width width: contactView.width
height: 15 height: 77
Row MouseArea
{ {
//spacing: 9 anchors.fill: parent
Text onClicked:
{ {
text: model.name contactView.currentIndex = index
width: 175 contactView.highlightFollowsCurrentItem = true
horizontalAlignment: Text.AlignLeft }
} }
Text
{
text: model.phone Column
width: 100 {
horizontalAlignment: Text.AlignLeft anchors.margins: 5
}
Text //spacing: 3
{ Text
text: model.posizion {
width: 150 text: '<b>' + qsTr('Name: ') + '</b>' + model.name
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
} color: "white"
} }
} Text
} {
text: '<b>' + qsTr('Telefon: ') + '</b>' + model.phone
horizontalAlignment: Text.AlignLeft
color: "white"
}
Text
{
text: '<b>' + qsTr('Handy: ') + '</b>' + model.mobile
horizontalAlignment: Text.AlignLeft
color: "white"
}
Text
{
text: '<b>' + qsTr('Position: ') + '</b>' + model.posizion
horizontalAlignment: Text.AlignLeft
color: "white"
}
} // Column
} // delegate
} // Listview
} // Scrollview
} }
} }

View File

@@ -4,120 +4,120 @@ import QtQuick.Controls
GridLayout GridLayout
{ {
property var employeeForm: null // property var employeeForm: null
property var employees: null // property var employees: null
id: oaoemployee // id: oaoemployee
columns: 2 // columns: 2
rows: 4 // rows: 4
Label // Label
{ // {
text: qsTr("Mitarbeiter") // text: qsTr("Mitarbeiter")
Layout.alignment: Qt.AlignRight | Qt.AlignTop // Layout.alignment: Qt.AlignRight | Qt.AlignTop
} // }
ListModel // ListModel
{ // {
id: employeeModel // id: employeeModel
} // }
Component // Component
{ // {
id: employeesHeader // id: employeesHeader
Row // Row
{ // {
Text // Text
{ // {
id: empName // id: empName
text: qsTr("Mitarbeiter") // text: qsTr("Mitarbeiter")
width: 175 // width: 175
font.bold: true // font.bold: true
horizontalAlignment: Text.AlignLeft // horizontalAlignment: Text.AlignLeft
color: "black" // color: "black"
} // }
} // }
} // }
Rectangle // Rectangle
{ // {
Layout.fillWidth: true // Layout.fillWidth: true
implicitHeight: 75 // implicitHeight: 75
Layout.rowSpan: 2 // Layout.rowSpan: 2
color: mitarbeiterhin.palette.base // color: mitarbeiterhin.palette.base
border.color: mitarbeiterhin.activeFocus? mitarbeiterhin.palette.highlight: mitarbeiterhin.palette.base // border.color: mitarbeiterhin.activeFocus? mitarbeiterhin.palette.highlight: mitarbeiterhin.palette.base
ListView // ListView
{ // {
id: employeesList // id: employeesList
//anchors.fill: parent // //anchors.fill: parent
implicitHeight: parent.height // implicitHeight: parent.height
model: employeeModel // model: employeeModel
header: employeesHeader // header: employeesHeader
delegate: Row // delegate: Row
{ // {
width: 200 // width: 200
height: 15 // height: 15
//padding: 7 // //padding: 7
Text // Text
{ // {
text: model.namens // text: model.namens
} // }
} // }
} // }
} // }
RowLayout // RowLayout
{ // {
Layout.columnSpan: 2 // Layout.columnSpan: 2
Layout.fillWidth: true // Layout.fillWidth: true
Item // Item
{ // {
Layout.fillWidth: true // Layout.fillWidth: true
} // }
Button // Button
{ // {
id: mitarbeiterraus // id: mitarbeiterraus
text: qsTr("Mitarbeiter entfernen") // text: qsTr("Mitarbeiter entfernen")
} // }
Button // Button
{ // {
id: mitarbeiterhin // id: mitarbeiterhin
text: qsTr("Mitarbeiter hinzufügen") // text: qsTr("Mitarbeiter hinzufügen")
onClicked: // onClicked:
{ // {
var nm = Qt.createComponent("AddObjectEmployee.qml") // var nm = Qt.createComponent("AddObjectEmployee.qml")
if (nm.status === Component.Ready) // if (nm.status === Component.Ready)
{ // {
employeeForm = nm.createObject (appWindow, {width: 600, height: 400}) // employeeForm = nm.createObject (appWindow, {width: 600, height: 400})
employeeForm.addNewEmployee.connect(onAddEmployee) // employeeForm.addNewEmployee.connect(onAddEmployee)
employeeForm.show() // employeeForm.show()
} // }
else console.log(nm.errorString()) // else console.log(nm.errorString())
} // }
} // }
} // }
function onAddEmployee(new_employee) // function onAddEmployee(new_employee)
{ // {
var num_employees = 0 // var num_employees = 0
if (employees === null || employees === undefined) employees = {} // if (employees === null || employees === undefined) employees = {}
else num_employees = Object.keys(employees).length; // else num_employees = Object.keys(employees).length;
employees[num_employees] = {} // employees[num_employees] = {}
employees[num_employees]["assignee"] = new_employee["assignee"]; // employees[num_employees]["assignee"] = new_employee["assignee"];
employees[num_employees]["duration"] = new_employee["duration"]; // employees[num_employees]["duration"] = new_employee["duration"];
employees[num_employees]["wage"] = new_employee["wage"]; // employees[num_employees]["wage"] = new_employee["wage"];
employees[num_employees]["cleandays"] = new_employee["cleandays"]; // employees[num_employees]["cleandays"] = new_employee["cleandays"];
employees[num_employees]["tasks"] = new_employee["tasks"]; // employees[num_employees]["tasks"] = new_employee["tasks"];
employees[num_employees]["output"] = new_employee["output"]; // employees[num_employees]["output"] = new_employee["output"];
employeeModel.append({namens: new_employee["assignee"]}); // employeeModel.append({namens: new_employee["assignee"]});
} // }
} }

View File

@@ -1,19 +1,17 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
import Js
Frame Frame
{ {
property alias contactPerson: oaocontactperson
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
Layout.fillWidth: true Layout.fillWidth: true
ColumnLayout ColumnLayout
{ {
id: addObjectLayout id: addObjectLayout
width: parent.width width: parent.width
ObjectAddOnEmployee
{
id: oaoemployee
}
ObjectAddOnContactPerson ObjectAddOnContactPerson
{ {
id: oaocontactperson id: oaocontactperson
@@ -23,4 +21,8 @@ Frame
Layout.fillHeight: true Layout.fillHeight: true
} }
} }
function getForm()
{
return oaocontactperson.contacts
}
} }

View File

@@ -15,13 +15,13 @@ Item
Button Button
{ {
text: qsTr("Objekts zeigen") text: qsTr("Zurück zu den Objekten")
onClicked: customersStack.pop() onClicked: contentStack.pop()
} }
} }
Component.onCompleted: Component.onCompleted:
{ {
business_model.onRowClicked(selectedObject) object_model.onRowClicked(selectedObject)
} }
} }

View File

@@ -1,22 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
import QtQuick.Controls.Fusion
Item {
property var availableFilters: [""]
StackView
{
id: objectsStack
anchors.fill: parent
initialItem: "ObjectsTable.qml"
}
}

View File

@@ -6,45 +6,85 @@ GridLayout
{ {
id: objectView id: objectView
columns: 2 columns: 4
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
rowSpacing: 9 rowSpacing: 9
Label
{
text: qsTr("Firma")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "business"
id: business
editable: true
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label Label
{ {
text: qsTr("Objektstraße") text: qsTr("Straße*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
} }
TextField TextField
{ {
id: objectName property string name: "street"
id: street
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields() onTextChanged: checkFields()
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
//Layout.maximumWidth: parent.width / 2
} }
Label Label
{ {
text: qsTr("Leistungsort") text: qsTr("Nr.*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
} }
TextField TextField
{ {
id: leistungsortid property string name: "houseno"
id: houseno
Layout.fillWidth: true Layout.fillWidth: true
//Layout.maximumWidth: parent.width / 2 Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields() onTextChanged: checkFields()
placeholderText: "Pflichtfeld" }
placeholderTextColor: "red"
Label
{
text: qsTr("PLZ*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "postcode"
id: postcode
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label
{
text: qsTr("Ort")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "city"
id: city
Layout.fillWidth: true
editable: true
onEditTextChanged: checkFields()
onCurrentTextChanged: checkFields()
model: address_model
textRole: "city"
popup.height: 300
currentIndex: -1
} }
Label Label
@@ -57,7 +97,7 @@ GridLayout
{ {
id: lohnanteil id: lohnanteil
Layout.fillWidth: true Layout.fillWidth: true
//Layout.maximumWidth: parent.width / 2 Layout.columnSpan: 3
} }
Label Label
@@ -70,7 +110,7 @@ GridLayout
{ {
id: materialanteil id: materialanteil
Layout.fillWidth: true Layout.fillWidth: true
//Layout.maximumWidth: parent.width / 2 Layout.columnSpan: 3
} }
Label Label
@@ -83,7 +123,7 @@ GridLayout
{ {
id: zusatz1 id: zusatz1
Layout.fillWidth: true Layout.fillWidth: true
//Layout.maximumWidth: parent.width / 2 Layout.columnSpan: 3
} }
Label Label
@@ -96,7 +136,7 @@ GridLayout
{ {
id: zusatz2 id: zusatz2
Layout.fillWidth: true Layout.fillWidth: true
//Layout.maximumWidth: parent.width / 2 Layout.columnSpan: 3
} }
Label Label
@@ -106,10 +146,9 @@ GridLayout
} }
TextField TextField
{ {id: gesamtnetto
id: gesamtnetto
Layout.fillWidth: true Layout.fillWidth: true
//Layout.maximumWidth: parent.width / 2 Layout.columnSpan: 3
} }
Label Label
@@ -122,7 +161,7 @@ GridLayout
{ {
id: mwst id: mwst
Layout.fillWidth: true Layout.fillWidth: true
//Layout.maximumWidth: parent.width / 2 Layout.columnSpan: 3
} }
Label Label
@@ -135,7 +174,7 @@ GridLayout
{ {
id: gesamt id: gesamt
Layout.fillWidth: true Layout.fillWidth: true
//Layout.maximumWidth: parent.width / 2 Layout.columnSpan: 3
} }
Label Label
@@ -149,9 +188,8 @@ GridLayout
id: zahlungsziel id: zahlungsziel
Layout.fillWidth: true Layout.fillWidth: true
editable: false editable: false
//model: business_type
textRole: "display" textRole: "display"
//Layout.maximumWidth: parent.width / 2 Layout.columnSpan: 3
} }
@@ -165,6 +203,7 @@ GridLayout
id: infoview id: infoview
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 110 Layout.preferredHeight: 110
Layout.columnSpan: 3
ScrollBar.horizontal: ScrollBar ScrollBar.horizontal: ScrollBar
{ {
policy: ScrollBar.AlwaysOn policy: ScrollBar.AlwaysOn
@@ -180,6 +219,7 @@ GridLayout
{ {
color: objectInfo.palette.base color: objectInfo.palette.base
border.color: objectInfo.activeFocus? objectInfo.palette.highlight: objectInfo.palette.base border.color: objectInfo.activeFocus? objectInfo.palette.highlight: objectInfo.palette.base
width: parent.width
} }
} }
} }

View File

@@ -0,0 +1,255 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: newObject
columns: 4
Layout.fillWidth: true
Layout.fillHeight: true
rowSpacing: 9
//// New grid row
Label
{
text: qsTr("Land")
Layout.alignment: Qt.AlignRight
visible: false
}
ComboBox
{
property string name: "country"
id: country
Layout.fillWidth: true
editable: true
// onEditTextChanged: checkFields()
// onCurrentTextChanged: checkFields()
model: address_model
textRole: "country"
popup.height: 300
currentIndex: 37
visible: false
}
Label
{
text: qsTr("PLZ")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "postcode"
id: postcode
Layout.fillWidth: true
editable: true
onCurrentTextChanged: checkFields()
onEditTextChanged: checkFields()
onActivated: currentValue
model: address_model
textRole: "display"
popup.height: 300
currentIndex: -1
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
validator: RegularExpressionValidator
{
regularExpression: /([0-9]{1,5})/
}
}
Label
{
text: qsTr("Ort")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "city"
id: city
Layout.fillWidth: true
editable: true
onEditTextChanged: checkFields()
onCurrentTextChanged: checkFields()
model: address_model
textRole: "city"
popup.height: 300
currentIndex: -1
}
Label
{
text: qsTr("Straße*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "street"
id: street
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields()
}
Label
{
text: qsTr("Nr.*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "houseno"
id: houseno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields()
}
// New grid row
// New grid row
Label
{
text: qsTr("Parteien")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
SpinBox
{
property string name: "units"
id: partitions
Layout.fillWidth: true
from: 1
to: 100
value: 1
editable: true
}
Label
{
text: qsTr("Stockwerke")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
SpinBox
{
property string name: "floors"
id: floors
Layout.fillWidth: true
from: 1
to: 100
value: 1
editable: true
}
// New grid row
Label
{
text: qsTr("Zwischenetage")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "mezzanin"
id: mezzanin
Layout.fillWidth: true
editable: false
model: [qsTr("Ja"), qsTr("Nein")]
}
Label
{
text: qsTr("Aufzug")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "lift"
id: lift
Layout.fillWidth: true
editable: false
model: [qsTr("Ja"), qsTr("Nein")]
}
//New grid row
Label
{
text: qsTr("Objekt-Nr.")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "objectno"
id: objectno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
placeholderText: qsTr("0 oder leer um eine Nummer automatisch zu generieren")
placeholderTextColor: "pink"
}
Label
{
text: qsTr("Besonderheiten")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "remarks"
id: remarks
Layout.fillWidth: true
}
//// New grid row
Label
{
text: qsTr("Reinigungsmittel wo?*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "cleaningproducts"
id: cleaningproducts
Layout.fillWidth: true
onTextChanged: checkFields()
}
Item
{
Layout.fillHeight: true
}
function checkObjectField()
{
return street.text.trim() && houseno.text.trim() &&
(postcode.editText.trim() || postcode.currentText.trim()) &&
(city.editText.trim() || city.currentText.trim()) &&
cleaningproducts.text.trim()
}
}

155
Gui/Objects/AddObject.qml Normal file
View File

@@ -0,0 +1,155 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs
import Js
ColumnLayout
{
property var new_object: null
//property alias checkAddContact: checkAddContact
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 15
Label
{
text: qsTr("Objekt anlegen")
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
font.pixelSize: 35
}
CheckBox
{
id: checkAddObjectContact
text: qsTr("Ansprechpartner hinzufügen")
Layout.alignment: Qt.AlignRight
checked: false
onCheckStateChanged:
{
checkFields()
}
}
RowLayout
{
id: addObject
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 45
Frame
{
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
AddNewObject
{
id: newObject
width: parent.width
}
}
ObjectAddOns
{
id: addObjectLayout
visible: checkAddObjectContact.checked
}
}
RowLayout
{
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Button
{
text: qsTr("Abbrechen")
onClicked: contentStack.pop()
}
Button
{
property var new_object: null
id: saveBtn
text: qsTr("Speichern")
enabled: false
onClicked:
{
new_object = JsLib.parseForm(newObject)
// For Debugging
console.log(JSON.stringify(new_object))
//
new_object['lift'] = new_object['lift'] === 'Ja' ? 1 : 0
new_object['mezzanin'] = new_object['mezzanin'] === 'Ja' ? 1 : 0
object_model.addObject(new_object)
}
}
}
Item
{
id: spacer3
Layout.fillHeight: true
}
Component.onCompleted:
{
//object_model.objectAdded.connect(onObjectAdded)
//contact_model.objectContactAdded.connect(onObjectContact)
}
Connections
{
target: object_model
function onObjectIdReady()
{
var obj_id = arguments[0]
if (checkAddObjectContact.checked && obj_id)
{
var new_objecto = addObjectLayout.getForm()
contact_model.addObjectContact(new_objecto, obj_id)
object_model.viewCriterion("Alle")
}
contentStack.pop()
}
}
// function onObjectAdded(added, oid)
// {
// if (!added)
// console.log(qsTr("Fehler beim Objekt-Anlegen!"))
// if (checkAddObjectContact.checked && oid)
// {
// var new_objecto = addObjectLayout.getForm()
// contact_model.addObjectContact(new_objecto, oid)
// }
// else appLoader.source = "ObjectTable.qml"
// }
// function onObjectContact(added)
// {
// if (!added)
// console.log(qsTr("Fehler beim Objekt-Kontakt-Anlegen!"))
// else
// {
// //object_model.viewCriterion("Alle")
// appLoader.source = "ObjectTable.qml"
// }
// }
function checkFields()
{
if(checkAddObjectContact.checked)
{
if(!newObject.checkObjectField() || !addObjectLayout.contactPerson.contacts || !addObjectLayout.contactPerson.contacts.length)
saveBtn.enabled = false
else
saveBtn.enabled = true
}
else if (!newObject.checkObjectField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
}

View File

@@ -0,0 +1,130 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
ApplicationWindow
{
id: addMitarbeiter
title: qsTr("Objekt - Neuer Mitarbeiter")
ColumnLayout
{
anchors.fill: parent
anchors.margins: 10
Label
{
text: qsTr("Mitarbeiter zuweisen")
Layout.alignment: Qt.AlignHCenter
font.pixelSize: 35
}
GridLayout
{
Layout.fillWidth: true
columns: 2
rowSpacing: 4
columnSpacing: 6
Label
{
text: qsTr("Eingesetzter Mitarbeiter")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
id: assignee
Layout.fillWidth: true
}
Label
{
text: qsTr("Lohn Mitarbeiter pro Stunde")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: wage
Layout.fillWidth: true
}
Label
{
text: qsTr("Einsatzdauer")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: duration
Layout.fillWidth: true
}
Label
{
text: qsTr("Reinigungstage")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: cleanDays
Layout.fillWidth: true
}
Label
{
text: qsTr("Tätigkeiten")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: tasks
Layout.fillWidth: true
}
Label
{
text: qsTr("Ertrag")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: output
Layout.fillWidth: true
}
Item
{
Layout.fillHeight: true
Layout.columnSpan: 2
}
}
RowLayout
{
Layout.fillWidth: true
spacing: 5
Item
{
Layout.fillWidth: true
}
Button
{
text: qsTr("Abbrechen")
onClicked: addMitarbeiter.close()
}
Button
{
text: qsTr("Hinzufügen")
onClicked:
{
if (duration.text.trim() !== "" && wage.text.trim() !== "" && cleanDays.text.trim() !== "" && tasks.text.trim() !== "" && output.text.trim() !== "")
{
var ne = {
"assignee": assignee.currentText,
"duration": duration.text.trim(),
"wage": wage.text.trim(),
"cleandays": cleanDays.text.trim(),
"tasks": tasks.text.trim(),
"output": output.text.trim(),
};
addMitarbeiter.addNewEmployee(ne)
addMitarbeiter.close()
}
}
}
}
}
signal addNewEmployee(var new_employee)
}

View File

@@ -0,0 +1,317 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
GridLayout
{
property var contacts: null
columns: 2
Layout.fillWidth: true
Label
{
text: qsTr("Position")
Layout.alignment: Qt.AlignRight | Qt.AlignTop
}
ComboBox
{
//property string name: "contacttype"
id: posizion
Layout.fillWidth: true
editable: false
model: [qsTr("Beirat"), qsTr("Hausmeister"), qsTr("Hausbewohner"), qsTr("Sonstiges")]
}
Label
{
text: qsTr("Anrede")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
id: title
model: [qsTr("Herr"), qsTr("Frau"), qsTr("Keine Angabe")]
Layout.fillWidth: true
}
Label
{
text: qsTr("Vorname*")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: firstname
Layout.fillWidth: true
// onTextChanged: checkContactFields()
}
Label
{
text: qsTr("Nachname*")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: lastname
Layout.fillWidth: true
}
Label
{
text: mobile.text ? qsTr("Telefonnummer") : qsTr("Telefonnummer*")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: phonenumber
Layout.fillWidth: true
}
Label
{
text: phonenumber.text ? qsTr("Mobil") : qsTr("Mobil*")
Layout.alignment: Qt.AlignRight
}
TextField
{
id: mobile
Layout.fillWidth: true
}
RowLayout
{
Layout.fillWidth: true
Layout.columnSpan: 2
Item
{
Layout.fillWidth: true
}
Button
{
id: removeContact
text: qsTr("Entfernen")
enabled: false
onClicked:
{
if (contactView.highlightFollowsCurrentItem)
{
delete contacts[contactView.currentIndex]
contacts = contacts.filter(elm => elm)
contactModel.remove(contactView.currentIndex)
contactView.highlightFollowsCurrentItem = false
contactView.currentIndex = -1
if (Object.keys(contacts).length === 0)
{
enabled = false
console.log(contacts)
}
checkFields()
}
}
}
Button
{
id: addContact
text: qsTr("Hinzufügen")
enabled: firstname.text.trim() && lastname.text.trim() && (phonenumber.text.trim() || mobile.text.trim()) && (contacts === null || Object.keys(contacts).length < 3)
onClicked:
{
var num_contacts = 0
if (contacts !== null && contacts !== undefined) num_contacts = Object.keys(contacts).length
else contacts = []
if (num_contacts < 3 && firstname.text.trim() !== "" && lastname.text.trim() !== "" && (phonenumber.text.trim() !== "" || mobile.text.trim() !== ""))
{
contacts[num_contacts] = {}
contacts[num_contacts]["title"] = title.currentText
contacts[num_contacts]["position"] = posizion.currentText
contacts[num_contacts]["fname"] = firstname.text.trim()
contacts[num_contacts]["lname"] = lastname.text.trim()
contacts[num_contacts]["phone"] = phonenumber.text.trim()
contacts[num_contacts]["mobile"] = mobile.text.trim()
contactModel.append({name: title.currentText + " " + firstname.text.trim() + " " + lastname.text.trim(), phone: phonenumber.text.trim(), mobile: mobile.text.trim(), posizion: posizion.currentText})
if (checkFields())
{
saveBtn.enabled = true
}
firstname.text = ""
lastname.text = ""
phonenumber.text = ""
mobile.text = ""
posizion.currentIndex = 0
title.currentIndex = 0
removeContact.enabled = true
checkFields()
}
}
}
}
Label
{
text: qsTr("Ansprechpartner")
Layout.alignment: Qt.AlignRight | Qt.AlignTop
}
ListModel
{
id: contactModel
}
// Component
// {
// id: headline
// Row
// {
// spacing: 9
// Text
// {
// id: cpname
// text: qsTr("Name")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// Text
// {
// id: cpphone
// text: qsTr("Telefon")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// Text
// {
// id: cpmobile
// text: qsTr("Mobil")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// Text
// {
// id: cppos
// text: qsTr("Position")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// Text
// {
// id: cttype
// text: qsTr("Typ")
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "white"
// }
// }
// }
Component
{
id: highlight
Rectangle
{
width: parent.width
color: "lightsteelblue"; radius: 5
y: contactView.currentItem.y
Behavior on y
{
SpringAnimation
{
spring: 3
damping: 0.2
}
}
}
}
Rectangle
{
id: mainRect
Layout.fillWidth: true
implicitHeight: 100
color: firstname.palette.base
border.color: firstname.activeFocus? firstname.palette.highlight: firstname.palette.base
clip: true
ScrollView
{
id: objContactView
// Layout.fillWidth: true
// Layout.preferredHeight: 100
//Layout.columnSpan: 3
anchors.fill: mainRect
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
ListView
{
id: contactView
anchors.fill: objContactView
// implicitHeight: objContactView.height
// implicitWidth: objContactView.width
model: contactModel
// header: headline
highlight: Rectangle { color: "slategray"; radius: 3}
highlightFollowsCurrentItem: false
//focus: true test
onActiveFocusChanged: if(!focus) currentIndex = -1
delegate: Item
{
width: contactView.width
height: 77
MouseArea
{
anchors.fill: parent
onClicked:
{
contactView.currentIndex = index
contactView.highlightFollowsCurrentItem = true
}
}
Column
{
anchors.margins: 5
//spacing: 3
Text
{
text: '<b>' + qsTr('Name: ') + '</b>' + model.name
horizontalAlignment: Text.AlignLeft
color: "white"
}
Text
{
text: '<b>' + qsTr('Telefon: ') + '</b>' + model.phone
horizontalAlignment: Text.AlignLeft
color: "white"
}
Text
{
text: '<b>' + qsTr('Handy: ') + '</b>' + model.mobile
horizontalAlignment: Text.AlignLeft
color: "white"
}
Text
{
text: '<b>' + qsTr('Position: ') + '</b>' + model.posizion
horizontalAlignment: Text.AlignLeft
color: "white"
}
} // Column
} // delegate
} // Listview
} // Scrollview
}
}

View File

@@ -0,0 +1,125 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
GridLayout
{
// property var employeeForm: null
// property var employees: null
// id: oaoemployee
// columns: 2
// rows: 4
// Label
// {
// text: qsTr("Mitarbeiter")
// Layout.alignment: Qt.AlignRight | Qt.AlignTop
// }
// ListModel
// {
// id: employeeModel
// }
// Component
// {
// id: employeesHeader
// Row
// {
// Text
// {
// id: empName
// text: qsTr("Mitarbeiter")
// width: 175
// font.bold: true
// horizontalAlignment: Text.AlignLeft
// color: "black"
// }
// }
// }
// Rectangle
// {
// Layout.fillWidth: true
// implicitHeight: 75
// Layout.rowSpan: 2
// color: mitarbeiterhin.palette.base
// border.color: mitarbeiterhin.activeFocus? mitarbeiterhin.palette.highlight: mitarbeiterhin.palette.base
// ListView
// {
// id: employeesList
// //anchors.fill: parent
// implicitHeight: parent.height
// model: employeeModel
// header: employeesHeader
// delegate: Row
// {
// width: 200
// height: 15
// //padding: 7
// Text
// {
// text: model.namens
// }
// }
// }
// }
// RowLayout
// {
// Layout.columnSpan: 2
// Layout.fillWidth: true
// Item
// {
// Layout.fillWidth: true
// }
// Button
// {
// id: mitarbeiterraus
// text: qsTr("Mitarbeiter entfernen")
// }
// Button
// {
// id: mitarbeiterhin
// text: qsTr("Mitarbeiter hinzufügen")
// onClicked:
// {
// var nm = Qt.createComponent("AddObjectEmployee.qml")
// if (nm.status === Component.Ready)
// {
// employeeForm = nm.createObject (appWindow, {width: 600, height: 400})
// employeeForm.addNewEmployee.connect(onAddEmployee)
// employeeForm.show()
// }
// else console.log(nm.errorString())
// }
// }
// }
// function onAddEmployee(new_employee)
// {
// var num_employees = 0
// if (employees === null || employees === undefined) employees = {}
// else num_employees = Object.keys(employees).length;
// employees[num_employees] = {}
// employees[num_employees]["assignee"] = new_employee["assignee"];
// employees[num_employees]["duration"] = new_employee["duration"];
// employees[num_employees]["wage"] = new_employee["wage"];
// employees[num_employees]["cleandays"] = new_employee["cleandays"];
// employees[num_employees]["tasks"] = new_employee["tasks"];
// employees[num_employees]["output"] = new_employee["output"];
// employeeModel.append({namens: new_employee["assignee"]});
// }
}

View File

@@ -0,0 +1,28 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Js
Frame
{
property alias contactPerson: oaocontactperson
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
ColumnLayout
{
id: addObjectLayout
width: parent.width
ObjectAddOnContactPerson
{
id: oaocontactperson
}
Item
{
Layout.fillHeight: true
}
}
function getForm()
{
return oaocontactperson.contacts
}
}

View File

@@ -0,0 +1,27 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Item
{
property int selectedObject: -1
id: obDet
ColumnLayout
{
Label
{
text: qsTr("Ausgewählter Objekt " + selectedObject)
}
Button
{
text: qsTr("Zurück zu den Objekten")
onClicked: contentStack.pop()
}
}
Component.onCompleted:
{
object_model.onRowClicked(selectedObject)
}
}

238
Gui/Objects/ObjectView.qml Normal file
View File

@@ -0,0 +1,238 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: objectView
columns: 4
Layout.fillWidth: true
Layout.fillHeight: true
rowSpacing: 9
Label
{
text: qsTr("Firma")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "business"
id: business
editable: true
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label
{
text: qsTr("Straße*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "street"
id: street
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields()
}
Label
{
text: qsTr("Nr.*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "houseno"
id: houseno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields()
}
Label
{
text: qsTr("PLZ*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
property string name: "postcode"
id: postcode
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label
{
text: qsTr("Ort")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "city"
id: city
Layout.fillWidth: true
editable: true
onEditTextChanged: checkFields()
onCurrentTextChanged: checkFields()
model: address_model
textRole: "city"
popup.height: 300
currentIndex: -1
}
Label
{
text: qsTr("Lohnanteil inkl. Fahrtkosten")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
id: lohnanteil
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label
{
text: qsTr("Materialanteil")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
id: materialanteil
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label
{
text: qsTr("Zusatz 1")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
id: zusatz1
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label
{
text: qsTr("Zusatz 2")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
id: zusatz2
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label
{
text: qsTr("Gesamt Netto")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{id: gesamtnetto
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label
{
text: qsTr("MwSt")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
id: mwst
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label
{
text: qsTr("Gesamt(Netto+MwSt)")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
id: gesamt
Layout.fillWidth: true
Layout.columnSpan: 3
}
Label
{
text: qsTr("Zahlungsziel")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "zahlungsziel"
id: zahlungsziel
Layout.fillWidth: true
editable: false
textRole: "display"
Layout.columnSpan: 3
}
Label
{
text: qsTr("Info")
Layout.alignment: Qt.AlignRight | Qt.AlignTop
}
ScrollView
{
id: infoview
Layout.fillWidth: true
Layout.preferredHeight: 110
Layout.columnSpan: 3
ScrollBar.horizontal: ScrollBar
{
policy: ScrollBar.AlwaysOn
}
TextArea
{
id: objectInfo
property string name: "objectinfo"
implicitWidth: parent.width
wrapMode: TextEdit.Wrap
background: Rectangle
{
color: objectInfo.palette.base
border.color: objectInfo.activeFocus? objectInfo.palette.highlight: objectInfo.palette.base
width: parent.width
}
}
}
Item
{
Layout.fillHeight: true
}
}

View File

@@ -0,0 +1,186 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout
{
property var availableFilters: [""]
spacing: Dimensions.l
function viewCriterion(criterion)
{
business_model.viewCriterion(criterion.text);
}
function onObjectContactAdded(added)
{
console.log(added)
if (added) object_model.viewCriterion("")
}
Component.onCompleted:
{
contact_model.objectContactAdded.connect(onObjectContactAdded)
// contentStack.pop()
}
RowLayout
{
Layout.fillWidth: true
spacing: Dimensions.l
SearchBar
{
}
QuickFilter {
onSelectedChanged: (name) => {
business_model.viewCriterion(name)
}
model: ListModel {
ListElement {
name: "Alle"
text: qsTr("Alle")
selected: true
}
ListElement {
name: "Aktiv"
text: qsTr("Aktiv")
selected: false
}
ListElement {
name: "Ehemalig"
text: qsTr("Ehemalig")
selected: false
}
ListElement {
name: "Angebote"
text: qsTr("Angebote")
selected: false
}
}
}
Button
{
id: addObjectBtn
icon.source: "qrc:/images/PlusCircle.svg"
text: qsTr("Objekt Hinzufügen")
Layout.alignment: Qt.AlignRight
onClicked: contentStack.push("AddObject.qml")
}
}
ColumnLayout
{
id: tableColumn
Layout.fillWidth: true
Layout.fillHeight: true
Layout.verticalStretchFactor: 1
clip: true
// anchors
// {
// top: searchBar.bottom
// bottom: parent.bottom
// left: parent.left
// right: parent.right
// topMargin: 15
// }
HorizontalHeaderView
{
id: horizontalHeaderview
Layout.fillWidth: true
implicitHeight: 40
movableColumns: true //@disable-check M16
syncView: objectTable
delegate: Rectangle {
color: addObjectBtn.palette.alternateBase
border.color: addObjectBtn.palette.base
implicitHeight: 40
Layout.fillWidth: true
implicitWidth: 1
Text
{
text: model.display
elide: Text.ElideRight
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: addObjectBtn.palette.text
}
}
}
TableView
{
property real newWidth: 0
id: objectTable
z: 1
// height: tableColumn.height - horizontalHeaderview.height
Layout.fillHeight: true
Layout.fillWidth: true
columnSpacing: 1
rowSpacing: 2
model: object_model
alternatingRows: true
resizableColumns: true // @disable-check M16
selectionBehavior: TableView.SelectRows
ScrollBar.vertical: ScrollBar
{
policy: objectTable.contentHeight > objectTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
}
selectionModel: ItemSelectionModel
{
id: obmodel
model: objectTable.model
}
delegate:Rectangle
{
required property bool selected
required property bool current
implicitWidth: objectTable.width / objectTable.columns
implicitHeight: 25
color: selected
? addObjectBtn.palette.highlight //palette.highlight
: (objectTable.alternatingRows && row % 2 !== 0
? addObjectBtn.palette.base // palette.base
: addObjectBtn.palette.alternateBase) //palette.alternateBase)
Text
{
text: (model.display === null || model.display === undefined)? "": model.display
elide: Text.ElideRight
width: parent.width
height: parent.height
verticalAlignment: Text.AlignVCenter
leftPadding: 9 //@d isable-check M16
color: addObjectBtn.palette.text
}
MouseArea
{
property bool hovered: false
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onDoubleClicked:
{
contentStack.push("ObjectDetails.qml", {selectedObject: row});
}
onEntered:
{
objectTable.selectionModel.select(objectTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows)
}
}
}
}
}
Item {
Layout.fillHeight: true
}
}

1
Gui/Objects/qmldir Normal file
View File

@@ -0,0 +1 @@
module Objects

View File

@@ -2,44 +2,96 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
import Qt.labs.qmlmodels import Qt.labs.qmlmodels
import QtQuick.Controls.Fusion
Item ColumnLayout
{ {
SearchBar property var availableFilters: [""]
anchors.fill: parent
spacing: Dimensions.l
function viewCriterion(criterion)
{ {
id:searchBar business_model.viewCriterion(criterion.text);
anchors.margins: 9 }
function onObjectContactAdded(added)
{
console.log(added)
if (added) object_model.viewCriterion("")
} }
Component.onCompleted:
{
contact_model.objectContactAdded.connect(onObjectContactAdded)
contentStack.pop()
}
RowLayout
{
Layout.fillWidth: true
spacing: Dimensions.l
SearchBar
{
}
QuickFilter {
onSelectedChanged: (name) => {
business_model.viewCriterion(name)
}
model: ListModel {
ListElement {
name: "Alle"
text: qsTr("Alle")
selected: true
}
ListElement {
name: "Aktiv"
text: qsTr("Aktiv")
selected: false
}
ListElement {
name: "Ehemalig"
text: qsTr("Ehemalig")
selected: false
}
ListElement {
name: "Angebote"
text: qsTr("Angebote")
selected: false
}
}
}
Button Button
{ {
id: addObjectBtn id: addObjectBtn
icon.source: "qrc:/images/addbusiness.svg" icon.source: "qrc:/images/PlusCircle.svg"
icon.color: "olive" text: qsTr("Objekt Hinzufügen")
anchors.right: parent.right Layout.alignment: Qt.AlignRight
flat: true onClicked: contentStack.push("AddObject.qml")
onClicked: appLoader.source = "AddObject.qml" }
} }
ColumnLayout ColumnLayout
{ {
id: tableColumn id: tableColumn
anchors Layout.fillWidth: true
{ Layout.fillHeight: true
top: searchBar.bottom Layout.verticalStretchFactor: 1
bottom: parent.bottom clip: true
left: parent.left // anchors
right: parent.right // {
} // top: searchBar.bottom
// bottom: parent.bottom
// left: parent.left
// right: parent.right
// topMargin: 15
// }
HorizontalHeaderView HorizontalHeaderView
{ {
id: horizontalHeaderview id: horizontalHeaderview
Layout.fillWidth: true Layout.fillWidth: true
implicitHeight: 40 implicitHeight: 40
visible: false
movableColumns: true //@disable-check M16 movableColumns: true //@disable-check M16
syncView: objectTable syncView: objectTable
@@ -66,38 +118,26 @@ Item
{ {
property real newWidth: 0 property real newWidth: 0
id: objectTable id: objectTable
z: 1
// height: tableColumn.height - horizontalHeaderview.height
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
columnSpacing: 1
rowSpacing: 2
model: object_model
alternatingRows: true
resizableColumns: true // @disable-check M16
selectionBehavior: TableView.SelectRows
ScrollBar.vertical: ScrollBar ScrollBar.vertical: ScrollBar
{ {
policy: objectTable.contentHeight > objectTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff policy: objectTable.contentHeight > objectTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
} }
columnSpacing: 1
rowSpacing: 2
//model: object_model
alternatingRows: true
resizableColumns: true // @disable-check M16
selectionBehavior: TableView.SelectRows
selectionModel: ItemSelectionModel selectionModel: ItemSelectionModel
{ {
id: obmodel id: obmodel
model: objectTable.model model: objectTable.model
} }
// Timer
// {
// id: redrawTable
// running: true
// interval: 1
// repeat: false
// onTriggered:
// {
// objectTable.forceLayout();
// }
// }
delegate:Rectangle delegate:Rectangle
{ {
required property bool selected required property bool selected
@@ -112,7 +152,7 @@ Item
Text Text
{ {
text: model.display == null? "": model.display text: (model.display === null || model.display === undefined)? "": model.display
elide: Text.ElideRight elide: Text.ElideRight
width: parent.width width: parent.width
height: parent.height height: parent.height
@@ -129,7 +169,7 @@ Item
hoverEnabled: true hoverEnabled: true
onDoubleClicked: onDoubleClicked:
{ {
objectsStack.push("ObjectDetails.qml", {selectedObject: row}); contentStack.push("ObjectDetails.qml", {selectedObject: row});
} }
onEntered: onEntered:
{ {
@@ -137,24 +177,10 @@ Item
} }
} }
} }
// onContentWidthChanged:
// {
// redrawTable.start()
// }
} }
Item }
{ Item {
Layout.fillHeight: true
Layout.fillWidth: true
} }
} }
// function viewCriterion(criterion)
// {
// object_model.viewCriterion(criterion.text)
// }
Component.onCompleted: objectsStack.pop()
}

236
Gui/Offers/AddNewOffer.qml Normal file
View File

@@ -0,0 +1,236 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
GridLayout
{
id: newObject
columns: 4
Layout.fillWidth: true
Layout.fillHeight: true
rowSpacing: 9
//New Grid
Label
{
text: qsTr("Objekt:")
Layout.alignment: Qt.AlignRight
font: Typography.h2
}
Item
{
Layout.columnSpan: 3
}
//New grid row
Label
{
text: qsTr("Objekt-Nr.")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "objectno"
id: objectno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
}
Button
{
text: qsTr("Objekt hinzufügen")
icon.source: "qrc:/images/PlusCircle.svg"
}
Item
{
}
//// New grid row
Label
{
text: qsTr("PLZ")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "postcode"
id: postcode
Layout.fillWidth: true
editable: true
// onCurrentTextChanged: checkFields()
// onEditTextChanged: checkFields()
onActivated: currentValue
model: address_model
textRole: "display"
popup.height: 300
currentIndex: -1
onCurrentIndexChanged:
{
city.currentIndex = postcode.currentIndex
}
validator: RegularExpressionValidator
{
regularExpression: /([0-9]{1,5})/
}
}
Label
{
text: qsTr("Ort")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "city"
id: city
Layout.fillWidth: true
editable: true
// onEditTextChanged: checkFields()
// onCurrentTextChanged: checkFields()
model: address_model
textRole: "city"
popup.height: 300
currentIndex: -1
}
Label
{
text: qsTr("Straße")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "street"
id: street
model: object_model
textRole: "StreetInPostcode"
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
// onTextChanged: checkFields()
}
Label
{
text: qsTr("Nr.*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "houseno"
id: houseno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
// onTextChanged: checkFields()
}
// New grid row
//New Grid
Label
{
text: qsTr("Kunde:")
Layout.alignment: Qt.AlignRight
font: Typography.h2
}
Item
{
Layout.columnSpan: 3
}
//New grid row
Label
{
text: qsTr("Kunden-Nr.")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "customerno"
id: customerno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
}
Button
{
text: qsTr("Kunde hinzufügen")
icon.source: "qrc:/images/PlusCircle.svg"
}
Item
{
}
// New grid row
Label
{
text: qsTr("Kunden-Name")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
TextField
{
id: customerName
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
}
Item
{
Layout.columnSpan: 2
}
//New Grid
Label
{
text: qsTr("Leistungen:")
Layout.alignment: Qt.AlignRight
font: Typography.h2
}
Item
{
Layout.columnSpan: 3
}
Item
{
Layout.fillHeight: true
}
// function checkObjectField()
// {
// return street.text.trim() && houseno.text.trim() &&
// (postcode.editText.trim() || postcode.currentText.trim()) &&
// (city.editText.trim() || city.currentText.trim()) &&
// cleaningproducts.text.trim()
// }
}

111
Gui/Offers/AddOffer.qml Normal file
View File

@@ -0,0 +1,111 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs
import Js
ColumnLayout
{
property var new_object: null
//property alias checkAddContact: checkAddContact
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 15
Label
{
text: qsTr("Angebot anlegen")
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
font.pixelSize: 35
}
RowLayout
{
id: addObject
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 45
AddNewOffer
{
id: newOffer
width: parent.width
}
}
RowLayout
{
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Button
{
text: qsTr("Abbrechen")
onClicked: contentStack.pop()
}
Button
{
id: saveBtn
text: qsTr("Speichern")
// enabled: false
onClicked:
{
// new_object = JsLib.parseForm(newObject)
// new_object['lift'] = new_object['lift'] === 'Ja' ? 1 : 0
// new_object['mezzanin'] = new_object['mezzanin'] === 'Ja' ? 1 : 0
// object_model.addObject(new_object)
}
}
}
Item
{
id: spacer3
Layout.fillHeight: true
}
Component.onCompleted:
{
//object_model.objectAdded.connect(onObjectAdded)
//contact_model.objectContactAdded.connect(onObjectContact)
}
// Connections
// {
// target: object_model
// function onObjectIdReady()
// {
// var obj_id = arguments[0]
// if (checkAddObjectContact.checked && obj_id)
// {
// var new_objecto = addObjectLayout.getForm()
// contact_model.addObjectContact(new_objecto, obj_id)
// object_model.viewCriterion("Alle")
// }
// appLoader.source = "ObjectTable.qml"
// }
// }
// function checkFields()
// {
// if(checkAddObjectContact.checked)
// {
// if(!newObject.checkObjectField() || !addObjectLayout.contactPerson.contacts || !addObjectLayout.contactPerson.contacts.length)
// saveBtn.enabled = false
// else
// saveBtn.enabled = true
// }
// else if (!newObject.checkObjectField())
// saveBtn.enabled = false
// else
// saveBtn.enabled = true
// }
}

View File

@@ -0,0 +1,66 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout
{
spacing: Dimensions.l
function viewOffers(criterion)
{
//offer_model.viewCriterion(criterion)
}
RowLayout
{
Layout.fillWidth: true
spacing: Dimensions.l
SearchBar
{
id: searchBar
}
QuickFilter {
model: ListModel {
ListElement {
name: "Alle"
text: qsTr("Alle")
selected: true
}
ListElement
{
name: "Offen"
text: qsTr("Offen")
selected: false
}
ListElement
{
name: "Abgeschlossen"
selected: false
text: qsTr("Abgeschlossen")
}
ListElement {
name: "Erledigt"
selected: false
text: qsTr("Erledigt")
}
}
onSelectedChanged: name => {
business_model.viewCriterion(name);
}
}
Button
{
id: addOfferBtn
text: qsTr("Angebote Hinzufügen")
icon.source: "qrc:/images/PlusCircle.svg"
Layout.alignment: Qt.AlignRight
flat: true
onClicked: contentStack.push("AddOffer.qml")
}
}
Item {
id: spacer
Layout.fillHeight: true
}
}

1
Gui/Offers/qmldir Normal file
View File

@@ -0,0 +1 @@
module Offers

144
Gui/PrinterDialog.qml Normal file
View File

@@ -0,0 +1,144 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "qrc:/TeroStyle"
Window
{
property alias printerDialog: printDialog
property var printers: null
id: printDialog
title: qsTr("PYQCRM - Drucker")
color: palette.base
minimumWidth: 300
maximumWidth: 600
minimumHeight: 150
maximumHeight: 150
ColumnLayout
{
spacing: 9
y: 15
implicitWidth: parent.width
RowLayout
{
Layout.fillWidth: true
Layout.leftMargin: 5
Layout.rightMargin: 5
Label
{
id: printersLabel
Layout.alignment: Qt.AlignRight
text: qsTr("Drucker")
}
ComboBox
{
id: allPrinters
model: printers
Layout.fillWidth: true
}
}
RowLayout
{
Layout.leftMargin: 5
Layout.rightMargin: 5
Layout.fillWidth: true
Label
{
Layout.minimumWidth: printersLabel.width
Layout.alignment: Qt.AlignRight
text: qsTr("Kopie")
}
SpinBox
{
id: copiesSpinBox
from: 1
to: 10
value: 1
}
Item
{
Layout.fillWidth: true
}
}
RowLayout
{
Layout.leftMargin: 5
Layout.rightMargin: 5
Layout.fillWidth: true
CheckBox
{
id: colorPrint
text: qsTr("Farbe")
Layout.minimumWidth: printersLabel.width
}
Item
{
Layout.fillWidth: true
}
}
RowLayout
{
Layout.leftMargin: 5
Layout.rightMargin: 5
Layout.fillWidth: true
Item
{
Layout.fillWidth: true
}
Button
{
id: printButton
text: qsTr("Drucken")
onClicked:
{
var copies = copiesSpinBox.value > 1? copiesSpinBox.value + " copies": "one copy"
console.log("Printing ", copies, " using ", allPrinters.currentText);
printDialog.close();
}
}
Button
{
text: qsTr("Ablehnen")
onClicked: printDialog.close();
}
}
Item
{
Layout.fillHeight: true
}
}
onVisibleChanged:
{
copiesSpinBox.value = 1
colorPrint.checked = true
if (!sys_printers)
{
printers = sys_printers.getPrinters()
if (sys_printers.getDefaultPrinter())
allPrinters.currentIndex = allPrinters.indexOfValue(sys_printers.getDefaultPrinter())
}
}
Component.onCompleted:
{
if (sys_printers)
{
printers = sys_printers.getPrinters()
if (sys_printers.getDefaultPrinter())
allPrinters.currentIndex = allPrinters.indexOfValue(sys_printers.getDefaultPrinter())
}
}
}

172
Gui/PyqcrmConf.qml Normal file
View File

@@ -0,0 +1,172 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
//import "qrc:/TeroStyle"
Item
{
property alias companyConf: companyConf
property alias miscConf: miscConf
anchors.fill: parent
TabBar
{
id: bar
width: parent.width
TabButton
{
text: qsTr("Benutzer")
}
TabButton
{
text: qsTr("Datenbank")
}
TabButton
{
text: qsTr("Das Unternehmen")
}
TabButton
{
text: qsTr("Sicherung")
}
TabButton
{
text: qsTr("Sonstiges")
}
}
StackLayout
{
id: confContainer
anchors.fill: parent
currentIndex: bar.currentIndex
Item
{
id: userTab
UsersPage
{
id: usersPage
anchors.fill: parent
}
}
Item
{
id: dbTab
DbConfiguration
{
id: dbConf
anchors.fill: parent
}
}
Item
{
id: companyTab
CompanyConf
{
id: companyConf
anchors.fill: parent
}
}
Item
{
id: backup
BackupSettings
{
id: backupSettings
anchors.fill: parent
}
}
Item
{
id: miscelanea
MiscConf
{
id: miscConf
anchors.fill: parent
}
}
}
RowLayout
{
width: parent.width
anchors.bottom: parent.bottom
Item
{
Layout.fillWidth: true
}
Button
{
text: qsTr("Ablehnen")
onClicked: contentStack.pop()
}
Button
{
text: qsTr("Speichern")
onClicked:
{
switch (confContainer.currentIndex)
{
case 1:
updateDbConf()
break
case 2:
updateCompanyInfo()
break
case 4:
updateMiscConf()
break
default:
console.log("Need to handle users")
}
}
}
}
function updateDbConf()
{
var db = {}
db['database'] = {}
db['database']['DB_HOST'] = dbConf.dbHost.text.trim()
db['database']['DB_PORT'] = dbConf.dbPort.text.trim()
db['database']['DB_NAME'] = dbConf.dbName.text.trim()
db['database']['DB_USER'] = dbConf.dbUserName.text.trim()
db['database']['DB_PASS'] = dbConf.dbPassword.text.trim()
if (db['database']['DB_HOST'] === '' || db['database']['DB_PORT'] === '' ||
db['database']['DB_NAME'] === '' || db['database']['DB_USER'] === '' ||
db['database']['DB_PASS'] === '');
else config.saveDbConf(db)
}
function updateCompanyInfo()
{
var company = {}
company['company'] = {}
company['company']['NAME'] = companyConf.name.text.trim()
company['company']['STREET'] = companyConf.street.text.trim()
company['company']['HOUSE'] = companyConf.house.text.trim()
company['company']['ZIPCODE'] = companyConf.zipcode.editText? companyConf.zipcode.editText.trim(): companyConf.zipcode.currentText
company['company']['CITY'] = companyConf.city.editText? companyConf.city.editText.trim(): companyConf.city.currentText
if (company['company']['NAME'] === '' || company['company']['STREET'] === '' ||
company['company']['HOUSE'] === '' || company['company']['ZIPCODE'] === '' ||
company['company']['CITY'] === '');
else config.saveCompanyInfo(company)
}
function updateMiscConf()
{
var misc = {}
misc['misc'] = {}
misc['misc']['SYSTRAY'] = miscConf.sysTray.checked
config.saveMiscConf(misc)
}
}

47
Gui/ReadMe.qml Normal file
View File

@@ -0,0 +1,47 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Window
{
property alias readMeWin: readMeWin
id: readMeWin
width: 400
height: 300
title: "PYQCRM - README"
color: palette.base
ScrollView
{
anchors.fill: parent
TextArea
{
id: readMe
anchors.fill: parent
readOnly: true
wrapMode: TextArea.Wrap
color: "darksalmon"
Component.onCompleted:
{
var filePath = "qrc:/README";
var xhr = new XMLHttpRequest();
xhr.open("GET", filePath, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE)
{
if (xhr.status === 200)
{
readMe.text = xhr.responseText;
}
else
{
readMe.text = qsTr("Datei nicht gefunden!");
}
}
};
xhr.send();
}
}
}
}

View File

@@ -1,82 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
RowLayout
{
id: searchBar
TextField
{
id: searchField
placeholderText: qsTr("Suche")
leftPadding: 3
rightPadding: 3
Layout.preferredWidth: 300
Button
{
icon.source: "qrc:/images/search.svg"
icon.color: "olive"
x: parent.x + parent.width - width
height: parent.height
flat: true
}
Button
{
id: filterBtn
icon.source: "qrc:/images/filter.svg"
icon.color: "olive"
x: parent.x + parent.width
height: searchField.height
flat: true
onClicked: filterPopup.open()
}
}
Popup
{
id: filterPopup
x: filterBtn.x + filterBtn.width
y: filterBtn.y
width: 100
height: 150
modal: true
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
contentItem: Item
{
ColumnLayout
{
anchors.fill: parent
//id: filterContent
Repeater
{
model: availableFilters
CheckBox
{
text: model.modelData
onClicked:
{
setFilter(text, checkState)
}
}
}
}
}
}
function setFilter(filter,activated)
{
console.log(filter)
console.log(activated)
}
}

View File

@@ -1,96 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
RowLayout
{
id: topBar
spacing: 0
height: 35
width: parent.width
anchors
{
top: parent.top
left: parent.left
}
Button
{
id: dashBoard
flat: true
text: qsTr("Dashboard")
implicitWidth: dashBoard.implicitContentWidth + 10
onClicked:
{
appLoader.source = "Dashboard.qml"
}
}
Button
{
id: kunden
flat: true
text: qsTr("Kunden")
implicitWidth: kunden.implicitContentWidth + 10
onClicked:
{
// TODO: here we should call the model
appLoader.source = "CustomerTable.qml"
}
}
Button
{
id: objekt
flat: true
text: qsTr("Objekt")
implicitWidth: objekt.implicitContentWidth + 10
onClicked:
{
appLoader.source = "ObjectTable.qml"
}
}
Button
{
id: mitarbeiter
flat: true
text: qsTr("Mitarbeiter")
implicitWidth: mitarbeiter.implicitContentWidth + 10
onClicked:
{
appLoader.source = "EmployeeTable.qml"
}
}
Button
{
id: abrechnung
flat: true
text: qsTr("Abrechnung")
implicitWidth: abrechnung.implicitContentWidth + 10
}
Item
{
id: hspacer
Layout.fillWidth: true
}
Button
{
id: atajos
icon.source: "qrc:/images/menu.svg"
icon.color: "red"
flat: true
Layout.rightMargin: 9
}
}

17
Gui/UsersPage.qml Normal file
View File

@@ -0,0 +1,17 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
Item
{
property string name: "users"
anchors.fill: parent
Label
{
text: qsTr("Benutzer-Verwaltung")
anchors.centerIn: parent
font.pixelSize: 57
font.bold: true
}
}

208
Gui/UtilityDialogs.qml Normal file
View File

@@ -0,0 +1,208 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import QtCore
import "../js/qmldict.js" as JsLib
Item
{
id: utilityDialogs
property alias backup_config: backupConfig
property alias backup_encrypt_pw: recoveryPasswordDialog
property var recpass
property var configpass
Dialog
{
anchors.centerIn: parent
id: backupConfig
title: "Backup Config"
standardButtons: Dialog.Apply | Dialog.Cancel
onApplied:
{
if (configPwd.text === repeatConfigPwd.text)
{
configpass = repeatConfigPwd.text
saveConfigFile.open()
}
else
{
configPwd.text = ""
configPwd.placeholderText = qsTr("Passwort stimmt nicht überein")
configPwd.placeholderTextColor = "red"
repeatConfigPwd.placeholderText = qsTr("")
repeatConfigPwd.text = ""
}
}
onRejected: resetRecoveryConfigDialog()
GridLayout
{
id: gridPw
columns: 2
Label
{
text: qsTr("Passwort eingeben")
}
TextField
{
id: configPwd
placeholderText: qsTr("Sicherungspasswort festlegen")
echoMode: TextInput.Password
implicitWidth: 300
}
Label
{
text: qsTr("Passwort wiederholen")
}
TextField
{
property string name: "password"
id: repeatConfigPwd
placeholderText: qsTr("Sicherungspasswort wiederholen")
echoMode: TextInput.Password
implicitWidth: 300
}
}
}
FileDialog
{
id: saveConfigFile
fileMode: FileDialog.SaveFile
nameFilters: ["PYQCRM Recovery files (*.pyqrec)"]
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
onAccepted:
{
config.backupConfig(saveConfigFile.currentFile, configpass)
}
onRejected:
{
backupConfig.close()
resetRecoveryConfigDialog()
}
}
MessageDialog
{
id: recoveryDialog
text: qsTr("Diesen Wiederherstellungscode musst du sicher aufbewahren!\nMöchtest du das jetzt machen?")
title: qsTr("Wiederherstellen")
buttons: MessageDialog.Yes | MessageDialog.No
onAccepted: recoveryPasswordDialog.open()
onRejected: contentStack.replace("LoginSreen.qml")
}
MessageDialog
{
id: conErrDialog
text: qsTr("Datenbankverbindung fehlgeschlagen")
title: qsTr("Datenbank Verbindung")
}
Dialog
{
id: recoveryPasswordDialog
modal: true
title: qsTr("Wiederherstellung")
anchors.centerIn: parent
standardButtons: Dialog.Apply | Dialog.Cancel
onApplied:
{
if (recoveryPasswordInput.text === repeatRecoveryPasswordInput.text)
{
recpass = recoveryPasswordInput.text
saveRecoveryDialog.open()
}
else
{
recoveryPasswordInput.text = ""
recoveryPasswordInput.placeholderText = qsTr("Passwort stimmt nicht überein")
recoveryPasswordInput.placeholderTextColor = "red"
repeatRecoveryPasswordInput.placeholderText = qsTr("")
repeatRecoveryPasswordInput.text = ""
}
}
onClosed: resetRecoveryPwDialog()
ColumnLayout
{
GridLayout
{
columns: 2
Label
{
text: qsTr("Wiederherstellungspasswort festlegen: ")
}
TextField
{
id: recoveryPasswordInput
text: ""
echoMode: TextInput.Password
implicitWidth: 300
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
}
Label
{
text: qsTr("Wiederherstellungspasswort wiederholen: ")
}
TextField
{
id: repeatRecoveryPasswordInput
text: ""
echoMode: TextInput.Password
implicitWidth: 300
placeholderText: qsTr("Hier Wiederherstellungspasswort wiederholen")
}
}
}
}
FileDialog
{
id: saveRecoveryDialog
title: qsTr("Wiederherstellungsdatei")
fileMode: FileDialog.SaveFile
nameFilters: ["PYQCRM Recovery files (*.pyqrec)"]
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
onAccepted:
{
config.backupEncryptkey(saveRecoveryDialog.currentFile, recpass)
}
onRejected:
{
recoveryPasswordDialog.close()
resetRecoveryPwDialog()
}
}
function resetRecoveryPwDialog()
{
recoveryPasswordInput.text = ""
recoveryPasswordInput.placeholderText = qsTr("Hier Wiederherstellungspasswort eingeben")
recoveryPasswordInput.placeholderTextColor = repeatRecoveryPasswordInput.placeholderTextColor
repeatRecoveryPasswordInput.text = ""
repeatRecoveryPasswordInput.placeholderText = qsTr("Hier Wiederherstellungspasswort wiederholen")
}
function resetRecoveryConfigDialog()
{
configPwd.text = ""
configPwd.placeholderText = qsTr("Hier Wiederherstellungspasswort eingeben")
configPwd.placeholderTextColor = repeatConfigPwd.placeholderTextColor
repeatConfigPwd.text = ""
repeatConfigPwd.placeholderText = qsTr("Hier Wiederherstellungspasswort wiederholen")
}
}

View File

@@ -4,109 +4,138 @@ import QtQuick.Controls
import QtQuick.Dialogs import QtQuick.Dialogs
import QtCore import QtCore
ApplicationWindow ApplicationWindow {
{
id: appWindow id: appWindow
width: Screen.width * .75
height: Screen.height * .85
visible: true
title: "PYQCRM"
property string confile: "" property string confile: ""
property alias settingsFileDialog: settingsFiledialog
TopBar function showWindow(why) {
{ if (why === 3) {
systray.setVisible(false);
id:topBar appWindow.show();
anchors }
{
rightMargin: 9
leftMargin: 9
} }
visible: bad_config || !db_con ? false: true font: Typography.body
} height: Screen.desktopAvailableHeight
palette.window: Colors.mantle
palette.placeholderText: Colors.interactive
palette.text: Colors.foreground
title: "TERO Personal"
visible: true
width: Screen.desktopAvailableWidth
Item Component.onCompleted: {
{ systray.activated.connect(showWindow);
id: mainView
}
Loader if (bad_config) {
{ importDialog.open();
id: appLoader } else {
anchors if (db_con)
{ contentStack.replace("LoginScreen.qml")
left: parent.left
right: parent.right
top: topBar.bottom
bottom: parent.bottom
topMargin: 0
bottomMargin: 5
rightMargin: 9
leftMargin: 9
}
property alias window: appWindow
}
Component.onCompleted:
{
if(bad_config)
{
importDialog.open()
}
else else
{ contentStack.replace("NoDbConnection.qml");
if (db_con) appLoader.source= "LoginScreen.qml" }
else appLoader.source= "NoDbConnection.qml" }
onClosing: close => {
if (false) {
console.log("Main window closed!! Was soll ich tun? kann ich mich beenden?!");
}
}
onVisibilityChanged: {
if (appWindow.visibility === Window.Minimized && config.systray()) {
systray.setVisible(true);
appWindow.hide();
}
}
onWindowStateChanged: windowState => {
if (windowState !== Qt.WindowMinimized) {
systray.setVisible(false);
appWindow.show();
} }
} }
Dialog Navigation {
{ id: navigation
visible: !(bad_config || !db_con)
}
PrinterDialog {
id: printerDialog
}
ReadMe {
id: readMeWin
}
Item {
id: mainView
}
Rectangle {
id: contentBackground
anchors {
bottom: parent.bottom
left: navigation.visible ? navigation.right : parent.left
right: parent.right
top: parent.top
}
color: Colors.background
}
StackView {
id: contentStack
anchors {
fill: contentBackground
margins: Dimensions.l
}
}
Dialog {
id: importDialog id: importDialog
modal: true
anchors.centerIn: parent
standardButtons: Dialog.Yes | Dialog.No
onAccepted: settingsFiledialog.open()
onRejected: appLoader.source= "firststart.qml"
title: qsTr("Einstellungen importieren")
}
FileDialog anchors.centerIn: parent
{ modal: true
standardButtons: Dialog.Yes | Dialog.No
title: qsTr("Einstellungen importieren")
onAccepted: settingsFiledialog.open()
onRejected: contentStack.replace("Firststart.qml")
}
FileDialog {
id: settingsFiledialog id: settingsFiledialog
title: qsTr("PYQCRM Einstellungen")
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0] currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
modality: "ApplicationModal" modality: "ApplicationModal"
nameFilters: [qsTr("PYQCRM Einstellungen (*.pyqcrm)")] nameFilters: [qsTr("PYQCRM Einstellungen (*.pyqrec)")]
onAccepted:
{
exportFilePassword.open()
confile = selectedFile
}
}
Dialog
{
id: exportFilePassword
modal: true
title: qsTr("PYQCRM Einstellungen") title: qsTr("PYQCRM Einstellungen")
onAccepted: {
exportFilePassword.open();
confile = selectedFile;
}
}
Dialog {
id: exportFilePassword
anchors.centerIn: parent anchors.centerIn: parent
modal: true
standardButtons: Dialog.Ok | Dialog.Cancel standardButtons: Dialog.Ok | Dialog.Cancel
title: qsTr("PYQCRM Einstellungen")
onAccepted: config.importConfig(confile, exportPasswordInput.text) onAccepted: config.importConfig(confile, exportPasswordInput.text)
ColumnLayout
{ ColumnLayout {
RowLayout RowLayout {
{ Label {
Label
{
text: qsTr("Passwort eingeben:") text: qsTr("Passwort eingeben:")
} }
TextField {
TextField
{
id: exportPasswordInput id: exportPasswordInput
echoMode: TextInput.Password echoMode: TextInput.Password
implicitWidth: 300 implicitWidth: 300
} }

View File

@@ -1,2 +1,3 @@
module gui module gui
TopBar 1.0 TopBar.qml Navigation 1.0 Navigation.qml
AddContact 1.0 AddContact.qml

73
Js/JsLib.js Normal file
View File

@@ -0,0 +1,73 @@
.pragma library
function firstConf(tabs)
{
let pyqcrm_conf = {};
pyqcrm_conf[tabs.name] = {}
for (var i = 0; i < tabs.children.length; i++)
{
if (tabs.children[i].name)
{
if (!tabs.children[i].text.trim())
return false
if (pyqcrm_conf[tabs.name][tabs.children[i].name] !== "DB_PASS")
pyqcrm_conf[tabs.name] [tabs.children[i].name] = tabs.children[i].text.trim()
else
pyqcrm_conf[tabs.name] [tabs.children[i].name] = tabs.children[i].text
}
}
return pyqcrm_conf
}
function parseForm(...form)
{
let data_form = {};
for (var i = 0; i < form.length; i++)
{
for (var j = 0; j < form[i].children.length; j++)
{
console.log(form[i].children[j])
if (form[i].children[j].toString().startsWith("Combo"))
{
if(form[i].children[j].editText)
{
data_form[form[i].children[j].name] = form[i].children[j].editText
}
else
{
data_form[form[i].children[j].name] = form[i].children[j].currentText
}
}
else if (form[i].children[j].toString().startsWith("TextField"))
{
data_form[form[i].children[j].name] = form[i].children[j].text.trim()
}
else if (form[i].children[j].toString().startsWith("Scroll"))
{
data_form[form[i].children[j].contentChildren[0].name] = form[i].children[j].contentChildren[0].text.trim()
}
else if (form[i].children[j].toString().startsWith("CheckBox"))
{
data_form[form[i].children[j].name] = form[i].children[j].checked
}
else if (form[i].children[j].toString().startsWith("SpinBox"))
{
data_form[form[i].children[j].name] = form[i].children[j].value
}
// else if (form[i].children[j].toString().startsWith("QQuickContentItem"))
// {
// console.log(form[i].children[j].children.children)
// for (var k = 0; k < form[i].children[j].length; k++)
// {
// console.log(form[i].children[j].name)
// }
// }
}
}
return data_form
}

70
Js/qmldict.js Normal file
View File

@@ -0,0 +1,70 @@
.pragma library
function firstConf(tabs)
{
let pyqcrm_conf = {};
pyqcrm_conf[tabs.name] = {}
for (var i = 0; i < tabs.children.length; i++)
{
if (tabs.children[i].name)
{
if (!tabs.children[i].text.trim())
return false
if (pyqcrm_conf[tabs.name][tabs.children[i].name] !== "DB_PASS")
pyqcrm_conf[tabs.name] [tabs.children[i].name] = tabs.children[i].text.trim()
else
pyqcrm_conf[tabs.name] [tabs.children[i].name] = tabs.children[i].text
}
}
return pyqcrm_conf
}
function parseForm(...form)
{
let data_form = {};
for (var i = 0; i < form.length; i++)
{
for (var j = 0; j < form[i].children.length; j++)
{
if (form[i].children[j].toString().startsWith("Combo"))
{
if(form[i].children[j].editText)
{
data_form[form[i].children[j].name] = form[i].children[j].editText
}
else
{
data_form[form[i].children[j].name] = form[i].children[j].currentText
}
}
else if (form[i].children[j].toString().startsWith("TextField"))
{
data_form[form[i].children[j].name] = form[i].children[j].text.trim()
}
else if (form[i].children[j].toString().startsWith("Scroll"))
{
data_form[form[i].children[j].contentChildren[0].name] = form[i].children[j].contentChildren[0].text.trim()
}
else if (form[i].children[j].toString().startsWith("CheckBox"))
{
data_form[form[i].children[j].name] = form[i].children[j].checked
}
else if (form[i].children[j].toString().startsWith("SpinBox"))
{
data_form[form[i].children[j].name] = form[i].children[j].value
}
// else if (form[i].children[j].toString().startsWith("QQuickContentItem"))
// {
// console.log(form[i].children[j].children.children)
// for (var k = 0; k < form[i].children[j].length; k++)
// {
// console.log(form[i].children[j].name)
// }
// }
}
}
return data_form
}

2
Js/qmldir Normal file
View File

@@ -0,0 +1,2 @@
module Js
JsLib 1.0 JsLib.js

1
LICENSE Normal file
View File

@@ -0,0 +1 @@
Nicht zu verwenden ohne Zahlung!

54
README Normal file
View File

@@ -0,0 +1,54 @@
PYQCRM - Python QtQuick CRM System
Einleitung:
----------------
PYQCRM entstand als Teil einer Abschlusspraxis und dem Bedarf der TERO GmbH an einem Managementprogramm für den internen Gebrauch.
Erstellung:
----------------
Das Program wurde mit den folgenen Techologien entwickelt:
- IDE: Qt-Creator 6.8.x
- Framework: QtQuick - QML 6.8.x
- Sprache: Python 3.13.x
- Datenbank: MariaDB 10.11.x
- Sonstiges: JavaScript
Installation:
------------------
Möglicherweise ist für deine Plattform ein Installationspaket verfügbar. Prüfe es also zuerst.
Es gibt zwei möglichkeiten das Program zu verwenden:
Möglichkeit I:
1. Datenbank einrichten (MaraiDB SQL-Schema verfügbar)
2. Python installiert und eingerichtet
3. Das Program in einen bevorzugten Pfad kopieren.
4. Erstelle einen Link zum main.py-Skript und stelle ihn so ein, dass er mit deinem Python-Interpreter ausgeführt wird
Möglichkeit II:
1. Datenbank einrichten (MaraiDB SQL-Schema verfügbar)
2. Die ausführbare Version des Programs in einen bevorzugten Pfad kopieren
3. Erstelle einen Link zur ausführbaren Datei, die für dein System erstellt wurde (pyqcrm/pyqcrm.exe)
Kudos:
----------
Wenn dir dieses Kunstwerk gefällt, kannst du uns deine Wertschätzung einfach dadurch zeigen, dass du jedem von uns einen Bungalow, einen 760IL BMW, lebenslange Flugtickets inklusive Begleitung kaufst und als Geschenk ein paar Millionen Euro auf ein Schweizer Bankkonto überweist.
Team:
---------
Marcopolo
Schnacke
Renegade

61
TeroStyle/BarButton.qml Normal file
View File

@@ -0,0 +1,61 @@
import QtQuick
import QtQuick.Controls.impl
import QtQuick.Controls
import QtQuick.Templates as T
T.ToolButton {
id: control
property string target
checkable: true
icon.color: Colors.foreground
icon.height: 36
icon.width: 36
implicitHeight: 90
implicitWidth: 100
topPadding: 20
contentItem: Column {
readonly property color color: control.checked ? Colors.primaryShade : control.hovered ? Colors.primary : Colors.foreground
IconLabel {
color: parent.color
icon.color: parent.color
icon.height: control.icon.height
icon.source: control.icon.source
icon.width: control.icon.width
x: parent.width * .5 - width * .5
}
Label {
color: parent.color
font: Typography.smaller
text: control.text
x: parent.width * .5 - width * .5
}
}
Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.top: parent.top
color: control.checked ? Colors.primaryShade : Colors.primary
implicitWidth: 6
visible: control.checked || control.hovered
}
MouseArea {
id: mouseArea
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: mouse => mouse.accepted = false
}
onClicked: {
if(!target) {
return
}
contentStack.replace(target)
}
}

69
TeroStyle/Button.qml Executable file
View File

@@ -0,0 +1,69 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls.impl as I
import QtQuick.Templates as T
T.Button {
id: control
/**
* Set true when the button is supposed to be displayed in e.g. a TextField.
* You want to do this when this button is directly related to the TextField
* and the primary and only action for the TextField.
* Usually, you'd only want to display an icon in this button.
* If true, automatically sets height, width and position.
*
* ```qml
* TextField {
* placeholderText: "Search..."
* Button {
* icon.source: "qrc:/images/MagnifyingGlass.svg"
* isFieldButton: true
* }
* }
* ```
*/
property bool isFieldButton: false
height: isFieldButton ? parent.height : null
icon.color: Colors.primaryContrast
icon.height: 21
icon.width: 21
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding)
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding)
/**
* Icon is slightly larger than Text, so we need to reduce the padding a
* tiny bit to make sure all Buttons are still the same height.
*/
padding: Dimensions.m - (icon.source.toString() === "" ? 0 : 1)
x: isFieldButton ? parent.x + parent.width - width : null
background: Rectangle {
anchors.fill: parent
border.color: Colors.interactive
border.width: isFieldButton ? 1 : 0
bottomLeftRadius: topLeftRadius
color: !control.enabled ? Colors.disabled : !control.hovered ? Colors.primary : Colors.primaryLighter
radius: Dimensions.radius
topLeftRadius: isFieldButton ? 0 : radius
}
contentItem: I.IconLabel {
color: !control.enabled ? Colors.disabledForeground : Colors.primaryContrast
display: control.display
font: control.font
icon: control.icon
mirrored: control.mirrored
spacing: Dimensions.s
text: control.text
}
MouseArea {
id: mouseArea
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: mouse => mouse.accepted = false
}
}

26
TeroStyle/Colors.qml Normal file
View File

@@ -0,0 +1,26 @@
pragma Singleton
import QtQuick
QtObject {
readonly property int dark: 0
readonly property int light: 1
property int theme: Application.styleHints.colorScheme === Qt.ColorScheme.Light ? light : dark
readonly property color primary: "#b81a34"
readonly property color primaryContrast: "#fdfdfd"
readonly property color primaryLighter: Qt.lighter(primary, 1.5)
readonly property color primaryShade: theme === dark ? primaryLighter : Qt.darker(primary, 1.5)
readonly property color primaryHighlight: theme === dark ? Qt.darker(primary, 2- Colors.highlightOpacity) : Qt.lighter(primary, 2- Colors.highlightOpacity)
readonly property color foreground: theme === dark ? "#fdfdfd" : "#110b0c"
readonly property color background: theme === dark ? "#303136" : "#eff1f5"
readonly property color mantle: theme === dark ? "#1E1E23" : "#e7e9ef"
readonly property color interactive: theme === dark ? "#878b97" : "#d9d9da"
readonly property color error: theme === dark ? "#ff2264" : "#ff004b"
readonly property color disabled: theme === dark ? Qt.darker(interactive, 1.9) : Qt.darker(interactive, 1.3)
readonly property color disabledForeground: theme === dark ? Qt.darker(foreground, 1.4) : Qt.lighter(foreground, 1.9)
readonly property color transparent: "transparent"
readonly property double highlightOpacity: .3
}

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