animation added to vm termination

This commit is contained in:
Arvind Tiwari 2017-09-14 02:24:10 +05:30
parent 821f854fc9
commit 07a464231d
8 changed files with 141 additions and 51 deletions

View file

@ -853,6 +853,9 @@ a.list-group-item-danger:focus,
.panel-danger > .panel-heading { .panel-danger > .panel-heading {
color: #eb4d5c; color: #eb4d5c;
} }
.alert-danger{
background: rgba(235, 204, 209, 0.2);
}
.has-error .form-control, .has-error .form-control,
.has-error .input-group-addon { .has-error .input-group-addon {
color: #eb4d5c; color: #eb4d5c;

View file

@ -290,6 +290,11 @@
text-align: center; text-align: center;
} }
.vm-vmid .alert {
margin-top: 15px;
margin-bottom: -60px;
}
.vm-item-lg { .vm-item-lg {
font-size: 22px; font-size: 22px;
margin-top: 5px; margin-top: 5px;
@ -305,6 +310,10 @@
color: #e47f2f; color: #e47f2f;
} }
.vm-color-failed {
color: #eb4d5c;
}
.vm-detail-item .value{ .vm-detail-item .value{
font-weight: 400; font-weight: 400;
} }
@ -627,4 +636,28 @@
left: auto; left: auto;
right: 8px; right: 8px;
} }
}
.processing > .btn {
position: relative;
border-color: #eee;
}
.processing > .btn:hover,
.processing > .btn:focus,
.processing > .btn:active {
border-color: #eee;
}
.processing > .btn:after {
content: ' ';
display: block;
position: absolute;
background-image: url('/static/hosting/img/ajax-loader.gif');
background-repeat: no-repeat;
background-position: center;
background-color: #eee;
width: 100%;
top: 0;
height: 100%;
left: 0;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

View file

@ -2,7 +2,43 @@
$( document ).ready(function() { $( document ).ready(function() {
$('#confirm-cancel').on('click', '.btn-ok', function(e) { $('#confirm-cancel').on('click', '.btn-ok', function(e) {
$('#virtual_machine_cancel_form').trigger('submit'); var url = $('#virtual_machine_cancel_form').attr('action');
var $container = $('#terminate-VM');
var $btn = $container.find('.btn');
var text = $container.find('.vm-item-lg').text();
var altText = $container.attr('data-alt');
$container.find('.alert-danger').addClass('hide');
$container.addClass('processing')
.find('.vm-item-lg').attr('class', '')
.addClass('vm-item-lg vm-color-failed')
.text(altText);
$btn.prop('disabled', true);
$('#confirm-cancel').modal('hide');
$.post(url)
.done(function(data) {
console.log( "success" , data);
if (data.status == true) {
$container.addClass('terminate-success')
.find('.vm-item-lg').text(data.text);
$btn.remove();
// window.location = data.redirect;
}
else {
$container.addClass('terminate-fail')
.find('.vm-item-lg').text(text);
$container.find('.btn').prop('disabled', false);
$container.find('.alert-danger').text(data.text).removeClass('hide');
}
})
.fail(function(data) {
$container.addClass('terminate-fail')
.find('.vm-item-lg').text(text);
$container.find('.btn').prop('disabled', false);
$container.find('.alert-danger').removeClass('hide');
})
.always(function(data) {
$container.removeClass('processing');
});
}); });
var hash = window.location.hash; var hash = window.location.hash;

View file

@ -37,11 +37,6 @@
</li> </li>
<li> <li>
{% get_current_language as LANGUAGE_CODE %} {% get_current_language as LANGUAGE_CODE %}
{% if LANGUAGE_CODE == 'en-us'%}
<a href="{% change_lang 'de' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i>&nbsp;&nbsp;Deutsch</a>
{% else %}
<a href="{% change_lang 'en-us' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i>&nbsp;&nbsp;English</a>
{% endif %}
</li> </li>
</ul> </ul>
</div> </div>

View file

@ -46,26 +46,33 @@
<div class="vm-vmid"> <div class="vm-vmid">
<div class="vm-item-subtitle">{% trans "Current Pricing" %}</div> <div class="vm-item-subtitle">{% trans "Current Pricing" %}</div>
<div class="vm-item-lg">{{virtual_machine.price|floatformat}} CHF/{% trans "Month" %}</div> <div class="vm-item-lg">{{virtual_machine.price|floatformat}} CHF/{% trans "Month" %}</div>
<a class="btn btn-vm-invoice" href="{% url 'hosting:orders' order.pk %}">{% trans "See Invoice" %}</a> <a class="btn btn-vm-invoice" href="{% url 'hosting:orders' 2 %}">{% trans "See Invoice" %}</a>
</div> </div>
</div> </div>
<div class="vm-detail-item"> <div class="vm-detail-item">
<h2 class="vm-detail-title">{% trans "Status" %} <img src="{% static 'hosting/img/connected.svg' %}" class="un-icon"></h2> <h2 class="vm-detail-title">{% trans "Status" %} <img src="{% static 'hosting/img/connected.svg' %}" class="un-icon"></h2>
<div class="vm-vmid"> <div class="vm-vmid">
<div class="vm-item-subtitle">{% trans "Your VM is" %}</div> <div class="vm-item-subtitle">{% trans "Your VM is" %}</div>
{% if virtual_machine.state == 'PENDING' %} <div id="terminate-VM" data-alt="{% trans 'Terminating' %}">
<div class="vm-item-lg vm-color-pending">{% trans "Pending" %}</div> {% if virtual_machine.state == 'PENDING' %}
{% elif virtual_machine.state == 'ACTIVE' %} <div class="vm-item-lg vm-color-pending">{% trans "Pending" %}</div>
<div class="vm-item-lg vm-color-online">{% trans "Online" %}</div> {% elif virtual_machine.state == 'ACTIVE' %}
{% elif virtual_machine.state == 'FAILED'%} <div class="vm-item-lg vm-color-online">{% trans "Online" %}</div>
<div class="vm-item-lg vm-color-failed">{% trans "Failed" %}</div> {% elif virtual_machine.state == 'FAILED'%}
{% endif %} <div class="vm-item-lg vm-color-failed">{% trans "Failed" %}</div>
{% if not virtual_machine.status == 'canceled' %} {% else %}
<form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}"> <div class="vm-item-lg"></div>
{% csrf_token %} {% endif %}
</form> {% if not virtual_machine.status == 'canceled' %}
<button data-href="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}" data-toggle="modal" data-target="#confirm-cancel" class="btn btn-vm-term">{% trans "Terminate VM" %}</button> <form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' 2 %}">
{% endif %} {% csrf_token %}
</form>
<button data-toggle="modal" data-target="#confirm-cancel" class="btn btn-vm-term">{% trans "Terminate VM" %}</button>
<div class="alert alert-danger hide">
{% trans "Sorry, there was an unexpected error. Kindly retry." %}
</div>
{% endif %}
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -10,9 +10,11 @@ from .views import (
HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView,
SSHKeyChoiceView, DashboardView, SettingsView) SSHKeyChoiceView, DashboardView, SettingsView)
from django.views.generic import TemplateView
urlpatterns = [ urlpatterns = [
url(r'test/?$', TemplateView.as_view(template_name='hosting/virtual_machine_detail.html')),
url(r'index/?$', IndexView.as_view(), name='index'), url(r'index/?$', IndexView.as_view(), name='index'),
url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'), url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'), url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'),

View file

@ -1,4 +1,6 @@
import uuid import uuid
import json
from time import sleep
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
@ -6,13 +8,12 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.tokens import default_token_generator from django.contrib.auth.tokens import default_token_generator
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.urlresolvers import reverse_lazy, reverse from django.core.urlresolvers import reverse_lazy, reverse
from django.http import Http404 from django.http import Http404, HttpResponseRedirect, HttpResponse
from django.http import HttpResponseRedirect from django.shortcuts import redirect, render
from django.shortcuts import redirect
from django.shortcuts import render
from django.utils.http import urlsafe_base64_decode from django.utils.http import urlsafe_base64_decode
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from django.views.generic import View, CreateView, FormView, ListView, \ from django.views.generic import View, CreateView, FormView, ListView, \
DetailView, \ DetailView, \
DeleteView, TemplateView, UpdateView DeleteView, TemplateView, UpdateView
@ -711,7 +712,7 @@ class PaymentVMView(LoginRequiredMixin, FormView):
request.get_host()), request.get_host()),
'page_header': _( 'page_header': _(
'Your New VM %(vm_name)s at Data Center Light') % { 'Your New VM %(vm_name)s at Data Center Light') % {
'vm_name': vm.get('name')} 'vm_name': vm.get('name')}
} }
email_data = { email_data = {
'subject': context.get('page_header'), 'subject': context.get('page_header'),
@ -924,6 +925,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
return render(request, self.template_name, context) return render(request, self.template_name, context)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
response = {}
owner = self.request.user owner = self.request.user
vm = self.get_object() vm = self.get_object()
@ -934,41 +936,53 @@ class VirtualMachineView(LoginRequiredMixin, View):
password=owner.password password=owner.password
) )
vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data
terminated = manager.delete_vm(
vm.id terminated = manager.delete_vm(vm.id)
)
if not terminated: if not terminated:
messages.error( messages.error(
request, request,
'Error terminating VM %s' % (opennebula_vm_id) 'Error terminating VM %s' % (opennebula_vm_id)
) )
return HttpResponseRedirect(self.get_success_url()) response['status'] = False
context = { else:
'vm': vm_data, context = {
'base_url': "{0}://{1}".format(self.request.scheme, 'vm': vm_data,
self.request.get_host()), 'base_url': "{0}://{1}".format(self.request.scheme,
'page_header': _('Virtual Machine Cancellation') self.request.get_host()),
} 'page_header': _('Virtual Machine Cancellation')
email_data = { }
'subject': context['page_header'], email_data = {
'to': self.request.user.email, 'subject': context['page_header'],
'context': context, 'to': self.request.user.email,
'template_name': 'vm_canceled', 'context': context,
'template_path': 'hosting/emails/', 'template_name': 'vm_canceled',
'from_address': settings.DCL_SUPPORT_FROM_ADDRESS, 'template_path': 'hosting/emails/',
} 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
email = BaseEmail(**email_data) }
email.send() email = BaseEmail(**email_data)
email.send()
messages.error( # messages.error(
request, # request,
_('VM %(VM_ID)s terminated successfully') % { # _('VM %(VM_ID)s terminated successfully') % {
'VM_ID': opennebula_vm_id} # 'VM_ID': opennebula_vm_id}
# )
deleting = True
t = 0
while deleting:
if t < 150 and manager.get_vm(self.kwargs.get('pk')):
sleep(2)
else:
deleting = False
response['status'] = True
response['redirect'] = self.get_success_url()
response['text'] = ugettext('Terminated')
return HttpResponse(
json.dumps(response),
content_type="application/json"
) )
return HttpResponseRedirect(self.get_success_url())
class HostingBillListView(PermissionRequiredMixin, LoginRequiredMixin, class HostingBillListView(PermissionRequiredMixin, LoginRequiredMixin,
ListView): ListView):