mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Remove closeOnEscape from $(':ui-dialog') option calls, as they cause
JS errors breaking the projects UI. closeOnEscape is already defined
when the dialog is initialized, so these don't need to be defined
again.
722 lines
24 KiB
JavaScript
722 lines
24 KiB
JavaScript
// Copyright 2012 Citrix Systems, Inc. Licensed under the
|
|
// Apache License, Version 2.0 (the "License"); you may not use this
|
|
// file except in compliance with the License. Citrix Systems, Inc.
|
|
// reserves all rights not expressly granted by the License.
|
|
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
// Automatically generated by addcopyright.py at 04/03/2012
|
|
(function(cloudStack, $) {
|
|
var pageElems = cloudStack.uiCustom.projectsTabs = {
|
|
/**
|
|
* User management multi-edit
|
|
*/
|
|
userManagement: function(args) {
|
|
var multiEdit = !args.useInvites ?
|
|
cloudStack.projects.addUserForm :
|
|
cloudStack.projects.inviteForm;
|
|
|
|
var $multi = $('<div>').multiEdit($.extend(true, {}, multiEdit, {
|
|
context: args.context
|
|
}));
|
|
|
|
if (args.useInvites) {
|
|
var $fields = $multi.find('form table').find('th, td');
|
|
var $accountFields = $fields.filter(function() {
|
|
return $(this).hasClass('account');
|
|
});
|
|
var $emailFields = $fields.filter(function() {
|
|
return $(this).hasClass('email');
|
|
});
|
|
|
|
$multi.prepend(
|
|
$('<div>').addClass('add-by')
|
|
.append($('<span>').html(_l('label.add.by') + ':'))
|
|
.append(
|
|
$('<div>').addClass('selection')
|
|
.append(
|
|
$('<input>').attr({
|
|
type: 'radio',
|
|
name: 'add-by',
|
|
checked: 'checked'
|
|
}).click(function() {
|
|
$accountFields.show();
|
|
$emailFields.hide();
|
|
$emailFields.find('input').val('');
|
|
|
|
return true;
|
|
}).click()
|
|
)
|
|
.append($('<label>').html(_l('label.account')))
|
|
.append(
|
|
$('<input>').attr({
|
|
type: 'radio',
|
|
name: 'add-by'
|
|
}).click(function() {
|
|
$accountFields.hide();
|
|
$accountFields.find('input').val('');
|
|
$emailFields.show();
|
|
|
|
return true;
|
|
})
|
|
)
|
|
.append($('<label>').html(_l('label.email')))
|
|
)
|
|
);
|
|
}
|
|
|
|
return $multi;
|
|
},
|
|
|
|
dashboardTabs: {
|
|
overview: function() {
|
|
var $dashboard = $('#template').find('.project-dashboard-view').clone();
|
|
$dashboard.data('tab-title', _l('label.menu.dashboard'));
|
|
|
|
var getData = function() {
|
|
// Populate data
|
|
$dashboard.find('[data-item]').hide();
|
|
var $loading = $('<div>').addClass('loading-overlay').prependTo($dashboard);
|
|
cloudStack.projects.dashboard({
|
|
response: {
|
|
success: function(args) {
|
|
$loading.remove();
|
|
var data = args.data;
|
|
|
|
// 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();
|
|
|
|
$.each(item, function(arrayKey, arrayValue) {
|
|
var $arrayElem = $li.find('[data-list-item=' + arrayKey + ']');
|
|
|
|
$arrayElem.html(_s(arrayValue));
|
|
});
|
|
|
|
$li.attr({ title: 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();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
getData();
|
|
|
|
$dashboard.find('.button.manage-resources').click(function() {
|
|
$('.navigation-item.network').click();
|
|
});
|
|
|
|
$dashboard.find('.info-box.events .button').click(function() {
|
|
$('.navigation-item.events').click();
|
|
});
|
|
|
|
return $dashboard;
|
|
},
|
|
|
|
users: function() {
|
|
return $('<div>').addClass('management').data('tab-title', _l('label.menu.accounts'));
|
|
},
|
|
|
|
invitations: function() {
|
|
return $('<div>').addClass('management-invite').data('tab-title', _l('label.invitations'));
|
|
},
|
|
|
|
resources: function(options) {
|
|
if (!options) options = {};
|
|
|
|
var $resources = $('<div>').addClass('resources').data('tab-title', _l('label.resources'));
|
|
var $form = $('<form>');
|
|
var $submit = $('<input>').attr({
|
|
type: 'submit'
|
|
}).val(_l('label.apply'));
|
|
|
|
cloudStack.projects.resourceManagement.dataProvider({
|
|
response: {
|
|
success: function(args) {
|
|
$(args.data).each(function() {
|
|
var resource = this;
|
|
var $field = $('<div>').addClass('field');
|
|
var $label = $('<label>').attr({
|
|
'for': resource.type
|
|
}).html(_s(resource.label));
|
|
var $input = $('<input>').attr({
|
|
type: 'text',
|
|
name: resource.type,
|
|
value: resource.value
|
|
}).addClass('required');
|
|
|
|
$field.append($label, $input);
|
|
$field.appendTo($form);
|
|
});
|
|
|
|
$form.validate();
|
|
$form.submit(function() {
|
|
if (!$form.valid) {
|
|
return false;
|
|
}
|
|
|
|
var $loading = $('<div>').addClass('loading-overlay').appendTo($form);
|
|
|
|
cloudStack.projects.resourceManagement.update({
|
|
data: cloudStack.serializeForm($form),
|
|
response: {
|
|
success: function(args) {
|
|
$loading.remove();
|
|
$('.notifications').notifications('add', {
|
|
section: 'dashboard',
|
|
desc: 'label.update.project.resources',
|
|
interval: 1000,
|
|
poll: function(args) {
|
|
args.complete();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}, options.projectID);
|
|
|
|
return false;
|
|
});
|
|
|
|
$submit.appendTo($form);
|
|
$form.appendTo($resources);
|
|
}
|
|
}
|
|
}, options.projectID);
|
|
|
|
return $resources;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Projects dashboard
|
|
*/
|
|
dashboard: function() {
|
|
var tabs = {
|
|
dashboard: pageElems.dashboardTabs.overview
|
|
};
|
|
|
|
// Only show management tabs to owner of project
|
|
if (isAdmin() || isDomainAdmin() || (
|
|
cloudStack.context.projects &&
|
|
(cloudStack.context.projects[0].account == cloudStack.context.users[0].account)
|
|
)) {
|
|
tabs.users = pageElems.dashboardTabs.users;
|
|
|
|
if (g_capabilities.projectinviterequired) {
|
|
tabs.invitations = pageElems.dashboardTabs.invitations;
|
|
}
|
|
|
|
if (isAdmin() || isDomainAdmin()) {
|
|
tabs.resources = pageElems.dashboardTabs.resources;
|
|
}
|
|
}
|
|
|
|
var $tabs = $('<div>').addClass('tab-content').append($('<ul>'));
|
|
var $toolbar = $('<div>').addClass('toolbar');
|
|
|
|
// Make UI tabs
|
|
$.each(tabs, function(tabName, tab) {
|
|
var $tab = $('<li>').appendTo($tabs.find('ul:first'));
|
|
var $tabContent = tab();
|
|
var $tabLink = $('<a>')
|
|
.attr({ href: '#project-view-dashboard-' + tabName })
|
|
.html($tabContent.data('tab-title'))
|
|
.appendTo($tab);
|
|
var $content = $('<div>')
|
|
.appendTo($tabs)
|
|
.attr({ id: 'project-view-dashboard-' + tabName })
|
|
.append($tabContent);
|
|
});
|
|
|
|
$tabs.find('ul li:first').addClass('first');
|
|
$tabs.find('ul li:last').addClass('last');
|
|
|
|
$tabs.bind('tabsshow', function(event, ui) {
|
|
var $panel = $(ui.panel);
|
|
var $management = $panel.find('.management');
|
|
var $managementInvite = $panel.find('.management-invite');
|
|
|
|
if ($management.size()) {
|
|
$management.children().remove();
|
|
$management.append(pageElems.userManagement({
|
|
context: cloudStack.context
|
|
}));
|
|
|
|
return true;
|
|
}
|
|
|
|
if ($managementInvite.size()) {
|
|
$managementInvite.children().remove();
|
|
$managementInvite.append(pageElems.userManagement({
|
|
context: cloudStack.context,
|
|
useInvites: true
|
|
}));
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
return $('<div>').addClass('project-dashboard')
|
|
.append($.merge(
|
|
$toolbar,
|
|
$tabs.tabs()
|
|
));
|
|
},
|
|
|
|
/**
|
|
* Add new project flow
|
|
*/
|
|
newProjectForm: function() {
|
|
var $newProject = $('<div>').addClass('new-project');
|
|
$newProject.append($('<div>').addClass('title').html(_l('label.create.project')));
|
|
|
|
var $form = $('<form>');
|
|
var $formDesc = $('<div>').addClass('form-desc');
|
|
var $projectName = $('<div>').addClass('field name')
|
|
.append($('<label>').attr('for', 'project-name').html(_l('label.project.name')))
|
|
.append($('<input>').addClass('required').attr({
|
|
type: 'text',
|
|
name: 'project-name'
|
|
}));
|
|
var $projectDesc = $('<div>').addClass('field desc')
|
|
.append($('<label>').attr('for', 'project-desc').html(_l('label.display.text')))
|
|
.append($('<input>').attr({
|
|
type: 'text',
|
|
name: 'project-display-text'
|
|
}));
|
|
var $submit = $('<input>').attr({ type: 'submit' }).val(_l('label.create.project'));
|
|
var $cancel = $('<div>').addClass('button cancel').html(_l('label.cancel'));
|
|
var $loading = $('<div>').addClass('loading-overlay');
|
|
|
|
// Form events/validation
|
|
$form.validate();
|
|
$form.submit(function() {
|
|
if (!$form.valid()) return false;
|
|
|
|
$form.prepend($loading);
|
|
|
|
cloudStack.projects.add({
|
|
context: cloudStack.context,
|
|
data: cloudStack.serializeForm($form),
|
|
response: {
|
|
success: function(args) {
|
|
var project = args.data;
|
|
|
|
$(window).trigger('cloudStack.fullRefresh');
|
|
|
|
$loading.remove();
|
|
|
|
// Confirmation
|
|
$form.replaceWith(function() {
|
|
var $confirm = $('<div>').addClass('confirm');
|
|
|
|
// Update title with project name
|
|
$newProject.find('.title').html(_s(args.data.name));
|
|
|
|
// Show field data
|
|
$confirm.append($projectName).find('input').replaceWith( // Name
|
|
$('<span>').addClass('value').html(_s(
|
|
args.data.name
|
|
))
|
|
);
|
|
$confirm.append($projectDesc).find('input').replaceWith( // Display text
|
|
$('<span>').addClass('value').html(_s(
|
|
args.data.displayText
|
|
))
|
|
);
|
|
|
|
var $buttons = $('<div>').addClass('buttons');
|
|
var $addAccountButton = $('<div>').addClass('button confirm').html(_l('label.add.accounts'));
|
|
|
|
$addAccountButton.click(function() {
|
|
// Show add user form
|
|
$confirm.replaceWith(function() {
|
|
var $userManagement = pageElems.userManagement({
|
|
context: $.extend(true, {}, cloudStack.context, {
|
|
projects: [project]
|
|
}),
|
|
useInvites: cloudStack.projects.requireInvitation()
|
|
});
|
|
var $nextButton = $('<div>').addClass('button confirm next').html(_l('label.next'));
|
|
|
|
$newProject.find('.title').html(
|
|
cloudStack.projects.requireInvitation() ?
|
|
_l('label.invite.to') + ' ' + _s(args.data.name) :
|
|
_l('label.add.accounts.to') + ' ' + _s(args.data.name)
|
|
);
|
|
$nextButton.appendTo($userManagement).click(function() {
|
|
$newProject.find('.title').html(_l('label.review'));
|
|
$userManagement.replaceWith(function() {
|
|
var $review = $('<div>').addClass('review');
|
|
var $projectData = $('<div>').addClass('project-data');
|
|
|
|
// Basic project data
|
|
$review.append($projectData);
|
|
$projectData.append($projectName).find('input').replaceWith( // Name
|
|
$('<span>').addClass('value').html(_s(
|
|
args.data.name
|
|
))
|
|
);
|
|
$projectData.append($projectDesc).find('input').replaceWith( // Display text
|
|
$('<span>').addClass('value').html(_s(
|
|
args.data.displayText
|
|
))
|
|
);
|
|
|
|
// User/resouce tabs
|
|
var $tabs = $('<div>').addClass('tabs resources').appendTo($review);
|
|
var $ul = $('<ul>').appendTo($tabs)
|
|
.append(
|
|
// Users tab
|
|
$('<li>').addClass('first').append(
|
|
$('<a>').attr({ href: '#new-project-review-tabs-users'}).html(
|
|
cloudStack.projects.requireInvitation() ?
|
|
_l('label.invitations') : _l('label.accounts')
|
|
)
|
|
)
|
|
);
|
|
|
|
if (isAdmin() || isDomainAdmin()) {
|
|
$ul.append(
|
|
// Resources tab
|
|
$('<li>').addClass('last').append(
|
|
$('<a>').attr({ href: '#new-project-review-tabs-resouces'}).html(_l('label.resources'))
|
|
)
|
|
);
|
|
}
|
|
|
|
var $users = $('<div>').attr({ id: 'new-project-review-tabs-users' }).appendTo($tabs);
|
|
cloudStack.context.projects = [project];
|
|
|
|
var $resources;
|
|
if (isAdmin() || isDomainAdmin()) {
|
|
$resouces = $('<div>')
|
|
.attr({ id: 'new-project-review-tabs-resouces' })
|
|
.appendTo($tabs)
|
|
.append(pageElems.dashboardTabs.resources);
|
|
}
|
|
|
|
$tabs.tabs();
|
|
|
|
$users.listView({
|
|
listView: {
|
|
id: 'project-accounts',
|
|
disableInfiniteScrolling: true,
|
|
fields: !cloudStack.projects.requireInvitation() ? {
|
|
username: { label: _l('label.account') }
|
|
} : {
|
|
account: { label: _l('label.invited.accounts') }
|
|
},
|
|
dataProvider: function(args) {
|
|
setTimeout(function() {
|
|
args.response.success({
|
|
data: $.map($userManagement.find('.data-item tr'), function(elem) {
|
|
// Store previous user data in list table
|
|
return !cloudStack.projects.requireInvitation() ? {
|
|
username: $(elem).find('td.username span').html()
|
|
} : {
|
|
account: $(elem).find('td.account span').html()
|
|
};
|
|
})
|
|
});
|
|
}, 0);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Save button
|
|
var $saveButton = $nextButton.clone().appendTo($review);
|
|
$saveButton.html(_l('label.save'));
|
|
$saveButton.click(function() {
|
|
$('#new-project-review-tabs-resouces').find('form').submit();
|
|
$('.ui-dialog, .overlay').remove();
|
|
});
|
|
|
|
$laterButton.click(function() {
|
|
$(':ui-dialog, .overlay').remove();
|
|
|
|
return false;
|
|
});
|
|
|
|
return $review;
|
|
});
|
|
|
|
$(':ui-dialog').dialog('option', 'position', 'center');
|
|
});
|
|
$laterButton.html(_l('label.close')).appendTo($userManagement);
|
|
|
|
return $userManagement;
|
|
});
|
|
|
|
$(':ui-dialog').dialog('option', 'position', 'center');
|
|
|
|
return false;
|
|
});
|
|
|
|
var $laterButton = $('<div>').addClass('button later').html(_l('label.remind.later'));
|
|
$laterButton.click(function() {
|
|
$(':ui-dialog, .overlay').remove();
|
|
|
|
return false;
|
|
});
|
|
|
|
$buttons.appendTo($confirm).append($.merge(
|
|
$addAccountButton, $laterButton
|
|
));
|
|
|
|
return $confirm;
|
|
});
|
|
},
|
|
error: cloudStack.dialog.error(function() {
|
|
$loading.remove();
|
|
})
|
|
}
|
|
});
|
|
|
|
return false;
|
|
});
|
|
|
|
$cancel.click(function() {
|
|
$(':ui-dialog, .overlay').remove();
|
|
});
|
|
|
|
return $newProject
|
|
.append(
|
|
$form
|
|
.append($formDesc)
|
|
.append($projectName)
|
|
.append($projectDesc)
|
|
.append($cancel)
|
|
.append($submit)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Project selection list
|
|
*/
|
|
selector: function(args) {
|
|
var $selector = $('<div>').addClass('project-selector');
|
|
var $toolbar = $('<div>').addClass('toolbar');
|
|
var $list = $('<div>').addClass('listing')
|
|
.append($('<div>').addClass('header').html(_l('label.name')))
|
|
.append($('<div>').addClass('data').append($('<ul>')));
|
|
var $searchForm = $('<form>');
|
|
var $search = $('<div>').appendTo($toolbar).addClass('search')
|
|
.append(
|
|
$searchForm
|
|
.append($('<input>').attr({ type: 'text' }))
|
|
.append($('<input>').attr({ type: 'submit' }).val(''))
|
|
);
|
|
var $projectSelect = args.$projectSelect;
|
|
|
|
// Get project data
|
|
var loadData = function(complete) {
|
|
cloudStack.projects.dataProvider({
|
|
context: cloudStack.context,
|
|
response: {
|
|
success: function(args) {
|
|
var data = args.data;
|
|
|
|
$projectSelect.find('option').remove();
|
|
$(data).each(function() {
|
|
var displayText = this.displayText ? this.displayText : this.name;
|
|
|
|
$('<li>')
|
|
.data('json-obj', this)
|
|
.html(_s(displayText))
|
|
.appendTo($list.find('ul'));
|
|
|
|
// Populate project select
|
|
$('<option>')
|
|
.appendTo($projectSelect)
|
|
.data('json-obj', this)
|
|
.html(_s(displayText));
|
|
});
|
|
|
|
cloudStack.evenOdd($list, 'li', {
|
|
even: function($elem) {
|
|
$elem.addClass('even');
|
|
},
|
|
|
|
odd: function($elem) {
|
|
$elem.addClass('odd');
|
|
}
|
|
});
|
|
|
|
if (complete) complete();
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
// Search form
|
|
$searchForm.submit(function() {
|
|
$list.find('li').remove();
|
|
loadData();
|
|
|
|
return false;
|
|
});
|
|
|
|
// Initial load
|
|
loadData(function() {
|
|
if (!$list.find('li').size()) {
|
|
cloudStack.dialog.notice({
|
|
message: isAdmin() || isDomainAdmin() || g_userProjectsEnabled ?
|
|
_l('message.no.projects') :
|
|
_l('message.no.projects.adminOnly')
|
|
}).closest('.ui-dialog');
|
|
$.merge($selector, $('.overlay')).remove();
|
|
$('.select.default-view').click();
|
|
} else {
|
|
$selector.dialog({
|
|
title: _l('label.select.project'),
|
|
dialogClass: 'project-selector-dialog',
|
|
closeOnEscape: false ,
|
|
width: 420
|
|
}).closest('.ui-dialog').overlay();
|
|
}
|
|
});
|
|
|
|
// Project item click event
|
|
$selector.click(function(event) {
|
|
var $target = $(event.target);
|
|
|
|
if ($target.is('li')) {
|
|
cloudStack.context.projects = [$target.data('json-obj')];
|
|
showDashboard();
|
|
|
|
var $switcher = $('.select.project-view');
|
|
var projectName = _s(cloudStack.context.projects[0].name);
|
|
|
|
$switcher.attr('title', projectName);
|
|
if (projectName.length > 10) {
|
|
projectName = projectName.substr(0, 10).concat('...');
|
|
}
|
|
|
|
// Put project name in header
|
|
$switcher.html('<span class="icon"> </span>' + projectName);
|
|
|
|
|
|
$.merge($selector, $('.overlay')).remove();
|
|
|
|
// Select active project
|
|
$projectSelect
|
|
.find('option').attr('selected', '')
|
|
.filter(function() {
|
|
return $(this).data('json-obj').name == _s(cloudStack.context.projects[0].name);
|
|
}).attr('selected', 'selected');
|
|
|
|
////
|
|
// Hidden for now
|
|
//$projectSelect.parent().show();
|
|
}
|
|
});
|
|
|
|
return $selector
|
|
.append($toolbar)
|
|
.append($list);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Show project-mode appearance on CloudStack UI
|
|
*/
|
|
var applyProjectStyle = function() {
|
|
var $container = $('#cloudStack3-container');
|
|
$container.addClass('project-view');
|
|
};
|
|
|
|
/**
|
|
* Initiate new project flow
|
|
*/
|
|
var addProject = function() {
|
|
pageElems.newProjectForm().dialog({
|
|
title: 'New Project',
|
|
closeOnEscape: false,
|
|
width: 760
|
|
}).closest('.ui-dialog').overlay();
|
|
};
|
|
|
|
/**
|
|
* Show the dashboard, in panel
|
|
*/
|
|
var showDashboard = function() {
|
|
var $browser = $('#browser .container');
|
|
applyProjectStyle($('html body'));
|
|
|
|
// Cleanup project context
|
|
if (cloudStack.context.projects)
|
|
cloudStack.context.projects[0].isNew = false;
|
|
|
|
$browser.cloudBrowser('removeAllPanels');
|
|
$browser.cloudBrowser('addPanel', {
|
|
title: _l('label.project.dashboard'),
|
|
complete: function($newPanel) {
|
|
$('#navigation li.dashboard').addClass('active').siblings().removeClass('active');
|
|
$newPanel.append(pageElems.dashboard);
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Projects entry point
|
|
*/
|
|
cloudStack.uiCustom.projects = function(args) {
|
|
var $dashboardNavItem = $('#navigation li.navigation-item.dashboard');
|
|
|
|
// Use project dashboard
|
|
var event = function() {
|
|
if (!$('#cloudStack3-container').hasClass('project-view')) {
|
|
// No longer in project view, go back to normal dashboard
|
|
$dashboardNavItem.unbind('click', event);
|
|
|
|
return true;
|
|
}
|
|
|
|
$(this).addClass('active');
|
|
$(this).siblings().removeClass('active');
|
|
|
|
if (cloudStack.context.projects && cloudStack.context.projects[0]) {
|
|
showDashboard();
|
|
}
|
|
|
|
return false;
|
|
};
|
|
$dashboardNavItem.bind('click', event);
|
|
|
|
pageElems.selector(args);
|
|
};
|
|
|
|
/**
|
|
* New project event
|
|
*/
|
|
$(window).bind('cloudStack.newProject', function() {
|
|
addProject();
|
|
});
|
|
})(cloudStack, jQuery);
|