From be866dbe6e38057cb16e7267819cb9bf490dbc2c Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Wed, 21 Mar 2018 18:16:08 +0800 Subject: [PATCH] UX: Allow group owners to manage members from group members page. --- .../components/group-member-dropdown.js.es6 | 32 +++++++++++++++++++ .../discourse/controllers/group-index.js.es6 | 5 +++ .../discourse/controllers/group.js.es6 | 3 +- .../discourse/routes/group-index.js.es6 | 2 +- .../components/group-members-input.hbs | 2 +- .../discourse/templates/group-index.hbs | 9 ++++++ app/assets/stylesheets/common/base/group.scss | 4 +++ .../components/group-member-dropdown.scss | 9 ++++++ config/locales/client.en.yml | 7 ++-- .../acceptance/group-index-test.js.es6 | 31 ++++++++++++++++++ .../javascripts/acceptance/groups-test.js.es6 | 4 --- 11 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 app/assets/javascripts/discourse/components/group-member-dropdown.js.es6 create mode 100644 app/assets/stylesheets/common/components/group-member-dropdown.scss create mode 100644 test/javascripts/acceptance/group-index-test.js.es6 diff --git a/app/assets/javascripts/discourse/components/group-member-dropdown.js.es6 b/app/assets/javascripts/discourse/components/group-member-dropdown.js.es6 new file mode 100644 index 00000000000..1b5d97d00be --- /dev/null +++ b/app/assets/javascripts/discourse/components/group-member-dropdown.js.es6 @@ -0,0 +1,32 @@ +import { iconHTML } from 'discourse-common/lib/icon-library'; +import DropdownButton from 'discourse/components/dropdown-button'; +import computed from "ember-addons/ember-computed-decorators"; + +export default DropdownButton.extend({ + buttonExtraClasses: 'no-text', + title: '', + text: iconHTML('ellipsis-h'), + classNames: ['group-member-dropdown'], + + @computed() + dropDownContent() { + const items = [ + { + id: 'removeMember', + title: I18n.t('groups.members.remove_member'), + description: I18n.t('groups.members.remove_member_description'), + icon: 'user-times' + } + ]; + + return items; + }, + + clicked(id) { + switch (id) { + case 'removeMember': + this.sendAction('removeMember', this.get('member')); + break; + } + } +}); diff --git a/app/assets/javascripts/discourse/controllers/group-index.js.es6 b/app/assets/javascripts/discourse/controllers/group-index.js.es6 index 269ecab7cdb..1223e764211 100644 --- a/app/assets/javascripts/discourse/controllers/group-index.js.es6 +++ b/app/assets/javascripts/discourse/controllers/group-index.js.es6 @@ -27,6 +27,11 @@ export default Ember.Controller.extend({ return members && members.length > 0; }, + @computed + canManageGroup() { + return this.currentUser && this.currentUser.canManageGroup(this.get('model')); + }, + actions: { toggleActions() { this.toggleProperty("showActions"); diff --git a/app/assets/javascripts/discourse/controllers/group.js.es6 b/app/assets/javascripts/discourse/controllers/group.js.es6 index 755e6fecde3..c0df0d65132 100644 --- a/app/assets/javascripts/discourse/controllers/group.js.es6 +++ b/app/assets/javascripts/discourse/controllers/group.js.es6 @@ -19,7 +19,8 @@ export default Ember.Controller.extend({ const membersTab = Tab.create({ name: 'members', route: 'group.index', - icon: 'users' + icon: 'users', + i18nKey: "members.title" }); membersTab.set('count', userCount); diff --git a/app/assets/javascripts/discourse/routes/group-index.js.es6 b/app/assets/javascripts/discourse/routes/group-index.js.es6 index 003a4a8d9e1..faac0525b0e 100644 --- a/app/assets/javascripts/discourse/routes/group-index.js.es6 +++ b/app/assets/javascripts/discourse/routes/group-index.js.es6 @@ -1,6 +1,6 @@ export default Discourse.Route.extend({ titleToken() { - return I18n.t('groups.members'); + return I18n.t('groups.members.title'); }, model() { diff --git a/app/assets/javascripts/discourse/templates/components/group-members-input.hbs b/app/assets/javascripts/discourse/templates/components/group-members-input.hbs index 4f0ab683ccb..fc0e9667b85 100644 --- a/app/assets/javascripts/discourse/templates/components/group-members-input.hbs +++ b/app/assets/javascripts/discourse/templates/components/group-members-input.hbs @@ -1,4 +1,4 @@ - + {{#if model.members}}
diff --git a/app/assets/javascripts/discourse/templates/group-index.hbs b/app/assets/javascripts/discourse/templates/group-index.hbs index a58ed87a3c4..57f3b503a8c 100644 --- a/app/assets/javascripts/discourse/templates/group-index.hbs +++ b/app/assets/javascripts/discourse/templates/group-index.hbs @@ -5,6 +5,7 @@ {{group-index-toggle order=order desc=desc field='username_lower' i18nKey='username'}} {{group-index-toggle order=order desc=desc field='last_posted_at' i18nKey='last_post'}} {{group-index-toggle order=order desc=desc field='last_seen_at' i18nKey='last_seen'}} + @@ -21,6 +22,14 @@ {{bound-date m.last_seen_at}} + + + {{#if canManageGroup}} + {{group-member-dropdown + removeMember="removeMember" + member=m}} + {{/if}} + {{/each}} diff --git a/app/assets/stylesheets/common/base/group.scss b/app/assets/stylesheets/common/base/group.scss index 6b4586ad7de..059680df3ea 100644 --- a/app/assets/stylesheets/common/base/group.scss +++ b/app/assets/stylesheets/common/base/group.scss @@ -124,6 +124,10 @@ table.group-members { text-align: left; } + th:last-child { + width: 5%; + } + th.group-members-actions { width: 5%; } diff --git a/app/assets/stylesheets/common/components/group-member-dropdown.scss b/app/assets/stylesheets/common/components/group-member-dropdown.scss new file mode 100644 index 00000000000..49b3209fd23 --- /dev/null +++ b/app/assets/stylesheets/common/components/group-member-dropdown.scss @@ -0,0 +1,9 @@ +.group-member-dropdown { + ul { + width: 250px; + top: 27px; + bottom: auto; + left: -217px; + text-align: left; + } +} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index aebfd9ea785..cc5b80ad8cc 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -464,7 +464,10 @@ en: one: "Group" other: "Groups" activity: "Activity" - members: "Members" + members: + title: "Members" + remove_member: "Remove member" + remove_member_description: "Remove a member from this group" topics: "Topics" posts: "Posts" mentions: "Mentions" @@ -1368,7 +1371,7 @@ en: desc: Whispers are only visible to staff members create_topic: label: "New Topic" - shared_draft: + shared_draft: label: "Shared Draft" desc: "Draft a topic that will only be visible to staff" diff --git a/test/javascripts/acceptance/group-index-test.js.es6 b/test/javascripts/acceptance/group-index-test.js.es6 new file mode 100644 index 00000000000..fd22b18d0da --- /dev/null +++ b/test/javascripts/acceptance/group-index-test.js.es6 @@ -0,0 +1,31 @@ +import { acceptance, logIn } from "helpers/qunit-helpers"; + +acceptance("Group Members"); + +QUnit.test("Viewing Members as anon user", assert => { + visit("/groups/discourse"); + + andThen(() => { + assert.ok(count('.avatar-flair .fa-adjust') === 1, "it displays the group's avatar flair"); + assert.ok(count('.group-members tr') > 0, "it lists group members"); + + assert.ok( + count('.group-member-dropdown') === 0, + 'it does not allow anon user to manage group members' + ); + }); +}); + +QUnit.test("Viewing Members as an admin user", assert => { + logIn(); + Discourse.reset(); + + visit("/groups/discourse"); + + andThen(() => { + assert.ok( + count('.group-member-dropdown') > 0, + 'it allows admin user to manage group members' + ); + }); +}); diff --git a/test/javascripts/acceptance/groups-test.js.es6 b/test/javascripts/acceptance/groups-test.js.es6 index 19106a1ace6..0c3e94ddeda 100644 --- a/test/javascripts/acceptance/groups-test.js.es6 +++ b/test/javascripts/acceptance/groups-test.js.es6 @@ -69,10 +69,6 @@ QUnit.test("Anonymous Viewing Group", assert => { visit("/groups/discourse"); andThen(() => { - assert.ok(count('.avatar-flair .fa-adjust') === 1, "it displays the group's avatar flair"); - assert.ok(count('.group-members tr') > 0, "it lists group members"); - assert.ok(count('.group-message-button') === 0, 'it does not show group message button'); - assert.equal( count(".nav-pills li a[title='Messages']"), 0,