Commit 4b2c34ea by Kálmán Viktor

dashboard: activity updates itself via ajax in vm detail

parent 25e424c8
$(function() {
if($('.timeline .activity:first i:first').hasClass('icon-spin'))
checkNewActivity();
});
function checkNewActivity() {
var latest = $('.activity:first').data('activity-id');
var latest_sub = $('div[data-activity-id="' + latest + '"] .sub-timeline .sub-activity:first').data('activity-id');
var instance = location.href.split('/'); instance = instance[instance.length - 2];
$.ajax({
type: 'POST',
url: '/dashboard/vm/' + instance + '/activity/',
headers: {"X-CSRFToken": getCookie('csrftoken')},
data: {'latest': latest, 'latest_sub': latest_sub},
success: function(data) {
if(data['new_sub_activities'].length > 0) {
d = data['new_sub_activities'];
html = ""
for(var i=0; i<d.length; i++) {
html += '<div data-activity-id="' + d[i].id + '" class="sub-activity">' + d[i].name + ' - ';
if(d[i].finished != null) {
html += d[i].finished
} else {
html += '<i class="icon-refresh icon-spin" class="sub-activity-loading-icon"></i>';
}
html += '</div>';
}
$('div[data-activity-id="' + latest_sub + '"] .sub-activity .sub-activity-loading-icon').remove();
$('div[data-activity-id="' + latest + '"] .sub-timeline').prepend(html);
}
if(data['is_parent_finished']) {
var c = "icon-plus"
$('div[data-activity-id="' + latest + '"] .icon-refresh.icon-spin:first').removeClass('icon-refresh').removeClass('icon-spin').addClass(c);
}
if(data['latest_sub_finished'] != null) {
s = $('div[data-activity-id="' + latest_sub + '"]')
$('.icon-refresh.icon-spin', s).remove();
$(s).append(data['latest_sub_finished']);
}
if(data['is_parent_finished'])
return;
else
setTimeout(checkNewActivity, 1000);
},
error: function() {
}
});
}
...@@ -7,17 +7,27 @@ ...@@ -7,17 +7,27 @@
padding-left: 10px; padding-left: 10px;
} }
</style> </style>
<div class="timeline"> <div class="timeline">
<div><span class="timeline-icon timeline-warning"><i class="icon-remove"></i></span> <strong>Removing</strong> 2013-11-21 15:32</div>
<div><span class="timeline-icon timeline-warning"><i class="icon-pause"></i></span> <strong>Suspending</strong> 2013-09-21 15:32</div>
{% for a in activity %} {% for a in activity %}
<div><span class="timeline-icon"><i class="icon-plus"></i></span> <strong>{{ a.get_readable_name }}</strong> <div class="activity" data-activity-id="{{ a.pk }}">
<span class="timeline-icon">
<i class="{% if not a.finished %} icon-refresh icon-spin {% else %}icon-plus{% endif %}"></i>
</span>
<strong>{{ a.get_readable_name }}</strong>
{{ a.started|date:"Y-m-d. H:i" }}, {{ a.user }} {{ a.started|date:"Y-m-d. H:i" }}, {{ a.user }}
{% if a.instanceactivity_set.count > 0 %} {% if a.instanceactivity_set.count > 0 %}
<div class="sub-timeline"> <div class="sub-timeline">
{% for s in a.instanceactivity_set.all %} {% for s in a.instanceactivity_set.all %}
{{ s.get_readable_name }} - {{ a.started|time:"H:i:s" }} <br /> <div data-activity-id="{{ s.pk }}" class="sub-activity">
{% endfor %} {{ s.get_readable_name }} -
{% if s.finished %}
{{ s.finished|time:"H:i:s" }}
{% else %}
<i class="icon-refresh icon-spin" class="sub-activity-loading-icon"></i>
{% endif %}
</div>
{% endfor %}
</div> </div>
{% endif %} {% endif %}
</div> </div>
...@@ -29,3 +39,7 @@ ...@@ -29,3 +39,7 @@
<div><span class="timeline-icon"><i class="icon-refresh"></i></span> <strong>Forced reboot</strong> 2013-04-21 15:32, ABC123</div> <div><span class="timeline-icon"><i class="icon-refresh"></i></span> <strong>Forced reboot</strong> 2013-04-21 15:32, ABC123</div>
<div><span class="timeline-icon"><i class="icon-plus"></i></span> <strong>Created</strong> 2013-04-21 15:32, ABC123</div> <div><span class="timeline-icon"><i class="icon-plus"></i></span> <strong>Created</strong> 2013-04-21 15:32, ABC123</div>
</div> </div>
{% block extra_js %}
<script src="{{ STATIC_URL }}dashboard/vm-details.js"></script>
{% endblock %}
...@@ -3,7 +3,7 @@ from django.conf.urls import patterns, url ...@@ -3,7 +3,7 @@ from django.conf.urls import patterns, url
from vm.models import Instance from vm.models import Instance
from .views import ( from .views import (
IndexView, VmDetailView, VmList, VmCreate, TemplateDetail, AclUpdateView, IndexView, VmDetailView, VmList, VmCreate, TemplateDetail, AclUpdateView,
VmDelete, mass_delete_vm) VmDelete, mass_delete_vm, vm_activity)
urlpatterns = patterns( urlpatterns = patterns(
'', '',
...@@ -20,5 +20,6 @@ urlpatterns = patterns( ...@@ -20,5 +20,6 @@ urlpatterns = patterns(
url(r'^vm/delete/(?P<pk>\d+)/$', VmDelete.as_view(), url(r'^vm/delete/(?P<pk>\d+)/$', VmDelete.as_view(),
name="dashboard.views.delete-vm"), name="dashboard.views.delete-vm"),
url(r'^vm/mass-delete/', mass_delete_vm, url(r'^vm/mass-delete/', mass_delete_vm,
name='dashboard.view.mass-delete-vm') name='dashboard.view.mass-delete-vm'),
url(r'^vm/(?P<pk>\d+)/activity/$', vm_activity)
) )
...@@ -94,6 +94,7 @@ class VmDetailView(CheckedDetailView): ...@@ -94,6 +94,7 @@ class VmDetailView(CheckedDetailView):
ia = InstanceActivity.objects.filter( ia = InstanceActivity.objects.filter(
instance=self.object, parent=None instance=self.object, parent=None
).order_by('-started').select_related() ).order_by('-started').select_related()
context['activity'] = ia context['activity'] = ia
context['acl'] = get_acl_data(instance) context['acl'] = get_acl_data(instance)
return context return context
...@@ -329,3 +330,40 @@ def mass_delete_vm(request, **kwargs): ...@@ -329,3 +330,40 @@ def mass_delete_vm(request, **kwargs):
messages.success(request, success_message) messages.success(request, success_message)
next = request.GET.get('next') next = request.GET.get('next')
return redirect(next if next else reverse_lazy('dashboard.index')) return redirect(next if next else reverse_lazy('dashboard.index'))
@require_POST
def vm_activity(request, pk):
latest = request.POST.get('latest')
latest_sub = request.POST.get('latest_sub')
instance = Instance.objects.get(pk=pk)
new_sub_activities = InstanceActivity.objects.filter(
parent=latest, pk__gt=latest_sub,
instance=instance)
# new_activities = InstanceActivity.objects.filter(
# parent=None, instance=instance, pk__gt=latest).values('finished')
latest_sub_finished = InstanceActivity.objects.get(pk=latest_sub).finished
time_string = "%H:%M:%S"
new_sub_activities = [
{'name': a.get_readable_name(), 'id': a.pk,
'finished': None if a.finished is None else a.finished.strftime(
time_string
)
} for a in new_sub_activities
]
response = {
'new_sub_activities': new_sub_activities,
# TODO 'new_acitivites': new_activities,
'is_parent_finished': True if InstanceActivity.objects.get(
pk=latest).finished is not None else False,
'latest_sub_finished': None if latest_sub_finished is None else
latest_sub_finished.strftime(time_string)
}
return HttpResponse(
json.dumps(response),
content_type="application/json"
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment