Commit c02d3a8c authored by Kostas Papadimitriou's avatar Kostas Papadimitriou
Browse files

ui: Resize view improvements

- Display grayed out start button if no available quota to start the
  corresponding vm
- Open resize overlay instead of start confirmation for the above cases
- Allow overlimit resizing of inactive machines
- Minor styling fixes
parent 7ee2fc15
......@@ -1060,6 +1060,11 @@ div.machine div.actions .disabled {
display: none;
}
div.machine div.actions .disabled-visible a,
div.machine div.vm-actions .disabled-visible a {
color: #aaa;
}
div.single-container div.vm-actions .disabled {
display: none;
}
......@@ -4767,6 +4772,7 @@ table.list-machines .wave {
font-size: 0.8em;
}
.overlay .start-warn .important,
.overlay .v6-warn .important {
display: block;
margin: 8px 0;
......@@ -5739,6 +5745,16 @@ table.list-machines .wave {
border: 1px solid #C97943;
}
.create-vm .flavor-options-cont .flavor-options li.selected.disabled {
background-color: #AAA;
background-image:linear-gradient(top, #AAA, #E88B4D);
background-image:-webkit-linear-gradient(top, #AAA, #E88B4D);
background-image:-o-linear-gradient(top, #AAA, #E88B4D);
background-image:-moz-linear-gradient(top, #AAA, #E88B4D);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#AAAAAA', endColorstr='#E88B4D', GradientType=0);
border: 1px solid #999;
}
.create-vm .predefined-list li.disabled {
color: #ddd !important;
}
......
......@@ -1103,6 +1103,25 @@
models.VM.__super__.unbind.apply(this, arguments);
},
can_start: function(flv, count_current) {
var get_quota = function(key) {
return synnefo.storage.quotas.get(key).get('available');
}
var flavor = flv || this.get_flavor();
var vm_ram_current = 0, vm_cpu_current = 0;
if (flv && this.is_active() || flv && count_current) {
var current = this.get_flavor();
vm_ram_current = current.ram_to_bytes();
vm_cpu_current = parseInt(current.get('cpu'));
}
var vm_ram = flavor.ram_to_bytes();
var vm_cpu = parseInt(flavor.get('cpu'));
var available_cpu = get_quota('cyclades.cpu') + vm_cpu_current;
var available_ram = get_quota('cyclades.ram') + vm_ram_current;
if (vm_ram > available_ram || vm_cpu > available_cpu) { return false }
return true
},
can_connect: function() {
return _.contains(["ACTIVE", "STOPPED"], this.get("status")) &&
!this.get('suspended')
......@@ -1328,9 +1347,9 @@
get_flavor_quotas: function() {
var flavor = this.get_flavor();
return {
cpu: flavor.get('cpu') + 1,
ram: flavor.get_ram_size() + 1,
disk:flavor.get_disk_size() + 1
cpu: flavor.get('cpu'),
ram: flavor.get_ram_size(),
disk:flavor.get_disk_size()
}
},
......@@ -2434,6 +2453,11 @@
if (!this.is_bytes()) {
return value + "";
}
// greater than max js int (assume infinite quota)
if (value > Math.pow(2, 53)) {
return "Infinite"
}
return snf.util.readablizeBytes(value);
}
});
......
......@@ -101,10 +101,20 @@
this.init_handlers();
},
get_current: function(choice, value) {
var found = false;
_.each(this.flavors, _.bind(function(f){
if (found) { return }
if (f.get(choice) == value) {
found = true;
to_select = f;
}
}, this));
},
init_handlers: function() {
this.$el.on('click', 'li.choice', _.bind(function(e) {
var el = $(e.target).closest('li');
if (el.hasClass('disabled')) { return }
var choice = el.data('type');
var value = el.data('value');
var to_select = this.selected_flavor;
......@@ -117,14 +127,7 @@
}
if (!to_select) {
var found = false;
_.each(this.flavors, _.bind(function(f){
if (found) { return }
if (f.get(choice) == value) {
found = true;
to_select = f;
}
}, this));
to_select = this.get_current(choice, value);
}
this.set_flavor(to_select);
}, this));
......@@ -159,11 +162,11 @@
var extra_quotas = this.extra_quotas;
var user_excluded = storage.flavors.unavailable_values_for_quotas(
quotas,
storage.flavors.active());
storage.flavors.active(), extra_quotas);
_.each(user_excluded, _.bind(function(values, key) {
_.each(values, _.bind(function(value) {
var choice_el = this.select_choice(key, value);
choice_el.addClass("disabled");
choice_el.addClass("disabled").removeClass("selected");
}, this));
}, this));
},
......@@ -199,6 +202,8 @@
set_flavor: function(flavor) {
this.$el.find("li").removeClass("selected");
if (!flavor) {this.selected_flavor = undefined; return}
var no_select = false;
var self = this;
this.each_choice(function(choice){
var el = this[choice + '_el'];
var choice = el.find('.choice-'+choice+'[data-value='+flavor.get(choice)+']');
......@@ -206,6 +211,7 @@
});
this.selected_flavor = flavor;
this.trigger("flavor:select", this.selected_flavor);
return this.selected_flavor;
},
each_choice: function(f) {
......@@ -263,7 +269,7 @@
},
handle_shutdown_complete: function(vm) {
if (vm.get("status") == "STOPPED") {
if (!vm.is_active()) {
this.shutdown.removeClass("in-progress");
this.vm.unbind("change:status", this.handle_shutdown_complete);
}
......@@ -279,24 +285,36 @@
}, this);
this.vm.call("resize", complete, complete, {flavor:flv.id});
},
show_with_warning: function(vm) {
this.show(vm);
this.start_warning.show();
},
show: function(vm) {
this.start_warning = this.$(".warning.start").hide();
this.start_warning.hide();
this.submit.removeClass("in-progress");
this.vm = vm;
this.vm.bind("change", this.handle_vm_change);
if (this.flavors_view) {
this.flavors_view.remove();
}
this.warning = this.$(".warning");
this.warning = this.$(".warning.shutdown");
this.warning.hide();
this.submit.show();
this.shutdown.removeClass("in-progress");
this.$(".flavor-options-inner-cont").append("<div>");
var extra_quota = this.vm.get_flavor_quotas();
if (!this.vm.is_active()) {
extra_quota = undefined;
}
this.flavors_view = new snf.views.FlavorOptionsView({
flavors:this.vm.get_resize_flavors(),
el: this.$(".flavor-options-inner-cont div"),
hidden_choices:['disk', 'disk_template'],
selected_flavor: this.vm.get_flavor(),
extra_quotas: this.vm.get_flavor_quotas()
extra_quotas: extra_quota
});
this.flavors_view.bind("flavor:select", this.handle_flavor_select)
this.submit.addClass("disabled");
......@@ -304,7 +322,8 @@
},
handle_flavor_select: function(flv) {
if (flv.id == this.vm.get_flavor().id) {
this.selected_flavor = flv;
if (!flv || (flv.id == this.vm.get_flavor().id)) {
this.submit.addClass("disabled");
if (!this.shutdown.hasClass("in-progress")) {
this.shutdown.addClass("disabled");
......@@ -317,12 +336,19 @@
this.warning.show();
}
}
if (flv && !this.vm.can_start(flv, true)) {
if (!this.vm.is_active()) {
this.start_warning.show();
}
} else {
this.start_warning.hide();
}
this.update_vm_status();
},
update_vm_status: function() {
if (this.selected_flavor) {
this.handle_flavor_select(this.selected_flavor);
if (this.vm.get("status") == "STOPPED") {
this.warning.hide();
}
if (this.vm.get("status") == "SHUTDOWN") {
this.shutdown.addClass("in-progress").removeClass("disabled");
......@@ -356,7 +382,9 @@
}
this.submit.addClass("disabled");
} else {
this.submit.removeClass("disabled");
if (this.selected_flavor) {
this.submit.removeClass("disabled");
}
this.shutdown.hide();
}
},
......
......@@ -496,9 +496,27 @@
hide_actions: function() {
$(this.el).find("a").css("visibility", "hidden");
},
set_can_start: function() {
var el = $(this.el).find("a.action-start").parent();
el.removeClass("disabled-visible");
},
set_cannot_start: function() {
var el = $(this.el).find("a.action-start").parent();
el.addClass("disabled-visible")
},
// update the actions layout, depending on the selected actions
update_layout: function() {
if (this.vm.get('status') == 'STOPPED') {
if (this.vm.can_start()) {
this.set_can_start();
} else {
this.set_cannot_start();
}
}
if (!this.vm_handlers_initialized) {
this.vm = storage.vms.get(this.vm.id);
......@@ -636,8 +654,14 @@
// action links click events
$(this.el).find(".action-container."+action+" a").click(function(ev) {
ev.preventDefault();
if (action == "start" && !self.vm.can_start()) {
ui.main.vm_resize_view.show_with_warning(self.vm);
return;
}
if (action == "resize") {
ui.main.vm_resize_view.show(self.vm);
return;
} else {
self.set(action);
}
......
......@@ -6,9 +6,12 @@
id="create-vm-flavor-options">
</div>
<div class="form-actions plain clearfix">
<div class="warning">
<div class="warning shutdown">
{% blocktrans %}You need to shutdown your machine before you can resize it.{% endblocktrans %}
</div>
<div class="warning start">
Insufficient quota to start this machine.
</div>
<span class="form-action resize">{% trans "resize machine" %}</span>
<span class="form-action shutdown">{% trans "shutdown machine" %}</span>
</div>
......
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 to comment