diff --git a/app/assets/javascripts/discourse/components/mobile-nav.js.es6 b/app/assets/javascripts/discourse/components/mobile-nav.js.es6 index cee8a2111aa..deccf48ef2d 100644 --- a/app/assets/javascripts/discourse/components/mobile-nav.js.es6 +++ b/app/assets/javascripts/discourse/components/mobile-nav.js.es6 @@ -14,6 +14,7 @@ export default Ember.Component.extend({ }, tagName: 'ul', + selectedHtml: null, classNames: ['mobile-nav'], diff --git a/app/assets/javascripts/discourse/controllers/group-posts.js.es6 b/app/assets/javascripts/discourse/controllers/group-activity-posts.js.es6 similarity index 100% rename from app/assets/javascripts/discourse/controllers/group-posts.js.es6 rename to app/assets/javascripts/discourse/controllers/group-activity-posts.js.es6 diff --git a/app/assets/javascripts/discourse/controllers/group-activity.js.es6 b/app/assets/javascripts/discourse/controllers/group-activity.js.es6 new file mode 100644 index 00000000000..955822ffcf5 --- /dev/null +++ b/app/assets/javascripts/discourse/controllers/group-activity.js.es6 @@ -0,0 +1,10 @@ +import computed from 'ember-addons/ember-computed-decorators'; + +export default Ember.Controller.extend({ + application: Ember.inject.controller(), + + @computed('model.is_group_user') + showGroupMessages(isGroupUser) { + return isGroupUser || (this.currentUser && this.currentUser.admin); + } +}); diff --git a/app/assets/javascripts/discourse/controllers/group.js.es6 b/app/assets/javascripts/discourse/controllers/group.js.es6 index 8ce8e7c821f..4a8a87c0851 100644 --- a/app/assets/javascripts/discourse/controllers/group.js.es6 +++ b/app/assets/javascripts/discourse/controllers/group.js.es6 @@ -16,19 +16,15 @@ export default Ember.Controller.extend({ application: Ember.inject.controller(), counts: null, showing: 'members', + tabs: [ - Tab.create({ name: 'members', active: true, 'location': 'group.index' }), - Tab.create({ name: 'posts' }), - Tab.create({ name: 'topics' }), - Tab.create({ name: 'mentions' }), - Tab.create({ name: 'messages', requiresMembership: true }), + Tab.create({ name: 'members', 'location': 'group.index', icon: 'users' }), + Tab.create({ name: 'activity' }), Tab.create({ - name: 'edit', i18nKey: 'edit.title', - requiresMembership: true, requiresGroupAdmin: true + name: 'edit', i18nKey: 'edit.title', icon: 'pencil', requiresGroupAdmin: true }), Tab.create({ - name: 'logs', i18nKey: 'logs.title', - requiresMembership: true, requiresGroupAdmin: true + name: 'logs', i18nKey: 'logs.title', icon: 'list-alt', requiresGroupAdmin: true }) ], @@ -57,31 +53,22 @@ export default Ember.Controller.extend({ this.get('tabs')[0].set('count', this.get('model.user_count')); }, - @observes('showing') - showingChanged() { - const showing = this.get('showing'); - - this.get('tabs').forEach(tab => { - tab.set('active', showing === tab.get('name')); - }); - }, - @computed('model.is_group_user', 'model.is_group_owner', 'model.automatic') getTabs(isGroupUser, isGroupOwner, automatic) { return this.get('tabs').filter(t => { - let isMember = false; + let display = true; - if (this.currentUser && !automatic) { + if (this.currentUser) { let admin = this.currentUser.admin; - if (t.get('requiresGroupAdmin')) { - isMember = admin || isGroupOwner; + if (automatic && t.get('requiresGroupAdmin')) { + display = false; } else { - isMember = admin || isGroupUser; + display = admin || isGroupOwner; } } - return isMember || !t.get('requiresMembership'); + return display; }); } }); diff --git a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 b/app/assets/javascripts/discourse/routes/app-route-map.js.es6 index 38cebdd9659..7dc4502cf75 100644 --- a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 +++ b/app/assets/javascripts/discourse/routes/app-route-map.js.es6 @@ -49,10 +49,14 @@ export default function() { this.route('group', { path: '/groups/:name', resetNamespace: true }, function() { this.route('members'); - this.route('posts'); - this.route('topics'); - this.route('mentions'); - this.route('messages'); + + this.route('activity', function() { + this.route('posts'); + this.route('topics'); + this.route('mentions'); + this.route('messages'); + }); + this.route('logs'); this.route('edit'); }); diff --git a/app/assets/javascripts/discourse/routes/group-activity-mentions.js.es6 b/app/assets/javascripts/discourse/routes/group-activity-mentions.js.es6 new file mode 100644 index 00000000000..48f4fc7d9d5 --- /dev/null +++ b/app/assets/javascripts/discourse/routes/group-activity-mentions.js.es6 @@ -0,0 +1,3 @@ +import { buildGroupPage } from 'discourse/routes/group-activity-posts'; + +export default buildGroupPage('mentions'); diff --git a/app/assets/javascripts/discourse/routes/group-activity-messages.js.es6 b/app/assets/javascripts/discourse/routes/group-activity-messages.js.es6 new file mode 100644 index 00000000000..660a5c7cd5f --- /dev/null +++ b/app/assets/javascripts/discourse/routes/group-activity-messages.js.es6 @@ -0,0 +1,3 @@ +import { buildGroupPage } from 'discourse/routes/group-activity-posts'; + +export default buildGroupPage('messages'); diff --git a/app/assets/javascripts/discourse/routes/group-posts.js.es6 b/app/assets/javascripts/discourse/routes/group-activity-posts.js.es6 similarity index 79% rename from app/assets/javascripts/discourse/routes/group-posts.js.es6 rename to app/assets/javascripts/discourse/routes/group-activity-posts.js.es6 index 25ee29e4dd0..03cd7ec1147 100644 --- a/app/assets/javascripts/discourse/routes/group-posts.js.es6 +++ b/app/assets/javascripts/discourse/routes/group-activity-posts.js.es6 @@ -11,12 +11,12 @@ export function buildGroupPage(type) { }, setupController(controller, model) { - this.controllerFor('group-posts').setProperties({ model, type }); + this.controllerFor('group-activity-posts').setProperties({ model, type }); this.controllerFor("group").set("showing", type); }, renderTemplate() { - this.render('group-posts'); + this.render('group-activity-posts'); }, actions: { diff --git a/app/assets/javascripts/discourse/routes/group-activity-topics.js.es6 b/app/assets/javascripts/discourse/routes/group-activity-topics.js.es6 new file mode 100644 index 00000000000..16164a51bb3 --- /dev/null +++ b/app/assets/javascripts/discourse/routes/group-activity-topics.js.es6 @@ -0,0 +1,3 @@ +import { buildGroupPage } from 'discourse/routes/group-activity-posts'; + +export default buildGroupPage('topics'); diff --git a/app/assets/javascripts/discourse/routes/group-activity.js.es6 b/app/assets/javascripts/discourse/routes/group-activity.js.es6 new file mode 100644 index 00000000000..84011db59f4 --- /dev/null +++ b/app/assets/javascripts/discourse/routes/group-activity.js.es6 @@ -0,0 +1,5 @@ +export default Ember.Route.extend({ + beforeModel: function() { + this.transitionTo("group.activity.posts"); + } +}); diff --git a/app/assets/javascripts/discourse/routes/group-mentions.js.es6 b/app/assets/javascripts/discourse/routes/group-mentions.js.es6 deleted file mode 100644 index 2a12734dc18..00000000000 --- a/app/assets/javascripts/discourse/routes/group-mentions.js.es6 +++ /dev/null @@ -1,3 +0,0 @@ -import { buildGroupPage } from 'discourse/routes/group-posts'; - -export default buildGroupPage('mentions'); diff --git a/app/assets/javascripts/discourse/routes/group-messages.js.es6 b/app/assets/javascripts/discourse/routes/group-messages.js.es6 deleted file mode 100644 index c800d6f7774..00000000000 --- a/app/assets/javascripts/discourse/routes/group-messages.js.es6 +++ /dev/null @@ -1,3 +0,0 @@ -import { buildGroupPage } from 'discourse/routes/group-posts'; - -export default buildGroupPage('messages'); diff --git a/app/assets/javascripts/discourse/routes/group-topics.js.es6 b/app/assets/javascripts/discourse/routes/group-topics.js.es6 deleted file mode 100644 index be4e87077e9..00000000000 --- a/app/assets/javascripts/discourse/routes/group-topics.js.es6 +++ /dev/null @@ -1,3 +0,0 @@ -import { buildGroupPage } from 'discourse/routes/group-posts'; - -export default buildGroupPage('topics'); diff --git a/app/assets/javascripts/discourse/templates/group-posts.hbs b/app/assets/javascripts/discourse/templates/group-activity-posts.hbs similarity index 100% rename from app/assets/javascripts/discourse/templates/group-posts.hbs rename to app/assets/javascripts/discourse/templates/group-activity-posts.hbs diff --git a/app/assets/javascripts/discourse/templates/group.hbs b/app/assets/javascripts/discourse/templates/group.hbs index e570322d699..571c1813d6e 100644 --- a/app/assets/javascripts/discourse/templates/group.hbs +++ b/app/assets/javascripts/discourse/templates/group.hbs @@ -1,6 +1,4 @@ <div class="container group"> - {{#link-to "groups" class='group-breadcrumb'}}{{fa-icon 'arrow-left'}} {{i18n 'groups.index.title'}}{{/link-to}} - <div class='group-details-container'> <div class='group-info'> {{#if model.flair_url}} @@ -31,10 +29,11 @@ {{/if}} </div> - {{#mobile-nav class='group-nav' desktopClass="pull-left nav nav-stacked" currentPath=application.currentPath}} + {{#mobile-nav class='group-nav' desktopClass="nav nav-pills" currentPath=application.currentPath}} {{#each getTabs as |tab|}} - <li class="{{if tab.active 'active'}}"> + <li> {{#link-to tab.location model title=tab.message}} + {{#if tab.icon}}{{fa-icon tab.icon}}{{/if}} {{tab.message}} {{#if tab.count}}<span class='count'>({{tab.count}})</span>{{/if}} {{/link-to}} @@ -42,9 +41,7 @@ {{/each}} {{/mobile-nav}} - <div class='pull-left group-outlet'> - <div class='user-main'> - {{outlet}} - </div> + <div class='group-outlet'> + {{outlet}} </div> </div> diff --git a/app/assets/javascripts/discourse/templates/group/activity.hbs b/app/assets/javascripts/discourse/templates/group/activity.hbs new file mode 100644 index 00000000000..d03a14e84f1 --- /dev/null +++ b/app/assets/javascripts/discourse/templates/group/activity.hbs @@ -0,0 +1,27 @@ +<div class='group-activity container'> + {{#mobile-nav class='group-activity-nav' desktopClass="pull-left nav nav-stacked" currentPath=application.currentPath}} + <li> + {{#link-to 'group.activity.posts'}}{{i18n 'groups.posts'}}{{/link-to}} + </li> + + <li> + {{#link-to 'group.activity.topics'}}{{i18n 'groups.topics'}}{{/link-to}} + </li> + + <li> + {{#link-to 'group.activity.mentions'}}{{i18n 'groups.mentions'}}{{/link-to}} + </li> + + {{#if showGroupMessages}} + <li> + {{#link-to 'group.activity.messages'}}{{i18n 'groups.messages'}}{{/link-to}} + </li> + {{/if}} + {{/mobile-nav}} + + <div class="{{if site.mobileView "" "pull-left"}} group-activity-outlet"> + <div class='user-main'> + {{outlet}} + </div> + </div> +</div> diff --git a/app/assets/javascripts/discourse/templates/mobile/components/mobile-nav.hbs b/app/assets/javascripts/discourse/templates/mobile/components/mobile-nav.hbs index 6b46d500ee7..cdab47c07bb 100644 --- a/app/assets/javascripts/discourse/templates/mobile/components/mobile-nav.hbs +++ b/app/assets/javascripts/discourse/templates/mobile/components/mobile-nav.hbs @@ -1,4 +1,6 @@ -<li><a {{action 'toggleExpanded'}}>{{{selectedHtml}}} <i class='fa fa-caret-down'></i></a></li> +{{#if selectedHtml}} + <li><a {{action 'toggleExpanded'}}>{{{selectedHtml}}} <i class='fa fa-caret-down'></i></a></li> +{{/if}} <ul class='drop {{if expanded 'expanded'}}'> {{yield}} </ul> diff --git a/app/assets/stylesheets/common/base/group.scss b/app/assets/stylesheets/common/base/group.scss index 5654944fde8..29ee2625611 100644 --- a/app/assets/stylesheets/common/base/group.scss +++ b/app/assets/stylesheets/common/base/group.scss @@ -1,12 +1,7 @@ .group-details-container { background: rgba(230, 230, 230, 0.3); padding: 20px; - margin-bottom: 30px; -} - -.group-breadcrumb { - display: block; - margin-bottom: 10px; + margin-bottom: 15px; } .group-info { @@ -160,9 +155,11 @@ table.group-members { } } -.group-edit .form-horizontal { - label { - font-weight: bold; +.group-edit { + .form-horizontal { + label { + font-weight: bold; + } } } diff --git a/app/assets/stylesheets/common/components/group-members-input.scss b/app/assets/stylesheets/common/components/group-members-input.scss index b620ab3c027..fde660de04a 100644 --- a/app/assets/stylesheets/common/components/group-members-input.scss +++ b/app/assets/stylesheets/common/components/group-members-input.scss @@ -1,8 +1,4 @@ .group-members-input { - .ac-wrap { - width: 100% !important; - } - .group-members-input-selector { margin-top: 10px; diff --git a/app/assets/stylesheets/desktop/group.scss b/app/assets/stylesheets/desktop/group.scss index 1114dae40b7..5c913eef7f3 100644 --- a/app/assets/stylesheets/desktop/group.scss +++ b/app/assets/stylesheets/desktop/group.scss @@ -1,12 +1,59 @@ -.group-outlet { - width: 75%; -} - .group-nav { - width: 20%; - margin-right: 30px; + li { + float: left; + + a, i { + color: dark-light-choose(scale-color($primary, $lightness: 40%), scale-color($secondary, $lightness: 40%)); + } + + .active { + a, i { + color: $secondary; + } + } + } + + margin-bottom: 30px; } .group-info { margin-bottom: 20px; } + +.group-activity-nav { + width: 15%; + background-color: transparent; + + li { + border: none; + + a { + padding: 8px 13px; + } + + a.active { + background-color: transparent; + font-weight: bold; + color: $primary; + } + + a.active:after { + display: none; + } + } +} + +.group-activity-outlet { + width: 85%; +} + +.group-edit { + border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%); + padding: 10px; + + .form-horizontal { + button { + float: none; + } + } +} diff --git a/app/assets/stylesheets/mobile/group.scss b/app/assets/stylesheets/mobile/group.scss index b465ba77612..cfbb849340b 100644 --- a/app/assets/stylesheets/mobile/group.scss +++ b/app/assets/stylesheets/mobile/group.scss @@ -10,7 +10,7 @@ margin: 5px 0px 0px 0px; } -.group-nav, .group-outlet { +.group-nav { width: 100%; } @@ -20,16 +20,20 @@ .group-nav.mobile-nav { margin-bottom: 15px; +} - > li { - a { - color: white; +.group-activity { + position: relative; +} - .fa { color: white; } - } - } +.group-activity-nav.mobile-nav { + position: absolute; + right: 0px; + top: -50px; +} - background-color: $quaternary; +.group-activity-outlet { + float: none; } .form-horizontal { @@ -55,7 +59,7 @@ table.group-members { tr { .user-info { - width: 130px; + width: auto; } td { diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 3e42afcc4d2..0e4db9e6f72 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -432,6 +432,7 @@ en: title: one: "group" other: "groups" + activity: "Activity" members: "Members" topics: "Topics" posts: "Posts" diff --git a/config/routes.rb b/config/routes.rb index 87580f122ba..cc95f859fea 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -401,6 +401,8 @@ Discourse::Application.routes.draw do get "posts.rss" => "groups#posts_feed", format: :rss get "mentions.rss" => "groups#mentions_feed", format: :rss + get 'activity' => "groups#show" + get 'activity/:filter' => "groups#show" get 'members' get 'posts' get 'topics' diff --git a/test/javascripts/acceptance/groups-test.js.es6 b/test/javascripts/acceptance/groups-test.js.es6 index f7f649f26df..74422b10658 100644 --- a/test/javascripts/acceptance/groups-test.js.es6 +++ b/test/javascripts/acceptance/groups-test.js.es6 @@ -24,24 +24,31 @@ test("Viewing Group", () => { ok(count('.group-members tr') > 0, "it lists group members"); }); - visit("/groups/discourse/posts"); + click(".nav-pills li a[title='Activity']"); + andThen(() => { ok(count('.user-stream .item') > 0, "it lists stream items"); }); - visit("/groups/discourse/topics"); + click(".group-activity-nav li a[href='/groups/discourse/activity/topics']"); + andThen(() => { ok(count('.user-stream .item') > 0, "it lists stream items"); }); - visit("/groups/discourse/mentions"); + click(".group-activity-nav li a[href='/groups/discourse/activity/mentions']"); + andThen(() => { ok(count('.user-stream .item') > 0, "it lists stream items"); }); - visit("/groups/discourse/messages"); andThen(() => { - ok(find(".nav-stacked li a[title='Messages']").length === 0, 'it should not show messages tab if user is not admin'); + equal( + find(".group-activity li a[href='/groups/discourse/activity/messages']").length, + 0, + 'it should not show messages tab if user is not a group user or admin' + ); + ok(find(".nav-stacked li a[title='Edit Group']").length === 0, 'it should not show messages tab if user is not admin'); ok(find(".nav-stacked li a[title='Logs']").length === 0, 'it should not show Logs tab if user is not admin'); ok(count('.user-stream .item') > 0, "it lists stream items"); @@ -55,10 +62,19 @@ test("Admin Viewing Group", () => { visit("/groups/discourse"); andThen(() => { - ok(find(".nav-stacked li a[title='Messages']").length === 1, 'it should show messages tab if user is admin'); - ok(find(".nav-stacked li a[title='Edit Group']").length === 1, 'it should show edit group tab if user is admin'); - ok(find(".nav-stacked li a[title='Logs']").length === 1, 'it should show Logs tab if user is admin'); + ok(find(".nav-pills li a[title='Edit Group']").length === 1, 'it should show edit group tab if user is admin'); + ok(find(".nav-pills li a[title='Logs']").length === 1, 'it should show Logs tab if user is admin'); equal(find('.group-info-name').text(), 'Awesome Team', 'it should display the group name'); }); + + click(".nav-pills li a[title='Activity']"); + + andThen(() => { + equal( + find(".group-activity li a[href='/groups/discourse/activity/messages']").length, + 1, + 'it should show messages tab if user is admin' + ); + }); });