diff --git a/endpoints/web.py b/endpoints/web.py index 3e6b2fc4d..ddfbca3d6 100644 --- a/endpoints/web.py +++ b/endpoints/web.py @@ -67,6 +67,11 @@ def signin(): return index('') +@app.route('/new/') +def new(): + return index('') + + @app.route('/repository/') def repository(): return index('') diff --git a/static/css/quay.css b/static/css/quay.css index fd8e2f109..aaad9aa5f 100644 --- a/static/css/quay.css +++ b/static/css/quay.css @@ -75,6 +75,57 @@ text-decoration: none !important; } +.new-repo .new-header { + font-size: 22px; +} + +.new-repo .new-header .repo-circle { + margin-right: 14px; +} + +.new-repo .new-header .name-container { + display: inline-block; + width: 300px; +} + +.new-repo .description { + margin-left: 10px; + margin-top: 10px; +} + +.new-repo .section { + padding-bottom: 20px; + border-bottom: 1px solid #eee; + margin-bottom: 16px; +} + +.new-repo .repo-option { + margin: 6px; + margin-top: 16px; +} + +.new-repo .repo-option i { + font-size: 18px; + padding-left: 10px; + padding-right: 10px; + width: 42px; + display: inline-block; + text-align: center; +} + +.new-repo .option-description { + display: inline-block; + vertical-align: top; +} + +.new-repo .option-description label { + display: block; +} + +.new-repo .cbox { + margin: 10px; +} + .user-guide h3 { margin-bottom: 20px; } @@ -1051,6 +1102,7 @@ p.editable:hover i { border: 1px solid #eee; margin-top: 10px; padding: 10px; + min-height: 50px; } /* Overrides for typeahead to work with bootstrap 3. */ diff --git a/static/directives/repo-circle.html b/static/directives/repo-circle.html index 62986d4bf..76ebd2cfd 100644 --- a/static/directives/repo-circle.html +++ b/static/directives/repo-circle.html @@ -1,2 +1,2 @@ -<i class="icon-lock icon-large" style="{{ repo.is_public ? 'visibility: hidden' : 'visibility: visible' }}" title="Private Repository"></i> +<i class="icon-lock icon-large" style="{{ !!(repo.is_public) ? 'visibility: hidden' : 'visibility: visible' }}" title="Private Repository"></i> <i class="icon-hdd icon-large"></i> diff --git a/static/js/app.js b/static/js/app.js index 73161f17e..568c19637 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -155,6 +155,7 @@ quayApp = angular.module('quay', ['restangular', 'angularMoment', 'angulartics', when('/guide/', {title: 'User Guide', templateUrl: '/static/partials/guide.html', controller: GuideCtrl}). when('/plans/', {title: 'Plans and Pricing', templateUrl: '/static/partials/plans.html', controller: PlansCtrl}). when('/signin/', {title: 'Signin', templateUrl: '/static/partials/signin.html', controller: SigninCtrl}). + when('/new/', {title: 'Create new repository', templateUrl: '/static/partials/new-repo.html', controller: NewRepoCtrl}). when('/v1/', {title: 'Activation information', templateUrl: '/static/partials/v1-page.html', controller: V1Ctrl}). diff --git a/static/js/controllers.js b/static/js/controllers.js index f624c10b7..72610a23f 100644 --- a/static/js/controllers.js +++ b/static/js/controllers.js @@ -893,4 +893,42 @@ function V1Ctrl($scope, UserService) { $scope.browseRepos = function() { document.location = '/repository/'; }; +} + +function NewRepoCtrl($scope, UserService) { + $scope.repo = { + 'is_public': 1, + 'description': '', + 'initialize': false + }; + + $scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) { + $scope.user = currentUser; + + if ($scope.user.anonymous) { + document.location = '/signin/'; + } + }, true); + + $scope.editDescription = function() { + 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.getMarkedDown = function(string) { + if (!string) { return ''; } + return getMarkedDown(string); + }; + + $scope.saveDescription = function() { + $('#editModal').modal('hide'); + $scope.repo.description = $('#wmd-input-description')[0].value; + }; } \ No newline at end of file diff --git a/static/partials/header.html b/static/partials/header.html index 321e08612..8e3f288dc 100644 --- a/static/partials/header.html +++ b/static/partials/header.html @@ -27,9 +27,11 @@ </div> </form> - <li class="dropdown" ng-switch-when="false"> - <!--<button type="button" class="btn btn-default navbar-btn">Sign in</button>--> + <span class="navbar-left" ng-show="!user.anonymous"> + <i class="icon-plus-circle"></i> + </span> + <li class="dropdown" ng-switch-when="false"> <a href="javascript:void(0)" class="dropdown-toggle user-dropdown" data-toggle="dropdown"> <img src="//www.gravatar.com/avatar/{{ user.gravatar }}?s=32&d=identicon" /> {{ user.username }} diff --git a/static/partials/new-repo.html b/static/partials/new-repo.html new file mode 100644 index 000000000..71159bbc4 --- /dev/null +++ b/static/partials/new-repo.html @@ -0,0 +1,103 @@ +<div class="container new-repo" ng-show="!user.anonymous"> + <form method="post" name="newRepoForm" ng-submit="createNewRepo()"> + + <!-- Header --> + <div class="row"> + <div class="col-md-1"></div> + <div class="col-md-8"> + <div class="section"> + <div class="new-header"> + <span class="repo-circle no-background" repo="repo"></span> + <span style="color: #444;"> {{user.username}}</span> <span style="color: #ccc">/</span> <span class="name-container"><input id="repoName" name="repoName" type="text" class="form-control" placeholder="Repository Name" ng-model="repo.name" required autofocus></span> + </div> + </div> + + <div class="section"> + <strong>Description:</strong><br> + <p class="description lead editable" ng-click="editDescription()"> + <span class="content" ng-bind-html-unsafe="getMarkedDown(repo.description)"></span> + <i class="icon-edit"></i> + </p> + </div> + </div> + </div> + + <!-- Private/public --> + <div class="row"> + <div class="col-md-1"></div> + <div class="col-md-8"> + <div class="section"> + <div class="repo-option"> + <input type="radio" id="publicrepo" name="publicorprivate" ng-model="repo.is_public" value="1"> + <i class="icon-unlock icon-large" title="Public Repository"></i> + + <div class="option-description"> + <label for="publicrepo">Public</label> + <span class="description-text">Anyone can see and pull from this repository. You choose who can push.</span> + </div> + </div> + <div class="repo-option"> + <input type="radio" id="privaterepo" name="publicorprivate" ng-model="repo.is_public" value="0"> + <i class="icon-lock icon-large" title="Private Repository"></i> + + <div class="option-description"> + <label for="privaterepo">Private</label> + <span class="description-text">You choose who can see, pull and push from/to this repository.</span> + </div> + </div> + </div> + </div> + </div> + + <!-- Initialize repository --> + <div class="row"> + <div class="col-md-1"></div> + <div class="col-md-8"> + <div class="section"> + <input type="checkbox" class="cbox" id="initialize" name="initialize" ng-model="repo.initialize"> + <div class="option-description"> + <label for="initialize">Initialize Repository from <a href="http://www.docker.io/learn/dockerfile/" target="_new">Dockerfile</a></label> + <span class="description-text">Automatically populate your repository with a new image constructed from a Dockerfile</span> + </div> + + <div ng-show="repo.initialize"> + Initialize + </div> + </div> + </div> + </div> + + <div class="row"> + <div class="col-md-1"></div> + <div class="col-md-8"> + <button class="btn btn-large btn-success" type="submit" ng-disabled="newRepoForm.$invalid">Create Repository</button> + </div> + </div> + + </form> +</div> + +<!-- Modal edit for the description --> +<div class="modal fade" id="editModal"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <h4 class="modal-title">Edit Repository Description</h4> + </div> + <div class="modal-body"> + <div class="wmd-panel"> + <div id="wmd-button-bar-description"></div> + <textarea class="wmd-input" id="wmd-input-description" placeholder="Enter description">{{ repo.description }}</textarea> + </div> + + <div id="wmd-preview-description" class="wmd-panel wmd-preview"></div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary" ng-click="saveDescription()">Save changes</button> + </div> + </div><!-- /.modal-content --> + </div><!-- /.modal-dialog --> +</div><!-- /.modal --> +