activeadmin 0.5.1 → 0.6.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.
- data/.travis.yml +8 -5
- data/CHANGELOG.md +151 -0
- data/Gemfile +16 -16
- data/LICENSE +1 -1
- data/activeadmin.gemspec +1 -0
- data/app/assets/images/active_admin/index_list_icons/block_icon.svg +10 -0
- data/app/assets/images/active_admin/index_list_icons/blog_icon.svg +4 -0
- data/app/assets/images/active_admin/index_list_icons/grid_icon.svg +13 -0
- data/app/assets/images/active_admin/index_list_icons/table_icon.svg +3 -0
- data/app/assets/javascripts/active_admin/components/jquery.aa.checkbox-toggler.js.coffee +17 -44
- data/app/assets/javascripts/active_admin/components/jquery.aa.dropdown-menu.js.coffee +2 -4
- data/app/assets/javascripts/active_admin/components/jquery.aa.popover.js.coffee +0 -3
- data/app/assets/javascripts/active_admin/components/jquery.aa.table-checkbox-toggler.js.coffee +10 -12
- data/app/assets/javascripts/active_admin/pages/application.js.coffee +13 -10
- data/app/assets/javascripts/active_admin/pages/batch_actions.js.coffee +3 -3
- data/app/assets/stylesheets/active_admin/_base.css.scss +1 -0
- data/app/assets/stylesheets/active_admin/_header.css.scss +5 -2
- data/app/assets/stylesheets/active_admin/components/_dropdown_menu.scss +2 -2
- data/app/assets/stylesheets/active_admin/components/_index_list.scss +12 -0
- data/app/assets/stylesheets/active_admin/components/_popovers.css.scss +2 -2
- data/app/assets/stylesheets/active_admin/components/_table_tools.css.scss +2 -2
- data/app/assets/stylesheets/active_admin/mixins/_buttons.css.scss +4 -4
- data/app/assets/stylesheets/active_admin/mixins/_gradients.css.scss +5 -4
- data/app/assets/stylesheets/active_admin/mixins/_sections.css.scss +1 -1
- data/app/assets/stylesheets/active_admin/pages/_logged_out.scss +1 -1
- data/app/assets/stylesheets/active_admin/print.css.scss +2 -2
- data/app/assets/stylesheets/active_admin/structure/_title_bar.scss +1 -1
- data/app/views/active_admin/devise/unlocks/new.html.erb +14 -12
- data/docs/1-general-configuration.md +13 -0
- data/docs/10-custom-pages.md +40 -28
- data/docs/11-decorators.md +6 -4
- data/docs/12-arbre-components.md +1 -1
- data/docs/13-authorization-adapter.md +206 -0
- data/docs/2-resource-customization.md +129 -14
- data/docs/3-index-pages.md +65 -0
- data/docs/3-index-pages/create-an-index.md +29 -0
- data/docs/3-index-pages/index-as-table.md +35 -11
- data/docs/5-forms.md +2 -2
- data/features/authorization.feature +64 -0
- data/features/authorization_cancan.feature +52 -0
- data/features/belongs_to.feature +41 -5
- data/features/index/batch_actions.feature +27 -3
- data/features/index/formats.feature +27 -0
- data/features/index/index_as_table.feature +74 -2
- data/features/index/index_parameters.feature +69 -0
- data/features/index/index_scopes.feature +7 -11
- data/features/index/page_title.feature +18 -0
- data/features/index/switch_index_view.feature +73 -0
- data/features/menu.feature +27 -0
- data/features/registering_pages.feature +21 -0
- data/features/step_definitions/additional_web_steps.rb +4 -0
- data/features/step_definitions/batch_action_steps.rb +16 -6
- data/features/step_definitions/index_scope_steps.rb +3 -3
- data/features/step_definitions/index_views_steps.rb +3 -0
- data/features/step_definitions/menu_steps.rb +4 -0
- data/features/support/env.rb +4 -0
- data/features/support/paths.rb +3 -0
- data/lib/active_admin.rb +4 -0
- data/lib/active_admin/application.rb +43 -76
- data/lib/active_admin/authorization_adapter.rb +128 -0
- data/lib/active_admin/base_controller.rb +18 -1
- data/lib/active_admin/base_controller/authorization.rb +153 -0
- data/lib/active_admin/base_controller/menu.rb +8 -3
- data/lib/active_admin/batch_actions/resource_extension.rb +8 -7
- data/lib/active_admin/batch_actions/views/batch_action_form.rb +1 -1
- data/lib/active_admin/cancan_adapter.rb +40 -0
- data/lib/active_admin/dashboards.rb +4 -5
- data/lib/active_admin/dashboards/dashboard_controller.rb +1 -1
- data/lib/active_admin/devise.rb +22 -7
- data/lib/active_admin/dsl.rb +18 -5
- data/lib/active_admin/engine.rb +1 -1
- data/lib/active_admin/filters/dsl.rb +1 -1
- data/lib/active_admin/filters/forms.rb +9 -7
- data/lib/active_admin/filters/resource_extension.rb +20 -15
- data/lib/active_admin/form_builder.rb +44 -49
- data/lib/active_admin/helpers/optional_display.rb +4 -8
- data/lib/active_admin/inputs/filter_boolean_input.rb +1 -1
- data/lib/active_admin/inputs/filter_string_input.rb +5 -1
- data/lib/active_admin/locales/bg.yml +1 -1
- data/lib/active_admin/locales/ca.yml +1 -1
- data/lib/active_admin/locales/cs.yml +26 -25
- data/lib/active_admin/locales/da.yml +1 -1
- data/lib/active_admin/locales/de.yml +1 -1
- data/lib/active_admin/locales/en.yml +11 -1
- data/lib/active_admin/locales/es.yml +16 -16
- data/lib/active_admin/locales/fr.yml +1 -1
- data/lib/active_admin/locales/he.yml +1 -1
- data/lib/active_admin/locales/hr.yml +1 -1
- data/lib/active_admin/locales/hu.yml +1 -1
- data/lib/active_admin/locales/it.yml +1 -1
- data/lib/active_admin/locales/ja.yml +4 -1
- data/lib/active_admin/locales/ko.yml +1 -1
- data/lib/active_admin/locales/lt.yml +1 -1
- data/lib/active_admin/locales/lv.yml +12 -1
- data/lib/active_admin/locales/nl.yml +2 -2
- data/lib/active_admin/locales/no-NB.yml +22 -1
- data/lib/active_admin/locales/pl.yml +1 -1
- data/lib/active_admin/locales/pt-BR.yml +1 -1
- data/lib/active_admin/locales/pt-PT.yml +81 -0
- data/lib/active_admin/locales/ro.yml +1 -1
- data/lib/active_admin/locales/ru.yml +1 -1
- data/lib/active_admin/locales/sv-SE.yml +1 -1
- data/lib/active_admin/locales/tr.yml +1 -1
- data/lib/active_admin/locales/vi.yml +1 -1
- data/lib/active_admin/locales/zh-CN.yml +1 -1
- data/lib/active_admin/locales/zh-TW.yml +1 -1
- data/lib/active_admin/menu.rb +76 -38
- data/lib/active_admin/menu_collection.rb +96 -0
- data/lib/active_admin/menu_item.rb +61 -71
- data/lib/active_admin/namespace.rb +67 -5
- data/lib/active_admin/page.rb +6 -0
- data/lib/active_admin/page_controller.rb +13 -3
- data/lib/active_admin/resource.rb +11 -20
- data/lib/active_admin/resource/action_items.rb +3 -3
- data/lib/active_admin/resource/controllers.rb +0 -17
- data/lib/active_admin/resource/menu.rb +52 -24
- data/lib/active_admin/resource/naming.rb +6 -10
- data/lib/active_admin/resource/page_presenters.rb +57 -3
- data/lib/active_admin/resource/routes.rb +46 -0
- data/lib/active_admin/resource_controller.rb +2 -17
- data/lib/active_admin/resource_controller/data_access.rb +299 -0
- data/lib/active_admin/resource_controller/decorators.rb +2 -1
- data/lib/active_admin/resource_dsl.rb +12 -14
- data/lib/active_admin/router.rb +61 -56
- data/lib/active_admin/scope.rb +28 -18
- data/lib/active_admin/version.rb +1 -1
- data/lib/active_admin/view_factory.rb +0 -1
- data/lib/active_admin/view_helpers/breadcrumb_helper.rb +13 -19
- data/lib/active_admin/view_helpers/fields_for.rb +2 -0
- data/lib/active_admin/view_helpers/form_helper.rb +1 -1
- data/lib/active_admin/view_helpers/method_or_proc_helper.rb +66 -11
- data/lib/active_admin/views/components/attributes_table.rb +7 -4
- data/lib/active_admin/views/components/index_list.rb +68 -0
- data/lib/active_admin/views/components/paginated_collection.rb +13 -9
- data/lib/active_admin/views/components/scopes.rb +2 -8
- data/lib/active_admin/views/components/table_for.rb +1 -1
- data/lib/active_admin/views/footer.rb +1 -1
- data/lib/active_admin/views/header.rb +3 -2
- data/lib/active_admin/views/index_as_block.rb +4 -0
- data/lib/active_admin/views/index_as_blog.rb +4 -0
- data/lib/active_admin/views/index_as_grid.rb +4 -0
- data/lib/active_admin/views/index_as_table.rb +49 -7
- data/lib/active_admin/views/pages/index.rb +19 -4
- data/lib/active_admin/views/tabbed_navigation.rb +10 -54
- data/lib/generators/active_admin/install/install_generator.rb +5 -1
- data/lib/generators/active_admin/install/templates/active_admin.rb.erb +58 -0
- data/spec/integration/{default_namespace.rb → default_namespace_spec.rb} +0 -16
- data/spec/spec_helper.rb +3 -0
- data/spec/support/detect_rails_version.rb +10 -3
- data/spec/support/rails_template.rb +1 -1
- data/spec/support/templates/post_decorator.rb +6 -6
- data/spec/unit/application_spec.rb +5 -5
- data/spec/unit/authorization/authorization_adapter_spec.rb +61 -0
- data/spec/unit/authorization/controller_authorization_spec.rb +47 -0
- data/spec/unit/base_controller_spec.rb +0 -2
- data/spec/unit/batch_actions/resource_spec.rb +1 -1
- data/spec/unit/breadcrumbs_spec.rb +3 -3
- data/spec/unit/cancan_adapter_spec.rb +35 -0
- data/spec/unit/config_shared_examples.rb +9 -30
- data/spec/unit/devise_spec.rb +29 -0
- data/spec/unit/dsl_spec.rb +61 -0
- data/spec/unit/filters/filter_form_builder_spec.rb +58 -4
- data/spec/unit/filters/resource_spec.rb +17 -5
- data/spec/unit/form_builder_spec.rb +15 -0
- data/spec/unit/menu_collection_spec.rb +62 -0
- data/spec/unit/menu_item_spec.rb +51 -37
- data/spec/unit/menu_spec.rb +33 -29
- data/spec/unit/namespace/authorization_spec.rb +31 -0
- data/spec/unit/namespace/register_page_spec.rb +6 -28
- data/spec/unit/namespace/register_resource_spec.rb +11 -34
- data/spec/unit/namespace_spec.rb +63 -2
- data/spec/unit/page_controller_spec.rb +0 -3
- data/spec/unit/reloader_spec.rb +5 -5
- data/spec/unit/resource/menu_spec.rb +1 -13
- data/spec/unit/resource/naming_spec.rb +20 -2
- data/spec/unit/resource/page_presenters_spec.rb +14 -2
- data/spec/unit/resource_controller/{collection_spec.rb → data_access_spec.rb} +31 -13
- data/spec/unit/resource_controller_spec.rb +4 -5
- data/spec/unit/resource_spec.rb +33 -11
- data/spec/unit/routing_spec.rb +43 -0
- data/spec/unit/scope_spec.rb +13 -0
- data/spec/unit/view_factory_spec.rb +0 -1
- data/spec/unit/view_helpers/fields_for_spec.rb +4 -0
- data/spec/unit/view_helpers/form_helper_spec.rb +6 -2
- data/spec/unit/view_helpers/method_or_proc_helper_spec.rb +97 -0
- data/spec/unit/views/components/attributes_table_spec.rb +11 -0
- data/spec/unit/views/components/index_list_spec.rb +32 -0
- data/spec/unit/views/tabbed_navigation_spec.rb +42 -40
- data/tasks/test.rake +1 -1
- metadata +127 -40
- data/lib/active_admin/menu_builder.rb +0 -65
- data/lib/active_admin/resource_controller/callbacks.rb +0 -59
- data/lib/active_admin/resource_controller/collection.rb +0 -158
- data/lib/active_admin/views/utility_nav.rb +0 -41
- data/spec/unit/base_controller_shared_examples.rb +0 -25
- data/spec/unit/dsl_include_spec.rb +0 -20
@@ -3,7 +3,7 @@ vi:
|
|
3
3
|
dashboard: Dashboard
|
4
4
|
dashboard_welcome:
|
5
5
|
welcome: "Chào mừng bạn đến với Active Admin. Đây là trang Dashboard mặc định."
|
6
|
-
call_to_action: "Để thêm phần phần cho trang Dashboar hãy chỉnh sửa 'app/admin/
|
6
|
+
call_to_action: "Để thêm phần phần cho trang Dashboar hãy chỉnh sửa 'app/admin/dashboard.rb'"
|
7
7
|
view: "Xem"
|
8
8
|
edit: "Chỉnh sửa"
|
9
9
|
delete: "Xóa"
|
data/lib/active_admin/menu.rb
CHANGED
@@ -5,8 +5,8 @@ module ActiveAdmin
|
|
5
5
|
# To build a new menu:
|
6
6
|
#
|
7
7
|
# menu = Menu.new do |m|
|
8
|
-
# m.add
|
9
|
-
# m.add
|
8
|
+
# m.add label: 'Dashboard', url: '/'
|
9
|
+
# m.add label: 'Users', url: '/users'
|
10
10
|
# end
|
11
11
|
#
|
12
12
|
# If you're interested in configuring a menu item, take a look at the
|
@@ -14,54 +14,92 @@ module ActiveAdmin
|
|
14
14
|
#
|
15
15
|
class Menu
|
16
16
|
|
17
|
-
attr_accessor :children
|
18
|
-
|
19
17
|
def initialize
|
20
|
-
|
21
|
-
|
18
|
+
super # MenuNode
|
22
19
|
yield(self) if block_given?
|
23
20
|
end
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
# menu = Menu.new
|
29
|
-
# dash = MenuItem.new :label => "Dashboard"
|
30
|
-
# menu.add dash
|
31
|
-
#
|
32
|
-
# Accepts as many menu items as you wish to add:
|
33
|
-
#
|
34
|
-
# menu = Menu.new
|
35
|
-
# dash = MenuItem.new :label => "Dashboard"
|
36
|
-
# admin = MenuItem.new :label => "Admin"
|
37
|
-
# menu.add dash, admin
|
38
|
-
#
|
39
|
-
# @param [MenuItem] menu_items Add as many menu items as you pass in
|
40
|
-
def add(*menu_items)
|
41
|
-
menu_items.each do |menu_item|
|
42
|
-
menu_item.parent = nil
|
43
|
-
@children << menu_item
|
22
|
+
module MenuNode
|
23
|
+
def initialize
|
24
|
+
@children = {}
|
44
25
|
end
|
45
|
-
end
|
46
26
|
|
47
|
-
|
48
|
-
|
49
|
-
|
27
|
+
def [](id)
|
28
|
+
@children[normalize_id(id)]
|
29
|
+
end
|
30
|
+
def []=(id, child)
|
31
|
+
@children[normalize_id(id)] = child
|
32
|
+
end
|
50
33
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
34
|
+
# Recursively builds any given menu items. There are two syntaxes supported,
|
35
|
+
# as shown in the below examples. Both create an identical menu structure.
|
36
|
+
#
|
37
|
+
# Example 1:
|
38
|
+
# menu = Menu.new
|
39
|
+
# menu.add label: 'Dashboard' do |dash|
|
40
|
+
# dash.add label: 'My Child Dashboard'
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# Example 2:
|
44
|
+
# menu = Menu.new
|
45
|
+
# menu.add label: 'Dashboard'
|
46
|
+
# menu.add parent: 'Dashboard', label: 'My Child Dashboard'
|
47
|
+
#
|
48
|
+
def add(options)
|
49
|
+
item = if parent = options.delete(:parent)
|
50
|
+
(self[parent] || add(:label => parent)).add options
|
51
|
+
else
|
52
|
+
_add options.merge :parent => self
|
53
|
+
end
|
55
54
|
|
56
|
-
|
55
|
+
yield(item) if block_given?
|
57
56
|
|
58
|
-
|
59
|
-
id = MenuItem.generate_item_id(id)
|
60
|
-
find{ |i| i.id == id }
|
57
|
+
item
|
61
58
|
end
|
62
59
|
|
60
|
+
# Whether any children match the given item.
|
61
|
+
def include?(item)
|
62
|
+
@children.values.include? item
|
63
|
+
end
|
64
|
+
|
65
|
+
# Used in the UI to visually distinguish which menu item is selected.
|
66
|
+
def current?(item)
|
67
|
+
self == item || include?(item)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns sorted array of menu items that should be displayed in this context.
|
71
|
+
# Sorts by priority first, then alphabetically by label if needed.
|
72
|
+
def items(context = nil)
|
73
|
+
@children.values.select{ |i| i.display?(context) }.sort do |a,b|
|
74
|
+
result = a.priority <=> b.priority
|
75
|
+
result = a.label(context) <=> b.label(context) if result == 0
|
76
|
+
result
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
attr_reader :children
|
81
|
+
private
|
82
|
+
attr_writer :children
|
83
|
+
|
84
|
+
# The method that actually adds new menu items. Called by the public method.
|
85
|
+
# If this ID is already taken, transfer the children of the existing item to the new item.
|
86
|
+
def _add(options)
|
87
|
+
item = ActiveAdmin::MenuItem.new(options)
|
88
|
+
item.send :children=, self[item.id].children if self[item.id]
|
89
|
+
self[item.id] = item
|
90
|
+
end
|
91
|
+
|
92
|
+
def normalize_id(id)
|
93
|
+
case id
|
94
|
+
when String, Symbol
|
95
|
+
id.to_s.downcase.gsub ' ', '_'
|
96
|
+
else
|
97
|
+
raise TypeError, "#{id.class} isn't supported as a Menu ID"
|
98
|
+
end
|
99
|
+
end
|
63
100
|
end
|
64
101
|
|
65
|
-
|
102
|
+
include MenuNode
|
66
103
|
|
104
|
+
end
|
67
105
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
|
3
|
+
DEFAULT_MENU = :default
|
4
|
+
|
5
|
+
# A MenuCollection stores multiple menus for any given namespace. Namespaces delegate
|
6
|
+
# the addition of menu items to this class.
|
7
|
+
class MenuCollection
|
8
|
+
|
9
|
+
NoMenuError = Class.new(KeyError)
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@menus = {}
|
13
|
+
@build_callbacks = []
|
14
|
+
@built = false
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add a new menu item to a menu in the collection
|
18
|
+
def add(menu_name, menu_item_options = {})
|
19
|
+
menu = find_or_create(menu_name)
|
20
|
+
|
21
|
+
menu.add menu_item_options
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear!
|
25
|
+
@menus = {}
|
26
|
+
@built = false
|
27
|
+
end
|
28
|
+
|
29
|
+
def exists?(menu_name)
|
30
|
+
@menus.keys.include? menu_name
|
31
|
+
end
|
32
|
+
|
33
|
+
def fetch(menu_name)
|
34
|
+
build_menus!
|
35
|
+
|
36
|
+
@menus[menu_name] or
|
37
|
+
raise NoMenuError, "No menu by the name of #{menu_name.inspect} in availble menus: #{@menus.keys.join(", ")}"
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add callbacks that will be run when the menu is going to be built. This
|
41
|
+
# helps use with reloading and allows configurations to add items to menus.
|
42
|
+
#
|
43
|
+
# @param [Proc] block A block which will be ran when the menu is built. The
|
44
|
+
# will have the menu collection yielded.
|
45
|
+
def on_build(&block)
|
46
|
+
@build_callbacks << block
|
47
|
+
end
|
48
|
+
|
49
|
+
# Add callbacks that will be run before the menu is built
|
50
|
+
def before_build(&block)
|
51
|
+
@build_callbacks.unshift(block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def menu(menu_name)
|
55
|
+
menu = find_or_create(menu_name)
|
56
|
+
|
57
|
+
yield(menu) if block_given?
|
58
|
+
|
59
|
+
menu
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def built?
|
65
|
+
@built
|
66
|
+
end
|
67
|
+
|
68
|
+
def build_menus!
|
69
|
+
return if built?
|
70
|
+
|
71
|
+
build_default_menu
|
72
|
+
run_on_build_callbacks
|
73
|
+
|
74
|
+
@built = true
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_on_build_callbacks
|
78
|
+
@build_callbacks.each do |callback|
|
79
|
+
callback.call(self)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def build_default_menu
|
84
|
+
find_or_create DEFAULT_MENU
|
85
|
+
end
|
86
|
+
|
87
|
+
def find_or_create(menu_name)
|
88
|
+
menu_name ||= DEFAULT_MENU
|
89
|
+
@menus[menu_name] ||= ActiveAdmin::Menu.new
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -1,106 +1,96 @@
|
|
1
|
-
|
1
|
+
require 'active_admin/view_helpers/method_or_proc_helper'
|
2
2
|
|
3
|
+
module ActiveAdmin
|
3
4
|
class MenuItem
|
5
|
+
include Menu::MenuNode
|
6
|
+
include MethodOrProcHelper
|
4
7
|
|
5
|
-
|
8
|
+
attr_reader :html_options, :parent, :priority
|
6
9
|
|
7
|
-
#
|
10
|
+
# Builds a new menu item
|
8
11
|
#
|
9
12
|
# @param [Hash] options The options for the menu
|
10
13
|
#
|
11
|
-
# @option options [String, Proc] :label
|
12
|
-
# The label to display for this menu item.
|
13
|
-
#
|
14
|
+
# @option options [String, Symbol, Proc] :label
|
15
|
+
# The label to display for this menu item.
|
16
|
+
# Default: Titleized Resource Name
|
14
17
|
#
|
15
18
|
# @option options [String] :id
|
16
|
-
# A custom id to reference this menu item with.
|
17
|
-
#
|
19
|
+
# A custom id to reference this menu item with.
|
20
|
+
# Default: underscored_resource_name
|
18
21
|
#
|
19
|
-
# @option options [String, Symbol] :url
|
20
|
-
#
|
21
|
-
# view will automatically call the method for you.
|
22
|
+
# @option options [String, Symbol, Proc] :url
|
23
|
+
# The URL this item will link to.
|
22
24
|
#
|
23
25
|
# @option options [Integer] :priority
|
24
|
-
#
|
25
|
-
# earlier in the menu the item will be displayed.
|
26
|
+
# The lower the priority, the earlier in the menu the item will be displayed.
|
26
27
|
# Default: 10
|
27
28
|
#
|
28
|
-
# @option options [Proc] :if
|
29
|
-
#
|
30
|
-
#
|
29
|
+
# @option options [Symbol, Proc] :if
|
30
|
+
# This decides whether the menu item will be displayed. Evaluated on each request.
|
31
|
+
#
|
32
|
+
# @option options [Hash] :html_options
|
33
|
+
# A hash of options to pass to `link_to` when rendering the item
|
34
|
+
#
|
35
|
+
# @option [ActiveAdmin::MenuItem] :parent
|
36
|
+
# This menu item's parent. It will be displayed nested below its parent.
|
37
|
+
#
|
38
|
+
# NOTE: for :label, :url, and :if
|
39
|
+
# These options are evaluated in the view context at render time. Symbols are called
|
40
|
+
# as methods on `self`, and Procs are exec'd within `self`.
|
41
|
+
# Here are some examples of what you can do:
|
42
|
+
#
|
43
|
+
# menu if: :admin?
|
44
|
+
# menu url: :new_book_path
|
45
|
+
# menu url: :awesome_helper_you_defined
|
46
|
+
# menu label: ->{ User.some_method }
|
47
|
+
# menu label: ->{ I18n.t 'menus.user' }
|
31
48
|
#
|
32
|
-
# @option options [Proc] :parent
|
33
|
-
# The parent label to display for this menu item. Menu item will be nested
|
34
|
-
# under that label. It can either be a String or a Proc. If the option is Proc,
|
35
|
-
# it is called each time the label is requested.
|
36
49
|
def initialize(options = {})
|
37
|
-
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
|
44
|
-
@
|
50
|
+
super() # MenuNode
|
51
|
+
@label = options[:label]
|
52
|
+
@dirty_id = options[:id] || options[:label]
|
53
|
+
@url = options[:url] || '#'
|
54
|
+
@priority = options[:priority] || 10
|
55
|
+
@html_options = options[:html_options] || {}
|
56
|
+
@should_display = options[:if] || proc{true}
|
57
|
+
@parent = options[:parent]
|
45
58
|
|
46
59
|
yield(self) if block_given? # Builder style syntax
|
47
60
|
end
|
48
61
|
|
49
|
-
def
|
50
|
-
id
|
62
|
+
def id
|
63
|
+
@id ||= normalize_id @dirty_id
|
51
64
|
end
|
52
65
|
|
53
|
-
def label
|
54
|
-
|
55
|
-
when Proc
|
56
|
-
@label.call
|
57
|
-
else
|
58
|
-
@label.to_s
|
59
|
-
end
|
66
|
+
def label(context = nil)
|
67
|
+
render_in_context context, @label
|
60
68
|
end
|
61
69
|
|
62
|
-
def
|
63
|
-
|
64
|
-
menu_item.parent = self
|
65
|
-
@children << menu_item
|
66
|
-
end
|
70
|
+
def url(context = nil)
|
71
|
+
render_in_context context, @url
|
67
72
|
end
|
68
73
|
|
69
|
-
|
70
|
-
|
74
|
+
# Don't display if the :if option passed says so
|
75
|
+
# Don't display if the link isn't real, we have children, and none of the children are being displayed.
|
76
|
+
def display?(context = nil)
|
77
|
+
return false unless render_in_context(context, @should_display)
|
78
|
+
return false if !real_url?(context) && @children.any? && !items(context).any?
|
79
|
+
true
|
71
80
|
end
|
72
81
|
|
73
|
-
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
def dom_id
|
78
|
-
id.gsub( " ", '_' ).gsub( /[^a-z0-9_]/, '' )
|
79
|
-
end
|
80
|
-
|
81
|
-
# Returns an array of the ancestory of this menu item
|
82
|
-
# The first item is the immediate parent fo the item
|
82
|
+
# Returns an array of the ancestory of this menu item.
|
83
|
+
# The first item is the immediate parent of the item.
|
83
84
|
def ancestors
|
84
|
-
|
85
|
-
[parent, parent.ancestors].flatten
|
85
|
+
parent ? [parent, parent.ancestors].flatten : []
|
86
86
|
end
|
87
87
|
|
88
|
-
|
89
|
-
# @blog_menu["Create New"] => <#MenuItem @name="Create New" >
|
90
|
-
def [](id)
|
91
|
-
@children.find_by_id(id)
|
92
|
-
end
|
93
|
-
|
94
|
-
def <=>(other)
|
95
|
-
result = priority <=> other.priority
|
96
|
-
result = label <=> other.label if result == 0
|
97
|
-
result
|
98
|
-
end
|
88
|
+
private
|
99
89
|
|
100
|
-
#
|
101
|
-
|
102
|
-
|
103
|
-
|
90
|
+
# URL is not nil, empty, or '#'
|
91
|
+
def real_url?(context = nil)
|
92
|
+
url = url context
|
93
|
+
url.present? && url != '#'
|
104
94
|
end
|
105
95
|
|
106
96
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'active_admin/helpers/settings'
|
2
2
|
require 'active_admin/resource_collection'
|
3
|
-
require 'active_admin/menu_builder'
|
4
3
|
|
5
4
|
module ActiveAdmin
|
6
5
|
|
@@ -33,7 +32,7 @@ module ActiveAdmin
|
|
33
32
|
|
34
33
|
RegisterEvent = 'active_admin.namespace.register'.freeze
|
35
34
|
|
36
|
-
attr_reader :application, :resources, :name, :
|
35
|
+
attr_reader :application, :resources, :name, :menus
|
37
36
|
|
38
37
|
def initialize(application, name)
|
39
38
|
@application = application
|
@@ -41,6 +40,7 @@ module ActiveAdmin
|
|
41
40
|
@resources = ResourceCollection.new
|
42
41
|
register_module unless root?
|
43
42
|
generate_dashboard_controller
|
43
|
+
build_menu_collection
|
44
44
|
end
|
45
45
|
|
46
46
|
# Register a resource into this namespace. The preffered method to access this is to
|
@@ -114,16 +114,78 @@ module ActiveAdmin
|
|
114
114
|
application.send(name)
|
115
115
|
end
|
116
116
|
|
117
|
-
def
|
118
|
-
@
|
117
|
+
def fetch_menu(name)
|
118
|
+
@menus.fetch(name)
|
119
119
|
end
|
120
120
|
|
121
121
|
def reset_menu!
|
122
|
-
@
|
122
|
+
@menus.clear!
|
123
|
+
end
|
124
|
+
|
125
|
+
# Add a callback to be ran when we build the menu
|
126
|
+
#
|
127
|
+
# @param [Symbol] name The name of the menu. Default: :default
|
128
|
+
# @param [Proc] block The block to be ran when the menu is built
|
129
|
+
#
|
130
|
+
# @returns [void]
|
131
|
+
def build_menu(name = DEFAULT_MENU, &block)
|
132
|
+
@menus.before_build do |menus|
|
133
|
+
menus.menu name do |menu|
|
134
|
+
block.call(menu)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Add the default logout button to the menu, using the ActiveAdmin configuration settings
|
140
|
+
#
|
141
|
+
# @param [ActiveAdmin::MenuItem] menu The menu to add the logout link to
|
142
|
+
# @param [Fixnum] priority Override the default priority of 100 to position the logout button where you want
|
143
|
+
# @param [Hash] html_options An options hash to pass along to link_to
|
144
|
+
#
|
145
|
+
# @returns [void]
|
146
|
+
def add_logout_button_to_menu(menu, priority=100, html_options={})
|
147
|
+
if logout_link_path
|
148
|
+
logout_method = logout_link_method || :get
|
149
|
+
menu.add :id => 'logout',
|
150
|
+
:priority => priority,
|
151
|
+
:label => proc{ I18n.t('active_admin.logout') },
|
152
|
+
:html_options => html_options.reverse_merge(:method => logout_method),
|
153
|
+
:url => proc{ render_or_call_method_or_proc_on self, active_admin_namespace.logout_link_path },
|
154
|
+
:if => proc{ current_active_admin_user? }
|
155
|
+
end
|
123
156
|
end
|
124
157
|
|
125
158
|
protected
|
126
159
|
|
160
|
+
def build_menu_collection
|
161
|
+
@menus = MenuCollection.new
|
162
|
+
|
163
|
+
@menus.on_build do |menus|
|
164
|
+
# Support for deprecated dashboards...
|
165
|
+
Dashboards.add_to_menu(self, menus.menu(DEFAULT_MENU))
|
166
|
+
|
167
|
+
# Build the default utility navigation
|
168
|
+
build_default_utility_nav
|
169
|
+
|
170
|
+
resources.each do |resource|
|
171
|
+
resource.add_to_menu(@menus)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Builds the default utility navigation in top right header with current user & logout button
|
177
|
+
def build_default_utility_nav
|
178
|
+
return if @menus.exists? :utility_navigation
|
179
|
+
@menus.menu :utility_navigation do |menu|
|
180
|
+
menu.add :label => proc{ display_name current_active_admin_user },
|
181
|
+
:url => '#',
|
182
|
+
:id => 'current_user',
|
183
|
+
:if => proc{ current_active_admin_user? }
|
184
|
+
|
185
|
+
add_logout_button_to_menu menu
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
127
189
|
# Either returns an existing Resource instance or builds a new
|
128
190
|
# one for the resource and options
|
129
191
|
def find_or_build_resource(resource_class, options)
|