activeadmin 2.2.0 → 2.14.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activeadmin might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +469 -32
- data/CONTRIBUTING.md +46 -69
- data/README.md +13 -6
- data/app/assets/javascripts/active_admin/base.js +521 -0
- data/app/assets/stylesheets/active_admin/_base.scss +53 -37
- data/app/assets/stylesheets/active_admin/_forms.scss +1 -11
- data/app/assets/stylesheets/active_admin/_header.scss +40 -8
- data/app/assets/stylesheets/active_admin/_mixins.scss +1 -1
- data/{vendor → app}/assets/stylesheets/active_admin/_normalize.scss +25 -123
- data/app/assets/stylesheets/active_admin/{print.scss → _print.scss} +2 -2
- data/app/assets/stylesheets/active_admin/components/_comments.scss +2 -2
- data/app/assets/stylesheets/active_admin/components/_date_picker.scss +1 -2
- data/app/assets/stylesheets/active_admin/components/_dropdown_menu.scss +0 -1
- data/app/assets/stylesheets/active_admin/components/_tables.scss +1 -2
- data/app/assets/stylesheets/active_admin/mixins/_all.scss +8 -8
- data/app/assets/stylesheets/active_admin/mixins/_variables.scss +17 -0
- data/app/assets/stylesheets/active_admin/structure/_footer.scss +6 -1
- data/app/assets/stylesheets/active_admin/structure/_main_structure.scss +1 -1
- data/app/assets/stylesheets/active_admin/structure/_title_bar.scss +0 -1
- data/app/javascript/active_admin/base.js +28 -0
- data/app/{assets/javascripts/active_admin/lib/batch_actions.es6 → javascript/active_admin/initializers/batch-actions.js} +9 -3
- data/app/javascript/active_admin/initializers/checkbox-toggler.js +3 -0
- data/app/javascript/active_admin/initializers/dropdown-menu.js +9 -0
- data/app/javascript/active_admin/initializers/filters.js +10 -0
- data/app/{assets/javascripts/active_admin/lib/has_many.es6 → javascript/active_admin/initializers/has-many.js} +4 -1
- data/app/javascript/active_admin/initializers/per-page.js +13 -0
- data/app/javascript/active_admin/initializers/table-checkbox-toggler.js +3 -0
- data/app/{assets/javascripts/active_admin/lib/checkbox-toggler.es6 → javascript/active_admin/lib/checkbox-toggler.js} +5 -5
- data/app/{assets/javascripts/active_admin/lib/dropdown-menu.es6 → javascript/active_admin/lib/dropdown-menu.js} +3 -10
- data/app/javascript/active_admin/lib/filters.js +39 -0
- data/app/{assets/javascripts/active_admin/lib/modal_dialog.es6 → javascript/active_admin/lib/modal-dialog.js} +10 -8
- data/app/javascript/active_admin/lib/per-page.js +38 -0
- data/app/{assets/javascripts/active_admin/lib/table-checkbox-toggler.es6 → javascript/active_admin/lib/table-checkbox-toggler.js} +5 -3
- data/app/javascript/active_admin/lib/utils.js +40 -0
- data/app/views/active_admin/devise/mailer/reset_password_instructions.html.erb +1 -1
- data/app/views/active_admin/devise/mailer/unlock_instructions.html.erb +2 -2
- data/app/views/active_admin/devise/shared/_links.erb +1 -1
- data/app/views/active_admin/page/index.html.arb +1 -0
- data/app/views/active_admin/resource/edit.html.arb +1 -0
- data/app/views/active_admin/resource/index.html.arb +1 -0
- data/app/views/active_admin/resource/new.html.arb +1 -0
- data/app/views/active_admin/resource/show.html.arb +1 -0
- data/app/views/kaminari/active_admin_countless/_first_page.html.erb +11 -0
- data/app/views/kaminari/active_admin_countless/_gap.html.erb +8 -0
- data/app/views/kaminari/active_admin_countless/_next_page.html.erb +11 -0
- data/app/views/kaminari/active_admin_countless/_page.html.erb +12 -0
- data/app/views/kaminari/active_admin_countless/_paginator.html.erb +24 -0
- data/app/views/kaminari/active_admin_countless/_prev_page.html.erb +11 -0
- data/app/views/layouts/active_admin.html.arb +1 -0
- data/app/views/layouts/active_admin_logged_out.html.erb +18 -7
- data/config/locales/ar.yml +6 -6
- data/config/locales/az.yml +138 -0
- data/config/locales/ca.yml +0 -1
- data/config/locales/de.yml +18 -0
- data/config/locales/en-CA.yml +3 -3
- data/config/locales/en-GB.yml +3 -3
- data/config/locales/en.yml +3 -3
- data/config/locales/es-MX.yml +2 -1
- data/config/locales/es.yml +5 -5
- data/config/locales/fr.yml +7 -7
- data/config/locales/it.yml +18 -0
- data/config/locales/ja.yml +3 -3
- data/config/locales/ko.yml +1 -1
- data/config/locales/lv.yml +2 -2
- data/config/locales/nl.yml +1 -1
- data/config/locales/ro.yml +3 -2
- data/config/locales/sk.yml +59 -0
- data/config/locales/vi.yml +40 -12
- data/config/locales/zh-CN.yml +36 -17
- data/lib/active_admin/abstract_view_factory.rb +1 -0
- data/lib/active_admin/application.rb +20 -20
- data/lib/active_admin/application_settings.rb +4 -3
- data/lib/active_admin/asset_registration.rb +4 -3
- data/lib/active_admin/authorization_adapter.rb +6 -3
- data/lib/active_admin/base_controller/authorization.rb +15 -13
- data/lib/active_admin/base_controller/menu.rb +1 -0
- data/lib/active_admin/base_controller.rb +6 -5
- data/lib/active_admin/batch_actions/controller.rb +4 -3
- data/lib/active_admin/batch_actions/resource_extension.rb +10 -8
- data/lib/active_admin/batch_actions/views/batch_action_form.rb +4 -3
- data/lib/active_admin/batch_actions/views/batch_action_selector.rb +7 -6
- data/lib/active_admin/batch_actions/views/selection_cells.rb +4 -3
- data/lib/active_admin/batch_actions.rb +1 -0
- data/lib/active_admin/callbacks.rb +1 -0
- data/lib/active_admin/cancan_adapter.rb +2 -1
- data/lib/active_admin/collection_decorator.rb +32 -0
- data/lib/active_admin/component.rb +1 -0
- data/lib/active_admin/controller_action.rb +1 -0
- data/lib/active_admin/csv_builder.rb +13 -23
- data/lib/active_admin/dependency.rb +12 -15
- data/lib/active_admin/deprecation.rb +1 -0
- data/lib/active_admin/devise.rb +16 -5
- data/lib/active_admin/dsl.rb +2 -1
- data/lib/active_admin/dynamic_setting.rb +1 -0
- data/lib/active_admin/dynamic_settings_node.rb +3 -2
- data/lib/active_admin/engine.rb +13 -9
- data/lib/active_admin/error.rb +1 -2
- data/lib/active_admin/filters/active.rb +2 -1
- data/lib/active_admin/filters/active_filter.rb +7 -7
- data/lib/active_admin/filters/active_sidebar.rb +4 -30
- data/lib/active_admin/filters/dsl.rb +1 -0
- data/lib/active_admin/filters/forms.rb +7 -6
- data/lib/active_admin/filters/formtastic_addons.rb +2 -6
- data/lib/active_admin/filters/resource_extension.rb +30 -5
- data/lib/active_admin/filters.rb +8 -7
- data/lib/active_admin/form_builder.rb +25 -20
- data/lib/active_admin/generators/boilerplate.rb +13 -4
- data/lib/active_admin/helpers/collection.rb +2 -0
- data/lib/active_admin/helpers/i18n.rb +1 -0
- data/lib/active_admin/helpers/optional_display.rb +3 -2
- data/lib/active_admin/helpers/routes/url_helpers.rb +1 -0
- data/lib/active_admin/helpers/scope_chain.rb +1 -0
- data/lib/active_admin/inputs/datepicker_input.rb +2 -1
- data/lib/active_admin/inputs/filters/base/search_method_select.rb +5 -4
- data/lib/active_admin/inputs/filters/base.rb +2 -1
- data/lib/active_admin/inputs/filters/boolean_input.rb +2 -1
- data/lib/active_admin/inputs/filters/check_boxes_input.rb +2 -1
- data/lib/active_admin/inputs/filters/date_picker_input.rb +1 -0
- data/lib/active_admin/inputs/filters/date_range_input.rb +16 -12
- data/lib/active_admin/inputs/filters/numeric_input.rb +1 -0
- data/lib/active_admin/inputs/filters/select_input.rb +3 -2
- data/lib/active_admin/inputs/filters/string_input.rb +1 -0
- data/lib/active_admin/inputs/filters/text_input.rb +1 -0
- data/lib/active_admin/inputs.rb +1 -0
- data/lib/active_admin/localizers/resource_localizer.rb +4 -3
- data/lib/active_admin/localizers.rb +2 -1
- data/lib/active_admin/menu.rb +7 -3
- data/lib/active_admin/menu_collection.rb +1 -0
- data/lib/active_admin/menu_item.rb +8 -7
- data/lib/active_admin/namespace.rb +15 -14
- data/lib/active_admin/namespace_settings.rb +21 -4
- data/lib/active_admin/order_clause.rb +3 -2
- data/lib/active_admin/orm/active_record/comments/comment.rb +4 -3
- data/lib/active_admin/orm/active_record/comments/namespace_helper.rb +1 -0
- data/lib/active_admin/orm/active_record/comments/resource_helper.rb +1 -0
- data/lib/active_admin/orm/active_record/comments/show_page_helper.rb +1 -0
- data/lib/active_admin/orm/active_record/comments/views/active_admin_comments.rb +21 -20
- data/lib/active_admin/orm/active_record/comments/views.rb +3 -2
- data/lib/active_admin/orm/active_record/comments.rb +28 -27
- data/lib/active_admin/orm/active_record.rb +2 -1
- data/lib/active_admin/orm/mongoid.rb +1 -0
- data/lib/active_admin/page.rb +2 -1
- data/lib/active_admin/page_controller.rb +1 -0
- data/lib/active_admin/page_dsl.rb +1 -0
- data/lib/active_admin/page_presenter.rb +1 -0
- data/lib/active_admin/pundit_adapter.rb +57 -15
- data/lib/active_admin/resource/action_items.rb +6 -5
- data/lib/active_admin/resource/attributes.rb +2 -1
- data/lib/active_admin/resource/belongs_to.rb +6 -2
- data/lib/active_admin/resource/controllers.rb +2 -1
- data/lib/active_admin/resource/includes.rb +1 -0
- data/lib/active_admin/resource/menu.rb +5 -4
- data/lib/active_admin/resource/model.rb +16 -0
- data/lib/active_admin/resource/naming.rb +6 -5
- data/lib/active_admin/resource/ordering.rb +1 -0
- data/lib/active_admin/resource/page_presenters.rb +1 -0
- data/lib/active_admin/resource/pagination.rb +1 -0
- data/lib/active_admin/resource/routes.rb +17 -10
- data/lib/active_admin/resource/scope_to.rb +8 -7
- data/lib/active_admin/resource/scopes.rb +1 -0
- data/lib/active_admin/resource/sidebars.rb +2 -1
- data/lib/active_admin/resource.rb +33 -19
- data/lib/active_admin/resource_collection.rb +1 -0
- data/lib/active_admin/resource_controller/action_builder.rb +1 -0
- data/lib/active_admin/resource_controller/data_access.rb +31 -5
- data/lib/active_admin/resource_controller/decorators.rb +8 -29
- data/lib/active_admin/resource_controller/polymorphic_routes.rb +38 -0
- data/lib/active_admin/resource_controller/resource_class_methods.rb +1 -0
- data/lib/active_admin/resource_controller/scoping.rb +1 -0
- data/lib/active_admin/resource_controller/sidebars.rb +1 -0
- data/lib/active_admin/resource_controller/streaming.rb +9 -7
- data/lib/active_admin/resource_controller.rb +14 -10
- data/lib/active_admin/resource_dsl.rb +11 -25
- data/lib/active_admin/router.rb +1 -0
- data/lib/active_admin/scope.rb +7 -6
- data/lib/active_admin/settings_node.rb +1 -0
- data/lib/active_admin/sidebar_section.rb +1 -0
- data/lib/active_admin/version.rb +2 -1
- data/lib/active_admin/view_factory.rb +18 -17
- data/lib/active_admin/view_helpers/active_admin_application_helper.rb +1 -0
- data/lib/active_admin/view_helpers/auto_link_helper.rb +2 -1
- data/lib/active_admin/view_helpers/breadcrumb_helper.rb +4 -3
- data/lib/active_admin/view_helpers/display_helper.rb +15 -7
- data/lib/active_admin/view_helpers/download_format_links_helper.rb +2 -1
- data/lib/active_admin/view_helpers/fields_for.rb +3 -2
- data/lib/active_admin/view_helpers/flash_helper.rb +1 -0
- data/lib/active_admin/view_helpers/form_helper.rb +1 -0
- data/lib/active_admin/view_helpers/method_or_proc_helper.rb +1 -0
- data/lib/active_admin/view_helpers/scope_name_helper.rb +1 -0
- data/lib/active_admin/view_helpers/sidebar_helper.rb +1 -0
- data/lib/active_admin/view_helpers/title_helper.rb +1 -0
- data/lib/active_admin/view_helpers/view_factory_helper.rb +1 -0
- data/lib/active_admin/view_helpers.rb +2 -1
- data/lib/active_admin/views/action_items.rb +1 -0
- data/lib/active_admin/views/components/active_admin_form.rb +7 -6
- data/lib/active_admin/views/components/active_filters_sidebar_content.rb +59 -0
- data/lib/active_admin/views/components/attributes_table.rb +6 -5
- data/lib/active_admin/views/components/blank_slate.rb +2 -1
- data/lib/active_admin/views/components/columns.rb +1 -0
- data/lib/active_admin/views/components/dropdown_menu.rb +7 -9
- data/lib/active_admin/views/components/index_list.rb +4 -3
- data/lib/active_admin/views/components/menu.rb +2 -1
- data/lib/active_admin/views/components/menu_item.rb +5 -4
- data/lib/active_admin/views/components/paginated_collection.rb +21 -19
- data/lib/active_admin/views/components/panel.rb +2 -1
- data/lib/active_admin/views/components/scopes.rb +8 -5
- data/lib/active_admin/views/components/sidebar.rb +1 -0
- data/lib/active_admin/views/components/sidebar_section.rb +1 -0
- data/lib/active_admin/views/components/site_title.rb +2 -1
- data/lib/active_admin/views/components/status_tag.rb +12 -11
- data/lib/active_admin/views/components/table_for.rb +19 -17
- data/lib/active_admin/views/components/tabs.rb +4 -3
- data/lib/active_admin/views/components/unsupported_browser.rb +1 -0
- data/lib/active_admin/views/footer.rb +3 -1
- data/lib/active_admin/views/header.rb +3 -2
- data/lib/active_admin/views/index_as_block.rb +1 -0
- data/lib/active_admin/views/index_as_blog.rb +2 -1
- data/lib/active_admin/views/index_as_grid.rb +2 -1
- data/lib/active_admin/views/index_as_table.rb +24 -16
- data/lib/active_admin/views/pages/base.rb +22 -14
- data/lib/active_admin/views/pages/form.rb +1 -0
- data/lib/active_admin/views/pages/index.rb +16 -13
- data/lib/active_admin/views/pages/layout.rb +1 -0
- data/lib/active_admin/views/pages/page.rb +1 -0
- data/lib/active_admin/views/pages/show.rb +1 -0
- data/lib/active_admin/views/tabbed_navigation.rb +3 -2
- data/lib/active_admin/views/title_bar.rb +2 -1
- data/lib/active_admin/views.rb +2 -1
- data/lib/active_admin.rb +63 -64
- data/lib/activeadmin.rb +2 -1
- data/lib/generators/active_admin/assets/assets_generator.rb +3 -2
- data/lib/generators/active_admin/assets/templates/active_admin.scss +2 -2
- data/lib/generators/active_admin/devise/devise_generator.rb +6 -5
- data/lib/generators/active_admin/install/install_generator.rb +15 -8
- data/lib/generators/active_admin/install/templates/active_admin.rb.erb +38 -1
- data/lib/generators/active_admin/install/templates/dashboard.rb +1 -0
- data/lib/generators/active_admin/page/page_generator.rb +2 -1
- data/lib/generators/active_admin/page/templates/page.rb +1 -0
- data/lib/generators/active_admin/resource/resource_generator.rb +4 -3
- data/lib/generators/active_admin/resource/templates/admin.rb.erb +4 -2
- data/lib/generators/active_admin/webpacker/plugins/jquery.js +7 -0
- data/lib/generators/active_admin/webpacker/templates/active_admin.js +5 -0
- data/lib/generators/active_admin/webpacker/templates/active_admin.scss +17 -0
- data/lib/generators/active_admin/webpacker/templates/print.scss +2 -0
- data/lib/generators/active_admin/webpacker/webpacker_generator.rb +27 -0
- data/lib/ransack_ext.rb +9 -8
- metadata +64 -132
- data/app/assets/images/active_admin/nested_menu_arrow.gif +0 -0
- data/app/assets/images/active_admin/nested_menu_arrow_dark.gif +0 -0
- data/app/assets/images/active_admin/orderable.png +0 -0
- data/app/assets/javascripts/active_admin/base.es6 +0 -23
- data/app/assets/javascripts/active_admin/initializers/filters.es6 +0 -45
- data/app/assets/javascripts/active_admin/lib/active_admin.es6 +0 -41
- data/app/assets/javascripts/active_admin/lib/per_page.es6 +0 -47
- data/docs/.gitignore +0 -1
- data/docs/0-installation.md +0 -118
- data/docs/1-general-configuration.md +0 -204
- data/docs/10-custom-pages.md +0 -150
- data/docs/11-decorators.md +0 -59
- data/docs/12-arbre-components.md +0 -214
- data/docs/13-authorization-adapter.md +0 -285
- data/docs/14-gotchas.md +0 -138
- data/docs/2-resource-customization.md +0 -466
- data/docs/3-index-pages/custom-index.md +0 -35
- data/docs/3-index-pages/index-as-block.md +0 -19
- data/docs/3-index-pages/index-as-blog.md +0 -69
- data/docs/3-index-pages/index-as-grid.md +0 -27
- data/docs/3-index-pages/index-as-table.md +0 -227
- data/docs/3-index-pages.md +0 -328
- data/docs/4-csv-format.md +0 -74
- data/docs/5-forms.md +0 -232
- data/docs/6-show-pages.md +0 -81
- data/docs/7-sidebars.md +0 -75
- data/docs/8-custom-actions.md +0 -177
- data/docs/9-batch-actions.md +0 -237
- data/docs/CNAME +0 -1
- data/docs/Gemfile +0 -4
- data/docs/Gemfile.lock +0 -249
- data/docs/README.md +0 -24
- data/docs/_config.yml +0 -2
- data/docs/_includes/footer.html +0 -8
- data/docs/_includes/google-analytics.html +0 -16
- data/docs/_includes/head.html +0 -7
- data/docs/_includes/toc.html +0 -98
- data/docs/_includes/top-menu.html +0 -17
- data/docs/_layouts/default.html +0 -21
- data/docs/documentation.md +0 -60
- data/docs/images/activeadmin.png +0 -0
- data/docs/images/code-header.png +0 -0
- data/docs/images/divider.png +0 -0
- data/docs/images/features.png +0 -0
- data/docs/images/tidelift.svg +0 -14
- data/docs/index.html +0 -125
- data/docs/stylesheets/main.css +0 -1176
- /data/app/{assets/javascripts/active_admin/ext/jquery-ui.es6 → javascript/active_admin/ext/jquery-ui.js} +0 -0
- /data/app/{assets/javascripts/active_admin/ext/jquery.es6 → javascript/active_admin/ext/jquery.js} +0 -0
- /data/app/{assets/javascripts/active_admin/initializers/datepicker.es6 → javascript/active_admin/initializers/datepicker.js} +0 -0
- /data/app/{assets/javascripts/active_admin/initializers/tabs.es6 → javascript/active_admin/initializers/tabs.js} +0 -0
data/lib/active_admin/devise.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
ActiveAdmin::Dependency.devise! ActiveAdmin::Dependency::Requirements::DEVISE
|
2
3
|
|
3
|
-
require
|
4
|
+
require "devise"
|
4
5
|
|
5
6
|
module ActiveAdmin
|
6
7
|
module Devise
|
@@ -9,7 +10,7 @@ module ActiveAdmin
|
|
9
10
|
{
|
10
11
|
path: ActiveAdmin.application.default_namespace || "/",
|
11
12
|
controllers: ActiveAdmin::Devise.controllers,
|
12
|
-
path_names: { sign_in:
|
13
|
+
path_names: { sign_in: "login", sign_out: "logout" },
|
13
14
|
sign_out_via: [*::Devise.sign_out_via, ActiveAdmin.application.logout_link_method].uniq
|
14
15
|
}
|
15
16
|
end
|
@@ -27,14 +28,14 @@ module ActiveAdmin
|
|
27
28
|
module Controller
|
28
29
|
extend ::ActiveSupport::Concern
|
29
30
|
included do
|
30
|
-
layout
|
31
|
+
layout "active_admin_logged_out"
|
31
32
|
helper ::ActiveAdmin::ViewHelpers
|
32
33
|
end
|
33
34
|
|
34
35
|
# Redirect to the default namespace on logout
|
35
36
|
def root_path
|
36
37
|
namespace = ActiveAdmin.application.default_namespace.presence
|
37
|
-
root_path_method = [namespace, :root_path].compact.join(
|
38
|
+
root_path_method = [namespace, :root_path].compact.join("_")
|
38
39
|
|
39
40
|
path = if Helpers::Routes.respond_to? root_path_method
|
40
41
|
Helpers::Routes.send root_path_method
|
@@ -45,29 +46,39 @@ module ActiveAdmin
|
|
45
46
|
|
46
47
|
# NOTE: `relative_url_root` is deprecated by Rails.
|
47
48
|
# Remove prefix here if it is removed completely.
|
48
|
-
prefix = Rails.configuration.action_controller[:relative_url_root] ||
|
49
|
+
prefix = Rails.configuration.action_controller[:relative_url_root] || ""
|
49
50
|
prefix + path
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
54
|
class SessionsController < ::Devise::SessionsController
|
54
55
|
include ::ActiveAdmin::Devise::Controller
|
56
|
+
|
57
|
+
ActiveSupport.run_load_hooks(:active_admin_controller, self)
|
55
58
|
end
|
56
59
|
|
57
60
|
class PasswordsController < ::Devise::PasswordsController
|
58
61
|
include ::ActiveAdmin::Devise::Controller
|
62
|
+
|
63
|
+
ActiveSupport.run_load_hooks(:active_admin_controller, self)
|
59
64
|
end
|
60
65
|
|
61
66
|
class UnlocksController < ::Devise::UnlocksController
|
62
67
|
include ::ActiveAdmin::Devise::Controller
|
68
|
+
|
69
|
+
ActiveSupport.run_load_hooks(:active_admin_controller, self)
|
63
70
|
end
|
64
71
|
|
65
72
|
class RegistrationsController < ::Devise::RegistrationsController
|
66
73
|
include ::ActiveAdmin::Devise::Controller
|
74
|
+
|
75
|
+
ActiveSupport.run_load_hooks(:active_admin_controller, self)
|
67
76
|
end
|
68
77
|
|
69
78
|
class ConfirmationsController < ::Devise::ConfirmationsController
|
70
79
|
include ::ActiveAdmin::Devise::Controller
|
80
|
+
|
81
|
+
ActiveSupport.run_load_hooks(:active_admin_controller, self)
|
71
82
|
end
|
72
83
|
|
73
84
|
def self.controllers_for_filters
|
data/lib/active_admin/dsl.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
|
3
4
|
# The Active Admin DSL. This class is where all the registration blocks
|
@@ -101,7 +102,7 @@ module ActiveAdmin
|
|
101
102
|
def batch_action(title, options = {}, &block)
|
102
103
|
# Create symbol & title information
|
103
104
|
if title.is_a? String
|
104
|
-
sym = title.titleize.tr(
|
105
|
+
sym = title.titleize.tr(" ", "").underscore.to_sym
|
105
106
|
else
|
106
107
|
sym = title
|
107
108
|
title = sym.to_s.titleize
|
data/lib/active_admin/engine.rb
CHANGED
@@ -1,21 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
class Engine < ::Rails::Engine
|
3
|
-
|
4
|
+
# Set default values for app_path and load_paths before running initializers
|
5
|
+
initializer "active_admin.load_app_path", before: :load_config_initializers do |app|
|
4
6
|
ActiveAdmin::Application.setting :app_path, app.root
|
5
|
-
ActiveAdmin::Application.setting :load_paths, [File.expand_path(
|
7
|
+
ActiveAdmin::Application.setting :load_paths, [File.expand_path("app/admin", app.root)]
|
6
8
|
end
|
7
9
|
|
8
10
|
initializer "active_admin.precompile", group: :all do |app|
|
9
|
-
ActiveAdmin.application.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
unless ActiveAdmin.application.use_webpacker
|
12
|
+
ActiveAdmin.application.stylesheets.each do |path, _|
|
13
|
+
app.config.assets.precompile << path
|
14
|
+
end
|
15
|
+
ActiveAdmin.application.javascripts.each do |path, _|
|
16
|
+
app.config.assets.precompile << path
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
17
|
-
initializer
|
18
|
-
require
|
21
|
+
initializer "active_admin.routes" do
|
22
|
+
require "active_admin/helpers/routes/url_helpers"
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
data/lib/active_admin/error.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
# Exception class to raise when there is an authorized access
|
3
4
|
# exception thrown. The exception has a few goodies that may
|
@@ -45,8 +46,6 @@ module ActiveAdmin
|
|
45
46
|
raise new exception
|
46
47
|
end
|
47
48
|
|
48
|
-
private
|
49
|
-
|
50
49
|
def self.database_error_classes
|
51
50
|
@classes ||= []
|
52
51
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
module Filters
|
3
4
|
|
@@ -39,8 +40,9 @@ module ActiveAdmin
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def predicate_name
|
42
|
-
I18n.t(
|
43
|
-
|
43
|
+
I18n.t(
|
44
|
+
"active_admin.filters.predicates.#{condition.predicate.name}",
|
45
|
+
default: ransack_predicate_name)
|
44
46
|
end
|
45
47
|
|
46
48
|
def html_options
|
@@ -66,7 +68,7 @@ module ActiveAdmin
|
|
66
68
|
def filter_label
|
67
69
|
return unless filter
|
68
70
|
|
69
|
-
filter[:label] || I18n.t(name, scope: [
|
71
|
+
filter[:label] || I18n.t(name, scope: ["formtastic", "labels"], default: nil)
|
70
72
|
end
|
71
73
|
|
72
74
|
#@return Ransack::Nodes::Attribute
|
@@ -83,7 +85,7 @@ module ActiveAdmin
|
|
83
85
|
end
|
84
86
|
|
85
87
|
def find_class?
|
86
|
-
[
|
88
|
+
["eq", "in"].include? condition.predicate.arel_predicate
|
87
89
|
end
|
88
90
|
|
89
91
|
# detect related class for Ransack::Nodes::Attribute
|
@@ -96,7 +98,7 @@ module ActiveAdmin
|
|
96
98
|
end
|
97
99
|
|
98
100
|
def filter
|
99
|
-
resource.filters[name.to_sym]
|
101
|
+
resource.filters[name.to_sym] || resource.filters[condition.key.to_sym]
|
100
102
|
end
|
101
103
|
|
102
104
|
def related_primary_key
|
@@ -112,8 +114,6 @@ module ActiveAdmin
|
|
112
114
|
@predicate_association
|
113
115
|
end
|
114
116
|
|
115
|
-
private
|
116
|
-
|
117
117
|
def find_predicate_association
|
118
118
|
condition_attribute.klass.reflect_on_all_associations.
|
119
119
|
reject { |r| r.options[:polymorphic] }. #skip polymorphic
|
@@ -1,42 +1,16 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "active_admin/filters/active"
|
2
3
|
|
3
4
|
module ActiveAdmin
|
4
5
|
module Filters
|
5
6
|
class ActiveSidebar < ActiveAdmin::SidebarSection
|
6
7
|
|
7
8
|
def initialize
|
8
|
-
super
|
9
|
+
super "search_status", sidebar_options
|
9
10
|
end
|
10
11
|
|
11
12
|
def block
|
12
|
-
->
|
13
|
-
active_filters = ActiveAdmin::Filters::Active.new(active_admin_config, assigns[:search])
|
14
|
-
span do
|
15
|
-
if current_scope
|
16
|
-
h4 I18n.t("active_admin.search_status.current_scope"), style: 'display: inline'
|
17
|
-
b scope_name(current_scope), class: 'current_scope_name', style: "display: inline"
|
18
|
-
end
|
19
|
-
div style: "margin-top: 10px" do
|
20
|
-
h4 I18n.t("active_admin.search_status.current_filters"), style: 'margin-bottom: 10px'
|
21
|
-
ul do
|
22
|
-
if active_filters.filters.blank?
|
23
|
-
li I18n.t("active_admin.search_status.no_current_filters")
|
24
|
-
else
|
25
|
-
active_filters.filters.each do |filter|
|
26
|
-
li filter.html_options do
|
27
|
-
span do
|
28
|
-
text_node filter.label
|
29
|
-
end
|
30
|
-
b do
|
31
|
-
text_node to_sentence(filter.values.map { |v| pretty_format(v) })
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
13
|
+
-> { active_filters_sidebar_content }
|
40
14
|
end
|
41
15
|
|
42
16
|
def title
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
module Filters
|
3
4
|
# This form builder defines methods to build filter forms such
|
@@ -48,15 +49,15 @@ module ActiveAdmin
|
|
48
49
|
def active_admin_filters_form_for(search, filters, options = {})
|
49
50
|
defaults = { builder: ActiveAdmin::Filters::FormBuilder,
|
50
51
|
url: collection_path,
|
51
|
-
html: { class:
|
52
|
+
html: { class: "filter_form" } }
|
52
53
|
required = { html: { method: :get },
|
53
54
|
as: :q }
|
54
|
-
options
|
55
|
+
options = defaults.deep_merge(options).deep_merge(required)
|
55
56
|
|
56
57
|
form_for search, options do |f|
|
57
58
|
filters.each do |attribute, opts|
|
58
|
-
next if opts.key?(:if)
|
59
|
-
next if opts.key?(:unless) &&
|
59
|
+
next if opts.key?(:if) && !call_method_or_proc_on(self, opts[:if])
|
60
|
+
next if opts.key?(:unless) && call_method_or_proc_on(self, opts[:unless])
|
60
61
|
|
61
62
|
filter_opts = opts.except(:if, :unless)
|
62
63
|
filter_opts[:input_html] = instance_exec(&filter_opts[:input_html]) if filter_opts[:input_html].is_a?(Proc)
|
@@ -65,8 +66,8 @@ module ActiveAdmin
|
|
65
66
|
end
|
66
67
|
|
67
68
|
buttons = content_tag :div, class: "buttons" do
|
68
|
-
f.submit(I18n.t(
|
69
|
-
link_to(I18n.t(
|
69
|
+
f.submit(I18n.t("active_admin.filters.buttons.filter")) +
|
70
|
+
link_to(I18n.t("active_admin.filters.buttons.clear"), "#", class: "clear_filters_btn") +
|
70
71
|
hidden_field_tags_for(params, except: except_hidden_fields)
|
71
72
|
end
|
72
73
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
module Filters
|
3
4
|
module FormtasticAddons
|
@@ -54,7 +55,7 @@ module ActiveAdmin
|
|
54
55
|
end
|
55
56
|
|
56
57
|
def seems_searchable?
|
57
|
-
has_predicate? || scope?
|
58
|
+
column_for(method).nil? && (has_predicate? || scope?)
|
58
59
|
end
|
59
60
|
|
60
61
|
# If the given method has a predicate (like _eq or _lteq), it's pretty
|
@@ -63,11 +64,6 @@ module ActiveAdmin
|
|
63
64
|
!!Ransack::Predicate.detect_from_string(method.to_s)
|
64
65
|
end
|
65
66
|
|
66
|
-
# Ransack lets you define custom search methods, called ransackers.
|
67
|
-
def ransacker?
|
68
|
-
klass._ransackers.key? method.to_s
|
69
|
-
end
|
70
|
-
|
71
67
|
# Ransack supports exposing selected scopes on your model for advanced searches.
|
72
68
|
def scope?
|
73
69
|
context = Ransack::Context.for klass
|
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
module Filters
|
3
4
|
|
4
5
|
class Disabled < RuntimeError
|
5
|
-
def initialize
|
6
|
-
super "
|
6
|
+
def initialize(action)
|
7
|
+
super "Cannot #{action} a filter when filters are disabled. Enable filters with 'config.filters = true'"
|
7
8
|
end
|
8
9
|
end
|
9
10
|
|
@@ -60,7 +61,7 @@ module ActiveAdmin
|
|
60
61
|
#
|
61
62
|
# @param [Symbol] attributes The attributes to not filter on
|
62
63
|
def remove_filter(*attributes)
|
63
|
-
raise Disabled unless filters_enabled?
|
64
|
+
raise Disabled, "remove" unless filters_enabled?
|
64
65
|
|
65
66
|
attributes.each { |attribute| (@filters_to_remove ||= []) << attribute.to_sym }
|
66
67
|
end
|
@@ -72,7 +73,7 @@ module ActiveAdmin
|
|
72
73
|
# @param [Hash] options The set of options that are passed through to
|
73
74
|
# ransack for the field definition.
|
74
75
|
def add_filter(attribute, options = {})
|
75
|
-
raise Disabled unless filters_enabled?
|
76
|
+
raise Disabled, "add" unless filters_enabled?
|
76
77
|
|
77
78
|
(@filters ||= {})[attribute.to_sym] = options
|
78
79
|
end
|
@@ -129,19 +130,43 @@ module ActiveAdmin
|
|
129
130
|
not_poly.reject! { |r| r.chain.length > 2 }
|
130
131
|
|
131
132
|
filters = poly.map(&:foreign_type) + not_poly.map(&:name)
|
133
|
+
|
134
|
+
# Check high-arity associations for filterable columns
|
135
|
+
max = namespace.maximum_association_filter_arity
|
136
|
+
if max != :unlimited
|
137
|
+
high_arity, low_arity = not_poly.partition do |r|
|
138
|
+
r.klass.reorder(nil).limit(max + 1).count > max
|
139
|
+
end
|
140
|
+
|
141
|
+
# Remove high-arity associations with no searchable column
|
142
|
+
high_arity = high_arity.select(&method(:searchable_column_for))
|
143
|
+
|
144
|
+
high_arity = high_arity.map { |r| r.name.to_s + "_" + searchable_column_for(r) + namespace.filter_method_for_large_association }
|
145
|
+
|
146
|
+
filters = poly.map(&:foreign_type) + low_arity.map(&:name) + high_arity
|
147
|
+
end
|
148
|
+
|
132
149
|
filters.map &:to_sym
|
133
150
|
else
|
134
151
|
[]
|
135
152
|
end
|
136
153
|
end
|
137
154
|
|
155
|
+
def search_columns
|
156
|
+
@search_columns ||= namespace.filter_columns_for_large_association.map(&:to_s)
|
157
|
+
end
|
158
|
+
|
159
|
+
def searchable_column_for(relation)
|
160
|
+
relation.klass.column_names.find { |name| search_columns.include?(name) }
|
161
|
+
end
|
162
|
+
|
138
163
|
def add_filters_sidebar_section
|
139
164
|
self.sidebar_sections << filters_sidebar_section
|
140
165
|
end
|
141
166
|
|
142
167
|
def filters_sidebar_section
|
143
168
|
ActiveAdmin::SidebarSection.new :filters, only: :index, if: -> { active_admin_config.filters.any? } do
|
144
|
-
active_admin_filters_form_for assigns[:search], active_admin_config.filters
|
169
|
+
active_admin_filters_form_for assigns[:search], **active_admin_config.filters
|
145
170
|
end
|
146
171
|
end
|
147
172
|
|
data/lib/active_admin/filters.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "active_admin/filters/dsl"
|
3
|
+
require "active_admin/filters/resource_extension"
|
4
|
+
require "active_admin/filters/formtastic_addons"
|
5
|
+
require "active_admin/filters/forms"
|
6
|
+
require "active_admin/helpers/optional_display"
|
7
|
+
require "active_admin/filters/active_sidebar"
|
7
8
|
|
8
9
|
# Add our Extensions
|
9
10
|
ActiveAdmin::ResourceDSL.send :include, ActiveAdmin::Filters::DSL
|
10
|
-
ActiveAdmin::Resource.send
|
11
|
+
ActiveAdmin::Resource.send :include, ActiveAdmin::Filters::ResourceExtension
|
11
12
|
ActiveAdmin::ViewHelpers.send :include, ActiveAdmin::Filters::ViewHelper
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Provides an intuitive way to build has_many associated records in the same form.
|
2
3
|
module Formtastic
|
3
4
|
module Inputs
|
@@ -22,7 +23,7 @@ module ActiveAdmin
|
|
22
23
|
|
23
24
|
def cancel_link(url = { action: "index" }, html_options = {}, li_attrs = {})
|
24
25
|
li_attrs[:class] ||= "cancel"
|
25
|
-
li_content = template.link_to I18n.t(
|
26
|
+
li_content = template.link_to I18n.t("active_admin.cancel"), url, html_options
|
26
27
|
template.content_tag(:li, li_content, li_attrs)
|
27
28
|
end
|
28
29
|
|
@@ -40,14 +41,14 @@ module ActiveAdmin
|
|
40
41
|
attr_reader :assoc
|
41
42
|
attr_reader :options
|
42
43
|
attr_reader :heading, :sortable_column, :sortable_start
|
43
|
-
attr_reader :new_record, :destroy_option
|
44
|
+
attr_reader :new_record, :destroy_option, :remove_record
|
44
45
|
|
45
46
|
def initialize(has_many_form, assoc, options)
|
46
47
|
super has_many_form
|
47
48
|
@assoc = assoc
|
48
49
|
@options = extract_custom_settings!(options.dup)
|
49
50
|
@options.reverse_merge!(for: assoc)
|
50
|
-
@options[:class] = [options[:class], "inputs has_many_fields"].compact.join(
|
51
|
+
@options[:class] = [options[:class], "inputs has_many_fields"].compact.join(" ")
|
51
52
|
|
52
53
|
if sortable_column
|
53
54
|
@options[:for] = [assoc, sorted_children(sortable_column)]
|
@@ -69,9 +70,10 @@ module ActiveAdmin
|
|
69
70
|
def extract_custom_settings!(options)
|
70
71
|
@heading = options.key?(:heading) ? options.delete(:heading) : default_heading
|
71
72
|
@sortable_column = options.delete(:sortable)
|
72
|
-
@sortable_start
|
73
|
+
@sortable_start = options.delete(:sortable_start) || 0
|
73
74
|
@new_record = options.key?(:new_record) ? options.delete(:new_record) : true
|
74
75
|
@destroy_option = options.delete(:allow_destroy)
|
76
|
+
@remove_record = options.delete(:remove_record)
|
75
77
|
options
|
76
78
|
end
|
77
79
|
|
@@ -93,7 +95,7 @@ module ActiveAdmin
|
|
93
95
|
contents = without_wrapper { inputs(options, &form_block) }
|
94
96
|
contents ||= "".html_safe
|
95
97
|
|
96
|
-
js = new_record ? js_for_has_many(options[:class], &form_block) :
|
98
|
+
js = new_record ? js_for_has_many(options[:class], &form_block) : ""
|
97
99
|
contents << js
|
98
100
|
end
|
99
101
|
|
@@ -107,19 +109,21 @@ module ActiveAdmin
|
|
107
109
|
def has_many_actions(form_builder, contents)
|
108
110
|
if form_builder.object.new_record?
|
109
111
|
contents << template.content_tag(:li) do
|
110
|
-
|
112
|
+
remove_text = remove_record.is_a?(String) ? remove_record : I18n.t("active_admin.has_many_remove")
|
113
|
+
template.link_to remove_text, "#", class: "button has_many_remove"
|
111
114
|
end
|
112
115
|
elsif allow_destroy?(form_builder.object)
|
113
|
-
form_builder.input(
|
114
|
-
|
115
|
-
|
116
|
+
form_builder.input(
|
117
|
+
:_destroy, as: :boolean,
|
118
|
+
wrapper_html: { class: "has_many_delete" },
|
119
|
+
label: I18n.t("active_admin.has_many_delete"))
|
116
120
|
end
|
117
121
|
|
118
122
|
if sortable_column
|
119
123
|
form_builder.input sortable_column, as: :hidden
|
120
124
|
|
121
|
-
contents << template.content_tag(:li, class:
|
122
|
-
I18n.t(
|
125
|
+
contents << template.content_tag(:li, class: "handle") do
|
126
|
+
I18n.t("active_admin.move")
|
123
127
|
end
|
124
128
|
end
|
125
129
|
|
@@ -156,27 +160,28 @@ module ActiveAdmin
|
|
156
160
|
|
157
161
|
# Capture the ADD JS
|
158
162
|
def js_for_has_many(class_string, &form_block)
|
159
|
-
assoc_name
|
160
|
-
placeholder
|
163
|
+
assoc_name = assoc_klass.model_name
|
164
|
+
placeholder = "NEW_#{assoc_name.to_s.underscore.upcase.gsub(/\//, '_')}_RECORD"
|
161
165
|
opts = {
|
162
166
|
for: [assoc, assoc_klass.new],
|
163
167
|
class: class_string,
|
164
168
|
for_options: { child_index: placeholder }
|
165
169
|
}
|
166
170
|
html = template.capture { __getobj__.send(:inputs_for_nested_attributes, opts, &form_block) }
|
167
|
-
text = new_record.is_a?(String) ? new_record : I18n.t(
|
171
|
+
text = new_record.is_a?(String) ? new_record : I18n.t("active_admin.has_many_new", model: assoc_name.human)
|
168
172
|
|
169
|
-
template.link_to text,
|
173
|
+
template.link_to text, "#", class: "button has_many_add", data: {
|
170
174
|
html: CGI.escapeHTML(html).html_safe, placeholder: placeholder
|
171
175
|
}
|
172
176
|
end
|
173
177
|
|
174
178
|
def wrap_div_or_li(html)
|
175
|
-
template.content_tag(
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
179
|
+
template.content_tag(
|
180
|
+
already_in_an_inputs_block ? :li : :div,
|
181
|
+
html,
|
182
|
+
class: "has_many_container #{assoc}",
|
183
|
+
"data-sortable" => sortable_column,
|
184
|
+
"data-sortable-start" => sortable_start)
|
180
185
|
end
|
181
186
|
end
|
182
187
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
module Generators
|
3
4
|
class Boilerplate
|
@@ -9,8 +10,16 @@ module ActiveAdmin
|
|
9
10
|
@class_name.constantize.new.attributes.keys
|
10
11
|
end
|
11
12
|
|
13
|
+
def assignable_attributes
|
14
|
+
attributes - %w(id created_at updated_at)
|
15
|
+
end
|
16
|
+
|
17
|
+
def permit_params
|
18
|
+
assignable_attributes.map { |a| a.to_sym.inspect }.join(", ")
|
19
|
+
end
|
20
|
+
|
12
21
|
def rows
|
13
|
-
attributes.map { |a| row(a) }.join("\n")
|
22
|
+
attributes.map { |a| row(a) }.join("\n ")
|
14
23
|
end
|
15
24
|
|
16
25
|
def row(name)
|
@@ -18,7 +27,7 @@ module ActiveAdmin
|
|
18
27
|
end
|
19
28
|
|
20
29
|
def columns
|
21
|
-
attributes.map { |a| column(a) }.join("\n")
|
30
|
+
attributes.map { |a| column(a) }.join("\n ")
|
22
31
|
end
|
23
32
|
|
24
33
|
def column(name)
|
@@ -26,7 +35,7 @@ module ActiveAdmin
|
|
26
35
|
end
|
27
36
|
|
28
37
|
def filters
|
29
|
-
attributes.map { |a| filter(a) }.join("\n")
|
38
|
+
attributes.map { |a| filter(a) }.join("\n ")
|
30
39
|
end
|
31
40
|
|
32
41
|
def filter(name)
|
@@ -34,7 +43,7 @@ module ActiveAdmin
|
|
34
43
|
end
|
35
44
|
|
36
45
|
def form_inputs
|
37
|
-
|
46
|
+
assignable_attributes.map { |a| form_input(a) }.join("\n ")
|
38
47
|
end
|
39
48
|
|
40
49
|
def form_input(name)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
module Helpers
|
3
4
|
module Collection
|
@@ -5,6 +6,7 @@ module ActiveAdmin
|
|
5
6
|
# 2. correctly handles the Hash returned when `group by` is used
|
6
7
|
def collection_size(c = collection)
|
7
8
|
return c.count if c.is_a?(Array)
|
9
|
+
return c.length if c.limit_value
|
8
10
|
|
9
11
|
c = c.except :select, :order
|
10
12
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
|
3
4
|
# Shareable module to give a #display_on?(action) method
|
@@ -15,7 +16,7 @@ module ActiveAdmin
|
|
15
16
|
|
16
17
|
module OptionalDisplay
|
17
18
|
def display_on?(action, render_context = self)
|
18
|
-
return false if @options[:only]
|
19
|
+
return false if @options[:only] && !@options[:only].include?(action.to_sym)
|
19
20
|
return false if @options[:except] && @options[:except].include?(action.to_sym)
|
20
21
|
|
21
22
|
case condition = @options[:if]
|
@@ -31,7 +32,7 @@ module ActiveAdmin
|
|
31
32
|
private
|
32
33
|
|
33
34
|
def normalize_display_options!
|
34
|
-
@options[:only]
|
35
|
+
@options[:only] = Array(@options[:only]) if @options[:only]
|
35
36
|
@options[:except] = Array(@options[:except]) if @options[:except]
|
36
37
|
end
|
37
38
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveAdmin
|
2
3
|
module Inputs
|
3
4
|
class DatepickerInput < ::Formtastic::Inputs::StringInput
|
4
5
|
def input_html_options
|
5
6
|
super.tap do |options|
|
6
|
-
options[:class] = [options[:class], "datepicker"].compact.join(
|
7
|
+
options[:class] = [options[:class], "datepicker"].compact.join(" ")
|
7
8
|
options[:data] ||= {}
|
8
9
|
options[:data].merge! datepicker_options
|
9
10
|
end
|