Commit 3e1fb2a5 authored by Jacob Schatz's avatar Jacob Schatz

Merge branch '29866-navbar-counters' into 'master'

Add shortcuts and counters to MRs and issues in navbar

Closes #29866

See merge request !10314
parents 4cf16426 d08d12ae
/* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, no-var */ /* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, no-var */
$(document).on('todo:toggle', function(e, count) { $(document).on('todo:toggle', function(e, count) {
var $todoPendingCount = $('.todos-pending-count'); var $todoPendingCount = $('.todos-count');
$todoPendingCount.text(gl.text.highCountTrim(count)); $todoPendingCount.text(gl.text.highCountTrim(count));
$todoPendingCount.toggleClass('hidden', count === 0); $todoPendingCount.toggleClass('hidden', count === 0);
}); });
...@@ -48,10 +48,10 @@ header { ...@@ -48,10 +48,10 @@ header {
color: $gl-text-color-secondary; color: $gl-text-color-secondary;
font-size: 18px; font-size: 18px;
padding: 0; padding: 0;
margin: ($header-height - 28) / 2 0; margin: (($header-height - 28) / 2) 3px;
margin-left: 8px; margin-left: 8px;
height: 28px; height: 28px;
min-width: 28px; min-width: 32px;
line-height: 28px; line-height: 28px;
text-align: center; text-align: center;
...@@ -73,21 +73,29 @@ header { ...@@ -73,21 +73,29 @@ header {
background-color: $gray-light; background-color: $gray-light;
color: $gl-text-color; color: $gl-text-color;
.todos-pending-count { svg {
background: darken($todo-alert-blue, 10%); fill: $gl-text-color;
} }
} }
.fa-caret-down { .fa-caret-down {
font-size: 14px; font-size: 14px;
} }
svg {
position: relative;
top: 2px;
height: 17px;
// hack to get SVG to line up with FA icons
width: 23px;
fill: $gl-text-color-secondary;
}
} }
.navbar-toggle { .navbar-toggle {
color: $nav-toggle-gray; color: $nav-toggle-gray;
margin: 7px 0; margin: 5px 0;
border-radius: 0; border-radius: 0;
position: absolute;
right: -10px; right: -10px;
padding: 6px 10px; padding: 6px 10px;
...@@ -141,10 +149,6 @@ header { ...@@ -141,10 +149,6 @@ header {
min-height: $header-height; min-height: $header-height;
padding-left: 30px; padding-left: 30px;
@media (max-width: $screen-sm-max) {
padding-right: 20px;
}
.dropdown-menu { .dropdown-menu {
margin-top: -5px; margin-top: -5px;
} }
...@@ -243,10 +247,7 @@ header { ...@@ -243,10 +247,7 @@ header {
.navbar-collapse { .navbar-collapse {
flex: 0 0 auto; flex: 0 0 auto;
border-top: none; border-top: none;
@media (min-width: $screen-md-min) {
padding: 0; padding: 0;
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
flex: 1 1 auto; flex: 1 1 auto;
...@@ -263,6 +264,34 @@ header { ...@@ -263,6 +264,34 @@ header {
} }
} }
.navbar-nav {
li {
.badge {
position: inherit;
top: -3px;
font-weight: normal;
margin-left: -12px;
font-size: 11px;
color: $white-light;
padding: 1px 5px 2px;
border-radius: 7px;
box-shadow: 0 1px 0 rgba($gl-header-color, .2);
&.issues-count {
background-color: $green-500;
}
&.merge-requests-count {
background-color: $orange-600;
}
&.todos-count {
background-color: $blue-500;
}
}
}
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
header .container-fluid { header .container-fluid {
font-size: 18px; font-size: 18px;
......
...@@ -3,25 +3,6 @@ ...@@ -3,25 +3,6 @@
* *
*/ */
.navbar-nav {
li {
.badge.todos-pending-count {
position: inherit;
top: -10px;
margin-top: -5px;
font-weight: normal;
background: $todo-alert-blue;
margin-left: -13px;
font-size: 11px;
color: $white-light;
padding: 4px;
padding-top: 1px;
padding-bottom: 2px;
border-radius: 7px;
}
}
}
.todos-list > .todo { .todos-list > .todo {
// workaround because we cannot use border-colapse // workaround because we cannot use border-colapse
border-top: 1px solid transparent; border-top: 1px solid transparent;
......
...@@ -11,9 +11,6 @@ ...@@ -11,9 +11,6 @@
= render 'layouts/nav/dashboard' = render 'layouts/nav/dashboard'
- else - else
= render 'layouts/nav/explore' = render 'layouts/nav/explore'
%button.navbar-toggle{ type: 'button' }
%span.sr-only Toggle navigation
= icon('ellipsis-v')
.header-logo .header-logo
= link_to root_path, class: 'home', title: 'Dashboard', id: 'logo' do = link_to root_path, class: 'home', title: 'Dashboard', id: 'logo' do
...@@ -38,10 +35,20 @@ ...@@ -38,10 +35,20 @@
%li %li
= link_to admin_root_path, title: 'Admin Area', aria: { label: "Admin Area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to admin_root_path, title: 'Admin Area', aria: { label: "Admin Area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('wrench fw') = icon('wrench fw')
%li
= link_to assigned_issues_dashboard_path, title: 'Issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('hashtag fw')
%span.badge.issues-count
= number_with_delimiter(cached_assigned_issuables_count(current_user, :issues, :opened))
%li
= link_to assigned_mrs_dashboard_path, title: 'Merge requests', aria: { label: "Merge requests" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= custom_icon('mr_bold')
%span.badge.merge-requests-count
= number_with_delimiter(cached_assigned_issuables_count(current_user, :merge_requests, :opened))
%li %li
= link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('check-square fw') = icon('check-circle fw')
%span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) } %span.badge.todos-count
= todos_count_format(todos_pending_count) = todos_count_format(todos_pending_count)
- if current_user.can_create_project? - if current_user.can_create_project?
%li %li
...@@ -70,6 +77,10 @@ ...@@ -70,6 +77,10 @@
%div %div
= link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success' = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success'
%button.navbar-toggle{ type: 'button' }
%span.sr-only Toggle navigation
= icon('ellipsis-v')
= yield :header_content = yield :header_content
= render 'shared/outdated_browser' = render 'shared/outdated_browser'
......
<svg width="15" height="20" viewBox="0 0 12 14" xmlns="http://www.w3.org/2000/svg"><path d="M1 4.967a2.15 2.15 0 1 1 2.3 0v5.066a2.15 2.15 0 1 1-2.3 0V4.967zm7.85 5.17V5.496c0-.745-.603-1.346-1.35-1.346V6l-3-3 3-3v1.85c2.016 0 3.65 1.63 3.65 3.646v4.45a2.15 2.15 0 1 1-2.3.191z" fill-rule="nonzero"/></svg>
---
title: Add shortcuts and counters to MRs and issues in navbar
merge_request:
author:
...@@ -28,7 +28,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps ...@@ -28,7 +28,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
merge_request_reference = merge_request.to_reference(full: true) merge_request_reference = merge_request.to_reference(full: true)
issue_reference = issue.to_reference(full: true) issue_reference = issue.to_reference(full: true)
page.within('.todos-pending-count') { expect(page).to have_content '4' } page.within('.todos-count') { expect(page).to have_content '4' }
expect(page).to have_content 'To do 4' expect(page).to have_content 'To do 4'
expect(page).to have_content 'Done 0' expect(page).to have_content 'Done 0'
...@@ -44,7 +44,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps ...@@ -44,7 +44,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
click_link 'Done' click_link 'Done'
end end
page.within('.todos-pending-count') { expect(page).to have_content '3' } page.within('.todos-count') { expect(page).to have_content '3' }
expect(page).to have_content 'To do 3' expect(page).to have_content 'To do 3'
expect(page).to have_content 'Done 1' expect(page).to have_content 'Done 1'
should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_reversible) should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_reversible)
...@@ -56,7 +56,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps ...@@ -56,7 +56,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
click_link 'Mark all as done' click_link 'Mark all as done'
page.within('.todos-pending-count') { expect(page).to have_content '0' } page.within('.todos-count') { expect(page).to have_content '0' }
expect(page).to have_content 'To do 0' expect(page).to have_content 'To do 0'
expect(page).to have_content 'Done 4' expect(page).to have_content 'Done 4'
expect(page).to have_content "You're all done!" expect(page).to have_content "You're all done!"
......
...@@ -17,13 +17,13 @@ feature 'Manually create a todo item from issue', feature: true, js: true do ...@@ -17,13 +17,13 @@ feature 'Manually create a todo item from issue', feature: true, js: true do
expect(page).to have_content 'Mark done' expect(page).to have_content 'Mark done'
end end
page.within '.header-content .todos-pending-count' do page.within '.header-content .todos-count' do
expect(page).to have_content '1' expect(page).to have_content '1'
end end
visit namespace_project_issue_path(project.namespace, project, issue) visit namespace_project_issue_path(project.namespace, project, issue)
page.within '.header-content .todos-pending-count' do page.within '.header-content .todos-count' do
expect(page).to have_content '1' expect(page).to have_content '1'
end end
end end
...@@ -34,10 +34,10 @@ feature 'Manually create a todo item from issue', feature: true, js: true do ...@@ -34,10 +34,10 @@ feature 'Manually create a todo item from issue', feature: true, js: true do
click_button 'Mark done' click_button 'Mark done'
end end
expect(page).to have_selector('.todos-pending-count', visible: false) expect(page).to have_selector('.todos-count', visible: false)
visit namespace_project_issue_path(project.namespace, project, issue) visit namespace_project_issue_path(project.namespace, project, issue)
expect(page).to have_selector('.todos-pending-count', visible: false) expect(page).to have_selector('.todos-count', visible: false)
end end
end end
...@@ -251,7 +251,7 @@ describe 'Dashboard Todos', feature: true do ...@@ -251,7 +251,7 @@ describe 'Dashboard Todos', feature: true do
end end
it 'shows "All done" message' do it 'shows "All done" message' do
within('.todos-pending-count') { expect(page).to have_content '0' } within('.todos-count') { expect(page).to have_content '0' }
expect(page).to have_content 'To do 0' expect(page).to have_content 'To do 0'
expect(page).to have_content 'Done 0' expect(page).to have_content 'Done 0'
expect(page).to have_selector('.todos-all-done', count: 1) expect(page).to have_selector('.todos-all-done', count: 1)
...@@ -267,7 +267,7 @@ describe 'Dashboard Todos', feature: true do ...@@ -267,7 +267,7 @@ describe 'Dashboard Todos', feature: true do
end end
it 'shows 99+ for count >= 100 in notification' do it 'shows 99+ for count >= 100 in notification' do
expect(page).to have_selector('.todos-pending-count', text: '99+') expect(page).to have_selector('.todos-count', text: '99+')
end end
it 'shows exact number in To do tab' do it 'shows exact number in To do tab' do
...@@ -277,7 +277,7 @@ describe 'Dashboard Todos', feature: true do ...@@ -277,7 +277,7 @@ describe 'Dashboard Todos', feature: true do
it 'shows exact number for count < 100' do it 'shows exact number for count < 100' do
3.times { first('.js-done-todo').click } 3.times { first('.js-done-todo').click }
expect(page).to have_selector('.todos-pending-count', text: '98') expect(page).to have_selector('.todos-count', text: '98')
end end
end end
......
...@@ -5,7 +5,7 @@ require('~/lib/utils/text_utility'); ...@@ -5,7 +5,7 @@ require('~/lib/utils/text_utility');
(function() { (function() {
describe('Header', function() { describe('Header', function() {
var todosPendingCount = '.todos-pending-count'; var todosPendingCount = '.todos-count';
var fixtureTemplate = 'issues/open-issue.html.raw'; var fixtureTemplate = 'issues/open-issue.html.raw';
function isTodosCountHidden() { function isTodosCountHidden() {
...@@ -21,31 +21,31 @@ require('~/lib/utils/text_utility'); ...@@ -21,31 +21,31 @@ require('~/lib/utils/text_utility');
loadFixtures(fixtureTemplate); loadFixtures(fixtureTemplate);
}); });
it('should update todos-pending-count after receiving the todo:toggle event', function() { it('should update todos-count after receiving the todo:toggle event', function() {
triggerToggle(5); triggerToggle(5);
expect($(todosPendingCount).text()).toEqual('5'); expect($(todosPendingCount).text()).toEqual('5');
}); });
it('should hide todos-pending-count when it is 0', function() { it('should hide todos-count when it is 0', function() {
triggerToggle(0); triggerToggle(0);
expect(isTodosCountHidden()).toEqual(true); expect(isTodosCountHidden()).toEqual(true);
}); });
it('should show todos-pending-count when it is more than 0', function() { it('should show todos-count when it is more than 0', function() {
triggerToggle(10); triggerToggle(10);
expect(isTodosCountHidden()).toEqual(false); expect(isTodosCountHidden()).toEqual(false);
}); });
describe('when todos-pending-count is 1000', function() { describe('when todos-count is 1000', function() {
beforeEach(function() { beforeEach(function() {
triggerToggle(1000); triggerToggle(1000);
}); });
it('should show todos-pending-count', function() { it('should show todos-count', function() {
expect(isTodosCountHidden()).toEqual(false); expect(isTodosCountHidden()).toEqual(false);
}); });
it('should show 99+ for todos-pending-count', function() { it('should show 99+ for todos-count', function() {
expect($(todosPendingCount).text()).toEqual('99+'); expect($(todosPendingCount).text()).toEqual('99+');
}); });
}); });
......
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