godmin 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +12 -0
  5. data/README.md +58 -8
  6. data/Rakefile +45 -16
  7. data/app/views/godmin/resource/show.html.erb +1 -1
  8. data/app/views/layouts/godmin/_layout.html.erb +1 -0
  9. data/app/views/layouts/godmin/application.html.erb +7 -1
  10. data/config/locales/en.yml +1 -1
  11. data/config/locales/pt-BR.yml +44 -0
  12. data/config/locales/sv.yml +1 -1
  13. data/godmin.gemspec +2 -1
  14. data/lib/generators/godmin/authentication/authentication_generator.rb +1 -1
  15. data/lib/godmin/application_controller.rb +1 -1
  16. data/lib/godmin/generators/named_base.rb +8 -0
  17. data/lib/godmin/resolver.rb +44 -18
  18. data/lib/godmin/resources/resource_controller.rb +17 -30
  19. data/lib/godmin/resources/resource_controller/batch_actions.rb +49 -0
  20. data/lib/godmin/version.rb +1 -1
  21. data/template.rb +180 -18
  22. data/test/dummy/admin/app/assets/javascripts/admin/application.js +1 -0
  23. data/test/dummy/app/assets/javascripts/application.js +1 -0
  24. data/test/dummy/app/controllers/application_controller.rb +2 -2
  25. data/test/dummy/app/controllers/articles_controller.rb +10 -0
  26. data/test/dummy/app/services/article_service.rb +31 -0
  27. data/test/dummy/app/services/secret_article_service.rb +0 -7
  28. data/test/dummy/db/migrate/20150717121532_create_articles.rb +1 -1
  29. data/test/dummy/db/schema.rb +3 -3
  30. data/test/integration/batch_actions_test.rb +51 -0
  31. data/test/integration/filters_test.rb +21 -0
  32. data/test/integration/scopes_test.rb +23 -0
  33. data/test/lib/godmin/resolver_test.rb +22 -8
  34. data/test/test_helper.rb +19 -3
  35. metadata +25 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d8d8456ed97a4b0447080f6faecfcb647dec74de
4
- data.tar.gz: 80c9d86243368a78a4f40d9b684a3aabb90c396a
3
+ metadata.gz: 19ea145e85a221046da2c5f9bac8653bf16fa24f
4
+ data.tar.gz: 9fa954f22350d6891ba27cbc999f6f54572fbbb8
5
5
  SHA512:
6
- metadata.gz: 33c8e7b29d921d19f61057f023ffb15987fe9bee65c4544a2ec77b834d9a7c8775765d56c5ec3e91ae8601b11ad94c532c1664676d6e7e7b6b4c84ea30acd076
7
- data.tar.gz: 8dcccc5c59e0b6b7890694ca06d9075779387aebc1a13f21122be7f4af97f491da77e4fd6c13b33ccfbd1fd7a7e78073afd33ec83d04e89079046a037a900e0a
6
+ metadata.gz: 8468f4af31b9a57d6cf81429294e7d97140cd9609c607af195c792d9971b84138ec3fddab1259115de77b38a0404bf4538d368e023ba07ef350d22c802cc6dc7
7
+ data.tar.gz: c4d0f3a0f7dd3e76a7909682d0e40aa6f3b97a61746e72673ab1a724def65863cf2905a59c8d646b62f9ba823e456c2ccec2cf070573c54bf16d485210c74e9f
data/.rubocop.yml CHANGED
@@ -10,6 +10,9 @@ Metrics/LineLength:
10
10
  Metrics/ClassLength:
11
11
  Max: 300
12
12
 
13
+ Metrics/ModuleLength:
14
+ Max: 300
15
+
13
16
  Metrics/MethodLength:
14
17
  Max: 25
15
18
 
data/.travis.yml CHANGED
@@ -7,6 +7,7 @@ cache: bundler
7
7
  rvm:
8
8
  - 2.0.0
9
9
  - 2.1
10
+ - 2.2
10
11
 
11
12
  addons:
12
13
  code_climate:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ### 1.1.0 - 2015-12-08
4
+ Features
5
+ - Adds locale for pt-BR (Brazilian Portuguese) (https://github.com/varvet/godmin/pull/141)
6
+ - New sandbox template with with more examples (https://github.com/varvet/godmin/pull/135)
7
+ - Permits belongs to association by default (https://github.com/varvet/godmin/pull/149)
8
+ - Enables responsive design (https://github.com/varvet/godmin/pull/146)
9
+ - Batch actions now receive a relation instead of an array (https://github.com/varvet/godmin/pull/158)
10
+
11
+ Bug fixes
12
+ - Fixes a bug that masked errors in templates with a template not found error (https://github.com/varvet/godmin/pull/142)
13
+ - Fixes a namespace issue with the authentication generator (https://github.com/varvet/godmin/pull/150)
14
+
3
15
  ### 1.0.0 - 2015-11-13
4
16
  Release of 1.0.0 :tada:
5
17
 
data/README.md CHANGED
@@ -168,6 +168,11 @@ Using `attrs_for_index` we can control what fields are displayed in the table li
168
168
  attrs_for_form :title, :body, :published
169
169
  ```
170
170
 
171
+ For quick prototyping, we could build the parameters this way (if appropriate).
172
+ ```ruby
173
+ attrs_for_show *Article.column_names
174
+ ```
175
+
171
176
  By now we have a basic admin interface for managing articles.
172
177
 
173
178
  ## Resources
@@ -213,7 +218,7 @@ class ArticleService
213
218
  end
214
219
  ```
215
220
 
216
- There are four types of filters: `string`, `select`, `multiselect` and `checkboxes`, specified using the `as` parameter.
221
+ There are three types of filters: `string`, `select` and `multiselect`, specified using the `as` parameter.
217
222
 
218
223
  When using `select` or `multiselect`, a collection must be specified. The collection must conform to the format used by Rails `options_for_select` helpers. It can be either an array consisting of name/value tuples, or a collection of ActiveRecords.
219
224
 
@@ -295,7 +300,7 @@ class ArticleService
295
300
  end
296
301
  ```
297
302
 
298
- To scope resources, e.g. based on the signed in user:
303
+ To scope resources for quering and building, e.g. based on the signed in user:
299
304
 
300
305
  ```ruby
301
306
  class ArticleService
@@ -303,19 +308,19 @@ class ArticleService
303
308
 
304
309
  # The signed in admin user is available to all service objects via the options hash
305
310
  def resources_relation
306
- options[:admin_user].articles
311
+ super.where(user: options[:admin_user])
307
312
  end
308
313
  end
309
314
  ```
310
315
 
311
- To add to the resources query, e.g. to change the default order:
316
+ To add to the index page resources query, e.g. to change the default order:
312
317
 
313
318
  ```ruby
314
319
  class ArticleService
315
320
  include Godmin::Resources::ResourceService
316
321
 
317
- def resources
318
- super.order(author: :desc)
322
+ def resources(params)
323
+ super(params).order(author: :desc)
319
324
  end
320
325
  end
321
326
  ```
@@ -401,6 +406,36 @@ class ArticlesController < ApplicationController
401
406
  end
402
407
  ```
403
408
 
409
+ #### Passing parameters to the service object
410
+
411
+ Sometimes you want to pass additional params to the service object, other that those passed in `resource_params`. In order to do this, you need to pass them along when initializing the service object in the controller:
412
+
413
+ ```ruby
414
+ class ArticlesController < ApplicationController
415
+ include Godmin::Resources::ResourceController
416
+
417
+ private
418
+
419
+ def resource_service
420
+ service = super
421
+ service.options[:some_param] = params[:some_param]
422
+ service
423
+ end
424
+ end
425
+ ```
426
+
427
+ You can then access it from the service object:
428
+
429
+ ```ruby
430
+ class ArticleService
431
+ include Godmin::Resources::ResourceService
432
+
433
+ def some_method
434
+ options[:some_param]
435
+ end
436
+ end
437
+ ```
438
+
404
439
  ### Redirecting
405
440
 
406
441
  By default the user is redirected to the resource show page after create and update, and to the index page after destroy. To change this, there are four controller methods that can be overridden: `redirect_after_create`, `redirect_after_update`, `redirect_after_save`, and `redirect_after_destroy`.
@@ -481,6 +516,13 @@ end
481
516
 
482
517
  It's easy to override view templates and partials in Godmin, both globally and per resource. All you have to do is place a file with an identical name in your `app/views` directory. For instance, to override the `godmin/resource/index.html.erb` template for all resources, place a file under `app/views/resource/index.html.erb`. If you only wish to override it for articles, place it instead under `app/views/articles/index.html.erb`.
483
518
 
519
+ You can also inherit from the default template as such:
520
+ ```ruby
521
+ <%= render template: 'godmin/resource/show' %>
522
+
523
+ <p>Append stuff here</p>
524
+ ```
525
+
484
526
  If you wish to customize the content of a table column, you can place a partial under `app/views/{resource}/columns/{column_name}.html.erb`, e.g. `app/views/articles/columns/_title.html.erb`. The resource is available to the partial through the `resource` variable.
485
527
 
486
528
  The full list of templates and partials that can be overridden [can be found here](https://github.com/varvet/godmin/tree/master/app/views/godmin).
@@ -737,12 +779,12 @@ end
737
779
  ```
738
780
 
739
781
  ### Batch action authorization
740
- Batch actions must be authorized in your policy if you are using Godmin's built in authorization functionality. The policy method is called once for each record before they are passed to the batch action method defined by the user. If a user is not allowed to "batch action" a particular record, it will be filtered out before passed to the batch action method. Note that this does not raise any `NotAuthorizedError`.
782
+ Batch actions must be authorized in your policy if you are using Godmin's built in authorization functionality. The policy method is called with the relation containing all records to be processed.
741
783
 
742
784
  ```ruby
743
785
  class ArticlePolicy < Godmin::Authorization::Policy
744
786
  def batch_action_destroy?
745
- @record.user_id == user.id
787
+ record.all? { |r| r.user_id == user.id }
746
788
  end
747
789
  end
748
790
  ```
@@ -832,6 +874,14 @@ If you wish to translate the datetimepicker, change `moment/en-gb` in your `app/
832
874
 
833
875
  Please note that the datepickers default to en-GB, not en-US, because Rails cannot automatically parse en-US dates.
834
876
 
877
+ To use an alternative format, use the format option.
878
+
879
+ ```js
880
+ Godmin.Datetimepickers.initializeDatepicker($elems, {
881
+ format: 'YYYY-MM-DD'
882
+ });
883
+ ```
884
+
835
885
  ### Select boxes
836
886
 
837
887
  Make a [selectize.js](http://brianreavis.github.io/selectize.js/) select box out of a text field or select box:
data/Rakefile CHANGED
@@ -1,34 +1,63 @@
1
1
  begin
2
- require 'bundler/setup'
2
+ require "bundler/setup"
3
3
  rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
4
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
5
  end
6
6
 
7
- require 'rdoc/task'
7
+ require "rdoc/task"
8
8
 
9
9
  RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'Godmin'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.rdoc')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
10
+ rdoc.rdoc_dir = "rdoc"
11
+ rdoc.title = "Godmin"
12
+ rdoc.options << "--line-numbers"
13
+ rdoc.rdoc_files.include("README.rdoc")
14
+ rdoc.rdoc_files.include("lib/**/*.rb")
15
15
  end
16
16
 
17
17
  APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
- load 'rails/tasks/engine.rake'
19
-
20
-
18
+ load "rails/tasks/engine.rake"
21
19
 
22
20
  Bundler::GemHelper.install_tasks
23
21
 
24
- require 'rake/testtask'
22
+ require "rake/testtask"
25
23
 
26
24
  Rake::TestTask.new(:test) do |t|
27
- t.libs << 'lib'
28
- t.libs << 'test'
29
- t.pattern = 'test/**/*_test.rb'
25
+ t.libs << "lib"
26
+ t.libs << "test"
27
+ t.pattern = "test/**/*_test.rb"
30
28
  t.verbose = false
31
29
  end
32
30
 
33
-
34
31
  task default: :test
32
+
33
+ namespace :sandbox do
34
+ desc "Push the sandbox app to GitHub which deploys it to Heroku"
35
+ task :deploy do
36
+ message = "Generated from: https://github.com/varvet/godmin/commit/#{`git rev-parse HEAD`.strip}"
37
+ template_path = File.expand_path("../template.rb", __FILE__)
38
+ Bundler.with_clean_env do
39
+ Dir.mktmpdir do |dir|
40
+ Dir.chdir(dir)
41
+ system("git clone git@github.com:varvet/godmin-sandbox.git")
42
+ if $CHILD_STATUS.success?
43
+ Dir.chdir("godmin-sandbox")
44
+ system("rm -rf *")
45
+ system("rails new . -d postgresql -m #{template_path} --without-engine")
46
+ if $CHILD_STATUS.success?
47
+ system("git add --all")
48
+ system("git commit -m '#{message}'")
49
+ system("git push origin master")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ desc "Empty and reseed the database on Heroku"
57
+ task :reseed do
58
+ app = "godmin-sandbox"
59
+ Bundler.with_clean_env do
60
+ system("heroku run rake sandbox:reseed --app #{app}")
61
+ end
62
+ end
63
+ end
@@ -1,6 +1,6 @@
1
1
  <%= render partial: "breadcrumb" %>
2
2
 
3
- <table class="table table-bordere table-striped">
3
+ <table class="table table-striped">
4
4
  <% @resource_service.attrs_for_show.each do |attr| %>
5
5
  <tr>
6
6
  <th><%= @resource_class.human_attribute_name(attr) %></th>
@@ -5,6 +5,7 @@
5
5
  <%= stylesheet_link_tag File.join(engine_wrapper.namespaced_path, "application").gsub(/^\//, ""), media: "all" %>
6
6
  <%= javascript_include_tag File.join(engine_wrapper.namespaced_path, "application").gsub(/^\//, "") %>
7
7
  <%= csrf_meta_tags %>
8
+ <meta name="viewport" content="width=device-width, initial-scale=1">
8
9
  <%= yield :head %>
9
10
  </head>
10
11
  <body>
@@ -2,9 +2,15 @@
2
2
  <nav class="navbar navbar-default navbar-static-top" role="navigation">
3
3
  <div class="container">
4
4
  <div class="navbar-header">
5
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#godmin-navbar-collapse" aria-expanded="false">
6
+ <span class="sr-only">Toggle navigation</span>
7
+ <span class="icon-bar"></span>
8
+ <span class="icon-bar"></span>
9
+ <span class="icon-bar"></span>
10
+ </button>
5
11
  <%= link_to t("godmin.title"), root_path, class: "navbar-brand" %>
6
12
  </div>
7
- <div class="collapse navbar-collapse">
13
+ <div class="collapse navbar-collapse" id="godmin-navbar-collapse">
8
14
  <ul class="nav navbar-nav">
9
15
  <%= render partial: File.join(engine_wrapper.namespaced_path, "shared/navigation") %>
10
16
  </ul>
@@ -32,7 +32,7 @@ en:
32
32
  create: "%{resource} was successfully created"
33
33
  update: "%{resource} was successfully updated"
34
34
  destroy: "%{resource} was successfully destroyed"
35
- batch_action: "%{number_of_affected_records} of %{total_number_of_records} %{resource} were affected"
35
+ batch_action: "%{number_of_records} %{resource} were affected"
36
36
  pagination:
37
37
  first: "First"
38
38
  last: "Last"
@@ -0,0 +1,44 @@
1
+ pt-BR:
2
+ godmin:
3
+ title: Godmin
4
+ batch_actions:
5
+ buttons:
6
+ select_all: Selecionar todos
7
+ deselect_all: Remover seleção
8
+ confirm_message: Você tem certeza?
9
+ filters:
10
+ select:
11
+ placeholder:
12
+ one: Selecionar um
13
+ many: Selecionar vários
14
+ buttons:
15
+ apply: Filtrar
16
+ clear: Limpar filtro
17
+ actions:
18
+ label: Ações
19
+ show: Exibir
20
+ edit: Editar
21
+ destroy: Remover
22
+ confirm_message: Você tem certeza?
23
+ export: Exportar
24
+ export_as: Como
25
+ sessions:
26
+ sign_in: Entrar
27
+ sign_out: Sair
28
+ signed_in: Conectado
29
+ signed_out: Desconectado
30
+ failed_sign_in: Credenciais inválidas
31
+ flash:
32
+ create: "%{resource} foi criado com sucesso"
33
+ update: "%{resource} foi atualizado com sucesso"
34
+ destroy: "%{resource} foi removido com sucesso"
35
+ batch_action: "%{number_of_records} %{resource} foram modificados"
36
+ pagination:
37
+ first: "Primeiro"
38
+ last: "Último"
39
+ entries:
40
+ zero: "Nenhum %{resource} encontrado"
41
+ other: "Exibindo %{count} de %{total} %{resource}"
42
+ datetimepickers:
43
+ datepicker: ! "%d/%m/%Y"
44
+ datetimepicker: ! "%d/%m/%Y %H:%M"
@@ -32,7 +32,7 @@ sv:
32
32
  create: "%{resource} skapades"
33
33
  update: "%{resource} uppdaterades"
34
34
  destroy: "%{resource} togs bort"
35
- batch_action: "%{number_of_affected_records} av %{total_number_of_records} %{resource} påverkades"
35
+ batch_action: "%{number_of_records} %{resource} påverkades"
36
36
  pagination:
37
37
  first: "Första"
38
38
  last: "Sista"
data/godmin.gemspec CHANGED
@@ -32,8 +32,9 @@ Gem::Specification.new do |gem|
32
32
 
33
33
  gem.add_development_dependency "capybara"
34
34
  gem.add_development_dependency "m"
35
- gem.add_development_dependency "minitest"
36
35
  gem.add_development_dependency "minitest-reporters"
36
+ gem.add_development_dependency "minitest"
37
+ gem.add_development_dependency "poltergeist"
37
38
  gem.add_development_dependency "pry"
38
39
  gem.add_development_dependency "sqlite3"
39
40
  end
@@ -33,7 +33,7 @@ class Godmin::AuthenticationGenerator < Godmin::Generators::NamedBase
33
33
  include Godmin::Authentication
34
34
 
35
35
  def admin_user_class
36
- #{class_name}
36
+ #{full_class_name}
37
37
  end
38
38
  END
39
39
  end
@@ -33,7 +33,7 @@ module Godmin
33
33
  end
34
34
 
35
35
  def append_view_paths
36
- append_view_path Godmin::Resolver.new(controller_path, engine_wrapper)
36
+ append_view_path Godmin::Resolver.resolvers(controller_path, engine_wrapper)
37
37
  end
38
38
 
39
39
  def authentication_enabled?
@@ -7,6 +7,14 @@ module Godmin
7
7
 
8
8
  private
9
9
 
10
+ def full_class_name
11
+ if namespace
12
+ "#{namespace}::#{class_name}"
13
+ else
14
+ class_name
15
+ end
16
+ end
17
+
10
18
  def class_name
11
19
  @class_name ||= name.classify
12
20
  end
@@ -1,7 +1,14 @@
1
1
  module Godmin
2
2
  class Resolver < ::ActionView::FileSystemResolver
3
- def initialize(controller_path, engine_wrapper)
4
- super ""
3
+ def self.resolvers(controller_path, engine_wrapper)
4
+ [
5
+ EngineResolver.new(controller_path, engine_wrapper),
6
+ GodminResolver.new(controller_path, engine_wrapper)
7
+ ]
8
+ end
9
+
10
+ def initialize(path, controller_path, engine_wrapper)
11
+ super(path)
5
12
  @controller_path = controller_path
6
13
  @engine_wrapper = engine_wrapper
7
14
  end
@@ -19,34 +26,53 @@ module Godmin
19
26
 
20
27
  templates
21
28
  end
29
+ end
30
+
31
+ # Matches templates such as:
32
+ #
33
+ # { name: index, prefix: articles } => app/views/resource/index
34
+ # { name: form, prefix: articles } => app/views/resource/_form
35
+ # { name: title, prefix: columns } => app/views/resource/columns/_title
36
+ class EngineResolver < Resolver
37
+ def initialize(controller_path, engine_wrapper)
38
+ super(File.join(engine_wrapper.root, "app/views"), controller_path, engine_wrapper)
39
+ end
22
40
 
23
- # Matches templates such as:
24
- #
25
- # { name: index, prefix: articles } => [app/views/resource/index, godmin/app/views/godmin/resource/index]
26
- # { name: form, prefix: articles } => [app/views/resource/_form, godmin/app/views/godmin/resource/_form]
27
- # { name: title, prefix: columns } => [app/views/resource/columns/_title]
28
- # { name: welcome, prefix: application } => [godmin/app/views/godmin/application/welcome]
29
- # { name: navigation, prefix: shared } => [godmin/app/views/godmin/shared/navigation]
30
41
  def template_paths(prefix)
31
42
  [
32
- File.join(@engine_wrapper.root, "app/views", resource_path_for_engine(prefix)),
33
- File.join(Godmin::Engine.root, "app/views/godmin", default_path_for_godmin(prefix)),
34
- File.join(Godmin::Engine.root, "app/views/godmin", resource_path_for_godmin(prefix))
43
+ resource_path_for_engine(prefix)
35
44
  ]
36
45
  end
37
46
 
38
- private
39
-
40
47
  def resource_path_for_engine(prefix)
41
- prefix.sub(/\A#{@controller_path}/, File.join(@engine_wrapper.namespaced_path, "resource"))
48
+ prefix.sub(/\A#{@controller_path}/, File.join(@engine_wrapper.namespaced_path, "resource")).sub(/\A\//, "")
42
49
  end
50
+ end
43
51
 
44
- def resource_path_for_godmin(prefix)
45
- prefix.sub(/\A#{@controller_path}/, "resource")
52
+ # Matches templates such as:
53
+ #
54
+ # { name: index, prefix: articles } => godmin/app/views/godmin/resource/index
55
+ # { name: form, prefix: articles } => godmin/app/views/godmin/resource/_form
56
+ # { name: welcome, prefix: application } => godmin/app/views/godmin/application/welcome
57
+ # { name: navigation, prefix: shared } => godmin/app/views/godmin/shared/navigation
58
+ class GodminResolver < Resolver
59
+ def initialize(controller_path, engine_wrapper)
60
+ super(File.join(Godmin::Engine.root, "app/views/godmin"), controller_path, engine_wrapper)
61
+ end
62
+
63
+ def template_paths(prefix)
64
+ [
65
+ default_path_for_godmin(prefix),
66
+ resource_path_for_godmin(prefix)
67
+ ]
46
68
  end
47
69
 
48
70
  def default_path_for_godmin(prefix)
49
- prefix.sub(/\A#{File.join(@engine_wrapper.namespaced_path)}/, "")
71
+ prefix.sub(/\A#{File.join(@engine_wrapper.namespaced_path)}/, "").sub(/\A\//, "")
72
+ end
73
+
74
+ def resource_path_for_godmin(prefix)
75
+ prefix.sub(/\A#{@controller_path}/, "resource").sub(/\A\//, "")
50
76
  end
51
77
  end
52
78
  end