diff options
| author | Luc Donnet | 2018-02-19 11:04:29 +0100 |
|---|---|---|
| committer | Luc Donnet | 2018-02-19 11:04:29 +0100 |
| commit | 7b17deff51545358009cb417cbb9d796565e7540 (patch) | |
| tree | a43a5586ad39d838dd607e600dbc15ff18a58ab3 /lib/af83/decorator.rb | |
| parent | 89428163fc93a7e09ebb0ca47939f8558afeb5eb (diff) | |
| parent | 5f6008d165df4499319a2121a71842657d6ac3c9 (diff) | |
| download | chouette-core-7b17deff51545358009cb417cbb9d796565e7540.tar.bz2 | |
Merge branch 'master' into 0000-docker
Diffstat (limited to 'lib/af83/decorator.rb')
| -rw-r--r-- | lib/af83/decorator.rb | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/af83/decorator.rb b/lib/af83/decorator.rb new file mode 100644 index 000000000..71cf1170d --- /dev/null +++ b/lib/af83/decorator.rb @@ -0,0 +1,131 @@ +class AF83::Decorator < ModelDecorator + include AF83::Decorator::EnhancedDecorator + extend AF83::Decorator::EnhancedDecorator::ClassMethods + + class << self + def decorates klass + instance_decorator.decorates klass + end + + def instance_decorator + @instance_decorator ||= begin + klass = Class.new(AF83::Decorator::InstanceDecorator) + klass.delegate_all + klass + end + end + + def with_instance_decorator + @_with_instance_decorator = true + yield instance_decorator + @_with_instance_decorator = false + end + + def decorate object, options = {} + if object.is_a?(ActiveRecord::Base) + return instance_decorator.decorate object, options + else + self.new object, options.update(with: instance_decorator) + end + end + + def define_instance_method method_name, &block + instance_decorator.send(:define_method, method_name, &block) + end + + # Defines a class method on the decorated object's class. These + # can be called like `object.class.my_method`. + def define_instance_class_method method_name, &block + instance_decorator.send(:define_singleton_method, method_name, &block) + end + + def set_scope_with_instance_decorator value=nil, &block + set_scope_without_instance_decorator value, &block + instance_decorator.set_scope value, &block + end + + alias_method_chain :set_scope, :instance_decorator + end + + class ActionLinks + attr_reader :options + + delegate :each, :map, :size, :first, :last, :any?, :select, to: :resolve + + def initialize opts + @options = opts.deep_dup + end + + def for_group group + returning_a_copy do + @options[:groups] = [group] if group.present? + end + end + + def for_groups groups + returning_a_copy do + @options[:groups] = groups if groups.present? + end + end + + def primary + for_group :primary + end + + def secondary + for_group :secondary + end + + def resolve + out = @options[:links].map{|l| l.bind_to_context(@options[:context], @options[:action])}.select{|l| l.enabled?} + if @options[:groups].present? + out = out.select do |l| + @options[:groups].any? do |g| + l.in_group_for_action?(g) + end + end + end + out + end + alias_method :to_ary, :resolve + + def grouped_by *groups + add_footer = groups.include?(:footer) + groups -= [:footer] + out = HashWithIndifferentAccess[*groups.map{|g| [g, []]}.flatten(1)] + out[:other] = [] + if add_footer + out[:footer] = [] + groups << :footer + end + + each do |l| + found = false + groups.each do |g| + if l.in_group_for_action?(g) + out[g] << l + found = true + next + end + end + out[:other] << l unless found + end + out + end + + private + def returning_a_copy &block + out = ActionLinks.new options + out.instance_eval &block + out + end + end + + class IncompleteLinkDefinition < RuntimeError + end + + class InstanceDecorator < Draper::Decorator + include AF83::Decorator::EnhancedDecorator + extend AF83::Decorator::EnhancedDecorator::ClassMethods + end +end |
