Commit 8ff7d298 authored by Denys Mishunov's avatar Denys Mishunov

Merge branch '326427-fj-add-repository-menu' into 'master'

Add `Repository` menu to project sidebar refactor

See merge request gitlab-org/gitlab!59111
parents 13a4a9d9 b9c8745b
...@@ -746,25 +746,6 @@ module ProjectsHelper ...@@ -746,25 +746,6 @@ module ProjectsHelper
] ]
end end
def sidebar_repository_paths
%w[
tree
blob
blame
edit_tree
new_tree
find_file
commit
commits
compare
projects/repositories
tags
branches
graphs
network
]
end
def sidebar_operations_paths def sidebar_operations_paths
%w[ %w[
environments environments
......
...@@ -14,8 +14,10 @@ module SidebarsHelper ...@@ -14,8 +14,10 @@ module SidebarsHelper
end end
end end
def project_sidebar_context(project, user) def project_sidebar_context(project, user, current_ref)
Sidebars::Projects::Context.new(**project_sidebar_context_data(project, user)) context_data = project_sidebar_context_data(project, user, current_ref)
Sidebars::Projects::Context.new(**context_data)
end end
private private
...@@ -32,11 +34,12 @@ module SidebarsHelper ...@@ -32,11 +34,12 @@ module SidebarsHelper
tracking_attrs('user_side_navigation', 'render', 'user_side_navigation') tracking_attrs('user_side_navigation', 'render', 'user_side_navigation')
end end
def project_sidebar_context_data(project, user) def project_sidebar_context_data(project, user, current_ref)
{ {
current_user: user, current_user: user,
container: project, container: project,
learn_gitlab_experiment_enabled: learn_gitlab_experiment_enabled?(project) learn_gitlab_experiment_enabled: learn_gitlab_experiment_enabled?(project),
current_ref: current_ref
} }
end end
end end
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
class Menu < ::Sidebars::Menu
override :configure_menu_items
def configure_menu_items
add_item(MenuItems::Files.new(context))
add_item(MenuItems::Commits.new(context))
add_item(MenuItems::Branches.new(context))
add_item(MenuItems::Tags.new(context))
add_item(MenuItems::Contributors.new(context))
add_item(MenuItems::Graphs.new(context))
add_item(MenuItems::Compare.new(context))
end
override :link
def link
project_tree_path(context.project)
end
override :extra_container_html_options
def extra_container_html_options
{
class: 'shortcuts-tree'
}
end
override :title
def title
_('Repository')
end
override :title_html_options
def title_html_options
{
id: 'js-onboarding-repo-link'
}
end
override :sprite_icon
def sprite_icon
'doc-text'
end
override :render?
def render?
can?(context.current_user, :download_code, context.project) &&
!context.project.empty_repo?
end
end
end
end
end
end
Sidebars::Projects::Menus::Repository::Menu.prepend_if_ee('EE::Sidebars::Projects::Menus::Repository::Menu')
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
module MenuItems
class Branches < ::Sidebars::MenuItem
override :link
def link
project_branches_path(context.project)
end
override :extra_container_html_options
def extra_container_html_options
{
id: 'js-onboarding-branches-link'
}
end
override :active_routes
def active_routes
{ controller: :branches }
end
override :title
def title
_('Branches')
end
end
end
end
end
end
end
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
module MenuItems
class Commits < ::Sidebars::MenuItem
override :link
def link
project_commits_path(context.project, context.current_ref)
end
override :extra_container_html_options
def extra_container_html_options
{
id: 'js-onboarding-commits-link'
}
end
override :active_routes
def active_routes
{ controller: %w(commit commits) }
end
override :title
def title
_('Commits')
end
end
end
end
end
end
end
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
module MenuItems
class Compare < ::Sidebars::MenuItem
override :link
def link
project_compare_index_path(context.project, from: context.project.repository.root_ref, to: context.current_ref)
end
override :active_routes
def active_routes
{ controller: :compare }
end
override :title
def title
_('Compare')
end
end
end
end
end
end
end
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
module MenuItems
class Contributors < ::Sidebars::MenuItem
override :link
def link
project_graph_path(context.project, context.current_ref)
end
override :active_routes
def active_routes
{ path: 'graphs#show' }
end
override :title
def title
_('Contributors')
end
end
end
end
end
end
end
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
module MenuItems
class Files < ::Sidebars::MenuItem
override :link
def link
project_tree_path(context.project, context.current_ref)
end
override :active_routes
def active_routes
{ controller: %w[tree blob blame edit_tree new_tree find_file] }
end
override :title
def title
_('Files')
end
end
end
end
end
end
end
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
module MenuItems
class Graphs < ::Sidebars::MenuItem
override :link
def link
project_network_path(context.project, context.current_ref)
end
override :active_routes
def active_routes
{ controller: :network }
end
override :title
def title
_('Graph')
end
end
end
end
end
end
end
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
module MenuItems
class Tags < ::Sidebars::MenuItem
override :link
def link
project_tags_path(context.project)
end
override :active_routes
def active_routes
{ controller: :tags }
end
override :title
def title
_('Tags')
end
end
end
end
end
end
end
...@@ -9,6 +9,7 @@ module Sidebars ...@@ -9,6 +9,7 @@ module Sidebars
add_menu(Sidebars::Projects::Menus::ProjectOverview::Menu.new(context)) add_menu(Sidebars::Projects::Menus::ProjectOverview::Menu.new(context))
add_menu(Sidebars::Projects::Menus::LearnGitlab::Menu.new(context)) add_menu(Sidebars::Projects::Menus::LearnGitlab::Menu.new(context))
add_menu(Sidebars::Projects::Menus::Repository::Menu.new(context))
end end
override :render_raw_menus_partial override :render_raw_menus_partial
......
-# We're migration the project sidebar to a logical model based structure. If you need to update -# We're migration the project sidebar to a logical model based structure. If you need to update
-# any of the existing menus, you can find them in app/views/layouts/nav/sidebar/_project_menus.html.haml. -# any of the existing menus, you can find them in app/views/layouts/nav/sidebar/_project_menus.html.haml.
= render partial: 'shared/nav/sidebar', object: Sidebars::Projects::Panel.new(project_sidebar_context(@project, current_user)) = render partial: 'shared/nav/sidebar', object: Sidebars::Projects::Panel.new(project_sidebar_context(@project, current_user, current_ref))
- if project_nav_tab? :files
= nav_link(controller: sidebar_repository_paths, unless: -> { current_path?('projects/graphs#charts') }) do
= link_to project_tree_path(@project), class: 'shortcuts-tree', data: { qa_selector: "repository_link" } do
.nav-icon-container
= sprite_icon('doc-text')
%span.nav-item-name#js-onboarding-repo-link
= _('Repository')
%ul.sidebar-sub-level-items
= nav_link(controller: sidebar_repository_paths, html_options: { class: "fly-out-top-item" } ) do
= link_to project_tree_path(@project) do
%strong.fly-out-top-item-name
= _('Repository')
%li.divider.fly-out-top-item
= nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
= link_to project_tree_path(@project) do
= _('Files')
= nav_link(controller: [:commit, :commits]) do
= link_to project_commits_path(@project, current_ref), id: 'js-onboarding-commits-link' do
= _('Commits')
= nav_link(html_options: {class: branches_tab_class}) do
= link_to project_branches_path(@project), data: { qa_selector: "branches_link" }, id: 'js-onboarding-branches-link' do
= _('Branches')
= nav_link(controller: [:tags]) do
= link_to project_tags_path(@project), data: { qa_selector: "tags_link" } do
= _('Tags')
= nav_link(path: 'graphs#show') do
= link_to project_graph_path(@project, current_ref) do
= _('Contributors')
= nav_link(controller: %w(network)) do
= link_to project_network_path(@project, current_ref) do
= _('Graph')
= nav_link(controller: :compare) do
= link_to project_compare_index_path(@project, from: @repository.root_ref, to: current_ref) do
= _('Compare')
= render_if_exists 'projects/sidebar/repository_locked_files'
- if project_nav_tab? :issues - if project_nav_tab? :issues
= nav_link(controller: @project.issues_enabled? ? ['projects/issues', :labels, :milestones, :boards, :iterations] : 'projects/issues') do = nav_link(controller: @project.issues_enabled? ? ['projects/issues', :labels, :milestones, :boards, :iterations] : 'projects/issues') do
= link_to project_issues_path(@project), class: 'shortcuts-issues qa-issues-item' do = link_to project_issues_path(@project), class: 'shortcuts-issues qa-issues-item' do
......
...@@ -11,11 +11,6 @@ module EE ...@@ -11,11 +11,6 @@ module EE
] ]
end end
override :sidebar_repository_paths
def sidebar_repository_paths
super + %w(path_locks)
end
override :sidebar_operations_paths override :sidebar_operations_paths
def sidebar_operations_paths def sidebar_operations_paths
super + %w[ super + %w[
......
# frozen_string_literal: true
module EE
module Sidebars
module Projects
module Menus
module Repository
module Menu
extend ::Gitlab::Utils::Override
override :configure_menu_items
def configure_menu_items
super
add_item(::Sidebars::Projects::Menus::Repository::MenuItems::FileLocks.new(context))
end
end
end
end
end
end
end
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
module Repository
module MenuItems
class FileLocks < ::Sidebars::MenuItem
override :link
def link
project_path_locks_path(context.project)
end
override :extra_container_html_options
def extra_container_html_options
{
data: { qa_selector: 'path_locks_link' }
}
end
override :active_routes
def active_routes
{ controller: :path_locks }
end
override :title
def title
_('Locked Files')
end
override :render?
def render?
context.project.licensed_feature_available?(:file_locks)
end
end
end
end
end
end
end
- return unless @project.feature_available?(:file_locks)
= nav_link(controller: [:path_locks]) do
= link_to project_path_locks_path(@project), data: { qa_selector: 'path_locks_link' } do
= _('Locked Files')
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Sidebars::Projects::Menus::Repository::MenuItems::FileLocks do
let(:project) { build(:project) }
let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project) }
subject { described_class.new(context) }
describe '#render?' do
before do
stub_licensed_features(file_locks: license_feature_status)
end
context 'when project has the licensed feature' do
let(:license_feature_status) { true }
it 'returns true' do
expect(subject.render?).to eq true
end
end
context 'when project does not have the licensed feature' do
let(:license_feature_status) { false }
it 'returns false' do
expect(subject.render?).to eq false
end
end
end
end
...@@ -5,12 +5,27 @@ require 'spec_helper' ...@@ -5,12 +5,27 @@ require 'spec_helper'
RSpec.describe 'layouts/nav/sidebar/_project' do RSpec.describe 'layouts/nav/sidebar/_project' do
let_it_be_with_refind(:project) { create(:project, :repository) } let_it_be_with_refind(:project) { create(:project, :repository) }
let(:user) { project.owner }
before do before do
assign(:project, project) assign(:project, project)
assign(:repository, project.repository) assign(:repository, project.repository)
allow(view).to receive(:current_ref).and_return('master') allow(view).to receive(:current_ref).and_return('master')
end end
describe 'Repository' do
describe 'Files' do
it 'has a link to the project file locks path' do
allow(view).to receive(:current_user).and_return(user)
render
expect(rendered).to have_link('Locked Files', href: project_path_locks_path(project))
end
end
end
describe 'issue boards' do describe 'issue boards' do
it 'has boards tab' do it 'has boards tab' do
allow(view).to receive(:can?).and_return(true) allow(view).to receive(:can?).and_return(true)
......
...@@ -10,8 +10,8 @@ module QA ...@@ -10,8 +10,8 @@ module QA
def self.prepended(base) def self.prepended(base)
base.class_eval do base.class_eval do
view 'ee/app/views/projects/sidebar/_repository_locked_files.html.haml' do view 'app/views/shared/nav/_sidebar_menu_item.html.haml' do
element :path_locks_link element :sidebar_menu_item_link
end end
end end
end end
...@@ -19,7 +19,7 @@ module QA ...@@ -19,7 +19,7 @@ module QA
def go_to_repository_locked_files def go_to_repository_locked_files
hover_repository do hover_repository do
within_submenu do within_submenu do
click_element :path_locks_link click_element(:sidebar_menu_item_link, menu_item: 'Locked Files')
end end
end end
end end
......
...@@ -13,24 +13,26 @@ module QA ...@@ -13,24 +13,26 @@ module QA
base.class_eval do base.class_eval do
include QA::Page::Project::SubMenus::Common include QA::Page::Project::SubMenus::Common
view 'app/views/layouts/nav/sidebar/_project_menus.html.haml' do view 'app/views/shared/nav/_sidebar_menu_item.html.haml' do
element :repository_link element :sidebar_menu_item_link
element :branches_link end
element :tags_link
view 'app/views/shared/nav/_sidebar_menu.html.haml' do
element :sidebar_menu_link
end end
end end
end end
def click_repository def click_repository
within_sidebar do within_sidebar do
click_element(:repository_link) click_element(:sidebar_menu_link, menu_item: 'Repository')
end end
end end
def go_to_repository_branches def go_to_repository_branches
hover_repository do hover_repository do
within_submenu do within_submenu do
click_element(:branches_link) click_element(:sidebar_menu_item_link, menu_item: 'Branches')
end end
end end
end end
...@@ -38,7 +40,7 @@ module QA ...@@ -38,7 +40,7 @@ module QA
def go_to_repository_tags def go_to_repository_tags
hover_repository do hover_repository do
within_submenu do within_submenu do
click_element(:tags_link) click_element(:sidebar_menu_item_link, menu_item: 'Tags')
end end
end end
end end
...@@ -47,7 +49,7 @@ module QA ...@@ -47,7 +49,7 @@ module QA
def hover_repository def hover_repository
within_sidebar do within_sidebar do
find_element(:repository_link).hover find_element(:sidebar_menu_link, menu_item: 'Repository').hover
yield yield
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Sidebars::Projects::Menus::Repository::Menu do
let_it_be(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
subject { described_class.new(context) }
describe '#render?' do
context 'when project repository is empty' do
it 'returns false' do
allow(project).to receive(:empty_repo?).and_return(true)
expect(subject.render?).to eq false
end
end
context 'when project repository is not empty' do
context 'when user can download code' do
it 'returns true' do
expect(subject.render?).to eq true
end
end
context 'when user cannot download code' do
let(:user) { nil }
it 'returns false' do
expect(subject.render?).to eq false
end
end
end
end
end
...@@ -6,12 +6,13 @@ RSpec.describe 'layouts/nav/sidebar/_project' do ...@@ -6,12 +6,13 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
let_it_be_with_reload(:project) { create(:project, :repository) } let_it_be_with_reload(:project) { create(:project, :repository) }
let(:user) { project.owner } let(:user) { project.owner }
let(:current_ref) { 'master' }
before do before do
assign(:project, project) assign(:project, project)
assign(:repository, project.repository) assign(:repository, project.repository)
allow(view).to receive(:current_ref).and_return('master') allow(view).to receive(:current_ref).and_return(current_ref)
allow(view).to receive(:can?).and_return(true) allow(view).to receive(:can?).and_return(true)
allow(view).to receive(:current_user).and_return(user) allow(view).to receive(:current_user).and_return(user)
end end
...@@ -60,6 +61,70 @@ RSpec.describe 'layouts/nav/sidebar/_project' do ...@@ -60,6 +61,70 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end end
end end
describe 'Repository' do
it 'has a link to the project tree path' do
render
expect(rendered).to have_link('Repository', href: project_tree_path(project, current_ref), class: 'shortcuts-tree')
end
describe 'Files' do
it 'has a link to the project tree path' do
render
expect(rendered).to have_link('Files', href: project_tree_path(project, current_ref))
end
end
describe 'Commits' do
it 'has a link to the project commits path' do
render
expect(rendered).to have_link('Commits', href: project_commits_path(project, current_ref), id: 'js-onboarding-commits-link')
end
end
describe 'Branches' do
it 'has a link to the project branches path' do
render
expect(rendered).to have_link('Branches', href: project_branches_path(project), id: 'js-onboarding-branches-link')
end
end
describe 'Tags' do
it 'has a link to the project tags path' do
render
expect(rendered).to have_link('Tags', href: project_tags_path(project))
end
end
describe 'Contributors' do
it 'has a link to the project contributors path' do
render
expect(rendered).to have_link('Contributors', href: project_graph_path(project, current_ref))
end
end
describe 'Graph' do
it 'has a link to the project graph path' do
render
expect(rendered).to have_link('Graph', href: project_network_path(project, current_ref))
end
end
describe 'Compare' do
it 'has a link to the project compare path' do
render
expect(rendered).to have_link('Compare', href: project_compare_index_path(project, from: project.repository.root_ref, to: current_ref))
end
end
end
describe 'issue boards' do describe 'issue boards' do
it 'has board tab' do it 'has board tab' do
render render
......
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