mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Format JS
This commit is contained in:
parent
dfa612d1fe
commit
ad69bc8da3
File diff suppressed because it is too large
Load Diff
@ -15,169 +15,193 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function(cloudStack) {
|
(function(cloudStack) {
|
||||||
cloudStack.sections.affinityGroups = {
|
cloudStack.sections.affinityGroups = {
|
||||||
title: 'label.affinity.groups',
|
title: 'label.affinity.groups',
|
||||||
listView: {
|
listView: {
|
||||||
id: 'affinityGroups',
|
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: {
|
fields: {
|
||||||
name: {
|
name: {
|
||||||
label: 'label.name',
|
label: 'label.name'
|
||||||
validation: { required: true }
|
},
|
||||||
},
|
type: {
|
||||||
description: {
|
label: 'label.type'
|
||||||
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) {
|
dataProvider: function(args) {
|
||||||
$.ajax({
|
var data = {};
|
||||||
url: createURL('listAffinityGroups'),
|
if (args.context != null) {
|
||||||
data: {
|
if ("instances" in args.context) {
|
||||||
id: args.context.affinityGroups[0].id
|
$.extend(data, {
|
||||||
},
|
virtualmachineid: args.context.instances[0].id
|
||||||
success: function(json) {
|
});
|
||||||
var item = json.listaffinitygroupsresponse.affinitygroup[0];
|
}
|
||||||
args.response.success({data: item});
|
}
|
||||||
}
|
$.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);
|
})(cloudStack);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,13 @@
|
|||||||
// KIND, either express or implied. See the License for the
|
// KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
$.urlParam = function(name){ var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href); if (!results) { return 0; } return results[1] || 0;}
|
$.urlParam = function(name) {
|
||||||
|
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
|
||||||
|
if (!results) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return results[1] || 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file is meant to help with implementing single signon integration. If you are using the
|
This file is meant to help with implementing single signon integration. If you are using the
|
||||||
@ -26,12 +32,13 @@ This callback function is called when either the session has timed out for the u
|
|||||||
the session ID has been changed (i.e. another user logging into the UI via a different tab),
|
the session ID has been changed (i.e. another user logging into the UI via a different tab),
|
||||||
or it's the first time the user has come to this page.
|
or it's the first time the user has come to this page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function onLogoutCallback() {
|
function onLogoutCallback() {
|
||||||
g_loginResponse = null; //clear single signon variable g_loginResponse
|
g_loginResponse = null; //clear single signon variable g_loginResponse
|
||||||
|
|
||||||
|
|
||||||
return true; // return true means the login page will show
|
return true; // return true means the login page will show
|
||||||
/*
|
/*
|
||||||
window.location.replace("http://www.google.com"); //redirect to a different location
|
window.location.replace("http://www.google.com"); //redirect to a different location
|
||||||
return false; //return false means it will stay in the location window.location.replace() sets it to (i.e. "http://www.google.com")
|
return false; //return false means it will stay in the location window.location.replace() sets it to (i.e. "http://www.google.com")
|
||||||
*/
|
*/
|
||||||
@ -50,29 +57,27 @@ Below is a sample login attempt
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var clientApiUrl = "/client/api";
|
var clientApiUrl = "/client/api";
|
||||||
var clientConsoleUrl = "/client/console";
|
var clientConsoleUrl = "/client/console";
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
var url = $.urlParam("loginUrl");
|
var url = $.urlParam("loginUrl");
|
||||||
if (url != undefined && url != null && url.length > 0) {
|
if (url != undefined && url != null && url.length > 0) {
|
||||||
url = unescape(clientApiUrl+"?"+url);
|
url = unescape(clientApiUrl + "?" + url);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
async: false,
|
async: false,
|
||||||
success: function(json) {
|
success: function(json) {
|
||||||
g_loginResponse = json.loginresponse;
|
g_loginResponse = json.loginresponse;
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function() {
|
||||||
onLogoutCallback();
|
onLogoutCallback();
|
||||||
// This means the login failed. You should redirect to your login page.
|
// This means the login failed. You should redirect to your login page.
|
||||||
},
|
},
|
||||||
beforeSend: function(XMLHttpRequest) {
|
beforeSend: function(XMLHttpRequest) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -15,480 +15,518 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function(cloudStack, $) {
|
(function(cloudStack, $) {
|
||||||
$.extend(cloudStack, {
|
$.extend(cloudStack, {
|
||||||
home: 'dashboard',
|
home: 'dashboard',
|
||||||
|
|
||||||
sectionPreFilter: function(args) {
|
sectionPreFilter: function(args) {
|
||||||
var sections = [];
|
var sections = [];
|
||||||
|
|
||||||
if(isAdmin()) {
|
if (isAdmin()) {
|
||||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "system", "global-settings", "configuration", "projects", "regions", "affinityGroups"];
|
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "system", "global-settings", "configuration", "projects", "regions", "affinityGroups"];
|
||||||
}
|
} else if (isDomainAdmin()) {
|
||||||
else if(isDomainAdmin()) {
|
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "projects", "regions", "affinityGroups"];
|
||||||
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", "affinityGroups"];
|
||||||
else if (g_userProjectsEnabled) {
|
} else { //normal user
|
||||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "projects", "regions", "affinityGroups"];
|
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "regions", "affinityGroups"];
|
||||||
}
|
|
||||||
else { //normal user
|
|
||||||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "regions", "affinityGroups"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cloudStack.plugins.length) {
|
|
||||||
sections.push('plugins');
|
|
||||||
}
|
|
||||||
|
|
||||||
return sections;
|
|
||||||
},
|
|
||||||
sections: {
|
|
||||||
/**
|
|
||||||
* Dashboard
|
|
||||||
*/
|
|
||||||
dashboard: {},
|
|
||||||
instances: {},
|
|
||||||
affinityGroups: {},
|
|
||||||
storage: {},
|
|
||||||
network: {},
|
|
||||||
templates: {},
|
|
||||||
events: {},
|
|
||||||
projects: {},
|
|
||||||
accounts: {},
|
|
||||||
|
|
||||||
domains: {}, //domain-admin and root-admin only
|
|
||||||
|
|
||||||
regions: {}, //root-admin only
|
|
||||||
system: {}, //root-admin only
|
|
||||||
'global-settings': {}, //root-admin only
|
|
||||||
configuration: {}, //root-admin only
|
|
||||||
plugins: {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(window).bind('cloudStack.pluginReady', function() {
|
|
||||||
// Get language
|
|
||||||
g_lang = $.cookie('lang') ? $.cookie('lang') : 'en';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic error handling
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.ajaxSetup({
|
|
||||||
url: clientApiUrl,
|
|
||||||
async: true,
|
|
||||||
dataType: 'json',
|
|
||||||
cache: false,
|
|
||||||
error: function(data) {
|
|
||||||
var clickAction = false;
|
|
||||||
if (isValidJsonString(data.responseText)) {
|
|
||||||
var json = JSON.parse(data.responseText);
|
|
||||||
if (json != null) {
|
|
||||||
var property;
|
|
||||||
for(property in json) {}
|
|
||||||
var errorObj = json[property];
|
|
||||||
if(errorObj.errorcode == 401 && errorObj.errortext == "unable to verify user credentials and/or request signature") {
|
|
||||||
clickAction = function() {
|
|
||||||
$('#user-options a').eq(0).trigger('click');
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (cloudStack.plugins.length) {
|
||||||
|
sections.push('plugins');
|
||||||
|
}
|
||||||
|
|
||||||
|
return sections;
|
||||||
|
},
|
||||||
|
sections: {
|
||||||
|
/**
|
||||||
|
* Dashboard
|
||||||
|
*/
|
||||||
|
dashboard: {},
|
||||||
|
instances: {},
|
||||||
|
affinityGroups: {},
|
||||||
|
storage: {},
|
||||||
|
network: {},
|
||||||
|
templates: {},
|
||||||
|
events: {},
|
||||||
|
projects: {},
|
||||||
|
accounts: {},
|
||||||
|
|
||||||
|
domains: {}, //domain-admin and root-admin only
|
||||||
|
|
||||||
|
regions: {}, //root-admin only
|
||||||
|
system: {}, //root-admin only
|
||||||
|
'global-settings': {}, //root-admin only
|
||||||
|
configuration: {}, //root-admin only
|
||||||
|
plugins: {}
|
||||||
}
|
}
|
||||||
cloudStack.dialog.notice({ message: parseXMLHttpResponse(data), clickAction: clickAction });
|
|
||||||
},
|
|
||||||
beforeSend: function(XMLHttpRequest) {
|
|
||||||
if (g_mySession == $.cookie("JSESSIONID")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var clickAction = function() {
|
|
||||||
$('#user-options a').eq(0).trigger('click');
|
|
||||||
};
|
|
||||||
cloudStack.dialog.notice({ message: _l('label.session.expired'), clickAction: clickAction });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var $container = $('#cloudStack3-container');
|
$(window).bind('cloudStack.pluginReady', function() {
|
||||||
|
// Get language
|
||||||
|
g_lang = $.cookie('lang') ? $.cookie('lang') : 'en';
|
||||||
|
|
||||||
var loginArgs = {
|
/**
|
||||||
$container: $container,
|
* Generic error handling
|
||||||
|
*/
|
||||||
|
|
||||||
// Use this for checking the session, to bypass login screen
|
$.ajaxSetup({
|
||||||
bypassLoginCheck: function(args) { //determine to show or bypass login screen
|
url: clientApiUrl,
|
||||||
if (g_loginResponse == null) { //show login screen
|
async: true,
|
||||||
/*
|
dataType: 'json',
|
||||||
|
cache: false,
|
||||||
|
error: function(data) {
|
||||||
|
var clickAction = false;
|
||||||
|
if (isValidJsonString(data.responseText)) {
|
||||||
|
var json = JSON.parse(data.responseText);
|
||||||
|
if (json != null) {
|
||||||
|
var property;
|
||||||
|
for (property in json) {}
|
||||||
|
var errorObj = json[property];
|
||||||
|
if (errorObj.errorcode == 401 && errorObj.errortext == "unable to verify user credentials and/or request signature") {
|
||||||
|
clickAction = function() {
|
||||||
|
$('#user-options a').eq(0).trigger('click');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: parseXMLHttpResponse(data),
|
||||||
|
clickAction: clickAction
|
||||||
|
});
|
||||||
|
},
|
||||||
|
beforeSend: function(XMLHttpRequest) {
|
||||||
|
if (g_mySession == $.cookie("JSESSIONID")) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
var clickAction = function() {
|
||||||
|
$('#user-options a').eq(0).trigger('click');
|
||||||
|
};
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _l('label.session.expired'),
|
||||||
|
clickAction: clickAction
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var $container = $('#cloudStack3-container');
|
||||||
|
|
||||||
|
var loginArgs = {
|
||||||
|
$container: $container,
|
||||||
|
|
||||||
|
// Use this for checking the session, to bypass login screen
|
||||||
|
bypassLoginCheck: function(args) { //determine to show or bypass login screen
|
||||||
|
if (g_loginResponse == null) { //show login screen
|
||||||
|
/*
|
||||||
but if this is a 2nd browser window (of the same domain), login screen still won't show because $.cookie('sessionKey') is valid for 2nd browser window (of the same domain) as well.
|
but if this is a 2nd browser window (of the same domain), login screen still won't show because $.cookie('sessionKey') is valid for 2nd browser window (of the same domain) as well.
|
||||||
i.e. calling listCapabilities API with g_sessionKey from $.cookie('sessionKey') will succeed,
|
i.e. calling listCapabilities API with g_sessionKey from $.cookie('sessionKey') will succeed,
|
||||||
then userValid will be set to true, then an user object (instead of "false") will be returned, then login screen will be bypassed.
|
then userValid will be set to true, then an user object (instead of "false") will be returned, then login screen will be bypassed.
|
||||||
*/
|
*/
|
||||||
g_mySession = $.cookie('JSESSIONID');
|
g_mySession = $.cookie('JSESSIONID');
|
||||||
g_sessionKey = $.cookie('sessionKey');
|
g_sessionKey = $.cookie('sessionKey');
|
||||||
g_role = $.cookie('role');
|
g_role = $.cookie('role');
|
||||||
g_username = $.cookie('username');
|
g_username = $.cookie('username');
|
||||||
g_userid = $.cookie('userid');
|
g_userid = $.cookie('userid');
|
||||||
g_account = $.cookie('account');
|
g_account = $.cookie('account');
|
||||||
g_domainid = $.cookie('domainid');
|
g_domainid = $.cookie('domainid');
|
||||||
g_userfullname = $.cookie('userfullname');
|
g_userfullname = $.cookie('userfullname');
|
||||||
g_timezone = $.cookie('timezone');
|
g_timezone = $.cookie('timezone');
|
||||||
if($.cookie('timezoneoffset') != null)
|
if ($.cookie('timezoneoffset') != null)
|
||||||
g_timezoneoffset = isNaN($.cookie('timezoneoffset'))? null: parseFloat($.cookie('timezoneoffset'));
|
g_timezoneoffset = isNaN($.cookie('timezoneoffset')) ? null : parseFloat($.cookie('timezoneoffset'));
|
||||||
else
|
else
|
||||||
g_timezoneoffset = null;
|
g_timezoneoffset = null;
|
||||||
}
|
} else { //single-sign-on (bypass login screen)
|
||||||
else { //single-sign-on (bypass login screen)
|
g_mySession = $.cookie('JSESSIONID');
|
||||||
g_mySession = $.cookie('JSESSIONID');
|
g_sessionKey = encodeURIComponent(g_loginResponse.sessionkey);
|
||||||
g_sessionKey = encodeURIComponent(g_loginResponse.sessionkey);
|
g_role = g_loginResponse.type;
|
||||||
g_role = g_loginResponse.type;
|
g_username = g_loginResponse.username;
|
||||||
g_username = g_loginResponse.username;
|
g_userid = g_loginResponse.userid;
|
||||||
g_userid = g_loginResponse.userid;
|
g_account = g_loginResponse.account;
|
||||||
g_account = g_loginResponse.account;
|
g_domainid = g_loginResponse.domainid;
|
||||||
g_domainid = g_loginResponse.domainid;
|
g_userfullname = g_loginResponse.firstname + ' ' + g_loginResponse.lastname;
|
||||||
g_userfullname = g_loginResponse.firstname + ' ' + g_loginResponse.lastname;
|
g_timezone = g_loginResponse.timezone;
|
||||||
g_timezone = g_loginResponse.timezone;
|
if (g_loginResponse.timezoneoffset != null)
|
||||||
if(g_loginResponse.timezoneoffset != null)
|
g_timezoneoffset = isNaN(g_loginResponse.timezoneoffset) ? null : parseFloat(g_loginResponse.timezoneoffset);
|
||||||
g_timezoneoffset = isNaN(g_loginResponse.timezoneoffset)? null: parseFloat(g_loginResponse.timezoneoffset);
|
else
|
||||||
else
|
g_timezoneoffset = null;
|
||||||
g_timezoneoffset = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var userValid = false;
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("listCapabilities"),
|
|
||||||
dataType: "json",
|
|
||||||
async: false,
|
|
||||||
success: function(json) {
|
|
||||||
g_capabilities = json.listcapabilitiesresponse.capability;
|
|
||||||
$.cookie('capabilities', g_capabilities, { expires: 1});
|
|
||||||
|
|
||||||
g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean
|
|
||||||
$.cookie('supportELB', g_supportELB, { expires: 1});
|
|
||||||
|
|
||||||
if (json.listcapabilitiesresponse.capability.userpublictemplateenabled != null) {
|
|
||||||
g_userPublicTemplateEnabled = json.listcapabilitiesresponse.capability.userpublictemplateenabled.toString(); //convert boolean to string if it's boolean
|
|
||||||
$.cookie('userpublictemplateenabled', g_userPublicTemplateEnabled, { expires: 1});
|
|
||||||
}
|
|
||||||
|
|
||||||
g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;
|
|
||||||
$.cookie('userProjectsEnabled', g_userProjectsEnabled, { expires: 1 });
|
|
||||||
|
|
||||||
g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion;
|
|
||||||
|
|
||||||
if(json.listcapabilitiesresponse.capability.apilimitinterval != null && json.listcapabilitiesresponse.capability.apilimitmax != null) {
|
|
||||||
var intervalLimit = ((json.listcapabilitiesresponse.capability.apilimitinterval * 1000) / json.listcapabilitiesresponse.capability.apilimitmax ) * 3; //multiply 3 to be on safe side
|
|
||||||
//intervalLimit = 9999; //this line is for testing only, comment it before check in
|
|
||||||
if(intervalLimit > g_queryAsyncJobResultInterval)
|
|
||||||
g_queryAsyncJobResultInterval = intervalLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
userValid = true;
|
|
||||||
},
|
|
||||||
error: function(xmlHTTP) { //override default error handling, do nothing instead of showing error "unable to verify user credentials" on login screen
|
|
||||||
},
|
|
||||||
beforeSend : function(XMLHttpResponse) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (userValid && isAdmin()) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("listImageStores"),
|
|
||||||
data: {
|
|
||||||
provider: 'Swift'
|
|
||||||
},
|
|
||||||
async: false,
|
|
||||||
success: function(json) {
|
|
||||||
var items = json.listimagestoreresponse.imagestore;
|
|
||||||
if(items != null && items.length > 0)
|
|
||||||
havingSwift = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (havingSwift == false) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("listImageStores"),
|
|
||||||
data: {
|
|
||||||
provider: 'S3'
|
|
||||||
},
|
|
||||||
async: false,
|
|
||||||
success: function(json) {
|
|
||||||
var items = json.listimagestoreresponse.imagestore;
|
|
||||||
if (items != null && items.length > 0) {
|
|
||||||
havingS3 = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
havingSwift = false;
|
|
||||||
havingS3 = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return userValid ? {
|
|
||||||
user: {
|
|
||||||
userid: g_userid,
|
|
||||||
username: g_username,
|
|
||||||
account: g_account,
|
|
||||||
name: g_userfullname,
|
|
||||||
role: g_role,
|
|
||||||
domainid: g_domainid
|
|
||||||
}
|
|
||||||
} : false;
|
|
||||||
|
|
||||||
return testAddUser;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Actual login process, via form
|
|
||||||
loginAction: function(args) {
|
|
||||||
var array1 = [];
|
|
||||||
array1.push("&username=" + encodeURIComponent(args.data.username));
|
|
||||||
|
|
||||||
var password;
|
|
||||||
if (md5HashedLogin)
|
|
||||||
password = $.md5(args.data.password);
|
|
||||||
else
|
|
||||||
password = todb(args.data.password);
|
|
||||||
array1.push("&password=" + password);
|
|
||||||
|
|
||||||
var domain;
|
|
||||||
if(args.data.domain != null && args.data.domain.length > 0) {
|
|
||||||
if (args.data.domain.charAt(0) != "/")
|
|
||||||
domain = "/" + args.data.domain;
|
|
||||||
else
|
|
||||||
domain = args.data.domain;
|
|
||||||
array1.push("&domain=" + encodeURIComponent(domain));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
array1.push("&domain=" + encodeURIComponent("/"));
|
|
||||||
}
|
|
||||||
|
|
||||||
var loginCmdText = array1.join("");
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
data: "command=login" + loginCmdText + "&response=json",
|
|
||||||
dataType: "json",
|
|
||||||
async: false,
|
|
||||||
success: function(json) {
|
|
||||||
var loginresponse = json.loginresponse;
|
|
||||||
|
|
||||||
g_mySession = $.cookie('JSESSIONID');
|
|
||||||
g_sessionKey = encodeURIComponent(loginresponse.sessionkey);
|
|
||||||
g_role = loginresponse.type;
|
|
||||||
g_username = loginresponse.username;
|
|
||||||
g_userid = loginresponse.userid;
|
|
||||||
g_account = loginresponse.account;
|
|
||||||
g_domainid = loginresponse.domainid;
|
|
||||||
g_timezone = loginresponse.timezone;
|
|
||||||
g_timezoneoffset = loginresponse.timezoneoffset;
|
|
||||||
g_userfullname = loginresponse.firstname + ' ' + loginresponse.lastname;
|
|
||||||
|
|
||||||
$.cookie('sessionKey', g_sessionKey, { expires: 1});
|
|
||||||
$.cookie('username', g_username, { expires: 1});
|
|
||||||
$.cookie('account', g_account, { expires: 1});
|
|
||||||
$.cookie('domainid', g_domainid, { expires: 1});
|
|
||||||
$.cookie('role', g_role, { expires: 1});
|
|
||||||
$.cookie('timezoneoffset', g_timezoneoffset, { expires: 1});
|
|
||||||
$.cookie('timezone', g_timezone, { expires: 1});
|
|
||||||
$.cookie('userfullname', g_userfullname, { expires: 1 });
|
|
||||||
$.cookie('userid', g_userid, { expires: 1 });
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("listCapabilities"),
|
|
||||||
dataType: "json",
|
|
||||||
async: false,
|
|
||||||
success: function(json) {
|
|
||||||
g_capabilities = json.listcapabilitiesresponse.capability;
|
|
||||||
$.cookie('capabilities', g_capabilities, { expires: 1});
|
|
||||||
|
|
||||||
g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean
|
|
||||||
$.cookie('supportELB', g_supportELB, { expires: 1});
|
|
||||||
|
|
||||||
if (json.listcapabilitiesresponse.capability.userpublictemplateenabled != null) {
|
|
||||||
g_userPublicTemplateEnabled = json.listcapabilitiesresponse.capability.userpublictemplateenabled.toString(); //convert boolean to string if it's boolean
|
|
||||||
$.cookie('userpublictemplateenabled', g_userPublicTemplateEnabled, { expires: 1});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;
|
var userValid = false;
|
||||||
$.cookie('userProjectsEnabled', g_userProjectsEnabled, { expires: 1 });
|
|
||||||
|
|
||||||
g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion;
|
|
||||||
|
|
||||||
if(json.listcapabilitiesresponse.capability.apilimitinterval != null && json.listcapabilitiesresponse.capability.apilimitmax != null) {
|
|
||||||
var intervalLimit = ((json.listcapabilitiesresponse.capability.apilimitinterval * 1000) / json.listcapabilitiesresponse.capability.apilimitmax ) * 3; //multiply 3 to be on safe side
|
|
||||||
//intervalLimit = 8888; //this line is for testing only, comment it before check in
|
|
||||||
if(intervalLimit > g_queryAsyncJobResultInterval)
|
|
||||||
g_queryAsyncJobResultInterval = intervalLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
args.response.success({
|
|
||||||
data: {
|
|
||||||
user: $.extend(true, {}, loginresponse, {
|
|
||||||
name: loginresponse.firstname + ' ' + loginresponse.lastname,
|
|
||||||
role: loginresponse.type == 1 ? 'admin' : 'user',
|
|
||||||
type: loginresponse.type
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
error: function(xmlHTTP) {
|
|
||||||
args.response.error();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isAdmin()) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("listImageStores"),
|
|
||||||
data:{
|
|
||||||
provider: 'Swift'
|
|
||||||
},
|
|
||||||
async: false,
|
|
||||||
success: function(json) {
|
|
||||||
var items = json.listimagestoreresponse.imagestore;
|
|
||||||
if(items != null && items.length > 0)
|
|
||||||
havingSwift = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (havingSwift = false) {
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: createURL("listImageStores"),
|
url: createURL("listCapabilities"),
|
||||||
data: {
|
dataType: "json",
|
||||||
provider: 'S3'
|
async: false,
|
||||||
},
|
success: function(json) {
|
||||||
async: false,
|
g_capabilities = json.listcapabilitiesresponse.capability;
|
||||||
success: function(json) {
|
$.cookie('capabilities', g_capabilities, {
|
||||||
var items = json.listimagestoreresponse.imagestore;
|
expires: 1
|
||||||
if (items != null && items.length > 0) {
|
});
|
||||||
havingS3 = true;
|
|
||||||
|
g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean
|
||||||
|
$.cookie('supportELB', g_supportELB, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
if (json.listcapabilitiesresponse.capability.userpublictemplateenabled != null) {
|
||||||
|
g_userPublicTemplateEnabled = json.listcapabilitiesresponse.capability.userpublictemplateenabled.toString(); //convert boolean to string if it's boolean
|
||||||
|
$.cookie('userpublictemplateenabled', g_userPublicTemplateEnabled, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;
|
||||||
|
$.cookie('userProjectsEnabled', g_userProjectsEnabled, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion;
|
||||||
|
|
||||||
|
if (json.listcapabilitiesresponse.capability.apilimitinterval != null && json.listcapabilitiesresponse.capability.apilimitmax != null) {
|
||||||
|
var intervalLimit = ((json.listcapabilitiesresponse.capability.apilimitinterval * 1000) / json.listcapabilitiesresponse.capability.apilimitmax) * 3; //multiply 3 to be on safe side
|
||||||
|
//intervalLimit = 9999; //this line is for testing only, comment it before check in
|
||||||
|
if (intervalLimit > g_queryAsyncJobResultInterval)
|
||||||
|
g_queryAsyncJobResultInterval = intervalLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
userValid = true;
|
||||||
|
},
|
||||||
|
error: function(xmlHTTP) { //override default error handling, do nothing instead of showing error "unable to verify user credentials" on login screen
|
||||||
|
},
|
||||||
|
beforeSend: function(XMLHttpResponse) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else {
|
|
||||||
havingSwift = false;
|
|
||||||
havingS3 = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get project configuration
|
if (userValid && isAdmin()) {
|
||||||
// TEMPORARY -- replace w/ output of capability response, etc., once implemented
|
$.ajax({
|
||||||
window.g_projectsInviteRequired = false;
|
url: createURL("listImageStores"),
|
||||||
},
|
data: {
|
||||||
error: function(XMLHttpRequest) {
|
provider: 'Swift'
|
||||||
var errorMsg = parseXMLHttpResponse(XMLHttpRequest);
|
},
|
||||||
if(errorMsg.length == 0 && XMLHttpRequest.status == 0)
|
async: false,
|
||||||
errorMsg = dictionary['error.unable.to.reach.management.server'];
|
success: function(json) {
|
||||||
else
|
var items = json.listimagestoreresponse.imagestore;
|
||||||
errorMsg = _l('error.invalid.username.password'); //override error message
|
if (items != null && items.length > 0)
|
||||||
args.response.error(errorMsg);
|
havingSwift = true;
|
||||||
},
|
}
|
||||||
beforeSend : function(XMLHttpResponse) {
|
});
|
||||||
return true;
|
if (havingSwift == false) {
|
||||||
}
|
$.ajax({
|
||||||
});
|
url: createURL("listImageStores"),
|
||||||
},
|
data: {
|
||||||
|
provider: 'S3'
|
||||||
logoutAction: function(args) {
|
},
|
||||||
$.ajax({
|
async: false,
|
||||||
url: createURL('logout'),
|
success: function(json) {
|
||||||
async: false,
|
var items = json.listimagestoreresponse.imagestore;
|
||||||
success: function() {
|
if (items != null && items.length > 0) {
|
||||||
g_mySession = null;
|
havingS3 = true;
|
||||||
g_sessionKey = null;
|
}
|
||||||
g_username = null;
|
}
|
||||||
g_account = null;
|
});
|
||||||
g_domainid = null;
|
|
||||||
g_timezoneoffset = null;
|
|
||||||
g_timezone = null;
|
|
||||||
g_supportELB = null;
|
|
||||||
g_loginCmdText = null;
|
|
||||||
|
|
||||||
$.cookie('JSESSIONID', null);
|
|
||||||
$.cookie('sessionKey', null);
|
|
||||||
$.cookie('username', null);
|
|
||||||
$.cookie('account', null);
|
|
||||||
$.cookie('domainid', null);
|
|
||||||
$.cookie('role', null);
|
|
||||||
$.cookie('networktype', null);
|
|
||||||
$.cookie('timezoneoffset', null);
|
|
||||||
$.cookie('timezone', null);
|
|
||||||
$.cookie('supportELB', null);
|
|
||||||
|
|
||||||
if(onLogoutCallback()) { //onLogoutCallback() will set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen.
|
|
||||||
document.location.reload(); //when onLogoutCallback() returns true, reload the current document.
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
if(onLogoutCallback()) { //onLogoutCallback() will set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen.
|
|
||||||
document.location.reload(); //when onLogoutCallback() returns true, reload the current document.
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeSend : function(XMLHttpResponse) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Show cloudStack main UI widget
|
|
||||||
complete: function(args) {
|
|
||||||
var context = {
|
|
||||||
users: [args.user]
|
|
||||||
};
|
|
||||||
var cloudStackArgs = $.extend(cloudStack, {
|
|
||||||
context: context
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check to invoke install wizard
|
|
||||||
cloudStack.installWizard.check({
|
|
||||||
context: context,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
if (args.doInstall && isAdmin()) {
|
|
||||||
var initInstallWizard = function() {
|
|
||||||
cloudStack.uiCustom.installWizard({
|
|
||||||
$container: $container,
|
|
||||||
context: context,
|
|
||||||
complete: function() {
|
|
||||||
// Show cloudStack main UI
|
|
||||||
$container.cloudStack($.extend(cloudStackArgs, { hasLogo: false }));
|
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
havingSwift = false;
|
||||||
|
havingS3 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return userValid ? {
|
||||||
|
user: {
|
||||||
|
userid: g_userid,
|
||||||
|
username: g_username,
|
||||||
|
account: g_account,
|
||||||
|
name: g_userfullname,
|
||||||
|
role: g_role,
|
||||||
|
domainid: g_domainid
|
||||||
|
}
|
||||||
|
} : false;
|
||||||
|
|
||||||
|
return testAddUser;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Actual login process, via form
|
||||||
|
loginAction: function(args) {
|
||||||
|
var array1 = [];
|
||||||
|
array1.push("&username=" + encodeURIComponent(args.data.username));
|
||||||
|
|
||||||
|
var password;
|
||||||
|
if (md5HashedLogin)
|
||||||
|
password = $.md5(args.data.password);
|
||||||
|
else
|
||||||
|
password = todb(args.data.password);
|
||||||
|
array1.push("&password=" + password);
|
||||||
|
|
||||||
|
var domain;
|
||||||
|
if (args.data.domain != null && args.data.domain.length > 0) {
|
||||||
|
if (args.data.domain.charAt(0) != "/")
|
||||||
|
domain = "/" + args.data.domain;
|
||||||
|
else
|
||||||
|
domain = args.data.domain;
|
||||||
|
array1.push("&domain=" + encodeURIComponent(domain));
|
||||||
|
} else {
|
||||||
|
array1.push("&domain=" + encodeURIComponent("/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var loginCmdText = array1.join("");
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
data: "command=login" + loginCmdText + "&response=json",
|
||||||
|
dataType: "json",
|
||||||
|
async: false,
|
||||||
|
success: function(json) {
|
||||||
|
var loginresponse = json.loginresponse;
|
||||||
|
|
||||||
|
g_mySession = $.cookie('JSESSIONID');
|
||||||
|
g_sessionKey = encodeURIComponent(loginresponse.sessionkey);
|
||||||
|
g_role = loginresponse.type;
|
||||||
|
g_username = loginresponse.username;
|
||||||
|
g_userid = loginresponse.userid;
|
||||||
|
g_account = loginresponse.account;
|
||||||
|
g_domainid = loginresponse.domainid;
|
||||||
|
g_timezone = loginresponse.timezone;
|
||||||
|
g_timezoneoffset = loginresponse.timezoneoffset;
|
||||||
|
g_userfullname = loginresponse.firstname + ' ' + loginresponse.lastname;
|
||||||
|
|
||||||
|
$.cookie('sessionKey', g_sessionKey, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
$.cookie('username', g_username, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
$.cookie('account', g_account, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
$.cookie('domainid', g_domainid, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
$.cookie('role', g_role, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
$.cookie('timezoneoffset', g_timezoneoffset, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
$.cookie('timezone', g_timezone, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
$.cookie('userfullname', g_userfullname, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
$.cookie('userid', g_userid, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("listCapabilities"),
|
||||||
|
dataType: "json",
|
||||||
|
async: false,
|
||||||
|
success: function(json) {
|
||||||
|
g_capabilities = json.listcapabilitiesresponse.capability;
|
||||||
|
$.cookie('capabilities', g_capabilities, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean
|
||||||
|
$.cookie('supportELB', g_supportELB, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
if (json.listcapabilitiesresponse.capability.userpublictemplateenabled != null) {
|
||||||
|
g_userPublicTemplateEnabled = json.listcapabilitiesresponse.capability.userpublictemplateenabled.toString(); //convert boolean to string if it's boolean
|
||||||
|
$.cookie('userpublictemplateenabled', g_userPublicTemplateEnabled, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;
|
||||||
|
$.cookie('userProjectsEnabled', g_userProjectsEnabled, {
|
||||||
|
expires: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion;
|
||||||
|
|
||||||
|
if (json.listcapabilitiesresponse.capability.apilimitinterval != null && json.listcapabilitiesresponse.capability.apilimitmax != null) {
|
||||||
|
var intervalLimit = ((json.listcapabilitiesresponse.capability.apilimitinterval * 1000) / json.listcapabilitiesresponse.capability.apilimitmax) * 3; //multiply 3 to be on safe side
|
||||||
|
//intervalLimit = 8888; //this line is for testing only, comment it before check in
|
||||||
|
if (intervalLimit > g_queryAsyncJobResultInterval)
|
||||||
|
g_queryAsyncJobResultInterval = intervalLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.response.success({
|
||||||
|
data: {
|
||||||
|
user: $.extend(true, {}, loginresponse, {
|
||||||
|
name: loginresponse.firstname + ' ' + loginresponse.lastname,
|
||||||
|
role: loginresponse.type == 1 ? 'admin' : 'user',
|
||||||
|
type: loginresponse.type
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(xmlHTTP) {
|
||||||
|
args.response.error();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isAdmin()) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("listImageStores"),
|
||||||
|
data: {
|
||||||
|
provider: 'Swift'
|
||||||
|
},
|
||||||
|
async: false,
|
||||||
|
success: function(json) {
|
||||||
|
var items = json.listimagestoreresponse.imagestore;
|
||||||
|
if (items != null && items.length > 0)
|
||||||
|
havingSwift = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (havingSwift = false) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("listImageStores"),
|
||||||
|
data: {
|
||||||
|
provider: 'S3'
|
||||||
|
},
|
||||||
|
async: false,
|
||||||
|
success: function(json) {
|
||||||
|
var items = json.listimagestoreresponse.imagestore;
|
||||||
|
if (items != null && items.length > 0) {
|
||||||
|
havingS3 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
havingSwift = false;
|
||||||
|
havingS3 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get project configuration
|
||||||
|
// TEMPORARY -- replace w/ output of capability response, etc., once implemented
|
||||||
|
window.g_projectsInviteRequired = false;
|
||||||
|
},
|
||||||
|
error: function(XMLHttpRequest) {
|
||||||
|
var errorMsg = parseXMLHttpResponse(XMLHttpRequest);
|
||||||
|
if (errorMsg.length == 0 && XMLHttpRequest.status == 0)
|
||||||
|
errorMsg = dictionary['error.unable.to.reach.management.server'];
|
||||||
|
else
|
||||||
|
errorMsg = _l('error.invalid.username.password'); //override error message
|
||||||
|
args.response.error(errorMsg);
|
||||||
|
},
|
||||||
|
beforeSend: function(XMLHttpResponse) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
logoutAction: function(args) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('logout'),
|
||||||
|
async: false,
|
||||||
|
success: function() {
|
||||||
|
g_mySession = null;
|
||||||
|
g_sessionKey = null;
|
||||||
|
g_username = null;
|
||||||
|
g_account = null;
|
||||||
|
g_domainid = null;
|
||||||
|
g_timezoneoffset = null;
|
||||||
|
g_timezone = null;
|
||||||
|
g_supportELB = null;
|
||||||
|
g_loginCmdText = null;
|
||||||
|
|
||||||
|
$.cookie('JSESSIONID', null);
|
||||||
|
$.cookie('sessionKey', null);
|
||||||
|
$.cookie('username', null);
|
||||||
|
$.cookie('account', null);
|
||||||
|
$.cookie('domainid', null);
|
||||||
|
$.cookie('role', null);
|
||||||
|
$.cookie('networktype', null);
|
||||||
|
$.cookie('timezoneoffset', null);
|
||||||
|
$.cookie('timezone', null);
|
||||||
|
$.cookie('supportELB', null);
|
||||||
|
|
||||||
|
if (onLogoutCallback()) { //onLogoutCallback() will set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen.
|
||||||
|
document.location.reload(); //when onLogoutCallback() returns true, reload the current document.
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
if (onLogoutCallback()) { //onLogoutCallback() will set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen.
|
||||||
|
document.location.reload(); //when onLogoutCallback() returns true, reload the current document.
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeSend: function(XMLHttpResponse) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Show cloudStack main UI widget
|
||||||
|
complete: function(args) {
|
||||||
|
var context = {
|
||||||
|
users: [args.user]
|
||||||
};
|
};
|
||||||
|
var cloudStackArgs = $.extend(cloudStack, {
|
||||||
|
context: context
|
||||||
|
});
|
||||||
|
|
||||||
initInstallWizard();
|
// Check to invoke install wizard
|
||||||
} else {
|
cloudStack.installWizard.check({
|
||||||
// Show cloudStack main UI
|
context: context,
|
||||||
$container.cloudStack($.extend(cloudStackArgs, { hasLogo: false }));
|
response: {
|
||||||
}
|
success: function(args) {
|
||||||
|
if (args.doInstall && isAdmin()) {
|
||||||
|
var initInstallWizard = function() {
|
||||||
|
cloudStack.uiCustom.installWizard({
|
||||||
|
$container: $container,
|
||||||
|
context: context,
|
||||||
|
complete: function() {
|
||||||
|
// Show cloudStack main UI
|
||||||
|
$container.cloudStack($.extend(cloudStackArgs, {
|
||||||
|
hasLogo: false
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
initInstallWizard();
|
||||||
|
} else {
|
||||||
|
// Show cloudStack main UI
|
||||||
|
$container.cloudStack($.extend(cloudStackArgs, {
|
||||||
|
hasLogo: false
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Logout action
|
||||||
|
$('#user-options a').live('click', function() {
|
||||||
|
loginArgs.logoutAction({
|
||||||
|
context: cloudStack.context
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window._reloadUI = function() {
|
||||||
|
$('#container').html('');
|
||||||
|
$('#container').cloudStack(window.cloudStack);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Logout action
|
|
||||||
$('#user-options a').live('click', function() {
|
|
||||||
loginArgs.logoutAction({
|
|
||||||
context: cloudStack.context
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
window._reloadUI = function() {
|
|
||||||
$('#container').html('');
|
|
||||||
$('#container').cloudStack(window.cloudStack);
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($.urlParam('loginUrl') != 0) {
|
if ($.urlParam('loginUrl') != 0) {
|
||||||
// SSO
|
// SSO
|
||||||
loginArgs.hideLoginScreen = true;
|
loginArgs.hideLoginScreen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cloudStack.uiCustom.login(loginArgs);
|
cloudStack.uiCustom.login(loginArgs);
|
||||||
|
|
||||||
// Localization
|
// Localization
|
||||||
if (!$.isFunction(cloudStack.localizationFn)) { // i.e., localize is overridden by a plugin/module
|
if (!$.isFunction(cloudStack.localizationFn)) { // i.e., localize is overridden by a plugin/module
|
||||||
cloudStack.localizationFn = function(str) {
|
cloudStack.localizationFn = function(str) {
|
||||||
return dictionary[str];
|
return dictionary[str];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
document.title = _l('label.app.name');
|
document.title = _l('label.app.name');
|
||||||
});
|
});
|
||||||
})(cloudStack, jQuery);
|
})(cloudStack, jQuery);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -15,249 +15,245 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
// Admin dashboard
|
|
||||||
cloudStack.sections.dashboard = {
|
|
||||||
title: 'label.menu.dashboard',
|
|
||||||
show: cloudStack.uiCustom.dashboard,
|
|
||||||
|
|
||||||
adminCheck: function(args) {
|
|
||||||
return isAdmin() ? true : false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// User dashboard
|
|
||||||
user: {
|
|
||||||
dataProvider: function(args) {
|
|
||||||
var dataFns = {
|
|
||||||
instances: function(data) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listVirtualMachines'),
|
|
||||||
data: {
|
|
||||||
listAll: true
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var instances = json.listvirtualmachinesresponse.virtualmachine ?
|
|
||||||
json.listvirtualmachinesresponse.virtualmachine : [];
|
|
||||||
|
|
||||||
dataFns.account($.extend(data, {
|
|
||||||
runningInstances: $.grep(instances, function(instance) {
|
|
||||||
return instance.state == 'Running';
|
|
||||||
}).length,
|
|
||||||
stoppedInstances: $.grep(instances, function(instance) {
|
|
||||||
return instance.state == 'Stopped';
|
|
||||||
}).length,
|
|
||||||
totalInstances: instances.length
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
account: function(data) {
|
|
||||||
var user = cloudStack.context.users[0];
|
|
||||||
dataFns.events($.extend(data, {
|
|
||||||
accountID: user.userid,
|
|
||||||
accountName: user.account,
|
|
||||||
userName: user.username,
|
|
||||||
accountType: user.role,
|
|
||||||
accountDomainID: user.domainid
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
events: function(data) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listEvents'),
|
|
||||||
data: {
|
|
||||||
listAll: true,
|
|
||||||
page: 1,
|
|
||||||
pageSize: 4
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
dataFns.ipAddresses($.extend(data, {
|
|
||||||
events: json.listeventsresponse.event ?
|
|
||||||
json.listeventsresponse.event : []
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
ipAddresses: function(data) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listNetworks'),
|
|
||||||
data: {
|
|
||||||
listAll: true,
|
|
||||||
type: 'isolated',
|
|
||||||
supportedServices: 'SourceNat'
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var netTotal = json.listnetworksresponse.count ?
|
|
||||||
json.listnetworksresponse.count : 0;
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listPublicIpAddresses'),
|
|
||||||
success: function(json) {
|
|
||||||
var ipTotal = json.listpublicipaddressesresponse.count ?
|
|
||||||
json.listpublicipaddressesresponse.count : 0;
|
|
||||||
|
|
||||||
complete($.extend(data, {
|
|
||||||
netTotal: netTotal,
|
|
||||||
ipTotal: ipTotal
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var complete = function(data) {
|
|
||||||
args.response.success({
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
dataFns.instances({});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Admin dashboard
|
// Admin dashboard
|
||||||
admin: {
|
cloudStack.sections.dashboard = {
|
||||||
zoneDetailView: {
|
title: 'label.menu.dashboard',
|
||||||
tabs: {
|
show: cloudStack.uiCustom.dashboard,
|
||||||
resources: {
|
|
||||||
title: 'label.resources',
|
adminCheck: function(args) {
|
||||||
custom: cloudStack.uiCustom.systemChart('resources')
|
return isAdmin() ? true : false;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// User dashboard
|
||||||
|
user: {
|
||||||
|
dataProvider: function(args) {
|
||||||
|
var dataFns = {
|
||||||
|
instances: function(data) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listVirtualMachines'),
|
||||||
|
data: {
|
||||||
|
listAll: true
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var instances = json.listvirtualmachinesresponse.virtualmachine ?
|
||||||
|
json.listvirtualmachinesresponse.virtualmachine : [];
|
||||||
|
|
||||||
|
dataFns.account($.extend(data, {
|
||||||
|
runningInstances: $.grep(instances, function(instance) {
|
||||||
|
return instance.state == 'Running';
|
||||||
|
}).length,
|
||||||
|
stoppedInstances: $.grep(instances, function(instance) {
|
||||||
|
return instance.state == 'Stopped';
|
||||||
|
}).length,
|
||||||
|
totalInstances: instances.length
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
account: function(data) {
|
||||||
|
var user = cloudStack.context.users[0];
|
||||||
|
dataFns.events($.extend(data, {
|
||||||
|
accountID: user.userid,
|
||||||
|
accountName: user.account,
|
||||||
|
userName: user.username,
|
||||||
|
accountType: user.role,
|
||||||
|
accountDomainID: user.domainid
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
events: function(data) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listEvents'),
|
||||||
|
data: {
|
||||||
|
listAll: true,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 4
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
dataFns.ipAddresses($.extend(data, {
|
||||||
|
events: json.listeventsresponse.event ? json.listeventsresponse.event : []
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
ipAddresses: function(data) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listNetworks'),
|
||||||
|
data: {
|
||||||
|
listAll: true,
|
||||||
|
type: 'isolated',
|
||||||
|
supportedServices: 'SourceNat'
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var netTotal = json.listnetworksresponse.count ?
|
||||||
|
json.listnetworksresponse.count : 0;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listPublicIpAddresses'),
|
||||||
|
success: function(json) {
|
||||||
|
var ipTotal = json.listpublicipaddressesresponse.count ?
|
||||||
|
json.listpublicipaddressesresponse.count : 0;
|
||||||
|
|
||||||
|
complete($.extend(data, {
|
||||||
|
netTotal: netTotal,
|
||||||
|
ipTotal: ipTotal
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var complete = function(data) {
|
||||||
|
args.response.success({
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
dataFns.instances({});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Admin dashboard
|
||||||
|
admin: {
|
||||||
|
zoneDetailView: {
|
||||||
|
tabs: {
|
||||||
|
resources: {
|
||||||
|
title: 'label.resources',
|
||||||
|
custom: cloudStack.uiCustom.systemChart('resources')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dataProvider: function(args) {
|
||||||
|
var dataFns = {
|
||||||
|
zones: function(data) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listZones'),
|
||||||
|
success: function(json) {
|
||||||
|
dataFns.capacity({
|
||||||
|
zones: json.listzonesresponse.zone
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
capacity: function(data) {
|
||||||
|
var latestData = null;
|
||||||
|
if (window.fetchLatestflag == 1) {
|
||||||
|
latestData = {
|
||||||
|
|
||||||
|
fetchLatest: true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
latestData = {
|
||||||
|
fetchLatest: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.fetchLatestflag = 0;
|
||||||
|
|
||||||
|
dataFns.alerts(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
alerts: function(data) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listAlerts'),
|
||||||
|
data: {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 4
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var alerts = json.listalertsresponse.alert ?
|
||||||
|
json.listalertsresponse.alert : [];
|
||||||
|
|
||||||
|
dataFns.hostAlerts($.extend(data, {
|
||||||
|
alerts: $.map(alerts, function(alert) {
|
||||||
|
return {
|
||||||
|
name: cloudStack.converters.toAlertType(alert.type),
|
||||||
|
description: alert.description,
|
||||||
|
sent: cloudStack.converters.toLocalDate(alert.sent)
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
hostAlerts: function(data) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listHosts'),
|
||||||
|
data: {
|
||||||
|
state: 'Alert',
|
||||||
|
page: 1,
|
||||||
|
pageSize: 4
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var hosts = json.listhostsresponse.host ?
|
||||||
|
json.listhostsresponse.host : [];
|
||||||
|
|
||||||
|
dataFns.zoneCapacity($.extend(data, {
|
||||||
|
hostAlerts: $.map(hosts, function(host) {
|
||||||
|
return {
|
||||||
|
name: host.name,
|
||||||
|
description: 'message.alert.state.detected'
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
zoneCapacity: function(data) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listCapacity'),
|
||||||
|
data: {
|
||||||
|
fetchLatest: false,
|
||||||
|
sortBy: 'usage',
|
||||||
|
page: 0,
|
||||||
|
pagesize: 8
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var capacities = json.listcapacityresponse.capacity ?
|
||||||
|
json.listcapacityresponse.capacity : [];
|
||||||
|
|
||||||
|
complete($.extend(data, {
|
||||||
|
zoneCapacities: $.map(capacities, function(capacity) {
|
||||||
|
if (capacity.podname) {
|
||||||
|
capacity.zonename = capacity.zonename.concat(', ' + _l('label.pod') + ': ' + capacity.podname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capacity.clustername) {
|
||||||
|
capacity.zonename = capacity.zonename.concat(', ' + _l('label.cluster') + ': ' + capacity.clustername);
|
||||||
|
}
|
||||||
|
|
||||||
|
capacity.zonename.replace('Zone:', _l('label.zone') + ':');
|
||||||
|
|
||||||
|
return {
|
||||||
|
zoneID: capacity.zoneid, // Temporary fix for dashboard
|
||||||
|
zoneName: capacity.zonename,
|
||||||
|
type: cloudStack.converters.toCapacityCountType(capacity.type),
|
||||||
|
percent: parseInt(capacity.percentused),
|
||||||
|
used: cloudStack.converters.convertByType(capacity.type, capacity.capacityused),
|
||||||
|
total: cloudStack.converters.convertByType(capacity.type, capacity.capacitytotal)
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var complete = function(data) {
|
||||||
|
args.response.success({
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
dataFns.zones({});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
dataProvider: function(args) {
|
|
||||||
var dataFns = {
|
|
||||||
zones: function(data) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listZones'),
|
|
||||||
success: function(json) {
|
|
||||||
dataFns.capacity({
|
|
||||||
zones: json.listzonesresponse.zone
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
capacity: function(data) {
|
|
||||||
var latestData =null;
|
|
||||||
if(window.fetchLatestflag == 1)
|
|
||||||
{
|
|
||||||
latestData = {
|
|
||||||
|
|
||||||
fetchLatest:true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
latestData = {
|
|
||||||
fetchLatest:false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.fetchLatestflag = 0;
|
|
||||||
|
|
||||||
dataFns.alerts(data);
|
|
||||||
},
|
|
||||||
|
|
||||||
alerts: function(data) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listAlerts'),
|
|
||||||
data: {
|
|
||||||
page: 1,
|
|
||||||
pageSize: 4
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var alerts = json.listalertsresponse.alert ?
|
|
||||||
json.listalertsresponse.alert : [];
|
|
||||||
|
|
||||||
dataFns.hostAlerts($.extend(data, {
|
|
||||||
alerts: $.map(alerts, function(alert) {
|
|
||||||
return {
|
|
||||||
name: cloudStack.converters.toAlertType(alert.type),
|
|
||||||
description: alert.description,
|
|
||||||
sent: cloudStack.converters.toLocalDate(alert.sent)
|
|
||||||
};
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
hostAlerts: function(data) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listHosts'),
|
|
||||||
data: {
|
|
||||||
state: 'Alert',
|
|
||||||
page: 1,
|
|
||||||
pageSize: 4
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var hosts = json.listhostsresponse.host ?
|
|
||||||
json.listhostsresponse.host : [];
|
|
||||||
|
|
||||||
dataFns.zoneCapacity($.extend(data, {
|
|
||||||
hostAlerts: $.map(hosts, function(host) {
|
|
||||||
return {
|
|
||||||
name: host.name,
|
|
||||||
description: 'message.alert.state.detected'
|
|
||||||
};
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
zoneCapacity: function(data) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listCapacity'),
|
|
||||||
data: {
|
|
||||||
fetchLatest: false,
|
|
||||||
sortBy: 'usage',
|
|
||||||
page: 0,
|
|
||||||
pagesize: 8
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var capacities = json.listcapacityresponse.capacity ?
|
|
||||||
json.listcapacityresponse.capacity : [];
|
|
||||||
|
|
||||||
complete($.extend(data, {
|
|
||||||
zoneCapacities: $.map(capacities, function(capacity) {
|
|
||||||
if (capacity.podname) {
|
|
||||||
capacity.zonename = capacity.zonename.concat(', ' + _l('label.pod') + ': ' + capacity.podname);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (capacity.clustername) {
|
|
||||||
capacity.zonename = capacity.zonename.concat(', ' + _l('label.cluster') + ': ' + capacity.clustername);
|
|
||||||
}
|
|
||||||
|
|
||||||
capacity.zonename.replace('Zone:', _l('label.zone') + ':');
|
|
||||||
|
|
||||||
return {
|
|
||||||
zoneID: capacity.zoneid, // Temporary fix for dashboard
|
|
||||||
zoneName: capacity.zonename,
|
|
||||||
type: cloudStack.converters.toCapacityCountType(capacity.type),
|
|
||||||
percent: parseInt(capacity.percentused),
|
|
||||||
used: cloudStack.converters.convertByType(capacity.type, capacity.capacityused),
|
|
||||||
total: cloudStack.converters.convertByType(capacity.type, capacity.capacitytotal)
|
|
||||||
};
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var complete = function(data) {
|
|
||||||
args.response.success({
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
dataFns.zones({});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
2026
ui/scripts/docs.js
2026
ui/scripts/docs.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1026
ui/scripts/events.js
1026
ui/scripts/events.js
File diff suppressed because it is too large
Load Diff
@ -16,341 +16,428 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
(function(cloudStack) {
|
(function(cloudStack) {
|
||||||
cloudStack.sections['global-settings'] = {
|
cloudStack.sections['global-settings'] = {
|
||||||
title: 'label.menu.global.settings',
|
|
||||||
id: 'global-settings',
|
|
||||||
sectionSelect: {
|
|
||||||
label: 'label.select-view'
|
|
||||||
},
|
|
||||||
sections: {
|
|
||||||
globalSettings: {
|
|
||||||
type: 'select',
|
|
||||||
title: 'label.menu.global.settings',
|
title: 'label.menu.global.settings',
|
||||||
listView: {
|
id: 'global-settings',
|
||||||
label: 'label.menu.global.settings',
|
sectionSelect: {
|
||||||
actions: {
|
label: 'label.select-view'
|
||||||
edit: {
|
},
|
||||||
label: 'label.change.value',
|
sections: {
|
||||||
action: function(args) {
|
globalSettings: {
|
||||||
var data = {
|
type: 'select',
|
||||||
name: args.data.jsonObj.name,
|
title: 'label.menu.global.settings',
|
||||||
value: args.data.value
|
listView: {
|
||||||
};
|
label: 'label.menu.global.settings',
|
||||||
$.ajax({
|
actions: {
|
||||||
url: createURL('updateConfiguration'),
|
edit: {
|
||||||
data: data,
|
label: 'label.change.value',
|
||||||
success: function(json) {
|
action: function(args) {
|
||||||
var item = json.updateconfigurationresponse.configuration;
|
var data = {
|
||||||
if(item.category == "Usage")
|
name: args.data.jsonObj.name,
|
||||||
cloudStack.dialog.notice({ message: _l('message.restart.mgmt.usage.server') });
|
value: args.data.value
|
||||||
else
|
};
|
||||||
cloudStack.dialog.notice({ message: _l('message.restart.mgmt.server') });
|
$.ajax({
|
||||||
args.response.success({data: item});
|
url: createURL('updateConfiguration'),
|
||||||
},
|
data: data,
|
||||||
error: function(json) {
|
success: function(json) {
|
||||||
args.response.error(parseXMLHttpResponse(json));
|
var item = json.updateconfigurationresponse.configuration;
|
||||||
}
|
if (item.category == "Usage")
|
||||||
});
|
cloudStack.dialog.notice({
|
||||||
}
|
message: _l('message.restart.mgmt.usage.server')
|
||||||
}
|
});
|
||||||
},
|
else
|
||||||
fields: {
|
cloudStack.dialog.notice({
|
||||||
name: { label: 'label.name', id: true },
|
message: _l('message.restart.mgmt.server')
|
||||||
description: { label: 'label.description' },
|
});
|
||||||
value: { label: 'label.value', editable: true, truncate: true }
|
args.response.success({
|
||||||
},
|
data: item
|
||||||
dataProvider: function(args) {
|
});
|
||||||
var data = {
|
},
|
||||||
page: args.page,
|
error: function(json) {
|
||||||
pagesize: pageSize
|
args.response.error(parseXMLHttpResponse(json));
|
||||||
};
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
name: {
|
||||||
|
label: 'label.name',
|
||||||
|
id: true
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
label: 'label.description'
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
label: 'label.value',
|
||||||
|
editable: true,
|
||||||
|
truncate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataProvider: function(args) {
|
||||||
|
var data = {
|
||||||
|
page: args.page,
|
||||||
|
pagesize: pageSize
|
||||||
|
};
|
||||||
|
|
||||||
if (args.filterBy.search.value) {
|
if (args.filterBy.search.value) {
|
||||||
data.name = args.filterBy.search.value;
|
data.name = args.filterBy.search.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listConfigurations'),
|
|
||||||
data: data,
|
|
||||||
dataType: "json",
|
|
||||||
async: true,
|
|
||||||
success: function(json) {
|
|
||||||
var items = json.listconfigurationsresponse.configuration;
|
|
||||||
args.response.success({ data: items });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
ldapConfiguration:{
|
|
||||||
type:'select',
|
|
||||||
title:'LDAP Configuration',
|
|
||||||
listView:{
|
|
||||||
id:'ldap',
|
|
||||||
label:'LDAP Configuration',
|
|
||||||
fields:{
|
|
||||||
hostname: {label: 'Hostname'},
|
|
||||||
queryfilter: {label: 'Query Filter'},
|
|
||||||
searchbase: {label: 'Search Base'},
|
|
||||||
port: {label: 'LDAP Port'},
|
|
||||||
ssl: {
|
|
||||||
label: 'SSL'
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
dataProvider:function(args){
|
|
||||||
var data = {};
|
|
||||||
listViewDataProvider(args, data);
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('ldapConfig&listall=true'), //Need a list LDAP configuration API call which needs to be implemented
|
|
||||||
data: data,
|
|
||||||
success: function(json) {
|
|
||||||
var items = json.ldapconfigresponse.ldapconfig;
|
|
||||||
args.response.success({data:items});
|
|
||||||
},
|
|
||||||
error: function(data) {
|
|
||||||
args.response.error(parseXMLHttpResponse(data));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
detailView: {
|
|
||||||
name: 'label.details',
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
// Remove LDAP
|
|
||||||
remove: {
|
|
||||||
label: 'Remove LDAP',
|
|
||||||
messages: {
|
|
||||||
notification: function(args) {
|
|
||||||
return 'LDAP Configuration Deleted';
|
|
||||||
},
|
|
||||||
confirm: function() {
|
|
||||||
return 'Are you sure you want to delete the LDAP configuration?';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
action: function(args) {
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url:createURL("ldapRemove"),
|
|
||||||
success:function(json){
|
|
||||||
|
|
||||||
args.response.success();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
$(window).trigger('cloudStack.fullRefresh');
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listConfigurations'),
|
||||||
|
data: data,
|
||||||
|
dataType: "json",
|
||||||
|
async: true,
|
||||||
|
success: function(json) {
|
||||||
|
var items = json.listconfigurationsresponse.configuration;
|
||||||
|
args.response.success({
|
||||||
|
data: items
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
|
|
||||||
tabs:{
|
ldapConfiguration: {
|
||||||
|
type: 'select',
|
||||||
details: {
|
title: 'LDAP Configuration',
|
||||||
title: 'LDAP Configuration Details',
|
listView: {
|
||||||
fields: [
|
id: 'ldap',
|
||||||
{
|
label: 'LDAP Configuration',
|
||||||
hostname: { label: 'Hostname' },
|
fields: {
|
||||||
description: { label: 'label.description' },
|
hostname: {
|
||||||
ssl : { label: 'SSL'}
|
label: 'Hostname'
|
||||||
}
|
},
|
||||||
],
|
queryfilter: {
|
||||||
dataProvider: function(args) {
|
label: 'Query Filter'
|
||||||
$.ajax({
|
},
|
||||||
url: createURL("ldapConfig&listAll=true" ),
|
searchbase: {
|
||||||
dataType: "json",
|
label: 'Search Base'
|
||||||
async: true,
|
},
|
||||||
success: function(json) {
|
port: {
|
||||||
var item = json.ldapconfigresponse.ldapconfig;
|
label: 'LDAP Port'
|
||||||
args.response.success({data: item});
|
},
|
||||||
}
|
ssl: {
|
||||||
});
|
label: 'SSL'
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
add:{
|
|
||||||
|
|
||||||
label: 'Configure LDAP',
|
|
||||||
|
|
||||||
messages: {
|
|
||||||
confirm: function(args) {
|
|
||||||
return 'Do you really want to configure LDAP ? ';
|
|
||||||
},
|
|
||||||
notification: function(args) {
|
|
||||||
return 'LDAP configured';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
createForm: {
|
|
||||||
|
|
||||||
title: 'Configure LDAP',
|
|
||||||
fields:{
|
|
||||||
name:{label: 'Bind DN' , validation: {required:true} },
|
|
||||||
password: {label: 'Bind Password', validation: {required: true },isPassword:true },
|
|
||||||
hostname: {label:'Hostname' , validation:{required:true}},
|
|
||||||
queryfilter: {label:'Query Filter' , validation: {required:true} , docID:'helpLdapQueryFilter'},
|
|
||||||
searchbase: {label:'SearchBase',validation:{required:true}},
|
|
||||||
ssl: {
|
|
||||||
label:'SSL' ,
|
|
||||||
isBoolean:true,
|
|
||||||
isChecked:false
|
|
||||||
|
|
||||||
},
|
|
||||||
port: { label: 'Port' , defaultValue: '389' },
|
|
||||||
truststore:{ label:'Trust Store' , isHidden:true , dependsOn:'ssl',validation:{required:true} },
|
|
||||||
truststorepassword:{ label:'Trust Store Password' ,isHidden:true , dependsOn:'ssl', validation:{required:true}}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
action:function(args) {
|
|
||||||
var array = [];
|
|
||||||
array.push("&binddn=" + todb(args.data.name));
|
|
||||||
array.push("&bindpass=" + todb(args.data.password));
|
|
||||||
array.push("&hostname=" + todb(args.data.hostname));
|
|
||||||
array.push("&searchbase=" +todb(args.data.searchbase));
|
|
||||||
array.push("&queryfilter=" +todb(args.data.queryfilter));
|
|
||||||
array.push("&port=" +todb(args.data.port));
|
|
||||||
|
|
||||||
if(args.$form.find('.form-item[rel=ssl]').find('input[type=checkbox]').is(':Checked')== true) {
|
|
||||||
|
|
||||||
array.push("&ssl=true");
|
|
||||||
if(args.data.truststore != "")
|
|
||||||
array.push("&truststore=" +todb(args.data.truststore));
|
|
||||||
|
|
||||||
if(args.data.truststorepassword !="")
|
|
||||||
array.push("&truststorepass=" +todb(args.data.truststorepassword));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
|
||||||
array.push("&ssl=false");
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("ldapConfig" + array.join("")),
|
|
||||||
dataType: "json",
|
|
||||||
async: true,
|
|
||||||
success: function(json) {
|
|
||||||
var items = json.ldapconfigresponse.ldapconfig;
|
|
||||||
args.response.success({
|
|
||||||
data: items
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
error:function(json){
|
|
||||||
args.response.error(parseXMLHttpResponse(json));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
hypervisorCapabilities: {
|
|
||||||
type: 'select',
|
|
||||||
title: 'label.hypervisor.capabilities',
|
|
||||||
listView: {
|
|
||||||
id: 'hypervisorCapabilities',
|
|
||||||
label: 'label.hypervisor.capabilities',
|
|
||||||
fields: {
|
|
||||||
hypervisor: { label: 'label.hypervisor' },
|
|
||||||
hypervisorversion: { label: 'label.hypervisor.version' },
|
|
||||||
maxguestslimit: { label: 'label.max.guest.limit' }
|
|
||||||
},
|
|
||||||
dataProvider: function(args) {
|
|
||||||
var data = {};
|
|
||||||
listViewDataProvider(args, data);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listHypervisorCapabilities'),
|
|
||||||
data: data,
|
|
||||||
success: function(json) {
|
|
||||||
var items = json.listhypervisorcapabilitiesresponse.hypervisorCapabilities;
|
|
||||||
args.response.success({data:items});
|
|
||||||
},
|
|
||||||
error: function(data) {
|
|
||||||
args.response.error(parseXMLHttpResponse(data));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
detailView: {
|
|
||||||
name: 'label.details',
|
|
||||||
actions: {
|
|
||||||
edit: {
|
|
||||||
label: 'label.edit',
|
|
||||||
action: function(args) {
|
|
||||||
var data = {
|
|
||||||
id: args.context.hypervisorCapabilities[0].id,
|
|
||||||
maxguestslimit: args.data.maxguestslimit
|
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('updateHypervisorCapabilities'),
|
|
||||||
data: data,
|
|
||||||
success: function(json) {
|
|
||||||
var item = json.updatehypervisorcapabilitiesresponse['null'];
|
|
||||||
args.response.success({data: item});
|
|
||||||
},
|
},
|
||||||
error: function(data) {
|
dataProvider: function(args) {
|
||||||
args.response.error(parseXMLHttpResponse(data));
|
var data = {};
|
||||||
}
|
listViewDataProvider(args, data);
|
||||||
});
|
$.ajax({
|
||||||
}
|
url: createURL('ldapConfig&listall=true'), //Need a list LDAP configuration API call which needs to be implemented
|
||||||
}
|
data: data,
|
||||||
},
|
success: function(json) {
|
||||||
|
var items = json.ldapconfigresponse.ldapconfig;
|
||||||
|
args.response.success({
|
||||||
|
data: items
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(data) {
|
||||||
|
args.response.error(parseXMLHttpResponse(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
detailView: {
|
||||||
|
name: 'label.details',
|
||||||
|
actions: {
|
||||||
|
|
||||||
|
// Remove LDAP
|
||||||
|
remove: {
|
||||||
|
label: 'Remove LDAP',
|
||||||
|
messages: {
|
||||||
|
notification: function(args) {
|
||||||
|
return 'LDAP Configuration Deleted';
|
||||||
|
},
|
||||||
|
confirm: function() {
|
||||||
|
return 'Are you sure you want to delete the LDAP configuration?';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
action: function(args) {
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("ldapRemove"),
|
||||||
|
success: function(json) {
|
||||||
|
|
||||||
|
args.response.success();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
$(window).trigger('cloudStack.fullRefresh');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
tabs: {
|
||||||
|
|
||||||
|
details: {
|
||||||
|
title: 'LDAP Configuration Details',
|
||||||
|
fields: [{
|
||||||
|
hostname: {
|
||||||
|
label: 'Hostname'
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
label: 'label.description'
|
||||||
|
},
|
||||||
|
ssl: {
|
||||||
|
label: 'SSL'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
dataProvider: function(args) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("ldapConfig&listAll=true"),
|
||||||
|
dataType: "json",
|
||||||
|
async: true,
|
||||||
|
success: function(json) {
|
||||||
|
var item = json.ldapconfigresponse.ldapconfig;
|
||||||
|
args.response.success({
|
||||||
|
data: item
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
add: {
|
||||||
|
|
||||||
|
label: 'Configure LDAP',
|
||||||
|
|
||||||
|
messages: {
|
||||||
|
confirm: function(args) {
|
||||||
|
return 'Do you really want to configure LDAP ? ';
|
||||||
|
},
|
||||||
|
notification: function(args) {
|
||||||
|
return 'LDAP configured';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createForm: {
|
||||||
|
|
||||||
|
title: 'Configure LDAP',
|
||||||
|
fields: {
|
||||||
|
name: {
|
||||||
|
label: 'Bind DN',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
label: 'Bind Password',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isPassword: true
|
||||||
|
},
|
||||||
|
hostname: {
|
||||||
|
label: 'Hostname',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
queryfilter: {
|
||||||
|
label: 'Query Filter',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
docID: 'helpLdapQueryFilter'
|
||||||
|
},
|
||||||
|
searchbase: {
|
||||||
|
label: 'SearchBase',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ssl: {
|
||||||
|
label: 'SSL',
|
||||||
|
isBoolean: true,
|
||||||
|
isChecked: false
|
||||||
|
|
||||||
|
},
|
||||||
|
port: {
|
||||||
|
label: 'Port',
|
||||||
|
defaultValue: '389'
|
||||||
|
},
|
||||||
|
truststore: {
|
||||||
|
label: 'Trust Store',
|
||||||
|
isHidden: true,
|
||||||
|
dependsOn: 'ssl',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
truststorepassword: {
|
||||||
|
label: 'Trust Store Password',
|
||||||
|
isHidden: true,
|
||||||
|
dependsOn: 'ssl',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
action: function(args) {
|
||||||
|
var array = [];
|
||||||
|
array.push("&binddn=" + todb(args.data.name));
|
||||||
|
array.push("&bindpass=" + todb(args.data.password));
|
||||||
|
array.push("&hostname=" + todb(args.data.hostname));
|
||||||
|
array.push("&searchbase=" + todb(args.data.searchbase));
|
||||||
|
array.push("&queryfilter=" + todb(args.data.queryfilter));
|
||||||
|
array.push("&port=" + todb(args.data.port));
|
||||||
|
|
||||||
|
if (args.$form.find('.form-item[rel=ssl]').find('input[type=checkbox]').is(':Checked') == true) {
|
||||||
|
|
||||||
|
array.push("&ssl=true");
|
||||||
|
if (args.data.truststore != "")
|
||||||
|
array.push("&truststore=" + todb(args.data.truststore));
|
||||||
|
|
||||||
|
if (args.data.truststorepassword != "")
|
||||||
|
array.push("&truststorepass=" + todb(args.data.truststorepassword));
|
||||||
|
|
||||||
|
} else
|
||||||
|
array.push("&ssl=false");
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("ldapConfig" + array.join("")),
|
||||||
|
dataType: "json",
|
||||||
|
async: true,
|
||||||
|
success: function(json) {
|
||||||
|
var items = json.ldapconfigresponse.ldapconfig;
|
||||||
|
args.response.success({
|
||||||
|
data: items
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
error: function(json) {
|
||||||
|
args.response.error(parseXMLHttpResponse(json));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tabs: {
|
|
||||||
details: {
|
|
||||||
title: 'label.details',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
id: { label: 'label.id' },
|
|
||||||
hypervisor: { label: 'label.hypervisor' },
|
|
||||||
hypervisorversion: { label: 'label.hypervisor.version' },
|
|
||||||
maxguestslimit: {
|
|
||||||
label: 'label.max.guest.limit',
|
|
||||||
isEditable: true
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
],
|
|
||||||
dataProvider: function(args) {
|
|
||||||
args.response.success(
|
}
|
||||||
{
|
|
||||||
data:args.context.hypervisorCapabilities[0]
|
|
||||||
}
|
|
||||||
);
|
},
|
||||||
|
hypervisorCapabilities: {
|
||||||
|
type: 'select',
|
||||||
|
title: 'label.hypervisor.capabilities',
|
||||||
|
listView: {
|
||||||
|
id: 'hypervisorCapabilities',
|
||||||
|
label: 'label.hypervisor.capabilities',
|
||||||
|
fields: {
|
||||||
|
hypervisor: {
|
||||||
|
label: 'label.hypervisor'
|
||||||
|
},
|
||||||
|
hypervisorversion: {
|
||||||
|
label: 'label.hypervisor.version'
|
||||||
|
},
|
||||||
|
maxguestslimit: {
|
||||||
|
label: 'label.max.guest.limit'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataProvider: function(args) {
|
||||||
|
var data = {};
|
||||||
|
listViewDataProvider(args, data);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listHypervisorCapabilities'),
|
||||||
|
data: data,
|
||||||
|
success: function(json) {
|
||||||
|
var items = json.listhypervisorcapabilitiesresponse.hypervisorCapabilities;
|
||||||
|
args.response.success({
|
||||||
|
data: items
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(data) {
|
||||||
|
args.response.error(parseXMLHttpResponse(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
detailView: {
|
||||||
|
name: 'label.details',
|
||||||
|
actions: {
|
||||||
|
edit: {
|
||||||
|
label: 'label.edit',
|
||||||
|
action: function(args) {
|
||||||
|
var data = {
|
||||||
|
id: args.context.hypervisorCapabilities[0].id,
|
||||||
|
maxguestslimit: args.data.maxguestslimit
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('updateHypervisorCapabilities'),
|
||||||
|
data: data,
|
||||||
|
success: function(json) {
|
||||||
|
var item = json.updatehypervisorcapabilitiesresponse['null'];
|
||||||
|
args.response.success({
|
||||||
|
data: item
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(data) {
|
||||||
|
args.response.error(parseXMLHttpResponse(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
tabs: {
|
||||||
|
details: {
|
||||||
|
title: 'label.details',
|
||||||
|
fields: [{
|
||||||
|
id: {
|
||||||
|
label: 'label.id'
|
||||||
|
},
|
||||||
|
hypervisor: {
|
||||||
|
label: 'label.hypervisor'
|
||||||
|
},
|
||||||
|
hypervisorversion: {
|
||||||
|
label: 'label.hypervisor.version'
|
||||||
|
},
|
||||||
|
maxguestslimit: {
|
||||||
|
label: 'label.max.guest.limit',
|
||||||
|
isEditable: true
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
dataProvider: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
data: args.context.hypervisorCapabilities[0]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
})(cloudStack);
|
})(cloudStack);
|
||||||
|
|||||||
@ -15,342 +15,344 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.installWizard = {
|
cloudStack.installWizard = {
|
||||||
// Check if install wizard should be invoked
|
// Check if install wizard should be invoked
|
||||||
check: function(args) {
|
check: function(args) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: createURL('listZones'),
|
url: createURL('listZones'),
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
async: true,
|
async: true,
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
args.response.success({
|
args.response.success({
|
||||||
doInstall: !data.listzonesresponse.zone
|
doInstall: !data.listzonesresponse.zone
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
changeUser: function(args) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('updateUser'),
|
|
||||||
data: {
|
|
||||||
id: cloudStack.context.users[0].userid,
|
|
||||||
password: md5Hashed ? $.md5(args.data.password) : todb(args.data.password)
|
|
||||||
},
|
|
||||||
dataType: 'json',
|
|
||||||
async: true,
|
|
||||||
success: function(data) {
|
|
||||||
args.response.success({
|
|
||||||
data: { newUser: data.updateuserresponse.user }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Copy text
|
|
||||||
copy: {
|
|
||||||
// Tooltips
|
|
||||||
'tooltip.addZone.name': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addZone.name'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addZone.ip4dns1': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addZone.dns1'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addZone.ip4dns2': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addZone.dns2'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addZone.internaldns1': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addZone.internaldns1'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addZone.internaldns2': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addZone.internaldns2'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.configureGuestTraffic.name': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.configureGuestTraffic.name'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.configureGuestTraffic.description': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.configureGuestTraffic.description'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.configureGuestTraffic.guestGateway': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.configureGuestTraffic.guestGateway'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.configureGuestTraffic.guestNetmask': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.configureGuestTraffic.guestNetmask'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.configureGuestTraffic.guestStartIp': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.configureGuestTraffic.guestStartIp'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.configureGuestTraffic.guestEndIp': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.configureGuestTraffic.guestEndIp'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addPod.name': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addPod.name'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addPod.reservedSystemGateway': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addPod.reservedSystemGateway'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addPod.reservedSystemNetmask': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addPod.reservedSystemNetmask'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addPod.reservedSystemStartIp': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addPod.reservedSystemStartIp'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addPod.reservedSystemEndIp': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addPod.reservedSystemEndIp'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addCluster.name': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addCluster.name'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addHost.hostname': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addHost.hostname'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addHost.username': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addHost.username'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addHost.password': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addHost.password'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addPrimaryStorage.name': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addPrimaryStorage.name'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addPrimaryStorage.server': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addPrimaryStorage.server'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addPrimaryStorage.path': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addPrimaryStorage.path'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addSecondaryStorage.nfsServer': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addSecondaryStorage.nfsServer'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'tooltip.addSecondaryStorage.path': function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.tooltip.addSecondaryStorage.path'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Intro text
|
|
||||||
whatIsCloudStack: function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.copy.whatIsCloudStack'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
whatIsAZone: function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.copy.whatIsAZone'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
whatIsAPod: function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.copy.whatIsAPod'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
whatIsACluster: function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.copy.whatIsACluster'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
whatIsAHost: function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.copy.whatIsAHost'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
whatIsPrimaryStorage: function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.copy.whatIsPrimaryStorage'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
whatIsSecondaryStorage: function(args) {
|
|
||||||
args.response.success({
|
|
||||||
text: 'message.installWizard.copy.whatIsSecondaryStorage'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
action: function(args) {
|
|
||||||
var success = args.response.success;
|
|
||||||
var message = args.response.message;
|
|
||||||
|
|
||||||
// Get default network offering
|
|
||||||
var selectedNetworkOffering;
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("listNetworkOfferings&state=Enabled&guestiptype=Shared"),
|
|
||||||
dataType: "json",
|
|
||||||
async: false,
|
|
||||||
success: function(json) {
|
|
||||||
selectedNetworkOffering = $.grep(
|
|
||||||
json.listnetworkofferingsresponse.networkoffering,
|
|
||||||
function(networkOffering) {
|
|
||||||
var services = $.map(networkOffering.service, function(service) {
|
|
||||||
return service.name;
|
|
||||||
});
|
|
||||||
|
|
||||||
//pick the network offering including SecurityGroup, but excluding Lb and StaticNat. (bug 13665)
|
|
||||||
return (($.inArray('SecurityGroup', services) != -1) && ($.inArray('Lb', services) == -1) && ($.inArray('StaticNat', services) == -1)) ;
|
|
||||||
}
|
|
||||||
)[0];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cloudStack.zoneWizard.action($.extend(true, {}, args, {
|
|
||||||
// Plug in hard-coded values specific to quick install
|
|
||||||
data: {
|
|
||||||
zone: {
|
|
||||||
networkType: 'Basic',
|
|
||||||
networkOfferingId: selectedNetworkOffering.id
|
|
||||||
},
|
|
||||||
pluginFrom: {
|
|
||||||
name: 'installWizard',
|
|
||||||
selectedNetworkOffering: selectedNetworkOffering,
|
|
||||||
selectedNetworkOfferingHavingSG: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
var enableZone = function() {
|
|
||||||
message('Enabling zone...');
|
|
||||||
cloudStack.zoneWizard.enableZoneAction({
|
|
||||||
data: args.data,
|
|
||||||
formData: args.data,
|
|
||||||
launchData: args.data,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
pollSystemVMs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var pollSystemVMs = function() {
|
|
||||||
// Poll System VMs, then enable zone
|
|
||||||
message('Creating system VMs (this may take a while)');
|
|
||||||
var poll = setInterval(function() {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listSystemVms'),
|
|
||||||
success: function(data) {
|
|
||||||
var systemVMs = data.listsystemvmsresponse.systemvm;
|
|
||||||
|
|
||||||
if (systemVMs && systemVMs.length > 1) {
|
|
||||||
if (systemVMs.length == $.grep(systemVMs, function(vm) {
|
|
||||||
return vm.state == 'Running';
|
|
||||||
}).length) {
|
|
||||||
clearInterval(poll);
|
|
||||||
message('System VMs ready.');
|
|
||||||
setTimeout(pollBuiltinTemplates, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Wait for builtin template to be present -- otherwise VMs cannot launch
|
|
||||||
var pollBuiltinTemplates = function() {
|
|
||||||
message('Waiting for builtin templates to load...');
|
|
||||||
var poll = setInterval(function() {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('listTemplates'),
|
|
||||||
data: {
|
|
||||||
templatefilter: 'all'
|
|
||||||
},
|
|
||||||
success: function(data) {
|
|
||||||
var templates = data.listtemplatesresponse.template ?
|
|
||||||
data.listtemplatesresponse.template : [];
|
|
||||||
var builtinTemplates = $.grep(templates, function(template) {
|
|
||||||
return template.templatetype == 'BUILTIN';
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
if (builtinTemplates.length) {
|
changeUser: function(args) {
|
||||||
clearInterval(poll);
|
$.ajax({
|
||||||
message('Your CloudStack is ready!');
|
url: createURL('updateUser'),
|
||||||
setTimeout(success, 1000);
|
data: {
|
||||||
}
|
id: cloudStack.context.users[0].userid,
|
||||||
}
|
password: md5Hashed ? $.md5(args.data.password) : todb(args.data.password)
|
||||||
|
},
|
||||||
|
dataType: 'json',
|
||||||
|
async: true,
|
||||||
|
success: function(data) {
|
||||||
|
args.response.success({
|
||||||
|
data: {
|
||||||
|
newUser: data.updateuserresponse.user
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Copy text
|
||||||
|
copy: {
|
||||||
|
// Tooltips
|
||||||
|
'tooltip.addZone.name': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addZone.name'
|
||||||
});
|
});
|
||||||
}, 5000);
|
},
|
||||||
};
|
|
||||||
|
|
||||||
enableZone();
|
'tooltip.addZone.ip4dns1': function(args) {
|
||||||
}
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addZone.dns1'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addZone.ip4dns2': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addZone.dns2'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addZone.internaldns1': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addZone.internaldns1'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addZone.internaldns2': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addZone.internaldns2'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.configureGuestTraffic.name': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.configureGuestTraffic.name'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.configureGuestTraffic.description': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.configureGuestTraffic.description'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.configureGuestTraffic.guestGateway': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.configureGuestTraffic.guestGateway'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.configureGuestTraffic.guestNetmask': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.configureGuestTraffic.guestNetmask'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.configureGuestTraffic.guestStartIp': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.configureGuestTraffic.guestStartIp'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.configureGuestTraffic.guestEndIp': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.configureGuestTraffic.guestEndIp'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addPod.name': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addPod.name'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addPod.reservedSystemGateway': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addPod.reservedSystemGateway'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addPod.reservedSystemNetmask': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addPod.reservedSystemNetmask'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addPod.reservedSystemStartIp': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addPod.reservedSystemStartIp'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addPod.reservedSystemEndIp': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addPod.reservedSystemEndIp'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addCluster.name': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addCluster.name'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addHost.hostname': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addHost.hostname'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addHost.username': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addHost.username'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addHost.password': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addHost.password'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addPrimaryStorage.name': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addPrimaryStorage.name'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addPrimaryStorage.server': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addPrimaryStorage.server'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addPrimaryStorage.path': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addPrimaryStorage.path'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addSecondaryStorage.nfsServer': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addSecondaryStorage.nfsServer'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'tooltip.addSecondaryStorage.path': function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.tooltip.addSecondaryStorage.path'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Intro text
|
||||||
|
whatIsCloudStack: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.copy.whatIsCloudStack'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
whatIsAZone: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.copy.whatIsAZone'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
whatIsAPod: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.copy.whatIsAPod'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
whatIsACluster: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.copy.whatIsACluster'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
whatIsAHost: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.copy.whatIsAHost'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
whatIsPrimaryStorage: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.copy.whatIsPrimaryStorage'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
whatIsSecondaryStorage: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
text: 'message.installWizard.copy.whatIsSecondaryStorage'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
action: function(args) {
|
||||||
|
var success = args.response.success;
|
||||||
|
var message = args.response.message;
|
||||||
|
|
||||||
|
// Get default network offering
|
||||||
|
var selectedNetworkOffering;
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("listNetworkOfferings&state=Enabled&guestiptype=Shared"),
|
||||||
|
dataType: "json",
|
||||||
|
async: false,
|
||||||
|
success: function(json) {
|
||||||
|
selectedNetworkOffering = $.grep(
|
||||||
|
json.listnetworkofferingsresponse.networkoffering,
|
||||||
|
function(networkOffering) {
|
||||||
|
var services = $.map(networkOffering.service, function(service) {
|
||||||
|
return service.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
//pick the network offering including SecurityGroup, but excluding Lb and StaticNat. (bug 13665)
|
||||||
|
return (($.inArray('SecurityGroup', services) != -1) && ($.inArray('Lb', services) == -1) && ($.inArray('StaticNat', services) == -1));
|
||||||
|
}
|
||||||
|
)[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cloudStack.zoneWizard.action($.extend(true, {}, args, {
|
||||||
|
// Plug in hard-coded values specific to quick install
|
||||||
|
data: {
|
||||||
|
zone: {
|
||||||
|
networkType: 'Basic',
|
||||||
|
networkOfferingId: selectedNetworkOffering.id
|
||||||
|
},
|
||||||
|
pluginFrom: {
|
||||||
|
name: 'installWizard',
|
||||||
|
selectedNetworkOffering: selectedNetworkOffering,
|
||||||
|
selectedNetworkOfferingHavingSG: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
var enableZone = function() {
|
||||||
|
message('Enabling zone...');
|
||||||
|
cloudStack.zoneWizard.enableZoneAction({
|
||||||
|
data: args.data,
|
||||||
|
formData: args.data,
|
||||||
|
launchData: args.data,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
pollSystemVMs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var pollSystemVMs = function() {
|
||||||
|
// Poll System VMs, then enable zone
|
||||||
|
message('Creating system VMs (this may take a while)');
|
||||||
|
var poll = setInterval(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listSystemVms'),
|
||||||
|
success: function(data) {
|
||||||
|
var systemVMs = data.listsystemvmsresponse.systemvm;
|
||||||
|
|
||||||
|
if (systemVMs && systemVMs.length > 1) {
|
||||||
|
if (systemVMs.length == $.grep(systemVMs, function(vm) {
|
||||||
|
return vm.state == 'Running';
|
||||||
|
}).length) {
|
||||||
|
clearInterval(poll);
|
||||||
|
message('System VMs ready.');
|
||||||
|
setTimeout(pollBuiltinTemplates, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wait for builtin template to be present -- otherwise VMs cannot launch
|
||||||
|
var pollBuiltinTemplates = function() {
|
||||||
|
message('Waiting for builtin templates to load...');
|
||||||
|
var poll = setInterval(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('listTemplates'),
|
||||||
|
data: {
|
||||||
|
templatefilter: 'all'
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
var templates = data.listtemplatesresponse.template ?
|
||||||
|
data.listtemplatesresponse.template : [];
|
||||||
|
var builtinTemplates = $.grep(templates, function(template) {
|
||||||
|
return template.templatetype == 'BUILTIN';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (builtinTemplates.length) {
|
||||||
|
clearInterval(poll);
|
||||||
|
message('Your CloudStack is ready!');
|
||||||
|
setTimeout(success, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
enableZone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}));
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -16,292 +16,304 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.lbStickyPolicy = {
|
cloudStack.lbStickyPolicy = {
|
||||||
dialog: function(args) {
|
dialog: function(args) {
|
||||||
return function(args) {
|
return function(args) {
|
||||||
var success = args.response.success;
|
var success = args.response.success;
|
||||||
var context = args.context;
|
var context = args.context;
|
||||||
|
|
||||||
var network;
|
var network;
|
||||||
if('vpc' in args.context) { //from VPC section
|
if ('vpc' in args.context) { //from VPC section
|
||||||
var data = {
|
var data = {
|
||||||
listAll: true,
|
listAll: true,
|
||||||
supportedservices: 'Lb'
|
supportedservices: 'Lb'
|
||||||
};
|
};
|
||||||
if(args.context.ipAddresses[0].associatednetworkid == null) {
|
if (args.context.ipAddresses[0].associatednetworkid == null) {
|
||||||
$.extend(data, {
|
$.extend(data, {
|
||||||
vpcid: args.context.vpc[0].id
|
vpcid: args.context.vpc[0].id
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
$.extend(data, {
|
||||||
$.extend(data, {
|
id: args.context.ipAddresses[0].associatednetworkid
|
||||||
id: args.context.ipAddresses[0].associatednetworkid
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: createURL("listNetworks"), //check whether the VPC has a network including Lb service
|
url: createURL("listNetworks"), //check whether the VPC has a network including Lb service
|
||||||
data: data,
|
data: data,
|
||||||
async: false,
|
async: false,
|
||||||
success: function(json) {
|
success: function(json) {
|
||||||
var items = json.listnetworksresponse.network;
|
var items = json.listnetworksresponse.network;
|
||||||
if(items != null && items.length > 0) {
|
if (items != null && items.length > 0) {
|
||||||
network = items[0];
|
network = items[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} else { //from Guest Network section
|
||||||
else { //from Guest Network section
|
network = args.context.networks[0];
|
||||||
network = args.context.networks[0];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var $item = args.$item;
|
var $item = args.$item;
|
||||||
|
|
||||||
var lbService = $.grep(network.service, function(service) {
|
var lbService = $.grep(network.service, function(service) {
|
||||||
return service.name == 'Lb';
|
return service.name == 'Lb';
|
||||||
})[0];
|
|
||||||
|
|
||||||
var stickinessCapabilities = JSON.parse($.grep(
|
|
||||||
lbService.capability,
|
|
||||||
function(capability) {
|
|
||||||
return capability.name == 'SupportedStickinessMethods';
|
|
||||||
}
|
|
||||||
)[0].value);
|
|
||||||
|
|
||||||
var baseFields = {
|
|
||||||
stickyName: { label: 'Sticky Name', validation: { required: true } }
|
|
||||||
};
|
|
||||||
|
|
||||||
$.map(
|
|
||||||
$.map(
|
|
||||||
stickinessCapabilities,
|
|
||||||
function(c) { return c.paramlist; }
|
|
||||||
),
|
|
||||||
function(p) {
|
|
||||||
baseFields[p.paramname] = {
|
|
||||||
label: _l('label.sticky.' + p.paramname),
|
|
||||||
isHidden: true,
|
|
||||||
isBoolean: p.isflag,
|
|
||||||
validation: { required: p.required }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
var conditionalFields = {
|
|
||||||
methodname: {
|
|
||||||
label: 'Stickiness method',
|
|
||||||
select: function(args) {
|
|
||||||
var $select = args.$select;
|
|
||||||
var $form = $select.closest('form');
|
|
||||||
var stickyOptions = [];
|
|
||||||
|
|
||||||
stickinessCapabilities.push({ methodname: 'None', paramlist: [] });
|
|
||||||
$(stickinessCapabilities).each(function() {
|
|
||||||
var stickyCapability = this;
|
|
||||||
|
|
||||||
stickyOptions.push({
|
|
||||||
id: stickyCapability.methodname,
|
|
||||||
description: stickyCapability.methodname
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
stickyOptions = stickyOptions.sort(function() {
|
|
||||||
return this.id != 'None';
|
|
||||||
});
|
|
||||||
|
|
||||||
args.response.success({
|
|
||||||
data: stickyOptions
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
$select.change(function() {
|
|
||||||
var value = $select.val();
|
|
||||||
var showFields = [];
|
|
||||||
var targetMethod = $.grep(stickinessCapabilities, function(stickyCapability) {
|
|
||||||
return stickyCapability.methodname == value;
|
|
||||||
})[0];
|
})[0];
|
||||||
var visibleParams = $.map(targetMethod.paramlist, function(param) {
|
|
||||||
return param.paramname;
|
|
||||||
});
|
|
||||||
|
|
||||||
$select.closest('.form-item').siblings('.form-item').each(function() {
|
var stickinessCapabilities = JSON.parse($.grep(
|
||||||
var $field = $(this);
|
lbService.capability,
|
||||||
var id = $field.attr('rel');
|
function(capability) {
|
||||||
|
return capability.name == 'SupportedStickinessMethods';
|
||||||
|
}
|
||||||
|
)[0].value);
|
||||||
|
|
||||||
if ($.inArray(id, visibleParams) > -1) {
|
var baseFields = {
|
||||||
$field.css('display', 'inline-block');
|
stickyName: {
|
||||||
$field.attr('sticky-method', value);
|
label: 'Sticky Name',
|
||||||
} else {
|
validation: {
|
||||||
$field.hide();
|
required: true
|
||||||
$field.attr('sticky-method', null);
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
// Name always is required
|
$.map(
|
||||||
if ($select.val() != 'None') {
|
$.map(
|
||||||
$select.closest('.form-item').siblings('.form-item[rel=stickyName]')
|
stickinessCapabilities,
|
||||||
.css('display', 'inline-block');
|
function(c) {
|
||||||
|
return c.paramlist;
|
||||||
|
}
|
||||||
|
),
|
||||||
|
function(p) {
|
||||||
|
baseFields[p.paramname] = {
|
||||||
|
label: _l('label.sticky.' + p.paramname),
|
||||||
|
isHidden: true,
|
||||||
|
isBoolean: p.isflag,
|
||||||
|
validation: {
|
||||||
|
required: p.required
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var conditionalFields = {
|
||||||
|
methodname: {
|
||||||
|
label: 'Stickiness method',
|
||||||
|
select: function(args) {
|
||||||
|
var $select = args.$select;
|
||||||
|
var $form = $select.closest('form');
|
||||||
|
var stickyOptions = [];
|
||||||
|
|
||||||
|
stickinessCapabilities.push({
|
||||||
|
methodname: 'None',
|
||||||
|
paramlist: []
|
||||||
|
});
|
||||||
|
$(stickinessCapabilities).each(function() {
|
||||||
|
var stickyCapability = this;
|
||||||
|
|
||||||
|
stickyOptions.push({
|
||||||
|
id: stickyCapability.methodname,
|
||||||
|
description: stickyCapability.methodname
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
stickyOptions = stickyOptions.sort(function() {
|
||||||
|
return this.id != 'None';
|
||||||
|
});
|
||||||
|
|
||||||
|
args.response.success({
|
||||||
|
data: stickyOptions
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
$select.change(function() {
|
||||||
|
var value = $select.val();
|
||||||
|
var showFields = [];
|
||||||
|
var targetMethod = $.grep(stickinessCapabilities, function(stickyCapability) {
|
||||||
|
return stickyCapability.methodname == value;
|
||||||
|
})[0];
|
||||||
|
var visibleParams = $.map(targetMethod.paramlist, function(param) {
|
||||||
|
return param.paramname;
|
||||||
|
});
|
||||||
|
|
||||||
|
$select.closest('.form-item').siblings('.form-item').each(function() {
|
||||||
|
var $field = $(this);
|
||||||
|
var id = $field.attr('rel');
|
||||||
|
|
||||||
|
if ($.inArray(id, visibleParams) > -1) {
|
||||||
|
$field.css('display', 'inline-block');
|
||||||
|
$field.attr('sticky-method', value);
|
||||||
|
} else {
|
||||||
|
$field.hide();
|
||||||
|
$field.attr('sticky-method', null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Name always is required
|
||||||
|
if ($select.val() != 'None') {
|
||||||
|
$select.closest('.form-item').siblings('.form-item[rel=stickyName]')
|
||||||
|
.css('display', 'inline-block');
|
||||||
|
}
|
||||||
|
|
||||||
|
$select.closest(':ui-dialog').dialog('option', 'position', 'center');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var fields = $.extend(conditionalFields, baseFields);
|
||||||
|
|
||||||
|
if (args.data) {
|
||||||
|
var populatedFields = $.map(fields, function(field, id) {
|
||||||
|
return id;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(populatedFields).each(function() {
|
||||||
|
var id = this;
|
||||||
|
var field = fields[id];
|
||||||
|
var dataItem = args.data[id];
|
||||||
|
|
||||||
|
if (field.isBoolean) {
|
||||||
|
field.isChecked = dataItem ? true : false;
|
||||||
|
} else {
|
||||||
|
field.defaultValue = dataItem;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$select.closest(':ui-dialog').dialog('option', 'position', 'center');
|
cloudStack.dialog.createForm({
|
||||||
});
|
form: {
|
||||||
}
|
title: 'Configure Sticky Policy',
|
||||||
}
|
desc: 'Please complete the following fields',
|
||||||
};
|
fields: fields
|
||||||
|
},
|
||||||
|
after: function(args) {
|
||||||
|
// Remove fields not applicable to sticky method
|
||||||
|
args.$form.find('.form-item:hidden').remove();
|
||||||
|
|
||||||
var fields = $.extend(conditionalFields, baseFields);
|
var data = cloudStack.serializeForm(args.$form);
|
||||||
|
|
||||||
if (args.data) {
|
/* $item indicates that this is an existing sticky rule;
|
||||||
var populatedFields = $.map(fields, function(field, id) {
|
|
||||||
return id;
|
|
||||||
});
|
|
||||||
|
|
||||||
$(populatedFields).each(function() {
|
|
||||||
var id = this;
|
|
||||||
var field = fields[id];
|
|
||||||
var dataItem = args.data[id];
|
|
||||||
|
|
||||||
if (field.isBoolean) {
|
|
||||||
field.isChecked = dataItem ? true : false;
|
|
||||||
} else {
|
|
||||||
field.defaultValue = dataItem;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cloudStack.dialog.createForm({
|
|
||||||
form: {
|
|
||||||
title: 'Configure Sticky Policy',
|
|
||||||
desc: 'Please complete the following fields',
|
|
||||||
fields: fields
|
|
||||||
},
|
|
||||||
after: function(args) {
|
|
||||||
// Remove fields not applicable to sticky method
|
|
||||||
args.$form.find('.form-item:hidden').remove();
|
|
||||||
|
|
||||||
var data = cloudStack.serializeForm(args.$form);
|
|
||||||
|
|
||||||
/* $item indicates that this is an existing sticky rule;
|
|
||||||
re-create sticky rule with new parameters */
|
re-create sticky rule with new parameters */
|
||||||
if ($item) {
|
if ($item) {
|
||||||
var $loading = $('<div>').addClass('loading-overlay');
|
var $loading = $('<div>').addClass('loading-overlay');
|
||||||
|
|
||||||
$loading.prependTo($item);
|
$loading.prependTo($item);
|
||||||
cloudStack.lbStickyPolicy.actions.recreate(
|
cloudStack.lbStickyPolicy.actions.recreate(
|
||||||
$item.data('multi-custom-data').id,
|
$item.data('multi-custom-data').id,
|
||||||
$item.data('multi-custom-data').lbRuleID,
|
$item.data('multi-custom-data').lbRuleID,
|
||||||
data,
|
data,
|
||||||
function() { // Complete
|
function() { // Complete
|
||||||
$(window).trigger('cloudStack.fullRefresh');
|
$(window).trigger('cloudStack.fullRefresh');
|
||||||
},
|
},
|
||||||
function(error) { // Error
|
function(error) { // Error
|
||||||
$(window).trigger('cloudStack.fullRefresh');
|
$(window).trigger('cloudStack.fullRefresh');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
success({
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
add: function(lbRuleID, data, complete, error) {
|
||||||
|
var stickyURLData = '';
|
||||||
|
var stickyParams = $.map(data, function(value, key) {
|
||||||
|
return key;
|
||||||
|
});
|
||||||
|
|
||||||
|
var notParams = ['methodname', 'stickyName'];
|
||||||
|
|
||||||
|
var index = 0;
|
||||||
|
$(stickyParams).each(function() {
|
||||||
|
var param = '¶m[' + index + ']';
|
||||||
|
var name = this.toString();
|
||||||
|
var value = data[name];
|
||||||
|
|
||||||
|
if (!value || $.inArray(name, notParams) > -1) return true;
|
||||||
|
if (value == 'on') value = true;
|
||||||
|
|
||||||
|
stickyURLData += param + '.name=' + name + param + '.value=' + value;
|
||||||
|
|
||||||
|
index++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('createLBStickinessPolicy' + stickyURLData),
|
||||||
|
data: {
|
||||||
|
lbruleid: lbRuleID,
|
||||||
|
name: data.stickyName,
|
||||||
|
methodname: data.methodname
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
cloudStack.ui.notifications.add({
|
||||||
|
desc: 'Add new LB sticky rule',
|
||||||
|
section: 'Network',
|
||||||
|
poll: pollAsyncJobResult,
|
||||||
|
_custom: {
|
||||||
|
jobId: json.createLBStickinessPolicy.jobid
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete, {},
|
||||||
|
error, {}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
error: function(json) {
|
||||||
|
complete();
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: parseXMLHttpResponse(json)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'delete': function(stickyRuleID, complete, error) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('deleteLBStickinessPolicy'),
|
||||||
|
data: {
|
||||||
|
id: stickyRuleID
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
cloudStack.ui.notifications.add({
|
||||||
|
desc: 'Remove previous LB sticky rule',
|
||||||
|
section: 'Network',
|
||||||
|
poll: pollAsyncJobResult,
|
||||||
|
_custom: {
|
||||||
|
jobId: json.deleteLBstickinessrruleresponse.jobid
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete, {},
|
||||||
|
error, {}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
error: function(json) {
|
||||||
|
complete();
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: parseXMLHttpResponse(json)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
recreate: function(stickyRuleID, lbRuleID, data, complete, error) {
|
||||||
|
var addStickyPolicy = function() {
|
||||||
|
cloudStack.lbStickyPolicy.actions.add(
|
||||||
|
lbRuleID,
|
||||||
|
data,
|
||||||
|
complete,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Delete existing rule
|
||||||
|
if (data.methodname !== 'None') {
|
||||||
|
addStickyPolicy();
|
||||||
|
} else {
|
||||||
|
cloudStack.lbStickyPolicy.actions['delete'](stickyRuleID, complete, error);
|
||||||
}
|
}
|
||||||
);
|
|
||||||
} else {
|
|
||||||
success({
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
add: function(lbRuleID, data, complete, error) {
|
|
||||||
var stickyURLData = '';
|
|
||||||
var stickyParams = $.map(data, function(value, key) {
|
|
||||||
return key;
|
|
||||||
});
|
|
||||||
|
|
||||||
var notParams = ['methodname', 'stickyName'];
|
|
||||||
|
|
||||||
var index = 0;
|
|
||||||
$(stickyParams).each(function() {
|
|
||||||
var param = '¶m[' + index + ']';
|
|
||||||
var name = this.toString();
|
|
||||||
var value = data[name];
|
|
||||||
|
|
||||||
if (!value || $.inArray(name, notParams) > -1) return true;
|
|
||||||
if (value == 'on') value = true;
|
|
||||||
|
|
||||||
stickyURLData += param + '.name=' + name + param + '.value=' + value;
|
|
||||||
|
|
||||||
index++;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('createLBStickinessPolicy' + stickyURLData),
|
|
||||||
data: {
|
|
||||||
lbruleid: lbRuleID,
|
|
||||||
name: data.stickyName,
|
|
||||||
methodname: data.methodname
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
cloudStack.ui.notifications.add(
|
|
||||||
{
|
|
||||||
desc: 'Add new LB sticky rule',
|
|
||||||
section: 'Network',
|
|
||||||
poll: pollAsyncJobResult,
|
|
||||||
_custom: {
|
|
||||||
jobId: json.createLBStickinessPolicy.jobid
|
|
||||||
}
|
|
||||||
},
|
|
||||||
complete, {},
|
|
||||||
error, {}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
error: function(json) {
|
|
||||||
complete();
|
|
||||||
cloudStack.dialog.notice({ message: parseXMLHttpResponse(json) });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'delete': function(stickyRuleID, complete, error) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('deleteLBStickinessPolicy'),
|
|
||||||
data: {
|
|
||||||
id: stickyRuleID
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
cloudStack.ui.notifications.add(
|
|
||||||
{
|
|
||||||
desc: 'Remove previous LB sticky rule',
|
|
||||||
section: 'Network',
|
|
||||||
poll: pollAsyncJobResult,
|
|
||||||
_custom: {
|
|
||||||
jobId: json.deleteLBstickinessrruleresponse.jobid
|
|
||||||
}
|
|
||||||
},
|
|
||||||
complete, {},
|
|
||||||
error, {}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
error: function(json) {
|
|
||||||
complete();
|
|
||||||
cloudStack.dialog.notice({ message: parseXMLHttpResponse(json) });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
recreate: function(stickyRuleID, lbRuleID, data, complete, error) {
|
|
||||||
var addStickyPolicy = function() {
|
|
||||||
cloudStack.lbStickyPolicy.actions.add(
|
|
||||||
lbRuleID,
|
|
||||||
data,
|
|
||||||
complete,
|
|
||||||
error
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delete existing rule
|
|
||||||
if (data.methodname !== 'None') {
|
|
||||||
addStickyPolicy();
|
|
||||||
} else {
|
|
||||||
cloudStack.lbStickyPolicy.actions['delete'](stickyRuleID, complete, error);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|||||||
10829
ui/scripts/network.js
10829
ui/scripts/network.js
File diff suppressed because it is too large
Load Diff
@ -15,100 +15,100 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack, require) {
|
(function($, cloudStack, require) {
|
||||||
if (!cloudStack.pluginAPI) {
|
if (!cloudStack.pluginAPI) {
|
||||||
cloudStack.pluginAPI = {};
|
cloudStack.pluginAPI = {};
|
||||||
}
|
|
||||||
|
|
||||||
var loadCSS = function(path) {
|
|
||||||
if (document.createStyleSheet) {
|
|
||||||
// IE-compatible CSS loading
|
|
||||||
document.createStyleSheet(path);
|
|
||||||
} else {
|
|
||||||
var $link = $('<link>');
|
|
||||||
|
|
||||||
$link.attr({
|
|
||||||
rel: 'stylesheet',
|
|
||||||
type: 'text/css',
|
|
||||||
href: path
|
|
||||||
});
|
|
||||||
|
|
||||||
$('html head').append($link);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
$.extend(cloudStack.pluginAPI, {
|
var loadCSS = function(path) {
|
||||||
ui: {
|
if (document.createStyleSheet) {
|
||||||
pollAsyncJob: pollAsyncJobResult,
|
// IE-compatible CSS loading
|
||||||
apiCall: function(command, args) {
|
document.createStyleSheet(path);
|
||||||
$.ajax({
|
} else {
|
||||||
url: createURL(command),
|
var $link = $('<link>');
|
||||||
data: args.data,
|
|
||||||
success: args.success,
|
|
||||||
error: function(json) {
|
|
||||||
args.error(parseXMLHttpResponse(json));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
addSection: function(section) {
|
|
||||||
cloudStack.sections[section.id] = $.extend(section, {
|
|
||||||
customIcon: 'plugins/' + section.id + '/icon.png'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
extend: function(obj) {
|
|
||||||
$.extend(true, cloudStack, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cloudStack.sections.plugins = {
|
$link.attr({
|
||||||
title: 'label.plugins',
|
rel: 'stylesheet',
|
||||||
show: cloudStack.uiCustom.pluginListing
|
type: 'text/css',
|
||||||
};
|
href: path
|
||||||
|
});
|
||||||
|
|
||||||
var loadedPlugins = 0;
|
$('html head').append($link);
|
||||||
var pluginTotal = cloudStack.plugins.length + cloudStack.modules.length;
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Load
|
$.extend(cloudStack.pluginAPI, {
|
||||||
$(['modules', 'plugins']).each(function() {
|
ui: {
|
||||||
var type = this;
|
pollAsyncJob: pollAsyncJobResult,
|
||||||
var paths = $(cloudStack[type]).map(function(index, id) {
|
apiCall: function(command, args) {
|
||||||
return type + '/' + id + '/' + id;
|
$.ajax({
|
||||||
}).toArray();
|
url: createURL(command),
|
||||||
|
data: args.data,
|
||||||
|
success: args.success,
|
||||||
|
error: function(json) {
|
||||||
|
args.error(parseXMLHttpResponse(json));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addSection: function(section) {
|
||||||
|
cloudStack.sections[section.id] = $.extend(section, {
|
||||||
|
customIcon: 'plugins/' + section.id + '/icon.png'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
extend: function(obj) {
|
||||||
|
$.extend(true, cloudStack, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Load modules
|
cloudStack.sections.plugins = {
|
||||||
require(
|
title: 'label.plugins',
|
||||||
paths,
|
show: cloudStack.uiCustom.pluginListing
|
||||||
function() {
|
};
|
||||||
$(cloudStack[type]).map(function(index, id) {
|
|
||||||
var basePath = type + '/' + id + '/';
|
|
||||||
var css = basePath + id + '.css';
|
|
||||||
var configJS = type == 'plugins' ? basePath + 'config' : null;
|
|
||||||
|
|
||||||
if (configJS) {
|
var loadedPlugins = 0;
|
||||||
// Load config metadata
|
var pluginTotal = cloudStack.plugins.length + cloudStack.modules.length;
|
||||||
require([configJS]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute module
|
// Load
|
||||||
cloudStack[type][id](
|
$(['modules', 'plugins']).each(function() {
|
||||||
$.extend(true, {}, cloudStack.pluginAPI, {
|
var type = this;
|
||||||
pluginAPI: {
|
var paths = $(cloudStack[type]).map(function(index, id) {
|
||||||
extend: function(api) {
|
return type + '/' + id + '/' + id;
|
||||||
cloudStack.pluginAPI[id] = api;
|
}).toArray();
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
loadedPlugins = loadedPlugins + 1;
|
// Load modules
|
||||||
|
require(
|
||||||
|
paths,
|
||||||
|
function() {
|
||||||
|
$(cloudStack[type]).map(function(index, id) {
|
||||||
|
var basePath = type + '/' + id + '/';
|
||||||
|
var css = basePath + id + '.css';
|
||||||
|
var configJS = type == 'plugins' ? basePath + 'config' : null;
|
||||||
|
|
||||||
if (loadedPlugins === pluginTotal) {
|
if (configJS) {
|
||||||
$(window).trigger('cloudStack.pluginReady');
|
// Load config metadata
|
||||||
}
|
require([configJS]);
|
||||||
|
}
|
||||||
|
|
||||||
loadCSS(css);
|
// Execute module
|
||||||
});
|
cloudStack[type][id](
|
||||||
}
|
$.extend(true, {}, cloudStack.pluginAPI, {
|
||||||
);
|
pluginAPI: {
|
||||||
});
|
extend: function(api) {
|
||||||
|
cloudStack.pluginAPI[id] = api;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
loadedPlugins = loadedPlugins + 1;
|
||||||
|
|
||||||
|
if (loadedPlugins === pluginTotal) {
|
||||||
|
$(window).trigger('cloudStack.pluginReady');
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCSS(css);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
}(jQuery, cloudStack, require));
|
}(jQuery, cloudStack, require));
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
30207
ui/scripts/system.js
30207
ui/scripts/system.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -15,159 +15,160 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function(cloudStack, $) {
|
(function(cloudStack, $) {
|
||||||
cloudStack.uiCustom.affinity = function(args) {
|
cloudStack.uiCustom.affinity = function(args) {
|
||||||
var listView = args.listView;
|
var listView = args.listView;
|
||||||
var action = args.action;
|
var action = args.action;
|
||||||
var tierSelect = args.tierSelect;
|
var tierSelect = args.tierSelect;
|
||||||
|
|
||||||
return function(args) {
|
return function(args) {
|
||||||
var context = args.context;
|
var context = args.context;
|
||||||
var $instanceRow = args.$instanceRow;
|
var $instanceRow = args.$instanceRow;
|
||||||
|
|
||||||
var vmList = function(args) {
|
var vmList = function(args) {
|
||||||
// Create a listing of instances, based on limited information
|
// Create a listing of instances, based on limited information
|
||||||
// from main instances list view
|
// from main instances list view
|
||||||
var $listView;
|
var $listView;
|
||||||
var instances = $.extend(true, {}, args.listView, {
|
var instances = $.extend(true, {}, args.listView, {
|
||||||
context: context,
|
context: context,
|
||||||
uiCustom: true
|
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() {
|
instances.listView.actions = {
|
||||||
$('div.overlay').remove();
|
select: {
|
||||||
$(':ui-dialog').dialog('destroy');
|
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'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
{
|
|
||||||
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));
|
}(cloudStack, jQuery));
|
||||||
|
|||||||
@ -16,386 +16,403 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.uiCustom.autoscaler = function(args) {
|
cloudStack.uiCustom.autoscaler = function(args) {
|
||||||
// Place outer args here as local variables
|
// Place outer args here as local variables
|
||||||
// i.e, -- var dataProvider = args.dataProvider
|
// i.e, -- var dataProvider = args.dataProvider
|
||||||
var forms = $.extend(true, {}, args.forms);
|
var forms = $.extend(true, {}, args.forms);
|
||||||
var topfields = forms.topFields;
|
var topfields = forms.topFields;
|
||||||
var bottomfields = forms.bottomFields;
|
var bottomfields = forms.bottomFields;
|
||||||
var scaleuppolicy = forms.scaleUpPolicy;
|
var scaleuppolicy = forms.scaleUpPolicy;
|
||||||
var scaledownpolicy = forms.scaleDownPolicy;
|
var scaledownpolicy = forms.scaleDownPolicy;
|
||||||
var dataProvider = cloudStack.autoscaler.dataProvider;
|
var dataProvider = cloudStack.autoscaler.dataProvider;
|
||||||
var actions = cloudStack.autoscaler.autoscaleActions;
|
var actions = cloudStack.autoscaler.autoscaleActions;
|
||||||
var actionFilter = cloudStack.autoscaler.actionFilter;
|
var actionFilter = cloudStack.autoscaler.actionFilter;
|
||||||
|
|
||||||
return function(args) {
|
return function(args) {
|
||||||
var context = args.data ?
|
var context = args.data ?
|
||||||
$.extend(true, {}, args.context, {
|
$.extend(true, {}, args.context, {
|
||||||
lbRules: [args.data]
|
lbRules: [args.data]
|
||||||
}) : args.context;
|
}) : args.context;
|
||||||
var formData = args.formData;
|
var formData = args.formData;
|
||||||
var $autoscalerDialog = $('<div>').addClass('autoscaler');
|
var $autoscalerDialog = $('<div>').addClass('autoscaler');
|
||||||
var $topFields = $('<div>').addClass('field-group top-fields');
|
var $topFields = $('<div>').addClass('field-group top-fields');
|
||||||
var $bottomFields = $('<div>').addClass('field-group bottom-fields');
|
var $bottomFields = $('<div>').addClass('field-group bottom-fields');
|
||||||
var $scaleUpPolicy = $('<div>').addClass('scale-up-policy');
|
var $scaleUpPolicy = $('<div>').addClass('scale-up-policy');
|
||||||
var $slideScaleUp = $('<div></div>').addClass('expand');
|
var $slideScaleUp = $('<div></div>').addClass('expand');
|
||||||
var $hideScaleUp = $('<div></div>').addClass('hide');
|
var $hideScaleUp = $('<div></div>').addClass('hide');
|
||||||
var $scaleUpLabel= $('<div>Show</div>').addClass('slide-label');
|
var $scaleUpLabel = $('<div>Show</div>').addClass('slide-label');
|
||||||
var $scaleUpHideLabel=$('<div>Hide</div>').addClass('slide-label');
|
var $scaleUpHideLabel = $('<div>Hide</div>').addClass('slide-label');
|
||||||
var $scaleDownHideLabel=$('<div>Hide</div>').addClass('slide-label');
|
var $scaleDownHideLabel = $('<div>Hide</div>').addClass('slide-label');
|
||||||
var $scaleDownLabel=$('<div>Show</div>').addClass('slide-label');
|
var $scaleDownLabel = $('<div>Show</div>').addClass('slide-label');
|
||||||
var $slideScaleDown = $('<div></div>').addClass('expand');
|
var $slideScaleDown = $('<div></div>').addClass('expand');
|
||||||
var $hideScaleDown = $('<div></div>').addClass('hide');
|
var $hideScaleDown = $('<div></div>').addClass('hide');
|
||||||
var $scaleUpDivider = $('<hr></hr>').addClass('policy-divider');
|
var $scaleUpDivider = $('<hr></hr>').addClass('policy-divider');
|
||||||
var $scaleDownDivider = $('<hr></hr>').addClass('policy-divider');
|
var $scaleDownDivider = $('<hr></hr>').addClass('policy-divider');
|
||||||
var $bottomFieldDivider = $('<hr></hr>').addClass('policy-divider');
|
var $bottomFieldDivider = $('<hr></hr>').addClass('policy-divider');
|
||||||
var $scaleDownPolicy = $('<div>').addClass('scale-down-policy');
|
var $scaleDownPolicy = $('<div>').addClass('scale-down-policy');
|
||||||
var $scaleUpPolicyTitle = $('<div>').addClass('scale-up-policy-title')
|
var $scaleUpPolicyTitle = $('<div>').addClass('scale-up-policy-title')
|
||||||
.html("Scale Up Policy");
|
.html("Scale Up Policy");
|
||||||
var $scaleDownPolicyTitle = $('<div>').addClass('scale-down-policy-title')
|
var $scaleDownPolicyTitle = $('<div>').addClass('scale-down-policy-title')
|
||||||
.html("Scale Down Policy");
|
.html("Scale Down Policy");
|
||||||
var topFieldForm, $topFieldForm,
|
var topFieldForm, $topFieldForm,
|
||||||
bottomFieldForm, $bottomFieldForm,
|
bottomFieldForm, $bottomFieldForm,
|
||||||
scaleUpPolicyTitleForm, $scaleUpPolicyTitleForm,
|
scaleUpPolicyTitleForm, $scaleUpPolicyTitleForm,
|
||||||
scaleDownPolicyTitleForm, $scaleDownPolicyTitleForm,
|
scaleDownPolicyTitleForm, $scaleDownPolicyTitleForm,
|
||||||
scaleUpPolicyForm, scaleDownPolicyForm;
|
scaleUpPolicyForm, scaleDownPolicyForm;
|
||||||
|
|
||||||
var renderActions = function(args) {
|
var renderActions = function(args) {
|
||||||
var targetActionFilter = args.actionFilter ? args.actionFilter : actionFilter;
|
var targetActionFilter = args.actionFilter ? args.actionFilter : actionFilter;
|
||||||
var data = args.data;
|
var data = args.data;
|
||||||
var context = args.context;
|
var context = args.context;
|
||||||
var $actions = $('<div>').addClass('detail-group');
|
var $actions = $('<div>').addClass('detail-group');
|
||||||
var $actionsTable = $('<table>').append('<tr>');
|
var $actionsTable = $('<table>').append('<tr>');
|
||||||
var $detailActions = $('<td>').addClass('detail-actions');
|
var $detailActions = $('<td>').addClass('detail-actions');
|
||||||
var $buttons = $('<div>').addClass('buttons');
|
var $buttons = $('<div>').addClass('buttons');
|
||||||
var visibleActions = targetActionFilter ?
|
var visibleActions = targetActionFilter ?
|
||||||
targetActionFilter({
|
targetActionFilter({
|
||||||
context: $.extend(true, {}, context, {
|
context: $.extend(true, {}, context, {
|
||||||
originalAutoscaleData: data ? [data] : null
|
originalAutoscaleData: data ? [data] : null
|
||||||
})
|
})
|
||||||
}) :
|
}) :
|
||||||
$.map(actions, function(value, key) { return key; });
|
$.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
|
|
||||||
if(data != null) { //data is originalAutoscaleData in \ui\scripts\autoscaler.js
|
|
||||||
data['afterActionIsComplete'] = args.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $newActions = renderActions({
|
|
||||||
data: data ? $.extend(data, args.data) : args.data,
|
|
||||||
actionFilter: args.actionFilter,
|
|
||||||
context: context
|
|
||||||
});
|
|
||||||
|
|
||||||
$actions.after($newActions);
|
|
||||||
$actions.remove();
|
|
||||||
};
|
|
||||||
var error = function(message) {
|
|
||||||
$loading.remove();
|
|
||||||
cloudStack.dialog.notice({ message: message });
|
|
||||||
};
|
|
||||||
|
|
||||||
action.action({
|
|
||||||
context: {
|
|
||||||
originalAutoscaleData: args.data
|
|
||||||
},
|
|
||||||
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(in sec)', validation: { required: true } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$scaleUpPolicyTitleForm = scaleUpPolicyTitleForm.$formContainer;
|
|
||||||
$scaleUpPolicyTitleForm.appendTo($scaleUpPolicyTitle);
|
|
||||||
|
|
||||||
|
|
||||||
scaleDownPolicyTitleForm = cloudStack.dialog.createForm({
|
|
||||||
context: context,
|
|
||||||
noDialog: true,
|
|
||||||
form: {
|
|
||||||
title: '',
|
|
||||||
fields: {
|
|
||||||
scaleDownDuration: { label: 'Duration(in sec)', 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'));
|
|
||||||
|
|
||||||
// Pass VPC data
|
|
||||||
if (formData.tier) {
|
|
||||||
data.tier = formData.tier;
|
|
||||||
}
|
|
||||||
|
|
||||||
$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: 'Autoscale configured successfully.'
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
error: function(message) {
|
$detailActions.append($buttons);
|
||||||
cloudStack.dialog.notice({ message: message });
|
$actionsTable.find('tr').append($detailActions);
|
||||||
$loading.remove();
|
$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
|
||||||
|
if (data != null) { //data is originalAutoscaleData in \ui\scripts\autoscaler.js
|
||||||
|
data['afterActionIsComplete'] = args.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $newActions = renderActions({
|
||||||
|
data: data ? $.extend(data, args.data) : args.data,
|
||||||
|
actionFilter: args.actionFilter,
|
||||||
|
context: context
|
||||||
|
});
|
||||||
|
|
||||||
|
$actions.after($newActions);
|
||||||
|
$actions.remove();
|
||||||
|
};
|
||||||
|
var error = function(message) {
|
||||||
|
$loading.remove();
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
action.action({
|
||||||
|
context: {
|
||||||
|
originalAutoscaleData: args.data
|
||||||
|
},
|
||||||
|
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(in sec)',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$scaleUpPolicyTitleForm = scaleUpPolicyTitleForm.$formContainer;
|
||||||
|
$scaleUpPolicyTitleForm.appendTo($scaleUpPolicyTitle);
|
||||||
|
|
||||||
|
|
||||||
|
scaleDownPolicyTitleForm = cloudStack.dialog.createForm({
|
||||||
|
context: context,
|
||||||
|
noDialog: true,
|
||||||
|
form: {
|
||||||
|
title: '',
|
||||||
|
fields: {
|
||||||
|
scaleDownDuration: {
|
||||||
|
label: 'Duration(in sec)',
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}).closest('.ui-dialog').overlay();
|
|
||||||
|
|
||||||
dataProvider({
|
if (data.scaleUpPolicy && data.scaleUpPolicy.duration) {
|
||||||
context: context,
|
$scaleUpPolicyTitleForm.find('input[name=scaleUpDuration]').val(
|
||||||
response: {
|
data.scaleUpPolicy.duration
|
||||||
success: function(args) {
|
);
|
||||||
$loading.remove();
|
}
|
||||||
renderDialogContent(args);
|
|
||||||
|
|
||||||
if (args.data == null) { //from a new LB rule
|
scaleuppolicy.context = context;
|
||||||
$autoscalerDialog.find('select[name=serviceOfferingId]').removeAttr('disabled');
|
scaleUpPolicyForm = $scaleUpPolicy.multiEdit(scaleuppolicy);
|
||||||
$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) {
|
// Scale down policy
|
||||||
$autoscalerDialog.find('input[type=checkbox]').trigger('click');
|
if (data.scaleDownPolicy && $.isArray(data.scaleDownPolicy.conditions)) {
|
||||||
$autoscalerDialog.find('input[type=checkbox]').attr('checked', 'checked');
|
$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'));
|
||||||
|
|
||||||
|
// Pass VPC data
|
||||||
|
if (formData.tier) {
|
||||||
|
data.tier = formData.tier;
|
||||||
|
}
|
||||||
|
|
||||||
|
$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: 'Autoscale 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));
|
}(jQuery, cloudStack));
|
||||||
|
|||||||
@ -15,178 +15,191 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.uiCustom.dashboard = function() {
|
cloudStack.uiCustom.dashboard = function() {
|
||||||
/**
|
/**
|
||||||
* Retrieve chart data
|
* Retrieve chart data
|
||||||
*/
|
*/
|
||||||
var getData = function() {
|
var getData = function() {
|
||||||
// Populate data
|
// Populate data
|
||||||
$dashboard.find('[data-item]').hide();
|
$dashboard.find('[data-item]').hide();
|
||||||
cloudStack.sections.dashboard[dashboardType].dataProvider({
|
cloudStack.sections.dashboard[dashboardType].dataProvider({
|
||||||
response: {
|
response: {
|
||||||
success: function(args) {
|
success: function(args) {
|
||||||
var $browser = $dashboard.closest('#browser .container');
|
var $browser = $dashboard.closest('#browser .container');
|
||||||
var data = args.data;
|
var data = args.data;
|
||||||
|
|
||||||
// Iterate over data; populate corresponding DOM elements
|
// Iterate over data; populate corresponding DOM elements
|
||||||
$.each(data, function(key, value) {
|
$.each(data, function(key, value) {
|
||||||
var $elem = $dashboard.find('[data-item=' + key + ']');
|
var $elem = $dashboard.find('[data-item=' + key + ']');
|
||||||
|
|
||||||
// This assumes an array of data
|
// This assumes an array of data
|
||||||
if ($elem.is('ul')) {
|
if ($elem.is('ul')) {
|
||||||
$elem.show();
|
$elem.show();
|
||||||
var $liTmpl = $elem.find('li').remove();
|
var $liTmpl = $elem.find('li').remove();
|
||||||
$(value).each(function() {
|
$(value).each(function() {
|
||||||
var item = this;
|
var item = this;
|
||||||
var $li = $liTmpl.clone().appendTo($elem).hide();
|
var $li = $liTmpl.clone().appendTo($elem).hide();
|
||||||
|
|
||||||
if ($li.is('.zone-stats li')) {
|
if ($li.is('.zone-stats li')) {
|
||||||
$li.click(function() {
|
$li.click(function() {
|
||||||
$browser.cloudBrowser('addPanel', {
|
$browser.cloudBrowser('addPanel', {
|
||||||
title: _l('label.zone.details'),
|
title: _l('label.zone.details'),
|
||||||
parent: $dashboard.closest('.panel'),
|
parent: $dashboard.closest('.panel'),
|
||||||
maximizeIfSelected: true,
|
maximizeIfSelected: true,
|
||||||
complete: function($newPanel) {
|
complete: function($newPanel) {
|
||||||
$newPanel.detailView($.extend(true, {},
|
$newPanel.detailView($.extend(true, {},
|
||||||
cloudStack.sections.dashboard.admin.zoneDetailView,
|
cloudStack.sections.dashboard.admin.zoneDetailView, {
|
||||||
{
|
$browser: $browser,
|
||||||
$browser: $browser,
|
context: $.extend(true, {}, cloudStack.context, {
|
||||||
context: $.extend(true, {}, cloudStack.context, {
|
physicalResources: [{
|
||||||
physicalResources: [{ id: item.zoneID }]
|
id: item.zoneID
|
||||||
})
|
}]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$.each(item, function(arrayKey, arrayValue) {
|
$.each(item, function(arrayKey, arrayValue) {
|
||||||
if (!arrayValue) arrayValue = '';
|
if (!arrayValue) arrayValue = '';
|
||||||
|
|
||||||
var $arrayElem = $li.find('[data-list-item=' + arrayKey + ']');
|
var $arrayElem = $li.find('[data-list-item=' + arrayKey + ']');
|
||||||
|
|
||||||
$arrayElem.each(function() {
|
$arrayElem.each(function() {
|
||||||
var $arrayElem = $(this);
|
var $arrayElem = $(this);
|
||||||
|
|
||||||
if ($arrayElem.hasClass('pie-chart')) {
|
if ($arrayElem.hasClass('pie-chart')) {
|
||||||
// Generate pie chart
|
// Generate pie chart
|
||||||
// -- values above 80 have a red color
|
// -- values above 80 have a red color
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
pieChart($arrayElem, [
|
pieChart($arrayElem, [{
|
||||||
{ data: [[1, 100 - arrayValue]], color: '#54697e' },
|
data: [
|
||||||
{ data: [[1, arrayValue]], color: arrayValue < 80 ? 'orange' : 'red' }
|
[1, 100 - arrayValue]
|
||||||
]);
|
],
|
||||||
|
color: '#54697e'
|
||||||
|
}, {
|
||||||
|
data: [
|
||||||
|
[1, arrayValue]
|
||||||
|
],
|
||||||
|
color: arrayValue < 80 ? 'orange' : 'red'
|
||||||
|
}]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if ($li.attr('concat-value')) {
|
||||||
|
var val = $(_l(arrayValue).toString().split(', ')).map(function() {
|
||||||
|
var val = _s(this.toString());
|
||||||
|
var concatValue = parseInt($li.attr('concat-value'));
|
||||||
|
|
||||||
|
return val.length >= concatValue ?
|
||||||
|
val.substring(0, concatValue).concat('...') : val;
|
||||||
|
}).toArray().join('<br />');
|
||||||
|
|
||||||
|
$arrayElem.html(val);
|
||||||
|
} else {
|
||||||
|
$arrayElem.html(_s(_l(arrayValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$arrayElem.attr('title', _l(arrayValue).toString().replace('<br/>', ', '));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$li.attr({
|
||||||
|
title: _s(_l(item.description))
|
||||||
|
});
|
||||||
|
|
||||||
|
$li.fadeIn();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$elem.each(function() {
|
||||||
|
var $item = $(this);
|
||||||
|
if ($item.hasClass('chart-line')) {
|
||||||
|
$item.show().animate({
|
||||||
|
width: value + '%'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$item.hide().html(_s(value)).fadeIn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
if ($li.attr('concat-value')) {
|
}
|
||||||
var val = $(_l(arrayValue).toString().split(', ')).map(function() {
|
});
|
||||||
var val = _s(this.toString());
|
};
|
||||||
var concatValue = parseInt($li.attr('concat-value'));
|
|
||||||
|
|
||||||
return val.length >= concatValue ?
|
/**
|
||||||
val.substring(0, concatValue).concat('...') : val;
|
* Render circular pie chart, without labels
|
||||||
}).toArray().join('<br />');
|
*/
|
||||||
|
var pieChart = function($container, data) {
|
||||||
$arrayElem.html(val);
|
$container.css({
|
||||||
} else {
|
width: 70,
|
||||||
$arrayElem.html(_s(_l(arrayValue)));
|
height: 66
|
||||||
|
});
|
||||||
|
$.plot($container, data, {
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
series: {
|
||||||
|
pie: {
|
||||||
|
innerRadius: 0.7,
|
||||||
|
show: true,
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$arrayElem.attr('title', _l(arrayValue).toString().replace('<br/>', ', '));
|
},
|
||||||
}
|
legend: {
|
||||||
});
|
show: false
|
||||||
});
|
}
|
||||||
|
|
||||||
$li.attr({ title: _s(_l(item.description)) });
|
|
||||||
|
|
||||||
$li.fadeIn();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$elem.each(function() {
|
|
||||||
var $item = $(this);
|
|
||||||
if ($item.hasClass('chart-line')) {
|
|
||||||
$item.show().animate({ width: value + '%' });
|
|
||||||
} else {
|
|
||||||
$item.hide().html(_s(value)).fadeIn();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
// Determine if user or admin dashboard should be shown
|
||||||
* Render circular pie chart, without labels
|
var dashboardType = cloudStack.sections.dashboard.adminCheck({
|
||||||
*/
|
context: cloudStack.context
|
||||||
var pieChart = function($container, data) {
|
}) ? 'admin' : 'user';
|
||||||
$container.css({ width: 70, height: 66 });
|
|
||||||
$.plot($container, data, {
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
series: {
|
|
||||||
pie: {
|
|
||||||
innerRadius: 0.7,
|
|
||||||
show: true,
|
|
||||||
label: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine if user or admin dashboard should be shown
|
// Get dashboard layout
|
||||||
var dashboardType = cloudStack.sections.dashboard.adminCheck({
|
var $dashboard = $('#template').find('div.dashboard.' + dashboardType).clone();
|
||||||
context: cloudStack.context
|
|
||||||
}) ? 'admin' : 'user';
|
|
||||||
|
|
||||||
// Get dashboard layout
|
// Update text
|
||||||
var $dashboard = $('#template').find('div.dashboard.' + dashboardType).clone();
|
$dashboard.find('.button.view-all').html(_l('label.view.all'));
|
||||||
|
$dashboard.find('.dashboard-container.sub.alerts.first .top .title span').html(_l('label.general.alerts'));
|
||||||
|
$dashboard.find('.dashboard-container.sub.alerts.last .top .title span').html(_l('label.host.alerts'));
|
||||||
|
$dashboard.find('.dashboard-container.head .top .title span').html(_l('label.system.capacity'));
|
||||||
|
|
||||||
// Update text
|
// View all action
|
||||||
$dashboard.find('.button.view-all').html(_l('label.view.all'));
|
$dashboard.find('.view-all').click(function() {
|
||||||
$dashboard.find('.dashboard-container.sub.alerts.first .top .title span').html(_l('label.general.alerts'));
|
var $browser = $('#browser .container');
|
||||||
$dashboard.find('.dashboard-container.sub.alerts.last .top .title span').html(_l('label.host.alerts'));
|
|
||||||
$dashboard.find('.dashboard-container.head .top .title span').html(_l('label.system.capacity'));
|
|
||||||
|
|
||||||
// View all action
|
if ($(this).hasClass('network')) $('#navigation li.network').click();
|
||||||
$dashboard.find('.view-all').click(function() {
|
else {
|
||||||
var $browser = $('#browser .container');
|
$browser.cloudBrowser('addPanel', {
|
||||||
|
title: $dashboard.hasClass('admin') ? 'Alerts' : 'Events',
|
||||||
if ($(this).hasClass('network')) $('#navigation li.network').click();
|
maximizeIfSelected: true,
|
||||||
else {
|
complete: function($newPanel) {
|
||||||
$browser.cloudBrowser('addPanel', {
|
$newPanel.listView({
|
||||||
title: $dashboard.hasClass('admin') ? 'Alerts' : 'Events',
|
$browser: $browser,
|
||||||
maximizeIfSelected: true,
|
context: cloudStack.context,
|
||||||
complete: function($newPanel) {
|
listView: $dashboard.hasClass('admin') ? cloudStack.sections.events.sections.alerts.listView : cloudStack.sections.events.sections.events.listView // Users cannot see events
|
||||||
$newPanel.listView({
|
});
|
||||||
$browser: $browser,
|
}
|
||||||
context: cloudStack.context,
|
});
|
||||||
listView: $dashboard.hasClass('admin') ?
|
};
|
||||||
cloudStack.sections.events.sections.alerts.listView :
|
|
||||||
cloudStack.sections.events.sections.events.listView // Users cannot see events
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
//Fetch Latest action
|
//Fetch Latest action
|
||||||
$dashboard.find('.fetch-latest').click(function() {
|
$dashboard.find('.fetch-latest').click(function() {
|
||||||
window.fetchLatestflag = 1;
|
window.fetchLatestflag = 1;
|
||||||
var $browser = $('#browser .container');
|
var $browser = $('#browser .container');
|
||||||
|
|
||||||
if ($(this).hasClass('fetch-latest')) $('#navigation li.dashboard').click();
|
if ($(this).hasClass('fetch-latest')) $('#navigation li.dashboard').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
getData();
|
getData();
|
||||||
|
|
||||||
return $dashboard;
|
return $dashboard;
|
||||||
};
|
};
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|||||||
@ -15,157 +15,160 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function(cloudStack, $) {
|
(function(cloudStack, $) {
|
||||||
cloudStack.uiCustom.enableStaticNAT = function(args) {
|
cloudStack.uiCustom.enableStaticNAT = function(args) {
|
||||||
var listView = args.listView;
|
var listView = args.listView;
|
||||||
var action = args.action;
|
var action = args.action;
|
||||||
var tierSelect = args.tierSelect;
|
var tierSelect = args.tierSelect;
|
||||||
|
|
||||||
return function(args) {
|
return function(args) {
|
||||||
var context = args.context;
|
var context = args.context;
|
||||||
var $instanceRow = args.$instanceRow;
|
var $instanceRow = args.$instanceRow;
|
||||||
|
|
||||||
var vmList = function(args) {
|
var vmList = function(args) {
|
||||||
// Create a listing of instances, based on limited information
|
// Create a listing of instances, based on limited information
|
||||||
// from main instances list view
|
// from main instances list view
|
||||||
var $listView;
|
var $listView;
|
||||||
var instances = $.extend(true, {}, args.listView, {
|
var instances = $.extend(true, {}, args.listView, {
|
||||||
context: context,
|
context: context,
|
||||||
uiCustom: true
|
uiCustom: true
|
||||||
});
|
|
||||||
|
|
||||||
instances.listView.actions = {
|
|
||||||
select: {
|
|
||||||
label: _l('label.select.instance'),
|
|
||||||
type: 'radio',
|
|
||||||
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() {
|
instances.listView.actions = {
|
||||||
$('div.overlay').remove();
|
select: {
|
||||||
});
|
label: _l('label.select.instance'),
|
||||||
|
type: 'radio',
|
||||||
|
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'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
{
|
|
||||||
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));
|
}(cloudStack, jQuery));
|
||||||
|
|||||||
@ -16,31 +16,39 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.uiCustom.granularSettings = function(args) {
|
cloudStack.uiCustom.granularSettings = function(args) {
|
||||||
var dataProvider = args.dataProvider;
|
var dataProvider = args.dataProvider;
|
||||||
var actions = args.actions;
|
var actions = args.actions;
|
||||||
|
|
||||||
return function(args) {
|
return function(args) {
|
||||||
var context = args.context;
|
var context = args.context;
|
||||||
|
|
||||||
var listView = {
|
var listView = {
|
||||||
id: 'settings',
|
id: 'settings',
|
||||||
fields: {
|
fields: {
|
||||||
name: { label: 'label.name' },
|
name: {
|
||||||
value: { label: 'label.value', editable: true }
|
label: 'label.name'
|
||||||
},
|
},
|
||||||
actions: {
|
value: {
|
||||||
edit: {
|
label: 'label.value',
|
||||||
label: 'label.change.value',
|
editable: true
|
||||||
action: actions.edit
|
}
|
||||||
}
|
},
|
||||||
},
|
actions: {
|
||||||
dataProvider: dataProvider
|
edit: {
|
||||||
};
|
label: 'label.change.value',
|
||||||
|
action: actions.edit
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataProvider: dataProvider
|
||||||
|
};
|
||||||
|
|
||||||
var $listView = $('<div>').listView({ context: context, listView: listView });
|
var $listView = $('<div>').listView({
|
||||||
|
context: context,
|
||||||
|
listView: listView
|
||||||
|
});
|
||||||
|
|
||||||
return $listView;
|
return $listView;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|||||||
@ -17,334 +17,367 @@
|
|||||||
|
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
|
|
||||||
cloudStack.uiCustom.healthCheck = function(args) {
|
cloudStack.uiCustom.healthCheck = function(args) {
|
||||||
|
|
||||||
// Place outer args here as local variables
|
// Place outer args here as local variables
|
||||||
// i.e, -- var dataProvider = args.dataProvider
|
// i.e, -- var dataProvider = args.dataProvider
|
||||||
|
|
||||||
return function(args){
|
return function(args) {
|
||||||
if(args.context.multiRules == undefined) { //LB rule is not created yet
|
if (args.context.multiRules == undefined) { //LB rule is not created yet
|
||||||
cloudStack.dialog.notice({ message: _l('Health Check can only be configured on a created LB rule') });
|
cloudStack.dialog.notice({
|
||||||
return;
|
message: _l('Health Check can only be configured on a created LB rule')
|
||||||
}
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var formData = args.formData;
|
var formData = args.formData;
|
||||||
var forms = $.extend(true, {}, args.forms);
|
var forms = $.extend(true, {}, args.forms);
|
||||||
var topFieldForm, bottomFieldForm , $topFieldForm , $bottomFieldForm;
|
var topFieldForm, bottomFieldForm, $topFieldForm, $bottomFieldForm;
|
||||||
var topfields = forms.topFields;
|
var topfields = forms.topFields;
|
||||||
|
|
||||||
var $healthCheckDesc = $('<div>Your load balancer will automatically perform health checks on your cloudstack instances and only route traffic to instances that pass the health check </div>').addClass('health-check-description');
|
var $healthCheckDesc = $('<div>Your load balancer will automatically perform health checks on your cloudstack instances and only route traffic to instances that pass the health check </div>').addClass('health-check-description');
|
||||||
var $healthCheckConfigTitle = $('<div><br><br>Configuration Options :</div>').addClass('health-check-config-title');
|
var $healthCheckConfigTitle = $('<div><br><br>Configuration Options :</div>').addClass('health-check-config-title');
|
||||||
var $healthCheckAdvancedTitle = $('<div><br><br> Advanced Options : </div>').addClass('health-check-advanced-title');
|
var $healthCheckAdvancedTitle = $('<div><br><br> Advanced Options : </div>').addClass('health-check-advanced-title');
|
||||||
|
|
||||||
var $healthCheckDialog = $('<div>').addClass('health-check');
|
var $healthCheckDialog = $('<div>').addClass('health-check');
|
||||||
$healthCheckDialog.append($healthCheckDesc);
|
$healthCheckDialog.append($healthCheckDesc);
|
||||||
$healthCheckDialog.append($healthCheckConfigTitle);
|
$healthCheckDialog.append($healthCheckConfigTitle);
|
||||||
var $loadingOnDialog = $('<div>').addClass('loading-overlay');
|
var $loadingOnDialog = $('<div>').addClass('loading-overlay');
|
||||||
|
|
||||||
var policyObj = null;
|
var policyObj = null;
|
||||||
var pingpath1 = '/';
|
var pingpath1 = '/';
|
||||||
var responsetimeout1 = '2';
|
var responsetimeout1 = '2';
|
||||||
var healthinterval1 = '5';
|
var healthinterval1 = '5';
|
||||||
var healthythreshold1 = '2';
|
var healthythreshold1 = '2';
|
||||||
var unhealthythreshold1 = '1';
|
var unhealthythreshold1 = '1';
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: createURL('listLBHealthCheckPolicies'),
|
url: createURL('listLBHealthCheckPolicies'),
|
||||||
data: {
|
data: {
|
||||||
lbruleid: args.context.multiRules[0].id
|
lbruleid: args.context.multiRules[0].id
|
||||||
},
|
},
|
||||||
async: false,
|
async: false,
|
||||||
success: function(json) {
|
success: function(json) {
|
||||||
if(json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0] != undefined) {
|
if (json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0] != undefined) {
|
||||||
policyObj = json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0];
|
policyObj = json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0];
|
||||||
pingpath1 = policyObj.pingpath; //API bug: API doesn't return it
|
pingpath1 = policyObj.pingpath; //API bug: API doesn't return it
|
||||||
responsetimeout1 = policyObj.responsetime;
|
responsetimeout1 = policyObj.responsetime;
|
||||||
healthinterval1 = policyObj.healthcheckinterval;
|
healthinterval1 = policyObj.healthcheckinterval;
|
||||||
healthythreshold1 = policyObj.healthcheckthresshold;
|
healthythreshold1 = policyObj.healthcheckthresshold;
|
||||||
unhealthythreshold1 = policyObj.unhealthcheckthresshold;
|
unhealthythreshold1 = policyObj.unhealthcheckthresshold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
topFieldForm = cloudStack.dialog.createForm({
|
topFieldForm = cloudStack.dialog.createForm({
|
||||||
context: args.context,
|
context: args.context,
|
||||||
noDialog: true, // Don't render a dialog, just return $formContainer
|
noDialog: true, // Don't render a dialog, just return $formContainer
|
||||||
form: {
|
form: {
|
||||||
title: '',
|
title: '',
|
||||||
fields:{
|
fields: {
|
||||||
pingpath: {label: 'Ping Path', validation: {required: false}, defaultValue: pingpath1}
|
pingpath: {
|
||||||
}
|
label: 'Ping Path',
|
||||||
}
|
validation: {
|
||||||
});
|
required: false
|
||||||
|
},
|
||||||
|
defaultValue: pingpath1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$topFieldForm = topFieldForm.$formContainer;
|
$topFieldForm = topFieldForm.$formContainer;
|
||||||
$topFieldForm.appendTo($healthCheckDialog);
|
$topFieldForm.appendTo($healthCheckDialog);
|
||||||
|
|
||||||
$healthCheckDialog.append($healthCheckAdvancedTitle);
|
$healthCheckDialog.append($healthCheckAdvancedTitle);
|
||||||
|
|
||||||
|
bottomFieldForm = cloudStack.dialog.createForm({
|
||||||
|
context: args.context,
|
||||||
|
noDialog: true,
|
||||||
|
form: {
|
||||||
|
title: '',
|
||||||
|
fields: {
|
||||||
|
responsetimeout: {
|
||||||
|
label: 'Response Timeout (in sec)',
|
||||||
|
validation: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
defaultValue: responsetimeout1
|
||||||
|
},
|
||||||
|
healthinterval: {
|
||||||
|
label: 'Health Check Interval (in sec)',
|
||||||
|
validation: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
defaultValue: healthinterval1
|
||||||
|
},
|
||||||
|
healthythreshold: {
|
||||||
|
label: 'Healthy Threshold',
|
||||||
|
validation: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
defaultValue: healthythreshold1
|
||||||
|
},
|
||||||
|
unhealthythreshold: {
|
||||||
|
label: 'Unhealthy Threshold',
|
||||||
|
validation: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
defaultValue: unhealthythreshold1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$bottomFieldForm = bottomFieldForm.$formContainer;
|
||||||
|
$bottomFieldForm.appendTo($healthCheckDialog);
|
||||||
|
|
||||||
|
|
||||||
|
var buttons = [{
|
||||||
|
text: _l('label.cancel'),
|
||||||
|
'class': 'cancel',
|
||||||
|
click: function() {
|
||||||
|
$healthCheckDialog.dialog('destroy');
|
||||||
|
$('.overlay').remove();
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
if (policyObj == null) { //policy is not created yet
|
||||||
|
buttons.push({
|
||||||
|
text: _l('Create'),
|
||||||
|
'class': 'ok',
|
||||||
|
click: function() {
|
||||||
|
$loadingOnDialog.appendTo($healthCheckDialog);
|
||||||
|
var formData = cloudStack.serializeForm($healthCheckDialog.find('form'));
|
||||||
|
var data = {
|
||||||
|
lbruleid: args.context.multiRules[0].id,
|
||||||
|
pingpath: formData.pingpath,
|
||||||
|
responsetimeout: formData.responsetimeout,
|
||||||
|
intervaltime: formData.healthinterval,
|
||||||
|
healthythreshold: formData.healthythreshold,
|
||||||
|
unhealthythreshold: formData.unhealthythreshold
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('createLBHealthCheckPolicy'),
|
||||||
|
data: data,
|
||||||
|
success: function(json) {
|
||||||
|
var jobId = json.createlbhealthcheckpolicyresponse.jobid;
|
||||||
|
var createLBHealthCheckPolicyIntervalId = setInterval(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('queryAsyncJobResult'),
|
||||||
|
data: {
|
||||||
|
jobid: jobId
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var result = json.queryasyncjobresultresponse;
|
||||||
|
if (result.jobstatus == 0) {
|
||||||
|
return; //Job has not completed
|
||||||
|
} else {
|
||||||
|
clearInterval(createLBHealthCheckPolicyIntervalId);
|
||||||
|
|
||||||
|
if (result.jobstatus == 1) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _l('Health Check Policy has been created')
|
||||||
|
});
|
||||||
|
$loadingOnDialog.remove();
|
||||||
|
$healthCheckDialog.dialog('destroy');
|
||||||
|
$('.overlay').remove();
|
||||||
|
} else if (result.jobstatus == 2) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _s(result.jobresult.errortext)
|
||||||
|
});
|
||||||
|
$loadingOnDialog.remove();
|
||||||
|
$healthCheckDialog.dialog('destroy');
|
||||||
|
$('.overlay').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, g_queryAsyncJobResultInterval);
|
||||||
|
},
|
||||||
|
|
||||||
|
error: function(json) {
|
||||||
|
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _s(json.responseText)
|
||||||
|
}); //Error message in the API needs to be improved
|
||||||
|
$healthCheckDialog.dialog('close');
|
||||||
|
$('.overlay').remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else { //policy exists already
|
||||||
|
buttons.push(
|
||||||
|
//Update Button (begin) - call delete API first, then create API
|
||||||
|
{
|
||||||
|
text: _l('Update'),
|
||||||
|
'class': 'ok',
|
||||||
|
click: function() {
|
||||||
|
$loadingOnDialog.appendTo($healthCheckDialog);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('deleteLBHealthCheckPolicy'),
|
||||||
|
data: {
|
||||||
|
id: policyObj.id
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var jobId = json.deletelbhealthcheckpolicyresponse.jobid;
|
||||||
|
var deleteLBHealthCheckPolicyIntervalId = setInterval(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('queryAsyncJobResult'),
|
||||||
|
data: {
|
||||||
|
jobid: jobId
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var result = json.queryasyncjobresultresponse;
|
||||||
|
if (result.jobstatus == 0) {
|
||||||
|
return; //Job has not completed
|
||||||
|
} else {
|
||||||
|
clearInterval(deleteLBHealthCheckPolicyIntervalId);
|
||||||
|
|
||||||
|
if (result.jobstatus == 1) {
|
||||||
|
var formData = cloudStack.serializeForm($healthCheckDialog.find('form'));
|
||||||
|
var data = {
|
||||||
|
lbruleid: args.context.multiRules[0].id,
|
||||||
|
pingpath: formData.pingpath,
|
||||||
|
responsetimeout: formData.responsetimeout,
|
||||||
|
intervaltime: formData.healthinterval,
|
||||||
|
healthythreshold: formData.healthythreshold,
|
||||||
|
unhealthythreshold: formData.unhealthythreshold
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('createLBHealthCheckPolicy'),
|
||||||
|
data: data,
|
||||||
|
success: function(json) {
|
||||||
|
var jobId = json.createlbhealthcheckpolicyresponse.jobid;
|
||||||
|
var createLBHealthCheckPolicyIntervalId = setInterval(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('queryAsyncJobResult'),
|
||||||
|
data: {
|
||||||
|
jobid: jobId
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var result = json.queryasyncjobresultresponse;
|
||||||
|
if (result.jobstatus == 0) {
|
||||||
|
return; //Job has not completed
|
||||||
|
} else {
|
||||||
|
clearInterval(createLBHealthCheckPolicyIntervalId);
|
||||||
|
|
||||||
|
if (result.jobstatus == 1) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _l('Health Check Policy has been updated')
|
||||||
|
});
|
||||||
|
$loadingOnDialog.remove();
|
||||||
|
$healthCheckDialog.dialog('destroy');
|
||||||
|
$('.overlay').remove();
|
||||||
|
} else if (result.jobstatus == 2) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _s(result.jobresult.errortext)
|
||||||
|
});
|
||||||
|
$loadingOnDialog.remove();
|
||||||
|
$healthCheckDialog.dialog('destroy');
|
||||||
|
$('.overlay').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, g_queryAsyncJobResultInterval);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (result.jobstatus == 2) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _s(result.jobresult.errortext)
|
||||||
|
});
|
||||||
|
$loadingOnDialog.remove();
|
||||||
|
$healthCheckDialog.dialog('destroy');
|
||||||
|
$('.overlay').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, g_queryAsyncJobResultInterval);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Update Button (end)
|
||||||
|
,
|
||||||
|
//Delete Button (begin) - call delete API
|
||||||
|
{
|
||||||
|
text: _l('Delete'),
|
||||||
|
'class': 'delete',
|
||||||
|
click: function() {
|
||||||
|
$loadingOnDialog.appendTo($healthCheckDialog);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('deleteLBHealthCheckPolicy'),
|
||||||
|
data: {
|
||||||
|
id: policyObj.id
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var jobId = json.deletelbhealthcheckpolicyresponse.jobid;
|
||||||
|
var deleteLBHealthCheckPolicyIntervalId = setInterval(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('queryAsyncJobResult'),
|
||||||
|
data: {
|
||||||
|
jobid: jobId
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
var result = json.queryasyncjobresultresponse;
|
||||||
|
if (result.jobstatus == 0) {
|
||||||
|
return; //Job has not completed
|
||||||
|
} else {
|
||||||
|
clearInterval(deleteLBHealthCheckPolicyIntervalId);
|
||||||
|
|
||||||
|
if (result.jobstatus == 1) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _l('Health Check Policy has been deleted')
|
||||||
|
});
|
||||||
|
$loadingOnDialog.remove();
|
||||||
|
$healthCheckDialog.dialog('destroy');
|
||||||
|
$('.overlay').remove();
|
||||||
|
} else if (result.jobstatus == 2) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _s(result.jobresult.errortext)
|
||||||
|
});
|
||||||
|
$loadingOnDialog.remove();
|
||||||
|
$healthCheckDialog.dialog('destroy');
|
||||||
|
$('.overlay').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, g_queryAsyncJobResultInterval);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Delete Button (end)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$healthCheckDialog.dialog({
|
||||||
|
title: 'Health Check Wizard',
|
||||||
|
width: 600,
|
||||||
|
height: 600,
|
||||||
|
draggable: true,
|
||||||
|
closeonEscape: false,
|
||||||
|
overflow: 'auto',
|
||||||
|
open: function() {
|
||||||
|
$("button").each(function() {
|
||||||
|
$(this).attr("style", "left: 400px; position: relative; margin-right: 5px; ");
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.ui-dialog .delete').css('left', '140px');
|
||||||
|
|
||||||
|
},
|
||||||
|
buttons: buttons
|
||||||
|
}).closest('.ui-dialog').overlay();
|
||||||
|
|
||||||
bottomFieldForm = cloudStack.dialog.createForm ({
|
|
||||||
context:args.context,
|
|
||||||
noDialog:true,
|
|
||||||
form:{
|
|
||||||
title:'',
|
|
||||||
fields:{
|
|
||||||
responsetimeout: {label: 'Response Timeout (in sec)' , validation:{required:false}, defaultValue: responsetimeout1},
|
|
||||||
healthinterval: {label: 'Health Check Interval (in sec)', validation:{required:false}, defaultValue: healthinterval1},
|
|
||||||
healthythreshold: {label: 'Healthy Threshold', validation: {required:false}, defaultValue: healthythreshold1},
|
|
||||||
unhealthythreshold: {label: 'Unhealthy Threshold' , validation: { required:false}, defaultValue: unhealthythreshold1}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
$bottomFieldForm = bottomFieldForm.$formContainer;
|
|
||||||
$bottomFieldForm.appendTo($healthCheckDialog);
|
|
||||||
|
|
||||||
|
|
||||||
var buttons = [
|
|
||||||
{
|
|
||||||
text: _l('label.cancel'),
|
|
||||||
'class': 'cancel',
|
|
||||||
click: function() {
|
|
||||||
$healthCheckDialog.dialog('destroy');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
if(policyObj == null) { //policy is not created yet
|
|
||||||
buttons.push(
|
|
||||||
{
|
|
||||||
text: _l('Create'),
|
|
||||||
'class': 'ok',
|
|
||||||
click: function() {
|
|
||||||
$loadingOnDialog.appendTo($healthCheckDialog);
|
|
||||||
var formData = cloudStack.serializeForm($healthCheckDialog.find('form'));
|
|
||||||
var data = {
|
|
||||||
lbruleid: args.context.multiRules[0].id,
|
|
||||||
pingpath: formData.pingpath,
|
|
||||||
responsetimeout: formData.responsetimeout,
|
|
||||||
intervaltime: formData.healthinterval,
|
|
||||||
healthythreshold: formData.healthythreshold,
|
|
||||||
unhealthythreshold: formData.unhealthythreshold
|
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('createLBHealthCheckPolicy'),
|
|
||||||
data: data,
|
|
||||||
success: function(json) {
|
|
||||||
var jobId = json.createlbhealthcheckpolicyresponse.jobid;
|
|
||||||
var createLBHealthCheckPolicyIntervalId = setInterval(function(){
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('queryAsyncJobResult'),
|
|
||||||
data: {
|
|
||||||
jobid: jobId
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var result = json.queryasyncjobresultresponse;
|
|
||||||
if (result.jobstatus == 0) {
|
|
||||||
return; //Job has not completed
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clearInterval(createLBHealthCheckPolicyIntervalId);
|
|
||||||
|
|
||||||
if (result.jobstatus == 1) {
|
|
||||||
cloudStack.dialog.notice({ message: _l('Health Check Policy has been created') });
|
|
||||||
$loadingOnDialog.remove();
|
|
||||||
$healthCheckDialog.dialog('destroy');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
else if (result.jobstatus == 2) {
|
|
||||||
cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });
|
|
||||||
$loadingOnDialog.remove();
|
|
||||||
$healthCheckDialog.dialog('destroy');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, g_queryAsyncJobResultInterval);
|
|
||||||
},
|
|
||||||
|
|
||||||
error:function(json){
|
|
||||||
|
|
||||||
cloudStack.dialog.notice({message: _s(json.responseText)}); //Error message in the API needs to be improved
|
|
||||||
$healthCheckDialog.dialog('close');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else { //policy exists already
|
|
||||||
buttons.push(
|
|
||||||
//Update Button (begin) - call delete API first, then create API
|
|
||||||
{
|
|
||||||
text: _l('Update'),
|
|
||||||
'class': 'ok',
|
|
||||||
click: function() {
|
|
||||||
$loadingOnDialog.appendTo($healthCheckDialog);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('deleteLBHealthCheckPolicy'),
|
|
||||||
data: {
|
|
||||||
id : policyObj.id
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var jobId = json.deletelbhealthcheckpolicyresponse.jobid;
|
|
||||||
var deleteLBHealthCheckPolicyIntervalId = setInterval(function(){
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('queryAsyncJobResult'),
|
|
||||||
data: {
|
|
||||||
jobid: jobId
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var result = json.queryasyncjobresultresponse;
|
|
||||||
if (result.jobstatus == 0) {
|
|
||||||
return; //Job has not completed
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clearInterval(deleteLBHealthCheckPolicyIntervalId);
|
|
||||||
|
|
||||||
if (result.jobstatus == 1) {
|
|
||||||
var formData = cloudStack.serializeForm($healthCheckDialog.find('form'));
|
|
||||||
var data = {
|
|
||||||
lbruleid: args.context.multiRules[0].id,
|
|
||||||
pingpath: formData.pingpath,
|
|
||||||
responsetimeout: formData.responsetimeout,
|
|
||||||
intervaltime: formData.healthinterval,
|
|
||||||
healthythreshold: formData.healthythreshold,
|
|
||||||
unhealthythreshold: formData.unhealthythreshold
|
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('createLBHealthCheckPolicy'),
|
|
||||||
data: data,
|
|
||||||
success: function(json) {
|
|
||||||
var jobId = json.createlbhealthcheckpolicyresponse.jobid;
|
|
||||||
var createLBHealthCheckPolicyIntervalId = setInterval(function(){
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('queryAsyncJobResult'),
|
|
||||||
data: {
|
|
||||||
jobid: jobId
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var result = json.queryasyncjobresultresponse;
|
|
||||||
if (result.jobstatus == 0) {
|
|
||||||
return; //Job has not completed
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clearInterval(createLBHealthCheckPolicyIntervalId);
|
|
||||||
|
|
||||||
if (result.jobstatus == 1) {
|
|
||||||
cloudStack.dialog.notice({ message: _l('Health Check Policy has been updated') });
|
|
||||||
$loadingOnDialog.remove();
|
|
||||||
$healthCheckDialog.dialog('destroy');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
else if (result.jobstatus == 2) {
|
|
||||||
cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });
|
|
||||||
$loadingOnDialog.remove();
|
|
||||||
$healthCheckDialog.dialog('destroy');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, g_queryAsyncJobResultInterval);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (result.jobstatus == 2) {
|
|
||||||
cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });
|
|
||||||
$loadingOnDialog.remove();
|
|
||||||
$healthCheckDialog.dialog('destroy');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, g_queryAsyncJobResultInterval);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Update Button (end)
|
|
||||||
,
|
|
||||||
//Delete Button (begin) - call delete API
|
|
||||||
{
|
|
||||||
text: _l('Delete'),
|
|
||||||
'class': 'delete',
|
|
||||||
click: function() {
|
|
||||||
$loadingOnDialog.appendTo($healthCheckDialog);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('deleteLBHealthCheckPolicy'),
|
|
||||||
data: {
|
|
||||||
id : policyObj.id
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var jobId = json.deletelbhealthcheckpolicyresponse.jobid;
|
|
||||||
var deleteLBHealthCheckPolicyIntervalId = setInterval(function(){
|
|
||||||
$.ajax({
|
|
||||||
url: createURL('queryAsyncJobResult'),
|
|
||||||
data: {
|
|
||||||
jobid: jobId
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
var result = json.queryasyncjobresultresponse;
|
|
||||||
if (result.jobstatus == 0) {
|
|
||||||
return; //Job has not completed
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clearInterval(deleteLBHealthCheckPolicyIntervalId);
|
|
||||||
|
|
||||||
if (result.jobstatus == 1) {
|
|
||||||
cloudStack.dialog.notice({ message: _l('Health Check Policy has been deleted') });
|
|
||||||
$loadingOnDialog.remove();
|
|
||||||
$healthCheckDialog.dialog('destroy');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
else if (result.jobstatus == 2) {
|
|
||||||
cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });
|
|
||||||
$loadingOnDialog.remove();
|
|
||||||
$healthCheckDialog.dialog('destroy');
|
|
||||||
$('.overlay').remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, g_queryAsyncJobResultInterval);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Delete Button (end)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$healthCheckDialog.dialog({
|
|
||||||
title: 'Health Check Wizard',
|
|
||||||
width: 600,
|
|
||||||
height: 600,
|
|
||||||
draggable: true,
|
|
||||||
closeonEscape: false,
|
|
||||||
overflow:'auto',
|
|
||||||
open:function() {
|
|
||||||
$("button").each(function(){
|
|
||||||
$(this).attr("style", "left: 400px; position: relative; margin-right: 5px; ");
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.ui-dialog .delete').css('left','140px');
|
|
||||||
|
|
||||||
},
|
|
||||||
buttons: buttons
|
|
||||||
}).closest('.ui-dialog').overlay();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}(jQuery, cloudStack));
|
||||||
}(jQuery, cloudStack));
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -15,152 +15,149 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.ipRules = function(args) {
|
cloudStack.ipRules = function(args) {
|
||||||
return function(detailArgs) {
|
return function(detailArgs) {
|
||||||
var context = detailArgs.context;
|
var context = detailArgs.context;
|
||||||
|
|
||||||
var portMultiEdit = function(args) {
|
var portMultiEdit = function(args) {
|
||||||
return $('<div>').multiEdit(args);
|
return $('<div>').multiEdit(args);
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeMultiEditPanel = function($item) {
|
var makeMultiEditPanel = function($item) {
|
||||||
if ($item.closest('li').hasClass('disabled'))
|
if ($item.closest('li').hasClass('disabled'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var targetId = $item.attr('net-target');
|
var targetId = $item.attr('net-target');
|
||||||
var targetName = $item.parent().find('.name').find('span').html();
|
var targetName = $item.parent().find('.name').find('span').html();
|
||||||
var target = args[targetId];
|
var target = args[targetId];
|
||||||
|
|
||||||
var $browser = $item.closest('.detail-view').data('view-args').$browser;
|
var $browser = $item.closest('.detail-view').data('view-args').$browser;
|
||||||
|
|
||||||
$browser.cloudBrowser('addPanel', {
|
|
||||||
title: targetName,
|
|
||||||
maximizeIfSelected: true,
|
|
||||||
complete: function($newPanel) {
|
|
||||||
$newPanel.detailView({
|
|
||||||
$browser: $browser,
|
|
||||||
name: targetId,
|
|
||||||
context: context,
|
|
||||||
tabs: {
|
|
||||||
network: {
|
|
||||||
title: targetName,
|
|
||||||
custom: function(args) {
|
|
||||||
return portMultiEdit($.extend(target, {
|
|
||||||
context: context
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var staticNATChart = function(args, includingFirewall) {
|
|
||||||
var $chart = $('#template').find('.network-chart.static-nat').clone();
|
|
||||||
var $vmName = $chart.find('li.static-nat-enabled .vmname');
|
|
||||||
var $browser = $('#browser .container');
|
|
||||||
var vmDataProvider = args.vmDataProvider;
|
|
||||||
var vmDetails = args.vmDetails;
|
|
||||||
|
|
||||||
args.staticNATDataProvider({
|
|
||||||
context: context,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
var vmID = args.data.virtualmachineid;
|
|
||||||
var vmIP = args.data.vmipaddress;
|
|
||||||
var vmName = args.data.virtualmachinename;
|
|
||||||
|
|
||||||
$vmName.append(
|
|
||||||
$('<span>').html('VM: ' + _s(vmName)),
|
|
||||||
$('<span>').html('<br/>VM IP: ' + vmIP)
|
|
||||||
);
|
|
||||||
|
|
||||||
$vmName.click(function() {
|
|
||||||
$browser.cloudBrowser('addPanel', {
|
$browser.cloudBrowser('addPanel', {
|
||||||
title: _l('label.static.nat.vm.details'),
|
title: targetName,
|
||||||
complete: function($newPanel) {
|
maximizeIfSelected: true,
|
||||||
vmDataProvider({
|
complete: function($newPanel) {
|
||||||
context: context,
|
$newPanel.detailView({
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
var instance = args.data;
|
|
||||||
var detailViewArgs = $.extend(true, {}, vmDetails, {
|
|
||||||
$browser: $browser,
|
$browser: $browser,
|
||||||
context: $.extend(true, {}, context, {
|
name: targetId,
|
||||||
instances: [instance]
|
context: context,
|
||||||
}),
|
tabs: {
|
||||||
jsonObj: instance,
|
network: {
|
||||||
id: instance.id
|
title: targetName,
|
||||||
});
|
custom: function(args) {
|
||||||
|
return portMultiEdit($.extend(target, {
|
||||||
// No actions available
|
context: context
|
||||||
detailViewArgs.actions = {};
|
}));
|
||||||
|
}
|
||||||
$newPanel.detailView(detailViewArgs);
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(includingFirewall == true) {
|
return true;
|
||||||
$chart.find('li.firewall .view-details').click(function() {
|
};
|
||||||
//makeMultiEditPanel($(this), { title: _l('label.nat.port.range')});
|
|
||||||
makeMultiEditPanel($(this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$chart.find('li.firewall').hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $chart;
|
var staticNATChart = function(args, includingFirewall) {
|
||||||
};
|
var $chart = $('#template').find('.network-chart.static-nat').clone();
|
||||||
|
var $vmName = $chart.find('li.static-nat-enabled .vmname');
|
||||||
|
var $browser = $('#browser .container');
|
||||||
|
var vmDataProvider = args.vmDataProvider;
|
||||||
|
var vmDetails = args.vmDetails;
|
||||||
|
|
||||||
var netChart = function(args) {
|
args.staticNATDataProvider({
|
||||||
|
context: context,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
var vmID = args.data.virtualmachineid;
|
||||||
|
var vmIP = args.data.vmipaddress;
|
||||||
|
var vmName = args.data.virtualmachinename;
|
||||||
|
|
||||||
var $chart = $('#template').find('.network-chart.normal').clone();
|
$vmName.append(
|
||||||
var preFilter = args.preFilter ? args.preFilter({
|
$('<span>').html('VM: ' + _s(vmName)),
|
||||||
items: ['firewall', 'portForwarding', 'loadBalancing'],
|
$('<span>').html('<br/>VM IP: ' + vmIP)
|
||||||
context: context
|
);
|
||||||
}) : [];
|
|
||||||
|
|
||||||
// 1. choose between staticNAT chart and non-staticNAT chart 2. filter disabled tabs
|
$vmName.click(function() {
|
||||||
if (preFilter.length) {
|
$browser.cloudBrowser('addPanel', {
|
||||||
if($.inArray('nonStaticNATChart', preFilter) != -1) { //choose static NAT chart
|
title: _l('label.static.nat.vm.details'),
|
||||||
if($.inArray('firewall', preFilter) == -1) {
|
complete: function($newPanel) {
|
||||||
return staticNATChart(args, true); //static NAT including Firewall
|
vmDataProvider({
|
||||||
}
|
context: context,
|
||||||
else {
|
response: {
|
||||||
return staticNATChart(args, false); //static NAT excluding Firewall
|
success: function(args) {
|
||||||
}
|
var instance = args.data;
|
||||||
}
|
var detailViewArgs = $.extend(true, {}, vmDetails, {
|
||||||
else { //choose non-static NAT chart
|
$browser: $browser,
|
||||||
$(preFilter).each(function() {
|
context: $.extend(true, {}, context, {
|
||||||
var id = this;
|
instances: [instance]
|
||||||
|
}),
|
||||||
|
jsonObj: instance,
|
||||||
|
id: instance.id
|
||||||
|
});
|
||||||
|
|
||||||
var $li = $chart.find('li').filter(function() {
|
// No actions available
|
||||||
return $(this).hasClass(id);
|
detailViewArgs.actions = {};
|
||||||
}).addClass('disabled');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$chart.find('.view-details').click(function() {
|
$newPanel.detailView(detailViewArgs);
|
||||||
makeMultiEditPanel($(this));
|
}
|
||||||
return false;
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return $chart;
|
if (includingFirewall == true) {
|
||||||
};
|
$chart.find('li.firewall .view-details').click(function() {
|
||||||
|
//makeMultiEditPanel($(this), { title: _l('label.nat.port.range')});
|
||||||
|
makeMultiEditPanel($(this));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$chart.find('li.firewall').hide();
|
||||||
|
}
|
||||||
|
|
||||||
return netChart(args);
|
return $chart;
|
||||||
|
};
|
||||||
|
|
||||||
|
var netChart = function(args) {
|
||||||
|
|
||||||
|
var $chart = $('#template').find('.network-chart.normal').clone();
|
||||||
|
var preFilter = args.preFilter ? args.preFilter({
|
||||||
|
items: ['firewall', 'portForwarding', 'loadBalancing'],
|
||||||
|
context: context
|
||||||
|
}) : [];
|
||||||
|
|
||||||
|
// 1. choose between staticNAT chart and non-staticNAT chart 2. filter disabled tabs
|
||||||
|
if (preFilter.length) {
|
||||||
|
if ($.inArray('nonStaticNATChart', preFilter) != -1) { //choose static NAT chart
|
||||||
|
if ($.inArray('firewall', preFilter) == -1) {
|
||||||
|
return staticNATChart(args, true); //static NAT including Firewall
|
||||||
|
} else {
|
||||||
|
return staticNATChart(args, false); //static NAT excluding Firewall
|
||||||
|
}
|
||||||
|
} else { //choose non-static NAT chart
|
||||||
|
$(preFilter).each(function() {
|
||||||
|
var id = this;
|
||||||
|
|
||||||
|
var $li = $chart.find('li').filter(function() {
|
||||||
|
return $(this).hasClass(id);
|
||||||
|
}).addClass('disabled');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart.find('.view-details').click(function() {
|
||||||
|
makeMultiEditPanel($(this));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $chart;
|
||||||
|
};
|
||||||
|
|
||||||
|
return netChart(args);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
@ -15,133 +15,135 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
/**
|
/**
|
||||||
* Login process
|
* Login process
|
||||||
*/
|
*/
|
||||||
cloudStack.uiCustom.login = function(args) {
|
cloudStack.uiCustom.login = function(args) {
|
||||||
var $container = args.$container;
|
var $container = args.$container;
|
||||||
var $login = $('#template').find('.login').clone();
|
var $login = $('#template').find('.login').clone();
|
||||||
var $form = $login.find('form');
|
var $form = $login.find('form');
|
||||||
var $inputs = $form.find('input[type=text], input[type=password]');
|
var $inputs = $form.find('input[type=text], input[type=password]');
|
||||||
var complete = args.complete;
|
var complete = args.complete;
|
||||||
var bypass = args.bypassLoginCheck && args.bypassLoginCheck();
|
var bypass = args.bypassLoginCheck && args.bypassLoginCheck();
|
||||||
|
|
||||||
// Check to see if we can bypass login screen
|
// Check to see if we can bypass login screen
|
||||||
if (bypass) {
|
if (bypass) {
|
||||||
complete({
|
|
||||||
user: bypass.user
|
|
||||||
});
|
|
||||||
$(window).trigger('cloudStack.init');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$login.appendTo('html body');
|
|
||||||
$('html body').addClass('login');
|
|
||||||
|
|
||||||
// Remove label if field was auto filled
|
|
||||||
$.each($form.find('label'), function() {
|
|
||||||
var $label = $(this);
|
|
||||||
var $input = $form.find('input').filter(function() {
|
|
||||||
return $(this).attr('name') == $label.attr('for');
|
|
||||||
});
|
|
||||||
if ($input.val()) {
|
|
||||||
$label.hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Form validation
|
|
||||||
$form.validate();
|
|
||||||
|
|
||||||
// Form label behavior
|
|
||||||
$inputs.bind('keydown focus click blur', function(event) {
|
|
||||||
var $target = $(event.target);
|
|
||||||
var $label = $form.find('label').filter(function() {
|
|
||||||
return $(this).attr('for') == $target.attr('name');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (event.type == 'keydown') {
|
|
||||||
$label.hide();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else if (event.type == 'blur') {
|
|
||||||
if ($target.hasClass('first-input')) {
|
|
||||||
$target.removeClass('first-input');
|
|
||||||
}
|
|
||||||
if (!$(this).val()) {
|
|
||||||
$label.show();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!$target.hasClass('first-input')) {
|
|
||||||
$label.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!args.hasLogo) $login.addClass('nologo');
|
|
||||||
|
|
||||||
// Labels cause related input to be focused
|
|
||||||
$login.find('label').click(function() {
|
|
||||||
var $input = $inputs.filter('[name=' + $(this).attr('for') + ']');
|
|
||||||
var $label = $(this);
|
|
||||||
|
|
||||||
$input.focus();
|
|
||||||
$label.hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
$inputs.filter(':first').addClass('first-input').focus();
|
|
||||||
|
|
||||||
// Login action
|
|
||||||
$login.find('input[type=submit]').click(function() {
|
|
||||||
if (!$form.valid()) return false;
|
|
||||||
|
|
||||||
var data = cloudStack.serializeForm($form);
|
|
||||||
|
|
||||||
args.loginAction({
|
|
||||||
data: data,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
$login.remove();
|
|
||||||
$('html body').removeClass('login');
|
|
||||||
complete({
|
complete({
|
||||||
user: args.data.user
|
user: bypass.user
|
||||||
});
|
});
|
||||||
},
|
$(window).trigger('cloudStack.init');
|
||||||
error: function(args) {
|
|
||||||
cloudStack.dialog.notice({ message: args });
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
$login.appendTo('html body');
|
||||||
});
|
$('html body').addClass('login');
|
||||||
|
|
||||||
// Select language
|
// Remove label if field was auto filled
|
||||||
var $languageSelect = $login.find('select[name=language]');
|
$.each($form.find('label'), function() {
|
||||||
$languageSelect.change(function() {
|
var $label = $(this);
|
||||||
if($(this).val() != '') //language dropdown is not blank
|
var $input = $form.find('input').filter(function() {
|
||||||
$.cookie('lang', $(this).val()); //the selected option in language dropdown will be used (instead of browser's default language)
|
return $(this).attr('name') == $label.attr('for');
|
||||||
else //language dropdown is blank
|
});
|
||||||
$.cookie('lang', null); //null $.cookie('lang'), so browser's default language will be used.
|
if ($input.val()) {
|
||||||
document.location.reload();
|
$label.hide();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$languageSelect.val($.cookie('lang'));
|
// Form validation
|
||||||
|
$form.validate();
|
||||||
|
|
||||||
// Hide login screen, mainly for SSO
|
// Form label behavior
|
||||||
if (args.hideLoginScreen) {
|
$inputs.bind('keydown focus click blur', function(event) {
|
||||||
$login.children().hide();
|
var $target = $(event.target);
|
||||||
$login.append($('<div>').addClass('loading-overlay').append(
|
var $label = $form.find('label').filter(function() {
|
||||||
$('<span>').html(
|
return $(this).attr('for') == $target.attr('name');
|
||||||
// _l is not set yet, so localize directly to dictionary
|
});
|
||||||
// [should fix in future]
|
|
||||||
dictionary['label.loading'] + '...'
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$(window).trigger('cloudStack.init');
|
if (event.type == 'keydown') {
|
||||||
};
|
$label.hide();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if (event.type == 'blur') {
|
||||||
|
if ($target.hasClass('first-input')) {
|
||||||
|
$target.removeClass('first-input');
|
||||||
|
}
|
||||||
|
if (!$(this).val()) {
|
||||||
|
$label.show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!$target.hasClass('first-input')) {
|
||||||
|
$label.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!args.hasLogo) $login.addClass('nologo');
|
||||||
|
|
||||||
|
// Labels cause related input to be focused
|
||||||
|
$login.find('label').click(function() {
|
||||||
|
var $input = $inputs.filter('[name=' + $(this).attr('for') + ']');
|
||||||
|
var $label = $(this);
|
||||||
|
|
||||||
|
$input.focus();
|
||||||
|
$label.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
$inputs.filter(':first').addClass('first-input').focus();
|
||||||
|
|
||||||
|
// Login action
|
||||||
|
$login.find('input[type=submit]').click(function() {
|
||||||
|
if (!$form.valid()) return false;
|
||||||
|
|
||||||
|
var data = cloudStack.serializeForm($form);
|
||||||
|
|
||||||
|
args.loginAction({
|
||||||
|
data: data,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
$login.remove();
|
||||||
|
$('html body').removeClass('login');
|
||||||
|
complete({
|
||||||
|
user: args.data.user
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(args) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: args
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Select language
|
||||||
|
var $languageSelect = $login.find('select[name=language]');
|
||||||
|
$languageSelect.change(function() {
|
||||||
|
if ($(this).val() != '') //language dropdown is not blank
|
||||||
|
$.cookie('lang', $(this).val()); //the selected option in language dropdown will be used (instead of browser's default language)
|
||||||
|
else //language dropdown is blank
|
||||||
|
$.cookie('lang', null); //null $.cookie('lang'), so browser's default language will be used.
|
||||||
|
document.location.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
$languageSelect.val($.cookie('lang'));
|
||||||
|
|
||||||
|
// Hide login screen, mainly for SSO
|
||||||
|
if (args.hideLoginScreen) {
|
||||||
|
$login.children().hide();
|
||||||
|
$login.append($('<div>').addClass('loading-overlay').append(
|
||||||
|
$('<span>').html(
|
||||||
|
// _l is not set yet, so localize directly to dictionary
|
||||||
|
// [should fix in future]
|
||||||
|
dictionary['label.loading'] + '...'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$(window).trigger('cloudStack.init');
|
||||||
|
};
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
@ -15,123 +15,139 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function(cloudStack, $) {
|
(function(cloudStack, $) {
|
||||||
cloudStack.uiCustom.physicalResources = function(args) {
|
cloudStack.uiCustom.physicalResources = function(args) {
|
||||||
var listView = function(targetID) {
|
var listView = function(targetID) {
|
||||||
var target = args.sections.physicalResources.listView[targetID];
|
var target = args.sections.physicalResources.listView[targetID];
|
||||||
var listViewArgs = $.isFunction(target) ? target() : target;
|
var listViewArgs = $.isFunction(target) ? target() : target;
|
||||||
|
|
||||||
return $('<div>').listView(
|
return $('<div>').listView(
|
||||||
(listViewArgs.listView || listViewArgs.sections) ? listViewArgs : { listView: listViewArgs }
|
(listViewArgs.listView || listViewArgs.sections) ? listViewArgs : {
|
||||||
);
|
listView: listViewArgs
|
||||||
};
|
}
|
||||||
var $dashboard = $('#template').find('.system-dashboard-view').clone();
|
);
|
||||||
var getData = function() {
|
};
|
||||||
// Populate data
|
var $dashboard = $('#template').find('.system-dashboard-view').clone();
|
||||||
$dashboard.find('[data-item]').hide();
|
var getData = function() {
|
||||||
cloudStack.sections.system.dashboard.dataProvider({
|
// Populate data
|
||||||
response: {
|
$dashboard.find('[data-item]').hide();
|
||||||
success: function(args) {
|
cloudStack.sections.system.dashboard.dataProvider({
|
||||||
var data = args.data;
|
response: {
|
||||||
$.each(data, function(key, value) {
|
success: function(args) {
|
||||||
var $elem = $dashboard.find('[data-item=' + key + ']');
|
var data = args.data;
|
||||||
$elem.hide().html(value).fadeIn();
|
$.each(data, function(key, value) {
|
||||||
});
|
var $elem = $dashboard.find('[data-item=' + key + ']');
|
||||||
}
|
$elem.hide().html(value).fadeIn();
|
||||||
}
|
});
|
||||||
});
|
|
||||||
};
|
|
||||||
var resourceChart = function(args) {
|
|
||||||
getData();
|
|
||||||
return $dashboard
|
|
||||||
.click(function(event) {
|
|
||||||
var $target = $(event.target);
|
|
||||||
if ($target.closest('[view-all-target]').size()) {
|
|
||||||
var targetID = $target.closest('[view-all-target]').attr('view-all-target');
|
|
||||||
args.$browser.cloudBrowser('addPanel', {
|
|
||||||
title: $target.closest('[view-all-title]').attr('view-all-title'),
|
|
||||||
data: '',
|
|
||||||
noSelectPanel: true,
|
|
||||||
maximizeIfSelected: true,
|
|
||||||
complete: function($newPanel) {
|
|
||||||
listView(targetID).appendTo($newPanel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
$(window).bind('cloudStack.fullRefresh cloudStack.updateResources', function() {
|
|
||||||
if ($dashboard.is(':visible')) {
|
|
||||||
getData();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return function(args) {
|
|
||||||
$dashboard.find('#update_ssl_button').click(function() {
|
|
||||||
cloudStack.dialog.createForm({
|
|
||||||
form: {
|
|
||||||
title: 'label.update.ssl',
|
|
||||||
desc: 'message.update.ssl',
|
|
||||||
fields: {
|
|
||||||
certificate: { label: 'label.certificate', isTextarea: true },
|
|
||||||
privatekey: { label: 'label.privatekey', isTextarea: true },
|
|
||||||
domainsuffix: { label: 'label.domain.suffix' }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
after: function(args) {
|
|
||||||
var $loading = $('<div>').addClass('loading-overlay');
|
|
||||||
$('.system-dashboard-view:visible').prepend($loading);
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: createURL('uploadCustomCertificate'),
|
|
||||||
data: {
|
|
||||||
certificate: encodeURIComponent(args.data.certificate),
|
|
||||||
privatekey: encodeURIComponent(args.data.privatekey),
|
|
||||||
domainsuffix: args.data.domainsuffix
|
|
||||||
},
|
|
||||||
dataType: 'json',
|
|
||||||
success: function(json) {
|
|
||||||
var jid = json.uploadcustomcertificateresponse.jobid;
|
|
||||||
var uploadCustomCertificateIntervalID = setInterval(function() {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("queryAsyncJobResult&jobId=" + jid),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(json) {
|
|
||||||
var result = json.queryasyncjobresultresponse;
|
|
||||||
if (result.jobstatus == 0) {
|
|
||||||
return; //Job has not completed
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clearInterval(uploadCustomCertificateIntervalID);
|
|
||||||
if (result.jobstatus == 1) {
|
|
||||||
cloudStack.dialog.notice({ message: 'Update SSL Certiciate succeeded' });
|
|
||||||
}
|
|
||||||
else if (result.jobstatus == 2) {
|
|
||||||
cloudStack.dialog.notice({ message: 'Failed to update SSL Certificate. ' + _s(result.jobresult.errortext) });
|
|
||||||
}
|
|
||||||
$loading.remove();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(XMLHttpResponse) {
|
|
||||||
cloudStack.dialog.notice({ message: 'Failed to update SSL Certificate. ' + parseXMLHttpResponse(XMLHttpResponse) });
|
|
||||||
$loading.remove();
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}, g_queryAsyncJobResultInterval);
|
|
||||||
},
|
|
||||||
error: function(XMLHttpResponse) {
|
|
||||||
cloudStack.dialog.notice({ message: 'Failed to update SSL Certificate. ' + parseXMLHttpResponse(XMLHttpResponse) });
|
|
||||||
$loading.remove();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
context: {}
|
var resourceChart = function(args) {
|
||||||
|
getData();
|
||||||
|
return $dashboard
|
||||||
|
.click(function(event) {
|
||||||
|
var $target = $(event.target);
|
||||||
|
if ($target.closest('[view-all-target]').size()) {
|
||||||
|
var targetID = $target.closest('[view-all-target]').attr('view-all-target');
|
||||||
|
args.$browser.cloudBrowser('addPanel', {
|
||||||
|
title: $target.closest('[view-all-title]').attr('view-all-title'),
|
||||||
|
data: '',
|
||||||
|
noSelectPanel: true,
|
||||||
|
maximizeIfSelected: true,
|
||||||
|
complete: function($newPanel) {
|
||||||
|
listView(targetID).appendTo($newPanel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$(window).bind('cloudStack.fullRefresh cloudStack.updateResources', function() {
|
||||||
|
if ($dashboard.is(':visible')) {
|
||||||
|
getData();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return false;
|
return function(args) {
|
||||||
});
|
$dashboard.find('#update_ssl_button').click(function() {
|
||||||
$dashboard.find('#refresh_button').click(function() {
|
cloudStack.dialog.createForm({
|
||||||
getData();
|
form: {
|
||||||
return false;
|
title: 'label.update.ssl',
|
||||||
});
|
desc: 'message.update.ssl',
|
||||||
return resourceChart(args);
|
fields: {
|
||||||
|
certificate: {
|
||||||
|
label: 'label.certificate',
|
||||||
|
isTextarea: true
|
||||||
|
},
|
||||||
|
privatekey: {
|
||||||
|
label: 'label.privatekey',
|
||||||
|
isTextarea: true
|
||||||
|
},
|
||||||
|
domainsuffix: {
|
||||||
|
label: 'label.domain.suffix'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
after: function(args) {
|
||||||
|
var $loading = $('<div>').addClass('loading-overlay');
|
||||||
|
$('.system-dashboard-view:visible').prepend($loading);
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: createURL('uploadCustomCertificate'),
|
||||||
|
data: {
|
||||||
|
certificate: encodeURIComponent(args.data.certificate),
|
||||||
|
privatekey: encodeURIComponent(args.data.privatekey),
|
||||||
|
domainsuffix: args.data.domainsuffix
|
||||||
|
},
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(json) {
|
||||||
|
var jid = json.uploadcustomcertificateresponse.jobid;
|
||||||
|
var uploadCustomCertificateIntervalID = setInterval(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("queryAsyncJobResult&jobId=" + jid),
|
||||||
|
dataType: "json",
|
||||||
|
success: function(json) {
|
||||||
|
var result = json.queryasyncjobresultresponse;
|
||||||
|
if (result.jobstatus == 0) {
|
||||||
|
return; //Job has not completed
|
||||||
|
} else {
|
||||||
|
clearInterval(uploadCustomCertificateIntervalID);
|
||||||
|
if (result.jobstatus == 1) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: 'Update SSL Certiciate succeeded'
|
||||||
|
});
|
||||||
|
} else if (result.jobstatus == 2) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: 'Failed to update SSL Certificate. ' + _s(result.jobresult.errortext)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$loading.remove();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(XMLHttpResponse) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: 'Failed to update SSL Certificate. ' + parseXMLHttpResponse(XMLHttpResponse)
|
||||||
|
});
|
||||||
|
$loading.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, g_queryAsyncJobResultInterval);
|
||||||
|
},
|
||||||
|
error: function(XMLHttpResponse) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: 'Failed to update SSL Certificate. ' + parseXMLHttpResponse(XMLHttpResponse)
|
||||||
|
});
|
||||||
|
$loading.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
context: {}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$dashboard.find('#refresh_button').click(function() {
|
||||||
|
getData();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
return resourceChart(args);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}(cloudStack, jQuery));
|
}(cloudStack, jQuery));
|
||||||
|
|||||||
@ -15,95 +15,107 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
var elems = {
|
var elems = {
|
||||||
pluginItem: function(args) {
|
pluginItem: function(args) {
|
||||||
var id = args.id;
|
var id = args.id;
|
||||||
var title = args.title;
|
var title = args.title;
|
||||||
var desc = args.desc;
|
var desc = args.desc;
|
||||||
var iconURL = args.iconURL;
|
var iconURL = args.iconURL;
|
||||||
var $pluginItem = $('<li>').addClass('plugin-item').addClass(id);
|
var $pluginItem = $('<li>').addClass('plugin-item').addClass(id);
|
||||||
var $title = $('<span>').addClass('title').html(title);
|
var $title = $('<span>').addClass('title').html(title);
|
||||||
var $desc = $('<span>').addClass('desc').html(desc);
|
var $desc = $('<span>').addClass('desc').html(desc);
|
||||||
var $icon = $('<span>').addClass('icon').append(
|
var $icon = $('<span>').addClass('icon').append(
|
||||||
$('<img>').attr({ src: iconURL })
|
$('<img>').attr({
|
||||||
);
|
src: iconURL
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
$pluginItem.append(
|
$pluginItem.append(
|
||||||
$icon, $title, $desc
|
$icon, $title, $desc
|
||||||
);
|
);
|
||||||
|
|
||||||
return $pluginItem;
|
return $pluginItem;
|
||||||
},
|
},
|
||||||
pluginListing: function(args) {
|
pluginListing: function(args) {
|
||||||
var plugins = args.plugins;
|
var plugins = args.plugins;
|
||||||
var $plugins = $('<ul>');
|
var $plugins = $('<ul>');
|
||||||
var $pluginsListing = $('<div>').addClass('plugins-listing');
|
var $pluginsListing = $('<div>').addClass('plugins-listing');
|
||||||
|
|
||||||
$(plugins).each(function() {
|
$(plugins).each(function() {
|
||||||
var plugin = this;
|
var plugin = this;
|
||||||
var $plugin = elems.pluginItem({
|
var $plugin = elems.pluginItem({
|
||||||
id: plugin.id,
|
id: plugin.id,
|
||||||
title: plugin.title,
|
title: plugin.title,
|
||||||
desc: plugin.desc,
|
desc: plugin.desc,
|
||||||
iconURL: 'plugins/' + plugin.id + '/icon.png'
|
iconURL: 'plugins/' + plugin.id + '/icon.png'
|
||||||
});
|
});
|
||||||
var $browser = $('#browser .container');
|
var $browser = $('#browser .container');
|
||||||
|
|
||||||
$plugin.click(function() {
|
$plugin.click(function() {
|
||||||
$browser.cloudBrowser('addPanel', {
|
$browser.cloudBrowser('addPanel', {
|
||||||
title: plugin.title,
|
title: plugin.title,
|
||||||
$parent: $('.panel:first'),
|
$parent: $('.panel:first'),
|
||||||
complete: function($panel) {
|
complete: function($panel) {
|
||||||
$panel.detailView({
|
$panel.detailView({
|
||||||
name: 'Plugin details',
|
name: 'Plugin details',
|
||||||
tabs: {
|
tabs: {
|
||||||
details: {
|
details: {
|
||||||
title: 'label.plugin.details',
|
title: 'label.plugin.details',
|
||||||
fields: [
|
fields: [{
|
||||||
{
|
name: {
|
||||||
name: { label: 'label.name' }
|
label: 'label.name'
|
||||||
},
|
}
|
||||||
{
|
}, {
|
||||||
desc: { label: 'label.description' },
|
desc: {
|
||||||
externalLink: {
|
label: 'label.description'
|
||||||
isExternalLink: true,
|
},
|
||||||
label: 'label.external.link'
|
externalLink: {
|
||||||
|
isExternalLink: true,
|
||||||
|
label: 'label.external.link'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
authorName: {
|
||||||
|
label: 'label.author.name'
|
||||||
|
},
|
||||||
|
authorEmail: {
|
||||||
|
label: 'label.author.email'
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
label: 'label.id'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
dataProvider: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
data: plugin
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
{
|
});
|
||||||
authorName: { label: 'label.author.name' },
|
|
||||||
authorEmail: { label: 'label.author.email' },
|
$plugin.appendTo($plugins);
|
||||||
id: { label: 'label.id' }
|
});
|
||||||
}
|
|
||||||
],
|
$pluginsListing.append($plugins);
|
||||||
dataProvider: function(args) {
|
|
||||||
args.response.success({ data: plugin });
|
return $pluginsListing;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
});
|
cloudStack.uiCustom.pluginListing = function() {
|
||||||
}
|
var plugins = cloudStack.plugins;
|
||||||
});
|
|
||||||
|
return elems.pluginListing({
|
||||||
|
plugins: $(plugins).map(function(index, pluginID) {
|
||||||
|
var plugin = cloudStack.plugins[pluginID].config;
|
||||||
|
|
||||||
|
return $.extend(plugin, {
|
||||||
|
id: pluginID
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
};
|
||||||
$plugin.appendTo($plugins);
|
|
||||||
});
|
|
||||||
|
|
||||||
$pluginsListing.append($plugins);
|
|
||||||
|
|
||||||
return $pluginsListing;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
cloudStack.uiCustom.pluginListing = function() {
|
|
||||||
var plugins = cloudStack.plugins;
|
|
||||||
|
|
||||||
return elems.pluginListing({
|
|
||||||
plugins: $(plugins).map(function(index, pluginID) {
|
|
||||||
var plugin = cloudStack.plugins[pluginID].config;
|
|
||||||
|
|
||||||
return $.extend(plugin, { id: pluginID });
|
|
||||||
})
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|||||||
@ -16,51 +16,52 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
$(window).bind('cloudStack.ready', function() {
|
$(window).bind('cloudStack.ready', function() {
|
||||||
var $header = $('#header .controls');
|
var $header = $('#header .controls');
|
||||||
var $projectSwitcher = $('<div>').addClass('project-switcher');
|
var $projectSwitcher = $('<div>').addClass('project-switcher');
|
||||||
var $projectSelect = $('<select>').append(
|
var $projectSelect = $('<select>').append(
|
||||||
$('<option>').attr('value', '-1').html(_l('Default view'))
|
$('<option>').attr('value', '-1').html(_l('Default view'))
|
||||||
);
|
);
|
||||||
var $label = $('<label>').html('Project:');
|
var $label = $('<label>').html('Project:');
|
||||||
|
|
||||||
// Get project list
|
// Get project list
|
||||||
cloudStack.projects.dataProvider({
|
cloudStack.projects.dataProvider({
|
||||||
context: cloudStack.context,
|
context: cloudStack.context,
|
||||||
response: {
|
response: {
|
||||||
success: function(args) {
|
success: function(args) {
|
||||||
var projects = args.data;
|
var projects = args.data;
|
||||||
|
|
||||||
$(projects).map(function(index, project) {
|
$(projects).map(function(index, project) {
|
||||||
var $option = $('<option>').val(_s(project.id));
|
var $option = $('<option>').val(_s(project.id));
|
||||||
|
|
||||||
$option.html(_s(project.displaytext ? project.displaytext : project.name));
|
$option.html(_s(project.displaytext ? project.displaytext : project.name));
|
||||||
$option.appendTo($projectSelect);
|
$option.appendTo($projectSelect);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
error: function() {}
|
error: function() {}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$projectSwitcher.append($label, $projectSelect);
|
||||||
|
$projectSwitcher.insertBefore($header.find('.region-switcher'));
|
||||||
|
|
||||||
|
// Change project event
|
||||||
|
$projectSelect.change(function() {
|
||||||
|
var projectID = $projectSelect.val();
|
||||||
|
|
||||||
|
if (projectID != -1) {
|
||||||
|
cloudStack.context.projects = [{
|
||||||
|
id: projectID
|
||||||
|
}];
|
||||||
|
|
||||||
|
cloudStack.uiCustom.projects({
|
||||||
|
alreadySelected: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cloudStack.context.projects = null;
|
||||||
|
$('#cloudStack3-container').removeClass('project-view');
|
||||||
|
$('#navigation li.dashboard').click();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$projectSwitcher.append($label, $projectSelect);
|
|
||||||
$projectSwitcher.insertBefore($header.find('.region-switcher'));
|
|
||||||
|
|
||||||
// Change project event
|
|
||||||
$projectSelect.change(function() {
|
|
||||||
var projectID = $projectSelect.val();
|
|
||||||
|
|
||||||
if (projectID != -1) {
|
|
||||||
cloudStack.context.projects = [{
|
|
||||||
id: projectID
|
|
||||||
}];
|
|
||||||
|
|
||||||
cloudStack.uiCustom.projects({ alreadySelected: true });
|
|
||||||
} else {
|
|
||||||
cloudStack.context.projects = null;
|
|
||||||
$('#cloudStack3-container').removeClass('project-view');
|
|
||||||
$('#navigation li.dashboard').click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -15,200 +15,201 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function(cloudStack, $) {
|
(function(cloudStack, $) {
|
||||||
cloudStack.uiCustom.recurringSnapshots = function(args) {
|
cloudStack.uiCustom.recurringSnapshots = function(args) {
|
||||||
var desc = args.desc;
|
var desc = args.desc;
|
||||||
var selects = args.selects;
|
var selects = args.selects;
|
||||||
var actions = args.actions;
|
var actions = args.actions;
|
||||||
var dataProvider = args.dataProvider;
|
var dataProvider = args.dataProvider;
|
||||||
|
|
||||||
return function(args) {
|
return function(args) {
|
||||||
var $snapshots = $('#template').find('.recurring-snapshots').clone();
|
var $snapshots = $('#template').find('.recurring-snapshots').clone();
|
||||||
var context = args.context;
|
var context = args.context;
|
||||||
|
|
||||||
// Update labels
|
// Update labels
|
||||||
$snapshots.find('.forms ul li.hourly a').html(_l('label.hourly'));
|
$snapshots.find('.forms ul li.hourly a').html(_l('label.hourly'));
|
||||||
$snapshots.find('.forms ul li.daily a').html(_l('label.daily'));
|
$snapshots.find('.forms ul li.daily a').html(_l('label.daily'));
|
||||||
$snapshots.find('.forms ul li.weekly a').html(_l('label.weekly'));
|
$snapshots.find('.forms ul li.weekly a').html(_l('label.weekly'));
|
||||||
$snapshots.find('.forms ul li.monthly a').html(_l('label.monthly'));
|
$snapshots.find('.forms ul li.monthly a').html(_l('label.monthly'));
|
||||||
$snapshots.find('.field.timezone .name').html(_l('label.timezone'));
|
$snapshots.find('.field.timezone .name').html(_l('label.timezone'));
|
||||||
$snapshots.find('.field.time .name').html(_l('label.time'));
|
$snapshots.find('.field.time .name').html(_l('label.time'));
|
||||||
$snapshots.find('.field.time .value label').html(_l('label.minute.past.hour'));
|
$snapshots.find('.field.time .value label').html(_l('label.minute.past.hour'));
|
||||||
$snapshots.find('.add-snapshot-action.add').html(_l('label.add'));
|
$snapshots.find('.add-snapshot-action.add').html(_l('label.add'));
|
||||||
|
|
||||||
// Get description
|
// Get description
|
||||||
$snapshots.find('.desc').html(_l(desc));
|
$snapshots.find('.desc').html(_l(desc));
|
||||||
|
|
||||||
// Snapshot type tabs
|
// Snapshot type tabs
|
||||||
$snapshots.find('.forms').tabs();
|
$snapshots.find('.forms').tabs();
|
||||||
|
|
||||||
// Populate selects
|
// Populate selects
|
||||||
$snapshots.find('form select').each(function() {
|
$snapshots.find('form select').each(function() {
|
||||||
var $select = $(this);
|
var $select = $(this);
|
||||||
var selectData = selects[$select.attr('name')];
|
var selectData = selects[$select.attr('name')];
|
||||||
|
|
||||||
if (selectData) {
|
if (selectData) {
|
||||||
selectData({
|
selectData({
|
||||||
response: {
|
response: {
|
||||||
success: function(args) {
|
success: function(args) {
|
||||||
$(args.data).each(function() {
|
$(args.data).each(function() {
|
||||||
var $option = $('<option>').appendTo($select);
|
var $option = $('<option>').appendTo($select);
|
||||||
|
|
||||||
$option.val(this.id).html(_l(this.name));
|
$option.val(this.id).html(_l(this.name));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Form validation
|
|
||||||
$snapshots.find('form').validate();
|
|
||||||
|
|
||||||
// Add snapshot
|
|
||||||
$snapshots.find('.add-snapshot-action.add').click(function() {
|
|
||||||
var $form = $snapshots.find('form:visible');
|
|
||||||
|
|
||||||
if (!$form.valid()) return false;
|
|
||||||
|
|
||||||
var formData = cloudStack.serializeForm($form);
|
|
||||||
|
|
||||||
actions.add({
|
|
||||||
context: context,
|
|
||||||
snapshot: formData,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
var $snapshotRow = $snapshots.find('.scheduled-snapshots tr').filter(function() {
|
|
||||||
return $(this).index() == args.data.type;
|
|
||||||
}).addClass('active').show();
|
|
||||||
|
|
||||||
$snapshotRow.data('json-obj', args.data);
|
|
||||||
|
|
||||||
// Update fields
|
|
||||||
$snapshotRow.find('td.time span').html(args.data.time);
|
|
||||||
$snapshotRow.find('td.day-of-week span').html(_l(
|
|
||||||
args.data['day-of-week'] ?
|
|
||||||
$snapshots.find('select[name=day-of-week] option').filter(function() {
|
|
||||||
return $(this).val() == args.data['day-of-week'];
|
|
||||||
}).html() :
|
|
||||||
args.data['day-of-month']
|
|
||||||
));
|
|
||||||
$snapshotRow.find('td.timezone span').html(
|
|
||||||
$snapshots.find('select[name=timezone] option').filter(function() {
|
|
||||||
return $(this).val() == args.data['timezone'];
|
|
||||||
}).html()
|
|
||||||
);
|
|
||||||
$snapshotRow.find('td.keep span').html(args.data.keep);
|
|
||||||
|
|
||||||
$(':ui-dialog').dialog('option', 'position', 'center');
|
|
||||||
|
|
||||||
refreshSnapshotTabs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Enable/disable snapshot tabs based on table contents;
|
|
||||||
var refreshSnapshotTabs = function() {
|
|
||||||
$snapshots.find('li').each(function() {
|
|
||||||
var index = $(this).index();
|
|
||||||
var $tr = $snapshots.find('tr').filter(function() {
|
|
||||||
return $(this).index() == index;
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($tr.size() && $tr.hasClass('active')) { $(this).addClass('disabled ui-state-disabled'); }
|
|
||||||
else { $(this).removeClass('disabled ui-state-disabled'); }
|
|
||||||
|
|
||||||
if ($(this).is('.ui-tabs-selected.ui-state-disabled')) {
|
|
||||||
$snapshots.find('form').show();
|
|
||||||
|
|
||||||
if ($snapshots.find('li.ui-state-disabled').size() == $snapshots.find('li').size()) {
|
|
||||||
$snapshots.find('form').hide();
|
|
||||||
} else {
|
|
||||||
$snapshots.find('li:not(.ui-state-disabled):first a').click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Remove snapshot
|
|
||||||
$snapshots.find('.action.destroy').click(function() {
|
|
||||||
var $tr = $(this).closest('tr');
|
|
||||||
actions.remove({
|
|
||||||
context: context,
|
|
||||||
snapshot: $tr.data('json-obj'),
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
$tr.hide().removeClass('active');
|
|
||||||
$(':ui-dialog').dialog('option', 'position', 'center');
|
|
||||||
|
|
||||||
refreshSnapshotTabs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get existing data
|
|
||||||
dataProvider({
|
|
||||||
context: context,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
$(args.data).each(function() {
|
|
||||||
var snapshot = this;
|
|
||||||
|
|
||||||
// Get matching table row
|
|
||||||
var $tr = $snapshots.find('tr').filter(function() {
|
|
||||||
return $(this).index() == snapshot.type;
|
|
||||||
}).addClass('active').show();
|
|
||||||
|
|
||||||
$tr.data('json-obj', snapshot);
|
|
||||||
|
|
||||||
$tr.find('td.time span').html(snapshot.time);
|
|
||||||
$tr.find('td.timezone span').html(
|
|
||||||
$snapshots.find('select[name=timezone] option').filter(function() {
|
|
||||||
return $(this).val() == snapshot['timezone'];
|
|
||||||
}).html()
|
|
||||||
);
|
|
||||||
$tr.find('td.keep span').html(snapshot.keep);
|
|
||||||
$tr.find('td.day-of-week span').html(
|
|
||||||
snapshot['day-of-week'] ?
|
|
||||||
$snapshots.find('select[name=day-of-week] option').filter(function() {
|
|
||||||
return $(this).val() == snapshot['day-of-week'];
|
|
||||||
}).html() :
|
|
||||||
snapshot['day-of-month']
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
refreshSnapshotTabs();
|
// Form validation
|
||||||
}
|
$snapshots.find('form').validate();
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create dialog
|
// Add snapshot
|
||||||
var $dialog = $snapshots.dialog({
|
$snapshots.find('.add-snapshot-action.add').click(function() {
|
||||||
title: _l('label.action.recurring.snapshot'),
|
var $form = $snapshots.find('form:visible');
|
||||||
dialogClass: 'recurring-snapshots',
|
|
||||||
closeOnEscape:false,
|
|
||||||
width: 600,
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: _l('label.done'),
|
|
||||||
'class': 'ok',
|
|
||||||
click: function() {
|
|
||||||
$dialog.fadeOut(function() {
|
|
||||||
$dialog.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('div.overlay').fadeOut(function() {
|
if (!$form.valid()) return false;
|
||||||
$('div.overlay').remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}).closest('.ui-dialog').overlay();
|
|
||||||
|
|
||||||
return $dialog;
|
var formData = cloudStack.serializeForm($form);
|
||||||
|
|
||||||
|
actions.add({
|
||||||
|
context: context,
|
||||||
|
snapshot: formData,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
var $snapshotRow = $snapshots.find('.scheduled-snapshots tr').filter(function() {
|
||||||
|
return $(this).index() == args.data.type;
|
||||||
|
}).addClass('active').show();
|
||||||
|
|
||||||
|
$snapshotRow.data('json-obj', args.data);
|
||||||
|
|
||||||
|
// Update fields
|
||||||
|
$snapshotRow.find('td.time span').html(args.data.time);
|
||||||
|
$snapshotRow.find('td.day-of-week span').html(_l(
|
||||||
|
args.data['day-of-week'] ?
|
||||||
|
$snapshots.find('select[name=day-of-week] option').filter(function() {
|
||||||
|
return $(this).val() == args.data['day-of-week'];
|
||||||
|
}).html() :
|
||||||
|
args.data['day-of-month']
|
||||||
|
));
|
||||||
|
$snapshotRow.find('td.timezone span').html(
|
||||||
|
$snapshots.find('select[name=timezone] option').filter(function() {
|
||||||
|
return $(this).val() == args.data['timezone'];
|
||||||
|
}).html()
|
||||||
|
);
|
||||||
|
$snapshotRow.find('td.keep span').html(args.data.keep);
|
||||||
|
|
||||||
|
$(':ui-dialog').dialog('option', 'position', 'center');
|
||||||
|
|
||||||
|
refreshSnapshotTabs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enable/disable snapshot tabs based on table contents;
|
||||||
|
var refreshSnapshotTabs = function() {
|
||||||
|
$snapshots.find('li').each(function() {
|
||||||
|
var index = $(this).index();
|
||||||
|
var $tr = $snapshots.find('tr').filter(function() {
|
||||||
|
return $(this).index() == index;
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($tr.size() && $tr.hasClass('active')) {
|
||||||
|
$(this).addClass('disabled ui-state-disabled');
|
||||||
|
} else {
|
||||||
|
$(this).removeClass('disabled ui-state-disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($(this).is('.ui-tabs-selected.ui-state-disabled')) {
|
||||||
|
$snapshots.find('form').show();
|
||||||
|
|
||||||
|
if ($snapshots.find('li.ui-state-disabled').size() == $snapshots.find('li').size()) {
|
||||||
|
$snapshots.find('form').hide();
|
||||||
|
} else {
|
||||||
|
$snapshots.find('li:not(.ui-state-disabled):first a').click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Remove snapshot
|
||||||
|
$snapshots.find('.action.destroy').click(function() {
|
||||||
|
var $tr = $(this).closest('tr');
|
||||||
|
actions.remove({
|
||||||
|
context: context,
|
||||||
|
snapshot: $tr.data('json-obj'),
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
$tr.hide().removeClass('active');
|
||||||
|
$(':ui-dialog').dialog('option', 'position', 'center');
|
||||||
|
|
||||||
|
refreshSnapshotTabs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get existing data
|
||||||
|
dataProvider({
|
||||||
|
context: context,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
$(args.data).each(function() {
|
||||||
|
var snapshot = this;
|
||||||
|
|
||||||
|
// Get matching table row
|
||||||
|
var $tr = $snapshots.find('tr').filter(function() {
|
||||||
|
return $(this).index() == snapshot.type;
|
||||||
|
}).addClass('active').show();
|
||||||
|
|
||||||
|
$tr.data('json-obj', snapshot);
|
||||||
|
|
||||||
|
$tr.find('td.time span').html(snapshot.time);
|
||||||
|
$tr.find('td.timezone span').html(
|
||||||
|
$snapshots.find('select[name=timezone] option').filter(function() {
|
||||||
|
return $(this).val() == snapshot['timezone'];
|
||||||
|
}).html()
|
||||||
|
);
|
||||||
|
$tr.find('td.keep span').html(snapshot.keep);
|
||||||
|
$tr.find('td.day-of-week span').html(
|
||||||
|
snapshot['day-of-week'] ?
|
||||||
|
$snapshots.find('select[name=day-of-week] option').filter(function() {
|
||||||
|
return $(this).val() == snapshot['day-of-week'];
|
||||||
|
}).html() :
|
||||||
|
snapshot['day-of-month']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
refreshSnapshotTabs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create dialog
|
||||||
|
var $dialog = $snapshots.dialog({
|
||||||
|
title: _l('label.action.recurring.snapshot'),
|
||||||
|
dialogClass: 'recurring-snapshots',
|
||||||
|
closeOnEscape: false,
|
||||||
|
width: 600,
|
||||||
|
buttons: [{
|
||||||
|
text: _l('label.done'),
|
||||||
|
'class': 'ok',
|
||||||
|
click: function() {
|
||||||
|
$dialog.fadeOut(function() {
|
||||||
|
$dialog.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('div.overlay').fadeOut(function() {
|
||||||
|
$('div.overlay').remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}).closest('.ui-dialog').overlay();
|
||||||
|
|
||||||
|
return $dialog;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}(cloudStack, jQuery));
|
}(cloudStack, jQuery));
|
||||||
|
|||||||
@ -16,115 +16,117 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
$(window).bind('cloudStack.ready', function() {
|
$(window).bind('cloudStack.ready', function() {
|
||||||
// Region switcher
|
// Region switcher
|
||||||
var $regionList = $('<ul>');
|
var $regionList = $('<ul>');
|
||||||
|
|
||||||
// Get region listing
|
// Get region listing
|
||||||
var refreshRegions = function() {
|
var refreshRegions = function() {
|
||||||
$regionList.find('li').remove();
|
$regionList.find('li').remove();
|
||||||
cloudStack.sections.regions.regionSelector.dataProvider({
|
cloudStack.sections.regions.regionSelector.dataProvider({
|
||||||
response: {
|
response: {
|
||||||
success: function(args) {
|
success: function(args) {
|
||||||
var data = args.data;
|
var data = args.data;
|
||||||
|
|
||||||
var currentRegion = null;
|
var currentRegion = null;
|
||||||
$(data).each(function() {
|
$(data).each(function() {
|
||||||
var region = this;
|
var region = this;
|
||||||
var regionName = region.name;
|
var regionName = region.name;
|
||||||
var $li = $('<li>').append($('<span>').html(_s(region.name)));
|
var $li = $('<li>').append($('<span>').html(_s(region.name)));
|
||||||
|
|
||||||
$li.data('region-data', region);
|
$li.data('region-data', region);
|
||||||
|
|
||||||
/* e.g.
|
/* e.g.
|
||||||
region.endpoint == "http://localhost:8080/client/"
|
region.endpoint == "http://localhost:8080/client/"
|
||||||
document.location.href == "http://localhost:8080/client/#"
|
document.location.href == "http://localhost:8080/client/#"
|
||||||
*/
|
*/
|
||||||
if(document.location.href.indexOf(region.endpoint) != -1) {
|
if (document.location.href.indexOf(region.endpoint) != -1) {
|
||||||
currentRegion = region;
|
currentRegion = region;
|
||||||
$li.addClass('active');
|
$li.addClass('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
$regionList.append($li);
|
$regionList.append($li);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (currentRegion != null) {
|
||||||
|
$regionSwitcherButton.find('.title').html(_s(currentRegion.name)).attr('title', _s(currentRegion.name));
|
||||||
|
} else {
|
||||||
|
$regionSwitcherButton.find('.title').html('').attr('title', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if(currentRegion != null) {
|
$(window).bind('cloudStack.refreshRegions', refreshRegions);
|
||||||
$regionSwitcherButton.find('.title').html(_s(currentRegion.name)).attr('title', _s(currentRegion.name));
|
|
||||||
|
var $regionSelector = $('<div>').addClass('region-selector')
|
||||||
|
.append($('<div>').addClass('top-arrow'))
|
||||||
|
.append($('<h2>').html(_l('label.menu.regions')))
|
||||||
|
.append($regionList)
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('buttons')
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('button close').append($('<span>').html(_l('label.close')))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.hide();
|
||||||
|
var $regionSwitcherButton = $('<div>').addClass('region-switcher')
|
||||||
|
.attr('title', 'Select region')
|
||||||
|
.append(
|
||||||
|
$('<span>').addClass('icon').html(' '),
|
||||||
|
$('<span>').addClass('title').html('')
|
||||||
|
);
|
||||||
|
|
||||||
|
var closeRegionSelector = function(args) {
|
||||||
|
$regionSwitcherButton.removeClass('active');
|
||||||
|
$regionSelector.fadeOut(args ? args.complete : null);
|
||||||
|
$('body > .overlay').fadeOut(function() {
|
||||||
|
$('body > .overlay').remove()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var switchRegion = function(url) {
|
||||||
|
closeRegionSelector({
|
||||||
|
complete: function() {
|
||||||
|
$('#container').prepend($('<div>').addClass('loading-overlay'));
|
||||||
|
document.location.href = url;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$regionList.click(function(event) {
|
||||||
|
var $target = $(event.target);
|
||||||
|
var $li = $target.closest('li');
|
||||||
|
var region, url;
|
||||||
|
|
||||||
|
if ($li.size() && !$li.hasClass('active')) {
|
||||||
|
region = $li.data('region-data');
|
||||||
|
url = region.endpoint;
|
||||||
|
id = region.id;
|
||||||
|
|
||||||
|
if (id != '-1') {
|
||||||
|
switchRegion(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
});
|
||||||
$regionSwitcherButton.find('.title').html('').attr('title', '');
|
|
||||||
|
$regionSwitcherButton.click(function() {
|
||||||
|
if ($regionSwitcherButton.hasClass('active')) {
|
||||||
|
closeRegionSelector();
|
||||||
|
} else {
|
||||||
|
$regionSwitcherButton.addClass('active');
|
||||||
|
$regionSelector.fadeIn('fast').overlay({
|
||||||
|
closeAction: closeRegionSelector
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$(window).bind('cloudStack.refreshRegions', refreshRegions);
|
$regionSelector.find('.button.close').click(function() {
|
||||||
|
closeRegionSelector();
|
||||||
|
});
|
||||||
|
|
||||||
var $regionSelector = $('<div>').addClass('region-selector')
|
$('#header .controls .view-switcher.button:last').after($regionSwitcherButton, $regionSelector);
|
||||||
.append($('<div>').addClass('top-arrow'))
|
refreshRegions();
|
||||||
.append($('<h2>').html(_l('label.menu.regions')))
|
|
||||||
.append($regionList)
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('buttons')
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('button close').append($('<span>').html(_l('label.close')))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.hide();
|
|
||||||
var $regionSwitcherButton = $('<div>').addClass('region-switcher')
|
|
||||||
.attr('title', 'Select region')
|
|
||||||
.append(
|
|
||||||
$('<span>').addClass('icon').html(' '),
|
|
||||||
$('<span>').addClass('title').html('')
|
|
||||||
);
|
|
||||||
|
|
||||||
var closeRegionSelector = function(args) {
|
|
||||||
$regionSwitcherButton.removeClass('active');
|
|
||||||
$regionSelector.fadeOut(args ? args.complete : null);
|
|
||||||
$('body > .overlay').fadeOut(function() { $('body > .overlay').remove() });
|
|
||||||
};
|
|
||||||
|
|
||||||
var switchRegion = function(url) {
|
|
||||||
closeRegionSelector({
|
|
||||||
complete: function() {
|
|
||||||
$('#container').prepend($('<div>').addClass('loading-overlay'));
|
|
||||||
document.location.href = url;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$regionList.click(function(event) {
|
|
||||||
var $target = $(event.target);
|
|
||||||
var $li = $target.closest('li');
|
|
||||||
var region, url;
|
|
||||||
|
|
||||||
if ($li.size() && !$li.hasClass('active')) {
|
|
||||||
region = $li.data('region-data');
|
|
||||||
url = region.endpoint;
|
|
||||||
id = region.id;
|
|
||||||
|
|
||||||
if (id != '-1') {
|
|
||||||
switchRegion(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$regionSwitcherButton.click(function() {
|
|
||||||
if ($regionSwitcherButton.hasClass('active')) {
|
|
||||||
closeRegionSelector();
|
|
||||||
} else {
|
|
||||||
$regionSwitcherButton.addClass('active');
|
|
||||||
$regionSelector.fadeIn('fast').overlay({ closeAction: closeRegionSelector });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$regionSelector.find('.button.close').click(function() {
|
|
||||||
closeRegionSelector();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#header .controls .view-switcher.button:last').after($regionSwitcherButton, $regionSelector);
|
|
||||||
refreshRegions();
|
|
||||||
});
|
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|
||||||
|
|||||||
@ -15,59 +15,59 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.uiCustom.securityRules = function(args) {
|
cloudStack.uiCustom.securityRules = function(args) {
|
||||||
var multiEdit = args;
|
var multiEdit = args;
|
||||||
|
|
||||||
return function(args) {
|
return function(args) {
|
||||||
var context = args.context;
|
var context = args.context;
|
||||||
var $multi = $('<div>').addClass('security-rules').multiEdit(
|
var $multi = $('<div>').addClass('security-rules').multiEdit(
|
||||||
$.extend(true, {}, multiEdit, {
|
$.extend(true, {}, multiEdit, {
|
||||||
context: context
|
context: context
|
||||||
})
|
|
||||||
);
|
|
||||||
var $fields = $multi.find('form table').find('th, td');
|
|
||||||
var $accountFields = $fields.filter(function() {
|
|
||||||
return $(this).hasClass('accountname') ||
|
|
||||||
$(this).hasClass('securitygroupname');
|
|
||||||
});
|
|
||||||
var $cidrFields = $fields.filter(function() {
|
|
||||||
return $(this).hasClass('cidr');
|
|
||||||
});
|
|
||||||
|
|
||||||
$multi.prepend(
|
|
||||||
$('<div>').addClass('add-by')
|
|
||||||
.append($('<span>').html('Add by:'))
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('selection')
|
|
||||||
.append(
|
|
||||||
$('<input>').attr({
|
|
||||||
type: 'radio',
|
|
||||||
name: 'add-by',
|
|
||||||
checked: 'checked'
|
|
||||||
}).click(function() {
|
|
||||||
$accountFields.hide();
|
|
||||||
$cidrFields.show();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}).click()
|
|
||||||
)
|
|
||||||
.append($('<label>').html('CIDR'))
|
|
||||||
.append(
|
|
||||||
$('<input>').attr({
|
|
||||||
type: 'radio',
|
|
||||||
name: 'add-by'
|
|
||||||
}).click(function() {
|
|
||||||
$accountFields.show();
|
|
||||||
$cidrFields.hide();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
.append($('<label>').html('Account'))
|
var $fields = $multi.find('form table').find('th, td');
|
||||||
)
|
var $accountFields = $fields.filter(function() {
|
||||||
);
|
return $(this).hasClass('accountname') ||
|
||||||
|
$(this).hasClass('securitygroupname');
|
||||||
|
});
|
||||||
|
var $cidrFields = $fields.filter(function() {
|
||||||
|
return $(this).hasClass('cidr');
|
||||||
|
});
|
||||||
|
|
||||||
return $multi;
|
$multi.prepend(
|
||||||
|
$('<div>').addClass('add-by')
|
||||||
|
.append($('<span>').html('Add by:'))
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('selection')
|
||||||
|
.append(
|
||||||
|
$('<input>').attr({
|
||||||
|
type: 'radio',
|
||||||
|
name: 'add-by',
|
||||||
|
checked: 'checked'
|
||||||
|
}).click(function() {
|
||||||
|
$accountFields.hide();
|
||||||
|
$cidrFields.show();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}).click()
|
||||||
|
)
|
||||||
|
.append($('<label>').html('CIDR'))
|
||||||
|
.append(
|
||||||
|
$('<input>').attr({
|
||||||
|
type: 'radio',
|
||||||
|
name: 'add-by'
|
||||||
|
}).click(function() {
|
||||||
|
$accountFields.show();
|
||||||
|
$cidrFields.hide();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append($('<label>').html('Account'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $multi;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
@ -15,157 +15,162 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function(cloudStack, $) {
|
(function(cloudStack, $) {
|
||||||
cloudStack.uiCustom.uploadVolume = function(args) {
|
cloudStack.uiCustom.uploadVolume = function(args) {
|
||||||
var listView = args.listView;
|
var listView = args.listView;
|
||||||
var action = args.action;
|
var action = args.action;
|
||||||
|
|
||||||
var validate = function($uploadVolume) {
|
var validate = function($uploadVolume) {
|
||||||
if (!$uploadVolume.find('input[type=text]').val()) {
|
if (!$uploadVolume.find('input[type=text]').val()) {
|
||||||
cloudStack.dialog.notice({ message: _l('message.specify.url')});
|
cloudStack.dialog.notice({
|
||||||
|
message: _l('message.specify.url')
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!$uploadVolume.find(
|
|
||||||
'input[type=radio]:checked, input[type=checkbox]:checked'
|
|
||||||
).size()) {
|
|
||||||
cloudStack.dialog.notice({ message: _l('message.select.instance')});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return function(args) {
|
|
||||||
var $uploadVolume = $('<div>').addClass('upload-volume');
|
|
||||||
var context = args.context;
|
|
||||||
var topFields = function() {
|
|
||||||
var $form = $('<form>').addClass('top-fields');
|
|
||||||
var $urlLabel = $('<label>').html(_l('label.url') + ':');
|
|
||||||
var $urlField = $('<div>').addClass('field url');
|
|
||||||
var $nameLabel = $('<label>').html(_l('label.name') + ':');
|
|
||||||
var $nameField = $('<div>').addClass('field name');
|
|
||||||
var $urlInput = $('<input>').attr({
|
|
||||||
type: 'text',
|
|
||||||
name: 'url'
|
|
||||||
}).addClass('required');
|
|
||||||
var $nameInput = $('<input>').attr({
|
|
||||||
type: 'text',
|
|
||||||
name: 'name'
|
|
||||||
}).addClass('required');
|
|
||||||
|
|
||||||
$urlField.append($urlLabel, $urlInput);
|
|
||||||
$nameField.append($nameLabel, $nameInput);
|
|
||||||
$form.append($nameField, $urlField);
|
|
||||||
|
|
||||||
return $form;
|
|
||||||
};
|
|
||||||
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: 'radio',
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (!$uploadVolume.find(
|
||||||
|
'input[type=radio]:checked, input[type=checkbox]:checked'
|
||||||
|
).size()) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _l('message.select.instance')
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
$listView = $('<div>').listView(instances);
|
return function(args) {
|
||||||
|
var $uploadVolume = $('<div>').addClass('upload-volume');
|
||||||
|
var context = args.context;
|
||||||
|
var topFields = function() {
|
||||||
|
var $form = $('<form>').addClass('top-fields');
|
||||||
|
var $urlLabel = $('<label>').html(_l('label.url') + ':');
|
||||||
|
var $urlField = $('<div>').addClass('field url');
|
||||||
|
var $nameLabel = $('<label>').html(_l('label.name') + ':');
|
||||||
|
var $nameField = $('<div>').addClass('field name');
|
||||||
|
var $urlInput = $('<input>').attr({
|
||||||
|
type: 'text',
|
||||||
|
name: 'url'
|
||||||
|
}).addClass('required');
|
||||||
|
var $nameInput = $('<input>').attr({
|
||||||
|
type: 'text',
|
||||||
|
name: 'name'
|
||||||
|
}).addClass('required');
|
||||||
|
|
||||||
// Change action label
|
$urlField.append($urlLabel, $urlInput);
|
||||||
$listView.find('th.actions').html(_l('label.select'));
|
$nameField.append($nameLabel, $nameInput);
|
||||||
|
$form.append($nameField, $urlField);
|
||||||
|
|
||||||
return $listView;
|
return $form;
|
||||||
};
|
};
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
$uploadVolume.append(
|
instances.listView.actions = {
|
||||||
topFields,
|
select: {
|
||||||
$('<div>').addClass('desc').html(_l('label.select.instance.to.attach.volume.to') + ':'),
|
label: _l('label.select.instance'),
|
||||||
$('<div>').addClass('listView-container').append(
|
type: 'radio',
|
||||||
vmList({ listView: listView })
|
action: {
|
||||||
)
|
uiCustom: function(args) {
|
||||||
);
|
var $item = args.$item;
|
||||||
$uploadVolume.dialog({
|
var $input = $item.find('td.actions input:visible');
|
||||||
dialogClass: 'multi-edit-add-list panel',
|
|
||||||
width: 900,
|
|
||||||
title: _l('label.upload.volume'),
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: _l('label.upload'),
|
|
||||||
'class': 'ok',
|
|
||||||
click: function() {
|
|
||||||
if (!validate($uploadVolume)) return false;
|
|
||||||
|
|
||||||
var complete = args.complete;
|
if ($input.attr('type') == 'checkbox') {
|
||||||
var $loading = $('<div>').addClass('loading-overlay');
|
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$loading.appendTo($uploadVolume);
|
$listView = $('<div>').listView(instances);
|
||||||
action({
|
|
||||||
data: cloudStack.serializeForm($uploadVolume.find('form')),
|
// Change action label
|
||||||
context: $.extend(true, {}, context, {
|
$listView.find('th.actions').html(_l('label.select'));
|
||||||
instances: [
|
|
||||||
$uploadVolume.find('tr.multi-edit-selected').data('json-obj')
|
return $listView;
|
||||||
]
|
};
|
||||||
}),
|
|
||||||
response: {
|
$uploadVolume.append(
|
||||||
success: function(args) {
|
topFields,
|
||||||
$('.ui-dialog').fadeOut(function() {
|
$('<div>').addClass('desc').html(_l('label.select.instance.to.attach.volume.to') + ':'),
|
||||||
$('.ui-dialog').remove();
|
$('<div>').addClass('listView-container').append(
|
||||||
$(window).trigger('cloudStack.fullRefresh');
|
vmList({
|
||||||
});
|
listView: listView
|
||||||
$('div.overlay').fadeOut(function() {
|
})
|
||||||
$('div.overlay').remove();
|
)
|
||||||
});
|
);
|
||||||
complete({
|
$uploadVolume.dialog({
|
||||||
$item: $('<div>'),
|
dialogClass: 'multi-edit-add-list panel',
|
||||||
_custom: args._custom
|
width: 900,
|
||||||
});
|
title: _l('label.upload.volume'),
|
||||||
},
|
buttons: [{
|
||||||
error: function(args) {
|
text: _l('label.upload'),
|
||||||
$loading.remove();
|
'class': 'ok',
|
||||||
cloudStack.dialog.notice({ message: args });
|
click: function() {
|
||||||
}
|
if (!validate($uploadVolume)) return false;
|
||||||
}
|
|
||||||
});
|
var complete = args.complete;
|
||||||
}
|
var $loading = $('<div>').addClass('loading-overlay');
|
||||||
},
|
|
||||||
{
|
$loading.appendTo($uploadVolume);
|
||||||
text: _l('label.cancel'),
|
action({
|
||||||
'class': 'cancel',
|
data: cloudStack.serializeForm($uploadVolume.find('form')),
|
||||||
click: function() {
|
context: $.extend(true, {}, context, {
|
||||||
$('.ui-dialog').fadeOut(function() {
|
instances: [
|
||||||
$('.ui-dialog').remove();
|
$uploadVolume.find('tr.multi-edit-selected').data('json-obj')
|
||||||
});
|
]
|
||||||
$('div.overlay').fadeOut(function() {
|
}),
|
||||||
$('div.overlay').remove();
|
response: {
|
||||||
});
|
success: function(args) {
|
||||||
}
|
$('.ui-dialog').fadeOut(function() {
|
||||||
}
|
$('.ui-dialog').remove();
|
||||||
]
|
$(window).trigger('cloudStack.fullRefresh');
|
||||||
}).closest('.ui-dialog').overlay();
|
});
|
||||||
|
$('div.overlay').fadeOut(function() {
|
||||||
|
$('div.overlay').remove();
|
||||||
|
});
|
||||||
|
complete({
|
||||||
|
$item: $('<div>'),
|
||||||
|
_custom: args._custom
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(args) {
|
||||||
|
$loading.remove();
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: args
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: _l('label.cancel'),
|
||||||
|
'class': 'cancel',
|
||||||
|
click: function() {
|
||||||
|
$('.ui-dialog').fadeOut(function() {
|
||||||
|
$('.ui-dialog').remove();
|
||||||
|
});
|
||||||
|
$('div.overlay').fadeOut(function() {
|
||||||
|
$('div.overlay').remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}).closest('.ui-dialog').overlay();
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}(cloudStack, jQuery));
|
}(cloudStack, jQuery));
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -15,412 +15,440 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
/**
|
|
||||||
* Zone details chart
|
|
||||||
*/
|
|
||||||
cloudStack.uiCustom.systemChart = function(chartID) {
|
|
||||||
/**
|
/**
|
||||||
* Make view all button
|
* Zone details chart
|
||||||
*/
|
*/
|
||||||
var viewAllButton = function(args) {
|
cloudStack.uiCustom.systemChart = function(chartID) {
|
||||||
var $viewAll = $('<div>').addClass('button view-all');
|
/**
|
||||||
var $label = $('<span>').addClass('view-all-label').html(args.label ? args.label : 'View all');
|
* Make view all button
|
||||||
var $browser = args.$browser;
|
*/
|
||||||
var action = args.action;
|
var viewAllButton = function(args) {
|
||||||
// Launch a list view
|
var $viewAll = $('<div>').addClass('button view-all');
|
||||||
//var $multiple-click=$viewAll.data('multiple-click',false);
|
var $label = $('<span>').addClass('view-all-label').html(args.label ? args.label : 'View all');
|
||||||
$viewAll.click(function() {
|
var $browser = args.$browser;
|
||||||
if ($viewAll.data('multiple-click')) return false;
|
var action = args.action;
|
||||||
//@pranav-handling the multiple clicks by using a flag variable
|
// Launch a list view
|
||||||
$viewAll.data('multiple-click', true);
|
//var $multiple-click=$viewAll.data('multiple-click',false);
|
||||||
$browser.cloudBrowser('addPanel', {
|
$viewAll.click(function() {
|
||||||
title: args.title,
|
if ($viewAll.data('multiple-click')) return false;
|
||||||
maximizeIfSelected: true,
|
//@pranav-handling the multiple clicks by using a flag variable
|
||||||
complete: function($newPanel) {
|
$viewAll.data('multiple-click', true);
|
||||||
$viewAll.data('multiple-click', false);
|
$browser.cloudBrowser('addPanel', {
|
||||||
action({ $panel: $newPanel });
|
title: args.title,
|
||||||
}
|
maximizeIfSelected: true,
|
||||||
});
|
complete: function($newPanel) {
|
||||||
});
|
$viewAll.data('multiple-click', false);
|
||||||
|
action({
|
||||||
|
$panel: $newPanel
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$viewAll.append($label);
|
$viewAll.append($label);
|
||||||
|
|
||||||
return $viewAll;
|
return $viewAll;
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Chart button action generators
|
|
||||||
*/
|
|
||||||
var actions = {
|
|
||||||
/**
|
|
||||||
* Makes a list view from given zone sub-section
|
|
||||||
*/
|
|
||||||
listView: function(targetID, context) {
|
|
||||||
return function(args) {
|
|
||||||
var $elem = args.$panel;
|
|
||||||
var listView = cloudStack.sections.system.subsections[targetID];
|
|
||||||
|
|
||||||
$elem.listView($.extend(true, {}, listView, {
|
|
||||||
context: context
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
providerListView: function(context) {
|
|
||||||
return function(args) {
|
|
||||||
var $elem = args.$panel;
|
|
||||||
var listViewArgs = cloudStack.sections.system.naas.providerListView;
|
|
||||||
|
|
||||||
$elem.listView({
|
|
||||||
context: context,
|
|
||||||
listView: listViewArgs
|
|
||||||
});
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes details for a given traffic type
|
|
||||||
*/
|
|
||||||
trafficTypeDetails: function(targetID, context) {
|
|
||||||
return function(args) {
|
|
||||||
var $elem = args.$panel;
|
|
||||||
var detailViewArgs = cloudStack.sections.system.naas.mainNetworks[targetID].detailView;
|
|
||||||
|
|
||||||
$elem.detailView($.extend(true, {}, detailViewArgs, {
|
|
||||||
$browser: $('#browser .container'),
|
|
||||||
context: context
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Chart generators
|
|
||||||
*/
|
|
||||||
var charts = {
|
|
||||||
/**
|
|
||||||
* Compute tab
|
|
||||||
*/
|
|
||||||
compute: function(args) {
|
|
||||||
var $chart = $('<div>');
|
|
||||||
var $browser = $('#browser .container');
|
|
||||||
var context = args.context;
|
|
||||||
|
|
||||||
// Resource items
|
|
||||||
var computeResources = {
|
|
||||||
zone: {
|
|
||||||
label: 'Zone'
|
|
||||||
},
|
|
||||||
|
|
||||||
pods: {
|
|
||||||
label: 'Pods',
|
|
||||||
viewAll: {
|
|
||||||
action: actions.listView('pods', context)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
clusters: {
|
|
||||||
label: 'Clusters',
|
|
||||||
viewAll: {
|
|
||||||
action: actions.listView('clusters', context)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
hosts: {
|
|
||||||
label: 'Hosts',
|
|
||||||
viewAll: {
|
|
||||||
action: actions.listView('hosts', context)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
primaryStorage: {
|
|
||||||
label: 'Primary Storage',
|
|
||||||
viewAll: {
|
|
||||||
action: actions.listView('primary-storage', context)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
ucs: {
|
|
||||||
label: 'UCS',
|
|
||||||
viewAll: {
|
|
||||||
action: actions.listView('ucs', context)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
secondaryStorage: {
|
|
||||||
label: 'Secondary Storage',
|
|
||||||
viewAll: {
|
|
||||||
action: actions.listView('secondary-storage', context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chart button action generators
|
||||||
|
*/
|
||||||
|
var actions = {
|
||||||
|
/**
|
||||||
|
* Makes a list view from given zone sub-section
|
||||||
|
*/
|
||||||
|
listView: function(targetID, context) {
|
||||||
|
return function(args) {
|
||||||
|
var $elem = args.$panel;
|
||||||
|
var listView = cloudStack.sections.system.subsections[targetID];
|
||||||
|
|
||||||
var $computeResources = $('<ul>').addClass('resources');
|
$elem.listView($.extend(true, {}, listView, {
|
||||||
|
context: context
|
||||||
// Make resource items
|
}));
|
||||||
$.each(computeResources, function(id, resource) {
|
|
||||||
var $li = $('<li>');
|
|
||||||
var $label = $('<span>').addClass('label');
|
|
||||||
|
|
||||||
$li.addClass(id);
|
|
||||||
$label.html(resource.label);
|
|
||||||
$label.appendTo($li);
|
|
||||||
|
|
||||||
// View all
|
|
||||||
if (resource.viewAll) {
|
|
||||||
viewAllButton($.extend(resource.viewAll, {
|
|
||||||
title: resource.label,
|
|
||||||
$browser: $browser,
|
|
||||||
context: context
|
|
||||||
})).appendTo($li);
|
|
||||||
}
|
|
||||||
|
|
||||||
$li.appendTo($computeResources);
|
|
||||||
});
|
|
||||||
|
|
||||||
$chart.append($computeResources);
|
|
||||||
|
|
||||||
return $chart;
|
|
||||||
},
|
|
||||||
|
|
||||||
network: function(args) {
|
|
||||||
var $chart = $('<div>');
|
|
||||||
var $browser = $('#browser .container');
|
|
||||||
var $loading = $('<div>').addClass('loading-overlay');
|
|
||||||
var context = args.context;
|
|
||||||
var networkDataProvider = cloudStack.sections.system.naas.networks.dataProvider;
|
|
||||||
var trafficTypeDataProvider = cloudStack.sections.system.naas.trafficTypes.dataProvider;
|
|
||||||
|
|
||||||
$loading.appendTo($chart);
|
|
||||||
|
|
||||||
var renderChart = function(args) {
|
|
||||||
var $targetChart = args.$chart ? args.$chart : $chart;
|
|
||||||
var targetContext = $.extend(true, {}, context, {
|
|
||||||
physicalNetworks: [args.data]
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get traffic type data
|
|
||||||
trafficTypeDataProvider({
|
|
||||||
context: targetContext,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
var $networkChart = $('<div>').addClass('system-network-chart');
|
|
||||||
var $trafficTypes = $('<ul>').addClass('resources traffic-types');
|
|
||||||
|
|
||||||
$loading.remove();
|
|
||||||
|
|
||||||
var trafficTypes = {
|
|
||||||
'public': {
|
|
||||||
label: _l('label.public'),
|
|
||||||
configure: {
|
|
||||||
action: actions.trafficTypeDetails('public', targetContext)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'guest': {
|
|
||||||
label: _l('label.guest'),
|
|
||||||
configure: {
|
|
||||||
action: actions.trafficTypeDetails('guest', targetContext)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'management': {
|
|
||||||
label: _l('label.management'),
|
|
||||||
configure: {
|
|
||||||
action: actions.trafficTypeDetails('management', targetContext)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'storage': {
|
|
||||||
label: _l('label.storage'),
|
|
||||||
configure: {
|
|
||||||
action: actions.trafficTypeDetails('storage', targetContext)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'providers': {
|
|
||||||
label: _l('label.network.service.providers'),
|
|
||||||
ignoreChart: true,
|
|
||||||
dependsOn: 'guest',
|
|
||||||
configure: {
|
|
||||||
action: actions.providerListView(targetContext)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
|
||||||
var validTrafficTypes = $.map(args.data, function(trafficType) {
|
providerListView: function(context) {
|
||||||
return trafficType.name.toLowerCase();
|
return function(args) {
|
||||||
});
|
var $elem = args.$panel;
|
||||||
|
var listViewArgs = cloudStack.sections.system.naas.providerListView;
|
||||||
|
|
||||||
// Make traffic type elems
|
$elem.listView({
|
||||||
$.each(trafficTypes, function(id, trafficType) {
|
context: context,
|
||||||
if ($.inArray(id, validTrafficTypes) == -1) { //if it is not a valid traffic type
|
listView: listViewArgs
|
||||||
if(trafficType.dependsOn != null && trafficType.dependsOn.length > 0) { //if it has dependsOn
|
});
|
||||||
if($.inArray(trafficType.dependsOn, validTrafficTypes) == -1) { //if its dependsOn is not a valid traffic type, either
|
};
|
||||||
return true; //skip this item
|
},
|
||||||
}
|
|
||||||
//else, if its dependsOn is a valid traffic type, continue to Make list item (e.g. providers.dependsOn is 'guest')
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return true; //if it doesn't have dependsOn, skip this item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make list item
|
/**
|
||||||
var $li = $('<li>').addClass(id);
|
* Makes details for a given traffic type
|
||||||
var $label = $('<span>').addClass('label').html(trafficType.label);
|
*/
|
||||||
var $configureButton = viewAllButton($.extend(trafficType.configure, {
|
trafficTypeDetails: function(targetID, context) {
|
||||||
label: _l('label.configure'),
|
return function(args) {
|
||||||
title: trafficType.label,
|
var $elem = args.$panel;
|
||||||
$browser: $browser,
|
var detailViewArgs = cloudStack.sections.system.naas.mainNetworks[targetID].detailView;
|
||||||
targetContext: targetContext
|
|
||||||
}));
|
|
||||||
|
|
||||||
$li.append($label, $configureButton);
|
$elem.detailView($.extend(true, {}, detailViewArgs, {
|
||||||
$li.appendTo($trafficTypes);
|
$browser: $('#browser .container'),
|
||||||
|
context: context
|
||||||
// Make chart
|
}));
|
||||||
if (trafficType.ignoreChart)
|
};
|
||||||
return true;
|
|
||||||
|
|
||||||
var $targetChartItem = $('<div>').addClass('network-chart-item').addClass(id);
|
|
||||||
$targetChartItem.appendTo($networkChart);
|
|
||||||
});
|
|
||||||
|
|
||||||
var $switchIcon = $('<div>').addClass('network-switch-icon').append(
|
|
||||||
$('<span>').html('L2/L3 switch')
|
|
||||||
);
|
|
||||||
var $circleIcon = $('<div>').addClass('base-circle-icon');
|
|
||||||
|
|
||||||
$targetChart.append($trafficTypes, $switchIcon, $networkChart, $circleIcon);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get network data
|
/**
|
||||||
networkDataProvider({
|
* Chart generators
|
||||||
context: context,
|
*/
|
||||||
response: {
|
var charts = {
|
||||||
success: function(args) {
|
/**
|
||||||
var data = args.data;
|
* Compute tab
|
||||||
var actionFilter = args.actionFilter;
|
*/
|
||||||
|
compute: function(args) {
|
||||||
|
var $chart = $('<div>');
|
||||||
|
var $browser = $('#browser .container');
|
||||||
|
var context = args.context;
|
||||||
|
|
||||||
$chart.listView({
|
// Resource items
|
||||||
listView: $.extend(true, {}, cloudStack.sections.system.naas.networks.listView, {
|
var computeResources = {
|
||||||
dataProvider: function(args) {
|
zone: {
|
||||||
args.response.success({ actionFilter: actionFilter, data: data });
|
label: 'Zone'
|
||||||
},
|
},
|
||||||
detailView: {
|
|
||||||
noCompact: true,
|
|
||||||
tabs: {
|
|
||||||
network: {
|
|
||||||
title: 'Network',
|
|
||||||
custom: function(args) {
|
|
||||||
var $chart = $('<div>').addClass('system-chart network');
|
|
||||||
|
|
||||||
renderChart({
|
pods: {
|
||||||
$chart: $chart,
|
label: 'Pods',
|
||||||
data: args.context.physicalNetworks[0]
|
viewAll: {
|
||||||
});
|
action: actions.listView('pods', context)
|
||||||
|
}
|
||||||
return $chart;
|
},
|
||||||
|
|
||||||
|
clusters: {
|
||||||
|
label: 'Clusters',
|
||||||
|
viewAll: {
|
||||||
|
action: actions.listView('clusters', context)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hosts: {
|
||||||
|
label: 'Hosts',
|
||||||
|
viewAll: {
|
||||||
|
action: actions.listView('hosts', context)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
primaryStorage: {
|
||||||
|
label: 'Primary Storage',
|
||||||
|
viewAll: {
|
||||||
|
action: actions.listView('primary-storage', context)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ucs: {
|
||||||
|
label: 'UCS',
|
||||||
|
viewAll: {
|
||||||
|
action: actions.listView('ucs', context)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
secondaryStorage: {
|
||||||
|
label: 'Secondary Storage',
|
||||||
|
viewAll: {
|
||||||
|
action: actions.listView('secondary-storage', context)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
})
|
|
||||||
});
|
|
||||||
$loading.remove();
|
var $computeResources = $('<ul>').addClass('resources');
|
||||||
|
|
||||||
|
// Make resource items
|
||||||
|
$.each(computeResources, function(id, resource) {
|
||||||
|
var $li = $('<li>');
|
||||||
|
var $label = $('<span>').addClass('label');
|
||||||
|
|
||||||
|
$li.addClass(id);
|
||||||
|
$label.html(resource.label);
|
||||||
|
$label.appendTo($li);
|
||||||
|
|
||||||
|
// View all
|
||||||
|
if (resource.viewAll) {
|
||||||
|
viewAllButton($.extend(resource.viewAll, {
|
||||||
|
title: resource.label,
|
||||||
|
$browser: $browser,
|
||||||
|
context: context
|
||||||
|
})).appendTo($li);
|
||||||
|
}
|
||||||
|
|
||||||
|
$li.appendTo($computeResources);
|
||||||
|
});
|
||||||
|
|
||||||
|
$chart.append($computeResources);
|
||||||
|
|
||||||
|
return $chart;
|
||||||
|
},
|
||||||
|
|
||||||
|
network: function(args) {
|
||||||
|
var $chart = $('<div>');
|
||||||
|
var $browser = $('#browser .container');
|
||||||
|
var $loading = $('<div>').addClass('loading-overlay');
|
||||||
|
var context = args.context;
|
||||||
|
var networkDataProvider = cloudStack.sections.system.naas.networks.dataProvider;
|
||||||
|
var trafficTypeDataProvider = cloudStack.sections.system.naas.trafficTypes.dataProvider;
|
||||||
|
|
||||||
|
$loading.appendTo($chart);
|
||||||
|
|
||||||
|
var renderChart = function(args) {
|
||||||
|
var $targetChart = args.$chart ? args.$chart : $chart;
|
||||||
|
var targetContext = $.extend(true, {}, context, {
|
||||||
|
physicalNetworks: [args.data]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get traffic type data
|
||||||
|
trafficTypeDataProvider({
|
||||||
|
context: targetContext,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
var $networkChart = $('<div>').addClass('system-network-chart');
|
||||||
|
var $trafficTypes = $('<ul>').addClass('resources traffic-types');
|
||||||
|
|
||||||
|
$loading.remove();
|
||||||
|
|
||||||
|
var trafficTypes = {
|
||||||
|
'public': {
|
||||||
|
label: _l('label.public'),
|
||||||
|
configure: {
|
||||||
|
action: actions.trafficTypeDetails('public', targetContext)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'guest': {
|
||||||
|
label: _l('label.guest'),
|
||||||
|
configure: {
|
||||||
|
action: actions.trafficTypeDetails('guest', targetContext)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'management': {
|
||||||
|
label: _l('label.management'),
|
||||||
|
configure: {
|
||||||
|
action: actions.trafficTypeDetails('management', targetContext)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'storage': {
|
||||||
|
label: _l('label.storage'),
|
||||||
|
configure: {
|
||||||
|
action: actions.trafficTypeDetails('storage', targetContext)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'providers': {
|
||||||
|
label: _l('label.network.service.providers'),
|
||||||
|
ignoreChart: true,
|
||||||
|
dependsOn: 'guest',
|
||||||
|
configure: {
|
||||||
|
action: actions.providerListView(targetContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var validTrafficTypes = $.map(args.data, function(trafficType) {
|
||||||
|
return trafficType.name.toLowerCase();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make traffic type elems
|
||||||
|
$.each(trafficTypes, function(id, trafficType) {
|
||||||
|
if ($.inArray(id, validTrafficTypes) == -1) { //if it is not a valid traffic type
|
||||||
|
if (trafficType.dependsOn != null && trafficType.dependsOn.length > 0) { //if it has dependsOn
|
||||||
|
if ($.inArray(trafficType.dependsOn, validTrafficTypes) == -1) { //if its dependsOn is not a valid traffic type, either
|
||||||
|
return true; //skip this item
|
||||||
|
}
|
||||||
|
//else, if its dependsOn is a valid traffic type, continue to Make list item (e.g. providers.dependsOn is 'guest')
|
||||||
|
} else {
|
||||||
|
return true; //if it doesn't have dependsOn, skip this item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make list item
|
||||||
|
var $li = $('<li>').addClass(id);
|
||||||
|
var $label = $('<span>').addClass('label').html(trafficType.label);
|
||||||
|
var $configureButton = viewAllButton($.extend(trafficType.configure, {
|
||||||
|
label: _l('label.configure'),
|
||||||
|
title: trafficType.label,
|
||||||
|
$browser: $browser,
|
||||||
|
targetContext: targetContext
|
||||||
|
}));
|
||||||
|
|
||||||
|
$li.append($label, $configureButton);
|
||||||
|
$li.appendTo($trafficTypes);
|
||||||
|
|
||||||
|
// Make chart
|
||||||
|
if (trafficType.ignoreChart)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var $targetChartItem = $('<div>').addClass('network-chart-item').addClass(id);
|
||||||
|
$targetChartItem.appendTo($networkChart);
|
||||||
|
});
|
||||||
|
|
||||||
|
var $switchIcon = $('<div>').addClass('network-switch-icon').append(
|
||||||
|
$('<span>').html('L2/L3 switch')
|
||||||
|
);
|
||||||
|
var $circleIcon = $('<div>').addClass('base-circle-icon');
|
||||||
|
|
||||||
|
$targetChart.append($trafficTypes, $switchIcon, $networkChart, $circleIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get network data
|
||||||
|
networkDataProvider({
|
||||||
|
context: context,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
var data = args.data;
|
||||||
|
var actionFilter = args.actionFilter;
|
||||||
|
|
||||||
|
$chart.listView({
|
||||||
|
listView: $.extend(true, {}, cloudStack.sections.system.naas.networks.listView, {
|
||||||
|
dataProvider: function(args) {
|
||||||
|
args.response.success({
|
||||||
|
actionFilter: actionFilter,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
detailView: {
|
||||||
|
noCompact: true,
|
||||||
|
tabs: {
|
||||||
|
network: {
|
||||||
|
title: 'Network',
|
||||||
|
custom: function(args) {
|
||||||
|
var $chart = $('<div>').addClass('system-chart network');
|
||||||
|
|
||||||
|
renderChart({
|
||||||
|
$chart: $chart,
|
||||||
|
data: args.context.physicalNetworks[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
return $chart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$loading.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $chart;
|
||||||
|
},
|
||||||
|
|
||||||
|
resources: function(args) {
|
||||||
|
var $chart = $('<div>').addClass('dashboard admin');
|
||||||
|
var $chartItems = $('<ul>');
|
||||||
|
var $stats = $('<div>').addClass('stats');
|
||||||
|
var $container = $('<div>').addClass('dashboard-container head');
|
||||||
|
var $top = $('<div>').addClass('top');
|
||||||
|
var $title = $('<div>').addClass('title').append($('<span>').html(_l('label.system.wide.capacity')));
|
||||||
|
|
||||||
|
var chartItems = {
|
||||||
|
// The keys are based on the internal type ID associated with each capacity
|
||||||
|
0: {
|
||||||
|
name: _l('label.memory')
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
name: _l('label.cpu')
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
name: _l('label.storage')
|
||||||
|
},
|
||||||
|
3: {
|
||||||
|
name: _l('label.primary.allocated')
|
||||||
|
},
|
||||||
|
6: {
|
||||||
|
name: _l('label.secondary.storage')
|
||||||
|
},
|
||||||
|
9: {
|
||||||
|
name: _l('label.local.storage')
|
||||||
|
},
|
||||||
|
4: {
|
||||||
|
name: _l('label.public.ips')
|
||||||
|
},
|
||||||
|
5: {
|
||||||
|
name: _l('label.management.ips')
|
||||||
|
},
|
||||||
|
8: {
|
||||||
|
name: _l('label.direct.ips')
|
||||||
|
},
|
||||||
|
7: {
|
||||||
|
name: _l('label.vlan')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$top.append($title);
|
||||||
|
$container.append($top, $stats.append($chartItems));
|
||||||
|
$chart.append($container);
|
||||||
|
var $loading = $('<div>').addClass('loading-overlay').prependTo($chart);
|
||||||
|
|
||||||
|
cloudStack.sections.system.zoneDashboard({
|
||||||
|
context: args.context,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
$loading.remove();
|
||||||
|
$.each(chartItems, function(id, chartItem) {
|
||||||
|
var data = args.data[id] ? args.data[id] : {
|
||||||
|
used: 0,
|
||||||
|
total: 0,
|
||||||
|
percent: 0
|
||||||
|
};
|
||||||
|
var $item = $('<li>');
|
||||||
|
var $name = $('<div>').addClass('name').html(chartItem.name);
|
||||||
|
var $value = $('<div>').addClass('value');
|
||||||
|
var $content = $('<div>').addClass('content').html('Allocated: ');
|
||||||
|
var $allocatedValue = $('<span>').addClass('allocated').html(data.used);
|
||||||
|
var $totalValue = $('<span>').addClass('total').html(data.total);
|
||||||
|
var $chart = $('<div>').addClass('chart');
|
||||||
|
var $chartLine = $('<div>').addClass('chart-line')
|
||||||
|
.css({
|
||||||
|
width: '0%'
|
||||||
|
})
|
||||||
|
.animate({
|
||||||
|
width: data.percent + '%'
|
||||||
|
});
|
||||||
|
var $percent = $('<div>').addClass('percentage');
|
||||||
|
var $percentValue = $('<soan>').addClass('value').html(data.percent);
|
||||||
|
|
||||||
|
$chartItems.append(
|
||||||
|
$item.append(
|
||||||
|
$name,
|
||||||
|
$value.append(
|
||||||
|
$content.append(
|
||||||
|
$allocatedValue,
|
||||||
|
' / ',
|
||||||
|
$totalValue
|
||||||
|
)
|
||||||
|
),
|
||||||
|
$chart.append($chartLine),
|
||||||
|
$percent.append($percentValue, '%')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $chart;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return $chart;
|
|
||||||
},
|
|
||||||
|
|
||||||
resources: function(args) {
|
|
||||||
var $chart = $('<div>').addClass('dashboard admin');
|
|
||||||
var $chartItems = $('<ul>');
|
|
||||||
var $stats = $('<div>').addClass('stats');
|
|
||||||
var $container = $('<div>').addClass('dashboard-container head');
|
|
||||||
var $top = $('<div>').addClass('top');
|
|
||||||
var $title = $('<div>').addClass('title').append($('<span>').html(_l('label.system.wide.capacity')));
|
|
||||||
|
|
||||||
var chartItems = {
|
|
||||||
// The keys are based on the internal type ID associated with each capacity
|
|
||||||
0: { name: _l('label.memory') },
|
|
||||||
1: { name: _l('label.cpu') },
|
|
||||||
2: { name: _l('label.storage') },
|
|
||||||
3: { name: _l('label.primary.allocated') },
|
|
||||||
6: { name: _l('label.secondary.storage') },
|
|
||||||
9: { name: _l('label.local.storage') },
|
|
||||||
4: { name: _l('label.public.ips') },
|
|
||||||
5: { name: _l('label.management.ips') },
|
|
||||||
8: { name: _l('label.direct.ips') },
|
|
||||||
7: { name: _l('label.vlan') }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$top.append($title);
|
return function(args) {
|
||||||
$container.append($top, $stats.append($chartItems));
|
// Fix zone context naming
|
||||||
$chart.append($container);
|
args.context.zones = args.context.physicalResources;
|
||||||
var $loading = $('<div>').addClass('loading-overlay').prependTo($chart);
|
|
||||||
|
|
||||||
cloudStack.sections.system.zoneDashboard({
|
var $chart = charts[chartID](args).addClass('system-chart').addClass(chartID);
|
||||||
context: args.context,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
$loading.remove();
|
|
||||||
$.each(chartItems, function(id, chartItem) {
|
|
||||||
var data = args.data[id] ? args.data[id] : {
|
|
||||||
used: 0,
|
|
||||||
total: 0,
|
|
||||||
percent: 0
|
|
||||||
};
|
|
||||||
var $item = $('<li>');
|
|
||||||
var $name = $('<div>').addClass('name').html(chartItem.name);
|
|
||||||
var $value = $('<div>').addClass('value');
|
|
||||||
var $content = $('<div>').addClass('content').html('Allocated: ');
|
|
||||||
var $allocatedValue = $('<span>').addClass('allocated').html(data.used);
|
|
||||||
var $totalValue = $('<span>').addClass('total').html(data.total);
|
|
||||||
var $chart = $('<div>').addClass('chart');
|
|
||||||
var $chartLine = $('<div>').addClass('chart-line')
|
|
||||||
.css({ width: '0%' })
|
|
||||||
.animate({ width: data.percent + '%' });
|
|
||||||
var $percent = $('<div>').addClass('percentage');
|
|
||||||
var $percentValue = $('<soan>').addClass('value').html(data.percent);
|
|
||||||
|
|
||||||
$chartItems.append(
|
return $chart;
|
||||||
$item.append(
|
};
|
||||||
$name,
|
|
||||||
$value.append(
|
|
||||||
$content.append(
|
|
||||||
$allocatedValue,
|
|
||||||
' / ',
|
|
||||||
$totalValue
|
|
||||||
)
|
|
||||||
),
|
|
||||||
$chart.append($chartLine),
|
|
||||||
$percent.append($percentValue, '%')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return $chart;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(args) {
|
|
||||||
// Fix zone context naming
|
|
||||||
args.context.zones = args.context.physicalResources;
|
|
||||||
|
|
||||||
var $chart = charts[chartID](args).addClass('system-chart').addClass(chartID);
|
|
||||||
|
|
||||||
return $chart;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
@ -16,24 +16,23 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
$(window).bind('cloudStack.ready', function() {
|
$(window).bind('cloudStack.ready', function() {
|
||||||
var $header = $('#header .controls');
|
var $header = $('#header .controls');
|
||||||
var $zoneFilter = $('<div>').addClass('zone-filter');
|
var $zoneFilter = $('<div>').addClass('zone-filter');
|
||||||
var $zoneTypeSelect = $('<select>').append(
|
var $zoneTypeSelect = $('<select>').append(
|
||||||
$('<option>').attr('value', '').html(_l('All zones')),
|
$('<option>').attr('value', '').html(_l('All zones')),
|
||||||
$('<option>').attr('value', 'Basic').html(_l('Basic')),
|
$('<option>').attr('value', 'Basic').html(_l('Basic')),
|
||||||
$('<option>').attr('value', 'Advanced').html(_l('Advanced'))
|
$('<option>').attr('value', 'Advanced').html(_l('Advanced'))
|
||||||
);
|
);
|
||||||
var $label = $('<label>').html('Zone type:');
|
var $label = $('<label>').html('Zone type:');
|
||||||
|
|
||||||
$zoneFilter.append($label, $zoneTypeSelect);
|
$zoneFilter.append($label, $zoneTypeSelect);
|
||||||
$zoneFilter.insertAfter($header.find('.project-switcher'));
|
$zoneFilter.insertAfter($header.find('.project-switcher'));
|
||||||
$zoneTypeSelect.change(function() {
|
$zoneTypeSelect.change(function() {
|
||||||
cloudStack.context.zoneType = $zoneTypeSelect.val();
|
cloudStack.context.zoneType = $zoneTypeSelect.val();
|
||||||
|
|
||||||
// Go to default/start page (dashboard)
|
// Go to default/start page (dashboard)
|
||||||
$('#breadcrumbs .home').click();
|
$('#breadcrumbs .home').click();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -15,443 +15,462 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
$.extend(cloudStack, {
|
$.extend(cloudStack, {
|
||||||
ui: {
|
ui: {
|
||||||
widgets: {} // Defines API methods for UI widgets
|
widgets: {} // Defines API methods for UI widgets
|
||||||
},
|
},
|
||||||
uiCustom: {}
|
uiCustom: {}
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate navigation <li>s
|
|
||||||
*
|
|
||||||
* @param args cloudStack data args
|
|
||||||
*/
|
|
||||||
var makeNavigation = function(args) {
|
|
||||||
var $navList = $('<ul>');
|
|
||||||
var preFilter = cloudStack.sectionPreFilter ?
|
|
||||||
cloudStack.sectionPreFilter({
|
|
||||||
context: $.extend(true, {}, args.context, {
|
|
||||||
sections: $.map(cloudStack.sections, function(value, key) {
|
|
||||||
return key;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}) : null;
|
|
||||||
|
|
||||||
$.each(args.sections, function(sectionID, args) {
|
|
||||||
if (preFilter && $.inArray(sectionID, preFilter) == -1) {
|
|
||||||
if (!(args.preFilter && args.preFilter())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var $li = $('<li>')
|
|
||||||
.addClass('navigation-item')
|
|
||||||
.addClass(sectionID)
|
|
||||||
.append($('<span>').addClass('icon').html(' '))
|
|
||||||
.append($('<span>').html(_l(args.title)))
|
|
||||||
.data('cloudStack-section-id', sectionID);
|
|
||||||
|
|
||||||
if (args.customIcon) {
|
|
||||||
$li.addClass('custom-icon').find('span.icon').html('').append(
|
|
||||||
$('<img>').attr({ src: args.customIcon })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$li.appendTo($navList);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Special classes for first and last items
|
/**
|
||||||
$navList.find('li:first').addClass('first');
|
* Generate navigation <li>s
|
||||||
$navList.find('li:last').addClass('last');
|
*
|
||||||
|
* @param args cloudStack data args
|
||||||
|
*/
|
||||||
|
var makeNavigation = function(args) {
|
||||||
|
var $navList = $('<ul>');
|
||||||
|
var preFilter = cloudStack.sectionPreFilter ?
|
||||||
|
cloudStack.sectionPreFilter({
|
||||||
|
context: $.extend(true, {}, args.context, {
|
||||||
|
sections: $.map(cloudStack.sections, function(value, key) {
|
||||||
|
return key;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}) : null;
|
||||||
|
|
||||||
return $navList;
|
$.each(args.sections, function(sectionID, args) {
|
||||||
};
|
if (preFilter && $.inArray(sectionID, preFilter) == -1) {
|
||||||
|
if (!(args.preFilter && args.preFilter())) {
|
||||||
/**
|
return true;
|
||||||
* Create section contents
|
}
|
||||||
*
|
|
||||||
* @param sectionID Section's ID to show
|
|
||||||
* @param args CloudStack3 configuration
|
|
||||||
*/
|
|
||||||
var showSection = function(sectionID, args, $browser) {
|
|
||||||
var $navItem = $('#navigation').find('li').filter(function() {
|
|
||||||
return $(this).hasClass(sectionID);
|
|
||||||
});
|
|
||||||
var data = args.sections[sectionID];
|
|
||||||
|
|
||||||
data.$browser = $browser;
|
|
||||||
$navItem.siblings().removeClass('active');
|
|
||||||
$navItem.addClass('active');
|
|
||||||
|
|
||||||
// Reset browser panels
|
|
||||||
$browser.cloudBrowser('removeAllPanels');
|
|
||||||
$browser.cloudBrowser('addPanel', {
|
|
||||||
title: '<span class="section">' + _l(data.title) + '</span>' + '<span class="subsection"></span>',
|
|
||||||
data: '',
|
|
||||||
complete: function($panel, $breadcrumb) {
|
|
||||||
$breadcrumb.attr('title', _l(data.title));
|
|
||||||
data.$breadcrumb = $breadcrumb;
|
|
||||||
|
|
||||||
// Hide breadcrumb if this is the home section
|
|
||||||
if (args.home === sectionID) {
|
|
||||||
$('#breadcrumbs').find('li:first, div.end:last').hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append specified widget to view
|
|
||||||
if (data.show)
|
|
||||||
$panel.append(data.show(data));
|
|
||||||
else if (data.treeView)
|
|
||||||
$panel.treeView(data, { context: args.context });
|
|
||||||
else
|
|
||||||
$panel.listView(data, { context: args.context });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return $navItem;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Define page element generation fns
|
|
||||||
var pageElems = {
|
|
||||||
header: function(args) {
|
|
||||||
// Make notification area
|
|
||||||
var $notificationArea = $('<div>').addClass('button notifications')
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('total')
|
|
||||||
// Total notifications
|
|
||||||
.append($('<span>').html(0))
|
|
||||||
)
|
|
||||||
.append($('<span>').html(_l('label.notifications')))
|
|
||||||
.notifications();
|
|
||||||
|
|
||||||
// Project switcher
|
|
||||||
var $viewSwitcher = $('<div>').addClass('button view-switcher')
|
|
||||||
.append(
|
|
||||||
// Default View
|
|
||||||
$('<div>').addClass('select default-view active')
|
|
||||||
.html(_l('label.default.view'))
|
|
||||||
.prepend(
|
|
||||||
$('<span>').addClass('icon').html(' ')
|
|
||||||
|
|
||||||
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
// Project View
|
|
||||||
$('<div>').addClass('select project-view')
|
|
||||||
.html(_l('label.project.view'))
|
|
||||||
.prepend(
|
|
||||||
$('<span>').addClass('icon').html(' ')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.click(function(event) {
|
|
||||||
var $target = $(event.target);
|
|
||||||
var $projectSwitcher = $(this);
|
|
||||||
var $container = $('html body');
|
|
||||||
var $navDisabled = $(
|
|
||||||
$.map([
|
|
||||||
'projects',
|
|
||||||
'accounts',
|
|
||||||
'domains',
|
|
||||||
'system',
|
|
||||||
'global-settings',
|
|
||||||
'configuration'
|
|
||||||
], function(id) {
|
|
||||||
return '#navigation li.' + id;
|
|
||||||
}).join(',')
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($target.closest('.select.project-view').size()) {
|
|
||||||
$('#cloudStack3-container').addClass('project-view');
|
|
||||||
$projectSwitcher.addClass('alt');
|
|
||||||
$projectSwitcher.find('.select.project-view').addClass('active')
|
|
||||||
.siblings().removeClass('active');
|
|
||||||
|
|
||||||
// Activate project view
|
|
||||||
$navDisabled.hide();
|
|
||||||
cloudStack.uiCustom.projects({
|
|
||||||
$projectSelect: $projectSelect.hide().find('select')
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$navDisabled.show();
|
|
||||||
$('#cloudStack3-container').removeClass('project-view');
|
|
||||||
$projectSwitcher.removeClass('alt');
|
|
||||||
$projectSelect.hide();
|
|
||||||
$projectSwitcher.find('.select.default-view').addClass('active')
|
|
||||||
.siblings().removeClass('active');
|
|
||||||
|
|
||||||
// Put project name in header
|
|
||||||
$('.select.project-view').html(
|
|
||||||
'<span class="icon"> </span>' + _l('label.project.view')
|
|
||||||
).attr('title', '');
|
|
||||||
|
|
||||||
// Clear out project
|
|
||||||
cloudStack.context.projects = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#navigation li.dashboard').click();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
var $projectSelect = $('<div>').addClass('view-switcher').hide()
|
|
||||||
.append($('<select>'));
|
|
||||||
|
|
||||||
// User status area
|
|
||||||
var userLabel = args.context.users[0].name ?
|
|
||||||
args.context.users[0].name : args.context.users[0].login;
|
|
||||||
var $userInfo = $('<div>').attr({ id: 'user' }).addClass('button')
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('name').html(
|
|
||||||
args.context && args.context.users ?
|
|
||||||
cloudStack.concat(userLabel, 14) : 'Invalid User'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('icon options')
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('icon arrow')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$userInfo.attr('title', userLabel);
|
|
||||||
|
|
||||||
return [
|
|
||||||
$('<div>').addClass('logo'),
|
|
||||||
$('<div>').addClass('controls')
|
|
||||||
.append($notificationArea)
|
|
||||||
.append($viewSwitcher)
|
|
||||||
.append($projectSelect)
|
|
||||||
.append($userInfo)
|
|
||||||
];
|
|
||||||
},
|
|
||||||
|
|
||||||
'main-area': function(args) {
|
|
||||||
var $navigation = $('<div>').attr({ id: 'navigation' });
|
|
||||||
var $browser = $('<div>').attr({ id: 'browser' })
|
|
||||||
.append(
|
|
||||||
// Home breadcrumb
|
|
||||||
$('<div>').attr({ id: 'breadcrumbs' })
|
|
||||||
.append($('<div>').addClass('home'))
|
|
||||||
.append($('<div>').addClass('end'))
|
|
||||||
)
|
|
||||||
|
|
||||||
.append(
|
|
||||||
// Panel container
|
|
||||||
$('<div>').addClass('container')
|
|
||||||
);
|
|
||||||
|
|
||||||
makeNavigation(args).appendTo($navigation);
|
|
||||||
|
|
||||||
return [
|
|
||||||
$navigation, $browser
|
|
||||||
];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.cloudStack = function(args) {
|
|
||||||
var $container = $('<div>')
|
|
||||||
.attr({
|
|
||||||
id: 'container',
|
|
||||||
'cloudStack-container': true
|
|
||||||
})
|
|
||||||
.data('cloudStack-args', args)
|
|
||||||
.appendTo(this);
|
|
||||||
var context = args.context;
|
|
||||||
|
|
||||||
// Create pageElems
|
|
||||||
$.each(pageElems, function(id, fn) {
|
|
||||||
var $elem = $('<div>').attr({ id: id });
|
|
||||||
|
|
||||||
$(fn(args)).each(function() {
|
|
||||||
$elem.append($(this));
|
|
||||||
});
|
|
||||||
|
|
||||||
$elem.appendTo($container);
|
|
||||||
});
|
|
||||||
|
|
||||||
// User options
|
|
||||||
var $options = $('<div>').attr({ id: 'user-options' })
|
|
||||||
.appendTo($('#header'));
|
|
||||||
|
|
||||||
$(['label.logout', 'label.help', 'label.about']).each(function() {
|
|
||||||
var $link = $('<a>')
|
|
||||||
.attr({ href: '#' })
|
|
||||||
.html(_l(this.toString()))
|
|
||||||
.appendTo($options);
|
|
||||||
|
|
||||||
if (this == 'label.help') {
|
|
||||||
$link.click(function() {
|
|
||||||
var helpURL = 'http://docs.cloud.com/CloudStack_Documentation';
|
|
||||||
|
|
||||||
window.open(helpURL, '_blank');
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this == 'label.about') {
|
|
||||||
$link.click(function() {
|
|
||||||
var $logo = $('<div>').addClass('logo').html(_l('label.app.name')),
|
|
||||||
$version = $('<div>').addClass('version').html(g_cloudstackversion),
|
|
||||||
$about = $('<div>').addClass('about').append($logo).append($version);
|
|
||||||
$about.dialog({
|
|
||||||
modal: true,
|
|
||||||
width: 300,
|
|
||||||
title: _l('label.about.app'),
|
|
||||||
closeOnEscape: false,
|
|
||||||
dialogClass: 'dialog-about',
|
|
||||||
buttons: {
|
|
||||||
'Close': function() {
|
|
||||||
$( this ).dialog( "close" );
|
|
||||||
$(':ui-dialog, .overlay').remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).closest('.ui-dialog').overlay();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
var $li = $('<li>')
|
||||||
|
.addClass('navigation-item')
|
||||||
|
.addClass(sectionID)
|
||||||
|
.append($('<span>').addClass('icon').html(' '))
|
||||||
|
.append($('<span>').html(_l(args.title)))
|
||||||
|
.data('cloudStack-section-id', sectionID);
|
||||||
|
|
||||||
|
if (args.customIcon) {
|
||||||
|
$li.addClass('custom-icon').find('span.icon').html('').append(
|
||||||
|
$('<img>').attr({
|
||||||
|
src: args.customIcon
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$li.appendTo($navList);
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initialize browser
|
// Special classes for first and last items
|
||||||
$container.find('#browser div.container').cloudBrowser();
|
$navList.find('li:first').addClass('first');
|
||||||
$container.find('#navigation li')
|
$navList.find('li:last').addClass('last');
|
||||||
.filter(function() {
|
|
||||||
return $(this).hasClass(args.home);
|
|
||||||
})
|
|
||||||
.click();
|
|
||||||
|
|
||||||
// Validation
|
return $navList;
|
||||||
$.extend($.validator.messages, { required: _l('label.required') });
|
};
|
||||||
|
|
||||||
$.validator.addMethod(
|
/**
|
||||||
"disallowSpecialCharacters",
|
* Create section contents
|
||||||
function(value, element) {
|
*
|
||||||
return (value.indexOf("<") == -1 && value.indexOf(">") == -1);
|
* @param sectionID Section's ID to show
|
||||||
},
|
* @param args CloudStack3 configuration
|
||||||
jQuery.format("Disallowed characters: <, >")
|
*/
|
||||||
);
|
var showSection = function(sectionID, args, $browser) {
|
||||||
|
var $navItem = $('#navigation').find('li').filter(function() {
|
||||||
|
return $(this).hasClass(sectionID);
|
||||||
|
});
|
||||||
|
var data = args.sections[sectionID];
|
||||||
|
|
||||||
// Check for pending project invitations
|
data.$browser = $browser;
|
||||||
if (args.projects) {
|
$navItem.siblings().removeClass('active');
|
||||||
args.projects.invitationCheck({
|
$navItem.addClass('active');
|
||||||
context: cloudStack.context,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
if (!args.data.length) return;
|
|
||||||
|
|
||||||
var projectList = $.map(args.data, function(invitation) {
|
// Reset browser panels
|
||||||
return '<li>' + invitation.project + '</li>';
|
$browser.cloudBrowser('removeAllPanels');
|
||||||
}).join('');
|
$browser.cloudBrowser('addPanel', {
|
||||||
|
title: '<span class="section">' + _l(data.title) + '</span>' + '<span class="subsection"></span>',
|
||||||
|
data: '',
|
||||||
|
complete: function($panel, $breadcrumb) {
|
||||||
|
$breadcrumb.attr('title', _l(data.title));
|
||||||
|
data.$breadcrumb = $breadcrumb;
|
||||||
|
|
||||||
cloudStack.dialog.notice({
|
// Hide breadcrumb if this is the home section
|
||||||
message: _l('message.pending.projects.1') +
|
if (args.home === sectionID) {
|
||||||
'<ul>' + projectList + '</ul>' +
|
$('#breadcrumbs').find('li:first, div.end:last').hide();
|
||||||
'<p>' + _l('message.pending.projects.2') + '</p>'
|
}
|
||||||
|
|
||||||
|
// Append specified widget to view
|
||||||
|
if (data.show)
|
||||||
|
$panel.append(data.show(data));
|
||||||
|
else if (data.treeView)
|
||||||
|
$panel.treeView(data, {
|
||||||
|
context: args.context
|
||||||
|
});
|
||||||
|
else
|
||||||
|
$panel.listView(data, {
|
||||||
|
context: args.context
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $navItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define page element generation fns
|
||||||
|
var pageElems = {
|
||||||
|
header: function(args) {
|
||||||
|
// Make notification area
|
||||||
|
var $notificationArea = $('<div>').addClass('button notifications')
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('total')
|
||||||
|
// Total notifications
|
||||||
|
.append($('<span>').html(0))
|
||||||
|
)
|
||||||
|
.append($('<span>').html(_l('label.notifications')))
|
||||||
|
.notifications();
|
||||||
|
|
||||||
|
// Project switcher
|
||||||
|
var $viewSwitcher = $('<div>').addClass('button view-switcher')
|
||||||
|
.append(
|
||||||
|
// Default View
|
||||||
|
$('<div>').addClass('select default-view active')
|
||||||
|
.html(_l('label.default.view'))
|
||||||
|
.prepend(
|
||||||
|
$('<span>').addClass('icon').html(' ')
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
// Project View
|
||||||
|
$('<div>').addClass('select project-view')
|
||||||
|
.html(_l('label.project.view'))
|
||||||
|
.prepend(
|
||||||
|
$('<span>').addClass('icon').html(' ')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.click(function(event) {
|
||||||
|
var $target = $(event.target);
|
||||||
|
var $projectSwitcher = $(this);
|
||||||
|
var $container = $('html body');
|
||||||
|
var $navDisabled = $(
|
||||||
|
$.map([
|
||||||
|
'projects',
|
||||||
|
'accounts',
|
||||||
|
'domains',
|
||||||
|
'system',
|
||||||
|
'global-settings',
|
||||||
|
'configuration'
|
||||||
|
], function(id) {
|
||||||
|
return '#navigation li.' + id;
|
||||||
|
}).join(',')
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($target.closest('.select.project-view').size()) {
|
||||||
|
$('#cloudStack3-container').addClass('project-view');
|
||||||
|
$projectSwitcher.addClass('alt');
|
||||||
|
$projectSwitcher.find('.select.project-view').addClass('active')
|
||||||
|
.siblings().removeClass('active');
|
||||||
|
|
||||||
|
// Activate project view
|
||||||
|
$navDisabled.hide();
|
||||||
|
cloudStack.uiCustom.projects({
|
||||||
|
$projectSelect: $projectSelect.hide().find('select')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$navDisabled.show();
|
||||||
|
$('#cloudStack3-container').removeClass('project-view');
|
||||||
|
$projectSwitcher.removeClass('alt');
|
||||||
|
$projectSelect.hide();
|
||||||
|
$projectSwitcher.find('.select.default-view').addClass('active')
|
||||||
|
.siblings().removeClass('active');
|
||||||
|
|
||||||
|
// Put project name in header
|
||||||
|
$('.select.project-view').html(
|
||||||
|
'<span class="icon"> </span>' + _l('label.project.view')
|
||||||
|
).attr('title', '');
|
||||||
|
|
||||||
|
// Clear out project
|
||||||
|
cloudStack.context.projects = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#navigation li.dashboard').click();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
var $projectSelect = $('<div>').addClass('view-switcher').hide()
|
||||||
|
.append($('<select>'));
|
||||||
|
|
||||||
|
// User status area
|
||||||
|
var userLabel = args.context.users[0].name ?
|
||||||
|
args.context.users[0].name : args.context.users[0].login;
|
||||||
|
var $userInfo = $('<div>').attr({
|
||||||
|
id: 'user'
|
||||||
|
}).addClass('button')
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('name').html(
|
||||||
|
args.context && args.context.users ?
|
||||||
|
cloudStack.concat(userLabel, 14) : 'Invalid User'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('icon options')
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('icon arrow')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$userInfo.attr('title', userLabel);
|
||||||
|
|
||||||
|
return [
|
||||||
|
$('<div>').addClass('logo'),
|
||||||
|
$('<div>').addClass('controls')
|
||||||
|
.append($notificationArea)
|
||||||
|
.append($viewSwitcher)
|
||||||
|
.append($projectSelect)
|
||||||
|
.append($userInfo)
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
'main-area': function(args) {
|
||||||
|
var $navigation = $('<div>').attr({
|
||||||
|
id: 'navigation'
|
||||||
});
|
});
|
||||||
}
|
var $browser = $('<div>').attr({
|
||||||
|
id: 'browser'
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
// Home breadcrumb
|
||||||
|
$('<div>').attr({
|
||||||
|
id: 'breadcrumbs'
|
||||||
|
})
|
||||||
|
.append($('<div>').addClass('home'))
|
||||||
|
.append($('<div>').addClass('end'))
|
||||||
|
)
|
||||||
|
|
||||||
|
.append(
|
||||||
|
// Panel container
|
||||||
|
$('<div>').addClass('container')
|
||||||
|
);
|
||||||
|
|
||||||
|
makeNavigation(args).appendTo($navigation);
|
||||||
|
|
||||||
|
return [
|
||||||
|
$navigation, $browser
|
||||||
|
];
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Hide logo conditionally
|
$.fn.cloudStack = function(args) {
|
||||||
if (!args.hasLogo) $('#header, #header .controls').addClass('nologo');
|
var $container = $('<div>')
|
||||||
|
.attr({
|
||||||
|
id: 'container',
|
||||||
|
'cloudStack-container': true
|
||||||
|
})
|
||||||
|
.data('cloudStack-args', args)
|
||||||
|
.appendTo(this);
|
||||||
|
var context = args.context;
|
||||||
|
|
||||||
$(window).trigger('cloudStack.ready');
|
// Create pageElems
|
||||||
|
$.each(pageElems, function(id, fn) {
|
||||||
|
var $elem = $('<div>').attr({
|
||||||
|
id: id
|
||||||
|
});
|
||||||
|
|
||||||
return this;
|
$(fn(args)).each(function() {
|
||||||
};
|
$elem.append($(this));
|
||||||
|
});
|
||||||
|
|
||||||
// Events
|
$elem.appendTo($container);
|
||||||
$(function() {
|
|
||||||
// Check if target should be hovered
|
|
||||||
function checkHoveredLabel($target) {
|
|
||||||
var $multiWizard = $('div.ui-dialog div.multi-wizard');
|
|
||||||
if (($target.is('label[for]') && !$target.parents('body.login')) ||
|
|
||||||
($multiWizard.size() &&
|
|
||||||
($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) ||
|
|
||||||
($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size())
|
|
||||||
))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rollover behavior for user options
|
|
||||||
$(document).bind('mouseover', function(event) {
|
|
||||||
var $target = $(event.target);
|
|
||||||
if (checkHoveredLabel($target)) {
|
|
||||||
$target.addClass('label-hovered');
|
|
||||||
}
|
|
||||||
if ($target.closest('#user, #user-options').size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else $('#user-options').hide();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('mouseout', function(event) {
|
|
||||||
var $target = $(event.target);
|
|
||||||
if (checkHoveredLabel($target)) {
|
|
||||||
$target.removeClass('label-hovered');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('click', function(event) {
|
|
||||||
var $target = $(event.target);
|
|
||||||
var $container = $target.closest('[cloudStack-container]');
|
|
||||||
var args = $container.data('cloudStack-args');
|
|
||||||
var $browser = $container.find('#browser .container');
|
|
||||||
var $multiWizard = $('div.ui-dialog div.multi-wizard');
|
|
||||||
|
|
||||||
// Wizard: trigger click event for input when click it label
|
|
||||||
if ($multiWizard.size()) {
|
|
||||||
if ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) {
|
|
||||||
$target.prev('input').trigger('click');
|
|
||||||
}
|
|
||||||
if ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size()) {
|
|
||||||
$target.parent('div.select-desc').prev('input').trigger('click');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$container.size()) return true;
|
|
||||||
|
|
||||||
// Navigation items
|
|
||||||
if ($target.closest('li.navigation-item').size() && $target.closest('#navigation').size()) {
|
|
||||||
var $navItem = $target.closest('li.navigation-item');
|
|
||||||
|
|
||||||
if ($navItem.is('.disabled')) return false;
|
|
||||||
showSection($navItem.data('cloudStack-section-id'), args, $browser);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Browser expand
|
|
||||||
if ($target.hasClass('control expand') && $target.closest('div.panel div.toolbar').size()) {
|
|
||||||
$browser.cloudBrowser('toggleMaximizePanel', {
|
|
||||||
panel: $target.closest('div.panel')
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return false;
|
// User options
|
||||||
}
|
var $options = $('<div>').attr({
|
||||||
|
id: 'user-options'
|
||||||
|
})
|
||||||
|
.appendTo($('#header'));
|
||||||
|
|
||||||
// Home breadcrumb
|
$(['label.logout', 'label.help', 'label.about']).each(function() {
|
||||||
if ($target.is('#breadcrumbs div.home')) {
|
var $link = $('<a>')
|
||||||
showSection(args.home, args, $browser);
|
.attr({
|
||||||
return false;
|
href: '#'
|
||||||
}
|
})
|
||||||
|
.html(_l(this.toString()))
|
||||||
|
.appendTo($options);
|
||||||
|
|
||||||
// User options
|
if (this == 'label.help') {
|
||||||
if ($target.closest('#user div.icon.options').size()) {
|
$link.click(function() {
|
||||||
$('#user-options').toggle();
|
var helpURL = 'http://docs.cloud.com/CloudStack_Documentation';
|
||||||
|
|
||||||
return false;
|
window.open(helpURL, '_blank');
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this == 'label.about') {
|
||||||
|
$link.click(function() {
|
||||||
|
var $logo = $('<div>').addClass('logo').html(_l('label.app.name')),
|
||||||
|
$version = $('<div>').addClass('version').html(g_cloudstackversion),
|
||||||
|
$about = $('<div>').addClass('about').append($logo).append($version);
|
||||||
|
$about.dialog({
|
||||||
|
modal: true,
|
||||||
|
width: 300,
|
||||||
|
title: _l('label.about.app'),
|
||||||
|
closeOnEscape: false,
|
||||||
|
dialogClass: 'dialog-about',
|
||||||
|
buttons: {
|
||||||
|
'Close': function() {
|
||||||
|
$(this).dialog("close");
|
||||||
|
$(':ui-dialog, .overlay').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).closest('.ui-dialog').overlay();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize browser
|
||||||
|
$container.find('#browser div.container').cloudBrowser();
|
||||||
|
$container.find('#navigation li')
|
||||||
|
.filter(function() {
|
||||||
|
return $(this).hasClass(args.home);
|
||||||
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// Validation
|
||||||
|
$.extend($.validator.messages, {
|
||||||
|
required: _l('label.required')
|
||||||
|
});
|
||||||
|
|
||||||
|
$.validator.addMethod(
|
||||||
|
"disallowSpecialCharacters",
|
||||||
|
function(value, element) {
|
||||||
|
return (value.indexOf("<") == -1 && value.indexOf(">") == -1);
|
||||||
|
},
|
||||||
|
jQuery.format("Disallowed characters: <, >")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check for pending project invitations
|
||||||
|
if (args.projects) {
|
||||||
|
args.projects.invitationCheck({
|
||||||
|
context: cloudStack.context,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
if (!args.data.length) return;
|
||||||
|
|
||||||
|
var projectList = $.map(args.data, function(invitation) {
|
||||||
|
return '<li>' + invitation.project + '</li>';
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _l('message.pending.projects.1') + '<ul>' + projectList + '</ul>' + '<p>' + _l('message.pending.projects.2') + '</p>'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide logo conditionally
|
||||||
|
if (!args.hasLogo) $('#header, #header .controls').addClass('nologo');
|
||||||
|
|
||||||
|
$(window).trigger('cloudStack.ready');
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Events
|
||||||
|
$(function() {
|
||||||
|
// Check if target should be hovered
|
||||||
|
function checkHoveredLabel($target) {
|
||||||
|
var $multiWizard = $('div.ui-dialog div.multi-wizard');
|
||||||
|
if (($target.is('label[for]') && !$target.parents('body.login')) ||
|
||||||
|
($multiWizard.size() &&
|
||||||
|
($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) ||
|
||||||
|
($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size())
|
||||||
|
))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rollover behavior for user options
|
||||||
|
$(document).bind('mouseover', function(event) {
|
||||||
|
var $target = $(event.target);
|
||||||
|
if (checkHoveredLabel($target)) {
|
||||||
|
$target.addClass('label-hovered');
|
||||||
|
}
|
||||||
|
if ($target.closest('#user, #user-options').size()) {
|
||||||
|
return false;
|
||||||
|
} else $('#user-options').hide();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('mouseout', function(event) {
|
||||||
|
var $target = $(event.target);
|
||||||
|
if (checkHoveredLabel($target)) {
|
||||||
|
$target.removeClass('label-hovered');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('click', function(event) {
|
||||||
|
var $target = $(event.target);
|
||||||
|
var $container = $target.closest('[cloudStack-container]');
|
||||||
|
var args = $container.data('cloudStack-args');
|
||||||
|
var $browser = $container.find('#browser .container');
|
||||||
|
var $multiWizard = $('div.ui-dialog div.multi-wizard');
|
||||||
|
|
||||||
|
// Wizard: trigger click event for input when click it label
|
||||||
|
if ($multiWizard.size()) {
|
||||||
|
if ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) {
|
||||||
|
$target.prev('input').trigger('click');
|
||||||
|
}
|
||||||
|
if ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size()) {
|
||||||
|
$target.parent('div.select-desc').prev('input').trigger('click');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$container.size()) return true;
|
||||||
|
|
||||||
|
// Navigation items
|
||||||
|
if ($target.closest('li.navigation-item').size() && $target.closest('#navigation').size()) {
|
||||||
|
var $navItem = $target.closest('li.navigation-item');
|
||||||
|
|
||||||
|
if ($navItem.is('.disabled')) return false;
|
||||||
|
showSection($navItem.data('cloudStack-section-id'), args, $browser);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Browser expand
|
||||||
|
if ($target.hasClass('control expand') && $target.closest('div.panel div.toolbar').size()) {
|
||||||
|
$browser.cloudBrowser('toggleMaximizePanel', {
|
||||||
|
panel: $target.closest('div.panel')
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Home breadcrumb
|
||||||
|
if ($target.is('#breadcrumbs div.home')) {
|
||||||
|
showSection(args.home, args, $browser);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User options
|
||||||
|
if ($target.closest('#user div.icon.options').size()) {
|
||||||
|
$('#user-options').toggle();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
})(window.jQuery,
|
})(window.jQuery,
|
||||||
window.cloudStack ? window.cloudStack : window.cloudStack = {});
|
window.cloudStack ? window.cloudStack : window.cloudStack = {});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -15,46 +15,48 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.ui.event = {
|
cloudStack.ui.event = {
|
||||||
// Attach element to specific event type
|
// Attach element to specific event type
|
||||||
elem: function(widget, elem, $elem, extraData) {
|
elem: function(widget, elem, $elem, extraData) {
|
||||||
// Setup DOM metadata
|
// Setup DOM metadata
|
||||||
var data = { cloudStack: {} };
|
var data = {
|
||||||
data.cloudStack[widget] = {
|
cloudStack: {}
|
||||||
elem: elem
|
};
|
||||||
};
|
data.cloudStack[widget] = {
|
||||||
if (extraData) $.extend(data.cloudStack[widget], extraData);
|
elem: elem
|
||||||
|
};
|
||||||
|
if (extraData) $.extend(data.cloudStack[widget], extraData);
|
||||||
|
|
||||||
return $elem
|
return $elem
|
||||||
.addClass('cloudStack-elem')
|
.addClass('cloudStack-elem')
|
||||||
.addClass(widget)
|
.addClass(widget)
|
||||||
.data(data);
|
.data(data);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Create widget-based event
|
// Create widget-based event
|
||||||
bind: function(widget, events) {
|
bind: function(widget, events) {
|
||||||
return function(event) {
|
return function(event) {
|
||||||
var $target = $(event.target);
|
var $target = $(event.target);
|
||||||
var $widget, $elem;
|
var $widget, $elem;
|
||||||
var data, elem;
|
var data, elem;
|
||||||
|
|
||||||
$elem = $target.closest('.cloudStack-elem.' + widget);
|
$elem = $target.closest('.cloudStack-elem.' + widget);
|
||||||
if (!$elem.size())
|
if (!$elem.size())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
$widget = $('.cloudStack-widget.' + widget);
|
$widget = $('.cloudStack-widget.' + widget);
|
||||||
data = $elem.data('cloudStack')[widget];
|
data = $elem.data('cloudStack')[widget];
|
||||||
elem = data.elem;
|
elem = data.elem;
|
||||||
|
|
||||||
events[elem]($elem, $widget, data);
|
events[elem]($elem, $widget, data);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
// Trigger CloudStack UI event (cloudStack.*)
|
// Trigger CloudStack UI event (cloudStack.*)
|
||||||
call: function(eventName, data) {
|
call: function(eventName, data) {
|
||||||
$(window).trigger('cloudStack.' + eventName, data);
|
$(window).trigger('cloudStack.' + eventName, data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
@ -15,113 +15,110 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
// General utils
|
// General utils
|
||||||
cloudStack.serializeForm = function($form, options) {
|
cloudStack.serializeForm = function($form, options) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
|
|
||||||
var data = {};
|
var data = {};
|
||||||
|
|
||||||
$($form.serializeArray()).each(function() {
|
$($form.serializeArray()).each(function() {
|
||||||
var dataItem = data[this.name];
|
var dataItem = data[this.name];
|
||||||
var value = _s(this.value.toString());
|
var value = _s(this.value.toString());
|
||||||
|
|
||||||
if (options.escapeSlashes) {
|
if (options.escapeSlashes) {
|
||||||
value = value.replace(/\//g, '__forwardSlash__');
|
value = value.replace(/\//g, '__forwardSlash__');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dataItem) {
|
if (!dataItem) {
|
||||||
data[this.name] = value;
|
data[this.name] = value;
|
||||||
} else if (dataItem && !$.isArray(dataItem)) {
|
} else if (dataItem && !$.isArray(dataItem)) {
|
||||||
data[this.name] = [dataItem, value];
|
data[this.name] = [dataItem, value];
|
||||||
} else if($.isArray(dataItem)){
|
} else if ($.isArray(dataItem)) {
|
||||||
dataItem.push(value);
|
dataItem.push(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Even/odd row handling
|
// Even/odd row handling
|
||||||
cloudStack.evenOdd = function($container, itemSelector, args) {
|
cloudStack.evenOdd = function($container, itemSelector, args) {
|
||||||
var even = false;
|
var even = false;
|
||||||
|
|
||||||
$container.find(itemSelector).each(function() {
|
$container.find(itemSelector).each(function() {
|
||||||
var $elem = $(this);
|
var $elem = $(this);
|
||||||
|
|
||||||
if (even) {
|
if (even) {
|
||||||
even = false;
|
even = false;
|
||||||
args.odd($elem);
|
args.odd($elem);
|
||||||
} else {
|
} else {
|
||||||
even = true;
|
even = true;
|
||||||
args.even($elem);
|
args.even($elem);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Localization -- shortcut _l
|
* Localization -- shortcut _l
|
||||||
*
|
*
|
||||||
* Takes string and runs through localization function -- if no code
|
* Takes string and runs through localization function -- if no code
|
||||||
* exists or function isn't present, return string as-is
|
* exists or function isn't present, return string as-is
|
||||||
*/
|
*/
|
||||||
cloudStack.localize = window._l = function(str) {
|
cloudStack.localize = window._l = function(str) {
|
||||||
var localized = cloudStack.localizationFn ?
|
var localized = cloudStack.localizationFn ?
|
||||||
cloudStack.localizationFn(str) : null;
|
cloudStack.localizationFn(str) : null;
|
||||||
|
|
||||||
return localized ? localized : str;
|
return localized ? localized : str;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanitize user input (HTML Encoding) -- shortcut _s
|
* Sanitize user input (HTML Encoding) -- shortcut _s
|
||||||
*
|
*
|
||||||
* Strip unwanted characters from user-based input
|
* Strip unwanted characters from user-based input
|
||||||
*/
|
*/
|
||||||
cloudStack.sanitize = window._s = function(value) {
|
cloudStack.sanitize = window._s = function(value) {
|
||||||
if(typeof(value) == "number") {
|
if (typeof(value) == "number") {
|
||||||
//alert("number does not need to be sanitized. Only string needs to be sanitized.");
|
//alert("number does not need to be sanitized. Only string needs to be sanitized.");
|
||||||
return value;
|
return value;
|
||||||
}
|
} else if (typeof(value) == "boolean") {
|
||||||
else if(typeof(value) == "boolean") {
|
//alert("boolean does not need to be sanitized. Only string needs to be sanitized.");
|
||||||
//alert("boolean does not need to be sanitized. Only string needs to be sanitized.");
|
return value;
|
||||||
return value;
|
} else if (typeof(value) == "object") {
|
||||||
}
|
//alert("object cant not be sanitized. Only string can be sanitized.");
|
||||||
else if(typeof(value) == "object") {
|
return value;
|
||||||
//alert("object cant not be sanitized. Only string can be sanitized.");
|
} else if (typeof(value) == null || typeof(value) == "undefined") {
|
||||||
return value;
|
return '';
|
||||||
}
|
}
|
||||||
else if(typeof(value) == null || typeof(value) == "undefined") {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
var sanitized = value
|
var sanitized = value
|
||||||
.replace(/&/g, "&")
|
.replace(/&/g, "&")
|
||||||
.replace(/</g, "<")
|
.replace(/</g, "<")
|
||||||
.replace(/>/g, ">");
|
.replace(/>/g, ">");
|
||||||
|
|
||||||
return sanitized;
|
return sanitized;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse sanitization (HTML Decoding)
|
* Reverse sanitization (HTML Decoding)
|
||||||
*/
|
*/
|
||||||
cloudStack.sanitizeReverse = function(value) {
|
cloudStack.sanitizeReverse = function(value) {
|
||||||
var reversedValue = value
|
var reversedValue = value
|
||||||
.replace(/&/g, "&")
|
.replace(/&/g, "&")
|
||||||
.replace(/</g, "<")
|
.replace(/</g, "<")
|
||||||
.replace(/>/g, ">");
|
.replace(/>/g, ">");
|
||||||
|
|
||||||
return reversedValue;
|
return reversedValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the str.length is > maxLen,
|
* If the str.length is > maxLen,
|
||||||
* then concatenate and add '...' to the end of the string
|
* then concatenate and add '...' to the end of the string
|
||||||
*/
|
*/
|
||||||
cloudStack.concat = function(str, maxLen) {
|
cloudStack.concat = function(str, maxLen) {
|
||||||
if (str.length > maxLen) {
|
if (str.length > maxLen) {
|
||||||
return str.substr(0, maxLen) + '...';
|
return str.substr(0, maxLen) + '...';
|
||||||
} else {
|
} else {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
@ -15,418 +15,427 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.ui.widgets.browser = {};
|
cloudStack.ui.widgets.browser = {};
|
||||||
|
|
||||||
/**
|
|
||||||
* Breadcrumb-related functions
|
|
||||||
*/
|
|
||||||
var _breadcrumb = cloudStack.ui.widgets.browser.breadcrumb = {
|
|
||||||
/**
|
|
||||||
* Generate new breadcrumb
|
|
||||||
*/
|
|
||||||
create: function($panel, title) {
|
|
||||||
// Attach panel as ref for breadcrumb
|
|
||||||
return cloudStack.ui.event.elem(
|
|
||||||
'cloudBrowser', 'breadcrumb',
|
|
||||||
$('<div>')
|
|
||||||
.append(
|
|
||||||
$('<li>')
|
|
||||||
.attr({
|
|
||||||
title: title
|
|
||||||
})
|
|
||||||
.append(
|
|
||||||
$('<span>').html(title)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append($('<div>').addClass('end'))
|
|
||||||
.children(),
|
|
||||||
{
|
|
||||||
panel: $panel
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get breadcrumbs matching specified panels
|
* Breadcrumb-related functions
|
||||||
*/
|
*/
|
||||||
filter: function($panels) {
|
var _breadcrumb = cloudStack.ui.widgets.browser.breadcrumb = {
|
||||||
var $breadcrumbs = $('#breadcrumbs ul li');
|
/**
|
||||||
var $result = $([]);
|
* Generate new breadcrumb
|
||||||
|
*/
|
||||||
|
create: function($panel, title) {
|
||||||
|
// Attach panel as ref for breadcrumb
|
||||||
|
return cloudStack.ui.event.elem(
|
||||||
|
'cloudBrowser', 'breadcrumb',
|
||||||
|
$('<div>')
|
||||||
|
.append(
|
||||||
|
$('<li>')
|
||||||
|
.attr({
|
||||||
|
title: title
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
$('<span>').html(title)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.append($('<div>').addClass('end'))
|
||||||
|
.children(), {
|
||||||
|
panel: $panel
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
$panels.each(function() {
|
/**
|
||||||
var $panel = $(this);
|
* Get breadcrumbs matching specified panels
|
||||||
|
*/
|
||||||
|
filter: function($panels) {
|
||||||
|
var $breadcrumbs = $('#breadcrumbs ul li');
|
||||||
|
var $result = $([]);
|
||||||
|
|
||||||
$.merge(
|
$panels.each(function() {
|
||||||
$result,
|
var $panel = $(this);
|
||||||
$.merge(
|
|
||||||
$breadcrumbs.filter(function() {
|
|
||||||
return $(this).index('#breadcrumbs ul li') == $panel.index();
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Also include ends
|
$.merge(
|
||||||
$breadcrumbs.siblings('div.end').filter(function() {
|
$result,
|
||||||
return $(this).index('div.end') == $panel.index() + 1;
|
$.merge(
|
||||||
})
|
$breadcrumbs.filter(function() {
|
||||||
)
|
return $(this).index('#breadcrumbs ul li') == $panel.index();
|
||||||
);
|
}),
|
||||||
});
|
|
||||||
|
|
||||||
return $result;
|
// Also include ends
|
||||||
}
|
$breadcrumbs.siblings('div.end').filter(function() {
|
||||||
};
|
return $(this).index('div.end') == $panel.index() + 1;
|
||||||
|
})
|
||||||
/**
|
)
|
||||||
* Container-related functions
|
);
|
||||||
*/
|
|
||||||
var _container = cloudStack.ui.widgets.browser.container = {
|
|
||||||
/**
|
|
||||||
* Get all panels from container
|
|
||||||
*/
|
|
||||||
panels: function($container) {
|
|
||||||
return $container.find('div.panel');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Panel-related functions
|
|
||||||
*/
|
|
||||||
var _panel = cloudStack.ui.widgets.browser.panel = {
|
|
||||||
/**
|
|
||||||
* Compute width of panel, relative to container
|
|
||||||
*/
|
|
||||||
width: function($container, options) {
|
|
||||||
options = options ? options : {};
|
|
||||||
var width = $container.find('div.panel').size() < 1 || options.maximized == true ?
|
|
||||||
$container.width() : $container.width() - $container.width() / 4;
|
|
||||||
|
|
||||||
return width;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get left position
|
|
||||||
*/
|
|
||||||
position: function($container, options) {
|
|
||||||
return $container.find('div.panel').size() <= 1 || options.maximized == true ?
|
|
||||||
0 : _panel.width($container, options) - _panel.width($container, options) / 1.5;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the top panel z-index, for proper stacking
|
|
||||||
*/
|
|
||||||
topIndex: function($container) {
|
|
||||||
var base = 50; // Minimum z-index
|
|
||||||
|
|
||||||
return Math.max.apply(
|
|
||||||
null,
|
|
||||||
$.map(
|
|
||||||
$container.find('div.panel'),
|
|
||||||
function(elem) {
|
|
||||||
return parseInt($(elem).css('z-index')) || base;
|
|
||||||
}
|
|
||||||
)
|
|
||||||
) + 1;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* State when panel is outside container
|
|
||||||
*/
|
|
||||||
initialState: function($container) {
|
|
||||||
return {
|
|
||||||
left: $container.width()
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get panel and breadcrumb behind specific panel
|
|
||||||
*/
|
|
||||||
lower: function($container, $panel) {
|
|
||||||
return _container.panels($container).filter(function() {
|
|
||||||
return $(this).index() < $panel.index();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get panel and breadcrumb stacked above specific panel
|
|
||||||
*/
|
|
||||||
higher: function($container, $panel) {
|
|
||||||
return _container.panels($container).filter(function() {
|
|
||||||
return $(this).index() > $panel.index();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate new panel
|
|
||||||
*/
|
|
||||||
create: function($container, options) {
|
|
||||||
var $panel = $('<div>').addClass('panel').css(
|
|
||||||
{
|
|
||||||
position: 'absolute',
|
|
||||||
width: _panel.width($container, { maximized: options.maximized }),
|
|
||||||
zIndex: _panel.topIndex($container)
|
|
||||||
}
|
|
||||||
).append(
|
|
||||||
// Shadow
|
|
||||||
$('<div>').addClass('shadow')
|
|
||||||
).append(options.data);
|
|
||||||
|
|
||||||
if (options.maximized) $panel.addClass('always-maximized');
|
|
||||||
|
|
||||||
return $panel;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Browser -- jQuery widget
|
|
||||||
*/
|
|
||||||
$.widget('cloudStack.cloudBrowser', {
|
|
||||||
_init: function() {
|
|
||||||
this.element.addClass('cloudStack-widget cloudBrowser');
|
|
||||||
$('#breadcrumbs').append(
|
|
||||||
$('<ul>')
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make target panel the top-most
|
|
||||||
*/
|
|
||||||
selectPanel: function(args) {
|
|
||||||
var $panel = args.panel;
|
|
||||||
var $container = this.element;
|
|
||||||
var $toShow = _panel.lower($container, $panel);
|
|
||||||
var $toRemove = _panel.higher($container, $panel);
|
|
||||||
var complete = args.complete;
|
|
||||||
|
|
||||||
if ($panel.hasClass('maximized')) return false;
|
|
||||||
|
|
||||||
_breadcrumb.filter($toRemove).remove();
|
|
||||||
_breadcrumb.filter($panel.siblings()).removeClass('active');
|
|
||||||
_breadcrumb.filter($panel).addClass('active');
|
|
||||||
_breadcrumb.filter($('div.panel')).find('span').animate({
|
|
||||||
opacity: 1
|
|
||||||
});
|
|
||||||
_breadcrumb.filter(
|
|
||||||
$('div.panel.maximized')
|
|
||||||
.removeClass('maximized')
|
|
||||||
.addClass('reduced')
|
|
||||||
).removeClass('active maximized');
|
|
||||||
|
|
||||||
$toRemove.animate(
|
|
||||||
_panel.initialState($container),
|
|
||||||
{
|
|
||||||
duration: 500,
|
|
||||||
complete: function() {
|
|
||||||
$(this).remove();
|
|
||||||
|
|
||||||
if (complete) complete($toShow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
$toShow.show();
|
|
||||||
$panel.animate({
|
|
||||||
left: _panel.position($container, { maximized: $panel.hasClass('always-maximized') })
|
|
||||||
});
|
|
||||||
$panel.show().removeClass('reduced');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle selected panel as fully expanded, hiding/showing other panels
|
|
||||||
*/
|
|
||||||
toggleMaximizePanel: function(args) {
|
|
||||||
var $panel = args.panel;
|
|
||||||
var $container = this.element;
|
|
||||||
var $toHide = $panel.siblings(':not(.always-maximized)');
|
|
||||||
var $shadow = $toHide.find('div.shadow');
|
|
||||||
|
|
||||||
if (args.panel.hasClass('maximized')) {
|
|
||||||
_breadcrumb.filter($panel).removeClass('maximized');
|
|
||||||
$panel.removeClass('maximized');
|
|
||||||
$panel.addClass('reduced');
|
|
||||||
_breadcrumb.filter($panel.siblings()).find('span').animate({ opacity: 1 });
|
|
||||||
$toHide.animate({ left: _panel.position($container, {}) },
|
|
||||||
{ duration: 500 });
|
|
||||||
$shadow.show();
|
|
||||||
} else {
|
|
||||||
_breadcrumb.filter($panel).addClass('maximized');
|
|
||||||
$panel.removeClass('reduced');
|
|
||||||
$panel.addClass('maximized');
|
|
||||||
_breadcrumb.filter($panel.siblings()).find('span').animate({ opacity: 0.5 });
|
|
||||||
$toHide.animate(_panel.initialState($container),
|
|
||||||
{ duration: 500 });
|
|
||||||
$shadow.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append new panel to end of container
|
|
||||||
*/
|
|
||||||
addPanel: function(args) {
|
|
||||||
var duration = args.duration ? args.duration : 500;
|
|
||||||
var $container = this.element;
|
|
||||||
var $parent = args.parent;
|
|
||||||
var $panel, $reduced, targetPosition;
|
|
||||||
|
|
||||||
// Create panel
|
|
||||||
$panel = _panel.create(this.element, {
|
|
||||||
maximized: args.maximizeIfSelected,
|
|
||||||
data: args.data
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove existing panels from parent
|
|
||||||
if ($parent) {
|
|
||||||
// Cleanup transitioning panels -- prevent old complete actions from running
|
|
||||||
$parent.siblings().stop();
|
|
||||||
|
|
||||||
_breadcrumb.filter(
|
|
||||||
$('div.panel.maximized')
|
|
||||||
.removeClass('maximized')
|
|
||||||
.addClass('reduced')
|
|
||||||
).removeClass('active maximized');
|
|
||||||
|
|
||||||
$parent.removeClass('maximized');
|
|
||||||
_breadcrumb.filter($parent.next()).remove();
|
|
||||||
$container.find($parent.next()).remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append panel
|
|
||||||
$panel.appendTo($container);
|
|
||||||
_breadcrumb.filter($panel.siblings()).removeClass('active');
|
|
||||||
_breadcrumb.create($panel, args.title)
|
|
||||||
.addClass('active')
|
|
||||||
.appendTo('#breadcrumbs ul');
|
|
||||||
|
|
||||||
// Reduced appearance for previous panels
|
|
||||||
$panel.siblings().filter(function() {
|
|
||||||
return $(this).index() < $panel.index();
|
|
||||||
}).addClass('reduced');
|
|
||||||
|
|
||||||
// Panel initial state
|
|
||||||
if ($panel.index() == 0) $panel.addClass('always-maximized');
|
|
||||||
$panel.css(
|
|
||||||
_panel.initialState($container, $panel)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Panel slide-in
|
|
||||||
targetPosition = _panel.position($container, {
|
|
||||||
maximized: args.maximizeIfSelected
|
|
||||||
});
|
|
||||||
if (!$panel.index()) {
|
|
||||||
// Just show immediately if this is the first panel
|
|
||||||
$panel.css(
|
|
||||||
{ left: targetPosition }
|
|
||||||
);
|
|
||||||
if (args.complete) args.complete($panel, _breadcrumb.filter($panel));
|
|
||||||
} else {
|
|
||||||
// Animate slide-in
|
|
||||||
$panel.animate({ left: targetPosition }, {
|
|
||||||
duration: duration,
|
|
||||||
easing: 'easeOutCirc',
|
|
||||||
complete: function() {
|
|
||||||
// Hide panels
|
|
||||||
$panel.siblings().filter(function() {
|
|
||||||
return $(this).width() == $panel.width();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($panel.is(':visible') && args.complete) args.complete($panel);
|
return $result;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
};
|
|
||||||
|
|
||||||
return $panel;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all panels
|
* Container-related functions
|
||||||
*/
|
*/
|
||||||
removeAllPanels: function(args) {
|
var _container = cloudStack.ui.widgets.browser.container = {
|
||||||
$('div.panel').stop(); // Prevent destroyed panels from animating
|
/**
|
||||||
this.element.find('div.panel').remove();
|
* Get all panels from container
|
||||||
$('#breadcrumbs').find('ul li').remove();
|
*/
|
||||||
$('#breadcrumbs').find('ul div.end').remove();
|
panels: function($container) {
|
||||||
}
|
return $container.find('div.panel');
|
||||||
});
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$('#breadcrumbs li').live('click', cloudStack.ui.event.bind(
|
/**
|
||||||
'cloudBrowser',
|
* Panel-related functions
|
||||||
{
|
*/
|
||||||
'breadcrumb': function($target, $browser, data) {
|
var _panel = cloudStack.ui.widgets.browser.panel = {
|
||||||
|
/**
|
||||||
|
* Compute width of panel, relative to container
|
||||||
|
*/
|
||||||
|
width: function($container, options) {
|
||||||
|
options = options ? options : {};
|
||||||
|
var width = $container.find('div.panel').size() < 1 || options.maximized == true ?
|
||||||
|
$container.width() : $container.width() - $container.width() / 4;
|
||||||
|
|
||||||
if ($ ('#browser').hasClass('panel-highlight')) {
|
return width;
|
||||||
return false;
|
},
|
||||||
}
|
|
||||||
|
|
||||||
$browser.cloudBrowser('selectPanel', { panel: data.panel });
|
/**
|
||||||
}
|
* Get left position
|
||||||
}
|
*/
|
||||||
));
|
position: function($container, options) {
|
||||||
|
return $container.find('div.panel').size() <= 1 || options.maximized == true ?
|
||||||
|
0 : _panel.width($container, options) - _panel.width($container, options) / 1.5;
|
||||||
|
},
|
||||||
|
|
||||||
// Breadcrumb hovering
|
/**
|
||||||
$('#breadcrumbs li').live('mouseover', cloudStack.ui.event.bind(
|
* Get the top panel z-index, for proper stacking
|
||||||
'cloudBrowser',
|
*/
|
||||||
{
|
topIndex: function($container) {
|
||||||
'breadcrumb': function($target, $browser, data) {
|
var base = 50; // Minimum z-index
|
||||||
var $hiddenPanels = data.panel.siblings().filter(function(){
|
|
||||||
return $(this).index() > data.panel.index();
|
|
||||||
});
|
|
||||||
var $targetPanel = data.panel.filter(':first');
|
|
||||||
var $targetBreadcrumb = _breadcrumb.filter($targetPanel);
|
|
||||||
var $panelWrapper = $('<div>').addClass('panel panel-highlight-wrapper');
|
|
||||||
|
|
||||||
$hiddenPanels.addClass('mouseover-hidden');
|
return Math.max.apply(
|
||||||
|
null,
|
||||||
|
$.map(
|
||||||
|
$container.find('div.panel'),
|
||||||
|
function(elem) {
|
||||||
|
return parseInt($(elem).css('z-index')) || base;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) + 1;
|
||||||
|
},
|
||||||
|
|
||||||
$browser.data('browser-panel-highlight-timer', setTimeout(function() {
|
/**
|
||||||
$('#browser').addClass('panel-highlight');
|
* State when panel is outside container
|
||||||
$('.overlay').remove();
|
*/
|
||||||
|
initialState: function($container) {
|
||||||
|
return {
|
||||||
|
left: $container.width()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
// Setup panel and wrapper positioning
|
/**
|
||||||
$panelWrapper
|
* Get panel and breadcrumb behind specific panel
|
||||||
.css({
|
*/
|
||||||
left: $targetPanel.position().left
|
lower: function($container, $panel) {
|
||||||
})
|
return _container.panels($container).filter(function() {
|
||||||
.width($targetPanel.width());
|
return $(this).index() < $panel.index();
|
||||||
$targetPanel
|
});
|
||||||
.wrap($panelWrapper);
|
},
|
||||||
$panelWrapper
|
|
||||||
.zIndex(10000)
|
|
||||||
.overlay();
|
|
||||||
$targetPanel.filter(':last').addClass('highlighted');
|
|
||||||
|
|
||||||
// Setup breadcrumbs
|
/**
|
||||||
$targetBreadcrumb.each(function() {
|
* Get panel and breadcrumb stacked above specific panel
|
||||||
$(this).data('breadcrumb-original-zindex', $(this).zIndex());
|
*/
|
||||||
});
|
higher: function($container, $panel) {
|
||||||
$targetBreadcrumb.zIndex(10001);
|
return _container.panels($container).filter(function() {
|
||||||
|
return $(this).index() > $panel.index();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
$hiddenPanels.hide();
|
/**
|
||||||
}, 1000));
|
* Generate new panel
|
||||||
}
|
*/
|
||||||
}
|
create: function($container, options) {
|
||||||
));
|
var $panel = $('<div>').addClass('panel').css({
|
||||||
|
position: 'absolute',
|
||||||
|
width: _panel.width($container, {
|
||||||
|
maximized: options.maximized
|
||||||
|
}),
|
||||||
|
zIndex: _panel.topIndex($container)
|
||||||
|
}).append(
|
||||||
|
// Shadow
|
||||||
|
$('<div>').addClass('shadow')
|
||||||
|
).append(options.data);
|
||||||
|
|
||||||
$('#breadcrumbs li').live('mouseout',cloudStack.ui.event.bind(
|
if (options.maximized) $panel.addClass('always-maximized');
|
||||||
'cloudBrowser',
|
|
||||||
{
|
|
||||||
'breadcrumb': function($target, $browser, data) {
|
|
||||||
var $getHiddenPanels = $browser.find('.panel.mouseover-hidden');
|
|
||||||
var $visiblePanels = $getHiddenPanels.siblings();
|
|
||||||
var $visibleBreadcrumbs = _breadcrumb.filter($visiblePanels);
|
|
||||||
|
|
||||||
clearTimeout($browser.data('browser-panel-highlight-timer'));
|
return $panel;
|
||||||
$('#browser').removeClass('panel-highlight');
|
}
|
||||||
$('#browser .panel').removeClass('highlighted');
|
};
|
||||||
$('#browser .panel.panel-highlight-wrapper').each(function() {
|
|
||||||
var $wrapper = $(this);
|
|
||||||
var $panel = $wrapper.find('.panel');
|
|
||||||
|
|
||||||
$wrapper.after($panel);
|
/**
|
||||||
$wrapper.remove();
|
* Browser -- jQuery widget
|
||||||
});
|
*/
|
||||||
$getHiddenPanels.removeClass('mouseover-hidden').show();
|
$.widget('cloudStack.cloudBrowser', {
|
||||||
$visibleBreadcrumbs.each(function() {
|
_init: function() {
|
||||||
$(this).zIndex($(this).data('breadcrumb-original-zindex'));
|
this.element.addClass('cloudStack-widget cloudBrowser');
|
||||||
});
|
$('#breadcrumbs').append(
|
||||||
$('.overlay').remove();
|
$('<ul>')
|
||||||
$('#browser .panel > .highlight-arrow').remove();
|
);
|
||||||
}
|
},
|
||||||
}
|
|
||||||
));
|
/**
|
||||||
|
* Make target panel the top-most
|
||||||
|
*/
|
||||||
|
selectPanel: function(args) {
|
||||||
|
var $panel = args.panel;
|
||||||
|
var $container = this.element;
|
||||||
|
var $toShow = _panel.lower($container, $panel);
|
||||||
|
var $toRemove = _panel.higher($container, $panel);
|
||||||
|
var complete = args.complete;
|
||||||
|
|
||||||
|
if ($panel.hasClass('maximized')) return false;
|
||||||
|
|
||||||
|
_breadcrumb.filter($toRemove).remove();
|
||||||
|
_breadcrumb.filter($panel.siblings()).removeClass('active');
|
||||||
|
_breadcrumb.filter($panel).addClass('active');
|
||||||
|
_breadcrumb.filter($('div.panel')).find('span').animate({
|
||||||
|
opacity: 1
|
||||||
|
});
|
||||||
|
_breadcrumb.filter(
|
||||||
|
$('div.panel.maximized')
|
||||||
|
.removeClass('maximized')
|
||||||
|
.addClass('reduced')
|
||||||
|
).removeClass('active maximized');
|
||||||
|
|
||||||
|
$toRemove.animate(
|
||||||
|
_panel.initialState($container), {
|
||||||
|
duration: 500,
|
||||||
|
complete: function() {
|
||||||
|
$(this).remove();
|
||||||
|
|
||||||
|
if (complete) complete($toShow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$toShow.show();
|
||||||
|
$panel.animate({
|
||||||
|
left: _panel.position($container, {
|
||||||
|
maximized: $panel.hasClass('always-maximized')
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$panel.show().removeClass('reduced');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle selected panel as fully expanded, hiding/showing other panels
|
||||||
|
*/
|
||||||
|
toggleMaximizePanel: function(args) {
|
||||||
|
var $panel = args.panel;
|
||||||
|
var $container = this.element;
|
||||||
|
var $toHide = $panel.siblings(':not(.always-maximized)');
|
||||||
|
var $shadow = $toHide.find('div.shadow');
|
||||||
|
|
||||||
|
if (args.panel.hasClass('maximized')) {
|
||||||
|
_breadcrumb.filter($panel).removeClass('maximized');
|
||||||
|
$panel.removeClass('maximized');
|
||||||
|
$panel.addClass('reduced');
|
||||||
|
_breadcrumb.filter($panel.siblings()).find('span').animate({
|
||||||
|
opacity: 1
|
||||||
|
});
|
||||||
|
$toHide.animate({
|
||||||
|
left: _panel.position($container, {})
|
||||||
|
}, {
|
||||||
|
duration: 500
|
||||||
|
});
|
||||||
|
$shadow.show();
|
||||||
|
} else {
|
||||||
|
_breadcrumb.filter($panel).addClass('maximized');
|
||||||
|
$panel.removeClass('reduced');
|
||||||
|
$panel.addClass('maximized');
|
||||||
|
_breadcrumb.filter($panel.siblings()).find('span').animate({
|
||||||
|
opacity: 0.5
|
||||||
|
});
|
||||||
|
$toHide.animate(_panel.initialState($container), {
|
||||||
|
duration: 500
|
||||||
|
});
|
||||||
|
$shadow.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append new panel to end of container
|
||||||
|
*/
|
||||||
|
addPanel: function(args) {
|
||||||
|
var duration = args.duration ? args.duration : 500;
|
||||||
|
var $container = this.element;
|
||||||
|
var $parent = args.parent;
|
||||||
|
var $panel, $reduced, targetPosition;
|
||||||
|
|
||||||
|
// Create panel
|
||||||
|
$panel = _panel.create(this.element, {
|
||||||
|
maximized: args.maximizeIfSelected,
|
||||||
|
data: args.data
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove existing panels from parent
|
||||||
|
if ($parent) {
|
||||||
|
// Cleanup transitioning panels -- prevent old complete actions from running
|
||||||
|
$parent.siblings().stop();
|
||||||
|
|
||||||
|
_breadcrumb.filter(
|
||||||
|
$('div.panel.maximized')
|
||||||
|
.removeClass('maximized')
|
||||||
|
.addClass('reduced')
|
||||||
|
).removeClass('active maximized');
|
||||||
|
|
||||||
|
$parent.removeClass('maximized');
|
||||||
|
_breadcrumb.filter($parent.next()).remove();
|
||||||
|
$container.find($parent.next()).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append panel
|
||||||
|
$panel.appendTo($container);
|
||||||
|
_breadcrumb.filter($panel.siblings()).removeClass('active');
|
||||||
|
_breadcrumb.create($panel, args.title)
|
||||||
|
.addClass('active')
|
||||||
|
.appendTo('#breadcrumbs ul');
|
||||||
|
|
||||||
|
// Reduced appearance for previous panels
|
||||||
|
$panel.siblings().filter(function() {
|
||||||
|
return $(this).index() < $panel.index();
|
||||||
|
}).addClass('reduced');
|
||||||
|
|
||||||
|
// Panel initial state
|
||||||
|
if ($panel.index() == 0) $panel.addClass('always-maximized');
|
||||||
|
$panel.css(
|
||||||
|
_panel.initialState($container, $panel)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Panel slide-in
|
||||||
|
targetPosition = _panel.position($container, {
|
||||||
|
maximized: args.maximizeIfSelected
|
||||||
|
});
|
||||||
|
if (!$panel.index()) {
|
||||||
|
// Just show immediately if this is the first panel
|
||||||
|
$panel.css({
|
||||||
|
left: targetPosition
|
||||||
|
});
|
||||||
|
if (args.complete) args.complete($panel, _breadcrumb.filter($panel));
|
||||||
|
} else {
|
||||||
|
// Animate slide-in
|
||||||
|
$panel.animate({
|
||||||
|
left: targetPosition
|
||||||
|
}, {
|
||||||
|
duration: duration,
|
||||||
|
easing: 'easeOutCirc',
|
||||||
|
complete: function() {
|
||||||
|
// Hide panels
|
||||||
|
$panel.siblings().filter(function() {
|
||||||
|
return $(this).width() == $panel.width();
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($panel.is(':visible') && args.complete) args.complete($panel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return $panel;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all panels
|
||||||
|
*/
|
||||||
|
removeAllPanels: function(args) {
|
||||||
|
$('div.panel').stop(); // Prevent destroyed panels from animating
|
||||||
|
this.element.find('div.panel').remove();
|
||||||
|
$('#breadcrumbs').find('ul li').remove();
|
||||||
|
$('#breadcrumbs').find('ul div.end').remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#breadcrumbs li').live('click', cloudStack.ui.event.bind(
|
||||||
|
'cloudBrowser', {
|
||||||
|
'breadcrumb': function($target, $browser, data) {
|
||||||
|
|
||||||
|
if ($('#browser').hasClass('panel-highlight')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$browser.cloudBrowser('selectPanel', {
|
||||||
|
panel: data.panel
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
// Breadcrumb hovering
|
||||||
|
$('#breadcrumbs li').live('mouseover', cloudStack.ui.event.bind(
|
||||||
|
'cloudBrowser', {
|
||||||
|
'breadcrumb': function($target, $browser, data) {
|
||||||
|
var $hiddenPanels = data.panel.siblings().filter(function() {
|
||||||
|
return $(this).index() > data.panel.index();
|
||||||
|
});
|
||||||
|
var $targetPanel = data.panel.filter(':first');
|
||||||
|
var $targetBreadcrumb = _breadcrumb.filter($targetPanel);
|
||||||
|
var $panelWrapper = $('<div>').addClass('panel panel-highlight-wrapper');
|
||||||
|
|
||||||
|
$hiddenPanels.addClass('mouseover-hidden');
|
||||||
|
|
||||||
|
$browser.data('browser-panel-highlight-timer', setTimeout(function() {
|
||||||
|
$('#browser').addClass('panel-highlight');
|
||||||
|
$('.overlay').remove();
|
||||||
|
|
||||||
|
// Setup panel and wrapper positioning
|
||||||
|
$panelWrapper
|
||||||
|
.css({
|
||||||
|
left: $targetPanel.position().left
|
||||||
|
})
|
||||||
|
.width($targetPanel.width());
|
||||||
|
$targetPanel
|
||||||
|
.wrap($panelWrapper);
|
||||||
|
$panelWrapper
|
||||||
|
.zIndex(10000)
|
||||||
|
.overlay();
|
||||||
|
$targetPanel.filter(':last').addClass('highlighted');
|
||||||
|
|
||||||
|
// Setup breadcrumbs
|
||||||
|
$targetBreadcrumb.each(function() {
|
||||||
|
$(this).data('breadcrumb-original-zindex', $(this).zIndex());
|
||||||
|
});
|
||||||
|
$targetBreadcrumb.zIndex(10001);
|
||||||
|
|
||||||
|
$hiddenPanels.hide();
|
||||||
|
}, 1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
$('#breadcrumbs li').live('mouseout', cloudStack.ui.event.bind(
|
||||||
|
'cloudBrowser', {
|
||||||
|
'breadcrumb': function($target, $browser, data) {
|
||||||
|
var $getHiddenPanels = $browser.find('.panel.mouseover-hidden');
|
||||||
|
var $visiblePanels = $getHiddenPanels.siblings();
|
||||||
|
var $visibleBreadcrumbs = _breadcrumb.filter($visiblePanels);
|
||||||
|
|
||||||
|
clearTimeout($browser.data('browser-panel-highlight-timer'));
|
||||||
|
$('#browser').removeClass('panel-highlight');
|
||||||
|
$('#browser .panel').removeClass('highlighted');
|
||||||
|
$('#browser .panel.panel-highlight-wrapper').each(function() {
|
||||||
|
var $wrapper = $(this);
|
||||||
|
var $panel = $wrapper.find('.panel');
|
||||||
|
|
||||||
|
$wrapper.after($panel);
|
||||||
|
$wrapper.remove();
|
||||||
|
});
|
||||||
|
$getHiddenPanels.removeClass('mouseover-hidden').show();
|
||||||
|
$visibleBreadcrumbs.each(function() {
|
||||||
|
$(this).zIndex($(this).data('breadcrumb-original-zindex'));
|
||||||
|
});
|
||||||
|
$('.overlay').remove();
|
||||||
|
$('#browser .panel > .highlight-arrow').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
@ -15,264 +15,264 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($) {
|
(function($) {
|
||||||
/**
|
|
||||||
* Convert table to be resizable and sortable
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$.fn.dataTable = function(method, options) {
|
|
||||||
var $table = this;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if position is in 'resize zone'
|
* Convert table to be resizable and sortable
|
||||||
*
|
*
|
||||||
* @return boolean, true if position is within bounds
|
|
||||||
*/
|
*/
|
||||||
var withinResizeBounds = function($elem, posX) {
|
$.fn.dataTable = function(method, options) {
|
||||||
var leftBound = $elem.offset().left + $elem.width() / 1.2;
|
var $table = this;
|
||||||
|
|
||||||
return posX > leftBound;
|
/**
|
||||||
};
|
* Check if position is in 'resize zone'
|
||||||
|
*
|
||||||
|
* @return boolean, true if position is within bounds
|
||||||
|
*/
|
||||||
|
var withinResizeBounds = function($elem, posX) {
|
||||||
|
var leftBound = $elem.offset().left + $elem.width() / 1.2;
|
||||||
|
|
||||||
/**
|
return posX > leftBound;
|
||||||
* Handles actual resizing of table headers
|
};
|
||||||
*/
|
|
||||||
var resizeDragEvent = function(event) {
|
|
||||||
var $elem = $(this);
|
|
||||||
|
|
||||||
if (event.type == 'mousedown') {
|
/**
|
||||||
$elem.addClass('dragging');
|
* Handles actual resizing of table headers
|
||||||
|
*/
|
||||||
|
var resizeDragEvent = function(event) {
|
||||||
|
var $elem = $(this);
|
||||||
|
|
||||||
return false;
|
if (event.type == 'mousedown') {
|
||||||
} else if (event.type == 'mouseup') {
|
$elem.addClass('dragging');
|
||||||
$table.find('th').removeClass('dragging');
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
} else if (event.type == 'mouseup') {
|
||||||
|
$table.find('th').removeClass('dragging');
|
||||||
|
|
||||||
var isDraggable = $elem.hasClass('dragging');
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isDraggable) {
|
var isDraggable = $elem.hasClass('dragging');
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var columnIndex = $elem.index();
|
if (!isDraggable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Get all TDs from column
|
var columnIndex = $elem.index();
|
||||||
var columnCells = [];
|
|
||||||
$table.find('tbody tr:first').each(function() {
|
|
||||||
var targetCell = $($(this).find('td')[columnIndex]);
|
|
||||||
|
|
||||||
columnCells.push(targetCell);
|
// Get all TDs from column
|
||||||
});
|
var columnCells = [];
|
||||||
|
$table.find('tbody tr:first').each(function() {
|
||||||
|
var targetCell = $($(this).find('td')[columnIndex]);
|
||||||
|
|
||||||
var tolerance = 25;
|
columnCells.push(targetCell);
|
||||||
var targetWidth = event.pageX - $elem.offset().left + tolerance;
|
});
|
||||||
$(columnCells).each(function() {
|
|
||||||
$(this).css({
|
|
||||||
width: targetWidth
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
resizeHeaders();
|
var tolerance = 25;
|
||||||
|
var targetWidth = event.pageX - $elem.offset().left + tolerance;
|
||||||
|
$(columnCells).each(function() {
|
||||||
|
$(this).css({
|
||||||
|
width: targetWidth
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
resizeHeaders();
|
||||||
};
|
|
||||||
|
|
||||||
var splitTable = function() {
|
return true;
|
||||||
var $mainContainer = $('<div>')
|
};
|
||||||
.addClass('data-table')
|
|
||||||
.appendTo($table.parent())
|
var splitTable = function() {
|
||||||
.append(
|
var $mainContainer = $('<div>')
|
||||||
$table.remove()
|
.addClass('data-table')
|
||||||
|
.appendTo($table.parent())
|
||||||
|
.append(
|
||||||
|
$table.remove()
|
||||||
);
|
);
|
||||||
$table = $mainContainer;
|
$table = $mainContainer;
|
||||||
var $theadContainer = $('<div>').addClass('fixed-header').prependTo($table);
|
var $theadContainer = $('<div>').addClass('fixed-header').prependTo($table);
|
||||||
var $theadTable = $('<table>').appendTo($theadContainer).attr('nowrap', 'nowrap');
|
var $theadTable = $('<table>').appendTo($theadContainer).attr('nowrap', 'nowrap');
|
||||||
var $thead = $table.find('thead').remove().appendTo($theadTable);
|
var $thead = $table.find('thead').remove().appendTo($theadTable);
|
||||||
|
|
||||||
return $thead;
|
return $thead;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event to set resizable appearance on hover
|
* Event to set resizable appearance on hover
|
||||||
*/
|
*/
|
||||||
var hoverResizableEvent = function(event) {
|
var hoverResizableEvent = function(event) {
|
||||||
var $elem = $(this);
|
var $elem = $(this);
|
||||||
var posX = event.pageX;
|
var posX = event.pageX;
|
||||||
|
|
||||||
if (event.type != 'mouseout' && withinResizeBounds($elem, posX)) {
|
if (event.type != 'mouseout' && withinResizeBounds($elem, posX)) {
|
||||||
$elem.addClass('resizable');
|
$elem.addClass('resizable');
|
||||||
} else {
|
} else {
|
||||||
$elem.removeClass('resizable');
|
$elem.removeClass('resizable');
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make row at specified index selected or unselected
|
* Make row at specified index selected or unselected
|
||||||
*
|
*
|
||||||
* @param rowIndex Row's index, starting at 1
|
* @param rowIndex Row's index, starting at 1
|
||||||
*/
|
*/
|
||||||
var toggleSelectRow = function(rowIndex) {
|
var toggleSelectRow = function(rowIndex) {
|
||||||
var $rows = $table.find('tbody tr');
|
var $rows = $table.find('tbody tr');
|
||||||
var $row = $($rows[rowIndex]);
|
var $row = $($rows[rowIndex]);
|
||||||
|
|
||||||
$row.siblings().removeClass('selected');
|
$row.siblings().removeClass('selected');
|
||||||
return $row.addClass('selected');
|
return $row.addClass('selected');
|
||||||
};
|
};
|
||||||
|
|
||||||
var computeEvenOddRows = function() {
|
var computeEvenOddRows = function() {
|
||||||
var currentRowType = 'even';
|
var currentRowType = 'even';
|
||||||
$table.find('tbody tr').each(function() {
|
$table.find('tbody tr').each(function() {
|
||||||
var $row = $(this);
|
var $row = $(this);
|
||||||
|
|
||||||
$row.removeClass('even').removeClass('odd');
|
$row.removeClass('even').removeClass('odd');
|
||||||
$row.addClass(currentRowType);
|
$row.addClass(currentRowType);
|
||||||
|
|
||||||
if (currentRowType == 'even') currentRowType = 'odd';
|
if (currentRowType == 'even') currentRowType = 'odd';
|
||||||
else currentRowType = 'even';
|
else currentRowType = 'even';
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort table by column
|
* Sort table by column
|
||||||
*
|
*
|
||||||
* @param columnIndex Index of column (starting at 0) to sort by
|
* @param columnIndex Index of column (starting at 0) to sort by
|
||||||
*/
|
*/
|
||||||
var sortTable = function(columnIndex) {
|
var sortTable = function(columnIndex) {
|
||||||
return false;
|
return false;
|
||||||
var direction = 'asc';
|
var direction = 'asc';
|
||||||
|
|
||||||
if ($table.find('thead th').hasClass('sorted ' + direction)) {
|
if ($table.find('thead th').hasClass('sorted ' + direction)) {
|
||||||
direction = 'desc';
|
direction = 'desc';
|
||||||
}
|
}
|
||||||
|
|
||||||
$table.find('thead th').removeClass('sorted desc asc');
|
$table.find('thead th').removeClass('sorted desc asc');
|
||||||
$($table.find('thead th')[columnIndex]).addClass('sorted').addClass(direction);
|
$($table.find('thead th')[columnIndex]).addClass('sorted').addClass(direction);
|
||||||
|
|
||||||
var $elems = $table.find('tbody td').filter(function() {
|
var $elems = $table.find('tbody td').filter(function() {
|
||||||
return $(this).index() == columnIndex;
|
return $(this).index() == columnIndex;
|
||||||
});
|
});
|
||||||
|
|
||||||
var sortData = [];
|
var sortData = [];
|
||||||
$elems.each(function() {
|
$elems.each(function() {
|
||||||
sortData.push($(this).html());
|
sortData.push($(this).html());
|
||||||
sortData.sort();
|
sortData.sort();
|
||||||
|
|
||||||
if (direction == 'asc') {
|
if (direction == 'asc') {
|
||||||
sortData.reverse();
|
sortData.reverse();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(sortData).each(function() {
|
$(sortData).each(function() {
|
||||||
var sortKey = this;
|
var sortKey = this;
|
||||||
var $targetCell = $elems.filter(function() {
|
var $targetCell = $elems.filter(function() {
|
||||||
return $(this).html() == sortKey;
|
return $(this).html() == sortKey;
|
||||||
});
|
});
|
||||||
var $targetContainer = $targetCell.parent();
|
var $targetContainer = $targetCell.parent();
|
||||||
|
|
||||||
$targetContainer.remove().appendTo($table.find('tbody'));
|
$targetContainer.remove().appendTo($table.find('tbody'));
|
||||||
});
|
});
|
||||||
|
|
||||||
computeEvenOddRows();
|
computeEvenOddRows();
|
||||||
};
|
};
|
||||||
|
|
||||||
var resizeHeaders = function() {
|
var resizeHeaders = function() {
|
||||||
var $thead = $table.closest('div.data-table').find('thead');
|
var $thead = $table.closest('div.data-table').find('thead');
|
||||||
var $tbody = $table.find('tbody');
|
var $tbody = $table.find('tbody');
|
||||||
var $ths = $thead.find('th');
|
var $ths = $thead.find('th');
|
||||||
var $tds = $tbody.find('tr:first td');
|
var $tds = $tbody.find('tr:first td');
|
||||||
|
|
||||||
if ($ths.size() > $tds.size()) {
|
if ($ths.size() > $tds.size()) {
|
||||||
$ths.width(
|
$ths.width(
|
||||||
$table.width() / $ths.size()
|
$table.width() / $ths.size()
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ths.each(function() {
|
$ths.each(function() {
|
||||||
var $th = $(this);
|
var $th = $(this);
|
||||||
|
|
||||||
var $td = $tds.filter(function() {
|
var $td = $tds.filter(function() {
|
||||||
return $(this).index() == $th.index();
|
return $(this).index() == $th.index();
|
||||||
});
|
});
|
||||||
|
|
||||||
$th.width($td.width());
|
$th.width($td.width());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
return $ths;
|
return $ths;
|
||||||
};
|
};
|
||||||
|
|
||||||
var methods = {
|
var methods = {
|
||||||
removeRow: function(rowIndex) {
|
removeRow: function(rowIndex) {
|
||||||
var $row = $($table.find('tbody tr')[rowIndex]);
|
var $row = $($table.find('tbody tr')[rowIndex]);
|
||||||
|
|
||||||
$row.fadeOut(function() {
|
$row.fadeOut(function() {
|
||||||
$row.remove();
|
$row.remove();
|
||||||
computeEvenOddRows();
|
computeEvenOddRows();
|
||||||
});
|
});
|
||||||
|
|
||||||
return $row;
|
return $row;
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
resizeHeaders();
|
resizeHeaders();
|
||||||
computeEvenOddRows();
|
computeEvenOddRows();
|
||||||
},
|
},
|
||||||
|
|
||||||
selectRow: function(rowIndex) {
|
selectRow: function(rowIndex) {
|
||||||
var $row = $($table.find('tbody tr')[rowIndex]);
|
var $row = $($table.find('tbody tr')[rowIndex]);
|
||||||
|
|
||||||
$row.siblings().removeClass('selected');
|
$row.siblings().removeClass('selected');
|
||||||
$row.addClass('selected');
|
$row.addClass('selected');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var init = function() {
|
var init = function() {
|
||||||
var noSelect = options && options.noSelect == true ? true : false;
|
var noSelect = options && options.noSelect == true ? true : false;
|
||||||
if (!$table.closest('div.data-table').size() && !$table.hasClass('no-split')) {
|
if (!$table.closest('div.data-table').size() && !$table.hasClass('no-split')) {
|
||||||
splitTable();
|
splitTable();
|
||||||
$table.find('tbody').closest('table').addClass('body');
|
$table.find('tbody').closest('table').addClass('body');
|
||||||
}
|
}
|
||||||
|
|
||||||
$table.find('th').bind('mousemove mouseout', hoverResizableEvent);
|
$table.find('th').bind('mousemove mouseout', hoverResizableEvent);
|
||||||
$table.find('th').bind('mousedown mousemove mouseup mouseout', resizeDragEvent);
|
$table.find('th').bind('mousedown mousemove mouseup mouseout', resizeDragEvent);
|
||||||
$table.find('th').bind('click', function(event) {
|
$table.find('th').bind('click', function(event) {
|
||||||
if ($(this).hasClass('resizable')) {
|
if ($(this).hasClass('resizable')) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sortTable($(event.target).index());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$table.bind('click', function(event) {
|
||||||
|
var $tr = $(event.target).closest('tr');
|
||||||
|
|
||||||
|
if (!$tr.size() || noSelect) return true;
|
||||||
|
var rowIndex = $tr.index();
|
||||||
|
|
||||||
|
toggleSelectRow(rowIndex);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
computeEvenOddRows();
|
||||||
|
resizeHeaders();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (methods[method]) {
|
||||||
|
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||||
|
} else if (!method) {
|
||||||
|
init();
|
||||||
|
} else {
|
||||||
|
$.error('Method ' + method + ' does not exist on jQuery.dataTable');
|
||||||
}
|
}
|
||||||
|
|
||||||
sortTable($(event.target).index());
|
return $table;
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$table.bind('click', function(event) {
|
|
||||||
var $tr = $(event.target).closest('tr');
|
|
||||||
|
|
||||||
if (!$tr.size() || noSelect) return true;
|
|
||||||
var rowIndex = $tr.index();
|
|
||||||
|
|
||||||
toggleSelectRow(rowIndex);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
computeEvenOddRows();
|
|
||||||
resizeHeaders();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (methods[method]) {
|
|
||||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
|
||||||
} else if (!method) {
|
|
||||||
init();
|
|
||||||
} else {
|
|
||||||
$.error('Method ' + method + ' does not exist on jQuery.dataTable');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $table;
|
|
||||||
};
|
|
||||||
}(jQuery));
|
}(jQuery));
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -15,356 +15,367 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack, _l) {
|
(function($, cloudStack, _l) {
|
||||||
/**
|
/**
|
||||||
* Notification handling
|
* Notification handling
|
||||||
*/
|
*/
|
||||||
var notifications = {
|
var notifications = {
|
||||||
activeTasks: [],
|
activeTasks: [],
|
||||||
cornerAlert: function(args, options) {
|
cornerAlert: function(args, options) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
|
|
||||||
var $container = $('#container'); // Put in main container box
|
var $container = $('#container'); // Put in main container box
|
||||||
var $cornerAlert = $('<div>').addClass('notification corner-alert')
|
var $cornerAlert = $('<div>').addClass('notification corner-alert')
|
||||||
.hide()
|
.hide()
|
||||||
.appendTo($container)
|
.appendTo($container)
|
||||||
.append(
|
|
||||||
$('<div>').addClass('title').append(
|
|
||||||
$('<span>').html(
|
|
||||||
options.error ? options.error : _l('label.task.completed')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('message')
|
|
||||||
.append(
|
.append(
|
||||||
$('<span>').html(_l(args.message))
|
$('<div>').addClass('title').append(
|
||||||
)
|
$('<span>').html(
|
||||||
);
|
options.error ? options.error : _l('label.task.completed')
|
||||||
|
)
|
||||||
if (options.error) {
|
)
|
||||||
$cornerAlert.addClass('error');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $cornerAlert
|
|
||||||
.css({
|
|
||||||
opacity: 0,
|
|
||||||
position: 'absolute',
|
|
||||||
top: $($container).height(),
|
|
||||||
left: $($container).width() - $cornerAlert.width()
|
|
||||||
})
|
|
||||||
.animate({
|
|
||||||
opacity: 1,
|
|
||||||
top: $container.height() - $cornerAlert.height()
|
|
||||||
}, {
|
|
||||||
complete: function() {
|
|
||||||
setTimeout(function() {
|
|
||||||
$cornerAlert.fadeOut('fast', function() {
|
|
||||||
$cornerAlert.remove();
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.show();
|
|
||||||
},
|
|
||||||
add: function(args, $popup, $total) {
|
|
||||||
var currentTotal = parseInt($total.html());
|
|
||||||
var newTotal = currentTotal + 1;
|
|
||||||
var desc = args.desc;
|
|
||||||
var section = $('html body')
|
|
||||||
.find('[cloudStack-container]')
|
|
||||||
.data('cloudStack-args')
|
|
||||||
.sections[args.section];
|
|
||||||
var _custom = args._custom;
|
|
||||||
|
|
||||||
var $item = $('<li>')
|
|
||||||
.append(
|
|
||||||
$('<span>').html(_l(args.desc))
|
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
$('<div>').addClass('remove')
|
$('<div>').addClass('message')
|
||||||
|
.append(
|
||||||
|
$('<span>').html(_l(args.message))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
var additionalComplete = args.complete;
|
|
||||||
|
|
||||||
// Get information for specified section path
|
if (options.error) {
|
||||||
$item.data('notification-section', args.section);
|
$cornerAlert.addClass('error');
|
||||||
$item.data('notification-custom', _custom);
|
|
||||||
$popup.find('ul').append($item);
|
|
||||||
$total.html(newTotal);
|
|
||||||
$total.parent().addClass('pending');
|
|
||||||
$item.addClass('pending');
|
|
||||||
|
|
||||||
// Setup timer
|
|
||||||
var pollTimer = setInterval(function() {
|
|
||||||
args.poll({
|
|
||||||
_custom: _custom,
|
|
||||||
pollTimer: pollTimer,
|
|
||||||
complete: function(args) {
|
|
||||||
clearInterval(pollTimer);
|
|
||||||
|
|
||||||
notifications.cornerAlert({ message: $item.html() });
|
|
||||||
notifications.activeTasks.pop(pollTimer);
|
|
||||||
$item.removeClass('pending');
|
|
||||||
|
|
||||||
if (additionalComplete) additionalComplete();
|
|
||||||
},
|
|
||||||
incomplete: function(args) {},
|
|
||||||
error: function(args) {
|
|
||||||
if (args.message) {
|
|
||||||
cloudStack.dialog.notice({ message: _s(args.message) });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clearInterval(pollTimer);
|
return $cornerAlert
|
||||||
notifications.activeTasks.pop(pollTimer);
|
.css({
|
||||||
notifications.cornerAlert({ message: $item.html() }, {
|
opacity: 0,
|
||||||
error: _l('label.error')
|
position: 'absolute',
|
||||||
|
top: $($container).height(),
|
||||||
|
left: $($container).width() - $cornerAlert.width()
|
||||||
|
})
|
||||||
|
.animate({
|
||||||
|
opacity: 1,
|
||||||
|
top: $container.height() - $cornerAlert.height()
|
||||||
|
}, {
|
||||||
|
complete: function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
$cornerAlert.fadeOut('fast', function() {
|
||||||
|
$cornerAlert.remove();
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
},
|
||||||
|
add: function(args, $popup, $total) {
|
||||||
|
var currentTotal = parseInt($total.html());
|
||||||
|
var newTotal = currentTotal + 1;
|
||||||
|
var desc = args.desc;
|
||||||
|
var section = $('html body')
|
||||||
|
.find('[cloudStack-container]')
|
||||||
|
.data('cloudStack-args')
|
||||||
|
.sections[args.section];
|
||||||
|
var _custom = args._custom;
|
||||||
|
|
||||||
|
var $item = $('<li>')
|
||||||
|
.append(
|
||||||
|
$('<span>').html(_l(args.desc))
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('remove')
|
||||||
|
);
|
||||||
|
var additionalComplete = args.complete;
|
||||||
|
|
||||||
|
// Get information for specified section path
|
||||||
|
$item.data('notification-section', args.section);
|
||||||
|
$item.data('notification-custom', _custom);
|
||||||
|
$popup.find('ul').append($item);
|
||||||
|
$total.html(newTotal);
|
||||||
|
$total.parent().addClass('pending');
|
||||||
|
$item.addClass('pending');
|
||||||
|
|
||||||
|
// Setup timer
|
||||||
|
var pollTimer = setInterval(function() {
|
||||||
|
args.poll({
|
||||||
|
_custom: _custom,
|
||||||
|
pollTimer: pollTimer,
|
||||||
|
complete: function(args) {
|
||||||
|
clearInterval(pollTimer);
|
||||||
|
|
||||||
|
notifications.cornerAlert({
|
||||||
|
message: $item.html()
|
||||||
|
});
|
||||||
|
notifications.activeTasks.pop(pollTimer);
|
||||||
|
$item.removeClass('pending');
|
||||||
|
|
||||||
|
if (additionalComplete) additionalComplete();
|
||||||
|
},
|
||||||
|
incomplete: function(args) {},
|
||||||
|
error: function(args) {
|
||||||
|
if (args.message) {
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: _s(args.message)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
clearInterval(pollTimer);
|
||||||
|
notifications.activeTasks.pop(pollTimer);
|
||||||
|
notifications.cornerAlert({
|
||||||
|
message: $item.html()
|
||||||
|
}, {
|
||||||
|
error: _l('label.error')
|
||||||
|
});
|
||||||
|
$item.removeClass('pending').addClass('error');
|
||||||
|
|
||||||
|
if (additionalComplete) additionalComplete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, args.interval);
|
||||||
|
notifications.activeTasks.push(pollTimer);
|
||||||
|
|
||||||
|
return $total;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set total to 0
|
||||||
|
*/
|
||||||
|
resetTotal: function($popup) {
|
||||||
|
var $total = $popup.data('notifications-attach-to').find('div.total span');
|
||||||
|
var $items = $popup.find('ul li');
|
||||||
|
var total = $items.size();
|
||||||
|
var completed = $items.filter(':not(.pending)').size();
|
||||||
|
var newTotal = total - completed;
|
||||||
|
|
||||||
|
if (newTotal < 0) newTotal = completed;
|
||||||
|
|
||||||
|
$total.html(newTotal);
|
||||||
|
|
||||||
|
if (!newTotal)
|
||||||
|
$total.parent().removeClass('pending');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove item from notification list
|
||||||
|
*/
|
||||||
|
removeItem: function($popup, $item) {
|
||||||
|
if ($item.closest('li').hasClass('pending')) return false;
|
||||||
|
|
||||||
|
$item.remove();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all completed notifications
|
||||||
|
*/
|
||||||
|
clear: function($popup) {
|
||||||
|
$popup.find('ul li').each(function() {
|
||||||
|
var $item = $(this);
|
||||||
|
|
||||||
|
if (!$item.hasClass('pending')) {
|
||||||
|
notifications.removeItem($popup, $item);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
$item.removeClass('pending').addClass('error');
|
},
|
||||||
|
popup: {
|
||||||
|
create: function($attachTo) {
|
||||||
|
var $popup = $('<div>')
|
||||||
|
.addClass('notification-box')
|
||||||
|
.append(
|
||||||
|
// Header
|
||||||
|
$('<h3>').html(_l('label.notifications'))
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
// Container
|
||||||
|
$('<div>').addClass('container')
|
||||||
|
.append(
|
||||||
|
// Notification list
|
||||||
|
$('<ul>')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
// Buttons
|
||||||
|
$('<div>').addClass('buttons')
|
||||||
|
.append(
|
||||||
|
// Clear list
|
||||||
|
$('<div>').addClass('button clear-list')
|
||||||
|
.append(
|
||||||
|
$('<span>').html(_l('label.clear.list'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('button close')
|
||||||
|
.append(
|
||||||
|
$('<span>').html(_l('label.close'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.css({
|
||||||
|
position: 'absolute'
|
||||||
|
})
|
||||||
|
.data('notifications-attach-to', $attachTo)
|
||||||
|
.hide();
|
||||||
|
|
||||||
if (additionalComplete) additionalComplete();
|
if (!$attachTo.hasClass('notifications')) $attachTo.addClass('notifications');
|
||||||
}
|
$attachTo.data('notifications-popup', $popup);
|
||||||
});
|
|
||||||
}, args.interval);
|
|
||||||
notifications.activeTasks.push(pollTimer);
|
|
||||||
|
|
||||||
return $total;
|
return $popup;
|
||||||
},
|
},
|
||||||
|
show: function($popup, $attachTo) {
|
||||||
/**
|
notifications.resetTotal($popup);
|
||||||
* Set total to 0
|
return notifications.popup.reposition($popup, $attachTo)
|
||||||
*/
|
.overlay({
|
||||||
resetTotal: function($popup) {
|
closeAction: function() {
|
||||||
var $total = $popup.data('notifications-attach-to').find('div.total span');
|
notifications.popup.hide($popup);
|
||||||
var $items = $popup.find('ul li');
|
}
|
||||||
var total = $items.size();
|
})
|
||||||
var completed = $items.filter(':not(.pending)').size();
|
.fadeIn();
|
||||||
var newTotal = total - completed;
|
},
|
||||||
|
hide: function($popup) {
|
||||||
if (newTotal < 0) newTotal = completed;
|
$popup.fadeOut();
|
||||||
|
},
|
||||||
$total.html(newTotal);
|
reposition: function($popup, $attachTo) {
|
||||||
|
return $popup
|
||||||
if (!newTotal)
|
.css({
|
||||||
$total.parent().removeClass('pending');
|
zIndex: 10000,
|
||||||
},
|
top: $attachTo.offset().top + $attachTo.height() + 10,
|
||||||
|
left: $attachTo.offset().left - $attachTo.width()
|
||||||
/**
|
});
|
||||||
* Remove item from notification list
|
|
||||||
*/
|
|
||||||
removeItem: function($popup, $item) {
|
|
||||||
if ($item.closest('li').hasClass('pending')) return false;
|
|
||||||
|
|
||||||
$item.remove();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all completed notifications
|
|
||||||
*/
|
|
||||||
clear: function($popup) {
|
|
||||||
$popup.find('ul li').each(function() {
|
|
||||||
var $item = $(this);
|
|
||||||
|
|
||||||
if (!$item.hasClass('pending')) {
|
|
||||||
notifications.removeItem($popup, $item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
popup: {
|
|
||||||
create: function($attachTo) {
|
|
||||||
var $popup = $('<div>')
|
|
||||||
.addClass('notification-box')
|
|
||||||
.append(
|
|
||||||
// Header
|
|
||||||
$('<h3>').html(_l('label.notifications'))
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
// Container
|
|
||||||
$('<div>').addClass('container')
|
|
||||||
.append(
|
|
||||||
// Notification list
|
|
||||||
$('<ul>')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
// Buttons
|
|
||||||
$('<div>').addClass('buttons')
|
|
||||||
.append(
|
|
||||||
// Clear list
|
|
||||||
$('<div>').addClass('button clear-list')
|
|
||||||
.append(
|
|
||||||
$('<span>').html(_l('label.clear.list'))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('button close')
|
|
||||||
.append(
|
|
||||||
$('<span>').html(_l('label.close'))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.css({ position: 'absolute' })
|
|
||||||
.data('notifications-attach-to', $attachTo)
|
|
||||||
.hide();
|
|
||||||
|
|
||||||
if (!$attachTo.hasClass('notifications')) $attachTo.addClass('notifications');
|
|
||||||
$attachTo.data('notifications-popup', $popup);
|
|
||||||
|
|
||||||
return $popup;
|
|
||||||
},
|
|
||||||
show: function($popup, $attachTo) {
|
|
||||||
notifications.resetTotal($popup);
|
|
||||||
return notifications.popup.reposition($popup, $attachTo)
|
|
||||||
.overlay({
|
|
||||||
closeAction: function() {
|
|
||||||
notifications.popup.hide($popup);
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.fadeIn();
|
|
||||||
},
|
|
||||||
hide: function($popup) {
|
|
||||||
$popup.fadeOut();
|
|
||||||
},
|
|
||||||
reposition: function($popup, $attachTo) {
|
|
||||||
return $popup
|
|
||||||
.css({
|
|
||||||
zIndex: 10000,
|
|
||||||
top: $attachTo.offset().top + $attachTo.height() + 10,
|
|
||||||
left: $attachTo.offset().left - $attachTo.width()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define notification widget -- this is basically represented in a
|
|
||||||
* notifications icon, that contains a pop-up list of notifications
|
|
||||||
*/
|
|
||||||
$.fn.notifications = function(method, args) {
|
|
||||||
var $attachTo = this;
|
|
||||||
var $total = $attachTo.find('div.total span');
|
|
||||||
var $popup;
|
|
||||||
|
|
||||||
var init = function() {
|
|
||||||
$popup = notifications.popup.create($attachTo).appendTo('html body');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (method == 'add')
|
/**
|
||||||
notifications.add(args, $attachTo.data('notifications-popup'), $total);
|
* Define notification widget -- this is basically represented in a
|
||||||
else
|
* notifications icon, that contains a pop-up list of notifications
|
||||||
init();
|
*/
|
||||||
|
$.fn.notifications = function(method, args) {
|
||||||
|
var $attachTo = this;
|
||||||
|
var $total = $attachTo.find('div.total span');
|
||||||
|
var $popup;
|
||||||
|
|
||||||
return this;
|
var init = function() {
|
||||||
};
|
$popup = notifications.popup.create($attachTo).appendTo('html body');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
if (method == 'add')
|
||||||
* Notifications UI helpers
|
notifications.add(args, $attachTo.data('notifications-popup'), $total);
|
||||||
*/
|
else
|
||||||
cloudStack.ui.notifications = {
|
init();
|
||||||
add: function(notification, success, successArgs, error, errorArgs) {
|
|
||||||
if (!notification) {
|
|
||||||
success(successArgs);
|
|
||||||
|
|
||||||
return false;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
var $notifications = $('div.notifications');
|
/**
|
||||||
|
* Notifications UI helpers
|
||||||
|
*/
|
||||||
|
cloudStack.ui.notifications = {
|
||||||
|
add: function(notification, success, successArgs, error, errorArgs) {
|
||||||
|
if (!notification) {
|
||||||
|
success(successArgs);
|
||||||
|
|
||||||
if (!notification.poll) {
|
return false;
|
||||||
cloudStack.ui.event.call('addNotification', {
|
};
|
||||||
section: notification.section,
|
|
||||||
desc: notification.desc,
|
|
||||||
interval: 0,
|
|
||||||
poll: function(args) { success(successArgs); args.complete(); }
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cloudStack.ui.event.call('addNotification', {
|
|
||||||
section: notification.section,
|
|
||||||
desc: notification.desc,
|
|
||||||
interval: notification.interval ? notification.interval : g_queryAsyncJobResultInterval,
|
|
||||||
_custom: notification._custom,
|
|
||||||
poll: function(args) {
|
|
||||||
var complete = args.complete;
|
|
||||||
var notificationError = args.error;
|
|
||||||
|
|
||||||
notification.poll({
|
var $notifications = $('div.notifications');
|
||||||
_custom: args._custom,
|
|
||||||
complete: function(args) {
|
|
||||||
success($.extend(successArgs, args));
|
|
||||||
complete(args);
|
|
||||||
},
|
|
||||||
error: function(args) {
|
|
||||||
error($.extend(errorArgs, args));
|
|
||||||
notificationError(args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
if (!notification.poll) {
|
||||||
}
|
cloudStack.ui.event.call('addNotification', {
|
||||||
};
|
section: notification.section,
|
||||||
|
desc: notification.desc,
|
||||||
|
interval: 0,
|
||||||
|
poll: function(args) {
|
||||||
|
success(successArgs);
|
||||||
|
args.complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cloudStack.ui.event.call('addNotification', {
|
||||||
|
section: notification.section,
|
||||||
|
desc: notification.desc,
|
||||||
|
interval: notification.interval ? notification.interval : g_queryAsyncJobResultInterval,
|
||||||
|
_custom: notification._custom,
|
||||||
|
poll: function(args) {
|
||||||
|
var complete = args.complete;
|
||||||
|
var notificationError = args.error;
|
||||||
|
|
||||||
// Setup notification listener -- accepts same args as
|
notification.poll({
|
||||||
$(window).bind('cloudStack.addNotification', function(event, data) {
|
_custom: args._custom,
|
||||||
$('.notifications').notifications('add', data);
|
complete: function(args) {
|
||||||
});
|
success($.extend(successArgs, args));
|
||||||
|
complete(args);
|
||||||
|
},
|
||||||
|
error: function(args) {
|
||||||
|
error($.extend(errorArgs, args));
|
||||||
|
notificationError(args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$(document).click(function(event) {
|
return true;
|
||||||
var $target = $(event.target);
|
}
|
||||||
var $attachTo, $popup;
|
};
|
||||||
|
|
||||||
// Notifications header area
|
// Setup notification listener -- accepts same args as
|
||||||
if ($target.closest('.notifications').size()) {
|
$(window).bind('cloudStack.addNotification', function(event, data) {
|
||||||
$attachTo = $target.closest('.notifications');
|
$('.notifications').notifications('add', data);
|
||||||
$popup = $attachTo.data('notifications-popup');
|
});
|
||||||
notifications.popup.show($popup, $attachTo);
|
|
||||||
|
|
||||||
return false;
|
$(document).click(function(event) {
|
||||||
}
|
var $target = $(event.target);
|
||||||
|
var $attachTo, $popup;
|
||||||
|
|
||||||
// Notification item
|
// Notifications header area
|
||||||
if ($target.is('.notification-box li span')) {
|
if ($target.closest('.notifications').size()) {
|
||||||
var $li = $target.closest('.notification-box li');
|
$attachTo = $target.closest('.notifications');
|
||||||
|
$popup = $attachTo.data('notifications-popup');
|
||||||
|
notifications.popup.show($popup, $attachTo);
|
||||||
|
|
||||||
$('#navigation ul li').filter(function() {
|
return false;
|
||||||
return $(this).hasClass($li.data('notification-section'));
|
}
|
||||||
}).click();
|
|
||||||
$('div.overlay').click();
|
|
||||||
|
|
||||||
return false;
|
// Notification item
|
||||||
}
|
if ($target.is('.notification-box li span')) {
|
||||||
|
var $li = $target.closest('.notification-box li');
|
||||||
|
|
||||||
// Popup
|
$('#navigation ul li').filter(function() {
|
||||||
if ($target.closest('div.notification-box').size()) {
|
return $(this).hasClass($li.data('notification-section'));
|
||||||
$popup = $target.closest('div.notification-box');
|
}).click();
|
||||||
|
$('div.overlay').click();
|
||||||
|
|
||||||
// Clear list
|
return false;
|
||||||
if ($target.closest('.button.clear-list').size()) {
|
}
|
||||||
notifications.clear($popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove instance item
|
// Popup
|
||||||
else if ($target.hasClass('remove')) {
|
if ($target.closest('div.notification-box').size()) {
|
||||||
notifications.removeItem($popup, $target.closest('li'));
|
$popup = $target.closest('div.notification-box');
|
||||||
}
|
|
||||||
|
|
||||||
// Close button
|
// Clear list
|
||||||
else if ($target.closest('.button.close')) {
|
if ($target.closest('.button.clear-list').size()) {
|
||||||
$('div.overlay').click();
|
notifications.clear($popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
// Remove instance item
|
||||||
}
|
else if ($target.hasClass('remove')) {
|
||||||
|
notifications.removeItem($popup, $target.closest('li'));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
// Close button
|
||||||
});
|
else if ($target.closest('.button.close')) {
|
||||||
|
$('div.overlay').click();
|
||||||
|
}
|
||||||
|
|
||||||
$(window).resize(function(event) {
|
return false;
|
||||||
var $popup = $('div.notification-box:visible');
|
}
|
||||||
|
|
||||||
if ($popup.size())
|
return true;
|
||||||
notifications.popup.reposition($popup, $popup.data('notifications-attach-to'));
|
});
|
||||||
});
|
|
||||||
|
$(window).resize(function(event) {
|
||||||
|
var $popup = $('div.notification-box:visible');
|
||||||
|
|
||||||
|
if ($popup.size())
|
||||||
|
notifications.popup.reposition($popup, $popup.data('notifications-attach-to'));
|
||||||
|
});
|
||||||
})(window.jQuery, window.cloudStack, window._l);
|
})(window.jQuery, window.cloudStack, window._l);
|
||||||
|
|||||||
@ -15,36 +15,36 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($) {
|
(function($) {
|
||||||
/**
|
/**
|
||||||
* Create a dark overlay, for modal dialogs, etc.
|
* Create a dark overlay, for modal dialogs, etc.
|
||||||
*/
|
*/
|
||||||
$.fn.overlay = function(args) {
|
$.fn.overlay = function(args) {
|
||||||
var $topElem = this;
|
var $topElem = this;
|
||||||
var $overlay = $('<div class="overlay">').hide().appendTo('html body').css({
|
var $overlay = $('<div class="overlay">').hide().appendTo('html body').css({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
background: 'black',
|
background: 'black',
|
||||||
opacity: 0.5,
|
opacity: 0.5,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
top: $(window).scrollTop(),
|
top: $(window).scrollTop(),
|
||||||
left: 0,
|
left: 0,
|
||||||
zIndex: $topElem.css('z-index') - 1
|
zIndex: $topElem.css('z-index') - 1
|
||||||
}).show();
|
}).show();
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
$overlay.click(function(event) {
|
$overlay.click(function(event) {
|
||||||
if (!args || !args.closeAction) return false;
|
if (!args || !args.closeAction) return false;
|
||||||
|
|
||||||
args.closeAction();
|
args.closeAction();
|
||||||
$overlay.fadeOut(function() {
|
$overlay.fadeOut(function() {
|
||||||
$overlay.remove();
|
$overlay.remove();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
$(window).bind('resize scroll', function() {
|
||||||
|
$('.overlay').css('top', $(window).scrollTop());
|
||||||
});
|
});
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
$(window).bind('resize scroll', function() {
|
|
||||||
$('.overlay').css( 'top', $(window).scrollTop());
|
|
||||||
});
|
|
||||||
})(window.jQuery);
|
})(window.jQuery);
|
||||||
|
|||||||
@ -16,220 +16,236 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
var isFormValid = function($form) {
|
var isFormValid = function($form) {
|
||||||
var key = $form.find('input[name=key]').val();
|
var key = $form.find('input[name=key]').val();
|
||||||
var value = $form.find('input[name=value]').val();
|
var value = $form.find('input[name=value]').val();
|
||||||
|
|
||||||
if (!key || !value) {
|
if (!key || !value) {
|
||||||
cloudStack.dialog.notice({ message: 'Please specify a tag key and value' });
|
cloudStack.dialog.notice({
|
||||||
return false;
|
message: 'Please specify a tag key and value'
|
||||||
}
|
|
||||||
|
|
||||||
if($form.find('div.field.key').find('label.error').css('display') == 'block' || $form.find('div.field.value').find('label.error').css('display') == 'block')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var elems = {
|
|
||||||
inputArea: function(args) {
|
|
||||||
var $form = $('<form>').addClass('tag-input');
|
|
||||||
var $keyField = $('<div>').addClass('field key');
|
|
||||||
var $keyLabel = $('<label>').attr('for', 'key').html(_l('label.key') + ':');
|
|
||||||
var $key = $('<input>').addClass('key disallowSpecialCharacters').attr('name', 'key');
|
|
||||||
var $valueField = $('<div>').addClass('field value');
|
|
||||||
var $valueLabel = $('<label>').attr('for', 'value').html(_l('label.value') + ':');
|
|
||||||
var $value = $('<input>').addClass('value disallowSpecialCharacters').attr('name', 'value');
|
|
||||||
var $submit = $('<input>').attr('type', 'submit').val('Add');
|
|
||||||
|
|
||||||
$keyField.append($keyLabel, $key);
|
|
||||||
$valueField.append($valueLabel, $value);
|
|
||||||
$form.append(
|
|
||||||
$keyField, $valueField,
|
|
||||||
$submit
|
|
||||||
);
|
|
||||||
|
|
||||||
$form.validate();
|
|
||||||
|
|
||||||
$form.submit(
|
|
||||||
args.onSubmit ?
|
|
||||||
function() {
|
|
||||||
if (!isFormValid($form)) return false;
|
|
||||||
|
|
||||||
args.onSubmit({
|
|
||||||
data: cloudStack.serializeForm($form),
|
|
||||||
response: {
|
|
||||||
success: function() {
|
|
||||||
// Restore editing of input
|
|
||||||
$key.attr('disabled', false);
|
|
||||||
$value.attr('disabled', false);
|
|
||||||
|
|
||||||
// Clear out old data
|
|
||||||
$key.val(''); $value.val('');
|
|
||||||
$key.focus();
|
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
// Restore editing of input
|
|
||||||
$key.attr('disabled', false);
|
|
||||||
$value.attr('disabled', false);
|
|
||||||
$key.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prevent input during submission
|
|
||||||
$key.attr('disabled', 'disabled');
|
|
||||||
$value.attr('disabled', 'disabled');
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} :
|
|
||||||
function() { return false; }
|
|
||||||
);
|
|
||||||
|
|
||||||
return $form;
|
|
||||||
},
|
|
||||||
tagItem: function(title, onRemove, data) {
|
|
||||||
var $li = $('<li>');
|
|
||||||
var $label = $('<span>').addClass('label').html(_s(title));
|
|
||||||
var $remove = $('<span>').addClass('remove').html('X');
|
|
||||||
|
|
||||||
$remove.click(function() {
|
|
||||||
if (onRemove) onRemove($li, data);
|
|
||||||
});
|
|
||||||
|
|
||||||
$li.append($remove, $label);
|
|
||||||
|
|
||||||
return $li;
|
|
||||||
},
|
|
||||||
|
|
||||||
info: function(text) {
|
|
||||||
var $info = $('<div>').addClass('tag-info');
|
|
||||||
var $text = $('<span>').html(text);
|
|
||||||
|
|
||||||
$text.appendTo($info);
|
|
||||||
|
|
||||||
return $info;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.widget('cloudStack.tagger', {
|
|
||||||
_init: function(args) {
|
|
||||||
var context = this.options.context;
|
|
||||||
var jsonObj = this.options.jsonObj;
|
|
||||||
var dataProvider = this.options.dataProvider;
|
|
||||||
var actions = this.options.actions;
|
|
||||||
var $container = this.element.addClass('tagger');
|
|
||||||
var $tagArea = $('<ul>').addClass('tags');
|
|
||||||
var $title = elems.info(_l('label.tags')).addClass('title');
|
|
||||||
var $loading = $('<div>').addClass('loading-overlay');
|
|
||||||
|
|
||||||
var onRemoveItem = function($item, data) {
|
|
||||||
$loading.appendTo($container);
|
|
||||||
actions.remove({
|
|
||||||
context: $.extend(true, {}, context, {
|
|
||||||
tagItems: [data]
|
|
||||||
}),
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
var notification = $.extend(true, {} , args.notification, {
|
|
||||||
interval: 500,
|
|
||||||
_custom: args._custom
|
|
||||||
});
|
|
||||||
|
|
||||||
cloudStack.ui.notifications.add(
|
|
||||||
notification,
|
|
||||||
|
|
||||||
// Success
|
|
||||||
function() {
|
|
||||||
$loading.remove();
|
|
||||||
$item.remove();
|
|
||||||
}, {},
|
|
||||||
|
|
||||||
// Error
|
|
||||||
function() {
|
|
||||||
$loading.remove();
|
|
||||||
}, {}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
error: function(message) {
|
|
||||||
$loading.remove();
|
|
||||||
cloudStack.dialog.notice({ message: message });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var $inputArea = elems.inputArea({
|
|
||||||
onSubmit: function(args) {
|
|
||||||
var data = args.data;
|
|
||||||
var success = args.response.success;
|
|
||||||
var error = args.response.error;
|
|
||||||
var title = data.key + ' = ' + data.value;
|
|
||||||
|
|
||||||
$loading.appendTo($container);
|
|
||||||
actions.add({
|
|
||||||
data: data,
|
|
||||||
context: context,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
var notification = $.extend(true, {} , args.notification, {
|
|
||||||
interval: 500,
|
|
||||||
_custom: args._custom
|
|
||||||
});
|
|
||||||
|
|
||||||
cloudStack.ui.notifications.add(
|
|
||||||
notification,
|
|
||||||
|
|
||||||
// Success
|
|
||||||
function() {
|
|
||||||
$loading.remove();
|
|
||||||
elems.tagItem(title, onRemoveItem, data).appendTo($tagArea);
|
|
||||||
success();
|
|
||||||
}, {},
|
|
||||||
|
|
||||||
// Error
|
|
||||||
function() {
|
|
||||||
$loading.remove();
|
|
||||||
error();
|
|
||||||
}, {}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
error: function(message) {
|
|
||||||
$loading.remove();
|
|
||||||
error();
|
|
||||||
cloudStack.dialog.notice({ message: message });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
$container.append($title, $inputArea, $tagArea);
|
if ($form.find('div.field.key').find('label.error').css('display') == 'block' || $form.find('div.field.value').find('label.error').css('display') == 'block')
|
||||||
|
return false;
|
||||||
|
|
||||||
// Get data
|
return true;
|
||||||
$loading.appendTo($container);
|
};
|
||||||
dataProvider({
|
|
||||||
context: context,
|
|
||||||
jsonObj: jsonObj,
|
|
||||||
response: {
|
|
||||||
success: function(args) {
|
|
||||||
var data = args.data;
|
|
||||||
|
|
||||||
$loading.remove();
|
var elems = {
|
||||||
$(data).map(function(index, item) {
|
inputArea: function(args) {
|
||||||
var key = item.key;
|
var $form = $('<form>').addClass('tag-input');
|
||||||
var value = item.value;
|
var $keyField = $('<div>').addClass('field key');
|
||||||
var data = { key: key, value: value };
|
var $keyLabel = $('<label>').attr('for', 'key').html(_l('label.key') + ':');
|
||||||
|
var $key = $('<input>').addClass('key disallowSpecialCharacters').attr('name', 'key');
|
||||||
|
var $valueField = $('<div>').addClass('field value');
|
||||||
|
var $valueLabel = $('<label>').attr('for', 'value').html(_l('label.value') + ':');
|
||||||
|
var $value = $('<input>').addClass('value disallowSpecialCharacters').attr('name', 'value');
|
||||||
|
var $submit = $('<input>').attr('type', 'submit').val('Add');
|
||||||
|
|
||||||
elems.tagItem(key + ' = ' + value, onRemoveItem, data).appendTo($tagArea);
|
$keyField.append($keyLabel, $key);
|
||||||
|
$valueField.append($valueLabel, $value);
|
||||||
|
$form.append(
|
||||||
|
$keyField, $valueField,
|
||||||
|
$submit
|
||||||
|
);
|
||||||
|
|
||||||
|
$form.validate();
|
||||||
|
|
||||||
|
$form.submit(
|
||||||
|
args.onSubmit ?
|
||||||
|
function() {
|
||||||
|
if (!isFormValid($form)) return false;
|
||||||
|
|
||||||
|
args.onSubmit({
|
||||||
|
data: cloudStack.serializeForm($form),
|
||||||
|
response: {
|
||||||
|
success: function() {
|
||||||
|
// Restore editing of input
|
||||||
|
$key.attr('disabled', false);
|
||||||
|
$value.attr('disabled', false);
|
||||||
|
|
||||||
|
// Clear out old data
|
||||||
|
$key.val('');
|
||||||
|
$value.val('');
|
||||||
|
$key.focus();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
// Restore editing of input
|
||||||
|
$key.attr('disabled', false);
|
||||||
|
$value.attr('disabled', false);
|
||||||
|
$key.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent input during submission
|
||||||
|
$key.attr('disabled', 'disabled');
|
||||||
|
$value.attr('disabled', 'disabled');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} :
|
||||||
|
function() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
},
|
||||||
|
tagItem: function(title, onRemove, data) {
|
||||||
|
var $li = $('<li>');
|
||||||
|
var $label = $('<span>').addClass('label').html(_s(title));
|
||||||
|
var $remove = $('<span>').addClass('remove').html('X');
|
||||||
|
|
||||||
|
$remove.click(function() {
|
||||||
|
if (onRemove) onRemove($li, data);
|
||||||
});
|
});
|
||||||
},
|
|
||||||
error: function(message) {
|
$li.append($remove, $label);
|
||||||
$loading.remove();
|
|
||||||
$container.find('ul').html(message);
|
return $li;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
info: function(text) {
|
||||||
|
var $info = $('<div>').addClass('tag-info');
|
||||||
|
var $text = $('<span>').html(text);
|
||||||
|
|
||||||
|
$text.appendTo($info);
|
||||||
|
|
||||||
|
return $info;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
|
||||||
});
|
$.widget('cloudStack.tagger', {
|
||||||
|
_init: function(args) {
|
||||||
|
var context = this.options.context;
|
||||||
|
var jsonObj = this.options.jsonObj;
|
||||||
|
var dataProvider = this.options.dataProvider;
|
||||||
|
var actions = this.options.actions;
|
||||||
|
var $container = this.element.addClass('tagger');
|
||||||
|
var $tagArea = $('<ul>').addClass('tags');
|
||||||
|
var $title = elems.info(_l('label.tags')).addClass('title');
|
||||||
|
var $loading = $('<div>').addClass('loading-overlay');
|
||||||
|
|
||||||
|
var onRemoveItem = function($item, data) {
|
||||||
|
$loading.appendTo($container);
|
||||||
|
actions.remove({
|
||||||
|
context: $.extend(true, {}, context, {
|
||||||
|
tagItems: [data]
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
var notification = $.extend(true, {}, args.notification, {
|
||||||
|
interval: 500,
|
||||||
|
_custom: args._custom
|
||||||
|
});
|
||||||
|
|
||||||
|
cloudStack.ui.notifications.add(
|
||||||
|
notification,
|
||||||
|
|
||||||
|
// Success
|
||||||
|
|
||||||
|
function() {
|
||||||
|
$loading.remove();
|
||||||
|
$item.remove();
|
||||||
|
}, {},
|
||||||
|
|
||||||
|
// Error
|
||||||
|
|
||||||
|
function() {
|
||||||
|
$loading.remove();
|
||||||
|
}, {}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
error: function(message) {
|
||||||
|
$loading.remove();
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var $inputArea = elems.inputArea({
|
||||||
|
onSubmit: function(args) {
|
||||||
|
var data = args.data;
|
||||||
|
var success = args.response.success;
|
||||||
|
var error = args.response.error;
|
||||||
|
var title = data.key + ' = ' + data.value;
|
||||||
|
|
||||||
|
$loading.appendTo($container);
|
||||||
|
actions.add({
|
||||||
|
data: data,
|
||||||
|
context: context,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
var notification = $.extend(true, {}, args.notification, {
|
||||||
|
interval: 500,
|
||||||
|
_custom: args._custom
|
||||||
|
});
|
||||||
|
|
||||||
|
cloudStack.ui.notifications.add(
|
||||||
|
notification,
|
||||||
|
|
||||||
|
// Success
|
||||||
|
|
||||||
|
function() {
|
||||||
|
$loading.remove();
|
||||||
|
elems.tagItem(title, onRemoveItem, data).appendTo($tagArea);
|
||||||
|
success();
|
||||||
|
}, {},
|
||||||
|
|
||||||
|
// Error
|
||||||
|
|
||||||
|
function() {
|
||||||
|
$loading.remove();
|
||||||
|
error();
|
||||||
|
}, {}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
error: function(message) {
|
||||||
|
$loading.remove();
|
||||||
|
error();
|
||||||
|
cloudStack.dialog.notice({
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$container.append($title, $inputArea, $tagArea);
|
||||||
|
|
||||||
|
// Get data
|
||||||
|
$loading.appendTo($container);
|
||||||
|
dataProvider({
|
||||||
|
context: context,
|
||||||
|
jsonObj: jsonObj,
|
||||||
|
response: {
|
||||||
|
success: function(args) {
|
||||||
|
var data = args.data;
|
||||||
|
|
||||||
|
$loading.remove();
|
||||||
|
$(data).map(function(index, item) {
|
||||||
|
var key = item.key;
|
||||||
|
var value = item.value;
|
||||||
|
var data = {
|
||||||
|
key: key,
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
|
||||||
|
elems.tagItem(key + ' = ' + value, onRemoveItem, data).appendTo($tagArea);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(message) {
|
||||||
|
$loading.remove();
|
||||||
|
$container.find('ul').html(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}(jQuery, cloudStack));
|
}(jQuery, cloudStack));
|
||||||
|
|||||||
@ -14,151 +14,157 @@
|
|||||||
// KIND, either express or implied. See the License for the
|
// KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($,cloudStack) {
|
(function($, cloudStack) {
|
||||||
$.widget("cloudStack.toolTip", {
|
$.widget("cloudStack.toolTip", {
|
||||||
_init: function(args) {
|
_init: function(args) {
|
||||||
var context = this.options.context;
|
var context = this.options.context;
|
||||||
var dataProvider = this.options.dataProvider;
|
var dataProvider = this.options.dataProvider;
|
||||||
var actions = this.options.actions;
|
var actions = this.options.actions;
|
||||||
var docID = this.options.docID;
|
var docID = this.options.docID;
|
||||||
var text = cloudStack.docs[docID].desc;
|
var text = cloudStack.docs[docID].desc;
|
||||||
var $tooltip = $('<div>').addClass('tooltip-box');
|
var $tooltip = $('<div>').addClass('tooltip-box');
|
||||||
var $text = $('<p>').html(text).appendTo($tooltip);
|
var $text = $('<p>').html(text).appendTo($tooltip);
|
||||||
var $container = $('#cloudStack3-container');
|
var $container = $('#cloudStack3-container');
|
||||||
|
|
||||||
$tooltip.appendTo($container);
|
$tooltip.appendTo($container);
|
||||||
|
|
||||||
if (this.options.mode == 'hover'){
|
if (this.options.mode == 'hover') {
|
||||||
$(this.element).hover(hoverHandler,outHandler);
|
$(this.element).hover(hoverHandler, outHandler);
|
||||||
} else if (this.options.mode == 'focus'){
|
} else if (this.options.mode == 'focus') {
|
||||||
$(this.element).focus(hoverHandler);
|
$(this.element).focus(hoverHandler);
|
||||||
$(this.element).blur(outHandler);
|
$(this.element).blur(outHandler);
|
||||||
} else if (this.options.mode == 'manual'){}
|
} else if (this.options.mode == 'manual') {}
|
||||||
|
|
||||||
$(this.element).data('$tooltip', $tooltip);
|
$(this.element).data('$tooltip', $tooltip);
|
||||||
|
|
||||||
// Add arrow
|
// Add arrow
|
||||||
$tooltip.append($('<div></div>').addClass('arrow'));
|
$tooltip.append($('<div></div>').addClass('arrow'));
|
||||||
|
|
||||||
$tooltip.hide();
|
$tooltip.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
show: function(){
|
show: function() {
|
||||||
var o = this.options;
|
var o = this.options;
|
||||||
|
|
||||||
if(o.mode=='manual'){
|
if (o.mode == 'manual') {
|
||||||
prepare(this.element,o);
|
prepare(this.element, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
$(o.toolTip).show();
|
$(o.toolTip).show();
|
||||||
},
|
},
|
||||||
|
|
||||||
hide: function(){
|
|
||||||
var o = this.options;
|
|
||||||
$(o.toolTip).hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$.extend($.cloudStack.toolTip, {
|
|
||||||
defaults: {
|
|
||||||
toolTip: '',
|
|
||||||
onShow: function(sender){
|
|
||||||
//Flipping arrow and text
|
|
||||||
|
|
||||||
var $tooltip = $('.tooltip-box');
|
|
||||||
|
|
||||||
//Switch styles based on how close to viewport border
|
|
||||||
|
|
||||||
if($(window).width()-sender.target.offset().left <= $tooltip.width()) {
|
|
||||||
|
|
||||||
$('.tooltiptextleft',$tooltip).removeClass('tooltiptextleft').addClass('tooltiptextright');
|
|
||||||
$('.tooltiparrowleft',$tooltip).removeClass('tooltiparrowleft').addClass('tooltiparrowright');
|
|
||||||
|
|
||||||
|
hide: function() {
|
||||||
|
var o = this.options;
|
||||||
|
$(o.toolTip).hide();
|
||||||
}
|
}
|
||||||
else{
|
});
|
||||||
$('.tooltiptextright',$tooltip).removeClass('tooltiptextright').addClass('tooltiptextleft');
|
|
||||||
$('.tooltiparrowright',$tooltip).removeClass('tooltiparrowright').addClass('tooltiparrowleft');
|
$.extend($.cloudStack.toolTip, {
|
||||||
|
defaults: {
|
||||||
|
toolTip: '',
|
||||||
|
onShow: function(sender) {
|
||||||
|
//Flipping arrow and text
|
||||||
|
|
||||||
|
var $tooltip = $('.tooltip-box');
|
||||||
|
|
||||||
|
//Switch styles based on how close to viewport border
|
||||||
|
|
||||||
|
if ($(window).width() - sender.target.offset().left <= $tooltip.width()) {
|
||||||
|
|
||||||
|
$('.tooltiptextleft', $tooltip).removeClass('tooltiptextleft').addClass('tooltiptextright');
|
||||||
|
$('.tooltiparrowleft', $tooltip).removeClass('tooltiparrowleft').addClass('tooltiparrowright');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$('.tooltiptextright', $tooltip).removeClass('tooltiptextright').addClass('tooltiptextleft');
|
||||||
|
$('.tooltiparrowright', $tooltip).removeClass('tooltiparrowright').addClass('tooltiparrowleft');
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
onHide: undefined,
|
||||||
|
mode: 'hover',
|
||||||
|
// provide a speed for the animation
|
||||||
|
speed: 1000,
|
||||||
|
// provide a period for the popup to keep showing
|
||||||
|
period: 2000,
|
||||||
|
// default the animation algorithm to the basic slide
|
||||||
|
animation: 'slide'
|
||||||
|
},
|
||||||
|
animations: {
|
||||||
|
slide: function(e, options) {
|
||||||
|
|
||||||
|
},
|
||||||
|
fade: function(e, options) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function hoverHandler(event) {
|
||||||
|
//Fetch Options
|
||||||
|
var o = $.data(this, 'toolTip').options;
|
||||||
|
|
||||||
|
//Element who raised the event
|
||||||
|
var $this = $(this);
|
||||||
|
|
||||||
|
//Helper functon for Positioning and Calling Callback function
|
||||||
|
prepare($this, o);
|
||||||
|
|
||||||
|
//Call Show method of the tooltip Widget,
|
||||||
|
//Show method should play on any required animations
|
||||||
|
$.data(this, '$tooltip').show();
|
||||||
|
};
|
||||||
|
|
||||||
|
function outHandler(event) {
|
||||||
|
//Fetch Options
|
||||||
|
var o = $.data(this, 'toolTip').options;
|
||||||
|
|
||||||
|
//Get tooptip Element
|
||||||
|
var $tooltip = $(o.toolTip);
|
||||||
|
|
||||||
|
//If call back method defined, initiate the call
|
||||||
|
if ($.data(this, 'toolTip').options.onHide) {
|
||||||
|
$.data(this, 'toolTip').options.onHide.call(this, {
|
||||||
|
target: $(this)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
//Call Hide method of the tooltip Widget,
|
||||||
onHide: undefined,
|
//Hide method should play on any required animations
|
||||||
mode: 'hover',
|
$.data(this, '$tooltip').hide();
|
||||||
// provide a speed for the animation
|
};
|
||||||
speed: 1000,
|
|
||||||
// provide a period for the popup to keep showing
|
|
||||||
period: 2000,
|
|
||||||
// default the animation algorithm to the basic slide
|
|
||||||
animation:'slide'
|
|
||||||
},
|
|
||||||
animations: {
|
|
||||||
slide: function(e, options) {
|
|
||||||
|
|
||||||
},
|
function prepare(jObj, options) {
|
||||||
fade: function(e, options) {
|
var $tooltip = $(options.tooltip);
|
||||||
|
var element = options.attachTo ?
|
||||||
|
jObj.closest(options.attachTo) : jObj;
|
||||||
|
var offset = element.offset();
|
||||||
|
|
||||||
}
|
var left = offset.left + element.width();
|
||||||
}
|
var top = offset.top - 5;
|
||||||
});
|
|
||||||
|
|
||||||
function hoverHandler(event)
|
if (options.onShow) {
|
||||||
{
|
options.onShow.call(this, {
|
||||||
//Fetch Options
|
target: jObj
|
||||||
var o = $.data(this,'toolTip').options;
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//Element who raised the event
|
if ($(window).width() - offset.left <= $tooltip.width()) {
|
||||||
var $this = $(this);
|
left = offset.left - $tooltip.width();
|
||||||
|
} else {
|
||||||
|
left += 35;
|
||||||
|
}
|
||||||
|
$tooltip.css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: top + 'px',
|
||||||
|
left: left + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
//Helper functon for Positioning and Calling Callback function
|
// Fix overlay
|
||||||
prepare($this,o);
|
setTimeout(function() {
|
||||||
|
$('.tooltip-box').zIndex($(':ui-dialog').zIndex() + 10);
|
||||||
|
});
|
||||||
|
|
||||||
//Call Show method of the tooltip Widget,
|
};
|
||||||
//Show method should play on any required animations
|
|
||||||
$.data(this,'$tooltip').show();
|
|
||||||
};
|
|
||||||
function outHandler(event)
|
|
||||||
{
|
|
||||||
//Fetch Options
|
|
||||||
var o = $.data(this,'toolTip').options;
|
|
||||||
|
|
||||||
//Get tooptip Element
|
|
||||||
var $tooltip = $(o.toolTip);
|
|
||||||
|
|
||||||
//If call back method defined, initiate the call
|
|
||||||
if($.data(this,'toolTip').options.onHide){
|
|
||||||
$.data(this,'toolTip').options.onHide.call(this, {target:$(this)});
|
|
||||||
}
|
|
||||||
|
|
||||||
//Call Hide method of the tooltip Widget,
|
|
||||||
//Hide method should play on any required animations
|
|
||||||
$.data(this,'$tooltip').hide();
|
|
||||||
};
|
|
||||||
function prepare(jObj, options)
|
|
||||||
{
|
|
||||||
var $tooltip = $(options.tooltip);
|
|
||||||
var element = options.attachTo ?
|
|
||||||
jObj.closest(options.attachTo) : jObj;
|
|
||||||
var offset = element.offset();
|
|
||||||
|
|
||||||
var left = offset.left + element.width();
|
|
||||||
var top = offset.top-5;
|
|
||||||
|
|
||||||
if(options.onShow){
|
|
||||||
options.onShow.call(this, {target:jObj});
|
|
||||||
}
|
|
||||||
|
|
||||||
if($(window).width()-offset.left <= $tooltip.width()) {
|
|
||||||
left = offset.left - $tooltip.width();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
left += 35;
|
|
||||||
}
|
|
||||||
$tooltip.css({position:'absolute', top:top+'px', left:left+'px'});
|
|
||||||
|
|
||||||
// Fix overlay
|
|
||||||
setTimeout(function() {
|
|
||||||
$('.tooltip-box').zIndex($(':ui-dialog').zIndex() + 10); });
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
})(jQuery,cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
@ -15,130 +15,136 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack, _s) {
|
(function($, cloudStack, _s) {
|
||||||
/**
|
/**
|
||||||
* Make <ul> of tree items
|
* Make <ul> of tree items
|
||||||
*/
|
*/
|
||||||
var makeTreeList = function(args) {
|
var makeTreeList = function(args) {
|
||||||
var $treeList = $('<ul>');
|
var $treeList = $('<ul>');
|
||||||
|
|
||||||
args.dataProvider({
|
args.dataProvider({
|
||||||
context: $.extend(args.context, {
|
context: $.extend(args.context, {
|
||||||
parentDomain: args.parent
|
parentDomain: args.parent
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
success: function(successArgs) {
|
success: function(successArgs) {
|
||||||
$(successArgs.data).each(function() {
|
$(successArgs.data).each(function() {
|
||||||
$('<li>')
|
$('<li>')
|
||||||
.data('tree-view-item-id', this.id)
|
.data('tree-view-item-id', this.id)
|
||||||
.data('tree-view-item-obj', this)
|
.data('tree-view-item-obj', this)
|
||||||
.append(
|
.append(
|
||||||
|
$('<div>')
|
||||||
|
.addClass('expand')
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<div>').addClass('name')
|
||||||
|
.html(_s(this.name))
|
||||||
|
)
|
||||||
|
.appendTo($treeList);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $treeList;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define an infinite 'tree' list
|
||||||
|
*/
|
||||||
|
$.fn.treeView = function(args) {
|
||||||
|
var $treeView = $('<div>')
|
||||||
|
.appendTo(this)
|
||||||
|
.addClass('view tree-view');
|
||||||
|
var $toolbar = $('<div>')
|
||||||
|
.addClass('toolbar')
|
||||||
|
.append(
|
||||||
$('<div>')
|
$('<div>')
|
||||||
.addClass('expand')
|
.addClass('text-search')
|
||||||
)
|
.append(
|
||||||
.append(
|
$('<div>')
|
||||||
$('<div>').addClass('name')
|
.addClass('search-bar').attr('style', 'display:none') //no place to show search result in a tree, so hide it for now
|
||||||
.html(_s(this.name))
|
.append(
|
||||||
)
|
$('<input>').attr('type', 'text')
|
||||||
.appendTo($treeList);
|
)
|
||||||
});
|
)
|
||||||
}
|
.append(
|
||||||
}
|
$('<div>').addClass('button search').attr('style', 'display:none') //no place to show search result in a tree, so hide it for now
|
||||||
});
|
)
|
||||||
|
)
|
||||||
return $treeList;
|
.prependTo($treeView);
|
||||||
};
|
var treeViewArgs = args.treeView;
|
||||||
|
var $browser = args.$browser;
|
||||||
/**
|
|
||||||
* Define an infinite 'tree' list
|
|
||||||
*/
|
|
||||||
$.fn.treeView = function(args) {
|
|
||||||
var $treeView = $('<div>')
|
|
||||||
.appendTo(this)
|
|
||||||
.addClass('view tree-view');
|
|
||||||
var $toolbar = $('<div>')
|
|
||||||
.addClass('toolbar')
|
|
||||||
.append(
|
|
||||||
$('<div>')
|
|
||||||
.addClass('text-search')
|
|
||||||
.append(
|
|
||||||
$('<div>')
|
|
||||||
.addClass('search-bar').attr('style', 'display:none') //no place to show search result in a tree, so hide it for now
|
|
||||||
.append(
|
|
||||||
$('<input>').attr('type', 'text')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
$('<div>').addClass('button search').attr('style', 'display:none') //no place to show search result in a tree, so hide it for now
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.prependTo($treeView);
|
|
||||||
var treeViewArgs = args.treeView;
|
|
||||||
var $browser = args.$browser;
|
|
||||||
|
|
||||||
makeTreeList({
|
|
||||||
parent: null,
|
|
||||||
dataProvider: treeViewArgs.dataProvider,
|
|
||||||
context: args.context
|
|
||||||
}).appendTo($treeView);
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
$treeView.find('li:first div.name').click();
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
this.click(function(event) {
|
|
||||||
var $target = $(event.target);
|
|
||||||
var $li = $target.closest('li');
|
|
||||||
|
|
||||||
if ($target.is('li div.expand') && $li.data('tree-view-item-obj')) {
|
|
||||||
if ($li.find('ul').size()) {
|
|
||||||
$li.find('ul').remove();
|
|
||||||
$li.removeClass('expanded');
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
makeTreeList({
|
makeTreeList({
|
||||||
parent: $li.data('tree-view-item-obj'),
|
parent: null,
|
||||||
dataProvider: treeViewArgs.dataProvider
|
dataProvider: treeViewArgs.dataProvider,
|
||||||
}).appendTo($li);
|
context: args.context
|
||||||
$li.addClass('expanded');
|
}).appendTo($treeView);
|
||||||
|
|
||||||
return false;
|
setTimeout(function() {
|
||||||
}
|
$treeView.find('li:first div.name').click();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
if ($target.is('li .name')) {
|
this.click(function(event) {
|
||||||
$treeView.find('li .name').removeClass('selected');
|
var $target = $(event.target);
|
||||||
$target.addClass('selected');
|
var $li = $target.closest('li');
|
||||||
$browser.cloudBrowser('addPanel', {
|
|
||||||
title: $target.html(),
|
if ($target.is('li div.expand') && $li.data('tree-view-item-obj')) {
|
||||||
data: '',
|
if ($li.find('ul').size()) {
|
||||||
parent: $treeView.closest('div.panel'),
|
$li.find('ul').remove();
|
||||||
complete: function($panel) {
|
$li.removeClass('expanded');
|
||||||
$panel.detailView($.extend(treeViewArgs.detailView, {
|
|
||||||
id: $li.data('tree-view-item-id'),
|
return false;
|
||||||
$browser: $browser,
|
}
|
||||||
context: { domains: [ $li.data('tree-view-item-obj') ] }
|
|
||||||
}));
|
makeTreeList({
|
||||||
}
|
parent: $li.data('tree-view-item-obj'),
|
||||||
|
dataProvider: treeViewArgs.dataProvider
|
||||||
|
}).appendTo($li);
|
||||||
|
$li.addClass('expanded');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($target.is('li .name')) {
|
||||||
|
$treeView.find('li .name').removeClass('selected');
|
||||||
|
$target.addClass('selected');
|
||||||
|
$browser.cloudBrowser('addPanel', {
|
||||||
|
title: $target.html(),
|
||||||
|
data: '',
|
||||||
|
parent: $treeView.closest('div.panel'),
|
||||||
|
complete: function($panel) {
|
||||||
|
$panel.detailView($.extend(treeViewArgs.detailView, {
|
||||||
|
id: $li.data('tree-view-item-id'),
|
||||||
|
$browser: $browser,
|
||||||
|
context: {
|
||||||
|
domains: [$li.data('tree-view-item-obj')]
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
// Action events
|
||||||
});
|
$(window).bind('cloudstack.view-item-action', function(event, data) {
|
||||||
|
var actionName = data.actionName;
|
||||||
|
var $li = $treeView.find('li').filter(function() {
|
||||||
|
return $(this).data('tree-view-item-id') == data.id;
|
||||||
|
});
|
||||||
|
|
||||||
// Action events
|
if (actionName == 'destroy') {
|
||||||
$(window).bind('cloudstack.view-item-action', function(event, data) {
|
$li.animate({
|
||||||
var actionName = data.actionName;
|
opacity: 0.5
|
||||||
var $li = $treeView.find('li').filter(function() {
|
});
|
||||||
return $(this).data('tree-view-item-id') == data.id;
|
$li.bind('click', function() {
|
||||||
});
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (actionName == 'destroy') {
|
return this;
|
||||||
$li.animate({ opacity: 0.5 });
|
};
|
||||||
$li.bind('click', function() { return false; });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
})(jQuery, cloudStack, cloudStack.sanitize);
|
})(jQuery, cloudStack, cloudStack.sanitize);
|
||||||
|
|||||||
@ -15,182 +15,185 @@
|
|||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
(function($, cloudStack) {
|
(function($, cloudStack) {
|
||||||
cloudStack.sections.vmsnapshots = {
|
cloudStack.sections.vmsnapshots = {
|
||||||
title: 'label.vmsnapshot',
|
title: 'label.vmsnapshot',
|
||||||
id: 'vmsnapshots',
|
id: 'vmsnapshots',
|
||||||
listView: {
|
listView: {
|
||||||
id: 'vmsnapshots',
|
id: 'vmsnapshots',
|
||||||
isMaximized: true,
|
isMaximized: true,
|
||||||
fields: {
|
|
||||||
displayname: {
|
|
||||||
label: 'label.name'
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
label: 'label.state',
|
|
||||||
indicator: {
|
|
||||||
'Ready': 'on',
|
|
||||||
'Error': 'off'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
type:{
|
|
||||||
label: 'label.vmsnapshot.type'
|
|
||||||
},
|
|
||||||
current:{
|
|
||||||
label: 'label.vmsnapshot.current',
|
|
||||||
converter: cloudStack.converters.toBooleanText
|
|
||||||
},
|
|
||||||
parentName:{
|
|
||||||
label: 'label.vmsnapshot.parentname'
|
|
||||||
},
|
|
||||||
created: {
|
|
||||||
label: 'label.date',
|
|
||||||
converter: cloudStack.converters.toLocalDate
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
dataProvider: function(args) {
|
|
||||||
var apiCmd = "listVMSnapshot&listAll=true";
|
|
||||||
if (args.context != null) {
|
|
||||||
if ("instances" in args.context) {
|
|
||||||
apiCmd += "&virtualmachineid=" + args.context.instances[0].id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$.ajax({
|
|
||||||
url: createURL(apiCmd),
|
|
||||||
dataType: "json",
|
|
||||||
async: true,
|
|
||||||
success: function(json) {
|
|
||||||
var jsonObj;
|
|
||||||
jsonObj = json.listvmsnapshotresponse.vmSnapshot;
|
|
||||||
args.response.success({
|
|
||||||
data: jsonObj
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
//dataProvider end
|
|
||||||
detailView: {
|
|
||||||
tabs: {
|
|
||||||
details: {
|
|
||||||
title: 'label.details',
|
|
||||||
fields: {
|
fields: {
|
||||||
id: {
|
displayname: {
|
||||||
label: 'label.id'
|
label: 'label.name'
|
||||||
},
|
},
|
||||||
name: {
|
state: {
|
||||||
label: 'label.name'
|
label: 'label.state',
|
||||||
},
|
indicator: {
|
||||||
displayname: {
|
'Ready': 'on',
|
||||||
label: 'label.display.name',
|
'Error': 'off'
|
||||||
},
|
}
|
||||||
type: {
|
},
|
||||||
label: 'label.vmsnapshot.type',
|
type: {
|
||||||
},
|
label: 'label.vmsnapshot.type'
|
||||||
description: {
|
},
|
||||||
label: 'label.description',
|
current: {
|
||||||
},
|
label: 'label.vmsnapshot.current',
|
||||||
state: {
|
converter: cloudStack.converters.toBooleanText
|
||||||
label: 'label.state',
|
},
|
||||||
indicator: {
|
parentName: {
|
||||||
'Ready': 'on',
|
label: 'label.vmsnapshot.parentname'
|
||||||
'Error': 'off'
|
},
|
||||||
|
created: {
|
||||||
|
label: 'label.date',
|
||||||
|
converter: cloudStack.converters.toLocalDate
|
||||||
}
|
}
|
||||||
},
|
|
||||||
current: {
|
|
||||||
label: 'label.vmsnapshot.current',
|
|
||||||
converter: cloudStack.converters.toBooleanText
|
|
||||||
},
|
|
||||||
parentName: {
|
|
||||||
label: 'label.vmsnapshot.parentname'
|
|
||||||
},
|
|
||||||
created: {
|
|
||||||
label: 'label.date',
|
|
||||||
converter: cloudStack.converters.toLocalDate
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
dataProvider: function(args) {
|
dataProvider: function(args) {
|
||||||
$.ajax({
|
var apiCmd = "listVMSnapshot&listAll=true";
|
||||||
url: createURL("listVMSnapshot&listAll=true&id=" + args.context.vmsnapshots[0].id),
|
if (args.context != null) {
|
||||||
dataType: "json",
|
if ("instances" in args.context) {
|
||||||
async: true,
|
apiCmd += "&virtualmachineid=" + args.context.instances[0].id;
|
||||||
success: function(json) {
|
|
||||||
var jsonObj;
|
|
||||||
jsonObj = json.listvmsnapshotresponse.vmSnapshot[0];
|
|
||||||
args.response.success({
|
|
||||||
//actionFilter: vmActionfilter,
|
|
||||||
data: jsonObj
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
tags: cloudStack.api.tags({ resourceType: 'VMSnapshot', contextId: 'vmsnapshots' })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
//delete a snapshot
|
|
||||||
remove: {
|
|
||||||
label: 'label.action.vmsnapshot.delete',
|
|
||||||
messages: {
|
|
||||||
confirm: function(args) {
|
|
||||||
return 'message.action.vmsnapshot.delete';
|
|
||||||
},
|
|
||||||
notification: function(args) {
|
|
||||||
return 'label.action.vmsnapshot.delete';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
action: function(args) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("deleteVMSnapshot&vmsnapshotid=" + args.context.vmsnapshots[0].id),
|
|
||||||
dataType: "json",
|
|
||||||
async: true,
|
|
||||||
success: function(json) {
|
|
||||||
var jid = json.deletevmsnapshotresponse.jobid;
|
|
||||||
args.response.success(
|
|
||||||
{_custom:
|
|
||||||
{jobId: jid}
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
$.ajax({
|
||||||
},
|
url: createURL(apiCmd),
|
||||||
notification: {
|
dataType: "json",
|
||||||
poll: pollAsyncJobResult
|
async: true,
|
||||||
}
|
success: function(json) {
|
||||||
},
|
var jsonObj;
|
||||||
restart: {
|
jsonObj = json.listvmsnapshotresponse.vmSnapshot;
|
||||||
label: 'label.action.vmsnapshot.revert',
|
args.response.success({
|
||||||
messages: {
|
data: jsonObj
|
||||||
confirm: function(args) {
|
});
|
||||||
return 'label.action.vmsnapshot.revert';
|
|
||||||
},
|
|
||||||
notification: function(args) {
|
|
||||||
return 'message.action.vmsnapshot.revert';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
action: function(args) {
|
|
||||||
$.ajax({
|
|
||||||
url: createURL("revertToVMSnapshot&vmsnapshotid=" + args.context.vmsnapshots[0].id),
|
|
||||||
dataType: "json",
|
|
||||||
async: true,
|
|
||||||
success: function(json) {
|
|
||||||
var jid = json.reverttovmsnapshotresponse.jobid;
|
|
||||||
args.response.success({
|
|
||||||
_custom: {
|
|
||||||
jobId: jid
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
//dataProvider end
|
||||||
|
detailView: {
|
||||||
|
tabs: {
|
||||||
|
details: {
|
||||||
|
title: 'label.details',
|
||||||
|
fields: {
|
||||||
|
id: {
|
||||||
|
label: 'label.id'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
label: 'label.name'
|
||||||
|
},
|
||||||
|
displayname: {
|
||||||
|
label: 'label.display.name',
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
label: 'label.vmsnapshot.type',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
label: 'label.description',
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
label: 'label.state',
|
||||||
|
indicator: {
|
||||||
|
'Ready': 'on',
|
||||||
|
'Error': 'off'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
current: {
|
||||||
|
label: 'label.vmsnapshot.current',
|
||||||
|
converter: cloudStack.converters.toBooleanText
|
||||||
|
},
|
||||||
|
parentName: {
|
||||||
|
label: 'label.vmsnapshot.parentname'
|
||||||
|
},
|
||||||
|
created: {
|
||||||
|
label: 'label.date',
|
||||||
|
converter: cloudStack.converters.toLocalDate
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
notification: {
|
dataProvider: function(args) {
|
||||||
poll: pollAsyncJobResult
|
$.ajax({
|
||||||
|
url: createURL("listVMSnapshot&listAll=true&id=" + args.context.vmsnapshots[0].id),
|
||||||
|
dataType: "json",
|
||||||
|
async: true,
|
||||||
|
success: function(json) {
|
||||||
|
var jsonObj;
|
||||||
|
jsonObj = json.listvmsnapshotresponse.vmSnapshot[0];
|
||||||
|
args.response.success({
|
||||||
|
//actionFilter: vmActionfilter,
|
||||||
|
data: jsonObj
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
tags: cloudStack.api.tags({
|
||||||
|
resourceType: 'VMSnapshot',
|
||||||
|
contextId: 'vmsnapshots'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
//delete a snapshot
|
||||||
|
remove: {
|
||||||
|
label: 'label.action.vmsnapshot.delete',
|
||||||
|
messages: {
|
||||||
|
confirm: function(args) {
|
||||||
|
return 'message.action.vmsnapshot.delete';
|
||||||
|
},
|
||||||
|
notification: function(args) {
|
||||||
|
return 'label.action.vmsnapshot.delete';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
action: function(args) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("deleteVMSnapshot&vmsnapshotid=" + args.context.vmsnapshots[0].id),
|
||||||
|
dataType: "json",
|
||||||
|
async: true,
|
||||||
|
success: function(json) {
|
||||||
|
var jid = json.deletevmsnapshotresponse.jobid;
|
||||||
|
args.response.success({
|
||||||
|
_custom: {
|
||||||
|
jobId: jid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
notification: {
|
||||||
|
poll: pollAsyncJobResult
|
||||||
|
}
|
||||||
|
},
|
||||||
|
restart: {
|
||||||
|
label: 'label.action.vmsnapshot.revert',
|
||||||
|
messages: {
|
||||||
|
confirm: function(args) {
|
||||||
|
return 'label.action.vmsnapshot.revert';
|
||||||
|
},
|
||||||
|
notification: function(args) {
|
||||||
|
return 'message.action.vmsnapshot.revert';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
action: function(args) {
|
||||||
|
$.ajax({
|
||||||
|
url: createURL("revertToVMSnapshot&vmsnapshotid=" + args.context.vmsnapshots[0].id),
|
||||||
|
dataType: "json",
|
||||||
|
async: true,
|
||||||
|
success: function(json) {
|
||||||
|
var jid = json.reverttovmsnapshotresponse.jobid;
|
||||||
|
args.response.success({
|
||||||
|
_custom: {
|
||||||
|
jobId: jid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
notification: {
|
||||||
|
poll: pollAsyncJobResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
//detailview end
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//detailview end
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})(jQuery, cloudStack);
|
})(jQuery, cloudStack);
|
||||||
|
|||||||
7839
ui/scripts/vpc.js
7839
ui/scripts/vpc.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user