-
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
[uiSettings] support defining settings with uiExports #12250
Conversation
f5970ce
to
3eadde0
Compare
3eadde0
to
eec0833
Compare
cc @tsullivan |
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, just few tiny nits.
foo: 'bar' | ||
}); | ||
sinon.assert.calledOnce(uiSettingsServiceFactory); | ||
const { args } = uiSettingsServiceFactory.firstCall; |
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.
nit: how about this instead?
sinon.assert.calledWithExactly(uiSettingsServiceFactory, server, {
foo: 'bar',
getDefaults: sinon.match.func
});
@@ -0,0 +1,24 @@ | |||
export class UiExportsConsumer { |
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.
question: Would you mind adding a brief comment for this class (what this is supposed to do and what are these consumers
)? Honestly, I'm having a hard time trying to understand what this thing does :/
@@ -1,8 +1,6 @@ | |||
import { defaultsDeep, noop } from 'lodash'; | |||
import { errors as esErrors } from 'elasticsearch'; | |||
|
|||
import { getDefaultSettings } from './defaults'; | |||
|
|||
function hydrateUserSettings(userSettings) { | |||
return Object.keys(userSettings) | |||
.map(key => ({ key, userValue: userSettings[key] })) |
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.
Not related to this PR, but looks funny that we map
before filter
that theoretically results in allocation of unnecessary objects, wondering if there is any hidden rationale 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.
IIRC I was coming down from an rx/observable high and didn't like that this method was previously implemented as a reduce that just assigned to a value and returned it (so that it could filter that value)... Then I remember wanting to implement it without the if()
... Yeah, not a huge fan of how it turned out. If you want to take a stab at it in another pr I'd love to see your prefered alternative
* @property {AsyncFunction} [options.getDefaults] async function that returns defaults/details about | ||
* the uiSettings. | ||
* @property {AsyncFunction} [options.readInterceptor] async function that is called when the | ||
* UiSettingsService does a read() an has an oportunity to intercept the |
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.
typo: read() an has
-----> read() and has
?
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'm struggling with following the flow here, but it feels like it's unavoidable without larger changes.
LGTM, just had a couple questions/nits.
@@ -57,7 +56,9 @@ export default (kibana) => { | |||
}); | |||
} | |||
|
|||
env.defaultUiSettings = getDefaultSettings(); | |||
env.defaultUiSettings = plugins.kbnServer.uiExports.consumers | |||
.find(consumer => consumer.getUiSettingDefaults) |
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'm a bit slow today, and I just couldn't understand this at first. I was just thinking "waaait, so getUiSettingDefaults
is not a function"? But yeah, I understand it now. I'd love a comment on why it's only doing this on the first consumer it finds that has this function.
I also think this should change to something like:
.find(consumer => consumer.getUiSettingDefaults !== undefined)
or
.find(consumer => isFunction(consumer.getUiSettingDefaults))
|
||
export default async (kbnServer, server, config) => { | ||
const uiExports = kbnServer.uiExports = new UiExports({ | ||
urlBasePath: config.get('server.basePath') | ||
}); | ||
|
||
await kbnServer.mixin(uiSettingsMixin); |
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'm soooo looking forward to 🔥 these mixins.
Why is this moved here, btw?
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.
Moved here so that the uiExport consumer is registered before we try to consume all of the exports. This bit of pluggability isn't quite as pluggable as originally thought, uiExportConsumers need to be registered between the time that kbnServer.uiExports
is created and when kbnServer.uiExports.consumePlugin()
is called for the first time, which doesn't provide any time in this case...
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.
👍
return uiSettingsServiceFactory(server, options); | ||
server.decorate('server', 'uiSettingsServiceFactory', (options = {}) => { | ||
return uiSettingsServiceFactory(server, { | ||
getDefaults, |
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.
Why pass around the function instead of just the defaults themselves?
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 the defaults can change without needing to tell the uiSettingsService
, but if you're really against it I can change that.
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.
Ah 👍 Let's keep it (maybe add a comment above it, so it's easier to understand when looking at it later and thinking the same thought I had?)
* [uiSettings] add `uiSettingDefaults` export type * [uiSettings/uiExportsConsumer] ensure that there are not conflicts * use `sinon.assert.calledWithExactly()` * describe the UiExportsConsumer class * make uiExport consumers filtering intention more clear * fix typo * fix typos * add note about why getDefaults() is a function (cherry picked from commit 7bec60c)
* [uiSettings] make service request based (#12243) * [server/uiSettings] make uiSettings service request based * [server/uiSettings] disambiguate UiSettings/Service * [server/uiSettings] link to PR in removal error * [server/uiSettings] await _read before hydrating * [server/uiSettings] focus tests, remove server integration * [server/uiSettings] add tests for readInterceptor() arg * [server/uiSettings] add server integration tests * [server/uiExports] fix replaceInjectedVars tests * [server/uiSettings] convert all methods to use async/await * [uiSettings/serviceFactory] fix doc block * [uiSettings/service] fix doc block * [uiSettings/tests/callClusterStub] stop tracking state needlessly * [uiSettings/tests] remove invalid tests and pointless promise helpers * [uiSettings/forRequest] fix typo * [uiSettings/tests] remove mixture of arrow and function expressions * [uiSettings/tests/callClusterStub] leverage sinon.calledWithExactly * [uiSettings/mixin/tests] add exception for eslint import/no-duplicates * [uiSettings/mixin/tests] wrap single args in parens (cherry picked from commit 65d6b5d) * [uiSettings] support defining settings with uiExports (#12250) * [uiSettings] add `uiSettingDefaults` export type * [uiSettings/uiExportsConsumer] ensure that there are not conflicts * use `sinon.assert.calledWithExactly()` * describe the UiExportsConsumer class * make uiExport consumers filtering intention more clear * fix typo * fix typos * add note about why getDefaults() is a function (cherry picked from commit 7bec60c)
Fixes #10863
This PR introduces a new uiExports type,
uiSettingDefaults
. The specification for these uiExports follow the same pattern as the defaults did before this change, the only difference is that they can be defined in a plugin's definition file and will be merged with theuiSettingDefaults
from all other plugins.Summary:
uiExports.uiSettingDefaults
key your plugin definition to adduiSettingDefaults
uiSettingDefaults
must be unique. If a key is already defined elsewhere then the server will not start.PS: I'd like to split the defaults in the kibana plugin from the "core" defaults and define those in
ui/ui_settings
, but didn't want to make too many changes to the defaults list in this PR. If you're up for the change now let me know, or I will send another PR once this one is merged.PS: I'd like to split the defaults in the kibana plugin from the "core" defaults and define those in
ui/ui_settings
, but didn't want to make too many changes to the defaults list in this PR. If you're up for the change now let me know, or I will send another PR once this one is merged.Release Note: We introduced a new uiExports type,
uiSettingDefaults
. The specification for these uiExports follow the same pattern as the defaults did before this change, the only difference is that they can be defined in a plugin's definition file and will be merged with theuiSettingDefaults
from all other plugins.