-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
Expose field formatters in kibana server #12625
Conversation
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.
The additional tests are great!! Just a few comments/questions.
|
||
let fieldFormats; | ||
beforeEach(function () { | ||
fieldFormats = new FieldFormatsService; |
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.
Can we add some parens here so it's new FieldFormatsService()
|
||
const config = {}; | ||
config['format:defaultTypeMap'] = { | ||
'ip': { 'id': 'ip', 'params': {} }, |
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.
The items besides number
aren't used by this test, can we remove them?
@@ -1,6 +1,6 @@ | |||
import _ from 'lodash'; | |||
import numeral from 'numeral'; | |||
import { FieldFormat } from 'ui/index_patterns/_field_format/field_format'; | |||
import numeral from '@spalger/numeral'; |
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.
Should we consider moving this to elastic/numeral
now that https://github.com/elastic/numeral-js exists?
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 created @elastic/numeral-js
and upgraded to numeral 3.0 at the same time, pretty sure we'll have to publish the old version at @spalger/numeral-js
in the new package if we want to move it over. That said, I'm not opposed.
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.
Can this wait for a separate PR? This seems like an existing artifact that is outside the scope of this PR and I am trying to get this PR finished ASAP since another feature is dependent on it and Tuesday is feature cutoff.
src/ui/field_formats_mixin.js
Outdated
import { getUiSettingDefaults } from '../core_plugins/kibana/ui_setting_defaults'; | ||
|
||
export function fieldFormatsMixin(kbnServer, server) { | ||
server.decorate('server', 'uiSettingDefaults', 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.
This doesn't feel like it belongs here, specifically because it's related to uiSettings. I know you're using the uiSettingDefaults with the fieldFormats, but the fieldFormatsMixin
really shouldn't be responsible for this.
Additionally, you should be able to do uiSettings.getDefaults();
and not have to expose this separately.
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.
uiSettings.getDefaults() is just a wrapper around options.getDefaults. If options.getDefaults is not provided than the default implementation of '() => ({})' is used. I was unable to figure out how to create a functioning getDefaults implementation to pass to server.uiSettingsServiceFactory
that would return the defaults. Please advise on how to implement getDefaults that properly returns the results of getUiSettingDefaults().
If field_formats_mixin is not the place, then where should uiSettingDefaults be exposed to the server?
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.
Never mind. Spencer straightened my out and you are correct. After a rebase, getDefaults is populated and spitting out the correct values. I will remove the uiSettingsDefaults decorator.
@@ -1,6 +1,6 @@ | |||
import { AggTypesBucketsBucketAggTypeProvider } from 'ui/agg_types/buckets/_bucket_agg_type'; | |||
import { AggTypesBucketsCreateFilterRangeProvider } from 'ui/agg_types/buckets/create_filter/range'; | |||
import { FieldFormat } from 'ui/index_patterns/_field_format/field_format'; | |||
import { FieldFormat } from '../../../../core_plugins/kibana/common/field_formats/field_format'; |
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.
Should we be reaching inside the core_plugins/kibana
folder from within src/ui/public
? What made you and @spalger choose to put the common
folder inside the kibana
plugin and not a direct descendant of src/
? This same issue applies to a few other situations below as well.
@@ -0,0 +1,29 @@ | |||
import { asPrettyString } from '../../utils/as_pretty_string'; |
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.
Were any changes made to the types that are showing up as additions and not renames in the diff?
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.
The types changed a lot. Instead of being wrapped in a function, now they just export the FieldFormat class
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.
Gotcha, I'll give them a closer look then :)
]; | ||
} | ||
|
||
ColorFormat.prototype._convert = { |
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 ColorFormat.prototype._convert
should be able to just me moved to a `_convert_method on the ColorFormat class.
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 tried to move those under the class with PR - Remove lodash mixin dependencies from Field Formatters but things are messy because _convert is an object and not a function and the way _convert is used in content types make references to this
tricky. @stacey-gammon and I decided it was best to leave this alone for now.
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... interesting... I'm fine leaving it as is for now in that case.
static outputFormats = outputFormats; | ||
} | ||
|
||
DurationFormat.prototype.getParamDefaults = function () { |
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.
Can we move this to a regular method on the DurationFormat
class instead of modifying the prototype as well?
static fieldType = '_source'; | ||
} | ||
|
||
SourceFormat.prototype._convert = { |
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.
Same comment about not extending the prototype directly.
]; | ||
} | ||
|
||
UrlFormat.prototype._convert = { |
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.
Same as above.
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.
Still working complete testing, but some early feedback
@@ -0,0 +1,45 @@ | |||
export class FieldFormatsService { |
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.
IMO, this belongs in src/ui/field_formats/field_formats_service.js
, not the kibana plugin. It's not optional like the kibana plugin theoretically is.
describe('Duration Format', function () { | ||
|
||
test({ inputFormat: 'seconds', outputFormat: 'humanize' }) | ||
(-60, 'minus a minute') |
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.
Interesting style, but I'm thinking this would be a little less mind bending as:
defineTests({
inputFormat: 'seconds',
outputFormat: 'humanize',
fixtures: [
[ 60, 'a minute' ],
// or
{ input: -60, output: 'minus a minute' },
]
})
@@ -0,0 +1,45 @@ | |||
export class FieldFormatsService { | |||
constructor() { | |||
this.fieldFormats = new Map(); |
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.
As far as I can tell this is intended for internal use only, it should be prefixed with an _
.
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 isn't actually a rule in our style guide, right? Airbnb also says not to use the leading underscore (https://github.com/airbnb/javascript#naming--leading-underscore), though we never officially committed to airbnb style guide asfaik.
Maybe we need a "vote" issue for this so we can put something in our style guide, because I see inconsistent use of leading underscores.
src/ui/field_formats_mixin.js
Outdated
import { FieldFormatsService } from '../core_plugins/kibana/common/field_formats/field_formats'; | ||
|
||
export function fieldFormatsMixin(kbnServer, server) { | ||
server.decorate('server', 'fieldFormats', new FieldFormatsService()); |
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 we could improve the ergonomics here a bit:
-
How about making more instances of the
FieldFormatService
that are configured with agetConfig()
function, rather than having a singleton that takedgetConfig
as an argument? -
If this followed the pattern
UiSettings
uses, and also depended onUiSettings
formally, it could look like this:// for use in the context of a request, the default context server.decorate('request', 'getFieldFormatService', async function () { return await server.fieldFormatServiceFactory(this.getUiSettingsService()) }) // for use outside of the request context, for special cases server.decorate('server', 'fieldFormatServiceFactory', async function (uiSettingsService) { const configVals = await ...; const getConfig = (key) => configVals[key]; return new FieldFormatService({ getConfig }); });
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
Move field formatters from ui/public to common so they can be used in both client and server.
Field formatters are exposed on the server via decorating the server with
fieldFormatters
which is an instance ofFieldFormatsService
. FieldFormatsService closely parallels how field formatters are exposed on the client by proving methods likegetDefaultInstance
andgetType
.The FieldFormat classes were also updated. Previously, the FieldFormats exported a function. Executing the function returned the FieldFormat class. Now the FieldFormats directly export a Class.