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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +8 -1
- data/README.md +4 -2
- data/admin_it.gemspec +1 -0
- data/lib/admin_it.rb +7 -5
- data/lib/admin_it/actions/action.rb +5 -2
- data/lib/admin_it/config.rb +1 -0
- data/lib/admin_it/context/collection_context.rb +10 -4
- data/lib/admin_it/context/context.rb +12 -13
- data/lib/admin_it/context/show_context.rb +6 -5
- data/lib/admin_it/context/single_context.rb +19 -8
- data/lib/admin_it/context/table_context.rb +9 -7
- data/lib/admin_it/context/tiles_context.rb +1 -0
- data/lib/admin_it/controller.rb +3 -1
- data/lib/admin_it/data.rb +4 -2
- data/lib/admin_it/data/active_record.rb +10 -301
- data/lib/admin_it/data/active_record/collection_context.rb +47 -0
- data/lib/admin_it/data/active_record/field.rb +64 -0
- data/lib/admin_it/data/active_record/filter.rb +36 -0
- data/lib/admin_it/data/active_record/resource.rb +66 -0
- data/lib/admin_it/data/active_record/single_context.rb +102 -0
- data/lib/admin_it/data/data_behavior.rb +2 -0
- data/lib/admin_it/data/hash.rb +3 -0
- data/lib/admin_it/data/mongoid.rb +14 -0
- data/lib/admin_it/data/mongoid/field.rb +58 -0
- data/lib/admin_it/data/mongoid/resource.rb +67 -0
- data/lib/admin_it/data/object.rb +3 -0
- data/lib/admin_it/engine.rb +4 -1
- data/lib/admin_it/env.rb +21 -2
- data/lib/admin_it/field/field.rb +15 -26
- data/lib/admin_it/filters/field_filter.rb +1 -0
- data/lib/admin_it/filters/filter.rb +8 -13
- data/lib/admin_it/filters/value_filter.rb +1 -0
- data/lib/admin_it/helpers.rb +2 -0
- data/lib/admin_it/helpers/field.rb +3 -3
- data/lib/admin_it/helpers/input.rb +1 -0
- data/lib/admin_it/helpers/page.rb +2 -0
- data/lib/admin_it/helpers/table.rb +12 -8
- data/lib/admin_it/helpers/tiles.rb +2 -0
- data/lib/admin_it/helpers/toolbar.rb +4 -0
- data/lib/admin_it/helpers/top_menu.rb +3 -0
- data/lib/admin_it/resource.rb +16 -21
- data/lib/admin_it/version.rb +1 -1
- data/lib/extend_it.rb +8 -4
- data/lib/extend_it/array_of.rb +12 -10
- data/lib/extend_it/base.rb +9 -8
- data/lib/extend_it/callbacks.rb +11 -12
- data/lib/extend_it/dsl.rb +33 -44
- data/spec/extend_it/dsl_spec.rb +21 -32
- data/spec/lib/data/mongoid/field_spec.rb +28 -0
- data/spec/lib/data/mongoid/resource_spec.rb +50 -0
- data/spec/spec_helper.rb +8 -3
- data/spec/support/module_helpers.rb +20 -0
- metadata +30 -13
- data/.ruby-version +0 -1
- data/lib/admin_it/definitions.rb +0 -89
- data/lib/admin_it/utils.rb +0 -21
- data/lib/extend_it/asserts.rb +0 -40
- data/lib/extend_it/caller.rb +0 -35
- data/lib/extend_it/config.rb +0 -30
- data/lib/extend_it/ensures.rb +0 -193
- data/spec/extend_it/config_spec.rb +0 -52
- 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
|
data/lib/admin_it/data/hash.rb
CHANGED
@@ -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
|