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 | 
