add manual binding
This commit is contained in:
parent
d008bb2921
commit
497e29a2da
|
@ -455,7 +455,7 @@ class NewDeviceForm(FlaskForm):
|
||||||
|
|
||||||
if self.phid.data and self.amount.data == 1 and not self._obj:
|
if self.phid.data and self.amount.data == 1 and not self._obj:
|
||||||
dev = Placeholder.query.filter(
|
dev = Placeholder.query.filter(
|
||||||
Placeholder.phid == self.phid.data, Device.owner == g.user
|
Placeholder.phid == self.phid.data, Placeholder.owner == g.user
|
||||||
).first()
|
).first()
|
||||||
if dev:
|
if dev:
|
||||||
msg = "Sorry, exist one snapshot device with this HID"
|
msg = "Sorry, exist one snapshot device with this HID"
|
||||||
|
@ -568,6 +568,7 @@ class NewDeviceForm(FlaskForm):
|
||||||
'id_device_supplier': self.id_device_supplier.data,
|
'id_device_supplier': self.id_device_supplier.data,
|
||||||
'info': self.info.data,
|
'info': self.info.data,
|
||||||
'pallet': self.pallet.data,
|
'pallet': self.pallet.data,
|
||||||
|
'is_abstract': False,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return self.placeholder
|
return self.placeholder
|
||||||
|
@ -577,6 +578,7 @@ class NewDeviceForm(FlaskForm):
|
||||||
self._obj.placeholder.id_device_supplier = self.id_device_supplier.data or None
|
self._obj.placeholder.id_device_supplier = self.id_device_supplier.data or None
|
||||||
self._obj.placeholder.info = self.info.data or None
|
self._obj.placeholder.info = self.info.data or None
|
||||||
self._obj.placeholder.pallet = self.pallet.data or None
|
self._obj.placeholder.pallet = self.pallet.data or None
|
||||||
|
self._obj.placeholder.is_abstract = False
|
||||||
self._obj.model = self.model.data
|
self._obj.model = self.model.data
|
||||||
self._obj.manufacturer = self.manufacturer.data
|
self._obj.manufacturer = self.manufacturer.data
|
||||||
self._obj.serial_number = self.serial_number.data
|
self._obj.serial_number = self.serial_number.data
|
||||||
|
@ -1555,6 +1557,7 @@ class UploadPlaceholderForm(FlaskForm):
|
||||||
'id_device_supplier': data['Id device Supplier'][i],
|
'id_device_supplier': data['Id device Supplier'][i],
|
||||||
'pallet': data['Pallet'][i],
|
'pallet': data['Pallet'][i],
|
||||||
'info': data['Info'][i],
|
'info': data['Info'][i],
|
||||||
|
'is_abstract': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot_json = schema.load(json_snapshot)
|
snapshot_json = schema.load(json_snapshot)
|
||||||
|
@ -1606,3 +1609,42 @@ class EditPlaceholderForm(FlaskForm):
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return self.placeholders
|
return self.placeholders
|
||||||
|
|
||||||
|
|
||||||
|
class BindingForm(FlaskForm):
|
||||||
|
phid = StringField('Phid', [validators.DataRequired()])
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.device = kwargs.pop('device', None)
|
||||||
|
self.placeholder = kwargs.pop('placeholder', None)
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def validate(self, extra_validators=None):
|
||||||
|
is_valid = super().validate(extra_validators)
|
||||||
|
|
||||||
|
if not is_valid:
|
||||||
|
txt = "This placeholder not exist."
|
||||||
|
self.phid.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self.device.placeholder:
|
||||||
|
txt = "This is not a device Workbench."
|
||||||
|
self.phid.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not self.placeholder:
|
||||||
|
self.placeholder = Placeholder.query.filter(
|
||||||
|
Placeholder.phid == self.phid.data, Placeholder.owner == g.user
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if not self.placeholder:
|
||||||
|
txt = "This placeholder not exist."
|
||||||
|
self.phid.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self.placeholder.binding:
|
||||||
|
txt = "This placeholder have a binding with other device. Before you need to do an unbinding with this other device."
|
||||||
|
self.phid.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
|
@ -19,6 +19,7 @@ from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.inventory.forms import (
|
from ereuse_devicehub.inventory.forms import (
|
||||||
AdvancedSearchForm,
|
AdvancedSearchForm,
|
||||||
AllocateForm,
|
AllocateForm,
|
||||||
|
BindingForm,
|
||||||
DataWipeForm,
|
DataWipeForm,
|
||||||
EditTransferForm,
|
EditTransferForm,
|
||||||
FilterForm,
|
FilterForm,
|
||||||
|
@ -36,7 +37,12 @@ from ereuse_devicehub.inventory.forms import (
|
||||||
from ereuse_devicehub.labels.forms import PrintLabelsForm
|
from ereuse_devicehub.labels.forms import PrintLabelsForm
|
||||||
from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog
|
from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog
|
||||||
from ereuse_devicehub.resources.action.models import Trade
|
from ereuse_devicehub.resources.action.models import Trade
|
||||||
from ereuse_devicehub.resources.device.models import Computer, DataStorage, Device
|
from ereuse_devicehub.resources.device.models import (
|
||||||
|
Computer,
|
||||||
|
DataStorage,
|
||||||
|
Device,
|
||||||
|
Placeholder,
|
||||||
|
)
|
||||||
from ereuse_devicehub.resources.documents.device_row import ActionRow, DeviceRow
|
from ereuse_devicehub.resources.documents.device_row import ActionRow, DeviceRow
|
||||||
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
||||||
from ereuse_devicehub.resources.hash_reports import insert_hash
|
from ereuse_devicehub.resources.hash_reports import insert_hash
|
||||||
|
@ -129,6 +135,7 @@ class AdvancedSearchView(DeviceListMixin):
|
||||||
|
|
||||||
|
|
||||||
class DeviceDetailView(GenericMixin):
|
class DeviceDetailView(GenericMixin):
|
||||||
|
methods = ['GET', 'POST']
|
||||||
decorators = [login_required]
|
decorators = [login_required]
|
||||||
template_name = 'inventory/device_detail.html'
|
template_name = 'inventory/device_detail.html'
|
||||||
|
|
||||||
|
@ -140,13 +147,73 @@ class DeviceDetailView(GenericMixin):
|
||||||
.one()
|
.one()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
form_binding = BindingForm(device=device)
|
||||||
|
|
||||||
self.context.update(
|
self.context.update(
|
||||||
{
|
{
|
||||||
'device': device,
|
'device': device,
|
||||||
'placeholder': device.binding or device.placeholder,
|
'placeholder': device.binding or device.placeholder,
|
||||||
'page_title': 'Device {}'.format(device.devicehub_id),
|
'page_title': 'Device {}'.format(device.devicehub_id),
|
||||||
|
'form_binding': form_binding,
|
||||||
|
'active_binding': False,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if form_binding.validate_on_submit():
|
||||||
|
next_url = url_for(
|
||||||
|
'inventory.binding',
|
||||||
|
dhid=form_binding.device.devicehub_id,
|
||||||
|
phid=form_binding.placeholder.phid,
|
||||||
|
)
|
||||||
|
return flask.redirect(next_url)
|
||||||
|
elif form_binding.phid.data:
|
||||||
|
self.context['active_binding'] = True
|
||||||
|
|
||||||
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
|
|
||||||
|
class BindingView(GenericMixin):
|
||||||
|
methods = ['GET', 'POST']
|
||||||
|
decorators = [login_required]
|
||||||
|
template_name = 'inventory/binding.html'
|
||||||
|
|
||||||
|
def dispatch_request(self, dhid, phid):
|
||||||
|
self.get_context()
|
||||||
|
device = (
|
||||||
|
Device.query.filter(Device.owner_id == g.user.id)
|
||||||
|
.filter(Device.devicehub_id == dhid)
|
||||||
|
.one()
|
||||||
|
)
|
||||||
|
placeholder = (
|
||||||
|
Placeholder.query.filter(Placeholder.owner_id == g.user.id)
|
||||||
|
.filter(Placeholder.phid == phid)
|
||||||
|
.one()
|
||||||
|
)
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
old_placeholder = device.binding
|
||||||
|
if old_placeholder.is_abstract:
|
||||||
|
for plog in PlaceholdersLog.query.filter_by(
|
||||||
|
placeholder_id=old_placeholder.id
|
||||||
|
):
|
||||||
|
db.session.delete(plog)
|
||||||
|
db.session.delete(old_placeholder)
|
||||||
|
device.binding = placeholder
|
||||||
|
db.session.commit()
|
||||||
|
next_url = url_for('inventory.device_details', id=dhid)
|
||||||
|
messages.success(
|
||||||
|
'Device "{}" bind successfully with {}!'.format(dhid, phid)
|
||||||
|
)
|
||||||
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
|
self.context.update(
|
||||||
|
{
|
||||||
|
'device': device.binding.device,
|
||||||
|
'placeholder': placeholder,
|
||||||
|
'page_title': 'Binding confirm',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return flask.render_template(self.template_name, **self.context)
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
|
|
||||||
|
@ -994,3 +1061,6 @@ devices.add_url_rule(
|
||||||
devices.add_url_rule(
|
devices.add_url_rule(
|
||||||
'/placeholder-logs/', view_func=PlaceholderLogListView.as_view('placeholder_logs')
|
'/placeholder-logs/', view_func=PlaceholderLogListView.as_view('placeholder_logs')
|
||||||
)
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/binding/<string:dhid>/<string:phid>/', view_func=BindingView.as_view('binding')
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
"""add owner to placeholder
|
||||||
|
|
||||||
|
Revision ID: d7ea9a3b2da1
|
||||||
|
Revises: 2b90b41a556a
|
||||||
|
Create Date: 2022-07-27 14:40:15.513820
|
||||||
|
|
||||||
|
"""
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import context, op
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'd7ea9a3b2da1'
|
||||||
|
down_revision = '2b90b41a556a'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_inv():
|
||||||
|
INV = context.get_x_argument(as_dictionary=True).get('inventory')
|
||||||
|
if not INV:
|
||||||
|
raise ValueError("Inventory value is not specified")
|
||||||
|
return INV
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_data():
|
||||||
|
con = op.get_bind()
|
||||||
|
sql = f"select {get_inv()}.placeholder.id, {get_inv()}.device.owner_id from {get_inv()}.placeholder"
|
||||||
|
sql += f" join {get_inv()}.device on {get_inv()}.device.id={get_inv()}.placeholder.device_id;"
|
||||||
|
|
||||||
|
for c in con.execute(sql):
|
||||||
|
id_placeholder = c.id
|
||||||
|
id_owner = c.owner_id
|
||||||
|
sql_update = f"update {get_inv()}.placeholder set owner_id='{id_owner}', is_abstract=False where id={id_placeholder};"
|
||||||
|
con.execute(sql_update)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column(
|
||||||
|
'placeholder',
|
||||||
|
sa.Column('is_abstract', sa.Boolean(), nullable=True),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
'placeholder',
|
||||||
|
sa.Column('owner_id', postgresql.UUID(), nullable=True),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"fk_placeholder_owner_id_user_id",
|
||||||
|
"placeholder",
|
||||||
|
"user",
|
||||||
|
["owner_id"],
|
||||||
|
["id"],
|
||||||
|
ondelete="SET NULL",
|
||||||
|
source_schema=f'{get_inv()}',
|
||||||
|
referent_schema='common',
|
||||||
|
)
|
||||||
|
|
||||||
|
upgrade_data()
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_constraint(
|
||||||
|
"fk_placeholder_owner_id_user_id",
|
||||||
|
"placeholder",
|
||||||
|
type_="foreignkey",
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.drop_column('placeholder', 'owner_id', schema=f'{get_inv()}')
|
||||||
|
op.drop_column('placeholder', 'is_abstract', schema=f'{get_inv()}')
|
|
@ -852,6 +852,7 @@ class Placeholder(Thing):
|
||||||
pallet.comment = "used for identification where from where is this placeholders"
|
pallet.comment = "used for identification where from where is this placeholders"
|
||||||
info = db.Column(CIText())
|
info = db.Column(CIText())
|
||||||
info.comment = "more info of placeholders"
|
info.comment = "more info of placeholders"
|
||||||
|
is_abstract = db.Column(Boolean, default=False)
|
||||||
id_device_supplier = db.Column(CIText())
|
id_device_supplier = db.Column(CIText())
|
||||||
id_device_supplier.comment = (
|
id_device_supplier.comment = (
|
||||||
"Identification used for one supplier of one placeholders"
|
"Identification used for one supplier of one placeholders"
|
||||||
|
@ -880,6 +881,13 @@ class Placeholder(Thing):
|
||||||
primaryjoin=binding_id == Device.id,
|
primaryjoin=binding_id == Device.id,
|
||||||
)
|
)
|
||||||
binding_id.comment = "binding placeholder with workbench device"
|
binding_id.comment = "binding placeholder with workbench device"
|
||||||
|
owner_id = db.Column(
|
||||||
|
UUID(as_uuid=True),
|
||||||
|
db.ForeignKey(User.id),
|
||||||
|
nullable=False,
|
||||||
|
default=lambda: g.user.id,
|
||||||
|
)
|
||||||
|
owner = db.relationship(User, primaryjoin=owner_id == User.id)
|
||||||
|
|
||||||
|
|
||||||
class Computer(Device):
|
class Computer(Device):
|
||||||
|
|
|
@ -310,11 +310,15 @@ class Sync:
|
||||||
c_placeholder = c.__class__(**c_dict)
|
c_placeholder = c.__class__(**c_dict)
|
||||||
c_placeholder.parent = dev_placeholder
|
c_placeholder.parent = dev_placeholder
|
||||||
c.parent = device
|
c.parent = device
|
||||||
component_placeholder = Placeholder(device=c_placeholder, binding=c)
|
component_placeholder = Placeholder(
|
||||||
|
device=c_placeholder, binding=c, is_abstract=True
|
||||||
|
)
|
||||||
db.session.add(c_placeholder)
|
db.session.add(c_placeholder)
|
||||||
db.session.add(component_placeholder)
|
db.session.add(component_placeholder)
|
||||||
|
|
||||||
placeholder = Placeholder(device=dev_placeholder, binding=device)
|
placeholder = Placeholder(
|
||||||
|
device=dev_placeholder, binding=device, is_abstract=True
|
||||||
|
)
|
||||||
db.session.add(dev_placeholder)
|
db.session.add(dev_placeholder)
|
||||||
db.session.add(placeholder)
|
db.session.add(placeholder)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
{% extends "ereuse_devicehub/base_site.html" %}
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
<div class="pagetitle">
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
<nav>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<!-- TODO@slamora replace with lot list URL when exists -->
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div><!-- End Page Title -->
|
||||||
|
|
||||||
|
<section class="section profile">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-12">
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<div class="pt-4 pb-2">
|
||||||
|
<h5 class="card-title text-center pb-0 fs-4">{{ title }}</h5>
|
||||||
|
<p class="text-center">Please check that the information is correct.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Basic Data</th>
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">PHID:</th>
|
||||||
|
<td class="table-success text-right">{{ placeholder.phid or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.placeholder.phid or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Manufacturer:</th>
|
||||||
|
<td class="table-success text-right">{{ placeholder.device.manufacturer or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.manufacturer or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Model:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.model or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.model or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Serial Number:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.serial_number or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.serial_number or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Brand:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.brand or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.brand or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Sku:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.sku or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.sku or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Generation:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.generation or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.generation or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Version:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.version or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.version or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Weight:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.weight or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.weight or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Width:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.width or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.width or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Height:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.height or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.height or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Depth:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.depth or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.depth or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Color:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.color or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.color or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Production date:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.production_date or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.production_date or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Variant:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.variant or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.variant or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{% if placeholder.device.components or device.components %}
|
||||||
|
<h2>Components</h2>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="table-success text-right">
|
||||||
|
{% for c in placeholder.device.components %}
|
||||||
|
* {{ c.verbose_name }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td class="table-danger">
|
||||||
|
{% for c in device.components %}
|
||||||
|
* {{ c.verbose_name }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{% if placeholder.device.actions or device.actions %}
|
||||||
|
<h2>Actions</h2>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="table-success text-right">
|
||||||
|
{% for a in placeholder.device.actions %}
|
||||||
|
* {{ a.t }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td class="table-danger">
|
||||||
|
{% for a in device.actions %}
|
||||||
|
* {{ a.t }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<form method="post">
|
||||||
|
<a href="{{ url_for('inventory.device_details', id=device.placeholder.binding.devicehub_id) }}" class="btn btn-danger">Cancel</a>
|
||||||
|
<button class="btn btn-primary" type="submit">Confirm</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xl-8">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock main %}
|
|
@ -62,10 +62,16 @@
|
||||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#components">Components</button>
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#components">Components</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
{% if device.binding %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#binding">Binding</button>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content pt-2">
|
<div class="tab-content pt-2">
|
||||||
|
|
||||||
<div class="tab-pane fade show active" id="type">
|
<div class="tab-pane fade {% if active_binding %}profile-overview{% else %}show active{% endif %}" id="type">
|
||||||
<h5 class="card-title">Details</h5>
|
<h5 class="card-title">Details</h5>
|
||||||
{% if device.placeholder %}(<a href="{{ url_for('inventory.device_edit', id=device.devicehub_id)}}">edit</a>){% endif %}
|
{% if device.placeholder %}(<a href="{{ url_for('inventory.device_edit', id=device.devicehub_id)}}">edit</a>){% endif %}
|
||||||
|
|
||||||
|
@ -216,6 +222,42 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if placeholder.binding %}
|
||||||
|
<div class="tab-pane fade {% if active_binding %}show active{% else %}profile-overview{% endif %}" id="binding">
|
||||||
|
<h5 class="card-title">Binding</h5>
|
||||||
|
<div class="list-group col-6">
|
||||||
|
<p>
|
||||||
|
Be careful, binding implies changes in the data of a device that affect its
|
||||||
|
traceability.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="list-group col-6">
|
||||||
|
<form action="{{ url_for('inventory.device_details', id=placeholder.binding.devicehub_id) }}" method="post">
|
||||||
|
{{ form_binding.csrf_token }}
|
||||||
|
{% for field in form_binding %}
|
||||||
|
{% if field != form_binding.csrf_token %}
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
{{ field.label(class_="form-label") }}:
|
||||||
|
{{ field }}
|
||||||
|
{% if field.errors %}
|
||||||
|
<p class="text-danger">
|
||||||
|
{% for error in field.errors %}
|
||||||
|
{{ error }}<br/>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<div class="col-12 mt-2">
|
||||||
|
<input type="submit" class="btn btn-primary" value="Search" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -401,6 +401,8 @@
|
||||||
<th scope="col">Select</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">PHID</th>
|
||||||
|
<th scope="col">Is Abstract</th>
|
||||||
<th scope="col">Unique Identifiers</th>
|
<th scope="col">Unique Identifiers</th>
|
||||||
<th scope="col">Lifecycle Status</th>
|
<th scope="col">Lifecycle Status</th>
|
||||||
<th scope="col">Allocated Status</th>
|
<th scope="col">Allocated Status</th>
|
||||||
|
@ -442,6 +444,12 @@
|
||||||
{{ dev.devicehub_id }}
|
{{ dev.devicehub_id }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ dev.binding and dev.binding.phid or dev.placeholder and dev.placeholder.phid or '' }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ dev.binding and dev.binding.is_abstract and '✓' or dev.placeholder and dev.placeholder.is_abstract and '✓' or '' }}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% for t in dev.tags | sort(attribute="id") %}
|
{% for t in dev.tags | sort(attribute="id") %}
|
||||||
<a href="{{ url_for('labels.label_details', id=t.id)}}">{{ t.id }}</a>
|
<a href="{{ url_for('labels.label_details', id=t.id)}}">{{ t.id }}</a>
|
||||||
|
|
Reference in New Issue