admin_it 1.0.1
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 +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.rubocop.yml +5 -0
- data/.yardopts +3 -0
- data/Gemfile +5 -0
- data/README.md +58 -0
- data/README_RU.md +52 -0
- data/Rakefile +23 -0
- data/admin_it.gemspec +38 -0
- data/app/assets/fonts/admin_it/FontAwesome.otf +0 -0
- data/app/assets/fonts/admin_it/fontawesome-webfont.eot +0 -0
- data/app/assets/fonts/admin_it/fontawesome-webfont.svg +414 -0
- data/app/assets/fonts/admin_it/fontawesome-webfont.ttf +0 -0
- data/app/assets/fonts/admin_it/fontawesome-webfont.woff +0 -0
- data/app/assets/fonts/admin_it/glyphicons-halflings-regular.eot +0 -0
- data/app/assets/fonts/admin_it/glyphicons-halflings-regular.svg +229 -0
- data/app/assets/fonts/admin_it/glyphicons-halflings-regular.ttf +0 -0
- data/app/assets/fonts/admin_it/glyphicons-halflings-regular.woff +0 -0
- data/app/assets/javascript/admin_it/admin_it.js +89 -0
- data/app/assets/javascript/admin_it/bootstrap.min.js +6 -0
- data/app/assets/stylesheets/admin_it/admin_it.css +25 -0
- data/app/assets/stylesheets/admin_it/bootstrap-theme.min.css +7 -0
- data/app/assets/stylesheets/admin_it/bootstrap.min.css +7 -0
- data/app/assets/stylesheets/admin_it/font-awesome.min.css +4 -0
- data/app/views/admin_it/context/_table.html.slim +38 -0
- data/app/views/admin_it/context/_tiles.html.slim +23 -0
- data/app/views/admin_it/edit.html.slim +2 -0
- data/app/views/admin_it/new.html.slim +2 -0
- data/app/views/admin_it/shared/_child.html.slim +15 -0
- data/app/views/admin_it/shared/_fields.html.slim +19 -0
- data/app/views/admin_it/shared/_filters.html.slim +40 -0
- data/app/views/admin_it/shared/_form.html.slim +50 -0
- data/app/views/admin_it/shared/_pagination.html.slim +41 -0
- data/app/views/admin_it/shared/_toolbar.html.slim +30 -0
- data/app/views/admin_it/show.html.slim +6 -0
- data/app/views/admin_it/table.html.slim +2 -0
- data/app/views/admin_it/tiles.html.slim +2 -0
- data/app/views/layouts/admin_it.html.slim +37 -0
- data/app/views/layouts/admin_it_dialog.html.slim +8 -0
- data/config.ru +7 -0
- data/lib/admin_it/config.rb +24 -0
- data/lib/admin_it/context/collection_context.rb +239 -0
- data/lib/admin_it/context/context.rb +232 -0
- data/lib/admin_it/context/show_context.rb +45 -0
- data/lib/admin_it/context/single_context.rb +199 -0
- data/lib/admin_it/context/table_context.rb +66 -0
- data/lib/admin_it/context/tiles_context.rb +31 -0
- data/lib/admin_it/context.rb +6 -0
- data/lib/admin_it/controller.rb +42 -0
- data/lib/admin_it/data/active_record.rb +283 -0
- data/lib/admin_it/data/data_behavior.rb +18 -0
- data/lib/admin_it/data/hash.rb +27 -0
- data/lib/admin_it/data/object.rb +51 -0
- data/lib/admin_it/data.rb +24 -0
- data/lib/admin_it/definitions.rb +89 -0
- data/lib/admin_it/engine.rb +56 -0
- data/lib/admin_it/env.rb +37 -0
- data/lib/admin_it/errors.rb +5 -0
- data/lib/admin_it/field/field.rb +174 -0
- data/lib/admin_it/field.rb +1 -0
- data/lib/admin_it/filters/entity_filter.rb +4 -0
- data/lib/admin_it/filters/field_filter.rb +31 -0
- data/lib/admin_it/filters/filter.rb +150 -0
- data/lib/admin_it/filters/value_filter.rb +52 -0
- data/lib/admin_it/filters.rb +4 -0
- data/lib/admin_it/helpers/field.rb +25 -0
- data/lib/admin_it/helpers/input.rb +22 -0
- data/lib/admin_it/helpers/page.rb +26 -0
- data/lib/admin_it/helpers/table.rb +85 -0
- data/lib/admin_it/helpers/tiles.rb +17 -0
- data/lib/admin_it/helpers/toolbar.rb +40 -0
- data/lib/admin_it/helpers/top_menu.rb +39 -0
- data/lib/admin_it/helpers.rb +12 -0
- data/lib/admin_it/locales/en.yml +14 -0
- data/lib/admin_it/locales/ru.yml +14 -0
- data/lib/admin_it/renderable.rb +18 -0
- data/lib/admin_it/resource.rb +292 -0
- data/lib/admin_it/utils.rb +21 -0
- data/lib/admin_it/version.rb +5 -0
- data/lib/admin_it.rb +19 -0
- data/lib/extend_it/array_of.rb +181 -0
- data/lib/extend_it/asserts.rb +38 -0
- data/lib/extend_it/callbacks.rb +105 -0
- data/lib/extend_it/caller.rb +35 -0
- data/lib/extend_it/class.rb +47 -0
- data/lib/extend_it/dsl.rb +94 -0
- data/lib/extend_it/refines.rb +6 -0
- data/lib/extend_it/symbolize.rb +39 -0
- data/lib/extend_it.rb +5 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +3 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/context/collection_context_spec.rb +20 -0
- data/spec/lib/context/context_spec.rb +28 -0
- data/spec/lib/context/single_context_spec.rb +26 -0
- data/spec/lib/data/object_spec.rb +29 -0
- data/spec/lib/definitions_spec.rb +171 -0
- data/spec/lib/field_spec.rb +62 -0
- data/spec/lib/resource_spec.rb +39 -0
- data/spec/lib/utils_spec.rb +39 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/example_groups/context_example_group.rb +50 -0
- data/spec/support/shared_examples/context.rb +2 -0
- metadata +337 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Helpers
|
3
|
+
class Field < WrapIt::Base
|
4
|
+
include WrapIt::TextContainer
|
5
|
+
attr_accessor :field, :context
|
6
|
+
option :field
|
7
|
+
option :context
|
8
|
+
argument :field, if: AdminIt::Field
|
9
|
+
argument :context, if: AdminIt::Context
|
10
|
+
|
11
|
+
before_capture do
|
12
|
+
unless context.is_a?(AdminIt::Context)
|
13
|
+
self.context = @template.context
|
14
|
+
end
|
15
|
+
if field.is_a?(AdminIt::Field)
|
16
|
+
entity = context.entity
|
17
|
+
field.render(entity, instance: self)
|
18
|
+
body << field.show(entity).to_s if body.empty?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
register :field, Field
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Helpers
|
3
|
+
class Input < WrapIt::Base
|
4
|
+
html_class 'form-control'
|
5
|
+
attr_accessor :field, :entity
|
6
|
+
option :field, :entity
|
7
|
+
argument :field, if: AdminIt::Field
|
8
|
+
|
9
|
+
before_capture do
|
10
|
+
html_attr[:type] = 'text'
|
11
|
+
if field.is_a?(AdminIt::Field)
|
12
|
+
context = @template.context
|
13
|
+
resource = context.resource
|
14
|
+
entity ||= context.entity
|
15
|
+
html_attr[:name] = "#{resource.name}[#{field.name}]"
|
16
|
+
html_attr[:id] = "#{resource.name}_#{field.name}"
|
17
|
+
html_attr[:value] = field.render(entity, instance: self)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Helpers
|
3
|
+
class Page < WrapIt::Container
|
4
|
+
default_tag 'body'
|
5
|
+
|
6
|
+
child :create_top_menu, TopMenu
|
7
|
+
child :create_toolbar, Toolbar
|
8
|
+
|
9
|
+
def top_menu
|
10
|
+
children.find { |item| item.is_a?(TopMenu) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def toolbar
|
14
|
+
children.find { |item| item.is_a?(Toolbar) }
|
15
|
+
end
|
16
|
+
|
17
|
+
after_initialize { self.deffered_render = true }
|
18
|
+
|
19
|
+
before_capture do
|
20
|
+
html_attr[:style] = 'padding-top: 70px;'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
register :body, Page
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Helpers
|
3
|
+
class Cell < WrapIt::Base
|
4
|
+
include WrapIt::TextContainer
|
5
|
+
default_tag 'td'
|
6
|
+
attr_accessor :column
|
7
|
+
option :column
|
8
|
+
|
9
|
+
before_capture do
|
10
|
+
unless column.nil?
|
11
|
+
col = parent.parent.context.field(column)
|
12
|
+
unless col.nil?
|
13
|
+
col.render(parent.parent.context.entity, instance: self)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ActionsCell < WrapIt::Base
|
20
|
+
default_tag 'td'
|
21
|
+
|
22
|
+
before_capture do
|
23
|
+
single = parent.parent.resource.singles.select { |c| !(c <= NewContext) }
|
24
|
+
buttons = single.map do |context|
|
25
|
+
cl = context <= ShowContext ? 'info' : 'default'
|
26
|
+
href = context.path(parent.parent.context.entity)
|
27
|
+
"<a class=\"btn btn-xs btn-#{cl}\" href=\"#{href}\">" \
|
28
|
+
"<i class=\"fa fa-#{context.icon}\"></i></a>"
|
29
|
+
end
|
30
|
+
show = single.first { |c| c <= ShowContext }
|
31
|
+
unless show.nil?
|
32
|
+
buttons << @template.link_to(
|
33
|
+
html_safe('<i class="fa fa-trash-o"></i>'),
|
34
|
+
show.path(parent.parent.context.entity),
|
35
|
+
method: :delete,
|
36
|
+
class: 'btn btn-xs btn-danger'
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
html = buttons.join
|
41
|
+
html = "<div class=\"btn-group\">#{html}</dic>" if buttons.size > 1
|
42
|
+
|
43
|
+
self[:content] = html_safe(html)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Header < WrapIt::Container
|
48
|
+
default_tag 'tr'
|
49
|
+
child :cell, Cell, tag: 'th'
|
50
|
+
end
|
51
|
+
|
52
|
+
class Row < WrapIt::Container
|
53
|
+
default_tag 'tr'
|
54
|
+
child :cell, Cell
|
55
|
+
child :actions, ActionsCell
|
56
|
+
|
57
|
+
before_capture do
|
58
|
+
block = parent.context.class.row
|
59
|
+
unless block.nil?
|
60
|
+
instance_exec(parent.context.entity, &block)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Table < WrapIt::Container
|
66
|
+
default_tag 'table'
|
67
|
+
html_class %w(table)
|
68
|
+
attr_writer :context
|
69
|
+
argument :context, if: AdminIt::Context
|
70
|
+
|
71
|
+
def context
|
72
|
+
@context ||= @template.context
|
73
|
+
end
|
74
|
+
|
75
|
+
def resource
|
76
|
+
context.resource
|
77
|
+
end
|
78
|
+
|
79
|
+
child :header, Header
|
80
|
+
child :row, Row
|
81
|
+
end
|
82
|
+
|
83
|
+
register :table, Table
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Helpers
|
3
|
+
class TileHeader < WrapIt::Base
|
4
|
+
include WrapIt::TextContainer
|
5
|
+
default_tag 'h4'
|
6
|
+
|
7
|
+
before_capture do
|
8
|
+
field = @template.context.field(@template.context.header)
|
9
|
+
unless field.nil?
|
10
|
+
field.render(@template.context.entity, instance: self)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
register :tile_header, TileHeader
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Helpers
|
3
|
+
class ToolbarItem < WrapIt::Link
|
4
|
+
attr_accessor :icon, :add_class, :add_data
|
5
|
+
option :icon
|
6
|
+
option :add_class
|
7
|
+
option :add_data
|
8
|
+
section :icon
|
9
|
+
place :icon, before: :body
|
10
|
+
|
11
|
+
before_capture do
|
12
|
+
unless icon.nil?
|
13
|
+
self[:icon] << html_safe("<i class=\"fa fa-#{icon}\"></i> ")
|
14
|
+
end
|
15
|
+
html_class << add_class
|
16
|
+
html_data.merge!(add_data) if add_data.is_a?(Hash)
|
17
|
+
# options = { tag: 'li' }
|
18
|
+
# options[:class] = 'active' if resource == @template.resource
|
19
|
+
# wrap(options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class ToolbarButtons < WrapIt::Container
|
24
|
+
html_class 'btn-group'
|
25
|
+
child :button, ToolbarItem, class: 'btn navbar-btn'
|
26
|
+
end
|
27
|
+
|
28
|
+
class Toolbar < WrapIt::Container
|
29
|
+
default_tag 'nav'
|
30
|
+
html_class 'navbar'
|
31
|
+
child :item, ToolbarItem
|
32
|
+
child :button, ToolbarItem, class: 'btn navbar-btn'
|
33
|
+
child :buttons, ToolbarButtons
|
34
|
+
|
35
|
+
after_initialize { self.deffered_render = true }
|
36
|
+
end
|
37
|
+
|
38
|
+
register :toolbar, Toolbar
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Helpers
|
3
|
+
class TopMenuItem < WrapIt::Link
|
4
|
+
attr_accessor :resource
|
5
|
+
option :resource
|
6
|
+
|
7
|
+
before_capture do
|
8
|
+
unless resource.icon.nil?
|
9
|
+
body << html_safe("<i class=\"fa fa-#{resource.icon}\"></i> ")
|
10
|
+
end
|
11
|
+
body << resource.display_name
|
12
|
+
self.link = @template.url_for(
|
13
|
+
controller: resource.name,
|
14
|
+
action: resource.default_context
|
15
|
+
)
|
16
|
+
options = { tag: 'li' }
|
17
|
+
options[:class] = 'active' if resource == @template.resource
|
18
|
+
wrap(options)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class TopMenu < WrapIt::Container
|
23
|
+
default_tag 'ul'
|
24
|
+
html_class 'nav'
|
25
|
+
child :item, TopMenuItem
|
26
|
+
|
27
|
+
after_initialize { self.deffered_render = true }
|
28
|
+
|
29
|
+
before_capture do
|
30
|
+
AdminIt.resources.each do |name, resource|
|
31
|
+
next unless resource.menu == true
|
32
|
+
item(resource: resource)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
register :top_menu, TopMenu
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'wrap_it'
|
2
|
+
|
3
|
+
module AdminIt
|
4
|
+
module Helpers; end
|
5
|
+
WrapIt.register_module Helpers
|
6
|
+
end
|
7
|
+
|
8
|
+
require File.join %w(admin_it helpers field)
|
9
|
+
require File.join %w(admin_it helpers top_menu)
|
10
|
+
require File.join %w(admin_it helpers toolbar)
|
11
|
+
require File.join %w(admin_it helpers table)
|
12
|
+
require File.join %w(admin_it helpers tiles)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
en:
|
2
|
+
admin_it:
|
3
|
+
collection:
|
4
|
+
no_data: 'No data'
|
5
|
+
relation:
|
6
|
+
no_resource: 'Resource for displaying property is not defined'
|
7
|
+
no_context: 'Context for displaying property is not defined'
|
8
|
+
section:
|
9
|
+
general: 'General properties'
|
10
|
+
action:
|
11
|
+
create: 'Create'
|
12
|
+
save: 'Save'
|
13
|
+
close: 'Close'
|
14
|
+
filters: 'FIlters'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
ru:
|
2
|
+
admin_it:
|
3
|
+
collection:
|
4
|
+
no_data: 'Нет данных'
|
5
|
+
relation:
|
6
|
+
no_resource: 'Не определён ресурс для отображения свойства'
|
7
|
+
no_context: 'Не определён контекст для отображения свойства'
|
8
|
+
section:
|
9
|
+
general: 'Основные свойства'
|
10
|
+
action:
|
11
|
+
create: 'Создать'
|
12
|
+
save: 'Сохранить'
|
13
|
+
close: 'Закрыть'
|
14
|
+
filters: 'Фильтры'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Renderable
|
3
|
+
def render(entity = nil, instance = nil, &block)
|
4
|
+
if entity.nil? && instance.nil?
|
5
|
+
# method used as setter - just save block
|
6
|
+
@renderer = block if block_given?
|
7
|
+
elsif !@renderer.nil?
|
8
|
+
# method used as event emmiter, call block in instance or caller
|
9
|
+
# context if it present
|
10
|
+
if instance.nil?
|
11
|
+
@renderer.call(entity)
|
12
|
+
else
|
13
|
+
instance.instance_exec(entity, &@renderer)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,292 @@
|
|
1
|
+
require File.join %w(extend_it symbolize)
|
2
|
+
require File.join %w(extend_it asserts)
|
3
|
+
require File.join %w(extend_it callbacks)
|
4
|
+
require File.join %w(extend_it class)
|
5
|
+
|
6
|
+
using ExtendIt::Symbolize
|
7
|
+
|
8
|
+
module AdminIt
|
9
|
+
module FieldsHolder
|
10
|
+
def fields(scope: :visible)
|
11
|
+
case scope
|
12
|
+
when nil, :all then @fields.values
|
13
|
+
when :visible then @fields.values.select { |f| f.visible? }
|
14
|
+
when :hidden then @fields.values.select { |f| !f.visible? }
|
15
|
+
when :readable then @fields.values.select { |f| f.readable? }
|
16
|
+
when :writable then @fields.values.select { |f| f.writable? }
|
17
|
+
when :sortable then @fields.values.select { |f| f.sortable? }
|
18
|
+
when Field::TYPES then @fields.values.select { |f| f.type == scope }
|
19
|
+
else @fields.values
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def hide_fields(*names)
|
24
|
+
names.ensure_symbols.each do |name|
|
25
|
+
@fields[name].hide if @fields.key?(name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_fields(*names)
|
30
|
+
names.ensure_symbols.each do |name|
|
31
|
+
@fields[name].show if @fields.key?(name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module FiltersHolder
|
37
|
+
def filters(scope: :all)
|
38
|
+
@filters ||= {}
|
39
|
+
case scope
|
40
|
+
when nil, :all then @filters.values
|
41
|
+
else @filters.values
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Resource
|
47
|
+
extend ExtendIt::Class
|
48
|
+
extend ExtendIt::Dsl
|
49
|
+
include ExtendIt::Asserts
|
50
|
+
include ExtendIt::Callbacks
|
51
|
+
include FieldsHolder
|
52
|
+
include FiltersHolder
|
53
|
+
|
54
|
+
attr_reader :name, :plural, :entity_class, :menu
|
55
|
+
|
56
|
+
dsl_accessor :icon
|
57
|
+
dsl_use_hash :fields
|
58
|
+
|
59
|
+
define_callbacks :initialize
|
60
|
+
|
61
|
+
def initialize(
|
62
|
+
name,
|
63
|
+
entity_class = nil,
|
64
|
+
menu: true,
|
65
|
+
destroyable: true,
|
66
|
+
auto_filters: true
|
67
|
+
)
|
68
|
+
assert_symbol(:name)
|
69
|
+
|
70
|
+
@name, @entity_class = name, entity_class
|
71
|
+
if @entity_class.nil?
|
72
|
+
begin
|
73
|
+
@entity_class = Object.const_get(name.to_s.camelize) # !PORTABLE
|
74
|
+
rescue NameError
|
75
|
+
fail ArgumentError, "Can't find entity class for #{name}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
import_data_module
|
80
|
+
|
81
|
+
run_callbacks :initialize do
|
82
|
+
@fields = Hash[default_fields.map { |f| [f.field_name, f] }]
|
83
|
+
|
84
|
+
@filters =
|
85
|
+
if auto_filters
|
86
|
+
Hash[default_filters.map { |f| [f.filter_name, f] }]
|
87
|
+
else
|
88
|
+
{}
|
89
|
+
end
|
90
|
+
|
91
|
+
@contexts = Hash[default_contexts.map { |c| [c.context_name, c] }]
|
92
|
+
|
93
|
+
@menu = menu == true
|
94
|
+
@destroyable = destroyable == true
|
95
|
+
@plural = name.to_s.pluralize # !POTABLE
|
96
|
+
@default_context = nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def field(*names, field_class: nil, &block)
|
101
|
+
names.ensure_symbols.each do |name|
|
102
|
+
if @fields.key?(name)
|
103
|
+
field = @fields[name]
|
104
|
+
else
|
105
|
+
field_class = Field if field_class.nil? || !field_class <= Field
|
106
|
+
field = @fields[name] = field_class.create(name, entity_class)
|
107
|
+
end
|
108
|
+
field.instance_eval(&block) if block_given?
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def [](name)
|
113
|
+
assert_symbol(:name)
|
114
|
+
@contexts[name]
|
115
|
+
end
|
116
|
+
|
117
|
+
def context(*names, context_class: nil, &block)
|
118
|
+
names.ensure_symbols.each do |name|
|
119
|
+
if @contexts.key?(name)
|
120
|
+
context = @contexts[name]
|
121
|
+
else
|
122
|
+
if context_class.nil? || !context_class <= Context
|
123
|
+
context_class = Context
|
124
|
+
end
|
125
|
+
context = @contexts[name] = context_class.create(name, entity_class)
|
126
|
+
end
|
127
|
+
context.instance_eval(&block) if block_given?
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def contexts
|
132
|
+
@contexts.values
|
133
|
+
end
|
134
|
+
|
135
|
+
dsl_use_hash :contexts
|
136
|
+
|
137
|
+
def filter(name, filter_class: nil, &block)
|
138
|
+
assert_symbol(:name)
|
139
|
+
filter = @filters[name]
|
140
|
+
if filter.nil?
|
141
|
+
filter_class = Filter if filter_class.nil? || !filter_class <= Filter
|
142
|
+
filter = @filters[name] = filter_class.create(name, self)
|
143
|
+
end
|
144
|
+
filter.instance_eval(&block) if block_given?
|
145
|
+
end
|
146
|
+
|
147
|
+
dsl_use_hash :filters
|
148
|
+
|
149
|
+
def collection(&block)
|
150
|
+
return unless block_given?
|
151
|
+
contexts.select { |c| c.collection? }.each do |c|
|
152
|
+
c.instance_eval(&block)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def single(&block)
|
157
|
+
return unless block_given?
|
158
|
+
contexts.select { |c| c.single? }.each do |c|
|
159
|
+
c.instance_eval(&block)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def default_context(value = nil)
|
164
|
+
if value.nil?
|
165
|
+
return @default_context unless @default_context.nil?
|
166
|
+
if collections.size > 0
|
167
|
+
@default_context = collections.first.context_name
|
168
|
+
elsif singles.size > 0
|
169
|
+
@default_context = singles.first.context_name
|
170
|
+
end
|
171
|
+
else
|
172
|
+
@default_context = @contexts.keys.include?(value) ? value : default_context
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def contexts_names
|
177
|
+
@contexts.map(&:context_name)
|
178
|
+
end
|
179
|
+
|
180
|
+
def display_name
|
181
|
+
plural.split('_').map { |s| s.capitalize }.join(' ')
|
182
|
+
end
|
183
|
+
|
184
|
+
def destroyable?
|
185
|
+
@destroyable
|
186
|
+
end
|
187
|
+
|
188
|
+
def collection_path
|
189
|
+
AdminIt::Engine.routes.url_helpers.send("#{plural}_path")
|
190
|
+
end
|
191
|
+
|
192
|
+
def single_path(entity)
|
193
|
+
AdminIt::Engine.routes.url_helpers.send("#{name}_path", entity)
|
194
|
+
end
|
195
|
+
|
196
|
+
def collections
|
197
|
+
contexts.select { |c| c.collection? }
|
198
|
+
end
|
199
|
+
|
200
|
+
def singles
|
201
|
+
contexts.select { |c| c.single? }
|
202
|
+
end
|
203
|
+
|
204
|
+
def define_controller
|
205
|
+
c_name = "#{name.to_s.camelize}Controller" # !POTABLE
|
206
|
+
resource = self
|
207
|
+
c_class = Class.new(AdminIt.config.controller) do
|
208
|
+
@resource = resource
|
209
|
+
include AdminIt::Controller
|
210
|
+
|
211
|
+
resource.contexts.each do |_context|
|
212
|
+
define_method(_context.context_name) { load_context(_context) }
|
213
|
+
|
214
|
+
if _context < SavableSingleContext
|
215
|
+
define_method _context.save_action do
|
216
|
+
load_context(_context) { context.save_entity(self) }
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
if resource.destroyable?
|
222
|
+
define_method :destroy do
|
223
|
+
load_context(resource[:show]) { context.destroy_entity(self) }
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
AdminIt.const_set(c_name, c_class)
|
228
|
+
contexts.each { |c| c.controller_class = c_class }
|
229
|
+
end
|
230
|
+
|
231
|
+
protected
|
232
|
+
|
233
|
+
# LAYOUTS = %w(content)
|
234
|
+
COLLECTIONS = %i(table tiles list)
|
235
|
+
SINGLE = %i(show new edit)
|
236
|
+
CONTEXTS = COLLECTIONS + SINGLE
|
237
|
+
|
238
|
+
def sanitize_entity_class
|
239
|
+
@entity_class = @name.to_s.camelize if @entity_class.nil? # !PORTABLE
|
240
|
+
if @entity_class.is_a?(Symbol)
|
241
|
+
@entity_class = @entity_class.to_s.camelize # !PORTABLE
|
242
|
+
end
|
243
|
+
if @entity_class.is_a?(String)
|
244
|
+
begin
|
245
|
+
@entity_class = Object.const_get(@entity_class)
|
246
|
+
rescue NameError
|
247
|
+
@entity_class = Object
|
248
|
+
end
|
249
|
+
end
|
250
|
+
unless @entity_class.is_a?(Class)
|
251
|
+
fail ArgumentError, 'Wrong entity class'
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def default_fields
|
256
|
+
[]
|
257
|
+
end
|
258
|
+
|
259
|
+
def default_contexts
|
260
|
+
CONTEXTS.map do |c|
|
261
|
+
context_class = AdminIt.const_get("#{c.capitalize}Context")
|
262
|
+
context_class.create(c, self)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def default_filters
|
267
|
+
[]
|
268
|
+
end
|
269
|
+
|
270
|
+
private
|
271
|
+
|
272
|
+
def import_data_module
|
273
|
+
data_module = AdminIt.data_module(entity_class)
|
274
|
+
return unless data_module.is_a?(Module)
|
275
|
+
resource_module = data_module.const_get(:Resource)
|
276
|
+
extend(resource_module) if resource_module.is_a?(Module)
|
277
|
+
rescue NameError
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def self.resource(name, entity_class = nil, **opts, &block)
|
282
|
+
_resource = Resource.new(name, entity_class, **opts)
|
283
|
+
_resource.instance_eval(&block) if block_given?
|
284
|
+
_resource.define_controller
|
285
|
+
@resources ||= {}
|
286
|
+
@resources[_resource.name] = _resource
|
287
|
+
end
|
288
|
+
|
289
|
+
def self.resources
|
290
|
+
@resources ||= {}
|
291
|
+
end
|
292
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module AdminIt
|
2
|
+
module Utils
|
3
|
+
def self.assert_symbol_arg!(arg, name = nil)
|
4
|
+
assert_symbol_arg(arg) do
|
5
|
+
_caller = caller_locations(3, 1).first
|
6
|
+
name = "#{name} " unless name.nil?
|
7
|
+
fail(
|
8
|
+
ArgumentError,
|
9
|
+
"Argument #{name}for #{_caller.label} should be a String or Symbol",
|
10
|
+
caller[3..-1]
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.assert_symbol_arg(arg)
|
16
|
+
return arg if arg.is_a?(Symbol)
|
17
|
+
return arg.to_sym if arg.is_a?(String)
|
18
|
+
yield arg if block_given?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/admin_it.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#require 'extend_it'
|
2
|
+
#module AdminIt
|
3
|
+
# using ExtendIt::Refines
|
4
|
+
#end
|
5
|
+
|
6
|
+
require File.join %w(admin_it env)
|
7
|
+
require File.join %w(admin_it errors)
|
8
|
+
require File.join %w(admin_it utils)
|
9
|
+
require File.join %w(admin_it config)
|
10
|
+
require File.join %w(admin_it renderable)
|
11
|
+
require File.join %w(admin_it data)
|
12
|
+
require File.join %w(admin_it field)
|
13
|
+
require File.join %w(admin_it filters)
|
14
|
+
require File.join %w(admin_it resource)
|
15
|
+
require File.join %w(admin_it context)
|
16
|
+
require File.join %w(admin_it controller)
|
17
|
+
require File.join %w(admin_it definitions)
|
18
|
+
require File.join %w(admin_it engine)
|
19
|
+
require File.join %w(admin_it helpers)
|