diff options
| author | Zog | 2018-01-15 13:06:19 +0100 |
|---|---|---|
| committer | Zog | 2018-01-25 17:17:58 +0100 |
| commit | fef78d49bbc89aa41fe043b4035585605e14d389 (patch) | |
| tree | e9bebcf9aa600507c1b6e0ead642af766a8b130e | |
| parent | 8c9ce8f5c143d1e9d3f2c038e447a01ee59c91d3 (diff) | |
| download | chouette-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.rb | 2 | ||||
| -rw-r--r-- | app/views/lines/show.html.slim | 9 | ||||
| -rw-r--r-- | lib/af83/decorator.rb | 70 | ||||
| -rw-r--r-- | spec/lib/af83/decorator/decorator_spec.rb | 95 |
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 |
