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.
- checksums.yaml +5 -5
- data/README.md +4 -3
- data/app/assets/javascripts/integral/backend.js +86 -2
- data/app/assets/javascripts/integral/support/character_counter.js +13 -8
- data/app/assets/javascripts/integral/support/list.coffee +1 -0
- data/app/assets/javascripts/integral/support/record_selector.coffee +2 -0
- data/app/assets/javascripts/integral/support/slug_generator.coffee +1 -0
- data/app/assets/stylesheets/integral/backend.sass +34 -23
- data/app/assets/stylesheets/integral/backend/_foundation_settings.scss +2 -2
- data/app/assets/stylesheets/integral/backend/dashboard-layout.scss +27 -63
- data/app/assets/stylesheets/integral/backend/devise.sass +2 -3
- data/app/assets/stylesheets/integral/backend/materialize-tags.sass +1 -0
- data/app/assets/stylesheets/integral/backend/modules/dropdown_pane_notifications.scss +150 -0
- data/app/assets/stylesheets/integral/backend/modules/dropdown_pane_profile.scss +59 -0
- data/app/assets/stylesheets/integral/backend/shared.sass +41 -2
- data/app/assets/stylesheets/integral/frontend/layout.sass +10 -0
- data/app/assets/stylesheets/integral/support/media-query-indicator.sass +4 -4
- data/app/controllers/integral/backend/activities_controller.rb +21 -27
- data/app/controllers/integral/backend/base_controller.rb +87 -37
- data/app/controllers/integral/backend/images_controller.rb +26 -8
- data/app/controllers/integral/backend/lists_controller.rb +2 -14
- data/app/controllers/integral/backend/notification_subscriptions_controller.rb +23 -0
- data/app/controllers/integral/backend/pages_controller.rb +0 -4
- data/app/controllers/integral/backend/posts_controller.rb +0 -4
- data/app/controllers/integral/backend/settings_controller.rb +4 -0
- data/app/controllers/integral/backend/static_pages_controller.rb +6 -0
- data/app/controllers/integral/backend/users_controller.rb +43 -24
- data/app/controllers/integral/blog_controller.rb +12 -0
- data/app/controllers/integral/categories_controller.rb +17 -3
- data/app/controllers/integral/tags_controller.rb +5 -2
- data/app/decorators/integral/base_decorator.rb +16 -0
- data/app/decorators/integral/image_decorator.rb +2 -2
- data/app/decorators/integral/list_decorator.rb +1 -13
- data/app/decorators/integral/notification/notification_decorator.rb +74 -0
- data/app/decorators/integral/page_decorator.rb +1 -13
- data/app/decorators/integral/post_decorator.rb +1 -2
- data/app/decorators/integral/user_decorator.rb +1 -13
- data/app/decorators/integral/version_decorator.rb +8 -4
- data/app/helpers/integral/backend/base_helper.rb +97 -31
- data/app/jobs/integral/application_job.rb +1 -0
- data/app/jobs/integral/newsletter_signup_job.rb +0 -2
- data/app/mailers/integral/devise_mailer.rb +6 -0
- data/app/models/concerns/integral/notification/subscribable.rb +67 -0
- data/app/models/integral/application_record.rb +9 -0
- data/app/models/integral/category.rb +9 -0
- data/app/models/integral/image.rb +40 -3
- data/app/models/integral/list.rb +10 -2
- data/app/models/integral/list_item.rb +14 -14
- data/app/models/integral/list_item_connection.rb +6 -0
- data/app/models/integral/notification/notification.rb +28 -0
- data/app/models/integral/notification/subscription.rb +14 -0
- data/app/models/integral/page.rb +15 -8
- data/app/models/integral/post.rb +11 -13
- data/app/models/integral/user.rb +45 -2
- data/app/policies/integral/base_policy.rb +7 -12
- data/app/policies/integral/page_policy.rb +1 -0
- data/app/policies/integral/version_policy.rb +0 -8
- data/app/views/devise/invitations/edit.haml +1 -4
- data/app/views/devise/mailer/invitation_instructions.inky-haml +20 -0
- data/app/views/integral/backend/activities/grid/_dropdown_actions.haml +1 -0
- data/app/views/integral/backend/activities/grid/_row_content.haml +13 -0
- data/app/views/integral/backend/activities/index.haml +7 -13
- data/app/views/integral/backend/activities/shared/_grid.haml +35 -20
- data/app/views/integral/backend/activities/shared/index.haml +12 -12
- data/app/views/integral/backend/activities/shared/show.haml +7 -7
- data/app/views/integral/backend/activities/show.haml +1 -1
- data/app/views/integral/backend/categories/_modal.haml +2 -3
- data/app/views/integral/backend/images/_form.haml +13 -25
- data/app/views/integral/backend/images/edit.haml +1 -9
- data/app/views/integral/backend/images/grid/_dropdown_actions.haml +5 -0
- data/app/views/integral/backend/images/grid/_row_content.haml +5 -0
- data/app/views/integral/backend/images/index.haml +11 -17
- data/app/views/integral/backend/images/list.haml +11 -0
- data/app/views/integral/backend/images/show.haml +26 -0
- data/app/views/integral/backend/lists/_form.haml +6 -19
- data/app/views/integral/backend/lists/_item_modal.haml +3 -3
- data/app/views/integral/backend/lists/_manager.haml +11 -13
- data/app/views/integral/backend/lists/edit.haml +6 -20
- data/app/views/integral/backend/lists/grid/_dropdown_actions.haml +9 -0
- data/app/views/integral/backend/lists/grid/_row_content.haml +3 -0
- data/app/views/integral/backend/lists/index.haml +11 -17
- data/app/views/integral/backend/lists/list.haml +11 -0
- data/app/views/integral/backend/lists/show.haml +30 -0
- data/app/views/integral/backend/notifications/_notification.haml +21 -0
- data/app/views/integral/backend/pages/_form.haml +19 -43
- data/app/views/integral/backend/pages/edit.haml +4 -12
- data/app/views/integral/backend/pages/grid/_dropdown_actions.haml +11 -0
- data/app/views/integral/backend/pages/grid/_row_content.haml +5 -0
- data/app/views/integral/backend/pages/index.haml +6 -6
- data/app/views/integral/backend/pages/list.haml +12 -19
- data/app/views/integral/backend/pages/show.haml +19 -35
- data/app/views/integral/backend/posts/_form.haml +18 -56
- data/app/views/integral/backend/posts/edit.haml +4 -14
- data/app/views/integral/backend/posts/grid/_dropdown_actions.haml +10 -0
- data/app/views/integral/backend/posts/grid/_row_content.haml +6 -0
- data/app/views/integral/backend/posts/index.haml +6 -6
- data/app/views/integral/backend/posts/list.haml +11 -18
- data/app/views/integral/backend/posts/new.haml +0 -1
- data/app/views/integral/backend/posts/show.haml +18 -41
- data/app/views/integral/backend/shared/_breadcrumbs.haml +7 -4
- data/app/views/integral/backend/shared/_image_preview.haml +10 -3
- data/app/views/integral/backend/shared/_image_selector.haml +1 -1
- data/app/views/integral/backend/shared/_notification_subscription_toggle.haml +22 -0
- data/app/views/integral/backend/shared/action_bar/_index.haml +9 -0
- data/app/views/integral/backend/shared/action_bar/_show.haml +3 -0
- data/app/views/integral/backend/shared/cards/_at_a_glance.haml +3 -3
- data/app/views/integral/backend/shared/cards/_categories.haml +27 -28
- data/app/views/integral/backend/shared/cards/_object.haml +1 -1
- data/app/views/integral/backend/shared/cards/_recent_activity.haml +12 -12
- data/app/views/integral/backend/shared/cards/_recent_resources.haml +17 -0
- data/app/views/integral/backend/shared/cards/_top_post_authors.haml +14 -15
- data/app/views/integral/backend/shared/cards/_welcome.haml +24 -25
- data/app/views/integral/backend/shared/{_empty_grid.haml → grid/_empty.haml} +0 -0
- data/app/views/integral/backend/shared/grid/_form.haml +9 -0
- data/app/views/integral/backend/shared/grid/_grid.haml +21 -0
- data/app/views/integral/backend/shared/{_pagination.haml → grid/_pagination.haml} +0 -0
- data/app/views/integral/backend/shared/grid/_row_layout.haml +8 -0
- data/app/views/integral/backend/shared/record_selector/_collection.haml +1 -0
- data/app/views/integral/backend/shared/record_selector/_modal.haml +9 -10
- data/app/views/integral/backend/static_pages/dashboard.haml +6 -7
- data/app/views/integral/backend/users/_form.haml +34 -46
- data/app/views/integral/backend/users/grid/_dropdown_actions.haml +17 -0
- data/app/views/integral/backend/users/grid/_row_content.haml +8 -0
- data/app/views/integral/backend/users/index.haml +6 -6
- data/app/views/integral/backend/users/list.haml +10 -16
- data/app/views/integral/backend/users/show.haml +10 -1
- data/app/views/integral/categories/show.haml +3 -3
- data/app/views/integral/posts/_article_footer.haml +1 -1
- data/app/views/integral/posts/_card.haml +1 -1
- data/app/views/integral/posts/_most_read_section.haml +1 -1
- data/app/views/integral/posts/_post.haml +1 -1
- data/app/views/integral/posts/templates/default.haml +1 -1
- data/app/views/integral/shared/sidebar/_item.haml +1 -1
- data/app/views/layouts/integral/backend.html.haml +24 -5
- data/app/views/layouts/integral/backend/_create_dropdown.haml +1 -30
- data/app/views/layouts/integral/backend/_main_menu_items.haml +1 -101
- data/config/initializers/devise.rb +1 -1
- data/config/locales/en.yml +60 -2
- data/config/routes.rb +2 -0
- data/db/migrate/20200407022636_create_integral_notifications.rb +25 -0
- data/db/migrate/20200421223602_add_status_to_integral_users.rb +5 -0
- data/db/seeds.rb +15 -11
- data/lib/integral.rb +1 -0
- data/lib/integral/acts_as_integral.rb +115 -0
- data/lib/integral/acts_as_listable.rb +1 -1
- data/lib/integral/engine.rb +9 -0
- data/lib/integral/grids/activities_grid.rb +0 -1
- data/lib/integral/grids/lists_grid.rb +1 -0
- data/lib/integral/grids/posts_grid.rb +5 -1
- data/lib/integral/grids/users_grid.rb +5 -0
- data/lib/integral/list_renderer.rb +5 -1
- data/lib/integral/router.rb +20 -4
- data/lib/integral/version.rb +1 -1
- data/spec/factories.rb +15 -1
- metadata +45 -39
- data/app/decorators/integral/category_version_decorator.rb +0 -7
- data/app/decorators/integral/image_version_decorator.rb +0 -7
- data/app/decorators/integral/list_version_decorator.rb +0 -7
- data/app/decorators/integral/page_version_decorator.rb +0 -7
- data/app/decorators/integral/post_version_decorator.rb +0 -7
- data/app/decorators/integral/user_version_decorator.rb +0 -7
- data/app/views/devise/mailer/invitation_instructions.html.erb +0 -13
- data/app/views/integral/backend/activities/_grid.haml +0 -22
- data/app/views/integral/backend/images/_grid.haml +0 -16
- data/app/views/integral/backend/lists/_grid.haml +0 -14
- data/app/views/integral/backend/pages/_grid.haml +0 -46
- data/app/views/integral/backend/posts/_grid.haml +0 -51
- data/app/views/integral/backend/shared/_grid.haml +0 -18
- data/app/views/integral/backend/shared/cards/_recent_pages.haml +0 -19
- data/app/views/integral/backend/shared/cards/_recent_posts.haml +0 -18
- data/app/views/integral/backend/shared/cards/_recent_users.haml +0 -19
- data/app/views/integral/backend/users/_grid.haml +0 -36
|
@@ -1,101 +1 @@
|
|
|
1
|
-
|
|
2
|
-
= link_to backend_dashboard_url do
|
|
3
|
-
= icon('home')
|
|
4
|
-
%span= t('integral.navigation.dashboard')
|
|
5
|
-
|
|
6
|
-
- if policy(Integral::Page).index?
|
|
7
|
-
%li
|
|
8
|
-
= link_to backend_pages_url do
|
|
9
|
-
= icon('file')
|
|
10
|
-
%span= t('integral.navigation.pages')
|
|
11
|
-
%ul
|
|
12
|
-
%li= t('integral.navigation.pages')
|
|
13
|
-
%li
|
|
14
|
-
= link_to backend_pages_url do
|
|
15
|
-
%span= t('integral.navigation.dashboard')
|
|
16
|
-
|
|
17
|
-
- if policy(Integral::Page).create?
|
|
18
|
-
%li
|
|
19
|
-
= link_to new_backend_page_url do
|
|
20
|
-
%span= t('integral.actions.create')
|
|
21
|
-
%li
|
|
22
|
-
= link_to list_backend_pages_url do
|
|
23
|
-
%span= t('integral.navigation.listing')
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- if policy(Integral::Post).index? && Integral.blog_enabled?
|
|
27
|
-
%li
|
|
28
|
-
= link_to backend_posts_url do
|
|
29
|
-
= icon('rss')
|
|
30
|
-
%span= t('integral.navigation.posts')
|
|
31
|
-
%ul
|
|
32
|
-
%li= t('integral.navigation.posts')
|
|
33
|
-
%li
|
|
34
|
-
= link_to backend_posts_url do
|
|
35
|
-
%span= t('integral.navigation.dashboard')
|
|
36
|
-
- if policy(Integral::Post).create?
|
|
37
|
-
%li
|
|
38
|
-
= link_to new_backend_post_url do
|
|
39
|
-
%span= t('integral.actions.create')
|
|
40
|
-
%li
|
|
41
|
-
= link_to list_backend_posts_url do
|
|
42
|
-
%span= t('integral.navigation.listing')
|
|
43
|
-
|
|
44
|
-
- if policy(Integral::List).index?
|
|
45
|
-
%li
|
|
46
|
-
= link_to backend_lists_url do
|
|
47
|
-
= icon('list')
|
|
48
|
-
%span= t('integral.navigation.lists')
|
|
49
|
-
%ul
|
|
50
|
-
%li= t('integral.navigation.lists')
|
|
51
|
-
%li
|
|
52
|
-
= link_to backend_lists_url do
|
|
53
|
-
%span= t('integral.navigation.dashboard')
|
|
54
|
-
- if policy(Integral::List).create?
|
|
55
|
-
%li
|
|
56
|
-
= link_to new_backend_list_url do
|
|
57
|
-
%span= t('integral.actions.create')
|
|
58
|
-
|
|
59
|
-
- if policy(Integral::Image).manager?
|
|
60
|
-
%li
|
|
61
|
-
= link_to backend_img_index_url do
|
|
62
|
-
= icon('picture-o')
|
|
63
|
-
%span= t('integral.navigation.images')
|
|
64
|
-
%ul
|
|
65
|
-
%li= t('integral.navigation.images')
|
|
66
|
-
%li
|
|
67
|
-
= link_to backend_img_index_url do
|
|
68
|
-
%span= t('integral.navigation.dashboard')
|
|
69
|
-
- if policy(Integral::Image).create?
|
|
70
|
-
%li
|
|
71
|
-
= link_to new_backend_img_url do
|
|
72
|
-
%span= t('integral.actions.create')
|
|
73
|
-
|
|
74
|
-
- if policy(current_user).manager?
|
|
75
|
-
%li
|
|
76
|
-
= link_to backend_users_url do
|
|
77
|
-
= icon('users')
|
|
78
|
-
%span=t('integral.navigation.users')
|
|
79
|
-
%ul
|
|
80
|
-
%li= t('integral.navigation.users')
|
|
81
|
-
%li
|
|
82
|
-
= link_to backend_users_url do
|
|
83
|
-
%span= t('integral.navigation.dashboard')
|
|
84
|
-
%li
|
|
85
|
-
= link_to new_backend_user_url do
|
|
86
|
-
%span= t('integral.actions.create')
|
|
87
|
-
%li
|
|
88
|
-
= link_to list_backend_users_url do
|
|
89
|
-
%span= t('integral.navigation.listing')
|
|
90
|
-
|
|
91
|
-
- if policy(Integral::Version).manager?
|
|
92
|
-
%li
|
|
93
|
-
= link_to backend_activities_url do
|
|
94
|
-
= icon('crosshairs')
|
|
95
|
-
%span=t('integral.navigation.activities')
|
|
96
|
-
|
|
97
|
-
- if current_user.admin?
|
|
98
|
-
%li
|
|
99
|
-
= link_to backend_settings_url do
|
|
100
|
-
= icon('cog')
|
|
101
|
-
%span=t('integral.navigation.settings')
|
|
1
|
+
= render_main_menu
|
|
@@ -13,7 +13,7 @@ Devise.setup do |config|
|
|
|
13
13
|
config.mailer_sender = Proc.new { "#{Integral::Settings.website_title} <#{Integral::Settings.contact_email}>" }
|
|
14
14
|
|
|
15
15
|
# Configure the class responsible to send e-mails.
|
|
16
|
-
|
|
16
|
+
config.mailer = 'Integral::DeviseMailer'
|
|
17
17
|
|
|
18
18
|
# ==> ORM configuration
|
|
19
19
|
# Load and configure the ORM. Supports :active_record (default) and
|
data/config/locales/en.yml
CHANGED
|
@@ -15,6 +15,44 @@ en:
|
|
|
15
15
|
default: "%A, %d %B %Y"
|
|
16
16
|
long: "%H:%M %d/%m/%Y"
|
|
17
17
|
|
|
18
|
+
datetime:
|
|
19
|
+
distance_in_words:
|
|
20
|
+
short:
|
|
21
|
+
half_a_minute: "30s"
|
|
22
|
+
less_than_x_seconds:
|
|
23
|
+
one: "1s"
|
|
24
|
+
other: "%{count}s"
|
|
25
|
+
x_seconds:
|
|
26
|
+
one: "1s"
|
|
27
|
+
other: "%{count}s"
|
|
28
|
+
less_than_x_minutes:
|
|
29
|
+
one: "~1m"
|
|
30
|
+
other: "~%{count}m"
|
|
31
|
+
x_minutes:
|
|
32
|
+
one: "1m"
|
|
33
|
+
other: "%{count}m"
|
|
34
|
+
about_x_hours:
|
|
35
|
+
one: "~1h"
|
|
36
|
+
other: "~%{count}h "
|
|
37
|
+
x_days:
|
|
38
|
+
one: "1d"
|
|
39
|
+
other: "%{count}d"
|
|
40
|
+
about_x_months:
|
|
41
|
+
one: "~1mn"
|
|
42
|
+
other: "~%{count}mn"
|
|
43
|
+
x_months:
|
|
44
|
+
one: "1mn"
|
|
45
|
+
other: "%{count}mn"
|
|
46
|
+
about_x_years:
|
|
47
|
+
one: "~1y"
|
|
48
|
+
other: "~%{count}y"
|
|
49
|
+
over_x_years:
|
|
50
|
+
one: "1y"
|
|
51
|
+
other: "%{count}y"
|
|
52
|
+
almost_x_years:
|
|
53
|
+
one: "~1y"
|
|
54
|
+
other: "~%{count}y"
|
|
55
|
+
|
|
18
56
|
errors:
|
|
19
57
|
generic: Unfortunately there was a problem. Please try again later.
|
|
20
58
|
unauthorized: You are not authorized to perform this action.
|
|
@@ -55,6 +93,8 @@ en:
|
|
|
55
93
|
confirmation:
|
|
56
94
|
deletion: If you delete this item it will be gone forever. Are you sure you want to proceed?
|
|
57
95
|
clone: Are you sure you want to clone this item?
|
|
96
|
+
block: Are you sure you want to block this user?
|
|
97
|
+
unblock: Are you sure you want to unblock this user?
|
|
58
98
|
new_page: Add new page
|
|
59
99
|
new_post: Add new post
|
|
60
100
|
edit_profile: Edit profile
|
|
@@ -63,6 +103,8 @@ en:
|
|
|
63
103
|
view_main_site: View main site
|
|
64
104
|
view_on_site: View on site
|
|
65
105
|
publish: Publish
|
|
106
|
+
block: Block
|
|
107
|
+
unblock: Unblock
|
|
66
108
|
create: Create
|
|
67
109
|
clone: Clone
|
|
68
110
|
save: Save
|
|
@@ -95,6 +137,9 @@ en:
|
|
|
95
137
|
select_image: Select Image..
|
|
96
138
|
select_type: Select Type..
|
|
97
139
|
unsaved_changes: Changes that you made may not be saved.
|
|
140
|
+
tooltips:
|
|
141
|
+
unsubscribe: Unsubscribe from notifications.
|
|
142
|
+
subscribe: Subscribe to notifications.
|
|
98
143
|
placeholders:
|
|
99
144
|
description: Description
|
|
100
145
|
title: Title
|
|
@@ -102,6 +147,9 @@ en:
|
|
|
102
147
|
draft: Draft
|
|
103
148
|
published: Published
|
|
104
149
|
archived: Archived
|
|
150
|
+
blocked: Blocked
|
|
151
|
+
pending: Pending
|
|
152
|
+
active: Active
|
|
105
153
|
records:
|
|
106
154
|
attributes:
|
|
107
155
|
category: Category
|
|
@@ -143,7 +191,7 @@ en:
|
|
|
143
191
|
actions: Actions
|
|
144
192
|
activity: Activity
|
|
145
193
|
activity_log: Activity Log
|
|
146
|
-
profile: My
|
|
194
|
+
profile: My profile
|
|
147
195
|
quick_links: Quick Links
|
|
148
196
|
activities: Activities
|
|
149
197
|
home: Home
|
|
@@ -161,7 +209,7 @@ en:
|
|
|
161
209
|
new: New
|
|
162
210
|
edit: Edit
|
|
163
211
|
log_out: Logout
|
|
164
|
-
my_account: Account &
|
|
212
|
+
my_account: Account & profile
|
|
165
213
|
settings: Settings
|
|
166
214
|
listing: Listing
|
|
167
215
|
|
|
@@ -368,6 +416,8 @@ en:
|
|
|
368
416
|
title: 'Image listing'
|
|
369
417
|
no_images_available: 'No images available. Try uploading some!'
|
|
370
418
|
new_image: 'New image'
|
|
419
|
+
edit:
|
|
420
|
+
title: Edit Image
|
|
371
421
|
users:
|
|
372
422
|
available_locales:
|
|
373
423
|
en: English
|
|
@@ -424,6 +474,8 @@ en:
|
|
|
424
474
|
list:
|
|
425
475
|
title: This is only used for internal reference.
|
|
426
476
|
description: This is only used for internal reference.
|
|
477
|
+
user:
|
|
478
|
+
notify_me: Subscribe to be notified whenever there is a change to any resource. Otherwise be notified about followed resources only.
|
|
427
479
|
inputs:
|
|
428
480
|
file:
|
|
429
481
|
button_label: 'File'
|
|
@@ -473,6 +525,12 @@ en:
|
|
|
473
525
|
create: 'Invite %{model}'
|
|
474
526
|
|
|
475
527
|
devise:
|
|
528
|
+
invitations:
|
|
529
|
+
edit:
|
|
530
|
+
title: Set your password
|
|
531
|
+
failure:
|
|
532
|
+
user:
|
|
533
|
+
blocked: User account is no longer active.
|
|
476
534
|
passwords:
|
|
477
535
|
edit:
|
|
478
536
|
title: Change your password
|
data/config/routes.rb
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class CreateIntegralNotifications < ActiveRecord::Migration[5.2]
|
|
2
|
+
def change
|
|
3
|
+
add_column :integral_users, :notify_me, :boolean, default: true
|
|
4
|
+
|
|
5
|
+
create_table :integral_notifications do |t|
|
|
6
|
+
t.integer :recipient_id
|
|
7
|
+
t.integer :actor_id
|
|
8
|
+
t.datetime :read_at
|
|
9
|
+
t.string :action
|
|
10
|
+
# (automated index name is too long)
|
|
11
|
+
t.references :subscribable, polymorphic: true, index: { name: 'index_integral_notifications_on_subscribable_type_id' }
|
|
12
|
+
|
|
13
|
+
t.timestamps null: false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
create_table :integral_notification_subscriptions do |t|
|
|
17
|
+
t.integer :user_id
|
|
18
|
+
t.string :state
|
|
19
|
+
# (automated index name is too long)
|
|
20
|
+
t.references :subscribable, polymorphic: true, index: { name: 'index_integral_subscriptions_on_subscribable_type_id' }
|
|
21
|
+
|
|
22
|
+
t.timestamps null: false
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/db/seeds.rb
CHANGED
|
@@ -18,7 +18,9 @@ Integral::Role.create!(name: 'PostManager')
|
|
|
18
18
|
Integral::Role.create!(name: 'ListManager')
|
|
19
19
|
|
|
20
20
|
# Demo User
|
|
21
|
-
user = Integral::User.create!({ name: 'Integrico', email: 'user@integralrails.com', password: 'password', role_ids: Integral::Role.ids, admin: true })
|
|
21
|
+
user = Integral::User.create!({ name: 'Integrico', email: 'user@integralrails.com', password: 'password', role_ids: Integral::Role.ids, admin: true, status: 1 })
|
|
22
|
+
|
|
23
|
+
return if Rails.env.test? # Test DB should start with blank slate ... although roles and initial user are required
|
|
22
24
|
|
|
23
25
|
# Demo Page
|
|
24
26
|
host = URI.parse(Rails.application.routes.default_url_options[:host] || 'http://localhost:3000')
|
|
@@ -33,16 +35,18 @@ Integral::Page.create!(title: 'Integral CMS - Demo Page',
|
|
|
33
35
|
body: renderer.render('integral/pages/_demo', layout: false),
|
|
34
36
|
status: 1)
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Integral::
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
if Integral.blog_enabled?
|
|
39
|
+
# Demo Post
|
|
40
|
+
category = Integral::Category.create!(title: 'Uncategorised', description: "Posts which we haven't yet categorized but are sure to grab your attention", slug: 'uncategorized')
|
|
41
|
+
Integral::Post.create!(title: 'Integral CMS - Demo Post',
|
|
42
|
+
description:'Integral CMS demo post. Integral is a rails content management system (CMS) which gives developers the ability to create a modern website with all the bells and whistles without the hassle.',
|
|
43
|
+
body: File.read(File.join(Integral::Engine.root.join('public', 'integral', 'ckeditor_demo_content.html'))),
|
|
44
|
+
slug: 'integral-demo',
|
|
45
|
+
user: user,
|
|
46
|
+
tag_list: 'integral-cms,example-tag',
|
|
47
|
+
status: 1,
|
|
48
|
+
category: category)
|
|
49
|
+
end
|
|
46
50
|
|
|
47
51
|
# Main Menu
|
|
48
52
|
Integral::List.create!({ title: 'Main Menu', list_items: [
|
data/lib/integral.rb
CHANGED
|
@@ -15,6 +15,7 @@ require 'integral/grids/lists_grid'
|
|
|
15
15
|
require 'integral/grids/posts_grid'
|
|
16
16
|
require 'integral/grids/images_grid'
|
|
17
17
|
require 'integral/acts_as_listable'
|
|
18
|
+
require 'integral/acts_as_integral'
|
|
18
19
|
require 'integral/widgets/recent_posts'
|
|
19
20
|
require 'integral/widgets/swiper_list'
|
|
20
21
|
require 'integral/content_renderer'
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
module Integral
|
|
2
|
+
# Handles adding Integral behaviour to a class
|
|
3
|
+
module ActsAsIntegral
|
|
4
|
+
DEFAULT_OPTIONS ={ notifications: { enabled: true },
|
|
5
|
+
cards: { at_a_glance: true, },
|
|
6
|
+
backend_main_menu: { enabled: true, order: 11 },
|
|
7
|
+
backend_create_menu: { enabled: true, order: 1 }}.freeze
|
|
8
|
+
class << self
|
|
9
|
+
attr_writer :backend_main_menu_items
|
|
10
|
+
attr_writer :backend_create_menu_items
|
|
11
|
+
attr_writer :backend_at_a_glance_card_items
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Accessor for backend main menu items
|
|
15
|
+
def self.backend_main_menu_items
|
|
16
|
+
@backend_main_menu_items ||= []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Accessor for backend create menu items
|
|
20
|
+
def self.backend_create_menu_items
|
|
21
|
+
@backend_create_menu_items ||= []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Accessor for at a glance card items
|
|
25
|
+
def self.backend_at_a_glance_card_items
|
|
26
|
+
@backend_at_a_glance_card_items ||= []
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Adds item to main backend dashboard at a glance chart
|
|
30
|
+
# @param [Class] item
|
|
31
|
+
def self.add_backend_at_a_glance_card_item(item)
|
|
32
|
+
backend_at_a_glance_card_items << item unless duplicate_menu_item?(item, backend_at_a_glance_card_items)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Adds item to create menu, expects Hash or Class
|
|
36
|
+
def self.add_backend_create_menu_item(item)
|
|
37
|
+
backend_create_menu_items << item unless duplicate_menu_item?(item, backend_create_menu_items)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Adds item to main menu, expects Hash or Class
|
|
41
|
+
def self.add_backend_main_menu_item(item)
|
|
42
|
+
backend_main_menu_items << item unless duplicate_menu_item?(item, backend_main_menu_items)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Checks for existing duplicates in menu. Useful in development when app reloads
|
|
46
|
+
def self.duplicate_menu_item?(item, menu)
|
|
47
|
+
duplicate_found = if item.class == Class
|
|
48
|
+
menu.map(&:to_s).include?(item.to_s)
|
|
49
|
+
else
|
|
50
|
+
menu.select { |item| item.is_a?(Hash) }.map {|item| item[:id] }.include?(item[:id])
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if duplicate_found
|
|
54
|
+
Rails.logger.error("ActsAsIntegral: Item '#{item.to_s}' not added to menu as it already exists.")
|
|
55
|
+
true
|
|
56
|
+
else
|
|
57
|
+
false
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
ActiveSupport.on_load(:active_record) do
|
|
62
|
+
# ActiveRecord::Base extension
|
|
63
|
+
class ActiveRecord::Base
|
|
64
|
+
# Adds integral behaviour to models
|
|
65
|
+
def self.acts_as_integral(options = {})
|
|
66
|
+
class << self
|
|
67
|
+
attr_accessor :integral_options
|
|
68
|
+
|
|
69
|
+
# @return [Hash] hash representing the class, used to render within the main menu
|
|
70
|
+
def integral_backend_main_menu_item
|
|
71
|
+
{
|
|
72
|
+
icon: integral_icon,
|
|
73
|
+
order: integral_options.dig(:backend_main_menu, :order),
|
|
74
|
+
label: model_name.human.pluralize,
|
|
75
|
+
url: url_helpers.send("backend_#{model_name.route_key}_url"),
|
|
76
|
+
# authorize: proc { policy(self).index? }, can't use this as self is in wrong context
|
|
77
|
+
authorize_class: self,
|
|
78
|
+
authorize_action: :index,
|
|
79
|
+
list_items: [
|
|
80
|
+
{ label: I18n.t('integral.navigation.dashboard'), url: url_helpers.send("backend_#{model_name.route_key}_url"), authorize_class: self, authorize_action: :index },
|
|
81
|
+
{ label: I18n.t('integral.actions.create'), url: url_helpers.send("new_backend_#{model_name.singular_route_key}_url"), authorize_class: self, authorize_action: :new },
|
|
82
|
+
{ label: I18n.t('integral.navigation.listing'), url: url_helpers.send("list_backend_#{model_name.route_key}_url"), authorize_class: self, authorize_action: :list },
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# @return [Hash] hash representing the class, used to render within the create menu
|
|
88
|
+
def integral_backend_create_menu_item
|
|
89
|
+
{
|
|
90
|
+
icon: integral_icon,
|
|
91
|
+
order: integral_options.dig(:backend_create_menu, :order),
|
|
92
|
+
label: model_name.human,
|
|
93
|
+
url: url_helpers.send("new_backend_#{model_name.singular_route_key}_url"),
|
|
94
|
+
# authorize: proc { policy(self).index? }, can't use this as self is in wrong context
|
|
95
|
+
authorize_class: self,
|
|
96
|
+
authorize_action: :new,
|
|
97
|
+
}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def url_helpers
|
|
101
|
+
Integral::Engine.routes.url_helpers
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
self.integral_options = Integral::ActsAsIntegral::DEFAULT_OPTIONS.deep_merge(options)
|
|
106
|
+
Integral::ActsAsIntegral.add_backend_create_menu_item(self) if integral_options.dig(:backend_create_menu, :enabled)
|
|
107
|
+
Integral::ActsAsIntegral.add_backend_main_menu_item(self) if integral_options.dig(:backend_main_menu, :enabled)
|
|
108
|
+
Integral::ActsAsIntegral.add_backend_at_a_glance_card_item(self) if integral_options.dig(:cards, :at_a_glance)
|
|
109
|
+
|
|
110
|
+
include Integral::Notification::Subscribable if integral_options.dig(:notifications, :enabled)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -16,7 +16,7 @@ module Integral
|
|
|
16
16
|
class ActiveRecord::Base
|
|
17
17
|
# Adds listable behaviour to objects
|
|
18
18
|
def self.acts_as_listable(_options = {})
|
|
19
|
-
Integral::ActsAsListable.objects << self
|
|
19
|
+
Integral::ActsAsListable.objects << self unless Integral::ActsAsListable.objects.map(&:name).include?(self.name)
|
|
20
20
|
|
|
21
21
|
# @return [Hash] instance as a list item
|
|
22
22
|
# Keys include: id, title, subtitle, image, description, url
|