Affinity rules UI: Add 'changeAffinity' action for VM

-Adds action to VM on stopped state

-Add dialog with list view showing affinity groups and checkboxes
This commit is contained in:
Brian Federle 2013-04-12 16:55:01 -07:00
parent 6629eb7468
commit 51cfc0709f
3 changed files with 249 additions and 5 deletions

View File

@ -1664,6 +1664,8 @@ under the License.
<script type="text/javascript" src="scripts/dashboard.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/ui-custom/instanceWizard.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/instanceWizard.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/affinity.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/ui-custom/affinity.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/instances.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/events.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/regions.js?t=<%=now%>"></script>

View File

@ -437,7 +437,6 @@
poll: pollAsyncJobResult
}
},
snapshot: {
messages: {
notification: function(args) {
@ -500,7 +499,6 @@
pool: pollAsyncJobResult
}
},
destroy: {
label: 'label.action.destroy.instance',
compactLabel: 'label.destroy',
@ -566,7 +564,6 @@
}
}
},
reset: {
label: 'Reset VM',
messages:{
@ -597,8 +594,81 @@
}
}
},
},
changeAffinity: {
label: 'Change affinity',
action: {
custom: cloudStack.uiCustom.affinity({
tierSelect: function(args) {
if ('vpc' in args.context) { //from VPC section
args.$tierSelect.show(); //show tier dropdown
$.ajax({ //populate tier dropdown
url: createURL("listNetworks"),
async: false,
data: {
vpcid: args.context.vpc[0].id,
//listAll: true, //do not pass listAll to listNetworks under VPC
domainid: args.context.vpc[0].domainid,
account: args.context.vpc[0].account,
supportedservices: 'StaticNat'
},
success: function(json) {
var networks = json.listnetworksresponse.network;
var items = [{ id: -1, description: 'Please select a tier' }];
$(networks).each(function(){
items.push({id: this.id, description: this.displaytext});
});
args.response.success({ data: items });
}
});
}
else { //from Guest Network section
args.$tierSelect.hide();
}
args.$tierSelect.change(function() {
args.$tierSelect.closest('.list-view').listView('refresh');
});
args.$tierSelect.closest('.list-view').listView('refresh');
},
listView: {
listView: {
id: 'affinityGroups',
fields: {
name: { label: 'label.name' },
type: { label: 'label.type' }
},
dataProvider: function(args) {
args.response.success({
data: [
{ name: 'Affinity Group 1', type: 'Affinity' },
{ name: 'Affinity Group 2', type: 'Anti-affinity' },
{ name: 'Anti-affinity Group', type: 'Anti-affinity' }
]
});
}
}
},
action: function(args) {
args.response.success();
}
})
},
messages: {
notification: function(args) {
return 'label.action.enable.static.NAT';
}
},
notification: {
poll: function(args) {
args.complete();
}
}
},
edit: {
label: 'label.edit',
@ -608,7 +678,7 @@
group: args.data.group,
ostypeid: args.data.guestosid
};
if(args.data.displayname != args.context.instances[0].displayname) {
$.extend(data, {
displayName: args.data.displayname
@ -1404,6 +1474,7 @@
allowedActions.push("reset");
allowedActions.push("snapshot");
allowedActions.push("scaleUp");
allowedActions.push("changeAffinity");
if(isAdmin())
allowedActions.push("migrateToAnotherStorage");

View File

@ -0,0 +1,171 @@
// 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.affinity = function(args) {
var listView = args.listView;
var action = args.action;
var tierSelect = args.tierSelect;
return function(args) {
var context = args.context;
var $instanceRow = args.$instanceRow;
var vmList = function(args) {
// Create a listing of instances, based on limited information
// from main instances list view
var $listView;
var instances = $.extend(true, {}, args.listView, {
context: context,
uiCustom: true
});
instances.listView.actions = {
select: {
label: _l('label.select.instance'),
type: 'checkbox',
action: {
uiCustom: function(args) {
var $item = args.$item;
var $input = $item.find('td.actions input:visible');
if ($input.attr('type') == 'checkbox') {
if ($input.is(':checked'))
$item.addClass('multi-edit-selected');
else
$item.removeClass('multi-edit-selected');
} else {
$item.siblings().removeClass('multi-edit-selected');
$item.addClass('multi-edit-selected');
}
}
}
}
};
$listView = $('<div>').listView(instances);
// Change action label
$listView.find('th.actions').html(_l('label.select'));
return $listView;
};
var $dataList = vmList({
listView: listView
}).dialog({
dialogClass: 'multi-edit-add-list panel',
width: 825,
title: _l('label.select.vm.for.static.nat'),
buttons: [
{
text: _l('label.apply'),
'class': 'ok',
click: function() {
if ($dataList.find('.tier-select select').val() == -1) {
cloudStack.dialog.notice({ message: ('Please select a tier')});
return false;
}
if (!$dataList.find(
'input[type=radio]:checked, input[type=checkbox]:checked'
).size()) {
cloudStack.dialog.notice({ message: _l('message.select.instance')});
return false;
}
var complete = args.complete;
var start = args.start;
start();
$dataList.fadeOut(function() {
action({
tierID: $dataList.find('.tier-select select').val(),
_subselect: $dataList.find('tr.multi-edit-selected .subselect select').val(),
context: $.extend(true, {}, context, {
instances: [
$dataList.find('tr.multi-edit-selected').data('json-obj')
]
}),
response: {
success: function(args) {
complete({
$item: $instanceRow
});
},
error: function(args) {
cloudStack.dialog.notice({ message: args });
}
}
});
$dataList.remove();
});
$('div.overlay').fadeOut(function() {
$('div.overlay').remove();
});
}
},
{
text: _l('label.cancel'),
'class': 'cancel',
click: function() {
$dataList.fadeOut(function() {
$dataList.remove();
});
$('div.overlay').fadeOut(function() {
$('div.overlay').remove();
});
}
}
]
}).parent('.ui-dialog').overlay();
// Add tier select dialog
if (tierSelect) {
var $toolbar = $dataList.find('.toolbar');
var $tierSelect = $('<div>').addClass('filters tier-select').prependTo($toolbar);
var $tierSelectLabel = $('<label>').html('Select tier').appendTo($tierSelect);
var $tierSelectInput = $('<select>').appendTo($tierSelect);
// Get tier data
tierSelect({
context: context,
$tierSelect: $tierSelect,
response: {
success: function(args) {
var data = args.data;
$(data).map(function(index, item) {
var $option = $('<option>');
$option.attr('value', item.id);
$option.html(item.description);
$option.appendTo($tierSelectInput);
});
},
error: function(message) {
cloudStack.dialog.notice({
message: message ? message : 'Could not retrieve VPC tiers'
});
}
}
});
}
};
};
}(cloudStack, jQuery));