Merge branch 'main' into schnacke

This commit is contained in:
2025-05-08 11:47:47 +02:00
70 changed files with 1154 additions and 1096 deletions

4
.idea/discord.xml generated
View File

@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="APPLICATION" />
<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" />

5
.idea/qmlSettings.xml generated
View File

@@ -6,6 +6,11 @@
<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>

View File

@@ -1,180 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "../js/qmldict.js" as JsLib
ColumnLayout
{
id: colPar
anchors.fill: parent
Layout.fillWidth: true
Layout.fillHeight: true
implicitWidth: parent.width
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")
}
}
// ScrollView
// {
// Layout.fillHeight: true
// Layout.fillWidth: true
// implicitWidth: parent.width
// ColumnLayout
// {
// anchors.fill: parent
// //implicitWidth: parent.width
// //width: parent.width
// //height: parent.height
RowLayout
{
Layout.fillWidth: true
//implicitWidth: parent.width
spacing: 50
Frame
{
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
//implicitWidth: parent.width
ApplicantPersonalData
{
id: personalData
width: parent.width
}
}
Frame
{
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
visible: radio.children[1].checked
ColumnLayout
{
Layout.alignment: Qt.AlignTop
implicitWidth: parent.width
ApplicantBankData
{
id: bankAccount
}
ApplicantNationalInsurance
{
id: nationalInsurance
}
ApplicantVarious
{
id: applicantVarious
}
}
}
}
Item
{
Layout.fillHeight: true
}
RowLayout
{
Layout.fillWidth: true
Layout.alignment: Qt.AlignRight
Button
{
text: qsTr("Abbrechen")
onClicked: appLoader.source = "EmployeeTable.qml"
}
Button
{
id: saveBtn
text: qsTr("Speichern")
enabled: false
onClicked:
{
var new_applicant
if (radio.children[0].checked)
{
// Ein Bewerber
new_applicant = JsLib.parseForm(personalData)
employee_model.addEmployee(new_applicant, true)
// appLoader.source = "EmployeeTable.qml"
// console.log(JSON.stringify (new_applicant))
}
else
{
// Ein Mitarbeiter
// console.log(personalData, bankAccount, nationalInsurance, applicantVarious)
new_applicant = JsLib.parseForm(personalData, bankAccount, nationalInsurance, applicantVarious)
employee_model.addEmployee(new_applicant, false)
// var new_contact = JsLib.addApplicant(addContactLayout)
// contact_model.addContact(new_contact)
// console.log(JSON.stringify (new_applicant))
}
}
}
}
Component.onCompleted:
{
employee_model.addedNewEmployee.connect(onAddNewEmployee)
}
// }
// } // ScrollView
function onAddNewEmployee(added)
{
if (added)
console.log('addedsuccesfully')
else
console.log('failedtoadd')
appLoader.source = 'EmployeeTable.qml'
}
function checkFields()
{
if(radio.children[1].checked)
{
if(!personalData.checkPersonalField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
else if (!personalData.checkPersonalField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
}

View File

@@ -59,7 +59,7 @@ ColumnLayout
Button
{
text: qsTr("Abbrechen")
onClicked: appLoader.source = "CustomerTable.qml"
onClicked: contentStack.pop()
}
Button
{
@@ -72,7 +72,7 @@ ColumnLayout
{
new_business = JsLib.parseForm(customerView)
business_model.addBusiness(new_business, 0)
appLoader.source = "CustomerTable.qml"
contentStack.pop()
}
else
{
@@ -99,7 +99,7 @@ ColumnLayout
{
var con_id = arguments[0]
business_model.addBusiness(new_business, con_id)
appLoader.source = "CustomerTable.qml"
contentStack.pop()
}
}

View File

@@ -61,7 +61,7 @@ ColumnLayout
Button
{
text: qsTr("Abbrechen")
onClicked: appLoader.source = "ObjectTable.qml"
onClicked: contentStack.pop()
}
Button
{
@@ -105,7 +105,7 @@ ColumnLayout
object_model.viewCriterion("Alle")
}
appLoader.source = "ObjectTable.qml"
contentStack.pop()
}
}

View File

@@ -47,7 +47,7 @@ ColumnLayout
Button
{
text: qsTr("Abbrechen")
onClicked: appLoader.source = "OfferTable.qml"
onClicked: contentStack.pop()
}
Button
{

View File

@@ -12,8 +12,7 @@ ColumnLayout
Button
{
text: qsTr("Zurück")
//Layout.columnSpan: 2
onClicked: customersStack.pop()
onClicked: contentStack.pop()
}
SplitView

View File

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

View File

@@ -4,6 +4,7 @@ import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout {
property var availableFilters: ["Name", "Adresse", "PLZ", "Ort"]
function viewCriterion(criterion)
{
@@ -15,7 +16,7 @@ ColumnLayout {
anchors.fill: parent
spacing: Dimensions.l
Component.onCompleted: customersStack.pop()
Component.onCompleted: contentStack.pop()
RowLayout
{
@@ -67,7 +68,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignRight
icon.source: "qrc:/images/PlusCircle.svg"
text: qsTr("Kunde Hinzufügen")
onClicked: appLoader.source = "AddCustomer.qml"
onClicked: contentStack.push("AddCustomer.qml")
}
}
ColumnLayout
@@ -153,7 +154,7 @@ ColumnLayout {
onDoubleClicked: {
business_model.onRowClicked(row);
customersStack.push("CustomerDetails.qml", {
contentStack.push("CustomerDetails.qml", {
selectedClient: row
});
}

View File

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

View File

@@ -0,0 +1,43 @@
import QtQuick
import QtQuick.Layouts
import TeroStyle
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,102 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "../../js/qmldict.js" as JsLib
ColumnLayout {
id: colPar
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');
}
}
Layout.fillHeight: true
Layout.fillWidth: true
anchors.fill: parent
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 / Bewerber hinzufügen")
}
RowLayout {
Layout.fillWidth: true
spacing: Dimensions.l
Frame {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.horizontalStretchFactor: 1
ApplicantPersonalData {
id: personalData
implicitWidth: parent.width
}
}
Frame {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.horizontalStretchFactor: 1
ColumnLayout {
Layout.alignment: Qt.AlignTop
implicitWidth: parent.width
ApplicantBankData {
id: bankAccount
}
ApplicantNationalInsurance {
id: nationalInsurance
}
ApplicantVarious {
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,221 @@
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.currentText ?? ""
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.editText ? street.editText : street.currentText) ?? ""
readonly property string title: title.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 {
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 {
id: firstname
implicitWidth: fieldM
placeholderText: qsTr("Max")
validator: NotEmptyValidator {
}
}
}
Field {
label: qsTr("Nachname")
mandatory: true
TextField {
id: lastname
implicitWidth: fieldM
placeholderText: qsTr("Mustermann")
validator: NotEmptyValidator {
}
}
}
}
RowLayout {
spacing: Dimensions.m
Field {
id: street
label: qsTr("Straße")
mandatory: true
TextField {
implicitWidth: fieldM
placeholderText: qsTr("Musterstraße")
validator: NotEmptyValidator {
}
}
}
Field {
id: houseno
mandatory: true
label: qsTr("Hausnummer")
TextField {
implicitWidth: fieldS
placeholderText: qsTr("1a")
validator: NotEmptyValidator {
}
}
}
Field {
label: qsTr("PLZ")
mandatory: true
ComboBox {
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 {
id: city
currentIndex: -1
editable: true
implicitWidth: fieldM
model: address_model
textRole: "city"
validator: NotEmptyValidator {
}
}
}
}
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 {
id: phone
implicitWidth: fieldM
placeholderText: "+49 1234 567890"
validator: OptionalPhoneNumberValidator {
}
}
}
Field {
label: qsTr("Mobil")
TextField {
id: mobile
implicitWidth: fieldM
placeholderText: "+49 123 4567891011"
validator: OptionalPhoneNumberValidator {
}
}
}
Field {
label: qsTr("E-Mail Adresse")
TextField {
id: email
implicitWidth: fieldM
placeholderText: "tero@example.org"
validator: OptionalEmailAddressValidator {
}
}
}
Field {
label: qsTr("Briefanrede")
TextField {
id: formofaddress
implicitWidth: fieldM
}
}
}
}

View File

@@ -1,444 +1,409 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import TeroStyle
GridLayout
{
GridLayout {
id: personalData
columns: 4
Label
{
text: qsTr("Anrede")
Layout.alignment: Qt.AlignRight
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());
}
ComboBox
{
property string name: "title"
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
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 "
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
{
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Vorname*")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "firstname"
TextField {
id: firstname
Layout.fillWidth: true
onTextChanged: checkFields()
Layout.columnSpan: 3
}
Label
{
text: qsTr("Nachname*")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "lastname"
id: lastname
Layout.fillWidth: true
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"
onTextChanged: checkFields()
property string name: "firstname"
Layout.columnSpan: 3
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label
{
text: qsTr("Nr.")
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Nachname*")
}
TextField
{
property string name: "houseno"
id: houseno
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()
validator: RegularExpressionValidator
{
}
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
{
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("PLZ")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "postcode"
ComboBox {
id: postcode
property string name: "postcode"
Layout.fillWidth: true
currentIndex: -1
editable: true
onEditTextChanged: checkFields()
onCurrentTextChanged: checkFields()
onActivated: currentValue
model: address_model
popup.height: 300
textRole: "display"
popup.height: 300
currentIndex: -1
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
validator: RegularExpressionValidator
{
regularExpression: /([^$][0-9]{1,4})/
validator: PostcodeValidator {
}
}
Label
{
text: qsTr("Ort")
Layout.alignment: Qt.AlignRight
}
ComboBox
{
property string name: "city"
id: city
Layout.fillWidth: true
editable: true
onEditTextChanged: checkFields()
onActivated: currentValue
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
onCurrentTextChanged: checkFields()
model: address_model
textRole: "city"
popup.height: 300
currentIndex: -1
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
{
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Geburtsname")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "birthname"
TextField {
id: birthname
Layout.fillWidth: true
onTextChanged: checkFields()
property string name: "birthname"
Layout.columnSpan: 3
visible: radio.children[1].checked
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label
{
text: qsTr("Geburtsdatum*")
Label {
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
text: qsTr("Geburtsdatum*")
}
TextField
{
property string name: "birthday"
TextField {
id: birthday
Layout.fillWidth: true
onTextChanged: checkFields()
property string name: "birthday"
Layout.columnSpan: 3
visible: radio.children[1].checked
validator: RegularExpressionValidator
{
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 + "."
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
{
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Geburtsort*")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "placeofbirth"
TextField {
id: placeofbirth
Layout.fillWidth: true
onTextChanged: checkFields()
Layout.columnSpan: 3
visible: radio.children[1].checked
}
Label
{
property string name: "placeofbirth"
Layout.columnSpan: 3
Layout.fillWidth: true
onTextChanged: checkFields()
}
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Telefonnummer")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "phone"
TextField {
id: phonenumber
property string name: "phone"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
Layout.columnSpan: 3
onTextChanged: checkFields()
validator: RegularExpressionValidator
{
validator: RegularExpressionValidator {
regularExpression: /([+0-9]{1})([0-9]{1,17})/
}
onTextChanged: checkFields()
}
Label
{
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Mobil")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "mobile"
TextField {
id: cellphone
property string name: "mobile"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
Layout.columnSpan: 3
onTextChanged: checkFields()
validator: RegularExpressionValidator
{
validator: RegularExpressionValidator {
regularExpression: /([+0-9]{1})([0-9]{1,17})/
}
}
Label
{
text: qsTr("E-Mail")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "email"
id: email
Layout.fillWidth: true
placeholderTextColor: "red"
Layout.columnSpan: 3
onTextChanged: checkFields()
placeholderText: qsTr("beispiel@domain.de")
validator: RegularExpressionValidator
{
regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
}
}
Label
{
text: qsTr("Familienstand")
Label {
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
text: qsTr("E-Mail")
}
ComboBox
{
property string name: "maritalstatus"
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")]
visible: radio.children[1].checked
Layout.columnSpan: 3
}
Label
{
Label {
Layout.alignment: Qt.AlignRight
text: qsTr("Stundenlohn")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "salary"
TextField {
id: salary
Layout.fillWidth: true
visible: radio.children[1].checked
placeholderTextColor: "red"
Layout.columnSpan: 3
onTextChanged: checkFields()
}
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
onTextChanged: checkFields()
}
Label
{
text: qsTr("Vertragsbeginn")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "contractstart"
id: contractstart
Layout.fillWidth: true
visible: radio.children[1].checked
placeholderTextColor: "red"
Layout.columnSpan: 3
onTextChanged: checkFields()
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 + "."
}
}
}
Label
{
text: qsTr("Vertragsende")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
TextField
{
property string name: "contractend"
id: contractend
Layout.fillWidth: true
visible: radio.children[1].checked
placeholderTextColor: "red"
Layout.columnSpan: 3
onTextChanged: checkFields()
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 + "."
}
}
}
Label
{
text: qsTr("Arbeitszeiten Tage")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
ComboBox
{
property string name: "workdays"
id: workdays
Layout.fillWidth: true
visible: radio.children[1].checked
model: ["1","2","3","4","5","6","7"]
}
Label
{
text: qsTr("Stunden")
Layout.alignment: Qt.AlignRight
visible: radio.children[1].checked
}
ComboBox
{
property string name: "workhours"
id: workhours
Layout.fillWidth: true
visible: radio.children[1].checked
model: ["1","2","3","4","5","6","7","8"]
}
Label
{
text: qsTr("Briefanrede")
Layout.alignment: Qt.AlignRight
}
TextField
{
property string name: "formofaddress"
id: briefAnrede
Layout.fillWidth: true
placeholderTextColor: "red"
Layout.columnSpan: 3
onTextChanged: checkFields()
}
Item
{
Layout.fillHeight: true
property string name: "salary"
Layout.columnSpan: 3
Layout.fillWidth: true
placeholderTextColor: "red"
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
}
function checkPersonalField()
{
if (radio.children[0].checked)
{
return (firstname.text.trim() && lastname.text.trim())
}
else
{
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()
{
var pf = (radio.children[1].checked)?"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
Layout.fillHeight: true
}
}

View File

@@ -16,7 +16,7 @@ Item
Button
{
text: qsTr("Mitarbeiter zeigen")
onClicked: employeesStack.pop()
onClicked: contentStack.pop()
}
}

View File

@@ -0,0 +1,142 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout {
anchors.fill: parent
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("Kunde")
}
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,187 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout
{
function viewEmployees(criterion)
{
employee_model.viewCriterion(criterion)
// employee_model.viewCriterion(criterion, showProcessed.checked, showFired.checked, showEveryone.checked)
}
anchors.fill: parent
spacing: Dimensions.l
Component.onCompleted: employeesStack.pop()
// property var availableFilters: ["Name", "Adresse", "PLZ", "Ort", "Status"]
RowLayout
{
Layout.fillWidth: true
spacing: Dimensions.l
SearchBar
{
id:searchBar
}
QuickFilter
{
onSelectedChanged: (name) =>
{
business_model.viewCriterion(name)
}
model: ListModel
{
ListElement
{
name: "Alle"
text: qsTr("Alle")
selected: true
}
ListElement
{
name: "Bewerber"
text: qsTr("Bewerber")
selected: false
}
ListElement
{
name: "Mitarbeiter"
text: qsTr("Kunde")
selected: false
}
ListElement
{
name: "Erledigt"
text: qsTr("Erledigt")
selected: false
}
}
}
Button
{
id: addEmployeeBtn
text: qsTr("Mitarbeiter Hinzufügen")
icon.source: "qrc:/images/PlusCircle.svg"
Layout.alignment: Qt.AlignRight
flat: true
onClicked: appLoader.source = "AddApplicant.qml"
}
}
HorizontalHeaderView
{
id: employeeTableHeader
Layout.fillWidth: true
syncView: appliEmpTable
implicitHeight: 40
movableColumns: true //@disable-check M16
delegate: Rectangle
{
color: addEmployeeBtn.palette.alternateBase
border.color: 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: palette.text
}
}
}
TableView
{
id: appliEmpTable
//Layout.fillHeight: true
//height: tableParent.height - (viewCriterion.height + employeeTableHeader.height)
Layout.fillWidth: true
Layout.fillHeight: true
columnSpacing: 1
rowSpacing: 2
alternatingRows: true
resizableColumns: true
model: employee_model
selectionBehavior: TableView.SelectRows
z: 1
ScrollBar.vertical: ScrollBar
{
policy: appliEmpTable.contentHeight > appliEmpTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
}
selectionModel: ItemSelectionModel
{
id: selModel
model: appliEmpTable.model
}
delegate:Rectangle
{
required property bool selected
required property bool current
implicitWidth: appliEmpTable.width / appliEmpTable.columns
implicitHeight: 25
color: selected
? addEmployeeBtn.palette.highlight //palette.highlight
: (appliEmpTable.alternatingRows && row % 2 !== 0
? addEmployeeBtn.palette.base // palette.base
: addEmployeeBtn.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: palette.text
}
MouseArea
{
id: mouseArea
property bool hovered:false
anchors.fill: parent
hoverEnabled: true
onDoubleClicked:
{
employeesStack.push("EmployeeDetails.qml", {selectedEmployee: row});
}
onEntered:
{
appliEmpTable.selectionModel.select(appliEmpTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows)
}
}
}
}
Item
{
Layout.fillWidth: true
}
}
// function viewEmployees(criterion)
// {
// employee_model.viewCriterion(criterion, showProcessed.checked, showFired.checked, showEveryone.checked)
// }
// Component.onCompleted: employeesStack.pop()

View File

@@ -77,7 +77,7 @@ Item
title: qsTr("Wiederherstellen")
buttons: MessageDialog.Yes | MessageDialog.No
onAccepted: recoveryPaswordDialog.open()
onRejected: gotoLogin()
onRejected: contentStack.replace("LoginSreen.qml")
}
MessageDialog
@@ -147,7 +147,7 @@ Item
if (!adminAvailable) config.saveRecoveryKey(saveRecoveryDialog.currentFile, recpass)
else config.getRecoveryKey(saveRecoveryDialog.currentFile, recpass)
gotoLogin()
contentStack.replace("LoginSreen.qml")
}
onRejected:

View File

@@ -4,20 +4,19 @@ import QtQuick.Controls
import QtQuick.Dialogs
import QtQuick.Layouts
Item {
property string recpass: ""
function dbConnectionFailed(msg) {
oschkar.notificationBox.informativeText = msg;
oschkar.notificationBox.text = "Verbindung zum Datenbankserver verloren";
oschkar.notificationBox.open();
notifications.notificationDialog.informativeText = msg;
notifications.notificationDialog.text = "Verbindung zum Datenbankserver verloren";
notifications.notificationDialog.open();
}
function getEncryptionKey() {
recoveryPaswordDialog.open();
}
function loggedin() {
appLoader.source = "Dashboard.qml";
contentStack.replace("Dashboard.qml");
}
anchors.fill: parent
@@ -79,8 +78,8 @@ Item {
}
Button {
Layout.topMargin: Dimensions.m
implicitWidth: parent.width
icon.source: "qrc:/images/ArrowRightEndOnRectangle.svg"
implicitWidth: parent.width
text: qsTr("Login")
onClicked: {
@@ -132,8 +131,7 @@ Item {
onRejected: quit()
}
Notifications {
id: oschkar
id: notifications
}
}
}

View File

@@ -3,92 +3,79 @@ 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: buttonBar
id: mainNav
}
BarButton {
id: dashBoard
ButtonGroup.group: buttonBar
icon.source: "qrc:/images/dash.svg"
ButtonGroup.group: mainNav
icon.source: "qrc:/images/Square3Stack3D-Outline.svg"
target: "/Gui/Dashboard.qml"
text: qsTr("Dashboard")
onClicked: {
appLoader.source = "Dashboard.qml";
}
visible: !onSubPage
}
BarButton {
id: kunden
ButtonGroup.group: buttonBar
icon.source: "qrc:/images/customer.svg"
ButtonGroup.group: mainNav
icon.source: "qrc:/images/UserGroup-Outline.svg"
target: "/Gui/CustomersTable.qml"
text: qsTr("Kunden")
onClicked: {
appLoader.source = "CustomerTable.qml";
}
visible: !onSubPage
}
BarButton {
id: objekt
ButtonGroup.group: buttonBar
icon.source: "qrc:/images/object.svg"
ButtonGroup.group: mainNav
icon.source: "qrc:/images/BuildingOffice2-Outline.svg"
target: "/Gui/ObjectsTable.qml"
text: qsTr("Objekt")
onClicked: {
appLoader.source = "ObjectTable.qml";
}
visible: !onSubPage
}
BarButton {
id: mitarbeiter
ButtonGroup.group: buttonBar
icon.source: "qrc:/images/employee.svg"
ButtonGroup.group: mainNav
icon.source: "qrc:/images/Identification-Outline.svg"
target: "/Gui/Employees/EmployeesTable.qml"
text: qsTr("Mitarbeiter")
onClicked: {
appLoader.source = "EmployeeTable.qml";
}
visible: !onSubPage
}
BarButton {
id: offers
ButtonGroup.group: buttonBar
icon.source: "qrc:/images/offer.svg"
ButtonGroup.group: mainNav
icon.source: "qrc:/images/RectangleStack-Outline.svg"
target: "/Gui/OffersTable.qml"
text: qsTr("Angebote")
onClicked: {
appLoader.source = "OfferTable.qml";
}
visible: !onSubPage
}
BarButton {
id: abrechnung
ButtonGroup.group: buttonBar
icon.source: "qrc:/images/invoice.svg"
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 {
id: hspacer
Layout.fillHeight: true
}
BarButton {
id: atajos
Layout.bottomMargin: Dimensions.s
checkable: false
flat: true
icon.source: "qrc:/images/Bars3.svg"
implicitHeight: 90
implicitWidth: 90
onClicked: mainMenu.open()
@@ -101,7 +88,8 @@ ColumnLayout {
onTriggered: {
// TODO: Check if logged-in user is admin first!!
appLoader.source = "PyqcrmConf.qml";
contentStack.push("PyqcrmConf.qml");
}
}
MenuSeparator {

View File

@@ -1,74 +1,27 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Rectangle
{
anchors.fill: parent
color: "slateblue"
ColumnLayout {
anchors.centerIn: parent
spacing: Dimensions.s
height: implicitHeight
Rectangle
{
id: info
anchors.horizontalCenter: parent.horizontalCenter
color: "slateblue"
implicitHeight: 55
implicitWidth: parent.width / 4
y: parent.height / 4
Text
{
anchors.centerIn: parent
text: qsTr("Keine Verbindung zur Datenbank!")
color: "moccasin"
font.bold: true
font.pixelSize: 45
}
H1 {
Layout.alignment: Qt.AlignCenter
text: qsTr("Keine Verbindung zur Datenbank!")
color: Colors.foreground
}
Rectangle
{
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
}
H2 {
Layout.alignment: Qt.AlignCenter
text: qsTr("Programm kann nicht starten…")
color: Colors.foreground
}
Button {
Layout.topMargin: Dimensions.l
Layout.alignment: Qt.AlignCenter
text: qsTr("Beenden")
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")
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
{
id: oschkar
property alias notificationBox: notificationDialog
MessageDialog
{
id: notificationDialog

View File

@@ -16,7 +16,7 @@ Item
Button
{
text: qsTr("Zurück zu den Objekten")
onClicked: objectsStack.pop()
onClicked: contentStack.pop()
}
}

View File

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

View File

@@ -5,6 +5,8 @@ import Qt.labs.qmlmodels
ColumnLayout
{
property var availableFilters: [""]
anchors.fill: parent
spacing: Dimensions.l
@@ -21,7 +23,7 @@ ColumnLayout
Component.onCompleted:
{
contact_model.objectContactAdded.connect(onObjectContactAdded)
objectsStack.pop()
contentStack.pop()
}
RowLayout
{
@@ -65,7 +67,7 @@ ColumnLayout
icon.source: "qrc:/images/PlusCircle.svg"
text: qsTr("Objekt Hinzufügen")
Layout.alignment: Qt.AlignRight
onClicked: appLoader.source = "AddObject.qml"
onClicked: contentStack.push("AddObject.qml")
}
}
@@ -167,7 +169,7 @@ ColumnLayout
hoverEnabled: true
onDoubleClicked:
{
objectsStack.push("ObjectDetails.qml", {selectedObject: row});
contentStack.push("ObjectDetails.qml", {selectedObject: row});
}
onEntered:
{

View File

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

View File

@@ -20,17 +20,9 @@ ColumnLayout
{
id: searchBar
}
QuickFilter
{
onSelectedChanged: (name) =>
{
business_model.viewCriterion(name)
}
model: ListModel
{
ListElement
{
QuickFilter {
model: ListModel {
ListElement {
name: "Alle"
text: qsTr("Alle")
selected: true
@@ -43,10 +35,19 @@ ColumnLayout
}
ListElement
{
name: "Abgesagt"
text: qsTr("Abgesagt")
name: "Abgeschlossen"
selected: false
text: qsTr("Abgeschlossen")
}
ListElement {
name: "Erledigt"
selected: false
text: qsTr("Erledigt")
}
}
onSelectedChanged: name => {
business_model.viewCriterion(name);
}
}
Button
@@ -62,8 +63,5 @@ ColumnLayout
Item {
id: spacer
Layout.fillHeight: true
}
}

View File

@@ -101,7 +101,7 @@ Item
Button
{
text: qsTr("Ablehnen")
onClicked: appLoader.source = "Dashboard.qml"
onClicked: contentStack.pop()
}
Button

View File

@@ -97,7 +97,7 @@ Item
title: qsTr("Wiederherstellen")
buttons: MessageDialog.Yes | MessageDialog.No
onAccepted: recoveryPasswordDialog.open()
onRejected: gotoLogin()
onRejected: contentStack.replace("LoginSreen.qml")
}
MessageDialog

View File

@@ -10,10 +10,6 @@ ApplicationWindow {
property string confile: ""
property alias settingsFileDialog: settingsFiledialog
function goToLogin() {
appLoader.source = "LoginScreen.qml";
navigation.visible = true;
}
function showWindow(why) {
if (why === 3) {
systray.setVisible(false);
@@ -21,25 +17,25 @@ ApplicationWindow {
}
}
color: Colors.mantle
font: Typography.body
height: Screen.height * .85
palette.window: Colors.mantle
palette.placeholderText: Colors.interactive
palette.text: Colors.foreground
title: "TERO Personal"
visible: true
width: Screen.width * .75
Component.onCompleted: {
config.configurationReady.connect(goToLogin);
systray.activated.connect(showWindow);
if (bad_config) {
importDialog.open();
} else {
if (db_con)
appLoader.source = "LoginScreen.qml";
contentStack.replace("LoginScreen.qml")
else
appLoader.source = "NoDbConnection.qml";
contentStack.replace("NoDbConnection.qml");
}
}
onClosing: close => {
@@ -63,7 +59,7 @@ ApplicationWindow {
Navigation {
id: navigation
visible: bad_config || !db_con ? false : true
visible: !(bad_config || !db_con)
}
PrinterDialog {
id: printerDialog
@@ -82,17 +78,15 @@ ApplicationWindow {
id: contentBackground
anchors {
bottom: parent.bottom
left: navigation.right
left: navigation.visible ? navigation.right : parent.left
right: parent.right
top: parent.top
}
color: Colors.background
}
Loader {
id: appLoader
property alias window: appWindow
StackView {
id: contentStack
anchors {
fill: contentBackground
@@ -109,7 +103,7 @@ ApplicationWindow {
title: qsTr("Einstellungen importieren")
onAccepted: settingsFiledialog.open()
onRejected: appLoader.source = "Firststart.qml"
onRejected: contentStack.replace("Firststart.qml")
}
FileDialog {
id: settingsFiledialog

View File

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

View File

@@ -6,6 +6,8 @@ import QtQuick.Templates as T
T.ToolButton {
id: control
property string target
checkable: true
icon.color: Colors.foreground
icon.height: 36
@@ -18,16 +20,16 @@ T.ToolButton {
readonly property color color: control.checked ? Colors.primaryShade : control.hovered ? Colors.primary : Colors.foreground
IconLabel {
icon.color: parent.color
icon.source: control.icon.source
icon.height: control.icon.height
icon.width: control.icon.width
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 {
font: Typography.small
color: parent.color
font: Typography.smaller
text: control.text
x: parent.width * .5 - width * .5
}
@@ -49,4 +51,11 @@ T.ToolButton {
onPressed: mouse => mouse.accepted = false
}
onClicked: {
if(!target) {
return
}
contentStack.replace(target)
}
}

View File

@@ -25,6 +25,7 @@ T.Button {
*/
property bool isFieldButton: false
height: isFieldButton ? parent.height : null
icon.color: Colors.primaryContrast
icon.height: 21
@@ -43,12 +44,12 @@ T.Button {
border.color: Colors.interactive
border.width: isFieldButton ? 1 : 0
bottomLeftRadius: topLeftRadius
color: !control.hovered ? Colors.primary : Colors.primaryLighter
color: !control.enabled ? Colors.disabled : !control.hovered ? Colors.primary : Colors.primaryLighter
radius: Dimensions.radius
topLeftRadius: isFieldButton ? 0 : radius
}
contentItem: I.IconLabel {
color: Colors.primaryContrast
color: !control.enabled ? Colors.disabledForeground : Colors.primaryContrast
display: control.display
font: control.font
icon: control.icon

View File

@@ -12,11 +12,14 @@ QtObject {
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

View File

@@ -33,36 +33,16 @@ T.ComboBox {
border.color: Colors.interactive
border.width: 1
color: Colors.mantle
// height: parent.height
radius: Dimensions.radius
width: parent.width
}
// delegate: MenuItem {
// id: menuItem
// required property int index
// required property var model
// highlighted: control.highlightedIndex === index
// hoverEnabled: control.hoverEnabled
// text: model[control.textRole]
// width: control.width
// background: Rectangle {
// color: menuItem.down || menuItem.highlighted ? Colors.primary : "transparent"
// height: menuItem.height
// width: menuItem.width
// }
// }
delegate: ItemDelegate {
required property var model
required property int index
width: ListView.view.width
text: model[control.textRole]
// palette.text: control.palette.text
// palette.highlightedText: control.palette.highlightedText
// font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
highlighted: control.highlightedIndex === index
hoverEnabled: control.hoverEnabled
}
@@ -125,8 +105,4 @@ T.ComboBox {
}
}
}
Component.onCompleted:
{
console.log(control.implicitContentHeight)
}
}

View File

@@ -0,0 +1,5 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
}

View File

@@ -5,11 +5,16 @@ import QtQuick.Layouts
ColumnLayout
{
required property string label
/**
* Adds an asterisk after the label, informing the user that this field
* is mandatory.
*/
property bool mandatory: false
spacing: Dimensions.s
Label
{
text: label
text: label + (mandatory ? "*" : "")
font: Typography.body
}
}

5
TeroStyle/H1.qml Normal file
View File

@@ -0,0 +1,5 @@
import QtQuick
Text {
font: Typography.h1
}

5
TeroStyle/H2.qml Normal file
View File

@@ -0,0 +1,5 @@
import QtQuick
Text {
font: Typography.h2
}

View File

@@ -0,0 +1,5 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /^\S+.*\S+$/
}

View File

@@ -0,0 +1,5 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /^$|([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
}

View File

@@ -0,0 +1,5 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /^$|([+0-9])([0-9\s]{1,17})/
}

View File

@@ -0,0 +1,5 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /([+0-9])([0-9\s]{1,17})/
}

View File

@@ -0,0 +1,5 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /([^$][0-9]{1,4})/
}

View File

@@ -4,6 +4,7 @@ import QtQuick.Templates as T
T.TextField
{
id: control
background: Rectangle
{
id: background

View File

@@ -11,7 +11,25 @@ Item {
letterSpacing: 0,
kerning: true
})
readonly property font small: ({
family: body.family,
pointSize: 14,
weight: Font.Medium,
letterSpacing: body.letterSpacing,
kerning: body.kerning
})
readonly property font smallBold: ({
family: small.family,
pointSize: small.pointSize,
weight: Font.Bold,
letterSpacing: small.letterSpacing,
kerning: small.kerning
})
readonly property font smaller: ({
family: body.family,
pointSize: 11,
weight: Font.DemiBold,
@@ -25,10 +43,9 @@ Item {
letterSpacing: body.letterSpacing,
kerning: body.kerning
})
readonly property font h2:
({
readonly property font h2: ({
family: body.family,
pointSize: 20,
pointSize: 28,
weight: body.weight,
letterSpacing: body.letterSpacing,
kerning: body.kerning,

View File

@@ -2,13 +2,19 @@ module TeroStyle
singleton Colors Colors.qml
singleton Dimensions Dimensions.qml
singleton Typography Typography.qml
BarButton BarButton.qml
Button Button.qml
ComboBox ComboBox.qml
EmailAddressValidator EmailAddressValidator.qml
Field Field.qml
TextField TextField.qml
BarButton BarButton.qml
H1 H1.qml
H2 H2.qml
Label Label.qml
NotEmptyValidator NotEmptyValidator.qml
OptionalEmailAddressValidator OptionalEmailAddressValidator.qml
PhoneNumberValidator PhoneNumberValidator.qml
OptionalPhoneNumberValidator OptionalPhoneNumberValidator.qml
PostcodeValidator PostcodeValidator.qml
QuickFilter QuickFilter.qml
SearchBar SearchBar.qml
TextField TextField.qml

View File

@@ -1,4 +0,0 @@
# pyqcrm
CRM - Tero
Python + QML

View File

@@ -0,0 +1,3 @@
<svg fill="none" stroke-width="2" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-slot="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="m11.25 9-3 3m0 0 3 3m-3-3h7.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 288 B

View File

Before

Width:  |  Height:  |  Size: 521 B

After

Width:  |  Height:  |  Size: 521 B

3
images/CheckCircle.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-slot="icon">
<path clip-rule="evenodd" fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 409 B

View File

Before

Width:  |  Height:  |  Size: 539 B

After

Width:  |  Height:  |  Size: 539 B

View File

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 501 B

3
images/Phone.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-slot="icon">
<path clip-rule="evenodd" fill-rule="evenodd" d="M1.5 4.5a3 3 0 0 1 3-3h1.372c.86 0 1.61.586 1.819 1.42l1.105 4.423a1.875 1.875 0 0 1-.694 1.955l-1.293.97c-.135.101-.164.249-.126.352a11.285 11.285 0 0 0 6.697 6.697c.103.038.25.009.352-.126l.97-1.293a1.875 1.875 0 0 1 1.955-.694l4.423 1.105c.834.209 1.42.959 1.42 1.82V19.5a3 3 0 0 1-3 3h-2.25C8.552 22.5 1.5 15.448 1.5 6.75V4.5Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 514 B

View File

Before

Width:  |  Height:  |  Size: 589 B

After

Width:  |  Height:  |  Size: 589 B

View File

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 418 B

3
images/UserCircle.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-slot="icon">
<path clip-rule="evenodd" fill-rule="evenodd" d="M18.685 19.097A9.723 9.723 0 0 0 21.75 12c0-5.385-4.365-9.75-9.75-9.75S2.25 6.615 2.25 12a9.723 9.723 0 0 0 3.065 7.097A9.716 9.716 0 0 0 12 21.75a9.716 9.716 0 0 0 6.685-2.653Zm-12.54-1.285A7.486 7.486 0 0 1 12 15a7.486 7.486 0 0 1 5.855 2.812A8.224 8.224 0 0 1 12 20.25a8.224 8.224 0 0 1-5.855-2.438ZM15.75 9a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 539 B

View File

Before

Width:  |  Height:  |  Size: 733 B

After

Width:  |  Height:  |  Size: 733 B

View File

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 490 B

View File

@@ -2,7 +2,6 @@ from .DbManager import DbManager
import json
import mariadb
from PySide6.QtCore import QObject, Signal
# from ..PyqcrmFlags import PyqcrmAppliEmpyFlags
class EmployeeDAO(QObject):
@@ -17,35 +16,30 @@ class EmployeeDAO(QObject):
if self.__con:
self.__cur = self.__con.cursor()
def getEmployees(self, enc_key, criterion = "Alle", processed = False, fired = False, every_state = True):
def getEmployees(self, enc_key, criterion="Alle", processed=False, fired=False, every_state=True):
try:
if self.__cur:
self.__cur.callproc("getEmployeeTable", (criterion, processed, fired, every_state, enc_key, ))
self.__cur.callproc("getEmployeeTable", (criterion, processed, fired, every_state, enc_key,))
self.__all_cols = [desc[0] for desc in self.__cur.description]
return self.__cur.fetchall(), self.__all_cols
return self.__cur.fetchall(), self.__all_cols
else:
return None, None
except mariadb.Error as e:
print(str(e))
def getEmployee(self, employee_id, enc_key = None):
def getEmployee(self, employee_id, enc_key=None):
try:
if self.__cur:
self.__cur.callproc("getEmployee", (employee_id, enc_key,))
#self.__all_cols = [desc[0] for desc in self.__cur.description]
return self.__cur.fetchall() #, self.__all_cols
# self.__all_cols = [desc[0] for desc in self.__cur.description]
return self.__cur.fetchall() # , self.__all_cols
else:
return None #, None
return None
except mariadb.Error as e:
print(str(e))
def addEmployee(self, data, enc_key, applicant = True):
try:
if self.__cur:
self.__cur.callproc("addApplicant", (json.dumps(data), applicant, enc_key,))
self.__con.commit()
self.newEmployeeAdded.emit(True)
except mariadb.Error as e:
print(str(e))
self.newEmployeeAdded.emit(False)
def addEmployee(self, data, enc_key, applicant=True):
if self.__cur:
self.__cur.callproc("addApplicant", (json.dumps(data), applicant, enc_key,))
self.__con.commit()
self.newEmployeeAdded.emit(True)

View File

@@ -1,4 +1,8 @@
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, Slot, Signal
import json
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, Slot, Signal, QJsonDocument
from PySide6.QtQml import QJSValue
from .EmployeeDAO import EmployeeDAO
# from ..PyqcrmFlags import PyqcrmFlags, PyqcrmAppliEmpyFlags
from ..ConfigLoader import ConfigLoader
@@ -12,7 +16,6 @@ class EmployeeModel(QAbstractTableModel):
__visible_index = None
__visible_columns = None
__col_name = ""
__employee_dao = None
__col_skip = 2
__everyone = True
@@ -24,12 +27,28 @@ class EmployeeModel(QAbstractTableModel):
self.__key = self.__conf['pyqcrm']['ENCRYPTION_KEY']
self.__getData()
@Slot(dict, bool)
def addEmployee(self, new_employee, applicant = True):
@Slot(dict)
def addEmployee(self, new_employee):
if 'worklicense' in new_employee:
new_employee['worklicense'] = int(new_employee['worklicense'])
new_employee['residencetype'] = int(new_employee['residencetype'])
self.__employee_dao.addEmployee(new_employee, self.__key, applicant)
self.__employee_dao.addEmployee(new_employee, self.__key, False)
@Slot(QJSValue)
def addApplicant(self, applicant: QJSValue):
self.__employee_dao.addEmployee({
"city": applicant.property("city").toString(),
"email": applicant.property("email").toString(),
"firstname": applicant.property("firstname").toString(),
"formofaddress": applicant.property("formofaddress").toString(),
"houseno": applicant.property("houseno").toString(),
"lastname": applicant.property("lastname").toString(),
"mobile": applicant.property("mobile").toString(),
"phone": applicant.property("phone").toString(),
"postcode": applicant.property("postcode").toInt(),
"street": applicant.property("street").toString(),
"title": applicant.property("title").toString(),
}, self.__key, True)
@Slot(bool)
def __refreshView(self, added):
@@ -37,43 +56,42 @@ class EmployeeModel(QAbstractTableModel):
self.__getData()
self.addedNewEmployee.emit(added)
def __getData(self, criterion = "Alle", processed = False, fired = False, every_state = True):
def __getData(self, criterion="Alle", processed=False, fired=False, every_state=True):
self.beginResetModel()
rows, self.__visible_columns = self.__employee_dao.getEmployees(self.__key, criterion, processed, fired, every_state)
rows, self.__visible_columns = self.__employee_dao.getEmployees(self.__key, criterion, processed, fired,
every_state)
self.__data = rows
self.endResetModel()
def rowCount(self, parent= QModelIndex()):
return len (self.__data)
def rowCount(self, parent=QModelIndex()):
return len(self.__data)
def columnCount(self, parent= QModelIndex()):
def columnCount(self, parent=QModelIndex()):
return len(self.__visible_columns) - self.__col_skip
@Slot(str, bool, bool, bool)
def viewCriterion(self, criterion, processed, fired, every_state):
self.__everyone = True if criterion == 'Alle' else False
if self.__everyone and criterion != "Alle":
self.__col_skip = 2
else:
self.__col_skip = 2
self.__getData(criterion, processed, fired, every_state)
@Slot(str)
def viewCriterion(self, criterion):
self.__everyone = criterion == 'Alle'
self.__col_skip = 2
self.__getData(criterion, criterion == 'Erledigt', False, criterion == 'Alle')
def data(self, index, role= Qt.DisplayRole):
def data(self, index, role=Qt.DisplayRole):
if role == Qt.DisplayRole:
row = self.__data[index.row()]
applicant_col = index.column() + self.__col_skip
tr = row[applicant_col] #if type(row[index.column() + 2]) is str else str(row[index.column() + 2], "utf-8")
tr = row[
applicant_col] # if type(row[index.column() + 2]) is str else str(row[index.column() + 2], "utf-8")
if applicant_col == 2 and self.__everyone:
tr = 'Ja' if tr == 1 else 'Nein'
else:
if tr:
tr = re.sub("Keine Angabe ","", tr)
#print(f"Data: {tr}")
tr = re.sub("Keine Angabe ", "", tr)
# print(f"Data: {tr}")
# return row[index.column() + 2]
return tr
return None
def headerData(self, section, orientation, role = Qt.DisplayRole):
def headerData(self, section, orientation, role=Qt.DisplayRole):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
self.__col_name = self.__visible_columns[section + self.__col_skip]
return self.__col_name
@@ -81,11 +99,11 @@ class EmployeeModel(QAbstractTableModel):
@Slot(int)
def onRowClicked(self, row):
#print(self.__data)
# print(self.__data)
print(f"Selected table row: {row}, corresponding DB ID: {self.__data[row][0]}")
#if not self.__employee_dict['employee'] or self.__data[row][0] != self.__employee_dict['employee']['id']:
#self.__employee = self.__employee_dao.getEmployee(self.__data[row][0], self.__key)
#print(self.__business)
#self.__getEmployeeInfo()
# self.__getContactInfo()
# print(self.__business_dict)
# if not self.__employee_dict['employee'] or self.__data[row][0] != self.__employee_dict['employee']['id']:
# self.__employee = self.__employee_dao.getEmployee(self.__data[row][0], self.__key)
# print(self.__business)
# self.__getEmployeeInfo()
# self.__getContactInfo()
# print(self.__business_dict)

View File

@@ -1,6 +1,5 @@
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, Slot, Signal
from .ObjectDAO import ObjectDAO
# from ..PyqcrmFlags import PyqcrmFlags, PyqcrmAppliEmpyFlags
from ..ConfigLoader import ConfigLoader
import re
import json

View File

@@ -1,13 +1,24 @@
<RCC>
<qresource prefix="/">
<file>qtquickcontrols2.conf</file>
<file>images/ArrowLeftCircle-Outline.svg</file>
<file>images/ArrowRightEndOnRectangle.svg</file>
<file>images/Bars3.svg</file>
<file>images/BuildingOffice2-Outline.svg</file>
<file>images/CheckCircle.svg</file>
<file>images/ChevronDown.svg</file>
<file>images/Funnel.svg</file>
<file>images/Identification-Outline.svg</file>
<file>images/MagnifyingGlass.svg</file>
<file>images/Newspaper-Outline.svg</file>
<file>images/Phone.svg</file>
<file>images/PlusCircle.svg</file>
<file>images/RectangleStack-Outline.svg</file>
<file>images/Square3Stack3D-Outline.svg</file>
<file>images/tero.jpg</file>
<file>images/UserCircle.svg</file>
<file>images/UserGroup-Outline.svg</file>
<file>images/Wallet-Outline.svg</file>
<file>sounds/error.ogg</file>
<file>sounds/fail2c.ogg</file>
<file>sounds/puzzerr.ogg</file>
@@ -17,12 +28,5 @@
<file>README</file>
<file>LICENSE</file>
<file>images/tero.jpg</file>
<file>images/dash.svg</file>
<file>images/invoice.svg</file>
<file>images/offer.svg</file>
<file>images/employee.svg</file>
<file>images/customer.svg</file>
<file>images/contract.svg</file>
<file>images/object.svg</file>
</qresource>
</RCC>

34
qml.qrc
View File

@@ -7,32 +7,21 @@
<file>Gui/LoginScreen.qml</file>
<file>Gui/AddContact.qml</file>
<file>Gui/AddCustomer.qml</file>
<file>Gui/CustomerTable.qml</file>
<file>Gui/Dashboard.qml</file>
<file>Gui/EmployeeTable.qml</file>
<file>Gui/main.qml</file>
<file>Gui/SearchBar.qml</file>
<file>js/qmldict.js</file>
<file>Gui/CustomerView.qml</file>
<file>Gui/NoDbConnection.qml</file>
<file>Gui/Notifications.qml</file>
<file>Gui/ObjectTable.qml</file>
<file>Gui/AddObject.qml</file>
<file>Gui/ObjectView.qml</file>
<file>Gui/ObjectAddOns.qml</file>
<file>Gui/ObjectAddOnContactPerson.qml</file>
<file>Gui/ObjectAddOnEmployee.qml</file>
<file>Gui/AddObjectEmployee.qml</file>
<file>Gui/AddApplicant.qml</file>
<file>Gui/ApplicantPersonalData.qml</file>
<file>Gui/ApplicantBankData.qml</file>
<file>Gui/ApplicantNationalInsurance.qml</file>
<file>Gui/ApplicantVarious.qml</file>
<file>Gui/CustomersTable.qml</file>
<file>Gui/CustomerDetails.qml</file>
<file>Gui/ObjectsTable.qml</file>
<file>Gui/EmployeesTable.qml</file>
<file>Gui/EmployeeDetails.qml</file>
<file>Gui/ObjectDetails.qml</file>
<file>Gui/AddNewObject.qml</file>
<file>Gui/PrinterDialog.qml</file>
@@ -48,20 +37,39 @@
<file>Gui/MiscConf.qml</file>
<file>Gui/UtilityDialogs.qml</file>
<file>Gui/OffersTable.qml</file>
<file>Gui/OfferTable.qml</file>
<file>Gui/Employees/AddApplicant.qml</file>
<file>Gui/Employees/AddEmployee.qml</file>
<file>Gui/Employees/ApplicantPersonalData.qml</file>
<file>Gui/Employees/ApplicantBankData.qml</file>
<file>Gui/Employees/ApplicantForm.qml</file>
<file>Gui/Employees/ApplicantNationalInsurance.qml</file>
<file>Gui/Employees/ApplicantVarious.qml</file>
<file>Gui/Employees/EmployeeDetails.qml</file>
<file>Gui/Employees/EmployeesTable.qml</file>
<file>Gui/Employees/qmldir</file>
<file>TeroStyle/BarButton.qml</file>
<file>TeroStyle/Button.qml</file>
<file>TeroStyle/Colors.qml</file>
<file>TeroStyle/ComboBox.qml</file>
<file>TeroStyle/Dimensions.qml</file>
<file>TeroStyle/EmailAddressValidator.qml</file>
<file>TeroStyle/Field.qml</file>
<file>TeroStyle/H1.qml</file>
<file>TeroStyle/H2.qml</file>
<file>TeroStyle/Label.qml</file>
<file>TeroStyle/NotEmptyValidator.qml</file>
<file>TeroStyle/OptionalEmailAddressValidator.qml</file>
<file>TeroStyle/OptionalPhoneNumberValidator.qml</file>
<file>TeroStyle/PhoneNumberValidator.qml</file>
<file>TeroStyle/PostcodeValidator.qml</file>
<file>TeroStyle/qmldir</file>
<file>TeroStyle/QuickFilter.qml</file>
<file>TeroStyle/SearchBar.qml</file>
<file>TeroStyle/TextField.qml</file>
<file>TeroStyle/Typography.qml</file>
<file>TeroStyle/BarButton.qml</file>
<file>Gui/AddOffer.qml</file>
<file>Gui/AddNewOffer.qml</file>
</qresource>
<qresource prefix="/Common"/>
<qresource prefix="/TeroStyle"/>
</RCC>