-
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
Expression datatable formatting hints #43091
Expression datatable formatting hints #43091
Conversation
💚 Build Succeeded |
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.
Overall LGTM, just added a few questions & comments.
src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts
Outdated
Show resolved
Hide resolved
@@ -21,9 +21,15 @@ import { map } from 'lodash'; | |||
|
|||
const name = 'kibana_datatable'; | |||
|
|||
export interface SerializedFieldFormat<TParams = object> { |
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.
Since this is public/exported, maybe it would make sense to co-locate it with getFormat
& the pipeline utilities, and import it into here instead? Since it doesn't have anything to do with the kibana_datatable
type specifically.
To some extent it doesn't matter a lot right now since all of the ui/visualize/loader
stuff is going away or moving eventually anyway, but IMO this is the only thing in the PR that feels like maybe it should be moved.
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.
That's how I started out over here (5548579), but somehow the type check fails in completely unrelated places if I do that - something about importing legacy stuff from the new world. Then I thought it's maybe even cleaner that way because the types of the data table are all defined in one place.
Maybe this was a configuration error already fixed, I'll move it over and check.
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 I didn't think about that @flash1293 -- you are totally right. You can import new platform into legacy, but you cannot import legacy into new platform.
Not sure what makes the most then, since we definitely won't want to keep this in with the datatable type longer term. Maybe instead we should stick it in the types/common.ts
file for now? I just don't want it to get lost in expression_types/kibana_datatable.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.
Moved it over to common
src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts
Outdated
Show resolved
Hide resolved
name: column.name, | ||
})), | ||
columns: response.columns.map((column: any) => { | ||
const cleanedColumn: KibanaDatatable['columns'][0] = { |
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.
Do you think enough folks will have a use case for this that it'd be worth exporting Column
separately, perhaps as KibanaDatatableColumn
, so that you don't have to do stuff like this?
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 do we always take the first column ?
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.
Because all of the columns in the array have the same type, this is a hack. I agree with @lukeelmers here, it makes sense to expose KibanaDatatableColumn
to be able to cleanly reference this type.
Current solution works like this:
KibanaDatatable
is of type { columns: Array<Column> }
KibanaDatatable['columns]
is of type Array<Column>
now the question is how do I get to the type of the Column itself? I could do a proper type inference like this: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#type-inference-in-conditional-types or I could do a dirty hack and get the type of the 0
property of KibanaDatatable['columns]
which happens to be Column
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.
A bit orthogonal to the discussion here, but in cases where magic like this is necessary, I find the syntax KibanaDatatable['columns'][number]
to be slightly easier to grok, mostly because the index number can be distracting as @ppisljar points out.
But agreed that exporting separately feels like the way to go here.
Pinging @elastic/kibana-app-arch |
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
name: column.name, | ||
})), | ||
columns: response.columns.map((column: any) => { | ||
const cleanedColumn: KibanaDatatable['columns'][0] = { |
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 do we always take the first column ?
timeRange: get(context, 'timeRange', null), | ||
query: get(context, 'query', null), | ||
filters: get(context, 'filters', null), | ||
timeRange: get(context, 'timeRange', undefined), |
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 went in because the existing RequestHandler
types don't allow null here (but they allow undefined)
@@ -42,7 +42,7 @@ export interface RequestHandlerParams { | |||
visParams?: any; | |||
} | |||
|
|||
export type RequestHandler = <T>(params: RequestHandlerParams) => T; | |||
export type RequestHandler<T = unknown> = (params: RequestHandlerParams) => T; |
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.
moving the type parameter to the outer type to be able to specify it in courier-specific type. Inferred types in other usages should work like before.
💔 Build Failed |
@lukeelmers :this: is the error I meant - no idea why this happens but if we don't import legacy from within NP world, it works. |
This reverts commit 4738f82.
💚 Build Succeeded |
💚 Build Succeeded |
This PR adds an optional property to the column of expression data tables:
formatHint
. It carries the JSON representation of a field formatter config that can be used by expression renderers to format the values of the column correctly.This is a design decision with trade-offs: Conceptually formatting belongs to the presentation of the data and shouldn't be part of the "data source"-ey expression functions. But correctly formatting something is very strongly coupled to the source of a given data table - the data source (in this case
esaggs
) knows about source-specific formatting information (e.g. user defined field formatters on the given index pattern or the interval of a date_histogram aggregation to format dates accordingly). The render functions shouldn't know or care about these concepts and passing in the formatting information as sub-expressions of the renderer function would cause redundant information on the expression that can get out of sync. Providing the data source with a way to pass formatting hints along with the data itself together with a way to overwrite/ignore this formatting offers the benefits of both ways - a clean and robust expression that integrates with existing formatting sources of the system in the standard case, but still full control over the formatting if this is necessary.The
esaggs
function is extended with an optional boolean argumentincludeFormatHints
that can be set to add formatting information to the data table returned byesaggs
. It uses the same implementation as thebuild_pipeline
helper for the expression loader for Visualize.Theoretically the Visualize renderers and
build_pipeline
could be rewritten to not include the formatting information in the arguments of the render function but to use the format hints from esaggs, but that's out of scope for this PR IMHO.Not 100% sure about the files the various helpers and types should reside, open for suggestions here.