solidus_admin 0.0.0 → 0.0.1

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 (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"