diff options
author | Luke Bennett <lukeeeebennettplus@gmail.com> | 2016-10-19 04:06:45 +0100 |
---|---|---|
committer | Luke Bennett <lukeeeebennettplus@gmail.com> | 2016-10-19 04:22:23 +0100 |
commit | 7633e36930dfbd07a6376e57a13168d660fc2c2a (patch) | |
tree | a90c5d472883c84f1ae0377810969aa7bcbaa8b6 | |
parent | ea9aee35a334fae2cc55e67a52c01e30fe337263 (diff) | |
download | gitlab-ce-23206-load-issuable-participants-asynchronously.tar.gz |
Created new participants actions and added clientside templating driven by ajax request23206-load-issuable-participants-asynchronously
-rw-r--r-- | app/assets/javascripts/issuable_context.js | 69 | ||||
-rw-r--r-- | app/assets/javascripts/issuable_context.js.es6 | 104 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/issuable.scss | 4 | ||||
-rw-r--r-- | app/controllers/projects/issues_controller.rb | 13 | ||||
-rw-r--r-- | app/controllers/projects/merge_requests_controller.rb | 13 | ||||
-rw-r--r-- | app/views/shared/issuable/_participants.html.haml | 37 | ||||
-rw-r--r-- | config/routes/project.rb | 2 |
7 files changed, 155 insertions, 87 deletions
diff --git a/app/assets/javascripts/issuable_context.js b/app/assets/javascripts/issuable_context.js deleted file mode 100644 index 8147e83ffe8..00000000000 --- a/app/assets/javascripts/issuable_context.js +++ /dev/null @@ -1,69 +0,0 @@ -(function() { - this.IssuableContext = (function() { - function IssuableContext(currentUser) { - this.initParticipants(); - new UsersSelect(currentUser); - $('select.select2').select2({ - width: 'resolve', - dropdownAutoWidth: true - }); - $(".issuable-sidebar .inline-update").on("change", "select", function() { - return $(this).submit(); - }); - $(".issuable-sidebar .inline-update").on("change", ".js-assignee", function() { - return $(this).submit(); - }); - $(document).off('click', '.issuable-sidebar .dropdown-content a').on('click', '.issuable-sidebar .dropdown-content a', function(e) { - return e.preventDefault(); - }); - $(document).off('click', '.edit-link').on('click', '.edit-link', function(e) { - var $block, $selectbox; - e.preventDefault(); - $block = $(this).parents('.block'); - $selectbox = $block.find('.selectbox'); - if ($selectbox.is(':visible')) { - $selectbox.hide(); - $block.find('.value').show(); - } else { - $selectbox.show(); - $block.find('.value').hide(); - } - if ($selectbox.is(':visible')) { - return setTimeout(function() { - return $block.find('.dropdown-menu-toggle').trigger('click'); - }, 0); - } - }); - $(".right-sidebar").niceScroll(); - } - - IssuableContext.prototype.initParticipants = function() { - var _this; - _this = this; - $(document).on("click", ".js-participants-more", this.toggleHiddenParticipants); - return $(".js-participants-author").each(function(i) { - if (i >= _this.PARTICIPANTS_ROW_COUNT) { - return $(this).addClass("js-participants-hidden").hide(); - } - }); - }; - - IssuableContext.prototype.toggleHiddenParticipants = function(e) { - var currentText, lessText, originalText; - e.preventDefault(); - currentText = $(this).text().trim(); - lessText = $(this).data("less-text"); - originalText = $(this).data("original-text"); - if (currentText === originalText) { - $(this).text(lessText); - } else { - $(this).text(originalText); - } - return $(".js-participants-hidden").toggle(); - }; - - return IssuableContext; - - })(); - -}).call(this); diff --git a/app/assets/javascripts/issuable_context.js.es6 b/app/assets/javascripts/issuable_context.js.es6 new file mode 100644 index 00000000000..802e1f9763e --- /dev/null +++ b/app/assets/javascripts/issuable_context.js.es6 @@ -0,0 +1,104 @@ +(function() { + this.IssuableContext = (function() { + function IssuableContext(currentUser) { + this.initParticipants(); + new UsersSelect(currentUser); + $('select.select2').select2({ + width: 'resolve', + dropdownAutoWidth: true + }); + $(".issuable-sidebar .inline-update").on("change", "select", function() { + return $(this).submit(); + }); + $(".issuable-sidebar .inline-update").on("change", ".js-assignee", function() { + return $(this).submit(); + }); + $(document).off('click', '.issuable-sidebar .dropdown-content a').on('click', '.issuable-sidebar .dropdown-content a', function(e) { + return e.preventDefault(); + }); + $(document).off('click', '.edit-link').on('click', '.edit-link', function(e) { + var $block, $selectbox; + e.preventDefault(); + $block = $(this).parents('.block'); + $selectbox = $block.find('.selectbox'); + if ($selectbox.is(':visible')) { + $selectbox.hide(); + $block.find('.value').show(); + } else { + $selectbox.show(); + $block.find('.value').hide(); + } + if ($selectbox.is(':visible')) { + return setTimeout(function() { + return $block.find('.dropdown-menu-toggle').trigger('click'); + }, 0); + } + }); + $(".right-sidebar").niceScroll(); + } + + IssuableContext.prototype.initParticipants = function() { + const participantsBlock = document.querySelector('.js-participants-block'); + this.participantsCount = participantsBlock.querySelector('.count'); + this.participantsTitle = participantsBlock.querySelector('.title'); + this.participantsList = participantsBlock.querySelector('.participants-list'); + + this.participantsOptions = participantsBlock.querySelector('#js-participants-options').dataset; + this.participantTemplate = _.template(_.unescape(participantsBlock.querySelector('#participant-template').innerHTML)); + this.moreParticipantsTemplate = _.template(_.unescape(participantsBlock.querySelector('#more-participants-template').innerHTML)); + this.PARTICIPANTS_ROW_COUNT = parseInt(this.participantsOptions.participantsRow); + + this.participantsOptions.participantsEndpoint ? this.loadParticipants() : this.bindParticipants(); + }; + + IssuableContext.prototype.loadParticipants = function() { + $.get(this.participantsOptions.participantsEndpoint) + .then((participants) => { + this.renderParticipants(participants); + this.bindParticipants(); + }); + }; + + IssuableContext.prototype.renderParticipants = function(participants) { + this.participantsCount.textContent = participants.length; + this.participantsTitle.textContent = `${participants.length} participant${participants.length > 1 ? 's' : ''}`; + let participantsListInnerHTML = ''; + for (participant of participants) { + participantsListInnerHTML += this.participantTemplate(participant); + } + if (participants.length > this.PARTICIPANTS_ROW_COUNT) { + participantsListInnerHTML += this.moreParticipantsTemplate({ + moreCount: `${participants.length - this.PARTICIPANTS_ROW_COUNT}` + }); + } + this.participantsList.innerHTML = participantsListInnerHTML; + }; + + IssuableContext.prototype.bindParticipants = function() { + $(document).on("click", ".js-participants-more", this.toggleHiddenParticipants); + return $(".js-participants-author").each((i, author) => { + if (i >= this.PARTICIPANTS_ROW_COUNT) { + return $(author).addClass("js-participants-hidden").hide(); + } + }); + }; + + IssuableContext.prototype.toggleHiddenParticipants = function(e) { + var currentText, lessText, originalText; + e.preventDefault(); + currentText = $(this).text().trim(); + lessText = $(this).data("less-text"); + originalText = $(this).data("original-text"); + if (currentText === originalText) { + $(this).text(lessText); + } else { + $(this).text(originalText); + } + return $(".js-participants-hidden").toggle(); + }; + + return IssuableContext; + + })(); + +}).call(this); diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 230b927a17d..a7a37b24bf3 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -320,6 +320,10 @@ .participants-list { margin: -5px; + + .spinner { + margin-left: 5px; + } } .participants-author { diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 96041b07647..67981d91678 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -5,11 +5,12 @@ class Projects::IssuesController < Projects::ApplicationController include ToggleAwardEmoji include IssuableCollections include SpammableActions + include ApplicationHelper before_action :redirect_to_external_issue_tracker, only: [:index, :new] before_action :module_enabled before_action :issue, only: [:edit, :update, :show, :referenced_merge_requests, - :related_branches, :can_create_branch] + :related_branches, :can_create_branch, :participants] # Allow read any issue before_action :authorize_read_issue!, only: [:show] @@ -156,6 +157,16 @@ class Projects::IssuesController < Projects::ApplicationController end end + def participants + participants = ::Projects::ParticipantsService.new(@project, current_user).execute(@noteable) + participants.map do |participant| + user = User.find_by_username(participant[:username]) + participant[:link] = user_path(participant) + participant[:avatar] = avatar_icon(user) + end + render json: participants + end + protected def issue diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index a39b47b6d95..8a945f2fc4c 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -6,11 +6,12 @@ class Projects::MergeRequestsController < Projects::ApplicationController include NotesHelper include ToggleAwardEmoji include IssuableCollections + include ApplicationHelper before_action :module_enabled before_action :merge_request, only: [ :edit, :update, :show, :diffs, :commits, :conflicts, :conflict_for_path, :builds, :pipelines, :merge, :merge_check, - :ci_status, :ci_environments_status, :toggle_subscription, :cancel_merge_when_build_succeeds, :remove_wip, :resolve_conflicts, :assign_related_issues + :ci_status, :ci_environments_status, :toggle_subscription, :cancel_merge_when_build_succeeds, :remove_wip, :resolve_conflicts, :assign_related_issues, :participants ] before_action :validates_merge_request, only: [:show, :diffs, :commits, :builds, :pipelines] before_action :define_show_vars, only: [:show, :diffs, :commits, :conflicts, :conflict_for_path, :builds, :pipelines] @@ -437,6 +438,16 @@ class Projects::MergeRequestsController < Projects::ApplicationController render json: environments end + def participants + participants = ::Projects::ParticipantsService.new(@project, current_user).execute(@issuable) + participants.map do |participant| + user = User.find_by_username(participant[:username]) + participant[:link] = user_path(participant) + participant[:avatar] = avatar_icon(user) + end + render json: participants + end + protected def selected_target_project diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml index 33a9a494857..dd149378150 100644 --- a/app/views/shared/issuable/_participants.html.haml +++ b/app/views/shared/issuable/_participants.html.haml @@ -1,20 +1,25 @@ -- participants_row = 7 -- participants_size = participants.size -- participants_extra = participants_size - participants_row -.block.participants +- if current_controller?(:issues) + - participants_endpoint = participants_namespace_project_issue_path(@project.namespace, @project, @issue) +- else + - participants_endpoint = participants_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + +.block.participants.js-participants-block + #js-participants-options{ data: { 'participants-endpoint': participants_endpoint, 'participants-row': 7 } } .sidebar-collapsed-icon = icon('users') - %span - = participants.count + %span.count + = icon('spinner spin') .title.hide-collapsed - = pluralize participants.count, "participant" + Participants .hide-collapsed.participants-list - - participants.each do |participant| - .participants-author.js-participants-author - = link_to_member(@project, participant, name: false, size: 24) - - if participants_extra > 0 - %div.participants-more - %a.js-participants-more{href: "#", data: {original_text: "+ #{participants_size - 7} more", less_text: "- show less"}} - + #{participants_extra} more -:javascript - IssuableContext.prototype.PARTICIPANTS_ROW_COUNT = #{participants_row}; + = icon('spinner spin', class: 'spinner') + + %script#participant-template{ type: 'text/template' } + .participants-author.js-participants-author + %a.author_link.has_tooltip{ href: '<%- link %>', data: { 'original-title': '<%- name %>' } } + %img.avatar.avatar-inline.s24{ width: '24', src: '<%- avatar %>' } + + %script#more-participants-template{ type: 'text/template' } + .participants-more + %a.js-participants-more{ href: '#', data: { 'original-text': '+ <%- moreCount %> more', 'less-text': '- show less' } } + + <%- moreCount %> more diff --git a/config/routes/project.rb b/config/routes/project.rb index 711a59df744..d87d4da64e4 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -280,6 +280,7 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: get :diff_for_path post :resolve_conflicts post :assign_related_issues + get :participants end collection do @@ -388,6 +389,7 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: get :referenced_merge_requests get :related_branches get :can_create_branch + get :participants end collection do post :bulk_update |