-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Dynamic uiActions & license support #68507
Conversation
@@ -39,6 +39,8 @@ export class DashboardToUrlDrilldown implements Drilldown<Config, ActionContext> | |||
|
|||
public readonly order = 8; | |||
|
|||
readonly minimalLicense = 'gold'; // example of minimal license support |
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.
only thing required for consumer 🙌
Pinging @elastic/kibana-app-arch (Team:AppArch) |
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.
LGTM for licensing
plugin change once the createStartMock
return type is fixed.
We have previously avoided the lock to signify options behind a license. We should however still keep the tooltip (I don't think we need the title 'License' though). In alerting, there is a link to the right of the 'Actions' header that goes to the Licensing page on Elastic.co As for the management screen, let's bring the disabled indicator closer to the title (and show the message |
This looks good! Only tiny nit is to increase the spacing between the name and error icon (Try |
@elasticmachine merge upstream |
I'm thinking maybe we should simplify and instead of creating a way of "enhancing" And plugins.uiActions.registerActionHook({
isCompatible: (action) => isCompatibleLicense(action),
}); I think it should simplify the architecture and then we don't need to export internal |
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.
Chatted with @Dosant, he said he could explore the "hook" approach if @ppisljar, @stacey-gammon you are OK with it.
Idea being that in the "hook" approach we get:
- Less and simpler code.
- Actions are still registered as before when they are registered, instead definitions being registered and actions created in start life-cycle.
- We don't inroduce setup and start life-cycles into,
UiActionsService
. As before,UiActionsService
does not need to know about those life-cycles, actions are simply registered whenever they are registered. - We don't need to export
ActionInternal
class fromui_actions
.
It could looks something like this:
interface ActionDefinition {
// Add extra information to action definition from X-Pack
enhancements: unknown;
}
// Register action "hooks" in X-Pack.
plugins.ui_actions.registerActionHook({
isCompatible: (action, context) => isLicenseValid(action.enhancements),
});
fb0842b
to
fa41858
Compare
…-license # Conflicts: # x-pack/plugins/ui_actions_enhanced/public/plugin.ts
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.
code LGTM
@elasticmachine merge upstream |
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.
From the perspective of a consumer of the ui_actions services, it's not clear to me how to use this functionality, and I think I can easily get into trouble with it.
I first tried to do something like:
deps.uiActions.registerActionHook({
onIsCompatible: (action: Action) => {
return action.isCompatible({}) && ...? //
},
});
Can't do that because onIsCompatible
is sync, while isCompatible
is async. Even if it was async, and I did the above, I'd hit a circular loop. It'd also pass the typescript check, but because of contra-variance, it'd throw a runtime exception on actions that require more than an empty object to be passed in as context
.
Maybe I'm forgetting some context, but is there a reason we can't just do something like this, and rely on our current public APIs to support this:
const createHelloWorldAction = (getStartServices: () => Promise<licensing>) => {
return createAction({
type: ACTION_HELLO_WORLD,
isCompatible: () => return (await getStartServices()).licensing.license$.getValue().hasAtLeast('gold');
getDisplayName: () => 'Hello World!',
execute: async () => {},
});
const helloWorldAction = createHelloWorldAction(async () => ({
licensing: (await core.getStartServices())[0].licensing,
}));
uiActions.registerAction(helloWorldAction);
It's less refactored, but also introduces no extra public APIs.
* @param action | ||
* @param context | ||
*/ | ||
onIsCompatible?: (action: Action, context: unknown) => boolean; |
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 context
needed? I don't see it used and since it's unknown
, probably not that helpful anyway.
Should it return Promise<boolean>
to match isCompatible
fns?
Also... don't let me block this PR, especially since I'm going on vacation for a couple weeks. I just wanted to bring up some thoughts about maybe simplifying/minimizing public APIs. Also just trying to focus on our public APIs from a public consumer standpoint. We often add public APIs for very specific use cases, and try to make them general/flexible enough for future use cases, but don't spend enough time thinking about examples/tests for the general cases. What would an example plugin look like to showcase how another plugin can use Are we introducing overly flexible APIs that will cause us issues later on the line and maintenance headaches? Do we want to support giving the ability for one plugin to turn off another plugins actions? Do we have an answer for how to avoid clashes if multiple plugins add custom state/functionality onto the If there is an easier way to solve this, without introducing new APIs, might be worth considering, to the support of our dev principles: Just some thoughts, but ultimately, I leave it to the team to make the final decision! |
@stacey-gammon, thanks for this review! I made a step back and reverted all changes to static uiActions level. I agree that we don't have right now a use case for that functionality. I left only Initially I was inspired looking at this #63170, What I did in this pr wasn't solving that particular issue, but I thought of similar use cases, where new static action registered in x-pack could benefit of simple @streamich, @ppisljar, Since Stacey enjoying vacation now, could you please re-review this simpler version? 🙏 |
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.
LGTM
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.
So much simpler, really like the changes. 🎉
💚 Build SucceededBuild metrics
History
To update your PR or re-run it, just comment with: |
This pr adds convenient license support to dynamic uiActions in x-pack. Works for actions created with action factories & drilldowns. Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This pr adds convenient license support to dynamic uiActions in x-pack. Works for actions created with action factories & drilldowns. Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
* master: (59 commits) [Lens] Fix broken test (elastic#70117) [SIEM] Import timeline fix (elastic#65448) [SECURITY SOLUTION][INGEST] UX update for ingest manager edit/create datasource for endpoint (elastic#70079) [Telemetry] Collector Schema (elastic#64942) [Endpoint] Add Endpoint empty states for onboarding (elastic#69626) Hide unused resolver buttons (elastic#70112) [Security] `Investigate in Resolver` Timeline Integration (elastic#70111) [Discover] Improve styling of graphs in sidebar (elastic#69440) [Metrics UI] Fix EuiTheme type issue (elastic#69735) skip failing suite (elastic#70104) (elastic#70103) [ENDPOINT] Hide the Timeline Flyout while on the Management Pages (elastic#69998) [SIEM][CASE] Persist callout when dismissed (elastic#68372) [SIEM][Exceptions] - Cleaned up and updated exception list item comment structure (elastic#69532) [Maps] remove indexing state from redux (elastic#69765) Add API integration test for deleting data streams. (elastic#70020) renames SIEM to Security Solution (elastic#70070) Adding saved_objects_page in OSS (elastic#69900) [Lens] Use accordion menus in field list for available and empty fields (elastic#68871) Dynamic uiActions & license support (elastic#68507) [SIEM] Update readme for timeline apis (elastic#67038) ...
…bana into alerting/consumer-based-rbac * 'alerting/consumer-based-rbac' of github.com:gmmorris/kibana: (25 commits) [Lens] Fix broken test (elastic#70117) [SIEM] Import timeline fix (elastic#65448) [SECURITY SOLUTION][INGEST] UX update for ingest manager edit/create datasource for endpoint (elastic#70079) [Telemetry] Collector Schema (elastic#64942) [Endpoint] Add Endpoint empty states for onboarding (elastic#69626) Hide unused resolver buttons (elastic#70112) [Security] `Investigate in Resolver` Timeline Integration (elastic#70111) [Discover] Improve styling of graphs in sidebar (elastic#69440) [Metrics UI] Fix EuiTheme type issue (elastic#69735) skip failing suite (elastic#70104) (elastic#70103) [ENDPOINT] Hide the Timeline Flyout while on the Management Pages (elastic#69998) [SIEM][CASE] Persist callout when dismissed (elastic#68372) [SIEM][Exceptions] - Cleaned up and updated exception list item comment structure (elastic#69532) [Maps] remove indexing state from redux (elastic#69765) Add API integration test for deleting data streams. (elastic#70020) renames SIEM to Security Solution (elastic#70070) Adding saved_objects_page in OSS (elastic#69900) [Lens] Use accordion menus in field list for available and empty fields (elastic#68871) Dynamic uiActions & license support (elastic#68507) [SIEM] Update readme for timeline apis (elastic#67038) ...
Summary
Needed for #55324
This pr adds convenient license support to dynamic uiActions in x-pack.
Works for actions created with action factories & drilldowns.
All is needed from consumer is to specify optional
minimalLicense?: LicenseType;
onActionFactoryDefinition
orDrilldownDefinition
Implements this nice state for
action_wizard
and drilldows list ⬇️In case there is an available action factory, but not sufficient license, we still show that action factory, but in disabled state. On hover there is a tooltip. Also a link to
subscriptions
page in the header (like in alerting)In case when there is existing Drilldowns with higher license, then current license, we show this warning in a drilldown list:
To try
yarn start --run-examples
. Example url drilldown is available fromgold
license.Checklist
Delete any items that are not applicable to this PR.
For maintainers