1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

Feature #4320: Add widget to edit boot order

This commit is contained in:
Carlos Martín 2016-04-29 12:28:07 +02:00
parent c7b7cd1d27
commit 5c2ebb126c
11 changed files with 223 additions and 62 deletions

View File

@ -76,7 +76,7 @@ define(function(require) {
var wizardTabInstance;
$.each(WIZARD_TABS, function(index, wizardTab) {
try {
wizardTabInstance = new wizardTab();
wizardTabInstance = new wizardTab({listener: that});
wizardTabInstance.contentHTML = wizardTabInstance.html();
that.wizardTabs.push(wizardTabInstance);
} catch (err) {
@ -97,6 +97,8 @@ define(function(require) {
FormPanel.prototype.submitWizard = _submitWizard;
FormPanel.prototype.submitAdvanced = _submitAdvanced;
FormPanel.prototype.fill = _fill;
FormPanel.prototype.notify = _notify;
FormPanel.prototype.retrieve = _retrieve;
return FormPanel;
@ -134,7 +136,7 @@ define(function(require) {
});
}
function _submitWizard(context) {
function _retrieve(context) {
var templateJSON = {}
$.each(this.wizardTabs, function(index, wizardTab) {
$.extend(true, templateJSON, wizardTab.retrieve($('#' + wizardTab.wizardTabId, context)));
@ -154,6 +156,12 @@ define(function(require) {
delete templateJSON["VCENTER_PUBLIC_CLOUD"];
}
return templateJSON;
}
function _submitWizard(context) {
var templateJSON = this.retrieve(context);
if (this.action == "create") {
Sunstone.runAction("Template.create", {'vmtemplate': templateJSON});
return false;
@ -188,5 +196,34 @@ define(function(require) {
$.each(this.wizardTabs, function(index, wizardTab) {
wizardTab.fill($('#' + wizardTab.wizardTabId, context), templateJSON);
});
// After all tabs have been filled, perform a notify
this.notify();
}
var in_progress = false;
function _notify() {
var that = this;
// Avoid lots of calls (debounce)
if(in_progress){
return;
}
in_progress = true;
setTimeout(function(){
var context = that.formContext;
var templateJSON = that.retrieve(context);
$.each(that.wizardTabs, function(index, wizardTab) {
if (wizardTab.notify != undefined){
wizardTab.notify($('#' + wizardTab.wizardTabId, context), templateJSON);
}
});
in_progress = false;
}, 500);
}
});

View File

@ -45,7 +45,7 @@ define(function(require) {
CONSTRUCTOR
*/
function WizardTab() {
function WizardTab(opts) {
if (!Config.isTemplateCreationTabEnabled('network')) {
throw "Wizard Tab not enabled";
}
@ -54,6 +54,10 @@ define(function(require) {
this.icon = 'fa-globe';
this.title = Locale.tr("Network");
this.classes = "hypervisor only_kvm only_vcenter"
if(opts.listener != undefined){
this.listener = opts.listener;
}
}
WizardTab.prototype.constructor = WizardTab;
@ -98,6 +102,12 @@ define(function(require) {
});
that.addNicTab(context);
if(that.listener != undefined){
$(context).on("change", "input", function(){
that.listener.notify();
});
}
}
function _retrieve(context) {
@ -202,5 +212,9 @@ define(function(require) {
$("#" + LINKS_CONTAINER_ID + " li", context).each(function(index) {
$("a", this).html(Locale.tr("NIC") + ' ' + index + " <i class='fa fa-times-circle remove-tab'></i>");
})
if(this.listener != undefined){
this.listener.notify();
}
}
});

View File

@ -169,6 +169,7 @@ define(function(require) {
WizardTab.prototype.onShow = _onShow;
WizardTab.prototype.retrieve = _retrieve;
WizardTab.prototype.fill = _fill;
WizardTab.prototype.notify = _notify;
return WizardTab;
@ -192,6 +193,28 @@ define(function(require) {
var that = this;
Foundation.reflow(context, 'tabs');
context.on("click", "button.boot-order-up", function(){
var tr = $(this).closest("tr");
tr.prev().before(tr);
_refreshBootValue(context);
return false;
});
context.on("click", "button.boot-order-down", function(){
var tr = $(this).closest("tr");
tr.next().after(tr);
_refreshBootValue(context);
return false;
});
$("table.boot-order tbody", context).on("change", "input", function(){
_refreshBootValue(context);
});
var kernelDSContext = $(".kernel_ds", context);
var kernelDSInputsContext = $("#kernel_path_inputs", context);
$("input[name='kernel_type']", context).change(function() {
@ -251,15 +274,7 @@ define(function(require) {
$.extend(osJSON, WizardFields.retrieve('.kernelTab', context));
$.extend(osJSON, WizardFields.retrieve('.ramdiskTab', context));
var boot = "";
var val;
for (var i = 0; i < 3; i++) {
val = $('#BOOT_' + i, context).val();
if (val != undefined && val.length > 0) {
if (boot.length > 0) {boot += ","}
boot += val;
}
}
var boot = _retrieveBootValue(context);
if (boot.length > 0) {
osJSON["BOOT"] = boot;
@ -288,11 +303,7 @@ define(function(require) {
WizardFields.fill(context, osJSON);
if (osJSON && osJSON['BOOT']) {
var boot_vals = osJSON['BOOT'].split(",");
for (var i = 0; i < 3 && i < boot_vals.length; i++) {
$('#BOOT_' + i, context).val(boot_vals[i]);
}
_fillBootValue(context, osJSON['BOOT']);
}
delete templateJSON['OS'];
@ -304,4 +315,108 @@ define(function(require) {
delete templateJSON['FEATURES'];
}
}
//----------------------------------------------------------------------------
// Boot order
//----------------------------------------------------------------------------
function _retrieveBootValue(context) {
return $("table.boot-order", context).attr("value");
}
function _fillBootValue(context, value) {
return $("table.boot-order", context).attr("value", value);
}
function _refreshBootValue(context) {
var table = $("table.boot-order", context);
var devices = [];
$.each($("tr", table), function(){
if ($("input", this).is(":checked")){
devices.push( $(this).attr("value") );
}
});
table.attr("value", devices.join(','));
}
function _addBootRow(context, value, label) {
$("table.boot-order tbody", context).append(
'<tr value="'+value+'">'+
'<td><input type="checkbox"/></td>'+
'<td>'+value+'</td>'+
'<td><label>'+label+'</label></td>'+
'<td>'+
'<button class="boot-order-up button radius tiny hollow secondary"><i class="fa fa-lg fa-arrow-up" aria-hidden="true"></i></button>'+
'<button class="boot-order-down button radius tiny hollow secondary"><i class="fa fa-lg fa-arrow-down" aria-hidden="true"></i></button>'+
'</td>'+
'</tr>');
}
function _notify(context, templateJSON) {
var table = $("table.boot-order", context);
var prev_value = $(table).attr("value");
$("table.boot-order tbody", context).html("");
if (templateJSON.DISK != undefined){
var disks = templateJSON.DISK;
if (!$.isArray(disks)){
disks = [disks];
}
$.each(disks, function(i,disk){
var label = '<i class="fa fa-fw fa-lg fa-tasks"></i> ';
if (disk.IMAGE != undefined){
label += disk.IMAGE;
} else if (disk.IMAGE_ID != undefined){
label += Locale.tr("Image ID") + " " + disk.IMAGE_ID;
} else {
label += Locale.tr("Volatile");
}
_addBootRow(context, 'disk'+i, label);
});
}
if (templateJSON.NIC != undefined){
var nics = templateJSON.NIC;
if (!$.isArray(nics)){
nics = [nics];
}
$.each(nics, function(i,nic){
var label = '<i class="fa fa-fw fa-lg fa-globe"></i> ';
if (nic.NETWORK != undefined){
label += nic.NETWORK;
} else if (nic.NETWORK_ID != undefined){
label += Locale.tr("Network ID") + " " + nic.NETWORK_ID;
} else {
label += Locale.tr("Manual settings");
}
_addBootRow(context, 'nic'+i, label);
});
}
if (prev_value.length > 0){
var pos = 0;
$.each(prev_value.split(','), function(i,device){
var tr = $('tr[value="'+device+'"]', table);
if(tr.length > 0){
$($("tr", table)[pos]).before(tr);
$("input", tr).click();
pos += 1;
}
});
}
}
});

View File

@ -62,46 +62,16 @@
</label>
</div>
</div>
<br>
<div class="row">
<div class="medium-4 columns">
<div class="medium-8 columns">
<label>
{{tr "1st Boot"}}
{{{tip (tr "1st Boot device type")}}}
<select id="BOOT_0" name="boot">
<option value=""></option>
<option value="hd">{{tr "HD"}}</option>
<option value="fd">{{tr "FD"}}</option>
<option value="cdrom">{{tr "CDROM"}}</option>
<option value="network">{{tr "NETWORK"}}</option>
</select>
</label>
</div>
<div class="medium-4 columns">
<label>
{{tr "2nd Boot"}}
{{{tip (tr "2nd Boot device type")}}}
<select id="BOOT_1" name="boot">
<option value=""></option>
<option value="hd">{{tr "HD"}}</option>
<option value="fd">{{tr "FD"}}</option>
<option value="cdrom">{{tr "CDROM"}}</option>
<option value="network">{{tr "NETWORK"}}</option>
</select>
</label>
</div>
<div class="medium-4 columns">
<label>
{{tr "3rd Boot"}}
{{{tip (tr "3rd Boot device type")}}}
<select id="BOOT_2" name="boot">
<option value=""></option>
<option value="hd">{{tr "HD"}}</option>
<option value="fd">{{tr "FD"}}</option>
<option value="cdrom">{{tr "CDROM"}}</option>
<option value="network">{{tr "NETWORK"}}</option>
</select>
{{tr "Boot order"}}
{{{tip (tr "Select the devices to boot from, and their order")}}}
</label>
<table class="boot-order dataTable" value="">
<tbody>
</tbody>
</table>
</div>
</div>
<div class="row">

View File

@ -45,7 +45,7 @@ define(function(require) {
CONSTRUCTOR
*/
function WizardTab() {
function WizardTab(opts) {
if (!Config.isTemplateCreationTabEnabled('storage')) {
throw "Wizard Tab not enabled";
}
@ -54,6 +54,10 @@ define(function(require) {
this.icon = 'fa-tasks';
this.title = Locale.tr("Storage");
this.classes = "hypervisor only_kvm only_vcenter"
if(opts.listener != undefined){
this.listener = opts.listener;
}
}
WizardTab.prototype.constructor = WizardTab;
@ -98,6 +102,12 @@ define(function(require) {
});
that.addDiskTab(context);
if(that.listener != undefined){
$(context).on("change", "input", function(){
that.listener.notify();
});
}
}
function _retrieve(context) {
@ -186,5 +196,9 @@ define(function(require) {
$("#" + LINKS_CONTAINER_ID + " li", context).each(function(index) {
$("a", this).html(Locale.tr("Disk") + ' ' + index + " <i class='fa fa-times-circle remove-tab'></i>");
})
if(this.listener != undefined){
this.listener.notify();
}
}
});

View File

@ -153,5 +153,14 @@ define(function(require) {
$.each(this.wizardTabs, function(index, wizardTab) {
wizardTab.fill($('#' + wizardTab.wizardTabId, context), templateJSON);
});
// After all tabs have been filled, perform a notify.
// There isn't a proper listener because this wizard does not allow to edit
// the disks and nics
$.each(this.wizardTabs, function(index, wizardTab) {
if (wizardTab.notify != undefined){
wizardTab.notify($('#' + wizardTab.wizardTabId, context), templateJSON);
}
});
}
});

View File

@ -97,7 +97,7 @@ define(function(require) {
Sunstone.showFormPanel(TAB_ID, UPDATECONF_FORM_ID, "updateconf",
function(formPanelInstance, context) {
formPanelInstance.fill(context, that.element.ID, that.conf);
formPanelInstance.fill(context, that.element.ID, that.element.TEMPLATE);
});
return false;

View File

@ -18,7 +18,7 @@
<div class="small-12 columns">
{{#isTabActionEnabled "vms-tab" "VM.updateconf"}}
<span class="right">
<button id="vm_updateconf" class="button success right radius">
<button id="vm_updateconf" class="button success right radius small">
{{tr "Update Configuration"}}
</button>
</span>

View File

@ -149,7 +149,7 @@ define(function(require) {
var disks = [];
if ($.isArray(that.element.TEMPLATE.DISK))
disks = that.element.TEMPLATE.DISK;
disks = that.element.TEMPLATE.DISK.slice(0); // clone
else if (!$.isEmptyObject(that.element.TEMPLATE.DISK))
disks = [that.element.TEMPLATE.DISK];

View File

@ -22,6 +22,8 @@ define(function(require) {
var Sunstone = require('sunstone');
function BaseFormPanel() {
this.formContext = $("#" + this.tabId+" div[form-panel-id="+this.formPanelId+"]");
return this;
}

View File

@ -765,9 +765,9 @@ define(function(require) {
$('#select_resource_' + that.dataTableId, section).hide();
$('.label', section).hide();
$('#selected_resource_id_' + that.dataTableId, section).val(aData[that.selectOptions.id_index]).change();
$('#selected_resource_id_' + that.dataTableId, section).val(aData[that.selectOptions.id_index]).trigger("change");
$('#selected_resource_name_' + that.dataTableId, section).text(aData[that.selectOptions.name_index]).change();
$('#selected_resource_name_' + that.dataTableId, section).text(aData[that.selectOptions.name_index]).trigger("change");
$('#selected_resource_name_' + that.dataTableId, section).show();
that.selectOptions.select_callback(aData, that.selectOptions);
@ -937,10 +937,10 @@ define(function(require) {
// $('input.check_item', this).prop('checked', true);
if (row_id !== undefined) {
$('#selected_resource_id_' + that.dataTableId, section).val(row_id).change();
$('#selected_resource_id_' + that.dataTableId, section).val(row_id).trigger("change");
}
$('#selected_resource_name_' + that.dataTableId, section).text(row_name).change();
$('#selected_resource_name_' + that.dataTableId, section).text(row_name).trigger("change");
$('#selected_resource_name_' + that.dataTableId, section).show();
that.refreshResourceTableSelect(section, that.dataTableId);