Was able to successfully implement htmx for interactive select. The advacement requires new documentation. sensor update have been implmented, sensor_add, sensor_account are the next steps

master
Kerem Yollu 10 months ago
parent a3858ff048
commit 996b2cdfcd

79
web/$

@ -1,79 +0,0 @@
from flask import render_template, url_for, flash, redirect, request, Blueprint
from flask_login import login_required, current_user
from minibase.app import db
import minibase.theme as theme
from minibase.blueprints.company.models import Companies
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 updateCompanyForm
from minibase.blueprints.user.utils import save_picture
from flask_wtf import FlaskForm
# Declaring a blueprint
company = Blueprint('company', __name__, template_folder='templates')
@company.route("/list", methods=['GET', 'POST'])
def list():
page=request.args.get('page', 1, type=int)
table=dbUtils.table_printable_paginate(Companies, page, 20, 'edit/', 'id')
return(render_template('view.html', theme=theme, table=table, title="Companies"))
@company.route("/edit/<int:companyId>", methods=['GET', 'POST'])
@login_required
def edit_company(companyId):
if id:
form = updateCompanyForm()
company = companyUtils.queryById(companyId)
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCiytNamesOfStateWithDefId(company.city_id, company.state_id)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesOfCuntryWithDefId(company.state_id, company.country_id)]
form.country.choices = [(row.id, row.name) for row in geoUtils.queryCountryNamesWithDefault(company.country_id)]
form.industry.choices = [(row.id, row.name) for row in mainUtils.queryIndustryNamesWithDefault(company.industry_id)]
form.legal_entity.choices = [(row.id, row.name) for row in companyUtils.queryLegalEntityNames()]
form.type.choices = [(row.id, row.name) for row in companyUtils.queryTypeNames()]
form.relation.choices = [(row.id, row.name) for row in companyUtils.queryRelationNames()]
form.status.choices = [(row.id, row.name) for row in companyUtils.queryStatusNames()]
if form.validate_on_submit():
comp = Companies(
name = form.name.data,
street = form.street.data,
website = form.website.data,
street_no = form.street_no.data,
post_code = form.post_code.data,
city_id = form.city.data,
state_id = form.state.data,
country_id = form.country.data,
industry_id = form.industry.data,
legal_entity_id = form.legal_entity.data,
type_id = form.type.data,
relation_id = form.relation.data,
status_id = form.status.data,
comment = form.comment.data)
flash('Company Has been successfully updated', 'success')
return redirect(url_for('company.edit', companyId))
elif request.method == 'GET':
form.name.data = company.name
form.website.data = company.website
form.street.data = company.street
form.street_no.data = company.street_no
form.post_code.data = company.post_code
form.comment.data = company.comment
# This could be very interesting but neds more time to think !
#for field in form:
# if field.name != 'csrf_token' and hasattr(company, field.name):
# attr = getattr(company, field.name)
# field.data = attr
image_file = url_for('static', filename='pics/' + companyUtils.queryImageById(companyId))
return render_template('company/account.html',
theme=theme,
image_file=image_file,
form=form)
else:
flash('You need to select a company id', 'alarm')
return redirect(url_for('company.list'))

139
web/2

@ -0,0 +1,139 @@
from flask import render_template, Blueprint, request, flash, redirect, url_for
import minibase.theme as theme
from minibase.blueprints.sensor.models import nbiotDevice
import minibase.blueprints.sensor.utils as sensorUtils
from minibase.blueprints.sensor.forms import updateNbioDeviceUpdateForm, updateNbioDeviceAddForm
import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.company.utils as companyUtils
import minibase.blueprints.user.utils as userUtils
from minibase.app import db
import json
import os
sensor = Blueprint('sensor', __name__, template_folder='templates')
DATA_FILE = 'data.json'
sensor.route('/callback', methods=['POST'])
def callback():
data = request.json
if not data:
return jsonify({"error": "Invalid data"}), 400
# Read existing data
if os.path.exists(DATA_FILE):
with open(DATA_FILE, 'r') as f:
stored_data = json.load(f)
else:
stored_data = []
# Append new data
stored_data.append(data)
# Write data back to file
with open(DATA_FILE, 'w') as f:
json.dump(stored_data, f, indent=4)
return 'Callback received', 200
@sensor.route('/data', methods=['GET'])
def get_data():
if os.path.exists(DATA_FILE):
with open(DATA_FILE, 'r') as f:
stored_data = json.load(f)
else:
stored_data = []
return jsonify(stored_data)
@sensor.route('/list', methods=['GET','POST'])
def list():
page=request.args.get('page', 1, type=int)
table=dbUtils.table_printable_paginate(nbiotDevice, page, 20, 'edit/', 'id')
return(render_template('view.html', theme=theme, table=table, title="Devices List"))
@sensor.route("/edit/<int:deviceId>", methods=['GET', 'POST'])
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.user_id)]
form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)]
form.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.manufacturer_id)]
form.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_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)]
if form.validate_on_submit():
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.owner_id=form.owner_id.data
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.manufacturer_id = form.manufacturer_id.data
device.company_id = form.manufacturer_id.data
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
return render_template('sensor/account.html',
theme=theme,
form=form)
else:
flash('You need to select a Device id', 'alarm')
return redirect(url_for('sensor.list'))
@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)]
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)
flash('Device has been successfully added', 'success')
return render_template('sensor/account.html',
theme=theme,
form=form)

@ -0,0 +1 @@
,key,devbian,13.08.2024 18:20,file:///home/key/.config/libreoffice/4;

@ -1,2 +1,2 @@
name,device_id,serial_no,imsi,iccid,ip,port,user_id,owner_id,man_id,status_id,type_id,area_id name,device_id,serial_no,imsi,iccid,ip,port,user_id,owner_id,manufacturer_id,status_id,type_id,area_id,company_id
miniUni,24070580,24070576,901405710203483,89882280000107407542,10.128.24.42,50000,1,1,1,1,1,1 miniUni,24070580,24070576,901405710203483,898822800001074,10.128.24.42,50000,1,1,1,1,1,1,3

1 name device_id serial_no imsi iccid ip port user_id owner_id man_id manufacturer_id status_id type_id area_id company_id
2 miniUni 24070580 24070576 901405710203483 89882280000107407542 898822800001074 10.128.24.42 50000 1 1 1 1 1 1 1 3

Binary file not shown.

@ -50,6 +50,7 @@ def create_app():
from minibase.blueprints.errors.routes import errors from minibase.blueprints.errors.routes import errors
from minibase.blueprints.company.routes import company from minibase.blueprints.company.routes import company
from minibase.blueprints.geography.routes import geography from minibase.blueprints.geography.routes import geography
from minibase.blueprints.sensor.routes import sensor
# (BLUEPRINTS) Registering the blueprints. # (BLUEPRINTS) Registering the blueprints.
# Giving them theie ulr_prefixes that will define their links on the webBrowser. # Giving them theie ulr_prefixes that will define their links on the webBrowser.
@ -58,6 +59,7 @@ def create_app():
app.register_blueprint(errors, url_prefix='/errors') app.register_blueprint(errors, url_prefix='/errors')
app.register_blueprint(company, url_prefix='/company') app.register_blueprint(company, url_prefix='/company')
app.register_blueprint(geography, url_prefix='/geography') app.register_blueprint(geography, url_prefix='/geography')
app.register_blueprint(sensor, url_prefix='/sensor')
# (APP) Returning the initialised app # (APP) Returning the initialised app
return app return app

@ -3,15 +3,16 @@ from flask_wtf.file import FileField, FileAllowed
from wtforms import StringField, SubmitField, URLField, IntegerField, SelectField from wtforms import StringField, SubmitField, URLField, IntegerField, SelectField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
import minibase.blueprints.company.utils as companyUtils import minibase.blueprints.company.utils as companyUtils
import minibase.theme as theme
class updateCompanyForm(FlaskForm): # Defines the form class to be used for the user update class updateCompanyForm(FlaskForm): # Defines the form class to be used for the user update
name = StringField('Name', validators=[DataRequired(), Length(min=3, max=100)]) name = StringField('Name', validators=[DataRequired(), Length(min=3, max=100)])
website = URLField('Website', validators=[DataRequired(), Length(min=3, max=100)]) website = URLField('Website', validators=[DataRequired(), Length(min=3, max=100)])
country = SelectField('Country', validators=[DataRequired()]) country = SelectField('Country', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_cities", "hx-target": "#city"})
city = SelectField('City', validators=[DataRequired()]) city = SelectField('City', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_states", "hx-target": "#state"})
post_code = IntegerField('Post', validators=[DataRequired()])
state = SelectField('State', validators=[]) state = SelectField('State', validators=[])
post_code = IntegerField('Post', validators=[DataRequired()])
street = StringField('Street', validators=[DataRequired()]) street = StringField('Street', validators=[DataRequired()])
street_no = IntegerField('No', validators=[DataRequired()]) street_no = IntegerField('No', validators=[DataRequired()])
industry = SelectField('Industry', validators=[DataRequired()]) industry = SelectField('Industry', validators=[DataRequired()])
@ -21,7 +22,7 @@ class updateCompanyForm(FlaskForm): # Defines the form class to be used for the
status = SelectField('Status', validators=[DataRequired()]) status = SelectField('Status', validators=[DataRequired()])
comment = StringField('Comment', validators=[DataRequired(), Length(min=3, max=400)]) comment = StringField('Comment', validators=[DataRequired(), Length(min=3, max=400)])
image_file = FileField('Update company Picture', validators=[FileAllowed(['jpg', 'png'])]) picture = FileField('Update company Picture', validators=[FileAllowed(['jpg', 'png'])])
submit = SubmitField('Update') submit = SubmitField('Update')
@ -31,3 +32,29 @@ class updateCompanyForm(FlaskForm): # Defines the form class to be used for the
if company: if company:
raise ValidationError('That username is taken please choose another one') raise ValidationError('That username is taken please choose another one')
class addCompanyForm(FlaskForm): # Defines the form class to be used for the user update
name = StringField('Name', validators=[DataRequired(), Length(min=3, max=100)])
website = URLField('Website', validators=[DataRequired(), Length(min=3, max=100)])
country = SelectField('Country', validators=[DataRequired()],choices=[], render_kw={"hx-get": "/geography/get_cities", "hx-target": "#city"})
city = SelectField('City', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_states", "hx-target": "#state"})
state = SelectField('State', validators=[])
post_code = IntegerField('Post', validators=[DataRequired()])
street = StringField('Street', validators=[DataRequired()])
street_no = IntegerField('No', validators=[DataRequired()])
industry = SelectField('Industry', validators=[DataRequired()])
legal_entity= SelectField('Legal Entity', validators=[DataRequired()])
type = SelectField('Type', validators=[DataRequired()])
relation = SelectField('Relation', validators=[DataRequired()])
status = SelectField('Status', validators=[DataRequired()])
comment = StringField('Comment', validators=[DataRequired(), Length(min=3, max=400)])
submit = SubmitField('Add')
# Queries to be made in order to validate the form : If username exists
def validate_companyName(self, company_name):
company = companyUtils.queryByNameFirst(company_name)
if company:
raise ValidationError('That username is taken please choose another one')

@ -1,36 +1,41 @@
from flask import render_template, url_for, flash, redirect, request, Blueprint 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, current_user
from minibase.app import db
import minibase.theme as theme import minibase.theme as theme
from minibase.blueprints.company.models import Companies from minibase.blueprints.company.models import Companies
from minibase.blueprints.geography.models import City
import minibase.blueprints.database.utils as dbUtils import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.main.utils as mainUtils import minibase.blueprints.main.utils as mainUtils
import minibase.blueprints.geography.utils as geoUtils import minibase.blueprints.geography.utils as geoUtils
import minibase.blueprints.company.utils as companyUtils import minibase.blueprints.company.utils as companyUtils
from minibase.blueprints.company.forms import updateCompanyForm from minibase.blueprints.company.forms import updateCompanyForm, addCompanyForm
from minibase.blueprints.user.utils import save_picture
from flask_wtf import FlaskForm
# Declaring a blueprint # Declaring a blueprint
company = Blueprint('company', __name__, template_folder='templates') company = Blueprint('company', __name__, template_folder='templates')
@company.route("/", methods=['GET', 'POST']) @company.route("/list", methods=['GET', 'POST'])
def list(): def list():
page=request.args.get('page', 1, type=int) page=request.args.get('page', 1, type=int)
table=dbUtils.table_printable_paginate(Companies, page, 20, 'edit/', 'id') table=dbUtils.table_printable_paginate(Companies, page, 20, 'account/', 'id')
return(render_template('view.html', theme=theme, table=table, title="Companies")) return(render_template('view.html', theme=theme, table=table, title="Companies"))
@company.route("/edit/<int:companyId>", methods=['GET', 'POST']) @company.route("/account/<int:companyId>", methods=['GET', 'POST'])
@login_required @login_required
def edit_company(companyId): def account(companyId):
if companyId: if companyId:
company = Companies.query.get_or_404(companyId) company = Companies.query.get_or_404(companyId)
form = updateCompanyForm() form = updateCompanyForm()
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCiytNamesOfStateWithDefId(company.city_id, company.state_id)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesOfCuntryWithDefId(company.state_id, company.country_id)]
form.country.choices = [(row.id, row.name) for row in geoUtils.queryCountryNamesWithDefault(company.country_id)] form.country.choices = [(row.id, row.name) for row in geoUtils.queryCountryNamesWithDefault(company.country_id)]
# This is for the htmx implementation. please be careful how of there is data we switch the funtion needed
if form.country.data:
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryId(form.country.data)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryId(form.country.data)]
else:
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryIdWithDefault(company.city_id, company.country_id)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryIdWithDefault(company.state_id, company.country_id)]
form.industry.choices = [(row.id, row.name) for row in mainUtils.queryIndustryNamesWithDefault(company.industry_id)] form.industry.choices = [(row.id, row.name) for row in mainUtils.queryIndustryNamesWithDefault(company.industry_id)]
form.legal_entity.choices = [(row.id, row.name) for row in companyUtils.queryLegalEntityNamesWithDefault(company.legal_entity_id)] form.legal_entity.choices = [(row.id, row.name) for row in companyUtils.queryLegalEntityNamesWithDefault(company.legal_entity_id)]
form.type.choices = [(row.id, row.name) for row in companyUtils.queryTypeNamesWithDefault(company.type_id)] form.type.choices = [(row.id, row.name) for row in companyUtils.queryTypeNamesWithDefault(company.type_id)]
@ -38,31 +43,39 @@ def edit_company(companyId):
form.status.choices = [(row.id, row.name) for row in companyUtils.queryStatusNamesWithDefault(company.status_id)] form.status.choices = [(row.id, row.name) for row in companyUtils.queryStatusNamesWithDefault(company.status_id)]
if form.validate_on_submit(): if form.validate_on_submit():
if form.picture.data:
picture_file = mainUtils.save_picture(form.picture.data)
company.image_file = picture_file
company.name = form.name.data company.name = form.name.data
company.street = form.street.data
company.website = form.website.data company.website = form.website.data
company.street_no = form.street_no.data company.country_id = form.country.data
company.post_code = form.post_code.data
company.city_id = form.city.data company.city_id = form.city.data
company.state_id = form.state.data company.state_id = form.state.data
company.country_id = form.country.data company.post_code = form.post_code.data
company.street = form.street.data
company.street_no = form.street_no.data
company.industry_id = form.industry.data company.industry_id = form.industry.data
company.legal_entity_id = form.legal_entity.data company.legal_entity_id = form.legal_entity.data
company.type_id = form.type.data company.type_id = form.type.data
company.relation_id = form.relation.data company.relation_id = form.relation.data
company.status_id = form.status.data company.status_id = form.status.data
company.comment = form.comment.data company.comment = form.comment.data
dbUtils.dbCommit()
flash('Company Has been successfully updated', 'success') flash('Company Has been successfully updated', 'success')
return redirect(url_for('company.edit', companyId=companyId)) return redirect(url_for('company.account', companyId=companyId))
elif request.method == 'GET': elif request.method == 'GET':
form.name.data = company.name form.name.data = company.name
form.website.data = company.website form.website.data = company.website
form.country.data = company.country_id
form.city.data = company.city_id
form.state.data = company.state_id
form.post_code.data = company.post_code
form.street.data = company.street form.street.data = company.street
form.street_no.data = company.street_no form.street_no.data = company.street_no
form.post_code.data = company.post_code
form.comment.data = company.comment
form.legal_entity.data = company.legal_entity.name form.legal_entity.data = company.legal_entity.name
form.type.data = company.type.name form.type.data = company.type.name
form.comment.data = company.comment
image_file = url_for('static', filename='pics/' + companyUtils.queryImageById(companyId)) image_file = url_for('static', filename='pics/' + companyUtils.queryImageById(companyId))
@ -72,10 +85,50 @@ def edit_company(companyId):
form=form) form=form)
else: else:
flash('You need to select a company id', 'alarm') flash('You need to select a company id', 'alarm')
return redirect(url_for('company./')) return redirect(url_for('company.list'))
@company.route("/add", methods=['GET', 'POST'])
@login_required
def add():
form = addCompanyForm()
form.country.choices = [(row.id, row.name) for row in geoUtils.queryCountryNames()]
# This could be very interesting but neds more time to think ! # This is for the htmx implementation. please be careful how of there is data we switch the funtion needed
#for field in form: if form.country.data:
# if field.name != 'csrf_token' and hasattr(company, field.name): form.city.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryId(form.country.data)]
# attr = getattr(company, field.name) form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryId(form.country.data)]
# field.data = attr else:
form.city.choices = []
form.state.choices = []
form.industry.choices = [(row.id, row.name) for row in mainUtils.queryIndustryNames()]
form.legal_entity.choices = [(row.id, row.name) for row in companyUtils.queryLegalEntityNames()]
form.type.choices = [(row.id, row.name) for row in companyUtils.queryTypeNames()]
form.relation.choices = [(row.id, row.name) for row in companyUtils.queryRelationNames()]
form.status.choices = [(row.id, row.name) for row in companyUtils.queryStatusNames()]
if form.validate_on_submit():
company = Companies(
name = form.name.data,
website = form.website.data,
country_id = form.country.data,
city_id = form.city.data,
state_id = form.state.data,
post_code = form.post_code.data,
street = form.street.data,
street_no = form.street_no.data,
industry_id = form.industry.data,
legal_entity_id = form.legal_entity.data,
type_id = form.type.data,
relation_id = form.relation.data,
status_id = form.status.data,
comment = form.comment.data)
dbUtils.dbAddAndCommit(company)
flash('Company Has been successfully added', 'success')
return redirect(url_for('company.list'))
return render_template('edit.html',
title="Add Company",
theme=theme,
form=form)

@ -15,6 +15,11 @@ def queryNameById(cid):
return selected.name return selected.name
def queryNamesWithDefault(defId):
choices = dbUtils.queryNameWithDefaultId(Companies, defId)
return choices
def queryStreetById(cid): def queryStreetById(cid):
selected = Companies.query.filter_by(id=cid).first() selected = Companies.query.filter_by(id=cid).first()
return selected.street return selected.street

@ -6,6 +6,7 @@ import minibase.blueprints.company.utils as companyUtils
class LocationForm(FlaskForm): class LocationForm(FlaskForm):
country = SelectField('Country', validators=[DataRequired()]) # Addinf custom argumets to the form filed to make it compatible with htmx, without hawing to edit the HTML fomrs.
country = SelectField('Country', validators=[DataRequired()],render_kw={"hx-get": "get_cities", "hx-target": "#city"})
city = SelectField('City', validators=[DataRequired()]) city = SelectField('City', validators=[DataRequired()])
submit = SubmitField('Update') submit = SubmitField('Update')

@ -12,6 +12,8 @@ from flask_wtf import FlaskForm
# Declaring a blueprint # Declaring a blueprint
geography = Blueprint('geography', __name__, template_folder='templates') geography = Blueprint('geography', __name__, template_folder='templates')
country_id = 0
@geography.route('/test', methods=["GET", "POST"]) @geography.route('/test', methods=["GET", "POST"])
def test(): def test():
print("hello") print("hello")
@ -34,19 +36,17 @@ def test():
@geography.route("/get_cities", methods=['GET', 'POST']) @geography.route("/get_cities", methods=['GET', 'POST'])
def get_cities(): def get_cities():
global country_id
country_id = request.args.get("country", type=int) country_id = request.args.get("country", type=int)
print(f"/get_cities -> country_id: {country_id}")
cities = City.query.filter_by(country_id=country_id).all() cities = City.query.filter_by(country_id=country_id).all()
print(len(cities)) print(len(cities))
if len(cities) == 0:
cities = 'Non Awailable'
return render_template("geography/city_options.html", cities=cities) return render_template("geography/city_options.html", cities=cities)
@geography.route("/get_states", methods=['GET', 'POST']) @geography.route("/get_states", methods=['GET', 'POST'])
def get_states(): def get_states():
country_id = request.args.get("country", type=int) global country_id
cities = State.query.filter_by(country_id=country_id).all() print(f"/get_states -> country_id: {country_id}")
print(len(cities)) states = State.query.filter_by(country_id=country_id).all()
if len(cities) == 0: return render_template("geography/state_options.html", states=states)
cities = 'Non Awailable'
return render_template("geography/city_options.html", cities=cities)

@ -3,7 +3,7 @@
<form method="POST" action="" enctype="multipart/form-data">> <form method="POST" action="" enctype="multipart/form-data">>
<fieldset class="form-group"> <fieldset class="form-group">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
{{ form.country(**{"hx-get": "get_cities", "hx-target": "#city"}) }} {{ form.country() }}
{{ form.city }} {{ form.city }}
<button>Submit</button> <button>Submit</button>
</fieldset> </fieldset>

@ -0,0 +1,7 @@
{% for city in cities %}
<option value="{{ city.id }}">{{ city.name }}</option>
{% endfor %}
{% for state in states %}
<option value="{{ state.id }}">{{ state.name }}</option>
{% endfor %}

@ -0,0 +1,3 @@
{% for state in states %}
<option value="{{ state.id }}">{{ state.name }}</option>
{% endfor %}

@ -23,12 +23,18 @@ def queryStateNamesWithDefault(defId):
return choices return choices
def queryStateNamesOfCuntryWithDefId(defId, Filterid): def queryStateNamesWithCountryIdWithDefault(defId, Filterid):
table = State table = State
choices = table.query.order_by(case((table.id == defId, 0), else_=1), table.name.asc()).filter_by(country_id=Filterid) choices = table.query.order_by(case((table.id == defId, 0), else_=1), table.name.asc()).filter_by(country_id=Filterid)
return choices return choices
def queryStateNamesWithCountryId(Filterid):
table = State
choices = table.query.order_by(table.name.asc()).filter_by(country_id=Filterid)
return choices
def queryCityNames(): def queryCityNames():
choices = City.query.order_by(City.name.asc()) choices = City.query.order_by(City.name.asc())
return choices return choices
@ -39,7 +45,13 @@ def queryCityNamesWithDefault(defId):
return choices return choices
def queryCiytNamesOfStateWithDefId(defId, Filterid): def queryCityNamesWithCountryIdWithDefault(defId, Filterid):
table = City
choices = table.query.order_by(case((table.id == defId, 0), else_=1), table.name.asc()).filter_by(country_id=Filterid)
return choices
def queryCityNamesWithCountryId(Filterid):
table = City table = City
choices = table.query.order_by(case((table.id == defId, 0), else_=1), table.name.asc()).filter_by(state_id=Filterid) choices = table.query.order_by(table.name.asc()).filter_by(country_id=Filterid)
return choices return choices

@ -1,15 +1,43 @@
import os
import secrets
from PIL import Image
from flask import url_for, current_app
from flask_mail import Message
from minibase.app import mail
from minibase.blueprints.main.models import Industries from minibase.blueprints.main.models import Industries
import minibase.blueprints.database.utils as dbUtils import minibase.blueprints.database.utils as dbUtils
from sqlalchemy import case
def save_picture(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(current_app.root_path, 'static/pics', picture_fn)
output_size = (125, 125)
i = Image.open(form_picture)
i.thumbnail(output_size)
i.save(picture_path)
return picture_fn
def send_reset_email(user):
token = user.get_reset_token()
msg = Message('Password Reset Request',
sender='noreply@demo.com',
recipients=[user.email_account])
msg.body = f'''To reset your password, visit the following link:
{url_for('user.reset_token', token=token, _external=True)}
If you didn't make this request, then simply ingnore this email and no chancges will be made.
'''
mail.send(msg)
def queryIndustryNames(): def queryIndustryNames():
choices = Industries.query.order_by(Industries.name.asc()) choices = Industries.query.order_by(Industries.name.asc())
return choices return choices
def queryIndustryNamesWithDefault(defId): def queryIndustryNamesWithDefault(defId):
choices = dbUtils.queryNameWithDefaultId(Industries,defId) choices = dbUtils.queryNameWithDefaultId(Industries,defId)
return choices return choices

@ -2,13 +2,13 @@ from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed from flask_wtf.file import FileField, FileAllowed
from wtforms import StringField, PasswordField, SubmitField, BooleanField, URLField, IntegerField, DateField, SelectField from wtforms import StringField, PasswordField, SubmitField, BooleanField, URLField, IntegerField, DateField, SelectField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from iot.blueprints.sensor.models import nbiotDevice from minibase.blueprints.sensor.models import nbiotDevice
from datetime import date from datetime import date
class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be used for the user update class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be used for the user update
name = StringField('Device Name', validators=[DataRequired(), Length(min=3, max=50)]) name = StringField('Device Name', validators=[DataRequired(), Length(min=3, max=50)])
device_id = StringField('Device Id', validators=[DataRequired(), Length(min=3, max=50)]) device_id = StringField('Device Id', validators=[DataRequired(), Length(min=3, max=50)])
serialNumber = StringField('Serial Number', 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)]) imsi = StringField('Imsi No', validators=[DataRequired(), Length(min=10, max=50)])
iccid = StringField('Iccid No', validators=[DataRequired(), Length(min=10, max=100)]) iccid = StringField('Iccid No', validators=[DataRequired(), Length(min=10, max=100)])
ip = StringField('Ip (ipv4)', validators=[DataRequired(), Length(min=7, max=15)]) ip = StringField('Ip (ipv4)', validators=[DataRequired(), Length(min=7, max=15)])
@ -21,7 +21,8 @@ class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be use
status_id = SelectField('Status', validators=[DataRequired()]) status_id = SelectField('Status', validators=[DataRequired()])
type_id = SelectField('Type', validators=[DataRequired()]) type_id = SelectField('Type', validators=[DataRequired()])
area_id = SelectField('Area', validators=[DataRequired()]) area_id = SelectField('Area', validators=[DataRequired()])
manufacturer_id = SelectField('Manufacturer', validators=[DataRequired()])
company_id = SelectField('Managed By', validators=[DataRequired()])
submit = SubmitField(f'Update') submit = SubmitField(f'Update')
@ -62,6 +63,7 @@ class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be use
class updateNbioDeviceAddForm(FlaskForm): # Defines the form class to be used for the user update 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)]) name = StringField('Device Name', validators=[DataRequired(), Length(min=3, max=50)])
device_id = StringField('Device Id', 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)]) imsi = StringField('Imsi No', validators=[DataRequired(), Length(min=10, max=50)])
iccid = StringField('Iccid No', validators=[DataRequired(), Length(min=10, max=100)]) iccid = StringField('Iccid No', validators=[DataRequired(), Length(min=10, max=100)])
ip = StringField('Ip (ipv4)', validators=[Length(min=7, max=15)]) ip = StringField('Ip (ipv4)', validators=[Length(min=7, max=15)])
@ -73,6 +75,8 @@ class updateNbioDeviceAddForm(FlaskForm): # Defines the form class to be used f
status_id = SelectField('Status', validators=[DataRequired()]) status_id = SelectField('Status', validators=[DataRequired()])
type_id = SelectField('Type', validators=[DataRequired()]) type_id = SelectField('Type', validators=[DataRequired()])
area_id = SelectField('Area', 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') submit = SubmitField(f'Add')

@ -1,4 +1,4 @@
from iot.app import db from minibase.app import db
from datetime import datetime from datetime import datetime
class nbiotDevice(db.Model): class nbiotDevice(db.Model):
@ -6,6 +6,7 @@ class nbiotDevice(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False) name = db.Column(db.String(50), nullable=False)
serial_no = db.Column(db.String(50), nullable=False)
device_id = db.Column(db.String(30), nullable=False) device_id = db.Column(db.String(30), nullable=False)
imsi = db.Column(db.String(30), nullable=False) imsi = db.Column(db.String(30), nullable=False)
iccid = db.Column(db.String(50), nullable=False) iccid = db.Column(db.String(50), nullable=False)
@ -14,6 +15,7 @@ class nbiotDevice(db.Model):
registration_date = db.Column(db.DateTime, nullable=True) registration_date = db.Column(db.DateTime, nullable=True)
activation_date = db.Column(db.DateTime, nullable=True) activation_date = db.Column(db.DateTime, nullable=True)
deactivation_date = db.Column(db.DateTime, nullable=True) deactivation_date = db.Column(db.DateTime, nullable=True)
image_file = db.Column(db.String(20), nullable=False, default='def_sensor.png')
created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
updated = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) updated = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
@ -22,9 +24,9 @@ class nbiotDevice(db.Model):
status_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceStatus.id'), nullable=False) status_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceStatus.id'), nullable=False)
type_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceType.id'), nullable=False) type_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceType.id'), nullable=False)
area_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceArea.id'), nullable=False) area_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceArea.id'), nullable=False)
manufacturer_id = db.Column(db.Integer, db.ForeignKey('companies.id'), nullable=False)
company_id = db.Column(db.Integer, db.ForeignKey('companies.id'), nullable=False)
owner = db.relationship('User', foreign_keys=[owner_id], backref='owned_devices')
user = db.relationship('User', foreign_keys=[user_id], backref='used_devices')
class nbiotDeviceStatus(db.Model): class nbiotDeviceStatus(db.Model):
__tablename__ = 'nbiotDeviceStatus' __tablename__ = 'nbiotDeviceStatus'

@ -1,11 +1,12 @@
from flask import render_template, Blueprint, request, flash, redirect, url_for from flask import render_template, Blueprint, request, flash, redirect, url_for
import iot.theme as theme import minibase.theme as theme
from iot.blueprints.sensor.models import nbiotDevice from minibase.blueprints.sensor.models import nbiotDevice
import iot.blueprints.sensor.utils as sensorUtils import minibase.blueprints.sensor.utils as sensorUtils
from iot.blueprints.sensor.forms import updateNbioDeviceUpdateForm, updateNbioDeviceAddForm from minibase.blueprints.sensor.forms import updateNbioDeviceUpdateForm, updateNbioDeviceAddForm
import iot.blueprints.database.utils as dbUtils import minibase.blueprints.database.utils as dbUtils
import iot.blueprints.user.utils as userUtils import minibase.blueprints.company.utils as companyUtils
from iot.app import db import minibase.blueprints.user.utils as userUtils
from minibase.app import db
import json import json
import os import os
@ -13,7 +14,6 @@ sensor = Blueprint('sensor', __name__, template_folder='templates')
DATA_FILE = 'data.json' DATA_FILE = 'data.json'
sensor.route('/callback', methods=['POST']) sensor.route('/callback', methods=['POST'])
def callback(): def callback():
data = request.json data = request.json
@ -61,13 +61,16 @@ def edit(deviceId):
if deviceId: if deviceId:
device = nbiotDevice.query.get_or_404(deviceId) device = nbiotDevice.query.get_or_404(deviceId)
form = updateNbioDeviceUpdateForm(current_device_id=device.id) form = updateNbioDeviceUpdateForm(current_device_id=device.id)
form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserChoices(device.user_id)] form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)]
form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserChoices(device.user_id)] form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)]
form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusChoices(device.status_id)] form.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.manufacturer_id)]
form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeChoices(device.type_id)] form.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_id)]
form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaChoices(device.area_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)]
if form.validate_on_submit(): if form.validate_on_submit():
device.name=form.name.data device.name=form.name.data
device.serial_no = form.serial_no.data
device.device_id=form.device_id.data device.device_id=form.device_id.data
device.imsi=form.imsi.data device.imsi=form.imsi.data
device.iccid=form.iccid.data device.iccid=form.iccid.data
@ -81,11 +84,14 @@ def edit(deviceId):
device.status_id=form.status_id.data device.status_id=form.status_id.data
device.type_id=form.type_id.data device.type_id=form.type_id.data
device.area_id=form.area_id.data device.area_id=form.area_id.data
device.manufacturer_id = form.manufacturer_id.data
device.company_id = form.company_id.data
db.session.commit() db.session.commit()
flash('Device has been successfully updated', 'success') flash('Device has been successfully updated', 'success')
return redirect(url_for('sensor.edit', deviceId=deviceId)) return redirect(url_for('sensor.edit', deviceId=deviceId))
elif request.method == 'GET': elif request.method == 'GET':
form.name.data = device.name form.name.data = device.name
form.serial_no.data = device.serial_no
form.device_id.data = device.device_id form.device_id.data = device.device_id
form.imsi.data = device.imsi form.imsi.data = device.imsi
form.iccid.data = device.iccid form.iccid.data = device.iccid

@ -1,4 +1,5 @@
from iot.blueprints.sensor.models import nbiotDevice, nbiotDeviceStatus, nbiotDeviceType, nbiotDeviceArea from minibase.blueprints.sensor.models import nbiotDevice, nbiotDeviceStatus, nbiotDeviceType, nbiotDeviceArea
import minibase.blueprints.database.utils as dbUtils
from sqlalchemy import case from sqlalchemy import case
@ -7,16 +8,16 @@ def queryById(id):
return nbiotDevice.query.filter_by(id=id).first() return nbiotDevice.query.filter_by(id=id).first()
def queryStatusChoices(curretnId): def queryStatusNamesWithDefault(defId):
choices = nbiotDeviceStatus.query.order_by(case((nbiotDeviceStatus.id == curretnId, 0),else_=1),nbiotDeviceStatus.name.asc()) choices = dbUtils.queryNameWithDefaultId(nbiotDeviceStatus, defId)
return choices return choices
def queryTypeChoices(curretnId): def queryTypeNamesWithDefault(defId):
choices = nbiotDeviceType.query.order_by(case((nbiotDeviceType.id == curretnId, 0),else_=1),nbiotDeviceType.name.asc()) choices = dbUtils.queryNameWithDefaultId(nbiotDeviceType, defId)
return choices return choices
def queryAreaChoices(curretnId): def queryAreaNamesWithDefault(defId):
choices = nbiotDeviceArea.query.order_by(case((nbiotDeviceArea.id == curretnId, 0),else_=1),nbiotDeviceArea.name.asc()) choices = dbUtils.queryNameWithDefaultId(nbiotDeviceArea, defId)
return choices return choices

@ -3,7 +3,6 @@ from itsdangerous import URLSafeTimedSerializer as Serializer
from minibase.app import db, login_manager from minibase.app import db, login_manager
from flask_login import UserMixin from flask_login import UserMixin
from datetime import datetime from datetime import datetime
from minibase.blueprints.main.models import Notes
# The Default User Loading proccess # The Default User Loading proccess
@ -29,6 +28,7 @@ class Users(db.Model, UserMixin):
notes = db.relationship('Notes', backref='author', lazy='dynamic') notes = db.relationship('Notes', backref='author', lazy='dynamic')
todos = db.relationship('Todos', backref='author', lazy='dynamic') todos = db.relationship('Todos', backref='author', lazy='dynamic')
# Here is a one to one relationship: each user can only have one role, and there can be multiple users with the same role # Here is a one to one relationship: each user can only have one role, and there can be multiple users with the same role
# type(user.role) = <class 'minibase.blueprints.user.models.User_Roles'> # type(user.role) = <class 'minibase.blueprints.user.models.User_Roles'>
# type(user.role_id) = <class 'int'> # # type(user.role_id) = <class 'int'> #
@ -36,6 +36,7 @@ class Users(db.Model, UserMixin):
role = db.relationship('User_Roles', backref=db.backref('users', lazy='dynamic')) role = db.relationship('User_Roles', backref=db.backref('users', lazy='dynamic'))
def get_reset_token(self, expires_sec=1800): def get_reset_token(self, expires_sec=1800):
s = Serializer(current_app.config['SECRET_KEY']) s = Serializer(current_app.config['SECRET_KEY'])
return s.dumps({'user_id': self.id}) return s.dumps({'user_id': self.id})

@ -6,7 +6,7 @@ from minibase.blueprints.user.models import Users, User_Roles
import minibase.blueprints.database.utils as dbUtils import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.user.utils as UserUtils import minibase.blueprints.user.utils as UserUtils
from minibase.blueprints.user.forms import registrationForm, loginForm, updateAccountForm, resetPasswordForm, requestResetForm, updateRoleForm from minibase.blueprints.user.forms import registrationForm, loginForm, updateAccountForm, resetPasswordForm, requestResetForm, updateRoleForm
from minibase.blueprints.user.utils import save_picture, send_reset_email import minibase.blueprints.main.utils as mainUtils
# Declaring a blueprint # Declaring a blueprint
user = Blueprint('user', __name__, template_folder='templates') user = Blueprint('user', __name__, template_folder='templates')
@ -60,7 +60,7 @@ def account():
form = updateAccountForm() form = updateAccountForm()
if form.validate_on_submit(): if form.validate_on_submit():
if form.picture.data: if form.picture.data:
picture_file = save_picture(form.picture.data) picture_file = mainUtils.save_picture(form.picture.data)
current_user.image_file = picture_file current_user.image_file = picture_file
current_user.username = form.username.data current_user.username = form.username.data
current_user.email_account = form.email_account.data current_user.email_account = form.email_account.data
@ -87,7 +87,7 @@ def reset_request():
form = requestResetForm() form = requestResetForm()
if form.validate_on_submit(): if form.validate_on_submit():
user = UserUtils.dbGetMailFirst(form.email.data) user = UserUtils.dbGetMailFirst(form.email.data)
send_reset_email(user) mainUtils.send_reset_email(user)
flash('An Email has been sent with instruction to reset your password', 'warning') flash('An Email has been sent with instruction to reset your password', 'warning')
return render_template('user/reset_request.html', return render_template('user/reset_request.html',
theme=theme, theme=theme,

@ -1,37 +1,16 @@
import os
import secrets
from PIL import Image
from flask import url_for, current_app
from flask_mail import Message
from minibase.app import mail
from minibase.blueprints.user.models import Users, User_Roles from minibase.blueprints.user.models import Users, User_Roles
import minibase.blueprints.database.utils as dbUtils
from sqlalchemy import case
def dbGetMailFirst(mail): def dbGetMailFirst(mail):
return Users.query.filter_by(email_account=mail).first() return Users.query.filter_by(email_account=mail).first()
def save_picture(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(current_app.root_path, 'static/pics', picture_fn)
output_size = (125, 125)
i = Image.open(form_picture)
i.thumbnail(output_size)
i.save(picture_path)
return picture_fn
def send_reset_email(user):
token = user.get_reset_token()
msg = Message('Password Reset Request',
sender='noreply@demo.com',
recipients=[user.email_account])
msg.body = f'''To reset your password, visit the following link:
{url_for('user.reset_token', token=token, _external=True)}
If you didn't make this request, then simply ingnore this email and no chancges will be made.
'''
mail.send(msg)
def queryRoleById(id): def queryRoleById(id):
return User_Roles.query.get_or_404(id) return User_Roles.query.get_or_404(id)
def queryUserNamesWithDefault(defId):
choices = Users.query.order_by(case((Users.id == defId, 0),else_=1),Users.username.asc())
return choices;

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

@ -4,8 +4,6 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<!-- Referencing custom CSS stylesheet --!>
<link rel="stylesheet" type="text/css" href="/css/style.css"/>
<!-- Referencing Bootstrap CSS stylesheet --!> <!-- Referencing Bootstrap CSS stylesheet --!>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Referencing Favicon --!> <!-- Referencing Favicon --!>

@ -1,14 +1,14 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}{{ title }}{% endblock %} {% block title %}{{ title }}{% endblock %}
{% block content %} {% block content %}
<div class="container-fluid text-center rounded-3 mt-2 mb-2" style="{{ theme.form.div_style }};"> <div class="container text-center rounded-3 mt-2 mb-2" style="{{ theme.form.div_style }};">
<h1 class="account-heading" style="color: {{ theme.orange }};">{{ title }}</h1> <h1 class="account-heading" style="color: {{ theme.orange }};">{{ title }}</h1>
</div> </div>
<div class="container-fluid rounded-3 " style="{{ theme.form.div_style }};"> <div class="container rounded-3 " style="{{ theme.form.div_style }};">
{% include 'form.html' %} {% include 'form.html' %}
{% if extraButtons %} {% if extraButtons %}
</div> </div>
<div class="container-fluid rounded-3 mt-2 mb-2" style="{{ theme.form.div_style }};"> <div class="container text-left rounded-3 mt-2 mb-2" style="{{ theme.form.div_style }};">
<div class="btn-group"> <div class="btn-group">
<br> <br>
{% for button in extraButtons %} {% for button in extraButtons %}

@ -5,15 +5,14 @@
{% if item.id == 'submit' %} {% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %} {% elif item.id == 'csrf_token' %}
{% else %} {% else %}
{% include 'form/stringField.html' %} {% include 'form/allFields.html' %}
{% include 'form/selectFieldVer.html' %} {% if item.errors %}
{% include 'form/dateField.html' %} {% include 'form/formError.html' %}
{% include 'form/boolField.html' %} {% endif %}
{% include 'form/fileField.html' %}
{% include 'form/urlField.html' %}
{% include 'form/integerField.html' %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</fieldset> </fieldset>
<div>{% include 'form/submitField.html' %}</div> <div>
{% include 'form/submitField.html' %}
</div>
</form> </form>

@ -0,0 +1,7 @@
{% include 'form/stringField.html' %}
{% include 'form/selectField.html' %}
{% include 'form/dateField.html' %}
{% include 'form/boolField.html' %}
{% include 'form/fileField.html' %}
{% include 'form/urlField.html' %}
{% include 'form/integerField.html' %}

@ -1,15 +1,6 @@
{% if item.type == 'BooleanField' %} {% if item.type == 'BooleanField' %}
<br>
{{ item.label(class=theme.form.check_label_class, style=theme.form.check_label_style) }} {{ item.label(class=theme.form.check_label_class, style=theme.form.check_label_style) }}
{% endif %} <br>
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type == 'BooleanField' %}
{{ item(class=theme.form.check_class) }} {{ item(class=theme.form.check_class) }}
{% endif %}
{% endif %} {% endif %}

@ -1,23 +0,0 @@
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% if item.type == 'BooleanField' %}
<br>
{{ item.label(class=theme.form.check_label_class, style=theme.form.check_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type == 'BooleanField' %}
<br>
{{ item(class=theme.form.check_class) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

@ -1,15 +1,6 @@
{% if item.type in ['DateField', 'DateTimeField'] %} {% if item.type in ['DateField', 'DateTimeField'] %}
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }} <br>
{% endif %} {{ item.label(class=theme.form.date_label_class, style=theme.form.date_label_style) }}
{% if item.errors %} <br>
{{ item(class=theme.form.input_error_class) }} {{ item(class=theme.form.date_class, style=theme.form.date_style, type=theme.form.date_type) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['DateField', 'DateTimeField'] %}
{{ item(class=theme.form.input_class, type=theme.form.date_type) }}
{% endif %}
{% endif %} {% endif %}

@ -1,23 +0,0 @@
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% if item.type in ['DateField', 'DateTimeField'] %}
<br>
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['DateField', 'DateTimeField'] %}
<br>
{{ item(class=theme.form.input_class, type=theme.form.date_type) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

@ -1,17 +1,6 @@
{% if item.type in ['FileField'] %} {% if item.type in ['FileField'] %}
<br>
{{ item.label(class=theme.form.file_label_class, style=theme.form.file_label_style) }} {{ item.label(class=theme.form.file_label_class, style=theme.form.file_label_style) }}
<br> <br>
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['FileField'] %}
{{ item(class=theme.form.file_class, type=theme.form.file_type, style=theme.form.file_style) }} {{ item(class=theme.form.file_class, type=theme.form.file_type, style=theme.form.file_style) }}
<br>
{% endif %}
{% endif %} {% endif %}

@ -1,15 +1,6 @@
{% if item.type in ['IntegerField', 'DecimalField', 'FloatField'] %} {% if item.type in ['IntegerField', 'DecimalField', 'FloatField'] %}
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }} <br>
{% endif %} {{ item.label(class=theme.form.integer_label_class, style=theme.form.integer_label_style) }}
{% if item.errors %} <br>
{{ item(class=theme.form.input_error_class) }} {{ item(class=theme.form.integer_class, style=theme.form.integer_style) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['IntegerField', 'DecimalField', 'FloatField'] %}
{{ item(class=theme.form.input_class) }}
{% endif %}
{% endif %} {% endif %}

@ -0,0 +1,6 @@
{% if item.type in ['SelectField'] %}
<br>
{{ item.label(class=theme.form.select_label_class, style=theme.form.select_label_style) }}
<br>
{{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style)}}
{% endif %}

@ -1,17 +0,0 @@
{% if item.type in ['SelectField'] %}
{{ item.label(class=theme.form.select_label_class, style=theme.form.select_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
<div class="col">
{% if item.type in ['SelectField'] %}
{{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style) }}
{% endif %}
</div>
{% endif %}

@ -1,17 +0,0 @@
{% if item.type in ['SelectField'] %}
{{ item.label(class=theme.form.select_label_class, style=theme.form.select_label_style) }}
<br>
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.select_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['SelectField'] %}
{{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style) }}
<br>
{% endif %}
{% endif %}

@ -1,23 +0,0 @@
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% if item.type in ['SelectField'] %}
<br>
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['SelectField'] %}
<br>
{{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

@ -1,17 +1,6 @@
{% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %} {% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %}
<br>
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }} {{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %} <br>
{% if item.errors %} {{ item(class=theme.form.input_class, style=theme.form.input_style) }}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %}
<div class="col">
{{ item(class=theme.form.input_class) }}
</div>
{% endif %}
{% endif %} {% endif %}

@ -1,21 +0,0 @@
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %}
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %}
{{ item(class=theme.form.input_class) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

@ -1,15 +1,6 @@
{% if item.type in ['URLField'] %} {% if item.type in ['URLField'] %}
<br>
{{ item.label(class=theme.form.url_label_class, style=theme.form.url_label_style) }} {{ item.label(class=theme.form.url_label_class, style=theme.form.url_label_style) }}
{% endif %} <br>
{% if item.errors %}
{{ item(class=theme.form.url_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['URLField'] %}
{{ item(class=theme.form.url_class, type=theme.form.url_type, style=theme.form.url_style) }} {{ item(class=theme.form.url_class, type=theme.form.url_type, style=theme.form.url_style) }}
{% endif %}
{% endif %} {% endif %}

@ -1,34 +0,0 @@
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<fieldset class="form-group">
{% if itemList | length == 1 %}
<div class="col-md-3 rounded">
<div class="p-3 py-5">
{% include 'form.html' %}
</div>
</div>
{% else %}
{% for labelItems in itemList %}
<div class="col-md-3">
<div class="p-3 py-4">
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% for label in labelItems %}
{% if label == item.name %}
{% include 'form/stringField.html' %}
{% include 'form/selectFieldVer.html' %}
{% include 'form/dateField.html' %}
{% include 'form/boolField.html' %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
{% endif %}
</fieldset>
<div>{% include 'form/submitField.html' %}</div>
</form>

@ -1,10 +0,0 @@
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<div>{% include 'form/stringFields.html' %}</div>
<div>{% include 'form/selectFields.html' %}</div>
<div>{% include 'form/dateFields.html' %}</div>
<div>{% include 'form/boolFields.html' %}</div>
</fieldset>
<div>{% include 'form/submitField.html' %}</div>
</form>

@ -9,6 +9,9 @@ light_orange = "#f9a36c"
orange = "#f26628" orange = "#f26628"
yellow = "#f8cb66" yellow = "#f8cb66"
label_font_size = "14pt"
field_font_size = "14pt"
class maineTheme: class maineTheme:
div_style = "background-color:" + yellow div_style = "background-color:" + yellow
@ -19,12 +22,14 @@ class form:
div_error_class = "invalid-feedback" div_error_class = "invalid-feedback"
default_label_class = "col-form-label" default_label_class = "col-form-label"
default_label_style = "color:" + orange + "; font-size: 14pt; font-weight: bold;" default_label_style = "color:" + orange + "; font-size: " + label_font_size + "; font-weight: bold;"
default_error_class = "form-control form-control-lg is-invalid" default_field_style = "color:" + black + "; font-size: " + field_font_size + "; background-color: " + white + ";"
default_error_class = "form-control is-invalid"
input_label_class = default_label_class input_label_class = default_label_class
input_label_style = default_label_style input_label_style = default_label_style
input_class = "form-control form-control-lg" input_class = "form-control"
input_style = default_field_style
input_error_class = default_error_class input_error_class = default_error_class
check_label_class = "form-check-label" check_label_class = "form-check-label"
@ -34,29 +39,35 @@ class form:
file_label_class = default_label_class file_label_class = default_label_class
file_label_style = default_label_style file_label_style = default_label_style
file_class = input_class file_class = input_class
file_style = default_field_style
file_type = "file" file_type = "file"
file_error_class = default_error_class
url_label_class = default_label_class url_label_class = default_label_class
url_label_style = default_label_style url_label_style = default_label_style
url_class = input_class url_class = input_class
url_style = default_field_style
url_default = "https://example.com/" url_default = "https://example.com/"
url_error_class = default_error_class
select_label_class = default_label_class select_label_class = default_label_class
select_label_style = default_label_style select_label_style = default_label_style
select_class = "btn btn-lg form-select" select_class = "btn btn-lg form-select"
select_style = "color:" + black + "; font-size: 14pt; background-color: " + white + ";" select_style = "color:" + black + "; font-size: 14pt; background-color: " + white + ";"
submit_class = "btn btn-outline-info mb-2 mt-2" integer_label_class = default_label_class
submit_style = "" integer_label_style = default_label_style
integer_class = input_class
integer_style = default_field_style
date_label_class = default_label_class date_label_class = default_label_class
date_label_style = default_label_style date_label_style = default_label_style
date_class = "" date_class = input_class
date_error_class = default_error_class date_style = default_field_style
date_type = "date" date_type = "date"
submit_class = "btn btn-outline-info mb-2 mt-2"
submit_style = ""
class menu: class menu:
menuDict = generate_blueprint_structure('minibase/blueprints') menuDict = generate_blueprint_structure('minibase/blueprints')
@ -64,13 +75,19 @@ class menu:
{"menuName":"Company", {"menuName":"Company",
"sublinks": [ "sublinks": [
{"text": "List", "url": "company.list"}, {"text": "List", "url": "company.list"},
{"text": "Presons", "url": "main.index"},
{"decoration": "line"}, {"decoration": "line"},
{"text": "Create Company", "url": "main.index"}, {"text": "Add", "url": "company.add"},
{"text": "Create Person", "url": "main.index"}, {"decoration": "line"},
{"text": "Remove", "url": "main.index"},
],},
{"menuName":"Sensor",
"sublinks": [
{"text": "List", "url": "main.index"},
{"decoration": "line"},
{"text": "Add", "url": "main.index"},
{"decoration": "line"}, {"decoration": "line"},
{"text": "Edit Company", "url": "main.index"}, {"text": "Edit", "url": "main.index"},
{"text": "Edit Person", "url": "main.index"},
],}, ],},
] ]

@ -2,8 +2,9 @@ from minibase.app import db, create_app, bcrypt
from minibase.blueprints.user.models import Users, User_Roles from minibase.blueprints.user.models import Users, User_Roles
from minibase.blueprints.company.models import Companies, Company_types, Company_legal_entities, Industries, Company_relations, Company_status from minibase.blueprints.company.models import Companies, Company_types, Company_legal_entities, Industries, Company_relations, Company_status
from minibase.blueprints.main.models import Notes from minibase.blueprints.main.models import Notes
from minibase.blueprints.sensor.models import nbiotDevice, nbiotDeviceArea, nbiotDeviceType, nbiotDeviceStatus
import csv import csv
import subprocess import os
app = create_app() app = create_app()
app.app_context().push() app.app_context().push()
@ -46,6 +47,10 @@ def initDatabase():
uploadCsvOnlyName(Industries) uploadCsvOnlyName(Industries)
uploadCsvOnlyName(User_Roles) uploadCsvOnlyName(User_Roles)
uploadCsvOnlyName(Notes) uploadCsvOnlyName(Notes)
uploadCsvOnlyName(nbiotDeviceStatus)
uploadCsvOnlyName(nbiotDeviceType)
uploadCsvOnlyName(nbiotDeviceArea)
uploadCsvOnlyName(nbiotDevice)
hashed_pw = bcrypt.generate_password_hash('pass').decode('utf-8') hashed_pw = bcrypt.generate_password_hash('pass').decode('utf-8')
user = Users(username="Admin", email_account="admin@kynsight.com", email_comm="admin@kynsight.com", password=hashed_pw, role_id=1) user = Users(username="Admin", email_account="admin@kynsight.com", email_comm="admin@kynsight.com", password=hashed_pw, role_id=1)
@ -68,3 +73,4 @@ if __name__ == '__main__':
users=Users.query.all() users=Users.query.all()
roles=User_Roles.query.all() roles=User_Roles.query.all()
notes=Notes.query.all() notes=Notes.query.all()
os.system("sqlite3 instance/test.db < init/static/countries/dump1.sql")

Loading…
Cancel
Save