animation added to vm termination
This commit is contained in:
parent
821f854fc9
commit
07a464231d
8 changed files with 141 additions and 51 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -628,3 +637,27 @@
|
||||||
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;
|
||||||
|
}
|
BIN
hosting/static/hosting/img/ajax-loader.gif
Normal file
BIN
hosting/static/hosting/img/ajax-loader.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 404 B |
|
@ -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;
|
||||||
|
|
|
@ -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> Deutsch</a>
|
|
||||||
{% else %}
|
|
||||||
<a href="{% change_lang 'en-us' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> English</a>
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -46,29 +46,36 @@
|
||||||
<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>
|
||||||
|
<div id="terminate-VM" data-alt="{% trans 'Terminating' %}">
|
||||||
{% if virtual_machine.state == 'PENDING' %}
|
{% if virtual_machine.state == 'PENDING' %}
|
||||||
<div class="vm-item-lg vm-color-pending">{% trans "Pending" %}</div>
|
<div class="vm-item-lg vm-color-pending">{% trans "Pending" %}</div>
|
||||||
{% elif virtual_machine.state == 'ACTIVE' %}
|
{% elif virtual_machine.state == 'ACTIVE' %}
|
||||||
<div class="vm-item-lg vm-color-online">{% trans "Online" %}</div>
|
<div class="vm-item-lg vm-color-online">{% trans "Online" %}</div>
|
||||||
{% elif virtual_machine.state == 'FAILED'%}
|
{% elif virtual_machine.state == 'FAILED'%}
|
||||||
<div class="vm-item-lg vm-color-failed">{% trans "Failed" %}</div>
|
<div class="vm-item-lg vm-color-failed">{% trans "Failed" %}</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="vm-item-lg"></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not virtual_machine.status == 'canceled' %}
|
{% if not virtual_machine.status == 'canceled' %}
|
||||||
<form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}">
|
<form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' 2 %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
</form>
|
</form>
|
||||||
<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>
|
<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 %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="vm-contact-us">
|
<div class="vm-contact-us">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="vm-detail-title">{% trans "Support / Contact" %} <img class="un-icon visible-xs" src="{% static 'hosting/img/24-hours-support.svg' %}"></h2>
|
<h2 class="vm-detail-title">{% trans "Support / Contact" %} <img class="un-icon visible-xs" src="{% static 'hosting/img/24-hours-support.svg' %}"></h2>
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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
|
||||||
|
@ -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,16 +936,16 @@ 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
|
||||||
|
else:
|
||||||
context = {
|
context = {
|
||||||
'vm': vm_data,
|
'vm': vm_data,
|
||||||
'base_url': "{0}://{1}".format(self.request.scheme,
|
'base_url': "{0}://{1}".format(self.request.scheme,
|
||||||
|
@ -961,14 +963,26 @@ class VirtualMachineView(LoginRequiredMixin, View):
|
||||||
email = BaseEmail(**email_data)
|
email = BaseEmail(**email_data)
|
||||||
email.send()
|
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):
|
||||||
|
|
Loading…
Reference in a new issue