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 Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/51cfc070 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/51cfc070 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/51cfc070 Branch: refs/heads/master Commit: 51cfc0709fdd956fedd0f774974eaaabf2d48cd5 Parents: 6629eb7 Author: Brian Federle <brian.fede...@citrix.com> Authored: Fri Apr 12 16:55:01 2013 -0700 Committer: Brian Federle <brian.fede...@citrix.com> Committed: Fri Apr 12 16:55:01 2013 -0700 ---------------------------------------------------------------------- ui/index.jsp | 2 + ui/scripts/instances.js | 81 +++++++++++++++- ui/scripts/ui-custom/affinity.js | 171 +++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51cfc070/ui/index.jsp ---------------------------------------------------------------------- diff --git a/ui/index.jsp b/ui/index.jsp index e82ff10..ed18645 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -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> http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51cfc070/ui/scripts/instances.js ---------------------------------------------------------------------- diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 1c4c38c..b230cf7 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -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"); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51cfc070/ui/scripts/ui-custom/affinity.js ---------------------------------------------------------------------- diff --git a/ui/scripts/ui-custom/affinity.js b/ui/scripts/ui-custom/affinity.js new file mode 100644 index 0000000..1a1eb55 --- /dev/null +++ b/ui/scripts/ui-custom/affinity.js @@ -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));