sincerely 1.0.0 → 1.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 +4 -4
- data/CHANGELOG.md +31 -0
- data/app/assets/config/sincerely.js +2 -0
- data/app/assets/images/sincerely/arrow_left.svg +1 -0
- data/app/assets/images/sincerely/check.svg +3 -0
- data/app/assets/images/sincerely/chevron_left.svg +1 -0
- data/app/assets/images/sincerely/clock.svg +1 -0
- data/app/assets/images/sincerely/code.svg +1 -0
- data/app/assets/images/sincerely/eye.svg +1 -0
- data/app/assets/images/sincerely/logout.svg +1 -0
- data/app/assets/images/sincerely/menu.svg +1 -0
- data/app/assets/images/sincerely/moon.svg +1 -0
- data/app/assets/images/sincerely/pencil.svg +4 -0
- data/app/assets/images/sincerely/plus.svg +3 -0
- data/app/assets/images/sincerely/progress_spinner.svg +3 -0
- data/app/assets/images/sincerely/spinner.svg +3 -0
- data/app/assets/images/sincerely/sun.svg +1 -0
- data/app/assets/images/sincerely/warning_circle.svg +4 -0
- data/app/assets/javascripts/sincerely/charts.js +115 -0
- data/app/assets/javascripts/sincerely/clickable_rows.js +29 -0
- data/app/assets/javascripts/sincerely/layout.js +104 -0
- data/app/assets/javascripts/sincerely/send_form.js +243 -0
- data/app/assets/javascripts/sincerely/template_form.js +44 -0
- data/app/assets/javascripts/sincerely/template_preview.js +12 -0
- data/app/assets/javascripts/sincerely/theme_init.js +9 -0
- data/app/assets/stylesheets/sincerely/charts.css +250 -0
- data/app/assets/stylesheets/sincerely/components.css +632 -0
- data/app/assets/stylesheets/sincerely/layout.css +233 -0
- data/app/assets/stylesheets/sincerely/navigation.css +198 -0
- data/app/assets/stylesheets/sincerely/send_form.css +287 -0
- data/app/assets/stylesheets/sincerely/template_form.css +74 -0
- data/app/assets/stylesheets/sincerely/template_preview.css +75 -0
- data/app/assets/stylesheets/sincerely/variables.css +88 -0
- data/app/controllers/sincerely/application_controller.rb +3 -72
- data/app/controllers/sincerely/concerns/authorization.rb +21 -0
- data/app/controllers/sincerely/concerns/delivery_metrics.rb +51 -0
- data/app/controllers/sincerely/concerns/event_filtering.rb +58 -0
- data/app/controllers/sincerely/concerns/event_timeline.rb +41 -0
- data/app/controllers/sincerely/concerns/notification_timeline.rb +73 -0
- data/app/controllers/sincerely/concerns/notifications.rb +47 -0
- data/app/controllers/sincerely/concerns/pagination.rb +39 -0
- data/app/controllers/sincerely/concerns/periods.rb +40 -0
- data/app/controllers/sincerely/dashboard_controller.rb +30 -88
- data/app/controllers/sincerely/delivery_events_controller.rb +13 -21
- data/app/controllers/sincerely/engagement_events_controller.rb +13 -22
- data/app/controllers/sincerely/notifications_controller.rb +68 -49
- data/app/controllers/sincerely/send_controller.rb +82 -67
- data/app/controllers/sincerely/templates_controller.rb +37 -8
- data/app/helpers/sincerely/application_helper.rb +22 -0
- data/app/helpers/sincerely/chart_helper.rb +79 -0
- data/app/views/layouts/sincerely/application.html.erb +24 -528
- data/app/views/sincerely/dashboard/index.html.erb +25 -256
- data/app/views/sincerely/delivery_events/index.html.erb +6 -38
- data/app/views/sincerely/engagement_events/index.html.erb +6 -38
- data/app/views/sincerely/notifications/index.html.erb +7 -23
- data/app/views/sincerely/notifications/show.html.erb +4 -4
- data/app/views/sincerely/send/new.html.erb +8 -522
- data/app/views/sincerely/shared/_event.html.erb +21 -0
- data/app/views/sincerely/shared/_line_chart.html.erb +38 -0
- data/app/views/sincerely/shared/_notification_type_filter.html.erb +9 -0
- data/app/views/sincerely/shared/_status_option.html.erb +1 -0
- data/app/views/sincerely/shared/_template_option.html.erb +3 -0
- data/app/views/sincerely/templates/_form.html.erb +8 -107
- data/app/views/sincerely/templates/edit.html.erb +2 -2
- data/app/views/sincerely/templates/index.html.erb +7 -15
- data/app/views/sincerely/templates/new.html.erb +2 -2
- data/app/views/sincerely/templates/preview.html.erb +7 -26
- data/app/views/sincerely/templates/show.html.erb +3 -3
- data/lib/config/sincerely_config.rb +2 -2
- data/lib/sincerely/delivery_systems/email_aws_ses.rb +2 -2
- data/lib/sincerely/engine.rb +4 -0
- data/lib/sincerely/mixins/notification_model.rb +5 -1
- data/lib/sincerely/services/process_delivery_event.rb +9 -7
- data/lib/sincerely/templates/notification_template.rb +1 -1
- data/lib/sincerely/version.rb +1 -1
- metadata +52 -4
- data/sincerely.gemspec +0 -37
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sincerely
|
|
4
|
+
module ChartHelper
|
|
5
|
+
DANGER_COLOR = '#d4183d'
|
|
6
|
+
|
|
7
|
+
STATE_COLORS = {
|
|
8
|
+
'draft' => '#9ca3af',
|
|
9
|
+
'accepted' => '#b9e0b8',
|
|
10
|
+
'delivered' => '#10b981',
|
|
11
|
+
'opened' => '#78c6cc',
|
|
12
|
+
'clicked' => '#bdd9db',
|
|
13
|
+
'bounced' => DANGER_COLOR,
|
|
14
|
+
'rejected' => DANGER_COLOR,
|
|
15
|
+
'complained' => DANGER_COLOR,
|
|
16
|
+
'delayed' => '#f97316'
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
DEFAULT_COLOR = '#6b7280'
|
|
20
|
+
|
|
21
|
+
LINE_CHART = {
|
|
22
|
+
width: 800, height: 220,
|
|
23
|
+
padding_left: 45, padding_right: 20,
|
|
24
|
+
padding_top: 20, padding_bottom: 30
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
DONUT_RADIUS = 68
|
|
28
|
+
|
|
29
|
+
def state_color(state)
|
|
30
|
+
STATE_COLORS[state.to_s] || DEFAULT_COLOR
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def line_chart_config(series, labels)
|
|
34
|
+
plot_width = LINE_CHART[:width] - LINE_CHART[:padding_left] - LINE_CHART[:padding_right]
|
|
35
|
+
plot_height = LINE_CHART[:height] - LINE_CHART[:padding_top] - LINE_CHART[:padding_bottom]
|
|
36
|
+
|
|
37
|
+
max_value = [series.values.flatten.max || 0, 1].max
|
|
38
|
+
magnitude = 10**Math.log10(max_value).floor
|
|
39
|
+
max_y = [((max_value.to_f / magnitude).ceil * magnitude).to_i, 1].max
|
|
40
|
+
x_step = labels.length > 1 ? plot_width.to_f / (labels.length - 1) : plot_width
|
|
41
|
+
|
|
42
|
+
LINE_CHART.merge(plot_width:, plot_height:, max_y:, x_step:)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def line_chart_points(values, config)
|
|
46
|
+
values.each_with_index.map do |value, i|
|
|
47
|
+
x = config[:padding_left] + (i * config[:x_step])
|
|
48
|
+
y = config[:padding_top] + config[:plot_height] - (value.to_f / config[:max_y] * config[:plot_height])
|
|
49
|
+
"#{x.round(2)},#{y.round(2)}"
|
|
50
|
+
end.join(' ')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def line_chart_area_points(points_str, values, config)
|
|
54
|
+
bottom_y = config[:padding_top] + config[:plot_height]
|
|
55
|
+
last_x = config[:padding_left] + ((values.length - 1) * config[:x_step])
|
|
56
|
+
"#{config[:padding_left]},#{bottom_y} #{points_str} #{last_x},#{bottom_y}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def donut_segment_data(notifications_by_state)
|
|
60
|
+
total = notifications_by_state.values.sum
|
|
61
|
+
circumference = 2 * Math::PI * DONUT_RADIUS
|
|
62
|
+
offset = 0
|
|
63
|
+
|
|
64
|
+
notifications_by_state.map do |state, count|
|
|
65
|
+
dash_length = circumference * (count.to_f / total)
|
|
66
|
+
visible_dash = [dash_length + 0.5, circumference].min
|
|
67
|
+
segment = {
|
|
68
|
+
state:, count:,
|
|
69
|
+
color: state_color(state),
|
|
70
|
+
visible_dash:,
|
|
71
|
+
gap: [circumference - visible_dash, 0].max,
|
|
72
|
+
offset: -offset
|
|
73
|
+
}
|
|
74
|
+
offset += dash_length
|
|
75
|
+
segment
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|