From 14af9660db752630b2763aef2c5e337e0eedf91a Mon Sep 17 00:00:00 2001 From: Bach Dániel <bd@ik.bme.hu> Date: Wed, 26 Nov 2014 21:20:42 +0100 Subject: [PATCH] dashboard: remove InterfaceDeleteVie --- circle/dashboard/forms.py | 30 ++++++++++++++++++++++++++++++ circle/dashboard/static/dashboard/vm-details.js | 29 ----------------------------- circle/dashboard/templates/dashboard/vm-detail/network.html | 13 +++++++------ circle/dashboard/urls.py | 5 +---- circle/dashboard/views/vm.py | 80 +++++++++++++++++++++++++++++--------------------------------------------------- 5 files changed, 67 insertions(+), 90 deletions(-) diff --git a/circle/dashboard/forms.py b/circle/dashboard/forms.py index ad1b0ec..a525f20 100644 --- a/circle/dashboard/forms.py +++ b/circle/dashboard/forms.py @@ -908,6 +908,36 @@ class VmDownloadDiskForm(OperationForm): return cleaned_data +class VmRemoveInterfaceForm(OperationForm): + def __init__(self, *args, **kwargs): + choices = kwargs.pop('choices') + self.interface = kwargs.pop('default') + + super(VmRemoveInterfaceForm, self).__init__(*args, **kwargs) + + self.fields.insert(0, 'interface', forms.ModelChoiceField( + queryset=choices, initial=self.interface, required=True, + empty_label=None, label=_('Interface'))) + if self.interface: + self.fields['interface'].widget = HiddenInput() + + @property + def helper(self): + helper = super(VmRemoveInterfaceForm, self).helper + print 'hi' + if self.interface: + helper.layout = Layout( + AnyTag( + "div", + HTML(format_html( + _("<label>Vlan:</label> {0}"), + self.interface.vlan)), + css_class="form-group", + ), + ) + return helper + + class VmAddInterfaceForm(OperationForm): def __init__(self, *args, **kwargs): choices = kwargs.pop('choices') diff --git a/circle/dashboard/static/dashboard/vm-details.js b/circle/dashboard/static/dashboard/vm-details.js index d0422e7..7000f28 100644 --- a/circle/dashboard/static/dashboard/vm-details.js +++ b/circle/dashboard/static/dashboard/vm-details.js @@ -168,35 +168,6 @@ $(function() { return false; }); - /* for interface remove buttons */ - $('.interface-remove').click(function() { - var interface_pk = $(this).data('interface-pk'); - addModalConfirmation(removeInterface, - { 'url': '/dashboard/interface/' + interface_pk + '/delete/', - 'data': [], - 'pk': interface_pk, - 'type': "interface", - }); - return false; - }); - - /* removing interface post */ - function removeInterface(data) { - $.ajax({ - type: 'POST', - url: data.url, - headers: {"X-CSRFToken": getCookie('csrftoken')}, - success: function(re, textStatus, xhr) { - /* remove the html element */ - $('a[data-interface-pk="' + data.pk + '"]').closest("div").fadeOut(); - location.reload(); - }, - error: function(xhr, textStatus, error) { - addMessage('Uh oh :(', 'danger'); - } - }); - } - /* rename */ $("#vm-details-h1-name, .vm-details-rename-button").click(function() { $("#vm-details-h1-name").hide(); diff --git a/circle/dashboard/templates/dashboard/vm-detail/network.html b/circle/dashboard/templates/dashboard/vm-detail/network.html index d4d63b8..8e0a0ed 100644 --- a/circle/dashboard/templates/dashboard/vm-detail/network.html +++ b/circle/dashboard/templates/dashboard/vm-detail/network.html @@ -21,13 +21,14 @@ <a href="{{ i.host.get_absolute_url }}" class="btn btn-default btn-xs">{% trans "edit" %}</a> {% endif %} - {% if is_owner %} - <a href="{% url "dashboard.views.interface-delete" pk=i.pk %}?next={{ request.path }}" - class="btn btn-danger btn-xs interface-remove" - data-interface-pk="{{ i.pk }}"> - {% trans "remove" %} + {% with op=op.remove_interface %}{% if op %} + <span class="operation-wrapper"> + <a href="{{op.get_url}}?interface={{ i.pk }}" + class="btn btn-{{op.effect}} btn-xs operation interface-remove" + {% if op.disabled %}disabled{% endif %}>{% trans "remove" %} </a> - {% endif %} + </span> + {% endif %}{% endwith %} </h3> {% if i.host %} <div class="row"> diff --git a/circle/dashboard/urls.py b/circle/dashboard/urls.py index 399a867..d0723a7 100644 --- a/circle/dashboard/urls.py +++ b/circle/dashboard/urls.py @@ -30,7 +30,7 @@ from .views import ( TemplateDelete, TemplateDetail, TemplateList, vm_activity, VmCreate, VmDetailView, VmDetailVncTokenView, VmList, - DiskRemoveView, get_disk_download_status, InterfaceDeleteView, + DiskRemoveView, get_disk_download_status, GroupRemoveUserView, GroupRemoveFutureUserView, GroupCreate, GroupProfileUpdate, @@ -154,9 +154,6 @@ urlpatterns = patterns( url(r'^disk/(?P<pk>\d+)/status/$', get_disk_download_status, name="dashboard.views.disk-status"), - url(r'^interface/(?P<pk>\d+)/delete/$', InterfaceDeleteView.as_view(), - name="dashboard.views.interface-delete"), - url(r'^profile/$', MyPreferencesView.as_view(), name="dashboard.views.profile-preferences"), url(r'^subscribe/(?P<token>.*)/$', UnsubscribeFormView.as_view(), diff --git a/circle/dashboard/views/vm.py b/circle/dashboard/views/vm.py index b02153f..337a1d6 100644 --- a/circle/dashboard/views/vm.py +++ b/circle/dashboard/views/vm.py @@ -37,7 +37,7 @@ from django.utils.translation import ( ) from django.views.decorators.http import require_GET from django.views.generic import ( - UpdateView, ListView, TemplateView, DeleteView + UpdateView, ListView, TemplateView ) from braces.views import SuperuserRequiredMixin, LoginRequiredMixin @@ -64,6 +64,7 @@ from ..forms import ( VmDiskResizeForm, RedeployForm, VmDiskRemoveForm, VmMigrateForm, VmDeployForm, VmPortRemoveForm, VmPortAddForm, + VmRemoveInterfaceForm, ) from ..models import Favourite @@ -324,6 +325,32 @@ def get_operations(instance, user): return ops +class VmRemoveInterfaceView(FormOperationMixin, VmOperationView): + op = 'remove_interface' + form_class = VmRemoveInterfaceForm + show_in_toolbar = False + wait_for_result = 0.5 + icon = 'times' + effect = "danger" + with_reload = True + + def get_form_kwargs(self): + instance = self.get_op().instance + choices = instance.interface_set.all() + interface_pk = self.request.GET.get('interface') + if interface_pk: + try: + default = choices.get(pk=interface_pk) + except (ValueError, Interface.DoesNotExist): + raise Http404() + else: + default = None + + val = super(VmRemoveInterfaceView, self).get_form_kwargs() + val.update({'choices': choices, 'default': default}) + return val + + class VmAddInterfaceView(FormOperationMixin, VmOperationView): op = 'add_interface' @@ -707,6 +734,7 @@ vm_ops = OrderedDict([ op='remove_disk', form_class=VmDiskRemoveForm, icon='times', effect="danger")), ('add_interface', VmAddInterfaceView), + ('remove_interface', VmRemoveInterfaceView), ('remove_port', VmPortRemoveView), ('add_port', VmPortAddView), ('renew', VmRenewView), @@ -1111,56 +1139,6 @@ def get_vm_screenshot(request, pk): return HttpResponse(image, mimetype="image/png") -class InterfaceDeleteView(DeleteView): - model = Interface - - 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(InterfaceDeleteView, self).get_context_data(**kwargs) - interface = self.get_object() - context['text'] = _("Are you sure you want to remove this interface " - "from <strong>%(vm)s</strong>?" % - {'vm': interface.instance.name}) - return context - - def delete(self, request, *args, **kwargs): - self.object = self.get_object() - instance = self.object.instance - - if not instance.has_level(request.user, "owner"): - raise PermissionDenied() - - instance.remove_interface(interface=self.object, user=request.user) - success_url = self.get_success_url() - success_message = _("Interface successfully deleted.") - - if request.is_ajax(): - return HttpResponse( - json.dumps( - {'message': success_message, - 'removed_network': { - 'vlan': self.object.vlan.name, - 'vlan_pk': self.object.vlan.pk, - 'managed': self.object.host is not None, - }}), - content_type="application/json", - ) - else: - messages.success(request, success_message) - return HttpResponseRedirect("%s#network" % success_url) - - def get_success_url(self): - redirect = self.request.POST.get("next") - if redirect: - return redirect - self.object.instance.get_absolute_url() - - class InstanceActivityDetail(CheckedDetailView): model = InstanceActivity context_object_name = 'instanceactivity' # much simpler to mock object -- libgit2 0.26.0