- Show the user's top repos if they have any - Show a link to the guide and the repos list if they do not - Add a getting starting guide - Redo the repos list to show the user's repos and the top 10 public repos separately
418 lines
No EOL
12 KiB
JavaScript
418 lines
No EOL
12 KiB
JavaScript
function getFirstTextLine(commentString) {
|
|
if (!commentString) { return; }
|
|
|
|
var lines = commentString.split('\n');
|
|
var MARKDOWN_CHARS = {
|
|
'#': true,
|
|
'-': true,
|
|
'>': true,
|
|
'`': true
|
|
};
|
|
|
|
for (var i = 0; i < lines.length; ++i) {
|
|
// Skip code lines.
|
|
if (lines[i].indexOf(' ') == 0) {
|
|
continue;
|
|
}
|
|
|
|
// Skip empty lines.
|
|
if ($.trim(lines[i]).length == 0) {
|
|
continue;
|
|
}
|
|
|
|
// Skip control lines.
|
|
if (MARKDOWN_CHARS[$.trim(lines[i])[0]]) {
|
|
continue;
|
|
}
|
|
|
|
return getMarkedDown(lines[i]);
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
function getMarkedDown(string) {
|
|
return Markdown.getSanitizingConverter().makeHtml(string || '');
|
|
}
|
|
|
|
function HeaderCtrl($scope, UserService) {
|
|
$scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
|
|
$scope.user = currentUser;
|
|
}, true);
|
|
|
|
$('#repoSearch').typeahead({
|
|
name: 'repositories',
|
|
remote: {
|
|
url: '/api/find/repository?query=%QUERY',
|
|
filter: function(data) {
|
|
var datums = [];
|
|
for (var i = 0; i < data.repositories.length; ++i) {
|
|
var repo = data.repositories[i];
|
|
datums.push({
|
|
'value': repo.name,
|
|
'tokens': [repo.name, repo.namespace],
|
|
'repo': repo
|
|
});
|
|
}
|
|
return datums;
|
|
}
|
|
},
|
|
template: function (datum) {
|
|
template = '<div class="repo-mini-listing">';
|
|
template += '<i class="icon-hdd icon-large"></i>'
|
|
template += '<span class="name">' + datum.repo.namespace +'/' + datum.repo.name + '</span>'
|
|
if (datum.repo.description) {
|
|
template += '<span class="description">' + getFirstTextLine(datum.repo.description) + '</span>'
|
|
}
|
|
|
|
template += '</div>'
|
|
return template;
|
|
},
|
|
|
|
});
|
|
|
|
$('#repoSearch').on('typeahead:selected', function (e, datum) {
|
|
$('#repoSearch').typeahead('setQuery', '');
|
|
document.location = '#/repository/' + datum.repo.namespace + '/' + datum.repo.name
|
|
});
|
|
}
|
|
|
|
function GuideCtrl($scope, Restangular) {
|
|
}
|
|
|
|
function RepoListCtrl($scope, Restangular) {
|
|
$scope.getCommentFirstLine = function(commentString) {
|
|
return getMarkedDown(getFirstTextLine(commentString));
|
|
};
|
|
|
|
$scope.getMarkedDown = function(string) {
|
|
if (!string) { return ''; }
|
|
return getMarkedDown(string);
|
|
};
|
|
|
|
$('.spin').spin();
|
|
$scope.loading = true;
|
|
$scope.public_repositories = null;
|
|
$scope.private_repositories = null;
|
|
|
|
// Load the list of personal repositories.
|
|
var repositoryPrivateFetch = Restangular.all('repository/');
|
|
repositoryPrivateFetch.getList({'public': false, 'sort': true}).then(function(resp) {
|
|
$scope.private_repositories = resp.repositories;
|
|
$scope.loading = !($scope.public_repositories && $scope.private_repositories);
|
|
});
|
|
|
|
// Load the list of public repositories.
|
|
var options = {'public': true, 'private': false, 'sort': true, 'limit': 10};
|
|
var repositoryPublicFetch = Restangular.all('repository/');
|
|
repositoryPublicFetch.getList(options).then(function(resp) {
|
|
$scope.public_repositories = resp.repositories;
|
|
$scope.loading = !($scope.public_repositories && $scope.private_repositories);
|
|
});
|
|
}
|
|
|
|
function LandingCtrl($scope, $timeout, Restangular, UserService) {
|
|
$('.form-signup').popover();
|
|
$('.spin').spin();
|
|
|
|
$scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
|
|
if (!currentUser.anonymous) {
|
|
$scope.loadMyRepos();
|
|
}
|
|
|
|
$scope.user = currentUser;
|
|
}, true);
|
|
|
|
$scope.awaitingConfirmation = false;
|
|
$scope.registering = false;
|
|
|
|
$scope.getCommentFirstLine = function(commentString) {
|
|
return getMarkedDown(getFirstTextLine(commentString));
|
|
};
|
|
|
|
$scope.browseRepos = function() {
|
|
document.location = '/#/repository';
|
|
};
|
|
|
|
$scope.register = function() {
|
|
$('.form-signup').popover('hide');
|
|
$scope.registering = true;
|
|
|
|
var newUserPost = Restangular.one('user/');
|
|
newUserPost.customPOST($scope.newUser).then(function() {
|
|
$scope.awaitingConfirmation = true;
|
|
$scope.registering = false;
|
|
}, function(result) {
|
|
console.log("Displaying error message.");
|
|
$scope.registering = false;
|
|
$scope.registerError = result.data.message;
|
|
$timeout(function() {
|
|
$('.form-signup').popover('show');
|
|
});
|
|
});
|
|
};
|
|
|
|
$scope.loadMyRepos = function() {
|
|
$scope.loadingmyrepos = true;
|
|
|
|
// Load the list of repositories.
|
|
var params = {
|
|
'limit': 5,
|
|
'public': false,
|
|
'sort': true
|
|
};
|
|
|
|
var repositoryFetch = Restangular.all('repository/');
|
|
repositoryFetch.getList(params).then(function(resp) {
|
|
$scope.myrepos = resp.repositories;
|
|
$scope.loadingmyrepos = false;
|
|
});
|
|
};
|
|
}
|
|
|
|
function RepoCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|
var tabs = ['current-image', 'image-history'];
|
|
|
|
$rootScope.title = 'Loading...';
|
|
|
|
$scope.showTab = function(tabName) {
|
|
for (var i = 0; i < tabs.length; ++i) {
|
|
$('#' + tabs[i]).hide();
|
|
$('#' + tabs[i] + '-tab').removeClass('active');
|
|
}
|
|
|
|
$('#' + tabName).show();
|
|
$('#' + tabName + '-tab').addClass('active');
|
|
|
|
if (tabName == 'image-history') {
|
|
$scope.listImages();
|
|
}
|
|
};
|
|
|
|
$scope.editDescription = function() {
|
|
if (!$scope.repo.can_write) { return; }
|
|
|
|
if (!$scope.markdownDescriptionEditor) {
|
|
var converter = Markdown.getSanitizingConverter();
|
|
var editor = new Markdown.Editor(converter, '-description');
|
|
editor.run();
|
|
$scope.markdownDescriptionEditor = editor;
|
|
}
|
|
|
|
$('#wmd-input-description')[0].value = $scope.repo.description;
|
|
$('#editModal').modal({});
|
|
};
|
|
|
|
$scope.saveDescription = function() {
|
|
$('#editModal').modal('hide');
|
|
$scope.repo.description = $('#wmd-input-description')[0].value;
|
|
$scope.repo.put();
|
|
};
|
|
|
|
$scope.parseDate = function(dateString) {
|
|
return Date.parse(dateString);
|
|
};
|
|
|
|
$scope.getCommentFirstLine = function(commentString) {
|
|
return getMarkedDown(getFirstTextLine(commentString));
|
|
};
|
|
|
|
$scope.getMarkedDown = function(string) {
|
|
if (!string) { return ''; }
|
|
return getMarkedDown(string);
|
|
};
|
|
|
|
$scope.listImages = function() {
|
|
if ($scope.imageHistory) { return; }
|
|
|
|
var imageFetch = Restangular.one('repository/' + namespace + '/' + name + '/tag/' + $scope.currentTag.name + '/images');
|
|
imageFetch.get().then(function(resp) {
|
|
$scope.imageHistory = resp.images;
|
|
});
|
|
};
|
|
|
|
var namespace = $routeParams.namespace;
|
|
var name = $routeParams.name;
|
|
var tag = $routeParams.tag || 'latest';
|
|
|
|
$('.spin').spin();
|
|
$scope.loading = true;
|
|
|
|
var repositoryFetch = Restangular.one('repository/' + namespace + '/' + name);
|
|
repositoryFetch.get().then(function(repo) {
|
|
$rootScope.title = namespace + '/' + name;
|
|
$scope.repo = repo;
|
|
$scope.currentTag = repo.tags[tag] || repo.tags['latest'];
|
|
|
|
var clip = new ZeroClipboard($('#copyClipboard'), { 'moviePath': 'static/lib/ZeroClipboard.swf' });
|
|
clip.on('complete', function() {
|
|
// Resets the animation.
|
|
var elem = $('#clipboardCopied')[0];
|
|
elem.style.display = 'none';
|
|
|
|
// Show the notification.
|
|
setTimeout(function() {
|
|
elem.style.display = 'block';
|
|
}, 1);
|
|
});
|
|
|
|
$scope.loading = false;
|
|
}, function() {
|
|
$scope.repo = null;
|
|
$scope.loading = false;
|
|
$rootScope.title = 'Unknown Repository';
|
|
});
|
|
}
|
|
|
|
function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|
var namespace = $routeParams.namespace;
|
|
var name = $routeParams.name;
|
|
|
|
$('#userSearch').typeahead({
|
|
name: 'users',
|
|
remote: {
|
|
url: '/api/users/%QUERY',
|
|
filter: function(data) {
|
|
var datums = [];
|
|
for (var i = 0; i < data.users.length; ++i) {
|
|
var user = data.users[i];
|
|
datums.push({
|
|
'value': user,
|
|
'tokens': [user],
|
|
'username': user
|
|
});
|
|
}
|
|
return datums;
|
|
}
|
|
},
|
|
template: function (datum) {
|
|
template = '<div class="user-mini-listing">';
|
|
template += '<i class="icon-user icon-large"></i>'
|
|
template += '<span class="name">' + datum.username + '</span>'
|
|
template += '</div>'
|
|
return template;
|
|
},
|
|
});
|
|
|
|
$('#userSearch').on('typeahead:selected', function(e, datum) {
|
|
$('#userSearch').typeahead('setQuery', '');
|
|
$scope.addNewPermission(datum.username);
|
|
});
|
|
|
|
$scope.addNewPermission = function(username) {
|
|
// Don't allow duplicates.
|
|
if ($scope.permissions[username]) { return; }
|
|
|
|
// Need the $scope.apply for both the permission stuff to change and for
|
|
// the XHR call to be made.
|
|
$scope.$apply(function() {
|
|
$scope.addRole(username, 'read')
|
|
});
|
|
};
|
|
|
|
$scope.deleteRole = function(username) {
|
|
var permissionDelete = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + username);
|
|
permissionDelete.customDELETE().then(function() {
|
|
delete $scope.permissions[username];
|
|
}, function(result) {
|
|
if (result.status == 409) {
|
|
$('#onlyadminModal').modal({});
|
|
} else {
|
|
$('#cannotchangeModal').modal({});
|
|
}
|
|
});
|
|
};
|
|
|
|
$scope.addRole = function(username, role) {
|
|
var permission = {
|
|
'role': role
|
|
};
|
|
|
|
var permissionPost = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + username);
|
|
permissionPost.customPOST(permission).then(function() {
|
|
$scope.permissions[username] = permission;
|
|
$scope.permissions = $scope.permissions;
|
|
}, function(result) {
|
|
$('#cannotchangeModal').modal({});
|
|
});
|
|
};
|
|
|
|
$scope.setRole = function(username, role) {
|
|
var permission = $scope.permissions[username];
|
|
var currentRole = permission.role;
|
|
permission.role = role;
|
|
|
|
var permissionPut = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + username);
|
|
permissionPut.customPUT(permission).then(function() {}, function(result) {
|
|
if (result.status == 409) {
|
|
permission.role = currentRole;
|
|
$('#onlyadminModal').modal({});
|
|
} else {
|
|
$('#cannotchangeModal').modal({});
|
|
}
|
|
});
|
|
};
|
|
|
|
$scope.askChangeAccess = function(newAccess) {
|
|
$('#make' + newAccess + 'Modal').modal({});
|
|
};
|
|
|
|
$scope.changeAccess = function(newAccess) {
|
|
$('#make' + newAccess + 'Modal').modal('hide');
|
|
|
|
var visibility = {
|
|
'visibility': newAccess
|
|
};
|
|
var visibilityPost = Restangular.one('repository/' + namespace + '/' + name + '/changevisibility');
|
|
visibilityPost.customPOST(visibility).then(function() {
|
|
$scope.repo.is_public = newAccess == 'public';
|
|
}, function() {
|
|
$('#cannotchangeModal').modal({});
|
|
});
|
|
};
|
|
|
|
$scope.askDelete = function() {
|
|
$('#confirmdeleteModal').modal({});
|
|
};
|
|
|
|
$scope.deleteRepo = function() {
|
|
$('#confirmdeleteModal').modal('hide');
|
|
|
|
var deleteAction = Restangular.one('repository/' + namespace + '/' + name);
|
|
deleteAction.customDELETE().then(function() {
|
|
$scope.repo = null;
|
|
|
|
setTimeout(function() {
|
|
document.location = '/#/repository';
|
|
}, 1000);
|
|
}, function() {
|
|
$('#cannotchangeModal').modal({});
|
|
});
|
|
};
|
|
|
|
$('.spin').spin();
|
|
$scope.loading = true;
|
|
|
|
// Fetch the repository information.
|
|
var repositoryFetch = Restangular.one('repository/' + namespace + '/' + name);
|
|
repositoryFetch.get().then(function(repo) {
|
|
$scope.repo = repo;
|
|
$scope.loading = !($scope.permissions && $scope.repo);
|
|
}, function() {
|
|
$scope.permissions = null;
|
|
$rootScope.title = 'Unknown Repository';
|
|
$scope.loading = false;
|
|
});
|
|
|
|
// Fetch the permissions.
|
|
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions');
|
|
permissionsFetch.get().then(function(resp) {
|
|
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
|
$scope.permissions = resp.permissions;
|
|
$scope.loading = !($scope.permissions && $scope.repo);
|
|
}, function() {
|
|
$scope.permissions = null;
|
|
$rootScope.title = 'Unknown Repository';
|
|
$scope.loading = false;
|
|
});
|
|
} |