diff --git a/app/assets/javascripts/header.js b/app/assets/javascripts/header.js index 34f44dad7a591ee2177b5e50dcd67bb9f462d53d..dc170c604561c3923661ca2d4a5e59c4d1ae72d9 100644 --- a/app/assets/javascripts/header.js +++ b/app/assets/javascripts/header.js @@ -1,7 +1,7 @@ /* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, no-var */ $(document).on('todo:toggle', function(e, count) { - var $todoPendingCount = $('.todos-pending-count'); + var $todoPendingCount = $('.todos-count'); $todoPendingCount.text(gl.text.highCountTrim(count)); $todoPendingCount.toggleClass('hidden', count === 0); }); diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 65bbbda41c8b5b636882aa2dcdcc1ed50197e548..abb092623c080812a47593c99f38f36307a09339 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -48,10 +48,10 @@ header { color: $gl-text-color-secondary; font-size: 18px; padding: 0; - margin: ($header-height - 28) / 2 0; + margin: (($header-height - 28) / 2) 3px; margin-left: 8px; height: 28px; - min-width: 28px; + min-width: 32px; line-height: 28px; text-align: center; @@ -73,21 +73,29 @@ header { background-color: $gray-light; color: $gl-text-color; - .todos-pending-count { - background: darken($todo-alert-blue, 10%); + svg { + fill: $gl-text-color; } } .fa-caret-down { 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 { color: $nav-toggle-gray; - margin: 7px 0; + margin: 5px 0; border-radius: 0; - position: absolute; right: -10px; padding: 6px 10px; @@ -141,10 +149,6 @@ header { min-height: $header-height; padding-left: 30px; - @media (max-width: $screen-sm-max) { - padding-right: 20px; - } - .dropdown-menu { margin-top: -5px; } @@ -243,10 +247,7 @@ header { .navbar-collapse { flex: 0 0 auto; border-top: none; - - @media (min-width: $screen-md-min) { - padding: 0; - } + padding: 0; @media (max-width: $screen-xs-max) { flex: 1 1 auto; @@ -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) { header .container-fluid { font-size: 18px; diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index 9c325227fa186b69ea768826272184fdd4a038ca..a39815319f3777a430edac2a549907bda5670998 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -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 { // workaround because we cannot use border-colapse border-top: 1px solid transparent; diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index afa6eec2fc708f3b8bca81451d329e3311dca648..43abd44d89f5ba7d8fd9f71093862e8cd940a5cc 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -11,9 +11,6 @@ = render 'layouts/nav/dashboard' - else = render 'layouts/nav/explore' - %button.navbar-toggle{ type: 'button' } - %span.sr-only Toggle navigation - = icon('ellipsis-v') .header-logo = link_to root_path, class: 'home', title: 'Dashboard', id: 'logo' do @@ -38,10 +35,20 @@ %li = link_to admin_root_path, title: 'Admin Area', aria: { label: "Admin Area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = 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 = 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') - %span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) } + = icon('check-circle fw') + %span.badge.todos-count = todos_count_format(todos_pending_count) - if current_user.can_create_project? %li @@ -70,6 +77,10 @@ %div = 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 = render 'shared/outdated_browser' diff --git a/app/views/shared/icons/_mr_bold.svg b/app/views/shared/icons/_mr_bold.svg new file mode 100644 index 0000000000000000000000000000000000000000..2daa55a8652716b2f6bf40bd569a7cb6022b264c --- /dev/null +++ b/app/views/shared/icons/_mr_bold.svg @@ -0,0 +1 @@ +<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> diff --git a/changelogs/unreleased/29866-navbar-counters.yml b/changelogs/unreleased/29866-navbar-counters.yml new file mode 100644 index 0000000000000000000000000000000000000000..c67dff6cffac15034249a173cdeacf684193b47f --- /dev/null +++ b/changelogs/unreleased/29866-navbar-counters.yml @@ -0,0 +1,4 @@ +--- +title: Add shortcuts and counters to MRs and issues in navbar +merge_request: +author: diff --git a/features/steps/dashboard/todos.rb b/features/steps/dashboard/todos.rb index 9f01dff776fa2455d1f5cdd4bb4055b3535f6ef9..7bd3c7ee65330a3418820b9b159b59aee3730dfb 100644 --- a/features/steps/dashboard/todos.rb +++ b/features/steps/dashboard/todos.rb @@ -28,7 +28,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps merge_request_reference = merge_request.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 'Done 0' @@ -44,7 +44,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps click_link 'Done' 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 'Done 1' 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 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 'Done 4' expect(page).to have_content "You're all done!" diff --git a/spec/features/issues/todo_spec.rb b/spec/features/issues/todo_spec.rb index 41ff31d2b99b95fc7f5fa0c2a60a4b6e4a799c1c..3fde85b0a5c5178887677d988ac67167d183352d 100644 --- a/spec/features/issues/todo_spec.rb +++ b/spec/features/issues/todo_spec.rb @@ -17,13 +17,13 @@ feature 'Manually create a todo item from issue', feature: true, js: true do expect(page).to have_content 'Mark done' end - page.within '.header-content .todos-pending-count' do + page.within '.header-content .todos-count' do expect(page).to have_content '1' end 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' end end @@ -34,10 +34,10 @@ feature 'Manually create a todo item from issue', feature: true, js: true do click_button 'Mark done' 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) - expect(page).to have_selector('.todos-pending-count', visible: false) + expect(page).to have_selector('.todos-count', visible: false) end end diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb index 850020109d417b4f587085a9e1f185558f71cb53..c270511c90369c67390f2bb7c9f9dfa29db8d1f6 100644 --- a/spec/features/todos/todos_spec.rb +++ b/spec/features/todos/todos_spec.rb @@ -251,7 +251,7 @@ describe 'Dashboard Todos', feature: true do end 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 'Done 0' expect(page).to have_selector('.todos-all-done', count: 1) @@ -267,7 +267,7 @@ describe 'Dashboard Todos', feature: true do end 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 it 'shows exact number in To do tab' do @@ -277,7 +277,7 @@ describe 'Dashboard Todos', feature: true do it 'shows exact number for count < 100' do 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 diff --git a/spec/javascripts/header_spec.js b/spec/javascripts/header_spec.js index 46a27b8c98f42e12a6bb645f7d85c811c3e680b7..b5dde5525e5c649bdd7abfd00cfd0489294185a4 100644 --- a/spec/javascripts/header_spec.js +++ b/spec/javascripts/header_spec.js @@ -5,7 +5,7 @@ require('~/lib/utils/text_utility'); (function() { describe('Header', function() { - var todosPendingCount = '.todos-pending-count'; + var todosPendingCount = '.todos-count'; var fixtureTemplate = 'issues/open-issue.html.raw'; function isTodosCountHidden() { @@ -21,31 +21,31 @@ require('~/lib/utils/text_utility'); 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); 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); 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); expect(isTodosCountHidden()).toEqual(false); }); - describe('when todos-pending-count is 1000', function() { + describe('when todos-count is 1000', function() { beforeEach(function() { triggerToggle(1000); }); - it('should show todos-pending-count', function() { + it('should show todos-count', function() { 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+'); }); });