mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-22 18:50:08 +03:00
Co-authored-by: Jorge Lobo <jlobo@opennebula.systems>
This commit is contained in:
parent
6c71efc9ad
commit
26c02b657e
@ -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;
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,7 @@ the License for the specific language governing permissions and }} {{! limitatio
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">{{{sched_actions_table}}}</td>
|
||||
<td colspan="3" class="sched_place">{{{sched_actions_table}}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="title" colspan="3">
|
||||
|
@ -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 = "<button id='minus_"+scheduling_action.ID+ "' class='small button btn-warning edit_action_x' data_id='"+action_id+"'><i class='fas fa-edit'></i></button>";
|
||||
}
|
||||
var str = "<td class='done_row'>" + done_str + "</td>\
|
||||
<td class='message_row'>" + TemplateUtils.htmlEncode(message_str) + "</td>\
|
||||
<td colspan='3' style='text-align: right;'>\
|
||||
<div style='display: flex;justify-content: flex-end;'>\
|
||||
<div>\
|
||||
<button id='minus_" + scheduling_action.ID + "' class='small button btn-danger remove_action_x'><i class='fas fa-trash-alt'></i></button>\
|
||||
</div>\
|
||||
<div>"+update_sched+"</div>\
|
||||
</td>\
|
||||
</tr>";
|
||||
return str;
|
||||
}
|
||||
|
||||
function actionsTable(parseData) {
|
||||
var str = "";
|
||||
var empty = "\
|
||||
<tr id=\"no_actions_tr\">\
|
||||
<td colspan=\"6\">" + Locale.tr("No actions to show") + "</td>\
|
||||
</tr>";
|
||||
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 = "<td class=\"id_row\"></td>";
|
||||
var id = 0;
|
||||
if(scheduling_action.ID){
|
||||
className = "_"+scheduling_action.ID;
|
||||
idTD = "<td class=\"id_row\">" + TemplateUtils.htmlEncode(scheduling_action.ID) + "</td>";
|
||||
id = scheduling_action.ID;
|
||||
}
|
||||
str += "<tr class='tr_action"+className+"' data='" + JSON.stringify(scheduling_action) + "'>";
|
||||
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 "<div class='row'>\
|
||||
<div class='large-12 columns'>\
|
||||
<table id='scheduling_"+RESOURCE_SCHED_ACTIONS+"_actions_table' class='info_table dataTable'>\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>" + Locale.tr("ID") + "</th>\
|
||||
<th>" + Locale.tr("Action") + "</th>\
|
||||
<th>" + Locale.tr("Time") + "</th>\
|
||||
<th>" + Locale.tr("Rep") + "</th>\
|
||||
<th>" + Locale.tr("End") + "</th>\
|
||||
<th>" + Locale.tr("Done") + "</th>\
|
||||
<th>" + Locale.tr("Message") + "</th>\
|
||||
<th colspan=''> </th>\
|
||||
<th><button id='add_scheduling_"+RESOURCE_SCHED_ACTIONS+"_action' class='button small success right radius' >" + Locale.tr("Add action") + "</button></th>\
|
||||
<th>" +
|
||||
Leases.html() +
|
||||
"</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id='sched_vms_actions_body' class='scheduling_place'>"+
|
||||
actionsTable(parseData && parseData.SCHED_ACTION) +
|
||||
"</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>";
|
||||
}
|
||||
|
||||
function _html() {
|
||||
var sched_actions_table = "";
|
||||
var optionsActions = this.actions.map(function(ac){
|
||||
return "<option value='"+ac+"'>"+ac+"</option>";
|
||||
}).join("");
|
||||
@ -99,43 +192,242 @@ define(function(require) {
|
||||
optionsRoles.unshift("<option value=''>"+Locale.tr("All Roles")+"</option>");
|
||||
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 = $("<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(
|
||||
$("<tr/>").append(
|
||||
$("<td/>").text(nameAction).add(
|
||||
$("<td/>").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);
|
||||
}
|
||||
});
|
||||
|
@ -83,7 +83,6 @@ define(function(require) {
|
||||
</table>\
|
||||
</div>\
|
||||
</div>";
|
||||
|
||||
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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 += "<tr class='tr_action' data='" + JSON.stringify(scheduling_action) + "'>";
|
||||
}
|
||||
|
||||
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 += "<td class='action_row'>" + TemplateUtils.htmlEncode(scheduling_action.ACTION) + "</td>\
|
||||
|
@ -22,18 +22,20 @@
|
||||
</style>
|
||||
|
||||
<table id="scheduling_{{res}}_actions_table" class="info_table dataTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> {{tr "Action"}} </th>
|
||||
<th> {{tr "Time"}} </th>
|
||||
<th> {{tr "Rep"}} </th>
|
||||
<th> {{tr "Ends"}} </th>
|
||||
<th colspan=""> </th>
|
||||
<th>
|
||||
<button id="add_scheduling_{{res}}_action" class="button small success right radius"> {{tr "Add action"}} </button>
|
||||
</th>
|
||||
{{#if leases}} <th>{{{leases}}}</th> {{/if}}
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
{{#if header}}
|
||||
<tr>
|
||||
<th> {{tr "Action"}} </th>
|
||||
<th> {{tr "Time"}} </th>
|
||||
<th> {{tr "Rep"}} </th>
|
||||
<th> {{tr "Ends"}} </th>
|
||||
<th colspan=""> </th>
|
||||
<th>
|
||||
<button id="add_scheduling_{{res}}_action" class="button small success right radius"> {{tr "Add action"}} </button>
|
||||
</th>
|
||||
{{#if leases}} <th>{{{leases}}}</th> {{/if}}
|
||||
</tr>
|
||||
{{/if}}
|
||||
</thead>
|
||||
<tbody id="sched_{{res}}_actions_body"></tbody>
|
||||
</table>
|
Loading…
x
Reference in New Issue
Block a user