Skip to content

Commit

Permalink
Prepare admin container for sidecar components
Browse files Browse the repository at this point in the history
We prepare the admin container to resolve components from within sidecar
directories and we namespace all components within a `components` key.

Example, from the engine directory:

    app/components/solidus_admin/main_nav/component.rb

gets registered as:

    components.main_nav.component

and can be overriden by the following in the host application:

    app/components/sandbox/solidus_admin/main_nav/component.rb
  • Loading branch information
waiting-for-dev authored and elia committed Jun 9, 2023
1 parent 61f1612 commit f589fa3
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

module SolidusAdmin
# Renders the main navigation of Solidus Admin.
class MainNavComponent < BaseComponent
class MainNav::Component < BaseComponent
include Import[
"main_nav_item_component",
main_nav_item_component: "components.main_nav_item.component",
items: "main_nav_items"
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module SolidusAdmin
# Menu item within a {MainNavComponent}
class MainNavItemComponent < BaseComponent
class MainNavItem::Component < BaseComponent
with_collection_parameter :item

attr_reader :item
Expand Down
2 changes: 1 addition & 1 deletion admin/app/helpers/solidus_admin/container_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def container
end

def component(name)
container.resolve("#{name}_component")
container.resolve("components.#{name}.component")
end
end
end
4 changes: 2 additions & 2 deletions admin/lib/solidus_admin/container.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ module SolidusAdmin
class Container < Dry::System::Container
configure do |config|
config.root = Pathname(__FILE__).dirname.join("../..").realpath
config.component_dirs.add("app/components") do |dir|
config.component_dirs.add("app/components/solidus_admin") do |dir|
dir.loader = System::Loaders::HostOverridableConstant.method(:call).curry["components"]
dir.namespaces.add "solidus_admin", key: nil
dir.namespaces.add nil, const: "solidus_admin", key: "components"
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@ module Loaders
# ```ruby
# config.component_dirs.add "app/components" do |dir|
# dir.loader = SolidusAdmin::System::Loaders::HostOverridableConstant.method(:call).curry["components"]
# dir.namespaces.add nil, const: "solidus_admin", key: "components"
# end
# ```
#
# When `Container["foo"]` is given and the loader is used:
#
# - It will return a `MyApp::SolidusAdmin::Foo` constant if `app/components/my_app/solidus_admin/foo.rb` exists.
# - It will return a `MyApp::SolidusAdmin::Foo` constant if `app/components/my_app/components/solidus_admin/foo.rb` exists.
# - Otherwise, it will return the resolved constant from the engine.
#
# @api private
class HostOverridableConstant < Dry::System::Loader
DIR_SEPARATOR = "/"

RUBY_EXT = ".rb"

# @param [String] namespace
def self.call(namespace, component, *_args)
return override_constant(component) if override_path(namespace, component).exist?
return override_constant(component, namespace) if override_path(namespace, component).exist?

require!(component)
constant(component)
Expand All @@ -47,12 +52,20 @@ def override_path(namespace, component)
namespace,
application_name.underscore,
"solidus_admin",
"#{component.identifier.key}.rb"
component_segment(component, namespace).concat(RUBY_EXT)
)
end

def override_constant(component)
"#{application_name}::SolidusAdmin::#{component.identifier.key.camelize}".constantize
def override_constant(component, namespace)
"#{application_name}::SolidusAdmin::#{component_segment(component, namespace).classify}".constantize
end

# "components.foo.component" => "foo/component"
def component_segment(component, namespace)
component
.identifier
.namespaced(from: namespace, to: nil)
.key_with_separator(DIR_SEPARATOR)
end
end
end
Expand Down

0 comments on commit f589fa3

Please sign in to comment.