Commit 2e48bf11 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch '43643-fix-mr-label-filtering' into 'master'

Enable filtering MR list based on clicked label in MR sidebar

Closes #43643

See merge request gitlab-org/gitlab-ce!17390
parents 65348cf0 90baab96
...@@ -21,7 +21,7 @@ export default class LabelsSelect { ...@@ -21,7 +21,7 @@ export default class LabelsSelect {
} }
$els.each(function(i, dropdown) { $els.each(function(i, dropdown) {
var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer; var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer;
$dropdown = $(dropdown); $dropdown = $(dropdown);
$dropdownContainer = $dropdown.closest('.labels-filter'); $dropdownContainer = $dropdown.closest('.labels-filter');
$toggleText = $dropdown.find('.dropdown-toggle-text'); $toggleText = $dropdown.find('.dropdown-toggle-text');
...@@ -53,13 +53,6 @@ export default class LabelsSelect { ...@@ -53,13 +53,6 @@ export default class LabelsSelect {
.map(function () { .map(function () {
return this.value; return this.value;
}).get(); }).get();
if (issueUpdateURL != null) {
issueURLSplit = issueUpdateURL.split('/');
}
if (issueUpdateURL) {
labelHTMLTemplate = _.template('<% _.each(labels, function(label){ %> <a href="<%- ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name[]=<%- encodeURIComponent(label.title) %>"> <span class="label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;"> <%- label.title %> </span> </a> <% }); %>');
labelNoneHTMLTemplate = '<span class="no-value">None</span>';
}
const handleClick = options.handleClick; const handleClick = options.handleClick;
$sidebarLabelTooltip.tooltip(); $sidebarLabelTooltip.tooltip();
...@@ -91,14 +84,17 @@ export default class LabelsSelect { ...@@ -91,14 +84,17 @@ export default class LabelsSelect {
$loading.fadeOut(); $loading.fadeOut();
$dropdown.trigger('loaded.gl.dropdown'); $dropdown.trigger('loaded.gl.dropdown');
$selectbox.hide(); $selectbox.hide();
data.issueURLSplit = issueURLSplit; data.issueUpdateURL = issueUpdateURL;
labelCount = 0; labelCount = 0;
if (data.labels.length) { if (data.labels.length && issueUpdateURL) {
template = labelHTMLTemplate(data); template = LabelsSelect.getLabelTemplate({
labels: data.labels,
issueUpdateURL,
});
labelCount = data.labels.length; labelCount = data.labels.length;
} }
else { else {
template = labelNoneHTMLTemplate; template = '<span class="no-value">None</span>';
} }
$value.removeAttr('style').html(template); $value.removeAttr('style').html(template);
$sidebarCollapsedValue.text(labelCount); $sidebarCollapsedValue.text(labelCount);
...@@ -418,6 +414,26 @@ export default class LabelsSelect { ...@@ -418,6 +414,26 @@ export default class LabelsSelect {
this.bindEvents(); this.bindEvents();
} }
static getLabelTemplate(tplData) {
// We could use ES6 template string here
// and properly indent markup for readability
// but that also introduces unintended white-space
// so best approach is to use traditional way of
// concatenation
// see: http://2ality.com/2016/05/template-literal-whitespace.html#joining-arrays
const tpl = _.template([
'<% _.each(labels, function(label){ %>',
'<a href="<%- issueUpdateURL.slice(0, issueUpdateURL.lastIndexOf("/")) %>?label_name[]=<%- encodeURIComponent(label.title) %>">',
'<span class="label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;">',
'<%- label.title %>',
'</span>',
'</a>',
'<% }); %>',
].join(''));
return tpl(tplData);
}
bindEvents() { bindEvents() {
return $('body').on('change', '.selected_issue', this.onSelectCheckboxIssue); return $('body').on('change', '.selected_issue', this.onSelectCheckboxIssue);
} }
......
...@@ -103,6 +103,7 @@ ...@@ -103,6 +103,7 @@
.issuable-show-labels { .issuable-show-labels {
a { a {
margin-bottom: 5px; margin-bottom: 5px;
margin-right: 5px;
display: inline-block; display: inline-block;
.color-label { .color-label {
...@@ -116,6 +117,12 @@ ...@@ -116,6 +117,12 @@
} }
&.has-labels { &.has-labels {
// this font size is a fix to
// prevent unintended spacing between labels
// which shows up when rendering markup has white-space
// characters present.
// see: https://css-tricks.com/fighting-the-space-between-inline-block-elements/#article-header-id-3
font-size: 0;
margin-bottom: -5px; margin-bottom: -5px;
} }
} }
......
---
title: Enable filtering MR list based on clicked label in MR sidebar
merge_request: 17390
author:
type: fixed
import LabelsSelect from '~/labels_select';
const mockUrl = '/foo/bar/url';
const mockLabels = [
{
id: 26,
title: 'Foo Label',
description: 'Foobar',
color: '#BADA55',
text_color: '#FFFFFF',
},
];
describe('LabelsSelect', () => {
describe('getLabelTemplate', () => {
const label = mockLabels[0];
let $labelEl;
beforeEach(() => {
$labelEl = $(LabelsSelect.getLabelTemplate({
labels: mockLabels,
issueUpdateURL: mockUrl,
}));
});
it('generated label item template has correct label URL', () => {
expect($labelEl.attr('href')).toBe('/foo/bar?label_name[]=Foo%20Label');
});
it('generated label item template has correct label title', () => {
expect($labelEl.find('span.label').text()).toBe(label.title);
});
it('generated label item template has label description as title attribute', () => {
expect($labelEl.find('span.label').attr('title')).toBe(label.description);
});
it('generated label item template has correct label styles', () => {
expect($labelEl.find('span.label').attr('style')).toBe(`background-color: ${label.color}; color: ${label.text_color};`);
});
});
});
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