diff --git a/src/sunstone/public/app/sunstone.js b/src/sunstone/public/app/sunstone.js index 2789c4904d..4347394cee 100644 --- a/src/sunstone/public/app/sunstone.js +++ b/src/sunstone/public/app/sunstone.js @@ -996,7 +996,10 @@ define(function(require) { timeout: true, success: callback, error:err, - data: {monitor: dataArg}}); + data: { + monitor: dataArg + } + }); break; case "monitor": case "monitor_single": @@ -1037,11 +1040,9 @@ define(function(require) { call(); } } - if (notify) { Notifier.notifySubmit(action, dataArg, extraParam); } - return 0; }; diff --git a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/sched-actions/html.hbs b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/sched-actions/html.hbs index bc7f0b0b1e..f5720b66ff 100644 --- a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/sched-actions/html.hbs +++ b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/sched-actions/html.hbs @@ -13,7 +13,7 @@ the License for the specific language governing permissions and }} {{! limitatio - {{{sched_actions_table}}} + {{{sched_actions_table}}} diff --git a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/sched_actions.js b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/sched_actions.js index 475435e70d..cfbdfe9806 100644 --- a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/sched_actions.js +++ b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/sched_actions.js @@ -19,11 +19,17 @@ define(function(require) { DEPENDENCIES */ + var Config = require("sunstone-config"); + var Sunstone = require("sunstone"); var Actions = require("opennebula/action"); + var Service = require("opennebula/service"); var Locale = require("utils/locale"); var Notifier = require("utils/notifier"); var ScheduleActions = require("utils/schedule_action"); var TemplateUtils = require("utils/template-utils"); + var Leases = require("utils/leases"); + var OpenNebulaAction = require("../../../opennebula/action"); + var Humanize = require("utils/humanize"); /* TEMPLATES @@ -38,6 +44,7 @@ define(function(require) { var PANEL_ID = require("./sched-actions/panelId"); var RESOURCE = "Service"; + var RESOURCE_SCHED_ACTIONS = "flow"; /* CONSTRUCTOR @@ -47,7 +54,9 @@ define(function(require) { this.icon = "fa-calendar-alt"; this.title = Locale.tr("Actions"); this.id = (info && info.DOCUMENT && info.DOCUMENT.ID) || "0"; - this.data = (info && info.DOCUMENT && info.DOCUMENT.TEMPLATE && info.DOCUMENT.TEMPLATE.BODY && info.DOCUMENT.TEMPLATE.BODY.roles) || []; + this.body = (info && info.DOCUMENT && info.DOCUMENT.TEMPLATE && info.DOCUMENT.TEMPLATE.BODY) || {}; + this.data = (this.body && this.body.roles) || []; + this.actions = [ "terminate", "terminate-hard", @@ -82,8 +91,92 @@ define(function(require) { FUNCTION DEFINITIONS */ + function actionRow(scheduling_action) { + var done_str = scheduling_action.DONE ? (Humanize.prettyTime(scheduling_action.DONE)) : ""; + var message_str = scheduling_action.MESSAGE ? scheduling_action.MESSAGE : ""; + var action_id = scheduling_action.ID || ""; + var update_sched = ""; + if(action_id){ + update_sched = ""; + } + var str = "" + done_str + "\ + " + TemplateUtils.htmlEncode(message_str) + "\ + \ +
\ +
\ + \ +
\ +
"+update_sched+"
\ + \ + "; + return str; + } + + function actionsTable(parseData) { + var str = ""; + var empty = "\ + \ + " + Locale.tr("No actions to show") + "\ + "; + if (!parseData) { + return empty; + } else { + var sched_actions = Array.isArray(parseData)? parseData : [parseData]; + if (sched_actions.length <= 0) { + return empty; + } + $.each(sched_actions, function(index, scheduling_action) { + if(scheduling_action && scheduling_action.ID){ + var className = ""; + var idTD = ""; + var id = 0; + if(scheduling_action.ID){ + className = "_"+scheduling_action.ID; + idTD = "" + TemplateUtils.htmlEncode(scheduling_action.ID) + ""; + id = scheduling_action.ID; + } + str += ""; + str += idTD; + var actions = ScheduleActions.fromJSONtoActionsTable([scheduling_action], id, true); + str += actions; + str += actionRow(scheduling_action); + } + }); + } + return str; + } + + + function _htmlSchedActions(vmTemplateContents){ + var parseData = TemplateUtils.stringToTemplate(vmTemplateContents); + return "
\ +
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + "+ + actionsTable(parseData && parseData.SCHED_ACTION) + + "\ +
" + Locale.tr("ID") + "" + Locale.tr("Action") + "" + Locale.tr("Time") + "" + Locale.tr("Rep") + "" + Locale.tr("End") + "" + Locale.tr("Done") + "" + Locale.tr("Message") + " " + + Leases.html() + + "
\ +
\ +
"; + } + function _html() { - var sched_actions_table = ""; var optionsActions = this.actions.map(function(ac){ return ""; }).join(""); @@ -99,43 +192,242 @@ define(function(require) { optionsRoles.unshift(""); optionsRoles = optionsRoles.join(""); - if(this.data && Array.isArray(this.data) && this.data[0] && this.data[0].vm_template_contents) { - var parseData = TemplateUtils.stringToTemplate(this.data[0].vm_template_contents); - if(parseData && parseData.SCHED_ACTION){ - var sched_actions = Array.isArray(parseData.SCHED_ACTION)? parseData.SCHED_ACTION : [parseData.SCHED_ACTION]; - sched_actions_table = $(""); - sched_actions.forEach(function(schedAction){ - if(schedAction && schedAction.TIME && schedAction.ACTION){ - if(schedAction.TIME.startsWith("+")){ - time = ScheduleActions.parseTime(schedAction.TIME); - }else{ - timeWithMiliSeconds = parseInt(schedAction.TIME,10) * 1000; - timeDate = new Date(timeWithMiliSeconds); - time = "on "+timeDate.getHours()+":"+timeDate.getMinutes()+":"+timeDate.getSeconds()+" "+timeDate.getDate() +"/"+(timeDate.getMonth()+1)+"/"+timeDate.getFullYear(); - } - var nameAction = schedAction.ACTION; - sched_actions_table = sched_actions_table.append( - $("").append( - $("
").text(nameAction).add( - $("").text(time) - ) - ) - ); - } - }); - sched_actions_table = sched_actions_table.prop("outerHTML"); - } - } return TemplateHTML({ - sched_actions_table: sched_actions_table, + sched_actions_table: _htmlSchedActions(this.data[0].vm_template_contents), actions: optionsActions, res: RESOURCE, roles: optionsRoles }); } + function findMaxID(items) { + return items.reduce((acc, val) => { + acc = ( acc === undefined || val.ID > acc ) ? val.ID : acc; + return acc; + }, 0); + } + + function addID(actns){ + acc = findMaxID(actns); + return actns.map(el=>{ + if(el && !el.ID){ + acc = el.ID = parseInt(acc, 10)+1; + } + return el; + }); + } + + /*** update schedule actions ***/ + function updateNodes(that, callback, type = "replace"){ + if(callback && typeof callback === "function" && that && that.data){ + var roles = Array.isArray(that.data)? that.data : [that.data]; + var updateService = true; + roles.forEach(function(element){ + if(element && element.vm_template_contents !== undefined && element.nodes){ + var jsonTemplateContents = TemplateUtils.stringToTemplate(element.vm_template_contents); + var nodes = Array.isArray(element.nodes)? element.nodes : [element.nodes]; + nodes.forEach(element => { + if(element && element.vm_info && element.vm_info.VM && element.vm_info.VM.ID){ + OpenNebulaAction.show({ + data:{ + id: element.vm_info.VM.ID + }, + success: function(req, res){ + var executedCallback = callback(jsonTemplateContents && jsonTemplateContents.SCHED_ACTION); + var userTemplate = res && res.VM && res.VM.USER_TEMPLATE || {}; + var newUserTemplate = {}; + switch (type) { + case "add": + var userTemplateSchedActions = userTemplate && userTemplate.SCHED_ACTION || []; + if(userTemplateSchedActions && executedCallback){ + var newActions = Array.isArray(userTemplateSchedActions) ? userTemplateSchedActions : [userTemplateSchedActions]; + if(Array.isArray(executedCallback)){ + newActions = newActions.concat(executedCallback); + }else{ + newActions.push(executedCallback); + } + newUserTemplate = addID(newActions); + } + break; + default: + if(executedCallback){ + newUserTemplate = addID(executedCallback); + } + break; + } + userTemplate.SCHED_ACTION = newUserTemplate; + //this update the VM + OpenNebulaAction.simple_action( + { + data:{ + id: element.vm_info.VM.ID + }, + success: function(req){ + if(userTemplate && userTemplate.SCHED_ACTION){ + $(".sched_place").empty().append(_htmlSchedActions(TemplateUtils.templateToString({SCHED_ACTION: userTemplate.SCHED_ACTION}))); + //update service + if(updateService){ + updateService = false; + //this set a new vm_template_contents in roles + var rols = that.data.forEach( + function(element){ + element.vm_template_contents = TemplateUtils.templateToString({SCHED_ACTION: userTemplate.SCHED_ACTION}); + return element; + } + ); + Service.update( + { + data:{ + id: that.id, + extra_param: JSON.stringify(that.body) + }, + success: function(){ + updateService = true; + Notifier.notifyCustom( + Locale.tr("Service Updated"), + "" + ); + }, + error: function(req, resp){ + updateService = true; + Notifier.notifyError( + (resp && resp.error && resp.error.message) || Locale.tr("Cannot update the Service: ")+(that.id || "") + ); + } + } + ); + } + } + }, + error: function(req, resp){ + Notifier.notifyError( + (resp && resp.error && resp.error.message) || Locale.tr("Cannot update the VM: ")+element.vm_info.VM.ID + ); + } + }, + "VM", + "update", + { + template_raw: TemplateUtils.templateToString(userTemplate) + } + ); + }, + error: function(){ + Notifier.notifyError(Locale.tr("Cannot get information of the VM: ")+element.vm_info.VM.ID); + } + }, "VM"); + } + }); + } + }); + } + } + + function functionButtons(context, that, actions){ + var CREATE = true; + + function clear(){ + CREATE = true; + } + + function renderCreateForm(){ + if(CREATE){ + ScheduleActions.htmlNewAction(actions, context, RESOURCE_SCHED_ACTIONS); + ScheduleActions.setup(context); + CREATE = false; + } + return false; + }; + + //add + context.off("click", "#add_scheduling_"+RESOURCE_SCHED_ACTIONS+"_action").on("click" , "#add_scheduling_"+RESOURCE_SCHED_ACTIONS+"_action", function(e){ + e.preventDefault(); + renderCreateForm(); + $("#edit_"+RESOURCE_SCHED_ACTIONS+"_action_json").hide(); + $("#add_"+RESOURCE_SCHED_ACTIONS+"_action_json").show(); + }); + context.off("click", "#add_"+RESOURCE_SCHED_ACTIONS+"_action_json").on("click" , "#add_"+RESOURCE_SCHED_ACTIONS+"_action_json", function(e) { + e.preventDefault(); + var sched_action = ScheduleActions.retrieveNewAction(context); + if (sched_action != false) { + $("#no_actions_tr", context).remove(); + $("#sched_vms_actions_body").prepend(ScheduleActions.fromJSONtoActionsTable(sched_action)); + } + updateNodes(that, function(){ + return sched_action; + },"add"); + clear(); + }); + + //update + context.off("click", ".edit_action_x").on("click", ".edit_action_x", function(e) { + e.preventDefault(); + var id = $(this).attr("data_id"); + if(id && id.length){ + renderCreateForm(); + $("#edit_"+RESOURCE_SCHED_ACTIONS+"_action_json").show().attr("data_id", id); + $("#add_"+RESOURCE_SCHED_ACTIONS+"_action_json").hide(); + ScheduleActions.fill($(this),context); + } + }); + context.off("click" , "#edit_"+RESOURCE_SCHED_ACTIONS+"_action_json").on("click" , "#edit_"+RESOURCE_SCHED_ACTIONS+"_action_json", function(e){ + e.preventDefault(); + var id = $(this).attr("data_id"); + if(id && id.length){ + $(".wickedpicker").hide(); + var sched_action = ScheduleActions.retrieveNewAction(context); + if (sched_action != false) { + var sched_actions = ScheduleActions.retrieve(context); + if(Array.isArray(sched_actions)){ + sched_actions = sched_actions.map( + function(action){ + if(action && action.ID && action.ID===id){ + return sched_action; + }else{ + return action; + } + } + ); + } + updateNodes(that, function(){ + return sched_actions; + },"replace"); + } + clear(); + } + return false; + }); + + //delete + context.off("click", ".remove_action_x").on("click", ".remove_action_x", function(e) { + e.preventDefault(); + var index = this.id.substring(6, this.id.length); + updateNodes(that, function(schedAction){ + var actions = Array.isArray(schedAction)? schedAction : [schedAction]; + actions.forEach(function(el, i){ + if(el && el.ID && String(el.ID) === index){ + delete actions[i]; + return; + } + }); + return actions; + }, "replace"); + clear(); + }); + } + function _setup(context) { var that = this; + + that.formContext = context; + Leases.actions(that, RESOURCE_SCHED_ACTIONS, "add-service", function(schedActions){ + updateNodes(that, function(){ + return schedActions; + },"add"); + }); + + var actions = ScheduleActions.defaultActions; + $("select#select_new_action").off("change").on("change",function(){ var snap_name = $("#snapname"); var snap_id = $("#snapid"); @@ -185,7 +477,6 @@ define(function(require) { var snap_name = $("#snapname").val(); var snap_id = $("#snapid").val(); var disk_id = $("#diskid").val(); - if(new_action){ var actionJSON = {}; actionJSON.error = function(e){ @@ -212,5 +503,6 @@ define(function(require) { } return false; }); + functionButtons(context, that, actions); } }); diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js index 7d81b1156b..2af0d5619f 100644 --- a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js +++ b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js @@ -83,7 +83,6 @@ define(function(require) {
\
\ "; - ScheduleActions.htmlTable(RESOURCE_SCHED_ACTIONS); //only charge the resource attribute return html; } @@ -168,8 +167,6 @@ define(function(require) { that.element.USER_TEMPLATE.SCHED_ACTION = tmp_tmpl; var template_str = TemplateUtils.templateToString(that.element.USER_TEMPLATE); - - // Let OpenNebula know Sunstone.runAction("VM.update_template", that.element.ID, template_str); }); context.off("click", ".edit_action_x"); diff --git a/src/sunstone/public/app/utils/leases.js b/src/sunstone/public/app/utils/leases.js index 7bf071ccf8..28fc9f1906 100644 --- a/src/sunstone/public/app/utils/leases.js +++ b/src/sunstone/public/app/utils/leases.js @@ -175,6 +175,14 @@ define(function(require) { ); break; + case "add-service": + var newAction = { + TIME: "+"+(last === 0? startTime.toString() : startTime+last), + ACTION: schedAction + }; + newSchedActions.push(newAction); + break; + default: break; } @@ -182,6 +190,7 @@ define(function(require) { pass = true; } }); + if(type==="submit"){ template.SCHED_ACTION = ( template.SCHED_ACTION? @@ -197,7 +206,7 @@ define(function(require) { } if(typeof callback === "function"){ - callback(); + callback(newSchedActions); } if(pass){ @@ -237,19 +246,25 @@ define(function(require) { default: break; } - - if(resource && action && template){ + if(resource && action){ switch (resource.toLowerCase()) { case "template": - displayAlertCreateLeases("add", template); - break; - case "vm": - if(action.toLowerCase() === "update" && id){ - displayAlertCreateLeases("submit", template); - }else{ + if(template){ displayAlertCreateLeases("add", template); } break; + case "vm": + if(template){ + if(action.toLowerCase() === "update" && id){ + displayAlertCreateLeases("submit", template); + }else{ + displayAlertCreateLeases("add", template); + } + } + break; + case "flow": + displayAlertCreateLeases("add-service"); + break; default: break; } diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index 095e094f9e..4eb6af315f 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -36,9 +36,10 @@ define(function (require) { 'disk-snapshot-delete' ]; - function _html(resource, leases = null) { + function _html(resource, leases = null, header = true) { this.res = resource; return TemplateTableHTML({ + header: header, res: resource, leases: leases }); @@ -155,6 +156,9 @@ define(function (require) { $("#title", context).prop("colspan", "10"); $("#td_days", context).prop("colspan", "8"); } + if (this.res === "flow") { + $("tr.create>td", context).prop("colspan", "8"); + } } function _setup(context) { @@ -794,7 +798,7 @@ define(function (require) { str += ""; } - var time = scheduling_action.TIME.toString(); + var time = String(scheduling_action.TIME); time = isNaN(time) ? time_str : (time && time.match(/^\+(.*)/gi) ? _time(time) : time_str); str += "" + TemplateUtils.htmlEncode(scheduling_action.ACTION) + "\ diff --git a/src/sunstone/public/app/utils/schedule_action/table.hbs b/src/sunstone/public/app/utils/schedule_action/table.hbs index 14fdbe6e14..a4df66c575 100644 --- a/src/sunstone/public/app/utils/schedule_action/table.hbs +++ b/src/sunstone/public/app/utils/schedule_action/table.hbs @@ -22,18 +22,20 @@ - - - - - - - - - {{#if leases}} {{/if}} - - + + {{#if header}} + + + + + + + + {{#if leases}} {{/if}} + + {{/if}} +
{{tr "Action"}} {{tr "Time"}} {{tr "Rep"}} {{tr "Ends"}} - - {{{leases}}}
{{tr "Action"}} {{tr "Time"}} {{tr "Rep"}} {{tr "Ends"}} + + {{{leases}}}
\ No newline at end of file