mirror of https://github.com/apache/cloudstack.git
Merge branch 'ui-vm-affinity'
This commit is contained in:
commit
5ce289034d
|
|
@ -14,7 +14,16 @@
|
|||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
label.add.affinity.group=Add new affinity group
|
||||
message.delete.affinity.group=Please confirm that you would like to remove this affinity group.
|
||||
label.delete.affinity.group=Delete Affinity Group
|
||||
label.edit.affinity.group=Edit Affinity Group
|
||||
label.affinity=Affinity
|
||||
label.anti.affinity=Anti-affinity
|
||||
label.affinity.groups=Affinity Groups
|
||||
label.anti.affinity.groups=Anti-affinity Groups
|
||||
label.affinity.group=Affinity Group
|
||||
label.anti.affinity.group=Anti-affinity Group
|
||||
changed.item.properties=Changed item properties
|
||||
confirm.enable.s3=Please fill in the following information to enable support for S3-backed Secondary Storage
|
||||
confirm.enable.swift=Please fill in the following information to enable support for Swift
|
||||
|
|
|
|||
|
|
@ -1502,7 +1502,6 @@ div.list-view td.state.off span {
|
|||
position: relative;
|
||||
left: 0px;
|
||||
float: left;
|
||||
width: 460px;
|
||||
height: 22px;
|
||||
border-top: 1px solid #808080;
|
||||
/*+box-shadow:inset 0px 1px #FFFFFF;*/
|
||||
|
|
@ -1907,7 +1906,7 @@ div.detail-group td.view-all a {
|
|||
background: url(../images/gradients.png) repeat-x 0px -529px;
|
||||
font-size: 11px;
|
||||
display: block;
|
||||
height: 25px;
|
||||
height: 27px;
|
||||
text-decoration: none;
|
||||
color: #4C5D6C;
|
||||
/*+text-shadow:0px 1px 2px #FFFFFF;*/
|
||||
|
|
@ -1916,7 +1915,7 @@ div.detail-group td.view-all a {
|
|||
-o-text-shadow: 0px 1px 2px #FFFFFF;
|
||||
text-shadow: 0px 1px 2px #FFFFFF;
|
||||
float: left;
|
||||
padding: 0 8px 0 5px;
|
||||
padding: 0 1px;
|
||||
border-left: 1px solid #9B9EA2;
|
||||
/*+border-radius:5px 0 0 5px;*/
|
||||
-moz-border-radius: 5px 0 0 5px;
|
||||
|
|
@ -1971,10 +1970,10 @@ div.details .main-groups label.error {
|
|||
}
|
||||
|
||||
.detail-view td.view-all.multiple {
|
||||
width: 123px !important;
|
||||
height: 22px;
|
||||
float: left;
|
||||
max-width: 145px;
|
||||
height: 17px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 8px 2px 8px 8px;
|
||||
border: none !important;
|
||||
/*+box-shadow:none;*/
|
||||
|
|
@ -5265,6 +5264,10 @@ label.error {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.multi-wizard.instance-wizard .progress ul li {
|
||||
width: 109px;
|
||||
}
|
||||
|
||||
.multi-wizard .progress ul li.first {
|
||||
/*+border-radius:5px 0 0 5px;*/
|
||||
-moz-border-radius: 5px 0 0 5px;
|
||||
|
|
@ -5306,6 +5309,10 @@ label.error {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.multi-wizard.instance-wizard .progress ul li span {
|
||||
left: 36px;
|
||||
}
|
||||
|
||||
.multi-wizard .progress ul li span.multiline {
|
||||
width: 71px;
|
||||
top: 12px;
|
||||
|
|
@ -5322,6 +5329,10 @@ label.error {
|
|||
z-index: 1000;
|
||||
}
|
||||
|
||||
.multi-wizard.instance-wizard .progress ul li span.arrow {
|
||||
left: 27px;
|
||||
}
|
||||
|
||||
.multi-wizard .progress ul li.active span.arrow {
|
||||
background-position: -1px -396px;
|
||||
}
|
||||
|
|
@ -5342,6 +5353,15 @@ label.error {
|
|||
background: transparent;
|
||||
}
|
||||
|
||||
.multi-wizard.instance-wizard .progress ul li span.number {
|
||||
left: 16px;
|
||||
}
|
||||
|
||||
.multi-wizard.instance-wizard .progress ul li span.multiline {
|
||||
width: 79px;
|
||||
left: 23px;
|
||||
}
|
||||
|
||||
.multi-wizard .progress ul li.active span {
|
||||
/*+text-shadow:0px -1px 1px #004AFF;*/
|
||||
-moz-text-shadow: 0px -1px 1px #004AFF;
|
||||
|
|
@ -11670,7 +11690,6 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
|
|||
background-position: 0px -707px;
|
||||
}
|
||||
|
||||
|
||||
.attach .icon,
|
||||
.attachISO .icon,
|
||||
.attachDisk .icon {
|
||||
|
|
@ -11854,16 +11873,13 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
|
|||
}
|
||||
|
||||
.removeVlanRange .icon {
|
||||
|
||||
background-position: 1px -92px;
|
||||
}
|
||||
|
||||
.removeVlanRange:hover .icon{
|
||||
|
||||
.removeVlanRange:hover .icon {
|
||||
background-position: 1px -92px;
|
||||
}
|
||||
|
||||
|
||||
.resize .icon,
|
||||
.updateResourceCount .icon {
|
||||
background-position: -167px -66px;
|
||||
|
|
@ -11893,9 +11909,8 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
|
|||
background-position: -168px -31px;
|
||||
}
|
||||
|
||||
.scaleUp .icon{
|
||||
background-position: -167px -66px;
|
||||
|
||||
.scaleUp .icon {
|
||||
background-position: -167px -66px;
|
||||
}
|
||||
|
||||
.restoreVM:hover .icon,
|
||||
|
|
@ -12027,6 +12042,30 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
|
|||
background-position: -228px -646px;
|
||||
}
|
||||
|
||||
.changeAffinity .icon {
|
||||
background-position: -264px -2px;
|
||||
}
|
||||
|
||||
.changeAffinity:hover .icon {
|
||||
background-position: -263px -583px;
|
||||
}
|
||||
|
||||
.releaseFromAccount .icon {
|
||||
background-position: -230px -123px;
|
||||
}
|
||||
|
||||
.releaseFromAccount:hover .icon {
|
||||
background-position: -229px -704px;
|
||||
}
|
||||
|
||||
.addAccount .icon {
|
||||
background-position: -231px -96px;
|
||||
}
|
||||
|
||||
.addAccount:hover .icon {
|
||||
background-position: -230px -677px;
|
||||
}
|
||||
|
||||
.label-hovered {
|
||||
cursor: pointer;
|
||||
color: #0000FF !important;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,16 @@ under the License.
|
|||
<% long now = System.currentTimeMillis(); %>
|
||||
<script language="javascript">
|
||||
dictionary = {
|
||||
'label.add.affinity.group': '<fmt:message key="label.add.affinity.group"/>',
|
||||
'message.delete.affinity.group': '<fmt:message key="message.delete.affinity.group"/>',
|
||||
'label.delete.affinity.group': '<fmt:message key="label.delete.affinity.group"/>',
|
||||
'label.edit.affinity.group': '<fmt:message key="label.edit.affinity.group"/>',
|
||||
'label.affinity': '<fmt:message key="label.affinity"/>',
|
||||
'label.anti.affinity': '<fmt:message key="label.anti.affinity"/>',
|
||||
'label.affinity.groups': '<fmt:message key="label.affinity.groups"/>',
|
||||
'label.anti.affinity.groups': '<fmt:message key="label.anti.affinity.groups"/>',
|
||||
'label.affinity.group': '<fmt:message key="label.affinity.group"/>',
|
||||
'label.anti.affinity.group': '<fmt:message key="label.anti.affinity.group"/>',
|
||||
'message.redirecting.region': '<fmt:message key="message.redirecting.region"/>',
|
||||
'label.use.vm.ip': '<fmt:message key="label.use.vm.ip"/>',
|
||||
'label.cpu.limits': '<fmt:message key="label.cpu.limits"/>',
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 188 KiB |
19
ui/index.jsp
19
ui/index.jsp
|
|
@ -94,8 +94,9 @@ under the License.
|
|||
<li><span class="number">2</span><span class="multiline"><fmt:message key="label.select.a.template"/></span><span class="arrow"></span></li>
|
||||
<li><span class="number">3</span><span class="multiline"><fmt:message key="label.compute.offering"/></span><span class="arrow"></span></li>
|
||||
<li><span class="number">4</span><span class="multiline"><fmt:message key="label.data.disk.offering"/></span><span class="arrow"></span></li>
|
||||
<li><span class="number">5</span><span><fmt:message key="label.menu.network"/></span><span class="arrow"></span></li>
|
||||
<li class="last"><span class="number">6</span><span><fmt:message key="label.review"/></span></li>
|
||||
<li><span class="number">5</span><span><fmt:message key="label.affinity"/></span><span class="arrow"></span></li>
|
||||
<li><span class="number">6</span><span><fmt:message key="label.menu.network"/></span><span class="arrow"></span></li>
|
||||
<li class="last"><span class="number">7</span><span><fmt:message key="label.review"/></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<form>
|
||||
|
|
@ -225,7 +226,15 @@ under the License.
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 5: Network -->
|
||||
<!-- Step 5: Affinity groups -->
|
||||
<div class="step affinity" wizard-step-id="affinity">
|
||||
<div class="content">
|
||||
<!-- Existing offerings -->
|
||||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 6: Network -->
|
||||
<div class="step network always-load" wizard-step-id="network">
|
||||
<!-- 5a: Network description -->
|
||||
<div class="wizard-step-conditional nothing-to-select">
|
||||
|
|
@ -325,7 +334,7 @@ under the License.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Step 6: Review -->
|
||||
<!-- Step 7: Review -->
|
||||
<div class="step review" wizard-step-id="review">
|
||||
<div class="main-desc">
|
||||
<fmt:message key="message.vm.review.launch"/>
|
||||
|
|
@ -1660,6 +1669,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>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
// 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.sections.affinityGroups = {
|
||||
title: 'label.affinity.groups',
|
||||
listView: {
|
||||
id: 'affinityGroups',
|
||||
fields: {
|
||||
name: { label: 'label.name' },
|
||||
type: { label: 'label.type' }
|
||||
},
|
||||
dataProvider: function(args) {
|
||||
var data = {};
|
||||
if (args.context != null) {
|
||||
if ("instances" in args.context) {
|
||||
$.extend(data, {
|
||||
virtualmachineid: args.context.instances[0].id
|
||||
});
|
||||
}
|
||||
}
|
||||
$.ajax({
|
||||
url: createURL('listAffinityGroups'),
|
||||
data: data,
|
||||
success: function(json) {
|
||||
var items = json.listaffinitygroupsresponse.affinitygroup;
|
||||
args.response.success({data: items});
|
||||
}
|
||||
});
|
||||
},
|
||||
actions: {
|
||||
add: {
|
||||
label: 'label.add.affinity.group',
|
||||
|
||||
messages: {
|
||||
notification: function(args) {
|
||||
return 'label.add.affinity.group';
|
||||
}
|
||||
},
|
||||
|
||||
createForm: {
|
||||
title: 'label.add.affinity.group',
|
||||
fields: {
|
||||
name: {
|
||||
label: 'label.name',
|
||||
validation: { required: true }
|
||||
},
|
||||
description: {
|
||||
label: 'label.description'
|
||||
},
|
||||
type: {
|
||||
label: 'label.type',
|
||||
select: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('listAffinityGroupTypes'),
|
||||
success: function(json) {
|
||||
var types = [];
|
||||
var items = json.listaffinitygrouptypesresponse.affinityGroupType;
|
||||
if(items != null) {
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
types.push({id: items[i].type, description: items[i].type});
|
||||
}
|
||||
}
|
||||
args.response.success({data: types})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
action: function(args) {
|
||||
var data = {
|
||||
name: args.data.name,
|
||||
type: args.data.type
|
||||
};
|
||||
if(args.data.description != null && args.data.description.length > 0)
|
||||
$.extend(data, {description: args.data.description});
|
||||
|
||||
$.ajax({
|
||||
url: createURL('createAffinityGroup'),
|
||||
data: data,
|
||||
success: function(json) {
|
||||
var jid = json.createaffinitygroupresponse.jobid;
|
||||
args.response.success(
|
||||
{_custom:
|
||||
{jobId: jid,
|
||||
getUpdatedItem: function(json) {
|
||||
return json.queryasyncjobresultresponse.jobresult.affinitygroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
notification: {
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
}
|
||||
},
|
||||
detailView: {
|
||||
actions: {
|
||||
remove: {
|
||||
label: 'label.delete.affinity.group',
|
||||
messages: {
|
||||
confirm: function(args) {
|
||||
return 'message.delete.affinity.group';
|
||||
},
|
||||
notification: function(args) {
|
||||
return 'label.delete.affinity.group';
|
||||
}
|
||||
},
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('deleteAffinityGroup'),
|
||||
data: {
|
||||
id: args.context.affinityGroups[0].id
|
||||
},
|
||||
success: function(json) {
|
||||
var jid = json.deleteaffinitygroupresponse.jobid;
|
||||
args.response.success({
|
||||
_custom:{
|
||||
jobId: jid
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
notification: {
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
viewAll: { path: 'instances', label: 'label.instances' },
|
||||
|
||||
tabs: {
|
||||
details: {
|
||||
title: 'label.details',
|
||||
fields: [
|
||||
{
|
||||
name: { label: 'label.name' }
|
||||
},
|
||||
{
|
||||
description: { label: 'label.description' },
|
||||
type: { label: 'label.type' },
|
||||
id: { label: 'label.id' }
|
||||
}
|
||||
],
|
||||
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('listAffinityGroups'),
|
||||
data: {
|
||||
id: args.context.affinityGroups[0].id
|
||||
},
|
||||
success: function(json) {
|
||||
var item = json.listaffinitygroupsresponse.affinitygroup[0];
|
||||
args.response.success({data: item});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})(cloudStack);
|
||||
|
|
@ -22,16 +22,16 @@
|
|||
var sections = [];
|
||||
|
||||
if(isAdmin()) {
|
||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "system", "global-settings", "configuration", "projects", "regions"];
|
||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "system", "global-settings", "configuration", "projects", "regions", "affinityGroups"];
|
||||
}
|
||||
else if(isDomainAdmin()) {
|
||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "projects", "regions"];
|
||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "projects", "regions", "affinityGroups"];
|
||||
}
|
||||
else if (g_userProjectsEnabled) {
|
||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "projects", "regions"];
|
||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "projects", "regions", "affinityGroups"];
|
||||
}
|
||||
else { //normal user
|
||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "regions"];
|
||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "regions", "affinityGroups"];
|
||||
}
|
||||
|
||||
if (cloudStack.plugins.length) {
|
||||
|
|
@ -46,6 +46,7 @@
|
|||
*/
|
||||
dashboard: {},
|
||||
instances: {},
|
||||
affinityGroups: {},
|
||||
storage: {},
|
||||
network: {},
|
||||
templates: {},
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -194,17 +194,23 @@
|
|||
}
|
||||
|
||||
if("hosts" in args.context) {
|
||||
$.extend(data, {
|
||||
hostid: args.context.hosts[0].id
|
||||
});
|
||||
}
|
||||
|
||||
$.extend(data, {
|
||||
hostid: args.context.hosts[0].id
|
||||
});
|
||||
}
|
||||
|
||||
if("affinityGroups" in args.context) {
|
||||
$.extend(data, {
|
||||
affinitygroupid: args.context.affinityGroups[0].id
|
||||
});
|
||||
}
|
||||
|
||||
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
|
||||
$.extend(data, {
|
||||
zonetype: args.context.zoneType
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listVirtualMachines'),
|
||||
data: data,
|
||||
|
|
@ -223,6 +229,7 @@
|
|||
viewAll: [
|
||||
{ path: 'storage.volumes', label: 'label.volumes' },
|
||||
{ path: 'vmsnapshots', label: 'label.snapshots' },
|
||||
{ path: 'affinityGroups', label: 'label.affinity.groups' },
|
||||
{
|
||||
path: '_zone.hosts',
|
||||
label: 'label.hosts',
|
||||
|
|
@ -426,7 +433,6 @@
|
|||
poll: pollAsyncJobResult
|
||||
}
|
||||
},
|
||||
|
||||
snapshot: {
|
||||
messages: {
|
||||
notification: function(args) {
|
||||
|
|
@ -489,7 +495,6 @@
|
|||
pool: pollAsyncJobResult
|
||||
}
|
||||
},
|
||||
|
||||
destroy: {
|
||||
label: 'label.action.destroy.instance',
|
||||
compactLabel: 'label.destroy',
|
||||
|
|
@ -555,7 +560,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
reset: {
|
||||
label: 'Reset VM',
|
||||
messages:{
|
||||
|
|
@ -586,8 +590,128 @@
|
|||
}
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
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) {
|
||||
$.ajax({
|
||||
url: createURL('listAffinityGroups'),
|
||||
async: false, //make it sync to avoid dataProvider() being called twice which produces duplicate data
|
||||
success: function(json) {
|
||||
var items = [];
|
||||
var allAffinityGroups = json.listaffinitygroupsresponse.affinitygroup;
|
||||
var previouslySelectedAffinityGroups = args.context.instances[0].affinitygroup;
|
||||
if(allAffinityGroups != null) {
|
||||
for(var i = 0; i < allAffinityGroups.length; i++) {
|
||||
var isPreviouslySelected = false;
|
||||
if(previouslySelectedAffinityGroups != null) {
|
||||
for(var k = 0; k < previouslySelectedAffinityGroups.length; k++) {
|
||||
if(previouslySelectedAffinityGroups[k].id == allAffinityGroups[i].id) {
|
||||
isPreviouslySelected = true;
|
||||
break; //break for loop
|
||||
}
|
||||
}
|
||||
}
|
||||
items.push($.extend(allAffinityGroups[i], {
|
||||
_isSelected: isPreviouslySelected
|
||||
}));
|
||||
}
|
||||
}
|
||||
args.response.success({data: items});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
action: function(args) {
|
||||
var affinityGroupIdArray = [];
|
||||
if(args.context.affinityGroups != null) {
|
||||
for(var i = 0; i < args.context.affinityGroups.length; i++) {
|
||||
if(args.context.affinityGroups[i]._isSelected == true) {
|
||||
affinityGroupIdArray.push(args.context.affinityGroups[i].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
var data = {
|
||||
id: args.context.instances[0].id,
|
||||
affinitygroupids: affinityGroupIdArray.join(",")
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('updateVMAffinityGroup'),
|
||||
data: data,
|
||||
success: function(json) {
|
||||
var jid = json.updatevirtualmachineresponse.jobid;
|
||||
args.response.success(
|
||||
{_custom:
|
||||
{jobId: jid,
|
||||
getUpdatedItem: function(json) {
|
||||
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
|
||||
},
|
||||
getActionFilter: function() {
|
||||
return vmActionfilter;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
messages: {
|
||||
notification: function(args) {
|
||||
return 'Change affinity';
|
||||
}
|
||||
},
|
||||
notification: {
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
},
|
||||
|
||||
edit: {
|
||||
label: 'label.edit',
|
||||
|
|
@ -597,7 +721,7 @@
|
|||
group: args.data.group,
|
||||
ostypeid: args.data.guestosid
|
||||
};
|
||||
|
||||
|
||||
if(args.data.displayname != args.context.instances[0].displayname) {
|
||||
$.extend(data, {
|
||||
displayName: args.data.displayname
|
||||
|
|
@ -1380,7 +1504,7 @@
|
|||
args.response.success({data: args.context.instances[0].securitygroup});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Statistics tab
|
||||
*/
|
||||
|
|
@ -1450,6 +1574,7 @@
|
|||
allowedActions.push("reset");
|
||||
allowedActions.push("snapshot");
|
||||
allowedActions.push("scaleUp");
|
||||
allowedActions.push("changeAffinity");
|
||||
|
||||
if(isAdmin())
|
||||
allowedActions.push("migrateToAnotherStorage");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,173 @@
|
|||
// 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.affinity.groups'),
|
||||
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;
|
||||
}
|
||||
|
||||
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, {
|
||||
affinityGroups: $dataList.find('tbody tr').map(function(index, elem) {
|
||||
var itemData = $(elem).data('json-obj');
|
||||
itemData._isSelected = false;
|
||||
|
||||
if ($(elem).hasClass('multi-edit-selected')) {
|
||||
itemData._isSelected = true;
|
||||
}
|
||||
|
||||
return itemData;
|
||||
})
|
||||
}),
|
||||
response: {
|
||||
success: function(args) {
|
||||
complete({
|
||||
_custom: args._custom,
|
||||
$item: $instanceRow
|
||||
});
|
||||
},
|
||||
error: function(args) {
|
||||
cloudStack.dialog.notice({ message: args });
|
||||
}
|
||||
}
|
||||
});
|
||||
$dataList.remove();
|
||||
});
|
||||
|
||||
$('div.overlay').fadeOut(function() {
|
||||
$('div.overlay').remove();
|
||||
$(':ui-dialog').dialog('destroy');
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
text: _l('label.cancel'),
|
||||
'class': 'cancel',
|
||||
click: function() {
|
||||
$dataList.fadeOut(function() {
|
||||
$dataList.remove();
|
||||
});
|
||||
$('div.overlay').fadeOut(function() {
|
||||
$('div.overlay').remove();
|
||||
$(':ui-dialog').dialog('destroy');
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
}).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));
|
||||
|
|
@ -482,6 +482,25 @@
|
|||
};
|
||||
},
|
||||
|
||||
'affinity': function($step, formData) {
|
||||
return {
|
||||
response: {
|
||||
success: function(args) {
|
||||
$step.find('.select-container').append(
|
||||
makeSelects('affinity-groups', args.data.affinityGroups, {
|
||||
name: 'name',
|
||||
desc: 'description',
|
||||
id: 'id'
|
||||
}, {
|
||||
type: 'checkbox',
|
||||
'wizard-field': 'affinity-groups'
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
'network': function($step, formData) {
|
||||
var showAddNetwork = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@
|
|||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
(function($, cloudStack, _l) {
|
||||
var replaceListViewItem = function($detailView, newData) {
|
||||
var $row = $detailView.data('list-view-row');
|
||||
var replaceListViewItem = function($detailView, newData, options) {
|
||||
var $row = $detailView ? $detailView.data('list-view-row') :
|
||||
options.$row;
|
||||
|
||||
if (!$row) return;
|
||||
|
||||
|
|
@ -32,7 +33,9 @@
|
|||
$row: $row,
|
||||
data: $.extend(jsonObj, newData),
|
||||
after: function($newRow) {
|
||||
$detailView.data('list-view-row', $newRow);
|
||||
if ($detailView) {
|
||||
$detailView.data('list-view-row', $newRow);
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
$('.data-table').dataTable('selectRow', $newRow.index());
|
||||
|
|
@ -42,11 +45,13 @@
|
|||
}
|
||||
|
||||
// Refresh detail view context
|
||||
$.extend(
|
||||
$detailView.data('view-args').context[
|
||||
$detailView.data('view-args').section
|
||||
][0], newData
|
||||
);
|
||||
if ($detailView) {
|
||||
$.extend(
|
||||
$detailView.data('view-args').context[
|
||||
$detailView.data('view-args').section
|
||||
][0], newData
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -125,6 +130,7 @@
|
|||
args = args ? args : {};
|
||||
|
||||
var $item = args.$item;
|
||||
var $row = $detailView.data('list-view-row');
|
||||
|
||||
notification.desc = messages.notification(args.messageArgs);
|
||||
notification._custom = $.extend(args._custom ? args._custom : {}, {
|
||||
|
|
@ -140,11 +146,14 @@
|
|||
viewArgs.onActionComplete();
|
||||
}
|
||||
|
||||
if (!$detailView.parents('html').size()) return;
|
||||
if (!$detailView.parents('html').size()) {
|
||||
replaceListViewItem(null, args.data, { $row: $row });
|
||||
return;
|
||||
}
|
||||
|
||||
replaceListViewItem($detailView, args.data);
|
||||
$loading.remove();
|
||||
$detailView.removeClass('detail-view-loading-state');
|
||||
replaceListViewItem($detailView, args.data);
|
||||
|
||||
if (!noRefresh) {
|
||||
updateTabContent(args.data);
|
||||
|
|
|
|||
|
|
@ -734,6 +734,8 @@
|
|||
var makeActionIcons = function($td, actions, options) {
|
||||
options = options ? options : {};
|
||||
var allowedActions = options.allowedActions;
|
||||
var $tr = $td.closest('tr');
|
||||
var data = $tr && $tr.data('json-obj') ? $tr.data('json-obj') : null;
|
||||
|
||||
$.each(actions, function(actionName, action) {
|
||||
if (actionName == 'add' || action.isHeader)
|
||||
|
|
@ -766,7 +768,9 @@
|
|||
.append(
|
||||
$('<input>').attr({
|
||||
type: 'checkbox',
|
||||
name: actionName
|
||||
name: actionName,
|
||||
checked: data && data._isSelected ?
|
||||
'checked' : false
|
||||
})
|
||||
)
|
||||
.attr({
|
||||
|
|
@ -776,6 +780,10 @@
|
|||
.data('list-view-action-id', actionName)
|
||||
);
|
||||
|
||||
if ($td.find('input[type=checkbox]').is(':checked')) {
|
||||
$tr.addClass('multi-edit-selected');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue