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

[Example] Embeddable by Reference and Value #68719

Merged
merged 25 commits into from
Jul 9, 2020

Conversation

ThomThomson
Copy link
Contributor

@ThomThomson ThomThomson commented Jun 9, 2020

Summary

This PR is a combination of #62698 and #64131.

In short, it provides an example book embeddable which does the following:

  • Uses a union type to ensure that its input is either by reference or by value, and nothing in between.
  • All behavior that requires the saved object client is handled by a separate service provided by the factory to fetch.
  • Supports editing by value or by reference.
  • Supports changing a by reference embeddable to by value and vice versa.

Screen Shot 2020-06-11 at 9 46 07 PM

Screen Shot 2020-06-11 at 9 46 47 PM

Screen Shot 2020-06-11 at 9 46 30 PM

Checklist

For maintainers

@ThomThomson ThomThomson added Feature:Embedding Embedding content via iFrame release_note:skip Skip the PR/issue when compiling release notes labels Jun 9, 2020
@ThomThomson ThomThomson added Team:Visualizations Visualization editors, elastic-charts and infrastructure Team:AppArch labels Jun 11, 2020
@ThomThomson ThomThomson marked this pull request as ready for review June 11, 2020 18:16
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-arch (Team:AppArch)

@ThomThomson ThomThomson requested a review from a team as a code owner June 12, 2020 02:03
Copy link
Contributor

@majagrubic majagrubic left a comment

Choose a reason for hiding this comment

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

Looks great! Left some questions for my own understanding mostly

> {
constructor(private type: string, private savedObjectsClient: SavedObjectsClientContract) {}

public async unwrapAttributes(input: RefType | ValType): Promise<SavedObjectAttributes> {
Copy link
Contributor

@Dosant Dosant Jun 12, 2020

Choose a reason for hiding this comment

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

We assume that saved object's attributes are matching embeddable input, correct?

But this isn't the case, for example, for dashboardContainer, right?

I wonder if we should keep this in mind and allow to provide custom mappers? Or are we consider dashboardContainer a legacy example?


Or is my example not related at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We aren't assuming that the saved object's attributes match the attributes key in embeddable input, because attribute_service actually requires it (which comes with its own problems).

When creating an instance of attribute_service, you need to provide a type argument for the saved object attributes AttributeType but also, the value type argument must extend { attributes: AttributeType }. This means that any embeddable that wants to make use of this service must follow an exact convention.

I certainly wouldn't say that this convention would mark any other types of embeddable as legacy. The idea is that it's more of an optional service (helper maybe?) to make it easier to adopt the 'by value OR by reference' paradigm.

The custom mappers you suggest might make this a little more flexible. For instance, a valueAttributesMapper function param which takes the 'by value' input and returns the attributes, but it seems like that would require method level type parameters instead of the current class level ones.

Do you have any thoughts on if it would be best to generalize this service, or leave it as an optional helper with very stringent requirements?

@stacey-gammon

Copy link
Contributor

Choose a reason for hiding this comment

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

@ppisljar, can you look into this and provide your thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

i am wondering if there is any existing embeddable this can be used for ? or do we know for sure of future embddable that would need this ? it feels we don't have the scenario where embeddable input would equal saved object attributes, also loading of saved objects in most cases happen in special way (is not general).

if that is the case then i would vote for not having this service at all and leave it up to the embeddable implementation to do this (if that is anyway what they would need to do, at least for current embeddables)

ThomThomson added a commit to ThomThomson/kibana that referenced this pull request Jun 25, 2020
@ThomThomson
Copy link
Contributor Author

@elasticmachine merge upstream

@ThomThomson
Copy link
Contributor Author

@elasticmachine merge upstream

@elasticmachine
Copy link
Contributor

merge conflict between base and head

return true;
}

public createFromSavedObject = async (
Copy link
Member

Choose a reason for hiding this comment

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

do we need this still ?

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 didn't notice that it was optional! I've removed this method.


public async unwrapAttributes(input: RefType | ValType): Promise<SavedObjectAttributes> {
if (isSavedObjectEmbeddableInput(input)) {
const savedObject: SimpleSavedObject<SavedObjectAttributes> = await this.savedObjectsClient.get<
Copy link
Member

Choose a reason for hiding this comment

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

we are using saved object client to get a saved object .... our general approach in kibana is to actually use a higher level abstraction (savedVisualizationLoader, savedSearchLoader, indexPatternsService) which will usually perform quite some magic on top of getting the saved object.

i am wondering do we/will we have any embeddable where saved object attributes are gonna exactly equal embeddable input ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed in our sync -- just documenting here -- The attribute service is meant to be used as a higher level abstraction in multiple places including, lens & visualize to provide a standardized pattern for using Embeddables by reference or value.

> {
constructor(private type: string, private savedObjectsClient: SavedObjectsClientContract) {}

public async unwrapAttributes(input: RefType | ValType): Promise<SavedObjectAttributes> {
Copy link
Member

Choose a reason for hiding this comment

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

i am wondering if there is any existing embeddable this can be used for ? or do we know for sure of future embddable that would need this ? it feels we don't have the scenario where embeddable input would equal saved object attributes, also loading of saved objects in most cases happen in special way (is not general).

if that is the case then i would vote for not having this service at all and leave it up to the embeddable implementation to do this (if that is anyway what they would need to do, at least for current embeddables)

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Build metrics

@kbn/optimizer bundle module count

id value diff baseline
embeddable 40 +1 39

History

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

Copy link
Contributor

@majagrubic majagrubic left a comment

Choose a reason for hiding this comment

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

I tested this example and works and looks great.
As discussed in our sync with @ppisljar two days ago - this is the approach we'd like to take with Lens and Visualize embeddables. We'll need to add some tests for AttributeService before we start using it in production embeddables, but not a blocker for now.

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.

discussed offline and agreed this is the right approach

@ThomThomson ThomThomson merged commit 33fd5cf into elastic:master Jul 9, 2020
ThomThomson added a commit to ThomThomson/kibana that referenced this pull request Jul 9, 2020
Added an attribute service to embeddable start contract which provides a higher level abstraction for embeddables that can be by reference OR by value. Added an example that uses this service.
ThomThomson added a commit that referenced this pull request Jul 9, 2020
Added an attribute service to embeddable start contract which provides a higher level abstraction for embeddables that can be by reference OR by value. Added an example that uses this service.
@ThomThomson ThomThomson linked an issue Jul 16, 2020 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Embedding Embedding content via iFrame release_note:skip Skip the PR/issue when compiling release notes Team:Visualizations Visualization editors, elastic-charts and infrastructure v7.9.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Example] Embeddable by Ref or Value
7 participants