Commit 3e045ff6 authored by Adam Hegyi's avatar Adam Hegyi

Expose user's availability on the issuable pages

This commit exposes and preloads the user.status.availability field on
various endpoints and pages:

- discussions API
- merge request and issue pages (assignees)
- assignee dropdown
parent 6945e1e5
......@@ -20,7 +20,7 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont
end
def preloadable_mr_relations
[:metrics, :assignees, { author: :status }]
[:metrics, { assignees: :status }, { author: :status }]
end
def merge_request_params
......
......@@ -38,7 +38,9 @@ module Autocomplete
end
end
items.uniq
items.uniq.tap do |unique_items|
preload_status(unique_items)
end
end
private
......@@ -91,6 +93,12 @@ module Autocomplete
User.none
end
end
# rubocop: disable CodeReuse/ActiveRecord
def preload_status(items)
ActiveRecord::Associations::Preloader.new.preload(items, :status)
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
......
......@@ -346,6 +346,7 @@ module IssuablesHelper
def assignee_sidebar_data(assignee, merge_request: nil)
{ avatar_url: assignee.avatar_url, name: assignee.name, username: assignee.username }.tap do |data|
data[:can_merge] = merge_request.can_be_merged_by?(assignee) if merge_request
data[:availability] = assignee.status.availability if assignee.association(:status).loaded? && assignee.status&.availability
end
end
......
......@@ -132,7 +132,7 @@ class Issue < ApplicationRecord
scope :counts_by_state, -> { reorder(nil).group(:state_id).count }
scope :service_desk, -> { where(author: ::User.support_bot) }
scope :inc_relations_for_view, -> { includes(author: :status) }
scope :inc_relations_for_view, -> { includes(author: :status, assignees: :status) }
# An issue can be uniquely identified by project_id and iid
# Takes one or more sets of composite IDs, expressed as hash-like records of
......
......@@ -16,6 +16,10 @@ module UserStatusTooltip
status_loaded? && show_status_emoji?(user.status)
end
expose :availability, if: -> (*) { status_loaded? } do |user|
user.status&.availability
end
private
def status_loaded?
......
# frozen_string_literal: true
class MergeRequestUserEntity < ::API::Entities::UserBasic
include UserStatusTooltip
expose :can_merge do |reviewer, options|
options[:merge_request]&.can_be_merged_by?(reviewer)
end
......
......@@ -107,5 +107,21 @@ RSpec.describe 'User views an open merge request' do
end
end
end
context 'when the assignee\'s availability set' do
before do
merge_request.author.create_status(availability: 'busy')
merge_request.assignees << merge_request.author
visit(merge_request_path(merge_request))
end
it 'exposes the availability in the data-availability attribute' do
assignees_data = find_all("input[name='merge_request[assignee_ids][]']", visible: false)
expect(assignees_data.size).to eq(1)
expect(assignees_data.first['data-availability']).to eq('busy')
end
end
end
end
......@@ -118,5 +118,10 @@ RSpec.describe Autocomplete::UsersFinder do
it { is_expected.to match_array([user1, external_user, omniauth_user, current_user]) }
end
it 'preloads the status association' do
associations = subject.map { |user| user.association(:status) }
expect(associations).to all(be_loaded)
end
end
end
......@@ -9,6 +9,7 @@
"web_url": { "type": "string" },
"blocked": { "type": "boolean" },
"two_factor_enabled": { "type": "boolean" },
"availability": { "type": ["string", "null"] },
"status": {
"type": "object",
"required": ["emoji"],
......
......@@ -17,5 +17,23 @@ RSpec.describe MergeRequestUserEntity do
it 'exposes needed attributes' do
expect(subject).to include(:id, :name, :username, :state, :avatar_url, :web_url, :can_merge)
end
context 'when `status` is not preloaded' do
it 'does not expose the availability attribute' do
expect(subject).not_to include(:availability)
end
end
context 'when `status` is preloaded' do
before do
user.create_status!(availability: :busy)
user.status # make sure `status` is loaded
end
it 'exposes the availibilty attribute' do
expect(subject[:availability]).to eq('busy')
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment