summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/application.js.coffee1
-rw-r--r--app/controllers/users_controller.rb39
-rw-r--r--app/views/groups/show.html.haml3
-rw-r--r--app/views/shared/groups/_list.html.haml3
-rw-r--r--app/views/shared/projects/_list.html.haml3
-rw-r--r--app/views/users/show.html.haml64
-rw-r--r--config/routes.rb9
-rw-r--r--features/user.feature6
-rw-r--r--vendor/assets/javascripts/jquery.stickytabs.js61
9 files changed, 149 insertions, 40 deletions
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index 5463397f475..f91a56d1cc6 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -17,6 +17,7 @@
#= require jquery.atwho
#= require jquery.scrollTo
#= require jquery.turbolinks
+#= require jquery.stickytabs
#= require d3
#= require cal-heatmap
#= require turbolinks
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 6055b606086..6f7021c43fd 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -3,13 +3,6 @@ class UsersController < ApplicationController
before_action :set_user
def show
- @contributed_projects = contributed_projects.joined(@user).reject(&:forked?)
-
- @projects = PersonalProjectsFinder.new(@user).execute(current_user)
- @projects = @projects.page(params[:page]).per(PER_PAGE)
-
- @groups = @user.groups.order_id_desc
-
respond_to do |format|
format.html
@@ -25,6 +18,24 @@ class UsersController < ApplicationController
end
end
+ def groups
+ load_groups
+
+ render 'shared/groups/_list', locals: { groups: @groups }, layout: false
+ end
+
+ def user_projects
+ load_projects
+
+ render 'shared/projects/_list', locals: { projects: @projects, remote: true }, layout: false
+ end
+
+ def user_contributed_projects
+ load_contributed_projects
+
+ render 'shared/projects/_list', locals: { projects: @contributed_projects }, layout: false
+ end
+
def calendar
calendar = contributions_calendar
@timestamps = calendar.timestamps
@@ -69,6 +80,20 @@ class UsersController < ApplicationController
limit_recent(20, params[:offset])
end
+ def load_projects
+ @projects =
+ PersonalProjectsFinder.new(@user).execute(current_user)
+ .page(params[:page]).per(PER_PAGE)
+ end
+
+ def load_contributed_projects
+ @contributed_projects = contributed_projects.joined(@user)
+ end
+
+ def load_groups
+ @groups = @user.groups.order_id_desc
+ end
+
def projects_for_current_user
ProjectsFinder.new.execute(current_user)
end
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 6148d8cb3d2..76c7d5ee2e1 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -55,3 +55,6 @@
- else
%p.nav-links.no-top
No projects to show
+
+:javascript
+ $('.nav-links').stickyTabs();
diff --git a/app/views/shared/groups/_list.html.haml b/app/views/shared/groups/_list.html.haml
new file mode 100644
index 00000000000..0833c6e61e5
--- /dev/null
+++ b/app/views/shared/groups/_list.html.haml
@@ -0,0 +1,3 @@
+- if groups.any?
+ - groups.each_with_index do |group, i|
+ = render "shared/groups/group", group: group
diff --git a/app/views/shared/projects/_list.html.haml b/app/views/shared/projects/_list.html.haml
index e75af50a537..b5c0c7ed57c 100644
--- a/app/views/shared/projects/_list.html.haml
+++ b/app/views/shared/projects/_list.html.haml
@@ -6,6 +6,7 @@
- ci = false unless local_assigns[:ci] == true
- skip_namespace = false unless local_assigns[:skip_namespace] == true
- show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true
+- remote = false unless local_assigns[:remote] == true
%ul.projects-list.content-list
- if projects.any?
@@ -21,7 +22,7 @@
#{projects_limit} of #{pluralize(projects.count, 'project')} displayed.
= link_to '#', class: 'js-expand' do
Show all
- = paginate projects, theme: "gitlab" if projects.respond_to? :total_pages
+ = paginate(projects, remote: remote, theme: "gitlab") if projects.respond_to? :total_pages
- else
%h3 No projects found
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index d109635fa1e..33530ddd797 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -39,7 +39,7 @@
@#{@user.username}
%span.middle-dot-divider
Member since #{@user.created_at.to_s(:medium)}
-
+
- if @user.bio.present?
.cover-desc
%p.profile-user-bio
@@ -73,18 +73,15 @@
%li.active
= link_to "#activity", 'data-toggle' => 'tab' do
Activity
- - if @groups.any?
- %li
- = link_to "#groups", 'data-toggle' => 'tab' do
- Groups
- - if @contributed_projects.present?
- %li
- = link_to "#contributed", 'data-toggle' => 'tab' do
- Contributed projects
- - if @projects.present?
- %li
- = link_to "#personal", 'data-toggle' => 'tab' do
- Personal projects
+ %li
+ = link_to "#groups", 'data-toggle' => 'tab' do
+ Groups
+ %li
+ = link_to "#contributed", 'data-toggle' => 'tab' do
+ Contributed projects
+ %li
+ = link_to "#personal", 'data-toggle' => 'tab' do
+ Personal projects
%div{ class: container_class }
.tab-content
@@ -100,25 +97,28 @@
.content_list
= spinner
- - if @groups.any?
- .tab-pane#groups
- %ul.content-list
- - @groups.each do |group|
- = render 'shared/groups/group', group: group
-
- - if @contributed_projects.present?
- .tab-pane#contributed
- .contributed-projects
- = render 'shared/projects/list',
- projects: @contributed_projects.sort_by(&:star_count).reverse,
- projects_limit: 10, stars: true, avatar: true
-
- - if @projects.present?
- .tab-pane#personal
- .personal-projects
- = render 'shared/projects/list',
- projects: @projects.sort_by(&:star_count).reverse,
- projects_limit: 10, stars: true, avatar: true
+ .tab-pane#groups
+ %ul.content-list.user-groups
+ %h4.center.light
+ %i.fa.fa-spinner.fa-spin
+
+ .tab-pane#contributed
+ .contributed-projects
+ %h4.center.light
+ %i.fa.fa-spinner.fa-spin
+
+ .tab-pane#personal
+ .personal-projects
+ %h4.center.light
+ %i.fa.fa-spinner.fa-spin
:javascript
+ $('.nav-links').stickyTabs();
$(".user-calendar").load("#{user_calendar_path}");
+ $(".user-groups").load("#{user_groups_path}");
+ $(".contributed-projects").load("#{user_contributed_projects_path}");
+ $(".personal-projects").load("#{user_projects_path}");
+
+ $("body").on("ajax:success", function(e, data, status, xhr) {
+ $(".personal-projects").html(xhr.responseText)
+ });
diff --git a/config/routes.rb b/config/routes.rb
index a2acf170a6b..e1448d231b5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -332,6 +332,15 @@ Rails.application.routes.draw do
get 'u/:username/calendar_activities' => 'users#calendar_activities', as: :user_calendar_activities,
constraints: { username: /.*/ }
+ get 'u/:username/groups' => 'users#groups', as: :user_groups,
+ constraints: { username: /.*/ }
+
+ get 'u/:username/projects' => 'users#user_projects', as: :user_projects,
+ constraints: { username: /.*/ }
+
+ get 'u/:username/contributed_projects' => 'users#user_contributed_projects', as: :user_contributed_projects,
+ constraints: { username: /.*/ }
+
get '/u/:username' => 'users#show', as: :user,
constraints: { username: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }
diff --git a/features/user.feature b/features/user.feature
index 35eae842e77..209afab4db7 100644
--- a/features/user.feature
+++ b/features/user.feature
@@ -5,6 +5,7 @@ Feature: User
# Signed out
+ @javascript
Scenario: I visit user "John Doe" page while not signed in when he owns a public project
Given "John Doe" owns internal project "Internal"
And "John Doe" owns public project "Community"
@@ -16,6 +17,7 @@ Feature: User
# Signed in as someone else
+ @javascript
Scenario: I visit user "John Doe" page while signed in as someone else when he owns a public project
Given "John Doe" owns public project "Community"
And "John Doe" owns internal project "Internal"
@@ -26,6 +28,7 @@ Feature: User
And I should see project "Internal"
And I should see project "Community"
+ @javascript
Scenario: I visit user "John Doe" page while signed in as someone else when he is not authorized to a public project
Given "John Doe" owns internal project "Internal"
And I sign in as a user
@@ -35,6 +38,7 @@ Feature: User
And I should see project "Internal"
And I should not see project "Community"
+ @javascript
Scenario: I visit user "John Doe" page while signed in as someone else when he is not authorized to a project I can see
Given I sign in as a user
When I visit user "John Doe" page
@@ -45,6 +49,7 @@ Feature: User
# Signed in as the user himself
+ @javascript
Scenario: I visit user "John Doe" page while signed in as "John Doe" when he has a public project
Given "John Doe" owns internal project "Internal"
And "John Doe" owns public project "Community"
@@ -55,6 +60,7 @@ Feature: User
And I should see project "Internal"
And I should see project "Community"
+ @javascript
Scenario: I visit user "John Doe" page while signed in as "John Doe" when he has no public project
Given I sign in as "John Doe"
When I visit user "John Doe" page
diff --git a/vendor/assets/javascripts/jquery.stickytabs.js b/vendor/assets/javascripts/jquery.stickytabs.js
new file mode 100644
index 00000000000..8856fb04262
--- /dev/null
+++ b/vendor/assets/javascripts/jquery.stickytabs.js
@@ -0,0 +1,61 @@
+/**
+ * jQuery Plugin: Sticky Tabs
+ *
+ * @author Aidan Lister <aidan@php.net>
+ * @version 1.2.0
+ */
+(function ( $ ) {
+ $.fn.stickyTabs = function( options ) {
+ var context = this
+
+ var settings = $.extend({
+ getHashCallback: function(hash, btn) { return hash },
+ selectorAttribute: "href",
+ backToTop: false,
+ initialTab: $('li.active > a', context)
+ }, options );
+
+ // Show the tab corresponding with the hash in the URL, or the first tab.
+ var showTabFromHash = function() {
+ var hash = settings.selectorAttribute == "href" ? window.location.hash : window.location.hash.substring(1);
+ var selector = hash ? 'a[' + settings.selectorAttribute +'="' + hash + '"]' : settings.initialTab;
+ $(selector, context).tab('show');
+ setTimeout(backToTop, 1);
+ }
+
+ // We use pushState if it's available so the page won't jump, otherwise a shim.
+ var changeHash = function(hash) {
+ if (history && history.pushState) {
+ history.pushState(null, null, window.location.pathname + window.location.search + '#' + hash);
+ } else {
+ scrollV = document.body.scrollTop;
+ scrollH = document.body.scrollLeft;
+ window.location.hash = hash;
+ document.body.scrollTop = scrollV;
+ document.body.scrollLeft = scrollH;
+ }
+ }
+
+ var backToTop = function() {
+ if (settings.backToTop === true) {
+ window.scrollTo(0, 0);
+ }
+ }
+
+ // Set the correct tab when the page loads
+ showTabFromHash();
+
+ // Set the correct tab when a user uses their back/forward button
+ $(window).on('hashchange', showTabFromHash);
+
+ // Change the URL when tabs are clicked
+ $('a', context).on('click', function(e) {
+ var hash = this.href.split('#')[1];
+ var adjustedhash = settings.getHashCallback(hash, this);
+ changeHash(adjustedhash);
+ setTimeout(backToTop, 1);
+ });
+
+ return this;
+ };
+}( jQuery ));