solidus_admin 0.0.0 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +7 -0
  3. data/README.md +31 -0
  4. data/Rakefile +21 -0
  5. data/app/assets/config/solidus_admin_manifest.js +4 -0
  6. data/app/assets/images/solidus_admin/.keep +0 -0
  7. data/app/assets/images/solidus_admin/arrow_down_s_fill_gray_700.svg +3 -0
  8. data/app/assets/images/solidus_admin/arrow_down_s_fill_red_400.svg +3 -0
  9. data/app/assets/images/solidus_admin/arrow_right_up_line.svg +5 -0
  10. data/app/assets/images/solidus_admin/favicon.ico +0 -0
  11. data/app/assets/images/solidus_admin/remixicon.symbol.svg +11 -0
  12. data/app/assets/stylesheets/solidus_admin/application.css +3 -0
  13. data/app/assets/stylesheets/solidus_admin/application.tailwind.css.erb +35 -0
  14. data/app/components/solidus_admin/base_component.rb +42 -0
  15. data/app/components/solidus_admin/feedback/component.html.erb +11 -0
  16. data/app/components/solidus_admin/feedback/component.rb +4 -0
  17. data/app/components/solidus_admin/feedback/component.yml +5 -0
  18. data/app/components/solidus_admin/orders/index/component.html.erb +31 -0
  19. data/app/components/solidus_admin/orders/index/component.rb +118 -0
  20. data/app/components/solidus_admin/orders/index/component.yml +13 -0
  21. data/app/components/solidus_admin/products/index/component.html.erb +30 -0
  22. data/app/components/solidus_admin/products/index/component.rb +126 -0
  23. data/app/components/solidus_admin/products/index/component.yml +13 -0
  24. data/app/components/solidus_admin/products/show/component.html.erb +149 -0
  25. data/app/components/solidus_admin/products/show/component.js +9 -0
  26. data/app/components/solidus_admin/products/show/component.rb +26 -0
  27. data/app/components/solidus_admin/products/show/component.yml +17 -0
  28. data/app/components/solidus_admin/products/status/component.rb +31 -0
  29. data/app/components/solidus_admin/products/status/component.yml +3 -0
  30. data/app/components/solidus_admin/sidebar/account_nav/component.html.erb +67 -0
  31. data/app/components/solidus_admin/sidebar/account_nav/component.rb +15 -0
  32. data/app/components/solidus_admin/sidebar/account_nav/component.yml +3 -0
  33. data/app/components/solidus_admin/sidebar/component.html.erb +39 -0
  34. data/app/components/solidus_admin/sidebar/component.js +14 -0
  35. data/app/components/solidus_admin/sidebar/component.rb +21 -0
  36. data/app/components/solidus_admin/sidebar/component.yml +2 -0
  37. data/app/components/solidus_admin/sidebar/item/component.html.erb +26 -0
  38. data/app/components/solidus_admin/sidebar/item/component.rb +27 -0
  39. data/app/components/solidus_admin/skip_link/component.rb +24 -0
  40. data/app/components/solidus_admin/skip_link/component.yml +2 -0
  41. data/app/components/solidus_admin/ui/badge/component.rb +34 -0
  42. data/app/components/solidus_admin/ui/button/component.rb +101 -0
  43. data/app/components/solidus_admin/ui/forms/checkbox/component.rb +42 -0
  44. data/app/components/solidus_admin/ui/forms/field/component.html.erb +28 -0
  45. data/app/components/solidus_admin/ui/forms/field/component.rb +72 -0
  46. data/app/components/solidus_admin/ui/forms/input/component.js +16 -0
  47. data/app/components/solidus_admin/ui/forms/input/component.rb +99 -0
  48. data/app/components/solidus_admin/ui/forms/switch/component.rb +47 -0
  49. data/app/components/solidus_admin/ui/icon/component.rb +25 -0
  50. data/app/components/solidus_admin/ui/icon/names.txt +2494 -0
  51. data/app/components/solidus_admin/ui/panel/component.html.erb +36 -0
  52. data/app/components/solidus_admin/ui/panel/component.js +14 -0
  53. data/app/components/solidus_admin/ui/panel/component.rb +19 -0
  54. data/app/components/solidus_admin/ui/panel/component.yml +4 -0
  55. data/app/components/solidus_admin/ui/tab/component.rb +43 -0
  56. data/app/components/solidus_admin/ui/table/component.html.erb +170 -0
  57. data/app/components/solidus_admin/ui/table/component.js +118 -0
  58. data/app/components/solidus_admin/ui/table/component.rb +150 -0
  59. data/app/components/solidus_admin/ui/table/component.yml +11 -0
  60. data/app/components/solidus_admin/ui/table/pagination/component.html.erb +28 -0
  61. data/app/components/solidus_admin/ui/table/pagination/component.rb +14 -0
  62. data/app/components/solidus_admin/ui/table/pagination/component.yml +3 -0
  63. data/app/components/solidus_admin/ui/toast/component.html.erb +26 -0
  64. data/app/components/solidus_admin/ui/toast/component.js +17 -0
  65. data/app/components/solidus_admin/ui/toast/component.rb +18 -0
  66. data/app/components/solidus_admin/ui/toast/component.yml +4 -0
  67. data/app/components/solidus_admin/ui/toggletip/component.html.erb +53 -0
  68. data/app/components/solidus_admin/ui/toggletip/component.js +26 -0
  69. data/app/components/solidus_admin/ui/toggletip/component.rb +98 -0
  70. data/app/components/solidus_admin/ui/toggletip/component.yml +2 -0
  71. data/app/controllers/solidus_admin/accounts_controller.rb +11 -0
  72. data/app/controllers/solidus_admin/authentication_adapters/backend.rb +26 -0
  73. data/app/controllers/solidus_admin/base_controller.rb +21 -0
  74. data/app/controllers/solidus_admin/controller_helpers/authentication.rb +31 -0
  75. data/app/controllers/solidus_admin/controller_helpers/authorization.rb +29 -0
  76. data/app/controllers/solidus_admin/controller_helpers/locale.rb +32 -0
  77. data/app/controllers/solidus_admin/orders_controller.rb +21 -0
  78. data/app/controllers/solidus_admin/products_controller.rb +93 -0
  79. data/app/helpers/solidus_admin/components_helper.rb +9 -0
  80. data/app/helpers/solidus_admin/layout_helper.rb +18 -0
  81. data/app/javascript/solidus_admin/application.js +2 -0
  82. data/app/javascript/solidus_admin/controllers/application.js +9 -0
  83. data/app/javascript/solidus_admin/controllers/components.js +35 -0
  84. data/app/javascript/solidus_admin/controllers/hello_controller.js +7 -0
  85. data/app/javascript/solidus_admin/controllers/index.js +14 -0
  86. data/app/javascript/solidus_admin/utils.js +8 -0
  87. data/app/views/layouts/solidus_admin/application.html.erb +30 -0
  88. data/app/views/layouts/solidus_admin/preview.html.erb +10 -0
  89. data/app/views/solidus_admin/.keep +0 -0
  90. data/bin/rails +13 -0
  91. data/config/importmap.rb +13 -0
  92. data/config/locales/main_nav.en.yml +13 -0
  93. data/config/locales/orders.en.yml +4 -0
  94. data/config/locales/products.en.yml +10 -0
  95. data/config/routes.rb +13 -0
  96. data/config/solidus_admin/tailwind.config.js.erb +95 -0
  97. data/docs/customizing_main_navigation.md +42 -0
  98. data/docs/customizing_tailwind.md +78 -0
  99. data/docs/customizing_view_components.md +153 -0
  100. data/lib/generators/solidus_admin/component/USAGE +13 -0
  101. data/lib/generators/solidus_admin/component/component_generator.rb +130 -0
  102. data/lib/generators/solidus_admin/component/templates/component.html.erb.tt +3 -0
  103. data/lib/generators/solidus_admin/component/templates/component.js.tt +14 -0
  104. data/lib/generators/solidus_admin/component/templates/component.rb.tt +14 -0
  105. data/lib/generators/solidus_admin/component/templates/component.yml.tt +4 -0
  106. data/lib/generators/solidus_admin/component/templates/component_preview.rb.tt +15 -0
  107. data/lib/generators/solidus_admin/component/templates/component_preview_overview.html.erb +7 -0
  108. data/lib/generators/solidus_admin/component/templates/component_spec.rb.tt +16 -0
  109. data/lib/generators/solidus_admin/install/install_generator.rb +44 -0
  110. data/lib/generators/solidus_admin/install/templates/config/initializers/solidus_admin.rb +44 -0
  111. data/lib/solidus_admin/configuration.rb +217 -0
  112. data/lib/solidus_admin/engine.rb +67 -0
  113. data/lib/solidus_admin/importmap.rb +26 -0
  114. data/lib/solidus_admin/main_nav_item.rb +97 -0
  115. data/lib/solidus_admin/preview.rb +81 -0
  116. data/lib/solidus_admin/tailwindcss.rb +58 -0
  117. data/lib/solidus_admin/version.rb +5 -0
  118. data/lib/solidus_admin.rb +15 -0
  119. data/lib/tasks/importmap.rake +10 -0
  120. data/lib/tasks/tailwindcss.rake +55 -0
  121. data/solidus_admin.gemspec +35 -0
  122. metadata +255 -18
@@ -0,0 +1,4 @@
1
+ en:
2
+ default_label: Information
3
+ error_label: Error
4
+ close_text: "Close"
@@ -0,0 +1,53 @@
1
+ <details
2
+ data-controller="<%= stimulus_id %>"
3
+ <%= tag.attributes(**@attributes) %>
4
+ >
5
+ <summary
6
+ type="button"
7
+ class="
8
+ block
9
+ w-[1rem]
10
+ h-[1rem]
11
+ cursor-pointer
12
+ [&::marker]:hidden
13
+ [&::-webkit-details-marker]:hidden
14
+ "
15
+ data-<%= stimulus_id %>-target="button"
16
+ data-action="
17
+ click:prevent-><%= stimulus_id %>#toggle
18
+ keydown.esc@window-><%= stimulus_id %>#close
19
+ "
20
+ aria-label="<%= t('.get_help') %>"
21
+ >
22
+ <%= icon_tag("question-fill", class: "w-[1rem] h-[1rem] #{icon_theme_classes}") %>
23
+ </summary>
24
+
25
+ <div
26
+ class="
27
+ absolute
28
+ inline-block
29
+ w-[9rem]
30
+ px-[0.75rem]
31
+ body-tiny-bold
32
+ rounded
33
+ z-10
34
+ <%= bubble_position_classes %>
35
+ <%= bubble_theme_classes %>
36
+ "
37
+ data-<%= stimulus_id %>-target="bubble"
38
+ >
39
+ <span
40
+ role="status"
41
+ class="
42
+ relative
43
+ block
44
+ bg-inherit
45
+ py-[0.5rem]
46
+ <%= bubble_arrow_pseudo_element %>
47
+ "
48
+ data-<%= stimulus_id %>-target="content"
49
+ >
50
+ <%= @text %>
51
+ </span>
52
+ </div>
53
+ </details>
@@ -0,0 +1,26 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import { useClickOutside } from 'stimulus-use'
3
+
4
+ export default class extends Controller {
5
+ static targets = ['button', 'bubble', 'content']
6
+
7
+ connect () {
8
+ useClickOutside(this)
9
+ }
10
+
11
+ clickOutside () {
12
+ this.close()
13
+ }
14
+
15
+ toggle (e) {
16
+ this.element.open = !this.element.open
17
+ }
18
+
19
+ open () {
20
+ this.element.open = true
21
+ }
22
+
23
+ close () {
24
+ this.element.open = false
25
+ }
26
+ }
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SolidusAdmin::UI::Toggletip::Component < SolidusAdmin::BaseComponent
4
+ # Icon size: 1rem
5
+ # Arrow size: 0.375rem
6
+ # Banner padding x: 0.75rem
7
+ POSITIONS = {
8
+ up: {
9
+ arrow: %w[before:top-0 before:left-1/2 before:translate-y-[-50%] before:translate-x-[-50%]],
10
+ bubble: %w[translate-x-[calc(-50%+(1rem/2))] translate-y-[calc(0.375rem/2)]]
11
+ },
12
+ up_right: {
13
+ arrow: %w[before:top-0 before:right-0 before:translate-y-[-50%]],
14
+ bubble: %w[translate-x-[calc(-100%+0.75rem+(1rem/2)+(0.375rem/2))] translate-y-[calc(0.375rem/2)]]
15
+ },
16
+ right: {
17
+ arrow: %w[before:top-1/2 before:right-0 before:translate-y-[-50%] before:translate-x-[0.93rem]],
18
+ bubble: %w[translate-x-[calc(-100%+(-0.375rem/2))] translate-y-[calc(-50%-(1rem/2))]]
19
+ },
20
+ down_right: {
21
+ arrow: %w[before:bottom-0 before:right-0 before:translate-y-[50%]],
22
+ bubble: %w[translate-x-[calc(-100%+0.75rem+(1rem/2)+(0.376rem/2))] translate-y-[calc(-100%-1rem-(0.375rem/2))]]
23
+ },
24
+ down: {
25
+ arrow: %w[before:bottom-0 before:left-1/2 before:translate-y-[50%] before:translate-x-[-50%]],
26
+ bubble: %w[translate-x-[calc(-50%+(1rem/2))] translate-y-[calc(-100%-1rem-(0.375rem/2))]]
27
+ },
28
+ down_left: {
29
+ arrow: %w[before:bottom-0 before:left-0 before:translate-y-[50%]],
30
+ bubble: %w[translate-x-[calc(-1rem/2)] translate-y-[calc(-100%-0.75rem-0.375rem)]]
31
+ },
32
+ left: {
33
+ arrow: %w[before:top-1/2 before:left-0 before:translate-y-[-50%] before:translate-x-[-0.93rem]],
34
+ bubble: %w[translate-x-[calc(1rem+(0.375rem/2))] translate-y-[calc(-50%-(1rem/2))]]
35
+ },
36
+ up_left: {
37
+ arrow: %w[before:top-0 before:left-0 before:translate-y-[-50%]],
38
+ bubble: %w[translate-x-[calc(-0.75rem+0.375rem)] translate-y-[calc(0.375rem/2)]]
39
+ },
40
+ none: {
41
+ arrow: %w[before:hidden],
42
+ bubble: %w[translate-x-[calc(-50%+0.75rem)]]
43
+ }
44
+ }.freeze
45
+
46
+ THEMES = {
47
+ light: {
48
+ icon: %w[fill-gray-500],
49
+ bubble: %w[text-gray-800 bg-gray-50]
50
+ },
51
+ dark: {
52
+ icon: %w[fill-gray-800],
53
+ bubble: %w[text-white bg-gray-800]
54
+ }
55
+ }.freeze
56
+
57
+ # @param text [String] The toggletip text
58
+ # @param position [Symbol] The position of the arrow in relation to the
59
+ # toggletip. The latter will be positioned accordingly in relation to the
60
+ # help icon. Defaults to `:up`. See `POSITIONS` for available options.
61
+ # @param theme [Symbol] The theme of the toggletip. Defaults to `:light`. See
62
+ # `THEMES` for available options.
63
+ def initialize(text:, position: :down, theme: :light, **attributes)
64
+ @text = text
65
+ @position = position
66
+ @theme = theme
67
+ @attributes = attributes
68
+ @attributes[:class] = [
69
+ "relative inline-block",
70
+ @attributes[:class],
71
+ ].join(" ")
72
+ end
73
+
74
+ def icon_theme_classes
75
+ THEMES.fetch(@theme)[:icon].join(" ")
76
+ end
77
+
78
+ def bubble_theme_classes
79
+ THEMES.fetch(@theme)[:bubble].join(" ")
80
+ end
81
+
82
+ def bubble_position_classes
83
+ POSITIONS.fetch(@position)[:bubble].join(" ")
84
+ end
85
+
86
+ def bubble_arrow_pseudo_element
87
+ (
88
+ [
89
+ "before:content['']",
90
+ "before:absolute",
91
+ "before:w-[0.375rem]",
92
+ "before:h-[0.375rem]",
93
+ "before:rotate-45",
94
+ "before:bg-inherit",
95
+ ] + POSITIONS.fetch(@position)[:arrow]
96
+ ).join(" ")
97
+ end
98
+ end
@@ -0,0 +1,2 @@
1
+ en:
2
+ get_help: "Get help"
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin
4
+ class AccountsController < SolidusAdmin::BaseController
5
+ skip_before_action :authorize_solidus_admin_user!
6
+
7
+ def show
8
+ redirect_to spree.edit_admin_user_path(current_solidus_admin_user)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin::AuthenticationAdapters::Backend
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ delegate :admin_logout_path, to: :spree
8
+ helper_method :admin_logout_path
9
+ end
10
+
11
+ private
12
+
13
+ def authenticate_solidus_backend_user!
14
+ return if spree_current_user
15
+
16
+ instance_exec(&Spree::Admin::BaseController.unauthorized_redirect)
17
+ end
18
+
19
+ def store_location
20
+ Spree::UserLastUrlStorer.new(self).store_location
21
+ end
22
+
23
+ def spree_current_user
24
+ defined?(super) ? super : nil
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'geared_pagination'
4
+
5
+ module SolidusAdmin
6
+ class BaseController < ApplicationController
7
+ include ActiveStorage::SetCurrent
8
+ include Spree::Core::ControllerHelpers::Store
9
+ include GearedPagination::Controller
10
+
11
+ include SolidusAdmin::ControllerHelpers::Authentication
12
+ include SolidusAdmin::ControllerHelpers::Authorization
13
+ include SolidusAdmin::ControllerHelpers::Locale
14
+ include SolidusAdmin::ComponentsHelper
15
+ include SolidusAdmin::AuthenticationAdapters::Backend if defined?(Spree::Backend)
16
+
17
+ layout 'solidus_admin/application'
18
+ helper 'solidus_admin/components'
19
+ helper 'solidus_admin/layout'
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin::ControllerHelpers::Authentication
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_action :authenticate_solidus_admin_user!
8
+
9
+ helper_method :current_solidus_admin_user
10
+ helper_method :solidus_admin_logout_path
11
+ helper_method :solidus_admin_logout_method
12
+ end
13
+
14
+ private
15
+
16
+ def authenticate_solidus_admin_user!
17
+ send SolidusAdmin::Config.authentication_method if SolidusAdmin::Config.authentication_method
18
+ end
19
+
20
+ def current_solidus_admin_user
21
+ send SolidusAdmin::Config.current_user_method if SolidusAdmin::Config.current_user_method
22
+ end
23
+
24
+ def solidus_admin_logout_path
25
+ SolidusAdmin::Config.logout_link_path
26
+ end
27
+
28
+ def solidus_admin_logout_method
29
+ SolidusAdmin::Config.logout_link_method
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin::ControllerHelpers::Authorization
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_action :authorize_solidus_admin_user!
8
+ end
9
+
10
+ private
11
+
12
+ def current_ability
13
+ @current_ability ||= Spree::Ability.new(current_solidus_admin_user)
14
+ end
15
+
16
+ def authorize_solidus_admin_user!
17
+ subject = authorization_subject
18
+
19
+ authorize! :admin, subject
20
+ authorize! action_name, subject
21
+ end
22
+
23
+ def authorization_subject
24
+ "Spree::#{controller_name.classify}".constantize
25
+ rescue NameError
26
+ raise NotImplementedError, "Couldn't infer the model class from the controller name, " \
27
+ "please implement `#{self.class}#authorization_subject`."
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin::ControllerHelpers::Locale
4
+ extend ActiveSupport::Concern
5
+ include Spree::Admin::SetsUserLanguageLocaleKey
6
+
7
+ included do
8
+ before_action :set_locale
9
+ before_action :update_user_locale
10
+ end
11
+
12
+ private
13
+
14
+ def update_user_locale
15
+ requested_locale = params[:switch_to_locale] or return
16
+
17
+ if requested_locale.to_sym != user_locale
18
+ session[set_user_language_locale_key] = requested_locale
19
+
20
+ flash[:notice] = t('spree.locale_changed')
21
+ redirect_to url_for(request.params.except(:switch_to_locale))
22
+ end
23
+ end
24
+
25
+ def user_locale
26
+ session[set_user_language_locale_key] || I18n.default_locale
27
+ end
28
+
29
+ def set_locale
30
+ I18n.locale = user_locale
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin
4
+ class OrdersController < SolidusAdmin::BaseController
5
+ def index
6
+ orders = Spree::Order
7
+ .order(created_at: :desc, id: :desc)
8
+ .ransack(params[:q])
9
+ .result(distinct: true)
10
+
11
+ set_page_and_extract_portion_from(
12
+ orders,
13
+ per_page: SolidusAdmin::Config[:orders_per_page]
14
+ )
15
+
16
+ respond_to do |format|
17
+ format.html { render component('orders/index').new(page: @page) }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin
4
+ class ProductsController < SolidusAdmin::BaseController
5
+ def edit
6
+ redirect_to action: :show
7
+ end
8
+
9
+ def show
10
+ @product = Spree::Product.friendly.find(params[:id])
11
+
12
+ respond_to do |format|
13
+ format.html { render component('products/show').new(product: @product) }
14
+ end
15
+ end
16
+
17
+ def update
18
+ @product = Spree::Product.friendly.find(params[:id])
19
+
20
+ if @product.update(params.require(:product).permit!)
21
+ flash[:success] = t('spree.successfully_updated', resource: [
22
+ Spree::Product.model_name.human,
23
+ @product.name.inspect,
24
+ ].join(' '))
25
+
26
+ redirect_to action: :show, status: :see_other
27
+ else
28
+ flash.now[:error] = @product.errors.full_messages.join(", ")
29
+
30
+ respond_to do |format|
31
+ format.html { render component('products/show').new(product: @product), status: :unprocessable_entity }
32
+ end
33
+ end
34
+ end
35
+
36
+ def index
37
+ products = Spree::Product
38
+ .order(created_at: :desc, id: :desc)
39
+ .ransack(params[:q])
40
+ .result(distinct: true)
41
+
42
+ set_page_and_extract_portion_from(
43
+ products,
44
+ per_page: SolidusAdmin::Config[:products_per_page]
45
+ )
46
+
47
+ respond_to do |format|
48
+ format.html { render component('products/index').new(page: @page) }
49
+ end
50
+ end
51
+
52
+ def destroy
53
+ @products = Spree::Product.where(id: params[:id])
54
+
55
+ Spree::Product.transaction do
56
+ @products.discard_all
57
+ end
58
+
59
+ flash[:notice] = t('.success')
60
+ redirect_to products_path, status: :see_other
61
+ end
62
+
63
+ def discontinue
64
+ @products = Spree::Product.where(id: params[:id])
65
+
66
+ Spree::Product.transaction do
67
+ @products
68
+ .update_all(discontinue_on: Time.current)
69
+ end
70
+
71
+ flash[:notice] = t('.success')
72
+ redirect_to products_path, status: :see_other
73
+ end
74
+
75
+ def activate
76
+ @products = Spree::Product.where(id: params[:id])
77
+
78
+ Spree::Product.transaction do
79
+ @products
80
+ .where.not(discontinue_on: nil)
81
+ .update_all(discontinue_on: nil)
82
+
83
+ @products
84
+ .where("available_on <= ?", Time.current)
85
+ .or(@products.where(available_on: nil))
86
+ .update_all(discontinue_on: nil)
87
+ end
88
+
89
+ flash[:notice] = t('.success')
90
+ redirect_to products_path, status: :see_other
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin
4
+ module ComponentsHelper
5
+ def component(name)
6
+ SolidusAdmin::Config.components[name]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAdmin
4
+ # Helpers for the admin layout
5
+ module LayoutHelper
6
+ # @return [Symbol]
7
+ def current_locale(backend: I18n)
8
+ backend.locale
9
+ end
10
+
11
+ # @param store_name [String]
12
+ # @param controller_name [String]
13
+ # @return [String] HTML title
14
+ def solidus_admin_title(store_name: current_store.name, controller_name: self.controller_name)
15
+ "#{store_name} - #{t("solidus_admin.#{controller_name}.title")}"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,2 @@
1
+ import "@hotwired/turbo-rails"
2
+ import "solidus_admin/controllers"
@@ -0,0 +1,9 @@
1
+ import { Application } from "@hotwired/stimulus"
2
+
3
+ const application = Application.start()
4
+
5
+ // Configure Stimulus development experience
6
+ application.debug = location.hostname === "localhost"
7
+ window.Stimulus = application
8
+
9
+ export { application }
@@ -0,0 +1,35 @@
1
+ import "@hotwired/stimulus"
2
+
3
+ const registeredControllers = {}
4
+
5
+ // Eager load all controllers registered beneath the `under` path in the import map to the passed application instance.
6
+ export function eagerLoadComponents(application, { under, suffix }) {
7
+ const paths = Object.keys(parseImportmapJson()).filter((path) => path.match(new RegExp(`^${under}/.*${suffix}$`)))
8
+ paths.forEach((path) => registerComponent(path, under, application, suffix))
9
+ }
10
+
11
+ function parseImportmapJson() {
12
+ return JSON.parse(document.querySelector("script[type=importmap]").text).imports
13
+ }
14
+
15
+ function registerComponent(path, under, application, suffix) {
16
+ const name = path
17
+ .replace(new RegExp(`^${under}/(.*)${suffix}$`), '$1')
18
+ .replace(/\//g, "--")
19
+ .replace(/_/g, "-")
20
+
21
+ application.logDebugActivity(name, 'registerComponent', { path, under, suffix })
22
+
23
+ if (!(name in registeredControllers)) {
24
+ import(path)
25
+ .then(module => registerController(name, module, application))
26
+ .catch(error => console.error(`Failed to register controller: ${name} (${path})`, error))
27
+ }
28
+ }
29
+
30
+ function registerController(name, module, application) {
31
+ if (!(name in registeredControllers)) {
32
+ application.register(name, module.default)
33
+ registeredControllers[name] = true
34
+ }
35
+ };
@@ -0,0 +1,7 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ greet() {
5
+ console.log(`Hello World! ${new Date()}`)
6
+ }
7
+ }
@@ -0,0 +1,14 @@
1
+ // Import and register all your controllers from the importmap under controllers/*
2
+
3
+ import { application } from "solidus_admin/controllers/application"
4
+
5
+ // Eager load all controllers defined in the import map under controllers/**/*_controller
6
+ import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
7
+ eagerLoadControllersFrom("solidus_admin/controllers", application)
8
+
9
+ // Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
10
+ // import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
11
+ // lazyLoadControllersFrom("controllers", application)
12
+
13
+ import { eagerLoadComponents } from "solidus_admin/controllers/components"
14
+ eagerLoadComponents(application, { under: "solidus_admin", suffix: "/component" })
@@ -0,0 +1,8 @@
1
+ export const debounce = (func, wait) => {
2
+ let timeout
3
+
4
+ return () => {
5
+ clearTimeout(timeout)
6
+ timeout = setTimeout(func, wait)
7
+ }
8
+ }
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html lang="<%= current_locale %>">
3
+ <head>
4
+ <%= favicon_link_tag 'solidus_admin/favicon.ico' %>
5
+ <title><%= solidus_admin_title %></title>
6
+ <%= stylesheet_link_tag "solidus_admin/application.css", "inter-font", "data-turbo-track": "reload" %>
7
+ <%= javascript_importmap_tags "solidus_admin/application", shim: false, importmap: SolidusAdmin.importmap %>
8
+ </head>
9
+
10
+ <body class="bg-gray-15">
11
+ <%= render component("skip_link").new(href: "#main") %>
12
+ <div class="fixed right-3 bottom-3 flex flex-col gap-3" role="alert">
13
+ <% flash.each do |key, message| %>
14
+ <%= render component("ui/toast").new(text: message, scheme: key == :error ? :error : :default) %>
15
+ <% end %>
16
+ </div>
17
+
18
+ <div class="flex gap-0">
19
+ <div class="min-w-[240px] border-r border-r-gray-100 relative">
20
+ <div class="min-h-screen top-0 sticky flex">
21
+ <%= render component("sidebar").new(store: current_store) %>
22
+ </div>
23
+ </div>
24
+
25
+ <main id="main" class="flex-grow">
26
+ <%= yield %>
27
+ </main>
28
+ </div>
29
+ </body>
30
+ </html>
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <%= stylesheet_link_tag "solidus_admin/application.css", "inter-font", "data-turbo-track": "reload" %>
5
+ <%= javascript_importmap_tags "solidus_admin/application", shim: false, importmap: SolidusAdmin.importmap %>
6
+ </head>
7
+ <body class="p-3">
8
+ <%= yield %>
9
+ </body>
10
+ </html>
File without changes
data/bin/rails ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('..', __dir__)
6
+ ENGINE_PATH = File.expand_path('../lib/solidus_admin/engine', __dir__)
7
+
8
+ # Set up gems listed in the Gemfile.
9
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __dir__)
10
+ require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
11
+
12
+ require "rails/all"
13
+ require "rails/engine/commands"
@@ -0,0 +1,13 @@
1
+ # Remember to restart your application after editing this file.
2
+
3
+ # Stimulus & Turbo
4
+ pin "@hotwired/stimulus", to: "stimulus.js"
5
+ pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
6
+ pin "@hotwired/turbo-rails", to: "turbo.js"
7
+
8
+ pin "stimulus-use", to: "https://ga.jspm.io/npm:stimulus-use@0.52.0/dist/index.js"
9
+
10
+ pin "solidus_admin/application", preload: true
11
+ pin "solidus_admin/utils"
12
+ pin_all_from SolidusAdmin::Engine.root.join("app/javascript/solidus_admin/controllers"), under: "solidus_admin/controllers"
13
+ pin_all_from SolidusAdmin::Engine.root.join("app/components")
@@ -0,0 +1,13 @@
1
+ en:
2
+ solidus_admin:
3
+ main_nav:
4
+ orders: Orders
5
+ products: Products
6
+ option_types: Option Types
7
+ property_types: Property Types
8
+ taxonomies: Taxonomies
9
+ taxons: Display Order
10
+ promotions: Promotions
11
+ stock: Stock
12
+ users: Users
13
+ settings: Settings
@@ -0,0 +1,4 @@
1
+ en:
2
+ solidus_admin:
3
+ orders:
4
+ title: "Orders"