administrate 0.10.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/administrate/components/associative.js +5 -0
  3. data/app/assets/javascripts/administrate/components/date_time_picker.js +6 -2
  4. data/app/assets/javascripts/administrate/components/table.js +1 -1
  5. data/app/assets/stylesheets/administrate/base/_tables.scss +3 -0
  6. data/app/assets/stylesheets/administrate/base/_typography.scss +1 -1
  7. data/app/assets/stylesheets/administrate/components/_attributes.scss +4 -3
  8. data/app/assets/stylesheets/administrate/components/_buttons.scss +8 -0
  9. data/app/assets/stylesheets/administrate/components/_cells.scss +2 -0
  10. data/app/assets/stylesheets/administrate/components/_field-unit.scss +17 -4
  11. data/app/assets/stylesheets/administrate/components/_flashes.scss +0 -8
  12. data/app/assets/stylesheets/administrate/components/_main-content.scss +1 -0
  13. data/app/assets/stylesheets/administrate/components/_navigation.scss +2 -3
  14. data/app/assets/stylesheets/administrate/library/_variables.scss +10 -8
  15. data/app/controllers/administrate/application_controller.rb +33 -9
  16. data/app/controllers/concerns/administrate/punditize.rb +3 -3
  17. data/app/helpers/administrate/application_helper.rb +47 -15
  18. data/app/views/administrate/application/_collection.html.erb +8 -7
  19. data/app/views/administrate/application/_form.html.erb +2 -2
  20. data/app/views/administrate/application/{_icons.erb → _icons.html.erb} +0 -0
  21. data/app/views/administrate/application/_navigation.html.erb +5 -3
  22. data/app/views/administrate/application/index.html.erb +4 -2
  23. data/app/views/administrate/application/show.html.erb +2 -2
  24. data/app/views/fields/belongs_to/_form.html.erb +3 -3
  25. data/app/views/fields/date/_form.html.erb +24 -0
  26. data/app/views/fields/date/_index.html.erb +21 -0
  27. data/app/views/fields/date/_show.html.erb +21 -0
  28. data/app/views/fields/has_many/_form.html.erb +2 -2
  29. data/app/views/fields/has_many/_show.html.erb +8 -5
  30. data/app/views/fields/has_one/_form.html.erb +1 -1
  31. data/app/views/fields/has_one/_index.html.erb +1 -1
  32. data/app/views/fields/has_one/_show.html.erb +4 -4
  33. data/app/views/fields/number/_form.html.erb +1 -1
  34. data/app/views/fields/polymorphic/_form.html.erb +0 -3
  35. data/app/views/fields/polymorphic/_show.html.erb +1 -1
  36. data/app/views/fields/select/_form.html.erb +22 -10
  37. data/app/views/fields/string/_show.html.erb +2 -2
  38. data/app/views/fields/text/_show.html.erb +2 -3
  39. data/app/views/fields/time/_form.html.erb +3 -2
  40. data/app/views/fields/time/_index.html.erb +3 -1
  41. data/app/views/fields/time/_show.html.erb +3 -1
  42. data/app/views/fields/url/_form.html.erb +23 -0
  43. data/app/views/fields/url/_index.html.erb +20 -0
  44. data/app/views/fields/url/_show.html.erb +20 -0
  45. data/app/views/layouts/administrate/application.html.erb +2 -1
  46. data/config/locales/administrate.ar.yml +2 -0
  47. data/config/locales/administrate.bs.yml +2 -0
  48. data/config/locales/administrate.ca.yml +2 -0
  49. data/config/locales/administrate.da.yml +2 -0
  50. data/config/locales/administrate.de.yml +2 -0
  51. data/config/locales/administrate.en.yml +2 -0
  52. data/config/locales/administrate.es.yml +3 -1
  53. data/config/locales/administrate.fi.yml +30 -0
  54. data/config/locales/administrate.fr.yml +4 -2
  55. data/config/locales/administrate.id.yml +30 -0
  56. data/config/locales/administrate.it.yml +2 -0
  57. data/config/locales/administrate.ja.yml +2 -0
  58. data/config/locales/administrate.ko.yml +12 -10
  59. data/config/locales/administrate.nl.yml +7 -5
  60. data/config/locales/administrate.pl.yml +2 -0
  61. data/config/locales/administrate.pt-BR.yml +4 -2
  62. data/config/locales/administrate.pt.yml +4 -2
  63. data/config/locales/administrate.ru.yml +2 -0
  64. data/config/locales/{administrate.al.yml → administrate.sq.yml} +3 -1
  65. data/config/locales/administrate.sv.yml +2 -0
  66. data/config/locales/administrate.tr.yml +30 -0
  67. data/config/locales/administrate.uk.yml +2 -0
  68. data/config/locales/administrate.vi.yml +2 -0
  69. data/config/locales/administrate.zh-CN.yml +4 -2
  70. data/config/locales/administrate.zh-TW.yml +6 -4
  71. data/config/unicorn.rb +8 -13
  72. data/docs/adding_controllers_without_related_model.md +54 -0
  73. data/docs/adding_custom_field_types.md +3 -1
  74. data/docs/authentication.md +3 -1
  75. data/docs/authorization.md +5 -3
  76. data/docs/customizing_attribute_partials.md +5 -2
  77. data/docs/customizing_controller_actions.md +32 -2
  78. data/docs/customizing_dashboards.md +74 -34
  79. data/docs/customizing_page_views.md +18 -4
  80. data/docs/extending_administrate.md +27 -0
  81. data/docs/getting_started.md +49 -56
  82. data/docs/guides.md +5 -0
  83. data/docs/guides/hiding_dashboards_from_sidebar.md +19 -0
  84. data/docs/rails_api.md +45 -0
  85. data/lib/administrate.rb +19 -0
  86. data/lib/administrate/base_dashboard.rb +35 -9
  87. data/lib/administrate/custom_dashboard.rb +15 -0
  88. data/lib/administrate/engine.rb +8 -1
  89. data/lib/administrate/field/associative.rb +49 -5
  90. data/lib/administrate/field/base.rb +35 -9
  91. data/lib/administrate/field/belongs_to.rb +13 -3
  92. data/lib/administrate/field/date.rb +20 -0
  93. data/lib/administrate/field/deferred.rb +22 -3
  94. data/lib/administrate/field/has_many.rb +31 -11
  95. data/lib/administrate/field/has_one.rb +32 -12
  96. data/lib/administrate/field/number.rb +19 -2
  97. data/lib/administrate/field/polymorphic.rb +5 -5
  98. data/lib/administrate/field/select.rb +6 -1
  99. data/lib/administrate/field/url.rb +21 -0
  100. data/lib/administrate/namespace.rb +4 -0
  101. data/lib/administrate/order.rb +17 -7
  102. data/lib/administrate/page/base.rb +9 -3
  103. data/lib/administrate/page/collection.rb +5 -1
  104. data/lib/administrate/page/form.rb +1 -1
  105. data/lib/administrate/resource_resolver.rb +1 -1
  106. data/lib/administrate/search.rb +107 -23
  107. data/lib/administrate/version.rb +1 -1
  108. data/lib/administrate/view_generator.rb +9 -3
  109. data/lib/generators/administrate/dashboard/dashboard_generator.rb +21 -15
  110. data/lib/generators/administrate/dashboard/templates/controller.rb.erb +33 -8
  111. data/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +18 -6
  112. data/lib/generators/administrate/install/install_generator.rb +37 -1
  113. data/lib/generators/administrate/install/templates/application_controller.rb.erb +3 -3
  114. data/lib/generators/administrate/routes/routes_generator.rb +21 -26
  115. data/lib/generators/administrate/views/layout_generator.rb +1 -0
  116. data/lib/generators/administrate/views/views_generator.rb +5 -4
  117. metadata +50 -53
  118. data/app/assets/javascripts/administrate/components/has_many_form.js +0 -3
  119. data/config/secrets.yml +0 -14
@@ -1,16 +1,18 @@
1
- # Getting Started
1
+ ---
2
+ title: Getting Started
3
+ ---
2
4
 
3
5
  Administrate is released as a Ruby gem, and can be installed on Rails
4
- applications version 4.2 or greater.
6
+ applications version 5.0 or greater. We support Ruby 2.4 and up.
5
7
 
6
- Add the following to your Gemfile:
8
+ First, add the following to your Gemfile:
7
9
 
8
10
  ```ruby
9
11
  # Gemfile
10
12
  gem "administrate"
11
13
  ```
12
14
 
13
- Re-bundle, then run the installer:
15
+ Re-bundle with `bundle install`, then run the installer:
14
16
 
15
17
  ```bash
16
18
  $ rails generate administrate:install
@@ -35,13 +37,13 @@ You will also want to add a `root` route to show a dashboard when you go to `/ad
35
37
  Rails.application.routes.draw do
36
38
  namespace :admin do
37
39
  # Add dashboard for your models here
38
- resources :customers,
40
+ resources :customers
39
41
  resources :orders
40
-
42
+
41
43
  root to: "customers#index" # <--- Root route
42
44
  end
43
45
  end
44
- ```
46
+ ```
45
47
 
46
48
  The routes can be customized to show or hide
47
49
  different models on the dashboard.
@@ -54,6 +56,28 @@ Each `Admin::FooController` can be overwritten to specify custom behavior.
54
56
  Once you have Administrate installed,
55
57
  visit <http://localhost:3000/admin> to see your new dashboard in action.
56
58
 
59
+ ### Errors about assets?
60
+
61
+ If your apps uses Sprockets 4, you'll need to add Administrate's assets to
62
+ your `manifest.js` file. To do this, add these two lines to the file:
63
+
64
+ ```
65
+ //= link administrate/application.css
66
+ //= link administrate/application.js
67
+ ```
68
+
69
+ Otherwise, your app will show you this error:
70
+
71
+ ```
72
+ Asset `administrate/application.css` was not declared to be precompiled in production.
73
+ Declare links to your assets in `app/assets/config/manifest.js`.
74
+ ```
75
+
76
+ For more information on why this is necessary, see Richard Schneeman's article
77
+ ["Self Hosted Config: Introducing the Sprockets manifest.js"][]
78
+
79
+ [schneems]: https://www.schneems.com/2017/11/22/self-hosted-config-introducing-the-sprockets-manifestjs
80
+
57
81
  ## Create Additional Dashboards
58
82
 
59
83
  In order to create additional dashboards, pass in the resource name to
@@ -63,7 +87,7 @@ the dashboard generator. A dashboard and controller will be created.
63
87
  $ rails generate administrate:dashboard Foo
64
88
  ```
65
89
 
66
- Add a route for the new dashboard.
90
+ Then add a route for the new dashboard.
67
91
 
68
92
  ```ruby
69
93
  # config/routes.rb
@@ -73,10 +97,19 @@ namespace :admin do
73
97
  end
74
98
  ```
75
99
 
100
+ ## Using a Custom Namespace
101
+
102
+ Administrate supports using a namespace other than `Admin`, such as
103
+ `Supervisor`. This will also change the route it's using:
104
+
105
+ ```sh
106
+ rails generate administrate:install --namespace=supervisor
107
+ ```
108
+
76
109
  ## Keep Dashboards Updated as Model Attributes Change
77
110
 
78
- If you've installed Administrate and generated dashboards and _then_
79
- subsequently added attributes to your models you'll need to manually add
111
+ If you've installed Administrate and generated dashboards and _then_
112
+ subsequently added attributes to your models you'll need to manually add
80
113
  these additions (or removals) to your dashboards.
81
114
 
82
115
  Example:
@@ -89,7 +122,7 @@ Example:
89
122
  the_new_attribute: Field::String,
90
123
  # ...
91
124
  }.freeze
92
-
125
+
93
126
  SHOW_PAGE_ATTRIBUTES = [
94
127
  # ...
95
128
  :the_new_attribute,
@@ -101,7 +134,7 @@ Example:
101
134
  :the_new_attribute,
102
135
  # ...
103
136
  ].freeze
104
-
137
+
105
138
  COLLECTION_ATTRIBUTES = [
106
139
  # ...
107
140
  :the_new_attribute, # if you want it on the index, also.
@@ -109,49 +142,9 @@ Example:
109
142
  ].freeze
110
143
  ```
111
144
 
112
- It's recommended that you make this change at the same time as you add the
145
+ It's recommended that you make this change at the same time as you add the
113
146
  attribute to the model.
114
147
 
115
- The alternative way to handle this is to re-run `rails g administrate:install` and
116
- carefully pick through the diffs. This latter method is probably more cumbersome.
117
-
118
- ## Rails API
119
-
120
- Since Rails 5.0, we've been able to have API only applications. Yet, sometimes
121
- we still want to have an admin.
122
-
123
- To get this working, we recommend updating this config:
124
-
125
- ```ruby
126
- # config/application.rb
127
- config.api_only = false
128
- ```
129
-
130
- That means, when your app _boots_, we'll have access to flashes and such. We
131
- also don't use your `ApplicationController`. Instead, Administrate provides its
132
- own. Meaning you're free to specify `ActionController::API` as your parent
133
- controller to make sure no flash, session, or cookie middleware is used by your
134
- API.
135
-
136
- Alternatively, if your application needs to have `config.api_only = true`, we recommend you add the following lines to your `config/application.rb`
137
-
138
- ```ruby
139
- # Enable Flash, Cookies, MethodOverride for Administrate Gem
140
- config.middleware.use ActionDispatch::Flash
141
- config.session_store :cookie_store
142
- config.middleware.use ActionDispatch::Cookies
143
- config.middleware.use ActionDispatch::Session::CookieStore, config.session_options
144
- config.middleware.use ::Rack::MethodOverride
145
- ```
146
-
147
- You must also ensure that the all the required controller actions are available and accessible as routes since generators in API-only applications only generate some of the required actions. Here is an example:
148
-
149
- ```ruby
150
- # routes.rb
151
- namespace :admin do
152
- resources name, only: %i(index show new create edit update destroy)
153
- end
154
-
155
- # names_controller.rb
156
- # Ensure each of those methods are defined
157
- ```
148
+ The alternative way to handle this is to re-run `rails g administrate:install`
149
+ and carefully pick through the diffs. This latter method is probably more
150
+ cumbersome.
data/docs/guides.md ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Guides
3
+ ---
4
+
5
+ * [Hiding Dashboards from the Sidebar](./guides/hiding_dashboards_from_sidebar)
@@ -0,0 +1,19 @@
1
+ ---
2
+ title: Hiding Dashboards from the Sidebar
3
+ ---
4
+
5
+ Resources can be removed form the sidebar by removing their index action from the routes. For example:
6
+
7
+ ```ruby
8
+ # config/routes.rb
9
+ Rails.application.routes.draw do
10
+ namespace :admin do
11
+ resources :line_items, except: :index
12
+ resources :orders
13
+ resources :products
14
+ root to: "customers#index"
15
+ end
16
+ end
17
+ ```
18
+
19
+ In this case, only Orders and Products will appear in the sidebar, while Line Items can still appear as an association.
data/docs/rails_api.md ADDED
@@ -0,0 +1,45 @@
1
+ ---
2
+ title: Rails API
3
+ ---
4
+
5
+ Since Rails 5.0, we've been able to have API only applications. Yet, sometimes
6
+ we still want to have an admin.
7
+
8
+ To get this working, we recommend updating this config:
9
+
10
+ ```ruby
11
+ # config/application.rb
12
+ config.api_only = false
13
+ ```
14
+
15
+ That means, when your app _boots_, we'll have access to flashes and such. We
16
+ also don't use your `ApplicationController`. Instead, Administrate provides its
17
+ own. Meaning you're free to specify `ActionController::API` as your parent
18
+ controller to make sure no flash, session, or cookie middleware is used by your
19
+ API.
20
+
21
+ Alternatively, if your application needs to have `config.api_only = true`, we
22
+ recommend you add the following lines to your `config/application.rb`
23
+
24
+ ```ruby
25
+ # Enable Flash, Cookies, MethodOverride for Administrate Gem
26
+ config.middleware.use ActionDispatch::Flash
27
+ config.session_store :cookie_store
28
+ config.middleware.use ActionDispatch::Cookies
29
+ config.middleware.use ActionDispatch::Session::CookieStore, config.session_options
30
+ config.middleware.use ::Rack::MethodOverride
31
+ ```
32
+
33
+ You must also ensure that all the required controller actions are available
34
+ and accessible as routes since generators in API-only applications only
35
+ generate some of the required actions. Here is an example:
36
+
37
+ ```ruby
38
+ # routes.rb
39
+ namespace :admin do
40
+ resources :name, only: %i(index show new create edit update destroy)
41
+ end
42
+
43
+ # names_controller.rb
44
+ # Ensure each of those methods are defined
45
+ ```
data/lib/administrate.rb CHANGED
@@ -1,4 +1,23 @@
1
1
  require "administrate/engine"
2
2
 
3
3
  module Administrate
4
+ def self.warn_of_missing_resource_class
5
+ ActiveSupport::Deprecation.warn(
6
+ "Calling Field::Base.permitted_attribute without the option " +
7
+ ":resource_class is deprecated. If you are seeing this " +
8
+ "message, you are probably using a custom field type that" +
9
+ "does this. Please make sure to update it to a version that " +
10
+ "does not use a deprecated API",
11
+ )
12
+ end
13
+
14
+ def self.warn_of_deprecated_option(name)
15
+ ActiveSupport::Deprecation.warn(
16
+ "The option :#{name} is deprecated. " +
17
+ "Administrate should detect it automatically. " +
18
+ "Please file an issue at " +
19
+ "https://github.com/thoughtbot/administrate/issues " +
20
+ "if you think otherwise.",
21
+ )
22
+ end
4
23
  end
@@ -1,6 +1,7 @@
1
1
  require "administrate/field/belongs_to"
2
2
  require "administrate/field/boolean"
3
3
  require "administrate/field/date_time"
4
+ require "administrate/field/date"
4
5
  require "administrate/field/email"
5
6
  require "administrate/field/has_many"
6
7
  require "administrate/field/has_one"
@@ -10,12 +11,25 @@ require "administrate/field/select"
10
11
  require "administrate/field/string"
11
12
  require "administrate/field/text"
12
13
  require "administrate/field/time"
14
+ require "administrate/field/url"
13
15
  require "administrate/field/password"
14
16
 
15
17
  module Administrate
16
18
  class BaseDashboard
17
19
  include Administrate
18
20
 
21
+ DASHBOARD_SUFFIX = "Dashboard".freeze
22
+
23
+ class << self
24
+ def model
25
+ to_s.chomp(DASHBOARD_SUFFIX).classify.constantize
26
+ end
27
+
28
+ def resource_name(opts)
29
+ model.model_name.human(opts)
30
+ end
31
+ end
32
+
19
33
  def attribute_types
20
34
  self.class::ATTRIBUTE_TYPES
21
35
  end
@@ -32,13 +46,20 @@ module Administrate
32
46
  end
33
47
  end
34
48
 
49
+ def all_attributes
50
+ attribute_types.keys
51
+ end
52
+
35
53
  def form_attributes
36
54
  self.class::FORM_ATTRIBUTES
37
55
  end
38
56
 
39
57
  def permitted_attributes
40
58
  form_attributes.map do |attr|
41
- attribute_types[attr].permitted_attribute(attr)
59
+ attribute_types[attr].permitted_attribute(
60
+ attr,
61
+ resource_class: self.class.model,
62
+ )
42
63
  end.uniq
43
64
  end
44
65
 
@@ -54,15 +75,12 @@ module Administrate
54
75
  "#{resource.class} ##{resource.id}"
55
76
  end
56
77
 
57
- def association_includes
58
- association_classes = [Field::HasMany, Field::HasOne, Field::BelongsTo]
59
-
60
- collection_attributes.map do |key|
61
- field = self.class::ATTRIBUTE_TYPES[key]
78
+ def collection_includes
79
+ attribute_includes(collection_attributes)
80
+ end
62
81
 
63
- next key if association_classes.include?(field)
64
- key if association_classes.include?(field.try :deferred_class)
65
- end.compact
82
+ def item_includes
83
+ attribute_includes(show_page_attributes)
66
84
  end
67
85
 
68
86
  private
@@ -70,5 +88,13 @@ module Administrate
70
88
  def attribute_not_found_message(attr)
71
89
  "Attribute #{attr} could not be found in #{self.class}::ATTRIBUTE_TYPES"
72
90
  end
91
+
92
+ def attribute_includes(attributes)
93
+ attributes.map do |key|
94
+ field = attribute_type_for(key)
95
+
96
+ key if field.associative?
97
+ end.compact
98
+ end
73
99
  end
74
100
  end
@@ -0,0 +1,15 @@
1
+ module Administrate
2
+ class CustomDashboard
3
+ include Administrate
4
+
5
+ class << self
6
+ def resource_name(_opts)
7
+ named_resource.pluralize.titleize
8
+ end
9
+
10
+ def resource(resource_name)
11
+ define_singleton_method(:named_resource) { resource_name }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,7 +2,7 @@ require "datetime_picker_rails"
2
2
  require "jquery-rails"
3
3
  require "kaminari"
4
4
  require "momentjs-rails"
5
- require "sass-rails"
5
+ require "sassc-rails"
6
6
  require "selectize-rails"
7
7
  require "sprockets/railtie"
8
8
 
@@ -22,6 +22,13 @@ module Administrate
22
22
  @@javascripts = []
23
23
  @@stylesheets = []
24
24
 
25
+ initializer "administrate.assets.precompile" do |app|
26
+ app.config.assets.precompile += [
27
+ "administrate/application.js",
28
+ "administrate/application.css",
29
+ ]
30
+ end
31
+
25
32
  def self.add_javascript(script)
26
33
  @@javascripts << script
27
34
  end
@@ -3,30 +3,74 @@ require_relative "base"
3
3
  module Administrate
4
4
  module Field
5
5
  class Associative < Base
6
+ def self.foreign_key_for(resource_class, attr)
7
+ reflection(resource_class, attr).foreign_key
8
+ end
9
+
10
+ def self.associated_class(resource_class, attr)
11
+ reflection(resource_class, attr).klass
12
+ end
13
+
14
+ def self.associated_class_name(resource_class, attr)
15
+ reflection(resource_class, attr).class_name
16
+ end
17
+
18
+ def self.reflection(resource_class, attr)
19
+ resource_class.reflect_on_association(attr)
20
+ end
21
+
6
22
  def display_associated_resource
7
23
  associated_dashboard.display_resource(data)
8
24
  end
9
25
 
10
26
  def associated_class
11
- associated_class_name.constantize
27
+ if option_given?(:class_name)
28
+ associated_class_name.constantize
29
+ else
30
+ self.class.associated_class(resource.class, attribute)
31
+ end
12
32
  end
13
33
 
14
- protected
34
+ private
15
35
 
16
36
  def associated_dashboard
17
37
  "#{associated_class_name}Dashboard".constantize.new
18
38
  end
19
39
 
20
40
  def associated_class_name
21
- options.fetch(:class_name, attribute.to_s.singularize.camelcase)
41
+ if option_given?(:class_name)
42
+ deprecated_option(:class_name)
43
+ else
44
+ self.class.associated_class_name(
45
+ resource.class,
46
+ attribute,
47
+ )
48
+ end
22
49
  end
23
50
 
24
51
  def primary_key
25
- options.fetch(:primary_key, :id)
52
+ if option_given?(:primary_key)
53
+ deprecated_option(:primary_key)
54
+ else
55
+ :id
56
+ end
26
57
  end
27
58
 
28
59
  def foreign_key
29
- options.fetch(:foreign_key, :"#{attribute}_id")
60
+ if option_given?(:foreign_key)
61
+ deprecated_option(:foreign_key)
62
+ else
63
+ self.class.foreign_key_for(resource.class, attribute)
64
+ end
65
+ end
66
+
67
+ def option_given?(name)
68
+ options.key?(name)
69
+ end
70
+
71
+ def deprecated_option(name)
72
+ Administrate.warn_of_deprecated_option(name)
73
+ options.fetch(name)
30
74
  end
31
75
  end
32
76
  end