Delete the old UI!
This commit is contained in:
parent
33039e9bc4
commit
ff3d8bb013
54 changed files with 308 additions and 4383 deletions
|
@ -84,12 +84,6 @@ quayApp.config(['$routeProvider', '$locationProvider', 'pages', function($routeP
|
|||
// WARNING WARNING WARNING
|
||||
|
||||
var layoutProfile = 'layout';
|
||||
|
||||
// Check for the override flag.
|
||||
if (window.location.search.indexOf('old-ui=1') >= 0) {
|
||||
layoutProfile = 'old-layout';
|
||||
}
|
||||
|
||||
window.console.log('Using layout profile: ' + layoutProfile);
|
||||
|
||||
var routeBuilder = new AngularRouteBuilder($routeProvider, pages, [
|
||||
|
@ -108,18 +102,9 @@ quayApp.config(['$routeProvider', '$locationProvider', 'pages', function($routeP
|
|||
// Image View
|
||||
.route('/repository/:namespace/:name/image/:image', 'image-view')
|
||||
|
||||
// Repo Admin
|
||||
.route('/repository/:namespace/:name/admin', 'repo-admin')
|
||||
|
||||
// Repo Builds
|
||||
.route('/repository/:namespace/:name/build', 'repo-build')
|
||||
|
||||
// Repo Build View
|
||||
.route('/repository/:namespace/:name/build/:buildid', 'build-view')
|
||||
|
||||
// Repo Build Package
|
||||
.route('/repository/:namespace/:name/build/:buildid/buildpack', 'build-package')
|
||||
|
||||
// Repo List
|
||||
.route('/repository/', 'repo-list')
|
||||
|
||||
|
@ -132,24 +117,15 @@ quayApp.config(['$routeProvider', '$locationProvider', 'pages', function($routeP
|
|||
// View Organization
|
||||
.route('/organization/:orgname', 'org-view')
|
||||
|
||||
// Organization Admin
|
||||
.route('/organization/:orgname/admin', 'org-admin')
|
||||
|
||||
// View Organization Team
|
||||
.route('/organization/:orgname/teams/:teamname', 'team-view')
|
||||
|
||||
// Organization Member Logs
|
||||
.route('/organization/:orgname/logs/:membername', 'org-member-logs')
|
||||
|
||||
// Organization View Application
|
||||
.route('/organization/:orgname/application/:clientid', 'manage-application')
|
||||
|
||||
// View User
|
||||
.route('/user/:username', 'user-view')
|
||||
|
||||
// DEPRECATED: User Admin
|
||||
.route('/user/', 'user-admin')
|
||||
|
||||
// Sign In
|
||||
.route('/signin/', 'signin')
|
||||
|
||||
|
@ -189,9 +165,6 @@ quayApp.config(['$routeProvider', '$locationProvider', 'pages', function($routeP
|
|||
// Confirm Invite
|
||||
.route('/confirminvite', 'confirm-invite')
|
||||
|
||||
// Enable/disable experimental layout
|
||||
.route('/__exp/newlayout', 'exp-new-layout')
|
||||
|
||||
// Default: Redirect to the landing page
|
||||
.otherwise({redirectTo: '/'});
|
||||
}]);
|
||||
|
|
|
@ -235,21 +235,6 @@ angular.module("core-ui", [])
|
|||
return directiveDefinitionObject;
|
||||
})
|
||||
|
||||
// TODO(jschorr): Remove this once new layout is in prod.
|
||||
.directive('corTabShim', function() {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 3,
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {},
|
||||
controller: function($rootScope, $scope, $element, $timeout, $location, UIService) {
|
||||
UIService.initializeTabs($scope, $element);
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
})
|
||||
|
||||
.directive('corTabs', function() {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 3,
|
||||
|
|
|
@ -21,14 +21,6 @@ angular.module('quay').directive('entityReference', function () {
|
|||
};
|
||||
|
||||
$scope.getRobotUrl = function(name) {
|
||||
if (Config.isNewLayout()) {
|
||||
return $scope.getNewRobotUrl(name);
|
||||
} else {
|
||||
return $scope.getOldRobotUrl(name);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.getNewRobotUrl = function(name) {
|
||||
var namespace = $scope.getPrefix(name);
|
||||
if (!namespace) {
|
||||
return '';
|
||||
|
@ -47,26 +39,6 @@ angular.module('quay').directive('entityReference', function () {
|
|||
return '/organization/' + org['name'] + '?tab=robots&showRobot=' + UtilService.textToSafeHtml(name);
|
||||
};
|
||||
|
||||
// TODO(jschorr): Remove when new layout is in prod.
|
||||
$scope.getOldRobotUrl = function(name) {
|
||||
var namespace = $scope.getPrefix(name);
|
||||
if (!namespace) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!$scope.getIsAdmin(namespace)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var org = UserService.getOrganization(namespace);
|
||||
if (!org) {
|
||||
// This robot is owned by the user.
|
||||
return '/user/?tab=robots&showRobot=' + UtilService.textToSafeHtml(name);
|
||||
}
|
||||
|
||||
return '/organization/' + org['name'] + '/admin?tab=robots&showRobot=' + UtilService.textToSafeHtml(name);
|
||||
};
|
||||
|
||||
$scope.getTitle = function(entity) {
|
||||
if (!entity) { return ''; }
|
||||
|
||||
|
|
|
@ -14,41 +14,36 @@ angular.module('quay').directive('headerBar', function () {
|
|||
},
|
||||
controller: function($rootScope, $scope, $element, $location, $timeout, hotkeys, UserService,
|
||||
PlanService, ApiService, NotificationService, Config, CreateService, Features) {
|
||||
$scope.isNewLayout = Config.isNewLayout();
|
||||
|
||||
var hotkeysAdded = false;
|
||||
var userUpdated = function(cUser) {
|
||||
$scope.searchingAllowed = Features.ANONYMOUS_ACCESS || !cUser.anonymous;
|
||||
|
||||
if (hotkeysAdded) { return; }
|
||||
hotkeysAdded = true;
|
||||
|
||||
if ($scope.isNewLayout) {
|
||||
hotkeysAdded = true;
|
||||
// Register hotkeys.
|
||||
if ($scope.searchingAllowed) {
|
||||
hotkeys.add({
|
||||
combo: '/',
|
||||
description: 'Show search',
|
||||
callback: function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$scope.toggleSearch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Register hotkeys.
|
||||
if ($scope.searchingAllowed) {
|
||||
hotkeys.add({
|
||||
combo: '/',
|
||||
description: 'Show search',
|
||||
callback: function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$scope.toggleSearch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!cUser.anonymous) {
|
||||
hotkeys.add({
|
||||
combo: 'alt+c',
|
||||
description: 'Create new repository',
|
||||
callback: function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$location.url('/new');
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!cUser.anonymous) {
|
||||
hotkeys.add({
|
||||
combo: 'alt+c',
|
||||
description: 'Create new repository',
|
||||
callback: function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$location.url('/new');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
(function() {
|
||||
/**
|
||||
* Page which displays a build package for a specific build.
|
||||
*/
|
||||
angular.module('quayPages').config(['pages', function(pages) {
|
||||
pages.create('build-package', 'build-package.html', BuildPackageCtrl);
|
||||
}]);
|
||||
|
||||
function BuildPackageCtrl($scope, Restangular, ApiService, DataFileService, $routeParams, $rootScope, $location, $timeout) {
|
||||
var namespace = $routeParams.namespace;
|
||||
var name = $routeParams.name;
|
||||
var buildid = $routeParams.buildid;
|
||||
|
||||
var params = {
|
||||
'repository': namespace + '/' + name,
|
||||
'build_uuid': buildid
|
||||
};
|
||||
|
||||
$scope.initializeTree = function() {
|
||||
if ($scope.drawn) {
|
||||
$scope.tree.notifyResized();
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.drawn = true;
|
||||
$timeout(function() {
|
||||
$scope.tree.draw('file-tree-container');
|
||||
}, 10);
|
||||
};
|
||||
|
||||
var determineDockerfilePath = function() {
|
||||
var dockerfilePath = 'Dockerfile';
|
||||
var dockerfileFolder = ($scope.repobuild['subdirectory'] || '');
|
||||
if (dockerfileFolder[0] == '/') {
|
||||
dockerfileFolder = dockerfileFolder.substr(1);
|
||||
}
|
||||
if (dockerfileFolder && dockerfileFolder[dockerfileFolder.length - 1] != '/') {
|
||||
dockerfileFolder += '/';
|
||||
}
|
||||
dockerfilePath = dockerfileFolder + 'Dockerfile';
|
||||
return dockerfilePath;
|
||||
};
|
||||
|
||||
var processBuildPack = function(uint8array) {
|
||||
var archiveread = function(files) {
|
||||
var getpath = function(file) {
|
||||
return file.path;
|
||||
};
|
||||
|
||||
var findFile = function(path) {
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
var file = files[i];
|
||||
if (file.path == path) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
$scope.tree = new FileTree($.map(files, getpath));
|
||||
$($scope.tree).bind('fileClicked', function(e) {
|
||||
var file = findFile(e.path);
|
||||
if (file && file.canRead) {
|
||||
saveAs(file.toBlob(), file.name);
|
||||
}
|
||||
});
|
||||
|
||||
var dockerfilePath = determineDockerfilePath();
|
||||
var dockerfile = findFile(dockerfilePath);
|
||||
if (dockerfile && dockerfile.canRead) {
|
||||
DataFileService.blobToString(dockerfile.toBlob(), function(result) {
|
||||
$scope.$apply(function() {
|
||||
$scope.dockerFilePath = dockerfilePath || 'Dockerfile';
|
||||
$scope.dockerFileContents = result;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$scope.loaded = true;
|
||||
};
|
||||
|
||||
var notarchive = function() {
|
||||
DataFileService.arrayToString(uint8array, function(r) {
|
||||
$scope.dockerFilePath = 'Dockerfile';
|
||||
$scope.dockerFileContents = r;
|
||||
$scope.loaded = true;
|
||||
});
|
||||
};
|
||||
|
||||
setTimeout(function() {
|
||||
$scope.$apply(function() {
|
||||
DataFileService.readDataArrayAsPossibleArchive(uint8array, archiveread, notarchive);
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
var downloadBuildPack = function(url) {
|
||||
$scope.downloadProgress = 0;
|
||||
$scope.downloading = true;
|
||||
startDownload(url);
|
||||
};
|
||||
|
||||
var startDownload = function(url) {
|
||||
var onprogress = function(p) {
|
||||
$scope.downloadProgress = p * 100;
|
||||
};
|
||||
|
||||
var onerror = function() {
|
||||
$scope.downloading = false;
|
||||
$scope.downloadError = true;
|
||||
};
|
||||
|
||||
var onloaded = function(uint8array) {
|
||||
$scope.downloading = false;
|
||||
processBuildPack(uint8array);
|
||||
};
|
||||
|
||||
DataFileService.downloadDataFileAsArrayBuffer($scope, url, onprogress, onerror, onloaded);
|
||||
};
|
||||
|
||||
var getBuildInfo = function() {
|
||||
$scope.repository_build = ApiService.getRepoBuildStatus(null, params, true).then(function(resp) {
|
||||
if (!resp['is_writer']) {
|
||||
$rootScope.title = 'Unknown build';
|
||||
$scope.accessDenied = true;
|
||||
return;
|
||||
}
|
||||
|
||||
$rootScope.title = 'Repository Build Pack - ' + resp['display_name'];
|
||||
$scope.repobuild = resp;
|
||||
$scope.repo = {
|
||||
'namespace': namespace,
|
||||
'name': name
|
||||
};
|
||||
|
||||
downloadBuildPack(resp['archive_url']);
|
||||
return resp;
|
||||
});
|
||||
};
|
||||
|
||||
getBuildInfo();
|
||||
}
|
||||
})();
|
|
@ -1,20 +0,0 @@
|
|||
(function() {
|
||||
/**
|
||||
* Experiment enable page: New layout
|
||||
*/
|
||||
angular.module('quayPages').config(['pages', function(pages) {
|
||||
pages.create('exp-new-layout', 'exp-new-layout.html', ExpCtrl, {
|
||||
'newLayout': true
|
||||
});
|
||||
}]);
|
||||
|
||||
function ExpCtrl($scope, CookieService) {
|
||||
$scope.isEnabled = CookieService.get('quay.exp-new-layout') == 'true';
|
||||
|
||||
$scope.setEnabled = function(value) {
|
||||
$scope.isEnabled = value;
|
||||
CookieService.putPermanent('quay.exp-new-layout', value.toString());
|
||||
document.location.reload();
|
||||
};
|
||||
}
|
||||
}());
|
|
@ -7,10 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': '{{ image.id }}',
|
||||
'description': 'Image {{ image.id }}'
|
||||
}, ['layout'])
|
||||
|
||||
pages.create('image-view', 'old-image-view.html', OldImageViewCtrl, {
|
||||
}, ['old-layout']);
|
||||
})
|
||||
}]);
|
||||
|
||||
function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, ImageMetadataService) {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
});
|
||||
|
||||
UserService.updateUserIn($scope, function(user) {
|
||||
if (!user.anonymous && Config.isNewLayout()) {
|
||||
if (!user.anonymous) {
|
||||
$location.path('/repository');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,12 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': 'Manage Application {{ application.name }}',
|
||||
'description': 'Manage an OAuth application'
|
||||
}, ['layout']);
|
||||
|
||||
pages.create('manage-application', 'old-manage-application.html', ManageApplicationCtrl, {
|
||||
'title': 'Manage Application {{ application.name }}',
|
||||
'description': 'Manage an OAuth application'
|
||||
}, ['old-layout']);
|
||||
});
|
||||
}]);
|
||||
|
||||
function ManageApplicationCtrl($scope, $routeParams, $rootScope, $location, $timeout, OAuthService, ApiService, UserService, Config) {
|
||||
|
|
|
@ -7,12 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': 'New Organization',
|
||||
'description': 'Create a new organization to manage teams and permissions'
|
||||
}, ['layout']);
|
||||
|
||||
pages.create('new-organization', 'old-new-organization.html', NewOrgCtrl, {
|
||||
'title': 'New Organization',
|
||||
'description': 'Create a new organization to manage teams and permissions'
|
||||
}, ['old-layout']);
|
||||
});
|
||||
}]);
|
||||
|
||||
function NewOrgCtrl($scope, $routeParams, $timeout, $location, UserService, PlanService, ApiService, CookieService, Features) {
|
||||
|
|
|
@ -7,12 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': 'New Repository',
|
||||
'description': 'Create a new Docker repository'
|
||||
}, ['layout'])
|
||||
|
||||
pages.create('new-repo', 'old-new-repo.html', NewRepoCtrl, {
|
||||
'title': 'New Repository',
|
||||
'description': 'Create a new Docker repository'
|
||||
}, ['old-layout']);
|
||||
})
|
||||
}]);
|
||||
|
||||
function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService, PlanService, TriggerService, Features) {
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
(function() {
|
||||
/**
|
||||
* DEPRECATED: Organization admin/settings page.
|
||||
*/
|
||||
angular.module('quayPages').config(['pages', function(pages) {
|
||||
pages.create('org-admin', 'org-admin.html', OrgAdminCtrl);
|
||||
}]);
|
||||
|
||||
function OrgAdminCtrl($rootScope, $scope, $timeout, Restangular, $routeParams, UserService, PlanService, ApiService, Features, UIService) {
|
||||
var orgname = $routeParams.orgname;
|
||||
|
||||
// Load the list of plans.
|
||||
if (Features.BILLING) {
|
||||
PlanService.getPlans(function(plans) {
|
||||
$scope.plans = plans;
|
||||
$scope.plan_map = {};
|
||||
|
||||
for (var i = 0; i < plans.length; ++i) {
|
||||
$scope.plan_map[plans[i].stripeId] = plans[i];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.orgname = orgname;
|
||||
$scope.membersLoading = true;
|
||||
$scope.membersFound = null;
|
||||
$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++;
|
||||
};
|
||||
|
||||
$scope.planChanged = function(plan) {
|
||||
$scope.hasPaidPlan = plan && plan.price > 0;
|
||||
};
|
||||
|
||||
$scope.$watch('organizationEmail', function(e) {
|
||||
UIService.hidePopover('#changeEmailForm');
|
||||
});
|
||||
|
||||
$scope.changeEmail = function() {
|
||||
UIService.hidePopover('#changeEmailForm');
|
||||
|
||||
$scope.changingOrganization = true;
|
||||
var params = {
|
||||
'orgname': orgname
|
||||
};
|
||||
|
||||
var data = {
|
||||
'email': $scope.organizationEmail
|
||||
};
|
||||
|
||||
ApiService.changeOrganizationDetails(data, params).then(function(org) {
|
||||
$scope.changingOrganization = false;
|
||||
$scope.changeEmailForm.$setPristine();
|
||||
$scope.organization = org;
|
||||
}, function(result) {
|
||||
$scope.changingOrganization = false;
|
||||
UIService.showFormError('#changeEmailForm', result);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.loadMembers = function() {
|
||||
if ($scope.membersFound) { return; }
|
||||
$scope.membersLoading = true;
|
||||
|
||||
var params = {
|
||||
'orgname': orgname
|
||||
};
|
||||
|
||||
ApiService.getOrganizationMembers(null, params).then(function(resp) {
|
||||
var membersArray = [];
|
||||
for (var key in resp.members) {
|
||||
if (resp.members.hasOwnProperty(key)) {
|
||||
membersArray.push(resp.members[key]);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.membersFound = membersArray;
|
||||
$scope.membersLoading = false;
|
||||
});
|
||||
};
|
||||
|
||||
var loadOrganization = function() {
|
||||
$scope.orgResource = ApiService.getOrganizationAsResource({'orgname': orgname}).get(function(org) {
|
||||
if (org && org.is_admin) {
|
||||
$scope.organization = org;
|
||||
$scope.organizationEmail = org.email;
|
||||
$rootScope.title = orgname + ' (Admin)';
|
||||
$rootScope.description = 'Administration page for organization ' + orgname;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Load the organization.
|
||||
loadOrganization();
|
||||
}
|
||||
})();
|
|
@ -1,49 +0,0 @@
|
|||
(function() {
|
||||
/**
|
||||
* Page for displaying the logs of a member in an organization.
|
||||
*/
|
||||
angular.module('quayPages').config(['pages', function(pages) {
|
||||
pages.create('org-member-logs', 'org-member-logs.html', OrgMemberLogsCtrl);
|
||||
}]);
|
||||
|
||||
function OrgMemberLogsCtrl($scope, $routeParams, $rootScope, $timeout, Restangular, ApiService) {
|
||||
var orgname = $routeParams.orgname;
|
||||
var membername = $routeParams.membername;
|
||||
|
||||
$scope.orgname = orgname;
|
||||
$scope.memberInfo = null;
|
||||
$scope.ready = false;
|
||||
|
||||
var loadOrganization = function() {
|
||||
$scope.orgResource = ApiService.getOrganizationAsResource({'orgname': orgname}).get(function(org) {
|
||||
$scope.organization = org;
|
||||
return org;
|
||||
});
|
||||
};
|
||||
|
||||
var loadMemberInfo = function() {
|
||||
var params = {
|
||||
'orgname': orgname,
|
||||
'membername': membername
|
||||
};
|
||||
|
||||
$scope.memberResource = ApiService.getOrganizationMemberAsResource(params).get(function(resp) {
|
||||
$scope.memberInfo = resp.member;
|
||||
|
||||
$rootScope.title = 'Logs for ' + $scope.memberInfo.name + ' (' + $scope.orgname + ')';
|
||||
$rootScope.description = 'Shows all the actions of ' + $scope.memberInfo.username +
|
||||
' under organization ' + $scope.orgname;
|
||||
|
||||
$timeout(function() {
|
||||
$scope.ready = true;
|
||||
});
|
||||
|
||||
return resp.member;
|
||||
});
|
||||
};
|
||||
|
||||
// Load the org info and the member info.
|
||||
loadOrganization();
|
||||
loadMemberInfo();
|
||||
}
|
||||
})();
|
|
@ -7,10 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': 'Organization {{ organization.name }}',
|
||||
'description': 'Organization {{ organization.name }}'
|
||||
}, ['layout'])
|
||||
|
||||
pages.create('org-view', 'old-org-view.html', OldOrgViewCtrl, {
|
||||
}, ['old-layout']);
|
||||
})
|
||||
}]);
|
||||
|
||||
function OrgViewCtrl($scope, $routeParams, $timeout, ApiService, UIService, AvatarService) {
|
||||
|
|
|
@ -1,399 +0,0 @@
|
|||
(function() {
|
||||
/**
|
||||
* DEPRECATED: Repository admin/settings page.
|
||||
*/
|
||||
angular.module('quayPages').config(['pages', function(pages) {
|
||||
pages.create('repo-admin', 'repo-admin.html', RepoAdminCtrl);
|
||||
}]);
|
||||
|
||||
function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerService, $routeParams,
|
||||
$rootScope, $location, UserService, Config, Features, ExternalNotificationData, UtilService) {
|
||||
|
||||
var namespace = $routeParams.namespace;
|
||||
var name = $routeParams.name;
|
||||
|
||||
$scope.Features = Features;
|
||||
$scope.TriggerService = TriggerService;
|
||||
$scope.KeyService = KeyService;
|
||||
|
||||
$scope.permissions = {'team': [], 'user': [], 'loading': 2};
|
||||
$scope.logsShown = 0;
|
||||
$scope.deleting = false;
|
||||
|
||||
$scope.permissionCache = {};
|
||||
$scope.showTriggerSetupCounter = 0;
|
||||
|
||||
$scope.getBadgeFormat = function(format, repo) {
|
||||
if (!repo) { return; }
|
||||
|
||||
var imageUrl = Config.getUrl('/repository/' + namespace + '/' + name + '/status');
|
||||
if (!$scope.repo.is_public) {
|
||||
imageUrl += '?token=' + $scope.repo.status_token;
|
||||
}
|
||||
|
||||
var linkUrl = Config.getUrl('/repository/' + namespace + '/' + name);
|
||||
|
||||
switch (format) {
|
||||
case 'svg':
|
||||
return imageUrl;
|
||||
|
||||
case 'md':
|
||||
return '[](' + linkUrl + ')';
|
||||
|
||||
case 'asciidoc':
|
||||
return 'image:' + imageUrl + '["Docker Repository on ' + Config.REGISTRY_TITLE_SHORT + '", link="' + linkUrl + '"]';
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
$scope.buildEntityForPermission = function(name, permission, kind) {
|
||||
var key = name + ':' + kind;
|
||||
if ($scope.permissionCache[key]) {
|
||||
return $scope.permissionCache[key];
|
||||
}
|
||||
|
||||
return $scope.permissionCache[key] = {
|
||||
'kind': kind,
|
||||
'name': name,
|
||||
'is_robot': permission.is_robot,
|
||||
'is_org_member': permission.is_org_member
|
||||
};
|
||||
};
|
||||
|
||||
$scope.loadLogs = function() {
|
||||
$scope.logsShown++;
|
||||
};
|
||||
|
||||
$scope.grantRole = function() {
|
||||
$('#confirmaddoutsideModal').modal('hide');
|
||||
var entity = $scope.currentAddEntity;
|
||||
$scope.addRole(entity.name, 'read', entity.kind, entity.is_org_member)
|
||||
$scope.currentAddEntity = null;
|
||||
};
|
||||
|
||||
$scope.addNewPermission = function(entity) {
|
||||
// Don't allow duplicates.
|
||||
if (!entity || !entity.kind || $scope.permissions[entity.kind][entity.name]) { return; }
|
||||
|
||||
if (entity.is_org_member === false) {
|
||||
$scope.currentAddEntity = entity;
|
||||
$('#confirmaddoutsideModal').modal('show');
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.addRole(entity.name, 'read', entity.kind);
|
||||
};
|
||||
|
||||
$scope.deleteRole = function(entityName, kind) {
|
||||
var errorHandler = ApiService.errorDisplay('Cannot change permission', function(resp) {
|
||||
if (resp.status == 409) {
|
||||
return 'Cannot change permission as you do not have the authority';
|
||||
}
|
||||
});
|
||||
|
||||
var permissionDelete = Restangular.one(UtilService.getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
||||
permissionDelete.customDELETE().then(function() {
|
||||
delete $scope.permissions[kind][entityName];
|
||||
}, errorHandler);
|
||||
};
|
||||
|
||||
$scope.addRole = function(entityName, role, kind) {
|
||||
var permission = {
|
||||
'role': role,
|
||||
};
|
||||
|
||||
var permissionPost = Restangular.one(UtilService.getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
||||
permissionPost.customPUT(permission).then(function(result) {
|
||||
$scope.permissions[kind][entityName] = result;
|
||||
}, ApiService.errorDisplay('Cannot change permission'));
|
||||
};
|
||||
|
||||
$scope.setRole = function(role, entityName, kind) {
|
||||
var permission = $scope.permissions[kind][entityName];
|
||||
var currentRole = permission.role;
|
||||
permission.role = role;
|
||||
|
||||
var permissionPut = Restangular.one(UtilService.getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
||||
permissionPut.customPUT(permission).then(function() {}, function(resp) {
|
||||
$scope.permissions[kind][entityName] = {'role': currentRole};
|
||||
$scope.changePermError = null;
|
||||
if (resp.status == 409 || resp.data) {
|
||||
$scope.changePermError = resp.data || '';
|
||||
$('#channgechangepermModal').modal({});
|
||||
} else {
|
||||
$('#cannotchangeModal').modal({});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.newTokenName = null;
|
||||
|
||||
$scope.createToken = function() {
|
||||
var data = {
|
||||
'friendlyName': $scope.newTokenName
|
||||
};
|
||||
|
||||
var params = {'repository': namespace + '/' + name};
|
||||
ApiService.createToken(data, params).then(function(newToken) {
|
||||
$scope.newTokenName = null;
|
||||
$scope.createTokenForm.$setPristine();
|
||||
$scope.tokens[newToken.code] = newToken;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteToken = function(tokenCode) {
|
||||
var params = {
|
||||
'repository': namespace + '/' + name,
|
||||
'code': tokenCode
|
||||
};
|
||||
|
||||
ApiService.deleteToken(null, params).then(function() {
|
||||
delete $scope.tokens[tokenCode];
|
||||
});
|
||||
};
|
||||
|
||||
$scope.changeTokenAccess = function(tokenCode, newAccess) {
|
||||
var role = {
|
||||
'role': newAccess
|
||||
};
|
||||
|
||||
var params = {
|
||||
'repository': namespace + '/' + name,
|
||||
'code': tokenCode
|
||||
};
|
||||
|
||||
ApiService.changeToken(role, params).then(function(updated) {
|
||||
$scope.tokens[updated.code] = updated;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.shownTokenCounter = 0;
|
||||
|
||||
$scope.showToken = function(tokenCode) {
|
||||
$scope.shownToken = $scope.tokens[tokenCode];
|
||||
$scope.shownTokenCounter++;
|
||||
};
|
||||
|
||||
$scope.askChangeAccess = function(newAccess) {
|
||||
$('#make' + newAccess + 'Modal').modal({});
|
||||
};
|
||||
|
||||
$scope.changeAccess = function(newAccess) {
|
||||
$('#make' + newAccess + 'Modal').modal('hide');
|
||||
|
||||
var visibility = {
|
||||
'visibility': newAccess
|
||||
};
|
||||
|
||||
var params = {
|
||||
'repository': namespace + '/' + name
|
||||
};
|
||||
|
||||
ApiService.changeRepoVisibility(visibility, params).then(function() {
|
||||
$scope.repo.is_public = newAccess == 'public';
|
||||
}, function() {
|
||||
$('#cannotchangeModal').modal({});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.askDelete = function() {
|
||||
$('#confirmdeleteModal').modal({});
|
||||
};
|
||||
|
||||
$scope.deleteRepo = function() {
|
||||
$('#confirmdeleteModal').modal('hide');
|
||||
|
||||
var params = {
|
||||
'repository': namespace + '/' + name
|
||||
};
|
||||
|
||||
$scope.deleting = true;
|
||||
ApiService.deleteRepository(null, params).then(function() {
|
||||
$scope.repo = null;
|
||||
|
||||
setTimeout(function() {
|
||||
document.location = '/repository/';
|
||||
}, 1000);
|
||||
}, function() {
|
||||
$scope.deleting = true;
|
||||
$('#cannotchangeModal').modal({});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showNewNotificationCounter = 0;
|
||||
|
||||
$scope.showNewNotificationDialog = function() {
|
||||
$scope.showNewNotificationCounter++;
|
||||
};
|
||||
|
||||
$scope.handleNotificationCreated = function(notification) {
|
||||
$scope.notifications.push(notification);
|
||||
};
|
||||
|
||||
$scope.handleNotificationDeleted = function(notification) {
|
||||
var index = $.inArray(notification, $scope.notifications);
|
||||
if (index < 0) { return; }
|
||||
$scope.notifications.splice(index, 1);
|
||||
};
|
||||
|
||||
$scope.loadNotifications = function() {
|
||||
var params = {
|
||||
'repository': namespace + '/' + name
|
||||
};
|
||||
|
||||
$scope.notificationsResource = ApiService.listRepoNotificationsAsResource(params).get(
|
||||
function(resp) {
|
||||
$scope.notifications = resp.notifications;
|
||||
return $scope.notifications;
|
||||
});
|
||||
};
|
||||
|
||||
$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.currentSetupTrigger = trigger;
|
||||
$scope.showTriggerSetupCounter++;
|
||||
};
|
||||
|
||||
$scope.cancelSetupTrigger = function(trigger) {
|
||||
if ($scope.currentSetupTrigger != trigger) { return; }
|
||||
|
||||
$scope.currentSetupTrigger = null;
|
||||
$scope.deleteTrigger(trigger);
|
||||
};
|
||||
|
||||
$scope.showManualBuildDialog = 0;
|
||||
|
||||
$scope.startTrigger = function(trigger, opt_custom) {
|
||||
var parameters = TriggerService.getRunParameters(trigger.service);
|
||||
if (parameters.length && !opt_custom) {
|
||||
$scope.currentStartTrigger = trigger;
|
||||
$scope.showManualBuildDialog++;
|
||||
return;
|
||||
}
|
||||
|
||||
var params = {
|
||||
'repository': namespace + '/' + name,
|
||||
'trigger_uuid': trigger.id
|
||||
};
|
||||
|
||||
ApiService.manuallyStartBuildTrigger(opt_custom || {}, params).then(function(resp) {
|
||||
var url = '/repository/' + namespace + '/' + name + '/build?current=' + resp['id'];
|
||||
document.location = url;
|
||||
}, ApiService.errorDisplay('Could not start build'));
|
||||
};
|
||||
|
||||
$scope.deleteTrigger = function(trigger) {
|
||||
if (!trigger) { return; }
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
ApiService.listRepoTokens(null, params).then(function(resp) {
|
||||
$scope.tokens = resp.tokens;
|
||||
}, function() {
|
||||
$scope.tokens = null;
|
||||
});
|
||||
};
|
||||
|
||||
var fetchPermissions = function(kind) {
|
||||
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/');
|
||||
permissionsFetch.get().then(function(resp) {
|
||||
$scope.permissions[kind] = resp.permissions;
|
||||
$scope.permissions['loading']--;
|
||||
}, function() {
|
||||
$scope.permissions[kind] = null;
|
||||
});
|
||||
};
|
||||
|
||||
var fetchRepository = function() {
|
||||
var params = {
|
||||
'repository': namespace + '/' + name
|
||||
};
|
||||
|
||||
$scope.repository = ApiService.getRepoAsResource(params).get(function(repo) {
|
||||
if (!repo.can_admin) {
|
||||
$rootScope.title = 'Forbidden';
|
||||
$scope.accessDenied = true;
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.repo = repo;
|
||||
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
||||
$rootScope.description = 'Administrator settings for ' + namespace + '/' + name +
|
||||
': Permissions, notifications and other settings';
|
||||
|
||||
// Fetch all the permissions and token info for the repository.
|
||||
fetchPermissions('user');
|
||||
fetchPermissions('team');
|
||||
fetchTokens();
|
||||
|
||||
$('.info-icon').popover({
|
||||
'trigger': 'hover',
|
||||
'html': true
|
||||
});
|
||||
|
||||
return $scope.repo;
|
||||
});
|
||||
};
|
||||
|
||||
// Fetch the repository.
|
||||
fetchRepository();
|
||||
}
|
||||
})();
|
|
@ -1,294 +0,0 @@
|
|||
(function() {
|
||||
/**
|
||||
* Repository Build view page. Displays the status of a repository build.
|
||||
*/
|
||||
angular.module('quayPages').config(['pages', function(pages) {
|
||||
pages.create('repo-build', 'repo-build.html', RepoBuildCtrl);
|
||||
}]);
|
||||
|
||||
function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $location, $interval, $sanitize,
|
||||
ansi2html, AngularViewArray, AngularPollChannel) {
|
||||
var namespace = $routeParams.namespace;
|
||||
var name = $routeParams.name;
|
||||
|
||||
// Watch for changes to the current parameter.
|
||||
$scope.$on('$routeUpdate', function(){
|
||||
if ($location.search().current) {
|
||||
$scope.setCurrentBuild($location.search().current, false);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.builds = null;
|
||||
$scope.pollChannel = null;
|
||||
$scope.buildDialogShowCounter = 0;
|
||||
|
||||
$scope.showNewBuildDialog = function() {
|
||||
$scope.buildDialogShowCounter++;
|
||||
};
|
||||
|
||||
$scope.handleBuildStarted = function(newBuild) {
|
||||
if (!$scope.builds) { return; }
|
||||
|
||||
$scope.builds.unshift(newBuild);
|
||||
$scope.setCurrentBuild(newBuild['id'], true);
|
||||
};
|
||||
|
||||
$scope.adjustLogHeight = function() {
|
||||
var triggerOffset = 0;
|
||||
if ($scope.currentBuild && $scope.currentBuild.trigger) {
|
||||
triggerOffset = 85;
|
||||
}
|
||||
$('.build-logs').height($(window).height() - 415 - triggerOffset);
|
||||
};
|
||||
|
||||
$scope.askRestartBuild = function(build) {
|
||||
$('#confirmRestartBuildModal').modal({});
|
||||
};
|
||||
|
||||
$scope.askCancelBuild = function(build) {
|
||||
bootbox.confirm('Are you sure you want to cancel this build?', function(r) {
|
||||
if (r) {
|
||||
var params = {
|
||||
'repository': namespace + '/' + name,
|
||||
'build_uuid': build.id
|
||||
};
|
||||
|
||||
ApiService.cancelRepoBuild(null, params).then(function() {
|
||||
if (!$scope.builds) { return; }
|
||||
$scope.builds.splice($.inArray(build, $scope.builds), 1);
|
||||
|
||||
if ($scope.builds.length) {
|
||||
$scope.currentBuild = $scope.builds[0];
|
||||
} else {
|
||||
$scope.currentBuild = null;
|
||||
}
|
||||
}, ApiService.errorDisplay('Cannot cancel build'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.restartBuild = function(build) {
|
||||
$('#confirmRestartBuildModal').modal('hide');
|
||||
|
||||
var subdirectory = build['subdirectory'] || '';
|
||||
|
||||
var data = {
|
||||
'file_id': build['resource_key'],
|
||||
'subdirectory': subdirectory,
|
||||
'docker_tags': build['tags']
|
||||
};
|
||||
|
||||
if (build['pull_robot']) {
|
||||
data['pull_robot'] = build['pull_robot']['name'];
|
||||
}
|
||||
|
||||
var params = {
|
||||
'repository': namespace + '/' + name
|
||||
};
|
||||
|
||||
ApiService.requestRepoBuild(data, params).then(function(newBuild) {
|
||||
if (!$scope.builds) { return; }
|
||||
|
||||
$scope.builds.unshift(newBuild);
|
||||
$scope.setCurrentBuild(newBuild['id'], true);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.hasLogs = function(container) {
|
||||
return container.logs.hasEntries;
|
||||
};
|
||||
|
||||
$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) {
|
||||
$scope.setCurrentBuildInternal(i, $scope.builds[i], opt_updateURL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.processANSI = function(message, container) {
|
||||
var filter = container.logs._filter = (container.logs._filter || ansi2html.create());
|
||||
|
||||
// Note: order is important here.
|
||||
var setup = filter.getSetupHtml();
|
||||
var stream = filter.addInputToStream(message);
|
||||
var teardown = filter.getTeardownHtml();
|
||||
return setup + stream + teardown;
|
||||
};
|
||||
|
||||
$scope.setCurrentBuildInternal = function(index, build, opt_updateURL) {
|
||||
if (build == $scope.currentBuild) { return; }
|
||||
|
||||
$scope.logEntries = null;
|
||||
$scope.logStartIndex = null;
|
||||
$scope.currentParentEntry = null;
|
||||
|
||||
$scope.currentBuild = build;
|
||||
|
||||
if (opt_updateURL) {
|
||||
if (build) {
|
||||
$location.search('current', build.id);
|
||||
} else {
|
||||
$location.search('current', null);
|
||||
}
|
||||
}
|
||||
|
||||
// Timeout needed to ensure the log element has been created
|
||||
// before its height is adjusted.
|
||||
setTimeout(function() {
|
||||
$scope.adjustLogHeight();
|
||||
}, 1);
|
||||
|
||||
// Stop any existing polling.
|
||||
if ($scope.pollChannel) {
|
||||
$scope.pollChannel.stop();
|
||||
}
|
||||
|
||||
// Create a new channel for polling the build status and logs.
|
||||
var conductStatusAndLogRequest = function(callback) {
|
||||
getBuildStatusAndLogs(build, callback);
|
||||
};
|
||||
|
||||
$scope.pollChannel = AngularPollChannel.create($scope, conductStatusAndLogRequest, 5 * 1000 /* 5s */);
|
||||
$scope.pollChannel.start();
|
||||
};
|
||||
|
||||
var processLogs = function(logs, startIndex, endIndex) {
|
||||
if (!$scope.logEntries) { $scope.logEntries = []; }
|
||||
|
||||
// If the start index given is less than that requested, then we've received a larger
|
||||
// pool of logs, and we need to only consider the new ones.
|
||||
if (startIndex < $scope.logStartIndex) {
|
||||
logs = logs.slice($scope.logStartIndex - startIndex);
|
||||
}
|
||||
|
||||
for (var i = 0; i < logs.length; ++i) {
|
||||
var entry = logs[i];
|
||||
var type = entry['type'] || 'entry';
|
||||
if (type == 'command' || type == 'phase' || type == 'error') {
|
||||
entry['logs'] = AngularViewArray.create();
|
||||
entry['index'] = $scope.logStartIndex + i;
|
||||
|
||||
$scope.logEntries.push(entry);
|
||||
$scope.currentParentEntry = entry;
|
||||
} else if ($scope.currentParentEntry) {
|
||||
$scope.currentParentEntry['logs'].push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return endIndex;
|
||||
};
|
||||
|
||||
var handleLogsData = function(logsData, callback) {
|
||||
// Process the logs we've received.
|
||||
$scope.logStartIndex = processLogs(logsData['logs'], logsData['start'], logsData['total']);
|
||||
|
||||
// If the build status is an error, open the last two log entries.
|
||||
var currentBuild = $scope.currentBuild;
|
||||
if (currentBuild['phase'] == 'error' && $scope.logEntries.length > 1) {
|
||||
var openLogEntries = function(entry) {
|
||||
if (entry.logs) {
|
||||
entry.logs.setVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
openLogEntries($scope.logEntries[$scope.logEntries.length - 2]);
|
||||
openLogEntries($scope.logEntries[$scope.logEntries.length - 1]);
|
||||
}
|
||||
|
||||
// If the build phase is an error or a complete, then we mark the channel
|
||||
// as closed.
|
||||
callback(currentBuild['phase'] != 'error' && currentBuild['phase'] != 'complete');
|
||||
};
|
||||
|
||||
var getBuildStatusAndLogs = function(build, callback) {
|
||||
var params = {
|
||||
'repository': namespace + '/' + name,
|
||||
'build_uuid': build.id
|
||||
};
|
||||
|
||||
ApiService.getRepoBuildStatus(null, params, true).then(function(resp) {
|
||||
if (build != $scope.currentBuild) { callback(false); return; }
|
||||
|
||||
// Note: We use extend here rather than replacing as Angular is depending on the
|
||||
// root build object to remain the same object.
|
||||
var matchingBuilds = $.grep($scope.builds, function(elem) {
|
||||
return elem['id'] == resp['id']
|
||||
});
|
||||
|
||||
var currentBuild = matchingBuilds.length > 0 ? matchingBuilds[0] : null;
|
||||
if (currentBuild) {
|
||||
currentBuild = $.extend(true, currentBuild, resp);
|
||||
} else {
|
||||
currentBuild = resp;
|
||||
$scope.builds.push(currentBuild);
|
||||
}
|
||||
|
||||
// Load the updated logs for the build.
|
||||
var options = {
|
||||
'start': $scope.logStartIndex
|
||||
};
|
||||
|
||||
ApiService.getRepoBuildLogsAsResource(params, true).withOptions(options).get(function(resp) {
|
||||
if (build != $scope.currentBuild) { callback(false); return; }
|
||||
|
||||
// If we get a logs url back, then we need to make another XHR request to retrieve the
|
||||
// data.
|
||||
if (resp['logs_url']) {
|
||||
$.ajax({
|
||||
url: resp['logs_url'],
|
||||
}).done(function(r) {
|
||||
handleLogsData(r, callback);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
handleLogsData(resp, callback);
|
||||
}, function() {
|
||||
callback(false);
|
||||
});
|
||||
}, function() {
|
||||
callback(false);
|
||||
});
|
||||
};
|
||||
|
||||
var fetchRepository = function() {
|
||||
var params = {'repository': namespace + '/' + name};
|
||||
$rootScope.title = 'Loading Repository...';
|
||||
$scope.repository = ApiService.getRepoAsResource(params).get(function(repo) {
|
||||
if (!repo.can_write) {
|
||||
$rootScope.title = 'Unknown builds';
|
||||
$scope.accessDenied = true;
|
||||
return;
|
||||
}
|
||||
|
||||
$rootScope.title = 'Repository Builds';
|
||||
$scope.repo = repo;
|
||||
|
||||
getBuildInfo();
|
||||
});
|
||||
};
|
||||
|
||||
var getBuildInfo = function(repo) {
|
||||
var params = {
|
||||
'repository': namespace + '/' + name
|
||||
};
|
||||
|
||||
ApiService.getRepoBuilds(null, params).then(function(resp) {
|
||||
$scope.builds = resp.builds;
|
||||
|
||||
if ($location.search().current) {
|
||||
$scope.setCurrentBuild($location.search().current, false);
|
||||
} else if ($scope.builds.length > 0) {
|
||||
$scope.setCurrentBuild($scope.builds[0].id, true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
fetchRepository();
|
||||
}
|
||||
})();
|
|
@ -7,12 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': 'Repositories',
|
||||
'description': 'View and manage Docker repositories'
|
||||
}, ['layout'])
|
||||
|
||||
pages.create('repo-list', 'old-repo-list.html', OldRepoListCtrl, {
|
||||
'title': 'Repositories',
|
||||
'description': 'View and manage Docker repositories'
|
||||
}, ['old-layout']);
|
||||
})
|
||||
}]);
|
||||
|
||||
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': '{{ namespace }}/{{ name }}',
|
||||
'description': 'Repository {{ namespace }}/{{ name }}'
|
||||
}, ['layout'])
|
||||
|
||||
pages.create('repo-view', 'old-repo-view.html', OldRepoViewCtrl, {
|
||||
}, ['old-layout']);
|
||||
})
|
||||
}]);
|
||||
|
||||
function RepoViewCtrl($scope, $routeParams, $location, $timeout, ApiService, UserService, AngularPollChannel) {
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
{
|
||||
'newLayout': true,
|
||||
'title': 'Enterprise Registry Setup'
|
||||
},
|
||||
|
||||
// Note: This page has already been converted, but also needs to be available in the old layout
|
||||
['layout', 'old-layout'])
|
||||
})
|
||||
}]);
|
||||
|
||||
function SetupCtrl($scope, $timeout, ApiService, Features, UserService, ContainerService, CoreDialog) {
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
{
|
||||
'newLayout': true,
|
||||
'title': 'Enterprise Registry Management'
|
||||
},
|
||||
|
||||
// Note: This page has already been converted, but also needs to be available in the old layout
|
||||
['layout', 'old-layout'])
|
||||
})
|
||||
}]);
|
||||
|
||||
function SuperuserCtrl($scope, $timeout, ApiService, Features, UserService, ContainerService, AngularPollChannel, CoreDialog) {
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': 'Team {{ teamname }}',
|
||||
'description': 'Team {{ teamname }}'
|
||||
}, ['layout'])
|
||||
|
||||
pages.create('team-view', 'old-team-view.html', TeamViewCtrl, {
|
||||
}, ['old-layout']);
|
||||
})
|
||||
}]);
|
||||
|
||||
function TeamViewCtrl($rootScope, $scope, $timeout, Features, Restangular, ApiService, $routeParams) {
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': 'Tutorial',
|
||||
'description': 'Basic tutorial on using Quay.io'
|
||||
}, ['layout'])
|
||||
|
||||
pages.create('tutorial', 'old-tutorial.html', TutorialCtrl, {
|
||||
}, ['old-layout']);
|
||||
})
|
||||
}]);
|
||||
|
||||
function TutorialCtrl($scope, AngularTour, AngularTourSignals, UserService, Config, Features) {
|
||||
|
|
|
@ -1,222 +0,0 @@
|
|||
(function() {
|
||||
/**
|
||||
* DEPRECATED: User admin/settings page.
|
||||
*/
|
||||
angular.module('quayPages').config(['pages', function(pages) {
|
||||
pages.create('user-admin', 'user-admin.html', UserAdminCtrl, {
|
||||
'title': 'User Settings'
|
||||
});
|
||||
}]);
|
||||
|
||||
function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, UserService, CookieService, KeyService,
|
||||
$routeParams, $http, UIService, Features, Config) {
|
||||
$scope.Features = Features;
|
||||
|
||||
if ($routeParams['migrate']) {
|
||||
$('#migrateTab').tab('show')
|
||||
}
|
||||
|
||||
UserService.updateUserIn($scope, function(user) {
|
||||
$scope.cuser = jQuery.extend({}, user);
|
||||
|
||||
if ($scope.cuser.logins) {
|
||||
for (var i = 0; i < $scope.cuser.logins.length; i++) {
|
||||
var login = $scope.cuser.logins[i];
|
||||
login.metadata = login.metadata || {};
|
||||
|
||||
if (login.service == 'github') {
|
||||
$scope.hasGithubLogin = true;
|
||||
$scope.githubLogin = login.metadata['service_username'];
|
||||
$scope.githubEndpoint = KeyService['githubEndpoint'];
|
||||
}
|
||||
|
||||
if (login.service == 'google') {
|
||||
$scope.hasGoogleLogin = true;
|
||||
$scope.googleLogin = login.metadata['service_username'];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.readyForPlan = function() {
|
||||
// Show the subscribe dialog if a plan was requested.
|
||||
return $routeParams['plan'];
|
||||
};
|
||||
|
||||
$scope.loading = true;
|
||||
$scope.updatingUser = false;
|
||||
$scope.changePasswordSuccess = false;
|
||||
$scope.changeEmailSent = false;
|
||||
$scope.convertStep = 0;
|
||||
$scope.org = {};
|
||||
$scope.githubRedirectUri = KeyService.githubRedirectUri;
|
||||
$scope.authorizedApps = null;
|
||||
|
||||
$scope.logsShown = 0;
|
||||
$scope.invoicesShown = 0;
|
||||
|
||||
$scope.USER_PATTERN = USER_PATTERN;
|
||||
|
||||
$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);
|
||||
}, ApiService.errorDisplay('Could not revoke authorization'));
|
||||
};
|
||||
|
||||
$scope.loadLogs = function() {
|
||||
if (!$scope.hasPaidBusinessPlan) { return; }
|
||||
$scope.logsShown++;
|
||||
};
|
||||
|
||||
$scope.loadInvoices = function() {
|
||||
$scope.invoicesShown++;
|
||||
};
|
||||
|
||||
$scope.planChanged = function(plan) {
|
||||
$scope.hasPaidPlan = plan && plan.price > 0;
|
||||
$scope.hasPaidBusinessPlan = PlanService.isOrgCompatible(plan) && plan.price > 0;
|
||||
};
|
||||
|
||||
$scope.showConvertForm = function() {
|
||||
if (Features.BILLING) {
|
||||
PlanService.getMatchingBusinessPlan(function(plan) {
|
||||
$scope.org.plan = plan;
|
||||
});
|
||||
|
||||
PlanService.getPlans(function(plans) {
|
||||
$scope.orgPlans = plans;
|
||||
});
|
||||
}
|
||||
|
||||
$scope.convertStep = 1;
|
||||
};
|
||||
|
||||
$scope.convertToOrg = function() {
|
||||
$('#reallyconvertModal').modal({});
|
||||
};
|
||||
|
||||
$scope.reallyConvert = function() {
|
||||
if (Config.AUTHENTICATION_TYPE != 'Database') { return; }
|
||||
|
||||
$scope.loading = true;
|
||||
|
||||
var data = {
|
||||
'adminUser': $scope.org.adminUser,
|
||||
'adminPassword': $scope.org.adminPassword,
|
||||
'plan': $scope.org.plan ? $scope.org.plan.stripeId : ''
|
||||
};
|
||||
|
||||
ApiService.convertUserToOrganization(data).then(function(resp) {
|
||||
CookieService.putPermanent('quay.namespace', $scope.cuser.username);
|
||||
UserService.load();
|
||||
$location.path('/');
|
||||
}, function(resp) {
|
||||
$scope.loading = false;
|
||||
if (resp.data.reason == 'invaliduser') {
|
||||
$('#invalidadminModal').modal({});
|
||||
} else {
|
||||
$('#cannotconvertModal').modal({});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.changeUsername = function() {
|
||||
UserService.load();
|
||||
|
||||
$scope.updatingUser = true;
|
||||
|
||||
ApiService.changeUserDetails($scope.cuser).then(function() {
|
||||
$scope.updatingUser = false;
|
||||
|
||||
// Reset the form.
|
||||
delete $scope.cuser['username'];
|
||||
|
||||
$scope.changeUsernameForm.$setPristine();
|
||||
}, function(result) {
|
||||
$scope.updatingUser = false;
|
||||
UIService.showFormError('#changeUsernameForm', result);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.changeEmail = function() {
|
||||
UIService.hidePopover('#changeEmailForm');
|
||||
|
||||
$scope.updatingUser = true;
|
||||
$scope.changeEmailSent = false;
|
||||
|
||||
ApiService.changeUserDetails($scope.cuser).then(function() {
|
||||
$scope.updatingUser = false;
|
||||
$scope.changeEmailSent = true;
|
||||
$scope.sentEmail = $scope.cuser.email;
|
||||
delete $scope.cuser['email'];
|
||||
}, function(result) {
|
||||
$scope.updatingUser = false;
|
||||
UIService.showFormError('#changeEmailForm', result);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.changePassword = function() {
|
||||
UIService.hidePopover('#changePasswordForm');
|
||||
|
||||
$scope.updatingUser = true;
|
||||
$scope.changePasswordSuccess = false;
|
||||
|
||||
ApiService.changeUserDetails($scope.cuser).then(function(resp) {
|
||||
|
||||
$scope.updatingUser = false;
|
||||
$scope.changePasswordSuccess = true;
|
||||
|
||||
// Reset the form
|
||||
delete $scope.cuser['password']
|
||||
delete $scope.cuser['repeatPassword']
|
||||
|
||||
$scope.changePasswordForm.$setPristine();
|
||||
|
||||
// Reload the user.
|
||||
UserService.load();
|
||||
}, function(result) {
|
||||
$scope.updatingUser = false;
|
||||
UIService.showFormError('#changePasswordForm', result);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.generateClientToken = function() {
|
||||
var generateToken = function(password) {
|
||||
var data = {
|
||||
'password': password
|
||||
};
|
||||
|
||||
ApiService.generateUserClientKey(data).then(function(resp) {
|
||||
$scope.generatedClientToken = resp['key'];
|
||||
$('#clientTokenModal').modal({});
|
||||
}, ApiService.errorDisplay('Could not generate token'));
|
||||
};
|
||||
|
||||
UIService.showPasswordDialog('Enter your password to generated an encrypted version:', generateToken);
|
||||
};
|
||||
|
||||
$scope.detachExternalLogin = function(kind) {
|
||||
var params = {
|
||||
'servicename': kind
|
||||
};
|
||||
|
||||
ApiService.detachExternalLogin(null, params).then(function() {
|
||||
$scope.hasGithubLogin = false;
|
||||
$scope.hasGoogleLogin = false;
|
||||
UserService.load();
|
||||
}, ApiService.errorDisplay('Count not detach service'));
|
||||
};
|
||||
}
|
||||
})();
|
|
@ -7,7 +7,7 @@
|
|||
'newLayout': true,
|
||||
'title': 'User {{ user.username }}',
|
||||
'description': 'User {{ user.username }}'
|
||||
}, ['layout'])
|
||||
})
|
||||
}]);
|
||||
|
||||
function UserViewCtrl($scope, $routeParams, $timeout, ApiService, UserService, UIService, AvatarService) {
|
||||
|
|
|
@ -14,9 +14,7 @@ angular.module('quay').factory('AvatarService', ['Config', '$sanitize', 'md5',
|
|||
break;
|
||||
|
||||
case 'gravatar':
|
||||
// TODO(jschorr): Remove once the new layout is in place everywhere.
|
||||
var default_kind = Config.isNewLayout() ? '404' : 'identicon';
|
||||
return '//www.gravatar.com/avatar/' + hash + '?d=' + default_kind + '&size=' + size;
|
||||
return '//www.gravatar.com/avatar/' + hash + '?d=404&size=' + size;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -71,10 +71,5 @@ angular.module('quay').factory('Config', [function() {
|
|||
return value;
|
||||
};
|
||||
|
||||
config.isNewLayout = function() {
|
||||
// TODO(jschorr): Remove in the cleanup CL.
|
||||
return true;
|
||||
};
|
||||
|
||||
return config;
|
||||
}]);
|
|
@ -56,20 +56,10 @@ function($rootScope, $interval, UserService, ApiService, StringBuilderService, P
|
|||
'<br><br>Please upgrade your plan to avoid disruptions in service.',
|
||||
'page': function(metadata) {
|
||||
var organization = UserService.getOrganization(metadata['namespace']);
|
||||
|
||||
// TODO(jschorr): Remove once the new layout is in prod.
|
||||
if (Config.isNewLayout()) {
|
||||
if (organization) {
|
||||
return '/organization/' + metadata['namespace'] + '?tab=billing';
|
||||
} else {
|
||||
return '/user/' + metadata['namespace'] + '?tab=billing';
|
||||
}
|
||||
}
|
||||
|
||||
if (organization) {
|
||||
return '/organization/' + metadata['namespace'] + '/admin';
|
||||
return '/organization/' + metadata['namespace'] + '?tab=billing';
|
||||
} else {
|
||||
return '/user';
|
||||
return '/user/' + metadata['namespace'] + '?tab=billing';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Reference in a new issue