Commit d63de44d authored by Annabel Dunstone Gray's avatar Annabel Dunstone Gray

Merge branch '30975-fixed-top-nav-POC' into 'master'

Add fixed positioning to top level navbar

Closes #30975

See merge request !10751
parents 09ca4c92 c757000e
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, no-unused-vars, one-var, one-var-declaration-per-line, vars-on-top, max-len */ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, no-unused-vars, one-var, one-var-declaration-per-line, vars-on-top, max-len */
import _ from 'underscore';
(function() { (function() {
var hideEndFade; var hideEndFade;
...@@ -45,4 +46,13 @@ ...@@ -45,4 +46,13 @@
} }
}); });
}); });
function applyScrollNavClass() {
const scrollOpacityHeight = 40;
$('.navbar-border').css('opacity', Math.min($(window).scrollTop() / scrollOpacityHeight, 1));
}
$(() => {
$(window).on('scroll', _.throttle(applyScrollNavClass, 100));
});
}).call(window); }).call(window);
...@@ -353,6 +353,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; ...@@ -353,6 +353,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
initAffix() { initAffix() {
const $tabs = $('.js-tabs-affix'); const $tabs = $('.js-tabs-affix');
const $fixedNav = $('.navbar-gitlab');
// Screen space on small screens is usually very sparse // Screen space on small screens is usually very sparse
// So we dont affix the tabs on these // So we dont affix the tabs on these
...@@ -371,7 +372,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; ...@@ -371,7 +372,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
.affix({ .affix({
offset: { offset: {
top: () => ( top: () => (
$diffTabs.offset().top - $tabs.height() $diffTabs.offset().top - $tabs.height() - $fixedNav.height()
), ),
}, },
}) })
......
...@@ -30,13 +30,17 @@ header { ...@@ -30,13 +30,17 @@ header {
background-color: $gray-light; background-color: $gray-light;
border: none; border: none;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
position: fixed;
top: 0;
left: 0;
right: 0;
@media (max-width: $screen-xs-min) { @media (max-width: $screen-xs-min) {
padding: 0 16px; padding: 0 16px;
} }
&.with-horizontal-nav { &.with-horizontal-nav {
border-bottom: none; border-color: transparent;
} }
.container-fluid { .container-fluid {
...@@ -110,6 +114,16 @@ header { ...@@ -110,6 +114,16 @@ header {
} }
} }
.navbar-border {
height: 1px;
position: absolute;
right: 0;
left: 0;
bottom: 0;
background-color: $border-color;
opacity: 0;
}
.global-dropdown { .global-dropdown {
position: absolute; position: absolute;
left: -10px; left: -10px;
......
...@@ -25,6 +25,10 @@ body { ...@@ -25,6 +25,10 @@ body {
.content-wrapper { .content-wrapper {
padding-bottom: 100px; padding-bottom: 100px;
&:not(.page-with-layout-nav) {
margin-top: $header-height;
}
} }
.container { .container {
......
...@@ -291,6 +291,7 @@ ...@@ -291,6 +291,7 @@
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
transition: padding $sidebar-transition-duration; transition: padding $sidebar-transition-duration;
text-align: center; text-align: center;
margin-top: $header-height;
.container-fluid { .container-fluid {
position: relative; position: relative;
...@@ -428,7 +429,7 @@ ...@@ -428,7 +429,7 @@
top: ($header-height + 1) * 3; top: ($header-height + 1) * 3;
&.affix { &.affix {
top: 0; top: $header-height;
} }
} }
} }
......
...@@ -80,6 +80,6 @@ ...@@ -80,6 +80,6 @@
&.affix { &.affix {
position: fixed; position: fixed;
top: 0; top: $header-height;
} }
} }
...@@ -689,7 +689,7 @@ ...@@ -689,7 +689,7 @@
} }
.merge-request-tabs-holder { .merge-request-tabs-holder {
top: 0; top: $header-height;
z-index: 10; z-index: 10;
background-color: $white-light; background-color: $white-light;
......
%header.navbar.navbar-gitlab{ class: nav_header_class } %header.navbar.navbar-gitlab{ class: nav_header_class }
.navbar-border
%a.sr-only.gl-accessibility{ href: "#content-body", tabindex: "1" } Skip to content %a.sr-only.gl-accessibility{ href: "#content-body", tabindex: "1" } Skip to content
.container-fluid .container-fluid
.header-content .header-content
......
- builds = @build.pipeline.builds.to_a - builds = @build.pipeline.builds.to_a
%aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar.js-right-sidebar{ data: { "offset-top" => "153", "spy" => "affix" } } %aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar.js-right-sidebar{ data: { "offset-top" => "101", "spy" => "affix" } }
.block.build-sidebar-header.visible-xs-block.visible-sm-block.append-bottom-default .block.build-sidebar-header.visible-xs-block.visible-sm-block.append-bottom-default
Job Job
%strong ##{@build.id} %strong ##{@build.id}
......
%aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "102", "spy" => "affix" } } %aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } }
.block.wiki-sidebar-header.append-bottom-default .block.wiki-sidebar-header.append-bottom-default
%a.gutter-toggle.pull-right.visible-xs-block.visible-sm-block.js-sidebar-wiki-toggle{ href: "#" } %a.gutter-toggle.pull-right.visible-xs-block.visible-sm-block.js-sidebar-wiki-toggle{ href: "#" }
= icon('angle-double-right') = icon('angle-double-right')
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
= page_specific_javascript_bundle_tag('common_vue') = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('sidebar') = page_specific_javascript_bundle_tag('sidebar')
%aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => "102", "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' } %aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
.issuable-sidebar{ data: { endpoint: "#{issuable_json_path(issuable)}" } } .issuable-sidebar{ data: { endpoint: "#{issuable_json_path(issuable)}" } }
- can_edit_issuable = can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - can_edit_issuable = can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.block.issuable-sidebar-header .block.issuable-sidebar-header
......
- affix_offset = local_assigns.fetch(:affix_offset, "102") - affix_offset = local_assigns.fetch(:affix_offset, "50")
- project = local_assigns[:project] - project = local_assigns[:project]
%aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => affix_offset, "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' } %aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => affix_offset, "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
......
...@@ -9,6 +9,7 @@ Feature: Search ...@@ -9,6 +9,7 @@ Feature: Search
Given I search for "Sho" Given I search for "Sho"
Then I should see "Shop" project link Then I should see "Shop" project link
@javascript
Scenario: I should see issues I am looking for Scenario: I should see issues I am looking for
And project has issues And project has issues
When I search for "Foo" When I search for "Foo"
...@@ -16,6 +17,7 @@ Feature: Search ...@@ -16,6 +17,7 @@ Feature: Search
Then I should see "Foo" link in the search results Then I should see "Foo" link in the search results
And I should not see "Bar" link in the search results And I should not see "Bar" link in the search results
@javascript
Scenario: I should see merge requests I am looking for Scenario: I should see merge requests I am looking for
And project has merge requests And project has merge requests
When I search for "Foo" When I search for "Foo"
...@@ -23,6 +25,7 @@ Feature: Search ...@@ -23,6 +25,7 @@ Feature: Search
Then I should see "Foo" link in the search results Then I should see "Foo" link in the search results
And I should not see "Bar" link in the search results And I should not see "Bar" link in the search results
@javascript
Scenario: I should see milestones I am looking for Scenario: I should see milestones I am looking for
And project has milestones And project has milestones
When I search for "Foo" When I search for "Foo"
...@@ -78,6 +81,7 @@ Feature: Search ...@@ -78,6 +81,7 @@ Feature: Search
And I search for "Sho" And I search for "Sho"
Then I should see "Shop" project link Then I should see "Shop" project link
@javascript
Scenario: I logout and should see issues I am looking for Scenario: I logout and should see issues I am looking for
Given project "Shop" is public Given project "Shop" is public
And I logout directly And I logout directly
......
...@@ -55,7 +55,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps ...@@ -55,7 +55,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)
click_link 'Mark all as done' find('.js-todos-mark-all').trigger('click')
page.within('.todos-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'
...@@ -69,7 +69,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps ...@@ -69,7 +69,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
end end
step 'I should see the todo marked as done' do step 'I should see the todo marked as done' do
click_link 'Done 1' find('.todos-done a').trigger('click')
expect(page).to have_link project.name_with_namespace expect(page).to have_link project.name_with_namespace
should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_irreversible) should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_irreversible)
...@@ -79,7 +79,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps ...@@ -79,7 +79,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)
click_link 'Done 4' find('.todos-done a').trigger('click')
expect(page).to have_link project.name_with_namespace expect(page).to have_link project.name_with_namespace
should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title, state: :done_irreversible) should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title, state: :done_irreversible)
......
...@@ -33,7 +33,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps ...@@ -33,7 +33,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end end
step 'I click link "Merged"' do step 'I click link "Merged"' do
click_link "Merged" find('#state-merged').trigger('click')
end end
step 'I click link "Closed"' do step 'I click link "Closed"' do
...@@ -331,7 +331,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps ...@@ -331,7 +331,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
step 'I click on the Discussion tab' do step 'I click on the Discussion tab' do
page.within '.merge-request-tabs' do page.within '.merge-request-tabs' do
click_link 'Discussion' find('.notes-tab').trigger('click')
end end
# Waits for load # Waits for load
......
...@@ -10,12 +10,12 @@ class Spinach::Features::Search < Spinach::FeatureSteps ...@@ -10,12 +10,12 @@ class Spinach::Features::Search < Spinach::FeatureSteps
step 'I search for "Foo"' do step 'I search for "Foo"' do
fill_in "dashboard_search", with: "Foo" fill_in "dashboard_search", with: "Foo"
click_button "Search" find('.btn-search').trigger('click')
end end
step 'I search for "rspec"' do step 'I search for "rspec"' do
fill_in "dashboard_search", with: "rspec" fill_in "dashboard_search", with: "rspec"
click_button "Search" find('.btn-search').trigger('click')
end end
step 'I search for "rspec" on project page' do step 'I search for "rspec" on project page' do
...@@ -25,7 +25,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps ...@@ -25,7 +25,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps
step 'I search for "Wiki content"' do step 'I search for "Wiki content"' do
fill_in "dashboard_search", with: "content" fill_in "dashboard_search", with: "content"
click_button "Search" find('.btn-search').trigger('click')
end end
step 'I click "Issues" link' do step 'I click "Issues" link' do
...@@ -35,7 +35,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps ...@@ -35,7 +35,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps
end end
step 'I click project "Shop" link' do step 'I click project "Shop" link' do
click_button 'Project' find('.js-search-project-dropdown').trigger('click')
page.within '.project-filter' do page.within '.project-filter' do
click_link project.name_with_namespace click_link project.name_with_namespace
end end
......
...@@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Group', feature: true do ...@@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Group', feature: true do
it 'creates new group', js: true do it 'creates new group', js: true do
visit dashboard_groups_path visit dashboard_groups_path
click_link 'New group' find('.btn-new').trigger('click')
new_path = 'Samurai' new_path = 'Samurai'
new_description = 'Tokugawa Shogunate' new_description = 'Tokugawa Shogunate'
......
...@@ -275,7 +275,7 @@ feature 'Diff notes resolve', feature: true, js: true do ...@@ -275,7 +275,7 @@ feature 'Diff notes resolve', feature: true, js: true do
end end
page.within '.line-resolve-all-container' do page.within '.line-resolve-all-container' do
page.find('.discussion-next-btn').click page.find('.discussion-next-btn').trigger('click')
end end
expect(page.evaluate_script("$('body').scrollTop()")).to be > 0 expect(page.evaluate_script("$('body').scrollTop()")).to be > 0
......
...@@ -44,7 +44,7 @@ describe 'Profile > Preferences', feature: true do ...@@ -44,7 +44,7 @@ describe 'Profile > Preferences', feature: true do
expect(page.current_path).to eq starred_dashboard_projects_path expect(page.current_path).to eq starred_dashboard_projects_path
end end
click_link 'Your projects' find('.shortcuts-activity').trigger('click')
expect(page).not_to have_content("You don't have starred projects yet") expect(page).not_to have_content("You don't have starred projects yet")
expect(page.current_path).to eq dashboard_projects_path expect(page.current_path).to eq dashboard_projects_path
......
...@@ -17,14 +17,14 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t ...@@ -17,14 +17,14 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t
login_as(user) login_as(user)
visit namespace_project_path(project.namespace, project) visit namespace_project_path(project.namespace, project)
click_link 'Wiki' find('.shortcuts-wiki').trigger('click')
WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute
end end
context "while creating a new wiki page" do context "while creating a new wiki page" do
context "when there are no spaces or hyphens in the page name" do context "when there are no spaces or hyphens in the page name" do
it "rewrites relative links as expected" do it "rewrites relative links as expected" do
click_link 'New page' find('.add-new-wiki').trigger('click')
page.within '#modal-new-wiki' do page.within '#modal-new-wiki' do
fill_in :new_wiki_path, with: 'a/b/c/d' fill_in :new_wiki_path, with: 'a/b/c/d'
click_button 'Create page' click_button 'Create page'
...@@ -91,7 +91,7 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t ...@@ -91,7 +91,7 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t
context "while editing a wiki page" do context "while editing a wiki page" do
def create_wiki_page(path) def create_wiki_page(path)
click_link 'New page' find('.add-new-wiki').trigger('click')
page.within '#modal-new-wiki' do page.within '#modal-new-wiki' do
fill_in :new_wiki_path, with: path fill_in :new_wiki_path, with: path
......
require 'spec_helper' require 'spec_helper'
feature 'Projects > Wiki > User creates wiki page', feature: true do feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do
let(:user) { create(:user) } let(:user) { create(:user) }
background do background do
...@@ -8,7 +8,7 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do ...@@ -8,7 +8,7 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do
login_as(user) login_as(user)
visit namespace_project_path(project.namespace, project) visit namespace_project_path(project.namespace, project)
click_link 'Wiki' find('.shortcuts-wiki').trigger('click')
end end
context 'in the user namespace' do context 'in the user namespace' do
......
...@@ -27,7 +27,7 @@ describe "Search", feature: true do ...@@ -27,7 +27,7 @@ describe "Search", feature: true do
end end
it 'shows group name after filtering' do it 'shows group name after filtering' do
find('.js-search-group-dropdown').click find('.js-search-group-dropdown').trigger('click')
wait_for_ajax wait_for_ajax
page.within '.search-holder' do page.within '.search-holder' do
...@@ -38,7 +38,7 @@ describe "Search", feature: true do ...@@ -38,7 +38,7 @@ describe "Search", feature: true do
end end
it 'filters by group projects after filtering by group' do it 'filters by group projects after filtering by group' do
find('.js-search-group-dropdown').click find('.js-search-group-dropdown').trigger('click')
wait_for_ajax wait_for_ajax
page.within '.search-holder' do page.within '.search-holder' do
...@@ -48,7 +48,7 @@ describe "Search", feature: true do ...@@ -48,7 +48,7 @@ describe "Search", feature: true do
expect(find('.js-search-group-dropdown')).to have_content(group.name) expect(find('.js-search-group-dropdown')).to have_content(group.name)
page.within('.project-filter') do page.within('.project-filter') do
find('.js-search-project-dropdown').click find('.js-search-project-dropdown').trigger('click')
wait_for_ajax wait_for_ajax
expect(page).to have_link(group_project.name_with_namespace) expect(page).to have_link(group_project.name_with_namespace)
...@@ -57,7 +57,7 @@ describe "Search", feature: true do ...@@ -57,7 +57,7 @@ describe "Search", feature: true do
it 'shows project name after filtering' do it 'shows project name after filtering' do
page.within('.project-filter') do page.within('.project-filter') do
find('.js-search-project-dropdown').click find('.js-search-project-dropdown').trigger('click')
wait_for_ajax wait_for_ajax
click_link project.name_with_namespace click_link project.name_with_namespace
......
...@@ -251,7 +251,7 @@ describe 'Dashboard Todos', feature: true do ...@@ -251,7 +251,7 @@ describe 'Dashboard Todos', feature: true do
describe 'mark all as done', js: true do describe 'mark all as done', js: true do
before do before do
visit dashboard_todos_path visit dashboard_todos_path
click_link 'Mark all as done' find('.js-todos-mark-all').trigger('click')
end end
it 'shows "All done" message!' do it 'shows "All done" message!' do
...@@ -308,9 +308,9 @@ describe 'Dashboard Todos', feature: true do ...@@ -308,9 +308,9 @@ describe 'Dashboard Todos', feature: true do
end end
def mark_all_and_undo def mark_all_and_undo
click_link 'Mark all as done' find('.js-todos-mark-all').trigger('click')
wait_for_ajax wait_for_ajax
click_link 'Undo mark all as done' find('.js-todos-undo-all').trigger('click')
wait_for_ajax wait_for_ajax
end end
end end
......
...@@ -20,7 +20,7 @@ describe 'User Callouts', js: true do ...@@ -20,7 +20,7 @@ describe 'User Callouts', js: true do
visit dashboard_projects_path visit dashboard_projects_path
within('.user-callout') do within('.user-callout') do
find('.close').click find('.close').trigger('click')
end end
visit dashboard_projects_path visit dashboard_projects_path
......
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