diff --git a/src/webui/service/device/routes.py b/src/webui/service/device/routes.py index 110a19b402da15697a903e80729c52a118031ba0..ce15c7abaa527191e87dcaeee5b91599014c1e72 100644 --- a/src/webui/service/device/routes.py +++ b/src/webui/service/device/routes.py @@ -149,6 +149,16 @@ def detail(device_uuid: str): return render_template( 'device/detail.html', device=device_obj, dde=DeviceDriverEnum, dose=DeviceOperationalStatusEnum) + +@device.route('inventory/<path:device_uuid>', methods=['GET', 'POST']) +def inventory(device_uuid: str): + context_client.connect() + device_obj = get_device(context_client, device_uuid, rw_copy=False) + if device_obj is None: + flash('Device({:s}) not found'.format(str(device_uuid)), 'danger') + device_obj = Device() + context_client.close() + return render_template('device/inventory.html', device=device_obj) @device.get('<path:device_uuid>/delete') def delete(device_uuid): diff --git a/src/webui/service/templates/device/detail.html b/src/webui/service/templates/device/detail.html index b02be6f4d4f6c975c4ebf3528bc6770ae25e6702..a9c069ac3a526af46392ffd2f23205a7604dbb7d 100644 --- a/src/webui/service/templates/device/detail.html +++ b/src/webui/service/templates/device/detail.html @@ -86,42 +86,6 @@ </tbody> </table> </div> - {% if device.components|length > 0 %} - <div class="col-sm-8"> - <table class="table table-striped table-hover"> - <thead> - <tr> - <th scope="col">Component UUID</th> - <th scope="col">Name</th> - <th scope="col">Type</th> - <th scope="col">Parent</th> - <th scope="col">Attributes</th> - </tr> - </thead> - <tbody> - {% for component in device.components %} - <tr> - <td> - {{ component.component_uuid.uuid }} - </td> - <td> - {{ component.name }} - </td> - <td> - {{ component.type }} - </td> - <td> - {{ component.parent }} - </td> - <td> - {{ component.attributes }} - </td> - </tr> - {% endfor %} - </tbody> - </table> - </div> - {% endif %} </div> <b>Configurations:</b> diff --git a/src/webui/service/templates/device/home.html b/src/webui/service/templates/device/home.html index 53434196f85c3a8c79fe9b861204e9bd8c6a5d8f..e356fd4fbeccc6e735d9723b8b1ca3e5fcf865ec 100644 --- a/src/webui/service/templates/device/home.html +++ b/src/webui/service/templates/device/home.html @@ -50,6 +50,7 @@ <th scope="col">Status</th> <th scope="col">Config Rules</th> <th scope="col"></th> + <th scope="col"></th> </tr> </thead> <tbody> @@ -74,6 +75,14 @@ </svg> </a> </td> + <td> + <a href="{{ url_for('device.inventory', device_uuid=device.device_id.device_uuid.uuid) }}"> + <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pci-card" viewBox="0 0 16 16"> + <path d="M0 1.5A.5.5 0 0 1 .5 1h1a.5.5 0 0 1 .5.5V4h13.5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-.5.5H2v2.5a.5.5 0 0 1-1 0V2H.5a.5.5 0 0 1-.5-.5Z"/> + <path d="M3 12.5h3.5v1a.5.5 0 0 1-.5.5H3.5a.5.5 0 0 1-.5-.5v-1Zm4 0h4v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1Z"/> + </svg> + </a> + </td> </tr> {% endfor %} {% else %} diff --git a/src/webui/service/templates/device/inventory.html b/src/webui/service/templates/device/inventory.html new file mode 100644 index 0000000000000000000000000000000000000000..17c14785a89658b59e07373bc7d939e234937631 --- /dev/null +++ b/src/webui/service/templates/device/inventory.html @@ -0,0 +1,151 @@ +<!-- + Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +{% extends 'base.html' %} + +{% block content %} +<style> + ul, + #myUL { + list-style-type: none; + } + + #myUL { + margin: 0; + padding: 0; + } + + .caret { + cursor: pointer; + -webkit-user-select: none; + /* Safari 3.1+ */ + -moz-user-select: none; + /* Firefox 2+ */ + -ms-user-select: none; + /* IE 10+ */ + user-select: none; + } + + .caret::before { + content: "\25B6"; + color: black; + display: inline-block; + margin-right: 6px; + } + + .caret-down::before { + -ms-transform: rotate(90deg); + /* IE 9 */ + -webkit-transform: rotate(90deg); + /* Safari */ + transform: rotate(90deg); + } + + .nested { + display: none; + } + + .active { + display: block; + } +</style> + +<h1>Device {{ device.name }} ({{ device.device_id.device_uuid.uuid }})</h1> + +<div class="row mb-3"> + <div class="col-sm-3"> + <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('device.home') }}'"> + <i class="bi bi-box-arrow-in-left"></i> + Back to device list + </button> + </div> +</div> + +<br> +<div class="row mb-3"> + <div class="col-sm-3"> + <ul id="myUL"> + <li><span class="caret"></span>Components</span> + <ul class="nested"> + {% for item in (device.components|sort(true, attribute='name')) %} + {% if item.parent |length < 1 or item.type=='CHASSIS' %} + <li><span class="caret"></span>{{item.name}}</span> + <ul class="nested"> + {% for comp in (device.components|sort(true, attribute='name')) %} + {% if item.name == comp.parent %} + <li>{{comp.name}}</li> + {% endif %} + {% endfor %} + </ul> + </li> + {% endif %} + {% endfor %} + </ul> + </li> + </ul> + + <script> + var toggler = document.getElementsByClassName("caret"); + var i; + + for (i = 0; i < toggler.length; i++) { + toggler[i].addEventListener("click", function() { + this.parentElement.querySelector(".nested").classList.toggle("active"); + this.classList.toggle("caret-down"); + }); + } + </script> + + </div> + {% if device.components|length > 1 %} + <div class="col-sm-8"> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th scope="col">Component UUID</th> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col">Parent</th> + <th scope="col">Attributes</th> + </tr> + </thead> + <tbody> + {% for component in (device.components|sort(true, attribute='name')) %} + <tr> + <td> + {{ component.component_uuid.uuid }} + </td> + <td> + {{ component.name }} + </td> + <td> + {{ component.type }} + </td> + <td> + {{ component.parent }} + </td> + <td> + {{ component.attributes }} + </td> + </tr> + {% endfor %} + </tbody> + </table> + </div> + {% endif %} +</div> + +{% endblock %}