Merge branch 'testing' into feature/4094-add-new-fields
This commit is contained in:
commit
b84f379468
42
docs/conf.py
42
docs/conf.py
|
@ -30,7 +30,6 @@ from teal.enums import Country, Currency, Layouts, Subdivision
|
||||||
from teal.marshmallow import EnumField
|
from teal.marshmallow import EnumField
|
||||||
|
|
||||||
from ereuse_devicehub.marshmallow import NestedOn
|
from ereuse_devicehub.marshmallow import NestedOn
|
||||||
from ereuse_devicehub.resources.schemas import Thing
|
|
||||||
|
|
||||||
project = 'Devicehub'
|
project = 'Devicehub'
|
||||||
copyright = '2020, eReuse.org team'
|
copyright = '2020, eReuse.org team'
|
||||||
|
@ -56,7 +55,7 @@ extensions = [
|
||||||
'sphinx.ext.viewcode',
|
'sphinx.ext.viewcode',
|
||||||
'sphinxcontrib.plantuml',
|
'sphinxcontrib.plantuml',
|
||||||
'sphinx.ext.autosectionlabel',
|
'sphinx.ext.autosectionlabel',
|
||||||
'sphinx.ext.autodoc'
|
'sphinx.ext.autodoc',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
@ -126,15 +125,12 @@ latex_elements = {
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
# The paper size ('letterpaper' or 'a4paper').
|
||||||
#
|
#
|
||||||
# 'papersize': 'letterpaper',
|
# 'papersize': 'letterpaper',
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
#
|
#
|
||||||
# 'pointsize': '10pt',
|
# 'pointsize': '10pt',
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
# Additional stuff for the LaTeX preamble.
|
||||||
#
|
#
|
||||||
# 'preamble': '',
|
# 'preamble': '',
|
||||||
|
|
||||||
# Latex figure (float) alignment
|
# Latex figure (float) alignment
|
||||||
#
|
#
|
||||||
# 'figure_align': 'htbp',
|
# 'figure_align': 'htbp',
|
||||||
|
@ -144,18 +140,20 @@ latex_elements = {
|
||||||
# (source start file, target name, title,
|
# (source start file, target name, title,
|
||||||
# author, documentclass [howto, manual, or own class]).
|
# author, documentclass [howto, manual, or own class]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
(master_doc, 'Devicehub.tex', 'Devicehub Documentation',
|
(
|
||||||
'eReuse.org team', 'manual'),
|
master_doc,
|
||||||
|
'Devicehub.tex',
|
||||||
|
'Devicehub Documentation',
|
||||||
|
'eReuse.org team',
|
||||||
|
'manual',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# -- Options for manual page output ------------------------------------------
|
# -- Options for manual page output ------------------------------------------
|
||||||
|
|
||||||
# One entry per manual page. List of tuples
|
# One entry per manual page. List of tuples
|
||||||
# (source start file, name, description, authors, manual section).
|
# (source start file, name, description, authors, manual section).
|
||||||
man_pages = [
|
man_pages = [(master_doc, 'devicehub', 'Devicehub Documentation', [author], 1)]
|
||||||
(master_doc, 'devicehub', 'Devicehub Documentation',
|
|
||||||
[author], 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
# -- Options for Texinfo output ----------------------------------------------
|
# -- Options for Texinfo output ----------------------------------------------
|
||||||
|
|
||||||
|
@ -163,9 +161,15 @@ man_pages = [
|
||||||
# (source start file, target name, title, author,
|
# (source start file, target name, title, author,
|
||||||
# dir menu entry, description, category)
|
# dir menu entry, description, category)
|
||||||
texinfo_documents = [
|
texinfo_documents = [
|
||||||
(master_doc, 'Devicehub', 'Devicehub Documentation',
|
(
|
||||||
author, 'Devicehub', 'One line description of project.',
|
master_doc,
|
||||||
'Miscellaneous'),
|
'Devicehub',
|
||||||
|
'Devicehub Documentation',
|
||||||
|
author,
|
||||||
|
'Devicehub',
|
||||||
|
'One line description of project.',
|
||||||
|
'Miscellaneous',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# -- Extension configuration -------------------------------------------------
|
# -- Extension configuration -------------------------------------------------
|
||||||
|
@ -199,6 +203,7 @@ class DhlistDirective(Directive):
|
||||||
This requires :py:class:`ereuse_devicehub.resources.schemas.SchemaMeta`.
|
This requires :py:class:`ereuse_devicehub.resources.schemas.SchemaMeta`.
|
||||||
You will find in that module more information.
|
You will find in that module more information.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
has_content = False
|
has_content = False
|
||||||
|
|
||||||
# Definition of passed-in options
|
# Definition of passed-in options
|
||||||
|
@ -216,7 +221,7 @@ class DhlistDirective(Directive):
|
||||||
|
|
||||||
sections = []
|
sections = []
|
||||||
sections.append(self.links(things)) # Make index
|
sections.append(self.links(things)) # Make index
|
||||||
for thng in things: # type: Thing
|
for thng in things:
|
||||||
# Generate a section for each class, with a title,
|
# Generate a section for each class, with a title,
|
||||||
# fields description and a paragraph
|
# fields description and a paragraph
|
||||||
section = n.section(ids=[self._id(thng)])
|
section = n.section(ids=[self._id(thng)])
|
||||||
|
@ -228,7 +233,9 @@ class DhlistDirective(Directive):
|
||||||
for key, f in thng._own:
|
for key, f in thng._own:
|
||||||
name = n.field_name(text=f.data_key or key)
|
name = n.field_name(text=f.data_key or key)
|
||||||
body = [
|
body = [
|
||||||
self.parse('{} {}'.format(self.type(f), f.metadata.get('description', '')))
|
self.parse(
|
||||||
|
'{} {}'.format(self.type(f), f.metadata.get('description', ''))
|
||||||
|
)
|
||||||
]
|
]
|
||||||
if isinstance(f, EnumField):
|
if isinstance(f, EnumField):
|
||||||
body.append(self._parse_enum_field(f))
|
body.append(self._parse_enum_field(f))
|
||||||
|
@ -244,6 +251,7 @@ class DhlistDirective(Directive):
|
||||||
|
|
||||||
def _parse_enum_field(self, f):
|
def _parse_enum_field(self, f):
|
||||||
from ereuse_devicehub.resources.device import states
|
from ereuse_devicehub.resources.device import states
|
||||||
|
|
||||||
if issubclass(f.enum, (Subdivision, Currency, Country, Layouts, states.State)):
|
if issubclass(f.enum, (Subdivision, Currency, Country, Layouts, states.State)):
|
||||||
return self.parse(f.enum.__doc__)
|
return self.parse(f.enum.__doc__)
|
||||||
else:
|
else:
|
||||||
|
@ -298,7 +306,7 @@ class DhlistDirective(Directive):
|
||||||
|
|
||||||
def parse(self, text) -> n.container:
|
def parse(self, text) -> n.container:
|
||||||
"""Parses text possibly containing ReST stuff and adds it in
|
"""Parses text possibly containing ReST stuff and adds it in
|
||||||
a node."""
|
a node."""
|
||||||
p = n.container('')
|
p = n.container('')
|
||||||
self.state.nested_parse(StringList(string2lines(inspect.cleandoc(text))), 0, p)
|
self.state.nested_parse(StringList(string2lines(inspect.cleandoc(text))), 0, p)
|
||||||
return p
|
return p
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import Set
|
|
||||||
|
|
||||||
from decouple import config
|
from decouple import config
|
||||||
from teal.auth import TokenAuth
|
from teal.auth import TokenAuth
|
||||||
|
@ -44,7 +43,7 @@ class DevicehubConfig(Config):
|
||||||
import_resource(metric_def),
|
import_resource(metric_def),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
PASSWORD_SCHEMES = {'pbkdf2_sha256'} # type: Set[str]
|
PASSWORD_SCHEMES = {'pbkdf2_sha256'}
|
||||||
SECRET_KEY = config('SECRET_KEY')
|
SECRET_KEY = config('SECRET_KEY')
|
||||||
DB_USER = config('DB_USER', 'dhub')
|
DB_USER = config('DB_USER', 'dhub')
|
||||||
DB_PASSWORD = config('DB_PASSWORD', 'ereuse')
|
DB_PASSWORD = config('DB_PASSWORD', 'ereuse')
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import itertools
|
import itertools
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Set
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import click_spinner
|
import click_spinner
|
||||||
|
@ -109,7 +108,7 @@ class Dummy:
|
||||||
files = tuple(Path(__file__).parent.joinpath('files').iterdir())
|
files = tuple(Path(__file__).parent.joinpath('files').iterdir())
|
||||||
print('done.')
|
print('done.')
|
||||||
sample_pc = None # We treat this one as a special sample for demonstrations
|
sample_pc = None # We treat this one as a special sample for demonstrations
|
||||||
pcs = set() # type: Set[int]
|
pcs = set()
|
||||||
with click.progressbar(files, label='Creating devices...'.ljust(28)) as bar:
|
with click.progressbar(files, label='Creating devices...'.ljust(28)) as bar:
|
||||||
for path in bar:
|
for path in bar:
|
||||||
with path.open() as f:
|
with path.open() as f:
|
||||||
|
|
|
@ -91,7 +91,7 @@ DEVICES = {
|
||||||
],
|
],
|
||||||
"Drives & Storage": [
|
"Drives & Storage": [
|
||||||
"All DataStorage",
|
"All DataStorage",
|
||||||
"HardDrives",
|
"HardDrive",
|
||||||
"SolidStageDrive",
|
"SolidStageDrive",
|
||||||
],
|
],
|
||||||
"Accessories": [
|
"Accessories": [
|
||||||
|
|
|
@ -55,15 +55,26 @@ devices = Blueprint('inventory', __name__, url_prefix='/inventory')
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
PER_PAGE = 20
|
||||||
|
|
||||||
|
|
||||||
class DeviceListMixin(GenericMixin):
|
class DeviceListMixin(GenericMixin):
|
||||||
template_name = 'inventory/device_list.html'
|
template_name = 'inventory/device_list.html'
|
||||||
|
|
||||||
def get_context(self, lot_id=None, all_devices=False):
|
def get_context(self, lot_id=None, all_devices=False):
|
||||||
super().get_context()
|
super().get_context()
|
||||||
|
|
||||||
|
page = int(request.args.get('page', 1))
|
||||||
|
per_page = int(request.args.get('per_page', PER_PAGE))
|
||||||
|
filter = request.args.get('filter', "All+Computers")
|
||||||
|
# import pdb; pdb.set_trace()
|
||||||
|
|
||||||
lots = self.context['lots']
|
lots = self.context['lots']
|
||||||
form_filter = FilterForm(lots, lot_id, all_devices=all_devices)
|
form_filter = FilterForm(lots, lot_id, all_devices=all_devices)
|
||||||
devices = form_filter.search()
|
devices = form_filter.search().paginate(page=page, per_page=per_page)
|
||||||
|
devices.first = per_page * devices.page - per_page + 1
|
||||||
|
devices.last = len(devices.items) + devices.first - 1
|
||||||
|
|
||||||
lot = None
|
lot = None
|
||||||
form_transfer = ''
|
form_transfer = ''
|
||||||
form_delivery = ''
|
form_delivery = ''
|
||||||
|
@ -92,6 +103,7 @@ class DeviceListMixin(GenericMixin):
|
||||||
'tags': self.get_user_tags(),
|
'tags': self.get_user_tags(),
|
||||||
'list_devices': self.get_selected_devices(form_new_action),
|
'list_devices': self.get_selected_devices(form_new_action),
|
||||||
'all_devices': all_devices,
|
'all_devices': all_devices,
|
||||||
|
'filter': filter,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -118,16 +130,36 @@ class ErasureListView(DeviceListMixin):
|
||||||
def dispatch_request(self, orphans=0):
|
def dispatch_request(self, orphans=0):
|
||||||
self.get_context()
|
self.get_context()
|
||||||
self.get_devices(orphans)
|
self.get_devices(orphans)
|
||||||
if orphans:
|
|
||||||
self.context['orphans'] = True
|
|
||||||
return flask.render_template(self.template_name, **self.context)
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
def get_devices(self, orphans):
|
def get_devices(self, orphans):
|
||||||
|
page = int(request.args.get('page', 1))
|
||||||
|
per_page = int(request.args.get('per_page', PER_PAGE))
|
||||||
|
|
||||||
erasure = EraseBasic.query.filter_by(author=g.user).order_by(
|
erasure = EraseBasic.query.filter_by(author=g.user).order_by(
|
||||||
EraseBasic.created.desc()
|
EraseBasic.created.desc()
|
||||||
)
|
)
|
||||||
if orphans:
|
if orphans:
|
||||||
erasure = [e for e in erasure if e.device.orphan]
|
schema = app.config.get('SCHEMA')
|
||||||
|
sql = f"""
|
||||||
|
select action.id from {schema}.action as action
|
||||||
|
inner join {schema}.erase_basic as erase
|
||||||
|
on action.id=erase.id
|
||||||
|
inner join {schema}.device as device
|
||||||
|
on device.id=action.parent_id
|
||||||
|
inner join {schema}.placeholder as placeholder
|
||||||
|
on placeholder.binding_id=device.id
|
||||||
|
where action.parent_id is null or placeholder.kangaroo=true
|
||||||
|
"""
|
||||||
|
ids = (e[0] for e in db.session.execute(sql))
|
||||||
|
erasure = EraseBasic.query.filter(EraseBasic.id.in_(ids)).order_by(
|
||||||
|
EraseBasic.created.desc()
|
||||||
|
)
|
||||||
|
self.context['orphans'] = True
|
||||||
|
|
||||||
|
erasure = erasure.paginate(page=page, per_page=per_page)
|
||||||
|
erasure.first = per_page * erasure.page - per_page + 1
|
||||||
|
erasure.last = len(erasure.items) + erasure.first - 1
|
||||||
self.context['erasure'] = erasure
|
self.context['erasure'] = erasure
|
||||||
|
|
||||||
|
|
||||||
|
@ -1178,43 +1210,17 @@ class SnapshotListView(GenericMixin):
|
||||||
return flask.render_template(self.template_name, **self.context)
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
def get_snapshots_log(self):
|
def get_snapshots_log(self):
|
||||||
|
page = int(request.args.get('page', 1))
|
||||||
|
per_page = int(request.args.get('per_page', PER_PAGE))
|
||||||
|
|
||||||
snapshots_log = SnapshotsLog.query.filter(
|
snapshots_log = SnapshotsLog.query.filter(
|
||||||
SnapshotsLog.owner == g.user
|
SnapshotsLog.owner == g.user
|
||||||
).order_by(SnapshotsLog.created.desc())
|
).order_by(SnapshotsLog.created.desc())
|
||||||
logs = {}
|
|
||||||
for snap in snapshots_log:
|
|
||||||
try:
|
|
||||||
system_uuid = snap.snapshot.device.system_uuid or ''
|
|
||||||
except AttributeError:
|
|
||||||
system_uuid = ''
|
|
||||||
|
|
||||||
if snap.snapshot_uuid not in logs:
|
snapshots_log = snapshots_log.paginate(page=page, per_page=per_page)
|
||||||
logs[snap.snapshot_uuid] = {
|
snapshots_log.first = per_page * snapshots_log.page - per_page + 1
|
||||||
'sid': snap.sid,
|
snapshots_log.last = len(snapshots_log.items) + snapshots_log.first - 1
|
||||||
'snapshot_uuid': snap.snapshot_uuid,
|
return snapshots_log
|
||||||
'version': snap.version,
|
|
||||||
'device': snap.get_device(),
|
|
||||||
'system_uuid': system_uuid,
|
|
||||||
'status': snap.get_status(),
|
|
||||||
'severity': snap.severity,
|
|
||||||
'created': snap.created,
|
|
||||||
'type_device': snap.get_type_device(),
|
|
||||||
'original_dhid': snap.get_original_dhid(),
|
|
||||||
'new_device': snap.get_new_device(),
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
|
|
||||||
if snap.created > logs[snap.snapshot_uuid]['created']:
|
|
||||||
logs[snap.snapshot_uuid]['created'] = snap.created
|
|
||||||
|
|
||||||
if snap.severity > logs[snap.snapshot_uuid]['severity']:
|
|
||||||
logs[snap.snapshot_uuid]['severity'] = snap.severity
|
|
||||||
logs[snap.snapshot_uuid]['status'] = snap.get_status()
|
|
||||||
|
|
||||||
result = sorted(logs.values(), key=lambda d: d['created'])
|
|
||||||
result.reverse()
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class SnapshotDetailView(GenericMixin):
|
class SnapshotDetailView(GenericMixin):
|
||||||
|
@ -1344,10 +1350,17 @@ class PlaceholderLogListView(GenericMixin):
|
||||||
return flask.render_template(self.template_name, **self.context)
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
def get_placeholders_log(self):
|
def get_placeholders_log(self):
|
||||||
|
page = int(request.args.get('page', 1))
|
||||||
|
per_page = int(request.args.get('per_page', PER_PAGE))
|
||||||
|
|
||||||
placeholder_log = PlaceholdersLog.query.filter(
|
placeholder_log = PlaceholdersLog.query.filter(
|
||||||
PlaceholdersLog.owner == g.user
|
PlaceholdersLog.owner == g.user
|
||||||
).order_by(PlaceholdersLog.created.desc())
|
).order_by(PlaceholdersLog.created.desc())
|
||||||
|
|
||||||
|
placeholder_log = placeholder_log.paginate(page=page, per_page=per_page)
|
||||||
|
placeholder_log.first = per_page * placeholder_log.page - per_page + 1
|
||||||
|
placeholder_log.last = len(placeholder_log.items) + placeholder_log.first - 1
|
||||||
|
|
||||||
return placeholder_log
|
return placeholder_log
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from contextlib import suppress
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
from math import hypot
|
from math import hypot
|
||||||
from typing import Iterator, List, Optional, Type, TypeVar
|
from typing import Iterator, List, Optional, TypeVar
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
from ereuse_utils import getter, text
|
from ereuse_utils import getter, text
|
||||||
|
@ -404,7 +404,7 @@ class Computer(Device):
|
||||||
chassis value.
|
chassis value.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
COMPONENTS = list(Component.__subclasses__()) # type: List[Type[Component]]
|
COMPONENTS = list(Component.__subclasses__())
|
||||||
COMPONENTS.remove(Motherboard)
|
COMPONENTS.remove(Motherboard)
|
||||||
|
|
||||||
def __init__(self, node: dict) -> None:
|
def __init__(self, node: dict) -> None:
|
||||||
|
|
|
@ -78,6 +78,12 @@ class SnapshotsLog(Thing):
|
||||||
snapshots.append(s)
|
snapshots.append(s)
|
||||||
return snapshots and 'Update' or 'New Device'
|
return snapshots and 'Update' or 'New Device'
|
||||||
|
|
||||||
|
def get_system_uuid(self):
|
||||||
|
try:
|
||||||
|
return self.snapshot.device.system_uuid or ''
|
||||||
|
except AttributeError:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
class PlaceholdersLog(Thing):
|
class PlaceholdersLog(Thing):
|
||||||
"""A Placeholder log."""
|
"""A Placeholder log."""
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from ereuse_workbench.computer import Component, Computer, DataStorage
|
from ereuse_workbench.computer import Computer, DataStorage
|
||||||
from ereuse_workbench.utils import Dumpeable
|
from ereuse_workbench.utils import Dumpeable
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,8 +23,8 @@ class Snapshot(Dumpeable):
|
||||||
self.endTime = datetime.now(timezone.utc)
|
self.endTime = datetime.now(timezone.utc)
|
||||||
self.closed = False
|
self.closed = False
|
||||||
self.elapsed = None
|
self.elapsed = None
|
||||||
self.device = None # type: Computer
|
self.device = None
|
||||||
self.components = None # type: List[Component]
|
self.components = None
|
||||||
self._storages = None
|
self._storages = None
|
||||||
|
|
||||||
def computer(self):
|
def computer(self):
|
||||||
|
|
|
@ -632,6 +632,14 @@ class Device(Thing):
|
||||||
return self.binding.device.devicehub_id
|
return self.binding.device.devicehub_id
|
||||||
return self.devicehub_id
|
return self.devicehub_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def my_partner(self):
|
||||||
|
if self.placeholder and self.placeholder.binding:
|
||||||
|
return self.placeholder.binding
|
||||||
|
if self.binding:
|
||||||
|
return self.binding.device
|
||||||
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def get_updated(self):
|
def get_updated(self):
|
||||||
if self.placeholder and self.placeholder.binding:
|
if self.placeholder and self.placeholder.binding:
|
||||||
|
|
|
@ -335,6 +335,8 @@
|
||||||
{% for f in form_filter %}
|
{% for f in form_filter %}
|
||||||
{{ f }}
|
{{ f }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<input type="hidden" class="d-none" value="1" name="page" />
|
||||||
|
<input type="hidden" class="d-none" value="{{ devices.per_page }}" name="per_page" />
|
||||||
<input type="submit" class="ms-2 btn btn-primary" value="Filter" />
|
<input type="submit" class="ms-2 btn btn-primary" value="Filter" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -344,6 +346,38 @@
|
||||||
<em>{{ form_filter.filter.data or "Computer" }}</em>
|
<em>{{ form_filter.filter.data or "Computer" }}</em>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div class="dataTable-top" style="float: left;">
|
||||||
|
<div class="dataTable-dropdown">
|
||||||
|
<label>
|
||||||
|
<select class="dataTable-selector">
|
||||||
|
<option value="5"{% if devices.per_page == 5 %} selected="selected"{% endif %}>
|
||||||
|
5
|
||||||
|
</option>
|
||||||
|
<option value="10"{% if devices.per_page == 10 %} selected="selected"{% endif %}>
|
||||||
|
10
|
||||||
|
</option>
|
||||||
|
<option value="15"{% if devices.per_page == 15 %} selected="selected"{% endif %}>
|
||||||
|
15
|
||||||
|
</option>
|
||||||
|
<option value="20"{% if devices.per_page == 20 %} selected="selected"{% endif %}>
|
||||||
|
20
|
||||||
|
</option>
|
||||||
|
<option value="25"{% if devices.per_page == 25 %} selected="selected"{% endif %}>
|
||||||
|
25
|
||||||
|
</option>
|
||||||
|
<option value="50"{% if devices.per_page == 50 %} selected="selected"{% endif %}>
|
||||||
|
50
|
||||||
|
</option>
|
||||||
|
<option value="100"{% if devices.per_page == 100 %} selected="selected"{% endif %}>
|
||||||
|
100
|
||||||
|
</option>
|
||||||
|
</select> entries per page
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-search">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-container">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -362,7 +396,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for dev in devices %}
|
{% for dev in devices.items %}
|
||||||
{% if dev.placeholder and (not dev.parent_id or dev.parent.placeholder.kangaroo) %}
|
{% if dev.placeholder and (not dev.parent_id or dev.parent.placeholder.kangaroo) %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
@ -421,6 +455,57 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div class="dataTable-bottom">
|
||||||
|
<div class="dataTable-info">
|
||||||
|
Showing {{ devices.first }} to {{ devices.last }} of {{ devices.total }} entries
|
||||||
|
</div>
|
||||||
|
<nav class="dataTable-pagination">
|
||||||
|
<ul class="dataTable-pagination-list">
|
||||||
|
{% if devices.has_prev %}
|
||||||
|
<li class="pager">
|
||||||
|
{% if all_devices %}
|
||||||
|
<a href="{{ url_for('inventory.alldevicelist', page=devices.prev_num, per_page=devices.per_page, filter=filter) }}">‹</a>
|
||||||
|
{% elif lot %}
|
||||||
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id, page=devices.prev_num, per_page=devices.per_page, filter=filter) }}">‹</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('inventory.devicelist', page=devices.prev_num, per_page=devices.per_page, filter=filter) }}">‹</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% for page in devices.iter_pages() %}
|
||||||
|
{% if page %}
|
||||||
|
{% if page == devices.page %}
|
||||||
|
<li class="active"><a href="javascript:void()">{{ page }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li class="">
|
||||||
|
{% if all_devices %}
|
||||||
|
<a href="{{ url_for('inventory.alldevicelist', page=page, per_page=devices.per_page, filter=filter) }}">
|
||||||
|
{% elif lot %}
|
||||||
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id, page=page, per_page=devices.per_page, filter=filter) }}">
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('inventory.devicelist', page=page, per_page=devices.per_page, filter=filter) }}">
|
||||||
|
{% endif %}
|
||||||
|
{{ page }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if devices.has_next %}
|
||||||
|
<li class="pager">
|
||||||
|
{% if all_devices %}
|
||||||
|
<a href="{{ url_for('inventory.alldevicelist', page=devices.next_num, per_page=devices.per_page, filter=filter) }}">›</a>
|
||||||
|
{% elif lot %}
|
||||||
|
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id, page=devices.next_num, per_page=devices.per_page, filter=filter) }}">›</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('inventory.devicelist', page=devices.next_num, per_page=devices.per_page, filter=filter) }}">›</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -592,10 +677,25 @@
|
||||||
{% include "inventory/alert_lots_changes.html" %}
|
{% include "inventory/alert_lots_changes.html" %}
|
||||||
|
|
||||||
<!-- Custom Code -->
|
<!-- Custom Code -->
|
||||||
|
<script>
|
||||||
|
$(document).ready(() => {
|
||||||
|
$(".dataTable-selector").on("change", function() {
|
||||||
|
const per_page = $('.dataTable-selector').val();
|
||||||
|
{% if all_devices %}
|
||||||
|
window.location.href = "{{ url_for('inventory.alldevicelist', page=1) }}&filter={{ filter }}&per_page="+per_page;
|
||||||
|
{% elif lot %}
|
||||||
|
window.location.href = "{{ url_for('inventory.lotdevicelist', lot_id=lot.id, page=1) }}&filter={{ filter }}&per_page="+per_page;
|
||||||
|
{% else %}
|
||||||
|
window.location.href = "{{ url_for('inventory.devicelist', page=1) }}&filter={{ filter }}&per_page="+per_page;
|
||||||
|
{% endif %}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<script>
|
<script>
|
||||||
let table = new simpleDatatables.DataTable("table", {
|
let table = new simpleDatatables.DataTable("table", {
|
||||||
perPageSelect: [5, 10, 15, 20, 25, 50, 100],
|
footer: false,
|
||||||
perPage: 20
|
paging: false,
|
||||||
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
{% if config['DEBUG'] %}
|
{% if config['DEBUG'] %}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('inventory.device_erasure_list') }}" class="nav-link{% if not orphans %} active{% endif %}">
|
<a href="{{ url_for('inventory.device_erasure_list') }}" class="nav-link{% if not orphans %} active{% endif %}">
|
||||||
All hard drivers
|
All hard drives
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
@ -109,7 +109,43 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<div id="select-devices-info" class="alert alert-info mb-0 mt-3 d-none" role="alert">
|
||||||
|
If this text is showing is because there are an error
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="tab-content pt-2">
|
<div class="tab-content pt-2">
|
||||||
|
<div class="dataTable-top" style="float: left;">
|
||||||
|
<div class="dataTable-dropdown">
|
||||||
|
<label>
|
||||||
|
<select class="dataTable-selector">
|
||||||
|
<option value="5"{% if erasure.per_page == 5 %} selected="selected"{% endif %}>
|
||||||
|
5
|
||||||
|
</option>
|
||||||
|
<option value="10"{% if erasure.per_page == 10 %} selected="selected"{% endif %}>
|
||||||
|
10
|
||||||
|
</option>
|
||||||
|
<option value="15"{% if erasure.per_page == 15 %} selected="selected"{% endif %}>
|
||||||
|
15
|
||||||
|
</option>
|
||||||
|
<option value="20"{% if erasure.per_page == 20 %} selected="selected"{% endif %}>
|
||||||
|
20
|
||||||
|
</option>
|
||||||
|
<option value="25"{% if erasure.per_page == 25 %} selected="selected"{% endif %}>
|
||||||
|
25
|
||||||
|
</option>
|
||||||
|
<option value="50"{% if erasure.per_page == 50 %} selected="selected"{% endif %}>
|
||||||
|
50
|
||||||
|
</option>
|
||||||
|
<option value="100"{% if erasure.per_page == 100 %} selected="selected"{% endif %}>
|
||||||
|
100
|
||||||
|
</option>
|
||||||
|
</select> entries per page
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-search">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-container">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -125,10 +161,10 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for ac in erasure %}
|
{% for ac in erasure.items %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<input type="checkbox" class="deviceSelect" data="{{ ac.device.id }}"
|
<input type="checkbox" class="deviceSelect" data="{{ ac.device.my_partner.id }}"
|
||||||
data-device-type="{{ ac.device.type }}" data-device-manufacturer="{{ ac.device.manufacturer }}"
|
data-device-type="{{ ac.device.type }}" data-device-manufacturer="{{ ac.device.manufacturer }}"
|
||||||
data-device-dhid="{{ ac.device.dhid }}" data-device-vname="{{ ac.device.verbose_name }}"
|
data-device-dhid="{{ ac.device.dhid }}" data-device-vname="{{ ac.device.verbose_name }}"
|
||||||
data-action-erasure="{{ ac.id }}"
|
data-action-erasure="{{ ac.id }}"
|
||||||
|
@ -151,9 +187,9 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ ac.device.serial_number.upper() }}
|
{{ ac.device.serial_number.upper() }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if ac.device.lots | length > 0 %}
|
{% if ac.device.my_partner.lots | length > 0 %}
|
||||||
<h6 class="d-inline">
|
<h6 class="d-inline">
|
||||||
{% for lot in ac.device.get_lots_for_template() %}
|
{% for lot in ac.device.my_partner.get_lots_for_template() %}
|
||||||
<span class="badge rounded-pill bg-light text-dark">{{ lot }}</span>
|
<span class="badge rounded-pill bg-light text-dark">{{ lot }}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</h6>
|
</h6>
|
||||||
|
@ -170,7 +206,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('inventory.export', export_id='snapshot') }}?id={{ ac.snapshot.uuid }}">
|
<a href="{{ url_for('inventory.export', export_id='snapshot') }}?id={{ ac.snapshot.uuid }}">
|
||||||
{{ ac.snapshot.uuid }}
|
{{ ac.snapshot.uuid }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -194,135 +230,54 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-bottom">
|
||||||
|
<div class="dataTable-info">
|
||||||
|
Showing {{ erasure.first }} to {{ erasure.last }} of {{ erasure.total }} entries
|
||||||
|
</div>
|
||||||
|
<nav class="dataTable-pagination">
|
||||||
|
<ul class="dataTable-pagination-list">
|
||||||
|
{% if erasure.has_prev %}
|
||||||
|
<li class="pager">
|
||||||
|
{% if orphans %}
|
||||||
|
<a href="{{ url_for('inventory.device_erasure_list_orphans', orphans=1, page=erasure.prev_num, per_page=erasure.per_page) }}">‹</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('inventory.device_erasure_list', page=erasure.prev_num, per_page=erasure.per_page) }}">‹</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% for page in erasure.iter_pages() %}
|
||||||
|
{% if page %}
|
||||||
|
{% if page == erasure.page %}
|
||||||
|
<li class="active"><a href="javascript:void()">{{ page }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li class="">
|
||||||
|
{% if orphans %}
|
||||||
|
<a href="{{ url_for('inventory.device_erasure_list_orphans', orphans=1, page=page, per_page=erasure.per_page) }}">
|
||||||
|
{{ page }}
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('inventory.device_erasure_list', page=page, per_page=erasure.per_page) }}">
|
||||||
|
{{ page }}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if erasure.has_next %}
|
||||||
|
<li class="pager">
|
||||||
|
{% if orphans %}
|
||||||
|
<a href="{{ url_for('inventory.device_erasure_list_orphans', orphans=1, page=erasure.next_num, per_page=erasure.per_page) }}">›</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('inventory.device_erasure_list', page=erasure.next_num, per_page=erasure.per_page) }}">›</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if lot and not lot.is_temporary %}
|
|
||||||
<div id="trade-documents-list" class="tab-pane fade trade-documents-list">
|
|
||||||
<h5 class="card-title">Documents</h5>
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">File</th>
|
|
||||||
<th scope="col" data-type="date" data-format="DD-MM-YYYY">Uploaded on</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for doc in lot.trade.documents %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{% if doc.url %}
|
|
||||||
<a href="{{ doc.url.to_text() }}" target="_blank">{{ doc.file_name}}</a>
|
|
||||||
{% else %}
|
|
||||||
{{ doc.file_name}}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ doc.created.strftime('%H:%M %d-%m-%Y')}}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div id="edit-transfer" class="tab-pane fade edit-transfer">
|
|
||||||
<h5 class="card-title">Transfer</h5>
|
|
||||||
<form method="post" action="{{ url_for('inventory.edit_transfer', lot_id=lot.id) }}" class="row g-3 needs-validation" novalidate>
|
|
||||||
{{ form_transfer.csrf_token }}
|
|
||||||
|
|
||||||
{% for field in form_transfer %}
|
|
||||||
{% if field != form_transfer.csrf_token %}
|
|
||||||
<div class="col-12">
|
|
||||||
{% if field != form_transfer.type %}
|
|
||||||
{{ field.label(class_="form-label") }}
|
|
||||||
{% if field == form_transfer.code %}
|
|
||||||
<span class="text-danger">*</span>
|
|
||||||
{% endif %}
|
|
||||||
{{ field }}
|
|
||||||
<small class="text-muted">{{ field.description }}</small>
|
|
||||||
{% if field.errors %}
|
|
||||||
<p class="text-danger">
|
|
||||||
{% for error in field.errors %}
|
|
||||||
{{ error }}<br/>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}" class="btn btn-danger">Cancel</a>
|
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div id="edit-delivery-note" class="tab-pane fade edit-delivery-note">
|
|
||||||
<h5 class="card-title">Delivery Note</h5>
|
|
||||||
<form method="post" action="{{ url_for('inventory.delivery_note', lot_id=lot.id) }}" class="row g-3 needs-validation" novalidate>
|
|
||||||
{{ form_delivery.csrf_token }}
|
|
||||||
|
|
||||||
{% for field in form_delivery %}
|
|
||||||
{% if field != form_delivery.csrf_token %}
|
|
||||||
<div class="col-12">
|
|
||||||
{% if field != form_delivery.type %}
|
|
||||||
{{ field.label(class_="form-label") }}
|
|
||||||
{{ field }}
|
|
||||||
<small class="text-muted">{{ field.description }}</small>
|
|
||||||
{% if field.errors %}
|
|
||||||
<p class="text-danger">
|
|
||||||
{% for error in field.errors %}
|
|
||||||
{{ error }}<br/>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if lot.transfer and form_receiver.is_editable() %}
|
|
||||||
<div>
|
|
||||||
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}" class="btn btn-danger">Cancel</a>
|
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div id="edit-receiver-note" class="tab-pane fade edit-receiver-note">
|
|
||||||
<h5 class="card-title">Receiver Note</h5>
|
|
||||||
<form method="post" action="{{ url_for('inventory.receiver_note', lot_id=lot.id) }}" class="row g-3 needs-validation" novalidate>
|
|
||||||
{{ form_receiver.csrf_token }}
|
|
||||||
|
|
||||||
{% for field in form_receiver %}
|
|
||||||
{% if field != form_receiver.csrf_token %}
|
|
||||||
<div class="col-12">
|
|
||||||
{% if field != form_receiver.type %}
|
|
||||||
{{ field.label(class_="form-label") }}
|
|
||||||
{{ field }}
|
|
||||||
<small class="text-muted">{{ field.description }}</small>
|
|
||||||
{% if field.errors %}
|
|
||||||
<p class="text-danger">
|
|
||||||
{% for error in field.errors %}
|
|
||||||
{{ error }}<br/>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if lot.transfer and form_receiver.is_editable() %}
|
|
||||||
<div>
|
|
||||||
<a href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}" class="btn btn-danger">Cancel</a>
|
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div><!-- End Bordered Tabs -->
|
</div><!-- End Bordered Tabs -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -334,21 +289,32 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% include "inventory/lot_delete_modal.html" %}
|
|
||||||
{% include "inventory/actions.html" %}
|
|
||||||
{% include "inventory/allocate.html" %}
|
|
||||||
{% include "inventory/data_wipe.html" %}
|
|
||||||
{% include "inventory/trade.html" %}
|
|
||||||
{% include "inventory/alert_export_error.html" %}
|
{% include "inventory/alert_export_error.html" %}
|
||||||
{% include "inventory/alert_lots_changes.html" %}
|
{% include "inventory/alert_lots_changes.html" %}
|
||||||
|
|
||||||
<!-- Custom Code -->
|
<!-- Custom Code -->
|
||||||
|
<script>
|
||||||
|
$(document).ready(() => {
|
||||||
|
$(".dataTable-selector").on("change", function() {
|
||||||
|
const per_page = $('.dataTable-selector').val();
|
||||||
|
{% if orphans %}
|
||||||
|
window.location.href = "{{ url_for('inventory.device_erasure_list_orphans', orphans=1, page=1) }}&per_page="+per_page;
|
||||||
|
{% else %}
|
||||||
|
window.location.href = "{{ url_for('inventory.device_erasure_list', page=1) }}&per_page="+per_page;
|
||||||
|
{% endif %}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<script>
|
<script>
|
||||||
let table = new simpleDatatables.DataTable("table", {
|
let table = new simpleDatatables.DataTable("table", {
|
||||||
perPageSelect: [5, 10, 15, 20, 25, 50, 100],
|
//perPageSelect: [5, 10, 15, 20, 25, 50, 100],
|
||||||
perPage: 20
|
//perPage: 20,
|
||||||
|
footer: false,
|
||||||
|
paging: false,
|
||||||
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% if config['DEBUG'] %}
|
{% if config['DEBUG'] %}
|
||||||
<script src="{{ url_for('static', filename='js/main_inventory.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/main_inventory.js') }}"></script>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -22,6 +22,38 @@
|
||||||
<div class="tab-content pt-5">
|
<div class="tab-content pt-5">
|
||||||
<div id="devices-list" class="tab-pane fade devices-list active show">
|
<div id="devices-list" class="tab-pane fade devices-list active show">
|
||||||
<div class="tab-content pt-2">
|
<div class="tab-content pt-2">
|
||||||
|
<div class="dataTable-top" style="float: left;">
|
||||||
|
<div class="dataTable-dropdown">
|
||||||
|
<label>
|
||||||
|
<select class="dataTable-selector">
|
||||||
|
<option value="5"{% if placeholders_log.per_page == 5 %} selected="selected"{% endif %}>
|
||||||
|
5
|
||||||
|
</option>
|
||||||
|
<option value="10"{% if placeholders_log.per_page == 10 %} selected="selected"{% endif %}>
|
||||||
|
10
|
||||||
|
</option>
|
||||||
|
<option value="15"{% if placeholders_log.per_page == 15 %} selected="selected"{% endif %}>
|
||||||
|
15
|
||||||
|
</option>
|
||||||
|
<option value="20"{% if placeholders_log.per_page == 20 %} selected="selected"{% endif %}>
|
||||||
|
20
|
||||||
|
</option>
|
||||||
|
<option value="25"{% if placeholders_log.per_page == 25 %} selected="selected"{% endif %}>
|
||||||
|
25
|
||||||
|
</option>
|
||||||
|
<option value="50"{% if placeholders_log.per_page == 50 %} selected="selected"{% endif %}>
|
||||||
|
50
|
||||||
|
</option>
|
||||||
|
<option value="100"{% if placeholders_log.per_page == 100 %} selected="selected"{% endif %}>
|
||||||
|
100
|
||||||
|
</option>
|
||||||
|
</select> entries per page
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-search">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-container">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -34,7 +66,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for log in placeholders_log %}
|
{% for log in placeholders_log.items %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{ log.phid }}
|
{{ log.phid }}
|
||||||
|
@ -58,6 +90,38 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div class="dataTable-bottom">
|
||||||
|
<div class="dataTable-info">
|
||||||
|
Showing {{ placeholders_log.first }} to {{ placeholders_log.last }} of {{ placeholders_log.total }} entries
|
||||||
|
</div>
|
||||||
|
<nav class="dataTable-pagination">
|
||||||
|
<ul class="dataTable-pagination-list">
|
||||||
|
{% if placeholders_log.has_prev %}
|
||||||
|
<li class="pager">
|
||||||
|
<a href="{{ url_for('inventory.placeholder_logs', page=placeholders_log.prev_num, per_page=placeholders_log.per_page) }}">‹</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% for page in placeholders_log.iter_pages() %}
|
||||||
|
{% if page %}
|
||||||
|
{% if page == placeholders_log.page %}
|
||||||
|
<li class="active"><a href="javascript:void()">{{ page }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li class="">
|
||||||
|
<a href="{{ url_for('inventory.placeholder_logs', page=page, per_page=placeholders_log.per_page) }}">
|
||||||
|
{{ page }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if placeholders_log.has_next %}
|
||||||
|
<li class="pager">
|
||||||
|
<a href="{{ url_for('inventory.placeholder_logs', page=placeholders_log.next_num, per_page=placeholders_log.per_page) }}">›</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,6 +139,18 @@
|
||||||
|
|
||||||
<!-- Custom Code -->
|
<!-- Custom Code -->
|
||||||
<script>
|
<script>
|
||||||
const table = new simpleDatatables.DataTable("table")
|
$(document).ready(() => {
|
||||||
|
$(".dataTable-selector").on("change", function() {
|
||||||
|
const per_page = $('.dataTable-selector').val();
|
||||||
|
window.location.href = "{{ url_for('inventory.placeholder_logs', page=1) }}&per_page="+per_page;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
let table = new simpleDatatables.DataTable("table", {
|
||||||
|
footer: false,
|
||||||
|
paging: false,
|
||||||
|
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock main %}
|
{% endblock main %}
|
||||||
|
|
|
@ -22,6 +22,38 @@
|
||||||
<div class="tab-content pt-5">
|
<div class="tab-content pt-5">
|
||||||
<div id="devices-list" class="tab-pane fade devices-list active show">
|
<div id="devices-list" class="tab-pane fade devices-list active show">
|
||||||
<div class="tab-content pt-2">
|
<div class="tab-content pt-2">
|
||||||
|
<div class="dataTable-top" style="float: left;">
|
||||||
|
<div class="dataTable-dropdown">
|
||||||
|
<label>
|
||||||
|
<select class="dataTable-selector">
|
||||||
|
<option value="5"{% if snapshots_log.per_page == 5 %} selected="selected"{% endif %}>
|
||||||
|
5
|
||||||
|
</option>
|
||||||
|
<option value="10"{% if snapshots_log.per_page == 10 %} selected="selected"{% endif %}>
|
||||||
|
10
|
||||||
|
</option>
|
||||||
|
<option value="15"{% if snapshots_log.per_page == 15 %} selected="selected"{% endif %}>
|
||||||
|
15
|
||||||
|
</option>
|
||||||
|
<option value="20"{% if snapshots_log.per_page == 20 %} selected="selected"{% endif %}>
|
||||||
|
20
|
||||||
|
</option>
|
||||||
|
<option value="25"{% if snapshots_log.per_page == 25 %} selected="selected"{% endif %}>
|
||||||
|
25
|
||||||
|
</option>
|
||||||
|
<option value="50"{% if snapshots_log.per_page == 50 %} selected="selected"{% endif %}>
|
||||||
|
50
|
||||||
|
</option>
|
||||||
|
<option value="100"{% if snapshots_log.per_page == 100 %} selected="selected"{% endif %}>
|
||||||
|
100
|
||||||
|
</option>
|
||||||
|
</select> entries per page
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-search">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dataTable-container">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -39,7 +71,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for snap in snapshots_log %}
|
{% for snap in snapshots_log.items %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{% if snap.sid and snap.snapshot_uuid %}
|
{% if snap.sid and snap.snapshot_uuid %}
|
||||||
|
@ -59,26 +91,26 @@
|
||||||
{{ snap.version }}
|
{{ snap.version }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if snap.device %}
|
{% if snap.get_device() %}
|
||||||
<a href="{{ url_for('inventory.device_details', id=snap.device) }}">
|
<a href="{{ url_for('inventory.device_details', id=snap.device) }}">
|
||||||
{{ snap.device }}
|
{{ snap.get_device() }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ snap.system_uuid }}
|
{{ snap.get_system_uuid() }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ snap.status }}
|
{{ snap.get_status() }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ snap.new_device }}
|
{{ snap.get_new_device() }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ snap.type_device }}
|
{{ snap.get_type_device() }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ snap.original_dhid }}
|
{{ snap.get_original_dhid() }}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ snap.created.strftime('%Y-%m-%d %H:%M') }}</td>
|
<td>{{ snap.created.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -93,6 +125,38 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div class="dataTable-bottom">
|
||||||
|
<div class="dataTable-info">
|
||||||
|
Showing {{ snapshots_log.first }} to {{ snapshots_log.last }} of {{ snapshots_log.total }} entries
|
||||||
|
</div>
|
||||||
|
<nav class="dataTable-pagination">
|
||||||
|
<ul class="dataTable-pagination-list">
|
||||||
|
{% if snapshots_log.has_prev %}
|
||||||
|
<li class="pager">
|
||||||
|
<a href="{{ url_for('inventory.snapshotslist', page=snapshots_log.prev_num, per_page=snapshots_log.per_page) }}">‹</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% for page in snapshots_log.iter_pages() %}
|
||||||
|
{% if page %}
|
||||||
|
{% if page == snapshots_log.page %}
|
||||||
|
<li class="active"><a href="javascript:void()">{{ page }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li class="">
|
||||||
|
<a href="{{ url_for('inventory.snapshotslist', page=page, per_page=snapshots_log.per_page) }}">
|
||||||
|
{{ page }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if snapshots_log.has_next %}
|
||||||
|
<li class="pager">
|
||||||
|
<a href="{{ url_for('inventory.snapshotslist', page=snapshots_log.next_num, per_page=snapshots_log.per_page) }}">›</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -109,6 +173,18 @@
|
||||||
|
|
||||||
<!-- Custom Code -->
|
<!-- Custom Code -->
|
||||||
<script>
|
<script>
|
||||||
const table = new simpleDatatables.DataTable("table")
|
$(document).ready(() => {
|
||||||
|
$(".dataTable-selector").on("change", function() {
|
||||||
|
const per_page = $('.dataTable-selector').val();
|
||||||
|
window.location.href = "{{ url_for('inventory.snapshotslist', page=1) }}&per_page="+per_page;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
let table = new simpleDatatables.DataTable("table", {
|
||||||
|
footer: false,
|
||||||
|
paging: false,
|
||||||
|
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock main %}
|
{% endblock main %}
|
||||||
|
|
|
@ -2368,6 +2368,9 @@ def test_upload_snapshot_smartphone(user3: UserClientFlask):
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_list_erasures(user3: UserClientFlask):
|
def test_list_erasures(user3: UserClientFlask):
|
||||||
|
from flask import current_app as app
|
||||||
|
|
||||||
|
app.config['SCHEMA'] = 'test'
|
||||||
uri = '/inventory/upload-snapshot/'
|
uri = '/inventory/upload-snapshot/'
|
||||||
file_name = 'erase-sectors-2-hdd.snapshot.yaml'
|
file_name = 'erase-sectors-2-hdd.snapshot.yaml'
|
||||||
body, status = user3.get(uri)
|
body, status = user3.get(uri)
|
||||||
|
|
Reference in New Issue