From 95f4c0f5835e23716f7335b0a8ea52418ae93157 Mon Sep 17 00:00:00 2001
From: verg <ryanvergeront@gmail.com>
Date: Tue, 11 Feb 2014 20:56:49 -0500
Subject: [PATCH] Add User dropdown menu to Header

---
 .../controllers/user_dropdown_controller.js   | 10 ++++++++
 .../discourse/templates/header.js.handlebars  | 13 +++++++++--
 .../templates/user_dropdown.js.handlebars     | 11 +++++++++
 app/assets/stylesheets/desktop/header.scss    | 12 ++++++++++
 app/assets/stylesheets/mobile/header.scss     | 10 ++++++++
 .../user_dropdown_controller_test.js          | 23 +++++++++++++++++++
 test/javascripts/integration/header_test.js   | 19 +++++++++++++++
 7 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 app/assets/javascripts/discourse/controllers/user_dropdown_controller.js
 create mode 100644 app/assets/javascripts/discourse/templates/user_dropdown.js.handlebars
 create mode 100644 test/javascripts/controllers/user_dropdown_controller_test.js

diff --git a/app/assets/javascripts/discourse/controllers/user_dropdown_controller.js b/app/assets/javascripts/discourse/controllers/user_dropdown_controller.js
new file mode 100644
index 00000000000..4110dd01ce2
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/user_dropdown_controller.js
@@ -0,0 +1,10 @@
+Discourse.UserDropdownController = Ember.ArrayController.extend(Discourse.HasCurrentUser, {
+  showAdminLinks: Em.computed.alias("currentUser.staff"),
+
+  actions: {
+    logout: function() {
+      Discourse.logout();
+      return false;
+    }
+  }
+});
diff --git a/app/assets/javascripts/discourse/templates/header.js.handlebars b/app/assets/javascripts/discourse/templates/header.js.handlebars
index 0b5601e5a27..e850f5fd803 100644
--- a/app/assets/javascripts/discourse/templates/header.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/header.js.handlebars
@@ -89,9 +89,16 @@
             <a href='/admin/flags/active' title='{{i18n notifications.total_flagged}}' class='badge-notification flagged-posts'>{{currentUser.site_flagged_posts_count}}</a>
           {{/if}}
         </li>
-        <li class='current-user'>
+        <li class='current-user dropdown'>
           {{#if currentUser}}
-            {{#titledLinkTo 'userActivity.index' currentUser titleKey="current_user" class="icon"}}{{boundAvatar currentUser imageSize="medium" }}{{/titledLinkTo}}
+            <a class='icon'
+               data-dropdown="user-dropdown"
+               data-render="renderUserDropdown"
+               href="#"
+               title='{{i18n user.avatar.title}}'
+               id="current-user">
+                 {{boundAvatar currentUser imageSize="medium" }}
+            </a>
           {{else}}
             <div class="icon not-logged-in-avatar" {{action showLogin}}><i class='fa fa-user' title='{{i18n not_logged_in_user}}'></i></div>
           {{/if}}
@@ -106,6 +113,8 @@
         {{render siteMap}}
       {{/if}}
 
+      {{ render userDropdown }}
+
     </div>
   </div>
 </div>
diff --git a/app/assets/javascripts/discourse/templates/user_dropdown.js.handlebars b/app/assets/javascripts/discourse/templates/user_dropdown.js.handlebars
new file mode 100644
index 00000000000..4791a2f5dc1
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/user_dropdown.js.handlebars
@@ -0,0 +1,11 @@
+<section class='d-dropdown' id='user-dropdown'>
+  <ul class='user-dropdown-links'>
+    <li>{{#link-to 'userActivity' currentUser class="user-activity-link" }}{{i18n activity}}{{/link-to}}</li>
+    {{#if showAdminLinks}}
+      <li>{{#link-to 'adminUser' currentUser.username }}{{i18n admin_title}}{{/link-to}}</li>
+    {{/if}}
+    <li>{{#link-to 'userPrivateMessages.index' currentUser}}{{i18n user.private_messages}}{{/link-to}}</li>
+    <li>{{#link-to 'preferences' currentUser}}{{i18n user.preferences}}{{/link-to}}</li>
+    <li><button {{action "logout"}} class='btn btn-danger right logout'><i class='fa fa-sign-out'></i>{{i18n user.log_out}}</button></li>
+  </ul>
+</section>
diff --git a/app/assets/stylesheets/desktop/header.scss b/app/assets/stylesheets/desktop/header.scss
index 4275cbf0849..7cdd0fde4a0 100644
--- a/app/assets/stylesheets/desktop/header.scss
+++ b/app/assets/stylesheets/desktop/header.scss
@@ -237,4 +237,16 @@
     background-color: transparent;
     line-height: 20px;
   }
+
+  &#user-dropdown {
+    width: 154px;
+  }
+
+  .btn {
+    padding: 2px 8px;
+    margin-bottom: 2px;
+    .fa {
+      margin-right: 5px;
+    }
+  }
 }
diff --git a/app/assets/stylesheets/mobile/header.scss b/app/assets/stylesheets/mobile/header.scss
index 6ff15754ded..791625111de 100644
--- a/app/assets/stylesheets/mobile/header.scss
+++ b/app/assets/stylesheets/mobile/header.scss
@@ -240,4 +240,14 @@
     line-height: 20px;
   }
 
+  &#user-dropdown {
+    width: 154px;
+  }
+
+  .btn {
+    padding: 2px 8px;
+    .fa {
+      margin-right: 5px;
+    }
+  }
 }
diff --git a/test/javascripts/controllers/user_dropdown_controller_test.js b/test/javascripts/controllers/user_dropdown_controller_test.js
new file mode 100644
index 00000000000..05855d00ed8
--- /dev/null
+++ b/test/javascripts/controllers/user_dropdown_controller_test.js
@@ -0,0 +1,23 @@
+module("Discourse.UserDropdownController");
+
+test("logout action logs out the current user", function () {
+  var logout_mock = sinon.mock(Discourse, "logout");
+  logout_mock.expects("logout").once();
+
+  var controller = Discourse.UserDropdownController.create();
+  controller.send("logout");
+
+  logout_mock.verify();
+});
+
+test("showAdminLinks", function() {
+  var currentUserStub = Ember.Object.create();
+  this.stub(Discourse.User, "current").returns(currentUserStub);
+
+  var controller = Discourse.UserDropdownController.create();
+  currentUserStub.set("staff", true);
+  equal(controller.get("showAdminLinks"), true, "is true when current user is a staff member");
+
+  currentUserStub.set("staff", false);
+  equal(controller.get("showAdminLinks"), false, "is false when current user is not a staff member");
+});
diff --git a/test/javascripts/integration/header_test.js b/test/javascripts/integration/header_test.js
index 74640655952..987e32ddb2b 100644
--- a/test/javascripts/integration/header_test.js
+++ b/test/javascripts/integration/header_test.js
@@ -171,3 +171,22 @@ test("search dropdown", function() {
     equal(find("#search-dropdown .selected a").attr("href"), "another-url", "after clicking 'more of type' link, results are reloaded");
   });
 });
+
+test("user dropdown when logged in", function() {
+  expect(3);
+
+  var userDropdownSelector = "#user-dropdown";
+
+  visit("/")
+  .then(function() {
+    not(exists(userDropdownSelector + ":visible"), "initially user dropdown is closed");
+  })
+  .click("#current-user")
+  .then(function() {
+    var $userDropdown = $(userDropdownSelector);
+
+    ok(exists(userDropdownSelector + ":visible"), "is lazily rendered after user opens it");
+
+    ok(exists($userDropdown.find(".user-dropdown-links")), "has showing / hiding user-dropdown links correctly bound");
+  });
+});