-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[Observability] Landing page for Observability #67467
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
Changes from all commits
fe63501
fe9d636
377a3f3
df6410b
5b55b84
e790500
3035d48
1aaeb79
f60716d
bae11f4
47170f2
69d4e3d
405491a
69ca82e
d382091
0636b5f
d9d1d6a
9111811
0d5b98d
94bf0fc
1067fad
3ce844f
f3b8cd8
6f59f71
e302e33
f2443fe
be5e21c
f1676a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
| import React from 'react'; | ||
| import ReactDOM from 'react-dom'; | ||
| import { EuiThemeProvider } from '../../../../legacy/common/eui_styled_components'; | ||
| import { AppMountParameters, CoreStart } from '../../../../../src/core/public'; | ||
| import { Home } from '../pages/home'; | ||
| import { PluginContext } from '../context/plugin_context'; | ||
|
|
||
| export const renderApp = (core: CoreStart, { element }: AppMountParameters) => { | ||
| const i18nCore = core.i18n; | ||
| const isDarkMode = core.uiSettings.get('theme:darkMode'); | ||
| ReactDOM.render( | ||
| <PluginContext.Provider value={{ core }}> | ||
| <EuiThemeProvider darkMode={isDarkMode}> | ||
| <i18nCore.Context> | ||
| <Home /> | ||
| </i18nCore.Context> | ||
| </EuiThemeProvider> | ||
| </PluginContext.Provider>, | ||
| element | ||
| ); | ||
| return () => { | ||
| ReactDOM.unmountComponentAtNode(element); | ||
| }; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import { createContext } from 'react'; | ||
| import { AppMountContext } from 'kibana/public'; | ||
|
|
||
| export interface PluginContextValue { | ||
| core: AppMountContext['core']; | ||
| } | ||
|
|
||
| export const PluginContext = createContext({} as PluginContextValue); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import { useContext } from 'react'; | ||
| import { PluginContext } from '../context/plugin_context'; | ||
|
|
||
| export function usePluginContext() { | ||
| return useContext(PluginContext); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,205 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import { | ||
| EuiButton, | ||
| EuiCard, | ||
| EuiFlexGrid, | ||
| EuiFlexGroup, | ||
| EuiFlexItem, | ||
| EuiHorizontalRule, | ||
| EuiIcon, | ||
| EuiImage, | ||
| EuiSpacer, | ||
| EuiText, | ||
| EuiTitle, | ||
| } from '@elastic/eui'; | ||
| import { i18n } from '@kbn/i18n'; | ||
| import React, { useEffect } from 'react'; | ||
| import styled from 'styled-components'; | ||
| import { usePluginContext } from '../../hooks/use_plugin_context'; | ||
| import { appsSection, tryItOutItemsSection } from './section'; | ||
|
|
||
| const Container = styled.div` | ||
| min-height: calc(100vh - 48px); | ||
| background: ${(props) => props.theme.eui.euiColorEmptyShade}; | ||
| `; | ||
|
|
||
| const Title = styled.div` | ||
| background-color: ${(props) => props.theme.eui.euiPageBackgroundColor}; | ||
| border-bottom: ${(props) => props.theme.eui.euiBorderThin}; | ||
| `; | ||
|
|
||
| const Page = styled.div` | ||
| width: 100%; | ||
| max-width: 1200px; | ||
| margin: 0 auto; | ||
| overflow: hidden; | ||
| } | ||
| `; | ||
|
|
||
| const EuiCardWithoutPadding = styled(EuiCard)` | ||
| padding: 0; | ||
| `; | ||
|
|
||
| export const Home = () => { | ||
| const { core } = usePluginContext(); | ||
|
|
||
| useEffect(() => { | ||
| core.chrome.setBreadcrumbs([ | ||
| { | ||
| text: i18n.translate('xpack.observability.home.breadcrumb.observability', { | ||
| defaultMessage: 'Observability', | ||
| }), | ||
| }, | ||
| { | ||
| text: i18n.translate('xpack.observability.home.breadcrumb.gettingStarted', { | ||
| defaultMessage: 'Getting started', | ||
| }), | ||
| }, | ||
| ]); | ||
| }, [core]); | ||
|
|
||
| return ( | ||
| <Container> | ||
| <Title> | ||
| <Page> | ||
| <EuiSpacer size="xxl" /> | ||
| <EuiFlexGroup> | ||
| <EuiFlexItem grow={false}> | ||
| <EuiIcon type="logoObservability" size="xxl" /> | ||
| </EuiFlexItem> | ||
| <EuiFlexItem> | ||
| <EuiTitle size="m"> | ||
| <h1> | ||
| {i18n.translate('xpack.observability.home.title', { | ||
| defaultMessage: 'Observability', | ||
| })} | ||
| </h1> | ||
| </EuiTitle> | ||
| </EuiFlexItem> | ||
| </EuiFlexGroup> | ||
| <EuiSpacer size="xxl" /> | ||
| </Page> | ||
| </Title> | ||
| <Page> | ||
| <EuiSpacer size="xxl" /> | ||
| <EuiFlexGroup direction="column"> | ||
| {/* title and description */} | ||
| <EuiFlexItem style={{ maxWidth: '50%' }}> | ||
| <EuiTitle size="s"> | ||
| <h2> | ||
| {i18n.translate('xpack.observability.home.sectionTitle', { | ||
| defaultMessage: 'Observability built on the Elastic Stack', | ||
| })} | ||
| </h2> | ||
| </EuiTitle> | ||
| <EuiSpacer size="m" /> | ||
| <EuiText size="s" color="subdued"> | ||
| {i18n.translate('xpack.observability.home.sectionsubtitle', { | ||
| defaultMessage: | ||
| 'Bring your logs, metrics, and APM traces together at scale in a single stack so you can monitor and react to events happening anywhere in your environment.', | ||
| })} | ||
| </EuiText> | ||
| </EuiFlexItem> | ||
|
|
||
| {/* Apps sections */} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason the EuiCard doesn't work for the App sections? Otherwise this all looks good.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might need to add an option in EUI to render EuiCard without the panel (border & shadow) display. But I'd certainly switch to using the EuiCard, and I can work on getting this display style into EUI
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about that too, but since we talked in one of the comments above that we shouldn't overwrite the Eui styles I thought I shouldn't do it. But I also agree that replacing it by EuiCard is way better. Since both of you are fine with that, I go with the EuiCard here too.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cauemarcondes thanks for considering that! In most cases, we want to do a flow like this (@sqren please correct me if I'm off here for APM):
I think we ran into a case of (2) here, and the EUI team is the BEST at helping us out with those situations. Thanks for being flexible!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the clarification @jasonrhodes .
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cchaos I just noticed there's a property called
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gah, hahaha, You're right. We just never added an example in our docs specifically for that. Glad you found it! |
||
| <EuiFlexItem> | ||
| <EuiSpacer size="s" /> | ||
| <EuiFlexGroup> | ||
| <EuiFlexItem> | ||
| <EuiFlexGrid columns={2}> | ||
| {appsSection.map((app) => ( | ||
| <EuiFlexItem> | ||
| <EuiCardWithoutPadding | ||
| display="plain" | ||
| layout="horizontal" | ||
| icon={<EuiIcon size="l" type={app.icon} />} | ||
| title={ | ||
| <EuiTitle size="xs" className="title"> | ||
| <h3>{app.title}</h3> | ||
| </EuiTitle> | ||
| } | ||
| description={app.description} | ||
| /> | ||
| </EuiFlexItem> | ||
| ))} | ||
| </EuiFlexGrid> | ||
| </EuiFlexItem> | ||
| <EuiFlexItem> | ||
| <EuiImage | ||
| size="xl" | ||
| alt="observability overview image" | ||
| url={core.http.basePath.prepend( | ||
| '/plugins/observability/assets/observability_overview.png' | ||
| )} | ||
| /> | ||
| </EuiFlexItem> | ||
| </EuiFlexGroup> | ||
| </EuiFlexItem> | ||
|
|
||
| {/* Get started button */} | ||
| <EuiFlexItem> | ||
| <EuiFlexGroup justifyContent="center" gutterSize="none"> | ||
| <EuiFlexItem grow={false}> | ||
| <EuiButton | ||
| fill | ||
| iconType="sortRight" | ||
| iconSide="right" | ||
| href={core.http.basePath.prepend('/app/home#/tutorial_directory/logging')} | ||
| > | ||
| {i18n.translate('xpack.observability.home.getStatedButton', { | ||
| defaultMessage: 'Get started', | ||
| })} | ||
| </EuiButton> | ||
| </EuiFlexItem> | ||
| </EuiFlexGroup> | ||
| </EuiFlexItem> | ||
|
|
||
| <EuiHorizontalRule margin="xl" /> | ||
|
|
||
| {/* Try it out */} | ||
| <EuiFlexItem> | ||
| <EuiFlexGroup justifyContent="center"> | ||
| <EuiFlexItem grow={false}> | ||
| <EuiTitle size="s"> | ||
| <h3> | ||
| {i18n.translate('xpack.observability.home.tryItOut', { | ||
| defaultMessage: 'Try it out', | ||
| })} | ||
| </h3> | ||
| </EuiTitle> | ||
| </EuiFlexItem> | ||
| </EuiFlexGroup> | ||
| </EuiFlexItem> | ||
|
|
||
| {/* Try it out sections */} | ||
| <EuiFlexItem> | ||
| <EuiFlexGroup justifyContent="center"> | ||
| {tryItOutItemsSection.map((item) => ( | ||
| <EuiFlexItem grow={false} key={item.id} style={{ width: '260px' }}> | ||
| <EuiCard | ||
| layout="horizontal" | ||
| icon={<EuiIcon size="l" type={item.icon} />} | ||
| title={ | ||
| <EuiTitle size="xs" className="title"> | ||
| <h3>{item.title}</h3> | ||
| </EuiTitle> | ||
| } | ||
| description={item.description} | ||
| target={item.target} | ||
| href={item.href} | ||
| /> | ||
| </EuiFlexItem> | ||
| ))} | ||
| </EuiFlexGroup> | ||
| <EuiSpacer /> | ||
| </EuiFlexItem> | ||
| </EuiFlexGroup> | ||
| </Page> | ||
| </Container> | ||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
| import { i18n } from '@kbn/i18n'; | ||
|
|
||
| interface ISection { | ||
| id: string; | ||
| title: string; | ||
| icon: string; | ||
| description: string; | ||
| href?: string; | ||
| target?: '_blank'; | ||
| } | ||
|
|
||
| export const appsSection: ISection[] = [ | ||
| { | ||
| id: 'logs', | ||
| title: i18n.translate('xpack.observability.section.apps.logs.title', { | ||
| defaultMessage: 'Logs', | ||
| }), | ||
| icon: 'logoLogging', | ||
| description: i18n.translate('xpack.observability.section.apps.logs.description', { | ||
| defaultMessage: | ||
| 'The Elastic Stack (sometimes known as the ELK Stack) is the most popular open source logging platform.', | ||
| }), | ||
| }, | ||
| { | ||
| id: 'apm', | ||
| title: i18n.translate('xpack.observability.section.apps.apm.title', { | ||
| defaultMessage: 'APM', | ||
| }), | ||
| icon: 'logoAPM', | ||
| description: i18n.translate('xpack.observability.section.apps.apm.description', { | ||
| defaultMessage: | ||
| 'See exactly where your application is spending time so you can quickly fix issues and feel good about the code you push.', | ||
| }), | ||
| }, | ||
| { | ||
| id: 'metrics', | ||
| title: i18n.translate('xpack.observability.section.apps.metrics.title', { | ||
| defaultMessage: 'Metrics', | ||
| }), | ||
| icon: 'logoMetrics', | ||
| description: i18n.translate('xpack.observability.section.apps.metrics.description', { | ||
| defaultMessage: | ||
| 'Already using the Elastic Stack for logs? Add metrics in just a few steps and correlate metrics and logs in one place.', | ||
| }), | ||
| }, | ||
| { | ||
| id: 'uptime', | ||
| title: i18n.translate('xpack.observability.section.apps.uptime.title', { | ||
| defaultMessage: 'Uptime', | ||
| }), | ||
| icon: 'logoUptime', | ||
| description: i18n.translate('xpack.observability.section.apps.uptime.description', { | ||
| defaultMessage: | ||
| 'React to availability issues across your apps and services before they affect users.', | ||
| }), | ||
| }, | ||
| ]; | ||
|
|
||
| export const tryItOutItemsSection: ISection[] = [ | ||
| { | ||
| id: 'demo', | ||
| title: i18n.translate('xpack.observability.section.tryItOut.demo.title', { | ||
| defaultMessage: 'Demo Playground', | ||
| }), | ||
| icon: 'play', | ||
| description: '', | ||
| href: 'https://demo.elastic.co/', | ||
| target: '_blank', | ||
| }, | ||
| { | ||
| id: 'sampleData', | ||
| title: i18n.translate('xpack.observability.section.tryItOut.sampleData.title', { | ||
| defaultMessage: 'Add sample data', | ||
| }), | ||
| icon: 'documents', | ||
| description: '', | ||
| href: '/app/home#/tutorial_directory/sampleData', | ||
| }, | ||
| ]; |

Uh oh!
There was an error while loading. Please reload this page.