ama_layout 5.12.0 → 6.3.0.pre
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/.travis.yml +0 -2
- data/ama_layout.gemspec +20 -21
- data/app/assets/javascripts/ama_layout/desktop/foundation-custom.js +8 -10
- data/app/assets/javascripts/ama_layout/desktop/index.js +0 -1
- data/app/helpers/ama_layout_path_helper.rb +5 -5
- data/app/views/ama_layout/_siteheader.html.erb +3 -8
- data/lib/ama_layout.rb +20 -28
- data/lib/ama_layout/decorators/moneris_decorator.rb +2 -3
- data/lib/ama_layout/decorators/navigation_decorator.rb +6 -52
- data/lib/ama_layout/decorators/navigation_item_decorator.rb +2 -3
- data/lib/ama_layout/moneris.rb +1 -4
- data/lib/ama_layout/navigation.rb +1 -7
- data/lib/ama_layout/navigation.yml +6 -58
- data/lib/ama_layout/navigation_item.rb +1 -4
- data/lib/ama_layout/version.rb +1 -1
- data/spec/ama_layout/decorators/navigation_decorator_spec.rb +8 -124
- data/spec/ama_layout/decorators/navigation_item_decorator_spec.rb +4 -2
- data/spec/ama_layout/navigation_spec.rb +43 -13
- data/spec/helpers/ama_layout_path_helper_spec.rb +6 -6
- data/spec/internal/app/controllers/application_controller.rb +0 -21
- data/spec/internal/config/routes.rb +0 -1
- data/spec/spec_helper.rb +16 -9
- data/styles.scss +0 -0
- metadata +41 -79
- data/PULL_REQUEST_TEMPLATE.md +0 -10
- data/app/assets/javascripts/ama_layout/notifications.coffee +0 -17
- data/app/controllers/ama_layout/api/v1/notifications_controller.rb +0 -18
- data/app/views/ama_layout/_notification.html.erb +0 -10
- data/app/views/ama_layout/_notification_sidebar.html.erb +0 -22
- data/app/views/ama_layout/_notifications.html.erb +0 -6
- data/app/views/ama_layout/_sign_out_link.html.erb +0 -3
- data/config/routes.rb +0 -9
- data/lib/ama_layout/decorators/notification_decorator.rb +0 -46
- data/lib/ama_layout/draper_replacement.rb +0 -27
- data/lib/ama_layout/navigation_helper.rb +0 -31
- data/lib/ama_layout/notification.rb +0 -87
- data/lib/ama_layout/notification_scrubber.rb +0 -13
- data/lib/ama_layout/notification_set.rb +0 -140
- data/lib/ama_layout/notifications.rb +0 -73
- data/lib/ama_layout/notifications/abstract_store.rb +0 -17
- data/lib/ama_layout/notifications/redis_store.rb +0 -38
- data/spec/ama_layout/controllers/ama_layout/api/v1/notifications_controller_spec.rb +0 -13
- data/spec/ama_layout/decorators/notification_decorator_spec.rb +0 -57
- data/spec/ama_layout/navigation_helper_spec.rb +0 -63
- data/spec/ama_layout/notification_scrubber_spec.rb +0 -10
- data/spec/ama_layout/notification_set_spec.rb +0 -281
- data/spec/ama_layout/notification_spec.rb +0 -193
- data/spec/ama_layout/notifications/abstract_store_spec.rb +0 -23
- data/spec/ama_layout/notifications/redis_store_spec.rb +0 -94
- data/spec/ama_layout/notifications_spec.rb +0 -109
- data/spec/factories/users.rb +0 -35
- data/spec/support/shared_examples/member_navigation.rb +0 -105
data/PULL_REQUEST_TEMPLATE.md
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
### PR Review Checklist
|
2
|
-
To be completed by the person who opens the PR. Use strikethroughs for items that are not applicable in list.
|
3
|
-
- [ ] I have reviewed my own PR to check syntax & logic, removed unnecessary/old code, made sure everything aligns with our style guide and BEM.
|
4
|
-
- [ ] I've added new components to the style guide (or have a PR in to add them).
|
5
|
-
- [ ] Any applicable version numbers have been updated.
|
6
|
-
- [ ] I've tested on mobile, tablet, and desktop, as well as across all of the browsers we support.
|
7
|
-
- [ ] I've proof-read all text for legibility, proper grammar, punctuation, and capitalization (titlecase).
|
8
|
-
- [ ] I have written a detailed PR message explaining what is being changed and why
|
9
|
-
- [ ] I’ve linked to any relevant VSTS tickets
|
10
|
-
- [ ] I’ve added the appropriate review symbols to my PR - (elephant) for dev review, (art) for design
|
@@ -1,17 +0,0 @@
|
|
1
|
-
class AMALayout.Notifications
|
2
|
-
constructor: () ->
|
3
|
-
$(document).on 'click', '[data-notifications-toggle]', (event) =>
|
4
|
-
event.preventDefault();
|
5
|
-
badge = event.currentTarget
|
6
|
-
if $(badge).find('[data-notification-count]').remove().size()
|
7
|
-
@request()
|
8
|
-
|
9
|
-
request: () ->
|
10
|
-
$.ajax(
|
11
|
-
type: 'DELETE',
|
12
|
-
url: '/ama_layout/api/v1/notifications',
|
13
|
-
timeout: 10000
|
14
|
-
)
|
15
|
-
|
16
|
-
$(document).ready ->
|
17
|
-
window.AMALayout.notifications = new AMALayout.Notifications()
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
module Api
|
3
|
-
module V1
|
4
|
-
class NotificationsController < ApplicationController
|
5
|
-
before_action :require_login
|
6
|
-
|
7
|
-
# DELETE /api/v1/notifications
|
8
|
-
# Dismiss all user notifications
|
9
|
-
def dismiss_all
|
10
|
-
notifications = current_user.notifications
|
11
|
-
notifications.each(&:dismiss!)
|
12
|
-
notifications.save
|
13
|
-
head :no_content
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
<div class="row <%= notification.active_class %>">
|
2
|
-
<div class="small-2 column">
|
3
|
-
<%= notification.icon %>
|
4
|
-
</div>
|
5
|
-
<div class="small-10 column">
|
6
|
-
<p class="bold"><%= notification.header %></p>
|
7
|
-
<p><%= sanitize notification.content, scrubber: AmaLayout::NotificationScrubber.new %></p>
|
8
|
-
<p class="micetype"><%= notification.created_at %></p>
|
9
|
-
</div>
|
10
|
-
</div>
|
@@ -1,22 +0,0 @@
|
|
1
|
-
<div class="off-canvas position-right right-sidebar" id="offCanvasRight" data-off-canvas>
|
2
|
-
<div class="row column right-sidebar__header">
|
3
|
-
<h2 class="mt1">Notification Centre</h2>
|
4
|
-
<button class="close-button" aria-label="Close menu" type="button" data-close>
|
5
|
-
<span aria-hidden="true">×</span>
|
6
|
-
</button>
|
7
|
-
</div>
|
8
|
-
<div class="row column">
|
9
|
-
<%= navigation.notifications_heading %>
|
10
|
-
</div>
|
11
|
-
<%= render partial: 'ama_layout/notification', collection: notifications %>
|
12
|
-
<div class="row column">
|
13
|
-
<p class="mt1">Did You Know?</p>
|
14
|
-
<div class="section-content">
|
15
|
-
<p class="bold">Sign up for Vehicle Registration Auto-Renew</p>
|
16
|
-
<p>
|
17
|
-
We'll process your payment and mail you a new registration certificate and licence plate sticker. It's that simple!
|
18
|
-
</p>
|
19
|
-
<%= link_to 'Sign up now', "#{Rails.configuration.registries_site}/order/registrations/new", class: 'button--right button--expand-small-down' %>
|
20
|
-
</div>
|
21
|
-
</div>
|
22
|
-
</div>
|
data/config/routes.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
class NotificationDecorator
|
3
|
-
include AmaLayout::DraperReplacement
|
4
|
-
extend AmaLayout::DraperReplacement
|
5
|
-
|
6
|
-
ICONS = {
|
7
|
-
notice: {
|
8
|
-
icon_class: 'fa-info',
|
9
|
-
colour_class: 'right-sidebar__content-icon--blue' # currently not in use
|
10
|
-
},
|
11
|
-
warning: {
|
12
|
-
icon_class: 'fa-exclamation',
|
13
|
-
colour_class: 'right-sidebar__content-icon--orange'
|
14
|
-
},
|
15
|
-
alert: {
|
16
|
-
icon_class: 'fa-exclamation-triangle',
|
17
|
-
colour_class: 'right-sidebar__content-icon--red'
|
18
|
-
}
|
19
|
-
}.freeze
|
20
|
-
|
21
|
-
def created_at
|
22
|
-
"#{time_elapsed} ago".humanize
|
23
|
-
end
|
24
|
-
|
25
|
-
def icon
|
26
|
-
h.content_tag :div, class: icon_data.fetch(:colour_class) do
|
27
|
-
klass = icon_data.fetch(:icon_class)
|
28
|
-
h.content_tag :i, nil, class: "fa #{klass} right-sidebar__notice-icon"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def active_class
|
33
|
-
active? ? 'right-sidebar__content--active' : 'right-sidebar__content--inactive'
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def icon_data
|
39
|
-
@icon_data ||= ICONS.fetch(type)
|
40
|
-
end
|
41
|
-
|
42
|
-
def time_elapsed
|
43
|
-
h.time_ago_in_words(object.created_at, include_seconds: true)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
module DraperReplacement
|
3
|
-
attr_accessor :object
|
4
|
-
|
5
|
-
def h
|
6
|
-
ActionView::Base.new(::ActionController::Base.view_paths, {}, ::ApplicationController.new)
|
7
|
-
end
|
8
|
-
|
9
|
-
def initialize(args = {})
|
10
|
-
self.object = args
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.decorate_collection(objects = {})
|
14
|
-
objects.map { |o| self.new(o) }
|
15
|
-
end
|
16
|
-
|
17
|
-
def method_missing(method, *args, &block)
|
18
|
-
return super unless delegatable?(method)
|
19
|
-
|
20
|
-
(object || DraperReplacement).send(method, *args, &block)
|
21
|
-
end
|
22
|
-
|
23
|
-
def delegatable?(method)
|
24
|
-
object.respond_to?(method) || DraperReplacement.respond_to?(method)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
module NavigationHelper
|
3
|
-
def navigation
|
4
|
-
return AmaLayout::Navigation.non_member unless member?
|
5
|
-
case
|
6
|
-
when _has_outstanding_balance?
|
7
|
-
AmaLayout::Navigation.member_with_outstanding_balance
|
8
|
-
when _in_renewal_late?
|
9
|
-
AmaLayout::Navigation.member_in_renewal_late
|
10
|
-
when _in_renewal?
|
11
|
-
AmaLayout::Navigation.member_in_renewal
|
12
|
-
else
|
13
|
-
AmaLayout::Navigation.member
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def _in_renewal?
|
20
|
-
in_renewal
|
21
|
-
end
|
22
|
-
|
23
|
-
def _in_renewal_late?
|
24
|
-
status == "AL"
|
25
|
-
end
|
26
|
-
|
27
|
-
def _has_outstanding_balance?
|
28
|
-
has_outstanding_balance
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
class Notification
|
3
|
-
TYPES = %i[notice warning alert].freeze
|
4
|
-
DEFAULT_LIFESPAN = 1.year.freeze
|
5
|
-
FORMAT_VERSION = '1.0.0'.freeze
|
6
|
-
|
7
|
-
# NOTE: The following attributes are designed to be immutable - you need
|
8
|
-
# make a new instance to change them. The only mutable attribute is :active.
|
9
|
-
attr_reader :id, :type, :brand, :header, :content, :created_at, :lifespan,
|
10
|
-
:version
|
11
|
-
attr_accessor :active
|
12
|
-
|
13
|
-
def initialize(args = {})
|
14
|
-
args = args.with_indifferent_access
|
15
|
-
@id = args[:id]
|
16
|
-
@type = args.fetch(:type, :notice).to_sym
|
17
|
-
@brand = args[:brand]
|
18
|
-
@header = args.fetch(:header)
|
19
|
-
@content = args.fetch(:content)
|
20
|
-
@created_at = parse_time(args.fetch(:created_at))
|
21
|
-
@lifespan = parse_duration(args.fetch(:lifespan, DEFAULT_LIFESPAN))
|
22
|
-
@version = args.fetch(:version, FORMAT_VERSION)
|
23
|
-
self.active = args.fetch(:active)
|
24
|
-
invalid_type! if TYPES.exclude?(type)
|
25
|
-
end
|
26
|
-
|
27
|
-
def <=>(other)
|
28
|
-
created_at <=> other.created_at
|
29
|
-
end
|
30
|
-
|
31
|
-
def active?
|
32
|
-
active
|
33
|
-
end
|
34
|
-
|
35
|
-
def dismissed?
|
36
|
-
!active?
|
37
|
-
end
|
38
|
-
|
39
|
-
def dismiss!
|
40
|
-
self.active = false
|
41
|
-
dismissed?
|
42
|
-
end
|
43
|
-
|
44
|
-
def digest
|
45
|
-
Digest::SHA256.hexdigest(
|
46
|
-
"#{type}#{header}#{content}#{brand}#{version}"
|
47
|
-
)
|
48
|
-
end
|
49
|
-
|
50
|
-
def stale?
|
51
|
-
Time.current > created_at + lifespan
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_h
|
55
|
-
# NOTE: We want the following keys to be strings to provide
|
56
|
-
# consistency with the underlying data store.
|
57
|
-
{
|
58
|
-
'type' => type.to_s,
|
59
|
-
'brand' => brand,
|
60
|
-
'header' => header,
|
61
|
-
'content' => content,
|
62
|
-
'created_at' => created_at.iso8601,
|
63
|
-
'active' => active,
|
64
|
-
'lifespan' => lifespan.to_i,
|
65
|
-
'version' => version
|
66
|
-
}
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
def invalid_type!
|
72
|
-
raise ArgumentError, "invalid notification type: #{type}"
|
73
|
-
end
|
74
|
-
|
75
|
-
def parse_time(time)
|
76
|
-
time.is_a?(String) ? Time.zone.parse(time) : time
|
77
|
-
end
|
78
|
-
|
79
|
-
def parse_duration(duration)
|
80
|
-
if duration.is_a?(ActiveSupport::Duration)
|
81
|
-
duration
|
82
|
-
else
|
83
|
-
duration.seconds
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
class NotificationScrubber < Rails::Html::PermitScrubber
|
3
|
-
def initialize
|
4
|
-
super
|
5
|
-
self.tags = %w(i a div span strong br em h1 h2 h3 h4 h5 h6 blockquote)
|
6
|
-
self.attributes = %w(href class id)
|
7
|
-
end
|
8
|
-
|
9
|
-
def skip_node?(node)
|
10
|
-
node.text?
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,140 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
# An array-like object that handles the storage and retrieval of notifications
|
3
|
-
# from the underlying data store.
|
4
|
-
#
|
5
|
-
# The raw serialization format is JSON as follows (keys are SHA256 hashes):
|
6
|
-
#
|
7
|
-
# {
|
8
|
-
# "57107043eab0f60a37f7735307dc6fc6709d04eec2dbeea8c284958057af9b77": {
|
9
|
-
# "type": "notice",
|
10
|
-
# "brand": "membership",
|
11
|
-
# "header": "test",
|
12
|
-
# "content": "test",
|
13
|
-
# "created_at": "2017-06-19T11:26:57.730-06:00",
|
14
|
-
# "lifespan": 31557600,
|
15
|
-
# "active": true,
|
16
|
-
# "version": "1.0.0"
|
17
|
-
# }
|
18
|
-
# }
|
19
|
-
#
|
20
|
-
class NotificationSet
|
21
|
-
include Enumerable
|
22
|
-
attr_accessor :base, :data_store, :key
|
23
|
-
|
24
|
-
delegate :each, :first, :last, :size, :[], :empty?, :any?, to: :all
|
25
|
-
|
26
|
-
def initialize(data_store, key)
|
27
|
-
self.data_store = data_store
|
28
|
-
self.key = key
|
29
|
-
self.base = fetch
|
30
|
-
clean!
|
31
|
-
end
|
32
|
-
|
33
|
-
def active
|
34
|
-
all.select(&:active?)
|
35
|
-
end
|
36
|
-
|
37
|
-
def all
|
38
|
-
@all ||= normalize(base_notifications)
|
39
|
-
end
|
40
|
-
|
41
|
-
def create(args = {})
|
42
|
-
args[:created_at] = Time.current
|
43
|
-
args[:active] = true
|
44
|
-
notification = Notification.new(args)
|
45
|
-
# previously dismissed notifications always take precendence
|
46
|
-
all.push(notification) unless base.key?(notification.digest)
|
47
|
-
save
|
48
|
-
end
|
49
|
-
|
50
|
-
def destroy!
|
51
|
-
data_store.delete(key) && reload!
|
52
|
-
end
|
53
|
-
|
54
|
-
def delete(*digests)
|
55
|
-
digests = Array.wrap(digests.flatten)
|
56
|
-
delta = all.reject { |n| digests.include?(n.digest) }
|
57
|
-
if delta != all
|
58
|
-
@all = delta
|
59
|
-
save
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def find(digest)
|
64
|
-
all.find { |n| n.id == digest }
|
65
|
-
end
|
66
|
-
|
67
|
-
def save
|
68
|
-
data_store.transaction do |store|
|
69
|
-
normalized = normalize(all)
|
70
|
-
self.base = serialize(normalized)
|
71
|
-
store.set(key, base.to_json)
|
72
|
-
end
|
73
|
-
reload!
|
74
|
-
end
|
75
|
-
|
76
|
-
def inspect
|
77
|
-
"<#{self.class.name}>: #{all}"
|
78
|
-
end
|
79
|
-
alias_method :to_s, :inspect
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def clean!
|
84
|
-
if dirty?
|
85
|
-
all.reject!(&:stale?)
|
86
|
-
save
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def dirty?
|
91
|
-
all.any?(&:stale?)
|
92
|
-
end
|
93
|
-
|
94
|
-
def reload!
|
95
|
-
@all = nil
|
96
|
-
self.base = fetch
|
97
|
-
all
|
98
|
-
self
|
99
|
-
end
|
100
|
-
|
101
|
-
def base_notifications
|
102
|
-
base.map { |k, v| Notification.new(v.merge(id: k)) }
|
103
|
-
end
|
104
|
-
|
105
|
-
def serialize(data)
|
106
|
-
data.inject({}) do |hash, element|
|
107
|
-
hash[element.digest] = element.to_h
|
108
|
-
hash
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def normalize(data)
|
113
|
-
# sort by reverse chronological order
|
114
|
-
data.sort { |a, b| b <=> a }
|
115
|
-
end
|
116
|
-
|
117
|
-
def fetch
|
118
|
-
result = data_store.get(key)
|
119
|
-
result.present? ? build(result) : {}
|
120
|
-
end
|
121
|
-
|
122
|
-
def build(raw)
|
123
|
-
JSON.parse(raw)
|
124
|
-
rescue JSON::ParserError
|
125
|
-
data_store.delete(key) # we should try to prevent further errors
|
126
|
-
::Rails.logger.error json_message(__FILE__, __LINE__, raw)
|
127
|
-
{}
|
128
|
-
end
|
129
|
-
|
130
|
-
def json_message(file, line, raw)
|
131
|
-
{
|
132
|
-
error: "#{self.class.name} - Invalid JSON",
|
133
|
-
file: file,
|
134
|
-
line: line,
|
135
|
-
key: key,
|
136
|
-
raw: raw
|
137
|
-
}.to_json
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|