merge
This commit is contained in:
commit
ccc28435db
|
@ -7,7 +7,6 @@ repos:
|
||||||
rev: 5.9.3
|
rev: 5.9.3
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
# args: ["--profile", "black", "--filter-files"]
|
|
||||||
- repo: https://github.com/PyCQA/flake8
|
- repo: https://github.com/PyCQA/flake8
|
||||||
rev: 4.0.1
|
rev: 4.0.1
|
||||||
hooks:
|
hooks:
|
||||||
|
|
63
CHANGELOG.md
63
CHANGELOG.md
|
@ -5,34 +5,39 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.ht
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.ht
|
||||||
ml).
|
ml).
|
||||||
|
|
||||||
|
## master
|
||||||
|
|
||||||
## [2.0.0-alpha]
|
## testing
|
||||||
- [changes] #209 adding a new device in a lot if it is created from a lot
|
|
||||||
- [addend] #208 render from backend filter for type of devices in the general list
|
## [2.0.0] - 2022-03-15
|
||||||
- [bugfix] #206 fix 2 bugs about visibility devices when you are not the owner
|
First server render HTML version. Completely rewrites views of angular JS client on flask.
|
||||||
- [addend] #205 ux improvements
|
- [added] #193 render on backend devices and lots
|
||||||
- [addend] #204 render from backend export files
|
- [added] #195 render on backend tags system
|
||||||
- [addend] #203 render from backend Trade action
|
- [added] #196 render on backend action system
|
||||||
- [addend] #201 render from backend Data Wipe action
|
- [added] #201 render on backend Data Wipe action
|
||||||
- [addend] #196 render from backend action system
|
- [added] #203 render on backend Trade action
|
||||||
- [addend] #195 render from backend tags system
|
- [added] #204 render on backend export files
|
||||||
- [addend] #193 render from backend devices and lots
|
- [added] #205 UX improvements
|
||||||
- [changes] #191 pass to drop teal and use the pure flask and use render from flask
|
- [added] #208 render on backend filter for type of devices in the general list
|
||||||
|
- [changed] #191 pass to drop teal and use the pure flask and use render from flask
|
||||||
|
- [changed] #207 Create automatic tag only for Computers.
|
||||||
|
- [changed] #209 adding a new device in a lot if it is created from a lot
|
||||||
|
- [fixed] #206 fix 2 bugs about visibility devices when you are not the owner
|
||||||
|
|
||||||
## [1.0.12-beta]
|
## [1.0.12-beta]
|
||||||
- [changes] #187 now is possible duplicate slots of RAM.
|
- [changed] #187 now is possible duplicate slots of RAM.
|
||||||
- [changes] #188 Excel report devices allow to see device to old owners.
|
- [changed] #188 Excel report devices allow to see device to old owners.
|
||||||
|
|
||||||
## [1.0.11-beta]
|
## [1.0.11-beta]
|
||||||
- [addend] #186 adding property power_on_hours.
|
- [added] #186 adding property power_on_hours.
|
||||||
|
|
||||||
## [1.0.10-beta]
|
## [1.0.10-beta]
|
||||||
- [addend] #170 can delete/deactivate devices.
|
- [added] #170 can delete/deactivate devices.
|
||||||
- [bugfix] #168 can to do a trade without devices.
|
|
||||||
- [added] #167 new actions of status devices: use, recycling, refurbish and management.
|
- [added] #167 new actions of status devices: use, recycling, refurbish and management.
|
||||||
- [changes] #177 new structure of trade.
|
|
||||||
- [bugfix] #184 clean nested of schemas of lot
|
|
||||||
- [added] #182 adding power on hours
|
- [added] #182 adding power on hours
|
||||||
|
- [changed] #177 new structure of trade.
|
||||||
|
- [fixed] #168 can to do a trade without devices.
|
||||||
|
- [fixed] #184 clean nested of schemas of lot
|
||||||
|
|
||||||
## [1.0.9-beta]
|
## [1.0.9-beta]
|
||||||
- [added] #159 external document as proof of erase of disk
|
- [added] #159 external document as proof of erase of disk
|
||||||
|
@ -40,7 +45,7 @@ ml).
|
||||||
|
|
||||||
|
|
||||||
## [1.0.8-beta]
|
## [1.0.8-beta]
|
||||||
- [bugfix] #161 fixing DataStorage with bigInteger
|
- [fixed] #161 fixing DataStorage with bigInteger
|
||||||
|
|
||||||
## [1.0.7-beta]
|
## [1.0.7-beta]
|
||||||
- [added] #158 support for encrypted snapshots data
|
- [added] #158 support for encrypted snapshots data
|
||||||
|
@ -48,26 +53,26 @@ ml).
|
||||||
- [added] #140 adding endpoint for download the settings for usb workbench
|
- [added] #140 adding endpoint for download the settings for usb workbench
|
||||||
|
|
||||||
## [1.0.6-beta]
|
## [1.0.6-beta]
|
||||||
- [bugfix] #143 biginteger instead of integer in TestDataStorage
|
- [fixed] #143 biginteger instead of integer in TestDataStorage
|
||||||
|
|
||||||
## [1.0.5-beta]
|
## [1.0.5-beta]
|
||||||
- [added] #124 adding endpoint for extract the internal stats of use
|
- [added] #124 adding endpoint for extract the internal stats of use
|
||||||
- [added] #122 system for verify all documents that it's produced from devicehub
|
- [added] #122 system for verify all documents that it's produced from devicehub
|
||||||
- [added] #127 add one code for every named tag
|
- [added] #127 add one code for every named tag
|
||||||
- [added] #131 add one code for every device
|
- [added] #131 add one code for every device
|
||||||
- [bugfix] #138 search device with devicehubId
|
- [fixed] #138 search device with devicehubId
|
||||||
|
|
||||||
## [1.0.4-beta]
|
## [1.0.4-beta]
|
||||||
- [added] #95 adding endpoint for check the hash of one report
|
- [added] #95 adding endpoint for check the hash of one report
|
||||||
- [added] #98 adding endpoint for insert a new live
|
- [added] #98 adding endpoint for insert a new live
|
||||||
- [added] #98 adding endpoint for get all licences in one query
|
- [added] #98 adding endpoint for get all licences in one query
|
||||||
- [added] #102 adding endpoint for download metrics
|
- [added] #102 adding endpoint for download metrics
|
||||||
- [bugfix] #100 fixing bug of scheme live
|
- [changed] #114 clean blockchain of all models
|
||||||
- [bugfix] #101 fixing bug when 2 users have one device and launch one live
|
- [changed] #118 deactivate manual merge
|
||||||
- [changes] #114 clean blockchain of all models
|
- [changed] #118 clean datas of public information of devices
|
||||||
- [changes] #118 deactivate manual merge
|
- [fixed] #100 fixing bug of scheme live
|
||||||
- [changes] #118 clean datas of public information of devices
|
- [fixed] #101 fixing bug when 2 users have one device and launch one live
|
||||||
- [remove] #114 remove proof system
|
- [removed] #114 remove proof system
|
||||||
|
|
||||||
## [1.0.3-beta]
|
## [1.0.3-beta]
|
||||||
- [added] #85 add mac of network adapter to device hid
|
- [added] #85 add mac of network adapter to device hid
|
||||||
|
@ -75,6 +80,6 @@ ml).
|
||||||
|
|
||||||
## [1.0.2-beta]
|
## [1.0.2-beta]
|
||||||
- [added] #87 allocate, deallocate and live actions
|
- [added] #87 allocate, deallocate and live actions
|
||||||
- [fixed] #89 save json on disk only for shapshots
|
|
||||||
- [added] #83 add owner_id in all kind of device
|
- [added] #83 add owner_id in all kind of device
|
||||||
|
- [fixed] #89 save json on disk only for shapshots
|
||||||
- [fixed] #91 The most old time allow is 1970-01-01
|
- [fixed] #91 The most old time allow is 1970-01-01
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
; SHARED on https://pad.cas.cat/usody-devicehub-contributing
|
|
||||||
|
|
||||||
# Contributing to devicehub
|
# Contributing to devicehub
|
||||||
|
|
||||||
## Writing code
|
## Writing code
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
__version__ = "1.0.12-beta"
|
__version__ = "2.1.0.dev"
|
||||||
|
|
|
@ -51,6 +51,51 @@ from ereuse_devicehub.resources.tradedocument.models import TradeDocument
|
||||||
from ereuse_devicehub.resources.user.exceptions import InsufficientPermission
|
from ereuse_devicehub.resources.user.exceptions import InsufficientPermission
|
||||||
from ereuse_devicehub.resources.user.models import User
|
from ereuse_devicehub.resources.user.models import User
|
||||||
|
|
||||||
|
DEVICES = {
|
||||||
|
"All": ["All"],
|
||||||
|
"Computer": [
|
||||||
|
"Desktop",
|
||||||
|
"Laptop",
|
||||||
|
"Server",
|
||||||
|
],
|
||||||
|
"Monitor": ["ComputerMonitor", "Monitor", "TelevisionSet", "Projector"],
|
||||||
|
"Mobile, tablet & smartphone": ["Mobile", "Tablet", "Smartphone", "Cellphone"],
|
||||||
|
"DataStorage": ["HardDrive", "SolidStateDrive"],
|
||||||
|
"Accessories & Peripherals": [
|
||||||
|
"GraphicCard",
|
||||||
|
"Motherboard",
|
||||||
|
"NetworkAdapter",
|
||||||
|
"Processor",
|
||||||
|
"RamModule",
|
||||||
|
"SoundCard",
|
||||||
|
"Battery",
|
||||||
|
"Keyboard",
|
||||||
|
"Mouse",
|
||||||
|
"MemoryCardReader",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FilterForm(FlaskForm):
|
||||||
|
filter = SelectField(
|
||||||
|
'', choices=DEVICES, default="Computer", render_kw={'class': "form-select"}
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
types_of_devices = [item for sublist in DEVICES.values() for item in sublist]
|
||||||
|
dev = request.args.get('filter')
|
||||||
|
self.device = dev if dev in types_of_devices else None
|
||||||
|
if self.device:
|
||||||
|
self.filter.data = self.device
|
||||||
|
|
||||||
|
def search(self):
|
||||||
|
|
||||||
|
if self.device:
|
||||||
|
return [self.device]
|
||||||
|
|
||||||
|
return ['Desktop', 'Laptop', 'Server']
|
||||||
|
|
||||||
|
|
||||||
class LotDeviceForm(FlaskForm):
|
class LotDeviceForm(FlaskForm):
|
||||||
lot = StringField('Lot', [validators.UUID()])
|
lot = StringField('Lot', [validators.UUID()])
|
||||||
|
|
|
@ -11,11 +11,12 @@ from requests.exceptions import ConnectionError
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import or_
|
||||||
from werkzeug.exceptions import NotFound
|
from werkzeug.exceptions import NotFound
|
||||||
|
|
||||||
from ereuse_devicehub import messages
|
from ereuse_devicehub import __version__, messages
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.inventory.forms import (
|
from ereuse_devicehub.inventory.forms import (
|
||||||
AllocateForm,
|
AllocateForm,
|
||||||
DataWipeForm,
|
DataWipeForm,
|
||||||
|
FilterForm,
|
||||||
LotDeviceForm,
|
LotDeviceForm,
|
||||||
LotForm,
|
LotForm,
|
||||||
NewActionForm,
|
NewActionForm,
|
||||||
|
@ -34,8 +35,7 @@ from ereuse_devicehub.resources.hash_reports import insert_hash
|
||||||
from ereuse_devicehub.resources.lot.models import Lot
|
from ereuse_devicehub.resources.lot.models import Lot
|
||||||
from ereuse_devicehub.resources.tag.model import Tag
|
from ereuse_devicehub.resources.tag.model import Tag
|
||||||
|
|
||||||
# TODO(@slamora): rename base 'inventory.devices' --> 'inventory'
|
devices = Blueprint('inventory', __name__, url_prefix='/inventory')
|
||||||
devices = Blueprint('inventory.devices', __name__, url_prefix='/inventory')
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -60,9 +60,8 @@ class DeviceListMix(GenericMixView):
|
||||||
template_name = 'inventory/device_list.html'
|
template_name = 'inventory/device_list.html'
|
||||||
|
|
||||||
def get_context(self, lot_id):
|
def get_context(self, lot_id):
|
||||||
# TODO @cayop adding filter
|
form_filter = FilterForm()
|
||||||
# https://github.com/eReuse/devicehub-teal/blob/testing/ereuse_devicehub/resources/device/views.py#L56
|
filter_types = form_filter.search()
|
||||||
filter_types = ['Desktop', 'Laptop', 'Server']
|
|
||||||
lots = self.get_lots()
|
lots = self.get_lots()
|
||||||
lot = None
|
lot = None
|
||||||
tags = (
|
tags = (
|
||||||
|
@ -72,9 +71,10 @@ class DeviceListMix(GenericMixView):
|
||||||
)
|
)
|
||||||
|
|
||||||
if lot_id:
|
if lot_id:
|
||||||
# import pdb; pdb.set_trace()
|
|
||||||
lot = lots.filter(Lot.id == lot_id).one()
|
lot = lots.filter(Lot.id == lot_id).one()
|
||||||
devices = [dev for dev in lot.devices if dev.type in filter_types]
|
devices = lot.devices
|
||||||
|
if "All" not in filter_types:
|
||||||
|
devices = [dev for dev in lot.devices if dev.type in filter_types]
|
||||||
devices = sorted(devices, key=lambda x: x.updated, reverse=True)
|
devices = sorted(devices, key=lambda x: x.updated, reverse=True)
|
||||||
form_new_action = NewActionForm(lot=lot.id)
|
form_new_action = NewActionForm(lot=lot.id)
|
||||||
form_new_allocate = AllocateForm(lot=lot.id)
|
form_new_allocate = AllocateForm(lot=lot.id)
|
||||||
|
@ -85,12 +85,20 @@ class DeviceListMix(GenericMixView):
|
||||||
user_from=g.user.email,
|
user_from=g.user.email,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
devices = (
|
if "All" in filter_types:
|
||||||
Device.query.filter(Device.owner_id == current_user.id)
|
devices = (
|
||||||
.filter(Device.type.in_(filter_types))
|
Device.query.filter(Device.owner_id == current_user.id)
|
||||||
.filter_by(lots=None)
|
.filter_by(lots=None)
|
||||||
.order_by(Device.updated.desc())
|
.order_by(Device.updated.desc())
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
devices = (
|
||||||
|
Device.query.filter(Device.owner_id == current_user.id)
|
||||||
|
.filter_by(lots=None)
|
||||||
|
.filter(Device.type.in_(filter_types))
|
||||||
|
.order_by(Device.updated.desc())
|
||||||
|
)
|
||||||
|
|
||||||
form_new_action = NewActionForm()
|
form_new_action = NewActionForm()
|
||||||
form_new_allocate = AllocateForm()
|
form_new_allocate = AllocateForm()
|
||||||
form_new_datawipe = DataWipeForm()
|
form_new_datawipe = DataWipeForm()
|
||||||
|
@ -109,9 +117,11 @@ class DeviceListMix(GenericMixView):
|
||||||
'form_new_allocate': form_new_allocate,
|
'form_new_allocate': form_new_allocate,
|
||||||
'form_new_datawipe': form_new_datawipe,
|
'form_new_datawipe': form_new_datawipe,
|
||||||
'form_new_trade': form_new_trade,
|
'form_new_trade': form_new_trade,
|
||||||
|
'form_filter': form_filter,
|
||||||
'lot': lot,
|
'lot': lot,
|
||||||
'tags': tags,
|
'tags': tags,
|
||||||
'list_devices': list_devices,
|
'list_devices': list_devices,
|
||||||
|
'version': __version__,
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.context
|
return self.context
|
||||||
|
@ -139,6 +149,7 @@ class DeviceDetailView(GenericMixView):
|
||||||
'device': device,
|
'device': device,
|
||||||
'lots': lots,
|
'lots': lots,
|
||||||
'page_title': 'Device {}'.format(device.devicehub_id),
|
'page_title': 'Device {}'.format(device.devicehub_id),
|
||||||
|
'version': __version__,
|
||||||
}
|
}
|
||||||
return flask.render_template(self.template_name, **context)
|
return flask.render_template(self.template_name, **context)
|
||||||
|
|
||||||
|
@ -159,7 +170,7 @@ class LotDeviceAddView(View):
|
||||||
else:
|
else:
|
||||||
messages.error('Error adding devices to lot!')
|
messages.error('Error adding devices to lot!')
|
||||||
|
|
||||||
next_url = request.referrer or url_for('inventory.devices.devicelist')
|
next_url = request.referrer or url_for('inventory.devicelist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,7 +190,7 @@ class LotDeviceDeleteView(View):
|
||||||
else:
|
else:
|
||||||
messages.error('Error removing devices from lot!')
|
messages.error('Error removing devices from lot!')
|
||||||
|
|
||||||
next_url = request.referrer or url_for('inventory.devices.devicelist')
|
next_url = request.referrer or url_for('inventory.devicelist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,11 +204,16 @@ class LotCreateView(GenericMixView):
|
||||||
form = LotForm()
|
form = LotForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
form.save()
|
form.save()
|
||||||
next_url = url_for('inventory.devices.lotdevicelist', lot_id=form.id)
|
next_url = url_for('inventory.lotdevicelist', lot_id=form.id)
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
lots = self.get_lots()
|
lots = self.get_lots()
|
||||||
context = {'form': form, 'title': self.title, 'lots': lots}
|
context = {
|
||||||
|
'form': form,
|
||||||
|
'title': self.title,
|
||||||
|
'lots': lots,
|
||||||
|
'version': __version__,
|
||||||
|
}
|
||||||
return flask.render_template(self.template_name, **context)
|
return flask.render_template(self.template_name, **context)
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,11 +227,16 @@ class LotUpdateView(View):
|
||||||
form = LotForm(id=id)
|
form = LotForm(id=id)
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
form.save()
|
form.save()
|
||||||
next_url = url_for('inventory.devices.lotdevicelist', lot_id=id)
|
next_url = url_for('inventory.lotdevicelist', lot_id=id)
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
||||||
context = {'form': form, 'title': self.title, 'lots': lots}
|
context = {
|
||||||
|
'form': form,
|
||||||
|
'title': self.title,
|
||||||
|
'lots': lots,
|
||||||
|
'version': __version__,
|
||||||
|
}
|
||||||
return flask.render_template(self.template_name, **context)
|
return flask.render_template(self.template_name, **context)
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,11 +250,11 @@ class LotDeleteView(View):
|
||||||
if form.instance.trade:
|
if form.instance.trade:
|
||||||
msg = "Sorry, the lot cannot be deleted because have a trade action "
|
msg = "Sorry, the lot cannot be deleted because have a trade action "
|
||||||
messages.error(msg)
|
messages.error(msg)
|
||||||
next_url = url_for('inventory.devices.lotdevicelist', lot_id=id)
|
next_url = url_for('inventory.lotdevicelist', lot_id=id)
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
form.remove()
|
form.remove()
|
||||||
next_url = url_for('inventory.devices.devicelist')
|
next_url = url_for('inventory.devicelist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,6 +271,7 @@ class UploadSnapshotView(GenericMixView):
|
||||||
'lots': lots,
|
'lots': lots,
|
||||||
'form': form,
|
'form': form,
|
||||||
'lot_id': lot_id,
|
'lot_id': lot_id,
|
||||||
|
'version': __version__,
|
||||||
}
|
}
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
snapshot = form.save(commit=False)
|
snapshot = form.save(commit=False)
|
||||||
|
@ -275,12 +297,13 @@ class DeviceCreateView(GenericMixView):
|
||||||
'lots': lots,
|
'lots': lots,
|
||||||
'form': form,
|
'form': form,
|
||||||
'lot_id': lot_id,
|
'lot_id': lot_id,
|
||||||
|
'version': __version__,
|
||||||
}
|
}
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
snapshot = form.save(commit=False)
|
snapshot = form.save(commit=False)
|
||||||
next_url = url_for('inventory.devices.devicelist')
|
next_url = url_for('inventory.devicelist')
|
||||||
if lot_id:
|
if lot_id:
|
||||||
next_url = url_for('inventory.devices.lotdevicelist', lot_id=lot_id)
|
next_url = url_for('inventory.lotdevicelist', lot_id=lot_id)
|
||||||
lot = lots.filter(Lot.id == lot_id).one()
|
lot = lots.filter(Lot.id == lot_id).one()
|
||||||
lot.devices.add(snapshot.device)
|
lot.devices.add(snapshot.device)
|
||||||
db.session.add(lot)
|
db.session.add(lot)
|
||||||
|
@ -304,6 +327,7 @@ class TagListView(View):
|
||||||
'lots': lots,
|
'lots': lots,
|
||||||
'tags': tags,
|
'tags': tags,
|
||||||
'page_title': 'Tags Management',
|
'page_title': 'Tags Management',
|
||||||
|
'version': __version__,
|
||||||
}
|
}
|
||||||
return flask.render_template(self.template_name, **context)
|
return flask.render_template(self.template_name, **context)
|
||||||
|
|
||||||
|
@ -315,11 +339,11 @@ class TagAddView(View):
|
||||||
|
|
||||||
def dispatch_request(self):
|
def dispatch_request(self):
|
||||||
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
||||||
context = {'page_title': 'New Tag', 'lots': lots}
|
context = {'page_title': 'New Tag', 'lots': lots, 'version': __version__}
|
||||||
form = TagForm()
|
form = TagForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
form.save()
|
form.save()
|
||||||
next_url = url_for('inventory.devices.taglist')
|
next_url = url_for('inventory.taglist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
return flask.render_template(self.template_name, form=form, **context)
|
return flask.render_template(self.template_name, form=form, **context)
|
||||||
|
@ -332,7 +356,11 @@ class TagAddUnnamedView(View):
|
||||||
|
|
||||||
def dispatch_request(self):
|
def dispatch_request(self):
|
||||||
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
||||||
context = {'page_title': 'New Unnamed Tag', 'lots': lots}
|
context = {
|
||||||
|
'page_title': 'New Unnamed Tag',
|
||||||
|
'lots': lots,
|
||||||
|
'version': __version__,
|
||||||
|
}
|
||||||
form = TagUnnamedForm()
|
form = TagUnnamedForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
try:
|
try:
|
||||||
|
@ -347,7 +375,7 @@ class TagAddUnnamedView(View):
|
||||||
)
|
)
|
||||||
messages.error(msg)
|
messages.error(msg)
|
||||||
|
|
||||||
next_url = url_for('inventory.devices.taglist')
|
next_url = url_for('inventory.taglist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
return flask.render_template(self.template_name, form=form, **context)
|
return flask.render_template(self.template_name, form=form, **context)
|
||||||
|
@ -367,6 +395,7 @@ class TagDetailView(View):
|
||||||
'lots': lots,
|
'lots': lots,
|
||||||
'tag': tag,
|
'tag': tag,
|
||||||
'page_title': '{} Tag'.format(tag.code),
|
'page_title': '{} Tag'.format(tag.code),
|
||||||
|
'version': __version__,
|
||||||
}
|
}
|
||||||
return flask.render_template(self.template_name, **context)
|
return flask.render_template(self.template_name, **context)
|
||||||
|
|
||||||
|
@ -395,11 +424,15 @@ class TagUnlinkDeviceView(View):
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
form.remove()
|
form.remove()
|
||||||
|
|
||||||
next_url = url_for('inventory.devices.devicelist')
|
next_url = url_for('inventory.devicelist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
return flask.render_template(
|
return flask.render_template(
|
||||||
self.template_name, form=form, lots=lots, referrer=request.referrer
|
self.template_name,
|
||||||
|
form=form,
|
||||||
|
lots=lots,
|
||||||
|
referrer=request.referrer,
|
||||||
|
version=__version__,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -424,9 +457,9 @@ class NewActionView(View):
|
||||||
lot_id = self.form.lot.data
|
lot_id = self.form.lot.data
|
||||||
|
|
||||||
if lot_id:
|
if lot_id:
|
||||||
return url_for('inventory.devices.lotdevicelist', lot_id=lot_id)
|
return url_for('inventory.lotdevicelist', lot_id=lot_id)
|
||||||
|
|
||||||
return url_for('inventory.devices.devicelist')
|
return url_for('inventory.devicelist')
|
||||||
|
|
||||||
|
|
||||||
class NewAllocateView(NewActionView, DeviceListMix):
|
class NewAllocateView(NewActionView, DeviceListMix):
|
||||||
|
@ -508,11 +541,11 @@ class NewTradeDocumentView(View):
|
||||||
if self.form.validate_on_submit():
|
if self.form.validate_on_submit():
|
||||||
self.form.save()
|
self.form.save()
|
||||||
messages.success('Document created successfully!')
|
messages.success('Document created successfully!')
|
||||||
next_url = url_for('inventory.devices.lotdevicelist', lot_id=lot_id)
|
next_url = url_for('inventory.lotdevicelist', lot_id=lot_id)
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
return flask.render_template(
|
return flask.render_template(
|
||||||
self.template_name, form=self.form, title=self.title
|
self.template_name, form=self.form, title=self.title, version=__version__
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1736,7 +1736,7 @@ class MoveOnDocument(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
||||||
"""Action than certify one movement of some indescriptible material of
|
"""Action than certify one movement of some indescriptible material of
|
||||||
one container to an other."""
|
one container to an other."""
|
||||||
|
|
||||||
weight = db.Column(db.Float(nullable=True))
|
weight = db.Column(db.Float())
|
||||||
weight.comment = """Weight than go to recycling"""
|
weight.comment = """Weight than go to recycling"""
|
||||||
container_from_id = db.Column(
|
container_from_id = db.Column(
|
||||||
db.BigInteger,
|
db.BigInteger,
|
||||||
|
|
|
@ -1217,8 +1217,9 @@ def create_code_tag(mapper, connection, device):
|
||||||
this tag is the same of devicehub_id.
|
this tag is the same of devicehub_id.
|
||||||
"""
|
"""
|
||||||
from ereuse_devicehub.resources.tag.model import Tag
|
from ereuse_devicehub.resources.tag.model import Tag
|
||||||
tag = Tag(device_id=device.id, id=device.devicehub_id)
|
if isinstance(device, Computer):
|
||||||
db.session.add(tag)
|
tag = Tag(device_id=device.id, id=device.devicehub_id)
|
||||||
|
db.session.add(tag)
|
||||||
|
|
||||||
|
|
||||||
event.listen(Device, 'after_insert', create_code_tag, propagate=True)
|
event.listen(Device, 'after_insert', create_code_tag, propagate=True)
|
||||||
|
|
|
@ -72,7 +72,7 @@ class TradeDocument(Thing):
|
||||||
file_hash.comment = """This is the hash of the file produced from frontend."""
|
file_hash.comment = """This is the hash of the file produced from frontend."""
|
||||||
url = db.Column(URL())
|
url = db.Column(URL())
|
||||||
url.comment = """This is the url where resides the document."""
|
url.comment = """This is the url where resides the document."""
|
||||||
weight = db.Column(db.Float(nullable=True))
|
weight = db.Column(db.Float())
|
||||||
weight.comment = """This is the weight of one container than this document express."""
|
weight.comment = """This is the weight of one container than this document express."""
|
||||||
|
|
||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<header id="header" class="header fixed-top d-flex align-items-center">
|
<header id="header" class="header fixed-top d-flex align-items-center">
|
||||||
|
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
<a href="{{ url_for('inventory.devices.devicelist')}}" class="logo d-flex align-items-center">
|
<a href="{{ url_for('inventory.devicelist')}}" class="logo d-flex align-items-center">
|
||||||
<img src="{{ url_for('static', filename='img/usody-logo-black.svg') }}" alt="">
|
<img src="{{ url_for('static', filename='img/usody-logo-black.svg') }}" alt="">
|
||||||
</a>
|
</a>
|
||||||
<i class="bi bi-list toggle-sidebar-btn"></i>
|
<i class="bi bi-list toggle-sidebar-btn"></i>
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
</li><!-- End Dashboard Nav -->
|
</li><!-- End Dashboard Nav -->
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link collapsed" href="{{ url_for('inventory.devices.devicelist') }}">
|
<a class="nav-link collapsed" href="{{ url_for('inventory.devicelist') }}">
|
||||||
<i class="bi-menu-button-wide"></i>
|
<i class="bi-menu-button-wide"></i>
|
||||||
<span>Unassigned devices</span>
|
<span>Unassigned devices</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
{% for lot in lots %}
|
{% for lot in lots %}
|
||||||
{% if lot.is_incoming %}
|
{% if lot.is_incoming %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('inventory.devices.lotdevicelist', lot_id=lot.id) }}">
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}">
|
||||||
<i class="bi bi-circle"></i><span>{{ lot.name }}</span>
|
<i class="bi bi-circle"></i><span>{{ lot.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -139,7 +139,7 @@
|
||||||
{% for lot in lots %}
|
{% for lot in lots %}
|
||||||
{% if lot.is_outgoing %}
|
{% if lot.is_outgoing %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('inventory.devices.lotdevicelist', lot_id=lot.id) }}">
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}">
|
||||||
<i class="bi bi-circle"></i><span>{{ lot.name }}</span>
|
<i class="bi bi-circle"></i><span>{{ lot.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -162,14 +162,14 @@
|
||||||
<ul id="temporal-lots-nav" class="nav-content collapse " data-bs-parent="#sidebar-nav">
|
<ul id="temporal-lots-nav" class="nav-content collapse " data-bs-parent="#sidebar-nav">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('inventory.devices.lot_add')}}">
|
<a href="{{ url_for('inventory.lot_add')}}">
|
||||||
<i class="bi bi-plus" style="font-size: larger;"></i><span>New temporary lot</span>
|
<i class="bi bi-plus" style="font-size: larger;"></i><span>New temporary lot</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% for lot in lots %}
|
{% for lot in lots %}
|
||||||
{% if lot.is_temporary %}
|
{% if lot.is_temporary %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('inventory.devices.lotdevicelist', lot_id=lot.id) }}">
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}">
|
||||||
<i class="bi bi-circle"></i><span>{{ lot.name }}</span>
|
<i class="bi bi-circle"></i><span>{{ lot.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -181,7 +181,7 @@
|
||||||
<li class="nav-heading">Utils</li>
|
<li class="nav-heading">Utils</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link collapsed" href="{{ url_for('inventory.devices.taglist')}}">
|
<a class="nav-link collapsed" href="{{ url_for('inventory.taglist')}}">
|
||||||
<i class="bi bi-tags"></i>
|
<i class="bi bi-tags"></i>
|
||||||
<span>Tags</span>
|
<span>Tags</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -209,14 +209,14 @@
|
||||||
<!-- ======= Footer ======= -->
|
<!-- ======= Footer ======= -->
|
||||||
<footer id="footer" class="footer">
|
<footer id="footer" class="footer">
|
||||||
<div class="copyright">
|
<div class="copyright">
|
||||||
© Copyright <strong><span>NiceAdmin</span></strong>. All Rights Reserved
|
© Copyright <strong><span>USOdy</span></strong>. All Rights Reserved
|
||||||
</div>
|
</div>
|
||||||
<div class="credits">
|
<div class="credits">
|
||||||
<!-- All the links in the footer should remain intact. -->
|
<!-- All the links in the footer should remain intact. -->
|
||||||
<!-- You can delete the links only if you purchased the pro version. -->
|
<!-- You can delete the links only if you purchased the pro version. -->
|
||||||
<!-- Licensing information: https://bootstrapmade.com/license/ -->
|
<!-- Licensing information: https://bootstrapmade.com/license/ -->
|
||||||
<!-- Purchase the pro version with working PHP/AJAX contact form: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/ -->
|
<!-- Purchase the pro version with working PHP/AJAX contact form: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/ -->
|
||||||
Designed by <a href="https://bootstrapmade.com/">BootstrapMade</a>
|
Designed by <a href="https://bootstrapmade.com/">BootstrapMade</a> // DeviceHub {{ version }}
|
||||||
</div>
|
</div>
|
||||||
</footer><!-- End Footer -->
|
</footer><!-- End Footer -->
|
||||||
|
|
||||||
|
|
|
@ -48,12 +48,14 @@
|
||||||
<div class="invalid-feedback">Please enter your password!</div>
|
<div class="invalid-feedback">Please enter your password!</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- TODO(@slamora): hidde until it is implemented
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" name="remember" {% if form.remember.data %}checked{% endif %} id="rememberMe">
|
<input class="form-check-input" type="checkbox" name="remember" {% if form.remember.data %}checked{% endif %} id="rememberMe">
|
||||||
<label class="form-check-label" for="rememberMe">Remember me</label>
|
<label class="form-check-label" for="rememberMe">Remember me</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<button class="btn btn-primary w-100" type="submit">Login</button>
|
<button class="btn btn-primary w-100" type="submit">Login</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.action_add') }}" method="post">
|
<form action="{{ url_for('inventory.action_add') }}" method="post">
|
||||||
{{ form_new_action.csrf_token }}
|
{{ form_new_action.csrf_token }}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{% for field in form_new_action %}
|
{% for field in form_new_action %}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.lot_devices_add') }}" method="post">
|
<form action="{{ url_for('inventory.lot_devices_add') }}" method="post">
|
||||||
{{ form_lot_device.csrf_token }}
|
{{ form_lot_device.csrf_token }}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
Please write a name of a lot
|
Please write a name of a lot
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.tag_devices_add') }}" method="post">
|
<form action="{{ url_for('inventory.tag_devices_add') }}" method="post">
|
||||||
{{ form_tag_device.csrf_token }}
|
{{ form_tag_device.csrf_token }}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
Please write a name of a tag
|
Please write a name of a tag
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.allocate_add') }}" method="post">
|
<form action="{{ url_for('inventory.allocate_add') }}" method="post">
|
||||||
{{ form_new_allocate.csrf_token }}
|
{{ form_new_allocate.csrf_token }}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{% for field in form_new_allocate %}
|
{% for field in form_new_allocate %}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.datawipe_add') }}" method="post" enctype="multipart/form-data">
|
<form action="{{ url_for('inventory.datawipe_add') }}" method="post" enctype="multipart/form-data">
|
||||||
{{ form_new_datawipe.csrf_token }}
|
{{ form_new_datawipe.csrf_token }}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{% for field in form_new_datawipe %}
|
{% for field in form_new_datawipe %}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<h1>{{ page_title }}</h1>
|
<h1>{{ page_title }}</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devices.devicelist')}}">Inventory</a></li>
|
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devicelist')}}">Inventory</a></li>
|
||||||
<li class="breadcrumb-item">{{ page_title }}</li>
|
<li class="breadcrumb-item">{{ page_title }}</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -371,9 +371,9 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{% if lot_id %}
|
{% if lot_id %}
|
||||||
<a href="{{ url_for('inventory.devices.lotdevicelist', lot_id=lot_id) }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot_id) }}" class="btn btn-danger">Cancel</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('inventory.devices.devicelist') }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.devicelist') }}" class="btn btn-danger">Cancel</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
<button class="btn btn-primary" type="submit">Save</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<h1>Inventory</h1>
|
<h1>Inventory</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devices.devicelist')}}">Inventory</a></li>
|
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devicelist')}}">Inventory</a></li>
|
||||||
<li class="breadcrumb-item active">{{ page_title }}</li>
|
<li class="breadcrumb-item active">{{ page_title }}</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<h1>Inventory</h1>
|
<h1>Inventory</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devices.devicelist')}}">Inventory</a></li>
|
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devicelist')}}">Inventory</a></li>
|
||||||
{% if not lot %}
|
{% if not lot %}
|
||||||
<li class="breadcrumb-item active">Unassgined</li>
|
<li class="breadcrumb-item active">Unassgined</li>
|
||||||
{% elif lot.is_temporary %}
|
{% elif lot.is_temporary %}
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
<!-- Bordered Tabs -->
|
<!-- Bordered Tabs -->
|
||||||
|
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
<h3><a href="{{ url_for('inventory.devices.lot_edit', id=lot.id) }}">{{ lot.name }}</a></h3>
|
<h3><a href="{{ url_for('inventory.lot_edit', id=lot.id) }}">{{ lot.name }}</a></h3>
|
||||||
|
|
||||||
<div><!-- lot actions -->
|
<div><!-- lot actions -->
|
||||||
{% if lot.is_temporary %}
|
{% if lot.is_temporary %}
|
||||||
|
@ -246,9 +246,9 @@
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnSnapshot">
|
<ul class="dropdown-menu" aria-labelledby="btnSnapshot">
|
||||||
<li>
|
<li>
|
||||||
{% if lot %}
|
{% if lot %}
|
||||||
<a href="{{ url_for('inventory.devices.lot_upload_snapshot', lot_id=lot.id) }}" class="dropdown-item">
|
<a href="{{ url_for('inventory.lot_upload_snapshot', lot_id=lot.id) }}" class="dropdown-item">
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('inventory.devices.upload_snapshot') }}" class="dropdown-item">
|
<a href="{{ url_for('inventory.upload_snapshot') }}" class="dropdown-item">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<i class="bi bi-plus"></i>
|
<i class="bi bi-plus"></i>
|
||||||
Upload a new Snapshot
|
Upload a new Snapshot
|
||||||
|
@ -256,9 +256,9 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{% if lot %}
|
{% if lot %}
|
||||||
<a href="{{ url_for('inventory.devices.lot_device_add', lot_id=lot.id) }}" class="dropdown-item">
|
<a href="{{ url_for('inventory.lot_device_add', lot_id=lot.id) }}" class="dropdown-item">
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('inventory.devices.device_add') }}" class="dropdown-item">
|
<a href="{{ url_for('inventory.device_add') }}" class="dropdown-item">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<i class="bi bi-plus"></i>
|
<i class="bi bi-plus"></i>
|
||||||
Create a new Device
|
Create a new Device
|
||||||
|
@ -275,7 +275,7 @@
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnSnapshot">
|
<ul class="dropdown-menu" aria-labelledby="btnSnapshot">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('inventory.devices.trade_document_add', lot_id=lot.id)}}" class="dropdown-item">
|
<a href="{{ url_for('inventory.trade_document_add', lot_id=lot.id)}}" class="dropdown-item">
|
||||||
<i class="bi bi-plus"></i>
|
<i class="bi bi-plus"></i>
|
||||||
Add new document
|
Add new document
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
|
@ -286,12 +286,24 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="tab-content pt-2">
|
<div class="tab-content pt-2">
|
||||||
|
<form method="get">
|
||||||
|
<div class="d-flex mt-4 mb-4">
|
||||||
|
{% for f in form_filter %}
|
||||||
|
{{ f }}
|
||||||
|
{% endfor %}
|
||||||
|
<input type="submit" class="ms-2 btn btn-primary" value="Filter" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<p class="mt-3">
|
||||||
|
Displaying devices of type
|
||||||
|
<em>{{ form_filter.filter.data or "Computer" }}</em>
|
||||||
|
</p>
|
||||||
|
|
||||||
<h5 class="card-title">Computers</h5>
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">Select all</th>
|
<th scope="col">Select</th>
|
||||||
<th scope="col">Title</th>
|
<th scope="col">Title</th>
|
||||||
<th scope="col">DHID</th>
|
<th scope="col">DHID</th>
|
||||||
<th scope="col">Tags</th>
|
<th scope="col">Tags</th>
|
||||||
|
@ -312,18 +324,18 @@
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('inventory.devices.device_details', id=dev.devicehub_id)}}">
|
<a href="{{ url_for('inventory.device_details', id=dev.devicehub_id)}}">
|
||||||
{{ dev.verbose_name }}
|
{{ dev.verbose_name }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('inventory.devices.device_details', id=dev.devicehub_id)}}">
|
<a href="{{ url_for('inventory.device_details', id=dev.devicehub_id)}}">
|
||||||
{{ dev.devicehub_id }}
|
{{ dev.devicehub_id }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% for t in dev.tags | sort(attribute="id") %}
|
{% for t in dev.tags | sort(attribute="id") %}
|
||||||
<a href="{{ url_for('inventory.devices.tag_details', id=t.id)}}">{{ t.id }}</a>
|
<a href="{{ url_for('inventory.tag_details', id=t.id)}}">{{ t.id }}</a>
|
||||||
{% if not loop.last %},{% endif %}
|
{% if not loop.last %},{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -44,9 +44,9 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{% if form.id %}
|
{% if form.id %}
|
||||||
<a href="{{ url_for('inventory.devices.lotdevicelist', lot_id=form.id) }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=form.id) }}" class="btn btn-danger">Cancel</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('inventory.devices.devicelist') }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.devicelist') }}" class="btn btn-danger">Cancel</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
<button class="btn btn-primary" type="submit">Save</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.lot_devices_del') }}" method="post">
|
<form action="{{ url_for('inventory.lot_devices_del') }}" method="post">
|
||||||
{{ form_lot_device.csrf_token }}
|
{{ form_lot_device.csrf_token }}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
Please write a name of a lot
|
Please write a name of a lot
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
<a href="{{ url_for('inventory.devices.lot_del', id=lot.id)}}" type="button" class="btn btn-primary">
|
<a href="{{ url_for('inventory.lot_del', id=lot.id)}}" type="button" class="btn btn-primary">
|
||||||
Confirm
|
Confirm
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<h1>{{ title }}</h1>
|
<h1>{{ title }}</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devices.taglist')}}">Tag management</a></li>
|
<li class="breadcrumb-item"><a href="{{ url_for('inventory.taglist')}}">Tag management</a></li>
|
||||||
<li class="breadcrumb-item">{{ page_title }}</li>
|
<li class="breadcrumb-item">{{ page_title }}</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<a href="{{ url_for('inventory.devices.taglist') }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.taglist') }}" class="btn btn-danger">Cancel</a>
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
<button class="btn btn-primary" type="submit">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<h1>{{ title }}</h1>
|
<h1>{{ title }}</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devices.taglist')}}">Tag management</a></li>
|
<li class="breadcrumb-item"><a href="{{ url_for('inventory.taglist')}}">Tag management</a></li>
|
||||||
<li class="breadcrumb-item">{{ page_title }}</li>
|
<li class="breadcrumb-item">{{ page_title }}</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<a href="{{ url_for('inventory.devices.taglist') }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.taglist') }}" class="btn btn-danger">Cancel</a>
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
<button class="btn btn-primary" type="submit">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<h1>Inventory</h1>
|
<h1>Inventory</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devices.taglist')}}">Tag management</a></li>
|
<li class="breadcrumb-item"><a href="{{ url_for('inventory.taglist')}}">Tag management</a></li>
|
||||||
<li class="breadcrumb-item active">Tag details {{ tag.id }}</li>
|
<li class="breadcrumb-item active">Tag details {{ tag.id }}</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
<div class="col-lg-3 col-md-4 label">Device</div>
|
<div class="col-lg-3 col-md-4 label">Device</div>
|
||||||
<div class="col-lg-9 col-md-8">
|
<div class="col-lg-9 col-md-8">
|
||||||
{% if tag.device %}
|
{% if tag.device %}
|
||||||
<a href="{{url_for('inventory.devices.device_details', id=tag.device.devicehub_id)}}">
|
<a href="{{url_for('inventory.device_details', id=tag.device.devicehub_id)}}">
|
||||||
{{ tag.device.verbose_name }}
|
{{ tag.device.verbose_name }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -109,6 +109,6 @@
|
||||||
<script src="{{ url_for('static', filename='js/jspdf.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/jspdf.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/print.pdf.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/print.pdf.js') }}"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
qr_draw("{{url_for('inventory.devices.device_details', id=tag.device.devicehub_id, _external=True)}}");
|
qr_draw("{{url_for('inventory.device_details', id=tag.device.devicehub_id, _external=True)}}");
|
||||||
</script>
|
</script>
|
||||||
{% endblock main %}
|
{% endblock main %}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<!-- Bordered Tabs -->
|
<!-- Bordered Tabs -->
|
||||||
|
|
||||||
<div class="btn-group dropdown ml-1">
|
<div class="btn-group dropdown ml-1">
|
||||||
<a href="{{ url_for('inventory.devices.tag_add')}}" type="button" class="btn btn-primary">
|
<a href="{{ url_for('inventory.tag_add')}}" type="button" class="btn btn-primary">
|
||||||
<i class="bi bi-plus"></i>
|
<i class="bi bi-plus"></i>
|
||||||
Create Named Tag
|
Create Named Tag
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group dropdown ml-1" uib-dropdown="">
|
<div class="btn-group dropdown ml-1" uib-dropdown="">
|
||||||
<a href="{{ url_for('inventory.devices.tag_unnamed_add')}}" type="button" class="btn btn-primary">
|
<a href="{{ url_for('inventory.tag_unnamed_add')}}" type="button" class="btn btn-primary">
|
||||||
<i class="bi bi-plus"></i>
|
<i class="bi bi-plus"></i>
|
||||||
Create UnNamed Tag
|
Create UnNamed Tag
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
|
@ -52,12 +52,12 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for tag in tags %}
|
{% for tag in tags %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ url_for('inventory.devices.tag_details', id=tag.id) }}">{{ tag.id }}</a></td>
|
<td><a href="{{ url_for('inventory.tag_details', id=tag.id) }}">{{ tag.id }}</a></td>
|
||||||
<td>{% if tag.provider %}Unnamed tag {% else %}Named tag{% endif %}</td>
|
<td>{% if tag.provider %}Unnamed tag {% else %}Named tag{% endif %}</td>
|
||||||
<td>{{ tag.get_provider }}</td>
|
<td>{{ tag.get_provider }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if tag.device %}
|
{% if tag.device %}
|
||||||
<a href={{ url_for('inventory.devices.device_details', id=tag.device.devicehub_id)}}>
|
<a href={{ url_for('inventory.device_details', id=tag.device.devicehub_id)}}>
|
||||||
{{ tag.device.verbose_name }}
|
{{ tag.device.verbose_name }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="pagetitle">
|
<div class="pagetitle">
|
||||||
<nav>
|
<nav>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devices.devicelist')}}">Inventory</a></li>
|
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devicelist')}}">Inventory</a></li>
|
||||||
<li class="breadcrumb-item">Unlink Tag from Device</li>
|
<li class="breadcrumb-item">Unlink Tag from Device</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.trade_add') }}" method="post">
|
<form action="{{ url_for('inventory.trade_add') }}" method="post">
|
||||||
{{ form_new_trade.csrf_token }}
|
{{ form_new_trade.csrf_token }}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{% for field in form_new_trade %}
|
{% for field in form_new_trade %}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.trade_document_add', lot_id=form._lot.id) }}" method="post"
|
<form action="{{ url_for('inventory.trade_document_add', lot_id=form._lot.id) }}" method="post"
|
||||||
class="row g-3 needs-validation" enctype="multipart/form-data">
|
class="row g-3 needs-validation" enctype="multipart/form-data">
|
||||||
{{ form.csrf_token }}
|
{{ form.csrf_token }}
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<a href="{{ url_for('inventory.devices.lotdevicelist', lot_id=form._lot.id) }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=form._lot.id) }}" class="btn btn-danger">Cancel</a>
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
<button class="btn btn-primary" type="submit">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<h1>Inventory</h1>
|
<h1>Inventory</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devices.devicelist')}}">Inventory</a></li>
|
<li class="breadcrumb-item"><a href="{{ url_for('inventory.devicelist')}}">Inventory</a></li>
|
||||||
<li class="breadcrumb-item active">{{ page_title }}</li>
|
<li class="breadcrumb-item active">{{ page_title }}</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -56,9 +56,9 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{% if lot_id %}
|
{% if lot_id %}
|
||||||
<a href="{{ url_for('inventory.devices.lotdevicelist', lot_id=lot_id) }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot_id) }}" class="btn btn-danger">Cancel</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('inventory.devices.devicelist') }}" class="btn btn-danger">Cancel</a>
|
<a href="{{ url_for('inventory.devicelist') }}" class="btn btn-danger">Cancel</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-primary" type="submit">Send</button>
|
<button class="btn btn-primary" type="submit">Send</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,6 +3,7 @@ from flask import Blueprint
|
||||||
from flask.views import View
|
from flask.views import View
|
||||||
from flask_login import current_user, login_required, login_user, logout_user
|
from flask_login import current_user, login_required, login_user, logout_user
|
||||||
|
|
||||||
|
from ereuse_devicehub import __version__
|
||||||
from ereuse_devicehub.forms import LoginForm
|
from ereuse_devicehub.forms import LoginForm
|
||||||
from ereuse_devicehub.resources.user.models import User
|
from ereuse_devicehub.resources.user.models import User
|
||||||
from ereuse_devicehub.utils import is_safe_url
|
from ereuse_devicehub.utils import is_safe_url
|
||||||
|
@ -28,10 +29,9 @@ class LoginView(View):
|
||||||
if not is_safe_url(flask.request, next_url):
|
if not is_safe_url(flask.request, next_url):
|
||||||
return flask.abort(400)
|
return flask.abort(400)
|
||||||
|
|
||||||
return flask.redirect(
|
return flask.redirect(next_url or flask.url_for('inventory.devicelist'))
|
||||||
next_url or flask.url_for('inventory.devices.devicelist')
|
context = {'form': form, 'version': __version__}
|
||||||
)
|
return flask.render_template('ereuse_devicehub/user_login.html', **context)
|
||||||
return flask.render_template('ereuse_devicehub/user_login.html', form=form)
|
|
||||||
|
|
||||||
|
|
||||||
class LogoutView(View):
|
class LogoutView(View):
|
||||||
|
@ -47,6 +47,7 @@ class UserProfileView(View):
|
||||||
def dispatch_request(self):
|
def dispatch_request(self):
|
||||||
context = {
|
context = {
|
||||||
'current_user': current_user,
|
'current_user': current_user,
|
||||||
|
'version': __version__,
|
||||||
}
|
}
|
||||||
return flask.render_template(self.template_name, **context)
|
return flask.render_template(self.template_name, **context)
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ Flask-SQLAlchemy==2.3.2
|
||||||
Flask-WTF==1.0.0
|
Flask-WTF==1.0.0
|
||||||
hashids==1.2.0
|
hashids==1.2.0
|
||||||
inflection==0.3.1
|
inflection==0.3.1
|
||||||
|
itsdangerous==2.0.1
|
||||||
marshmallow==3.0.0b11
|
marshmallow==3.0.0b11
|
||||||
marshmallow-enum==1.4.1
|
marshmallow-enum==1.4.1
|
||||||
passlib==1.7.1
|
passlib==1.7.1
|
||||||
|
@ -25,7 +26,7 @@ python-stdnum==1.9
|
||||||
PyYAML==5.4
|
PyYAML==5.4
|
||||||
requests[security]==2.27.1
|
requests[security]==2.27.1
|
||||||
requests-mock==1.5.2
|
requests-mock==1.5.2
|
||||||
SQLAlchemy==1.2.17
|
SQLAlchemy==1.3.24
|
||||||
SQLAlchemy-Utils==0.33.11
|
SQLAlchemy-Utils==0.33.11
|
||||||
teal==0.2.0a38
|
teal==0.2.0a38
|
||||||
webargs==5.5.3
|
webargs==5.5.3
|
||||||
|
|
Reference in New Issue