summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/users_select/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/users_select/index.js')
-rw-r--r--app/assets/javascripts/users_select/index.js214
1 files changed, 43 insertions, 171 deletions
diff --git a/app/assets/javascripts/users_select/index.js b/app/assets/javascripts/users_select/index.js
index bd425bdc2a8..7c1204c511c 100644
--- a/app/assets/javascripts/users_select/index.js
+++ b/app/assets/javascripts/users_select/index.js
@@ -1,21 +1,17 @@
-/* eslint-disable func-names, prefer-rest-params, consistent-return, no-shadow, no-self-compare, no-unused-expressions, yoda, prefer-spread, camelcase, no-param-reassign */
+/* eslint-disable func-names, consistent-return, no-shadow, no-self-compare, no-unused-expressions, camelcase, no-param-reassign */
/* global Issuable */
/* global emitSidebarEvent */
import $ from 'jquery';
import { escape, template, uniqBy } from 'lodash';
-import {
- AJAX_USERS_SELECT_OPTIONS_MAP,
- AJAX_USERS_SELECT_PARAMS_MAP,
-} from 'ee_else_ce/users_select/constants';
+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 axios from '~/lib/utils/axios_utils';
import { parseBoolean, spriteIcon } from '~/lib/utils/common_utils';
-import { loadCSSFile } from '~/lib/utils/css_utils';
import { s__, __, sprintf } from '~/locale';
-import { getAjaxUsersSelectOptions, getAjaxUsersSelectParams } from './utils';
+import { getAjaxUsersSelectParams } from './utils';
// TODO: remove eventHub hack after code splitting refactor
window.emitSidebarEvent = window.emitSidebarEvent || $.noop;
@@ -24,9 +20,7 @@ function UsersSelect(currentUser, els, options = {}) {
const elsClassName = els?.toString().match('.(.+$)')[1];
const $els = $(els || '.js-user-search');
this.users = this.users.bind(this);
- this.user = this.user.bind(this);
this.usersPath = '/-/autocomplete/users.json';
- this.userPath = '/-/autocomplete/users/:id.json';
if (currentUser != null) {
if (typeof currentUser === 'object') {
this.currentUser = currentUser;
@@ -35,28 +29,29 @@ function UsersSelect(currentUser, els, options = {}) {
}
}
- const { handleClick } = options;
- const userSelect = this;
+ const { handleClick, states } = options;
$els.each((i, dropdown) => {
const userSelect = this;
- const options = {};
const $dropdown = $(dropdown);
- options.projectId = $dropdown.data('projectId');
- options.groupId = $dropdown.data('groupId');
- options.showCurrentUser = $dropdown.data('currentUser');
- options.todoFilter = $dropdown.data('todoFilter');
- options.todoStateFilter = $dropdown.data('todoStateFilter');
- options.iid = $dropdown.data('iid');
- options.issuableType = $dropdown.data('issuableType');
- options.targetBranch = $dropdown.data('targetBranch');
- options.showSuggested = $dropdown.data('showSuggested');
+ const options = {
+ states,
+ projectId: $dropdown.data('projectId'),
+ groupId: $dropdown.data('groupId'),
+ showCurrentUser: $dropdown.data('currentUser'),
+ todoFilter: $dropdown.data('todoFilter'),
+ todoStateFilter: $dropdown.data('todoStateFilter'),
+ iid: $dropdown.data('iid'),
+ issuableType: $dropdown.data('issuableType'),
+ targetBranch: $dropdown.data('targetBranch'),
+ authorId: $dropdown.data('authorId'),
+ showSuggested: $dropdown.data('showSuggested'),
+ };
const showNullUser = $dropdown.data('nullUser');
const defaultNullUser = $dropdown.data('nullUserDefault');
const showMenuAbove = $dropdown.data('showMenuAbove');
const showAnyUser = $dropdown.data('anyUser');
const firstUser = $dropdown.data('firstUser');
- options.authorId = $dropdown.data('authorId');
const defaultLabel = $dropdown.data('defaultLabel');
const issueURL = $dropdown.data('issueUpdate');
const $selectbox = $dropdown.closest('.selectbox');
@@ -72,6 +67,22 @@ function UsersSelect(currentUser, els, options = {}) {
let assigneeTemplate;
let collapsedAssigneeTemplate;
+ const suggestedReviewersHelpPath = $dropdown.data('suggestedReviewersHelpPath');
+ const suggestedReviewersHeaderTemplate = template(
+ `<div class="gl-display-flex gl-align-items-center">
+ <%- header %>
+ <a
+ title="${s__('SuggestedReviewers|Learn about suggested reviewers')}"
+ href="${suggestedReviewersHelpPath}"
+ rel="noopener"
+ target="_blank"
+ aria-label="${s__('SuggestedReviewers|Suggested reviewers help link')}"
+ class="gl-hover-bg-transparent! gl-p-0! has-tooltip">
+ ${spriteIcon('question-o', 'gl-ml-3 gl-icon s16')}
+ </a>
+ </div>`,
+ );
+
if (selectedId === undefined) {
selectedId = selectedIdDefault;
}
@@ -388,7 +399,12 @@ function UsersSelect(currentUser, els, options = {}) {
if (!suggestedUsers.length) return [];
const items = [
- { type: 'header', content: $dropdown.data('suggestedReviewersHeader') },
+ {
+ type: 'header',
+ content: suggestedReviewersHeaderTemplate({
+ header: $dropdown.data('suggestedReviewersHeader'),
+ }),
+ },
...suggestedUsers,
{ type: 'header', content: $dropdown.data('allMembersHeader') },
];
@@ -431,6 +447,10 @@ function UsersSelect(currentUser, els, options = {}) {
hidden() {
if ($dropdown.hasClass('js-multiselect')) {
if ($dropdown.hasClass(elsClassName)) {
+ if (window.gon?.features?.realtimeReviewers) {
+ $dropdown.data('deprecatedJQueryDropdown').clearMenu();
+ $dropdown.closest('.selectbox').children('input[type="hidden"]').remove();
+ }
emitSidebarEvent('sidebar.saveReviewers');
} else {
emitSidebarEvent('sidebar.saveAssignees');
@@ -615,156 +635,8 @@ function UsersSelect(currentUser, els, options = {}) {
},
});
});
-
- if ($('.ajax-users-select').length) {
- import(/* webpackChunkName: 'select2' */ 'select2/select2')
- .then(() => {
- // eslint-disable-next-line promise/no-nesting
- loadCSSFile(gon.select2_css_path)
- .then(() => {
- $('.ajax-users-select').each((i, select) => {
- const options = getAjaxUsersSelectOptions($(select), AJAX_USERS_SELECT_OPTIONS_MAP);
- options.skipLdap = $(select).hasClass('skip_ldap');
- const showNullUser = $(select).data('nullUser');
- const showAnyUser = $(select).data('anyUser');
- const showEmailUser = $(select).data('emailUser');
- const firstUser = $(select).data('firstUser');
- return $(select).select2({
- placeholder: __('Search for a user'),
- multiple: $(select).hasClass('multiselect'),
- minimumInputLength: 0,
- query(query) {
- return userSelect.users(query.term, options, (users) => {
- let name;
- const data = {
- results: users,
- };
- if (query.term.length === 0) {
- if (firstUser) {
- // Move current user to the front of the list
- const ref = data.results;
-
- for (let index = 0, len = ref.length; index < len; index += 1) {
- const obj = ref[index];
- if (obj.username === firstUser) {
- data.results.splice(index, 1);
- data.results.unshift(obj);
- break;
- }
- }
- }
- if (showNullUser) {
- const nullUser = {
- name: s__('UsersSelect|Unassigned'),
- id: 0,
- };
- data.results.unshift(nullUser);
- }
- if (showAnyUser) {
- name = showAnyUser;
- if (name === true) {
- name = s__('UsersSelect|Any User');
- }
- const anyUser = {
- name,
- id: null,
- };
- data.results.unshift(anyUser);
- }
- }
- if (
- showEmailUser &&
- data.results.length === 0 &&
- query.term.match(/^[^@]+@[^@]+$/)
- ) {
- const trimmed = query.term.trim();
- const emailUser = {
- name: sprintf(__('Invite "%{trimmed}" by email'), { trimmed }),
- username: trimmed,
- id: trimmed,
- invite: true,
- };
- data.results.unshift(emailUser);
- }
- return query.callback(data);
- });
- },
- initSelection() {
- const args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
- return userSelect.initSelection.apply(userSelect, args);
- },
- formatResult() {
- const args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
- return userSelect.formatResult.apply(userSelect, args);
- },
- formatSelection() {
- const args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
- return userSelect.formatSelection.apply(userSelect, args);
- },
- dropdownCssClass: 'ajax-users-dropdown',
- // we do not want to escape markup since we are displaying html in results
- escapeMarkup(m) {
- return m;
- },
- });
- });
- })
- .catch(() => {});
- })
- .catch(() => {});
- }
}
-UsersSelect.prototype.initSelection = function (element, callback) {
- const id = $(element).val();
- if (id === '0') {
- const nullUser = {
- name: s__('UsersSelect|Unassigned'),
- };
- return callback(nullUser);
- } else if (id !== '') {
- return this.user(id, callback);
- }
-};
-
-UsersSelect.prototype.formatResult = function (user) {
- let avatar = gon.default_avatar_url;
- if (user.avatar_url) {
- avatar = user.avatar_url;
- }
- return `
- <div class='user-result'>
- <div class='user-image'>
- <img class='avatar avatar-inline s32' src='${avatar}'>
- </div>
- <div class='user-info'>
- <div class='user-name dropdown-menu-user-full-name'>
- ${escape(user.name)}
- </div>
- <div class='user-username dropdown-menu-user-username text-secondary'>
- ${!user.invite ? `@${escape(user.username)}` : ''}
- </div>
- </div>
- </div>
- `;
-};
-
-UsersSelect.prototype.formatSelection = function (user) {
- return escape(user.name);
-};
-
-UsersSelect.prototype.user = function (user_id, callback) {
- if (!/^\d+$/.test(user_id)) {
- return false;
- }
-
- let url = this.buildUrl(this.userPath);
- url = url.replace(':id', user_id);
- return axios.get(url).then(({ data }) => {
- callback(data);
- });
-};
-
// Return users list. Filtered by query
// Only active users retrieved
UsersSelect.prototype.users = function (query, options, callback) {