Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-docs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasilii Iakliushin <viakliushin@gitlab.com>2020-11-13 16:24:32 +0300
committerVasilii Iakliushin <viakliushin@gitlab.com>2020-11-13 16:24:32 +0300
commited69ecf57f1d72d06954b7d756bf6a5a06508414 (patch)
tree50cce819689cec9868f2ef7f4957329b9bb7a37f
parent66258e352ba22ce28b39d2da15982e14a8c6b733 (diff)
parentcc8137e80c00b4dc3584a73b8e17d48e06e687e0 (diff)
Merge branch '879_refactor_global_navigation' into omnibus_mash
-rw-r--r--layouts/global_nav.html71
-rw-r--r--lib/gitlab/navigation.rb58
-rw-r--r--lib/gitlab/navigation/category.rb41
-rw-r--r--lib/gitlab/navigation/doc.rb37
-rw-r--r--lib/gitlab/navigation/section.rb37
-rw-r--r--spec/gitlab/navigation/category_spec.rb81
-rw-r--r--spec/gitlab/navigation/doc_spec.rb56
-rw-r--r--spec/gitlab/navigation/section_spec.rb73
-rw-r--r--spec/gitlab/navigation_spec.rb86
9 files changed, 497 insertions, 43 deletions
diff --git a/layouts/global_nav.html b/layouts/global_nav.html
index 334f4d85..1bf3795a 100644
--- a/layouts/global_nav.html
+++ b/layouts/global_nav.html
@@ -1,62 +1,47 @@
-<%
-dir = @item.identifier.to_s[%r{(?<=/)[^/]+}]
-nav_items_dir = "/_data/#{dir}-nav.yaml"
-nav_items_exists = !@items[nav_items_dir].nil?
-is_ee_prefixed = !nav_items_exists && dir != 'ce'
-nav_items = nav_items_exists ? @items[nav_items_dir] : @items["/_data/default-nav.yaml"]
-%>
+<% navigation = Gitlab::Navigation.new(@items, @item) %>
<nav class="global-nav-content">
<!-- nav sections -->
- <% nav_items[:sections].each do |sec| %>
+ <% navigation.children.each do |sec| %>
<div class="global-nav-section">
<span class="global-nav-block-top nav-link">
- <% section_href = is_ee_prefixed ? "/ee/#{sec[:section_url]}" : "/#{dir}/#{sec[:section_url]}" %>
- <a class="global-nav-link level-0 <% if sec[:section_categories] %>has-collapse<% end %> <% if @item.path == "/#{dir}/#{sec[:section_url]}" %>active<% end %>" href="<%= section_href %>">
- <%= sec[:section_title] %>
- <% if sec[:ee_only] %>
- <span class="badges-drop global-nav-badges" data-toggle="tooltip" data-placement="top" title="Available in <%= sec[:ee_tier] %>"><i class="fa fa-info-circle" aria-hidden="true"></i></span>
- <% end %><!-- end of if sec[:ee_only] -->
+ <a class="global-nav-link level-0 <%= sec.has_children? ? 'has-collapse' : '' %> <%= navigation.show_element?(sec) ? 'active' : '' %>" href="<%= navigation.element_href(sec) %>">
+ <%= sec.title %>
+ <%= navigation.optional_ee_badge(sec) %>
</a>
- <div class="section-title <% if sec[:section_categories] %>collapse-toggle<% end %> <% if @item.path == "/#{dir}/#{sec[:section_url]}" %>active<% else %>collapsed<% end %>" data-toggle="collapse" aria-expanded="false" data-target="#<%= sec[:section_title].gsub(/[\s\/\(\)]/, '') %>"></div>
+ <div class="section-title <%= sec.has_children? ? 'collapse-toggle': '' %> <%= navigation.show_element?(sec) ? 'active' : 'collapsed' %>" data-toggle="collapse" aria-expanded="false" data-target="#<%= navigation.id_for(sec) %>"></div>
</span>
<!-- nav categories -->
- <% if sec[:section_categories] %>
- <div class="collapse <% if @item.path == "/#{dir}/#{sec[:section_url]}" %>show<% end %>" id="<%= sec[:section_title].gsub(/[\s\/\(\)]/, '') %>">
- <% sec[:section_categories].each do |cat| %>
- <span class="global-nav-cat nav-link">
- <% if cat[:external_url] %>
- <a class="global-nav-link level-1 <% if cat[:docs] %>has-collapse<% end %>" href="<%= cat[:category_url] %>" target="_blank">
- <%= cat[:category_title] %>
- </a>
- <% else %>
- <% category_href = is_ee_prefixed ? "/ee/#{cat[:category_url]}" : "/#{dir}/#{cat[:category_url]}" %>
- <a class="global-nav-link level-1 <% if cat[:docs] %>has-collapse<% end %> <% if @item.path == "/#{dir}/#{cat[:category_url]}" %>active<% end %>" href="<%= category_href %>">
- <%= cat[:category_title] %>
- <% if cat[:ee_only] %>
- <span class="badges-drop global-nav-badges" data-toggle="tooltip" data-placement="top" title="Available in <%= cat[:ee_tier] %>"><i class="fa fa-info-circle" aria-hidden="true"></i></span>
- <% end %><!-- end of if cat[:ee_only] -->
+ <% if sec.has_children? %>
+ <div class="collapse <%= navigation.show_element?(sec) ? 'show' : '' %>" id="<%= navigation.id_for(sec) %>">
+ <% sec.children.each do |cat| %>
+ <span class="global-nav-cat nav-link">
+ <% if cat.external_url %>
+ <a class="global-nav-link level-1 <%= cat.has_children? ? 'has-collapse' : '' %>" href="<%= cat.url %>" target="_blank">
+ <%= cat.title %>
+ </a>
+ <% else %>
+ <a class="global-nav-link level-1 <%= cat.has_children? ? 'has-collapse' : '' %> <%= navigation.show_element?(cat) ? 'active' : '' %>" href="<%= navigation.element_href(cat) %>">
+ <%= cat.title %>
+ <%= navigation.optional_ee_badge(cat) %>
</a>
<% end %><!-- end of if cat[:external_url] -->
- <div class="<% if cat[:docs] %>collapse-toggle<% end %> <% if @item.path == "/#{dir}/#{cat[:category_url]}" %>active<% else %>collapsed<% end %>" data-toggle="collapse" aria-expanded="false" data-target="#<%= cat[:category_title].gsub(/[\s\/\(\)]/, '') %>"></div>
+ <div class="<%= cat.has_children? ? 'collapse-toggle' : '' %> <%= navigation.show_element?(cat) ? 'active' : 'collapsed' %>" data-toggle="collapse" aria-expanded="false" data-target="#<%= navigation.id_for(cat) %>"></div>
</span>
<!-- nav docs -->
- <% if cat[:docs] %>
- <div class="collapse <% if @item.path == "/#{dir}/#{cat[:category_url]}" %>show<% end %>" id="<%= cat[:category_title].gsub(/[\s\/\(\)]/, '') %>">
- <% cat[:docs].each do |doc| %>
+ <% if cat.has_children? %>
+ <div class="collapse <%= navigation.show_element?(cat) ? 'show' : '' %>" id="<%= navigation.id_for(cat) %>">
+ <% cat.children.each do |doc| %>
<span class="nav-link">
- <% if doc[:external_url] %>
- <a class="global-nav-link level-2" href="<%= doc[:doc_url] %>" target="_blank">
- <%= doc[:doc_title] %>
+ <% if doc.external_url %>
+ <a class="global-nav-link level-2" href="<%= doc.url %>" target="_blank">
+ <%= doc.title %>
</a>
<% else%>
- <% docs_href = is_ee_prefixed ? "/ee/#{doc[:doc_url]}" : "/#{dir}/#{doc[:doc_url]}" %>
- <a class="global-nav-link level-2 <% if @item.path == "/#{dir}/#{doc[:doc_url]}" %>active<% end %>" href="<%= docs_href %>">
- <%= doc[:doc_title] %>
- <% if doc[:ee_only] %>
- <span class="badges-drop global-nav-badges" data-toggle="tooltip" data-placement="top" title="Available in <%= doc[:ee_tier] %>"><i class="fa fa-info-circle" aria-hidden="true"></i></span>
- <% end %><!-- end if doc[:ee_only] -->
+ <a class="global-nav-link level-2 <%= navigation.show_element?(doc) ? 'active' : '' %>" href="<%= navigation.element_href(doc) %>">
+ <%= doc.title %>
+ <%= navigation.optional_ee_badge(doc) %>
</a>
<% end %><!-- end of if doc[:external_url] -->
</span>
diff --git a/lib/gitlab/navigation.rb b/lib/gitlab/navigation.rb
new file mode 100644
index 00000000..022654e0
--- /dev/null
+++ b/lib/gitlab/navigation.rb
@@ -0,0 +1,58 @@
+module Gitlab
+ class Navigation
+ def initialize(items, item)
+ @items = items
+ @item = item
+ end
+
+ def nav_items
+ @nav_items ||= nav_items_exists ? items[nav_items_dir] : items["/_data/default-nav.yaml"]
+ end
+
+ def element_href(element)
+ is_ee_prefixed ? "/ee/#{element.url}" : "/#{dir}/#{element.url}"
+ end
+
+ def show_element?(element)
+ item.path == "/#{dir}/#{element.url}"
+ end
+
+ def id_for(element)
+ element.title.gsub(/[\s\/\(\)]/, '')
+ end
+
+ def optional_ee_badge(element)
+ return unless element.ee_only?
+
+ %[<span class="badges-drop global-nav-badges" data-toggle="tooltip" data-placement="top" title="Available in #{element.ee_tier}"><i class="fa fa-info-circle" aria-hidden="true"></i></span>]
+ end
+
+ def children
+ @children ||= nav_items.fetch(:sections, []).map { |section| Section.new(section) }
+ end
+
+ private
+
+ attr_reader :items, :item
+
+ def dir
+ @dir ||= item.identifier.to_s[%r{(?<=/)[^/]+}]
+ end
+
+ def nav_items_dir
+ @nav_items_dir ||= "/_data/#{dir}-nav.yaml"
+ end
+
+ def nav_items_exists
+ !items[nav_items_dir].nil?
+ end
+
+ def is_ee_prefixed
+ !nav_items_exists && dir != 'ce'
+ end
+
+ def is_omnibus?
+ ENV['NANOC_ENV'] == 'omnibus'
+ end
+ end
+end
diff --git a/lib/gitlab/navigation/category.rb b/lib/gitlab/navigation/category.rb
new file mode 100644
index 00000000..75f401fa
--- /dev/null
+++ b/lib/gitlab/navigation/category.rb
@@ -0,0 +1,41 @@
+module Gitlab
+ class Navigation
+ class Category
+ def initialize(category)
+ @category = category
+ end
+
+ def title
+ category[:category_title]
+ end
+
+ def external_url
+ category[:external_url]
+ end
+
+ def url
+ category[:category_url]
+ end
+
+ def ee_only?
+ category[:ee_only]
+ end
+
+ def ee_tier
+ category[:ee_tier]
+ end
+
+ def has_children?
+ !children.empty?
+ end
+
+ def children
+ @children ||= category.fetch(:docs, []).map { |doc| Doc.new(doc) }
+ end
+
+ private
+
+ attr_reader :category
+ end
+ end
+end
diff --git a/lib/gitlab/navigation/doc.rb b/lib/gitlab/navigation/doc.rb
new file mode 100644
index 00000000..8bed2d43
--- /dev/null
+++ b/lib/gitlab/navigation/doc.rb
@@ -0,0 +1,37 @@
+module Gitlab
+ class Navigation
+ class Doc
+ def initialize(doc)
+ @doc = doc
+ end
+
+ def title
+ doc[:doc_title]
+ end
+
+ def external_url
+ doc[:external_url]
+ end
+
+ def url
+ doc[:doc_url]
+ end
+
+ def ee_only?
+ doc[:ee_only]
+ end
+
+ def ee_tier
+ doc[:ee_tier]
+ end
+
+ def children
+ []
+ end
+
+ private
+
+ attr_reader :doc
+ end
+ end
+end
diff --git a/lib/gitlab/navigation/section.rb b/lib/gitlab/navigation/section.rb
new file mode 100644
index 00000000..8b761fb8
--- /dev/null
+++ b/lib/gitlab/navigation/section.rb
@@ -0,0 +1,37 @@
+module Gitlab
+ class Navigation
+ class Section
+ def initialize(section)
+ @section = section
+ end
+
+ def title
+ section[:section_title]
+ end
+
+ def ee_only?
+ section[:ee_only]
+ end
+
+ def ee_tier
+ section[:ee_tier]
+ end
+
+ def url
+ section[:section_url]
+ end
+
+ def has_children?
+ !children.empty?
+ end
+
+ def children
+ @children ||= section.fetch(:section_categories, []).map { |cat| Category.new(cat) }
+ end
+
+ private
+
+ attr_reader :section
+ end
+ end
+end
diff --git a/spec/gitlab/navigation/category_spec.rb b/spec/gitlab/navigation/category_spec.rb
new file mode 100644
index 00000000..67d28482
--- /dev/null
+++ b/spec/gitlab/navigation/category_spec.rb
@@ -0,0 +1,81 @@
+require 'spec_helper'
+require 'gitlab/navigation/category'
+require 'gitlab/navigation/doc'
+
+describe Gitlab::Navigation::Category do
+ subject(:category) { described_class.new(element) }
+ let(:element) do
+ {
+ category_title: title,
+ external_url: external_url,
+ category_url: url,
+ ee_only: ee_only,
+ ee_tier: ee_tier,
+ docs: docs
+ }
+ end
+ let(:title) { 'Title' }
+ let(:external_url) { 'http://example.com' }
+ let(:url) { 'README.html' }
+ let(:ee_only) { true }
+ let(:ee_tier) { 'GitLab Premium' }
+ let(:docs) { [ { doc_title: 'Doc Title' } ] }
+
+ describe '#title' do
+ subject { category.title }
+
+ it { is_expected.to eq(title) }
+ end
+
+ describe '#external_url' do
+ subject { category.external_url }
+
+ it { is_expected.to eq(external_url) }
+ end
+
+ describe '#url' do
+ subject { category.url }
+
+ it { is_expected.to eq(url) }
+ end
+
+ describe '#ee_only?' do
+ subject { category.ee_only? }
+
+ it { is_expected.to eq(ee_only) }
+ end
+
+ describe '#ee_tier' do
+ subject { category.ee_tier }
+
+ it { is_expected.to eq(ee_tier) }
+ end
+
+ describe '#has_children?' do
+ subject { category.has_children? }
+
+ it { is_expected.to be_truthy }
+
+ context 'when docs are empty' do
+ let(:docs) { [] }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#children' do
+ subject { category.children }
+
+ it 'returns a list of children' do
+ children = subject
+
+ expect(children.first.title).to eq('Doc Title')
+ end
+
+ context 'when docs are empty' do
+ let(:docs) { [] }
+
+ it { is_expected.to eq([]) }
+ end
+ end
+end
diff --git a/spec/gitlab/navigation/doc_spec.rb b/spec/gitlab/navigation/doc_spec.rb
new file mode 100644
index 00000000..f823a73b
--- /dev/null
+++ b/spec/gitlab/navigation/doc_spec.rb
@@ -0,0 +1,56 @@
+require 'spec_helper'
+require 'gitlab/navigation/doc'
+
+describe Gitlab::Navigation::Doc do
+ subject(:doc) { described_class.new(element) }
+ let(:element) do
+ {
+ doc_title: title,
+ external_url: external_url,
+ doc_url: url,
+ ee_only: ee_only,
+ ee_tier: ee_tier
+ }
+ end
+ let(:title) { 'Title' }
+ let(:external_url) { 'http://example.com' }
+ let(:url) { 'README.html' }
+ let(:ee_only) { true }
+ let(:ee_tier) { 'GitLab Premium' }
+
+ describe '#title' do
+ subject { doc.title }
+
+ it { is_expected.to eq(title) }
+ end
+
+ describe '#external_url' do
+ subject { doc.external_url }
+
+ it { is_expected.to eq(external_url) }
+ end
+
+ describe '#url' do
+ subject { doc.url }
+
+ it { is_expected.to eq(url) }
+ end
+
+ describe '#ee_only?' do
+ subject { doc.ee_only? }
+
+ it { is_expected.to eq(ee_only) }
+ end
+
+ describe '#ee_tier' do
+ subject { doc.ee_tier }
+
+ it { is_expected.to eq(ee_tier) }
+ end
+
+ describe '#children' do
+ subject { doc.children }
+
+ it { is_expected.to eq([]) }
+ end
+end
diff --git a/spec/gitlab/navigation/section_spec.rb b/spec/gitlab/navigation/section_spec.rb
new file mode 100644
index 00000000..328793e9
--- /dev/null
+++ b/spec/gitlab/navigation/section_spec.rb
@@ -0,0 +1,73 @@
+require 'spec_helper'
+require 'gitlab/navigation/section'
+require 'gitlab/navigation/category'
+
+describe Gitlab::Navigation::Section do
+ subject(:section) { described_class.new(element) }
+ let(:element) do
+ {
+ section_title: title,
+ section_url: url,
+ ee_only: ee_only,
+ ee_tier: ee_tier,
+ section_categories: categories
+ }
+ end
+ let(:title) { 'Title' }
+ let(:url) { 'README.html' }
+ let(:ee_only) { true }
+ let(:ee_tier) { 'GitLab Premium' }
+ let(:categories) { [ { category_title: 'Category Title' } ] }
+
+ describe '#title' do
+ subject { section.title }
+
+ it { is_expected.to eq(title) }
+ end
+
+ describe '#url' do
+ subject { section.url }
+
+ it { is_expected.to eq(url) }
+ end
+
+ describe '#ee_only?' do
+ subject { section.ee_only? }
+
+ it { is_expected.to eq(ee_only) }
+ end
+
+ describe '#ee_tier' do
+ subject { section.ee_tier }
+
+ it { is_expected.to eq(ee_tier) }
+ end
+
+ describe '#has_children?' do
+ subject { section.has_children? }
+
+ it { is_expected.to be_truthy }
+
+ context 'when categories are empty' do
+ let(:categories) { [] }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#children' do
+ subject { section.children }
+
+ it 'returns a list of children' do
+ children = subject
+
+ expect(children.first.title).to eq('Category Title')
+ end
+
+ context 'when categories are empty' do
+ let(:categories) { [] }
+
+ it { is_expected.to eq([]) }
+ end
+ end
+end
diff --git a/spec/gitlab/navigation_spec.rb b/spec/gitlab/navigation_spec.rb
new file mode 100644
index 00000000..a2d2bda7
--- /dev/null
+++ b/spec/gitlab/navigation_spec.rb
@@ -0,0 +1,86 @@
+require 'spec_helper'
+require 'gitlab/navigation'
+require 'gitlab/navigation/section'
+
+describe Gitlab::Navigation do
+ subject(:navigation) { described_class.new(items, item) }
+ let(:item) { double(path: '/omnibus/user/README.html', identifier: double(to_s: '/omnibus/user/README.md')) }
+ let(:items) do
+ {
+ '/_data/omnibus-nav.yaml' => { sections: [Gitlab::Navigation::Section.new(section_title: 'Omnibus Section')] },
+ '/_data/default-nav.yaml' => { sections: [Gitlab::Navigation::Section.new(section_title: 'Default Section')] }
+ }
+ end
+
+ describe '#nav_items' do
+ subject { navigation.nav_items }
+
+ it 'returns project specific sections' do
+ sections = subject[:sections]
+ section = sections.first
+
+ expect(section.title).to eq('Omnibus Section')
+ end
+
+ context 'when yaml configuration for project does not exist' do
+ let(:item) { double(path: '/ee/user/README.html', identifier: double(to_s: '/ee/user/README.md')) }
+
+ it 'returns default sections' do
+ sections = subject[:sections]
+ section = sections.first
+
+ expect(section.title).to eq('Default Section')
+ end
+ end
+ end
+
+ describe '#element_href' do
+ subject { navigation.element_href(element) }
+ let(:element) { Gitlab::Navigation::Section.new(section_url: url) }
+ let(:url) { 'user/README.html' }
+
+ it { is_expected.to eq('/omnibus/user/README.html') }
+
+ context 'when yaml configuration for project does not exist' do
+ let(:item) { double(path: '/ee/user/README.html', identifier: double(to_s: '/ee/user/README.md')) }
+
+ it { is_expected.to eq('/ee/user/README.html') }
+ end
+ end
+
+ describe '#show_element?' do
+ subject { navigation.show_element?(element) }
+ let(:element) { Gitlab::Navigation::Section.new(section_url: url) }
+ let(:url) { 'user/README.html' }
+
+ it { is_expected.to be_truthy }
+
+ context 'when url does not match item path' do
+ let(:url) { 'project/README.html' }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#id_for' do
+ subject { navigation.id_for(element) }
+ let(:element) { Gitlab::Navigation::Section.new(section_title: 'Section Example') }
+
+ it { is_expected.to eq 'SectionExample' }
+ end
+
+ describe '#optional_ee_badge' do
+ subject { navigation.optional_ee_badge(element) }
+ let(:element) { Gitlab::Navigation::Section.new(ee_only: ee_only, ee_tier: ee_tier) }
+ let(:ee_tier) { 'GitLab Starter' }
+ let(:ee_only) { true }
+
+ it { is_expected.to include('span').and include(ee_tier) }
+
+ context 'when ee_only -> false' do
+ let(:ee_only) { false }
+
+ it { is_expected.to be_nil }
+ end
+ end
+end