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.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +5 -0
  5. data/.yardopts +3 -0
  6. data/Gemfile +5 -0
  7. data/README.md +58 -0
  8. data/README_RU.md +52 -0
  9. data/Rakefile +23 -0
  10. data/admin_it.gemspec +38 -0
  11. data/app/assets/fonts/admin_it/FontAwesome.otf +0 -0
  12. data/app/assets/fonts/admin_it/fontawesome-webfont.eot +0 -0
  13. data/app/assets/fonts/admin_it/fontawesome-webfont.svg +414 -0
  14. data/app/assets/fonts/admin_it/fontawesome-webfont.ttf +0 -0
  15. data/app/assets/fonts/admin_it/fontawesome-webfont.woff +0 -0
  16. data/app/assets/fonts/admin_it/glyphicons-halflings-regular.eot +0 -0
  17. data/app/assets/fonts/admin_it/glyphicons-halflings-regular.svg +229 -0
  18. data/app/assets/fonts/admin_it/glyphicons-halflings-regular.ttf +0 -0
  19. data/app/assets/fonts/admin_it/glyphicons-halflings-regular.woff +0 -0
  20. data/app/assets/javascript/admin_it/admin_it.js +89 -0
  21. data/app/assets/javascript/admin_it/bootstrap.min.js +6 -0
  22. data/app/assets/stylesheets/admin_it/admin_it.css +25 -0
  23. data/app/assets/stylesheets/admin_it/bootstrap-theme.min.css +7 -0
  24. data/app/assets/stylesheets/admin_it/bootstrap.min.css +7 -0
  25. data/app/assets/stylesheets/admin_it/font-awesome.min.css +4 -0
  26. data/app/views/admin_it/context/_table.html.slim +38 -0
  27. data/app/views/admin_it/context/_tiles.html.slim +23 -0
  28. data/app/views/admin_it/edit.html.slim +2 -0
  29. data/app/views/admin_it/new.html.slim +2 -0
  30. data/app/views/admin_it/shared/_child.html.slim +15 -0
  31. data/app/views/admin_it/shared/_fields.html.slim +19 -0
  32. data/app/views/admin_it/shared/_filters.html.slim +40 -0
  33. data/app/views/admin_it/shared/_form.html.slim +50 -0
  34. data/app/views/admin_it/shared/_pagination.html.slim +41 -0
  35. data/app/views/admin_it/shared/_toolbar.html.slim +30 -0
  36. data/app/views/admin_it/show.html.slim +6 -0
  37. data/app/views/admin_it/table.html.slim +2 -0
  38. data/app/views/admin_it/tiles.html.slim +2 -0
  39. data/app/views/layouts/admin_it.html.slim +37 -0
  40. data/app/views/layouts/admin_it_dialog.html.slim +8 -0
  41. data/config.ru +7 -0
  42. data/lib/admin_it/config.rb +24 -0
  43. data/lib/admin_it/context/collection_context.rb +239 -0
  44. data/lib/admin_it/context/context.rb +232 -0
  45. data/lib/admin_it/context/show_context.rb +45 -0
  46. data/lib/admin_it/context/single_context.rb +199 -0
  47. data/lib/admin_it/context/table_context.rb +66 -0
  48. data/lib/admin_it/context/tiles_context.rb +31 -0
  49. data/lib/admin_it/context.rb +6 -0
  50. data/lib/admin_it/controller.rb +42 -0
  51. data/lib/admin_it/data/active_record.rb +283 -0
  52. data/lib/admin_it/data/data_behavior.rb +18 -0
  53. data/lib/admin_it/data/hash.rb +27 -0
  54. data/lib/admin_it/data/object.rb +51 -0
  55. data/lib/admin_it/data.rb +24 -0
  56. data/lib/admin_it/definitions.rb +89 -0
  57. data/lib/admin_it/engine.rb +56 -0
  58. data/lib/admin_it/env.rb +37 -0
  59. data/lib/admin_it/errors.rb +5 -0
  60. data/lib/admin_it/field/field.rb +174 -0
  61. data/lib/admin_it/field.rb +1 -0
  62. data/lib/admin_it/filters/entity_filter.rb +4 -0
  63. data/lib/admin_it/filters/field_filter.rb +31 -0
  64. data/lib/admin_it/filters/filter.rb +150 -0
  65. data/lib/admin_it/filters/value_filter.rb +52 -0
  66. data/lib/admin_it/filters.rb +4 -0
  67. data/lib/admin_it/helpers/field.rb +25 -0
  68. data/lib/admin_it/helpers/input.rb +22 -0
  69. data/lib/admin_it/helpers/page.rb +26 -0
  70. data/lib/admin_it/helpers/table.rb +85 -0
  71. data/lib/admin_it/helpers/tiles.rb +17 -0
  72. data/lib/admin_it/helpers/toolbar.rb +40 -0
  73. data/lib/admin_it/helpers/top_menu.rb +39 -0
  74. data/lib/admin_it/helpers.rb +12 -0
  75. data/lib/admin_it/locales/en.yml +14 -0
  76. data/lib/admin_it/locales/ru.yml +14 -0
  77. data/lib/admin_it/renderable.rb +18 -0
  78. data/lib/admin_it/resource.rb +292 -0
  79. data/lib/admin_it/utils.rb +21 -0
  80. data/lib/admin_it/version.rb +5 -0
  81. data/lib/admin_it.rb +19 -0
  82. data/lib/extend_it/array_of.rb +181 -0
  83. data/lib/extend_it/asserts.rb +38 -0
  84. data/lib/extend_it/callbacks.rb +105 -0
  85. data/lib/extend_it/caller.rb +35 -0
  86. data/lib/extend_it/class.rb +47 -0
  87. data/lib/extend_it/dsl.rb +94 -0
  88. data/lib/extend_it/refines.rb +6 -0
  89. data/lib/extend_it/symbolize.rb +39 -0
  90. data/lib/extend_it.rb +5 -0
  91. data/spec/internal/config/database.yml +3 -0
  92. data/spec/internal/config/routes.rb +3 -0
  93. data/spec/internal/db/combustion_test.sqlite +0 -0
  94. data/spec/internal/db/schema.rb +3 -0
  95. data/spec/internal/log/.gitignore +1 -0
  96. data/spec/internal/public/favicon.ico +0 -0
  97. data/spec/lib/context/collection_context_spec.rb +20 -0
  98. data/spec/lib/context/context_spec.rb +28 -0
  99. data/spec/lib/context/single_context_spec.rb +26 -0
  100. data/spec/lib/data/object_spec.rb +29 -0
  101. data/spec/lib/definitions_spec.rb +171 -0
  102. data/spec/lib/field_spec.rb +62 -0
  103. data/spec/lib/resource_spec.rb +39 -0
  104. data/spec/lib/utils_spec.rb +39 -0
  105. data/spec/spec_helper.rb +21 -0
  106. data/spec/support/example_groups/context_example_group.rb +50 -0
  107. data/spec/support/shared_examples/context.rb +2 -0
  108. metadata +337 -0
@@ -0,0 +1,37 @@
1
+ doctype html
2
+ html
3
+ head
4
+ title Admin
5
+ meta charset="utf-8"
6
+ = csrf_meta_tags
7
+
8
+ = stylesheet_link_tag 'admin_it/bootstrap.min', \
9
+ media: 'all', \
10
+ 'data-turbolinks-track' => true
11
+ = stylesheet_link_tag 'admin_it/font-awesome.min', \
12
+ media: 'all', \
13
+ 'data-turbolinks-track' => true
14
+ = stylesheet_link_tag 'admin_it/admin_it', \
15
+ media: 'all', \
16
+ 'data-turbolinks-track' => true
17
+ = javascript_include_tag 'jquery', 'jquery_ujs', 'turbolinks'
18
+ = javascript_include_tag 'admin_it/bootstrap.min', \
19
+ 'data-turbolinks-track' => true
20
+ = javascript_include_tag 'admin_it/admin_it'
21
+
22
+ - html = capture do
23
+ body style="padding-top: 70px"
24
+ nav class="navbar navbar-fixed-top navbar-inverse" role="navigation"
25
+ div class="container"
26
+ <!-- top-menu -->
27
+
28
+ div class="container"
29
+ = render File.join(%w(admin_it shared toolbar))
30
+ = render File.join(%w(admin_it shared filters))
31
+ = yield
32
+
33
+ - top_menu_html = capture { context.top_menu.render }
34
+ - toolbar_html = capture { context.toolbar.render }
35
+ = html.gsub('<!-- top-menu -->', top_menu_html) \
36
+ .gsub('<!-- toolbar -->', toolbar_html) \
37
+ .html_safe
@@ -0,0 +1,8 @@
1
+ div class="modal-header"
2
+ h4.modal-title title
3
+ div class="modal-body"
4
+ = yield
5
+ div class="modal-footer"
6
+ button type="button" class="btn btn-default" data-dismiss="modal"
7
+ = t('admin_it.action.close')
8
+ = yield :buttons
data/config.ru ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require :default, :development
5
+
6
+ Combustion.initialize!
7
+ run Combustion::Application
@@ -0,0 +1,24 @@
1
+ module AdminIt
2
+ module Config
3
+ def self.root
4
+ @root ||= Rails.root.join('app', 'admin_it')
5
+ end
6
+
7
+ def self.root=(value)
8
+ value = File.expand_path(value, Rails.root)
9
+ fail ArgumentError unless File.directory?(value)
10
+ @root = value
11
+ end
12
+
13
+ def self.controller
14
+ @controller ||= ActionController::Base
15
+ end
16
+
17
+ def self.controller=(value)
18
+ unless value <= ActionController::Base
19
+ fail ArgumentError, 'Wrong controller'
20
+ end
21
+ @controller = value
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,239 @@
1
+ require 'json'
2
+ require File.join %w(extend_it symbolize)
3
+
4
+ using ExtendIt::Symbolize
5
+
6
+ module AdminIt
7
+ class CollectionContext < Context
8
+ extend FiltersHolder
9
+
10
+ @entities_getter = nil
11
+
12
+ class << self
13
+ dsl_block :entities
14
+ dsl_accessor :default_sorting
15
+ dsl_use_hash :filters
16
+ end
17
+
18
+ def self.before_configure
19
+ return if resource.nil?
20
+ visible = fields(scope: :visible).map(&:field_name)
21
+ @filters = Hash[
22
+ resource.filters
23
+ .select { |f| f <= FieldFilter }
24
+ .select { |f| visible.include?(f.field.field_name) }
25
+ .map { |f| [f.filter_name, f] }
26
+ ]
27
+ end
28
+
29
+ def self.filter(name, filter_class: nil, &block)
30
+ assert_symbol(:name)
31
+ if @filters.key?(name)
32
+ filter = @filters[name] = Class.new(@filters[name]) if block_given?
33
+ else
34
+ filter_class = Filter if filter_class.nil? || !filter_class <= Filter
35
+ filter = @filters[name] = filter_class.create(name, self)
36
+ end
37
+ filter.instance_eval(&block) if block_given?
38
+ end
39
+
40
+ def self.entities_getter
41
+ @entities
42
+ end
43
+
44
+ def self.collection?
45
+ true
46
+ end
47
+
48
+ def self.path
49
+ AdminIt::Engine.routes.url_helpers.send("#{resource.plural}_path")
50
+ end
51
+
52
+ def self.sortable_fields(*names)
53
+ names = names.ensure_symbols
54
+ fields.each do |_field|
55
+ _field.sortable = names.include?(_field.field_name)
56
+ end
57
+ end
58
+
59
+ attr_accessor :entity
60
+ class_attr_reader :entities_getter, :path
61
+
62
+ before_load do |store: {}, params: {}|
63
+ self.sorting = store[:sorting] || self.class.default_sorting
64
+ self.sorting = params[:sorting] if params.key?(:sorting)
65
+ self.filters = store[:filters] || []
66
+ self.filters = params[:filters] if params.key?(:filters)
67
+ end
68
+
69
+ after_load do |store: {}, params: {}|
70
+ self.active_filter = params[:active_filter] || store[:active_filter]
71
+ end
72
+
73
+ before_save do |params: {}|
74
+ params.merge!(sorting: sorting.join(';'))
75
+ params.merge!(filters: filters.map { |f| f.dump }.join(';'))
76
+ unless active_filter.nil?
77
+ params.merge!(active_filter: active_filter.name.to_s)
78
+ end
79
+ end
80
+
81
+ def sorting
82
+ return @sorting unless @sorting.nil?
83
+ self.sorting = self.class.default_sorting
84
+ end
85
+
86
+ def sorting=(value)
87
+ value = value.to_s if value.is_a?(Symbol)
88
+ if value.is_a?(Array)
89
+ @sorting = value
90
+ elsif value.is_a?(String) && !value.empty?
91
+ @sorting = [] unless /\W[+\-]\w/ =~ value
92
+ @sorting ||= []
93
+ sortable = self.class.fields(scope: :sortable).map(&:field_name)
94
+ value.split(/[;,|]/).each do |sort|
95
+ sort.strip!
96
+ if sort[0] == '-'
97
+ sort = sort[1..-1] + ':'
98
+ @sorting.delete_if { |s| s.index(sort) == 0 }
99
+ else
100
+ sort = sort[1..-1] if sort[0] == '+'
101
+ sort, order = sort.split(':')
102
+ order = 'asc' if order != 'desc'
103
+ sort = sort.to_sym
104
+ @sorting << "#{sort}:#{order}" if sortable.include?(sort)
105
+ end
106
+ end
107
+ else
108
+ @sorting = []
109
+ end
110
+ end
111
+
112
+ def all_filters
113
+ self.class.filters
114
+ end
115
+
116
+ def filters
117
+ (@filters ||= {}).values
118
+ end
119
+
120
+ def filters=(value)
121
+ if value.is_a?(Array)
122
+ @filters = Hash[
123
+ value.select { |f| f.is_a?(Filter) }.map { |f| [f.name, f] }
124
+ ]
125
+ elsif value.is_a?(Hash)
126
+ self.filters = value.values
127
+ elsif value.is_a?(String)
128
+ @filters ||= {}
129
+ value.strip!
130
+ @filters = {} if value.empty?
131
+ value.split(/[;|]/).each do |str|
132
+ str.strip!
133
+ remove = str[0] == '-'
134
+ str = str[1..-1] if remove
135
+ m = Filter::REGEXP.match(str)
136
+ next if m.nil?
137
+ if remove
138
+ @filters.delete(m[:name].to_sym)
139
+ else
140
+ name = m[:name].to_sym
141
+ if @filters.key?(name)
142
+ @filters[name].change(m[:params])
143
+ else
144
+ @filters[name] = Filter.load(str, self.class.filters)
145
+ end
146
+ end
147
+ end
148
+ else
149
+ @filters = {}
150
+ end
151
+ end
152
+
153
+ def active_filter
154
+ @active_filter ||= filters.empty? ? nil : filters.first
155
+ end
156
+
157
+ def active_filter=(value)
158
+ if value.nil?
159
+ active_filter
160
+ elsif value.is_a?(Class) && value <= Filter
161
+ @active_filter = value
162
+ elsif value.is_a?(String)
163
+ value = value.to_sym
164
+ @active_filter = filters.find { |f| f.name == value }
165
+ end
166
+ end
167
+
168
+ def sortable_fields
169
+ @sortable_fields ||= fields(scope: :sortable)
170
+ end
171
+
172
+ def sortable
173
+ @sortable ||= sortable_fields.map(&:name)
174
+ end
175
+
176
+ def load_context
177
+ collection =
178
+ if entities_getter.nil?
179
+ if controller.respond_to?("#{resource.name}_entities")
180
+ controller.send("#{resource.name}_entities", name)
181
+ elsif controller.respond_to?(:entities)
182
+ controller.entities(entity_class, name)
183
+ else
184
+ load_entities
185
+ end
186
+ else
187
+ entities_getter.call
188
+ end
189
+ filters.each do |filter|
190
+ collection = filter.apply(collection)
191
+ end
192
+ self.entities = collection
193
+ end
194
+
195
+ def entities=(value)
196
+ @entities = value
197
+ end
198
+
199
+ def entities
200
+ self.entity = nil
201
+ collection = self
202
+ @enumerator ||= Enumerator.new do |yielder|
203
+ @entities.each do |v|
204
+ collection.entity = v
205
+ yielder << v
206
+ end
207
+ collection.entity = nil
208
+ end
209
+ end
210
+
211
+ def count
212
+ return @count unless @count.nil?
213
+ # apply filters and limits first
214
+ entities if @enumerator.nil?
215
+ # if @count is not setted yet - calculate it
216
+ @count = entities.count
217
+ end
218
+
219
+ protected
220
+
221
+ def load_entities
222
+ []
223
+ end
224
+ end
225
+
226
+ class ListContext < CollectionContext
227
+ def self.path
228
+ AdminIt::Engine.routes.url_helpers.send("list_#{resource.plural}_path")
229
+ end
230
+
231
+ class << self
232
+ protected
233
+
234
+ def default_icon
235
+ 'bars'
236
+ end
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,232 @@
1
+ require 'uri'
2
+ require File.join %w(extend_it dsl)
3
+ require File.join %w(extend_it array_of)
4
+ require File.join %w(extend_it symbolize)
5
+
6
+ using ExtendIt::Symbolize
7
+
8
+ module AdminIt
9
+ class Context
10
+ extend ExtendIt::Class
11
+ extend ExtendIt::Dsl
12
+ include ExtendIt::Callbacks
13
+ extend DataBehavior
14
+ extend FieldsHolder
15
+
16
+ class << self
17
+ extend ExtendIt::Dsl
18
+
19
+ attr_reader :context_name
20
+ attr_accessor :controller_class
21
+
22
+ dsl_accessor :icon do |value|
23
+ value.nil? ? default_icon : value.to_s
24
+ end
25
+ dsl_use_hash :fields
26
+ end
27
+
28
+ inherited_class_reader :resource, :entity_class
29
+ define_callbacks :initialize, :load, :save
30
+
31
+ def self.create(context_name, _resource, &block)
32
+ fail ArgumentError, 'Wrong resource' unless _resource.is_a?(Resource)
33
+ base = self
34
+ Class.new(base) do
35
+ @resource = _resource
36
+ @context_name = context_name
37
+ @entity_class = @resource.entity_class
38
+
39
+ import_data_module(base)
40
+
41
+ @fields = Hash[
42
+ _resource.fields(scope: :all).map { |f| [f.field_name, f] }
43
+ ]
44
+
45
+ before_configure if respond_to?(:before_configure)
46
+ instance_eval(&block) if block_given?
47
+ after_configure if respond_to?(:after_configure)
48
+ end
49
+ end
50
+
51
+ def self.field(*names, field_class: nil, &block)
52
+ names.ensure_symbols.each do |name|
53
+ if @fields.key?(name)
54
+ field = @fields[name] = Class.new(@fields[name]) if block_given?
55
+ else
56
+ field_class = Field if field_class.nil? || !field_class <= Field
57
+ field = @fields[name] = field_class.create(name, entity_class)
58
+ end
59
+ field.instance_eval(&block) if block_given?
60
+ end
61
+ end
62
+
63
+ def self.collection?
64
+ false
65
+ end
66
+
67
+ def self.single?
68
+ false
69
+ end
70
+
71
+ def self.entity_path?
72
+ false
73
+ end
74
+
75
+ def self.url(context = nil, **params)
76
+ url = context.nil? ? path : context.path
77
+ params = context.nil? ? params : context.url_params(**params)
78
+ unless params.empty?
79
+ url << '?' << params.map { |k, v| "#{k}=#{v}" }.join('&')
80
+ url = URI.escape(url)
81
+ end
82
+ url
83
+ end
84
+
85
+ class << self
86
+ protected
87
+
88
+ def default_icon
89
+ ''
90
+ end
91
+ end
92
+
93
+ class_attr_reader :collection?, :single?, :entity_class, :resource, :icon,
94
+ :entity_path?
95
+ attr_reader :top_menu, :toolbar, :parent, :template, :controller
96
+
97
+ CONTEXT_REGEXP = /\A
98
+ (?<resource_name>[a-zA-Z_][a-zA-Z_0-9]*)\/
99
+ (?<context_name>[a-zA-Z_][a-zA-Z_0-9]*)
100
+ (\((?<identity_value>[a-zA-Z_0-9]+)\))?
101
+ \z/x
102
+
103
+ def initialize(from, params: nil, store: nil, parent_init: false)
104
+ run_callbacks :initialize do
105
+ if from.is_a?(self.class.controller_class)
106
+ @controller = from
107
+ elsif from.is_a?(Context)
108
+ @controller = from.controller
109
+ self.parent = from unless parent_init == true
110
+ params ||= {}
111
+ store ||= {}
112
+ end
113
+
114
+ @fields = self.class.fields(scope: :all).map { |f| f.new }
115
+
116
+ if store.nil?
117
+ session = controller.session
118
+ store = session[:admin_it] ||= {}
119
+ store = store[resource.name] ||= {}
120
+ store = store[name] ||= {}
121
+ end
122
+
123
+ if params.nil?
124
+ params = controller.request.query_parameters
125
+ end
126
+ params = Hash[params.map { |k, v| [k.to_sym, v] }]
127
+
128
+ run_callbacks :load, arguments: { params: params, store: store } do
129
+ load_context unless parent_init == true
130
+ end
131
+ end
132
+ end
133
+
134
+ after_load do |store: {}, params: {}|
135
+ self.layout = params[:layout] if params.key?(:layout)
136
+ if params.key?(:parent)
137
+ self.parent = params[:parent]
138
+ elsif store.key?(:parent)
139
+ self.parent = store[:parent]
140
+ end
141
+ end
142
+
143
+ def name
144
+ @name ||= self.class.context_name
145
+ end
146
+
147
+ def field(name)
148
+ @fields.find { |f| f.name == name }
149
+ end
150
+
151
+ def fields(scope: :visible)
152
+ case scope
153
+ when nil, :all then @fields
154
+ when :visible then @fields.select { |f| f.visible? }
155
+ when :hidden then @fields.select { |f| !f.visible? }
156
+ when :readable then @fields.select { |f| f.readable? }
157
+ when :writable then @fields.select { |f| f.writable? }
158
+ when Field::TYPES then @fields.select { |f| f.type == scope }
159
+ else @fields
160
+ end
161
+ end
162
+
163
+ def save(**params)
164
+ return if controller.nil?
165
+ session = controller.session
166
+ store = session[:admin_it] ||= {}
167
+ store = store[resource.name] ||= {}
168
+ run_callbacks :save, arguments: [{ params: params }] do
169
+ store[name] = params
170
+ end
171
+ end
172
+
173
+ def layout
174
+ @layout ||= ''
175
+ end
176
+
177
+ def layout=(value)
178
+ value = value.to_sym if value.is_a?(String)
179
+ return unless value.is_a?(Symbol)
180
+ @layout = case value
181
+ when :dialog then 'dialog'
182
+ else ''
183
+ end
184
+ end
185
+
186
+ def parent=(value)
187
+ return if value.nil?
188
+ if value.is_a?(Context)
189
+ @parent = value
190
+ elsif value.is_a?(String)
191
+ m = CONTEXT_REGEXP.match(value)
192
+ unless m.nil?
193
+ r = AdminIt.resources[m[:resource_name].downcase.to_sym]
194
+ return if r.nil?
195
+ c = r[m[:context_name].downcase.to_sym]
196
+ return if c.nil?
197
+ @parent = c.new(self, parent_init: true)
198
+ unless m[:identity_value].nil?
199
+ @parent.entity = @parent.load_entity(identity: m[:identity_value])
200
+ end
201
+ end
202
+ else
203
+ @parent = nil
204
+ end
205
+ end
206
+
207
+ def child?
208
+ parent.is_a?(Context)
209
+ end
210
+
211
+ def begin_render(template)
212
+ @template = template
213
+ @toolbar = Helpers::Toolbar.new(template)
214
+ @top_menu = Helpers::TopMenu.new(template, class: 'navbar-nav')
215
+ end
216
+
217
+ def url_params(**params)
218
+ unless @parent.nil?
219
+ params.merge!(parent: @parent.send(:context_param))
220
+ end
221
+ params
222
+ end
223
+
224
+ protected
225
+
226
+ def context_param
227
+ "#{resource.name}/#{name}"
228
+ end
229
+
230
+ def load_context; end
231
+ end
232
+ end
@@ -0,0 +1,45 @@
1
+ module AdminIt
2
+ class ShowContext < SingleContext
3
+ include Identifiable
4
+
5
+ class << self
6
+ include Renderable
7
+
8
+ protected
9
+
10
+ def default_icon
11
+ 'info-circle'
12
+ end
13
+ end
14
+
15
+ def self.entity_path?
16
+ true
17
+ end
18
+
19
+ def self.read(entity = nil, &block)
20
+ if entity.nil?
21
+ @reader = block if block_given?
22
+ elsif !@reader.nil?
23
+ @reader.call(entity)
24
+ end
25
+ end
26
+
27
+ def destroy_entity
28
+ if entity_destroyer.nil?
29
+ if controller.respond_to?("#{resource.name}_destroy")
30
+ controller.send("#{resource.name}_destroy")
31
+ elsif controller.respond_to?(:destroy_entity)
32
+ controller.destroy_entity(entity_class)
33
+ else
34
+ destroy
35
+ end
36
+ else
37
+ entity_destroyer.call(controller)
38
+ end
39
+ end
40
+
41
+ protected
42
+
43
+ def destroy; end
44
+ end
45
+ end