-
Notifications
You must be signed in to change notification settings - Fork 366
Implement toolbar extension mechanism for providers #4262
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
Conversation
|
The toolbar overrides live under provider repositories under The class names are like this To get rid of the to With that: I believe the autoloades splits the class name on "::" and resolves each module in a turn and it does not see a module name
I can "fix" that: So the problem is the What's the best way to fix that? |
|
ping @Fryguy |
| instance = [plugin.name.sub('::Engine',''), 'ToolbarOverrides', self.class.name.to_s.split('::').last].join('::') | ||
| instance.constantize | ||
| end | ||
| end.compact |
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 this can all live in the Vmdb::Plugins class itself, but this is mostly pretty good 👍
| class ApplicationHelper::Toolbar::Override < ApplicationHelper::Toolbar::Basic | ||
| def definition | ||
| @definition | ||
| end |
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.
attr_reader :definition seems better.
| @loaded = true | ||
| end | ||
|
|
||
| @definition |
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.
Prefer something like @definition ||= load_overrides and then have load_overrides just return the thing.
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.
Ugh...I see that custom_content injects itself via the ivars...might be better if those methods all go through the definition accessor. That way they are loaded "first". I guess I don't understand the DSL in this class and what is trying to be solved, so perhaps my suggestions should be ignored 😁
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 will be redoing that all. So while your comments make sense, I'll just dump the code and do it differently once the autoloading works.
| name = "#{name}.rb" | ||
| if File.exist?(name) | ||
| require name | ||
| instance = [plugin.name.sub('::Engine',''), 'ToolbarOverrides', self.class.name.to_s.split('::').last].join('::') |
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.
plugin.name.sub('::Engine','')
Slightly better: plugin.name.chomp("::Engine")
self.class.name
What is an example of self.class.name here? Trying to understand what this does....I think it might be easier with a simple .gsub of the middle section, but I'm not sure.
| end.compact | ||
| end | ||
|
|
||
| def load_overrides |
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.
probably should be a private method. Didn't realize this was in the private section, so ignore :)
|
|
||
| def initialize | ||
| @loaded = false | ||
| @definition = {} |
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.
Unset both of these and let the accessor deal with the lazy loading on first access.
|
@martinpovolny I'm not sure what exactly you need. |
|
@slemrmartin: What I need to do: We have toolbar classes in the form of The providers will have a way of extending the toolbar class. So I need to query and load class in the form of:
In case of Amazon provider and the CloudTenantCenter toolbar it would be:
I have no problem doing that with a require statement: And placing the toolbar override classes in the provider repo under 'app/toolbar_overrides'. That works just fine and I am happy. However I'd like to do that w/o that require statement with the Rails autoloading mechanism. I am looking for a way
To get the same or similar effect but w/o the So far I have no success. I am obviously structuring the modules and classes and files in a way that is not compatible with how the autoloading works. Help welcome. |
|
@martinpovolny I think you need to follow namespaces when building directory structure - for autoloader in plugin manageiq-providers-amazon: then you can have: |
|
Problem solved. Thx @slemrmartin, @Fryguy, @Ladas ! |
* Toolbar::Basic is moved to a base class Toolbar::Base * Toolbar::Override (practically Toolbar::Base) is where the provider extentions should inherit from. * Toolbar::Basic newly includes the extention mechanism.
403126f to
bb21aa7
Compare
| # "ManageIQ::Providers::Amazon::ToolbarOverrides::EmsCloudCenter" is a match for | ||
| # "ManageIQ::Providers::Amazon::CloudManager | ||
| extension_classes.find_all do |ext| | ||
| ext.name.split('::')[0..-3] == record.class.name.split('::')[0..-2] |
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.
@Ladas, @slemrmartin : Do we have a better way to do the matching?
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 compare just the ManageIQ::Providers::Amazon, right? So maybe
ext.name.split('::')[0..2] == record.class.name.split('::')[0..2] looks less fragile
Not sure about a better way
|
@himdel, can you, please, review and merge this one? |
|
Checked commits martinpovolny/manageiq-ui-classic@bb21aa7~...787442e with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0 |
|
I would have liked a second chance to review this, considering I had issues 😕 |
|
@Fryguy : sorry for that, will address any feedback in a separate PR. |
|
@Fryguy Whups, sorry about that. I'm sure we can address any problems in future PRs. |
Context
We want to allow the provider authors to extend ManageIQ with Ansible playbooks and roles. ManageIQ core provides the capability to execute an Asible playbook from the provider repository. The ManageIQ UI provides a way to call that playbook from a toolbar. Before calling the playbook additional parameters can be collected using a custom dialog.
Provider workflow
manageiq-provider-xxxExample provider PR
Related UI PRs:
Goal of this PR
This allows providers to extend existing toolbars by creating classes such as:
app/helpers/manageiq/providers/amazon/toolbar_overrides/ems_cloud_center.rbin themanageiq-providers-amazonrepo.Any toolbar can be overridden but we focus on providers on the entity detail screen in this PR. Examples:
For these (detail) screens. The toolbar is not only extended, but the proper extension is selected by matching
@recordwith the toolbar's class.For screens where there is no
@recordall available extensions are loaded.How it is done?
Toolbar base class is reorganized as follows:
Toolbar::Basicis moved to a base classToolbar::BaseToolbar::Override(practicallyToolbar::Base) is where the providerextentions should inherit from.
Toolbar::Basicnewly includes the extention mechanism.ToolbarBuildernow passed the@recordto the toolbardefinitionmethod (now a method). And it filters the available extensions by matching the record's class with the extension class (the provider base module).