Skip to content
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

Implementing ReferenceOrValueEmbeddable for visualize embeddable #76088

Merged
merged 19 commits into from
Sep 15, 2020

Conversation

majagrubic
Copy link
Contributor

@majagrubic majagrubic commented Aug 27, 2020

Summary

This PR implements ReferenceOrValueEmbeddable for visualize embeddable, so that we can easily switch between by-value and by-reference embeddable. It uses AttributeService where appropriate.
Add to library

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@majagrubic majagrubic marked this pull request as ready for review September 10, 2020 14:40
@majagrubic majagrubic requested a review from a team September 10, 2020 14:40
@majagrubic majagrubic requested a review from a team as a code owner September 10, 2020 14:40
@majagrubic majagrubic added Feature:Dashboard Dashboard related features release_note:roadmap Team:Visualizations Visualization editors, elastic-charts and infrastructure v7.1.0 labels Sep 10, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app (Team:KibanaApp)

@botelastic botelastic bot added the Feature:Embedding Embedding content via iFrame label Sep 10, 2020
@majagrubic majagrubic changed the title [DRAFT] Implementing ReferenceOrValueEmbeddable for visualize embeddable Implementing ReferenceOrValueEmbeddable for visualize embeddable Sep 10, 2020
Copy link
Contributor

@ThomThomson ThomThomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally in chrome, everything works as it should.

I did notice a few small inconsistencies with custom panel titles and time ranges, during the add / unlink actions but they are fixed in the next version of lens by value so it would be best not to address them here.

I have a few small questions/comments about the code but otherwise everything LGTM

return this.attributeService.inputIsRefType(input as VisualizeByReferenceInput);
};

getInputAsValueType = async (): Promise<VisualizeByValueInput> => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the attribute service here as well? The implementation is quite simple, but it could be more consistent that way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried, but it's honestly too much hassle. I'd need a customUnwrapMethod and the code becomes so much more complicated. I don't think it's worth the effort.

((savedObjectId: string, input: Partial<I>, parent?: IContainer) => {
throw new Error(`Creation from saved object not supported by type ${def.type}`);
}),
createFromSavedObject: def.createFromSavedObject
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure why this change is required, why the bind, and why a ternary here instead of nullish coalescing?

Copy link
Contributor Author

@majagrubic majagrubic Sep 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn't bound properly and was causing an error when creating visualize embeddable from saved object:
https://github.com/elastic/kibana/blob/master/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx#L108

savedVis?: VisSavedObject;
};
export type VisualizeByValueInput = { attributes: VisualizeSavedObjectAttributes } & VisualizeInput;
export type VisualizeByReferenceInput = SavedObjectEmbeddableInput & VisualizeInput;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice looking input shapes!

if ('id' in savedItem) {
return { ...originalInput, savedObjectId: savedItem.id } as RefType;
}
return { ...originalInput } as RefType;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering about this case for when there isn't an id in the returned saved item - is this part of the error case that you've added to the API? If so, shouldn't we return the error?

Copy link
Contributor Author

@majagrubic majagrubic Sep 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The id check here is to make typescript happy. But good point that we need error handling for the scenario where saving a saved object fails

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay yes, makes sense. You need the check because you changed the signature of the custom save method to send back an error case.

@majagrubic
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Member

@ppisljar ppisljar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code LGTM

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Build metrics

page load bundle size

id value diff baseline
dashboard 711.6KB +140.0B 711.5KB
embeddable 430.6KB -71.0B 430.7KB
visualizations 412.5KB +5.6KB 406.9KB
total +5.7KB

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Contributor

@ThomThomson ThomThomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally on chrome - everything still works great, and all my questions have been answered.

LGTM!

@@ -3,6 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
"requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "usageCollection", "inspector"],
"requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "usageCollection", "inspector", "dashboard"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we certain the only way to address this is to introduce a required dependency between visualizations and dashboard?

This doesn't feel right to me, but I'm also not familiar enough with the AttributeService to understand whether alternatives are possible.

I just wanted to raise the question before we move forward with merging this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Luke! This is a really good point.

I made the decision to move attributeService out of the embeddable plugin and temporarily into the dashboard plugin in #74302. It was moved because it makes use of the savedObjectsClient, and @streamich and I had a discussion about how best to avoid coupling savedObjects and embeddables.

The attributeService is an additional layer of abstraction on top of savedObjects. It provides a default implementation that embeddables can use to deal more easily with input that can be either 'by value' or 'by reference' . It also provides code for translating between the two types of input.

The dashboard plugin is not its permanent home, however, it needs to stay somewhere until we find a better place for it.

Do you have any thoughts on where it could live?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, right i didn't notice this ...
saved objects is its own plugin, why did we prefer having attribute service in dashboard plugin instead of embeddable ? it seems embeddable specific ? if we don't want to add saved objects dependency to embeddable maybe this should be its own plugin ? shouldn't be a problem now that we can group plugins under domain folders

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attribute service is indeed embeddable specific, but it's also only used within the dashboard (at least for now). I don't think saved objects plugin is the best place for it, since it's more than just saved objects. If there are major concerns about this living inside the dashboard, I think a separate plugin is the best way to go.
I am going to merge this PR now as much of the logic will remain unaffected regardless of where the attribute service lives. If concerns exists, I will revisit this in a follow-up PR.

@majagrubic majagrubic merged commit e6e7187 into elastic:master Sep 15, 2020
@majagrubic majagrubic deleted the vis-by-value-or-reference branch September 15, 2020 09:18
majagrubic pushed a commit that referenced this pull request Sep 15, 2020
) (#77457)

* Adding dashboard as dependency to visualize

* Making visualize embeddable as ReferenceOrValueEmbeddable

* Adding attribute service to visualize embeddable

* Binding createFromSavedObject method

* Add/remove visualize embeddable from library

* Removing debugger statement

* Using custom save method on attribute service

* Reverting to not using attribute service

* Resetting flag value

* Fix i18n title and update title

* Using custom save method on attribute service

* Fixing eslint

* Using custom save method in visualize embeddable factory

* Making getInputAsValueType return Promise as it should

* Better error handling when saving a visualization fails

Co-authored-by: Elastic Machine <[email protected]>

Co-authored-by: Elastic Machine <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Dashboard Dashboard related features Feature:Embedding Embedding content via iFrame Team:Visualizations Visualization editors, elastic-charts and infrastructure v7.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants