Commit b1230bbd authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'group-navigation-redesign' into 'master'

Redesign navigation for group pages

Part of #14838. This MR targets on desktop version. Mobile version improvements will be in separate merge request 

See merge request !3980
parents 0cdd4f31 00b3eedf
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
&.s46 { width: 46px; height: 46px; margin-right: 15px; } &.s46 { width: 46px; height: 46px; margin-right: 15px; }
&.s48 { width: 48px; height: 48px; margin-right: 10px; } &.s48 { width: 48px; height: 48px; margin-right: 10px; }
&.s60 { width: 60px; height: 60px; margin-right: 12px; } &.s60 { width: 60px; height: 60px; margin-right: 12px; }
&.s70 { width: 70px; height: 70px; margin-right: 14px; }
&.s90 { width: 90px; height: 90px; margin-right: 15px; } &.s90 { width: 90px; height: 90px; margin-right: 15px; }
&.s110 { width: 110px; height: 110px; margin-right: 15px; } &.s110 { width: 110px; height: 110px; margin-right: 15px; }
&.s140 { width: 140px; height: 140px; margin-right: 20px; } &.s140 { width: 140px; height: 140px; margin-right: 20px; }
......
...@@ -155,6 +155,41 @@ ...@@ -155,6 +155,41 @@
right: auto; right: auto;
} }
} }
&.groups-cover-block {
background: $white-light;
border-bottom: 1px solid $border-color;
text-align: left;
padding: 24px 0;
.group-info {
.cover-title {
margin-top: 9px;
}
p {
margin-bottom: 0;
}
}
@media (max-width: $screen-xs-max) {
text-align: center;
.avatar {
float: none;
}
}
}
.group-info {
h1 {
display: inline;
font-weight: normal;
font-size: 24px;
color: $gl-title-color;
}
}
} }
.block-connector { .block-connector {
......
...@@ -30,6 +30,10 @@ header { ...@@ -30,6 +30,10 @@ header {
border: none; border: none;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
&.with-horizontal-nav {
border-bottom: none;
}
.container-fluid { .container-fluid {
width: 100% !important; width: 100% !important;
filter: none; filter: none;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
} }
.rss-btn { .rss-btn {
display: none !important; display: none;
} }
.project-home-links { .project-home-links {
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
} }
&.active a { &.active a {
color: #000; border-bottom: 2px solid $link-underline-blue;
border-bottom: 2px solid #4688f1; color: $black;
} }
.badge { .badge {
...@@ -140,6 +140,12 @@ ...@@ -140,6 +140,12 @@
} }
} }
.project-filter-form {
input {
background-color: $background-color;
}
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
padding-bottom: 0; padding-bottom: 0;
...@@ -187,13 +193,31 @@ ...@@ -187,13 +193,31 @@
} }
.layout-nav { .layout-nav {
position: fixed;
top: $header-height;
width: 100%;
z-index: 1;
background: $background-color; background: $background-color;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
transition-duration: .3s;
.controls { .controls {
float: right; float: right;
position: relative; padding: 7px 5px 0 0;
top: 10px;
i {
color: $layout-link-gray;
}
.fa-rss,
.fa-cog {
font-size: 16px;
}
.fa-caret-down {
margin-left: 5px;
color: $gl-icon-color;
}
.dropdown { .dropdown {
margin-left: 7px; margin-left: 7px;
...@@ -202,5 +226,34 @@ ...@@ -202,5 +226,34 @@
.nav-links { .nav-links {
border-bottom: none; border-bottom: none;
height: 51px;
white-space: nowrap;
overflow-x: auto;
li {
a {
padding-top: 10px;
}
a, i {
color: $layout-link-gray;
}
&.active {
a, i {
color: $black;
}
}
.badge {
color: $gl-icon-color;
}
}
} }
}
.page-with-layout-nav {
margin-top: 50px;
} }
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
position: absolute; position: absolute;
width: 58px; width: 58px;
cursor: pointer; cursor: pointer;
margin-top: 8px;
} }
.page-with-sidebar { .page-with-sidebar {
...@@ -62,7 +63,7 @@ ...@@ -62,7 +63,7 @@
float: left; float: left;
height: $header-height; height: $header-height;
width: 100%; width: 100%;
padding: 11px 0 11px 22px; padding-left: 22px;
overflow: hidden; overflow: hidden;
outline: none; outline: none;
transition-duration: .3s; transition-duration: .3s;
...@@ -85,7 +86,7 @@ ...@@ -85,7 +86,7 @@
margin: 0; margin: 0;
margin-left: 50px; margin-left: 50px;
font-size: 19px; font-size: 19px;
line-height: 41px; line-height: 50px;
font-weight: normal; font-weight: normal;
} }
} }
...@@ -254,6 +255,10 @@ ...@@ -254,6 +255,10 @@
} }
} }
} }
.layout-nav {
padding-right: $sidebar_collapsed_width;
}
} }
.page-sidebar-expanded { .page-sidebar-expanded {
...@@ -280,6 +285,10 @@ ...@@ -280,6 +285,10 @@
} }
} }
} }
.layout-nav {
padding-right: $sidebar_width;
}
} }
.right-sidebar-collapsed { .right-sidebar-collapsed {
......
...@@ -66,7 +66,7 @@ $gl-padding-top: 10px; ...@@ -66,7 +66,7 @@ $gl-padding-top: 10px;
$row-hover: #f4f8fe; $row-hover: #f4f8fe;
$progress-color: #c0392b; $progress-color: #c0392b;
$avatar_radius: 50%; $avatar_radius: 50%;
$header-height: 58px; $header-height: 50px;
$fixed-layout-width: 1280px; $fixed-layout-width: 1280px;
$gl-avatar-size: 40px; $gl-avatar-size: 40px;
$error-exclamation-point: #e62958; $error-exclamation-point: #e62958;
...@@ -75,6 +75,8 @@ $btn-transparent-color: #8f8f8f; ...@@ -75,6 +75,8 @@ $btn-transparent-color: #8f8f8f;
$settings-icon-size: 18px; $settings-icon-size: 18px;
$provider-btn-group-border: #e5e5e5; $provider-btn-group-border: #e5e5e5;
$provider-btn-not-active-color: #4688f1; $provider-btn-not-active-color: #4688f1;
$link-underline-blue: #4a8bee;
$layout-link-gray: #7e7c7c;
/* /*
* Color schema * Color schema
...@@ -109,6 +111,7 @@ $red-light: #e52c5a; ...@@ -109,6 +111,7 @@ $red-light: #e52c5a;
$red-normal: #d22852; $red-normal: #d22852;
$red-dark: darken($red-normal, 5%); $red-dark: darken($red-normal, 5%);
$black: #000;
$black-transparent: rgba(0, 0, 0, 0.3); $black-transparent: rgba(0, 0, 0, 0.3);
$border-white-light: #f1f2f4; $border-white-light: #f1f2f4;
......
...@@ -205,3 +205,21 @@ ...@@ -205,3 +205,21 @@
text-align: center; text-align: center;
} }
} }
.user-profile {
@media (max-width: $screen-xs-max) {
.cover-block {
padding-top: 20px;
}
.cover-controls {
position: static;
margin-bottom: 20px;
.btn {
display: inline-block;
width: 48%;
}
}
}
}
...@@ -34,10 +34,13 @@ module NavHelper ...@@ -34,10 +34,13 @@ module NavHelper
end end
def nav_header_class def nav_header_class
class_name =
if nav_menu_collapsed? if nav_menu_collapsed?
"header-collapsed" "header-collapsed"
else else
"header-expanded" "header-expanded"
end end
class_name += " with-horizontal-nav" if defined?(nav) && nav
class_name
end end
end end
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
- page_title "Activity" - page_title "Activity"
- header_title group_title(@group, "Activity", activity_group_path(@group))
%section.activities %section.activities
= render 'activities' = render 'activities'
- header_title group_title(@group, "Settings", edit_group_path(@group))
.panel.panel-default.prepend-top-default .panel.panel-default.prepend-top-default
.panel-heading .panel-heading
Group settings Group settings
......
- page_title "Members" - page_title "Members"
- header_title group_title(@group, "Members", group_group_members_path(@group))
.group-members-page.prepend-top-default .group-members-page.prepend-top-default
- if current_user && current_user.can?(:admin_group_member, @group) - if current_user && current_user.can?(:admin_group_member, @group)
......
- page_title "Issues" - page_title "Issues"
- header_title group_title(@group, "Issues", issues_group_path(@group))
= content_for :meta_tags do = content_for :meta_tags do
- if current_user - if current_user
= auto_discovery_link_tag(:atom, issues_group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} issues") = auto_discovery_link_tag(:atom, issues_group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} issues")
......
- page_title "Merge Requests" - page_title "Merge Requests"
- header_title group_title(@group, "Merge Requests", merge_requests_group_path(@group))
.top-area .top-area
= render 'shared/issuable/nav', type: :merge_requests = render 'shared/issuable/nav', type: :merge_requests
......
- page_title "Milestones" - page_title "Milestones"
- header_title group_title(@group, "Milestones", group_milestones_path(@group))
.top-area .top-area
= render 'shared/milestones_filter' = render 'shared/milestones_filter'
......
- page_title "Projects" - page_title "Projects"
- header_title group_title(@group, "Projects", projects_group_path(@group))
.panel.panel-default.prepend-top-default .panel.panel-default.prepend-top-default
.panel-heading .panel-heading
......
...@@ -4,25 +4,17 @@ ...@@ -4,25 +4,17 @@
- if current_user - if current_user
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
.cover-block .cover-block.groups-cover-block
.cover-controls .container-fluid.container-limited
- if @group && can?(current_user, :admin_group, @group)
= link_to icon('pencil'), edit_group_path(@group), class: 'btn'
- if current_user
= link_to icon('rss'), group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'btn rss-btn'
.avatar-holder
= link_to group_icon(@group), target: '_blank' do = link_to group_icon(@group), target: '_blank' do
= image_tag group_icon(@group), class: "avatar group-avatar s90" = image_tag group_icon(@group), class: "avatar group-avatar s70"
.group-info
.cover-title .cover-title
%h1 %h1
= @group.name @#{@group.path}
%span.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) } %span.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
= visibility_level_icon(@group.visibility_level, fw: false) = visibility_level_icon(@group.visibility_level, fw: false)
.cover-desc.username
@#{@group.path}
- if @group.description.present? - if @group.description.present?
.cover-desc.description .cover-desc.description
= markdown(@group.description, pipeline: :description) = markdown(@group.description, pipeline: :description)
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
.layout-nav .layout-nav
.container-fluid .container-fluid
= render "layouts/nav/#{nav}" = render "layouts/nav/#{nav}"
.content-wrapper .content-wrapper{ class: ('page-with-layout-nav' if defined?(nav) && nav) }
= render "layouts/flash" = render "layouts/flash"
= yield :flash_message = yield :flash_message
%div{ class: (container_class unless @no_container) } %div{ class: (container_class unless @no_container) }
......
- page_title @group.name - page_title @group.name
- page_description @group.description unless page_description - page_description @group.description unless page_description
- header_title group_title(@group) unless header_title - header_title group_title(@group) unless header_title
- sidebar "group" unless sidebar - nav "group"
= render template: "layouts/application" = render template: "layouts/application"
- page_title "Settings" - page_title "Settings"
- header_title group_title(@group, "Settings", edit_group_path(@group)) - nav "group"
- sidebar "group_settings"
= render template: "layouts/group" = render template: "layouts/group"
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
= icon('dashboard fw') = icon('dashboard fw')
%span %span
Activity Activity
= nav_link(controller: :groups) do = nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
= link_to dashboard_groups_path, title: 'Groups' do = link_to dashboard_groups_path, title: 'Groups' do
= icon('group fw') = icon('group fw')
%span %span
Groups Groups
= nav_link(controller: :milestones) do = nav_link(controller: 'dashboard/milestones') do
= link_to dashboard_milestones_path, title: 'Milestones' do = link_to dashboard_milestones_path, title: 'Milestones' do
= icon('clock-o fw') = icon('clock-o fw')
%span %span
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
= icon('bookmark fw') = icon('bookmark fw')
%span %span
Projects Projects
= nav_link(controller: :groups) do = nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
= link_to explore_groups_path, title: 'Groups' do = link_to explore_groups_path, title: 'Groups' do
= icon('group fw') = icon('group fw')
%span %span
......
%ul.nav.nav-sidebar - if current_user
= nav_link do - if access = @group.users.find_by(id: current_user.id)
= link_to root_path, title: 'Go to dashboard', class: 'back-link' do .controls
= icon('caret-square-o-left fw') %span.dropdown.group-settings-dropdown
%span %a.dropdown-new.btn.btn-gray#group-settings-button{href: '#', 'data-toggle' => 'dropdown'}
Go to dashboard = icon('cog')
= icon('caret-down')
%li.separate-item %ul.dropdown-menu.dropdown-menu-align-right
- if can?(current_user, :admin_group, @group)
= nav_link(path: 'groups#projects') do
= link_to projects_group_path(@group), title: 'Projects' do
Projects
%li.divider
%li
= link_to edit_group_path(@group) do
Edit Group
%li
= link_to leave_group_group_members_path(@group),
data: { confirm: leave_group_message(@group.name) }, method: :delete, title: 'Leave group' do
Leave Group
%ul.nav-links
= nav_link(path: 'groups#show', html_options: {class: 'home'}) do = nav_link(path: 'groups#show', html_options: {class: 'home'}) do
= link_to group_path(@group), title: 'Home' do = link_to group_path(@group), title: 'Home' do
= icon('group fw') = icon('group fw')
...@@ -28,22 +41,16 @@ ...@@ -28,22 +41,16 @@
%span %span
Issues Issues
- issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute - issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
%span.count= number_with_delimiter(issues.count) %span.badge.count= number_with_delimiter(issues.count)
= nav_link(path: 'groups#merge_requests') do = nav_link(path: 'groups#merge_requests') do
= link_to merge_requests_group_path(@group), title: 'Merge Requests' do = link_to merge_requests_group_path(@group), title: 'Merge Requests' do
= icon('tasks fw') = icon('tasks fw')
%span %span
Merge Requests Merge Requests
- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened').execute - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened').execute
%span.count= number_with_delimiter(merge_requests.count) %span.badge.count= number_with_delimiter(merge_requests.count)
= nav_link(controller: [:group_members]) do = nav_link(controller: [:group_members]) do
= link_to group_group_members_path(@group), title: 'Members' do = link_to group_group_members_path(@group), title: 'Members' do
= icon('users fw') = icon('users fw')
%span %span
Members Members
- if can?(current_user, :admin_group, @group)
= nav_link(html_options: { class: "separate-item" }) do
= link_to edit_group_path(@group), title: 'Settings' do
= icon ('cogs fw')
%span
Settings
...@@ -7,10 +7,6 @@ Feature: Groups ...@@ -7,10 +7,6 @@ Feature: Groups
When I visit group "NonExistentGroup" page When I visit group "NonExistentGroup" page
Then page status code should be 404 Then page status code should be 404
Scenario: I should have back to group button
When I visit group "Owned" page
Then I should see back to dashboard button
@javascript @javascript
Scenario: I should see group "Owned" dashboard list Scenario: I should see group "Owned" dashboard list
When I visit group "Owned" page When I visit group "Owned" page
......
...@@ -5,8 +5,10 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps ...@@ -5,8 +5,10 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps
include SharedUser include SharedUser
step 'I click on group milestones' do step 'I click on group milestones' do
page.within('.layout-nav') do
click_link 'Milestones' click_link 'Milestones'
end end
end
step 'I should see group milestones index page has no milestones' do step 'I should see group milestones index page has no milestones' do
expect(page).to have_content('No milestones to show') expect(page).to have_content('No milestones to show')
...@@ -84,7 +86,7 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps ...@@ -84,7 +86,7 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps
end end
step 'I click on the "Labels" tab' do step 'I click on the "Labels" tab' do
page.within('.nav-links') do page.within('.content .nav-links') do
page.find(:xpath, "//a[@href='#tab-labels']").click page.find(:xpath, "//a[@href='#tab-labels']").click
end end
end end
......
...@@ -4,10 +4,6 @@ class Spinach::Features::Groups < Spinach::FeatureSteps ...@@ -4,10 +4,6 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
include SharedGroup include SharedGroup
include SharedUser include SharedUser
step 'I should see back to dashboard button' do
expect(page).to have_content 'Go to dashboard'
end
step 'I should see group "Owned"' do step 'I should see group "Owned"' do
expect(page).to have_content '@owned' expect(page).to have_content '@owned'
end end
......
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