Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-06 00:09:02 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-06 00:09:02 +0300
commit76623c12c136f43f24c3966ed4b469e2c0b434b7 (patch)
tree7c5ec884c25e03e4fea131a4d112a9d0ccfd59b8 /app/assets/javascripts/gfm_auto_complete.js
parentb042382bbf5a4977c5b5c6b0a9a33f4e8ca8d16d (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/gfm_auto_complete.js')
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js57
1 files changed, 55 insertions, 2 deletions
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index de69daf5c22..c762e298eb8 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -1,6 +1,7 @@
import $ from 'jquery';
import 'at.js';
import _ from 'underscore';
+import SidebarMediator from '~/sidebar/sidebar_mediator';
import glRegexp from './lib/utils/regexp';
import AjaxCache from './lib/utils/ajax_cache';
import { spriteIcon } from './lib/utils/common_utils';
@@ -53,8 +54,8 @@ export const defaultAutocompleteConfig = {
};
class GfmAutoComplete {
- constructor(dataSources) {
- this.dataSources = dataSources || {};
+ constructor(dataSources = {}) {
+ this.dataSources = dataSources;
this.cachedData = {};
this.isLoadingData = {};
}
@@ -199,6 +200,16 @@ class GfmAutoComplete {
}
setupMembers($input) {
+ const fetchData = this.fetchData.bind(this);
+ const MEMBER_COMMAND = {
+ ASSIGN: '/assign',
+ UNASSIGN: '/unassign',
+ REASSIGN: '/reassign',
+ CC: '/cc',
+ };
+ let assignees = [];
+ let command = '';
+
// Team Members
$input.atwho({
at: '@',
@@ -225,6 +236,48 @@ class GfmAutoComplete {
callbacks: {
...this.getDefaultCallbacks(),
beforeSave: membersBeforeSave,
+ matcher(flag, subtext) {
+ const subtextNodes = subtext
+ .split(/\n+/g)
+ .pop()
+ .split(GfmAutoComplete.regexSubtext);
+
+ // Check if @ is followed by '/assign', '/reassign', '/unassign' or '/cc' commands.
+ command = subtextNodes.find(node => {
+ if (Object.values(MEMBER_COMMAND).includes(node)) {
+ return node;
+ }
+ return null;
+ });
+
+ // Cache assignees list for easier filtering later
+ assignees = SidebarMediator.singleton?.store?.assignees?.map(
+ assignee => `${assignee.username} ${assignee.name}`,
+ );
+
+ const match = GfmAutoComplete.defaultMatcher(flag, subtext, this.app.controllers);
+ return match && match.length ? match[1] : null;
+ },
+ filter(query, data, searchKey) {
+ if (GfmAutoComplete.isLoading(data)) {
+ fetchData(this.$inputor, this.at);
+ return data;
+ }
+
+ if (data === GfmAutoComplete.defaultLoadingData) {
+ return $.fn.atwho.default.callbacks.filter(query, data, searchKey);
+ }
+
+ if (command === MEMBER_COMMAND.ASSIGN) {
+ // Only include members which are not assigned to Issuable currently
+ return data.filter(member => !assignees.includes(member.search));
+ } else if (command === MEMBER_COMMAND.UNASSIGN) {
+ // Only include members which are assigned to Issuable currently
+ return data.filter(member => assignees.includes(member.search));
+ }
+
+ return data;
+ },
},
});
}