cloudstack/ui/scripts/ui-custom/autoscaler.js
Brian Federle 2e4923a286 Autoscale UI: Add actions to top of dialog
Support performing actions via the autoscaler dialog. This adds
'autoscaleActions' and 'actionFilter' options to the autoscaler, which
specify and handle the actions appearing in the UI.

Performing these actions will cause a loading overlay to appear until
actions are finished, when the action bar is refreshed via the action
filter.
2012-11-16 10:56:46 +05:30

388 lines
15 KiB
JavaScript

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
cloudStack.uiCustom.autoscaler = function(args) {
// Place outer args here as local variables
// i.e, -- var dataProvider = args.dataProvider
var forms = $.extend(true, {}, args.forms);
var topfields = forms.topFields;
var bottomfields = forms.bottomFields;
var scaleuppolicy = forms.scaleUpPolicy;
var scaledownpolicy = forms.scaleDownPolicy;
var dataProvider = cloudStack.autoscaler.dataProvider;
var actions = cloudStack.autoscaler.autoscaleActions;
var actionFilter = cloudStack.autoscaler.actionFilter;
return function(args) {
var context = args.data ?
$.extend(true, {}, args.context, {
lbRules: [args.data]
}) : args.context;
var formData = args.formData;
var $autoscalerDialog = $('<div>').addClass('autoscaler');
var $topFields = $('<div>').addClass('field-group top-fields');
var $bottomFields = $('<div>').addClass('field-group bottom-fields');
var $scaleUpPolicy = $('<div>').addClass('scale-up-policy');
var $slideScaleUp = $('<div></div>').addClass('expand');
var $hideScaleUp = $('<div></div>').addClass('hide');
var $scaleUpLabel= $('<div>Show</div>').addClass('slide-label');
var $scaleUpHideLabel=$('<div>Hide</div>').addClass('slide-label');
var $scaleDownHideLabel=$('<div>Hide</div>').addClass('slide-label');
var $scaleDownLabel=$('<div>Show</div>').addClass('slide-label');
var $slideScaleDown = $('<div></div>').addClass('expand');
var $hideScaleDown = $('<div></div>').addClass('hide');
var $scaleUpDivider = $('<hr></hr>').addClass('policy-divider');
var $scaleDownDivider = $('<hr></hr>').addClass('policy-divider');
var $bottomFieldDivider = $('<hr></hr>').addClass('policy-divider');
var $scaleDownPolicy = $('<div>').addClass('scale-down-policy');
var $scaleUpPolicyTitle = $('<div>').addClass('scale-up-policy-title')
.html("Scale Up Policy");
var $scaleDownPolicyTitle = $('<div>').addClass('scale-down-policy-title')
.html("Scale Down Policy");
var topFieldForm, $topFieldForm,
bottomFieldForm, $bottomFieldForm,
scaleUpPolicyTitleForm, $scaleUpPolicyTitleForm,
scaleDownPolicyTitleForm, $scaleDownPolicyTitleForm,
scaleUpPolicyForm, scaleDownPolicyForm;
var renderActions = function(args) {
var data = args.data;
var context = args.context;
var $actions = $('<div>').addClass('detail-group');
var $actionsTable = $('<table>').append('<tr>');
var $detailActions = $('<td>').addClass('detail-actions');
var $buttons = $('<div>').addClass('buttons');
var visibleActions = actionFilter ?
actionFilter({
context: $.extend(true, {}, context, {
originalAutoscaleData: data ? [data] : null
})
}) :
$.map(actions, function(value, key) { return key; });
$detailActions.append($buttons);
$actionsTable.find('tr').append($detailActions);
$actions.append($actionsTable);
$(visibleActions).map(function(index, actionID) {
var action = actions[actionID];
var label = _l(action.label);
var $action = $('<div>').addClass('action').addClass(actionID);
var $icon = $('<a>')
.attr({ href: '#', title: label })
.append($('<span>').addClass('icon'));
if (visibleActions.length == 1) $action.addClass('single');
else if (!index) $action.addClass('first');
else if (index == visibleActions.length - 1) $action.addClass('last');
// Perform action event
$action.click(function() {
var $loading = $('<div>').addClass('loading-overlay').appendTo($autoscalerDialog);
var success = function(args) {
$loading.remove();
cloudStack.dialog.notice({
message: _l('label.task.completed') + ': ' + label
});
// Reload actions
var $newActions = renderActions({
data: data ? $.extend(data, args.data) : args.data,
context: context
});
$actions.after($newActions);
$actions.remove();
};
var error = function(message) {
$loading.remove();
cloudStack.dialog.notice({ message: message });
};
action.action({
response: {
success: function(args) {
var notification = $.extend(args.notification, {
_custom: args._custom,
desc: label
});
cloudStack.ui.notifications.add(
notification,
success, {},
error, {}
);
},
error: error
}
});
});
$action.append($icon);
$action.appendTo($buttons);
});
if (!visibleActions || !visibleActions.length) $actions.hide();
return $actions;
};
var renderDialogContent = function(args) {
var data = args.data ? args.data : {};
// Setup default values, in case where existing data is present
var setDefaultFields = function(fieldID, field) {
var fieldData = data[fieldID];
if (fieldData && !field.isBoolean) {
field.defaultValue = fieldData;
} else {
field.isChecked = fieldData;
}
};
$.each(topfields, setDefaultFields);
$.each(bottomfields, setDefaultFields);
$.extend(context, {
originalAutoscaleData: args.data
});
// Create and append top fields
// -- uses create form to generate fields
topFieldForm = cloudStack.dialog.createForm({
context: context,
noDialog: true, // Don't render a dialog, just return $formContainer
form: {
title: '',
fields: topfields
}
});
$topFieldForm = topFieldForm.$formContainer;
$topFieldForm.appendTo($topFields);
scaleUpPolicyTitleForm = cloudStack.dialog.createForm({
context: context,
noDialog: true,
form: {
title: '',
fields: {
scaleUpDuration: { label: 'Duration', validation: { required: true } }
}
}
});
$scaleUpPolicyTitleForm = scaleUpPolicyTitleForm.$formContainer;
$scaleUpPolicyTitleForm.appendTo($scaleUpPolicyTitle);
scaleDownPolicyTitleForm = cloudStack.dialog.createForm({
context: context,
noDialog: true,
form: {
title: '',
fields: {
scaleDownDuration: { label: 'Duration', validation: { required: true } }
}
}
});
$scaleDownPolicyTitleForm = scaleDownPolicyTitleForm.$formContainer;
$scaleDownPolicyTitleForm.appendTo($scaleDownPolicyTitle);
// Make multi-edits
//
// Scale up policy
if (data.scaleUpPolicy && $.isArray(data.scaleUpPolicy.conditions)) {
$autoscalerDialog.data('autoscaler-scale-up-data',
data.scaleUpPolicy.conditions);
}
if (data.scaleUpPolicy && data.scaleUpPolicy.duration) {
$scaleUpPolicyTitleForm.find('input[name=scaleUpDuration]').val(
data.scaleUpPolicy.duration
);
}
scaleuppolicy.context = context;
scaleUpPolicyForm = $scaleUpPolicy.multiEdit(scaleuppolicy);
// Scale down policy
if (data.scaleDownPolicy && $.isArray(data.scaleDownPolicy.conditions)) {
$autoscalerDialog.data('autoscaler-scale-down-data',
data.scaleDownPolicy.conditions);
}
if (data.scaleDownPolicy && data.scaleDownPolicy.duration) {
$scaleDownPolicyTitleForm.find('input[name=scaleDownDuration]').val(
data.scaleDownPolicy.duration
);
}
scaledownpolicy.context = context;
scaleDownPolicyForm = $scaleDownPolicy.multiEdit(scaledownpolicy);
// Create and append bottom fields
bottomFieldForm = cloudStack.dialog.createForm({
context: context,
noDialog: true, // Don't render a dialog, just return $formContainer
form: {
title: '',
fields: bottomfields
}
});
$bottomFieldForm = bottomFieldForm.$formContainer;
$bottomFieldForm.appendTo($bottomFields);
// Append main div elements
$autoscalerDialog.append(
$topFields,
$scaleUpPolicyTitle,
$scaleUpPolicy,
$scaleDownPolicyTitle,
$scaleDownPolicy,
$bottomFields
);
// Render dialog
//$autoscalerDialog.find('.form-item[rel=templateNames] label').hide();
/* Duration Fields*/
//$('div.ui-dialog div.autoscaler').find('div.scale-up-policy-title').append("<br></br>").append($inputLabel = $('<label>').html('Duration').attr({left:'200'})).append($('<input>').attr({ name: 'username' }));
//$('div.ui-dialog div.autoscaler').find('div.scale-down-policy-title').append("<br></br>").append($inputLabel = $('<label>').html('Duration').attr({left:'200'})).append($('<input>').attr({ name: 'username' }));
/*Dividers*/
$autoscalerDialog.find('div.scale-up-policy-title').prepend($scaleUpDivider);
$autoscalerDialog.find('div.scale-down-policy-title').prepend($scaleDownDivider);
$autoscalerDialog.find('div.field-group.bottom-fields').prepend($bottomFieldDivider);
/* Hide effects for multi-edit table*/
$autoscalerDialog.find('div.scale-up-policy').prepend($hideScaleUp);
$autoscalerDialog.find('div.scale-down-policy ').prepend($hideScaleDown);
$autoscalerDialog.find('div.scale-up-policy').prepend($scaleUpHideLabel);
$autoscalerDialog.find('div.scale-down-policy').prepend($scaleDownHideLabel);
/*Toggling the labels and data-item table - SCALE UP POLICY*/
$autoscalerDialog.find('div.scale-up-policy div.hide').click(function() {
$autoscalerDialog.find('div.scale-up-policy div.multi-edit div.data-item').slideToggle();
$scaleUpLabel = $autoscalerDialog.find('div.scale-up-policy div.slide-label').replaceWith($scaleUpLabel);
});
/*Toggling the images */
$('div.ui-dialog div.autoscaler div.scale-up-policy div.hide').click(function() {
$(this).toggleClass('expand hide');
});
$('div.ui-dialog div.autoscaler div.scale-down-policy div.hide').click(function() {
$(this).toggleClass('expand hide');
});
/*Toggling the labels and data-item table - SCALE DOWN POLICY*/
$('div.ui-dialog div.autoscaler div.scale-down-policy div.hide').click(function() {
$('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.data-item').slideToggle();
$scaleDownLabel = $('div.ui-dialog div.autoscaler div.scale-down-policy div.slide-label').replaceWith($scaleDownLabel);
});
$('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.expand').click(function() { $('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.data-item').slideToggle(); });
$autoscalerDialog.dialog('option', 'position', 'center');
$autoscalerDialog.dialog('option', 'height', 'auto');
// Setup actions
renderActions(args).prependTo($autoscalerDialog);
};
var $loading = $('<div>').addClass('loading-overlay').appendTo($autoscalerDialog);
$autoscalerDialog.dialog({
title: 'AutoScale Configuration Wizard',
width: 825,
height: 600,
draggable: true,
closeonEscape: false,
overflow:'auto',
open:function() {
$("button").each(function(){
$(this).attr("style", "left: 600px; position: relative; margin-right: 5px; ");
});
},
buttons: [
{
text: _l('label.cancel'),
'class': 'cancel',
click: function() {
$autoscalerDialog.dialog('destroy');
$('.overlay').remove();
}
},
{
text: _l('Apply'),
'class': 'ok',
click: function() {
var data = cloudStack.serializeForm($('.ui-dialog .autoscaler form'));
$loading.appendTo($autoscalerDialog);
cloudStack.autoscaler.actions.apply({
formData: formData,
context: context,
data: data,
response: {
success: function() {
$loading.remove();
$autoscalerDialog.dialog('destroy');
$autoscalerDialog.closest(':ui-dialog').remove();
$('.overlay').remove();
cloudStack.dialog.notice({
message: 'Autoscaler configured successfully.'
});
},
error: function(message) {
cloudStack.dialog.notice({ message: message });
$loading.remove();
}
}
});
}
}
]
}).closest('.ui-dialog').overlay();
dataProvider({
context: context,
response: {
success: function(args) {
$loading.remove();
renderDialogContent(args);
if (args.data == null) { //from a new LB rule
$autoscalerDialog.find('select[name=serviceOfferingId]').removeAttr('disabled');
$autoscalerDialog.find('select[name=securityGroups]').removeAttr('disabled');
$autoscalerDialog.find('select[name=diskOfferingId]').removeAttr('disabled');
}
else { //from an existing LB rule
$autoscalerDialog.find('select[name=serviceOfferingId]').attr('disabled', true);
$autoscalerDialog.find('select[name=securityGroups]').attr('disabled', true);
$autoscalerDialog.find('select[name=diskOfferingId]').attr('disabled', true);
if(args.data.isAdvanced != null) {
$autoscalerDialog.find('input[type=checkbox]').trigger('click');
$autoscalerDialog.find('input[type=checkbox]').attr('checked', 'checked');
}
}
}
}
});
};
};
}(jQuery, cloudStack));