diff --git a/web/instance/test.db b/web/instance/test.db index 88f1be94..e118a4ab 100644 Binary files a/web/instance/test.db and b/web/instance/test.db differ diff --git a/web/minibase/blueprints/company/__pycache__/forms.cpython-311.pyc b/web/minibase/blueprints/company/__pycache__/forms.cpython-311.pyc index cd7de6aa..2f1c87a7 100644 Binary files a/web/minibase/blueprints/company/__pycache__/forms.cpython-311.pyc and b/web/minibase/blueprints/company/__pycache__/forms.cpython-311.pyc differ diff --git a/web/minibase/blueprints/company/__pycache__/routes.cpython-311.pyc b/web/minibase/blueprints/company/__pycache__/routes.cpython-311.pyc index 62dff425..5a8b1904 100644 Binary files a/web/minibase/blueprints/company/__pycache__/routes.cpython-311.pyc and b/web/minibase/blueprints/company/__pycache__/routes.cpython-311.pyc differ diff --git a/web/minibase/blueprints/company/forms.py b/web/minibase/blueprints/company/forms.py index 6e2d6f62..5fea3b3f 100644 --- a/web/minibase/blueprints/company/forms.py +++ b/web/minibase/blueprints/company/forms.py @@ -32,7 +32,7 @@ class companyForm(FlaskForm): # Defines the form class to be used for the user submit = SubmitField() - def populate_for_update(self, company): + def populate_for_updating(self, company): self.submit.label.text = "Update" self.country_id.choices = [(row.id, row.name) for row in geoUtils.queryCountryNamesWithDefault(company.country_id)] @@ -54,6 +54,7 @@ class companyForm(FlaskForm): # Defines the form class to be used for the user self.submit.label.text = "Add" del self.image_file + self.country_id.choices = [(row.id, row.name) for row in geoUtils.queryCountryNames()] # This is for the htmx implementation. please be careful how of there is data we switch the funtion needed diff --git a/web/minibase/blueprints/company/routes.py b/web/minibase/blueprints/company/routes.py index b0a7781e..f9057c0f 100644 --- a/web/minibase/blueprints/company/routes.py +++ b/web/minibase/blueprints/company/routes.py @@ -1,12 +1,9 @@ from flask import render_template, url_for, flash, redirect, request, Blueprint -from flask_login import login_required, current_user +from flask_login import login_required import minibase.theme as theme from minibase.blueprints.company.models import Companies -from minibase.blueprints.geography.models import City import minibase.blueprints.database.utils as dbUtils import minibase.blueprints.main.utils as mainUtils -import minibase.blueprints.geography.utils as geoUtils -import minibase.blueprints.company.utils as companyUtils from minibase.blueprints.company.forms import companyForm # Declaring a blueprint @@ -26,8 +23,7 @@ def account(companyId): if companyId: company = Companies.query.get_or_404(companyId) form = companyForm() - form.populate_for_update(company) - + form.populate_for_updating(company) _accountInfo = mainUtils.accountInfo( title=company.name, description=company.legal_entity.name, @@ -55,7 +51,6 @@ def account(companyId): return redirect(url_for('company.list')) - @company.route("/add", methods=['GET', 'POST']) @login_required def add(): diff --git a/web/minibase/blueprints/sensor/__pycache__/forms.cpython-311.pyc b/web/minibase/blueprints/sensor/__pycache__/forms.cpython-311.pyc index af45123c..aa521cc7 100644 Binary files a/web/minibase/blueprints/sensor/__pycache__/forms.cpython-311.pyc and b/web/minibase/blueprints/sensor/__pycache__/forms.cpython-311.pyc differ diff --git a/web/minibase/blueprints/sensor/__pycache__/models.cpython-311.pyc b/web/minibase/blueprints/sensor/__pycache__/models.cpython-311.pyc index fb9244c2..c427c599 100644 Binary files a/web/minibase/blueprints/sensor/__pycache__/models.cpython-311.pyc and b/web/minibase/blueprints/sensor/__pycache__/models.cpython-311.pyc differ diff --git a/web/minibase/blueprints/sensor/__pycache__/routes.cpython-311.pyc b/web/minibase/blueprints/sensor/__pycache__/routes.cpython-311.pyc index 9bb30bde..d83ead71 100644 Binary files a/web/minibase/blueprints/sensor/__pycache__/routes.cpython-311.pyc and b/web/minibase/blueprints/sensor/__pycache__/routes.cpython-311.pyc differ diff --git a/web/minibase/blueprints/sensor/forms.py b/web/minibase/blueprints/sensor/forms.py index c70ed270..aaaeec6d 100644 --- a/web/minibase/blueprints/sensor/forms.py +++ b/web/minibase/blueprints/sensor/forms.py @@ -1,14 +1,17 @@ from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileAllowed -from wtforms import StringField, PasswordField, SubmitField, BooleanField, URLField, IntegerField, DateField, SelectField -from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError +from wtforms import StringField, SubmitField, BooleanField, URLField, IntegerField, DateField, SelectField +from wtforms.validators import DataRequired, Length, ValidationError from minibase.blueprints.sensor.models import nbiotDevice +import minibase.blueprints.company.utils as companyUtils +import minibase.blueprints.user.utils as userUtils +import minibase.blueprints.sensor.utils as sensorUtils from datetime import date -class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be used for the user update +class nbiotDeviceForm(FlaskForm): # Defines the self class to be used for the user update name = StringField('Device Name', validators=[DataRequired(), Length(min=3, max=50)]) - device_id = StringField('Device Id', validators=[DataRequired(), Length(min=3, max=50)]) serial_no = StringField('Serial Number', validators=[DataRequired(), Length(min=3, max=50)]) + device_id = StringField('Device Id', validators=[DataRequired(), Length(min=3, max=50)]) imsi = StringField('Imsi No', validators=[DataRequired(), Length(min=10, max=50)]) iccid = StringField('Iccid No', validators=[DataRequired(), Length(min=10, max=100)]) ip = StringField('Ip (ipv4)', validators=[DataRequired(), Length(min=7, max=15)]) @@ -21,87 +24,66 @@ class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be use status_id = SelectField('Status', validators=[DataRequired()]) type_id = SelectField('Type', validators=[DataRequired()]) area_id = SelectField('Area', validators=[DataRequired()]) - manufacturer_id = SelectField('Manufacturer', validators=[DataRequired()]) + manufacturer_id = SelectField('Manufacturer', validators=[DataRequired()], + render_kw={ + 'hx-target': '#manufacturer_id', # Target div or modal for the popup + 'hx-swap': 'outerHTML' # Swap the outer HTML of the target element + }) company_id = SelectField('Managed By', validators=[DataRequired()]) - picture = FileField('Update Sensor Picture', validators=[FileAllowed(['jpg', 'png'])]) - submit = SubmitField(f'Update') + image_file = FileField('Update Sensor Picture', validators=[FileAllowed(['jpg', 'png'])]) + + submit = SubmitField() + + def populate_for_updating(self, device): + self.submit.label.text = "Update" + self.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.device_user_id)] + self.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.device_owner_id)] + self.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_manufacturer_id)] + self.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_owner_id)] + self.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusNamesWithDefault(device.status_id)] + self.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeNamesWithDefault(device.type_id)] + self.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaNamesWithDefault(device.area_id)] - def __init__(self, current_device_id, *args, **kwargs): - super().__init__(*args, **kwargs) - self.current_device = nbiotDevice.query.get(current_device_id) + def populate_for_adding(self, device): + self.submit.label.text = "Add" + + if self.manufacturer_id.data: + self.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(self.manufacturer_id.data)] + + self.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.device_user_id)] + self.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.device_owner_id)] + self.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_manufacturer_id)] + self.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_owner_id)] + self.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusNamesWithDefault(device.status_id)] + self.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeNamesWithDefault(device.type_id)] + self.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaNamesWithDefault(device.area_id)] def validate_name(self, input): - if input.data != self.current_device.name: + if input.data != self.name: content = nbiotDevice.query.filter_by(name=input.data).first() if content: raise ValidationError('That device name is taken please choose another one') - + def validate_device_id(self, input): - if input.data != self.current_device.device_id: + if input.data != self.device_id: content = nbiotDevice.query.filter_by(device_id=input.data).first() if content: raise ValidationError('That device id is taken please choose another one') - + def validate_imsi(self, input): - if input.data != self.current_device.imsi: + if input.data != self.imsi: content = nbiotDevice.query.filter_by(imsi=input.data).first() if content: raise ValidationError('That IMSI id is taken please choose another one') def validate_iccid(self, input): - if input.data != self.current_device.iccid: + if input.data != self.iccid: content = nbiotDevice.query.filter_by(iccid=input.data).first() if content: raise ValidationError('That ICCID id is taken please choose another one') - + def validate_ip(self, input): - if input.data != self.current_device.ip: + if input.data != self.ip: content = nbiotDevice.query.filter_by(ip=input.data).first() if content: raise ValidationError('That IP id is taken please choose another one') - -class updateNbioDeviceAddForm(FlaskForm): # Defines the form class to be used for the user update - name = StringField('Device Name', validators=[DataRequired(), Length(min=3, max=50)]) - device_id = StringField('Device Id', validators=[DataRequired(), Length(min=3, max=50)]) - serial_no = StringField('Serial Number', validators=[DataRequired(), Length(min=3, max=50)]) - imsi = StringField('Imsi No', validators=[DataRequired(), Length(min=10, max=50)]) - iccid = StringField('Iccid No', validators=[DataRequired(), Length(min=10, max=100)]) - ip = StringField('Ip (ipv4)', validators=[Length(min=7, max=15)]) - port = StringField('Port', validators=[Length(min=3, max=10)]) - registration_date = DateField('Registration Date', format='%Y-%m-%d', default=date.today, validators=[DataRequired()]) - activation_date = DateField('Activation Date', format='%Y-%m-%d', default=date.today, validators=[DataRequired()]) - deactivation_date = DateField('Deactivation Date', format='%Y-%m-%d', default=date.today, validators=[DataRequired()]) - user_id = SelectField('Owner', validators=[DataRequired()]) - status_id = SelectField('Status', validators=[DataRequired()]) - type_id = SelectField('Type', validators=[DataRequired()]) - area_id = SelectField('Area', validators=[DataRequired()]) - manufacturer_id = SelectField('Manufacturer', validators=[DataRequired()]) - company_id = SelectField('Managed By', validators=[DataRequired()]) - - submit = SubmitField(f'Add') - - def validate_name(self, input): - content = nbiotDevice.query.filter_by(name=input.data).first() - if content: - raise ValidationError('That device name is taken please choose another one') - - def validate_device_id(self, input): - content = nbiotDevice.query.filter_by(device_id=input.data).first() - if content: - raise ValidationError('That device id is taken please choose another one') - - def validate_imsi(self, input): - content = nbiotDevice.query.filter_by(imsi=input.data).first() - if content: - raise ValidationError('That IMSI id is taken please choose another one') - - def validate_iccid(self, input): - content = nbiotDevice.query.filter_by(iccid=input.data).first() - if content: - raise ValidationError('That ICCID id is taken please choose another one') - - def validate_ip(self, input): - content = nbiotDevice.query.filter_by(ip=input.data).first() - if content: - raise ValidationError('That IP id is taken please choose another one') - diff --git a/web/minibase/blueprints/sensor/routes.py b/web/minibase/blueprints/sensor/routes.py index b384e1c2..a427686c 100644 --- a/web/minibase/blueprints/sensor/routes.py +++ b/web/minibase/blueprints/sensor/routes.py @@ -1,11 +1,10 @@ from flask import render_template, Blueprint, request, flash, redirect, url_for, jsonify import minibase.theme as theme from minibase.blueprints.sensor.models import nbiotDevice +from minibase.blueprints.company.models import Companies import minibase.blueprints.sensor.utils as sensorUtils -from minibase.blueprints.sensor.forms import updateNbioDeviceUpdateForm, updateNbioDeviceAddForm +from minibase.blueprints.sensor.forms import nbiotDeviceForm import minibase.blueprints.database.utils as dbUtils -import minibase.blueprints.company.utils as companyUtils -import minibase.blueprints.user.utils as userUtils import minibase.blueprints.main.utils as mainUtils from minibase.app import db import json @@ -13,6 +12,7 @@ import os sensor = Blueprint('sensor', __name__, template_folder='templates') +_form = () DATA_FILE = 'data.json' @@ -76,60 +76,32 @@ def list(): def edit(deviceId): if deviceId: device = nbiotDevice.query.get_or_404(deviceId) - form = updateNbioDeviceUpdateForm(current_device_id=device.id) - form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.device_user_id)] - form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.device_owner_id)] - form.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_manufacturer_id)] - form.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_owner_id)] - form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusNamesWithDefault(device.status_id)] - form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeNamesWithDefault(device.type_id)] - form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaNamesWithDefault(device.area_id)] + form = nbiotDeviceForm() + form.populate_for_updating(device) + _accountInfo = mainUtils.accountInfo( + title=device.name, + description=device.legal_entity.name, + short=device.website, + status=device.type.name, + image_file=mainUtils.imageFileLink(device.image_file) + ) + if form.validate_on_submit(): if form.picture.data: picture_file = mainUtils.save_picture(form.picture.data) device.image_file = picture_file - device.name=form.name.data - device.serial_no = form.serial_no.data - device.device_id=form.device_id.data - device.imsi=form.imsi.data - device.iccid=form.iccid.data - device.ip=form.ip.data - device.port=form.port.data - device.registration_date=form.registration_date.data - device.activation_date=form.activation_date.data - device.deactivation_date=form.deactivation_date.data - device.device_owner_id=form.owner_id.data - device.device_user_id=form.user_id.data - device.status_id=form.status_id.data - device.type_id=form.type_id.data - device.area_id=form.area_id.data - device.company_manufacturer_id = form.manufacturer_id.data - device.company_owner_id = form.company_id.data + + mainUtils.fill_model(device, form) db.session.commit() flash('Device has been successfully updated', 'success') return redirect(url_for('sensor.edit', deviceId=deviceId)) + elif request.method == 'GET': - form.name.data = device.name - form.serial_no.data = device.serial_no - form.device_id.data = device.device_id - form.imsi.data = device.imsi - form.iccid.data = device.iccid - form.ip.data = device.ip - form.port.data = device.port - form.registration_date.data = device.registration_date - form.activation_date.data = device.activation_date - form.deactivation_date.data = device.deactivation_date - form.user_id.data = device.device_user.username - form.owner_id.data = device.device_owner.username - form.manufacturer_id.data = device.company_manufacturer.name - form.company_id.data = device.company_owner.name - form.status_id.data = device.status.name - form.type_id.data = device.type.name - form.area_id.data = device.area.name - image_file = url_for('static', filename='pics/' + sensorUtils.queryImageById(deviceId)) - return render_template('sensor/account.html', + mainUtils.populate_form(form, device) + + return render_template('account.html', theme=theme, - image_file=image_file, + accountInfo=_accountInfo, form=form) else: flash('You need to select a Device id', 'alarm') @@ -138,29 +110,39 @@ def edit(deviceId): @sensor.route('/add', methods=['GET', 'POST']) def add(): - form = updateNbioDeviceAddForm() - form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserChoices(1)] - form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusChoices(1)] - form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeChoices(1)] - form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaChoices(1)] + device = nbiotDevice() + form = nbiotDeviceForm() + print(f"Route : manufacturer_id : { form.manufacturer_id.data }") + form.populate_for_adding(device) + + + if request.method == 'GET': + form.populate_for_adding(device) + if form.validate_on_submit(): - dev = nbiotDevice( - name=form.name.data, - device_id=form.device_id.data, - imsi=form.imsi.data, - iccid=form.iccid.data, - ip=form.ip.data, - port=form.port.data, - registration_date=form.registration_date.data, - activation_date=form.activation_date.data, - deactivation_date=form.deactivation_date.data, - user_id=form.user_id.data, - status_id=form.status_id.data, - type_id=form.type_id.data, - area_id=form.area_id.data) - dbUtils.dbAddAndCommit(dev) + mainUtils.fill_model(device, form) + #dbUtils.dbAddAndCommit(device) flash('Device has been successfully added', 'success') - return render_template('sensor/account.html', + return render_template('edit.html', theme=theme, form=form) + +@sensor.route('/search/', methods=['GET']) +def search_field(field_name): + query = request.args.get('modalQueryArg', '') + # Assuming field_name corresponds to a model field, you would add conditional logic here to query the correct model. + if field_name == 'manufacturer_id': + results = Companies.query.filter(Companies.name.ilike(f'%{query}%')).all() + # Add more conditions for other fields as needed + return render_template('sensor/manufacturer_search_results.html', results=results, field_name=field_name) + + +@sensor.route('/select//', methods=['GET']) +def select_field(field_name, result_id): + # Return the selected option + # This is a simplified example, you'll need to adapt this to your specific model fields and logic. + if field_name == 'manufacturer_id': + selected = Companies.query.get(result_id) + return render_template("sensor/manufacturer_options.html", selected=selected) + diff --git a/web/minibase/blueprints/sensor/templates/sensor/manufacturer_options.html b/web/minibase/blueprints/sensor/templates/sensor/manufacturer_options.html new file mode 100644 index 00000000..fb4d2fab --- /dev/null +++ b/web/minibase/blueprints/sensor/templates/sensor/manufacturer_options.html @@ -0,0 +1,3 @@ + diff --git a/web/minibase/blueprints/sensor/templates/sensor/manufacturer_search_results.html b/web/minibase/blueprints/sensor/templates/sensor/manufacturer_search_results.html new file mode 100644 index 00000000..636c830c --- /dev/null +++ b/web/minibase/blueprints/sensor/templates/sensor/manufacturer_search_results.html @@ -0,0 +1,7 @@ + diff --git a/web/minibase/templates/edit.html b/web/minibase/templates/edit.html index 38540c37..eb4c26fb 100644 --- a/web/minibase/templates/edit.html +++ b/web/minibase/templates/edit.html @@ -5,7 +5,7 @@

{{ title }}

- {% include 'form.html' %} + {% include 'formModal.html' %} {% if extraButtons %}
@@ -18,5 +18,4 @@
{% endif %} - {% endblock content %} diff --git a/web/minibase/templates/editModal.html b/web/minibase/templates/editModal.html new file mode 100644 index 00000000..bdef555a --- /dev/null +++ b/web/minibase/templates/editModal.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% block title %}{{ title }}{% endblock %} +{% block content %} +
+

{{ title }}

+
+
+ {% include 'form.html' %} + {% if extraButtons %} +
+
+
+
+ {% for button in extraButtons %} +
  • {{ button.name }} + {% endfor %} +
    +
  • + {% endif %} +
    +{% endblock content %} diff --git a/web/minibase/templates/form/allFieldsModal.html b/web/minibase/templates/form/allFieldsModal.html new file mode 100644 index 00000000..342a5ecb --- /dev/null +++ b/web/minibase/templates/form/allFieldsModal.html @@ -0,0 +1,7 @@ +{% include 'form/stringField.html' %} +{% include 'form/selectFieldModal.html' %} +{% include 'form/dateField.html' %} +{% include 'form/boolField.html' %} +{% include 'form/fileField.html' %} +{% include 'form/urlField.html' %} +{% include 'form/integerField.html' %} diff --git a/web/minibase/templates/form/selectField.html b/web/minibase/templates/form/selectField.html index 92237bd6..c73e3524 100644 --- a/web/minibase/templates/form/selectField.html +++ b/web/minibase/templates/form/selectField.html @@ -2,5 +2,5 @@
    {{ item.label(class=theme.form.select_label_class, style=theme.form.select_label_style) }}
    - {{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style)}} -{% endif %} + {{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style)}} + {% endif %} diff --git a/web/minibase/templates/form/selectFieldModal.html b/web/minibase/templates/form/selectFieldModal.html new file mode 100644 index 00000000..22e34208 --- /dev/null +++ b/web/minibase/templates/form/selectFieldModal.html @@ -0,0 +1,33 @@ +{% if item.type in ['SelectField'] %} +
    + {{ item.label(class=theme.form.select_label_class, style=theme.form.select_label_style) }} +
    +
    + {{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style)}} + +
    + +{% endif %} diff --git a/web/minibase/templates/formModal.html b/web/minibase/templates/formModal.html new file mode 100644 index 00000000..433d0856 --- /dev/null +++ b/web/minibase/templates/formModal.html @@ -0,0 +1,18 @@ +
    + {{ form.hidden_tag() }} +
    + {% for item in form %} + {% if item.id == 'submit' %} + {% elif item.id == 'csrf_token' %} + {% else %} + {% include 'form/allFieldsModal.html' %} + {% if item.errors %} + {% include 'form/formError.html' %} + {% endif %} + {% endif %} + {% endfor %} +
    +
    + {% include 'form/submitField.html' %} +
    +