diff options
author | Winnie Hellmann <winnie@gitlab.com> | 2017-05-06 01:47:32 +0300 |
---|---|---|
committer | Jacob Schatz <jschatz@gitlab.com> | 2017-05-06 01:47:32 +0300 |
commit | b51f2a60800829ee7585f10451a41bc4db0359a9 (patch) | |
tree | 2ea7ea74e3fa867b2eadf5ffc8652022b25b2321 /app | |
parent | 9e041f2185ecb957e1f3d1205ea3bac54a5eb803 (diff) |
Colorize labels in issue search field
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js | 40 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/ajax_cache.js | 32 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/filters.scss | 14 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/variables.scss | 2 | ||||
-rw-r--r-- | app/controllers/dashboard/labels_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/groups/labels_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/labels_controller.rb | 2 | ||||
-rw-r--r-- | app/serializers/label_entity.rb | 1 | ||||
-rw-r--r-- | app/serializers/label_serializer.rb | 7 |
9 files changed, 95 insertions, 7 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 59ce0587e1e..f3003b86493 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js +++ b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js @@ -1,3 +1,5 @@ +import AjaxCache from '~/lib/utils/ajax_cache'; +import '~/flash'; /* global Flash */ import FilteredSearchContainer from './container'; class FilteredSearchVisualTokens { @@ -48,6 +50,40 @@ class FilteredSearchVisualTokens { `; } + static updateLabelTokenColor(tokenValueContainer, tokenValue) { + const filteredSearchInput = FilteredSearchContainer.container.querySelector('.filtered-search'); + const baseEndpoint = filteredSearchInput.dataset.baseEndpoint; + const labelsEndpoint = `${baseEndpoint}/labels.json`; + + return AjaxCache.retrieve(labelsEndpoint) + .then((labels) => { + const matchingLabel = (labels || []).find(label => `~${gl.DropdownUtils.getEscapedText(label.title)}` === tokenValue); + + if (!matchingLabel) { + return; + } + + const tokenValueStyle = tokenValueContainer.style; + tokenValueStyle.backgroundColor = matchingLabel.color; + tokenValueStyle.color = matchingLabel.text_color; + + if (matchingLabel.text_color === '#FFFFFF') { + const removeToken = tokenValueContainer.querySelector('.remove-token'); + removeToken.classList.add('inverted'); + } + }) + .catch(() => new Flash('An error occurred while fetching label colors.')); + } + + static renderVisualTokenValue(parentElement, tokenName, tokenValue) { + const tokenValueContainer = parentElement.querySelector('.value-container'); + tokenValueContainer.querySelector('.value').innerText = tokenValue; + + if (tokenName.toLowerCase() === 'label') { + FilteredSearchVisualTokens.updateLabelTokenColor(tokenValueContainer, tokenValue); + } + } + static addVisualTokenElement(name, value, isSearchTerm) { const li = document.createElement('li'); li.classList.add('js-visual-token'); @@ -55,7 +91,7 @@ class FilteredSearchVisualTokens { if (value) { li.innerHTML = FilteredSearchVisualTokens.createVisualTokenElementHTML(); - li.querySelector('.value').innerText = value; + FilteredSearchVisualTokens.renderVisualTokenValue(li, name, value); } else { li.innerHTML = '<div class="name"></div>'; } @@ -74,7 +110,7 @@ class FilteredSearchVisualTokens { const name = FilteredSearchVisualTokens.getLastTokenPartial(); lastVisualToken.innerHTML = FilteredSearchVisualTokens.createVisualTokenElementHTML(); lastVisualToken.querySelector('.name').innerText = name; - lastVisualToken.querySelector('.value').innerText = value; + FilteredSearchVisualTokens.renderVisualTokenValue(lastVisualToken, name, value); } } diff --git a/app/assets/javascripts/lib/utils/ajax_cache.js b/app/assets/javascripts/lib/utils/ajax_cache.js new file mode 100644 index 00000000000..d99eefb5089 --- /dev/null +++ b/app/assets/javascripts/lib/utils/ajax_cache.js @@ -0,0 +1,32 @@ +const AjaxCache = { + internalStorage: { }, + get(endpoint) { + return this.internalStorage[endpoint]; + }, + hasData(endpoint) { + return Object.prototype.hasOwnProperty.call(this.internalStorage, endpoint); + }, + purge(endpoint) { + delete this.internalStorage[endpoint]; + }, + retrieve(endpoint) { + if (AjaxCache.hasData(endpoint)) { + return Promise.resolve(AjaxCache.get(endpoint)); + } + + return new Promise((resolve, reject) => { + $.ajax(endpoint) // eslint-disable-line promise/catch-or-return + .then(data => resolve(data), + (jqXHR, textStatus, errorThrown) => { + const error = new Error(`${endpoint}: ${errorThrown}`); + error.textStatus = textStatus; + reject(error); + }, + ); + }) + .then((data) => { this.internalStorage[endpoint] = data; }) + .then(() => AjaxCache.get(endpoint)); + }, +}; + +export default AjaxCache; diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index 0692f65043b..e624d0d951e 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -114,11 +114,21 @@ padding-right: 8px; .fa-close { - color: $gl-text-color-disabled; + color: $gl-text-color-secondary; } &:hover .fa-close { - color: $gl-text-color-secondary; + color: $gl-text-color; + } + + &.inverted { + .fa-close { + color: $gl-text-color-secondary-inverted; + } + + &:hover .fa-close { + color: $gl-text-color-inverted; + } } } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 49741c963df..08bcb582613 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -101,6 +101,8 @@ $gl-font-size: 14px; $gl-text-color: rgba(0, 0, 0, .85); $gl-text-color-secondary: rgba(0, 0, 0, .55); $gl-text-color-disabled: rgba(0, 0, 0, .35); +$gl-text-color-inverted: rgba(255, 255, 255, 1.0); +$gl-text-color-secondary-inverted: rgba(255, 255, 255, .85); $gl-text-green: $green-600; $gl-text-red: $red-500; $gl-text-orange: $orange-600; diff --git a/app/controllers/dashboard/labels_controller.rb b/app/controllers/dashboard/labels_controller.rb index d5031da867a..dd1d46a68c7 100644 --- a/app/controllers/dashboard/labels_controller.rb +++ b/app/controllers/dashboard/labels_controller.rb @@ -3,7 +3,7 @@ class Dashboard::LabelsController < Dashboard::ApplicationController labels = LabelsFinder.new(current_user).execute respond_to do |format| - format.json { render json: labels.as_json(only: [:id, :title, :color]) } + format.json { render json: LabelSerializer.new.represent_appearance(labels) } end end end diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb index facb25525b5..3fa0516fb0c 100644 --- a/app/controllers/groups/labels_controller.rb +++ b/app/controllers/groups/labels_controller.rb @@ -15,7 +15,7 @@ class Groups::LabelsController < Groups::ApplicationController format.json do available_labels = LabelsFinder.new(current_user, group_id: @group.id).execute - render json: available_labels.as_json(only: [:id, :title, :color]) + render json: LabelSerializer.new.represent_appearance(available_labels) end end end diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index 2f55ba4e700..71bfb7163da 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -19,7 +19,7 @@ class Projects::LabelsController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: @available_labels.as_json(only: [:id, :title, :color]) + render json: LabelSerializer.new.represent_appearance(@available_labels) end end end diff --git a/app/serializers/label_entity.rb b/app/serializers/label_entity.rb index 304fd9de08f..ad565654342 100644 --- a/app/serializers/label_entity.rb +++ b/app/serializers/label_entity.rb @@ -6,6 +6,7 @@ class LabelEntity < Grape::Entity expose :group_id expose :project_id expose :template + expose :text_color expose :created_at expose :updated_at end diff --git a/app/serializers/label_serializer.rb b/app/serializers/label_serializer.rb new file mode 100644 index 00000000000..ad6ba8c46c9 --- /dev/null +++ b/app/serializers/label_serializer.rb @@ -0,0 +1,7 @@ +class LabelSerializer < BaseSerializer + entity LabelEntity + + def represent_appearance(resource) + represent(resource, { only: [:id, :title, :color, :text_color] }) + end +end |