typus-rails4 4.0.0.beta6

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 (198) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +488 -0
  3. data/Gemfile +57 -0
  4. data/Gemfile.lock +253 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +101 -0
  7. data/Rakefile +51 -0
  8. data/app/assets/javascripts/typus/application.js +11 -0
  9. data/app/assets/javascripts/typus/custom.js +2 -0
  10. data/app/assets/javascripts/typus/jquery-2.1.1.min.js +4 -0
  11. data/app/assets/javascripts/typus/jquery.application.js +30 -0
  12. data/app/assets/stylesheets/typus/application.css +6 -0
  13. data/app/assets/stylesheets/typus/custom.scss +4 -0
  14. data/app/assets/stylesheets/typus/overrides.scss +10 -0
  15. data/app/assets/stylesheets/typus/signin.scss +45 -0
  16. data/app/controllers/admin/account_controller.rb +47 -0
  17. data/app/controllers/admin/base_controller.rb +40 -0
  18. data/app/controllers/admin/dashboard_controller.rb +6 -0
  19. data/app/controllers/admin/resource_controller.rb +8 -0
  20. data/app/controllers/admin/resources_controller.rb +268 -0
  21. data/app/controllers/admin/session_controller.rb +43 -0
  22. data/app/controllers/concerns/admin/actions.rb +88 -0
  23. data/app/controllers/concerns/admin/acts_as_list.rb +35 -0
  24. data/app/controllers/concerns/admin/ancestry.rb +26 -0
  25. data/app/controllers/concerns/admin/autocomplete.rb +11 -0
  26. data/app/controllers/concerns/admin/bulk.rb +76 -0
  27. data/app/controllers/concerns/admin/featured_image.rb +22 -0
  28. data/app/controllers/concerns/admin/filters.rb +57 -0
  29. data/app/controllers/concerns/admin/format.rb +49 -0
  30. data/app/controllers/concerns/admin/headless.rb +23 -0
  31. data/app/controllers/concerns/admin/hooks.rb +4 -0
  32. data/app/controllers/concerns/admin/multisite.rb +10 -0
  33. data/app/controllers/concerns/admin/navigation.rb +27 -0
  34. data/app/controllers/concerns/admin/trash.rb +65 -0
  35. data/app/helpers/admin/base_helper.rb +78 -0
  36. data/app/helpers/admin/resources/data_types/belongs_to_helper.rb +88 -0
  37. data/app/helpers/admin/resources/data_types/boolean_helper.rb +33 -0
  38. data/app/helpers/admin/resources/data_types/date_helper.rb +16 -0
  39. data/app/helpers/admin/resources/data_types/datetime_helper.rb +19 -0
  40. data/app/helpers/admin/resources/data_types/dragonfly_helper.rb +49 -0
  41. data/app/helpers/admin/resources/data_types/float_helper.rb +2 -0
  42. data/app/helpers/admin/resources/data_types/has_and_belongs_to_many_helper.rb +59 -0
  43. data/app/helpers/admin/resources/data_types/has_many_helper.rb +76 -0
  44. data/app/helpers/admin/resources/data_types/has_one_helper.rb +44 -0
  45. data/app/helpers/admin/resources/data_types/integer_helper.rb +13 -0
  46. data/app/helpers/admin/resources/data_types/paperclip_helper.rb +49 -0
  47. data/app/helpers/admin/resources/data_types/selector_helper.rb +11 -0
  48. data/app/helpers/admin/resources/data_types/string_helper.rb +38 -0
  49. data/app/helpers/admin/resources/data_types/text_helper.rb +6 -0
  50. data/app/helpers/admin/resources/data_types/transversal_helper.rb +8 -0
  51. data/app/helpers/admin/resources/data_types/tree_helper.rb +28 -0
  52. data/app/helpers/admin/resources/display_helper.rb +27 -0
  53. data/app/helpers/admin/resources/filters_helper.rb +18 -0
  54. data/app/helpers/admin/resources/form_helper.rb +85 -0
  55. data/app/helpers/admin/resources/list_helper.rb +31 -0
  56. data/app/helpers/admin/resources/pagination_helper.rb +28 -0
  57. data/app/helpers/admin/resources/relationships_helper.rb +33 -0
  58. data/app/helpers/admin/resources/sidebar_helper.rb +34 -0
  59. data/app/helpers/admin/resources/table_helper.rb +69 -0
  60. data/app/helpers/admin/resources_helper.rb +25 -0
  61. data/app/mailers/admin/mailer.rb +19 -0
  62. data/app/views/admin/account/_form.html.erb +17 -0
  63. data/app/views/admin/account/forgot_password.html.erb +16 -0
  64. data/app/views/admin/account/new.html.erb +10 -0
  65. data/app/views/admin/dashboard/_sidebar.html.erb +14 -0
  66. data/app/views/admin/dashboard/index.html.erb +8 -0
  67. data/app/views/admin/dashboard/styles.html.erb +153 -0
  68. data/app/views/admin/dashboard/widgets/_applications.html.erb +44 -0
  69. data/app/views/admin/dashboard/widgets/_default.html.erb +43 -0
  70. data/app/views/admin/dashboard/widgets/_models.html.erb +23 -0
  71. data/app/views/admin/dashboard/widgets/_models_extended.html.erb +25 -0
  72. data/app/views/admin/dashboard/widgets/_resources.html.erb +23 -0
  73. data/app/views/admin/dashboard/widgets/_users.html.erb +23 -0
  74. data/app/views/admin/mailer/reset_password_instructions.html.erb +7 -0
  75. data/app/views/admin/mailer/reset_password_instructions.text.erb +7 -0
  76. data/app/views/admin/resource/_sidebar.html.erb +14 -0
  77. data/app/views/admin/resources/_edit.html.erb +0 -0
  78. data/app/views/admin/resources/_form.html.erb +28 -0
  79. data/app/views/admin/resources/_form_javascripts.html.erb +0 -0
  80. data/app/views/admin/resources/_form_modal.html.erb +13 -0
  81. data/app/views/admin/resources/_index.html.erb +0 -0
  82. data/app/views/admin/resources/_new.html.erb +0 -0
  83. data/app/views/admin/resources/_pagination.html.erb +15 -0
  84. data/app/views/admin/resources/_show.html.erb +0 -0
  85. data/app/views/admin/resources/_sidebar.html.erb +1 -0
  86. data/app/views/admin/resources/destroy.html.erb +16 -0
  87. data/app/views/admin/resources/edit.html.erb +22 -0
  88. data/app/views/admin/resources/edit/_actions.html.erb +7 -0
  89. data/app/views/admin/resources/edit/_recently_edited.html.erb +8 -0
  90. data/app/views/admin/resources/index.html.erb +29 -0
  91. data/app/views/admin/resources/new.html.erb +20 -0
  92. data/app/views/admin/resources/show.html.erb +26 -0
  93. data/app/views/admin/session/new.html.erb +18 -0
  94. data/app/views/admin/shared/_head.html.erb +24 -0
  95. data/app/views/admin/shared/_modals.html.erb +3 -0
  96. data/app/views/admin/shared/_sidebar_placeholder.html.erb +0 -0
  97. data/app/views/admin/templates/README.md +5 -0
  98. data/app/views/admin/templates/_belongs_to.html.erb +8 -0
  99. data/app/views/admin/templates/_boolean.html.erb +7 -0
  100. data/app/views/admin/templates/_date.html.erb +6 -0
  101. data/app/views/admin/templates/_datetime.html.erb +8 -0
  102. data/app/views/admin/templates/_dragonfly.html.erb +6 -0
  103. data/app/views/admin/templates/_dragonfly_form_preview.html.erb +21 -0
  104. data/app/views/admin/templates/_dragonfly_preview.html.erb +12 -0
  105. data/app/views/admin/templates/_has_and_belongs_to_many.html.erb +21 -0
  106. data/app/views/admin/templates/_has_many.html.erb +18 -0
  107. data/app/views/admin/templates/_has_one.html.erb +14 -0
  108. data/app/views/admin/templates/_json.html.erb +11 -0
  109. data/app/views/admin/templates/_paperclip.html.erb +5 -0
  110. data/app/views/admin/templates/_paperclip_form_preview.html.erb +21 -0
  111. data/app/views/admin/templates/_paperclip_preview.html.erb +12 -0
  112. data/app/views/admin/templates/_password.html.erb +6 -0
  113. data/app/views/admin/templates/_position.html.erb +5 -0
  114. data/app/views/admin/templates/_profile_sidebar.html.erb +4 -0
  115. data/app/views/admin/templates/_selector.html.erb +4 -0
  116. data/app/views/admin/templates/_string.html.erb +4 -0
  117. data/app/views/admin/templates/_string_with_preview.html.erb +11 -0
  118. data/app/views/admin/templates/_text.html.erb +11 -0
  119. data/app/views/admin/templates/_text_with_ckeditor.html.erb +24 -0
  120. data/app/views/admin/templates/_text_with_ckeditor_and_assets.html.erb +38 -0
  121. data/app/views/admin/templates/_time.html.erb +9 -0
  122. data/app/views/admin/templates/_tree.html.erb +6 -0
  123. data/app/views/admin/templates/modals/_belongs_to.html.erb +60 -0
  124. data/app/views/admin/templates/modals/_dragonfly.html.erb +13 -0
  125. data/app/views/admin/templates/modals/_has_and_belongs_to_many.html.erb +25 -0
  126. data/app/views/admin/templates/modals/_has_many.html.erb +59 -0
  127. data/app/views/admin/templates/modals/_paperclip.html.erb +13 -0
  128. data/app/views/helpers/admin/base/_apps.html.erb +86 -0
  129. data/app/views/helpers/admin/base/_breadcrumbs.html.erb +6 -0
  130. data/app/views/helpers/admin/base/_flash_message.html.erb +3 -0
  131. data/app/views/helpers/admin/base/_login_info.html.erb +0 -0
  132. data/app/views/helpers/admin/dashboard/_resources.html.erb +19 -0
  133. data/app/views/helpers/admin/resources/_actions.html.erb +18 -0
  134. data/app/views/helpers/admin/resources/_errors.html.erb +12 -0
  135. data/app/views/helpers/admin/resources/_filters.html.erb +16 -0
  136. data/app/views/helpers/admin/resources/_search.html.erb +17 -0
  137. data/app/views/helpers/admin/resources/_sidebar.html.erb +4 -0
  138. data/app/views/helpers/admin/resources/_table.html.erb +45 -0
  139. data/app/views/helpers/admin/resources/sidebar/_item.html.erb +26 -0
  140. data/app/views/helpers/admin/resources/sidebar/_items.html.erb +14 -0
  141. data/app/views/helpers/admin/resources/sidebar/_items_index.html.erb +57 -0
  142. data/app/views/layouts/admin/base.html.erb +30 -0
  143. data/app/views/layouts/admin/headless.html.erb +1 -0
  144. data/app/views/layouts/admin/session.html.erb +26 -0
  145. data/bin/run-tests +7 -0
  146. data/bin/setup +9 -0
  147. data/config/locales/typus.en.yml +125 -0
  148. data/config/routes.rb +46 -0
  149. data/lib/generators/templates/config/initializers/typus.rb +34 -0
  150. data/lib/generators/templates/config/initializers/typus_authentication.rb +18 -0
  151. data/lib/generators/templates/config/initializers/typus_resources.rb +24 -0
  152. data/lib/generators/templates/config/typus/README +58 -0
  153. data/lib/generators/templates/config/typus/application.yml +3 -0
  154. data/lib/generators/templates/config/typus/application_roles.yml +4 -0
  155. data/lib/generators/templates/config/typus/typus.yml +15 -0
  156. data/lib/generators/templates/config/typus/typus_roles.yml +4 -0
  157. data/lib/generators/templates/controller.erb +2 -0
  158. data/lib/generators/templates/migration.erb +22 -0
  159. data/lib/generators/templates/view.html.erb +13 -0
  160. data/lib/generators/typus/config_generator.rb +67 -0
  161. data/lib/generators/typus/controller_generator.rb +26 -0
  162. data/lib/generators/typus/initializers_generator.rb +20 -0
  163. data/lib/generators/typus/migration_generator.rb +94 -0
  164. data/lib/generators/typus/model_generator.rb +93 -0
  165. data/lib/generators/typus/typus_generator.rb +54 -0
  166. data/lib/generators/typus/views_generator.rb +19 -0
  167. data/lib/support/active_record.rb +42 -0
  168. data/lib/support/fake_user.rb +47 -0
  169. data/lib/support/hash.rb +8 -0
  170. data/lib/support/object.rb +9 -0
  171. data/lib/support/string.rb +40 -0
  172. data/lib/tasks/typus.rake +11 -0
  173. data/lib/typus.rb +215 -0
  174. data/lib/typus/authentication/base.rb +39 -0
  175. data/lib/typus/authentication/devise.rb +19 -0
  176. data/lib/typus/authentication/http_basic.rb +18 -0
  177. data/lib/typus/authentication/none.rb +15 -0
  178. data/lib/typus/authentication/none_with_role.rb +15 -0
  179. data/lib/typus/authentication/session.rb +123 -0
  180. data/lib/typus/configuration.rb +43 -0
  181. data/lib/typus/engine.rb +4 -0
  182. data/lib/typus/orm/active_record.rb +10 -0
  183. data/lib/typus/orm/active_record/admin_user.rb +65 -0
  184. data/lib/typus/orm/active_record/class_methods.rb +104 -0
  185. data/lib/typus/orm/active_record/instance_methods.rb +76 -0
  186. data/lib/typus/orm/active_record/search.rb +43 -0
  187. data/lib/typus/orm/base/class_methods.rb +188 -0
  188. data/lib/typus/orm/base/search.rb +70 -0
  189. data/lib/typus/regex.rb +11 -0
  190. data/lib/typus/resources.rb +55 -0
  191. data/lib/typus/version.rb +10 -0
  192. data/typus.gemspec +27 -0
  193. data/vendor/assets/chosen/LICENSE.md +24 -0
  194. data/vendor/assets/chosen/chosen-sprite.png +0 -0
  195. data/vendor/assets/chosen/chosen-sprite@2x.png +0 -0
  196. data/vendor/assets/chosen/chosen.jquery.js +1239 -0
  197. data/vendor/assets/chosen/chosen.scss +437 -0
  198. metadata +271 -0
@@ -0,0 +1,43 @@
1
+ class Admin::SessionController < Admin::BaseController
2
+
3
+ skip_before_filter :reload_config_and_roles, :authenticate
4
+
5
+ before_filter :create_an_account?, only: [:new, :create]
6
+
7
+ def new
8
+ end
9
+
10
+ def create
11
+ email, password = admin_user_params[:email], admin_user_params[:password]
12
+ user = user_scope.authenticate(email, password)
13
+
14
+ path = if user
15
+ session[:typus_user_id] = user.id
16
+ params[:return_to] || admin_dashboard_index_path
17
+ else
18
+ new_admin_session_path(return_to: params[:return_to])
19
+ end
20
+
21
+ redirect_to path
22
+ end
23
+
24
+ def destroy
25
+ deauthenticate
26
+ end
27
+
28
+ private
29
+
30
+ def create_an_account?
31
+ redirect_to new_admin_account_path if zero_users
32
+ end
33
+
34
+ def set_locale
35
+ I18n.locale = Typus.default_locale
36
+ end
37
+
38
+ def user_scope
39
+ klass = Typus.user_class
40
+ klass.respond_to?(:in_domain) ? klass.in_domain(request.host) : klass
41
+ end
42
+
43
+ end
@@ -0,0 +1,88 @@
1
+ require 'active_support/concern'
2
+
3
+ module Admin
4
+ module Actions
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ helper_method :resource_actions
10
+ helper_method :resources_actions
11
+ end
12
+
13
+ def resource_actions
14
+ @resource_actions ||= []
15
+ end
16
+
17
+ def resources_actions
18
+ @resources_actions ||= []
19
+ end
20
+
21
+ protected
22
+
23
+ ##
24
+ # @resource_actions is used to customize the actions which appear under
25
+ # each item on the tables. This is really a nice feature because allows
26
+ # us to enable actions for items without much effort. For example adding
27
+ # a "Recover from Trash" action:
28
+ #
29
+ # def index
30
+ # add_resource_action('typus.buttons.restore', {action: 'untrash'}, {data: {confirm: I18n.t("Recover %{resource}?"}, resource: @resource.model_name.human)})
31
+ # super
32
+ # end
33
+ #
34
+ # Additionally you can set a condition to each action passing a Proc as
35
+ # 4th parameter. If the proc return true the item will be showed and if
36
+ # return false will be hidden.
37
+ #
38
+ # def index
39
+ # add_resource_action('typus.buttons.restore', {action: 'untrash'}, {}, Proc.new { |item| item.is_trash? })
40
+ # super
41
+ # end
42
+ #
43
+
44
+ def add_resource_action(*args)
45
+ @resource_actions ||= []
46
+ @resource_actions << args unless args.empty?
47
+ end
48
+
49
+ def prepend_resource_action(*args)
50
+ @resource_actions ||= []
51
+ @resource_actions = @resource_actions.unshift(args) unless args.empty?
52
+ end
53
+
54
+ def append_resource_action(*args)
55
+ @resource_actions ||= []
56
+ @resource_actions = @resource_actions.concat([args]) unless args.empty?
57
+ end
58
+
59
+ ##
60
+ # @resources_actions is used to build a list of custom actions which will
61
+ # be appended beside "<h2></h2>" all the actions.
62
+ #
63
+ # Let's say for example that I want to be able to run the application
64
+ # without sidebars and headers (headless mode). In this case I need to
65
+ # somehow add custom actions to the page so I can navigate.
66
+ #
67
+ # Instead of having this code here, maybe it's better to duplicate the
68
+ # actions on the pages. So for example: Admin::PostsController#index will
69
+ # show a link to add new in the sidebar and beside the "<h2>" header.
70
+ #
71
+
72
+ def add_resources_action(*args)
73
+ @resources_actions ||= []
74
+ @resources_actions << args unless args.empty?
75
+ end
76
+
77
+ def prepend_resources_action(*args)
78
+ @resources_actions ||= []
79
+ @resources_actions = @resources_actions.unshift(args) unless args.empty?
80
+ end
81
+
82
+ def append_resources_action(*args)
83
+ @resources_actions ||= []
84
+ @resources_actions = @resources_actions.concat([args]) unless args.empty?
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,35 @@
1
+ # Module designed to work with `acts_as_list`.
2
+
3
+ require 'active_support/concern'
4
+
5
+ module Admin
6
+ module ActsAsList
7
+
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ # before_filter :set_predefined_filter_for_position, only: [:index]
12
+ end
13
+
14
+ def set_predefined_filter_for_position
15
+ if admin_user.can?('edit', @resource.model_name)
16
+ add_resource_action('typus.buttons.position', {action: 'position'}, {glyphicon: 'th-list'})
17
+ end
18
+ end
19
+ private :set_predefined_filter_for_position
20
+
21
+ def position
22
+ get_object
23
+ check_resource_ownership
24
+
25
+ if %w(move_to_top move_higher move_lower move_to_bottom).include?(params[:go])
26
+ @item.send(params[:go])
27
+ notice = I18n.t("typus.flash.update_success", model: @resource.model_name.human)
28
+ redirect_to :back, notice: notice
29
+ else
30
+ not_allowed
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ module Admin
2
+ module Ancestry
3
+
4
+ def index
5
+ @items = []
6
+
7
+ @resource.roots.each do |item|
8
+ @items << item
9
+ if item.has_children?
10
+ item.children.each do |child|
11
+ @items << child
12
+ if child.has_children?
13
+ child.children.each do |local_child|
14
+ @items << local_child
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ set_default_action
22
+ add_resource_action('typus.buttons.destroy', {action: 'destroy'}, {data: {confirm: "#{I18n.t('Trash')}?"}, method: 'delete'})
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module Admin
2
+ module Autocomplete
3
+
4
+ def autocomplete
5
+ get_objects
6
+ @items = @resource.limit(20)
7
+ render json: @items.map { |i| { id: i.id, name: i.to_label } }
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,76 @@
1
+ require 'active_support/concern'
2
+
3
+ module Admin
4
+ module Bulk
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ helper_method :bulk_actions
10
+ before_filter :set_bulk_action, only: [:index]
11
+ before_filter :set_bulk_action_for_trash, only: [:trash]
12
+ end
13
+
14
+ def set_bulk_action
15
+ add_bulk_action('typus.buttons.destroy', 'bulk_destroy')
16
+ end
17
+ private :set_bulk_action
18
+
19
+ # This only happens if we try to access the trash, which won't happen
20
+ # if trash module is not loaded.
21
+ def set_bulk_action_for_trash
22
+ add_bulk_action('Restore from Trash', 'bulk_restore')
23
+ end
24
+ private :set_bulk_action_for_trash
25
+
26
+ def bulk
27
+ if params[:selected_item_ids] && params[:batch_action].present?
28
+ send(params[:batch_action], params[:selected_item_ids])
29
+ else
30
+ notice = if params[:batch_action].empty?
31
+ I18n.t('typus.flash.bulk_no_action')
32
+ else
33
+ I18n.t('typus.flash.bulk_no_items')
34
+ end
35
+ redirect_to :back, notice: notice
36
+ end
37
+ end
38
+
39
+ def bulk_destroy(ids)
40
+ ids.each { |id| @resource.destroy(id) }
41
+ notice = I18n.t('typus.flash.bulk_delete_success', count: ids.count)
42
+ redirect_to :back, notice: notice
43
+ end
44
+ private :bulk_destroy
45
+
46
+ def bulk_restore(ids)
47
+ ids.each { |id| @resource.deleted.find(id).restore }
48
+ notice = I18n.t('Successfully restored %{count} entries.', count: ids.count)
49
+ redirect_to :back, notice: notice
50
+ end
51
+ private :bulk_restore
52
+
53
+ def add_bulk_action(*args)
54
+ bulk_actions
55
+ @bulk_actions << args unless args.empty?
56
+ end
57
+ protected :add_bulk_action
58
+
59
+ def prepend_bulk_action(*args)
60
+ bulk_actions
61
+ @bulk_actions = @bulk_actions.unshift(args) unless args.empty?
62
+ end
63
+ protected :prepend_bulk_action
64
+
65
+ def append_bulk_action(*args)
66
+ bulk_actions
67
+ @bulk_actions = @bulk_actions.concat([args]) unless args.empty?
68
+ end
69
+ protected :append_bulk_action
70
+
71
+ def bulk_actions
72
+ @bulk_actions ||= []
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,22 @@
1
+ module Admin
2
+ module FeaturedImage
3
+
4
+ def set_featured_image
5
+ attachment = Attachment.find(params[:id])
6
+
7
+ item = params[:resource].constantize.unscoped.find(params[:resource_id])
8
+ item.set_featured_image(attachment.id)
9
+
10
+ options = { controller: params[:resource].tableize, action: 'edit', id: item.id }
11
+ redirect_to options, notice: I18n.t('typus.flash.image_removed')
12
+ end
13
+
14
+ def remove_featured_image
15
+ item = @resource.unscoped.find(params[:id])
16
+ item.try(:remove_featured_image)
17
+ options = { action: 'edit', id: item.id }
18
+ redirect_to options, notice: I18n.t('typus.flash.image_removed')
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,57 @@
1
+ # How to setup a predefined filter?
2
+ # ---------------------------------
3
+ #
4
+ # On your controllers:
5
+ #
6
+ # def index
7
+ # # Added predefined filter takes any argument, but in the views we
8
+ # # expected the following:
9
+ # #
10
+ # # add_predefined_filter(filter_name, action, scope)
11
+ # #
12
+ # ...
13
+ # add_predefined_filter("typus.filters.trash", "trash", "deleted")
14
+ # ...
15
+ # end
16
+ #
17
+ # On your views:
18
+ #
19
+ # <% predefined_filters.each do |filter_name, action, scope| %>
20
+ # ...
21
+ # <% end %>
22
+ #
23
+
24
+ require 'active_support/concern'
25
+
26
+ module Admin
27
+ module Filters
28
+
29
+ extend ActiveSupport::Concern
30
+
31
+ included do
32
+ helper_method :predefined_filters
33
+ end
34
+
35
+ protected
36
+
37
+ def add_predefined_filter(*args)
38
+ predefined_filters
39
+ @predefined_filters << args unless args.empty?
40
+ end
41
+
42
+ def prepend_predefined_filter(*args)
43
+ predefined_filters
44
+ @predefined_filters = @predefined_filters.unshift(args) unless args.empty?
45
+ end
46
+
47
+ def append_predefined_filter(*args)
48
+ predefined_filters
49
+ @predefined_filters = @predefined_filters.concat([args]) unless args.empty?
50
+ end
51
+
52
+ def predefined_filters
53
+ @predefined_filters ||= []
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,49 @@
1
+ require 'csv'
2
+
3
+ module Admin
4
+ module Format
5
+
6
+ protected
7
+
8
+ def get_paginated_data
9
+ items_per_page = params[:per_page] || @resource.typus_options_for(:per_page)
10
+ offset = params[:offset] || 0
11
+ @items = @resource.limit(items_per_page).offset(offset)
12
+ end
13
+
14
+ def generate_csv
15
+ fields = @resource.typus_fields_for(:csv)
16
+ records = @resource.all
17
+
18
+ data = ::CSV.generate do |csv|
19
+ csv << fields.keys.map { |k| @resource.human_attribute_name(k) }
20
+ records.each do |record|
21
+ csv << fields.map do |key, value|
22
+ case value
23
+ when :transversal
24
+ a, b = key.split('.')
25
+ record.send(a).try(b)
26
+ when :belongs_to
27
+ record.send(key).try(:to_label)
28
+ else
29
+ record.send(key)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ send_data data, filename: "export-#{@resource.to_resource}-#{Time.zone.now.to_s(:number)}.csv"
36
+ end
37
+
38
+ def export(format)
39
+ fields = @resource.typus_fields_for(format).map(&:first)
40
+ methods = fields - @resource.column_names
41
+ except = @resource.column_names - fields
42
+
43
+ get_paginated_data
44
+
45
+ render format => @items.send("to_#{format}", methods: methods, except: except)
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,23 @@
1
+ require 'active_support/concern'
2
+
3
+ module Admin
4
+ module Headless
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ helper_method :headless_mode?
10
+ layout :headless_layout
11
+ end
12
+
13
+ def headless_layout
14
+ headless_mode? ? 'admin/headless' : 'admin/base'
15
+ end
16
+ private :headless_layout
17
+
18
+ def headless_mode?
19
+ params[:_popup]
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ module Admin
2
+ module Hooks
3
+ end
4
+ end