integral 1.4.0 → 1.5.0

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 (172) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +4 -3
  3. data/app/assets/javascripts/integral/backend.js +86 -2
  4. data/app/assets/javascripts/integral/support/character_counter.js +13 -8
  5. data/app/assets/javascripts/integral/support/list.coffee +1 -0
  6. data/app/assets/javascripts/integral/support/record_selector.coffee +2 -0
  7. data/app/assets/javascripts/integral/support/slug_generator.coffee +1 -0
  8. data/app/assets/stylesheets/integral/backend.sass +34 -23
  9. data/app/assets/stylesheets/integral/backend/_foundation_settings.scss +2 -2
  10. data/app/assets/stylesheets/integral/backend/dashboard-layout.scss +27 -63
  11. data/app/assets/stylesheets/integral/backend/devise.sass +2 -3
  12. data/app/assets/stylesheets/integral/backend/materialize-tags.sass +1 -0
  13. data/app/assets/stylesheets/integral/backend/modules/dropdown_pane_notifications.scss +150 -0
  14. data/app/assets/stylesheets/integral/backend/modules/dropdown_pane_profile.scss +59 -0
  15. data/app/assets/stylesheets/integral/backend/shared.sass +41 -2
  16. data/app/assets/stylesheets/integral/frontend/layout.sass +10 -0
  17. data/app/assets/stylesheets/integral/support/media-query-indicator.sass +4 -4
  18. data/app/controllers/integral/backend/activities_controller.rb +21 -27
  19. data/app/controllers/integral/backend/base_controller.rb +87 -37
  20. data/app/controllers/integral/backend/images_controller.rb +26 -8
  21. data/app/controllers/integral/backend/lists_controller.rb +2 -14
  22. data/app/controllers/integral/backend/notification_subscriptions_controller.rb +23 -0
  23. data/app/controllers/integral/backend/pages_controller.rb +0 -4
  24. data/app/controllers/integral/backend/posts_controller.rb +0 -4
  25. data/app/controllers/integral/backend/settings_controller.rb +4 -0
  26. data/app/controllers/integral/backend/static_pages_controller.rb +6 -0
  27. data/app/controllers/integral/backend/users_controller.rb +43 -24
  28. data/app/controllers/integral/blog_controller.rb +12 -0
  29. data/app/controllers/integral/categories_controller.rb +17 -3
  30. data/app/controllers/integral/tags_controller.rb +5 -2
  31. data/app/decorators/integral/base_decorator.rb +16 -0
  32. data/app/decorators/integral/image_decorator.rb +2 -2
  33. data/app/decorators/integral/list_decorator.rb +1 -13
  34. data/app/decorators/integral/notification/notification_decorator.rb +74 -0
  35. data/app/decorators/integral/page_decorator.rb +1 -13
  36. data/app/decorators/integral/post_decorator.rb +1 -2
  37. data/app/decorators/integral/user_decorator.rb +1 -13
  38. data/app/decorators/integral/version_decorator.rb +8 -4
  39. data/app/helpers/integral/backend/base_helper.rb +97 -31
  40. data/app/jobs/integral/application_job.rb +1 -0
  41. data/app/jobs/integral/newsletter_signup_job.rb +0 -2
  42. data/app/mailers/integral/devise_mailer.rb +6 -0
  43. data/app/models/concerns/integral/notification/subscribable.rb +67 -0
  44. data/app/models/integral/application_record.rb +9 -0
  45. data/app/models/integral/category.rb +9 -0
  46. data/app/models/integral/image.rb +40 -3
  47. data/app/models/integral/list.rb +10 -2
  48. data/app/models/integral/list_item.rb +14 -14
  49. data/app/models/integral/list_item_connection.rb +6 -0
  50. data/app/models/integral/notification/notification.rb +28 -0
  51. data/app/models/integral/notification/subscription.rb +14 -0
  52. data/app/models/integral/page.rb +15 -8
  53. data/app/models/integral/post.rb +11 -13
  54. data/app/models/integral/user.rb +45 -2
  55. data/app/policies/integral/base_policy.rb +7 -12
  56. data/app/policies/integral/page_policy.rb +1 -0
  57. data/app/policies/integral/version_policy.rb +0 -8
  58. data/app/views/devise/invitations/edit.haml +1 -4
  59. data/app/views/devise/mailer/invitation_instructions.inky-haml +20 -0
  60. data/app/views/integral/backend/activities/grid/_dropdown_actions.haml +1 -0
  61. data/app/views/integral/backend/activities/grid/_row_content.haml +13 -0
  62. data/app/views/integral/backend/activities/index.haml +7 -13
  63. data/app/views/integral/backend/activities/shared/_grid.haml +35 -20
  64. data/app/views/integral/backend/activities/shared/index.haml +12 -12
  65. data/app/views/integral/backend/activities/shared/show.haml +7 -7
  66. data/app/views/integral/backend/activities/show.haml +1 -1
  67. data/app/views/integral/backend/categories/_modal.haml +2 -3
  68. data/app/views/integral/backend/images/_form.haml +13 -25
  69. data/app/views/integral/backend/images/edit.haml +1 -9
  70. data/app/views/integral/backend/images/grid/_dropdown_actions.haml +5 -0
  71. data/app/views/integral/backend/images/grid/_row_content.haml +5 -0
  72. data/app/views/integral/backend/images/index.haml +11 -17
  73. data/app/views/integral/backend/images/list.haml +11 -0
  74. data/app/views/integral/backend/images/show.haml +26 -0
  75. data/app/views/integral/backend/lists/_form.haml +6 -19
  76. data/app/views/integral/backend/lists/_item_modal.haml +3 -3
  77. data/app/views/integral/backend/lists/_manager.haml +11 -13
  78. data/app/views/integral/backend/lists/edit.haml +6 -20
  79. data/app/views/integral/backend/lists/grid/_dropdown_actions.haml +9 -0
  80. data/app/views/integral/backend/lists/grid/_row_content.haml +3 -0
  81. data/app/views/integral/backend/lists/index.haml +11 -17
  82. data/app/views/integral/backend/lists/list.haml +11 -0
  83. data/app/views/integral/backend/lists/show.haml +30 -0
  84. data/app/views/integral/backend/notifications/_notification.haml +21 -0
  85. data/app/views/integral/backend/pages/_form.haml +19 -43
  86. data/app/views/integral/backend/pages/edit.haml +4 -12
  87. data/app/views/integral/backend/pages/grid/_dropdown_actions.haml +11 -0
  88. data/app/views/integral/backend/pages/grid/_row_content.haml +5 -0
  89. data/app/views/integral/backend/pages/index.haml +6 -6
  90. data/app/views/integral/backend/pages/list.haml +12 -19
  91. data/app/views/integral/backend/pages/show.haml +19 -35
  92. data/app/views/integral/backend/posts/_form.haml +18 -56
  93. data/app/views/integral/backend/posts/edit.haml +4 -14
  94. data/app/views/integral/backend/posts/grid/_dropdown_actions.haml +10 -0
  95. data/app/views/integral/backend/posts/grid/_row_content.haml +6 -0
  96. data/app/views/integral/backend/posts/index.haml +6 -6
  97. data/app/views/integral/backend/posts/list.haml +11 -18
  98. data/app/views/integral/backend/posts/new.haml +0 -1
  99. data/app/views/integral/backend/posts/show.haml +18 -41
  100. data/app/views/integral/backend/shared/_breadcrumbs.haml +7 -4
  101. data/app/views/integral/backend/shared/_image_preview.haml +10 -3
  102. data/app/views/integral/backend/shared/_image_selector.haml +1 -1
  103. data/app/views/integral/backend/shared/_notification_subscription_toggle.haml +22 -0
  104. data/app/views/integral/backend/shared/action_bar/_index.haml +9 -0
  105. data/app/views/integral/backend/shared/action_bar/_show.haml +3 -0
  106. data/app/views/integral/backend/shared/cards/_at_a_glance.haml +3 -3
  107. data/app/views/integral/backend/shared/cards/_categories.haml +27 -28
  108. data/app/views/integral/backend/shared/cards/_object.haml +1 -1
  109. data/app/views/integral/backend/shared/cards/_recent_activity.haml +12 -12
  110. data/app/views/integral/backend/shared/cards/_recent_resources.haml +17 -0
  111. data/app/views/integral/backend/shared/cards/_top_post_authors.haml +14 -15
  112. data/app/views/integral/backend/shared/cards/_welcome.haml +24 -25
  113. data/app/views/integral/backend/shared/{_empty_grid.haml → grid/_empty.haml} +0 -0
  114. data/app/views/integral/backend/shared/grid/_form.haml +9 -0
  115. data/app/views/integral/backend/shared/grid/_grid.haml +21 -0
  116. data/app/views/integral/backend/shared/{_pagination.haml → grid/_pagination.haml} +0 -0
  117. data/app/views/integral/backend/shared/grid/_row_layout.haml +8 -0
  118. data/app/views/integral/backend/shared/record_selector/_collection.haml +1 -0
  119. data/app/views/integral/backend/shared/record_selector/_modal.haml +9 -10
  120. data/app/views/integral/backend/static_pages/dashboard.haml +6 -7
  121. data/app/views/integral/backend/users/_form.haml +34 -46
  122. data/app/views/integral/backend/users/grid/_dropdown_actions.haml +17 -0
  123. data/app/views/integral/backend/users/grid/_row_content.haml +8 -0
  124. data/app/views/integral/backend/users/index.haml +6 -6
  125. data/app/views/integral/backend/users/list.haml +10 -16
  126. data/app/views/integral/backend/users/show.haml +10 -1
  127. data/app/views/integral/categories/show.haml +3 -3
  128. data/app/views/integral/posts/_article_footer.haml +1 -1
  129. data/app/views/integral/posts/_card.haml +1 -1
  130. data/app/views/integral/posts/_most_read_section.haml +1 -1
  131. data/app/views/integral/posts/_post.haml +1 -1
  132. data/app/views/integral/posts/templates/default.haml +1 -1
  133. data/app/views/integral/shared/sidebar/_item.haml +1 -1
  134. data/app/views/layouts/integral/backend.html.haml +24 -5
  135. data/app/views/layouts/integral/backend/_create_dropdown.haml +1 -30
  136. data/app/views/layouts/integral/backend/_main_menu_items.haml +1 -101
  137. data/config/initializers/devise.rb +1 -1
  138. data/config/locales/en.yml +60 -2
  139. data/config/routes.rb +2 -0
  140. data/db/migrate/20200407022636_create_integral_notifications.rb +25 -0
  141. data/db/migrate/20200421223602_add_status_to_integral_users.rb +5 -0
  142. data/db/seeds.rb +15 -11
  143. data/lib/integral.rb +1 -0
  144. data/lib/integral/acts_as_integral.rb +115 -0
  145. data/lib/integral/acts_as_listable.rb +1 -1
  146. data/lib/integral/engine.rb +9 -0
  147. data/lib/integral/grids/activities_grid.rb +0 -1
  148. data/lib/integral/grids/lists_grid.rb +1 -0
  149. data/lib/integral/grids/posts_grid.rb +5 -1
  150. data/lib/integral/grids/users_grid.rb +5 -0
  151. data/lib/integral/list_renderer.rb +5 -1
  152. data/lib/integral/router.rb +20 -4
  153. data/lib/integral/version.rb +1 -1
  154. data/spec/factories.rb +15 -1
  155. metadata +45 -39
  156. data/app/decorators/integral/category_version_decorator.rb +0 -7
  157. data/app/decorators/integral/image_version_decorator.rb +0 -7
  158. data/app/decorators/integral/list_version_decorator.rb +0 -7
  159. data/app/decorators/integral/page_version_decorator.rb +0 -7
  160. data/app/decorators/integral/post_version_decorator.rb +0 -7
  161. data/app/decorators/integral/user_version_decorator.rb +0 -7
  162. data/app/views/devise/mailer/invitation_instructions.html.erb +0 -13
  163. data/app/views/integral/backend/activities/_grid.haml +0 -22
  164. data/app/views/integral/backend/images/_grid.haml +0 -16
  165. data/app/views/integral/backend/lists/_grid.haml +0 -14
  166. data/app/views/integral/backend/pages/_grid.haml +0 -46
  167. data/app/views/integral/backend/posts/_grid.haml +0 -51
  168. data/app/views/integral/backend/shared/_grid.haml +0 -18
  169. data/app/views/integral/backend/shared/cards/_recent_pages.haml +0 -19
  170. data/app/views/integral/backend/shared/cards/_recent_posts.haml +0 -18
  171. data/app/views/integral/backend/shared/cards/_recent_users.haml +0 -19
  172. data/app/views/integral/backend/users/_grid.haml +0 -36
@@ -15,5 +15,17 @@ module Integral
15
15
  def set_breadcrumbs
16
16
  add_breadcrumb I18n.t('integral.breadcrumbs.home'), :root_url
17
17
  end
18
+
19
+ def page_title
20
+ return t('.title') unless params[:page].present?
21
+
22
+ "Page #{params[:page]} - #{t('.title')}"
23
+ end
24
+
25
+ def page_description
26
+ return t('.description') unless params[:page].present?
27
+
28
+ "Page #{params[:page]} - #{t('.description')}"
29
+ end
18
30
  end
19
31
  end
@@ -8,14 +8,28 @@ module Integral
8
8
  def show
9
9
  add_breadcrumb @resource.title, nil
10
10
 
11
+ page_title = params[:page].present? ? "#{@resource.title} - Page #{params[:page]}" : @resource.title
12
+ page_description = params[:page].present? ? "#{@resource.description} - Page #{params[:page]}" : @resource.description
13
+
11
14
  @meta_data = {
12
- page_title: @resource.title,
13
- page_description: @resource.description,
15
+ page_title: page_title,
16
+ page_description: page_description,
14
17
  image: @resource&.image&.url
15
18
  }
16
19
 
17
- @posts = Integral::Post.published.where(category_id: @resource.id).paginate(page: params[:page])
20
+ @posts = Integral::Post.published.where(category_id: @resource.id).includes(:image).order('published_at DESC').paginate(page: params[:page]).decorate
21
+ end
22
+
23
+ def url_for(options={})
24
+ if options.is_a?(Hash) && options.include?(:category_path) && options[:category_path] == true
25
+ "#{category_path(@resource)}?page=#{options[:page]}"
26
+ elsif options.is_a?(Hash) && options.empty?
27
+ category_path(@resource)
28
+ else
29
+ super(options)
30
+ end
18
31
  end
32
+ helper_method :url_for
19
33
 
20
34
  private
21
35
 
@@ -16,9 +16,12 @@ module Integral
16
16
  add_breadcrumb t('integral.breadcrumbs.tags'), :tags_url
17
17
  add_breadcrumb @tag.name, nil
18
18
 
19
+ page_title = params[:page].present? ? "#{@tag.name} - Page #{params[:page]}" : @tag.name
20
+ page_description = params[:page].present? ? "Page #{params[:page] } - #{t('integral.tags.show.description', tag_name: @tag.name)}" : t('integral.tags.show.description', tag_name: @tag.name)
21
+
19
22
  @meta_data = {
20
- page_title: @tag.name,
21
- page_description: t('integral.tags.show.description', tag_name: @tag.name)
23
+ page_title: page_title,
24
+ page_description: page_description
22
25
  }
23
26
 
24
27
  @tagged_posts = Integral::Post.tagged_with(@tag.name).published.paginate(page: params[:page])
@@ -0,0 +1,16 @@
1
+ module Integral
2
+ # Base decorator for Integral view-level logic
3
+ class BaseDecorator < Draper::Decorator
4
+ delegate_all
5
+
6
+ # @return [String] URL to backend activity
7
+ def activity_url(activity_id)
8
+ Integral::Engine.routes.url_helpers.send("activity_backend_#{object.class.model_name.singular_route_key}_url", object.id, activity_id)
9
+ end
10
+
11
+ # @return [String] URL to backend Image page
12
+ def backend_url
13
+ Integral::Engine.routes.url_helpers.send("backend_#{object.class.model_name.singular_route_key}_url", object.id)
14
+ end
15
+ end
16
+ end
@@ -5,12 +5,12 @@ module Integral
5
5
 
6
6
  # @return [String] URL to backend activity
7
7
  def activity_url(activity_id)
8
- # Integral::Engine.routes.url_helpers.activity_backend_img_url(object.id, activity_id)
8
+ Integral::Engine.routes.url_helpers.activity_backend_img_url(object.id, activity_id)
9
9
  end
10
10
 
11
11
  # @return [String] URL to backend Image page
12
12
  def backend_url
13
- Integral::Engine.routes.url_helpers.edit_backend_img_url(object)
13
+ Integral::Engine.routes.url_helpers.backend_img_url(object)
14
14
  end
15
15
  end
16
16
  end
@@ -1,18 +1,6 @@
1
1
  module Integral
2
2
  # List view-level logic
3
- class ListDecorator < Draper::Decorator
4
- delegate_all
5
-
6
- # @return [String] URL to backend activity
7
- def activity_url(activity_id)
8
- # Integral::Engine.routes.url_helpers.activity_backend_user_url(object.id, activity_id)
9
- end
10
-
11
- # @return [String] URL to backend list page
12
- def backend_url
13
- Integral::Engine.routes.url_helpers.edit_backend_list_url(self)
14
- end
15
-
3
+ class ListDecorator < BaseDecorator
16
4
  # @return [String] formatted title
17
5
  def title
18
6
  object.title
@@ -0,0 +1,74 @@
1
+ module Integral
2
+ module Notification
3
+ class NotificationDecorator < Draper::Decorator
4
+ delegate_all
5
+
6
+ def formatted_action
7
+ h.t("integral.actions.#{object.action}")
8
+ end
9
+
10
+ def action_verb
11
+ h.t("integral.actions.tense.past.#{object.action}")
12
+ end
13
+
14
+ # @return [String] Item URL
15
+ def item_url
16
+ decorated_item&.backend_url
17
+ end
18
+
19
+ def whodunnit_url
20
+ Integral::Engine.routes.url_helpers.backend_user_url(whodunnit.id) if whodunnit.present?
21
+ end
22
+
23
+ # @return [Integral::User] who carried out the version (if one exists)
24
+ def whodunnit
25
+ user_id = object.actor_id.to_i
26
+
27
+ return '' if user_id.zero?
28
+
29
+ @user = Integral::User.unscoped.find_by_id(object.actor_id)&.decorate
30
+ end
31
+
32
+ # @return [String] image linked to whodunnit
33
+ def whodunnit_avatar_url
34
+ if whodunnit.present?
35
+ whodunnit.avatar.url(:thumbnail)
36
+ else
37
+ ActionController::Base.helpers.asset_path('integral/defaults/user_avatar.jpg')
38
+ end
39
+ end
40
+
41
+ # @return [String] name linked to whodunnit
42
+ def whodunnit_name
43
+ if whodunnit.present?
44
+ whodunnit.name
45
+ else
46
+ 'System'
47
+ end
48
+ end
49
+
50
+ def item
51
+ @item ||= item_klass.unscoped.find(subscribable_id)
52
+ end
53
+
54
+ # @return [String] formatted title
55
+ def item_title
56
+ decorated_item&.title
57
+ end
58
+
59
+ # @return [Object] Associated Item
60
+ def decorated_item
61
+ @decorated_item ||= item&.decorate
62
+ end
63
+
64
+ # @return [String] formatted item type
65
+ def model_name
66
+ item_klass.model_name.human
67
+ end
68
+
69
+ def item_klass
70
+ subscribable_type.constantize
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,18 +1,6 @@
1
1
  module Integral
2
2
  # Page view-level logic
3
- class PageDecorator < Draper::Decorator
4
- delegate_all
5
-
6
- # @return [String] URL to backend activity
7
- def activity_url(activity_id)
8
- Integral::Engine.routes.url_helpers.activity_backend_page_url(object.id, activity_id)
9
- end
10
-
11
- # @return [String] URL to backend list page
12
- def backend_url
13
- Integral::Engine.routes.url_helpers.edit_backend_page_url(self)
14
- end
15
-
3
+ class PageDecorator < BaseDecorator
16
4
  # @return [String] formatted title
17
5
  def title
18
6
  object.title
@@ -1,7 +1,6 @@
1
1
  module Integral
2
2
  # Page view-level logic
3
- class PostDecorator < Draper::Decorator
4
- delegate_all
3
+ class PostDecorator < BaseDecorator
5
4
  decorates_association :category
6
5
 
7
6
  # Enables pagination
@@ -1,18 +1,6 @@
1
1
  module Integral
2
2
  # User view-level logic
3
- class UserDecorator < Draper::Decorator
4
- delegate_all
5
-
6
- # @return [String] URL to backend activity
7
- def activity_url(activity_id)
8
- Integral::Engine.routes.url_helpers.activity_backend_user_url(object.id, activity_id)
9
- end
10
-
11
- # @return [String] URL to backend list page
12
- def backend_url
13
- Integral::Engine.routes.url_helpers.backend_user_url(self)
14
- end
15
-
3
+ class UserDecorator < BaseDecorator
16
4
  # @return [String] formatted title
17
5
  def title
18
6
  object.name
@@ -54,13 +54,17 @@ module Integral
54
54
  end
55
55
  end
56
56
 
57
+ def item_class
58
+ item_type.constantize
59
+ end
60
+
57
61
  def item
58
- @item ||= item_type.constantize.unscoped.find(item_id)
62
+ @item ||= item_class.unscoped.find_by_id(item_id)
59
63
  end
60
64
 
61
65
  # @return [String] formatted title
62
66
  def item_title
63
- decorated_item&.title
67
+ decorated_item.present? ? decorated_item.title : '<deleted>'
64
68
  end
65
69
 
66
70
  # @return [Object] Associated Item
@@ -70,12 +74,12 @@ module Integral
70
74
 
71
75
  # @return [String] Font Awesome icon
72
76
  def item_icon
73
- 'ellipsis-v'
77
+ item_class.respond_to?(:integral_icon) ? item_class.integral_icon : 'ellipsis-v'
74
78
  end
75
79
 
76
80
  # @return [String] formatted item type
77
81
  def model_name
78
- object.item_type.constantize.model_name.human
82
+ item_class.model_name.human
79
83
  end
80
84
 
81
85
  # Currently not possible to show this as changeset isn't available in the query resultset for performance reasons - One possible solution would be to create a Grid class for each Version - rather than unioning all the tables it only includes it's own
@@ -5,6 +5,54 @@ module Integral
5
5
  module BaseHelper
6
6
  include Integral::SupportHelper
7
7
 
8
+ def render_main_menu
9
+ render_menu(extract_menu_items(Integral::ActsAsIntegral.backend_main_menu_items, :integral_backend_main_menu_item))
10
+ end
11
+
12
+ def render_create_menu
13
+ render_menu(extract_menu_items(Integral::ActsAsIntegral.backend_create_menu_items, :integral_backend_create_menu_item))
14
+ end
15
+
16
+ def recent_user_notifications
17
+ @recent_user_notifications ||= current_user.notifications.recent
18
+ end
19
+
20
+ # Handles extra optional options to `link_to` - Font awesome icons & wrapper
21
+ def link_to(name = nil, options = nil, html_options = nil, &block)
22
+ return super if block_given?
23
+ return super if html_options.nil?
24
+
25
+ if html_options[:icon]
26
+ name = content_tag(:span, name)
27
+ name.prepend(icon(html_options.delete(:icon)))
28
+ end
29
+
30
+ if html_options[:wrapper]
31
+ wrapper = html_options.delete(:wrapper)
32
+ if wrapper == :cell
33
+ content_tag(:div, super(name, options, html_options, &block), class: 'cell')
34
+ else
35
+ content_tag(wrapper, super(name, options, html_options, &block))
36
+ end
37
+ else
38
+ super(name, options, html_options, &block)
39
+ end
40
+ end
41
+
42
+ # @return [String] Resource Grid Form
43
+ def render_resource_grid_form(&block)
44
+ if block_given?
45
+ render(layout: "integral/backend/shared/grid/form", &block)
46
+ else
47
+ render(partial: "integral/backend/shared/grid/form")
48
+ end
49
+ end
50
+
51
+ # @return [String] Resource Grid
52
+ def render_resource_grid(locals = {})
53
+ render(partial: "integral/backend/shared/grid/grid", locals: locals)
54
+ end
55
+
8
56
  # @return [String] Integral card
9
57
  def render_card(partial, locals = {})
10
58
  render(partial: "integral/backend/shared/cards/#{partial}", locals: locals)
@@ -33,7 +81,10 @@ module Integral
33
81
  end
34
82
 
35
83
  def recent_activity_grid(options)
36
- Integral::Grids::ActivitiesGrid.new(options)
84
+ #Integral::Grids::ActivitiesGrid.new(options)
85
+ Integral::Grids::ActivitiesGrid.new options do |scope|
86
+ scope.where.not(whodunnit: nil)
87
+ end
37
88
  end
38
89
 
39
90
  # @return [String] title provided through yield or i18n scoped to controller namespace & action
@@ -85,36 +136,6 @@ module Integral
85
136
  ChartRenderer::Donut.render(dataset)
86
137
  end
87
138
 
88
- # Donut Graph - At a Glance
89
- def dataset_at_a_glance_posts
90
- [
91
- { scope: Integral::Post.published, label: 'Published' },
92
- { scope: Integral::Post.draft, label: 'Draft ' }
93
- ]
94
- end
95
-
96
- # Donut Graph - At a Glance
97
- def dataset_at_a_glance_pages
98
- [
99
- { scope: Integral::Page.published, label: 'Published' },
100
- { scope: Integral::Page.draft, label: 'Draft ' },
101
- { scope: Integral::Page.archived, label: 'Archived ' }
102
- ]
103
- end
104
-
105
- # Donut Graph - At a Glance
106
- def dataset_dashboard_atg
107
- data = [
108
- { scope: Integral::Page, label: 'Total Pages' },
109
- { scope: Integral::List, label: 'Total Lists' },
110
- { scope: Integral::Image, label: 'Total Images' },
111
- { scope: Integral::User, label: 'Total Users' }
112
- ]
113
-
114
- data.prepend(scope: Integral::Post, label: 'Total Posts') if Integral.blog_enabled?
115
- data
116
- end
117
-
118
139
  # Line graph - Last week
119
140
  def dataset_dashboard_last_week
120
141
  data = [
@@ -127,6 +148,51 @@ module Integral
127
148
  data.prepend(scope: Integral::Post, label: 'Posts') if Integral.blog_enabled?
128
149
  data
129
150
  end
151
+
152
+ def current_user_authorized_for_menu_item?(item)
153
+ if item[:authorize]
154
+ instance_eval(&item[:authorize])
155
+ elsif item[:authorize_class] && item[:authorize_action]
156
+ Pundit.policy(current_user, item[:authorize_class]).public_send("#{item[:authorize_action]}?")
157
+ else
158
+ true
159
+ end
160
+ end
161
+
162
+ private
163
+
164
+ def extract_menu_items(items, extract_method)
165
+ items = items.map { |item| item.class == Class ? item.send(extract_method) : item }
166
+ end
167
+
168
+ def render_menu(items, options={})
169
+ return '' if items.empty?
170
+
171
+ output = ''
172
+ items = items.sort_by { |item| item[:order] }
173
+
174
+ items.each do |item|
175
+ next unless current_user_authorized_for_menu_item?(item)
176
+
177
+ if item[:list_items]&.any?
178
+ output += content_tag :li do
179
+ list = content_tag :ul do
180
+ list_items = item[:list_items].map do |list_item|
181
+ next unless current_user_authorized_for_menu_item?(list_item)
182
+
183
+ link_to list_item[:label], list_item[:url], wrapper: :li
184
+ end.join.html_safe
185
+ list_items.prepend(content_tag(:li, item[:label]))
186
+ end
187
+ list.prepend(link_to(item[:label], item[:url], icon: item[:icon]))
188
+ end
189
+ else
190
+ output += link_to item[:label], item[:url], wrapper: :li, icon: item[:icon]
191
+ end
192
+ end
193
+
194
+ output.html_safe
195
+ end
130
196
  end
131
197
  end
132
198
  end
@@ -1,6 +1,7 @@
1
1
  module Integral
2
2
  # All jobs inherit this behaviour
3
3
  class ApplicationJob < ActiveJob::Base
4
+ queue_as :default
4
5
  # Automatically retry jobs that encountered a deadlock
5
6
  # retry_on ActiveRecord::Deadlocked
6
7
 
@@ -1,8 +1,6 @@
1
1
  module Integral
2
2
  # Carry out actual newsletter signing up process
3
3
  class NewsletterSignupJob < ApplicationJob
4
- queue_as :default
5
-
6
4
  rescue_from(Gibbon::MailChimpError) do |e|
7
5
  error_msg = "NewsletterSignupJob - Error when signing visitor up to Newsletter: #{e.message}"
8
6
  Rails.logger.error(error_msg)