Skip to content

Commit

Permalink
Fixes #12716 - Extensible pages for smart proxy with mount points
Browse files Browse the repository at this point in the history
  • Loading branch information
Ondrej Prazak authored and lzap committed Jan 12, 2016
1 parent 24f70e1 commit 33f7c66
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 1 deletion.
35 changes: 35 additions & 0 deletions app/helpers/pagelets_helper.rb
@@ -0,0 +1,35 @@
module PageletsHelper
def pagelets_for(mountpoint)
Pagelets::Manager.sorted_pagelets_at("#{controller_name}/#{action_name}", mountpoint)
end

def render_pagelets_for(mountpoint, opts = {})
result = ""
pagelets_for(mountpoint).each do |pagelet|
result += render_pagelet(pagelet, opts)
end
result.html_safe
end

def render_tab_content_for(mountpoint, opts = {})
result = ""
pagelets_for(mountpoint).each do |pagelet|
result += "<div id='#{pagelet.id}' class='tab-pane'>"
result += render_pagelet(pagelet, opts)
result += "</div>"
end
result.html_safe
end

def render_tab_header_for(mountpoint, opts = {})
result = ""
pagelets_for(mountpoint).each do |pagelet|
result += "<li><a href='##{pagelet.id}' data-toggle='tab'>#{pagelet.name}</a></li>"
end
result.html_safe
end

def render_pagelet(pagelet, opts)
render(pagelet.partial, opts.merge!({ :pagelet => pagelet })).html_safe
end
end
2 changes: 2 additions & 0 deletions app/helpers/smart_proxies_helper.rb
Expand Up @@ -28,6 +28,8 @@ def feature_actions(proxy, authorizer)
actions << display_link_if_authorized(_("Import subnets"), hash_for_import_subnets_path(:smart_proxy_id => proxy))
end

actions << render_pagelets_for(:smart_proxy_title_actions)

actions
end

Expand Down
10 changes: 10 additions & 0 deletions app/services/foreman/plugin.rb
Expand Up @@ -175,6 +175,16 @@ def delete_menu_item(menu, item)
Menu::Manager.map(menu).delete(item)
end

# Extends an already registered extensible page.
# Usage:
#
# extend_page("smart_proxies/show") do |context|
# context.add_pagelet :mountpoint, :name => "Example Pagelet", :partial => "path/to/partial", :priority => 10000, :id => 'custom-html-id'
# end
def extend_page(page_name, &block)
yield Pagelets::Manager.new(page_name) if block_given?
end

def tests_to_skip(hash)
Rails.logger.warn "Minitest 5 deprecated the runner API and plugin tests \
can't be skipped right now. Future versions of Foreman might bring back this \
Expand Down
44 changes: 44 additions & 0 deletions app/services/pagelets/manager.rb
@@ -0,0 +1,44 @@
module Pagelets
class Manager
def initialize(page_name)
@page_name = page_name
end

def add_pagelet(mountpoint, opts)
self.class.add_pagelet(@page_name, mountpoint, opts)
end

class << self
def add_pagelet(page_name, mountpoint, opts)
handle_empty_keys_for page_name, mountpoint
raise ::Foreman::Exception.new(N_("Cannot add pagelet to page %s without partial", page_name)) unless opts[:partial]
raise ::Foreman::Exception.new(N_("Cannot add pagelet to page %s without mountpoint", page_name)) if mountpoint.nil?
priority = opts[:priority] || default_pagelet_priority(page_name, mountpoint)
pagelet = Pagelets::Pagelet.new(opts.delete(:name), opts.delete(:partial), priority, opts)
@pagelets[page_name][mountpoint] << pagelet
end

def default_pagelet_priority(page_name, mountpoint)
# We need a default priority value for the first pagelet if it is not specified
@pagelets[page_name][mountpoint].map(&:priority).push(0).max + 100
end

def pagelets_at(page_name, mountpoint)
handle_empty_keys_for page_name, mountpoint
@pagelets[page_name][mountpoint]
end

def sorted_pagelets_at(page_name, mountpoint)
pagelets_at(page_name, mountpoint).sort
end

private

def handle_empty_keys_for(page_name, mountpoint)
@pagelets ||= {}.with_indifferent_access
@pagelets[page_name] ||= {}
@pagelets[page_name][mountpoint] ||= []
end
end
end
end
24 changes: 24 additions & 0 deletions app/services/pagelets/pagelet.rb
@@ -0,0 +1,24 @@
module Pagelets
class Pagelet
attr_reader :name, :partial, :priority, :opts

def initialize(name, partial, priority, opts)
@name = name
@partial = partial
@priority = priority
@opts = opts
end

def <=>(other)
priority <=> other.priority
end

def id
opts[:id] || 'pagelet-id-' + @name.gsub(/\s+/, "_").underscore
end

def method_missing(method_name, *arguments, &block)
@opts[method_name]
end
end
end
5 changes: 4 additions & 1 deletion app/views/smart_proxies/show.html.erb
Expand Up @@ -7,6 +7,7 @@
<% if service_features.any? %>
<li><a href="#services" data-toggle="tab"><%= _('Services') %></a></li>
<% end %>
<%= render_tab_header_for(:main_tabs, :smart_proxy => @smart_proxy) %>
</ul>
<div id="proxy-tab-content" class="proxy-content tab-content">
<div class="tab-pane active in" id="properties">
Expand Down Expand Up @@ -50,9 +51,10 @@
<%= @smart_proxy.features.to_sentence %> <%= refresh_proxy_icon(@smart_proxy, authorizer) %>
</div>
</div>
<%= render_pagelets_for(:overview_content, :smart_proxy => @smart_proxy) %>
</div>
<div class="col-md-6">
<!--place holder for Capsule sync-->
<%= render_pagelets_for(:details_content, :smart_proxy => @smart_proxy) %>
</div>
</div>
<% if service_features.any? %>
Expand All @@ -69,5 +71,6 @@
</div>
</div>
<% end %>
<%= render_tab_content_for(:main_tabs, :smart_proxy => @smart_proxy)%>
</div>
</div>
25 changes: 25 additions & 0 deletions test/unit/pagelet_manager_test.rb
@@ -0,0 +1,25 @@
require 'test_helper'

class PageletManagerTest < ActiveSupport::TestCase
test 'should assign default priority' do
::Pagelets::Manager.add_pagelet("test", :test_point, :partial => "tests")
assert_equal 100, ::Pagelets::Manager.pagelets_at("test", :test_point).first.priority
end

test 'should return sorted pagelets at mountpoint' do
assert_equal 0, ::Pagelets::Manager.sorted_pagelets_at("test", :mountpoint).count
::Pagelets::Manager.add_pagelet("test", :mountpoint, :partial => "tests", :priority => 20)
::Pagelets::Manager.add_pagelet("test", :mountpoint, :partial => "tests", :priority => 15)
::Pagelets::Manager.add_pagelet("test", :mountpoint, :partial => "tests", :priority => 5)
assert_equal 3, ::Pagelets::Manager.sorted_pagelets_at("test", :mountpoint).count
assert_equal 5, ::Pagelets::Manager.sorted_pagelets_at("test", :mountpoint).first.priority
end

test 'should add default priority' do
::Pagelets::Manager.add_pagelet("test", :point, :partial => "tests")
::Pagelets::Manager.add_pagelet("test", :point, :partial => "tests")

assert_equal 100, ::Pagelets::Manager.sorted_pagelets_at("test", :point).first.priority
assert_equal 200, ::Pagelets::Manager.sorted_pagelets_at("test", :point).last.priority
end
end
27 changes: 27 additions & 0 deletions test/unit/pagelet_test.rb
@@ -0,0 +1,27 @@
require 'test_helper'

class PageletTest < ActiveSupport::TestCase
test 'order pagelets asc' do
pagelets = []
pagelets << ::Pagelets::Pagelet.new("first", "tests/test", 40, {})
pagelets << ::Pagelets::Pagelet.new("first", "tests/test", 50, {})
pagelets << ::Pagelets::Pagelet.new("first", "tests/test", 10, {})
pagelets << ::Pagelets::Pagelet.new("first", "tests/test", 20, {})
pagelets = pagelets.sort

assert_equal 10, pagelets[0].priority
assert_equal 50, pagelets[3].priority
end

test 'should show id for pagelet' do
pagelet = ::Pagelets::Pagelet.new("test pagelet", "tests/show", 50, {})
assert_equal "test pagelet", pagelet.name
assert_equal "pagelet-id-test_pagelet", pagelet.id
end

test 'should override default id' do
pagelet = ::Pagelets::Pagelet.new("test pagelet", "tests/show", 50, { :id => "custom-id"})
assert_equal "test pagelet", pagelet.name
assert_equal "custom-id", pagelet.id
end
end
11 changes: 11 additions & 0 deletions test/unit/plugin_test.rb
Expand Up @@ -268,4 +268,15 @@ def test_add_provision_method
end
assert_equal 'Awesomeness Based', Host::Managed.provision_methods['awesome']
end

def test_extend_page
Foreman::Plugin.register(:foo) do
extend_page("tests/show") do |context|
context.add_pagelet :main_tabs, :name => "My Tab", :partial => "partial"
end
end

assert_equal 1, ::Pagelets::Manager.sorted_pagelets_at("tests/show", :main_tabs).count
assert_equal "My Tab", ::Pagelets::Manager.sorted_pagelets_at("tests/show", :main_tabs).first.name
end
end

2 comments on commit 33f7c66

@dLobatog
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some documentation about this?

@domcleal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.