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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -2
  3. data/ama_layout.gemspec +20 -21
  4. data/app/assets/javascripts/ama_layout/desktop/foundation-custom.js +8 -10
  5. data/app/assets/javascripts/ama_layout/desktop/index.js +0 -1
  6. data/app/helpers/ama_layout_path_helper.rb +5 -5
  7. data/app/views/ama_layout/_siteheader.html.erb +3 -8
  8. data/lib/ama_layout.rb +20 -28
  9. data/lib/ama_layout/decorators/moneris_decorator.rb +2 -3
  10. data/lib/ama_layout/decorators/navigation_decorator.rb +6 -52
  11. data/lib/ama_layout/decorators/navigation_item_decorator.rb +2 -3
  12. data/lib/ama_layout/moneris.rb +1 -4
  13. data/lib/ama_layout/navigation.rb +1 -7
  14. data/lib/ama_layout/navigation.yml +6 -58
  15. data/lib/ama_layout/navigation_item.rb +1 -4
  16. data/lib/ama_layout/version.rb +1 -1
  17. data/spec/ama_layout/decorators/navigation_decorator_spec.rb +8 -124
  18. data/spec/ama_layout/decorators/navigation_item_decorator_spec.rb +4 -2
  19. data/spec/ama_layout/navigation_spec.rb +43 -13
  20. data/spec/helpers/ama_layout_path_helper_spec.rb +6 -6
  21. data/spec/internal/app/controllers/application_controller.rb +0 -21
  22. data/spec/internal/config/routes.rb +0 -1
  23. data/spec/spec_helper.rb +16 -9
  24. data/styles.scss +0 -0
  25. metadata +41 -79
  26. data/PULL_REQUEST_TEMPLATE.md +0 -10
  27. data/app/assets/javascripts/ama_layout/notifications.coffee +0 -17
  28. data/app/controllers/ama_layout/api/v1/notifications_controller.rb +0 -18
  29. data/app/views/ama_layout/_notification.html.erb +0 -10
  30. data/app/views/ama_layout/_notification_sidebar.html.erb +0 -22
  31. data/app/views/ama_layout/_notifications.html.erb +0 -6
  32. data/app/views/ama_layout/_sign_out_link.html.erb +0 -3
  33. data/config/routes.rb +0 -9
  34. data/lib/ama_layout/decorators/notification_decorator.rb +0 -46
  35. data/lib/ama_layout/draper_replacement.rb +0 -27
  36. data/lib/ama_layout/navigation_helper.rb +0 -31
  37. data/lib/ama_layout/notification.rb +0 -87
  38. data/lib/ama_layout/notification_scrubber.rb +0 -13
  39. data/lib/ama_layout/notification_set.rb +0 -140
  40. data/lib/ama_layout/notifications.rb +0 -73
  41. data/lib/ama_layout/notifications/abstract_store.rb +0 -17
  42. data/lib/ama_layout/notifications/redis_store.rb +0 -38
  43. data/spec/ama_layout/controllers/ama_layout/api/v1/notifications_controller_spec.rb +0 -13
  44. data/spec/ama_layout/decorators/notification_decorator_spec.rb +0 -57
  45. data/spec/ama_layout/navigation_helper_spec.rb +0 -63
  46. data/spec/ama_layout/notification_scrubber_spec.rb +0 -10
  47. data/spec/ama_layout/notification_set_spec.rb +0 -281
  48. data/spec/ama_layout/notification_spec.rb +0 -193
  49. data/spec/ama_layout/notifications/abstract_store_spec.rb +0 -23
  50. data/spec/ama_layout/notifications/redis_store_spec.rb +0 -94
  51. data/spec/ama_layout/notifications_spec.rb +0 -109
  52. data/spec/factories/users.rb +0 -35
  53. data/spec/support/shared_examples/member_navigation.rb +0 -105
@@ -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">&times;</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>
@@ -1,6 +0,0 @@
1
- <li>
2
- <a href="#" class="notification link--no-underline" data-toggle="offCanvasRight" data-notifications-toggle>
3
- <i class="fa fa-2x fa-bell"></i>
4
- <%= navigation.notification_badge %>
5
- </a>
6
- </li>
@@ -1,3 +0,0 @@
1
- <li class="side-nav__item">
2
- <a class="side-nav__link" href="/logout">Sign Out</a>
3
- </li>
data/config/routes.rb DELETED
@@ -1,9 +0,0 @@
1
- AmaLayout::Engine.routes.draw do
2
- scope module: 'ama_layout' do
3
- namespace :api do
4
- namespace :v1 do
5
- delete :notifications, to: 'notifications#dismiss_all'
6
- end
7
- end
8
- end
9
- end
@@ -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