Merge branch 'experimental-top-nav' into 'master'

Top navigation redesign

Closes #34022, #34035, #34037, #34038, and #34021

See merge request !12214
This commit is contained in:
Annabel Dunstone Gray 2017-06-26 18:28:30 +00:00
commit 439816529e
18 changed files with 490 additions and 8 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -55,6 +55,7 @@ import RefSelectDropdown from './ref_select_dropdown';
import GfmAutoComplete from './gfm_auto_complete';
import ShortcutsBlob from './shortcuts_blob';
import initSettingsPanels from './settings_panels';
import initExperimentalFlags from './experimental_flags';
(function() {
var Dispatcher;
@ -120,6 +121,9 @@ import initSettingsPanels from './settings_panels';
}
switch (page) {
case 'profiles:preferences:show':
initExperimentalFlags();
break;
case 'sessions:new':
new UsernameValidator();
new ActiveTabMemoizer();

View file

@ -0,0 +1,11 @@
import Cookies from 'js-cookie';
export default () => {
$('.js-experiment-feature-toggle').on('change', (e) => {
const el = e.target;
Cookies.set(el.name, el.value, {
expires: 365 * 10,
});
});
};

View file

@ -299,9 +299,10 @@ $(function () {
// Commit show suppressed diff
});
$('.navbar-toggle').on('click', function () {
$('.header-content .title').toggle();
$('.header-content .title, .header-content .navbar-sub-nav').toggle();
$('.header-content .header-logo').toggle();
$('.header-content .navbar-collapse').toggle();
$('.js-navbar-toggle-left, .js-navbar-toggle-right, .title-container').toggle();
return $('.navbar-toggle').toggleClass('active');
});
// Show/hide comments on diff

View file

@ -34,6 +34,8 @@ header {
top: 0;
left: 0;
right: 0;
color: $gl-text-color-secondary;
border-radius: 0;
@media (max-width: $screen-xs-min) {
padding: 0 16px;
@ -59,7 +61,7 @@ header {
padding: 0;
.nav > li > a {
color: $gl-text-color-secondary;
color: currentColor;
font-size: 18px;
padding: 0;
margin: (($header-height - 28) / 2) 3px;
@ -84,7 +86,7 @@ header {
&:hover,
&:focus,
&:active {
background-color: $gray-light;
background-color: transparent;
color: $gl-text-color;
svg {
@ -96,13 +98,19 @@ header {
font-size: 14px;
}
.fa-chevron-down {
position: relative;
top: -3px;
font-size: 10px;
}
svg {
position: relative;
top: 2px;
height: 17px;
// hack to get SVG to line up with FA icons
width: 23px;
fill: $gl-text-color-secondary;
fill: currentColor;
}
}
@ -225,7 +233,7 @@ header {
}
a {
color: $gl-text-color;
color: currentColor;
&:hover {
text-decoration: underline;
@ -346,6 +354,7 @@ header {
width: auto;
min-width: 140px;
margin-top: -5px;
color: $gl-text-color;
left: auto;
.current-user {

View file

@ -74,6 +74,10 @@ $red-700: #a62d19;
$red-800: #8b2615;
$red-900: #711e11;
$purple-700: #4a2192;
$purple-800: #2c0a5c;
$purple-900: #380d75;
$black: #000;
$black-transparent: rgba(0, 0, 0, 0.3);

View file

@ -0,0 +1,267 @@
@import "framework/variables";
@import 'framework/tw_bootstrap_variables';
@import "bootstrap/variables";
header.navbar-gitlab-new {
color: $white-light;
background-color: $purple-900;
border-bottom: 0;
.header-content {
padding-left: 0;
.title-container {
padding-top: 0;
overflow: visible;
}
.title {
display: block;
height: 100%;
padding-right: 0;
color: currentColor;
> a {
display: flex;
align-items: center;
height: 100%;
padding-top: 3px;
padding-right: $gl-padding;
padding-left: $gl-padding;
margin-left: -$gl-padding;
border-bottom: 3px solid transparent;
@media (min-width: $screen-sm-min) {
padding-right: $gl-padding;
padding-left: $gl-padding;
}
svg {
margin-top: -3px;
@media (min-width: $screen-sm-min) {
margin-right: 10px;
}
}
&:hover,
&:focus {
color: currentColor;
text-decoration: none;
border-bottom-color: $white-light;
}
}
}
.dropdown.open {
> a {
border-bottom-color: $white-light;
}
}
.dropdown-menu {
margin-top: 4px;
min-width: 130px;
@media (max-width: $screen-xs-max) {
left: auto;
right: 0;
}
}
}
.navbar-collapse {
padding-left: 0;
color: $white-light;
box-shadow: 0;
@media (max-width: $screen-xs-max) {
margin-left: -$gl-padding;
margin-right: -10px;
}
.dropdown-bold-header {
color: initial;
}
.nav {
> li:not(.hidden-xs) a {
@media (max-width: $screen-xs-max) {
margin-left: 0;
min-width: 100%;
}
}
}
}
.container-fluid {
.navbar-toggle {
min-width: 45px;
padding: 6px $gl-padding;
margin-right: -7px;
font-size: 14px;
text-align: center;
color: currentColor;
border-left: 1px solid lighten($purple-700, 10%);
&:hover,
&:focus,
&.active {
color: currentColor;
background-color: transparent;
}
}
.navbar-nav {
@media (max-width: $screen-xs-max) {
display: flex;
padding-right: 10px;
}
li {
.badge {
box-shadow: none;
}
}
}
.nav > li {
&.header-user {
@media (max-width: $screen-xs-max) {
padding-left: 10px;
}
}
> a {
background: none;
opacity: .9;
will-change: opacity;
&.header-user-dropdown-toggle {
.header-user-avatar {
border-color: $white-light;
}
}
&:hover,
&:focus {
color: $white-light;
opacity: 1;
> svg {
fill: $white-light;
}
&.header-user-dropdown-toggle {
.header-user-avatar {
border-color: $white-light;
}
}
}
}
}
}
}
.navbar-sub-nav {
display: flex;
margin-bottom: 0;
color: $white-light;
> li {
&.active > a,
a:hover,
a:focus {
border-bottom-color: $white-light;
text-decoration: none;
outline: 0;
opacity: 1;
}
> a {
display: block;
padding: 16px 10px 13px;
font-size: 13px;
color: currentColor;
border-bottom: 3px solid transparent;
opacity: .9;
will-change: opacity;
@media (min-width: $screen-sm-min) {
padding: 15px $gl-padding 12px;
font-size: 14px;
}
}
}
.dropdown-chevron {
position: relative;
top: -1px;
font-size: 10px;
}
}
.header-user .dropdown-menu-nav,
.header-new .dropdown-menu-nav {
margin-top: 4px;
}
.search {
form {
border-color: $purple-800;
&:hover {
border-color: rgba($white-light, .6);
box-shadow: none;
}
}
&.search-active form {
border-color: $white-light;
}
form,
.search-input {
background-color: $purple-700;
}
.search-input {
color: $white-light;
}
.search-input::placeholder {
color: rgba($white-light, .6);
}
.location-badge {
font-size: 12px;
color: rgba($white-light, .6);
background-color: $purple-800;
transition: color 0.15s;
will-change: color;
}
.search-input-wrap {
.search-icon,
.clear-icon {
color: rgba($white-light, .6);
}
}
&.search-active {
.location-badge {
color: $white-light;
background-color: $purple-800;
}
.search-input-wrap {
.search-icon {
color: rgba($white-light, .6);
}
.clear-icon {
color: $white-light;
}
}
}
}

View file

@ -300,4 +300,12 @@ module ApplicationHelper
"https://www.twitter.com/#{name}"
end
end
def can_toggle_new_nav?
Rails.env.development?
end
def show_new_nav?
cookies["new_nav"] == "true"
end
end

View file

@ -30,6 +30,9 @@
= stylesheet_link_tag "test", media: "all" if Rails.env.test?
= stylesheet_link_tag 'peek' if peek_enabled?
- if show_new_nav?
= stylesheet_link_tag "new_nav", media: "all"
= Gon::Base.render_data
= webpack_bundle_tag "runtime"

View file

@ -4,7 +4,10 @@
%body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}" } }
= render "layouts/init_auto_complete" if @gfm_form
= render 'peek/bar'
= render "layouts/header/default", title: header_title
- if show_new_nav?
= render "layouts/header/new"
- else
= render "layouts/header/default", title: header_title
= render 'layouts/page', sidebar: sidebar, nav: nav
= yield :scripts_body

View file

@ -74,6 +74,9 @@
= link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username }
%li
= link_to "Settings", profile_path
- if can_toggle_new_nav?
%li
= link_to "Turn on new nav", profile_preferences_path(anchor: "new-navigation")
%li.divider
%li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link"

View file

@ -0,0 +1,93 @@
%header.navbar.navbar-gitlab.navbar-gitlab-new{ class: nav_header_class }
%a.sr-only.gl-accessibility{ href: "#content-body", tabindex: "1" } Skip to content
.container-fluid
.header-content
.title-container
%h1.title
= link_to root_path, title: 'Dashboard' do
= brand_header_logo
%span.hidden-xs
GitLab
- if current_user
= render "layouts/nav/new_dashboard"
- else
= render "layouts/nav/new_explore"
.navbar-collapse.collapse
%ul.nav.navbar-nav
%li.hidden-sm.hidden-xs
= render 'layouts/search' unless current_controller?(:search)
%li.visible-sm-inline-block.visible-xs-inline-block
= link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('search')
- if current_user
- if session[:impersonator_id]
%li.impersonation
= link_to admin_impersonation_path, method: :delete, title: "Stop impersonation", aria: { label: 'Stop impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= icon('user-secret fw')
- if current_user.admin?
%li
= link_to admin_root_path, title: 'Admin area', aria: { label: "Admin area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('wrench fw')
= render 'layouts/header/new_dropdown'
- if Gitlab::Sherlock.enabled?
%li
= link_to sherlock_transactions_path, title: 'Sherlock Transactions',
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('tachometer fw')
%li
= link_to assigned_issues_dashboard_path, title: 'Issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('hashtag fw')
- issues_count = assigned_issuables_count(:issues)
%span.badge.issues-count{ class: ('hidden' if issues_count.zero?) }
= number_with_delimiter(issues_count)
%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')
- merge_requests_count = assigned_issuables_count(:merge_requests)
%span.badge.merge-requests-count{ class: ('hidden' if merge_requests_count.zero?) }
= number_with_delimiter(merge_requests_count)
%li
= link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('check-circle fw')
%span.badge.todos-count{ class: ('hidden' if todos_pending_count.zero?) }
= todos_count_format(todos_pending_count)
%li.header-user.dropdown
= link_to current_user, class: "header-user-dropdown-toggle", data: { toggle: "dropdown" } do
= image_tag avatar_icon(current_user, 26), width: 26, height: 26, class: "header-user-avatar"
= icon('chevron-down')
.dropdown-menu-nav.dropdown-menu-align-right
%ul
%li.current-user
.user-name.bold
= current_user.name
@#{current_user.username}
%li.divider
%li
= link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username }
%li
= link_to "Settings", profile_path
%li
= link_to "Turn off new nav", profile_preferences_path(anchor: "new-navigation")
%li.divider
%li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link"
- else
%li
%div
= link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success'
%button.navbar-toggle.hidden-sm.hidden-md.hidden-lg{ type: 'button' }
%span.sr-only Toggle navigation
= icon('ellipsis-v', class: 'js-navbar-toggle-right')
= icon('times', class: 'js-navbar-toggle-left', style: 'display: none;')
= yield :header_content
= render 'shared/outdated_browser'
- if @project && !@project.empty_repo?
- if ref = @ref || @project.repository.root_ref
:javascript
var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, ref)}";

View file

@ -1,7 +1,11 @@
%li.header-new.dropdown
= link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip", title: "New...", ref: 'tooltip', aria: { label: "New..." }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body' } do
= icon('plus fw')
= icon('caret-down')
- if show_new_nav?
= icon('plus')
= icon('chevron-down')
- else
= icon('plus fw')
= icon('caret-down')
.dropdown-menu-nav.dropdown-menu-align-right
%ul
- if @group&.persisted?

View file

@ -0,0 +1,33 @@
%ul.list-unstyled.navbar-sub-nav
= nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: {class: "home"}) do
= link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do
Projects
= nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
= link_to dashboard_groups_path, class: 'dashboard-shortcuts-groups', title: 'Groups' do
Groups
= nav_link(path: 'dashboard#activity', html_options: { class: "hidden-xs hidden-sm" }) do
= link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do
Activity
%li.dropdown
%a{ href: "#", data: { toggle: "dropdown" } }
More
= icon("chevron-down", class: "dropdown-chevron")
.dropdown-menu
%ul
= nav_link(path: 'dashboard#activity', html_options: { class: "visible-xs visible-sm" }) do
= link_to activity_dashboard_path, title: 'Activity' do
Activity
= nav_link(controller: 'dashboard/milestones') do
= link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: 'Milestones' do
Milestones
= nav_link(controller: 'dashboard/snippets') do
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: 'Snippets' do
Snippets
%li.divider
%li
= link_to "Help", help_path, title: 'About GitLab CE'

View file

@ -0,0 +1,19 @@
%ul.list-unstyled.navbar-sub-nav
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
= link_to explore_root_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do
Projects
= nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
= link_to explore_groups_path, title: 'Groups', class: 'dashboard-shortcuts-groups' do
Groups
%li.dropdown
%a{ href: "#", data: { toggle: "dropdown" } }
More
= icon("chevron-down", class: "dropdown-chevron")
.dropdown-menu
%ul
= nav_link(controller: :snippets) do
= link_to explore_snippets_path, title: 'Snippets', class: 'dashboard-shortcuts-snippets' do
Snippets
%li.divider
%li
= link_to "Help", help_path, title: 'About GitLab CE'

View file

@ -15,6 +15,25 @@
.preview= image_tag "#{scheme.css_class}-scheme-preview.png"
= f.radio_button :color_scheme_id, scheme.id
= scheme.name
- if can_toggle_new_nav?
.col-sm-12
%hr
.col-lg-3.profile-settings-sidebar#new-navigation
%h4.prepend-top-0
New Navigation
%p
This setting allows you to turn on or off the new upcoming navigation concept.
= succeed '.' do
= link_to 'Learn more', '', target: '_blank'
.col-lg-9.syntax-theme
= label_tag do
.preview= image_tag "old_nav.png"
%input.js-experiment-feature-toggle{ type: "radio", value: "false", name: "new_nav", checked: !show_new_nav? }
Old
= label_tag do
.preview= image_tag "new_nav.png"
%input.js-experiment-feature-toggle{ type: "radio", value: "true", name: "new_nav", checked: show_new_nav? }
New
.col-sm-12
%hr
.col-lg-3.profile-settings-sidebar

View file

@ -109,6 +109,7 @@ module Gitlab
config.assets.precompile << "lib/ace.js"
config.assets.precompile << "vendor/assets/fonts/*"
config.assets.precompile << "test.css"
config.assets.precompile << "new_nav.css"
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'