lesli_bell 0.1.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 +7 -0
- data/Rakefile +5 -0
- data/app/assets/config/lesli_bell_manifest.js +40 -0
- data/app/assets/javascripts/lesli_bell/application.js +2848 -0
- data/app/assets/stylesheets/lesli_bell/application.css +15 -0
- data/app/controllers/lesli_bell/accounts_controller.rb +4 -0
- data/app/controllers/lesli_bell/announcements_controller.rb +60 -0
- data/app/controllers/lesli_bell/application_controller.rb +4 -0
- data/app/controllers/lesli_bell/dashboards_controller.rb +59 -0
- data/app/controllers/lesli_bell/notifications_controller.rb +60 -0
- data/app/helpers/lesli_bell/accounts_helper.rb +4 -0
- data/app/helpers/lesli_bell/announcements_helper.rb +4 -0
- data/app/helpers/lesli_bell/application_helper.rb +4 -0
- data/app/helpers/lesli_bell/dashboards_helper.rb +4 -0
- data/app/helpers/lesli_bell/notifications_helper.rb +4 -0
- data/app/jobs/lesli_bell/application_job.rb +4 -0
- data/app/mailers/lesli_bell/application_mailer.rb +6 -0
- data/app/models/lesli_bell/account.rb +7 -0
- data/app/models/lesli_bell/announcement.rb +4 -0
- data/app/models/lesli_bell/application_record.rb +5 -0
- data/app/models/lesli_bell/dashboard.rb +4 -0
- data/app/models/lesli_bell/notification.rb +28 -0
- data/app/services/lesli_bell/notification_service.rb +87 -0
- data/app/views/lesli_bell/accounts/_account.html.erb +2 -0
- data/app/views/lesli_bell/accounts/_form.html.erb +17 -0
- data/app/views/lesli_bell/accounts/edit.html.erb +10 -0
- data/app/views/lesli_bell/accounts/index.html.erb +14 -0
- data/app/views/lesli_bell/accounts/new.html.erb +9 -0
- data/app/views/lesli_bell/accounts/show.html.erb +10 -0
- data/app/views/lesli_bell/announcements/_announcement.html.erb +2 -0
- data/app/views/lesli_bell/announcements/_form.html.erb +17 -0
- data/app/views/lesli_bell/announcements/edit.html.erb +10 -0
- data/app/views/lesli_bell/announcements/index.html.erb +14 -0
- data/app/views/lesli_bell/announcements/new.html.erb +9 -0
- data/app/views/lesli_bell/announcements/show.html.erb +10 -0
- data/app/views/lesli_bell/dashboards/_dashboard.html.erb +2 -0
- data/app/views/lesli_bell/dashboards/_form.html.erb +17 -0
- data/app/views/lesli_bell/dashboards/edit.html.erb +10 -0
- data/app/views/lesli_bell/dashboards/index.html.erb +14 -0
- data/app/views/lesli_bell/dashboards/new.html.erb +9 -0
- data/app/views/lesli_bell/dashboards/show.html.erb +1 -0
- data/app/views/lesli_bell/notifications/edit.html.erb +10 -0
- data/app/views/lesli_bell/notifications/index.html.erb +33 -0
- data/app/views/lesli_bell/notifications/new.html.erb +9 -0
- data/app/views/lesli_bell/notifications/show.html.erb +10 -0
- data/app/views/lesli_bell/partials/_engine-navigation.html.erb +24 -0
- data/config/routes.rb +6 -0
- data/db/migrate/v1.0/0308000110_create_lesli_bell_accounts.rb +28 -0
- data/db/migrate/v1.0/0308100110_create_lesli_bell_notifications.rb +41 -0
- data/db/migrate/v1.0/0308100210_create_lesli_bell_notification_activities.rb +17 -0
- data/db/migrate/v1.0/0308110110_create_lesli_bell_announcements.rb +40 -0
- data/db/migrate/v1.0/0308110210_create_lesli_bell_announcement_activities.rb +17 -0
- data/db/migrate/v1.0/0308110310_create_lesli_bell_announcement_users.rb +12 -0
- data/db/seed/development.rb +36 -0
- data/db/seed/production.rb +0 -0
- data/db/seed/test.rb +0 -0
- data/db/seeds.rb +25 -0
- data/lib/lesli_bell/engine.rb +18 -0
- data/lib/lesli_bell/version.rb +4 -0
- data/lib/lesli_bell.rb +6 -0
- data/lib/tasks/lesli_bell_tasks.rake +4 -0
- data/lib/vue/application.js +51 -0
- data/lib/vue/apps/announcements/components/form.vue +237 -0
- data/lib/vue/apps/announcements/index.vue +124 -0
- data/lib/vue/apps/announcements/new.vue +48 -0
- data/lib/vue/apps/notifications/components/notification-form.vue +149 -0
- data/lib/vue/apps/notifications/index.vue +129 -0
- data/lib/vue/apps/notifications/new.vue +45 -0
- data/lib/vue/stores/announcement.js +142 -0
- data/lib/vue/stores/notification.js +115 -0
- data/readme.md +28 -0
- metadata +116 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module LesliBell
|
2
|
+
class AnnouncementsController < ApplicationController
|
3
|
+
before_action :set_announcement, only: %i[ show edit update destroy ]
|
4
|
+
|
5
|
+
# GET /announcements
|
6
|
+
def index
|
7
|
+
@announcements = Announcement.all
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /announcements/1
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /announcements/new
|
15
|
+
def new
|
16
|
+
@announcement = Announcement.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /announcements/1/edit
|
20
|
+
def edit
|
21
|
+
end
|
22
|
+
|
23
|
+
# POST /announcements
|
24
|
+
def create
|
25
|
+
@announcement = Announcement.new(announcement_params)
|
26
|
+
|
27
|
+
if @announcement.save
|
28
|
+
redirect_to @announcement, notice: "Announcement was successfully created."
|
29
|
+
else
|
30
|
+
render :new, status: :unprocessable_entity
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# PATCH/PUT /announcements/1
|
35
|
+
def update
|
36
|
+
if @announcement.update(announcement_params)
|
37
|
+
redirect_to @announcement, notice: "Announcement was successfully updated.", status: :see_other
|
38
|
+
else
|
39
|
+
render :edit, status: :unprocessable_entity
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# DELETE /announcements/1
|
44
|
+
def destroy
|
45
|
+
@announcement.destroy
|
46
|
+
redirect_to announcements_url, notice: "Announcement was successfully destroyed.", status: :see_other
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
# Use callbacks to share common setup or constraints between actions.
|
51
|
+
def set_announcement
|
52
|
+
@announcement = Announcement.find(params[:id])
|
53
|
+
end
|
54
|
+
|
55
|
+
# Only allow a list of trusted parameters through.
|
56
|
+
def announcement_params
|
57
|
+
params.fetch(:announcement, {})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module LesliBell
|
2
|
+
class DashboardsController < ApplicationController
|
3
|
+
#before_action :set_dashboard, only: %i[ show edit update destroy ]
|
4
|
+
|
5
|
+
# GET /dashboards
|
6
|
+
def index
|
7
|
+
end
|
8
|
+
|
9
|
+
# GET /dashboards/1
|
10
|
+
def show
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /dashboards/new
|
14
|
+
def new
|
15
|
+
@dashboard = Dashboard.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# GET /dashboards/1/edit
|
19
|
+
def edit
|
20
|
+
end
|
21
|
+
|
22
|
+
# POST /dashboards
|
23
|
+
def create
|
24
|
+
@dashboard = Dashboard.new(dashboard_params)
|
25
|
+
|
26
|
+
if @dashboard.save
|
27
|
+
redirect_to @dashboard, notice: "Dashboard was successfully created."
|
28
|
+
else
|
29
|
+
render :new, status: :unprocessable_entity
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# PATCH/PUT /dashboards/1
|
34
|
+
def update
|
35
|
+
if @dashboard.update(dashboard_params)
|
36
|
+
redirect_to @dashboard, notice: "Dashboard was successfully updated.", status: :see_other
|
37
|
+
else
|
38
|
+
render :edit, status: :unprocessable_entity
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# DELETE /dashboards/1
|
43
|
+
def destroy
|
44
|
+
@dashboard.destroy
|
45
|
+
redirect_to dashboards_url, notice: "Dashboard was successfully destroyed.", status: :see_other
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
# Use callbacks to share common setup or constraints between actions.
|
50
|
+
def set_dashboard
|
51
|
+
@dashboard = Dashboard.find(params[:id])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Only allow a list of trusted parameters through.
|
55
|
+
def dashboard_params
|
56
|
+
params.fetch(:dashboard, {})
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module LesliBell
|
2
|
+
class NotificationsController < ApplicationController
|
3
|
+
before_action :set_notification, only: %i[ show edit update destroy ]
|
4
|
+
|
5
|
+
# GET /notifications
|
6
|
+
def index
|
7
|
+
@notifications = Notification.all
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /notifications/1
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /notifications/new
|
15
|
+
def new
|
16
|
+
@notification = Notification.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /notifications/1/edit
|
20
|
+
def edit
|
21
|
+
end
|
22
|
+
|
23
|
+
# POST /notifications
|
24
|
+
def create
|
25
|
+
@notification = Notification.new(notification_params)
|
26
|
+
|
27
|
+
if @notification.save
|
28
|
+
redirect_to @notification, notice: "Notification was successfully created."
|
29
|
+
else
|
30
|
+
render :new, status: :unprocessable_entity
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# PATCH/PUT /notifications/1
|
35
|
+
def update
|
36
|
+
if @notification.update(notification_params)
|
37
|
+
redirect_to @notification, notice: "Notification was successfully updated.", status: :see_other
|
38
|
+
else
|
39
|
+
render :edit, status: :unprocessable_entity
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# DELETE /notifications/1
|
44
|
+
def destroy
|
45
|
+
@notification.destroy
|
46
|
+
redirect_to notifications_url, notice: "Notification was successfully destroyed.", status: :see_other
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
# Use callbacks to share common setup or constraints between actions.
|
51
|
+
def set_notification
|
52
|
+
@notification = Notification.find(params[:id])
|
53
|
+
end
|
54
|
+
|
55
|
+
# Only allow a list of trusted parameters through.
|
56
|
+
def notification_params
|
57
|
+
params.fetch(:notification, {})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module LesliBell
|
2
|
+
class Notification < ApplicationRecord
|
3
|
+
belongs_to :account, class_name: "LesliBell::Account"
|
4
|
+
belongs_to :user, class_name: "::Lesli::User"
|
5
|
+
|
6
|
+
|
7
|
+
enum category: {
|
8
|
+
info: "info",
|
9
|
+
danger: "danger",
|
10
|
+
warning: "warning",
|
11
|
+
success: "success"
|
12
|
+
}
|
13
|
+
|
14
|
+
enum channel: {
|
15
|
+
push: "push", # webpush & mobilepush
|
16
|
+
email: "email", # notification sent by email only
|
17
|
+
webpush: "webpush", # notification for web interface only
|
18
|
+
mobilepush: "mobilepush", # notification for mobile only
|
19
|
+
mobiledialog: "mobiledialog", # open a dialog in the main app screen
|
20
|
+
}
|
21
|
+
|
22
|
+
enum status: {
|
23
|
+
read: "read",
|
24
|
+
sent: "sent",
|
25
|
+
created: "created"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module LesliBell
|
2
|
+
class NotificationService < Lesli::ApplicationLesliService
|
3
|
+
|
4
|
+
def index only_own_notifications=true
|
5
|
+
|
6
|
+
notifications = []
|
7
|
+
|
8
|
+
# work with all notifications
|
9
|
+
notifications = current_user.account.bell
|
10
|
+
.notifications
|
11
|
+
.order(created_at: :DESC)
|
12
|
+
|
13
|
+
# work only with notifications that belongs to the user
|
14
|
+
if only_own_notifications
|
15
|
+
notifications = notifications.where(:user => current_user, :status => ["created", "sent", nil])
|
16
|
+
end
|
17
|
+
|
18
|
+
# add pagination
|
19
|
+
notifications = notifications
|
20
|
+
.page(query[:pagination][:page])
|
21
|
+
.per(query[:pagination][:perPage])
|
22
|
+
.order(:updated_at)
|
23
|
+
|
24
|
+
return notifications
|
25
|
+
|
26
|
+
LC::Response.pagination(
|
27
|
+
notifications.current_page,
|
28
|
+
notifications.total_pages,
|
29
|
+
notifications.total_count,
|
30
|
+
notifications.length,
|
31
|
+
notifications.map do |notification|
|
32
|
+
{
|
33
|
+
id: notification[:id],
|
34
|
+
url: notification[:url],
|
35
|
+
body: notification[:body],
|
36
|
+
subject: notification[:subject],
|
37
|
+
category: notification[:category],
|
38
|
+
created_at: LC::Date.distance_to_words(notification[:created_at]),
|
39
|
+
status: notification[:status],
|
40
|
+
}
|
41
|
+
end
|
42
|
+
)
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def create(
|
47
|
+
subject,
|
48
|
+
url:nil,
|
49
|
+
body:nil,
|
50
|
+
media:nil,
|
51
|
+
payload:nil,
|
52
|
+
channel:nil,
|
53
|
+
category:nil,
|
54
|
+
user_receiver_id:nil,
|
55
|
+
notification_type:nil,
|
56
|
+
role_receiver_names:nil,
|
57
|
+
user_receiver_emails:nil
|
58
|
+
)
|
59
|
+
|
60
|
+
# validate that the notifications has a valid category
|
61
|
+
category = 'info' if not ['info', 'danger', 'warning', 'success'].include?(category)
|
62
|
+
|
63
|
+
# set push (web and mobile) notifications as default channel
|
64
|
+
channel = 'push' unless channel
|
65
|
+
|
66
|
+
# base notification data
|
67
|
+
notification_params = {
|
68
|
+
url: url,
|
69
|
+
body: body,
|
70
|
+
media: media,
|
71
|
+
payload: payload,
|
72
|
+
channel: channel,
|
73
|
+
subject: subject,
|
74
|
+
category: category,
|
75
|
+
notification_type: notification_type,
|
76
|
+
status: 'created',
|
77
|
+
user: current_user
|
78
|
+
}
|
79
|
+
|
80
|
+
# "bulk insert" all the notifications
|
81
|
+
notifications = current_user.account.bell.notifications.create([notification_params])
|
82
|
+
|
83
|
+
return { id: notifications.map(&:id) }
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= form_with(model: account) do |form| %>
|
2
|
+
<% if account.errors.any? %>
|
3
|
+
<div style="color: red">
|
4
|
+
<h2><%= pluralize(account.errors.count, "error") %> prohibited this account from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% account.errors.each do |error| %>
|
8
|
+
<li><%= error.full_message %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div>
|
15
|
+
<%= form.submit %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<p style="color: green"><%= notice %></p>
|
2
|
+
|
3
|
+
<h1>Accounts</h1>
|
4
|
+
|
5
|
+
<div id="accounts">
|
6
|
+
<% @accounts.each do |account| %>
|
7
|
+
<%= render account %>
|
8
|
+
<p>
|
9
|
+
<%= link_to "Show this account", account %>
|
10
|
+
</p>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<%= link_to "New account", new_account_path %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<p style="color: green"><%= notice %></p>
|
2
|
+
|
3
|
+
<%= render @account %>
|
4
|
+
|
5
|
+
<div>
|
6
|
+
<%= link_to "Edit this account", edit_account_path(@account) %> |
|
7
|
+
<%= link_to "Back to accounts", accounts_path %>
|
8
|
+
|
9
|
+
<%= button_to "Destroy this account", @account, method: :delete %>
|
10
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= form_with(model: announcement) do |form| %>
|
2
|
+
<% if announcement.errors.any? %>
|
3
|
+
<div style="color: red">
|
4
|
+
<h2><%= pluralize(announcement.errors.count, "error") %> prohibited this announcement from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% announcement.errors.each do |error| %>
|
8
|
+
<li><%= error.full_message %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div>
|
15
|
+
<%= form.submit %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<p style="color: green"><%= notice %></p>
|
2
|
+
|
3
|
+
<h1>Announcements</h1>
|
4
|
+
|
5
|
+
<div id="announcements">
|
6
|
+
<% @announcements.each do |announcement| %>
|
7
|
+
<%= render announcement %>
|
8
|
+
<p>
|
9
|
+
<%= link_to "Show this announcement", announcement %>
|
10
|
+
</p>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<%= link_to "New announcement", new_announcement_path %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<p style="color: green"><%= notice %></p>
|
2
|
+
|
3
|
+
<%= render @announcement %>
|
4
|
+
|
5
|
+
<div>
|
6
|
+
<%= link_to "Edit this announcement", edit_announcement_path(@announcement) %> |
|
7
|
+
<%= link_to "Back to announcements", announcements_path %>
|
8
|
+
|
9
|
+
<%= button_to "Destroy this announcement", @announcement, method: :delete %>
|
10
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= form_with(model: dashboard) do |form| %>
|
2
|
+
<% if dashboard.errors.any? %>
|
3
|
+
<div style="color: red">
|
4
|
+
<h2><%= pluralize(dashboard.errors.count, "error") %> prohibited this dashboard from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% dashboard.errors.each do |error| %>
|
8
|
+
<li><%= error.full_message %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div>
|
15
|
+
<%= form.submit %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<p style="color: green"><%= notice %></p>
|
2
|
+
|
3
|
+
<h1>Dashboards</h1>
|
4
|
+
|
5
|
+
<div id="dashboards">
|
6
|
+
<% @dashboards.each do |dashboard| %>
|
7
|
+
<%= render dashboard %>
|
8
|
+
<p>
|
9
|
+
<%= link_to "Show this dashboard", dashboard %>
|
10
|
+
</p>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<%= link_to "New dashboard", new_dashboard_path %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<router-view></router-view>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%#
|
2
|
+
|
3
|
+
Lesli
|
4
|
+
|
5
|
+
Copyright (c) 2023, Lesli Technologies, S. A.
|
6
|
+
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the GNU General Public License as published by
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
This program is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
GNU General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU General Public License
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
19
|
+
|
20
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
21
|
+
|
22
|
+
Made with ♥ by https://www.lesli.tech
|
23
|
+
Building a better future, one line of code at a time.
|
24
|
+
|
25
|
+
@contact hello@lesli.tech
|
26
|
+
@website https://www.lesli.dev
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
28
|
+
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
30
|
+
// ·
|
31
|
+
%>
|
32
|
+
|
33
|
+
<router-view></router-view>
|