Skip to content

Commit 436155f

Browse files
committed
Auto merge of #2253 - RobbieClarken:teams-in-manage-owners, r=locks
Display teams on the crate owners page This change updates the crate owners page (`/crates/<crate-name>/owners`) to display teams which are set to be crate owner. It also adds a "Remove" button for each team which allows removing teams from owning the crate in the same way that user type owners can be removed. I have displayed the team as `<organisation>/<team>` rather than `github:<organisation>:<team>` because I think it looks cleaner (eg `rust-lang/core` vs `github:rust-lang:core`). Happy to change it if people disagree. <img width="976" alt="Screen Shot 2020-03-06 at 5 17 50 pm" src="https://user-images.githubusercontent.com/663161/76058622-08489700-5fd1-11ea-8656-febb234f58ad.png"> I haven't touched adding teams via the owners page in this PR. From what I can tell, it is currently possible although the message that is returned is misleading. I think that should be tackled in a separate PR. Addresses #1617.
2 parents 463bc2a + 12fbdb6 commit 436155f

File tree

5 files changed

+63
-17
lines changed

5 files changed

+63
-17
lines changed

app/controllers/crate/owners.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,20 @@ export default Controller.extend({
3131
}
3232
},
3333

34-
async removeOwner(user) {
34+
async removeOwner(owner) {
3535
this.set('removed', false);
36-
3736
try {
38-
await this.crate.removeOwner(user.get('login'));
39-
this.set('removed', `User ${user.get('login')} removed as crate owner`);
40-
41-
this.get('crate.owner_user').removeObject(user);
37+
await this.crate.removeOwner(owner.get('login'));
38+
switch (owner.kind) {
39+
case 'user':
40+
this.set('removed', `User ${owner.get('login')} removed as crate owner`);
41+
this.get('crate.owner_user').removeObject(owner);
42+
break;
43+
case 'team':
44+
this.set('removed', `Team ${owner.get('display_name')} removed as crate owner`);
45+
this.get('crate.owner_team').removeObject(owner);
46+
break;
47+
}
4248
} catch (error) {
4349
if (error.errors) {
4450
this.set('removed', `Error removing owner: ${error.errors[0].detail}`);

app/models/team.js

+4
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ export default Model.extend({
1414
let login_split = login.split(':');
1515
return login_split[1];
1616
}),
17+
display_name: computed('name', 'org_name', function() {
18+
let { name, org_name } = this.getProperties('name', 'org_name');
19+
return `${org_name}/${name}`;
20+
}),
1721
});

app/templates/crate/owners.hbs

+25-1
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,32 @@
4444
{{/if}}
4545

4646
<div class='owners white-rows'>
47+
{{#each this.crate.owner_team as |team|}}
48+
<div class='crate row' data-test-owner-team={{team.login}}>
49+
<div>
50+
<LinkTo @route={{team.kind}} @model={{team.login}}>
51+
<UserAvatar @user={{team}} @size="medium-small" />
52+
</LinkTo>
53+
</div>
54+
<div>
55+
<LinkTo @route={{team.kind}} @model={{team.login}}>
56+
{{team.display_name}}
57+
</LinkTo>
58+
</div>
59+
<div class='stats'>
60+
{{#if team.email}}
61+
{{team.email}}
62+
{{else}}
63+
&nbsp;
64+
{{/if}}
65+
</div>
66+
<div class='stats downloads'>
67+
<button type="button" class='remove-owner small yellow-button' {{action 'removeOwner' team}}>Remove</button>
68+
</div>
69+
</div>
70+
{{/each}}
4771
{{#each this.crate.owner_user as |user|}}
48-
<div class='crate row'>
72+
<div class='crate row' data-test-owner-user={{user.login}}>
4973
<div>
5074
<LinkTo @route={{user.kind}} @model={{user.login}}>
5175
<UserAvatar @user={{user}} @size="medium-small" />

mirage/route-handlers/crates.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ export function register(server) {
181181

182182
const body = JSON.parse(request.requestBody);
183183
const [ownerId] = body.owners;
184-
const user = schema.users.findBy({ login: ownerId });
184+
const owner = schema.users.findBy({ login: ownerId }) || schema.teams.findBy({ login: ownerId });
185185

186-
if (!user) {
186+
if (!owner) {
187187
return notFound();
188188
}
189189

tests/acceptance/crate-test.js

+20-8
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,9 @@ module('Acceptance | crate page', function(hooks) {
255255

256256
await visit('/crates/nanomsg/owners');
257257

258-
assert.dom('.owners .row').exists({ count: 2 });
258+
assert.dom('.owners .row').exists({ count: 4 });
259+
assert.dom('a[href="/teams/github:org:thehydroimpulse"]').exists();
260+
assert.dom('a[href="/teams/github:org:blabaere"]').exists();
259261
assert.dom('a[href="/users/thehydroimpulse"]').exists();
260262
assert.dom('a[href="/users/blabaere"]').exists();
261263
});
@@ -268,7 +270,7 @@ module('Acceptance | crate page', function(hooks) {
268270

269271
assert.dom('.error').exists();
270272
assert.dom('.error').hasText('Please enter a username');
271-
assert.dom('.owners .row').exists({ count: 2 });
273+
assert.dom('.owners .row').exists({ count: 4 });
272274
});
273275

274276
test('attempting to add non-existent owner', async function(assert) {
@@ -280,7 +282,7 @@ module('Acceptance | crate page', function(hooks) {
280282

281283
assert.dom('.error').exists();
282284
assert.dom('.error').hasText('Error sending invite: Not Found');
283-
assert.dom('.owners .row').exists({ count: 2 });
285+
assert.dom('.owners .row').exists({ count: 4 });
284286
});
285287

286288
test('add a new owner', async function(assert) {
@@ -292,16 +294,26 @@ module('Acceptance | crate page', function(hooks) {
292294

293295
assert.dom('.invited').exists();
294296
assert.dom('.invited').hasText('An invite has been sent to iain8');
295-
assert.dom('.owners .row').exists({ count: 2 });
297+
assert.dom('.owners .row').exists({ count: 4 });
296298
});
297299

298-
test('remove a crate owner', async function(assert) {
300+
test('remove a crate owner when owner is a user', async function(assert) {
299301
this.server.loadFixtures();
300302

301303
await visit('/crates/nanomsg/owners');
302-
await click('.owners .row:first-child .remove-owner');
304+
await click('[data-test-owner-user="thehydroimpulse"] .remove-owner');
303305

304-
assert.dom('.removed').exists();
305-
assert.dom('.owners .row').exists({ count: 1 });
306+
assert.dom('.removed').hasText('User thehydroimpulse removed as crate owner');
307+
assert.dom('[data-test-owner-user]').exists({ count: 1 });
308+
});
309+
310+
test('remove a crate owner when owner is a team', async function(assert) {
311+
this.server.loadFixtures();
312+
313+
await visit('/crates/nanomsg/owners');
314+
await click('[data-test-owner-team="github:org:thehydroimpulse"] .remove-owner');
315+
316+
assert.dom('.removed').hasText('Team org/thehydroimpulseteam removed as crate owner');
317+
assert.dom('[data-test-owner-team]').exists({ count: 1 });
306318
});
307319
});

0 commit comments

Comments
 (0)