Initial redesigned UI for repo listings w/ stars.
This commit is contained in:
parent
97b605ca8d
commit
5a484cfe11
10 changed files with 308 additions and 103 deletions
|
@ -932,6 +932,8 @@ i.toggle-icon:hover {
|
|||
}
|
||||
|
||||
.repo-circle {
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
background: #eee;
|
||||
padding: 4px;
|
||||
|
@ -939,7 +941,6 @@ i.toggle-icon:hover {
|
|||
display: inline-block;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.repo-circle.no-background {
|
||||
|
@ -950,11 +951,11 @@ i.toggle-icon:hover {
|
|||
}
|
||||
|
||||
.repo-circle .fa-hdd-o {
|
||||
font-size: 36px;
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
.repo-circle.no-background .fa-hdd-o {
|
||||
font-size: 30px;
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
.repo-circle .fa-lock {
|
||||
|
@ -962,18 +963,18 @@ i.toggle-icon:hover {
|
|||
bottom: -2px;
|
||||
right: -4px;
|
||||
background: rgb(253, 191, 191);
|
||||
width: 20px;
|
||||
width: 16px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
line-height: 21px;
|
||||
font-size: 16px !important;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.repo-circle.no-background .fa-lock {
|
||||
bottom: -2px;
|
||||
right: -6px;
|
||||
bottom: 5px;
|
||||
right: 7px;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
|
@ -2480,10 +2481,41 @@ p.editable:hover i {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.empty-primary-msg {
|
||||
font-size: 18px;
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-secondary-msg {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.repo-list {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.repo-list-title {
|
||||
margin-bottom: 30px;
|
||||
margin-top: 10px;
|
||||
line-height: 24px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.repo-list-title a {
|
||||
font-size: 18px;
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.repo-list-title i {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.repo-list .button-bar-right {
|
||||
float: right;
|
||||
}
|
||||
|
@ -2503,11 +2535,42 @@ p.editable:hover i {
|
|||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.repo-panel {
|
||||
padding: 20px;
|
||||
border: 1px solid #eee;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.panel-body.starred {
|
||||
background: -moz-linear-gradient(top, rgba(255,240,188,1) 0%, rgba(255,255,255,0.5) 50%, rgba(255,255,255,0.49) 51%, rgba(255,255,255,0) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,240,188,1)), color-stop(50%,rgba(255,255,255,0.5)), color-stop(51%,rgba(255,255,255,0.49)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(255,240,188,1) 0%,rgba(255,255,255,0.5) 50%,rgba(255,255,255,0.49) 51%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(255,240,188,1) 0%,rgba(255,255,255,0.5) 50%,rgba(255,255,255,0.49) 51%,rgba(255,255,255,0) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(255,240,188,1) 0%,rgba(255,255,255,0.5) 50%,rgba(255,255,255,0.49) 51%,rgba(255,255,255,0) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(255,240,188,1) 0%,rgba(255,255,255,0.5) 50%,rgba(255,255,255,0.49) 51%,rgba(255,255,255,0) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff0bc', endColorstr='#00ffffff',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
|
||||
.star-icon {
|
||||
color: #ddd;
|
||||
display: block;
|
||||
font-size: 1.2em;
|
||||
text-align: right;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.star-icon:hover {
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
}
|
||||
|
||||
.star-icon.starred {
|
||||
color: #ffba6d;
|
||||
}
|
||||
|
||||
.repo-listing {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
line-height: normal;
|
||||
}
|
||||
|
@ -2521,18 +2584,13 @@ p.editable:hover i {
|
|||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.repo-listing a {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.repo-listing i {
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
margin-right: 6px;
|
||||
.repo-panel-repo-link {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.repo-listing .description {
|
||||
padding-left: 44px;
|
||||
font-size: 0.91em;
|
||||
padding-top: 13px;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2267,6 +2267,7 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
|
||||
when('/', {title: 'Hosted Private Docker Registry', templateUrl: '/static/partials/landing.html', controller: LandingCtrl,
|
||||
pageClass: 'landing-page'}).
|
||||
when ('/starred/', {title: 'Starred Repositories', templateUrl: '/static/partials/starred.html', controller: StarCtrl}).
|
||||
otherwise({redirectTo: '/'});
|
||||
}]).
|
||||
config(function(RestangularProvider) {
|
||||
|
|
|
@ -237,14 +237,52 @@ function RepoListCtrl($scope, $sanitize, Restangular, UserService, ApiService) {
|
|||
$scope.publicPageCount = null;
|
||||
|
||||
// Monitor changes in the user.
|
||||
UserService.updateUserIn($scope, function() {
|
||||
loadMyRepos($scope.namespace);
|
||||
UserService.load(function() {
|
||||
console.log("updateUserIn");
|
||||
var user = UserService.currentUser();
|
||||
$scope.namespaces = [user];
|
||||
for (var i = 0; i < user.organizations.length; i++) {
|
||||
$scope.namespaces.push(user.organizations[i]);
|
||||
}
|
||||
loadStarredRepos();
|
||||
loadRepos();
|
||||
console.log($scope.namespaces);
|
||||
});
|
||||
|
||||
|
||||
// Monitor changes in the namespace.
|
||||
$scope.$watch('namespace', function(namespace) {
|
||||
loadMyRepos(namespace);
|
||||
});
|
||||
//$scope.$watch('namespace', function(namespace) {
|
||||
// loadStarredRepos($scope.namespace)
|
||||
// loadRepos();
|
||||
//});
|
||||
|
||||
|
||||
$scope.starRepo = function(repo) {
|
||||
var data = {
|
||||
'namespace': repo.namespace,
|
||||
'repository': repo.name
|
||||
};
|
||||
ApiService.createStar(data).then(function(result) {
|
||||
loadStarredRepos($scope.namespace);
|
||||
loadRepos($scope.namespace);
|
||||
}, function(result) {
|
||||
loadStarredRepos();
|
||||
loadRepos();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.unstarRepo = function(repo) {
|
||||
var data = {
|
||||
'repository': repo.namespace + '/' + repo.name
|
||||
};
|
||||
ApiService.deleteStar(null, data).then(function(result) {
|
||||
loadStarredRepos($scope.namespace);
|
||||
loadRepos($scope.namespace);
|
||||
}, function(result) {
|
||||
loadStarredRepos($scope.namespace);
|
||||
loadRepos();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.movePublicPage = function(increment) {
|
||||
if ($scope.publicPageCount == null) {
|
||||
|
@ -263,18 +301,36 @@ function RepoListCtrl($scope, $sanitize, Restangular, UserService, ApiService) {
|
|||
loadPublicRepos();
|
||||
};
|
||||
|
||||
var loadMyRepos = function(namespace) {
|
||||
if (!$scope.user || $scope.user.anonymous || !namespace) {
|
||||
var loadStarredRepos = function() {
|
||||
if (!$scope.user || $scope.user.anonymous) {
|
||||
return;
|
||||
}
|
||||
|
||||
var options = {'public': false, 'sort': true, 'namespace': namespace};
|
||||
|
||||
$scope.user_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
|
||||
$scope.starred_repositories = ApiService.listStarredReposAsResource().get(function(resp) {
|
||||
return resp.repositories;
|
||||
});
|
||||
};
|
||||
|
||||
var loadRepos = function() {
|
||||
if ($scope.namespaces.length == 0 || $scope.user.anonymous) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < $scope.namespaces.length; i++) {
|
||||
var namespace = $scope.namespaces[i];
|
||||
var namespaceName = namespace.username || namespace.name;
|
||||
var options = {
|
||||
'public': false,
|
||||
'sort': true,
|
||||
'namespace': namespaceName,
|
||||
'starred': false,
|
||||
};
|
||||
namespace.repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
|
||||
return resp.repositories;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var loadPublicRepos = function() {
|
||||
var options = {
|
||||
'public': true,
|
||||
|
@ -293,7 +349,7 @@ function RepoListCtrl($scope, $sanitize, Restangular, UserService, ApiService) {
|
|||
});
|
||||
};
|
||||
|
||||
loadPublicRepos();
|
||||
//loadPublicRepos();
|
||||
}
|
||||
|
||||
function LandingCtrl($scope, UserService, ApiService, Features, Config) {
|
||||
|
@ -401,6 +457,10 @@ function LandingCtrl($scope, UserService, ApiService, Features, Config) {
|
|||
};
|
||||
}
|
||||
|
||||
function StarCtrl($scope) {
|
||||
$scope.test = "hello";
|
||||
}
|
||||
|
||||
function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiService, $routeParams, $rootScope, $location, $timeout, Config) {
|
||||
$scope.Config = Config;
|
||||
|
||||
|
|
|
@ -1,73 +1,136 @@
|
|||
<div class="container">
|
||||
<div class="repo-list" ng-show="!user.anonymous">
|
||||
<div ng-class="user.organizations.length ? 'section-header' : ''">
|
||||
<div class="button-bar-right">
|
||||
<a href="/new/">
|
||||
<button class="btn btn-success">
|
||||
<i class="fa fa-upload user-tool" data-title="Create new repository"></i>
|
||||
Create Repository
|
||||
</button>
|
||||
</a>
|
||||
|
||||
<a href="/organization/{{ namespace }}" ng-show="namespace != user.username">
|
||||
<button class="btn btn-default">
|
||||
<i class="fa fa-group user-tool"></i>
|
||||
View Organization
|
||||
</button>
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-lg-push-9 col-md-3 col-md-push-9 col-sm-4 col-sm-push-8 col-xs-12">
|
||||
<div class="button-bar-right">
|
||||
<a href="/new/">
|
||||
<button class="btn btn-success">
|
||||
<i class="fa fa-upload user-tool" data-title="Create new repository"></i>
|
||||
Create Repository
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Users
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<a href="javascript:void(0)">
|
||||
<span class="avatar" size="24" hash="user.avatar"></span>
|
||||
{{ user.username }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<span class="namespace-selector" user="user" namespace="namespace" ng-show="user.organizations"></span>
|
||||
</div>
|
||||
|
||||
<h3 ng-show="namespace == user.username">Your Repositories</h3>
|
||||
<h3 ng-show="namespace != user.username">Repositories</h3>
|
||||
|
||||
<div class="resource-view" resource="user_repositories">
|
||||
<!-- User/Org has repositories -->
|
||||
<div ng-show="user_repositories.value.length > 0">
|
||||
<div class="repo-listing" ng-repeat="repository in user_repositories.value">
|
||||
<span class="repo-circle no-background" repo="repository"></span>
|
||||
<a ng-href="/repository/{{repository.namespace}}/{{ repository.name }}"
|
||||
data-repo="{{repository.namespace}}/{{ repository.name }}">
|
||||
{{repository.namespace}}/{{repository.name}}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Organizations
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div ng-repeat="org in user.organizations">
|
||||
<a href="/organization/{{ org.name }}">
|
||||
<span class="avatar" size="24" hash="org.avatar"></span>
|
||||
{{ org.name }}
|
||||
</a>
|
||||
<a href="/organization/{{ org.name }}/admin">
|
||||
<i class="fa fa-gear" style="color:#000"></i>
|
||||
</a>
|
||||
<div class="description markdown-view" content="repository.description" first-line-only="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User/Org has no repositories -->
|
||||
<div ng-show="user_repositories.value.length == 0" style="padding:20px;">
|
||||
<div class="alert alert-info">
|
||||
<h4 ng-show="namespace == user.username">You don't have any repositories yet!</h4>
|
||||
<h4 ng-show="namespace != user.username">This organization doesn't have any repositories, or you have not been provided access.</h4>
|
||||
<a href="http://docs.quay.io/solution/getting-started.html"><b>Click here</b> to learn how to create a repository</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="repo-list">
|
||||
<h3>Top Public Repositories</h3>
|
||||
<div class="resource-view" resource="public_repositories">
|
||||
<div class="repo-listing" ng-repeat="repository in public_repositories.value">
|
||||
<span class="repo-circle no-background" repo="repository"></span>
|
||||
<a ng-href="/repository/{{repository.namespace}}/{{ repository.name }}"
|
||||
data-repo="{{repository.namespace}}/{{ repository.name }}">
|
||||
{{repository.namespace}}/{{repository.name}}
|
||||
</a>
|
||||
<div class="description markdown-view" content="repository.description" first-line-only="true"></div>
|
||||
<div class="col-lg-9 col-lg-pull-3 col-md-9 col-md-pull-3 col-sm-8 col-sm-pull-4 col-xs-12">
|
||||
<div class="resource-view" resource="starred_repositories">
|
||||
<div class="repo-listing">
|
||||
<div class="repo-list-title">
|
||||
<i class="fa fa-star"></i>
|
||||
Starred
|
||||
</div>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12" ng-repeat="repository in starred_repositories.value">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body starred">
|
||||
<div class="row">
|
||||
<div class="col-lg-10 col-md-10 col-sm-10 col-xs-10">
|
||||
<span class="repo-icon repo-circle no-background" repo="repository"></span>
|
||||
<a ng-href="/repository/{{repository.namespace}}/{{ repository.name }}" class="repo-panel-repo-link"
|
||||
data-repo="{{repository.namespace}}/{{ repository.name }}">
|
||||
{{repository.namespace}}/{{repository.name}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-lg-2 col-md-2 col-sm-2 col-xs-2">
|
||||
<i class="star-icon starred fa fa-star" ng-click="unstarRepo(repository)"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- The description automatically gets put in a <p> which adds margin that throws off our .repo-panel padding -->
|
||||
<div class="description markdown-view" content="repository.description" first-line-only="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="starred_repositories.value.length == 0">
|
||||
<div class="empty-primary-msg">You haven't starred any repositories yet.</div>
|
||||
<div class="empty-secondary-msg">Stars allow you to easily access your favorite repositories.</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-controls">
|
||||
<button class="btn btn-default" data-title="Previous Page" bs-tooltip="title" ng-show="page > 1"
|
||||
ng-click="movePublicPage(-1)">
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
</button>
|
||||
<button class="btn btn-default" data-title="Next Page" bs-tooltip="title" ng-show="page < publicPageCount"
|
||||
ng-click="movePublicPage(1)">
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Repo listings for User and Orgs -->
|
||||
<div ng-repeat="namespace in namespaces">
|
||||
<div class="resource-view" resource="namespace">
|
||||
<div class="repo-listing">
|
||||
<div class="repo-list-title" ng-show="user.username == namespace.username">
|
||||
<i class="fa fa-user"></i>
|
||||
{{ namespace.username }}
|
||||
</div>
|
||||
<div class="repo-list-title" ng-show="user.username != namespace.username">
|
||||
<i class="fa fa-sitemap"></i>
|
||||
<a href="/organization/{{ namespace.name }}">{{ namespace.name }}</a>
|
||||
</div>
|
||||
<div ng-show="namespace.repositories.value.length > 0">
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-md-6 col-sm-6 col-xs-12" ng-repeat="repository in namespace.repositories.value">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-lg-10 col-md-10 col-sm-10 col-xs-10">
|
||||
<span class="repo-icon repo-circle no-background" repo="repository"></span>
|
||||
<a ng-href="/repository/{{repository.namespace}}/{{ repository.name }}" class="repo-panel-repo-link"
|
||||
data-repo="{{repository.namespace}}/{{ repository.name }}">
|
||||
{{repository.namespace}}/{{repository.name}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-lg-2 col-md-2 col-sm-2 col-xs-2">
|
||||
<i class="star-icon fa fa-star-o" ng-click="starRepo(repository)"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- The description automatically gets put in a <p> which adds margin that throws off our .repo-panel padding -->
|
||||
<div class="description markdown-view" content="repository.description" first-line-only="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="namespace.value.length == 0">
|
||||
<div class="empty-primary-msg">There aren't any repositories yet.</div>
|
||||
<div class="empty-secondary-msg">This origanization does't have any repositories, or you have not been provided access. <a href="/new">Create a new repository</a>
|
||||
</div>
|
||||
|
||||
<!-- User/Org has no repositories -->
|
||||
<div ng-show="namespace.repositories.value.length == 0" style="padding:20px;">
|
||||
<div class="alert alert-info">
|
||||
<h4 ng-show="namespace == user.username">You don't have any repositories yet!</h4>
|
||||
<h4 ng-show="namespace != user.username">This organization doesn't have any repositories, or you have not been provided access.</h4>
|
||||
<a href="http://docs.quay.io/solution/getting-started.html"><b>Click here</b> to learn how to create a repository</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
3
static/partials/starred.html
Normal file
3
static/partials/starred.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div ng-show="test">
|
||||
{{ test }}
|
||||
</div>
|
Reference in a new issue