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
hooks:
- id: isort
# args: ["--profile", "black", "--filter-files"]
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
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
ml).
## master
## [2.0.0-alpha]
- [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
- [bugfix] #206 fix 2 bugs about visibility devices when you are not the owner
- [addend] #205 ux improvements
- [addend] #204 render from backend export files
- [addend] #203 render from backend Trade action
- [addend] #201 render from backend Data Wipe action
- [addend] #196 render from backend action system
- [addend] #195 render from backend tags system
- [addend] #193 render from backend devices and lots
- [changes] #191 pass to drop teal and use the pure flask and use render from flask
## testing
## [2.0.0] - 2022-03-15
First server render HTML version. Completely rewrites views of angular JS client on flask.
- [added] #193 render on backend devices and lots
- [added] #195 render on backend tags system
- [added] #196 render on backend action system
- [added] #201 render on backend Data Wipe action
- [added] #203 render on backend Trade action
- [added] #204 render on backend export files
- [added] #205 UX improvements
- [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]
- [changes] #187 now is possible duplicate slots of RAM.
- [changes] #188 Excel report devices allow to see device to old owners.
- [changed] #187 now is possible duplicate slots of RAM.
- [changed] #188 Excel report devices allow to see device to old owners.
## [1.0.11-beta]
- [addend] #186 adding property power_on_hours.
- [added] #186 adding property power_on_hours.
## [1.0.10-beta]
- [addend] #170 can delete/deactivate devices.
- [bugfix] #168 can to do a trade without devices.
- [added] #170 can delete/deactivate devices.
- [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
- [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]
- [added] #159 external document as proof of erase of disk
@ -40,7 +45,7 @@ ml).
## [1.0.8-beta]
- [bugfix] #161 fixing DataStorage with bigInteger
- [fixed] #161 fixing DataStorage with bigInteger
## [1.0.7-beta]
- [added] #158 support for encrypted snapshots data
@ -48,26 +53,26 @@ ml).
- [added] #140 adding endpoint for download the settings for usb workbench
## [1.0.6-beta]
- [bugfix] #143 biginteger instead of integer in TestDataStorage
- [fixed] #143 biginteger instead of integer in TestDataStorage
## [1.0.5-beta]
- [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] #127 add one code for every named tag
- [added] #131 add one code for every device
- [bugfix] #138 search device with devicehubId
- [fixed] #138 search device with devicehubId
## [1.0.4-beta]
- [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 get all licences in one query
- [added] #102 adding endpoint for download metrics
- [bugfix] #100 fixing bug of scheme live
- [bugfix] #101 fixing bug when 2 users have one device and launch one live
- [changes] #114 clean blockchain of all models
- [changes] #118 deactivate manual merge
- [changes] #118 clean datas of public information of devices
- [remove] #114 remove proof system
- [changed] #114 clean blockchain of all models
- [changed] #118 deactivate manual merge
- [changed] #118 clean datas of public information of devices
- [fixed] #100 fixing bug of scheme live
- [fixed] #101 fixing bug when 2 users have one device and launch one live
- [removed] #114 remove proof system
## [1.0.3-beta]
- [added] #85 add mac of network adapter to device hid
@ -75,6 +80,6 @@ ml).
## [1.0.2-beta]
- [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
- [fixed] #89 save json on disk only for shapshots
- [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
## 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.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):
lot = StringField('Lot', [validators.UUID()])

View File

@ -11,11 +11,12 @@ from requests.exceptions import ConnectionError
from sqlalchemy import or_
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.inventory.forms import (
AllocateForm,
DataWipeForm,
FilterForm,
LotDeviceForm,
LotForm,
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.tag.model import Tag
# TODO(@slamora): rename base 'inventory.devices' --> 'inventory'
devices = Blueprint('inventory.devices', __name__, url_prefix='/inventory')
devices = Blueprint('inventory', __name__, url_prefix='/inventory')
logger = logging.getLogger(__name__)
@ -60,9 +60,8 @@ class DeviceListMix(GenericMixView):
template_name = 'inventory/device_list.html'
def get_context(self, lot_id):
# TODO @cayop adding filter
# https://github.com/eReuse/devicehub-teal/blob/testing/ereuse_devicehub/resources/device/views.py#L56
filter_types = ['Desktop', 'Laptop', 'Server']
form_filter = FilterForm()
filter_types = form_filter.search()
lots = self.get_lots()
lot = None
tags = (
@ -72,8 +71,9 @@ class DeviceListMix(GenericMixView):
)
if lot_id:
# import pdb; pdb.set_trace()
lot = lots.filter(Lot.id == lot_id).one()
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)
form_new_action = NewActionForm(lot=lot.id)
@ -85,12 +85,20 @@ class DeviceListMix(GenericMixView):
user_from=g.user.email,
)
else:
if "All" in filter_types:
devices = (
Device.query.filter(Device.owner_id == current_user.id)
.filter(Device.type.in_(filter_types))
.filter_by(lots=None)
.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_allocate = AllocateForm()
form_new_datawipe = DataWipeForm()
@ -109,9 +117,11 @@ class DeviceListMix(GenericMixView):
'form_new_allocate': form_new_allocate,
'form_new_datawipe': form_new_datawipe,
'form_new_trade': form_new_trade,
'form_filter': form_filter,
'lot': lot,
'tags': tags,
'list_devices': list_devices,
'version': __version__,
}
return self.context
@ -139,6 +149,7 @@ class DeviceDetailView(GenericMixView):
'device': device,
'lots': lots,
'page_title': 'Device {}'.format(device.devicehub_id),
'version': __version__,
}
return flask.render_template(self.template_name, **context)
@ -159,7 +170,7 @@ class LotDeviceAddView(View):
else:
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)
@ -179,7 +190,7 @@ class LotDeviceDeleteView(View):
else:
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)
@ -193,11 +204,16 @@ class LotCreateView(GenericMixView):
form = LotForm()
if form.validate_on_submit():
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)
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)
@ -211,11 +227,16 @@ class LotUpdateView(View):
form = LotForm(id=id)
if form.validate_on_submit():
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)
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)
@ -229,11 +250,11 @@ class LotDeleteView(View):
if form.instance.trade:
msg = "Sorry, the lot cannot be deleted because have a trade action "
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)
form.remove()
next_url = url_for('inventory.devices.devicelist')
next_url = url_for('inventory.devicelist')
return flask.redirect(next_url)
@ -250,6 +271,7 @@ class UploadSnapshotView(GenericMixView):
'lots': lots,
'form': form,
'lot_id': lot_id,
'version': __version__,
}
if form.validate_on_submit():
snapshot = form.save(commit=False)
@ -275,12 +297,13 @@ class DeviceCreateView(GenericMixView):
'lots': lots,
'form': form,
'lot_id': lot_id,
'version': __version__,
}
if form.validate_on_submit():
snapshot = form.save(commit=False)
next_url = url_for('inventory.devices.devicelist')
next_url = url_for('inventory.devicelist')
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.devices.add(snapshot.device)
db.session.add(lot)
@ -304,6 +327,7 @@ class TagListView(View):
'lots': lots,
'tags': tags,
'page_title': 'Tags Management',
'version': __version__,
}
return flask.render_template(self.template_name, **context)
@ -315,11 +339,11 @@ class TagAddView(View):
def dispatch_request(self):
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()
if form.validate_on_submit():
form.save()
next_url = url_for('inventory.devices.taglist')
next_url = url_for('inventory.taglist')
return flask.redirect(next_url)
return flask.render_template(self.template_name, form=form, **context)
@ -332,7 +356,11 @@ class TagAddUnnamedView(View):
def dispatch_request(self):
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()
if form.validate_on_submit():
try:
@ -347,7 +375,7 @@ class TagAddUnnamedView(View):
)
messages.error(msg)
next_url = url_for('inventory.devices.taglist')
next_url = url_for('inventory.taglist')
return flask.redirect(next_url)
return flask.render_template(self.template_name, form=form, **context)
@ -367,6 +395,7 @@ class TagDetailView(View):
'lots': lots,
'tag': tag,
'page_title': '{} Tag'.format(tag.code),
'version': __version__,
}
return flask.render_template(self.template_name, **context)
@ -395,11 +424,15 @@ class TagUnlinkDeviceView(View):
if form.validate_on_submit():
form.remove()
next_url = url_for('inventory.devices.devicelist')
next_url = url_for('inventory.devicelist')
return flask.redirect(next_url)
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
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):
@ -508,11 +541,11 @@ class NewTradeDocumentView(View):
if self.form.validate_on_submit():
self.form.save()
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.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
one container to an other."""
weight = db.Column(db.Float(nullable=True))
weight = db.Column(db.Float())
weight.comment = """Weight than go to recycling"""
container_from_id = db.Column(
db.BigInteger,

View File

@ -1217,6 +1217,7 @@ def create_code_tag(mapper, connection, device):
this tag is the same of devicehub_id.
"""
from ereuse_devicehub.resources.tag.model import Tag
if isinstance(device, Computer):
tag = Tag(device_id=device.id, id=device.devicehub_id)
db.session.add(tag)

View File

@ -72,7 +72,7 @@ class TradeDocument(Thing):
file_hash.comment = """This is the hash of the file produced from frontend."""
url = db.Column(URL())
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."""
__table_args__ = (

View File

@ -5,7 +5,7 @@
<header id="header" class="header fixed-top d-flex align-items-center">
<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="">
</a>
<i class="bi bi-list toggle-sidebar-btn"></i>
@ -90,7 +90,7 @@
</li><!-- End Dashboard Nav -->
<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>
<span>Unassigned devices</span>
</a>
@ -114,7 +114,7 @@
{% for lot in lots %}
{% if lot.is_incoming %}
<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>
</a>
</li>
@ -139,7 +139,7 @@
{% for lot in lots %}
{% if lot.is_outgoing %}
<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>
</a>
</li>
@ -162,14 +162,14 @@
<ul id="temporal-lots-nav" class="nav-content collapse " data-bs-parent="#sidebar-nav">
{% endif %}
<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>
</a>
</li>
{% for lot in lots %}
{% if lot.is_temporary %}
<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>
</a>
</li>
@ -181,7 +181,7 @@
<li class="nav-heading">Utils</li>
<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>
<span>Tags</span>
</a>
@ -209,14 +209,14 @@
<!-- ======= Footer ======= -->
<footer id="footer" class="footer">
<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 class="credits">
<!-- All the links in the footer should remain intact. -->
<!-- You can delete the links only if you purchased the pro version. -->
<!-- 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/ -->
Designed by <a href="https://bootstrapmade.com/">BootstrapMade</a>
Designed by <a href="https://bootstrapmade.com/">BootstrapMade</a> // DeviceHub {{ version }}
</div>
</footer><!-- End Footer -->

View File

@ -48,12 +48,14 @@
<div class="invalid-feedback">Please enter your password!</div>
</div>
<!-- TODO(@slamora): hidde until it is implemented
<div class="col-12">
<div class="form-check">
<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>
</div>
</div>
-->
<div class="col-12">
<button class="btn btn-primary w-100" type="submit">Login</button>
</div>

View File

@ -7,7 +7,7 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</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 }}
<div class="modal-body">
{% 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>
</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 }}
<div class="modal-body">
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>
</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 }}
<div class="modal-body">
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>
</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 }}
<div class="modal-body">
{% 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>
</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 }}
<div class="modal-body">
{% for field in form_new_datawipe %}

View File

@ -5,7 +5,7 @@
<h1>{{ page_title }}</h1>
<nav>
<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>
</ol>
</nav>
@ -371,9 +371,9 @@
<div>
{% 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 %}
<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 %}
<button class="btn btn-primary" type="submit">Save</button>
</div>

View File

@ -5,7 +5,7 @@
<h1>Inventory</h1>
<nav>
<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>
</ol>
</nav>

View File

@ -5,7 +5,7 @@
<h1>Inventory</h1>
<nav>
<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 %}
<li class="breadcrumb-item active">Unassgined</li>
{% elif lot.is_temporary %}
@ -33,7 +33,7 @@
<!-- Bordered Tabs -->
<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 -->
{% if lot.is_temporary %}
@ -246,9 +246,9 @@
<ul class="dropdown-menu" aria-labelledby="btnSnapshot">
<li>
{% 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 %}
<a href="{{ url_for('inventory.devices.upload_snapshot') }}" class="dropdown-item">
<a href="{{ url_for('inventory.upload_snapshot') }}" class="dropdown-item">
{% endif %}
<i class="bi bi-plus"></i>
Upload a new Snapshot
@ -256,9 +256,9 @@
</li>
<li>
{% 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 %}
<a href="{{ url_for('inventory.devices.device_add') }}" class="dropdown-item">
<a href="{{ url_for('inventory.device_add') }}" class="dropdown-item">
{% endif %}
<i class="bi bi-plus"></i>
Create a new Device
@ -275,7 +275,7 @@
</button>
<ul class="dropdown-menu" aria-labelledby="btnSnapshot">
<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>
Add new document
<span class="caret"></span>
@ -286,12 +286,24 @@
{% endif %}
<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">
<thead>
<tr>
<th scope="col">Select all</th>
<th scope="col">Select</th>
<th scope="col">Title</th>
<th scope="col">DHID</th>
<th scope="col">Tags</th>
@ -312,18 +324,18 @@
/>
</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 }}
</a>
</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 }}
</a>
</td>
<td>
{% 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 %}
{% endfor %}
</td>

View File

@ -44,9 +44,9 @@
<div>
{% 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 %}
<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 %}
<button class="btn btn-primary" type="submit">Save</button>
</div>

View File

@ -6,7 +6,7 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</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 }}
<div class="modal-body">
Please write a name of a lot

View File

@ -16,7 +16,7 @@
<div class="modal-footer">
<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
</a>
</div>

View File

@ -5,7 +5,7 @@
<h1>{{ title }}</h1>
<nav>
<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>
</ol>
</nav>
@ -49,7 +49,7 @@
</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>
</div>
</form>

View File

@ -5,7 +5,7 @@
<h1>{{ title }}</h1>
<nav>
<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>
</ol>
</nav>
@ -49,7 +49,7 @@
</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>
</div>
</form>

View File

@ -5,7 +5,7 @@
<h1>Inventory</h1>
<nav>
<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>
</ol>
</nav>
@ -33,7 +33,7 @@
<div class="col-lg-3 col-md-4 label">Device</div>
<div class="col-lg-9 col-md-8">
{% 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 }}
</a>
{% endif %}
@ -109,6 +109,6 @@
<script src="{{ url_for('static', filename='js/jspdf.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/print.pdf.js') }}"></script>
<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>
{% endblock main %}

View File

@ -20,7 +20,7 @@
<!-- Bordered Tabs -->
<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>
Create Named Tag
<span class="caret"></span>
@ -28,7 +28,7 @@
</div>
<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>
Create UnNamed Tag
<span class="caret"></span>
@ -52,12 +52,12 @@
<tbody>
{% for tag in tags %}
<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>{{ tag.get_provider }}</td>
<td>
{% 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 }}
</a>
{% endif %}

View File

@ -4,7 +4,7 @@
<div class="pagetitle">
<nav>
<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>
</ol>
</nav>

View File

@ -9,7 +9,7 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</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 }}
<div class="modal-body">
{% for field in form_new_trade %}

View File

@ -30,7 +30,7 @@
{% endif %}
</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">
{{ form.csrf_token }}
{% for field in form %}
@ -51,7 +51,7 @@
{% endfor %}
<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>
</div>
</form>

View File

@ -5,7 +5,7 @@
<h1>Inventory</h1>
<nav>
<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>
</ol>
</nav>
@ -56,9 +56,9 @@
<div>
{% 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 %}
<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 %}
<button class="btn btn-primary" type="submit">Send</button>
</div>

View File

@ -3,6 +3,7 @@ from flask import Blueprint
from flask.views import View
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.resources.user.models import User
from ereuse_devicehub.utils import is_safe_url
@ -28,10 +29,9 @@ class LoginView(View):
if not is_safe_url(flask.request, next_url):
return flask.abort(400)
return flask.redirect(
next_url or flask.url_for('inventory.devices.devicelist')
)
return flask.render_template('ereuse_devicehub/user_login.html', form=form)
return flask.redirect(next_url or flask.url_for('inventory.devicelist'))
context = {'form': form, 'version': __version__}
return flask.render_template('ereuse_devicehub/user_login.html', **context)
class LogoutView(View):
@ -47,6 +47,7 @@ class UserProfileView(View):
def dispatch_request(self):
context = {
'current_user': current_user,
'version': __version__,
}
return flask.render_template(self.template_name, **context)

View File

@ -14,6 +14,7 @@ Flask-SQLAlchemy==2.3.2
Flask-WTF==1.0.0
hashids==1.2.0
inflection==0.3.1
itsdangerous==2.0.1
marshmallow==3.0.0b11
marshmallow-enum==1.4.1
passlib==1.7.1
@ -25,7 +26,7 @@ python-stdnum==1.9
PyYAML==5.4
requests[security]==2.27.1
requests-mock==1.5.2
SQLAlchemy==1.2.17
SQLAlchemy==1.3.24
SQLAlchemy-Utils==0.33.11
teal==0.2.0a38
webargs==5.5.3