diff --git a/endpoints/api.py b/endpoints/api.py index b5db0d544..c0720c5f7 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -329,7 +329,8 @@ def update_organization_team(orgname, teamname): description = json['description'] if 'description' in json else '' role = json['role'] if 'role' in json else 'member' - team = model.create_team(teamname, orgname, role, description) + org = model.get_organization(orgname) + team = model.create_team(teamname, org, role, description) if is_existing: if 'description' in json: diff --git a/static/css/quay.css b/static/css/quay.css index e23ece05e..1f7dab88a 100644 --- a/static/css/quay.css +++ b/static/css/quay.css @@ -3,7 +3,7 @@ } .organization-header-element { - padding: 10px; + padding: 20px; margin-bottom: 20px; border-bottom: 1px solid #eee; @@ -31,6 +31,10 @@ text-transform: capitalize; } +.organization-header-element .header-buttons { + float: right; +} + .namespace-selector-dropdown .namespace { padding: 6px; padding-left: 10px; @@ -1418,6 +1422,7 @@ p.editable:hover i { .org-view .header-col { color: #444; + margin-bottom: 10px; } .org-view .header-col dd { @@ -1429,29 +1434,62 @@ p.editable:hover i { margin-left: 10px; } -.org-view .team-listing .control-col { - margin-top: 20px; -} - -.org-view .team-listing .delete-col button { - padding: 4px; +.org-view .team-listing .control-col button.btn-danger { + margin-left: 10px; } .org-view .team-listing i { margin-right: 10px; } +.org-view .highlight .team-title { + animation: highlighttemp 1s 2; + animation-timing-function: ease-in-out; + animation-direction: alternate; + + -moz-animation: highlighttemp 1s 2; + -moz-animation-timing-function: ease-in-out; + -moz-animation-direction: alternate; + + -webkit-animation: highlighttemp 1s 2; + -webkit-animation-timing-function: ease-in-out; + -webkit-animation-direction: alternate; +} + +@-moz-keyframes highlighttemp { + 0% { background-color: white; } + 100% { background-color: rgba(92, 184, 92, 0.36); } +} + +@-webkit-keyframes highlighttemp { + 0% { background-color: white; } + 100% { background-color: rgba(92, 184, 92, 0.36); } +} + +@keyframes highlighttemp { + 0% { background-color: white; } + 100% { background-color: rgba(92, 184, 92, 0.36); } +} + + .org-view .team-title { font-size: 20px; text-transform: capitalize; + padding: 4px; } .org-view .team-listing .team-description { margin-top: 6px; - margin-left: 37px; + margin-left: 41px; font-size: 16px; } +.org-view #create-team-box { + border: none; + font-size: 14px; + padding: 6px; +} + /* Overrides for typeahead to work with bootstrap 3. */ .twitter-typeahead .tt-query, diff --git a/static/js/app.js b/static/js/app.js index 6a093b888..47aa90c52 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -569,6 +569,15 @@ quayApp.directive('buildStatus', function () { return directiveDefinitionObject; }); +// Note: ngBlur is not yet in Angular stable, so we add it manaully here. +quayApp.directive('ngBlur', function() { + return function( scope, elem, attrs ) { + elem.bind('blur', function() { + scope.$apply(attrs.ngBlur); + }); + }; +}); + quayApp.run(['$location', '$rootScope', function($location, $rootScope) { $rootScope.$on('$routeChangeSuccess', function (event, current, previous) { if (current.$$route.title) { diff --git a/static/js/controllers.js b/static/js/controllers.js index 13f4bb5b8..cec50c675 100644 --- a/static/js/controllers.js +++ b/static/js/controllers.js @@ -1122,6 +1122,41 @@ function OrgViewCtrl($rootScope, $scope, Restangular, $routeParams) { }); }; + $scope.createTeamShown = function() { + setTimeout(function() { + $('#create-team-box').focus(); + }, 10); + }; + + $scope.createTeam = function() { + var box = $('#create-team-box'); + if (box.hasClass('ng-invalid')) { return; } + + var teamname = box[0].value.toLowerCase(); + if (!teamname) { + return; + } + + if ($scope.organization.teams[teamname]) { + $('#team-' + teamname).removeClass('highlight'); + setTimeout(function() { + $('#team-' + teamname).addClass('highlight'); + }, 10); + return; + } + + var createTeam = Restangular.one(getRestUrl('organization', orgname, 'team', teamname)); + var data = { + 'name': teamname, + 'role': 'member' + }; + createTeam.customPOST(data).then(function(resp) { + $scope.organization.teams[teamname] = resp; + }, function() { + $('#cannotChangeTeamModal').modal({}); + }); + }; + $scope.askDeleteTeam = function(teamname) { $scope.currentDeleteTeam = teamname; $('#confirmdeleteModal').modal({}); diff --git a/static/partials/create-team-dialog.html b/static/partials/create-team-dialog.html new file mode 100644 index 000000000..41a599189 --- /dev/null +++ b/static/partials/create-team-dialog.html @@ -0,0 +1,3 @@ +
diff --git a/static/partials/org-view.html b/static/partials/org-view.html index d75d243e1..f26c35c67 100644 --- a/static/partials/org-view.html +++ b/static/partials/org-view.html @@ -8,7 +8,10 @@