beyond_canvas 0.16.2.pre → 0.17.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/beyond_canvas_manifest.js +1 -0
  3. data/app/assets/images/icons/arrow_right.svg +1 -0
  4. data/app/assets/images/icons/close.svg +1 -0
  5. data/app/assets/images/icons/home.svg +1 -0
  6. data/app/assets/javascripts/beyond_canvas/base.js +120 -246
  7. data/app/assets/stylesheets/beyond_canvas/base.scss +8 -1
  8. data/app/assets/stylesheets/beyond_canvas/components/_action_bar.scss +28 -0
  9. data/app/assets/stylesheets/beyond_canvas/components/_breadcrumbs.scss +29 -0
  10. data/app/assets/stylesheets/beyond_canvas/components/_buttons.scss +1 -1
  11. data/app/assets/stylesheets/beyond_canvas/components/_debug.scss +10 -0
  12. data/app/assets/stylesheets/beyond_canvas/components/_forms.scss +11 -14
  13. data/app/assets/stylesheets/beyond_canvas/components/_main.scss +12 -13
  14. data/app/assets/stylesheets/beyond_canvas/components/_margins.scss +8 -0
  15. data/app/assets/stylesheets/beyond_canvas/components/_menu.scss +40 -0
  16. data/app/assets/stylesheets/beyond_canvas/components/_modals.scss +27 -0
  17. data/app/assets/stylesheets/beyond_canvas/components/_sidebar.scss +53 -0
  18. data/app/assets/stylesheets/beyond_canvas/components/_titles.scss +7 -0
  19. data/app/assets/stylesheets/beyond_canvas/settings/_variables.scss +64 -9
  20. data/app/controllers/beyond_canvas/application_controller.rb +2 -0
  21. data/app/controllers/beyond_canvas/authentications_controller.rb +37 -30
  22. data/app/controllers/concerns/beyond_canvas/authentication.rb +1 -12
  23. data/app/controllers/concerns/beyond_canvas/locale_management.rb +5 -4
  24. data/app/helpers/beyond_canvas/authentications_helper.rb +28 -0
  25. data/app/helpers/beyond_canvas/cockpit_app_helper.rb +17 -0
  26. data/app/helpers/beyond_canvas/debug_helper.rb +9 -0
  27. data/app/helpers/beyond_canvas/locale_switch_helper.rb +5 -1
  28. data/app/javascript/beyond_canvas/base.js +3 -0
  29. data/app/javascript/beyond_canvas/initializers/buttons.js +65 -19
  30. data/app/javascript/beyond_canvas/initializers/flash.js +9 -2
  31. data/app/javascript/beyond_canvas/initializers/inputs.js +4 -1
  32. data/app/javascript/beyond_canvas/initializers/modals.js +14 -0
  33. data/app/views/beyond_canvas/authentications/new.html.erb +19 -10
  34. data/app/views/beyond_canvas/shared/_action_bar.html.erb +15 -0
  35. data/app/views/beyond_canvas/shared/_breadcrumbs.html.erb +14 -0
  36. data/app/views/beyond_canvas/shared/_flash.html.erb +22 -12
  37. data/app/views/beyond_canvas/shared/_locales.html.erb +8 -0
  38. data/app/views/beyond_canvas/shared/_menu.html.erb +31 -0
  39. data/app/views/beyond_canvas/shared/_modal.html.erb +6 -0
  40. data/app/views/beyond_canvas/shared/_sidebar.html.erb +16 -0
  41. data/app/views/layouts/beyond_canvas/application.html.erb +31 -0
  42. data/app/views/layouts/beyond_canvas/public.html.erb +11 -4
  43. data/config/locales/en.yml +5 -0
  44. data/config/routes.rb +5 -4
  45. data/lib/beyond_canvas.rb +12 -12
  46. data/lib/beyond_canvas/configuration.rb +11 -6
  47. data/lib/beyond_canvas/engine.rb +4 -2
  48. data/lib/beyond_canvas/menu_item_registration.rb +19 -0
  49. data/lib/beyond_canvas/parameter_sanitizer.rb +1 -1
  50. data/lib/beyond_canvas/rails/routes.rb +8 -7
  51. data/lib/beyond_canvas/version.rb +1 -1
  52. data/lib/generators/beyond_canvas/controller/controller_generator.rb +1 -2
  53. data/lib/generators/beyond_canvas/controller/templates/controller.erb +2 -19
  54. data/lib/generators/beyond_canvas/custom_menu/custom_menu_generator.rb +13 -0
  55. data/lib/generators/beyond_canvas/custom_menu/templates/beyond_canvas_custom_menu.html.erb +32 -0
  56. data/lib/generators/beyond_canvas/custom_styles/custom_styles_generator.rb +1 -1
  57. data/lib/generators/beyond_canvas/custom_styles/templates/beyond_canvas_custom_styles.scss +55 -9
  58. data/lib/generators/beyond_canvas/install/install_generator.rb +3 -5
  59. data/lib/generators/beyond_canvas/install/templates/beyond_canvas.rb.erb +51 -13
  60. data/lib/generators/beyond_canvas/{auth_model/auth_model_generator.rb → model/model_generator.rb} +4 -5
  61. data/lib/generators/beyond_canvas/{auth_model → model}/templates/migration.erb +2 -4
  62. data/lib/generators/beyond_canvas/{auth_model → model}/templates/model.erb +0 -0
  63. data/lib/generators/beyond_canvas/views/views_generator.rb +4 -6
  64. data/lib/models/concerns/authentication.rb +57 -0
  65. data/lib/models/concerns/utils.rb +79 -0
  66. data/lib/models/shop.rb +12 -0
  67. metadata +69 -30
  68. data/app/controllers/concerns/beyond_canvas/resource_management.rb +0 -33
  69. data/app/javascript/beyond_canvas/initializers/functions.js +0 -41
  70. data/app/views/beyond_canvas/locales/_edit.html.erb +0 -8
  71. data/lib/beyond_canvas/models/authentication.rb +0 -66
  72. data/lib/beyond_canvas/models/shop.rb +0 -28
  73. data/lib/beyond_canvas/models/utils.rb +0 -55
@@ -3,22 +3,11 @@
3
3
  module BeyondCanvas
4
4
  module Authentication # :nodoc:
5
5
  extend ActiveSupport::Concern
6
- AUTH_RESOURCE = BeyondCanvas.auth_model
7
-
8
- class_eval <<-METHODS, __FILE__, __LINE__ + 1
9
- def current_#{AUTH_RESOURCE}
10
- instance_variable_get("@#{AUTH_RESOURCE}")
11
- end
12
-
13
- def new_#{AUTH_RESOURCE}_params
14
- beyond_canvas_parameter_sanitizer.sanitize
15
- end
16
- METHODS
17
6
 
18
7
  private
19
8
 
20
9
  def beyond_canvas_parameter_sanitizer
21
- @beyond_canvas_parameter_sanitizer ||= BeyondCanvas::ParameterSanitizer.new(AUTH_RESOURCE, params)
10
+ @beyond_canvas_parameter_sanitizer ||= BeyondCanvas::ParameterSanitizer.new(:shop, params)
22
11
  end
23
12
  end
24
13
  end
@@ -15,16 +15,13 @@ module BeyondCanvas
15
15
  # browser compatible locale, sets the value to the cookie and set that locale as default locale.
16
16
  #
17
17
  def switch_locale(&action)
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
-
21
18
  unless valid_locale?(cookies[:locale])
22
19
  cookies[:locale] = { value: browser_compatible_locale, expires: 1.day.from_now }
23
20
  end
24
21
 
25
22
  I18n.with_locale(cookies[:locale], &action)
26
23
 
27
- logger.debug "[BeyondCanvas] Locale set to: #{cookies[:locale]}".yellow
24
+ logger.debug "[BeyondCanvas] Locale set to: #{cookies[:locale]}".yellow if debug_mode?
28
25
  end
29
26
 
30
27
  #
@@ -36,12 +33,16 @@ module BeyondCanvas
36
33
  # +I18n.default_locale+. (e.g. +'en-GB'+)
37
34
  #
38
35
  def browser_compatible_locale
36
+ return I18n.default_locale if request.headers['HTTP_ACCEPT_LANGUAGE'].blank?
37
+
39
38
  browser_locales = HTTP::Accept::Languages.parse(request.headers['HTTP_ACCEPT_LANGUAGE'])
40
39
  available_locales = HTTP::Accept::Languages::Locales.new(I18n.available_locales.map(&:to_s))
41
40
 
42
41
  locales = available_locales & browser_locales
43
42
 
44
43
  locales.empty? ? I18n.default_locale : locales.first
44
+ rescue
45
+ I18n.default_locale
45
46
  end
46
47
 
47
48
  #
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BeyondCanvas
4
+ module AuthenticationsHelper # :nodoc:
5
+ #
6
+ # Logs in the given shop
7
+ #
8
+ def log_in(shop)
9
+ session[:shop_id] = shop.id
10
+ end
11
+
12
+ #
13
+ # Returns the current logged-in shop (if any)
14
+ #
15
+ def current_shop
16
+ if session[:shop_id]
17
+ @current_shop ||= Shop.find_by(id: session[:shop_id])
18
+ end
19
+ end
20
+
21
+ #
22
+ # Returns true if the shop is logged in, false otherwise
23
+ #
24
+ def logged_in?
25
+ !current_shop.nil?
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BeyondCanvas
4
+ module CockpitAppHelper # :nodoc:
5
+ def is_cockpit_app?
6
+ BeyondCanvas.configuration.cockpit_app == true
7
+ end
8
+
9
+ def action_bar_content?
10
+ content_for?(:action_bar_left) || content_for?(:action_bar_right)
11
+ end
12
+
13
+ def menu_content?
14
+ BeyondCanvas.configuration.menu_items.any?
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BeyondCanvas
4
+ module DebugHelper # :nodoc:
5
+ def debug_mode?
6
+ Rails.env.development? && BeyondCanvas.configuration.debug_mode
7
+ end
8
+ end
9
+ end
@@ -2,11 +2,15 @@
2
2
 
3
3
  module BeyondCanvas
4
4
  module LocaleSwitchHelper # :nodoc:
5
+ def show_locale_switch?
6
+ defined?(I18n) && I18n.available_locales.count > 1
7
+ end
8
+
5
9
  def translate_locale(locale)
6
10
  if I18n.exists?("locales.#{locale}")
7
11
  I18n.t("locales.#{locale}")
8
12
  else
9
- logger.debug "[BeyondCanvas] Missing translation: #{I18n.locale}.locales.#{locale}".yellow
13
+ logger.debug "[BeyondCanvas] Missing translation: #{I18n.locale}.locales.#{locale}".yellow if debug_mode?
10
14
  locale
11
15
  end
12
16
  end
@@ -1,3 +1,6 @@
1
+ import 'jquery';
2
+
1
3
  import './initializers/buttons';
2
4
  import './initializers/flash';
3
5
  import './initializers/inputs';
6
+ import './initializers/modals';
@@ -1,8 +1,11 @@
1
- import { disableActionElements, enableActionElements, hideSpinner, showSpinner } from './functions';
1
+ const SPINNER_ANIMATION_TIMEOUT = 125;
2
+ const BUTTON_SELECTORS = '[class^="button"]';
2
3
 
3
4
  (function ($) {
4
- const onDOMReady = function () {
5
- const inputs = $('input, textarea, select').not(':input[type=button], :input[type=submit], :input[type=reset]');
5
+ const onDOMReady = function (e) {
6
+ const inputs = $('input, textarea, select').not(
7
+ ':input[type=button], :input[type=submit], :input[type=reset]'
8
+ );
6
9
 
7
10
  inputs.each(function () {
8
11
  var input = $(this);
@@ -11,12 +14,11 @@ import { disableActionElements, enableActionElements, hideSpinner, showSpinner }
11
14
  if ($(input).is(':hidden')) {
12
15
  e.preventDefault();
13
16
  }
14
- hideSpinner();
15
- enableActionElements();
17
+ $.restoreActionElements();
16
18
  });
17
19
  });
18
20
 
19
- $('button[class^="button"]').each(function () {
21
+ $(BUTTON_SELECTORS).each(function () {
20
22
  var button = $(this);
21
23
 
22
24
  // Add width attribute and save old width
@@ -24,31 +26,75 @@ import { disableActionElements, enableActionElements, hideSpinner, showSpinner }
24
26
  button.data('oldWidth', button.width());
25
27
 
26
28
  // 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>`);
29
+ if (button.find('.spinner').length == 0) {
30
+ button.prepend(`
31
+ <div class="spinner">
32
+ <div class="bounce1"></div>
33
+ <div class="bounce2"></div>
34
+ <div class="bounce3"></div>
35
+ </div>`);
36
+ }
33
37
 
34
38
  // Bind ajax:success and ajax:error to the form the button belongs to
35
39
  button
36
40
  .closest('form')
37
41
  .on('ajax:success', function () {
38
- hideSpinner();
39
- enableActionElements();
42
+ $.restoreActionElements();
40
43
  })
41
44
  .on('ajax:error', function () {
42
- hideSpinner();
43
- enableActionElements();
45
+ $.restoreActionElements();
44
46
  });
45
47
  });
46
48
  };
47
49
 
48
- $(document).on('click', '[class^="button"]', function () {
49
- disableActionElements();
50
- showSpinner($(this));
50
+ $(document).on('confirm:complete', function () {
51
+ $.restoreActionElements();
52
+ });
53
+
54
+ $(document).on('click', BUTTON_SELECTORS, function () {
55
+ $.disableActionElements();
56
+ $(this).showSpinner();
51
57
  });
52
58
 
53
59
  $(document).on('ready page:load turbolinks:load', onDOMReady);
54
60
  })(jQuery);
61
+
62
+ $.extend({
63
+ restoreActionElements: function () {
64
+ // Hide spinners
65
+ $(BUTTON_SELECTORS).each(function (_, button) {
66
+ setTimeout(function () {
67
+ // Hide the spinner
68
+ $(button).find('.spinner').hide();
69
+ // Adjust the width of the button
70
+ $(button).width($(button).data('oldWidth'));
71
+ }, SPINNER_ANIMATION_TIMEOUT);
72
+ });
73
+
74
+ // Enable action elements
75
+ $('a, input[type="submit"], input[type="button"], input[type="reset"], button').each(function () {
76
+ $(this).removeClass('actions--disabled');
77
+ });
78
+ },
79
+ disableActionElements: function () {
80
+ $('a, input[type="submit"], input[type="button"], input[type="reset"], button').each(function () {
81
+ $(this).addClass('actions--disabled');
82
+ });
83
+ }
84
+ });
85
+
86
+ $.fn.extend({
87
+ showSpinner: function () {
88
+ var button = $(this);
89
+
90
+ // Adjust the width of the button
91
+ button.width(
92
+ button.width() + $('.spinner').outerWidth(true)
93
+ );
94
+
95
+ // Show the spinner
96
+ setTimeout(function () {
97
+ button.find('.spinner').css('display', 'inline-flex');
98
+ }, SPINNER_ANIMATION_TIMEOUT);
99
+ }
100
+ });
@@ -1,5 +1,3 @@
1
- import { closeAlert } from './functions';
2
-
3
1
  (function ($) {
4
2
  const onDOMReady = function () {
5
3
  $('.flash').each(function () {
@@ -17,3 +15,12 @@ import { closeAlert } from './functions';
17
15
 
18
16
  $(document).on('ready page:load turbolinks:load', onDOMReady);
19
17
  })(jQuery);
18
+
19
+ function closeAlert() {
20
+ $('.flash')
21
+ .removeClass('flash--shown')
22
+ .delay(700)
23
+ .queue(function () {
24
+ $(this).remove();
25
+ });
26
+ }
@@ -9,7 +9,10 @@
9
9
  var fileName = '';
10
10
 
11
11
  if (this.files && this.files.length > 1)
12
- fileName = (this.getAttribute('data-multiple-caption') || '').replace('{count}', this.files.length);
12
+ fileName = (this.getAttribute('data-multiple-caption') || '').replace(
13
+ '{count}',
14
+ this.files.length
15
+ );
13
16
  else if (e.target.value) fileName = e.target.value.split('\\').pop();
14
17
 
15
18
  if (fileName)
@@ -0,0 +1,14 @@
1
+ $.extend({
2
+ displayModal: function (content, options = {}) {
3
+ $('#modal').find('#modal__content').html(content);
4
+ $('#modal').css('display', 'flex');
5
+ $.restoreActionElements();
6
+ $(document).trigger('modal:opened', options['extraEventParameters']);
7
+ },
8
+ closeModal: function () {
9
+ $('#modal').find('#modal__content').empty();
10
+ $('#modal').css('display', 'none');
11
+ $.restoreActionElements();
12
+ $(document).trigger('modal:closed');
13
+ }
14
+ });
@@ -1,17 +1,26 @@
1
- <div class='card card--padding'>
1
+ <% app_name = BeyondCanvas.configuration.site_title %>
2
+ <% i18n_scope = 'beyond_canvas.authentications.new' %>
2
3
 
3
- <%= form_for(resource, as: resource_name) do |f| %>
4
+ <div class="card card--padding">
4
5
 
5
- <h2 class='card__headline'>Install <%= BeyondCanvas.configuration.site_title %> in your shop</h2>
6
+ <%= form_with(url: callback_path, method: :post, scope: :shop, model: @shop, local: true, builder: BeyondCanvas::FormBuilder) do |f| %>
6
7
 
7
- <%= f.hidden_field :code, value: params[:code] || resource.code %>
8
- <%= f.hidden_field :signature, value: params[:signature] || resource.signature %>
9
- <%= f.hidden_field :return_url, value: params[:return_url] || resource.return_url %>
10
- <%= f.hidden_field :api_url, value: params[:api_url] || resource.api_url %>
11
- <%= f.hidden_field :access_token_url, value: params[:access_token_url] || resource.access_token_url %>
8
+ <h2 class="card__headline"><%= I18n.t('headline', app_name: app_name, scope: i18n_scope) %></h2>
12
9
 
13
- <div class='form__actions--spaced'>
14
- <%= f.button 'Save', type: :submit, class: 'button__solid--primary' %>
10
+ <p class="margin--bottom"><%= I18n.t('body', app_name: app_name, scope: i18n_scope) %></p>
11
+
12
+ <%# Don't delete or modify any ot these hidden fields. They are used on shop identification and authentication %>
13
+
14
+ <%= f.hidden_field :code, value: params[:code] || @shop.code %>
15
+ <%= f.hidden_field :signature, value: params[:signature] || @shop.signature %>
16
+ <%= f.hidden_field :return_url, value: params[:return_url] || @shop.return_url %>
17
+ <%= f.hidden_field :api_url, value: params[:api_url] || @shop.api_url %>
18
+ <%= f.hidden_field :access_token_url, value: params[:access_token_url] || @shop.access_token_url %>
19
+
20
+ <%# Add HERE your custom shop fields %>
21
+
22
+ <div class="form__actions--spaced">
23
+ <%= f.button I18n.t('actions.install', scope: i18n_scope), type: :submit, class: 'button__solid--primary' %>
15
24
  </div>
16
25
 
17
26
  <% end %>
@@ -0,0 +1,15 @@
1
+ <% if action_bar_content? %>
2
+
3
+ <div class="action_bar<% if menu_content? %> action_bar--menu<% end %>">
4
+
5
+ <div class="action_bar--left">
6
+ <%= yield :action_bar_left %>
7
+ </div>
8
+
9
+ <div class="action_bar--right">
10
+ <%= yield :action_bar_right %>
11
+ </div>
12
+
13
+ </div>
14
+
15
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <% if is_cockpit_app? %>
2
+
3
+ <div class='breadcrumbs'>
4
+
5
+ <%= inline_svg_tag 'icons/home.svg' %>
6
+
7
+ <% breadcrumb_trail do |crumb| %>
8
+ <%= link_to crumb.name, crumb.url, class: "breadcrumb__item#{ '--current' if crumb.current? }" %>
9
+ <% unless crumb.current? %><%= inline_svg_tag 'icons/arrow_right.svg' %><% end %>
10
+ <% end %>
11
+
12
+ </div>
13
+
14
+ <% end %>
@@ -1,13 +1,23 @@
1
- <% flash.each do |key, value| %>
2
- <div class="flash">
3
- <div class="flash__icon flash__icon--<%= key %>">
4
- <%= get_flash_icon(key) %>
1
+ <div id="flash">
2
+
3
+ <% flash.each do |key, value| %>
4
+
5
+ <div class="flash">
6
+
7
+ <div class="flash__icon flash__icon--<%= key %>">
8
+ <%= get_flash_icon(key) %>
9
+ </div>
10
+
11
+ <div class="flash__message">
12
+ <%= value %>
13
+ </div>
14
+
15
+ <div class="flash__close">
16
+ <%= inline_svg_tag 'icons/flash_close.svg' %>
17
+ </div>
18
+
5
19
  </div>
6
- <div class="flash__message">
7
- <%= value %>
8
- </div>
9
- <div class="flash__close">
10
- <%= inline_svg_tag 'icons/flash_close.svg' %>
11
- </div>
12
- </div>
13
- <% end %>
20
+
21
+ <% end %>
22
+
23
+ </div>
@@ -0,0 +1,8 @@
1
+ <% if show_locale_switch? && !is_cockpit_app? %>
2
+ <%= form_for :system, url: beyond_canvas.update_locale_path, method: :put do |f| %>
3
+ <%= f.select :locale, I18n.available_locales.collect { |l| [translate_locale(l), l] },
4
+ { selected: cookies[:locale] },
5
+ class: 'select--locale',
6
+ onchange: 'this.form.submit()' %>
7
+ <% end %>
8
+ <% end %>
@@ -0,0 +1,31 @@
1
+ <% if menu_content? %>
2
+
3
+ <div class="menu">
4
+
5
+ <div class="menu--left">
6
+ <%= render 'beyond_canvas/shared/logo' %>
7
+ </div>
8
+
9
+ <div class="menu--center">
10
+
11
+ <% BeyondCanvas.configuration.menu_items.each do |menu_item| %>
12
+ <% name, url, options = menu_item.name.to_s, menu_item.url.to_s, menu_item.options %>
13
+
14
+ <% url, external_url = respond_to?(url) ? [send(url), false] : [url, true] %>
15
+ <% name = defined?(I18n) && I18n.exists?(name) ? I18n.t(name) : name %>
16
+
17
+ <% path = Rails.application.routes.recognize_path(url) %>
18
+
19
+ <% options = options.merge(class: 'menu__item--active') { |_key, old_val, new_val| [new_val, old_val].join(' ') if !external_url && path[:controller] == params[:controller] } %>
20
+ <% options = options.merge(class: 'menu__item') { |_key, old_val, new_val| [new_val, old_val].join(' ') } %>
21
+
22
+ <%= link_to name, url, options %>
23
+ <% end %>
24
+
25
+ </div>
26
+
27
+ <div class="menu--right"></div>
28
+
29
+ </div>
30
+
31
+ <% end %>