mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[SharedUX] SCSS migration Home plugin (#214859)
## Summary - rewriting styles in home plugin using `@emotion/react` - updating functional a11y and unit tests - adding a util function in core-app for fullScreenGraphicsMixin mixin
This commit is contained in:
parent
109d79d3f0
commit
27ca807175
26 changed files with 298 additions and 263 deletions
|
@ -9,7 +9,12 @@
|
|||
|
||||
// This file replaces scss core/public/_mixins.scss
|
||||
|
||||
import { css } from '@emotion/react';
|
||||
import { css, keyframes } from '@emotion/react';
|
||||
import { COLOR_MODES_STANDARD, UseEuiTheme, euiCanAnimate } from '@elastic/eui';
|
||||
import bg_top_branded from './styles/core_app/images/bg_top_branded.svg';
|
||||
import bg_top_branded_dark from './styles/core_app/images/bg_top_branded_dark.svg';
|
||||
import bg_bottom_branded from './styles/core_app/images/bg_bottom_branded.svg';
|
||||
import bg_bottom_branded_dark from './styles/core_app/images/bg_bottom_branded_dark.svg';
|
||||
|
||||
// The `--kbnAppHeadersOffset` CSS variable is automatically updated by
|
||||
// styles/rendering/_base.scss, based on whether the Kibana chrome has a
|
||||
|
@ -19,3 +24,58 @@ export const kibanaFullBodyHeightCss = (additionalOffset = 0) => css`
|
|||
100vh - var(--kbnAppHeadersOffset, var(--euiFixedHeadersOffset, 0)) - ${additionalOffset}px
|
||||
);
|
||||
`;
|
||||
|
||||
export const fullScreenGraphicsMixinStyles = (euiZLevel: number, euiTheme: UseEuiTheme) => {
|
||||
const lightOrDarkTheme = (lightSvg: any, darkSvg: any) => {
|
||||
return euiTheme.colorMode === COLOR_MODES_STANDARD.light ? lightSvg : darkSvg;
|
||||
};
|
||||
const fullScreenGraphicsFadeIn = keyframes`
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
return css({
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
zIndex: euiZLevel + 1000,
|
||||
background: 'inherit',
|
||||
backgroundColor: euiTheme.euiTheme.colors.backgroundBasePlain,
|
||||
opacity: 0,
|
||||
overflow: 'auto',
|
||||
[euiCanAnimate]: {
|
||||
animation: `${fullScreenGraphicsFadeIn} ${euiTheme.euiTheme.animation.extraSlow} ${euiTheme.euiTheme.animation.resistance} 0s forwards`,
|
||||
},
|
||||
'.kbnBody--hasHeaderBanner &': {
|
||||
top: 'var(--kbnHeaderBannerHeight)',
|
||||
},
|
||||
'&::before': {
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 1,
|
||||
width: '400px',
|
||||
height: '400px',
|
||||
content: `url(${lightOrDarkTheme(bg_top_branded, bg_top_branded_dark)})`,
|
||||
},
|
||||
'&::after': {
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
zIndex: 1,
|
||||
width: '400px',
|
||||
height: '400px',
|
||||
content: `url(${lightOrDarkTheme(bg_bottom_branded, bg_bottom_branded_dark)})`,
|
||||
},
|
||||
[`@media (max-width: ${euiTheme.euiTheme.breakpoint.l}px)`]: {
|
||||
'&::before, &::after': {
|
||||
content: 'none',
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -309,4 +309,4 @@ export type { CoreSystem } from '@kbn/core-root-browser-internal';
|
|||
|
||||
export { __kbnBootstrap__ } from '@kbn/core-root-browser-internal';
|
||||
|
||||
export { kibanaFullBodyHeightCss } from './cssUtils';
|
||||
export { kibanaFullBodyHeightCss, fullScreenGraphicsMixinStyles } from './cssUtils';
|
||||
|
|
|
@ -16,7 +16,6 @@ import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
|
|||
import { SampleDataTabKibanaProvider } from '@kbn/home-sample-data-tab';
|
||||
import { HomeApp } from './components/home_app';
|
||||
import { getServices } from './kibana_services';
|
||||
import './index.scss';
|
||||
|
||||
export const renderApp = async (
|
||||
element: HTMLElement,
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
.homDataAdd__illustration {
|
||||
display: block;
|
||||
margin-block: 0 #{-($euiSizeXL + $euiSizeXS)};
|
||||
margin-inline: auto;
|
||||
|
||||
@include euiBreakpoint('m', 'l', 'xl') {
|
||||
margin-block-end: -$euiSizeXL;
|
||||
}
|
||||
|
||||
@include euiBreakpoint('l', 'xl') {
|
||||
inline-size: 80%;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Prefix all styles with "hom" to avoid conflicts.
|
||||
// Examples
|
||||
// homChart
|
||||
// homChart__legend
|
||||
// homChart__legend--small
|
||||
// homChart__legend-isLoading
|
||||
|
||||
@import 'welcome';
|
||||
@import 'solutions_section';
|
||||
@import 'add_data';
|
||||
@import 'manage_data';
|
||||
@import 'tutorial/tutorial';
|
|
@ -1,5 +0,0 @@
|
|||
.homDataManage__item {
|
||||
@include euiBreakpoint('l', 'xl') {
|
||||
max-width: calc(33.33% - #{$euiSizeM * 2});
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
.homSolutions__content {
|
||||
padding-block-start: 0;
|
||||
}
|
||||
|
||||
.homSolutions__item {
|
||||
@include euiBreakpoint('l', 'xl') {
|
||||
max-inline-size: calc(33.33% - #{$euiSizeM * 2});
|
||||
}
|
||||
}
|
||||
|
||||
.homSolutionPanel {
|
||||
img {
|
||||
background-color: $euiColorPrimary;
|
||||
max-block-size: $euiSize * 10;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
&--enterpriseSearch img {
|
||||
background-color: $euiColorWarning;
|
||||
}
|
||||
|
||||
&--observability img {
|
||||
background-color: $euiColorAccent;
|
||||
}
|
||||
|
||||
&--securitySolution img {
|
||||
background-color: $euiColorAccentSecondary;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
.homWelcome {
|
||||
@include kibanaFullScreenGraphics($euiZLevel6);
|
||||
}
|
||||
|
||||
.homWelcome__header {
|
||||
position: relative;
|
||||
padding: $euiSizeXL;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.homWelcome__logo {
|
||||
margin-bottom: $euiSizeXL;
|
||||
@include kibanaCircleLogo;
|
||||
@include euiBottomShadowMedium;
|
||||
}
|
||||
|
||||
.homWelcome__footerAction {
|
||||
margin-right: $euiSizeS;
|
||||
}
|
||||
|
||||
.homWelcome__content {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
max-width: 512px;
|
||||
padding-left: $euiSizeXL;
|
||||
padding-right: $euiSizeXL;
|
||||
z-index: 10;
|
||||
}
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
exports[`AddData render 1`] = `
|
||||
<_EuiPageSection
|
||||
aria-labelledby="homDataAdd__title"
|
||||
aria-labelledby="homeDataAdd__title"
|
||||
bottomBorder={true}
|
||||
className="homDataAdd"
|
||||
paddingSize="xl"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
|
@ -15,7 +14,7 @@ exports[`AddData render 1`] = `
|
|||
size="s"
|
||||
>
|
||||
<h2
|
||||
id="homDataAdd__title"
|
||||
id="homeDataAdd__title"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Get started by adding integrations"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { FC, MouseEvent } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import {
|
||||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
|
@ -18,6 +19,9 @@ import {
|
|||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
UseEuiTheme,
|
||||
mathWithUnits,
|
||||
useEuiMinBreakpoint,
|
||||
} from '@elastic/eui';
|
||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
@ -37,19 +41,33 @@ interface Props {
|
|||
|
||||
export const AddData: FC<Props> = ({ addBasePath, application, isDarkMode, isCloudEnabled }) => {
|
||||
const { trackUiMetric, guidedOnboardingService } = getServices();
|
||||
const euiBreakpointM = useEuiMinBreakpoint('m');
|
||||
const euiBreakpointL = useEuiMinBreakpoint('l');
|
||||
const styles = ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
display: 'block',
|
||||
marginBlock: `0 -${mathWithUnits([euiTheme.size.xl, euiTheme.size.xs], (x, y) => x + y)}`,
|
||||
marginInline: 'auto',
|
||||
[euiBreakpointM]: {
|
||||
marginBlockEnd: euiTheme.size.xl,
|
||||
},
|
||||
[euiBreakpointL]: {
|
||||
inlineSize: '80%',
|
||||
},
|
||||
});
|
||||
|
||||
const canAccessIntegrations = application.capabilities.navLinks.integrations;
|
||||
if (canAccessIntegrations) {
|
||||
return (
|
||||
<KibanaPageTemplate.Section
|
||||
bottomBorder
|
||||
paddingSize="xl"
|
||||
className="homDataAdd"
|
||||
aria-labelledby="homDataAdd__title"
|
||||
aria-labelledby="homeDataAdd__title"
|
||||
>
|
||||
<EuiFlexGroup alignItems="flexEnd">
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="s">
|
||||
<h2 id="homDataAdd__title">
|
||||
<h2 id="homeDataAdd__title">
|
||||
<FormattedMessage
|
||||
id="home.addData.sectionTitle"
|
||||
defaultMessage="Get started by adding integrations"
|
||||
|
@ -135,7 +153,7 @@ export const AddData: FC<Props> = ({ addBasePath, application, isDarkMode, isClo
|
|||
alt={i18n.translate('home.addData.illustration.alt.text', {
|
||||
defaultMessage: 'Illustration of Elastic data integrations',
|
||||
})}
|
||||
className="homDataAdd__illustration"
|
||||
css={styles}
|
||||
src={
|
||||
addBasePath('/plugins/kibanaReact/assets/') +
|
||||
(isDarkMode
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
exports[`ManageData hide dev tools and stack management links if unavailable 1`] = `
|
||||
<_EuiPageSection
|
||||
aria-labelledby="homDataManage__title"
|
||||
aria-labelledby="homeDataManage__title"
|
||||
bottomBorder={true}
|
||||
className="homDataManage"
|
||||
data-test-subj="homDataManage"
|
||||
data-test-subj="homeDataManage"
|
||||
paddingSize="xl"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
|
@ -18,7 +17,7 @@ exports[`ManageData hide dev tools and stack management links if unavailable 1`]
|
|||
size="s"
|
||||
>
|
||||
<h2
|
||||
id="homDataManage__title"
|
||||
id="homeDataManage__title"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Management"
|
||||
|
@ -29,11 +28,9 @@ exports[`ManageData hide dev tools and stack management links if unavailable 1`]
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer />
|
||||
<EuiFlexGroup
|
||||
className="homDataManage__content"
|
||||
>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__item"
|
||||
css={[Function]}
|
||||
key="security"
|
||||
>
|
||||
<Synopsis
|
||||
|
@ -46,7 +43,7 @@ exports[`ManageData hide dev tools and stack management links if unavailable 1`]
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__item"
|
||||
css={[Function]}
|
||||
key="monitoring"
|
||||
>
|
||||
<Synopsis
|
||||
|
@ -59,7 +56,7 @@ exports[`ManageData hide dev tools and stack management links if unavailable 1`]
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__item"
|
||||
css={[Function]}
|
||||
key="snapshot_restore"
|
||||
>
|
||||
<Synopsis
|
||||
|
@ -72,7 +69,7 @@ exports[`ManageData hide dev tools and stack management links if unavailable 1`]
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__item"
|
||||
css={[Function]}
|
||||
key="index_lifecycle_management"
|
||||
>
|
||||
<Synopsis
|
||||
|
@ -90,10 +87,9 @@ exports[`ManageData hide dev tools and stack management links if unavailable 1`]
|
|||
|
||||
exports[`ManageData render 1`] = `
|
||||
<_EuiPageSection
|
||||
aria-labelledby="homDataManage__title"
|
||||
aria-labelledby="homeDataManage__title"
|
||||
bottomBorder={true}
|
||||
className="homDataManage"
|
||||
data-test-subj="homDataManage"
|
||||
data-test-subj="homeDataManage"
|
||||
paddingSize="xl"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
|
@ -106,7 +102,7 @@ exports[`ManageData render 1`] = `
|
|||
size="s"
|
||||
>
|
||||
<h2
|
||||
id="homDataManage__title"
|
||||
id="homeDataManage__title"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Management"
|
||||
|
@ -116,7 +112,6 @@ exports[`ManageData render 1`] = `
|
|||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__actions"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
|
@ -142,7 +137,6 @@ exports[`ManageData render 1`] = `
|
|||
}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="kbnOverviewPageHeader__actionButton"
|
||||
data-test-subj="homeDevTools"
|
||||
flush="both"
|
||||
href=""
|
||||
|
@ -173,7 +167,6 @@ exports[`ManageData render 1`] = `
|
|||
}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="kbnOverviewPageHeader__actionButton"
|
||||
data-test-subj="homeManage"
|
||||
flush="both"
|
||||
href=""
|
||||
|
@ -190,11 +183,9 @@ exports[`ManageData render 1`] = `
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer />
|
||||
<EuiFlexGroup
|
||||
className="homDataManage__content"
|
||||
>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__item"
|
||||
css={[Function]}
|
||||
key="security"
|
||||
>
|
||||
<Synopsis
|
||||
|
@ -207,7 +198,7 @@ exports[`ManageData render 1`] = `
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__item"
|
||||
css={[Function]}
|
||||
key="monitoring"
|
||||
>
|
||||
<Synopsis
|
||||
|
@ -220,7 +211,7 @@ exports[`ManageData render 1`] = `
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__item"
|
||||
css={[Function]}
|
||||
key="snapshot_restore"
|
||||
>
|
||||
<Synopsis
|
||||
|
@ -233,7 +224,7 @@ exports[`ManageData render 1`] = `
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homDataManage__item"
|
||||
css={[Function]}
|
||||
key="index_lifecycle_management"
|
||||
>
|
||||
<Synopsis
|
||||
|
|
|
@ -8,7 +8,15 @@
|
|||
*/
|
||||
|
||||
import React, { FC, MouseEvent } from 'react';
|
||||
import { EuiButtonEmpty, EuiFlexGroup, EuiSpacer, EuiTitle, EuiFlexItem } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import {
|
||||
EuiButtonEmpty,
|
||||
EuiFlexGroup,
|
||||
EuiSpacer,
|
||||
EuiTitle,
|
||||
EuiFlexItem,
|
||||
UseEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
|
@ -27,6 +35,7 @@ interface Props {
|
|||
|
||||
export const ManageData: FC<Props> = ({ addBasePath, application, features }) => {
|
||||
const { share, trackUiMetric } = getServices();
|
||||
|
||||
const consoleHref = share.url.locators.get('CONSOLE_APP_LOCATOR')?.useUrl({});
|
||||
const managementHref = share.url.locators
|
||||
.get('MANAGEMENT_APP_LOCATOR')
|
||||
|
@ -40,21 +49,20 @@ export const ManageData: FC<Props> = ({ addBasePath, application, features }) =>
|
|||
<KibanaPageTemplate.Section
|
||||
bottomBorder
|
||||
paddingSize="xl"
|
||||
className="homDataManage"
|
||||
aria-labelledby="homDataManage__title"
|
||||
data-test-subj="homDataManage"
|
||||
aria-labelledby="homeDataManage__title"
|
||||
data-test-subj="homeDataManage"
|
||||
>
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem grow={1}>
|
||||
<EuiTitle size="s">
|
||||
<h2 id="homDataManage__title">
|
||||
<h2 id="homeDataManage__title">
|
||||
<FormattedMessage id="home.manageData.sectionTitle" defaultMessage="Management" />
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
|
||||
{isDevToolsEnabled || isManagementEnabled ? (
|
||||
<EuiFlexItem className="homDataManage__actions" grow={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup alignItems="center" responsive={false} wrap>
|
||||
{/* Check if both the Dev Tools UI and the Console UI are enabled. */}
|
||||
{isDevToolsEnabled && consoleHref !== undefined ? (
|
||||
|
@ -66,7 +74,6 @@ export const ManageData: FC<Props> = ({ addBasePath, application, features }) =>
|
|||
>
|
||||
<EuiButtonEmpty
|
||||
data-test-subj="homeDevTools"
|
||||
className="kbnOverviewPageHeader__actionButton"
|
||||
flush="both"
|
||||
iconType="wrench"
|
||||
href={consoleHref}
|
||||
|
@ -89,7 +96,6 @@ export const ManageData: FC<Props> = ({ addBasePath, application, features }) =>
|
|||
>
|
||||
<EuiButtonEmpty
|
||||
data-test-subj="homeManage"
|
||||
className="kbnOverviewPageHeader__actionButton"
|
||||
flush="both"
|
||||
iconType="gear"
|
||||
href={managementHref}
|
||||
|
@ -109,9 +115,18 @@ export const ManageData: FC<Props> = ({ addBasePath, application, features }) =>
|
|||
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiFlexGroup className="homDataManage__content">
|
||||
<EuiFlexGroup>
|
||||
{features.map((feature) => (
|
||||
<EuiFlexItem className="homDataManage__item" key={feature.id}>
|
||||
<EuiFlexItem
|
||||
css={({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
[`@media (min-width: ${euiTheme.breakpoint.l}px)`]: {
|
||||
maxWidth: `calc(33.33% - ${euiTheme.size.l})`,
|
||||
},
|
||||
})
|
||||
}
|
||||
key={feature.id}
|
||||
>
|
||||
<Synopsis
|
||||
description={feature.description}
|
||||
iconType={feature.icon}
|
||||
|
|
|
@ -14,12 +14,8 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
// @ts-ignore
|
||||
EuiCard,
|
||||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
} from '@elastic/eui';
|
||||
import { EuiCard, EuiButton, EuiButtonEmpty, UseEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { getServices } from '../../kibana_services';
|
||||
|
||||
|
@ -51,14 +47,10 @@ export function SampleDataCard({ urlBasePath, onDecline, onConfirm }: Props) {
|
|||
}
|
||||
footer={
|
||||
<footer>
|
||||
<EuiButton fill className="homWelcome__footerAction" onClick={onConfirm}>
|
||||
<EuiButton fill css={footerAction} onClick={onConfirm}>
|
||||
<FormattedMessage id="home.tryButtonLabel" defaultMessage="Add integrations" />
|
||||
</EuiButton>
|
||||
<EuiButtonEmpty
|
||||
className="homWelcome__footerAction"
|
||||
onClick={onDecline}
|
||||
data-test-subj="skipWelcomeScreen"
|
||||
>
|
||||
<EuiButtonEmpty css={footerAction} onClick={onDecline} data-test-subj="skipWelcomeScreen">
|
||||
<FormattedMessage id="home.exploreButtonLabel" defaultMessage="Explore on my own" />
|
||||
</EuiButtonEmpty>
|
||||
</footer>
|
||||
|
@ -66,3 +58,8 @@ export function SampleDataCard({ urlBasePath, onDecline, onConfirm }: Props) {
|
|||
/>
|
||||
);
|
||||
}
|
||||
const footerAction = ({ euiTheme }: UseEuiTheme) => {
|
||||
return css({
|
||||
marginRight: euiTheme.size.s,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
exports[`SolutionPanel renders the solution panel for the given solution 1`] = `
|
||||
<EuiFlexItem
|
||||
className="homSolutions__item"
|
||||
data-test-subj="homSolutionPanel homSolutionPanel_kibana"
|
||||
css={[Function]}
|
||||
data-test-subj="homeSolutionPanel homeSolutionPanel_kibana"
|
||||
>
|
||||
<EuiCard
|
||||
className="homSolutionPanel homSolutionPanel--kibana"
|
||||
className="homeSolutionPanel homeSolutionPanel--kibana"
|
||||
description="Explore and analyze your data"
|
||||
href="kibana_landing_page"
|
||||
icon={
|
||||
|
|
|
@ -2,19 +2,13 @@
|
|||
|
||||
exports[`SolutionsSection renders a single solution 1`] = `
|
||||
<_EuiPageSection
|
||||
aria-labelledby="homSolutions__title"
|
||||
aria-labelledby="homeSolutions__title"
|
||||
bottomBorder={true}
|
||||
className="homSolutions"
|
||||
contentProps={
|
||||
Object {
|
||||
"className": "homSolutions__content",
|
||||
}
|
||||
}
|
||||
paddingSize="xl"
|
||||
>
|
||||
<EuiScreenReaderOnly>
|
||||
<h2
|
||||
id="homSolutions__title"
|
||||
id="homeSolutions__title"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Pick your solution"
|
||||
|
@ -22,9 +16,7 @@ exports[`SolutionsSection renders a single solution 1`] = `
|
|||
/>
|
||||
</h2>
|
||||
</EuiScreenReaderOnly>
|
||||
<EuiFlexGroup
|
||||
className="homSolutions__content"
|
||||
>
|
||||
<EuiFlexGroup>
|
||||
<SolutionPanel
|
||||
addBasePath={[Function]}
|
||||
key="kibana"
|
||||
|
@ -45,19 +37,13 @@ exports[`SolutionsSection renders a single solution 1`] = `
|
|||
|
||||
exports[`SolutionsSection renders multiple solutions 1`] = `
|
||||
<_EuiPageSection
|
||||
aria-labelledby="homSolutions__title"
|
||||
aria-labelledby="homeSolutions__title"
|
||||
bottomBorder={true}
|
||||
className="homSolutions"
|
||||
contentProps={
|
||||
Object {
|
||||
"className": "homSolutions__content",
|
||||
}
|
||||
}
|
||||
paddingSize="xl"
|
||||
>
|
||||
<EuiScreenReaderOnly>
|
||||
<h2
|
||||
id="homSolutions__title"
|
||||
id="homeSolutions__title"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Pick your solution"
|
||||
|
@ -65,9 +51,7 @@ exports[`SolutionsSection renders multiple solutions 1`] = `
|
|||
/>
|
||||
</h2>
|
||||
</EuiScreenReaderOnly>
|
||||
<EuiFlexGroup
|
||||
className="homSolutions__content"
|
||||
>
|
||||
<EuiFlexGroup>
|
||||
<SolutionPanel
|
||||
addBasePath={[Function]}
|
||||
key="kibana"
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
import { snakeCase } from 'lodash';
|
||||
import React, { FC, MouseEvent } from 'react';
|
||||
import { EuiCard, EuiFlexItem } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiCard, EuiFlexItem, UseEuiTheme, mathWithUnits } from '@elastic/eui';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { KibanaPageTemplateSolutionNavAvatar } from '@kbn/kibana-react-plugin/public';
|
||||
import { FeatureCatalogueSolution } from '../../..';
|
||||
|
@ -21,19 +22,16 @@ interface Props {
|
|||
solution: FeatureCatalogueSolution;
|
||||
}
|
||||
|
||||
const getSolutionGraphicURL = (solutionId: string) =>
|
||||
`/plugins/kibanaReact/assets/solutions_${solutionId}.svg`;
|
||||
|
||||
export const SolutionPanel: FC<Props> = ({ addBasePath, solution }) => {
|
||||
const { trackUiMetric } = getServices();
|
||||
|
||||
const getSolutionGraphicURL = (solutionId: string) =>
|
||||
`/plugins/kibanaReact/assets/solutions_${solutionId}.svg`;
|
||||
|
||||
return (
|
||||
<EuiFlexItem
|
||||
className="homSolutions__item"
|
||||
data-test-subj={`homSolutionPanel homSolutionPanel_${solution.id}`}
|
||||
>
|
||||
<EuiFlexItem css={styles} data-test-subj={`homeSolutionPanel homeSolutionPanel_${solution.id}`}>
|
||||
<EuiCard
|
||||
className={`homSolutionPanel homSolutionPanel--${solution.id}`}
|
||||
className={`homeSolutionPanel homeSolutionPanel--${solution.id}`}
|
||||
description={solution.description}
|
||||
href={addBasePath(solution.path)}
|
||||
icon={
|
||||
|
@ -54,3 +52,29 @@ export const SolutionPanel: FC<Props> = ({ addBasePath, solution }) => {
|
|||
</EuiFlexItem>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
[`@media (min-width: ${euiTheme.breakpoint.m}px)`]: {
|
||||
maxInlineSize: `calc(33.33% - ${euiTheme.size.m} * 10)`,
|
||||
},
|
||||
'.homeSolutionPanel': {
|
||||
img: {
|
||||
backgroundColor: euiTheme.colors.primary,
|
||||
maxBlockSize: mathWithUnits(euiTheme.size.m, (x) => x * 10),
|
||||
objectFit: 'cover',
|
||||
},
|
||||
|
||||
'&--enterpriseSearch img': {
|
||||
backgroundColor: euiTheme.colors.warning,
|
||||
},
|
||||
|
||||
'&--observability img': {
|
||||
backgroundColor: euiTheme.colors.accent,
|
||||
},
|
||||
|
||||
'&--securitySolution img': {
|
||||
backgroundColor: euiTheme.colors.accentSecondary,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -32,12 +32,10 @@ export const SolutionsSection: FC<Props> = ({ addBasePath, solutions }) => {
|
|||
<KibanaPageTemplate.Section
|
||||
bottomBorder
|
||||
paddingSize="xl"
|
||||
aria-labelledby="homSolutions__title"
|
||||
className="homSolutions"
|
||||
contentProps={{ className: 'homSolutions__content' }}
|
||||
aria-labelledby="homeSolutions__title"
|
||||
>
|
||||
<EuiScreenReaderOnly>
|
||||
<h2 id="homSolutions__title">
|
||||
<h2 id="homeSolutions__title">
|
||||
<FormattedMessage
|
||||
id="home.solutionsSection.sectionTitle"
|
||||
defaultMessage="Pick your solution"
|
||||
|
@ -45,7 +43,7 @@ export const SolutionsSection: FC<Props> = ({ addBasePath, solutions }) => {
|
|||
</h2>
|
||||
</EuiScreenReaderOnly>
|
||||
|
||||
<EuiFlexGroup className="homSolutions__content">
|
||||
<EuiFlexGroup>
|
||||
{solutions.map((solution) => (
|
||||
<SolutionPanel addBasePath={addBasePath} key={solution.id} solution={solution} />
|
||||
))}
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
.homTutorial__instruction {
|
||||
flex-shrink: 0;
|
||||
}
|
|
@ -10,13 +10,16 @@
|
|||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { EuiThemeProvider } from '@elastic/eui';
|
||||
import './welcome.test.mocks';
|
||||
import { Welcome } from './welcome';
|
||||
|
||||
test('should render a Welcome screen', () => {
|
||||
const { getByText } = render(
|
||||
<I18nProvider>
|
||||
<Welcome urlBasePath="/" onSkip={() => {}} />
|
||||
<EuiThemeProvider>
|
||||
<Welcome urlBasePath="" onSkip={() => {}} />
|
||||
</EuiThemeProvider>
|
||||
</I18nProvider>
|
||||
);
|
||||
expect(getByText('Welcome to Elastic')).toBeInTheDocument();
|
||||
|
|
|
@ -13,91 +13,131 @@
|
|||
* in Elasticsearch.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiTitle, EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiPortal } from '@elastic/eui';
|
||||
import React, { useEffect } from 'react';
|
||||
import {
|
||||
EuiTitle,
|
||||
EuiSpacer,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiIcon,
|
||||
EuiPortal,
|
||||
UseEuiTheme,
|
||||
useEuiShadow,
|
||||
mathWithUnits,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { css } from '@emotion/react';
|
||||
import { fullScreenGraphicsMixinStyles } from '@kbn/core/public';
|
||||
import { getServices } from '../kibana_services';
|
||||
|
||||
import { SampleDataCard } from './sample_data';
|
||||
|
||||
interface Props {
|
||||
interface WelcomeProps {
|
||||
urlBasePath: string;
|
||||
onSkip: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a full-screen welcome page that gives helpful quick links to beginners.
|
||||
*/
|
||||
export class Welcome extends React.Component<Props> {
|
||||
private services = getServices();
|
||||
export const Welcome: React.FC<WelcomeProps> = ({ urlBasePath, onSkip }: WelcomeProps) => {
|
||||
const services = getServices();
|
||||
const euiShadowM = useEuiShadow('m');
|
||||
const theme = useEuiTheme();
|
||||
|
||||
private hideOnEsc = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
this.props.onSkip();
|
||||
}
|
||||
const redirectToAddData = () => {
|
||||
services.application.navigateToApp('integrations', { path: '/browse' });
|
||||
};
|
||||
|
||||
private redirectToAddData() {
|
||||
this.services.application.navigateToApp('integrations', { path: '/browse' });
|
||||
}
|
||||
|
||||
private onSampleDataDecline = () => {
|
||||
this.services.trackUiMetric(METRIC_TYPE.CLICK, 'sampleDataDecline');
|
||||
this.props.onSkip();
|
||||
const onSampleDataDecline = () => {
|
||||
services.trackUiMetric(METRIC_TYPE.CLICK, 'sampleDataDecline');
|
||||
onSkip();
|
||||
};
|
||||
|
||||
private onSampleDataConfirm = () => {
|
||||
this.services.trackUiMetric(METRIC_TYPE.CLICK, 'sampleDataConfirm');
|
||||
this.redirectToAddData();
|
||||
const onSampleDataConfirm = () => {
|
||||
services.trackUiMetric(METRIC_TYPE.CLICK, 'sampleDataConfirm');
|
||||
redirectToAddData();
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { welcomeService } = this.services;
|
||||
this.services.trackUiMetric(METRIC_TYPE.LOADED, 'welcomeScreenMount');
|
||||
document.addEventListener('keydown', this.hideOnEsc);
|
||||
useEffect(() => {
|
||||
const hideOnEsc = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
onSkip();
|
||||
}
|
||||
};
|
||||
const { welcomeService } = services;
|
||||
services.trackUiMetric(METRIC_TYPE.LOADED, 'welcomeScreenMount');
|
||||
document.addEventListener('keydown', hideOnEsc);
|
||||
welcomeService.onRendered();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.hideOnEsc);
|
||||
}
|
||||
return () => {
|
||||
document.removeEventListener('keydown', hideOnEsc);
|
||||
};
|
||||
}, [onSkip, services]);
|
||||
|
||||
render() {
|
||||
const { urlBasePath } = this.props;
|
||||
const { welcomeService } = this.services;
|
||||
return (
|
||||
<EuiPortal>
|
||||
<div className="homWelcome" data-test-subj="homeWelcomeInterstitial">
|
||||
<header className="homWelcome__header">
|
||||
<div className="homWelcome__content eui-textCenter">
|
||||
<EuiSpacer size="xl" />
|
||||
<span className="homWelcome__logo">
|
||||
<EuiIcon type="logoElastic" size="xxl" />
|
||||
</span>
|
||||
<EuiTitle size="l" className="homWelcome__title">
|
||||
<h1>
|
||||
<FormattedMessage id="home.welcomeTitle" defaultMessage="Welcome to Elastic" />
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="m" />
|
||||
</div>
|
||||
</header>
|
||||
<div className="homWelcome__content homWelcome-body">
|
||||
<EuiFlexGroup gutterSize="l">
|
||||
<EuiFlexItem>
|
||||
<SampleDataCard
|
||||
urlBasePath={urlBasePath}
|
||||
onConfirm={this.onSampleDataConfirm}
|
||||
onDecline={this.onSampleDataDecline}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
{welcomeService.renderTelemetryNotice()}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
const { welcomeService } = services;
|
||||
|
||||
return (
|
||||
<EuiPortal>
|
||||
<div
|
||||
data-test-subj="homeWelcomeInterstitial"
|
||||
css={[
|
||||
styles,
|
||||
fullScreenGraphicsMixinStyles(Number(theme.euiTheme.levels.navigation), theme),
|
||||
]}
|
||||
>
|
||||
<header className="homeWelcome__header">
|
||||
<div className="homeWelcome__content eui-textCenter">
|
||||
<EuiSpacer size="xl" />
|
||||
<span
|
||||
className="homeWelcome__logo"
|
||||
css={css`
|
||||
${euiShadowM}
|
||||
`}
|
||||
>
|
||||
<EuiIcon type="logoElastic" size="xxl" />
|
||||
</span>
|
||||
<EuiTitle size="l">
|
||||
<h1>
|
||||
<FormattedMessage id="home.welcomeTitle" defaultMessage="Welcome to Elastic" />
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="m" />
|
||||
</div>
|
||||
</header>
|
||||
<div className="homeWelcome__content">
|
||||
<EuiFlexGroup gutterSize="l">
|
||||
<EuiFlexItem>
|
||||
<SampleDataCard
|
||||
urlBasePath={urlBasePath}
|
||||
onConfirm={onSampleDataConfirm}
|
||||
onDecline={onSampleDataDecline}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
{welcomeService.renderTelemetryNotice()}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
</EuiPortal>
|
||||
);
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</EuiPortal>
|
||||
);
|
||||
};
|
||||
const styles = ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
'.homeWelcome__header': {
|
||||
padding: euiTheme.size.xl,
|
||||
zIndex: 10,
|
||||
},
|
||||
'.homeWelcome__logo': {
|
||||
marginBottom: euiTheme.size.xl,
|
||||
display: 'inline-block',
|
||||
},
|
||||
'.homeWelcome__content': {
|
||||
margin: 'auto',
|
||||
maxWidth: mathWithUnits(euiTheme.size.xxxxl, (x) => x * 8),
|
||||
paddingLeft: euiTheme.size.xl,
|
||||
paddingRight: euiTheme.size.xl,
|
||||
zIndex: 10,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
@import 'components/index';
|
|
@ -4,7 +4,7 @@
|
|||
"outDir": "target/types",
|
||||
"isolatedModules": true
|
||||
},
|
||||
"include": ["common/**/*", "public/**/*", "server/**/*", ".storybook/**/*"],
|
||||
"include": ["common/**/*", "public/**/*", "server/**/*", ".storybook/**/*", "../../../../../typings/emotion.d.ts"],
|
||||
"kbn_references": [
|
||||
"@kbn/core",
|
||||
"@kbn/data-views-plugin",
|
||||
|
|
|
@ -30,7 +30,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
expect(event.properties.target).to.be.an('array');
|
||||
const targets = event.properties.target as string[];
|
||||
expect(targets.includes('DIV')).to.be(true);
|
||||
expect(targets.includes('class=homWelcome')).to.be(true);
|
||||
expect(targets.includes('data-test-subj=homeWelcomeInterstitial')).to.be(true);
|
||||
expect(targets.includes('BUTTON')).to.be(true);
|
||||
expect(targets.includes('data-test-subj=skipWelcomeScreen')).to.be(true);
|
||||
|
|
|
@ -77,11 +77,11 @@ export class HomePageObject extends FtrService {
|
|||
}
|
||||
|
||||
async getVisibileSolutions() {
|
||||
const solutionPanels = await this.testSubjects.findAll('~homSolutionPanel', 2000);
|
||||
const solutionPanels = await this.testSubjects.findAll('~homeSolutionPanel', 2000);
|
||||
const panelAttributes = await Promise.all(
|
||||
solutionPanels.map((panel) => panel.getAttribute('data-test-subj'))
|
||||
);
|
||||
return panelAttributes.map((attributeValue) => attributeValue?.split('homSolutionPanel_')[1]);
|
||||
return panelAttributes.map((attributeValue) => attributeValue?.split('homeSolutionPanel_')[1]);
|
||||
}
|
||||
|
||||
async goToSampleDataPage() {
|
||||
|
|
|
@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('Kibana overview page meets a11y requirements ', async () => {
|
||||
await testSubjects.click('homSolutionPanel homSolutionPanel_kibana');
|
||||
await testSubjects.click('homeSolutionPanel homeSolutionPanel_kibana');
|
||||
await a11y.testAppSnapshot();
|
||||
});
|
||||
|
||||
|
@ -48,19 +48,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
it('Enterprise search overview page meets a11y requirements ', async () => {
|
||||
await home.clickGoHome();
|
||||
await testSubjects.click('homSolutionPanel homSolutionPanel_enterpriseSearch');
|
||||
await testSubjects.click('homeSolutionPanel homeSolutionPanel_enterpriseSearch');
|
||||
await a11y.testAppSnapshot();
|
||||
});
|
||||
|
||||
it('Observability overview page meets a11y requirements ', async () => {
|
||||
await home.clickGoHome();
|
||||
await testSubjects.click('homSolutionPanel homSolutionPanel_observability');
|
||||
await testSubjects.click('homeSolutionPanel homeSolutionPanel_observability');
|
||||
await a11y.testAppSnapshot();
|
||||
});
|
||||
|
||||
it('Security overview page meets a11y requirements ', async () => {
|
||||
await home.clickGoHome();
|
||||
await testSubjects.click('homSolutionPanel homSolutionPanel_securitySolution');
|
||||
await testSubjects.click('homeSolutionPanel homeSolutionPanel_securitySolution');
|
||||
await a11y.testAppSnapshot();
|
||||
});
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('shows the management section', async () => {
|
||||
await testSubjects.existOrFail('homDataManage', { timeout: 2000 });
|
||||
await testSubjects.existOrFail('homeDataManage', { timeout: 2000 });
|
||||
});
|
||||
|
||||
it('shows the "Manage" action item', async () => {
|
||||
|
@ -124,7 +124,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('does not show the management section', async () => {
|
||||
await testSubjects.missingOrFail('homDataManage', { timeout: 2000 });
|
||||
await testSubjects.missingOrFail('homeDataManage', { timeout: 2000 });
|
||||
});
|
||||
|
||||
it('does not show the "Manage" action item', async () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue