This commit is contained in:
Cayo Puigdefabregas 2022-03-17 10:18:02 +01:00
commit ccc28435db
32 changed files with 229 additions and 132 deletions

View File

@ -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:

View File

@ -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

View File

@ -1,5 +1,3 @@
; SHARED on https://pad.cas.cat/usody-devicehub-contributing
# Contributing to devicehub # Contributing to devicehub
## Writing code ## Writing code

View File

@ -1 +1 @@
__version__ = "1.0.12-beta" __version__ = "2.1.0.dev"

View File

@ -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()])

View File

@ -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__
) )

View File

@ -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,

View File

@ -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)

View File

@ -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__ = (
@ -150,10 +150,10 @@ class TradeDocument(Thing):
with suppress(StopIteration, ValueError): with suppress(StopIteration, ValueError):
actions = copy.copy(self.actions) actions = copy.copy(self.actions)
actions.sort(key=lambda x: x.created) actions.sort(key=lambda x: x.created)
t_trades = ['Trade', t_trades = ['Trade',
'Confirm', 'Confirm',
'ConfirmRevokeDocument', 'ConfirmRevokeDocument',
'RevokeDocument', 'RevokeDocument',
'ConfirmDocument'] 'ConfirmDocument']
return next(e for e in reversed(actions) if e.t in t_trades) return next(e for e in reversed(actions) if e.t in t_trades)

View File

@ -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">
&copy; Copyright <strong><span>NiceAdmin</span></strong>. All Rights Reserved &copy; 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 -->

View File

@ -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>

View File

@ -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 %}

View File

@ -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

View File

@ -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

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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>

View File

@ -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 %}

View File

@ -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>

View File

@ -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>

View File

@ -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)

View File

@ -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