mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Format JS
This commit is contained in:
parent
dfa612d1fe
commit
ad69bc8da3
File diff suppressed because it is too large
Load Diff
@ -15,169 +15,193 @@
|
||||
// specific language governing permissions and limitations
|
||||
// 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
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -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
@ -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);
|
||||
|
||||
2026
ui/scripts/docs.js
2026
ui/scripts/docs.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1046
ui/scripts/events.js
1046
ui/scripts/events.js
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
@ -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
@ -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 = '¶m[' + index + ']';
|
||||
var name = this.toString();
|
||||
var value = data[name];
|
||||
|
||||
if (!value || $.inArray(name, notParams) > -1) return true;
|
||||
if (value == 'on') value = true;
|
||||
|
||||
stickyURLData += param + '.name=' + name + param + '.value=' + value;
|
||||
|
||||
index++;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: createURL('createLBStickinessPolicy' + stickyURLData),
|
||||
data: {
|
||||
lbruleid: lbRuleID,
|
||||
name: data.stickyName,
|
||||
methodname: data.methodname
|
||||
},
|
||||
success: function(json) {
|
||||
cloudStack.ui.notifications.add({
|
||||
desc: 'Add new LB sticky rule',
|
||||
section: 'Network',
|
||||
poll: pollAsyncJobResult,
|
||||
_custom: {
|
||||
jobId: json.createLBStickinessPolicy.jobid
|
||||
}
|
||||
},
|
||||
complete, {},
|
||||
error, {}
|
||||
);
|
||||
},
|
||||
error: function(json) {
|
||||
complete();
|
||||
cloudStack.dialog.notice({
|
||||
message: parseXMLHttpResponse(json)
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
'delete': function(stickyRuleID, complete, error) {
|
||||
$.ajax({
|
||||
url: createURL('deleteLBStickinessPolicy'),
|
||||
data: {
|
||||
id: stickyRuleID
|
||||
},
|
||||
success: function(json) {
|
||||
cloudStack.ui.notifications.add({
|
||||
desc: 'Remove previous LB sticky rule',
|
||||
section: 'Network',
|
||||
poll: pollAsyncJobResult,
|
||||
_custom: {
|
||||
jobId: json.deleteLBstickinessrruleresponse.jobid
|
||||
}
|
||||
},
|
||||
complete, {},
|
||||
error, {}
|
||||
);
|
||||
},
|
||||
error: function(json) {
|
||||
complete();
|
||||
cloudStack.dialog.notice({
|
||||
message: parseXMLHttpResponse(json)
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
recreate: function(stickyRuleID, lbRuleID, data, complete, error) {
|
||||
var addStickyPolicy = function() {
|
||||
cloudStack.lbStickyPolicy.actions.add(
|
||||
lbRuleID,
|
||||
data,
|
||||
complete,
|
||||
error
|
||||
);
|
||||
};
|
||||
|
||||
// Delete existing rule
|
||||
if (data.methodname !== 'None') {
|
||||
addStickyPolicy();
|
||||
} else {
|
||||
cloudStack.lbStickyPolicy.actions['delete'](stickyRuleID, complete, error);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
success({
|
||||
data: data
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
actions: {
|
||||
add: function(lbRuleID, data, complete, error) {
|
||||
var stickyURLData = '';
|
||||
var stickyParams = $.map(data, function(value, key) {
|
||||
return key;
|
||||
});
|
||||
|
||||
var notParams = ['methodname', 'stickyName'];
|
||||
|
||||
var index = 0;
|
||||
$(stickyParams).each(function() {
|
||||
var param = '¶m[' + index + ']';
|
||||
var name = this.toString();
|
||||
var value = data[name];
|
||||
|
||||
if (!value || $.inArray(name, notParams) > -1) return true;
|
||||
if (value == 'on') value = true;
|
||||
|
||||
stickyURLData += param + '.name=' + name + param + '.value=' + value;
|
||||
|
||||
index++;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: createURL('createLBStickinessPolicy' + stickyURLData),
|
||||
data: {
|
||||
lbruleid: lbRuleID,
|
||||
name: data.stickyName,
|
||||
methodname: data.methodname
|
||||
},
|
||||
success: function(json) {
|
||||
cloudStack.ui.notifications.add(
|
||||
{
|
||||
desc: 'Add new LB sticky rule',
|
||||
section: 'Network',
|
||||
poll: pollAsyncJobResult,
|
||||
_custom: {
|
||||
jobId: json.createLBStickinessPolicy.jobid
|
||||
}
|
||||
},
|
||||
complete, {},
|
||||
error, {}
|
||||
);
|
||||
},
|
||||
error: function(json) {
|
||||
complete();
|
||||
cloudStack.dialog.notice({ message: parseXMLHttpResponse(json) });
|
||||
}
|
||||
});
|
||||
},
|
||||
'delete': function(stickyRuleID, complete, error) {
|
||||
$.ajax({
|
||||
url: createURL('deleteLBStickinessPolicy'),
|
||||
data: {
|
||||
id: stickyRuleID
|
||||
},
|
||||
success: function(json) {
|
||||
cloudStack.ui.notifications.add(
|
||||
{
|
||||
desc: 'Remove previous LB sticky rule',
|
||||
section: 'Network',
|
||||
poll: pollAsyncJobResult,
|
||||
_custom: {
|
||||
jobId: json.deleteLBstickinessrruleresponse.jobid
|
||||
}
|
||||
},
|
||||
complete, {},
|
||||
error, {}
|
||||
);
|
||||
},
|
||||
error: function(json) {
|
||||
complete();
|
||||
cloudStack.dialog.notice({ message: parseXMLHttpResponse(json) });
|
||||
}
|
||||
});
|
||||
},
|
||||
recreate: function(stickyRuleID, lbRuleID, data, complete, error) {
|
||||
var addStickyPolicy = function() {
|
||||
cloudStack.lbStickyPolicy.actions.add(
|
||||
lbRuleID,
|
||||
data,
|
||||
complete,
|
||||
error
|
||||
);
|
||||
};
|
||||
|
||||
// Delete existing rule
|
||||
if (data.methodname !== 'None') {
|
||||
addStickyPolicy();
|
||||
} else {
|
||||
cloudStack.lbStickyPolicy.actions['delete'](stickyRuleID, complete, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}(jQuery, cloudStack));
|
||||
|
||||
10851
ui/scripts/network.js
10851
ui/scripts/network.js
File diff suppressed because it is too large
Load Diff
@ -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
30373
ui/scripts/system.js
30373
ui/scripts/system.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -15,159 +15,160 @@
|
||||
// specific language governing permissions and limitations
|
||||
// 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));
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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
@ -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));
|
||||
|
||||
@ -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(' '),
|
||||
$('<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(' '),
|
||||
$('<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));
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
@ -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);
|
||||
|
||||
@ -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
@ -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(' '))
|
||||
.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(' ')
|
||||
|
||||
|
||||
)
|
||||
)
|
||||
.append(
|
||||
// Project View
|
||||
$('<div>').addClass('select project-view')
|
||||
.html(_l('label.project.view'))
|
||||
.prepend(
|
||||
$('<span>').addClass('icon').html(' ')
|
||||
)
|
||||
)
|
||||
.click(function(event) {
|
||||
var $target = $(event.target);
|
||||
var $projectSwitcher = $(this);
|
||||
var $container = $('html body');
|
||||
var $navDisabled = $(
|
||||
$.map([
|
||||
'projects',
|
||||
'accounts',
|
||||
'domains',
|
||||
'system',
|
||||
'global-settings',
|
||||
'configuration'
|
||||
], function(id) {
|
||||
return '#navigation li.' + id;
|
||||
}).join(',')
|
||||
);
|
||||
|
||||
if ($target.closest('.select.project-view').size()) {
|
||||
$('#cloudStack3-container').addClass('project-view');
|
||||
$projectSwitcher.addClass('alt');
|
||||
$projectSwitcher.find('.select.project-view').addClass('active')
|
||||
.siblings().removeClass('active');
|
||||
|
||||
// Activate project view
|
||||
$navDisabled.hide();
|
||||
cloudStack.uiCustom.projects({
|
||||
$projectSelect: $projectSelect.hide().find('select')
|
||||
});
|
||||
} else {
|
||||
$navDisabled.show();
|
||||
$('#cloudStack3-container').removeClass('project-view');
|
||||
$projectSwitcher.removeClass('alt');
|
||||
$projectSelect.hide();
|
||||
$projectSwitcher.find('.select.default-view').addClass('active')
|
||||
.siblings().removeClass('active');
|
||||
|
||||
// Put project name in header
|
||||
$('.select.project-view').html(
|
||||
'<span class="icon"> </span>' + _l('label.project.view')
|
||||
).attr('title', '');
|
||||
|
||||
// Clear out project
|
||||
cloudStack.context.projects = null;
|
||||
}
|
||||
|
||||
$('#navigation li.dashboard').click();
|
||||
|
||||
return false;
|
||||
});
|
||||
var $projectSelect = $('<div>').addClass('view-switcher').hide()
|
||||
.append($('<select>'));
|
||||
|
||||
// User status area
|
||||
var userLabel = args.context.users[0].name ?
|
||||
args.context.users[0].name : args.context.users[0].login;
|
||||
var $userInfo = $('<div>').attr({ id: 'user' }).addClass('button')
|
||||
.append(
|
||||
$('<div>').addClass('name').html(
|
||||
args.context && args.context.users ?
|
||||
cloudStack.concat(userLabel, 14) : 'Invalid User'
|
||||
)
|
||||
)
|
||||
.append(
|
||||
$('<div>').addClass('icon options')
|
||||
.append(
|
||||
$('<div>').addClass('icon arrow')
|
||||
)
|
||||
);
|
||||
$userInfo.attr('title', userLabel);
|
||||
|
||||
return [
|
||||
$('<div>').addClass('logo'),
|
||||
$('<div>').addClass('controls')
|
||||
.append($notificationArea)
|
||||
.append($viewSwitcher)
|
||||
.append($projectSelect)
|
||||
.append($userInfo)
|
||||
];
|
||||
},
|
||||
|
||||
'main-area': function(args) {
|
||||
var $navigation = $('<div>').attr({ id: 'navigation' });
|
||||
var $browser = $('<div>').attr({ id: 'browser' })
|
||||
.append(
|
||||
// Home breadcrumb
|
||||
$('<div>').attr({ id: 'breadcrumbs' })
|
||||
.append($('<div>').addClass('home'))
|
||||
.append($('<div>').addClass('end'))
|
||||
)
|
||||
|
||||
.append(
|
||||
// Panel container
|
||||
$('<div>').addClass('container')
|
||||
);
|
||||
|
||||
makeNavigation(args).appendTo($navigation);
|
||||
|
||||
return [
|
||||
$navigation, $browser
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.cloudStack = function(args) {
|
||||
var $container = $('<div>')
|
||||
.attr({
|
||||
id: 'container',
|
||||
'cloudStack-container': true
|
||||
})
|
||||
.data('cloudStack-args', args)
|
||||
.appendTo(this);
|
||||
var context = args.context;
|
||||
|
||||
// Create pageElems
|
||||
$.each(pageElems, function(id, fn) {
|
||||
var $elem = $('<div>').attr({ id: id });
|
||||
|
||||
$(fn(args)).each(function() {
|
||||
$elem.append($(this));
|
||||
});
|
||||
|
||||
$elem.appendTo($container);
|
||||
});
|
||||
|
||||
// User options
|
||||
var $options = $('<div>').attr({ id: 'user-options' })
|
||||
.appendTo($('#header'));
|
||||
|
||||
$(['label.logout', 'label.help', 'label.about']).each(function() {
|
||||
var $link = $('<a>')
|
||||
.attr({ href: '#' })
|
||||
.html(_l(this.toString()))
|
||||
.appendTo($options);
|
||||
|
||||
if (this == 'label.help') {
|
||||
$link.click(function() {
|
||||
var helpURL = 'http://docs.cloud.com/CloudStack_Documentation';
|
||||
|
||||
window.open(helpURL, '_blank');
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
if (this == 'label.about') {
|
||||
$link.click(function() {
|
||||
var $logo = $('<div>').addClass('logo').html(_l('label.app.name')),
|
||||
$version = $('<div>').addClass('version').html(g_cloudstackversion),
|
||||
$about = $('<div>').addClass('about').append($logo).append($version);
|
||||
$about.dialog({
|
||||
modal: true,
|
||||
width: 300,
|
||||
title: _l('label.about.app'),
|
||||
closeOnEscape: false,
|
||||
dialogClass: 'dialog-about',
|
||||
buttons: {
|
||||
'Close': function() {
|
||||
$( this ).dialog( "close" );
|
||||
$(':ui-dialog, .overlay').remove();
|
||||
}
|
||||
$.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(' '))
|
||||
.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(' ')
|
||||
|
||||
|
||||
)
|
||||
)
|
||||
.append(
|
||||
// Project View
|
||||
$('<div>').addClass('select project-view')
|
||||
.html(_l('label.project.view'))
|
||||
.prepend(
|
||||
$('<span>').addClass('icon').html(' ')
|
||||
)
|
||||
)
|
||||
.click(function(event) {
|
||||
var $target = $(event.target);
|
||||
var $projectSwitcher = $(this);
|
||||
var $container = $('html body');
|
||||
var $navDisabled = $(
|
||||
$.map([
|
||||
'projects',
|
||||
'accounts',
|
||||
'domains',
|
||||
'system',
|
||||
'global-settings',
|
||||
'configuration'
|
||||
], function(id) {
|
||||
return '#navigation li.' + id;
|
||||
}).join(',')
|
||||
);
|
||||
|
||||
if ($target.closest('.select.project-view').size()) {
|
||||
$('#cloudStack3-container').addClass('project-view');
|
||||
$projectSwitcher.addClass('alt');
|
||||
$projectSwitcher.find('.select.project-view').addClass('active')
|
||||
.siblings().removeClass('active');
|
||||
|
||||
// Activate project view
|
||||
$navDisabled.hide();
|
||||
cloudStack.uiCustom.projects({
|
||||
$projectSelect: $projectSelect.hide().find('select')
|
||||
});
|
||||
} else {
|
||||
$navDisabled.show();
|
||||
$('#cloudStack3-container').removeClass('project-view');
|
||||
$projectSwitcher.removeClass('alt');
|
||||
$projectSelect.hide();
|
||||
$projectSwitcher.find('.select.default-view').addClass('active')
|
||||
.siblings().removeClass('active');
|
||||
|
||||
// Put project name in header
|
||||
$('.select.project-view').html(
|
||||
'<span class="icon"> </span>' + _l('label.project.view')
|
||||
).attr('title', '');
|
||||
|
||||
// Clear out project
|
||||
cloudStack.context.projects = null;
|
||||
}
|
||||
|
||||
$('#navigation li.dashboard').click();
|
||||
|
||||
return false;
|
||||
});
|
||||
var $projectSelect = $('<div>').addClass('view-switcher').hide()
|
||||
.append($('<select>'));
|
||||
|
||||
// User status area
|
||||
var userLabel = args.context.users[0].name ?
|
||||
args.context.users[0].name : args.context.users[0].login;
|
||||
var $userInfo = $('<div>').attr({
|
||||
id: 'user'
|
||||
}).addClass('button')
|
||||
.append(
|
||||
$('<div>').addClass('name').html(
|
||||
args.context && args.context.users ?
|
||||
cloudStack.concat(userLabel, 14) : 'Invalid User'
|
||||
)
|
||||
)
|
||||
.append(
|
||||
$('<div>').addClass('icon options')
|
||||
.append(
|
||||
$('<div>').addClass('icon arrow')
|
||||
)
|
||||
);
|
||||
$userInfo.attr('title', userLabel);
|
||||
|
||||
return [
|
||||
$('<div>').addClass('logo'),
|
||||
$('<div>').addClass('controls')
|
||||
.append($notificationArea)
|
||||
.append($viewSwitcher)
|
||||
.append($projectSelect)
|
||||
.append($userInfo)
|
||||
];
|
||||
},
|
||||
|
||||
'main-area': function(args) {
|
||||
var $navigation = $('<div>').attr({
|
||||
id: 'navigation'
|
||||
});
|
||||
}
|
||||
var $browser = $('<div>').attr({
|
||||
id: 'browser'
|
||||
})
|
||||
.append(
|
||||
// Home breadcrumb
|
||||
$('<div>').attr({
|
||||
id: 'breadcrumbs'
|
||||
})
|
||||
.append($('<div>').addClass('home'))
|
||||
.append($('<div>').addClass('end'))
|
||||
)
|
||||
|
||||
.append(
|
||||
// Panel container
|
||||
$('<div>').addClass('container')
|
||||
);
|
||||
|
||||
makeNavigation(args).appendTo($navigation);
|
||||
|
||||
return [
|
||||
$navigation, $browser
|
||||
];
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Hide logo conditionally
|
||||
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
@ -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);
|
||||
|
||||
@ -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, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">");
|
||||
var sanitized = value
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">");
|
||||
|
||||
return sanitized;
|
||||
};
|
||||
return sanitized;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reverse sanitization (HTML Decoding)
|
||||
*/
|
||||
cloudStack.sanitizeReverse = function(value) {
|
||||
var reversedValue = value
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">");
|
||||
/**
|
||||
* Reverse sanitization (HTML Decoding)
|
||||
*/
|
||||
cloudStack.sanitizeReverse = function(value) {
|
||||
var reversedValue = value
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
7871
ui/scripts/vpc.js
7871
ui/scripts/vpc.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user