-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build admin menu using configuration #260
Conversation
app/models/spree/admin/main_menu/default_configuration_builder.rb
Outdated
Show resolved
Hide resolved
app/models/spree/admin/main_menu/default_configuration_builder.rb
Outdated
Show resolved
Hide resolved
823bec7
to
fbb0ba9
Compare
|
||
def insert_before(item_key, item_to_add) | ||
item_index = index_for_key(item_key) | ||
raise ArgumentError, "Item not found for key #{item_key}" unless item_index |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a KeyError
would be more fitting here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also - it seems that this logic (get index by key, raise if the key is nil) is used in multiple places. Maybe we could use a second function like index_for_key!
or fetch_index_for_key
(mirroring Hash#fetch
) which would wrap the exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean, adding a private method that would throw an exception if key is not found?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, just so the concrete exception is only defined once.
|
||
def add_products_section(root) | ||
items = [ | ||
ItemBuilder.new('products', admin_products_path).with_match_path('/products').build, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any advantage to using the builder here rather than simply using the Item
constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More explicit interface, getting default values for e.g. translation key, and skipping unnecessary arguments in the constructor.
Spree::Backend::Config = Spree::Backend::Configuration.new | ||
app.config.spree_backend = Environment.new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I think "Environment" is not a great name in this context.
- Isn't it a little awkward that now there are two backend "configs"? The Preference-based
Spree::Backend::Config
and thisEnvironment
struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pattern that we use in spree_core as well.
Preferences are persisted in the database, this is slightly different.
fbb0ba9
to
3ae2197
Compare
3ae2197
to
64d455d
Compare
A bit of a backstory: A lot of spree extension currently rely on deface gem, which is no longer recommended as it introduces a lot of complexity that's hard to debug, it's prone to errors and its performance is not that great.
As a part of moving away from deface, we need to create interfaces for extensions to modify the admin panel. This is an attempt to move main menu from hardcoded templates, to an object-oriented structure which allows to define and modify the menu using ruby code.
An extension should be then able to modfiy
Rails.application.config.spree_backend.main_menu
by either using interfaces ofAdmin::MainMenu::Section
to mutate/extend the structure, or by providing a totally customized menu.I've also migrated the existing menus to
Admin::MainMenu::DefaultConfigurationBuilder
, which can also act as a demo of the tools I've introduced.I would love to hear your feedback on the overall structure.