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
]
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
%w[
environments
......
......@@ -14,8 +14,10 @@ module SidebarsHelper
end
end
def project_sidebar_context(project, user)
Sidebars::Projects::Context.new(**project_sidebar_context_data(project, user))
def project_sidebar_context(project, user, current_ref)
context_data = project_sidebar_context_data(project, user, current_ref)
Sidebars::Projects::Context.new(**context_data)
end
private
......@@ -32,11 +34,12 @@ module SidebarsHelper
tracking_attrs('user_side_navigation', 'render', 'user_side_navigation')
end
def project_sidebar_context_data(project, user)
def project_sidebar_context_data(project, user, current_ref)
{
current_user: user,
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
# 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
add_menu(Sidebars::Projects::Menus::ProjectOverview::Menu.new(context))
add_menu(Sidebars::Projects::Menus::LearnGitlab::Menu.new(context))
add_menu(Sidebars::Projects::Menus::Repository::Menu.new(context))
end
override :render_raw_menus_partial
......
-# 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.
= 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
= 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
......
......@@ -11,11 +11,6 @@ module EE
]
end
override :sidebar_repository_paths
def sidebar_repository_paths
super + %w(path_locks)
end
override :sidebar_operations_paths
def sidebar_operations_paths
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'
RSpec.describe 'layouts/nav/sidebar/_project' do
let_it_be_with_refind(:project) { create(:project, :repository) }
let(:user) { project.owner }
before do
assign(:project, project)
assign(:repository, project.repository)
allow(view).to receive(:current_ref).and_return('master')
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
it 'has boards tab' do
allow(view).to receive(:can?).and_return(true)
......
......@@ -10,8 +10,8 @@ module QA
def self.prepended(base)
base.class_eval do
view 'ee/app/views/projects/sidebar/_repository_locked_files.html.haml' do
element :path_locks_link
view 'app/views/shared/nav/_sidebar_menu_item.html.haml' do
element :sidebar_menu_item_link
end
end
end
......@@ -19,7 +19,7 @@ module QA
def go_to_repository_locked_files
hover_repository do
within_submenu do
click_element :path_locks_link
click_element(:sidebar_menu_item_link, menu_item: 'Locked Files')
end
end
end
......
......@@ -13,24 +13,26 @@ module QA
base.class_eval do
include QA::Page::Project::SubMenus::Common
view 'app/views/layouts/nav/sidebar/_project_menus.html.haml' do
element :repository_link
element :branches_link
element :tags_link
view 'app/views/shared/nav/_sidebar_menu_item.html.haml' do
element :sidebar_menu_item_link
end
view 'app/views/shared/nav/_sidebar_menu.html.haml' do
element :sidebar_menu_link
end
end
end
def click_repository
within_sidebar do
click_element(:repository_link)
click_element(:sidebar_menu_link, menu_item: 'Repository')
end
end
def go_to_repository_branches
hover_repository do
within_submenu do
click_element(:branches_link)
click_element(:sidebar_menu_item_link, menu_item: 'Branches')
end
end
end
......@@ -38,7 +40,7 @@ module QA
def go_to_repository_tags
hover_repository do
within_submenu do
click_element(:tags_link)
click_element(:sidebar_menu_item_link, menu_item: 'Tags')
end
end
end
......@@ -47,7 +49,7 @@ module QA
def hover_repository
within_sidebar do
find_element(:repository_link).hover
find_element(:sidebar_menu_link, menu_item: 'Repository').hover
yield
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
let_it_be_with_reload(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:current_ref) { 'master' }
before do
assign(:project, project)
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(:current_user).and_return(user)
end
......@@ -60,6 +61,70 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
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
it 'has board tab' do
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