admin_it 1.0.11 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile +8 -1
  4. data/README.md +4 -2
  5. data/admin_it.gemspec +1 -0
  6. data/lib/admin_it.rb +7 -5
  7. data/lib/admin_it/actions/action.rb +5 -2
  8. data/lib/admin_it/config.rb +1 -0
  9. data/lib/admin_it/context/collection_context.rb +10 -4
  10. data/lib/admin_it/context/context.rb +12 -13
  11. data/lib/admin_it/context/show_context.rb +6 -5
  12. data/lib/admin_it/context/single_context.rb +19 -8
  13. data/lib/admin_it/context/table_context.rb +9 -7
  14. data/lib/admin_it/context/tiles_context.rb +1 -0
  15. data/lib/admin_it/controller.rb +3 -1
  16. data/lib/admin_it/data.rb +4 -2
  17. data/lib/admin_it/data/active_record.rb +10 -301
  18. data/lib/admin_it/data/active_record/collection_context.rb +47 -0
  19. data/lib/admin_it/data/active_record/field.rb +64 -0
  20. data/lib/admin_it/data/active_record/filter.rb +36 -0
  21. data/lib/admin_it/data/active_record/resource.rb +66 -0
  22. data/lib/admin_it/data/active_record/single_context.rb +102 -0
  23. data/lib/admin_it/data/data_behavior.rb +2 -0
  24. data/lib/admin_it/data/hash.rb +3 -0
  25. data/lib/admin_it/data/mongoid.rb +14 -0
  26. data/lib/admin_it/data/mongoid/field.rb +58 -0
  27. data/lib/admin_it/data/mongoid/resource.rb +67 -0
  28. data/lib/admin_it/data/object.rb +3 -0
  29. data/lib/admin_it/engine.rb +4 -1
  30. data/lib/admin_it/env.rb +21 -2
  31. data/lib/admin_it/field/field.rb +15 -26
  32. data/lib/admin_it/filters/field_filter.rb +1 -0
  33. data/lib/admin_it/filters/filter.rb +8 -13
  34. data/lib/admin_it/filters/value_filter.rb +1 -0
  35. data/lib/admin_it/helpers.rb +2 -0
  36. data/lib/admin_it/helpers/field.rb +3 -3
  37. data/lib/admin_it/helpers/input.rb +1 -0
  38. data/lib/admin_it/helpers/page.rb +2 -0
  39. data/lib/admin_it/helpers/table.rb +12 -8
  40. data/lib/admin_it/helpers/tiles.rb +2 -0
  41. data/lib/admin_it/helpers/toolbar.rb +4 -0
  42. data/lib/admin_it/helpers/top_menu.rb +3 -0
  43. data/lib/admin_it/resource.rb +16 -21
  44. data/lib/admin_it/version.rb +1 -1
  45. data/lib/extend_it.rb +8 -4
  46. data/lib/extend_it/array_of.rb +12 -10
  47. data/lib/extend_it/base.rb +9 -8
  48. data/lib/extend_it/callbacks.rb +11 -12
  49. data/lib/extend_it/dsl.rb +33 -44
  50. data/spec/extend_it/dsl_spec.rb +21 -32
  51. data/spec/lib/data/mongoid/field_spec.rb +28 -0
  52. data/spec/lib/data/mongoid/resource_spec.rb +50 -0
  53. data/spec/spec_helper.rb +8 -3
  54. data/spec/support/module_helpers.rb +20 -0
  55. metadata +30 -13
  56. data/.ruby-version +0 -1
  57. data/lib/admin_it/definitions.rb +0 -89
  58. data/lib/admin_it/utils.rb +0 -21
  59. data/lib/extend_it/asserts.rb +0 -40
  60. data/lib/extend_it/caller.rb +0 -35
  61. data/lib/extend_it/config.rb +0 -30
  62. data/lib/extend_it/ensures.rb +0 -193
  63. data/spec/extend_it/config_spec.rb +0 -52
  64. data/spec/extend_it/ensures_spec.rb +0 -39
@@ -0,0 +1,47 @@
1
+ module AdminIt
2
+ module ActiveRecordData
3
+ #
4
+ module CollectionContext
5
+ def entities=(value)
6
+ super(value)
7
+ @count = @entities.nil? ? 0 : @entities.count
8
+ end
9
+
10
+ protected
11
+
12
+ def load_entities
13
+ collection =
14
+ if AdminIt::Env.pundit?
15
+ controller.policy_scope(entity_class)
16
+ else
17
+ entity_class.all
18
+ end
19
+ if child?
20
+ collection = collection.where(parent.resource.name => parent.entity)
21
+ end
22
+ sort = {}
23
+ sorting.each do |_sort|
24
+ name, order = _sort.split(':')
25
+ sort[name.to_sym] = order.to_sym
26
+ end
27
+ unless collection.nil? || sort.empty?
28
+ collection = collection.order(sort)
29
+ end
30
+ collection
31
+ end
32
+ end
33
+
34
+ #
35
+ module TableContext
36
+ def entities
37
+ if @entities.count > page_size
38
+ # limit collection to current page
39
+ @entities = @entities
40
+ .offset(page_size * (page - 1))
41
+ .limit(page_size)
42
+ end
43
+ super
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,64 @@
1
+ module AdminIt
2
+ module ActiveRecordData
3
+ #
4
+ module Field
5
+ def self.included(base)
6
+ base.class_eval do
7
+ class << self
8
+ attr_accessor :assoc
9
+
10
+ protected
11
+
12
+ def default_display_name
13
+ entity_class.human_attribute_name(field_name)
14
+ end
15
+ end
16
+ class_attr_reader :assoc
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ def read_value(entity)
23
+ value = entity.send(name)
24
+ if type == :relation
25
+ if assoc.collection?
26
+ value.nil? || value.empty? ? [] : value.map(&:id).to_json
27
+ else
28
+ value.nil? ? nil : value.id
29
+ end
30
+ else
31
+ value
32
+ end
33
+ end
34
+
35
+ def show_value(entity)
36
+ value = entity.send(name)
37
+ if type == :relation
38
+ resource = AdminIt.resources.values.find do |r|
39
+ r.entity_class == assoc.klass
40
+ end
41
+ return I18n.t('admin_it.relation.no_resource') if resource.nil?
42
+ context = resource.contexts.find { |c| c <= ShowContext }
43
+ return I18n.t('admin_it.relation.no_context') if context.nil?
44
+ if assoc.collection?
45
+ if value.count == 0
46
+ I18n.t('admin_it.collection.no_data')
47
+ else
48
+ v = context.read(value.first)
49
+ v.nil? ? '' : context.read(value.first) + ' ...'
50
+ end
51
+ else
52
+ context.read(value)
53
+ end
54
+ else
55
+ value
56
+ end
57
+ end
58
+
59
+ def write_value(entity, value)
60
+ entity.send("#{name}=", value)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,36 @@
1
+ module AdminIt
2
+ module ActiveRecordData
3
+ #
4
+ module ValueFilter
5
+ def all_values(collection = nil, &block)
6
+ enum = Enumerator.new do |yielder|
7
+ field
8
+ .entity_class
9
+ .select(self.class.field.field_name)
10
+ .group(self.class.field.field_name)
11
+ .count
12
+ .each do |v, c|
13
+ yielder << { value: v, count: c }
14
+ end
15
+ end
16
+ block_given? ? enum.each(&block) : enum
17
+ end
18
+
19
+ def apply(collection)
20
+ return collection if @values.empty?
21
+ binding = []
22
+ conditions = ''
23
+ if @values.size == 1 && @values[0].nil?
24
+ conditions = "#{field.field_name} IS NULL"
25
+ else
26
+ conditions = "#{field.field_name} IN (?)"
27
+ binding << @values.select { |v| !v.nil? }
28
+ if @values.any? { |v| v.nil? }
29
+ conditions += " OR #{field.field_name} IS NULL"
30
+ end
31
+ end
32
+ collection.where(conditions, *binding)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,66 @@
1
+ module AdminIt
2
+ module ActiveRecordData
3
+ #
4
+ module Resource
5
+ protected
6
+
7
+ TYPE_MAPPING = {
8
+ primary_key: :integer,
9
+ string: :string,
10
+ text: :string,
11
+ integer: :integer,
12
+ float: :float,
13
+ decimal: :float,
14
+ datetime: :datetime,
15
+ timestamp: :datetime,
16
+ time: :time,
17
+ date: :date,
18
+ binary: :binary,
19
+ boolean: :boolean
20
+ }
21
+
22
+ def default_display_name
23
+ entity_class
24
+ .model_name
25
+ .human# (count: 0)
26
+ .split(' ')
27
+ .map { |s| s.mb_chars.capitalize }
28
+ .join(' ')
29
+ end
30
+
31
+ def default_fields(&block)
32
+ enum = Enumerator.new do |yielder|
33
+ exclude = []
34
+ entity_class.reflections.each do |name, a|
35
+ f = AdminIt::Field.create(name, entity_class, type: :relation)
36
+ f.assoc = a
37
+ yielder << f
38
+ exclude << "#{name}_id" if a.belongs_to?
39
+ end
40
+ entity_class.columns_hash.each do |name, c|
41
+ next if exclude.include?(name)
42
+ name = name.to_sym
43
+ opts = { type: TYPE_MAPPING[c.type] }
44
+ if name == :id
45
+ opts[:visible] = false
46
+ opts[:writable] = false
47
+ end
48
+ yielder << AdminIt::Field.create(name, entity_class, opts)
49
+ end
50
+ end
51
+ block_given? ? enum.each(&block) : enum
52
+ end
53
+
54
+ def default_filters
55
+ enum = Enumerator.new do |yielder|
56
+ fields.each do |field|
57
+ next if field.type == :relation
58
+ name = "#{field.field_name}_value"
59
+ yielder << AdminIt::ValueFilter.create(name, self, field)
60
+ end
61
+ end
62
+ block_given? ? enum.each(&block) : enum
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,102 @@
1
+ module AdminIt
2
+ module ActiveRecordData
3
+ #
4
+ module SingleContext
5
+ protected
6
+
7
+ def load_entity(identity: nil)
8
+ identity ||= controller.params[:id]
9
+ entity = entity_class.find(identity)
10
+ controller.authorize(entity, "#{name}?") if AdminIt::Env.pundit?
11
+ if child?
12
+ fields
13
+ .select { |f| f.type == :relation &&
14
+ f.assoc.klass == parent.entity_class }
15
+ .each do |f|
16
+ if f.assoc.collection?
17
+ entity.send(f.name) << parent.entity
18
+ else
19
+ entity.send("#{f.name}=", parent.entity)
20
+ end
21
+ end
22
+ end
23
+ entity
24
+ end
25
+ end
26
+
27
+ #
28
+ module SavableSingleContext
29
+ protected
30
+
31
+ def do_save_entity
32
+ if AdminIt::Env.pundit?
33
+ controller.authorize(entity, "#{self.class.save_action}?")
34
+ end
35
+ params = controller.params[resource.name]
36
+ fields(scope: :writable).each do |field|
37
+ next unless params.key?(field.name)
38
+ next unless field.writable?
39
+ next if field.type == :relation
40
+ field.write(entity, params[field.name])
41
+ end
42
+ controller.redirect_to_default if entity.save
43
+ end
44
+
45
+ def add_child_context(for_resource, context_class: :table)
46
+ child_resource = AdminIt.resources[for_resource]
47
+ return nil if child_resource.nil?
48
+ child_resource[context_class].new(self)
49
+ end
50
+ end
51
+
52
+ #
53
+ module NewContext
54
+ def self.included(base)
55
+ base.after_initialize do
56
+ if child?
57
+ fields
58
+ .select { |f| f.type == :relation &&
59
+ f.assoc.klass == parent.entity_class }
60
+ .each do |f|
61
+ if f.assoc.collection?
62
+ entity.send(f.name) << parent.entity
63
+ else
64
+ entity.send("#{f.name}=", parent.entity)
65
+ end
66
+ f.visible = false
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ protected
73
+
74
+ def load_entity(identity: nil)
75
+ entity = entity_class.new
76
+ controller.authorize(entity, "#{name}?") if AdminIt::Env.pundit?
77
+ entity
78
+ end
79
+ end
80
+
81
+ #
82
+ module ShowContext
83
+ def identity
84
+ entity.id
85
+ end
86
+
87
+ protected
88
+
89
+ def do_destroy_entity
90
+ controller.authorize(entity, :destroy?) if AdminIt::Env.pundit?
91
+ controller.redirect_to_default if entity.destroy
92
+ end
93
+ end
94
+
95
+ #
96
+ module EditContext
97
+ def identity
98
+ entity.id
99
+ end
100
+ end
101
+ end
102
+ end
@@ -1,4 +1,5 @@
1
1
  module AdminIt
2
+ #
2
3
  module DataBehavior
3
4
  private
4
5
 
@@ -11,6 +12,7 @@ module AdminIt
11
12
  import_module = @data_module.const_get(mod.name.split('::').last)
12
13
  include(import_module) if import_module.is_a?(Module)
13
14
  rescue NameError
15
+ nil
14
16
  end
15
17
  end
16
18
  end
@@ -1,10 +1,12 @@
1
1
  module AdminIt
2
2
  module HashData
3
+ #
3
4
  module Context
4
5
  def self.included(base)
5
6
  base.extend(ClassMethods)
6
7
  end
7
8
 
9
+ #
8
10
  module ClassMethods
9
11
  def load_fields
10
12
  []
@@ -12,6 +14,7 @@ module AdminIt
12
14
  end
13
15
  end
14
16
 
17
+ #
15
18
  module Field
16
19
  protected
17
20
 
@@ -0,0 +1,14 @@
1
+ if AdminIt::Env.mongoid?
2
+ require 'mongoid'
3
+ require File.join %w(admin_it data mongoid resource)
4
+ require File.join %w(admin_it data mongoid field)
5
+ # require File.join %w(admin_it data monfo_id collection_context)
6
+ # require File.join %w(admin_it data monfo_id single_context)
7
+ # require File.join %w(admin_it data monfo_id field)
8
+ # require File.join %w(admin_it data monfo_id filter)
9
+
10
+ #
11
+ module AdminIt
12
+ register_data ::Mongoid::Document, AdminIt::MongoidData
13
+ end
14
+ end
@@ -0,0 +1,58 @@
1
+ module AdminIt
2
+ module MongoidData
3
+ #
4
+ module Field
5
+ def self.included(base)
6
+ base.class_eval do
7
+ class << self
8
+ attr_accessor :assoc
9
+ end
10
+ class_attr_reader :assoc
11
+ end
12
+ end
13
+
14
+ protected
15
+
16
+ def read_value(entity)
17
+ value = entity.send(name)
18
+ if type == :relation
19
+ if assoc.collection?
20
+ value.nil? || value.empty? ? [] : value.map(&:id).to_json
21
+ else
22
+ value.nil? ? nil : value.id
23
+ end
24
+ else
25
+ value
26
+ end
27
+ end
28
+
29
+ def show_value(entity)
30
+ value = entity.send(name)
31
+ if type == :relation
32
+ resource = AdminIt.resources.values.find do |r|
33
+ r.entity_class == assoc.klass
34
+ end
35
+ return I18n.t('admin_it.relation.no_resource') if resource.nil?
36
+ context = resource.contexts.find { |c| c <= ShowContext }
37
+ return I18n.t('admin_it.relation.no_context') if context.nil?
38
+ if assoc.collection?
39
+ if value.count == 0
40
+ I18n.t('admin_it.collection.no_data')
41
+ else
42
+ v = context.read(value.first)
43
+ v.nil? ? '' : context.read(value.first) + ' ...'
44
+ end
45
+ else
46
+ context.read(value)
47
+ end
48
+ else
49
+ value
50
+ end
51
+ end
52
+
53
+ def write_value(entity, value)
54
+ entity.send("#{name}=", value)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,67 @@
1
+ require 'bson'
2
+ require 'moped'
3
+
4
+ module AdminIt
5
+ module MongoidData
6
+ #
7
+ module Resource
8
+ protected
9
+
10
+ TYPE_MAPPING = {
11
+ Array => :array,
12
+ BigDecimal => :float,
13
+ Boolean => :boolean,
14
+ Date => :date,
15
+ DateTime => :datetime,
16
+ Float => :float,
17
+ Hash => :hash,
18
+ Integer => :integer,
19
+ BSON::ObjectId => :integer,
20
+ BSON::Binary => :binary,
21
+ Range => :range,
22
+ Regexp => :regexp,
23
+ String => :string,
24
+ Symbol => :symbol,
25
+ Time => :time
26
+ }
27
+
28
+ NONFILTER_TYPES = %i(array hash binary range regexp relation)
29
+
30
+ def default_fields(&block)
31
+ enum = Enumerator.new do |yielder|
32
+ entity_class.fields.each do |name, field|
33
+ name = name.to_sym
34
+ opts = { type: TYPE_MAPPING[field.options[:type]] }
35
+ if name == :_id
36
+ name = :id
37
+ opts[:visible] = false
38
+ opts[:writable] = false
39
+ end
40
+ yielder << AdminIt::Field.create(name, entity_class, opts)
41
+ end
42
+ relations = entity_class.relations
43
+ relations.merge!(entity_class.embedded_relations)
44
+ relations.each do |name, rel|
45
+ name = name.to_sym
46
+ opts = { type: :relation }
47
+ field = AdminIt::Field.create(name, entity_class, opts)
48
+ field.assoc = rel
49
+ yielder << field
50
+ end
51
+ end
52
+ block_given? ? enum.each(&block) : enum
53
+ end
54
+
55
+ def default_filters
56
+ enum = Enumerator.new do |yielder|
57
+ fields.each do |field|
58
+ next if NONFILTER_TYPES.include?(field.type)
59
+ name = "#{field.field_name}_value"
60
+ yielder << AdminIt::ValueFilter.create(name, self, field)
61
+ end
62
+ end
63
+ block_given? ? enum.each(&block) : enum
64
+ end
65
+ end
66
+ end
67
+ end