admin_it 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|