aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZog2018-01-15 13:06:19 +0100
committerZog2018-01-25 17:17:58 +0100
commitfef78d49bbc89aa41fe043b4035585605e14d389 (patch)
treee9bebcf9aa600507c1b6e0ead642af766a8b130e
parent8c9ce8f5c143d1e9d3f2c038e447a01ee59c91d3 (diff)
downloadchouette-core-fef78d49bbc89aa41fe043b4035585605e14d389.tar.bz2
Refs #5586 @1h; Primary and secondary lonks implementation
As well as the `to_html` method
-rw-r--r--app/decorators/line_decorator.rb2
-rw-r--r--app/views/lines/show.html.slim9
-rw-r--r--lib/af83/decorator.rb70
-rw-r--r--spec/lib/af83/decorator/decorator_spec.rb95
4 files changed, 160 insertions, 16 deletions
diff --git a/app/decorators/line_decorator.rb b/app/decorators/line_decorator.rb
index 8e8e3bbc5..6c6df1a95 100644
--- a/app/decorators/line_decorator.rb
+++ b/app/decorators/line_decorator.rb
@@ -8,7 +8,7 @@ class LineDecorator < AF83::Decorator
### - an array of actions
### - a boolean
- action_link primary: :index do |l|
+ action_link primary: :index, on: :index do |l|
l.content h.t('lines.actions.show')
l.href { [context[:line_referential], object] }
end
diff --git a/app/views/lines/show.html.slim b/app/views/lines/show.html.slim
index 83244f739..1c0578b0b 100644
--- a/app/views/lines/show.html.slim
+++ b/app/views/lines/show.html.slim
@@ -2,12 +2,9 @@
- content_for :page_header_content do
.row
.col-lg-12.text-right.mb-sm
- - @line.action_links.each do |link|
- = link_to link.href,
- method: link.method,
- data: link.data,
- class: "btn btn-primary #{link.disabled ? "disabled" : ""}" do
- = link.content
+ - @line.action_links(:show, :primary).each do |link|
+ = link.to_html do |l|
+ - l.class "btn btn-primary #{l.disabled ? "disabled" : ""}"
- page_header_content_for @line
diff --git a/lib/af83/decorator.rb b/lib/af83/decorator.rb
index f1570008f..50889ede7 100644
--- a/lib/af83/decorator.rb
+++ b/lib/af83/decorator.rb
@@ -1,6 +1,7 @@
class AF83::Decorator < Draper::Decorator
def self.action_link args={}
args[:if] = @_condition if args[:if].nil?
+
options, link_options = parse_options args
link = Link.new(link_options)
@@ -23,12 +24,18 @@ class AF83::Decorator < Draper::Decorator
(@_action_links || []).flatten.compact.select{|l| l.for_action?(action)}
end
- def action_links action=:index
+ def action_links action=:index, scope=nil
+ return send("#{scope}_links", action) if scope.present?
+
self.class.action_links(action)\
.map{|l| l.bind_to_context(self)}\
.select{|l| l.enabled?}
end
+ def primary_links action=:index
+ action_links(action).select{|l| l.primary_for_action?(action)}
+ end
+
def check_policy policy
_object = policy.to_s == "create" ? object.class : object
method = "#{policy}?"
@@ -38,17 +45,22 @@ class AF83::Decorator < Draper::Decorator
private
def self.parse_options args
options = {}
- %i(primary secondary permission weight).each do |k|
+ %i(weight primary secondary on action actions policy if).each do |k|
options[k] = args.delete(k) if args.has_key?(k)
end
link_options = args.dup
- actions = args.delete :actions
- actions ||= args.delete :on
- actions ||= [args.delete(:action)]
+
+ actions = options.delete :actions
+ actions ||= options.delete :on
+ actions ||= [options.delete(:action)]
actions = [actions] unless actions.is_a?(Array)
link_options[:_actions] = actions.compact
- link_options[:_if] = args.delete(:if)
- link_options[:_policy] = args.delete(:policy)
+
+ link_options[:_primary] = options.delete :primary
+ link_options[:_secondary] = options.delete :secondary
+
+ link_options[:_if] = options.delete(:if)
+ link_options[:_policy] = options.delete(:policy)
[options, link_options]
end
@@ -70,6 +82,10 @@ class AF83::Decorator < Draper::Decorator
link_method *args
end
+ def class *args
+ link_class *args
+ end
+
def method_missing name, *args, &block
if block_given?
@options[name] = block
@@ -82,6 +98,10 @@ class AF83::Decorator < Draper::Decorator
end
end
+ def options
+ @options.symbolize_keys
+ end
+
def complete?
@missing_attributes = REQUIRED_ATTRIBUTES.select{|a| !@options[a].present?}
@missing_attributes.empty?
@@ -95,6 +115,24 @@ class AF83::Decorator < Draper::Decorator
enabled_actions.empty? || enabled_actions.include?(action.to_s)
end
+ %i(primary secondary).each do |k|
+ define_method "#{k}_for_action?" do |action|
+ vals = send("#{k}_actions")
+ if vals.is_a?(Array)
+ return vals.include?(action.to_s)
+ elsif vals.is_a?(String) || vals.is_a?(Symbol)
+ vals.to_s == action.to_s
+ else
+ !!vals
+ end
+ end
+
+ define_method "#{k}_actions" do
+ val = @options[:"_#{k}"]
+ val.is_a?(Array) ? val.map(&:to_s) : val
+ end
+ end
+
def enabled?
enabled = false
if @options[:_if].nil?
@@ -117,6 +155,24 @@ class AF83::Decorator < Draper::Decorator
def errors
"Missing attributes: #{@missing_attributes.to_sentence}"
end
+
+ def html_options
+ out = {}
+ options.each do |k, v|
+ out[k] = v unless k == :content || k == :href || k.to_s =~ /^_/
+ end
+ out[:class] = out.delete(:link_class)
+ out
+ end
+
+ def to_html
+ if block_given?
+ link = Link.new(@options)
+ yield link
+ return link.bind_to_context(context).to_html
+ end
+ context.h.link_to content, href, html_options
+ end
end
class IncompleteLinkDefinition < RuntimeError
diff --git a/spec/lib/af83/decorator/decorator_spec.rb b/spec/lib/af83/decorator/decorator_spec.rb
index 2e046b004..b70e0d7c1 100644
--- a/spec/lib/af83/decorator/decorator_spec.rb
+++ b/spec/lib/af83/decorator/decorator_spec.rb
@@ -1,7 +1,7 @@
RSpec.describe AF83::Decorator, type: :decorator do
describe(:parse_options) do
let(:options){
- {primary: true, secondary: %i(index show), permission: :blublu, weight: 12}
+ {primary: true, secondary: %i(index show), policy: :blublu, weight: 12}
}
let(:link_options){
{foo: :foo, bar: :bar}
@@ -9,10 +9,13 @@ RSpec.describe AF83::Decorator, type: :decorator do
let(:args){ options.dup.update(link_options.dup) }
it "should separate options from link_options" do
_options, _link_options = AF83::Decorator.send :parse_options, args
- expect(_options).to eq options
+ expect(_options).to eq({weight: 12})
link_options.each do |k, v|
expect(_link_options[k]).to eq v
end
+ expect(_link_options[:_primary]).to eq true
+ expect(_link_options[:_secondary]).to eq %i(index show)
+ expect(_link_options[:_policy]).to eq :blublu
end
end
@@ -420,4 +423,92 @@ RSpec.describe AF83::Decorator, type: :decorator do
end
end
end
+
+ describe(:primary_links) do
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj)
+ end
+
+ context "without links" do
+ let(:decorator) do
+ Class.new(AF83::Decorator)
+ end
+
+ it "should return no link" do
+ links = decorated.action_links
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "with a single link" do
+ let(:link_options) do
+ {
+ href: "/foo/bar/baz",
+ content: "Blublu",
+ primary: primary
+ }
+ end
+
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.action_link link_options
+ klass
+ end
+
+ context "always primary" do
+ let(:primary){ true }
+
+ it "should return the link" do
+ links = decorated.primary_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "primary on this action" do
+ let(:primary){ :show }
+
+ it "should return the link" do
+ links = decorated.primary_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "primary on this action among others" do
+ let(:primary){ %i(show edit) }
+
+ it "should return the link" do
+ links = decorated.action_links(:show, :primary)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "primary on other actions" do
+ let(:primary){ %i(index edit) }
+
+ it "should not return the link" do
+ links = decorated.action_links(:show, :primary)
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "primary on another action" do
+ let(:primary){ :index }
+
+ it "should not return the link" do
+ links = decorated.primary_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "never primary" do
+ let(:primary){ nil }
+
+ it "should not return the link" do
+ links = decorated.primary_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+ end
+ end
end