Commit fc553851 by Bach Dániel

Merge remote-tracking branch 'origin/master' into feature-port-operations

Conflicts:
	circle/dashboard/urls.py
parents c4872897 833d5490
......@@ -64,6 +64,13 @@ CACHES = {
########## END CACHE CONFIGURATION
########## ROSETTA CONFIGURATION
INSTALLED_APPS += (
'rosetta',
)
########## END ROSETTA CONFIGURATION
########## TOOLBAR CONFIGURATION
# https://github.com/django-debug-toolbar/django-debug-toolbar#installation
if get_env_variable('DJANGO_TOOLBAR', 'FALSE') == 'TRUE':
......
......@@ -18,9 +18,11 @@
from django.conf.urls import patterns, include, url
from django.views.generic import TemplateView
from django.conf import settings
from django.contrib import admin
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from circle.settings.base import get_env_variable
from dashboard.views import circle_login, HelpView
......@@ -71,6 +73,13 @@ urlpatterns = patterns(
)
if 'rosetta' in settings.INSTALLED_APPS:
urlpatterns += patterns(
'',
url(r'^rosetta/', include('rosetta.urls')),
)
if get_env_variable('DJANGO_SAML', 'FALSE') == 'TRUE':
urlpatterns += patterns(
'',
......
......@@ -216,7 +216,7 @@ html {
}
#vm-list-rename-name, #node-list-rename-name, #group-list-rename-name {
max-width: 100px;
max-width: 150px;
}
.label-tag {
......@@ -1042,3 +1042,12 @@ textarea[name="new_members"] {
#vm-migrate-node-list li {
cursor: pointer;
}
.group-list-table .actions,
.group-list-table .admin,
.group-list-table .number_of_users,
.group-list-table .pk {
width: 1px;
white-space: nowrap;
text-align: center;
}
......@@ -50,6 +50,21 @@ $(function () {
return false;
});
$('.tx-tpl-ownership').click(function(e) {
$.ajax({
type: 'GET',
url: $('.tx-tpl-ownership').attr('href'),
success: function(data) {
$('body').append(data);
$('#confirmation-modal').modal('show');
$('#confirmation-modal').on('hidden.bs.modal', function() {
$('#confirmation-modal').remove();
});
}
});
return false;
});
$('.template-choose').click(function(e) {
$.ajax({
type: 'GET',
......@@ -428,7 +443,7 @@ function generateVmHTML(pk, name, host, icon, _status, fav, is_last) {
return '<a href="/dashboard/vm/' + pk + '/" class="list-group-item' +
(is_last ? ' list-group-item-last' : '') + '">' +
'<span class="index-vm-list-name">' +
'<i class="fa ' + icon + '" title="' + _status + '"></i> ' + name +
'<i class="fa ' + icon + '" title="' + _status + '"></i> ' + safe_tags_replace(name) +
'</span>' +
'<small class="text-muted"> ' + host + '</small>' +
'<div class="pull-right dashboard-vm-favourite" data-vm="' + pk + '">' +
......@@ -441,14 +456,14 @@ function generateVmHTML(pk, name, host, icon, _status, fav, is_last) {
function generateGroupHTML(url, name, is_last) {
return '<a href="' + url + '" class="list-group-item real-link' + (is_last ? " list-group-item-last" : "") +'">'+
'<i class="fa fa-users"></i> '+ name +
'<i class="fa fa-users"></i> '+ safe_tags_replace(name) +
'</a>';
}
function generateNodeHTML(name, icon, _status, url, is_last) {
return '<a href="' + url + '" class="list-group-item real-link' + (is_last ? ' list-group-item-last' : '') + '">' +
'<span class="index-node-list-name">' +
'<i class="fa ' + icon + '" title="' + _status + '"></i> ' + name +
'<i class="fa ' + icon + '" title="' + _status + '"></i> ' + safe_tags_replace(name) +
'</span>' +
'<div style="clear: both;"></div>' +
'</a>';
......@@ -456,7 +471,7 @@ function generateNodeHTML(name, icon, _status, url, is_last) {
function generateNodeTagHTML(name, icon, _status, label , url) {
return '<a href="' + url + '" class="label ' + label + '" >' +
'<i class="fa ' + icon + '" title="' + _status + '"></i> ' + name +
'<i class="fa ' + icon + '" title="' + _status + '"></i> ' + safe_tags_replace(name) +
'</a> ';
}
......@@ -678,3 +693,18 @@ function getParameterByName(name) {
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
var tagsToReplace = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;'
};
function replaceTag(tag) {
return tagsToReplace[tag] || tag;
}
function safe_tags_replace(str) {
return str.replace(/[&<>]/g, replaceTag);
}
$(function() {
$(".disk-list-disk-percentage").each(function() {
var disk = $(this).data("disk-pk");
var element = $(this);
refreshDisk(disk, element);
});
});
function refreshDisk(disk, element) {
$.get("/dashboard/disk/" + disk + "/status/", function(result) {
if(result.percentage == null || result.failed == "True") {
location.reload();
} else {
var diff = result.percentage - parseInt(element.html());
var refresh = 5 - diff;
refresh = refresh < 1 ? 1 : (result.percentage == 0 ? 1 : refresh);
if(isNaN(refresh)) refresh = 2; // this should not happen
element.html(result.percentage);
setTimeout(function() {refreshDisk(disk, element)}, refresh * 1000);
}
});
}
......@@ -14,7 +14,7 @@
data: {'new_name': name},
headers: {"X-CSRFToken": getCookie('csrftoken')},
success: function(data, textStatus, xhr) {
$("#group-details-h1-name").html(data['new_name']).show();
$("#group-details-h1-name").text(data['new_name']).show();
$('#group-details-rename').hide();
// addMessage(data['message'], "success");
},
......
......@@ -3,6 +3,7 @@ $(function() {
$("#group-list-rename-button, .group-details-rename-button").click(function() {
$("#group-list-column-name", $(this).closest("tr")).hide();
$("#group-list-rename", $(this).closest("tr")).css('display', 'inline');
$("#group-list-rename").find("input").select();
});
/* rename ajax */
......
......@@ -15,7 +15,7 @@ $(function() {
data: {'new_name': name},
headers: {"X-CSRFToken": getCookie('csrftoken')},
success: function(data, textStatus, xhr) {
$("#node-details-h1-name").html(data['new_name']).show();
$("#node-details-h1-name").text(data['new_name']).show();
$('#node-details-rename').hide();
// addMessage(data['message'], "success");
},
......
......@@ -12,40 +12,6 @@ $(function() {
tr.removeClass('danger');
}
/* rename */
$("#node-list-rename-button, .node-details-rename-button").click(function() {
$("#node-list-column-name", $(this).closest("tr")).hide();
$("#node-list-rename", $(this).closest("tr")).css('display', 'inline');
});
/* rename ajax */
$('.node-list-rename-submit').click(function() {
var row = $(this).closest("tr")
var name = $('#node-list-rename-name', row).val();
var url = '/dashboard/node/' + row.children("td:first-child").text().replace(" ", "") + '/';
$.ajax({
method: 'POST',
url: url,
data: {'new_name': name},
headers: {"X-CSRFToken": getCookie('csrftoken')},
success: function(data, textStatus, xhr) {
$("#node-list-column-name", row).html(
$("<a/>", {
'class': "real-link",
href: "/dashboard/node/" + data['node_pk'] + "/",
text: data['new_name']
})
).show();
$('#node-list-rename', row).hide();
// addMessage(data['message'], "success");
},
error: function(xhr, textStatus, error) {
addMessage("Error during renaming!", "danger");
}
});
return false;
});
function statuschangeSuccess(tr){
var tspan=tr.children('.enabled').children();
......
......@@ -88,18 +88,21 @@ class GroupListTable(Table):
number_of_users = TemplateColumn(
orderable=False,
verbose_name=_("Number of users"),
template_name='dashboard/group-list/column-users.html',
attrs={'th': {'class': 'group-list-table-admin'}},
)
admin = TemplateColumn(
orderable=False,
verbose_name=_("Admin"),
template_name='dashboard/group-list/column-admin.html',
attrs={'th': {'class': 'group-list-table-admin'}},
)
actions = TemplateColumn(
orderable=False,
verbose_name=_("Actions"),
attrs={'th': {'class': 'group-list-table-thin'}},
template_code=('{% include "dashboard/group-list/column-'
'actions.html" with btn_size="btn-xs" %}'),
......
......@@ -15,11 +15,11 @@
<form action="{% url "dashboard.views.status-node" pk=object.pk %}" method="POST">
{% csrf_token %}
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Cancel" %}</button>
<input type="hidden" name="change_status" value=""/>
<input type="hidden" name="change_status" value=""/>
<button class="btn btn-warning">{% blocktrans with status=status %}Yes, {{status}}{% endblocktrans %}</button>
</form>
</div>
<div class="clearfix"></div>
<div class="clearfix"></div>
</div>
</div><!-- /.modal-content -->
......
......@@ -7,7 +7,7 @@
{{ text }}
{% else %}
{%blocktrans with object=object%}
Are you sure you want to remove <strong>{{ member }}</strong> from <strong>{{ object }}</strong>?
Are you sure you want to remove <strong>{{ member }}</strong> from <strong>{{ object }}</strong>?
{%endblocktrans%}
{% endif %}
<br />
......
......@@ -23,9 +23,9 @@
<div class="pull-right">
<form action="" method="POST">
{% csrf_token %}
<a class="btn btn-default">{% trans "Back" %}</a>
<input type="hidden" name="flush" value=""/>
<button class="btn btn-warning">{% trans "Yes" %}</button>
<a class="btn btn-default">{% trans "Back" %}</a>
<input type="hidden" name="flush" value=""/>
<button class="btn btn-warning">{% trans "Yes" %}</button>
</form>
</div>
</div>
......
......@@ -26,7 +26,7 @@
{% csrf_token %}
<a class="btn btn-default">{% trans "Cancel" %}</a>
<button type="button" class="btn btn-default" data-dismiss="modal"></button>
<input type="hidden" name="change_status" value=""/>
<input type="hidden" name="change_status" value=""/>
<button class="btn btn-warning">{% blocktrans with status=status %}Yes, {{status}}{% endblocktrans %}</button>
</form>
</div>
......
......@@ -6,15 +6,15 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin">
{% trans "Ownership transfer" %}
{% trans "Ownership transfer" %}
</h3>
</div>
<div class="panel-body">
{% blocktrans with owner=instance.owner name=instance.name id=instance.id%}
<strong>{{ owner }}</strong> offered to take the ownership of
virtual machine <strong>{{name}} ({{id}})</strong>.
Do you accept the responsility of being the host's owner?
{% endblocktrans %}
{% blocktrans with owner=instance.owner name=instance.name id=instance.id%}
<strong>{{ owner }}</strong> offered to take the ownership of
virtual machine <strong>{{name}} ({{id}})</strong>.
Do you accept the responsility of being the host's owner?
{% endblocktrans %}
<div class="pull-right">
<form action="" method="POST">
{% csrf_token %}
......
{% extends "dashboard/base.html" %}
{% load i18n %}
{% block content %}
<div class="body-content">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin">
{% trans "Ownership transfer" %}
</h3>
</div>
<div class="panel-body">
{% blocktrans with owner=instance.owner name=instance.name id=instance.id%}
<strong>{{ owner }}</strong> offered to take the ownership of
template <strong>{{name}} ({{id}})</strong>.
Do you accept the responsility of being the template's owner?
{% endblocktrans %}
<div class="pull-right">
<form action="" method="POST">
{% csrf_token %}
<a class="btn btn-default" href="{% url "dashboard.index" %}">{% trans "No" %}</a>
<input type="hidden" name="key" value="{{ key }}"/>
<button class="btn btn-danger" type="submit">{% trans "Yes" %}</button>
</form>
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load crispy_forms_tags %}
{% load i18n %}
{% load static %}
{% block title-page %}{{ group.name }} | {% trans "group" %}{% endblock %}
......@@ -8,9 +9,15 @@
<div class="body-content">
<div class="page-header">
<div class="pull-right" style="padding-top: 15px;">
<a title="{% trans "Rename" %}" href="#" class="btn btn-default btn-xs group-details-rename-button"><i class="fa fa-pencil"></i></a>
<a title="{% trans "Delete" %}" data-group-pk="{{ group.pk }}" class="btn btn-default btn-xs real-link group-delete" href="{% url "dashboard.views.delete-group" pk=group.pk %}"><i class="fa fa-trash-o"></i></a>
<a title="{% trans "Help" %}" href="#" class="btn btn-default btn-xs group-details-help-button"><i class="fa fa-question"></i></a>
<a title="{% trans "Rename" %}" href="#" class="btn btn-default btn-xs group-details-rename-button">
<i class="fa fa-pencil"></i>
</a>
<a title="{% trans "Delete" %}" data-group-pk="{{ group.pk }}" class="btn btn-default btn-xs real-link group-delete" href="{% url "dashboard.views.delete-group" pk=group.pk %}">
<i class="fa fa-trash-o"></i>
</a>
<a title="{% trans "Help" %}" href="#" class="btn btn-default btn-xs group-details-help-button">
<i class="fa fa-question"></i>
</a>
</div>
<h1>
<div id="group-details-rename">
......@@ -39,122 +46,125 @@
</li>
</ul>
</div>
</div>
</div><!-- .page-header -->
<div class="row">
<div class="col-md-12" id="group-detail-pane">
<div class="panel panel-default" id="group-detail-panel">
<div class="tab-content panel-body" id="group-form-body">
<form method="POST" action="{% url "dashboard.views.group-update" pk=group.pk %}">
{% csrf_token %}
{% crispy group_profile_form %}
</form>
<hr />
<h3>{% trans "Available objects for this group" %}</h3>
<ul class="dashboard-profile-vm-list fa-ul">
{% for i in vm_objects %}
<li>
<a href="{{ i.get_absolute_url }}">
<i class="fa fa-li {{ i.get_status_icon }}"></i>
{{ i }}
</a>
</li>
{% endfor %}
{% for t in template_objects %}
<li>
<a href="{{ t.get_absolute_url }}">
<i class="fa fa-li fa-puzzle-piece"></i>
{{ t }}
</a>
</li>
{% endfor %}
{% for g in group_objects %}
<li>
<a href="{{ g.get_absolute_url }}">
<i class="fa fa-li fa-users"></i>
{{ g }}
</a>
</li>
{% endfor %}
</ul>
<hr />
<div class="panel panel-default panel-body" id="group-detail-panel">
<form method="POST" action="{% url "dashboard.views.group-update" pk=group.pk %}">
{% csrf_token %}
{% crispy group_profile_form %}
</form>
<hr />
<h3>{% trans "User list"|capfirst %}
{% if perms.auth.add_user %}
<a href="{% url "dashboard.views.create-user" group.pk %}" class="btn btn-success pull-right">{% trans "Create user" %}</a>
{% endif %}
</h3>
<form action="" method="post">{% csrf_token %}
<table class="table table-striped table-with-form-fields table-bordered" id="group-detail-user-table">
<tbody>
<thead><tr><th></th><th>{% trans "Who" %}</th><th>{% trans "Remove" %}</th></tr></thead>
{% for i in users %}
<tr>
<td>
<i class="fa fa-user"></i>
</td>
<td>
<a href="{% url "dashboard.views.profile" username=i.username %}" title="{{ i.username }}"
>{% include "dashboard/_display-name.html" with user=i show_org=True %}</a>
</td>
<td>
<a data-group_pk="{{ group.pk }}" data-member_pk="{{i.pk}}" href="{% url "dashboard.views.remove-user" member_pk=i.pk group_pk=group.pk %}" class="real-link delete-from-group btn btn-link btn-xs"><i class="fa fa-times"><span class="sr-only">{% trans "remove" %}</span></i></a>
</td>
</tr>
{% endfor %}
{% for i in future_users %}
<tr>
<td>
<i class="fa fa-user text-muted"></i>
</td>
<td> {{ i.org_id }} </td>
<td>
<a href="{% url "dashboard.views.remove-future-user" member_org_id=i.org_id group_pk=group.pk %}"
class="real-link btn-link btn-xs">
<i class="fa fa-times"><span class="sr-only">{% trans "remove" %}</span></i></a>
</td>
</tr>
{% endfor %}
<tr>
<td><i class="fa fa-plus"></i></td>
<td colspan="2">
{{addmemberform.new_member}}
</td>
</tr>
</tbody>
</table>
<textarea name="new_members" class="form-control"
placeholder="{% trans "Add multiple users at once (one identifier per line)." %}"></textarea>
<div class="form-actions">
<button type="submit" class="btn btn-success">{% trans "Save" %}</button>
</div>
</form>
<h3>{% trans "Available objects for this group" %}</h3>
<ul class="dashboard-profile-vm-list fa-ul">
{% for i in vm_objects %}
<li>
<a href="{{ i.get_absolute_url }}">
<i class="fa fa-li {{ i.get_status_icon }}"></i>
{{ i }}
</a>
</li>
{% endfor %}
{% for t in template_objects %}
<li>
<a href="{{ t.get_absolute_url }}">
<i class="fa fa-li fa-puzzle-piece"></i>
{{ t }}
</a>
</li>
{% endfor %}
{% for g in group_objects %}
<li>
<a href="{{ g.get_absolute_url }}">
<i class="fa fa-li fa-users"></i>
{{ g }}
</a>
</li>
{% endfor %}
</ul>
<hr />
<hr />
<h3 id="group-detail-perm-header">{% trans "Access permissions"|capfirst %}</h3>
{% include "dashboard/_manage_access.html" with table_id="group-detail-perm-table" %}
{% if user.is_superuser %}
<hr />
<h3>
{% trans "User list" %}
{% if perms.auth.add_user %}
<a href="{% url "dashboard.views.create-user" group.pk %}" class="btn btn-success pull-right">
{% trans "Create user" %}
</a>
{% endif %}
</h3>
<form action="" method="post">{% csrf_token %}
<table class="table table-striped table-with-form-fields table-bordered" id="group-detail-user-table">
<tbody>
<thead><tr><th></th><th>{% trans "Who" %}</th><th>{% trans "Remove" %}</th></tr></thead>
{% for i in users %}
<tr>
<td>
<i class="fa fa-user"></i>
</td>
<td>
<a href="{% url "dashboard.views.profile" username=i.username %}" title="{{ i.username }}"
>{% include "dashboard/_display-name.html" with user=i show_org=True %}</a>
</td>
<td>
<a data-group_pk="{{ group.pk }}" data-member_pk="{{i.pk}}" href="{% url "dashboard.views.remove-user" member_pk=i.pk group_pk=group.pk %}" class="real-link delete-from-group btn btn-link btn-xs"><i class="fa fa-times">
<span class="sr-only">{% trans "remove" %}</span></i>
</a>
</td>
</tr>
{% endfor %}
{% for i in future_users %}
<tr>
<td>
<i class="fa fa-user text-muted"></i>
</td>
<td> {{ i.org_id }} </td>
<td>
<a href="{% url "dashboard.views.remove-future-user" member_org_id=i.org_id group_pk=group.pk %}"
class="real-link btn-link btn-xs">
<i class="fa fa-times"><span class="sr-only">{% trans "remove" %}</span></i></a>
</td>
</tr>
{% endfor %}
<tr>
<td><i class="fa fa-plus"></i></td>
<td colspan="2">
{{addmemberform.new_member}}
</td>
</tr>
</tbody>
</table>
<textarea name="new_members" class="form-control"
placeholder="{% trans "Add multiple users at once (one identifier per line)." %}"></textarea>
<div class="form-actions">
<button type="submit" class="btn btn-success">{% trans "Save" %}</button>
</div>
</form>
<hr />
<h3 id="group-detail-perm-header">{% trans "Access permissions" %}</h3>
{% include "dashboard/_manage_access.html" with table_id="group-detail-perm-table" %}
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
{{ group_perm_form.media }}
{% if user.is_superuser %}
<hr />
<h3>{% trans "Group permissions" %}</h3>
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
{{ group_perm_form.media }}
<div id="group-detail-permissions">
{% crispy group_perm_form %}
</div>
<h3>{% trans "Group permissions" %}</h3>
<link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css" />
<div id="group-detail-permissions">
{% crispy group_perm_form %}
</div>
{% endif %}
</div>
</div>
<link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css" />
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script type="text/javascript" src="{% static "dashboard/group-details.js" %}"></script>
{% endblock %}
......@@ -10,10 +10,10 @@
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin"><i class="fa fa-group"></i> Your groups</h3>
<h3 class="no-margin"><i class="fa fa-group"></i> {% trans "Groups" %}</h3>
</div>
<div class="panel-body">
<div id="table_container">
<div id="table_container">
<div id="rendered_table" class="panel-body">
{% render_table table %}
</div>
......
......@@ -26,7 +26,7 @@
<div class="col-sm-6 text-right">
<a class="btn btn-primary btn-xs" href="{% url "dashboard.views.group-list" %}">
<i class="fa fa-chevron-circle-right"></i>
{% if more_groups > 0 %}
{% if more_groups > 0 %}
{% blocktrans count more=more_groups %}
<strong>{{ more }}</strong> more
{% plural %}
......
......@@ -74,9 +74,11 @@
{% trans "list" %}
{% endif %}
</a>
{% if request.user.is_superuser %}
<a class="btn btn-success btn-xs node-create" href="{% url "dashboard.views.node-create" %}">
<i class="fa fa-plus-circle"></i> {% trans "new" %}
</a>
{% endif %}
</div>
</div>
</div>
......
......@@ -35,7 +35,7 @@
</div>
{% endif %}
{% if user.is_superuser %}
{% if perms.vm.view_statistics %}
<div class="col-lg-4 col-sm-6">
{% include "dashboard/index-nodes.html" %}
</div>
......
......@@ -16,7 +16,7 @@
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin"><i class="fa fa-plus"></i> {% trans "Add Trait" %}</h3>
<h3 class="no-margin"><i class="fa fa-plus"></i> {% trans "Add Trait" %}</h3>
</div>
<div class="panel-body">
{% with form=form %}
......
......@@ -6,14 +6,16 @@
{% block content %}
<div class="body-content">
<div class="page-header">
{% if request.user.is_superuser %}
<div class="pull-right" id="ops">
{% include "dashboard/vm-detail/_operations.html" %}
</div>
<div class="pull-right" style="padding-top: 15px;">
<a title="{% trans "Rename" %}" href="#" class="btn btn-default btn-xs node-details-rename-button"><i class="fa fa-pencil"></i></a>
<a title="{% trans "Delete" %}" data-node-pk="{{ node.pk }}" class="btn btn-default btn-xs real-link node-delete" href="{% url "dashboard.views.delete-node" pk=node.pk %}"><i class="fa fa-trash-o"></i></a>
<div class="pull-right" style="padding-top: 15px;">
<a title="{% trans "Rename" %}" href="#" class="btn btn-default btn-xs node-details-rename-button"><i class="fa fa-pencil"></i></a>
<a title="{% trans "Delete" %}" data-node-pk="{{ node.pk }}" class="btn btn-default btn-xs real-link node-delete" href="{% url "dashboard.views.delete-node" pk=node.pk %}"><i class="fa fa-trash-o"></i></a>
</div>
<h1>
{% endif %}
<h1>
<div id="node-details-rename">
<form action="" method="POST" id="node-details-rename-form">
{% csrf_token %}
......@@ -69,26 +71,26 @@
{% trans "Resources" %}
</a>
</li>
<li>
<li>
<a href="{% url "dashboard.views.vm-list" %}?s=node:{{ node.name }}"
target="blank" class="text-center">
<i class="fa fa-desktop fa-2x"></i><br>
{% trans "Virtual Machines" %}
</a>
</li>
<li>
<li>
<a href="#activity" data-toggle="pill" class="text-center">
<i class="fa fa-clock-o fa-2x"></i><br>
{% trans "Activity" %}
</a>
</li>
</ul>
</ul>
<div id="panel-body" class="tab-content panel-body">
<div class="tab-pane active" id="home">{% include "dashboard/node-detail/home.html" %}</div>
<div class="tab-pane" id="resources">{% include "dashboard/node-detail/resources.html" %}</div>
<div class="tab-pane" id="resources">{% include "dashboard/node-detail/resources.html" %}</div>
<div class="tab-pane" id="activity">{% include "dashboard/node-detail/activity.html" %}</div>
</div>