Merge remote-tracking branch 'origin/master' into tagyourit

Conflicts:
	endpoints/api.py
	static/js/app.js
	static/partials/view-repo.html
	test/data/test.db
	test/specs.py
	test/test_api_usage.py
This commit is contained in:
jakedt 2014-03-26 19:42:29 -04:00
commit 302bfb27ae
123 changed files with 16314 additions and 3789 deletions

View file

@ -638,10 +638,8 @@ function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiServi
$rootScope.description = jQuery(getFirstTextLine(repo.description)).text() ||
'Visualization of images and tags for ' + kind + ' Docker repository: ' + qualifiedRepoName;
// If the repository is marked as building, start monitoring it for changes.
if (repo.is_building) {
startBuildInfoTimer(repo);
}
// Load the builds for this repository. If none are active it will cancel the poll.
startBuildInfoTimer(repo);
$('#copyClipboard').clipboardCopy();
});
@ -672,15 +670,19 @@ function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiServi
};
ApiService.getRepoBuilds(null, params, true).then(function(resp) {
// Build a filtered list of the builds that are currently running.
var runningBuilds = [];
for (var i = 0; i < resp.builds.length; ++i) {
var build = resp.builds[i];
if (build.status != 'complete') {
if (build['phase'] != 'complete' && build['phase'] != 'error') {
runningBuilds.push(build);
}
}
$scope.buildsInfo = runningBuilds;
var existingBuilds = $scope.runningBuilds || [];
$scope.runningBuilds = runningBuilds;
$scope.buildHistory = resp.builds;
if (!runningBuilds.length) {
// Cancel the build timer.
cancelBuildInfoTimer();
@ -688,8 +690,10 @@ function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiServi
// Mark the repo as no longer building.
$scope.repo.is_building = false;
// Reload the repo information.
loadViewInfo();
// Reload the repo information if all of the builds recently finished.
if (existingBuilds.length > 0) {
loadViewInfo();
}
}
});
};
@ -798,9 +802,23 @@ function BuildPackageCtrl($scope, Restangular, ApiService, $routeParams, $rootSc
// itself (should) be the Dockerfile.
if (zipFiles && Object.keys(zipFiles).length) {
// Load the dockerfile contents.
var dockerfile = zip.file('Dockerfile');
var dockerfilePath = 'Dockerfile';
if ($scope.repobuild['job_config']) {
var dockerfileFolder = ($scope.repobuild['job_config']['build_subdir'] || '');
if (dockerfileFolder[0] == '/') {
dockerfileFolder = dockerfileFolder.substr(1);
}
if (dockerfileFolder && dockerfileFolder[dockerfileFolder.length - 1] != '/') {
dockerfileFolder += '/';
}
dockerfilePath = dockerfileFolder + 'Dockerfile';
}
var dockerfile = zip.file(dockerfilePath);
if (dockerfile) {
$scope.dockerFileContents = dockerfile.asText();
$scope.dockerFilePath = dockerfilePath;
}
// Build the zip file tree.
@ -815,21 +833,17 @@ function BuildPackageCtrl($scope, Restangular, ApiService, $routeParams, $rootSc
});
} else {
$scope.dockerFileContents = response;
$scope.dockerFilePath = 'Dockerfile';
}
$scope.loaded = true;
};
var downloadBuildPack = function() {
var downloadBuildPack = function(url) {
$scope.downloadProgress = 0;
$scope.downloading = true;
ApiService.getRepoBuildArchiveUrl(null, params).then(function(resp) {
startDownload(resp['url']);
}, function() {
$scope.downloading = false;
$scope.downloadError = true;
});
startDownload(url);
};
var startDownload = function(url) {
@ -880,7 +894,7 @@ function BuildPackageCtrl($scope, Restangular, ApiService, $routeParams, $rootSc
'name': name
};
downloadBuildPack();
downloadBuildPack(resp['archive_url']);
return resp;
});
};
@ -888,7 +902,8 @@ function BuildPackageCtrl($scope, Restangular, ApiService, $routeParams, $rootSc
getBuildInfo();
}
function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $location, $interval, $sanitize, ansi2html) {
function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $location, $interval, $sanitize,
ansi2html, AngularViewArray) {
var namespace = $routeParams.namespace;
var name = $routeParams.name;
var pollTimerHandle = null;
@ -904,7 +919,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
}
});
$scope.builds = [];
$scope.builds = null;
$scope.polling = false;
$scope.buildDialogShowCounter = 0;
@ -914,12 +929,16 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
};
$scope.handleBuildStarted = function(newBuild) {
$scope.builds.push(newBuild);
$scope.builds.unshift(newBuild);
$scope.setCurrentBuild(newBuild['id'], true);
};
$scope.adjustLogHeight = function() {
$('.build-logs').height($(window).height() - 415);
var triggerOffset = 0;
if ($scope.currentBuild && $scope.currentBuild.trigger) {
triggerOffset = 85;
}
$('.build-logs').height($(window).height() - 415 - triggerOffset);
};
$scope.askRestartBuild = function(build) {
@ -929,8 +948,14 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
$scope.restartBuild = function(build) {
$('#confirmRestartBuildModal').modal('hide');
var subdirectory = '';
if (build['job_config']) {
subdirectory = build['job_config']['build_subdir'] || '';
}
var data = {
'file_id': build['resource_key']
'file_id': build['resource_key'],
'subdirectory': subdirectory
};
var params = {
@ -938,26 +963,18 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
};
ApiService.requestRepoBuild(data, params).then(function(newBuild) {
$scope.builds.push(newBuild);
$scope.builds.unshift(newBuild);
$scope.setCurrentBuild(newBuild['id'], true);
});
};
$scope.hasLogs = function(container) {
return ((container.logs && container.logs.length) || (container._logs && container._logs.length));
return container.logs.hasEntries;
};
$scope.toggleLogs = function(container) {
if (container._logs) {
container.logs = container._logs;
container._logs = null;
} else {
container._logs = container.logs;
container.logs = null;
}
};
$scope.setCurrentBuild = function(buildId, opt_updateURL) {
if (!$scope.builds) { return; }
// Find the build.
for (var i = 0; i < $scope.builds.length; ++i) {
if ($scope.builds[i].id == buildId) {
@ -1042,17 +1059,13 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
var entry = logs[i];
var type = entry['type'] || 'entry';
if (type == 'command' || type == 'phase' || type == 'error') {
entry['_logs'] = [];
entry['logs'] = AngularViewArray.create();
entry['index'] = startIndex + i;
$scope.logEntries.push(entry);
$scope.currentParentEntry = entry;
$scope.currentParentEntry = entry;
} else if ($scope.currentParentEntry) {
if ($scope.currentParentEntry['logs']) {
$scope.currentParentEntry['logs'].push(entry);
} else {
$scope.currentParentEntry['_logs'].push(entry);
}
$scope.currentParentEntry['logs'].push(entry);
}
}
};
@ -1120,7 +1133,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
if ($location.search().current) {
$scope.setCurrentBuild($location.search().current, false);
} else if ($scope.builds.length > 0) {
$scope.setCurrentBuild($scope.builds[$scope.builds.length - 1].id, true);
$scope.setCurrentBuild($scope.builds[0].id, true);
}
});
};
@ -1128,7 +1141,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
fetchRepository();
}
function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope) {
function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, $routeParams, $rootScope, $location) {
var namespace = $routeParams.namespace;
var name = $routeParams.name;
@ -1138,6 +1151,33 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
$scope.permissionCache = {};
$scope.githubRedirectUri = KeyService.githubRedirectUri;
$scope.githubClientId = KeyService.githubClientId;
$scope.getBadgeFormat = function(format, repo) {
if (!repo) { return; }
var imageUrl = 'https://quay.io/repository/' + namespace + '/' + name + '/status';
if (!$scope.repo.is_public) {
imageUrl += '?token=' + $scope.repo.status_token;
}
var linkUrl = 'https://quay.io/repository/' + namespace + '/' + name;
switch (format) {
case 'svg':
return imageUrl;
case 'md':
return '[![Docker Repository on Quay.io](' + imageUrl + ' "Docker Repository on Quay.io")](' + linkUrl + ')';
case 'asciidoc':
return 'image:' + imageUrl + '["Docker Repository on Quay.io", link="' + linkUrl + '"]';
}
return '';
};
$scope.buildEntityForPermission = function(name, permission, kind) {
var key = name + ':' + kind;
if ($scope.permissionCache[key]) {
@ -1196,7 +1236,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
};
var permissionPost = Restangular.one(getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
permissionPost.customPOST(permission).then(function(result) {
permissionPost.customPUT(permission).then(function(result) {
$scope.permissions[kind][entityName] = result;
}, function(result) {
$('#cannotchangeModal').modal({});
@ -1358,6 +1398,130 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
});
};
$scope.showBuild = function(buildInfo) {
$location.path('/repository/' + namespace + '/' + name + '/build');
$location.search('current', buildInfo.id);
};
$scope.loadTriggerBuildHistory = function(trigger) {
trigger.$loadingHistory = true;
var params = {
'repository': namespace + '/' + name,
'trigger_uuid': trigger.id,
'limit': 3
};
ApiService.listTriggerRecentBuilds(null, params).then(function(resp) {
trigger.$builds = resp['builds'];
trigger.$loadingHistory = false;
});
};
$scope.loadTriggers = function() {
var params = {
'repository': namespace + '/' + name
};
$scope.triggersResource = ApiService.listBuildTriggersAsResource(params).get(function(resp) {
$scope.triggers = resp.triggers;
// Check to see if we need to setup any trigger.
var newTriggerId = $routeParams.new_trigger;
if (newTriggerId) {
for (var i = 0; i < $scope.triggers.length; ++i) {
var trigger = $scope.triggers[i];
if (trigger['id'] == newTriggerId && !trigger['is_active']) {
$scope.setupTrigger(trigger);
break;
}
}
}
return $scope.triggers;
});
};
$scope.setupTrigger = function(trigger) {
$scope.triggerSetupReady = false;
$scope.currentSetupTrigger = trigger;
$('#setupTriggerModal').modal({});
$('#setupTriggerModal').on('hidden.bs.modal', function () {
$scope.$apply(function() {
$scope.cancelSetupTrigger();
});
});
};
$scope.finishSetupTrigger = function(trigger) {
$('#setupTriggerModal').modal('hide');
$scope.currentSetupTrigger = null;
var params = {
'repository': namespace + '/' + name,
'trigger_uuid': trigger.id
};
ApiService.activateBuildTrigger(trigger['config'], params).then(function(resp) {
trigger['is_active'] = true;
}, function(resp) {
$scope.triggers.splice($scope.triggers.indexOf(trigger), 1);
bootbox.dialog({
"message": resp['data']['message'] || 'The build trigger setup could not be completed',
"title": "Could not activate build trigger",
"buttons": {
"close": {
"label": "Close",
"className": "btn-primary"
}
}
});
});
};
$scope.cancelSetupTrigger = function() {
if (!$scope.currentSetupTrigger) { return; }
$('#setupTriggerModal').modal('hide');
$scope.deleteTrigger($scope.currentSetupTrigger);
$scope.currentSetupTrigger = null;
};
$scope.startTrigger = function(trigger) {
var params = {
'repository': namespace + '/' + name,
'trigger_uuid': trigger.id
};
ApiService.manuallyStartBuildTrigger(null, params).then(function(resp) {
window.console.log(resp);
var url = '/repository/' + namespace + '/' + name + '/build?current=' + resp['id'];
document.location = url;
}, function(resp) {
bootbox.dialog({
"message": resp['message'] || 'The build could not be started',
"title": "Could not start build",
"buttons": {
"close": {
"label": "Close",
"className": "btn-primary"
}
}
});
});
};
$scope.deleteTrigger = function(trigger) {
var params = {
'repository': namespace + '/' + name,
'trigger_uuid': trigger.id
};
ApiService.deleteBuildTrigger(null, params).then(function(resp) {
$scope.triggers.splice($scope.triggers.indexOf(trigger), 1);
});
};
var fetchTokens = function() {
var params = {
'repository': namespace + '/' + name
@ -1421,7 +1585,6 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
}
UserService.updateUserIn($scope, function(user) {
$scope.askForPassword = user.askForPassword;
$scope.cuser = jQuery.extend({}, user);
for (var i = 0; i < $scope.cuser.logins.length; i++) {
@ -1447,12 +1610,42 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
$scope.org = {};
$scope.githubRedirectUri = KeyService.githubRedirectUri;
$scope.githubClientId = KeyService.githubClientId;
$scope.authorizedApps = null;
$('.form-change').popover();
$scope.logsShown = 0;
$scope.invoicesShown = 0;
$scope.loadAuthedApps = function() {
if ($scope.authorizedApps) { return; }
ApiService.listUserAuthorizations().then(function(resp) {
$scope.authorizedApps = resp['authorizations'];
});
};
$scope.deleteAccess = function(accessTokenInfo) {
var params = {
'access_token_uuid': accessTokenInfo['uuid']
};
ApiService.deleteUserAuthorization(null, params).then(function(resp) {
$scope.authorizedApps.splice($scope.authorizedApps.indexOf(accessTokenInfo), 1);
}, function(resp) {
bootbox.dialog({
"message": resp.message || 'Could not revoke authorization',
"title": "Cannot revoke authorization",
"buttons": {
"close": {
"label": "Close",
"className": "btn-primary"
}
}
});
});
};
$scope.loadLogs = function() {
if (!$scope.hasPaidBusinessPlan) { return; }
$scope.logsShown++;
@ -1518,7 +1711,8 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
$scope.sentEmail = $scope.cuser.email;
// Reset the form.
$scope.cuser.repeatEmail = '';
delete $scope.cuser['repeatEmail'];
$scope.changeEmailForm.$setPristine();
}, function(result) {
$scope.updatingUser = false;
@ -1540,8 +1734,9 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
$scope.changePasswordSuccess = true;
// Reset the form
$scope.cuser.password = '';
$scope.cuser.repeatPassword = '';
delete $scope.cuser['password']
delete $scope.cuser['repeatPassword']
$scope.changePasswordForm.$setPristine();
// Reload the user.
@ -1614,6 +1809,16 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, I
}, 10);
};
var fetchRepository = function() {
var params = {
'repository': namespace + '/' + name
};
ApiService.getRepoAsResource(params).get(function(repo) {
$scope.repo = repo;
});
};
var fetchImage = function() {
var params = {
'repository': namespace + '/' + name,
@ -1621,10 +1826,13 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, I
};
$scope.image = ApiService.getImageAsResource(params).get(function(image) {
$scope.repo = {
'name': name,
'namespace': namespace
};
if (!$scope.repo) {
$scope.repo = {
'name': name,
'namespace': namespace,
'is_public': true
};
}
$rootScope.title = 'View Image - ' + image.id;
$rootScope.description = 'Viewing docker image ' + image.id + ' under repository ' + namespace + '/' + name +
@ -1665,6 +1873,9 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, I
});
};
// Fetch the repository.
fetchRepository();
// Fetch the image.
fetchImage();
}
@ -1673,13 +1884,16 @@ function V1Ctrl($scope, $location, UserService) {
UserService.updateUserIn($scope);
}
function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService, PlanService) {
function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService, PlanService, KeyService) {
UserService.updateUserIn($scope);
$scope.githubRedirectUri = KeyService.githubRedirectUri;
$scope.githubClientId = KeyService.githubClientId;
$scope.repo = {
'is_public': 1,
'description': '',
'initialize': false
'initialize': ''
};
// Watch the namespace on the repo. If it changes, we update the plan and the public/private
@ -1691,37 +1905,14 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService
var isUserNamespace = (namespace == $scope.user.username);
$scope.checkingPlan = true;
$scope.planRequired = null;
$scope.isUserNamespace = isUserNamespace;
if (isUserNamespace) {
// Load the user's subscription information in case they want to create a private
// repository.
ApiService.getUserPrivateCount().then(function(resp) {
if (resp.privateCount + 1 > resp.reposAllowed) {
PlanService.getMinimumPlan(resp.privateCount + 1, false, function(minimum) {
$scope.planRequired = minimum;
});
}
// Determine whether private repositories are allowed for the namespace.
checkPrivateAllowed();
$scope.checkingPlan = false;
}, function() {
$scope.planRequired = {};
$scope.checkingPlan = false;
});
} else {
ApiService.getOrganizationPrivateAllowed(null, {'orgname': namespace}).then(function(resp) {
$scope.planRequired = resp.privateAllowed ? null : {};
$scope.checkingPlan = false;
}, function() {
$scope.planRequired = {};
$scope.checkingPlan = false;
});
// Auto-set to private repo.
$scope.repo.is_public = '0';
}
// Default to private repos for organizations.
$scope.repo.is_public = isUserNamespace ? '1' : '0';
});
$scope.changeNamespace = function(namespace) {
@ -1771,12 +1962,20 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService
$scope.creating = false;
$scope.created = created;
// Repository created. Start the upload process if applicable.
if ($scope.repo.initialize) {
// Start the upload process if applicable.
if ($scope.repo.initialize == 'dockerfile' || $scope.repo.initialize == 'zipfile') {
$scope.createdForBuild = created;
return;
}
// Conduct the Github redirect if applicable.
if ($scope.repo.initialize == 'github') {
window.location = 'https://github.com/login/oauth/authorize?client_id=' + $scope.githubClientId +
'&scope=repo,user:email&redirect_uri=' + $scope.githubRedirectUri + '/trigger/' +
repo.namespace + '/' + repo.name;
return;
}
// Otherwise, redirect to the repo page.
$location.path('/repository/' + created.namespace + '/' + created.name);
}, function(result) {
@ -1800,7 +1999,35 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService
}
};
PlanService.changePlan($scope, null, $scope.planRequired.stripeId, callbacks);
var namespace = $scope.isUserNamespace ? null : $scope.repo.namespace;
PlanService.changePlan($scope, namespace, $scope.planRequired.stripeId, callbacks);
};
var checkPrivateAllowed = function() {
if (!$scope.repo || !$scope.repo.namespace) { return; }
$scope.checkingPlan = true;
var isUserNamespace = $scope.isUserNamespace;
ApiService.getPrivateAllowed(isUserNamespace ? null : $scope.repo.namespace).then(function(resp) {
$scope.checkingPlan = false;
if (resp['privateAllowed']) {
$scope.planRequired = null;
return;
}
if (resp['privateCount'] == null) {
// Organization where we are not the admin.
$scope.planRequired = {};
return;
}
// Otherwise, lookup the matching plan.
PlanService.getMinimumPlan(resp['privateCount'] + 1, !isUserNamespace, function(minimum) {
$scope.planRequired = minimum;
});
});
};
var subscribedToPlan = function(sub) {
@ -1810,16 +2037,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService
PlanService.getPlan(sub.plan, function(subscribedPlan) {
$scope.subscribedPlan = subscribedPlan;
$scope.planRequired = null;
// Check to see if the current plan allows for an additional private repository to
// be created.
var privateAllowed = $scope.subscription.usedPrivateRepos < $scope.subscribedPlan.privateRepos;
if (!privateAllowed) {
// If not, find the minimum repository that does.
PlanService.getMinimumPlan($scope.subscription.usedPrivateRepos + 1, !$scope.isUserNamespace, function(minimum) {
$scope.planRequired = minimum;
});
}
checkPrivateAllowed();
});
};
}
@ -1933,12 +2151,17 @@ function OrgAdminCtrl($rootScope, $scope, $timeout, Restangular, $routeParams, U
$scope.invoiceLoading = true;
$scope.logsShown = 0;
$scope.invoicesShown = 0;
$scope.applicationsShown = 0;
$scope.changingOrganization = false;
$scope.loadLogs = function() {
$scope.logsShown++;
};
$scope.loadApplications = function() {
$scope.applicationsShown++;
};
$scope.loadInvoices = function() {
$scope.invoicesShown++;
};
@ -2223,4 +2446,132 @@ function OrgMemberLogsCtrl($scope, $routeParams, $rootScope, $timeout, Restangul
// Load the org info and the member info.
loadOrganization();
loadMemberInfo();
}
function ManageApplicationCtrl($scope, $routeParams, $rootScope, $location, $timeout, ApiService) {
var orgname = $routeParams.orgname;
var clientId = $routeParams.clientid;
$scope.updating = false;
$scope.askResetClientSecret = function() {
$('#resetSecretModal').modal({});
};
$scope.askDelete = function() {
$('#deleteAppModal').modal({});
};
$scope.deleteApplication = function() {
var params = {
'orgname': orgname,
'client_id': clientId
};
$('#deleteAppModal').modal('hide');
ApiService.deleteOrganizationApplication(null, params).then(function(resp) {
$timeout(function() {
$location.path('/organization/' + orgname + '/admin');
}, 500);
}, function(resp) {
bootbox.dialog({
"message": resp.message || 'Could not delete application',
"title": "Cannot delete application",
"buttons": {
"close": {
"label": "Close",
"className": "btn-primary"
}
}
});
});
};
$scope.updateApplication = function() {
$scope.updating = true;
var params = {
'orgname': orgname,
'client_id': clientId
};
if (!$scope.application['description']) {
delete $scope.application['description'];
}
if (!$scope.application['gravatar_email']) {
delete $scope.application['gravatar_email'];
}
ApiService.updateOrganizationApplication($scope.application, params).then(function(resp) {
$scope.application = resp;
$scope.updating = false;
}, function(resp) {
$scope.updating = false;
bootbox.dialog({
"message": resp.message || 'Could not update application',
"title": "Cannot update application",
"buttons": {
"close": {
"label": "Close",
"className": "btn-primary"
}
}
});
});
};
$scope.resetClientSecret = function() {
var params = {
'orgname': orgname,
'client_id': clientId
};
$('#resetSecretModal').modal('hide');
ApiService.resetOrganizationApplicationClientSecret(null, params).then(function(resp) {
$scope.application = resp;
}, function(resp) {
bootbox.dialog({
"message": resp.message || 'Could not reset client secret',
"title": "Cannot reset client secret",
"buttons": {
"close": {
"label": "Close",
"className": "btn-primary"
}
}
});
});
};
var loadOrganization = function() {
$scope.orgResource = ApiService.getOrganizationAsResource({'orgname': orgname}).get(function(org) {
$scope.organization = org;
return org;
});
};
var loadApplicationInfo = function() {
var params = {
'orgname': orgname,
'client_id': clientId
};
$scope.appResource = ApiService.getOrganizationApplicationAsResource(params).get(function(resp) {
$scope.application = resp;
$rootScope.title = 'Manage Application ' + $scope.application.name + ' (' + $scope.orgname + ')';
$rootScope.description = 'Manage the details of application ' + $scope.application.name +
' under organization ' + $scope.orgname;
return resp;
});
};
// Load the organization and application info.
loadOrganization();
loadApplicationInfo();
}