diff options
author | Robert Speicher <robert@gitlab.com> | 2016-08-19 16:00:47 +0000 |
---|---|---|
committer | Robert Speicher <robert@gitlab.com> | 2016-08-19 16:00:47 +0000 |
commit | 4ecfd74fff060a3a6aaa16ace3b3360c74ed893a (patch) | |
tree | cf00c098be86aececef51761473f627109d35018 | |
parent | 55cd2e791bfeb90548e1cd4c142213470f1f2aac (diff) | |
parent | d1b987fd05ef650cfb227da5828a1cd4fc811436 (diff) | |
download | gitlab-ce-4ecfd74fff060a3a6aaa16ace3b3360c74ed893a.tar.gz |
Merge branch 'label-tooltip-sidebar-collapsed' into 'master'
Added tooltip to label value in collapsed sidebar
## What does this MR do?
Adds a list of the issuables labels to a tooltip in the collapsed
sidebar. Limited to 5 otherwise the list could get crazy long.
Closes #19398
See merge request !5232
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/assets/javascripts/labels_select.js | 32 | ||||
-rw-r--r-- | app/helpers/issuables_helper.rb | 9 | ||||
-rw-r--r-- | app/views/shared/issuable/_sidebar.html.haml | 2 | ||||
-rw-r--r-- | spec/helpers/issuables_helper_spec.rb | 16 | ||||
-rw-r--r-- | spec/javascripts/fixtures/issue_sidebar_label.html.haml | 16 | ||||
-rw-r--r-- | spec/javascripts/labels_issue_sidebar_spec.js.es6 | 89 |
7 files changed, 161 insertions, 4 deletions
diff --git a/CHANGELOG b/CHANGELOG index 941e85f68d7..ec6246a0681 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ v 8.11.0 (unreleased) - API: Endpoints for enabling and disabling deploy keys - API: List access requests, request access, approve, and deny access requests to a project or a group. !4833 - Use long options for curl examples in documentation !5703 (winniehell) + - Added tooltip listing label names to the labels value in the collapsed issuable sidebar - Remove magic comments (`# encoding: UTF-8`) from Ruby files. !5456 (winniehell) - Fix badge count alignment (ClemMakesApps) - GitLab Performance Monitoring can now track custom events such as the number of tags pushed to a repository diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js index 0526430989f..565dbeacdb3 100644 --- a/app/assets/javascripts/labels_select.js +++ b/app/assets/javascripts/labels_select.js @@ -4,7 +4,7 @@ var _this; _this = this; $('.js-label-select').each(function(i, dropdown) { - var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, projectId, saveLabelData, selectedLabel, showAny, showNo; + var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, projectId, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip; $dropdown = $(dropdown); projectId = $dropdown.data('project-id'); labelUrl = $dropdown.data('labels'); @@ -21,6 +21,7 @@ $block = $selectbox.closest('.block'); $form = $dropdown.closest('form'); $sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon span'); + $sidebarLabelTooltip = $block.find('.js-sidebar-labels-tooltip'); $value = $block.find('.value'); $loading = $block.find('.block-loading').fadeOut(); if (issueUpdateURL != null) { @@ -31,7 +32,11 @@ labelNoneHTMLTemplate = '<span class="no-value">None</span>'; } - new gl.CreateLabelDropdown($dropdown.closest('.dropdown').find('.dropdown-new-label'), projectId); + $sidebarLabelTooltip.tooltip(); + + if ($dropdown.closest('.dropdown').find('.dropdown-new-label').length) { + new gl.CreateLabelDropdown($dropdown.closest('.dropdown').find('.dropdown-new-label'), projectId); + } saveLabelData = function() { var data, selected; @@ -52,7 +57,7 @@ dataType: 'JSON', data: data }).done(function(data) { - var labelCount, template; + var labelCount, template, labelTooltipTitle, labelTitles; $loading.fadeOut(); $dropdown.trigger('loaded.gl.dropdown'); $selectbox.hide(); @@ -66,6 +71,27 @@ } $value.removeAttr('style').html(template); $sidebarCollapsedValue.text(labelCount); + + if (data.labels.length) { + labelTitles = data.labels.map(function(label) { + return label.title; + }); + + if (labelTitles.length > 5) { + labelTitles = labelTitles.slice(0, 5); + labelTitles.push('and ' + (data.labels.length - 5) + ' more'); + } + + labelTooltipTitle = labelTitles.join(', '); + } else { + labelTooltipTitle = ''; + $sidebarLabelTooltip.tooltip('destroy'); + } + + $sidebarLabelTooltip + .attr('title', labelTooltipTitle) + .tooltip('fixTitle'); + $('.has-tooltip', $value).tooltip({ container: 'body' }); diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 47d174361db..b9baeb1d6c4 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -72,6 +72,15 @@ module IssuablesHelper end end + def issuable_labels_tooltip(labels, limit: 5) + first, last = labels.partition.with_index{ |_, i| i < limit } + + label_names = first.collect(&:name) + label_names << "and #{last.size} more" unless last.empty? + + label_names.join(', ') + end + private def sidebar_gutter_collapsed? diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 8e2fcbdfab8..c1b50e65af5 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -109,7 +109,7 @@ - if issuable.project.labels.any? .block.labels - .sidebar-collapsed-icon + .sidebar-collapsed-icon.js-sidebar-labels-tooltip{ title: issuable_labels_tooltip(issuable.labels_array), data: { placement: "left", container: "body" } } = icon('tags') %span = issuable.labels_array.size diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb new file mode 100644 index 00000000000..2dd2eab0524 --- /dev/null +++ b/spec/helpers/issuables_helper_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe IssuablesHelper do + let(:label) { build_stubbed(:label) } + let(:label2) { build_stubbed(:label) } + + context 'label tooltip' do + it 'returns label text' do + expect(issuable_labels_tooltip([label])).to eq(label.title) + end + + it 'returns label text' do + expect(issuable_labels_tooltip([label, label2], limit: 1)).to eq("#{label.title}, and 1 more") + end + end +end diff --git a/spec/javascripts/fixtures/issue_sidebar_label.html.haml b/spec/javascripts/fixtures/issue_sidebar_label.html.haml new file mode 100644 index 00000000000..397bdc85c67 --- /dev/null +++ b/spec/javascripts/fixtures/issue_sidebar_label.html.haml @@ -0,0 +1,16 @@ +.block.labels + .sidebar-collapsed-icon.js-sidebar-labels-tooltip + .title.hide-collapsed + %a.edit-link.pull-right{ href: "#" } + Edit + .selectbox.hide-collapsed{ style: "display: none;" } + .dropdown + %button.dropdown-menu-toggle.js-label-select.js-multiselect{ type: "button", data: { ability_name: "issue", field_name: "issue[label_names][]", issue_update: "/root/test/issues/2.json", labels: "/root/test/labels.json", project_id: "12", show_any: "true", show_no: "true", toggle: "dropdown" } } + %span.dropdown-toggle-text + Label + %i.fa.fa-chevron-down + .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable + .dropdown-page-one + .dropdown-content + .dropdown-loading + %i.fa.fa-spinner.fa-spin diff --git a/spec/javascripts/labels_issue_sidebar_spec.js.es6 b/spec/javascripts/labels_issue_sidebar_spec.js.es6 new file mode 100644 index 00000000000..840c7b6d015 --- /dev/null +++ b/spec/javascripts/labels_issue_sidebar_spec.js.es6 @@ -0,0 +1,89 @@ +//= require lib/utils/type_utility +//= require jquery +//= require bootstrap +//= require gl_dropdown +//= require select2 +//= require jquery.nicescroll +//= require api +//= require create_label +//= require issuable_context +//= require users_select +//= require labels_select + +(() => { + let saveLabelCount = 0; + describe('Issue dropdown sidebar', () => { + fixture.preload('issue_sidebar_label.html'); + + beforeEach(() => { + fixture.load('issue_sidebar_label.html'); + new IssuableContext('{"id":1,"name":"Administrator","username":"root"}'); + new LabelsSelect(); + + spyOn(jQuery, 'ajax').and.callFake((req) => { + const d = $.Deferred(); + let LABELS_DATA = [] + + if (req.url === '/root/test/labels.json') { + for (let i = 0; i < 10; i++) { + LABELS_DATA.push({id: i, title: `test ${i}`, color: '#5CB85C'}); + } + } else if (req.url === '/root/test/issues/2.json') { + let tmp = [] + for (let i = 0; i < saveLabelCount; i++) { + tmp.push({id: i, title: `test ${i}`, color: '#5CB85C'}); + } + LABELS_DATA = {labels: tmp}; + } + + d.resolve(LABELS_DATA); + return d.promise(); + }); + }); + + it('changes collapsed tooltip when changing labels when less than 5', (done) => { + saveLabelCount = 5; + $('.edit-link').get(0).click(); + + setTimeout(() => { + expect($('.dropdown-content a').length).toBe(10); + + $('.dropdow-content a').each((i, $link) => { + if (i < 5) { + $link.get(0).click(); + } + }); + + $('.edit-link').get(0).click(); + + setTimeout(() => { + expect($('.sidebar-collapsed-icon').attr('data-original-title')).toBe('test 0, test 1, test 2, test 3, test 4'); + done(); + }, 0); + }, 0); + }); + + it('changes collapsed tooltip when changing labels when more than 5', (done) => { + saveLabelCount = 6; + $('.edit-link').get(0).click(); + + setTimeout(() => { + expect($('.dropdown-content a').length).toBe(10); + + $('.dropdow-content a').each((i, $link) => { + if (i < 5) { + $link.get(0).click(); + } + }); + + $('.edit-link').get(0).click(); + + setTimeout(() => { + expect($('.sidebar-collapsed-icon').attr('data-original-title')).toBe('test 0, test 1, test 2, test 3, test 4, and 1 more'); + done(); + }, 0); + }, 0); + }); + }); +})(); + |