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:
Diffstat (limited to 'app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js')
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js151
1 files changed, 132 insertions, 19 deletions
diff --git a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
index 7746908714e..addf1ad94df 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
@@ -1,6 +1,10 @@
-import VisualTokenValue from 'ee_else_ce/filtered_search/visual_token_value';
+import _ from 'underscore';
+import AjaxCache from '~/lib/utils/ajax_cache';
import { objectToQueryString } from '~/lib/utils/common_utils';
+import Flash from '../flash';
import FilteredSearchContainer from './container';
+import UsersCache from '../lib/utils/users_cache';
+import DropdownUtils from './dropdown_utils';
export default class FilteredSearchVisualTokens {
static getLastVisualTokenBeforeInput() {
@@ -16,6 +20,21 @@ export default class FilteredSearchVisualTokens {
};
}
+ /**
+ * Returns a computed API endpoint
+ * and query string composed of values from endpointQueryParams
+ * @param {String} endpoint
+ * @param {String} endpointQueryParams
+ */
+ static getEndpointWithQueryParams(endpoint, endpointQueryParams) {
+ if (!endpointQueryParams) {
+ return endpoint;
+ }
+
+ const queryString = objectToQueryString(JSON.parse(endpointQueryParams));
+ return `${endpoint}?${queryString}`;
+ }
+
static unselectTokens() {
const otherTokens = FilteredSearchContainer.container.querySelectorAll(
'.js-visual-token .selectable.selected',
@@ -57,15 +76,124 @@ export default class FilteredSearchVisualTokens {
`;
}
+ static setTokenStyle(tokenContainer, backgroundColor, textColor) {
+ const token = tokenContainer;
+
+ token.style.backgroundColor = backgroundColor;
+ token.style.color = textColor;
+
+ if (textColor === '#FFFFFF') {
+ const removeToken = token.querySelector('.remove-token');
+ removeToken.classList.add('inverted');
+ }
+
+ return token;
+ }
+
+ static updateLabelTokenColor(tokenValueContainer, tokenValue) {
+ const filteredSearchInput = FilteredSearchContainer.container.querySelector('.filtered-search');
+ const { baseEndpoint } = filteredSearchInput.dataset;
+ const labelsEndpoint = FilteredSearchVisualTokens.getEndpointWithQueryParams(
+ `${baseEndpoint}/labels.json`,
+ filteredSearchInput.dataset.endpointQueryParams,
+ );
+
+ return AjaxCache.retrieve(labelsEndpoint)
+ .then(labels => {
+ const matchingLabel = (labels || []).find(
+ label => `~${DropdownUtils.getEscapedText(label.title)}` === tokenValue,
+ );
+
+ if (!matchingLabel) {
+ return;
+ }
+
+ FilteredSearchVisualTokens.setTokenStyle(
+ tokenValueContainer,
+ matchingLabel.color,
+ matchingLabel.text_color,
+ );
+ })
+ .catch(() => new Flash('An error occurred while fetching label colors.'));
+ }
+
+ static updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) {
+ const username = tokenValue.replace(/^@/, '');
+ return (
+ UsersCache.retrieve(username)
+ .then(user => {
+ if (!user) {
+ return;
+ }
+
+ /* eslint-disable no-param-reassign */
+ tokenValueContainer.dataset.originalValue = tokenValue;
+ tokenValueElement.innerHTML = `
+ <img class="avatar s20" src="${user.avatar_url}" alt="">
+ ${_.escape(user.name)}
+ `;
+ /* eslint-enable no-param-reassign */
+ })
+ // ignore error and leave username in the search bar
+ .catch(() => {})
+ );
+ }
+
+ static updateEmojiTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) {
+ const container = tokenValueContainer;
+ const element = tokenValueElement;
+ const value = tokenValue;
+
+ return (
+ import(/* webpackChunkName: 'emoji' */ '../emoji')
+ .then(Emoji => {
+ Emoji.initEmojiMap()
+ .then(() => {
+ if (!Emoji.isEmojiNameValid(value)) {
+ return;
+ }
+
+ container.dataset.originalValue = value;
+ element.innerHTML = Emoji.glEmojiTag(value);
+ })
+ // ignore error and leave emoji name in the search bar
+ .catch(err => {
+ throw err;
+ });
+ })
+ // ignore error and leave emoji name in the search bar
+ .catch(importError => {
+ throw importError;
+ })
+ );
+ }
+
static renderVisualTokenValue(parentElement, tokenName, tokenValue) {
- const tokenType = tokenName.toLowerCase();
const tokenValueContainer = parentElement.querySelector('.value-container');
const tokenValueElement = tokenValueContainer.querySelector('.value');
tokenValueElement.innerText = tokenValue;
- const visualTokenValue = new VisualTokenValue(tokenValue, tokenType);
+ if (['none', 'any'].includes(tokenValue.toLowerCase())) {
+ return;
+ }
- visualTokenValue.render(tokenValueContainer, tokenValueElement);
+ const tokenType = tokenName.toLowerCase();
+
+ if (tokenType === 'label') {
+ FilteredSearchVisualTokens.updateLabelTokenColor(tokenValueContainer, tokenValue);
+ } else if (tokenType === 'author' || tokenType === 'assignee') {
+ FilteredSearchVisualTokens.updateUserTokenAppearance(
+ tokenValueContainer,
+ tokenValueElement,
+ tokenValue,
+ );
+ } else if (tokenType === 'my-reaction') {
+ FilteredSearchVisualTokens.updateEmojiTokenAppearance(
+ tokenValueContainer,
+ tokenValueElement,
+ tokenValue,
+ );
+ }
}
static addVisualTokenElement(name, value, options = {}) {
@@ -200,21 +328,6 @@ export default class FilteredSearchVisualTokens {
}
}
- /**
- * Returns a computed API endpoint
- * and query string composed of values from endpointQueryParams
- * @param {String} endpoint
- * @param {String} endpointQueryParams
- */
- static getEndpointWithQueryParams(endpoint, endpointQueryParams) {
- if (!endpointQueryParams) {
- return endpoint;
- }
-
- const queryString = objectToQueryString(JSON.parse(endpointQueryParams));
- return `${endpoint}?${queryString}`;
- }
-
static editToken(token) {
const input = FilteredSearchContainer.container.querySelector('.filtered-search');