Merge pull request #1842 from coreos-inc/better-team-management

Better UX for managing teams
This commit is contained in:
josephschorr 2016-09-16 21:06:48 -04:00 committed by GitHub
commit 63d92f5010
6 changed files with 69 additions and 51 deletions

View file

@ -1176,7 +1176,7 @@ a:focus {
@media (max-width: 767px) { @media (max-width: 767px) {
.co-table tr.indented-row td:first-child { .co-table tr.indented-row td:first-child {
padding-left: 0px; padding-left: 10px;
} }
} }

View file

@ -1,5 +1,6 @@
.team-view .co-main-content-panel { .team-view .co-main-content-panel {
padding: 20px; padding: 20px;
position: relative;
} }
.team-view .team-title { .team-view .team-title {
@ -59,3 +60,9 @@
.team-view .co-table-header-row:first-child td { .team-view .co-table-header-row:first-child td {
padding-top: 10px !important; padding-top: 10px !important;
} }
.team-view .section-header {
text-align: left;
color: #aaa;
margin-bottom: 20px;
}

View file

@ -2456,34 +2456,6 @@ p.editable:hover i {
min-height: 50px; min-height: 50px;
} }
.team-view .panel {
display: inline-block;
width: 620px;
}
.team-view .entity {
font-size: 1.2em;
min-width: 510px;
}
.team-view .entity i {
margin-right: 6px;
}
.team-view .entity-search {
margin-top: 10px;
}
.team-view .delete-ui {
display: inline-block;
width: 78px;
}
.team-view .delete-ui i {
margin-top: 8px;
float: right;
}
.org-view .team-listing { .org-view .team-listing {
padding: 4px; padding: 4px;
} }

View file

@ -1,6 +1,6 @@
<div class="team-view-add-element" focusable-popover-content> <div class="team-view-add-element" focusable-popover-content>
<div class="entity-search" <div class="entity-search"
namespace="orgname" placeholder="allowEmail ? 'Add a registered user, robot or email address...' : 'Add a registered user or robot...'" namespace="orgname" placeholder="allowEmail ? 'Add a registered user, robot or email address to the team' : 'Add a registered user or robot to the team'"
entity-selected="addNewMember(entity)" entity-selected="addNewMember(entity)"
email-selected="inviteEmail(email)" email-selected="inviteEmail(email)"
current-entity="selectedMember" current-entity="selectedMember"
@ -10,7 +10,9 @@
allow-emails="allowEmail" allow-emails="allowEmail"
email-message="Press enter to invite the entered e-mail address to this team" email-message="Press enter to invite the entered e-mail address to this team"
ng-show="!addingMember"></div> ng-show="!addingMember"></div>
<div class="quay-spinner" ng-show="addingMember"></div> <div ng-show="addingMember">
<div class="cor-loader-inline"></div> Inviting team member
</div>
<div class="help-text" ng-show="!addingMember"> <div class="help-text" ng-show="!addingMember">
<span ng-if="allowEmail">Search by registry username, robot account name or enter an email address to invite</span> <span ng-if="allowEmail">Search by registry username, robot account name or enter an email address to invite</span>
<span ng-if="!allowEmail">Search by registry username or robot account name</span> <span ng-if="!allowEmail">Search by registry username or robot account name</span>

View file

@ -19,6 +19,7 @@
$scope.addingMember = false; $scope.addingMember = false;
$scope.memberMap = null; $scope.memberMap = null;
$scope.allowEmail = Features.MAILING; $scope.allowEmail = Features.MAILING;
$scope.feedback = null;
$rootScope.title = 'Loading...'; $rootScope.title = 'Loading...';
@ -49,6 +50,14 @@
$scope.members.push(resp); $scope.members.push(resp);
$scope.memberMap[resp.email] = resp; $scope.memberMap[resp.email] = resp;
$scope.addingMember = false; $scope.addingMember = false;
$scope.feedback = {
'kind': 'success',
'message': 'E-mail address {email} was invited to join the team',
'data': {
'email': email
}
};
}, errorHandler); }, errorHandler);
}; };
@ -70,6 +79,14 @@
$scope.members.push(resp); $scope.members.push(resp);
$scope.memberMap[resp.name] = resp; $scope.memberMap[resp.name] = resp;
$scope.addingMember = false; $scope.addingMember = false;
$scope.feedback = {
'kind': 'success',
'message': 'User {username} was added to the team',
'data': {
'username': member.name
}
};
}, errorHandler); }, errorHandler);
}; };
@ -95,6 +112,14 @@
var index = $.inArray($scope.memberMap[email], $scope.members); var index = $.inArray($scope.memberMap[email], $scope.members);
$scope.members.splice(index, 1); $scope.members.splice(index, 1);
delete $scope.memberMap[email]; delete $scope.memberMap[email];
$scope.feedback = {
'kind': 'success',
'message': 'Invitation to e-amil address {email} was revoked',
'data': {
'email': email
}
};
}, ApiService.errorDisplay('Cannot revoke team invite')); }, ApiService.errorDisplay('Cannot revoke team invite'));
}; };
@ -110,6 +135,14 @@
var index = $.inArray($scope.memberMap[username], $scope.members); var index = $.inArray($scope.memberMap[username], $scope.members);
$scope.members.splice(index, 1); $scope.members.splice(index, 1);
delete $scope.memberMap[username]; delete $scope.memberMap[username];
$scope.feedback = {
'kind': 'success',
'message': 'User {username} was removed from the team',
'data': {
'username': username
}
};
}, ApiService.errorDisplay('Cannot remove team member')); }, ApiService.errorDisplay('Cannot remove team member'));
}; };
@ -123,6 +156,11 @@
var teaminfo = $scope.organization.teams[teamname]; var teaminfo = $scope.organization.teams[teamname];
ApiService.updateOrganizationTeam(teaminfo, params).then(function(resp) { ApiService.updateOrganizationTeam(teaminfo, params).then(function(resp) {
$scope.feedback = {
'kind': 'success',
'message': 'Team description changed',
'data': {}
};
}, function() { }, function() {
$('#cannotChangeTeamModal').modal({}); $('#cannotChangeTeamModal').modal({});
}); });

View file

@ -16,27 +16,25 @@
</div> </div>
<div class="co-main-content-panel"> <div class="co-main-content-panel">
<div class="team-view-header"> <div class="feedback-bar" feedback="feedback"></div>
<div ng-show="canEditMembers" class="side-controls">
<div class="hidden-xs">
<button class="btn btn-primary"
id="showAddMember"
data-title="Add Team Member"
data-content-template="/static/directives/team-view-add.html"
data-placement="bottom-right"
bs-popover="bs-popover">
<i class="fa fa-plus"></i>
Add Team Member
</button>
</div>
</div>
<!-- Description -->
<div class="section-header">Team Description</div>
<div class="team-view-header">
<div class="description markdown-input" content="team.description" <div class="description markdown-input" content="team.description"
can-write="organization.is_admin" can-write="organization.is_admin"
content-changed="updateForDescription" content-changed="updateForDescription"
field-title="'team description'"></div> field-title="'team description'"></div>
</div> </div>
<!-- Members -->
<div ng-show="canEditMembers" style="float:right; margin-top: 10px;">
<div class="hidden-xs">
<div ng-include="'/static/directives/team-view-add.html'" style="max-width: 500px;"></div>
</div>
</div>
<div class="section-header">Team Members</div>
<div class="empty" ng-if="!members.length"> <div class="empty" ng-if="!members.length">
<div class="empty-primary-msg">This team has no members.</div> <div class="empty-primary-msg">This team has no members.</div>
<div class="empty-secondary-msg"> <div class="empty-secondary-msg">
@ -57,7 +55,7 @@
<span class="entity-reference" entity="member" namespace="organization.name" <span class="entity-reference" entity="member" namespace="organization.name"
show-avatar="true" avatar-size="24"></span> show-avatar="true" avatar-size="24"></span>
</td> </td>
<td> <td class="options-col">
<span class="cor-options-menu" ng-if="canEditMembers"> <span class="cor-options-menu" ng-if="canEditMembers">
<span class="cor-option" option-click="removeMember(member.name)"> <span class="cor-option" option-click="removeMember(member.name)">
<i class="fa fa-times"></i> Remove {{ member.name }} <i class="fa fa-times"></i> Remove {{ member.name }}
@ -77,7 +75,7 @@
<td class="user entity"> <td class="user entity">
<span class="entity-reference" entity="member" namespace="organization.name"></span> <span class="entity-reference" entity="member" namespace="organization.name"></span>
</td> </td>
<td> <td class="options-col">
<span class="cor-options-menu" ng-if="canEditMembers"> <span class="cor-options-menu" ng-if="canEditMembers">
<span class="cor-option" option-click="removeMember(member.name)"> <span class="cor-option" option-click="removeMember(member.name)">
<i class="fa fa-times"></i> Remove {{ member.name }} <i class="fa fa-times"></i> Remove {{ member.name }}
@ -103,7 +101,7 @@
{{ member.email }} {{ member.email }}
</span> </span>
</td> </td>
<td> <td class="options-col">
<span class="cor-options-menu" ng-if="canEditMembers"> <span class="cor-options-menu" ng-if="canEditMembers">
<span class="cor-option" option-click="revokeInvite(member)"> <span class="cor-option" option-click="revokeInvite(member)">
<i class="fa fa-times"></i> Revoke invite <i class="fa fa-times"></i> Revoke invite
@ -113,12 +111,13 @@
</tr> </tr>
</table> </table>
<!-- Add team member (mobile) -->
<div ng-show="canEditMembers"> <div ng-show="canEditMembers">
<div ng-if-media="'(max-width: 767px)'"> <div class="visible-xs" style="margin-top: 20px; padding-top: 10px; border-top: 1px solid #eee;">
<div ng-include="'/static/directives/team-view-add.html'"></div> <div class="section-header">Add team member</div>
<div ng-include="'/static/directives/team-view-add.html'" style="max-width: 500px;"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>