integral 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|