Skip to content

Conversation

@clintandrewhall
Copy link
Contributor

@clintandrewhall clintandrewhall commented Jan 19, 2022

Replaced by #123772

Summary

This is a proof-of-concept for a new plugin I'm calling "Engagement", which enables the integration of Drift on certain pages in Kibana. It is fully mocked in Storybook, as well.

Rather than add the logic to every page, this approach opts for plugins to add the engagement plugin as a dependency, wrap their app in the ServicesContext provided by the start contract, and explicitly render the chat component. I opted for this approach so we can be surgical in how we add this component, (for now).

Screen Shot 2022-01-19 at 1 14 14 AM

Screen Shot 2022-01-19 at 1 14 54 AM

Why a new plugin?

  • To have a home for other engagement projects, (product tours?, etc)
  • To make the implementation a bit more abstract.
  • cloud is an xpack plugin, which limits its code use in OSS plugins.

To Test

Storybook

Run yarn storybook engagement from /kibana.

In Kibana

Add the following to kibana.dev.yml:

engagement.drift.enabled: true
engagement.drift.chatURL: "https://elasticcloud-production-chat-us-east-1.s3.amazonaws.com/drift-iframe.html"
engagement.drift.pocID: "53877975"
engagement.drift.pocEmail: "[email protected]"
engagement.drift.pocJWT: "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1Mzg3Nzk3NSIsImV4cCI6MTY0MjUxNDc0Mn0.CcAZbD8R865UmoHGi27wKn0aH1bzkZXhX449yyDH2Vk"

Known Issues

  • For some reason, I can't get the config to be read in public/plugin.tsx. I confirmed it works on the server, though.
  • @SergeyPoluektov The portions of the config starting with poc need to be sourced appropriately, rather than set in config.
  • @SergeyPoluektov The chat iframe is receiving a message to size to 100px wide after clicking on the chat bubble.

Next steps

  • Review appropriateness of approach with stakeholders.
  • Write extensive tests and documentation.
  • Identify pages where the chat icon should be placed (@alexfrancoeur)

@clintandrewhall clintandrewhall added WIP Work in progress Team:Cloud Team:SharedUX Platform AppEx-SharedUX (formerly Global Experience) t// labels Jan 19, 2022
Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

Just passing by. The approach to have each plugin to manually opt-in by importing and using the component sounds good to me.

Comment on lines +77 to +86
<startServices.engagement.ContextProvider>
<Router history={history}>
<AgentPolicyContextProvider>
<PackageInstallProvider
notifications={startServices.notifications}
theme$={theme$}
>
<IntegrationsHeader {...{ setHeaderActionMenu, theme$ }} />
{children}
<EngagementChat />
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this engagement.ContextProvider only used for the EngagementChat component? If so, did you though about exposing a context-wrapper component via the engagement plugin's contract instead of having to use both the plugin's contract to access the context provider and direct imports to import the chat component?

something like

<Router history={history}>
  <....>
    <startServices.engagement.Chat />
  </...>
</Router>

this is a pattern commonly used in other parts of Kibana when in need of exposing preconfigured/context-injected components to other plugins

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea was for this plugin to have more than one component, so the initial API matters.

That's an interesting approach! I'll have to think about it a bit more. My concerns with it at the moment are:

  • getting startServices down the tree in cases where a component is more granular, (e.g. a configured drop down control.
  • storing all startServices in context in the off chance you use a single component, whereas the ContextProvider simply provides services for components. I'm not sure if the difference is meaningful or not.
  • mocking the startServices in Storybook and Jest tests has been notoriously difficult. I'm loathe to introduce a complex startServices construct when you're only relying on ContextProvider.

I need to look into this more.

Comment on lines +28 to +32
const getContext = () => {
const { location, navigator, innerHeight, innerWidth } = window;
const { hash, host, hostname, href, origin, pathname, port, protocol, search } = location;
const { language, userAgent } = navigator;
const { title, referrer } = document;
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the purpose of this function compared to using window and document directly? To have more control over what's we're effectively sending and avoid potentially leaking things when calling chatIframe.contentWindow.postMessage?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just understanding what we have to send to the frame. This is a refactored bit of another draft PR from the Journey team, and, since I don't have insight into the messaging API, splitting it out like this seemed like a good way to keep track of precisely what we need to send, (and for testing purposes).

@SergeyPoluektov
Copy link
Contributor

The chat iframe is receiving a message to size to 100px wide after clicking on the chat bubble.

This issue seemed solved, although I didn't get last update from Drift support. But the chat window is sizing correctly now

@kibana-ci
Copy link

kibana-ci commented Jan 25, 2022

💔 Build Failed

Failed CI Steps

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
engagement - 9 +9

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
engagement - 1.6KB +1.6KB
fleet 644.5KB 644.6KB +110.0B
total +1.7KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
engagement - 3.8KB +3.8KB
fleet 112.8KB 113.0KB +140.0B
sharedUX 3.7KB 3.8KB +88.0B
total +4.0KB
Unknown metric groups

async chunk count

id before after diff
engagement - 1 +1

History

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

id: 'user-id',
email: '[email protected]',
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to find a way to obtain a Kibana or Cloud user data here. Particularly we need to get user ID (might be Kibana user's username) and user email (this should be the same as in Cloud for Cloud users)
@pgayvallet maybe you know how to do this?

@clintandrewhall
Copy link
Contributor Author

Closing in favor of #123772

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Team:Cloud Team:SharedUX Platform AppEx-SharedUX (formerly Global Experience) t// WIP Work in progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants