style: make more consistent styles 07/69407/3
authorJeremy Plsek <jeremyplsek@gmail.com>
Thu, 19 Dec 2019 17:58:33 +0000 (12:58 -0500)
committerJeremy Plsek <jeremyplsek@gmail.com>
Thu, 19 Dec 2019 17:58:33 +0000 (12:58 -0500)
- Fix indentation in places
- User settings have better labels
- Lab info title now the same as others
- Add "empty" sections to be more helpful to the user. They are not
using links, since most of the "workflow" is handled by javascript.
- Update padding in places to better line up with other elements
- Add padding to bootstrap notifications (add check for messages to not
just have random padding on the top of the page)
- Remove unnecessary text in a form
- Remove card-body from table-only or list-only cards (lists and tables
are now flush with cards)
- Add bg-danger to not-working hosts
- Replace True/False text shown to the user with Yes/No
- Remove ":" from some headers
- Vertical buttons are now in a button group
- Add pre-wrap class to avoid pre from breaking box sizing on the
booking detail page
- Reduce table indent in pod card and add table overflow scrollbar

Signed-off-by: Jeremy Plsek <jeremyplsek@gmail.com>
Change-Id: If09dca2f2b7386c44eeeb817ef76e8f748e456da

24 files changed:
src/account/forms.py
src/dashboard/views.py
src/static/css/base.css
src/templates/account/booking_list.html
src/templates/account/configuration_list.html
src/templates/account/image_list.html
src/templates/account/resource_list.html
src/templates/account/userprofile_update_form.html
src/templates/base.html
src/templates/booking/booking_detail.html
src/templates/booking/quick_deploy.html
src/templates/booking/stats.html
src/templates/config_bundle/steps/config_software.html
src/templates/dashboard/lab_detail.html
src/templates/dashboard/lab_list.html
src/templates/dashboard/landing.html
src/templates/dashboard/multiple_select_filter_widget.html
src/templates/dashboard/searchable_select_multiple.html
src/templates/resource/hostprofile_detail.html
src/templates/resource/hosts.html
src/templates/resource/steps/define_hardware.html
src/templates/resource/steps/meta_info.html
src/templates/resource/steps/pod_definition.html
src/templates/workflow/viewport-base.html

index 3b9c627..dd1a0a9 100644 (file)
@@ -10,6 +10,7 @@
 
 import django.forms as forms
 import pytz as pytz
+from django.utils.translation import gettext_lazy as _
 
 from account.models import UserProfile
 
@@ -18,5 +19,10 @@ class AccountSettingsForm(forms.ModelForm):
     class Meta:
         model = UserProfile
         fields = ['company', 'email_addr', 'ssh_public_key', 'pgp_public_key', 'timezone']
+        labels = {
+            'email_addr': _('Email Address'),
+            'ssh_public_key': _('SSH Public Key'),
+            'pgp_public_key': _('PGP Public Key')
+        }
 
     timezone = forms.ChoiceField(choices=[(x, x) for x in pytz.common_timezones], initial='UTC')
index c387251..2f37774 100644 (file)
@@ -21,7 +21,7 @@ from workflow.workflow_manager import ManagerTracker
 
 def lab_list_view(request):
     labs = Lab.objects.all()
-    context = {"labs": labs}
+    context = {"labs": labs, 'title': 'Labs'}
 
     return render(request, "dashboard/lab_list.html", context)
 
index 9fec97e..4673a5e 100644 (file)
     color: inherit;
 }
 
+/* Make sure pre elements wrap to not break box sizing */
+/* Note: the pre element or parent may need to use the text-break class as well */
+.pre-wrap {
+    white-space: pre-wrap;
+}
+
 /* Allow for sidebar to be small, but also resize on small screens */
 .sidebar {
     min-width: 200px;
@@ -72,12 +78,6 @@ a[aria-expanded="true"] > i.rotate {
     cursor: not-allowed;
 }
 
-/* Used with position-absolute class to make a full height object */
-.topToBottom {
-    bottom: 0;
-    top: 0;
-}
-
 .z-2 {
     z-index: 2;
 }
index 55c6c0d..f9234bc 100644 (file)
 {% extends "base.html" %}
 {% block content %}
 <h2>Bookings I Own</h2>
-    <div class="row">
-        {% for booking in bookings %}
-            <div class="col-12 col-md-6 col-lg-4 col-xl-3 p-2">
-                <div class="card h-100">
-                    <div class="card-header">
-                        <h3>Booking {{booking.id}}</h3>
-                    </div>
-                    <div class="card-body">
-                        <ul class="list-group">
-                            <li class="list-group-item">id: {{booking.id}}</li>
-                            <li class="list-group-item">lab: {{booking.lab}}</li>
-                            <li class="list-group-item">resource: {{booking.resource.template.name}}</li>
-                            <li class="list-group-item">start: {{booking.start}}</li>
-                            <li class="list-group-item">end: {{booking.end}}</li>
-                            <li class="list-group-item">purpose: {{booking.purpose}}</li>
-                        </ul>
-                    </div>
-                    <div class="card-footer d-flex">
-                        <a class="btn btn-primary ml-auto mr-2" href="/booking/detail/{{booking.id}}/">Details</a>
-                        <button
-                            class="btn btn-danger"
-                            onclick='cancel_booking({{booking.id}});'
-                            data-toggle="modal"
-                            data-target="#resModal"
-                        >Cancel</button>
-                    </div>
+<div class="row">
+    {% for booking in bookings %}
+        <div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-3">
+            <div class="card h-100">
+                <div class="card-header">
+                    <h3>Booking {{booking.id}}</h3>
+                </div>
+                <ul class="list-group list-group-flush h-100">
+                    <li class="list-group-item">id: {{booking.id}}</li>
+                    <li class="list-group-item">lab: {{booking.lab}}</li>
+                    <li class="list-group-item">resource: {{booking.resource.template.name}}</li>
+                    <li class="list-group-item">start: {{booking.start}}</li>
+                    <li class="list-group-item">end: {{booking.end}}</li>
+                    <li class="list-group-item">purpose: {{booking.purpose}}</li>
+                </ul>
+                <div class="card-footer d-flex">
+                    <a class="btn btn-primary ml-auto mr-2" href="/booking/detail/{{booking.id}}/">Details</a>
+                    <button
+                        class="btn btn-danger"
+                        onclick='cancel_booking({{booking.id}});'
+                        data-toggle="modal"
+                        data-target="#resModal"
+                    >Cancel</button>
                 </div>
             </div>
-        {% endfor %}
-    </div>
+        </div>
+    {% empty %}
+        <div class="col">
+            <p>You don't have any bookings. You can create a booking by booking a pod.</p>
+        </div>
+    {% endfor %}
+</div>
+
 <h2>Bookings I Collaborate On</h2>
-    <div class="row">
-        {% for booking in collab_bookings %}
-            <div class="col-12 col-md-6 col-lg-4 col-xl-3 p-2">
-                <div class="card h-100">
-                    <div class="card-header">
-                        <h3>Booking {{booking.id}}</h3>
-                    </div>
-                    <div class="card-body">
-                        <ul class="list-group">
-                            <li class="list-group-item">id: {{booking.id}}</li>
-                            <li class="list-group-item">lab: {{booking.lab}}</li>
-                            <li class="list-group-item">resource: {{booking.resource.template.name}}</li>
-                            <li class="list-group-item">start: {{booking.start}}</li>
-                            <li class="list-group-item">end: {{booking.end}}</li>
-                            <li class="list-group-item">purpose: {{booking.purpose}}</li>
-                        </ul>
-                    </div>
-                    <div class="card-footer d-flex">
-                        <a class="btn btn-primary ml-auto" href="/booking/detail/{{booking.id}}/">Details</a>
-                    </div>
+<div class="row">
+
+    {% for booking in collab_bookings %}
+        <div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-3">
+            <div class="card h-100">
+                <div class="card-header">
+                    <h3>Booking {{booking.id}}</h3>
+                </div>
+                <ul class="list-group list-group-flush h-100">
+                    <li class="list-group-item">id: {{booking.id}}</li>
+                    <li class="list-group-item">lab: {{booking.lab}}</li>
+                    <li class="list-group-item">resource: {{booking.resource.template.name}}</li>
+                    <li class="list-group-item">start: {{booking.start}}</li>
+                    <li class="list-group-item">end: {{booking.end}}</li>
+                    <li class="list-group-item">purpose: {{booking.purpose}}</li>
+                </ul>
+                <div class="card-footer d-flex">
+                    <a class="btn btn-primary ml-auto" href="/booking/detail/{{booking.id}}/">Details</a>
                 </div>
             </div>
-        {% endfor %}
-    </div>
-    <a href="#expired_bookings" data-toggle="collapse" class="h2 discrete-a">
-        Expired Bookings
-        <i class="fas fa-angle-down rotate"></i>
-    </a>
-    <div id="expired_bookings" class="row collapse">
-        {% for booking in expired_bookings %}
-            <div class="col-12 col-md-6 col-lg-4 col-xl-3 p-2">
-                <div class="card h-100">
-                    <div class="card-header">
-                        <h3>Booking {{booking.id}}</h3>
-                    </div>
-                    <div class="card-body">
-                        <ul class="list-group">
-                            <li class="list-group-item">id: {{booking.id}}</li>
-                            <li class="list-group-item">lab: {{booking.lab}}</li>
-                            <li class="list-group-item">resource: {{booking.resource.template.name}}</li>
-                            <li class="list-group-item">start: {{booking.start}}</li>
-                            <li class="list-group-item">end: {{booking.end}}</li>
-                            <li class="list-group-item">purpose: {{booking.purpose}}</li>
-                            <li class="list-group-item">owner: {{booking.owner.userprofile.email_addr}}</li>
-                        </ul>
-                    </div>
-                    <div class="card-footer d-flex">
-                        <a class="btn btn-primary ml-auto" href="/booking/detail/{{booking.id}}/">Details</a>
-                    </div>
+        </div>
+    {% empty %}
+        <div class="col">
+            <p>There are no collaborative bookings.</p>
+        </div>
+    {% endfor %}
+</div>
+
+<a href="#expired_bookings" data-toggle="collapse" class="h2 discrete-a">
+    Expired Bookings
+    <i class="fas fa-angle-down rotate"></i>
+</a>
+<div id="expired_bookings" class="row collapse">
+    {% for booking in expired_bookings %}
+        <div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-3">
+            <div class="card h-100">
+                <div class="card-header">
+                    <h3>Booking {{booking.id}}</h3>
+                </div>
+                <ul class="list-group list-group-flush h-100">
+                    <li class="list-group-item">id: {{booking.id}}</li>
+                    <li class="list-group-item">lab: {{booking.lab}}</li>
+                    <li class="list-group-item">resource: {{booking.resource.template.name}}</li>
+                    <li class="list-group-item">start: {{booking.start}}</li>
+                    <li class="list-group-item">end: {{booking.end}}</li>
+                    <li class="list-group-item">purpose: {{booking.purpose}}</li>
+                    <li class="list-group-item">owner: {{booking.owner.userprofile.email_addr}}</li>
+                </ul>
+                <div class="card-footer d-flex">
+                    <a class="btn btn-primary ml-auto" href="/booking/detail/{{booking.id}}/">Details</a>
                 </div>
             </div>
-        {% endfor %}
-    </div>
+        </div>
+    {% empty %}
+        <div class="col">
+            <p>There are no expired bookings.</p>
+        </div>
+    {% endfor %}
+</div>
+
 <script>
     var current_booking_id = -1;
     function cancel_booking(booking_id) {
         req.send(formData);
     }
 </script>
+
 <div class="modal fade" id="resModal" tabindex="-1" role="dialog" aria-hidden="true">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
index 94a1120..206c203 100644 (file)
@@ -2,19 +2,17 @@
 {% block content %}
 <div class="row">
 {% for config in configurations %}
-    <div class="p-2 col-12 col-md-6 col-lg-4 col-xl-3">
+    <div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-3">
         <div class="card h-100">
             <div class="card-header">
                 <h3>Configuration {{config.id}}</h3>
             </div>
-            <div class="card-body">
-                <ul class="list-group">
-                    <li class="list-group-item">id: {{config.id}}</li>
-                    <li class="list-group-item">name: {{config.name}}</li>
-                    <li class="list-group-item">description: {{config.description}}</li>
-                    <li class="list-group-item">resource: {{config.bundle}}</li>
-                </ul>
-            </div>
+            <ul class="list-group list-group-flush h-100">
+                <li class="list-group-item">id: {{config.id}}</li>
+                <li class="list-group-item">name: {{config.name}}</li>
+                <li class="list-group-item">description: {{config.description}}</li>
+                <li class="list-group-item">resource: {{config.bundle}}</li>
+            </ul>
             <div class="card-footer">
                 <button
                     class="btn btn-danger w-100"
             </div>
         </div>
     </div>
+{% empty %}
+    <div class="col">
+        <p>You don't have any configurations. You can create a configuration by configuring a pod.</p>
+    </div>
 {% endfor %}
 </div>
+
 <script>
     var current_config_id = -1;
     function delete_config(config_id) {
@@ -44,6 +47,7 @@
         req.send(formData);
     }
 </script>
+
 <div class="modal fade" id="configModal" tabindex="-1" role="dialog" aria-hidden="true">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
index a626710..6263016 100644 (file)
@@ -3,20 +3,18 @@
 <h2>Images I Own</h2>
 <div class="row">
 {% for image in images %}
-    <div class="p-2 col-12 col-md-6 col-lg-4 col-xl-3">
+    <div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-3">
         <div class="card h-100">
             <div class="card-header">
                 <h3>Image {{image.id}}</h3>
             </div>
-            <div class="card-body">
-                <ul class="list-group">
-                    <li class="list-group-item">id: {{image.id}}</li>
-                    <li class="list-group-item">lab: {{image.from_lab.name}}</li>
-                    <li class="list-group-item">name: {{image.name}}</li>
-                    <li class="list-group-item">description: {{image.description}}</li>
-                    <li class="list-group-item">host profile: {{image.host_type.name}}</li>
-                </ul>
-            </div>
+            <ul class="list-group list-group-flush h-100">
+                <li class="list-group-item">id: {{image.id}}</li>
+                <li class="list-group-item">lab: {{image.from_lab.name}}</li>
+                <li class="list-group-item">name: {{image.name}}</li>
+                <li class="list-group-item">description: {{image.description}}</li>
+                <li class="list-group-item">host profile: {{image.host_type.name}}</li>
+            </ul>
             <div class="card-footer">
                 <button class="btn btn-danger w-100" onclick='delete_image({{image.id}});'
                     data-toggle="modal" data-target="#imageModal">
             </div>
         </div>
     </div>
+{% empty %}
+    <div class="col">
+        <p>You don't have any images. You can create an image by creating a snapshot.</p>
+    </div>
 {% endfor %}
 </div>
+
 <h2>Public Images</h2>
 <div class="row">
     {% for image in public_images %}
-        <div class="p-2 col-12 col-md-6 col-lg-4 col-xl-3">
+        <div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-3">
             <div class="card h-100">
                 <div class="card-header">
                     <h3>Image {{image.id}}</h3>
                 </div>
-                <div class="card-body">
-                    <ul class="list-group">
-                        <li class="list-group-item">id: {{image.id}}</li>
-                        <li class="list-group-item">lab: {{image.from_lab.name}}</li>
-                        <li class="list-group-item">name: {{image.name}}</li>
-                        <li class="list-group-item">description: {{image.description}}</li>
-                        <li class="list-group-item">host profile: {{image.host_type.name}}</li>
-                    </ul>
-                </div>
+                <ul class="list-group list-group-flush h-100">
+                    <li class="list-group-item">id: {{image.id}}</li>
+                    <li class="list-group-item">lab: {{image.from_lab.name}}</li>
+                    <li class="list-group-item">name: {{image.name}}</li>
+                    <li class="list-group-item">description: {{image.description}}</li>
+                    <li class="list-group-item">host profile: {{image.host_type.name}}</li>
+                </ul>
             </div>
         </div>
+    {% empty %}
+        <div class="col">
+            <p>There are no public images.</p>
+        </div>
     {% endfor %}
 </div>
 
index 1203534..65b46f1 100644 (file)
@@ -2,18 +2,16 @@
 {% block content %}
 <div class="row">
 {% for resource in resources %}
-    <div class="col-12 col-md-6 col-lg-4 col-xl-3 p-2">
+    <div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-3">
         <div class="card h-100">
             <div class="card-header">
                 <h3>Resource {{resource.id}}</h3>
             </div>
-            <div class="card-body p-4">
-                <ul class="list-group">
-                    <li class="list-group-item">id: {{resource.id}}</li>
-                    <li class="list-group-item">name: {{resource.name}}</li>
-                    <li class="list-group-item">description: {{resource.description}}</li>
-                </ul>
-            </div>
+            <ul class="list-group list-group-flush h-100">
+                <li class="list-group-item">id: {{resource.id}}</li>
+                <li class="list-group-item">name: {{resource.name}}</li>
+                <li class="list-group-item">description: {{resource.description}}</li>
+            </ul>
             <div class="card-footer">
                 <button
                     class="btn btn-danger w-100"
             </div>
         </div>
     </div>
+{% empty %}
+    <div class="col">
+        <p>You don't have any resources. You can create a resource by designing a pod.</p>
+    </div>
 {% endfor %}
 </div>
 <script>
index 5ddb867..16a8270 100644 (file)
@@ -2,32 +2,30 @@
 {% load bootstrap4 %}
 
 {% block content %}
-    <div class="container-fluid">
-        <div class="row">
-            <div class="col-12 col-xl-6">
-                {% bootstrap_messages %}
-                <div class="login-panel panel panel-default">
-                    <div class="panel-body">
-                        <form enctype="multipart/form-data" method="post">
-                            {% csrf_token %}
-                            {% bootstrap_form form %}
-                            <p><b>API Token</b>
-                                <a href="{% url 'generate_token' %}" class="btn btn-primary">
-                                    Generate
-                                </a>
-                            </p>
-                            <p class="text-break">{{ token.key }}</p>
+<div class="row">
+    <div class="col-12 col-xl-6">
+        {% bootstrap_messages %}
+        <div class="login-panel panel panel-default">
+            <div class="panel-body">
+                <form enctype="multipart/form-data" method="post">
+                    {% csrf_token %}
+                    {% bootstrap_form form %}
+                    <p><b>API Token</b>
+                        <a href="{% url 'generate_token' %}" class="btn btn-primary">
+                            Generate
+                        </a>
+                    </p>
+                    <p class="text-break">{{ token.key }}</p>
 
-                            <p></p>
-                            {% buttons %}
-                                <button type="submit" class="btn btn btn-success">
-                                    Save Profile
-                                </button>
-                            {% endbuttons %}
-                        </form>
-                    </div>
-                </div>
+                    <p></p>
+                    {% buttons %}
+                        <button type="submit" class="btn btn btn-success">
+                            Save Profile
+                        </button>
+                    {% endbuttons %}
+                </form>
             </div>
         </div>
     </div>
+</div>
 {% endblock content %}
index 0b3f8c2..4011739 100644 (file)
                 <nav class="navbar navbar-expand-lg border-bottom p-0 w-100 sidebar">
                     <div class="collapse navbar-collapse" id="sidebar">
                         <div class="list-group list-group-flush w-100 bg-light">
-                            <a href="/" class="list-group-item list-group-item-action bg-light">
+                            <a href="/" class="list-group-item list-group-item-action">
                                 Home
                             </a>
                             {% csrf_token %}
-                            <a class="list-group-item list-group-item-action bg-light" data-toggle="collapse"
+                            <a class="list-group-item list-group-item-action" data-toggle="collapse"
                                 href="#createList" role="button">
                                 Create <i class="fas fa-angle-down rotate"></i>
                             </a>
                                     Configure OPNFV
                                 </a>
                             </div>
-                            <a href="{% url 'resource:hosts' %}" class="list-group-item list-group-item-action bg-light">
+                            <a href="{% url 'resource:hosts' %}" class="list-group-item list-group-item-action">
                                 Hosts
                             </a>
                             {% if user.is_authenticated %}
-                                <a href="{% url 'account:users' %}" class="list-group-item list-group-item-action bg-light">
+                                <a href="{% url 'account:users' %}" class="list-group-item list-group-item-action">
                                     User List
                                 </a>
                             {% endif %}
-                            <a href="{% url 'booking:list' %}" class="list-group-item list-group-item-action bg-light">
+                            <a href="{% url 'booking:list' %}" class="list-group-item list-group-item-action">
                                 Booking List
                             </a>
-                            <a href="{% url 'booking:stats' %}" class="list-group-item list-group-item-action bg-light">
+                            <a href="{% url 'booking:stats' %}" class="list-group-item list-group-item-action">
                                 Booking Statistics
                             </a>
-                            <a class="list-group-item list-group-item-action bg-light" data-toggle="collapse"
+                            <a class="list-group-item list-group-item-action" data-toggle="collapse"
                                 href="#accountList" role="button">
                                 Account <i class="fas fa-angle-down rotate"></i>
                             </a>
                                     My Snapshots
                                 </a>
                             </div>
-                            <a href="{% url 'dashboard:all_labs' %}" class="list-group-item list-group-item-action bg-light">
+                            <a href="{% url 'dashboard:all_labs' %}" class="list-group-item list-group-item-action">
                                 Lab Info
                             </a>
-                            <a href="{% url 'notifier:messages' %}" class="list-group-item list-group-item-action bg-light">
+                            <a href="{% url 'notifier:messages' %}" class="list-group-item list-group-item-action">
                                 Inbox
                             </a>
                         </div>
                     </div>
                 </div>
                 {% endif %}
-                <div id="bsm">{% bootstrap_messages %}</div>
+                {% if messages %}
+                    <div id="bsm" class="mt-4">{% bootstrap_messages %}</div>
+                {% endif %}
                 <!-- Content block placed here -->
                 {% block content %}
                 {% endblock content %}
index 99de747..fea2bb6 100644 (file)
 {% endblock %}
 
 {% block content %}
-
-<div class="container-fluid">
-    <div class="row">
-        <div class="col-12 col-lg-5">
-            <div class="card mb-4">
-                <div class="card-header d-flex">
-                    <h4 class="d-inline">Overview</h4>
-                    <button data-toggle="collapse" data-target="#panel_overview" class="btn btn-outline-secondary ml-auto">Expand</button>
-                </div>
-                <div class="collapse show" id="panel_overview">
-                    <div class="card-body">
-                        <table class="table">
-                            <tr>
-                                <td>Purpose</td>
-                                <td>{{ booking.purpose }}</td>
-                            </tr>
-                            <tr>
-                                <td>Project</td>
-                                <td>{{ booking.project }}</td>
-                            </tr>
-                            <tr>
-                                <td>Start Time</td>
-                                <td>{{ booking.start }}</td>
-                            </tr>
-                            <tr>
-                                <td>End Time</td>
-                                <td>{{ booking.end }}</td>
-                            </tr>
-                            <tr>
-                                <td>Pod Definition</td>
-                                <td>{{ booking.resource.template }}</td>
-                            </tr>
-                            <tr>
-                                <td>Pod Configuration</td>
-                                <td>{{ booking.config_bundle }}</td>
-                            </tr>
-                            <tr>
-                                <td>Lab Deployed At</td>
-                                <td>{{ booking.lab }}</td>
-                            </tr>
-                        </table>
-                    </div>
-                </div>
+<div class="row">
+    <div class="col-12 col-lg-5">
+        <div class="card mb-3">
+            <div class="card-header d-flex">
+                <h4 class="d-inline">Overview</h4>
+                <button data-toggle="collapse" data-target="#panel_overview" class="btn btn-outline-secondary ml-auto">Expand</button>
             </div>
-            <div class="row">
-                <div class="col-lg-12">
-                    <div class="card">
-                        <div class="card-header d-flex">
-                            <h4 class="d-inline">Pod</h4>
-                            <button data-toggle="collapse" data-target="#pod_panel" class="btn btn-outline-secondary ml-auto">Expand</button>
-                        </div>
-                        <div class="collapse show" id="pod_panel">
-                            <div class="card-body">
-                                <table class="table">
-                                {% for host in booking.resource.hosts.all %}
+            <div class="collapse show" id="panel_overview">
+                <table class="table m-0">
+                    <tr>
+                        <td>Purpose</td>
+                        <td>{{ booking.purpose }}</td>
+                    </tr>
+                    <tr>
+                        <td>Project</td>
+                        <td>{{ booking.project }}</td>
+                    </tr>
+                    <tr>
+                        <td>Start Time</td>
+                        <td>{{ booking.start }}</td>
+                    </tr>
+                    <tr>
+                        <td>End Time</td>
+                        <td>{{ booking.end }}</td>
+                    </tr>
+                    <tr>
+                        <td>Pod Definition</td>
+                        <td>{{ booking.resource.template }}</td>
+                    </tr>
+                    <tr>
+                        <td>Pod Configuration</td>
+                        <td>{{ booking.config_bundle }}</td>
+                    </tr>
+                    <tr>
+                        <td>Lab Deployed At</td>
+                        <td>{{ booking.lab }}</td>
+                    </tr>
+                </table>
+            </div>
+        </div>
+        <div class="card my-3">
+            <div class="card-header d-flex">
+                <h4 class="d-inline">Pod</h4>
+                <button data-toggle="collapse" data-target="#pod_panel" class="btn btn-outline-secondary ml-auto">Expand</button>
+            </div>
+            <div class="collapse show" id="pod_panel">
+                <div class="card-body">
+                    {% for host in booking.resource.hosts.all %}
+                        <h4>{{host.template.resource.name}}</h4>
+                        <div class="overflow-auto">
+                            <table class="table m-0">
+                                <tr>
+                                    <td>Hostname:</td>
+                                    <td>{{host.template.resource.name}}</td>
+                                </tr>
+                                <tr>
+                                    <td>Machine:</td>
+                                    <td>{{host.name}}</td>
+                                </tr>
+                                <tr>
+                                    <td>Role:</td>
+                                    <td>{{host.config.opnfvRole}}</td>
+                                </tr>
+                                <tr>
+                                    <td>Image:</td>
+                                    <td id="host_image_{{host.id}}">
+                                        {{host.config.image}}
+                                        <button
+                                            class="btn btn-primary ml-4"
+                                            data-toggle="modal"
+                                            data-target="#imageModal"
+                                            onclick="set_image_dropdown('{{host.profile.name}}', {{host.id}});"
+                                        >Change/Reset</button></td>
+                                </tr>
                                 <tr>
-                                    <td><h4>{{host.template.resource.name}}</h4></td>
+                                    <td>RAM:</td>
+                                    <td>{{host.profile.ramprofile.first.amount}}G,
+                                        {{host.profile.ramprofile.first.channels}} channels</td>
+                                </tr>
+                                <tr>
+                                    <td>CPU:</td>
                                     <td>
-                                        <table class="table">
+                                        <table class="table m-0">
                                             <tr>
-                                                <td>Hostname:</td>
-                                                <td>{{host.template.resource.name}}</td>
+                                                <td>Arch:</td>
+                                                <td>{{host.profile.cpuprofile.first.architecture}}</td>
                                             </tr>
                                             <tr>
-                                                <td>Profile:</td>
-                                                <td>{{host.name}}</td>
+                                                <td>Cores:</td>
+                                                <td>{{host.profile.cpuprofile.first.cores}}</td>
                                             </tr>
                                             <tr>
-                                                <td>Role:</td>
-                                                <td>{{host.config.opnfvRole}}</td>
-                                            </tr>
-                                            <tr>
-                                                <td>Image:</td>
-                                                <td id="host_image_{{host.id}}">
-                                                    {{host.config.image}}
-                                                    <button
-                                                        class="btn btn-primary ml-4"
-                                                        data-toggle="modal"
-                                                        data-target="#imageModal"
-                                                        onclick="set_image_dropdown('{{host.profile.name}}', {{host.id}});"
-                                                    >Change/Reset</button></td>
-                                            </tr>
-                                            <tr>
-                                                <td>RAM:</td>
-                                                <td>{{host.profile.ramprofile.first.amount}}G,
-                                                    {{host.profile.ramprofile.first.channels}} channels</td>
+                                                <td>Sockets:</td>
+                                                <td>{{host.profile.cpuprofile.first.cpus}}</td>
                                             </tr>
+                                        </table>
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td>DISK:</td>
+                                    <td>
+                                        <table class="table m-0">
                                             <tr>
-                                                <td>CPU:</td>
-                                                <td>
-                                                    <table class="table">
-                                                        <tr>
-                                                            <td>Arch:</td>
-                                                            <td>{{host.profile.cpuprofile.first.architecture}}</td>
-                                                        </tr>
-                                                        <tr>
-                                                            <td>Cores:</td>
-                                                            <td>{{host.profile.cpuprofile.first.cores}}</td>
-                                                        </tr>
-                                                        <tr>
-                                                            <td>Sockets:</td>
-                                                            <td>{{host.profile.cpuprofile.first.cpus}}</td>
-                                                        </tr>
-                                                    </table>
-                                                </td>
+                                                <td>Size:</td>
+                                                <td>{{host.profile.storageprofile.first.size}} GiB</td>
                                             </tr>
                                             <tr>
-                                                <td>DISK:</td>
-                                                <td>
-                                                    <table class="table">
-                                                        <tr>
-                                                            <td>Size:</td>
-                                                            <td>{{host.profile.storageprofile.first.size}} GiB</td>
-                                                        </tr>
-                                                        <tr>
-                                                            <td>Type:</td>
-                                                            <td>{{host.profile.storageprofile.first.media_type}}</td>
-                                                        </tr>
-                                                        <tr>
-                                                            <td>Mount Point:</td>
-                                                            <td>{{host.profile.storageprofile.first.name}}</td>
-                                                        </tr>
-                                                    </table>
-                                                </td>
+                                                <td>Type:</td>
+                                                <td>{{host.profile.storageprofile.first.media_type}}</td>
                                             </tr>
                                             <tr>
-                                                <td>Interfaces:</td>
-                                                <td>
-                                                    <table class="table">
-                                                    {% for intprof in host.profile.interfaceprofile.all %}
-                                                    <tr>
-                                                        <td>
-                                                        <table class="table table-borderless">
-                                                            <tr>
-                                                                <td>Name:</td>
-                                                                <td>{{intprof.name}}</td>
-                                                            </tr>
-                                                            <tr>
-                                                                <td>Speed:</td>
-                                                                <td>{{intprof.speed}}</td>
-                                                            </tr>
-                                                        </table>
-                                                        </td>
-                                                    </tr>
-                                                    {% endfor %}
-                                                    </table>
-                                                </td>
+                                                <td>Mount Point:</td>
+                                                <td>{{host.profile.storageprofile.first.name}}</td>
                                             </tr>
                                         </table>
                                     </td>
-                                {% endfor %}
                                 </tr>
-                                </table>
-                            </div>
+                                <tr>
+                                    <td>Interfaces:</td>
+                                    <td>
+                                        <table class="table m-0">
+                                        {% for intprof in host.profile.interfaceprofile.all %}
+                                        <tr>
+                                            <td>
+                                            <table class="table table-sm table-borderless m-0">
+                                                <tr>
+                                                    <td>Name:</td>
+                                                    <td>{{intprof.name}}</td>
+                                                </tr>
+                                                <tr>
+                                                    <td>Speed:</td>
+                                                    <td>{{intprof.speed}}</td>
+                                                </tr>
+                                            </table>
+                                            </td>
+                                        </tr>
+                                        {% endfor %}
+                                        </table>
+                                    </td>
+                                </tr>
+                            </table>
                         </div>
-                    </div>
+                    {% endfor %}
                 </div>
             </div>
         </div>
-        <div class="col">
-            <div class="card mb-4">
-                <div class="card-header d-flex">
-                    <h4 class="d-inline">Deployment Progress</h4>
-                    <p>These are the different tasks that have to be completed before your deployment is ready</p>
-                    <button data-toggle="collapse" data-target="#panel_tasks" class="btn btn-outline-secondary ml-auto">Expand</button>
-                </div>
-                <div class="collapse show" id="panel_tasks">
-                    <div class="card-body">
-                        <table class="table">
-                            <tr>
-                                <th></th>
-                                <th>Status</th>
-                                <th>Lab Response</th>
-                                <th>Type</th>
-                            </tr>
-                            {% for task in booking.job.get_tasklist %}
-                            <tr>
-                                <td>
-                                    {% if task.status < 100 %}
-                                        <div class="rounded-circle bg-secondary square-20"></div>
-                                    {% elif task.status < 200 %}
-                                        <div class="spinner-border text-primary square-20"></div>
-                                    {% else %}
-                                        <div class="rounded-circle bg-success square-20"></div>
-                                    {% endif %}
-                                </td>
-                                <td>
-                                    {% if task.status < 100 %}
-                                        PENDING
-                                    {% elif task.status < 200 %}
-                                        IN PROGRESS
-                                    {% else %}
-                                        DONE
-                                    {% endif %}
-                                </td>
-                                <td>
-                                    {% if task.message %}
-                                    {% if task.type_str == "Access Task" and user_id != task.config.user.id %}
+    </div>
+    <div class="col">
+        <div class="card mb-3">
+            <div class="card-header d-flex">
+                <h4 class="d-inline">Deployment Progress</h4>
+                <p>These are the different tasks that have to be completed before your deployment is ready</p>
+                <button data-toggle="collapse" data-target="#panel_tasks" class="btn btn-outline-secondary ml-auto">Expand</button>
+            </div>
+            <div class="collapse show" id="panel_tasks">
+                <table class="table m-0">
+                    <tr>
+                        <th></th>
+                        <th>Status</th>
+                        <th>Lab Response</th>
+                        <th>Type</th>
+                    </tr>
+                    {% for task in booking.job.get_tasklist %}
+                    <tr>
+                        <td>
+                            {% if task.status < 100 %}
+                                <div class="rounded-circle bg-secondary square-20"></div>
+                            {% elif task.status < 200 %}
+                                <div class="spinner-border text-primary square-20"></div>
+                            {% else %}
+                                <div class="rounded-circle bg-success square-20"></div>
+                            {% endif %}
+                        </td>
+                        <td>
+                            {% if task.status < 100 %}
+                                PENDING
+                            {% elif task.status < 200 %}
+                                IN PROGRESS
+                            {% else %}
+                                DONE
+                            {% endif %}
+                        </td>
+                        <td>
+                            {% if task.message %}
+                                {% if task.type_str == "Access Task" and user_id != task.config.user.id %}
                                     Message from Lab: <pre>--secret--</pre>
-                                    {% else %}
-                                    Message from Lab: <pre>{{ task.message }}</pre>
-                                    {% endif %}
-                                    {% else %}
-                                    No response provided (yet)
-                                    {% endif %}
-                                </td>
-                                <td>
-                                    {{ task.type_str }}
-                                </td>
-                            </tr>
-                            {% endfor %}
-                        </table>
-                    </div>
-                </div>
+                                {% else %}
+                                    Message from Lab: <pre class="text-break pre-wrap">{{ task.message }}</pre>
+                                {% endif %}
+                            {% else %}
+                                No response provided (yet)
+                            {% endif %}
+                        </td>
+                        <td>
+                            {{ task.type_str }}
+                        </td>
+                    </tr>
+                    {% endfor %}
+                </table>
             </div>
-            <div class="row">
-                <div class="col">
-                    <div class="card">
-                        <div class="card-header d-flex">
-                            <h4 class="d-inline">PDF</h4>
-                            <button data-toggle="collapse" data-target="#pdf_panel" class="btn btn-outline-secondary ml-auto">Expand</button>
-                        </div>
-                        <div class="collapse show" id="pdf_panel">
-                            <div class="card-body p-0">
-                                <pre class="prettyprint lang-yaml m-0 p-4 border-0">
-                                    {{pdf}}
-                                </pre>
-                            </div>
-                        </div>
-                    </div>
+        </div>
+        <div class="card my-3">
+            <div class="card-header d-flex">
+                <h4 class="d-inline">PDF</h4>
+                <button data-toggle="collapse" data-target="#pdf_panel" class="btn btn-outline-secondary ml-auto">Expand</button>
+            </div>
+            <div class="collapse show" id="pdf_panel">
+                <div class="card-body">
+                    <pre class="prettyprint lang-yaml m-0 border-0 text-break pre-wrap">
+{{pdf}}
+                    </pre>
                 </div>
             </div>
         </div>
                     <select class="form-control" id="image_select" name="image_id">
                     </select>
                     <input id="host_id_input" type="hidden" name="host_id">
-                    </input>
                 </form>
             </div>
             <div class="modal-footer d-flex flex-column">
index 6776980..8570f25 100644 (file)
@@ -6,7 +6,6 @@
 {% bootstrap_form_errors form type='non_fields' %}
 <form id="quick_booking_form" action="/booking/quick/" method="POST" class="form">
     {% csrf_token %}
-    <div class="container-fluid">
         <div class="row mx-0 px-0">
             <div class="col-12 mx-0 px-0 mt-2">
                 <p class="my-0">Please select a host type you wish to book. Only available types are shown.</p>
@@ -14,7 +13,7 @@
             </div>
         </div>
         <div class="row">
-            <div class="col-12 col-lg-3 px-1 my-2">
+            <div class="col-12 col-lg-3 my-2">
                 <div class="col border rounded py-2 h-100">
                     {% bootstrap_field form.purpose %}
                     {% bootstrap_field form.project %}
                     </script>
                 </div>
             </div>
-            <div class="col-12 col-lg-3 px-1 my-2">
+            <div class="col-12 col-lg-3 my-2">
                 <div class="col border rounded py-2 h-100">
                     <label>Collaborators</label>
                     {{ form.users }}
                 </div>
             </div>
-            <div class="col-12 col-lg-3 px-1 my-2">
+            <div class="col-12 col-lg-3 my-2">
                 <div class="col border rounded py-2 h-100">
                     {% bootstrap_field form.hostname %}
                     {% bootstrap_field form.image %}
                 </div>
             </div>
-            <div class="col-12 col-lg-3 px-1 my-2">
+            <div class="col-12 col-lg-3 my-2">
                 <div class="col border rounded py-2 h-100">
                     <strong>OPNFV: (Optional)</strong>
                     {% bootstrap_field form.installer %}
                     {% bootstrap_field form.scenario %}
                 </div>
             </div>
-            <div class="col-12 d-flex px-0 mt-2 justify-content-end">
+            <div class="col-12 d-flex mt-2 justify-content-end">
                 <button id="quick_booking_confirm" onclick="submit_form();" type="button" class="btn btn-success">Confirm</button>
             </div>
         </div>
-    </div>
 </form>
 
 <script type="text/javascript">
index ed34731..94239f9 100644 (file)
@@ -41,33 +41,31 @@ function getData(){
 {% endblock %}
 
 {% block content %}
-    <div class="container-fluid">
-        <div class="row">
-                <div class="col-auto">
-                        <p>Number of days to plot: </p>
-                        <div class="form-group d-flex align-content-center">
-                            <input id="number_days" type="number" class="form-control d-inline-block w-auto" min="1" step="1"/>
-                            <button class="btn btn-primary ml-1" onclick="getData();">Submit</button>
-                        </div>
-                </div>
+<div class="row">
+    <div class="col-auto">
+        <p>Number of days to plot: </p>
+        <div class="form-group d-flex align-content-center">
+            <input id="number_days" type="number" class="form-control d-inline-block w-auto" min="1" step="1"/>
+            <button class="btn btn-primary ml-1" onclick="getData();">Submit</button>
         </div>
-        <div class="row">
-            <div class="col-12 col-md-10">
-                <!-- These graphs do NOT get redrawn when the browser size is changed -->
-                <div id="all_graph_container border" class="mw-100">
-                    <div id="booking_graph_wrapper">
-                        <div id="booking_graph_container"/>
-                    </div>
-                    <div id="user_graph_wrapper">
-                        <div id="user_graph_container"/>
-                    </div>
-                </div>
+    </div>
+</div>
+<div class="row">
+    <div class="col-12 col-md-10">
+        <!-- These graphs do NOT get redrawn when the browser size is changed -->
+        <div id="all_graph_container border" class="mw-100">
+            <div id="booking_graph_wrapper">
+                <div id="booking_graph_container"/>
+            </div>
+            <div id="user_graph_wrapper">
+                <div id="user_graph_container"/>
             </div>
         </div>
     </div>
-    <script>
+</div>
+<script>
 var data = {{data|safe}};
 drawGraph(data["booking"], "booking_graph_container", "Active Bookings");
 drawGraph(data["user"], "user_graph_container", "Active Users");
-    </script>
+</script>
 {% endblock content %}
index 6fe0ac1..7e8b25d 100644 (file)
@@ -7,10 +7,7 @@
 
 <form method="POST" id="step_form" class="form">
     {% csrf_token %}
-    <p>Give it a name:</p>
     {% bootstrap_field form.name %}
-
-    <p>And a description:</p>
     {% bootstrap_field form.description %}
 </form>
 
index 3c41caf..a12c5da 100644 (file)
@@ -9,14 +9,14 @@
 {% block content %}
 <div class="row">
     <div class="col-lg-4">
-        <div class="card my-2">
+        <div class="card mb-3">
             <div class="card-header d-flex">
                 <h4>Lab Profile</h4>
                 <button class="btn btn-outline-secondary ml-auto" data-toggle="collapse" data-target="#panel_overview">Expand</button>
             </div>
             <div class="collapse show" id="panel_overview">
-                <div class="card-body">
-                    <table class="table">
+                <div class="overflow-auto">
+                    <table class="table m-0">
                         <tr>
                             <td>Lab Name: </td>
                             <td>{{lab.name}}</td>
                 </div>
             </div>
         </div>
-        <div class="card my-2">
+        <div class="card my-3">
             <div class="card-header d-flex">
                 <h4 class="d-inline-block">Host Profiles</h4>
                 <button data-toggle="collapse" data-target="#profile_panel" class="btn btn-outline-secondary ml-auto">Expand</button>
             </div>
             <div class="collapse show" id="profile_panel">
-                <div class="card-body">
-                    <table class="table">
+                <div class="overflow-auto">
+                    <table class="table m-0">
                         {% for profile in hostprofiles %}
                             <tr>
                                 <td>{{profile.name}}</td>
             </div>
         </div>
 
-
-        <div class="card my-2">
+        <div class="card my-3">
             <div class="card-header d-flex">
                 <h4 class="d-inline">Networking Capabilities</h4>
                 <button data-toggle="collapse" data-target="#network_panel" class="btn btn-outline-secondary ml-auto">Expand</button>
             </div>
 
             <div class="collapse show" id="network_panel">
-                <div class="card-body">
-                    <table class="table">
-                        <tr>
-                            <td>Block Size: (number of VLANs allowed per deployment)</td><td>{{lab.vlan_manager.block_size}}</td>
-                        </tr>
-                        <tr>
-                            <td>Overlapping Vlans Allowed (user can pick which VLANs they wish to use): </td>
-                            <td>{{lab.vlan_manager.allow_overlapping}}</td>
-                        </tr>
-                    </table>
-                </div>
+                <table class="table m-0">
+                    <tr>
+                        <td>Block Size: (number of VLANs allowed per deployment)</td><td>{{lab.vlan_manager.block_size}}</td>
+                    </tr>
+                    <tr>
+                        <td>Overlapping Vlans Allowed (user can pick which VLANs they wish to use): </td>
+                        <td>{{lab.vlan_manager.allow_overlapping|yesno:"Yes,No"}}</td>
+                    </tr>
+                </table>
             </div>
         </div>
-        <div class="card my-2">
+        <div class="card my-3">
             <div class="card-header d-flex">
                 <h4>Images</h4>
                 <button data-toggle="collapse" data-target="#image_panel" class="btn btn-outline-secondary ml-auto">Expand</button>
             </div>
             <div class="collapse show" id="image_panel">
-                <div class="card-body">
-                    <table class="table">
+                <div class="overflow-auto">
+                    <table class="table m-0">
                         <tr>
                             <th>Name</th>
                             <th>Owner</th>
 
     </div>
     <div class="col-lg-8">
-        <div class="card my-2">
+        <div class="card mb-3">
             <div class="card-header d-flex">
                 <h4>Lab Hosts</h4>
                 <button data-toggle="collapse" data-target="#lab_hosts_panel" class="btn btn-outline-secondary ml-auto">Expand</button>
             </div>
 
             <div class="collapse show" id="lab_hosts_panel">
-                <div class="card-body">
-                    <table class="table">
+                <table class="table m-0">
+                    <tr>
+                        <th>Name</th>
+                        <th>Profile</th>
+                        <th>Booked</th>
+                        <th>Working</th>
+                        <th>Vendor</th>
+                    </tr>
+                    {% for host in lab.host_set.all %}
                         <tr>
-                            <th>Name</th>
-                            <th>Profile</th>
-                            <th>Booked</th>
-                            <th>Working</th>
-                            <th>Vendor</th>
+                            <td>{{host.labid}}</td>
+                            <td>{{host.profile}}</td>
+                            <td>{{host.booked|yesno:"Yes,No"}}</td>
+                            {% if host.working %}
+                                <td class="bg-success text-white">Yes</td>
+                            {% else %}
+                                <td class="bg-danger text-white">No</td>
+                            {% endif %}
+                            <td>{{host.vendor}}</td>
                         </tr>
-                        {% for host in lab.host_set.all %}
-                            <tr>
-                                <td>{{host.labid}}</td>
-                                <td>{{host.profile}}</td>
-                                <td>{{host.booked}}</td>
-                                {% if host.working %}
-                                    <td class="bg-success text-white">{{host.working}}</td>
-                                {% else %}
-                                    <td>{{host.working}}</td>
-                                {% endif %}
-                                <td>{{host.vendor}}</td>
-                            </tr>
-                        {% endfor %}
-                    </table>
-                </div>
+                    {% endfor %}
+                </table>
             </div>
         </div>
     </div>
index 2efebfc..ba627bc 100644 (file)
@@ -1,27 +1,26 @@
 {% extends "base.html" %}
 {% block content %}
-<h2>Labs</h2>
 <div class="row">
     {% for lab in labs %}
-    <div class="p-2 col-12 col-md-6 col-lg-4 col-xl-3">
+    <div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-3">
         <div class="card h-100">
             <div class="card-header">
                 <h3 class="mt-2">{{lab.name}}</h3>
             </div>
-            <div class="p-4">
-                <ul class="list-group">
-                    <li class="list-group-item">name: {{lab.name}}</li>
-                    <li class="list-group-item">description: {{lab.description}}</li>
-                    <li class="list-group-item">location: {{lab.location}}</li>
-                    {% if lab.status == 0 %}
-                    <li class="list-group-item">status: Up</li>
-                    {% elif lab.status == 100 %}
-                    <li class="list-group-item">status: Down for Maintenance</li>
-                    {% elif lab.status == 200 %}
-                    <li class="list-group-item">status: Down</li>
-                    {% endif %}
-                </ul>
-                <a class="btn btn-primary mt-4 w-100" href="/lab/{{lab.name}}/">Details</a>
+            <ul class="list-group list-group-flush h-100">
+                <li class="list-group-item">name: {{lab.name}}</li>
+                <li class="list-group-item">description: {{lab.description}}</li>
+                <li class="list-group-item">location: {{lab.location}}</li>
+                {% if lab.status == 0 %}
+                <li class="list-group-item">status: Up</li>
+                {% elif lab.status == 100 %}
+                <li class="list-group-item">status: Down for Maintenance</li>
+                {% elif lab.status == 200 %}
+                <li class="list-group-item">status: Down</li>
+                {% endif %}
+            </ul>
+            <div class="card-footer">
+                <a class="btn btn-primary w-100" href="/lab/{{lab.name}}/">Details</a>
             </div>
         </div>
     </div>
index 72f9e6e..f0fa954 100644 (file)
 </div>
 {% csrf_token %}
 
-<div class="container-fluid">
-    <div class="row">
-        <!-- About us -->
-        <div class="col-12 col-lg-6 mb-4">
-            <h2 class="border-bottom">About Us:</h2>
-            <p>The Lab as a Service (LaaS) project aims to help in the development and testing of LFN projects such as
-                OPNFV
-                by hosting hardware and providing access to the community. Currently, the only participating lab is the
-                University of New Hampshire Interoperability Lab (UNH-IOL).</p>
-            <p>To get started, you can request access to a server at the right. PTL's have the ability to design and
-                book a
-                whole block of servers with customized layer2 networks (e.g. a Pharos Pod). Read more here: <a
-                    href="https://wiki.opnfv.org/display/INF/Lab+as+a+Service+2.0">LaaS Wiki</a></p>
+<div class="row">
+    <!-- About us -->
+    <div class="col-12 col-lg-6 mb-4">
+        <h2 class="border-bottom">About Us</h2>
+        <p>The Lab as a Service (LaaS) project aims to help in the development and testing of LFN projects such as
+            OPNFV
+            by hosting hardware and providing access to the community. Currently, the only participating lab is the
+            University of New Hampshire Interoperability Lab (UNH-IOL).</p>
+        <p>To get started, you can request access to a server at the right. PTL's have the ability to design and
+            book a
+            whole block of servers with customized layer2 networks (e.g. a Pharos Pod). Read more here: <a
+                href="https://wiki.opnfv.org/display/INF/Lab+as+a+Service+2.0">LaaS Wiki</a></p>
+    </div>
+
+    <!-- Get started -->
+    <div class="col-12 col-lg-6 mb-4">
+        <h2 class="border-bottom">Get Started</h2>
+        {% if request.user.is_anonymous %}
+        <h4 class="text-center">
+            To get started, please log in with your <a href="/accounts/login">Linux Foundation Jira account</a>
+        </h4>
+        {% else %}
+        <p>To get started, book a server below:</p>
+        <a class="btn btn-primary btn-lg d-flex flex-column justify-content-center align-content-center border text-white p-4"
+            href="/booking/quick/">
+            Book a Server
+        </a>
+        <p class="mt-4">PTLs can use our advanced options to book multi-node pods. If you are a PTL, you may use the options
+            below:
+        </p>
+        <div class="btn-group-vertical w-100">
+            <button class="btn btn-primary" onclick="create_workflow(0)">Book a Pod</button>
+            <button class="btn btn-primary" onclick="create_workflow(1)">Design a Pod</button>
+            <button class="btn btn-primary" onclick="create_workflow(2)">Configure a Pod</button>
         </div>
-        <!-- Get started -->
-        <div class="col-12 col-lg-6 mb-4">
-            <h2 class="border-bottom">Get Started:</h2>
-            {% if request.user.is_anonymous %}
-            <h4 class="text-center">
-                To get started, please log in with your <a href="/accounts/login">Linux Foundation Jira account</a>
-            </h4>
-            {% else %}
-            <p>To get started, book a server below:</p>
-            <a class="btn btn-primary d-flex flex-column justify-content-center align-content-center border text-white p-4"
-                href="/booking/quick/">
-                <h4>Book a Server</h4>
+        {% endif %}
+    </div>
+
+    <!-- Returning users -->
+    {% if not request.user.is_anonymous %}
+    <div class="col-12 col-lg-6 offset-lg-6 mb-4 mt-lg-4">
+        <h2 class="ht-4 border-bottom">Returning Users</h2>
+        <p>If you're a returning user, some of the following options may be of interest:</p>
+        <div class="btn-group-vertical w-100">
+            <button class="btn btn-primary" onclick="create_workflow(3)">Snapshot a Host</button>
+            <a class="btn btn-primary" href="{% url 'account:my-bookings' %}">
+                My Bookings
             </a>
-            <p class="mt-4">PTLs can use our advanced options to book multi-node pods. If you are a PTL, you may use the options
-                below:
-            </p>
-            <div class="row">
-                <div class="col-12 col-xl-4">
-                    <button class="btn btn-primary w-100" onclick="create_workflow(0)">Book a Pod</button>
-                </div>
-                <div class="col-12 col-xl-4">
-                    <button class="btn btn-primary w-100" onclick="create_workflow(1)">Design a Pod</button>
-                </div>
-                <div class="col-12 col-xl-4">
-                    <button class="btn btn-primary w-100" onclick="create_workflow(2)">Configure a Pod</button>
-                </div>
-            </div>
+            {% if manager == True %}
+            <button class="btn btn-primary" onclick="continue_workflow()">
+                Resume Workflow
+            </button>
             {% endif %}
         </div>
-        <!-- Returning users -->
-        {% if not request.user.is_anonymous %}
-        <div class="col-12 col-lg-6 offset-lg-6 mb-4 mt-lg-4">
-            <h2 class="ht-4 border-bottom">Returning Users:</h2>
-            <p>If you're a returning user, some of the following options may be of interest:</p>
-            <div class="row">
-                <div class="col-12 col-xl-4">
-                    <button class="btn btn-primary w-100" onclick="create_workflow(3)">Snapshot a Host</button>
-                </div>
-                <div class="col-12 col-xl-4">
-                    <a class="btn btn-primary w-100" href="{% url 'account:my-bookings' %}">
-                        My Bookings
-                    </a>
-                </div>
-                {% if manager == True %}
-                    <div class="col-12 col-xl-4">
-                        <button class="btn btn-primary w-100" onclick="continue_workflow()">
-                            Resume Workflow
-                        </button>
-                    </div>
-                {% endif %}
-            </div>
-        </div>
-        {% endif %}
     </div>
+    {% endif %}
 </div>
 
 <div class="hidden_form d-none" id="form_div">
index aee5f23..92aa1ba 100644 (file)
@@ -1,7 +1,7 @@
 <input name="filter_field" id="filter_field" type="hidden"/>
 <div class="row">
     {% for object_class, object_list in display_objects %}
-        <div class="col-12 col-lg-6 d-flex flex-column pt-2 mx-0 px-1">
+        <div class="col-12 col-lg-6 d-flex flex-column pt-2 mx-0">
             <div class="col mx-0 border rounded py-2 flex-grow-1 d-flex flex-column">
                 <div class="w-100">
                     <h4 class="text-capitalize">{{object_class}}</h4>
@@ -36,7 +36,7 @@
 </div>
 
 <div id="dropdown_row" class="row">
-    <div id="dropdown_wrapper" class="col-12 col-lg-6 d-flex flex-column pt-2 mx-0 px-1">
+    <div id="dropdown_wrapper" class="col-12 col-lg-6 d-flex flex-column pt-2 mx-0">
     </div>
 </div>
 <script>
index be51989..f7fd189 100644 (file)
     </div>
 
     <input id="user_field" name="ignore_this" class="form-control" autocomplete="off" type="text" placeholder="{{placeholder}}" value="" oninput="searchable_select_multiple_widget.search(this.value)"
-    {% if disabled %} disabled {% endif %}
-    >
-    </input>
+    {% if disabled %} disabled {% endif %}>
 
     <input type="hidden" id="selector" name="{{ name }}" class="form-control d-none"
-    {% if disabled %} disabled {% endif %}
-    >
-    </input>
+    {% if disabled %} disabled {% endif %}>
 
     <div id="scroll_restrictor" class="d-flex pb-4 position-relative">
         <div id="drop_results" class="list-group w-100 z-2 overflow-auto position-absolute mh-30vh"></div>
index c26d774..0b3262c 100644 (file)
                 <button data-toggle="collapse" data-target="#availableAt" class="btn ml-auto btn-outline-secondary">Expand</button>
             </div>
             <div class="collapse show" id="availableAt">
-                <div class="card-body">
-                    <ul class="list-group">
-                        {% for lab in hostprofile.labs.all %}
-                            <li class="list-group-item">{{lab.name}}</li>
-                        {% endfor %}
-                    </ul>
-                </div>
+                <ul class="list-group list-group-flush">
+                    {% for lab in hostprofile.labs.all %}
+                        <li class="list-group-item">{{lab.name}}</li>
+                    {% endfor %}
+                </ul>
             </div>
         </div>
         <div class="card mb-4">
                 <button data-toggle="collapse" data-target="#cpuPanel" class="btn ml-auto btn-outline-secondary">Expand</button>
             </div>
             <div class="collapse show" id="cpuPanel">
-                <div class="card-body">
-                    <table class="table">
-                        <tr>
-                            <td>Arch:</td>
-                            <td>{{hostprofile.cpuprofile.first.architecture}}</td>
-                        </tr>
-                        <tr>
-                            <td>Cores:</td>
-                            <td>{{hostprofile.cpuprofile.first.cores}}</td>
-                        </tr>
-                        <tr>
-                            <td>Sockets:</td>
-                            <td>{{hostprofile.cpuprofile.first.cpus}}</td>
-                        </tr>
-                    </table>
-                </div>
+                <table class="table">
+                    <tr>
+                        <td>Arch:</td>
+                        <td>{{hostprofile.cpuprofile.first.architecture}}</td>
+                    </tr>
+                    <tr>
+                        <td>Cores:</td>
+                        <td>{{hostprofile.cpuprofile.first.cores}}</td>
+                    </tr>
+                    <tr>
+                        <td>Sockets:</td>
+                        <td>{{hostprofile.cpuprofile.first.cpus}}</td>
+                    </tr>
+                </table>
             </div>
         </div>
         <div class="card mb-4">
                 <button data-toggle="collapse" data-target="#diskPanel" class="btn ml-auto btn-outline-secondary">Expand</button>
             </div>
             <div class="collapse show" id="diskPanel">
-                <div class="card-body">
-                    <table class="table">
-                        <tr>
-                            <td>Size:</td>
-                            <td>{{hostprofile.storageprofile.first.size}} GiB</td>
-                        </tr>
-                        <tr>
-                            <td>Type:</td>
-                            <td>{{hostprofile.storageprofile.first.media_type}}</td>
-                        </tr>
-                        <tr>
-                            <td>Mount Point:</td>
-                            <td>{{hostprofile.storageprofile.first.name}}</td>
-                        </tr>
-                    </table>
-                </div>
+                <table class="table">
+                    <tr>
+                        <td>Size:</td>
+                        <td>{{hostprofile.storageprofile.first.size}} GiB</td>
+                    </tr>
+                    <tr>
+                        <td>Type:</td>
+                        <td>{{hostprofile.storageprofile.first.media_type}}</td>
+                    </tr>
+                    <tr>
+                        <td>Mount Point:</td>
+                        <td>{{hostprofile.storageprofile.first.name}}</td>
+                    </tr>
+                </table>
             </div>
         </div>
     </div>
                 <button data-toggle="collapse" data-target="#interfacePanel" class="btn ml-auto btn-outline-secondary">Expand</button>
             </div>
             <div class="collapse show" id="interfacePanel">
-                <div class="card-body">
-                    <table class="table">
-                        <thead>
-                            <tr>
-                                <th>Name</th>
-                                <th>Speed</th>
-                            </tr>
-                        </thead>
-                        <tbody>
-                            {% for intprof in hostprofile.interfaceprofile.all %}
-                            <tr>
-                                <td>{{intprof.name}}</td>
-                                <td>{{intprof.speed}}</td>
-                            </tr>
-                            {% endfor %}
-                        </tbody>
-                    </table>
-                </div>
+                <table class="table">
+                    <thead>
+                        <tr>
+                            <th>Name</th>
+                            <th>Speed</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {% for intprof in hostprofile.interfaceprofile.all %}
+                        <tr>
+                            <td>{{intprof.name}}</td>
+                            <td>{{intprof.speed}}</td>
+                        </tr>
+                        {% endfor %}
+                    </tbody>
+                </table>
             </div>
         </div>
     </div>
index 69b7231..9fc50ce 100644 (file)
                 <a href="profiles/{{ host.profile.id }}">{{ host.profile }}</a>
             </td>
             <td>
-                {{ host.booked }}
+                {{ host.booked|yesno:"Yes,No" }}
             </td>
             <td>
-                {{ host.working }}
+                {{ host.working|yesno:"Yes,No" }}
             </td>
         </tr>
     {% endfor %}
index efd8a09..573b996 100644 (file)
@@ -10,7 +10,7 @@ with your current configuration will become unavailable.</p>
 <h4>NOTE: Only PTL's are able to create multi-node PODs. See
     <a href="https://wiki.opnfv.org/display/INF/Lab-as-a-Service+at+the+UNH-IOL">here</a>
     for more details</h4>
-<form id="step_form" method="post" class="px-3">
+<form id="step_form" method="post">
     {% csrf_token %}
     {{form.filter_field|default:"<p>No Form</p>"}}
 </form>
index b6a17a9..6fef065 100644 (file)
@@ -8,7 +8,7 @@
 <form id="step_form" method="post">
     {% csrf_token %}
     <table class="px-4">
-        {% bootstrap_form form field_class="px-4" label_class="px-4 mt-2" %}
+        {% bootstrap_form form %}
     </table>
 </form>
 {% endblock content %}
index d0a28ed..a6810de 100644 (file)
 
 <!-- Calls the main function after the page has loaded. Container is dynamically created. -->
 {% block content %}
-    <div class="row p-0 w-100 mx-0 position-absolute overflow-hidden topToBottom">
-        <div id="graphParent" class="col px-0">
-            <div class="row">
-                <div class="col pr-0">
-                    <div id="toolbarContainer" class="bg-light pl-4"></div>
+<div class="h-100 w-100 position-relative">
+    <div class="h-100 w-100 position-absolute overflow-hidden">
+        <div class="row h-100">
+            <div id="graphParent" class="col h-100">
+                <div class="d-flex bg-light border">
+                    <div id="toolbarContainer"></div>
+                    <div class="ml-4 text-info">Hold right click to drag</div>
                 </div>
+                <!-- Creates a container for the sidebar -->
+                <div id="graphContainer" class="border h-100"></div>
             </div>
-            <!-- Creates a container for the sidebar -->
-            <div id="graphContainer"></div>
-        </div>
 
-        <div id="network_select" class="p-0 w-25 ml-auto col-2">
-            <div class="px-0 mb-2">
+            <div id="network_select" class="col-2">
                 <!-- Creates a container for the outline -->
-                <div id="outlineContainer" class="border"></div>
-            </div>
-            <div>
-                <button id="btn_add_network" type="button" class="btn btn-primary w-100" onclick="network_step.newNetworkWindow();">Add Network</button>
+                <div id="outlineContainer" class="border mb-2"></div>
+                <button id="btn_add_network" type="button" class="btn btn-primary w-100 mb-2" onclick="network_step.newNetworkWindow();">Add Network</button>
+                <ul id="network_list" class="list-group">
+                </ul>
+                <button type="button" class="d-none" onclick="network_step.submitForm();">Submit</button>
             </div>
-            <ul id="network_list" class="list-group">
-            </ul>
-            <button type="button" class="d-none" onclick="network_step.submitForm();">Submit</button>
         </div>
     </div>
-    <form id="step_form" method="post">
-        {% csrf_token %}
-        <input type="hidden" id="hidden_xml_input" name="xml" />
-    </form>
-    <script>
-        //gather context data
-        let debug = false;
-        {% if debug %}
-        debug = true;
-        {% endif %}
+</div>
+<form id="step_form" method="post">
+    {% csrf_token %}
+    <input type="hidden" id="hidden_xml_input" name="xml">
+</form>
+<script>
+    //gather context data
+    let debug = false;
+    {% if debug %}
+    debug = true;
+    {% endif %}
 
-        let xml = '';
-        {% if xml %}
-        xml = '{{xml|safe}}';
-        {% endif %}
+    let xml = '';
+    {% if xml %}
+    xml = '{{xml|safe}}';
+    {% endif %}
 
-        let hosts = [];
-        {% for host in hosts %}
-        hosts.push({{host|safe}});
-        {% endfor %}
+    let hosts = [];
+    {% for host in hosts %}
+    hosts.push({{host|safe}});
+    {% endfor %}
 
-        let added_hosts = [];
-        {% for host in added_hosts %}
-        added_hosts.push({{host|safe}});
-        {% endfor %}
+    let added_hosts = [];
+    {% for host in added_hosts %}
+    added_hosts.push({{host|safe}});
+    {% endfor %}
 
-        let removed_host_ids = {{removed_hosts|safe}};
+    let removed_host_ids = {{removed_hosts|safe}};
 
-        network_step = new NetworkStep(
-            debug,
-            xml,
-            hosts,
-            added_hosts,
-            removed_host_ids,
-            document.getElementById('graphContainer'),
-            document.getElementById('outlineContainer'),
-            document.getElementById('toolbarContainer'),
-            document.getElementById('sidebarContainer')
-        );
-        form_submission_callbacks.push(() => network_step.prepareForm());
-    </script>
+    network_step = new NetworkStep(
+        debug,
+        xml,
+        hosts,
+        added_hosts,
+        removed_host_ids,
+        document.getElementById('graphContainer'),
+        document.getElementById('outlineContainer'),
+        document.getElementById('toolbarContainer'),
+        document.getElementById('sidebarContainer')
+    );
+    form_submission_callbacks.push(() => network_step.prepareForm());
+</script>
 {% endblock content %}
 {% block onleave %}
 network_step.submitForm();
index 4ae2ff3..bb13ab7 100644 (file)
@@ -30,7 +30,7 @@
     </div>
 </div>
 <!-- Top header -->
-<div class="row px-4">
+<div class="row">
     <div class="col">
         <div id="iframe_header" class="row view-header">
             <div class="col-lg-12">
         <button id="cancel_btn" class="btn btn-danger ml-auto" onclick="pop_workflow()">Cancel</button>
     </div>
 </div>
-<div class="row d-flex flex-column flex-grow-1">
-    <div class="container-fluid d-flex flex-column h-100">
-        <div class="row d-flex flex-grow-1 p-4">
-            <div class="col-12 d-flex flex-grow-1 px-0">
-                <div id="formContainer" class="h-100 w-100"></div>
-            </div>
-        </div>
+<div class="row d-flex flex-column flex-grow-1 mt-3">
+    <div class="col flex-grow-1">
+        <div id="formContainer" class="h-100 w-100"></div>
     </div>
 </div>
 {% csrf_token %}