express_admin 1.4.6 → 1.4.7

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/app/components/express_admin/nav_bar_actions.rb +7 -0
  3. data/app/views/shared/express_admin/_navigation_bar.html.et +1 -1
  4. data/lib/express_admin/standard_actions.rb +139 -8
  5. data/lib/express_admin/version.rb +1 -1
  6. data/test/controllers/standard_controller_test.rb +17 -3
  7. data/test/dummy/app/controllers/admin/categories_controller.rb +5 -6
  8. data/test/dummy/app/controllers/admin/parts_controller.rb +11 -0
  9. data/test/dummy/app/controllers/admin/widgets_controller.rb +5 -6
  10. data/test/dummy/app/models/part.rb +3 -0
  11. data/test/dummy/app/models/widget.rb +1 -0
  12. data/test/dummy/app/views/admin/parts/index.html.et +8 -0
  13. data/test/dummy/app/views/admin/parts/show.html.et +3 -0
  14. data/test/dummy/app/views/admin/widgets/index.html.et +6 -8
  15. data/test/dummy/app/views/admin/widgets/show.html.et +3 -0
  16. data/test/dummy/config/menu.yml +2 -0
  17. data/test/dummy/config/routes.rb +6 -1
  18. data/test/dummy/db/migrate/20150812073447_create_parts.rb +10 -0
  19. data/test/dummy/db/schema.rb +8 -1
  20. data/test/dummy/db/test.sqlite3 +0 -0
  21. data/test/dummy/test/components/smart_form_test.rb +0 -5
  22. data/test/dummy/test/components/smart_table_test.rb +0 -1
  23. data/test/dummy/test/controllers/admin/parts_controller_test.rb +20 -0
  24. data/test/dummy/test/controllers/admin/widgets_controller_test.rb +20 -0
  25. data/test/dummy/test/fixtures/parts.yml +10 -0
  26. data/test/fixtures/parts.yml +10 -0
  27. data/test/generators_test_helper.rb +25 -6
  28. data/test/lib/generators/express_admin/install_generator_test.rb +47 -43
  29. data/vendor/gems/express_templates/Gemfile.lock +1 -1
  30. data/vendor/gems/express_templates/express_templates-0.9.6.gem +0 -0
  31. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/resourceful.rb +13 -5
  32. data/vendor/gems/express_templates/lib/express_templates/version.rb +1 -1
  33. data/vendor/gems/express_templates/test/components/forms/express_form_test.rb +4 -0
  34. data/vendor/gems/express_templates/test/dummy/log/test.log +963 -0
  35. metadata +68 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 50d6a3fea68da45a25497be729e3f4122d3073ec
4
- data.tar.gz: 1ffe48826b7a7a330a6adf849bcfd92b20562de0
3
+ metadata.gz: faf9fd31ec56bd2a725c15cfe8b2b902bc9e841b
4
+ data.tar.gz: 7d118947bdd9dcda591c6aeae958afbf6600bc14
5
5
  SHA512:
6
- metadata.gz: 5de456daa50c148a1eff7f6119f3edb0213589fb4111ae344fd9e70b9630c436a51d0c9cfa2b068ab7576beb8873b7f4ae0b2276fbfee9469144853646910961
7
- data.tar.gz: 7c543198ff8aabf901bc459cb48bde95afede6f011e3c4507e7e6936daf74ce68ccd995e83ae1658470ed470eea30fcf8bbd42cc337835f4b0eff1422ce81d08
6
+ metadata.gz: 78fd0b1a04e2fa9a3ecfae55300f5644497dc344fe0b3224be6c1e702ea1817be66d1b735d039e1648f2a955c5a5293b09e98f0b8c77c2a60942ea404ea2e796
7
+ data.tar.gz: 3a2515fe8b7729c1dfebb11955b9e4b7f250806ffa1a1527d6771281aaa51fc1fd3647d24412b9cebbe39e2bd01b51bce019265e15db5fa9ef0c31daf380f8f7
@@ -0,0 +1,7 @@
1
+ module ExpressAdmin
2
+ class NavBarActions < ExpressTemplates::Components::Base
3
+ contains -> {
4
+ render(partial: 'shared/nav_bar_actions') rescue nil
5
+ }
6
+ end
7
+ end
@@ -10,7 +10,7 @@ nav(class: 'top-bar') {
10
10
  li {
11
11
  icon_link("android-open", text: 'View Site', href: '/', target: '_blank')
12
12
  }
13
- render(partial: 'shared/nav_bar_actions')
13
+ nav_bar_actions
14
14
  li { flash_messages } unless helpers.flash.empty?
15
15
  }
16
16
  }
@@ -7,9 +7,13 @@ module ExpressAdmin
7
7
  include InstanceMethods
8
8
  helper_method :collection
9
9
  helper_method :resource
10
+ helper_method :resource_path
11
+ helper_method :collection_path
10
12
 
11
13
  class_attribute :defaults
12
14
  self.defaults = {layout: 'layouts/express_admin/admin'}
15
+
16
+ before_filter :expose_parent_resources
13
17
  end
14
18
  end
15
19
 
@@ -94,14 +98,48 @@ module ExpressAdmin
94
98
 
95
99
  protected
96
100
  def resource_path
97
- namespace_route_proxy.send("#{resource_name}_path", resource)
101
+ if parent_resource_names.blank?
102
+ self.send(scoped_path_helper("#{resource_name}_path"), resource)
103
+ elsif proxy = route_proxy
104
+ proxy.send(scoped_path_helper(nested_resource_path_helper), resource_ids_hash)
105
+ else
106
+ self.send(scoped_path_helper(nested_resource_path_helper), resource_ids_hash)
107
+ end
108
+ end
109
+
110
+ def scoped_path_helper(path_helper)
111
+ [scope_name, path_helper].compact.join('_')
112
+ end
113
+
114
+ def collection_path
115
+ if parent_resource_names.blank?
116
+ self.send(scoped_path_helper("#{collection_name}_path"), resource)
117
+ elsif proxy = route_proxy
118
+ proxy.send(scoped_path_helper(nested_collection_path_helper), resource_ids_hash)
119
+ else
120
+ self.send(scoped_path_helper(nested_collection_path_helper), resource_ids_hash)
121
+ end
122
+ end
123
+
124
+ def parent_module_name
125
+ self.class.to_s.match(/(\w+)::/).try(:[], 1)
98
126
  end
99
127
 
100
- def namespace_route_proxy
101
- if parent_namespace = self.class.to_s.match(/(\w+)::/).try(:[], 1)
102
- self.send(parent_namespace.underscore)
128
+ def route_proxy
129
+ engine = "#{parent_module_name}::Engine".constantize rescue nil
130
+ if parent_module_name && engine
131
+ self.send(parent_module_name.underscore)
103
132
  else
104
- self
133
+ nil
134
+ end
135
+ end
136
+
137
+ def scope_name
138
+ engine = "#{parent_module_name}::Engine".constantize rescue nil
139
+ if parent_module_name && engine.nil?
140
+ return parent_module_name.underscore
141
+ else
142
+ nil
105
143
  end
106
144
  end
107
145
 
@@ -109,8 +147,24 @@ module ExpressAdmin
109
147
  self.send("#{resource_name}_params")
110
148
  end
111
149
 
150
+ def nested?
151
+ !parent_resource_names.empty?
152
+ end
153
+
154
+ def parent_resource
155
+ self.send("current_#{parent_resource_names.last}")
156
+ end
157
+
158
+ def end_of_association_chain
159
+ if nested?
160
+ parent_resource.send(resource_name.pluralize)
161
+ else
162
+ resource_class
163
+ end
164
+ end
165
+
112
166
  def load_collection
113
- self.instance_variable_set(collection_ivar, resource_class.all)
167
+ self.instance_variable_set(collection_ivar, end_of_association_chain.all)
114
168
  end
115
169
 
116
170
  def collection_ivar
@@ -149,7 +203,84 @@ module ExpressAdmin
149
203
  def resource_name
150
204
  self.class.resource_name
151
205
  end
152
- end
153
206
 
207
+ def nested_resource_path_helper
208
+ (parent_resource_names + [resource_name, 'path']).join('_')
209
+ end
210
+
211
+ def nested_collection_path_helper
212
+ (parent_resource_names + [collection_name, 'path']).join('_')
213
+ end
214
+
215
+ def expose_parent_resources
216
+ parent_resources = parent_resource_names
217
+ return if parent_resources.blank?
218
+ previous_parent = nil
219
+ parent_resources.each do |parent_name|
220
+ # TODO: optimize
221
+ parent_id = extract_path_info_from_routes["#{parent_name}_id".to_sym]
222
+ current_parent = "current_#{parent_name}".to_sym
223
+ unless self.respond_to?(current_parent)
224
+ if previous_parent.nil?
225
+ self.class_eval do
226
+ define_method(current_parent) do
227
+ "::#{parent_name.capitalize}".constantize.find(parent_id)
228
+ end
229
+ end
230
+ else
231
+ self.class_eval do
232
+ grandparent_accessor = previous_parent
233
+ define_method(current_parent) do
234
+ grandparent_resource = self.send(grandparent_accessor)
235
+ parent_scope = grandparent_resource.send(parent_name.pluralize)
236
+ parent_scope.find(parent_id)
237
+ end
238
+ end
239
+ end
240
+ end
241
+ previous_parent = current_parent
242
+ end
243
+ end
244
+
245
+ def parent_resource_names
246
+ path_info = extract_path_info_from_routes
247
+ unless path_info.nil?
248
+ path_info.keys.grep(/_id$/).map do |id|
249
+ id.to_s.gsub(/_id$/, '')
250
+ end
251
+ end
252
+ end
253
+
254
+ def extract_path_info_from_routes
255
+ recognized_path = nil
256
+ Rails::Engine.subclasses.each do |engine|
257
+ engine_instance = engine.instance
258
+ engine_route = Rails.application.routes.routes.find do |r|
259
+ r.app.app == engine_instance.class
260
+ end
261
+ next unless engine_route
262
+ path_for_engine = request.path.gsub(%r(^#{engine_route.path.spec.to_s}), "")
263
+ begin
264
+ recognized_path = engine_instance.routes.recognize_path(path_for_engine, method: request.method)
265
+ rescue ActionController::RoutingError => e
266
+ end
267
+ end
268
+ if recognized_path.nil?
269
+ begin
270
+ recognized_path = Rails.application.routes.recognize_path(request.path, method: request.method)
271
+ rescue ActionController::RoutingError => e
272
+ end
273
+ end
274
+ recognized_path
275
+ end
276
+
277
+ def resource_ids_hash
278
+ parent_resource_names.inject({id: resource.to_param}) do |hash, name|
279
+ hash["#{name}_id".to_sym] = self.send("current_#{name}".to_sym).to_param
280
+ hash
281
+ end
282
+ end
283
+
284
+ end
154
285
  end
155
- end
286
+ end
@@ -1,3 +1,3 @@
1
1
  module ExpressAdmin
2
- VERSION = "1.4.6"
2
+ VERSION = "1.4.7"
3
3
  end
@@ -8,6 +8,9 @@ module ExpressAdmin
8
8
  def resource_class
9
9
  Widget
10
10
  end
11
+ def parent_resource_names
12
+ [] # skip nested resource handling
13
+ end
11
14
  end
12
15
 
13
16
  def widgets_controller(params = {})
@@ -88,10 +91,21 @@ module ExpressAdmin
88
91
  end
89
92
  end
90
93
 
91
- # test "it should provide collection and resource helpers"
94
+ test "it should provide collection and resource helpers" do
95
+ controller = widgets_controller
96
+ controller.index
97
+ assert controller.send(:collection).respond_to?(:count), "collection not provided by #index"
98
+ assert controller.send(:resource), "resource not provided by #index"
99
+ end
92
100
 
93
- # test "it should provide a default strong params"
101
+ test "it should provide a default strong params" do
102
+ assert_raises(ActionController::ParameterMissing) do
103
+ widgets_controller.create
104
+ end
105
+ widgets_controller(widget: {column2: 'nothing'}).create
106
+ end
94
107
 
108
+ # TODO: Implement later
95
109
  # test "for nested resources it should try to expose a current method for parent resources"
96
110
  end
97
- end
111
+ end
@@ -1,12 +1,11 @@
1
1
  module Admin
2
- class CategoriesController < AdminController
2
+ class CategoriesController < ExpressAdmin::StandardController
3
3
 
4
- defaults resource_class: Category
4
+ protected
5
5
 
6
- private
7
-
8
- def category_params
9
- params.require(:category).permit!
6
+ def resource_class
7
+ ::Category
10
8
  end
9
+
11
10
  end
12
11
  end
@@ -0,0 +1,11 @@
1
+ module Admin
2
+ class PartsController < ExpressAdmin::StandardController
3
+
4
+ protected
5
+
6
+ def resource_class
7
+ ::Part
8
+ end
9
+
10
+ end
11
+ end
@@ -1,12 +1,11 @@
1
1
  module Admin
2
- class WidgetsController < AdminController
2
+ class WidgetsController < ExpressAdmin::StandardController
3
3
 
4
- defaults resource_class: Widget
4
+ protected
5
5
 
6
- private
7
-
8
- def widget_params
9
- params.require(:widget).permit!
6
+ def resource_class
7
+ ::Widget
10
8
  end
9
+
11
10
  end
12
11
  end
@@ -0,0 +1,3 @@
1
+ class Part < ActiveRecord::Base
2
+ belongs_to :widget
3
+ end
@@ -3,5 +3,6 @@ class Widget < ActiveRecord::Base
3
3
 
4
4
  has_many :widget_tags, inverse_of: :widget
5
5
  has_many :tags, through: :widget_tags
6
+ has_many :parts
6
7
 
7
8
  end
@@ -0,0 +1,8 @@
1
+ main_region {
2
+ smart_table(:parts)
3
+ }
4
+ sidebar_region {
5
+ widget_box(:part) {
6
+ smart_form(:part, only: [:name])
7
+ }
8
+ }
@@ -0,0 +1,3 @@
1
+ main_region {
2
+ smart_form(:part, only: [:name])
3
+ }
@@ -1,10 +1,8 @@
1
- row {
2
- main_region {
3
- smart_table(:widgets, show_on_click: true)
4
- }
5
- sidebar_region {
6
- widget_box(:widget) {
7
- smart_form(:widget)
8
- }
1
+ main_region {
2
+ smart_table(:widgets)
3
+ }
4
+ sidebar_region {
5
+ widget_box(:widget) {
6
+ smart_form(:widget)
9
7
  }
10
8
  }
@@ -0,0 +1,3 @@
1
+ main_region {
2
+ smart_form(:widget)
3
+ }
@@ -0,0 +1,2 @@
1
+ title: 'Express Widget'
2
+ path: 'admin_widgets_path'
@@ -1,7 +1,12 @@
1
1
  Rails.application.routes.draw do
2
2
 
3
3
  namespace :admin do
4
- resources :categories
4
+ resources :categories do
5
+ resources :widgets do
6
+ resources :parts
7
+ end
8
+ end
9
+
5
10
  resources :widgets
6
11
  end
7
12
 
@@ -0,0 +1,10 @@
1
+ class CreateParts < ActiveRecord::Migration
2
+ def change
3
+ create_table :parts do |t|
4
+ t.string :name
5
+ t.integer :widget_id
6
+
7
+ t.timestamps null: false
8
+ end
9
+ end
10
+ end
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20150610081204) do
14
+ ActiveRecord::Schema.define(version: 20150812073447) do
15
15
 
16
16
  create_table "categories", force: :cascade do |t|
17
17
  t.string "name"
@@ -19,6 +19,13 @@ ActiveRecord::Schema.define(version: 20150610081204) do
19
19
  t.datetime "updated_at", null: false
20
20
  end
21
21
 
22
+ create_table "parts", force: :cascade do |t|
23
+ t.string "name"
24
+ t.integer "widget_id"
25
+ t.datetime "created_at", null: false
26
+ t.datetime "updated_at", null: false
27
+ end
28
+
22
29
  create_table "tags", force: :cascade do |t|
23
30
  t.string "name"
24
31
  end
Binary file
@@ -87,11 +87,6 @@ module ExpressAdmin
87
87
  assert_match /<div class="[^"]*field-wrapper"/, widget_form
88
88
  end
89
89
 
90
- test 'path prefix is provided' do
91
- action_attrib = 'action="/admin/widgets"'
92
- assert_match action_attrib, widget_form(path_prefix: 'admin')
93
- end
94
-
95
90
  test "options for select come from the related collection" do
96
91
  assert_match /<option.*>Toys<\/option>/, widget_form
97
92
  assert_match /<option.*>Tools<\/option>/, widget_form
@@ -15,7 +15,6 @@ module Components
15
15
  def widget_path(widget_id)
16
16
  "/widgets/#{widget_id.to_param}"
17
17
  end
18
- alias resource_path widget_path
19
18
  end
20
19
  view
21
20
  end
@@ -0,0 +1,20 @@
1
+ require "test_helper"
2
+
3
+ module Admin
4
+ class PartsControllerTest < ActionController::TestCase
5
+ fixtures :all
6
+
7
+ test "should get show" do
8
+ get :show, category_id: categories(:toys).to_param, widget_id: widgets(:one).to_param, id: parts(:one).to_param
9
+ assert_response :success
10
+ end
11
+
12
+ test "should display the nested index" do
13
+ response = get :index, category_id: categories(:toys).to_param, widget_id: widgets(:one).to_param
14
+ assert_response :success
15
+ assert_match /Some part/, response.body
16
+ refute_match /Another part/, response.body
17
+ end
18
+
19
+ end
20
+ end