Format JS

This commit is contained in:
Ian Duffy 2013-07-18 15:39:28 +01:00 committed by Sebastien Goasguen
parent dfa612d1fe
commit ad69bc8da3
62 changed files with 64071 additions and 59088 deletions

File diff suppressed because it is too large Load Diff

View File

@ -15,169 +15,193 @@
// specific language governing permissions and limitations
// under the License.
(function(cloudStack) {
cloudStack.sections.affinityGroups = {
title: 'label.affinity.groups',
listView: {
id: 'affinityGroups',
fields: {
name: { label: 'label.name' },
type: { label: 'label.type' }
},
dataProvider: function(args) {
var data = {};
if (args.context != null) {
if ("instances" in args.context) {
$.extend(data, {
virtualmachineid: args.context.instances[0].id
});
}
}
$.ajax({
url: createURL('listAffinityGroups'),
data: data,
success: function(json) {
var items = json.listaffinitygroupsresponse.affinitygroup;
args.response.success({data: items});
}
});
},
actions: {
add: {
label: 'label.add.affinity.group',
messages: {
notification: function(args) {
return 'label.add.affinity.group';
}
},
createForm: {
title: 'label.add.affinity.group',
cloudStack.sections.affinityGroups = {
title: 'label.affinity.groups',
listView: {
id: 'affinityGroups',
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})
}
});
name: {
label: 'label.name'
},
type: {
label: 'label.type'
}
}
}
},
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
}
});
}
});
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
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
actions: {
add: {
label: 'label.add.affinity.group',
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' }
}
],
messages: {
notification: function(args) {
return 'label.add.affinity.group';
}
},
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});
}
});
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);

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,14 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// 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
cloud.com default UI, there is no need to touch this file.
@ -23,17 +29,18 @@ cloud.com default UI, there is no need to touch this file.
/*
This callback function is called when either the session has timed out for the user,
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.
*/
function onLogoutCallback() {
g_loginResponse = null; //clear single signon variable g_loginResponse
return true; // return true means the login page will show
/*
g_loginResponse = null; //clear single signon variable g_loginResponse
return true; // return true means the login page will show
/*
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 clientConsoleUrl = "/client/console";
var clientConsoleUrl = "/client/console";
$(document).ready(function() {
var url = $.urlParam("loginUrl");
if (url != undefined && url != null && url.length > 0) {
url = unescape(clientApiUrl+"?"+url);
$.ajax({
url: url,
dataType: "json",
async: false,
success: function(json) {
g_loginResponse = json.loginresponse;
},
error: function() {
onLogoutCallback();
// This means the login failed. You should redirect to your login page.
},
beforeSend: function(XMLHttpRequest) {
return true;
}
});
}
var url = $.urlParam("loginUrl");
if (url != undefined && url != null && url.length > 0) {
url = unescape(clientApiUrl + "?" + url);
$.ajax({
url: url,
dataType: "json",
async: false,
success: function(json) {
g_loginResponse = json.loginresponse;
},
error: function() {
onLogoutCallback();
// This means the login failed. You should redirect to your login page.
},
beforeSend: function(XMLHttpRequest) {
return true;
}
});
}
});

View File

@ -15,480 +15,518 @@
// specific language governing permissions and limitations
// under the License.
(function(cloudStack, $) {
$.extend(cloudStack, {
home: 'dashboard',
$.extend(cloudStack, {
home: 'dashboard',
sectionPreFilter: function(args) {
var sections = [];
sectionPreFilter: function(args) {
var sections = [];
if(isAdmin()) {
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "system", "global-settings", "configuration", "projects", "regions", "affinityGroups"];
}
else if(isDomainAdmin()) {
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "projects", "regions", "affinityGroups"];
}
else if (g_userProjectsEnabled) {
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "projects", "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 (isAdmin()) {
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "system", "global-settings", "configuration", "projects", "regions", "affinityGroups"];
} else if (isDomainAdmin()) {
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "projects", "regions", "affinityGroups"];
} else if (g_userProjectsEnabled) {
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "projects", "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: {}
}
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
bypassLoginCheck: function(args) { //determine to show or bypass login screen
if (g_loginResponse == null) { //show login screen
/*
$.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');
};
}
}
}
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.
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.
*/
g_mySession = $.cookie('JSESSIONID');
g_sessionKey = $.cookie('sessionKey');
g_role = $.cookie('role');
g_username = $.cookie('username');
g_userid = $.cookie('userid');
g_account = $.cookie('account');
g_domainid = $.cookie('domainid');
g_userfullname = $.cookie('userfullname');
g_timezone = $.cookie('timezone');
if($.cookie('timezoneoffset') != null)
g_timezoneoffset = isNaN($.cookie('timezoneoffset'))? null: parseFloat($.cookie('timezoneoffset'));
else
g_timezoneoffset = null;
}
else { //single-sign-on (bypass login screen)
g_mySession = $.cookie('JSESSIONID');
g_sessionKey = encodeURIComponent(g_loginResponse.sessionkey);
g_role = g_loginResponse.type;
g_username = g_loginResponse.username;
g_userid = g_loginResponse.userid;
g_account = g_loginResponse.account;
g_domainid = g_loginResponse.domainid;
g_userfullname = g_loginResponse.firstname + ' ' + g_loginResponse.lastname;
g_timezone = g_loginResponse.timezone;
if(g_loginResponse.timezoneoffset != null)
g_timezoneoffset = isNaN(g_loginResponse.timezoneoffset)? null: parseFloat(g_loginResponse.timezoneoffset);
else
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_mySession = $.cookie('JSESSIONID');
g_sessionKey = $.cookie('sessionKey');
g_role = $.cookie('role');
g_username = $.cookie('username');
g_userid = $.cookie('userid');
g_account = $.cookie('account');
g_domainid = $.cookie('domainid');
g_userfullname = $.cookie('userfullname');
g_timezone = $.cookie('timezone');
if ($.cookie('timezoneoffset') != null)
g_timezoneoffset = isNaN($.cookie('timezoneoffset')) ? null : parseFloat($.cookie('timezoneoffset'));
else
g_timezoneoffset = null;
} else { //single-sign-on (bypass login screen)
g_mySession = $.cookie('JSESSIONID');
g_sessionKey = encodeURIComponent(g_loginResponse.sessionkey);
g_role = g_loginResponse.type;
g_username = g_loginResponse.username;
g_userid = g_loginResponse.userid;
g_account = g_loginResponse.account;
g_domainid = g_loginResponse.domainid;
g_userfullname = g_loginResponse.firstname + ' ' + g_loginResponse.lastname;
g_timezone = g_loginResponse.timezone;
if (g_loginResponse.timezoneoffset != null)
g_timezoneoffset = isNaN(g_loginResponse.timezoneoffset) ? null : parseFloat(g_loginResponse.timezoneoffset);
else
g_timezoneoffset = null;
}
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) {
var userValid = 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;
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;
}
}
});
}
} 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
});
// 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 }));
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;
$.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();
} else {
// Show cloudStack main UI
$container.cloudStack($.extend(cloudStackArgs, { hasLogo: false }));
}
// 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
}));
}
});
};
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) {
// SSO
loginArgs.hideLoginScreen = true;
}
if ($.urlParam('loginUrl') != 0) {
// SSO
loginArgs.hideLoginScreen = true;
}
cloudStack.uiCustom.login(loginArgs);
cloudStack.uiCustom.login(loginArgs);
// Localization
if (!$.isFunction(cloudStack.localizationFn)) { // i.e., localize is overridden by a plugin/module
cloudStack.localizationFn = function(str) {
return dictionary[str];
};
}
// Localization
if (!$.isFunction(cloudStack.localizationFn)) { // i.e., localize is overridden by a plugin/module
cloudStack.localizationFn = function(str) {
return dictionary[str];
};
}
document.title = _l('label.app.name');
});
document.title = _l('label.app.name');
});
})(cloudStack, jQuery);

File diff suppressed because it is too large Load Diff

View File

@ -15,249 +15,245 @@
// specific language governing permissions and limitations
// under the License.
(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: {
zoneDetailView: {
tabs: {
resources: {
title: 'label.resources',
custom: cloudStack.uiCustom.systemChart('resources')
}
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: {
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);

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

View File

@ -16,341 +16,428 @@
// under the License.
(function(cloudStack) {
cloudStack.sections['global-settings'] = {
title: 'label.menu.global.settings',
id: 'global-settings',
sectionSelect: {
label: 'label.select-view'
},
sections: {
globalSettings: {
type: 'select',
cloudStack.sections['global-settings'] = {
title: 'label.menu.global.settings',
listView: {
label: 'label.menu.global.settings',
actions: {
edit: {
label: 'label.change.value',
action: function(args) {
var data = {
name: args.data.jsonObj.name,
value: args.data.value
};
$.ajax({
url: createURL('updateConfiguration'),
data: data,
success: function(json) {
var item = json.updateconfigurationresponse.configuration;
if(item.category == "Usage")
cloudStack.dialog.notice({ message: _l('message.restart.mgmt.usage.server') });
else
cloudStack.dialog.notice({ message: _l('message.restart.mgmt.server') });
args.response.success({data: item});
},
error: function(json) {
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
};
id: 'global-settings',
sectionSelect: {
label: 'label.select-view'
},
sections: {
globalSettings: {
type: 'select',
title: 'label.menu.global.settings',
listView: {
label: 'label.menu.global.settings',
actions: {
edit: {
label: 'label.change.value',
action: function(args) {
var data = {
name: args.data.jsonObj.name,
value: args.data.value
};
$.ajax({
url: createURL('updateConfiguration'),
data: data,
success: function(json) {
var item = json.updateconfigurationresponse.configuration;
if (item.category == "Usage")
cloudStack.dialog.notice({
message: _l('message.restart.mgmt.usage.server')
});
else
cloudStack.dialog.notice({
message: _l('message.restart.mgmt.server')
});
args.response.success({
data: item
});
},
error: function(json) {
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) {
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');
if (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
});
}
});
}
}
}
},
},
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));
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'
}
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) {
args.response.error(parseXMLHttpResponse(data));
}
});
}
}
},
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');
}
}
},
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);

View File

@ -15,342 +15,344 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
cloudStack.installWizard = {
// Check if install wizard should be invoked
check: function(args) {
$.ajax({
url: createURL('listZones'),
dataType: 'json',
async: true,
success: function(data) {
args.response.success({
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';
cloudStack.installWizard = {
// Check if install wizard should be invoked
check: function(args) {
$.ajax({
url: createURL('listZones'),
dataType: 'json',
async: true,
success: function(data) {
args.response.success({
doInstall: !data.listzonesresponse.zone
});
}
});
},
if (builtinTemplates.length) {
clearInterval(poll);
message('Your CloudStack is ready!');
setTimeout(success, 1000);
}
}
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'
});
}, 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));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,292 +16,304 @@
// under the License.
(function($, cloudStack) {
cloudStack.lbStickyPolicy = {
dialog: function(args) {
return function(args) {
var success = args.response.success;
var context = args.context;
var network;
if('vpc' in args.context) { //from VPC section
var data = {
listAll: true,
supportedservices: 'Lb'
};
if(args.context.ipAddresses[0].associatednetworkid == null) {
$.extend(data, {
vpcid: args.context.vpc[0].id
});
}
else {
$.extend(data, {
id: args.context.ipAddresses[0].associatednetworkid
});
}
$.ajax({
url: createURL("listNetworks"), //check whether the VPC has a network including Lb service
data: data,
async: false,
success: function(json) {
var items = json.listnetworksresponse.network;
if(items != null && items.length > 0) {
network = items[0];
}
}
});
}
else { //from Guest Network section
network = args.context.networks[0];
}
var $item = args.$item;
cloudStack.lbStickyPolicy = {
dialog: function(args) {
return function(args) {
var success = args.response.success;
var context = args.context;
var lbService = $.grep(network.service, function(service) {
return service.name == 'Lb';
})[0];
var stickinessCapabilities = JSON.parse($.grep(
lbService.capability,
function(capability) {
return capability.name == 'SupportedStickinessMethods';
}
)[0].value);
var network;
if ('vpc' in args.context) { //from VPC section
var data = {
listAll: true,
supportedservices: 'Lb'
};
if (args.context.ipAddresses[0].associatednetworkid == null) {
$.extend(data, {
vpcid: args.context.vpc[0].id
});
} else {
$.extend(data, {
id: args.context.ipAddresses[0].associatednetworkid
});
}
var baseFields = {
stickyName: { label: 'Sticky Name', validation: { required: true } }
};
$.ajax({
url: createURL("listNetworks"), //check whether the VPC has a network including Lb service
data: data,
async: false,
success: function(json) {
var items = json.listnetworksresponse.network;
if (items != null && items.length > 0) {
network = items[0];
}
}
});
} else { //from Guest Network section
network = args.context.networks[0];
}
$.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 $item = args.$item;
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;
var lbService = $.grep(network.service, function(service) {
return service.name == 'Lb';
})[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');
var stickinessCapabilities = JSON.parse($.grep(
lbService.capability,
function(capability) {
return capability.name == 'SupportedStickinessMethods';
}
)[0].value);
if ($.inArray(id, visibleParams) > -1) {
$field.css('display', 'inline-block');
$field.attr('sticky-method', value);
} else {
$field.hide();
$field.attr('sticky-method', null);
}
});
var baseFields = {
stickyName: {
label: 'Sticky Name',
validation: {
required: true
}
}
};
// Name always is required
if ($select.val() != 'None') {
$select.closest('.form-item').siblings('.form-item[rel=stickyName]')
.css('display', 'inline-block');
$.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];
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) {
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;
/* $item indicates that this is an existing sticky rule;
re-create sticky rule with new parameters */
if ($item) {
var $loading = $('<div>').addClass('loading-overlay');
if ($item) {
var $loading = $('<div>').addClass('loading-overlay');
$loading.prependTo($item);
cloudStack.lbStickyPolicy.actions.recreate(
$item.data('multi-custom-data').id,
$item.data('multi-custom-data').lbRuleID,
data,
function() { // Complete
$(window).trigger('cloudStack.fullRefresh');
},
function(error) { // Error
$(window).trigger('cloudStack.fullRefresh');
$loading.prependTo($item);
cloudStack.lbStickyPolicy.actions.recreate(
$item.data('multi-custom-data').id,
$item.data('multi-custom-data').lbRuleID,
data,
function() { // Complete
$(window).trigger('cloudStack.fullRefresh');
},
function(error) { // Error
$(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 = '&param[' + 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 = '&param[' + 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));

File diff suppressed because it is too large Load Diff

View File

@ -15,100 +15,100 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack, require) {
if (!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);
if (!cloudStack.pluginAPI) {
cloudStack.pluginAPI = {};
}
};
$.extend(cloudStack.pluginAPI, {
ui: {
pollAsyncJob: pollAsyncJobResult,
apiCall: function(command, args) {
$.ajax({
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);
}
}
});
cloudStack.sections.plugins = {
title: 'label.plugins',
show: cloudStack.uiCustom.pluginListing
};
var loadCSS = function(path) {
if (document.createStyleSheet) {
// IE-compatible CSS loading
document.createStyleSheet(path);
} else {
var $link = $('<link>');
var loadedPlugins = 0;
var pluginTotal = cloudStack.plugins.length + cloudStack.modules.length;
$link.attr({
rel: 'stylesheet',
type: 'text/css',
href: path
});
// Load
$(['modules', 'plugins']).each(function() {
var type = this;
var paths = $(cloudStack[type]).map(function(index, id) {
return type + '/' + id + '/' + id;
}).toArray();
$('html head').append($link);
}
};
// 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;
$.extend(cloudStack.pluginAPI, {
ui: {
pollAsyncJob: pollAsyncJobResult,
apiCall: function(command, args) {
$.ajax({
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);
}
}
});
if (configJS) {
// Load config metadata
require([configJS]);
}
cloudStack.sections.plugins = {
title: 'label.plugins',
show: cloudStack.uiCustom.pluginListing
};
// Execute module
cloudStack[type][id](
$.extend(true, {}, cloudStack.pluginAPI, {
pluginAPI: {
extend: function(api) {
cloudStack.pluginAPI[id] = api;
}
}
})
);
var loadedPlugins = 0;
var pluginTotal = cloudStack.plugins.length + cloudStack.modules.length;
loadedPlugins = loadedPlugins + 1;
// Load
$(['modules', 'plugins']).each(function() {
var type = this;
var paths = $(cloudStack[type]).map(function(index, id) {
return type + '/' + id + '/' + id;
}).toArray();
if (loadedPlugins === pluginTotal) {
$(window).trigger('cloudStack.pluginReady');
}
// 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;
loadCSS(css);
});
}
);
});
if (configJS) {
// Load config metadata
require([configJS]);
}
// 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));

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -16,386 +16,403 @@
// under the License.
(function($, cloudStack) {
cloudStack.uiCustom.autoscaler = function(args) {
// Place outer args here as local variables
// i.e, -- var dataProvider = args.dataProvider
var forms = $.extend(true, {}, args.forms);
var topfields = forms.topFields;
var bottomfields = forms.bottomFields;
var scaleuppolicy = forms.scaleUpPolicy;
var scaledownpolicy = forms.scaleDownPolicy;
var dataProvider = cloudStack.autoscaler.dataProvider;
var actions = cloudStack.autoscaler.autoscaleActions;
var actionFilter = cloudStack.autoscaler.actionFilter;
cloudStack.uiCustom.autoscaler = function(args) {
// Place outer args here as local variables
// i.e, -- var dataProvider = args.dataProvider
var forms = $.extend(true, {}, args.forms);
var topfields = forms.topFields;
var bottomfields = forms.bottomFields;
var scaleuppolicy = forms.scaleUpPolicy;
var scaledownpolicy = forms.scaleDownPolicy;
var dataProvider = cloudStack.autoscaler.dataProvider;
var actions = cloudStack.autoscaler.autoscaleActions;
var actionFilter = cloudStack.autoscaler.actionFilter;
return function(args) {
var context = args.data ?
$.extend(true, {}, args.context, {
lbRules: [args.data]
}) : args.context;
var formData = args.formData;
var $autoscalerDialog = $('<div>').addClass('autoscaler');
var $topFields = $('<div>').addClass('field-group top-fields');
var $bottomFields = $('<div>').addClass('field-group bottom-fields');
var $scaleUpPolicy = $('<div>').addClass('scale-up-policy');
var $slideScaleUp = $('<div></div>').addClass('expand');
var $hideScaleUp = $('<div></div>').addClass('hide');
var $scaleUpLabel= $('<div>Show</div>').addClass('slide-label');
var $scaleUpHideLabel=$('<div>Hide</div>').addClass('slide-label');
var $scaleDownHideLabel=$('<div>Hide</div>').addClass('slide-label');
var $scaleDownLabel=$('<div>Show</div>').addClass('slide-label');
var $slideScaleDown = $('<div></div>').addClass('expand');
var $hideScaleDown = $('<div></div>').addClass('hide');
var $scaleUpDivider = $('<hr></hr>').addClass('policy-divider');
var $scaleDownDivider = $('<hr></hr>').addClass('policy-divider');
var $bottomFieldDivider = $('<hr></hr>').addClass('policy-divider');
var $scaleDownPolicy = $('<div>').addClass('scale-down-policy');
var $scaleUpPolicyTitle = $('<div>').addClass('scale-up-policy-title')
.html("Scale Up Policy");
var $scaleDownPolicyTitle = $('<div>').addClass('scale-down-policy-title')
.html("Scale Down Policy");
var topFieldForm, $topFieldForm,
bottomFieldForm, $bottomFieldForm,
scaleUpPolicyTitleForm, $scaleUpPolicyTitleForm,
scaleDownPolicyTitleForm, $scaleDownPolicyTitleForm,
scaleUpPolicyForm, scaleDownPolicyForm;
return function(args) {
var context = args.data ?
$.extend(true, {}, args.context, {
lbRules: [args.data]
}) : args.context;
var formData = args.formData;
var $autoscalerDialog = $('<div>').addClass('autoscaler');
var $topFields = $('<div>').addClass('field-group top-fields');
var $bottomFields = $('<div>').addClass('field-group bottom-fields');
var $scaleUpPolicy = $('<div>').addClass('scale-up-policy');
var $slideScaleUp = $('<div></div>').addClass('expand');
var $hideScaleUp = $('<div></div>').addClass('hide');
var $scaleUpLabel = $('<div>Show</div>').addClass('slide-label');
var $scaleUpHideLabel = $('<div>Hide</div>').addClass('slide-label');
var $scaleDownHideLabel = $('<div>Hide</div>').addClass('slide-label');
var $scaleDownLabel = $('<div>Show</div>').addClass('slide-label');
var $slideScaleDown = $('<div></div>').addClass('expand');
var $hideScaleDown = $('<div></div>').addClass('hide');
var $scaleUpDivider = $('<hr></hr>').addClass('policy-divider');
var $scaleDownDivider = $('<hr></hr>').addClass('policy-divider');
var $bottomFieldDivider = $('<hr></hr>').addClass('policy-divider');
var $scaleDownPolicy = $('<div>').addClass('scale-down-policy');
var $scaleUpPolicyTitle = $('<div>').addClass('scale-up-policy-title')
.html("Scale Up Policy");
var $scaleDownPolicyTitle = $('<div>').addClass('scale-down-policy-title')
.html("Scale Down Policy");
var topFieldForm, $topFieldForm,
bottomFieldForm, $bottomFieldForm,
scaleUpPolicyTitleForm, $scaleUpPolicyTitleForm,
scaleDownPolicyTitleForm, $scaleDownPolicyTitleForm,
scaleUpPolicyForm, scaleDownPolicyForm;
var renderActions = function(args) {
var targetActionFilter = args.actionFilter ? args.actionFilter : actionFilter;
var data = args.data;
var context = args.context;
var $actions = $('<div>').addClass('detail-group');
var $actionsTable = $('<table>').append('<tr>');
var $detailActions = $('<td>').addClass('detail-actions');
var $buttons = $('<div>').addClass('buttons');
var visibleActions = targetActionFilter ?
targetActionFilter({
context: $.extend(true, {}, context, {
originalAutoscaleData: data ? [data] : null
})
}) :
$.map(actions, function(value, key) { return key; });
$detailActions.append($buttons);
$actionsTable.find('tr').append($detailActions);
$actions.append($actionsTable);
$(visibleActions).map(function(index, actionID) {
var action = actions[actionID];
var label = _l(action.label);
var $action = $('<div>').addClass('action').addClass(actionID);
var $icon = $('<a>')
.attr({ href: '#', title: label })
.append($('<span>').addClass('icon'));
if (visibleActions.length == 1) $action.addClass('single');
else if (!index) $action.addClass('first');
else if (index == visibleActions.length - 1) $action.addClass('last');
// Perform action event
$action.click(function() {
var $loading = $('<div>').addClass('loading-overlay').appendTo($autoscalerDialog);
var success = function(args) {
$loading.remove();
cloudStack.dialog.notice({
message: _l('label.task.completed') + ': ' + label
});
// Reload actions
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.'
var renderActions = function(args) {
var targetActionFilter = args.actionFilter ? args.actionFilter : actionFilter;
var data = args.data;
var context = args.context;
var $actions = $('<div>').addClass('detail-group');
var $actionsTable = $('<table>').append('<tr>');
var $detailActions = $('<td>').addClass('detail-actions');
var $buttons = $('<div>').addClass('buttons');
var visibleActions = targetActionFilter ?
targetActionFilter({
context: $.extend(true, {}, context, {
originalAutoscaleData: data ? [data] : null
})
}) :
$.map(actions, function(value, key) {
return key;
});
},
error: function(message) {
cloudStack.dialog.notice({ message: message });
$loading.remove();
}
$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);
}
});
}
}
]
}).closest('.ui-dialog').overlay();
dataProvider({
context: context,
response: {
success: function(args) {
$loading.remove();
renderDialogContent(args);
if (data.scaleUpPolicy && data.scaleUpPolicy.duration) {
$scaleUpPolicyTitleForm.find('input[name=scaleUpDuration]').val(
data.scaleUpPolicy.duration
);
}
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');
}
}
}
}
});
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) {
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));

View File

@ -15,178 +15,191 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
cloudStack.uiCustom.dashboard = function() {
/**
* Retrieve chart data
*/
var getData = function() {
// Populate data
$dashboard.find('[data-item]').hide();
cloudStack.sections.dashboard[dashboardType].dataProvider({
response: {
success: function(args) {
var $browser = $dashboard.closest('#browser .container');
var data = args.data;
cloudStack.uiCustom.dashboard = function() {
/**
* Retrieve chart data
*/
var getData = function() {
// Populate data
$dashboard.find('[data-item]').hide();
cloudStack.sections.dashboard[dashboardType].dataProvider({
response: {
success: function(args) {
var $browser = $dashboard.closest('#browser .container');
var data = args.data;
// Iterate over data; populate corresponding DOM elements
$.each(data, function(key, value) {
var $elem = $dashboard.find('[data-item=' + key + ']');
// Iterate over data; populate corresponding DOM elements
$.each(data, function(key, value) {
var $elem = $dashboard.find('[data-item=' + key + ']');
// This assumes an array of data
if ($elem.is('ul')) {
$elem.show();
var $liTmpl = $elem.find('li').remove();
$(value).each(function() {
var item = this;
var $li = $liTmpl.clone().appendTo($elem).hide();
// This assumes an array of data
if ($elem.is('ul')) {
$elem.show();
var $liTmpl = $elem.find('li').remove();
$(value).each(function() {
var item = this;
var $li = $liTmpl.clone().appendTo($elem).hide();
if ($li.is('.zone-stats li')) {
$li.click(function() {
$browser.cloudBrowser('addPanel', {
title: _l('label.zone.details'),
parent: $dashboard.closest('.panel'),
maximizeIfSelected: true,
complete: function($newPanel) {
$newPanel.detailView($.extend(true, {},
cloudStack.sections.dashboard.admin.zoneDetailView,
{
$browser: $browser,
context: $.extend(true, {}, cloudStack.context, {
physicalResources: [{ id: item.zoneID }]
})
if ($li.is('.zone-stats li')) {
$li.click(function() {
$browser.cloudBrowser('addPanel', {
title: _l('label.zone.details'),
parent: $dashboard.closest('.panel'),
maximizeIfSelected: true,
complete: function($newPanel) {
$newPanel.detailView($.extend(true, {},
cloudStack.sections.dashboard.admin.zoneDetailView, {
$browser: $browser,
context: $.extend(true, {}, cloudStack.context, {
physicalResources: [{
id: item.zoneID
}]
})
}
));
}
});
});
}
));
}
});
});
}
$.each(item, function(arrayKey, arrayValue) {
if (!arrayValue) arrayValue = '';
$.each(item, function(arrayKey, arrayValue) {
if (!arrayValue) arrayValue = '';
var $arrayElem = $li.find('[data-list-item=' + arrayKey + ']');
var $arrayElem = $li.find('[data-list-item=' + arrayKey + ']');
$arrayElem.each(function() {
var $arrayElem = $(this);
$arrayElem.each(function() {
var $arrayElem = $(this);
if ($arrayElem.hasClass('pie-chart')) {
// Generate pie chart
// -- values above 80 have a red color
setTimeout(function() {
pieChart($arrayElem, [
{ data: [[1, 100 - arrayValue]], color: '#54697e' },
{ data: [[1, arrayValue]], color: arrayValue < 80 ? 'orange' : 'red' }
]);
if ($arrayElem.hasClass('pie-chart')) {
// Generate pie chart
// -- values above 80 have a red color
setTimeout(function() {
pieChart($arrayElem, [{
data: [
[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;
}).toArray().join('<br />');
$arrayElem.html(val);
} else {
$arrayElem.html(_s(_l(arrayValue)));
/**
* Render circular pie chart, without labels
*/
var pieChart = function($container, data) {
$container.css({
width: 70,
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/>', ', '));
}
});
});
$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();
}
});
}
}
},
legend: {
show: false
}
});
}
}
});
};
};
/**
* Render circular pie chart, without labels
*/
var pieChart = function($container, data) {
$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
var dashboardType = cloudStack.sections.dashboard.adminCheck({
context: cloudStack.context
}) ? 'admin' : 'user';
// Determine if user or admin dashboard should be shown
var dashboardType = cloudStack.sections.dashboard.adminCheck({
context: cloudStack.context
}) ? 'admin' : 'user';
// Get dashboard layout
var $dashboard = $('#template').find('div.dashboard.' + dashboardType).clone();
// Get dashboard layout
var $dashboard = $('#template').find('div.dashboard.' + dashboardType).clone();
// Update text
$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
$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'));
// View all action
$dashboard.find('.view-all').click(function() {
var $browser = $('#browser .container');
// View all action
$dashboard.find('.view-all').click(function() {
var $browser = $('#browser .container');
if ($(this).hasClass('network')) $('#navigation li.network').click();
else {
$browser.cloudBrowser('addPanel', {
title: $dashboard.hasClass('admin') ? 'Alerts' : 'Events',
maximizeIfSelected: true,
complete: function($newPanel) {
$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
});
}
if ($(this).hasClass('network')) $('#navigation li.network').click();
else {
$browser.cloudBrowser('addPanel', {
title: $dashboard.hasClass('admin') ? 'Alerts' : 'Events',
maximizeIfSelected: true,
complete: function($newPanel) {
$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
$dashboard.find('.fetch-latest').click(function() {
window.fetchLatestflag = 1;
var $browser = $('#browser .container');
//Fetch Latest action
$dashboard.find('.fetch-latest').click(function() {
window.fetchLatestflag = 1;
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));

View File

@ -15,157 +15,160 @@
// specific language governing permissions and limitations
// under the License.
(function(cloudStack, $) {
cloudStack.uiCustom.enableStaticNAT = function(args) {
var listView = args.listView;
var action = args.action;
var tierSelect = args.tierSelect;
cloudStack.uiCustom.enableStaticNAT = function(args) {
var listView = args.listView;
var action = args.action;
var tierSelect = args.tierSelect;
return function(args) {
var context = args.context;
var $instanceRow = args.$instanceRow;
return function(args) {
var context = args.context;
var $instanceRow = args.$instanceRow;
var vmList = function(args) {
// Create a listing of instances, based on limited information
// from main instances list view
var $listView;
var instances = $.extend(true, {}, args.listView, {
context: context,
uiCustom: true
});
instances.listView.actions = {
select: {
label: _l('label.select.instance'),
type: '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 });
}
}
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
});
$dataList.remove();
});
$('div.overlay').fadeOut(function() {
$('div.overlay').remove();
});
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() {
$('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));

View File

@ -16,31 +16,39 @@
// under the License.
(function($, cloudStack) {
cloudStack.uiCustom.granularSettings = function(args) {
var dataProvider = args.dataProvider;
var actions = args.actions;
return function(args) {
var context = args.context;
var listView = {
id: 'settings',
fields: {
name: { label: 'label.name' },
value: { label: 'label.value', editable: true }
},
actions: {
edit: {
label: 'label.change.value',
action: actions.edit
}
},
dataProvider: dataProvider
};
var $listView = $('<div>').listView({ context: context, listView: listView });
return $listView;
}
};
cloudStack.uiCustom.granularSettings = function(args) {
var dataProvider = args.dataProvider;
var actions = args.actions;
return function(args) {
var context = args.context;
var listView = {
id: 'settings',
fields: {
name: {
label: 'label.name'
},
value: {
label: 'label.value',
editable: true
}
},
actions: {
edit: {
label: 'label.change.value',
action: actions.edit
}
},
dataProvider: dataProvider
};
var $listView = $('<div>').listView({
context: context,
listView: listView
});
return $listView;
}
};
}(jQuery, cloudStack));

View File

@ -17,334 +17,367 @@
(function($, cloudStack) {
cloudStack.uiCustom.healthCheck = function(args) {
cloudStack.uiCustom.healthCheck = function(args) {
// Place outer args here as local variables
// i.e, -- var dataProvider = args.dataProvider
// Place outer args here as local variables
// i.e, -- var dataProvider = args.dataProvider
return function(args){
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') });
return;
}
var formData = args.formData;
var forms = $.extend(true, {}, args.forms);
var topFieldForm, bottomFieldForm , $topFieldForm , $bottomFieldForm;
var topfields = forms.topFields;
return function(args) {
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')
});
return;
}
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 $healthCheckAdvancedTitle = $('<div><br><br> Advanced Options : </div>').addClass('health-check-advanced-title');
var $healthCheckDialog = $('<div>').addClass('health-check');
$healthCheckDialog.append($healthCheckDesc);
$healthCheckDialog.append($healthCheckConfigTitle);
var $loadingOnDialog = $('<div>').addClass('loading-overlay');
var policyObj = null;
var pingpath1 = '/';
var responsetimeout1 = '2';
var healthinterval1 = '5';
var healthythreshold1 = '2';
var unhealthythreshold1 = '1';
$.ajax({
url: createURL('listLBHealthCheckPolicies'),
data: {
lbruleid: args.context.multiRules[0].id
},
async: false,
success: function(json) {
if(json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0] != undefined) {
policyObj = json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0];
pingpath1 = policyObj.pingpath; //API bug: API doesn't return it
responsetimeout1 = policyObj.responsetime;
healthinterval1 = policyObj.healthcheckinterval;
healthythreshold1 = policyObj.healthcheckthresshold;
unhealthythreshold1 = policyObj.unhealthcheckthresshold;
}
}
});
topFieldForm = cloudStack.dialog.createForm({
context: args.context,
noDialog: true, // Don't render a dialog, just return $formContainer
form: {
title: '',
fields:{
pingpath: {label: 'Ping Path', validation: {required: false}, defaultValue: pingpath1}
}
}
});
var formData = args.formData;
var forms = $.extend(true, {}, args.forms);
var topFieldForm, bottomFieldForm, $topFieldForm, $bottomFieldForm;
var topfields = forms.topFields;
$topFieldForm = topFieldForm.$formContainer;
$topFieldForm.appendTo($healthCheckDialog);
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 $healthCheckAdvancedTitle = $('<div><br><br> Advanced Options : </div>').addClass('health-check-advanced-title');
$healthCheckDialog.append($healthCheckAdvancedTitle);
var $healthCheckDialog = $('<div>').addClass('health-check');
$healthCheckDialog.append($healthCheckDesc);
$healthCheckDialog.append($healthCheckConfigTitle);
var $loadingOnDialog = $('<div>').addClass('loading-overlay');
var policyObj = null;
var pingpath1 = '/';
var responsetimeout1 = '2';
var healthinterval1 = '5';
var healthythreshold1 = '2';
var unhealthythreshold1 = '1';
$.ajax({
url: createURL('listLBHealthCheckPolicies'),
data: {
lbruleid: args.context.multiRules[0].id
},
async: false,
success: function(json) {
if (json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0] != undefined) {
policyObj = json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0];
pingpath1 = policyObj.pingpath; //API bug: API doesn't return it
responsetimeout1 = policyObj.responsetime;
healthinterval1 = policyObj.healthcheckinterval;
healthythreshold1 = policyObj.healthcheckthresshold;
unhealthythreshold1 = policyObj.unhealthcheckthresshold;
}
}
});
topFieldForm = cloudStack.dialog.createForm({
context: args.context,
noDialog: true, // Don't render a dialog, just return $formContainer
form: {
title: '',
fields: {
pingpath: {
label: 'Ping Path',
validation: {
required: false
},
defaultValue: pingpath1
}
}
}
});
$topFieldForm = topFieldForm.$formContainer;
$topFieldForm.appendTo($healthCheckDialog);
$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

View File

@ -15,152 +15,149 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
cloudStack.ipRules = function(args) {
return function(detailArgs) {
var context = detailArgs.context;
cloudStack.ipRules = function(args) {
return function(detailArgs) {
var context = detailArgs.context;
var portMultiEdit = function(args) {
return $('<div>').multiEdit(args);
};
var portMultiEdit = function(args) {
return $('<div>').multiEdit(args);
};
var makeMultiEditPanel = function($item) {
if ($item.closest('li').hasClass('disabled'))
return false;
var makeMultiEditPanel = function($item) {
if ($item.closest('li').hasClass('disabled'))
return false;
var targetId = $item.attr('net-target');
var targetName = $item.parent().find('.name').find('span').html();
var target = args[targetId];
var targetId = $item.attr('net-target');
var targetName = $item.parent().find('.name').find('span').html();
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', {
title: _l('label.static.nat.vm.details'),
complete: function($newPanel) {
vmDataProvider({
context: context,
response: {
success: function(args) {
var instance = args.data;
var detailViewArgs = $.extend(true, {}, vmDetails, {
title: targetName,
maximizeIfSelected: true,
complete: function($newPanel) {
$newPanel.detailView({
$browser: $browser,
context: $.extend(true, {}, context, {
instances: [instance]
}),
jsonObj: instance,
id: instance.id
});
// No actions available
detailViewArgs.actions = {};
$newPanel.detailView(detailViewArgs);
}
}
});
}
name: targetId,
context: context,
tabs: {
network: {
title: targetName,
custom: function(args) {
return portMultiEdit($.extend(target, {
context: context
}));
}
}
}
});
}
});
});
}
}
});
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 true;
};
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();
var preFilter = args.preFilter ? args.preFilter({
items: ['firewall', 'portForwarding', 'loadBalancing'],
context: context
}) : [];
$vmName.append(
$('<span>').html('VM: ' + _s(vmName)),
$('<span>').html('<br/>VM IP: ' + vmIP)
);
// 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;
$vmName.click(function() {
$browser.cloudBrowser('addPanel', {
title: _l('label.static.nat.vm.details'),
complete: function($newPanel) {
vmDataProvider({
context: context,
response: {
success: function(args) {
var instance = args.data;
var detailViewArgs = $.extend(true, {}, vmDetails, {
$browser: $browser,
context: $.extend(true, {}, context, {
instances: [instance]
}),
jsonObj: instance,
id: instance.id
});
var $li = $chart.find('li').filter(function() {
return $(this).hasClass(id);
}).addClass('disabled');
});
}
}
// No actions available
detailViewArgs.actions = {};
$chart.find('.view-details').click(function() {
makeMultiEditPanel($(this));
return false;
});
$newPanel.detailView(detailViewArgs);
}
}
});
}
});
});
}
}
});
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);

View File

@ -15,133 +15,135 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
/**
* Login process
*/
cloudStack.uiCustom.login = function(args) {
var $container = args.$container;
var $login = $('#template').find('.login').clone();
var $form = $login.find('form');
var $inputs = $form.find('input[type=text], input[type=password]');
var complete = args.complete;
var bypass = args.bypassLoginCheck && args.bypassLoginCheck();
/**
* Login process
*/
cloudStack.uiCustom.login = function(args) {
var $container = args.$container;
var $login = $('#template').find('.login').clone();
var $form = $login.find('form');
var $inputs = $form.find('input[type=text], input[type=password]');
var complete = args.complete;
var bypass = args.bypassLoginCheck && args.bypassLoginCheck();
// Check to see if we can bypass login screen
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');
// Check to see if we can bypass login screen
if (bypass) {
complete({
user: args.data.user
user: bypass.user
});
},
error: function(args) {
cloudStack.dialog.notice({ message: args });
}
$(window).trigger('cloudStack.init');
return;
}
});
return false;
});
$login.appendTo('html body');
$('html body').addClass('login');
// 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'));
// 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();
}
});
// 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'] + '...'
)
));
}
// Form validation
$form.validate();
$(window).trigger('cloudStack.init');
};
// 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({
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);

View File

@ -15,123 +15,139 @@
// specific language governing permissions and limitations
// under the License.
(function(cloudStack, $) {
cloudStack.uiCustom.physicalResources = function(args) {
var listView = function(targetID) {
var target = args.sections.physicalResources.listView[targetID];
var listViewArgs = $.isFunction(target) ? target() : target;
cloudStack.uiCustom.physicalResources = function(args) {
var listView = function(targetID) {
var target = args.sections.physicalResources.listView[targetID];
var listViewArgs = $.isFunction(target) ? target() : target;
return $('<div>').listView(
(listViewArgs.listView || listViewArgs.sections) ? listViewArgs : { listView: listViewArgs }
);
};
var $dashboard = $('#template').find('.system-dashboard-view').clone();
var getData = function() {
// Populate data
$dashboard.find('[data-item]').hide();
cloudStack.sections.system.dashboard.dataProvider({
response: {
success: function(args) {
var data = args.data;
$.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();
return $('<div>').listView(
(listViewArgs.listView || listViewArgs.sections) ? listViewArgs : {
listView: listViewArgs
}
);
};
var $dashboard = $('#template').find('.system-dashboard-view').clone();
var getData = function() {
// Populate data
$dashboard.find('[data-item]').hide();
cloudStack.sections.system.dashboard.dataProvider({
response: {
success: function(args) {
var data = args.data;
$.each(data, function(key, value) {
var $elem = $dashboard.find('[data-item=' + key + ']');
$elem.hide().html(value).fadeIn();
});
}
});
}, 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;
});
$dashboard.find('#refresh_button').click(function() {
getData();
return false;
});
return resourceChart(args);
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: {}
});
return false;
});
$dashboard.find('#refresh_button').click(function() {
getData();
return false;
});
return resourceChart(args);
};
};
};
}(cloudStack, jQuery));

View File

@ -15,95 +15,107 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
var elems = {
pluginItem: function(args) {
var id = args.id;
var title = args.title;
var desc = args.desc;
var iconURL = args.iconURL;
var $pluginItem = $('<li>').addClass('plugin-item').addClass(id);
var $title = $('<span>').addClass('title').html(title);
var $desc = $('<span>').addClass('desc').html(desc);
var $icon = $('<span>').addClass('icon').append(
$('<img>').attr({ src: iconURL })
);
var elems = {
pluginItem: function(args) {
var id = args.id;
var title = args.title;
var desc = args.desc;
var iconURL = args.iconURL;
var $pluginItem = $('<li>').addClass('plugin-item').addClass(id);
var $title = $('<span>').addClass('title').html(title);
var $desc = $('<span>').addClass('desc').html(desc);
var $icon = $('<span>').addClass('icon').append(
$('<img>').attr({
src: iconURL
})
);
$pluginItem.append(
$icon, $title, $desc
);
$pluginItem.append(
$icon, $title, $desc
);
return $pluginItem;
},
pluginListing: function(args) {
var plugins = args.plugins;
var $plugins = $('<ul>');
var $pluginsListing = $('<div>').addClass('plugins-listing');
return $pluginItem;
},
pluginListing: function(args) {
var plugins = args.plugins;
var $plugins = $('<ul>');
var $pluginsListing = $('<div>').addClass('plugins-listing');
$(plugins).each(function() {
var plugin = this;
var $plugin = elems.pluginItem({
id: plugin.id,
title: plugin.title,
desc: plugin.desc,
iconURL: 'plugins/' + plugin.id + '/icon.png'
});
var $browser = $('#browser .container');
$(plugins).each(function() {
var plugin = this;
var $plugin = elems.pluginItem({
id: plugin.id,
title: plugin.title,
desc: plugin.desc,
iconURL: 'plugins/' + plugin.id + '/icon.png'
});
var $browser = $('#browser .container');
$plugin.click(function() {
$browser.cloudBrowser('addPanel', {
title: plugin.title,
$parent: $('.panel:first'),
complete: function($panel) {
$panel.detailView({
name: 'Plugin details',
tabs: {
details: {
title: 'label.plugin.details',
fields: [
{
name: { label: 'label.name' }
},
{
desc: { label: 'label.description' },
externalLink: {
isExternalLink: true,
label: 'label.external.link'
$plugin.click(function() {
$browser.cloudBrowser('addPanel', {
title: plugin.title,
$parent: $('.panel:first'),
complete: function($panel) {
$panel.detailView({
name: 'Plugin details',
tabs: {
details: {
title: 'label.plugin.details',
fields: [{
name: {
label: 'label.name'
}
}, {
desc: {
label: 'label.description'
},
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' },
id: { label: 'label.id' }
}
],
dataProvider: function(args) {
args.response.success({ data: plugin });
}
}
}
});
}
});
});
});
$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
});
})
});
$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));

View File

@ -16,51 +16,52 @@
// under the License.
(function($, cloudStack) {
$(window).bind('cloudStack.ready', function() {
var $header = $('#header .controls');
var $projectSwitcher = $('<div>').addClass('project-switcher');
var $projectSelect = $('<select>').append(
$('<option>').attr('value', '-1').html(_l('Default view'))
);
var $label = $('<label>').html('Project:');
$(window).bind('cloudStack.ready', function() {
var $header = $('#header .controls');
var $projectSwitcher = $('<div>').addClass('project-switcher');
var $projectSelect = $('<select>').append(
$('<option>').attr('value', '-1').html(_l('Default view'))
);
var $label = $('<label>').html('Project:');
// Get project list
cloudStack.projects.dataProvider({
context: cloudStack.context,
response: {
success: function(args) {
var projects = args.data;
// Get project list
cloudStack.projects.dataProvider({
context: cloudStack.context,
response: {
success: function(args) {
var projects = args.data;
$(projects).map(function(index, project) {
var $option = $('<option>').val(_s(project.id));
$(projects).map(function(index, project) {
var $option = $('<option>').val(_s(project.id));
$option.html(_s(project.displaytext ? project.displaytext : project.name));
$option.appendTo($projectSelect);
});
},
error: function() {}
}
$option.html(_s(project.displaytext ? project.displaytext : project.name));
$option.appendTo($projectSelect);
});
},
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

View File

@ -15,200 +15,201 @@
// specific language governing permissions and limitations
// under the License.
(function(cloudStack, $) {
cloudStack.uiCustom.recurringSnapshots = function(args) {
var desc = args.desc;
var selects = args.selects;
var actions = args.actions;
var dataProvider = args.dataProvider;
cloudStack.uiCustom.recurringSnapshots = function(args) {
var desc = args.desc;
var selects = args.selects;
var actions = args.actions;
var dataProvider = args.dataProvider;
return function(args) {
var $snapshots = $('#template').find('.recurring-snapshots').clone();
var context = args.context;
return function(args) {
var $snapshots = $('#template').find('.recurring-snapshots').clone();
var context = args.context;
// Update labels
$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.weekly a').html(_l('label.weekly'));
$snapshots.find('.forms ul li.monthly a').html(_l('label.monthly'));
$snapshots.find('.field.timezone .name').html(_l('label.timezone'));
$snapshots.find('.field.time .name').html(_l('label.time'));
$snapshots.find('.field.time .value label').html(_l('label.minute.past.hour'));
$snapshots.find('.add-snapshot-action.add').html(_l('label.add'));
// Update labels
$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.weekly a').html(_l('label.weekly'));
$snapshots.find('.forms ul li.monthly a').html(_l('label.monthly'));
$snapshots.find('.field.timezone .name').html(_l('label.timezone'));
$snapshots.find('.field.time .name').html(_l('label.time'));
$snapshots.find('.field.time .value label').html(_l('label.minute.past.hour'));
$snapshots.find('.add-snapshot-action.add').html(_l('label.add'));
// Get description
$snapshots.find('.desc').html(_l(desc));
// Get description
$snapshots.find('.desc').html(_l(desc));
// Snapshot type tabs
$snapshots.find('.forms').tabs();
// Snapshot type tabs
$snapshots.find('.forms').tabs();
// Populate selects
$snapshots.find('form select').each(function() {
var $select = $(this);
var selectData = selects[$select.attr('name')];
// Populate selects
$snapshots.find('form select').each(function() {
var $select = $(this);
var selectData = selects[$select.attr('name')];
if (selectData) {
selectData({
response: {
success: function(args) {
$(args.data).each(function() {
var $option = $('<option>').appendTo($select);
if (selectData) {
selectData({
response: {
success: function(args) {
$(args.data).each(function() {
var $option = $('<option>').appendTo($select);
$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']
);
$option.val(this.id).html(_l(this.name));
});
}
}
});
}
});
refreshSnapshotTabs();
}
}
});
// Form validation
$snapshots.find('form').validate();
// 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();
});
// Add snapshot
$snapshots.find('.add-snapshot-action.add').click(function() {
var $form = $snapshots.find('form:visible');
$('div.overlay').fadeOut(function() {
$('div.overlay').remove();
});
}
}
]
}).closest('.ui-dialog').overlay();
if (!$form.valid()) return false;
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));

View File

@ -16,115 +16,117 @@
// under the License.
(function($, cloudStack) {
$(window).bind('cloudStack.ready', function() {
// Region switcher
var $regionList = $('<ul>');
$(window).bind('cloudStack.ready', function() {
// Region switcher
var $regionList = $('<ul>');
// Get region listing
var refreshRegions = function() {
$regionList.find('li').remove();
cloudStack.sections.regions.regionSelector.dataProvider({
response: {
success: function(args) {
var data = args.data;
var currentRegion = null;
$(data).each(function() {
var region = this;
var regionName = region.name;
var $li = $('<li>').append($('<span>').html(_s(region.name)));
// Get region listing
var refreshRegions = function() {
$regionList.find('li').remove();
cloudStack.sections.regions.regionSelector.dataProvider({
response: {
success: function(args) {
var data = args.data;
$li.data('region-data', region);
/* e.g.
region.endpoint == "http://localhost:8080/client/"
document.location.href == "http://localhost:8080/client/#"
var currentRegion = null;
$(data).each(function() {
var region = this;
var regionName = region.name;
var $li = $('<li>').append($('<span>').html(_s(region.name)));
$li.data('region-data', region);
/* e.g.
region.endpoint == "http://localhost:8080/client/"
document.location.href == "http://localhost:8080/client/#"
*/
if(document.location.href.indexOf(region.endpoint) != -1) {
currentRegion = region;
$li.addClass('active');
}
$regionList.append($li);
if (document.location.href.indexOf(region.endpoint) != -1) {
currentRegion = region;
$li.addClass('active');
}
$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) {
$regionSwitcherButton.find('.title').html(_s(currentRegion.name)).attr('title', _s(currentRegion.name));
}
else {
$regionSwitcherButton.find('.title').html('').attr('title', '');
}
}
}
});
};
};
$(window).bind('cloudStack.refreshRegions', refreshRegions);
$(window).bind('cloudStack.refreshRegions', refreshRegions);
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('&nbsp;'),
$('<span>').addClass('title').html('')
);
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('&nbsp;'),
$('<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 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;
}
});
};
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;
$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 ($li.size() && !$li.hasClass('active')) {
region = $li.data('region-data');
url = region.endpoint;
id = region.id;
if (id != '-1') {
switchRegion(url);
}
}
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();
});
$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));

View File

@ -15,59 +15,59 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
cloudStack.uiCustom.securityRules = function(args) {
var multiEdit = args;
cloudStack.uiCustom.securityRules = function(args) {
var multiEdit = args;
return function(args) {
var context = args.context;
var $multi = $('<div>').addClass('security-rules').multiEdit(
$.extend(true, {}, multiEdit, {
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;
return function(args) {
var context = args.context;
var $multi = $('<div>').addClass('security-rules').multiEdit(
$.extend(true, {}, multiEdit, {
context: context
})
)
.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);

View File

@ -15,157 +15,162 @@
// specific language governing permissions and limitations
// under the License.
(function(cloudStack, $) {
cloudStack.uiCustom.uploadVolume = function(args) {
var listView = args.listView;
var action = args.action;
cloudStack.uiCustom.uploadVolume = function(args) {
var listView = args.listView;
var action = args.action;
var validate = function($uploadVolume) {
if (!$uploadVolume.find('input[type=text]').val()) {
cloudStack.dialog.notice({ message: _l('message.specify.url')});
var validate = function($uploadVolume) {
if (!$uploadVolume.find('input[type=text]').val()) {
cloudStack.dialog.notice({
message: _l('message.specify.url')
});
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');
}
}
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;
};
$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
$listView.find('th.actions').html(_l('label.select'));
$urlField.append($urlLabel, $urlInput);
$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(
topFields,
$('<div>').addClass('desc').html(_l('label.select.instance.to.attach.volume.to') + ':'),
$('<div>').addClass('listView-container').append(
vmList({ listView: listView })
)
);
$uploadVolume.dialog({
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;
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');
var complete = args.complete;
var $loading = $('<div>').addClass('loading-overlay');
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');
}
}
}
}
};
$loading.appendTo($uploadVolume);
action({
data: cloudStack.serializeForm($uploadVolume.find('form')),
context: $.extend(true, {}, context, {
instances: [
$uploadVolume.find('tr.multi-edit-selected').data('json-obj')
]
}),
response: {
success: function(args) {
$('.ui-dialog').fadeOut(function() {
$('.ui-dialog').remove();
$(window).trigger('cloudStack.fullRefresh');
});
$('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();
$listView = $('<div>').listView(instances);
// Change action label
$listView.find('th.actions').html(_l('label.select'));
return $listView;
};
$uploadVolume.append(
topFields,
$('<div>').addClass('desc').html(_l('label.select.instance.to.attach.volume.to') + ':'),
$('<div>').addClass('listView-container').append(
vmList({
listView: listView
})
)
);
$uploadVolume.dialog({
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;
var $loading = $('<div>').addClass('loading-overlay');
$loading.appendTo($uploadVolume);
action({
data: cloudStack.serializeForm($uploadVolume.find('form')),
context: $.extend(true, {}, context, {
instances: [
$uploadVolume.find('tr.multi-edit-selected').data('json-obj')
]
}),
response: {
success: function(args) {
$('.ui-dialog').fadeOut(function() {
$('.ui-dialog').remove();
$(window).trigger('cloudStack.fullRefresh');
});
$('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));

File diff suppressed because it is too large Load Diff

View File

@ -15,412 +15,440 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
/**
* Zone details chart
*/
cloudStack.uiCustom.systemChart = function(chartID) {
/**
* Make view all button
* Zone details chart
*/
var viewAllButton = function(args) {
var $viewAll = $('<div>').addClass('button view-all');
var $label = $('<span>').addClass('view-all-label').html(args.label ? args.label : 'View all');
var $browser = args.$browser;
var action = args.action;
// Launch a list view
//var $multiple-click=$viewAll.data('multiple-click',false);
$viewAll.click(function() {
if ($viewAll.data('multiple-click')) return false;
//@pranav-handling the multiple clicks by using a flag variable
$viewAll.data('multiple-click', true);
$browser.cloudBrowser('addPanel', {
title: args.title,
maximizeIfSelected: true,
complete: function($newPanel) {
$viewAll.data('multiple-click', false);
action({ $panel: $newPanel });
}
});
});
cloudStack.uiCustom.systemChart = function(chartID) {
/**
* Make view all button
*/
var viewAllButton = function(args) {
var $viewAll = $('<div>').addClass('button view-all');
var $label = $('<span>').addClass('view-all-label').html(args.label ? args.label : 'View all');
var $browser = args.$browser;
var action = args.action;
// Launch a list view
//var $multiple-click=$viewAll.data('multiple-click',false);
$viewAll.click(function() {
if ($viewAll.data('multiple-click')) return false;
//@pranav-handling the multiple clicks by using a flag variable
$viewAll.data('multiple-click', true);
$browser.cloudBrowser('addPanel', {
title: args.title,
maximizeIfSelected: true,
complete: function($newPanel) {
$viewAll.data('multiple-click', false);
action({
$panel: $newPanel
});
}
});
});
$viewAll.append($label);
$viewAll.append($label);
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)
}
}
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];
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)
}
}
$elem.listView($.extend(true, {}, listView, {
context: context
}));
};
},
var validTrafficTypes = $.map(args.data, function(trafficType) {
return trafficType.name.toLowerCase();
});
providerListView: function(context) {
return function(args) {
var $elem = args.$panel;
var listViewArgs = cloudStack.sections.system.naas.providerListView;
// 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
}
}
$elem.listView({
context: context,
listView: listViewArgs
});
};
},
// 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
}));
/**
* 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;
$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);
}
$elem.detailView($.extend(true, {}, detailViewArgs, {
$browser: $('#browser .container'),
context: context
}));
};
}
});
};
// Get network data
networkDataProvider({
context: context,
response: {
success: function(args) {
var data = args.data;
var actionFilter = args.actionFilter;
/**
* Chart generators
*/
var charts = {
/**
* Compute tab
*/
compute: function(args) {
var $chart = $('<div>');
var $browser = $('#browser .container');
var context = args.context;
$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');
// Resource items
var computeResources = {
zone: {
label: 'Zone'
},
renderChart({
$chart: $chart,
data: args.context.physicalNetworks[0]
});
return $chart;
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)
}
}
}
}
})
});
$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);
$container.append($top, $stats.append($chartItems));
$chart.append($container);
var $loading = $('<div>').addClass('loading-overlay').prependTo($chart);
return function(args) {
// Fix zone context naming
args.context.zones = args.context.physicalResources;
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);
var $chart = charts[chartID](args).addClass('system-chart').addClass(chartID);
$chartItems.append(
$item.append(
$name,
$value.append(
$content.append(
$allocatedValue,
' / ',
$totalValue
)
),
$chart.append($chartLine),
$percent.append($percentValue, '%')
)
);
});
}
}
});
return $chart;
}
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);

View File

@ -16,24 +16,23 @@
// under the License.
(function($, cloudStack) {
$(window).bind('cloudStack.ready', function() {
var $header = $('#header .controls');
var $zoneFilter = $('<div>').addClass('zone-filter');
var $zoneTypeSelect = $('<select>').append(
$('<option>').attr('value', '').html(_l('All zones')),
$('<option>').attr('value', 'Basic').html(_l('Basic')),
$('<option>').attr('value', 'Advanced').html(_l('Advanced'))
);
var $label = $('<label>').html('Zone type:');
$(window).bind('cloudStack.ready', function() {
var $header = $('#header .controls');
var $zoneFilter = $('<div>').addClass('zone-filter');
var $zoneTypeSelect = $('<select>').append(
$('<option>').attr('value', '').html(_l('All zones')),
$('<option>').attr('value', 'Basic').html(_l('Basic')),
$('<option>').attr('value', 'Advanced').html(_l('Advanced'))
);
var $label = $('<label>').html('Zone type:');
$zoneFilter.append($label, $zoneTypeSelect);
$zoneFilter.insertAfter($header.find('.project-switcher'));
$zoneTypeSelect.change(function() {
cloudStack.context.zoneType = $zoneTypeSelect.val();
$zoneFilter.append($label, $zoneTypeSelect);
$zoneFilter.insertAfter($header.find('.project-switcher'));
$zoneTypeSelect.change(function() {
cloudStack.context.zoneType = $zoneTypeSelect.val();
// Go to default/start page (dashboard)
$('#breadcrumbs .home').click();
// Go to default/start page (dashboard)
$('#breadcrumbs .home').click();
});
});
});
}(jQuery, cloudStack));
}(jQuery, cloudStack));

File diff suppressed because it is too large Load Diff

View File

@ -15,443 +15,462 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
$.extend(cloudStack, {
ui: {
widgets: {} // Defines API methods for UI widgets
},
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('&nbsp;'))
.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;
$.extend(cloudStack, {
ui: {
widgets: {} // Defines API methods for UI widgets
},
uiCustom: {}
});
// Special classes for first and last items
$navList.find('li:first').addClass('first');
$navList.find('li:last').addClass('last');
/**
* 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;
return $navList;
};
/**
* 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('&nbsp;')
)
)
.append(
// Project View
$('<div>').addClass('select project-view')
.html(_l('label.project.view'))
.prepend(
$('<span>').addClass('icon').html('&nbsp;')
)
)
.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">&nbsp;</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();
}
$.each(args.sections, function(sectionID, args) {
if (preFilter && $.inArray(sectionID, preFilter) == -1) {
if (!(args.preFilter && args.preFilter())) {
return true;
}
}
}).closest('.ui-dialog').overlay();
return false;
var $li = $('<li>')
.addClass('navigation-item')
.addClass(sectionID)
.append($('<span>').addClass('icon').html('&nbsp;'))
.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
$container.find('#browser div.container').cloudBrowser();
$container.find('#navigation li')
.filter(function() {
return $(this).hasClass(args.home);
})
.click();
// Special classes for first and last items
$navList.find('li:first').addClass('first');
$navList.find('li:last').addClass('last');
// Validation
$.extend($.validator.messages, { required: _l('label.required') });
return $navList;
};
$.validator.addMethod(
"disallowSpecialCharacters",
function(value, element) {
return (value.indexOf("<") == -1 && value.indexOf(">") == -1);
},
jQuery.format("Disallowed characters: <, >")
);
/**
* 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];
// Check for pending project invitations
if (args.projects) {
args.projects.invitationCheck({
context: cloudStack.context,
response: {
success: function(args) {
if (!args.data.length) return;
data.$browser = $browser;
$navItem.siblings().removeClass('active');
$navItem.addClass('active');
var projectList = $.map(args.data, function(invitation) {
return '<li>' + invitation.project + '</li>';
}).join('');
// 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;
cloudStack.dialog.notice({
message: _l('message.pending.projects.1') +
'<ul>' + projectList + '</ul>' +
'<p>' + _l('message.pending.projects.2') + '</p>'
// 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('&nbsp;')
)
)
.append(
// Project View
$('<div>').addClass('select project-view')
.html(_l('label.project.view'))
.prepend(
$('<span>').addClass('icon').html('&nbsp;')
)
)
.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">&nbsp;</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
if (!args.hasLogo) $('#header, #header .controls').addClass('nologo');
$(window).trigger('cloudStack.ready');
$.fn.cloudStack = function(args) {
var $container = $('<div>')
.attr({
id: 'container',
'cloudStack-container': true
})
.data('cloudStack-args', args)
.appendTo(this);
var context = args.context;
return this;
};
// Create pageElems
$.each(pageElems, function(id, fn) {
var $elem = $('<div>').attr({
id: id
});
// 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;
$(fn(args)).each(function() {
$elem.append($(this));
});
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')
$elem.appendTo($container);
});
return false;
}
// User options
var $options = $('<div>').attr({
id: 'user-options'
})
.appendTo($('#header'));
// Home breadcrumb
if ($target.is('#breadcrumbs div.home')) {
showSection(args.home, args, $browser);
return false;
}
$(['label.logout', 'label.help', 'label.about']).each(function() {
var $link = $('<a>')
.attr({
href: '#'
})
.html(_l(this.toString()))
.appendTo($options);
// User options
if ($target.closest('#user div.icon.options').size()) {
$('#user-options').toggle();
if (this == 'label.help') {
$link.click(function() {
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.cloudStack ? window.cloudStack : window.cloudStack = {});
window.cloudStack ? window.cloudStack : window.cloudStack = {});

File diff suppressed because it is too large Load Diff

View File

@ -15,46 +15,48 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
cloudStack.ui.event = {
// Attach element to specific event type
elem: function(widget, elem, $elem, extraData) {
// Setup DOM metadata
var data = { cloudStack: {} };
data.cloudStack[widget] = {
elem: elem
};
if (extraData) $.extend(data.cloudStack[widget], extraData);
cloudStack.ui.event = {
// Attach element to specific event type
elem: function(widget, elem, $elem, extraData) {
// Setup DOM metadata
var data = {
cloudStack: {}
};
data.cloudStack[widget] = {
elem: elem
};
if (extraData) $.extend(data.cloudStack[widget], extraData);
return $elem
.addClass('cloudStack-elem')
.addClass(widget)
.data(data);
},
return $elem
.addClass('cloudStack-elem')
.addClass(widget)
.data(data);
},
// Create widget-based event
bind: function(widget, events) {
return function(event) {
var $target = $(event.target);
var $widget, $elem;
var data, elem;
// Create widget-based event
bind: function(widget, events) {
return function(event) {
var $target = $(event.target);
var $widget, $elem;
var data, elem;
$elem = $target.closest('.cloudStack-elem.' + widget);
if (!$elem.size())
return true;
$elem = $target.closest('.cloudStack-elem.' + widget);
if (!$elem.size())
return true;
$widget = $('.cloudStack-widget.' + widget);
data = $elem.data('cloudStack')[widget];
elem = data.elem;
$widget = $('.cloudStack-widget.' + widget);
data = $elem.data('cloudStack')[widget];
elem = data.elem;
events[elem]($elem, $widget, data);
events[elem]($elem, $widget, data);
return false;
};
},
return false;
};
},
// Trigger CloudStack UI event (cloudStack.*)
call: function(eventName, data) {
$(window).trigger('cloudStack.' + eventName, data);
}
};
// Trigger CloudStack UI event (cloudStack.*)
call: function(eventName, data) {
$(window).trigger('cloudStack.' + eventName, data);
}
};
})(jQuery, cloudStack);

View File

@ -15,113 +15,110 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
// General utils
cloudStack.serializeForm = function($form, options) {
if (!options) options = {};
// General utils
cloudStack.serializeForm = function($form, options) {
if (!options) options = {};
var data = {};
var data = {};
$($form.serializeArray()).each(function() {
var dataItem = data[this.name];
var value = _s(this.value.toString());
$($form.serializeArray()).each(function() {
var dataItem = data[this.name];
var value = _s(this.value.toString());
if (options.escapeSlashes) {
value = value.replace(/\//g, '__forwardSlash__');
}
if (options.escapeSlashes) {
value = value.replace(/\//g, '__forwardSlash__');
}
if (!dataItem) {
data[this.name] = value;
} else if (dataItem && !$.isArray(dataItem)) {
data[this.name] = [dataItem, value];
} else if($.isArray(dataItem)){
dataItem.push(value);
}
});
if (!dataItem) {
data[this.name] = value;
} else if (dataItem && !$.isArray(dataItem)) {
data[this.name] = [dataItem, value];
} else if ($.isArray(dataItem)) {
dataItem.push(value);
}
});
return data;
};
return data;
};
// Even/odd row handling
cloudStack.evenOdd = function($container, itemSelector, args) {
var even = false;
// Even/odd row handling
cloudStack.evenOdd = function($container, itemSelector, args) {
var even = false;
$container.find(itemSelector).each(function() {
var $elem = $(this);
$container.find(itemSelector).each(function() {
var $elem = $(this);
if (even) {
even = false;
args.odd($elem);
} else {
even = true;
args.even($elem);
}
});
};
if (even) {
even = false;
args.odd($elem);
} else {
even = true;
args.even($elem);
}
});
};
/**
* Localization -- shortcut _l
*
* Takes string and runs through localization function -- if no code
* exists or function isn't present, return string as-is
*/
cloudStack.localize = window._l = function(str) {
var localized = cloudStack.localizationFn ?
cloudStack.localizationFn(str) : null;
/**
* Localization -- shortcut _l
*
* Takes string and runs through localization function -- if no code
* exists or function isn't present, return string as-is
*/
cloudStack.localize = window._l = function(str) {
var localized = cloudStack.localizationFn ?
cloudStack.localizationFn(str) : null;
return localized ? localized : str;
};
return localized ? localized : str;
};
/**
* Sanitize user input (HTML Encoding) -- shortcut _s
*
* Strip unwanted characters from user-based input
*/
cloudStack.sanitize = window._s = function(value) {
if(typeof(value) == "number") {
//alert("number does not need to be sanitized. Only string needs to be sanitized.");
return value;
}
else if(typeof(value) == "boolean") {
//alert("boolean does not need to be sanitized. Only string needs to be sanitized.");
return value;
}
else if(typeof(value) == "object") {
//alert("object cant not be sanitized. Only string can be sanitized.");
return value;
}
else if(typeof(value) == null || typeof(value) == "undefined") {
return '';
}
/**
* Sanitize user input (HTML Encoding) -- shortcut _s
*
* Strip unwanted characters from user-based input
*/
cloudStack.sanitize = window._s = function(value) {
if (typeof(value) == "number") {
//alert("number does not need to be sanitized. Only string needs to be sanitized.");
return value;
} else if (typeof(value) == "boolean") {
//alert("boolean does not need to be sanitized. Only string needs to be sanitized.");
return value;
} else if (typeof(value) == "object") {
//alert("object cant not be sanitized. Only string can be sanitized.");
return value;
} else if (typeof(value) == null || typeof(value) == "undefined") {
return '';
}
var sanitized = value
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
var sanitized = value
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
return sanitized;
};
return sanitized;
};
/**
* Reverse sanitization (HTML Decoding)
*/
cloudStack.sanitizeReverse = function(value) {
var reversedValue = value
.replace(/&amp;/g, "&")
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">");
/**
* Reverse sanitization (HTML Decoding)
*/
cloudStack.sanitizeReverse = function(value) {
var reversedValue = value
.replace(/&amp;/g, "&")
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">");
return reversedValue;
};
return reversedValue;
};
/**
* If the str.length is > maxLen,
* then concatenate and add '...' to the end of the string
*/
cloudStack.concat = function(str, maxLen) {
if (str.length > maxLen) {
return str.substr(0, maxLen) + '...';
} else {
return str;
}
};
/**
* If the str.length is > maxLen,
* then concatenate and add '...' to the end of the string
*/
cloudStack.concat = function(str, maxLen) {
if (str.length > maxLen) {
return str.substr(0, maxLen) + '...';
} else {
return str;
}
};
})(jQuery, cloudStack);

View File

@ -15,418 +15,427 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
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
}
);
},
cloudStack.ui.widgets.browser = {};
/**
* Get breadcrumbs matching specified panels
* Breadcrumb-related functions
*/
filter: function($panels) {
var $breadcrumbs = $('#breadcrumbs ul li');
var $result = $([]);
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
}
);
},
$panels.each(function() {
var $panel = $(this);
/**
* Get breadcrumbs matching specified panels
*/
filter: function($panels) {
var $breadcrumbs = $('#breadcrumbs ul li');
var $result = $([]);
$.merge(
$result,
$.merge(
$breadcrumbs.filter(function() {
return $(this).index('#breadcrumbs ul li') == $panel.index();
}),
$panels.each(function() {
var $panel = $(this);
// Also include ends
$breadcrumbs.siblings('div.end').filter(function() {
return $(this).index('div.end') == $panel.index() + 1;
})
)
);
});
$.merge(
$result,
$.merge(
$breadcrumbs.filter(function() {
return $(this).index('#breadcrumbs ul li') == $panel.index();
}),
return $result;
}
};
/**
* 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();
// Also include ends
$breadcrumbs.siblings('div.end').filter(function() {
return $(this).index('div.end') == $panel.index() + 1;
})
)
);
});
if ($panel.is(':visible') && args.complete) args.complete($panel);
}
});
};
return $panel;
},
return $result;
}
};
/**
* Clear all panels
* Container-related functions
*/
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();
}
});
var _container = cloudStack.ui.widgets.browser.container = {
/**
* Get all panels from container
*/
panels: function($container) {
return $container.find('div.panel');
}
};
$('#breadcrumbs li').live('click', cloudStack.ui.event.bind(
'cloudBrowser',
{
'breadcrumb': function($target, $browser, data) {
/**
* 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;
if ($ ('#browser').hasClass('panel-highlight')) {
return false;
}
return width;
},
$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();
/**
* 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;
},
// 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');
/**
* Get the top panel z-index, for proper stacking
*/
topIndex: function($container) {
var base = 50; // Minimum z-index
// Setup breadcrumbs
$targetBreadcrumb.each(function() {
$(this).data('breadcrumb-original-zindex', $(this).zIndex());
});
$targetBreadcrumb.zIndex(10001);
$hiddenPanels.hide();
}, 1000));
}
}
));
return Math.max.apply(
null,
$.map(
$container.find('div.panel'),
function(elem) {
return parseInt($(elem).css('z-index')) || base;
}
)
) + 1;
},
$('#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);
/**
* State when panel is outside container
*/
initialState: function($container) {
return {
left: $container.width()
};
},
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();
}
}
));
/**
* 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 $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);

View File

@ -15,264 +15,264 @@
// specific language governing permissions and limitations
// under the License.
(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) {
var leftBound = $elem.offset().left + $elem.width() / 1.2;
$.fn.dataTable = function(method, options) {
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;
/**
* Handles actual resizing of table headers
*/
var resizeDragEvent = function(event) {
var $elem = $(this);
return posX > leftBound;
};
if (event.type == 'mousedown') {
$elem.addClass('dragging');
/**
* Handles actual resizing of table headers
*/
var resizeDragEvent = function(event) {
var $elem = $(this);
return false;
} else if (event.type == 'mouseup') {
$table.find('th').removeClass('dragging');
if (event.type == 'mousedown') {
$elem.addClass('dragging');
return false;
}
return false;
} else if (event.type == 'mouseup') {
$table.find('th').removeClass('dragging');
var isDraggable = $elem.hasClass('dragging');
return false;
}
if (!isDraggable) {
return false;
}
var isDraggable = $elem.hasClass('dragging');
var columnIndex = $elem.index();
if (!isDraggable) {
return false;
}
// Get all TDs from column
var columnCells = [];
$table.find('tbody tr:first').each(function() {
var targetCell = $($(this).find('td')[columnIndex]);
var columnIndex = $elem.index();
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;
var targetWidth = event.pageX - $elem.offset().left + tolerance;
$(columnCells).each(function() {
$(this).css({
width: targetWidth
});
});
columnCells.push(targetCell);
});
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() {
var $mainContainer = $('<div>')
.addClass('data-table')
.appendTo($table.parent())
.append(
$table.remove()
return true;
};
var splitTable = function() {
var $mainContainer = $('<div>')
.addClass('data-table')
.appendTo($table.parent())
.append(
$table.remove()
);
$table = $mainContainer;
var $theadContainer = $('<div>').addClass('fixed-header').prependTo($table);
var $theadTable = $('<table>').appendTo($theadContainer).attr('nowrap', 'nowrap');
var $thead = $table.find('thead').remove().appendTo($theadTable);
$table = $mainContainer;
var $theadContainer = $('<div>').addClass('fixed-header').prependTo($table);
var $theadTable = $('<table>').appendTo($theadContainer).attr('nowrap', 'nowrap');
var $thead = $table.find('thead').remove().appendTo($theadTable);
return $thead;
};
return $thead;
};
/**
* Event to set resizable appearance on hover
*/
var hoverResizableEvent = function(event) {
var $elem = $(this);
var posX = event.pageX;
/**
* Event to set resizable appearance on hover
*/
var hoverResizableEvent = function(event) {
var $elem = $(this);
var posX = event.pageX;
if (event.type != 'mouseout' && withinResizeBounds($elem, posX)) {
$elem.addClass('resizable');
} else {
$elem.removeClass('resizable');
}
if (event.type != 'mouseout' && withinResizeBounds($elem, posX)) {
$elem.addClass('resizable');
} else {
$elem.removeClass('resizable');
}
return true;
};
return true;
};
/**
* Make row at specified index selected or unselected
*
* @param rowIndex Row's index, starting at 1
*/
var toggleSelectRow = function(rowIndex) {
var $rows = $table.find('tbody tr');
var $row = $($rows[rowIndex]);
/**
* Make row at specified index selected or unselected
*
* @param rowIndex Row's index, starting at 1
*/
var toggleSelectRow = function(rowIndex) {
var $rows = $table.find('tbody tr');
var $row = $($rows[rowIndex]);
$row.siblings().removeClass('selected');
return $row.addClass('selected');
};
$row.siblings().removeClass('selected');
return $row.addClass('selected');
};
var computeEvenOddRows = function() {
var currentRowType = 'even';
$table.find('tbody tr').each(function() {
var $row = $(this);
var computeEvenOddRows = function() {
var currentRowType = 'even';
$table.find('tbody tr').each(function() {
var $row = $(this);
$row.removeClass('even').removeClass('odd');
$row.addClass(currentRowType);
$row.removeClass('even').removeClass('odd');
$row.addClass(currentRowType);
if (currentRowType == 'even') currentRowType = 'odd';
else currentRowType = 'even';
});
};
if (currentRowType == 'even') currentRowType = 'odd';
else currentRowType = 'even';
});
};
/**
* Sort table by column
*
* @param columnIndex Index of column (starting at 0) to sort by
*/
var sortTable = function(columnIndex) {
return false;
var direction = 'asc';
/**
* Sort table by column
*
* @param columnIndex Index of column (starting at 0) to sort by
*/
var sortTable = function(columnIndex) {
return false;
var direction = 'asc';
if ($table.find('thead th').hasClass('sorted ' + direction)) {
direction = 'desc';
}
if ($table.find('thead th').hasClass('sorted ' + direction)) {
direction = 'desc';
}
$table.find('thead th').removeClass('sorted desc asc');
$($table.find('thead th')[columnIndex]).addClass('sorted').addClass(direction);
$table.find('thead th').removeClass('sorted desc asc');
$($table.find('thead th')[columnIndex]).addClass('sorted').addClass(direction);
var $elems = $table.find('tbody td').filter(function() {
return $(this).index() == columnIndex;
});
var $elems = $table.find('tbody td').filter(function() {
return $(this).index() == columnIndex;
});
var sortData = [];
$elems.each(function() {
sortData.push($(this).html());
sortData.sort();
var sortData = [];
$elems.each(function() {
sortData.push($(this).html());
sortData.sort();
if (direction == 'asc') {
sortData.reverse();
}
});
if (direction == 'asc') {
sortData.reverse();
}
});
$(sortData).each(function() {
var sortKey = this;
var $targetCell = $elems.filter(function() {
return $(this).html() == sortKey;
});
var $targetContainer = $targetCell.parent();
$(sortData).each(function() {
var sortKey = this;
var $targetCell = $elems.filter(function() {
return $(this).html() == sortKey;
});
var $targetContainer = $targetCell.parent();
$targetContainer.remove().appendTo($table.find('tbody'));
});
$targetContainer.remove().appendTo($table.find('tbody'));
});
computeEvenOddRows();
};
computeEvenOddRows();
};
var resizeHeaders = function() {
var $thead = $table.closest('div.data-table').find('thead');
var $tbody = $table.find('tbody');
var $ths = $thead.find('th');
var $tds = $tbody.find('tr:first td');
var resizeHeaders = function() {
var $thead = $table.closest('div.data-table').find('thead');
var $tbody = $table.find('tbody');
var $ths = $thead.find('th');
var $tds = $tbody.find('tr:first td');
if ($ths.size() > $tds.size()) {
$ths.width(
$table.width() / $ths.size()
);
return false;
}
if ($ths.size() > $tds.size()) {
$ths.width(
$table.width() / $ths.size()
);
return false;
}
$ths.each(function() {
var $th = $(this);
$ths.each(function() {
var $th = $(this);
var $td = $tds.filter(function() {
return $(this).index() == $th.index();
});
var $td = $tds.filter(function() {
return $(this).index() == $th.index();
});
$th.width($td.width());
$th.width($td.width());
return true;
});
return true;
});
return $ths;
};
return $ths;
};
var methods = {
removeRow: function(rowIndex) {
var $row = $($table.find('tbody tr')[rowIndex]);
var methods = {
removeRow: function(rowIndex) {
var $row = $($table.find('tbody tr')[rowIndex]);
$row.fadeOut(function() {
$row.remove();
computeEvenOddRows();
});
$row.fadeOut(function() {
$row.remove();
computeEvenOddRows();
});
return $row;
},
return $row;
},
refresh: function() {
resizeHeaders();
computeEvenOddRows();
},
refresh: function() {
resizeHeaders();
computeEvenOddRows();
},
selectRow: function(rowIndex) {
var $row = $($table.find('tbody tr')[rowIndex]);
selectRow: function(rowIndex) {
var $row = $($table.find('tbody tr')[rowIndex]);
$row.siblings().removeClass('selected');
$row.addClass('selected');
}
};
$row.siblings().removeClass('selected');
$row.addClass('selected');
}
};
var init = function() {
var noSelect = options && options.noSelect == true ? true : false;
if (!$table.closest('div.data-table').size() && !$table.hasClass('no-split')) {
splitTable();
$table.find('tbody').closest('table').addClass('body');
}
var init = function() {
var noSelect = options && options.noSelect == true ? true : false;
if (!$table.closest('div.data-table').size() && !$table.hasClass('no-split')) {
splitTable();
$table.find('tbody').closest('table').addClass('body');
}
$table.find('th').bind('mousemove mouseout', hoverResizableEvent);
$table.find('th').bind('mousedown mousemove mouseup mouseout', resizeDragEvent);
$table.find('th').bind('click', function(event) {
if ($(this).hasClass('resizable')) {
return false;
$table.find('th').bind('mousemove mouseout', hoverResizableEvent);
$table.find('th').bind('mousedown mousemove mouseup mouseout', resizeDragEvent);
$table.find('th').bind('click', function(event) {
if ($(this).hasClass('resizable')) {
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 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();
return $table;
};
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));

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

View File

@ -15,356 +15,367 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack, _l) {
/**
* Notification handling
*/
var notifications = {
activeTasks: [],
cornerAlert: function(args, options) {
if (!options) options = {};
/**
* Notification handling
*/
var notifications = {
activeTasks: [],
cornerAlert: function(args, options) {
if (!options) options = {};
var $container = $('#container'); // Put in main container box
var $cornerAlert = $('<div>').addClass('notification corner-alert')
.hide()
.appendTo($container)
.append(
$('<div>').addClass('title').append(
$('<span>').html(
options.error ? options.error : _l('label.task.completed')
)
)
)
.append(
$('<div>').addClass('message')
var $container = $('#container'); // Put in main container box
var $cornerAlert = $('<div>').addClass('notification corner-alert')
.hide()
.appendTo($container)
.append(
$('<span>').html(_l(args.message))
)
);
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))
$('<div>').addClass('title').append(
$('<span>').html(
options.error ? options.error : _l('label.task.completed')
)
)
)
.append(
$('<div>').addClass('remove')
.append(
$('<div>').addClass('message')
.append(
$('<span>').html(_l(args.message))
)
);
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) });
if (options.error) {
$cornerAlert.addClass('error');
}
clearInterval(pollTimer);
notifications.activeTasks.pop(pollTimer);
notifications.cornerAlert({ message: $item.html() }, {
error: _l('label.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(
$('<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();
}
});
}, args.interval);
notifications.activeTasks.push(pollTimer);
if (!$attachTo.hasClass('notifications')) $attachTo.addClass('notifications');
$attachTo.data('notifications-popup', $popup);
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);
}
});
},
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);
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()
});
}
})
.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);
else
init();
/**
* 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;
return this;
};
var init = function() {
$popup = notifications.popup.create($attachTo).appendTo('html body');
};
/**
* Notifications UI helpers
*/
cloudStack.ui.notifications = {
add: function(notification, success, successArgs, error, errorArgs) {
if (!notification) {
success(successArgs);
if (method == 'add')
notifications.add(args, $attachTo.data('notifications-popup'), $total);
else
init();
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) {
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;
return false;
};
notification.poll({
_custom: args._custom,
complete: function(args) {
success($.extend(successArgs, args));
complete(args);
},
error: function(args) {
error($.extend(errorArgs, args));
notificationError(args);
}
});
}
});
}
var $notifications = $('div.notifications');
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
$(window).bind('cloudStack.addNotification', function(event, data) {
$('.notifications').notifications('add', data);
});
notification.poll({
_custom: args._custom,
complete: function(args) {
success($.extend(successArgs, args));
complete(args);
},
error: function(args) {
error($.extend(errorArgs, args));
notificationError(args);
}
});
}
});
}
$(document).click(function(event) {
var $target = $(event.target);
var $attachTo, $popup;
return true;
}
};
// Notifications header area
if ($target.closest('.notifications').size()) {
$attachTo = $target.closest('.notifications');
$popup = $attachTo.data('notifications-popup');
notifications.popup.show($popup, $attachTo);
// Setup notification listener -- accepts same args as
$(window).bind('cloudStack.addNotification', function(event, data) {
$('.notifications').notifications('add', data);
});
return false;
}
$(document).click(function(event) {
var $target = $(event.target);
var $attachTo, $popup;
// Notification item
if ($target.is('.notification-box li span')) {
var $li = $target.closest('.notification-box li');
// Notifications header area
if ($target.closest('.notifications').size()) {
$attachTo = $target.closest('.notifications');
$popup = $attachTo.data('notifications-popup');
notifications.popup.show($popup, $attachTo);
$('#navigation ul li').filter(function() {
return $(this).hasClass($li.data('notification-section'));
}).click();
$('div.overlay').click();
return false;
}
return false;
}
// Notification item
if ($target.is('.notification-box li span')) {
var $li = $target.closest('.notification-box li');
// Popup
if ($target.closest('div.notification-box').size()) {
$popup = $target.closest('div.notification-box');
$('#navigation ul li').filter(function() {
return $(this).hasClass($li.data('notification-section'));
}).click();
$('div.overlay').click();
// Clear list
if ($target.closest('.button.clear-list').size()) {
notifications.clear($popup);
}
return false;
}
// Remove instance item
else if ($target.hasClass('remove')) {
notifications.removeItem($popup, $target.closest('li'));
}
// Popup
if ($target.closest('div.notification-box').size()) {
$popup = $target.closest('div.notification-box');
// Close button
else if ($target.closest('.button.close')) {
$('div.overlay').click();
}
// Clear list
if ($target.closest('.button.clear-list').size()) {
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) {
var $popup = $('div.notification-box:visible');
return false;
}
if ($popup.size())
notifications.popup.reposition($popup, $popup.data('notifications-attach-to'));
});
return true;
});
$(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);

View File

@ -15,36 +15,36 @@
// specific language governing permissions and limitations
// under the License.
(function($) {
/**
* Create a dark overlay, for modal dialogs, etc.
*/
$.fn.overlay = function(args) {
var $topElem = this;
var $overlay = $('<div class="overlay">').hide().appendTo('html body').css({
position: 'absolute',
background: 'black',
opacity: 0.5,
width: '100%',
height: '100%',
top: $(window).scrollTop(),
left: 0,
zIndex: $topElem.css('z-index') - 1
}).show();
/**
* Create a dark overlay, for modal dialogs, etc.
*/
$.fn.overlay = function(args) {
var $topElem = this;
var $overlay = $('<div class="overlay">').hide().appendTo('html body').css({
position: 'absolute',
background: 'black',
opacity: 0.5,
width: '100%',
height: '100%',
top: $(window).scrollTop(),
left: 0,
zIndex: $topElem.css('z-index') - 1
}).show();
// Events
$overlay.click(function(event) {
if (!args || !args.closeAction) return false;
// Events
$overlay.click(function(event) {
if (!args || !args.closeAction) return false;
args.closeAction();
$overlay.fadeOut(function() {
$overlay.remove();
});
args.closeAction();
$overlay.fadeOut(function() {
$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);

View File

@ -16,220 +16,236 @@
// under the License.
(function($, cloudStack) {
var isFormValid = function($form) {
var key = $form.find('input[name=key]').val();
var value = $form.find('input[name=value]').val();
var isFormValid = function($form) {
var key = $form.find('input[name=key]').val();
var value = $form.find('input[name=value]').val();
if (!key || !value) {
cloudStack.dialog.notice({ message: 'Please specify a tag key and value' });
return false;
}
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();
}
}
if (!key || !value) {
cloudStack.dialog.notice({
message: 'Please specify a tag key and value'
});
// 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);
});
$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
$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 };
return true;
};
elems.tagItem(key + ' = ' + value, onRemoveItem, data).appendTo($tagArea);
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;
} :
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) {
$loading.remove();
$container.find('ul').html(message);
}
$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);
// 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));

View File

@ -14,151 +14,157 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
(function($,cloudStack) {
$.widget("cloudStack.toolTip", {
_init: function(args) {
var context = this.options.context;
var dataProvider = this.options.dataProvider;
var actions = this.options.actions;
var docID = this.options.docID;
var text = cloudStack.docs[docID].desc;
var $tooltip = $('<div>').addClass('tooltip-box');
var $text = $('<p>').html(text).appendTo($tooltip);
var $container = $('#cloudStack3-container');
(function($, cloudStack) {
$.widget("cloudStack.toolTip", {
_init: function(args) {
var context = this.options.context;
var dataProvider = this.options.dataProvider;
var actions = this.options.actions;
var docID = this.options.docID;
var text = cloudStack.docs[docID].desc;
var $tooltip = $('<div>').addClass('tooltip-box');
var $text = $('<p>').html(text).appendTo($tooltip);
var $container = $('#cloudStack3-container');
$tooltip.appendTo($container);
$tooltip.appendTo($container);
if (this.options.mode == 'hover'){
$(this.element).hover(hoverHandler,outHandler);
} else if (this.options.mode == 'focus'){
$(this.element).focus(hoverHandler);
$(this.element).blur(outHandler);
} else if (this.options.mode == 'manual'){}
if (this.options.mode == 'hover') {
$(this.element).hover(hoverHandler, outHandler);
} else if (this.options.mode == 'focus') {
$(this.element).focus(hoverHandler);
$(this.element).blur(outHandler);
} else if (this.options.mode == 'manual') {}
$(this.element).data('$tooltip', $tooltip);
$(this.element).data('$tooltip', $tooltip);
// Add arrow
$tooltip.append($('<div></div>').addClass('arrow'));
// Add arrow
$tooltip.append($('<div></div>').addClass('arrow'));
$tooltip.hide();
},
$tooltip.hide();
},
show: function(){
var o = this.options;
show: function() {
var o = this.options;
if(o.mode=='manual'){
prepare(this.element,o);
}
if (o.mode == 'manual') {
prepare(this.element, o);
}
$(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');
$(o.toolTip).show();
},
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)
});
}
},
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) {
//Call Hide method of the tooltip Widget,
//Hide method should play on any required animations
$.data(this, '$tooltip').hide();
};
},
fade: function(e, options) {
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;
function hoverHandler(event)
{
//Fetch Options
var o = $.data(this,'toolTip').options;
if (options.onShow) {
options.onShow.call(this, {
target: jObj
});
}
//Element who raised the event
var $this = $(this);
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'
});
//Helper functon for Positioning and Calling Callback function
prepare($this,o);
// Fix overlay
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);

View File

@ -15,130 +15,136 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack, _s) {
/**
* Make <ul> of tree items
*/
var makeTreeList = function(args) {
var $treeList = $('<ul>');
/**
* Make <ul> of tree items
*/
var makeTreeList = function(args) {
var $treeList = $('<ul>');
args.dataProvider({
context: $.extend(args.context, {
parentDomain: args.parent
}),
response: {
success: function(successArgs) {
$(successArgs.data).each(function() {
$('<li>')
.data('tree-view-item-id', this.id)
.data('tree-view-item-obj', this)
.append(
args.dataProvider({
context: $.extend(args.context, {
parentDomain: args.parent
}),
response: {
success: function(successArgs) {
$(successArgs.data).each(function() {
$('<li>')
.data('tree-view-item-id', this.id)
.data('tree-view-item-obj', this)
.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>')
.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>')
.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;
}
.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: $li.data('tree-view-item-obj'),
dataProvider: treeViewArgs.dataProvider
}).appendTo($li);
$li.addClass('expanded');
parent: null,
dataProvider: treeViewArgs.dataProvider,
context: args.context
}).appendTo($treeView);
return false;
}
setTimeout(function() {
$treeView.find('li:first div.name').click();
}, 100);
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') ] }
}));
}
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({
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
$(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;
});
if (actionName == 'destroy') {
$li.animate({
opacity: 0.5
});
$li.bind('click', function() {
return false;
});
}
});
if (actionName == 'destroy') {
$li.animate({ opacity: 0.5 });
$li.bind('click', function() { return false; });
}
});
return this;
};
return this;
};
})(jQuery, cloudStack, cloudStack.sanitize);

View File

@ -15,182 +15,185 @@
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
cloudStack.sections.vmsnapshots = {
title: 'label.vmsnapshot',
id: 'vmsnapshots',
listView: {
id: 'vmsnapshots',
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',
cloudStack.sections.vmsnapshots = {
title: 'label.vmsnapshot',
id: 'vmsnapshots',
listView: {
id: 'vmsnapshots',
isMaximized: true,
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'
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
}
},
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) {
$.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}
var apiCmd = "listVMSnapshot&listAll=true";
if (args.context != null) {
if ("instances" in args.context) {
apiCmd += "&virtualmachineid=" + args.context.instances[0].id;
}
);
}
});
},
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
$.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: {
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: {
poll: pollAsyncJobResult
},
dataProvider: function(args) {
$.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);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff