beyond_canvas 0.13.1.pre → 0.15.3.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/icons/checkbox_checked.svg +1 -0
  3. data/app/assets/images/icons/checkbox_unchecked.svg +1 -0
  4. data/app/assets/images/icons/file.svg +1 -0
  5. data/app/assets/images/icons/flash_checkbox.svg +1 -0
  6. data/app/assets/images/icons/flash_close.svg +1 -0
  7. data/app/assets/images/icons/flash_error.svg +1 -0
  8. data/app/assets/images/icons/flash_info.svg +1 -0
  9. data/app/assets/images/icons/flash_warning.svg +1 -0
  10. data/app/assets/images/icons/radiobutton_checked.svg +1 -0
  11. data/app/assets/images/icons/radiobutton_unchecked.svg +1 -0
  12. data/app/assets/javascripts/beyond_canvas/base.js +255 -0
  13. data/app/assets/stylesheets/beyond_canvas/base.scss +28 -0
  14. data/app/assets/stylesheets/beyond_canvas/components/_actions.scss +6 -0
  15. data/app/assets/stylesheets/beyond_canvas/components/_buttons.scss +112 -0
  16. data/app/assets/stylesheets/beyond_canvas/components/_cards.scss +34 -0
  17. data/app/assets/stylesheets/beyond_canvas/components/_comments.scss +6 -0
  18. data/app/assets/stylesheets/beyond_canvas/components/_containers.scss +37 -0
  19. data/app/assets/stylesheets/beyond_canvas/components/_flash.scss +66 -0
  20. data/app/assets/stylesheets/beyond_canvas/components/_forms.scss +43 -0
  21. data/app/assets/stylesheets/beyond_canvas/components/_inputs.scss +143 -0
  22. data/app/assets/stylesheets/beyond_canvas/components/_layouts.scss +7 -0
  23. data/app/assets/stylesheets/beyond_canvas/components/_links.scss +17 -0
  24. data/app/assets/stylesheets/beyond_canvas/components/_main.scss +39 -0
  25. data/app/assets/stylesheets/beyond_canvas/components/_margins.scss +9 -0
  26. data/app/assets/stylesheets/beyond_canvas/components/_markdown.scss +74 -0
  27. data/app/assets/stylesheets/beyond_canvas/components/_notices.scss +58 -0
  28. data/app/assets/stylesheets/beyond_canvas/components/_relative.scss +3 -0
  29. data/app/assets/stylesheets/beyond_canvas/components/_spinner.scss +48 -0
  30. data/app/assets/stylesheets/beyond_canvas/components/_tables.scss +31 -0
  31. data/app/assets/stylesheets/beyond_canvas/components/_texts.scss +7 -0
  32. data/app/assets/stylesheets/beyond_canvas/mailer.scss +5 -0
  33. data/app/assets/stylesheets/beyond_canvas/settings/_breakpoints.scss +6 -0
  34. data/app/assets/stylesheets/beyond_canvas/settings/{_reset_css.sass → _reset_css.scss} +29 -21
  35. data/app/assets/stylesheets/beyond_canvas/settings/_typography.scss +67 -0
  36. data/app/assets/stylesheets/beyond_canvas/settings/_variables.scss +171 -0
  37. data/app/assets/stylesheets/beyond_canvas/utilities/_functions.scss +15 -0
  38. data/app/assets/stylesheets/beyond_canvas/utilities/_mixins.scss +24 -0
  39. data/app/controllers/beyond_canvas/application_controller.rb +1 -1
  40. data/app/controllers/beyond_canvas/system_controller.rb +1 -1
  41. data/app/controllers/concerns/beyond_canvas/locale_management.rb +4 -4
  42. data/app/controllers/concerns/beyond_canvas/request_validation.rb +8 -6
  43. data/app/controllers/concerns/beyond_canvas/status_codes.rb +5 -3
  44. data/app/form_builders/beyond_canvas/form_builder.rb +74 -13
  45. data/app/helpers/beyond_canvas/application_helper.rb +17 -18
  46. data/app/helpers/beyond_canvas/locale_switch_helper.rb +1 -1
  47. data/app/javascript/beyond_canvas/base.js +3 -0
  48. data/app/javascript/beyond_canvas/initializers/buttons.js +54 -0
  49. data/app/javascript/beyond_canvas/initializers/flash.js +19 -0
  50. data/app/javascript/beyond_canvas/initializers/functions.js +41 -0
  51. data/app/javascript/beyond_canvas/initializers/inputs.js +34 -0
  52. data/app/views/beyond_canvas/custom/_public_head.html.erb +1 -0
  53. data/app/views/beyond_canvas/locales/_edit.html.erb +8 -0
  54. data/app/views/beyond_canvas/mailer/_header.html.erb +2 -2
  55. data/app/views/beyond_canvas/shared/_flash.html.erb +13 -0
  56. data/app/views/beyond_canvas/shared/_head.html.erb +29 -0
  57. data/app/views/beyond_canvas/shared/_logo.html.erb +2 -0
  58. data/app/views/layouts/beyond_canvas/public.html.erb +16 -0
  59. data/config/initializers/beyond_canvas/filter_parameter_logging.rb +5 -5
  60. data/lib/beyond_canvas.rb +12 -17
  61. data/lib/beyond_canvas/asset_registration.rb +29 -0
  62. data/lib/beyond_canvas/configuration.rb +27 -0
  63. data/lib/beyond_canvas/engine.rb +10 -1
  64. data/lib/beyond_canvas/version.rb +1 -1
  65. data/lib/generators/beyond_canvas/assets/assets_generator.rb +14 -0
  66. data/lib/generators/beyond_canvas/assets/templates/beyond_canvas.js +1 -0
  67. data/lib/generators/beyond_canvas/assets/templates/beyond_canvas.scss +1 -0
  68. data/lib/generators/beyond_canvas/{install_generator.rb → beyond_api/beyond_api_generator.rb} +1 -7
  69. data/lib/generators/beyond_canvas/{custom_styles_generator.rb → custom_styles/custom_styles_generator.rb} +2 -2
  70. data/lib/generators/{templates → beyond_canvas/custom_styles/templates}/beyond_canvas_custom_styles.sass +0 -0
  71. data/lib/generators/beyond_canvas/install/install_generator.rb +35 -0
  72. data/lib/generators/beyond_canvas/install/templates/beyond_canvas.rb.erb +40 -0
  73. data/lib/generators/beyond_canvas/webpacker/plugins/jquery.js +7 -0
  74. data/lib/generators/beyond_canvas/webpacker/templates/beyond_canvas.js +3 -0
  75. data/lib/generators/beyond_canvas/webpacker/templates/beyond_canvas.scss +1 -0
  76. data/lib/generators/beyond_canvas/webpacker/webpacker_generator.rb +26 -0
  77. metadata +93 -69
  78. data/app/assets/javascripts/beyond_canvas.js +0 -3
  79. data/app/assets/javascripts/beyond_canvas/buttons.js +0 -67
  80. data/app/assets/javascripts/beyond_canvas/flash.js +0 -24
  81. data/app/assets/javascripts/beyond_canvas/inputs.js +0 -28
  82. data/app/assets/stylesheets/beyond_canvas.sass +0 -25
  83. data/app/assets/stylesheets/beyond_canvas/components/_actions.sass +0 -5
  84. data/app/assets/stylesheets/beyond_canvas/components/_buttons.sass +0 -86
  85. data/app/assets/stylesheets/beyond_canvas/components/_cards.sass +0 -26
  86. data/app/assets/stylesheets/beyond_canvas/components/_comments.sass +0 -5
  87. data/app/assets/stylesheets/beyond_canvas/components/_flash.sass +0 -51
  88. data/app/assets/stylesheets/beyond_canvas/components/_forms.sass +0 -32
  89. data/app/assets/stylesheets/beyond_canvas/components/_inputs.sass +0 -79
  90. data/app/assets/stylesheets/beyond_canvas/components/_layouts.sass +0 -5
  91. data/app/assets/stylesheets/beyond_canvas/components/_links.sass +0 -13
  92. data/app/assets/stylesheets/beyond_canvas/components/_main.sass +0 -28
  93. data/app/assets/stylesheets/beyond_canvas/components/_margins.sass +0 -7
  94. data/app/assets/stylesheets/beyond_canvas/components/_markdown.sass +0 -60
  95. data/app/assets/stylesheets/beyond_canvas/components/_notices.sass +0 -41
  96. data/app/assets/stylesheets/beyond_canvas/components/_relative.sass +0 -2
  97. data/app/assets/stylesheets/beyond_canvas/components/_spinner.sass +0 -38
  98. data/app/assets/stylesheets/beyond_canvas/components/_tables.sass +0 -25
  99. data/app/assets/stylesheets/beyond_canvas/components/_texts.sass +0 -6
  100. data/app/assets/stylesheets/beyond_canvas/mailer.sass +0 -5
  101. data/app/assets/stylesheets/beyond_canvas/settings/_typography.sass +0 -53
  102. data/app/assets/stylesheets/beyond_canvas/settings/_variables.sass +0 -145
  103. data/app/assets/stylesheets/beyond_canvas/utilities/_mixins.sass +0 -19
  104. data/app/views/beyond_canvas/custom/_public_head.html.slim +0 -0
  105. data/app/views/beyond_canvas/locales/_edit.html.slim +0 -6
  106. data/app/views/beyond_canvas/shared/_flash.html.slim +0 -6
  107. data/app/views/beyond_canvas/shared/_head.html.slim +0 -20
  108. data/app/views/beyond_canvas/shared/_logo.html.slim +0 -2
  109. data/app/views/layouts/beyond_canvas/public.html.slim +0 -12
  110. data/config/initializers/beyond_canvas/assets.rb +0 -5
  111. data/lib/generators/templates/beyond_canvas.rb +0 -20
@@ -0,0 +1,15 @@
1
+ /// Replace `$search` with `$replace` in `$string`
2
+ /// @author Hugo Giraudel
3
+ /// @param {String} $string - Initial string
4
+ /// @param {String} $search - Substring to replace
5
+ /// @param {String} $replace ('') - New value
6
+ /// @return {String} - Updated string
7
+ @function str-replace($string, $search, $replace: '') {
8
+ $index: str-index($string, $search);
9
+
10
+ @if $index {
11
+ @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
12
+ }
13
+
14
+ @return $string;
15
+ }
@@ -0,0 +1,24 @@
1
+ @mixin background-color-darken($color, $percent) {
2
+ background-color: $color;
3
+ transition: $main-transition;
4
+
5
+ &:hover {
6
+ background-color: darken($color, $percent);
7
+ transition: $main-transition;
8
+ }
9
+ }
10
+
11
+ @mixin color-darken($color, $percent) {
12
+ color: $color;
13
+ transition: $main-transition;
14
+
15
+ &:hover {
16
+ color: darken($color, $percent);
17
+ transition: $main-transition;
18
+ }
19
+ }
20
+
21
+ @mixin background-color-lighten($color, $percent) {
22
+ background-color: lighten($color, $percent);
23
+ transition: $main-transition;
24
+ }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BeyondCanvas
4
- class ApplicationController < ActionController::Base
4
+ class ApplicationController < ActionController::Base # :nodoc:
5
5
  protect_from_forgery with: :exception
6
6
 
7
7
  include ::BeyondCanvas::StatusCodes
@@ -3,7 +3,7 @@
3
3
  require_dependency 'beyond_canvas/application_controller'
4
4
 
5
5
  module BeyondCanvas
6
- class SystemController < ApplicationController
6
+ class SystemController < ApplicationController # :nodoc:
7
7
  include ::BeyondCanvas::LocaleManagement
8
8
 
9
9
  def update_locale
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BeyondCanvas
4
- module LocaleManagement
4
+ module LocaleManagement # :nodoc:
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- around_action :switch_locale, except: :update_locale
8
+ around_action :switch_locale, except: :update_locale # rubocop:disable Rails/LexicallyScopedActionFilter
9
9
  end
10
10
 
11
11
  private
@@ -16,8 +16,8 @@ module BeyondCanvas
16
16
  #
17
17
  def switch_locale(&action)
18
18
  # NOTE: Check the HTTP_ACCEPT_LANGUAGE header to identify if the request comes from a browser or a server
19
- return I18n.with_locale(I18n.default_locale, &action) if request.headers['HTTP_ACCEPT_LANGUAGE'].blank?
20
-
19
+ return I18n.with_locale(I18n.default_locale, &action) if request.headers['HTTP_ACCEPT_LANGUAGE'].blank?
20
+
21
21
  unless valid_locale?(cookies[:locale])
22
22
  cookies[:locale] = { value: browser_compatible_locale, expires: 1.day.from_now }
23
23
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BeyondCanvas
2
- module RequestValidation
4
+ module RequestValidation # :nodoc:
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  private
@@ -12,10 +14,10 @@ module BeyondCanvas
12
14
 
13
15
  def app_installation_params?
14
16
  if params[:code].nil? ||
15
- params[:signature].nil? ||
16
- params[:return_url].nil? ||
17
- params[:api_url].nil? ||
18
- params[:access_token_url].nil?
17
+ params[:signature].nil? ||
18
+ params[:return_url].nil? ||
19
+ params[:api_url].nil? ||
20
+ params[:access_token_url].nil?
19
21
  false
20
22
  else
21
23
  true
@@ -29,7 +31,7 @@ module BeyondCanvas
29
31
  def valid_signature?(signature, data, secret)
30
32
  digest = OpenSSL::Digest.new('SHA1')
31
33
  hmac = OpenSSL::HMAC.digest(digest, secret, data)
32
- signature == Base64.encode64(hmac).chop
34
+ URI.decode(signature) == Base64.encode64(hmac).chop
33
35
  end
34
36
  end
35
37
  end
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BeyondCanvas
2
- module StatusCodes
4
+ module StatusCodes # :nodoc:
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  private
6
8
 
7
9
  def bad_request
8
- raise ActionController::BadRequest.new 'Bad Request'
10
+ raise ActionController::BadRequest, 'Bad Request'
9
11
  end
10
12
 
11
13
  def not_found
12
- raise ActionController::RoutingError.new 'Not Found'
14
+ raise ActionController::RoutingError, 'Not Found'
13
15
  end
14
16
  end
15
17
  end
@@ -1,23 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BeyondCanvas
4
- class FormBuilder < ActionView::Helpers::FormBuilder
4
+ class FormBuilder < ActionView::Helpers::FormBuilder # :nodoc:
5
+ ############################################################################
6
+ # Wrappers
7
+ ############################################################################
8
+
5
9
  def field_wrapper(attribute, args, &block)
6
- label = args[:label].present? ? args[:label] : attribute.to_s.humanize
10
+ label = args[:label] == false ? nil : args[:label].presence || attribute.to_s.humanize
7
11
 
8
12
  errors = object.errors[attribute].join(', ') if object.respond_to?(:errors) && object.errors.include?(attribute)
9
13
 
10
14
  @template.content_tag(:div, class: 'form__row') do
11
15
  @template.content_tag(:label, label, class: 'input__label') +
12
- @template.content_tag(:div, class: 'relative') do
13
- block.call +
14
- (@template.content_tag(:label, errors, class: 'input__error') unless errors.blank?)
15
- end +
16
- (@template.content_tag(:div, args[:hint].html_safe, class: 'input__hint') if args[:hint].present?)
16
+ @template.content_tag(:div, class: 'relative') do
17
+ block.call +
18
+ (@template.content_tag(:label, errors, class: 'input__error') if errors.present?)
19
+ end +
20
+ (@template.content_tag(:div, args[:hint].html_safe, class: 'input__hint') if args[:hint].present?)
17
21
  end
18
22
  end
19
23
 
20
- [:email, :text, :number, :password].each do |method|
24
+ def inline_wrapper(attribute, args, &block)
25
+ label = args[:label] == false ? nil : args[:label].presence || attribute.to_s.humanize
26
+
27
+ errors = object.errors[attribute].join(', ') if object.respond_to?(:errors) && object.errors.include?(attribute)
28
+
29
+ @template.content_tag(:div, class: 'form__row') do
30
+ @template.content_tag(:div, class: 'relative', style: 'display: flex; align-items: center;') do
31
+ block.call +
32
+ @template.content_tag(:div) do
33
+ @template.content_tag(:label, label, class: 'input__label') +
34
+ (@template.content_tag(:div, args[:hint].html_safe, class: 'input__hint') if args[:hint].present?)
35
+ end +
36
+ (@template.content_tag(:label, errors, class: 'input__error') if errors.present?)
37
+ end
38
+ end
39
+ end
40
+
41
+ %i[email text number password].each do |method|
21
42
  define_method :"#{method}_field" do |attribute, args = {}|
22
43
  field_wrapper(attribute, args) do
23
44
  super(attribute, args)
@@ -25,9 +46,39 @@ module BeyondCanvas
25
46
  end
26
47
  end
27
48
 
49
+ def check_box(attribute, args = {})
50
+ inline_wrapper(attribute, args) do
51
+ filed_identifyer = filed_identifyer(attribute)
52
+
53
+ args.merge!(id: filed_identifyer)
54
+ .merge!(hidden: true)
55
+
56
+ @template.content_tag(:div, class: 'input__checkbox') do
57
+ super(attribute, args) +
58
+ @template.content_tag(:label, nil, class: 'input__checkbox__control', for: filed_identifyer)
59
+ end
60
+ end
61
+ end
62
+
63
+ def radio_button(attribute, value, args = {})
64
+ args.merge!(label: value) unless args[:label]
65
+
66
+ inline_wrapper(attribute, args) do
67
+ filed_identifyer = filed_identifyer(attribute)
68
+
69
+ args.merge!(id: filed_identifyer)
70
+ .merge!(hidden: true)
71
+
72
+ @template.content_tag(:div, class: 'input__radio') do
73
+ super(attribute, value, args) +
74
+ @template.content_tag(:label, nil, class: 'input__radio__control', for: filed_identifyer)
75
+ end
76
+ end
77
+ end
78
+
28
79
  def file_field(attribute, args = {})
29
80
  field_wrapper(attribute, args) do
30
- filed_identifyer = "#{attribute}_#{(Time.now.to_f * 1000).to_i.to_s}"
81
+ filed_identifyer = filed_identifyer(attribute)
31
82
 
32
83
  args.merge!(id: filed_identifyer)
33
84
  .merge!(hidden: true)
@@ -37,12 +88,22 @@ module BeyondCanvas
37
88
 
38
89
  @template.content_tag(:div, class: 'input__file') do
39
90
  super(attribute, args) +
40
- @template.content_tag(:label, for: filed_identifyer, class: 'input__file__label button__transparent--primary') do
41
- args[:data][:button_text] || 'Choose file'
42
- end +
43
- @template.content_tag(:span, args[:data][:no_file_text] || 'No file chosen', class: "input__file__text #{filed_identifyer}")
91
+ @template.content_tag(:label,
92
+ for: filed_identifyer,
93
+ class: 'input__file__control button__transparent--primary') do
94
+ args[:data][:button_text] || 'Choose file'
95
+ end +
96
+ @template.content_tag(:span,
97
+ args[:data][:no_file_text] || 'No file chosen',
98
+ class: "input__file__text #{filed_identifyer}")
44
99
  end
45
100
  end
46
101
  end
102
+
103
+ private
104
+
105
+ def filed_identifyer(attribute)
106
+ "#{attribute}_#{DateTime.now.strftime('%Q') + rand(10_000).to_s}"
107
+ end
47
108
  end
48
109
  end
@@ -1,14 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BeyondCanvas
4
- module ApplicationHelper
4
+ module ApplicationHelper # :nodoc:
5
5
  def full_title(page_title = '')
6
- if I18n.exists?('app_name')
7
- base_title = I18n.t('app_name')
8
- else
9
- logger.debug "[BeyondCanvas] Missing translation: #{I18n.locale}.app_name".yellow
10
- base_title = File.basename(Rails.root).humanize
11
- end
6
+ base_title = BeyondCanvas.configuration.site_title
12
7
 
13
8
  page_title.empty? ? base_title : page_title + ' | ' + base_title
14
9
  end
@@ -27,7 +22,7 @@ module BeyondCanvas
27
22
  end
28
23
  end
29
24
 
30
- [:success, :info, :warning, :error].each do |method|
25
+ %i[success info warning error].each do |method|
31
26
  define_method :"notice_#{method}" do |name = nil, html_options = nil, &block|
32
27
  notice_render(method, name, html_options, &block)
33
28
  end
@@ -45,29 +40,33 @@ module BeyondCanvas
45
40
 
46
41
  def get_flash_icon(key)
47
42
  case key
48
- when 'success'
49
- 'fas fa-check'
43
+ when 'success', 'notice'
44
+ inline_svg_tag 'icons/flash_checkbox.svg'
50
45
  when 'info'
51
- 'fas fa-info-circle'
46
+ inline_svg_tag 'icons/flash_info.svg'
52
47
  when 'warning'
53
- 'fas fa-exclamation-circle'
48
+ inline_svg_tag 'icons/flash_warning.svg'
54
49
  when 'error'
55
- 'far fa-times-circle'
50
+ inline_svg_tag 'icons/flash_error.svg'
56
51
  else
57
- 'fas fa-info'
52
+ inline_svg_tag 'icons/flash_info.svg'
58
53
  end
59
54
  end
60
55
 
61
56
  def notice_render(method, name = nil, html_options = nil, &block)
62
- html_options, name = name, block if block_given?
57
+ if block_given?
58
+ html_options = name
59
+ name = block
60
+ end
63
61
 
64
62
  html_options ||= {}
65
63
 
66
- html_options.merge!(class: "notice notice--#{method}") { |key, old_val, new_val| [new_val, old_val].join(' ') }
64
+ html_options.merge!(class: "notice notice--#{method}") { |_key, old_val, new_val| [new_val, old_val].join(' ') }
67
65
 
68
66
  content_tag('div', html_options) do
69
- content_tag('i', nil, class: "notice__icon #{get_flash_icon(method.to_s)}") +
70
- content_tag('span', block_given? ? capture(&name) : name, class: 'notice__content')
67
+ content_tag('div', class: 'notice__icon') do
68
+ get_flash_icon(method.to_s)
69
+ end + content_tag('span', block_given? ? capture(&name) : name, class: 'notice__content')
71
70
  end
72
71
  end
73
72
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BeyondCanvas
4
- module LocaleSwitchHelper
4
+ module LocaleSwitchHelper # :nodoc:
5
5
  def translate_locale(locale)
6
6
  if I18n.exists?("locales.#{locale}")
7
7
  I18n.t("locales.#{locale}")
@@ -0,0 +1,3 @@
1
+ import './initializers/buttons';
2
+ import './initializers/flash';
3
+ import './initializers/inputs';
@@ -0,0 +1,54 @@
1
+ import { disableActionElements, enableActionElements, hideSpinner, showSpinner } from './functions';
2
+
3
+ (function ($) {
4
+ const onDOMReady = function () {
5
+ const inputs = $('input, textarea, select').not(':input[type=button], :input[type=submit], :input[type=reset]');
6
+
7
+ inputs.each(function () {
8
+ var input = $(this);
9
+
10
+ input.bind('invalid', function (e) {
11
+ if ($(input).is(':hidden')) {
12
+ e.preventDefault();
13
+ }
14
+ hideSpinner();
15
+ enableActionElements();
16
+ });
17
+ });
18
+
19
+ $('button[class^="button"]').each(function () {
20
+ var button = $(this);
21
+
22
+ // Add width attribute and save old width
23
+ button.width(button.width());
24
+ button.data('oldWidth', button.width());
25
+
26
+ // Add the spinner
27
+ button.prepend(`
28
+ <div class="spinner">
29
+ <div class="bounce1"></div>
30
+ <div class="bounce2"></div>
31
+ <div class="bounce3"></div>
32
+ </div>`);
33
+
34
+ // Bind ajax:success and ajax:error to the form the button belongs to
35
+ button
36
+ .closest('form')
37
+ .on('ajax:success', function () {
38
+ hideSpinner();
39
+ enableActionElements();
40
+ })
41
+ .on('ajax:error', function () {
42
+ hideSpinner();
43
+ enableActionElements();
44
+ });
45
+ });
46
+ };
47
+
48
+ $(document).on('click', '[class^="button"]', function () {
49
+ disableActionElements();
50
+ showSpinner($(this));
51
+ });
52
+
53
+ $(document).on('ready page:load turbolinks:load', onDOMReady);
54
+ })(jQuery);
@@ -0,0 +1,19 @@
1
+ import { closeAlert } from './functions';
2
+
3
+ (function ($) {
4
+ const onDOMReady = function () {
5
+ $('.flash').each(function () {
6
+ $(this).css('right', -$(this).width() + 'px');
7
+ });
8
+
9
+ setTimeout(function () {
10
+ $('.flash').addClass('flash--shown');
11
+ }, 100);
12
+ };
13
+
14
+ $(document).on('click', '.flash', function () {
15
+ closeAlert();
16
+ });
17
+
18
+ $(document).on('ready page:load turbolinks:load', onDOMReady);
19
+ })(jQuery);
@@ -0,0 +1,41 @@
1
+ const SPINNER_ANIMATION_TIMEOUT = 125;
2
+
3
+ export function showSpinner(button) {
4
+ // Adjust the width of the button
5
+ button.width(button.width() + $('.spinner').outerWidth(true));
6
+ // Show the spinner
7
+ setTimeout(function () {
8
+ button.find('.spinner').css('display', 'flex');
9
+ }, SPINNER_ANIMATION_TIMEOUT);
10
+ }
11
+
12
+ export function hideSpinner() {
13
+ $('button[class^="button"]').each(function (_, button) {
14
+ setTimeout(function () {
15
+ // Hide the spinner
16
+ $(button).find('.spinner').hide();
17
+ // Adjust the width of the button
18
+ $(button).width($(button).data('oldWidth'));
19
+ }, SPINNER_ANIMATION_TIMEOUT);
20
+ });
21
+ }
22
+
23
+ export function disableActionElements() {
24
+ $('a, input[type="submit"], input[type="button"], input[type="reset"], button').each(function (_, button) {
25
+ $(button).addClass('actions--disabled');
26
+ });
27
+ }
28
+ export function enableActionElements() {
29
+ $('a, input[type="submit"], input[type="button"], input[type="reset"], button').each(function (_, button) {
30
+ $(button).removeClass('actions--disabled');
31
+ });
32
+ }
33
+
34
+ export function closeAlert() {
35
+ $('.flash')
36
+ .removeClass('flash--shown')
37
+ .delay(700)
38
+ .queue(function () {
39
+ $(this).remove();
40
+ });
41
+ }