From 209c6248ac5a96f8792fb72816b1b1fc0082a7d4 Mon Sep 17 00:00:00 2001 From: Lucie Long <llong@cttc.es> Date: Tue, 13 Sep 2022 10:48:48 +0000 Subject: [PATCH] WebUI improvement: Main page: - Change page title to "ETSI TeraFlowSDN Controller" - Add slogan "Open Source for Smart Networks and Services" next to the logo (on top) - Change Logo and Icon About page: - Change title to "ETSI TeraFlowSDN Controller" - Remove link "TeraFlow H2020 webpage" and add link "ETSI Open Source Group for TeraFlowSDN" pointing to: https://tfs.etsi.org/ - Remove partners logo Service detail page : - Show correct Service Type instead of integer - Show service status - Format configurations as in device details - Format constraints as in device details - Add constraints - Format endpoints and add device uuid Service page: -Remove constraints Link detail page: -Add device uuid to the endpoints table --- src/webui/service/service/routes.py | 3 +- ...Flow SDN Logo ScreenColour with Slogan.png | Bin 0 -> 34434 bytes src/webui/service/templates/base.html | 297 +++++++++--------- src/webui/service/templates/link/detail.html | 10 +- src/webui/service/templates/main/about.html | 6 +- .../service/templates/service/detail.html | 258 +++++++++------ src/webui/service/templates/service/home.html | 10 +- 7 files changed, 317 insertions(+), 267 deletions(-) create mode 100644 src/webui/service/static/TeraFlow SDN Logo ScreenColour with Slogan.png diff --git a/src/webui/service/service/routes.py b/src/webui/service/service/routes.py index d62e28ca1..bc05daee3 100644 --- a/src/webui/service/service/routes.py +++ b/src/webui/service/service/routes.py @@ -79,7 +79,8 @@ def detail(service_uuid: str): flash('The system encountered an error and cannot show the details of this service.', 'warning') current_app.logger.exception(e) return redirect(url_for('service.home')) - return render_template('service/detail.html', service=response, connections=connections) + return render_template('service/detail.html', service=response, connections=connections,ste=ServiceTypeEnum, + sse=ServiceStatusEnum) @service.get('<path:service_uuid>/delete') diff --git a/src/webui/service/static/TeraFlow SDN Logo ScreenColour with Slogan.png b/src/webui/service/static/TeraFlow SDN Logo ScreenColour with Slogan.png new file mode 100644 index 0000000000000000000000000000000000000000..218cc713c0a2704f96371fdd2916ef16b44cf667 GIT binary patch literal 34434 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 literal 0 HcmV?d00001 diff --git a/src/webui/service/templates/base.html b/src/webui/service/templates/base.html index d314acb3d..cc245819e 100644 --- a/src/webui/service/templates/base.html +++ b/src/webui/service/templates/base.html @@ -1,160 +1,161 @@ -<!doctype html> -<!-- - Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) - 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. ---> - -<html lang="en"> - <head> - <!-- Required meta tags --> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <link rel="shortcut icon" href="https://teraflow-h2020.eu/sites/teraflow/files/public/favicon.png" type="image/png" /> - - <!-- Bootstrap CSS --> - <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-uWxY/CJNBR+1zjPWmfnSnVxwRheevXITnMqoEIeG1LJrdI0GlVs/9cVSyPYXdcSF" crossorigin="anonymous"> - <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"> - - <title>TeraFlow OFC 2022 Demo</title> - </head> - <body> - <div id="teraflow-branding" style="width: 260px; margin: 7px;"> - <a href="{{ url_for('main.home') }}" title="Home" rel="home" id="main-logo" class="site-logo site-logo-pages"> - <svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 436.3 132.1"><defs><style>.cls-1{fill:#36a9e1;}.cls-2{fill:#1d71b8;}.cls-3{fill:none;stroke-width:2.52px;}.cls-10,.cls-3,.cls-4,.cls-5,.cls-7,.cls-8,.cls-9{stroke:#0f77b6;}.cls-3,.cls-4,.cls-8{stroke-miterlimit:10;}.cls-10,.cls-4,.cls-5,.cls-7,.cls-8,.cls-9{fill:#fff;}.cls-4{stroke-width:0.73px;}.cls-5,.cls-7{stroke-miterlimit:10;}.cls-5{stroke-width:0.75px;}.cls-6{fill:#0f77b6;}.cls-7{stroke-width:0.72px;}.cls-8{stroke-width:0.7px;}.cls-9{stroke-miterlimit:10;stroke-width:0.69px;}.cls-10{stroke-miterlimit:10;stroke-width:0.7px;}</style></defs><path class="cls-1" d="M96,57V51.3h44.1V57H121v52.3h-5.9V57Z"></path><path class="cls-1" d="M168.9,95.1l4.7,2.4a26,26,0,0,1-5.3,7.3,22.27,22.27,0,0,1-6.7,4.2,22.64,22.64,0,0,1-8.5,1.4c-7,0-12.5-2.3-16.4-6.9a23.53,23.53,0,0,1-5.9-15.6,23,23,0,0,1,5-14.5c4.2-5.4,9.9-8.1,17-8.1,7.3,0,13.2,2.8,17.5,8.3,3.1,3.9,4.7,8.8,4.7,14.7H136.4a17.48,17.48,0,0,0,4.8,12.3,15.26,15.26,0,0,0,11.4,4.8,20,20,0,0,0,6.4-1.1,19.3,19.3,0,0,0,5.3-3A33.07,33.07,0,0,0,168.9,95.1Zm0-11.6a18.66,18.66,0,0,0-3.2-7.1,15.25,15.25,0,0,0-5.6-4.3,16.87,16.87,0,0,0-7.3-1.6,16.06,16.06,0,0,0-10.9,4.1,18.15,18.15,0,0,0-5,8.9Z"></path><path class="cls-1" d="M182,66.4h5.6v6.3a20,20,0,0,1,5.3-5.5,10.67,10.67,0,0,1,5.8-1.8,9.87,9.87,0,0,1,4.9,1.5l-2.9,4.7a7.52,7.52,0,0,0-2.9-.7,8.09,8.09,0,0,0-5.3,2.3,14.64,14.64,0,0,0-3.9,7c-.7,2.4-1,7.4-1,14.8v14.5H182Z"></path><path class="cls-1" d="M246.2,66.4v42.9h-5.4V102a23.11,23.11,0,0,1-7.8,6.3,21.23,21.23,0,0,1-9.4,2.1,21,21,0,0,1-15.6-6.6,23.07,23.07,0,0,1,.1-32,21.23,21.23,0,0,1,15.7-6.6,20,20,0,0,1,17.1,8.9V66.2h5.3Zm-22.1,4.2a16.67,16.67,0,0,0-8.5,2.3,15.93,15.93,0,0,0-6.2,6.4,17.68,17.68,0,0,0-2.3,8.7,18.26,18.26,0,0,0,2.3,8.7,15.93,15.93,0,0,0,6.2,6.4,16.58,16.58,0,0,0,8.4,2.3,17.59,17.59,0,0,0,8.6-2.3,15.42,15.42,0,0,0,6.2-6.2,17.17,17.17,0,0,0,2.2-8.8,16.73,16.73,0,0,0-4.9-12.4A15.8,15.8,0,0,0,224.1,70.6Z"></path><path class="cls-2" d="M259.5,51.3h29.1V57H265.3V75.2h23.3v5.7H265.3v28.5h-5.8V51.3Z"></path><path class="cls-2" d="M296.9,49.9h5.5v59.5h-5.5Z"></path><path class="cls-2" d="M330.5,65.3a21.1,21.1,0,0,1,16.4,7.2A22.55,22.55,0,0,1,352.8,88a22.24,22.24,0,0,1-6.3,15.7c-4.2,4.5-9.5,6.7-16.1,6.7s-12-2.2-16.1-6.7A22.24,22.24,0,0,1,308,88a22.73,22.73,0,0,1,5.9-15.5A21.81,21.81,0,0,1,330.5,65.3Zm0,5.4a15.83,15.83,0,0,0-11.8,5.1,17,17,0,0,0-4.9,12.3,17.68,17.68,0,0,0,2.3,8.7,15.19,15.19,0,0,0,6.1,6.2,16.48,16.48,0,0,0,8.4,2.2A16,16,0,0,0,339,103a15.82,15.82,0,0,0,6.1-6.2,17.68,17.68,0,0,0,2.3-8.7,17.07,17.07,0,0,0-5-12.3A16.2,16.2,0,0,0,330.5,70.7Z"></path><path class="cls-2" d="M351.2,66.4h5.7L370,97.6l13.7-31.1h1l13.8,31.1,13.4-31.1h5.7L399,109.3h-1L384.3,78.6l-13.7,30.7h-1Z"></path><polyline class="cls-3" points="51 105 51 41.2 27 41.2"></polyline><polyline class="cls-3" points="38.1 33.8 56.4 33.8 56.4 93"></polyline><polyline class="cls-3" points="79.9 33.8 61.5 33.8 61.5 79.2"></polyline><polyline class="cls-3" points="90.7 41.2 66.7 41.2 66.7 105"></polyline><line class="cls-3" x1="83.1" y1="62.6" x2="66.7" y2="62.6"></line><circle class="cls-4" cx="27" cy="41.2" r="5.3"></circle><path class="cls-1" d="M23.3,41.2a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,23.3,41.2Z"></path><circle class="cls-5" cx="51" cy="105" r="5.4"></circle><path class="cls-1" d="M47.3,105a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,47.3,105Z"></path><circle class="cls-6" cx="56.36" cy="93.02" r="3.4"></circle><circle class="cls-6" cx="61.5" cy="79.2" r="2.8"></circle><circle class="cls-7" cx="66.7" cy="105.01" r="5.3"></circle><path class="cls-1" d="M63,105a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,63,105Z"></path><circle class="cls-8" cx="90.7" cy="41.2" r="5.1"></circle><path class="cls-1" d="M87,41.2a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,87,41.2Z"></path><circle class="cls-8" cx="84.7" cy="62.6" r="5.1"></circle><path class="cls-1" d="M81,62.6a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,81,62.6Z"></path><line class="cls-3" x1="34.8" y1="62.6" x2="51.1" y2="62.6"></line><circle class="cls-8" cx="33.1" cy="62.6" r="5.1"></circle><path class="cls-1" d="M36.9,62.6a3.8,3.8,0,1,1-3.8-3.8A3.8,3.8,0,0,1,36.9,62.6Z"></path><line class="cls-3" x1="23.7" y1="26.7" x2="94.1" y2="26.7"></line><circle class="cls-9" cx="94.09" cy="26.67" r="5"></circle><path class="cls-1" d="M90.3,26.7a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,90.3,26.7Z"></path><circle class="cls-6" cx="78" cy="33.8" r="3.8"></circle><circle class="cls-6" cx="40" cy="33.8" r="3.8"></circle><circle class="cls-10" cx="23.71" cy="26.71" r="5.1"></circle><path class="cls-1" d="M20,26.7a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,20,26.7Z"></path></svg> - </a> - </div> - - <nav class="navbar navbar-expand-lg navbar-dark bg-primary" style="margin-bottom: 10px;"> - <div class="container-fluid"> - <a class="navbar-brand" href="{{ url_for('main.home') }}"> - <img src="https://teraflow-h2020.eu/sites/teraflow/files/public/favicon.png" alt="" width="30" height="24" class="d-inline-block align-text-top"/> - TeraFlow + <!doctype html> + <!-- + Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) + + 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. + --> + + <html lang="en"> + <head> + <!-- Required meta tags --> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <link rel="shortcut icon" href="https://tfs.etsi.org/images/logos/tfs_logo_small.png" type="image/png" /> + + <!-- Bootstrap CSS --> + <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-uWxY/CJNBR+1zjPWmfnSnVxwRheevXITnMqoEIeG1LJrdI0GlVs/9cVSyPYXdcSF" crossorigin="anonymous"> + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"> + + <title>ETSI TeraFlowSDN Controller</title> + </head> + <body> + <div id="teraflow-branding"> + <a href="{{ url_for('main.home') }}" title="Home" rel="home" id="main-logo" class="site-logo site-logo-pages"> + <img src="{{ url_for('static', filename='TeraFlow SDN Logo ScreenColour with Slogan.png') }}" width="400" type="image/png"> </a> - <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor02" aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation"> - <span class="navbar-toggler-icon"></span> - </button> - <div class="collapse navbar-collapse" id="navbarColor02"> - <ul class="navbar-nav me-auto mb-2 mb-lg-0"> - <li class="nav-item"> - {% if request.path == '/' %} - <a class="nav-link active" aria-current="page" href="{{ url_for('main.home') }}">Home</a> - {% else %} - <a class="nav-link" href="{{ url_for('main.home') }}">Home</a> - {% endif %} - </li> - <li class="nav-item"> - {% if '/device/' in request.path %} - <a class="nav-link active" aria-current="page" href="{{ url_for('device.home') }}">Device</a> - {% else %} - <a class="nav-link" href="{{ url_for('device.home') }}">Device</a> - {% endif %} - </li> - <li class="nav-item"> - {% if '/link/' in request.path %} - <a class="nav-link active" aria-current="page" href="{{ url_for('link.home') }}">Link</a> - {% else %} - <a class="nav-link" href="{{ url_for('link.home') }}">Link</a> - {% endif %} - </li> - <li class="nav-item"> - {% if '/service/' in request.path %} - <a class="nav-link active" aria-current="page" href="{{ url_for('service.home') }}">Service</a> - {% else %} - <a class="nav-link" href="{{ url_for('service.home') }}">Service</a> - {% endif %} - </li> - - <li class="nav-item"> - <a class="nav-link" href="/grafana" id="grafana_link" target="grafana">Grafana</a> - </li> - - <li class="nav-item"> - <a class="nav-link" href="{{ url_for('main.debug') }}">Debug</a> - </li> - - <!-- <li class="nav-item"> - <a class="nav-link" href="#">Context</a> - </li> - - <li class="nav-item"> - <a class="nav-link" href="#">Monitoring</a> - </li> --> - <li class="nav-item"> - <a class="nav-link" href="{{ url_for('main.about') }}">About</a> - </li> - </ul> - <span class="navbar-text" style="color: #fff;"> - Current context: <b>{{ get_working_context() }}</b> - </span> - </div> </div> - </nav> - - <main class="container"> - <div class="row"> - <div class="col-md-12"> - {% with messages = get_flashed_messages(with_categories=true) %} - {% if messages %} - {% for category, message in messages %} - <div class="alert alert-{{ category }} alert-dismissible fade show" role="alert"> - {{ message }} - <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> - </div> - - {% endfor %} - {% endif %} - {% endwith %} - </div> - </div> - <div class="row"> - <div class="col-xxl-12"> - {% block content %}{% endblock %} + + <nav class="navbar navbar-expand-lg navbar-dark bg-primary" style="margin-bottom: 10px;"> + <div class="container-fluid"> + <a class="navbar-brand" href="{{ url_for('main.home') }}"> + <img src="https://teraflow-h2020.eu/sites/teraflow/files/public/favicon.png" alt="" width="30" height="24" class="d-inline-block align-text-top"/> + TeraFlow + </a> + <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor02" aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarColor02"> + <ul class="navbar-nav me-auto mb-2 mb-lg-0"> + <li class="nav-item"> + {% if request.path == '/' %} + <a class="nav-link active" aria-current="page" href="{{ url_for('main.home') }}">Home</a> + {% else %} + <a class="nav-link" href="{{ url_for('main.home') }}">Home</a> + {% endif %} + </li> + <li class="nav-item"> + {% if '/device/' in request.path %} + <a class="nav-link active" aria-current="page" href="{{ url_for('device.home') }}">Device</a> + {% else %} + <a class="nav-link" href="{{ url_for('device.home') }}">Device</a> + {% endif %} + </li> + <li class="nav-item"> + {% if '/link/' in request.path %} + <a class="nav-link active" aria-current="page" href="{{ url_for('link.home') }}">Link</a> + {% else %} + <a class="nav-link" href="{{ url_for('link.home') }}">Link</a> + {% endif %} + </li> + <li class="nav-item"> + {% if '/service/' in request.path %} + <a class="nav-link active" aria-current="page" href="{{ url_for('service.home') }}">Service</a> + {% else %} + <a class="nav-link" href="{{ url_for('service.home') }}">Service</a> + {% endif %} + </li> + + <li class="nav-item"> + <a class="nav-link" href="/grafana" id="grafana_link" target="grafana">Grafana</a> + </li> + + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('main.debug') }}">Debug</a> + </li> + + <!-- <li class="nav-item"> + <a class="nav-link" href="#">Context</a> + </li> + + <li class="nav-item"> + <a class="nav-link" href="#">Monitoring</a> + </li> --> + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('main.about') }}">About</a> + </li> + </ul> + <span class="navbar-text" style="color: #fff;"> + Current context: <b>{{ get_working_context() }}</b> + </span> + </div> </div> - </div> - </main> - - <footer class="footer" style="background-color: darkgrey; margin-top: 30px; padding-top: 20px;"> - <div class="container"> + </nav> + + <main class="container"> <div class="row"> <div class="col-md-12"> - <p class="text-center" style="color: white;">© 2021-2023</p> + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + <div class="alert alert-{{ category }} alert-dismissible fade show" role="alert"> + {{ message }} + <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> + </div> + + {% endfor %} + {% endif %} + {% endwith %} </div> </div> <div class="row"> - <div class="col-md-6"> - <p>This project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement No 101015857.</p> + <div class="col-xxl-12"> + {% block content %}{% endblock %} + </div> + </div> + </main> + + <footer class="footer" style="background-color: darkgrey; margin-top: 30px; padding-top: 20px;"> + <div class="container"> + <div class="row"> + <div class="col-md-12"> + <p class="text-center" style="color: white;">© 2021-2023</p> + </div> </div> - <div class="col-md-6"> - <img src="https://teraflow-h2020.eu/sites/teraflow/files/public/content-images/media/2021/logo%205G-ppp%20eu.png" width="310" alt="5g ppp EU logo" loading="lazy" typeof="foaf:Image"> + <div class="row"> + <div class="col-md-6"> + <p>This project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement No 101015857.</p> + </div> + <div class="col-md-6"> + <img src="https://teraflow-h2020.eu/sites/teraflow/files/public/content-images/media/2021/logo%205G-ppp%20eu.png" width="310" alt="5g ppp EU logo" loading="lazy" typeof="foaf:Image"> + </div> </div> </div> - </div> - </footer> - - <!-- Optional JavaScript; choose one of the two! --> - - <!-- Option 1: Bootstrap Bundle with Popper --> - <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-kQtW33rZJAHjgefvhyyzcGF3C5TFyBQBA13V1RKPf4uH+bwyzQxZ6CmMZHmNBEfJ" crossorigin="anonymous"></script> - <!-- <script src="{{ url_for('static', filename='site.js') }}"/> --> - <!-- <script> - document.getElementById("grafana_link").href = window.location.protocol + "//" + window.location.hostname + ":30300" - </script> --> - <!-- Option 2: Separate Popper and Bootstrap JS --> - <!-- - <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script> - <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.min.js" integrity="sha384-PsUw7Xwds7x08Ew3exXhqzbhuEYmA2xnwc8BuD6SEr+UmEHlX8/MCltYEodzWA4u" crossorigin="anonymous"></script> - --> - </body> -</html> \ No newline at end of file + </footer> + + <!-- Optional JavaScript; choose one of the two! --> + + <!-- Option 1: Bootstrap Bundle with Popper --> + <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-kQtW33rZJAHjgefvhyyzcGF3C5TFyBQBA13V1RKPf4uH+bwyzQxZ6CmMZHmNBEfJ" crossorigin="anonymous"></script> + <!-- <script src="{{ url_for('static', filename='site.js') }}"/> --> + <!-- <script> + document.getElementById("grafana_link").href = window.location.protocol + "//" + window.location.hostname + ":30300" + </script> --> + <!-- Option 2: Separate Popper and Bootstrap JS --> + <!-- + <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script> + <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.min.js" integrity="sha384-PsUw7Xwds7x08Ew3exXhqzbhuEYmA2xnwc8BuD6SEr+UmEHlX8/MCltYEodzWA4u" crossorigin="anonymous"></script> + --> + </body> + </html> \ No newline at end of file diff --git a/src/webui/service/templates/link/detail.html b/src/webui/service/templates/link/detail.html index 8b49a65eb..7df9ddce6 100644 --- a/src/webui/service/templates/link/detail.html +++ b/src/webui/service/templates/link/detail.html @@ -36,7 +36,7 @@ <thead> <tr> <th scope="col">Endpoints</th> - <th scope="col">Type</th> + <th scope="col">Device</th> </tr> </thead> <tbody> @@ -46,7 +46,13 @@ {{ end_point.endpoint_uuid.uuid }} </td> <td> - {{ end_point.endpoint_uuid.uuid }} + <a href="{{ url_for('device.detail', device_uuid=end_point.device_id.device_uuid.uuid) }}"> + {{ end_point.device_id.device_uuid.uuid }} + <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"> + <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/> + <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/> + </svg> + </a> </td> </tr> {% endfor %} diff --git a/src/webui/service/templates/main/about.html b/src/webui/service/templates/main/about.html index 4ba3a5845..80d61891c 100644 --- a/src/webui/service/templates/main/about.html +++ b/src/webui/service/templates/main/about.html @@ -16,10 +16,10 @@ {% extends 'base.html' %} {% block content %} - <h1>TeraFlow OS</h1> + <h1>ETSI TeraFlowSDN Controller</h1> - <p>For more information, visit the <a href="https://teraflow-h2020.eu/" target="_newtf">TeraFlow H2020 webpage</a>.</p> + <p>For more information, visit the <a href="https://tfs.etsi.org/" target="_newtf">ETSI Open Source Group for TeraFlowSDN</a>.</p> - <img alt="Consortium" class="img-fluid" src="{{ url_for('static', filename='partners.png') }}"/> + <!--<img alt="Consortium" class="img-fluid" src="{{ url_for('static', filename='partners.png') }}"/>--> {% endblock %} \ No newline at end of file diff --git a/src/webui/service/templates/service/detail.html b/src/webui/service/templates/service/detail.html index 3a0f0f7d0..9d2c1e736 100644 --- a/src/webui/service/templates/service/detail.html +++ b/src/webui/service/templates/service/detail.html @@ -17,120 +17,170 @@ {% extends 'base.html' %} {% block content %} - <h1>Service {{ service.service_id.service_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('service.home') }}'"> - <i class="bi bi-box-arrow-in-left"></i> - Back to service list - </button> - </div> - <div class="col-sm-3"> - <a id="update" class="btn btn-secondary" href="#"> - <i class="bi bi-pencil-square"></i> - Update - </a> - </div> - <div class="col-sm-3"> - <!-- <button type="button" class="btn btn-danger"><i class="bi bi-x-square"></i>Delete service</button> --> - <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal"> - <i class="bi bi-x-square"></i>Delete service - </button> - </div> +<h1>Service {{ service.service_id.service_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('service.home') }}'"> + <i class="bi bi-box-arrow-in-left"></i> + Back to service list + </button> </div> - - <div class="row mb-3"> - <div class="col-sm-1"><b>UUID:</b></div> - <div class="col-sm-5"> - {{ service.service_id.service_uuid.uuid }} - </div> - <div class="col-sm-1"><b>Type:</b></div> - <div class="col-sm-5"> - {{ service.service_type }} - </div> + <div class="col-sm-3"> + <a id="update" class="btn btn-secondary" href="#"> + <i class="bi bi-pencil-square"></i> + Update + </a> </div> - <div class="row mb-3"> - <b>Endpoints:</b> - <div class="col-sm-10"> - <ul> - {% for endpoint in service.service_endpoint_ids %} - <li>{{ endpoint.endpoint_uuid.uuid }}: {{ endpoint.endpoint_type }}</li> - {% endfor %} - </ul> - </div> - </div> - <div class="row mb-3"> - <b>Configurations:</b> - <div class="col-sm-10"> - <ul> - {% for config in service.service_config.config_rules %} - {% if config.WhichOneof('config_rule') == 'custom' %} - <li>{{ config.custom.resource_key }}: - <ul> - {% for key, value in (config.custom.resource_value | from_json).items() %} - <li><b>{{ key }}:</b> {{ value }}</li> - {% endfor %} - </ul> - </li> - {% endif %} - {% endfor %} - </ul> - </div> + <div class="col-sm-3"> + <!-- <button type="button" class="btn btn-danger"><i class="bi bi-x-square"></i>Delete service</button> --> + <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal"> + <i class="bi bi-x-square"></i>Delete service + </button> </div> +</div> - <!-- Modal --> -<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"> +<div class="row mb-3"> + <div class="col-sm-4"> + <b>UUID: </b> {{ service.service_id.service_uuid.uuid }}<br><br> + <b>Type: </b> {{ ste.Name(service.service_type).replace('SERVICETYPE_', '') }}<br><br> + <b>Status: </b> {{ sse.Name(service.service_status.service_status).replace('SERVICESTATUS_', '') }}<br><br> + </div> + <div class="col-sm-8"> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th scope="col">Endpoints</th> + <th scope="col">Device</th> + </tr> + </thead> + <tbody> + {% for endpoint in service.service_endpoint_ids %} + <tr> + <td> + {{ endpoint.endpoint_uuid.uuid }} + </td> + <td> + <a href="{{ url_for('device.detail', device_uuid=endpoint.device_id.device_uuid.uuid) }}"> + {{ endpoint.device_id.device_uuid.uuid }} + <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"> + <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/> + <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/> + </svg> + </a> + </td> + </tr> + {% endfor %} + </tbody> + </table> + </div> +</div> +<b>Constraints:</b> +<table class="table table-striped table-hover"> + <thead> + <tr> + <th scope="col">Type</th> + <th scope="col">Value</th> + </tr> + </thead> + <tbody> + {% for constraint in service.service_constraints %} + <tr> + <td> + {{ constraint.custom.constraint_type }} + </td> + <td> + <ul> + {{ constraint.custom.constraint_value }} + </ul> + </td> + </tr> + {% endfor %} + </tbody> +</table> +<b>Configurations:</b> +<table class="table table-striped table-hover"> + <thead> + <tr> + <th scope="col">Key</th> + <th scope="col">Value</th> + </tr> + </thead> + <tbody> + {% for config in service.service_config.config_rules %} + {% if config.WhichOneof('config_rule') == 'custom' %} + <tr> + <td> + {{ config.custom.resource_key }} + </td> + <td> + <ul> + {% for key, value in (config.custom.resource_value | from_json).items() %} + <li><b>{{ key }}:</b> {{ value }}</li> + {% endfor %} + </ul> + </td> + </tr> + {% endif %} + {% endfor %} + </tbody> +</table> +<!-- Modal --> +<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" + aria-labelledby="staticBackdropLabel" aria-hidden="true"> <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <h5 class="modal-title" id="staticBackdropLabel">Delete service?</h5> - <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="staticBackdropLabel">Delete service?</h5> + <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> + </div> + <div class="modal-body"> + Are you sure you want to delete the service "{{ service.service_id.service_uuid.uuid }}"? + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button> + <a type="button" class="btn btn-danger" + href="{{ url_for('service.delete', service_uuid=service.service_id.service_uuid.uuid) }}"><i + class="bi bi-exclamation-diamond"></i>Yes</a> + </div> </div> - <div class="modal-body"> - Are you sure you want to delete the service "{{ service.service_id.service_uuid.uuid }}"? - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button> - <a type="button" class="btn btn-danger" href="{{ url_for('service.delete', service_uuid=service.service_id.service_uuid.uuid) }}"><i class="bi bi-exclamation-diamond"></i>Yes</a> - </div> - </div> </div> - </div> - - - <table class="table table-striped table-hover"> - <thead> - <tr> - <th scope="col">Connection Id</th> - <th scope="col">Sub-service</th> - <th scope="col">Path</th> - </tr> - </thead> - <tbody> - {% for connections in connections.connections %} - <tr> - <td> - {{ connections.connection_id.connection_uuid.uuid }} - </td> - <td> - {{ connections.sub_service_ids|map(attribute='service_uuid')|map(attribute='uuid')|join(', ') }} - </td> - - {% for i in range(connections.path_hops_endpoint_ids|length) %} -<td> - {{ connections.path_hops_endpoint_ids[i].device_id.device_uuid.uuid }} / {{ connections.path_hops_endpoint_ids[i].endpoint_uuid.uuid }} -</td> -{% endfor %} - - - </tr> +</div> + + +<table class="table table-striped table-hover"> + <thead> + <tr> + <th scope="col">Connection Id</th> + <th scope="col">Sub-service</th> + <th scope="col">Path</th> + </tr> + </thead> + <tbody> + {% for connections in connections.connections %} + <tr> + <td> + {{ connections.connection_id.connection_uuid.uuid }} + </td> + <td> + {{ connections.sub_service_ids|map(attribute='service_uuid')|map(attribute='uuid')|join(', ') }} + </td> + + {% for i in range(connections.path_hops_endpoint_ids|length) %} + <td> + {{ connections.path_hops_endpoint_ids[i].device_id.device_uuid.uuid }} / {{ + connections.path_hops_endpoint_ids[i].endpoint_uuid.uuid }} + </td> {% endfor %} - </tbody> - </table> + + + </tr> + {% endfor %} + </tbody> +</table> -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/src/webui/service/templates/service/home.html b/src/webui/service/templates/service/home.html index 8d231cf17..c0a01839b 100644 --- a/src/webui/service/templates/service/home.html +++ b/src/webui/service/templates/service/home.html @@ -46,7 +46,6 @@ <th scope="col">#</th> <th scope="col">Type</th> <th scope="col">End points</th> - <th scope="col">Constraints</th> <th scope="col">Status</th> <th scope="col"></th> </tr> @@ -70,14 +69,7 @@ {% endfor %} </ul> </td> - <td> - <ul> - {% for constraint in service.service_constraints %} - <li>{{ constraint.custom.constraint_type }}: {{ constraint.custom.constraint_value }}</li> - {% endfor %} - </ul> - </td> - <td>{{ sse.Name(service.service_status.service_status).replace('SERVICESTATUS_', '') }}</td> + <td>{{ sse.Name(service.service_status.service_status).replace('SERVICESTATUS_', '') }} </td> <td> <a href="{{ url_for('service.detail', service_uuid=service.service_id.service_uuid.uuid) }}"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"> -- GitLab