activeadmin 0.2.1 → 0.2.2

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.

Potentially problematic release.


This version of activeadmin might be problematic. Click here for more details.

Files changed (66) hide show
  1. data/CHANGELOG.rdoc +60 -11
  2. data/Gemfile +7 -3
  3. data/README.rdoc +118 -8
  4. data/Rakefile +5 -1
  5. data/activeadmin.gemspec +20 -13
  6. data/cucumber.yml +1 -0
  7. data/features/comments/commenting.feature +5 -1
  8. data/features/dashboard.feature +26 -0
  9. data/features/menu.feature +26 -0
  10. data/features/step_definitions/dashboard_steps.rb +11 -0
  11. data/features/step_definitions/menu_steps.rb +7 -0
  12. data/features/sti_resource.feature +49 -0
  13. data/lib/active_admin.rb +20 -13
  14. data/lib/active_admin/arbre/tag.rb +10 -2
  15. data/lib/active_admin/comments.rb +15 -0
  16. data/lib/active_admin/form_builder.rb +1 -1
  17. data/lib/active_admin/resource.rb +9 -4
  18. data/lib/active_admin/resource_controller.rb +4 -4
  19. data/lib/active_admin/resource_controller/collection.rb +3 -2
  20. data/lib/active_admin/stylesheets/active_admin.scss +9 -2
  21. data/lib/active_admin/stylesheets/active_admin/_forms.scss +2 -2
  22. data/lib/active_admin/version.rb +1 -1
  23. data/lib/active_admin/view_helpers/filter_form_helper.rb +1 -1
  24. data/lib/active_admin/views/components/table_for.rb +1 -1
  25. data/lib/active_admin/views/index_as_table.rb +3 -3
  26. data/lib/active_admin/views/pages/base.rb +8 -1
  27. data/lib/active_admin/views/pages/dashboard.rb +0 -2
  28. data/lib/active_admin/views/pages/index.rb +3 -1
  29. data/lib/active_admin/views/templates/active_admin/devise/sessions/new.html.erb +1 -1
  30. data/lib/active_admin/views/templates/layouts/active_admin_logged_out.html.erb +1 -1
  31. data/lib/generators/active_admin/devise/devise_generator.rb +7 -3
  32. data/lib/generators/active_admin/install/templates/active_admin.rb.erb +7 -6
  33. data/lib/generators/active_admin/install/templates/dashboards.rb +4 -3
  34. data/spec/{integration → controllers}/index_as_csv_spec.rb +8 -13
  35. data/spec/integration/belongs_to_spec.rb +1 -1
  36. data/spec/spec_helper.rb +10 -4
  37. data/spec/support/integration_example_group.rb +0 -4
  38. data/spec/support/rails_template.rb +2 -1
  39. data/spec/unit/action_builder_spec.rb +1 -1
  40. data/spec/unit/action_items_spec.rb +1 -1
  41. data/spec/unit/active_admin_spec.rb +19 -6
  42. data/spec/unit/arbre/html_spec.rb +26 -1
  43. data/spec/unit/asset_registration_spec.rb +1 -1
  44. data/spec/unit/belongs_to_spec.rb +1 -1
  45. data/spec/unit/breadcrumbs_spec.rb +1 -1
  46. data/spec/unit/comments_spec.rb +1 -1
  47. data/spec/unit/controller_filters_spec.rb +1 -1
  48. data/spec/unit/dashboard_controller_spec.rb +1 -1
  49. data/spec/unit/dashboard_section_spec.rb +1 -1
  50. data/spec/unit/dashboards_spec.rb +1 -1
  51. data/spec/unit/filter_form_builder_spec.rb +1 -1
  52. data/spec/unit/form_builder_spec.rb +1 -1
  53. data/spec/unit/menu_item_spec.rb +1 -1
  54. data/spec/unit/menu_spec.rb +1 -1
  55. data/spec/unit/namespace_spec.rb +1 -1
  56. data/spec/unit/registration_spec.rb +1 -1
  57. data/spec/unit/renderer_spec.rb +1 -1
  58. data/spec/unit/resource_controller/collection_spec.rb +34 -0
  59. data/spec/unit/resource_controller_spec.rb +1 -1
  60. data/spec/unit/resource_spec.rb +23 -2
  61. data/spec/unit/routing_spec.rb +1 -1
  62. data/spec/unit/tabs_renderer_spec.rb +1 -1
  63. metadata +36 -13
  64. data/spec/integration/dashboard_spec.rb +0 -44
  65. data/spec/integration/index_as_table_spec.rb +0 -41
  66. data/spec/integration/layout_spec.rb +0 -48
@@ -0,0 +1,26 @@
1
+ Feature: Menu
2
+
3
+ Background:
4
+ Given I am logged in
5
+
6
+ Scenario: Hide the menu item
7
+ Given a configuration of:
8
+ """
9
+ ActiveAdmin.register Post do
10
+ menu false
11
+ end
12
+ """
13
+ When I am on the dashboard
14
+ Then I should not see a menu item for "Posts"
15
+
16
+ @wip
17
+ Scenario: Set the menu item label
18
+ Given a configuration of:
19
+ """
20
+ ActiveAdmin.register Post do
21
+ menu :label => "Articles"
22
+ end
23
+ """
24
+ When I am on the dashboard
25
+ Then I should see a menu item for "Articles"
26
+ And I should not see a menu item for "Posts"
@@ -0,0 +1,11 @@
1
+ Then /^I should see the default welcome message$/ do
2
+ Then %{I should see "Welcome to Active Admin" within "#dashboard_default_message"}
3
+ end
4
+
5
+ Then /^I should not see the default welcome message$/ do
6
+ Then %{I should not see "Welcome to Active Admin"}
7
+ end
8
+
9
+ Then /^I should see a dashboard widget "([^"]*)"$/ do |name|
10
+ Then %{I should see "#{name}" within ".dashboard .panel h3"}
11
+ end
@@ -0,0 +1,7 @@
1
+ Then /^I should see a menu item for "([^"]*)"$/ do |name|
2
+ Then %{I should see "#{name}" within "#tabs li a"}
3
+ end
4
+
5
+ Then /^I should not see a menu item for "([^"]*)"$/ do |name|
6
+ Then %{I should not see "#{name}" within "#tabs li a"}
7
+ end
@@ -0,0 +1,49 @@
1
+ Feature: STI Resource
2
+
3
+ Ensure that standard CRUD works with STI models
4
+
5
+ Background:
6
+ Given I am logged in
7
+ And a configuration of:
8
+ """
9
+ ActiveAdmin.register Publisher
10
+ ActiveAdmin.register User
11
+ """
12
+
13
+ Scenario: Create, update and delete a child STI resource
14
+ Given I am on the index page for publishers
15
+ When I follow "New Publisher"
16
+ And I fill in "First name" with "Terry"
17
+ And I fill in "Last name" with "Fox"
18
+ And I fill in "Username" with "terry_fox"
19
+ And I press "Create Publisher"
20
+ Then I should see "Publisher was successfully created"
21
+ And I should see "Terry"
22
+
23
+ When I follow "Edit Publisher"
24
+ And I fill in "First name" with "Joe"
25
+ And I press "Update Publisher"
26
+ Then I should see "Publisher was successfully updated"
27
+ And I should see "Joe"
28
+
29
+ When I follow "Delete Publisher"
30
+ Then I should see "Publisher was successfully destroyed"
31
+
32
+ Scenario: Create, update and delete a parent STI resource
33
+ Given I am on the index page for users
34
+ When I follow "New User"
35
+ And I fill in "First name" with "Terry"
36
+ And I fill in "Last name" with "Fox"
37
+ And I fill in "Username" with "terry_fox"
38
+ And I press "Create User"
39
+ Then I should see "User was successfully created"
40
+ And I should see "Terry"
41
+
42
+ When I follow "Edit User"
43
+ And I fill in "First name" with "Joe"
44
+ And I press "Update User"
45
+ Then I should see "User was successfully updated"
46
+ And I should see "Joe"
47
+
48
+ When I follow "Delete User"
49
+ Then I should see "User was successfully destroyed"
@@ -55,13 +55,13 @@ module ActiveAdmin
55
55
  @@namespaces = {}
56
56
  mattr_accessor :namespaces
57
57
 
58
- # The title which get's displayed in the main layout
58
+ # The title which gets displayed in the main layout
59
59
  @@site_title = ""
60
60
  mattr_accessor :site_title
61
61
 
62
62
  # Load paths for admin configurations. Add folders to this load path
63
63
  # to load up other resources for administration. External gems can
64
- # include thier paths in this load path to provide active_admin UIs
64
+ # include their paths in this load path to provide active_admin UIs
65
65
  @@load_paths = [File.expand_path('app/admin', Rails.root)]
66
66
  mattr_accessor :load_paths
67
67
 
@@ -70,10 +70,10 @@ module ActiveAdmin
70
70
  @@view_factory = ActiveAdmin::ViewFactory.new
71
71
  mattr_accessor :view_factory
72
72
 
73
- # Whether or not to use admin comments
74
- @@admin_notes = true
73
+ # DEPRECATED: This option is deprecated and will be removed. Use
74
+ # the #allow_comments_in option instead
75
75
  mattr_accessor :admin_notes
76
-
76
+
77
77
  # The method to call in controllers to get the current user
78
78
  @@current_user_method = :current_admin_user
79
79
  mattr_accessor :current_user_method
@@ -84,7 +84,7 @@ module ActiveAdmin
84
84
  mattr_accessor :authentication_method
85
85
 
86
86
  # Active Admin makes educated guesses when displaying objects, this is
87
- # the list of methods its tries calling in order
87
+ # the list of methods it tries calling in order
88
88
  @@display_name_methods = [:display_name, :full_name, :name, :username, :login, :title, :email, :to_s]
89
89
  mattr_accessor :display_name_methods
90
90
 
@@ -96,7 +96,7 @@ module ActiveAdmin
96
96
  class << self
97
97
 
98
98
 
99
- # Get's called within the initializer
99
+ # Gets called within the initializer
100
100
  def setup
101
101
  # Register the default assets
102
102
  register_stylesheet 'admin/active_admin.css'
@@ -105,7 +105,7 @@ module ActiveAdmin
105
105
 
106
106
  # Since we're dealing with all our own file loading, we need
107
107
  # to remove our paths from the ActiveSupport autoload paths.
108
- # If not, file nameing becomes very important and can cause clashes.
108
+ # If not, file naming becomes very important and can cause clashes.
109
109
  ActiveSupport::Dependencies.autoload_paths.reject!{|path| load_paths.include?(path) }
110
110
 
111
111
  # Add the Active Admin view path to the rails view path
@@ -125,14 +125,18 @@ module ActiveAdmin
125
125
 
126
126
  yield self
127
127
 
128
+ generate_stylesheets
129
+ end
130
+
131
+ def generate_stylesheets
128
132
  # Setup SASS
129
133
  require 'sass/plugin' # This must be required after initialization
130
- Sass::Plugin.add_template_location(File.expand_path("../active_admin/stylesheets/", __FILE__), File.join(Rails.root, "public/stylesheets/admin"))
134
+ Sass::Plugin.add_template_location(File.expand_path("../active_admin/stylesheets/", __FILE__), File.join(Sass::Plugin.options[:css_location], 'admin'))
131
135
  end
132
136
 
133
137
  # Registers a brand new configuration for the given resource.
134
138
  def register(resource, options = {}, &block)
135
- namespace_name = options[:namespace] == false ? :root : (options[:namespace] || default_namespace)
139
+ namespace_name = options[:namespace] == false ? :root : (options[:namespace] || default_namespace || :root)
136
140
  namespace = find_or_create_namespace(namespace_name)
137
141
  namespace.register(resource, options, &block)
138
142
  end
@@ -178,9 +182,7 @@ module ActiveAdmin
178
182
  return false if loaded?
179
183
 
180
184
  # Load files
181
- load_paths.flatten.compact.uniq.each do |path|
182
- Dir["#{path}/*.rb"].each{|f| load f }
183
- end
185
+ files_in_load_path.each{|file| load file }
184
186
 
185
187
  # If no configurations, let's make sure you can still login
186
188
  load_default_namespace if namespaces.values.empty?
@@ -191,6 +193,11 @@ module ActiveAdmin
191
193
  @@loaded = true
192
194
  end
193
195
 
196
+ # Returns ALL the files to load from all the load paths
197
+ def files_in_load_path
198
+ load_paths.flatten.compact.uniq.collect{|path| Dir["#{path}/**/*.rb"] }.flatten
199
+ end
200
+
194
201
  # Creates all the necessary routes for the ActiveAdmin configurations
195
202
  #
196
203
  # Use this within the routes.rb file:
@@ -86,8 +86,12 @@ module Arbre
86
86
  html = ""
87
87
 
88
88
  if no_child? || child_is_text?
89
- # one line
90
- html << spaces << open_tag << child_content << close_tag
89
+ if self_closing_tag?
90
+ html << spaces << open_tag.sub( />$/, '/>' )
91
+ else
92
+ # one line
93
+ html << spaces << open_tag << child_content << close_tag
94
+ end
91
95
  else
92
96
  # multiple lines
93
97
  html << spaces << open_tag << "\n"
@@ -100,6 +104,10 @@ module Arbre
100
104
  html
101
105
  end
102
106
 
107
+ def self_closing_tag?
108
+ %w|meta link|.include?(tag_name)
109
+ end
110
+
103
111
  def no_child?
104
112
  children.empty?
105
113
  end
@@ -53,6 +53,21 @@ ActiveAdmin::Event.subscribe ActiveAdmin::Namespace::RegisterEvent do |namespace
53
53
  comment.author = current_active_admin_user
54
54
  end
55
55
 
56
+ # Redirect to the resource show page when failing to add a comment
57
+ # TODO: Provide helpers to make such kind of customization much simpler
58
+ controller do
59
+ def create
60
+ create! do |success, failure|
61
+ failure.html do
62
+ resource_config = active_admin_config.namespace.resource_for(@comment.resource.class)
63
+ flash[:error] = "Comment wasn't saved, text was empty."
64
+ redirect_to send(resource_config.route_instance_path, @comment.resource)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+
56
71
  # Display as a table
57
72
  index do
58
73
  column("Resource"){|comment| auto_link(comment.resource) }
@@ -42,7 +42,7 @@ module ActiveAdmin
42
42
  def cancel_link(url = nil, html_options = {}, li_attributes = {})
43
43
  li_attributes[:class] ||= "cancel"
44
44
  url ||= {:action => "index"}
45
- template.content_tag(:li, (template.link_to ActiveAdmin::Iconic.icon(:x) + " Cancel", url, html_options), li_attributes)
45
+ template.content_tag(:li, (template.link_to "Cancel", url, html_options), li_attributes)
46
46
  end
47
47
 
48
48
  def commit_button_with_cancel_link
@@ -82,6 +82,10 @@ module ActiveAdmin
82
82
  @plural_resource_name ||= resource_name.pluralize
83
83
  end
84
84
 
85
+ def resource_table_name
86
+ resource.table_name
87
+ end
88
+
85
89
  # Returns a properly formatted controller name for this
86
90
  # resource within its namespace
87
91
  def controller_name
@@ -121,16 +125,17 @@ module ActiveAdmin
121
125
  @menu_options[:parent]
122
126
  end
123
127
 
128
+ # Returns the name to be displayed in the menu for this resource
129
+ def menu_item_name
130
+ @menu_options[:label] || plural_resource_name
131
+ end
132
+
124
133
  # Should this resource be added to the menu system?
125
134
  def include_in_menu?
126
135
  return false if @menu_options[:display] == false
127
136
  !(belongs_to? && !belongs_to_config.optional?)
128
137
  end
129
138
 
130
- # Returns the name to be displayed in the menu for this resource
131
- def menu_item_name
132
- @menu_item_name ||= plural_resource_name
133
- end
134
139
 
135
140
  # Clears all the member actions this resource knows about
136
141
  def clear_member_actions!
@@ -53,20 +53,20 @@ module ActiveAdmin
53
53
  end
54
54
 
55
55
  # Default Sidebar Sections
56
- sidebar :filters, :only => :index, :icon => :magnifying_glass do
56
+ sidebar :filters, :only => :index do
57
57
  active_admin_filters_form_for assigns["search"], filters_config
58
58
  end
59
59
 
60
60
  # Default Action Item Links
61
61
  action_item :only => :show do
62
62
  if controller.action_methods.include?('edit')
63
- link_to(icon(:pen) + "Edit #{active_admin_config.resource_name}", edit_resource_path(resource))
63
+ link_to("Edit #{active_admin_config.resource_name}", edit_resource_path(resource))
64
64
  end
65
65
  end
66
66
 
67
67
  action_item :only => :show do
68
68
  if controller.action_methods.include?("destroy")
69
- link_to(icon(:trash_stroke) + "Delete #{active_admin_config.resource_name}",
69
+ link_to("Delete #{active_admin_config.resource_name}",
70
70
  resource_path(resource),
71
71
  :method => :delete, :confirm => "Are you sure you want to delete this?")
72
72
  end
@@ -74,7 +74,7 @@ module ActiveAdmin
74
74
 
75
75
  action_item :except => [:new, :show] do
76
76
  if controller.action_methods.include?('new')
77
- link_to(icon(:plus_alt) + "New #{active_admin_config.resource_name}", new_resource_path)
77
+ link_to("New #{active_admin_config.resource_name}", new_resource_path)
78
78
  end
79
79
  end
80
80
 
@@ -46,8 +46,9 @@ module ActiveAdmin
46
46
 
47
47
  def sort_order(chain)
48
48
  params[:order] ||= active_admin_config.sort_order
49
+ table_name = active_admin_config.resource_table_name
49
50
  if params[:order] && params[:order] =~ /^([\w\_\.]+)_(desc|asc)$/
50
- chain.order("#{$1} #{$2}")
51
+ chain.order("#{table_name}.#{$1} #{$2}")
51
52
  else
52
53
  chain # just return the chain
53
54
  end
@@ -63,7 +64,7 @@ module ActiveAdmin
63
64
  end
64
65
 
65
66
  def search(chain)
66
- @search = chain.search(clean_search_params(params[:q]))
67
+ @search = chain.metasearch(clean_search_params(params[:q]))
67
68
  @search.relation
68
69
  end
69
70
 
@@ -56,7 +56,7 @@ body {
56
56
  }
57
57
 
58
58
  // ----------------------------------- Main Structure
59
- #content {
59
+ #active_admin_content {
60
60
  margin: 0;
61
61
  padding: 25px $horizontal-page-margin;
62
62
 
@@ -222,6 +222,9 @@ table {
222
222
  .previous_page, .next_page { display:none; }
223
223
  }
224
224
 
225
+
226
+ .index_content { clear: both; }
227
+
225
228
  // -------------------------------------- Index as Grid
226
229
  table.index_grid td { border: none; background: none; padding: 0 20px 20px 0; margin: 0;}
227
230
 
@@ -268,7 +271,7 @@ body.logged_out {
268
271
  #content_wrapper{
269
272
  width: 500px;
270
273
  margin: 70px auto;
271
- #content {
274
+ #active_admin_content {
272
275
  @include shadow;
273
276
  background: #fff;
274
277
  padding: 13px 30px;
@@ -342,7 +345,10 @@ table.dashboard {
342
345
  .dashboard_section { @include section; }
343
346
  }
344
347
 
348
+
345
349
  // -------------------------------------- Resource Attributes Table
350
+ .attributes_table { overflow: hidden; }
351
+
346
352
  .attributes_table table {
347
353
  th, td {
348
354
  padding: 8px $cell-horizontal-padding 6px $cell-horizontal-padding;
@@ -371,6 +377,7 @@ table.dashboard {
371
377
 
372
378
  .sidebar_section .attributes_table th { width: 50px; }
373
379
 
380
+
374
381
  // -------------------------------------- Status Tags
375
382
  .status {
376
383
  background: darken($secondary-color, 15%);
@@ -74,7 +74,7 @@ form {
74
74
  }
75
75
 
76
76
  /* Text Fields */
77
- input[type=text], input[type=password], input[type=email], input[type=tel], textarea {
77
+ input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], textarea {
78
78
  width: 76%;
79
79
  border: 1px solid #c9d0d6;
80
80
  font-size: 0.95em;
@@ -150,7 +150,7 @@ form {
150
150
  }
151
151
 
152
152
  &.error {
153
- input[type=text], input[type=password], input[type=email], input[type=tel], textarea {
153
+ input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], textarea {
154
154
  border: 1px solid #cc0000;
155
155
  }
156
156
  }
@@ -1,3 +1,3 @@
1
1
  module ActiveAdmin
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.2'
3
3
  end
@@ -155,7 +155,7 @@ module ActiveAdmin
155
155
  end
156
156
 
157
157
  if reflection = reflection_for(method)
158
- return :select if reflection.macro == :belongs_to && reflection.collection?
158
+ return :select if reflection.macro == :belongs_to && !reflection.options[:polymorphic]
159
159
  end
160
160
  end
161
161
 
@@ -76,7 +76,7 @@ module ActiveAdmin
76
76
  def build_table_body
77
77
  @tbody = tbody do
78
78
  # Build enough rows for our collection
79
- @collection.each{|_| tr(:class => cycle('odd', 'event')) }
79
+ @collection.each{|_| tr(:class => cycle('odd', 'even')) }
80
80
  end
81
81
  end
82
82
 
@@ -35,9 +35,9 @@ module ActiveAdmin
35
35
  :name => ""
36
36
  }.merge(options)
37
37
  column options[:name] do |resource|
38
- links = link_to icon(:arrow_right_alt1) + "View", resource_path(resource), :class => "view_link"
39
- links += link_to icon(:pen) + "Edit", edit_resource_path(resource), :class => "edit_link"
40
- links += link_to icon(:trash_stroke) + "Delete", resource_path(resource), :method => :delete, :confirm => "Are you sure you want to delete this?", :class => "delete_link"
38
+ links = link_to "View", resource_path(resource), :class => "view_link"
39
+ links += link_to "Edit", edit_resource_path(resource), :class => "edit_link"
40
+ links += link_to "Delete", resource_path(resource), :method => :delete, :confirm => "Are you sure you want to delete this?", :class => "delete_link"
41
41
  links
42
42
  end
43
43
  end
@@ -5,12 +5,19 @@ module ActiveAdmin
5
5
 
6
6
  def build(*args)
7
7
  super
8
+ add_classes_to_body
8
9
  build_active_admin_head
9
10
  build_page
10
11
  end
11
12
 
12
13
  private
13
14
 
15
+
16
+ def add_classes_to_body
17
+ @body.add_class(params[:action])
18
+ @body.add_class(params[:controller].gsub('/', '_'))
19
+ end
20
+
14
21
  def build_active_admin_head
15
22
  within @head do
16
23
  meta :"http-equiv" => "Content-type", :content => "text/html; charset=utf-8"
@@ -71,7 +78,7 @@ module ActiveAdmin
71
78
  end
72
79
 
73
80
  def build_page_content
74
- div :id => "content", :class => (skip_sidebar? ? "without_sidebar" : "with_sidebar") do
81
+ div :id => "active_admin_content", :class => (skip_sidebar? ? "without_sidebar" : "with_sidebar") do
75
82
  build_flash_messages
76
83
  build_main_content_wrapper
77
84
  build_sidebar