diff --git a/Changelog b/Changelog
index 423517ee..f03a04ed 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,16 @@
+1.2.3: 2017-09-25
+ * #3484: [dcl, hosting] Refactored account activation, password reset, VM order and cancellation email
+ * #3731: [dcl, hosting] Added cdist ssh key handler
+ * #3628: [dcl] on hosting, VM is created at credit card info submit
+ * #3772: [dcl] Updated hosting app billing into monthly subscription and added new text and translations
+ * #3786: [hosting] Redesigned the hosting invoice and order-confirmation page
+ * #3728: [hosting] VM Termination animation added
+ * #3777: [hosting] Create new VM calculator added like dcl landing
+ * #3781: [hosting] Resend activation mail
+ * #3806: [hosting] Fix can not create VMs after password reset
+ * Feature: [cms, blog] Added /cms prefix for all the django-cms generated urls
+ * Bugfix: [dcl, hosting] added host to celery error mails
+ * Bugfix: [ungleich] Fixed wrong subdomain digitalglarus.ungleich.ch
1.2.2: 2017-09-08
* #3704: [hosting] Added my settings page
* #3771: [datacenterlight] Fixed the inconsistency in navbar style in billing page and onward
diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po
index 62580154..89e35e8c 100644
--- a/datacenterlight/locale/de/LC_MESSAGES/django.po
+++ b/datacenterlight/locale/de/LC_MESSAGES/django.po
@@ -194,13 +194,13 @@ msgid "All Rights Reserved"
msgstr "Alle Rechte vorbehalten"
msgid "Toggle navigation"
-msgstr "Konfiguration"
+msgstr "Umschalten"
msgid "Why Data Center Light?"
msgstr "Warum Data Center Light?"
msgid "Login"
-msgstr ""
+msgstr "Anmelden"
msgid "Dashboard"
msgstr ""
diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js
index c508d76d..ab37a68b 100644
--- a/datacenterlight/static/datacenterlight/js/main.js
+++ b/datacenterlight/static/datacenterlight/js/main.js
@@ -147,7 +147,6 @@
function _fetchPricing() {
Object.keys(cardPricing).map(function(element) {
- //$('#'+cardPricing[element].id).val(cardPricing[element].value);
$('input[name=' + element + ']').val(cardPricing[element].value);
});
_calcPricing();
diff --git a/datacenterlight/templates/datacenterlight/calculator_form.html b/datacenterlight/templates/datacenterlight/calculator_form.html
index cdba4809..b5bac1f9 100644
--- a/datacenterlight/templates/datacenterlight/calculator_form.html
+++ b/datacenterlight/templates/datacenterlight/calculator_form.html
@@ -26,9 +26,9 @@
{% for message in messages %}
{% if 'cores' in message.tags %}
-
+
{% endif %}
{% endfor %}
diff --git a/dynamicweb/urls.py b/dynamicweb/urls.py
index 84f3fb3d..699ce50b 100644
--- a/dynamicweb/urls.py
+++ b/dynamicweb/urls.py
@@ -49,9 +49,14 @@ urlpatterns += i18n_patterns(
include('ungleich_page.urls',
namespace='ungleich_page'),
name='ungleich_page'),
- url(r'^blog/', include('ungleich.urls',
- namespace='ungleich')),
- url(r'^', include('cms.urls'))
+ url(r'^cms/blog/',
+ include('ungleich.urls', namespace='ungleich')),
+ url(
+ r'^blog/(?P\d{4})/(?P\d{1,2})/(?P\d{1,2})/(?P\w[-\w]*)/$',
+ RedirectView.as_view(pattern_name='ungleich:post-detail')),
+ url(r'^blog/|cms/$', RedirectView.as_view(
+ url=reverse_lazy('ungleich:post-list')), name='blog_list_view'),
+ url(r'^cms/', include('cms.urls')),
)
urlpatterns += [
diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po
index 83dbc3ac..e1a3c694 100644
--- a/hosting/locale/de/LC_MESSAGES/django.po
+++ b/hosting/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-09-23 02:19+0530\n"
+"POT-Creation-Date: 2017-09-24 12:34+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -28,10 +28,10 @@ msgid "User does not exist"
msgstr "Der Benutzer existiert nicht"
msgid "Paste here your public key"
-msgstr "Füge deinen Public Key ein"
+msgstr "Füge Deinen Public Key ein"
msgid "Give a name to your key"
-msgstr "Gebe deinem SSH-Key einen Name"
+msgstr "Gebe Deinem SSH-Key einen Name"
msgid "Key name"
msgstr "Key-Name"
@@ -110,6 +110,27 @@ msgstr "vorherige"
msgid "next"
msgstr "nächste"
+msgid "Month"
+msgstr "Monat"
+
+msgid "VAT included"
+msgstr "MwSt. inklusive"
+
+msgid "Please enter a value in range 1 - 48."
+msgstr "Bitte gib einen Wert von 1 bis 48 ein."
+
+msgid "Please enter a value in range 2 - 200."
+msgstr "Bitte gib einen Wert von 2 bis 200 ein."
+
+msgid "Please enter a value in range 10 - 2000."
+msgstr "Bitte gib einen Wert von 10 bis 200 ein."
+
+msgid "GB Storage (SSD)"
+msgstr "GB Storage (SSD)"
+
+msgid "Continue"
+msgstr "Weiter"
+
msgid "SSH Key"
msgstr "SSH Key"
@@ -135,10 +156,10 @@ msgid "Upload"
msgstr "Hochladen"
msgid "Your VM hosted in Switzerland"
-msgstr "deine VM in der Schweiz"
+msgstr "Deine VM in der Schweiz"
msgid "Set your new password"
-msgstr "Setze dein neues Passwort"
+msgstr "Setze Dein neues Passwort"
msgid "Reset"
msgstr "Zurücksetzen"
@@ -149,35 +170,17 @@ msgstr "Hast Du bereits ein Benutzerkonto?"
msgid "Login"
msgstr "Anmelden"
-msgid "New Virtual Machine"
-msgstr "Neue virtuelle Maschine"
-
-msgid "Step 1. Select VM Template:"
-msgstr "Wähle eine Vorlage"
-
-msgid "Step2. Select VM Configuration"
-msgstr "Wähle eine Konfiguration"
-
-msgid "Price "
-msgstr "Preis"
-
-msgid "CHF/Month"
-msgstr "CHF/Monat"
-
-msgid "Start VM"
-msgstr "VM jetzt starten"
+msgid "Create VM"
+msgstr "VM erstellen"
msgid "My Dashboard"
msgstr "Mein Dashboard"
-msgid "Create VM"
-msgstr "VM erstellen"
-
msgid "My VMs"
msgstr "Meine VMs"
msgid "My SSH Keys"
-msgstr "Meine SSH Keys"
+msgstr "Meine SSH-Keys"
msgid "My Bills"
msgstr "Meine Rechnungen"
@@ -229,6 +232,40 @@ msgstr "Dankeschön!"
msgid "Virtual Machine Cancellation"
msgstr "VM Kündigung"
+#, python-format
+msgid ""
+"\n"
+"You're receiving this email because you requested a password reset for your "
+"user account at %(site_name)s.
\n"
+"Please go to the following page and choose a new password: %(base_url)s"
+"%(password_reset_url)s
\n"
+"If you didn't request a new password, ignore this e-mail.
\n"
+"Thank you!\n"
+msgstr ""
+"\n"
+"Du erhälst diese E-Mail da Du Dein Passwort für Deinen Account bei "
+"%(site_name)s zurücksetzen möchtest.
\n"
+"Bitte folge diesem Link und wähle ein neues Passwort: %(base_url)s"
+"%(password_reset_url)s Solltest Du kein neues Passwort angefordert haben, "
+"dann ignoriere diese E-Mail.
\n"
+"Dankeschön!\n"
+
+#, python-format
+msgid ""
+"You're receiving this email because you requested a password reset for your "
+"user account at %(site_name)s.\n"
+"Please go to the following page and choose a new password: %(base_url)s"
+"%(password_reset_url)s\n"
+"If you didn't request a new password, ignore this e-mail.\n"
+"Thank you!\n"
+msgstr ""
+"Du erhälst diese E-Mail da Du Dein Passwort für Deinen Account bei "
+"%(site_name)s zurücksetzen möchtest.\n"
+"Bitte folge diesem Link und wähle ein neues Passwort: %(base_url)s"
+"%(password_reset_url)s Solltest Du kein neues Passwort angefordert haben, "
+"dann ignoriere diese E-Mail.\n"
+"Dankeschön!\n"
+
#, python-format
msgid ""
"You are receiving this email because your virutal machine [%(vm_name)s] has "
@@ -246,11 +283,29 @@ msgstr "NEUE VM"
msgid "You can always order a new VM by following the link below."
msgstr ""
+#, python-format
+msgid ""
+"You're receiving this mail because your virtual machine [%(vm_name)s] has "
+"been cancelled.\n"
+"You can see your order status by clicking here\n"
+"%(base_url)s%(vm_order_url)s\n"
+"If you want to order a new virtual machine, you can do it by clicking this "
+"link.\n"
+"%(base_url)s%(my_virtual_machines_url)s\n"
+msgstr ""
+"Du erhälst diese E-Mail, da Deine virtuelle Maschine [%(vm_name)s] gekündigt "
+"wurde.\n"
+"Um Deinen Auftragsstatus zu sehen, klicke hier.\n"
+"%(base_url)s%(vm_order_url)s\n"
+"Falls Du eine neue virtuelle Maschine bestellen möchtest, kannst Du dies "
+"tun, indem Du diesen Link klickst.\n"
+"%(base_url)s%(my_virtual_machines_url)s\n"
+
msgid "Toggle navigation"
-msgstr "Konfiguration"
+msgstr "Umschalten"
msgid "Dashboard"
-msgstr "Mein Dashboard"
+msgstr "Dashboard"
msgid "Logout"
msgstr "Abmelden"
@@ -264,6 +319,9 @@ msgstr "Registrieren"
msgid "Forgot your password ? "
msgstr "Passwort vergessen?"
+msgid "Resend activation link"
+msgstr "Aktivierungslink noch einmal senden"
+
msgid "Notifications"
msgstr "Benachrichtigungen"
@@ -282,10 +340,14 @@ msgstr "Als gelesen markieren"
msgid "All notifications"
msgstr "Alle Benachrichtigungen"
-msgid "Date"
-msgstr "Datum"
+#, python-format
+msgid "%(page_header_text)s"
+msgstr ""
-msgid "Status:"
+msgid "Invoice Date"
+msgstr "Rechnung Datum"
+
+msgid "Status"
msgstr ""
msgid "Approved"
@@ -294,10 +356,10 @@ msgstr "Akzeptiert"
msgid "Declined"
msgstr "Abgelehnt"
-msgid "Billed To:"
+msgid "Billed to"
msgstr "Rechnungsadresse"
-msgid "Payment Method:"
+msgid "Payment method"
msgstr "Bezahlmethode"
msgid "ending in"
@@ -306,6 +368,9 @@ msgstr "endend in"
msgid "Order summary"
msgstr "Bestellungsübersicht"
+msgid "Product"
+msgstr "Produkt"
+
msgid "Cores"
msgstr "Prozessorkerne"
@@ -315,15 +380,9 @@ msgstr "Arbeitsspeicher"
msgid "Disk space"
msgstr "Festplattenkapazität"
-msgid "Configuration"
-msgstr "Konfiguration"
-
msgid "Total"
msgstr "Gesamt"
-msgid "Month"
-msgstr "Monat"
-
#, python-format
msgid ""
"By clicking \"Place order\" this plan will charge your credit card account "
@@ -333,7 +392,10 @@ msgstr ""
"pro Monat belastet"
msgid "Place order"
-msgstr "Bestelle"
+msgstr "Bestellen"
+
+msgid "BACK TO LIST"
+msgstr "ZURÜCK ZUR LISTE"
msgid "Processing..."
msgstr "Abarbeitung..."
@@ -347,14 +409,14 @@ msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
msgid "Order Nr."
msgstr "Bestellung Nr."
+msgid "Date"
+msgstr "Datum"
+
msgid "Amount"
msgstr "Betrag"
-msgid "Status"
-msgstr ""
-
msgid "See Invoice"
-msgstr "Rechnung"
+msgstr "Siehe Rechnung"
msgid "Page"
msgstr ""
@@ -365,6 +427,9 @@ msgstr ""
msgid "Your Order"
msgstr "Deine Bestellung"
+msgid "Configuration"
+msgstr "Konfiguration"
+
msgid "including VAT"
msgstr "inkl. Mehrwertsteuer"
@@ -512,6 +577,9 @@ msgstr "Aktueller Preis"
msgid "Your VM is"
msgstr "Deine VM ist"
+msgid "Terminating"
+msgstr "Beenden"
+
msgid "Pending"
msgstr "In Vorbereitung"
@@ -524,6 +592,11 @@ msgstr "Fehlgeschlagen"
msgid "Terminate VM"
msgstr "VM Beenden"
+msgid "Sorry, there was an unexpected error. Kindly retry."
+msgstr ""
+"Bitte entschuldige, es scheint ein unerwarteter Fehler aufgetreten zu sein. "
+"Versuche es doch bitte noch einmal."
+
msgid "Something doesn't work?"
msgstr "Etwas funktioniert nicht?"
@@ -531,10 +604,7 @@ msgid "We are here to help you!"
msgstr "Wir sind hier, um Dir zu helfen!"
msgid "CONTACT"
-msgstr "KONTACT"
-
-msgid "BACK TO LIST"
-msgstr "ZURÜCK ZUR LISTE"
+msgstr "KONTAKT"
msgid "Terminate your Virtual Machine"
msgstr "Deine Virtuelle Maschine beenden"
@@ -545,6 +615,14 @@ msgstr "Bist Du sicher, dass Du Deine virtuelle Maschine beenden willst"
msgid "OK"
msgstr ""
+#, python-format
+msgid ""
+"Your Virtual Machine %(machine_name)s is successfully "
+"terminated!"
+msgstr ""
+"Deine Virtuelle Machine (VM) %(machine_name)s wurde erfolgreich "
+"beendet!"
+
msgid "Virtual Machines"
msgstr "Virtuelle Maschinen"
@@ -579,13 +657,13 @@ msgid "Sorry. Your request is invalid."
msgstr "Entschuldigung, deine Anfrage ist ungültig."
msgid "Password has been reset."
-msgstr ""
+msgstr "Dein Passwort wurde erfolgreich zurückgesetzt."
msgid "Password reset has not been successful."
-msgstr ""
+msgstr "Dein Passwort konnte nicht zurückgesetzt werden."
msgid "The reset password link is no longer valid."
-msgstr ""
+msgstr "Der Link zum Zurücksetzen Deines Passwortes ist nicht mehr gültig."
msgid "Invalid credit card"
msgstr "Ungültige Kreditkarte"
@@ -593,6 +671,15 @@ msgstr "Ungültige Kreditkarte"
msgid "Confirm Order"
msgstr "Bestellung Bestätigen"
+msgid ""
+"The VM you are looking for is unavailable at the moment. Please contact Data "
+"Center Light support."
+msgstr "Kontaktiere den Data Center Light Support."
+
+msgid "In order to create a VM, you need to create/upload your SSH KEY first."
+msgstr ""
+"Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen."
+
msgid "Thank you for the order."
msgstr "Danke für Deine Bestellung."
@@ -603,9 +690,14 @@ msgstr ""
"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du "
"auf sie zugreifen kannst."
-msgid "In order to create a VM, you need to create/upload your SSH KEY first."
-msgstr ""
-"Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen."
+msgid "Invalid number of cores"
+msgstr "Ungültige Anzahle CPU-Kerne"
+
+msgid "Invalid RAM size"
+msgstr "Ungültige RAM-Grösse"
+
+msgid "Invalid storage size"
+msgstr "Ungültige Speicher-Grösse"
msgid ""
"We could not find the requested VM. Please "
@@ -616,6 +708,42 @@ msgstr "Kontaktiere den Data Center Light Support."
msgid "VM %(VM_ID)s terminated successfully"
msgstr "VM %(VM_ID)s erfolgreich beendet"
+msgid "Terminated"
+msgstr "Beendet"
+
+msgid "Error terminating VM"
+msgstr "Fehler beenden VM"
+
+msgid "Virtual Machine Cancellation"
+msgstr "VM Kündigung"
+
+#~ msgid "Close"
+#~ msgstr "Schliessen"
+
+#~ msgid "VM %(VM_ID)s terminated successfully"
+#~ msgstr "VM %(VM_ID)s erfolgreich beendet"
+
+#~ msgid "days"
+#~ msgstr "Tage"
+
+#~ msgid "New Virtual Machine"
+#~ msgstr "Neue virtuelle Maschine"
+
+#~ msgid "Step 1. Select VM Template:"
+#~ msgstr "Wähle eine Vorlage"
+
+#~ msgid "Step2. Select VM Configuration"
+#~ msgstr "Wähle eine Konfiguration"
+
+#~ msgid "Price "
+#~ msgstr "Preis"
+
+#~ msgid "CHF/Month"
+#~ msgstr "CHF/Monat"
+
+#~ msgid "Start VM"
+#~ msgstr "VM jetzt starten"
+
#~ msgid "View Invoice"
#~ msgstr "Zur Rechnung"
@@ -693,7 +821,7 @@ msgstr "VM %(VM_ID)s erfolgreich beendet"
#~ msgstr "Meine Bestellungen"
#~ msgid "SSH Keys"
-#~ msgstr "SSH Key"
+#~ msgstr "SSH Keys"
#~ msgid "Notifications "
#~ msgstr "Benachrichtigungen"
@@ -734,9 +862,6 @@ msgstr "VM %(VM_ID)s erfolgreich beendet"
#~ msgid "Ipv6"
#~ msgstr "IPv6"
-#~ msgid "Close"
-#~ msgstr "Schliessen"
-
#~ msgid "Cancel"
#~ msgstr "Beenden"
@@ -744,19 +869,19 @@ msgstr "VM %(VM_ID)s erfolgreich beendet"
#~ msgstr "Hinzufügen"
#~ msgid "Keys"
-#~ msgstr "Schlüssel"
+#~ msgstr "Keys"
#~ msgid "Log in"
#~ msgstr "Anmelden"
#~ msgid "You haven been logged out"
-#~ msgstr "Sie wurden abgmeldet"
+#~ msgstr "Du wurdest abgemeldet"
#~ msgid "How it works"
#~ msgstr "So funktioniert es"
#~ msgid "Your infrastructure"
-#~ msgstr "deine Infrastruktur"
+#~ msgstr "Deine Infrastruktur"
#~ msgid "Our inftrastructure"
#~ msgstr "Unsere Infrastruktur"
@@ -765,10 +890,10 @@ msgstr "VM %(VM_ID)s erfolgreich beendet"
#~ msgstr "Preise"
#~ msgid "Access Key"
-#~ msgstr "Zugriffsschlüssel"
+#~ msgstr "SSH Key"
#~ msgid "Upload your own key. "
-#~ msgstr "Lade deinen Key hoch"
+#~ msgstr "Lade Deinen Key hoch"
#~ msgid "Generate Key Pair"
#~ msgstr "Schlüsselpaar generieren"
@@ -792,5 +917,5 @@ msgstr "VM %(VM_ID)s erfolgreich beendet"
#~ "Your SSH private key was already generated and downloaded, if you lost "
#~ "it, contact us. "
#~ msgstr ""
-#~ "Dein privater SSH Schlüssel wurde bereits generiert und heruntergeladen. "
-#~ "Falls du ihn verloren hast, kontaktiere uns."
+#~ "Dein privater SSH Key wurde bereits generiert und heruntergeladen. "
+#~ "Falls Du ihn verloren hast, kontaktiere uns."
diff --git a/hosting/static/hosting/css/commons.css b/hosting/static/hosting/css/commons.css
index 01ff5090..317caabc 100644
--- a/hosting/static/hosting/css/commons.css
+++ b/hosting/static/hosting/css/commons.css
@@ -139,6 +139,10 @@
.modal-text p:not(:last-of-type){
margin-bottom: 5px;
}
+
+.modal-title + .modal-footer {
+ margin-top: 5px;
+}
.modal-footer {
border-top: 0px solid #e5e5e5;
width: 100%;
@@ -355,4 +359,20 @@
.no-cards a {
color: #7ca3d0;
+}
+
+.btn-plain {
+ background: transparent;
+ border: none;
+ fill: #595959;
+ color: #595959;
+ outline: none;
+}
+.btn-plain:hover,
+.btn-plain:focus,
+.btn-plain:active,
+.btn-plain:active:focus {
+ outline: none;
+ color: #999;
+ fill: #999;
}
\ No newline at end of file
diff --git a/hosting/static/hosting/css/landing-page.css b/hosting/static/hosting/css/landing-page.css
index 71b7a33d..ed8fb310 100644
--- a/hosting/static/hosting/css/landing-page.css
+++ b/hosting/static/hosting/css/landing-page.css
@@ -580,9 +580,9 @@ a.unlink:hover {
}
.dcl-place-order-text{
- font-size: 13px;
+ /* font-size: 13px; */
color: #808080;
- margin-bottom: 15px;
+ /* margin-bottom: 15px; */
}
.dcl-order-table-total .tbl-total {
@@ -853,6 +853,9 @@ a.list-group-item-danger:focus,
.panel-danger > .panel-heading {
color: #eb4d5c;
}
+.alert-danger{
+ background: rgba(235, 204, 209, 0.2);
+}
.has-error .form-control,
.has-error .input-group-addon {
color: #eb4d5c;
diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css
index e8bc0328..8e9226e2 100644
--- a/hosting/static/hosting/css/order.css
+++ b/hosting/static/hosting/css/order.css
@@ -1,4 +1,15 @@
-.order-detail-container {padding-top: 70px; padding-bottom: 70px; margin-bottom: 70px;}
+.order-detail-container {
+ max-width: 600px;
+ margin: 100px auto 40px;
+ border: 1px solid #ccc;
+ padding: 15px;
+}
+
+@media(min-width: 768px) {
+ .order-detail-container {
+ padding: 30px;
+ }
+}
.order-detail-container .invoice-title h2, .invoice-title h3 {
display: inline-block;
@@ -15,3 +26,67 @@
.order-detail-container .table > tbody > tr > .thick-line {
border-top: 2px solid;
}
+
+.order-detail-container .dashboard-title-thin {
+ margin-top: 0;
+ margin-left: -3px;
+}
+
+.order-detail-container .dashboard-title-thin .un-icon {
+ margin-top: -6px;
+}
+
+.order-detail-container .dashboard-container-head {
+ position: relative;
+ padding: 0;
+ margin-bottom: 38px;
+}
+
+.order-detail-container .dashboard-container-options {
+ position: absolute;
+ top: 10px;
+ right: 0;
+}
+.order-detail-container .dashboard-container-options .svg-img {
+ height: 22px;
+ width: 22px;
+}
+
+.order-detail-container .order-details {
+ margin-bottom: 30px;
+}
+
+.order-detail-container .order-details strong {
+ color: #595959;
+}
+
+.order-detail-container h4 {
+ font-size: 16px;
+ font-weight: bold;
+ margin-bottom: 10px;
+}
+
+.order-detail-container p {
+ margin-bottom: 5px;
+ color: #595959;
+}
+
+.order-detail-container hr {
+ margin: 15px 0;
+}
+
+@media (max-width: 767px) {
+ .order-confirm-btn {
+ text-align: center;
+ margin-top: 10px;
+ }
+ .order-detail-container .dashboard-container-options {
+ position: absolute;
+ top: 4px;
+ right: -4px;
+ }
+ .order-detail-container .dashboard-container-options .svg-img {
+ height: 16px;
+ width: 16px;
+ }
+}
diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css
new file mode 100644
index 00000000..24624f10
--- /dev/null
+++ b/hosting/static/hosting/css/price_calculator.css
@@ -0,0 +1,237 @@
+/* Create VM calculator */
+
+.price-calc-section {
+ padding: 80px 40px !important;
+}
+
+@media (max-width: 768px) {
+ .price-calc-section {
+ margin-top: 40px;
+ }
+}
+
+.price-calc-section .text {
+ width: 50%;
+}
+
+.price-calc-section .text .section-heading {
+ font-size: 48px;
+ line-height: 48px;
+ padding-bottom: 27px;
+ color: #3a3a3a;
+ letter-spacing: 1px;
+ position: relative;
+ text-align: right;
+}
+
+.price-calc-section .text .description {
+ font-size: 20px;
+ text-align: right;
+}
+
+.price-calc-section .text .section-heading::before {
+ content: "";
+ position: absolute;
+ bottom: 0;
+ background: #29427A;
+ height: 7px;
+ width: 70px;
+ right: 0;
+}
+
+.price-calc-section .card {
+ width: 50%;
+ margin: 0 auto;
+ background: #fff;
+ box-shadow: 1px 3px 6px 2px rgba(0, 0, 0, 0.2);
+ padding-bottom: 30px;
+ text-align: center;
+ max-width: 320px;
+ position: relative;
+}
+
+@media (min-width: 768px) {
+ .price-calc-section .card {
+ margin-left: 0;
+ }
+}
+
+.price-calc-section .landing {
+ width: 100% !important;
+}
+
+.no-padding {
+ padding: 0 !important;
+}
+
+.price-calc-section .card .img-beta {
+ position: absolute;
+ top: 5px;
+ width: 60px;
+ left: 3px;
+}
+
+.price-calc-section .card .title {
+ padding: 15px 40px;
+}
+
+.price-calc-section .card .title h3 {
+ /*font-family: 'Lato', sans-serif;*/
+ font-weight: normal;
+}
+
+.price-calc-section .card .price {
+ background: #5A74AF;
+ padding: 22px;
+ color: #fff;
+ font-size: 32px;
+}
+
+.price-calc-section .card .price .price-text {
+ font-size: 14px;
+}
+
+.price-calc-section .card .description {
+ padding: 7px 8px 2px;
+ position: relative;
+ display: flex;
+ justify-content: space-around !important;
+ align-items: center !important;
+}
+
+.price-calc-section .card .description span {
+ font-size: 14px;
+ margin-left: 5px;
+ /* margin-left: 0px; */
+ /* justify-self: start; */
+ width: 29%;
+ text-align: left;
+ line-height: 16px;
+ /* font-weight: normal; */
+}
+
+.price-calc-section .card .description .select-number{
+ font-size: 16px;
+ text-align: center;
+ width: 85px;
+}
+
+.price-calc-section .card .description i {
+ color: #29427a;
+ cursor: pointer;
+ font-size: 20px;
+ border: 1px solid #ccc;
+ padding: 5px 6px 3px;
+ border-radius: 5px;
+}
+
+.price-calc-section .card .description .left {
+ margin-right: 7px;
+}
+
+.price-calc-section .card .description .right {
+ margin-left: 7px;
+}
+
+.price-calc-section .card .descriptions {
+ padding: 10px;
+}
+
+.price-calc-section .card .description p {
+ margin: 0;
+}
+
+.price-calc-section .card .btn {
+ margin-top: 15px;
+ font-size: 20px;
+ width: 150px;
+ border: none;
+}
+
+.price-calc-section .card .select-configuration select {
+ outline: none;
+ background: #fff;
+ border-color: #d0d0d0;
+ height: 32px;
+ width: 150px;
+ text-align: center;
+ font-size: 14px;
+ margin-left: 10px;
+ padding: 6px;
+ border-radius: 4px;
+}
+
+.price-calc-section .card .check-ip {
+ font-size: 18px;
+}
+
+.price-calc-section .card .justify-center {
+ justify-content: center !important;
+}
+
+.price-calc-section .card .description.input label {
+ font-size: 15px;
+ font-weight: 700;
+ /*font-weight: 800;*/
+ /*font-family: 'Lato';*/
+ margin-bottom: 0;
+ width: 40px;
+}
+
+
+/*Changed class****.price-calc-section .card .description.input input*/
+
+.price-calc-section .card .description input {
+ width: 200px;
+ font-size: 14px;
+ text-align: left;
+ padding: 4px 10px;
+ border-radius: 4px;
+ border: 1px solid #d0d0d0;
+ background: #fff;
+ margin-left: 10px;
+}
+
+.price-calc-section .card .check-ip input[type=checkbox] {
+ font-size: 17px;
+ margin: 0 8px;
+}
+
+.price-calc-section .help-block.with-errors {
+ text-align: center;
+ margin: 0 0;
+ padding: 0 0 5px;
+}
+.price-calc-section .help-block.with-errors ul {
+ margin-bottom: 0;
+}
+
+.price-calc-section .form-group {
+ margin: 0;
+ position: relative;
+}
+
+.price-calc-section .form-group:after {
+ content: ' ';
+ display: block;
+ position: absolute;
+ bottom: 0;
+ left: 18%;
+ z-index: 20;
+ height: 1px;
+ width: 65%;
+ background: rgba(128, 128, 128, 0.2);
+}
+
+.price-calc-section .btn-primary {
+ background: #29427A;
+ border-color: #29427A;
+ color: #fff;
+ width: auto;
+}
+
+@media(min-width: 768px) {
+ .create-vm-container {
+ padding-top: 120px;
+ }
+}
diff --git a/hosting/static/hosting/css/virtual-machine.css b/hosting/static/hosting/css/virtual-machine.css
index b4916da0..a14abc31 100644
--- a/hosting/static/hosting/css/virtual-machine.css
+++ b/hosting/static/hosting/css/virtual-machine.css
@@ -290,6 +290,11 @@
text-align: center;
}
+.vm-vmid .alert {
+ margin-top: 15px;
+ margin-bottom: -60px;
+}
+
.vm-item-lg {
font-size: 22px;
margin-top: 5px;
@@ -305,6 +310,10 @@
color: #e47f2f;
}
+.vm-color-failed {
+ color: #eb4d5c;
+}
+
.vm-detail-item .value{
font-weight: 400;
}
@@ -512,7 +521,7 @@
color: #87B6EA;
}
-.vm-status, .vm-status-active, .vm-status-failed {
+.vm-status, .vm-status-active, .vm-status-failed, .vm-status-pending {
font-weight: 600;
}
.vm-status-active {
@@ -521,6 +530,9 @@
.vm-status-failed {
color: #eb4d5c;
}
+.vm-status-pending {
+ color: #e47f2f;
+}
@media (min-width:768px) {
.dashboard-subtitle {
@@ -627,4 +639,28 @@
left: auto;
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;
}
\ No newline at end of file
diff --git a/hosting/static/hosting/img/ajax-loader.gif b/hosting/static/hosting/img/ajax-loader.gif
new file mode 100644
index 00000000..a7c3f2ba
Binary files /dev/null and b/hosting/static/hosting/img/ajax-loader.gif differ
diff --git a/hosting/static/hosting/img/icon-pdf.svg b/hosting/static/hosting/img/icon-pdf.svg
new file mode 100644
index 00000000..3743bbb8
--- /dev/null
+++ b/hosting/static/hosting/img/icon-pdf.svg
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file
diff --git a/hosting/static/hosting/img/icon-print.svg b/hosting/static/hosting/img/icon-print.svg
new file mode 100644
index 00000000..75eb175f
--- /dev/null
+++ b/hosting/static/hosting/img/icon-print.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/hosting/static/hosting/js/createvm.js b/hosting/static/hosting/js/createvm.js
index 53646b40..726513ad 100644
--- a/hosting/static/hosting/js/createvm.js
+++ b/hosting/static/hosting/js/createvm.js
@@ -1,73 +1,75 @@
(function($){
"use strict"; // Start of use strict
-
-
- $(window).load(function(){
-
-
- });
-
- $(document).ready(function(){
- _initOs();
-
- });
-
- $(window).resize(function(){
-
-
- });
-
-
- function _initOs(){
-
-
- $('.os-circle').click(function(event){
- $('.os-circle').removeClass('active');
- $(this).addClass('active');
-
- var idTemplate = $(this).data('id');
- $('input[name=vm_template_id]').val(idTemplate);
- });
- $('.config-box').click(function(event){
- $('.config-box').removeClass('active');
- $(this).addClass('active');
- var idConfig = $(this).data('id');
- var price = $(this).data('price');
- $('input[name=configuration]').val(idConfig);
- $('.container-button').fadeIn();
- $('#priceValue').text(price);
- });
-
- $('.owl-carousel').owlCarousel({
- items:4,
- nav: true,
- margin:30,
- responsiveClass:true,
- navText: ['', ''],
- responsive:{
- 0:{
- items:1,
- nav:true
- },
- 600:{
- items:2,
- nav:true
- },
- 768:{
- items:3,
- nav:true
- },
- 990:{
- items:4,
- nav:true
- }
+ var cardPricing = {
+ 'cpu': {
+ 'id': 'coreValue',
+ 'value': 1,
+ 'min': 1,
+ 'max': 48,
+ 'interval': 1
+ },
+ 'ram': {
+ 'id': 'ramValue',
+ 'value': 2,
+ 'min': 2,
+ 'max': 200,
+ 'interval': 1
+ },
+ 'storage': {
+ 'id': 'storageValue',
+ 'value': 10,
+ 'min': 10,
+ 'max': 2000,
+ 'interval': 10
}
- });
- }
-
-
-
-})(jQuery);
+ };
+
+ function _initPricing() {
+ _fetchPricing();
+
+ $('.fa-minus.left').click(function(event) {
+ var data = $(this).data('minus');
+
+ if (cardPricing[data].value > cardPricing[data].min) {
+ cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval;
+ }
+ _fetchPricing();
+ });
+ $('.fa-plus.right').click(function(event) {
+ var data = $(this).data('plus');
+ if (cardPricing[data].value < cardPricing[data].max) {
+ cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval;
+ }
+ _fetchPricing();
+ });
+
+ $('.input-price').change(function() {
+ var data = $(this).attr("name");
+ cardPricing[data].value = $('input[name=' + data + ']').val();
+ _fetchPricing();
+ });
+ }
+
+ function _fetchPricing() {
+ Object.keys(cardPricing).map(function(element) {
+ $('input[name=' + element + ']').val(cardPricing[element].value);
+ });
+ _calcPricing();
+ }
+
+ function _calcPricing() {
+ var total = (cardPricing['cpu'].value * 5) + (2 * cardPricing['ram'].value) + (0.6 * cardPricing['storage'].value);
+ total = parseFloat(total.toFixed(2));
+
+ $("#total").text(total);
+ $('input[name=total]').val(total);
+ }
+
+ $(document).ready(function() {
+ _initPricing();
+ });
+
+})(jQuery);
diff --git a/hosting/static/hosting/js/createvm_old.js b/hosting/static/hosting/js/createvm_old.js
new file mode 100644
index 00000000..53646b40
--- /dev/null
+++ b/hosting/static/hosting/js/createvm_old.js
@@ -0,0 +1,73 @@
+(function($){
+ "use strict"; // Start of use strict
+
+
+ $(window).load(function(){
+
+
+ });
+
+ $(document).ready(function(){
+ _initOs();
+
+ });
+
+ $(window).resize(function(){
+
+
+ });
+
+
+
+ function _initOs(){
+
+
+ $('.os-circle').click(function(event){
+ $('.os-circle').removeClass('active');
+ $(this).addClass('active');
+
+ var idTemplate = $(this).data('id');
+ $('input[name=vm_template_id]').val(idTemplate);
+ });
+ $('.config-box').click(function(event){
+ $('.config-box').removeClass('active');
+ $(this).addClass('active');
+ var idConfig = $(this).data('id');
+ var price = $(this).data('price');
+ $('input[name=configuration]').val(idConfig);
+ $('.container-button').fadeIn();
+ $('#priceValue').text(price);
+ });
+
+ $('.owl-carousel').owlCarousel({
+ items:4,
+ nav: true,
+ margin:30,
+ responsiveClass:true,
+ navText: ['', ''],
+ responsive:{
+ 0:{
+ items:1,
+ nav:true
+ },
+ 600:{
+ items:2,
+ nav:true
+ },
+ 768:{
+ items:3,
+ nav:true
+ },
+ 990:{
+ items:4,
+ nav:true
+ }
+ }
+ });
+ }
+
+
+
+})(jQuery);
+
+
diff --git a/hosting/static/hosting/js/html2pdf.js b/hosting/static/hosting/js/html2pdf.js
new file mode 100644
index 00000000..45ae5b0c
--- /dev/null
+++ b/hosting/static/hosting/js/html2pdf.js
@@ -0,0 +1,387 @@
+/**
+ * @license
+ *
+ * MIT License
+ *
+ * Copyright (c) 2017 Erik Koopmans
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * Generate a PDF from an HTML element or string using html2canvas and jsPDF.
+ *
+ * @param {Element|string} source The source element or HTML string.
+ * @param {Object=} opt An object of optional settings: 'margin', 'filename',
+ * 'image' ('type' and 'quality'), and 'html2canvas' / 'jspdf', which are
+ * sent as settings to their corresponding functions.
+ */
+var html2pdf = (function(html2canvas, jsPDF) {
+
+ /* ---------- MAIN FUNCTION ---------- */
+
+ var html2pdf = function(source, opt) {
+ // Handle input.
+ opt = objType(opt) === 'object' ? opt : {};
+ var source = html2pdf.parseInput(source, opt);
+
+ // Determine the PDF page size.
+ var pageSize = jsPDF.getPageSize(opt.jsPDF);
+ pageSize.inner = {
+ width: pageSize.width - opt.margin[1] - opt.margin[3],
+ height: pageSize.height - opt.margin[0] - opt.margin[2]
+ };
+ pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
+
+ // Copy the source element into a PDF-styled container div.
+ var container = html2pdf.makeContainer(source, pageSize);
+ var overlay = container.parentElement;
+
+ // Get the locations of all hyperlinks.
+ if (opt.enableLinks) {
+ // Find all anchor tags and get the container's bounds for reference.
+ opt.links = [];
+ var links = container.querySelectorAll('a');
+ var containerRect = unitConvert(container.getBoundingClientRect(), pageSize.k);
+
+ // Treat each client rect as a separate link (for text-wrapping).
+ Array.prototype.forEach.call(links, function(link) {
+ var clientRects = link.getClientRects();
+ for (var i=0; i pageTop && link.clientRect.top < pageTop + pageSize.inner.height) {
+ var left = opt.margin[1] + link.clientRect.left;
+ var top = opt.margin[0] + link.clientRect.top - pageTop;
+ pdf.link(left, top, link.clientRect.width, link.clientRect.height, { url: link.el.href });
+ }
+ });
+ }
+ }
+
+ // Finish the PDF.
+ pdf.save( opt.filename );
+ }
+
+
+ /* ---------- UTILS ---------- */
+
+ // Determine the type of a variable/object.
+ var objType = function(obj) {
+ if (typeof obj === 'undefined') return 'undefined';
+ else if (typeof obj === 'string' || obj instanceof String) return 'string';
+ else if (typeof obj === 'number' || obj instanceof Number) return 'number';
+ else if (!!obj && obj.constructor === Array) return 'array';
+ else if (obj && obj.nodeType === 1) return 'element';
+ else if (typeof obj === 'object') return 'object';
+ else return 'unknown';
+ };
+
+ // Create an HTML element with optional className, innerHTML, and style.
+ var createElement = function(tagName, opt) {
+ var el = document.createElement(tagName);
+ if (opt.className) el.className = opt.className;
+ if (opt.innerHTML) {
+ el.innerHTML = opt.innerHTML;
+ var scripts = el.getElementsByTagName('script');
+ for (var i = scripts.length; i-- > 0; null) {
+ scripts[i].parentNode.removeChild(scripts[i]);
+ }
+ }
+ for (var key in opt.style) {
+ el.style[key] = opt.style[key];
+ }
+ return el;
+ };
+
+ // Deep-clone a node and preserve contents/properties.
+ var cloneNode = function(node, javascriptEnabled) {
+ // Recursively clone the node.
+ var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
+ clone.appendChild(cloneNode(child, javascriptEnabled));
+ }
+ }
+
+ if (node.nodeType === 1) {
+ // Preserve contents/properties of special nodes.
+ if (node.nodeName === 'CANVAS') {
+ clone.width = node.width;
+ clone.height = node.height;
+ clone.getContext('2d').drawImage(node, 0, 0);
+ } else if (node.nodeName === 'TEXTAREA' || node.nodeName === 'SELECT') {
+ clone.value = node.value;
+ }
+
+ // Preserve the node's scroll position when it loads.
+ clone.addEventListener('load', function() {
+ clone.scrollTop = node.scrollTop;
+ clone.scrollLeft = node.scrollLeft;
+ }, true);
+ }
+
+ // Return the cloned node.
+ return clone;
+ }
+
+ // Convert units using the conversion value 'k' from jsPDF.
+ var unitConvert = function(obj, k) {
+ var newObj = {};
+ for (var key in obj) {
+ newObj[key] = obj[key] * 72 / 96 / k;
+ }
+ return newObj;
+ };
+
+ // Get dimensions of a PDF page, as determined by jsPDF.
+ jsPDF.getPageSize = function(orientation, unit, format) {
+ // Decode options object
+ if (typeof orientation === 'object') {
+ var options = orientation;
+ orientation = options.orientation;
+ unit = options.unit || unit;
+ format = options.format || format;
+ }
+
+ // Default options
+ unit = unit || 'mm';
+ format = format || 'a4';
+ orientation = ('' + (orientation || 'P')).toLowerCase();
+ var format_as_string = ('' + format).toLowerCase();
+
+ // Size in pt of various paper formats
+ pageFormats = {
+ 'a0' : [2383.94, 3370.39], 'a1' : [1683.78, 2383.94],
+ 'a2' : [1190.55, 1683.78], 'a3' : [ 841.89, 1190.55],
+ 'a4' : [ 595.28, 841.89], 'a5' : [ 419.53, 595.28],
+ 'a6' : [ 297.64, 419.53], 'a7' : [ 209.76, 297.64],
+ 'a8' : [ 147.40, 209.76], 'a9' : [ 104.88, 147.40],
+ 'a10' : [ 73.70, 104.88], 'b0' : [2834.65, 4008.19],
+ 'b1' : [2004.09, 2834.65], 'b2' : [1417.32, 2004.09],
+ 'b3' : [1000.63, 1417.32], 'b4' : [ 708.66, 1000.63],
+ 'b5' : [ 498.90, 708.66], 'b6' : [ 354.33, 498.90],
+ 'b7' : [ 249.45, 354.33], 'b8' : [ 175.75, 249.45],
+ 'b9' : [ 124.72, 175.75], 'b10' : [ 87.87, 124.72],
+ 'c0' : [2599.37, 3676.54], 'c1' : [1836.85, 2599.37],
+ 'c2' : [1298.27, 1836.85], 'c3' : [ 918.43, 1298.27],
+ 'c4' : [ 649.13, 918.43], 'c5' : [ 459.21, 649.13],
+ 'c6' : [ 323.15, 459.21], 'c7' : [ 229.61, 323.15],
+ 'c8' : [ 161.57, 229.61], 'c9' : [ 113.39, 161.57],
+ 'c10' : [ 79.37, 113.39], 'dl' : [ 311.81, 623.62],
+ 'letter' : [612, 792],
+ 'government-letter' : [576, 756],
+ 'legal' : [612, 1008],
+ 'junior-legal' : [576, 360],
+ 'ledger' : [1224, 792],
+ 'tabloid' : [792, 1224],
+ 'credit-card' : [153, 243]
+ };
+
+ // Unit conversion
+ switch (unit) {
+ case 'pt': k = 1; break;
+ case 'mm': k = 72 / 25.4; break;
+ case 'cm': k = 72 / 2.54; break;
+ case 'in': k = 72; break;
+ case 'px': k = 72 / 96; break;
+ case 'pc': k = 12; break;
+ case 'em': k = 12; break;
+ case 'ex': k = 6; break;
+ default:
+ throw ('Invalid unit: ' + unit);
+ }
+
+ // Dimensions are stored as user units and converted to points on output
+ if (pageFormats.hasOwnProperty(format_as_string)) {
+ pageHeight = pageFormats[format_as_string][1] / k;
+ pageWidth = pageFormats[format_as_string][0] / k;
+ } else {
+ try {
+ pageHeight = format[1];
+ pageWidth = format[0];
+ } catch (err) {
+ throw new Error('Invalid format: ' + format);
+ }
+ }
+
+ // Handle page orientation
+ if (orientation === 'p' || orientation === 'portrait') {
+ orientation = 'p';
+ if (pageWidth > pageHeight) {
+ tmp = pageWidth;
+ pageWidth = pageHeight;
+ pageHeight = tmp;
+ }
+ } else if (orientation === 'l' || orientation === 'landscape') {
+ orientation = 'l';
+ if (pageHeight > pageWidth) {
+ tmp = pageWidth;
+ pageWidth = pageHeight;
+ pageHeight = tmp;
+ }
+ } else {
+ throw('Invalid orientation: ' + orientation);
+ }
+
+ // Return information (k is the unit conversion ratio from pts)
+ var info = { 'width': pageWidth, 'height': pageHeight, 'unit': unit, 'k': k };
+ return info;
+ };
+
+
+ // Expose the html2pdf function.
+ return html2pdf;
+}(html2canvas, jsPDF));
diff --git a/hosting/static/hosting/js/order.js b/hosting/static/hosting/js/order.js
new file mode 100644
index 00000000..e9de4cf9
--- /dev/null
+++ b/hosting/static/hosting/js/order.js
@@ -0,0 +1,15 @@
+$(document).ready(function() {
+ $('.btn-pdf').click(function(e) {
+ e.preventDefault();
+ var $target = $($(this).attr('data-target')) || $('body');
+ var fileName = $target.attr('id') + '.pdf';
+ html2pdf($target[0], {
+ filename: fileName,
+ });
+ });
+ $('.btn-print').click(function(e) {
+ e.preventDefault();
+ console.log('a');
+ window.print();
+ });
+});
\ No newline at end of file
diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js
index b6202e97..db2621c1 100644
--- a/hosting/static/hosting/js/virtual_machine_detail.js
+++ b/hosting/static/hosting/js/virtual_machine_detail.js
@@ -1,4 +1,85 @@
-$(document).ready(function () {
+function VMTerminateStatus($container, url) {
+ $.ajax({
+ url: url,
+ type: 'GET',
+ dataType: 'json',
+ success: function(data) {
+ VMTerminateSuccess($container, data);
+ },
+ error: function() {
+ setTimeout(function(){
+ VMTerminateStatus($container, url);
+ }, 5000);
+ }
+ });
+}
+
+function VMTerminateActive($container, altText) {
+ $container.find('.alert-danger').addClass('hide');
+ $container.addClass('processing')
+ .find('.vm-item-lg').attr('class', '')
+ .addClass('vm-item-lg vm-color-failed')
+ .text(altText);
+ $container.find('.btn').prop('disabled', true);
+ $('#confirm-cancel').modal('hide');
+}
+
+function VMTerminateSuccess($container, data) {
+ $container.addClass('terminate-success')
+ .find('.vm-item-lg').text(data.text);
+ $container.find('.btn').remove();
+ $('#terminate-success').modal('show');
+}
+
+function VMTerminateFail($container, data, text) {
+ $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');
+ $container.removeClass('processing');
+}
+
+
+$(document).ready(function() {
+ $('#confirm-cancel').on('click', '.btn-ok', function(e) {
+ var url = $('#virtual_machine_cancel_form').attr('action');
+ var $container = $('#terminate-VM');
+ var text = $container.find('.vm-item-lg').text();
+ var altText = $container.attr('data-alt');
+ VMTerminateActive($container, altText);
+
+ $.post(url)
+ .done(function(data) {
+ if (data.status == true) {
+ VMTerminateSuccess($container, data);
+ } else {
+ if ('text' in data) {
+ VMTerminateFail($container, data, text);
+ } else {
+ VMTerminateStatus($container, url);
+ }
+ }
+ })
+ .fail(function(data) {
+ if (data.status==504) {
+ VMTerminateStatus($container, url);
+ } else {
+ VMTerminateFail($container, data, text);
+ }
+ })
+ });
+
+ var hash = window.location.hash;
+ hash && $('ul.nav a[href="' + hash + '"]').tab('show');
+
+ $('.nav-tabs a').click(function(e) {
+ $(this).tab('show');
+ var scrollmem = $('body').scrollTop() || $('html').scrollTop();
+ window.location.hash = this.hash;
+ $('html,body').scrollTop(scrollmem);
+ });
+
+ $('.modal-text').removeClass('hide');
var create_vm_form = $('#virtual_machine_create_form');
create_vm_form.submit(function () {
$('#btn-create-vm').prop('disabled', true);
@@ -22,6 +103,7 @@ $(document).ready(function () {
fa_icon = $('.modal-icon > .fa');
fa_icon.attr('class', 'fa fa-times');
$('.modal-header > .close').attr('class', 'close');
+ $('.modal-text').addClass('hide');
if (typeof(create_vm_error_message) !== 'undefined') {
$('#createvm-modal-title').text(create_vm_error_message);
}
@@ -30,19 +112,4 @@ $(document).ready(function () {
});
return false;
});
-
- $('#confirm-cancel').on('click', '.btn-ok', function (e) {
- $('#virtual_machine_cancel_form').trigger('submit');
- });
-
- var hash = window.location.hash;
- hash && $('ul.nav a[href="' + hash + '"]').tab('show');
-
- $('.nav-tabs a').click(function (e) {
- $(this).tab('show');
- var scrollmem = $('body').scrollTop() || $('html').scrollTop();
- window.location.hash = this.hash;
- $('html,body').scrollTop(scrollmem);
- });
-
});
diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html
index 63a0681d..5cf0953c 100644
--- a/hosting/templates/hosting/base_short.html
+++ b/hosting/templates/hosting/base_short.html
@@ -25,6 +25,7 @@
+
{% block css_extra %}
{% endblock css_extra %}
@@ -33,9 +34,6 @@
-
-
-
@@ -76,8 +74,8 @@
{% endif %}
-
-
+
+
@@ -94,6 +92,13 @@
+ {% block js_extra %}
+ {% comment %}
+ this block is above some files, because on stripe error scripts below the stripe
+ script are not properly executed.
+ {% endcomment %}
+ {% endblock js_extra %}
+
@@ -108,8 +113,6 @@
-
-