Skip to content

Commit

Permalink
[Observability] Landing page for Observability (elastic#67467)
Browse files Browse the repository at this point in the history
* creating overview page and menu

* styling the home page

* adjusting breadcrumb

* renaming isnt working

* renaming isnt working

* renaming isnt working

* fixing import

* fixing scroll when resize window

* fixing eslint errors

* prepending links

* adding target option

* refactoring

* adding dark mode support

* fixing prettier format

* fixing i18n

* reverting some unnecessary changes

* addressing PR comments

* fixing functional tests

* ordering observability menu

* fixing tests

* addressing PR comments

* fixing test

* fixing scroll

* addressing pr comments

* addressing pr comments

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
cauemarcondes and elasticmachine committed Jun 8, 2020
1 parent e96ad7b commit 3a97729
Show file tree
Hide file tree
Showing 24 changed files with 408 additions and 39 deletions.
3 changes: 2 additions & 1 deletion x-pack/.i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"xpack.triggersActionsUI": "plugins/triggers_actions_ui",
"xpack.upgradeAssistant": "plugins/upgrade_assistant",
"xpack.uptime": ["plugins/uptime"],
"xpack.watcher": "plugins/watcher"
"xpack.watcher": "plugins/watcher",
"xpack.observability": "plugins/observability"
},
"translations": [
"plugins/translations/translations/zh-CN.json",
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/apm/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
core.application.register({
id: 'apm',
title: 'APM',
order: 8100,
order: 8300,
euiIconType: 'apmApp',
appRoute: '/app/apm',
icon: 'plugins/apm/public/icon.svg',
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/infra/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class Plugin
defaultMessage: 'Logs',
}),
euiIconType: 'logsApp',
order: 8000,
order: 8100,
appRoute: '/app/logs',
category: DEFAULT_APP_CATEGORIES.observability,
mount: async (params: AppMountParameters) => {
Expand All @@ -89,7 +89,7 @@ export class Plugin
defaultMessage: 'Metrics',
}),
euiIconType: 'metricsApp',
order: 8001,
order: 8200,
appRoute: '/app/metrics',
category: DEFAULT_APP_CATEGORIES.observability,
mount: async (params: AppMountParameters) => {
Expand Down
29 changes: 29 additions & 0 deletions x-pack/plugins/observability/public/application/index.tsx
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);
};
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions x-pack/plugins/observability/public/context/plugin_context.tsx
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);
12 changes: 12 additions & 0 deletions x-pack/plugins/observability/public/hooks/use_plugin_context.tsx
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);
}
205 changes: 205 additions & 0 deletions x-pack/plugins/observability/public/pages/home/index.tsx
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 */}
<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>
);
};
84 changes: 84 additions & 0 deletions x-pack/plugins/observability/public/pages/home/section.ts
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',
},
];
Loading

0 comments on commit 3a97729

Please sign in to comment.