From 466a8a4dd6734f9deed7ac8ac3b6423a334e5d96 Mon Sep 17 00:00:00 2001
From: Radomir Dopieralski <openstack@sheep.art.pl>
Date: Thu, 18 Dec 2014 11:01:08 +0100
Subject: [PATCH] Show popups on node boxes everywhere

The patch that added popups on node boxes skipped the
progress and live deployment views. This patch makes sure
the popups are displayed on all the node boxes on all views.

It also makes sure that the nodes information is available
even when there is no stack -- for the undeploy progress page.

Change-Id: Ib5bd428f9ba4d7b324c2b0fa4421994c4e3165c7
---
 tuskar_boxes/overview/views.py                | 20 +++++++++-------
 .../tuskar_boxes/js/tuskar.boxes_progress.js  |  9 +++++++-
 .../tuskar_boxes/overview/_node_info.html     | 18 ++++++++++++---
 .../tuskar_boxes/overview/_node_info_js.html  | 23 +++++++++++++++++++
 .../tuskar_boxes/overview/index.html          |  6 +----
 .../overview/role_nodes_edit.html             |  6 +----
 .../overview/role_nodes_status.html           | 16 ++-----------
 7 files changed, 62 insertions(+), 36 deletions(-)
 create mode 100644 tuskar_boxes/templates/tuskar_boxes/overview/_node_info_js.html

diff --git a/tuskar_boxes/overview/views.py b/tuskar_boxes/overview/views.py
index bb97cf0..a628f07 100644
--- a/tuskar_boxes/overview/views.py
+++ b/tuskar_boxes/overview/views.py
@@ -16,6 +16,7 @@ import collections
 
 from django.core.urlresolvers import reverse
 import django.utils.text
+from django.utils.translation import ugettext_lazy as _
 from openstack_dashboard.api import base as api_base
 
 from tuskar_ui import api
@@ -66,6 +67,8 @@ def _node_data(request, nodes):
             'uuid': node.uuid,
             'role_name': role.name if role else '',
             'role_slug': django.utils.text.slugify(role.name) if role else '',
+            'node_title': unicode(_("{0} node").format(role.name.title())
+                                  if role else _("Free node")),
             'state': node.state,
             'state_slug': django.utils.text.slugify(unicode(node.state)),
             'state_icon': NODE_STATE_ICON.get(node.state,
@@ -101,12 +104,20 @@ class IndexView(views.IndexView):
     def get_data(self, request, context, *args, **kwargs):
         data = super(IndexView, self).get_data(request, context,
                                                *args, **kwargs)
+        nodes = list(_node_data(
+            request, api.node.Node.list(request, maintenance=False),
+        ))
+        nodes.sort(key=lambda node: node.get('role_name'))
+        nodes.reverse()
+        data['nodes'] = nodes
+
         if not data['stack']:
             roles = data['roles']
             free_roles = []
             flavor_roles = {}
             for role in roles:
-                role['flavor_field'] = data['form'][role['id'] + '-flavor']
+                if 'form' in data:
+                    role['flavor_field'] = data['form'][role['id'] + '-flavor']
                 flavor = role['role'].flavor(data['plan'])
                 if flavor:
                     role['flavor_name'] = flavor.name
@@ -121,13 +132,6 @@ class IndexView(views.IndexView):
             data['flavors'] = list(
                 _flavor_data(self.request, flavors, flavor_roles))
         else:
-            nodes = list(_node_data(
-                request, api.node.Node.list(request, maintenance=False),
-            ))
-
-            nodes.sort(key=lambda node: node.get('role_name'))
-            nodes.reverse()
-            data['nodes'] = nodes
             distribution = collections.Counter()
 
             for node in nodes:
diff --git a/tuskar_boxes/static/tuskar_boxes/js/tuskar.boxes_progress.js b/tuskar_boxes/static/tuskar_boxes/js/tuskar.boxes_progress.js
index 7cfc299..5f98e1b 100644
--- a/tuskar_boxes/static/tuskar_boxes/js/tuskar.boxes_progress.js
+++ b/tuskar_boxes/static/tuskar_boxes/js/tuskar.boxes_progress.js
@@ -7,7 +7,14 @@ tuskar.boxes_progress = function () {
   };
 
   module.update_progress = function (data) {
-    $('div.boxes-nodes').html(module.nodes_template.render(data));
+    var $nodes = $('div.boxes-nodes');
+    $nodes.html(module.nodes_template.render(data));
+    $nodes.find('div.boxes-node').popover({
+      'trigger': 'hover',
+      'placement': 'auto',
+      'delay': 500,
+      'html': true
+    });
   };
 
   // Attach to the original update procedure.
diff --git a/tuskar_boxes/templates/tuskar_boxes/overview/_node_info.html b/tuskar_boxes/templates/tuskar_boxes/overview/_node_info.html
index 7740605..23d4d70 100644
--- a/tuskar_boxes/templates/tuskar_boxes/overview/_node_info.html
+++ b/tuskar_boxes/templates/tuskar_boxes/overview/_node_info.html
@@ -1,8 +1,18 @@
 {% load i18n %}
 <div
-  class="boxes-node boxes-role-none"
+  class="boxes-nodes
+  {% if nodes|length >= 100 %}
+    boxes-nodes-small
+  {% elif nodes|length >= 25 %}
+    boxes-nodes-medium
+  {% endif %}
+  {{ classes }}"
+>
+{% for node in nodes %}{% spaceless %}
+<div
+  class="boxes-node boxes-role-{{ node.role_slug }}"
   data-toggle="popover"
-  title="{{ node.role_name|title|default:_('Free') }} {% trans 'node' %}"
+  title="{{ node.node_title }}"
   data-content="<dl>
     <dt>{% trans "Node UUID" %}</dt>
     <dd>{{ node.uuid }}</dd>
@@ -15,4 +25,6 @@
     <dt>{% trans "HDD (GB)" %}</dt>
     <dd>{{ node.local_gb }}</dd>
   </dl>"
->free</div>
+  ><i class="fa fa-lg {{ node.state_icon }}"></i></div>
+{% endspaceless %}{% endfor %}
+</div>
diff --git a/tuskar_boxes/templates/tuskar_boxes/overview/_node_info_js.html b/tuskar_boxes/templates/tuskar_boxes/overview/_node_info_js.html
new file mode 100644
index 0000000..0df96b8
--- /dev/null
+++ b/tuskar_boxes/templates/tuskar_boxes/overview/_node_info_js.html
@@ -0,0 +1,23 @@
+{% load i18n %}
+{% load horizon %}
+<script type="text/html" id="nodes-template">{% spaceless %}{% jstemplate %}
+[[#nodes]]
+  <div
+    class="boxes-node boxes-role-[[ role_slug ]] status-[[ state_slug ]]"
+    data-toggle="popover"
+    title="[[ node_title ]]"
+    data-content="<dl>
+      <dt>{% trans "Node UUID" %}</dt>
+      <dd>[[ uuid ]]</dd>
+      <dt>{% trans "Architecture" %}</dt>
+      <dd>[[ cpu_arch ]]</dd>
+      <dt>{% trans "CPUs" %}</dt>
+      <dd>[[ cpus ]]</dt>
+      <dt>{% trans "RAM (MB)" %}</dt>
+      <dd>[[ memory_mb ]]</dd>
+      <dt>{% trans "HDD (GB)" %}</dt>
+      <dd>[[ local_gb ]]</dd>
+    </dl>"
+  ><i class="fa fa-lg [[ state_icon ]]"></i></div>
+[[/nodes]]
+{% endjstemplate %}{% endspaceless %}</script>
diff --git a/tuskar_boxes/templates/tuskar_boxes/overview/index.html b/tuskar_boxes/templates/tuskar_boxes/overview/index.html
index 346f2fa..1149312 100644
--- a/tuskar_boxes/templates/tuskar_boxes/overview/index.html
+++ b/tuskar_boxes/templates/tuskar_boxes/overview/index.html
@@ -67,11 +67,7 @@
                 {% endif %}
             {% endfor %}
         </div>
-        <div class="boxes-nodes {% if nodes|length >= 100 %}boxes-nodes-small{% elif nodes|length >= 25 %}boxes-nodes-medium{% endif %}">
-            {% for node in nodes %}{% spaceless %}
-                <div class="boxes-node boxes-role-{{ node.role_slug }}"></div>
-            {% endspaceless %}{% endfor %}
-        </div>
+        {% include "tuskar_boxes/overview/_node_info.html" with nodes=nodes %}
     {% endif %}
   </div>
 </div>
diff --git a/tuskar_boxes/templates/tuskar_boxes/overview/role_nodes_edit.html b/tuskar_boxes/templates/tuskar_boxes/overview/role_nodes_edit.html
index 29869d3..283d5f4 100644
--- a/tuskar_boxes/templates/tuskar_boxes/overview/role_nodes_edit.html
+++ b/tuskar_boxes/templates/tuskar_boxes/overview/role_nodes_edit.html
@@ -58,11 +58,7 @@
               </ul>
             </div>
         </div>
-        <div class="col-xs-7 boxes-nodes {% if flavor.nodes|length >= 100 %}boxes-nodes-small{% elif flavor.nodes|length >= 25 %}boxes-nodes-medium{% endif %}">
-            {% for node in flavor.nodes %}{% spaceless %}
-            {% include "tuskar_boxes/overview/_node_info.html" with node=node %}
-            {% endspaceless %}{% endfor %}
-        </div>
+        {% include "tuskar_boxes/overview/_node_info.html" with nodes=flavor.nodes classes="col-xs-7" %}
     </div>
 </div>
 {% endfor %}
diff --git a/tuskar_boxes/templates/tuskar_boxes/overview/role_nodes_status.html b/tuskar_boxes/templates/tuskar_boxes/overview/role_nodes_status.html
index f8ff324..656cbd9 100644
--- a/tuskar_boxes/templates/tuskar_boxes/overview/role_nodes_status.html
+++ b/tuskar_boxes/templates/tuskar_boxes/overview/role_nodes_status.html
@@ -20,13 +20,7 @@
       </div>
   {% endfor %}
   </div>
-  <div class="col-xs-7 boxes-nodes {% if nodes|length >= 100 %}boxes-nodes-small{% elif nodes|length >= 25 %}boxes-nodes-medium{% endif %}">
-      {% for node in nodes %}{% spaceless %}
-      <div class="boxes-node boxes-role-{{ node.role_slug }} status-{{ node.state_slug }}" title="{{ node.uuid }}">
-        <i class="fa fa-lg {{ node.state_icon }}"></i>
-      </div>
-      {% endspaceless %}{% endfor %}
-  </div>
+  {% include "tuskar_boxes/overview/_node_info.html" with nodes=nodes classes="col-xs-7" %}
 </div>
 
 <script type="text/html" id="roles-template">{% spaceless %}{% jstemplate %}
@@ -46,10 +40,4 @@
     </div>
 [[/roles]]
 {% endjstemplate %}{% endspaceless %}</script>
-<script type="text/html" id="nodes-template">{% spaceless %}{% jstemplate %}
-[[#nodes]]
-  <div class="boxes-node boxes-role-[[ role_slug ]] status-[[ state_slug ]]" title="[[ uuid ]]">
-    <i class="fa fa-lg [[ state_icon ]]"></i>
-  </div>
-[[/nodes]]
-{% endjstemplate %}{% endspaceless %}</script>
+{% include "tuskar_boxes/overview/_node_info_js.html" %}