Commit 56721df3 by Kálmán Viktor

dashboard: add mass delete to vm list

parent 7b7d32dd
$(function() {
var ctrlDown, shiftDown = false;
var ctrlKey = 17;
var shiftKey = 16;
var selected = [];
$(document).keydown(function(e) {
if (e.keyCode == ctrlKey) ctrlDown = true;
if (e.keyCode == shiftKey) shiftDown = true;
}).keyup(function(e) {
if (e.keyCode == ctrlKey) ctrlDown = false;
if (e.keyCode == shiftKey) shiftDown = false;
});
$('.vm-list-table tbody').find('tr').mousedown(function() {
if (ctrlDown) {
setRowColor($(this));
if(!$(this).hasClass('vm-list-selected')) {
selected.splice(selected.indexOf($(this).index()), 1);
} else {
selected.push($(this).index());
}
} else if(shiftDown) {
if(selected.length > 0) {
start = selected[selected.length - 1] + 1;
end = $(this).index();
if(start > end) {
var tmp = start - 1; start = end; end = tmp - 1;
}
for(var i = start; i <= end; i++) {
if(selected.indexOf(i) < 0) {
selected.push(i);
setRowColor($('.vm-list-table tbody tr').eq(i));
}
}
}
} else {
$('.vm-list-selected').removeClass('vm-list-selected');
$(this).addClass('vm-list-selected');
selected = [$(this).index()];
}
// reset btn disables
$('.vm-list-table tbody tr .btn').attr('disabled', false);
// show/hide group controls
if(selected.length > 1) {
$('.vm-list-group-control .btn').attr('disabled', false);
for(var i = 0; i < selected.length; i++) {
$('.vm-list-table tbody tr').eq(selected[i]).find('.btn').attr('disabled', true);
}
} else {
$('.vm-list-group-control .btn').attr('disabled', true);
}
return false;
});
$('#vm-list-group-migrate').click(function() {
console.log(collectIds(selected));
});
$('.vm-list-details').popover({
'placement': 'auto',
'html': true,
'trigger': 'hover'
});
$('.vm-list-connect').popover({
'placement': 'left',
'html': true,
'trigger': 'click'
});
$('tbody a').mousedown(function(e) {
// parent tr doesn't get selected when clicked
e.stopPropagation();
});
$('tbody a').click(function(e) {
// browser doesn't jump to top when clicked the buttons
if(!$(this).hasClass('real-link')) {
return false;
}
});
/* group actions */
/* mass vm delete */
$('#vm-list-group-delete').click(function() {
$.ajax({
traditional: true,
url: '/dashboard/vm/mass-delete/',
headers: {"X-CSRFToken": getCookie('csrftoken')},
type: 'POST',
data: {'vms': collectIds(selected)},
success: function(data, textStatus, xhr) {
for(var i=0; i< selected.length; i++)
$('.vm-list-table tbody tr').eq(selected[i]).fadeOut(500, function() {
// reset group buttons
selected = []
$('.vm-list-group-control .btn').attr('disabled', true);
});
console.log(data);
},
error: function(xhr, textStatus, error) {
// TODO this
}
});
});
});
function collectIds(rows) {
var ids = [];
for(var i = 0; i < rows.length; i++) {
var div = $('td:first-child div', $('.vm-list-table tbody tr').eq(rows[i]));
ids.push(div.prop('id').replace('vm-', ''));
}
return ids;
}
function setRowColor(row) {
if(!row.hasClass('vm-list-selected')) {
row.addClass('vm-list-selected');
} else {
row.removeClass('vm-list-selected');
}
}
// TODO common getCookie
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<a class="btn btn-default btn-xs" id="vm-list-group-migrate" disabled><i class="icon-truck"></i> Migrate</a> <a class="btn btn-default btn-xs" id="vm-list-group-migrate" disabled><i class="icon-truck"></i> Migrate</a>
<a disabled href="#" class="btn btn-default btn-xs"><i class="icon-refresh"></i> Reboot</a> <a disabled href="#" class="btn btn-default btn-xs"><i class="icon-refresh"></i> Reboot</a>
<a disabled href="#" class="btn btn-default btn-xs"><i class="icon-off"></i> Shutdown</a> <a disabled href="#" class="btn btn-default btn-xs"><i class="icon-off"></i> Shutdown</a>
<a disabled href="#" class="btn btn-danger btn-xs"><i class="icon-remove"></i> Discard</a> <a id="vm-list-group-delete" disabled href="#" class="btn btn-danger btn-xs"><i class="icon-remove"></i> Discard</a>
</p> </p>
</div> </div>
<div class="panel-body"> <div class="panel-body">
...@@ -62,112 +62,5 @@ ...@@ -62,112 +62,5 @@
{% endblock %} {% endblock %}
{% block extra_js %} {% block extra_js %}
<script> <script src="{{ STATIC_URL}}dashboard/vm-list.js"></script>
$(function() {
var ctrlDown, shiftDown = false;
var ctrlKey = 17;
var shiftKey = 16;
var selected = [];
$(document).keydown(function(e) {
if (e.keyCode == ctrlKey) ctrlDown = true;
if (e.keyCode == shiftKey) shiftDown = true;
}).keyup(function(e) {
if (e.keyCode == ctrlKey) ctrlDown = false;
if (e.keyCode == shiftKey) shiftDown = false;
});
$('.vm-list-table tbody').find('tr').mousedown(function() {
if (ctrlDown) {
setRowColor($(this));
if(!$(this).hasClass('vm-list-selected')) {
selected.splice(selected.indexOf($(this).index()), 1);
} else {
selected.push($(this).index());
}
} else if(shiftDown) {
if(selected.length > 0) {
start = selected[selected.length - 1] + 1;
end = $(this).index();
if(start > end) {
var tmp = start - 1; start = end; end = tmp - 1;
}
for(var i = start; i <= end; i++) {
if(selected.indexOf(i) < 0) {
selected.push(i);
setRowColor($('.vm-list-table tbody tr').eq(i));
}
}
}
} else {
$('.vm-list-selected').removeClass('vm-list-selected');
$(this).addClass('vm-list-selected');
selected = [$(this).index()];
}
// reset btn disables
$('.vm-list-table tbody tr .btn').attr('disabled', false);
// show/hide group controls
if(selected.length > 1) {
$('.vm-list-group-control .btn').attr('disabled', false);
for(var i = 0; i < selected.length; i++) {
$('.vm-list-table tbody tr').eq(selected[i]).find('.btn').attr('disabled', true);
}
} else {
$('.vm-list-group-control .btn').attr('disabled', true);
}
return false;
});
$('#vm-list-group-migrate').click(function() {
console.log(collectIds(selected));
});
$('.vm-list-details').popover({
'placement': 'auto',
'html': true,
'trigger': 'hover'
});
$('.vm-list-connect').popover({
'placement': 'left',
'html': true,
'trigger': 'click'
});
$('tbody a').mousedown(function(e) {
// parent tr doesn't get selected when clicked
e.stopPropagation();
});
$('tbody a').click(function(e) {
// browser doesn't jump to top when clicked the buttons
if(!$(this).hasClass('real-link')) {
return false;
}
});
});
function collectIds(rows) {
var ids = [];
for(var i = 0; i < rows.length; i++) {
var div = $('td:first-child div', $('.vm-list-table tbody tr').eq(rows[i]));
ids.push(div.prop('id').replace('vm-', ''));
}
return ids;
}
function setRowColor(row) {
if(!row.hasClass('vm-list-selected')) {
row.addClass('vm-list-selected');
} else {
row.removeClass('vm-list-selected');
}
}
</script>
{% endblock %} {% endblock %}
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li><a href="#"><i class="icon-refresh"></i> Reboot</a></li> <li><a href="#"><i class="icon-refresh"></i> Reboot</a></li>
<li><a href="#"><i class="icon-off"></i> Shutdown</a></li> <li><a href="#"><i class="icon-off"></i> Shutdown</a></li>
<li><a href="#"><i class="icon-remove"></i> Discard</a></li> <li><a class="real-link" href="{% url "dashboard.views.delete-vm" pk=record.pk %}?next={{ request.path }}"><i class="icon-remove"></i> Discard</a></li>
</ul> </ul>
</div> </div>
...@@ -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,
delete_vm) delete_vm, mass_delete_vm)
urlpatterns = patterns( urlpatterns = patterns(
'', '',
...@@ -19,4 +19,6 @@ urlpatterns = patterns( ...@@ -19,4 +19,6 @@ urlpatterns = patterns(
name='dashboard.views.vm-create'), name='dashboard.views.vm-create'),
url(r'^vm/delete/(?P<pk>\d+)/$', delete_vm, url(r'^vm/delete/(?P<pk>\d+)/$', delete_vm,
name="dashboard.views.delete-vm"), name="dashboard.views.delete-vm"),
url(r'^vm/mass-delete/', mass_delete_vm,
name='dashboard.view.mass-delete-vm')
) )
...@@ -254,3 +254,24 @@ def delete_vm(request, **kwargs): ...@@ -254,3 +254,24 @@ def 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'))
def mass_delete_vm(request, **kwargs):
vms = request.POST.getlist('vms')
names = []
if vms is not None:
for i in Instance.objects.filter(pk__in=vms):
i.destroy_async()
names.append(i.name)
success_message = _("Mass delete complete, the following VMs were " +
"deleted: %s" % u', '.join(names))
# we can get this only via AJAX ...
if request.is_ajax():
return HttpResponse(
json.dumps({'message': success_message}),
content_type="application/json"
)
else:
print "wat"
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