Commit 3aaf7e00 by Kálmán Viktor Committed by Guba Sándor

dashboard: call save as async

dashboard: remove disks
dashboard: handle None disk sizes
dashboard: disk list design
dashboard: create diskless vm from new template

Conflicts:

	circle/dashboard/templates/dashboard/_disk-list-element.html
	circle/dashboard/urls.py
	circle/dashboard/views.py
parent f6e1dcbe
......@@ -122,6 +122,18 @@ $(function () {
'redirect': dir});
return false;
});
/* for disk remove buttons */
$('.disk-remove').click(function() {
var disk_pk = $(this).data('disk-pk');
addModalConfirmation(deleteObject,
{ 'url': '/dashboard/disk/' + disk_pk + '/remove/',
'data': [],
'pk': disk_pk,
'type': "disk",
});
return false;
});
/* for Node removes buttons */
$('.node-delete').click(function() {
......@@ -258,9 +270,15 @@ function deleteObject(data) {
if(!data['redirect']) {
selected = [];
addMessage(re['message'], 'success');
$('a[data-'+data['type']+'-pk="' + data['pk'] + '"]').closest('tr').fadeOut(function() {
$(this).remove();
});
if(data.type === "disk") {
// no need to remove them from DOM
$('a[data-disk-pk="' + data.pk + '"]').parent("li").fadeOut();
$('a[data-disk-pk="' + data.pk + '"]').parent("h4").fadeOut();
} else {
$('a[data-'+data['type']+'-pk="' + data['pk'] + '"]').closest('tr').fadeOut(function() {
$(this).remove();
});
}
} else {
window.location.replace('/dashboard');
}
......
......@@ -10,5 +10,8 @@
<div class="label label-danger">failed</div>
{% endif %}
{% else %}<span class="disk-list-disk-percentage" data-disk-pk="{{ d.pk }}">{{ d.get_download_percentage }}</span>%{% endif %}
<div class="btn btn-xs btn-danger pull-right"><i class="icon-remove"></i> Remove</div>
<a href="{% url "dashboard.views.disk-remove" pk=d.pk %}?next={{ request.path }}"
data-disk-pk="{{ d.pk }}" class="btn btn-xs btn-danger pull-right disk-remove">
<i class="icon-remove"></i>{% if long_remove %} Remove{% endif %}
</a>
<div style="clear: both;"></div>
......@@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-body">
{% if text %}
{{ text }}
{{ text|safe }}
{% else %}
{%blocktrans with object=object%}
Are you sure you want to delete <strong>{{ object }}</strong>?
......
......@@ -15,7 +15,7 @@
</div>
<div class="panel-body">
{% if text %}
{{ text }}
{{ text|safe }}
{% else %}
{%blocktrans with object=object%}
Are you sure you want to delete <strong>{{ object }}</strong>?
......@@ -26,7 +26,7 @@
{% csrf_token %}
<a class="btn btn-default">Back</a>
<input type="hidden" name="next" value="{{ request.GET.next }}"/>
<button class="btn btn-danger">Yes, delete</button>
<button class="btn btn-danger">Yes</button>
</form>
</div>
</div>
......
......@@ -10,7 +10,7 @@ from .views import (
TemplateDelete, TemplateDetail, TemplateList, TransferOwnershipConfirmView,
TransferOwnershipView, vm_activity, VmCreate, VmDelete, VmDetailView,
VmDetailVncTokenView, VmGraphView, VmList, VmMassDelete, VmMigrateView,
VmRenewView,
VmRenewView, DiskRemoveView
)
urlpatterns = patterns(
......@@ -99,4 +99,6 @@ urlpatterns = patterns(
name="dashboard.views.disk-add"),
url(r'^profile/$', MyPreferencesView.as_view(),
name="dashboard.views.profile"),
url(r'^disk/(?P<pk>\d+)/remove/$', DiskRemoveView.as_view(),
name="dashboard.views.disk-remove"),
)
......@@ -43,6 +43,7 @@ from vm.models import (
Instance, instance_activity, InstanceActivity, InstanceTemplate, Interface,
InterfaceTemplate, Lease, Node, NodeActivity, Trait,
)
from storage.models import Disk
from firewall.models import Vlan, Host, Rule
from dashboard.models import Favourite, Profile
......@@ -2082,3 +2083,49 @@ def set_language_cookie(request, response, lang=None):
cname = getattr(settings, 'LANGUAGE_COOKIE_NAME', 'django_language')
response.set_cookie(cname, lang, 365 * 86400)
class DiskRemoveView(DeleteView):
model = Disk
def get_template_names(self):
if self.request.is_ajax():
return ['dashboard/confirm/ajax-delete.html']
else:
return ['dashboard/confirm/base-delete.html']
def get_context_data(self, **kwargs):
context = super(DiskRemoveView, self).get_context_data(**kwargs)
disk = self.get_object()
app = disk.get_appliance()
context['title'] = _("Disk remove confirmation")
context['text'] = _("Are you sure you want to remove "
"<strong>%(disk)s</strong> from "
"<strong>%(app)s</strong>?" % {'disk': disk,
'app': app}
)
return context
def delete(self, request, *args, **kwargs):
disk = self.get_object()
if not disk.has_level(request.user, 'owner'):
raise PermissionDenied()
disk = self.get_object()
app = disk.get_appliance()
app.disks.remove(disk)
disk.destroy()
next_url = request.POST.get("next")
success_url = next_url if next_url else app.get_absolute_url()
success_message = _("Disk successfully removed!")
if request.is_ajax():
return HttpResponse(
json.dumps({'message': success_message}),
content_type="application/json",
)
else:
messages.success(request, success_message)
return HttpResponseRedirect("%s#resources" % success_url)
......@@ -204,6 +204,17 @@ class Disk(AclBase, TimeStampedModel):
"""
return any(i.state != 'STOPPED' for i in self.instance_set.all())
def get_appliance(self):
"""Return an Instance or InstanceTemplate object where the disk is used
"""
instance = self.instance_set.all()
template = self.template_set.all()
app = list(instance) + list(template)
if len(app) > 0:
return app[0]
else:
return None
def get_exclusive(self):
"""Get an instance of the disk for exclusive usage.
......
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