Commit e7c254d0 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo Committed by Kushal Pandya

Expose availability in issue sidebar assignees

Extract user status from hidden data

Extracts the user availability status for assignees
from the hidden input field
parent 931ad1c6
......@@ -51,7 +51,7 @@ export default {
<div>
<collapsed-assignee-list :users="sortedAssigness" :issuable-type="issuableType" />
<div class="value hide-collapsed">
<div data-testid="expanded-assignee" class="value hide-collapsed">
<template v-if="hasNoUsers">
<span class="assign-yourself no-value qa-assign-yourself">
{{ __('None') }}
......
......@@ -44,6 +44,11 @@ export default {
type: String,
required: true,
},
assigneeAvailabilityStatus: {
type: Object,
required: false,
default: () => ({}),
},
},
data() {
return {
......@@ -101,6 +106,13 @@ export default {
return new Flash(__('Error occurred when saving assignees'));
});
},
exposeAvailabilityStatus(users) {
return users.map(({ username, ...rest }) => ({
...rest,
username,
availability: this.assigneeAvailabilityStatus[username] || '',
}));
},
},
};
</script>
......@@ -123,7 +135,7 @@ export default {
<assignees
v-if="!store.isFetching.assignees"
:root-path="relativeUrlRoot"
:users="store.assignees"
:users="exposeAvailabilityStatus(store.assignees)"
:editable="store.editable"
:issuable-type="issuableType"
class="value"
......
......@@ -30,6 +30,28 @@ function getSidebarOptions(sidebarOptEl = document.querySelector('.js-sidebar-op
return JSON.parse(sidebarOptEl.innerHTML);
}
/**
* Extracts the list of assignees with availability information from a hidden input
* field and converts to a key:value pair for use in the sidebar assignees component.
* The assignee username is used as the key and their busy status is the value
*
* e.g { root: 'busy', admin: '' }
*
* @returns {Object}
*/
function getSidebarAssigneeAvailabilityData() {
const sidebarAssigneeEl = document.querySelectorAll('.js-sidebar-assignee-data input');
return Array.from(sidebarAssigneeEl)
.map((el) => el.dataset)
.reduce(
(acc, { username, availability = '' }) => ({
...acc,
[username]: availability,
}),
{},
);
}
function mountAssigneesComponent(mediator) {
const el = document.getElementById('js-vue-sidebar-assignees');
const apolloProvider = new VueApollo({
......@@ -39,6 +61,7 @@ function mountAssigneesComponent(mediator) {
if (!el) return;
const { iid, fullPath } = getSidebarOptions();
const assigneeAvailabilityStatus = getSidebarAssigneeAvailabilityData();
// eslint-disable-next-line no-new
new Vue({
el,
......@@ -56,6 +79,7 @@ function mountAssigneesComponent(mediator) {
signedIn: el.hasAttribute('data-signed-in'),
issuableType:
isInIssuePage() || isInIncidentPage() || isInDesignPage() ? 'issue' : 'merge_request',
assigneeAvailabilityStatus,
},
}),
});
......
......@@ -9,6 +9,7 @@ import {
AJAX_USERS_SELECT_PARAMS_MAP,
} from 'ee_else_ce/users_select/constants';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import { isUserBusy } from '~/set_status_modal/utils';
import { fixTitle, dispose } from '~/tooltips';
import ModalStore from '../boards/stores/modal_store';
import axios from '../lib/utils/axios_utils';
......@@ -795,13 +796,17 @@ UsersSelect.prototype.renderRow = function (
? `data-container="body" data-placement="left" data-title="${tooltip}"`
: '';
const name =
user?.availability && isUserBusy(user.availability)
? sprintf(__('%{name} (Busy)'), { name: user.name })
: user.name;
return `
<li data-user-id=${user.id}>
<a href="#" class="dropdown-menu-user-link d-flex align-items-center ${linkClasses}" ${tooltipAttributes}>
${this.renderRowAvatar(issuableType, user, img)}
<span class="d-flex flex-column overflow-hidden">
<strong class="dropdown-menu-user-full-name gl-font-weight-bold">
${escape(user.name)}
${escape(name)}
</strong>
${
username
......
......@@ -5,7 +5,7 @@
= _('Assignee')
= loading_icon(css_class: 'gl-vertical-align-text-bottom')
.selectbox.hide-collapsed
.js-sidebar-assignee-data.selectbox.hide-collapsed
- if assignees.none?
= hidden_field_tag "#{issuable_type}[assignee_ids][]", 0, id: nil
- else
......
---
title: Display user busy status in issue sidebar
merge_request: 54165
author:
type: added
......@@ -199,6 +199,38 @@ RSpec.describe 'User edit profile' do
expect(busy_status.checked?).to eq(true)
end
context 'with user status set to busy' do
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project, author: user) }
before do
toggle_busy_status
submit_settings
project.add_developer(user)
visit project_issue_path(project, issue)
end
it 'shows author as busy in the assignee dropdown' do
find('.block.assignee .edit-link').click
wait_for_requests
page.within '.dropdown-menu-user' do
expect(page).to have_content("#{user.name} (Busy)")
end
end
it 'displays the assignee busy status' do
click_button 'assign yourself'
wait_for_requests
visit project_issue_path(project, issue)
wait_for_requests
expect(page.find('[data-testid="expanded-assignee"]')).to have_text("#{user.name} (Busy)")
end
end
context 'with set_user_availability_status feature flag disabled' do
before do
stub_feature_flags(set_user_availability_status: false)
......
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