Commit bbb8e102 authored by Mark Florian's avatar Mark Florian

Merge branch 'mrincon-tabs-haml-helper' into 'master'

Add tabs_nav helper to render gl-tab component

See merge request gitlab-org/gitlab!70919
parents 8896ceeb 127a3e01
# frozen_string_literal: true # frozen_string_literal: true
module TabHelper module TabHelper
# Navigation tabs helper
# Create a <gl-tabs> container
#
# Returns a `ul` element with classes that correspond to
# the <gl-tabs/> component. Can be populated by
# gl_tab_link_to elements.
#
# See more at: https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-tabs-tab--default
def gl_tabs_nav(html_options = {}, &block)
gl_tabs_classes = %w[nav gl-tabs-nav]
html_options = html_options.merge(
class: [*html_options[:class], gl_tabs_classes].join(' '),
role: 'tablist'
)
content = capture(&block) if block_given?
content_tag(:ul, content, html_options)
end
# Create a <gl-tab> link
#
# When a tab is active it gets highlighted to indicate this is currently viewed tab.
# Internally `current_page?` is called to determine if this is the current tab.
#
# Usage is the same as "link_to", with the following additional options:
#
# html_options - The html_options hash (default: {})
# :item_active - Overrides the default state focing the "active" css classes (optional).
#
def gl_tab_link_to(name = nil, options = {}, html_options = {}, &block)
tab_class = 'nav-item'
link_classes = %w[nav-link gl-tab-nav-item]
active_link_classes = %w[active gl-tab-nav-item-active gl-tab-nav-item-active-indigo]
if block_given?
# Shift params to skip the omitted "name" param
html_options = options
options = name
end
html_options = html_options.merge(
class: [*html_options[:class], link_classes].join(' ')
)
if gl_tab_link_to_active?(options, html_options)
html_options[:class] = [*html_options[:class], active_link_classes].join(' ')
end
html_options = html_options.except(:item_active)
content_tag(:li, class: tab_class, role: 'presentation') do
if block_given?
link_to(options, html_options, &block)
else
link_to(name, options, html_options)
end
end
end
# Navigation link helper # Navigation link helper
# #
# Returns an `li` element with an 'active' class if the supplied # Returns an `li` element with an 'active' class if the supplied
...@@ -148,4 +209,12 @@ module TabHelper ...@@ -148,4 +209,12 @@ module TabHelper
current_controller?(*controller) || current_action?(*action) current_controller?(*controller) || current_action?(*action)
end end
end end
def gl_tab_link_to_active?(options, html_options)
if html_options.has_key?(:item_active)
return html_options[:item_active]
end
current_page?(options)
end
end end
- page_title _('Projects') - page_title _('Projects')
- params[:visibility_level] ||= [] - params[:visibility_level] ||= []
- active_tab_classes = 'active gl-tab-nav-item-active gl-tab-nav-item-active-indigo'
.top-area.scrolling-tabs-container.inner-page-scroll-tabs .top-area.scrolling-tabs-container.inner-page-scroll-tabs
%ul.nav.gl-tabs-nav.gl-overflow-x-auto.gl-display-flex.gl-flex-grow-1.gl-flex-shrink-1.gl-border-b-0.gl-flex-nowrap.gl-webkit-scrollbar-display-none = gl_tabs_nav({ class: 'gl-border-b-0 gl-overflow-x-auto gl-flex-grow-1 gl-flex-nowrap gl-webkit-scrollbar-display-none' }) do
= nav_link(html_options: { class: "nav-item" } ) do = gl_tab_link_to _('All'), admin_projects_path(visibility_level: nil), { item_active: params[:visibility_level].empty? }
= link_to _('All'), admin_projects_path, class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level].empty?}" = gl_tab_link_to _('Private'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
= nav_link(html_options: { class: "nav-item" } ) do = gl_tab_link_to _('Internal'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
= link_to _('Private'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::PRIVATE.to_s}" = gl_tab_link_to _('Public'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
= nav_link(html_options: { class: "nav-item" } ) do
= link_to _('Internal'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::INTERNAL.to_s}"
= nav_link(html_options: { class: "nav-item" } ) do
= link_to _('Public'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::PUBLIC.to_s}"
.nav-controls .nav-controls
.search-holder .search-holder
......
...@@ -33,16 +33,11 @@ ...@@ -33,16 +33,11 @@
- if can_force_email_confirmation?(@user) - if can_force_email_confirmation?(@user)
%button.btn.gl-button.btn-info.js-confirm-modal-button{ data: confirm_user_data(@user) } %button.btn.gl-button.btn-info.js-confirm-modal-button{ data: confirm_user_data(@user) }
= _('Confirm user') = _('Confirm user')
%ul.nav-links.nav.nav-tabs = gl_tabs_nav do
= nav_link(path: 'users#show') do = gl_tab_link_to _("Account"), admin_user_path(@user)
= link_to _("Account"), admin_user_path(@user) = gl_tab_link_to _("Groups and projects"), projects_admin_user_path(@user)
= nav_link(path: 'users#projects') do = gl_tab_link_to _("SSH keys"), keys_admin_user_path(@user)
= link_to _("Groups and projects"), projects_admin_user_path(@user) = gl_tab_link_to _("Identities"), admin_user_identities_path(@user)
= nav_link(path: 'users#keys') do
= link_to _("SSH keys"), keys_admin_user_path(@user)
= nav_link(controller: :identities) do
= link_to _("Identities"), admin_user_identities_path(@user)
- if impersonation_enabled? - if impersonation_enabled?
= nav_link(controller: :impersonation_tokens) do = gl_tab_link_to _("Impersonation Tokens"), admin_user_impersonation_tokens_path(@user)
= link_to _("Impersonation Tokens"), admin_user_impersonation_tokens_path(@user)
.gl-mb-3 .gl-mb-3
...@@ -5,6 +5,60 @@ require 'spec_helper' ...@@ -5,6 +5,60 @@ require 'spec_helper'
RSpec.describe TabHelper do RSpec.describe TabHelper do
include ApplicationHelper include ApplicationHelper
describe 'gl_tabs_nav' do
it 'creates a tabs navigation' do
expect(gl_tabs_nav).to match(%r{<ul class=".*" role="tablist"><\/ul>})
end
it 'captures block output' do
expect(gl_tabs_nav { "block content" }).to match(/block content/)
end
it 'adds styles classes' do
expect(gl_tabs_nav).to match(/class="nav gl-tabs-nav"/)
end
it 'adds custom class' do
expect(gl_tabs_nav(class: 'my-class' )).to match(/class=".*my-class.*"/)
end
end
describe 'gl_tab_link_to' do
before do
allow(self).to receive(:current_page?).and_return(false)
end
it 'creates a tab' do
expect(gl_tab_link_to('Link', '/url')).to eq('<li class="nav-item" role="presentation"><a class="nav-link gl-tab-nav-item" href="/url">Link</a></li>')
end
it 'creates a tab with block output' do
expect(gl_tab_link_to('/url') { 'block content' }).to match(/block content/)
end
it 'creates a tab with custom classes' do
expect(gl_tab_link_to('Link', '/url', { class: 'my-class' })).to match(/<a class=".*my-class.*"/)
end
it 'creates an active tab with item_active = true' do
expect(gl_tab_link_to('Link', '/url', { item_active: true })).to match(/<a class=".*active gl-tab-nav-item-active gl-tab-nav-item-active-indigo.*"/)
end
context 'when on the active page' do
before do
allow(self).to receive(:current_page?).and_return(true)
end
it 'creates an active tab' do
expect(gl_tab_link_to('Link', '/url')).to match(/<a class=".*active gl-tab-nav-item-active gl-tab-nav-item-active-indigo.*"/)
end
it 'creates an inactive tab with item_active = false' do
expect(gl_tab_link_to('Link', '/url', { item_active: false })).not_to match(/<a class=".*active.*"/)
end
end
end
describe 'nav_link' do describe 'nav_link' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
......
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